Bläddra i källkod

- 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://svn.code.sf.net/p/rathena/svn/trunk@10206 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex 18 år sedan
förälder
incheckning
b6bfcce712
8 ändrade filer med 88 tillägg och 73 borttagningar
  1. 4 0
      Changelog-Trunk.txt
  2. 3 0
      conf-tmpl/Changelog.txt
  3. 4 4
      conf-tmpl/battle/status.conf
  4. 2 2
      src/map/battle.c
  5. 2 5
      src/map/script.c
  6. 3 3
      src/map/skill.c
  7. 69 53
      src/map/status.c
  8. 1 6
      src/map/status.h

+ 4 - 0
Changelog-Trunk.txt

@@ -4,6 +4,10 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2007/04/11
+	* 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. Curse duration is now reduced by vit.
+	  [Skotlex]
 	* Removed an ugly cast in socket.c
 	* Fixed Makefile (-Wno-unused-parameter was added twice with gcc4) [Toms]
 2007/04/10

+ 3 - 0
conf-tmpl/Changelog.txt

@@ -1,5 +1,8 @@
 Date	Added
 
+2007/04/11
+	* The pc_max_status_def and mob_max_status_def configs are now set on a
+	  1-100 scale instead of 1-10000 (status.conf)
 2007/04/03
 	* Added hom_setting&0x40, when set it clears the "can't reuse" skill delay
 	  when you vaporize a homunculus (set by default). [Skotlex]

+ 4 - 4
conf-tmpl/battle/status.conf

@@ -49,13 +49,13 @@ mob_status_def_rate: 100
 
 // Required luk to gain inmunity to status changes.
 // Luk increases resistance by closing the gap between natural resist and max 
-// linearly. This setting indicates required luk to gain complete inmunity.
+// linearly. This setting indicates required luk to gain complete immunity.
 // Eg: 40 vit -> 40% resist. 150 luk -> +50% of the missing gap. 
 //     So 40% + (50% of 60%) = 70%
 pc_luk_status_def: 300
 mob_luk_status_def: 300
 
-// Maximum resistance to status changes. (10000 = 100%)
+// Maximum resistance to status changes. (100 = 100%)
 // NOTE: Cards and equipment can go over this limit, so it only applies to natural resist.
-pc_max_status_def: 10000
-mob_max_status_def: 10000
+pc_max_status_def: 100
+mob_max_status_def: 100

+ 2 - 2
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;

+ 2 - 5
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;
-
 }
 
 /*==========================================

+ 3 - 3
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);

+ 69 - 53
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;

+ 1 - 6
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)