diff options
author | skotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-04-17 15:43:40 +0000 |
---|---|---|
committer | skotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-04-17 15:43:40 +0000 |
commit | 94e745cce4166dea9b34b617cf66b14cfa1faab1 (patch) | |
tree | f7c86a380249e7eb197297026e211014a3a24bae /src | |
parent | d5afc60338c63c69ca26211131d98986b6b5ca82 (diff) | |
download | hercules-94e745cce4166dea9b34b617cf66b14cfa1faab1.tar.gz hercules-94e745cce4166dea9b34b617cf66b14cfa1faab1.tar.bz2 hercules-94e745cce4166dea9b34b617cf66b14cfa1faab1.tar.xz hercules-94e745cce4166dea9b34b617cf66b14cfa1faab1.zip |
- Expanded the autospell structure to hold a flag, which contains the required Battle Flag conditions required for a skill to trigger.
- Added the required constants to const.txt to specify the autospell trigger properties.
- Added bonus5 bAutoSpell/bAutoSpellWhenHit. The new parameter is used to specify when the spell should trigger (melee/range + weapon/magic/misc attack), see item_bonus for details.
- Applied use of packet 0x28a (clif_changeoption2) to transmit opt3 changes.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@10278 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r-- | src/map/clif.c | 35 | ||||
-rw-r--r-- | src/map/clif.h | 1 | ||||
-rw-r--r-- | src/map/map.h | 2 | ||||
-rw-r--r-- | src/map/pc.c | 34 | ||||
-rw-r--r-- | src/map/pc.h | 1 | ||||
-rw-r--r-- | src/map/script.c | 12 | ||||
-rw-r--r-- | src/map/skill.c | 15 | ||||
-rw-r--r-- | src/map/status.c | 68 |
8 files changed, 125 insertions, 43 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index 8025f7014..f66868b66 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3119,6 +3119,31 @@ int clif_changeoption(struct block_list* bl) return 0; } +int clif_changeoption2(struct block_list* bl) +{ + unsigned char buf[20]; + struct status_change *sc; + + sc = status_get_sc(bl); + if (!sc) return 0; //How can an option change if there's no sc? + + WBUFW(buf,0) = 0x28a; + WBUFL(buf,2) = bl->id; + WBUFL(buf,6) = sc->option; + WBUFL(buf,10) = clif_setlevel(status_get_lv(bl)); + WBUFL(buf,14) = sc->opt3; + if(disguised(bl)) { + clif_send(buf,packet_len(0x28a),bl,AREA_WOS); + WBUFL(buf,2) = -bl->id; + clif_send(buf,packet_len(0x28a),bl,SELF); + WBUFL(buf,2) = bl->id; + WBUFL(buf,6) = OPTION_INVISIBLE; + clif_send(buf,packet_len(0x28a),bl,SELF); + } else + clif_send(buf,packet_len(0x28a),bl,AREA); + return 0; +} + /*========================================== * *------------------------------------------ @@ -12012,7 +12037,7 @@ static int packetdb_readdb(void) int skip_ver = 0; int warned = 0; char *str[64],*p,*str2[64],*p2,w1[64],w2[64]; - int packet_len_table[0x260] = { + int packet_len_table[0x290] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -12067,7 +12092,11 @@ static int packetdb_readdb(void) 12, 26, 9, 11, -1, -1, 10, 2, 282, 11, 4, 36, -1,-1, 4, 2, //#0x0240 -1, -1, -1, -1, -1, 3, 4, 8, -1, 3, 70, 4, 8,12, 4, 10, - 3, 32, -1, 3, 3, 5, 5, 8, 2, 3, -1, -1, 4,-1, 4, 0 + 3, 32, -1, 3, 3, 5, 5, 8, 2, 3, -1, -1, 4,-1, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + //#0x0280 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0 }; struct { void (*func)(int, struct map_session_data *); @@ -12212,7 +12241,7 @@ static int packetdb_readdb(void) // Set server packet lengths - packet_db[SERVER] memset(packet_db,0,sizeof(packet_db)); - for( i = 0; i < 0x260; ++i ) + for( i = 0; i < sizeof(packet_len_table)/sizeof(packet_len_table[0]); ++i ) packet_len(i) = packet_len_table[i]; sprintf(line, "%s/packet_db.txt", db_path); diff --git a/src/map/clif.h b/src/map/clif.h index af5bcdd8d..947f63a9d 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -109,6 +109,7 @@ int clif_unequipitemack(struct map_session_data *,int,int,int); // self int clif_misceffect(struct block_list*,int); // area int clif_misceffect2(struct block_list *bl,int type); int clif_changeoption(struct block_list*); // area +int clif_changeoption2(struct block_list*); // area int clif_useitemack(struct map_session_data*,int,int,int); // self void clif_GlobalMessage(struct block_list* bl, const char* message); int clif_createchat(struct map_session_data*,int); // self diff --git a/src/map/map.h b/src/map/map.h index bfdddcbbd..00f95356a 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -658,7 +658,7 @@ struct map_session_data { // zeroed arrays end here. // zeroed structures start here struct s_autospell{ - short id, lv, rate, card_id; + short id, lv, rate, card_id, flag; } autospell[MAX_PC_BONUS], autospell2[MAX_PC_BONUS]; struct s_addeffect{ short id, rate, arrow_rate; diff --git a/src/map/pc.c b/src/map/pc.c index 90b9217ab..6d0c88b05 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1236,7 +1236,7 @@ static int pc_bonus_autospell_del(struct s_autospell *spell, int max, short id, return rate; } -static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, short rate, short card_id) { +static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, short rate, short flag, short card_id) { int i; if (rate < 0) return //Remove the autobonus. pc_bonus_autospell_del(spell, max, id, lv, -rate, card_id); @@ -1260,6 +1260,7 @@ static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, shor spell[i].id = id; spell[i].lv = lv; spell[i].rate = rate; + spell[i].flag|= flag; spell[i].card_id = card_id; return 1; } @@ -2328,11 +2329,11 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) break; case SP_AUTOSPELL: if(sd->state.lr_flag != 2) - pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, type2, type3, val, current_equip_card_id); + pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, type2, type3, val, BF_WEAPON|BF_SHORT|BF_LONG, current_equip_card_id); break; case SP_AUTOSPELL_WHENHIT: if(sd->state.lr_flag != 2) - pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, type2, type3, val, current_equip_card_id); + pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, type2, type3, val, BF_WEAPON|BF_SHORT|BF_LONG, current_equip_card_id); break; case SP_HP_LOSS_RATE: if(sd->state.lr_flag != 2) { @@ -2421,12 +2422,12 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4 switch(type){ case SP_AUTOSPELL: if(sd->state.lr_flag != 2) - pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, current_equip_card_id); + pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, BF_WEAPON|BF_SHORT|BF_LONG, current_equip_card_id); break; case SP_AUTOSPELL_WHENHIT: if(sd->state.lr_flag != 2) - pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, current_equip_card_id); + pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, BF_WEAPON|BF_SHORT|BF_LONG, current_equip_card_id); break; default: if(battle_config.error_log) @@ -2437,6 +2438,29 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4 return 0; } +int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4,int type5,int val) +{ + nullpo_retr(0, sd); + + switch(type){ + case SP_AUTOSPELL: + if(sd->state.lr_flag != 2) + pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id); + break; + + case SP_AUTOSPELL_WHENHIT: + if(sd->state.lr_flag != 2) + pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id); + break; + default: + if(battle_config.error_log) + ShowWarning("pc_bonus5: unknown type %d %d %d %d %d %d!\n",type,type2,type3,type4,type5,val); + break; + } + + return 0; +} + /*========================================== * Grants a player a given skill. Flag values are: * 0 - Grant skill unconditionally and forever (only this one invokes status_calc_pc, diff --git a/src/map/pc.h b/src/map/pc.h index dc6be203d..a0302cad0 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -165,6 +165,7 @@ int pc_bonus(struct map_session_data*,int,int); int pc_bonus2(struct map_session_data *sd,int,int,int); int pc_bonus3(struct map_session_data *sd,int,int,int,int); int pc_bonus4(struct map_session_data *sd,int,int,int,int,int); +int pc_bonus5(struct map_session_data *sd,int,int,int,int,int,int); int pc_skill(struct map_session_data* sd, int id, int level, int flag); int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip); diff --git a/src/map/script.c b/src/map/script.c index 8e17495ff..691334802 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -3615,6 +3615,7 @@ BUILDIN_FUNC(bonus); BUILDIN_FUNC(bonus2); BUILDIN_FUNC(bonus3); BUILDIN_FUNC(bonus4); +BUILDIN_FUNC(bonus5); BUILDIN_FUNC(skill); BUILDIN_FUNC(addtoskill); // [Valaris] BUILDIN_FUNC(guildskill); @@ -3946,6 +3947,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF2(bonus,"bonus2","iii"), BUILDIN_DEF2(bonus,"bonus3","iiii"), BUILDIN_DEF2(bonus,"bonus4","iiiii"), + BUILDIN_DEF2(bonus,"bonus5","iiiiii"), BUILDIN_DEF(skill,"ii?"), BUILDIN_DEF(addtoskill,"ii?"), // [Valaris] BUILDIN_DEF(guildskill,"ii"), @@ -6558,12 +6560,14 @@ BUILDIN_FUNC(statusup2) /// bonus2 <bonus type>,<val1>,<val2> /// bonus3 <bonus type>,<val1>,<val2>,<val3> /// bonus4 <bonus type>,<val1>,<val2>,<val3>,<val4> +/// bonus4 <bonus type>,<val1>,<val2>,<val3>,<val4>,<val5> BUILDIN_FUNC(bonus) { int type; int type2; int type3; int type4; + int type5; int val; TBL_PC* sd; @@ -6595,6 +6599,14 @@ BUILDIN_FUNC(bonus) val = script_getnum(st,6); pc_bonus4(sd, type, type2, type3, type4, val); break; + case 7: + type2 = script_getnum(st,3); + type3 = script_getnum(st,4); + type4 = script_getnum(st,5); + type5 = script_getnum(st,6); + val = script_getnum(st,7); + pc_bonus5(sd, type, type2, type3, type4, type5, val); + break; default: ShowDebug("buildin_bonus: unexpected last data (%d)\n", script_lastdata(st)); } diff --git a/src/map/skill.c b/src/map/skill.c index 74e254333..08e0f518a 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1413,14 +1413,16 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int //Reports say that autospell effects get triggered on skills and pretty much everything including splash attacks. [Skotlex] //But Gravity Patched this silently, and it now seems to trigger only on //weapon attacks. - if(sd && !status_isdead(bl) && src != bl && attack_type&BF_WEAPON -// !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE) - ) { + if(sd && !status_isdead(bl) && src != bl && sd->autospell[0].id) { struct block_list *tbl; struct unit_data *ud; int i, skilllv; for (i = 0; i < MAX_PC_BONUS && sd->autospell[i].id; i++) { + if(!(sd->autospell[i].flag&attack_type&BF_RANGEMASK && + sd->autospell[i].flag&attack_type&BF_WEAPONMASK)) + continue; //Attack type or range type did not match. + skill = (sd->autospell[i].id > 0) ? sd->autospell[i].id : -sd->autospell[i].id; if (skillnotok(skill, sd)) @@ -1582,7 +1584,8 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * } //Trigger counter-spells to retaliate against damage causing skills. [Skotlex] - if(dstsd && !status_isdead(bl) && src != bl && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE)) + if(dstsd && !status_isdead(bl) && src != bl && dstsd->autospell2[0].id && + !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE)) { struct block_list *tbl; struct unit_data *ud; @@ -1590,6 +1593,10 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * for (i = 0; i < MAX_PC_BONUS && dstsd->autospell2[i].id; i++) { + if(!(dstsd->autospell2[i].flag&attack_type&BF_RANGEMASK && + dstsd->autospell2[i].flag&attack_type&BF_WEAPONMASK)) + continue; //Attack type or range type did not match. + skillid = (dstsd->autospell2[i].id > 0) ? dstsd->autospell2[i].id : -dstsd->autospell2[i].id; skilllv = dstsd->autospell2[i].lv?dstsd->autospell2[i].lv:1; if (skilllv < 0) skilllv = 1+rand()%(-skilllv); diff --git a/src/map/status.c b/src/map/status.c index cdf74be31..564d10d08 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -5861,18 +5861,18 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val case SC_SPEARQUICKEN: case SC_CONCENTRATION: sc->opt3 |= 0x1; - opt_flag = 0; + opt_flag = 2; break; case SC_MAXOVERTHRUST: case SC_OVERTHRUST: case SC_SWOO: //Why does it shares the same opt as Overthrust? Perhaps we'll never know... sc->opt3 |= 0x2; - opt_flag = 0; + opt_flag = 2; break; case SC_ENERGYCOAT: case SC_SKE: sc->opt3 |= 0x4; - opt_flag = 0; + opt_flag = 2; break; case SC_INCATKRATE: //Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex] @@ -5882,39 +5882,39 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val } case SC_EXPLOSIONSPIRITS: sc->opt3 |= 0x8; - opt_flag = 0; + opt_flag = 2; break; case SC_STEELBODY: case SC_SKA: sc->opt3 |= 0x10; - opt_flag = 0; + opt_flag = 2; break; case SC_BLADESTOP: sc->opt3 |= 0x20; - opt_flag = 0; + opt_flag = 2; break; //0x40 missing? case SC_BERSERK: sc->opt3 |= 0x80; - opt_flag = 0; + opt_flag = 2; break; //0x100, 0x200 missing? case SC_MARIONETTE: case SC_MARIONETTE2: sc->opt3 |= 0x400; - opt_flag = 0; + opt_flag = 2; break; case SC_ASSUMPTIO: sc->opt3 |= 0x800; - opt_flag = 0; + opt_flag = 2; break; case SC_WARM: //SG skills [Komurka] sc->opt3 |= 0x1000; - opt_flag = 0; + opt_flag = 2; break; case SC_KAITE: sc->opt3 |= 0x2000; - opt_flag = 0; + opt_flag = 2; break; //OPTION case SC_HIDING: @@ -5950,8 +5950,12 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val //On Aegis, when turning on a status change, first goes the option packet, // then the sc packet. - if(opt_flag) - clif_changeoption(bl); + if(opt_flag) { + if (opt_flag == 2) + clif_changeoption2(bl); + else + clif_changeoption(bl); + } if (calc_flag&SCB_DYE) { //Reset DYE color @@ -6371,15 +6375,15 @@ int status_change_end( struct block_list* bl , int type,int tid ) case SC_HIDING: sc->option &= ~OPTION_HIDE; - opt_flag|= 2|4; //Check for warp trigger + AoE trigger + opt_flag|= 8|4; //Check for warp trigger + AoE trigger break; case SC_CLOAKING: sc->option &= ~OPTION_CLOAK; - opt_flag|= 2; + opt_flag|= 8; break; case SC_CHASEWALK: sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK); - opt_flag|= 2; + opt_flag|= 8; break; case SC_SIGHT: sc->option &= ~OPTION_SIGHT; @@ -6405,55 +6409,55 @@ int status_change_end( struct block_list* bl , int type,int tid ) case SC_SPEARQUICKEN: case SC_CONCENTRATION: sc->opt3 &= ~0x1; - opt_flag = 0; + opt_flag = 2; break; case SC_OVERTHRUST: case SC_MAXOVERTHRUST: case SC_SWOO: sc->opt3 &= ~0x2; - opt_flag = 0; + opt_flag = 2; break; case SC_ENERGYCOAT: case SC_SKE: sc->opt3 &= ~0x4; - opt_flag = 0; + opt_flag = 2; break; case SC_INCATKRATE: //Simulated Explosion spirits effect. if (bl->type != BL_MOB) break; case SC_EXPLOSIONSPIRITS: sc->opt3 &= ~0x8; - opt_flag = 0; + opt_flag = 2; break; case SC_STEELBODY: case SC_SKA: sc->opt3 &= ~0x10; - opt_flag = 0; + opt_flag = 2; break; case SC_BLADESTOP: sc->opt3 &= ~0x20; - opt_flag = 0; + opt_flag = 2; break; case SC_BERSERK: sc->opt3 &= ~0x80; - opt_flag = 0; + opt_flag = 2; break; case SC_MARIONETTE: case SC_MARIONETTE2: sc->opt3 &= ~0x400; - opt_flag = 0; + opt_flag = 2; break; case SC_ASSUMPTIO: sc->opt3 &= ~0x800; - opt_flag = 0; + opt_flag = 2; break; case SC_WARM: //SG skills [Komurka] sc->opt3 &= ~0x1000; - opt_flag = 0; + opt_flag = 2; break; case SC_KAITE: sc->opt3 &= ~0x2000; - opt_flag = 0; + opt_flag = 2; break; default: opt_flag = 0; @@ -6472,8 +6476,12 @@ int status_change_end( struct block_list* bl , int type,int tid ) else if (sd) clif_status_load(bl,StatusIconChangeTable[type],0); - if(opt_flag) - clif_changeoption(bl); + if(opt_flag) { + if (opt_flag & 2) + clif_changeoption2(bl); + else + clif_changeoption(bl); + } if (calc_flag) status_calc_bl(bl,calc_flag); @@ -6481,7 +6489,7 @@ int status_change_end( struct block_list* bl , int type,int tid ) if(opt_flag&4) //Out of hiding, invoke on place. skill_unit_move(bl,gettick(),1); - if(opt_flag&2 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC)) + if(opt_flag&8 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC)) npc_touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event. return 1; |