summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/battle.c17
-rw-r--r--src/map/pc.c178
-rw-r--r--src/map/pc.h19
-rw-r--r--src/map/script.c145
-rw-r--r--src/map/skill.c58
-rw-r--r--src/map/status.c52
-rw-r--r--src/map/status.h36
-rw-r--r--src/map/unit.c7
8 files changed, 274 insertions, 238 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 17f052bb0..505d37373 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -1786,12 +1786,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
}
}
- if( sc && sc->count && sc->data[SC_DEFRATIOATK]
- && !is_boss(target)
- && skill_num != PA_SACRIFICE && skill_num != CR_GRANDCROSS && skill_num != NPC_GRANDDARKNESS && skill_num != PA_SHIELDCHAIN
- && !flag.cri )
- flag.pdef = flag.pdef2 = sc->data[SC_DEFRATIOATK]->val1; // Occult Impact Effect
-
if (!flag.idef || !flag.idef2)
{ //Defense reduction
short vit_def;
@@ -1806,19 +1800,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
{
if( i > 100 ) i = 100;
def1 -= def1 * i / 100;
- // def2 -= def2 * i / 100;
+ def2 -= def2 * i / 100;
}
}
- if( sc && sc->count && sc->data[SC_IGNOREDEF]
- && !is_boss(target)
- && skill_num != CR_GRANDCROSS && skill_num != NPC_GRANDDARKNESS )
- {
- i = cap_value(sc->data[SC_IGNOREDEF]->val1,1,100);
- def1 -= def1 * i / 100;
- def2 -= def2 * i / 100;
- }
-
if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type )
{
unsigned char target_count; //256 max targets should be a sane max
diff --git a/src/map/pc.c b/src/map/pc.c
index 3c596ec13..a378e0bfe 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -804,7 +804,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
sd->followtimer = INVALID_TIMER; // [MouseJstr]
sd->invincible_timer = INVALID_TIMER;
- sd->npc_timer_id = -1;
+ sd->npc_timer_id = INVALID_TIMER;
sd->pvp_timer = INVALID_TIMER;
sd->canuseitem_tick = tick;
@@ -813,7 +813,13 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
sd->cansendmail_tick = tick;
for(i = 0; i < MAX_SKILL_LEVEL; i++)
- sd->spirit_timer[i] = -1;
+ sd->spirit_timer[i] = INVALID_TIMER;
+ for(i = 0; i < ARRAYLENGTH(sd->autobonus); i++)
+ sd->autobonus[i].active = INVALID_TIMER;
+ for(i = 0; i < ARRAYLENGTH(sd->autobonus2); i++)
+ sd->autobonus2[i].active = INVALID_TIMER;
+ for(i = 0; i < ARRAYLENGTH(sd->autobonus3); i++)
+ sd->autobonus3[i].active = INVALID_TIMER;
if (battle_config.item_auto_get)
sd->state.autoloot = 10000;
@@ -1406,59 +1412,6 @@ int pc_disguise(struct map_session_data *sd, int class_)
return 1;
}
-int pc_autoscript_add(struct s_autoscript *scripts, int max, short rate, short flag, short target, struct script_code *script, bool onskill)
-{
- int i;
- ARR_FIND(0, max, i, scripts[i].script == NULL);
- if( i == max )
- {
- ShowWarning("pc_autoscript_bonus: Reached max (%d) number of autoscripts per character!\n", max);
- return 0;
- }
-
- scripts[i].script = script;
- scripts[i].rate = rate;
- scripts[i].target = target; // 0 = Script on Self 1 = Script on Target
-
- if( !onskill )
- { // Auto-update flag value.
- if( !(flag&BF_RANGEMASK) )
- flag|=BF_SHORT|BF_LONG; //No range defined? Use both.
- if( !(flag&BF_WEAPONMASK) )
- flag|=BF_WEAPON; //No attack type defined? Use weapon.
- if( !(flag&BF_SKILLMASK) )
- {
- if( flag&(BF_MAGIC|BF_MISC) )
- flag|=BF_SKILL; //These two would never trigger without BF_SKILL
- if( flag&BF_WEAPON )
- flag|=BF_NORMAL|BF_SKILL;
- }
- }
- scripts[i].flag = flag;
- return 1;
-}
-
-void pc_autoscript_clear(struct map_session_data *sd)
-{
- int i;
-
- if( sd->state.autocast )
- return;
-
- for (i = 0; i < MAX_PC_BONUS && sd->autoscript[i].script; i++)
- script_free_code(sd->autoscript[i].script);
-
- for (i = 0; i < MAX_PC_BONUS && sd->autoscript2[i].script; i++)
- script_free_code(sd->autoscript2[i].script);
-
- for (i = 0; i < MAX_PC_BONUS && sd->autoscript3[i].script; i++)
- script_free_code(sd->autoscript3[i].script);
-
- memset(&sd->autoscript, 0, sizeof(sd->autoscript));
- memset(&sd->autoscript2, 0, sizeof(sd->autoscript2));
- memset(&sd->autoscript3, 0, sizeof(sd->autoscript3));
-}
-
static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, short rate, short flag, short card_id)
{
int i;
@@ -1626,6 +1579,107 @@ static int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id
return 1;
}
+int pc_addautobonus(struct s_autobonus *bonus,char max,struct script_code *script,short rate,unsigned int dur,short flag,struct script_code *other_script,unsigned short pos,bool onskill)
+{
+ int i;
+
+ ARR_FIND(0, max, i, bonus[i].rate == 0);
+ if( i == max )
+ {
+ ShowWarning("pc_addautobonus: Reached max (%d) number of autobonus per character!\n", max);
+ return 0;
+ }
+
+ if( !onskill )
+ {
+ if( !(flag&BF_RANGEMASK) )
+ flag|=BF_SHORT|BF_LONG; //No range defined? Use both.
+ if( !(flag&BF_WEAPONMASK) )
+ flag|=BF_WEAPON; //No attack type defined? Use weapon.
+ if( !(flag&BF_SKILLMASK) )
+ {
+ if( flag&(BF_MAGIC|BF_MISC) )
+ flag|=BF_SKILL; //These two would never trigger without BF_SKILL
+ if( flag&BF_WEAPON )
+ flag|=BF_NORMAL|BF_SKILL;
+ }
+ }
+
+ bonus[i].rate = rate;
+ bonus[i].duration = dur;
+ bonus[i].active = INVALID_TIMER;
+ bonus[i].atk_type = flag;
+ bonus[i].pos = pos;
+ bonus[i].bonus_script = script;
+ bonus[i].other_script = other_script;
+ return 1;
+}
+
+int pc_delautobonus(struct map_session_data* sd, struct s_autobonus *autobonus,char max,bool restore)
+{
+ int i;
+ nullpo_retr(0, sd);
+
+ for( i = 0; i < max; i++ )
+ {
+ if( autobonus[i].active != INVALID_TIMER && ( !restore || (autobonus[i].pos && !(sd->state.autobonus&autobonus[i].pos)) ) )
+ { // Logout / Unequipped an item with an activated bonus
+ delete_timer(autobonus[i].active,pc_endautobonus);
+ autobonus[i].active = INVALID_TIMER;
+ }
+
+ if( restore && sd->state.autobonus&autobonus[i].pos )
+ {
+ if( autobonus[i].active != INVALID_TIMER )
+ run_script(autobonus[i].bonus_script,0,sd->bl.id,0);
+ continue;
+ }
+
+ if( sd->state.autocast )
+ continue;
+
+ if( autobonus[i].bonus_script )
+ script_free_code(autobonus[i].bonus_script);
+ if( autobonus[i].other_script )
+ script_free_code(autobonus[i].other_script);
+ autobonus[i].rate = autobonus[i].atk_type = autobonus[i].duration = autobonus[i].pos = 0;
+ autobonus[i].bonus_script = autobonus[i].other_script = NULL;
+ autobonus[i].active = INVALID_TIMER;
+ }
+
+ return 0;
+}
+
+int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus)
+{
+ nullpo_retr(0, sd);
+ nullpo_retr(0, autobonus);
+
+ if( autobonus->bonus_script )
+ run_script(autobonus->bonus_script,0,sd->bl.id,0);
+ if( autobonus->other_script )
+ run_script(autobonus->other_script,0,sd->bl.id,0);
+
+ autobonus->active = add_timer(gettick()+autobonus->duration, pc_endautobonus, sd->bl.id, (intptr)autobonus);
+ sd->state.autobonus |= autobonus->pos;
+
+ return 0;
+}
+
+int pc_endautobonus(int tid, unsigned int tick, int id, intptr data)
+{
+ struct map_session_data *sd = map_id2sd(id);
+ struct s_autobonus *autobonus = (struct s_autobonus *)data;
+
+ nullpo_retr(0, sd);
+ nullpo_retr(0, autobonus);
+
+ autobonus->active = INVALID_TIMER;
+ sd->state.autobonus &= ~autobonus->pos;
+ status_calc_pc(sd,0);
+ return 0;
+}
+
/*==========================================
* ? 備品による能力等のボ?ナス設定
*------------------------------------------*/
@@ -5240,16 +5294,6 @@ int pc_skillatk_bonus(struct map_session_data *sd, int skill_num)
ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == skill_num);
if( i < ARRAYLENGTH(sd->skillatk) ) bonus = sd->skillatk[i].val;
- if( sd->sc.data[SC_SKILLATKBONUS] )
- {
- if( sd->sc.data[SC_SKILLATKBONUS]->val1 && sd->sc.data[SC_SKILLATKBONUS]->val1 == skill_num )
- bonus += sd->sc.data[SC_SKILLATKBONUS]->val4;
- if( sd->sc.data[SC_SKILLATKBONUS]->val2 && sd->sc.data[SC_SKILLATKBONUS]->val2 == skill_num )
- bonus += sd->sc.data[SC_SKILLATKBONUS]->val4;
- if( sd->sc.data[SC_SKILLATKBONUS]->val3 && sd->sc.data[SC_SKILLATKBONUS]->val3 == skill_num )
- bonus += sd->sc.data[SC_SKILLATKBONUS]->val4;
- }
-
return bonus;
}
@@ -6966,6 +7010,9 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
status_change_end(&sd->bl, SC_ARMOR_RESIST, -1);
}
+ if( sd->state.autobonus&sd->status.inventory[n].equip )
+ sd->state.autobonus &= ~sd->status.inventory[n].equip; //Check for activated autobonus [Inkfish]
+
sd->status.inventory[n].equip=0;
if(flag&1) {
@@ -7920,6 +7967,7 @@ int do_init_pc(void)
add_timer_func_list(pc_autosave, "pc_autosave");
add_timer_func_list(pc_spiritball_timer, "pc_spiritball_timer");
add_timer_func_list(pc_follow_timer, "pc_follow_timer");
+ add_timer_func_list(pc_endautobonus, "pc_endautobonus");
add_timer(gettick() + autosave_interval, pc_autosave, 0, 0);
diff --git a/src/map/pc.h b/src/map/pc.h
index 3d09ebcbe..90e055c17 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -67,9 +67,13 @@ struct s_add_drop {
int race, rate;
};
-struct s_autoscript {
- unsigned short rate, flag, target;
- struct script_code *script;
+struct s_autobonus {
+ short rate,atk_type;
+ unsigned int duration;
+ struct script_code *bonus_script;
+ struct script_code *other_script;
+ int active;
+ unsigned short pos;
};
struct map_session_data {
@@ -126,6 +130,7 @@ struct map_session_data {
unsigned int bg_id;
unsigned skillonskill : 1;
unsigned short user_font;
+ unsigned short autobonus;
} state;
struct {
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
@@ -243,7 +248,7 @@ struct map_session_data {
} itemhealrate[MAX_PC_BONUS];
// zeroed structures end here
// manually zeroed structures start here.
- struct s_autoscript autoscript[MAX_PC_BONUS], autoscript2[MAX_PC_BONUS], autoscript3[MAX_PC_BONUS]; //Auto script on attack, when attacked, on skill usage
+ struct s_autobonus autobonus[MAX_PC_BONUS], autobonus2[MAX_PC_BONUS], autobonus3[MAX_PC_BONUS]; //Auto script on attack, when attacked, on skill usage
// manually zeroed structures end here.
// zeroed vars start here.
int arrow_atk,arrow_ele,arrow_cri,arrow_hit;
@@ -571,8 +576,10 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd,
int pc_updateweightstatus(struct map_session_data *sd);
-int pc_autoscript_add(struct s_autoscript *scripts, int max, short rate, short flag, short target, struct script_code *script, bool onskill);
-void pc_autoscript_clear(struct map_session_data *sd);
+int pc_addautobonus(struct s_autobonus *bonus,char max,struct script_code *script,short rate,unsigned int dur,short atk_type,struct script_code *other_script,unsigned short pos,bool onskill);
+int pc_exeautobonus(struct map_session_data* sd,struct s_autobonus *bonus);
+int pc_endautobonus(int tid, unsigned int tick, int id, intptr data);
+int pc_delautobonus(struct map_session_data* sd,struct s_autobonus *bonus,char max,bool restore);
int pc_bonus(struct map_session_data*,int,int);
int pc_bonus2(struct map_session_data *sd,int,int,int);
diff --git a/src/map/script.c b/src/map/script.c
index dd4022220..9edab3e2a 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -6624,87 +6624,121 @@ BUILDIN_FUNC(bonus)
return 0;
}
-/// Bonus script that has a chance of being executed on attack.
-BUILDIN_FUNC(bonusautoscript)
+BUILDIN_FUNC(autobonus)
{
- int rate, flag = 0, target = 0;
- const char *str;
- struct script_code *script;
+ unsigned int dur;
+ short rate;
+ short atk_type = 0;
TBL_PC* sd;
+ struct script_code *bonus_script;
+ struct script_code *other_script = NULL;
sd = script_rid2sd(st);
if( sd == NULL )
- return 0;// no player attached, report source
+ return 0; // no player attached
+ if( sd->state.autocast )
+ return 0;
+ if( sd->state.autobonus&sd->status.inventory[current_equip_item_index].equip )
+ return 0;
- str = script_getstr(st,2);
+ bonus_script = parse_script(script_getstr(st,2), "autobonus bonus", 0, 0);
rate = script_getnum(st,3);
- if( script_hasdata(st,4) )
- flag = script_getnum(st,4);
+ dur = script_getnum(st,4);
+
+ if( !bonus_script || !rate || !dur )
+ return 0;
+
if( script_hasdata(st,5) )
- target = script_getnum(st,5);
- script = parse_script(str, "autoscript bonus", 0, 0);
- if( !script )
- return 1;
- if( sd->state.autocast || !pc_autoscript_add(sd->autoscript, ARRAYLENGTH(sd->autoscript), rate, flag, target, script, false) )
+ atk_type = script_getnum(st,5);
+ if( script_hasdata(st,6) )
+ other_script = parse_script(script_getstr(st,6), "autobonus other", 0, 0);
+
+ if( !pc_addautobonus(sd->autobonus,ARRAYLENGTH(sd->autobonus),bonus_script,rate,dur,atk_type,other_script,sd->status.inventory[current_equip_item_index].equip,false) )
{
- script_free_code(script);
- return 1;
+ if( bonus_script )
+ script_free_code(bonus_script);
+ if( other_script )
+ script_free_code(other_script);
}
- return 0;
+
+ return 0;
}
-/// Bonus script that has a chance of being executed when attacked.
-BUILDIN_FUNC(bonusautoscript2)
+
+BUILDIN_FUNC(autobonus2)
{
- int rate, flag = 0, target = 0;
- const char *str;
- struct script_code *script;
+ unsigned int dur;
+ short rate;
+ short atk_type = 0;
TBL_PC* sd;
+ struct script_code *bonus_script;
+ struct script_code *other_script = NULL;
sd = script_rid2sd(st);
if( sd == NULL )
- return 0;// no player attached, report source
+ return 0; // no player attached
+ if( sd->state.autocast )
+ return 0;
+ if( sd->state.autobonus&sd->status.inventory[current_equip_item_index].equip )
+ return 0;
- str = script_getstr(st,2);
+ bonus_script = parse_script(script_getstr(st,2), "autobonus bonus", 0, 0);
rate = script_getnum(st,3);
- if( script_hasdata(st,4) )
- flag = script_getnum(st,4);
+ dur = script_getnum(st,4);
+
+ if( !bonus_script || !rate || !dur )
+ return 0;
+
if( script_hasdata(st,5) )
- target = script_getnum(st,5);
- script = parse_script(str, "autoscript2 bonus", 0, 0);
- if (!script)
- return 1;
- if( sd->state.autocast || !pc_autoscript_add(sd->autoscript2, ARRAYLENGTH(sd->autoscript2), rate, flag, target, script, false) )
+ atk_type = script_getnum(st,5);
+ if( script_hasdata(st,6) )
+ other_script = parse_script(script_getstr(st,6), "autobonus2 other", 0, 0);
+
+ if( !pc_addautobonus(sd->autobonus2,ARRAYLENGTH(sd->autobonus2),bonus_script,rate,dur,atk_type,other_script,sd->status.inventory[current_equip_item_index].equip,false) )
{
- script_free_code(script);
- return 1;
+ if( bonus_script )
+ script_free_code(bonus_script);
+ if( other_script )
+ script_free_code(other_script);
}
- return 0;
+
+ return 0;
}
-/// Bonus script that has a chance of being executed when used a skill
-BUILDIN_FUNC(bonusautoscript3)
+
+BUILDIN_FUNC(autobonus3)
{
- int rate, skill, target = 0;
- const char *str;
- struct script_code *script;
+ unsigned int dur;
+ short rate,atk_type;
TBL_PC* sd;
+ struct script_code *bonus_script;
+ struct script_code *other_script = NULL;
sd = script_rid2sd(st);
if( sd == NULL )
- return 0;// no player attached, report source
+ return 0; // no player attached
+ if( sd->state.autocast )
+ return 0;
+ if( sd->state.autobonus&sd->status.inventory[current_equip_item_index].equip )
+ return 0;
- str = script_getstr(st,2);
+ bonus_script = parse_script(script_getstr(st,2), "autobonus bonus", 0, 0);
rate = script_getnum(st,3);
- skill = ( script_isstring(st,4) ? skill_name2id(script_getstr(st,4)) : script_getnum(st,4) );
- if( script_hasdata(st,5) )
- target = script_getnum(st,5);
- script = parse_script(str, "autoscript3 bonus", 0, 0);
- if( !script )
- return 1;
- if( sd->state.autocast || !pc_autoscript_add(sd->autoscript3, ARRAYLENGTH(sd->autoscript3), rate, skill, target, script, true) )
+ dur = script_getnum(st,4);
+ atk_type = ( script_isstring(st,5) ? skill_name2id(script_getstr(st,5)) : script_getnum(st,5) );
+
+ if( !bonus_script || !rate || !dur || !atk_type )
+ return 0;
+
+ if( script_hasdata(st,6) )
+ other_script = parse_script(script_getstr(st,6), "autobonus3 other", 0, 0);
+
+ if( !pc_addautobonus(sd->autobonus3,ARRAYLENGTH(sd->autobonus3),bonus_script,rate,dur,atk_type,other_script,sd->status.inventory[current_equip_item_index].equip,true) )
{
- script_free_code(script);
- return 1;
+ if( bonus_script )
+ script_free_code(bonus_script);
+ if( other_script )
+ script_free_code(other_script);
}
+
return 0;
}
@@ -14029,7 +14063,7 @@ static int buildin_mobuseskill_sub(struct block_list *bl,va_list ap)
int skillid = va_arg(ap,int);
int skilllv = va_arg(ap,int);
int casttime = va_arg(ap,int);
- bool cancel = va_arg(ap,bool);
+ int cancel = va_arg(ap,int);
int emotion = va_arg(ap,int);
int target = va_arg(ap,int);
@@ -14066,8 +14100,7 @@ static int buildin_mobuseskill_sub(struct block_list *bl,va_list ap)
BUILDIN_FUNC(areamobuseskill)
{
struct block_list center;
- int m,range,mobid,skillid,skilllv,casttime,emotion,target;
- bool cancel;
+ int m,range,mobid,skillid,skilllv,casttime,emotion,target,cancel;
if( (m = map_mapname2mapid(script_getstr(st,2))) < 0 )
{
@@ -14185,9 +14218,9 @@ struct script_function buildin_func[] = {
BUILDIN_DEF2(bonus,"bonus3","ivii"),
BUILDIN_DEF2(bonus,"bonus4","ivvii"),
BUILDIN_DEF2(bonus,"bonus5","ivviii"),
- BUILDIN_DEF(bonusautoscript,"si??"),
- BUILDIN_DEF(bonusautoscript2,"si??"),
- BUILDIN_DEF(bonusautoscript3,"siv?"),
+ BUILDIN_DEF(autobonus,"sii??"),
+ BUILDIN_DEF(autobonus2,"sii??"),
+ BUILDIN_DEF(autobonus3,"siiv?"),
BUILDIN_DEF(skill,"vi?"),
BUILDIN_DEF(addtoskill,"vi?"), // [Valaris]
BUILDIN_DEF(guildskill,"vi"),
diff --git a/src/map/skill.c b/src/map/skill.c
index 27bf689ac..6c6bb0cf0 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -1042,20 +1042,22 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
}
}
- //Auto-script when attacking
- if( sd && sd->autoscript[0].script )
+ //Autobonus when attacking
+ if( sd && sd->autobonus[0].rate )
{
int i;
- for( i = 0; i < ARRAYLENGTH(sd->autoscript) && sd->autoscript[i].script; i++ )
+ for( i = 0; i < ARRAYLENGTH(sd->autobonus); i++ )
{
- if(!(sd->autoscript[i].flag&attack_type&BF_WEAPONMASK &&
- sd->autoscript[i].flag&attack_type&BF_RANGEMASK &&
- sd->autoscript[i].flag&attack_type&BF_SKILLMASK))
- continue; // one or more trigger conditions were not fulfilled
- if( rand()%1000 > sd->autoscript[i].rate )
+ if( rand()%1000 > sd->autobonus[i].rate )
+ continue;
+ if( sd->autobonus[i].active != INVALID_TIMER )
continue;
+ if(!(sd->autobonus[i].atk_type&attack_type&BF_WEAPONMASK &&
+ sd->autobonus[i].atk_type&attack_type&BF_RANGEMASK &&
+ sd->autobonus[i].atk_type&attack_type&BF_SKILLMASK))
+ continue; // one or more trigger conditions were not fulfilled
sd->state.autocast = 1;
- run_script(sd->autoscript[i].script,0,sd->autoscript[i].target?bl->id:src->id,0);
+ pc_exeautobonus(sd,&sd->autobonus[i]);
sd->state.autocast = 0;
}
}
@@ -1128,18 +1130,18 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, int s
sd->state.autocast = 0;
}
- if( sd->autoscript3[0].script )
+ if( sd && sd->autobonus3[0].rate )
{
- for( i = 0; i < ARRAYLENGTH(sd->autoscript3) && sd->autoscript3[i].script; i++ )
+ for( i = 0; i < ARRAYLENGTH(sd->autobonus3); i++ )
{
- if( sd->autoscript3[i].flag != skillid )
+ if( rand()%1000 > sd->autobonus3[i].rate )
continue;
- if( sd->autoscript3[i].target && bl == NULL )
+ if( sd->autobonus3[i].active != INVALID_TIMER )
continue;
- if( rand()%1000 > sd->autoscript3[i].rate )
+ if( sd->autobonus3[i].atk_type != skillid )
continue;
sd->state.autocast = 1;
- run_script(sd->autoscript3[i].script,0,sd->bl.id,0);
+ pc_exeautobonus(sd,&sd->autobonus3[i]);
sd->state.autocast = 0;
}
}
@@ -1316,20 +1318,23 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
}
}
}
- //Auto-script when attacked
- if( dstsd && !status_isdead(bl) && dstsd->autoscript2[0].script && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE) )
+
+ //Autobonus when attacked
+ if( dstsd && !status_isdead(bl) && dstsd->autobonus2[0].rate && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE) )
{
int i;
- for( i = 0; i < ARRAYLENGTH(dstsd->autoscript2) && dstsd->autoscript2[i].script; i++ )
+ for( i = 0; i < ARRAYLENGTH(dstsd->autobonus2); i++ )
{
- if(!(dstsd->autoscript2[i].flag&attack_type&BF_WEAPONMASK &&
- dstsd->autoscript2[i].flag&attack_type&BF_RANGEMASK &&
- dstsd->autoscript2[i].flag&attack_type&BF_SKILLMASK))
- continue; // one or more trigger conditions were not fulfilled
- if( rand()%1000 > dstsd->autoscript2[i].rate )
+ if( rand()%1000 > dstsd->autobonus2[i].rate )
+ continue;
+ if( dstsd->autobonus2[i].active != INVALID_TIMER )
continue;
+ if(!(dstsd->autobonus2[i].atk_type&attack_type&BF_WEAPONMASK &&
+ dstsd->autobonus2[i].atk_type&attack_type&BF_RANGEMASK &&
+ dstsd->autobonus2[i].atk_type&attack_type&BF_SKILLMASK))
+ continue; // one or more trigger conditions were not fulfilled
dstsd->state.autocast = 1;
- run_script(dstsd->autoscript2[i].script,0,dstsd->autoscript2[i].target?src->id:bl->id,0);
+ pc_exeautobonus(dstsd,&dstsd->autobonus2[i]);
dstsd->state.autocast = 0;
}
}
@@ -8984,9 +8989,6 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv)
}
}
- if( sc && sc->count && sc->data[SC_SKILLCASTRATE] && (sc->data[SC_SKILLCASTRATE]->val1 == skill_id || sc->data[SC_SKILLCASTRATE]->val2 == skill_id || sc->data[SC_SKILLCASTRATE]->val3 == skill_id) )
- time += time * sc->data[SC_SKILLCASTRATE]->val4 / 100;
-
// config cast time multiplier
if (battle_config.cast_rate != 100)
time = time * battle_config.cast_rate / 100;
@@ -9005,8 +9007,6 @@ int skill_castfix_sc (struct block_list *bl, int time)
if (sc && sc->count) {
if (sc->data[SC_SLOWCAST])
time += time * sc->data[SC_SLOWCAST]->val2 / 100;
- if (sc->data[SC_FASTCAST])
- time -= time * sc->data[SC_FASTCAST]->val1 / 100;
if (sc->data[SC_SUFFRAGIUM]) {
time -= time * sc->data[SC_SUFFRAGIUM]->val2 / 100;
status_change_end(bl, SC_SUFFRAGIUM, -1);
diff --git a/src/map/status.c b/src/map/status.c
index 2955520c6..6a3acd8cf 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -518,14 +518,11 @@ void initChangeTables(void)
StatusChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE;
StatusChangeFlagTable[SC_INCCRI] |= SCB_CRI;
StatusChangeFlagTable[SC_INCFLEE2] |= SCB_FLEE2;
- StatusChangeFlagTable[SC_INCDEF] |= SCB_DEF;
StatusChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP;
StatusChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP;
- StatusChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD;
StatusChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK;
StatusChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK;
StatusChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF;
- StatusChangeFlagTable[SC_INCBASEATK] |= SCB_BATK;
StatusChangeFlagTable[SC_STRFOOD] |= SCB_STR;
StatusChangeFlagTable[SC_AGIFOOD] |= SCB_AGI;
StatusChangeFlagTable[SC_VITFOOD] |= SCB_VIT;
@@ -1782,8 +1779,6 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
+ sizeof(sd->add_drop)
+ sizeof(sd->itemhealrate)
);
- // clear autoscripts...
- pc_autoscript_clear(sd);
// vars zeroing. ints, shorts, chars. in that order.
memset (&sd->arrow_atk, 0,sizeof(sd->arrow_atk)
@@ -1835,6 +1830,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
+ sizeof(sd->unstripable_equip)
);
+ // Autobonus
+ pc_delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true);
+ pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus),true);
+ pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus),true);
+
// Parse equipment.
for(i=0;i<EQI_MAX-1;i++) {
current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
@@ -3382,8 +3382,6 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
if(!sc || !sc->count)
return cap_value(batk,0,USHRT_MAX);
- if(sc->data[SC_INCBASEATK])
- batk += sc->data[SC_INCBASEATK]->val1;
if(sc->data[SC_ATKPOTION])
batk += sc->data[SC_ATKPOTION]->val1;
if(sc->data[SC_BATKFOOD])
@@ -3602,8 +3600,6 @@ static signed char status_calc_def(struct block_list *bl, struct status_change *
return 90;
if(sc->data[SC_STEELBODY])
return 90;
- if(sc->data[SC_INCDEF])
- def += sc->data[SC_INCDEF]->val1;
if(sc->data[SC_ARMORCHANGE])
def += sc->data[SC_ARMORCHANGE]->val2;
if(sc->data[SC_DRUMBATTLE])
@@ -3914,8 +3910,6 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
aspd_rate -= 200;
}
- if(sc->data[SC_INCASPDRATE])
- aspd_rate -= sc->data[SC_INCASPDRATE]->val2;
if(sc->data[i=SC_ASPDPOTION3] ||
sc->data[i=SC_ASPDPOTION2] ||
sc->data[i=SC_ASPDPOTION1] ||
@@ -5023,9 +5017,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (sce->val2 > val2)
return 0;
break;
- case SC_HPREGEN:
- case SC_HPDRAIN:
- case SC_SPREGEN:
case SC_S_LIFEPOTION:
case SC_L_LIFEPOTION:
case SC_BOSSMAPINFO:
@@ -5355,9 +5346,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (!val4) val4 = 1;
tick = 10000;
break;
- case SC_HPREGEN:
- case SC_HPDRAIN:
- case SC_SPREGEN:
case SC_S_LIFEPOTION:
case SC_L_LIFEPOTION:
if( val1 == 0 ) return 0;
@@ -5897,7 +5885,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (val1 < 0)
val1 = 0;
break;
- case SC_INCASPDRATE:
case SC_INCFLEE2:
case SC_INCCRI:
val2 = val1*10; //Actual boost (since 100% = 1000)
@@ -5923,7 +5910,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
// Mod your resistance against elements:
// val1 = water | val2 = earth | val3 = fire | val4 = wind
// break;
- case SC_FASTCAST:
+ //case ????:
//Place here SCs that have no SCB_* data, no skill associated, no ICON
//associated, and yet are not wrong/unknown. [Skotlex]
break;
@@ -6994,20 +6981,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr data)
}
break;
- case SC_HPDRAIN:
- if( --(sce->val4) >= 0 )
- {
- int flag, hp = (sce->val1 < 0) ? (int)(status->max_hp * -1 * sce->val1 / 100.) : sce->val1;
- map_freeblock_lock();
- status_fix_damage(NULL, bl, hp, 0);
- flag = !sc->data[type];
- map_freeblock_unlock();
- if( flag ) return 0;
- sc_timer_next((sce->val2 * 1000) + tick, status_change_timer, bl->id, data);
- }
- break;
-
- case SC_HPREGEN:
case SC_S_LIFEPOTION:
case SC_L_LIFEPOTION:
if( sd && --(sce->val4) >= 0 )
@@ -7022,19 +6995,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr data)
}
break;
- case SC_SPREGEN:
- if( sd && --(sce->val4) >= 0 )
- {
- // val1 < 0 = per max% | val1 > 0 = exact amount
- int sp = 0;
- if( status->sp < status->max_sp )
- sp = (sce->val1 < 0) ? (int)(sd->status.max_sp * -1 * sce->val1 / 100.) : sce->val1 ;
- status_heal(bl, 0, sp, 2);
- sc_timer_next((sce->val2 * 1000) + tick, status_change_timer, bl->id, data);
- return 0;
- }
- break;
-
case SC_BOSSMAPINFO:
if( sd && --(sce->val4) >= 0 )
{
diff --git a/src/map/status.h b/src/map/status.h
index 2d45b2626..21d2ba67d 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -264,8 +264,8 @@ typedef enum sc_type {
SC_FLEET,
SC_SPEED,
SC_DEFENCE,
- SC_INCASPDRATE,
- SC_INCFLEE2,
+ //SC_INCASPDRATE,
+ SC_INCFLEE2 = 247,
SC_JAILED,
SC_ENCHANTARMS, //250
SC_MAGICALATTACK,
@@ -279,22 +279,22 @@ typedef enum sc_type {
SC_BOSSMAPINFO,
SC_LIFEINSURANCE, //260
SC_INCCRI,
- SC_INCDEF,
- SC_INCBASEATK,
- SC_FASTCAST,
- SC_MDEF_RATE,
- SC_HPREGEN,
- SC_INCHEALRATE,
+ //SC_INCDEF,
+ //SC_INCBASEATK = 263,
+ //SC_FASTCAST,
+ SC_MDEF_RATE = 265,
+ //SC_HPREGEN,
+ SC_INCHEALRATE = 267,
SC_PNEUMA,
SC_AUTOTRADE,
SC_KSPROTECTED, //270
- SC_ARMOR_RESIST,
+ SC_ARMOR_RESIST = 271,
SC_SPCOST_RATE,
SC_COMMONSC_RESIST,
SC_SEVENWIND,
SC_DEF_RATE,
- SC_SPREGEN,
- SC_WALKSPEED,
+ //SC_SPREGEN,
+ SC_WALKSPEED = 277,
// Mercenary Only Bonus Effects
SC_MERC_FLEEUP,
@@ -305,16 +305,16 @@ typedef enum sc_type {
SC_MERC_QUICKEN,
SC_REBIRTH,
- SC_SKILLCASTRATE, //285
- SC_DEFRATIOATK,
- SC_HPDRAIN,
- SC_SKILLATKBONUS,
- SC_ITEMSCRIPT,
+ //SC_SKILLCASTRATE, //285
+ //SC_DEFRATIOATK,
+ //SC_HPDRAIN,
+ //SC_SKILLATKBONUS,
+ SC_ITEMSCRIPT = 289,
SC_S_LIFEPOTION, //290
SC_L_LIFEPOTION,
SC_JEXPBOOST,
- SC_IGNOREDEF,
- SC_HELLPOWER,
+ //SC_IGNOREDEF,
+ SC_HELLPOWER = 294,
SC_INVINCIBLE, //295
SC_INVINCIBLEOFF,
diff --git a/src/map/unit.c b/src/map/unit.c
index 88304940b..89e1b3788 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -1955,12 +1955,15 @@ int unit_free(struct block_list *bl, int clrtype)
case BL_PC:
{
struct map_session_data *sd = (struct map_session_data*)bl;
+
if( status_isdead(bl) )
pc_setrestartvalue(sd,2);
pc_delinvincibletimer(sd);
- pc_autoscript_clear(sd);
-
+ pc_delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),false);
+ pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus),false);
+ pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus),false);
+
if( sd->followtimer != -1 )
pc_stop_following(sd);