diff options
author | shennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-02-17 15:33:13 +0000 |
---|---|---|
committer | shennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-02-17 15:33:13 +0000 |
commit | 5cc9f30cbe8c57a97e58a5a3b5387622e4304873 (patch) | |
tree | fa7590892983540d46245781a83d9fb2a08ecaa4 /src/map/status.c | |
parent | c021f63e10a7dca24119e436e2450e0bbb2266a3 (diff) | |
download | hercules-5cc9f30cbe8c57a97e58a5a3b5387622e4304873.tar.gz hercules-5cc9f30cbe8c57a97e58a5a3b5387622e4304873.tar.bz2 hercules-5cc9f30cbe8c57a97e58a5a3b5387622e4304873.tar.xz hercules-5cc9f30cbe8c57a97e58a5a3b5387622e4304873.zip |
Initial support for Shadow Chaser and a few adjustments here and there.
- credits to 3ceam for the base
- should you step by any bugs let us know, http://rathena.org/board/tracker
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@15589 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/status.c')
-rw-r--r-- | src/map/status.c | 306 |
1 files changed, 238 insertions, 68 deletions
diff --git a/src/map/status.c b/src/map/status.c index a65de486b..c0628ab24 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -539,22 +539,22 @@ void initChangeTables(void) ///** // * Shadow Chaser // **/ - //set_sc( SC_REPRODUCE , SC__REPRODUCE , SI_REPRODUCE , SCB_NONE ); - //set_sc( SC_AUTOSHADOWSPELL , SC__AUTOSHADOWSPELL, SI_AUTOSHADOWSPELL , SCB_NONE ); - //set_sc( SC_SHADOWFORM , SC__SHADOWFORM , SI_SHADOWFORM , SCB_NONE ); - //set_sc( SC_BODYPAINT , SC__BODYPAINT , SI_BODYPAINTING , SCB_ASPD ); - //set_sc( SC_INVISIBILITY , SC__INVISIBILITY , SI_INVISIBILITY , SCB_ASPD|SCB_CRI|SCB_ATK_ELE ); - //set_sc( SC_DEADLYINFECT , SC__DEADLYINFECT , SI_DEADLYINFECT , SCB_NONE ); - //set_sc( SC_ENERVATION , SC__ENERVATION , SI_ENERVATION , SCB_BATK ); - //set_sc( SC_GROOMY , SC__GROOMY , SI_GROOMY , SCB_ASPD|SCB_HIT|SCB_SPEED ); - //set_sc( SC_IGNORANCE , SC__IGNORANCE , SI_IGNORANCE , SCB_NONE ); - //set_sc( SC_LAZINESS , SC__LAZINESS , SI_LAZINESS , SCB_FLEE ); - //set_sc( SC_UNLUCKY , SC__UNLUCKY , SI_UNLUCKY , SCB_CRI|SCB_FLEE2 ); - //set_sc( SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_FLEE2|SCB_MAXHP ); - //set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSORY , SCB_DEX|SCB_INT|SCB_LUK ); - //set_sc( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE ); - //add_sc( SC_CHAOSPANIC , SC_CHAOS ); - //set_sc( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK ); + set_sc( SC_REPRODUCE , SC__REPRODUCE , SI_REPRODUCE , SCB_NONE ); + set_sc( SC_AUTOSHADOWSPELL , SC__AUTOSHADOWSPELL, SI_AUTOSHADOWSPELL , SCB_NONE ); + set_sc( SC_SHADOWFORM , SC__SHADOWFORM , SI_SHADOWFORM , SCB_NONE ); + set_sc( SC_BODYPAINT , SC__BODYPAINT , SI_BODYPAINT , SCB_ASPD ); + set_sc( SC_INVISIBILITY , SC__INVISIBILITY , SI_INVISIBILITY , SCB_ASPD|SCB_CRI|SCB_ATK_ELE ); + set_sc( SC_DEADLYINFECT , SC__DEADLYINFECT , SI_DEADLYINFECT , SCB_NONE ); + set_sc( SC_ENERVATION , SC__ENERVATION , SI_ENERVATION , SCB_BATK ); + set_sc( SC_GROOMY , SC__GROOMY , SI_GROOMY , SCB_ASPD|SCB_HIT|SCB_SPEED ); + set_sc( SC_IGNORANCE , SC__IGNORANCE , SI_IGNORANCE , SCB_NONE ); + set_sc( SC_LAZINESS , SC__LAZINESS , SI_LAZINESS , SCB_FLEE ); + set_sc( SC_UNLUCKY , SC__UNLUCKY , SI_UNLUCKY , SCB_CRI|SCB_FLEE2 ); + set_sc( SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_FLEE2|SCB_MAXHP ); + set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK ); + set_sc( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE ); + add_sc( SC_CHAOSPANIC , SC_CHAOS ); + set_sc( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK ); ///** // * Sura // **/ @@ -978,6 +978,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s status_change_end(target, SC_CLOAKING, INVALID_TIMER); status_change_end(target, SC_CHASEWALK, INVALID_TIMER); status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER); + status_change_end(target, SC__INVISIBILITY, INVALID_TIMER); if ((sce=sc->data[SC_ENDURE]) && !sce->val4) { //Endure count is only reduced by non-players on non-gvg maps. //val4 signals infinite endure. [Skotlex] @@ -1405,7 +1406,11 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int (sc->data[SC_MARIONETTE2] && skill_num == CG_MARIONETTE) || //Cannot use marionette if you are being buffed by another sc->data[SC_STEELBODY] || sc->data[SC_BERSERK] || - sc->data[SC_OBLIVIONCURSE] + sc->data[SC_OBLIVIONCURSE] || + sc->data[SC_WHITEIMPRISON] || + (sc->data[SC_STASIS] && skill_stasis_check(src, sc->data[SC_STASIS]->val2, skill_num)) || + sc->data[SC__INVISIBILITY] || + sc->data[SC__IGNORANCE] )) return 0; @@ -1418,6 +1423,17 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int ) return 0; + if( sc->data[SC__MANHOLE] || ((tsc = status_get_sc(target)) && tsc->data[SC__MANHOLE]) ) { + switch(skill_num) {//##TODO## make this a flag in skill_db? + // Skills that can be used even under Man Hole effects. + case SC_SHADOWFORM: + case SC_STRIPACCESSARY: + break; + default: + return 0; + } + } + } } @@ -1528,12 +1544,12 @@ int status_check_visibility(struct block_list *src, struct block_list *target) { //Check for chase-walk/hiding/cloaking opponents. case BL_PC: if ( tsc->data[SC_CLOAKINGEXCEED] && !(status->mode&MD_BOSS) ) - if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&MD_BOSS) && + if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&MD_BOSS) && ( ((TBL_PC*)target)->special_state.perfect_hiding || !(status->mode&MD_DETECTOR) ) ) return 0; break; default: - if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&(MD_BOSS|MD_DETECTOR)) ) + if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&(MD_BOSS|MD_DETECTOR)) ) return 0; } @@ -3778,6 +3794,8 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang int_ += ((sc->data[SC_MARIONETTE2]->val4)>>16)&0xFF; if(sc->data[SC_INSPIRATION]) int_ += sc->data[SC_INSPIRATION]->val3; + if(sc->data[SC__STRIPACCESSORY]) + int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100; if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && int_ < 50) int_ = 50; @@ -3822,6 +3840,8 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang dex += ((sc->data[SC_MARIONETTE2]->val4)>>8)&0xFF; if(sc->data[SC_INSPIRATION]) dex += sc->data[SC_INSPIRATION]->val3; + if(sc->data[SC__STRIPACCESSORY]) + dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100; if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && dex < 50) dex = 50; @@ -3853,6 +3873,8 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang luk += sc->data[SC_MARIONETTE2]->val4&0xFF; if(sc->data[SC_INSPIRATION]) luk += sc->data[SC_INSPIRATION]->val3; + if(sc->data[SC__STRIPACCESSORY]) + luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100; if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && luk < 50) luk = 50; @@ -3891,6 +3913,10 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan batk += sc->data[SC_GATLINGFEVER]->val3; if(sc->data[SC_MADNESSCANCEL]) batk += 100; + if(sc->data[SC__ENERVATION]) + batk -= batk * sc->data[SC__ENERVATION]->val2 / 100; + if(sc->data[SC__BLOODYLUST]) + batk += batk * 32 / 100; #if RE_EDP /** * in RE EDP increases your base atk by atk x Skill Level. @@ -3932,8 +3958,10 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan watk += sc->data[SC_NIBELUNGEN]->val2; } } - if(sc->data[SC_BLOODLUST]) - watk += watk * sc->data[SC_BLOODLUST]->val2/100; + if(sc->data[SC__ENERVATION]) + watk -= watk * sc->data[SC__ENERVATION]->val2 / 100; + if(sc->data[SC__BLOODYLUST]) + watk += watk * 32 / 100; if(sc->data[SC_FLEET]) watk += watk * sc->data[SC_FLEET]->val3/100; if(sc->data[SC_CURSE]) @@ -3994,8 +4022,13 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch critical += sc->data[SC_TRUESIGHT]->val2; if(sc->data[SC_CLOAKING]) critical += critical; + if(sc->data[SC__INVISIBILITY]) + critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100; if(sc->data[SC_CAMOUFLAGE]) critical += 100; + if(sc->data[SC__UNLUCKY]) + critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100; + return (short)cap_value(critical,10,SHRT_MAX); } @@ -4026,6 +4059,8 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change hit += 20; // RockmanEXE; changed based on updated [Reddozen] if(sc->data[SC_MERC_HITUP]) hit += sc->data[SC_MERC_HITUP]->val2; + if(sc->data[SC__GROOMY]) + hit -= hit * sc->data[SC__GROOMY]->val3 / 100; if(sc->data[SC_FEAR]) hit -= hit * 20 / 100; if(sc->data[SC_INSPIRATION]) @@ -4113,6 +4148,8 @@ static signed short status_calc_flee2(struct block_list *bl, struct status_chang flee2 += sc->data[SC_INCFLEE2]->val2; if(sc->data[SC_WHISTLE]) flee2 += sc->data[SC_WHISTLE]->val3*10; + if(sc->data[SC__UNLUCKY]) + flee2 -= flee2 * sc->data[SC__UNLUCKY]->val2 / 100; return (short)cap_value(flee2,10,SHRT_MAX); } @@ -4665,6 +4702,8 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang maxhp += maxhp * 5 * sc->data[SC_EPICLESIS]->val1 / 100; if(sc->data[SC_VENOMBLEED]) maxhp -= maxhp * 15 / 100; + if(sc->data[SC__WEAKNESS]) + maxhp -= maxhp * sc->data[SC__WEAKNESS]->val2 / 100; if(sc->data[SC_FORCEOFVANGUARD]) maxhp += maxhp * 3 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100; if(sc->data[SC_INSPIRATION]) //Custom value. @@ -4727,6 +4766,8 @@ static unsigned char status_calc_element_lv(struct block_list *bl, struct status return sc->data[SC_ELEMENTALCHANGE]->val1; if(sc->data[SC_SHAPESHIFT]) return 1; + if(sc->data[SC__INVISIBILITY]) + return 1; return (unsigned char)cap_value(lv,1,4); } @@ -4752,7 +4793,7 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch return ELE_HOLY; if(sc->data[SC_SHADOWWEAPON]) return ELE_DARK; - if(sc->data[SC_GHOSTWEAPON]) + if(sc->data[SC_GHOSTWEAPON] || sc->data[SC__INVISIBILITY]) return ELE_GHOST; return (unsigned char)cap_value(element,0,UCHAR_MAX); } @@ -5214,39 +5255,48 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti //Status that are blocked by Golden Thief Bug card or Wand of Hermod if (status_isimmune(bl)) - switch (type) - { - case SC_DECREASEAGI: - case SC_SILENCE: - case SC_COMA: - case SC_INCREASEAGI: - case SC_BLESSING: - case SC_SLOWPOISON: - case SC_IMPOSITIO: - case SC_AETERNA: - case SC_SUFFRAGIUM: - case SC_BENEDICTIO: - case SC_PROVIDENCE: - case SC_KYRIE: - case SC_ASSUMPTIO: - case SC_ANGELUS: - case SC_MAGNIFICAT: - case SC_GLORIA: - case SC_WINDWALK: - case SC_MAGICROD: - case SC_HALLUCINATION: - case SC_STONE: - case SC_QUAGMIRE: - case SC_SUITON: - return 0; - } + switch (type) { + case SC_DECREASEAGI: + case SC_SILENCE: + case SC_COMA: + case SC_INCREASEAGI: + case SC_BLESSING: + case SC_SLOWPOISON: + case SC_IMPOSITIO: + case SC_AETERNA: + case SC_SUFFRAGIUM: + case SC_BENEDICTIO: + case SC_PROVIDENCE: + case SC_KYRIE: + case SC_ASSUMPTIO: + case SC_ANGELUS: + case SC_MAGNIFICAT: + case SC_GLORIA: + case SC_WINDWALK: + case SC_MAGICROD: + case SC_HALLUCINATION: + case SC_STONE: + case SC_QUAGMIRE: + case SC_SUITON: + case SC__ENERVATION: + case SC__GROOMY: + case SC__IGNORANCE: + case SC__LAZINESS: + case SC__UNLUCKY: + case SC__WEAKNESS: + return 0; + } sd = BL_CAST(BL_PC,bl); status = status_get_status_data(bl); - switch (type) - { + sc = status_get_sc(bl); + if( sc && !sc->count ) + sc = NULL; + switch (type) { case SC_STUN: case SC_POISON: + if( sc && sc->data[SC__UNLUCKY] ) + return tick; case SC_DPOISON: case SC_SILENCE: case SC_BLEEDING: @@ -5271,6 +5321,8 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti tick_def = status->vit; break; case SC_BLIND: + if( sc && sc->data[SC__UNLUCKY] ) + return tick; sc_def = 3 +(status->vit + status->int_)/2; break; case SC_CONFUSION: @@ -5360,9 +5412,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti } } - sc = status_get_sc(bl); - if (sc && sc->count) - { + if (sc) { if (sc->data[SC_SCRESIST]) sc_def += sc->data[SC_SCRESIST]->val1; //Status resist else if (sc->data[SC_SIEGFRIED]) @@ -5741,6 +5791,23 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val if( sd && pc_checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill_check_camouflage(bl,NULL) ) return 0; break; + case SC__STRIPACCESSORY: + if( sd ) { + int i = -1; + if( !(sd->unstripable_equip&EQI_ACC_L) ) { + i = sd->equip_index[EQI_ACC_L]; + if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR ) + pc_unequipitem(sd,i,3); //L-Accessory + } if( !(sd->unstripable_equip&EQI_ACC_R) ) { + i = sd->equip_index[EQI_ACC_R]; + if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR ) + pc_unequipitem(sd,i,3); //R-Accessory + } + if( i < 0 ) + return 0; + } + if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC + break; } //Check for BOSS resistances @@ -5972,6 +6039,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_MARIONETTE2: case SC_NOCHAT: case SC_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation. + case SC__INVISIBILITY: + case SC__ENERVATION: + case SC__GROOMY: + case SC__IGNORANCE: + case SC__LAZINESS: + case SC__WEAKNESS: + case SC__UNLUCKY: + case SC_CHAOS: return 0; case SC_COMBO: case SC_DANCING: @@ -6996,11 +7071,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val val4 = gettick(); //Store time at which you started running. tick = -1; break; - case SC__SHADOWFORM: - { - //struct map_session_data * s_sd = map_id2sd(val2); - //if( s_sd ) - // s_sd->shadowform_id = bl->id; + case SC__SHADOWFORM: { + struct map_session_data * s_sd = map_id2sd(val2); + if( s_sd ) + s_sd->shadowform_id = bl->id; val4 = tick / 1000; val_flag |= 1|2|4; tick_time = 1000; // [GodLesZ] tick time @@ -7381,6 +7455,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_ANKLE: case SC_SPIDERWEB: case SC_ELECTRICSHOCKER: + case SC_BITE: + case SC__MANHOLE: + case SC_CHAOS: unit_stop_walking(bl,1); break; case SC_HIDING: @@ -7412,7 +7489,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_POISON: sc->opt2 |= OPT2_POISON; break; case SC_CURSE: sc->opt2 |= OPT2_CURSE; break; case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break; - case SC_SIGNUMCRUCIS: sc->opt2 |= OPT2_SIGNUMCRUCIS; break; + + case SC_SIGNUMCRUCIS: + case SC_CHAOS: + sc->opt2 |= OPT2_SIGNUMCRUCIS; + break; + case SC_BLIND: sc->opt2 |= OPT2_BLIND; break; case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break; case SC_BLEEDING: sc->opt2 |= OPT2_BLEEDING; break; @@ -7513,6 +7595,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_CLOAKING: case SC_CLOAKINGEXCEED: + case SC__INVISIBILITY: sc->option |= OPTION_CLOAK; opt_flag = 2; break; @@ -8066,6 +8149,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const if (vd) vd->dead_sit = 0; break; case SC_WARM: + case SC__MANHOLE: if (sce->val4) { //Clear the group. struct skill_unit_group* group = skill_id2group(sce->val4); sce->val4 = 0; @@ -8138,9 +8222,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const case SC_ADORAMUS: status_change_end(bl, SC_BLIND, -1); break; - /* - case SC__SHADOWFORM: - { + case SC__SHADOWFORM: { struct map_session_data *s_sd = map_id2sd(sce->val2); if( !s_sd ) break; @@ -8148,13 +8230,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const } break; case SC_SITDOWN_FORCE: - if( sd && pc_issit(sd) ) - { + if( sd && pc_issit(sd) ) { pc_setstand(sd); - clif_standing(bl,true); + clif_standing(bl); } break; - */ case SC_NEUTRALBARRIER_MASTER: case SC_STEALTHFIELD_MASTER: if( sce->val2 ) @@ -8216,6 +8296,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const sc->opt2 &= ~OPT2_DPOISON; break; case SC_SIGNUMCRUCIS: + case SC_CHAOS: sc->opt2 &= ~OPT2_SIGNUMCRUCIS; break; @@ -8225,6 +8306,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const break; case SC_CLOAKING: case SC_CLOAKINGEXCEED: + case SC__INVISIBILITY: sc->option &= ~OPTION_CLOAK; opt_flag|= 2; break; @@ -9226,13 +9308,17 @@ int status_change_timer_sub(struct block_list* bl, va_list ap) status_change_end(bl, SC_CLOAKING, INVALID_TIMER); status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER); + status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER); break; case SC_RUWACH: /* ƒ‹ƒAƒt */ - if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED])) { + if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || + tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED] || + tsc->data[SC__INVISIBILITY])) { status_change_end(bl, SC_HIDING, INVALID_TIMER); status_change_end(bl, SC_CLOAKING, INVALID_TIMER); status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER); status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); + status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER); if(battle_check_target( src, bl, BCT_ENEMY ) > 0) skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0); } @@ -9317,6 +9403,15 @@ int status_change_clear_buffs (struct block_list* bl, int type) case SC_EXPBOOST: case SC_JEXPBOOST: case SC_ITEMBOOST: + case SC_ELECTRICSHOCKER: + case SC__MANHOLE: + case SC_GIANTGROWTH: + case SC_MILLENNIUMSHIELD: + case SC_REFRESH: + case SC_STONEHARDSKIN: + case SC_VITALITYACTIVATION: + case SC_FIGHTINGSPIRIT: + case SC_ABUNDANCE: continue; //Debuffs that can be removed. @@ -9352,6 +9447,81 @@ int status_change_clear_buffs (struct block_list* bl, int type) return 0; } +int status_change_spread( struct block_list *src, struct block_list *bl ) { + int i, flag = 0; + struct status_change *sc = status_get_sc(src); + const struct TimerData *timer; + unsigned int tick; + struct status_change_data data; + + if( !sc || !sc->count ) + return 0; + + tick = gettick(); + + for( i = SC_COMMON_MIN; i < SC_MAX; i++ ) { + if( !sc->data[i] || i == SC_COMMON_MAX ) + continue; + + switch( i ) { + //Debuffs that can be spreaded. + // NOTE: We'll add/delte SCs when we are able to confirm it. + case SC_POISON: + case SC_CURSE: + case SC_SILENCE: + case SC_CONFUSION: + case SC_BLIND: + case SC_BLEEDING: + case SC_DPOISON: + case SC_NOCHAT: + case SC_HALLUCINATION: + case SC_SIGNUMCRUCIS: + case SC_DECREASEAGI: + case SC_SLOWDOWN: + case SC_MINDBREAKER: + case SC_WINKCHARM: + case SC_STOP: + case SC_ORCISH: + //case SC_STRIPWEAPON://Omg I got infected and had the urge to strip myself physically. + //case SC_STRIPSHIELD://No this is stupid and shouldnt be spreadable at all. + //case SC_STRIPARMOR:// Disabled until I can confirm if it does or not. [Rytech] + //case SC_STRIPHELM: + //case SC__STRIPACCESSORY: + case SC_BITE: + case SC_FREEZING: + case SC_BURNING: + case SC_FEAR: + case SC_PYREXIA: + case SC_PARALYSE: + case SC_DEATHHURT: + case SC_MAGICMUSHROOM: + case SC_VENOMBLEED: + case SC_TOXIN: + case SC_OBLIVIONCURSE: + case SC_LEECHESEND: + if( sc->data[i]->timer != INVALID_TIMER ) { + timer = get_timer(sc->data[i]->timer); + if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0) + continue; + data.tick = DIFF_TICK(timer->tick,tick); + } else + data.tick = INVALID_TIMER; + data.val1 = sc->data[i]->val1; + data.val2 = sc->data[i]->val2; + data.val3 = sc->data[i]->val3; + data.val4 = sc->data[i]->val4; + status_change_start(bl,i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8); + flag = 1; + break; + default: + continue; + break; + } + } + + return flag; +} + //Natural regen related stuff. static unsigned int natural_heal_prev_tick,natural_heal_diff_tick; static int status_natural_heal(struct block_list* bl, va_list args) @@ -9381,7 +9551,7 @@ static int status_natural_heal(struct block_list* bl, va_list args) if (flag && ( status_isdead(bl) || - (sc && sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)) + (sc && (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || sc->data[SC__INVISIBILITY])) )) flag=0; |