merge upstream

This commit is contained in:
Arthur Ice
2014-12-21 13:45:26 -08:00
193 changed files with 4491 additions and 9483 deletions
+12 -7
View File
@@ -19,7 +19,6 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
#include "../common/classes.h"
#include "../common/debug.h"
#include "../common/eq_packet_structs.h"
#include "../common/packet_dump.h"
#include "../common/races.h"
#include "../common/spdat.h"
#include "../common/string_util.h"
@@ -519,8 +518,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
}
}
if(IsClient())
pet.duration += (CastToClient()->GetFocusEffect(focusSwarmPetDuration, spell_id) / 1000);
pet.duration += GetFocusEffect(focusSwarmPetDuration, spell_id) / 1000;
pet.npc_id = record.npc_type;
@@ -893,7 +891,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
//turn on an AA effect
//duration == 0 means no time limit, used for one-shot deals, etc..
void Client::EnableAAEffect(aaEffectType type, uint32 duration) {
if(type > 32)
if(type > _maxaaEffectType)
return; //for now, special logic needed.
m_epp.aa_effects |= 1 << (type-1);
@@ -905,7 +903,7 @@ void Client::EnableAAEffect(aaEffectType type, uint32 duration) {
}
void Client::DisableAAEffect(aaEffectType type) {
if(type > 32)
if(type > _maxaaEffectType)
return; //for now, special logic needed.
uint32 bit = 1 << (type-1);
if(m_epp.aa_effects & bit) {
@@ -919,7 +917,7 @@ By default an AA effect is a one shot deal, unless
a duration timer is set.
*/
bool Client::CheckAAEffect(aaEffectType type) {
if(type > 32)
if(type > _maxaaEffectType)
return(false); //for now, special logic needed.
if(m_epp.aa_effects & (1 << (type-1))) { //is effect enabled?
//has our timer expired?
@@ -987,13 +985,20 @@ void Client::BuyAA(AA_Action* action)
}
uint32 real_cost;
uint8 req_level;
std::map<uint32, AALevelCost_Struct>::iterator RequiredLevel = AARequiredLevelAndCost.find(action->ability);
if(RequiredLevel != AARequiredLevelAndCost.end()) {
real_cost = RequiredLevel->second.Cost;
req_level = RequiredLevel->second.Level;
}
else
else {
real_cost = aa2->cost + (aa2->cost_inc * cur_level);
req_level = aa2->class_type + (aa2->level_inc * cur_level);
}
if (req_level > GetLevel())
return; //Cheater trying to Buy AA...
if (m_pp.aapoints >= real_cost && cur_level < aa2->max_level) {
SetAA(aa2->id, cur_level + 1);
+4 -1
View File
@@ -5,6 +5,7 @@
struct AA_Ability;
struct SendAA_Struct;
#define MANA_BURN 664
#include <map>
@@ -51,7 +52,8 @@ typedef enum { //AA Effect IDs
aaEffectFrostArrows,
aaEffectWarcry,
aaEffectLeechTouch,
aaEffectProjectIllusion // unused - Handled via spell effect
aaEffectProjectIllusion, // unused - Handled via spell effect
_maxaaEffectType = 32
} aaEffectType;
@@ -2154,6 +2156,7 @@ enum { //values of AA_Action.action
};
class Timer;
class Mob;
class AA_SwarmPetInfo {
public:
AA_SwarmPetInfo();
+15 -13
View File
@@ -15,18 +15,22 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include <stdlib.h>
#include <math.h>
#include "masterentity.h"
#include "../common/faction.h"
#include "map.h"
#include "../common/spdat.h"
#include "../common/skills.h"
#include "../common/misc_functions.h"
#include "../common/rulesys.h"
#include "string_ids.h"
#include <iostream>
#include "../common/spdat.h"
#include "client.h"
#include "corpse.h"
#include "entity.h"
#include "mob.h"
#ifdef BOTS
#include "bot.h"
#endif
#include "map.h"
extern Zone* zone;
//#define LOSDEBUG 6
@@ -1124,8 +1128,7 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, bool isproc)
int HateMod = RuleI(Aggro, SpellAggroMod);
if (IsClient())
HateMod += CastToClient()->GetFocusEffect(focusSpellHateMod, spell_id);
HateMod += GetFocusEffect(focusSpellHateMod, spell_id);
AggroAmount = (AggroAmount * HateMod) / 100;
@@ -1174,8 +1177,7 @@ int32 Mob::CheckHealAggroAmount(uint16 spell_id, uint32 heal_possible)
if (AggroAmount > 0) {
int HateMod = RuleI(Aggro, SpellAggroMod);
if (IsClient())
HateMod += CastToClient()->GetFocusEffect(focusSpellHateMod, spell_id);
HateMod += GetFocusEffect(focusSpellHateMod, spell_id);
//Live AA - Spell casting subtlety
HateMod += aabonuses.hatemod + spellbonuses.hatemod + itembonuses.hatemod;
+70 -77
View File
@@ -38,6 +38,10 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef BOTS
#include "bot.h"
#endif
extern QueryServ* QServ;
extern WorldServer worldserver;
@@ -197,7 +201,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
pvpmode = true;
if (chance_mod >= 10000)
return true;
return true;
float avoidanceBonus = 0;
float hitBonus = 0;
@@ -293,7 +297,6 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
attacker->spellbonuses.HitChanceEffect[HIGHEST_SKILL+1] +
attacker->aabonuses.HitChanceEffect[HIGHEST_SKILL+1];
//Accuracy = Spell Effect , HitChance = 'Accuracy' from Item Effect
//Only AA derived accuracy can be skill limited. ie (Precision of the Pathfinder, Dead Aim)
hitBonus += (attacker->itembonuses.Accuracy[HIGHEST_SKILL+1] +
@@ -330,7 +333,6 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
//I dont know the best way to handle a garunteed hit discipline being used
//agains a garunteed riposte (for example) discipline... for now, garunteed hit wins
#if EQDEBUG>=11
LogFile->write(EQEMuLog::Debug, "3 FINAL calculated chance to hit is: %5.2f", chancetohit);
#endif
@@ -346,7 +348,6 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
return(tohit_roll <= chancetohit);
}
bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
{
/* solar: called when a mob is attacked, does the checks to see if it's a hit
@@ -1164,7 +1165,6 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
if (GetFeigned())
return false; // Rogean: How can you attack while feigned? Moved up from Aggro Code.
ItemInst* weapon;
if (Hand == MainSecondary){ // Kaiyodo - Pick weapon from the attacking hand
weapon = GetInv().GetItem(MainSecondary);
@@ -1225,7 +1225,6 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
CheckIncreaseSkill(skillinuse, other, -15);
CheckIncreaseSkill(SkillOffense, other, -15);
// ***************************************************************
// *** Calculate the damage bonus, if applicable, for this hit ***
// ***************************************************************
@@ -1386,15 +1385,6 @@ void Client::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes att
if(spell_id==0)
spell_id = SPELL_UNKNOWN;
if(spell_id!=0 && spell_id != SPELL_UNKNOWN && other && damage > 0)
{
if(other->IsNPC() && !other->IsPet())
{
float npcspellscale = other->CastToNPC()->GetSpellScale();
damage = ((float)damage * npcspellscale) / (float)100;
}
}
// cut all PVP spell damage to 2/3 -solar
// Blasting ourselfs is considered PvP
//Don't do PvP mitigation if the caster is damaging himself
@@ -1531,7 +1521,6 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
hate_list.RemoveEnt(this);
RemoveAutoXTargets();
//remove ourself from all proximities
ClearAllProximities();
@@ -1607,7 +1596,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
else
UnmemSpellAll(false);
if(RuleB(Character, LeaveCorpses) && GetLevel() >= RuleI(Character, DeathItemLossLevel) || RuleB(Character, LeaveNakedCorpses))
if((RuleB(Character, LeaveCorpses) && GetLevel() >= RuleI(Character, DeathItemLossLevel)) || RuleB(Character, LeaveNakedCorpses))
{
// creating the corpse takes the cash/items off the player too
Corpse *new_corpse = new Corpse(this, exploss);
@@ -1845,7 +1834,6 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
else
damage = zone->random.Int((min_dmg+eleBane),(max_dmg+eleBane));
//check if we're hitting above our max or below it.
if((min_dmg+eleBane) != 0 && damage < (min_dmg+eleBane)) {
mlog(COMBAT__DAMAGE, "Damage (%d) is below min (%d). Setting to min.", damage, (min_dmg+eleBane));
@@ -2115,6 +2103,18 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
#endif //BOTS
}
if(give_exp && give_exp->IsTempPet() && give_exp->IsPetOwnerClient()) {
if (give_exp->IsNPC() && give_exp->CastToNPC()->GetSwarmOwner()){
Mob* temp_owner = nullptr;
temp_owner = entity_list.GetMobID(give_exp->CastToNPC()->GetSwarmOwner());
if (temp_owner)
give_exp = temp_owner;
}
}
int PlayerCount = 0; // QueryServ Player Counting
Client *give_exp_client = nullptr;
@@ -2127,8 +2127,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
Group *kg = entity_list.GetGroupByClient(give_exp_client);
Raid *kr = entity_list.GetRaidByClient(give_exp_client);
int32 finalxp = EXP_FORMULA;
finalxp = give_exp_client->mod_client_xp(finalxp, this);
int32 finalxp = EXP_FORMULA;
finalxp = give_exp_client->mod_client_xp(finalxp, this);
if(kr)
{
@@ -2506,7 +2506,6 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
}
#endif //BOTS
// if other is a merc, add the merc client to the hate list
if(other->IsMerc()) {
if(other->CastToMerc()->GetMercOwner() && other->CastToMerc()->GetMercOwner()->CastToClient()->GetFeigned()) {
@@ -2645,7 +2644,6 @@ uint8 Mob::GetWeaponDamageBonus( const Item_Struct *Weapon )
// This function calculates and returns the damage bonus for the weapon identified by the parameter "Weapon".
// Modified 9/21/2008 by Cantus
// Assert: This function should only be called for hits by the mainhand, as damage bonuses apply only to the
// weapon in the primary slot. Be sure to check that Hand == MainPrimary before calling.
@@ -2657,7 +2655,6 @@ uint8 Mob::GetWeaponDamageBonus( const Item_Struct *Weapon )
// Assert: This function should not be called unless the player is a melee class, as casters do not receive a damage bonus.
if( Weapon == nullptr || Weapon->ItemType == ItemType1HSlash || Weapon->ItemType == ItemType1HBlunt || Weapon->ItemType == ItemTypeMartial || Weapon->ItemType == ItemType1HPiercing )
{
// The weapon in the player's main (primary) hand is a one-handed weapon, or there is no item equipped at all.
@@ -2685,7 +2682,6 @@ uint8 Mob::GetWeaponDamageBonus( const Item_Struct *Weapon )
// as I suspect, then please feel free to delete the following line, and replace all occurences of "ucPlayerLevel" with "GetLevel()".
uint8 ucPlayerLevel = (uint8) GetLevel();
// The following may look cleaner, and would certainly be easier to understand, if it was
// a simple 53x150 cell matrix.
//
@@ -2703,7 +2699,6 @@ uint8 Mob::GetWeaponDamageBonus( const Item_Struct *Weapon )
// lookup table. In cases where a formula is the best bet, I use a formula. In other places
// where a formula would be ugly, I use a lookup table in the interests of speed.
if( Weapon->Delay <= 27 )
{
// Damage Bonuses for all 2H weapons with delays of 27 or less are identical.
@@ -2715,7 +2710,6 @@ uint8 Mob::GetWeaponDamageBonus( const Item_Struct *Weapon )
return (ucPlayerLevel - 22) / 3;
}
if( ucPlayerLevel == 65 && Weapon->Delay <= 59 )
{
// Consider these two facts:
@@ -2734,7 +2728,6 @@ uint8 Mob::GetWeaponDamageBonus( const Item_Struct *Weapon )
return ucLevel65DamageBonusesForDelays28to59[Weapon->Delay-28];
}
if( ucPlayerLevel > 65 )
{
if( ucPlayerLevel > 80 )
@@ -2873,7 +2866,6 @@ uint8 Mob::GetWeaponDamageBonus( const Item_Struct *Weapon )
}
}
// If we've gotten to this point in the function without hitting a return statement,
// we know that the character's level is between 28 and 65, and that the 2H weapon's
// delay is 28 or higher.
@@ -3119,7 +3111,6 @@ int Mob::GetMonkHandToHandDelay(void)
}
}
int32 Mob::ReduceDamage(int32 damage)
{
if(damage <= 0)
@@ -3170,7 +3161,6 @@ int32 Mob::ReduceDamage(int32 damage)
}
}
if (spellbonuses.MitigateMeleeRune[0] && !DisableMeleeRune){
slot = spellbonuses.MitigateMeleeRune[1];
if(slot >= 0)
@@ -3240,7 +3230,7 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
// If this is a DoT, use DoT Shielding...
if(iBuffTic) {
damage -= (damage * itembonuses.DoTShielding / 100);
damage -= (damage * itembonuses.DoTShielding / 100);
if (spellbonuses.MitigateDotRune[0]){
slot = spellbonuses.MitigateDotRune[1];
@@ -3274,7 +3264,6 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
// Reduce damage by the Spell Shielding first so that the runes don't take the raw damage.
damage -= (damage * itembonuses.SpellShield / 100);
//Only mitigate if damage is above the minimium specified.
if (spellbonuses.SpellThresholdGuard[0]){
slot = spellbonuses.SpellThresholdGuard[1];
@@ -3297,7 +3286,6 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
}
}
// Do runes now.
if (spellbonuses.MitigateSpellRune[0] && !DisableSpellRune){
slot = spellbonuses.MitigateSpellRune[1];
@@ -3730,18 +3718,15 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
//if the attacker is a client, try them with the correct filter
if(attacker && attacker->IsClient()) {
if (((spell_id != SPELL_UNKNOWN)||(FromDamageShield)) && damage>0) {
if ((spell_id != SPELL_UNKNOWN || FromDamageShield) && damage > 0) {
//special crap for spell damage, looks hackish to me
char val1[20]={0};
if (FromDamageShield)
{
if(!attacker->CastToClient()->GetFilter(FilterDamageShields) == FilterHide)
{
attacker->Message_StringID(MT_DS,OTHER_HIT_NONMELEE,GetCleanName(),ConvertArray(damage,val1));
}
}
else
entity_list.MessageClose_StringID(this, true, 100, MT_NonMelee,HIT_NON_MELEE,attacker->GetCleanName(),GetCleanName(),ConvertArray(damage,val1));
char val1[20] = {0};
if (FromDamageShield) {
if (attacker->CastToClient()->GetFilter(FilterDamageShields) != FilterHide)
attacker->Message_StringID(MT_DS,OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1));
} else {
entity_list.MessageClose_StringID(this, true, 100, MT_NonMelee, HIT_NON_MELEE, attacker->GetCleanName(), GetCleanName(), ConvertArray(damage, val1));
}
} else {
if(damage > 0) {
if(spell_id != SPELL_UNKNOWN)
@@ -3799,20 +3784,12 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
}
void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id)
{
int32 maxhp = GetMaxHP();
int32 curhp = GetHP();
uint32 acthealed = 0;
if (caster && amount > 0) {
if (caster->IsNPC() && !caster->IsPet()) {
float npchealscale = caster->CastToNPC()->GetHealScale();
amount = (static_cast<float>(amount) * npchealscale) / 100.0f;
}
}
if (amount > (maxhp - curhp))
acthealed = (maxhp - curhp);
else
@@ -3957,6 +3934,11 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
return;
}
if (DivineAura()) {
mlog(COMBAT__PROCS, "Procs canceled, Divine Aura is in effect.");
return;
}
if(!weapon_g) {
TrySpellProc(nullptr, (const Item_Struct*)nullptr, on);
return;
@@ -4206,7 +4188,7 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack
// decided to branch this into it's own function since it's going to be duplicating a lot of the
// code in here, but could lead to some confusion otherwise
if (IsPet() && GetOwner()->IsClient() || (IsNPC() && CastToNPC()->GetSwarmOwner())) {
if ((IsPet() && GetOwner()->IsClient()) || (IsNPC() && CastToNPC()->GetSwarmOwner())) {
TryPetCriticalHit(defender,skill,damage);
return;
}
@@ -4351,7 +4333,6 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack
}
}
bool Mob::TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse)
{
if (defender && !defender->IsClient() && defender->GetHPRatio() < 10){
@@ -4519,20 +4500,25 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
for(int e = 0; e < MAX_SKILL_PROCS; e++){
if (CanProc &&
(!Success && spellbonuses.SkillProc[e] && IsValidSpell(spellbonuses.SkillProc[e]))
|| (Success && spellbonuses.SkillProcSuccess[e] && IsValidSpell(spellbonuses.SkillProcSuccess[e]))) {
base_spell_id = spellbonuses.SkillProc[e];
base_spell_id = 0;
((!Success && spellbonuses.SkillProc[e] && IsValidSpell(spellbonuses.SkillProc[e]))
|| (Success && spellbonuses.SkillProcSuccess[e] && IsValidSpell(spellbonuses.SkillProcSuccess[e])))) {
if (Success)
base_spell_id = spellbonuses.SkillProcSuccess[e];
else
base_spell_id = spellbonuses.SkillProc[e];
proc_spell_id = 0;
ProcMod = 0;
for (int i = 0; i < EFFECT_COUNT; i++) {
if (spells[base_spell_id].effectid[i] == SE_SkillProc) {
if (spells[base_spell_id].effectid[i] == SE_SkillProc || spells[base_spell_id].effectid[i] == SE_SkillProcSuccess) {
proc_spell_id = spells[base_spell_id].base[i];
ProcMod = static_cast<float>(spells[base_spell_id].base2[i]);
}
else if (spells[base_spell_id].effectid[i] == SE_LimitToSkill && spells[base_spell_id].effectid[i] <= HIGHEST_SKILL) {
else if (spells[base_spell_id].effectid[i] == SE_LimitToSkill && spells[base_spell_id].base[i] <= HIGHEST_SKILL) {
if (CanProc && spells[base_spell_id].base[i] == skill && IsValidSpell(proc_spell_id)) {
float final_chance = chance * (ProcMod / 100.0f);
@@ -4545,6 +4531,7 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
}
}
else {
//Reset and check for proc in sequence
proc_spell_id = 0;
ProcMod = 0;
}
@@ -4557,20 +4544,24 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
CanProc = true;
for(int e = 0; e < MAX_SKILL_PROCS; e++){
if (CanProc &&
(!Success && itembonuses.SkillProc[e] && IsValidSpell(itembonuses.SkillProc[e]))
|| (Success && itembonuses.SkillProcSuccess[e] && IsValidSpell(itembonuses.SkillProcSuccess[e]))) {
base_spell_id = itembonuses.SkillProc[e];
base_spell_id = 0;
((!Success && itembonuses.SkillProc[e] && IsValidSpell(itembonuses.SkillProc[e]))
|| (Success && itembonuses.SkillProcSuccess[e] && IsValidSpell(itembonuses.SkillProcSuccess[e])))) {
if (Success)
base_spell_id = itembonuses.SkillProcSuccess[e];
else
base_spell_id = itembonuses.SkillProc[e];
proc_spell_id = 0;
ProcMod = 0;
for (int i = 0; i < EFFECT_COUNT; i++) {
if (spells[base_spell_id].effectid[i] == SE_SkillProc) {
if (spells[base_spell_id].effectid[i] == SE_SkillProc || spells[base_spell_id].effectid[i] == SE_SkillProcSuccess) {
proc_spell_id = spells[base_spell_id].base[i];
ProcMod = static_cast<float>(spells[base_spell_id].base2[i]);
}
else if (spells[base_spell_id].effectid[i] == SE_LimitToSkill && spells[base_spell_id].effectid[i] <= HIGHEST_SKILL) {
else if (spells[base_spell_id].effectid[i] == SE_LimitToSkill && spells[base_spell_id].base[i] <= HIGHEST_SKILL) {
if (CanProc && spells[base_spell_id].base[i] == skill && IsValidSpell(proc_spell_id)) {
float final_chance = chance * (ProcMod / 100.0f);
@@ -4600,10 +4591,16 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
for(int e = 0; e < MAX_SKILL_PROCS; e++){
if (CanProc &&
(!Success && aabonuses.SkillProc[e])
|| (Success && aabonuses.SkillProcSuccess[e])){
int aaid = aabonuses.SkillProc[e];
base_spell_id = 0;
((!Success && aabonuses.SkillProc[e])
|| (Success && aabonuses.SkillProcSuccess[e]))) {
int aaid = 0;
if (Success)
base_spell_id = aabonuses.SkillProcSuccess[e];
else
base_spell_id = aabonuses.SkillProc[e];
proc_spell_id = 0;
ProcMod = 0;
std::map<uint32, std::map<uint32, AA_Ability> >::const_iterator find_iter = aa_effects.find(aaid);
@@ -4616,12 +4613,12 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
base2 = iter->second.base2;
slot = iter->second.slot;
if (effect == SE_SkillProc) {
if (effect == SE_SkillProc || effect == SE_SkillProcSuccess) {
proc_spell_id = base1;
ProcMod = static_cast<float>(base2);
}
else if (effect == SE_LimitToSkill && effect <= HIGHEST_SKILL) {
else if (effect == SE_LimitToSkill && base1 <= HIGHEST_SKILL) {
if (CanProc && base1 == skill && IsValidSpell(proc_spell_id)) {
float final_chance = chance * (ProcMod / 100.0f);
@@ -4649,11 +4646,8 @@ float Mob::GetSkillProcChances(uint16 ReuseTime, uint16 hand) {
float ProcChance = 0;
if (!ReuseTime && hand) {
weapon_speed = GetWeaponSpeedbyHand(hand);
ProcChance = static_cast<float>(weapon_speed) * (RuleR(Combat, AvgProcsPerMinute) / 60000.0f);
if (hand != MainPrimary)
ProcChance /= 2;
}
@@ -4742,7 +4736,6 @@ int32 Mob::RuneAbsorb(int32 damage, uint16 type)
}
}
else{
for(uint32 slot = 0; slot < buff_max; slot++) {
if(slot == spellbonuses.AbsorbMagicAtt[1] && spellbonuses.AbsorbMagicAtt[0] && buffs[slot].magic_rune && IsValidSpell(buffs[slot].spellid)){
+12 -2
View File
@@ -23,7 +23,7 @@ target to center around.
*/
#include "../common/debug.h"
class Zone;
#ifdef _WINDOWS
#define snprintf _snprintf
@@ -32,7 +32,17 @@ target to center around.
#define strcasecmp _stricmp
#endif
#include "masterentity.h"
#include "../common/races.h"
#include "beacon.h"
#include "entity.h"
#include "mob.h"
#ifdef BOTS
#include "bot.h"
#endif
#include "../common/spdat.h"
extern EntityList entity_list;
+4 -1
View File
@@ -19,11 +19,14 @@
#ifndef BEACON_H
#define BEACON_H
#include "entity.h"
#include "mob.h"
#include "../common/types.h"
#include "../common/timer.h"
class Group;
class Raid;
struct ExtraAttackOptions;
class Beacon : public Mob
{
public:
+25 -16
View File
@@ -15,27 +15,29 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "../common/spdat.h"
#include "masterentity.h"
#include "../common/packet_dump.h"
#include "../common/moremath.h"
#include "../common/item.h"
#include "worldserver.h"
#include "../common/skills.h"
#include "../common/bodytypes.h"
#include "../common/classes.h"
#include "../common/debug.h"
#include "../common/item.h"
#include "../common/rulesys.h"
#include "../common/skills.h"
#include "../common/spdat.h"
#include "client.h"
#include "entity.h"
#include "mob.h"
#ifdef BOTS
#include "bot.h"
#endif
#include "quest_parser_collection.h"
#include <math.h>
#include <assert.h>
#include <iostream>
#ifndef WIN32
#include <stdlib.h>
#include "../common/unix.h"
#endif
#include "string_ids.h"
void Mob::CalcBonuses()
{
@@ -536,9 +538,9 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAu
}
void Client::CalcEdibleBonuses(StatBonuses* newbon) {
#if EQDEBUG >= 11
std::cout<<"Client::CalcEdibleBonuses(StatBonuses* newbon)"<<std::endl;
#endif
//#if EQDEBUG >= 11
// std::cout<<"Client::CalcEdibleBonuses(StatBonuses* newbon)"<<std::endl;
//#endif
// Search player slots for skill=14(food) and skill=15(drink)
uint32 i;
@@ -3050,6 +3052,13 @@ void NPC::CalcItemBonuses(StatBonuses *newbon)
if (cur->Worn.Effect>0 && (cur->Worn.Type == ET_WornEffect)) { // latent effects
ApplySpellsBonuses(cur->Worn.Effect, cur->Worn.Level, newbon);
}
if (RuleB(Spells, NPC_UseFocusFromItems)){
if (cur->Focus.Effect>0 && (cur->Focus.Type == ET_Focus)){ // focus effects
ApplySpellsBonuses(cur->Focus.Effect, cur->Focus.Level, newbon, 0, true);
}
}
if (cur->Haste > newbon->haste)
newbon->haste = cur->Haste;
}
+51 -84
View File
@@ -4173,7 +4173,7 @@ void Bot::SetBotItemInSlot(uint32 slotID, uint32 itemID, const ItemInst* inst, s
"augslot1, augslot2, augslot3, augslot4, augslot5) "
"VALUES(%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)",
(unsigned long)this->GetBotID(), (unsigned long)slotID, (unsigned long)itemID,
(unsigned long)inst->GetCharges(), (unsigned long)(inst->IsInstNoDrop()? 1: 0),
(unsigned long)inst->GetCharges(), (unsigned long)(inst->IsAttuned()? 1: 0),
(unsigned long)inst->GetColor(), (unsigned long)augslot[0], (unsigned long)augslot[1],
(unsigned long)augslot[2], (unsigned long)augslot[3], (unsigned long)augslot[4]);
auto results = database.QueryDatabase(query);
@@ -4235,7 +4235,7 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
int16 put_slot_id = INVALID_INDEX;
if (instnodrop || ((slot_id >= EmuConstants::EQUIPMENT_BEGIN) && (slot_id <= EmuConstants::EQUIPMENT_END) && inst->GetItem()->Attuneable))
inst->SetInstNoDrop(true);
inst->SetAttuned(true);
if (color > 0)
inst->SetColor(color);
@@ -4361,7 +4361,8 @@ void Bot::SetLevel(uint8 in_level, bool command) {
}
void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
if(ns) {
if(ns)
{
Mob::FillSpawnStruct(ns, ForWho);
ns->spawn.afk = 0;
@@ -4389,98 +4390,62 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
uint32 spawnedbotid = 0;
spawnedbotid = this->GetBotID();
inst = GetBotItem(MainHands);
if(inst) {
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MaterialHands] = item->Material;
ns->spawn.colors[MaterialHands].color = GetEquipmentColor(MaterialHands);
}
}
for (int i = 0; i < MaterialPrimary; i++)
{
inst = GetBotItem(i);
if (inst)
{
item = inst->GetItem();
if (item != 0)
{
ns->spawn.equipment[i].material = item->Material;
ns->spawn.equipment[i].elitematerial = item->EliteMaterial;
ns->spawn.equipment[i].heroforgemodel = item->HerosForgeModel;
if (armor_tint[i])
{
ns->spawn.colors[i].color = armor_tint[i];
inst = GetBotItem(MainHead);
if(inst) {
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MaterialHead] = item->Material;
ns->spawn.colors[MaterialHead].color = GetEquipmentColor(MaterialHead);
}
}
inst = GetBotItem(MainArms);
if(inst) {
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MaterialArms] = item->Material;
ns->spawn.colors[MaterialArms].color = GetEquipmentColor(MaterialArms);
}
}
inst = GetBotItem(MainWrist1);
if(inst) {
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MaterialWrist] = item->Material;
ns->spawn.colors[MaterialWrist].color = GetEquipmentColor(MaterialWrist);
}
}
/*
// non-live behavior
inst = GetBotItem(MainWrist2);
if(inst) {
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MaterialWrist] = item->Material;
ns->spawn.colors[MaterialWrist].color = GetEquipmentColor(MaterialWrist);
}
}
*/
inst = GetBotItem(MainChest);
if(inst) {
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MaterialChest] = item->Material;
ns->spawn.colors[MaterialChest].color = GetEquipmentColor(MaterialChest);
}
}
inst = GetBotItem(MainLegs);
if(inst) {
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MaterialLegs] = item->Material;
ns->spawn.colors[MaterialLegs].color = GetEquipmentColor(MaterialLegs);
}
}
inst = GetBotItem(MainFeet);
if(inst) {
item = inst->GetItem();
if(item) {
ns->spawn.equipment[MaterialFeet] = item->Material;
ns->spawn.colors[MaterialFeet].color = GetEquipmentColor(MaterialFeet);
}
else
{
ns->spawn.colors[i].color = item->Color;
}
}
else
{
if (armor_tint[i])
{
ns->spawn.colors[i].color = armor_tint[i];
}
}
}
}
inst = GetBotItem(MainPrimary);
if(inst) {
if(inst)
{
item = inst->GetItem();
if(item) {
if(item)
{
if(strlen(item->IDFile) > 2)
ns->spawn.equipment[MaterialPrimary] = atoi(&item->IDFile[2]);
ns->spawn.colors[MaterialPrimary].color = GetEquipmentColor(MaterialPrimary);
{
ns->spawn.equipment[MaterialPrimary].material = atoi(&item->IDFile[2]);
}
ns->spawn.colors[MaterialPrimary].color = GetEquipmentColor(MaterialPrimary);
}
}
inst = GetBotItem(MainSecondary);
if(inst) {
if(inst)
{
item = inst->GetItem();
if(item) {
if(item)
{
if(strlen(item->IDFile) > 2)
ns->spawn.equipment[MaterialSecondary] = atoi(&item->IDFile[2]);
ns->spawn.colors[MaterialSecondary].color = GetEquipmentColor(MaterialSecondary);
{
ns->spawn.equipment[MaterialSecondary].material = atoi(&item->IDFile[2]);
}
ns->spawn.colors[MaterialSecondary].color = GetEquipmentColor(MaterialSecondary);
}
}
}
@@ -11311,7 +11276,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
if(!results.Success())
return;
int slotmaterial = Inventory::CalcMaterialFromSlot(setslot);
uint8 slotmaterial = Inventory::CalcMaterialFromSlot(setslot);
c->GetTarget()->CastToBot()->SendWearChange(slotmaterial);
}
else {
@@ -16062,11 +16027,13 @@ uint8 Bot::GetNumberNeedingHealedInGroup(uint8 hpr, bool includePets) {
uint32 Bot::GetEquipmentColor(uint8 material_slot) const
{
//Bot tints
uint32 slotid = 0;
int16 slotid = 0;
uint32 botid = this->GetBotID();
//Translate code slot # to DB slot #
slotid = Inventory::CalcSlotFromMaterial(material_slot);
if (slotid == INVALID_INDEX)
return 0;
//read from db
std::string query = StringFormat("SELECT color FROM botinventory "
+54 -158
View File
@@ -1809,96 +1809,43 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
ns->spawn.runspeed = (gmspeed == 0) ? runspeed : 3.125f;
if (!m_pp.showhelm) ns->spawn.showhelm = 0;
// pp also hold this info; should we pull from there or inventory?
// (update: i think pp should do it, as this holds LoY dye - plus, this is ugly code with Inventory!)
/*
// Equipment/Weapons already set from Mob::FillSpawnStruct
// Commenting this out for now
const Item_Struct* item = nullptr;
const ItemInst* inst = nullptr;
if ((inst = m_inv[MainHands]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialHands] = item->Material;
ns->spawn.colors[MaterialHands].color = GetEquipmentColor(MaterialHands);
}
if ((inst = m_inv[MainHead]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialHead] = item->Material;
ns->spawn.colors[MaterialHead].color = GetEquipmentColor(MaterialHead);
}
if ((inst = m_inv[MainArms]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialArms] = item->Material;
ns->spawn.colors[MaterialArms].color = GetEquipmentColor(MaterialArms);
}
if ((inst = m_inv[MainWrist1]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialWrist]= item->Material;
ns->spawn.colors[MaterialWrist].color = GetEquipmentColor(MaterialWrist);
}
int16 invslot;
/*
// non-live behavior
if ((inst = m_inv[SLOT_BRACER02]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialWrist]= item->Material;
ns->spawn.colors[MaterialWrist].color = GetEquipmentColor(MaterialWrist);
for (uint32 matslot = 0; matslot < _MaterialCount; matslot++)
{
// Only Player Races Wear Armor
if (IsPlayerRace(race) || matslot > 6)
{
invslot = Inventory::CalcSlotFromMaterial(matslot);
if (invslot == INVALID_INDEX)
continue;
if ((inst = m_inv[invslot]) && inst->IsType(ItemClassCommon))
{
item = inst->GetItem();
if (matslot > 6)
{
// Weapon Models
ns->spawn.equipment[matslot].material = GetEquipmentMaterial(matslot);
}
else
{
// Armor Materials/Models
ns->spawn.equipment[matslot].material = item->Material;
ns->spawn.equipment[matslot].elitematerial = item->EliteMaterial;
ns->spawn.equipment[matslot].heroforgemodel = GetHerosForgeModel(matslot);
ns->spawn.colors[matslot].color = m_pp.item_tint[matslot].rgb.use_tint ? m_pp.item_tint[matslot].color : item->Color;
}
}
}
}
*/
if ((inst = m_inv[MainChest]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialChest] = item->Material;
ns->spawn.colors[MaterialChest].color = GetEquipmentColor(MaterialChest);
}
if ((inst = m_inv[MainLegs]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialLegs] = item->Material;
ns->spawn.colors[MaterialLegs].color = GetEquipmentColor(MaterialLegs);
}
if ((inst = m_inv[MainFeet]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialFeet] = item->Material;
ns->spawn.colors[MaterialFeet].color = GetEquipmentColor(MaterialFeet);
}
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
if ((inst = m_inv[MainPrimary]) && inst->IsType(ItemClassCommon)) {
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
if (strlen(item->IDFile) > 2)
ns->spawn.equipment[MaterialPrimary] = atoi(&item->IDFile[2]);
}
else if (inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
ns->spawn.equipment[MaterialPrimary] = inst->GetOrnamentationIDFile();
}
else {
item = inst->GetItem();
if (strlen(item->IDFile) > 2)
ns->spawn.equipment[MaterialPrimary] = atoi(&item->IDFile[2]);
}
}
if ((inst = m_inv[MainSecondary]) && inst->IsType(ItemClassCommon)) {
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
if (strlen(item->IDFile) > 2)
ns->spawn.equipment[MaterialSecondary] = atoi(&item->IDFile[2]);
}
else if (inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
ns->spawn.equipment[MaterialSecondary] = inst->GetOrnamentationIDFile();
}
else {
item = inst->GetItem();
if (strlen(item->IDFile) > 2)
ns->spawn.equipment[MaterialSecondary] = atoi(&item->IDFile[2]);
}
}
//these two may be related to ns->spawn.texture
/*
ns->spawn.npc_armor_graphic = texture;
ns->spawn.npc_helm_graphic = helmtexture;
*/
//filling in some unknowns to make the client happy
// ns->spawn.unknown0002[2] = 3;
}
bool Client::GMHideMe(Client* client) {
@@ -2726,47 +2673,12 @@ bool Client::BindWound(Mob* bindmob, bool start, bool fail){
void Client::SetMaterial(int16 in_slot, uint32 item_id) {
const Item_Struct* item = database.GetItem(item_id);
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
if (item && (item->ItemClass==ItemClassCommon)) {
if (in_slot==MainHead)
m_pp.item_material[MaterialHead] = item->Material;
else if (in_slot==MainChest)
m_pp.item_material[MaterialChest] = item->Material;
else if (in_slot==MainArms)
m_pp.item_material[MaterialArms] = item->Material;
else if (in_slot==MainWrist1)
m_pp.item_material[MaterialWrist] = item->Material;
else if (in_slot==MainHands)
m_pp.item_material[MaterialHands] = item->Material;
else if (in_slot==MainLegs)
m_pp.item_material[MaterialLegs] = item->Material;
else if (in_slot==MainFeet)
m_pp.item_material[MaterialFeet] = item->Material;
else if (in_slot == MainPrimary) {
const ItemInst* inst = m_inv[MainPrimary];
if (inst && inst->GetOrnamentationAug(ornamentationAugtype)) {
item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
m_pp.item_material[MaterialPrimary] = atoi(item->IDFile + 2);
}
else if (inst && inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
m_pp.item_material[MaterialPrimary] = inst->GetOrnamentationIDFile();
}
else {
m_pp.item_material[MaterialPrimary] = atoi(item->IDFile + 2);
}
}
else if (in_slot == MainSecondary) {
const ItemInst* inst = m_inv[MainSecondary];
if (inst && inst->GetOrnamentationAug(ornamentationAugtype)) {
item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
m_pp.item_material[MaterialSecondary] = atoi(item->IDFile + 2);
}
else if (inst && inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
m_pp.item_material[MaterialSecondary] = inst->GetOrnamentationIDFile();
}
else {
m_pp.item_material[MaterialSecondary] = atoi(item->IDFile + 2);
}
if (item && (item->ItemClass==ItemClassCommon))
{
uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot);
if (matslot != _MaterialInvalid)
{
m_pp.item_material[matslot] = GetEquipmentMaterial(matslot);
}
}
}
@@ -3097,31 +3009,14 @@ void Client::SetTint(int16 in_slot, uint32 color) {
// Still need to reconcile bracer01 versus bracer02
void Client::SetTint(int16 in_slot, Color_Struct& color) {
if (in_slot==MainHead)
m_pp.item_tint[MaterialHead].color=color.color;
else if (in_slot==MainArms)
m_pp.item_tint[MaterialArms].color=color.color;
else if (in_slot==MainWrist1)
m_pp.item_tint[MaterialWrist].color=color.color;
/*
// non-live behavior
else if (in_slot==SLOT_BRACER02)
m_pp.item_tint[MaterialWrist].color=color.color;
*/
else if (in_slot==MainHands)
m_pp.item_tint[MaterialHands].color=color.color;
else if (in_slot==MainPrimary)
m_pp.item_tint[MaterialPrimary].color=color.color;
else if (in_slot==MainSecondary)
m_pp.item_tint[MaterialSecondary].color=color.color;
else if (in_slot==MainChest)
m_pp.item_tint[MaterialChest].color=color.color;
else if (in_slot==MainLegs)
m_pp.item_tint[MaterialLegs].color=color.color;
else if (in_slot==MainFeet)
m_pp.item_tint[MaterialFeet].color=color.color;
database.SaveCharacterMaterialColor(this->CharacterID(), in_slot, color.color);
uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot);
if (matslot != _MaterialInvalid)
{
m_pp.item_tint[matslot].color = color.color;
database.SaveCharacterMaterialColor(this->CharacterID(), in_slot, color.color);
}
}
void Client::SetHideMe(bool flag)
@@ -5808,17 +5703,18 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
if(inst) {
item = inst->GetItem();
if(item) {
if (inst && inst->GetOrnamentationAug(ornamentationAugtype)) {
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
strcpy(insr->itemnames[L], item->Name);
insr->itemicons[L] = aug_weap->Icon;
strcpy(insr->itemnames[L], item->Name);
if (inst && inst->GetOrnamentationAug(ornamentationAugtype))
{
const Item_Struct *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
insr->itemicons[L] = aug_item->Icon;
}
else if (inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
strcpy(insr->itemnames[L], item->Name);
else if (inst && inst->GetOrnamentationIcon())
{
insr->itemicons[L] = inst->GetOrnamentationIcon();
}
else {
strcpy(insr->itemnames[L], item->Name);
else
{
insr->itemicons[L] = item->Icon;
}
}
+17 -18
View File
@@ -17,7 +17,17 @@
*/
#ifndef CLIENT_H
#define CLIENT_H
class Client;
class EQApplicationPacket;
class EQStream;
class Group;
class NPC;
class Object;
class Raid;
class Seperator;
class ServerPacket;
struct Item_Struct;
#include "../common/timer.h"
#include "../common/ptimer.h"
@@ -28,25 +38,21 @@ class Client;
#include "../common/eq_packet.h"
#include "../common/linked_list.h"
#include "../common/extprofile.h"
#include "../common/classes.h"
#include "../common/races.h"
#include "../common/deity.h"
#include "../common/seperator.h"
#include "../common/item.h"
#include "../common/guilds.h"
#include "../common/item_struct.h"
#include "../common/clientversions.h"
#include "common.h"
#include "zonedb.h"
#include "errno.h"
#include "mob.h"
#include "npc.h"
#include "merc.h"
#include "zone.h"
#include "aa.h"
#include "questmgr.h"
#include "common.h"
#include "merc.h"
#include "mob.h"
#include "qglobals.h"
#include "questmgr.h"
#include "zone.h"
#include "zonedb.h"
#ifdef _WINDOWS
// since windows defines these within windef.h (which windows.h include)
@@ -57,7 +63,6 @@ class Client;
#include <float.h>
#include <set>
#include <string>
#include <algorithm>
@@ -485,14 +490,8 @@ public:
inline virtual int32 GetDelayDeath() const { return aabonuses.DelayDeath + spellbonuses.DelayDeath + itembonuses.DelayDeath + 11; }
float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false);
int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
int32 GetActSpellCost(uint16 spell_id, int32);
int32 GetActSpellDuration(uint16 spell_id, int32);
int32 GetActSpellCasttime(uint16 spell_id, int32);
int32 GetDotFocus(uint16 spell_id, int32 value);
int32 GetActDoTDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
virtual bool CheckFizzle(uint16 spell_id);
virtual bool CheckSpellLevelRestriction(uint16 spell_id);
virtual int GetCurrentBuffSlots() const;
@@ -811,7 +810,7 @@ public:
void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false);
void PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootItem_Struct** bag_item_data = 0);
bool AutoPutLootInInventory(ItemInst& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0);
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, bool attuned = false, uint16 to_slot = MainCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0);
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false, uint16 to_slot = MainCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0);
void SetStats(uint8 type,int16 set_val);
void IncStats(uint8 type,int16 increase_val);
void DropItem(int16 slot_id);
+1 -1
View File
@@ -18,11 +18,11 @@
#ifndef CLIENT_LOGS_H
#define CLIENT_LOGS_H
#include "../common/debug.h"
#include "../common/features.h"
#ifdef CLIENT_LOGS
#include "../common/eq_packet_structs.h"
#define CLIENT_LOG_CHANNEL MT_Chat10Echo
+10 -8
View File
@@ -15,18 +15,20 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <algorithm>
#include "../common/debug.h"
#include "../common/logsys.h"
#include "../common/spdat.h"
#include "../common/rulesys.h"
#include "masterentity.h"
#include "npc_ai.h"
#include "petitions.h"
#include "string_ids.h"
#include "worldserver.h"
#include "zonedb.h"
#include "../common/spdat.h"
#include "client.h"
#include "mob.h"
#ifdef BOTS
#include "bot.h"
#endif
#include <algorithm>
int32 Client::GetMaxStat() const {
+49 -21
View File
@@ -58,6 +58,10 @@
#include "worldserver.h"
#include "zone.h"
#ifdef BOTS
#include "bot.h"
#endif
extern QueryServ* QServ;
extern Zone* zone;
extern volatile bool ZoneLoaded;
@@ -1421,8 +1425,12 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
/* Set item material tint */
for (int i = EmuConstants::MATERIAL_BEGIN; i <= EmuConstants::MATERIAL_END; i++)
if (m_pp.item_tint[i].rgb.use_tint == 1 || m_pp.item_tint[i].rgb.use_tint == 255)
m_pp.item_tint[i].rgb.use_tint = 0xFF;
{
if (m_pp.item_tint[i].rgb.use_tint == 1 || m_pp.item_tint[i].rgb.use_tint == 255)
{
m_pp.item_tint[i].rgb.use_tint = 0xFF;
}
}
if (level){ level = m_pp.level; }
@@ -1484,9 +1492,28 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
m_pp.gm = 0;
/* Load Guild */
if (!IsInAGuild()) { m_pp.guild_id = GUILD_NONE; }
else {
if (!IsInAGuild()) {
m_pp.guild_id = GUILD_NONE;
} else {
m_pp.guild_id = GuildID();
uint8 rank = guild_mgr.GetDisplayedRank(GuildID(), GuildRank(), CharacterID());
// FIXME: RoF guild rank
if (GetClientVersion() >= EQClientRoF) {
switch (rank) {
case 0:
rank = 5;
break;
case 1:
rank = 3;
break;
case 2:
rank = 1;
break;
default:
break;
}
}
m_pp.guildrank = rank;
if (zone->GetZoneID() == RuleI(World, GuildBankZoneID))
GuildBanker = (guild_mgr.IsGuildLeader(GuildID(), CharacterID()) || guild_mgr.GetBankerFlag(CharacterID()));
}
@@ -2724,7 +2751,7 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app)
SetAlternateCurrencyValue(reclaim->currency_id, 0);
}
else {
SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, false, MainCursor);
SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, 0, false, MainCursor);
AddAlternateCurrencyValue(reclaim->currency_id, -((int32)reclaim->count));
}
/* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */
@@ -3067,7 +3094,6 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
uint16 slot_id = in_augment->container_slot;
uint16 aug_slot_id = in_augment->augment_slot;
//Message(13, "%i AugSlot", aug_slot_id);
if (slot_id == INVALID_INDEX || aug_slot_id == INVALID_INDEX)
{
Message(13, "Error: Invalid Aug Index.");
@@ -3083,6 +3109,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
(tobe_auged->AvailableWearSlot(auged_with->GetItem()->Slots)))
{
tobe_auged->PutAugment(in_augment->augment_index, *auged_with);
tobe_auged->UpdateOrnamentationInfo();
ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_index);
if (aug) {
@@ -3105,15 +3132,16 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
{
DeleteItemInInventory(slot_id, 0, true);
DeleteItemInInventory(MainCursor, 0, true);
if (PutItemInInventory(slot_id, *itemOneToPush, true))
{
CalcBonuses();
//Message(13, "Sucessfully added an augment to your item!");
// Successfully added an augment to the item
return;
}
else
{
Message(13, "Error: No available slot for end result. Please free up some bag space.");
Message(13, "Error: No available slot for end result. Please free up the augment slot.");
}
}
else
@@ -3167,6 +3195,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
return;
}
old_aug = tobe_auged->RemoveAugment(in_augment->augment_index);
tobe_auged->UpdateOrnamentationInfo();
itemOneToPush = tobe_auged->Clone();
if (old_aug)
@@ -3175,9 +3204,10 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
{
DeleteItemInInventory(slot_id, 0, true);
DeleteItemInInventory(aug_slot_id, auged_with->IsStackable() ? 1 : 0, true);
if (!PutItemInInventory(slot_id, *itemOneToPush, true))
{
Message(15, "Shouldn't happen, contact an admin!");
Message(15, "Failed to remove augment properly!");
}
if (PutItemInInventory(MainCursor, *itemTwoToPush, true))
@@ -5657,7 +5687,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
}
else
{
std::list<int> pathlist = zone->pathing->FindRoute(Start, End);
std::deque<int> pathlist = zone->pathing->FindRoute(Start, End);
if (pathlist.size() == 0)
{
@@ -5696,7 +5726,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
p.z = GetZ();
points.push_back(p);
for (std::list<int>::iterator Iterator = pathlist.begin(); Iterator != pathlist.end(); ++Iterator)
for (auto Iterator = pathlist.begin(); Iterator != pathlist.end(); ++Iterator)
{
if ((*Iterator) == -1) // Teleporter
{
@@ -6915,7 +6945,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
const Item_Struct* CursorItem = CursorItemInst->GetItem();
if (!CursorItem->NoDrop || CursorItemInst->IsInstNoDrop())
if (!CursorItem->NoDrop || CursorItemInst->IsAttuned())
{
Message_StringID(13, GUILD_BANK_CANNOT_DEPOSIT);
@@ -7981,17 +8011,15 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app)
item = inst ? inst->GetItem() : nullptr;
if (item) {
strcpy(insr->itemnames[L], item->Name);
if (inst && inst->GetOrnamentationAug(ornamentationAugtype)) {
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
strcpy(insr->itemnames[L], item->Name);
insr->itemicons[L] = aug_weap->Icon;
const Item_Struct *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
insr->itemicons[L] = aug_item->Icon;
}
else if (inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
strcpy(insr->itemnames[L], item->Name);
else if (inst->GetOrnamentationIcon()) {
insr->itemicons[L] = inst->GetOrnamentationIcon();
}
else {
strcpy(insr->itemnames[L], item->Name);
insr->itemicons[L] = item->Icon;
}
}
@@ -8162,7 +8190,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
}
ItemInst* inst = database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4]);
ItemInst* inst = database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]);
if (inst) {
SendItemPacket(0, inst, ItemPacketViewLink);
safe_delete(inst);
@@ -8310,7 +8338,7 @@ void Client::Handle_OP_ItemPreview(const EQApplicationPacket *app)
outapp->WriteUInt32(item->Material);
outapp->WriteUInt32(0); //unknown
outapp->WriteUInt32(item->EliteMaterial);
outapp->WriteUInt32(0); // unknown
outapp->WriteUInt32(item->HerosForgeModel);
outapp->WriteUInt32(0); // unknown
outapp->WriteUInt32(0); //This is unknown057 from lucy
for (spacer = 0; spacer < 77; spacer++) { //More Item stats, but some seem to be off based on packet check
@@ -8318,7 +8346,7 @@ void Client::Handle_OP_ItemPreview(const EQApplicationPacket *app)
}
outapp->WriteUInt32(0xFFFFFFFF); //Unknown but always seen as FF FF FF FF
outapp->WriteUInt32(0); //Unknown
for (spacer = 0; spacer < 5; spacer++) { //Augment stuff
for (spacer = 0; spacer < 6; spacer++) { //Augment stuff
outapp->WriteUInt32(item->AugSlotType[spacer]);
outapp->WriteUInt8(item->AugSlotVisible[spacer]);
outapp->WriteUInt8(item->AugSlotUnk2[spacer]);
+75 -20
View File
@@ -153,6 +153,8 @@ int command_init(void) {
command_add("version","- Display current version of EQEmu server",0,command_version) ||
command_add("setfaction","[faction number] - Sets targeted NPC's faction in the database",170,command_setfaction) ||
command_add("wc","[wear slot] [material] - Sends an OP_WearChange for your target",200,command_wc) ||
command_add("heromodel", "[hero model] [slot] - Full set of Hero's Forge Armor appearance. If slot is set, sends exact model just to slot.", 200, command_heromodel) ||
command_add("hm", "[hero model] [slot] - Full set of Hero's Forge Armor appearance. If slot is set, sends exact model just to slot.)", 200, command_heromodel) ||
command_add("setanim","[animnum] - Set target's appearance to animnum",200,command_setanim) ||
command_add("connectworldserver","- Make zone attempt to connect to worldserver",200,command_connectworldserver) ||
command_add("connectworld",nullptr,0,command_connectworldserver) ||
@@ -787,6 +789,47 @@ void command_wc(Client *c, const Seperator *sep)
}
}
void command_heromodel(Client *c, const Seperator *sep)
{
if (sep->argnum < 1)
{
c->Message(0, "Usage: #heromodel [hero forge model] [ [slot] ] (example: #heromodel 63)");
}
else if (c->GetTarget() == nullptr)
{
c->Message(13, "You must have a target to do a wear change for Hero's Forge Models.");
}
else
{
uint32 hero_forge_model = atoi(sep->arg[1]);
if (sep->argnum > 1)
{
uint8 wearslot = (uint8)atoi(sep->arg[2]);
c->GetTarget()->SendTextureWC(wearslot, 0, hero_forge_model, 0, 0, 0);
}
else
{
if (hero_forge_model > 0)
{
// Conversion to simplify the command arguments
// Hero's Forge model is actually model * 1000 + texture * 100 + wearslot
// Hero's Forge Model slot 7 is actually for Robes, but it still needs to use wearslot 1 in the packet
hero_forge_model *= 100;
for (uint8 wearslot = 0; wearslot < 7; wearslot++)
{
c->GetTarget()->SendTextureWC(wearslot, 0, (hero_forge_model + wearslot), 0, 0, 0);
}
}
else
{
c->Message(13, "Hero's Forge Model must be greater than 0.");
}
}
}
}
void command_setanim(Client *c, const Seperator *sep)
{
if (c->GetTarget() && sep->IsNumber(1)) {
@@ -5509,18 +5552,20 @@ void command_summonitem(Client *c, const Seperator *sep)
if (item_status > c->Admin())
c->Message(13, "Error: Insufficient status to summon this item.");
else if (sep->argnum==2 && sep->IsNumber(2)) {
c->SummonItem(itemid, atoi(sep->arg[2]) );
} else if (sep->argnum==3) {
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]) );
} else if (sep->argnum==4)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]) );
else if (sep->argnum==2 && sep->IsNumber(2))
c->SummonItem(itemid, atoi(sep->arg[2]));
else if (sep->argnum==3)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]));
else if (sep->argnum==4)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]));
else if (sep->argnum==5)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]) );
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]));
else if (sep->argnum==6)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]) );
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]));
else if (sep->argnum==7)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]) );
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]));
else if (sep->argnum==8)
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]), atoi(sep->arg[8]));
else {
c->SummonItem(itemid);
}
@@ -5546,18 +5591,20 @@ void command_giveitem(Client *c, const Seperator *sep)
if (item_status > c->Admin())
c->Message(13, "Error: Insufficient status to summon this item.");
else if (sep->argnum==2 && sep->IsNumber(2)) {
t->SummonItem(itemid, atoi(sep->arg[2]) );
} else if (sep->argnum==3) {
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]) );
} else if (sep->argnum==4)
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]) );
else if (sep->argnum==2 && sep->IsNumber(2))
t->SummonItem(itemid, atoi(sep->arg[2]));
else if (sep->argnum==3)
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]));
else if (sep->argnum==4)
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]));
else if (sep->argnum==5)
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]) );
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]));
else if (sep->argnum==6)
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]) );
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]));
else if (sep->argnum==7)
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]) );
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]));
else if (sep->argnum == 7)
t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]), atoi(sep->arg[8]));
else {
t->SummonItem(itemid);
}
@@ -5594,7 +5641,11 @@ void command_itemsearch(Client *c, const Seperator *sep)
if (Seperator::IsNumber(search_criteria)) {
item = database.GetItem(atoi(search_criteria));
if (item)
if (c->GetClientVersion() >= EQClientRoF)
if (c->GetClientVersion() >= EQClientRoF2)
{
c->Message(0, " %i: %c%06X00000000000000000000000000000000000000000000000000%s%c", (int)item->ID, 0x12, item->ID, item->Name, 0x12);
}
else if (c->GetClientVersion() >= EQClientRoF)
{
c->Message(0, " %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12);
}
@@ -5623,7 +5674,11 @@ void command_itemsearch(Client *c, const Seperator *sep)
strupr(sName);
pdest = strstr(sName, sCriteria);
if (pdest != nullptr) {
if (c->GetClientVersion() >= EQClientRoF)
if (c->GetClientVersion() >= EQClientRoF2)
{
c->Message(0, " %i: %c%06X00000000000000000000000000000000000000000000000000%s%c", (int)item->ID, 0x12, item->ID, item->Name, 0x12);
}
else if (c->GetClientVersion() >= EQClientRoF)
{
c->Message(0, " %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12);
}
+1
View File
@@ -76,6 +76,7 @@ void command_serversidename(Client *c, const Seperator *sep);
void command_testspawnkill(Client *c, const Seperator *sep);
void command_testspawn(Client *c, const Seperator *sep);
void command_wc(Client *c, const Seperator *sep);
void command_heromodel(Client *c, const Seperator *sep);
void command_numauths(Client *c, const Seperator *sep);
void command_setanim(Client *c, const Seperator *sep);
void command_connectworldserver(Client *c, const Seperator *sep);
+2 -2
View File
@@ -134,8 +134,8 @@ enum {
DISABLE_MELEE = 39,
NPC_CHASE_DISTANCE = 40,
ALLOW_TO_TANK = 41,
MAX_SPECIAL_ATTACK = 42
IGNORE_ROOT_AGGRO_RULES = 42,
MAX_SPECIAL_ATTACK = 43
};
typedef enum { //fear states
+33 -35
View File
@@ -20,12 +20,7 @@ New class for handeling corpses and everything associated with them.
Child of the Mob class.
-Quagmire
*/
#include "../common/debug.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <sstream>
#ifdef _WINDOWS
#define snprintf _snprintf
#define vsnprintf _vsnprintf
@@ -33,14 +28,26 @@ Child of the Mob class.
#define strcasecmp _stricmp
#endif
#include "masterentity.h"
#include "../common/packet_functions.h"
#include "../common/debug.h"
#include "../common/rulesys.h"
#include "../common/string_util.h"
#include "../common/crc32.h"
#include "client.h"
#include "corpse.h"
#include "entity.h"
#include "groups.h"
#include "mob.h"
#include "raids.h"
#ifdef BOTS
#include "bot.h"
#endif
#include "quest_parser_collection.h"
#include "string_ids.h"
#include "worldserver.h"
#include "../common/rulesys.h"
#include "quest_parser_collection.h"
#include <iostream>
extern EntityList entity_list;
extern Zone* zone;
@@ -63,8 +70,7 @@ void Corpse::SendLootReqErrorPacket(Client* client, uint8 response) {
safe_delete(outapp);
}
Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const xyz_heading& position, std::string time_of_death, bool rezzed, bool was_at_graveyard)
{
Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const xyz_heading& position, std::string time_of_death, bool rezzed, bool was_at_graveyard) {
uint32 item_count = database.GetCharacterCorpseItemCount(in_dbid);
char *buffer = new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))];
PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer;
@@ -101,11 +107,11 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
pcs->exp, // uint32 in_rezexp
was_at_graveyard // bool wasAtGraveyard
);
if (pcs->locked)
pc->Lock();
/* Load Item Tints */
// memcpy(pc->item_tint, pcs->item_tint, sizeof(pc->item_tint));
pc->item_tint[0].color = pcs->item_tint[0].color;
pc->item_tint[1].color = pcs->item_tint[1].color;
pc->item_tint[2].color = pcs->item_tint[2].color;
@@ -116,7 +122,6 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
pc->item_tint[7].color = pcs->item_tint[7].color;
pc->item_tint[8].color = pcs->item_tint[8].color;
/* Load Physical Appearance */
pc->haircolor = pcs->haircolor;
pc->beardcolor = pcs->beardcolor;
@@ -136,8 +141,6 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
return pc;
}
// To be used on NPC death and ZoneStateLoad
// Mongrel: added see_invis and see_invis_undead
Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime)
// vesuvias - appearence fix
: Mob("Unnamed_Corpse","",0,0,in_npc->GetGender(),in_npc->GetRace(),in_npc->GetClass(),BT_Humanoid,//bodytype added
@@ -173,7 +176,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
player_corpse_depop = false;
strcpy(corpse_name, in_npc->GetName());
strcpy(name, in_npc->GetName());
// Added By Hogie
for(int count = 0; count < 100; count++) {
if ((level >= npcCorpseDecayTimes[count].minlvl) && (level <= npcCorpseDecayTimes[count].maxlvl)) {
corpse_decay_timer.SetTimer(npcCorpseDecayTimes[count].seconds*1000);
@@ -189,7 +192,6 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
corpse_delay_timer.SetTimer(corpse_decay_timer.GetRemainingTime() + 1000);
}
// Added By Hogie -- End
for (int i = 0; i < MAX_LOOTERS; i++){
allowed_looters[i] = 0;
}
@@ -392,7 +394,6 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
Save();
}
// solar: helper function for client corpse constructor
std::list<uint32> Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot)
{
int bagindex;
@@ -400,7 +401,7 @@ std::list<uint32> Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16
ItemInst *interior_item;
std::list<uint32> returnlist;
AddItem(item->GetItem()->ID, item->GetCharges(), equipslot, item->GetAugmentItemID(0), item->GetAugmentItemID(1), item->GetAugmentItemID(2), item->GetAugmentItemID(3), item->GetAugmentItemID(4));
AddItem(item->GetItem()->ID, item->GetCharges(), equipslot, item->GetAugmentItemID(0), item->GetAugmentItemID(1), item->GetAugmentItemID(2), item->GetAugmentItemID(3), item->GetAugmentItemID(4), item->GetAugmentItemID(5), item->IsAttuned());
returnlist.push_back(equipslot);
// Qualified bag slot iterations. processing bag slots that don't exist is probably not a good idea.
@@ -411,7 +412,7 @@ std::list<uint32> Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16
interior_item = client->GetInv().GetItem(interior_slot);
if (interior_item) {
AddItem(interior_item->GetItem()->ID, interior_item->GetCharges(), interior_slot, interior_item->GetAugmentItemID(0), interior_item->GetAugmentItemID(1), interior_item->GetAugmentItemID(2), interior_item->GetAugmentItemID(3), interior_item->GetAugmentItemID(4));
AddItem(interior_item->GetItem()->ID, interior_item->GetCharges(), interior_slot, interior_item->GetAugmentItemID(0), interior_item->GetAugmentItemID(1), interior_item->GetAugmentItemID(2), interior_item->GetAugmentItemID(3), interior_item->GetAugmentItemID(4), interior_item->GetAugmentItemID(5), item->IsAttuned());
returnlist.push_back(Inventory::CalcSlotId(equipslot, bagindex));
client->DeleteItemInInventory(interior_slot, 0, true, false);
}
@@ -422,7 +423,6 @@ std::list<uint32> Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16
}
// To be called from LoadFromDBData
// Mongrel: added see_invis and see_invis_undead
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 xyz_heading& 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("Unnamed_Corpse",
"",
@@ -615,7 +615,6 @@ void Corpse::Bury() {
if (IsPlayerCorpse() && corpse_db_id != 0)
database.BuryCharacterCorpse(corpse_db_id);
corpse_db_id = 0;
player_corpse_depop = true;
}
@@ -632,7 +631,7 @@ uint32 Corpse::CountItems() {
return itemlist.size();
}
void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5) {
void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned) {
if (!database.GetItem(itemnum))
return;
@@ -649,13 +648,14 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui
item->aug_3=aug3;
item->aug_4=aug4;
item->aug_5=aug5;
item->aug_6=aug6;
item->attuned=attuned;
itemlist.push_back(item);
}
ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data) {
ServerLootItem_Struct *sitem = 0, *sitem2;
// find the item
ItemList::iterator cur,end;
cur = itemlist.begin();
end = itemlist.end();
@@ -768,8 +768,8 @@ bool Corpse::Process() {
return true;
}
if(corpse_graveyard_timer.Check()) {
if(zone->HasGraveyard()) {
if (corpse_graveyard_timer.Check()) {
if (zone->HasGraveyard()) {
Save();
player_corpse_depop = true;
database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(),
@@ -855,7 +855,6 @@ void Corpse::AllowPlayerLoot(Mob *them, uint8 slot) {
allowed_looters[slot] = them->CastToClient()->CharacterID();
}
// @merth: this function needs some work
void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* app) {
// Added 12/08. Started compressing loot struct on live.
char tmp[10];
@@ -986,7 +985,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
if(i < corpselootlimit) {
item = database.GetItem(item_data->item_id);
if(client && item) {
ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5);
ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
if(inst) {
// MainGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = MainGeneral1 + MainCursor
client->SendItemPacket(i + EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
@@ -1100,8 +1099,8 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
}
if (item != 0) {
if (item_data){
inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5);
if (item_data){
inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
}
else {
inst = database.CreateItem(item);
@@ -1373,7 +1372,7 @@ void Corpse::Spawn() {
}
uint32 Corpse::GetEquipment(uint8 material_slot) const {
int invslot;
int16 invslot;
if(material_slot > EmuConstants::MATERIAL_END) {
return NO_ITEM;
@@ -1429,5 +1428,4 @@ void Corpse::LoadPlayerCorpseDecayTime(uint32 corpse_db_id){
else {
corpse_graveyard_timer.SetTimer(3000);
}
}
}
+9 -2
View File
@@ -22,7 +22,14 @@
#include "mob.h"
class Client;
class EQApplicationPacket;
class Group;
class ItemInst;
class NPC;
class Raid;
struct ExtraAttackOptions;
struct NPCType;
#define MAX_LOOTERS 72
@@ -76,8 +83,8 @@ class Corpse : public Mob {
int32 GetPlayerKillItem() { return player_kill_item; }
void RemoveItem(uint16 lootslot);
void RemoveItem(ServerLootItem_Struct* item_data);
void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0);
void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
/* Corpse: Coin */
void SetCash(uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_platinum);
void RemoveCash();
+12 -9
View File
@@ -15,18 +15,21 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include "masterentity.h"
#include "worldserver.h"
#include "string_ids.h"
#include "zonedb.h"
#include "../common/packet_functions.h"
#include "../common/packet_dump.h"
#include "../common/string_util.h"
#include "client.h"
#include "doors.h"
#include "entity.h"
#include "guild_mgr.h"
#include "mob.h"
#include "string_ids.h"
#include "worldserver.h"
#include "zonedb.h"
#include <iostream>
#include <string.h>
#define OPEN_DOOR 0x02
#define CLOSE_DOOR 0x03
+8 -4
View File
@@ -1,14 +1,18 @@
#ifndef DOORS_H
#define DOORS_H
#include "../common/types.h"
#include "../common/linked_list.h"
#include "../common/timer.h"
#include "../common/emu_opcodes.h"
#include "../common/eq_packet_structs.h"
#include "entity.h"
#include "../common/linked_list.h"
#include "mob.h"
#include "zonedump.h"
class Client;
class Mob;
class NPC;
struct Door;
class Doors : public Entity
{
public:
+82 -124
View File
@@ -15,22 +15,19 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "masterentity.h"
#include "../common/spdat.h"
#include "client.h"
#include "entity.h"
#include "mob.h"
#include "string_ids.h"
#include "worldserver.h"
#include "zonedb.h"
#include "../common/spdat.h"
#include "../common/packet_dump.h"
#include "../common/packet_functions.h"
#include "petitions.h"
#include "../common/serverinfo.h"
#include "../common/zone_numbers.h"
#include "../common/moremath.h"
#include "../common/guilds.h"
#include "string_ids.h"
#include "npc_ai.h"
float Client::GetActSpellRange(uint16 spell_id, float range, bool IsBard)
float Mob::GetActSpellRange(uint16 spell_id, float range, bool IsBard)
{
float extrange = 100;
@@ -39,94 +36,58 @@ float Client::GetActSpellRange(uint16 spell_id, float range, bool IsBard)
return (range * extrange) / 100;
}
int32 NPC::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
//Quest scale all NPC spell damage via $npc->SetSpellFocusDMG(value)
//DoT Damage - Mob::DoBuffTic [spell_effects.cpp] / Direct Damage Mob::SpellEffect [spell_effects.cpp]
int32 dmg = value;
if (target) {
value += dmg*target->GetVulnerability(this, spell_id, 0)/100;
if (spells[spell_id].buffduration == 0)
value -= target->GetFcDamageAmtIncoming(this, spell_id);
else
value -= target->GetFcDamageAmtIncoming(this, spell_id)/spells[spell_id].buffduration;
}
value += dmg*GetSpellFocusDMG()/100;
if (AI_HasSpellsEffects()){
int16 chance = 0;
int ratio = 0;
if (spells[spell_id].buffduration == 0) {
chance += spellbonuses.CriticalSpellChance + spellbonuses.FrenziedDevastation;
if (chance && zone->random.Roll(chance)) {
ratio += spellbonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncNoStack;
value += (value*ratio)/100;
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits, OTHER_CRIT_BLAST, GetCleanName(), itoa(-value));
}
}
else {
chance += spellbonuses.CriticalDoTChance;
if (chance && zone->random.Roll(chance)) {
ratio += spellbonuses.DotCritDmgIncrease;
value += (value*ratio)/100;
}
}
}
return value;
}
int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
if (spells[spell_id].targettype == ST_Self)
return value;
if (IsNPC())
value += value*CastToNPC()->GetSpellFocusDMG()/100;
bool Critical = false;
int32 value_BaseEffect = 0;
int chance = 0;
value_BaseEffect = value + (value*GetFocusEffect(focusFcBaseEffects, spell_id)/100);
// Need to scale HT damage differently after level 40! It no longer scales by the constant value in the spell file. It scales differently, instead of 10 more damage per level, it does 30 more damage per level. So we multiply the level minus 40 times 20 if they are over level 40.
if ( (spell_id == SPELL_HARM_TOUCH || spell_id == SPELL_HARM_TOUCH2 || spell_id == SPELL_IMP_HARM_TOUCH ) && GetLevel() > 40)
if ((spell_id == SPELL_HARM_TOUCH || spell_id == SPELL_HARM_TOUCH2 || spell_id == SPELL_IMP_HARM_TOUCH ) && GetLevel() > 40)
value -= (GetLevel() - 40) * 20;
//This adds the extra damage from the AA Unholy Touch, 450 per level to the AA Improved Harm TOuch.
if (spell_id == SPELL_IMP_HARM_TOUCH) //Improved Harm Touch
if (spell_id == SPELL_IMP_HARM_TOUCH && IsClient()) //Improved Harm Touch
value -= GetAA(aaUnholyTouch) * 450; //Unholy Touch
int chance = RuleI(Spells, BaseCritChance); //Wizard base critical chance is 2% (Does not scale with level)
chance = RuleI(Spells, BaseCritChance); //Wizard base critical chance is 2% (Does not scale with level)
chance += itembonuses.CriticalSpellChance + spellbonuses.CriticalSpellChance + aabonuses.CriticalSpellChance;
chance += itembonuses.FrenziedDevastation + spellbonuses.FrenziedDevastation + aabonuses.FrenziedDevastation;
if (chance > 0 || (GetClass() == WIZARD && GetLevel() >= RuleI(Spells, WizCritLevel))) {
//Crtical Hit Calculation pathway
if (chance > 0 || (IsClient() && GetClass() == WIZARD && GetLevel() >= RuleI(Spells, WizCritLevel))) {
int32 ratio = RuleI(Spells, BaseCritRatio); //Critical modifier is applied from spell effects only. Keep at 100 for live like criticals.
//Improved Harm Touch is a guaranteed crit if you have at least one level of SCF.
if (spell_id == SPELL_IMP_HARM_TOUCH && (GetAA(aaSpellCastingFury) > 0) && (GetAA(aaUnholyTouch) > 0))
if (spell_id == SPELL_IMP_HARM_TOUCH && IsClient() && (GetAA(aaSpellCastingFury) > 0) && (GetAA(aaUnholyTouch) > 0))
chance = 100;
if (zone->random.Roll(chance)) {
if (zone->random.Roll(chance)) {
Critical = true;
ratio += itembonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncrease + aabonuses.SpellCritDmgIncrease;
ratio += itembonuses.SpellCritDmgIncNoStack + spellbonuses.SpellCritDmgIncNoStack + aabonuses.SpellCritDmgIncNoStack;
}
else if (GetClass() == WIZARD && (GetLevel() >= RuleI(Spells, WizCritLevel)) && (zone->random.Roll(RuleI(Spells, WizCritChance)))) {
ratio += zone->random.Int(20,70); //Wizard innate critical chance is calculated seperately from spell effect and is not a set ratio. (20-70 is parse confirmed)
Critical = true;
else if ((IsClient() && GetClass() == WIZARD) || (IsMerc() && GetClass() == CASTERDPS)) {
if ((GetLevel() >= RuleI(Spells, WizCritLevel)) && zone->random.Roll(RuleI(Spells, WizCritChance))){
//Wizard innate critical chance is calculated seperately from spell effect and is not a set ratio. (20-70 is parse confirmed)
ratio += zone->random.Int(20,70);
Critical = true;
}
}
ratio += RuleI(Spells, WizCritRatio); //Default is zero
if (IsClient() && GetClass() == WIZARD)
ratio += RuleI(Spells, WizCritRatio); //Default is zero
if (Critical){
value = value_BaseEffect*ratio/100;
@@ -147,14 +108,19 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
else if (IsNPC() && CastToNPC()->GetSpellScale())
value = int(static_cast<float>(value) * CastToNPC()->GetSpellScale() / 100.0f);
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits,
OTHER_CRIT_BLAST, GetName(), itoa(-value));
Message_StringID(MT_SpellCrits, YOU_CRIT_BLAST, itoa(-value));
if (IsClient())
Message_StringID(MT_SpellCrits, YOU_CRIT_BLAST, itoa(-value));
return value;
}
}
//Non Crtical Hit Calculation pathway
value = value_BaseEffect;
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
@@ -173,14 +139,20 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
if (IsNPC() && CastToNPC()->GetSpellScale())
value = int(static_cast<float>(value) * CastToNPC()->GetSpellScale() / 100.0f);
return value;
}
int32 Client::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
int32 Mob::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
if (target == nullptr)
return value;
if (IsNPC())
value += value*CastToNPC()->GetSpellFocusDMG()/100;
int32 value_BaseEffect = 0;
int32 extra_dmg = 0;
int16 chance = 0;
@@ -209,25 +181,28 @@ int32 Client::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
}
value -= extra_dmg;
}
else {
return value;
value = value_BaseEffect;
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
value += value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100;
value += value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100;
extra_dmg = target->GetFcDamageAmtIncoming(this, spell_id) +
GetFocusEffect(focusFcDamageAmtCrit, spell_id) +
GetFocusEffect(focusFcDamageAmt, spell_id);
if (extra_dmg) {
int duration = CalcBuffDuration(this, this, spell_id);
if (duration > 0)
extra_dmg /= duration;
}
value -= extra_dmg;
}
value = value_BaseEffect;
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
value += value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100;
value += value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100;
extra_dmg = target->GetFcDamageAmtIncoming(this, spell_id) +
GetFocusEffect(focusFcDamageAmtCrit, spell_id) +
GetFocusEffect(focusFcDamageAmt, spell_id);
if (extra_dmg) {
int duration = CalcBuffDuration(this, this, spell_id);
if (duration > 0)
extra_dmg /= duration;
}
value -= extra_dmg;
if (IsNPC() && CastToNPC()->GetSpellScale())
value = int(static_cast<float>(value) * CastToNPC()->GetSpellScale() / 100.0f);
return value;
}
@@ -254,39 +229,14 @@ int32 Mob::GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_s
return extra_spell_amt;
}
int32 NPC::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
//Scale all NPC spell healing via SetSpellFocusHeal(value)
value += value*GetSpellFocusHeal()/100;
if (target) {
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id);
value += value*target->GetHealRate(spell_id, this)/100;
}
//Allow for critical heal chance if NPC is loading spell effect bonuses.
if (AI_HasSpellsEffects()){
if(spells[spell_id].buffduration < 1) {
if(spellbonuses.CriticalHealChance && (zone->random.Roll(spellbonuses.CriticalHealChance))) {
value = value*2;
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits, OTHER_CRIT_HEAL, GetCleanName(), itoa(value));
}
}
else if(spellbonuses.CriticalHealOverTime && (zone->random.Roll(spellbonuses.CriticalHealOverTime))) {
value = value*2;
}
}
return value;
}
int32 Client::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
if (target == nullptr)
target = this;
if (IsNPC())
value += value*CastToNPC()->GetSpellFocusHeal()/100;
int32 value_BaseEffect = 0;
int16 chance = 0;
int8 modifier = 1;
@@ -323,10 +273,15 @@ int32 Client::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
value += value*target->GetHealRate(spell_id, this)/100;
if (IsNPC() && CastToNPC()->GetHealScale())
value = int(static_cast<float>(value) * CastToNPC()->GetHealScale() / 100.0f);
if (Critical) {
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits,
OTHER_CRIT_HEAL, GetName(), itoa(value));
Message_StringID(MT_SpellCrits, YOU_CRIT_HEAL, itoa(value));
if (IsClient())
Message_StringID(MT_SpellCrits, YOU_CRIT_HEAL, itoa(value));
}
return value;
@@ -343,9 +298,12 @@ int32 Client::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
chance += GetDecayEffectValue(spell_id, SE_CriticalRegenDecay);
if(chance && zone->random.Roll(chance))
return (value * 2);
value *= 2;
}
if (IsNPC() && CastToNPC()->GetHealScale())
value = int(static_cast<float>(value) * CastToNPC()->GetHealScale() / 100.0f);
return value;
}
@@ -359,9 +317,9 @@ int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
cost *= 2;
// Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell
if(this->itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
if(itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
{
int16 mana_back = this->itembonuses.Clairvoyance * zone->random.Int(1, 100) / 100;
int16 mana_back = itembonuses.Clairvoyance * zone->random.Int(1, 100) / 100;
// Doesnt generate mana, so best case is a free spell
if(mana_back > cost)
mana_back = cost;
@@ -451,7 +409,7 @@ int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
return cost;
}
int32 Client::GetActSpellDuration(uint16 spell_id, int32 duration)
int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
{
if (spells[spell_id].not_extendable)
return duration;
@@ -463,7 +421,7 @@ int32 Client::GetActSpellDuration(uint16 spell_id, int32 duration)
// Only need this for clients, since the change was for bard songs, I assume we should keep non bard songs getting +1
// However if its bard or not and is mez, charm or fear, we need to add 1 so that client is in sync
if (!(IsShortDurationBuff(spell_id) && IsBardSong(spell_id)) ||
if (IsClient() && !(IsShortDurationBuff(spell_id) && IsBardSong(spell_id)) ||
IsFearSpell(spell_id) ||
IsCharmSpell(spell_id) ||
IsMezSpell(spell_id) ||
@@ -664,7 +622,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
if(spell.recast_time > 0)
{
uint32 reduced_recast = spell.recast_time / 1000;
reduced_recast -= CastToClient()->GetFocusEffect(focusReduceRecastTime, spell_id);
reduced_recast -= GetFocusEffect(focusReduceRecastTime, spell_id);
if(reduced_recast <= 0){
reduced_recast = 0;
if (GetPTimers().Enabled((uint32)DiscTimer))
+1 -1
View File
@@ -1146,7 +1146,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
temp_var_name = var_name;
temp_var_name += "_attuned";
ExportVar(package_name.c_str(), temp_var_name.c_str(), inst->IsInstNoDrop());
ExportVar(package_name.c_str(), temp_var_name.c_str(), inst->IsAttuned());
} else {
ExportVar(package_name.c_str(), var_name.c_str(), 0);
+3 -2
View File
@@ -23,12 +23,13 @@
#include "../common/debug.h"
#include "../common/misc_functions.h"
#include "embparser.h"
#include "questmgr.h"
#include "embxs.h"
#include "entity.h"
#include "zone.h"
#include "queryserv.h"
#include "questmgr.h"
#include "zone.h"
extern Zone* zone;
extern QueryServ* QServ;
+6 -2
View File
@@ -31,7 +31,7 @@
#include "../common/features.h"
#include "../common/guilds.h"
#include "../common/spdat.h"
#include "guild_mgr.h"
#include "net.h"
#include "petitions.h"
@@ -46,6 +46,10 @@
#define strcasecmp _stricmp
#endif
#ifdef BOTS
#include "bot.h"
#endif
extern Zone *zone;
extern volatile bool ZoneLoaded;
extern WorldServer worldserver;
@@ -2631,7 +2635,7 @@ void EntityList::FindPathsToAllNPCs()
while (it != npc_list.end()) {
Map::Vertex Node0 = zone->pathing->GetPathNodeCoordinates(0, false);
Map::Vertex Dest(it->second->GetX(), it->second->GetY(), it->second->GetZ());
std::list<int> Route = zone->pathing->FindRoute(Node0, Dest);
std::deque<int> Route = zone->pathing->FindRoute(Node0, Dest);
if (Route.size() == 0)
printf("Unable to find a route to %s\n", it->second->GetName());
else
+19 -14
View File
@@ -17,6 +17,7 @@
*/
#ifndef ENTITY_H
#define ENTITY_H
#include <unordered_map>
#include <queue>
@@ -27,26 +28,30 @@
#include "../common/eq_constants.h"
#include "position.h"
#include "zonedb.h"
#include "zonedump.h"
#include "qglobals.h"
class EQApplicationPacket;
class Client;
class Mob;
class NPC;
class Merc;
class Corpse;
class Beacon;
class Petition;
class Object;
class Group;
class Raid;
class Client;
class Corpse;
class Doors;
class Trap;
class EQApplicationPacket;
class Entity;
class EntityList;
class Group;
class Merc;
class Mob;
class NPC;
class Object;
class Petition;
class Raid;
class Spawn2;
class Trap;
struct GuildBankItemUpdate_Struct;
struct NewSpawn_Struct;
struct QGlobal;
struct UseAA_Struct;
struct Who_All_Struct;
#ifdef BOTS
class Bot;
+14 -4
View File
@@ -15,14 +15,24 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "../common/features.h"
#include "masterentity.h"
#include "string_ids.h"
#include "../common/string_util.h"
#include "../common/rulesys.h"
#include "quest_parser_collection.h"
#include "../common/string_util.h"
#include "client.h"
#include "groups.h"
#include "mob.h"
#include "raids.h"
#include "queryserv.h"
#include "quest_parser_collection.h"
#include "string_ids.h"
#ifdef BOTS
#include "bot.h"
#endif
extern QueryServ* QServ;
+4 -9
View File
@@ -16,17 +16,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <cstdlib>
#include "../common/rulesys.h"
#include "../common/misc_functions.h"
#include "map.h"
#include "zone.h"
#include "pathing.h"
#include "zone.h"
#ifdef _WINDOWS
#define snprintf _snprintf
#endif
@@ -163,7 +158,7 @@ void Mob::CalculateNewFearpoint()
Map::Vertex CurrentPosition(GetX(), GetY(), GetZ());
std::list<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);
std::deque<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);
if(Route.size() > 0)
{
+1
View File
@@ -22,6 +22,7 @@
#include "../common/packet_dump.h"
#include "../common/string_util.h"
#include "worldserver.h"
extern EntityList entity_list;
extern WorldServer worldserver;
+6 -6
View File
@@ -18,14 +18,14 @@
#ifndef GROUPS_H
#define GROUPS_H
#include "../common/types.h"
#include "../common/linked_list.h"
#include "../common/emu_opcodes.h"
#include "../common/eq_packet_structs.h"
#include "entity.h"
#include "../common/types.h"
#include "mob.h"
#include "../common/features.h"
#include "../common/servertalk.h"
class Client;
class EQApplicationPacket;
class Mob;
#define MAX_MARKED_NPCS 3
+5 -4
View File
@@ -15,14 +15,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "guild_mgr.h"
#include "zonedb.h"
#include "worldserver.h"
#include "../common/servertalk.h"
#include "../common/string_util.h"
#include "client.h"
#include "entity.h"
#include "guild_mgr.h"
#include "worldserver.h"
#include "zonedb.h"
ZoneGuildManager guild_mgr;
GuildBankManager *GuildBanks;
+10 -7
View File
@@ -16,19 +16,22 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include <assert.h>
#include <stdlib.h>
#include <math.h>
#include <list>
#include "masterentity.h"
#include "client.h"
#include "entity.h"
#include "groups.h"
#include "mob.h"
#include "raids.h"
#include "../common/rulesys.h"
#include "../common/misc_functions.h"
#include "hate_list.h"
#include "quest_parser_collection.h"
#include "zone.h"
#include "water_map.h"
#include <stdlib.h>
#include <list>
extern Zone *zone;
HateList::HateList()
+6
View File
@@ -19,6 +19,12 @@
#ifndef HATELIST_H
#define HATELIST_H
class Client;
class Group;
class Mob;
class Raid;
struct ExtraAttackOptions;
struct tHateEntry
{
Mob *ent;
+5 -5
View File
@@ -17,13 +17,13 @@
*/
#include "../common/debug.h"
#include "masterentity.h"
#include "../common/item.h"
#include "../common/linked_list.h"
#include "../common/string_util.h"
#include <math.h>
#include <assert.h>
#include "worldserver.h"
#include "client.h"
#include "entity.h"
#include "horse.h"
#include "mob.h"
std::map<uint16, const NPCType *> Horse::horse_types;
LinkedList<NPCType *> horses_auto_delete;
+5 -1
View File
@@ -18,11 +18,15 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
#ifndef HORSES_H
#define HORSES_H
#include "../common/debug.h"
#include "npc.h"
#include <map>
class Client;
class Mob;
struct NPCType;
struct NewSpawn_Struct;
class Horse : public NPC {
public:
Horse(Client *owner, uint16 spell_id, const xyz_heading& position);
+65 -42
View File
@@ -189,7 +189,7 @@ bool Client::CheckLoreConflict(const Item_Struct* item) {
return (m_inv.HasItemByLoreGroup(item->LoreGroup, ~invWhereSharedBank) != INVALID_INDEX);
}
bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned, uint16 to_slot, uint32 ornament_icon, uint32 ornament_idfile) {
bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, bool attuned, uint16 to_slot, uint32 ornament_icon, uint32 ornament_idfile, uint32 ornament_hero_model) {
this->EVENT_ITEM_ScriptStopReturn();
// TODO: update calling methods and script apis to handle a failure return
@@ -199,8 +199,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
// make sure the item exists
if(item == nullptr) {
Message(13, "Item %u does not exist.", item_id);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an item with an invalid id.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, item_id, aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an item with an invalid id.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, item_id, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
@@ -212,10 +212,10 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
return false;
}
// check to make sure we are augmenting an augmentable item
else if(((item->ItemClass != ItemClassCommon) || (item->AugType > 0)) && (aug1 | aug2 | aug3 | aug4 | aug5)) {
else if (((item->ItemClass != ItemClassCommon) || (item->AugType > 0)) && (aug1 | aug2 | aug3 | aug4 | aug5 | aug6)) {
Message(13, "You can not augment an augment or a non-common class item.");
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to augment an augment or a non-common class item.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to augment an augment or a non-common class item.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug5: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
@@ -228,14 +228,14 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
/*
else if(item->MinStatus && ((this->Admin() < item->MinStatus) || (this->Admin() < RuleI(GM, MinStatusToSummonItem)))) {
Message(13, "You are not a GM or do not have the status to summon this item.");
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create a GM-only item with a status of %i.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, MinStatus: %u)\n",
GetName(), account_name, this->Admin(), item->ID, aug1, aug2, aug3, aug4, aug5, item->MinStatus);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create a GM-only item with a status of %i.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u, MinStatus: %u)\n",
GetName(), account_name, this->Admin(), item->ID, aug1, aug2, aug3, aug4, aug5, aug6, item->MinStatus);
return false;
}
*/
uint32 augments[EmuConstants::ITEM_COMMON_SIZE] = { aug1, aug2, aug3, aug4, aug5 };
uint32 augments[EmuConstants::ITEM_COMMON_SIZE] = { aug1, aug2, aug3, aug4, aug5, aug6 };
uint32 classes = item->Classes;
uint32 races = item->Races;
@@ -251,8 +251,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
if(augtest == nullptr) {
if(augments[iter]) {
Message(13, "Augment %u (Aug%i) does not exist.", augments[iter], iter + 1);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an augment (Aug%i) with an invalid id.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an augment (Aug%i) with an invalid id.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
@@ -268,8 +268,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
// check that augment is an actual augment
else if(augtest->AugType == 0) {
Message(13, "%s (%u) (Aug%i) is not an actual augment.", augtest->Name, augtest->ID, iter + 1);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to use a non-augment item (Aug%i) as an augment.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, item->ID, (iter + 1), aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to use a non-augment item (Aug%i) as an augment.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, item->ID, (iter + 1), aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
@@ -281,7 +281,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
else if(augtest->MinStatus && ((this->Admin() < augtest->MinStatus) || (this->Admin() < RuleI(GM, MinStatusToSummonItem)))) {
Message(13, "You are not a GM or do not have the status to summon this augment.");
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create a GM-only augment (Aug%i) with a status of %i.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, MinStatus: %u)\n",
GetName(), account_name, (iter + 1), this->Admin(), item->ID, aug1, aug2, aug3, aug4, aug5, item->MinStatus);
GetName(), account_name, (iter + 1), this->Admin(), item->ID, aug1, aug2, aug3, aug4, aug5, aug6, item->MinStatus);
return false;
}
@@ -291,16 +291,16 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
if(enforcewear) {
if((item->AugSlotType[iter] == AugTypeNone) || !(((uint32)1 << (item->AugSlotType[iter] - 1)) & augtest->AugType)) {
Message(13, "Augment %u (Aug%i) is not acceptable wear on Item %u.", augments[iter], iter + 1, item->ID);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to augment an item with an unacceptable augment type (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to augment an item with an unacceptable augment type (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
if(item->AugSlotVisible[iter] == 0) {
Message(13, "Item %u has not evolved enough to accept Augment %u (Aug%i).", item->ID, augments[iter], iter + 1);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to augment an unevolved item with augment type (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to augment an unevolved item with augment type (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
@@ -476,8 +476,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
if(restrictfail) {
Message(13, "Augment %u (Aug%i) is restricted from wear on Item %u.", augments[iter], (iter + 1), item->ID);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to augment an item with a restricted augment (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to augment an item with a restricted augment (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
@@ -487,8 +487,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
// check for class usability
if(item->Classes && !(classes &= augtest->Classes)) {
Message(13, "Augment %u (Aug%i) will result in an item not usable by any class.", augments[iter], (iter + 1));
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an item unusable by any class.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an item unusable by any class.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
@@ -496,8 +496,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
// check for race usability
if(item->Races && !(races &= augtest->Races)) {
Message(13, "Augment %u (Aug%i) will result in an item not usable by any race.", augments[iter], (iter + 1));
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an item unusable by any race.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an item unusable by any race.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
@@ -505,8 +505,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
// check for slot usability
if(item->Slots && !(slots &= augtest->Slots)) {
Message(13, "Augment %u (Aug%i) will result in an item not usable in any slot.", augments[iter], (iter + 1));
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an item unusable in any slot.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to create an item unusable in any slot.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
@@ -532,8 +532,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
if(inst == nullptr) {
Message(13, "An unknown server error has occurred and your item was not created.");
// this goes to logfile since this is a major error
LogFile->write(EQEMuLog::Error, "Player %s on account %s encountered an unknown item creation error.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5);
LogFile->write(EQEMuLog::Error, "Player %s on account %s encountered an unknown item creation error.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
}
@@ -546,12 +546,11 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
// attune item
if(attuned && inst->GetItem()->Attuneable)
inst->SetInstNoDrop(true);
inst->SetAttuned(true);
if(ornament_icon > 0 && ornament_idfile > 0) {
inst->SetOrnamentIcon(ornament_icon);
inst->SetOrnamentationIDFile(ornament_idfile);
}
inst->SetOrnamentIcon(ornament_icon);
inst->SetOrnamentationIDFile(ornament_idfile);
inst->SetOrnamentHeroModel(ornament_hero_model);
// check to see if item is usable in requested slot
if(enforceusable && (((to_slot >= MainCharm) && (to_slot <= MainAmmo)) || (to_slot == MainPowerSource))) {
@@ -559,8 +558,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
if(!(slots & ((uint32)1 << slottest))) {
Message(0, "This item is not equipable at slot %u - moving to cursor.", to_slot);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to equip an item unusable in slot %u - moved to cursor.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, to_slot, item->ID, aug1, aug2, aug3, aug4, aug5);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to equip an item unusable in slot %u - moved to cursor.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, to_slot, item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
to_slot = MainCursor;
}
@@ -581,11 +580,13 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
if((RuleB(Character, EnableDiscoveredItems)) && !GetGM()) {
if(!IsDiscovered(item_id))
DiscoverItem(item_id);
/*
// Augments should have been discovered prior to being placed on an item.
for (int iter = AUG_BEGIN; iter < EmuConstants::ITEM_COMMON_SIZE; ++iter) {
if(augments[iter] && !IsDiscovered(augments[iter]))
DiscoverItem(augments[iter]);
}
*/
}
return true;
@@ -819,7 +820,11 @@ bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client
m_inv.PutItem(slot_id, inst);
if (client_update)
{
SendItemPacket(slot_id, &inst, ((slot_id == MainCursor) ? ItemPacketSummonItem : ItemPacketTrade));
//SendWearChange(Inventory::CalcMaterialFromSlot(slot_id));
}
if (slot_id == MainCursor) {
std::list<ItemInst*>::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end();
@@ -853,7 +858,7 @@ void Client::PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootI
{
if(bag_item_data[i] == nullptr)
continue;
const ItemInst *bagitem = database.CreateItem(bag_item_data[i]->item_id, bag_item_data[i]->charges, bag_item_data[i]->aug_1, bag_item_data[i]->aug_2, bag_item_data[i]->aug_3, bag_item_data[i]->aug_4, bag_item_data[i]->aug_5);
const ItemInst *bagitem = database.CreateItem(bag_item_data[i]->item_id, bag_item_data[i]->charges, bag_item_data[i]->aug_1, bag_item_data[i]->aug_2, bag_item_data[i]->aug_3, bag_item_data[i]->aug_4, bag_item_data[i]->aug_5, bag_item_data[i]->aug_6, bag_item_data[i]->attuned);
interior_slot = Inventory::CalcSlotId(slot_id, i);
mlog(INVENTORY__SLOTS, "Putting bag loot item %s (%d) into slot %d (bag slot %d)", inst.GetItem()->Name, inst.GetItem()->ID, interior_slot, i);
PutLootInInventory(interior_slot, *bagitem);
@@ -1032,7 +1037,25 @@ bool Client::MakeItemLink(char* &ret_link, const ItemInst *inst) {
uint8 evolvedlevel = 0;
int hash = 0;
//int hash = GetItemLinkHash(inst); //eventually this will work (currently crashes zone), but for now we'll skip the extra overhead
if (GetClientVersion() >= EQClientRoF)
if (GetClientVersion() >= EQClientRoF2)
{
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%01X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item->ID,
inst->GetAugmentItemID(0),
inst->GetAugmentItemID(1),
inst->GetAugmentItemID(2),
inst->GetAugmentItemID(3),
inst->GetAugmentItemID(4),
inst->GetAugmentItemID(5),
evolving,
loregroup,
evolvedlevel,
0,
hash
);
}
else if (GetClientVersion() >= EQClientRoF)
{
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
@@ -1599,13 +1622,13 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
// Not dealing with charges - just do direct swap
if(src_inst && (dst_slot_id <= EmuConstants::EQUIPMENT_END || dst_slot_id == MainPowerSource) && dst_slot_id >= EmuConstants::EQUIPMENT_BEGIN) {
if (src_inst->GetItem()->Attuneable) {
src_inst->SetInstNoDrop(true);
src_inst->SetAttuned(true);
}
if (src_inst->IsAugmented()) {
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (src_inst->GetAugment(i)) {
if (src_inst->GetAugment(i)->GetItem()->Attuneable) {
src_inst->GetAugment(i)->SetInstNoDrop(true);
src_inst->GetAugment(i)->SetAttuned(true);
}
}
}
@@ -2274,7 +2297,7 @@ void Client::MoveSlotNotAllowed(bool client_update) {
// these functions operate with a material slot, which is from 0 to 8
uint32 Client::GetEquipment(uint8 material_slot) const
{
int invslot;
int16 invslot;
const ItemInst *item;
if(material_slot > EmuConstants::MATERIAL_END)
@@ -2283,7 +2306,7 @@ uint32 Client::GetEquipment(uint8 material_slot) const
}
invslot = Inventory::CalcSlotFromMaterial(material_slot);
if(invslot == -1)
if (invslot == INVALID_INDEX)
{
return 0;
}
+13 -6
View File
@@ -15,15 +15,20 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include "npc.h"
#include "masterentity.h"
#include "zonedb.h"
#include "../common/loottable.h"
#include "../common/misc_functions.h"
#include "client.h"
#include "entity.h"
#include "mob.h"
#include "npc.h"
#include "zonedb.h"
#include <iostream>
#include <stdlib.h>
#ifdef _WINDOWS
#define snprintf _snprintf
#endif
@@ -201,6 +206,8 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
item->aug_3 = 0;
item->aug_4 = 0;
item->aug_5 = 0;
item->aug_6 = 0;
item->attuned = 0;
item->min_level = minlevel;
item->max_level = maxlevel;
if (equipit) {
+2 -2
View File
@@ -703,13 +703,13 @@ void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
bool attuned) {
Lua_Safe_Call_Void();
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, attuned);
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned);
}
void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
bool attuned, int to_slot) {
Lua_Safe_Call_Void();
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, attuned, to_slot);
self->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attuned, to_slot);
}
void Lua_Client::SetStats(int type, int value) {
-1
View File
@@ -1759,7 +1759,6 @@ luabind::scope lua_register_client_version() {
.enum_("constants")
[
luabind::value("Unknown", static_cast<int>(EQClientUnknown)),
luabind::value("62", static_cast<int>(EQClient62)),
luabind::value("Titanium", static_cast<int>(EQClientTitanium)),
luabind::value("SoF", static_cast<int>(EQClientSoF)),
luabind::value("SoD", static_cast<int>(EQClientSoD)),
+2 -2
View File
@@ -166,12 +166,12 @@ uint32 Lua_ItemInst::GetColor() {
bool Lua_ItemInst::IsInstNoDrop() {
Lua_Safe_Call_Bool();
return self->IsInstNoDrop();
return self->IsAttuned();
}
void Lua_ItemInst::SetInstNoDrop(bool flag) {
Lua_Safe_Call_Void();
return self->SetInstNoDrop(flag);
return self->SetAttuned(flag);
}
std::string Lua_ItemInst::GetCustomDataString() {
+4 -4
View File
@@ -1,15 +1,15 @@
#include "../common/debug.h"
#include "../common/misc_functions.h"
#include "map.h"
#include "raycast_mesh.h"
#include "zone.h"
#include <stdint.h>
#include <algorithm>
#include <locale>
#include <vector>
#include <map>
#include <memory>
#include <tuple>
#include <map>
#include <vector>
#include <zlib.h>
uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max) {
-1
View File
@@ -24,7 +24,6 @@
#include "position.h"
#include <stdio.h>
#include <string>
#define BEST_Z_INVALID -99999
+29 -158
View File
@@ -1,18 +1,21 @@
#include "merc.h"
#include "masterentity.h"
#include "npc_ai.h"
#include "../common/packet_dump.h"
#include "client.h"
#include "corpse.h"
#include "entity.h"
#include "groups.h"
#include "mob.h"
#include "../common/eq_packet_structs.h"
#include "../common/eq_constants.h"
#include "../common/skills.h"
#include "../common/spdat.h"
#include "zone.h"
#include "string_ids.h"
#include "../common/misc_functions.h"
#include "../common/string_util.h"
#include "../common/rulesys.h"
#include "quest_parser_collection.h"
#include "water_map.h"
extern volatile bool ZoneLoaded;
@@ -1196,18 +1199,32 @@ 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;
/*
// Wear Slots are not setup for Mercs yet
unsigned int i;
//should not include 21 (SLOT_AMMO)
for (i = 0; i < MainAmmo; i++) {
if(equipment[i] == 0)
for (i = 0; i < _MaterialCount; i++)
{
if (equipment[i] == 0)
{
continue;
}
const Item_Struct* item = database.GetItem(equipment[i]);
if(item)
{
ns->spawn.equipment[i] = item->Material;
ns->spawn.colors[i].color = item->Color;
ns->spawn.equipment[i].material = item->Material;
ns->spawn.equipment[i].elitematerial = item->EliteMaterial;
ns->spawn.equipment[i].heroforgemodel = item->HerosForgeModel;
if (armor_tint[i])
{
ns->spawn.colors[i].color = armor_tint[i];
}
else
{
ns->spawn.colors[i].color = item->Color;
}
}
}
*/
}
}
@@ -2656,153 +2673,6 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) {
return realTotal + realTotal2 + realTotal3;
}
int32 Merc::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
if (spells[spell_id].targettype == ST_Self)
return value;
bool Critical = false;
int32 value_BaseEffect = 0;
value_BaseEffect = value + (value*GetFocusEffect(focusFcBaseEffects, spell_id)/100);
int chance = RuleI(Spells, BaseCritChance);
chance += itembonuses.CriticalSpellChance + spellbonuses.CriticalSpellChance + aabonuses.CriticalSpellChance;
if (chance > 0){
int32 ratio = RuleI(Spells, BaseCritRatio); //Critical modifier is applied from spell effects only. Keep at 100 for live like criticals.
if (zone->random.Roll(chance)) {
Critical = true;
ratio += itembonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncrease + aabonuses.SpellCritDmgIncrease;
ratio += itembonuses.SpellCritDmgIncNoStack + spellbonuses.SpellCritDmgIncNoStack + aabonuses.SpellCritDmgIncNoStack;
}
else if (GetClass() == CASTERDPS && (GetLevel() >= RuleI(Spells, WizCritLevel)) && (zone->random.Roll(RuleI(Spells, WizCritChance)))) {
ratio = zone->random.Int(1,100); //Wizard innate critical chance is calculated seperately from spell effect and is not a set ratio.
Critical = true;
}
ratio += RuleI(Spells, WizCritRatio); //Default is zero
if (Critical){
value = value_BaseEffect*ratio/100;
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
value += int(value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100)*ratio/100;
if (target) {
value += int(value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100)*ratio/100;
value -= target->GetFcDamageAmtIncoming(this, spell_id);
}
value -= GetFocusEffect(focusFcDamageAmtCrit, spell_id)*ratio/100;
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
value = (value * GetSpellScale() / 100);
entity_list.MessageClose_StringID(this, false, 100, MT_SpellCrits,
OTHER_CRIT_BLAST, GetName(), itoa(-value));
return value;
}
}
value = value_BaseEffect;
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
value += value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100;
if (target) {
value += value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100;
value -= target->GetFcDamageAmtIncoming(this, spell_id);
}
value -= GetFocusEffect(focusFcDamageAmtCrit, spell_id);
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
value = (value * GetSpellScale() / 100);
return value;
}
int32 Merc::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
if (target == nullptr)
target = this;
int32 value_BaseEffect = 0;
int16 chance = 0;
int8 modifier = 1;
bool Critical = false;
value_BaseEffect = value + (value*GetFocusEffect(focusFcBaseEffects, spell_id)/100);
value = value_BaseEffect;
value += int(value_BaseEffect*GetFocusEffect(focusImprovedHeal, spell_id)/100);
// Instant Heals
if(spells[spell_id].buffduration < 1) {
chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
chance += target->GetFocusIncoming(focusFcHealPctCritIncoming, SE_FcHealPctCritIncoming, this, spell_id);
if (spellbonuses.CriticalHealDecay)
chance += GetDecayEffectValue(spell_id, SE_CriticalHealDecay);
if(chance && zone->random.Roll(chance)) {
Critical = true;
modifier = 2; //At present time no critical heal amount modifier SPA exists.
}
value *= modifier;
value += GetFocusEffect(focusFcHealAmtCrit, spell_id) * modifier;
value += GetFocusEffect(focusFcHealAmt, spell_id);
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id);
if(itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, value) * modifier;
value += value*target->GetHealRate(spell_id, this)/100;
if (Critical)
entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s performs an exceptional heal! (%d)", GetName(), value);
return value;
}
//Heal over time spells. [Heal Rate and Additional Healing effects do not increase this value]
else {
chance = itembonuses.CriticalHealOverTime + spellbonuses.CriticalHealOverTime + aabonuses.CriticalHealOverTime;
chance += target->GetFocusIncoming(focusFcHealPctCritIncoming, SE_FcHealPctCritIncoming, this, spell_id);
if (spellbonuses.CriticalRegenDecay)
chance += GetDecayEffectValue(spell_id, SE_CriticalRegenDecay);
if(chance && zone->random.Roll(chance))
return (value * 2);
}
return value;
}
int32 Merc::GetActSpellCost(uint16 spell_id, int32 cost)
{
// Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell
@@ -4905,6 +4775,7 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
npc_type->npc_id = 0; //NPC ID has to be 0, otherwise db gets all confuzzled.
npc_type->class_ = merc_template->ClassID;
npc_type->maxlevel = 0; //We should hard-set this to override scalerate's functionality in the NPC class when it is constructed.
npc_type->no_target_hotkey = 1;
Merc* merc = new Merc(npc_type, c->GetX(), c->GetY(), c->GetZ(), 0);
+11 -4
View File
@@ -1,9 +1,18 @@
#ifndef MERC_H
#define MERC_H
#include "mob.h"
#include "zonedb.h"
#include "npc.h"
class Client;
class Corpse;
class Group;
class Mob;
class Raid;
struct Item_Struct;
struct MercTemplate;
struct NPCType;
struct NewSpawn_Struct;
#define MERC_DEBUG 0
#define MAXMERCS 1
#define TANK 1
@@ -83,8 +92,6 @@ public:
Corpse* GetGroupMemberCorpse();
// Merc Spell Casting Methods
virtual int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
virtual int32 GetActSpellCost(uint16 spell_id, int32 cost);
int8 GetChanceToCastBySpellType(int16 spellType);
+198 -129
View File
@@ -27,6 +27,10 @@
#include <math.h>
#include <sstream>
#ifdef BOTS
#include "bot.h"
#endif
extern EntityList entity_list;
extern Zone* zone;
@@ -512,6 +516,8 @@ float Mob::_GetMovementSpeed(int mod) const
// http://everquest.allakhazam.com/db/item.html?item=1721;page=1;howmany=50#m10822246245352
if (IsRooted())
return 0.0f;
else if (IsPseudoRooted())
return 0.00001f;
float speed_mod = runspeed;
@@ -897,7 +903,8 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
ns->spawn.invis = (invisible || hidden) ? 1 : 0; // TODO: load this before spawning players
ns->spawn.NPC = IsClient() ? 0 : 1;
ns->spawn.IsMercenary = (IsMerc() || no_target_hotkey) ? 1 : 0;
ns->spawn.IsMercenary = IsMerc() ? 1 : 0;
ns->spawn.targetable_with_hotkey = no_target_hotkey ? 0 : 1; // opposite logic!
ns->spawn.petOwnerId = ownerid;
@@ -933,9 +940,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
// 3 - Mobs in water do not sink. A value of 3 in this field appears to be the default setting for all mobs
// (in water or not) according to 6.2 era packet collects.
if(IsClient())
{
ns->spawn.flymode = FindType(SE_Levitate) ? 2 : 0;
}
else
ns->spawn.flymode = flymode;
@@ -943,15 +948,14 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
for(i = 0; i < _MaterialCount; i++)
for (i = 0; i < _MaterialCount; i++)
{
ns->spawn.equipment[i] = GetEquipmentMaterial(i);
if (armor_tint[i])
{
ns->spawn.colors[i].color = armor_tint[i];
}
else
// Only Player Races Wear Armor
if (Mob::IsPlayerRace(race) || i > 6)
{
ns->spawn.equipment[i].material = GetEquipmentMaterial(i);
ns->spawn.equipment[i].elitematerial = IsEliteMaterialItem(i);
ns->spawn.equipment[i].heroforgemodel = GetHerosForgeModel(i);
ns->spawn.colors[i].color = GetEquipmentColor(i);
}
}
@@ -974,7 +978,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
//ns->spawn.DestructibleAppearance = static_cast<EmuAppearance>(_appearance);
// #appearance 44 1 makes it jump but no visible damage
// #appearance 44 2 makes it look completely broken but still visible
// #appearnace 44 3 makes it jump but not visible difference to 3
// #appearance 44 3 makes it jump but not visible difference to 3
// #appearance 44 4 makes it disappear altogether
// #appearance 44 5 makes the client crash.
@@ -2560,8 +2564,8 @@ uint32 NPC::GetEquipment(uint8 material_slot) const
{
if(material_slot > 8)
return 0;
int invslot = Inventory::CalcSlotFromMaterial(material_slot);
if (invslot == -1)
int16 invslot = Inventory::CalcSlotFromMaterial(material_slot);
if (invslot == INVALID_INDEX)
return 0;
return equipment[invslot];
}
@@ -2574,6 +2578,7 @@ void Mob::SendWearChange(uint8 material_slot)
wc->spawn_id = GetID();
wc->material = GetEquipmentMaterial(material_slot);
wc->elite_material = IsEliteMaterialItem(material_slot);
wc->hero_forge_model = GetHerosForgeModel(material_slot);
wc->color.color = GetEquipmentColor(material_slot);
wc->wear_slot_id = material_slot;
@@ -2618,6 +2623,7 @@ void Mob::SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uin
wc->spawn_id = this->GetID();
wc->material = GetEquipmentMaterial(material_slot);
wc->hero_forge_model = GetHerosForgeModel(material_slot);
wc->color.color = color;
wc->wear_slot_id = material_slot;
@@ -2625,7 +2631,7 @@ void Mob::SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uin
safe_delete(outapp);
}
void Mob::WearChange(uint8 material_slot, uint16 texture, uint32 color)
void Mob::WearChange(uint8 material_slot, uint16 texture, uint32 color, uint32 hero_forge_model)
{
armor_tint[material_slot] = color;
@@ -2634,6 +2640,7 @@ void Mob::WearChange(uint8 material_slot, uint16 texture, uint32 color)
wc->spawn_id = this->GetID();
wc->material = texture;
wc->hero_forge_model = hero_forge_model;
wc->color.color = color;
wc->wear_slot_id = material_slot;
@@ -2643,60 +2650,114 @@ void Mob::WearChange(uint8 material_slot, uint16 texture, uint32 color)
int32 Mob::GetEquipmentMaterial(uint8 material_slot) const
{
uint32 equipmaterial = 0;
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
const Item_Struct *item;
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
item = database.GetItem(GetEquipment(material_slot));
if(item != 0)
if (item != 0)
{
if // for primary and secondary we need the model, not the material
(
material_slot == MaterialPrimary ||
material_slot == MaterialSecondary
)
// For primary and secondary we need the model, not the material
if (material_slot == MaterialPrimary || material_slot == MaterialSecondary)
{
if (this->IsClient()){
int currMatslot = MaterialPrimary == material_slot ? MainPrimary : MainSecondary;
const ItemInst* inst = CastToClient()->m_inv[currMatslot];
if (inst && inst->GetOrnamentationAug(ornamentationAugtype)) {
item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
return atoi(&item->IDFile[2]);
if (this->IsClient())
{
int16 invslot = Inventory::CalcSlotFromMaterial(material_slot);
if (invslot == INVALID_INDEX)
{
return 0;
}
else if (inst->GetOrnamentationIcon() && inst->GetOrnamentationIDFile()) {
return inst->GetOrnamentationIDFile();
}
else {
if (strlen(item->IDFile) > 2)
return atoi(&item->IDFile[2]);
else //may as well try this, since were going to 0 anyways
return item->Material;
const ItemInst* inst = CastToClient()->m_inv[invslot];
if (inst)
{
if (inst->GetOrnamentationAug(ornamentationAugtype))
{
item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
if (item && strlen(item->IDFile) > 2)
{
equipmaterial = atoi(&item->IDFile[2]);
}
}
else if (inst->GetOrnamentationIDFile())
{
equipmaterial = inst->GetOrnamentationIDFile();
}
}
}
else {
if (strlen(item->IDFile) > 2)
return atoi(&item->IDFile[2]);
else //may as well try this, since were going to 0 anyways
return item->Material;
if (equipmaterial == 0 && strlen(item->IDFile) > 2)
{
equipmaterial = atoi(&item->IDFile[2]);
}
}
else
{
return item->Material;
equipmaterial = item->Material;
}
}
return 0;
return equipmaterial;
}
int32 Mob::GetHerosForgeModel(uint8 material_slot) const
{
uint32 HeroModel = 0;
if (material_slot >= 0 && material_slot < MaterialPrimary)
{
uint32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
const Item_Struct *item;
item = database.GetItem(GetEquipment(material_slot));
int16 invslot = Inventory::CalcSlotFromMaterial(material_slot);
if (item != 0 && invslot != INVALID_INDEX)
{
if (this->IsClient())
{
const ItemInst* inst = CastToClient()->m_inv[invslot];
if (inst)
{
if (inst->GetOrnamentationAug(ornamentationAugtype))
{
item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
HeroModel = item->HerosForgeModel;
}
else if (inst->GetOrnamentHeroModel())
{
HeroModel = inst->GetOrnamentHeroModel();
}
}
}
if (HeroModel == 0)
{
HeroModel = item->HerosForgeModel;
}
}
}
if (HeroModel > 0)
{
HeroModel *= 100;
HeroModel += material_slot;
}
return HeroModel;
}
uint32 Mob::GetEquipmentColor(uint8 material_slot) const
{
const Item_Struct *item;
item = database.GetItem(GetEquipment(material_slot));
if(item != 0)
if (armor_tint[material_slot])
{
return item->Color;
return armor_tint[material_slot];
}
item = database.GetItem(GetEquipment(material_slot));
if (item != 0)
return item->Color;
return 0;
}
@@ -2894,6 +2955,10 @@ uint32 Mob::GetLevelHP(uint8 tlevel)
}
int32 Mob::GetActSpellCasttime(uint16 spell_id, int32 casttime) {
int32 cast_reducer = 0;
cast_reducer += GetFocusEffect(focusSpellHaste, spell_id);
if (level >= 60 && casttime > 1000)
{
casttime = casttime / 2;
@@ -2906,7 +2971,9 @@ int32 Mob::GetActSpellCasttime(uint16 spell_id, int32 casttime) {
else
casttime -= cast_deduction;
}
return(casttime);
casttime = (casttime*(100 - cast_reducer)/100);
return casttime;
}
void Mob::ExecWeaponProc(const ItemInst *inst, uint16 spell_id, Mob *on) {
@@ -3757,6 +3824,8 @@ int32 Mob::GetItemStat(uint32 itemid, const char *identifier)
stat = int32(item->CastTime);
if (id == "elitematerial")
stat = int32(item->EliteMaterial);
if (id == "herosforgemodel")
stat = int32(item->HerosForgeModel);
if (id == "procrate")
stat = int32(item->ProcRate);
if (id == "combateffects")
@@ -5205,99 +5274,99 @@ int32 Mob::GetSpellStat(uint32 spell_id, const char *identifier, uint8 slot)
}
if (slot < 16){
if (id == "classes") {stat = spells[spell_id].classes[slot]; }
else if (id == "dieties") {stat = spells[spell_id].deities[slot];}
if (id == "classes") {return spells[spell_id].classes[slot]; }
else if (id == "dieties") {return spells[spell_id].deities[slot];}
}
if (slot < 12){
if (id == "base") {stat = spells[spell_id].base[slot];}
else if (id == "base2") {stat = spells[spell_id].base2[slot];}
else if (id == "max") {stat = spells[spell_id].max[slot];}
else if (id == "formula") {spells[spell_id].formula[slot];}
else if (id == "effectid") {spells[spell_id].effectid[slot];}
if (id == "base") {return spells[spell_id].base[slot];}
else if (id == "base2") {return spells[spell_id].base2[slot];}
else if (id == "max") {return spells[spell_id].max[slot];}
else if (id == "formula") {return spells[spell_id].formula[slot];}
else if (id == "effectid") {return spells[spell_id].effectid[slot];}
}
if (slot < 4){
if (id == "components") { spells[spell_id].components[slot];}
else if (id == "component_counts") {spells[spell_id].component_counts[slot];}
else if (id == "NoexpendReagent") {spells[spell_id].NoexpendReagent[slot];}
if (id == "components") { return spells[spell_id].components[slot];}
else if (id == "component_counts") { return spells[spell_id].component_counts[slot];}
else if (id == "NoexpendReagent") {return spells[spell_id].NoexpendReagent[slot];}
}
if (id == "range") {stat = static_cast<int32>(spells[spell_id].range); }
else if (id == "aoerange") {stat = static_cast<int32>(spells[spell_id].aoerange);}
else if (id == "pushback") {stat = static_cast<int32>(spells[spell_id].pushback);}
else if (id == "pushup") {stat = static_cast<int32>(spells[spell_id].pushup);}
else if (id == "cast_time") {stat = spells[spell_id].cast_time;}
else if (id == "recovery_time") {stat = spells[spell_id].recovery_time;}
else if (id == "recast_time") {stat = spells[spell_id].recast_time;}
else if (id == "buffdurationformula") {stat = spells[spell_id].buffdurationformula;}
else if (id == "buffduration") {stat = spells[spell_id].buffduration;}
else if (id == "AEDuration") {stat = spells[spell_id].AEDuration;}
else if (id == "mana") {stat = spells[spell_id].mana;}
if (id == "range") {return static_cast<int32>(spells[spell_id].range); }
else if (id == "aoerange") {return static_cast<int32>(spells[spell_id].aoerange);}
else if (id == "pushback") {return static_cast<int32>(spells[spell_id].pushback);}
else if (id == "pushup") {return static_cast<int32>(spells[spell_id].pushup);}
else if (id == "cast_time") {return spells[spell_id].cast_time;}
else if (id == "recovery_time") {return spells[spell_id].recovery_time;}
else if (id == "recast_time") {return spells[spell_id].recast_time;}
else if (id == "buffdurationformula") {return spells[spell_id].buffdurationformula;}
else if (id == "buffduration") {return spells[spell_id].buffduration;}
else if (id == "AEDuration") {return spells[spell_id].AEDuration;}
else if (id == "mana") {return spells[spell_id].mana;}
//else if (id == "LightType") {stat = spells[spell_id].LightType;} - Not implemented
else if (id == "goodEffect") {stat = spells[spell_id].goodEffect;}
else if (id == "Activated") {stat = spells[spell_id].Activated;}
else if (id == "resisttype") {stat = spells[spell_id].resisttype;}
else if (id == "targettype") {stat = spells[spell_id].targettype;}
else if (id == "basedeiff") {stat = spells[spell_id].basediff;}
else if (id == "skill") {stat = spells[spell_id].skill;}
else if (id == "zonetype") {stat = spells[spell_id].zonetype;}
else if (id == "EnvironmentType") {stat = spells[spell_id].EnvironmentType;}
else if (id == "TimeOfDay") {stat = spells[spell_id].TimeOfDay;}
else if (id == "CastingAnim") {stat = spells[spell_id].CastingAnim;}
else if (id == "SpellAffectIndex") {stat = spells[spell_id].SpellAffectIndex; }
else if (id == "disallow_sit") {stat = spells[spell_id].disallow_sit; }
else if (id == "goodEffect") {return spells[spell_id].goodEffect;}
else if (id == "Activated") {return spells[spell_id].Activated;}
else if (id == "resisttype") {return spells[spell_id].resisttype;}
else if (id == "targettype") {return spells[spell_id].targettype;}
else if (id == "basedeiff") {return spells[spell_id].basediff;}
else if (id == "skill") {return spells[spell_id].skill;}
else if (id == "zonetype") {return spells[spell_id].zonetype;}
else if (id == "EnvironmentType") {return spells[spell_id].EnvironmentType;}
else if (id == "TimeOfDay") {return spells[spell_id].TimeOfDay;}
else if (id == "CastingAnim") {return spells[spell_id].CastingAnim;}
else if (id == "SpellAffectIndex") {return spells[spell_id].SpellAffectIndex; }
else if (id == "disallow_sit") {return spells[spell_id].disallow_sit; }
//else if (id == "spellanim") {stat = spells[spell_id].spellanim; } - Not implemented
else if (id == "uninterruptable") {stat = spells[spell_id].uninterruptable; }
else if (id == "ResistDiff") {stat = spells[spell_id].ResistDiff; }
else if (id == "dot_stacking_exemp") {stat = spells[spell_id].dot_stacking_exempt; }
else if (id == "RecourseLink") {stat = spells[spell_id].RecourseLink; }
else if (id == "no_partial_resist") {stat = spells[spell_id].no_partial_resist; }
else if (id == "short_buff_box") {stat = spells[spell_id].short_buff_box; }
else if (id == "descnum") {stat = spells[spell_id].descnum; }
else if (id == "effectdescnum") {stat = spells[spell_id].effectdescnum; }
else if (id == "npc_no_los") {stat = spells[spell_id].npc_no_los; }
else if (id == "reflectable") {stat = spells[spell_id].reflectable; }
else if (id == "bonushate") {stat = spells[spell_id].bonushate; }
else if (id == "EndurCost") {stat = spells[spell_id].EndurCost; }
else if (id == "EndurTimerIndex") {stat = spells[spell_id].EndurTimerIndex; }
else if (id == "IsDisciplineBuf") {stat = spells[spell_id].IsDisciplineBuff; }
else if (id == "HateAdded") {stat = spells[spell_id].HateAdded; }
else if (id == "EndurUpkeep") {stat = spells[spell_id].EndurUpkeep; }
else if (id == "numhitstype") {stat = spells[spell_id].numhitstype; }
else if (id == "numhits") {stat = spells[spell_id].numhits; }
else if (id == "pvpresistbase") {stat = spells[spell_id].pvpresistbase; }
else if (id == "pvpresistcalc") {stat = spells[spell_id].pvpresistcalc; }
else if (id == "pvpresistcap") {stat = spells[spell_id].pvpresistcap; }
else if (id == "spell_category") {stat = spells[spell_id].spell_category; }
else if (id == "can_mgb") {stat = spells[spell_id].can_mgb; }
else if (id == "dispel_flag") {stat = spells[spell_id].dispel_flag; }
else if (id == "MinResist") {stat = spells[spell_id].MinResist; }
else if (id == "MaxResist") {stat = spells[spell_id].MaxResist; }
else if (id == "viral_targets") {stat = spells[spell_id].viral_targets; }
else if (id == "viral_timer") {stat = spells[spell_id].viral_timer; }
else if (id == "NimbusEffect") {stat = spells[spell_id].NimbusEffect; }
else if (id == "directional_start") {stat = static_cast<int32>(spells[spell_id].directional_start); }
else if (id == "directional_end") {stat = static_cast<int32>(spells[spell_id].directional_end); }
else if (id == "not_extendable") {stat = spells[spell_id].not_extendable; }
else if (id == "suspendable") {stat = spells[spell_id].suspendable; }
else if (id == "viral_range") {stat = spells[spell_id].viral_range; }
else if (id == "spellgroup") {stat = spells[spell_id].spellgroup; }
else if (id == "rank") {stat = spells[spell_id].rank; }
else if (id == "powerful_flag") {stat = spells[spell_id].powerful_flag; }
else if (id == "CastRestriction") {stat = spells[spell_id].CastRestriction; }
else if (id == "AllowRest") {stat = spells[spell_id].AllowRest; }
else if (id == "InCombat") {stat = spells[spell_id].InCombat; }
else if (id == "OutofCombat") {stat = spells[spell_id].OutofCombat; }
else if (id == "aemaxtargets") {stat = spells[spell_id].aemaxtargets; }
else if (id == "maxtargets") {stat = spells[spell_id].maxtargets; }
else if (id == "persistdeath") {stat = spells[spell_id].persistdeath; }
else if (id == "min_dist") {stat = static_cast<int32>(spells[spell_id].min_dist); }
else if (id == "min_dist_mod") {stat = static_cast<int32>(spells[spell_id].min_dist_mod); }
else if (id == "max_dist") {stat = static_cast<int32>(spells[spell_id].max_dist); }
else if (id == "min_range") {stat = static_cast<int32>(spells[spell_id].min_range); }
else if (id == "DamageShieldType") {stat = spells[spell_id].DamageShieldType; }
else if (id == "uninterruptable") {return spells[spell_id].uninterruptable; }
else if (id == "ResistDiff") {return spells[spell_id].ResistDiff; }
else if (id == "dot_stacking_exemp") {return spells[spell_id].dot_stacking_exempt; }
else if (id == "RecourseLink") {return spells[spell_id].RecourseLink; }
else if (id == "no_partial_resist") {return spells[spell_id].no_partial_resist; }
else if (id == "short_buff_box") {return spells[spell_id].short_buff_box; }
else if (id == "descnum") {return spells[spell_id].descnum; }
else if (id == "effectdescnum") {return spells[spell_id].effectdescnum; }
else if (id == "npc_no_los") {return spells[spell_id].npc_no_los; }
else if (id == "reflectable") {return spells[spell_id].reflectable; }
else if (id == "bonushate") {return spells[spell_id].bonushate; }
else if (id == "EndurCost") {return spells[spell_id].EndurCost; }
else if (id == "EndurTimerIndex") {return spells[spell_id].EndurTimerIndex; }
else if (id == "IsDisciplineBuf") {return spells[spell_id].IsDisciplineBuff; }
else if (id == "HateAdded") {return spells[spell_id].HateAdded; }
else if (id == "EndurUpkeep") {return spells[spell_id].EndurUpkeep; }
else if (id == "numhitstype") {return spells[spell_id].numhitstype; }
else if (id == "numhits") {return spells[spell_id].numhits; }
else if (id == "pvpresistbase") {return spells[spell_id].pvpresistbase; }
else if (id == "pvpresistcalc") {return spells[spell_id].pvpresistcalc; }
else if (id == "pvpresistcap") {return spells[spell_id].pvpresistcap; }
else if (id == "spell_category") {return spells[spell_id].spell_category; }
else if (id == "can_mgb") {return spells[spell_id].can_mgb; }
else if (id == "dispel_flag") {return spells[spell_id].dispel_flag; }
else if (id == "MinResist") {return spells[spell_id].MinResist; }
else if (id == "MaxResist") {return spells[spell_id].MaxResist; }
else if (id == "viral_targets") {return spells[spell_id].viral_targets; }
else if (id == "viral_timer") {return spells[spell_id].viral_timer; }
else if (id == "NimbusEffect") {return spells[spell_id].NimbusEffect; }
else if (id == "directional_start") {return static_cast<int32>(spells[spell_id].directional_start); }
else if (id == "directional_end") {return static_cast<int32>(spells[spell_id].directional_end); }
else if (id == "not_extendable") {return spells[spell_id].not_extendable; }
else if (id == "suspendable") {return spells[spell_id].suspendable; }
else if (id == "viral_range") {return spells[spell_id].viral_range; }
else if (id == "spellgroup") {return spells[spell_id].spellgroup; }
else if (id == "rank") {return spells[spell_id].rank; }
else if (id == "powerful_flag") {return spells[spell_id].powerful_flag; }
else if (id == "CastRestriction") {return spells[spell_id].CastRestriction; }
else if (id == "AllowRest") {return spells[spell_id].AllowRest; }
else if (id == "InCombat") {return spells[spell_id].InCombat; }
else if (id == "OutofCombat") {return spells[spell_id].OutofCombat; }
else if (id == "aemaxtargets") {return spells[spell_id].aemaxtargets; }
else if (id == "maxtargets") {return spells[spell_id].maxtargets; }
else if (id == "persistdeath") {return spells[spell_id].persistdeath; }
else if (id == "min_dist") {return static_cast<int32>(spells[spell_id].min_dist); }
else if (id == "min_dist_mod") {return static_cast<int32>(spells[spell_id].min_dist_mod); }
else if (id == "max_dist") {return static_cast<int32>(spells[spell_id].max_dist); }
else if (id == "min_range") {return static_cast<int32>(spells[spell_id].min_range); }
else if (id == "DamageShieldType") {return spells[spell_id].DamageShieldType; }
return stat;
}
+9 -6
View File
@@ -169,7 +169,7 @@ public:
virtual void SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model = 0, uint32 elite_material = 0,
uint32 unknown06 = 0, uint32 unknown18 = 0);
virtual void SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint);
virtual void WearChange(uint8 material_slot, uint16 texture, uint32 color);
virtual void WearChange(uint8 material_slot, uint16 texture, uint32 color, uint32 hero_forge_model = 0);
void DoAnim(const int animnum, int type=0, bool ackreq = true, eqFilterType filter = FilterNone);
void ProjectileAnimation(Mob* to, int item_id, bool IsArrow = false, float speed = 0,
float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr, SkillUseTypes skillInUse = SkillArchery);
@@ -196,11 +196,12 @@ public:
bool item_bonus = false, uint32 ticsremaining = 0, int buffslot = -1,
bool IsAISpellEffect = false, uint16 effect_id = 0, int32 se_base = 0, int32 se_limit = 0, int32 se_max = 0);
void NegateSpellsBonuses(uint16 spell_id);
virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false) { return range;}
virtual int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr) { return value; }
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr) { return value; }
virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false);
virtual int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
virtual int32 GetActDoTDamage(uint16 spell_id, int32 value, Mob* target);
virtual int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
virtual int32 GetActSpellCost(uint16 spell_id, int32 cost){ return cost;}
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration){ return duration;}
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration);
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
float ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use_resist_override = false,
int resist_override = 0, bool CharismaCheck = false, bool CharmTick = false, bool IsRoot = false);
@@ -309,6 +310,7 @@ public:
virtual uint16 GetSkill(SkillUseTypes skill_num) const { return 0; }
virtual uint32 GetEquipment(uint8 material_slot) const { return(0); }
virtual int32 GetEquipmentMaterial(uint8 material_slot) const;
virtual int32 GetHerosForgeModel(uint8 material_slot) const;
virtual uint32 GetEquipmentColor(uint8 material_slot) const;
virtual uint32 IsEliteMaterialItem(uint8 material_slot) const;
bool AffectedBySpellExcludingSlot(int slot, int effect);
@@ -1037,6 +1039,7 @@ protected:
int GetKickDamage();
int GetBashDamage();
virtual void ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg);
virtual int16 GetFocusEffect(focusType type, uint16 spell_id) { return 0; }
void CalculateNewFearpoint();
float FindGroundZ(float new_x, float new_y, float z_offset=0.0);
Map::Vertex UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached);
@@ -1206,7 +1209,7 @@ protected:
Map::Vertex PathingLastPosition;
int PathingLoopCount;
int PathingLastNodeVisited;
std::list<int> Route;
std::deque<int> Route;
LOSType PathingLOSState;
Timer *PathingLOSCheckTimer;
Timer *PathingRouteUpdateTimerShort;
+16 -16
View File
@@ -15,25 +15,25 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include "npc.h"
#include "masterentity.h"
#include "npc_ai.h"
#include "map.h"
#include "../common/moremath.h"
#include "string_ids.h"
#include "../common/misc_functions.h"
#include "../common/string_util.h"
#include "../common/rulesys.h"
#include "../common/features.h"
#include "../common/rulesys.h"
#include "../common/string_util.h"
#include "client.h"
#include "entity.h"
#include "map.h"
#include "mob.h"
#include "npc.h"
#include "quest_parser_collection.h"
#include "string_ids.h"
#include "water_map.h"
#include <algorithm>
#include <iostream>
#include <math.h>
extern EntityList entity_list;
extern Zone *zone;
@@ -1085,7 +1085,7 @@ void Mob::AI_Process() {
{
// we are prevented from getting here if we are blind and don't have a target in range
// from above, so no extra blind checks needed
if (IsRooted() || IsBlind())
if ((IsRooted() && !GetSpecialAbility(IGNORE_ROOT_AGGRO_RULES)) || IsBlind())
SetTarget(hate_list.GetClosest(this));
else
{
@@ -2730,7 +2730,7 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) {
npc_spells_cache[iDBSpellsID]->attack_proc = tmpattack_proc;
npc_spells_cache[iDBSpellsID]->proc_chance = tmpproc_chance;
npc_spells_cache[iDBSpellsID]->range_proc = tmprange_proc;
npc_spells_cache[iDBSpellsID]->rproc_chance = tmpdproc_chance;
npc_spells_cache[iDBSpellsID]->rproc_chance = tmprproc_chance;
npc_spells_cache[iDBSpellsID]->defensive_proc = tmpdefensive_proc;
npc_spells_cache[iDBSpellsID]->dproc_chance = tmpdproc_chance;
npc_spells_cache[iDBSpellsID]->fail_recast = tmppfail_recast;
+15 -10
View File
@@ -464,7 +464,7 @@ void NPC::CheckMinMaxLevel(Mob *them)
if(themlevel < (*cur)->min_level || themlevel > (*cur)->max_level)
{
material = Inventory::CalcMaterialFromSlot((*cur)->equip_slot);
if(material != 0xFF)
if (material != _MaterialInvalid)
SendWearChange(material);
cur = itemlist.erase(cur);
@@ -1310,11 +1310,14 @@ int32 NPC::GetEquipmentMaterial(uint8 material_slot) const
if (material_slot >= _MaterialCount)
return 0;
int inv_slot = Inventory::CalcSlotFromMaterial(material_slot);
if (inv_slot == -1)
int16 invslot = Inventory::CalcSlotFromMaterial(material_slot);
if (invslot == INVALID_INDEX)
return 0;
if(equipment[inv_slot] == 0) {
switch(material_slot) {
if (equipment[invslot] == 0)
{
switch(material_slot)
{
case MaterialHead:
return helmtexture;
case MaterialChest:
@@ -1330,7 +1333,7 @@ int32 NPC::GetEquipmentMaterial(uint8 material_slot) const
}
//they have some loot item in this slot, pass it up to the default handler
return(Mob::GetEquipmentMaterial(material_slot));
return (Mob::GetEquipmentMaterial(material_slot));
}
uint32 NPC::GetMaxDamage(uint8 tlevel)
@@ -1849,14 +1852,15 @@ void NPC::PetOnSpawn(NewSpawn_Struct* ns)
{
SetPetOwnerClient(true); //Simple flag to determine if pet belongs to a client
SetAllowBeneficial(1);//Allow temp pets to receive buffs and heals if owner is client.
//This is a hack to allow CLIENT swarm pets NOT to be targeted with F8. Warning: Will turn name 'Yellow'!
if (RuleB(Pets, SwarmPetNotTargetableWithHotKey))
ns->spawn.IsMercenary = 1;
//This will allow CLIENT swarm pets NOT to be targeted with F8.
ns->spawn.targetable_with_hotkey = 0;
no_target_hotkey = 1;
}
else
{
//NPC cast swarm pets should still be targetable with F8.
ns->spawn.IsMercenary = 0;
ns->spawn.targetable_with_hotkey = 1;
no_target_hotkey = 0;
}
SetTempPet(true); //Simple mob flag for checking if temp pet
@@ -1926,6 +1930,7 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; }
else if(id == "special_abilities") { ProcessSpecialAbilities(val.c_str()); return; }
else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; }
else if(id == "attack_delay") { attack_delay = atoi(val.c_str()); CalcBonuses(); return; }
else if(id == "atk") { ATK = atoi(val.c_str()); return; }
else if(id == "accuracy") { accuracy_rating = atoi(val.c_str()); return; }
else if(id == "avoidance") { avoidance_rating = atoi(val.c_str()); return; }
+5 -5
View File
@@ -135,9 +135,6 @@ public:
void CalcNPCRegen();
void CalcNPCDamage();
int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr);
int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr);
virtual void SetTarget(Mob* mob);
virtual uint16 GetSkill(SkillUseTypes skill_num) const { if (skill_num <= HIGHEST_SKILL) { return skills[skill_num]; } return 0; }
@@ -158,6 +155,7 @@ public:
virtual void RangedAttack(Mob* other);
virtual void ThrowingAttack(Mob* other) { }
int32 GetNumberOfAttacks() const { return attack_count; }
void DoRangedAttackDmg(Mob* other, bool Launch=true, int16 damage_mod=0, int16 chance_mod=0, SkillUseTypes skill=SkillArchery, float speed=4.0f, const char *IDFile = nullptr);
bool DatabaseCastAccepted(int spell_id);
bool IsFactionListAlly(uint32 other_faction);
@@ -256,6 +254,7 @@ public:
uint32 GetMinDMG() const {return min_dmg;}
int16 GetSlowMitigation() const {return slow_mitigation;}
float GetAttackSpeed() const {return attack_speed;}
uint8 GetAttackDelay() const {return attack_delay;}
bool IsAnimal() const { return(bodytype == BT_Animal); }
uint16 GetPetSpellID() const {return pet_spell_id;}
void SetPetSpellID(uint16 amt) {pet_spell_id = amt;}
@@ -266,7 +265,7 @@ public:
void AddLootDrop(const Item_Struct*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false);
virtual void DoClassAttacks(Mob *target);
void CheckSignal();
inline bool IsTargetableWithHotkey() const { return no_target_hotkey; }
inline bool IsNotTargetableWithHotkey() const { return no_target_hotkey; }
int32 GetNPCHPRegen() const { return hp_regen + itembonuses.HPRegen + spellbonuses.HPRegen; }
inline const char* GetAmmoIDfile() const { return ammo_idfile; }
@@ -439,7 +438,8 @@ protected:
virtual bool AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes);
virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
AISpellsVar_Struct AISpellVar;
int16 GetFocusEffect(focusType type, uint16 spell_id);
uint32 npc_spells_effects_id;
std::vector<AISpellsEffects_Struct> AIspellsEffects;
bool HasAISpellEffects;
+8 -10
View File
@@ -17,19 +17,17 @@
*/
#include "../common/debug.h"
#include <iostream>
#include <stdlib.h>
#include "masterentity.h"
#include "zonedb.h"
#include "../common/packet_functions.h"
#include "../common/packet_dump.h"
#include "../common/misc_functions.h"
#include "../common/string_util.h"
#include "../common/features.h"
#include "string_ids.h"
#include "client.h"
#include "entity.h"
#include "mob.h"
#include "object.h"
#include "quest_parser_collection.h"
#include "zonedb.h"
#include <iostream>
const char DEFAULT_OBJECT_NAME[] = "IT63_ACTORDEF";
const char DEFAULT_OBJECT_NAME_SUFFIX[] = "_ACTORDEF";
+7 -8
View File
@@ -21,16 +21,15 @@
// Object Class:
// Represents Zone Objects (forges, ovens, brew barrels, items dropped to ground, etc)
#include "../common/types.h"
#include "../common/linked_list.h"
#include "../common/emu_opcodes.h"
#include "../common/eq_packet_structs.h"
#include "../common/item.h"
#include "client.h"
#include "mob.h"
#include "npc.h"
#include "entity.h"
#include "../common/timer.h"
#include "../common/types.h"
#include "entity.h"
class Client;
class EQApplicationPacket;
class ItemInst;
/*
item icon numbers (showeq)
+30 -32
View File
@@ -1,22 +1,22 @@
#include "../common/debug.h"
#include <string.h>
#include <math.h>
#include <list>
#include <algorithm>
#include <sstream>
#include <fstream>
#include "client.h"
#include "doors.h"
#include "pathing.h"
#include "water_map.h"
#include "../common/misc_functions.h"
#include "doors.h"
#include "client.h"
#include "zone.h"
#include <fstream>
#include <list>
#include <math.h>
#include <sstream>
#include <string.h>
#ifdef _WINDOWS
#define snprintf _snprintf
#endif
//#define PATHDEBUG
//#define PATHDEBUG
#define ABS(x) ((x)<0?-(x):(x))
extern Zone *zone;
@@ -205,15 +205,15 @@ Map::Vertex PathManager::GetPathNodeCoordinates(int NodeNumber, bool BestZ)
}
std::list<int> PathManager::FindRoute(int startID, int endID)
std::deque<int> PathManager::FindRoute(int startID, int endID)
{
_log(PATHING__DEBUG, "FindRoute from node %i to %i", startID, endID);
memset(ClosedListFlag, 0, sizeof(int) * Head.PathNodeCount);
std::list<AStarNode> OpenList, ClosedList;
std::deque<AStarNode> OpenList, ClosedList;
std::list<int>Route;
std::deque<int>Route;
AStarNode AStarEntry, CurrentNode;
@@ -251,7 +251,7 @@ std::list<int> PathManager::FindRoute(int startID, int endID)
Route.push_back(endID);
std::list<AStarNode>::iterator RouteIterator;
std::deque<AStarNode>::iterator RouteIterator;
while(CurrentNode.PathNodeID != startID)
{
@@ -300,7 +300,7 @@ std::list<int> PathManager::FindRoute(int startID, int endID)
bool AlreadyInOpenList = false;
std::list<AStarNode>::iterator OpenListIterator, InsertionPoint = OpenList.end();
std::deque<AStarNode>::iterator OpenListIterator, InsertionPoint = OpenList.end();
for(OpenListIterator = OpenList.begin(); OpenListIterator != OpenList.end(); ++OpenListIterator)
{
@@ -350,11 +350,11 @@ bool SortPathNodesByDistance(PathNodeSortStruct n1, PathNodeSortStruct n2)
return n1.Distance < n2.Distance;
}
std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
{
_log(PATHING__DEBUG, "FindRoute(%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)", Start.x, Start.y, Start.z, End.x, End.y, End.z);
std::list<int> noderoute;
std::deque<int> noderoute;
float CandidateNodeRangeXY = RuleR(Pathing, CandidateNodeRangeXY);
@@ -365,7 +365,7 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
//
int ClosestPathNodeToStart = -1;
std::list<PathNodeSortStruct> SortedByDistance;
std::deque<PathNodeSortStruct> SortedByDistance;
PathNodeSortStruct TempNode;
@@ -382,9 +382,9 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
}
}
SortedByDistance.sort(SortPathNodesByDistance);
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
for(std::list<PathNodeSortStruct>::iterator Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
{
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
@@ -420,9 +420,9 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
}
}
SortedByDistance.sort(SortPathNodesByDistance);
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
for(std::list<PathNodeSortStruct>::iterator Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
{
_log(PATHING__DEBUG, "Checking Reachability of Node %i from End Position.", PathNodes[(*Iterator).id].id);
_log(PATHING__DEBUG, " (%8.3f, %8.3f, %8.3f) to (%8.3f, %8.3f, %8.3f)",
@@ -456,7 +456,7 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
{
int CulledNodes = 0;
std::list<int>::iterator First, Second;
std::deque<int>::iterator First, Second;
while((noderoute.size() >= 2) && (CulledNodes < NodesToAttemptToCull))
{
@@ -487,7 +487,7 @@ std::list<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
{
int CulledNodes = 0;
std::list<int>::iterator First, Second;
std::deque<int>::iterator First, Second;
while((noderoute.size() >= 2) && (CulledNodes < NodesToAttemptToCull))
{
@@ -611,7 +611,7 @@ void PathManager::MeshTest()
if(j == i)
continue;
std::list<int> Route = FindRoute(PathNodes[i].id, PathNodes[j].id);
std::deque<int> Route = FindRoute(PathNodes[i].id, PathNodes[j].id);
if(Route.size() == 0)
{
@@ -638,7 +638,7 @@ void PathManager::SimpleMeshTest()
for(uint32 j = 1; j < Head.PathNodeCount; ++j)
{
std::list<int> Route = FindRoute(PathNodes[0].id, PathNodes[j].id);
std::deque<int> Route = FindRoute(PathNodes[0].id, PathNodes[j].id);
if(Route.size() == 0)
{
@@ -1103,7 +1103,7 @@ int PathManager::FindNearestPathNode(Map::Vertex Position)
int ClosestPathNodeToStart = -1;
std::list<PathNodeSortStruct> SortedByDistance;
std::deque<PathNodeSortStruct> SortedByDistance;
PathNodeSortStruct TempNode;
@@ -1120,9 +1120,9 @@ int PathManager::FindNearestPathNode(Map::Vertex Position)
}
}
SortedByDistance.sort(SortPathNodesByDistance);
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
for(std::list<PathNodeSortStruct>::iterator Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
{
_log(PATHING__DEBUG, "Checking Reachability of Node %i from Start Position.", PathNodes[(*Iterator).id].id);
@@ -1264,9 +1264,7 @@ void Mob::PrintRoute()
printf("Route is : ");
std::list<int>::iterator Iterator;
for(Iterator = Route.begin(); Iterator !=Route.end(); ++Iterator)
for(auto Iterator = Route.begin(); Iterator !=Route.end(); ++Iterator)
{
printf("%i, ", (*Iterator));
}
+6 -7
View File
@@ -1,13 +1,12 @@
#ifndef PATHING_H
#define PATHING_H
#include <algorithm>
#include "map.h"
#include "../common/timer.h"
#include <list>
#include <vector>
#include <algorithm>
#include <deque>
class Client;
class Mob;
#define PATHNODENEIGHBOURS 50
@@ -61,8 +60,8 @@ public:
static PathManager *LoadPathFile(const char *ZoneName);
bool loadPaths(FILE *fp);
void PrintPathing();
std::list<int> FindRoute(Map::Vertex Start, Map::Vertex End);
std::list<int> FindRoute(int startID, int endID);
std::deque<int> FindRoute(Map::Vertex Start, Map::Vertex End);
std::deque<int> FindRoute(int startID, int endID);
Map::Vertex GetPathNodeCoordinates(int NodeNumber, bool BestZ = true);
bool CheckLosFN(Map::Vertex a, Map::Vertex b);
+1 -1
View File
@@ -3134,7 +3134,7 @@ XS(XS_Client_SummonItem)
slot_id = (uint16)SvUV(ST(9));
}
THIS->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, attune, slot_id);
THIS->SummonItem(item_id, charges, aug1, aug2, aug3, aug4, aug5, 0, attune, slot_id);
}
XSRETURN_EMPTY;
}
+7 -3
View File
@@ -7460,12 +7460,13 @@ XS(XS_Mob_WearChange)
{
dXSARGS;
if (items < 3 || items > 4)
Perl_croak(aTHX_ "Usage: Mob::WearChange(THIS, material_slot, texture, color)");
Perl_croak(aTHX_ "Usage: Mob::WearChange(THIS, material_slot, texture, [color, hero_forge_model])");
{
Mob * THIS;
uint8 material_slot = (uint8)SvIV(ST(1));
uint16 texture = (uint16)SvUV(ST(2));
uint32 color = 0;
uint32 hero_forge_model = 0;
if (sv_derived_from(ST(0), "Mob")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
@@ -7479,8 +7480,11 @@ XS(XS_Mob_WearChange)
if (items > 3) {
color = (uint32)SvUV(ST(3));
}
if (items > 4) {
hero_forge_model = (uint32)SvUV(ST(3));
}
THIS->WearChange(material_slot, texture, color);
THIS->WearChange(material_slot, texture, color, hero_forge_model);
}
XSRETURN_EMPTY;
}
@@ -8611,7 +8615,7 @@ XS(boot_Mob)
newXSproto(strcpy(buf, "TarGlobal"), XS_Mob_TarGlobal, file, "$$$$$$$");
newXSproto(strcpy(buf, "DelGlobal"), XS_Mob_DelGlobal, file, "$$");
newXSproto(strcpy(buf, "SetSlotTint"), XS_Mob_SetSlotTint, file, "$$$$$");
newXSproto(strcpy(buf, "WearChange"), XS_Mob_WearChange, file, "$$$;$");
newXSproto(strcpy(buf, "WearChange"), XS_Mob_WearChange, file, "$$$;$$");
newXSproto(strcpy(buf, "DoKnockback"), XS_Mob_DoKnockback, file, "$$$$");
newXSproto(strcpy(buf, "RemoveNimbusEffect"), XS_Mob_RemoveNimbusEffect, file, "$$");
newXSproto(strcpy(buf, "IsRunning"), XS_Mob_IsRunning, file, "$");
+132
View File
@@ -2120,6 +2120,32 @@ XS(XS_NPC_GetAttackSpeed)
XSRETURN(1);
}
XS(XS_NPC_GetAttackDelay); /* prototype to pass -Wmissing-prototypes */
XS(XS_NPC_GetAttackDelay)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: NPC::GetAttackDelay(THIS)");
{
NPC * THIS;
float RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetAttackDelay();
XSprePUSH; PUSHn((double)RETVAL);
}
XSRETURN(1);
}
XS(XS_NPC_GetAccuracyRating); /* prototype to pass -Wmissing-prototypes */
XS(XS_NPC_GetAccuracyRating)
{
@@ -2146,6 +2172,32 @@ XS(XS_NPC_GetAccuracyRating)
XSRETURN(1);
}
XS(XS_NPC_GetAvoidanceRating); /* prototype to pass -Wmissing-prototypes */
XS(XS_NPC_GetAvoidanceRating)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: NPC::GetAvoidanceyRating(THIS)");
{
NPC * THIS;
int32 RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetAvoidanceRating();
XSprePUSH; PUSHu((UV)RETVAL);
}
XSRETURN(1);
}
XS(XS_NPC_GetSpawnKillCount); /* prototype to pass -Wmissing-prototypes */
XS(XS_NPC_GetSpawnKillCount)
{
@@ -2246,6 +2298,81 @@ XS(XS_NPC_GetMerchantProbability) {
XSRETURN(1);
}
XS(XS_NPC_AddMeleeProc);
XS(XS_NPC_AddMeleeProc) {
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: NPC::AddMeleeProc(THIS,spellid,chance)");
{
NPC * THIS;
int spell_id = (int)SvIV(ST(1));
int chance = (int)SvIV(ST(2));
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == NULL)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
THIS->AddProcToWeapon(spell_id, true, chance);
}
XSRETURN_EMPTY;
}
XS(XS_NPC_AddRangedProc);
XS(XS_NPC_AddRangedProc) {
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: NPC::AddRangedProc(THIS,spellid,chance)");
{
NPC * THIS;
int spell_id = (int)SvIV(ST(1));
int chance = (int)SvIV(ST(2));
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == NULL)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
THIS->AddDefensiveProc(spell_id,chance);
}
XSRETURN_EMPTY;
}
XS(XS_NPC_AddDefensiveProc);
XS(XS_NPC_AddDefensiveProc) {
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: NPC::AddDefensiveProc(THIS,spellid,chance)");
{
NPC * THIS;
int spell_id = (int)SvIV(ST(1));
int chance = (int)SvIV(ST(2));
dXSTARG;
if (sv_derived_from(ST(0), "NPC")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(NPC *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type NPC");
if(THIS == NULL)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
THIS->AddProcToWeapon(spell_id, true, chance);
}
XSRETURN_EMPTY;
}
#ifdef __cplusplus
extern "C"
#endif
@@ -2343,11 +2470,16 @@ XS(boot_NPC)
newXSproto(strcpy(buf, "GetSpellFocusHeal"), XS_NPC_GetSpellFocusHeal, file, "$");
newXSproto(strcpy(buf, "GetSlowMitigation"), XS_NPC_GetSlowMitigation, file, "$");
newXSproto(strcpy(buf, "GetAttackSpeed"), XS_NPC_GetAttackSpeed, file, "$");
newXSproto(strcpy(buf, "GetAttackDelay"), XS_NPC_GetAttackDelay, file, "$");
newXSproto(strcpy(buf, "GetAccuracyRating"), XS_NPC_GetAccuracyRating, file, "$");
newXSproto(strcpy(buf, "GetAvoidanceRating"), XS_NPC_GetAvoidanceRating, file, "$");
newXSproto(strcpy(buf, "GetSpawnKillCount"), XS_NPC_GetSpawnKillCount, file, "$");
newXSproto(strcpy(buf, "GetScore"), XS_NPC_GetScore, file, "$");
newXSproto(strcpy(buf, "SetMerchantProbability"), XS_NPC_SetMerchantProbability, file, "$$");
newXSproto(strcpy(buf, "GetMerchantProbability"), XS_NPC_GetMerchantProbability, file, "$");
newXSproto(strcpy(buf, "AddMeleeProc"), XS_NPC_AddMeleeProc, file, "$$$");
newXSproto(strcpy(buf, "AddRangedProc"), XS_NPC_AddRangedProc, file, "$$$");
newXSproto(strcpy(buf, "AddDefensiveProc"), XS_NPC_AddDefensiveProc, file, "$$$");
XSRETURN_YES;
}
+1 -1
View File
@@ -160,7 +160,7 @@ XS(XS_QuestItem_IsAttuned)
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->IsInstNoDrop();
RETVAL = THIS->IsAttuned();
ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0));
}
+1
View File
@@ -33,6 +33,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
#include "../common/eq_packet_structs.h"
#include "../common/servertalk.h"
#include "../common/string_util.h"
#include "entity.h"
#include "petitions.h"
#include "worldserver.h"
+1
View File
@@ -22,6 +22,7 @@
#include "../common/misc_functions.h"
#include "../common/mutex.h"
#include "../common/types.h"
#include "client.h"
#include "zonedb.h"
+1 -3
View File
@@ -17,7 +17,6 @@
*/
#include "../common/debug.h"
#include "../common/misc_functions.h"
#include "../common/spdat.h"
#include "../common/string_util.h"
#include "../common/types.h"
@@ -27,7 +26,6 @@
#include "mob.h"
#include "pets.h"
#include "worldserver.h"
#include "zonedb.h"
#ifndef WIN32
@@ -230,7 +228,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
int16 act_power = 0; // The actual pet power we'll use.
if (petpower == -1) {
if (this->IsClient()) {
act_power = CastToClient()->GetFocusEffect(focusPetPower, spell_id);
act_power = CastToClient()->GetFocusEffect(focusPetPower, spell_id);//Client only
act_power = CastToClient()->mod_pet_power(act_power, spell_id);
}
}
+24 -21
View File
@@ -1,28 +1,31 @@
#ifndef PETS_H
#define PETS_H
#define PET_BACKOFF 1
#define PET_GETLOST 2
#define PET_HEALTHREPORT 4
#define PET_GUARDHERE 5
#define PET_GUARDME 6
#define PET_ATTACK 7
#define PET_FOLLOWME 8
#define PET_SITDOWN 9
#define PET_STANDUP 10
#define PET_TAUNT 11
#define PET_HOLD 12
#define PET_NOTAUNT 14
#define PET_LEADER 16
#define PET_SLUMBER 17
#define PET_NOCAST 18
#define PET_FOCUS 19
#define PET_FOCUS_ON 25
#define PET_FOCUS_OFF 26
#define PET_HOLD_ON 27
#define PET_HOLD_OFF 28
#define PET_BACKOFF 1
#define PET_GETLOST 2
#define PET_HEALTHREPORT 4
#define PET_GUARDHERE 5
#define PET_GUARDME 6
#define PET_ATTACK 7
#define PET_FOLLOWME 8
#define PET_SITDOWN 9
#define PET_STANDUP 10
#define PET_TAUNT 11
#define PET_HOLD 12
#define PET_NOTAUNT 14
#define PET_LEADER 16
#define PET_SLUMBER 17
#define PET_NOCAST 18
#define PET_FOCUS 19
#define PET_FOCUS_ON 25
#define PET_FOCUS_OFF 26
#define PET_HOLD_ON 27
#define PET_HOLD_OFF 28
class Pet : public NPC {
class Mob;
struct NPCType;
class Pet : public NPC {
public:
Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power);
+2 -3
View File
@@ -1,9 +1,8 @@
#include "../common/debug.h"
#include "../common/string_util.h"
#include "qglobals.h"
#include "masterentity.h"
#include "client.h"
#include "zone.h"
#include "zonedb.h"
void QGlobalCache::AddGlobal(uint32 id, QGlobal global)
{
-3
View File
@@ -2,9 +2,6 @@
#define __QGLOBALS__H
#include <list>
#include <string>
#include <stdlib.h>
#include "../common/timer.h"
class NPC;
class Client;
-1
View File
@@ -23,7 +23,6 @@ Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
#include "worldserver.h"
#include "net.h"
#include <iostream>
extern WorldServer worldserver;
extern QueryServ* QServ;
+1 -2
View File
@@ -19,14 +19,13 @@
#include "../common/debug.h"
#include "../common/misc_functions.h"
#include "../common/features.h"
#include "quest_parser_collection.h"
#include "quest_interface.h"
#include "zone.h"
#include "questmgr.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
extern Zone* zone;
extern void MapOpcodes();
+17 -4
View File
@@ -20,19 +20,32 @@
#define _EQE_QUESTPARSERCOLLECTION_H
#include "../common/types.h"
#include "../common/item.h"
#include "masterentity.h"
#include "beacon.h"
#include "client.h"
#include "corpse.h"
#include "doors.h"
#include "groups.h"
#include "mob.h"
#include "object.h"
#include "raids.h"
#include "trap.h"
#include "quest_interface.h"
#include <string.h>
#include <string>
#include <list>
#include <map>
#define QuestFailedToLoad 0xFFFFFFFF
#define QuestUnloaded 0x00
class Client;
class ItemInst;
class Mob;
class NPC;
class QuestInterface;
namespace EQEmu { class Any; }
class QuestParserCollection {
public:
QuestParserCollection();
+11 -8
View File
@@ -22,18 +22,19 @@
#include "../common/skills.h"
#include "../common/spdat.h"
#include "../common/string_util.h"
#include "entity.h"
#include "event_codes.h"
#include "guild_mgr.h"
#include "net.h"
#include "qglobals.h"
#include "queryserv.h"
#include "questmgr.h"
#include "quest_parser_collection.h"
#include "questmgr.h"
#include "spawn2.h"
#include "worldserver.h"
#include "zone.h"
#include "zonedb.h"
#include <iostream>
#include <limits.h>
#include <list>
@@ -2653,14 +2654,16 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
char linktext[250];
if (initiator) {
if (initiator->GetClientVersion() >= EQClientRoF)
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"0000000000000000000000000000000000000000000000000",LinkName,0x12);
if (initiator->GetClientVersion() >= EQClientRoF2)
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000000000", LinkName, 0x12);
else if (initiator->GetClientVersion() >= EQClientRoF)
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "0000000000000000000000000000000000000000000000000", LinkName, 0x12);
else if (initiator->GetClientVersion() >= EQClientSoF)
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"00000000000000000000000000000000000000000000",LinkName,0x12);
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000", LinkName, 0x12);
else
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"000000000000000000000000000000000000000",LinkName,0x12);
} else { // If no initiator, create an RoF saylink, since older clients handle RoF ones better than RoF handles older ones.
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"0000000000000000000000000000000000000000000000000",LinkName,0x12);
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "000000000000000000000000000000000000000", LinkName, 0x12);
} else { // If no initiator, create an RoF2 saylink, since older clients handle RoF2 ones better than RoF2 handles older ones.
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000000000", LinkName, 0x12);
}
strcpy(Phrase,linktext);
-1
View File
@@ -21,7 +21,6 @@
#include "../common/timer.h"
#include "tasks.h"
#include <string>
#include <list>
#include <stack>
+9 -5
View File
@@ -15,13 +15,17 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "masterentity.h"
#include "npc_ai.h"
#include "../common/packet_functions.h"
#include "../common/packet_dump.h"
#include "../common/string_util.h"
#include "client.h"
#include "entity.h"
#include "groups.h"
#include "mob.h"
#include "raids.h"
#include "worldserver.h"
extern EntityList entity_list;
extern WorldServer worldserver;
+1 -4
View File
@@ -19,14 +19,11 @@
#define RAIDS_H
#include "../common/types.h"
#include "../common/linked_list.h"
#include "groups.h"
#include <vector>
#include <string>
#include <queue>
class Client;
class EQApplicationPacket;
class Mob;
enum { //raid packet types:
raidAdd = 0,
+6 -5
View File
@@ -15,16 +15,17 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "../common/string_util.h"
#include <stdlib.h>
#include "spawn2.h"
#include "client.h"
#include "entity.h"
#include "masterentity.h"
#include "zone.h"
#include "spawn2.h"
#include "spawngroup.h"
#include "zonedb.h"
#include "worldserver.h"
#include "zone.h"
#include "zonedb.h"
extern EntityList entity_list;
extern Zone* zone;
-2
View File
@@ -21,8 +21,6 @@
#include "../common/timer.h"
#include "npc.h"
#include <string>
#define SC_AlwaysEnabled 0
class SpawnCondition;
+6 -8
View File
@@ -15,17 +15,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "spawngroup.h"
#include "entity.h"
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include "../common/types.h"
#include "zonedb.h"
#include "../common/misc_functions.h"
#include "../common/string_util.h"
#include "../common/types.h"
#include "entity.h"
#include "spawngroup.h"
#include "zone.h"
#include "zonedb.h"
extern EntityList entity_list;
extern Zone* zone;
-1
View File
@@ -18,7 +18,6 @@
#ifndef SPAWNGROUP_H
#define SPAWNGROUP_H
#include "../common/linked_list.h"
#include "../common/types.h"
#include <map>
+118 -90
View File
@@ -16,15 +16,14 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "../common/misc_functions.h"
#include "../common/rulesys.h"
#include "../common/string_util.h"
#include "masterentity.h"
#include "client.h"
#include "entity.h"
#include "mob.h"
#include "string_ids.h"
#include <stdio.h>
#include <string.h>
@@ -104,6 +103,9 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
if (!who)
return;
if(who->GetInvul() || who->GetSpecialAbility(IMMUNE_MELEE) || who->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE))
return; //-5?
int32 hate = max_damage;
if(hate_override > -1)
hate = hate_override;
@@ -979,7 +981,9 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
if (HeadShot)
entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, FATAL_BOW_SHOT, GetName());
other->AddToHateList(this, hate, 0, false);
if (IsClient() && !CastToClient()->GetFeigned())
other->AddToHateList(this, hate, 0, false);
other->Damage(this, TotalDmg, SPELL_UNKNOWN, SkillArchery);
//Skill Proc Success
@@ -1058,8 +1062,8 @@ bool Mob::TryProjectileAttack(Mob* other, const Item_Struct *item, SkillUseTypes
if(item)
SendItemAnimation(other, item, skillInUse, speed);
else if (IsNPC())
ProjectileAnimation(other, 0,false,speed,0,0,0,CastToNPC()->GetAmmoIDfile(),skillInUse);
//else if (IsNPC())
//ProjectileAnimation(other, 0,false,speed,0,0,0,CastToNPC()->GetAmmoIDfile(),skillInUse);
return true;
}
@@ -1096,12 +1100,19 @@ void Mob::ProjectileAttack()
if (ProjectileAtk[i].hit_increment <= ProjectileAtk[i].increment){
if (target){
if (ProjectileAtk[i].skill == SkillArchery)
DoArcheryAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0,ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_id, nullptr, ProjectileAtk[i].ammo_slot);
else if (ProjectileAtk[i].skill == SkillThrowing)
DoThrowingAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0, ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_slot);
else if (ProjectileAtk[i].skill == SkillConjuration && IsValidSpell(ProjectileAtk[i].wpn_dmg))
SpellOnTarget(ProjectileAtk[i].wpn_dmg, target, false, true, spells[ProjectileAtk[i].wpn_dmg].ResistDiff, true);
if (IsNPC())
CastToNPC()->DoRangedAttackDmg(target, false, ProjectileAtk[i].wpn_dmg,0, static_cast<SkillUseTypes>(ProjectileAtk[i].skill));
else
{
if (ProjectileAtk[i].skill == SkillArchery)
DoArcheryAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0,ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_id, nullptr, ProjectileAtk[i].ammo_slot);
else if (ProjectileAtk[i].skill == SkillThrowing)
DoThrowingAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0, ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_slot);
else if (ProjectileAtk[i].skill == SkillConjuration && IsValidSpell(ProjectileAtk[i].wpn_dmg))
SpellOnTarget(ProjectileAtk[i].wpn_dmg, target, false, true, spells[ProjectileAtk[i].wpn_dmg].ResistDiff, true);
}
}
ProjectileAtk[i].increment = 0;
@@ -1186,14 +1197,8 @@ void NPC::RangedAttack(Mob* other)
attacks = attacks > 0 ? attacks : 1;
for(int i = 0; i < attacks; ++i) {
//if we have SPECATK_RANGED_ATK set then we range attack without weapon or ammo
const Item_Struct* weapon = nullptr;
const Item_Struct* ammo = nullptr;
if(!GetSpecialAbility(SPECATK_RANGED_ATK))
{
//find our bow and ammo return if we can't find them...
return;
}
int sa_min_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 4); //Min Range of NPC attack
int sa_max_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 1); //Max Range of NPC attack
@@ -1207,16 +1212,11 @@ void NPC::RangedAttack(Mob* other)
if (sa_min_range)
min_range = static_cast<float>(sa_min_range);
mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", max_range);
max_range *= max_range;
if(DistNoRootNoZ(*other) > max_range) {
mlog(COMBAT__RANGED, "Ranged attack out of range...%.2f vs %.2f", DistNoRootNoZ(*other), max_range);
//target is out of range, client does a message
if(DistNoRoot(*other) > max_range)
return;
}
else if(DistNoRootNoZ(*other) < (min_range * min_range))
else if(DistNoRoot(*other) < (min_range * min_range))
return;
if(!other || !IsAttackAllowed(other) ||
IsCasting() ||
@@ -1228,74 +1228,100 @@ void NPC::RangedAttack(Mob* other)
return;
}
SkillUseTypes skillinuse = SkillArchery;
skillinuse = static_cast<SkillUseTypes>(GetRangedSkill());
if(!ammo && !GetAmmoIDfile())
ammo = database.GetItem(8005);
if(ammo)
SendItemAnimation(other, ammo, SkillArchery);
else
ProjectileAnimation(other, 0,false,0,0,0,0,GetAmmoIDfile(),skillinuse);
FaceTarget(other);
if (!other->CheckHitChance(this, skillinuse, MainRange, GetSpecialAbilityParam(SPECATK_RANGED_ATK, 2)))
{
mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName());
other->Damage(this, 0, SPELL_UNKNOWN, skillinuse);
}
else
{
int16 WDmg = GetWeaponDamage(other, weapon);
int16 ADmg = GetWeaponDamage(other, ammo);
int32 TotalDmg = 0;
if(WDmg > 0 || ADmg > 0)
{
mlog(COMBAT__RANGED, "Ranged attack hit %s.", other->GetName());
int32 MaxDmg = max_dmg * RuleR(Combat, ArcheryNPCMultiplier); // should add a field to npc_types
int32 MinDmg = min_dmg * RuleR(Combat, ArcheryNPCMultiplier);
if(RuleB(Combat, UseIntervalAC))
TotalDmg = MaxDmg;
else
TotalDmg = zone->random.Int(MinDmg, MaxDmg);
TotalDmg += TotalDmg * GetSpecialAbilityParam(SPECATK_RANGED_ATK, 3) / 100; //Damage modifier
other->AvoidDamage(this, TotalDmg, false);
other->MeleeMitigation(this, TotalDmg, MinDmg);
if (TotalDmg > 0)
CommonOutgoingHitSuccess(other, TotalDmg, skillinuse);
}
else
TotalDmg = -5;
if (TotalDmg > 0)
other->AddToHateList(this, TotalDmg, 0, false);
else
other->AddToHateList(this, 0, 0, false);
other->Damage(this, TotalDmg, SPELL_UNKNOWN, skillinuse);
if (TotalDmg > 0 && HasSkillProcSuccess() && GetTarget() && !other->HasDied())
TrySkillProc(other, skillinuse, 0, true, MainRange);
}
//try proc on hits and misses
if(other && !other->HasDied())
TrySpellProc(nullptr, (const Item_Struct*)nullptr, other, MainRange);
if (HasSkillProcs() && other && !other->HasDied())
TrySkillProc(other, skillinuse, 0, false, MainRange);
DoRangedAttackDmg(other);
CommonBreakInvisible();
}
}
void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 chance_mod, SkillUseTypes skill, float speed, const char *IDFile) {
if ((other == nullptr ||
(other->HasDied())) ||
HasDied() ||
(!IsAttackAllowed(other)) ||
(other->GetInvul() ||
other->GetSpecialAbility(IMMUNE_MELEE)))
{
return;
}
SkillUseTypes skillInUse = static_cast<SkillUseTypes>(GetRangedSkill());
if (skill != skillInUse)
skillInUse = skill;
if (Launch)
{
const char *ammo = "IT10";
if (IDFile != nullptr)
ammo = IDFile;
else if (GetAmmoIDfile())
ammo = GetAmmoIDfile();
ProjectileAnimation(other, 0,false,speed,0,0,0,ammo,skillInUse);
if (RuleB(Combat, ProjectileDmgOnImpact))
{
TryProjectileAttack(other, nullptr, skillInUse, damage_mod, nullptr, nullptr, 0, speed);
return;
}
}
if (!chance_mod)
chance_mod = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 2);
if (!other->CheckHitChance(this, skillInUse, MainRange, chance_mod))
{
other->Damage(this, 0, SPELL_UNKNOWN, skillInUse);
}
else
{
int32 TotalDmg = 0;
int32 MaxDmg = max_dmg * RuleR(Combat, ArcheryNPCMultiplier); // should add a field to npc_types
int32 MinDmg = min_dmg * RuleR(Combat, ArcheryNPCMultiplier);
if(RuleB(Combat, UseIntervalAC))
TotalDmg = MaxDmg;
else
TotalDmg = zone->random.Int(MinDmg, MaxDmg);
if (!damage_mod)
damage_mod = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 3);//Damage modifier
TotalDmg += TotalDmg * damage_mod / 100;
other->AvoidDamage(this, TotalDmg, false);
other->MeleeMitigation(this, TotalDmg, MinDmg);
if (TotalDmg > 0)
CommonOutgoingHitSuccess(other, TotalDmg, skillInUse);
else
TotalDmg = -5;
if (TotalDmg > 0)
other->AddToHateList(this, TotalDmg, 0, false);
else
other->AddToHateList(this, 0, 0, false);
other->Damage(this, TotalDmg, SPELL_UNKNOWN, skillInUse);
if (TotalDmg > 0 && HasSkillProcSuccess() && !other->HasDied())
TrySkillProc(other, skillInUse, 0, true, MainRange);
}
//try proc on hits and misses
if(other && !other->HasDied())
TrySpellProc(nullptr, (const Item_Struct*)nullptr, other, MainRange);
if (HasSkillProcs() && other && !other->HasDied())
TrySkillProc(other, skillInUse, 0, false, MainRange);
}
uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg) {
uint16 MaxDmg = (((2 * wDmg) * GetDamageTable(SkillThrowing)) / 100);
@@ -1513,7 +1539,9 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
else
TotalDmg = -5;
other->AddToHateList(this, 2*WDmg, 0, false);
if (IsClient() && !CastToClient()->GetFeigned())
other->AddToHateList(this, 2*WDmg, 0, false);
other->Damage(this, TotalDmg, SPELL_UNKNOWN, SkillThrowing);
if (TotalDmg > 0 && HasSkillProcSuccess() && other && !other->HasDied()){
+138 -41
View File
@@ -23,9 +23,11 @@
#include "../common/rulesys.h"
#include "../common/skills.h"
#include "../common/spdat.h"
#include "quest_parser_collection.h"
#include "string_ids.h"
#include "worldserver.h"
#include <math.h>
#ifndef WIN32
@@ -179,11 +181,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
int numhit = spells[spell_id].numhits;
if (caster && caster->IsClient()){
numhit += numhit*caster->CastToClient()->GetFocusEffect(focusFcLimitUse, spell_id)/100;
numhit += caster->CastToClient()->GetFocusEffect(focusIncreaseNumHits, spell_id);
}
numhit += numhit*caster->GetFocusEffect(focusFcLimitUse, spell_id)/100;
numhit += caster->GetFocusEffect(focusIncreaseNumHits, spell_id);
buffs[buffslot].numhits = numhit;
}
@@ -714,7 +713,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
mlog(COMBAT__HITS, "Stunned. We had %d percent resist chance.", stun_resist);
if (caster->IsClient())
effect_value += effect_value*caster->CastToClient()->GetFocusEffect(focusFcStunTimeMod, spell_id)/100;
effect_value += effect_value*caster->GetFocusEffect(focusFcStunTimeMod, spell_id)/100;
Stun(effect_value);
} else {
@@ -2265,8 +2264,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
int16 focus = 0;
int ReuseTime = spells[spell_id].recast_time + spells[spell_id].recovery_time;
if(caster->IsClient())
focus = caster->CastToClient()->GetFocusEffect(focusFcBaseEffects, spell_id);
focus = caster->GetFocusEffect(focusFcBaseEffects, spell_id);
switch(spells[spell_id].skill)
{
@@ -3469,30 +3467,18 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
{
effect_value = CalcSpellEffectValue(spell_id, i, caster_level, caster, ticsremaining);
//Handle client cast DOTs here.
if (caster && caster->IsClient() && IsDetrimentalSpell(spell_id) && effect_value < 0) {
effect_value = caster->CastToClient()->GetActDoTDamage(spell_id, effect_value, this);
if (!caster->CastToClient()->GetFeigned())
AddToHateList(caster, -effect_value);
}
if(effect_value < 0)
{
if(caster)
{
if(!caster->IsClient()){
if (!IsClient()) //Allow NPC's to generate hate if casted on other NPC's.
AddToHateList(caster, -effect_value);
}
if(caster->IsNPC())
effect_value = caster->CastToNPC()->GetActSpellDamage(spell_id, effect_value, this);
caster->ResourceTap(-effect_value, spell_id);
if (caster && effect_value < 0 && IsDetrimentalSpell(spell_id)){
if (caster->IsClient()){
if (!caster->CastToClient()->GetFeigned())
AddToHateList(caster, -effect_value);
}
else if (!IsClient()) //Allow NPC's to generate hate if casted on other NPC's.
AddToHateList(caster, -effect_value);
effect_value = caster->GetActDoTDamage(spell_id, effect_value, this);
caster->ResourceTap(-effect_value, spell_id);
effect_value = -effect_value;
Damage(caster, effect_value, spell_id, spell.skill, false, i, true);
} else if(effect_value > 0) {
@@ -5318,11 +5304,8 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
//Improved Healing, Damage & Mana Reduction are handled differently in that some are random percentages
//In these cases we need to find the most powerful effect, so that each piece of gear wont get its own chance
if((type == focusManaCost || type == focusImprovedHeal || type == focusImprovedDamage)
&& RuleB(Spells, LiveLikeFocusEffects))
{
if(RuleB(Spells, LiveLikeFocusEffects) && (type == focusManaCost || type == focusImprovedHeal || type == focusImprovedDamage))
rand_effectiveness = true;
}
//Check if item focus effect exists for the client.
if (itembonuses.FocusEffects[type]){
@@ -5540,6 +5523,122 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
return realTotal + realTotal2 + realTotal3;
}
int16 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
int16 realTotal = 0;
int16 realTotal2 = 0;
bool rand_effectiveness = false;
//Improved Healing, Damage & Mana Reduction are handled differently in that some are random percentages
//In these cases we need to find the most powerful effect, so that each piece of gear wont get its own chance
if(RuleB(Spells, LiveLikeFocusEffects) && (type == focusManaCost || type == focusImprovedHeal || type == focusImprovedDamage))
rand_effectiveness = true;
if (RuleB(Spells, NPC_UseFocusFromItems) && itembonuses.FocusEffects[type]){
const Item_Struct* TempItem = 0;
const Item_Struct* UsedItem = 0;
uint16 UsedFocusID = 0;
int16 Total = 0;
int16 focus_max = 0;
int16 focus_max_real = 0;
//item focus
for(int i = 0; i < EmuConstants::EQUIPMENT_SIZE; i++){
const Item_Struct *cur = database.GetItem(equipment[i]);
if(!cur)
continue;
TempItem = cur;
if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) {
if(rand_effectiveness) {
focus_max = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id, true);
if (focus_max > 0 && focus_max_real >= 0 && focus_max > focus_max_real) {
focus_max_real = focus_max;
UsedItem = TempItem;
UsedFocusID = TempItem->Focus.Effect;
} else if (focus_max < 0 && focus_max < focus_max_real) {
focus_max_real = focus_max;
UsedItem = TempItem;
UsedFocusID = TempItem->Focus.Effect;
}
}
else {
Total = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id);
if (Total > 0 && realTotal >= 0 && Total > realTotal) {
realTotal = Total;
UsedItem = TempItem;
UsedFocusID = TempItem->Focus.Effect;
} else if (Total < 0 && Total < realTotal) {
realTotal = Total;
UsedItem = TempItem;
UsedFocusID = TempItem->Focus.Effect;
}
}
}
}
if(UsedItem && rand_effectiveness && focus_max_real != 0)
realTotal = CalcFocusEffect(type, UsedFocusID, spell_id);
}
if (RuleB(Spells, NPC_UseFocusFromSpells) && spellbonuses.FocusEffects[type]){
//Spell Focus
int16 Total2 = 0;
int16 focus_max2 = 0;
int16 focus_max_real2 = 0;
int buff_tracker = -1;
int buff_slot = 0;
uint16 focusspellid = 0;
uint16 focusspell_tracker = 0;
int buff_max = GetMaxTotalSlots();
for (buff_slot = 0; buff_slot < buff_max; buff_slot++) {
focusspellid = buffs[buff_slot].spellid;
if (focusspellid == 0 || focusspellid >= SPDAT_RECORDS)
continue;
if(rand_effectiveness) {
focus_max2 = CalcFocusEffect(type, focusspellid, spell_id, true);
if (focus_max2 > 0 && focus_max_real2 >= 0 && focus_max2 > focus_max_real2) {
focus_max_real2 = focus_max2;
buff_tracker = buff_slot;
focusspell_tracker = focusspellid;
} else if (focus_max2 < 0 && focus_max2 < focus_max_real2) {
focus_max_real2 = focus_max2;
buff_tracker = buff_slot;
focusspell_tracker = focusspellid;
}
}
else {
Total2 = CalcFocusEffect(type, focusspellid, spell_id);
if (Total2 > 0 && realTotal2 >= 0 && Total2 > realTotal2) {
realTotal2 = Total2;
buff_tracker = buff_slot;
focusspell_tracker = focusspellid;
} else if (Total2 < 0 && Total2 < realTotal2) {
realTotal2 = Total2;
buff_tracker = buff_slot;
focusspell_tracker = focusspellid;
}
}
}
if(focusspell_tracker && rand_effectiveness && focus_max_real2 != 0)
realTotal2 = CalcFocusEffect(type, focusspell_tracker, spell_id);
// For effects like gift of mana that only fire once, save the spellid into an array that consists of all available buff slots.
if(buff_tracker >= 0 && buffs[buff_tracker].numhits > 0) {
m_spellHitsLeft[buff_tracker] = focusspell_tracker;
}
}
return realTotal + realTotal2;
}
void Mob::CheckNumHitsRemaining(uint8 type, int32 buff_slot, uint16 spell_id)
{
/*
@@ -5946,15 +6045,13 @@ int32 Mob::ApplySpellEffectiveness(Mob* caster, int16 spell_id, int32 value, boo
if (!caster)
return value;
if (caster->IsClient()){
int16 focus = caster->CastToClient()->GetFocusEffect(focusFcBaseEffects, spell_id);
int16 focus = GetFocusEffect(focusFcBaseEffects, spell_id);
if (IsBard)
value += focus;
if (IsBard)
value += focus;
else
value += value*focus/100;
else
value += value*focus/100;
}
return value;
}
+17 -20
View File
@@ -74,9 +74,11 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
#include "../common/skills.h"
#include "../common/spdat.h"
#include "../common/string_util.h"
#include "quest_parser_collection.h"
#include "string_ids.h"
#include "worldserver.h"
#include <assert.h>
#include <math.h>
@@ -89,6 +91,10 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
#include "../common/packet_dump_file.h"
#endif
#ifdef BOTS
#include "bot.h"
#endif
extern Zone* zone;
@@ -176,7 +182,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
BuffFadeByEffect(SE_Sanctuary);
if(IsClient()){
int chance = CastToClient()->GetFocusEffect(focusFcMute, spell_id);
int chance = CastToClient()->GetFocusEffect(focusFcMute, spell_id);//Client only
if (zone->random.Roll(chance)) {
Message_StringID(13, SILENCED_STRING);
@@ -1043,7 +1049,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot,
// Check for consumables and Reagent focus items
// first check for component reduction
if(IsClient()) {
int reg_focus = CastToClient()->GetFocusEffect(focusReagentCost,spell_id);
int reg_focus = CastToClient()->GetFocusEffect(focusReagentCost,spell_id);//Client only
if(zone->random.Roll(reg_focus)) {
mlog(SPELLS__CASTING, "Spell %d: Reagent focus item prevented reagent consumption (%d chance)", spell_id, reg_focus);
} else {
@@ -2237,7 +2243,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
{
recast -= GetAA(aaTouchoftheWicked) * 420;
}
int reduction = CastToClient()->GetFocusEffect(focusReduceRecastTime, spell_id);
int reduction = CastToClient()->GetFocusEffect(focusReduceRecastTime, spell_id);//Client only
if(reduction)
recast -= reduction;
@@ -4189,14 +4195,8 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
//Get resist modifier and adjust it based on focus 2 resist about eq to 1% resist chance
int resist_modifier = (use_resist_override) ? resist_override : spells[spell_id].ResistDiff;
if(caster->IsClient())
{
if(IsValidSpell(spell_id))
{
int focus_resist = caster->CastToClient()->GetFocusEffect(focusResistRate, spell_id);
resist_modifier -= 2 * focus_resist;
}
}
int focus_resist = caster->GetFocusEffect(focusResistRate, spell_id);
resist_modifier -= 2 * focus_resist;
//Check for fear resist
bool IsFear = false;
@@ -4580,17 +4580,14 @@ float Mob::GetAOERange(uint16 spell_id) {
if(range == 0)
range = 10; //something....
if (IsClient()) {
if(IsBardSong(spell_id) && IsBeneficialSpell(spell_id)) {
//Live AA - Extended Notes, SionachiesCrescendo
float song_bonus = static_cast<float>(aabonuses.SongRange + spellbonuses.SongRange + itembonuses.SongRange);
range += range*song_bonus /100.0f;
}
range = CastToClient()->GetActSpellRange(spell_id, range);
if(IsBardSong(spell_id) && IsBeneficialSpell(spell_id)) {
//Live AA - Extended Notes, SionachiesCrescendo
float song_bonus = static_cast<float>(aabonuses.SongRange + spellbonuses.SongRange + itembonuses.SongRange);
range += range*song_bonus /100.0f;
}
range = GetActSpellRange(spell_id, range);
return(range);
}
+6 -19
View File
@@ -21,20 +21,21 @@ Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
#include "tasks.h"
#include <string.h>
#include <stdlib.h>
#ifdef _WINDOWS
#define strcasecmp _stricmp
#endif
#include "../common/misc_functions.h"
#include "../common/string_util.h"
#include "../common/rulesys.h"
#include "masterentity.h"
#include "../common/features.h"
#include "quest_parser_collection.h"
#include "../common/string_util.h"
#include "client.h"
#include "entity.h"
#include "mob.h"
#include "queryserv.h"
#include "quest_parser_collection.h"
extern QueryServ* QServ;
@@ -2772,13 +2773,6 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN
if(strlen(Tasks[TaskID]->Reward) != 0) {
switch(c->GetClientVersion()) {
case EQClient62:
{
MakeAnyLenString(&RewardTmp, "%c%07i-00001-00001-00001-00001-000013E0ABA6B%s%c",
0x12, ItemID, Tasks[TaskID]->Reward,0x12);
break;
}
case EQClientTitanium:
{
MakeAnyLenString(&RewardTmp, "%c%06X000000000000000000000000000000014505DC2%s%c",
@@ -2806,13 +2800,6 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN
if(Item) {
switch(c->GetClientVersion()) {
case EQClient62:
{
MakeAnyLenString(&RewardTmp, "%c%07i-00001-00001-00001-00001-000013E0ABA6B%s%c",
0x12, ItemID, Item->Name,0x12);
break;
}
case EQClientTitanium:
{
MakeAnyLenString(&RewardTmp, "%c%06X000000000000000000000000000000014505DC2%s%c",
+2 -2
View File
@@ -21,9 +21,8 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
#define TASKS_H
#include "../common/types.h"
#include "mob.h"
#include <vector>
#include <queue>
#define MAXTASKS 10000
#define MAXTASKSETS 1000
@@ -44,6 +43,7 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
#define RELOADTASKSETS 3
class Client;
class Mob;
struct TaskGoalList_Struct {
int ListID;
+7 -3
View File
@@ -15,11 +15,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "../common/eq_packet_structs.h"
#include "masterentity.h"
#include "titles.h"
#include "../common/string_util.h"
#include "client.h"
#include "entity.h"
#include "mob.h"
#include "titles.h"
#include "worldserver.h"
extern WorldServer worldserver;
-2
View File
@@ -18,9 +18,7 @@
#ifndef TITLES_H
#define TITLES_H
#include "../common/types.h"
#include <vector>
#include <string>
class Client;
class EQApplicationPacket;
+4 -3
View File
@@ -17,6 +17,7 @@
*/
#include "../common/debug.h"
#include <stdlib.h>
#include <list>
@@ -24,9 +25,9 @@
#include <netinet/in.h> //for htonl
#endif
#include "../common/misc_functions.h"
#include "../common/rulesys.h"
#include "../common/string_util.h"
#include "queryserv.h"
#include "quest_parser_collection.h"
#include "string_ids.h"
@@ -287,7 +288,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob
const Item_Struct* new_weapon = inst->GetItem();
user->DeleteItemInInventory(Inventory::CalcSlotId(in_combine->container_slot, 0), 0, true);
container->Clear();
user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->IsInstNoDrop(), MainCursor, container->GetItem()->Icon, atoi(container->GetItem()->IDFile + 2));
user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), MainCursor, container->GetItem()->Icon, atoi(container->GetItem()->IDFile + 2));
user->Message_StringID(4, TRANSFORM_COMPLETE, inst->GetItem()->Name);
if (RuleB(Inventory, DeleteTransformationMold))
user->DeleteItemInInventory(in_combine->container_slot, 0, true);
@@ -307,7 +308,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob
const Item_Struct* new_weapon = inst->GetItem();
user->DeleteItemInInventory(Inventory::CalcSlotId(in_combine->container_slot, 0), 0, true);
container->Clear();
user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->IsInstNoDrop(), MainCursor, 0, 0);
user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), MainCursor, 0, 0);
user->Message_StringID(4, TRANSFORM_COMPLETE, inst->GetItem()->Name);
}
else if (inst) {
+12 -6
View File
@@ -15,14 +15,20 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "masterentity.h"
#include "string_ids.h"
#include "../common/string_util.h"
#include "../common/rulesys.h"
#include "../common/string_util.h"
#include "client.h"
#include "entity.h"
#include "mob.h"
#include "quest_parser_collection.h"
#include "string_ids.h"
#include "worldserver.h"
#include "queryserv.h"
class QueryServ;
extern WorldServer worldserver;
extern QueryServ* QServ;
@@ -878,14 +884,14 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st
const Item_Struct* item = inst->GetItem();
if(item && quest_npc == false) {
// if it was not a NO DROP or Attuned item (or if a GM is trading), let the NPC have it
if(GetGM() || (item->NoDrop != 0 && inst->IsInstNoDrop() == false)) {
if(GetGM() || (item->NoDrop != 0 && inst->IsAttuned() == false)) {
// pets need to look inside bags and try to equip items found there
if(item->ItemClass == ItemClassContainer && item->BagSlots > 0) {
for(int16 bslot = SUB_BEGIN; bslot < item->BagSlots; bslot++) {
const ItemInst* baginst = inst->GetItem(bslot);
if (baginst) {
const Item_Struct* bagitem = baginst->GetItem();
if (bagitem && (GetGM() || (bagitem->NoDrop != 0 && baginst->IsInstNoDrop() == false))) {
if (bagitem && (GetGM() || (bagitem->NoDrop != 0 && baginst->IsAttuned() == false))) {
tradingWith->CastToNPC()->AddLootDrop(bagitem, &tradingWith->CastToNPC()->itemlist,
baginst->GetCharges(), 1, 127, true, true);
}
+7 -5
View File
@@ -15,13 +15,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "../common/types.h"
#include "entity.h"
#include "masterentity.h"
#include "../common/spdat.h"
#include "../common/misc_functions.h"
#include "../common/string_util.h"
#include "../common/types.h"
#include "client.h"
#include "entity.h"
#include "mob.h"
#include "trap.h"
/*
+3 -2
View File
@@ -18,10 +18,11 @@
#ifndef _TRAP_H
#define _TRAP_H
#include "../common/debug.h"
#include "entity.h"
class Mob;
class NPC;
//ID of the NPC type to spawn when a trap is set off, to do the damage
#define TRAP_NPC_TYPE 1586
+4 -4
View File
@@ -15,13 +15,13 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "../common/eq_packet_structs.h"
#include "../common/features.h"
#include "masterentity.h"
#include "../common/packet_dump.h"
#include "../common/misc_functions.h"
#include <string>
#include "client.h"
#include <map>
#ifdef _WINDOWS
+6 -6
View File
@@ -1,14 +1,14 @@
#include "../common/debug.h"
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <functional>
#include <cctype>
#include "water_map.h"
#include "water_map_v1.h"
#include "water_map_v2.h"
#include <algorithm>
#include <cctype>
#include <stdio.h>
#include <string.h>
WaterMap* WaterMap::LoadWaterMapfile(std::string zone_name) {
std::transform(zone_name.begin(), zone_name.end(), zone_name.begin(), ::tolower);
+3 -1
View File
@@ -21,13 +21,15 @@
#endif
#include "../common/features.h"
#include "../common/misc_functions.h"
#include "../common/rulesys.h"
#include "../common/string_util.h"
#include "../common/misc_functions.h"
#include "map.h"
#include "npc.h"
#include "quest_parser_collection.h"
#include "water_map.h"
#include <math.h>
#include <stdlib.h>
+12 -14
View File
@@ -15,13 +15,12 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <iomanip>
#include <time.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef _WINDOWS
@@ -32,25 +31,24 @@
#define strcasecmp _stricmp
#endif
#include "../common/servertalk.h"
#include "worldserver.h"
#include "../common/eq_packet_structs.h"
#include "../common/packet_dump.h"
#include "../common/misc_functions.h"
#include "zonedb.h"
#include "zone.h"
#include "../common/rulesys.h"
#include "../common/servertalk.h"
#include "client.h"
#include "corpse.h"
#include "entity.h"
#include "masterentity.h"
#include "guild_mgr.h"
#include "mob.h"
#include "net.h"
#include "petitions.h"
#include "../common/packet_functions.h"
#include "../common/md5.h"
#include "zone_config.h"
#include "raids.h"
#include "string_ids.h"
#include "guild_mgr.h"
#include "../common/rulesys.h"
#include "titles.h"
#include "qglobals.h"
#include "worldserver.h"
#include "zone.h"
#include "zone_config.h"
extern EntityList entity_list;
+2 -1
View File
@@ -35,6 +35,7 @@
#include "../common/rulesys.h"
#include "../common/seperator.h"
#include "../common/string_util.h"
#include "client_logs.h"
#include "guild_mgr.h"
#include "map.h"
@@ -48,8 +49,8 @@
#include "spawngroup.h"
#include "water_map.h"
#include "worldserver.h"
#include "zone_config.h"
#include "zone.h"
#include "zone_config.h"
#ifdef _WINDOWS
#define snprintf _snprintf
+5 -1
View File
@@ -67,10 +67,14 @@ struct item_tick_struct {
std::string qglobal;
};
class Client;
class Map;
class WaterMap;
class Mob;
class PathManager;
class WaterMap;
extern EntityList entity_list;
struct NPCType;
struct ServerZoneIncommingClient_Struct;
class Zone
{
+2 -3
View File
@@ -15,8 +15,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include "zone_config.h"
ZoneConfig *ZoneConfig::_zone_config = nullptr;
ZoneConfig *ZoneConfig::_zone_config = nullptr;
+2 -1
View File
@@ -19,9 +19,10 @@
#include "../common/debug.h"
#include "../common/logsys.h"
#include "../common/base_packet.h"
#include "mob.h"
#include <stdarg.h>
#include <stdio.h>
void log_message_mob(LogType type, Mob *who, const char *fmt, ...) {
if(!who->IsLoggingEnabled())
+124 -103
View File
@@ -3,12 +3,14 @@
#include "../common/item.h"
#include "../common/rulesys.h"
#include "../common/string_util.h"
#include "client.h"
#include "corpse.h"
#include "groups.h"
#include "merc.h"
#include "zone.h"
#include "zonedb.h"
#include <ctime>
#include <iostream>
@@ -427,7 +429,7 @@ void ZoneDatabase::LoadWorldContainer(uint32 parentid, ItemInst* container)
return;
}
std::string query = StringFormat("SELECT bagidx, itemid, charges, augslot1, augslot2, augslot3, augslot4, augslot5 "
std::string query = StringFormat("SELECT bagidx, itemid, charges, augslot1, augslot2, augslot3, augslot4, augslot5, augslot6 "
"FROM object_contents WHERE parentid = %i", parentid);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -440,11 +442,12 @@ void ZoneDatabase::LoadWorldContainer(uint32 parentid, ItemInst* container)
uint32 item_id = (uint32)atoi(row[1]);
int8 charges = (int8)atoi(row[2]);
uint32 aug[EmuConstants::ITEM_COMMON_SIZE];
aug[0] = (uint32)atoi(row[3]);
aug[1] = (uint32)atoi(row[4]);
aug[2] = (uint32)atoi(row[5]);
aug[3] = (uint32)atoi(row[6]);
aug[4] = (uint32)atoi(row[7]);
aug[0] = (uint32)atoi(row[3]);
aug[1] = (uint32)atoi(row[4]);
aug[2] = (uint32)atoi(row[5]);
aug[3] = (uint32)atoi(row[6]);
aug[4] = (uint32)atoi(row[7]);
aug[5] = (uint32)atoi(row[8]);
ItemInst* inst = database.CreateItem(item_id, charges);
if (inst && inst->GetItem()->ItemClass == ItemClassCommon) {
@@ -478,7 +481,7 @@ void ZoneDatabase::SaveWorldContainer(uint32 zone_id, uint32 parent_id, const It
continue;
uint32 item_id = inst->GetItem()->ID;
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
if (inst->IsType(ItemClassCommon)) {
for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
@@ -489,10 +492,10 @@ void ZoneDatabase::SaveWorldContainer(uint32 zone_id, uint32 parent_id, const It
std::string query = StringFormat("REPLACE INTO object_contents "
"(zoneid, parentid, bagidx, itemid, charges, "
"augslot1, augslot2, augslot3, augslot4, augslot5, droptime) "
"VALUES (%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, now())",
"augslot1, augslot2, augslot3, augslot4, augslot5, augslot6, droptime) "
"VALUES (%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, now())",
zone_id, parent_id, index, item_id, inst->GetCharges(),
augslot[0], augslot[1], augslot[2], augslot[3], augslot[4]);
augslot[0], augslot[1], augslot[2], augslot[3], augslot[4], augslot[5]);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::SaveWorldContainer: %s", results.ErrorMessage().c_str());
@@ -1002,15 +1005,16 @@ bool ZoneDatabase::LoadCharacterLanguages(uint32 character_id, PlayerProfile_Str
"WHERE `id` = %u ORDER BY `lang_id`", character_id);
auto results = database.QueryDatabase(query); int i = 0;
/* Initialize Languages */
for (i = 0; i < MAX_PP_LANGUAGE; i++){
for (i = 0; i < MAX_PP_LANGUAGE; ++i)
pp->languages[i] = 0;
}
for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]);
for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]);
if (i < MAX_PP_LANGUAGE){
pp->languages[i] = atoi(row[1]);
}
}
return true;
}
@@ -1033,14 +1037,14 @@ bool ZoneDatabase::LoadCharacterDisciplines(uint32 character_id, PlayerProfile_S
"WHERE `id` = %u ORDER BY `slot_id`", character_id);
auto results = database.QueryDatabase(query);
int i = 0;
/* Initialize Disciplines */
memset(pp->disciplines.values, 0, (sizeof(pp->disciplines.values[0]) * MAX_PP_DISCIPLINES));
for (auto row = results.begin(); row != results.end(); ++row) {
if (i < MAX_PP_DISCIPLINES){
if (i < MAX_PP_DISCIPLINES)
pp->disciplines.values[i] = atoi(row[0]);
}
i++;
}
++i;
}
return true;
}
@@ -1052,17 +1056,18 @@ bool ZoneDatabase::LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct
"FROM "
"`character_skills` "
"WHERE `id` = %u ORDER BY `skill_id`", character_id);
auto results = database.QueryDatabase(query); int i = 0;
auto results = database.QueryDatabase(query);
int i = 0;
/* Initialize Skill */
for (i = 0; i < MAX_PP_SKILL; i++){
for (i = 0; i < MAX_PP_SKILL; ++i)
pp->skills[i] = 0;
}
for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]);
if (i < MAX_PP_SKILL){
for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]);
if (i < MAX_PP_SKILL)
pp->skills[i] = atoi(row[1]);
}
}
return true;
}
@@ -1172,44 +1177,49 @@ bool ZoneDatabase::LoadCharacterPotions(uint32 character_id, PlayerProfile_Struc
pp->potionbelt.items[i].item_id = 0;
strncpy(pp->potionbelt.items[i].item_name, "\0", 1);
}
for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]); /* Potion belt slot number */
uint32 item_id = atoi(row[1]);
const Item_Struct *item = database.GetItem(item_id);
if(item) {
pp->potionbelt.items[i].item_id = item_id;
pp->potionbelt.items[i].icon = atoi(row[2]);
strncpy(pp->potionbelt.items[i].item_name, item->Name, 64);
}
if(!item)
continue;
pp->potionbelt.items[i].item_id = item_id;
pp->potionbelt.items[i].icon = atoi(row[2]);
strncpy(pp->potionbelt.items[i].item_name, item->Name, 64);
}
return true;
}
bool ZoneDatabase::LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp){
std::string query = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `is_home` FROM `character_bind` WHERE `id` = %u LIMIT 2", character_id);
auto results = database.QueryDatabase(query); int i = 0;
auto results = database.QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) {
i = 0;
/* Is home bind */
if (atoi(row[6]) == 1){
pp->binds[4].zoneId = atoi(row[i++]);
pp->binds[4].instance_id = atoi(row[i++]);
pp->binds[4].x = atoi(row[i++]);
pp->binds[4].y = atoi(row[i++]);
pp->binds[4].z = atoi(row[i++]);
pp->binds[4].heading = atoi(row[i++]);
pp->binds[4].zoneId = atoi(row[0]);
pp->binds[4].instance_id = atoi(row[1]);
pp->binds[4].x = atoi(row[2]);
pp->binds[4].y = atoi(row[3]);
pp->binds[4].z = atoi(row[4]);
pp->binds[4].heading = atoi(row[5]);
continue;
}
/* Is regular bind point */
else{
pp->binds[0].zoneId = atoi(row[i++]);
pp->binds[0].instance_id = atoi(row[i++]);
pp->binds[0].x = atoi(row[i++]);
pp->binds[0].y = atoi(row[i++]);
pp->binds[0].z = atoi(row[i++]);
pp->binds[0].heading = atoi(row[i++]);
}
pp->binds[0].zoneId = atoi(row[0]);
pp->binds[0].instance_id = atoi(row[1]);
pp->binds[0].x = atoi(row[2]);
pp->binds[0].y = atoi(row[3]);
pp->binds[0].z = atoi(row[4]);
pp->binds[0].heading = atoi(row[5]);
}
return true;
}
@@ -2100,7 +2110,7 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
bool ZoneDatabase::LoadMercInfo(Client *client) {
std::string query = StringFormat("SELECT MercID, Slot, Name, TemplateID, SuspendedTime, "
"IsSuspended, TimerRemaining, Gender, StanceID, HP, Mana, "
"IsSuspended, TimerRemaining, Gender, MercSize, StanceID, HP, Mana, "
"Endurance, Face, LuclinHairStyle, LuclinHairColor, "
"LuclinEyeColor, LuclinEyeColor2, LuclinBeardColor, LuclinBeard, "
"DrakkinHeritage, DrakkinTattoo, DrakkinDetails "
@@ -2126,21 +2136,22 @@ bool ZoneDatabase::LoadMercInfo(Client *client) {
client->GetMercInfo(slot).IsSuspended = atoi(row[5]) == 1 ? true : false;
client->GetMercInfo(slot).MercTimerRemaining = atoi(row[6]);
client->GetMercInfo(slot).Gender = atoi(row[7]);
client->GetMercInfo(slot).MercSize = atof(row[8]);
client->GetMercInfo(slot).State = 5;
client->GetMercInfo(slot).Stance = atoi(row[8]);
client->GetMercInfo(slot).hp = atoi(row[9]);
client->GetMercInfo(slot).mana = atoi(row[10]);
client->GetMercInfo(slot).endurance = atoi(row[11]);
client->GetMercInfo(slot).face = atoi(row[12]);
client->GetMercInfo(slot).luclinHairStyle = atoi(row[13]);
client->GetMercInfo(slot).luclinHairColor = atoi(row[14]);
client->GetMercInfo(slot).luclinEyeColor = atoi(row[15]);
client->GetMercInfo(slot).luclinEyeColor2 = atoi(row[16]);
client->GetMercInfo(slot).luclinBeardColor = atoi(row[17]);
client->GetMercInfo(slot).luclinBeard = atoi(row[18]);
client->GetMercInfo(slot).drakkinHeritage = atoi(row[19]);
client->GetMercInfo(slot).drakkinTattoo = atoi(row[20]);
client->GetMercInfo(slot).drakkinDetails = atoi(row[21]);
client->GetMercInfo(slot).Stance = atoi(row[9]);
client->GetMercInfo(slot).hp = atoi(row[10]);
client->GetMercInfo(slot).mana = atoi(row[11]);
client->GetMercInfo(slot).endurance = atoi(row[12]);
client->GetMercInfo(slot).face = atoi(row[13]);
client->GetMercInfo(slot).luclinHairStyle = atoi(row[14]);
client->GetMercInfo(slot).luclinHairColor = atoi(row[15]);
client->GetMercInfo(slot).luclinEyeColor = atoi(row[16]);
client->GetMercInfo(slot).luclinEyeColor2 = atoi(row[17]);
client->GetMercInfo(slot).luclinBeardColor = atoi(row[18]);
client->GetMercInfo(slot).luclinBeard = atoi(row[19]);
client->GetMercInfo(slot).drakkinHeritage = atoi(row[20]);
client->GetMercInfo(slot).drakkinTattoo = atoi(row[21]);
client->GetMercInfo(slot).drakkinDetails = atoi(row[22]);
}
return true;
@@ -2154,7 +2165,7 @@ bool ZoneDatabase::LoadCurrentMerc(Client *client) {
return false;
std::string query = StringFormat("SELECT MercID, Name, TemplateID, SuspendedTime, "
"IsSuspended, TimerRemaining, Gender, StanceID, HP, "
"IsSuspended, TimerRemaining, Gender, MercSize, StanceID, HP, "
"Mana, Endurance, Face, LuclinHairStyle, LuclinHairColor, "
"LuclinEyeColor, LuclinEyeColor2, LuclinBeardColor, "
"LuclinBeard, DrakkinHeritage, DrakkinTattoo, DrakkinDetails "
@@ -2164,7 +2175,7 @@ bool ZoneDatabase::LoadCurrentMerc(Client *client) {
if(!results.Success())
return false;
if(results.RowCount() == 0)
return false;
@@ -2178,20 +2189,21 @@ bool ZoneDatabase::LoadCurrentMerc(Client *client) {
client->GetMercInfo(slot).IsSuspended = atoi(row[4]) == 1? true: false;
client->GetMercInfo(slot).MercTimerRemaining = atoi(row[5]);
client->GetMercInfo(slot).Gender = atoi(row[6]);
client->GetMercInfo(slot).State = atoi(row[7]);
client->GetMercInfo(slot).hp = atoi(row[8]);
client->GetMercInfo(slot).mana = atoi(row[9]);
client->GetMercInfo(slot).endurance = atoi(row[10]);
client->GetMercInfo(slot).face = atoi(row[11]);
client->GetMercInfo(slot).luclinHairStyle = atoi(row[12]);
client->GetMercInfo(slot).luclinHairColor = atoi(row[13]);
client->GetMercInfo(slot).luclinEyeColor = atoi(row[14]);
client->GetMercInfo(slot).luclinEyeColor2 = atoi(row[15]);
client->GetMercInfo(slot).luclinBeardColor = atoi(row[16]);
client->GetMercInfo(slot).luclinBeard = atoi(row[17]);
client->GetMercInfo(slot).drakkinHeritage = atoi(row[18]);
client->GetMercInfo(slot).drakkinTattoo = atoi(row[19]);
client->GetMercInfo(slot).drakkinDetails = atoi(row[20]);
client->GetMercInfo(slot).MercSize = atof(row[7]);
client->GetMercInfo(slot).State = atoi(row[8]);
client->GetMercInfo(slot).hp = atoi(row[9]);
client->GetMercInfo(slot).mana = atoi(row[10]);
client->GetMercInfo(slot).endurance = atoi(row[11]);
client->GetMercInfo(slot).face = atoi(row[12]);
client->GetMercInfo(slot).luclinHairStyle = atoi(row[13]);
client->GetMercInfo(slot).luclinHairColor = atoi(row[14]);
client->GetMercInfo(slot).luclinEyeColor = atoi(row[15]);
client->GetMercInfo(slot).luclinEyeColor2 = atoi(row[16]);
client->GetMercInfo(slot).luclinBeardColor = atoi(row[17]);
client->GetMercInfo(slot).luclinBeard = atoi(row[18]);
client->GetMercInfo(slot).drakkinHeritage = atoi(row[19]);
client->GetMercInfo(slot).drakkinTattoo = atoi(row[20]);
client->GetMercInfo(slot).drakkinDetails = atoi(row[21]);
}
return true;
@@ -2209,19 +2221,19 @@ bool ZoneDatabase::SaveMerc(Merc *merc) {
std::string query = StringFormat("INSERT INTO mercs "
"(OwnerCharacterID, Slot, Name, TemplateID, "
"SuspendedTime, IsSuspended, TimerRemaining, "
"Gender, StanceID, HP, Mana, Endurance, Face, "
"Gender, MercSize, StanceID, HP, Mana, Endurance, Face, "
"LuclinHairStyle, LuclinHairColor, LuclinEyeColor, "
"LuclinEyeColor2, LuclinBeardColor, LuclinBeard, "
"DrakkinHeritage, DrakkinTattoo, DrakkinDetails) "
"VALUES('%u', '%u', '%s', '%u', '%u', '%u', '%u', "
"'%u', '%u', '%u', '%u', '%u', '%i', '%i', '%i', "
"'%u', '%u', '%f', '%u', '%u', '%u', '%i', '%i', '%i', "
"'%i', '%i', '%i', '%i', '%i', '%i', '%i')",
merc->GetMercCharacterID(), owner->GetNumMercs(),
merc->GetCleanName(), merc->GetMercTemplateID(),
owner->GetMercInfo().SuspendedTime, merc->IsSuspended(),
owner->GetMercInfo().MercTimerRemaining, merc->GetGender(),
merc->GetStance(), merc->GetHP(), merc->GetMana(),
merc->GetEndurance(), merc->GetLuclinFace(),
merc->GetSize(), merc->GetStance(), merc->GetHP(),
merc->GetMana(), merc->GetEndurance(), merc->GetLuclinFace(),
merc->GetHairStyle(), merc->GetHairColor(), merc->GetEyeColor1(),
merc->GetEyeColor2(), merc->GetBeardColor(),
merc->GetBeard(), merc->GetDrakkinHeritage(),
@@ -2245,7 +2257,7 @@ bool ZoneDatabase::SaveMerc(Merc *merc) {
// Update existing merc record
std::string query = StringFormat("UPDATE mercs SET OwnerCharacterID = '%u', Slot = '%u', "
"Name = '%s', TemplateID = '%u', SuspendedTime = '%u', "
"IsSuspended = '%u', TimerRemaining = '%u', Gender = '%u', "
"IsSuspended = '%u', TimerRemaining = '%u', Gender = '%u', MercSize = '%f', "
"StanceID = '%u', HP = '%u', Mana = '%u', Endurance = '%u', "
"Face = '%i', LuclinHairStyle = '%i', LuclinHairColor = '%i', "
"LuclinEyeColor = '%i', LuclinEyeColor2 = '%i', LuclinBeardColor = '%i', "
@@ -2254,11 +2266,12 @@ bool ZoneDatabase::SaveMerc(Merc *merc) {
merc->GetMercCharacterID(), owner->GetMercSlot(), merc->GetCleanName(),
merc->GetMercTemplateID(), owner->GetMercInfo().SuspendedTime,
merc->IsSuspended(), owner->GetMercInfo().MercTimerRemaining,
merc->GetGender(), merc->GetStance(), merc->GetHP(), merc->GetMana(),
merc->GetEndurance(), merc->GetLuclinFace(), merc->GetHairStyle(),
merc->GetHairColor(), merc->GetEyeColor1(), merc->GetEyeColor2(),
merc->GetBeardColor(), merc->GetBeard(), merc->GetDrakkinHeritage(),
merc->GetDrakkinTattoo(), merc->GetDrakkinDetails(), merc->GetMercID());
merc->GetGender(), merc->GetSize(), merc->GetStance(), merc->GetHP(),
merc->GetMana(), merc->GetEndurance(), merc->GetLuclinFace(),
merc->GetHairStyle(), merc->GetHairColor(), merc->GetEyeColor1(),
merc->GetEyeColor2(), merc->GetBeardColor(), merc->GetBeard(),
merc->GetDrakkinHeritage(), merc->GetDrakkinTattoo(), merc->GetDrakkinDetails(),
merc->GetMercID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
@@ -3362,9 +3375,9 @@ uint32 ZoneDatabase::GetCharacterCorpseDecayTimer(uint32 corpse_db_id){
std::string query = StringFormat("SELECT(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) FROM `character_corpses` WHERE `id` = %d AND NOT `time_of_death` = 0", corpse_db_id);
auto results = QueryDatabase(query);
auto row = results.begin();
if (results.Success() && results.RowsAffected() != 0){
return atoul(row[0]);
}
if (results.Success() && results.RowsAffected() != 0)
return atoul(row[0]);
return 0;
}
@@ -3438,22 +3451,24 @@ uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, ui
for (unsigned int i = 0; i < dbpc->itemcount; i++) {
if (first_entry != 1){
query = StringFormat("REPLACE INTO `character_corpse_items` \n"
" (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, attuned) \n"
" VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n",
last_insert_id,
" (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n"
" VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
last_insert_id,
dbpc->items[i].equip_slot,
dbpc->items[i].item_id,
dbpc->items[i].charges,
dbpc->items[i].aug_1,
dbpc->items[i].aug_2,
dbpc->items[i].aug_3,
dbpc->items[i].aug_4,
dbpc->items[i].aug_5
dbpc->items[i].item_id,
dbpc->items[i].charges,
dbpc->items[i].aug_1,
dbpc->items[i].aug_2,
dbpc->items[i].aug_3,
dbpc->items[i].aug_4,
dbpc->items[i].aug_5,
dbpc->items[i].aug_6,
dbpc->items[i].attuned
);
first_entry = 1;
}
else{
query = query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n",
else{
query = query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
last_insert_id,
dbpc->items[i].equip_slot,
dbpc->items[i].item_id,
@@ -3462,7 +3477,9 @@ uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, ui
dbpc->items[i].aug_2,
dbpc->items[i].aug_3,
dbpc->items[i].aug_4,
dbpc->items[i].aug_5
dbpc->items[i].aug_5,
dbpc->items[i].aug_6,
dbpc->items[i].attuned
);
}
}
@@ -3613,6 +3630,7 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct
"aug_3, \n"
"aug_4, \n"
"aug_5, \n"
"aug_6, \n"
"attuned \n"
"FROM \n"
"character_corpse_items \n"
@@ -3635,6 +3653,8 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct
pcs->items[i].aug_3 = atoi(row[r++]); // aug_3,
pcs->items[i].aug_4 = atoi(row[r++]); // aug_4,
pcs->items[i].aug_5 = atoi(row[r++]); // aug_5,
pcs->items[i].aug_6 = atoi(row[r++]); // aug_6,
pcs->items[i].attuned = atoi(row[r++]); // attuned,
r = 0;
i++;
}
@@ -3824,3 +3844,4 @@ bool ZoneDatabase::DeleteCharacterCorpse(uint32 db_id) {
return false;
}
+2
View File
@@ -139,6 +139,8 @@ namespace player_lootitem {
uint32 aug_3;
uint32 aug_4;
uint32 aug_5;
uint32 aug_6;
int8 attuned;
uint8 min_level; //
uint8 max_level; //
};
+5
View File
@@ -19,12 +19,17 @@
#include "../common/debug.h"
#include "../common/rulesys.h"
#include "../common/string_util.h"
#include "queryserv.h"
#include "quest_parser_collection.h"
#include "string_ids.h"
#include "worldserver.h"
#include "zone.h"
#ifdef BOTS
#include "bot.h"
#endif
extern QueryServ* QServ;
extern WorldServer worldserver;
extern Zone* zone;