Bläddra i källkod

* Implemented `useskilltopc' (tid:74685), and now if desired npcs can carry status such as str, atk, def, etc and level.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17048 54d463be-8e91-2dee-dedb-b68131a5f0ec
momacabu 12 år sedan
förälder
incheckning
825ddd053c
4 ändrade filer med 97 tillägg och 6 borttagningar
  1. 4 0
      src/map/npc.h
  2. 54 6
      src/map/script.c
  3. 38 0
      src/map/status.c
  4. 1 0
      src/map/status.h

+ 4 - 0
src/map/npc.h

@@ -39,6 +39,10 @@ struct npc_data {
 
 	unsigned size : 2;
 
+	struct status_data status;
+	unsigned int level;
+	unsigned int stat_point;
+
 	void* chatdb; // pointer to a npc_parse struct (see npc_chat.c)
 	char* path;/* path dir */
 	enum npc_subtype subtype;

+ 54 - 6
src/map/script.c

@@ -17254,9 +17254,9 @@ BUILDIN_FUNC(cleanmap)
 		map_foreachinmap(atcommand_cleanfloor_sub, m, BL_ITEM);
 	} else {
 		x0 = script_getnum(st, 3);
-				y0 = script_getnum(st, 4);
-				x1 = script_getnum(st, 5);
-				y1 = script_getnum(st, 6);
+		y0 = script_getnum(st, 4);
+		x1 = script_getnum(st, 5);
+		y1 = script_getnum(st, 6);
 		if (x0 > 0 && y0 > 0 && x1 > 0 && y1 > 0) {
 			map_foreachinarea(atcommand_cleanfloor_sub, m, x0, y0, x1, y1, BL_ITEM);
 		} else {
@@ -17267,7 +17267,54 @@ BUILDIN_FUNC(cleanmap)
 	
 	return 0;
 }
+/* Cast a skill on the attached player.
+ * useskilltopc <skill_id>, <skill_level>, <stat_point>, <npc_level>;
+ * useskilltopc "<skill_name>", <skill_level>, <stat_point>, <npc_level>; */
+BUILDIN_FUNC(useskilltopc)
+{
+	unsigned int skill_id;
+	unsigned short skill_level;
+	unsigned int stat_point;
+	unsigned int npc_level;
+	struct npc_data *nd;
+	struct map_session_data *sd;
+
+	skill_id	= script_isstring(st, 2) ? skill_name2id(script_getstr(st, 2)) : script_getnum(st, 2);
+	skill_level	= script_getnum(st, 3);
+	stat_point	= script_getnum(st, 4);
+	npc_level	= script_getnum(st, 5);
+	sd			= script_rid2sd(st);
+	nd			= (struct npc_data *)map_id2bl(sd->npc_id);
+
+	if (stat_point > battle_config.max_third_parameter) {
+		ShowError("useskilltopc: stat point exceeded maximum of %d.\n",battle_config.max_third_parameter );
+		return 1;
+	}
+	if (npc_level > MAX_LEVEL) {
+		ShowError("useskilltopc: level exceeded maximum of %d.\n", MAX_LEVEL);
+		return 1;
+	}
+	if (sd == NULL || nd == NULL) { //ain't possible, but I don't trust people.
+		return 1;
+	}
+
+	nd->level = npc_level;
+	nd->stat_point = stat_point;
+
+	if (!nd->status.hp) {
+		status_calc_npc(nd, true);
+	} else {
+		status_calc_npc(nd, false);
+	}
 
+	if (skill_get_inf(skill_id)&INF_GROUND_SKILL) {
+		unit_skilluse_pos(&nd->bl, sd->bl.x, sd->bl.y, skill_id, skill_level);
+	} else {
+		unit_skilluse_id(&nd->bl, sd->bl.id, skill_id, skill_level);
+	}
+
+	return 0;
+}
 
 // declarations that were supposed to be exported from npc_chat.c
 #ifdef PCRE_SUPPORT
@@ -17708,9 +17755,10 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(is_function,"s"),
 	BUILDIN_DEF(get_revision,""),
 	BUILDIN_DEF(freeloop,"i"),
-	BUILDIN_DEF(getrandgroupitem, "ii"),
-	BUILDIN_DEF(cleanmap, "s"),
-	BUILDIN_DEF2(cleanmap, "cleanarea", "siiii"),
+	BUILDIN_DEF(getrandgroupitem,"ii"),
+	BUILDIN_DEF(cleanmap,"s"),
+	BUILDIN_DEF2(cleanmap,"cleanarea","siiii"),
+	BUILDIN_DEF(useskilltopc,"viii"),
 	/**
 	 * @commands (script based)
 	 **/

+ 38 - 0
src/map/status.c

@@ -3225,6 +3225,40 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) {
 	return 0;
 }
 
+int status_calc_npc_(struct npc_data *nd, bool first) {
+	struct status_data *status = &nd->status;
+	
+	if (!nd)
+		return 0;
+	
+	if (first) {
+		status->hp = 1;
+		status->sp = 1;
+		status->max_hp = 1;
+		status->max_sp = 1;
+		
+		status->def_ele = ELE_NEUTRAL;
+		status->ele_lv = 1;
+		status->race = RC_DEMIHUMAN;
+		status->size = nd->size;
+		status->rhw.range = 1 + status->size;
+		status->mode = MD_CANMOVE|MD_CANATTACK;
+		status->speed = nd->speed;
+	}
+
+	status->str = nd->stat_point;
+	status->agi = nd->stat_point;
+	status->vit = nd->stat_point;
+	status->int_= nd->stat_point;
+	status->dex = nd->stat_point;
+	status->luk = nd->stat_point;
+	
+	status_calc_misc(&nd->bl, status, nd->level);
+	status_cpy(&nd->status, status);
+
+	return 0;
+}
+
 static unsigned short status_calc_str(struct block_list *,struct status_change *,int);
 static unsigned short status_calc_agi(struct block_list *,struct status_change *,int);
 static unsigned short status_calc_vit(struct block_list *,struct status_change *,int);
@@ -3963,6 +3997,7 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first)
 		case BL_HOM: status_calc_homunculus_(BL_CAST(BL_HOM,bl), first); break;
 		case BL_MER: status_calc_mercenary_(BL_CAST(BL_MER,bl), first);  break;
 		case BL_ELEM: status_calc_elemental_(BL_CAST(BL_ELEM,bl), first);  break;
+		case BL_NPC: status_calc_npc_(BL_CAST(BL_NPC,bl), first); break;
 		}
 	}
 
@@ -5739,6 +5774,7 @@ int status_get_lv(struct block_list *bl) {
 		case BL_HOM: return ((TBL_HOM*)bl)->homunculus.level;
 		case BL_MER: return ((TBL_MER*)bl)->db->lv;
 		case BL_ELEM: return ((TBL_ELEM*)bl)->db->lv;
+		case BL_NPC: return ((TBL_NPC*)bl)->level;
 	}
 	return 1;
 }
@@ -5767,6 +5803,7 @@ struct status_data *status_get_status_data(struct block_list *bl)
 		case BL_HOM: return &((TBL_HOM*)bl)->battle_status;
 		case BL_MER: return &((TBL_MER*)bl)->battle_status;
 		case BL_ELEM: return &((TBL_ELEM*)bl)->battle_status;
+		case BL_NPC: return &((TBL_NPC*)bl)->status;
 		default:
 			return &dummy_status;
 	}
@@ -5782,6 +5819,7 @@ struct status_data *status_get_base_status(struct block_list *bl)
 		case BL_HOM: return &((TBL_HOM*)bl)->base_status;
 		case BL_MER: return &((TBL_MER*)bl)->base_status;
 		case BL_ELEM: return &((TBL_ELEM*)bl)->base_status;
+		case BL_NPC: return &((TBL_NPC*)bl)->status;
 		default:
 			return NULL;
 	}

+ 1 - 0
src/map/status.h

@@ -1786,6 +1786,7 @@ int status_change_clear_buffs(struct block_list* bl, int type);
 #define status_calc_homunculus(hd, first) status_calc_bl_(&(hd)->bl, SCB_ALL, first)
 #define status_calc_mercenary(md, first) status_calc_bl_(&(md)->bl, SCB_ALL, first)
 #define status_calc_elemental(ed, first) status_calc_bl_(&(ed)->bl, SCB_ALL, first)
+#define status_calc_npc(nd, first) status_calc_bl_(&(nd)->bl, SCB_ALL, first)
 
 void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first);
 int status_calc_mob_(struct mob_data* md, bool first);