Pārlūkot izejas kodu

- The autoloot range check is no longer done unless AUTOLOOT_DISTANCE is defined (by default it is no longer defined)
- Ganbantein now deletes individual skill cells instead of the whole skill in the area it is casted.
- Modified the mob total damage code to prevent overflows when mobs receive over 2kM damage.
- Made the dmg structure of the damage log an unsigned int rather than signed.


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@10343 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex 18 gadi atpakaļ
vecāks
revīzija
e587ff356b
5 mainītis faili ar 32 papildinājumiem un 17 dzēšanām
  1. 4 0
      Changelog-Trunk.txt
  2. 2 3
      src/map/atcommand.h
  3. 1 1
      src/map/map.h
  4. 23 8
      src/map/mob.c
  5. 2 5
      src/map/skill.c

+ 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/25
+	* Ganbantein now deletes individual skill cells instead of the whole skill
+	  in the area it is casted.
+	* Modified the mob total damage code to prevent overflows when mobs receive
+	  over 2kM damage. [Skotlex]
 	* Spider Web / Fiber Lock status cannot be dispelled now [ultramage]
 2007/04/24
 	* All mob casted skills have a fixed range of 9 now.

+ 2 - 3
src/map/atcommand.h

@@ -7,9 +7,8 @@
 //This is the distance at which @autoloot works,
 //if the item drops farther from the player than this,
 //it will not be autolooted. [Skotlex]
-#ifndef AUTOLOOT_DISTANCE 
-	#define AUTOLOOT_DISTANCE AREA_SIZE
-#endif
+//Note: The range is unlimited unless this define is set.
+//#define AUTOLOOT_DISTANCE AREA_SIZE
 
 enum AtCommandType {
 	AtCommand_None = -1,

+ 1 - 1
src/map/map.h

@@ -923,7 +923,7 @@ struct mob_data {
 	struct guardian_data* guardian_data; 
 	struct {
 		int id;
-		int dmg;
+		unsigned int dmg;
 		unsigned flag : 1; //0: Normal. 1: Homunc exp
 	} dmglog[DAMAGELOG_SIZE];
 	struct spawn_data *spawn; //Spawn data.

+ 23 - 8
src/map/mob.c

@@ -1513,8 +1513,10 @@ static void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, str
 	}
 
 	if (dlist->first_sd && dlist->first_sd->state.autoloot &&
-		drop_rate <= dlist->first_sd->state.autoloot &&
-		check_distance_blxy(&dlist->first_sd->bl, dlist->x, dlist->y, AUTOLOOT_DISTANCE)
+		drop_rate <= dlist->first_sd->state.autoloot
+#ifdef AUTOLOOT_DISTANCE
+		&& check_distance_blxy(&dlist->first_sd->bl, dlist->x, dlist->y, AUTOLOOT_DISTANCE)
+#endif
 	) {	//Autoloot.
 		if (party_share_loot(
 			dlist->first_sd->status.party_id?
@@ -1617,7 +1619,14 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
 
 	if (damage > 0)
 	{	//Store total damage...
-		md->tdmg+=damage;
+		if (UINT_MAX - (unsigned int)damage > md->tdmg)
+			md->tdmg+=damage;
+		else if (md->tdmg == UINT_MAX)
+			damage = 0; //Stop recording damage once the cap has been reached.
+		else { //Cap damage log...
+			damage = (int)(UINT_MAX - md->tdmg);
+			md->tdmg = UINT_MAX;
+		}
 		if (md->state.aggressive)
 		{	//No longer aggressive, change to retaliate AI.
 			md->state.aggressive = 0;
@@ -1688,8 +1697,9 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
 	}
 	//Log damage...
 	if (char_id && damage > 0) {
-		int i,minpos,mindmg;
-		for(i=0,minpos=DAMAGELOG_SIZE-1,mindmg=INT_MAX;i<DAMAGELOG_SIZE;i++){
+		int i,minpos;
+		unsigned int mindmg;
+		for(i=0,minpos=DAMAGELOG_SIZE-1,mindmg=UINT_MAX;i<DAMAGELOG_SIZE;i++){
 			if(md->dmglog[i].id==char_id &&
 				md->dmglog[i].flag==flag)
 				break;
@@ -1811,7 +1821,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 			tmpsd[i] = NULL;
 			continue;
 		}
-		if(mvp_damage<(unsigned int)md->dmglog[i].dmg){
+		if(mvp_damage<md->dmglog[i].dmg){
 			third_sd = second_sd;
 			second_sd = mvp_sd;
 			mvp_sd=tmpsd[i];
@@ -1822,8 +1832,13 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 	if(!battle_config.exp_calc_type && count > 1)
 	{	//Apply first-attacker 200% exp share bonus
 		//TODO: Determine if this should go before calculating the MVP player instead of after.
-		md->tdmg += md->dmglog[0].dmg;
-		md->dmglog[0].dmg<<=1;
+		if (UINT_MAX - md->dmglog[0].dmg > md->tdmg) {
+			md->tdmg += md->dmglog[0].dmg;
+			md->dmglog[0].dmg<<=1;
+		} else {
+			md->dmglog[0].dmg+= UINT_MAX - md->tdmg;
+			md->tdmg = UINT_MAX;
+		}
 	}
 
 	if(!(type&2) && //No exp

+ 2 - 5
src/map/skill.c

@@ -6527,7 +6527,7 @@ int skill_dance_overlap(struct skill_unit *unit, int flag)
  * Flag: 0 - Convert, 1 - Revert, 2 - Initialize.
  *------------------------------------------
  */
-#define skill_dance_switch(unit, group, flag) ((group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE)?skill_dance_switch_sub(unit, group, flag):0)
+#define skill_dance_switch(unit, group, flag) (((group)->state.song_dance&0x1 && (unit)->val2&UF_ENSEMBLE)?skill_dance_switch_sub(unit, group, flag):0)
 static int skill_dance_switch_sub(struct skill_unit *unit, struct skill_unit_group *group, int flag)
 {
 	static struct skill_unit_group original, dissonance, uglydance, *group2;
@@ -9552,10 +9552,7 @@ int skill_ganbatein (struct block_list *bl, va_list ap)
 	if (unit->group->state.song_dance&0x1)
 		return 0; //Don't touch song/dance.
 
-	if (unit->group->skill_id == SA_LANDPROTECTOR)
-		skill_delunit(unit, 1);
-	else skill_delunitgroup(NULL, unit->group, 1);
-
+	skill_delunit(unit, 1);
 	return 1;
 }