summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt1
-rw-r--r--src/map/clif.c43
-rw-r--r--src/map/map.h1
-rw-r--r--src/map/script.c54
-rw-r--r--src/map/script.h1
5 files changed, 90 insertions, 10 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index eb1a5d1c9..3560508e3 100644
--- a/Changelog-Trunk.txt
+++ b/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
diff --git a/src/map/clif.c b/src/map/clif.c
index 8705b30bf..9ce77129d 100644
--- a/src/map/clif.c
+++ b/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]);
diff --git a/src/map/map.h b/src/map/map.h
index 716f61c5d..3c32e4605 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -794,6 +794,7 @@ struct npc_data {
short arenaflag;
void *chatdb;
+ struct npc_data *master_nd;
union {
struct {
diff --git a/src/map/script.c b/src/map/script.c
index d603995d7..fdae52784 100644
--- a/src/map/script.c
+++ b/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...
diff --git a/src/map/script.h b/src/map/script.h
index 9baff784e..61803da89 100644
--- a/src/map/script.h
+++ b/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);