diff options
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/ecommon/struct/strutildata.h | 16 | ||||
-rw-r--r-- | src/ecommon/utils/strutil.c | 53 | ||||
-rw-r--r-- | src/ecommon/utils/strutil.h | 12 | ||||
-rw-r--r-- | src/emap/craft.c | 206 | ||||
-rw-r--r-- | src/emap/craft.h | 35 | ||||
-rw-r--r-- | src/emap/init.c | 4 | ||||
-rw-r--r-- | src/emap/script.c | 10 | ||||
-rw-r--r-- | src/emap/script.h | 1 |
9 files changed, 343 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 1a21bb2..9c01232 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,6 +36,8 @@ MAP_SRC = emap/atcommand.c \ emap/battleground.h \ emap/clif.c \ emap/clif.h \ + emap/craft.c \ + emap/craft.h \ emap/horse.c \ emap/horse.h \ emap/init.c \ @@ -95,7 +97,10 @@ MAP_SRC = emap/atcommand.c \ ecommon/config.h \ ecommon/init.c \ ecommon/init.h \ - ecommon/serverversion.h + ecommon/serverversion.h \ + ecommon/struct/strutildata.h \ + ecommon/utils/strutil.c \ + ecommon/utils/strutil.h # need remove -Wno-unused diff --git a/src/ecommon/struct/strutildata.h b/src/ecommon/struct/strutildata.h new file mode 100644 index 0000000..fa9c11d --- /dev/null +++ b/src/ecommon/struct/strutildata.h @@ -0,0 +1,16 @@ +// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// Copyright (c) 2014 - 2015 Evol developers + +#ifndef EVOL_MAP_STRUTILDATA +#define EVOL_MAP_STRUTILDATA + +#include "common/db.h" + +struct strutil_data +{ + char *str; + VECTOR_DECL(char*) parts; + int len; +}; + +#endif // EVOL_MAP_STRUTILDATA diff --git a/src/ecommon/utils/strutil.c b/src/ecommon/utils/strutil.c new file mode 100644 index 0000000..d782b0a --- /dev/null +++ b/src/ecommon/utils/strutil.c @@ -0,0 +1,53 @@ +// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// Copyright (c) 2014 - 2015 Evol developers + +#include "common/hercules.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "common/memmgr.h" +#include "common/strlib.h" + +#include "ecommon/utils/strutil.h" + +#include "ecommon/struct/strutildata.h" + +struct strutil_data *strutil_split(const char *str, + const char separator, + const int len) +{ + if (!str || len < 1) + return NULL; + struct strutil_data *data = aCalloc(1, sizeof(struct strutil_data)); + if (!data) + return NULL; + data->str = aStrdup(str); + VECTOR_INIT(data->parts); + VECTOR_ENSURE(data->parts, len + 1, 1); + + data->len = sv->split(data->str, + strlen(data->str), + 0, + separator, + VECTOR_DATA(data->parts), + len + 1, + 0); + if (data->len < 1) + { + strutil_free(data); + return NULL; + } + + return data; +} + +void strutil_free(struct strutil_data *data) +{ + if (!data) + return NULL; + VECTOR_CLEAR(data->parts); + aFree(data->str); + aFree(data); +} diff --git a/src/ecommon/utils/strutil.h b/src/ecommon/utils/strutil.h new file mode 100644 index 0000000..75d9f20 --- /dev/null +++ b/src/ecommon/utils/strutil.h @@ -0,0 +1,12 @@ +// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// Copyright (c) 2014 - 2015 Evol developers + +#ifndef EVOL_COMMON_UTILS_STRUTIL +#define EVOL_COMMON_UTILS_STRUTIL + +struct strutil_data *strutil_split(const char *str, + const char separator, + const int len); +void strutil_free(struct strutil_data *data); + +#endif // EVOL_COMMON_UTILS_STRUTIL diff --git a/src/emap/craft.c b/src/emap/craft.c new file mode 100644 index 0000000..e5d2c2c --- /dev/null +++ b/src/emap/craft.c @@ -0,0 +1,206 @@ +// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// Copyright (c) 2014 - 2015 Evol developers + +#include "common/hercules.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "common/HPMi.h" +#include "common/memmgr.h" +#include "common/mmo.h" +#include "common/socket.h" +#include "common/strlib.h" +#include "map/npc.h" +#include "map/pc.h" + +#include "ecommon/utils/strutil.h" + +#include "ecommon/struct/strutildata.h" + +#include "emap/craft.h" + +struct DBMap *craftvar_db = NULL; + +int craft_counter = 0; + +void do_init_craft(void) +{ + craftvar_db = idb_alloc(DB_OPT_RELEASE_BOTH); +} + +static int delete_craft_sub(DBKey key __attribute__ ((unused)), + DBData *data, + va_list args __attribute__ ((unused))) +{ + struct craft_vardata *craft = DB->data2ptr(data); + if (!craft) + return 0; + + int index; + for (index = 0; index < craft_inventory_size; index ++) + { + struct craft_slot *slot = &craft->slots[index]; + VECTOR_CLEAR(slot->items); + } + return 0; +} + +void do_final_craft(void) +{ + craftvar_db->destroy(craftvar_db, delete_craft_sub); +} + +bool craft_checkstr(TBL_PC *sd, const char *craftstr) +{ + if (!sd || !craftstr) + return false; + int amounts[MAX_INVENTORY]; + + int f; + for (f = 0; f < MAX_INVENTORY; f ++) + amounts[f] = 0; + + struct strutil_data *craftdata = strutil_split(craftstr, '|', craft_inventory_size + 1); + if (!craftdata) + return false; + + if (craftdata->len < 1) + { + strutil_free(craftdata); + return false; + } + int index; + for (index = 0; index < craftdata->len; index ++) + { + const char *slotstr = VECTOR_INDEX(craftdata->parts, index + 1); + if (!slotstr || !*slotstr) + continue; + struct strutil_data *slotdata = strutil_split(slotstr, ';', MAX_INVENTORY + 1); + if (!slotdata) + { + strutil_free(slotdata); + continue; + } + int slot; + for (slot = 0; slot < slotdata->len; slot ++) + { + const char *itemstr = VECTOR_INDEX(slotdata->parts, slot + 1); + if (!itemstr || !*itemstr) + continue; + int index; + int amount; + int cnt = sscanf(itemstr, "%d,%d", &index, &amount); + if (cnt != 2) + { + index = atoi(itemstr); + amount = 1; + } + if (index < 0 || index >= MAX_INVENTORY) + { // wrong item index + strutil_free(slotdata); + strutil_free(craftdata); + return false; + } + amounts[index] += amount; + if (amounts[index] > 32000) + { // slot overflow + strutil_free(slotdata); + strutil_free(craftdata); + return false; + } + } + strutil_free(slotdata); + } + strutil_free(craftdata); + + for (f = 0; f < MAX_INVENTORY; f ++) + { + const int amount = amounts[f]; + if (!amount) + continue; + if(sd->status.inventory[f].nameid == 0 || + sd->status.inventory[f].amount < amount) + { + return false; + } + } + return true; +} + +struct craft_vardata *craft_str_to_craft(const char *craftstr) +{ + struct strutil_data *craftdata = strutil_split(craftstr, '|', craft_inventory_size + 1); + if (!craftdata) + return false; + + if (craftdata->len < 1) + { + strutil_free(craftdata); + return NULL; + } + + struct craft_vardata *vardata = aCalloc(1, sizeof(struct craft_vardata)); + int index; + for (index = 0; index < craftdata->len; index ++) + { + const char *slotstr = VECTOR_INDEX(craftdata->parts, index + 1); + if (!slotstr || !*slotstr) + continue; + struct strutil_data *slotdata = strutil_split(slotstr, ';', MAX_INVENTORY + 1); + if (!slotdata) + { + strutil_free(slotdata); + continue; + } + struct craft_slot *crslot = &vardata->slots[index]; + VECTOR_INIT(crslot->items); + int slot; + for (slot = 0; slot < slotdata->len; slot ++) + { + const char *itemstr = VECTOR_INDEX(slotdata->parts, slot + 1); + if (!itemstr || !*itemstr) + continue; + int index; + int amount; + int cnt = sscanf(itemstr, "%d,%d", &index, &amount); + if (cnt != 2) + { + index = atoi(itemstr); + amount = 1; + } + if (index < 0 || index >= MAX_INVENTORY) + { // wrong item index + strutil_free(slotdata); + strutil_free(craftdata); + return false; + } + VECTOR_ENSURE(crslot->items, slot + 1, 1); + struct item_pair *pair = &VECTOR_INDEX(crslot->items, slot); + pair->index = index; + pair->amount = amount; + } + strutil_free(slotdata); + } + strutil_free(craftdata); + + return vardata; +} + +int str_to_craftvar(TBL_PC *sd, const char *craftstr) +{ + if (!craft_checkstr(sd, craftstr)) + { + if (sd) + ShowWarning("invalid craft: %d\n", sd->bl.id); + return -1; + } + + struct craft_vardata *craft = craft_str_to_craft(craftstr); + if (!craft) + return -1; + craft_counter ++; + idb_put(craftvar_db, craft_counter, craft); + return craft_counter; +} diff --git a/src/emap/craft.h b/src/emap/craft.h new file mode 100644 index 0000000..48acd31 --- /dev/null +++ b/src/emap/craft.h @@ -0,0 +1,35 @@ +// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// Copyright (c) 2014 - 2015 Evol developers + +#ifndef EVOL_MAP_CRAFT +#define EVOL_MAP_CRAFT + +#include "common/db.h" + +extern struct DBMap *craftvar_db; + +#define craft_inventory_size 9 + +struct item_pair +{ + int index; + int amount; +}; + +struct craft_slot +{ + VECTOR_DECL(struct item_pair) items; +}; + +struct craft_vardata +{ + struct craft_slot slots[craft_inventory_size]; +}; + +void do_init_craft(void); +void do_final_craft(void); +bool craft_checkstr(TBL_PC *sd, const char *craftstr); +int str_to_craftvar(TBL_PC *sd, const char *craftstr); +struct craft_vardata *craft_str_to_craft(const char *craftstr); + +#endif // EVOL_MAP_CRAFT diff --git a/src/emap/init.c b/src/emap/init.c index c71a7b1..b846336 100644 --- a/src/emap/init.c +++ b/src/emap/init.c @@ -45,6 +45,7 @@ #include "emap/atcommand.h" #include "emap/battleground.h" #include "emap/clif.h" +#include "emap/craft.h" #include "emap/itemdb.h" #include "emap/lang.h" #include "emap/mail.h" @@ -99,6 +100,7 @@ HPExport void plugin_init (void) addScriptCommand("requestitemindex", "v", requestItemIndex); addScriptCommand("requestitemsindex", "v*", requestItemsIndex); addScriptCommand("requestcraft", "v*", requestCraft); + addScriptCommand("initcraft", "s", initCraft); addScriptCommand("getq", "i", getq); addScriptCommand("setq", "ii", setq); addScriptCommand("setnpcdir", "*", setNpcDir); @@ -138,6 +140,7 @@ HPExport void plugin_init (void) addScriptCommand("setskin", "s", setSkin); do_init_langs(); + do_init_craft(); addPacket(0x7530, 22, map_parse_version, hpClif_Parse); addPacket(0xb07, 26, map_parse_join_channel, hpClif_Parse); @@ -268,6 +271,7 @@ HPExport void server_online (void) HPExport void plugin_final (void) { do_final_langs(); + do_final_craft(); commonClean(); isInit = false; } diff --git a/src/emap/script.c b/src/emap/script.c index 955e650..f1deb4e 100644 --- a/src/emap/script.c +++ b/src/emap/script.c @@ -25,6 +25,7 @@ #include "emap/script.h" #include "emap/clif.h" +#include "emap/craft.h" #include "emap/lang.h" #include "emap/map.h" #include "emap/scriptdefines.h" @@ -1869,3 +1870,12 @@ BUILDIN(setSkin) send_pc_skin(sd->fd, st->oid, skin); return true; } + +BUILDIN(initCraft) +{ + getSD() + + int var = str_to_craftvar(sd, script_getstr(st, 2)); + script_pushint(st, var); + return true; +} diff --git a/src/emap/script.h b/src/emap/script.h index 007fa31..e5a4958 100644 --- a/src/emap/script.h +++ b/src/emap/script.h @@ -65,5 +65,6 @@ BUILDIN(checkNpcCell); BUILDIN(setCells); BUILDIN(delCells); BUILDIN(setSkin); +BUILDIN(initCraft); #endif // EVOL_MAP_SCRIPT |