realityincarnate
04-04-2009, 02:27 PM
I don't know of any Live-like functions that would use these commands, so I guess they belong in the custom code section.
This code adds two new perl commands: quest::MerchantSetItem and quest::MerchantCountItem, which are used to access a merchant's temporary inventory list. They can be called from any quest script, not just the merchant in question. I can think of quite a few ways that these could be used, but I have two specific uses on my server. The first is a tradeskills merchant who sells items from zones that aren't accessible yet (garlic, lemons, lemming fur, geodes, etc.) He randomly selects a couple of items to sell, and the selections change each game day.
The second use is a set of caravan quests. By completing the quests for caravan masters in different towns, trade routes are set up and different items and potions appear on the caravan merchants.
Syntax:
quest::MerchantSetItem(merchant's npc id, item id, quanity of item) - changes the number of the item that the merchant has available to sell
quest::MerchantCountItem(merchant npc id, item id) returns the number of that item in stock.
Index: zone/perlparser.cpp
================================================== =================
--- zone/perlparser.cpp (revision 403)
+++ zone/perlparser.cpp (working copy)
@@ -2416,6 +2416,37 @@
XSRETURN_EMPTY;
}
+XS(XS__MerchantSetItem);
+XS(XS__MerchantSetItem) {
+ dXSARGS;
+ if (items != 2 && items != 3)
+ Perl_croak(aTHX_ "Usage: MerchantSetItem(NPCid, itemid [, quantity])");
+
+ int32 NPCid = (int)SvUV(ST(0));
+ int32 itemid = (int)SvUV(ST(1));
+ int32 quantity = 0;
+ if (items == 3)
+ quantity = (int)SvUV(ST(2));
+
+ quest_manager.MerchantSetItem(NPCid, itemid, quantity);
+
+ XSRETURN_EMPTY;
+}
+
+XS(XS__MerchantCountItem);
+XS(XS__MerchantCountItem) {
+ dXSARGS;
+ if (items != 2)
+ Perl_croak(aTHX_ "Usage: MerchantCountItem(NPCid, itemid)");
+
+ int32 NPCid = (int)SvUV(ST(0));
+ int32 itemid = (int)SvUV(ST(1));
+ int32 quantity = quest_manager.MerchantCountItem(NPCid, itemid);
+
+ XSRETURN_UV(quantity);
+}
+
+
/*
This is the callback perl will look for to setup the
quest package's XSUBs
@@ -2584,12 +2615,11 @@
newXS(strcpy(buf, "modifynpcstat"), XS__ModifyNPCStat, file);
newXS(strcpy(buf, "collectitems"), XS__collectitems, file);
newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
+ newXS(strcpy(buf, "MerchantSetItem"), XS__MerchantSetItem, file);
+ newXS(strcpy(buf, "MerchantCountItem"), XS__MerchantCountItem, file);
XSRETURN_YES;
}
-
-
-
#endif
#endif
Index: zone/questmgr.cpp
================================================== =================
--- zone/questmgr.cpp (revision 403)
+++ zone/questmgr.cpp (working copy)
@@ -1774,3 +1774,44 @@
safe_delete(pack);
}
}
+
+// used to set the number of an item in the selected merchant's temp item list. Defaults to zero if no quantity is specified.
+void QuestManager::MerchantSetItem(int32 NPCid, int32 itemid, int32 quantity) {
+ Mob* merchant = entity_list.GetMobByNpcTypeID(NPCid);
+
+ if (merchant == 0 || !merchant->IsNPC() || (merchant->GetClass() != MERCHANT))
+ return; // don't do anything if NPCid isn't a merchant
+
+ const Item_Struct* item = NULL;
+ item = database.GetItem(itemid);
+ if (!item) return; // if the item id doesn't correspond to a real item, do nothing
+
+ zone->SaveTempItem(merchant->CastToNPC()->MerchantType, NPCid, itemid, quantity);
+}
+
+int32 QuestManager::MerchantCountItem(int32 NPCid, int32 itemid) {
+ Mob* merchant = entity_list.GetMobByNpcTypeID(NPCid);
+
+ if (merchant == 0 || !merchant->IsNPC() || (merchant->GetClass() != MERCHANT))
+ return 0; // if it isn't a merchant, it doesn't have any items
+
+ const Item_Struct* item = NULL;
+ item = database.GetItem(itemid);
+ if (!item) return 0; // likewise, if it isn't a valid item, the merchant doesn't have any
+
+ // look for the item in the merchant's temporary list
+ std::list<TempMerchantList> MerchList = zone->tmpmerchanttable[NPCid];
+ std::list<TempMerchantList>::const_iterator itr;
+ TempMerchantList ml;
+ int32 Quant = 0;
+
+ for(itr = MerchList.begin(); itr != MerchList.end(); itr++){
+ ml = *itr;
+ if (ml.item == itemid) { // if this is the item we're looking for
+ Quant = ml.charges;
+ break;
+ }
+ }
+
+ return Quant; // return the quantity of itemid (0 if it was never found)
+}
\ No newline at end of file
Index: zone/questmgr.h
================================================== =================
--- zone/questmgr.h (revision 403)
+++ zone/questmgr.h (working copy)
@@ -194,6 +194,9 @@
void CreateGroundObject(int32 itemid, float x, float y, float z, float heading, int32 decay_time = 300000);
void ModifyNPCStat(const char *identifier, const char *newValue);
void UpdateSpawnTimer(int32 id, int32 newTime);
+
+ void MerchantSetItem(int32 NPCid, int32 itemid, int32 quantity = 0);
+ int32 MerchantCountItem(int32 NPCid, int32 itemid);
//not in here because it retains perl types
//thing ChooseRandom(array_of_things)
This code adds two new perl commands: quest::MerchantSetItem and quest::MerchantCountItem, which are used to access a merchant's temporary inventory list. They can be called from any quest script, not just the merchant in question. I can think of quite a few ways that these could be used, but I have two specific uses on my server. The first is a tradeskills merchant who sells items from zones that aren't accessible yet (garlic, lemons, lemming fur, geodes, etc.) He randomly selects a couple of items to sell, and the selections change each game day.
The second use is a set of caravan quests. By completing the quests for caravan masters in different towns, trade routes are set up and different items and potions appear on the caravan merchants.
Syntax:
quest::MerchantSetItem(merchant's npc id, item id, quanity of item) - changes the number of the item that the merchant has available to sell
quest::MerchantCountItem(merchant npc id, item id) returns the number of that item in stock.
Index: zone/perlparser.cpp
================================================== =================
--- zone/perlparser.cpp (revision 403)
+++ zone/perlparser.cpp (working copy)
@@ -2416,6 +2416,37 @@
XSRETURN_EMPTY;
}
+XS(XS__MerchantSetItem);
+XS(XS__MerchantSetItem) {
+ dXSARGS;
+ if (items != 2 && items != 3)
+ Perl_croak(aTHX_ "Usage: MerchantSetItem(NPCid, itemid [, quantity])");
+
+ int32 NPCid = (int)SvUV(ST(0));
+ int32 itemid = (int)SvUV(ST(1));
+ int32 quantity = 0;
+ if (items == 3)
+ quantity = (int)SvUV(ST(2));
+
+ quest_manager.MerchantSetItem(NPCid, itemid, quantity);
+
+ XSRETURN_EMPTY;
+}
+
+XS(XS__MerchantCountItem);
+XS(XS__MerchantCountItem) {
+ dXSARGS;
+ if (items != 2)
+ Perl_croak(aTHX_ "Usage: MerchantCountItem(NPCid, itemid)");
+
+ int32 NPCid = (int)SvUV(ST(0));
+ int32 itemid = (int)SvUV(ST(1));
+ int32 quantity = quest_manager.MerchantCountItem(NPCid, itemid);
+
+ XSRETURN_UV(quantity);
+}
+
+
/*
This is the callback perl will look for to setup the
quest package's XSUBs
@@ -2584,12 +2615,11 @@
newXS(strcpy(buf, "modifynpcstat"), XS__ModifyNPCStat, file);
newXS(strcpy(buf, "collectitems"), XS__collectitems, file);
newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
+ newXS(strcpy(buf, "MerchantSetItem"), XS__MerchantSetItem, file);
+ newXS(strcpy(buf, "MerchantCountItem"), XS__MerchantCountItem, file);
XSRETURN_YES;
}
-
-
-
#endif
#endif
Index: zone/questmgr.cpp
================================================== =================
--- zone/questmgr.cpp (revision 403)
+++ zone/questmgr.cpp (working copy)
@@ -1774,3 +1774,44 @@
safe_delete(pack);
}
}
+
+// used to set the number of an item in the selected merchant's temp item list. Defaults to zero if no quantity is specified.
+void QuestManager::MerchantSetItem(int32 NPCid, int32 itemid, int32 quantity) {
+ Mob* merchant = entity_list.GetMobByNpcTypeID(NPCid);
+
+ if (merchant == 0 || !merchant->IsNPC() || (merchant->GetClass() != MERCHANT))
+ return; // don't do anything if NPCid isn't a merchant
+
+ const Item_Struct* item = NULL;
+ item = database.GetItem(itemid);
+ if (!item) return; // if the item id doesn't correspond to a real item, do nothing
+
+ zone->SaveTempItem(merchant->CastToNPC()->MerchantType, NPCid, itemid, quantity);
+}
+
+int32 QuestManager::MerchantCountItem(int32 NPCid, int32 itemid) {
+ Mob* merchant = entity_list.GetMobByNpcTypeID(NPCid);
+
+ if (merchant == 0 || !merchant->IsNPC() || (merchant->GetClass() != MERCHANT))
+ return 0; // if it isn't a merchant, it doesn't have any items
+
+ const Item_Struct* item = NULL;
+ item = database.GetItem(itemid);
+ if (!item) return 0; // likewise, if it isn't a valid item, the merchant doesn't have any
+
+ // look for the item in the merchant's temporary list
+ std::list<TempMerchantList> MerchList = zone->tmpmerchanttable[NPCid];
+ std::list<TempMerchantList>::const_iterator itr;
+ TempMerchantList ml;
+ int32 Quant = 0;
+
+ for(itr = MerchList.begin(); itr != MerchList.end(); itr++){
+ ml = *itr;
+ if (ml.item == itemid) { // if this is the item we're looking for
+ Quant = ml.charges;
+ break;
+ }
+ }
+
+ return Quant; // return the quantity of itemid (0 if it was never found)
+}
\ No newline at end of file
Index: zone/questmgr.h
================================================== =================
--- zone/questmgr.h (revision 403)
+++ zone/questmgr.h (working copy)
@@ -194,6 +194,9 @@
void CreateGroundObject(int32 itemid, float x, float y, float z, float heading, int32 decay_time = 300000);
void ModifyNPCStat(const char *identifier, const char *newValue);
void UpdateSpawnTimer(int32 id, int32 newTime);
+
+ void MerchantSetItem(int32 NPCid, int32 itemid, int32 quantity = 0);
+ int32 MerchantCountItem(int32 NPCid, int32 itemid);
//not in here because it retains perl types
//thing ChooseRandom(array_of_things)