summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emap/craft.c132
-rw-r--r--src/emap/craft.h2
-rw-r--r--src/emap/craftconf.c1
-rw-r--r--src/emap/craftconf.h1
-rw-r--r--src/emap/init.c1
-rw-r--r--src/emap/script.c6
-rw-r--r--src/emap/script.h1
7 files changed, 144 insertions, 0 deletions
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