Skip to content

Commit de6b3e7

Browse files
AsherafMishimaHaruna
authored andcommitted
Implementation of LapineDdukDdak System
1 parent b574468 commit de6b3e7

File tree

12 files changed

+4961
-2
lines changed

12 files changed

+4961
-2
lines changed

db/pre-re/item_lapineddukddak.conf

Lines changed: 2318 additions & 0 deletions
Large diffs are not rendered by default.

db/re/item_lapineddukddak.conf

Lines changed: 2318 additions & 0 deletions
Large diffs are not rendered by default.

doc/script_commands.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10622,3 +10622,9 @@ Opens refinery user interface for the player
1062210622
returns true on success and false on failure
1062310623

1062410624
---------------------------------------
10625+
*openlapineddukddakboxui(<item_id>)
10626+
10627+
Opens lapine ddukddak user interface for the player
10628+
returns true on success and false on failure
10629+
10630+
---------------------------------------

src/map/clif.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23332,6 +23332,109 @@ static void clif_parse_GuildCastleInfoRequest(int fd, struct map_session_data *s
2333223332
#endif
2333323333
}
2333423334

23335+
static bool clif_lapineDdukDdak_open(struct map_session_data *sd, int item_id)
23336+
{
23337+
#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
23338+
nullpo_retr(false, sd);
23339+
nullpo_retr(false, itemdb->exists(item_id));
23340+
struct PACKET_ZC_LAPINEDDUKDDAK_OPEN p;
23341+
23342+
p.packetType = HEADER_ZC_LAPINEDDUKDDAK_OPEN;
23343+
p.itemId = item_id;
23344+
clif->send(&p, sizeof(p), &sd->bl, SELF);
23345+
23346+
sd->state.lapine_ui = 1;
23347+
return true;
23348+
#else
23349+
return false;
23350+
#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
23351+
}
23352+
23353+
static bool clif_lapineDdukDdak_result(struct map_session_data *sd, enum lapineddukddak_result result)
23354+
{
23355+
#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
23356+
nullpo_retr(false, sd);
23357+
struct PACKET_ZC_LAPINEDDUKDDAK_RESULT p;
23358+
23359+
p.packetType = HEADER_ZC_LAPINEDDUKDDAK_RESULT;
23360+
p.result = result;
23361+
clif->send(&p, sizeof(p), &sd->bl, SELF);
23362+
return true;
23363+
#else
23364+
return false;
23365+
#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
23366+
}
23367+
23368+
static void clif_parse_lapineDdukDdak_ack(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
23369+
static void clif_parse_lapineDdukDdak_ack(int fd, struct map_session_data *sd)
23370+
{
23371+
#if PACKETVER >= 20160302
23372+
const struct PACKET_CZ_LAPINEDDUKDDAK_ACK *p = RP2PTR(fd);
23373+
struct item_data *it = itemdb->exists(p->itemId);
23374+
23375+
if (it == NULL || it->lapineddukddak == NULL)
23376+
return;
23377+
if (pc_cant_act(sd))
23378+
return;
23379+
if (pc->search_inventory(sd, it->nameid) == INDEX_NOT_FOUND)
23380+
return;
23381+
23382+
if (((p->packetLength - sizeof(struct PACKET_CZ_LAPINEDDUKDDAK_ACK)) / sizeof(struct PACKET_CZ_LAPINEDDUKDDAK_ACK_sub)) != it->lapineddukddak->NeedCount)
23383+
return;
23384+
23385+
for (int i = 0; i < it->lapineddukddak->NeedCount; ++i) {
23386+
int16 idx = p->items[i].index - 2;
23387+
Assert_retv(idx >= 0 && idx < sd->status.inventorySize);
23388+
23389+
struct item itr = sd->status.inventory[idx];
23390+
int j = 0;
23391+
for (j = 0; j < VECTOR_LENGTH(it->lapineddukddak->SourceItems); ++j) {
23392+
if (itr.nameid == VECTOR_INDEX(it->lapineddukddak->SourceItems, j).id) {
23393+
// Validate that the amount sent in the packet is matching the database
23394+
if (p->items[i].count != VECTOR_INDEX(it->lapineddukddak->SourceItems, j).amount) {
23395+
clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_INSUFFICIENT_AMOUNT);
23396+
return;
23397+
}
23398+
23399+
// Validate that the player have enough of the item
23400+
if (itr.amount < VECTOR_INDEX(it->lapineddukddak->SourceItems, j).amount) {
23401+
clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_INSUFFICIENT_AMOUNT);
23402+
return;
23403+
}
23404+
23405+
// Validate refine rate requirement
23406+
if ((itemdb_type(itr.nameid) == IT_ARMOR || itemdb_type(itr.nameid) == IT_WEAPON)
23407+
&& (itr.refine < it->lapineddukddak->NeedRefineMin || itr.refine > it->lapineddukddak->NeedRefineMax))
23408+
return;
23409+
23410+
// All requirements are met, move to the next one
23411+
break;
23412+
}
23413+
}
23414+
// The item is not in sources list
23415+
if (j == VECTOR_LENGTH(it->lapineddukddak->SourceItems)) {
23416+
clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_INVALID_ITEM);
23417+
return;
23418+
}
23419+
}
23420+
23421+
for (int i = 0; i < it->lapineddukddak->NeedCount; ++i)
23422+
pc->delitem(sd, p->items[i].index - 2, p->items[i].count, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT);
23423+
if (it->lapineddukddak->script != NULL)
23424+
script->run_item_lapineddukddak_script(sd, it, npc->fake_nd->bl.id);
23425+
clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_SUCCESS);
23426+
return;
23427+
#endif // PACKETVER >= 20160302
23428+
}
23429+
23430+
static void clif_parse_lapineDdukDdak_close(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
23431+
static void clif_parse_lapineDdukDdak_close(int fd, struct map_session_data *sd)
23432+
{
23433+
#if PACKETVER >= 20160504
23434+
sd->state.lapine_ui = 0;
23435+
#endif // PACKETVER >= 20160504
23436+
}
23437+
2333523438
/*==========================================
2333623439
* Main client packet processing function
2333723440
*------------------------------------------*/
@@ -24562,4 +24665,8 @@ void clif_defaults(void)
2456224665
clif->pGuildCastleTeleportRequest = clif_parse_GuildCastleTeleportRequest;
2456324666
clif->pGuildCastleInfoRequest = clif_parse_GuildCastleInfoRequest;
2456424667
clif->guild_castleteleport_res = clif_guild_castleteleport_res;
24668+
clif->lapineDdukDdak_open = clif_lapineDdukDdak_open;
24669+
clif->lapineDdukDdak_result = clif_lapineDdukDdak_result;
24670+
clif->plapineDdukDdak_ack = clif_parse_lapineDdukDdak_ack;
24671+
clif->plapineDdukDdak_close = clif_parse_lapineDdukDdak_close;
2456524672
}

src/map/clif.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,12 @@ enum market_buy_result {
727727
};
728728
#endif
729729

730+
enum lapineddukddak_result {
731+
LAPINEDDKUKDDAK_SUCCESS = 0,
732+
LAPINEDDKUKDDAK_INSUFFICIENT_AMOUNT = 5,
733+
LAPINEDDKUKDDAK_INVALID_ITEM = 7,
734+
};
735+
730736
/**
731737
* Clif.c Interface
732738
**/
@@ -1659,6 +1665,10 @@ struct clif_interface {
16591665
void (*pGuildCastleTeleportRequest) (int fd, struct map_session_data *sd);
16601666
void (*pGuildCastleInfoRequest) (int fd, struct map_session_data *sd);
16611667
void (*guild_castleteleport_res) (struct map_session_data *sd, enum siege_teleport_result result);
1668+
bool (*lapineDdukDdak_open) (struct map_session_data *sd, int item_id);
1669+
bool (*lapineDdukDdak_result) (struct map_session_data *sd, enum lapineddukddak_result result);
1670+
void (*plapineDdukDdak_ack) (int fd, struct map_session_data *sd);
1671+
void (*plapineDdukDdak_close) (int fd, struct map_session_data *sd);
16621672
};
16631673

16641674
#ifdef HERCULES_CORE

src/map/itemdb.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2419,6 +2419,98 @@ static uint64 itemdb_unique_id(struct map_session_data *sd)
24192419
return ((uint64)sd->status.char_id << 32) | sd->status.uniqueitem_counter++;
24202420
}
24212421

2422+
static bool itemdb_read_libconfig_lapineddukddak(void)
2423+
{
2424+
struct config_t item_lapineddukddak;
2425+
struct config_setting_t *it = NULL;
2426+
char filepath[256];
2427+
2428+
int i = 0;
2429+
int count = 0;
2430+
2431+
safesnprintf(filepath, sizeof(filepath), "%s/%s", map->db_path, DBPATH"item_lapineddukddak.conf");
2432+
if (libconfig->load_file(&item_lapineddukddak, filepath) == CONFIG_FALSE)
2433+
return false;
2434+
2435+
while ((it = libconfig->setting_get_elem(item_lapineddukddak.root, i++)) != NULL) {
2436+
if (itemdb->read_libconfig_lapineddukddak_sub(it, filepath))
2437+
++count;
2438+
}
2439+
2440+
libconfig->destroy(&item_lapineddukddak);
2441+
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filepath);
2442+
return true;
2443+
}
2444+
2445+
static bool itemdb_read_libconfig_lapineddukddak_sub(struct config_setting_t *it, const char *source)
2446+
{
2447+
nullpo_retr(false, it);
2448+
nullpo_retr(false, source);
2449+
2450+
struct item_data *data = NULL;
2451+
const char *name = config_setting_name(it);
2452+
const char *str = NULL;
2453+
int i32 = 0;
2454+
2455+
if ((data = itemdb->name2id(name)) == NULL) {
2456+
ShowWarning("itemdb_read_libconfig_lapineddukddak_sub: unknown item '%s', skipping..\n", name);
2457+
return false;
2458+
}
2459+
2460+
data->lapineddukddak = aCalloc(1, sizeof(struct item_lapineddukddak));
2461+
if (libconfig->setting_lookup_int(it, "NeedCount", &i32) == CONFIG_TRUE)
2462+
data->lapineddukddak->NeedCount = (int16)i32;
2463+
2464+
if (libconfig->setting_lookup_int(it, "NeedRefineMin", &i32) == CONFIG_TRUE)
2465+
data->lapineddukddak->NeedRefineMin = (int8)i32;
2466+
2467+
if (libconfig->setting_lookup_int(it, "NeedRefineMax", &i32) == CONFIG_TRUE)
2468+
data->lapineddukddak->NeedRefineMax = (int8)i32;
2469+
2470+
struct config_setting_t *sources = libconfig->setting_get_member(it, "SourceItems");
2471+
itemdb->read_libconfig_lapineddukddak_sub_sources(sources, data);
2472+
2473+
if (libconfig->setting_lookup_string(it, "Script", &str) == CONFIG_TRUE)
2474+
data->lapineddukddak->script = *str ? script->parse(str, source, -data->nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
2475+
return true;
2476+
}
2477+
2478+
static bool itemdb_read_libconfig_lapineddukddak_sub_sources(struct config_setting_t *sources, struct item_data *data)
2479+
{
2480+
nullpo_retr(false, data);
2481+
nullpo_retr(false, data->lapineddukddak);
2482+
2483+
int i = 0;
2484+
struct config_setting_t *entry = NULL;
2485+
2486+
if (sources == NULL || !config_setting_is_group(sources))
2487+
return false;
2488+
2489+
VECTOR_INIT(data->lapineddukddak->SourceItems);
2490+
while ((entry = libconfig->setting_get_elem(sources, i++)) != NULL) {
2491+
struct item_data *edata = NULL;
2492+
struct itemlist_entry item = { 0 };
2493+
const char *name = config_setting_name(entry);
2494+
int i32 = 0;
2495+
2496+
if ((edata = itemdb->name2id(name)) == NULL) {
2497+
ShowWarning("itemdb_read_libconfig_lapineddukddak_sub: unknown item '%s', skipping..\n", name);
2498+
continue;
2499+
}
2500+
item.id = edata->nameid;
2501+
2502+
if ((i32 = libconfig->setting_get_int(entry)) == CONFIG_TRUE && (i32 <= 0 || i32 > MAX_AMOUNT)) {
2503+
ShowWarning("itemdb_read_libconfig_lapineddukddak_sub: invalid amount (%d) for source item '%s', skipping..\n", i32, name);
2504+
continue;
2505+
}
2506+
item.amount = i32;
2507+
2508+
VECTOR_ENSURE(data->lapineddukddak->SourceItems, 1, 1);
2509+
VECTOR_PUSH(data->lapineddukddak->SourceItems, item);
2510+
}
2511+
return true;
2512+
}
2513+
24222514
/**
24232515
* Reads all item-related databases.
24242516
*/
@@ -2457,6 +2549,7 @@ static void itemdb_read(bool minimal)
24572549
itemdb->read_groups();
24582550
itemdb->read_chains();
24592551
itemdb->read_packages();
2552+
itemdb->read_libconfig_lapineddukddak();
24602553
}
24612554

24622555
/**
@@ -2517,6 +2610,12 @@ static void destroy_item_data(struct item_data *self, int free_self)
25172610
script->free_code(self->rental_end_script);
25182611
if( self->combos )
25192612
aFree(self->combos);
2613+
if (self->lapineddukddak != NULL) {
2614+
if (self->lapineddukddak->script != NULL)
2615+
script->free_code(self->lapineddukddak->script);
2616+
VECTOR_CLEAR(self->lapineddukddak->SourceItems);
2617+
aFree(self->lapineddukddak);
2618+
}
25202619
HPM->data_store_destroy(&self->hdata);
25212620
#if defined(DEBUG)
25222621
// trash item
@@ -2821,4 +2920,7 @@ void itemdb_defaults(void)
28212920
itemdb->lookup_const = itemdb_lookup_const;
28222921
itemdb->lookup_const_mask = itemdb_lookup_const_mask;
28232922
itemdb->addname_sub = itemdb_addname_sub;
2923+
itemdb->read_libconfig_lapineddukddak = itemdb_read_libconfig_lapineddukddak;
2924+
itemdb->read_libconfig_lapineddukddak_sub = itemdb_read_libconfig_lapineddukddak_sub;
2925+
itemdb->read_libconfig_lapineddukddak_sub_sources = itemdb_read_libconfig_lapineddukddak_sub_sources;
28242926
}

src/map/itemdb.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,14 @@ struct itemdb_option {
482482
struct script_code *script;
483483
};
484484

485+
struct item_lapineddukddak {
486+
int16 NeedCount;
487+
int8 NeedRefineMin;
488+
int8 NeedRefineMax;
489+
VECTOR_DECL(struct itemlist_entry) SourceItems;
490+
struct script_code *script;
491+
};
492+
485493
struct item_data {
486494
int nameid;
487495
char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH];
@@ -551,6 +559,7 @@ struct item_data {
551559
/* TODO add a pointer to some sort of (struct extra) and gather all the not-common vals into it to save memory */
552560
struct item_group *group;
553561
struct item_package *package;
562+
struct item_lapineddukddak *lapineddukddak;
554563
struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
555564
};
556565

@@ -688,6 +697,9 @@ struct itemdb_interface {
688697
bool (*lookup_const) (const struct config_setting_t *it, const char *name, int *value);
689698
bool (*lookup_const_mask) (const struct config_setting_t *it, const char *name, int *value);
690699
int (*addname_sub) (union DBKey key, struct DBData *data, va_list ap);
700+
bool (*read_libconfig_lapineddukddak) (void);
701+
bool (*read_libconfig_lapineddukddak_sub) (struct config_setting_t *it, const char *source);
702+
bool (*read_libconfig_lapineddukddak_sub_sources) (struct config_setting_t *sources, struct item_data *data);
691703
};
692704

693705
#ifdef HERCULES_CORE

src/map/packets.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,4 +1959,12 @@ packet(0x96e,clif->ackmergeitems);
19591959
packet(0x0b2c,clif->pGuildCastleInfoRequest);
19601960
#endif
19611961

1962+
#if PACKETVER >= 20160302
1963+
packet(0x0a4f,clif->plapineDdukDdak_ack);
1964+
#endif
1965+
1966+
#if PACKETVER >= 20160504
1967+
packet(0x0a70,clif->plapineDdukDdak_close);
1968+
#endif
1969+
19621970
#endif /* MAP_PACKETS_H */

src/map/packets_struct.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3669,6 +3669,45 @@ struct PACKET_CZ_CASTLE_INFO_REQUEST {
36693669
DEFINE_PACKET_HEADER(CZ_CASTLE_INFO_REQUEST, 0x0b2c);
36703670
#endif
36713671

3672+
#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
3673+
struct PACKET_ZC_LAPINEDDUKDDAK_OPEN {
3674+
int16 packetType;
3675+
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
3676+
int32 itemId;
3677+
#else
3678+
int16 itemId;
3679+
#endif
3680+
} __attribute__((packed));
3681+
DEFINE_PACKET_HEADER(ZC_LAPINEDDUKDDAK_OPEN, 0x0a4e);
3682+
#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
3683+
3684+
#if PACKETVER >= 20160302
3685+
struct PACKET_CZ_LAPINEDDUKDDAK_ACK_sub {
3686+
int16 index;
3687+
int16 count;
3688+
} __attribute__((packed));
3689+
3690+
struct PACKET_CZ_LAPINEDDUKDDAK_ACK {
3691+
int16 packetType;
3692+
int16 packetLength;
3693+
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
3694+
int32 itemId;
3695+
#else
3696+
int16 itemId;
3697+
#endif
3698+
struct PACKET_CZ_LAPINEDDUKDDAK_ACK_sub items[];
3699+
} __attribute__((packed));
3700+
DEFINE_PACKET_HEADER(CZ_LAPINEDDUKDDAK_ACK, 0x0a4f);
3701+
#endif // PACKETVER >= 20160302
3702+
3703+
#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
3704+
struct PACKET_ZC_LAPINEDDUKDDAK_RESULT {
3705+
int16 packetType;
3706+
int16 result;
3707+
} __attribute__((packed));
3708+
DEFINE_PACKET_HEADER(ZC_LAPINEDDUKDDAK_RESULT, 0x0a50);
3709+
#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
3710+
36723711
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
36733712
#pragma pack(pop)
36743713
#endif // not NetBSD < 6 / Solaris

src/map/pc.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ struct map_session_data {
239239
unsigned int warp_clean : 1;
240240
unsigned int refine_ui : 1;
241241
unsigned int npc_unloaded : 1; ///< The player is talking with an unloaded NPCs (respawned tombstones)
242+
unsigned int lapine_ui : 1;
242243
} state;
243244
struct {
244245
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
@@ -665,10 +666,10 @@ END_ZEROED_BLOCK;
665666
#define pc_issit(sd) ( (sd)->vd.dead_sit == 2 )
666667
#define pc_isidle(sd) ( (sd)->chat_id != 0 || (sd)->state.vending || (sd)->state.buyingstore || DIFF_TICK(sockt->last_tick, (sd)->idletime) >= battle->bc->idle_no_share )
667668
#define pc_istrading(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->state.trading )
668-
#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1)
669+
#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
669670

670671
/* equals pc_cant_act except it doesn't check for chat rooms */
671-
#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1)
672+
#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
672673

673674
#define pc_setdir(sd,b,h) ( (sd)->ud.dir = (b) ,(sd)->head_dir = (h) )
674675
#define pc_setchatid(sd,n) ( (sd)->chat_id = (n) )

0 commit comments

Comments
 (0)