Jelajahi Sumber

* [Removed]:
- Large part of scripted mob control commands are removed.
- Large part of scripted player control commands are removed.
- Scripted mob slaves changing master ID.

[Added]:
- Unit control commands.
- CALLBACK_NPCCLICK for scripted mobs, added this to db/const.txt too.
- Macro RECURSIVE_MASTER_CHECK in battle.c

[Modified]:
- buildin_skilluseid and buildin_skillusepos -> buildin_unitskilluseid and buildin_unitskillusepos.
- md->callback_flag to short (double word). [Lance]

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

Lance 19 tahun lalu
induk
melakukan
61cf41923c
9 mengubah file dengan 266 tambahan dan 310 penghapusan
  1. 14 0
      Changelog-Trunk.txt
  2. 2 0
      db/const.txt
  3. 19 0
      src/map/battle.c
  4. 7 5
      src/map/clif.c
  5. 1 1
      src/map/map.h
  6. 0 1
      src/map/mob.c
  7. 1 0
      src/map/mob.h
  8. 0 7
      src/map/npc.c
  9. 222 296
      src/map/script.c

+ 14 - 0
Changelog-Trunk.txt

@@ -3,6 +3,20 @@ 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.
 
+2006/06/18
+	* [Removed]:
+	  - Large part of scripted mob control commands are removed.
+	  - Large part of scripted player control commands are removed.
+	  - Scripted mob slaves changing master ID.
+	  [Added]:
+	  - Unit control commands.
+	  - CALLBACK_NPCCLICK for scripted mobs, added this to db/const.txt too.
+	  - Macro RECURSIVE_MASTER_CHECK in battle.c
+	  [Modified]:
+	  - buildin_skilluseid and buildin_skillusepos -> buildin_unitskilluseid
+	    and buildin_unitskillusepos.
+	  - md->callback_flag to short (double word).	[Lance]
+
 2006/06/17
 	* Devotion absorbed damage will now appear to come from oneself (instead of
 	  the original attacker changing directions towards the Crusader) [Skotlex]

+ 2 - 0
db/const.txt

@@ -706,6 +706,8 @@ AI_ACTION_TAR_TYPE_PC	1
 AI_ACTION_TAR_TYPE_MOB	2
 AI_ACTION_TAR_TYPE_PET	4
 AI_ACTION_TAR_TYPE_HOMUN	8
+AI_ACTION_TAR_TYPE_ITEM	16
+AI_ACTION_TYPE_NPCCLICK	256
 AI_ACTION_TYPE_ATTACK	128
 AI_ACTION_TYPE_DETECT	64
 AI_ACTION_TYPE_DEAD	32

+ 19 - 0
src/map/battle.c

@@ -25,6 +25,9 @@
 #include "guild.h"
 #include "party.h"
 
+// Recursive master check to prevent custom AIs from messing with each other.
+// #define RECURSIVE_MASTER_CHECK
+
 #define	is_boss(bl)	status_get_mexp(bl)	// Can refine later [Aru]
 
 int attr_fix_table[4][ELE_MAX][ELE_MAX];
@@ -3094,8 +3097,24 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
 		case BL_MOB:
 		{
 			TBL_MOB*md = (TBL_MOB*)s_bl;
+#ifdef RECURSIVE_MASTER_CHECK
+			struct block_list *tmp_bl = NULL;
+			TBL_MOB *tmp_md = NULL;
+#endif
 			if (!agit_flag && md->guardian_data && md->guardian_data->guild_id)
 				return 0; //Disable guardians/emperium owned by Guilds on non-woe times.
+#ifdef RECURSIVE_MASTER_CHECK
+			tmp_md = md;
+			while(tmp_md->master_id && (tmp_bl = map_id2bl(tmp_md->master_id))){
+				if(t_bl->id == tmp_bl->id){
+					state |= BCT_PARTY;
+					break;
+				}
+				if(tmp_bl->type != BL_MOB)
+					break;
+				tmp_md = (TBL_MOB *)tmp_bl;
+			}
+#endif
 			if(md->state.killer) // Is on a rampage too :D
 				state |= BCT_ENEMY;
 			else if (!md->special_state.ai) { //Normal mobs.

+ 7 - 5
src/map/clif.c

@@ -2463,8 +2463,9 @@ int clif_updatestatus(struct map_session_data *sd,int type)
 		// 00b0
 	case SP_WEIGHT:
 		pc_checkweighticon(sd);
-		WFIFOW(fd,0)=0xb0;
-		WFIFOW(fd,2)=type;	//Added this packet back, Temp fix to the slow motion [Lupus]
+		// Redundancy? Look above.. - [Lance]
+		//WFIFOW(fd,0)=0xb0;
+		//WFIFOW(fd,2)=type;	//Added this packet back, Temp fix to the slow motion [Lupus]
 		WFIFOL(fd,4)=sd->weight;
 		break;
 	case SP_MAXWEIGHT:
@@ -2479,6 +2480,9 @@ int clif_updatestatus(struct map_session_data *sd,int type)
 	case SP_JOBLEVEL:
 		WFIFOL(fd,4)=sd->status.job_level;
 		break;
+	case SP_KARMA: // Adding this back, I wonder if the client intercepts this - [Lance]
+		WFIFOL(fd,4)=sd->status.karma;
+		break;
 	case SP_MANNER:
 		WFIFOL(fd,4)=sd->status.manner;
 		clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner);
@@ -9152,9 +9156,7 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
 	if (!bl) return;
 	switch (bl->type) {
 		case BL_MOB:
-			if (((TBL_MOB *)bl)->nd)
-				npc_click(sd, bl);
-			else
+			if (!((TBL_MOB *)bl)->nd || !mob_script_callback((TBL_MOB *)bl, &sd->bl, CALLBACK_NPCCLICK))
 				clif_parse_ActionRequest_sub(sd, 0x07, bl->id, gettick());
 			break;
 		case BL_PC:

+ 1 - 1
src/map/map.h

@@ -874,7 +874,7 @@ struct mob_data {
 	int master_id,master_dist;
 
 	struct npc_data *nd;
-	unsigned char callback_flag;
+	unsigned short callback_flag;
 	
 	short skillidx;
 	unsigned int skilldelay[MAX_MOBSKILL];

+ 0 - 1
src/map/mob.c

@@ -1509,7 +1509,6 @@ int mob_convertslave_sub(struct block_list *bl,va_list ap)
 	md2=va_arg(ap,TBL_MOB *);
 
 	if(md->master_id > 0 && md->master_id == md2->bl.id){
-		md->master_id = md2->master_id;
 		md->state.killer = md2->state.killer;
 		md->special_state.ai = md2->special_state.ai;
 		md->nd = md2->nd;

+ 1 - 0
src/map/mob.h

@@ -26,6 +26,7 @@
 #define MOB_CLONE_END 10000
 
 // Scripted Mob AI Constants
+#define CALLBACK_NPCCLICK	0x100
 #define CALLBACK_ATTACK		0x80
 #define CALLBACK_DETECT		0x40
 #define CALLBACK_DEAD		0x20

+ 0 - 7
src/map/npc.c

@@ -1089,13 +1089,6 @@ int npc_click(struct map_session_data *sd,struct block_list *bl)
 
 	if(!bl) return 1;
 	switch(bl->type){
-		case BL_MOB:
-			if (npc_checknear2(sd,bl))
-				return 1;
-			if((nd = ((TBL_MOB *)bl)->nd) == NULL)
-				return 1;
-			setd_sub(NULL,sd,"@smc_target",0,(void *)bl->id, NULL);
-			break;
 		case BL_NPC:
 			if ((nd = npc_checknear(sd,bl)) == NULL)
 				return 1;

+ 222 - 296
src/map/script.c

@@ -364,8 +364,6 @@ int buildin_checkoption1(struct script_state *st); // [celest]
 int buildin_checkoption2(struct script_state *st); // [celest]
 int buildin_guildgetexp(struct script_state *st); // [celest]
 int buildin_guildchangegm(struct script_state *st); // [Skotlex]
-int buildin_skilluseid(struct script_state *st); // originally by Qamera [celest]
-int buildin_skillusepos(struct script_state *st); // originally by Qamera [celest]
 int buildin_logmes(struct script_state *st); // [Lupus]
 int buildin_summon(struct script_state *st); // [celest]
 int buildin_isnight(struct script_state *st); // [celest]
@@ -414,29 +412,26 @@ int buildin_setbattleflag(struct script_state *st);
 int buildin_getbattleflag(struct script_state *st);
 // [zBuffer] List of player cont commands --->
 int buildin_rid2name(struct script_state *st);
-int buildin_pcwalkxy(struct script_state *st);
-int buildin_pctalk(struct script_state *st);
-int buildin_pcemote(struct script_state *st);
 int buildin_pcfollow(struct script_state *st);
 int buildin_pcstopfollow(struct script_state *st);
 int buildin_pcblockmove(struct script_state *st);
-int buildin_pcattack(struct script_state *st);
 // <--- [zBuffer] List of player cont commands
 // [zBuffer] List of mob control commands --->
-int buildin_spawnmob(struct script_state *st);
-int buildin_removemob(struct script_state *st);
-int buildin_mobwalk(struct script_state *st);
-int buildin_mobwarp(struct script_state *st);
+int buildin_mobspawn(struct script_state *st);
+int buildin_mobremove(struct script_state *st);
 int buildin_getmobdata(struct script_state *st);
 int buildin_setmobdata(struct script_state *st);
-int buildin_mobattack(struct script_state *st);
-int buildin_mobrandomwalk(struct script_state *st);
-int buildin_mobstop(struct script_state *st);
 int buildin_mobassist(struct script_state *st);
-int buildin_mobtalk(struct script_state *st);
-int buildin_mobemote(struct script_state *st);
-int buildin_mobdeadsit(struct script_state *st);
 int buildin_mobattach(struct script_state *st);
+int buildin_unitwalk(struct script_state *st);
+int buildin_unitwarp(struct script_state *st);
+int buildin_unitattack(struct script_state *st);
+int buildin_unitstop(struct script_state *st);
+int buildin_unittalk(struct script_state *st);
+int buildin_unitemote(struct script_state *st);
+int buildin_unitdeadsit(struct script_state *st);
+int buildin_unitskilluseid(struct script_state *st); // originally by Qamera [celest]
+int buildin_unitskillusepos(struct script_state *st); // originally by Qamera [celest]
 // <--- [zBuffer] List of mob control commands
 int buildin_sleep(struct script_state *st);
 int buildin_sleep2(struct script_state *st);
@@ -699,9 +694,6 @@ struct {
 	{buildin_checkoption2,"checkoption2","i"},
 	{buildin_guildgetexp,"guildgetexp","i"},
 	{buildin_guildchangegm,"guildchangegm","is"},
-	{buildin_skilluseid,"skilluseid","ii*"}, // originally by Qamera [Celest]
-	{buildin_skilluseid,"doskill","ii*"}, // since a lot of scripts would already use 'doskill'...
-	{buildin_skillusepos,"skillusepos","iiii*"}, // [Celest]
 	{buildin_logmes,"logmes","s"}, //this command actls as MES but rints info into LOG file either SQL/TXT [Lupus]
 	{buildin_summon,"summon","si*"}, // summons a slave monster [Celest]
 	{buildin_isnight,"isnight",""}, // check whether it is night time [Celest]
@@ -760,31 +752,28 @@ struct {
 	{buildin_getmonsterinfo,"getmonsterinfo","ii"}, //Lupus
 	// [zBuffer] List of player cont commands --->
 	{buildin_rid2name,"rid2name","i"},
-	{buildin_pcwalkxy,"pcwalkxy","iii"},
-	{buildin_pctalk,"pctalk","is"},
-	{buildin_pcemote,"pcemote","ii"},
 	{buildin_pcfollow,"pcfollow","ii"},
 	{buildin_pcstopfollow,"pcstopfollow","i"},
 	{buildin_pcblockmove,"pcblockmove","ii"},
-	{buildin_pcattack,"pcattack","iii"},
 	// <--- [zBuffer] List of player cont commands
 	// [zBuffer] List of mob control commands --->
-	{buildin_spawnmob,"spawnmob","*"},
-	{buildin_removemob,"removemob","i"},
-	{buildin_mobwalk,"mobwalk","i*"},
-	{buildin_mobwarp,"mobwarp","isii"},
-	{buildin_mobrandomwalk,"mobrandomwalk","ii"},
+	{buildin_mobspawn,"mobspawn","*"},
+	{buildin_mobremove,"mobremove","i"},
 	{buildin_getmobdata,"getmobdata","i*"},
 	{buildin_setmobdata,"setmobdata","iii"},
-	{buildin_mobattack,"mobattack","i*"},
-	{buildin_mobstop,"mobstop","i"},
 	{buildin_mobassist,"mobassist","i*"},
-	{buildin_mobtalk,"mobtalk","is"},
-	{buildin_mobemote,"mobemote","ii"},
-	{buildin_mobdeadsit,"mobdeadsit","ii"},
 	{buildin_mobattach,"mobattach","i*"},
+	{buildin_unitwalk,"unitwalk","i*"},
+	{buildin_unitwarp,"unitwarp","isii"},
+	{buildin_unitattack,"unitattack","i*"},
+	{buildin_unitstop,"unitstop","i"},
+	{buildin_unittalk,"unittalk","is"},
+	{buildin_unitemote,"unitemote","ii"},
+	{buildin_unitdeadsit,"unitdeadsit","ii"},
+	{buildin_unitskilluseid,"unitskilluseid","iii*"}, // originally by Qamera [Celest]
+	{buildin_unitskillusepos,"unitskillusepos","iiiii"}, // [Celest]
 // <--- [zBuffer] List of mob control commands
-{buildin_sleep,"sleep","i"},
+	{buildin_sleep,"sleep","i"},
 	{buildin_sleep2,"sleep2","i"},
 	{buildin_awake,"awake","s"},
 	{buildin_getvariableofnpc,"getvariableofnpc","is"},
@@ -9355,53 +9344,6 @@ int buildin_getmapxy(struct script_state *st){
         return 0;
 }
 
-/*=====================================================
- * Allows players to use a skill - by Qamera
- *-----------------------------------------------------
- */
-int buildin_skilluseid (struct script_state *st)
-{
-	int skid,sklv;
-	struct map_session_data *sd;
-
-	skid=conv_num(st,& (st->stack->stack_data[st->start+2]));
-	sklv=conv_num(st,& (st->stack->stack_data[st->start+3]));
-	if(st->end > st->start+4)
-		sd=(TBL_PC *)map_id2bl(conv_num(st,& (st->stack->stack_data[st->start+4])));
-	else
-		sd=script_rid2sd(st);
-
-	if (sd)
-		unit_skilluse_id(&sd->bl,(st->end>st->start+5)?conv_num(st,& (st->stack->stack_data[st->start+5])):sd->bl.id,skid,sklv);
-
-	return 0;
-}
-
-/*=====================================================
- * Allows players to use a skill on a position [Celest]
- *-----------------------------------------------------
- */
-int buildin_skillusepos(struct script_state *st)
-{
-	int skid,sklv,x,y;
-	struct map_session_data *sd;
-
-	skid=conv_num(st,& (st->stack->stack_data[st->start+2]));
-	sklv=conv_num(st,& (st->stack->stack_data[st->start+3]));
-	x=conv_num(st,& (st->stack->stack_data[st->start+4]));
-	y=conv_num(st,& (st->stack->stack_data[st->start+5]));
-
-	if(st->end > st->start+5)
-		sd=(TBL_PC *)map_id2bl(conv_num(st,& (st->stack->stack_data[st->start+5])));
-	else
-		sd=script_rid2sd(st);
-
-	if (sd)
-		unit_skilluse_pos(&sd->bl,x,y,skid,sklv);
-
-	return 0;
-}
-
 /*==========================================
  * Allows player to write NPC logs (i.e. Bank NPC, etc) [Lupus]
  *------------------------------------------
@@ -10433,30 +10375,6 @@ int buildin_rid2name(struct script_state *st){
 	return 0;
 }
 
-int buildin_pcwalkxy(struct script_state *st){
-	int id, x, y = 0;
-	struct map_session_data *sd = NULL;
-
-	id = conv_num(st, & (st->stack->stack_data[st->start + 2]));
-	x = conv_num(st, & (st->stack->stack_data[st->start + 3]));
-	if(st->end > st->start + 4)
-		y = conv_num(st, & (st->stack->stack_data[st->start + 4]));
-
-	if(id)
-		sd = map_id2sd(id);
-	else
-		sd = script_rid2sd(st);
-
-	if(sd){
-		if(y)
-			unit_walktoxy(&sd->bl, x, y, 0);
-		else
-			unit_walktobl(&sd->bl, map_id2bl(x), 65535, 1);
-	}
-
-	return 0;
-}
-
 int buildin_pcblockmove(struct script_state *st){
 	int id, flag;
 	struct map_session_data *sd = NULL;
@@ -10475,66 +10393,6 @@ int buildin_pcblockmove(struct script_state *st){
 	return 0;
 }
 
-int buildin_pctalk(struct script_state *st){
-	int id;
-	char *str;
-	char message[255];
-	struct map_session_data *sd = NULL;
-
-	id = conv_num(st, & (st->stack->stack_data[st->start + 2]));
-	str = conv_str(st, & (st->stack->stack_data[st->start + 3]));
-
-	if(id)
-		sd = map_id2sd(id);
-	else
-		sd = script_rid2sd(st);
-
-	if(sd){
-		memcpy(message, sd->status.name, NAME_LENGTH);
-		strcat(message," : ");
-		strncat(message,str, 254); //Prevent overflow possibility. [Skotlex]
-		clif_message(&(sd->bl), message);
-		clif_displaymessage(sd->fd, message);
-	}
-
-	return 0;
-}
-
-int buildin_pcattack(struct script_state *st) {
-	struct map_session_data *sd = NULL;
-
-	int id = conv_num(st, & (st->stack->stack_data[st->start + 2]));
-
-	if(id)
-		sd = map_id2sd(id);
-	else
-		sd = script_rid2sd(st);
-
-	if(sd)
-		clif_parse_ActionRequest_sub(sd, conv_num(st, & (st->stack->stack_data[st->start + 4]))>0?0x07:0x00, conv_num(st, & (st->stack->stack_data[st->start + 3])), gettick());
-
-	return 0;
-}
-
-int buildin_pcemote(struct script_state *st) {
-	int id, emo;
-	struct map_session_data *sd = NULL;
-
-	id = conv_num(st, & (st->stack->stack_data[st->start + 2]));
-	emo = conv_num(st, & (st->stack->stack_data[st->start + 3]));
-
-	if(id)
-		sd = map_id2sd(id);
-	else
-		sd = script_rid2sd(st);
-
-	if(sd)
-		clif_emotion(&sd->bl,emo);
-
-	return 0;
-
-}
-
 int buildin_pcfollow(struct script_state *st) {
 	int id, targetid;
 	struct map_session_data *sd = NULL;
@@ -10573,7 +10431,7 @@ int buildin_pcstopfollow(struct script_state *st) {
 }
 // <--- [zBuffer] List of player cont commands
 // [zBuffer] List of mob control commands --->
-int buildin_spawnmob(struct script_state *st){
+int buildin_mobspawn(struct script_state *st){
 	int class_,x,y,id;
 	char *str,*map,*event="";
 
@@ -10597,7 +10455,7 @@ int buildin_spawnmob(struct script_state *st){
 	return 0;
 }
 
-int buildin_removemob(struct script_state *st) {
+int buildin_mobremove(struct script_state *st) {
 	int id;
 	struct block_list *bl = NULL;
 	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
@@ -10609,47 +10467,6 @@ int buildin_removemob(struct script_state *st) {
 	return 0;
 }
 
-int buildin_mobwalk(struct script_state *st){
-	int id,x,y = 0;
-	struct block_list *bl = NULL;
-
-	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
-	x = conv_num(st, & (st->stack->stack_data[st->start+3]));
-	if(st->end > st->start+4)
-		y = conv_num(st, & (st->stack->stack_data[st->start+4]));
-
-	bl = map_id2bl(id);
-	if(bl && bl->type == BL_MOB){
-		if(y)
-			push_val(st->stack,C_INT,unit_walktoxy(bl,x,y,0)); // We'll use harder calculations.
-		else
-			push_val(st->stack,C_INT,unit_walktobl(bl,map_id2bl(x),1,65025));
-	} else {
-		push_val(st->stack,C_INT,0);
-	}
-
-	return 0;
-}
-
-int buildin_mobwarp(struct script_state *st){
-	int id,x,y,m = 0;
-	char *map;
-	struct block_list *bl = NULL;
-
-	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
-	map = conv_str(st, & (st->stack->stack_data[st->start+3]));
-	x = conv_num(st, & (st->stack->stack_data[st->start+4]));
-	y = conv_num(st, & (st->stack->stack_data[st->start+5]));
-
-	bl = map_id2bl(id);
-	m = mapindex_name2id(map);
-	if(m && bl){
-		unit_warp(bl, m, (short)x, (short)y, 0);
-	}
-
-	return 0;
-}
-
 int buildin_getmobdata(struct script_state *st) {
 	int num, id;
 	char *name;
@@ -10689,6 +10506,8 @@ int buildin_getmobdata(struct script_state *st) {
 	setd_sub(st,sd,name,22,(void *)(int)md->vd->shield,st->stack->stack_data[st->start+3].ref);
 	setd_sub(st,sd,name,23,(void *)(int)md->ud.dir,st->stack->stack_data[st->start+3].ref);
 	setd_sub(st,sd,name,24,(void *)(int)md->state.killer,st->stack->stack_data[st->start+3].ref);
+	setd_sub(st,sd,name,25,(void *)(int)md->callback_flag,st->stack->stack_data[st->start+3].ref);
+	setd_sub(st,sd,name,26,(void *)(int)md->state.no_random_walk, st->stack->stack_data[st->start+3].ref);
 	return 0;
 }
 
@@ -10779,7 +10598,10 @@ int buildin_setmobdata(struct script_state *st){
 			md->state.killer = value2>0?1:0;
 			break;
 		case 25:
-			md->callback_flag = (unsigned char)value2;
+			md->callback_flag = (short)value2;
+			break;
+		case 26:
+			md->state.no_random_walk = value2>0?1:0;
 			break;
 		default:
 			ShowError("buildin_setmobdata: argument id is not identified.");
@@ -10788,164 +10610,268 @@ int buildin_setmobdata(struct script_state *st){
 	return 0;
 }
 
-int buildin_mobattack(struct script_state *st) {
-	int id = 0;
-	char *target = NULL;
+int buildin_mobassist(struct script_state *st) {
+	int id;
+	char *target;
 	struct mob_data *md = NULL;
-	struct map_session_data *sd = NULL;
 	struct block_list *bl = NULL;
+	struct unit_data *ud;
 	
 	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
-	if(st->end > st->start + 3)
-		target = conv_str(st, & (st->stack->stack_data[st->start+3]));
-
-	if(target){
-		sd = map_nick2sd(target);
-		if(!sd)
-			bl = map_id2bl(atoi(target));
-		else
-			bl = &sd->bl;
-	}
+	target = conv_str(st, & (st->stack->stack_data[st->start+3]));
 
-	if((md = (struct mob_data *)map_id2bl(id))){
-		if (md && md->bl.type == BL_MOB) {
+	if((bl =&(map_nick2sd(target)->bl)) || (bl = map_id2bl(atoi(target)))) {
+		md = (struct mob_data *)map_id2bl(id);
+		if(md && md->bl.type == BL_MOB) {
+			ud = unit_bl2ud(bl);
+			md->master_id = bl->id;
 			md->state.killer = 1;
-			md->special_state.ai = 1;
-			if(bl){
-				md->target_id = bl->id;
-				unit_walktobl(&md->bl, bl, 65025, 2);
+			mob_convertslave(md);
+			if (ud) {
+				if (ud->target)
+					md->target_id = ud->target;
+				else if (ud->skilltarget)
+					md->target_id = ud->skilltarget;
+				if(md->target_id)
+					unit_walktobl(&md->bl, map_id2bl(md->target_id), 65025, 2);
 			}
 		}
 	}
-
 	return 0;
 }
 
-int buildin_mobstop(struct script_state *st) {
+int buildin_mobattach(struct script_state *st){
 	int id;
+	struct mob_data *md = NULL;
+	struct npc_data *nd = NULL;
+	char *npcname = NULL;
+	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
+	if(st->end > st->start + 3){
+		npcname = conv_str(st, & (st->stack->stack_data[st->start+3]));
+	}
+
+	if(npcname)
+		nd = npc_name2id(npcname);
+	else
+		nd = (struct npc_data *)map_id2bl(st->oid);
+
+	if(nd)
+		if((md = (struct mob_data *)map_id2bl(id)) && md->bl.type == BL_MOB)
+			md->nd = nd;
+
+	return 0;
+}
+
+int buildin_unitwalk(struct script_state *st){
+	int id,x,y = 0;
 	struct block_list *bl = NULL;
 
 	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
+	x = conv_num(st, & (st->stack->stack_data[st->start+3]));
+	if(st->end > st->start+4)
+		y = conv_num(st, & (st->stack->stack_data[st->start+4]));
 
 	bl = map_id2bl(id);
-	if(bl && bl->type == BL_MOB){
-		unit_stop_attack(bl);
-		unit_stop_walking(bl,0);
-		((TBL_MOB *)bl)->target_id = 0;
+	if(bl){
+		if(y)
+			push_val(st->stack,C_INT,unit_walktoxy(bl,x,y,0)); // We'll use harder calculations.
+		else
+			push_val(st->stack,C_INT,unit_walktobl(bl,map_id2bl(x),65025,1));
+	} else {
+		push_val(st->stack,C_INT,0);
 	}
 
 	return 0;
 }
 
-int buildin_mobrandomwalk(struct script_state *st){
-	int id = conv_num(st, &(st->stack->stack_data[st->start+2]));
-	int flag = conv_num(st, &(st->stack->stack_data[st->start+3]));
-	struct mob_data *md = (struct mob_data *)map_id2bl(id);
-	if(md->bl.type == BL_MOB){
-		md->state.no_random_walk = flag>0?0:1;
+int buildin_unitwarp(struct script_state *st){
+	int id,x,y,m = 0;
+	char *map;
+	struct block_list *bl = NULL;
+
+	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
+	map = conv_str(st, & (st->stack->stack_data[st->start+3]));
+	x = conv_num(st, & (st->stack->stack_data[st->start+4]));
+	y = conv_num(st, & (st->stack->stack_data[st->start+5]));
+
+	bl = map_id2bl(id);
+	m = mapindex_name2id(map);
+	if(m && bl){
+		push_val(st->stack,C_INT,unit_warp(bl, m, (short)x, (short)y, 0));
+	} else {
+		push_val(st->stack,C_INT,0);
 	}
+
 	return 0;
 }
 
-int buildin_mobassist(struct script_state *st) {
-	int id;
-	char *target;
+int buildin_unitattack(struct script_state *st) {
+	int id = 0;
+	char *target = NULL;
 	struct mob_data *md = NULL;
-	struct block_list *bl = NULL;
-	struct unit_data *ud;
+	struct map_session_data *sd = NULL;
+	struct block_list *bl = NULL, *tbl = NULL;
 	
 	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
-	target = conv_str(st, & (st->stack->stack_data[st->start+3]));
+	if(st->end > st->start + 3)
+		target = conv_str(st, & (st->stack->stack_data[st->start+3]));
 
-	if((bl =&(map_nick2sd(target)->bl)) || (bl = map_id2bl(atoi(target)))) {
-		md = (struct mob_data *)map_id2bl(id);
-		if(md && md->bl.type == BL_MOB) {
-			ud = unit_bl2ud(bl);
-			md->master_id = bl->id;
+	if(target){
+		sd = map_nick2sd(target);
+		if(!sd)
+			tbl = map_id2bl(atoi(target));
+		else
+			tbl = &sd->bl;
+	}
+
+	if(tbl && (bl = map_id2bl(id))){
+		if (bl->type == BL_MOB) {
 			md->state.killer = 1;
-			mob_convertslave(md);
-			if (ud) {
-				if (ud->target)
-					md->target_id = ud->target;
-				else if (ud->skilltarget)
-					md->target_id = ud->skilltarget;
-				if(md->target_id)
-					unit_walktobl(&md->bl, map_id2bl(md->target_id), 65025, 2);
-			}
+			md->target_id = bl->id;
 		}
+		push_val(st->stack,C_INT,unit_walktobl(bl, tbl, 65025, 2));
+	} else {
+		push_val(st->stack,C_INT,0);
 	}
+
 	return 0;
 }
 
-int buildin_mobtalk(struct script_state *st)
+int buildin_unitstop(struct script_state *st) {
+	int id;
+	struct block_list *bl = NULL;
+
+	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
+
+	bl = map_id2bl(id);
+	if(bl){
+		unit_stop_attack(bl);
+		unit_stop_walking(bl,0);
+		if(bl->type == BL_MOB)
+			((TBL_MOB *)bl)->target_id = 0;
+	}
+
+	return 0;
+}
+
+int buildin_unittalk(struct script_state *st)
 {
 	char *str;
 	int id;
 	char message[255];
 
-	struct mob_data *md = NULL;
+	struct block_list *bl = NULL;
 
 	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
 	str=conv_str(st,& (st->stack->stack_data[st->start+3]));
 
-	md = (struct mob_data *)map_id2bl(id);
-	if(md && md->bl.type == BL_MOB) {
-		memcpy(message, md->name, NAME_LENGTH);
+	bl = map_id2bl(id);
+	if(bl) {
+		switch(bl->type){
+			case BL_MOB:
+				memcpy(message, ((TBL_MOB *)bl)->name, NAME_LENGTH);
+				break;
+			case BL_PC:
+				if(strlen(((TBL_PC *)bl)->fakename)>0)
+					memcpy(message, ((TBL_PC *)bl)->fakename, NAME_LENGTH);
+				else
+					memcpy(message, ((TBL_PC *)bl)->status.name, NAME_LENGTH);
+				break;
+			case BL_NPC:
+				memcpy(message, ((TBL_NPC *)bl)->name, NAME_LENGTH);
+				break;
+			case BL_HOMUNCULUS:
+				memcpy(message, ((TBL_HOMUNCULUS *)bl)->name, NAME_LENGTH);
+				break;
+			case BL_PET:
+				memcpy(message, ((TBL_PET *)bl)->name, NAME_LENGTH);
+				break;
+			default:
+				strcpy(message, "Unknown");
+		}
 		strcat(message," : ");
-		strncat(message,str, 254); //Prevent overflow possibility. [Skotlex]
-		clif_message(&(md->bl), message);
+		strncat(message,str, 228); //Prevent overflow possibility. [Skotlex]
+		clif_message(bl, message);
+		if(bl->type == BL_PC)
+			clif_displaymessage(((TBL_PC*)bl)->fd, message);
 	}
 
 	return 0;
 }
 
-int buildin_mobemote(struct script_state *st) {
+int buildin_unitemote(struct script_state *st) {
 	int id, emo;
-	struct mob_data *md = NULL;
+	struct block_list *bl= NULL;
 	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
 	emo = conv_num(st, & (st->stack->stack_data[st->start+3]));
-	if((md = (struct mob_data *)map_id2bl(id)) && md->bl.type == BL_MOB)
-		clif_emotion(&md->bl,emo);
+	if((bl = map_id2bl(id)))
+		clif_emotion(bl,emo);
 	return 0;
 }
 
-int buildin_mobdeadsit(struct script_state *st){
+int buildin_unitdeadsit(struct script_state *st){
 	int id, action;
-	struct mob_data *md = NULL;
+	struct block_list *bl = NULL;
 	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
 	action = conv_num(st, & (st->stack->stack_data[st->start+3]));
-	if((md = (struct mob_data *)map_id2bl(id)) && md->bl.type == BL_MOB){
+	if((bl = map_id2bl(id))){
 		if(action > -1 && action < 3){
-			md->vd->dead_sit = action;
-		} else {
-			ShowError("buildin_mobdeadsit: Unrecognized action.\n");
+			switch(bl->type){
+				case BL_MOB:
+					((TBL_MOB *)bl)->vd->dead_sit = action;
+					break;
+				case BL_PC:
+					((TBL_PC *)bl)->vd.dead_sit = action;
+					break;
+				case BL_NPC:
+					((TBL_NPC *)bl)->vd->dead_sit = action;
+					break;
+				case BL_HOMUNCULUS:
+					((TBL_HOMUNCULUS *)bl)->vd->dead_sit = action;
+					break;
+				case BL_PET:
+					((TBL_PET *)bl)->vd.dead_sit = action;
+					break;
+			}
+		}else {
+			ShowError("buildin_unitdeadsit: Invalid action.\n");
 			report_src(st);
 		}
-	} else {
-		ShowError("buildin_mobdeadsit: Target is not a monster.\n");
+	}else{
+		ShowError("buildin_unitdeadsit: Target is not found.\n");
 		report_src(st);
 	}
 	return 0;
 }
 
-int buildin_mobattach(struct script_state *st){
-	int id;
-	struct mob_data *md = NULL;
-	struct npc_data *nd = NULL;
-	char *npcname = NULL;
-	id = conv_num(st, & (st->stack->stack_data[st->start+2]));
-	if(st->end > st->start + 3){
-		npcname = conv_str(st, & (st->stack->stack_data[st->start+3]));
-	}
+int buildin_unitskilluseid (struct script_state *st)
+{
+	int id,skid,sklv;
+	struct block_list *bl = NULL;
 
-	if(npcname)
-		nd = npc_name2id(npcname);
-	else
-		nd = (struct npc_data *)map_id2bl(st->oid);
+	id = conv_num(st,& (st->stack->stack_data[st->start+2]));
+	skid=conv_num(st,& (st->stack->stack_data[st->start+3]));
+	sklv=conv_num(st,& (st->stack->stack_data[st->start+4]));
 
-	if(nd)
-		if((md = (struct mob_data *)map_id2bl(id)) && md->bl.type == BL_MOB)
-			md->nd = nd;
+	if ((bl = map_id2bl(id)))
+		unit_skilluse_id(bl,(st->end>st->start+5)?conv_num(st,& (st->stack->stack_data[st->start+5])):bl->id,skid,sklv);
+
+	return 0;
+}
+
+int buildin_unitskillusepos(struct script_state *st)
+{
+	int skid,sklv,x,y,id;
+	struct block_list *bl = NULL;
+
+	id = conv_num(st,& (st->stack->stack_data[st->start+2]));
+	skid=conv_num(st,& (st->stack->stack_data[st->start+3]));
+	sklv=conv_num(st,& (st->stack->stack_data[st->start+4]));
+	x=conv_num(st,& (st->stack->stack_data[st->start+5]));
+	y=conv_num(st,& (st->stack->stack_data[st->start+6]));
+
+	if ((bl=map_id2bl(id)))
+		unit_skilluse_pos(bl,x,y,skid,sklv);
 
 	return 0;
 }