Selaa lähdekoodia

* update from Skotlex
- Fixed NPC_STOP's visual effect not clearing when the status ends
- Corrected @homshuffle making the skill tree be lost.
- Corrected homunculus skills being unusable if the master was sitting or inflicted by a disabling status (eg: petrify, stun)
- Some fixes to the cell no stacking mod (mainly mobs would just get stuck behind each other and not properly surround you)

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

ultramage 18 vuotta sitten
vanhempi
commit
c73c55d465
8 muutettua tiedostoa jossa 143 lisäystä ja 56 poistoa
  1. 8 0
      Changelog-Trunk.txt
  2. 2 0
      db/Changelog.txt
  3. 33 8
      db/const.txt
  4. 2 1
      src/map/atcommand.c
  5. 78 38
      src/map/clif.c
  6. 1 1
      src/map/status.c
  7. 1 0
      src/map/status.h
  8. 18 8
      src/map/unit.c

+ 8 - 0
Changelog-Trunk.txt

@@ -3,6 +3,14 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2007/07/05
+	* Fixed pet equip and pet hairstyle packet sends [ultramage]
+	* Fixed NPC_STOP's visual effect not clearing when the status ends
+	* Corrected @homshuffle making the skill tree be lost.
+	* Corrected homunculus skills being unusable if the master was sitting or
+	  inflicted by a disabling status (eg: petrify, stun)
+	* Some fixes to the cell no stacking mod (mainly mobs would just get stuck
+	  behind each other and not properly surround you). [Skotlex]
 2007/07/04
 	* Fixed a copy-paste typo messing up script variables pretty bad D:
 2007/07/03

+ 2 - 0
db/Changelog.txt

@@ -48,6 +48,8 @@
 	13107 Western_Outlaw		Need correct HIT and ASPD Rate
 	----
 ========================
+07/05
+	* Updated the SC constant listing in db/const.txt [Skotlex]
 07/04
 	* Fixed spiritual ring [Playtester]
 	* Cursey Abbey mob updates [Playtester]

+ 33 - 8
db/const.txt

@@ -493,7 +493,6 @@ IG_BleuBox	39
 SC_ALL -1
 SC_STONE	0
 SC_FREEZE	1
-SC_STAN	2
 SC_STUN	2
 SC_SLEEP	3
 SC_POISON	4
@@ -518,7 +517,7 @@ SC_SIGNUMCRUCIS	31
 SC_INCREASEAGI	32
 SC_DECREASEAGI	33
 SC_SLOWPOISON	34
-SC_IMPOSITIO  	35
+SC_IMPOSITIO	35
 SC_SUFFRAGIUM	36
 SC_ASPERSIO	37
 SC_BENEDICTIO	38
@@ -536,7 +535,7 @@ SC_ENERGYCOAT	49
 SC_BROKENARMOR	50
 SC_BROKENWEAPON	51
 SC_HALLUCINATION	52
-SC_WEIGHT50 	53
+SC_WEIGHT50	53
 SC_WEIGHT90	54
 SC_ASPDPOTION0	55
 SC_ASPDPOTION1	56
@@ -569,7 +568,7 @@ SC_SPELLBREAKER	82
 SC_AUTOSPELL	83
 SC_SIGHTTRASHER	84
 SC_AUTOBERSERK	85
-SC_SPEARSQUICKEN	86
+SC_SPEARQUICKEN	86
 SC_AUTOCOUNTER	87
 SC_SIGHT	88
 SC_SAFETYWALL	89
@@ -587,7 +586,7 @@ SC_VOLCANO	100
 SC_DELUGE	101
 SC_VIOLENTGALE	102
 SC_WATK_ELEMENT	103
-SC_LANDPROTECTOR	104
+SC_ARMOR	104
 SC_ARMOR_ELEMENT	105
 SC_NOCHAT	106
 SC_BABY	107
@@ -611,7 +610,7 @@ SC_CHASEWALK	124
 SC_REJECTSWORD	125
 SC_MARIONETTE	126
 SC_MARIONETTE2	127
-SC_MOONLIT	128
+SC_CHANGEUNDEAD	128
 SC_JOINTBEAT	129
 SC_MINDBREAKER	130
 SC_MEMORIZE	131
@@ -648,7 +647,7 @@ SC_WINKCHARM	161
 SC_CLOSECONFINE	162
 SC_CLOSECONFINE2	163
 SC_DANCING	164
-SC_LULLABY	165
+SC_ELEMENTALCHANGE	165
 SC_RICHMANKIM	166
 SC_ETERNALCHAOS	167
 SC_DRUMBATTLE	168
@@ -660,7 +659,7 @@ SC_WHISTLE	173
 SC_ASSNCROS	174
 SC_POEMBRAGI	175
 SC_APPLEIDUN	176
-SC_UGLYDANCE	177
+SC_MODECHANGE	177
 SC_HUMMING	178
 SC_DONTFORGETME	179
 SC_FORTUNE	180
@@ -709,6 +708,32 @@ SC_SKE	222
 SC_KAITE	223
 SC_SWOO	224
 SC_SKA	225
+SC_TKREST	226
+SC_MIRACLE	227
+SC_MADNESSCANCEL	228
+SC_ADJUSTMENT	229
+SC_INCREASING	230
+SC_GATLINGFEVER	231
+SC_TATAMIGAESHI	232
+SC_UTSUSEMI	233
+SC_BUNSINJYUTSU	234
+SC_KAENSIN	235
+SC_SUITON	236
+SC_NEN	237
+SC_KNOWLEDGE	238
+SC_SMA	239
+SC_FLING	240
+SC_AVOID	241
+SC_CHANGE	242
+SC_BLOODLUST	243
+SC_FLEET	244
+SC_SPEED	245
+SC_DEFENCE	246
+SC_INCAGIRATE	247
+SC_INCDEXRATE	248
+SC_JAILED	249
+SC_ENCHANTARMS	250
+SC_MAGICALATTACK	251
 
 e_gasp	0
 e_what	1

+ 2 - 1
src/map/atcommand.c

@@ -8550,7 +8550,7 @@ int atcommand_homshuffle(const int fd, struct map_session_data* sd, const char*
 	struct homun_data *hd;
 	int lv, i, skillpts;
 	unsigned int exp;
-	struct skill b_skill;
+	struct skill b_skill[MAX_HOMUNSKILL];
 	TBL_PC* tsd = sd;
 
 	nullpo_retr(-1, sd);
@@ -8591,6 +8591,7 @@ int atcommand_homshuffle(const int fd, struct map_session_data* sd, const char*
 	hd->homunculus.exp = exp;
 	memcpy(&hd->homunculus.hskill, &b_skill, sizeof(b_skill));
 	hd->homunculus.skillpts = skillpts;
+	clif_homskillinfoblock(hd->master);
 	status_calc_homunculus(hd,0);
 	status_percent_heal(&hd->bl, 100, 100);
 	clif_misceffect2(&hd->bl,568);

+ 78 - 38
src/map/clif.c

@@ -869,9 +869,11 @@ static int clif_set0078(struct block_list* bl, unsigned char* buf)
 		WBUFW(buf,30)=vd->cloth_color;
 		WBUFW(buf,32)=sd?sd->head_dir:0;
 		WBUFL(buf,34)=guild_id;
-		WBUFL(buf,38)=emblem_id;
-		if (sd)
+		WBUFW(buf,38)=emblem_id;
+		if (sd) {
+			WBUFW(buf,40)=sd->status.manner;
 			WBUFB(buf,44)=sd->status.karma;
+		}
 		WBUFB(buf,45)=vd->sex;
 		WBUFPOS(buf,46,bl->x,bl->y,dir);
 		WBUFB(buf,49)=5;
@@ -894,9 +896,9 @@ static int clif_set0078(struct block_list* bl, unsigned char* buf)
 		WBUFW(buf,42)=sc->opt3;
 	}
 	WBUFW(buf,14)=vd->class_;
-	WBUFW(buf,16)=vd->hair_style;  //Required for pets.
+	WBUFW(buf,16)=vd->hair_style;  //Required for pets (removes attack cursor)
 	//18W: Weapon
-	WBUFW(buf,20)=vd->head_bottom;	//Pet armor
+	WBUFW(buf,20)=vd->head_bottom;	//Pet armor (ignored by client)
 	if (bl->type == BL_NPC && vd->class_ == FLAG_CLASS)
 	{	//The hell, why flags work like this?
 		WBUFL(buf,22)=emblem_id;
@@ -907,22 +909,22 @@ static int clif_set0078(struct block_list* bl, unsigned char* buf)
 	//26W: Head mid
 	//28W: Hair color
 	//30W: Clothes color
-	WBUFW(buf,32)=dir;
+	//32W: Head dir
 	WBUFL(buf,34)=guild_id;
-	WBUFL(buf,38)=emblem_id;
-	//42W: Manner
+	WBUFW(buf,38)=emblem_id;
+	//40W: Manner
 	//44B: Karma
 	//45B: Sex
 	WBUFPOS(buf,46,bl->x,bl->y,dir);
-	//WBUFB(buf,49)=5;
-	//WBUFB(buf,50)=5;
+	//49B: ???
+	//50B: ???
 	//51B: Sit/Stand
 	WBUFW(buf,52)=clif_setlevel(lv);
 	return packet_len(0x78);
 }
 
 /*==========================================
- *
+ * Prepares 'unit walking' packet
  *------------------------------------------*/
 static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit_data *ud, unsigned char *buf)
 {
@@ -972,8 +974,8 @@ static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit
 		}
 		WBUFB(buf,53)=vd->sex;
 		WBUFPOS2(buf,54,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
-		WBUFB(buf,60)=0;
-		WBUFB(buf,61)=0;
+		WBUFB(buf,60)=5;
+		WBUFB(buf,61)=5;
 		WBUFW(buf,62)=clif_setlevel(lv);
 
 		return packet_len(0x22c);	
@@ -1037,9 +1039,11 @@ static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit
 		WBUFW(buf,34)=vd->cloth_color;
 		WBUFW(buf,36)=sd?sd->head_dir:0;
 		WBUFL(buf,38)=guild_id;
-		WBUFL(buf,42)=emblem_id;
-		if (sd)
+		WBUFW(buf,42)=emblem_id;
+		if (sd) {
+			WBUFW(buf,44)=sd->status.manner;
 			WBUFB(buf,48)=sd->status.karma;
+		}
 		WBUFB(buf,49)=vd->sex;
 		WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
 		WBUFB(buf,56)=5;
@@ -1063,15 +1067,23 @@ static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit
 		WBUFL(buf,48)=sc->opt3;
 	}
 	WBUFW(buf,16)=vd->class_;
-	WBUFW(buf,18)=vd->hair_style; //For pets
+	WBUFW(buf,18)=vd->hair_style; //Required for pets (removes attack cursor)
+	//20L: Weapon/Shield
 	WBUFW(buf,24)=vd->head_bottom;	//Pet armor
 	WBUFL(buf,26)=gettick();
-	WBUFW(buf,38)=unit_getdir(bl);
+	//30W: Head top
+	//32W: Head mid
+	//34W: Hair color
+	//36W: Cloth color
+ 	//38W: Head dir
 	WBUFL(buf,40)=guild_id;
-	WBUFL(buf,44)=emblem_id;
+	WBUFW(buf,44)=emblem_id;
+	//46W: Manner
+	//52B: Karma
+	//53B: Sex
 	WBUFPOS2(buf,54,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
-	WBUFB(buf,60)=0;
-	WBUFB(buf,61)=0;
+	//60B: ???
+	//61B: ???
 	WBUFW(buf,62)=clif_setlevel(lv);
 	return packet_len(0x22c);
 #else
@@ -1088,11 +1100,21 @@ static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit
 	}
 	WBUFW(buf,14)=vd->class_;
 	WBUFW(buf,16)=vd->hair_style; //For pets
-	WBUFW(buf,20)=vd->head_bottom;	//Pet armor
+	//18W: Weapon
+	WBUFW(buf,20)=vd->head_bottom; //Pet armor
 	WBUFL(buf,22)=gettick();
-	WBUFW(buf,36)=unit_getdir(bl);
+	//26W: Shield
+	//28W: Head top
+	//30W: Head mid
+	//32W: Hair color
+	//34W: Cloth color
+ 	//36W: Head dir
 	WBUFL(buf,38)=guild_id;
-	WBUFL(buf,42)=emblem_id;
+	WBUFW(buf,42)=emblem_id;
+	//44W: Manner
+	//46W: Opt3
+	//48B: Karma
+	//49B: Sex
 	WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
 	WBUFB(buf,56)=5;
 	WBUFB(buf,57)=5;
@@ -1109,6 +1131,7 @@ static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit
 static void clif_setdisguise(struct map_session_data *sd, unsigned char *buf,int len, int flag)
 {
 	if (flag) {
+		WBUFL(buf,2)=sd->bl.id;
 #if PACKETVER > 6
 		switch (WBUFW(buf,0)) {
 		case 0x22c:
@@ -1119,7 +1142,6 @@ static void clif_setdisguise(struct map_session_data *sd, unsigned char *buf,int
 			break;
 		default:
 #endif
-			WBUFL(buf,2)=sd->bl.id;
 			WBUFW(buf,12)=OPTION_INVISIBLE;
 			WBUFW(buf,14)=sd->status.class_;
 #if PACKETVER > 6
@@ -1259,7 +1281,7 @@ int clif_spawn(struct block_list *bl)
 		return 0;
 
 	if (pcdb_checkid(vd->class_))
-	{	//Player spawn packet.
+	{	// player spawn packet
 		clif_set0078(bl, buf);
 		switch(WBUFW(buf,0))
 		{
@@ -1289,7 +1311,7 @@ int clif_spawn(struct block_list *bl)
 				break;
 #endif
 		}
-	} else {	//Mob spawn packet.
+	} else {	// npc/mob/pet/homun spawn packet
 		struct status_change *sc = status_get_sc(bl);
 		memset(buf,0,sizeof(buf));
 		WBUFW(buf,0)=0x7c;
@@ -1300,9 +1322,21 @@ int clif_spawn(struct block_list *bl)
 			WBUFW(buf,10)=sc->opt2;
 			WBUFW(buf,12)=sc->option;
 		}
+		//14W: Hair Style
+		//16W: Weapon
+		//18W: Head bottom 
 		WBUFW(buf,20)=vd->class_;
-
+		//22W: Shield
+		//24W: Head top
+		//26W: Head mid
+		//28W: Hair color
+		//30W: Cloth color
+		//32W: Head dir
+		//34B: karma
+		//35B: Sex
 		WBUFPOS(buf,36,bl->x,bl->y,unit_getdir(bl));
+		//39B: ???
+		//40B: ???
 		clif_send(buf,packet_len(0x7c),bl,AREA_WOS);
 		if (disguised(bl)) {
 			WBUFL(buf,2)=-bl->id;
@@ -1337,9 +1371,9 @@ int clif_spawn(struct block_list *bl)
 	break;
 	case BL_PET:
 		{
-			unsigned char buf[64];
-			int len = clif_set0078(bl, buf);
-			clif_send(buf, len, bl, AREA_WOS);
+			TBL_PET* pd = (TBL_PET*)bl;
+			clif_pet_equip(pd); // needed to display pet equip properly
+			clif_send_petdata_area(pd, 5, battle_config.pet_hair_style); // removes the attack cursor
 		}
 		break;
 	}
@@ -3728,9 +3762,16 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
 		break;
 	case BL_PET:
 		{
-			unsigned char buf[64];
-			int len = clif_set0078(bl, buf);
-			clif_send(buf, len, &sd->bl, SELF);
+			// needed to display pet equip properly
+			//TODO: adjust clif_pet_equip() to support a 'target', then rewrite this mess into a function call
+			TBL_PET* pd = (TBL_PET*)bl;
+			int fd = sd->fd;
+			WFIFOHEAD(fd,packet_len(0x1a4));
+			WFIFOW(fd,0) = 0x1a4;
+			WFIFOB(fd,2) = 3;
+			WFIFOL(fd,3) = pd->bl.id;
+			WFIFOL(fd,7) = pd->vd.head_bottom;
+			WFIFOSET(fd,packet_len(0x1a4));
 		}
 		break;
 	}
@@ -8023,7 +8064,6 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 		map_addblock(&sd->pd->bl);
 		clif_spawn(&sd->pd->bl);
 		clif_send_petdata(sd,0,0);
-		clif_send_petdata(sd,5,battle_config.pet_hair_style);
 		clif_send_petstatus(sd);
 //		skill_unit_move(&sd->pd->bl,gettick(),1);
 	}
@@ -9420,11 +9460,6 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
 	int skillnum, skilllv, tmp, target_id;
 	unsigned int tick = gettick();
 
-	if (clif_cant_act(sd))
-		return;
-	if (pc_issit(sd))
-		return;
-
 	skilllv = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
 	if (skilllv < 1) skilllv = 1; //No clue, I have seen the client do this with guild skills :/ [Skotlex]
 	skillnum = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
@@ -9442,6 +9477,11 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
 		return;
 	}
 
+	if (clif_cant_act(sd))
+		return;
+	if (pc_issit(sd))
+		return;
+
 	if (skillnotok(skillnum, sd))
 		return;
 

+ 1 - 1
src/map/status.c

@@ -276,7 +276,7 @@ void initChangeTables(void)
 	set_sc(DC_SERVICEFORYOU, SC_SERVICE4U, SI_BLANK, SCB_MAXSP|SCB_PC);
 	add_sc(NPC_DARKCROSS, SC_BLIND);
 	add_sc(NPC_GRANDDARKNESS, SC_BLIND);
-	add_sc(NPC_STOP, SC_STOP);
+	set_sc(NPC_STOP, SC_STOP, SI_STOP, SCB_NONE);
 	set_sc(NPC_BREAKWEAPON, SC_BROKENWEAPON, SI_BROKENWEAPON, SCB_NONE);
 	set_sc(NPC_BREAKARMOR, SC_BROKENARMOR, SI_BROKENARMOR, SCB_NONE);
 	set_sc(NPC_CHANGEUNDEAD, SC_CHANGEUNDEAD, SI_UNDEAD, SCB_DEF_ELE);

+ 1 - 0
src/map/status.h

@@ -336,6 +336,7 @@ enum {
 	SI_WATERWEAPON		= 91,
 	SI_WINDWEAPON		= 92,
 	SI_EARTHWEAPON		= 93,
+	SI_STOP			= 95,
 	SI_UNDEAD		= 97,
 // 102 = again gloria - from what I saw on screenshots, I wonder if it isn't gospel... [DracoRPG]
 	SI_AURABLADE		= 103,

+ 18 - 8
src/map/unit.c

@@ -317,6 +317,11 @@ int unit_walktoxy( struct block_list *bl, int x, int y, int flag)
 	return unit_walktoxy_sub(bl);
 }
 
+//To set Mob's CHASE/FOLLOW states (shouldn't be done if there's no path to reach)
+#define set_mobstate(bl, flag) \
+	if((bl)->type == BL_MOB && (flag)) \
+		((TBL_MOB*)(bl))->state.skillstate = ((TBL_MOB*)(bl))->state.aggressive?MSS_FOLLOW:MSS_RUSH;
+
 static int unit_walktobl_sub(int tid,unsigned int tick,int id,int data)
 {
 	struct block_list *bl = map_id2bl(id);
@@ -327,7 +332,10 @@ static int unit_walktobl_sub(int tid,unsigned int tick,int id,int data)
 		if (DIFF_TICK(ud->canmove_tick, tick) > 0) //Keep waiting?
 			add_timer(ud->canmove_tick+1, unit_walktobl_sub, id, data);
 		else if (unit_can_move(bl))
-			unit_walktoxy_sub(bl);
+		{
+			if (unit_walktoxy_sub(bl))
+				set_mobstate(bl, ud->state.attack_continue);
+		}
 	}
 	return 0;	
 }
@@ -361,13 +369,10 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
 	sc = status_get_sc(bl);
 	if (sc && sc->count && sc->data[SC_CONFUSION].timer != -1) //Randomize the target position
 		map_random_dir(bl, &ud->to_x, &ud->to_y);
-	
-	//Set Mob's CHASE/FOLLOW states.
-	if(bl->type == BL_MOB && flag&2)
-		((TBL_MOB*)bl)->state.skillstate = ((TBL_MOB*)bl)->state.aggressive?MSS_FOLLOW:MSS_RUSH;
 
 	if(ud->walktimer != -1) {
 		ud->state.change_walk_target = 1;
+		set_mobstate(bl, flag&2);
 		return 1;
 	}
 
@@ -385,8 +390,13 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
 		ud->attacktimer = -1;
 	}
 
-	return unit_walktoxy_sub(bl);
+	if (unit_walktoxy_sub(bl)) {
+		set_mobstate(bl, flag&2);
+		return 1;
+	}
+	return 0;
 }
+#undef set_mobstate
 
 int unit_run(struct block_list *bl)
 {
@@ -1317,9 +1327,9 @@ int unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range, i
 	dx=(dx>0)?1:((dx<0)?-1:0);
 	dy=(dy>0)?1:((dy<0)?-1:0);
 	
-	if (map_getcell(tbl->m,tbl->x-dx,tbl->y-dy,CELL_CHKNOREACH))
+	if (map_getcell(tbl->m,tbl->x-dx,tbl->y-dy,CELL_CHKNOPASS))
 	{	//Look for a suitable cell to place in.
-		for(i=0;i<9 && map_getcell(tbl->m,tbl->x-dirx[i],tbl->y-diry[i],CELL_CHKNOREACH);i++);
+		for(i=0;i<9 && map_getcell(tbl->m,tbl->x-dirx[i],tbl->y-diry[i],CELL_CHKNOPASS);i++);
 		if (i==9) return 0; //No valid cells.
 		dx = dirx[i];
 		dy = diry[i];