diff --git a/changelog.txt b/changelog.txt index 4d2d34a2c..8fbdecd1f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,12 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 02/26/2015 == +Uleat: Updated light source criteria to (hopefully) match what the client uses (still needs tweaking) +Uleat: Changed 'general' light source checks to accept the last valid light source (client behavior) +Notes: + - "Fire Beetle Eyes" are still causing issues in general slots (no item movement sound effect) + - Wearable equipment types still register as valid light sources when in general slots (needs exemption criteria) + == 02/23/2015 == Uleat: Fix for RoF+ clients showing active 'Return Home' button when action is not available (swapped 'GoHome' and 'Enabled' fields in RoF-era CharacterSelectEntry structs) diff --git a/common/eq_constants.h b/common/eq_constants.h index 1a4d2e21a..6922d133a 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -21,6 +21,53 @@ #include "skills.h" #include "types.h" +/* +** Light Types +** +*/ +enum LightTypes +{ + lightTypeNone = 0, + lightTypeCandle, + lightTypeTorch, + lightTypeTinyGlowingSkull, + lightTypeSmallLantern, + lightTypeSteinOfMoggok, + lightTypeLargeLantern, + lightTypeFlamelessLantern, + lightTypeGlobeOfStars, + lightTypeLightGlobe, + lightTypeLightstone, + lightTypeGreaterLightstone, + lightTypeFireBeetleEye, + lightTypeColdlight, + lightTypeUnknown1, + lightTypeUnknown2 +}; + +#define LIGHT_TYPES_COUNT 16 + +/* +** Light Levels +** +*/ +enum LightLevels +{ + lightLevelUnlit = 0, + lightLevelCandle, + lightLevelTorch, + lightLevelSmallMagic, + lightLevelRedLight, + lightLevelBlueLight, + lightLevelSmallLantern, + lightLevelMagicLantern, + lightLevelLargeLantern, + lightLevelLargeMagic, + lightLevelBrilliant +}; + +#define LIGHT_LEVELS_COUNT 11 + /* ** Item attributes ** diff --git a/common/item.cpp b/common/item.cpp index 189c8e416..0a9bb2dc4 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -993,34 +993,43 @@ int InventoryOld::GetSlotByItemInst(ItemInst *inst) { return INVALID_INDEX; } -uint8 InventoryOld::FindHighestLightValue() +uint8 Inventory::FindBrightestLightType() { - uint8 light_value = NOT_USED; + uint8 brightest_light_type = 0; - // 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; } + if (iter->first == MainAmmo) { 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; } + + if (LightProfile_Struct::IsLevelGreater(item->Light, brightest_light_type)) + brightest_light_type = item->Light; } + uint8 general_light_type = 0; 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; } - // 'Gloomingdeep lantern' is ItemTypeArmor in the database..there may be others instances and/or types that need to be handled - if (item->ItemType != ItemTypeMisc && item->ItemType != ItemTypeLight && item->ItemType != ItemTypeArmor) { continue; } - if (item->Light & 0xF0) { continue; } - if (item->Light > light_value) { light_value = item->Light; } + + if (item->ItemClass != ItemClassCommon) { continue; } + if (item->Light < 9 || item->Light > 13) { continue; } + + if (LightProfile_Struct::TypeToLevel(item->Light)) + general_light_type = item->Light; } - return light_value; + if (LightProfile_Struct::IsLevelGreater(general_light_type, brightest_light_type)) + brightest_light_type = general_light_type; + + return brightest_light_type; } void InventoryOld::dumpEntireInventory() { @@ -2361,3 +2370,66 @@ bool ItemData::IsEquipable(uint16 Race, uint16 Class_) const return (IsRace && IsClass); } + +// +// struct LightProfile_Struct +// +uint8 LightProfile_Struct::TypeToLevel(uint8 lightType) +{ + switch (lightType) { + case lightTypeGlobeOfStars: + return lightLevelBrilliant; // 10 + case lightTypeFlamelessLantern: + case lightTypeGreaterLightstone: + return lightLevelLargeMagic; // 9 + case lightTypeLargeLantern: + return lightLevelLargeLantern; // 8 + case lightTypeSteinOfMoggok: + case lightTypeLightstone: + return lightLevelMagicLantern; // 7 + case lightTypeSmallLantern: + return lightLevelSmallLantern; // 6 + case lightTypeColdlight: + case lightTypeUnknown2: + return lightLevelBlueLight; // 5 + case lightTypeFireBeetleEye: + case lightTypeUnknown1: + return lightLevelRedLight; // 4 + case lightTypeTinyGlowingSkull: + case lightTypeLightGlobe: + return lightLevelSmallMagic; // 3 + case lightTypeTorch: + return lightLevelTorch; // 2 + case lightLevelCandle: + return lightLevelCandle; // 1 + default: + return lightLevelUnlit; // 0 + } +} + +bool LightProfile_Struct::IsLevelGreater(uint8 leftType, uint8 rightType) +{ + static const uint8 light_levels[LIGHT_TYPES_COUNT] = { + lightLevelUnlit, /* lightTypeNone */ + lightLevelCandle, /* lightTypeCandle */ + lightLevelTorch, /* lightTypeTorch */ + lightLevelSmallMagic, /* lightTypeTinyGlowingSkull */ + lightLevelSmallLantern, /* lightTypeSmallLantern */ + lightLevelMagicLantern, /* lightTypeSteinOfMoggok */ + lightLevelLargeLantern, /* lightTypeLargeLantern */ + lightLevelLargeMagic, /* lightTypeFlamelessLantern */ + lightLevelBrilliant, /* lightTypeGlobeOfStars */ + lightLevelSmallMagic, /* lightTypeLightGlobe */ + lightLevelMagicLantern, /* lightTypeLightstone */ + lightLevelLargeMagic, /* lightTypeGreaterLightstone */ + lightLevelRedLight, /* lightTypeFireBeetleEye */ + lightLevelBlueLight, /* lightTypeColdlight */ + lightLevelRedLight, /* lightTypeUnknown1 */ + lightLevelBlueLight /* lightTypeUnknown2 */ + }; + + if (leftType >= LIGHT_TYPES_COUNT) { leftType = lightTypeNone; } + if (rightType >= LIGHT_TYPES_COUNT) { rightType = lightTypeNone; } + + return (light_levels[leftType] > light_levels[rightType]); +} diff --git a/common/item.h b/common/item.h index d5f83c2d8..fe0b5ad1d 100644 --- a/common/item.h +++ b/common/item.h @@ -204,7 +204,7 @@ public: int GetSlotByItemInst(ItemInst *inst); - uint8 FindHighestLightValue(); + uint8 FindBrightestLightType(); void dumpEntireInventory(); void dumpWornItems(); @@ -472,4 +472,43 @@ public: ~EvolveInfo(); }; +struct LightProfile_Struct +{ + /* + Current criteria (light types): + Equipment: { 0 .. 15 } + General: { 9 .. 13 } + + Notes: + - Initial character load and item movement updates use different light source update behaviors + -- Server procedure matches the item movement behavior since most updates occur post-character load + - MainAmmo is not considered when determining light sources + - No 'Sub' or 'Aug' items are recognized as light sources + - Light types '< 9' and '> 13' are not considered for general (carried) light sources + - If values > 0x0F are valid, then assignment limiters will need to be removed + - MainCursor 'appears' to be a valid light source update slot..but, have not experienced updates during debug sessions + - All clients have a bug regarding stackable items (light and sound updates are not processed when picking up an item) + -- The timer-based update cancels out the invalid light source + */ + + static uint8 TypeToLevel(uint8 lightType); + static bool IsLevelGreater(uint8 leftType, uint8 rightType); + + // Light types (classifications) + struct { + uint8 Innate; // Defined by db field `npc_types`.`light` - where appropriate + uint8 Equipment; // Item_Struct::light value of worn/carried equipment + uint8 Spell; // Set value of any light-producing spell (can be modded to mimic equip_light behavior) + uint8 Active; // Highest value of all light sources + } Type; + + // Light levels (intensities) - used to determine which light source should be active + struct { + uint8 Innate; + uint8 Equipment; + uint8 Spell; + uint8 Active; + } Level; +}; + #endif // #define __ITEM_H diff --git a/common/skills.h b/common/skills.h index a589129ed..f7f66b49c 100644 --- a/common/skills.h +++ b/common/skills.h @@ -171,6 +171,8 @@ enum SkillUseTypes // temporary until it can be sorted out... #define HIGHEST_SKILL SkillFrenzy +// Spell Effects use this value to determine if an effect applies to all skills. +#define ALL_SKILLS -1 // server profile does not reflect this yet..so, prefixed with 'PACKET_' #define PACKET_SKILL_ARRAY_SIZE 100 diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 34aac8191..389323cdc 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -701,7 +701,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) { //Note: AA effects that use accuracy are skill limited, while spell effect is not. case SE_Accuracy: - if ((base2 == -1) && (newbon->Accuracy[HIGHEST_SKILL+1] < base1)) + if ((base2 == ALL_SKILLS) && (newbon->Accuracy[HIGHEST_SKILL+1] < base1)) newbon->Accuracy[HIGHEST_SKILL+1] = base1; else if (newbon->Accuracy[base2] < base1) newbon->Accuracy[base2] += base1; @@ -1043,7 +1043,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) case SE_HitChance: { - if(base2 == -1) + if(base2 == ALL_SKILLS) newbon->HitChanceEffect[HIGHEST_SKILL+1] += base1; else newbon->HitChanceEffect[base2] += base1; @@ -1099,7 +1099,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) case SE_CriticalHitChance: { - if(base2 == -1) + if(base2 == ALL_SKILLS) newbon->CriticalHitChance[HIGHEST_SKILL+1] += base1; else newbon->CriticalHitChance[base2] += base1; @@ -1109,7 +1109,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) case SE_CriticalDamageMob: { // base1 = effect value, base2 = skill restrictions(-1 for all) - if(base2 == -1) + if(base2 == ALL_SKILLS) newbon->CritDmgMob[HIGHEST_SKILL+1] += base1; else newbon->CritDmgMob[base2] += base1; @@ -1137,7 +1137,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) case SE_SkillDamageAmount: { - if(base2 == -1) + if(base2 == ALL_SKILLS) newbon->SkillDamageAmount[HIGHEST_SKILL+1] += base1; else newbon->SkillDamageAmount[base2] += base1; @@ -1154,7 +1154,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) case SE_DamageModifier: { - if(base2 == -1) + if(base2 == ALL_SKILLS) newbon->DamageModifier[HIGHEST_SKILL+1] += base1; else newbon->DamageModifier[base2] += base1; @@ -1163,7 +1163,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) case SE_DamageModifier2: { - if(base2 == -1) + if(base2 == ALL_SKILLS) newbon->DamageModifier2[HIGHEST_SKILL+1] += base1; else newbon->DamageModifier2[base2] += base1; @@ -1873,7 +1873,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_CriticalHitChance: { if (AdditiveWornBonus) { - if(base2 == -1) + if(base2 == ALL_SKILLS) new_bonus->CriticalHitChance[HIGHEST_SKILL+1] += effect_value; else new_bonus->CriticalHitChance[base2] += effect_value; @@ -1881,16 +1881,16 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne else if(effect_value < 0) { - if(base2 == -1 && new_bonus->CriticalHitChance[HIGHEST_SKILL+1] > effect_value) + if(base2 == ALL_SKILLS && new_bonus->CriticalHitChance[HIGHEST_SKILL+1] > effect_value) new_bonus->CriticalHitChance[HIGHEST_SKILL+1] = effect_value; - else if(base2 != -1 && new_bonus->CriticalHitChance[base2] > effect_value) + else if(base2 != ALL_SKILLS && new_bonus->CriticalHitChance[base2] > effect_value) new_bonus->CriticalHitChance[base2] = effect_value; } - else if(base2 == -1 && new_bonus->CriticalHitChance[HIGHEST_SKILL+1] < effect_value) + else if(base2 == ALL_SKILLS && new_bonus->CriticalHitChance[HIGHEST_SKILL+1] < effect_value) new_bonus->CriticalHitChance[HIGHEST_SKILL+1] = effect_value; - else if(base2 != -1 && new_bonus->CriticalHitChance[base2] < effect_value) + else if(base2 != ALL_SKILLS && new_bonus->CriticalHitChance[base2] < effect_value) new_bonus->CriticalHitChance[base2] = effect_value; break; @@ -2068,7 +2068,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne { if(new_bonus->MeleeSkillCheck < effect_value) { new_bonus->MeleeSkillCheck = effect_value; - new_bonus->MeleeSkillCheckSkill = base2==-1?255:base2; + new_bonus->MeleeSkillCheckSkill = base2==ALL_SKILLS?255:base2; } break; } @@ -2077,13 +2077,13 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne { if (AdditiveWornBonus){ - if(base2 == -1) + if(base2 == ALL_SKILLS) new_bonus->HitChanceEffect[HIGHEST_SKILL+1] += effect_value; else new_bonus->HitChanceEffect[base2] += effect_value; } - else if(base2 == -1){ + else if(base2 == ALL_SKILLS){ if ((effect_value < 0) && (new_bonus->HitChanceEffect[HIGHEST_SKILL+1] > effect_value)) new_bonus->HitChanceEffect[HIGHEST_SKILL+1] = effect_value; @@ -2109,7 +2109,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_DamageModifier: { - if(base2 == -1) + if(base2 == ALL_SKILLS) new_bonus->DamageModifier[HIGHEST_SKILL+1] += effect_value; else new_bonus->DamageModifier[base2] += effect_value; @@ -2118,7 +2118,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_DamageModifier2: { - if(base2 == -1) + if(base2 == ALL_SKILLS) new_bonus->DamageModifier2[HIGHEST_SKILL+1] += effect_value; else new_bonus->DamageModifier2[base2] += effect_value; @@ -2127,7 +2127,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_MinDamageModifier: { - if(base2 == -1) + if(base2 == ALL_SKILLS) new_bonus->MinDamageModifier[HIGHEST_SKILL+1] += effect_value; else new_bonus->MinDamageModifier[base2] += effect_value; @@ -2225,14 +2225,14 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne { //When using npc_spells_effects if MAX value set, use stackable quest based modifier. if (IsAISpellEffect && max){ - if(base2 == -1) + if(base2 == ALL_SKILLS) SkillDmgTaken_Mod[HIGHEST_SKILL+1] = effect_value; else SkillDmgTaken_Mod[base2] = effect_value; } else { - if(base2 == -1) + if(base2 == ALL_SKILLS) new_bonus->SkillDmgTaken[HIGHEST_SKILL+1] += effect_value; else new_bonus->SkillDmgTaken[base2] += effect_value; @@ -2341,7 +2341,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_CriticalDamageMob: { - if(base2 == -1) + if(base2 == ALL_SKILLS) new_bonus->CritDmgMob[HIGHEST_SKILL+1] += effect_value; else new_bonus->CritDmgMob[base2] += effect_value; @@ -2357,7 +2357,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_SkillDamageAmount: { - if(base2 == -1) + if(base2 == ALL_SKILLS) new_bonus->SkillDamageAmount[HIGHEST_SKILL+1] += effect_value; else new_bonus->SkillDamageAmount[base2] += effect_value; @@ -2462,7 +2462,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_SkillDamageAmount2: { - if(base2 == -1) + if(base2 == ALL_SKILLS) new_bonus->SkillDamageAmount2[HIGHEST_SKILL+1] += effect_value; else new_bonus->SkillDamageAmount2[base2] += effect_value; diff --git a/zone/bot.cpp b/zone/bot.cpp index 9da3aecd3..6335ad072 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -97,7 +97,7 @@ 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; + memset(&m_Light, 0, sizeof(LightProfile_Struct)); } // This constructor is used when the bot is loaded out of the database @@ -213,8 +213,6 @@ 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() { @@ -4121,8 +4119,8 @@ 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(); + UpdateEquipmentLight(); + UpdateActiveLight(); entity_list.AddBot(this, true, true); @@ -4187,7 +4185,7 @@ void Bot::RemoveBotItemBySlot(uint32 slotID, std::string *errorMessage) { *errorMessage = std::string(results.ErrorMessage()); m_inv.DeleteItem(slotID); - UpdateEquipLightValue(); + UpdateEquipmentLight(); } // Retrieves all the inventory records from the database for this bot. @@ -4249,7 +4247,7 @@ void Bot::GetBotItems(std::string* errorMessage, InventoryOld &inv) { } - UpdateEquipLightValue(); + UpdateEquipmentLight(); } // Returns the inventory record for this bot from the database for the specified equipment slot. @@ -4375,8 +4373,8 @@ 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; + UpdateActiveLight(); + ns->spawn.light = m_Light.Type.Active; ns->spawn.helm = helmtexture; //0xFF; ns->spawn.equip_chest2 = texture; //0xFF; @@ -5088,9 +5086,9 @@ void Bot::BotAddEquipItem(int slot, uint32 id) { SendWearChange(materialFromSlot); } - UpdateEquipLightValue(); - if (UpdateActiveLightValue()) - SendAppearancePacket(AT_Light, GetActiveLightValue()); + UpdateEquipmentLight(); + if (UpdateActiveLight()) + SendAppearancePacket(AT_Light, GetActiveLightType()); } } @@ -5106,9 +5104,9 @@ void Bot::BotRemoveEquipItem(int slot) { SendWearChange(MaterialArms); } - UpdateEquipLightValue(); - if (UpdateActiveLightValue()) - SendAppearancePacket(AT_Light, GetActiveLightValue()); + UpdateEquipmentLight(); + if (UpdateActiveLight()) + SendAppearancePacket(AT_Light, GetActiveLightType()); } } @@ -8407,7 +8405,7 @@ void Bot::EquipBot(std::string* errorMessage) { } } - UpdateEquipLightValue(); + UpdateEquipmentLight(); } //// 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. diff --git a/zone/bot.h b/zone/bot.h index ff6aca57b..03681454a 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -332,7 +332,7 @@ public: void EquipBot(std::string* errorMessage); bool CheckLoreConflict(const ItemData* item); uint32 GetEquipmentColor(uint8 material_slot) const; - virtual void UpdateEquipLightValue() { equip_light = m_inv.FindHighestLightValue(); } + virtual void UpdateEquipmentLight() { m_Light.Type.Equipment = m_inv.FindBrightestLightType(); m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment); } // Static Class Methods static void SaveBotGroup(Group* botGroup, std::string botGroupName, std::string* errorMessage); diff --git a/zone/client.cpp b/zone/client.cpp index db29aa107..4c260e934 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -308,9 +308,6 @@ Client::Client(EQStreamInterface* ieqs) interrogateinv_flag = false; - active_light = innate_light; - spell_light = equip_light = NOT_USED; - AI_Init(); } @@ -1869,9 +1866,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; + UpdateEquipmentLight(); + UpdateActiveLight(); + ns->spawn.light = m_Light.Type.Active; } bool Client::GMHideMe(Client* client) { diff --git a/zone/client.h b/zone/client.h index 2ceadae2a..923401f60 100644 --- a/zone/client.h +++ b/zone/client.h @@ -731,7 +731,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(); } + virtual void UpdateEquipmentLight() { m_Light.Type.Equipment = m_inv.FindBrightestLightType(); m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment); } inline bool AutoSplitEnabled() { return m_pp.autosplit != 0; } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 4304fc3c4..e9343ba0b 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -725,8 +725,8 @@ void Client::CompleteConnect() SendWearChange(x); } // added due to wear change above - UpdateActiveLightValue(); - SendAppearancePacket(AT_Light, GetActiveLightValue()); + UpdateActiveLight(); + SendAppearancePacket(AT_Light, GetActiveLightType()); Mob *pet = GetPet(); if (pet != nullptr) { @@ -734,8 +734,8 @@ void Client::CompleteConnect() pet->SendWearChange(x); } // added due to wear change above - pet->UpdateActiveLightValue(); - pet->SendAppearancePacket(AT_Light, pet->GetActiveLightValue()); + pet->UpdateActiveLight(); + pet->SendAppearancePacket(AT_Light, pet->GetActiveLightType()); } entity_list.SendTraders(this); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 901793df2..7d9066930 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -262,9 +262,10 @@ bool Client::Process() { } if(light_update_timer.Check()) { - UpdateEquipLightValue(); - if(UpdateActiveLightValue()) { - SendAppearancePacket(AT_Light, GetActiveLightValue()); + + UpdateEquipmentLight(); + if(UpdateActiveLight()) { + SendAppearancePacket(AT_Light, GetActiveLightType()); } } diff --git a/zone/corpse.cpp b/zone/corpse.cpp index d95842fb0..f407b5fbd 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -137,9 +137,9 @@ 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(); + pc->m_Light.Level.Innate = pc->m_Light.Type.Innate = 0; + pc->UpdateEquipmentLight(); // itemlist populated above..need to determine actual values + pc->m_Light.Level.Spell = pc->m_Light.Type.Spell = 0; safe_delete_array(pcs); @@ -150,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(), in_npc->GetInnateLightValue(), in_npc->GetTexture(),in_npc->GetHelmTexture(), + in_npc->GetPosition(), in_npc->GetInnateLightType(), 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), @@ -202,9 +202,8 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP } this->rez_experience = 0; - UpdateEquipLightValue(); - spell_light = NOT_USED; - UpdateActiveLightValue(); + UpdateEquipmentLight(); + UpdateActiveLight(); } Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( @@ -222,7 +221,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( client->GetSize(), // float in_size, 0, // float in_runspeed, client->GetPosition(), - 0, // uint8 in_light, - verified for client innate_light value + client->GetInnateLightType(), // uint8 in_light, - verified for client innate_light value client->GetTexture(), // uint8 in_texture, client->GetHelmTexture(), // uint8 in_helmtexture, 0, // uint16 in_ac, @@ -373,16 +372,14 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( database.TransactionCommit(); - UpdateEquipLightValue(); - spell_light = NOT_USED; - UpdateActiveLightValue(); + UpdateEquipmentLight(); + UpdateActiveLight(); return; } //end "not leaving naked corpses" - UpdateEquipLightValue(); - spell_light = NOT_USED; - UpdateActiveLightValue(); + UpdateEquipmentLight(); + UpdateActiveLight(); IsRezzed(false); Save(); @@ -521,9 +518,9 @@ in_helmtexture, } SetPlayerKillItemID(0); - UpdateEquipLightValue(); - spell_light = NOT_USED; - UpdateActiveLightValue(); + UpdateEquipmentLight(); + m_Light.Level.Spell = m_Light.Type.Spell = 0; + UpdateActiveLight(); } Corpse::~Corpse() { @@ -667,7 +664,7 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui item->attuned=attuned; itemlist.push_back(item); - UpdateEquipLightValue(); + UpdateEquipmentLight(); } ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data) { @@ -742,9 +739,9 @@ void Corpse::RemoveItem(ServerLootItem_Struct* item_data) if (material != _MaterialInvalid) SendWearChange(material); - UpdateEquipLightValue(); - if (UpdateActiveLightValue()) - SendAppearancePacket(AT_Light, GetActiveLightValue()); + UpdateEquipmentLight(); + if (UpdateActiveLight()) + SendAppearancePacket(AT_Light, GetActiveLightType()); safe_delete(sitem); return; @@ -1273,8 +1270,8 @@ void Corpse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) { ns->spawn.max_hp = 120; ns->spawn.NPC = 2; - UpdateActiveLightValue(); - ns->spawn.light = active_light; + UpdateActiveLight(); + ns->spawn.light = m_Light.Type.Active; } void Corpse::QueryLoot(Client* to) { @@ -1421,18 +1418,40 @@ uint32 Corpse::GetEquipmentColor(uint8 material_slot) const { return 0; } -void Corpse::UpdateEquipLightValue() +void Corpse::UpdateEquipmentLight() { - equip_light = NOT_USED; + m_Light.Type.Equipment = 0; + m_Light.Level.Equipment = 0; 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; } + if (((*iter)->equip_slot < EmuConstants::EQUIPMENT_BEGIN || (*iter)->equip_slot > EmuConstants::EQUIPMENT_END) && (*iter)->equip_slot != MainPowerSource) { continue; } + if ((*iter)->equip_slot == MainAmmo) { 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; } + + if (m_Light.IsLevelGreater(item->Light, m_Light.Type.Equipment)) + m_Light.Type.Equipment = item->Light; } + + uint8 general_light_type = 0; + for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) { + if ((*iter)->equip_slot < EmuConstants::GENERAL_BEGIN || (*iter)->equip_slot > EmuConstants::GENERAL_END) { continue; } + + auto item = database.GetItem((*iter)->item_id); + if (item == nullptr) { continue; } + + if (item->ItemClass != ItemClassCommon) { continue; } + if (item->Light < 9 || item->Light > 13) { continue; } + + if (m_Light.TypeToLevel(item->Light)) + general_light_type = item->Light; + } + + if (m_Light.IsLevelGreater(general_light_type, m_Light.Type.Equipment)) + m_Light.Type.Equipment = general_light_type; + + m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment); } void Corpse::AddLooter(Mob* who) { diff --git a/zone/corpse.h b/zone/corpse.h index 3342eae9f..562173e80 100644 --- a/zone/corpse.h +++ b/zone/corpse.h @@ -125,7 +125,7 @@ class Corpse : public Mob { uint32 GetEquipmentColor(uint8 material_slot) const; inline int GetRezExp() { return rez_experience; } - virtual void UpdateEquipLightValue(); + virtual void UpdateEquipmentLight(); protected: void MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, std::list &removedList); diff --git a/zone/loottables.cpp b/zone/loottables.cpp index 67022b259..512436b6b 100644 --- a/zone/loottables.cpp +++ b/zone/loottables.cpp @@ -184,7 +184,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml } } // We either ran out of items or reached our limit. - npc->UpdateEquipLightValue(); + npc->UpdateEquipmentLight(); // no wearchange associated with this function..so, this should not be needed //if (npc->UpdateActiveLightValue()) // npc->SendAppearancePacket(AT_Light, npc->GetActiveLightValue()); @@ -375,9 +375,9 @@ void NPC::AddLootDrop(const ItemData *item2, ItemList* itemlist, int16 charges, safe_delete(outapp); } - UpdateEquipLightValue(); - if (UpdateActiveLightValue()) - SendAppearancePacket(AT_Light, GetActiveLightValue()); + UpdateEquipmentLight(); + if (UpdateActiveLight()) + SendAppearancePacket(AT_Light, GetActiveLightType()); } void NPC::AddItem(const ItemData* item, uint16 charges, bool equipitem) { diff --git a/zone/merc.cpp b/zone/merc.cpp index 6b5ab0660..0ae9a9d84 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1201,8 +1201,8 @@ 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; + UpdateActiveLight(); + ns->spawn.light = m_Light.Type.Active; /* // Wear Slots are not setup for Mercs yet @@ -5028,34 +5028,48 @@ void Merc::UpdateMercAppearance() { } } - if (UpdateActiveLightValue()) - SendAppearancePacket(AT_Light, GetActiveLightValue()); + if (UpdateActiveLight()) + SendAppearancePacket(AT_Light, GetActiveLightType()); } -void Merc::UpdateEquipLightValue() +void Merc::UpdateEquipmentLight() { - equip_light = NOT_USED; + m_Light.Type.Equipment = 0; + m_Light.Level.Equipment = 0; for (int index = MAIN_BEGIN; index < EmuConstants::EQUIPMENT_SIZE; ++index) { - if (equipment[index] == NOT_USED) { continue; } + if (index == MainAmmo) { 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; } + + if (m_Light.IsLevelGreater(item->Light, m_Light.Type.Equipment)) { + m_Light.Type.Equipment = item->Light; + m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment); + } } + uint8 general_light_type = 0; 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; } + + if (item->ItemClass != ItemClassCommon) { continue; } + if (item->Light < 9 || item->Light > 13) { continue; } + + if (m_Light.TypeToLevel(item->Light)) + general_light_type = item->Light; } + + if (m_Light.IsLevelGreater(general_light_type, m_Light.Type.Equipment)) + m_Light.Type.Equipment = general_light_type; + + m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment); } void Merc::AddItem(uint8 slot, uint32 item_id) { equipment[slot] = item_id; - UpdateEquipLightValue(); + UpdateEquipmentLight(); } bool Merc::Spawn(Client *owner) { diff --git a/zone/merc.h b/zone/merc.h index d67baea94..f800642f8 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -139,7 +139,7 @@ public: void UpdateMercInfo(Client *c); void UpdateMercStats(Client *c, bool setmax = false); void UpdateMercAppearance(); - virtual void UpdateEquipLightValue(); + virtual void UpdateEquipmentLight(); void AddItem(uint8 slot, uint32 item_id); static const char *GetRandomName(); bool Spawn(Client *owner); diff --git a/zone/mob.cpp b/zone/mob.cpp index ab4233b4e..4793e7a66 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -150,9 +150,13 @@ Mob::Mob(const char* in_name, if (runspeed < 0 || runspeed > 20) runspeed = 1.25f; - active_light = innate_light = in_light; - spell_light = equip_light = NOT_USED; - + m_Light.Type.Innate = in_light; + m_Light.Level.Innate = m_Light.TypeToLevel(m_Light.Type.Innate); + m_Light.Level.Equipment = m_Light.Type.Equipment = 0; + m_Light.Level.Spell = m_Light.Type.Spell = 0; + m_Light.Type.Active = m_Light.Type.Innate; + m_Light.Level.Active = m_Light.Level.Innate; + texture = in_texture; helmtexture = in_helmtexture; haircolor = in_haircolor; @@ -904,8 +908,8 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.animation = 0; ns->spawn.findable = findable?1:0; - UpdateActiveLightValue(); - ns->spawn.light = active_light; + UpdateActiveLight(); + ns->spawn.light = m_Light.Type.Active; ns->spawn.showhelm = (helmtexture && helmtexture != 0xFF) ? 1 : 0; @@ -2033,37 +2037,20 @@ void Mob::SetAppearance(EmuAppearance app, bool iIgnoreSelf) { } } -bool Mob::UpdateActiveLightValue() +bool Mob::UpdateActiveLight() { - /* 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); + uint8 old_light_level = m_Light.Level.Active; - 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 + m_Light.Type.Active = 0; + m_Light.Level.Active = 0; - if (active_light != old_light) - return true; + if (m_Light.IsLevelGreater((m_Light.Type.Innate & 0x0F), m_Light.Type.Active)) { m_Light.Type.Active = m_Light.Type.Innate; } + if (m_Light.Level.Equipment > m_Light.Level.Active) { m_Light.Type.Active = m_Light.Type.Equipment; } // limiter in property handler + if (m_Light.Level.Spell > m_Light.Level.Active) { m_Light.Type.Active = m_Light.Type.Spell; } // limiter in property handler - return false; + m_Light.Level.Active = m_Light.TypeToLevel(m_Light.Type.Active); + + return (m_Light.Level.Active != old_light_level); } void Mob::ChangeSize(float in_size = 0, bool bNoRestriction) { @@ -3564,17 +3551,14 @@ int16 Mob::GetSkillDmgTaken(const SkillUseTypes skill_used) { int skilldmg_mod = 0; - int16 MeleeVuln = spellbonuses.MeleeVulnerability + itembonuses.MeleeVulnerability + aabonuses.MeleeVulnerability; - // All skill dmg mod + Skill specific skilldmg_mod += itembonuses.SkillDmgTaken[HIGHEST_SKILL+1] + spellbonuses.SkillDmgTaken[HIGHEST_SKILL+1] + itembonuses.SkillDmgTaken[skill_used] + spellbonuses.SkillDmgTaken[skill_used]; + - //Innate SetSkillDamgeTaken(skill,value) - if ((SkillDmgTaken_Mod[skill_used]) || (SkillDmgTaken_Mod[HIGHEST_SKILL+1])) - skilldmg_mod += SkillDmgTaken_Mod[skill_used] + SkillDmgTaken_Mod[HIGHEST_SKILL+1]; + skilldmg_mod += SkillDmgTaken_Mod[skill_used] + SkillDmgTaken_Mod[HIGHEST_SKILL+1]; - skilldmg_mod += MeleeVuln; + skilldmg_mod += spellbonuses.MeleeVulnerability + itembonuses.MeleeVulnerability + aabonuses.MeleeVulnerability; if(skilldmg_mod < -100) skilldmg_mod = -100; @@ -4657,22 +4641,21 @@ void Mob::SetBodyType(bodyType new_body, bool overwrite_orig) { void Mob::ModSkillDmgTaken(SkillUseTypes skill_num, int value) { - if (skill_num <= HIGHEST_SKILL) - SkillDmgTaken_Mod[skill_num] = value; - - - else if (skill_num == 255 || skill_num == -1) + if (skill_num == ALL_SKILLS) SkillDmgTaken_Mod[HIGHEST_SKILL+1] = value; + + else if (skill_num >= 0 && skill_num <= HIGHEST_SKILL) + SkillDmgTaken_Mod[skill_num] = value; } int16 Mob::GetModSkillDmgTaken(const SkillUseTypes skill_num) { - if (skill_num <= HIGHEST_SKILL) - return SkillDmgTaken_Mod[skill_num]; - - else if (skill_num == 255 || skill_num == -1) + if (skill_num == ALL_SKILLS) return SkillDmgTaken_Mod[HIGHEST_SKILL+1]; + else if (skill_num >= 0 && skill_num <= HIGHEST_SKILL) + return SkillDmgTaken_Mod[skill_num]; + return 0; } @@ -5388,4 +5371,3 @@ bool Mob::CanClassEquipItem(uint32 item_id) else return true; } - diff --git a/zone/mob.h b/zone/mob.h index 862963794..856a519c8 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -656,14 +656,17 @@ 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 GetInnateLightType() { return m_Light.Type.Innate; } + inline uint8 GetEquipmentLightType() { return m_Light.Type.Equipment; } + inline uint8 GetSpellLightType() { return m_Light.Type.Spell; } - inline uint8 GetActiveLightValue() { return active_light; } - bool UpdateActiveLightValue(); // returns true if change, false if no change + virtual void UpdateEquipmentLight() { m_Light.Type.Equipment = 0; m_Light.Level.Equipment = 0; } + inline void SetSpellLightType(uint8 lightType) { m_Light.Type.Spell = (lightType & 0x0F); m_Light.Level.Spell = m_Light.TypeToLevel(m_Light.Type.Spell); } + + inline uint8 GetActiveLightType() { return m_Light.Type.Active; } + bool UpdateActiveLight(); // returns true if change, false if no change + + LightProfile_Struct* GetLightProfile() { return &m_Light; } Mob* GetPet(); void SetPet(Mob* newpet); @@ -1078,10 +1081,7 @@ protected: glm::vec4 m_Delta; - 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 + LightProfile_Struct m_Light; float fixedZ; EmuAppearance _appearance; diff --git a/zone/npc.cpp b/zone/npc.cpp index 33a37c633..269b36b8d 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -352,9 +352,6 @@ 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() @@ -439,15 +436,15 @@ 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()); } + UpdateEquipmentLight(); + if (UpdateActiveLight()) { SendAppearancePacket(AT_Light, GetActiveLightType()); } return; } else if (item->item_id == item_id && item->equip_slot == slot && quantity >= 1) { if (item->charges <= quantity) { itemlist.erase(cur); - UpdateEquipLightValue(); - if (UpdateActiveLightValue()) { SendAppearancePacket(AT_Light, GetActiveLightValue()); } + UpdateEquipmentLight(); + if (UpdateActiveLight()) { SendAppearancePacket(AT_Light, GetActiveLightType()); } } else { item->charges -= quantity; @@ -483,9 +480,9 @@ void NPC::CheckMinMaxLevel(Mob *them) ++cur; } - UpdateEquipLightValue(); - if (UpdateActiveLightValue()) - SendAppearancePacket(AT_Light, GetActiveLightValue()); + UpdateEquipmentLight(); + if (UpdateActiveLight()) + SendAppearancePacket(AT_Light, GetActiveLightType()); } void NPC::ClearItemList() { @@ -498,9 +495,9 @@ void NPC::ClearItemList() { } itemlist.clear(); - UpdateEquipLightValue(); - if (UpdateActiveLightValue()) - SendAppearancePacket(AT_Light, GetActiveLightValue()); + UpdateEquipmentLight(); + if (UpdateActiveLight()) + SendAppearancePacket(AT_Light, GetActiveLightType()); } void NPC::QueryLoot(Client* to) @@ -718,25 +715,39 @@ uint32 NPC::CountLoot() { return(itemlist.size()); } -void NPC::UpdateEquipLightValue() +void NPC::UpdateEquipmentLight() { - equip_light = NOT_USED; + m_Light.Type.Equipment = 0; + m_Light.Level.Equipment = 0; for (int index = MAIN_BEGIN; index < EmuConstants::EQUIPMENT_SIZE; ++index) { - if (equipment[index] == NOT_USED) { continue; } + if (index == MainAmmo) { 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; } + + if (m_Light.IsLevelGreater(item->Light, m_Light.Type.Equipment)) { + m_Light.Type.Equipment = item->Light; + m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment); + } } + uint8 general_light_type = 0; 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; } + + if (item->ItemClass != ItemClassCommon) { continue; } + if (item->Light < 9 || item->Light > 13) { continue; } + + if (m_Light.TypeToLevel(item->Light)) + general_light_type = item->Light; } + + if (m_Light.IsLevelGreater(general_light_type, m_Light.Type.Equipment)) + m_Light.Type.Equipment = general_light_type; + + m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment); } void NPC::Depop(bool StartSpawnTimer) { @@ -1810,8 +1821,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(); + UpdateActiveLight(); + ns->spawn.light = GetActiveLightType(); } void NPC::PetOnSpawn(NewSpawn_Struct* ns) diff --git a/zone/npc.h b/zone/npc.h index 37a78c7ef..28dc6256a 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -187,7 +187,7 @@ public: void QueryLoot(Client* to); uint32 CountLoot(); inline uint32 GetLoottableID() const { return loottable_id; } - virtual void UpdateEquipLightValue(); + virtual void UpdateEquipmentLight(); inline uint32 GetCopper() const { return copper; } inline uint32 GetSilver() const { return silver; } diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 471697a3c..dab3e17a0 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -7783,7 +7783,7 @@ XS(XS_Mob_GetModSkillDmgTaken) Perl_croak(aTHX_ "Usage: Mob::GetModSkillDmgTaken(THIS, skill_num)"); { Mob * THIS; - uint32 RETVAL; + int16 RETVAL; dXSTARG; SkillUseTypes skill_num = (SkillUseTypes)SvUV(ST(1)); @@ -7797,7 +7797,7 @@ XS(XS_Mob_GetModSkillDmgTaken) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetModSkillDmgTaken(skill_num); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; PUSHi((IV)RETVAL); } XSRETURN(1); } diff --git a/zone/pets.cpp b/zone/pets.cpp index f4a5ac7b1..617c5fe31 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -417,7 +417,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, } } - npc->UpdateEquipLightValue(); + npc->UpdateEquipmentLight(); // finally, override size if one was provided if (in_size > 0.0f)