mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-16 05:11:29 +00:00
[Feature] Add "Keeps Sold Items" Flag to NPCs (#2671)
# Perl - Add `$npc->GetKeepsSoldItems()`. - Add `$npc->SetKeepsSoldItems(keeps_sold_items)`. # Lua - Add `npc:GetKeepsSoldItems()`. - Add `npc:SetKeepsSoldItems(keeps_sold_items)`. # Notes - Allows operators to keep specific NPCs from keeping items sold to them. - Keeps NPCs from being cluttered with stuff like Cloth Caps, Bone Chips, etc.
This commit is contained in:
parent
2ed73199bf
commit
a590ea1d52
@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseNpcTypesRepository {
|
class BaseNpcTypesRepository {
|
||||||
public:
|
public:
|
||||||
struct NpcTypes {
|
struct NpcTypes {
|
||||||
@ -145,6 +146,7 @@ public:
|
|||||||
int32_t exp_mod;
|
int32_t exp_mod;
|
||||||
int32_t heroic_strikethrough;
|
int32_t heroic_strikethrough;
|
||||||
int32_t faction_amount;
|
int32_t faction_amount;
|
||||||
|
uint8_t keeps_sold_items;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@ -281,6 +283,7 @@ public:
|
|||||||
"exp_mod",
|
"exp_mod",
|
||||||
"heroic_strikethrough",
|
"heroic_strikethrough",
|
||||||
"faction_amount",
|
"faction_amount",
|
||||||
|
"keeps_sold_items",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,6 +416,7 @@ public:
|
|||||||
"exp_mod",
|
"exp_mod",
|
||||||
"heroic_strikethrough",
|
"heroic_strikethrough",
|
||||||
"faction_amount",
|
"faction_amount",
|
||||||
|
"keeps_sold_items",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,6 +583,7 @@ public:
|
|||||||
e.exp_mod = 100;
|
e.exp_mod = 100;
|
||||||
e.heroic_strikethrough = 0;
|
e.heroic_strikethrough = 0;
|
||||||
e.faction_amount = 0;
|
e.faction_amount = 0;
|
||||||
|
e.keeps_sold_items = 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -604,8 +609,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
npc_types_id
|
npc_types_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -740,6 +746,7 @@ public:
|
|||||||
e.exp_mod = static_cast<int32_t>(atoi(row[123]));
|
e.exp_mod = static_cast<int32_t>(atoi(row[123]));
|
||||||
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[124]));
|
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[124]));
|
||||||
e.faction_amount = static_cast<int32_t>(atoi(row[125]));
|
e.faction_amount = static_cast<int32_t>(atoi(row[125]));
|
||||||
|
e.keeps_sold_items = static_cast<uint8_t>(strtoul(row[126], nullptr, 10));
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -898,6 +905,7 @@ public:
|
|||||||
v.push_back(columns[123] + " = " + std::to_string(e.exp_mod));
|
v.push_back(columns[123] + " = " + std::to_string(e.exp_mod));
|
||||||
v.push_back(columns[124] + " = " + std::to_string(e.heroic_strikethrough));
|
v.push_back(columns[124] + " = " + std::to_string(e.heroic_strikethrough));
|
||||||
v.push_back(columns[125] + " = " + std::to_string(e.faction_amount));
|
v.push_back(columns[125] + " = " + std::to_string(e.faction_amount));
|
||||||
|
v.push_back(columns[126] + " = " + std::to_string(e.keeps_sold_items));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -1045,6 +1053,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.exp_mod));
|
v.push_back(std::to_string(e.exp_mod));
|
||||||
v.push_back(std::to_string(e.heroic_strikethrough));
|
v.push_back(std::to_string(e.heroic_strikethrough));
|
||||||
v.push_back(std::to_string(e.faction_amount));
|
v.push_back(std::to_string(e.faction_amount));
|
||||||
|
v.push_back(std::to_string(e.keeps_sold_items));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -1200,6 +1209,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.exp_mod));
|
v.push_back(std::to_string(e.exp_mod));
|
||||||
v.push_back(std::to_string(e.heroic_strikethrough));
|
v.push_back(std::to_string(e.heroic_strikethrough));
|
||||||
v.push_back(std::to_string(e.faction_amount));
|
v.push_back(std::to_string(e.faction_amount));
|
||||||
|
v.push_back(std::to_string(e.keeps_sold_items));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@ -1359,6 +1369,7 @@ public:
|
|||||||
e.exp_mod = static_cast<int32_t>(atoi(row[123]));
|
e.exp_mod = static_cast<int32_t>(atoi(row[123]));
|
||||||
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[124]));
|
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[124]));
|
||||||
e.faction_amount = static_cast<int32_t>(atoi(row[125]));
|
e.faction_amount = static_cast<int32_t>(atoi(row[125]));
|
||||||
|
e.keeps_sold_items = static_cast<uint8_t>(strtoul(row[126], nullptr, 10));
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@ -1509,6 +1520,7 @@ public:
|
|||||||
e.exp_mod = static_cast<int32_t>(atoi(row[123]));
|
e.exp_mod = static_cast<int32_t>(atoi(row[123]));
|
||||||
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[124]));
|
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[124]));
|
||||||
e.faction_amount = static_cast<int32_t>(atoi(row[125]));
|
e.faction_amount = static_cast<int32_t>(atoi(row[125]));
|
||||||
|
e.keeps_sold_items = static_cast<uint8_t>(strtoul(row[126], nullptr, 10));
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9212
|
#define CURRENT_BINARY_DATABASE_VERSION 9213
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9035
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9035
|
||||||
|
|||||||
@ -466,6 +466,7 @@
|
|||||||
9210|2022_10_11_fix_misty_pok_stone.sql|select * from doors where id = 2040 and `name` = 'POKRVPORT500' and client_version_mask = 4294967232|empty|
|
9210|2022_10_11_fix_misty_pok_stone.sql|select * from doors where id = 2040 and `name` = 'POKRVPORT500' and client_version_mask = 4294967232|empty|
|
||||||
9211|2022_10_14_fix_neriak_pok_stone.sql|select * from doors where id = 2057 and `name` = 'POKNRKPORT500' and client_version_mask = 4294967232|empty|
|
9211|2022_10_14_fix_neriak_pok_stone.sql|select * from doors where id = 2057 and `name` = 'POKNRKPORT500' and client_version_mask = 4294967232|empty|
|
||||||
9212|2022_10_14_fix_misty_pok_stone.sql|select * from doors where id = 2040 and `name` = 'POKRVPORT500' and dest_zone = 'misty'|empty|
|
9212|2022_10_14_fix_misty_pok_stone.sql|select * from doors where id = 2040 and `name` = 'POKRVPORT500' and dest_zone = 'misty'|empty|
|
||||||
|
9213|2022_12_24_npc_keeps_sold_items.sql|SHOW COLUMNS FROM `npc_types` LIKE 'keeps_sold_items'|empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE `npc_types`
|
||||||
|
ADD COLUMN `keeps_sold_items` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 AFTER `faction_amount`;
|
||||||
@ -52,11 +52,63 @@ extern Zone* zone;
|
|||||||
|
|
||||||
// if lifetime is 0 this is a permanent beacon.. not sure if that'll be
|
// if lifetime is 0 this is a permanent beacon.. not sure if that'll be
|
||||||
// useful for anything
|
// useful for anything
|
||||||
Beacon::Beacon(const glm::vec4 &in_pos, int lifetime)
|
Beacon::Beacon(const glm::vec4 &in_pos, int lifetime) : Mob(
|
||||||
:Mob
|
nullptr, // in_name
|
||||||
(
|
nullptr, // in_lastname
|
||||||
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, in_pos, 0, 0, 0,
|
0, // in_cur_hp
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQ::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false
|
0, // in_max_hp
|
||||||
|
MALE, // in_gender
|
||||||
|
INVISIBLE_MAN, // in_race
|
||||||
|
0, // in_class
|
||||||
|
BT_NoTarget, // in_bodytype
|
||||||
|
0, // in_deity
|
||||||
|
0, // in_level
|
||||||
|
0, // in_npctype_id
|
||||||
|
0.0f, // in_size
|
||||||
|
0.0f, // in_runspeed
|
||||||
|
in_pos, // position
|
||||||
|
0, // in_light
|
||||||
|
0, // in_texture
|
||||||
|
0, // in_helmtexture
|
||||||
|
0, // in_ac
|
||||||
|
0, // in_atk
|
||||||
|
0, // in_str
|
||||||
|
0, // in_sta
|
||||||
|
0, // in_dex
|
||||||
|
0, // in_agi
|
||||||
|
0, // in_int
|
||||||
|
0, // in_wis
|
||||||
|
0, // in_cha
|
||||||
|
0, // in_haircolor
|
||||||
|
0, // in_beardcolor
|
||||||
|
0, // in_eyecolor1
|
||||||
|
0, // in_eyecolor2
|
||||||
|
0, // in_hairstyle
|
||||||
|
0, // in_luclinface
|
||||||
|
0, // in_beard
|
||||||
|
0, // in_drakkin_heritage
|
||||||
|
0, // in_drakkin_tattoo
|
||||||
|
0, // in_drakkin_details
|
||||||
|
EQ::TintProfile(), // in_armor_tint
|
||||||
|
0, // in_aa_title
|
||||||
|
0, // in_see_invis
|
||||||
|
0, // in_see_invis_undead
|
||||||
|
0, // in_see_hide
|
||||||
|
0, // in_see_improved_hide
|
||||||
|
0, // in_hp_regen
|
||||||
|
0, // in_mana_regen
|
||||||
|
0, // in_qglobal
|
||||||
|
0, // in_maxlevel
|
||||||
|
0, // in_scalerate
|
||||||
|
0, // in_armtexture
|
||||||
|
0, // in_bracertexture
|
||||||
|
0, // in_handtexture
|
||||||
|
0, // in_legtexture
|
||||||
|
0, // in_feettexture
|
||||||
|
0, // in_usemodel
|
||||||
|
false, // in_always_aggros_foes
|
||||||
|
0, //in_heroic_strikethrough
|
||||||
|
false // in_keeps_sold_items
|
||||||
),
|
),
|
||||||
remove_timer(lifetime),
|
remove_timer(lifetime),
|
||||||
spell_timer(0)
|
spell_timer(0)
|
||||||
|
|||||||
113
zone/client.cpp
113
zone/client.cpp
@ -82,62 +82,63 @@ char entirecommand[255];
|
|||||||
|
|
||||||
void UpdateWindowTitle(char* iNewTitle);
|
void UpdateWindowTitle(char* iNewTitle);
|
||||||
|
|
||||||
Client::Client(EQStreamInterface* ieqs)
|
Client::Client(EQStreamInterface *ieqs) : Mob(
|
||||||
: Mob("No name", // name
|
"No name", // in_name
|
||||||
"", // lastname
|
"", // in_lastname
|
||||||
0, // cur_hp
|
0, // in_cur_hp
|
||||||
0, // max_hp
|
0, // in_max_hp
|
||||||
0, // gender
|
0, // in_gender
|
||||||
0, // race
|
0, // in_race
|
||||||
0, // class
|
0, // in_class
|
||||||
BT_Humanoid, // bodytype
|
BT_Humanoid, // in_bodytype
|
||||||
0, // deity
|
0, // in_deity
|
||||||
0, // level
|
0, // in_level
|
||||||
0, // npctypeid
|
0, // in_npctype_id
|
||||||
0, // size
|
0.0f, // in_size
|
||||||
0.7, // runspeed
|
0.7f, // in_runspeed
|
||||||
glm::vec4(),
|
glm::vec4(), // position
|
||||||
0, // light - verified for client innate_light value
|
0, // in_light
|
||||||
0xFF, // texture
|
0xFF, // in_texture
|
||||||
0xFF, // helmtexture
|
0xFF, // in_helmtexture
|
||||||
0, // ac
|
0, // in_ac
|
||||||
0, // atk
|
0, // in_atk
|
||||||
0, // str
|
0, // in_str
|
||||||
0, // sta
|
0, // in_sta
|
||||||
0, // dex
|
0, // in_dex
|
||||||
0, // agi
|
0, // in_agi
|
||||||
0, // int
|
0, // in_int
|
||||||
0, // wis
|
0, // in_wis
|
||||||
0, // cha
|
0, // in_cha
|
||||||
0, // Luclin Hair Colour
|
0, // in_haircolor
|
||||||
0, // Luclin Beard Color
|
0, // in_beardcolor
|
||||||
0, // Luclin Eye1
|
0, // in_eyecolor1
|
||||||
0, // Luclin Eye2
|
0, // in_eyecolor2
|
||||||
0, // Luclin Hair Style
|
0, // in_hairstyle
|
||||||
0, // Luclin Face
|
0, // in_luclinface
|
||||||
0, // Luclin Beard
|
0, // in_beard
|
||||||
0, // Drakkin Heritage
|
0, // in_drakkin_heritage
|
||||||
0, // Drakkin Tattoo
|
0, // in_drakkin_tattoo
|
||||||
0, // Drakkin Details
|
0, // in_drakkin_details
|
||||||
EQ::TintProfile(), // Armor Tint
|
EQ::TintProfile(), // in_armor_tint
|
||||||
0xff, // AA Title
|
0xff, // in_aa_title
|
||||||
0, // see_invis
|
0, // in_see_invis
|
||||||
0, // see_invis_undead
|
0, // in_see_invis_undead
|
||||||
0,
|
0, // in_see_hide
|
||||||
0,
|
0, // in_see_improved_hide
|
||||||
0,
|
0, // in_hp_regen
|
||||||
0,
|
0, // in_mana_regen
|
||||||
0, // qglobal
|
0, // in_qglobal
|
||||||
0, // maxlevel
|
0, // in_maxlevel
|
||||||
0, // scalerate
|
0, // in_scalerate
|
||||||
0,
|
0, // in_armtexture
|
||||||
0,
|
0, // in_bracertexture
|
||||||
0,
|
0, // in_handtexture
|
||||||
0,
|
0, // in_legtexture
|
||||||
0,
|
0, // in_feettexture
|
||||||
0,
|
0, // in_usemodel
|
||||||
0,
|
false, // in_always_aggros_foes
|
||||||
false
|
0, // in_heroic_strikethrough
|
||||||
|
false // in_keeps_sold_items
|
||||||
),
|
),
|
||||||
hpupdate_timer(2000),
|
hpupdate_timer(2000),
|
||||||
camp_timer(29000),
|
camp_timer(29000),
|
||||||
|
|||||||
@ -13403,27 +13403,44 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
int charges = mp->quantity;
|
int charges = mp->quantity;
|
||||||
|
|
||||||
|
if (vendor->GetKeepsSoldItems()) {
|
||||||
int freeslot = 0;
|
int freeslot = 0;
|
||||||
if ((freeslot = zone->SaveTempItem(vendor->CastToNPC()->MerchantType, vendor->GetNPCTypeID(), itemid, charges, true)) > 0) {
|
if (
|
||||||
|
(freeslot = zone->SaveTempItem(
|
||||||
|
vendor->CastToNPC()->MerchantType,
|
||||||
|
vendor->GetNPCTypeID(),
|
||||||
|
itemid,
|
||||||
|
charges,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
) > 0) {
|
||||||
EQ::ItemInstance *inst2 = inst->Clone();
|
EQ::ItemInstance *inst2 = inst->Clone();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (inst2 == nullptr)
|
if (!inst2) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 price = (
|
||||||
|
item->Price *
|
||||||
|
RuleR(Merchant, SellCostMod) *
|
||||||
|
item->SellRate
|
||||||
|
);
|
||||||
|
|
||||||
if (RuleB(Merchant, UsePriceMod)) {
|
if (RuleB(Merchant, UsePriceMod)) {
|
||||||
inst2->SetPrice(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate*Client::CalcPriceMod(vendor, false));
|
price *= Client::CalcPriceMod(vendor, false);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
inst2->SetPrice(item->Price*(RuleR(Merchant, SellCostMod))*item->SellRate);
|
inst2->SetPrice(price);
|
||||||
inst2->SetMerchantSlot(freeslot);
|
inst2->SetMerchantSlot(freeslot);
|
||||||
|
|
||||||
uint32 MerchantQuantity = zone->GetTempMerchantQuantity(vendor->GetNPCTypeID(), freeslot);
|
uint32 merchant_quantity = zone->GetTempMerchantQuantity(vendor->GetNPCTypeID(), freeslot);
|
||||||
|
|
||||||
if (inst2->IsStackable()) {
|
if (inst2->IsStackable()) {
|
||||||
inst2->SetCharges(MerchantQuantity);
|
inst2->SetCharges(merchant_quantity);
|
||||||
}
|
}
|
||||||
inst2->SetMerchantCount(MerchantQuantity);
|
|
||||||
|
inst2->SetMerchantCount(merchant_quantity);
|
||||||
|
|
||||||
SendItemPacket(freeslot - 1, inst2, ItemPacketMerchant);
|
SendItemPacket(freeslot - 1, inst2, ItemPacketMerchant);
|
||||||
safe_delete(inst2);
|
safe_delete(inst2);
|
||||||
@ -13431,6 +13448,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// start QS code
|
// start QS code
|
||||||
if (RuleB(QueryServ, PlayerLogMerchantTransactions)) {
|
if (RuleB(QueryServ, PlayerLogMerchantTransactions)) {
|
||||||
|
|||||||
354
zone/corpse.cpp
354
zone/corpse.cpp
@ -30,6 +30,7 @@ Child of the Mob class.
|
|||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../common/data_verification.h"
|
||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "../common/eqemu_logsys.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
@ -148,14 +149,70 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
|
|||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime)
|
Corpse::Corpse(
|
||||||
// vesuvias - appearence fix
|
NPC *in_npc,
|
||||||
: Mob("Unnamed_Corpse","",0,0,in_npc->GetGender(),in_npc->GetRace(),in_npc->GetClass(),BT_Humanoid,//bodytype added
|
ItemList *in_itemlist,
|
||||||
in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0,
|
uint32 in_npctypeid,
|
||||||
in_npc->GetPosition(), in_npc->GetInnateLightType(), in_npc->GetTexture(),in_npc->GetHelmTexture(),
|
const NPCType **in_npctypedata,
|
||||||
0,0,0,0,0,0,0,0,0,
|
uint32 in_decaytime
|
||||||
0,0,0,0,0,0,0,0,0,0,EQ::TintProfile(),0xff,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
) : Mob(
|
||||||
(*in_npctypedata)->use_model, false),
|
"Unnamed_Corpse", // in_name
|
||||||
|
"", // in_lastname
|
||||||
|
0, // in_cur_hp
|
||||||
|
0, // in_max_hp
|
||||||
|
in_npc->GetGender(), // in_gender
|
||||||
|
in_npc->GetRace(), // in_race
|
||||||
|
in_npc->GetClass(), // in_class
|
||||||
|
BT_Humanoid, // in_bodytype
|
||||||
|
in_npc->GetDeity(), // in_deity
|
||||||
|
in_npc->GetLevel(), // in_level
|
||||||
|
in_npc->GetNPCTypeID(), // in_npctype_id
|
||||||
|
in_npc->GetSize(), // in_size
|
||||||
|
0.0f, // in_runspeed
|
||||||
|
in_npc->GetPosition(), // position
|
||||||
|
in_npc->GetInnateLightType(), // in_light
|
||||||
|
in_npc->GetTexture(), // in_texture
|
||||||
|
in_npc->GetHelmTexture(), // in_helmtexture
|
||||||
|
0, // in_ac
|
||||||
|
0, // in_atk
|
||||||
|
0, // in_str
|
||||||
|
0, // in_sta
|
||||||
|
0, // in_dex
|
||||||
|
0, // in_agi
|
||||||
|
0, // in_int
|
||||||
|
0, // in_wis
|
||||||
|
0, // in_cha
|
||||||
|
0, // in_haircolor
|
||||||
|
0, // in_beardcolor
|
||||||
|
0, // in_eyecolor1
|
||||||
|
0, // in_eyecolor2
|
||||||
|
0, // in_hairstyle
|
||||||
|
0, // in_luclinface
|
||||||
|
0, // in_beard
|
||||||
|
0, // in_drakkin_heritage
|
||||||
|
0, // in_drakkin_tattoo
|
||||||
|
0, // in_drakkin_details
|
||||||
|
EQ::TintProfile(), // in_armor_tint
|
||||||
|
0xFF, // in_aa_title
|
||||||
|
0, // in_see_invis
|
||||||
|
0, // in_see_invis_undead
|
||||||
|
0, // in_see_hide
|
||||||
|
0, // in_see_improved_hide
|
||||||
|
0, // in_hp_regen
|
||||||
|
0, // in_mana_regen
|
||||||
|
0, // in_qglobal
|
||||||
|
0, // in_maxlevel
|
||||||
|
0, // in_scalerate
|
||||||
|
0, // in_armtexture
|
||||||
|
0, // in_bracertexture
|
||||||
|
0, // in_handtexture
|
||||||
|
0, // in_legtexture
|
||||||
|
0, // in_feettexture
|
||||||
|
(*in_npctypedata)->use_model, // in_usemodel
|
||||||
|
false, // in_always_aggros_foes
|
||||||
|
0, // in_heroic_strikethrough
|
||||||
|
false // in_keeps_sold_items
|
||||||
|
),
|
||||||
corpse_decay_timer(in_decaytime),
|
corpse_decay_timer(in_decaytime),
|
||||||
corpse_rez_timer(0),
|
corpse_rez_timer(0),
|
||||||
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
|
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
|
||||||
@ -184,11 +241,18 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
|||||||
strcpy(name, in_npc->GetName());
|
strcpy(name, in_npc->GetName());
|
||||||
|
|
||||||
for(int count = 0; count < 100; count++) {
|
for(int count = 0; count < 100; count++) {
|
||||||
if ((level >= npcCorpseDecayTimes[count].minlvl) && (level <= npcCorpseDecayTimes[count].maxlvl)) {
|
if (
|
||||||
|
EQ::ValueWithin(
|
||||||
|
level,
|
||||||
|
npcCorpseDecayTimes[count].minlvl,
|
||||||
|
npcCorpseDecayTimes[count].maxlvl
|
||||||
|
)
|
||||||
|
) {
|
||||||
corpse_decay_timer.SetTimer(npcCorpseDecayTimes[count].seconds*1000);
|
corpse_decay_timer.SetTimer(npcCorpseDecayTimes[count].seconds*1000);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsEmpty()) {
|
if (IsEmpty()) {
|
||||||
corpse_decay_timer.SetTimer(RuleI(NPC,EmptyNPCCorpseDecayTimeMS)+1000);
|
corpse_decay_timer.SetTimer(RuleI(NPC,EmptyNPCCorpseDecayTimeMS)+1000);
|
||||||
}
|
}
|
||||||
@ -201,6 +265,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
|||||||
for (int i = 0; i < MAX_LOOTERS; i++){
|
for (int i = 0; i < MAX_LOOTERS; i++){
|
||||||
allowed_looters[i] = 0;
|
allowed_looters[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rez_experience = 0;
|
rez_experience = 0;
|
||||||
|
|
||||||
UpdateEquipmentLight();
|
UpdateEquipmentLight();
|
||||||
@ -210,61 +275,62 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
|||||||
}
|
}
|
||||||
|
|
||||||
Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||||
"Unnamed_Corpse", // const char* in_name,
|
"Unnamed_Corpse", // in_name
|
||||||
"", // const char* in_lastname,
|
"", // in_lastname
|
||||||
0, // int32 in_cur_hp,
|
0, // in_cur_hp
|
||||||
0, // int32 in_max_hp,
|
0, // in_max_hp
|
||||||
client->GetGender(), // uint8 in_gender,
|
client->GetGender(), // in_gender
|
||||||
client->GetRace(), // uint16 in_race,
|
client->GetRace(), // in_race
|
||||||
client->GetClass(), // uint8 in_class,
|
client->GetClass(), // in_class
|
||||||
BT_Humanoid, // bodyType in_bodytype,
|
BT_Humanoid, // in_bodytype
|
||||||
client->GetDeity(), // uint8 in_deity,
|
client->GetDeity(), // in_deity
|
||||||
client->GetLevel(), // uint8 in_level,
|
client->GetLevel(), // in_level
|
||||||
0, // uint32 in_npctype_id,
|
0, // in_npctype_id
|
||||||
client->GetSize(), // float in_size,
|
client->GetSize(), // in_size
|
||||||
0, // float in_runspeed,
|
0, // in_runspeed
|
||||||
client->GetPosition(),
|
client->GetPosition(), // position
|
||||||
client->GetInnateLightType(), // uint8 in_light, - verified for client innate_light value
|
client->GetInnateLightType(), // in_light
|
||||||
client->GetTexture(), // uint8 in_texture,
|
client->GetTexture(), // in_texture
|
||||||
client->GetHelmTexture(), // uint8 in_helmtexture,
|
client->GetHelmTexture(), // in_helmtexture
|
||||||
0, // uint16 in_ac,
|
0, // in_ac
|
||||||
0, // uint16 in_atk,
|
0, // in_atk
|
||||||
0, // uint16 in_str,
|
0, // in_str
|
||||||
0, // uint16 in_sta,
|
0, // in_sta
|
||||||
0, // uint16 in_dex,
|
0, // in_dex
|
||||||
0, // uint16 in_agi,
|
0, // in_agi
|
||||||
0, // uint16 in_int,
|
0, // in_int
|
||||||
0, // uint16 in_wis,
|
0, // in_wis
|
||||||
0, // uint16 in_cha,
|
0, // in_cha
|
||||||
client->GetPP().haircolor, // uint8 in_haircolor,
|
client->GetPP().haircolor, // in_haircolor
|
||||||
client->GetPP().beardcolor, // uint8 in_beardcolor,
|
client->GetPP().beardcolor, // in_beardcolor
|
||||||
client->GetPP().eyecolor1, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye?
|
client->GetPP().eyecolor1, // in_eyecolor1
|
||||||
client->GetPP().eyecolor2, // uint8 in_eyecolor2,
|
client->GetPP().eyecolor2, // in_eyecolor2
|
||||||
client->GetPP().hairstyle, // uint8 in_hairstyle,
|
client->GetPP().hairstyle, // in_hairstyle
|
||||||
client->GetPP().face, // uint8 in_luclinface,
|
client->GetPP().face, // in_luclinface
|
||||||
client->GetPP().beard, // uint8 in_beard,
|
client->GetPP().beard, // in_beard
|
||||||
client->GetPP().drakkin_heritage, // uint32 in_drakkin_heritage,
|
client->GetPP().drakkin_heritage, // in_drakkin_heritage
|
||||||
client->GetPP().drakkin_tattoo, // uint32 in_drakkin_tattoo,
|
client->GetPP().drakkin_tattoo, // in_drakkin_tattoo
|
||||||
client->GetPP().drakkin_details, // uint32 in_drakkin_details,
|
client->GetPP().drakkin_details, // in_drakkin_details
|
||||||
EQ::TintProfile(), // uint32 in_armor_tint[_MaterialCount],
|
EQ::TintProfile(), // in_armor_tint
|
||||||
0xff, // uint8 in_aa_title,
|
0xff, // in_aa_title
|
||||||
0, // uint8 in_see_invis, // see through invis
|
0, // in_see_invis
|
||||||
0, // uint8 in_see_invis_undead, // see through invis vs. undead
|
0, // in_see_invis_undead
|
||||||
0, // uint8 in_see_hide,
|
0, // in_see_hide
|
||||||
0, // uint8 in_see_improved_hide,
|
0, // in_see_improved_hide
|
||||||
0, // int32 in_hp_regen,
|
0, // in_hp_regen
|
||||||
0, // int32 in_mana_regen,
|
0, // in_mana_regen
|
||||||
0, // uint8 in_qglobal,
|
0, // in_qglobal
|
||||||
0, // uint8 in_maxlevel,
|
0, // in_maxlevel
|
||||||
0, // uint32 in_scalerate
|
0, // in_scalerate
|
||||||
0, // uint8 in_armtexture,
|
0, // in_armtexture
|
||||||
0, // uint8 in_bracertexture,
|
0, // in_bracertexture
|
||||||
0, // uint8 in_handtexture,
|
0, // in_handtexture
|
||||||
0, // uint8 in_legtexture,
|
0, // in_legtexture
|
||||||
0, // uint8 in_feettexture,
|
0, // in_feettexture
|
||||||
0, // uint8 in_usemodel,
|
0, // in_usemodel
|
||||||
0, // bool in_always_aggro,
|
false, // in_always_aggro
|
||||||
0 // Int32 in_heroic_strikethrough
|
0, // in_heroic_strikethrough
|
||||||
|
false // in_keeps_sold_items
|
||||||
),
|
),
|
||||||
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
|
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
|
||||||
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
|
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
|
||||||
@ -272,28 +338,25 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
|||||||
corpse_graveyard_timer(RuleI(Zone, GraveyardTimeMS)),
|
corpse_graveyard_timer(RuleI(Zone, GraveyardTimeMS)),
|
||||||
loot_cooldown_timer(10)
|
loot_cooldown_timer(10)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
PlayerProfile_Struct *pp = &client->GetPP();
|
PlayerProfile_Struct *pp = &client->GetPP();
|
||||||
EQ::ItemInstance *item = nullptr;
|
EQ::ItemInstance *item = nullptr;
|
||||||
|
|
||||||
/* Check if Zone has Graveyard First */
|
|
||||||
if (!zone->HasGraveyard()) {
|
if (!zone->HasGraveyard()) {
|
||||||
corpse_graveyard_timer.Disable();
|
corpse_graveyard_timer.Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAX_LOOTERS; i++){
|
for (int i = 0; i < MAX_LOOTERS; i++){
|
||||||
allowed_looters[i] = 0;
|
allowed_looters[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->AutoConsentGroupEnabled()) {
|
if (client->AutoConsentGroupEnabled()) {
|
||||||
Group* grp = client->GetGroup();
|
auto* g = client->GetGroup();
|
||||||
consented_group_id = grp ? grp->GetID() : 0;
|
consented_group_id = g ? g->GetID() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->AutoConsentRaidEnabled()) {
|
if (client->AutoConsentRaidEnabled()) {
|
||||||
Raid* raid = client->GetRaid();
|
auto* r = client->GetRaid();
|
||||||
consented_raid_id = raid ? raid->GetID() : 0;
|
consented_raid_id = r ? r->GetID() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
consented_guild_id = client->AutoConsentGuildEnabled() ? client->GuildID() : 0;
|
consented_guild_id = client->AutoConsentGuildEnabled() ? client->GuildID() : 0;
|
||||||
@ -321,13 +384,18 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
|||||||
SetPlayerKillItemID(0);
|
SetPlayerKillItemID(0);
|
||||||
|
|
||||||
/* Check Rule to see if we can leave corpses */
|
/* Check Rule to see if we can leave corpses */
|
||||||
if(!RuleB(Character, LeaveNakedCorpses) ||
|
if (
|
||||||
|
!RuleB(Character, LeaveNakedCorpses) ||
|
||||||
RuleB(Character, LeaveCorpses) &&
|
RuleB(Character, LeaveCorpses) &&
|
||||||
GetLevel() >= RuleI(Character, DeathItemLossLevel)) {
|
GetLevel() >= RuleI(Character, DeathItemLossLevel)
|
||||||
|
) {
|
||||||
// cash
|
// cash
|
||||||
// Let's not move the cash when 'RespawnFromHover = true' && 'client->GetClientVersion() < EQClientSoF' since the client doesn't.
|
// Let's not move the cash when 'RespawnFromHover = true' && 'client->GetClientVersion() < EQClientSoF' since the client doesn't.
|
||||||
// (change to first client that supports 'death hover' mode, if not SoF.)
|
// (change to first client that supports 'death hover' mode, if not SoF.)
|
||||||
if (!RuleB(Character, RespawnFromHover) || client->ClientVersion() < EQ::versions::ClientVersion::SoF) {
|
if (
|
||||||
|
!RuleB(Character, RespawnFromHover) ||
|
||||||
|
client->ClientVersion() < EQ::versions::ClientVersion::SoF
|
||||||
|
) {
|
||||||
SetCash(pp->copper, pp->silver, pp->gold, pp->platinum);
|
SetCash(pp->copper, pp->silver, pp->gold, pp->platinum);
|
||||||
pp->copper = 0;
|
pp->copper = 0;
|
||||||
pp->silver = 0;
|
pp->silver = 0;
|
||||||
@ -346,13 +414,22 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
|||||||
// ..then regress and process invslot::EQUIPMENT_BEGIN through invslot::EQUIPMENT_END...
|
// ..then regress and process invslot::EQUIPMENT_BEGIN through invslot::EQUIPMENT_END...
|
||||||
// without additional work to database loading of player corpses, this order is not
|
// without additional work to database loading of player corpses, this order is not
|
||||||
// currently preserved and a re-work of this processing loop is not warranted.
|
// currently preserved and a re-work of this processing loop is not warranted.
|
||||||
for (i = EQ::invslot::POSSESSIONS_BEGIN; i <= EQ::invslot::POSSESSIONS_END; ++i) {
|
for (int i = EQ::invslot::POSSESSIONS_BEGIN; i <= EQ::invslot::POSSESSIONS_END; ++i) {
|
||||||
item = client->GetInv().GetItem(i);
|
item = client->GetInv().GetItem(i);
|
||||||
if (item == nullptr) { continue; }
|
if (!item) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(!client->IsBecomeNPC() || (client->IsBecomeNPC() && !item->GetItem()->NoRent))
|
if (
|
||||||
|
!client->IsBecomeNPC() ||
|
||||||
|
(
|
||||||
|
client->IsBecomeNPC() &&
|
||||||
|
!item->GetItem()->NoRent
|
||||||
|
)
|
||||||
|
) {
|
||||||
MoveItemToCorpse(client, item, i, removed_list);
|
MoveItemToCorpse(client, item, i, removed_list);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
database.TransactionBegin();
|
database.TransactionBegin();
|
||||||
|
|
||||||
@ -393,7 +470,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
|||||||
UpdateActiveLight();
|
UpdateActiveLight();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} //end "not leaving naked corpses"
|
}
|
||||||
|
|
||||||
UpdateEquipmentLight();
|
UpdateEquipmentLight();
|
||||||
UpdateActiveLight();
|
UpdateActiveLight();
|
||||||
@ -450,73 +527,75 @@ void Corpse::MoveItemToCorpse(Client *client, EQ::ItemInstance *inst, int16 equi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// To be called from LoadFromDBData
|
// To be called from LoadFromDBData
|
||||||
Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, const glm::vec4& position, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard)
|
Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, const glm::vec4& position, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard) : Mob(
|
||||||
: Mob("Unnamed_Corpse",
|
"Unnamed_Corpse", // in_name
|
||||||
"",
|
"", // in_lastname
|
||||||
0,
|
0, // in_cur_hp
|
||||||
0,
|
0, // in_max_hp
|
||||||
in_gender,
|
in_gender, // in_gender
|
||||||
in_race,
|
in_race, // in_race
|
||||||
in_class,
|
in_class, // in_class
|
||||||
BT_Humanoid,
|
BT_Humanoid, // in_bodytype
|
||||||
in_deity,
|
in_deity, // in_deity
|
||||||
in_level,
|
in_level, // in_level
|
||||||
0,
|
0, // in_npctype_id
|
||||||
in_size,
|
in_size, // in_size
|
||||||
0,
|
0.0f, // in_runspeed
|
||||||
position,
|
position, // position
|
||||||
0, // verified for client innate_light value
|
0, // in_light
|
||||||
in_texture,
|
in_texture, // in_texture
|
||||||
in_helmtexture,
|
in_helmtexture, // in_helmtexture
|
||||||
0,
|
0, // in_ac
|
||||||
0,
|
0, // in_atk
|
||||||
0,
|
0, // in_str
|
||||||
0,
|
0, // in_sta
|
||||||
0,
|
0, // in_dex
|
||||||
0,
|
0, // in_agi
|
||||||
0,
|
0, // in_int
|
||||||
0,
|
0, // in_wis
|
||||||
0,
|
0, // in_cha
|
||||||
0,
|
0, // in_haircolor
|
||||||
0,
|
0, // in_beardcolor
|
||||||
0,
|
0, // in_eyecolor1
|
||||||
0,
|
0, // in_eyecolor2
|
||||||
0,
|
0, // in_hairstyle
|
||||||
0,
|
0, // in_luclinface
|
||||||
0,
|
0, // in_beard
|
||||||
0,
|
0, // in_drakkin_heritage
|
||||||
0,
|
0, // in_drakkin_tattoo
|
||||||
0,
|
0, // in_drakkin_details
|
||||||
EQ::TintProfile(),
|
EQ::TintProfile(), // in_armor_tint
|
||||||
0xff,
|
0xFF, // in_aa_title
|
||||||
0,
|
0, // in_see_invis
|
||||||
0,
|
0, // in_see_invis_undead
|
||||||
0,
|
0, // in_see_hide
|
||||||
0,
|
0, // in_see_improved_hide
|
||||||
0,
|
0, // in_hp_regen
|
||||||
0,
|
0, // in_mana_regen
|
||||||
0,
|
0, // in_qglobal
|
||||||
0,
|
0, // in_maxlevel
|
||||||
0,
|
0, // in_scalerate
|
||||||
0,
|
0, // in_armtexture
|
||||||
0,
|
0, // in_bracertexture
|
||||||
0,
|
0, // in_handtexture
|
||||||
0,
|
0, // in_legtexture
|
||||||
0,
|
0, // in_feettexture
|
||||||
0,
|
0, // in_usemodel
|
||||||
0,
|
false, // in_always_aggros_foes
|
||||||
false),
|
0, // in_heroic_strikethrough
|
||||||
|
false // in_keeps_sold_items
|
||||||
|
),
|
||||||
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
|
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
|
||||||
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
|
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
|
||||||
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
|
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
|
||||||
corpse_graveyard_timer(RuleI(Zone, GraveyardTimeMS)),
|
corpse_graveyard_timer(RuleI(Zone, GraveyardTimeMS)),
|
||||||
loot_cooldown_timer(10)
|
loot_cooldown_timer(10)
|
||||||
{
|
{
|
||||||
|
|
||||||
LoadPlayerCorpseDecayTime(in_dbid);
|
LoadPlayerCorpseDecayTime(in_dbid);
|
||||||
|
|
||||||
if (!zone->HasGraveyard() || wasAtGraveyard)
|
if (!zone->HasGraveyard() || wasAtGraveyard) {
|
||||||
corpse_graveyard_timer.Disable();
|
corpse_graveyard_timer.Disable();
|
||||||
|
}
|
||||||
|
|
||||||
is_corpse_changed = false;
|
is_corpse_changed = false;
|
||||||
is_player_corpse = true;
|
is_player_corpse = true;
|
||||||
@ -541,6 +620,7 @@ false),
|
|||||||
for (int i = 0; i < MAX_LOOTERS; i++){
|
for (int i = 0; i < MAX_LOOTERS; i++){
|
||||||
allowed_looters[i] = 0;
|
allowed_looters[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPlayerKillItemID(0);
|
SetPlayerKillItemID(0);
|
||||||
|
|
||||||
UpdateEquipmentLight();
|
UpdateEquipmentLight();
|
||||||
|
|||||||
@ -32,13 +32,64 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
class Zone;
|
class Zone;
|
||||||
|
|
||||||
Encounter::Encounter(const char* enc_name)
|
Encounter::Encounter(const char *enc_name) : Mob(
|
||||||
:Mob
|
nullptr, // in_name
|
||||||
(
|
nullptr, // in_lastname
|
||||||
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, glm::vec4(0,0,0,0), 0, 0, 0,
|
0, // in_cur_hp
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQ::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false
|
0, // in_max_hp
|
||||||
)
|
MALE, // in_gender
|
||||||
{
|
INVISIBLE_MAN, // in_race
|
||||||
|
0, // in_class
|
||||||
|
BT_NoTarget, // in_bodytype
|
||||||
|
0, // in_deity
|
||||||
|
0, // in_level
|
||||||
|
0, // in_npcype_id
|
||||||
|
0, // in_size
|
||||||
|
0, // in_runspeed
|
||||||
|
glm::vec4(0, 0, 0, 0), // position
|
||||||
|
0, // in_light
|
||||||
|
0, // in_texture
|
||||||
|
0, // in_helmtexture
|
||||||
|
0, // in_ac
|
||||||
|
0, // in_atk
|
||||||
|
0, // in_str
|
||||||
|
0, // in_sta
|
||||||
|
0, // in_dex
|
||||||
|
0, // in_agi
|
||||||
|
0, // in_int
|
||||||
|
0, // in_wis
|
||||||
|
0, // in_cha
|
||||||
|
0, // in_haircolor
|
||||||
|
0, // in_beardcolor
|
||||||
|
0, // in_eyecolor1
|
||||||
|
0, // in_eyecolor2
|
||||||
|
0, // in_hairstyle
|
||||||
|
0, // in_luclinface
|
||||||
|
0, // in_beard
|
||||||
|
0, // in_drakkin_heritage
|
||||||
|
0, // in_drakkin_tattoo
|
||||||
|
0, // in_drakkin_details
|
||||||
|
EQ::TintProfile(), // in_armor_tint
|
||||||
|
0, // in_aa_title
|
||||||
|
0, // in_see_invis
|
||||||
|
0, // in_see_invis_undead
|
||||||
|
0, // in_see_hide
|
||||||
|
0, // in_see_improved_hide
|
||||||
|
0, // in_hp_regen
|
||||||
|
0, // in_mana_regen
|
||||||
|
0, // in_qglobal
|
||||||
|
0, // in_maxlevel
|
||||||
|
0, // in_scalerate
|
||||||
|
0, // in_armtexture
|
||||||
|
0, // in_bracertexture
|
||||||
|
0, // in_handtexture
|
||||||
|
0, // in_legtexture
|
||||||
|
0, // in_feettexture
|
||||||
|
0, // in_usemodel
|
||||||
|
false, // in_always_aggros_foes
|
||||||
|
0, // in_heroic_strikethrough
|
||||||
|
false // in_keeps_sold_items
|
||||||
|
) {
|
||||||
encounter_name[0] = 0;
|
encounter_name[0] = 0;
|
||||||
strn0cpy(encounter_name, enc_name, 64);
|
strn0cpy(encounter_name, enc_name, 64);
|
||||||
remove_me = false;
|
remove_me = false;
|
||||||
|
|||||||
@ -76,6 +76,7 @@ std::map<std::string, std::string> GetModifyNPCStatMap()
|
|||||||
{ "hp_regen_per_second", "HP Regen Per Second" },
|
{ "hp_regen_per_second", "HP Regen Per Second" },
|
||||||
{ "int", "Intelligence" },
|
{ "int", "Intelligence" },
|
||||||
{ "_int", "Intelligence" },
|
{ "_int", "Intelligence" },
|
||||||
|
{ "keeps_sold_items", "Keeps Sold Items" },
|
||||||
{ "level", "Level" },
|
{ "level", "Level" },
|
||||||
{ "loottable_id", "Loottable ID" },
|
{ "loottable_id", "Loottable ID" },
|
||||||
{ "mana_regen", "Mana Regen" },
|
{ "mana_regen", "Mana Regen" },
|
||||||
|
|||||||
@ -1491,6 +1491,22 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (!strcasecmp(sep->arg[1], "keeps_sold_items")) {
|
||||||
|
if (sep->IsNumber(2)) {
|
||||||
|
auto keeps_sold_items = static_cast<uint8_t>(std::stoul(sep->arg[2]));
|
||||||
|
n.keeps_sold_items = keeps_sold_items;
|
||||||
|
d = fmt::format(
|
||||||
|
"{} will {} Keep Sold Items.",
|
||||||
|
npc_id_string,
|
||||||
|
keeps_sold_items ? "now" : "no longer"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
"Usage: #npcedit keeps_sold_items [Flag] - Sets an NPC's Keeps Sold Items Flag [0 = False, 1 = True]"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else if (!strcasecmp(sep->arg[1], "setanimation")) {
|
} else if (!strcasecmp(sep->arg[1], "setanimation")) {
|
||||||
if (sep->IsNumber(2)) {
|
if (sep->IsNumber(2)) {
|
||||||
auto animation_id = std::stoul(sep->arg[2]);
|
auto animation_id = std::stoul(sep->arg[2]);
|
||||||
@ -1760,6 +1776,10 @@ void SendNPCEditSubCommands(Client *c)
|
|||||||
Chat::White,
|
Chat::White,
|
||||||
"Usage: #npcedit exp_mod [Modifier] - Sets an NPC's Experience Modifier [50 = 50%, 100 = 100%, 200 = 200%]"
|
"Usage: #npcedit exp_mod [Modifier] - Sets an NPC's Experience Modifier [50 = 50%, 100 = 100%, 200 = 200%]"
|
||||||
);
|
);
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
"Usage: #npcedit keeps_sold_items [Flag] - Sets an NPC's Keeps Sold Items Flag [0 = False, 1 = True]"
|
||||||
|
);
|
||||||
c->Message(
|
c->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
"Usage: #npcedit setanimation [Animation ID] - Sets an NPC's Animation on Spawn (Stored in spawn2 table)"
|
"Usage: #npcedit setanimation [Animation ID] - Sets an NPC's Animation on Spawn (Stored in spawn2 table)"
|
||||||
|
|||||||
@ -691,6 +691,16 @@ void Lua_NPC::SendPayload(int payload_id, std::string payload_value) {
|
|||||||
self->SendPayload(payload_id, payload_value);
|
self->SendPayload(payload_id, payload_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Lua_NPC::GetKeepsSoldItems() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->GetKeepsSoldItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetKeepsSoldItems(bool keeps_sold_items) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetKeepsSoldItems(keeps_sold_items);
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_npc() {
|
luabind::scope lua_register_npc() {
|
||||||
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
@ -736,6 +746,7 @@ luabind::scope lua_register_npc() {
|
|||||||
.def("GetGuardPointZ", (float(Lua_NPC::*)(void))&Lua_NPC::GetGuardPointZ)
|
.def("GetGuardPointZ", (float(Lua_NPC::*)(void))&Lua_NPC::GetGuardPointZ)
|
||||||
.def("GetHealScale", (float(Lua_NPC::*)(void))&Lua_NPC::GetHealScale)
|
.def("GetHealScale", (float(Lua_NPC::*)(void))&Lua_NPC::GetHealScale)
|
||||||
.def("GetItemIDBySlot", (uint32(Lua_NPC::*)(uint16))&Lua_NPC::GetItemIDBySlot)
|
.def("GetItemIDBySlot", (uint32(Lua_NPC::*)(uint16))&Lua_NPC::GetItemIDBySlot)
|
||||||
|
.def("GetKeepsSoldItems", (bool(Lua_NPC::*)(void))&Lua_NPC::GetKeepsSoldItems)
|
||||||
.def("GetLootList", (Lua_NPC_Loot_List(Lua_NPC::*)(lua_State* L))&Lua_NPC::GetLootList)
|
.def("GetLootList", (Lua_NPC_Loot_List(Lua_NPC::*)(lua_State* L))&Lua_NPC::GetLootList)
|
||||||
.def("GetLoottableID", (int(Lua_NPC::*)(void))&Lua_NPC::GetLoottableID)
|
.def("GetLoottableID", (int(Lua_NPC::*)(void))&Lua_NPC::GetLoottableID)
|
||||||
.def("GetMaxDMG", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetMaxDMG)
|
.def("GetMaxDMG", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetMaxDMG)
|
||||||
@ -805,6 +816,7 @@ luabind::scope lua_register_npc() {
|
|||||||
.def("SetFollowID", (void(Lua_NPC::*)(int))&Lua_NPC::SetFollowID)
|
.def("SetFollowID", (void(Lua_NPC::*)(int))&Lua_NPC::SetFollowID)
|
||||||
.def("SetGold", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetGold)
|
.def("SetGold", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetGold)
|
||||||
.def("SetGrid", (void(Lua_NPC::*)(int))&Lua_NPC::SetGrid)
|
.def("SetGrid", (void(Lua_NPC::*)(int))&Lua_NPC::SetGrid)
|
||||||
|
.def("SetKeepsSoldItems", (void(Lua_NPC::*)(bool))&Lua_NPC::SetKeepsSoldItems)
|
||||||
.def("SetNPCFactionID", (void(Lua_NPC::*)(int))&Lua_NPC::SetNPCFactionID)
|
.def("SetNPCFactionID", (void(Lua_NPC::*)(int))&Lua_NPC::SetNPCFactionID)
|
||||||
.def("SetPetSpellID", (void(Lua_NPC::*)(int))&Lua_NPC::SetPetSpellID)
|
.def("SetPetSpellID", (void(Lua_NPC::*)(int))&Lua_NPC::SetPetSpellID)
|
||||||
.def("SetPlatinum", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetPlatinum)
|
.def("SetPlatinum", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetPlatinum)
|
||||||
|
|||||||
@ -159,6 +159,8 @@ public:
|
|||||||
float GetNPCStat(std::string stat);
|
float GetNPCStat(std::string stat);
|
||||||
void SendPayload(int payload_id);
|
void SendPayload(int payload_id);
|
||||||
void SendPayload(int payload_id, std::string payload_value);
|
void SendPayload(int payload_id, std::string payload_value);
|
||||||
|
bool GetKeepsSoldItems();
|
||||||
|
void SetKeepsSoldItems(bool keeps_sold_items);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -98,6 +98,7 @@ Mob::Mob(
|
|||||||
uint16 in_usemodel,
|
uint16 in_usemodel,
|
||||||
bool in_always_aggro,
|
bool in_always_aggro,
|
||||||
int32 in_heroic_strikethrough,
|
int32 in_heroic_strikethrough,
|
||||||
|
bool in_keeps_sold_items,
|
||||||
int64 in_hp_regen_per_second
|
int64 in_hp_regen_per_second
|
||||||
) :
|
) :
|
||||||
attack_timer(2000),
|
attack_timer(2000),
|
||||||
@ -285,6 +286,7 @@ Mob::Mob(
|
|||||||
rare_spawn = false;
|
rare_spawn = false;
|
||||||
always_aggro = in_always_aggro;
|
always_aggro = in_always_aggro;
|
||||||
heroic_strikethrough = in_heroic_strikethrough;
|
heroic_strikethrough = in_heroic_strikethrough;
|
||||||
|
keeps_sold_items = in_keeps_sold_items;
|
||||||
|
|
||||||
InitializeBuffSlots();
|
InitializeBuffSlots();
|
||||||
|
|
||||||
|
|||||||
@ -165,6 +165,7 @@ public:
|
|||||||
uint16 in_usemodel,
|
uint16 in_usemodel,
|
||||||
bool in_always_aggros_foes,
|
bool in_always_aggros_foes,
|
||||||
int32 in_heroic_strikethrough,
|
int32 in_heroic_strikethrough,
|
||||||
|
bool keeps_sold_items,
|
||||||
int64 in_hp_regen_per_second = 0
|
int64 in_hp_regen_per_second = 0
|
||||||
);
|
);
|
||||||
virtual ~Mob();
|
virtual ~Mob();
|
||||||
@ -653,6 +654,8 @@ public:
|
|||||||
bool IsControllableBoat() const;
|
bool IsControllableBoat() const;
|
||||||
inline const bool AlwaysAggro() const { return always_aggro; }
|
inline const bool AlwaysAggro() const { return always_aggro; }
|
||||||
inline int32 GetHeroicStrikethrough() const { return heroic_strikethrough; }
|
inline int32 GetHeroicStrikethrough() const { return heroic_strikethrough; }
|
||||||
|
inline const bool GetKeepsSoldItems() const { return keeps_sold_items; }
|
||||||
|
inline void SetKeepsSoldItems(bool in_keeps_sold_items) { keeps_sold_items = in_keeps_sold_items; }
|
||||||
|
|
||||||
void CopyHateList(Mob* to);
|
void CopyHateList(Mob* to);
|
||||||
|
|
||||||
@ -1531,6 +1534,7 @@ protected:
|
|||||||
bool no_target_hotkey;
|
bool no_target_hotkey;
|
||||||
bool rare_spawn;
|
bool rare_spawn;
|
||||||
int32 heroic_strikethrough;
|
int32 heroic_strikethrough;
|
||||||
|
bool keeps_sold_items;
|
||||||
|
|
||||||
uint32 m_PlayerState;
|
uint32 m_PlayerState;
|
||||||
uint32 GetPlayerState() { return m_PlayerState; }
|
uint32 GetPlayerState() { return m_PlayerState; }
|
||||||
|
|||||||
11
zone/npc.cpp
11
zone/npc.cpp
@ -121,7 +121,8 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
npc_type_data->use_model,
|
npc_type_data->use_model,
|
||||||
npc_type_data->always_aggro,
|
npc_type_data->always_aggro,
|
||||||
npc_type_data->hp_regen_per_second,
|
npc_type_data->hp_regen_per_second,
|
||||||
npc_type_data->heroic_strikethrough
|
npc_type_data->heroic_strikethrough,
|
||||||
|
npc_type_data->keeps_sold_items
|
||||||
),
|
),
|
||||||
attacked_timer(CombatEventTimer_expire),
|
attacked_timer(CombatEventTimer_expire),
|
||||||
swarm_timer(100),
|
swarm_timer(100),
|
||||||
@ -216,6 +217,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
avoidance_rating = npc_type_data->avoidance_rating;
|
avoidance_rating = npc_type_data->avoidance_rating;
|
||||||
ATK = npc_type_data->ATK;
|
ATK = npc_type_data->ATK;
|
||||||
heroic_strikethrough = npc_type_data->heroic_strikethrough;
|
heroic_strikethrough = npc_type_data->heroic_strikethrough;
|
||||||
|
keeps_sold_items = npc_type_data->keeps_sold_items;
|
||||||
|
|
||||||
// used for when switch back to charm
|
// used for when switch back to charm
|
||||||
default_ac = npc_type_data->AC;
|
default_ac = npc_type_data->AC;
|
||||||
@ -2672,6 +2674,10 @@ void NPC::ModifyNPCStat(std::string stat, std::string value)
|
|||||||
heroic_strikethrough = atoi(value.c_str());
|
heroic_strikethrough = atoi(value.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (stat_lower == "keeps_sold_items") {
|
||||||
|
SetKeepsSoldItems(Strings::ToBool(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float NPC::GetNPCStat(std::string stat)
|
float NPC::GetNPCStat(std::string stat)
|
||||||
@ -2813,6 +2819,9 @@ float NPC::GetNPCStat(std::string stat)
|
|||||||
else if (stat_lower == "heroic_strikethrough") {
|
else if (stat_lower == "heroic_strikethrough") {
|
||||||
return heroic_strikethrough;
|
return heroic_strikethrough;
|
||||||
}
|
}
|
||||||
|
else if (stat_lower == "keeps_sold_items") {
|
||||||
|
return keeps_sold_items;
|
||||||
|
}
|
||||||
//default values
|
//default values
|
||||||
else if (stat_lower == "default_ac") {
|
else if (stat_lower == "default_ac") {
|
||||||
return default_ac;
|
return default_ac;
|
||||||
|
|||||||
@ -680,6 +680,16 @@ void Perl_NPC_SendPayload(NPC* self, int payload_id, std::string payload_value)
|
|||||||
self->SendPayload(payload_id, payload_value);
|
self->SendPayload(payload_id, payload_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Perl_NPC_GetKeepsSoldItems(NPC* self)
|
||||||
|
{
|
||||||
|
return self->GetKeepsSoldItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Perl_NPC_SetKeepsSoldItems(NPC* self, bool keeps_sold_items)
|
||||||
|
{
|
||||||
|
self->SetKeepsSoldItems(keeps_sold_items);
|
||||||
|
}
|
||||||
|
|
||||||
void perl_register_npc()
|
void perl_register_npc()
|
||||||
{
|
{
|
||||||
perl::interpreter perl(PERL_GET_THX);
|
perl::interpreter perl(PERL_GET_THX);
|
||||||
@ -731,6 +741,7 @@ void perl_register_npc()
|
|||||||
package.add("GetGuardPointZ", &Perl_NPC_GetGuardPointZ);
|
package.add("GetGuardPointZ", &Perl_NPC_GetGuardPointZ);
|
||||||
package.add("GetHealScale", &Perl_NPC_GetHealScale);
|
package.add("GetHealScale", &Perl_NPC_GetHealScale);
|
||||||
package.add("GetItemIDBySlot", &Perl_NPC_GetItemIDBySlot);
|
package.add("GetItemIDBySlot", &Perl_NPC_GetItemIDBySlot);
|
||||||
|
package.add("GetKeepsSoldItems", &Perl_NPC_GetKeepsSoldItems);
|
||||||
package.add("GetLootList", &Perl_NPC_GetLootList);
|
package.add("GetLootList", &Perl_NPC_GetLootList);
|
||||||
package.add("GetLoottableID", &Perl_NPC_GetLoottableID);
|
package.add("GetLoottableID", &Perl_NPC_GetLoottableID);
|
||||||
package.add("GetMaxDMG", &Perl_NPC_GetMaxDMG);
|
package.add("GetMaxDMG", &Perl_NPC_GetMaxDMG);
|
||||||
@ -799,6 +810,7 @@ void perl_register_npc()
|
|||||||
package.add("SendPayload", (void(*)(NPC*, int))&Perl_NPC_SendPayload);
|
package.add("SendPayload", (void(*)(NPC*, int))&Perl_NPC_SendPayload);
|
||||||
package.add("SendPayload", (void(*)(NPC*, int, std::string))&Perl_NPC_SendPayload);
|
package.add("SendPayload", (void(*)(NPC*, int, std::string))&Perl_NPC_SendPayload);
|
||||||
package.add("SetCopper", &Perl_NPC_SetCopper);
|
package.add("SetCopper", &Perl_NPC_SetCopper);
|
||||||
|
package.add("SetKeepsSoldItems", &Perl_NPC_SetKeepsSoldItems);
|
||||||
package.add("SetGold", &Perl_NPC_SetGold);
|
package.add("SetGold", &Perl_NPC_SetGold);
|
||||||
package.add("SetGrid", &Perl_NPC_SetGrid);
|
package.add("SetGrid", &Perl_NPC_SetGrid);
|
||||||
package.add("SetNPCFactionID", &Perl_NPC_SetNPCFactionID);
|
package.add("SetNPCFactionID", &Perl_NPC_SetNPCFactionID);
|
||||||
|
|||||||
@ -2134,6 +2134,7 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
|||||||
t->hp_regen_per_second = n.hp_regen_per_second;
|
t->hp_regen_per_second = n.hp_regen_per_second;
|
||||||
t->heroic_strikethrough = n.heroic_strikethrough;
|
t->heroic_strikethrough = n.heroic_strikethrough;
|
||||||
t->faction_amount = n.faction_amount;
|
t->faction_amount = n.faction_amount;
|
||||||
|
t->keeps_sold_items = n.keeps_sold_items;
|
||||||
|
|
||||||
// If NPC with duplicate NPC id already in table,
|
// If NPC with duplicate NPC id already in table,
|
||||||
// free item we attempted to add.
|
// free item we attempted to add.
|
||||||
|
|||||||
@ -152,6 +152,7 @@ struct NPCType
|
|||||||
bool always_aggro;
|
bool always_aggro;
|
||||||
int exp_mod;
|
int exp_mod;
|
||||||
int heroic_strikethrough;
|
int heroic_strikethrough;
|
||||||
|
bool keeps_sold_items;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace player_lootitem {
|
namespace player_lootitem {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user