PDA

View Full Version : Merchant Inventory Quest Commands


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)

cavedude
04-04-2009, 02:45 PM
Actually, there are at least two such NPCs that would benefit from this. One in PoK, and the other in Bazaar for HQ ore. Currently, we are using two NPCs to implement them, using these Perl functions would be far superior. Thanks, when I get home and settled I'll take a look at this!