Sfoglia il codice sorgente

* Dynamic shops support with script callback. (needs testing)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5841 54d463be-8e91-2dee-dedb-b68131a5f0ec
Lance 19 anni fa
parent
commit
e051037bce
5 ha cambiato i file con 90 aggiunte e 10 eliminazioni
  1. 1 0
      Changelog-Trunk.txt
  2. 35 8
      src/map/clif.c
  3. 1 0
      src/map/map.h
  4. 52 2
      src/map/script.c
  5. 1 0
      src/map/script.h

+ 1 - 0
Changelog-Trunk.txt

@@ -4,6 +4,7 @@ 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/01
+	* Dynamic shops support with script callback. (needs testing) [Lance]
 	* Cleaned up and fixed @where command. [Skotlex]
 	* Fixed standing up no really making you stand up. [Skotlex]
 	* Added upgrade_svn5834.sql to update view for item type 10. Because of the

+ 35 - 8
src/map/clif.c

@@ -8965,17 +8965,31 @@ void clif_parse_NpcBuySellSelected(int fd,struct map_session_data *sd)
  */
 void clif_parse_NpcBuyListSend(int fd,struct map_session_data *sd)
 {
-	int fail=0,n;
+	int fail=0,n, i;
 	unsigned short *item_list;
+	unsigned char npc_ev[51];
+	struct npc_data *nd;
 	RFIFOHEAD(fd);
 
 	n = (RFIFOW(fd,2)-4) /4;
 	item_list = (unsigned short*)RFIFOP(fd,4);
 
-	if (sd->trade_partner || !sd->npc_shopid)
+
+	if (sd->trade_partner || !sd->npc_shopid){
 		fail = 1;
-	else
-		fail = npc_buylist(sd,n,item_list);
+	}else{
+		if((nd = ((struct npc_data *)map_id2bl(sd->npc_shopid))->master_nd)){
+			sprintf(npc_ev, "%s::OnBuyItem", nd->exname);
+			for(i=0;i<n;i++){
+				setd_sub(sd, "@bought_nameid", i, (void *)item_list[i*2+1]);
+				setd_sub(sd, "@bought_quantity", i, (void *)item_list[i*2]);
+				npc_event(sd, npc_ev, 0);
+			}
+			fail = 0;
+		}else{
+			fail = npc_buylist(sd,n,item_list);
+		}
+	}
 
 	sd->npc_shopid = 0; //Clear shop data.
 	WFIFOHEAD(fd,packet_len_table[0xca]);
@@ -8990,17 +9004,30 @@ void clif_parse_NpcBuyListSend(int fd,struct map_session_data *sd)
  */
 void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd)
 {
-	int fail=0,n;
+	int fail=0,n,i;
 	unsigned short *item_list;
+	unsigned char npc_ev[51];
+	struct npc_data *nd;
 	RFIFOHEAD(fd);
 
 	n = (RFIFOW(fd,2)-4) /4;
 	item_list = (unsigned short*)RFIFOP(fd,4);
 
-	if (sd->trade_partner || !sd->npc_shopid)
+	if (sd->trade_partner || !sd->npc_shopid){
 		fail = 1;
-	else
-		fail = npc_selllist(sd,n,item_list);
+	}else{
+		if((nd = ((struct npc_data *)map_id2bl(sd->npc_shopid))->master_nd)){
+			sprintf(npc_ev, "%s::OnSellItem", nd->exname);
+			for(i=0;i<n;i++){
+				setd_sub(sd, "@sold_nameid", i, (void *)item_list[i*2+1]);
+				setd_sub(sd, "@sold_quantity", i, (void *)item_list[i*2]);
+				npc_event(sd, npc_ev, 0);
+			}
+			fail = 0;
+		}else{
+			fail = npc_selllist(sd,n,item_list);
+		}
+	}
 	sd->npc_shopid = 0; //Clear shop data.
 
 	WFIFOHEAD(fd,packet_len_table[0xcb]);

+ 1 - 0
src/map/map.h

@@ -794,6 +794,7 @@ struct npc_data {
 	short arenaflag;
 
 	void *chatdb;
+	struct npc_data *master_nd;
 
 	union {
 		struct {

+ 52 - 2
src/map/script.c

@@ -403,6 +403,7 @@ int buildin_setd(struct script_state *st);
 // <--- [zBuffer] List of dynamic var commands
 int buildin_petstat(struct script_state *st); // [Lance] Pet Stat Rq: Dubby
 int buildin_callshop(struct script_state *st); // [Skotlex]
+int buildin_npcshopitem(struct script_state *st); // [Lance]
 int buildin_equip(struct script_state *st);
 int buildin_autoequip(struct script_state *st);
 int buildin_setbattleflag(struct script_state *st);
@@ -730,6 +731,7 @@ struct {
 	// <--- [zBuffer] List of dynamic var commands
 	{buildin_petstat,"petstat","i"},
 	{buildin_callshop,"callshop","si"}, // [Skotlex]
+	{buildin_npcshopitem,"npcshopitem","*"}, // [Lance]
 	{buildin_equip,"equip","i"},
 	{buildin_autoequip,"autoequip","ii"},
 	{buildin_setbattleflag,"setbattleflag","ss"},
@@ -8127,7 +8129,7 @@ int buildin_soundeffect(struct script_state *st)
 	name=conv_str(st,& (st->stack->stack_data[st->start+2]));
 	type=conv_num(st,& (st->stack->stack_data[st->start+3]));
 	if(sd){
-		if(st->oid)
+		if(!st->rid)
 			clif_soundeffect(sd,map_id2bl(st->oid),name,type);
 		else{
 			clif_soundeffect(sd,&sd->bl,name,type);
@@ -8163,7 +8165,7 @@ int buildin_soundeffectall(struct script_state *st)
 	type=conv_num(st,& (st->stack->stack_data[st->start+3]));
 	coverage=conv_num(st,& (st->stack->stack_data[st->start+4]));
 
-	if(st->oid)
+	if(!st->rid)
 		bl = map_id2bl(st->oid);
 	else
 		bl = &(script_rid2sd(st)->bl);
@@ -9831,6 +9833,54 @@ int buildin_callshop(struct script_state *st)
 	push_val(st->stack,C_INT,1);
 	return 0;
 }
+
+int buildin_npcshopitem(struct script_state *st)
+{
+	struct npc_data *nd= NULL;
+	int n = 0;
+	int i = 3;
+	int itemid, value;
+
+	char* npcname = conv_str(st, & (st->stack->stack_data[st->start + 2]));
+	nd = npc_name2id(npcname);
+
+#ifndef MAX_SHOPITEM
+	#define MAX_SHOPITEM 100
+#endif
+
+	if(nd){
+		nd = (struct npc_data *)aRealloc(nd,sizeof(struct npc_data) +
+			sizeof(nd->u.shop_item[0]) * (MAX_SHOPITEM + 1));
+
+		// Reset sell list.
+		for(;nd->u.shop_item[n].nameid && n < MAX_SHOPITEM; n++){
+			nd->u.shop_item[n].nameid = 0;
+			nd->u.shop_item[n].value = 0;
+		}
+
+		n = 0;
+
+		while (st->end > st->start + i) {
+			itemid = conv_num(st, & (st->stack->stack_data[st->start+i]));
+			nd->u.shop_item[n].nameid = itemid;
+			i++;
+			value = conv_num(st, & (st->stack->stack_data[st->start+i]));
+			nd->u.shop_item[n].value = value;
+			i++;
+			n++;
+		}
+
+		nd = (struct npc_data *)aRealloc(nd,sizeof(struct npc_data) +
+			sizeof(nd->u.shop_item[0]) * n);
+
+		nd->master_nd = ((struct npc_data *)map_id2bl(st->oid));
+	} else {
+		ShowError("buildin_npcshopitem: shop not found.\n");
+	}
+
+	return 0;
+}
+
 /*==========================================
  * Returns some values of an item [Lupus]
  * Price, Weight, etc...

+ 1 - 0
src/map/script.h

@@ -58,6 +58,7 @@ int run_script(unsigned char *,int,int,int);
 int set_var(struct map_session_data *sd, char *name, void *val);
 int conv_num(struct script_state *st,struct script_data *data);
 char* conv_str(struct script_state *st,struct script_data *data);
+void setd_sub(struct map_session_data *sd, char *varname, int elem, void *value);
 
 struct dbt* script_get_label_db(void);
 struct dbt* script_get_userfunc_db(void);