/**
* Opens the refine UI on the designated client.
* 0aa0
*/
void clif_refineui_open( struct map_session_data* sd ){
#if PACKETVER >= 20161012
int fd = sd->fd;
WFIFOHEAD(fd,packet_len(0x0AA0));
WFIFOW(fd,0) = 0x0AA0;
WFIFOSET(fd,packet_len(0x0AA0));
sd->state.refineui_open = true;
#endif
}
/**
* Parses cancel/close of the refine UI on client side.
* 0aa4
*/
void clif_parse_refineui_close( int fd, struct map_session_data* sd ){
#if PACKETVER >= 20161012
sd->state.refineui_open = false;
#endif
}
#define REFINEUI_MAT_BS_BLESS 4
#define REFINEUI_MAT_CNT (REFINEUI_MAT_BS_BLESS+1)
/**
* Structure to store all required data about refine requirements
*/
struct refine_materials {
struct refine_cost cost;
uint8 chance;
struct refine_bs_blessing bs_bless;
};
/**
* Fills the given index with the requested data for that item and
* returns true on success or false on failure.
*/
static inline bool clif_refineui_materials_sub( struct item *item, struct item_data *id, struct refine_materials materials[REFINEUI_MAT_CNT], int index, enum refine_cost_type type ){
if( index < 0 || index >= REFINEUI_MAT_CNT ){
return false;
}
struct refine_cost *cost = status_get_refine_cost_((enum refine_type)id->refine_type, type);
if (!cost || !cost->refineui)
return false;
memcpy(&materials[index].cost, cost, sizeof(struct refine_cost));
// Get the chance for refining the item with this material
materials[index].chance = status_get_refine_chance((enum refine_type)id->refine_type, item->refine, type);
// Either of the values was not set
if( materials[index].cost.nameid == 0 || materials[index].cost.zeny == 0 || materials[index].chance == 0 ){
// Reset all entries properly
materials[index].cost.nameid = materials[index].cost.zeny = materials[index].chance = 0;
return false;
}else{
// Everything was set properly
return true;
}
}
/**
* Calculates all possible materials for the given item.
* Returns the count of materials that were filled in the materials array.
*/
static inline uint8 clif_refineui_materials( struct item *item, struct item_data *id, struct refine_materials materials[REFINEUI_MAT_CNT] ){
// Initialize the counter
uint8 count = 0;
// Zero the memory
memset( materials, 0, sizeof(struct refine_materials)*REFINEUI_MAT_CNT );
/**
* Default material indexing is follow as
* 0: Normal refine for +1 ~ +10 or +11 ~ +20
* 1: HD materials for +7 ~ +9 and +11 ~ +20
* 2: Enriched
* 3: Undecided yet, you can add yours later
* 4: Is always for 'Blacksmith Blessing' item to prevent downrefine/break
**/
for (int i = 0; i < REFINE_COST_MAX; i++) {
if (clif_refineui_materials_sub(item, id, materials, count, (enum refine_cost_type)i))
count++;
}
// Blacksmith Blessing requirements if any
status_get_refine_blacksmithBlessing(&materials[REFINEUI_MAT_BS_BLESS].bs_bless, (enum refine_type)id->wlv, item->refine);
// Return the amount of found materials
return count;
}
void clif_refineui_notrefineable(struct map_session_data *sd, uint16 index) {
int fd = sd->fd;
WFIFOHEAD(fd, 7);
WFIFOW(fd, 0) = 0x0AA2;
WFIFOW(fd, 2) = 7;
WFIFOW(fd, 4) = index + 2;
WFIFOB(fd, 6) = 0;
WFIFOSET(fd, 7);
}
/**
* Adds the selected item into the refine UI and sends the possible materials
* to the client.
* 0aa2 <length>.W <index>.W <catalystcount>.B { <material>.W <chance>.B <price>.L }*
*/
void clif_refineui_info( struct map_session_data* sd, uint16 index ){
int fd = sd->fd;
struct item *item;
struct item_data *id;
uint16 length;
struct refine_materials materials[REFINEUI_MAT_CNT];
uint8 i, material_count;
// Get the item db reference
id = sd->inventory_data[index];
// No item data was found
if( id == NULL || id->refine_type == REFINE_TYPE_MAX){
return;
}
// Check if the item can be refined
if( id->flag.no_refine ){
clif_refineui_notrefineable(sd, index);
return;
}
// Check the inventory
item = &sd->inventory.u.items_inventory[index];
// No item was found at the given index
if( item == NULL ){
return;
}
// Check if the item is identified
if( !item->identify ){
clif_refineui_notrefineable(sd, index);
return;
}
// Check if the item is broken
if( item->attribute ){
clif_refineui_notrefineable(sd, index);
return;
}
// Check the current refine level
if( item->refine < 0 || item->refine >= MAX_REFINE ){
clif_refineui_notrefineable(sd, index);
return;
}
// Calculate the possible materials
material_count = clif_refineui_materials( item, id, materials );
// No possibilities were found
if( material_count == 0 ){
clif_refineui_notrefineable(sd, index);
return;
}
length = 7 + material_count * 7;
WFIFOHEAD(fd,length);
WFIFOW(fd,0) = 0x0AA2;
WFIFOW(fd,2) = length;
WFIFOW(fd,4) = index + 2;
WFIFOB(fd,6) = (uint8)materials[REFINEUI_MAT_BS_BLESS].bs_bless.count;
for( i = 0; i < material_count; i++ ){
WFIFOW(fd,7 + i * 7) = materials[i].cost.nameid;
WFIFOB(fd,7 + i * 7 + 2) = materials[i].chance;
WFIFOL(fd,7 + i * 7 + 3) = materials[i].cost.zeny;
}
WFIFOSET(fd,length);
}
/**
* Client request to add an item to the refine UI.
* 0aa1 <index>.W
*/
void clif_parse_refineui_add( int fd, struct map_session_data* sd ){
#if PACKETVER >= 20161012
uint16 index = RFIFOW(fd, 2) - 2;
// Check if the refine UI is open
if( !sd->state.refineui_open ){
return;
}
// Check if the index is valid
if( index < 0 || index >= MAX_INVENTORY ){
return;
}
// Send out the requirements for the refine process
clif_refineui_info( sd, index );
#endif
}
/**
* Client requests to try to refine an item.
* 0aa3 <index>.W <material>.W <catalyst>.B
*/
void clif_parse_refineui_refine( int fd, struct map_session_data* sd ){
#if PACKETVER >= 20161012
uint16 index = RFIFOW( fd, 2 ) - 2;
uint16 material = RFIFOW( fd, 4 );
bool use_blacksmith_blessing = RFIFOB( fd, 6 ) != 0;
struct refine_materials materials[REFINEUI_MAT_CNT];
uint8 i, material_count;
uint16 j;
struct item *item;
struct item_data *id;
// Check if the refine UI is open
if( !sd->state.refineui_open ){
return;
}
// Check if the index is valid
if( index < 0 || index >= MAX_INVENTORY ){
return;
}
// Get the item db reference
id = sd->inventory_data[index];
// No item data was found
if( id == NULL || id->refine_type == REFINE_TYPE_MAX){
return;
}
// Check if the item can be refined
if( id->flag.no_refine ){
return;
}
// Check the inventory
item = &sd->inventory.u.items_inventory[index];
// No item was found at the given index
if( item == NULL ){
return;
}
// Check if the item is identified
if( !item->identify ){
return;
}
// Check if the item is broken
if( item->attribute ){
return;
}
// Check the current refine level
if( item->refine < 0 || item->refine >= MAX_REFINE ){
return;
}
// Check if the player has the selected material
if( ( j = pc_search_inventory( sd, material ) ) < 0 ){
return;
}
// Calculate the possible materials
material_count = clif_refineui_materials( item, id, materials );
// No possibilities were found
if( material_count == 0 ){
return;
}
// Find the selected material
ARR_FIND( 0, REFINEUI_MAT_CNT, i, materials[i].cost.nameid == material );
// The material was not in the list of possible materials
if( i >= REFINEUI_MAT_CNT || i < 0 ){
return;
}
// Try to pay for the refine. By default, client checked if player has enough zeny or not
if( pc_payzeny( sd, materials[i].cost.zeny, LOG_TYPE_CONSUME, NULL ) ){
clif_npc_buy_result( sd, 1 ); // "You do not have enough zeny."
return;
}
// Delete the required material
if( pc_delitem( sd, j, 1, 0, 0, LOG_TYPE_CONSUME ) ){
return;
}
if (use_blacksmith_blessing && materials[REFINEUI_MAT_BS_BLESS].bs_bless.count) {
if ((j = pc_search_inventory(sd, materials[REFINEUI_MAT_BS_BLESS].bs_bless.nameid)) < 0) {
return;
}
if (pc_delitem(sd, j, materials[REFINEUI_MAT_BS_BLESS].bs_bless.count, 0, 0, LOG_TYPE_CONSUME)) {
return;
}
}
else {
use_blacksmith_blessing = false;
}
// Try to refine the item
if( materials[i].chance >= rnd() % 100 ){
// Success
item->refine = cap_value( item->refine + 1, 0, MAX_REFINE );
clif_misceffect( &sd->bl, 3 );
clif_refine( fd, 0, index, item->refine );
achievement_update_objective( sd, AG_REFINE_SUCCESS, 2, id->wlv, item->refine );
clif_refineui_info( sd, index );
}else{
// Failure
do {
if (!use_blacksmith_blessing) {
int r = rnd() % 100;
if (r < materials[i].cost.breaking) { // Breaking chance
clif_refine(fd, 1, index, item->refine);
pc_delitem(sd, index, 1, 0, 0, LOG_TYPE_CONSUME);
break;
}
else if (r < (materials[i].cost.breaking + materials[i].cost.downrefine)) { // Downrefine chance
item->refine = cap_value(item->refine - materials[i].cost.downrefine_num, 0, MAX_REFINE);
clif_refine(fd, 2, index, item->refine);
clif_refineui_info(sd, index);
break;
}
}
// Blacksmith Blessing were used, no break & no down refine
clif_refine(fd, 3, index, item->refine);
clif_refineui_info(sd, index);
} while (0);
clif_misceffect( &sd->bl, 2 );
achievement_update_objective( sd, AG_REFINE_FAIL, 1, 1 );
}
#endif
}
#undef REFINEUI_MAT_CNT
how can i change the blacksmith blessing to only prevent downrefine only not the unbreakable part thanks
Question
Bulizik
how can i change the blacksmith blessing to only prevent downrefine only not the unbreakable part thanks
im using these sources https://github.com/cydh/rathena/pull/10
Edited by Bulizik0 answers to this question
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.