summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-04-17 15:43:40 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-04-17 15:43:40 +0000
commit94e745cce4166dea9b34b617cf66b14cfa1faab1 (patch)
treef7c86a380249e7eb197297026e211014a3a24bae /src
parentd5afc60338c63c69ca26211131d98986b6b5ca82 (diff)
downloadhercules-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.c35
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/map.h2
-rw-r--r--src/map/pc.c34
-rw-r--r--src/map/pc.h1
-rw-r--r--src/map/script.c12
-rw-r--r--src/map/skill.c15
-rw-r--r--src/map/status.c68
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;