/** * 'Cancel' is pressed. (or trade was force-cancelled by the code) * @param sd : Player that pressed the button */ void trade_tradecancel(struct map_session_data *sd) { struct map_session_data *target_sd; int trade_i; nullpo_retv(sd); target_sd = map_id2sd(sd->trade_partner); sd->state.isBoundTrading = 0; if(!sd->state.trading) { // Not trade accepted if( target_sd ) { target_sd->trade_partner = 0; clif_tradecancelled(target_sd); } sd->trade_partner = 0; clif_tradecancelled(sd); return; } for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual) if (!sd->deal.item[trade_i].amount) continue; clif_additem(sd, sd->deal.item[trade_i].index, sd->deal.item[trade_i].amount, 0); sd->deal.item[trade_i].index = 0; sd->deal.item[trade_i].amount = 0; } if (sd->deal.zeny) { clif_updatestatus(sd, SP_ZENY); sd->deal.zeny = 0; } sd->state.deal_locked = 0; sd->state.trading = 0; sd->trade_partner = 0; clif_tradecancelled(sd); if (!target_sd) return; for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual) if (!target_sd->deal.item[trade_i].amount) continue; clif_additem(target_sd, target_sd->deal.item[trade_i].index, target_sd->deal.item[trade_i].amount, 0); target_sd->deal.item[trade_i].index = 0; target_sd->deal.item[trade_i].amount = 0; } if (target_sd->deal.zeny) { clif_updatestatus(target_sd, SP_ZENY); target_sd->deal.zeny = 0; } target_sd->state.deal_locked = 0; target_sd->trade_partner = 0; target_sd->state.trading = 0; clif_tradecancelled(target_sd); }
/*========================================== * 取引キャンセル *------------------------------------------ */ void trade_tradecancel(dumb_ptr<map_session_data> sd) { dumb_ptr<map_session_data> target_sd; int trade_i; nullpo_retv(sd); if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr) { for (trade_i = 0; trade_i < TRADE_MAX; trade_i++) { //give items back (only virtual) if (sd->deal_item_amount[trade_i] != 0) { assert (sd->deal_item_index[trade_i].ok()); clif_additem(sd, sd->deal_item_index[trade_i].unshift(), sd->deal_item_amount[trade_i], PickupFail::OKAY); sd->deal_item_index[trade_i] = IOff2::from(0); sd->deal_item_amount[trade_i] = 0; } if (target_sd->deal_item_amount[trade_i] != 0) { assert (target_sd->deal_item_index[trade_i].ok()); clif_additem(target_sd, target_sd->deal_item_index[trade_i].unshift(), target_sd->deal_item_amount[trade_i], PickupFail::OKAY); target_sd->deal_item_index[trade_i] = IOff2::from(0); target_sd->deal_item_amount[trade_i] = 0; } } if (sd->deal_zeny) { sd->deal_zeny = 0; clif_updatestatus(sd, SP::ZENY); } if (target_sd->deal_zeny) { clif_updatestatus(target_sd, SP::ZENY); target_sd->deal_zeny = 0; } sd->deal_locked = 0; sd->trade_partner = AccountId(); target_sd->deal_locked = 0; target_sd->trade_partner = AccountId(); clif_tradecancelled(sd); clif_tradecancelled(target_sd); } }
/*========================================== * 取引キャンセル *------------------------------------------ */ void trade_tradecancel(dumb_ptr<map_session_data> sd) { dumb_ptr<map_session_data> target_sd; int trade_i; nullpo_retv(sd); if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) { for (trade_i = 0; trade_i < 10; trade_i++) { //give items back (only virtual) if (sd->deal_item_amount[trade_i] != 0) { clif_additem(sd, sd->deal_item_index[trade_i] - 2, sd->deal_item_amount[trade_i], PickupFail::OKAY); sd->deal_item_index[trade_i] = 0; sd->deal_item_amount[trade_i] = 0; } if (target_sd->deal_item_amount[trade_i] != 0) { clif_additem(target_sd, target_sd->deal_item_index[trade_i] - 2, target_sd->deal_item_amount[trade_i], PickupFail::OKAY); target_sd->deal_item_index[trade_i] = 0; target_sd->deal_item_amount[trade_i] = 0; } } if (sd->deal_zeny) { sd->deal_zeny = 0; clif_updatestatus(sd, SP::ZENY); } if (target_sd->deal_zeny) { clif_updatestatus(target_sd, SP::ZENY); target_sd->deal_zeny = 0; } sd->deal_locked = 0; sd->trade_partner = 0; target_sd->deal_locked = 0; target_sd->trade_partner = 0; clif_tradecancelled(sd); clif_tradecancelled(target_sd); } }
/*========================================== * カプラ倉庫から出す *------------------------------------------ */ void storage_storageget(struct map_session_data *sd, int idx, int amount) { struct storage *stor; int flag; nullpo_retv(sd); nullpo_retv(stor = (struct storage *)numdb_search(storage_db,sd->status.account_id)); if(!stor->storage_status) return; if(idx < 0 || idx >= MAX_STORAGE) return; if(amount < 1 || amount > stor->store_item[idx].amount) return; if((flag = pc_additem(sd, &stor->store_item[idx], amount)) == 0) { storage_delitem(sd, stor, idx, amount); return; } clif_storageitemremoved(sd,idx,amount); clif_additem(sd,0,0,flag); clif_storageitemadded(sd,stor,idx,amount); return; }
/** * Attempt to retrieve an item from guild storage to inventory, then refresh it * @param sd : player * @param index : index of item in storage * @param amount : number of item to get * @return 1:success, 0:fail */ void storage_guild_storageget(struct map_session_data* sd, int index, int amount) { struct guild_storage *stor; unsigned char flag = 0; nullpo_retv(sd); nullpo_retv(stor=guild2storage2(sd->status.guild_id)); if(!stor->storage_status) return; if(index < 0 || index >= MAX_GUILD_STORAGE) return; if(stor->items[index].nameid == 0) return; if(amount < 1 || amount > stor->items[index].amount) return; if( stor->lock ) { storage_guild_storageclose(sd); return; } if((flag = pc_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)) == 0) guild_storage_delitem(sd,stor,index,amount); else {//inform fail clif_storageitemremoved(sd,index,0); clif_additem(sd,0,0,flag); } }
int pet_get_egg(int account_id,int pet_id,int flag) { //This function is invoked when a new pet has been created, and at no other time! struct map_session_data *sd; struct item tmp_item; int i=0,ret=0; if(flag) return 0; sd = map_id2sd(account_id); if(sd == NULL) return 0; i = search_petDB_index(sd->catch_target_class,PET_CLASS); sd->catch_target_class = -1; if(i < 0) { intif_delete_petdata(pet_id); return 0; } memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.nameid = pet_db[i].EggID; tmp_item.identify = 1; tmp_item.card[0] = CARD0_PET; tmp_item.card[1] = GetWord(pet_id,0); tmp_item.card[2] = GetWord(pet_id,1); tmp_item.card[3] = 0; //New pets are not named. if((ret = pc_additem(sd,&tmp_item,1,LOG_TYPE_PICKDROP_PLAYER))) { clif_additem(sd,0,0,ret); map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } return 1; }
/** [Cydh] * Gives item(s) to the player based on item group * @param sd: Player that obtains item from item group * @param group_id: The group ID of item that obtained by player * @param *group: struct s_item_group from itemgroup_db[group_id].random[idx] or itemgroup_db[group_id].must[sub_group][idx] */ static void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, uint16 group_id, struct s_item_group *group) { uint16 i; struct item tmp; nullpo_retv(group); memset(&tmp, 0, sizeof(tmp)); tmp.nameid = group->nameid; tmp.amount = (itemdb_isstackable(group->nameid)) ? group->amount : 1; tmp.bound = group->bound; tmp.identify = 1; tmp.expire_time = (group->duration) ? (unsigned int)(time(NULL) + group->duration * 60) : 0; if (group->isNamed) { tmp.card[0] = itemdb_isequip(group->nameid) ? CARD0_FORGE : CARD0_CREATE; tmp.card[1] = 0; tmp.card[2] = GetWord(sd->status.char_id, 0); tmp.card[3] = GetWord(sd->status.char_id, 1); } //Do loop for non-stackable item for (i = 0; i < group->amount; i++) { int flag; if ((flag = pc_additem(sd,&tmp,tmp.amount,LOG_TYPE_SCRIPT))) clif_additem(sd,0,0,flag); else if (!flag && group->isAnnounced) { char output[CHAT_SIZE_MAX]; sprintf(output, msg_txt(717), sd->status.name, itemdb_jname(group->nameid), itemdb_jname(sd->itemid)); clif_broadcast(&sd->bl, output,strlen(output), 0, ALL_CLIENT); } if (itemdb_isstackable(group->nameid)) break; } }
/*========================================== * Retrieve an item from the storage. *------------------------------------------ */ int storage_storageget(struct map_session_data *sd,int index,int amount) { struct storage *stor; int flag; nullpo_retr(0, sd); nullpo_retr(0, stor=account2storage2(sd->status.account_id)); if(index<0 || index>=MAX_STORAGE) return 0; if(stor->storage_[index].nameid <= 0) return 0; //Nothing there if(amount < 1 || amount > stor->storage_[index].amount) return 0; if((flag = pc_additem(sd,&stor->storage_[index],amount)) == 0) storage_delitem(sd,stor,index,amount); else clif_additem(sd,0,0,flag); // log_fromstorage(sd, index, 0); return 1; }
/*========================================== * Attempt to retrieve an item from guild storage to inventory, then refresh it * @index : storage idx * return * 0 : fail * 1 : succes *------------------------------------------*/ int storage_guild_storageget(struct map_session_data* sd, int index, int amount) { struct guild_storage *stor; int flag; nullpo_ret(sd); nullpo_ret(stor=guild2storage2(sd->status.guild_id)); if(!stor->storage_status) return 0; if(index<0 || index>=MAX_GUILD_STORAGE) return 0; if(stor->items[index].nameid <= 0) return 0; if(amount < 1 || amount > stor->items[index].amount) return 0; if( stor->lock ) { storage_guild_storageclose(sd); return 0; } if((flag = pc_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)) == 0) guild_storage_delitem(sd,stor,index,amount); else //inform fail clif_additem(sd,0,0,flag); // log_fromstorage(sd, index, 1); return 0; }
static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd) { struct item tmp_item; int flag; pet_lootitem_drop(pd,sd); memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.nameid = pd->petDB->EggID; tmp_item.identify = 1; tmp_item.card[0] = CARD0_PET; tmp_item.card[1] = GetWord(pd->pet.pet_id,0); tmp_item.card[2] = GetWord(pd->pet.pet_id,1); tmp_item.card[3] = pd->pet.rename_flag; if((flag = pc_additem(sd,&tmp_item,1))) { clif_additem(sd,0,0,flag); map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } pd->pet.incuvate = 1; //No need, pet is saved on unit_free below. //intif_save_petdata(sd->status.account_id,&pd->pet); if(pd->state.skillbonus) { pd->state.skillbonus = 0; status_calc_pc(sd,0); } unit_free(&pd->bl,0); sd->status.pet_id = 0; return 1; }
static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd) { struct item tmp_item; unsigned char flag = 0; pet_lootitem_drop(pd,sd); memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.nameid = pd->petDB->EggID; tmp_item.identify = 1; tmp_item.card[0] = CARD0_PET; tmp_item.card[1] = GetWord(pd->pet.pet_id,0); tmp_item.card[2] = GetWord(pd->pet.pet_id,1); tmp_item.card[3] = pd->pet.rename_flag; if((flag = pc_additem(sd,&tmp_item,1,LOG_TYPE_OTHER))) { clif_additem(sd,0,0,flag); map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0); } pd->pet.incubate = 1; unit_free(&pd->bl,CLR_OUTSIGHT); status_calc_pc(sd,SCO_NONE); sd->status.pet_id = 0; return 1; }
int mail_removeitem(struct map_session_data *sd, short flag, int idx, int amount) { int i; nullpo_ret(sd); idx -= 2; if( idx < 0 || idx >= MAX_INVENTORY ) return false; if( amount <= 0 || amount > sd->inventory.u.items_inventory[idx].amount ) return false; ARR_FIND(0, MAIL_MAX_ITEM, i, sd->mail.item[i].index == idx && sd->mail.item[i].nameid > 0); if( i == MAIL_MAX_ITEM ){ return false; } if( flag ){ if( battle_config.mail_attachment_price > 0 ){ if( pc_payzeny( sd, battle_config.mail_attachment_price, LOG_TYPE_MAIL, NULL ) ){ return false; } } #if PACKETVER < 20150513 // With client update packet pc_delitem(sd, idx, amount, 1, 0, LOG_TYPE_MAIL); #else // RODEX refreshes the client inventory from the ACK packet pc_delitem(sd, idx, amount, 0, 0, LOG_TYPE_MAIL); #endif }else{ for( ; i < MAIL_MAX_ITEM-1; i++ ){ if (sd->mail.item[i + 1].nameid == 0) break; sd->mail.item[i].index = sd->mail.item[i+1].index; sd->mail.item[i].nameid = sd->mail.item[i+1].nameid; sd->mail.item[i].amount = sd->mail.item[i+1].amount; } for( ; i < MAIL_MAX_ITEM; i++ ){ sd->mail.item[i].index = 0; sd->mail.item[i].nameid = 0; sd->mail.item[i].amount = 0; } #if PACKETVER < 20150513 clif_additem(sd, idx, amount, 0); #else clif_mail_removeitem(sd, true, idx + 2, amount); #endif } return 1; }
/*========================================== * 取引キャンセル *------------------------------------------ */ void trade_tradecancel(struct map_session_data *sd) { struct map_session_data *target_sd; int trade_i; nullpo_retv(sd); target_sd = map_id2sd(sd->trade.partner); if(target_sd && target_sd->bl.prev) { for(trade_i = 0; trade_i < MAX_DEAL_ITEMS; trade_i++) { //give items back (only virtual) if(target_sd->trade.item_amount[trade_i] != 0) { clif_additem(target_sd,target_sd->trade.item_index[trade_i]-2,target_sd->trade.item_amount[trade_i],0); target_sd->trade.item_index[trade_i] = 0; target_sd->trade.item_amount[trade_i] = 0; } } if(target_sd->trade.zeny) { clif_updatestatus(target_sd,SP_ZENY); target_sd->trade.zeny = 0; } target_sd->state.deal_locked = 0; target_sd->state.deal_mode = 0; target_sd->trade.partner = 0; clif_tradecancelled(target_sd); } for(trade_i = 0; trade_i < MAX_DEAL_ITEMS; trade_i++) { //give items back (only virtual) if (sd->trade.item_amount[trade_i] != 0) { clif_additem(sd, sd->trade.item_index[trade_i]-2, sd->trade.item_amount[trade_i], 0); sd->trade.item_index[trade_i] = 0; sd->trade.item_amount[trade_i] = 0; } } if (sd->trade.zeny) { clif_updatestatus(sd, SP_ZENY); sd->trade.zeny = 0; } sd->state.deal_locked = 0; sd->state.deal_mode = 0; sd->trade.partner = 0; clif_tradecancelled(sd); return; }
/*========================================== * 取引キャンセル *------------------------------------------ */ void trade_tradecancel(struct map_session_data *sd) { struct map_session_data *target_sd; int trade_i; nullpo_retv(sd); if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) { for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual) if (sd->deal.item[trade_i].amount != 0) { clif_additem(sd, sd->deal.item[trade_i].index, sd->deal.item[trade_i].amount, 0); sd->deal.item[trade_i].index = 0; sd->deal.item[trade_i].amount = 0; } if (target_sd->deal.item[trade_i].amount != 0) { clif_additem(target_sd, target_sd->deal.item[trade_i].index, target_sd->deal.item[trade_i].amount, 0); target_sd->deal.item[trade_i].index = 0; target_sd->deal.item[trade_i].amount = 0; } } if (sd->deal.zeny) { clif_updatestatus(sd, SP_ZENY); sd->deal.zeny = 0; } if (target_sd->deal.zeny) { clif_updatestatus(target_sd, SP_ZENY); target_sd->deal.zeny = 0; } sd->state.deal_locked = 0; sd->trade_partner = 0; sd->state.trading = 0; target_sd->state.deal_locked = 0; target_sd->trade_partner = 0; target_sd->state.trading = 0; clif_tradecancelled(sd); clif_tradecancelled(target_sd); } }
int mail_removeitem(struct map_session_data *sd, short flag) { nullpo_ret(sd); if( sd->mail.amount ) { if (flag) // Item send pc_delitem(sd, sd->mail.index, sd->mail.amount, 1, 0, LOG_TYPE_MAIL); else clif_additem(sd, sd->mail.index, sd->mail.amount, 0); } sd->mail.nameid = 0; sd->mail.index = 0; sd->mail.amount = 0; return 1; }
/** * Retrieve an item from the storage into inventory * @param sd : player * @param index : storage index to take the item from * @param amount : number of item to take * @return 0:fail, 1:success */ void storage_storageget(struct map_session_data *sd, struct s_storage *stor, int index, int amount) { unsigned char flag = 0; enum e_storage_add result; nullpo_retv(sd); result = storage_canGetItem(stor, index, amount); if (result != STORAGE_ADD_OK) return; if ((flag = pc_additem(sd,&stor->u.items_storage[index],amount,LOG_TYPE_STORAGE)) == ADDITEM_SUCCESS) storage_delitem(sd,stor,index,amount); else { clif_storageitemremoved(sd,index,0); clif_additem(sd,0,0,flag); } }
/** * Remove a pet's equipment. * @param sd : player requesting * @param pd : pet requesting * @return 0:success, 1:failure */ static int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd) { struct item tmp_item; unsigned short nameid; unsigned char flag = 0; if(pd->pet.equip == 0) return 1; nameid = pd->pet.equip; pd->pet.equip = 0; status_set_viewdata(&pd->bl, pd->pet.class_); clif_pet_equip_area(pd); memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.nameid = nameid; tmp_item.identify = 1; if((flag = pc_additem(sd,&tmp_item,1,LOG_TYPE_OTHER))) { clif_additem(sd,0,0,flag); map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0); } if( battle_config.pet_equip_required ) { // Skotlex: halt support timers if needed if( pd->state.skillbonus ) { pd->state.skillbonus = 0; status_calc_pc(sd,SCO_NONE); } if( pd->s_skill && pd->s_skill->timer != INVALID_TIMER ) { if( pd->s_skill->id ) delete_timer(pd->s_skill->timer, pet_skill_support_timer); else delete_timer(pd->s_skill->timer, pet_heal_timer); pd->s_skill->timer = INVALID_TIMER; } if( pd->bonus && pd->bonus->timer != INVALID_TIMER ) { delete_timer(pd->bonus->timer, pet_skill_bonus_timer); pd->bonus->timer = INVALID_TIMER; } } return 0; }
void bg_team_getitem(int bg_id, int nameid, int amount) { struct battleground_data *bg; struct map_session_data *sd; struct item_data *id; struct item it; int get_amount, i, j, flag, rank = 0; if( amount < 1 || (bg = bg_team_search(bg_id)) == NULL || (id = itemdb_exists(nameid)) == NULL ) return; if( nameid != 7828 && nameid != 7829 && nameid != 7773 ) return; if( battle_config.bg_reward_rates != 100 ) amount = amount * battle_config.bg_reward_rates / 100; memset(&it, 0, sizeof(it)); it.nameid = nameid; it.identify = 1; for( j = 0; j < MAX_BG_MEMBERS; j++ ) { if( (sd = bg->members[j].sd) == NULL ) continue; if( battle_config.bg_ranking_bonus ) { rank = 0; ARR_FIND(0,MAX_FAME_LIST,i,bgrank_fame_list[i].id == sd->status.char_id); if( i < MAX_FAME_LIST ) rank = 1; else { ARR_FIND(0,MAX_FAME_LIST,i,bg_fame_list[i].id == sd->status.char_id); if( i < MAX_FAME_LIST ) rank = 1; } } get_amount = amount; if( rank ) get_amount += battle_config.bg_ranking_bonus * get_amount / 100; if( (flag = pc_additem(sd,&it,get_amount,LOG_TYPE_SCRIPT)) ) clif_additem(sd,0,0,flag); } }
/** * Is invoked _only_ when a new pet has been created is a product of packet 0x3880 * see mapif_pet_created@int_pet.c for more information. * Handles new pet data from inter-server and prepares item information to add pet egg. * @param account_id : account ID of owner * @param pet_class : class of pet * @param pet_id : pet ID otherwise means failure * @return true : success, false : failure **/ bool pet_get_egg(int account_id, short pet_class, int pet_id ) { struct map_session_data *sd; struct item tmp_item; int i = 0, ret = 0; if( pet_id == 0 || pet_class == 0 ) return false; sd = map_id2sd(account_id); if( sd == NULL ) return false; // i = pet_search_petDB_index(sd->catch_target_class,PET_CLASS); // issue: 8150 // Before this change in cases where more than one pet egg were requested in a short // period of time it wasn't possible to know which kind of egg was being requested after // the first request. [Panikon] i = search_petDB_index(pet_class,PET_CLASS); sd->catch_target_class = -1; if(i < 0) { intif_delete_petdata(pet_id); return false; } memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.nameid = pet_db[i].EggID; tmp_item.identify = 1; tmp_item.card[0] = CARD0_PET; tmp_item.card[1] = GetWord(pet_id,0); tmp_item.card[2] = GetWord(pet_id,1); tmp_item.card[3] = 0; //New pets are not named. if((ret = pc_additem(sd,&tmp_item,1,LOG_TYPE_PICKDROP_PLAYER))) { clif_additem(sd,0,0,ret); map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0); } return true; }
/*========================================== * Retrieve an item from the storage into inventory * @index : storage idx * return * 0 : fail * 1 : success *------------------------------------------*/ int storage_storageget(struct map_session_data* sd, int index, int amount) { int flag; if( index < 0 || index >= MAX_STORAGE ) return 0; if( sd->status.storage.items[index].nameid <= 0 ) return 0; //Nothing there if( amount < 1 || amount > sd->status.storage.items[index].amount ) return 0; if( (flag = pc_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 ) storage_delitem(sd,index,amount); else clif_additem(sd,0,0,flag); return 1; }
/** * Retrieve an item from the storage into inventory * @param sd : player * @param index : storage index to take the item from * @param amount : number of item to take * @return 0:fail, 1:success */ void storage_storageget(struct map_session_data* sd, int index, int amount) { unsigned char flag = 0; if( index < 0 || index >= sd->storage_size ) return; if( sd->status.storage.items[index].nameid <= 0 ) return; //Nothing there if( amount < 1 || amount > sd->status.storage.items[index].amount ) return; if( (flag = pc_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 ) storage_delitem(sd,index,amount); else { clif_storageitemremoved(sd,index,0); clif_additem(sd,0,0,flag); } }
int mail_removeitem(struct map_session_data *sd, short flag) { nullpo_ret(sd); if( sd->mail.amount ) { if (flag) { // Item send log_pick_pc(sd, LOG_TYPE_MAIL, sd->mail.nameid, -sd->mail.amount, &sd->status.inventory[sd->mail.index]); pc_delitem(sd, sd->mail.index, sd->mail.amount, 1, 0); } else clif_additem(sd, sd->mail.index, sd->mail.amount, 0); } sd->mail.nameid = 0; sd->mail.index = 0; sd->mail.amount = 0; return 1; }
int mail_removeitem(struct map_session_data *sd, short flag) { nullpo_retr(0,sd); if( sd->mail.amount ) { if (flag) { // Item send if(log_config.enable_logs&0x2000) log_pick_pc(sd, "E", sd->mail.nameid, -sd->mail.amount, &sd->status.inventory[sd->mail.index]); pc_delitem(sd, sd->mail.index, sd->mail.amount, 1); } else clif_additem(sd, sd->mail.index, sd->mail.amount, 0); } sd->mail.nameid = 0; sd->mail.index = 0; sd->mail.amount = 0; return 1; }
//Vaporize a character's homun. If flag, HP needs to be 80% or above. int merc_hom_vaporize(struct map_session_data *sd, int flag) { struct item tmp_item; struct s_homunculus *hom; struct homun_data *hd; int rate; hd = sd->hd; hom = &hd->homunculus; sd->status.lock = 0; if(hom->ditto == 1){ //hd->homunculus.class_ = 2502; //status_set_viewdata(&hd->bl, 2502); //merc_hom_calc_skilltree(hd); rate = 8162; }else{ rate =(hd->homunculus.class_) + 5530; } merc_save(hd); hom->char_id = sd->status.char_id; memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.nameid = rate; tmp_item.identify = 1; tmp_item.card[0] = CARD0_HUN; tmp_item.card[1] = GetWord(hd->homunculus.hom_id,0); tmp_item.card[2] = GetWord(hd->homunculus.hom_id,1); tmp_item.card[3] = 0; if((flag = pc_additem(sd,&tmp_item,1))) { clif_additem(sd,0,0,flag); map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } sd = hd->master; hd->homunculus.intimacy = 0; return unit_remove_map(&hd->bl,CLR_OUTSIGHT); }
/** [Cydh] * Gives item(s) to the player based on item group * @param sd: Player that obtains item from item group * @param group_id: The group ID of item that obtained by player * @param *group: struct s_item_group from itemgroup_db[group_id].random[idx] or itemgroup_db[group_id].must[sub_group][idx] */ static void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, struct s_item_group_entry *data) { uint16 i; struct item tmp; nullpo_retv(data); memset(&tmp, 0, sizeof(tmp)); tmp.nameid = data->nameid; tmp.amount = (itemdb_isstackable(data->nameid)) ? data->amount : 1; tmp.bound = data->bound; tmp.identify = 1; tmp.expire_time = (data->duration) ? (unsigned int)(time(NULL) + data->duration*60) : 0; if (data->isNamed) { tmp.card[0] = itemdb_isequip(data->nameid) ? CARD0_FORGE : CARD0_CREATE; tmp.card[1] = 0; tmp.card[2] = GetWord(sd->status.char_id, 0); tmp.card[3] = GetWord(sd->status.char_id, 1); } // Do loop for non-stackable item for (i = 0; i < data->amount; i++) { char flag = 0; #ifdef ENABLE_ITEM_GUID tmp.unique_id = data->GUID ? pc_generate_unique_id(sd) : 0; // Generate UID #endif if ((flag = pc_additem(sd, &tmp, tmp.amount, LOG_TYPE_SCRIPT))) clif_additem(sd, 0, 0, flag); else if (!flag && data->isAnnounced) { char output[CHAT_SIZE_MAX]; sprintf(output, msg_txt(NULL, 717), sd->status.name, itemdb_jname(data->nameid), itemdb_jname(sd->itemid)); //! TODO: Move this broadcast to proper packet intif_broadcast(output, strlen(output) + 1, BC_DEFAULT); //clif_broadcast_obtain_special_item(); } if (itemdb_isstackable(data->nameid)) break; } }
int ext_storage_get(struct map_session_data* sd, int index, int amount) { int flag; nullpo_ret(sd); if( index < 0 || index >= MAX_EXTRA_STORAGE ) return 0; if( sd->status.ext_storage.items[index].nameid <= 0 ) return 0; //Nothing there if( amount < 1 || amount > sd->status.ext_storage.items[index].amount ) return 0; if( (flag = pc_additem(sd,&sd->status.ext_storage.items[index],amount)) == 0 ) ext_storage_delitem(sd,index,amount); else clif_additem(sd,0,0,flag); return 1; }
/*========================================== * ギルド倉庫から出す *------------------------------------------ */ void storage_guild_storageget(struct map_session_data *sd, int idx, int amount) { struct guild_storage *stor; int flag; nullpo_retv(sd); if((stor = (struct guild_storage *)numdb_search(guild_storage_db,sd->status.guild_id)) == NULL) return; if(!stor->storage_status) return; if(idx < 0 || idx >= MAX_GUILD_STORAGE) return; if(amount < 1 || amount > stor->store_item[idx].amount) return; if((flag = pc_additem(sd,&stor->store_item[idx],amount)) == 0) storage_guild_delitem(sd, stor, idx, amount); else clif_additem(sd,0,0,flag); return; }
/** [Cydh] * Gives item(s) to the player based on item group * @param sd: Player that obtains item from item group * @param group_id: The group ID of item that obtained by player * @param *group: struct s_item_group from itemgroup_db[group_id].random[idx] or itemgroup_db[group_id].must[sub_group][idx] */ static void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, struct s_item_group_entry *data) { uint16 i, get_amt = 0; struct item tmp; nullpo_retv(data); memset(&tmp, 0, sizeof(tmp)); tmp.nameid = data->nameid; tmp.bound = data->bound; tmp.identify = 1; tmp.expire_time = (data->duration) ? (unsigned int)(time(NULL) + data->duration*60) : 0; if (data->isNamed) { tmp.card[0] = itemdb_isequip(data->nameid) ? CARD0_FORGE : CARD0_CREATE; tmp.card[1] = 0; tmp.card[2] = GetWord(sd->status.char_id, 0); tmp.card[3] = GetWord(sd->status.char_id, 1); } if (!itemdb_isstackable(data->nameid)) get_amt = 1; else get_amt = data->amount; // Do loop for non-stackable item for (i = 0; i < data->amount; i += get_amt) { char flag = 0; tmp.unique_id = data->GUID ? pc_generate_unique_id(sd) : 0; // Generate GUID if ((flag = pc_additem(sd, &tmp, get_amt, LOG_TYPE_SCRIPT))) { clif_additem(sd, 0, 0, flag); if (pc_candrop(sd, &tmp)) map_addflooritem(&tmp, tmp.amount, sd->bl.m, sd->bl.x,sd->bl.y, 0, 0, 0, 0, 0); } else if (!flag && data->isAnnounced) intif_broadcast_obtain_special_item(sd, data->nameid, sd->itemid, ITEMOBTAIN_TYPE_BOXITEM); } }
int merc_hom_dead(struct homun_data *hd, int flag) { struct map_session_data *sd = hd->master; struct s_homunculus *hom; struct item tmp_item; int rate; sd = hd->master; hd = sd->hd; hom = &hd->homunculus; rate =(hd->homunculus.class_) + 5530; merc_save(hd); sd = hd->master; pc_delitem(sd, pc_search_inventory(sd,690), 1, 0, 0); //sd->status.hom_id = 0; sd->status.lock = 0; merc_hom_hungry_timer_delete(hd); hd->homunculus.hp = 0; hom->char_id = sd->status.char_id; memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.nameid = rate; tmp_item.identify = 1; tmp_item.card[0] = CARD0_HUN; tmp_item.card[1] = GetWord(hd->homunculus.hom_id,0); tmp_item.card[2] = GetWord(hd->homunculus.hom_id,1); tmp_item.card[3] = 1; if((flag = pc_additem(sd,&tmp_item,1))) { clif_additem(sd,0,0,flag); map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } hd->homunculus.hp = 0; hd->homunculus.intimacy = 0; return unit_remove_map(&hd->bl,CLR_OUTSIGHT); }
/*========================================== * Žæˆø‹–‘ø(trade‰Ÿ‚µ) *------------------------------------------*/ void trade_tradecommit (struct map_session_data *sd) { struct map_session_data *tsd; int trade_i; int flag; if (!sd->state.trading || !sd->state.deal_locked) //Locked should be 1 (pressed ok) before you can press trade. return; if ( (tsd = map_id2sd (sd->trade_partner)) == NULL) { trade_tradecancel (sd); return; } sd->state.deal_locked = 2; if (tsd->state.deal_locked < 2) return; //Not yet time for trading. //Now is a good time (to save on resources) to check that the trade can indeed be made and it's not exploitable. // check exploit (trade more items that you have) if (impossible_trade_check (sd)) { trade_tradecancel (sd); return; } // check exploit (trade more items that you have) if (impossible_trade_check (tsd)) { trade_tradecancel (tsd); return; } // check for full inventory (can not add traded items) if (!trade_check (sd, tsd)) { // check the both players trade_tradecancel (sd); return; } // trade is accepted and correct. for (trade_i = 0; trade_i < 10; trade_i++) { int n; if (sd->deal.item[trade_i].amount) { n = sd->deal.item[trade_i].index; flag = pc_additem (tsd, &sd->status.inventory[n], sd->deal.item[trade_i].amount, LOG_TYPE_TRADE); if (flag == 0) pc_delitem (sd, n, sd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE); else clif_additem (sd, n, sd->deal.item[trade_i].amount, 0); sd->deal.item[trade_i].index = 0; sd->deal.item[trade_i].amount = 0; } if (tsd->deal.item[trade_i].amount) { n = tsd->deal.item[trade_i].index; flag = pc_additem (sd, &tsd->status.inventory[n], tsd->deal.item[trade_i].amount, LOG_TYPE_TRADE); if (flag == 0) pc_delitem (tsd, n, tsd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE); else clif_additem (tsd, n, tsd->deal.item[trade_i].amount, 0); tsd->deal.item[trade_i].index = 0; tsd->deal.item[trade_i].amount = 0; } } if (sd->deal.zeny) { pc_payzeny (sd , sd->deal.zeny, LOG_TYPE_TRADE, tsd); pc_getzeny (tsd, sd->deal.zeny, LOG_TYPE_TRADE, sd); sd->deal.zeny = 0; sd->deal.zeny = 0; } if (tsd->deal.zeny) { pc_payzeny (tsd, tsd->deal.zeny, LOG_TYPE_TRADE, sd); pc_getzeny (sd , tsd->deal.zeny, LOG_TYPE_TRADE, tsd); tsd->deal.zeny = 0; } sd->state.deal_locked = 0; sd->trade_partner = 0; sd->state.trading = 0; tsd->state.deal_locked = 0; tsd->trade_partner = 0; tsd->state.trading = 0; clif_tradecompleted (sd, 0); clif_tradecompleted (tsd, 0); // save both player to avoid crash: they always have no advantage/disadvantage between the 2 players if (save_settings & 1) { chrif_save (sd, 0); chrif_save (tsd, 0); } }