/**
* 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 BulizikLink to comment
Share on other sites
0 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.