aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/Group.cpp18
-rw-r--r--src/game/GroupHandler.cpp15
-rw-r--r--src/game/Guild.cpp19
-rw-r--r--src/game/Map.cpp20
-rw-r--r--src/game/Object.cpp41
-rw-r--r--src/game/Object.h15
-rw-r--r--src/game/Unit.cpp463
-rw-r--r--src/game/WorldSession.cpp9
8 files changed, 95 insertions, 505 deletions
diff --git a/src/game/Group.cpp b/src/game/Group.cpp
index f0a9ce5add8..535a3d4392c 100644
--- a/src/game/Group.cpp
+++ b/src/game/Group.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
@@ -74,6 +74,8 @@ Group::~Group()
for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
itr->second.save->RemoveGroup(this);
+
+ // Sub group counters clean up
if (m_subGroupsCounts)
delete[] m_subGroupsCounts;
}
@@ -302,8 +304,7 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
{
bool leaderChanged = _removeMember(guid);
- Player *player = objmgr.GetPlayer( guid ); // FG: TODO: could be removed, its just here for consistency
- if (player)
+ if(Player *player = objmgr.GetPlayer( guid ))
{
WorldPacket data;
@@ -1048,6 +1049,7 @@ bool Group::_removeMember(const uint64 &guid)
if (slot != m_memberSlots.end())
{
SubGroupCounterDecrease(slot->group);
+
m_memberSlots.erase(slot);
}
@@ -1207,6 +1209,7 @@ void Group::ChangeMembersGroup(const uint64 &guid, const uint8 &group)
if(!isRaidGroup())
return;
Player *player = objmgr.GetPlayer(guid);
+
if (!player)
{
uint8 prevSubGroup;
@@ -1218,6 +1221,7 @@ void Group::ChangeMembersGroup(const uint64 &guid, const uint8 &group)
SendUpdate();
}
else
+ // This methods handles itself groupcounter decrease
ChangeMembersGroup(player, group);
}
@@ -1366,7 +1370,7 @@ uint32 Group::CanJoinBattleGroundQueue(uint32 bgTypeId, uint32 bgQueueType, uint
void Roll::targetObjectBuildLink()
{
// called from link()
- this->getTarget()->addLootValidatorRef(this);
+ getTarget()->addLootValidatorRef(this);
}
void Group::SetDifficulty(uint8 difficulty)
diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
index f35c60aa81c..f63505ae24a 100644
--- a/src/game/GroupHandler.cpp
+++ b/src/game/GroupHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -124,7 +124,6 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER);
return;
}
-
// not have place
if(group->IsFull())
{
@@ -203,7 +202,8 @@ void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ )
// forming a new group, create it
if(!group->IsCreated())
{
- if(leader) group->RemoveInvite(leader);
+ if( leader )
+ group->RemoveInvite(leader);
group->Create(group->GetLeaderGUID(), group->GetLeaderName());
objmgr.AddGroup(group);
}
@@ -533,6 +533,7 @@ void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,1+1);
+ // we will get correct pointer for group here, so we don't have to check if group is BG raid
Group *group = GetPlayer()->GetGroup();
if(!group)
return;
@@ -725,9 +726,6 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
uint32 updatedAura=player->GetUInt32Value(uint16(UNIT_FIELD_AURA + i));
*data << uint16(updatedAura);
*data << uint8(1);
- //TODO: find a safe place to do this cleanup
- //if(!updatedAura)
- //player->UnsetAuraUpdateMask(i);
}
}
}
@@ -810,9 +808,6 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
uint32 updatedAura=pet->GetUInt32Value(uint16(UNIT_FIELD_AURA + i));
*data << uint16(updatedAura);
*data << uint8(1);
- //TODO: find a safe place to do this cleanup
- //if(!updatedAura)
- //pet->UnsetAuraUpdateMask(i);
}
}
}
diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp
index ec14ca04192..56d82c1a313 100644
--- a/src/game/Guild.cpp
+++ b/src/game/Guild.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1212,18 +1212,19 @@ void Guild::LoadGuildBankFromDB()
delete result;
- // 0 1 2 3
- result = CharacterDatabase.PQuery("SELECT TabId, SlotId, item_guid, item_entry FROM guild_bank_item WHERE guildid='%u' ORDER BY TabId", Id);
+ // data needs to be at first place for Item::LoadFromDB
+ // 0 1 2 3 4
+ result = CharacterDatabase.PQuery("SELECT data, TabId, SlotId, item_guid, item_entry FROM guild_bank_item JOIN item_instance ON item_guid = guid WHERE guildid='%u' ORDER BY TabId", Id);
if(!result)
return;
do
{
Field *fields = result->Fetch();
- uint8 TabId = fields[0].GetUInt8();
- uint8 SlotId = fields[1].GetUInt8();
- uint32 ItemGuid = fields[2].GetUInt32();
- uint32 ItemEntry = fields[3].GetUInt32();
+ uint8 TabId = fields[1].GetUInt8();
+ uint8 SlotId = fields[2].GetUInt8();
+ uint32 ItemGuid = fields[3].GetUInt32();
+ uint32 ItemEntry = fields[4].GetUInt32();
if (TabId >= purchased_tabs || TabId >= GUILD_BANK_MAX_TABS)
{
@@ -1246,7 +1247,7 @@ void Guild::LoadGuildBankFromDB()
}
Item *pItem = NewItemOrBag(proto);
- if(!pItem->LoadFromDB(ItemGuid, 0))
+ if(!pItem->LoadFromDB(ItemGuid, 0, result))
{
CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'", Id, uint32(TabId), uint32(SlotId));
sLog.outError("Item GUID %u not found in item_instance, deleting from Guild Bank!", ItemGuid);
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 20e5dd70ebc..a3c76c59921 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -628,8 +628,8 @@ void Map::RelocationNotify()
if(unit->m_Notified || !unit->IsInWorld() || unit->GetMapId() != GetId())
continue;
- unit->m_IsInNotifyList = false;
unit->m_Notified = true;
+ unit->m_IsInNotifyList = false;
if(unit->GetTypeId() == TYPEID_PLAYER)
{
@@ -1480,8 +1480,8 @@ bool Map::CheckGridIntegrity(Creature* c, bool moved) const
Cell xy_cell(xy_val);
if(xy_cell != cur_cell)
{
- sLog.outDebug("ERROR: %s (GUID: %u) X: %f Y: %f (%s) in grid[%u,%u]cell[%u,%u] instead grid[%u,%u]cell[%u,%u]",
- (c->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature"),c->GetGUIDLow(),
+ sLog.outDebug("Creature (GUIDLow: %u) X: %f Y: %f (%s) in grid[%u,%u]cell[%u,%u] instead grid[%u,%u]cell[%u,%u]",
+ c->GetGUIDLow(),
c->GetPositionX(),c->GetPositionY(),(moved ? "final" : "original"),
cur_cell.GridX(), cur_cell.GridY(), cur_cell.CellX(), cur_cell.CellY(),
xy_cell.GridX(), xy_cell.GridY(), xy_cell.CellX(), xy_cell.CellY());
@@ -2188,12 +2188,14 @@ void BattleGroundMap::UnloadAll()
{
while(HavePlayers())
{
- Player * plr = m_mapRefManager.getFirst()->getSource();
- if(plr) (plr)->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation());
- // TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator.
- // just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop
- // note that this remove is not needed if the code works well in other places
- plr->GetMapRef().unlink();
+ if(Player * plr = m_mapRefManager.getFirst()->getSource())
+ {
+ plr->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation());
+ // TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator.
+ // just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop
+ // note that this remove is not needed if the code works well in other places
+ plr->GetMapRef().unlink();
+ }
}
Map::UnloadAll();
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index c0196c5a350..4159f05d4b8 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -80,8 +80,8 @@ Object::Object( )
Object::~Object( )
{
- if(m_objectUpdated)
- ObjectAccessor::Instance().RemoveUpdateObject(this);
+ //if(m_objectUpdated)
+ // ObjectAccessor::Instance().RemoveUpdateObject(this);
if(m_uint32Values)
{
@@ -89,9 +89,11 @@ Object::~Object( )
{
///- Do NOT call RemoveFromWorld here, if the object is a player it will crash
sLog.outError("Object::~Object - guid="I64FMTD", typeid=%d deleted but still in world!!", GetGUID(), GetTypeId());
- //assert(0);
+ assert(false);
}
+ assert(!m_objectUpdated);
+
//DEBUG_LOG("Object desctr 1 check (%p)",(void*)this);
delete [] m_uint32Values;
delete [] m_uint32Values_mirror;
@@ -146,14 +148,8 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
/** lower flag1 **/
if(target == this) // building packet for oneself
- {
flags |= UPDATEFLAG_SELF;
- /*** temporary reverted - until real source of stack corruption will not found
- updatetype = UPDATETYPE_CREATE_OBJECT2;
- ****/
- }
-
if(flags & UPDATEFLAG_HASPOSITION)
{
// UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses...
@@ -571,7 +567,6 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
if( updateMask->GetBit( index ) )
{
// remove custom flag before send
-
if( index == UNIT_NPC_FLAGS )
*data << uint32(m_uint32Values[ index ] & ~(UNIT_NPC_FLAG_GUARD + UNIT_NPC_FLAG_OUTDOORPVP));
// FIXME: Some values at server stored in float format but must be sent to client in uint32 format
@@ -1046,7 +1041,7 @@ void Object::RemoveByteFlag( uint16 index, uint8 offset, uint8 oldFlag )
bool Object::PrintIndexError(uint32 index, bool set) const
{
- sLog.outError("ERROR: Attempt %s non-existed value field: %u (count: %u) for object typeid: %u type mask: %u",(set ? "set value to" : "get value from"),index,m_valuesCount,GetTypeId(),m_objectType);
+ sLog.outError("Attempt %s non-existed value field: %u (count: %u) for object typeid: %u type mask: %u",(set ? "set value to" : "get value from"),index,m_valuesCount,GetTypeId(),m_objectType);
// assert must fail after function call
return false;
@@ -1130,7 +1125,7 @@ uint32 WorldObject::GetAreaId() const
InstanceData* WorldObject::GetInstanceData()
{
- Map *map = MapManager::Instance().GetMap(m_mapId, this);
+ Map *map = GetMap();
return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceData() : NULL;
}
@@ -1242,6 +1237,10 @@ float WorldObject::GetAngle( const float x, const float y ) const
bool WorldObject::HasInArc(const float arcangle, const WorldObject* obj) const
{
+ // always have self in arc
+ if(obj == this)
+ return true;
+
float arc = arcangle;
// move arc to range 0.. 2*pi
@@ -1346,13 +1345,13 @@ void Object::ForceValuesUpdateAtIndex(uint32 i)
{
m_uint32Values_mirror[i] = GetUInt32Value(i) + 1; // makes server think the field changed
if(m_inWorld)
- {
+ {
if(!m_objectUpdated)
- {
+ {
ObjectAccessor::Instance().AddUpdateObject(this);
m_objectUpdated = true;
- }
}
+ }
}
namespace Trinity
@@ -1733,18 +1732,20 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float
{
if(!IsInWorld())
return NULL;
- Map * map = GetMap();
- if(!map)
- return NULL;
+
GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry);
if(!goinfo)
{
sLog.outErrorDb("Gameobject template %u not found in database!", entry);
return NULL;
}
+ Map *map = GetMap();
GameObject *go = new GameObject();
if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry,map,x,y,z,ang,rotation0,rotation1,rotation2,rotation3,100,1))
+ {
+ delete go;
return NULL;
+ }
go->SetRespawnTime(respawnTime);
if(GetTypeId()==TYPEID_PLAYER || GetTypeId()==TYPEID_UNIT) //not sure how to handle this
((Unit*)this)->AddGameObject(go);
diff --git a/src/game/Object.h b/src/game/Object.h
index ef8a04c5c09..ecba2a77f65 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -123,6 +123,8 @@ class TRINITY_DLL_SPEC Object
if(m_inWorld)
return;
+ assert(m_uint32Values);
+
m_inWorld = true;
// synchronize values mirror with values array (changes will send in updatecreate opcode any way
@@ -133,10 +135,10 @@ class TRINITY_DLL_SPEC Object
if(!m_inWorld)
return;
- // if we remove from world then sending changes not required
- if(m_uint32Values)
- ClearUpdateMask(true);
m_inWorld = false;
+
+ // if we remove from world then sending changes not required
+ ClearUpdateMask(true);
}
const uint64& GetGUID() const { return GetUInt64Value(0); }
@@ -300,8 +302,6 @@ class TRINITY_DLL_SPEC Object
uint16 GetValuesCount() const { return m_valuesCount; }
- void InitValues() { _InitValues(); }
-
virtual bool hasQuest(uint32 /* quest_id */) const { return false; }
virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; }
@@ -419,7 +419,6 @@ class TRINITY_DLL_SPEC WorldObject : public Object
void GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z ) const;
void SetMapId(uint32 newMap) { m_mapId = newMap; }
-
uint32 GetMapId() const { return m_mapId; }
uint32 GetZoneId() const;
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 50a8748329d..7f5f943279b 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -197,9 +197,9 @@ Unit::Unit()
m_ShapeShiftFormSpellId = 0;
m_canModifyStats = false;
- for (int i = 0; i < MAX_SPELL_IMMUNITY; i++)
+ for (int i = 0; i < MAX_SPELL_IMMUNITY; ++i)
m_spellImmune[i].clear();
- for (int i = 0; i < UNIT_MOD_END; i++)
+ for (int i = 0; i < UNIT_MOD_END; ++i)
{
m_auraModifiersGroup[i][BASE_VALUE] = 0.0f;
m_auraModifiersGroup[i][BASE_PCT] = 1.0f;
@@ -214,7 +214,7 @@ Unit::Unit()
m_weaponDamage[i][MINDAMAGE] = BASE_MINDAMAGE;
m_weaponDamage[i][MAXDAMAGE] = BASE_MAXDAMAGE;
}
- for (int i = 0; i < MAX_STATS; i++)
+ for (int i = 0; i < MAX_STATS; ++i)
m_createStats[i] = 0.0f;
m_attacking = NULL;
@@ -260,6 +260,10 @@ Unit::~Unit()
RemoveAllDynObjects();
if(m_charmInfo) delete m_charmInfo;
+
+ assert(!m_attacking);
+ assert(m_attackers.empty());
+ assert(m_sharedVision.empty());
}
void Unit::Update( uint32 p_time )
@@ -1109,419 +1113,6 @@ void Unit::CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castI
spell->prepare(&targets, triggeredByAura);
}
-/*
-void Unit::DealFlatDamage(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit, bool isTriggeredSpell)
-{
- // TODO this in only generic way, check for exceptions
- DEBUG_LOG("DealFlatDamage (BEFORE) >> DMG:%u", *damage);
-
- // Per-damage class calculation
- switch (spellInfo->DmgClass)
- {
- // Melee and Ranged Spells
- case SPELL_DAMAGE_CLASS_RANGED:
- case SPELL_DAMAGE_CLASS_MELEE:
- {
- // Calculate physical outcome
- MeleeHitOutcome outcome = RollPhysicalOutcomeAgainst(pVictim, BASE_ATTACK, spellInfo);
-
- //Used to store the Hit Outcome
- cleanDamage->hitOutCome = outcome;
-
- // Return miss/evade first (sends miss message)
- switch(outcome)
- {
- case MELEE_HIT_EVADE:
- {
- SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, GetSpellSchoolMask(spellInfo), 0, 0,0,VICTIMSTATE_EVADES,0);
- *damage = 0;
- return;
- }
- case MELEE_HIT_MISS:
- {
- SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, GetSpellSchoolMask(spellInfo), 0, 0,0,VICTIMSTATE_NORMAL,0);
- *damage = 0;
-
- if(GetTypeId()== TYPEID_PLAYER)
- ((Player*)this)->UpdateWeaponSkill(BASE_ATTACK);
-
- CastMeleeProcDamageAndSpell(pVictim,0,GetSpellSchoolMask(spellInfo),BASE_ATTACK,MELEE_HIT_MISS,spellInfo,isTriggeredSpell);
- return;
- }
- }
-
- // Hitinfo, Victimstate
- uint32 hitInfo = HITINFO_NORMALSWING;
- VictimState victimState = VICTIMSTATE_NORMAL;
-
- // Physical Damage
- if ( GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NORMAL )
- {
- // apply spellmod to Done damage
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_DAMAGE, *damage);
-
- //Calculate armor mitigation
- uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage);
-
- // random durability for main hand weapon (ABSORB)
- if(damageAfterArmor < *damage)
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_ABSORB)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EquipmentSlots(urand(EQUIPMENT_SLOT_START,EQUIPMENT_SLOT_BACK)));
-
- cleanDamage->damage += *damage - damageAfterArmor;
- *damage = damageAfterArmor;
- }
- // Magical Damage
- else
- {
- // Calculate damage bonus
- *damage = SpellDamageBonus(pVictim, spellInfo, *damage, SPELL_DIRECT_DAMAGE);
- }
-
- // Classify outcome
- switch (outcome)
- {
- case MELEE_HIT_BLOCK_CRIT:
- case MELEE_HIT_CRIT:
- {
- uint32 bonusDmg = *damage;
-
- // Apply crit_damage bonus
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, bonusDmg);
-
- uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
- AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS);
- for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- bonusDmg = uint32(bonusDmg * ((*i)->GetModifierValue()+100.0f)/100.0f);
-
- *damage += bonusDmg;
-
- // Resilience - reduce crit damage
- if (pVictim->GetTypeId()==TYPEID_PLAYER)
- {
- uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);
- cleanDamage->damage += resilienceReduction;
- *damage -= resilienceReduction;
- }
-
- *crit = true;
- hitInfo |= HITINFO_CRITICALHIT;
-
- ModifyAuraState(AURA_STATE_CRIT, true);
- StartReactiveTimer( REACTIVE_CRIT );
-
- if(getClass()==CLASS_HUNTER)
- {
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
- StartReactiveTimer( REACTIVE_HUNTER_CRIT );
- }
-
- if ( outcome == MELEE_HIT_BLOCK_CRIT )
- {
- uint32 blocked_amount = uint32(pVictim->GetShieldBlockValue());
- if (blocked_amount >= *damage)
- {
- hitInfo |= HITINFO_SWINGNOHITSOUND;
- victimState = VICTIMSTATE_BLOCKS;
- cleanDamage->damage += *damage; // To Help Calculate Rage
- *damage = 0;
- }
- else
- {
- // To Help Calculate Rage
- cleanDamage->damage += blocked_amount;
- *damage = *damage - blocked_amount;
- }
-
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update defense
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (BLOCK)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND);
- }
- }
- break;
- }
- case MELEE_HIT_PARRY:
- {
- cleanDamage->damage += *damage; // To Help Calculate Rage
- *damage = 0;
- victimState = VICTIMSTATE_PARRY;
-
- // Counter-attack ( explained in Unit::DoAttackDamage() )
- if(pVictim->GetTypeId()==TYPEID_PLAYER || !(((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN) )
- {
- // Get attack timers
- float offtime = float(pVictim->getAttackTimer(OFF_ATTACK));
- float basetime = float(pVictim->getAttackTimer(BASE_ATTACK));
-
- // Reduce attack time
- if (pVictim->haveOffhandWeapon() && offtime < basetime)
- {
- float percent20 = pVictim->GetAttackTime(OFF_ATTACK) * 0.20;
- float percent60 = 3 * percent20;
- if(offtime > percent20 && offtime <= percent60)
- {
- pVictim->setAttackTimer(OFF_ATTACK, uint32(percent20));
- }
- else if(offtime > percent60)
- {
- offtime -= 2 * percent20;
- pVictim->setAttackTimer(OFF_ATTACK, uint32(offtime));
- }
- }
- else
- {
- float percent20 = pVictim->GetAttackTime(BASE_ATTACK) * 0.20;
- float percent60 = 3 * percent20;
- if(basetime > percent20 && basetime <= percent60)
- {
- pVictim->setAttackTimer(BASE_ATTACK, uint32(percent20));
- }
- else if(basetime > percent60)
- {
- basetime -= 2 * percent20;
- pVictim->setAttackTimer(BASE_ATTACK, uint32(basetime));
- }
- }
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update victim defense ?
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (PARRY)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_PARRY)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_MAINHAND);
- }
-
- // Set parry flags
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- // Mongoose bite - set only Counterattack here
- if (pVictim->getClass() == CLASS_HUNTER)
- {
- pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
- pVictim->StartReactiveTimer( REACTIVE_HUNTER_PARRY );
- }
- else
- {
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
- }
- break;
- }
- case MELEE_HIT_DODGE:
- {
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- ((Player*)pVictim)->UpdateDefense();
-
- cleanDamage->damage += *damage; // To Help Calculate Rage
- *damage = 0;
- hitInfo |= HITINFO_SWINGNOHITSOUND;
- victimState = VICTIMSTATE_DODGE;
-
- // Set dodge flags
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- // Overpower
- if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
- {
- ((Player*)this)->AddComboPoints(pVictim, 1);
- StartReactiveTimer( REACTIVE_OVERPOWER );
- }
-
- // Riposte
- if (pVictim->getClass() != CLASS_ROGUE)
- {
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
- }
- break;
- }
- case MELEE_HIT_BLOCK:
- {
- uint32 blocked_amount = uint32(pVictim->GetShieldBlockValue());
- if (blocked_amount >= *damage)
- {
- hitInfo |= HITINFO_SWINGNOHITSOUND;
- victimState = VICTIMSTATE_BLOCKS;
- cleanDamage->damage += *damage; // To Help Calculate Rage
- *damage = 0;
- }
- else
- {
- // To Help Calculate Rage
- cleanDamage->damage += blocked_amount;
- *damage = *damage - blocked_amount;
- }
-
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update defense
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (BLOCK)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND);
- }
- break;
- }
- case MELEE_HIT_EVADE: // already processed early
- case MELEE_HIT_MISS: // already processed early
- case MELEE_HIT_GLANCING:
- case MELEE_HIT_CRUSHING:
- case MELEE_HIT_NORMAL:
- break;
- }
-
- // do all damage=0 cases here
- if(*damage == 0)
- CastMeleeProcDamageAndSpell(pVictim,0,GetSpellSchoolMask(spellInfo),BASE_ATTACK,outcome,spellInfo,isTriggeredSpell);
-
- break;
- }
- // Magical Attacks
- case SPELL_DAMAGE_CLASS_NONE:
- case SPELL_DAMAGE_CLASS_MAGIC:
- {
- // Calculate damage bonus
- *damage = SpellDamageBonus(pVictim, spellInfo, *damage, SPELL_DIRECT_DAMAGE);
-
- *crit = isSpellCrit(pVictim, spellInfo, GetSpellSchoolMask(spellInfo), BASE_ATTACK);
- if (*crit)
- {
- *damage = SpellCriticalBonus(spellInfo, *damage, pVictim);
-
- // Resilience - reduce crit damage
- if (pVictim && pVictim->GetTypeId()==TYPEID_PLAYER)
- {
- uint32 damage_reduction = ((Player *)pVictim)->GetSpellCritDamageReduction(*damage);
- if(*damage > damage_reduction)
- *damage -= damage_reduction;
- else
- *damage = 0;
- }
-
- cleanDamage->hitOutCome = MELEE_HIT_CRIT;
- }
- // spell proc all magic damage==0 case in this function
- if(*damage == 0)
- {
- // Procflags
- uint32 procAttacker = PROC_FLAG_HIT_SPELL;
- uint32 procVictim = (PROC_FLAG_STRUCK_SPELL|PROC_FLAG_TAKE_DAMAGE);
-
- ProcDamageAndSpell(pVictim, procAttacker, procVictim, 0, GetSpellSchoolMask(spellInfo), spellInfo, isTriggeredSpell);
- }
-
- break;
- }
- }
-
- // TODO this in only generic way, check for exceptions
- DEBUG_LOG("DealFlatDamage (AFTER) >> DMG:%u", *damage);
-}
-
-uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell, bool useSpellDamage)
-{
- if(!this || !pVictim)
- return 0;
- if(!isAlive() || !pVictim->isAlive())
- return 0;
-
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID);
- if(!spellInfo)
- return 0;
-
- CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL);
- bool crit = false;
-
- if (useSpellDamage)
- DealFlatDamage(pVictim, spellInfo, &damage, &cleanDamage, &crit, isTriggeredSpell);
-
- // If we actually dealt some damage (spell proc's for 0 damage (normal and magic) called in DealFlatDamage)
- if(damage > 0)
- {
- // Calculate absorb & resists
- uint32 absorb = 0;
- uint32 resist = 0;
-
- CalcAbsorbResist(pVictim,GetSpellSchoolMask(spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
-
- //No more damage left, target absorbed and/or resisted all damage
- if (damage > absorb + resist)
- damage -= absorb + resist; //Remove Absorbed and Resisted from damage actually dealt
- else
- {
- uint32 HitInfo = HITINFO_SWINGNOHITSOUND;
-
- if (absorb)
- HitInfo |= HITINFO_ABSORB;
- if (resist)
- {
- HitInfo |= HITINFO_RESIST;
- ProcDamageAndSpell(pVictim, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SPELL, 0, GetSpellSchoolMask(spellInfo), spellInfo,isTriggeredSpell);
- }
-
- //Send resist
- SendAttackStateUpdate(HitInfo, pVictim, 1, GetSpellSchoolMask(spellInfo), damage, absorb,resist,VICTIMSTATE_NORMAL,0);
- return 0;
- }
-
- // Deal damage done
- damage = DealDamage(pVictim, damage, &cleanDamage, SPELL_DIRECT_DAMAGE, GetSpellSchoolMask(spellInfo), spellInfo, true);
-
- // Send damage log
- sLog.outDetail("SpellNonMeleeDamageLog: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u,absorb is %u,resist is %u",
- GetGUIDLow(), GetTypeId(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damage, spellID, absorb,resist);
-
- // Actual log sent to client
- SendSpellNonMeleeDamageLog(pVictim, spellID, damage + resist, GetSpellSchoolMask(spellInfo), absorb, resist, false, 0, crit);
-
- // Procflags
- uint32 procAttacker = PROC_FLAG_HIT_SPELL;
- uint32 procVictim = (PROC_FLAG_STRUCK_SPELL|PROC_FLAG_TAKE_DAMAGE);
-
- if (crit)
- {
- procAttacker |= PROC_FLAG_CRIT_SPELL;
- procVictim |= PROC_FLAG_STRUCK_CRIT_SPELL;
- }
-
- ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, GetSpellSchoolMask(spellInfo), spellInfo, isTriggeredSpell);
-
- return damage;
- }
- else
- {
- // all spell proc for 0 normal and magic damage called in DealFlatDamage
-
- //Check for rage
- if(cleanDamage.damage)
- // Rage from damage received.
- if(pVictim->GetTypeId() == TYPEID_PLAYER && (pVictim->getPowerType() == POWER_RAGE))
- ((Player*)pVictim)->RewardRage(cleanDamage.damage, 0, false);
-
- return 0;
- }
-}
-*/
-
// Obsolete func need remove, here only for comotability vs another patches
uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell, bool useSpellDamage)
{
@@ -11255,11 +10846,6 @@ uint32 Unit::GetCreatePowers( Powers power ) const
return 0;
}
-void Unit::AddToWorld()
-{
- WorldObject::AddToWorld();
-}
-
void Unit::RemoveFromWorld()
{
// cleanup
@@ -11274,20 +10860,23 @@ void Unit::RemoveFromWorld()
void Unit::CleanupsBeforeDelete()
{
- if(m_uint32Values) // only for fully created object
- {
- RemoveAllAuras();
- InterruptNonMeleeSpells(true);
- m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList
- CombatStop();
- ClearComboPointHolders();
- DeleteThreatList();
- getHostilRefManager().setOnlineOfflineState(false);
- RemoveAllGameObjects();
- RemoveAllDynObjects();
- GetMotionMaster()->Clear(false); // remove different non-standard movement generators.
- }
- RemoveFromWorld();
+ assert(m_uint32Values);
+
+ //A unit may be in removelist and not in world, but it is still in grid
+ //and may have some references during delete
+ RemoveAllAuras();
+ InterruptNonMeleeSpells(true);
+ m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList
+ CombatStop();
+ ClearComboPointHolders();
+ DeleteThreatList();
+ getHostilRefManager().setOnlineOfflineState(false);
+ RemoveAllGameObjects();
+ RemoveAllDynObjects();
+ GetMotionMaster()->Clear(false); // remove different non-standard movement generators.
+
+ if(IsInWorld())
+ RemoveFromWorld();
}
void Unit::UpdateCharmAI()
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
index 6065e491993..5b1261e664a 100644
--- a/src/game/WorldSession.cpp
+++ b/src/game/WorldSession.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,12 +22,11 @@
\ingroup u2w
*/
-#include "WorldSocket.h"
+#include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "Log.h"
#include "Opcodes.h"
-#include "WorldSocket.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Player.h"
@@ -374,7 +373,7 @@ void WorldSession::LogoutPlayer(bool Save)
// the player may not be in the world when logging out
// e.g if he got disconnected during a transfer to another map
// calls to GetMap in this case may cause crashes
- if(_player->IsInWorld()) MapManager::Instance().GetMap(_player->GetMapId(), _player)->Remove(_player, false);
+ if(_player->IsInWorld()) _player->GetMap()->Remove(_player, false);
// RemoveFromWorld does cleanup that requires the player to be in the accessor
ObjectAccessor::Instance().RemoveObject(_player);