From ac6e0a8cd56eaa51dc7e6cd68020d0ea7e9b5d96 Mon Sep 17 00:00:00 2001 From: Inkfish Date: Sun, 28 Jun 2009 08:23:53 +0000 Subject: * Implemented script command "autobonus". [Inkfish] - "autobonus" is similar to "bonusautoscript", however it has a timer of its own. - Updated itemdb changing items bonus using "bonusautoscript + sc_start" mode to "autobonus + bonus" mode. - Remove bonusautoscript and status changes that was needed by bonusautoscript and is no longer in use. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13915 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/battle.c | 17 +----- src/map/pc.c | 178 +++++++++++++++++++++++++++++++++++-------------------- src/map/pc.h | 19 ++++-- src/map/script.c | 145 +++++++++++++++++++++++++++----------------- src/map/skill.c | 58 +++++++++--------- src/map/status.c | 52 ++-------------- src/map/status.h | 36 +++++------ src/map/unit.c | 7 ++- 8 files changed, 274 insertions(+), 238 deletions(-) (limited to 'src/map') 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;iequip_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); -- cgit v1.2.3-60-g2f50