From 20115c5b2564762b0e9d7c929c38f34c757aac0f Mon Sep 17 00:00:00 2001 From: skotlex Date: Tue, 10 Apr 2007 15:34:49 +0000 Subject: - Modified status_get_sc_def to handle both rate and tick reductions. This way it can take care of the fact that curse rate/duration reductions are not reduced by the same stats. - Removed wrong defines status_get_sc_def_[mdef/vit/int/luk], they actually had a rather undefined behaviour. - The pc_max_status_def mob_max_status_def configs are now set on a 1-100% scale instead of 1.00-100.00% git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@10206 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/battle.c | 4 +- src/map/script.c | 7 +--- src/map/skill.c | 6 +-- src/map/status.c | 122 +++++++++++++++++++++++++++++++------------------------ src/map/status.h | 7 +--- 5 files changed, 77 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index 54c416ae7..e29e9d86a 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -4080,8 +4080,8 @@ void battle_set_defaults() { battle_config.mob_sc_def_rate = 100; battle_config.pc_luk_sc_def = 300; battle_config.mob_luk_sc_def = 300; - battle_config.pc_max_sc_def = 10000; - battle_config.mob_max_sc_def = 5000; + battle_config.pc_max_sc_def = 100; + battle_config.mob_max_sc_def = 50; battle_config.sg_miracle_skill_ratio=1; battle_config.sg_angel_skill_ratio=1; battle_config.sg_miracle_skill_duration=3600000; diff --git a/src/map/script.c b/src/map/script.c index bff02bce3..a270baa57 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -8128,13 +8128,10 @@ BUILDIN_FUNC(getscrate) bl = map_id2bl(st->rid); if (bl) - sc_def = status_get_sc_def(bl,type); - - rate = rate*(10000-sc_def)/10000; - script_pushint(st,rate<0?0:rate); + rate = status_get_sc_def(bl,type, 10000, 10000, 0); + script_pushint(st,rate); return 0; - } /*========================================== diff --git a/src/map/skill.c b/src/map/skill.c index 0cf04bbe6..456281d39 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4646,12 +4646,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in { int i; clif_skill_nodamage(src,bl,skillid,skilllv,1); - i = status_get_sc_def_mdef(bl); - if (i >= 10000 || + i = tstatus->mdef; + if (i >= 100 || (dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER) || tsc == NULL || (tsc->data[SC_SPIRIT].timer != -1 && tsc->data[SC_SPIRIT].val2 == SL_ROGUE) || //Rogue's spirit defends againt dispel. //Fixed & changed to use a proportionnal reduction (no info, but seems far more logical) [DracoRPG] - rand()%10000 >= (10000-i)*(50+10*skilllv)/100) + rand()%100 >= (100-i)*(50+10*skilllv)/100) { if (sd) clif_skill_fail(sd,skillid,0,0); diff --git a/src/map/status.c b/src/map/status.c index c2445bde2..238621063 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -4351,11 +4351,12 @@ void status_change_init(struct block_list *bl) sc->data[i].timer = -1; } -//Returns defense against the specified status change. -//Return range is 0 (no resist) to 10000 (inmunity) -int status_get_sc_def(struct block_list *bl, int type) +//Applies SC defense to a given status change. +//Returns the adjusted duration based on flag values. +//the flag values are the same as in status_change_start. +int status_get_sc_def(struct block_list *bl, int type, int rate, int tick, int flag) { - int sc_def; + int sc_def, tick_def = 0; struct status_data* status; struct status_change* sc; struct map_session_data *sd; @@ -4388,9 +4389,10 @@ int status_get_sc_def(struct block_list *bl, int type) case SC_STONE: case SC_QUAGMIRE: case SC_SUITON: - return 10000; + return 0; } + BL_CAST(BL_PC,bl,sd); status = status_get_status_data(bl); switch (type) { @@ -4399,37 +4401,42 @@ int status_get_sc_def(struct block_list *bl, int type) case SC_DPOISON: case SC_SILENCE: case SC_BLEEDING: - sc_def = 300 +100*status->vit; + sc_def = 3 +status->vit; break; case SC_SLEEP: - sc_def = 300 +100*status->int_; + sc_def = 3 +status->int_; break; + case SC_DECREASEAGI: + if (sd) tick>>=1; //Half duration for players. case SC_STONE: case SC_FREEZE: - case SC_DECREASEAGI: - sc_def = 300 +100*status->mdef; + sc_def = 3 +status->mdef; break; case SC_CURSE: + //Special property: inmunity when luk is greater than level if (status->luk > status_get_lv(bl)) - return 10000; //Special property: inmunity when luk is greater than level + return 0; else - sc_def = 300 +100*status->luk; + sc_def = 3 +status->luk; + tick_def = status->vit; break; case SC_BLIND: //TODO: These 50/50 factors are guessed. Need to find actual value. - sc_def = 300 +50*status->vit +50*status->int_; + sc_def = 3 +(status->vit + status->int_)/2; break; case SC_CONFUSION: - sc_def = 300 +50*status->str +50*status->int_; + sc_def = 3 +(status->str + status->int_)/2; break; case SC_ANKLE: - sc_def = 100*status->agi; + if(status->mode&MD_BOSS) // Lasts 5 times less on bosses + tick /= 5; + sc_def = status->agi; break; - default: - return 0; //Effect that cannot be reduced? Likely a buff. + //Effect that cannot be reduced? Likely a buff. + if (!(rand()%10000 < rate)) + return 0; + return tick; } - - BL_CAST(BL_PC,bl,sd); if (sd) { @@ -4442,6 +4449,11 @@ int status_get_sc_def(struct block_list *bl, int type) else sc_def = battle_config.pc_max_sc_def; + if (tick_def) { + if (battle_config.pc_sc_def_rate != 100) + tick_def = sc_def*battle_config.pc_sc_def_rate/100; + } + } else { if (battle_config.mob_sc_def_rate != 100) @@ -4453,17 +4465,50 @@ int status_get_sc_def(struct block_list *bl, int type) else sc_def = battle_config.mob_max_sc_def; + if (tick_def) { + if (battle_config.mob_sc_def_rate != 100) + tick_def = sc_def*battle_config.mob_sc_def_rate/100; + } } sc = status_get_sc(bl); if (sc && sc->count) { if (sc->data[SC_SCRESIST].timer != -1) - sc_def += 100*sc->data[SC_SCRESIST].val1; //Status resist + sc_def += sc->data[SC_SCRESIST].val1; //Status resist else if (sc->data[SC_SIEGFRIED].timer != -1) - sc_def += 100*sc->data[SC_SIEGFRIED].val3; //Status resistance. + sc_def += sc->data[SC_SIEGFRIED].val3; //Status resistance. + } + + //When no tick def, reduction is the same for both. + if (!tick_def) tick_def = sc_def; + + //Natural resistance + if (!(flag&8)) { + rate -= rate*sc_def/100; + + //Item resistance (only applies to rate%) + if(sd && SC_COMMON_MIN<=type && type<=SC_COMMON_MAX + && sd->reseff[type-SC_COMMON_MIN] > 0) + rate -= rate*sd->reseff[type-SC_COMMON_MIN]/10000; } - return sc_def>10000?10000:sc_def; + if (!(rand()%10000 < rate)) + return 0; + + //Why would a status start with no duration? Presume it has + //duration defined elsewhere. + if (!tick) return 1; + + //Rate reduction + if (flag&2) + return tick; + + tick -= tick*tick_def/100; + // Minimum trap time of 3+0.03*skilllv seconds [celest] + // Changed to 3 secs and moved from skill.c [Skotlex] + if (type == SC_ANKLE && tick < 3000) + tick = 3000; + return tick<=0?0:tick; } /*========================================== @@ -4510,30 +4555,10 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val return 0; } - //Check rate + //Check resistance. if (!(flag&(1|4))) { - int def = status_get_sc_def(bl, type); - - if (def && tick && !(flag&2)) - { - tick -= tick*def/10000; - if (tick <= 0 && type != SC_ANKLE) //Ankle Snare has it's opwn minimum - return 0; - } - - if (!(flag&8)) { - if (def) //Natural resistance - rate -= rate*def/10000; - - //Item resistance (only applies to rate%) - if(sd && SC_COMMON_MIN<=type && type<=SC_COMMON_MAX - && sd->reseff[type-SC_COMMON_MIN] > 0) - rate -= rate*sd->reseff[type-SC_COMMON_MIN]/10000; - } - - if (!(rand()%10000 < rate)) - return 0; - + tick = status_get_sc_def(bl, type, rate, tick, flag); + if (!tick) return 0; } undead_flag=battle_check_undead(status->race,status->def_ele); @@ -4925,7 +4950,6 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val if(!(flag&4)) //Do not parse val settings when loading SCs switch(type){ case SC_DECREASEAGI: - if (sd) tick>>=1; //Half duration for players. case SC_INCREASEAGI: val2 = 2 + val1; //Agi change break; @@ -5709,14 +5733,6 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val if(status->mode&MD_BOSS) tick /= 5; //TODO: Reduce skill's duration. But for how long? break; - case SC_ANKLE: - if(status->mode&MD_BOSS) // Lasts 5 times less on bosses - tick /= 5; - // Minimum trap time of 3+0.03*skilllv seconds [celest] - // Changed to 3 secs and moved from skill.c [Skotlex] - if (tick < 3000) - tick = 3000; - break; case SC_SPIDERWEB: if (bl->type == BL_PC) tick /=2; diff --git a/src/map/status.h b/src/map/status.h index 4e14ebd45..1220db8f0 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -619,12 +619,7 @@ struct status_change *status_get_sc(struct block_list *bl); int status_isdead(struct block_list *bl); int status_isimmune(struct block_list *bl); -int status_get_sc_def(struct block_list *bl, int type); -#define status_get_sc_def_mdef(bl) (status_get_sc_def(bl, SP_MDEF1)) -#define status_get_sc_def_vit(bl) (status_get_sc_def(bl, SP_DEF2)) -#define status_get_sc_def_int(bl) (status_get_sc_def(bl, SP_MDEF2)) -#define status_get_sc_def_luk(bl) (status_get_sc_def(bl, SP_LUK)) - +int status_get_sc_def(struct block_list *bl, int type, int rate, int tick, int flag); //Short version, receives rate in 1->100 range, and does not uses a flag setting. #define sc_start(bl, type, rate, val1, tick) status_change_start(bl,type,100*(rate),val1,0,0,0,tick,0) #define sc_start2(bl, type, rate, val1, val2, tick) status_change_start(bl,type,100*(rate),val1,val2,0,0,tick,0) -- cgit v1.2.3-70-g09d2