aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/287_world_scripts.sql2
-rw-r--r--src/bindings/scripts/scripts/creature/mob_event_ai.cpp10
-rw-r--r--src/game/AggressorAI.cpp4
-rw-r--r--src/game/Creature.cpp10
-rw-r--r--src/game/GridNotifiers.cpp2
-rw-r--r--src/game/GridNotifiers.h3
-rw-r--r--src/game/Map.cpp60
-rw-r--r--src/game/ObjectMgr.cpp3
-rw-r--r--src/game/OutdoorPvPObjectiveAI.cpp1
-rw-r--r--src/game/Player.cpp17
-rw-r--r--src/game/ReactorAI.cpp11
-rw-r--r--src/game/Spell.cpp14
-rw-r--r--src/game/SpellAuras.cpp25
-rw-r--r--src/game/SpellEffects.cpp3
-rw-r--r--src/game/StatSystem.cpp20
-rw-r--r--src/game/Totem.cpp4
-rw-r--r--src/game/Unit.cpp17
-rw-r--r--src/game/WaypointManager.cpp68
-rw-r--r--src/game/WaypointManager.h1
-rw-r--r--src/shared/Database/DBCStructure.h4
20 files changed, 218 insertions, 61 deletions
diff --git a/sql/updates/287_world_scripts.sql b/sql/updates/287_world_scripts.sql
index 725f81b02e9..8021ee2b01e 100644
--- a/sql/updates/287_world_scripts.sql
+++ b/sql/updates/287_world_scripts.sql
@@ -1,2 +1,2 @@
-UPDATE `creature_template` SET `ScriptName` = 'npc_steam_tonk' WHERE `entry` = '19405';
+UPDATE `creature_template` SET `ScriptName` = 'npc_steam_tonk' WHERE `entry` = '19405';
UPDATE `creature_template` SET `ScriptName` = 'npc_tonk_mine' WHERE `entry` = '15368'; \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
index 289b6b925c5..657a1f41b5b 100644
--- a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
+++ b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
@@ -1038,7 +1038,15 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI
m_creature->CombatStop();
m_creature->LoadCreaturesAddon();
if( m_creature->isAlive() )
- m_creature->GetMotionMaster()->MoveTargetedHome();
+ {
+ if (Unit* owner = m_creature->GetOwner())
+ {
+ if (owner->isAlive())
+ m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
+ }
+ else
+ m_creature->GetMotionMaster()->MoveTargetedHome();
+ }
m_creature->SetLootRecipient(NULL);
diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
index 0c45fff79f4..4b090f3c799 100644
--- a/src/game/AggressorAI.cpp
+++ b/src/game/AggressorAI.cpp
@@ -98,7 +98,7 @@ void AggressorAI::EnterEvadeMode()
//i_tracker.Reset(TIME_INTERVAL_LOOK);
}
- if(!i_creature.isCharmed())
+ if(!i_creature.GetCharmerOrOwner())
{
i_creature.RemoveAllAuras();
@@ -106,6 +106,8 @@ void AggressorAI::EnterEvadeMode()
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
i_creature.GetMotionMaster()->MoveTargetedHome();
}
+ else if (i_creature.GetOwner() && i_creature.GetOwner()->isAlive())
+ i_creature.GetMotionMaster()->MoveFollow(i_creature.GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
i_creature.DeleteThreatList();
i_victimGuid = 0;
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index b2b6639148e..79c1bf18008 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -1279,8 +1279,11 @@ void Creature::SelectLevel(const CreatureInfo *cinfo)
SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, cinfo->minrangedmg * damagemod);
SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, cinfo->maxrangedmg * damagemod);
- SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, cinfo->attackpower * damagemod);
- SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, cinfo->rangedattackpower * damagemod);
+ // this value is not accurate, but should be close to the real value
+ SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, level * 5);
+ SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, level * 5);
+ //SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, cinfo->attackpower * damagemod);
+ //SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, cinfo->rangedattackpower * damagemod);
}
float Creature::_GetHealthMod(int32 Rank)
@@ -1888,7 +1891,8 @@ void Creature::CallAssistence()
for(std::list<Creature*>::iterator iter = assistList.begin(); iter != assistList.end(); ++iter)
{
- (*iter)->SetNoCallAssistence(true);
+ //(*iter)->SetNoCallAssistence(true);
+ (*iter)->CombatStart(getVictim());
if((*iter)->AI())
(*iter)->AI()->AttackStart(getVictim());
}
diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp
index 54ee2e67726..0c952f69649 100644
--- a/src/game/GridNotifiers.cpp
+++ b/src/game/GridNotifiers.cpp
@@ -190,7 +190,7 @@ Deliverer::Visit(DynamicObjectMapType &m)
{
// Send packet back to the caster if the caster has vision of dynamic object
Player* caster = (Player*)iter->getSource()->GetCaster();
- if (caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->getSource()->GetGUID() &&
+ if (caster && caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->getSource()->GetGUID() &&
(!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist))
SendPacket(caster);
}
diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
index 3561f30861c..6b4dd39306c 100644
--- a/src/game/GridNotifiers.h
+++ b/src/game/GridNotifiers.h
@@ -783,6 +783,9 @@ namespace Trinity
if(u->getFaction() != i_funit->getFaction() )
return false;
+ if(!u->isAggressive())
+ return false;
+
// only free creature
if( u->GetCharmerOrOwnerGUID() )
return false;
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index f8201f53219..246af3792fb 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -594,7 +594,7 @@ bool Map::loaded(const GridPair &p) const
return ( getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord) );
}
-void Map::UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff)
+/*void Map::UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff)
{
CellPair standing_cell(Trinity::ComputeCellPair(x, y));
@@ -635,27 +635,75 @@ void Map::UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff
}
}
}
-}
+}*/
void Map::Update(const uint32 &t_diff)
{
resetMarkedCells();
// update cells around players
- for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
+ /*for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
{
Player* plr = iter->getSource();
if(plr->IsInWorld())
UpdateActiveCells(plr->GetPositionX(), plr->GetPositionY(), t_diff);
- }
+ }*/
// update cells around active objects
// clone the active object list, because update might remove from it
std::set<WorldObject *> activeObjects(i_activeObjects);
+ for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
+ {
+ Player* plr = iter->getSource();
+ if(plr->IsInWorld())
+ activeObjects.insert(plr);
+ }
+
+ Trinity::ObjectUpdater updater(t_diff);
+ // for creature
+ TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer > grid_object_update(updater);
+ // for pets
+ TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
+
for(std::set<WorldObject *>::iterator iter = activeObjects.begin(); iter != activeObjects.end(); ++iter)
{
- if((*iter)->IsInWorld())
- UpdateActiveCells((*iter)->GetPositionX(), (*iter)->GetPositionY(), t_diff);
+ if(!(*iter)->IsInWorld())
+ continue;
+
+ CellPair standing_cell(Trinity::ComputeCellPair((*iter)->GetPositionX(), (*iter)->GetPositionY()));
+
+ // Check for correctness of standing_cell, it also avoids problems with update_cell
+ if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
+ continue;
+
+ // the overloaded operators handle range checking
+ // so ther's no need for range checking inside the loop
+ CellPair begin_cell(standing_cell), end_cell(standing_cell);
+ begin_cell << 1; begin_cell -= 1; // upper left
+ end_cell >> 1; end_cell += 1; // lower right
+
+ for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x)
+ {
+ for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y)
+ {
+ // marked cells are those that have been visited
+ // don't visit the same cell twice
+ uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
+ if(!isCellMarked(cell_id))
+ {
+ markCell(cell_id);
+ CellPair pair(x,y);
+ Cell cell(pair);
+ cell.data.Part.reserved = CENTER_DISTRICT;
+ cell.SetNoCreate();
+ CellLock<NullGuard> cell_lock(cell, pair);
+ cell_lock->Visit(cell_lock, grid_object_update, *this);
+ cell_lock->Visit(cell_lock, world_object_update, *this);
+ }
+ }
+ }
+
+ // UpdateActiveCells((*iter)->GetPositionX(), (*iter)->GetPositionY(), t_diff);
}
// Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load !
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 751a3ca4fbc..e6fc35b21a4 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -44,6 +44,7 @@
#include "InstanceSaveMgr.h"
#include "SpellAuras.h"
#include "Util.h"
+#include "WaypointManager.h"
INSTANTIATE_SINGLETON_1(ObjectMgr);
@@ -7471,6 +7472,8 @@ void ObjectMgr::LoadDbScriptStrings()
CheckScripts(sGameObjectScripts,ids);
CheckScripts(sEventScripts,ids);
+ WaypointMgr.CheckTextsExistance(ids);
+
for(std::set<int32>::const_iterator itr = ids.begin(); itr != ids.end(); ++itr)
sLog.outErrorDb( "Table `db_script_string` has unused string id %u", *itr);
}
diff --git a/src/game/OutdoorPvPObjectiveAI.cpp b/src/game/OutdoorPvPObjectiveAI.cpp
index 9c9603a7f91..e8595e791f7 100644
--- a/src/game/OutdoorPvPObjectiveAI.cpp
+++ b/src/game/OutdoorPvPObjectiveAI.cpp
@@ -28,6 +28,7 @@
OutdoorPvPObjectiveAI::OutdoorPvPObjectiveAI(Creature &c) : i_creature(c)
{
sLog.outDebug("OutdoorPvP objective AI assigned to creature guid %u", c.GetGUIDLow());
+ c.SetAggressive(true);
}
void OutdoorPvPObjectiveAI::MoveInLineOfSight(Unit *u)
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 8fe5baed6f4..1f17a75819d 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -1016,6 +1016,13 @@ void Player::Update( uint32 p_time )
CheckExploreSystem();
+ /*if(isCharmed())
+ {
+ if(Unit *charmer = GetCharmer())
+ if(charmer->GetTypeId() == TYPEID_UNIT && ((Creature*)charmer)->AI())
+ ((Creature*)charmer)->AI()->UpdateCharmedAI(this, p_time);
+ }*/
+
// Update items that have just a limited lifetime
if (now>m_Last_tick)
UpdateItemDuration(uint32(now- m_Last_tick));
@@ -5266,6 +5273,10 @@ bool Player::SetPosition(float x, float y, float z, float orientation, bool tele
x = GetPositionX();
y = GetPositionY();
z = GetPositionZ();
+
+ // group update
+ if(GetGroup() && (old_x != x || old_y != y))
+ SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION);
}
// code block for underwater state update
@@ -5273,10 +5284,6 @@ bool Player::SetPosition(float x, float y, float z, float orientation, bool tele
CheckExploreSystem();
- // group update
- if(GetGroup())
- SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION);
-
return true;
}
@@ -14285,7 +14292,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
damage = aura->GetModifier()->m_amount;
aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
AddAura(aura);
- sLog.outString("Added aura spellid %u, effect %u", spellproto->Id, effindex);
+ sLog.outDetail("Added aura spellid %u, effect %u", spellproto->Id, effindex);
}
}
while( result->NextRow() );
diff --git a/src/game/ReactorAI.cpp b/src/game/ReactorAI.cpp
index 41e5fb51f10..9d596751075 100644
--- a/src/game/ReactorAI.cpp
+++ b/src/game/ReactorAI.cpp
@@ -123,7 +123,12 @@ ReactorAI::EnterEvadeMode()
i_creature.CombatStop();
i_creature.SetLootRecipient(NULL);
- // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
- if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
- i_creature.GetMotionMaster()->MoveTargetedHome();
+ if(!i_creature.GetCharmerOrOwner())
+ {
+ // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
+ if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
+ i_creature.GetMotionMaster()->MoveTargetedHome();
+ }
+ else if (i_creature.GetOwner() && i_creature.GetOwner()->isAlive())
+ i_creature.GetMotionMaster()->MoveFollow(i_creature.GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
}
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 0c1f25964a9..5cdbef26eed 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -715,7 +715,8 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
if(m_originalCaster)
target.missCondition = m_originalCaster->SpellHitResult(pVictim, m_spellInfo, m_canReflect);
else
- target.missCondition = SPELL_MISS_NONE;
+ target.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
+
if (target.missCondition == SPELL_MISS_NONE)
++m_countOfHit;
else
@@ -928,6 +929,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
return;
SpellMissInfo missInfo = target->missCondition;
+
// Need init unitTarget by default unit (can changed in code on reflect)
// Or on missInfo!=SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
unitTarget = unit;
@@ -939,6 +941,16 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if (target->reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
DoSpellHitOnUnit(m_caster, mask);
}
+ else //TODO: This is a hack. need fix
+ {
+ uint32 tempMask = 0;
+ for(uint32 i = 0; i < 3; ++i)
+ if(m_spellInfo->Effect[i] == SPELL_EFFECT_DUMMY
+ || m_spellInfo->Effect[i] == SPELL_EFFECT_TRIGGER_SPELL)
+ tempMask |= 1<<i;
+ if(tempMask &= mask)
+ DoSpellHitOnUnit(unit, tempMask);
+ }
// Do triggers only on miss/resist/parry/dodge
if (missInfo!=SPELL_MISS_NONE)
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 874b9236fc1..46842bc3ced 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -3147,18 +3147,23 @@ void Aura::HandleAuraModDisarm(bool apply, bool Real)
else
m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
- // only at real add/remove aura
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // main-hand attack speed already set to special value for feral form already and don't must change and reset at remove.
- if (((Player *)m_target)->IsInFeralForm())
- return;
+ if (m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ // main-hand attack speed already set to special value for feral form already and don't must change and reset at remove.
+ if (((Player *)m_target)->IsInFeralForm())
+ return;
- if (apply)
- m_target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME);
+ if (apply)
+ m_target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME);
+ else
+ ((Player *)m_target)->SetRegularAttackTime();
+ }
else
- ((Player *)m_target)->SetRegularAttackTime();
+ {
+ // creature does not have equipment
+ if(apply && !((Creature*)m_target)->GetCurrentEquipmentId())
+ return;
+ }
m_target->UpdateDamagePhysical(BASE_ATTACK);
}
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 6984fc5789c..56d8c415503 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -1871,6 +1871,7 @@ void Spell::EffectTriggerSpell(uint32 i)
// Cloak of Shadows
case 35729 :
{
+ m_caster->RemoveAurasWithDispelType(DISPEL_ALL);
Unit::AuraMap& Auras = m_caster->GetAuras();
for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter)
{
@@ -2187,7 +2188,7 @@ void Spell::EffectApplyAura(uint32 i)
// Prayer of Mending (jump animation), we need formal caster instead original for correct animation
if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & 0x00002000000000LL))
- m_caster->CastSpell(unitTarget,41637,true,NULL,Aur);
+ m_caster->CastSpell(unitTarget,41637,true,NULL,Aur,m_originalCasterGUID);
}
void Spell::EffectUnlearnSpecialization( uint32 i )
diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp
index 3533c5c8a02..64bad232994 100644
--- a/src/game/StatSystem.cpp
+++ b/src/game/StatSystem.cpp
@@ -737,15 +737,27 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
break;
}
- float att_speed = float(GetAttackTime(attType))/1000.0f;
+ //float att_speed = float(GetAttackTime(attType))/1000.0f;
- float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed;
+ float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE);
+ float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE);
+
+ //This formula is not correct
+ //The correct one is (Damage_from_AttackPower + Base_Weapon_Damage) * Multiplier
+ //We do not know the multiplier, so we assume attack power is about 25% damage
+ //float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed;
+ float base_value = GetModifierValue(unitMod, BASE_VALUE)
+ + (weapon_mindamage + weapon_maxdamage) / 6
+ / GetTotalAttackPowerValue(attType) * getLevel() * 5;
float base_pct = GetModifierValue(unitMod, BASE_PCT);
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
- float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE);
- float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE);
+ if(attType == BASE_ATTACK && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED))
+ {
+ weapon_mindamage = 0;
+ weapon_maxdamage = 0;
+ }
float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct ;
float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct ;
diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp
index 73ae274644e..26c471d441a 100644
--- a/src/game/Totem.cpp
+++ b/src/game/Totem.cpp
@@ -181,7 +181,7 @@ void Totem::SetTypeBySummonSpell(SpellEntry const * spellProto)
bool Totem::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
{
- for (int i=0;i<3;i++)
+/* for (int i=0;i<3;i++)
{
switch(spellInfo->EffectApplyAuraName[i])
{
@@ -191,6 +191,6 @@ bool Totem::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
default:
continue;
}
- }
+ }*/
return Creature::IsImmunedToSpell(spellInfo, useCharges);
}
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index e4a83c88093..642b49ee99a 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -1475,7 +1475,7 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage
GetGUIDLow(), GetTypeId(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damage, spellID, absorb,resist);
// Actual log sent to client
- SendSpellNonMeleeDamageLog(pVictim, spellID, damage, GetSpellSchoolMask(spellInfo), absorb, resist, false, 0, crit);
+ SendSpellNonMeleeDamageLog(pVictim, spellID, damage + resist, GetSpellSchoolMask(spellInfo), absorb, resist, false, 0, crit);
// Procflags
uint32 procAttacker = PROC_FLAG_HIT_SPELL;
@@ -8486,10 +8486,16 @@ void Unit::CombatStart(Unit* target)
if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER
&& ((Creature*)target)->isAggressive() && ((Creature*)target)->AI())
+ {
+ SetInCombatWith(target);
+ target->SetInCombatWith(this);
((Creature*)target)->AI()->AttackStart(this);
-
- SetInCombatWith(target);
- target->SetInCombatWith(this);
+ }
+ else
+ {
+ SetInCombatWith(target);
+ target->SetInCombatWith(this);
+ }
if(Player* attackedPlayer = target->GetCharmerOrOwnerPlayerOrPlayerItself())
SetContestedPvP(attackedPlayer);
@@ -9622,6 +9628,9 @@ void Unit::SetMaxHealth(uint32 val)
void Unit::SetPower(Powers power, uint32 val)
{
+ if(GetPower(power) == val)
+ return;
+
uint32 maxPower = GetMaxPower(power);
if(maxPower < val)
val = maxPower;
diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp
index a6dda2477ff..831f616060b 100644
--- a/src/game/WaypointManager.cpp
+++ b/src/game/WaypointManager.cpp
@@ -124,32 +124,18 @@ void WaypointManager::Load()
be.emote = fields[7].GetUInt32();
be.spell = fields[8].GetUInt32();
- // load and store without holes in array
- int j = 0;
for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
{
- be.textid[j] = fields[9+i].GetUInt32();
- if(be.textid[j])
+ be.textid[i] = fields[9+i].GetUInt32();
+ if(be.textid[i])
{
- if (be.textid[j] < MIN_DB_SCRIPT_STRING_ID || be.textid[j] >= MAX_DB_SCRIPT_STRING_ID)
+ if (be.textid[i] < MIN_DB_SCRIPT_STRING_ID || be.textid[i] >= MAX_DB_SCRIPT_STRING_ID)
{
- sLog.outErrorDb( "Table `db_script_string` not have string id %u", be.textid[j]);
+ sLog.outErrorDb( "Table `db_script_string` not have string id %u", be.textid[i]);
continue;
}
-
- if (!objmgr.GetTrinityStringLocale (be.textid[j]))
- {
- sLog.outErrorDb("ERROR: Waypoint path %d (point %d), have invalid text id (%i) in `textid%d, ignored.",
- id, point, be.textid[j], i+1);
- continue;
- }
-
- ++j; // to next internal field
}
}
- // fill array tail
- for(; j < MAX_WAYPOINT_TEXT; ++j)
- be.textid[j] = 0;
// save memory by not storing empty behaviors
if(!be.isEmpty())
@@ -308,3 +294,49 @@ void WaypointManager::SetNodeText(uint32 id, uint32 point, const char *text_fiel
if(field == "model2") node.behavior->model2 = text ? atoi(text) : 0;
}
}
+
+void WaypointManager::CheckTextsExistance(std::set<int32>& ids)
+{
+ WaypointPathMap::iterator pmItr = m_pathMap.begin();
+ for ( ; pmItr != m_pathMap.end(); ++pmItr)
+ {
+ for (int i = 0; i < pmItr->second.size(); ++i)
+ {
+ if (!pmItr->second[i].behavior)
+ continue;
+
+ // Now we check text existence and put all zero texts ids to the end of array
+
+ // Counting leading zeros for futher textid shift
+ int zeroCount = 0;
+ for (int j = 0; j < MAX_WAYPOINT_TEXT; ++j)
+ {
+ if (!pmItr->second[i].behavior->textid[j])
+ {
+ ++zeroCount;
+ continue;
+ }
+ else
+ {
+ if (!objmgr.GetTrinityStringLocale(pmItr->second[i].behavior->textid[j]))
+ {
+ sLog.outErrorDb("ERROR: Some waypoint has textid%u with not existing %u text.", j, pmItr->second[i].behavior->textid[j]);
+ pmItr->second[i].behavior->textid[j] = 0;
+ ++zeroCount;
+ continue;
+ }
+ else
+ ids.erase(pmItr->second[i].behavior->textid[j]);
+
+ // Shifting check
+ if (zeroCount)
+ {
+ // Correct textid but some zeros leading, so move it forward.
+ pmItr->second[i].behavior->textid[j-zeroCount] = pmItr->second[i].behavior->textid[j];
+ pmItr->second[i].behavior->textid[j] = 0;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/game/WaypointManager.h b/src/game/WaypointManager.h
index 75f01cc82f3..38cf5551d64 100644
--- a/src/game/WaypointManager.h
+++ b/src/game/WaypointManager.h
@@ -78,6 +78,7 @@ class WaypointManager
void DeletePath(uint32 id);
void SetNodePosition(uint32 id, uint32 point, float x, float y, float z);
void SetNodeText(uint32 id, uint32 point, const char *text_field, const char *text);
+ void CheckTextsExistance(std::set<int32>& ids);
private:
void _addNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h
index a71f80ac8c7..ce72661066b 100644
--- a/src/shared/Database/DBCStructure.h
+++ b/src/shared/Database/DBCStructure.h
@@ -229,6 +229,8 @@ struct FactionTemplateEntry
// helpers
bool IsFriendlyTo(FactionTemplateEntry const& entry) const
{
+ if(ID == entry.ID)
+ return true;
if(enemyFaction1 == entry.faction || enemyFaction2 == entry.faction || enemyFaction3 == entry.faction || enemyFaction4 == entry.faction )
return false;
if(friendFaction1 == entry.faction || friendFaction2 == entry.faction || friendFaction3 == entry.faction || friendFaction4 == entry.faction )
@@ -237,6 +239,8 @@ struct FactionTemplateEntry
}
bool IsHostileTo(FactionTemplateEntry const& entry) const
{
+ if(ID == entry.ID)
+ return false;
if(enemyFaction1 == entry.faction || enemyFaction2 == entry.faction || enemyFaction3 == entry.faction || enemyFaction4 == entry.faction )
return true;
if(friendFaction1 == entry.faction || friendFaction2 == entry.faction || friendFaction3 == entry.faction || friendFaction4 == entry.faction )