Revamped Laphine UIs (#6625)

Fixes #3302
Closes #4348

Thanks for the initial release by @Cydh in #4348 and everyone that contributed to it.

All existing data was migrated and cleaned up where necessary.
Thanks to @Everade for his help here.

Laphine UIs are now fully yamlified and not dependent on the script engine.
They make use of new item group features and of the already existing random option group feature.
This way they will be far easier to be maintained, even though they are a little less customize able.

Thanks to @limitro, @CairoLee, @dimasshotta and everyone else who contributed!

Co-authored-by: Cydh <cydh.ramdh@gmail.com>
Co-authored-by: Everade <Everade@users.noreply.github.com>
Co-authored-by: Aleos <aleos89@users.noreply.github.com>
This commit is contained in:
Lemongrass3110
2022-02-22 21:52:27 +01:00
committed by GitHub
parent 5227167716
commit 08192a35bc
29 changed files with 19587 additions and 468 deletions

View File

@@ -23085,6 +23085,345 @@ void clif_summon_hp_bar(struct mob_data& md) {
#endif
}
void clif_laphine_synthesis_open( struct map_session_data *sd, std::shared_ptr<s_laphine_synthesis> synthesis ){
#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
nullpo_retv( sd );
sd->state.laphine_synthesis = synthesis->item_id;
struct PACKET_ZC_LAPINEDDUKDDAK_OPEN p = {};
p.packetType = HEADER_ZC_LAPINEDDUKDDAK_OPEN;
p.itemId = client_nameid( synthesis->item_id );
clif_send( &p, sizeof( p ), &sd->bl, SELF );
#endif
}
void clif_parse_laphine_synthesis_close( int fd, struct map_session_data* sd ){
#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
sd->state.laphine_synthesis = 0;
#endif
}
enum e_laphine_synthesis_result : int16{
LAPHINE_SYNTHESIS_SUCCESS = 0,
LAPHINE_SYNTHESIS_AMOUNT = 5,
LAPHINE_SYNTHESIS_ITEM = 7
};
void clif_laphine_synthesis_result( struct map_session_data* sd, enum e_laphine_synthesis_result result ){
#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
nullpo_retv( sd );
struct PACKET_ZC_LAPINEDDUKDDAK_RESULT p = {};
p.packetType = HEADER_ZC_LAPINEDDUKDDAK_RESULT;
p.result = result;
clif_send( &p, sizeof( p ), &sd->bl, SELF );
#endif
}
void clif_parse_laphine_synthesis( int fd, struct map_session_data* sd ){
#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO)
if( sd->state.laphine_synthesis == 0 ){
return;
}
struct PACKET_CZ_LAPINEDDUKDDAK_ACK* p = (struct PACKET_CZ_LAPINEDDUKDDAK_ACK*)RFIFOP( fd, 0 );
if( sd->state.laphine_synthesis != p->itemId ){
return;
}
std::shared_ptr<s_laphine_synthesis> synthesis = laphine_synthesis_db.find( sd->state.laphine_synthesis );
if( synthesis == nullptr ){
return;
}
size_t count = ( p->packetLength - sizeof( struct PACKET_CZ_LAPINEDDUKDDAK_ACK ) ) / sizeof( struct PACKET_CZ_LAPINEDDUKDDAK_ACK_sub );
// Player sent more or less than actually required
if( count != synthesis->requiredRequirements ){
return;
}
// Check for duplicates
for( size_t i = 0; i < count; i++ ){
for( size_t j = i + 1; j < count; j++ ){
if( p->items[i].index == p->items[j].index ){
return;
}
}
}
for( size_t i = 0; i < count; i++ ){
int16 index = server_index( p->items[i].index );
if( index >= MAX_INVENTORY ){
return;
}
if( sd->inventory_data[i] == nullptr ){
return;
}
struct item* item = &sd->inventory.u.items_inventory[index];
std::shared_ptr<s_laphine_synthesis_requirement> requirement = util::umap_find( synthesis->requirements, item->nameid );
if( requirement == nullptr ){
clif_laphine_synthesis_result( sd, LAPHINE_SYNTHESIS_ITEM );
return;
}
if( p->items[i].count != requirement->amount ){
clif_laphine_synthesis_result( sd, LAPHINE_SYNTHESIS_AMOUNT );
return;
}
if( item->amount < requirement->amount ){
clif_laphine_synthesis_result( sd, LAPHINE_SYNTHESIS_AMOUNT );
return;
}
if( item->refine < synthesis->minimumRefine ){
clif_laphine_synthesis_result( sd, LAPHINE_SYNTHESIS_ITEM );
return;
}
if( item->refine > synthesis->maximumRefine ){
clif_laphine_synthesis_result( sd, LAPHINE_SYNTHESIS_ITEM );
return;
}
}
int16 index = pc_search_inventory( sd, sd->state.laphine_synthesis );
if( index < 0 ){
clif_laphine_synthesis_result( sd, LAPHINE_SYNTHESIS_ITEM );
return;
}
if( ( sd->inventory_data[index]->flag.delay_consume & DELAYCONSUME_NOCONSUME ) == 0 ){
if( pc_delitem( sd, index, 1, 0, 0, LOG_TYPE_CONSUME ) != 0 ){
return;
}
}
for( size_t i = 0; i < count; i++ ){
index = server_index( p->items[i].index );
if( pc_delitem( sd, index, p->items[i].count, 0, 0, LOG_TYPE_LAPHINE ) != 0 ){
return;
}
}
itemdb_group.pc_get_itemgroup( synthesis->rewardGroupId, true, sd );
clif_laphine_synthesis_result( sd, LAPHINE_SYNTHESIS_SUCCESS );
#endif
}
void clif_laphine_upgrade_open( struct map_session_data* sd, std::shared_ptr<s_laphine_upgrade> upgrade ){
#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
nullpo_retv( sd );
sd->state.laphine_upgrade = upgrade->item_id;
struct PACKET_ZC_LAPINEUPGRADE_OPEN p = {};
p.packetType = HEADER_ZC_LAPINEUPGRADE_OPEN;
p.itemId = client_nameid( upgrade->item_id );
clif_send( &p, sizeof( p ), &sd->bl, SELF );
#endif
}
void clif_parse_laphine_upgrade_close( int fd, struct map_session_data* sd ){
#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
sd->state.laphine_upgrade = 0;
#endif
}
void clif_laphine_upgrade_result( struct map_session_data *sd, bool failed ){
#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
struct PACKET_ZC_LAPINEUPGRADE_RESULT p = {};
p.packetType = HEADER_ZC_LAPINEUPGRADE_RESULT;
p.result = failed;
clif_send( &p, sizeof( p ), &sd->bl, SELF );
#endif
}
static void clif_item_preview( struct map_session_data *sd, int16 index ){
#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
nullpo_retv( sd );
struct item* item = &sd->inventory.u.items_inventory[index];
struct PACKET_ZC_ITEM_PREVIEW p = {};
p.packetType = HEADER_ZC_ITEM_PREVIEW;
p.index = client_index( index );
#if PACKETVER_MAIN_NUM >= 20181017 || PACKETVER_RE_NUM >= 20181017 || PACKETVER_ZERO_NUM >= 20181024
p.isDamaged = item->attribute != 0;
#endif
p.refiningLevel = item->refine;
#if PACKETVER_MAIN_NUM >= 20200916 || PACKETVER_RE_NUM >= 20200723
p.enchantgrade = item->enchantgrade;
#endif
clif_addcards( &p.slot, item );
clif_add_random_options( p.option_data, item );
clif_send( &p, sizeof( p ), &sd->bl, SELF );
#endif
}
void clif_parse_laphine_upgrade( int fd, struct map_session_data* sd ){
#if PACKETVER_MAIN_NUM >= 20170726 || PACKETVER_RE_NUM >= 20170621 || defined(PACKETVER_ZERO)
if( sd->state.laphine_upgrade == 0 ){
return;
}
struct PACKET_CZ_LAPINEUPGRADE_MAKE_ITEM* p = (struct PACKET_CZ_LAPINEUPGRADE_MAKE_ITEM*)RFIFOP( fd, 0 );
if( sd->state.laphine_upgrade != p->itemId ){
return;
}
std::shared_ptr<s_laphine_upgrade> upgrade = laphine_upgrade_db.find( sd->state.laphine_upgrade );
if( upgrade == nullptr ){
return;
}
uint16 index = server_index( p->index );
if( index >= MAX_INVENTORY ){
return;
}
if( sd->inventory_data[index] == nullptr ){
return;
}
struct item* item = &sd->inventory.u.items_inventory[index];
// Not a valid target item
if( !util::vector_exists( upgrade->target_item_ids, item->nameid ) ){
clif_laphine_upgrade_result( sd, true );
return;
}
// If target item is not identified
if( item->identify == 0 ){
clif_laphine_upgrade_result( sd, true );
return;
}
// If target item is equipped
if( item->equip != 0 ){
clif_laphine_upgrade_result( sd, true );
return;
}
// Check minimum refine requirement
if( item->refine < upgrade->minimumRefine ){
clif_laphine_upgrade_result( sd, true );
return;
}
// Check maximum refine requirement
if( item->refine > upgrade->maximumRefine ){
clif_laphine_upgrade_result( sd, true );
return;
}
// If no cards are allowed
if( !upgrade->cardsAllowed ){
for( int i = 0; i < MAX_SLOTS; i++ ){
if( item->card[i] != 0 ){
clif_laphine_upgrade_result( sd, true );
return;
}
}
}
// If random options are required
if( upgrade->requiredRandomOptions > 0 ){
int i;
for( i = MAX_ITEM_RDM_OPT - 1; i >= 0; i-- ){
if( item->option[i].id != 0 ){
break;
}
}
if( ( i + 1 ) < upgrade->requiredRandomOptions ){
clif_laphine_upgrade_result( sd, true );
return;
}
}
int16 index2 = pc_search_inventory( sd, sd->state.laphine_upgrade );
if( index2 < 0 ){
clif_laphine_upgrade_result( sd, true );
return;
}
if( ( sd->inventory_data[index2]->flag.delay_consume & DELAYCONSUME_NOCONSUME ) == 0 ){
if( pc_delitem( sd, index2, 1, 0, 0, LOG_TYPE_CONSUME ) != 0 ){
return;
}
}
// Log removal of item
log_pick_pc( sd, LOG_TYPE_LAPHINE, -1, item );
// Visually remove it from the client
clif_delitem( sd, index, 1, 0 );
// Apply the random options
if( upgrade->randomOptionGroup != nullptr ){
upgrade->randomOptionGroup->apply( *item );
}
// Change the refine rate if needed
if( upgrade->resultRefine > 0 ){
// Absolute refine level change
item->refine = max( item->refine, upgrade->resultRefine );
}else if( upgrade->resultRefineMaximum > 0 ){
// If a minimum is specified it can also downgrade
if( upgrade->resultRefineMinimum ){
item->refine = rnd_value( upgrade->resultRefineMinimum, upgrade->resultRefineMaximum );
}else{
// Otherwise it can only be upgraded until the maximum, but not downgraded
item->refine = rnd_value( item->refine, upgrade->resultRefineMaximum );
}
}else if( upgrade->resultRefineMinimum > 0 ){
// No maximum has been specified, so it can be anything between minimum and MAX_REFINE
item->refine = rnd_value( upgrade->resultRefineMinimum, MAX_REFINE );
}
// Log retrieving the item again -> with the new options
log_pick_pc( sd, LOG_TYPE_LAPHINE, 1, item );
// Make it visible for the client again
clif_additem( sd, index, 1, 0 );
// Open a preview of the item
clif_item_preview( sd, index );
// Tell the client we are done
clif_laphine_upgrade_result( sd, false );
#endif
}
/*==========================================
* Main client packet processing function
*------------------------------------------*/