From 77cc71cde657cca6c2747a41e3c1672cd4c6092b Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 24 Jan 2016 02:43:12 +0300 Subject: Add script command for use craft. New script command: usecraft CRAFT Where CRAFT - craft id created by initcraft. --- src/emap/craft.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/emap/craft.h | 2 + src/emap/craftconf.c | 1 + src/emap/craftconf.h | 1 + src/emap/init.c | 1 + src/emap/script.c | 6 +++ src/emap/script.h | 1 + 7 files changed, 144 insertions(+) diff --git a/src/emap/craft.c b/src/emap/craft.c index ae36e6e..54cf7b9 100644 --- a/src/emap/craft.c +++ b/src/emap/craft.c @@ -164,6 +164,9 @@ struct craft_vardata *craft_str_to_craft(const char *craftstr) } struct craft_vardata *vardata = aCalloc(1, sizeof(struct craft_vardata)); + if (!vardata) + return false; + vardata->entry_id = -1; int index; for (index = 0; index < craftdata->len; index ++) { @@ -485,7 +488,10 @@ static bool check_inventories(TBL_PC *sd, } } if (correct) + { + entry->selected_inventory = entry_inventory; return true; + } correct = true; } return false; @@ -591,6 +597,132 @@ int craft_find_entry(TBL_PC *sd, struct item_pair inventory[craft_inventory_size]; simplify_craftvar(sd, &inventory[0], craft); const int recipe = craft_get_recipe(sd, craft, &inventory[0], flag); + craft->entry_id = recipe; //ShowInfo("found recipe: %d\n", recipe); return recipe; } + +static bool craft_delete_items(TBL_PC *sd, + struct craft_items_collection *vector) +{ + int len = VECTOR_LENGTH(*vector); + int i; + if (len > 0) + { + for (i = 0; i < len; i ++) + { + struct item_pair *itemPair = &VECTOR_INDEX(*vector, i); + const int index = find_inventory_item(sd, itemPair->index, itemPair->amount); + if (!index) + return false; + pc->delitem(sd, index, itemPair->amount, 2, 8, LOG_TYPE_PRODUCE); + } + } + return true; +} + +static bool craft_create_items(TBL_PC *sd, + struct craft_items_collection *vector) +{ + int len = VECTOR_LENGTH(*vector); + int i; + if (len > 0) + { + struct item it; + for (i = 0; i < len; i ++) + { + struct item_pair *itemPair = &VECTOR_INDEX(*vector, i); + memset(&it, 0, sizeof(it)); + it.nameid = itemPair->index; + it.amount = itemPair->amount; + it.identify = 1; + pc->additem(sd, &it, itemPair->amount, LOG_TYPE_PRODUCE); + } + } + return true; +} + +static bool craft_delete_inventory(TBL_PC *sd, + struct craft_vardata *craft, + struct craft_db_entry *entry) +{ + if (!sd || !craft || !entry) + return false; + + struct craft_db_inventory *entry_inventory = entry->selected_inventory; + if (!entry_inventory) + return false; + + int f; + for (f = 0; f < craft_inventory_size; f ++) + { + struct item_pair *entryItem = &entry_inventory->items[f]; + int needAmount = entryItem->amount; + struct craft_slot *craftSlot = &craft->slots[f]; + int i; + int len = VECTOR_LENGTH(craftSlot->items); + for (i = 0; i < len && needAmount; i ++) + { + struct item_pair *craftItem = &VECTOR_INDEX(craftSlot->items, i); + if (needAmount > craftItem->amount) + { + pc->delitem(sd, craftItem->index, craftItem->amount, 2, 8, LOG_TYPE_PRODUCE); + needAmount -= craftItem->amount; + } + else + { + pc->delitem(sd, craftItem->index, needAmount, 2, 8, LOG_TYPE_PRODUCE); + needAmount = 0; + } + } + if (needAmount > 0) + { + ShowError("Craft broken amount. Probably exploit in use: '" + CL_WHITE"%s"CL_RESET"'" + " (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"'.\n", + sd->status.name, sd->status.account_id, sd->status.char_id); + return false; + } + } + + return true; +} + +bool craft_use(TBL_PC *sd, + const int id) +{ + struct craft_vardata *craft = idb_get(craftvar_db, id); + if (!craft) + { + ShowError("Craft object with id %d not exists.\n", id); + return -1; + } + struct craft_db_entry *entry = idb_get(craftconf_db, craft->entry_id); + if (!entry) + { + ShowError("Craft config entry with id %d not exists.\n", craft->entry_id); + return false; + } + + if (!craft_delete_inventory(sd, craft, entry)) + return false; + + if (!craft_delete_items(sd, &entry->delete_items)) + return false; + + if (sd->status.zeny < entry->price) + { + ShowError("Craft broken zeny. Probably exploit in use: '" + CL_WHITE"%s"CL_RESET"'" + " (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"'.\n", + sd->status.name, sd->status.account_id, sd->status.char_id); + return false; + } + sd->status.zeny -= entry->price; + + craft_create_items(sd, &entry->create_items); + + clif->updatestatus(sd, SP_ZENY); + clif->updatestatus(sd, SP_WEIGHT); + return true; +} diff --git a/src/emap/craft.h b/src/emap/craft.h index 41ee694..2763907 100644 --- a/src/emap/craft.h +++ b/src/emap/craft.h @@ -28,6 +28,7 @@ struct craft_slot struct craft_vardata { struct craft_slot slots[craft_inventory_size]; + int entry_id; }; void do_init_craft(void); @@ -40,5 +41,6 @@ void craft_delete(const int id); struct craft_slot *craft_get_slot(const int id, const int slot); bool craft_validate(TBL_PC *sd, const int id); int craft_find_entry(TBL_PC *sd, const int craftvar, const int flag); +bool craft_use_entry(TBL_PC *sd, const int id); #endif // EVOL_MAP_CRAFT diff --git a/src/emap/craftconf.c b/src/emap/craftconf.c index 62f3230..7afba56 100644 --- a/src/emap/craftconf.c +++ b/src/emap/craftconf.c @@ -38,6 +38,7 @@ struct craft_db_entry *craft_create_db_entry(const int id) VECTOR_INIT(entry->required_equips); VECTOR_INIT(entry->required_skills); VECTOR_INIT(entry->required_quests); + entry->selected_inventory = NULL; return entry; } diff --git a/src/emap/craftconf.h b/src/emap/craftconf.h index b42c9d5..235b984 100644 --- a/src/emap/craftconf.h +++ b/src/emap/craftconf.h @@ -30,6 +30,7 @@ struct craft_db_entry struct craft_items_collection required_equips; struct craft_items_collection required_skills; struct craft_items_collection required_quests; + struct craft_db_inventory *selected_inventory; int priority; int price; int level; diff --git a/src/emap/init.c b/src/emap/init.c index e628fb3..bb732ed 100644 --- a/src/emap/init.c +++ b/src/emap/init.c @@ -106,6 +106,7 @@ HPExport void plugin_init (void) addScriptCommand("dumpcraft", "i", dumpCraft); addScriptCommand("deletecraft", "i", deleteCraft); addScriptCommand("findcraftentry", "ii", findCraftEntry); + addScriptCommand("usecraft", "i", useCraft); addScriptCommand("getcraftslotid", "ii", getCraftSlotId); addScriptCommand("getcraftslotamount", "ii", getCraftSlotAmount); addScriptCommand("validatecraft", "i", validateCraft); diff --git a/src/emap/script.c b/src/emap/script.c index 1df6d0a..69c1f4e 100644 --- a/src/emap/script.c +++ b/src/emap/script.c @@ -1952,6 +1952,12 @@ BUILDIN(findCraftEntry) return true; } +BUILDIN(useCraft) +{ + getSDReturn(0) + return craft_use(sd, script_getnum(st, 2)); +} + BUILDIN(getInvIndexLink) { getSDReturnS("") diff --git a/src/emap/script.h b/src/emap/script.h index bb40d54..67c20e6 100644 --- a/src/emap/script.h +++ b/src/emap/script.h @@ -74,5 +74,6 @@ BUILDIN(validateCraft); BUILDIN(getInvIndexLink); BUILDIN(emotion); BUILDIN(findCraftEntry); +BUILDIN(useCraft); #endif // EVOL_MAP_SCRIPT -- cgit v1.2.3-70-g09d2