mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 01:11:29 +00:00
Implemented mob equipment light sources
This commit is contained in:
parent
7e980e1e7c
commit
cc1d7d54c2
@ -1,5 +1,13 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 01/24/2015 ==
|
||||
Uleat: Added equipment light source functionality to all mob derived classes (may still need tweaking...)
|
||||
Notes:
|
||||
- In addition to equipment light sources, innate npc type light sources have already been activated
|
||||
- Valid light source values are 0 thru 15 (values are bitmask checked and limited to 0x0F)
|
||||
- Not all classes handle equipment light sources the same way due to their equipment/loot list configurations
|
||||
- Spell (casting?) light sources may be implemented at some point..more information is needed
|
||||
|
||||
== 01/22/2015 ==
|
||||
Akkadius: Massive Log System overhaul, see: http://wiki.eqemulator.org/p?Logging_System_Overhaul&frm=Main
|
||||
|
||||
|
||||
@ -300,7 +300,7 @@ struct Spawn_Struct {
|
||||
/*0036*/ uint8 afk; // 0=no, 1=afk
|
||||
/*0238*/ uint32 guildID; // Current guild
|
||||
/*0242*/ char title[32]; // Title
|
||||
/*0274*/ uint8 unknown0274;
|
||||
/*0274*/ uint8 unknown0274; // non-zero prefixes name with '!'
|
||||
/*0275*/ uint8 set_to_0xFF[8]; // ***Placeholder (all ff)
|
||||
/*0283*/ uint8 helm; // Helm texture
|
||||
/*0284*/ uint32 race; // Spawn race
|
||||
|
||||
@ -990,6 +990,35 @@ int Inventory::GetSlotByItemInst(ItemInst *inst) {
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
uint8 Inventory::FindHighestLightValue()
|
||||
{
|
||||
uint8 light_value = NOT_USED;
|
||||
|
||||
// NOTE: The client does not recognize augment light sources, applied or otherwise, and should not be parsed
|
||||
for (auto iter = m_worn.begin(); iter != m_worn.end(); ++iter) {
|
||||
if ((iter->first < EmuConstants::EQUIPMENT_BEGIN || iter->first > EmuConstants::EQUIPMENT_END) && iter->first != MainPowerSource) { continue; }
|
||||
auto inst = iter->second;
|
||||
if (inst == nullptr) { continue; }
|
||||
auto item = inst->GetItem();
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > light_value) { light_value = item->Light; }
|
||||
}
|
||||
|
||||
for (auto iter = m_inv.begin(); iter != m_inv.end(); ++iter) {
|
||||
if (iter->first < EmuConstants::GENERAL_BEGIN || iter->first > EmuConstants::GENERAL_END) { continue; }
|
||||
auto inst = iter->second;
|
||||
if (inst == nullptr) { continue; }
|
||||
auto item = inst->GetItem();
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->ItemType != ItemTypeMisc && item->ItemType != ItemTypeLight) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > light_value) { light_value = item->Light; }
|
||||
}
|
||||
|
||||
return light_value;
|
||||
}
|
||||
|
||||
void Inventory::dumpEntireInventory() {
|
||||
|
||||
dumpWornItems();
|
||||
|
||||
@ -207,6 +207,8 @@ public:
|
||||
|
||||
int GetSlotByItemInst(ItemInst *inst);
|
||||
|
||||
uint8 FindHighestLightValue();
|
||||
|
||||
void dumpEntireInventory();
|
||||
void dumpWornItems();
|
||||
void dumpInventory();
|
||||
|
||||
24
zone/bot.cpp
24
zone/bot.cpp
@ -96,6 +96,8 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm
|
||||
}
|
||||
|
||||
strcpy(this->name, this->GetCleanName());
|
||||
|
||||
active_light = spell_light = equip_light = innate_light = NOT_USED;
|
||||
}
|
||||
|
||||
// This constructor is used when the bot is loaded out of the database
|
||||
@ -211,6 +213,8 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
||||
if(cur_mana > max_mana)
|
||||
cur_mana = max_mana;
|
||||
cur_end = max_end;
|
||||
|
||||
active_light = spell_light = equip_light = innate_light = NOT_USED;
|
||||
}
|
||||
|
||||
Bot::~Bot() {
|
||||
@ -380,6 +384,8 @@ NPCType Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::str
|
||||
BotNPCType.mana_regen = 1;
|
||||
BotNPCType.maxlevel = botLevel;
|
||||
|
||||
BotNPCType.light = NOT_USED; // due to the way that bots are coded..this is sent post-spawn
|
||||
|
||||
return BotNPCType;
|
||||
}
|
||||
|
||||
@ -4115,6 +4121,9 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) {
|
||||
// Level the bot to the same level as the bot owner
|
||||
//this->SetLevel(botCharacterOwner->GetLevel());
|
||||
|
||||
UpdateEquipLightValue();
|
||||
UpdateActiveLightValue();
|
||||
|
||||
entity_list.AddBot(this, true, true);
|
||||
|
||||
// Load pet
|
||||
@ -4178,6 +4187,7 @@ void Bot::RemoveBotItemBySlot(uint32 slotID, std::string *errorMessage) {
|
||||
*errorMessage = std::string(results.ErrorMessage());
|
||||
|
||||
m_inv.DeleteItem(slotID);
|
||||
UpdateEquipLightValue();
|
||||
}
|
||||
|
||||
// Retrieves all the inventory records from the database for this bot.
|
||||
@ -4239,6 +4249,7 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
|
||||
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
}
|
||||
|
||||
// Returns the inventory record for this bot from the database for the specified equipment slot.
|
||||
@ -4364,6 +4375,9 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
||||
ns->spawn.size = 0;
|
||||
ns->spawn.NPC = 0; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||
|
||||
UpdateActiveLightValue();
|
||||
ns->spawn.light = active_light;
|
||||
|
||||
ns->spawn.helm = helmtexture; //0xFF;
|
||||
ns->spawn.equip_chest2 = texture; //0xFF;
|
||||
|
||||
@ -5073,6 +5087,10 @@ void Bot::BotAddEquipItem(int slot, uint32 id) {
|
||||
equipment[slot] = id; // npc has more than just material slots. Valid material should mean valid inventory index
|
||||
SendWearChange(materialFromSlot);
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -5087,6 +5105,10 @@ void Bot::BotRemoveEquipItem(int slot) {
|
||||
if(materialFromSlot == MaterialChest)
|
||||
SendWearChange(MaterialArms);
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -8384,6 +8406,8 @@ void Bot::EquipBot(std::string* errorMessage) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
}
|
||||
|
||||
//// This method is meant to be called by zone or client methods to clean up objects when a client camps, goes LD, zones out or something like that.
|
||||
|
||||
@ -332,6 +332,7 @@ public:
|
||||
void EquipBot(std::string* errorMessage);
|
||||
bool CheckLoreConflict(const Item_Struct* item);
|
||||
uint32 GetEquipmentColor(uint8 material_slot) const;
|
||||
virtual void UpdateEquipLightValue() { equip_light = m_inv.FindHighestLightValue(); }
|
||||
|
||||
// Static Class Methods
|
||||
static void SaveBotGroup(Group* botGroup, std::string botGroupName, std::string* errorMessage);
|
||||
|
||||
@ -75,7 +75,7 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
0, // size
|
||||
0.7, // runspeed
|
||||
glm::vec4(),
|
||||
0, // light
|
||||
0, // light - verified for client innate_light value
|
||||
0xFF, // texture
|
||||
0xFF, // helmtexture
|
||||
0, // ac
|
||||
@ -302,6 +302,9 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
SavedRaidRestTimer = 0;
|
||||
|
||||
interrogateinv_flag = false;
|
||||
|
||||
active_light = innate_light;
|
||||
spell_light = equip_light = NOT_USED;
|
||||
}
|
||||
|
||||
Client::~Client() {
|
||||
@ -1795,6 +1798,9 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
ns->spawn.runspeed = (gmspeed == 0) ? runspeed : 3.125f;
|
||||
ns->spawn.showhelm = m_pp.showhelm ? 1 : 0;
|
||||
|
||||
UpdateEquipLightValue();
|
||||
UpdateActiveLightValue();
|
||||
ns->spawn.light = active_light;
|
||||
}
|
||||
|
||||
bool Client::GMHideMe(Client* client) {
|
||||
|
||||
@ -728,6 +728,7 @@ public:
|
||||
#endif
|
||||
uint32 GetEquipment(uint8 material_slot) const; // returns item id
|
||||
uint32 GetEquipmentColor(uint8 material_slot) const;
|
||||
virtual void UpdateEquipLightValue() { equip_light = m_inv.FindHighestLightValue(); }
|
||||
|
||||
inline bool AutoSplitEnabled() { return m_pp.autosplit != 0; }
|
||||
|
||||
|
||||
@ -731,12 +731,21 @@ void Client::CompleteConnect()
|
||||
entity_list.SendUntargetable(this);
|
||||
|
||||
int x;
|
||||
for (x = 0; x < 8; x++)
|
||||
for (x = 0; x < 8; x++) {
|
||||
SendWearChange(x);
|
||||
}
|
||||
// added due to wear change above
|
||||
UpdateActiveLightValue();
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
|
||||
Mob *pet = GetPet();
|
||||
if (pet != nullptr) {
|
||||
for (x = 0; x < 8; x++)
|
||||
for (x = 0; x < 8; x++) {
|
||||
pet->SendWearChange(x);
|
||||
}
|
||||
// added due to wear change above
|
||||
pet->UpdateActiveLightValue();
|
||||
pet->SendAppearancePacket(AT_Light, pet->GetActiveLightValue());
|
||||
}
|
||||
|
||||
entity_list.SendTraders(this);
|
||||
|
||||
@ -4383,7 +4383,7 @@ void command_time(Client *c, const Seperator *sep)
|
||||
zone->zone_time.getEQTimeZoneHr(),
|
||||
zone->zone_time.getEQTimeZoneMin()
|
||||
);
|
||||
c->Message(13, "It is now %s.", timeMessage);
|
||||
c->Message(13, "It is now %s.", timeMessage);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Current Time is: %s", timeMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,6 +137,10 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
|
||||
pc->IsRezzed(rezzed);
|
||||
pc->become_npc = false;
|
||||
|
||||
pc->spell_light = pc->innate_light = NOT_USED;
|
||||
pc->UpdateEquipLightValue();
|
||||
//pc->UpdateActiveLightValue();
|
||||
|
||||
safe_delete_array(pcs);
|
||||
|
||||
return pc;
|
||||
@ -146,7 +150,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
||||
// vesuvias - appearence fix
|
||||
: Mob("Unnamed_Corpse","",0,0,in_npc->GetGender(),in_npc->GetRace(),in_npc->GetClass(),BT_Humanoid,//bodytype added
|
||||
in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0,
|
||||
in_npc->GetPosition(), 0, in_npc->GetTexture(),in_npc->GetHelmTexture(),
|
||||
in_npc->GetPosition(), in_npc->GetInnateLightValue(), in_npc->GetTexture(),in_npc->GetHelmTexture(),
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0),
|
||||
corpse_decay_timer(in_decaytime),
|
||||
@ -197,6 +201,10 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
||||
allowed_looters[i] = 0;
|
||||
}
|
||||
this->rez_experience = 0;
|
||||
|
||||
UpdateEquipLightValue();
|
||||
spell_light = NOT_USED;
|
||||
UpdateActiveLightValue();
|
||||
}
|
||||
|
||||
Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
@ -214,7 +222,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
client->GetSize(), // float in_size,
|
||||
0, // float in_runspeed,
|
||||
client->GetPosition(),
|
||||
0, // uint8 in_light,
|
||||
0, // uint8 in_light, - verified for client innate_light value
|
||||
client->GetTexture(), // uint8 in_texture,
|
||||
client->GetHelmTexture(), // uint8 in_helmtexture,
|
||||
0, // uint16 in_ac,
|
||||
@ -403,6 +411,10 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
return;
|
||||
} //end "not leaving naked corpses"
|
||||
|
||||
UpdateEquipLightValue();
|
||||
spell_light = NOT_USED;
|
||||
UpdateActiveLightValue();
|
||||
|
||||
IsRezzed(false);
|
||||
Save();
|
||||
}
|
||||
@ -451,7 +463,7 @@ in_level,
|
||||
in_size,
|
||||
0,
|
||||
position,
|
||||
0,
|
||||
0, // verified for client innate_light value
|
||||
in_texture,
|
||||
in_helmtexture,
|
||||
0,
|
||||
@ -522,6 +534,10 @@ in_helmtexture,
|
||||
allowed_looters[i] = 0;
|
||||
}
|
||||
SetPlayerKillItemID(0);
|
||||
|
||||
UpdateEquipLightValue();
|
||||
spell_light = NOT_USED;
|
||||
UpdateActiveLightValue();
|
||||
}
|
||||
|
||||
Corpse::~Corpse() {
|
||||
@ -664,6 +680,8 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui
|
||||
item->aug_6=aug6;
|
||||
item->attuned=attuned;
|
||||
itemlist.push_back(item);
|
||||
|
||||
UpdateEquipLightValue();
|
||||
}
|
||||
|
||||
ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data) {
|
||||
@ -725,25 +743,25 @@ void Corpse::RemoveItem(uint16 lootslot) {
|
||||
}
|
||||
}
|
||||
|
||||
void Corpse::RemoveItem(ServerLootItem_Struct* item_data){
|
||||
uint8 material;
|
||||
ItemList::iterator cur,end;
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
for(; cur != end; ++cur) {
|
||||
ServerLootItem_Struct* sitem = *cur;
|
||||
if (sitem == item_data) {
|
||||
is_corpse_changed = true;
|
||||
itemlist.erase(cur);
|
||||
void Corpse::RemoveItem(ServerLootItem_Struct* item_data)
|
||||
{
|
||||
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
|
||||
auto sitem = *iter;
|
||||
if (sitem != item_data) { continue; }
|
||||
|
||||
material = Inventory::CalcMaterialFromSlot(sitem->equip_slot);
|
||||
if(material != _MaterialInvalid)
|
||||
SendWearChange(material);
|
||||
is_corpse_changed = true;
|
||||
itemlist.erase(iter);
|
||||
|
||||
safe_delete(sitem);
|
||||
uint8 material = Inventory::CalcMaterialFromSlot(sitem->equip_slot); // autos to unsigned char
|
||||
if (material != _MaterialInvalid)
|
||||
SendWearChange(material);
|
||||
|
||||
return;
|
||||
}
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
|
||||
safe_delete(sitem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -767,7 +785,7 @@ bool Corpse::IsEmpty() const {
|
||||
if (copper != 0 || silver != 0 || gold != 0 || platinum != 0)
|
||||
return false;
|
||||
|
||||
return(itemlist.size() == 0);
|
||||
return itemlist.empty();
|
||||
}
|
||||
|
||||
bool Corpse::Process() {
|
||||
@ -1267,6 +1285,9 @@ void Corpse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
||||
ns->spawn.NPC = 3;
|
||||
else
|
||||
ns->spawn.NPC = 2;
|
||||
|
||||
UpdateActiveLightValue();
|
||||
ns->spawn.light = active_light;
|
||||
}
|
||||
|
||||
void Corpse::QueryLoot(Client* to) {
|
||||
@ -1413,6 +1434,20 @@ uint32 Corpse::GetEquipmentColor(uint8 material_slot) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Corpse::UpdateEquipLightValue()
|
||||
{
|
||||
equip_light = NOT_USED;
|
||||
|
||||
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
|
||||
if (((*iter)->equip_slot < EmuConstants::EQUIPMENT_BEGIN || (*iter)->equip_slot > EmuConstants::GENERAL_END) && (*iter)->equip_slot != MainPowerSource) { continue; }
|
||||
auto item = database.GetItem((*iter)->item_id);
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->ItemType != ItemTypeMisc && item->ItemType != ItemTypeLight) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > equip_light) { equip_light = item->Light; }
|
||||
}
|
||||
}
|
||||
|
||||
void Corpse::AddLooter(Mob* who) {
|
||||
for (int i = 0; i < MAX_LOOTERS; i++) {
|
||||
if (allowed_looters[i] == 0) {
|
||||
|
||||
@ -125,6 +125,8 @@ class Corpse : public Mob {
|
||||
uint32 GetEquipmentColor(uint8 material_slot) const;
|
||||
inline int GetRezExp() { return rez_experience; }
|
||||
|
||||
virtual void UpdateEquipLightValue();
|
||||
|
||||
protected:
|
||||
std::list<uint32> MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot);
|
||||
|
||||
|
||||
@ -621,7 +621,7 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
|
||||
} else {
|
||||
NewSpawn_Struct *ns = new NewSpawn_Struct;
|
||||
memset(ns, 0, sizeof(NewSpawn_Struct));
|
||||
npc->FillSpawnStruct(ns, 0); // Not working on player newspawns, so it's safe to use a ForWho of 0
|
||||
npc->FillSpawnStruct(ns, nullptr); // Not working on player newspawns, so it's safe to use a ForWho of 0
|
||||
AddToSpawnQueue(npc->GetID(), &ns);
|
||||
safe_delete(ns);
|
||||
}
|
||||
|
||||
@ -174,6 +174,11 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
}
|
||||
}
|
||||
} // We either ran out of items or reached our limit.
|
||||
|
||||
npc->UpdateEquipLightValue();
|
||||
// no wearchange associated with this function..so, this should not be needed
|
||||
//if (npc->UpdateActiveLightValue())
|
||||
// npc->SendAppearancePacket(AT_Light, npc->GetActiveLightValue());
|
||||
}
|
||||
|
||||
//if itemlist is null, just send wear changes
|
||||
@ -359,6 +364,10 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
entity_list.QueueClients(this, outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
|
||||
void NPC::AddItem(const Item_Struct* item, uint16 charges, bool equipitem) {
|
||||
|
||||
@ -69,6 +69,8 @@ Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
|
||||
size = d->size;
|
||||
CalcBonuses();
|
||||
|
||||
// Class should use npc constructor to set light properties
|
||||
|
||||
SetHP(GetMaxHP());
|
||||
SetMana(GetMaxMana());
|
||||
SetEndurance(GetMaxEndurance());
|
||||
@ -1200,6 +1202,9 @@ void Merc::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
||||
ns->spawn.NPC = 1; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||
ns->spawn.IsMercenary = 1;
|
||||
|
||||
UpdateActiveLightValue();
|
||||
ns->spawn.light = active_light;
|
||||
|
||||
/*
|
||||
// Wear Slots are not setup for Mercs yet
|
||||
unsigned int i;
|
||||
@ -4899,10 +4904,35 @@ void Merc::UpdateMercAppearance() {
|
||||
this->SendWearChange(materialFromSlot);
|
||||
}
|
||||
}
|
||||
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
|
||||
void Merc::UpdateEquipLightValue()
|
||||
{
|
||||
equip_light = NOT_USED;
|
||||
|
||||
for (int index = MAIN_BEGIN; index < EmuConstants::EQUIPMENT_SIZE; ++index) {
|
||||
if (equipment[index] == NOT_USED) { continue; }
|
||||
auto item = database.GetItem(equipment[index]);
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > equip_light) { equip_light = item->Light; }
|
||||
}
|
||||
|
||||
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
|
||||
auto item = database.GetItem((*iter)->item_id);
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->ItemType != ItemTypeMisc && item->ItemType != ItemTypeLight) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > equip_light) { equip_light = item->Light; }
|
||||
}
|
||||
}
|
||||
|
||||
void Merc::AddItem(uint8 slot, uint32 item_id) {
|
||||
equipment[slot] = item_id;
|
||||
UpdateEquipLightValue();
|
||||
}
|
||||
|
||||
bool Merc::Spawn(Client *owner) {
|
||||
|
||||
@ -140,6 +140,7 @@ public:
|
||||
void UpdateMercInfo(Client *c);
|
||||
void UpdateMercStats(Client *c);
|
||||
void UpdateMercAppearance();
|
||||
virtual void UpdateEquipLightValue();
|
||||
void AddItem(uint8 slot, uint32 item_id);
|
||||
static const char *GetRandomName();
|
||||
bool Spawn(Client *owner);
|
||||
|
||||
42
zone/mob.cpp
42
zone/mob.cpp
@ -149,7 +149,9 @@ Mob::Mob(const char* in_name,
|
||||
if (runspeed < 0 || runspeed > 20)
|
||||
runspeed = 1.25f;
|
||||
|
||||
light = in_light;
|
||||
active_light = innate_light = in_light;
|
||||
spell_light = equip_light = NOT_USED;
|
||||
|
||||
texture = in_texture;
|
||||
helmtexture = in_helmtexture;
|
||||
haircolor = in_haircolor;
|
||||
@ -898,7 +900,10 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
ns->spawn.deity = deity;
|
||||
ns->spawn.animation = 0;
|
||||
ns->spawn.findable = findable?1:0;
|
||||
ns->spawn.light = light;
|
||||
|
||||
UpdateActiveLightValue();
|
||||
ns->spawn.light = active_light;
|
||||
|
||||
ns->spawn.showhelm = (helmtexture && helmtexture != 0xFF) ? 1 : 0;
|
||||
|
||||
ns->spawn.invis = (invisible || hidden) ? 1 : 0; // TODO: load this before spawning players
|
||||
@ -2024,6 +2029,39 @@ void Mob::SetAppearance(EmuAppearance app, bool iIgnoreSelf) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Mob::UpdateActiveLightValue()
|
||||
{
|
||||
/* This is old information...
|
||||
0 - "None"
|
||||
1 - "Candle"
|
||||
2 - "Torch"
|
||||
3 - "Tiny Glowing Skull"
|
||||
4 - "Small Lantern"
|
||||
5 - "Stein of Moggok"
|
||||
6 - "Large Lantern"
|
||||
7 - "Flameless Lantern"
|
||||
8 - "Globe of Stars"
|
||||
9 - "Light Globe"
|
||||
10 - "Lightstone"
|
||||
11 - "Greater Lightstone"
|
||||
12 - "Fire Beatle Eye"
|
||||
13 - "Coldlight"
|
||||
14 - "Unknown"
|
||||
15 - "Unknown"
|
||||
*/
|
||||
|
||||
uint8 old_light = (active_light & 0x0F);
|
||||
active_light = (innate_light & 0x0F);
|
||||
|
||||
if (equip_light > active_light) { active_light = equip_light; } // limiter in property handler
|
||||
if (spell_light > active_light) { active_light = spell_light; } // limiter in property handler
|
||||
|
||||
if (active_light != old_light)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Mob::ChangeSize(float in_size = 0, bool bNoRestriction) {
|
||||
// Size Code
|
||||
if (!bNoRestriction)
|
||||
|
||||
14
zone/mob.h
14
zone/mob.h
@ -651,6 +651,15 @@ public:
|
||||
bool IsDestructibleObject() { return destructibleobject; }
|
||||
void SetDestructibleObject(bool in) { destructibleobject = in; }
|
||||
|
||||
inline uint8 GetInnateLightValue() { return innate_light; }
|
||||
inline uint8 GetEquipLightValue() { return equip_light; }
|
||||
inline uint8 GetSpellLightValue() { return spell_light; }
|
||||
virtual void UpdateEquipLightValue() { equip_light = NOT_USED; }
|
||||
inline void SetSpellLightValue(uint8 light_value) { spell_light = (light_value & 0x0F); }
|
||||
|
||||
inline uint8 GetActiveLightValue() { return active_light; }
|
||||
bool UpdateActiveLightValue(); // returns true if change, false if no change
|
||||
|
||||
Mob* GetPet();
|
||||
void SetPet(Mob* newpet);
|
||||
virtual Mob* GetOwner();
|
||||
@ -1058,7 +1067,10 @@ protected:
|
||||
|
||||
glm::vec4 m_Delta;
|
||||
|
||||
uint8 light;
|
||||
uint8 innate_light; // defined by db field `npc_types`.`light` - where appropriate
|
||||
uint8 equip_light; // highest value of equipped/carried light-producing items
|
||||
uint8 spell_light; // set value of any light-producing spell (can be modded to mimic equip_light behavior)
|
||||
uint8 active_light; // highest value of all light sources
|
||||
|
||||
float fixedZ;
|
||||
EmuAppearance _appearance;
|
||||
|
||||
47
zone/npc.cpp
47
zone/npc.cpp
@ -71,7 +71,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
||||
d->size,
|
||||
d->runspeed,
|
||||
position,
|
||||
d->light,
|
||||
d->light, // innate_light
|
||||
d->texture,
|
||||
d->helmtexture,
|
||||
d->AC,
|
||||
@ -352,6 +352,9 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
||||
InitializeBuffSlots();
|
||||
CalcBonuses();
|
||||
raid_target = d->raid_target;
|
||||
|
||||
active_light = d->light;
|
||||
spell_light = equip_light = NOT_USED;
|
||||
}
|
||||
|
||||
NPC::~NPC()
|
||||
@ -436,13 +439,19 @@ void NPC::RemoveItem(uint32 item_id, uint16 quantity, uint16 slot) {
|
||||
ServerLootItem_Struct* item = *cur;
|
||||
if (item->item_id == item_id && slot <= 0 && quantity <= 0) {
|
||||
itemlist.erase(cur);
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue()) { SendAppearancePacket(AT_Light, GetActiveLightValue()); }
|
||||
return;
|
||||
}
|
||||
else if (item->item_id == item_id && item->equip_slot == slot && quantity >= 1) {
|
||||
if (item->charges <= quantity)
|
||||
if (item->charges <= quantity) {
|
||||
itemlist.erase(cur);
|
||||
else
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue()) { SendAppearancePacket(AT_Light, GetActiveLightValue()); }
|
||||
}
|
||||
else {
|
||||
item->charges -= quantity;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -474,6 +483,9 @@ void NPC::CheckMinMaxLevel(Mob *them)
|
||||
++cur;
|
||||
}
|
||||
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
|
||||
void NPC::ClearItemList() {
|
||||
@ -485,6 +497,10 @@ void NPC::ClearItemList() {
|
||||
safe_delete(item);
|
||||
}
|
||||
itemlist.clear();
|
||||
|
||||
UpdateEquipLightValue();
|
||||
if (UpdateActiveLightValue())
|
||||
SendAppearancePacket(AT_Light, GetActiveLightValue());
|
||||
}
|
||||
|
||||
void NPC::QueryLoot(Client* to)
|
||||
@ -702,6 +718,27 @@ uint32 NPC::CountLoot() {
|
||||
return(itemlist.size());
|
||||
}
|
||||
|
||||
void NPC::UpdateEquipLightValue()
|
||||
{
|
||||
equip_light = NOT_USED;
|
||||
|
||||
for (int index = MAIN_BEGIN; index < EmuConstants::EQUIPMENT_SIZE; ++index) {
|
||||
if (equipment[index] == NOT_USED) { continue; }
|
||||
auto item = database.GetItem(equipment[index]);
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > equip_light) { equip_light = item->Light; }
|
||||
}
|
||||
|
||||
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
|
||||
auto item = database.GetItem((*iter)->item_id);
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->ItemType != ItemTypeMisc && item->ItemType != ItemTypeLight) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > equip_light) { equip_light = item->Light; }
|
||||
}
|
||||
}
|
||||
|
||||
void NPC::Depop(bool StartSpawnTimer) {
|
||||
uint16 emoteid = this->GetEmoteID();
|
||||
if(emoteid != 0)
|
||||
@ -906,7 +943,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
|
||||
npc_type->npc_id = 0;
|
||||
npc_type->loottable_id = 0;
|
||||
npc_type->texture = atoi(sep.arg[3]);
|
||||
npc_type->light = 0;
|
||||
npc_type->light = 0; // spawncommand needs update
|
||||
npc_type->runspeed = 1.25;
|
||||
npc_type->d_melee_texture1 = atoi(sep.arg[7]);
|
||||
npc_type->d_melee_texture2 = atoi(sep.arg[8]);
|
||||
@ -1804,6 +1841,8 @@ void NPC::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
Mob::FillSpawnStruct(ns, ForWho);
|
||||
PetOnSpawn(ns);
|
||||
ns->spawn.is_npc = 1;
|
||||
UpdateActiveLightValue();
|
||||
ns->spawn.light = GetActiveLightValue();
|
||||
}
|
||||
|
||||
void NPC::PetOnSpawn(NewSpawn_Struct* ns)
|
||||
|
||||
@ -187,6 +187,7 @@ public:
|
||||
void QueryLoot(Client* to);
|
||||
uint32 CountLoot();
|
||||
inline uint32 GetLoottableID() const { return loottable_id; }
|
||||
virtual void UpdateEquipLightValue();
|
||||
|
||||
inline uint32 GetCopper() const { return copper; }
|
||||
inline uint32 GetSilver() const { return silver; }
|
||||
|
||||
@ -417,6 +417,8 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
}
|
||||
}
|
||||
|
||||
npc->UpdateEquipLightValue();
|
||||
|
||||
// finally, override size if one was provided
|
||||
if (in_size > 0.0f)
|
||||
npc->size = in_size;
|
||||
@ -437,6 +439,8 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po
|
||||
SetOwnerID(owner->GetID());
|
||||
SetPetSpellID(spell_id);
|
||||
taunting = true;
|
||||
|
||||
// Class should use npc constructor to set light properties
|
||||
}
|
||||
|
||||
bool ZoneDatabase::GetPetEntry(const char *pet_type, PetRecord *into) {
|
||||
|
||||
@ -1920,7 +1920,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
|
||||
tmpNPCType->no_target_hotkey = atoi(row[88]) == 1 ? true: false;
|
||||
tmpNPCType->raid_target = atoi(row[89]) == 0 ? false: true;
|
||||
tmpNPCType->attack_delay = atoi(row[90]);
|
||||
tmpNPCType->light = atoi(row[91]);
|
||||
tmpNPCType->light = (atoi(row[91]) & 0x0F);
|
||||
|
||||
// If NPC with duplicate NPC id already in table,
|
||||
// free item we attempted to add.
|
||||
|
||||
@ -58,7 +58,7 @@ struct NPCType
|
||||
uint32 alt_currency_type;
|
||||
uint32 adventure_template;
|
||||
uint32 trap_template;
|
||||
uint8 light; //not loaded from DB
|
||||
uint8 light;
|
||||
uint32 AC;
|
||||
uint32 Mana; //not loaded from DB
|
||||
uint32 ATK; //not loaded from DB
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user