瀏覽代碼

- Modified attack_walk_delay so it behaves on a 'per-object' basis, and changed the default to 15 (all types).
- Modified battle_delay_damage so damage is not delayed more than one second for non-player attacks.
- Modified party_member_added with a hack so that the clif functions will send the info of the new member since party_recv_info has not yet arrived.
- Updated clif_calc_delay so the type sent to the client is based on the number of hits of the skill (as Aegis packets reveal)


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

skotlex 17 年之前
父節點
當前提交
d6eb67c6c4
共有 9 個文件被更改,包括 57 次插入39 次删除
  1. 8 0
      Changelog-Trunk.txt
  2. 3 4
      conf/battle/battle.conf
  3. 7 5
      src/map/battle.c
  4. 1 1
      src/map/battle.h
  5. 5 4
      src/map/clif.c
  6. 1 0
      src/map/mob.c
  7. 28 20
      src/map/party.c
  8. 2 2
      src/map/skill.c
  9. 2 3
      src/map/unit.c

+ 8 - 0
Changelog-Trunk.txt

@@ -4,6 +4,14 @@ 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.
 
 2008/03/09
+	* Modified attack_walk_delay so it behaves on a 'per-object' basis, and
+	  changed the default to 15 (all types).
+	* Modified battle_delay_damage so damage is not delayed more than one
+	  second for non-player attacks. 
+	* Modified party_member_added with a hack so that the clif functions will
+	  send the info of the new member since party_recv_info has not yet arrived.
+	* Updated clif_calc_delay so the type sent to the client is based on the
+	  number of hits of the skill (as Aegis packets reveal) [Skotlex]
 	* Cleaned up and corrected some more land skill code [ultramage]
 	- removed redundant skill_ganbatein() function
 	- Added flag UF_PATHCHECK from jAthena which affects whether a skill's

+ 3 - 4
conf/battle/battle.conf

@@ -35,13 +35,12 @@ enable_critical: 1
 mob_critical_rate: 100
 critical_rate: 100
 
-// Should normal attacks give you a walk delay?
+// Should normal attacks give you a walk delay? (Note 3)
 // If no, characters can move as soon as they start an attack (attack animation
 // or walk animation may be omitted client-side, causing cropped attacks or
 // monsters that teleport to you)
-// If set, total walk delay is set to your attack animation duration divided by
-// this value (eg: 1 -> 100%, 2 -> 50%, 4->25%...)
-attack_walk_delay: 0
+// Otherwise, the delay is equal to the 'attack animation' (amotion)
+attack_walk_delay: 15
 
 // Move-delay adjustment after being hit. (Note 2)
 // The 'can't walk' delay after being hit is calculated as a percentage of the damage animation duration.

+ 7 - 5
src/map/battle.c

@@ -172,7 +172,7 @@ 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, enum damage_lv dmg_lv, int ddelay)
+int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, int skill_id, int skill_lv, int damage, enum damage_lv dmg_lv, int ddelay)
 {
 	struct delay_damage *dat;
 	nullpo_retr(0, src);
@@ -200,7 +200,9 @@ int battle_delay_damage (unsigned int tick, struct block_list *src, struct block
 	dat->dmg_lv = dmg_lv;
 	dat->delay = ddelay;
 	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);
+	if (src->type != BL_PC && amotion > 1000)
+		amotion = 1000; //Aegis places a damage-delay cap of 1 sec to non player attacks. [Skotlex]
+	add_timer(tick+amotion, battle_delay_damage_sub, src->id, (int)dat);
 	
 	return 0;
 }
@@ -2885,7 +2887,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
 
 	map_freeblock_lock();
 
-	battle_delay_damage(tick+wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion);
+	battle_delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion);
 
 	if (sc && sc->data[SC_AUTOSPELL] && rand()%100 < sc->data[SC_AUTOSPELL]->val4) {
 		int sp = 0;
@@ -2924,7 +2926,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
 	if (rdamage > 0) { //By sending attack type "none" skill_additional_effect won't be invoked. [Skotlex]
 		if(tsd && src != target)
 			battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
-		battle_delay_damage(tick+wd.amotion, target, src, 0, 0, 0, rdamage, ATK_DEF, rdelay);
+		battle_delay_damage(tick, wd.amotion, target, src, 0, 0, 0, rdamage, ATK_DEF, rdelay);
 	}
 
 	if (tsc) {
@@ -3582,7 +3584,7 @@ static const struct _battle_data {
 	{ "min_skill_delay_limit",              &battle_config.min_skill_delay_limit,           100,    10,     INT_MAX,        },
 	{ "default_walk_delay",                 &battle_config.default_walk_delay,              300,    0,      INT_MAX,        },
 	{ "no_skill_delay",                     &battle_config.no_skill_delay,                  BL_MOB, BL_NUL, BL_ALL,         },
-	{ "attack_walk_delay",                  &battle_config.attack_walk_delay,               0,      0,      INT_MAX,        },
+	{ "attack_walk_delay",                  &battle_config.attack_walk_delay,               BL_ALL, BL_NUL, BL_ALL,         },
 	{ "require_glory_guild",                &battle_config.require_glory_guild,             0,      0,      1,              },
 	{ "idle_no_share",                      &battle_config.idle_no_share,                   0,      0,      INT_MAX,        },
 	{ "party_even_share_bonus",             &battle_config.party_even_share_bonus,          0,      0,      INT_MAX,        }, 

+ 1 - 1
src/map/battle.h

@@ -55,7 +55,7 @@ enum {	// 
 	BF_SKILLMASK= 0x0f00,
 };
 
-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, enum damage_lv dmg_lv, int ddelay);
+int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, int skill_id, int skill_lv, int damage, enum damage_lv dmg_lv, int ddelay);
 
 // ’Ê�í�UŒ‚�ˆ—�‚܂Ƃß
 enum damage_lv battle_weapon_attack( struct block_list *bl,struct block_list *target,unsigned int tick,int flag);

+ 5 - 4
src/map/clif.c

@@ -3473,7 +3473,8 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
 }
 
 //Modifies the type of damage according to status changes [Skotlex]
-#define clif_calc_delay(type,damage,delay) ((type)==0x0a?type:((delay)==0&&(damage)>0?9:type))
+//Aegis data specifies that: 4 endure against single hit sources, 9 against multi-hit.
+#define clif_calc_delay(type,div,damage,delay) ((delay)==0&&(damage)>0?((div)>1?9:4):type)
 
 /*==========================================
  * Estimates walk delay based on the damage criteria. [Skotlex]
@@ -3518,7 +3519,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
 	nullpo_retr(0, src);
 	nullpo_retr(0, dst);
 
-	type = clif_calc_delay(type,damage+damage2,ddelay);
+	type = clif_calc_delay(type,div,damage+damage2,ddelay);
 	sc = status_get_sc(dst);
 	if(sc && sc->count) {
 		if(sc->data[SC_HALLUCINATION]) {
@@ -4092,7 +4093,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int
 	nullpo_retr(0, src);
 	nullpo_retr(0, dst);
 
-	type = clif_calc_delay(type,damage,ddelay);
+	type = clif_calc_delay(type,div,damage,ddelay);
 	sc = status_get_sc(dst);
 	if(sc && sc->count) {
 		if(sc->data[SC_HALLUCINATION] && damage)
@@ -4180,7 +4181,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned in
 	nullpo_retr(0, dst);
 
 	type = (type>0)?type:skill_get_hit(skill_id);
-	type = clif_calc_delay(type,damage,ddelay);
+	type = clif_calc_delay(type,div,damage,ddelay);
 	sc = status_get_sc(dst);
 
 	if(sc && sc->count) {

+ 1 - 0
src/map/mob.c

@@ -3431,6 +3431,7 @@ static bool mob_parse_dbrow(char** str)
 	status->adelay = atoi(str[27]);
 	status->amotion = atoi(str[28]);
 	//If the attack animation is longer than the delay, the client crops the attack animation!
+	//On aegis there is no real visible effect of having a recharge-time less than amotion anyway.
 	if (status->adelay < status->amotion)
 		status->adelay = status->amotion;
 	status->dmotion = atoi(str[29]);

+ 28 - 20
src/map/party.c

@@ -372,7 +372,6 @@ int party_member_added(int party_id,int account_id,int char_id, int flag)
 {
 	struct map_session_data *sd = map_id2sd(account_id),*sd2;
 	struct party_data *p = party_search(party_id);
-	int invite_aid;
 	int i;
 
 	if(sd == NULL || sd->status.char_id != char_id){
@@ -381,7 +380,10 @@ int party_member_added(int party_id,int account_id,int char_id, int flag)
 		return 0;
 	}
 
-	invite_aid = sd->party_invite_account;
+	sd2 = map_id2sd(sd->party_invite_account);
+	if( sd2 != NULL )
+		clif_party_inviteack(sd2,sd->status.name,flag?3:2);
+
 	sd->party_invite = 0;
 	sd->party_invite_account = 0;
 
@@ -391,26 +393,32 @@ int party_member_added(int party_id,int account_id,int char_id, int flag)
 		return 0;
 	}
 
-	if( flag == 0 ) {
-		sd->status.party_id = party_id;
-		party_check_conflict(sd);
-		clif_party_option(p,sd,0x100);
-		clif_party_info(p,sd);
-		clif_party_member_info(p,sd);
-		for( i = 0; i < ARRAYLENGTH(p->data); ++i )
-		{// hp of the other party members
-			sd2 = p->data[i].sd;
-			if( sd2 && sd2->status.account_id != account_id && sd2->status.char_id != char_id )
-				clif_hpmeter_single(sd->fd, sd2->bl.id, sd2->battle_status.hp, sd2->battle_status.max_hp);
-		}
-		clif_party_hp(sd);
-		clif_party_xy(sd);
-		clif_charnameupdate(sd); //Update char name's display [Skotlex]
+	if( flag ) return 0;
+
+	sd->status.party_id = party_id;
+
+	ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == 0 );
+	if (i < MAX_PARTY) {
+		//TODO: This is a hack to allow the following clif calls to send the data to the new player.
+		//The correct player data is set when party_recv_info arrives soon afterwards.
+		party_fill_member(&p->party.member[i], sd);
+		p->data[i].sd = sd;
 	}
 
-	sd2 = map_id2sd(invite_aid);
-	if( sd2 != NULL )
-		clif_party_inviteack(sd2,sd->status.name,flag?2:1);
+	party_check_conflict(sd);
+	clif_party_option(p,sd,0x100);
+	clif_party_info(p,sd);
+	clif_party_member_info(p,sd);
+	for( i = 0; i < ARRAYLENGTH(p->data); ++i )
+	{// hp of the other party members
+		sd2 = p->data[i].sd;
+		if( sd2 && sd2->status.account_id != account_id && sd2->status.char_id != char_id )
+			clif_hpmeter_single(sd->fd, sd2->bl.id, sd2->battle_status.hp, sd2->battle_status.max_hp);
+	}
+	clif_party_hp(sd);
+	clif_party_xy(sd);
+	clif_charnameupdate(sd); //Update char name's display [Skotlex]
+
 	return 0;
 }
 

+ 2 - 2
src/map/skill.c

@@ -1658,7 +1658,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 (dmg.amotion)
-		battle_delay_damage(tick+dmg.amotion,src,bl,attack_type,skillid,skilllv,damage,dmg.dmg_lv,dmg.dmotion);
+		battle_delay_damage(tick, dmg.amotion,src,bl,attack_type,skillid,skilllv,damage,dmg.dmg_lv,dmg.dmotion);
 
 	if(skillid == RG_INTIMIDATE && damage > 0 && !(tstatus->mode&MD_BOSS)) {
 		int rate = 50 + skilllv * 5;
@@ -1676,7 +1676,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 
 	if (rdamage>0) {
 		if (dmg.amotion)
-			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);
 		else
 			status_fix_damage(bl,src,rdamage,0);
 		clif_damage(src,src,tick, dmg.amotion,0,rdamage,1,4,0);

+ 2 - 3
src/map/unit.c

@@ -1422,9 +1422,8 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t
 
 		ud->attackabletime = tick + sstatus->adelay;
 //		You can't move if you can't attack neither.
-		if (battle_config.attack_walk_delay)
-			unit_set_walkdelay(src, tick,
-				sstatus->amotion/battle_config.attack_walk_delay, 1);
+		if (src->type&battle_config.attack_walk_delay)
+			unit_set_walkdelay(src, tick, sstatus->amotion, 1);
 	}
 
 	if(ud->state.attack_continue)