Fixed potentially dangerous map_addflooritem calls and related behaviors (#8360)
*Removed potentially dangerous map_additemfloor calls *Added weight/inventory checks for marry atcommand *Fixed overweight message for box items *Fixed inventory space check for box items to match official requirement (the total number of the items the box will give you *r min 10, plus 1) *Fixed inventory space message for box items *Fixed pet egg creation not deleting the pet data when failed to add it to the inventory *Fixed pet egg creation dropping the egg on the floor when failed to add it to the inventory *Fixed pet equipment dropping on the floor when failed to retrieve the item *Added a battle configuration to prevent removing the pet equipment (and disappear into nothingness) when failed to retrieve the item *Added missing skill_drop_items_full checks on several skills (official behavior makes the items disappear) --------- Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
parent
9267c2bf8a
commit
6ca99e7852
@ -93,7 +93,7 @@ allow_equip_restricted_item: yes
|
||||
// Default on official servers: yes for Pre-renewal, no for Renewal
|
||||
//item_enabled_npc: yes
|
||||
|
||||
// Allow map_flooritem to check if item is droppable? (Note 1)
|
||||
// Allow map_addflooritem to check if item is droppable? (Note 1)
|
||||
// If yes, undroppable items will be destroyed instead of appearing on the map when a player's inventory is full.
|
||||
// Default: yes
|
||||
item_flooritem_check: yes
|
||||
|
@ -41,6 +41,10 @@ pet_hungry_delay_rate: 100
|
||||
// These bonuses are unofficial and found in the import/pet_db.yml
|
||||
pet_equip_required: yes
|
||||
|
||||
// Should the pet equipment be destroyed if the owner doesn't have enough space in their inventory? (Note 1)
|
||||
// Official behavior is "yes", setting this to "no" will leave the item equipped.
|
||||
pet_unequip_destroy: yes
|
||||
|
||||
// When the master attacks a monster, whether or not the pet will also attack. (Note 1)
|
||||
pet_attack_support: no
|
||||
|
||||
|
@ -775,7 +775,7 @@
|
||||
730: Character cannot be disguised while in monster form.
|
||||
731: Transforming into monster is not allowed in Guild Wars.
|
||||
|
||||
732: Item cannot be opened when your inventory is full.
|
||||
//732: Free
|
||||
|
||||
733: Please enter a NPC file name (usage: @reloadnpcfile <file name>).
|
||||
|
||||
|
@ -765,7 +765,7 @@
|
||||
730: Karakter tidak dapat disguise ketika sedang berwujud monster.
|
||||
731: Perubahan menjadi monster tidak diizinkan dalam Guild Wars.
|
||||
|
||||
732: Item tidak dapat dibuka ketika inventory penuh.
|
||||
//732: Free
|
||||
|
||||
//733 free
|
||||
|
||||
|
@ -779,7 +779,7 @@
|
||||
730: O personagem não pode ser disfarçado enquanto estiver em forma de monstro.
|
||||
731: Transformar em monstro não é permitido em GvG.
|
||||
|
||||
732: O item não pode ser aberto quando o seu inventário está cheio.
|
||||
//732: Free
|
||||
|
||||
733: Por favor insira um nome de arquivo NPC (uso: @reloadnpcfile <nome do arquivo>).
|
||||
|
||||
|
@ -775,7 +775,7 @@
|
||||
730: El personaje no puede disfrazarse si está transformado en un monstruo.
|
||||
731: No puedes transformarte en monstruo durante la guerra de clanes.
|
||||
|
||||
732: No puedes abrir el objeto porque tu inventario está lleno.
|
||||
//732: libre
|
||||
|
||||
733: Introduce la ruta de archivo de un NPC (instrucciones: @reloadnpcfile <ruta>).
|
||||
|
||||
|
@ -6394,7 +6394,6 @@ void getring (map_session_data* sd)
|
||||
|
||||
if((flag = pc_additem(sd,&item_tmp,1,LOG_TYPE_COMMAND))) {
|
||||
clif_additem(sd,0,0,flag);
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6420,6 +6419,28 @@ ACMD_FUNC(marry)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!pc_inventoryblank(sd)) {
|
||||
clif_msg_color(sd, MSI_CANT_GET_ITEM_BECAUSE_COUNT, color_table[COLOR_RED]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!pc_inventoryblank(pl_sd)) {
|
||||
clif_msg_color(pl_sd, MSI_CANT_GET_ITEM_BECAUSE_COUNT, color_table[COLOR_RED]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32 w = 0;
|
||||
|
||||
if (w = itemdb_weight((sd->status.sex) ? WEDDING_RING_M : WEDDING_RING_F) && w + sd->weight > sd->max_weight) {
|
||||
clif_msg_color(sd, MSI_CANT_GET_ITEM_BECAUSE_WEIGHT, color_table[COLOR_RED]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (w = itemdb_weight((pl_sd->status.sex) ? WEDDING_RING_M : WEDDING_RING_F) && w + pl_sd->weight > pl_sd->max_weight) {
|
||||
clif_msg_color(pl_sd, MSI_CANT_GET_ITEM_BECAUSE_WEIGHT, color_table[COLOR_RED]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pc_marriage(sd, pl_sd)) {
|
||||
clif_displaymessage(fd, msg_txt(sd,1173)); // They are married... wish them well.
|
||||
clif_wedding_effect(&pl_sd->bl); //wedding effect and music [Lupus]
|
||||
|
@ -11181,6 +11181,7 @@ static const struct _battle_data {
|
||||
{ "pk_level_range", &battle_config.pk_level_range, 0, 0, INT_MAX, },
|
||||
{ "manner_system", &battle_config.manner_system, 0xFFF, 0, 0xFFF, },
|
||||
{ "pet_equip_required", &battle_config.pet_equip_required, 0, 0, 1, },
|
||||
{ "pet_unequip_destroy", &battle_config.pet_unequip_destroy, 1, 0, 1, },
|
||||
{ "multi_level_up", &battle_config.multi_level_up, 0, 0, 1, },
|
||||
{ "multi_level_up_base", &battle_config.multi_level_up_base, 0, 0, MAX_LEVEL, },
|
||||
{ "multi_level_up_job", &battle_config.multi_level_up_job, 0, 0, MAX_LEVEL, },
|
||||
|
@ -260,6 +260,7 @@ struct Battle_Config
|
||||
int pet_max_atk2; //[Skotlex]
|
||||
int pet_no_gvg; //Disables pets in gvg. [Skotlex]
|
||||
int pet_equip_required;
|
||||
int pet_unequip_destroy;
|
||||
int pet_master_dead;
|
||||
|
||||
int skill_min_damage;
|
||||
|
@ -23326,7 +23326,7 @@ void clif_parse_laphine_synthesis( int fd, map_session_data* sd ){
|
||||
}
|
||||
}
|
||||
|
||||
itemdb_group.pc_get_itemgroup( synthesis->rewardGroupId, true, sd );
|
||||
itemdb_group.pc_get_itemgroup( synthesis->rewardGroupId, true, *sd );
|
||||
|
||||
clif_laphine_synthesis_result( sd, LAPHINE_SYNTHESIS_SUCCESS );
|
||||
#endif
|
||||
|
@ -509,6 +509,9 @@ enum clif_messages : uint16_t {
|
||||
// You cannot carry more items because you are overweight.
|
||||
MSI_CANT_GET_ITEM_BECAUSE_WEIGHT = 52,
|
||||
|
||||
// You can't have this item because you will exceed the weight limit.
|
||||
MSI_CANT_GET_ITEM_BECAUSE_COUNT = 220,
|
||||
|
||||
// You can't put this item on.
|
||||
MSI_CAN_NOT_EQUIP_ITEM = 372,
|
||||
|
||||
|
@ -2944,7 +2944,7 @@ t_itemid ItemGroupDatabase::get_random_item_id(uint16 group_id, uint8 sub_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(map_session_data *sd, bool identify, std::shared_ptr<s_item_group_entry> data) {
|
||||
void ItemGroupDatabase::pc_get_itemgroup_sub( map_session_data& sd, bool identify, std::shared_ptr<s_item_group_entry> data ){
|
||||
if (data == nullptr)
|
||||
return;
|
||||
|
||||
@ -2957,8 +2957,8 @@ static void itemdb_pc_get_itemgroup_sub(map_session_data *sd, bool identify, std
|
||||
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);
|
||||
tmp.card[2] = GetWord( sd.status.char_id, 0 );
|
||||
tmp.card[3] = GetWord( sd.status.char_id, 1 );
|
||||
}
|
||||
|
||||
uint16 get_amt = 0;
|
||||
@ -2972,8 +2972,7 @@ static void itemdb_pc_get_itemgroup_sub(map_session_data *sd, bool identify, std
|
||||
|
||||
// Do loop for non-stackable item
|
||||
for (uint16 i = 0; i < data->amount; i += get_amt) {
|
||||
char flag = 0;
|
||||
tmp.unique_id = data->GUID ? pc_generate_unique_id(sd) : 0; // Generate GUID
|
||||
tmp.unique_id = data->GUID ? pc_generate_unique_id( &sd ) : 0; // Generate GUID
|
||||
|
||||
if( itemdb_isequip( data->nameid ) ){
|
||||
if( data->refineMinimum > 0 && data->refineMaximum > 0 ){
|
||||
@ -2993,13 +2992,15 @@ static void itemdb_pc_get_itemgroup_sub(map_session_data *sd, bool identify, std
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
e_additem_result flag = pc_additem( &sd, &tmp, get_amt, LOG_TYPE_SCRIPT );
|
||||
|
||||
if( flag == ADDITEM_SUCCESS ){
|
||||
if( data->isAnnounced ){
|
||||
intif_broadcast_obtain_special_item( &sd, data->nameid, sd.itemid, ITEMOBTAIN_TYPE_BOXITEM );
|
||||
}
|
||||
}else{
|
||||
clif_additem( &sd, 0, 0, flag );
|
||||
}
|
||||
else if (!flag && data->isAnnounced)
|
||||
intif_broadcast_obtain_special_item(sd, data->nameid, sd->itemid, ITEMOBTAIN_TYPE_BOXITEM);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3007,11 +3008,9 @@ static void itemdb_pc_get_itemgroup_sub(map_session_data *sd, bool identify, std
|
||||
* Find item(s) that will be obtained by player based on Item Group
|
||||
* @param group_id: The group ID that will be gained by player
|
||||
* @param nameid: The item that trigger this item group
|
||||
* @return val: 0:success, 1:no sd, 2:invalid item group
|
||||
* @return val: 0:success, 2:invalid item group
|
||||
*/
|
||||
uint8 ItemGroupDatabase::pc_get_itemgroup(uint16 group_id, bool identify, map_session_data *sd) {
|
||||
nullpo_retr(1,sd);
|
||||
|
||||
uint8 ItemGroupDatabase::pc_get_itemgroup( uint16 group_id, bool identify, map_session_data& sd ){
|
||||
std::shared_ptr<s_item_group_db> group = this->find(group_id);
|
||||
|
||||
if (group == nullptr) {
|
||||
@ -3020,21 +3019,22 @@ uint8 ItemGroupDatabase::pc_get_itemgroup(uint16 group_id, bool identify, map_se
|
||||
}
|
||||
if (group->random.empty())
|
||||
return 0;
|
||||
|
||||
// Get all the 'must' item(s) (subgroup 0)
|
||||
uint16 subgroup = 0;
|
||||
std::shared_ptr<s_item_group_random> random = util::umap_find(group->random, subgroup);
|
||||
|
||||
if (random != nullptr && !random->data.empty()) {
|
||||
for (const auto &it : random->data)
|
||||
itemdb_pc_get_itemgroup_sub(sd, identify, it.second);
|
||||
// Get all the 'must' item(s) (subgroup 0)
|
||||
std::shared_ptr<s_item_group_random> must = util::umap_find(group->random, static_cast<uint16>(0));
|
||||
if( must != nullptr ){
|
||||
for (const auto &it : must->data)
|
||||
this->pc_get_itemgroup_sub( sd, identify, it.second );
|
||||
}
|
||||
|
||||
// Get 1 'random' item from each subgroup
|
||||
for (const auto &random : group->random) {
|
||||
if (random.first == 0 || random.second->data.empty())
|
||||
// Skip the 'must' group
|
||||
if( random.first == 0 ){
|
||||
continue;
|
||||
itemdb_pc_get_itemgroup_sub(sd, identify, get_random_itemsubgroup(random.second));
|
||||
}
|
||||
|
||||
this->pc_get_itemgroup_sub( sd, identify, get_random_itemsubgroup( random.second ) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -3561,6 +3561,19 @@ uint64 ItemGroupDatabase::parseBodyNode(const ryml::NodeRef& node) {
|
||||
}
|
||||
|
||||
void ItemGroupDatabase::loadingFinished() {
|
||||
// Delete empty sub groups
|
||||
for( const auto &group : *this ){
|
||||
for( auto it = group.second->random.begin(); it != group.second->random.end(); ){
|
||||
if( it->second->data.empty() ){
|
||||
ShowDebug( "Deleting empty subgroup %u from item group %hu.\n", it->first, group.first );
|
||||
it = group.second->random.erase( it );
|
||||
}else{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate rates
|
||||
for (const auto &group : *this) {
|
||||
for (const auto &random : group.second->random) {
|
||||
random.second->total_rate = 0;
|
||||
|
@ -3173,7 +3173,10 @@ public:
|
||||
int16 item_exists_pc(map_session_data *sd, uint16 group_id);
|
||||
t_itemid get_random_item_id(uint16 group_id, uint8 sub_group);
|
||||
std::shared_ptr<s_item_group_entry> get_random_entry(uint16 group_id, uint8 sub_group);
|
||||
uint8 pc_get_itemgroup(uint16 group_id, bool identify, map_session_data *sd);
|
||||
uint8 pc_get_itemgroup( uint16 group_id, bool identify, map_session_data& sd );
|
||||
|
||||
private:
|
||||
void pc_get_itemgroup_sub( map_session_data& sd, bool identify, std::shared_ptr<s_item_group_entry> data );
|
||||
};
|
||||
|
||||
extern ItemGroupDatabase itemdb_group;
|
||||
|
@ -6262,14 +6262,35 @@ bool pc_isUseitem(map_session_data *sd,int n)
|
||||
if( itemdb_group.item_exists(IG_MERCENARY, nameid) && sd->md != nullptr )
|
||||
return false; // Mercenary Scrolls
|
||||
|
||||
if( item->flag.group || item->type == IT_CASH) { //safe check type cash disappear when overweight [Napster]
|
||||
if( pc_is90overweight(sd) ) {
|
||||
clif_msg(sd, MSI_CANT_GET_ITEM_BECAUSE_WEIGHT);
|
||||
return false;
|
||||
// Safe check type cash disappear when overweight [Napster]
|
||||
if( item->flag.group || item->type == IT_CASH ){
|
||||
#ifdef RENEWAL
|
||||
// Check if the player is not overweighted
|
||||
// In Renewal the limit is 70% weight and gives the same error message
|
||||
if (pc_is70overweight(sd)) {
|
||||
clif_msg_color(sd, MSI_PICKUP_FAILED_ITEMCREATE, color_table[COLOR_RED]);
|
||||
return 0;
|
||||
}
|
||||
if( !pc_inventoryblank(sd) ) {
|
||||
clif_messagecolor(&sd->bl, color_table[COLOR_RED], msg_txt(sd, 732), false, SELF); //Item cannot be open when inventory is full
|
||||
return false;
|
||||
#else
|
||||
// Check if the player is not overweighted
|
||||
// In Pre-Renewal the limit is 50% weight and gives a specific error message
|
||||
if (pc_is50overweight(sd)) {
|
||||
clif_msg_color(sd, MSI_CANT_GET_ITEM_BECAUSE_WEIGHT, color_table[COLOR_RED]);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if the player has enough free spaces in the inventory
|
||||
// Official servers use 10 as the minimum amount of slots required to get the items
|
||||
// The <= is intentional, as in official servers you actually need an extra empty slot
|
||||
// TODO: Count the items the player will get and check for the actual inventory space required std::max<size_t>( count, 10 )
|
||||
if (pc_inventoryblank(sd) <= 10) {
|
||||
#ifdef RENEWAL
|
||||
clif_msg_color(sd, MSI_PICKUP_FAILED_ITEMCREATE, color_table[COLOR_RED]);
|
||||
#else
|
||||
clif_msg_color(sd, MSI_CANT_GET_ITEM_BECAUSE_COUNT, color_table[COLOR_RED]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -9820,7 +9841,7 @@ int pc_dead(map_session_data *sd,struct block_list *src)
|
||||
item_tmp.card[1]=0;
|
||||
item_tmp.card[2]=GetWord(sd->status.char_id,0); // CharId
|
||||
item_tmp.card[3]=GetWord(sd->status.char_id,1);
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
}
|
||||
|
||||
//Remove bonus_script when dead
|
||||
|
@ -1278,7 +1278,6 @@ int pet_catch_process2(map_session_data* sd, int target_id)
|
||||
}
|
||||
|
||||
if(sd->catch_target_class != md->mob_id || !pet) {
|
||||
clif_emotion(&md->bl, ET_ANGER); //mob will do /ag if wrong lure is used on them.
|
||||
clif_pet_roulette( *sd, false );
|
||||
sd->catch_target_class = PET_CATCH_FAIL;
|
||||
|
||||
@ -1292,6 +1291,14 @@ int pet_catch_process2(map_session_data* sd, int target_id)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!pc_inventoryblank(sd)) {
|
||||
clif_pet_roulette(*sd, false);
|
||||
sd->catch_target_class = PET_CATCH_FAIL;
|
||||
clif_msg_color(sd, MSI_CANT_GET_ITEM_BECAUSE_COUNT, color_table[COLOR_RED]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
status_change* tsc = status_get_sc( &md->bl );
|
||||
|
||||
if( battle_config.pet_hide_check && tsc && ( tsc->getSCE(SC_HIDING) || tsc->getSCE(SC_CLOAKING) || tsc->getSCE(SC_CAMOUFLAGE) || tsc->getSCE(SC_NEWMOON) || tsc->getSCE(SC_CLOAKINGEXCEED) ) ){
|
||||
@ -1376,8 +1383,10 @@ bool pet_get_egg(uint32 account_id, short pet_class, int pet_id ) {
|
||||
tmp_item.card[3] |= pet_get_card3_intimacy( pet->intimate ); // Store intimacy status based on initial intimacy
|
||||
|
||||
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);
|
||||
clif_additem(sd, 0, 0, ret);
|
||||
intif_delete_petdata(pet_id);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1554,18 +1563,27 @@ static int pet_unequipitem(map_session_data *sd, struct pet_data *pd)
|
||||
return 1;
|
||||
|
||||
t_itemid 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);
|
||||
clif_additem(sd, 0, 0, flag);
|
||||
|
||||
// On official servers the item is destroyed if you don't have enough space
|
||||
if (battle_config.pet_unequip_destroy) {
|
||||
log_pick_pc( sd, LOG_TYPE_OTHER, -1, &tmp_item );
|
||||
}
|
||||
// Don't unequip (and don't destroy) the item if failed to add it to the inventory
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
pd->pet.equip = 0;
|
||||
status_set_viewdata(&pd->bl, pd->pet.class_);
|
||||
clif_pet_equip_area(pd);
|
||||
|
||||
if( battle_config.pet_equip_required ) { // Skotlex: halt support timers if needed
|
||||
if( pd->state.skillbonus ) {
|
||||
pd->state.skillbonus = 0;
|
||||
|
@ -7617,9 +7617,7 @@ BUILDIN_FUNC(getitem)
|
||||
int get_count, i;
|
||||
t_itemid nameid;
|
||||
unsigned short amount;
|
||||
struct item it;
|
||||
map_session_data *sd;
|
||||
unsigned char flag = 0;
|
||||
map_session_data* sd;
|
||||
const char* command = script_getfuncname(st);
|
||||
std::shared_ptr<item_data> id;
|
||||
|
||||
@ -7648,7 +7646,8 @@ BUILDIN_FUNC(getitem)
|
||||
if( (amount = script_getnum(st,3)) <= 0)
|
||||
return SCRIPT_CMD_SUCCESS; //return if amount <=0, skip the useles iteration
|
||||
|
||||
memset(&it,0,sizeof(it));
|
||||
item it = {};
|
||||
|
||||
it.nameid = nameid;
|
||||
it.identify = 1;
|
||||
it.bound = BOUND_NONE;
|
||||
@ -7680,11 +7679,12 @@ BUILDIN_FUNC(getitem)
|
||||
// if not pet egg
|
||||
if (!pet_create_egg(sd, nameid))
|
||||
{
|
||||
if ((flag = pc_additem(sd, &it, get_count, LOG_TYPE_SCRIPT)))
|
||||
{
|
||||
e_additem_result flag = pc_additem( sd, &it, get_count, LOG_TYPE_SCRIPT );
|
||||
|
||||
if( flag != ADDITEM_SUCCESS ){
|
||||
clif_additem(sd, 0, 0, flag);
|
||||
if( pc_candrop(sd,&it) )
|
||||
map_addflooritem(&it,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
ShowError( "buildin_getitem: Failed to add the item to player.\n" );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7719,7 +7719,7 @@ BUILDIN_FUNC(getitem)
|
||||
*------------------------------------------*/
|
||||
BUILDIN_FUNC(getitem2)
|
||||
{
|
||||
TBL_PC *sd;
|
||||
map_session_data* sd;
|
||||
char bound = BOUND_NONE;
|
||||
const char* command = script_getfuncname(st);
|
||||
int offset = 0;
|
||||
@ -7792,7 +7792,7 @@ BUILDIN_FUNC(getitem2)
|
||||
t_itemid c3 = script_getnum(st,9);
|
||||
t_itemid c4 = script_getnum(st,10);
|
||||
|
||||
struct item item_tmp = {};
|
||||
item item_tmp = {};
|
||||
|
||||
if( item_data ) {
|
||||
if( item_data->type == IT_WEAPON || item_data->type == IT_ARMOR || item_data->type == IT_SHADOWGEAR ) {
|
||||
@ -7847,12 +7847,12 @@ BUILDIN_FUNC(getitem2)
|
||||
// if not pet egg
|
||||
if (!pet_create_egg(sd, nameid))
|
||||
{
|
||||
unsigned char flag = 0;
|
||||
if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT)))
|
||||
{
|
||||
e_additem_result flag = pc_additem( sd, &item_tmp, get_count, LOG_TYPE_SCRIPT );
|
||||
|
||||
if( flag != ADDITEM_SUCCESS ){
|
||||
clif_additem(sd, 0, 0, flag);
|
||||
if( pc_candrop(sd,&item_tmp) )
|
||||
map_addflooritem(&item_tmp,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
ShowError( "buildin_getitem2: Failed to add the item to player.\n" );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13988,7 +13988,7 @@ BUILDIN_FUNC(getequipcardcnt)
|
||||
BUILDIN_FUNC(successremovecards) {
|
||||
int i=-1,c,cardflag=0;
|
||||
|
||||
TBL_PC* sd;
|
||||
map_session_data* sd;
|
||||
int num;
|
||||
|
||||
if( !script_rid2sd(sd) )
|
||||
@ -14008,24 +14008,26 @@ BUILDIN_FUNC(successremovecards) {
|
||||
|
||||
for( c = sd->inventory_data[i]->slots - 1; c >= 0; --c ) {
|
||||
if( sd->inventory.u.items_inventory[i].card[c] && itemdb_type(sd->inventory.u.items_inventory[i].card[c]) == IT_CARD ) {// extract this card from the item
|
||||
unsigned char flag = 0;
|
||||
struct item item_tmp;
|
||||
memset(&item_tmp,0,sizeof(item_tmp));
|
||||
item item_tmp = {};
|
||||
|
||||
cardflag = 1;
|
||||
item_tmp.nameid = sd->inventory.u.items_inventory[i].card[c];
|
||||
item_tmp.identify = 1;
|
||||
|
||||
if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ // get back the cart in inventory
|
||||
e_additem_result flag = pc_additem( sd, &item_tmp, 1, LOG_TYPE_SCRIPT );
|
||||
|
||||
// get back the card in inventory
|
||||
if( flag != ADDITEM_SUCCESS ){
|
||||
clif_additem(sd,0,0,flag);
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
ShowError( "buildin_successremovecards: Failed to add the item to player.\n" );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(cardflag == 1) {//if card was remove remplace item with no card
|
||||
unsigned char flag = 0;
|
||||
struct item item_tmp;
|
||||
memset(&item_tmp,0,sizeof(item_tmp));
|
||||
// if card was removed, replace item with no card
|
||||
if(cardflag == 1) {
|
||||
item item_tmp = {};
|
||||
|
||||
item_tmp.nameid = sd->inventory.u.items_inventory[i].nameid;
|
||||
item_tmp.identify = 1;
|
||||
@ -14045,9 +14047,14 @@ BUILDIN_FUNC(successremovecards) {
|
||||
}
|
||||
|
||||
pc_delitem(sd,i,1,0,3,LOG_TYPE_SCRIPT);
|
||||
if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ //chk if can be spawn in inventory otherwise put on floor
|
||||
|
||||
e_additem_result flag = pc_additem( sd, &item_tmp, 1, LOG_TYPE_SCRIPT );
|
||||
|
||||
// get back the card in inventory
|
||||
if( flag != ADDITEM_SUCCESS ){
|
||||
clif_additem(sd,0,0,flag);
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
ShowError( "buildin_successremovecards: Failed to add the item to player.\n" );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
clif_misceffect( sd->bl, NOTIFYEFFECT_REFINE_SUCCESS );
|
||||
@ -14064,7 +14071,7 @@ BUILDIN_FUNC(successremovecards) {
|
||||
BUILDIN_FUNC(failedremovecards) {
|
||||
int i=-1,c,cardflag=0;
|
||||
|
||||
TBL_PC* sd;
|
||||
map_session_data* sd;
|
||||
int num;
|
||||
int typefail;
|
||||
|
||||
@ -14088,17 +14095,17 @@ BUILDIN_FUNC(failedremovecards) {
|
||||
cardflag = 1;
|
||||
|
||||
if(typefail == 2) {// add cards to inventory, clear
|
||||
unsigned char flag = 0;
|
||||
struct item item_tmp;
|
||||
|
||||
memset(&item_tmp,0,sizeof(item_tmp));
|
||||
item item_tmp = {};
|
||||
|
||||
item_tmp.nameid = sd->inventory.u.items_inventory[i].card[c];
|
||||
item_tmp.identify = 1;
|
||||
|
||||
if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){
|
||||
e_additem_result flag = pc_additem( sd, &item_tmp, 1, LOG_TYPE_SCRIPT );
|
||||
|
||||
if( flag != ADDITEM_SUCCESS ){
|
||||
clif_additem(sd,0,0,flag);
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
ShowError( "failedremovecards: Failed to add the item to player.\n" );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14108,10 +14115,7 @@ BUILDIN_FUNC(failedremovecards) {
|
||||
if(typefail == 0 || typefail == 2){ // destroy the item
|
||||
pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
|
||||
}else if(typefail == 1){ // destroy the card
|
||||
unsigned char flag = 0;
|
||||
struct item item_tmp;
|
||||
|
||||
memset(&item_tmp,0,sizeof(item_tmp));
|
||||
item item_tmp = {};
|
||||
|
||||
item_tmp.nameid = sd->inventory.u.items_inventory[i].nameid;
|
||||
item_tmp.identify = 1;
|
||||
@ -14132,9 +14136,12 @@ BUILDIN_FUNC(failedremovecards) {
|
||||
|
||||
pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
|
||||
|
||||
if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){
|
||||
e_additem_result flag = pc_additem( sd, &item_tmp, 1, LOG_TYPE_SCRIPT );
|
||||
|
||||
if( flag != ADDITEM_SUCCESS ){
|
||||
clif_additem(sd,0,0,flag);
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
ShowError( "failedremovecards: Failed to add the item to player.\n" );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
}
|
||||
clif_misceffect( sd->bl, NOTIFYEFFECT_REFINE_FAILURE );
|
||||
@ -22819,11 +22826,10 @@ BUILDIN_FUNC(checkre)
|
||||
|
||||
/* getrandgroupitem <group_id>{,<quantity>{,<sub_group>{,<identify>{,<char_id>}}}} */
|
||||
BUILDIN_FUNC(getrandgroupitem) {
|
||||
TBL_PC* sd;
|
||||
map_session_data* sd;
|
||||
int i, get_count = 0, identify = 0;
|
||||
uint16 group, qty = 0;
|
||||
uint8 sub_group = 1;
|
||||
struct item item_tmp;
|
||||
|
||||
if (!script_charid2sd(6, sd))
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
@ -22840,10 +22846,14 @@ BUILDIN_FUNC(getrandgroupitem) {
|
||||
FETCH(5, identify);
|
||||
|
||||
std::shared_ptr<s_item_group_entry> entry = itemdb_group.get_random_entry(group,sub_group);
|
||||
if (!entry)
|
||||
return SCRIPT_CMD_FAILURE; //ensure valid itemid
|
||||
|
||||
memset(&item_tmp,0,sizeof(item_tmp));
|
||||
if( entry == nullptr ){
|
||||
ShowError( "buildin_getrandgroupitem: Unable to find a random entry in group %hu for sub group %hu.\n", group, sub_group );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
item item_tmp = {};
|
||||
|
||||
item_tmp.nameid = entry->nameid;
|
||||
item_tmp.identify = identify ? 1 : itemdb_isidentified(entry->nameid);
|
||||
|
||||
@ -22860,14 +22870,20 @@ BUILDIN_FUNC(getrandgroupitem) {
|
||||
get_count = 1;
|
||||
}
|
||||
|
||||
if( pc_inventoryblank( sd ) < get_count ){
|
||||
ShowError( "buildin_getrandgroupitem: Not enough free space in inventory.\n" );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; i < get_count; i++) {
|
||||
// if not pet egg
|
||||
if (!pet_create_egg(sd, entry->nameid)) {
|
||||
unsigned char flag = 0;
|
||||
if ((flag = pc_additem(sd,&item_tmp,item_tmp.amount,LOG_TYPE_SCRIPT))) {
|
||||
e_additem_result flag = pc_additem( sd, &item_tmp, item_tmp.amount, LOG_TYPE_SCRIPT );
|
||||
|
||||
if( flag != ADDITEM_SUCCESS ){
|
||||
clif_additem(sd,0,0,flag);
|
||||
if (pc_candrop(sd,&item_tmp))
|
||||
map_addflooritem(&item_tmp,item_tmp.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
ShowError( "buildin_getrandgroupitem: Failed to add the item to player.\n" );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22879,13 +22895,19 @@ BUILDIN_FUNC(getrandgroupitem) {
|
||||
* Gives item(s) to the attached player based on item group contents
|
||||
*/
|
||||
BUILDIN_FUNC(getgroupitem) {
|
||||
TBL_PC *sd;
|
||||
map_session_data* sd;
|
||||
int group_id = script_getnum(st,2);
|
||||
|
||||
if (!script_charid2sd(4,sd))
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
bool identify = false;
|
||||
|
||||
if( script_hasdata( st, 3 ) ){
|
||||
identify = script_getnum( st, 3 );
|
||||
}
|
||||
|
||||
if (itemdb_group.pc_get_itemgroup(group_id, (script_hasdata(st, 3) ? script_getnum(st, 3) != 0 : false), sd)) {
|
||||
if( itemdb_group.pc_get_itemgroup( group_id, identify, *sd ) ){
|
||||
ShowError("buildin_getgroupitem: Invalid group id '%d' specified.\n",group_id);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
@ -9386,7 +9386,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
eflag = pc_additem(sd,&item_tmp,1,LOG_TYPE_PRODUCE);
|
||||
if(eflag) {
|
||||
clif_additem(sd,0,0,eflag);
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
if (battle_config.skill_drop_items_full)
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -10173,7 +10174,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
item_tmp.amount = skill_group->require.amount[i];
|
||||
if( item_tmp.nameid && (flag2=pc_additem(sd,&item_tmp,item_tmp.amount,LOG_TYPE_OTHER)) ){
|
||||
clif_additem(sd,0,0,flag2);
|
||||
map_addflooritem(&item_tmp,item_tmp.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
if (battle_config.skill_drop_items_full)
|
||||
map_addflooritem(&item_tmp,item_tmp.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10187,7 +10189,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
if( item_tmp.nameid && (flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_OTHER)) )
|
||||
{
|
||||
clif_additem(sd,0,0,flag);
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
if (battle_config.skill_drop_items_full)
|
||||
map_addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22397,7 +22400,7 @@ bool skill_produce_mix(map_session_data *sd, uint16 skill_id, t_itemid nameid, i
|
||||
if ((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
|
||||
clif_additem(sd,0,0,flag);
|
||||
if( battle_config.skill_drop_items_full ){
|
||||
map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22417,7 +22420,7 @@ bool skill_produce_mix(map_session_data *sd, uint16 skill_id, t_itemid nameid, i
|
||||
if ((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
|
||||
clif_additem(sd,0,0,flag);
|
||||
if( battle_config.skill_drop_items_full ){
|
||||
map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
}
|
||||
}
|
||||
switch (skill_id) {
|
||||
@ -22504,7 +22507,7 @@ bool skill_produce_mix(map_session_data *sd, uint16 skill_id, t_itemid nameid, i
|
||||
if ((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
|
||||
clif_additem(sd,0,0,flag);
|
||||
if( battle_config.skill_drop_items_full ){
|
||||
map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
}
|
||||
}
|
||||
clif_produceeffect(sd,7,nameid);
|
||||
@ -22587,7 +22590,8 @@ bool skill_arrow_create(map_session_data *sd, t_itemid nameid)
|
||||
}
|
||||
if ((flag = pc_additem(sd,&tmp_item,tmp_item.amount,LOG_TYPE_PRODUCE))) {
|
||||
clif_additem(sd,0,0,flag);
|
||||
map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0,0);
|
||||
if( battle_config.skill_drop_items_full )
|
||||
map_addflooritem(&tmp_item,tmp_item.amount,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,4,0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -22854,7 +22858,8 @@ int skill_elementalanalysis( map_session_data& sd, int n, uint16 skill_lv, unsig
|
||||
unsigned char flag = pc_additem(&sd,&tmp_item,tmp_item.amount,LOG_TYPE_CONSUME);
|
||||
if( flag != 0 ) {
|
||||
clif_additem(&sd,0,0,flag);
|
||||
map_addflooritem(&tmp_item,tmp_item.amount,sd.bl.m,sd.bl.x,sd.bl.y,0,0,0,0,0);
|
||||
if( battle_config.skill_drop_items_full )
|
||||
map_addflooritem(&tmp_item,tmp_item.amount,sd.bl.m,sd.bl.x,sd.bl.y,0,0,0,4,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user