// ギルド倉庫データ削除 int inter_guild_storage_delete(int guild_id) { struct guild_storage *gs = (struct guild_storage*)idb_get(guild_storage_db,guild_id); if(gs) { int i; for(i=0;i<gs->storage_amount;i++){ if(gs->items[i].card[0] == (short)0xff00) inter_pet_delete( MakeDWord(gs->items[i].card[1],gs->items[i].card[2]) ); } idb_remove(guild_storage_db,guild_id); } return 0; }
// 倉庫データ削除 int inter_storage_delete(int account_id) { struct storage_data *s = (struct storage_data*)idb_get(storage_db,account_id); if(s) { int i; for(i=0;i<s->storage_amount;i++){ if(s->items[i].card[0] == (short)0xff00) inter_pet_delete( MakeDWord(s->items[i].card[1],s->items[i].card[2]) ); } idb_remove(storage_db,account_id); } return 0; }
/** * Finalize hatching process and load pet to client. * @param account_id : account ID of owner * @param p : pet requesting * @param flag : 1:stop loading of pet * @return 0:success, 1:failure */ int pet_recv_petdata(int account_id,struct s_pet *p,int flag) { struct map_session_data *sd; sd = map_id2sd(account_id); if(sd == NULL) return 1; if(flag == 1) { sd->status.pet_id = 0; return 1; } if(p->incubate == 1) { int i; //Delete egg from inventory. [Skotlex] for (i = 0; i < MAX_INVENTORY; i++) { if(sd->status.inventory[i].card[0] == CARD0_PET && p->pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2])) break; } if(i >= MAX_INVENTORY) { ShowError("pet_recv_petdata: Hatching pet (%d:%s) aborted, couldn't find egg in inventory for removal!\n",p->pet_id, p->name); sd->status.pet_id = 0; return 1; } if (!pet_birth_process(sd,p)) //Pet hatched. Delete egg. pc_delitem(sd,i,1,0,0,LOG_TYPE_OTHER); } else { pet_data_init(sd,p); if(sd->pd && sd->bl.prev != NULL) { if(map_addblock(&sd->pd->bl)) return 1; clif_spawn(&sd->pd->bl); clif_send_petdata(sd,sd->pd,0,0); clif_send_petdata(sd,sd->pd,5,battle_config.pet_hair_style); clif_pet_equip_area(sd->pd); clif_send_petstatus(sd); } } return 0; }
int pet_select_egg(struct map_session_data *sd,short egg_index) { nullpo_ret(sd); if(egg_index < 0 || egg_index >= MAX_INVENTORY) return 0; //Forged packet! if(sd->status.inventory[egg_index].card[0] == CARD0_PET) intif_request_petdata(sd->status.account_id,sd->status.char_id,MakeDWord(sd->status.inventory[egg_index].card[1],sd->status.inventory[egg_index].card[2])); else ShowError("Wrong egg item inventory %d\n",egg_index); return 0; }
int HPM_pc_equippoint(int ret,struct map_session_data *sd,int *nn) { int char_id = 0, n = *nn; if( !sd ) return 0; if( !ret ) return 0; // If the original function returned zero, we don't need to process it anymore if( reserved_costume_id && sd->status.inventory[n].card[0] == CARD0_CREATE && (char_id = MakeDWord(sd->status.inventory[n].card[2],sd->status.inventory[n].card[3])) == reserved_costume_id ) { // Costume Item - Converted if( ret&EQP_HEAD_TOP ) { ret &= ~EQP_HEAD_TOP; ret |= EQP_COSTUME_HEAD_TOP; } if( ret&EQP_HEAD_LOW ) { ret &= ~EQP_HEAD_LOW; ret |= EQP_COSTUME_HEAD_LOW; } if( ret&EQP_HEAD_MID ) { ret &= ~EQP_HEAD_MID; ret |= EQP_COSTUME_HEAD_MID; } } return ret; }
/*========================================== * Open shop * data := {<index>.w <amount>.w <value>.l}[count] *------------------------------------------*/ void vending_openvending(struct map_session_data* sd, const char* message, bool flag, const uint8* data, int count) { int i, j, char_id; int vending_skill_lvl; nullpo_retv(sd); if( !flag ) // cancelled return; // nothing to do if (pc_istrading(sd)) return; // can't have 2 shops at once vending_skill_lvl = pc_checkskill(sd, MC_VENDING); // skill level and cart check if( !vending_skill_lvl || !pc_iscarton(sd) ) { clif_skill_fail(sd, MC_VENDING, 0, 0); return; } // check number of items in shop if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl ) { // invalid item count clif_skill_fail(sd, MC_VENDING, 0, 0); return; } if((sd->bl.m == map_mapname2mapid("mercadores") && ( ((sd->bl.x != 65) && (sd->bl.x != 74) && (sd->bl.x != 85) && (sd->bl.x != 94) && (sd->bl.x != 34) && (sd->bl.x != 25) && (sd->bl.x != 14) && (sd->bl.x != 5) && (sd->bl.x != 44) && (sd->bl.x != 55)) ))) { clif_displaymessage(sd->fd,"Você não pode abrir lojas no meio da Sala."); return; } // filter out invalid items i = 0; for( j = 0; j < count; j++ ) { short index = *(uint16*)(data + 8*j + 0); short amount = *(uint16*)(data + 8*j + 2); unsigned int value = *(uint32*)(data + 8*j + 4); index -= 2; // offset adjustment (client says that the first cart position is 2) if( index < 0 || index >= MAX_CART // invalid position || pc_cartitem_amount(sd, index, amount) < 0 // invalid item or insufficient quantity //NOTE: official server does not do any of the following checks! || !sd->status.cart[index].identify // unidentified item || sd->status.cart[index].attribute == 1 // broken item || sd->status.cart[index].expire_time // It should not be in the cart but just in case || sd->status.cart[index].bound // Can't Trade Account bound items || ( sd->status.cart[index].card[0] == CARD0_CREATE && (char_id = MakeDWord(sd->status.cart[index].card[2],sd->status.cart[index].card[3])) > 0 && ((battle_config.bg_reserved_char_id && char_id == battle_config.bg_reserved_char_id) || (battle_config.ancient_reserved_char_id && char_id == battle_config.ancient_reserved_char_id)) ) || !itemdb_cantrade(&sd->status.cart[index], pc_isGM(sd), pc_isGM(sd)) ) // untradeable item continue; sd->vending[i].index = index; sd->vending[i].amount = amount; sd->vending[i].value = cap_value(value, 0, (unsigned int)battle_config.vending_max_value); i++; // item successfully added } if( i != j ) clif_displaymessage (sd->fd, msg_txt(266)); //"Some of your items cannot be vended and were removed from the shop." if( i == 0 ) { // no valid item found clif_skill_fail(sd, MC_VENDING, 0, 0); // custom reply packet return; } sd->state.vending = true; sd->vender_id = vending_getuid(); sd->vend_num = i; safestrncpy(sd->message, message, MESSAGE_SIZE); pc_stop_walking(sd,1); clif_openvending(sd,sd->bl.id,sd->vending); clif_showvendingboard(&sd->bl,message,0); if( battle_config.channel_announces&0x10 ) { char chat_message[256]; sprintf(chat_message, msg_txt(820), vending_chat_nick, sd->status.name, sd->message, map[sd->bl.m].name, sd->bl.x, sd->bl.y); clif_channel_message(server_channel[CHN_VENDING], chat_message, 27); } if( map[sd->bl.m].flag.vending_cell ) map_setcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_NOBOARDS, false); }
void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count) { int zeny = 0, char_id; unsigned int i, weight, listidx, k; struct map_session_data* pl_sd; if( count == 0 ) {// nothing to do return; } if( !battle_config.feature_buying_store || pc_istrading(sd) ) {// not allowed to sell clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0); return; } if( !pc_can_give_items(pc_isGM(sd)) ) {// custom: GM is not allowed to sell clif_displaymessage(sd->fd, msg_txt(246)); clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0); return; } if( ( pl_sd = map_id2sd(account_id) ) == NULL || !pl_sd->state.buyingstore || pl_sd->buyer_id != buyer_id ) {// not online, not buying or not same store clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0); return; } if( !searchstore_queryremote(sd, account_id) && ( sd->bl.m != pl_sd->bl.m || !check_distance_bl(&sd->bl, &pl_sd->bl, AREA_SIZE) ) ) {// out of view range clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0); return; } searchstore_clearremote(sd); if( pl_sd->status.zeny < pl_sd->buyingstore.zenylimit ) {// buyer lost zeny in the mean time? fix the limit pl_sd->buyingstore.zenylimit = pl_sd->status.zeny; } weight = pl_sd->weight; // check item list for( i = 0; i < count; i++ ) {// itemlist: <index>.W <name id>.W <amount>.W unsigned short nameid, amount; int index; index = RBUFW(itemlist,i*6+0)-2; nameid = RBUFW(itemlist,i*6+2); amount = RBUFW(itemlist,i*6+4); if( i ) {// duplicate check. as the client does this too, only malicious intent should be caught here ARR_FIND( 0, i, k, RBUFW(itemlist,k*6+0)-2 == index ); if( k != i ) {// duplicate ShowWarning("buyingstore_trade: Found duplicate item on selling list (prevnameid=%hu, prevamount=%hu, nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", RBUFW(itemlist,k*6+2), RBUFW(itemlist,k*6+4), nameid, amount, sd->status.account_id, sd->status.char_id); clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid); return; } } if( index < 0 || index >= ARRAYLENGTH(sd->status.inventory) || sd->inventory_data[index] == NULL || sd->status.inventory[index].nameid != nameid || sd->status.inventory[index].amount < amount ) {// invalid input clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid); return; } if( sd->status.inventory[index].expire_time || sd->status.inventory[index].bound || !itemdb_cantrade(&sd->status.inventory[index], pc_isGM(sd), pc_isGM(pl_sd)) || memcmp(sd->status.inventory[index].card, buyingstore_blankslots, sizeof(buyingstore_blankslots)) ) {// non-tradable item clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid); return; } if( sd->status.inventory[index].card[0] == CARD0_CREATE && (char_id = MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3])) > 0 && (char_id == battle_config.bg_reserved_char_id || char_id == battle_config.ancient_reserved_char_id || char_id == battle_config.woe_reserved_char_id) ) { // Items where creator's ID is important clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid); clif_displaymessage(sd->fd,"Cannot Trade event reserved Items (Battleground, WoE)."); return; } ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid ); if( listidx == pl_sd->buyingstore.slots || pl_sd->buyingstore.items[listidx].amount == 0 ) {// there is no such item or the buyer has already bought all of them clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid); return; } if( pl_sd->buyingstore.items[listidx].amount < amount ) {// buyer does not need that much of the item clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_COUNT, nameid); return; } if( pc_checkadditem(pl_sd, nameid, amount) == ADDITEM_OVERAMOUNT ) {// buyer does not have enough space for this item clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid); return; } if( amount*(unsigned int)sd->inventory_data[index]->weight > pl_sd->max_weight-weight ) {// normally this is not supposed to happen, as the total weight is // checked upon creation, but the buyer could have gained items clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid); return; } weight+= amount*sd->inventory_data[index]->weight; if( amount*pl_sd->buyingstore.items[listidx].price > pl_sd->buyingstore.zenylimit-zeny ) {// buyer does not have enough zeny clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_ZENY, nameid); return; } zeny+= amount*pl_sd->buyingstore.items[listidx].price; } // process item list for( i = 0; i < count; i++ ) {// itemlist: <index>.W <name id>.W <amount>.W unsigned short nameid, amount; int index; index = RBUFW(itemlist,i*6+0)-2; nameid = RBUFW(itemlist,i*6+2); amount = RBUFW(itemlist,i*6+4); ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid ); zeny = amount*pl_sd->buyingstore.items[listidx].price; // log log_zeny(sd, LOG_TYPE_BUYING_STORE, pl_sd, zeny); // move item pc_additem(pl_sd, &sd->status.inventory[index], amount,LOG_TYPE_BUYING_STORE); pc_delitem(sd, index, amount, 1, 0, LOG_TYPE_BUYING_STORE); pl_sd->buyingstore.items[listidx].amount-= amount; // pay up pc_payzeny(pl_sd, zeny); pc_getzeny(sd, zeny); pl_sd->buyingstore.zenylimit-= zeny; // notify clients clif_buyingstore_delete_item(sd, index, amount, pl_sd->buyingstore.items[listidx].price); clif_buyingstore_update_item(pl_sd, nameid, amount); } // check whether or not there is still something to buy ARR_FIND( 0, pl_sd->buyingstore.slots, i, pl_sd->buyingstore.items[i].amount != 0 ); if( i == pl_sd->buyingstore.slots ) {// everything was bought clif_buyingstore_trade_failed_buyer(pl_sd, BUYINGSTORE_TRADE_BUYER_NO_ITEMS); } else if( pl_sd->buyingstore.zenylimit == 0 ) {// zeny limit reached clif_buyingstore_trade_failed_buyer(pl_sd, BUYINGSTORE_TRADE_BUYER_ZENY); } else {// continue buying return; } // cannot continue buying buyingstore_close(pl_sd); // remove auto-trader if( pl_sd->state.autotrade ) { map_quit(pl_sd); } }
int status_calc_mine(struct map_session_data* sd, enum e_status_calc_opt opt) { static int calculating = 0; //Check for recursive call preemption. [Skotlex] struct status_data *bstatus; // pointer to the player's base status const struct status_change *sc = &sd->sc; struct s_skill b_skill[MAX_SKILL]; // previous skill tree int b_weight, b_max_weight, b_cart_weight_max, // previous weight i, k, index, skill_lv,refinedef=0; int64 i64; if (++calculating > 10) //Too many recursive calls! return -1; // remember player-specific values that are currently being shown to the client (for refresh purposes) memcpy(b_skill, &sd->status.skill, sizeof(b_skill)); b_weight = sd->weight; b_max_weight = sd->max_weight; b_cart_weight_max = sd->cart_weight_max; pc->calc_skilltree(sd); // SkillTree calculation sd->max_weight = status->max_weight_base[pc->class2idx(sd->status.class_)]+sd->status.str*300; if(opt&SCO_FIRST) { //Load Hp/SP from char-received data. sd->battle_status.hp = sd->status.hp; sd->battle_status.sp = sd->status.sp; sd->regen.sregen = &sd->sregen; sd->regen.ssregen = &sd->ssregen; sd->weight=0; for(i=0;i<MAX_INVENTORY;i++){ if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL) continue; sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount; } sd->cart_weight=0; sd->cart_num=0; for(i=0;i<MAX_CART;i++){ if(sd->status.cart[i].nameid==0) continue; sd->cart_weight+=itemdb_weight(sd->status.cart[i].nameid)*sd->status.cart[i].amount; sd->cart_num++; } } bstatus = &sd->base_status; // these are not zeroed. [zzo] sd->hprate=100; sd->sprate=100; sd->castrate=100; sd->delayrate=100; sd->dsprate=100; sd->hprecov_rate = 100; sd->sprecov_rate = 100; sd->matk_rate = 100; sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100; sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100; sd->regen.state.block = 0; // zeroed arrays, order follows the order in pc.h. // add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo] memset (sd->param_bonus, 0, sizeof(sd->param_bonus) + sizeof(sd->param_equip) + sizeof(sd->subele) + sizeof(sd->subrace) + sizeof(sd->subrace2) + sizeof(sd->subsize) + sizeof(sd->reseff) + sizeof(sd->weapon_coma_ele) + sizeof(sd->weapon_coma_race) + sizeof(sd->weapon_atk) + sizeof(sd->weapon_atk_rate) + sizeof(sd->arrow_addele) + sizeof(sd->arrow_addrace) + sizeof(sd->arrow_addsize) + sizeof(sd->magic_addele) + sizeof(sd->magic_addrace) + sizeof(sd->magic_addsize) + sizeof(sd->magic_atk_ele) + sizeof(sd->critaddrace) + sizeof(sd->expaddrace) + sizeof(sd->ignore_mdef) + sizeof(sd->ignore_def) + sizeof(sd->sp_gain_race) + sizeof(sd->sp_gain_race_attack) + sizeof(sd->hp_gain_race_attack) ); memset (&sd->right_weapon.overrefine, 0, sizeof(sd->right_weapon) - sizeof(sd->right_weapon.atkmods)); memset (&sd->left_weapon.overrefine, 0, sizeof(sd->left_weapon) - sizeof(sd->left_weapon.atkmods)); if (sd->special_state.intravision && !sd->sc.data[SC_CLAIRVOYANCE]) //Clear intravision as long as nothing else is using it clif->sc_end(&sd->bl,sd->bl.id,SELF,SI_CLAIRVOYANCE); memset(&sd->special_state,0,sizeof(sd->special_state)); if (!sd->state.permanent_speed) { memset(&bstatus->max_hp, 0, sizeof(struct status_data)-(sizeof(bstatus->hp)+sizeof(bstatus->sp))); bstatus->speed = DEFAULT_WALK_SPEED; } else { int pSpeed = bstatus->speed; memset(&bstatus->max_hp, 0, sizeof(struct status_data)-(sizeof(bstatus->hp)+sizeof(bstatus->sp))); bstatus->speed = pSpeed; } //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex] //Give them all modes except these (useful for clones) bstatus->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK); bstatus->size = (sd->class_&JOBL_BABY)?SZ_MEDIUM:SZ_SMALL; if (battle->bc->character_size && (pc_isridingpeco(sd) || pc_isridingdragon(sd)) ) { //[Lupus] if (sd->class_&JOBL_BABY) { if (battle->bc->character_size&SZ_BIG) bstatus->size++; } else if(battle->bc->character_size&SZ_SMALL) bstatus->size++; } bstatus->aspd_rate = 1000; bstatus->ele_lv = 1; bstatus->race = RC_DEMIHUMAN; //zero up structures... memset(&sd->autospell,0,sizeof(sd->autospell) + sizeof(sd->autospell2) + sizeof(sd->autospell3) + sizeof(sd->addeff) + sizeof(sd->addeff2) + sizeof(sd->addeff3) + sizeof(sd->skillatk) + sizeof(sd->skillusesprate) + sizeof(sd->skillusesp) + sizeof(sd->skillheal) + sizeof(sd->skillheal2) + sizeof(sd->hp_loss) + sizeof(sd->sp_loss) + sizeof(sd->hp_regen) + sizeof(sd->sp_regen) + sizeof(sd->skillblown) + sizeof(sd->skillcast) + sizeof(sd->add_def) + sizeof(sd->add_mdef) + sizeof(sd->add_mdmg) + sizeof(sd->add_drop) + sizeof(sd->itemhealrate) + sizeof(sd->subele2) + sizeof(sd->skillcooldown) + sizeof(sd->skillfixcast) + sizeof(sd->skillvarcast) + sizeof(sd->skillfixcastrate) ); memset (&sd->bonus, 0,sizeof(sd->bonus)); // Autobonus pc->delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true); pc->delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus2),true); pc->delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),true); // Parse equipment. for(i=0;i<EQI_MAX;i++) { status->current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to status->current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus] if(index < 0) continue; if(i == EQI_AMMO) continue;/* ammo has special handler down there */ if(i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue; if(i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue; if(i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue; if(i == EQI_COSTUME_MID && sd->equip_index[EQI_COSTUME_LOW] == index) continue; if(i == EQI_COSTUME_TOP && (sd->equip_index[EQI_COSTUME_MID] == index || sd->equip_index[EQI_COSTUME_LOW] == index)) continue; if( (int)MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) == reserved_costume_id ) continue; if(!sd->inventory_data[index]) continue; for(k = 0; k < map->list[sd->bl.m].zone->disabled_items_count; k++) { if( map->list[sd->bl.m].zone->disabled_items[k] == sd->inventory_data[index]->nameid ) { break; } } if( k < map->list[sd->bl.m].zone->disabled_items_count ) continue; bstatus->def += sd->inventory_data[index]->def; if(opt&SCO_FIRST && sd->inventory_data[index]->equip_script) { //Execute equip-script on login script->run(sd->inventory_data[index]->equip_script,0,sd->bl.id,0); if (!calculating) return 1; } // sanitize the refine level in case someone decreased the value inbetween if (sd->status.inventory[index].refine > MAX_REFINE) sd->status.inventory[index].refine = MAX_REFINE; if(sd->inventory_data[index]->type == IT_WEAPON) { int r,wlv = sd->inventory_data[index]->wlv; struct weapon_data *wd; struct weapon_atk *wa; if (wlv >= REFINE_TYPE_MAX) wlv = REFINE_TYPE_MAX - 1; if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) { wd = &sd->left_weapon; // Left-hand weapon wa = &bstatus->lhw; } else { wd = &sd->right_weapon; wa = &bstatus->rhw; } wa->atk += sd->inventory_data[index]->atk; if ( (r = sd->status.inventory[index].refine) ) wa->atk2 = status->refine_info[wlv].bonus[r-1] / 100; #ifdef RENEWAL wa->matk += sd->inventory_data[index]->matk; wa->wlv = wlv; if( r && sd->weapontype1 != W_BOW ) // renewal magic attack refine bonus wa->matk += status->refine_info[wlv].bonus[r-1] / 100; #endif //Overrefine bonus. if (r) wd->overrefine = status->refine_info[wlv].randombonus_max[r-1] / 100; wa->range += sd->inventory_data[index]->range; if(sd->inventory_data[index]->script) { if (wd == &sd->left_weapon) { sd->state.lr_flag = 1; script->run(sd->inventory_data[index]->script,0,sd->bl.id,0); sd->state.lr_flag = 0; } else script->run(sd->inventory_data[index]->script,0,sd->bl.id,0); if (!calculating) //Abort, script->run retriggered this. [Skotlex] return 1; } if(sd->status.inventory[index].card[0]==CARD0_FORGE) { // Forged weapon wd->star += (sd->status.inventory[index].card[1]>>8); if(wd->star >= 15) wd->star = 40; // 3 Star Crumbs now give +40 dmg if(pc->famerank(MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) ,MAPID_BLACKSMITH)) wd->star += 10; if (!wa->ele) //Do not overwrite element from previous bonuses. wa->ele = (sd->status.inventory[index].card[1]&0x0f); } }
/*========================================== * Adds an item/qty to the trade window *------------------------------------------*/ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) { struct map_session_data *target_sd; struct item *item; struct homun_data *hd; char atcmd_output[CHAT_SIZE_MAX]; int trade_i, trade_weight; int src_lv, dst_lv; int i, p, tid, amttsd = 0, amtt = 0; hd = sd->hd; nullpo_retv(sd); if( !sd->state.trading || sd->state.deal_locked > 0 ) return; //Can't add stuff. if( (target_sd = map_id2sd(sd->trade_partner)) == NULL ) { trade_tradecancel(sd); return; } if( amount == 0 ) { //Why do this.. ~.~ just send an ack, the item won't display on the trade window. clif_tradeitemok(sd, index, 0); return; } index -= 2; // 0 is for zeny, 1 is unknown. Gravity, go figure... //Item checks... if( index < 0 || index >= MAX_INVENTORY ) return; if( amount < 0 || amount > sd->status.inventory[index].amount ) return; item = &sd->status.inventory[index]; src_lv = pc_isGM(sd); dst_lv = pc_isGM(target_sd); if( !itemdb_cantrade(item, src_lv, dst_lv) && //Can't trade (pc_get_partner(sd) != target_sd || !itemdb_canpartnertrade(item, src_lv, dst_lv)) ) //Can't partner-trade { clif_displaymessage (sd->fd, msg_txt(260)); clif_tradeitemok(sd, index+2, 1); return; } if( item->expire_time ) { // Rental System clif_displaymessage (sd->fd, msg_txt(260)); clif_tradeitemok(sd, index+2, 1); return; } //Locate a trade position ARR_FIND( 0, 10, trade_i, sd->deal.item[trade_i].index == index || sd->deal.item[trade_i].amount == 0 ); if( trade_i == 10 ) //No space left { clif_tradeitemok(sd, index+2, 1); return; } //-------------| Bloquear Donates dias de semana |-------------// by: [Brunno Thadeu] //Abaixo, defini-se os dias (Falta testar isso, creio eu que 1 seja domingo, 2 segunda etc..) // if(t->tm_wday != 1 && t->tm_wday != 7){ //Abaixo, defini-se o range de ID's dos Donates. // if(sd->status.inventory[index].nameid >= 5000 && sd->status.inventory[index].nameid <= 5500) { // clif_tradeitemok(sd, index+2, 1); // return; // } // } //--------------------------------------------------------------// if(sd->status.inventory[index].nameid == 690) return ; if(sd->status.inventory[index].nameid >= 8031 && sd->status.inventory[index].nameid <= 8181) { for(i = 8031; i <= 8181; i++) amttsd += pc_countitem(target_sd, i); for(i = 0; i < 10; i++) { tid = sd->status.inventory[sd->deal.item[i].index].nameid; if(tid >= 8031 && tid <= 8181) amtt += sd->deal.item[i].amount; } p = 6; if((hd = target_sd->hd) == NULL ){ p = 7; } if((amttsd + amount + amtt) >= p) { clif_tradeitemok(sd, index+2, 1); return; } } if(sd->status.inventory[index].nameid >= 8031 && sd->status.inventory[index].nameid <= 8181){ snprintf(atcmd_output, sizeof(atcmd_output) ,"Pokemon ID: %d ", MakeDWord(sd->status.inventory[index].card[1], sd->status.inventory[index].card[2])); clif_displaymessage(target_sd->fd, atcmd_output); } trade_weight = sd->inventory_data[index]->weight * amount; if( target_sd->weight + sd->deal.weight + trade_weight > target_sd->max_weight ) { //fail to add item -- the player was over weighted. clif_tradeitemok(sd, index+2, 1); return; } if( sd->deal.item[trade_i].index == index ) { //The same item as before is being readjusted. if( sd->deal.item[trade_i].amount + amount > sd->status.inventory[index].amount ) { //packet deal exploit check amount = sd->status.inventory[index].amount - sd->deal.item[trade_i].amount; trade_weight = sd->inventory_data[index]->weight * amount; } sd->deal.item[trade_i].amount += amount; } else { //New deal item sd->deal.item[trade_i].index = index; sd->deal.item[trade_i].amount = amount; } sd->deal.weight += trade_weight; clif_tradeitemok(sd, index+2, 0); // Return the index as it was received clif_tradeadditem(sd, target_sd, index+2, amount); }