mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-01 01:52:02 +00:00
Merge branch 'master' of github.com:EQEmu/Server
This commit is contained in:
@@ -1,5 +1,16 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 6/28/2017 ==
|
||||
Akkadius: Fixed issues with Z correctness when NPCs are pathing on normal grids
|
||||
Akkadius: Fixed issues with Z correctness when NPCs are engaged with players following
|
||||
Akkadius: NPC corpses should fall into the ground far less
|
||||
|
||||
== 6/25/2017 ==
|
||||
Akkadius: New rules made by developers are now automatically created when world boots up, this keeps
|
||||
from having to issue schema SQL updates every time rules are added.
|
||||
- Whenever a rule isn't present in the database, it will be automatically created
|
||||
Akkadius: Sped up saylink retrieval x1000 helpful for dialogues, plugins with many saylinks
|
||||
|
||||
== 4/16/2017 ==
|
||||
KLS: Merge eqstream branch
|
||||
- UDP client stack completely rewritten should both have better throughput and recover better (peq has had far fewer reports of desyncs).
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace EQ
|
||||
resend_delay_ms = 150;
|
||||
resend_delay_factor = 1.5;
|
||||
resend_delay_min = 150;
|
||||
resend_delay_max = 4000;
|
||||
resend_delay_max = 1000;
|
||||
connect_delay_ms = 500;
|
||||
stale_connection_ms = 90000;
|
||||
connect_stale_ms = 5000;
|
||||
|
||||
@@ -274,6 +274,7 @@ RULE_BOOL(Map, FixPathingZWhenLoading, true) //increases zone boot times a bit
|
||||
RULE_BOOL(Map, FixPathingZAtWaypoints, false) //alternative to `WhenLoading`, accomplishes the same thing but does it at each waypoint instead of once at boot time.
|
||||
RULE_BOOL(Map, FixPathingZWhenMoving, false) //very CPU intensive, but helps hopping with widely spaced waypoints.
|
||||
RULE_BOOL(Map, FixPathingZOnSendTo, false) //try to repair Z coords in the SendTo routine as well.
|
||||
RULE_BOOL(Map, FixZWhenMoving, true) // Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)
|
||||
RULE_REAL(Map, FixPathingZMaxDeltaMoving, 20) //at runtime while pathing: max change in Z to allow the BestZ code to apply.
|
||||
RULE_REAL(Map, FixPathingZMaxDeltaWaypoint, 20) //at runtime at each waypoint: max change in Z to allow the BestZ code to apply.
|
||||
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20) //at runtime in SendTo: max change in Z to allow the BestZ code to apply.
|
||||
@@ -397,6 +398,7 @@ RULE_BOOL(Spells, FlatItemExtraSpellAmt, false) // allow SpellDmg stat to affect
|
||||
RULE_BOOL(Spells, IgnoreSpellDmgLvlRestriction, false) // ignore the 5 level spread on applying SpellDmg
|
||||
RULE_BOOL(Spells, AllowItemTGB, false) // TGB doesn't work with items on live, custom servers want it though
|
||||
RULE_BOOL(Spells, NPCInnateProcOverride, true) // NPC innate procs override the target type to single target.
|
||||
RULE_BOOL(Spells, OldRainTargets, false) // use old incorrectly implemented max targets for rains
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Combat)
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9111
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9112
|
||||
#ifdef BOTS
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9017
|
||||
#else
|
||||
|
||||
@@ -42,6 +42,7 @@ WeaponSkillFalloff = RuleR.Get(Rule.WeaponSkillFalloff);
|
||||
ArcheryHitPenalty = RuleR.Get(Rule.ArcheryHitPenalty);
|
||||
UseOldDamageIntervalRules = RuleB.Get(Rule.UseOldDamageIntervalRules);
|
||||
|
||||
CriticalMessageRange = RuleI.Get(Rule.CriticalDamage);
|
||||
|
||||
function MeleeMitigation(e)
|
||||
e.IgnoreDefault = true;
|
||||
@@ -238,9 +239,9 @@ function TryCriticalHit(e)
|
||||
e.hit.damage_done = (e.hit.damage_done * SlayDmgBonus * 2.25) / 100;
|
||||
|
||||
if (self:GetGender() == 1) then
|
||||
entity_list:FilteredMessageClose(self, false, 200, MT.CritMelee, Filter.MeleeCrits, string.format('%s\'s holy blade cleanses her target! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
entity_list:FilteredMessageClose(self, false, CriticalMessageRange, MT.CritMelee, Filter.MeleeCrits, string.format('%s\'s holy blade cleanses her target! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
else
|
||||
entity_list:FilteredMessageClose(self, false, 200, MT.CritMelee, Filter.MeleeCrits, string.format('%s\'s holy blade cleanses his target! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
entity_list:FilteredMessageClose(self, false, CriticalMessageRange, MT.CritMelee, Filter.MeleeCrits, string.format('%s\'s holy blade cleanses his target! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
end
|
||||
|
||||
return e;
|
||||
@@ -326,15 +327,15 @@ function TryCriticalHit(e)
|
||||
end
|
||||
|
||||
if (crip_success) then
|
||||
entity_list:FilteredMessageClose(self, false, 200, MT.CritMelee, Filter.MeleeCrits, string.format('%s lands a Crippling Blow! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
entity_list:FilteredMessageClose(self, false, CriticalMessageRange, MT.CritMelee, Filter.MeleeCrits, string.format('%s lands a Crippling Blow! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
if (defender:GetLevel() <= 55 and not defender:GetSpecialAbility(SpecialAbility.unstunable)) then
|
||||
defender:Emote("staggers.");
|
||||
defender:Stun(0);
|
||||
end
|
||||
elseif (deadlySuccess) then
|
||||
entity_list:FilteredMessageClose(self, false, 200, MT.CritMelee, Filter.MeleeCrits, string.format('%s scores a Deadly Strike! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
entity_list:FilteredMessageClose(self, false, CriticalMessageRange, MT.CritMelee, Filter.MeleeCrits, string.format('%s scores a Deadly Strike! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
else
|
||||
entity_list:FilteredMessageClose(self, false, 200, MT.CritMelee, Filter.MeleeCrits, string.format('%s scores a critical hit! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
entity_list:FilteredMessageClose(self, false, CriticalMessageRange, MT.CritMelee, Filter.MeleeCrits, string.format('%s scores a critical hit! (%d)', self:GetCleanName(), e.hit.damage_done));
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -379,9 +380,9 @@ function TryPetCriticalHit(self, defender, hit)
|
||||
local entity_list = eq.get_entity_list();
|
||||
critMod = critMod + GetCritDmgMod(self, hit.skill) * 2;
|
||||
hit.damage_done = (hit.damage_done * critMod) / 100;
|
||||
entity_list:FilteredMessageClose(this, false, 200,
|
||||
entity_list:FilteredMessageClose(this, false, CriticalMessageRange,
|
||||
MT.CritMelee, Filter.MeleeCrits, string.format('%s scores a critical hit! (%d)',
|
||||
self:GetCleanName(), hit.damage_done));
|
||||
self:GetCleanName(), e.hit.damage_done));
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -365,6 +365,7 @@
|
||||
9109|2017_04_08_doors_disable_timer.sql|SHOW COLUMNS FROM `doors` LIKE 'disable_timer'|empty|
|
||||
9110|2017_04_10_graveyard.sql|show index from graveyard WHERE key_name = 'zone_id_nonunique'|empty|
|
||||
9111|2017_06_24_saylink_index.sql|SHOW INDEX FROM `saylink` WHERE `key_name` = 'phrase_index'|empty|
|
||||
9112|2017_06_24_rule_values_expand.sql|SHOW COLUMNS FROM rule_values WHERE Field = 'rule_value' and Type = 'varchar(30)'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `rule_values`
|
||||
MODIFY COLUMN `rule_value` varchar(30) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `rule_name`;
|
||||
@@ -332,6 +332,8 @@ int main(int argc, char** argv) {
|
||||
database.ClearMerchantTemp();
|
||||
}
|
||||
|
||||
RuleManager::Instance()->SaveRules(&database);
|
||||
|
||||
Log(Logs::General, Logs::World_Server, "Loading EQ time of day..");
|
||||
TimeOfDay_Struct eqTime;
|
||||
time_t realtime;
|
||||
|
||||
+9
-3
@@ -53,9 +53,8 @@ extern WorldServer worldserver;
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
|
||||
EQEmu::skills::SkillType Mob::AttackAnimation(int Hand, const EQEmu::ItemInstance* weapon)
|
||||
EQEmu::skills::SkillType Mob::AttackAnimation(int Hand, const EQEmu::ItemInstance* weapon, EQEmu::skills::SkillType skillinuse)
|
||||
{
|
||||
EQEmu::skills::SkillType skillinuse = EQEmu::skills::Skill1HBlunt;
|
||||
// Determine animation
|
||||
int type = 0;
|
||||
if (weapon && weapon->IsClassCommon()) {
|
||||
@@ -1924,7 +1923,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
//do attack animation regardless of whether or not we can hit below
|
||||
int16 charges = 0;
|
||||
EQEmu::ItemInstance weapon_inst(weapon, charges);
|
||||
my_hit.skill = AttackAnimation(Hand, &weapon_inst);
|
||||
my_hit.skill = AttackAnimation(Hand, &weapon_inst, my_hit.skill);
|
||||
|
||||
//basically "if not immune" then do the attack
|
||||
if (weapon_damage > 0) {
|
||||
@@ -2388,6 +2387,13 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
|
||||
|
||||
entity_list.UnMarkNPC(GetID());
|
||||
entity_list.RemoveNPC(GetID());
|
||||
|
||||
/* Fix Z on Corpse Creation */
|
||||
glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);
|
||||
float new_z = zone->zonemap->FindBestZ(dest, nullptr);
|
||||
corpse->SetFlyMode(1);
|
||||
corpse->GMMove(m_Position.x, m_Position.y, new_z + 5, m_Position.w);
|
||||
|
||||
this->SetID(0);
|
||||
|
||||
if (killer != 0 && emoteid != 0)
|
||||
|
||||
+5
-2
@@ -68,6 +68,7 @@ Beacon::Beacon(Mob *at_mob, int lifetime)
|
||||
resist_adjust = 0;
|
||||
spell_iterations = 0;
|
||||
caster_id = 0;
|
||||
max_targets = 4; // default
|
||||
|
||||
if(lifetime)
|
||||
remove_timer.Start();
|
||||
@@ -93,10 +94,10 @@ bool Beacon::Process()
|
||||
)
|
||||
{
|
||||
Mob *caster = entity_list.GetMob(caster_id);
|
||||
if(caster && spell_iterations--)
|
||||
if(caster && spell_iterations-- && max_targets)
|
||||
{
|
||||
bool affect_caster = (!caster->IsNPC() && !caster->IsAIControlled()); //NPC AE spells do not affect the NPC caster
|
||||
entity_list.AESpell(caster, this, spell_id, affect_caster, resist_adjust);
|
||||
entity_list.AESpell(caster, this, spell_id, affect_caster, resist_adjust, &max_targets);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -126,6 +127,8 @@ void Beacon::AELocationSpell(Mob *caster, uint16 cast_spell_id, int16 resist_adj
|
||||
this->resist_adjust = resist_adjust;
|
||||
spell_iterations = spells[spell_id].AEDuration / 2500;
|
||||
spell_iterations = spell_iterations < 1 ? 1 : spell_iterations; // at least 1
|
||||
if (spells[spell_id].aemaxtargets)
|
||||
max_targets = spells[spell_id].aemaxtargets;
|
||||
spell_timer.Start(2500);
|
||||
spell_timer.Trigger();
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ protected:
|
||||
int16 resist_adjust;
|
||||
int spell_iterations;
|
||||
Timer spell_timer;
|
||||
int max_targets;
|
||||
|
||||
uint16 caster_id;
|
||||
private:
|
||||
|
||||
+28
-23
@@ -694,7 +694,7 @@ void EntityList::AETaunt(Client* taunter, float range, int32 bonus_hate)
|
||||
// causes caster to hit every mob within dist range of center with
|
||||
// spell_id.
|
||||
// NPC spells will only affect other NPCs with compatible faction
|
||||
void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust)
|
||||
void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust, int *max_targets)
|
||||
{
|
||||
Mob *curmob = nullptr;
|
||||
|
||||
@@ -703,12 +703,25 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
|
||||
float dist_targ = 0;
|
||||
|
||||
const auto &position = spells[spell_id].targettype == ST_Ring ? caster->GetTargetRingLocation() : static_cast<glm::vec3>(center->GetPosition());
|
||||
glm::vec2 min = { position.x - dist, position.y - dist };
|
||||
glm::vec2 max = { position.x + dist, position.y + dist };
|
||||
|
||||
bool bad = IsDetrimentalSpell(spell_id);
|
||||
bool isnpc = caster->IsNPC();
|
||||
int MAX_TARGETS_ALLOWED = 4;
|
||||
|
||||
if (spells[spell_id].aemaxtargets)
|
||||
MAX_TARGETS_ALLOWED = spells[spell_id].aemaxtargets;
|
||||
if (RuleB(Spells, OldRainTargets))
|
||||
max_targets = nullptr; // ignore it!
|
||||
|
||||
// if we have a passed in value, use it, otherwise default to data
|
||||
// detrimental Target AEs have a default value of 4 for PCs and unlimited for NPCs
|
||||
int max_targets_allowed = 0; // unlimited
|
||||
if (max_targets) // rains pass this in since they need to preserve the count through waves
|
||||
max_targets_allowed = *max_targets;
|
||||
else if (spells[spell_id].aemaxtargets)
|
||||
max_targets_allowed = spells[spell_id].aemaxtargets;
|
||||
else if (IsTargetableAESpell(spell_id) && bad && !isnpc)
|
||||
max_targets_allowed = 4;
|
||||
|
||||
int iCounter = 0;
|
||||
|
||||
@@ -732,13 +745,10 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
continue;
|
||||
if (spells[spell_id].pcnpc_only_flag == 2 && (curmob->IsClient() || curmob->IsMerc()))
|
||||
continue;
|
||||
if (!IsWithinAxisAlignedBox(static_cast<glm::vec2>(curmob->GetPosition()), min, max))
|
||||
continue;
|
||||
|
||||
if (spells[spell_id].targettype == ST_Ring) {
|
||||
dist_targ = DistanceSquared(static_cast<glm::vec3>(curmob->GetPosition()), caster->GetTargetRingLocation());
|
||||
}
|
||||
else if (center) {
|
||||
dist_targ = DistanceSquared(curmob->GetPosition(), center->GetPosition());
|
||||
}
|
||||
dist_targ = DistanceSquared(curmob->GetPosition(), position);
|
||||
|
||||
if (dist_targ > dist2) //make sure they are in range
|
||||
continue;
|
||||
@@ -776,24 +786,19 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
}
|
||||
|
||||
curmob->CalcSpellPowerDistanceMod(spell_id, dist_targ);
|
||||
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
|
||||
|
||||
//if we get here... cast the spell.
|
||||
if (IsTargetableAESpell(spell_id) && bad) {
|
||||
if (iCounter < MAX_TARGETS_ALLOWED) {
|
||||
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
|
||||
}
|
||||
} else {
|
||||
if (spells[spell_id].aemaxtargets && iCounter < spells[spell_id].aemaxtargets)
|
||||
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
|
||||
if (!spells[spell_id].aemaxtargets)
|
||||
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
|
||||
}
|
||||
|
||||
if (!isnpc || spells[spell_id].aemaxtargets) //npcs are not target limited (unless casting a spell with a target limit)...
|
||||
if (max_targets_allowed) { // if we have a limit, increment count
|
||||
iCounter++;
|
||||
if (iCounter >= max_targets_allowed) // we done
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_targets && max_targets_allowed)
|
||||
*max_targets = *max_targets - iCounter;
|
||||
}
|
||||
|
||||
void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster)
|
||||
{
|
||||
Mob *curmob = nullptr;
|
||||
|
||||
+1
-1
@@ -357,7 +357,7 @@ public:
|
||||
|
||||
void AEAttack(Mob *attacker, float dist, int Hand = EQEmu::inventory::slotPrimary, int count = 0, bool IsFromSpell = false);
|
||||
void AETaunt(Client *caster, float range=0, int32 bonus_hate=0);
|
||||
void AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true, int16 resist_adjust = 0);
|
||||
void AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true, int16 resist_adjust = 0, int *max_targets = nullptr);
|
||||
void MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
|
||||
void AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
|
||||
|
||||
|
||||
+3
-1
@@ -112,7 +112,9 @@ Mob::Mob(const char* in_name,
|
||||
m_Position(position),
|
||||
tmHidden(-1),
|
||||
mitigation_ac(0),
|
||||
m_specialattacks(eSpecialAttacks::None)
|
||||
m_specialattacks(eSpecialAttacks::None),
|
||||
fix_z_timer(1000),
|
||||
fix_z_timer_engaged(100)
|
||||
{
|
||||
targeted = 0;
|
||||
tar_ndx=0;
|
||||
|
||||
+4
-1
@@ -233,7 +233,7 @@ public:
|
||||
inline bool SeeImprovedHide() const { return see_improved_hide; }
|
||||
bool IsInvisible(Mob* other = 0) const;
|
||||
void SetInvisible(uint8 state);
|
||||
EQEmu::skills::SkillType AttackAnimation(int Hand, const EQEmu::ItemInstance* weapon);
|
||||
EQEmu::skills::SkillType AttackAnimation(int Hand, const EQEmu::ItemInstance* weapon, EQEmu::skills::SkillType skillinuse = EQEmu::skills::Skill1HBlunt);
|
||||
|
||||
//Song
|
||||
bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1);
|
||||
@@ -913,6 +913,7 @@ public:
|
||||
float GetGroundZ(float new_x, float new_y, float z_offset=0.0);
|
||||
void SendTo(float new_x, float new_y, float new_z);
|
||||
void SendToFixZ(float new_x, float new_y, float new_z);
|
||||
void FixZ();
|
||||
void NPCSpecialAttacks(const char* parse, int permtag, bool reset = true, bool remove = false);
|
||||
inline uint32 DontHealMeBefore() const { return pDontHealMeBefore; }
|
||||
inline uint32 DontBuffMeBefore() const { return pDontBuffMeBefore; }
|
||||
@@ -1373,6 +1374,8 @@ protected:
|
||||
|
||||
bool flee_mode;
|
||||
Timer flee_timer;
|
||||
Timer fix_z_timer;
|
||||
Timer fix_z_timer_engaged;
|
||||
|
||||
bool pAIControlled;
|
||||
bool roamer;
|
||||
|
||||
@@ -743,6 +743,10 @@ void Client::AI_Process()
|
||||
|
||||
if(RuleB(Combat, EnableFearPathing)){
|
||||
if(currently_fleeing) {
|
||||
|
||||
if (fix_z_timer_engaged.Check())
|
||||
this->FixZ();
|
||||
|
||||
if(IsRooted()) {
|
||||
//make sure everybody knows were not moving, for appearance sake
|
||||
if(IsMoving())
|
||||
@@ -782,6 +786,7 @@ void Client::AI_Process()
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -991,6 +996,12 @@ void Mob::AI_Process() {
|
||||
|
||||
if (engaged) {
|
||||
|
||||
/* Fix Z when following during pull, not when engaged and stationary */
|
||||
if (moving && fix_z_timer_engaged.Check())
|
||||
if(this->GetTarget())
|
||||
if(DistanceNoZ(this->GetPosition(), this->GetTarget()->GetPosition()) > 50)
|
||||
this->FixZ();
|
||||
|
||||
if (!(m_PlayerState & static_cast<uint32>(PlayerState::Aggressive)))
|
||||
SendAddPlayerState(PlayerState::Aggressive);
|
||||
// we are prevented from getting here if we are blind and don't have a target in range
|
||||
|
||||
@@ -541,6 +541,9 @@ int main(int argc, char** argv) {
|
||||
if (previous_loaded && !current_loaded) {
|
||||
process_timer.Stop();
|
||||
process_timer.Start(1000, true);
|
||||
|
||||
uint32 shutdown_timer = database.getZoneShutDownDelay(zone->GetZoneID(), zone->GetInstanceVersion());
|
||||
zone->StartShutdownTimer(shutdown_timer);
|
||||
}
|
||||
else if (!previous_loaded && current_loaded) {
|
||||
process_timer.Stop();
|
||||
|
||||
+1
-15
@@ -2237,21 +2237,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
|
||||
// special ae duration spell
|
||||
ae_center->CastToBeacon()->AELocationSpell(this, spell_id, resist_adjust);
|
||||
} else {
|
||||
// regular PB AE or targeted AE spell - spell_target is null if PB
|
||||
if(spell_target) // this must be an AETarget spell
|
||||
{
|
||||
bool cast_on_target = true;
|
||||
if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && spell_target->IsPetOwnerClient())
|
||||
cast_on_target = false;
|
||||
if (spells[spell_id].targettype == ST_AreaClientOnly && !spell_target->IsClient())
|
||||
cast_on_target = false;
|
||||
if (spells[spell_id].targettype == ST_AreaNPCOnly && !spell_target->IsNPC())
|
||||
cast_on_target = false;
|
||||
|
||||
// affect the target too
|
||||
if (cast_on_target)
|
||||
SpellOnTarget(spell_id, spell_target, false, true, resist_adjust);
|
||||
}
|
||||
// unsure if we actually need this? Need to find some spell examples
|
||||
if(ae_center && ae_center == this && IsBeneficialSpell(spell_id))
|
||||
SpellOnTarget(spell_id, this);
|
||||
|
||||
|
||||
+40
-101
@@ -513,39 +513,8 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
||||
m_Position.y = new_y;
|
||||
m_Position.z = new_z;
|
||||
|
||||
uint8 NPCFlyMode = 0;
|
||||
|
||||
if (IsNPC()) {
|
||||
if (CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
|
||||
NPCFlyMode = 1;
|
||||
}
|
||||
|
||||
//fix up pathing Z
|
||||
if (!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
|
||||
{
|
||||
if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
|
||||
(zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position))))
|
||||
{
|
||||
glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);
|
||||
|
||||
float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f;
|
||||
|
||||
if ((newz > -2000) &&
|
||||
std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
|
||||
{
|
||||
if ((std::abs(x - m_Position.x) < 0.5) &&
|
||||
(std::abs(y - m_Position.y) < 0.5)) {
|
||||
if (std::abs(z - m_Position.z) <=
|
||||
RuleR(Map, FixPathingZMaxDeltaMoving))
|
||||
m_Position.z = z;
|
||||
else
|
||||
m_Position.z = newz + 1;
|
||||
}
|
||||
else
|
||||
m_Position.z = newz + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(fix_z_timer.Check())
|
||||
this->FixZ();
|
||||
|
||||
tar_ndx++;
|
||||
return true;
|
||||
@@ -651,37 +620,8 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
|
||||
m_Position.w = CalculateHeadingToTarget(x, y);
|
||||
}
|
||||
|
||||
uint8 NPCFlyMode = 0;
|
||||
|
||||
if (IsNPC()) {
|
||||
if (CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
|
||||
NPCFlyMode = 1;
|
||||
}
|
||||
|
||||
//fix up pathing Z
|
||||
if (!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) {
|
||||
|
||||
if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
|
||||
(zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position))))
|
||||
{
|
||||
glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);
|
||||
|
||||
float newz = zone->zonemap->FindBestZ(dest, nullptr);
|
||||
|
||||
if ((newz > -2000) &&
|
||||
std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
|
||||
{
|
||||
if (std::abs(x - m_Position.x) < 0.5 && std::abs(y - m_Position.y) < 0.5) {
|
||||
if (std::abs(z - m_Position.z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
|
||||
m_Position.z = z;
|
||||
else
|
||||
m_Position.z = newz + 1;
|
||||
}
|
||||
else
|
||||
m_Position.z = newz + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fix_z_timer.Check())
|
||||
this->FixZ();
|
||||
|
||||
SetMoving(true);
|
||||
moved = true;
|
||||
@@ -769,39 +709,8 @@ bool Mob::CalculateNewPosition(float x, float y, float z, int speed, bool checkZ
|
||||
Log(Logs::Detail, Logs::AI, "Next position (%.3f, %.3f, %.3f)", m_Position.x, m_Position.y, m_Position.z);
|
||||
}
|
||||
|
||||
uint8 NPCFlyMode = 0;
|
||||
|
||||
if (IsNPC()) {
|
||||
if (CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
|
||||
NPCFlyMode = 1;
|
||||
}
|
||||
|
||||
//fix up pathing Z
|
||||
if (!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
|
||||
{
|
||||
if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
|
||||
(zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position))))
|
||||
{
|
||||
glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);
|
||||
|
||||
float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f;
|
||||
|
||||
Log(Logs::Detail, Logs::AI, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz, m_Position.x, m_Position.y, m_Position.z);
|
||||
|
||||
if ((newz > -2000) &&
|
||||
std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
|
||||
{
|
||||
if (std::abs(x - m_Position.x) < 0.5 && std::abs(y - m_Position.y) < 0.5) {
|
||||
if (std::abs(z - m_Position.z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
|
||||
m_Position.z = z;
|
||||
else
|
||||
m_Position.z = newz + 1;
|
||||
}
|
||||
else
|
||||
m_Position.z = newz + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fix_z_timer.Check())
|
||||
this->FixZ();
|
||||
|
||||
//OP_MobUpdate
|
||||
if ((old_test_vector != test_vector) || tar_ndx>20) { //send update
|
||||
@@ -943,9 +852,6 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
|
||||
m_Position.y = new_y;
|
||||
m_Position.z = new_z + 0.1;
|
||||
|
||||
//fix up pathing Z, this shouldent be needed IF our waypoints
|
||||
//are corrected instead
|
||||
|
||||
if (zone->HasMap() && RuleB(Map, FixPathingZOnSendTo))
|
||||
{
|
||||
if (!RuleB(Watermap, CheckForWaterOnSendTo) || !zone->HasWaterMap() ||
|
||||
@@ -955,7 +861,7 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
|
||||
|
||||
float newz = zone->zonemap->FindBestZ(dest, nullptr);
|
||||
|
||||
Log(Logs::Detail, Logs::AI, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz, m_Position.x, m_Position.y, m_Position.z);
|
||||
Log(Logs::Moderate, Logs::Pathing, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz, m_Position.x, m_Position.y, m_Position.z);
|
||||
|
||||
if ((newz > -2000) && std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaSendTo)) // Sanity check.
|
||||
m_Position.z = newz + 1;
|
||||
@@ -963,6 +869,39 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::FixZ() {
|
||||
BenchTimer timer;
|
||||
timer.reset();
|
||||
|
||||
if (zone->HasMap() && RuleB(Map, FixZWhenMoving) && (flymode != 1 && flymode != 2))
|
||||
{
|
||||
if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
|
||||
(zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position))))
|
||||
{
|
||||
glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);
|
||||
|
||||
float new_z = zone->zonemap->FindBestZ(dest, nullptr);
|
||||
|
||||
auto duration = timer.elapsed();
|
||||
|
||||
Log(
|
||||
Logs::Moderate,
|
||||
Logs::Pathing,
|
||||
"Mob::FixZ() (%s) returned %4.3f at %4.3f, %4.3f, %4.3f - Took %lf",
|
||||
this->GetCleanName(),
|
||||
new_z,
|
||||
m_Position.x,
|
||||
m_Position.y,
|
||||
m_Position.z,
|
||||
duration
|
||||
);
|
||||
|
||||
if ((new_z > -2000) && std::abs(new_z - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving))
|
||||
m_Position.z = new_z + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ZoneDatabase::GetHighestGrid(uint32 zoneid) {
|
||||
|
||||
std::string query = StringFormat("SELECT COALESCE(MAX(id), 0) FROM grid WHERE zoneid = %i", zoneid);
|
||||
|
||||
+3
-3
@@ -1414,11 +1414,11 @@ bool Zone::HasWeather()
|
||||
|
||||
void Zone::StartShutdownTimer(uint32 set_time) {
|
||||
if (set_time > autoshutdown_timer.GetRemainingTime()) {
|
||||
if (set_time == (RuleI(Zone, AutoShutdownDelay)))
|
||||
{
|
||||
if (set_time == (RuleI(Zone, AutoShutdownDelay))) {
|
||||
set_time = database.getZoneShutDownDelay(GetZoneID(), GetInstanceVersion());
|
||||
}
|
||||
autoshutdown_timer.Start(set_time, false);
|
||||
autoshutdown_timer.SetTimer(set_time);
|
||||
Log(Logs::General, Logs::Zone_Server, "Zone::StartShutdownTimer set to %u", set_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user