diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map/clif.c | 14 | ||||
-rw-r--r-- | src/map/map.c | 89 | ||||
-rw-r--r-- | src/map/map.h | 1 | ||||
-rw-r--r-- | src/map/pc.c | 9 | ||||
-rw-r--r-- | src/map/pc.h | 13 | ||||
-rw-r--r-- | src/map/script.c | 16 | ||||
-rw-r--r-- | src/map/skill.c | 91 |
7 files changed, 204 insertions, 29 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index b6044c166..678a3f716 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9016,6 +9016,20 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) { return; } } + } else if (skillnum == CH_TIGERFIST) { + if (sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_COMBOFINISH) { + if (!sd->state.skill_flag ) { + sd->state.skill_flag = 1; + if (!sd->attacktarget) { + clif_skillinfo(sd, CH_TIGERFIST, 1, -2); + return; + } else + target_id = sd->attacktarget; + } else if (sd->bl.id == target_id) { + clif_skillinfo(sd, CH_TIGERFIST, 1, -2); + return; + } + } } if ((lv = pc_checkskill(sd, skillnum)) > 0) { if (skilllv > lv) diff --git a/src/map/map.c b/src/map/map.c index 493a243ff..9515e8233 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -652,6 +652,95 @@ void map_foreachincell(int (*func)(struct block_list*,va_list),int m,int x,int y bl_list_count = blockcount; } +/*============================================================ +* For checking a path between two points (x0, y0) and (x1, y1) +*------------------------------------------------------------ + */ +void map_foreachinpath(int (*func)(struct block_list*,va_list),int m,int x0,int y0,int x1,int y1,int range,int length,int type,...) { + va_list ap; + int bx,by; + struct block_list *bl=NULL; + int blockcount=bl_list_count,i,c; + double s; + int in; // slope, interception + + if(m < 0) + return; + va_start(ap,type); + if (x0 < 0) x0 = 0; + if (y0 < 0) y0 = 0; + if (x1 >= map[m].xs) x1 = map[m].xs-1; + if (y1 >= map[m].ys) y1 = map[m].ys-1; + +// y = ax + c // ugh, algebra! xp +// x = (y - c) / a + if (x0 == x1) { + s = 999; in = 0; + } else if (y0 == y1) { + s = 0; in = y0; + } else { + s = (double)(y1 - y0)/(double)(x1 - x0); + in = y0 - s * x0; + } + //printf ("%lf %d\n", s, in); + + if (type == 0 || type != BL_MOB) + for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) { + for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){ + bl = map[m].block[bx+by*map[m].bxs]; + c = map[m].block_count[bx+by*map[m].bxs]; + for(i=0;i<c && bl;i++,bl=bl->next){ + if(bl && type && bl->type!=type) + continue; + if(bl) { + printf ("%lf %lf\n", s * bl->x + in - bl->y, (in - bl->y)/s - bl->x); + + if (((s == 999 && bl->x == x0) || + (s == 0 && in == y0 && bl->y == y0) || + abs(s * bl->x + in - bl->y) <= range || + abs((bl->y - in)/s - bl->x) <= range) && + bl_list_count<BL_LIST_MAX) + bl_list[bl_list_count++]=bl; + } + } + } + } + if(type==0 || type==BL_MOB) + for(by=y0/BLOCK_SIZE;by<=y1/BLOCK_SIZE;by++){ + for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){ + bl = map[m].block_mob[bx+by*map[m].bxs]; + c = map[m].block_mob_count[bx+by*map[m].bxs]; + for(i=0;i<c && bl;i++,bl=bl->next){ + if(bl) { + printf ("%lf %lf\n", s * bl->x + in - bl->y, (bl->y - in)/s - bl->x); + if (((s == 999 && bl->x == x0) || + (s == 0 && in == y0 && bl->y == y0) || + abs(s * bl->x + in - bl->y) <= range || + abs((bl->y - in)/s - bl->x) <= range) && + bl_list_count<BL_LIST_MAX) + bl_list[bl_list_count++]=bl; + } + } + } + } + + if(bl_list_count>=BL_LIST_MAX) { + if(battle_config.error_log) + printf("map_foreachinarea: *WARNING* block count too many!\n"); + } + + map_freeblock_lock(); // メモリからの解放を禁止する + + for(i=blockcount;i<bl_list_count;i++) + if(bl_list[i]->prev) // 有?かどうかチェック + func(bl_list[i],ap); + + map_freeblock_unlock(); // 解放を許可する + + va_end(ap); + bl_list_count = blockcount; +} + /*========================================== * 床アイテムやエフェクト用の一時obj割り?て * object[]への保存とid_db登?まで diff --git a/src/map/map.h b/src/map/map.h index 5944167ad..04baea121 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -689,6 +689,7 @@ void map_foreachinarea(int (*)(struct block_list*,va_list),int,int,int,int,int,i // -- moonsoul (added map_foreachincell) void map_foreachincell(int (*)(struct block_list*,va_list),int,int,int,int,...); void map_foreachinmovearea(int (*)(struct block_list*,va_list),int,int,int,int,int,int,int,int,...); +void map_foreachinpath(int (*)(struct block_list*,va_list),int,int,int,int,int,int,int,int,...); // Celest int map_countnearpc(int,int,int); //block関連に追加 int map_count_oncell(int m,int x,int y); diff --git a/src/map/pc.c b/src/map/pc.c index e98df2a02..512a097ed 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -48,7 +48,7 @@ static int exp_table[14][MAX_LEVEL]; static char statp[255][7]; // h-files are for declarations, not for implementations... [Shinomori] -struct skill_tree_entry skill_tree[3][MAX_PC_CLASS][100]; +struct skill_tree_entry skill_tree[3][25][MAX_SKILL_TREE]; // timer for night.day implementation int day_timer_tid; int night_timer_tid; @@ -6843,7 +6843,12 @@ int pc_readdb(void) s_class = pc_calc_base_job(atoi(split[0])); i = s_class.job; u = s_class.upper; - for(j=0;skill_tree[u][i][j].id;j++); + // check for bounds [celest] + if (i > 25 || u > 3) + continue; + for(j = 0; skill_tree[u][i][j].id && j < MAX_SKILL_TREE; j++); + if (j == MAX_SKILL_TREE) + continue; skill_tree[u][i][j].id=atoi(split[1]); skill_tree[u][i][j].max=atoi(split[2]); diff --git a/src/map/pc.h b/src/map/pc.h index 6fe04c946..8c28e299a 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -9,6 +9,8 @@ #define CART_MASK 0x788 #define STATE_BLIND 0x10 +#define MAX_SKILL_TREE 51 + #define pc_setdead(sd) ((sd)->state.dead_sit = 1) #define pc_setsit(sd) ((sd)->state.dead_sit = 2) //#define pc_setstand(sd) ((sd)->state.dead_sit = 0) @@ -175,13 +177,14 @@ int pc_calc_base_job2(int b_class); // Celest int pc_calc_upper(int b_class); struct skill_tree_entry { - int id; - int max; + short id; + unsigned char max; struct { - short id,lv; - } need[6]; + short id; + unsigned char lv; + } need[5]; }; // Celest -extern struct skill_tree_entry skill_tree[3][MAX_PC_CLASS][100]; +extern struct skill_tree_entry skill_tree[3][25][MAX_SKILL_TREE]; int pc_read_gm_account(int fd); int pc_setinvincibletimer(struct map_session_data *sd,int); diff --git a/src/map/script.c b/src/map/script.c index 07f642dc6..a5e29026d 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -298,6 +298,8 @@ int buildin_skilluseid(struct script_state *st); // originally by Qamera [celest int buildin_skillusepos(struct script_state *st); // originally by Qamera [celest] int buildin_logmes(struct script_state *st); // [Lupus] int buildin_summon(struct script_state *st); // [celest] +int buildin_isnight(struct script_state *st); // [celest] +int buildin_isday(struct script_state *st); // [celest] void push_val(struct script_stack *stack,int type,int val); int run_func(struct script_state *st); @@ -522,6 +524,8 @@ struct { {buildin_skillusepos,"skillusepos","iiii"}, // [Celest] {buildin_logmes,"logmes","s"}, //this command actls as MES but prints info into LOG file either SQL/TXT [Lupus] {buildin_summon,"summon","si*"}, // summons a slave monster [Celest] + {buildin_isnight,"isnight",""}, // check whether it is night time [Celest] + {buildin_isday,"isday",""}, // check whether it is day time [Celest] {NULL,NULL,NULL}, }; int buildin_message(struct script_state *st); // [MouseJstr] @@ -6515,6 +6519,18 @@ int buildin_summon(struct script_state *st) return 0; } +int buildin_isnight(struct script_state *st) +{ + push_val(st->stack,C_INT, (night_flag == 1)); + return 0; +} + +int buildin_isday(struct script_state *st) +{ + push_val(st->stack,C_INT, (night_flag == 0)); + return 0; +} + // // 実行部main // diff --git a/src/map/skill.c b/src/map/skill.c index aab8a77d4..8caaca02c 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1,4 +1,4 @@ -// $Id: skill.c,v 1.8 2004/12/16 6:46:08 PM Celestia $ +// $Id: skill.c,v 1.8 2004/01/07 10:46:38 PM Celestia $ /* スキル?係 */ #include <stdio.h> @@ -2297,10 +2297,12 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s case SN_SHARPSHOOTING: /* シャ?プシュ?ティング */ { - int dx, dy, wx = 0, wy = 0; + #if 0 // temporarily keeping this block for future reference [celest] + /*int dx, dy, wx = 0, wy = 0; int weight, num = 0; int x1 = src->x, y1 = src->y; int x0 = bl->x, y0 = bl->y; + int *xs, *ys; dx = (x1 - x0); if (dx < 0) { @@ -2310,6 +2312,8 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s } dy = (y1 - y0); weight = dx > abs(dy) ? dx : abs(y1 - y0); + xs = (int *)aCallocA(weight, sizeof(int)); + ys = (int *)aCallocA(weight, sizeof(int)); while ((x0 != x1 || y0 != y1) && num < skill_get_range(skillid,skilllv)) { // fixed [Shinomori] wx += dx; wy += dy; @@ -2325,11 +2329,28 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s if (dy > 0) { y0++; } else { y0--; } } - map_foreachinarea (skill_attack_area,src->m,x0,y0,x0,y0,0, - BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); + //xs[number] = x0; + //ys[number] = y0 + printf ("%d - %d %d\n", weight, x0, y0); + //map_foreachinarea (skill_attack_area,src->m,x0,y0,x0,y0,0, + //BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); num++; // make sure it doesn't run infinitely } + //for num = 0; num < weight; num++ + //map_foreach skill attack area + //if last of xs || ys != x y, manually skill attack clif_skill_nodamage(src,bl,skillid,skilllv,1); + aFree (xs); + aFree (ys);*/ + #endif + + #if 0 // change 0 to 1 to switch to the this system [celest] + skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); + #else + map_foreachinpath (skill_attack_area,src->m,src->x,src->y,bl->x,bl->y, + 2,skill_get_range(skillid,skilllv),0, + BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); + #endif } break; @@ -2486,7 +2507,7 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s break; /* 武器系範?攻?スキル */ case AC_SHOWER: /* アロ?シャワ? */ - case SM_MAGNUM: /* マグナムブレイク */ +// case SM_MAGNUM: /* マグナムブレイク */ case AS_GRIMTOOTH: /* グリムトゥ?ス */ case MC_CARTREVOLUTION: /* カ?トレヴォリュ?ション */ case NPC_SPLASHATTACK: /* スプラッシュアタック */ @@ -2496,11 +2517,11 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s /* 個別にダメ?ジを?える */ if(bl->id!=skill_area_temp[1]){ int dist=0; - if(skillid==SM_MAGNUM){ /* マグナムブレイクなら中心からの距離を計算 */ - int dx=abs( bl->x - skill_area_temp[2] ); - int dy=abs( bl->y - skill_area_temp[3] ); - dist=((dx>dy)?dx:dy); - } + //if(skillid==SM_MAGNUM){ /* マグナムブレイクなら中心からの距離を計算 */ + // int dx=abs( bl->x - skill_area_temp[2] ); + // int dy=abs( bl->y - skill_area_temp[3] ); + // dist=((dx>dy)?dx:dy); + //} skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick, 0x0500|dist ); if (bl->type == BL_MOB && skillid == AS_GRIMTOOTH) { @@ -2512,10 +2533,11 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s }else{ int ar=1; int x=bl->x,y=bl->y; - if( skillid==SM_MAGNUM){ + /*if( skillid==SM_MAGNUM){ x=src->x; y=src->y; - }else if(skillid==AC_SHOWER || skillid==ASC_METEORASSAULT) /* アロ?シャワ?、メテオアサルト範?5*5 */ + }else*/ + if(skillid==AC_SHOWER || skillid==ASC_METEORASSAULT) /* アロ?シャワ?、メテオアサルト範?5*5 */ ar=2; else if(skillid==AS_SPLASHER) /* ベナムスプラッシャ?範?3*3 */ ar=1; @@ -2535,8 +2557,19 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s bl->m,x-ar,y-ar,x+ar,y+ar,0, src,skillid,skilllv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id); - if (skillid == SM_MAGNUM) // fire element for 10 seconds - status_change_start(src,SC_FLAMELAUNCHER,0,0,0,0,10000,0); + } + break; + + case SM_MAGNUM: /* マグナムブレイク [celest] */ + { + int dist = 0; + int dx = abs( bl->x - skill_area_temp[2] ); + int dy = abs( bl->y - skill_area_temp[3] ); + dist = ((dx>dy)?dx:dy); + map_foreachinarea (skill_attack_area,src->m,src->x-1,src->y-1,src->x+1,src->y+1,0, + BF_WEAPON,src,src,skillid,skilllv,tick,0x0500|dist,BCT_ENEMY); + status_change_start (src,SC_FLAMELAUNCHER,0,0,0,0,10000,0); + clif_skill_nodamage (src,src,skillid,skilllv,1); } break; @@ -2773,15 +2806,20 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s if (skilllv == 5) skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,0 ); if (bl->type == BL_PC) { - ((struct map_session_data *)bl)->status.sp = 0; - clif_updatestatus((struct map_session_data *)bl,SP_SP); + struct map_session_data *tsd = (struct map_session_data *)bl; + if (tsd) { + tsd->status.sp = 0; + clif_updatestatus((struct map_session_data *)bl,SP_SP); + } } } else { clif_skill_nodamage(src,src,skillid,skilllv,1); if (skilllv == 5) skill_attack(BF_MAGIC,src,src,src,skillid,skilllv,tick,0 ); - sd->status.sp = 0; - clif_updatestatus(sd,SP_SP); + if (sd) { + sd->status.sp = 0; + clif_updatestatus(sd,SP_SP); + } } status_change_start(src,SC_BLOCKSKILL,skilllv,0,skillid,0, (skilllv < 5 ? 10000: 15000),0 ); } @@ -3363,7 +3401,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int lv = (lv<0)?-lv:lv; if((dstsd->bl.type!=BL_PC) // 相手はPCじゃないとだめ ||(sd->bl.id == dstsd->bl.id) // 相手が自分はだめ - ||(lv > 10) // レベル差±10まで + ||(lv > battle_config.devotion_level_difference) // レベル差±10まで ||(!sd->status.party_id && !sd->status.guild_id) // PTにもギルドにも所?無しはだめ ||((sd->status.party_id != dstsd->status.party_id) // 同じパ?ティ?か、 &&(sd->status.guild_id != dstsd->status.guild_id)) // 同じギルドじゃないとだめ @@ -5989,9 +6027,11 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int struct status_change *sc_data=status_get_sc_data(bl); if(sg->val2==0 && sc_data && sc_data[SC_ANKLE].timer==-1){ int moveblock = ( bl->x/BLOCK_SIZE != src->bl.x/BLOCK_SIZE || bl->y/BLOCK_SIZE != src->bl.y/BLOCK_SIZE); - int sec = skill_get_time2(sg->skill_id,sg->skill_lv) - status_get_agi(bl)/10; + int sec = skill_get_time2(sg->skill_id,sg->skill_lv) - status_get_agi(bl)*100; if(status_get_mode(bl)&0x20) sec = sec/5; + if (sec < 3000) // minimum time of 3 seconds [celest] + sec = 3000; battle_stopwalking(bl,1); status_change_start(bl,SC_ANKLE,sg->skill_lv,0,0,0,sec,0); @@ -7034,7 +7074,7 @@ int skill_check_condition(struct map_session_data *sd,int type) return 0; break; case CH_TIGERFIST: //伏虎拳 - if(sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_COMBOFINISH) + if((sd->sc_data[SC_COMBO].timer == -1 || sd->sc_data[SC_COMBO].val1 != MO_COMBOFINISH) && !sd->state.skill_flag) return 0; break; case CH_CHAINCRUSH: //連柱崩? @@ -7619,6 +7659,7 @@ int skill_use_id( struct map_session_data *sd, int target_id, skill_num != MO_EXTREMITYFIST && skill_num != CH_TIGERFIST && skill_num != CH_CHAINCRUSH) || + (skill_num == CH_CHAINCRUSH && sd->state.skill_flag) || (skill_num == MO_EXTREMITYFIST && sd->state.skill_flag) ) pc_stopattack(sd); @@ -7652,11 +7693,17 @@ int skill_use_id( struct map_session_data *sd, int target_id, } break; case MO_COMBOFINISH: /*猛龍拳*/ - case CH_TIGERFIST: /* 伏虎拳 */ +// case CH_TIGERFIST: /* 伏虎拳 */ case CH_CHAINCRUSH: /* 連柱崩? */ target_id = sd->attacktarget; break; + case CH_TIGERFIST: /* 伏虎拳 */ + if(sc_data && sc_data[SC_COMBO].timer != -1 && sc_data[SC_COMBO].val1 == MO_COMBOFINISH) + target_id = sd->attacktarget; + break; + + // -- moonsoul (altered to allow proper usage of extremity from new champion combos) // case MO_EXTREMITYFIST: /*阿修羅覇鳳拳*/ |