diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map/map.h | 8 | ||||
-rw-r--r-- | src/map/pc.c | 114 | ||||
-rw-r--r-- | src/map/pc.h | 15 | ||||
-rw-r--r-- | src/map/script.c | 50 | ||||
-rw-r--r-- | src/map/skill.c | 114 | ||||
-rw-r--r-- | src/map/status.c | 13 | ||||
-rw-r--r-- | src/map/status.h | 5 | ||||
-rw-r--r-- | src/map/unit.c | 1 |
8 files changed, 282 insertions, 38 deletions
diff --git a/src/map/map.h b/src/map/map.h index f96ae8db9..519138d1c 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -307,15 +307,14 @@ enum _sp { SP_HP_DRAIN_VALUE,SP_SP_DRAIN_VALUE, // 1079-1080 SP_WEAPON_ATK,SP_WEAPON_ATK_RATE, // 1081-1082 SP_DELAYRATE,SP_HP_DRAIN_RATE_RACE,SP_SP_DRAIN_RATE_RACE, // 1083-1085 - SP_IGNORE_MDEF_RATE,SP_IGNORE_DEF_RATE,SP_SKILL_HEAL2, //1086-1088 - - + SP_IGNORE_MDEF_RATE,SP_IGNORE_DEF_RATE,SP_SKILL_HEAL2,SP_ADDEFF_ONSKILL, //1086-1089 + SP_RESTART_FULL_RECOVER=2000,SP_NO_CASTCANCEL,SP_NO_SIZEFIX,SP_NO_MAGIC_DAMAGE,SP_NO_WEAPON_DAMAGE,SP_NO_GEMSTONE, // 2000-2005 SP_NO_CASTCANCEL2,SP_NO_MISC_DAMAGE,SP_UNBREAKABLE_WEAPON,SP_UNBREAKABLE_ARMOR, SP_UNBREAKABLE_HELM, // 2006-2010 SP_UNBREAKABLE_SHIELD, SP_LONG_ATK_RATE, // 2011-2012 SP_CRIT_ATK_RATE, SP_CRITICAL_ADDRACE, SP_NO_REGEN, SP_ADDEFF_WHENHIT, SP_AUTOSPELL_WHENHIT, // 2013-2017 - SP_SKILL_ATK, SP_UNSTRIPABLE, SP_FREE, // 2018-2020 + SP_SKILL_ATK, SP_UNSTRIPABLE, SP_AUTOSPELL_ONSKILL, // 2018-2020 SP_SP_GAIN_VALUE, SP_HP_REGEN_RATE, SP_HP_LOSS_RATE, SP_ADDRACE2, SP_HP_GAIN_VALUE, // 2021-2025 SP_SUBSIZE, SP_HP_DRAIN_VALUE_RACE, SP_ADD_ITEM_HEAL_RATE, SP_SP_DRAIN_VALUE_RACE, SP_EXP_ADDRACE, // 2026-2030 SP_SP_GAIN_RACE, SP_SUBRACE2, SP_FREE2, // 2031-2033 @@ -323,7 +322,6 @@ enum _sp { SP_INTRAVISION, SP_ADD_MONSTER_DROP_ITEMGROUP, SP_SP_LOSS_RATE, // 2038-2040 SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE //2041 //Before adding new bonuses, reuse the currently free slots: - //2020 (SP_FREE) (previously SP_ADD_DAMAGE_BY_CLASS) //2033 (SP_FREE2) (previously SP_ADDEFF_WHENHIT_SHORT) //1050 (SP_FREE3) (previously SP_ADD_SPEED) }; diff --git a/src/map/pc.c b/src/map/pc.c index 7de528cac..9e0157041 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1398,7 +1398,7 @@ 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) +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); @@ -1411,17 +1411,20 @@ int pc_autoscript_add(struct s_autoscript *scripts, int max, short rate, short f scripts[i].script = script; scripts[i].rate = rate; scripts[i].target = target; // 0 = Script on Self 1 = Script on Target - //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; + + 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; @@ -1501,6 +1504,36 @@ static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, shor return 1; } +static int pc_bonus_autospell_onskill(struct s_autospell *spell, int max, short src_skill, short id, short lv, short rate, short card_id) +{ + int i; + if( rate < 0 ) + return pc_bonus_autospell_del(spell, max, id, lv, -rate, card_id); + + for( i = 0; i < max && spell[i].id; i++ ) + { + if( spell[i].flag == src_skill && spell[i].id == id && spell[i].lv == lv && spell[i].card_id == card_id ) + { + if( !battle_config.autospell_stacking ) + rate += spell[i].rate; + break; + } + } + + if( i == max ) + { + ShowWarning("pc_bonus: Reached max (%d) number of autospells per character!\n", max); + return 0; + } + + spell[i].flag = src_skill; + spell[i].id = id; + spell[i].lv = lv; + spell[i].rate = rate; + spell[i].card_id = card_id; + return 1; +} + static int pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, short rate, short arrow_rate, unsigned char flag) { int i; @@ -1530,6 +1563,28 @@ static int pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, return 1; } +static int pc_bonus_addeff_onskill(struct s_addeffectonskill* effect, int max, enum sc_type id, short rate, short skill, unsigned char target) +{ + int i; + for( i = 0; i < max && effect[i].skill; i++ ) + { + if( effect[i].id == id && effect[i].skill == skill && effect[i].target == target ) + { + effect[i].rate += rate; + return 1; + } + } + if( i == max ) { + ShowWarning("pc_bonus: Reached max (%d) number of add effects on skill per character!\n", max); + return 0; + } + effect[i].id = id; + effect[i].rate = rate; + effect[i].skill = skill; + effect[i].target = target; + return 1; +} + static int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id, short group, int race, int rate) { int i; @@ -2673,6 +2728,15 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, type3, 0, val); break; + case SP_ADDEFF_ONSKILL: + if( type3 > SC_MAX ) { + ShowWarning("pc_bonus3 (Add Effect on skill): %d is not supported.\n", type3); + break; + } + if( sd->state.lr_flag != 2 ) + pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, val, type2, 2); + break; + default: ShowWarning("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val); break; @@ -2695,6 +2759,26 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4 if(sd->state.lr_flag != 2) pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2), (val&1?type2:-type2), (val&2?-type3:type3), type4, 0, current_equip_card_id); break; + + case SP_AUTOSPELL_ONSKILL: + if(sd->state.lr_flag != 2) + { + int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self. + target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill_get_inf2(type2)&INF2_NO_TARGET_SELF)); + + pc_bonus_autospell_onskill(sd->autospell3, ARRAYLENGTH(sd->autospell3), type2, target?-type3:type3, type4, val, current_equip_card_id); + } + break; + + case SP_ADDEFF_ONSKILL: + if( type2 > SC_MAX ) { + ShowWarning("pc_bonus3 (Add Effect on skill): %d is not supported.\n", type2); + break; + } + if( sd->state.lr_flag != 2 ) + pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, type4, type2, val); + break; + default: ShowWarning("pc_bonus4: unknown type %d %d %d %d %d!\n",type,type2,type3,type4,val); break; @@ -2717,6 +2801,12 @@ int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4 if(sd->state.lr_flag != 2) pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id); break; + + case SP_AUTOSPELL_ONSKILL: + if(sd->state.lr_flag != 2) + pc_bonus_autospell_onskill(sd->autospell3, ARRAYLENGTH(sd->autospell3), type2, (val&1?-type3:type3), (val&2?-type4:type4), type5, current_equip_card_id); + break; + default: ShowWarning("pc_bonus5: unknown type %d %d %d %d %d %d!\n",type,type2,type3,type4,type5,val); break; diff --git a/src/map/pc.h b/src/map/pc.h index 8a100f092..deedc4d70 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -56,6 +56,12 @@ struct s_addeffect { unsigned char flag; }; +struct s_addeffectonskill { + enum sc_type id; + short rate, skill; + unsigned char target; +}; + struct s_add_drop { short id, group; int race, rate; @@ -116,6 +122,7 @@ struct map_session_data { bool changemap; struct guild *gmaster_flag; unsigned int bg_id; + unsigned skillonskill : 1; } state; struct { unsigned char no_weapon_damage, no_magic_damage, no_misc_damage; @@ -208,8 +215,10 @@ struct map_session_data { short sp_gain_race[RC_MAX]; // zeroed arrays end here. // zeroed structures start here - struct s_autospell autospell[15], autospell2[15]; + struct s_autospell autospell[15], autospell2[15], autospell3[15]; struct s_addeffect addeff[MAX_PC_BONUS], addeff2[MAX_PC_BONUS]; + struct s_addeffectonskill addeff3[MAX_PC_BONUS]; + struct { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills. unsigned short id; short val; @@ -229,7 +238,7 @@ struct map_session_data { } itemhealrate[MAX_PC_BONUS]; // zeroed structures end here // manually zeroed structures start here. - struct s_autoscript autoscript[10], autoscript2[10]; //Auto script on attack, when attacked + struct s_autoscript autoscript[10], autoscript2[10], autoscript3[10]; //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; @@ -556,7 +565,7 @@ 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); +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 s_autoscript *scripts, int max); int pc_bonus(struct map_session_data*,int,int); diff --git a/src/map/script.c b/src/map/script.c index 5c1836c97..82c8079d1 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -6519,11 +6519,13 @@ BUILDIN_FUNC(bonus) { case SP_AUTOSPELL: case SP_AUTOSPELL_WHENHIT: + case SP_AUTOSPELL_ONSKILL: case SP_SKILL_ATK: case SP_SKILL_HEAL: case SP_SKILL_HEAL2: case SP_ADD_SKILL_BLOW: case SP_CASTRATE: + case SP_ADDEFF_ONSKILL: // these bonuses support skill names val1 = ( script_isstring(st,3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) ); break; @@ -6547,13 +6549,21 @@ BUILDIN_FUNC(bonus) pc_bonus3(sd, type, val1, val2, val3); break; case 4: - val2 = script_getnum(st,4); + if( type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4) ) + val2 = skill_name2id(script_getstr(st,4)); // 2nd value can be skill name + else + val2 = script_getnum(st,4); + val3 = script_getnum(st,5); val4 = script_getnum(st,6); pc_bonus4(sd, type, val1, val2, val3, val4); break; case 5: - val2 = script_getnum(st,4); + if( type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4) ) + val2 = skill_name2id(script_getstr(st,4)); // 2nd value can be skill name + else + val2 = script_getnum(st,4); + val3 = script_getnum(st,5); val4 = script_getnum(st,6); val5 = script_getnum(st,7); @@ -6588,7 +6598,7 @@ BUILDIN_FUNC(bonusautoscript) script = parse_script(str, "autoscript bonus", 0, 0); if( !script ) return 1; - if( !pc_autoscript_add(sd->autoscript, ARRAYLENGTH(sd->autoscript), rate, flag, target, script) ) + if( !pc_autoscript_add(sd->autoscript, ARRAYLENGTH(sd->autoscript), rate, flag, target, script, false) ) { script_free_code(script); return 1; @@ -6616,13 +6626,40 @@ BUILDIN_FUNC(bonusautoscript2) script = parse_script(str, "autoscript2 bonus", 0, 0); if (!script) return 1; - if (!pc_autoscript_add(sd->autoscript2, ARRAYLENGTH(sd->autoscript2), rate, flag, target, script)) + if (!pc_autoscript_add(sd->autoscript2, ARRAYLENGTH(sd->autoscript2), rate, flag, target, script, false)) { script_free_code(script); return 1; } return 0; } +/// Bonus script that has a chance of being executed when used a skill +BUILDIN_FUNC(bonusautoscript3) +{ + int rate, skill, target = 0; + const char *str; + struct script_code *script; + TBL_PC* sd; + + sd = script_rid2sd(st); + if( sd == NULL ) + return 0;// no player attached, report source + + str = script_getstr(st,2); + 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( !pc_autoscript_add(sd->autoscript3, ARRAYLENGTH(sd->autoscript3), rate, skill, target, script, true) ) + { + script_free_code(script); + return 1; + } + return 0; +} /// Changes the level of a player skill. /// <flag> defaults to 1 @@ -13649,10 +13686,11 @@ struct script_function buildin_func[] = { BUILDIN_DEF(bonus,"iv"), BUILDIN_DEF2(bonus,"bonus2","ivi"), BUILDIN_DEF2(bonus,"bonus3","ivii"), - BUILDIN_DEF2(bonus,"bonus4","iviii"), - BUILDIN_DEF2(bonus,"bonus5","iviiii"), + BUILDIN_DEF2(bonus,"bonus4","ivvii"), + BUILDIN_DEF2(bonus,"bonus5","ivviii"), BUILDIN_DEF(bonusautoscript,"si??"), BUILDIN_DEF(bonusautoscript2,"si??"), + BUILDIN_DEF(bonusautoscript3,"siv?"), 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 78d29cb40..61749e058 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -880,6 +880,24 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int } } + if( sd && skillid ) + { // Trigger status effects on skills + enum sc_type type; + int i; + for( i = 0; i < ARRAYLENGTH(sd->addeff3) && sd->addeff3[i].skill; i++ ) + { + if( skillid != sd->addeff3[i].skill || !sd->addeff3[i].rate ) + continue; + type = sd->addeff3[i].id; + skill = skill_get_time2(status_sc2skill(type),7); + + if( sd->addeff3[i].target&ATF_TARGET ) + status_change_start(bl,type,sd->addeff3[i].rate,7,0,0,0,skill,0); + if( sd->addeff3[i].target&ATF_SELF ) + status_change_start(src,type,sd->addeff3[i].rate,7,0,0,0,skill,0); + } + } + if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai) { //Pass heritage to Master for status causing effects. [Skotlex] sd = map_id2sd(md->master_id); @@ -887,7 +905,8 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int } // Autospell when attacking - if(sd && !status_isdead(bl) && src != bl && sd->autospell[0].id) { + if( sd && !status_isdead(bl) && src != bl && sd->autospell[0].id ) + { struct block_list *tbl; struct unit_data *ud; int i, skilllv; @@ -980,6 +999,64 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int return 0; } +int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, int skillid, unsigned int tick) +{ + int skill, skilllv, i; + struct block_list *tbl; + + if( sd == NULL || skillid <= 0 ) + return 0; + + sd->state.skillonskill = 1; + for( i = 0; i < ARRAYLENGTH(sd->autospell3) && sd->autospell3[i].flag; i++ ) + { + if( sd->autospell3[i].flag != skillid ) + continue; + skill = (sd->autospell3[i].id > 0) ? sd->autospell3[i].id : -sd->autospell3[i].id; + if( skillnotok(skill, sd) ) + continue; + + skilllv = sd->autospell3[i].lv ? sd->autospell3[i].lv : 1; + if( skilllv < 0 ) skilllv = 1 + rand()%(-skilllv); + + if( sd->autospell3[i].id >= 0 && bl == NULL ) + continue; // No target + if( rand()%1000 > sd->autospell3[i].rate ) + continue; + + if( sd->autospell3[i].id < 0 ) + tbl = &sd->bl; + else + tbl = bl; + + switch( skill_get_casttype(skill) ) + { + case CAST_GROUND: skill_castend_pos2(&sd->bl, tbl->x, tbl->y, skill, skilllv, tick, 0); break; + case CAST_NODAMAGE: skill_castend_nodamage_id(&sd->bl, tbl, skill, skilllv, tick, 0); break; + case CAST_DAMAGE: skill_castend_damage_id(&sd->bl, tbl, skill, skilllv, tick, 0); break; + } + break; + } + + if( sd->autoscript3[0].script ) + { + for( i = 0; i < ARRAYLENGTH(sd->autoscript3) && sd->autoscript3[i].script; i++ ) + { + if( sd->autoscript3[i].flag != skillid ) + continue; + if( sd->autoscript3[i].target && bl == NULL ) + continue; + if( rand()%1000 > sd->autoscript3[i].rate ) + continue; + run_script(sd->autoscript3[i].script,0,sd->bl.id,0); + break; + } + } + + sd->state.skillonskill = 0; + return 1; +} + /* Splitted off from skill_additional_effect, which is never called when the * attack skill kills the enemy. Place in this function counter status effects * when using skills (eg: Asura's sp regen penalty, or counter-status effects @@ -2888,8 +2965,14 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int map_freeblock_unlock(); - if (sd && !(flag&1) && sd->state.arrow_atk) //Consume arrow on last invocation to this skill. - battle_consume_ammo(sd, skillid, skilllv); + if( sd && !(flag&1) ) + { + if( sd->state.arrow_atk ) //Consume arrow on last invocation to this skill. + battle_consume_ammo(sd, skillid, skilllv); + if( !sd->state.skillonskill ) + skill_onskillusage(sd, bl, skillid, tick); + } + return 0; } @@ -5408,8 +5491,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in mobskill_event(dstmd, src, tick, MSC_SKILLUSED|(skillid<<16)); } - if (sd && !(flag&1) && sd->state.arrow_atk) //Consume arrow on last invocation to this skill. - battle_consume_ammo(sd, skillid, skilllv); + if( sd && !(flag&1) ) + { + if( sd->state.arrow_atk ) //Consume arrow on last invocation to this skill. + battle_consume_ammo(sd, skillid, skilllv); + if( !sd->state.skillonskill ) + skill_onskillusage(sd, bl, skillid, tick); + } map_freeblock_unlock(); return 0; @@ -6182,9 +6270,15 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk if (sc && sc->data[SC_MAGICPOWER]) status_change_end(src,SC_MAGICPOWER,-1); - if (sd && !(flag&1) && sd->state.arrow_atk) //Consume arrow if a ground skill was not invoked. [Skotlex] - battle_consume_ammo(sd, skillid, skilllv); - + if( sd ) + { + if( sd->state.arrow_atk && !(flag&1) ) //Consume arrow if a ground skill was not invoked. [Skotlex] + battle_consume_ammo(sd, skillid, skilllv); + + if( !sd->state.skillonskill ) + skill_onskillusage(sd, NULL, skillid, tick); + } + return 0; } @@ -8547,8 +8641,8 @@ 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 ) - time += time * sc->data[SC_SKILLCASTRATE]->val2 / 100; + 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) diff --git a/src/map/status.c b/src/map/status.c index 10eb77053..ae0da921f 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -193,7 +193,7 @@ void initChangeTables(void) set_sc( MG_ENERGYCOAT , SC_ENERGYCOAT , SI_ENERGYCOAT , SCB_NONE ); set_sc( NPC_EMOTION , SC_MODECHANGE , SI_BLANK , SCB_MODE ); add_sc( NPC_EMOTION_ON , SC_MODECHANGE ); - set_sc( NPC_ATTRICHANGE , SC_ELEMENTALCHANGE , SI_BLANK , SCB_DEF_ELE ); + set_sc( NPC_ATTRICHANGE , SC_ELEMENTALCHANGE , SI_ARMOR_RESIST , SCB_DEF_ELE ); add_sc( NPC_CHANGEWATER , SC_ELEMENTALCHANGE ); add_sc( NPC_CHANGEGROUND , SC_ELEMENTALCHANGE ); add_sc( NPC_CHANGEFIRE , SC_ELEMENTALCHANGE ); @@ -529,6 +529,7 @@ void initChangeTables(void) StatusChangeFlagTable[SC_ARMOR_RESIST] |= SCB_PC; StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_PC; StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED; + StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_PC; // Mercenary Bonus Effects StatusChangeFlagTable[SC_MERC_FLEEUP] |= SCB_FLEE; StatusChangeFlagTable[SC_MERC_ATKUP] |= SCB_WATK; @@ -1749,8 +1750,10 @@ int status_calc_pc(struct map_session_data* sd,int first) //zero up structures... memset(&sd->autospell,0,sizeof(sd->autospell) + sizeof(sd->autospell2) + + sizeof(sd->autospell3) + sizeof(sd->addeff) + sizeof(sd->addeff2) + + sizeof(sd->addeff3) + sizeof(sd->skillatk) + sizeof(sd->skillheal) + sizeof(sd->skillheal2) @@ -1769,6 +1772,7 @@ int status_calc_pc(struct map_session_data* sd,int first) // clear autoscripts... pc_autoscript_clear(sd->autoscript, ARRAYLENGTH(sd->autoscript)); pc_autoscript_clear(sd->autoscript2, ARRAYLENGTH(sd->autoscript2)); + pc_autoscript_clear(sd->autoscript3, ARRAYLENGTH(sd->autoscript3)); // vars zeroing. ints, shorts, chars. in that order. memset (&sd->arrow_atk, 0,sizeof(sd->arrow_atk) @@ -1966,6 +1970,13 @@ int status_calc_pc(struct map_session_data* sd,int first) } } + if( sc->count && sc->data[SC_ITEMSCRIPT] ) + { + struct item_data *data = itemdb_exists(sc->data[SC_ITEMSCRIPT]->val1); + if( data && data->script ) + run_script(data->script,0,sd->bl.id,0); + } + if( sd->pd ) { // Pet Bonus struct pet_data *pd = sd->pd; diff --git a/src/map/status.h b/src/map/status.h index d3301bd37..0ac17016f 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -309,6 +309,7 @@ typedef enum sc_type { SC_DEFRATIOATK, SC_HPDRAIN, SC_SKILLATKBONUS, + SC_ITEMSCRIPT, SC_MAX, //Automatically updated max, used in for's to check we are within bounds. } sc_type; @@ -488,7 +489,9 @@ enum si_type { SI_INCHEALRATE = 293, SI_HPREGEN = 294, // 295 Sword ? - SI_SPCOST_RATE = 300, + // 296 4 chars up ? + SI_SPCOST_RATE = 298, + // 300 Stars ? SI_COMMONSC_RESIST = 301, SI_ARMOR_RESIST = 302, }; diff --git a/src/map/unit.c b/src/map/unit.c index dce211fc9..194145e58 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1932,6 +1932,7 @@ int unit_free(struct block_list *bl, int clrtype) pc_delinvincibletimer(sd); pc_autoscript_clear(sd->autoscript, ARRAYLENGTH(sd->autoscript)); pc_autoscript_clear(sd->autoscript2, ARRAYLENGTH(sd->autoscript2)); + pc_autoscript_clear(sd->autoscript3, ARRAYLENGTH(sd->autoscript3)); if( sd->followtimer != -1 ) pc_stop_following(sd); |