summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-04-10 15:34:49 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-04-10 15:34:49 +0000
commit20115c5b2564762b0e9d7c929c38f34c757aac0f (patch)
tree8f7883c8b91d94a1a308d23f9a8403b9f1d63d5b /src
parent6d4c7182709b758782235857f22fd3632ba8df21 (diff)
downloadhercules-20115c5b2564762b0e9d7c929c38f34c757aac0f.tar.gz
hercules-20115c5b2564762b0e9d7c929c38f34c757aac0f.tar.bz2
hercules-20115c5b2564762b0e9d7c929c38f34c757aac0f.tar.xz
hercules-20115c5b2564762b0e9d7c929c38f34c757aac0f.zip
- 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
Diffstat (limited to 'src')
-rw-r--r--src/map/battle.c4
-rw-r--r--src/map/script.c7
-rw-r--r--src/map/skill.c6
-rw-r--r--src/map/status.c122
-rw-r--r--src/map/status.h7
5 files changed, 77 insertions, 69 deletions
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)