Index: db/packet_db.txt =================================================================== --- db/packet_db.txt (revision 527) +++ db/packet_db.txt (working copy) @@ -2154,6 +2154,7 @@ 0x023B,26,friendslistadd,2 0x0361,5,hommenu,2:4 0x0880,36,storagepassword,2:4:20 +0x097c,2,alchemist,0 //2013-07-17 Ragexe packet_ver: 44 Index: src/map/pc.c =================================================================== --- src/map/pc.c (revision 527) +++ src/map/pc.c (working copy) @@ -3901,11 +3901,41 @@ *------------------------------------------*/ int pc_search_inventory(struct map_session_data *sd,int item_id) { - int i; + int i, char_id; nullpo_retr(-1, sd); - ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == item_id && (sd->status.inventory[i].amount > 0 || item_id == 0) ); - return ( i < MAX_INVENTORY ) ? i : -1; + if (item_id) + { + if (map_bg_items(sd->bl.m) && battle_config.bg_reserved_char_id) // Battleground Items + { + ARR_FIND(0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == item_id && sd->status.inventory[i].amount > 0 && sd->status.inventory[i].card[0] == CARD0_CREATE && MakeDWord(sd->status.inventory[i].card[2], sd->status.inventory[i].card[3]) == battle_config.bg_reserved_char_id); + if (i < MAX_INVENTORY) return i; + } + else if (map_gvg_items(sd->bl.m) && battle_config.woe_reserved_char_id) // WoE Items + { + ARR_FIND(0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == item_id && sd->status.inventory[i].amount > 0 && sd->status.inventory[i].card[0] == CARD0_CREATE && MakeDWord(sd->status.inventory[i].card[2], sd->status.inventory[i].card[3]) == battle_config.woe_reserved_char_id); + if (i < MAX_INVENTORY) return i; + } + } + + for (i = 0; i < MAX_INVENTORY; i++) + { + if (sd->status.inventory[i].nameid != item_id) + continue; + if (item_id && sd->status.inventory[i].amount < 1) + continue; + if (item_id && sd->status.inventory[i].card[0] == CARD0_CREATE && (char_id = MakeDWord(sd->status.inventory[i].card[2], sd->status.inventory[i].card[3])) > 0) + { + if (!map_bg_items(sd->bl.m) && battle_config.bg_reserved_char_id && battle_config.bg_reserved_char_id == char_id) + continue; + if (!map_gvg_items(sd->bl.m) && battle_config.woe_reserved_char_id && battle_config.woe_reserved_char_id == char_id) + continue; + } + + return i; + } + + return -1; } /*========================================== @@ -4325,11 +4355,13 @@ * 0 = fail * 1 = success *------------------------------------------*/ -int pc_useitem(struct map_session_data *sd,int n) +int pc_useitem(struct map_session_data *sd, int n) { unsigned int tick = gettick(); - int amount, nameid; + int amount, nameid, char_id = 0; struct script_code *script; + struct item item; + struct item_data *id; nullpo_ret(sd); @@ -4340,17 +4372,34 @@ return 0; } - if( sd->status.inventory[n].nameid <= 0 || sd->status.inventory[n].amount <= 0 ) + item = sd->status.inventory[n]; + id = sd->inventory_data[n]; + if (item.nameid <= 0 || item.amount <= 0) return 0; - - if( sd->state.only_walk ) + + if (sd->state.only_walk) return 0; if( !pc_isUseitem(sd,n) ) return 0; + if (item.card[0] == CARD0_CREATE) // Do not allow use BG - Ancient Items on invalid maps + { + char_id = MakeDWord(item.card[2], item.card[3]); + if (battle_config.bg_reserved_char_id && char_id == battle_config.bg_reserved_char_id && !map_bg_items(sd->bl.m)) + return 0; + if (battle_config.woe_reserved_char_id && char_id == battle_config.woe_reserved_char_id && !map_gvg_items(sd->bl.m)) + return 0; + if (pc_famerank(char_id, MAPID_ALCHEMIST)){ + potion_flag = 2; // Famous player's potions have 50% more efficiency + if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ROGUE) + potion_flag = 3; //Even more effective potions. + } + } + + // Store information for later use before it is lost (via pc_delitem) [Paradox924X] - nameid = sd->inventory_data[n]->nameid; + nameid = id->nameid; if (nameid != ITEMID_NAUTHIZ && sd->sc.opt1 > 0 && sd->sc.opt1 != OPT1_STONEWAIT && sd->sc.opt1 != OPT1_BURNING) return 0; @@ -4374,8 +4423,8 @@ return 0; /* Items with delayed consume are not meant to work while in mounts except reins of mount(12622) */ - if( sd->inventory_data[n]->flag.delay_consume && nameid != ITEMID_REINS_OF_MOUNT ) { - if( sd->sc.option&OPTION_MOUNTING ) + if( id->flag.delay_consume ) { + if( nameid != ITEMID_REINS_OF_MOUNT && sd->sc.option&OPTION_MOUNTING ) return 0; else if( pc_issit(sd) ) return 0; @@ -4384,10 +4433,10 @@ //perform a skill-use check before going through. [Skotlex] //resurrection was picked as testing skill, as a non-offensive, generic skill, it will do. //FIXME: Is this really needed here? It'll be checked in unit.c after all and this prevents skill items using when silenced [Inkfish] - if( sd->inventory_data[n]->flag.delay_consume && ( sd->ud.skilltimer != INVALID_TIMER /*|| !status_check_skilluse(&sd->bl, &sd->bl, ALL_RESURRECTION, 0)*/ ) ) + if( id->flag.delay_consume && ( sd->ud.skilltimer != INVALID_TIMER /*|| !status_check_skilluse(&sd->bl, &sd->bl, ALL_RESURRECTION, 0)*/ ) ) return 0; - if( sd->inventory_data[n]->delay > 0 ) { + if( id->delay > 0 ) { int i; ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid ); if( i == MAX_ITEMDELAYS ) /* item not found. try first empty now */ @@ -4399,11 +4448,11 @@ char e_msg[100]; if( e_tick > 99 ) sprintf(e_msg,msg_txt(sd,379), //Item Failed. [%s] is cooling down. Wait %.1f minutes. - itemdb_jname(sd->status.inventory[n].nameid), + itemdb_jname(item.nameid), (double)e_tick / 60); else sprintf(e_msg,msg_txt(sd,380), //Item Failed. [%s] is cooling down. Wait %d seconds. - itemdb_jname(sd->status.inventory[n].nameid), + itemdb_jname(item.nameid), e_tick+1); clif_colormes(sd,color_table[COLOR_RED],e_msg); return 0; // Delay has not expired yet @@ -4427,38 +4476,41 @@ /* on restricted maps the item is consumed but the effect is not used */ if ( - (!map_flag_vs(sd->bl.m) && sd->inventory_data[n]->flag.no_equip&1) || // Normal - (map[sd->bl.m].flag.pvp && sd->inventory_data[n]->flag.no_equip&2) || // PVP - (map_flag_gvg(sd->bl.m) && sd->inventory_data[n]->flag.no_equip&4) || // GVG - (map[sd->bl.m].flag.battleground && sd->inventory_data[n]->flag.no_equip&8) || // Battleground - (map[sd->bl.m].flag.restricted && sd->inventory_data[n]->flag.no_equip&(8*map[sd->bl.m].zone)) // Zone restriction + (!map_flag_vs(sd->bl.m) && id->flag.no_equip&1) || // Normal + (map[sd->bl.m].flag.pvp && id->flag.no_equip&2) || // PVP + (map_flag_gvg(sd->bl.m) && id->flag.no_equip&4) || // GVG + (map[sd->bl.m].flag.battleground && id->flag.no_equip&8) || // Battleground + (map[sd->bl.m].flag.restricted && id->flag.no_equip&(8*map[sd->bl.m].zone)) // Zone restriction ) { if( battle_config.item_restricted_consumption_type ) { - clif_useitemack(sd,n,sd->status.inventory[n].amount-1,true); + clif_useitemack(sd,n,item.amount-1,true); pc_delitem(sd,n,1,1,0,LOG_TYPE_CONSUME); } return 0;/* regardless, effect is not run */ } - sd->itemid = sd->status.inventory[n].nameid; + sd->itemid = item.nameid; sd->itemindex = n; if(sd->catch_target_class != -1) //Abort pet catching. sd->catch_target_class = -1; - amount = sd->status.inventory[n].amount; - script = sd->inventory_data[n]->script; + amount = item.amount; + script = id->script; //Check if the item is to be consumed immediately [Skotlex] - if( sd->inventory_data[n]->flag.delay_consume ) - clif_useitemack(sd,n,amount,true); - else { - if( sd->status.inventory[n].expire_time == 0 ) { - clif_useitemack(sd,n,amount-1,true); - pc_delitem(sd,n,1,1,0,LOG_TYPE_CONSUME); // Rental Usable Items are not deleted until expiration - } else - clif_useitemack(sd,n,0,false); + if (id->flag.delay_consume) + clif_useitemack(sd, n, amount, true); + else + { + if (item.expire_time == 0) + { + clif_useitemack(sd, n, amount - 1, true); + pc_delitem(sd, n, 1, 1, 0, LOG_TYPE_CONSUME); // Rental Usable Items are not deleted until expiration + } + else + clif_useitemack(sd, n, 0, false); } - if(sd->status.inventory[n].card[0]==CARD0_CREATE && - pc_famerank(MakeDWord(sd->status.inventory[n].card[2],sd->status.inventory[n].card[3]), MAPID_ALCHEMIST)) + if(item.card[0]==CARD0_CREATE && + pc_famerank(MakeDWord(item.card[2],item.card[3]), MAPID_ALCHEMIST)) { potion_flag = 2; // Famous player's potions have 50% more efficiency if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ROGUE) Index: src/map/script.c =================================================================== --- src/map/script.c (revision 527) +++ src/map/script.c (working copy) @@ -404,13 +404,14 @@ MF_PVP_NOCALCRANK, //50 MF_BATTLEGROUND, MF_RESET, - MF_ALLOW_BG_ITEMS, MF_CHANNELAUTOJOIN, MF_NOUSECART, MF_NOITEMCONSUMPTION, MF_SUMSTARTMIRACLE, MF_NOMINEEFFECT, MF_NOLOCKON, + MF_ALLOWWOEIT, + MF_ALLOWBGIT, MF_NOTOMB }; @@ -6109,9 +6110,19 @@ if(script_lastdata(st) == 2) { // For countitem() function int nameid = id->nameid; - for(i = 0; i < MAX_INVENTORY; i++) - if(sd->status.inventory[i].nameid == nameid) - count += sd->status.inventory[i].amount; + + for (i = 0; i < MAX_INVENTORY; i++) { + if (sd->status.inventory[i].nameid != nameid) + continue; + if (sd->status.inventory[i].card[0] == CARD0_CREATE) { + int char_id = MakeDWord(sd->status.inventory[i].card[2], sd->status.inventory[i].card[3]); + if (battle_config.bg_reserved_char_id && char_id == battle_config.bg_reserved_char_id && !map_bg_items(sd->bl.m)) + continue; + if (battle_config.woe_reserved_char_id && char_id == battle_config.woe_reserved_char_id && !map_gvg_items(sd->bl.m)) + continue; + } + count += sd->status.inventory[i].amount; + } } else { // For countitem2() function int nameid, iden, ref, attr, c1, c2, c3, c4; @@ -6813,11 +6824,15 @@ continue; } - if( exact_match ) - { - if( inv->refine != it->refine || inv->identify != it->identify || inv->attribute != it->attribute || memcmp(inv->card, it->card, sizeof(inv->card)) ) - {// not matching attributes + if (exact_match) { + if (inv->refine != it->refine || inv->identify != it->identify || inv->attribute != it->attribute || memcmp(inv->card, it->card, sizeof (inv->card))) {// not matching attributes continue; + } else if (inv->card[0] == CARD0_CREATE) { + int char_id = MakeDWord(inv->card[2], inv->card[3]); + if (battle_config.bg_reserved_char_id && char_id == battle_config.bg_reserved_char_id && !map_bg_items(sd->bl.m)) + continue; + if (battle_config.woe_reserved_char_id && char_id == battle_config.woe_reserved_char_id && !map_gvg_items(sd->bl.m)) + continue; } } @@ -7805,8 +7820,10 @@ if (num > 0 && num <= ARRAYLENGTH(equip)) i=pc_checkequip(sd,equip[num-1]); if(i >= 0) { + int ret; pc_unequipitem(sd,i,3); //recalculate bonus - pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + ret=pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + script_pushint(st,ret==0); } return 0; @@ -10673,13 +10690,17 @@ BUILDIN_FUNC(getmapflag) { - int16 m,i; + int16 m,i,inst_id; const char *str; str=script_getstr(st,2); i=script_getnum(st,3); + m = map_mapname2mapid(str); + if(script_hasdata(st,4)){ + inst_id = script_getnum(st,4); //[Lighta] + m = instance_map2imap(m, inst_id); + } - m = map_mapname2mapid(str); if(m >= 0) { switch(i) { case MF_NOMEMO: script_pushint(st,map[m].flag.nomemo); break; @@ -10733,13 +10754,14 @@ case MF_PVP_NOCALCRANK: script_pushint(st,map[m].flag.pvp_nocalcrank); break; case MF_BATTLEGROUND: script_pushint(st,map[m].flag.battleground); break; case MF_RESET: script_pushint(st,map[m].flag.reset); break; - case MF_ALLOW_BG_ITEMS: script_pushint(st,map[m].flag.allow_bg_items); break; case MF_CHANNELAUTOJOIN: script_pushint(st,map[m].flag.chmautojoin); break; case MF_NOUSECART: script_pushint(st,map[m].flag.nousecart); break; case MF_NOITEMCONSUMPTION: script_pushint(st,map[m].flag.noitemconsumption); break; case MF_SUMSTARTMIRACLE: script_pushint(st,map[m].flag.nosumstarmiracle); break; case MF_NOMINEEFFECT: script_pushint(st,map[m].flag.nomineeffect); break; case MF_NOLOCKON: script_pushint(st,map[m].flag.nolockon); break; + case MF_ALLOWWOEIT: script_pushint(st,map[m].flag.allow_woe_items); break; + case MF_ALLOWBGIT: script_pushint(st,map[m].flag.allow_bg_items); break; case MF_NOTOMB: script_pushint(st,map[m].flag.notomb); break; } } @@ -10763,7 +10785,7 @@ } BUILDIN_FUNC(setmapflag) { - int16 m,i; + int16 m,i, inst_id; const char *str; int val=0; @@ -10772,7 +10794,18 @@ if(script_hasdata(st,4)){ val=script_getnum(st,4); } - m = map_mapname2mapid(str); + + if (strcmp(str, "this") == 0) { + struct block_list *bl = map_id2bl(st->oid); + m = bl ? bl->m : -1; + } else + m = map_mapname2mapid(str); + + if(script_hasdata(st,5)){ + inst_id = script_getnum(st,5); //[Lighta] + m = instance_map2imap(m, inst_id); + } + if(m >= 0) { switch(i) { case MF_NOMEMO: map[m].flag.nomemo = 1; break; @@ -10842,13 +10875,14 @@ case MF_PVP_NOCALCRANK: map[m].flag.pvp_nocalcrank = 1; break; case MF_BATTLEGROUND: map[m].flag.battleground = (val <= 0 || val > 2) ? 1 : val; break; case MF_RESET: map[m].flag.reset = 1; break; - case MF_ALLOW_BG_ITEMS: map[m].flag.allow_bg_items = 1; break; case MF_CHANNELAUTOJOIN: map[m].flag.chmautojoin = 1 ; break; case MF_NOUSECART: map[m].flag.nousecart = 1 ; break; case MF_NOITEMCONSUMPTION: map[m].flag.noitemconsumption = 1 ; break; case MF_SUMSTARTMIRACLE: map[m].flag.nosumstarmiracle = 1 ; break; case MF_NOMINEEFFECT: map[m].flag.nomineeffect = 1 ; break; case MF_NOLOCKON: map[m].flag.nolockon = 1 ; break; + case MF_ALLOWWOEIT: map[m].flag.allow_woe_items = 1; break; + case MF_ALLOWBGIT: map[m].flag.allow_bg_items = 1; break; case MF_NOTOMB: map[m].flag.notomb = 1; break; } } @@ -10867,7 +10901,17 @@ if(script_hasdata(st,4)){ val=script_getnum(st,4); } - m = map_mapname2mapid(str); + if (strcmp(str, "this") == 0) { + struct block_list *bl = map_id2bl(st->oid); + m = bl ? bl->m : -1; + } else + m = map_mapname2mapid(str); + + if(script_hasdata(st,5)){ + int inst_id = script_getnum(st,5); //[Lighta] + m = instance_map2imap(m, inst_id); + } + if(m >= 0) { switch(i) { case MF_NOMEMO: map[m].flag.nomemo = 0; break; @@ -10948,6 +10992,8 @@ case MF_SUMSTARTMIRACLE: map[m].flag.nosumstarmiracle = 0 ; break; case MF_NOMINEEFFECT: map[m].flag.nomineeffect = 0 ; break; case MF_NOLOCKON: map[m].flag.nolockon = 0 ; break; + case MF_ALLOWWOEIT: map[m].flag.allow_woe_items = 0; break; + case MF_ALLOWBGIT: map[m].flag.allow_bg_items = 0; break; case MF_NOTOMB: map[m].flag.notomb = 0; break; } } @@ -11798,11 +11844,16 @@ *------------------------------------------*/ BUILDIN_FUNC(setwall) { - const char *map, *name; - int x, y, m, size, dir; + const char *wmap, *name; + char uname[MAP_NAME_LENGTH]; + int x, y, m=0, size, dir; bool shootable; + int inst_id=0, im=0; - map = script_getstr(st,2); + wmap = script_getstr(st,2);//[Khalint] + if( (m = map_mapname2mapid(wmap)) < 0 )//[Khalint] + return 0; // Invalid Map + x = script_getnum(st,3); y = script_getnum(st,4); size = script_getnum(st,5); @@ -11810,15 +11861,36 @@ shootable = script_getnum(st,7); name = script_getstr(st,8); - if( (m = map_mapname2mapid(map)) < 0 ) - return 0; // Invalid Map + if(script_hasdata(st,9) ){ + inst_id = script_getnum(st,9); //[Lighta] + // Request the mapid of this src map into the instance of the party + im = instance_map2imap(m, inst_id); + if( im >= 0 ) + { // Changes destiny to the instance map, not the source map + snprintf(uname, sizeof(uname), "%s%d",name,inst_id); //auto unique name for instance + m = im; + name = uname; + } + } map_iwall_set(m, x, y, size, dir, shootable, name); return 0; } + BUILDIN_FUNC(delwall) { - const char *name = script_getstr(st,2); + int inst_id=0; + const char *name = NULL; + char uname[MAP_NAME_LENGTH]; + + name =script_getstr(st,2); + if( script_hasdata(st,3) ) + {// "instance_id + inst_id=script_getnum(st,3); + snprintf(uname, sizeof(uname), "%s%d",name,inst_id); //auto unique name for instance + name = uname; + } + map_iwall_remove(name); return 0; @@ -19256,8 +19328,8 @@ BUILDIN_DEF(detachrid,""), BUILDIN_DEF(isloggedin,"i?"), BUILDIN_DEF(setmapflagnosave,"ssii"), - BUILDIN_DEF(getmapflag,"si"), - BUILDIN_DEF(setmapflag,"si?"), + BUILDIN_DEF(getmapflag,"si?"), + BUILDIN_DEF(setmapflag,"si??"), BUILDIN_DEF(removemapflag,"si?"), BUILDIN_DEF(pvpon,"s"), BUILDIN_DEF(pvpoff,"s"), @@ -19456,8 +19528,8 @@ BUILDIN_DEF(setcell,"siiiiii"), BUILDIN_DEF(flooritem,"ii"), BUILDIN_DEF(flooritem2xy,"siiii"), - BUILDIN_DEF(setwall,"siiiiis"), - BUILDIN_DEF(delwall,"s"), + BUILDIN_DEF(setwall,"siiiiis?"), + BUILDIN_DEF(delwall,"s?"), BUILDIN_DEF(searchitem,"rs"), BUILDIN_DEF(mercenary_create,"ii"), BUILDIN_DEF(mercenary_heal,"ii"), Index: src/map/battle.c =================================================================== --- src/map/battle.c (revision 527) +++ src/map/battle.c (working copy) @@ -810,7 +810,6 @@ if( sc->data[SC_SAFETYWALL] && ((flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT || (skill_get_inf2(skill_id)&INF2_TRAP)) ) { - { struct skill_unit_group* group = skill_id2group(sc->data[SC_SAFETYWALL]->val3); //uint16 skill_id = sc->data[SC_SAFETYWALL]->val2; (safetywall or steinwand) if (group) { @@ -926,7 +925,6 @@ if (((sce=sc->data[SC_UTSUSEMI]) || sc->data[SC_BUNSINJYUTSU]) && flag&BF_WEAPON && !(skill_get_nk(skill_id)&NK_NO_CARDFIX_ATK)) { - skill_additional_effect (src, bl, skill_id, skill_lv, flag, ATK_BLOCK, gettick() ); if( !status_isdead(src) ) skill_counter_additional_effect( src, bl, skill_id, skill_lv, flag, gettick() ); @@ -1166,9 +1164,8 @@ } } } + } //end target sc - } - //SC effects from caster side. sc = status_get_sc(src); @@ -1268,8 +1265,6 @@ } } - } - return damage; } @@ -6988,6 +6983,8 @@ { "item_enabled_npc", &battle_config.item_enabled_npc, 1, 0, 1, }, { "item_flooritem_check", &battle_config.item_onfloor, 1, 0, 1, }, { "bowling_bash_area", &battle_config.bowling_bash_area, 0, 0, 20, }, + { "woe_reserved_char_id", &battle_config.woe_reserved_char_id, 999999, 0, INT_MAX,}, + { "bg_reserved_char_id", &battle_config.bg_reserved_char_id, 999998, 0, INT_MAX,}, }; #ifndef STATS_OPT_OUT /** Index: src/map/skill.c =================================================================== --- src/map/skill.c (revision 527) +++ src/map/skill.c (working copy) @@ -6441,14 +6441,15 @@ } if( sd ) { int x,bonus=100; + struct skill_condition require = skill_get_requirement(sd, skill_id, skill_lv); x = skill_lv%11 - 1; - i = pc_search_inventory(sd,skill_db[skill_id].itemid[x]); - if( i < 0 || skill_db[skill_id].itemid[x] <= 0 ) { + i = pc_search_inventory(sd, require.itemid[x]); + if (i < 0 || require.itemid[x] <= 0) { clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map_freeblock_unlock(); return 1; } - if(sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < skill_db[skill_id].amount[x]) { + if (sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < require.amount[x]) { clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map_freeblock_unlock(); return 1; @@ -6750,6 +6751,7 @@ sp = sp * tsc->data[SC_MAGICROD]->val2 / 100; if(sp < 1) sp = 1; status_heal(bl,0,sp,2); + clif_skill_nodamage(bl, bl, SA_MAGICROD, tsc->data[SC_MAGICROD]->val1, 1); status_percent_damage(bl, src, 0, -20, false); //20% max SP damage. } else { struct unit_data *ud = unit_bl2ud(bl); @@ -6787,7 +6789,7 @@ } break; case SA_MAGICROD: - clif_skill_nodamage(src,src,SA_MAGICROD,skill_lv,1); + //It activates silently, no use animation. [Lighta] sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)); break; case SA_AUTOSPELL: @@ -10254,9 +10256,11 @@ // Slim Pitcher [Celest] case CR_SLIMPITCHER: if (sd) { - int i = skill_lv%11 - 1; - int j = pc_search_inventory(sd,skill_db[skill_id].itemid[i]); - if( j < 0 || skill_db[skill_id].itemid[i] <= 0 || sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < skill_db[skill_id].amount[i] ) + int i = 0, j = 0; + struct skill_condition require = skill_get_requirement(sd, skill_id, skill_lv); + i = skill_lv%11 - 1; + j = pc_search_inventory(sd, require.itemid[i]); + if (j < 0 || require.itemid[i] <= 0 || sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < require.amount[i]) { clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 1; Index: src/map/battle.h =================================================================== --- src/map/battle.h (revision 527) +++ src/map/battle.h (working copy) @@ -476,7 +476,6 @@ // Aelys custom Battleground int bg_idle_announce; int bg_idle_autokick; - int bg_reserved_char_id; int bg_items_on_pvp; int bg_reward_rates; int bg_reportafk_leaderonly; @@ -504,6 +503,8 @@ int item_enabled_npc; int item_onfloor; // Whether to drop an undroppable item on the map or destroy it if inventory is full. int bowling_bash_area; + int bg_reserved_char_id; //charid for bg items + int woe_reserved_char_id; //charid for wot items } battle_config; void do_init_battle(void); Index: src/map/vending.c =================================================================== --- src/map/vending.c (revision 527) +++ src/map/vending.c (working copy) @@ -231,7 +231,7 @@ * data := {.w .w .l}[count] *------------------------------------------*/ void vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) { - int i, j; + int i, j, char_id; int vending_skill_lvl; nullpo_retv(sd); @@ -268,6 +268,7 @@ || 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 && !pc_can_give_bounded_items(sd)) // can't trade account bound items and has no permission + || (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))) || !itemdb_cantrade(&sd->status.cart[index], pc_get_group_level(sd), pc_get_group_level(sd)) ) // untradeable item continue; Index: src/map/buyingstore.c =================================================================== --- src/map/buyingstore.c (revision 527) +++ src/map/buyingstore.c (working copy) @@ -241,7 +241,7 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count) { - int zeny = 0; + int zeny = 0, char_id; unsigned int i, weight, listidx, k; struct map_session_data* pl_sd; @@ -316,6 +316,11 @@ 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.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 ) Index: src/map/clif.c =================================================================== --- src/map/clif.c (revision 527) +++ src/map/clif.c (working copy) @@ -55,8 +55,8 @@ /* for clif_clearunit_delayed */ static struct eri *delay_clearunit_ers; -//#define DUMP_UNKNOWN_PACKET -//#define DUMP_INVALID_PACKET +#define DUMP_UNKNOWN_PACKET +#define DUMP_INVALID_PACKET struct Clif_Config { int packet_db_ver; //Preferred packet version. @@ -1801,9 +1801,15 @@ if( !itemdb_cansell(&sd->status.inventory[i], pc_get_group_level(sd)) ) continue; - if( sd->status.inventory[i].expire_time || (sd->status.inventory[i].bound && !pc_can_give_bounded_items(sd)) ) - continue; // Cannot Sell Rental Items or Account Bounded Items - + if( sd->status.inventory[i].expire_time ) + continue; // Cannot Sell Rental Items + if (sd->status.inventory[i].card[0] == CARD0_CREATE) { // Do not allow sell BG - Ancient Items + uint32 char_id = MakeDWord(sd->status.inventory[i].card[2], sd->status.inventory[i].card[3]); + if (battle_config.bg_reserved_char_id && char_id == battle_config.bg_reserved_char_id) + continue; + if (battle_config.woe_reserved_char_id && char_id == battle_config.woe_reserved_char_id) + continue; + } if( sd->status.inventory[i].bound && !pc_can_give_bounded_items(sd)) continue; // Don't allow sale of bound items