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:
339
src/map/clif.cpp
339
src/map/clif.cpp
@@ -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
|
||||
*------------------------------------------*/
|
||||
|
||||
Reference in New Issue
Block a user