Explorar o código

- Changed clif_damage/clif_skill_damage to return the walk-delay based on the passed on damage-delay.
- Changed battle_damage to accept the walk-delay as well.
- Removed the walk-delay timers from unit.c, merged them to battle_delay_damage.
- Traps will not be displayed when you walk within their range.
- Added HT_DETECTING revealing traps.


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

skotlex %!s(int64=19) %!d(string=hai) anos
pai
achega
a489ed4364
Modificáronse 9 ficheiros con 176 adicións e 128 borrados
  1. 5 0
      Changelog-Trunk.txt
  2. 37 30
      src/map/battle.c
  3. 2 3
      src/map/battle.h
  4. 89 25
      src/map/clif.c
  5. 1 0
      src/map/clif.h
  6. 34 21
      src/map/skill.c
  7. 6 6
      src/map/status.c
  8. 2 41
      src/map/unit.c
  9. 0 2
      src/map/unit.h

+ 5 - 0
Changelog-Trunk.txt

@@ -4,6 +4,11 @@ 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.
 
 2006/04/11
+	* Merged the can't walk delay code into the weapon-damage delay one, means
+	  less timers for attacks, as well as fixing the ghost-mob issue that
+	  reappeared recently. [Skotlex]
+	* Traps will not be displayed when you walk within their range. [Skotlex]
+	* Added HT_DETECTING revealing traps. [Skotlex]
 	* Added ers handling for skill_timerskill structures. [Skotlex]
 	* You don't get critical'ed when in counter-attack stance anymore. [Skotlex]
 	* Changed the default counter-type to "always critical". [Skotlex]

+ 37 - 30
src/map/battle.c

@@ -109,6 +109,7 @@ struct delay_damage {
 	struct block_list *src;
 	int target;
 	int damage;
+	int delay;
 	unsigned short distance;
 	unsigned short skill_lv;
 	unsigned short skill_id;
@@ -124,12 +125,11 @@ int battle_delay_damage_sub (int tid, unsigned int tick, int id, int data)
 	if (target && dat && map_id2bl(id) == dat->src && target->prev != NULL && !status_isdead(target) &&
 		target->m == dat->src->m && check_distance_bl(dat->src, target, dat->distance)) //Check to see if you haven't teleported. [Skotlex]
 	{
-		battle_damage(dat->src, target, dat->damage, dat->flag);
+		battle_damage(dat->src, target, dat->damage, dat->delay, dat->flag);
 		if ((dat->dmg_lv == ATK_DEF || dat->damage > 0) && dat->attack_type)
 		{
 			if (!status_isdead(target))
 				skill_additional_effect(dat->src,target,dat->skill_id,dat->skill_lv,dat->attack_type, tick);
-
 			skill_counter_additional_effect(dat->src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
 		}
 
@@ -138,19 +138,18 @@ int battle_delay_damage_sub (int tid, unsigned int tick, int id, int data)
 	return 0;
 }
 
-int battle_delay_damage (unsigned int tick, struct block_list *src, struct block_list *target, int attack_type, int skill_id, int skill_lv, int damage, int dmg_lv, int flag)
+int battle_delay_damage (unsigned int tick, struct block_list *src, struct block_list *target, int attack_type, int skill_id, int skill_lv, int damage, int dmg_lv, int ddelay, int flag)
 {
 	struct delay_damage *dat;
 	nullpo_retr(0, src);
 	nullpo_retr(0, target);
 
 	if (!battle_config.delay_battle_damage) {
-		battle_damage(src, target, damage, flag);
+		battle_damage(src, target, damage, ddelay, flag);
 		if ((damage > 0 || dmg_lv == ATK_DEF) && attack_type)
 		{
 			if (!status_isdead(target))
 				skill_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());
-
 			skill_counter_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());
 		}
 		return 0;
@@ -163,6 +162,7 @@ int battle_delay_damage (unsigned int tick, struct block_list *src, struct block
 	dat->attack_type = attack_type;
 	dat->damage = damage;
 	dat->dmg_lv = dmg_lv;
+	dat->delay = ddelay;
 	dat->flag = flag;
 	dat->distance = distance_bl(src, target)+10; //Attack should connect regardless unless you teleported.
 	add_timer(tick, battle_delay_damage_sub, src->id, (int)dat);
@@ -171,26 +171,24 @@ int battle_delay_damage (unsigned int tick, struct block_list *src, struct block
 }
 
 // ŽÀ?Û‚ÉHP‚ð‘€?ì
-int battle_damage(struct block_list *src,struct block_list *target,int damage, int flag)
+int battle_damage(struct block_list *src,struct block_list *target,int damage, int walkdelay, int flag)
 {
 	struct map_session_data *sd = NULL;
 	struct status_change *sc;
-
+	int r_damage=0;
+	
 	nullpo_retr(0, target); //src‚ÍNULL‚ŌĂ΂ê‚邱‚Æ‚ª‚ ‚é‚̂ő¼‚Ń`ƒFƒbƒN
 	
 	if (damage == 0 || status_isdead(target))
 		return 0;
-	
-	sc = status_get_sc(target);
 
 	if (damage < 0)
 		return battle_heal(src,target,-damage,0,flag);
 	
-	if (src) {
-		if (src->prev == NULL)
-			return 0;
+	if (src)
 		BL_CAST(BL_PC, src, sd);
-	}
+	
+	sc = status_get_sc(target);
 
 	if (!flag && sc && sc->count) {
 		// “€Œ‹?A?Ή»?A?‡–°‚ð?Á‹Ž
@@ -244,13 +242,23 @@ int battle_damage(struct block_list *src,struct block_list *target,int damage, i
 	if (!flag)
 		unit_skillcastcancel(target, 2);
 	
-	if (target->type == BL_MOB) {
-		return mob_damage(src,(TBL_MOB*)target, damage,0);
-	} else if (target->type == BL_PC) {
-		return pc_damage(src,(TBL_PC*)target,damage);
-	} else if (target->type == BL_SKILL)
-		return skill_unit_ondamaged((struct skill_unit *)target, src, damage, gettick());
-	return 0;
+	switch (target->type)
+	{
+		case BL_MOB:
+			r_damage =  mob_damage(src,(TBL_MOB*)target, damage,0);
+			break;
+		case BL_PC:
+			r_damage = pc_damage(src,(TBL_PC*)target,damage);
+			break;
+		case BL_SKILL:
+			r_damage =  skill_unit_ondamaged((struct skill_unit *)target, src, damage, gettick());
+			break;
+	}
+	
+	if (walkdelay && !status_isdead(target))
+		unit_set_walkdelay(target, gettick(), walkdelay, 0);
+	
+	return r_damage;
 }
 
 int battle_heal(struct block_list *bl,struct block_list *target,int hp,int sp, int flag)
@@ -271,7 +279,7 @@ int battle_heal(struct block_list *bl,struct block_list *target,int hp,int sp, i
 	
 	if (sp == 0) {
 		if (hp < 0) //Use flag 1 because heal-damage shouldn't make you flinch. 
-			return battle_damage(bl, target, -hp, 1);
+			return battle_damage(bl, target, -hp, 0, 1);
 		if (hp == 0)
 			return 0;
 	}
@@ -505,8 +513,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
 			((struct map_session_data *)src)->status.weapon == W_2HSWORD)))){
 			if(rand()%100 < (15*sc->data[SC_REJECTSWORD].val1)){
 				damage = damage*50/100;
-				clif_damage(bl,src,gettick(),0,0,damage,0,0,0);
-				battle_damage(bl,src,damage,0);
+				battle_damage(bl,src,damage,clif_damage(bl,src,gettick(),0,0,damage,0,0,0),0);
 				clif_skill_nodamage(bl,bl,ST_REJECTSWORD,sc->data[SC_REJECTSWORD].val1,1);
 				if((--sc->data[SC_REJECTSWORD].val2)<=0)
 					status_change_end(bl, SC_REJECTSWORD, -1);
@@ -1399,7 +1406,7 @@ static struct Damage battle_calc_weapon_attack(
 			case PA_SACRIFICE:
 			{
 				int hp_dmg = status_get_max_hp(src)* 9/100;
-				battle_damage(src, src, hp_dmg, 1); //Damage to self is always 9%
+				battle_damage(src, src, hp_dmg, 0, 1); //Damage to self is always 9%
 				clif_damage(src,src, gettick(), 0, 0, hp_dmg, 0 , 0, 0);
 				
 				wd.damage = hp_dmg;
@@ -2287,7 +2294,7 @@ static struct Damage battle_calc_weapon_attack(
 				hp = sd->status.hp;
 		} else
 			hp = 5*hp/1000;
-		battle_damage(NULL, src, hp, 1);
+		battle_damage(NULL, src, hp, 0, 1);
 	}
 
 	return wd;
@@ -3022,7 +3029,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
 {
 	struct map_session_data *sd = NULL, *tsd = NULL;
 	struct status_change *sc, *tsc;
-	int race, ele, damage,rdamage=0;
+	int race, ele, damage,rdamage=0,rdelay=0;
 	struct Damage wd;
 
 	nullpo_retr(0, src);
@@ -3107,13 +3114,13 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
 	if (damage > 0 && src != target) {
 		rdamage = battle_calc_return_damage(target, &damage, wd.flag);
 		if (rdamage > 0) {
-			clif_damage(src, src, tick, wd.amotion, wd.dmotion, rdamage, 1, 4, 0);
+			rdelay = clif_damage(src, src, tick, wd.amotion, status_get_dmotion(src), rdamage, 1, 4, 0);
 			//Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
 			skill_additional_effect(target,src,CR_REFLECTSHIELD, 1,BF_WEAPON,tick);
 		}
 	}
 
-	clif_damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2);
+	wd.dmotion = clif_damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2);
 	//“ñ“?—¬?¶Žè‚ƃJƒ^?[ƒ‹’ÇŒ‚‚̃~ƒX•\ަ(–³—?‚â‚è?`)
 	if(sd && sd->status.weapon >= MAX_WEAPON_TYPE && wd.damage2 == 0)
 		clif_damage(src, target, tick+10, wd.amotion, wd.dmotion,0, 1, 0, 0);
@@ -3123,7 +3130,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
 
 	map_freeblock_lock();
 
-	battle_delay_damage(tick+wd.amotion, src, target, BF_WEAPON, 0, 0, damage, wd.dmg_lv, 0);
+	battle_delay_damage(tick+wd.amotion, src, target, BF_WEAPON, 0, 0, damage, wd.dmg_lv, wd.dmotion, 0);
 
 	if (!status_isdead(target) && damage > 0) {
 		if (sd) {
@@ -3209,7 +3216,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
 		}
 	}
 	if (rdamage > 0) //By sending attack type "none" skill_additional_effect won't be invoked. [Skotlex]
-		battle_delay_damage(tick+wd.amotion, target, src, 0, 0, 0, rdamage, ATK_DEF, 0);
+		battle_delay_damage(tick+wd.amotion, target, src, 0, 0, 0, rdamage, ATK_DEF, rdelay, 0);
 
 	if (tsc) {
 		if (tsc->data[SC_POISONREACT].timer != -1 && 

+ 2 - 3
src/map/battle.h

@@ -46,9 +46,8 @@ enum {	// 
 	BF_SKILLMASK= 0x0f00,
 };
 
-// ŽÀ�Û‚ÉHP‚ð‘�Œ¸
-int battle_delay_damage (unsigned int tick, struct block_list *src, struct block_list *target, int attack_type, int skill_id, int skill_lv, int damage, int dmg_lv, int flag);
-int battle_damage(struct block_list *bl,struct block_list *target,int damage,int flag);
+int battle_delay_damage (unsigned int tick, struct block_list *src, struct block_list *target, int attack_type, int skill_id, int skill_lv, int damage, int dmg_lv, int ddelay, int flag);
+int battle_damage(struct block_list *bl,struct block_list *target,int damage,int walkdelay,int flag);
 int battle_heal(struct block_list *bl,struct block_list *target,int hp,int sp,int flag);
 
 

+ 89 - 25
src/map/clif.c

@@ -3679,20 +3679,34 @@ int clif_fixpos2(struct block_list* bl)
 	return 0;
 }
 
+//Modifies the type of damage according to status changes [Skotlex]
+#define clif_calc_delay(type,delay) (type==1||type==4||type==0x0a)?type:(delay==0?9:type)
+
 /*==========================================
- * Modifies the type of damage according to status changes [Skotlex]
+ * Estimates walk delay based on the damage criteria. [Skotlex]
  *------------------------------------------
  */
-static int clif_calc_delay(struct block_list *dst, int type, int delay)
-{
-	if (type == 1 || type == 4 || type == 0x0a) //Type 1 is the crouching animation, type 4 are non-flinching attacks, 0x0a - crits. 
-		return type;
+static int clif_calc_walkdelay(struct block_list *bl,int delay, int type, int damage, int div_) {
+
+	if (type == 4 || type == 9 || damage <=0)
+		return 0;
 	
-	if (delay == 0)
-		return 9; //Endure type attack (damage delay is 0)
+	if (bl->type == BL_PC) {
+		if (battle_config.pc_walk_delay_rate != 100)
+			delay = delay*battle_config.pc_walk_delay_rate/100;
+	} else
+		if (battle_config.walk_delay_rate != 100)
+			delay = delay*battle_config.walk_delay_rate/100;
 	
-	return type;
+	if (div_ > 1) //Multi-hit skills mean higher delays.
+		delay += battle_config.multihit_delay*(div_-1);
+
+	if (delay <= 0)
+		return 0;
+
+	return delay>0?delay:0;
 }
+
 /*==========================================
  * 通常攻撃エフェクト&ダメージ
  *------------------------------------------
@@ -3705,7 +3719,7 @@ int clif_damage(struct block_list *src,struct block_list *dst,unsigned int tick,
 	nullpo_retr(0, src);
 	nullpo_retr(0, dst);
 
-	type = clif_calc_delay(dst, type, ddelay); //Type defaults to 0 for normal attacks.
+	type = clif_calc_delay(type, ddelay); //Type defaults to 0 for normal attacks.
 
 	sc = status_get_sc(dst);
 
@@ -3750,11 +3764,8 @@ int clif_damage(struct block_list *src,struct block_list *dst,unsigned int tick,
 		}
 		clif_send(buf,packet_len_table[0x8a],dst,SELF);
 	}
-	//Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex]
-	if (type != 4 && type != 9 && damage+damage2 > 0) //Non-endure/Non-flinch attack, update walk delay.
-		unit_walkdelay(dst, tick, sdelay, ddelay, div);
-
-	return 0;
+	//Return adjusted can't walk delay for further processing.
+	return clif_calc_walkdelay(dst,ddelay,type,damage+damage2,div);
 }
 
 /*==========================================
@@ -3782,6 +3793,7 @@ void clif_getareachar_item(struct map_session_data* sd,struct flooritem_data* fi
 	WFIFOB(fd,16)=fitem->suby;
 	WFIFOSET(fd,packet_len_table[0x9d]);
 }
+
 /*==========================================
  * 場所スキルエフェクトが視界に入る
  *------------------------------------------
@@ -3851,6 +3863,56 @@ int clif_getareachar_skillunit(struct map_session_data *sd,struct skill_unit *un
 
 	return 0;
 }
+
+int clif_reveal_skillunit(struct skill_unit *unit) {
+	struct block_list *bl;
+	unsigned char buf[97];
+	bl=map_id2bl(unit->group->src_id);
+#if PACKETVER < 3
+	memset(buf,0,packet_len_table[0x11f]);
+	WBUFW(buf, 0)=0x11f;
+	WBUFL(buf, 2)=unit->bl.id;
+	WBUFL(buf, 6)=unit->group->src_id;
+	WBUFW(buf,10)=unit->bl.x;
+	WBUFW(buf,12)=unit->bl.y;
+	WBUFB(buf,14)=unit->group->unit_id;
+	WBUFB(buf,15)=0;
+	clif_send(buf,packet_len_table[0x11f],&unit->bl,AREA);
+#else
+	memset(buf,0,packet_len_table[0x1c9]);
+	WBUFW(buf, 0)=0x1c9;
+	WBUFL(buf, 2)=unit->bl.id;
+	WBUFL(buf, 6)=unit->group->src_id;
+	WBUFW(buf,10)=unit->bl.x;
+	WBUFW(buf,12)=unit->bl.y;
+	WBUFB(buf,14)=unit->group->unit_id;
+	WBUFB(buf,15)=1;
+	WBUFL(buf,15+1)=0;
+	WBUFL(buf,15+5)=0;
+
+	WBUFL(buf,15+13)=unit->bl.y - 0x12;
+	WBUFL(buf,15+17)=0x004f37dd;
+	WBUFL(buf,15+21)=0x0012f674;
+	WBUFL(buf,15+25)=0x0012f664;
+	WBUFL(buf,15+29)=0x0012f654;
+	WBUFL(buf,15+33)=0x77527bbc;
+
+	WBUFB(buf,15+40)=0x2d;
+	WBUFL(buf,15+41)=0;
+	WBUFL(buf,15+45)=0;
+	WBUFL(buf,15+49)=0;
+	WBUFL(buf,15+53)=0x0048d919;
+	WBUFL(buf,15+57)=0x0000003e;
+	WBUFL(buf,15+61)=0x0012f66c;
+
+	if(bl) WBUFL(buf,15+73)=bl->y;
+	WBUFL(buf,15+77)=unit->bl.m;
+	WBUFB(buf,15+81)=0xaa;
+
+	clif_send(buf,packet_len_table[0x1c9],&unit->bl,AREA);
+#endif
+	return 0;
+}
 /*==========================================
  * 場所スキルエフェクトが視界から消える
  *------------------------------------------
@@ -3907,7 +3969,9 @@ int clif_01ac(struct block_list *bl)
 		clif_getareachar_item(sd,(struct flooritem_data*) bl);
 		break;
 	case BL_SKILL:
-		clif_getareachar_skillunit(sd,(struct skill_unit *)bl);
+		//Only reveal non-traps. [Skotlex]
+		if (!skill_get_inf2(((TBL_SKILL*)bl)->group->skill_id)&INF2_TRAP)
+			clif_getareachar_skillunit(sd,(TBL_SKILL*)bl);
 		break;
 	default:
 		if(&sd->bl == bl)
@@ -3989,7 +4053,9 @@ int clif_insight(struct block_list *bl,va_list ap)
 			clif_getareachar_item(tsd,(struct flooritem_data*)bl);
 			break;
 		case BL_SKILL:
-			clif_getareachar_skillunit(tsd,(struct skill_unit *)bl);
+			//Only reveal non-traps. [Skotlex]
+			if (!skill_get_inf2(((TBL_SKILL*)bl)->group->skill_id)&INF2_TRAP)
+				clif_getareachar_skillunit(tsd,(TBL_SKILL*)bl);
 			break;
 		default:
 			clif_getareachar_char(tsd,bl);
@@ -4196,8 +4262,9 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,
 
 	nullpo_retr(0, src);
 	nullpo_retr(0, dst);
-	
-	type = clif_calc_delay(dst, (type>0)?type:skill_get_hit(skill_id), ddelay);
+
+	type = (type>0)?type:skill_get_hit(skill_id);
+	type = clif_calc_delay(type, ddelay);
 	sc = status_get_sc(dst);
 
 	if(sc && sc->count) {
@@ -4262,9 +4329,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,
 #endif
 
 	//Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex]
-	if (type != 4 && type != 9 && damage > 0) //Non-endure/Non-flinch attack, update walk delay.
-		unit_walkdelay(dst, tick, sdelay, ddelay, div);
-	return 0;
+	return clif_calc_walkdelay(dst,ddelay,type,damage,div);
 }
 
 /*==========================================
@@ -4280,7 +4345,8 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,
 	nullpo_retr(0, src);
 	nullpo_retr(0, dst);
 
-	type = clif_calc_delay(dst, (type>0)?type:skill_get_hit(skill_id), ddelay);
+	type = (type>0)?type:skill_get_hit(skill_id);
+	type = clif_calc_delay(type, ddelay);
 	sc = status_get_sc(dst);
 
 	if(sc && sc->count) {
@@ -4318,9 +4384,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,
 	}
 
 	//Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex]
-	if (type != 4 && type != 9 && damage > 0) //Non-endure/Non-flinch attack, update walk delay.
-		unit_walkdelay(dst, tick, sdelay, ddelay, div);
-	return 0;
+	return clif_calc_walkdelay(dst,ddelay,type,damage,div);
 }
 
 /*==========================================

+ 1 - 0
src/map/clif.h

@@ -100,6 +100,7 @@ int clif_clearchat(struct chat_data*,int);	// area or fd
 int clif_leavechat(struct chat_data*,struct map_session_data*);	// chat
 int clif_changechatstatus(struct chat_data*);	// chat
 int clif_refresh(struct map_session_data*);	// self
+int clif_reveal_skillunit(struct skill_unit *unit); //Area
 
 int clif_fame_blacksmith(struct map_session_data *, int);
 int clif_fame_alchemist(struct map_session_data *, int);

+ 34 - 21
src/map/skill.c

@@ -1905,20 +1905,20 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
 	case SG_SUN_WARM:
 	case SG_MOON_WARM:
 	case SG_STAR_WARM:
-		clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5);
+		dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5);
 		break;
 	case KN_BRANDISHSPEAR:
 	case SN_SHARPSHOOTING:
 		{	//Only display skill animation for skill's target.
 			struct unit_data *ud = unit_bl2ud(src);
 			if (ud && ud->skilltarget == bl->id)
-				clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, (lv!=0)?lv:skilllv, type);
+				dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, (lv!=0)?lv:skilllv, type);
 			else
-				clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5);
+				dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5);
 			break;
 		}
 	case PA_GOSPEL: //Should look like Holy Cross [Skotlex]
-		clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, 5);
+		dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, 5);
 		break;
 
 	case ASC_BREAKER:	// [celest]
@@ -1930,7 +1930,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
 			damage += tmpdmg;	// add weapon and magic damage
 			tmpdmg = 0;	// clear the temporary weapon damage
 			if (damage > 0)	// if both attacks missed, do not display a 2nd 'miss'
-				clif_skill_damage(dsrc, bl, tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, skilllv, type);
+				dmg.dmotion = clif_skill_damage(dsrc, bl, tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, skilllv, type);
 		}
 		break;
 	case NPC_SELFDESTRUCTION:
@@ -1940,17 +1940,17 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
 	case KN_AUTOCOUNTER: //Skills that need be passed as a normal attack for the client to display correctly.
 	case TF_DOUBLE:
 	case GS_CHAINACTION:
-		clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,dmg.type,dmg.damage2);
+		dmg.dmotion = clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,dmg.type,dmg.damage2);
 		break;
 	case CR_GRANDCROSS:
 	case NPC_GRANDDARKNESS:
 		//Only show animation when hitting yourself. [Skotlex]
 		if (src!=bl) {
-			clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5);
+			dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, -1, 5);
 			break;
 		}
 	default:
-		clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, (lv!=0)?lv:skilllv, (skillid==0)? 5:type );
+		dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, (lv!=0)?lv:skilllv, (skillid==0)? 5:type );
 	}
 	
 	map_freeblock_lock();
@@ -1986,7 +1986,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
 			damage = 0; //Only Heaven's drive may damage traps. [Skotlex]
 	}
 	if ((skillid || flag) && !(attack_type&BF_WEAPON)) {  // do not really deal damage for ASC_BREAKER's 1st attack
-		battle_damage(src,bl,damage, 0); //Deal damage before knockback to allow stuff like firewall+storm gust combo.
+		battle_damage(src,bl,damage,dmg.dmotion,0); //Deal damage before knockback to allow stuff like firewall+storm gust combo.
 		if (dmg.dmg_lv == ATK_DEF || damage > 0) {
 			if (!status_isdead(bl))
 				skill_additional_effect(src,bl,skillid,skilllv,attack_type,tick);
@@ -2001,7 +2001,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
 	
 	//Delayed damage must be dealt after the knockback (it needs to know actual position of target)
 	if ((skillid || flag) && attack_type&BF_WEAPON && skillid != ASC_BREAKER) {  // do not really deal damage for ASC_BREAKER's 1st attack
-		battle_delay_damage(tick+dmg.amotion,src,bl,attack_type,skillid,skilllv,damage,dmg.dmg_lv,0);
+		battle_delay_damage(tick+dmg.amotion,src,bl,attack_type,skillid,skilllv,damage,dmg.dmg_lv,dmg.dmotion,0);
 	}
 
 	if(skillid == RG_INTIMIDATE && damage > 0 && !(status_get_mode(bl)&MD_BOSS)/* && !map_flag_gvg(src->m)*/) {
@@ -2042,9 +2042,9 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
 
 	if (rdamage>0) {
 		if (attack_type&BF_WEAPON)
-			battle_delay_damage(tick+dmg.amotion,bl,src,0,0,0,rdamage,ATK_DEF,0);
+			battle_delay_damage(tick+dmg.amotion,bl,src,0,0,0,rdamage,ATK_DEF,0,0);
 		else
-			battle_damage(bl,src,rdamage,0);
+			battle_damage(bl,src,rdamage,0,0);
 		clif_damage(src,src,tick, dmg.amotion,0,rdamage,1,4,0);
 		//Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
 		skill_additional_effect(bl,src,CR_REFLECTSHIELD, 1,BF_WEAPON,tick);
@@ -2431,6 +2431,17 @@ int skill_cleartimerskill(struct block_list *src)
 	return 1;
 }
 
+static int skill_reveal_trap( struct block_list *bl,va_list ap )
+{
+	TBL_SKILL *su = (TBL_SKILL*)bl;
+	if (su->alive && su->group && skill_get_inf2(su->group->skill_id)&INF2_TRAP)
+	{	//Reveal trap.
+		clif_reveal_skillunit(su);
+		return 1;
+	}
+	return 0;
+}
+
 /*==========================================
  * スキル使用?i詠?・完了?AID指定?U?系?j
  * ?iスパゲッティに向けて1?前?i?I(ダ�?ポ)?j
@@ -3463,7 +3474,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 		break;
 	case SA_INSTANTDEATH:
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
-		battle_damage(NULL,src,status_get_hp(src)-1,1);
+		battle_damage(NULL,src,status_get_hp(src)-1,0,1);
 		break;
 	case SA_QUESTION:
 	case SA_GRAVITY:
@@ -3489,7 +3500,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 		break;
 	case SA_DEATH:
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
-		battle_damage(NULL,bl,status_get_max_hp(bl),1);
+		battle_damage(NULL,bl,status_get_max_hp(bl),0,1);
 		break;
 	case SA_REVERSEORCISH:
 		clif_skill_nodamage(src,bl,skillid,skilllv,
@@ -4038,7 +4049,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			skill_get_splash(skillid, skilllv), BL_CHAR,
 			src, skillid, skilllv, tick, flag|BCT_ENEMY,
 			skill_castend_damage_id);
-		battle_damage(src, src, status_get_max_hp(src), 1);
+		battle_damage(src, src, status_get_max_hp(src),0,1);
 		break;
 
 	/* パ?ティスキル */
@@ -4736,7 +4747,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				sp = skill_get_sp(bl_skillid,bl_skilllv);
 				if (dstsd)
 					pc_damage_sp(dstsd, sp, 0);
-				battle_damage(NULL, bl, hp, 1);
+				battle_damage(NULL, bl, hp, 0, 1);
 				if(sd && sp) {
 					sp = sp*(25*(skilllv-1))/100;
 					if(skilllv > 1 && sp < 1) sp = 1;
@@ -4877,7 +4888,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 
 	case NPC_SUICIDE:			/* 自決 */
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
-		battle_damage(NULL, src,status_get_hp(src),3); //Suicidal Mobs should give neither exp (flag&1) not items (flag&2) [Skotlex]
+		battle_damage(NULL, src,status_get_hp(src),0,3); //Suicidal Mobs should give neither exp (flag&1) not items (flag&2) [Skotlex]
 		break;
 
 	case NPC_SUMMONSLAVE:		/* 手下?「喚 */
@@ -5286,7 +5297,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				case 3:	// 1000 damage, random armor destroyed
 					{
 						int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM };
-						battle_damage(src, bl, 1000, 0);
+						battle_damage(src, bl, 1000, 0, 0);
 						clif_damage(src,bl,tick,0,0,1000,0,0,0);
 						skill_break_equip(bl, where[rand()%3], 10000, BCT_ENEMY);
 					}
@@ -5319,14 +5330,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 					sc_start(bl,SC_CONFUSION,100,skilllv,skill_get_time2(skillid,skilllv));
 					break;
 				case 10:	// 6666 damage, atk matk halved, cursed
-					battle_damage(src, bl, 6666, 0);
+					battle_damage(src, bl, 6666, 0, 0);
 					clif_damage(src,bl,tick,0,0,6666,0,0,0);
 					sc_start(bl,SC_INCATKRATE,100,-50,skill_get_time2(skillid,skilllv));
 					sc_start(bl,SC_INCMATKRATE,100,-50,skill_get_time2(skillid,skilllv));
 					sc_start(bl,SC_CURSE,skilllv,100,skill_get_time2(skillid,skilllv));
 					break;
 				case 11:	// 4444 damage
-					battle_damage(src, bl, 4444, 0);
+					battle_damage(src, bl, 4444, 0, 0);
 					clif_damage(src,bl,tick,0,0,4444,0,0,0);
 					break;
 				case 12:	// stun
@@ -5914,6 +5925,8 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
 		map_foreachinarea( status_change_timer_sub,
 			src->m, x-i, y-i, x+i,y+i,BL_CHAR,
 			src,status_get_sc(src),SC_SIGHT,tick);
+		map_foreachinarea( skill_reveal_trap,
+			src->m, x-i, y-i, x+i,y+i,BL_SKILL);
 		break;
 
 	case MG_SAFETYWALL:			/* セイフティウォ?ル */
@@ -10249,7 +10262,7 @@ int skill_produce_mix( struct map_session_data *sd, int skill_id,
 	} else {
 		switch (skill_id) {
 			case ASC_CDP: //Damage yourself, and display same effect as failed potion.
-				battle_damage(NULL, &sd->bl, sd->status.max_hp>>2, 1);
+				battle_damage(NULL, &sd->bl, sd->status.max_hp>>2, 0, 1);
 			case AM_PHARMACY:
 			case AM_TWILIGHT1:
 			case AM_TWILIGHT2:

+ 6 - 6
src/map/status.c

@@ -4126,7 +4126,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
 				int diff = mhp*(bl->type==BL_PC?10:15)/100;
 				if (hp - diff < mhp>>2)
 					diff = hp - (mhp>>2);
-				battle_damage(NULL, bl, diff, 1);
+				battle_damage(NULL, bl, diff, 0, 1);
 			}
 		}	// fall through
 		case SC_POISON:				/* “Å */
@@ -4354,7 +4354,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
 		}
 
 		case SC_COMA: //Coma. Sends a char to 1HP
-			battle_damage(NULL, bl, status_get_hp(bl)-1, 1);
+			battle_damage(NULL, bl, status_get_hp(bl)-1, 0, 1);
 			return 1;
 
 		case SC_CLOSECONFINE2:
@@ -5440,7 +5440,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 			if((++sc->data[type].val4)%5 == 0 && status_get_hp(bl) > hp>>2) {
 				hp = hp/100;
 				if(hp < 1) hp = 1;
-				battle_damage(NULL, bl, hp, 1);
+				battle_damage(NULL, bl, hp, 0, 1);
 			}
 			sc->data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
 			return 0;
@@ -5452,7 +5452,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 			break;
 	case SC_DPOISON:
 		if ((--sc->data[type].val3) > 0 && sc->data[SC_SLOWPOISON].timer == -1)
-			battle_damage(NULL, bl, sc->data[type].val4, 1);
+			battle_damage(NULL, bl, sc->data[type].val4, 0, 1);
 		if (sc->data[type].val3 > 0 && !status_isdead(bl))
 		{
 			sc->data[type].timer = add_timer (1000 + tick, status_change_timer, bl->id, data );
@@ -5483,7 +5483,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 		// To-do: bleeding effect increases damage taken?
 		if ((sc->data[type].val4 -= 10000) >= 0) {
 			int hp = rand()%600 + 200;
-			battle_damage(NULL,bl,hp,0);
+			battle_damage(NULL,bl,hp,0,0);
 			if (!status_isdead(bl))
 				sc->data[type].timer = add_timer(10000 + tick, status_change_timer, bl->id, data );
 			return 0;
@@ -5651,7 +5651,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 			{
 				if (sd)
 					pc_damage_sp(sd, sp, 0);
-				battle_damage(NULL, bl, hp, 1);
+				battle_damage(NULL, bl, hp, 0, 1);
 				if ((sc->data[type].val2 -= 10000) > 0) {
 					sc->data[type].timer = add_timer(
 					10000+tick, status_change_timer,

+ 2 - 41
src/map/unit.c

@@ -642,45 +642,10 @@ int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int
 	return 1;
 }
 
-static int unit_walkdelay_sub(int tid, unsigned int tick, int id, int data)
-{
-	struct block_list *bl = map_id2bl(id);
-	if (!bl || status_isdead(bl))
-		return 0;
-	
-	unit_set_walkdelay(bl, tick, data, 0);
-	return 0;
-}
-
 /*==========================================
  * Applies walk delay based on attack type. [Skotlex]
  *------------------------------------------
  */
-int unit_walkdelay(struct block_list *bl, unsigned int tick, int adelay, int delay, int div_) {
-
-	if (status_isdead(bl))
-		return 0;
-	
-	if (bl->type == BL_PC) {
-		if (battle_config.pc_walk_delay_rate != 100)
-			delay = delay*battle_config.pc_walk_delay_rate/100;
-	} else
-		if (battle_config.walk_delay_rate != 100)
-			delay = delay*battle_config.walk_delay_rate/100;
-	
-	if (div_ > 1) //Multi-hit skills mean higher delays.
-		delay += battle_config.multihit_delay*(div_-1);
-
-	if (delay <= 0)
-		return 0;
-	
-	if (adelay > 0)
-		add_timer(tick+adelay, unit_walkdelay_sub, bl->id, delay);
-	else 
-		unit_set_walkdelay(bl, tick, delay, 0);
-	return 1;
-}
-
 
 int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int skill_lv, int casttime, int castcancel) {
 	struct unit_data *ud;
@@ -1373,7 +1338,6 @@ int unit_skillcastcancel(struct block_list *bl,int type)
 // unit_data の初期化処理
 void unit_dataset(struct block_list *bl) {
 	struct unit_data *ud;
-	int i;
 	nullpo_retv(ud = unit_bl2ud(bl));
 
 	memset( ud, 0, sizeof( struct unit_data) );
@@ -1413,14 +1377,12 @@ static int unit_counttargeted_sub(struct block_list *bl, va_list ap)
  */
 int unit_fixdamage(struct block_list *src,struct block_list *target,unsigned int tick,int sdelay,int ddelay,int damage,int div,int type,int damage2)
 {
-
 	nullpo_retr(0, target);
 
 	if(damage+damage2 <= 0)
 		return 0;
 	
-	clif_damage(target,target,tick,sdelay,ddelay,damage,div,type,damage2);
-	return battle_damage(src,target,damage+damage2,0);
+	return battle_damage(src,target,damage+damage2,clif_damage(target,target,tick,sdelay,ddelay,damage,div,type,damage2),0);
 }
 /*==========================================
  * 自分をロックしている対象の数を返す
@@ -1484,7 +1446,7 @@ int unit_remove_map(struct block_list *bl, int clrtype) {
 
 	map_freeblock_lock();
 
-	unit_stop_walking(bl,1);			// 歩行中断
+	unit_stop_walking(bl,0);			// 歩行中断
 	unit_stop_attack(bl);				// 攻撃中断
 	unit_skillcastcancel(bl,0);			// 詠唱中断
 	clif_clearchar_area(bl,clrtype);
@@ -1760,7 +1722,6 @@ int unit_free(struct block_list *bl) {
 int do_init_unit(void) {
 	add_timer_func_list(unit_attack_timer,  "unit_attack_timer");
 	add_timer_func_list(unit_walktoxy_timer,"unit_walktoxy_timer");
-	add_timer_func_list(unit_walkdelay_sub, "unit_walkdelay_sub");
 	add_timer_func_list(unit_walktobl_sub, "unit_walktobl_sub");
 
 	return 0;

+ 0 - 2
src/map/unit.h

@@ -22,8 +22,6 @@ int unit_stop_walking(struct block_list *bl,int type);
 int unit_can_move(struct block_list *bl);
 int unit_is_walking(struct block_list *bl);
 int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type);
-int unit_walkdelay(struct block_list *bl, unsigned int tick, int adelay, int delay, int div_);
-
 
 // 位置の強制移動(吹き飛ばしなど)
 int unit_movepos(struct block_list *bl,int dst_x,int dst_y, int easy, int checkpath);