Index: src/realmd/AuthSocket.cpp
===================================================================
--- src/realmd/AuthSocket.cpp (revision 4845)
+++ src/realmd/AuthSocket.cpp (working copy)
@@ -360,9 +360,9 @@
for(int i=0;accepted_versions[i];i++)
if(ch->build==accepted_versions[i])
{
- valid_version=true;
break;
}
+ valid_version=true;
///
- if this is a valid version
if(valid_version)
Index: src/shared/Common.h
===================================================================
--- src/shared/Common.h (revision 4845)
+++ src/shared/Common.h (working copy)
@@ -173,7 +173,7 @@
#endif
#ifndef M_PI
-#define M_PI 3.14159265358979323846
+#define M_PI 3.14159
#endif
#endif
Index: src/mangosd/Master.cpp
===================================================================
--- src/mangosd/Master.cpp (revision 4845)
+++ src/mangosd/Master.cpp (working copy)
@@ -64,21 +64,9 @@
/// Main function
void Master::Run()
{
- sLog.outString( "MaNGOS daemon %s", _FULLVERSION );
+ sLog.outString( "MaNGOS demon %s (~SantaCl~ build!/012508)", _FULLVERSION );
sLog.outString( " to stop.\n\n" );
- sLog.outTitle( "MM MM MM MM MMMMM MMMM MMMMM");
- sLog.outTitle( "MM MM MM MM MMM MMM MM MM MMM MMM");
- sLog.outTitle( "MMM MMM MMM MM MMM MMM MM MM MMM");
- sLog.outTitle( "MM M MM MMMM MM MMM MM MM MMM");
- sLog.outTitle( "MM M MM MMMMM MM MMMM MMM MM MM MMM");
- sLog.outTitle( "MM M MM M MMM MM MMM MMMMMMM MM MM MMM");
- sLog.outTitle( "MM MM MMM MM MM MM MMM MM MM MMM");
- sLog.outTitle( "MM MM MMMMMMM MM MM MMM MMM MM MM MMM MMM");
- sLog.outTitle( "MM MM MM MMM MM MM MMMMMM MMMM MMMMM");
- sLog.outTitle( " MM MMM http://www.mangosproject.org");
- sLog.outTitle( " MMMMMM\n\n");
-
///- Start the databases
if (!_StartDB())
return;
Index: src/game/Object.cpp
===================================================================
--- src/game/Object.cpp (revision 4845)
+++ src/game/Object.cpp (working copy)
@@ -568,9 +568,9 @@
Tokens::iterator iter;
int index;
- for (iter = tokens.begin(), index = 0; index < m_valuesCount; ++iter, ++index)
+ for (iter = tokens.begin(), index = 0; index < m_valuesCount; ++iter, ++index)
{
- m_uint32Values[index] = atol((*iter).c_str());
+ m_uint32Values[index] = atol((*iter).c_str());
}
return true;
Index: src/game/SpellEffects.cpp
===================================================================
--- src/game/SpellEffects.cpp (revision 4845)
+++ src/game/SpellEffects.cpp (working copy)
@@ -521,7 +521,7 @@
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %i\n", spell_id);
+ sLog.outError("SpellEffect: unknown spell id %i\n", spell_id);
return;
}
@@ -656,9 +656,6 @@
// Kill command
case 2226:
{
- if(m_caster->getClass()!=CLASS_HUNTER)
- return;
-
// clear hunter crit aura state
m_caster->ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE,false);
@@ -1172,7 +1169,7 @@
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %i\n", m_spellInfo->EffectTriggerSpell[i]);
+ sLog.outError("SpellEffect: unknown spell id %i\n", m_spellInfo->EffectTriggerSpell[i]);
return;
}
@@ -1224,8 +1221,7 @@
void Spell::EffectApplyAura(uint32 i)
{
- if(!unitTarget)
- return;
+ if(!unitTarget) return;
// ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
if( !unitTarget->isAlive() && m_spellInfo->Id != 20584 && m_spellInfo->Id != 8326 &&
(unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
@@ -2137,9 +2133,10 @@
//victim have to be alive and humanoid or undead
if( unitTarget->isAlive() && (unitTarget->GetCreatureTypeMask() &CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) != 0)
{
- int32 chance = 10 + m_caster->getLevel() - unitTarget->getLevel();
- if (chance > irand(0, 19))
+ int32 chance = 100 - (10* (unitTarget->getLevel() - m_caster->getLevel()) );
+
+ if (m_caster->getLevel() > unitTarget->getLevel() || chance > irand(0, 100) )
{
//Stealing successful
//sLog.outDebug("Sending loot from pickpocket");
@@ -2532,67 +2529,50 @@
void Spell::EffectTameCreature(uint32 i)
{
- if(m_caster->GetPetGUID())
- return;
+ if(m_caster->GetPetGUID()) return;
+ if(!unitTarget) return;
+ if(unitTarget->GetTypeId() == TYPEID_PLAYER) return;
- if(!unitTarget)
- return;
-
- if(unitTarget->GetTypeId() == TYPEID_PLAYER)
- return;
-
Creature* creatureTarget = (Creature*)unitTarget;
+ if(creatureTarget->isPet()) return;
- if(creatureTarget->isPet())
- return;
+ creatureTarget->AttackStop();
+ if(m_caster->getVictim()==creatureTarget) m_caster->AttackStop();
+ creatureTarget->setDeathState(JUST_DIED);
+ creatureTarget->RemoveCorpse();
- if(m_caster->getClass() == CLASS_HUNTER)
+ // cast finish successfully
+ SendChannelUpdate(0);
+ finish();
+
+ Pet* pet = new Pet(m_caster, HUNTER_PET);
+ if(!pet->CreateBaseAtCreature(creatureTarget))
{
- creatureTarget->AttackStop();
- if(m_caster->getVictim()==creatureTarget)
- m_caster->AttackStop();
+ delete pet;
+ return;
+ }
+ pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID());
+ pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID());
+ pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction());
+ pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
+ if(!pet->InitStatsForLevel( creatureTarget->getLevel() ) )
+ {
+ sLog.outError("ERROR: InitStatsForLevel() in EffectTameCreature failed! Pet deleted.");
+ delete pet;
+ return;
+ }
+ pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
- creatureTarget->setDeathState(JUST_DIED);
- creatureTarget->RemoveCorpse();
-
- // cast finish successfully
- SendChannelUpdate(0);
- finish();
-
- Pet* pet = new Pet(m_caster, HUNTER_PET);
-
- if(!pet->CreateBaseAtCreature(creatureTarget))
- {
- delete pet;
- return;
- }
-
- pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID());
- pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID());
- pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction());
- pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
-
- if(!pet->InitStatsForLevel( creatureTarget->getLevel() ) )
- {
- sLog.outError("ERROR: InitStatsForLevel() in EffectTameCreature failed! Pet deleted.");
- delete pet;
- return;
- }
-
- pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
- // this enables pet details window (Shift+P)
- pet->AIM_Initialize();
- pet->InitPetCreateSpells();
- pet->SetHealth(pet->GetMaxHealth());
-
- MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet);
-
- if(m_caster->GetTypeId() == TYPEID_PLAYER)
- {
- m_caster->SetPet(pet);
- pet->SavePetToDB(PET_SAVE_AS_CURRENT);
- ((Player*)m_caster)->PetSpellInitialize();
- }
+ // this enables pet details window (Shift+P)
+ pet->AIM_Initialize();
+ pet->InitPetCreateSpells();
+ pet->SetHealth(pet->GetMaxHealth());
+ MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet);
+ if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ m_caster->SetPet(pet);
+ pet->SavePetToDB(PET_SAVE_AS_CURRENT);
+ ((Player*)m_caster)->PetSpellInitialize();
}
}
@@ -3327,8 +3307,8 @@
sLog.outDebug("Spell Effect: Stuck");
sLog.outDetail("Player %s (guid %u) used auto-unstuck future at map %u (%f, %f, %f)", pTarget->GetName(), pTarget->GetGUIDLow(), m_caster->GetMapId(), m_caster->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ());
- if(pTarget->isInFlight())
- return;
+//SantaCl if(pTarget->isInFlight())
+// return;
//homebind location is loaded always
pTarget->TeleportTo(pTarget->m_homebindMapId,pTarget->m_homebindX,pTarget->m_homebindY,pTarget->m_homebindZ,pTarget->GetOrientation());
@@ -3337,8 +3317,8 @@
SpellEntry const *spellInfo = sSpellStore.LookupEntry(8690);
if(!spellInfo)
return;
- Spell spell(pTarget,spellInfo,true,0);
- spell.SendSpellCooldown();
+//SantaCl Spell spell(pTarget,spellInfo,true,0);
+// spell.SendSpellCooldown();
}
void Spell::EffectSummonPlayer(uint32 i)
Index: src/game/PetHandler.cpp
===================================================================
--- src/game/PetHandler.cpp (revision 4845)
+++ src/game/PetHandler.cpp (working copy)
@@ -141,7 +141,7 @@
_player->Uncharm();
break;
default:
- sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.\n", flag, spellid);
+ sLog.outError("PetHandler144: unknown PET flag Action %i and spellid %i.\n", flag, spellid);
}
break;
case ACT_REACTION: // 0x600
@@ -168,7 +168,7 @@
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid );
if(!spellInfo)
{
- sLog.outError("WORLD: unknown PET spell id %i\n", spellid);
+ sLog.outError("PetHandler171: unknown PET spell id %i\n", spellid);
return;
}
@@ -257,7 +257,7 @@
break;
}
default:
- sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.\n", flag, spellid);
+ sLog.outError("PEtHandler260: unknown PET flag Action %i and spellid %i.\n", flag, spellid);
}
}
@@ -557,7 +557,7 @@
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid);
if(!spellInfo)
{
- sLog.outError("WORLD: unknown PET spell id %i\n", spellid);
+ sLog.outError("PetHandler560: unknown PET spell id %i\n", spellid);
return;
}
Index: src/game/Level1.cpp
===================================================================
--- src/game/Level1.cpp (revision 4845)
+++ src/game/Level1.cpp (working copy)
@@ -308,11 +308,11 @@
chr->GetSession()->SendPacket( &data );
}
- chr->SaveRecallPosition();
// before GM
float x,y,z;
m_session->GetPlayer()->GetClosePoint(x,y,z,chr->GetObjectSize());
+ chr->SaveRecallPosition();
chr->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,chr->GetOrientation());
}
else if (uint64 guid = objmgr.GetPlayerGUIDByName(name))
@@ -408,12 +408,12 @@
chr->GetSession()->SendPacket(&data);
}
- _player->SaveRecallPosition();
// to point to see at target with same orientation
float x,y,z;
chr->GetContactPoint(m_session->GetPlayer(),x,y,z);
+ _player->SaveRecallPosition();
_player->TeleportTo(chr->GetMapId(), x, y, z, _player->GetAngle( chr ), true, true, true);
return true;
}
@@ -439,54 +439,22 @@
}
// Teleport player to last position
-bool ChatHandler::HandleRecallCommand(const char* args)
-{
- Player* chr = NULL;
+bool ChatHandler::HandleRecallCommand(const char* args){
+ Player* chr = NULL;
+ //hf001 start:
+ chr = m_session->GetPlayer();
- if(!*args)
- {
- chr = getSelectedPlayer();
-
- if(!chr)
- {
- chr = m_session->GetPlayer();
-
- if(chr->isInFlight())
- {
- SendSysMessage(LANG_TARGET_IN_FLIGHT);
- return true;
- }
- }
- }
- else
- {
- std::string name = args;
- normalizePlayerName(name);
- //WorldDatabase.escape_string(name); // prevent SQL injection - normal name don't must changed by this call
-
- chr = objmgr.GetPlayer(name.c_str());
-
- if(!chr)
- {
- PSendSysMessage(LANG_NO_PLAYER, args);
- return true;
- }
- }
-
- if(chr->IsBeingTeleported())
- {
- PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName());
- return true;
- }
-
- if(chr->isInFlight())
- {
- PSendSysMessage(LANG_CHAR_IN_FLIGHT, chr->GetName());
- return true;
- }
-
- chr->TeleportTo(chr->m_recallMap, chr->m_recallX, chr->m_recallY, chr->m_recallZ, chr->m_recallO);
+ if(chr->isInFlight()){
+ SendSysMessage(LANG_TARGET_IN_FLIGHT);
return true;
+ }
+ if(chr->IsBeingTeleported()){
+ PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName());
+ return true;
+ }
+ chr->TeleportTo(chr->m_recallMap, chr->m_recallX, chr->m_recallY, chr->m_recallZ, chr->m_recallO);
+ return true;
+ //hf001 end
}
//Edit Player KnownTitles
@@ -913,13 +881,12 @@
float ASpeed = (float)atof((char*)args);
- if (ASpeed > 10 || ASpeed < 0.1)
- {
- SendSysMessage(LANG_BAD_VALUE);
- return true;
- }
+ if (ASpeed > 10) ASpeed = 10;
+
+ if (ASpeed < 1) ASpeed = 1;
- Player *chr = getSelectedPlayer();
+
+ Player *chr = getSelectedPlayer();
if (chr == NULL)
{
SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -1594,7 +1561,6 @@
}
_player->SaveRecallPosition();
-
_player->TeleportTo(mapid, x, y, z, ort);
return true;
}
@@ -1870,7 +1836,6 @@
}
chr->SaveRecallPosition();
-
chr->TeleportTo(mapid,x,y,z,chr->GetOrientation());
}
else if (uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str()))
Index: src/game/MovementHandler.cpp
===================================================================
--- src/game/MovementHandler.cpp (revision 4845)
+++ src/game/MovementHandler.cpp (working copy)
@@ -109,12 +109,10 @@
void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
{
- CHECK_PACKET_SIZE(recv_data, 4+4+4+4+4+4);
+ if(GetPlayer()->GetDontMove()) return;
- if(GetPlayer()->GetDontMove())
- return;
-
- /* extract packet */
+ /* extract packet */
+ CHECK_PACKET_SIZE(recv_data, 4+4+4+4+4+4);
uint32 flags, time, fallTime;
float x, y, z, orientation;
@@ -127,7 +125,9 @@
recv_data >> flags >> time;
recv_data >> x >> y >> z >> orientation;
- if(flags & MOVEMENTFLAG_ONTRANSPORT) // and if opcode 909?
+ if (!MaNGOS::IsValidMapCoord(x, y)) return;
+
+ if(flags & MOVEMENTFLAG_ONTRANSPORT) // and if opcode 909?
{
// recheck
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4);
@@ -139,13 +139,16 @@
{
// recheck
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
-
recv_data >> s_angle; // kind of angle, -1.55=looking down, 0=looking straight forward, +1.55=looking up
+ if(!GetPlayer()->IsInWater()) GetPlayer()->SetInWater(true);
}
+ else
+ {
+ if(GetPlayer()->IsInWater()) GetPlayer()->SetInWater(false);
+ }
// recheck
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
-
recv_data >> fallTime; // duration of last jump (when in jump duration from jump begin to now)
if((flags & MOVEMENTFLAG_JUMPING) || (flags & MOVEMENTFLAG_FALLING))
@@ -167,8 +170,6 @@
}
/*----------------*/
- if (!MaNGOS::IsValidMapCoord(x, y))
- return;
/* handle special cases */
if (flags & MOVEMENTFLAG_ONTRANSPORT)
@@ -179,15 +180,15 @@
// unmount before boarding
_player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
- for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
- {
- if ((*iter)->GetGUID() == t_GUID)
- {
- GetPlayer()->m_transport = (*iter);
- (*iter)->AddPassenger(GetPlayer());
- break;
- }
- }
+// for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
+// {
+// if ((*iter)->GetGUID() == t_GUID)
+// {
+// GetPlayer()->m_transport = (*iter);
+// (*iter)->AddPassenger(GetPlayer());
+// break;
+// }
+// }
}
GetPlayer()->m_transX = t_x;
GetPlayer()->m_transY = t_y;
@@ -206,20 +207,19 @@
GetPlayer()->m_transTime = 0;
}
- if (GetPlayer()->HasMovementFlags(MOVEMENTFLAG_FALLING) && !(flags & MOVEMENTFLAG_FALLING))
+
+ if (GetPlayer()->HasMovementFlags(MOVEMENTFLAG_FALLING) && !(flags & MOVEMENTFLAG_FALLING) && !(flags & MOVEMENTFLAG_SWIMMING))
{
Player *target = GetPlayer();
- if (fallTime > 1100 && !target->isDead() && !target->isGameMaster() &&
- !target->HasAuraType(SPELL_AURA_HOVER) && !target->HasAuraType(SPELL_AURA_FEATHER_FALL))
+ if (fallTime > 1100 && !target->isDead() && !target->HasAuraType(SPELL_AURA_HOVER) && !target->HasAuraType(SPELL_AURA_FEATHER_FALL))
{
Map const *map = MapManager::Instance().GetBaseMap(target->GetMapId());
float posz = map->GetWaterLevel(x,y);
float fallperc = float(fallTime)*10/11000;
+ uint32 mindmg = target->GetMaxHealth()/20; //ignore falling damage if less than 5% of players HP so stealthed players can remain stealthed.
uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * target->GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL));
-
- if (damage > 0 && damage < 2* target->GetMaxHealth())
- target->EnvironmentalDamage(target->GetGUID(),DAMAGE_FALL, damage);
- DEBUG_LOG("!! z=%f, pz=%f FallTime=%d posz=%f damage=%d" , z, target->GetPositionZ(),fallTime, posz, damage);
+ if (damage > target->GetMaxHealth()) damage = target->GetMaxHealth()+1;
+ if (damage > mindmg) target->EnvironmentalDamage(target->GetGUID(),DAMAGE_FALL, damage);
}
//handle fall and logout at the sametime
@@ -235,8 +235,6 @@
}
}
- if(((flags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
- GetPlayer()->SetInWater( !GetPlayer()->IsInWater() );
/*----------------------*/
/* process position-change */
Index: src/game/Level3.cpp
===================================================================
--- src/game/Level3.cpp (revision 4845)
+++ src/game/Level3.cpp (working copy)
@@ -1380,9 +1380,9 @@
if(!spellInfo)
continue;
- // skip wrong class/race skills
- if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
- continue;
+ // skip wrong class/race skills SantaCl
+ // if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
+ // continue;
// skip other spell families
if( spellInfo->SpellFamilyName != family)
@@ -2494,19 +2494,19 @@
bool ChatHandler::HandleDieCommand(const char* args)
{
- Unit* target = getSelectedUnit();
+// Unit* target = getSelectedUnit();
+//
+// if(!target || !m_session->GetPlayer()->GetSelection())
+// {
+// SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+// return true;
+// }
- if(!target || !m_session->GetPlayer()->GetSelection())
- {
- SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
- return true;
- }
+// if( target->isAlive() )
+// {
+// m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, 0, false);
+// }
- if( target->isAlive() )
- {
- m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, 0, false);
- }
-
return true;
}
@@ -2528,7 +2528,6 @@
PSendSysMessage(LANG_NO_CHAR_SELECTED);
return true;
}
-
SelectedPlayer->ResurrectPlayer(0.5f);
SelectedPlayer->SpawnCorpseBones();
SelectedPlayer->SaveToDB();
@@ -3351,24 +3350,24 @@
Unit *unit = getSelectedUnit();
if(!unit)
{
- SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ sLog.outError(LANG_SELECT_CHAR_OR_CREATURE);
return true;
}
Unit::AuraMap& uAuras = unit->GetAuras();
- PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
+ sLog.outError(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
for (Unit::AuraMap::iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
{
- PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(), itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(), itr->second->GetSpellProto()->SpellName[sWorld.GetDBClang()]);
+ sLog.outError(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(), itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(), itr->second->GetSpellProto()->SpellName[sWorld.GetDBClang()]);
}
for (int i = 0; i < TOTAL_AURAS; i++)
{
Unit::AuraList const& uAuraList = unit->GetAurasByType(AuraType(i));
if (uAuraList.empty()) continue;
- PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
+ sLog.outError(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
{
- PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), (*itr)->GetSpellProto()->SpellName[sWorld.GetDBClang()]);
+ sLog.outError(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), (*itr)->GetSpellProto()->SpellName[sWorld.GetDBClang()]);
}
}
return true;
@@ -4387,8 +4386,7 @@
return false;
uint32 spell = (uint32)atol((char*)cId);
- if(!spell || !sSpellStore.LookupEntry(spell))
- return false;
+ if(!spell) return false;
// update orientation at server
caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
@@ -4399,7 +4397,6 @@
caster->SendMessageToSet(&data,true);
caster->CastSpell(m_session->GetPlayer(),spell,false);
-
return true;
}
Index: src/game/ItemHandler.cpp
===================================================================
--- src/game/ItemHandler.cpp (revision 4845)
+++ src/game/ItemHandler.cpp (working copy)
@@ -187,160 +187,149 @@
// Only _static_ data send in this packet !!!
void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
{
- CHECK_PACKET_SIZE(recv_data,4+4+4);
- //sLog.outDebug("WORLD: CMSG_ITEM_QUERY_SINGLE");
+// sLog.outDebug("WORLD: CMSG_ITEM_QUERY_SINGLE ItemQuery: %u", item");
+ CHECK_PACKET_SIZE(recv_data,4+4+4);
uint32 item;
recv_data >> item;
-
- sLog.outDetail("STORAGE: Item Query = %u", item);
-
ItemPrototype const *pProto = objmgr.GetItemPrototype( item );
- if( pProto )
- {
- std::string Name = pProto->Name1;
- std::string Description = pProto->Description;
+ if(!pProto )
+ {
+ uint64 guid;
+ recv_data >> guid;
- int loc_idx = GetSessionLocaleIndex();
- if ( loc_idx >= 0 )
+ sLog.outError( "ItemHandler201: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), item );
+ WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4);
+ data << uint32(item | 0x80000000);
+ SendPacket( &data );
+ return;
+ }
+ std::string Name = pProto->Name1;
+ std::string Description = pProto->Description;
+ int loc_idx = GetSessionLocaleIndex();
+ if ( loc_idx >= 0 )
+ {
+ ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
+ if (il)
+ {
+ if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) Name = il->Name[loc_idx];
+ if (il->Description.size() > loc_idx && !il->Description[loc_idx].empty()) Description = il->Description[loc_idx];
+ }
+ }
+ // guess size
+ WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600);
+ data << pProto->ItemId;
+ data << pProto->Class;
+ data << pProto->SubClass;
+ data << uint32(-1); // new 2.0.3, not exist in wdb cache?
+ data << Name;
+ data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
+ data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00);
+ data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00);
+ data << pProto->DisplayInfoID;
+ data << pProto->Quality;
+ data << pProto->Flags;
+ data << pProto->BuyPrice;
+ data << pProto->SellPrice;
+ data << pProto->InventoryType;
+ data << pProto->AllowableClass;
+ data << pProto->AllowableRace;
+ data << pProto->ItemLevel;
+ data << pProto->RequiredLevel;
+ data << pProto->RequiredSkill;
+ data << pProto->RequiredSkillRank;
+ data << pProto->RequiredSpell;
+ data << pProto->RequiredHonorRank;
+ data << pProto->RequiredCityRank;
+ data << pProto->RequiredReputationFaction;
+ data << pProto->RequiredReputationRank;
+ data << pProto->MaxCount;
+ data << pProto->Stackable;
+ data << pProto->ContainerSlots;
+ for(int i = 0; i < 10; i++)
+ {
+ data << pProto->ItemStat[i].ItemStatType;
+ data << pProto->ItemStat[i].ItemStatValue;
+ }
+ for(int i = 0; i < 5; i++)
+ {
+ data << pProto->Damage[i].DamageMin;
+ data << pProto->Damage[i].DamageMax;
+ data << pProto->Damage[i].DamageType;
+ }
+ data << pProto->Armor;
+ data << pProto->HolyRes;
+ data << pProto->FireRes;
+ data << pProto->NatureRes;
+ data << pProto->FrostRes;
+ data << pProto->ShadowRes;
+ data << pProto->ArcaneRes;
+ data << pProto->Delay;
+ data << pProto->Ammo_type;
+ data << (float)pProto->RangedModRange;
+ for(int s = 0; s < 5; s++)
+ {
+ // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
+ // use `item_template` or if not set then only use spell cooldowns
+ SpellEntry const* spell = sSpellStore.LookupEntry(pProto->Spells[s].SpellId);
+ if(spell)
+ {
+ bool db_data = pProto->Spells[s].SpellCooldown > 0 || pProto->Spells[s].SpellCategoryCooldown > 0;
+ data << pProto->Spells[s].SpellId;
+ data << pProto->Spells[s].SpellTrigger;
+ data << uint32(-abs(pProto->Spells[s].SpellCharges));
+ if(db_data)
{
- ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId);
- if (il)
- {
- if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
- Name = il->Name[loc_idx];
- if (il->Description.size() > loc_idx && !il->Description[loc_idx].empty())
- Description = il->Description[loc_idx];
- }
+ data << uint32(pProto->Spells[s].SpellCooldown);
+ data << uint32(pProto->Spells[s].SpellCategory);
+ data << uint32(pProto->Spells[s].SpellCategoryCooldown);
}
- // guess size
- WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600);
- data << pProto->ItemId;
- data << pProto->Class;
- data << pProto->SubClass;
- data << uint32(-1); // new 2.0.3, not exist in wdb cache?
- data << Name;
- data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
- data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00);
- data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00);
- data << pProto->DisplayInfoID;
- data << pProto->Quality;
- data << pProto->Flags;
- data << pProto->BuyPrice;
- data << pProto->SellPrice;
- data << pProto->InventoryType;
- data << pProto->AllowableClass;
- data << pProto->AllowableRace;
- data << pProto->ItemLevel;
- data << pProto->RequiredLevel;
- data << pProto->RequiredSkill;
- data << pProto->RequiredSkillRank;
- data << pProto->RequiredSpell;
- data << pProto->RequiredHonorRank;
- data << pProto->RequiredCityRank;
- data << pProto->RequiredReputationFaction;
- data << pProto->RequiredReputationRank;
- data << pProto->MaxCount;
- data << pProto->Stackable;
- data << pProto->ContainerSlots;
- for(int i = 0; i < 10; i++)
+ else
{
- data << pProto->ItemStat[i].ItemStatType;
- data << pProto->ItemStat[i].ItemStatValue;
+ data << uint32(spell->RecoveryTime);
+ data << uint32(spell->Category);
+ data << uint32(spell->CategoryRecoveryTime);
}
- for(int i = 0; i < 5; i++)
- {
- data << pProto->Damage[i].DamageMin;
- data << pProto->Damage[i].DamageMax;
- data << pProto->Damage[i].DamageType;
- }
- data << pProto->Armor;
- data << pProto->HolyRes;
- data << pProto->FireRes;
- data << pProto->NatureRes;
- data << pProto->FrostRes;
- data << pProto->ShadowRes;
- data << pProto->ArcaneRes;
- data << pProto->Delay;
- data << pProto->Ammo_type;
-
- data << (float)pProto->RangedModRange;
- for(int s = 0; s < 5; s++)
- {
- // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
- // use `item_template` or if not set then only use spell cooldowns
- SpellEntry const* spell = sSpellStore.LookupEntry(pProto->Spells[s].SpellId);
- if(spell)
- {
- bool db_data = pProto->Spells[s].SpellCooldown > 0 || pProto->Spells[s].SpellCategoryCooldown > 0;
-
- data << pProto->Spells[s].SpellId;
- data << pProto->Spells[s].SpellTrigger;
- data << uint32(-abs(pProto->Spells[s].SpellCharges));
-
- if(db_data)
- {
- data << uint32(pProto->Spells[s].SpellCooldown);
- data << uint32(pProto->Spells[s].SpellCategory);
- data << uint32(pProto->Spells[s].SpellCategoryCooldown);
- }
- else
- {
- data << uint32(spell->RecoveryTime);
- data << uint32(spell->Category);
- data << uint32(spell->CategoryRecoveryTime);
- }
- }
- else
- {
- data << uint32(0);
- data << uint32(0);
- data << uint32(0);
- data << uint32(-1);
- data << uint32(0);
- data << uint32(-1);
- }
- }
- data << pProto->Bonding;
- data << Description;
- data << pProto->PageText;
- data << pProto->LanguageID;
- data << pProto->PageMaterial;
- data << pProto->StartQuest;
- data << pProto->LockID;
- data << pProto->Material;
- data << pProto->Sheath;
- data << pProto->RandomProperty;
- data << pProto->RandomSuffix;
- data << pProto->Block;
- data << pProto->ItemSet;
- data << pProto->MaxDurability;
- data << pProto->Area;
- data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch
- data << pProto->BagFamily;
- data << pProto->TotemCategory;
- for(int s = 0; s < 3; s++)
- {
- data << pProto->Socket[s].Color;
- data << pProto->Socket[s].Content;
- }
- data << pProto->socketBonus;
- data << pProto->GemProperties;
- data << pProto->ExtendedCost;
- data << pProto->RequiredDisenchantSkill;
- data << pProto->ArmorDamageModifier;
- SendPacket( &data );
+ }
+ else
+ {
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(-1);
+ data << uint32(0);
+ data << uint32(-1);
+ }
}
- else
+ data << pProto->Bonding;
+ data << Description;
+ data << pProto->PageText;
+ data << pProto->LanguageID;
+ data << pProto->PageMaterial;
+ data << pProto->StartQuest;
+ data << pProto->LockID;
+ data << pProto->Material;
+ data << pProto->Sheath;
+ data << pProto->RandomProperty;
+ data << pProto->RandomSuffix;
+ data << pProto->Block;
+ data << pProto->ItemSet;
+ data << pProto->MaxDurability;
+ data << pProto->Area;
+ data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch
+ data << pProto->BagFamily;
+ data << pProto->TotemCategory;
+ for(int s = 0; s < 3; s++)
{
- uint64 guid;
- recv_data >> guid;
-
- sLog.outDetail( "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), item );
- WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4);
- data << uint32(item | 0x80000000);
- SendPacket( &data );
+ data << pProto->Socket[s].Color;
+ data << pProto->Socket[s].Content;
}
+ data << pProto->socketBonus;
+ data << pProto->GemProperties;
+ data << pProto->ExtendedCost;
+ data << pProto->RequiredDisenchantSkill;
+ data << pProto->ArmorDamageModifier;
+ SendPacket( &data );
}
void WorldSession::HandleReadItem( WorldPacket & recv_data )
Index: src/game/AuctionHouseObject.h
===================================================================
--- src/game/AuctionHouseObject.h (revision 4845)
+++ src/game/AuctionHouseObject.h (working copy)
@@ -45,7 +45,7 @@
uint32 startbid; //maybe useless
uint32 bid;
uint32 buyout;
- time_t time;
+ uint32 time;//SantaCl Fixx0r>?
uint32 bidder;
uint32 deposit; //deposit can be calculated only when creating auction
uint32 location;
Index: src/game/Object.h
===================================================================
--- src/game/Object.h (revision 4845)
+++ src/game/Object.h (working copy)
@@ -129,13 +129,13 @@
const int32& GetInt32Value( uint16 index ) const
{
- ASSERT( index < m_valuesCount || PrintIndexError( index , false) );
+// ASSERT( index < m_valuesCount || PrintIndexError( index , false) );
return m_int32Values[ index ];
}
const uint32& GetUInt32Value( uint16 index ) const
{
- ASSERT( index < m_valuesCount || PrintIndexError( index , false) );
+// ASSERT( index < m_valuesCount || PrintIndexError( index , false) );
return m_uint32Values[ index ];
}
@@ -184,7 +184,6 @@
bool HasFlag( uint16 index, uint32 flag ) const
{
- ASSERT( index < m_valuesCount || PrintIndexError( index , false ) );
return (m_uint32Values[ index ] & flag) != 0;
}
Index: src/game/SpellHandler.cpp
===================================================================
--- src/game/SpellHandler.cpp (revision 4845)
+++ src/game/SpellHandler.cpp (working copy)
@@ -569,7 +569,7 @@
SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId );
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %u\n", spellId);
+ sLog.outError("SpellHandler: unknown spell id %u\n", spellId);
return;
}
@@ -599,7 +599,7 @@
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %i\n", spellId);
+ sLog.outError("SpellHandler: unknown spell id %i\n", spellId);
return;
}
@@ -694,7 +694,7 @@
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
if(!spellInfo)
{
- sLog.outError("WORLD: unknown PET spell id %i\n", spellId);
+ sLog.outError("WSpellHandler697: unknown PET spell id %i\n", spellId);
return;
}
Index: src/game/WorldSocket.cpp
===================================================================
--- src/game/WorldSocket.cpp (revision 4845)
+++ src/game/WorldSocket.cpp (working copy)
@@ -416,9 +416,9 @@
// do small delay (10ms) at accepting successful authed connection to prevent droping packets by client
// don't must harm anyone (let login ~100 accounts in 1 sec ;) )
#ifdef WIN32
- Sleep(10);
+ Sleep(100);
#else
- ZThread::Thread::sleep(10);
+ ZThread::Thread::sleep(100);
#endif
///- Create and send the Addon packet
@@ -446,195 +446,168 @@
popu /= pLimit;
popu *= 2;
loginDatabase.PExecute("UPDATE `realmlist` SET `population` = '%f' WHERE `id` = '%d'",popu,realmID);
- sLog.outDetail( "Server Population (%f).",popu);
+ sLog.outDetail( "Server Population (%u).",(uint32) sWorld.GetActiveSessionCount());
}
-
return;
}
/// Handle the Ping packet
void WorldSocket::_HandlePing(WorldPacket& recvPacket)
{
- uint32 ping;
+ uint32 ping;
+ CHECK_PACKET_SIZE(recvPacket,4);
+ //- Get the ping packet content
+ recvPacket >> ping;
- CHECK_PACKET_SIZE(recvPacket,4);
-
- ///- Get the ping packet content
- recvPacket >> ping;
-
- ///- check ping speed for players
- if(_session && _session->GetSecurity() == SEC_PLAYER)
+// //- check ping speed for players
+// if(_session && _session->GetSecurity() == SEC_PLAYER)
+// {
+ uint32 cur_mstime = getMSTime();
+ uint32 diff_mstime = cur_mstime - m_LastPingMSTime;
+ m_LastPingMSTime = cur_mstime;
+ if(diff_mstime < 27000) // should be 30000 (=30 secs), add little tolerance
{
- uint32 cur_mstime = getMSTime();
- uint32 diff_mstime = cur_mstime - m_LastPingMSTime;
- m_LastPingMSTime = cur_mstime;
- if(diff_mstime < 27000) // should be 30000 (=30 secs), add little tolerance
- {
- ++m_OverSpeedPings;
-
- uint32 max_count = sWorld.getConfig(CONFIG_MAX_OVERSPEED_PINGS);
- if(max_count && m_OverSpeedPings > max_count)
- {
- sLog.outBasic("Player %s from account id %u kicked for overspeed ping packets from client (non-playable connection lags or cheating) ",_session->GetPlayerName(),_session->GetAccountId());
- _session->KickPlayer();
- return;
- }
- }
- else
- m_OverSpeedPings = 0;
-
- }
-
- ///- And put the pong answer in the to-be-sent queue
- WorldPacket packet( SMSG_PONG, 4 );
- packet << ping;
- SendPacket(&packet);
-
- return;
+ sLog.outDetail("worldsocket470: anti-spamm Last: %u",m_LastPingMSTime);
+ Sleep(150); //force a delay to client if the client is spamming.
+ }
+ //- And put the pong answer in the to-be-sent queue
+ WorldPacket packet( SMSG_PONG, 4 );
+ packet << ping;
+ SendPacket(&packet);
+ return;
}
/// Handle the update order for the socket
void WorldSocket::SendSinglePacket()
{
- WorldPacket *packet;
- ServerPktHeader hdr;
+ static uint32 LastMSTime;
+ WorldPacket *packet;
+ ServerPktHeader hdr;
+ if (_sendQueue.empty()) return; //exit if nothing to send!
- ///- If we have packet to send
- if (!_sendQueue.empty())
+ uint32 cur_mstime = getMSTime();
+ uint32 diff_mstime = cur_mstime - LastMSTime;
+ LastMSTime = cur_mstime;
+ if(diff_mstime < 40)
{
- packet = _sendQueue.next();
+ sLog.outDetail("worldsocket470: anti-spamm Last: %u",m_LastPingMSTime);
+ Sleep(40); //force a delay to client if the client is spamming.
+ }
- hdr.size = ntohs((uint16)packet->size() + 2);
- hdr.cmd = packet->GetOpcode();
+ packet = _sendQueue.next();
+ hdr.size = ntohs((uint16)packet->size() + 2);
+ hdr.cmd = packet->GetOpcode();
+ if( sWorldLog.LogWorld() )
+ {
+ sWorldLog.Log("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
+ (uint32)GetSocket(),
+ packet->size(),
+ LookupName(packet->GetOpcode(),
+ g_worldOpcodeNames),
+ packet->GetOpcode());
- if( sWorldLog.LogWorld() )
- {
- sWorldLog.Log("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
- (uint32)GetSocket(),
- packet->size(),
- LookupName(packet->GetOpcode(), g_worldOpcodeNames),
- packet->GetOpcode());
+ uint32 p = 0;
+ while (p < packet->size())
+ {
+ for (uint32 j = 0; j < 16 && p < packet->size(); j++)
+ sWorldLog.Log("%.2X ", (*packet)[p++]);
- uint32 p = 0;
- while (p < packet->size())
- {
- for (uint32 j = 0; j < 16 && p < packet->size(); j++)
- sWorldLog.Log("%.2X ", (*packet)[p++]);
+ sWorldLog.Log("\n");
+ }
+ sWorldLog.Log("\n\n");
+ }
- sWorldLog.Log("\n");
- }
+ //- Encrypt (if needed) the header
+ _crypt.EncryptSend((uint8*)&hdr, 4);
- sWorldLog.Log("\n\n");
- }
-
- ///- Encrypt (if needed) the header
- _crypt.EncryptSend((uint8*)&hdr, 4);
-
- ///- Send the header and body to the client
- TcpSocket::SendBuf((char*)&hdr, 4);
- if(!packet->empty()) TcpSocket::SendBuf((char*)packet->contents(), packet->size());
-
- delete packet;
- }
+ //- Send the header and body to the client
+ TcpSocket::SendBuf((char*)&hdr, 4);
+ if(!packet->empty()) TcpSocket::SendBuf((char*)packet->contents(), packet->size());
+ delete packet;
}
void WorldSocket::Update(time_t diff)
{
- const uint32 SEND_PACKETS_MAX = 100;
- const uint32 SEND_BUFFER_SIZE = 1024;
+ const uint32 SEND_PACKETS_MAX = 100;
+ const uint32 SEND_BUFFER_SIZE = 1024;
+ uint8 sendBuffer[SEND_BUFFER_SIZE];
- uint8 sendBuffer[SEND_BUFFER_SIZE];
+ while (!_sendQueue.empty())
+ {
+ bool haveBigPacket = false;
+ uint32 bufferSize = 0;
- while (!_sendQueue.empty())
+ //- While we have packets to send
+ for (uint32 packetCount = 0; (packetCount < SEND_PACKETS_MAX) && !_sendQueue.empty(); packetCount++)
{
- bool haveBigPacket = false;
- uint32 bufferSize = 0;
+ ServerPktHeader *hdr = (ServerPktHeader*)&sendBuffer[bufferSize];
- ///- While we have packets to send
- for (uint32 packetCount = 0; (packetCount < SEND_PACKETS_MAX) && !_sendQueue.empty(); packetCount++)
- {
- ServerPktHeader *hdr = (ServerPktHeader*)&sendBuffer[bufferSize];
+ // check merge possibility.
+ WorldPacket *front = _sendQueue.front();
+ uint32 packetSize = front->size();
+ if ((sizeof(*hdr) + packetSize) > SEND_BUFFER_SIZE)
+ {
+ haveBigPacket = true;
+ break;
+ }
+ if ((bufferSize + sizeof(*hdr) + packetSize) > sizeof(sendBuffer)) break;
- // check merge possibility.
- WorldPacket *front = _sendQueue.front();
- uint32 packetSize = front->size();
+ // can be merged
+ WorldPacket *packet = _sendQueue.next();
+ hdr->size = ntohs((uint16)packetSize + 2);
+ hdr->cmd = packet->GetOpcode();
+ if( sWorldLog.LogWorld() )
+ {
+ sWorldLog.Log("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
+ (uint32)GetSocket(),
+ packetSize,
+ LookupName(packet->GetOpcode(), g_worldOpcodeNames),
+ packet->GetOpcode());
- if ((sizeof(*hdr) + packetSize) > SEND_BUFFER_SIZE)
- {
- haveBigPacket = true;
- break;
- }
-
- if ((bufferSize + sizeof(*hdr) + packetSize) > sizeof(sendBuffer))
- break;
-
- // can be merged
- WorldPacket *packet = _sendQueue.next();
-
- hdr->size = ntohs((uint16)packetSize + 2);
- hdr->cmd = packet->GetOpcode();
-
- if( sWorldLog.LogWorld() )
- {
- sWorldLog.Log("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
- (uint32)GetSocket(),
- packetSize,
- LookupName(packet->GetOpcode(), g_worldOpcodeNames),
- packet->GetOpcode());
-
- uint32 p = 0;
- while (p < packetSize)
- {
- for (uint32 j = 0; j < 16 && p < packetSize; j++)
- sWorldLog.Log("%.2X ", (*packet)[p++]);
-
- sWorldLog.Log("\n");
- }
-
- sWorldLog.Log("\n\n");
- }
-
- ///- Encrypt (if needed) the header
- _crypt.EncryptSend((uint8*)hdr, sizeof(*hdr));
- bufferSize += sizeof(*hdr);
-
- if (packetSize)
- {
- memcpy(&sendBuffer[bufferSize], packet->contents(), packetSize);
- bufferSize += packetSize;
- }
-
- ///- Send the header and body to the client
- delete packet;
- }
-
- // send merged packets
- if (bufferSize) TcpSocket::SendBuf((char*)sendBuffer, bufferSize);
- // send too big non-merged packet
- if (haveBigPacket) SendSinglePacket();
- }
+ uint32 p = 0;
+ while (p < packetSize)
+ {
+ for (uint32 j = 0; j < 16 && p < packetSize; j++) sWorldLog.Log("%.2X ", (*packet)[p++]);
+ sWorldLog.Log("\n");
+ }
+ sWorldLog.Log("\n\n");
+ }
+ //- Encrypt (if needed) the header
+ _crypt.EncryptSend((uint8*)hdr, sizeof(*hdr));
+ bufferSize += sizeof(*hdr);
+ if (packetSize)
+ {
+ memcpy(&sendBuffer[bufferSize], packet->contents(), packetSize);
+ bufferSize += packetSize;
+ }
+ delete packet;
+ }
+ // send merged packets
+ if (bufferSize) TcpSocket::SendBuf((char*)sendBuffer, bufferSize);
+ if (haveBigPacket) SendSinglePacket(); // send too big non-merged packet
+ }
}
/// Handle the authentication waiting queue (to be completed)
void WorldSocket::SendAuthWaitQue(uint32 position)
{
- if(position == 0)
- {
- WorldPacket packet( SMSG_AUTH_RESPONSE, 1 );
- packet << uint8( AUTH_OK );
- SendPacket(&packet);
- }
- else
- {
- WorldPacket packet( SMSG_AUTH_RESPONSE, 5 );
- packet << uint8( AUTH_WAIT_QUEUE );
- packet << uint32 (position); //amount of players in queue
- SendPacket(&packet);
- }
+ if(position == 0)
+ {
+ WorldPacket packet( SMSG_AUTH_RESPONSE, 1 );
+ packet << uint8( AUTH_OK );
+ SendPacket(&packet);
+ }
+ else
+ {
+ WorldPacket packet( SMSG_AUTH_RESPONSE, 5 );
+ packet << uint8( AUTH_WAIT_QUEUE );
+ packet << uint32 (position); //amount of players in queue
+ SendPacket(&packet);
+ }
}
void WorldSocket::SizeError(WorldPacket const& packet, uint32 size) const
{
- sLog.outError("Client send packet %s (%u) with size %u but expected %u (attempt crash server?), skipped",
- LookupName(packet.GetOpcode(),g_worldOpcodeNames),packet.GetOpcode(),packet.size(),size);
+ sLog.outError("Client send packet %s (%u) with size %u but expected %u , skipped",
+ LookupName(packet.GetOpcode(),g_worldOpcodeNames),packet.GetOpcode(),packet.size(),size);
}
Index: src/game/CombatHandler.cpp
===================================================================
--- src/game/CombatHandler.cpp (revision 4845)
+++ src/game/CombatHandler.cpp (working copy)
@@ -40,7 +40,7 @@
if(!pEnemy)
{
if(GUID_HIPART(guid)!=HIGHGUID_PLAYER && GUID_HIPART(guid)!=HIGHGUID_UNIT)
- sLog.outError("WORLD: Object %u (TypeID: %u) isn't player or creature",GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)));
+ sLog.outError("CombatHandler43: Object %u (TypeID: %u) isn't player or creature",GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)));
else
sLog.outError( "WORLD: Enemy %s %u not found",(GUID_HIPART(guid)==HIGHGUID_PLAYER ? "player" : "creature"),GUID_LOPART(guid));
Index: src/game/CellImpl.h
===================================================================
--- src/game/CellImpl.h (revision 4845)
+++ src/game/CellImpl.h (working copy)
@@ -30,239 +30,192 @@
{
CellPair standing_cell = l.i_cellPair;
CellPair cell_iter;
+ if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) return;
- if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
- return;
-
- switch( (district_t)this->data.Part.reserved )
+ uint16 CurDistrict = (district_t)this->data.Part.reserved;
+ if (CurDistrict == CENTER_DISTRICT ){ m.Visit(l, visitor); return;}
+
+
+
+ switch(CurDistrict)
{
- case ALL_DISTRICT:
+ case ALL_DISTRICT:
+ {
+ CellPair update_cell(standing_cell);
+ update_cell << 1;
+ update_cell -= 1;
+ for(; abs(int(standing_cell.x_coord - update_cell.x_coord)) < 2; update_cell >> 1)
{
- CellPair update_cell(standing_cell);
- update_cell << 1;
- update_cell -= 1;
- for(; abs(int(standing_cell.x_coord - update_cell.x_coord)) < 2; update_cell >> 1)
- {
- for(cell_iter=update_cell; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter += 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
+ for(cell_iter=update_cell; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter += 1)
+ {
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
- if (cell_iter.y_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1)
- break;
- }
-
- if (cell_iter.x_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1)
- break;
- }
- break;
+ if (cell_iter.y_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1) break;
+ }
+ if (cell_iter.x_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1) break;
}
- case UPPER_LEFT_DISTRICT:
+ }
+ break;
+ case UPPER_LEFT_DISTRICT:
+ {
+ CellPair update_cell(standing_cell);
+ standing_cell << 1;
+ standing_cell -= 1;
+ for(cell_iter = update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter >> 1)
{
- CellPair update_cell(standing_cell);
- standing_cell << 1;
- standing_cell -= 1;
-
- for(cell_iter = update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter >> 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.x_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1)
- break;
- }
-
- for(cell_iter=update_cell, cell_iter += 1; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter += 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.y_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1)
- break;
- }
- break;
- }
- case UPPER_RIGHT_DISTRICT:
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.x_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1) break;
+ }
+ for(cell_iter=update_cell, cell_iter += 1; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter += 1)
+ {
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.y_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1) break;
+ }
+ }
+ break;
+ case UPPER_RIGHT_DISTRICT:
+ {
+ CellPair update_cell(standing_cell);
+ update_cell >> 1;
+ update_cell -= 1;
+ for(cell_iter = update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter << 1)
{
- CellPair update_cell(standing_cell);
- update_cell >> 1;
- update_cell -= 1;
-
- for(cell_iter = update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter << 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.x_coord == 0)
- break;
- }
-
- for(cell_iter=update_cell, cell_iter += 1; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter += 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.y_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1)
- break;
- }
-
- break;
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.x_coord == 0) break;
}
- case LOWER_LEFT_DISTRICT:
+ for(cell_iter=update_cell, cell_iter += 1; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter += 1)
{
- CellPair update_cell(standing_cell);
- update_cell << 1;
- update_cell += 1;
-
- for(cell_iter = update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter >> 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.x_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1)
- break;
- }
-
- for(cell_iter=update_cell, cell_iter -= 1; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter -= 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.y_coord == 0)
- break;
- }
-
- break;
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.y_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1) break;
+ }
+ }
+ break;
+ case LOWER_LEFT_DISTRICT:
+ {
+ CellPair update_cell(standing_cell);
+ update_cell << 1;
+ update_cell += 1;
+ for(cell_iter = update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter >> 1)
+ {
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.x_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1) break;
}
- case LOWER_RIGHT_DISTRICT:
+ for(cell_iter=update_cell, cell_iter -= 1; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter -= 1)
{
- CellPair update_cell(standing_cell);
- update_cell >> 1;
- update_cell += 1;
-
- for(cell_iter=update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter << 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.x_coord == 0)
- break;
- }
-
- for(cell_iter=update_cell, cell_iter -= 1; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter -= 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.y_coord == 0)
- break;
- }
-
- break;
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.y_coord == 0) break;
}
- case LEFT_DISTRICT:
+ }
+ break;
+ case LOWER_RIGHT_DISTRICT:
+ {
+ CellPair update_cell(standing_cell);
+ update_cell >> 1;
+ update_cell += 1;
+ for(cell_iter=update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter << 1)
{
- CellPair update_cell(standing_cell);
- update_cell << 1;
- update_cell -= 1;
-
- for(cell_iter=update_cell; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter += 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.y_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1)
- break;
- }
-
- break;
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.x_coord == 0) break;
}
- case RIGHT_DISTRICT:
+ for(cell_iter=update_cell, cell_iter -= 1; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter -= 1)
{
- CellPair update_cell(standing_cell);
- update_cell >> 1;
- update_cell -= 1;
-
- for(cell_iter=update_cell; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter += 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.y_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1)
- break;
- }
- break;
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.y_coord == 0) break;
}
- case UPPER_DISTRICT:
+ }
+ break;
+ case LEFT_DISTRICT:
+ {
+ CellPair update_cell(standing_cell);
+ update_cell << 1;
+ update_cell -= 1;
+ for(cell_iter=update_cell; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter += 1)
{
- CellPair update_cell(standing_cell);
- update_cell << 1;
- update_cell -= 1;
-
- for(cell_iter=update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter >> 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.x_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1)
- break;
- }
-
- break;
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.y_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1) break;
}
- case LOWER_DISTRICT:
+ }
+ break;
+ case RIGHT_DISTRICT:
+ {
+ CellPair update_cell(standing_cell);
+ update_cell >> 1;
+ update_cell -= 1;
+ for(cell_iter=update_cell; abs(int(standing_cell.y_coord - cell_iter.y_coord)) < 2; cell_iter += 1)
{
- CellPair update_cell(standing_cell);
- update_cell << 1;
- update_cell += 1;
-
- for(cell_iter=update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter >> 1)
- {
- Cell r_zone = RedZone::GetZone(cell_iter);
- r_zone.data.Part.nocreate = l->data.Part.nocreate;
- CellLock lock(r_zone, cell_iter);
- m.Visit(lock, visitor);
-
- if (cell_iter.x_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1)
- break;
- }
-
- break;
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.y_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1) break;
}
- case CENTER_DISTRICT:
+ }
+ break;
+ case UPPER_DISTRICT:
+ {
+ CellPair update_cell(standing_cell);
+ update_cell << 1;
+ update_cell -= 1;
+ for(cell_iter=update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter >> 1)
{
- m.Visit(l, visitor);
- break;
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.x_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1) break;
}
- default:
+ }
+ break;
+ case LOWER_DISTRICT:
+ {
+ CellPair update_cell(standing_cell);
+ update_cell << 1;
+ update_cell += 1;
+ for(cell_iter=update_cell; abs(int(standing_cell.x_coord - cell_iter.x_coord)) < 2; cell_iter >> 1)
{
- assert( false );
- break;
+ Cell r_zone = RedZone::GetZone(cell_iter);
+ r_zone.data.Part.nocreate = l->data.Part.nocreate;
+ CellLock lock(r_zone, cell_iter);
+ m.Visit(lock, visitor);
+ if (cell_iter.x_coord == TOTAL_NUMBER_OF_CELLS_PER_MAP-1) break;
}
+ }
+ break;
+ default:
+ {
+ assert( false );
+ }
+ break;
}
}
#endif
Index: src/game/MiscHandler.cpp
===================================================================
--- src/game/MiscHandler.cpp (revision 4845)
+++ src/game/MiscHandler.cpp (working copy)
@@ -451,11 +451,13 @@
uint32 newZone;
recv_data >> newZone;
- sLog.outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone);
+ sLog.outDetail("MiscHandler454: Recvd ZONE_UPDATE: %u", newZone);
if(newZone != _player->GetZoneId())
- GetPlayer()->SendInitWorldStates(); // only if really enters to new zone, not just area change, works strange...
-
+ {
+ GetPlayer()->DeleteThreatList(); //hf022: fix player stuck in combat after zone change
+ GetPlayer()->SendInitWorldStates(); // only if really enters to new zone, not just area change, works strange...
+ }
GetPlayer()->UpdateZone(newZone);
}
@@ -758,7 +760,7 @@
{
CHECK_PACKET_SIZE(recv_data,8);
- sLog.outDetail("WORLD: Received CMSG_RECLAIM_CORPSE");
+ sLog.outDetail("MiscHandler761: Received CMSG_RECLAIM_CORPSE");
if (GetPlayer()->isAlive())
return;
@@ -796,7 +798,7 @@
{
CHECK_PACKET_SIZE(recv_data,8+1);
- sLog.outDetail("WORLD: Received CMSG_RESURRECT_RESPONSE");
+ sLog.outDetail("MiscHandler799: Received CMSG_RESURRECT_RESPONSE");
if(GetPlayer()->isAlive())
return;
@@ -951,38 +953,42 @@
ItemPrototype const *pProto = objmgr.GetItemPrototype(ReqItem);
// pProto != NULL checked and fixed (if need with error output) at server load and don't must be happens here
- // item and level or GM
- if( (!pProto || GetPlayer()->HasItemCount(ReqItem, 1)) &&
- (GetPlayer()->getLevel() >= at->requiredLevel || sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL))
- || GetPlayer()->isGameMaster() )
- GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,true,false);
- else
- {
- std::stringstream msgstr;
- SendAreaTriggerMessage(LANG_LEVEL_MINREQUIRED "%u and have item %s" LANG_LEVEL_MINREQUIRED_END,(uint32)at->requiredLevel,pProto->Name1);
- }
+ // SantaCl item and level or GM
+// if( (!pProto || GetPlayer()->HasItemCount(ReqItem, 1)) &&
+// (GetPlayer()->getLevel() >= at->requiredLevel || sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL))
+// || GetPlayer()->isGameMaster() )
+ GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,true,true);
+// SendAreaTriggerMessage("959: Attempting to tele you to ",Trigger_ID );
+// else
+// {
+// std::stringstream msgstr;
+// SendAreaTriggerMessage(LANG_LEVEL_MINREQUIRED "%u and have item %s" LANG_LEVEL_MINREQUIRED_END,(uint32)at->requiredLevel,pProto->Name1);
+ // }
}
else
{
- if(GetPlayer()->getLevel() >= at->requiredLevel || sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL) || GetPlayer()->isGameMaster())
- GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,true,false);
- else
- {
- SendAreaTriggerMessage(LANG_LEVEL_MINREQUIRED "%u" LANG_LEVEL_MINREQUIRED_END,(uint32)at->requiredLevel );
- }
+ //SantaCl if(GetPlayer()->getLevel() >= at->requiredLevel || sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL) || GetPlayer()->isGameMaster())
+
+// if(GetPlayer()->getLevel() >= at->requiredLevel || sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL) || GetPlayer()->isGameMaster())
+ GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,true,true);
+// SendAreaTriggerMessage("971: Attempting to tele you to ",Trigger_ID );
+// else
+// {
+// SendAreaTriggerMessage(LANG_LEVEL_MINREQUIRED "%u" LANG_LEVEL_MINREQUIRED_END,(uint32)at->requiredLevel );
+// }
}
}
}
void WorldSession::HandleUpdateAccountData(WorldPacket &/*recv_data*/)
{
- sLog.outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
+ sLog.outDetail("MiscHandler983: Received CMSG_UPDATE_ACCOUNT_DATA");
//recv_data.hexlike();
}
void WorldSession::HandleRequestAccountData(WorldPacket& /*recv_data*/)
{
- sLog.outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
+ sLog.outDetail("MiscHandler989: Received CMSG_REQUEST_ACCOUNT_DATA");
//recv_data.hexlike();
}
Index: src/game/ArenaTeam.cpp
===================================================================
--- src/game/ArenaTeam.cpp (revision 4845)
+++ src/game/ArenaTeam.cpp (working copy)
@@ -345,7 +345,7 @@
}
}
session->SendPacket(&data);
- sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER");
+ sLog.outDebug("ArenaTeam348: Sent SMSG_ARENA_TEAM_ROSTER");
}
void ArenaTeam::Query(WorldSession *session)
@@ -360,7 +360,7 @@
data << BorderColor; // border color?
data << BackgroundColor; // background color?
session->SendPacket(&data);
- sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE");
+ sLog.outDebug("ArenaTeam363: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE");
}
void ArenaTeam::Stats(WorldSession *session)
Index: src/game/Item.cpp
===================================================================
--- src/game/Item.cpp (revision 4845)
+++ src/game/Item.cpp (working copy)
@@ -83,7 +83,7 @@
SpellEntry const *spellInfo = sSpellStore.LookupEntry(set->spells[x]);
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %u in items set %u effects", set->spells[x],setid);
+ sLog.outError("Item: unknown spell id %u in items set %u effects", set->spells[x],setid);
break;
}
@@ -300,7 +300,9 @@
ItemPrototype const *Item::GetProto() const
{
- return objmgr.GetItemPrototype(GetUInt32Value(OBJECT_FIELD_ENTRY));
+ ItemPrototype const *proto = objmgr.GetItemPrototype(GetUInt32Value(OBJECT_FIELD_ENTRY));
+ if(proto->ItemId) return proto;
+ return false;
}
Player* Item::GetOwner()const
Index: src/game/GameObject.cpp
===================================================================
--- src/game/GameObject.cpp (revision 4845)
+++ src/game/GameObject.cpp (working copy)
@@ -552,6 +552,7 @@
bool GameObject::IsTransport() const
{
+ return false; //hf021: turn off transports
// If something is marked as a transport, don't transmit an out of range packet for it.
GameObjectInfo const * gInfo = GetGOInfo();
if(!gInfo) return false;
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp (revision 4845)
+++ src/game/Unit.cpp (working copy)
@@ -398,554 +398,486 @@
void Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchools damageSchool, SpellEntry const *spellProto, uint32 procFlag, bool durabilityLoss)
{
- if (!pVictim->isAlive() || pVictim->isInFlight() || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
- return;
+ //In all cases...
+ //{
+ if (!pVictim->isAlive())
+ {
+ sLog.outError("ERROR: %d dmg dealt to something dead!? %u",damage,pVictim->GetGUID());
+ AttackStop();
+ pVictim->CombatStop(true);
+ pVictim->SetHealth(0);
+ pVictim->setDeathState(JUST_DIED);
+ pVictim->addUnitState(UNIT_STAT_DIED);
+ pVictim->getHostilRefManager().deleteReferences();
+ pVictim->DeleteThreatList();
+ return;
+ }
+ if (!isAlive())
+ {
+ sLog.outError("ERROR: %d dmg dealt from something dead!? %u",damage,GetGUID());
+ AttackStop();
+ CombatStop(true);
+ SetHealth(0);
+ setDeathState(JUST_DIED);
+ addUnitState(UNIT_STAT_DIED);
+ getHostilRefManager().deleteReferences();
+ DeleteThreatList();
+ return;
+ }
+ if(!damage) return;
- //You don't lose health from damage taken from another player while in a sanctuary
- //You still see it in the combat log though
- if(pVictim != this && GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- const AreaTableEntry *area = GetAreaEntryByAreaID(pVictim->GetAreaId());
- if(area && area->flags & 0x800) //sanctuary
- return;
- }
+ bool duel_hasEnded = false;
+ uint32 health = pVictim->GetHealth();
+ //sLog.outDetail("%d dmg dealt from %u to %u ",damage,GetGUID(),pVictim->GetGUIDLow());
- // remove affects from victim (including from 0 damage and DoTs)
- if(pVictim != this)
- pVictim->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ // root type spells do not dispell the root effect
+ if(!spellProto || spellProto->Mechanic != MECHANIC_ROOT) pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_ROOT, damage);
- // remove affects from attacker at any non-DoT damage (including 0 damage)
- if( damagetype != DOT)
- {
- RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
- RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ //}
- if(pVictim != this)
- RemoveSpellsCausingAura(SPELL_AURA_MOD_INVISIBILITY);
- }
+ uint8 DmgMode = 0;
+ //Player-vs-NPC...
+ if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER) DmgMode = 0;
+ //NPC-vs-Player...
+ if(GetTypeId() != TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER) DmgMode = 1;
+ //NPC-vs-NPC...
+ if(GetTypeId() != TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER) DmgMode = 2;
+ //Player-vs-Player...
+ if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER) DmgMode = 3;
+ switch(DmgMode)
+ {
+ case 0://Player-vs-NPC...
+ {
+// if (((Creature*)pVictim)->IsInEvadeMode()) return;
+ }
+ break;
- //Script Event damage Deal
- if( GetTypeId()== TYPEID_UNIT && ((Creature *)this)->AI())
- ((Creature *)this)->AI()->DamageDeal(pVictim, damage);
- //Script Event damage taken
- if( pVictim->GetTypeId()== TYPEID_UNIT && ((Creature *)pVictim)->AI() )
- ((Creature *)pVictim)->AI()->DamageTaken(this, damage);
+ case 1://NPC-vs-Player...
+ {
+ if (urand(0,300) == 10) ((Player*)pVictim)->DurabilityLossAll(0.05f); // durability loss
+ }
+ break;
- if(!damage)
- {
- // Rage from physical damage received .
- if(cleanDamage && cleanDamage->damage && damageSchool==SPELL_SCHOOL_NORMAL && pVictim->GetTypeId() == TYPEID_PLAYER && (pVictim->getPowerType() == POWER_RAGE))
- ((Player*)pVictim)->RewardRage(cleanDamage->damage, 0, false);
+ case 2://NPC-vs-NPC...
+ {
+ }
+ break;
- return;
- }
+ case 3://Player-vs-Player...
+ {
- pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_FEAR, damage);
- // root type spells do not dispell the root effect
- if(!spellProto || spellProto->Mechanic != MECHANIC_ROOT)
- pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_ROOT, damage);
+ if(((Player*)pVictim)->InBattleGround())
+ {
+ Player *killer = ((Player*)this);
+ if(killer != ((Player*)pVictim))
+ if(BattleGround *bg = killer->GetBattleGround()) bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damage);
+ }
+ }
+ break;
- if(pVictim->GetTypeId() != TYPEID_PLAYER)
- {
- //pVictim->SetInFront(this);
- // no xp,health if type 8 /critters/
- if ( pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
- {
- pVictim->setDeathState(JUST_DIED);
- pVictim->SetHealth(0);
- pVictim->CombatStop(true);
- pVictim->DeleteThreatList();
+ default:
+ {
+ }
+ break;
- // allow loot only if has loot_id in creature_template
- CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo();
- if(cInfo && cInfo->lootid)
- pVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
- // some critters required for quests
- if(GetTypeId() == TYPEID_PLAYER)
- ((Player*)this)->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
-
- return;
- }
-
- if(!pVictim->isInCombat() && ((Creature*)pVictim)->AI())
- ((Creature*)pVictim)->AI()->AttackStart(this);
- }
-
- DEBUG_LOG("DealDamageStart");
-
- uint32 health = pVictim->GetHealth();
- sLog.outDetail("deal dmg:%d to health:%d ",damage,health);
-
- // duel ends when player has 1 or less hp
- bool duel_hasEnded = false;
- if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->duel && damage >= (health-1))
- {
- // prevent kill only if killed in duel and killed by opponent or opponent controlled creature
- if(((Player*)pVictim)->duel->opponent==this || ((Player*)pVictim)->duel->opponent->GetGUID() == GetOwnerGUID())
- damage = health-1;
-
- duel_hasEnded = true;
- }
- //Get in CombatState
- if(pVictim != this && damagetype != DOT)
- {
- SetInCombat();
- pVictim->SetInCombat();
- }
-
- // Rage from Damage made (only from direct weapon damage)
- if( cleanDamage && damagetype==DIRECT_DAMAGE && this != pVictim && GetTypeId() == TYPEID_PLAYER && (getPowerType() == POWER_RAGE))
- {
- uint32 weaponSpeedHitFactor;
-
- switch(cleanDamage->attackType)
+ //all dmg dealers...
+ //{
+ RemoveSpellsCausingAura(SPELL_AURA_MOD_INVISIBILITY);
+ RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ if (GetTypeId() == TYPEID_UNIT) //as NPC
+ {
+ //Script Event damage Deal
+ if(((Creature *)this)->AI()) ((Creature *)this)->AI()->DamageDeal(pVictim, damage);
+ }
+ else //as Player
+ {
+ // Rage from Damage made (only from direct weapon damage)
+ if(getPowerType() == POWER_RAGE)
+ {
+ if(cleanDamage && damagetype==DIRECT_DAMAGE && this != pVictim)
{
- case BASE_ATTACK:
- {
- if(cleanDamage->hitOutCome == MELEE_HIT_CRIT)
- weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 7);
- else
- weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 3.5f);
+ uint32 weaponSpeedHitFactor;
+ if (cleanDamage->attackType == BASE_ATTACK)
+ {
+ if(cleanDamage->hitOutCome == MELEE_HIT_CRIT)
+ weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 7);
+ else
+ weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 3.5f);
+ }
+ else
+ {
+ if(cleanDamage->hitOutCome == MELEE_HIT_CRIT)
+ weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 3.5f);
+ else
+ weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 1.75f);
+ }
+ ((Player*)this)->RewardRage(damage, weaponSpeedHitFactor, true);
+ }
+ }
- ((Player*)this)->RewardRage(damage, weaponSpeedHitFactor, true);
+ }
+ //}
- break;
- }
- case OFF_ATTACK:
- {
- if(cleanDamage->hitOutCome == MELEE_HIT_CRIT)
- weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 3.5f);
- else
- weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType)/1000.0f * 1.75f);
+ //all victims...
+ //{
+ pVictim->RemoveSpellsCausingAura(SPELL_AURA_MOD_INVISIBILITY);
+ pVictim->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_FEAR, damage);
- ((Player*)this)->RewardRage(damage, weaponSpeedHitFactor, true);
+
+ if (pVictim->GetTypeId() != TYPEID_PLAYER) //as NPC
+ {
+ //Script Event damage taken
+ if(((Creature *)pVictim)->AI() ) ((Creature *)pVictim)->AI()->DamageTaken(this, damage);
- break;
- }
- case RANGED_ATTACK:
- break;
- }
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER)
- {
- if(((Player*)pVictim)->InBattleGround())
- {
- Player *killer = ((Player*)this);
- if(killer != ((Player*)pVictim))
- if(BattleGround *bg = killer->GetBattleGround())
- bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damage);
- }
- }
-
- if (health <= damage)
- {
- // battleground things
- if(pVictim->GetTypeId() == TYPEID_PLAYER && (((Player*)pVictim)->InBattleGround()))
- {
- Player *killed = ((Player*)pVictim);
- Player *killer = NULL;
- if(GetTypeId() == TYPEID_PLAYER)
- killer = ((Player*)this);
- else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
- {
- Unit *owner = GetOwner();
- if(owner && owner->GetTypeId() == TYPEID_PLAYER)
- killer = ((Player*)owner);
- }
-
- if(killer)
- {
- if(BattleGround *bg = killed->GetBattleGround())
- {
- bg->HandleKillPlayer(killed, killer); // drop flags and etc
- // add +1 deaths
- bg->UpdatePlayerScore(killed, SCORE_DEATHS, 1);
- if(killer)
- // add +1 kills
- bg->UpdatePlayerScore(killer, SCORE_HONORABLE_KILLS, 1);
- // to be able to remove insignia
- killed->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE );
- }
- }
- }
-
- DEBUG_LOG("DealDamage: victim just died");
-
- DEBUG_LOG("DealDamageAttackStop");
- AttackStop();
+ // no xp,health if type 8 /critters/
+ if ( pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
+ {
+ pVictim->setDeathState(JUST_DIED);
+ pVictim->SetHealth(0);
pVictim->CombatStop(true);
+ pVictim->DeleteThreatList();
+ // allow loot only if has loot_id in creature_template
+ CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo();
+ if(cInfo && cInfo->lootid) pVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ // some critters required for quests
+ if(GetTypeId() == TYPEID_PLAYER) ((Player*)this)->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
+ return;
+ }
+ if(!pVictim->isInCombat() && ((Creature*)pVictim)->AI()) ((Creature*)pVictim)->AI()->AttackStart(this);
- // if talent known but not triggered (check priest class for speedup check)
- Aura* spiritOfRedemtionTalentReady = NULL;
- if( (!spellProto || spellProto->Id != 27795 ) && // not called from SPELL_AURA_SPIRIT_OF_REDEMPTION
- pVictim->GetTypeId()==TYPEID_PLAYER && pVictim->getClass()==CLASS_PRIEST )
+ }
+ else //as Player
+ {
+ pVictim->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+ if(cleanDamage && cleanDamage->damage && damageSchool==SPELL_SCHOOL_NORMAL && (pVictim->getPowerType() == POWER_RAGE))
+ ((Player*)pVictim)->RewardRage(cleanDamage->damage, 0, false);
+ // duel ends when player has 1 or less hp
+ if(((Player*)pVictim)->duel)
+ {
+ if(damage >= (health-1))
{
- AuraList const& vDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
- for(AuraList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
- {
- if((*itr)->GetSpellProto()->SpellIconID==1654)
- {
- spiritOfRedemtionTalentReady = *itr;
- break;
- }
- }
- }
+ // prevent kill only if killed in duel and killed by opponent or opponent controlled creature
+ if(((Player*)pVictim)->duel->opponent==this || ((Player*)pVictim)->duel->opponent->GetGUID() == GetOwnerGUID()) damage = health-1;
+ Player *he = (Player*)pVictim;
+ CombatStop();
+ if (IsNonMeleeSpellCasted(true)) InterruptNonMeleeSpells(true);
+ if(he->duel->opponent!=this)
+ {
+ he->duel->opponent->CombatStop();
+ if(he->duel->opponent->IsNonMeleeSpellCasted(true)) he->duel->opponent->InterruptNonMeleeSpells(true);
+ }
+ if(he->duel->opponent!=this) he->duel->opponent->CombatStop();
+ CombatStop();
+ he->CombatStop();
+ if(he->IsNonMeleeSpellCasted(true)) he->InterruptNonMeleeSpells(true);
- DEBUG_LOG("SET JUST_DIED");
- if(!spiritOfRedemtionTalentReady)
- pVictim->setDeathState(JUST_DIED);
+ he->SetHealth(1);
+ he->CastSpell(he, 7267, true); // beg
+ he->DuelComplete(1);
+ }
+ }
+ }
+ //}
- DEBUG_LOG("DealDamageHealth1");
+ if (health <= damage)
+ {
+ bool PvP = false;
+ AttackStop();
+ pVictim->CombatStop(true);
+ pVictim->SetHealth(0);
+ pVictim->setDeathState(JUST_DIED);
- if(spiritOfRedemtionTalentReady)
- {
- // save value before aura remove
- uint32 ressSpellId = pVictim->GetUInt32Value(PLAYER_SELF_RES_SPELL);
- //Remove all expected to remove at death auras (most important negative case like DoT or periodic triggers)
- pVictim->RemoveAllAurasOnDeath();
-
- // restore for use at real death
- pVictim->SetUInt32Value(PLAYER_SELF_RES_SPELL,ressSpellId);
-
- // FORM_SPIRITOFREDEMPTION and related auras
- pVictim->CastSpell(pVictim,27827,true,NULL,spiritOfRedemtionTalentReady);
- }
+ //Player just died...
+ if(pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ sLog.outDetail("578: %u kills player %u",GetGUID(),pVictim->GetGUID());
+ PvP = true;
+ if(((Player*)pVictim)->InBattleGround())
+ {
+ Player *killed = ((Player*)pVictim);
+ Player *killer = NULL;
+ if(GetTypeId() == TYPEID_PLAYER)
+ killer = ((Player*)this);
else
- pVictim->SetHealth(0);
-
- // Call KilledUnit for creatures
- if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())
- ((Creature*)this)->AI()->KilledUnit(pVictim);
+ if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
+ {
+ Unit *owner = GetOwner();
+ if(owner && owner->GetTypeId() == TYPEID_PLAYER) killer = ((Player*)owner);
+ }
- // 10% durability loss on death
- // clean InHateListOf
- if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ if(killer)
{
- if (GetTypeId() != TYPEID_PLAYER && durabilityLoss)
- {
- DEBUG_LOG("We are dead, loosing 10 percents durability");
- ((Player*)pVictim)->DurabilityLossAll(0.10);
- // durability lost message
- WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0);
- ((Player*)pVictim)->GetSession()->SendPacket(&data);
- }
- pVictim->getHostilRefManager().deleteReferences();
-
- Pet *pet = pVictim->GetPet();
- if(pet && pVictim->GetTypeId() != TYPEID_PLAYER)
- {
- pet->setDeathState(JUST_DIED);
- pet->CombatStop(true);
- pet->SetHealth(0);
- pet->addUnitState(UNIT_STAT_DIED);
- pet->getHostilRefManager().deleteReferences();
- }
+ if(BattleGround *bg = killed->GetBattleGround())
+ {
+ bg->HandleKillPlayer(killed, killer); // drop flags and etc
+ bg->UpdatePlayerScore(killed, SCORE_DEATHS, 1); // add +1 deaths
+ bg->UpdatePlayerScore(killer, SCORE_HONORABLE_KILLS, 1); // add +1 kills
+ killed->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE ); // to be able to remove insignia
+ }
}
- else // creature died
- {
- DEBUG_LOG("DealDamageNotPlayer");
- if(((Creature*)pVictim)->isPet())
- pVictim->getHostilRefManager().deleteReferences();
- else
- {
- pVictim->DeleteThreatList();
- pVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
- }
- // Call creature just died function
- if (((Creature*)pVictim)->AI())
- ((Creature*)pVictim)->AI()->JustDied(this);
- }
+ }
- //judge if GainXP, Pet kill like player kill,kill pet not like PvP
- bool PvP = false;
- Player *player = NULL;
- if(GetTypeId() == TYPEID_PLAYER)
- {
- player = (Player*)this;
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- PvP = true;
- Unit* pet = NULL;
+ if(pVictim->getClass()==CLASS_PRIEST)
+ {
+ // if talent known but not triggered (check priest class for speedup check)
+ Aura* spiritOfRedemtionTalentReady = NULL;
+ if( (!spellProto || spellProto->Id != 27795 ) && pVictim->getClass()==CLASS_PRIEST )
+ {
+ AuraList const& vDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
+ for(AuraList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
+ {
+ if((*itr)->GetSpellProto()->SpellIconID==1654)
+ {
+ spiritOfRedemtionTalentReady = *itr;
+ break;
+ }
+ }
+ }
+ if(!spiritOfRedemtionTalentReady)
+ pVictim->setDeathState(JUST_DIED);
+ else
+ {
+ // save value before aura remove
+ uint32 ressSpellId = pVictim->GetUInt32Value(PLAYER_SELF_RES_SPELL);
+ //Remove all expected to remove at death auras (most important negative case like DoT or periodic triggers)
+ pVictim->RemoveAllAurasOnDeath();
+ // restore for use at real death
+ pVictim->SetUInt32Value(PLAYER_SELF_RES_SPELL,ressSpellId);
+ // FORM_SPIRITOFREDEMPTION and related auras
+ pVictim->CastSpell(pVictim,27827,true,NULL,spiritOfRedemtionTalentReady);
+ }
+ }
- if(player->GetPetGUID() && (pet = player->GetPet()))
- pet->ClearInCombat();
+ // clean InHateListOf
+ // 10% durability loss on death
+ if (GetTypeId() != TYPEID_PLAYER) // only loose durability if player killed by NPC!
+ {
+ ((Player*)pVictim)->DurabilityLossAll(0.10);
+ // durability lost message
+ WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0);
+ ((Player*)pVictim)->GetSession()->SendPacket(&data);
+ }
+ Pet *pet = pVictim->GetPet();
+ if(pet)
+ {
+ pet->setDeathState(JUST_DIED);
+ pet->CombatStop(true);
+ pet->SetHealth(0);
+ pet->addUnitState(UNIT_STAT_DIED);
+ pet->getHostilRefManager().deleteReferences();
+ }
+ }
+ else //NPC just died...
+ {
+ pVictim->addUnitState(UNIT_STAT_DIED);
+ pVictim->getHostilRefManager().deleteReferences();
+ pVictim->DeleteThreatList();
+ Player *player = NULL;
+ sLog.outDetail("662: %u kills NPC.",GetGUID());
+ if(((Creature*)pVictim)->isPet())
+ {
+ pVictim->getHostilRefManager().deleteReferences();
+ }
+ else
+ {
+ pVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
- if(player->GetCharmGUID() && (pet = player->GetCharm()))
- pet->ClearInCombat();
- }
- // FIXME: or charmed (can be player). Maybe must be check before GetTypeId() == TYPEID_PLAYER
- else if(GetCharmerOrOwnerGUID()) // Pet or timed creature, etc
- {
- Unit* pet = this;
- Unit* owner = pet->GetCharmerOrOwner();
+ if(GetTypeId() == TYPEID_PLAYER) //set player if the killer was a player OR the pet of a player
+ {
+ player =(Player*)this;
+ }
+ else
+ {
+ if( ((Creature*)this)->isPet() || ((Creature*)this)->isCharmed() )
+ {
+ sLog.outDetail("701: pet kills NPC.");
+ CombatStop(true);
+ Unit *owner = GetCharmerOrOwner();
+ if(owner && owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ player =(Player*)GetCharmerOrOwner();
+ sLog.outDetail("706: pet of %u kills NPC.",player->GetGUID());
+ }
+ }
+ }
- if(owner && owner->GetTypeId() == TYPEID_PLAYER)
- {
- player = (Player*)owner;
- player->ClearInCombat();
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- PvP = true;
- }
+ //deal with killer combat state/xp...
+ if(!PvP && player) //Killer is a Player or was a players pet...
+ {
+ //deal with player XP (xp reduction from grouped players has been removed!)
+ uint32 xp = 0;
+ player->CombatStop(true);
+ Group *pGroup = player->GetGroup();
+ if(pGroup) //killer is in group
+ {
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player *pGroupGuy = pGroup->GetMemberForXPAtKill(itr->getSource(),pVictim);
+ if(!pGroupGuy) continue;
+ xp = IsNoDamageXPArea(player->GetAreaId()) ? 0 : MaNGOS::XP::Gain(pGroupGuy, pVictim);
+ if(pGroupGuy->GetTypeId() == TYPEID_PLAYER)
+ {
+ pGroupGuy->RewardReputation(pVictim,1);
+ pGroupGuy->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
+ if(xp)
+ {
+ sLog.outDetail("692: Player %u gains %u xp",pGroupGuy->GetGUID(),xp);
+ pGroupGuy->GiveXP(xp, pVictim);
+ pGroupGuy->ProcDamageAndSpell(pVictim,PROC_FLAG_KILL_XP_GIVER,PROC_FLAG_NONE);
+ if(Pet* pet = pGroupGuy->GetPet()) pet->GivePetXP(xp/2);
+ }
+ }
+ }
+ }
+ else //killer not in group
+ {
+ xp = IsNoDamageXPArea(player->GetAreaId()) ? 0 : MaNGOS::XP::Gain(player, pVictim);
+ player->RewardReputation(pVictim,1);
+ player->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
+ if(xp)
+ {
+ sLog.outDetail("692: Player %u gains %u xp",player->GetGUID(),xp);
+ player->GiveXP(xp, pVictim);
+ player->ProcDamageAndSpell(pVictim,PROC_FLAG_KILL_XP_GIVER,PROC_FLAG_NONE);
+ }
+ }
- if(pet->GetTypeId()==TYPEID_UNIT && ((Creature*)pet)->isPet())
- {
- uint32 petxp = MaNGOS::XP::BaseGain(getLevel(), pVictim->getLevel());
- ((Pet*)pet)->GivePetXP(petxp);
- }
- }
+ //deal with pet/pet xp...
+ Unit* pet = NULL;
+ if(player->GetPetGUID())
+ {
+ if(pet = player->GetPet())
+ {
+ pet->ClearInCombat();
+ uint32 petxp = MaNGOS::XP::BaseGain(getLevel(), pVictim->getLevel());
+ ((Pet*)pet)->GivePetXP(petxp);
+ }
+ }
+ else if(player->GetCharmGUID())
+ {
+ if(pet = player->GetCharm()) pet->ClearInCombat();
+ }
+ }
+ else//killer is an NPC;
+ {
+ PvP = false;
+ if(!player)
+ {
+ //deal with attacker scripts only if killer was an NPC.
+ if (((Creature*)this)->AI()) ((Creature*)this)->AI()->KilledUnit(pVictim);
+ if (((Creature*)pVictim)->AI()) ((Creature*)pVictim)->AI()->JustDied(this);
+ }
+ }
+ }
+ }
+ // victim is NOT going to be killed.
+ else
+ {
+ if(damagetype != DOT)
+ {
+ //start melee attacks only after melee hit
+ Attack(pVictim,(damagetype == DIRECT_DAMAGE));
+ }
- // self or owner of pet
- if(player)
- {
- if(player!=pVictim)
- {
- // prepare data for near group iteration (PvP and !PvP cases
- uint32 xp = 0;
- bool honored_kill = false;
+ if(pVictim->GetTypeId() == TYPEID_PLAYER) //Victim is a Player...
+ {
- Group *pGroup = player->GetGroup();
- if(pGroup)
- {
- uint32 count = 0;
- uint32 sum_level = 0;
- Player* member_with_max_level = NULL;
+ if(pVictim->getPowerType() == POWER_RAGE)
+ {
+ uint32 rage_damage = damage + (cleanDamage ? cleanDamage->damage : 0);
+ ((Player*)pVictim)->RewardRage(rage_damage, 0, false);
+ }
- pGroup->GetDataForXPAtKill(pVictim,count,sum_level,member_with_max_level);
+ if(pVictim->GetHealth()*5 < pVictim->GetMaxHealth())
+ {
+ uint32 procVictim = PROC_FLAG_NONE;
+ // if just dropped below 20% (for CheatDeath)
+ if((pVictim->GetHealth()+damage)*5 > pVictim->GetMaxHealth()) procVictim = PROC_FLAG_LOW_HEALTH;
+ ProcDamageAndSpell(pVictim,PROC_FLAG_TARGET_LOW_HEALTH,procVictim);
+ }
+ // auras to remove because of damage.
+ AuraMap& vAuras = pVictim->GetAuras();
+ bool remove = true;
+ for (AuraMap::iterator i = vAuras.begin(), next; i != vAuras.end(); i = next)
+ {
+ const SpellEntry *se = i->second->GetSpellProto();
+ next = i; next++;
+ if( se->AuraInterruptFlags & AURA_INTERRUPT_FLAG_DAMAGE )
+ {
+ if (se->procFlags & (1<<3))
+ {
+ if (!roll_chance_i(se->procChance)) remove = false;
+ }
+ if (remove)
+ {
+ pVictim->RemoveAurasDueToSpell(i->second->GetId());
+ // FIXME: this may cause the auras with proc chance to be rerolled several times
+// break;
+ next = vAuras.begin();
+ }
+ }
+ }
+ }
+ else //Victim is an NPC...
+ {
+ if(spellProto && IsDamageToThreatSpell(spellProto)) damage *= 2;
+ pVictim->AddThreat(this, damage, damageSchool, spellProto);
+ }
- if(member_with_max_level)
- {
- xp = PvP || IsNoDamageXPArea(player->GetAreaId()) ? 0 : MaNGOS::XP::Gain(member_with_max_level, pVictim);
-
- // skip in check PvP case (for speed, not used)
- bool is_raid = PvP ? false : MapManager::Instance().GetBaseMap(player->GetMapId())->IsRaid() && pGroup->isRaidGroup();
- bool is_dungeon = PvP ? false : MapManager::Instance().GetBaseMap(player->GetMapId())->IsDungeon();
- float group_rate = MaNGOS::XP::xp_in_group_rate(count,is_raid);
-
- for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
- {
- Player *pGroupGuy = pGroup->GetMemberForXPAtKill(itr->getSource(),pVictim);
- if(!pGroupGuy)
- continue;
-
- // honor can be in PvP and !PvP (racial leader) cases
- if(pGroupGuy->RewardHonor(pVictim,count) && player==pGroupGuy)
- honored_kill = true;
-
- // xp and reputation only in !PvP case
- if(!PvP)
- {
- float rate = group_rate * float(pGroupGuy->getLevel()) / sum_level;
-
- // if is in dungeon then all receive full reputation at kill
- pGroupGuy->RewardReputation(pVictim,is_dungeon ? 1.0f : rate);
-
- uint32 itr_xp = uint32(xp*rate);
-
- pGroupGuy->GiveXP(itr_xp, pVictim);
- if(Pet* pet = pGroupGuy->GetPet())
- {
- pet->GivePetXP(itr_xp/2);
- }
-
- // normal creature (not pet/etc) can be only in !PvP case
- if(pVictim->GetTypeId()==TYPEID_UNIT)
- pGroupGuy->KilledMonster(pVictim->GetEntry(), pVictim->GetGUID());
- }
- }
- }
- }
- else // if (!pGroup)
- {
- xp = PvP || IsNoDamageXPArea(player->GetAreaId()) ? 0 : MaNGOS::XP::Gain(player, pVictim);
-
- // honor can be in PvP and !PvP (racial leader) cases
- if(player->RewardHonor(pVictim,1))
- honored_kill = true;
-
- // xp and reputation only in !PvP case
- if(!PvP)
- {
- player->RewardReputation(pVictim,1);
- player->GiveXP(xp, pVictim);
- if(Pet* pet = player->GetPet())
- {
- pet->GivePetXP(xp);
- }
-
- // normal creature (not pet/etc) can be only in !PvP case
- if(pVictim->GetTypeId()==TYPEID_UNIT)
- player->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
- }
- }
-
- if(xp || honored_kill)
- player->ProcDamageAndSpell(pVictim,PROC_FLAG_KILL_XP_GIVER,PROC_FLAG_NONE);
- }
- }
- else // if (player)
+ //ALL still living victims...
+ if(pVictim->getTransForm() && pVictim->hasUnitState(UNIT_STAT_CONFUSED)) pVictim->RemoveAurasDueToSpell(pVictim->getTransForm());
+ //set in CombatState
+ if (damagetype == DIRECT_DAMAGE)
+ {
+ if(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL])
+ {
+ if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_CASTING)
{
- DEBUG_LOG("Monster kill Monster");
+ uint32 channelInterruptFlags = pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->ChannelInterruptFlags;
+ if( channelInterruptFlags & CHANNEL_FLAG_DELAY )
+ {
+ pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->DelayedChannel((int32)(0.25f * GetDuration(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo)));
+ }
+ else if( (channelInterruptFlags & (CHANNEL_FLAG_DAMAGE | CHANNEL_FLAG_DAMAGE2)) )
+ {
+ pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL);
+ }
}
-
- // last damage from duel opponent or opponent controlled creature?
- if(duel_hasEnded)
+ else if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_DELAYED) // break channeled spell in delayed state on damage
{
- assert(pVictim->GetTypeId()==TYPEID_PLAYER);
- Player *he = (Player*)pVictim;
-
- assert(he->duel);
-
- CombatStop(); // for case killed by pet
- if (IsNonMeleeSpellCasted(true))
- InterruptNonMeleeSpells(true);
- if(he->duel->opponent!=this)
- {
- he->duel->opponent->CombatStop();
- if(he->duel->opponent->IsNonMeleeSpellCasted(true))
- he->duel->opponent->InterruptNonMeleeSpells(true);
- }
- he->CombatStop();
- if(he->IsNonMeleeSpellCasted(true))
- he->InterruptNonMeleeSpells(true);
-
- he->DuelComplete(0);
+ pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL);
}
+ }
}
- else // if (health <= damage)
+ if(pVictim != this && damagetype != DOT)
{
- DEBUG_LOG("DealDamageAlive");
-
- pVictim->ModifyHealth(- (int32)damage);
-
- // Check if health is below 20% (apply damage before to prevent case when after ProcDamageAndSpell health < damage
- if(pVictim->GetHealth()*5 < pVictim->GetMaxHealth())
- {
- uint32 procVictim = PROC_FLAG_NONE;
-
- // if just dropped below 20% (for CheatDeath)
- if((pVictim->GetHealth()+damage)*5 > pVictim->GetMaxHealth())
- procVictim = PROC_FLAG_LOW_HEALTH;
-
- ProcDamageAndSpell(pVictim,PROC_FLAG_TARGET_LOW_HEALTH,procVictim);
- }
-
- if(damagetype != DOT)
- {
- //start melee attacks only after melee hit
- Attack(pVictim,(damagetype == DIRECT_DAMAGE));
- }
-
- // polymorphed and other negative transformed cases
- if(pVictim->getTransForm() && pVictim->hasUnitState(UNIT_STAT_CONFUSED))
- pVictim->RemoveAurasDueToSpell(pVictim->getTransForm());
-
- if (pVictim->GetTypeId() != TYPEID_PLAYER)
- {
- if(spellProto && IsDamageToThreatSpell(spellProto))
- damage *= 2;
- pVictim->AddThreat(this, damage, damageSchool, spellProto);
- }
- else // victim is a player
- {
- // Rage from damage received
- if(this != pVictim && pVictim->getPowerType() == POWER_RAGE)
- {
- uint32 rage_damage = damage + (cleanDamage ? cleanDamage->damage : 0);
- ((Player*)pVictim)->RewardRage(rage_damage, 0, false);
- }
-
- // random durability for items (HIT)
- if (urand(0,300) == 10)
- {
- DEBUG_LOG("HIT: We decrease durability with 5 percent");
- ((Player*)pVictim)->DurabilityLossAll(0.05f);
- }
- }
-
- // TODO: Store auras by interrupt flag to speed this up.
- AuraMap& vAuras = pVictim->GetAuras();
- for (AuraMap::iterator i = vAuras.begin(), next; i != vAuras.end(); i = next)
- {
- const SpellEntry *se = i->second->GetSpellProto();
- next = i; next++;
- if( se->AuraInterruptFlags & AURA_INTERRUPT_FLAG_DAMAGE )
- {
- bool remove = true;
- if (se->procFlags & (1<<3))
- {
- if (!roll_chance_i(se->procChance))
- remove = false;
- }
- if (remove)
- {
- pVictim->RemoveAurasDueToSpell(i->second->GetId());
- // FIXME: this may cause the auras with proc chance to be rerolled several times
- next = vAuras.begin();
- }
- }
- }
-
- if (damagetype != NODAMAGE)
- {
- if(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL] && pVictim->GetTypeId() == TYPEID_PLAYER && damage)
- {
- if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_CASTING)
- {
- uint32 channelInterruptFlags = pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->ChannelInterruptFlags;
- if( channelInterruptFlags & CHANNEL_FLAG_DELAY )
- {
- sLog.outDetail("Spell %u delayed (%d) at damage!",pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id,(int32)(0.25f * GetDuration(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo)));
- pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->DelayedChannel((int32)(0.25f * GetDuration(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo)));
- }
- else if( (channelInterruptFlags & (CHANNEL_FLAG_DAMAGE | CHANNEL_FLAG_DAMAGE2)) )
- {
- sLog.outDetail("Spell %u canceled at damage!",pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id);
- pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL);
- }
- }
- else if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_DELAYED)
- // break channeled spell in delayed state on damage
- {
- sLog.outDetail("Spell %u canceled at damage!",pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id);
- pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL);
- }
- }
- }
-
- // last damage from duel opponent
- if(duel_hasEnded)
- {
- assert(pVictim->GetTypeId()==TYPEID_PLAYER);
- Player *he = (Player*)pVictim;
-
- assert(he->duel);
-
- he->SetHealth(1);
- CombatStop(); // for case killed by pet
- if(he->duel->opponent!=this)
- he->duel->opponent->CombatStop();
- he->CombatStop();
-
- he->CastSpell(he, 7267, true); // beg
- he->DuelComplete(1);
- }
+ SetInCombat();
+ pVictim->SetInCombat();
}
-
- DEBUG_LOG("DealDamageEnd");
+ pVictim->ModifyHealth(- (int32)damage);
+ }
}
void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem, Aura* triggredByAura, uint64 originalCaster)
{
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
+ if(spellId == 0)
+ {
+ sLog.outError("Unit833: %u cast unknown spell id %u\n",originalCaster, spellId);
+ return;
+ }
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %i\n", spellId);
+ sLog.outError("Unit844: %u cast unknown spell id %i\n",originalCaster, spellId);
return;
}
@@ -956,7 +888,7 @@
{
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell ");
+ sLog.outError("Unit958: unknown spell ");
return;
}
@@ -977,7 +909,7 @@
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %i\n", spellId);
+ sLog.outError("Unit876: unknown spell id %i\n", spellId);
return;
}
@@ -988,7 +920,7 @@
{
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell ");
+ sLog.outError("Unit990: unknown spell ");
return;
}
@@ -1732,414 +1664,369 @@
void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchools damageType, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted, bool isTriggeredSpell)
{
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, false);
- if(getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
- ((Player*)this)->ClearComboPoints();
+ pVictim->ModifyAuraState(AURA_STATE_DEFENSE, false);
- ModifyAuraState(AURA_STATE_CRIT, false);
+ ModifyAuraState(AURA_STATE_CRIT, false);
+ if(getClass()==CLASS_HUNTER) ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, false);
+ if(pVictim->getClass()==CLASS_HUNTER) pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
- if(getClass()==CLASS_HUNTER)
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, false);
+ // determine the damage type... If is casted Melee spell, calculate like physical
+ MeleeHitOutcome outcome;
+ if(!spellCasted)
+ outcome = RollMeleeOutcomeAgainst (pVictim, attType);
+ else
+ outcome = RollPhysicalOutcomeAgainst (pVictim, attType, spellCasted);
- if(pVictim->getClass()==CLASS_HUNTER)
- pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
+ if(outcome <= MELEE_HIT_MISS) //case: evade or miss...
+ {
+ *hitInfo |= HITINFO_MISS;
+ *damage = 0;
+ cleanDamage->damage = 0;
+ if(GetTypeId()== TYPEID_PLAYER) ((Player*)this)->UpdateWeaponSkill(attType);
+ return;
+ }
- MeleeHitOutcome outcome;
+ //attacker is a Player...
+ if(GetTypeId() == TYPEID_PLAYER) //moved so that warriors dont loose combo-points if they miss.
+ {
+ if(getClass() == CLASS_WARRIOR) ((Player*)this)->ClearComboPoints();
- // If is casted Melee spell, calculate like physical
- if(!spellCasted)
- outcome = RollMeleeOutcomeAgainst (pVictim, attType);
- else
- outcome = RollPhysicalOutcomeAgainst (pVictim, attType, spellCasted);
+ //Attacker is Player and victim is NPC...
+ if(pVictim->GetTypeId() != TYPEID_PLAYER)
+ {
+ ((Player*)this)->UpdateCombatSkills(pVictim, attType, outcome, false);
+ }
+ }
+ else //attacker is an NPC...
+ {
+ //if victim is hit from behind and its a crit, then daze the victim
+ if((outcome==MELEE_HIT_CRIT) && !((Creature*)this)->GetCharmerOrOwnerGUID() && !pVictim->HasInArc(M_PI, this))
+ {
+ CastSpell(pVictim, 1604, true);
+ }
+ //Attacker is NPC and victim is Player...
+ if(pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)pVictim)->UpdateCombatSkills(this, attType, outcome, true);
+ }
+ }
- switch(outcome)
- {
- case MELEE_HIT_EVADE:
- {
- *hitInfo |= HITINFO_MISS;
- *damage = 0;
- cleanDamage->damage = 0;
- return;
- }
- case MELEE_HIT_MISS:
- {
- *hitInfo |= HITINFO_MISS;
- *damage = 0;
- cleanDamage->damage = 0;
- if(GetTypeId()== TYPEID_PLAYER)
- ((Player*)this)->UpdateWeaponSkill(attType);
- return;
- }
- }
+ *damage += CalculateDamage (attType);
- /// If this is a creature and it attacks from behind it has a probability to daze it's victim
- if( (outcome==MELEE_HIT_CRIT || outcome==MELEE_HIT_CRUSHING || outcome==MELEE_HIT_NORMAL || outcome==MELEE_HIT_GLANCING) &&
- GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->GetCharmerOrOwnerGUID() && !pVictim->HasInArc(M_PI, this) )
- {
- // -probability is between 0% and 40%
- // 20% base chance
- float Probability = 20;
+ //reduce melee damage based on armor...
+ if (damageType == SPELL_SCHOOL_NORMAL)
+ {
+ uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage);
+ cleanDamage->damage += *damage - damageAfterArmor;
+ *damage = damageAfterArmor;
+ }
- //there is a newbie protection, at level 10 just 7% base chance; assuming linear function
- if( pVictim->getLevel() < 30 )
- Probability = 0.65f*pVictim->getLevel()+0.5;
+ // Instant Attacks (Spellmods)
+ // TODO: AP bonus related to mainhand weapon
+ if(spellCasted)
+ {
+ if(Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellCasted->Id, SPELLMOD_DAMAGE, *damage);
+ }
+sLog.outDetail("unit:1696 Process Attack Damege Type: %u",(uint32)outcome);
+ switch (outcome)
+ {
+ case MELEE_HIT_NORMAL:
+ break;
- uint32 VictimDefense=pVictim->GetDefenseSkillValue();
- uint32 AttackerMeleeSkill=GetUnitMeleeSkill();
+ case MELEE_HIT_CRIT:
+ {
+ *hitInfo = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | 0x8;
+ uint32 crit_bonus;
+ crit_bonus = *damage;
+ pVictim->HandleEmoteCommand(EMOTE_ONESHOT_WOUNDCRITICAL);
+ ModifyAuraState(AURA_STATE_CRIT, true);
- Probability *= AttackerMeleeSkill/(float)VictimDefense;
+ if (spellCasted)
+ { // Apply crit_damage bonus for melee spells
+ if(Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellCasted->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
+ }
+ *damage += crit_bonus;
+ if(attType == RANGED_ATTACK)
+ {
+ int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
+ *damage = int32((*damage) * float((100.0f + mod)/100.0f));
+ }
+ else
+ {
+ int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
+ *damage = int32((*damage) * float((100.0f + mod)/100.0f));
+ }
- if(Probability > 40)
- Probability = 40;
+ if(GetTypeId() == TYPEID_PLAYER)
+ {
+ // Resilience - reduce crit damage by 2x%
+ uint32 resilienceReduction;
+ resilienceReduction = uint32(pVictim->m_modResilience * 2/100 * (*damage));
+ *damage -= resilienceReduction;
+ cleanDamage->damage += resilienceReduction;
+ if(pVictim->GetTypeId() != TYPEID_PLAYER) ((Player*)this)->UpdateWeaponSkill(attType);
+ if(getClass()==CLASS_HUNTER) ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
+ }
+ }
+ break;
- if(roll_chance_f(Probability))
- CastSpell(pVictim, 1604, true);
- }
+ case MELEE_HIT_PARRY:
+ {
+ if(attType == RANGED_ATTACK) break; //no parry for ranged.
+ cleanDamage->damage = 0;
+ *damage = 0;
+ *victimState = VICTIMSTATE_PARRY;
+ pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
+ if(pVictim->GetTypeId() != TYPEID_PLAYER)
+ {
+ pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
+ return;
+ }
- *damage += CalculateDamage (attType);
+ float offtime = float(pVictim->getAttackTimer(OFF_ATTACK));
+ float basetime = float(pVictim->getAttackTimer(BASE_ATTACK));
- //Calculate the damage after armor mitigation if SPELL_SCHOOL_NORMAL
- if (damageType == SPELL_SCHOOL_NORMAL)
- {
- uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage);
- cleanDamage->damage += *damage - damageAfterArmor;
- *damage = damageAfterArmor;
- }
- // Instant Attacks (Spellmods)
- // TODO: AP bonus related to mainhand weapon
- if(spellCasted)
- {
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellCasted->Id, SPELLMOD_DAMAGE, *damage);
- }
+ // after parry nearest next attack time will reduced at %40 from full attack time.
+ // The delay cannot be reduced to less than 20% of your weapons base swing delay.
+ if (pVictim->haveOffhandWeapon() && offtime < basetime)
+ {
+ float percent20 = pVictim->GetAttackTime(OFF_ATTACK)*0.20;
+ float percent60 = 3*percent20;
+ // set to 20% if in range 20%...20+40% of full time
+ if(offtime > percent20 && offtime <= percent60)
+ {
+ pVictim->setAttackTimer(OFF_ATTACK,uint32(percent20));
+ }
+ // decrease at %40 from full time
+ else if(offtime > percent60)
+ {
+ offtime -= 2*percent20;
+ pVictim->setAttackTimer(OFF_ATTACK,uint32(offtime));
+ }
+ // ELSE not changed
+ }
+ else
+ {
+ float percent20 = pVictim->GetAttackTime(BASE_ATTACK)*0.20;
+ float percent60 = 3*percent20;
+ // set to 20% if in range 20%...20+40% of full time
+ if(basetime > percent20 && basetime <= percent60)
+ {
+ pVictim->setAttackTimer(BASE_ATTACK,uint32(percent20));
+ }
+ // decrease at %40 from full time
+ else if(basetime > percent60)
+ {
+ basetime -= 2*percent20;
+ pVictim->setAttackTimer(BASE_ATTACK,uint32(basetime));
+ }
+ // ELSE not changed
+ }
+ ((Player*)pVictim)->UpdateDefense();
+ if (pVictim->getClass() == CLASS_HUNTER)
+ pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
+ else
+ pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
+// CastMeleeProcDamageAndSpell(pVictim, 0, attType, outcome, spellCasted, isTriggeredSpell);
+ return;
+ }
+ break;
- if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER )
- ((Player*)this)->UpdateCombatSkills(pVictim, attType, outcome, false);
+ case MELEE_HIT_DODGE:
+ {
+ if(attType == RANGED_ATTACK) break; //no parry for ranged.
+ cleanDamage->damage = *damage;
+ *damage = 0;
+ *victimState = VICTIMSTATE_DODGE;
+ pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
+ if(pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (pVictim->getClass() != CLASS_ROGUE) pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); //riposte.
+ if (GetTypeId() == TYPEID_PLAYER) //attacker is a player also...
+ {
+ if(getClass() == CLASS_WARRIOR) ((Player*)this)->AddComboPoints(pVictim, 1); // Overpower
+ }
+// CastMeleeProcDamageAndSpell(pVictim, 0, attType, outcome, spellCasted, isTriggeredSpell);
+ ((Player*)pVictim)->UpdateDefense();
+ return;
+ }
+ pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
+ return;
+ }
+ break;
- if(GetTypeId() != TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
- ((Player*)pVictim)->UpdateCombatSkills(this, attType, outcome, true);
+ case MELEE_HIT_BLOCK:
+ {
+ *blocked_amount = pVictim->GetShieldBlockValue();
- switch (outcome)
- {
- case MELEE_HIT_CRIT:
- //*hitInfo = 0xEA;
- // 0xEA
- *hitInfo = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | 0x8;
+ if (pVictim->GetUnitBlockChance())
+ pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD);
+ else
+ pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
- // Crit bonus calc
- uint32 crit_bonus;
- crit_bonus = *damage;
+ //Only set VICTIMSTATE_BLOCK on a full block
+ if (*blocked_amount >= *damage)
+ {
+ *victimState = VICTIMSTATE_BLOCKS;
+ *blocked_amount = *damage;
+ cleanDamage->damage = 0;
+ *damage = 0;
+ *victimState = VICTIMSTATE_DODGE;
+ pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
+ pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
+ return;
+ }
+ if(pVictim->GetTypeId() == TYPEID_PLAYER) ((Player*)pVictim)->UpdateDefense();
+ pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true);
+ }
+ break;
- // Apply crit_damage bonus for melee spells
- if (spellCasted)
- {
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellCasted->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
- }
+ case MELEE_HIT_GLANCING:
+ {
+ float reducePercent = 1.0f; //damage factor
- *damage += crit_bonus;
+ // calculate base values and mods
+ float baseLowEnd = 1.3;
+ float baseHighEnd = 1.2;
+ float maxLowEnd = 0.6;
- if(attType == RANGED_ATTACK)
- {
- int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
- *damage = int32((*damage) * float((100.0f + mod)/100.0f));
- }
- else
- {
- int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
- *damage = int32((*damage) * float((100.0f + mod)/100.0f));
- }
+ switch(getClass()) // upper for melee classes
+ {
+ case CLASS_WARRIOR:
+ {
+ maxLowEnd = 0.81;
+ }
+ break;
+ case CLASS_ROGUE:
+ {
+ maxLowEnd = 0.99;
+ }
+ break;
+ }
- // Resilience - reduce crit damage by 2x%
- uint32 resilienceReduction;
- resilienceReduction = uint32(pVictim->m_modResilience * 2/100 * (*damage));
- *damage -= resilienceReduction;
- cleanDamage->damage += resilienceReduction;
+ // calculate values
+ int32 diff = pVictim->GetDefenseSkillValue() - GetWeaponSkillValue(attType);
+ float lowEnd = baseLowEnd - ( 0.05f * diff );
+ float highEnd = baseHighEnd - ( 0.03f * diff );
- if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER )
- ((Player*)this)->UpdateWeaponSkill(attType);
+ // apply max/min bounds
+ if ( lowEnd < 0.01f ) //the low end must not go bellow 0.01f
+ lowEnd = 0.01f;
+ else if ( lowEnd > maxLowEnd ) //the smaller value of this and 0.6 is kept as the low end
+ lowEnd = maxLowEnd;
- ModifyAuraState(AURA_STATE_CRIT, true);
+ if ( highEnd < 0.2f ) highEnd = 0.2f;
+ if ( highEnd > 0.99f ) highEnd = 0.99f;
+ if(lowEnd > highEnd) lowEnd = highEnd;
- if(getClass()==CLASS_HUNTER)
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
+ reducePercent = lowEnd + rand_norm() * ( highEnd - lowEnd );
+ *damage = uint32(reducePercent * *damage);
+ cleanDamage->damage += *damage;
+ *hitInfo |= HITINFO_GLANCING;
+ }
+ break;
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_WOUNDCRITICAL);
- break;
+ case MELEE_HIT_CRUSHING:
+ {
+ // 150% normal damage
+ *damage += (*damage / 2);
+ cleanDamage->damage = *damage;
+ *hitInfo |= HITINFO_CRUSHING;
+ // TODO: victimState, victim animation?
+ }
+ break;
+ default:
+ break;
+ }
+//sLog.outDetail("unit:1904");
- case MELEE_HIT_PARRY:
- if(attType == RANGED_ATTACK) //range attack - no parry
- break;
+ // apply melee damage bonus and absorb only if base damage not fully blocked to prevent negative damage or damage with full block
+ if(*victimState != VICTIMSTATE_BLOCKS)
+ {
+ MeleeDamageBonus(pVictim, damage,attType);
+ CalcAbsorbResist(pVictim, damageType, DIRECT_DAMAGE, *damage-*blocked_amount, absorbDamage, resistDamage);
+ }
- cleanDamage->damage += *damage;
- *damage = 0;
- *victimState = VICTIMSTATE_PARRY;
+ if (*absorbDamage) *hitInfo |= HITINFO_ABSORB;
+ if (*resistDamage) *hitInfo |= HITINFO_RESIST;
- // instant (maybe with small delay) counter attack
- {
- float offtime = float(pVictim->getAttackTimer(OFF_ATTACK));
- float basetime = float(pVictim->getAttackTimer(BASE_ATTACK));
+ cleanDamage->damage += *blocked_amount;
+ if (*damage <= *absorbDamage + *resistDamage + *blocked_amount)
+ {
+ CastMeleeProcDamageAndSpell(pVictim, 0, attType, outcome, spellCasted, isTriggeredSpell);
+ return;
+ }
- // after parry nearest next attack time will reduced at %40 from full attack time.
- // The delay cannot be reduced to less than 20% of your weapons base swing delay.
- if (pVictim->haveOffhandWeapon() && offtime < basetime)
- {
- float percent20 = pVictim->GetAttackTime(OFF_ATTACK)*0.20;
- float percent60 = 3*percent20;
- // set to 20% if in range 20%...20+40% of full time
- if(offtime > percent20 && offtime <= percent60)
- {
- pVictim->setAttackTimer(OFF_ATTACK,uint32(percent20));
- }
- // decrease at %40 from full time
- else if(offtime > percent60)
- {
- offtime -= 2*percent20;
- pVictim->setAttackTimer(OFF_ATTACK,uint32(offtime));
- }
- // ELSE not changed
- }
- else
- {
- float percent20 = pVictim->GetAttackTime(BASE_ATTACK)*0.20;
- float percent60 = 3*percent20;
- // set to 20% if in range 20%...20+40% of full time
- if(basetime > percent20 && basetime <= percent60)
- {
- pVictim->setAttackTimer(BASE_ATTACK,uint32(percent20));
- }
- // decrease at %40 from full time
- else if(basetime > percent60)
- {
- basetime -= 2*percent20;
- pVictim->setAttackTimer(BASE_ATTACK,uint32(basetime));
- }
- // ELSE not changed
- }
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- ((Player*)pVictim)->UpdateDefense();
-
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- if (pVictim->getClass() == CLASS_HUNTER)
- pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
- else
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
-
- CastMeleeProcDamageAndSpell(pVictim, 0, attType, outcome, spellCasted, isTriggeredSpell);
- return;
-
- case MELEE_HIT_DODGE:
- if(attType == RANGED_ATTACK) //range attack - no dodge
- break;
- cleanDamage->damage += *damage;
- *damage = 0;
- *victimState = VICTIMSTATE_DODGE;
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- ((Player*)pVictim)->UpdateDefense();
-
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- if (pVictim->getClass() != CLASS_ROGUE) // Riposte
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
-
- // Overpower
- if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
- ((Player*)this)->AddComboPoints(pVictim, 1);
-
- CastMeleeProcDamageAndSpell(pVictim, 0, attType, outcome, spellCasted, isTriggeredSpell);
- return;
-
- case MELEE_HIT_BLOCK:
- *blocked_amount = pVictim->GetShieldBlockValue();
-
- if (pVictim->GetUnitBlockChance())
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD);
- else
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- //Only set VICTIMSTATE_BLOCK on a full block
- if (*blocked_amount >= *damage)
- {
- *victimState = VICTIMSTATE_BLOCKS;
- *blocked_amount = *damage;
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- ((Player*)pVictim)->UpdateDefense();
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true);
- break;
-
- case MELEE_HIT_GLANCING:
- {
- float reducePercent = 1.0f; //damage factor
-
- // calculate base values and mods
- float baseLowEnd = 1.3;
- float baseHighEnd = 1.2;
- switch(getClass()) // lowering base values for casters
- {
- case CLASS_SHAMAN:
- case CLASS_PRIEST:
- case CLASS_MAGE:
- case CLASS_WARLOCK:
- case CLASS_DRUID:
- baseLowEnd -= 0.7;
- baseHighEnd -= 0.3;
- break;
- }
-
- float maxLowEnd = 0.6;
- switch(getClass()) // upper for melee classes
- {
- case CLASS_WARRIOR:
- case CLASS_ROGUE:
- maxLowEnd = 0.91; //If the attacker is a melee class then instead the lower value of 0.91
- }
-
- // calculate values
- int32 diff = pVictim->GetDefenseSkillValue() - GetWeaponSkillValue(attType);
- float lowEnd = baseLowEnd - ( 0.05f * diff );
- float highEnd = baseHighEnd - ( 0.03f * diff );
-
- // apply max/min bounds
- if ( lowEnd < 0.01f ) //the low end must not go bellow 0.01f
- lowEnd = 0.01f;
- else if ( lowEnd > maxLowEnd ) //the smaller value of this and 0.6 is kept as the low end
- lowEnd = maxLowEnd;
-
- if ( highEnd < 0.2f ) //high end limits
- highEnd = 0.2f;
- if ( highEnd > 0.99f )
- highEnd = 0.99f;
-
- if(lowEnd > highEnd) // prevent negative range size
- lowEnd = highEnd;
-
- reducePercent = lowEnd + rand_norm() * ( highEnd - lowEnd );
-
- *damage = uint32(reducePercent * *damage);
- cleanDamage->damage += *damage;
- *hitInfo |= HITINFO_GLANCING;
- break;
- }
- case MELEE_HIT_CRUSHING:
- {
- // 150% normal damage
- *damage += (*damage / 2);
- cleanDamage->damage = *damage;
- *hitInfo |= HITINFO_CRUSHING;
- // TODO: victimState, victim animation?
- break;
- }
- default:
- break;
- }
-
- // apply melee damage bonus and absorb only if base damage not fully blocked to prevent negative damage or damage with full block
- if(*victimState != VICTIMSTATE_BLOCKS)
+ // update at damage Judgement aura duration that applied by attacker at victim
+ if(*damage)
+ {
+ AuraMap& vAuras = pVictim->GetAuras();
+ for(AuraMap::iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr)
{
- MeleeDamageBonus(pVictim, damage,attType);
- CalcAbsorbResist(pVictim, damageType, DIRECT_DAMAGE, *damage-*blocked_amount, absorbDamage, resistDamage);
+ SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
+ if(spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN)
+ {
+ if( spellInfo->AttributesEx3 == 0x40000 && ((*itr).second->GetCasterGUID() == GetGUID() &&
+ (!spellCasted || spellCasted->Id == 35395)) )
+ {
+ (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
+ (*itr).second->UpdateAuraDuration();
+ }
+ }
}
+ }
+ CastMeleeProcDamageAndSpell(pVictim, (*damage - *absorbDamage - *resistDamage - *blocked_amount), attType, outcome, spellCasted, isTriggeredSpell);
- if (*absorbDamage) *hitInfo |= HITINFO_ABSORB;
- if (*resistDamage) *hitInfo |= HITINFO_RESIST;
-
- cleanDamage->damage += *blocked_amount;
-
- if (*damage <= *absorbDamage + *resistDamage + *blocked_amount)
+ // victim's damage shield
+ // yet another hack to fix crashes related to the aura getting removed during iteration
+ std::set alreadyDone;
+ uint32 removedAuras = pVictim->m_removedAuras;
+ AuraList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD);
+ for(AuraList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next)
+ {
+ next++;
+ if (alreadyDone.find(*i) == alreadyDone.end())
{
- //*hitInfo = 0x00010020;
- //*hitInfo |= HITINFO_SWINGNOHITSOUND;
- //*damageType = 0;
- CastMeleeProcDamageAndSpell(pVictim, 0, attType, outcome, spellCasted, isTriggeredSpell);
- return;
+ alreadyDone.insert(*i);
+ pVictim->SpellNonMeleeDamageLog(this, (*i)->GetId(), (*i)->GetModifier()->m_amount, false, false);
+ if (pVictim->m_removedAuras > removedAuras)
+ {
+ removedAuras = pVictim->m_removedAuras;
+ next = vDamageShields.begin();
+ }
}
+ }
- // update at damage Judgement aura duration that applied by attacker at victim
- if(*damage)
+ if (pVictim->GetTypeId() == TYPEID_PLAYER && *damage)
+ {
+ for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
{
- AuraMap& vAuras = pVictim->GetAuras();
- for(AuraMap::iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr)
- {
- SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
- if( spellInfo->AttributesEx3 == 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN &&
- ((*itr).second->GetCasterGUID() == GetGUID() && (!spellCasted || spellCasted->Id == 35395)) )
- {
- (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
- (*itr).second->UpdateAuraDuration();
- }
- }
+ if (i == CURRENT_CHANNELED_SPELL) continue; // skip channeled spell (processed differently below)
+ if(pVictim->m_currentSpells[i]) pVictim->m_currentSpells[i]->Delayed((int32)(0.25f * pVictim->m_currentSpells[i]->casttime));
}
- CastMeleeProcDamageAndSpell(pVictim, (*damage - *absorbDamage - *resistDamage - *blocked_amount), attType, outcome, spellCasted, isTriggeredSpell);
-
- // victim's damage shield
- // yet another hack to fix crashes related to the aura getting removed during iteration
- std::set alreadyDone;
- uint32 removedAuras = pVictim->m_removedAuras;
- AuraList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD);
- for(AuraList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next)
+ // process channeled spell separately
+ if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL])
{
- next++;
- if (alreadyDone.find(*i) == alreadyDone.end())
+ if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_CASTING)
+ {
+ uint32 channelInterruptFlags = pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->ChannelInterruptFlags;
+ if( channelInterruptFlags & CHANNEL_FLAG_DELAY )
{
- alreadyDone.insert(*i);
- pVictim->SpellNonMeleeDamageLog(this, (*i)->GetId(), (*i)->GetModifier()->m_amount, false, false);
- if (pVictim->m_removedAuras > removedAuras)
- {
- removedAuras = pVictim->m_removedAuras;
- next = vDamageShields.begin();
- }
+ pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->DelayedChannel((int32)(0.25f * GetDuration(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo)));
+ return;
}
+ else if( !(channelInterruptFlags & (CHANNEL_FLAG_DAMAGE | CHANNEL_FLAG_DAMAGE2)) ) return;
+ pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel();
+ }
+ else if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_DELAYED)
+ {
+ // break channeled spell in delayed state on damage
+ pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel();
+ }
}
-
- if (pVictim->GetTypeId() == TYPEID_PLAYER && *damage)
- {
- for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
- {
- // skip channeled spell (processed differently below)
- if (i == CURRENT_CHANNELED_SPELL)
- continue;
-
- if(pVictim->m_currentSpells[i])
- {
- sLog.outDetail("Spell Delayed!%d",(int32)(0.25f * pVictim->m_currentSpells[i]->casttime));
- pVictim->m_currentSpells[i]->Delayed((int32)(0.25f * pVictim->m_currentSpells[i]->casttime));
- }
- }
-
- // process channeled spell separately
- if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL])
- {
- if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_CASTING)
- {
- uint32 channelInterruptFlags = pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->ChannelInterruptFlags;
- if( channelInterruptFlags & CHANNEL_FLAG_DELAY )
- {
- sLog.outDetail("Spell Delayed!%d",(int32)(0.25f * GetDuration(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo)));
- pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->DelayedChannel((int32)(0.25f * GetDuration(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo)));
- return;
- }
- else if( !(channelInterruptFlags & (CHANNEL_FLAG_DAMAGE | CHANNEL_FLAG_DAMAGE2)) )
- return;
-
- sLog.outDetail("Spell Canceled!");
- pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel();
- }
- else if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_DELAYED)
- {
- // break channeled spell in delayed state on damage
- sLog.outDetail("Spell Canceled!");
- pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel();
- }
- }
- }
+ }
}
void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool isTriggered)
@@ -2457,15 +2344,14 @@
void Unit::SendAttackStop(Unit* victim)
{
- if(!victim)
- return;
+ if(!victim) return;
- WorldPacket data( SMSG_ATTACKSTOP, (4+16) ); // we guess size
- data.append(GetPackGUID());
- data.append(victim->GetPackGUID()); // can be 0x00...
- data << uint32(0); // can be 0x1
- SendMessageToSet(&data, true);
- sLog.outDetail("%s %u stopped attacking %s %u", (GetTypeId()==TYPEID_PLAYER ? "player" : "creature"), GetGUIDLow(), (victim->GetTypeId()==TYPEID_PLAYER ? "player" : "creature"),victim->GetGUIDLow());
+ WorldPacket data( SMSG_ATTACKSTOP, (4+16) ); // we guess size
+ data.append(GetPackGUID());
+ data.append(victim->GetPackGUID()); // can be 0x00...
+ data << uint32(0); // can be 0x1
+ SendMessageToSet(&data, true);
+ sLog.outDetail("%s %u stopped attacking %s %u", (GetTypeId()==TYPEID_PLAYER ? "player" : "creature"), GetGUIDLow(), (victim->GetTypeId()==TYPEID_PLAYER ? "player" : "creature"),victim->GetGUIDLow());
/*if(victim->GetTypeId() == TYPEID_UNIT)
((Creature*)victim)->AI().EnterEvadeMode(this);*/
@@ -3052,15 +2938,14 @@
bool Unit::AddAura(Aura *Aur)
{
- // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
- if( !isAlive() && Aur->GetSpellProto()->Id != 20584 && Aur->GetSpellProto()->Id != 8326 && Aur->GetSpellProto()->Id != 2584 &&
- (GetTypeId()!=TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) )
- {
- delete Aur;
- return false;
- }
+ uint32 SpellID = Aur->GetSpellProto()->Id;
+ if((SpellID == 20584) || (SpellID == 8326) || (SpellID == 2584))
+ {
+ sLog.outError("-- %u is DEAD!!--",GetName());
+ if(isAlive()){ delete Aur; return false;}
+ }
- if(Aur->GetTarget() != this)
+ if(Aur->GetTarget() != this)
{
sLog.outError("Aura (spell %u eff %u) add to aura list of %s (lowguid: %u) but Aura target is %s (lowguid: %u)",
Aur->GetId(),Aur->GetEffIndex(),(GetTypeId()==TYPEID_PLAYER?"player":"creature"),GetGUIDLow(),
@@ -3725,6 +3610,7 @@
void Unit::ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 damage, SpellEntry const *procSpell, bool isTriggeredSpell, WeaponAttackType attType)
{
+ if(!pVictim) return;
sLog.outDebug("ProcDamageAndSpell: attacker flags are 0x%x, victim flags 0x%x", procAttacker, procVictim);
if(procSpell)
sLog.outDebug("ProcDamageAndSpell: invoked due to spell id %u %s", procSpell->Id, (isTriggeredSpell?"(triggered)":""));
@@ -3762,7 +3648,7 @@
// Now go on with a victim's events'n'auras
// Not much to do if no flags are set or there is no victim
- if(pVictim && pVictim->isAlive() && procVictim)
+ if(pVictim->isAlive() && procVictim)
{
pVictim->ProcDamageAndSpellFor(true,this,procVictim,victimProcAuraTypes,attType,procSpell, damage);
}
@@ -3770,8 +3656,7 @@
void Unit::CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, WeaponAttackType attType, MeleeHitOutcome outcome, SpellEntry const *spellCasted, bool isTriggeredSpell)
{
- if(!pVictim)
- return;
+ if(!pVictim) return;
uint32 procAttacker = PROC_FLAG_NONE;
uint32 procVictim = PROC_FLAG_NONE;
@@ -4098,8 +3983,8 @@
if(!procSpell)
return;
- if(dummySpell->SpellFamilyName!=SPELLFAMILY_HUNTER)
- return;
+// if(dummySpell->SpellFamilyName!=SPELLFAMILY_HUNTER)
+// return;
int32 THManaCostSave = procSpell->manaCost * 40/100;
if(THManaCostSave <= 0)
@@ -4782,30 +4667,23 @@
bool Unit::AttackStop()
{
- if (!m_attacking)
- return false;
+ if (!m_attacking) return false;
+ Unit* victim = m_attacking;
+ m_attacking->_removeAttacker(this);
+ m_attacking = NULL;
- Unit* victim = m_attacking;
+ //Clear our target
+ SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ clearUnitState(UNIT_STAT_ATTACKING);
+ InterruptSpell(CURRENT_MELEE_SPELL);
- m_attacking->_removeAttacker(this);
- m_attacking = NULL;
-
- //Clear our target
- SetUInt64Value(UNIT_FIELD_TARGET, 0);
-
- clearUnitState(UNIT_STAT_ATTACKING);
-
- InterruptSpell(CURRENT_MELEE_SPELL);
-
- if( GetTypeId()==TYPEID_UNIT )
- {
- // reset call assistance
- ((Creature*)this)->SetNoCallAssistence(false);
- }
-
- SendAttackStop(victim);
-
- return true;
+ if( GetTypeId()==TYPEID_UNIT )
+ {
+ // reset call assistance
+ ((Creature*)this)->SetNoCallAssistence(false);
+ }
+ SendAttackStop(victim);
+ return true;
}
bool Unit::isAttackingPlayer() const
@@ -4847,7 +4725,7 @@
AttackerSet::iterator iter = m_attackers.begin();
if(!(*iter)->AttackStop())
{
- sLog.outError("WORLD: Unit has an attacker that isnt attacking it!");
+ sLog.outError("Unit4848: Unit has an attacker that isnt attacking it!");
m_attackers.erase(iter);
}
}
@@ -5767,102 +5645,73 @@
bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList) const
{
- if(!u)
- return false;
+ if(!u) return false;
+ if (u==this) return true;//can always see self.
+ if(!u->IsInWorld()) return false;
- // Always can see self
- if (u==this)
- return true;
- // player visible for other player if not logout and at same transport
- // including case when player is out of world
- bool at_same_transport =
- GetTypeId() == TYPEID_PLAYER && u->GetTypeId()==TYPEID_PLAYER &&
- !((Player*)this)->GetSession()->PlayerLogout() && !((Player*)u)->GetSession()->PlayerLogout() &&
- !((Player*)this)->GetSession()->PlayerLoading() && !((Player*)u)->GetSession()->PlayerLoading() &&
- ((Player*)this)->GetTransport() && ((Player*)this)->GetTransport() == ((Player*)u)->GetTransport();
- // not in world
- if(!at_same_transport && (!IsInWorld() || !u->IsInWorld()))
- return false;
+ // If is attacked then stealth is lost, some creature can use stealth too
+ if (this->isAttacked()) return true;
- // always seen by owner
- if(GetCharmerOrOwnerGUID()==u->GetGUID())
- return true;
-
- // Grid dead/alive checks
+ // u=player...
if( u->GetTypeId()==TYPEID_PLAYER)
{
- // non visible at grid for any stealth state
- if(!IsVisibleInGridForPlayer((Player *)u))
- return false;
+ if(GetCharmerOrOwnerGUID()) // distance for show pet/charmed
+ {
+ if(GetCharmerOrOwnerGUID()==u->GetGUID()) return true;//always seen by owner.
+ if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) return false;
+ }
+
+ if(GetTypeId()==TYPEID_PLAYER) // distance for show other player
+ {//target=player
+ if(((Player*)this)->IsGroupVisibleFor(((Player*)u))) return true;//always show invis. for group members
+ if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) return false;
+ }
+ else
+ { //target=creature
+ if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) return false;
+ }
+ if(!isAlive()) // distance for show body
+ {
+ if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) return false;
+ }
+
+ // different visible distance checks
+ if(u->isInFlight()) // what see player in flight
+ {
+ // use object grey distance for all (only see objects any way)
+ if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) return false;
+ }
+
+ // player visibity for transports
+ bool at_same_transport =
+ GetTypeId() == TYPEID_PLAYER && u->GetTypeId()==TYPEID_PLAYER &&
+ !((Player*)this)->GetSession()->PlayerLogout() && !((Player*)u)->GetSession()->PlayerLogout() &&
+ !((Player*)this)->GetSession()->PlayerLoading() && !((Player*)u)->GetSession()->PlayerLoading() &&
+ ((Player*)this)->GetTransport() && ((Player*)this)->GetTransport() == ((Player*)u)->GetTransport();
+ if(!at_same_transport && !IsInWorld()) return false;
+ if(!IsVisibleInGridForPlayer((Player *)u)) return false;
+
// if player is dead then he can't detect anyone in anycases
- if(!u->isAlive())
- detect = false;
+ if(!u->isAlive()) detect = false;
}
- else
+ else // u=Creature...
{
// all dead creatures/players not visible for any creatures
if(!u->isAlive() || !isAlive())
return false;
}
+ // max distance for show creature/creature
+ if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) return false;
- // different visible distance checks
- if(u->isInFlight()) // what see player in flight
- {
- // use object grey distance for all (only see objects any way)
- if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))
- return false;
- }
- else if(!isAlive()) // distance for show body
- {
- if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))
- return false;
- }
- else if(GetTypeId()==TYPEID_PLAYER) // distance for show player
- {
- if(u->GetTypeId()==TYPEID_PLAYER)
- {
- // Players far than max visible distance for player or not in our map are not visible too
- if (!at_same_transport && !IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
- return false;
- }
- else
- {
- // Units far than max visible distance for creature or not in our map are not visible too
- if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
- return false;
- }
- }
- else if(GetCharmerOrOwnerGUID()) // distance for show pet/charmed
- {
- // Pet/charmed far than max visible distance for player or not in our map are not visible too
- if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
- return false;
- }
- else // distance for show creature
- {
- // Units far than max visible distance for creature or not in our map are not visible too
- if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
- return false;
- }
+ // no invisibility auras, show visible for all that do not fit above criteria and are not hostile.
+ if (m_Visibility == VISIBILITY_ON ) return true;
+ if (!u->IsHostileTo(this)) return true;
- // Visible units, always are visible for all units, except for units under invisibility
- if (m_Visibility == VISIBILITY_ON && u->GetVisibility()!= VISIBILITY_GROUP_INVISIBILITY)
- return true;
-
- // GMs are visible for higher gms (or players are visible for gms)
- if (u->GetTypeId() == TYPEID_PLAYER && ((Player *)u)->isGameMaster())
- return (GetTypeId() == TYPEID_PLAYER && ((Player *)this)->GetSession()->GetSecurity() <= ((Player *)u)->GetSession()->GetSecurity());
-
- // non faction visibility non-breakable for non-GMs
- if (m_Visibility == VISIBILITY_OFF)
- return false;
-
// Invisible units, always are visible for units under same invisibility type
- if(m_invisibilityMask & u->m_invisibilityMask)
- return true;
+ if(m_invisibilityMask & u->m_invisibilityMask) return true;
// Invisible units, always are visible for unit that can detect this invisibility (have appropriate level for detect)
if(uint32 mask = (m_invisibilityMask & u->m_detectInvisibilityMask))
@@ -5928,72 +5777,42 @@
}
}
- // Stealth/invisible not hostile units, not visible (except Player-with-Player case)
- if (!u->IsHostileTo(this))
- {
- // player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting)
- if(GetTypeId()==TYPEID_PLAYER && u->GetTypeId()==TYPEID_PLAYER)
- {
- if(((Player*)this)->IsGroupVisibleFor(((Player*)u)))
- return true;
+ // check Hunter mark functionality
+ AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED);
+ for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
+ {
+ if((*iter)->GetCasterGUID()==u->GetGUID()) return true;
+ }
- // else apply same rules as for hostile case (detecting check)
- }
- }
- else
- {
- // Hunter mark functionality
- AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED);
- for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
- if((*iter)->GetCasterGUID()==u->GetGUID())
- return true;
- }
-
- // unit got in stealth in this moment and must ignore old detected state
- // invisibility not have chance for detection
- if (m_Visibility == VISIBILITY_ON || m_Visibility == VISIBILITY_GROUP_NO_DETECT || m_Visibility == VISIBILITY_GROUP_INVISIBILITY)
- return false;
-
- // NOW ONLY STEALTH CASE
-
// stealth and detected
- if (u->GetTypeId() == TYPEID_PLAYER && ((Player*)u)->HaveAtClient(this) )
- return true;
+ if (u->GetTypeId() == TYPEID_PLAYER && ((Player*)u)->HaveAtClient(this) ) return true;
//if in non-detect mode then invisible for unit
- if (!detect)
- return false;
+ if (!detect) return false;
// Special cases
bool IsVisible = true;
bool isInFront = u->isInFront(this,World::GetMaxVisibleDistanceForObject());
float distance = GetDistance(u);
- // If is attacked then stealth is lost, some creature can use stealth too
- if (this->isAttacked())
- return IsVisible;
- // If there is collision rogue is seen regardless of level difference
- // TODO: check sizes in DB
- if (distance < 0.24f)
- return IsVisible;
-
//If a mob or player is stunned he will not be able to detect stealth
- if (u->hasUnitState(UNIT_STAT_STUNDED) && (u != this))
- {
- IsVisible=false;
- return IsVisible;
- }
+ if (u->hasUnitState(UNIT_STAT_STUNDED) && (u != this)) return false;
- // Cases based on level difference and position
+ // SantaCl Cases based on level difference and position
+ uint32 stealthMod = GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL);
+ if(stealthMod > 4) return false;//rogue has talants maxxed out
int32 levelDiff = u->getLevel() - this->getLevel();
- //If mob is 5 levels more than player he gets detected automaticly
- if (u->GetTypeId()!=TYPEID_PLAYER && levelDiff > 5)
+ int32 mobDiff = levelDiff + stealthMod;
+
+
+ //If mob is 5 levels more than player he gets detected automaticly
+ if (u->GetTypeId()!=TYPEID_PLAYER && levelDiff > mobDiff)
return IsVisible;
// If victim has more than 5 lvls above caster
- if ((this->GetTypeId() == TYPEID_UNIT)&& ( levelDiff > 5 ))
+ if ((this->GetTypeId() == TYPEID_UNIT)&& ( levelDiff > mobDiff ))
return IsVisible;
// If caster has more than 5 levels above victim
@@ -6007,8 +5826,8 @@
float pvpMultiplier = 0.0f;
float distanceFormula = 0.0f;
int32 rank = 0;
- //This allows to check talent tree and will add addition stealth dependant on used points)
- uint32 stealthMod = GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL);
+
+ //This allows to check talent tree and will add addition stealth dependant on used points)
//****************************************************************************************
// Stealth detection calculation
int32 x = (((u->m_detectStealth+1) / 5) - (((m_stealthvalue+1) / 5) + (stealthMod/5) + 59));
@@ -6046,11 +5865,6 @@
// Mob rank affects modifier
modifier = rank <= 4 ? 1 + rank * 0.2f : 1;
- if (distance < 0.24f)
- {
- return IsVisible;
- }
-
// PVP distance assigned depending on level
if (this->GetTypeId() == TYPEID_UNIT)
{
@@ -6076,38 +5890,30 @@
return IsVisible;
}
- if (isInFront && (distance < pvpMultiplier))
- {
- return IsVisible;
- }
}
else
{
// PVE stealth handler
// Distance of approch player stays stealth 100% is dependant of level. No probabiliy or detection is rolled
// This establishes a buffer zone in between mob start to see you and mob start to roll probabilities or detect you
- if ((distance < 100.0f) && (distance > ((distanceFormula * 2) * modifier)) && (distance > 0.24f))
- {
- IsVisible=false;
- return IsVisible;
+ if ((distance < 100.0f) && (distance > ((distanceFormula * 2) * modifier))) return false;
- }
- //If victim is level lower or more probability of detection drops
- if ((levelDiff < 0) && (distance > 0.24f))
+ //If victim is level lower or more probability of detection drops
+ if (levelDiff < 0)
{
if (abs(levelDiff ) > 4)
IsVisible = false;
else
{
- if (rand_chance() > ( prob * modifier / (30 + levelDiff * 5)))
+ if ((rand_chance()/2) > ( prob * modifier / (30 + levelDiff * 5)))
IsVisible = false;
}
return IsVisible;
}
// Level detection based on level, the higher the mob level the higher the chance of detection.
- if ((distance > 0.24f) && (levelDiff < 5) && (levelDiff >= 0))
+ if (levelDiff >= 0)
{
- if (rand_chance() > ((prob * modifier) / (30 - levelDiff * 5) ))
+ if ((rand_chance()/2) > ((prob * modifier) / (30 - levelDiff * 5) ))
IsVisible = false;
else
IsVisible = true;
@@ -6247,6 +6053,8 @@
}
if (m_deathState != ALIVE && s == ALIVE)
{
+ CombatStop(true);
+ ClearComboPointHolders(); // any combo points pointed to unit lost at it death
//_ApplyAllAuraMods();
}
m_deathState = s;
@@ -6285,9 +6093,7 @@
void Unit::AddThreat(Unit* pVictim, float threat, SpellSchools school, SpellEntry const *threatSpell)
{
- // Only mobs can manage threat lists
- if(CanHaveThreatList())
- m_ThreatManager.addThreat(pVictim, threat, school, threatSpell);
+ if(CanHaveThreatList()) m_ThreatManager.addThreat(pVictim, threat, school, threatSpell);
}
//======================================================================
@@ -6358,53 +6164,36 @@
bool Unit::SelectHostilTarget()
{
- //function provides main threat functionality
- //next-victim-selection algorithm and evade mode are called
- //threat list sorting etc.
+ if ( !((Creature*)this)->AI() || HasAuraType(SPELL_AURA_MOD_TAUNT) ) return false; //select only if creature AI is active.
+ Unit* target = NULL;
+ if(!m_ThreatManager.isThreatListEmpty())
+ {
+ target = m_ThreatManager.getHostilTarget();
+ }
+ if(target)
+ {
+ if(!hasUnitState(UNIT_STAT_STUNDED)) SetInFront(target);
+ ((Creature*)this)->AI()->AttackStart(target);
+ return true;
+ }
+ // no target but something prevent go to evade mode
+ if( !isInCombat() || !CanFreeMove() ) return false;
- assert(GetTypeId()== TYPEID_UNIT);
- Unit* target = NULL;
-
- //This function only useful once AI has been initilazied
- if (!((Creature*)this)->AI())
- return false;
-
- if(!m_ThreatManager.isThreatListEmpty())
- {
- if(!HasAuraType(SPELL_AURA_MOD_TAUNT))
- {
- target = m_ThreatManager.getHostilTarget();
- }
- }
-
- if(target)
- {
- if(!hasUnitState(UNIT_STAT_STUNDED))
- SetInFront(target);
- ((Creature*)this)->AI()->AttackStart(target);
- return true;
- }
-
- // no target but something prevent go to evade mode
- if( !isInCombat() || HasAuraType(SPELL_AURA_MOD_TAUNT) || !CanFreeMove() )
- return false;
-
// last case when creature don't must go to evade mode:
// it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list
// for example at owner command to pet attack some far away creature
// Note: creature not have targeted movement generator but have attacker in this case
if( GetMotionMaster()->empty() || GetMotionMaster()->top()->GetMovementGeneratorType() != TARGETED_MOTION_TYPE )
{
- for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
- {
- if( (*itr)->IsInMap(this) && (*itr)->isTargetableForAttack() && (*itr)->isInAccessablePlaceFor((Creature*)this) )
- return false;
- }
+ for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
+ {
+ if( (*itr)->IsInMap(this) && (*itr)->isTargetableForAttack() && (*itr)->isInAccessablePlaceFor((Creature*)this) )
+ return false;
+ }
}
// enter in evade mode in other case
((Creature*)this)->AI()->EnterEvadeMode();
-
return false;
}
Index: src/game/Level2.cpp
===================================================================
--- src/game/Level2.cpp (revision 4845)
+++ src/game/Level2.cpp (working copy)
@@ -1292,17 +1292,11 @@
//morph creature or player
bool ChatHandler::HandleMorphCommand(const char* args)
{
- if (!*args)
- return false;
-
- uint16 display_id = (uint16)atoi((char*)args);
-
- Unit *target = getSelectedUnit();
- if(!target)
- target = m_session->GetPlayer();
-
- target->SetUInt32Value(UNIT_FIELD_DISPLAYID, display_id);
-
+ if (!*args) return false;
+ Unit *target = getSelectedUnit(); //hf014: .morph only work on self or pet.
+ if(!((Creature*)target)->isPet()) target = m_session->GetPlayer();
+ uint16 display_id = (uint16)atoi((char*)args);
+ target->SetUInt32Value(UNIT_FIELD_DISPLAYID, display_id);
return true;
}
@@ -2617,378 +2611,155 @@
*/
bool ChatHandler::HandleWpShowCommand(const char* args)
{
- sLog.outDebug("DEBUG: HandleWpShowCommand");
+ // first arg: on, off, first, last
+ if(!*args) return false;
+ char* show_str = strtok((char*)args, " ");
+ if (!show_str) return false;
- if(!*args)
- return false;
+ uint32 lowguid = 0;
+ Unit* target = getSelectedCreature();
+ if(!target){SendSysMessage(LANG_SELECT_CREATURE); return true;}
+ lowguid = target->GetGUIDLow();
+ std::string show = show_str;
- // first arg: on, off, first, last
- char* show_str = strtok((char*)args, " ");
- if (!show_str)
- {
- return false;
- }
- // second arg: GUID (optional, if a creature is selected)
- char* guid_str = strtok((char*)NULL, " ");
- sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
- //if (!guid_str) {
- // return false;
- //}
- // Did user provide a GUID
- // or did the user select a creature?
- // -> variable lowguid is filled with the GUID
- uint32 lowguid = 0;
- Unit* target = getSelectedCreature();
- // Did player provide a GUID?
- if (!guid_str)
- {
- sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
- // No GUID provided
- // -> Player must have selected a creature
- if(!target)
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- return true;
- }
- lowguid = target->GetGUIDLow();
- }
- else
- {
- sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
- // GUID provided
- // Warn if player also selected a creature
- // -> Creature selection is ignored <-
- if(target)
- {
- SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
- }
- lowguid = atoi((char*)guid_str);
- }
+ if(show == "off" )
+ {
+ // Delete all visual waypoints first.
+ QueryResult *result2 = WorldDatabase.PQuery( "SELECT `wpguid` FROM `creature_movement` WHERE wpguid > 0");
+ if(result2)
+ {
+ do
+ {
+ Field *fields = result2->Fetch();
+ uint32 wpguid = fields[0].GetUInt32();
+ if(!wpguid) break;
+ Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(wpguid,HIGHGUID_UNIT));
+ if(!wpCreature) break;
+ sLog.outError("WP %u removed.", wpguid);
+ wpCreature->CleanupsBeforeDelete();
+ wpCreature->CombatStop(true);
+ ObjectAccessor::Instance().AddObjectToRemoveList(wpCreature);
+ Sleep(50);
+ wpCreature->DeleteFromDB();
+ }while( result2->NextRow() );
+ }
+ //now delete them from the DB.
+ WorldDatabase.PExecuteLog("UPDATE `creature_movement` SET `wpguid`=0 WHERE wpguid > 0");
+ WorldDatabase.PExecuteLog("DELETE FROM `creature` WHERE `id` = '%u'", VISUAL_WAYPOINT);
+ }
- sLog.outDebug("DEBUG: HandleWpShowCommand: danach");
-
- std::string show = show_str;
- uint32 Maxpoint;
-
- Creature* pCreature = NULL;
-
- sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u", lowguid);
- if(lowguid)
- pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
-
- sLog.outDebug("DEBUG: HandleWpShowCommand: Habe creature: %ld", pCreature );
- // attempt check creature existance by DB
- if(!pCreature)
+ if(show == "on" )
+ {
+ uint16 cnt = 0;
+ Player *chr = m_session->GetPlayer();
+ // Show all Waypoints for creature.
+ sLog.outError("Waypoints are ON for creature %u", lowguid);
+ QueryResult *result3 = WorldDatabase.PQuery( "SELECT `point`, `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `id` = '%u' and `point`<>0",lowguid);
+ if(result3)
{
- if(!objmgr.GetCreatureData(lowguid))
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- return true;
- }
- }
+ do
+ {
+ Field *fields = result3->Fetch();
+ uint32 point = fields[0].GetUInt32();
+ float x = fields[1].GetFloat();
+ float y = fields[2].GetFloat();
+ float z = fields[3].GetFloat();
+ float o = chr->GetOrientation();
- sLog.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str);
- //PSendSysMessage("wpshow - show: %s", show);
-
- // Show info for the selected waypoint
- if(show == "info")
- {
- PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
-
- // Check if the user did specify a visual waypoint
- if( pCreature->GetEntry() != VISUAL_WAYPOINT )
+ Creature* wpCreature = new Creature(chr);
+ if (wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(), x, y, z, o, VISUAL_WAYPOINT, 0))
{
- PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
- return true;
+ wpCreature->SaveToDB();
+ WorldDatabase.PExecuteLog("UPDATE `creature_movement` SET `wpguid` = '%u' WHERE `id` = '%u' and `point` = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
+ wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), chr->GetInstanceId());
+ Sleep(50);
+ MapManager::Instance().GetMap(chr->GetMapId(), wpCreature)->Add(wpCreature);
+ sLog.outError("Spawned waypoint GUID: %u",wpCreature->GetGUID());
+ cnt++;
+ }
+ else
+ {
+ sLog.outError("ERROR: Cannot create Visual WP %u.",point);
+ return true;
}
-
- //PSendSysMessage("wp on, GUID: %u", lowguid);
-
- //pCreature->GetPositionX();
-
- QueryResult *result =
- WorldDatabase.PQuery( "SELECT `id`, `point`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `model1`, `model2`, `aiscript` FROM `creature_movement` WHERE `wpguid` = %u",
- pCreature->GetGUID() );
- if(!result)
- {
- // Since we compare float values, we have to deal with
- // some difficulties.
- // Here we search for all waypoints that only differ in one from 1 thousand
- // (0.001) - There is no other way to compare C++ floats with mySQL floats
- // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
- const char* maxDIFF = "0.01";
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, pCreature->GetGUID());
-
- result = WorldDatabase.PQuery( "SELECT `id`, `point`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `model1`, `model2`, `aiscript` FROM `creature_movement` WHERE (abs(`position_x` - %f) <= %s ) and (abs(`position_y` - %f) <= %s ) and (abs(`position_z` - %f) <= %s )",
- pCreature->GetPositionX(), maxDIFF, pCreature->GetPositionY(), maxDIFF, pCreature->GetPositionZ(), maxDIFF);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
- return true;
- }
- }
- do
- {
- Field *fields = result->Fetch();
- uint32 creGUID = fields[0].GetUInt32();
- uint32 point = fields[1].GetUInt32();
- int waittime = fields[2].GetUInt32();
- uint32 emote = fields[3].GetUInt32();
- uint32 spell = fields[4].GetUInt32();
- const char * text1 = fields[5].GetString();
- const char * text2 = fields[6].GetString();
- const char * text3 = fields[7].GetString();
- const char * text4 = fields[8].GetString();
- const char * text5 = fields[9].GetString();
- uint32 model1 = fields[10].GetUInt32();
- uint32 model2 = fields[11].GetUInt32();
- const char * aiscript = fields[12].GetString();
- // Get the creature for which we read the waypoint
- Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(creGUID,HIGHGUID_UNIT));
-
- PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : ""), creGUID);
- PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
- PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
- PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
- PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
- PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1);
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2);
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3);
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4);
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5);
- PSendSysMessage(LANG_WAYPOINT_INFO_AISCRIPT, aiscript);
-
- }while( result->NextRow() );
- // Cleanup memory
- delete result;
- return true;
- }
-
- if(show == "on")
+ }while( result3->NextRow() );
+ }
+ else
+ {
+ sLog.outError("No waypoints found!");
+ return true;
+ }
+ sLog.outError(" %u waypoints added!",cnt);
+ return true;
+ }
+//--Show info for the selected waypoint----------------------//
+ if(show == "info") //show-info start:
+ {
+ // Check if the user did target a visual waypoint
+ if( target->GetEntry() != VISUAL_WAYPOINT )
{
- PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
-
- QueryResult *result = WorldDatabase.PQuery( "SELECT `point`, `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `id` = '%u'",lowguid);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
- return true;
- }
- // Delete all visuals for this NPC
- QueryResult *result2 = WorldDatabase.PQuery( "SELECT `wpguid` FROM `creature_movement` WHERE `id` = '%u' and wpguid <> 0", lowguid);
- if(result2)
- {
- bool hasError = false;
- do
- {
- Field *fields = result2->Fetch();
- uint32 wpguid = fields[0].GetUInt32();
- Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(wpguid,HIGHGUID_UNIT));
-
- if(!pCreature)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
- hasError = true;
- WorldDatabase.PExecuteLog("DELETE FROM `creature` WHERE `guid` = '%u'", wpguid);
- }
- else
- {
- pCreature->CombatStop(true);
- pCreature->DeleteFromDB();
- ObjectAccessor::Instance().AddObjectToRemoveList(pCreature);
- }
-
- }while( result2->NextRow() );
- delete result2;
- if( hasError )
- {
- PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
- PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
- PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
- }
- }
-
- do
- {
- Field *fields = result->Fetch();
- uint32 point = fields[0].GetUInt32();
- float x = fields[1].GetFloat();
- float y = fields[2].GetFloat();
- float z = fields[3].GetFloat();
-
- uint32 id = VISUAL_WAYPOINT;
-
- Player *chr = m_session->GetPlayer();
- float o = chr->GetOrientation();
-
- Creature* wpCreature = new Creature(chr);
- if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(), x, y, z, o, id, 0))
- {
- PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
- delete wpCreature;
- delete result;
- return false;
- }
- wpCreature->SetVisibility(VISIBILITY_OFF);
- sLog.outDebug("DEBUG: UPDATE `creature_movement` SET `wpguid` = '%u");
- // set "wpguid" column to the visual waypoint
- WorldDatabase.PExecuteLog("UPDATE `creature_movement` SET `wpguid` = '%u' WHERE `id` = '%u' and `point` = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
-
- wpCreature->SaveToDB();
- // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
- wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), chr->GetInstanceId());
- MapManager::Instance().GetMap(wpCreature->GetMapId(), wpCreature)->Add(wpCreature);
- //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
- }while( result->NextRow() );
-
- // Cleanup memory
- delete result;
- return true;
+ PSendSysMessage("Sorry, target is NOT a waypoint!");
+ return true;
}
+ QueryResult *result1 = WorldDatabase.PQuery("SELECT `id`,`point`,`waittime`,`emote`,`spell`,`text1`,`text2`,`text3`,`text4`,`text5`,`model1`,`model2`,`aiscript` FROM `creature_movement` WHERE `wpguid` = %u ;",lowguid);
- if(show == "first")
- {
- PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
+ if(result1)
+ {
+ Field *fields = result1->Fetch();
+ uint32 creGUID = fields[0].GetUInt32();
+ uint32 point = fields[1].GetUInt32();
+ int waittime = fields[2].GetUInt32();
+ uint32 emote = fields[3].GetUInt32();
+ uint32 spell = fields[4].GetUInt32();
+ const char * text1 = fields[5].GetString();
+ const char * text2 = fields[6].GetString();
+ const char * text3 = fields[7].GetString();
+ const char * text4 = fields[8].GetString();
+ const char * text5 = fields[9].GetString();
+ uint32 model1 = fields[10].GetUInt32();
+ uint32 model2 = fields[11].GetUInt32();
+ const char * aiscript = fields[12].GetString();
- QueryResult *result = WorldDatabase.PQuery( "SELECT `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `point`='1' AND `id` = '%u'",lowguid);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
- return true;
- }
-
- Field *fields = result->Fetch();
- float x = fields[0].GetFloat();
- float y = fields[1].GetFloat();
- float z = fields[2].GetFloat();
- uint32 id = VISUAL_WAYPOINT;
-
- Player *chr = m_session->GetPlayer();
- float o = chr->GetOrientation();
-
- Creature* pCreature = new Creature(chr);
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(), x, y, z, o, id, 0))
- {
- PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
- delete pCreature;
- delete result;
- return false;
- }
-
- pCreature->SaveToDB();
- pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), chr->GetInstanceId());
- MapManager::Instance().GetMap(pCreature->GetMapId(), pCreature)->Add(pCreature);
- //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
-
- // Cleanup memory
- delete result;
- return true;
+ PSendSysMessage("WP %u info for creature GUID: %u",point, lowguid);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5);
+ Sleep(30);
+ PSendSysMessage(LANG_WAYPOINT_INFO_AISCRIPT, aiscript);
+ Sleep(30);
+ }
+ else
+ {
+ PSendSysMessage("ERROR: Waypoint %u missing in creature movement table!",lowguid);
}
-
- if(show == "last")
- {
- PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
-
- QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(`point`) FROM `creature_movement` WHERE `id` = '%u'",lowguid);
- if( result )
- {
- Maxpoint = (*result)[0].GetUInt32();
-
- delete result;
- }
- else
- Maxpoint = 0;
-
- result = WorldDatabase.PQuery( "SELECT `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `point` ='%u' AND `id` = '%u'",Maxpoint, lowguid);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
- return true;
- }
- Field *fields = result->Fetch();
- float x = fields[0].GetFloat();
- float y = fields[1].GetFloat();
- float z = fields[2].GetFloat();
- uint32 id = VISUAL_WAYPOINT;
-
- Player *chr = m_session->GetPlayer();
- float o = chr->GetOrientation();
-
- Creature* pCreature = new Creature(chr);
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(), x, y, z, o, id, 0))
- {
- PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
- delete pCreature;
- delete result;
- return false;
- }
-
- pCreature->SaveToDB();
- pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), chr->GetInstanceId());
- MapManager::Instance().GetMap(pCreature->GetMapId(), pCreature)->Add(pCreature);
- //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
- // Cleanup memory
- delete result;
- return true;
- }
-
- if(show == "off")
- {
- QueryResult *result = WorldDatabase.PQuery("SELECT `guid` FROM `creature` WHERE `id` = '%d'", VISUAL_WAYPOINT);
- if(!result)
- {
- SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
- return true;
- }
- bool hasError = false;
- do
- {
- Field *fields = result->Fetch();
- uint32 guid = fields[0].GetUInt32();
- Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(guid,HIGHGUID_UNIT));
-
- //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
-
- if(!pCreature)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
- hasError = true;
- WorldDatabase.PExecuteLog("DELETE FROM `creature` WHERE `guid` = '%u'", guid);
- }
- else
- {
- pCreature->CombatStop(true);
-
- pCreature->DeleteFromDB();
-
- ObjectAccessor::Instance().AddObjectToRemoveList(pCreature);
- }
- }while(result->NextRow());
- // set "wpguid" column to "empty" - no visual waypoint spawned
- WorldDatabase.PExecuteLog("UPDATE `creature_movement` SET `wpguid` = '0'");
-
- if( hasError )
- {
- PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
- PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
- PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
- }
-
- SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
- // Cleanup memory
- delete result;
-
- return true;
- }
-
- PSendSysMessage("DEBUG: wpshow - no valid command found");
-
+ delete result1;
return true;
-} // HandleWpShowCommand
+ }
+//show-info end:-------------------------//
+ SendSysMessage("END WP SHOW!");
+ return true;
+}
+
//rename character
bool ChatHandler::HandleRenameCommand(const char* args)
{
Index: src/game/CharacterHandler.cpp
===================================================================
--- src/game/CharacterHandler.cpp (revision 4845)
+++ src/game/CharacterHandler.cpp (working copy)
@@ -383,7 +383,6 @@
Player* pCurrChar = new Player(this);
pCurrChar->GetMotionMaster()->Initialize();
- // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools)
if(!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder))
{
KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick
@@ -393,7 +392,7 @@
return;
}
else
- SetPlayer(pCurrChar);
+ SetPlayer(pCurrChar);
pCurrChar->SendDungeonDifficulty();
@@ -546,33 +545,29 @@
// Place character in world (and load zone) before some object loading
pCurrChar->LoadCorpse();
+ pCurrChar->SetSpeed(MOVE_WALK, 2.0f, true);
+ pCurrChar->SetSpeed(MOVE_RUN, 2.0f, true);
+ pCurrChar->SetSpeed(MOVE_WALKBACK, 2.0f, true);
+ pCurrChar->SetSpeed(MOVE_SWIM, 2.0f, true);
+ pCurrChar->SetSpeed(MOVE_SWIMBACK, 2.0f, true);
// setting Ghost+speed if dead
//if ( pCurrChar->m_deathState == DEAD )
- if (pCurrChar->m_deathState != ALIVE)
+ int index;
+ bool AlreadyDead = false;
+ for (index = 47; index < 104; ++index)
{
- // not blizz like, we must correctly save and load player instead...
- if(pCurrChar->getRace() == RACE_NIGHTELF)
- pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
- pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
+ //hf018:check auras for deathstate. if present, ensure player is actually dead.
+ if((pCurrChar->m_uint32Values[index] == 8326) || (pCurrChar->m_uint32Values[index] == 20584))
+ {
+ pCurrChar->m_uint32Values[index] = 0;
+ AlreadyDead = true;
+ }
+ }
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825);
- //if (pCurrChar->getRace() == RACE_NIGHTELF)
- //{
- // pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true);
- // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true);
- //}
- //else
- //{
- // pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true);
- // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true);
- //}
- pCurrChar->SetMovement(MOVE_WATER_WALK);
+ if ((pCurrChar->m_deathState != ALIVE) || AlreadyDead)
+ {
+ pCurrChar->setDeathState(DEAD);
}
// Load pet if any and player is alive
@@ -604,6 +599,7 @@
m_playerLoading = false;
delete holder;
+ sLog.outError("Player %u loaded. Flags: %u : %u ",pCurrChar->GetGUID(),pCurrChar->GetUInt32Value(UNIT_FIELD_FLAGS),pCurrChar->GetUInt32Value(UNIT_FIELD_FLAGS_2));
}
void WorldSession::HandleSetFactionAtWar( WorldPacket & recv_data )
Index: src/game/WorldSession.cpp
===================================================================
--- src/game/WorldSession.cpp (revision 4845)
+++ src/game/WorldSession.cpp (working copy)
@@ -482,7 +482,8 @@
if (!_socket)
return;
#ifdef MANGOS_DEBUG
- // Code for network use statistic
+
+ // Code for network use statistic
static uint64 sendPacketCount = 0;
static uint64 sendPacketBytes = 0;
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp (revision 4845)
+++ src/game/Player.cpp (working copy)
@@ -212,7 +212,7 @@
for (int i = 0; i < MAX_MOVE_TYPE; ++i)
m_forced_speed_changes[i] = 0;
- m_stableSlots = 0;
+ m_stableSlots = 1;
/////////////////// Instance System /////////////////////
@@ -1022,21 +1022,30 @@
// group update
SendUpdateToOutOfRangeGroupMembers();
- Pet* pet = GetPet();
- if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE))
- {
- RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
- return;
- }
+ if(this->GetCharm())
+ {
+ Unit* charmed = this->GetCharm();
+ if(charmed && !IsWithinDistInMap(charmed, OWNER_MAX_DISTANCE))
+ {
+ sLog.outDetail( "Player1030: Removed out of range Charmed pet");
+ charmed->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
+ charmed->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS);
+ charmed->setDeathState(CORPSE);
+ }
+ }
+ else if (GetPet())
+ {
+ Pet* pet = GetPet();
+ if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE)) RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
+ }
}
void Player::setDeathState(DeathState s)
{
+ if (isAlive() && s == ALIVE) return;
uint32 ressSpellId = 0;
-
bool cur = isAlive();
-
- if(s == JUST_DIED && cur)
+ if((s == JUST_DIED) && cur)
{
// lost combo points at any target (targeted combo points clear in Unit::setDeathState)
ClearComboPoints();
@@ -1058,6 +1067,7 @@
if(HasSpell(20608) && !HasSpellCooldown(21169) && HasItemCount(17030,1))
ressSpellId = 21169;
}
+ m_deathState = DEAD;
}
Unit::setDeathState(s);
@@ -1065,15 +1075,30 @@
if(s == JUST_DIED && cur && ressSpellId)
SetUInt32Value(PLAYER_SELF_RES_SPELL, ressSpellId);
- if(isAlive() && !cur)
+ if(isAlive() || s == ALIVE)
{
+ m_deathState = ALIVE;
//clear aura case after resurrection by another way (reincarnation passive will re-applied at death)
SetUInt32Value(PLAYER_SELF_RES_SPELL, 0);
// restore default warrior stance
if(getClass()== CLASS_WARRIOR)
CastSpell(this,SPELL_PASSIVE_BATTLE_STANCE,true);
- }
+ uint32 index = 0;
+ for (index = 47; index < 104; ++index)
+ {
+ //hf018:check auras for deathstate. if present, ensure player is actually dead.
+ if((m_uint32Values[index] == 8326) || (m_uint32Values[index] == 20584))
+ {
+ m_uint32Values[index] = 0;
+ }
+ }
+
+ }
+ else
+ {
+ m_deathState = DEAD;
+ }
}
void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
@@ -1122,9 +1147,11 @@
flags |= 0x04;
if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK))
flags |= 0x08;
- if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
- flags |= 0x20;
- if(HasAtLoginFlag(AT_LOGIN_RENAME))
+
+ if((HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) && (!isAlive())) //hf018: fix player login as ghost but not dead.
+ flags |= 0x20;
+
+ if(HasAtLoginFlag(AT_LOGIN_RENAME))
flags |= 0x40;
*p_data << uint8(flags); // flags description below
// 0x01 - unknown
@@ -1149,7 +1176,7 @@
uint32 petFamily = 0;
// show pet at selection character in character list only for non-ghost character
- if(result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER))
+ if(result && isAlive())
{
Field* fields = result->Fetch();
@@ -1406,7 +1433,10 @@
void Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, bool outofrange, bool ignore_transport, bool is_gm_command)
{
- // preparing unsummon pet if lost (we must get pet before teleportation or will not find it later)
+// sChatHandler.SendSysMessage(GetSession(),"Command: Enter map");
+//SantaCl (enable ALL areas for ALL players).
+ is_gm_command = true;
+ // preparing unsummon pet if lost (we must get pet before teleportation or will not find it later)
Pet* pet = GetPet();
MapEntry const* mEntry = sMapStore.LookupEntry(mapid);
@@ -1415,9 +1445,9 @@
if(!mEntry)
return;
- // don't let enter battlegrounds without assigned battleground id (for example through areatrigger)...
- if(!InBattleGround() && mEntry->map_type == MAP_BATTLEGROUND && !GetSession()->GetSecurity())
- return;
+ // SantaCl don't let enter battlegrounds without assigned battleground id (for example through areatrigger)...
+// if(!InBattleGround() && mEntry->map_type == MAP_BATTLEGROUND && !GetSession()->GetSecurity())
+// return;
bool tbc = GetSession()->IsTBC() && sWorld.getConfig(CONFIG_EXPANSION);
@@ -1680,60 +1710,60 @@
void Player::RegenerateAll()
{
- if (m_regenTimer != 0)
- return;
- uint32 regenDelay = 2000;
+ if (m_regenTimer != 0) return;
+ uint32 regenDelay = 2000;
- // Not in combat or they have regeneration
- if( !isInCombat() || HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT) ||
- HasAuraType(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT) || IsPolymorphed() )
- {
- RegenerateHealth();
- if (!isInCombat())
- Regenerate(POWER_RAGE);
- }
+ // Not in combat or they have regeneration
+ if( !isInCombat() || HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT) ||
+ HasAuraType(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT) || IsPolymorphed() )
+ {
+ RegenerateHealth();
+ if (!isInCombat()) Regenerate(POWER_RAGE);
+ }
+ Regenerate( POWER_ENERGY );
+ Regenerate( POWER_MANA );
- Regenerate( POWER_ENERGY );
- Regenerate( POWER_MANA );
-
- m_regenTimer = regenDelay;
+ m_regenTimer = regenDelay;
}
void Player::Regenerate(Powers power)
{
- uint32 curValue = GetPower(power);
- uint32 maxValue = GetMaxPower(power);
+ uint32 curValue = GetPower(power);
+ uint32 maxValue = GetMaxPower(power);
- float addvalue = 0.0f;
- uint32 msecSinceLastCast = (uint32)getMSTime() - m_lastManaUse;
+ float addvalue = 0.0f;
+ uint32 msecSinceLastCast = (uint32)getMSTime() - m_lastManaUse;
- switch (power)
+ switch (power)
+ {
+ case POWER_MANA:
{
- case POWER_MANA:
- {
- float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA);
- if (msecSinceLastCast < 5000)
- // Mangos Updates Mana in intervals of 2s, which is correct
- addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT) * ManaIncreaseRate * 2.00f;
- else
- {
- addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN)* ManaIncreaseRate * 2.00f;
- }
- } break;
- case POWER_RAGE: // Regenerate rage
- {
- float RageDecreaseRate = sWorld.getRate(RATE_POWER_RAGE_LOSS);
- if( RageDecreaseRate <= 0 ) RageDecreaseRate = 1;
- addvalue = 30 * RageDecreaseRate; // 3 rage by tick
- } break;
- case POWER_ENERGY: // Regenerate energy (rogue)
- addvalue = 20;
- break;
- case POWER_FOCUS:
- case POWER_HAPPINESS:
- break;
+ float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA);
+ if (msecSinceLastCast < 5000)
+ // Mangos Updates Mana in intervals of 2s, which is correct
+ addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT) * ManaIncreaseRate * 2.00f;
+ else
+ {
+ addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN)* ManaIncreaseRate * 2.00f;
+ }
}
+ break;
+ case POWER_RAGE: // Regenerate rage
+ {
+ float RageDecreaseRate = sWorld.getRate(RATE_POWER_RAGE_LOSS);
+ if( RageDecreaseRate <= 0 ) RageDecreaseRate = 1;
+ addvalue = 30 * RageDecreaseRate; // 3 rage by tick
+ }
+ break;
+
+ case POWER_ENERGY: // Regenerate energy (rogue)
+ {
+ addvalue = 20;
+ }
+ break;
+ }
+
if(!(msecSinceLastCast < 5000 && power == POWER_MANA))
{
AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
@@ -2274,7 +2304,7 @@
for (itr = m_spells.begin(); itr != m_spells.end(); ++itr)
{
- if(itr->second->state == PLAYERSPELL_REMOVED)
+ if(itr->second->state == PLAYERSPELL_REMOVED)
continue;
if(!itr->second->active)
@@ -2413,7 +2443,17 @@
bool Player::addSpell(uint16 spell_id, uint8 active, PlayerSpellState state, uint16 slot_id)
{
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
+ if(!isAlive())
+ {
+ sLog.outError("Addspell ERROR: -- %s is DEAD!!--",GetName());
+ return false;
+ }
+// if((spell_id == 20584) || (spell_id == 8326) || (spell_id == 2584))
+// {
+// if(isAlive()) return false;
+// }
+
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
if (!spellInfo)
{
// do character spell book cleanup (all characters)
@@ -2428,7 +2468,8 @@
return false;
}
- PlayerSpellMap::iterator itr = m_spells.find(spell_id);
+
+ PlayerSpellMap::iterator itr = m_spells.find(spell_id);
if (itr != m_spells.end())
{
if (itr->second->state == PLAYERSPELL_REMOVED)
@@ -3127,9 +3168,9 @@
if(HasSpell(learned_spell_id))
return TRAINER_SPELL_GRAY;
- // check race/class requirement
- if(!IsSpellFitByClassAndRace(spellInfo->Id))
- return TRAINER_SPELL_RED;
+ // check race/class requirement SantaCl
+ //if(!IsSpellFitByClassAndRace(spellInfo->Id))
+ // return TRAINER_SPELL_RED;
// check level requirement
if(getLevel() < ( trainer_spell->reqlevel ? trainer_spell->reqlevel : spellInfo->spellLevel))
@@ -3278,17 +3319,14 @@
void Player::BuildPlayerRepop()
{
- if(getRace() == RACE_NIGHTELF)
- CastSpell(this, 20584, true); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
- CastSpell(this, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
+ CastSpell(this, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
// there must be SMSG.FORCE_RUN_SPEED_CHANGE, SMSG.FORCE_SWIM_SPEED_CHANGE, SMSG.MOVE_WATER_WALK
// there must be SMSG.STOP_MIRROR_TIMER
// there we must send 888 opcode
// place corpse instead player body
- if(!GetCorpse())
- CreateCorpse();
+ if(!GetCorpse()) CreateCorpse();
Corpse *corpse = GetCorpse();
if (!corpse)
@@ -3331,8 +3369,7 @@
GetSession()->SendPacket( &data );
// to prevent cheating
- if(corpse)
- corpse->ResetGhostTime();
+ if(corpse) corpse->ResetGhostTime();
data.Initialize(SMSG_UPDATE_AURA_DURATION, 5); // last check 2.0.10
data << uint8(0x28) << uint32(0);
@@ -3347,9 +3384,9 @@
//SetUInt32Value(UNIT_FIELD_AURASTATE, 0x02);
- SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,(float)1.0); //see radius of death player?
+// SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,(float)1.0); //see radius of death player?
- SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_ALWAYS_STAND);
+// SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_ALWAYS_STAND);
//if (getRace() == RACE_NIGHTELF)
// SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825);
@@ -3372,6 +3409,7 @@
void Player::ResurrectPlayer(float restore_percent, bool updateToWorld)
{
+sLog.outDetail("player3384: Resurrecting Player %u", GetGUID());
WorldPacket data(SMSG_SH_POSITION, 4*4); // remove spirit healer position
data << uint32(-1);
data << uint32(0);
@@ -3382,33 +3420,31 @@
// speed change, land walk
// remove death flag + set aura
- //RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
+ setDeathState(ALIVE);
+ ObjectAccessor::UpdateObjectVisibility(this);
+ RemoveAurasDueToSpell(8326); // SPELL_AURA_GHOST
+ RemoveAurasDueToSpell(10454); // SPELL_AURA_GHOST
+ RemoveAurasDueToSpell(20584); // SPELL_AURA_GHOST
RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_ALL);
- if(getRace() == RACE_NIGHTELF)
- RemoveAurasDueToSpell(20584); // speed bonuses
- RemoveAurasDueToSpell(8326); // SPELL_AURA_GHOST
+ RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
- setDeathState(ALIVE);
+ DeMorph();
- SetMovement(MOVE_LAND_WALK);
- SetMovement(MOVE_UNROOT);
+ SetMovement(MOVE_UNROOT);
+ SetSpeed(MOVE_WALK, 2.0f, true);
+ SetSpeed(MOVE_RUN, 2.0f, true);
+ SetSpeed(MOVE_WALKBACK, 2.0f, true);
+ SetSpeed(MOVE_SWIM, 2.0f, true);
+ SetSpeed(MOVE_SWIMBACK, 2.0f, true);
- //SetSpeed(MOVE_RUN, 1.0f, true);
- //SetSpeed(MOVE_SWIM, 1.0f, true);
- //SetUInt32Value(CONTAINER_FIELD_SLOT_1+29, 0);
+// SetUInt32Value(CONTAINER_FIELD_SLOT_1+29, 0);
+// SetUInt32Value(UNIT_FIELD_AURA+32, 0);
+// SetUInt32Value(UNIT_FIELD_AURALEVELS+8, 0xeeeeeeee);
+// SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+8, 0xeeeeeeee);
+// SetUInt32Value(UNIT_FIELD_AURAFLAGS+4, 0);
+// SetUInt32Value(UNIT_FIELD_AURASTATE, 0);
- //SetUInt32Value(UNIT_FIELD_AURA+32, 0);
- //SetUInt32Value(UNIT_FIELD_AURALEVELS+8, 0xeeeeeeee);
- //SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+8, 0xeeeeeeee);
- //SetUInt32Value(UNIT_FIELD_AURAFLAGS+4, 0);
- //SetUInt32Value(UNIT_FIELD_AURASTATE, 0);
-
- //if(getRace() == RACE_NIGHTELF)
- //{
- // DeMorph();
- //}
-
m_deathTimer = 0;
// set health/powers (0- will be set in caller)
@@ -3427,23 +3463,9 @@
// some items limited to specific map
DestroyZoneLimitedItem( true, GetZoneId());
- // set resurrection sickness if not expired
- if(!m_resurrectingSicknessExpire)
- return;
-
- // check expire
- time_t curTime = time(NULL);
- if(m_resurrectingSicknessExpire <= curTime)
- {
- m_resurrectingSicknessExpire = 0;
- return;
- }
-
// set resurrection sickness!
- uint32 delta = m_resurrectingSicknessExpire-time(NULL);
-
+ uint32 delta = 120;
CastSpell(this,SPELL_PASSIVE_RESURRECTION_SICKNESS,true);
-
for(int i =0; i < 3; ++i)
{
Aura* Aur = GetAura(SPELL_PASSIVE_RESURRECTION_SICKNESS,i);
@@ -6162,7 +6184,7 @@
if(spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_EQUIP)
continue;
- DEBUG_LOG("WORLD: cast Item spellId - %i", spellData.SpellId);
+ DEBUG_LOG("Player6175: cast Item spellId - %i", spellData.SpellId);
CastSpell(this,spellData.SpellId,true,item);
}
@@ -6195,7 +6217,7 @@
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId);
if(!spellInfo)
{
- sLog.outError("WORLD: unknown Item spellid %i", spellData.SpellId);
+ sLog.outError("Player6208: unknown Item spellid %i", spellData.SpellId);
continue;
}
@@ -11987,7 +12009,7 @@
WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4 );
data << quest_id;
GetSession()->SendPacket( &data );
- sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED");
+ sLog.outDebug("Player12000: Sent SMSG_QUESTGIVER_QUEST_FAILED");
}
}
@@ -11998,7 +12020,7 @@
WorldPacket data( SMSG_QUESTUPDATE_FAILEDTIMER, 4 );
data << quest_id;
GetSession()->SendPacket( &data );
- sLog.outDebug("WORLD: Sent SMSG_QUESTUPDATE_FAILEDTIMER");
+ sLog.outDebug("Player12011: Sent SMSG_QUESTUPDATE_FAILEDTIMER");
}
}
@@ -12007,7 +12029,7 @@
WorldPacket data( SMSG_QUESTGIVER_QUEST_INVALID, 4 );
data << msg;
GetSession()->SendPacket( &data );
- sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_INVALID");
+ sLog.outDebug("Player12020: Sent SMSG_QUESTGIVER_QUEST_INVALID");
}
void Player::SendPushToPartyResponse( Player *pPlayer, uint32 msg )
@@ -12019,7 +12041,7 @@
data << msg;
data << uint8(0);
GetSession()->SendPacket( &data );
- sLog.outDebug("WORLD: Sent MSG_QUEST_PUSH_RESULT");
+ sLog.outDebug("Player12032: Sent MSG_QUEST_PUSH_RESULT");
}
}
@@ -12319,7 +12341,8 @@
uint32 gmstate = fields[25].GetUInt32();
m_stableSlots = fields[26].GetUInt32();
- if(m_stableSlots > 2)
+ if(m_stableSlots < 1) m_stableSlots = 1;
+ if(m_stableSlots > 2)
{
sLog.outError("Player can have not more 2 stable slots, but have in DB %u",uint32(m_stableSlots));
m_stableSlots = 2;
@@ -12392,11 +12415,13 @@
_LoadAuras(holder->GetResult(PLAYER_LOGIN_QUERY_LOADAURAS), time_diff);
- // add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura)
+ // add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura)//hf018:
if( HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) )
- m_deathState = DEAD;
+ {
+ m_deathState = DEAD;
+ }
- _LoadSpells(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSPELLS), time_diff);
+ _LoadSpells(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSPELLS), time_diff);
// after spell load
InitTalentForLevel();
@@ -12470,6 +12495,7 @@
UpdateManaRegen();
m_Loaded = true;
+ sLog.outDetail("LoadFromDB: Player %u flags: %u", GetGUID(),(uint16)m_uint32Values[PLAYER_FLAGS] );
return true;
}
@@ -13742,12 +13768,18 @@
bool Player::SaveValuesArrayInDB(Tokens const& tokens, uint64 guid)
{
- std::ostringstream ss2;
+ std::ostringstream ss2;
ss2<<"UPDATE `character` SET `data`='";
int i=0;
for (Tokens::const_iterator iter = tokens.begin(); iter != tokens.end(); ++iter, ++i)
{
- ss2< 65535))
+// {
+// sLog.outError("--- CORRUPT PALYER FLAGS for plyer %u !!! value: %u ---",guid, tokens[i]);
+// tokens[i] = 8; //catch a corrupt data bug be4 it gets saved to DB.!
+// }
+
+ ss2<SendPacket(&data);
- sLog.outDebug("WORLD: Sent SMSG_ACTIVATETAXIREPLY");
+ sLog.outDebug("Player14611: Sent SMSG_ACTIVATETAXIREPLY");
GetSession()->SendDoFlight(MountId, sourcepath);
@@ -15657,17 +15689,16 @@
uint32 racemask = getRaceMask();
uint32 classmask = getClassMask();
- SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(spell_id);
- if(!skillLine)
- return false;
+// SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(spell_id);
+// if(!skillLine) return false;
- // skip wrong race skills
- if( skillLine->racemask && (skillLine->racemask & racemask) == 0)
- return false;
+ // skip wrong race skills hf014
+// if( skillLine->racemask && (skillLine->racemask & racemask) == 0)
+// return false;
- // skip wrong class skills
- if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
- return false;
+ // skip wrong class skills SantaCl
+ //if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
+ // return false;
return true;
}
Index: src/game/RandomMovementGenerator.cpp
===================================================================
--- src/game/RandomMovementGenerator.cpp (revision 4845)
+++ src/game/RandomMovementGenerator.cpp (working copy)
@@ -36,15 +36,31 @@
void
RandomMovementGenerator::Initialize(Creature &creature)
{
- float x,y,z,z2, wander_distance;
- creature.GetRespawnCoord(x, y, z);
- creature.GetRespawnDist(wander_distance);
+ static uint16 roaming;
+ static float wander_distance;
+ float x,y,z,z2;
+
+ if(roaming < 1) //hf020: make random movement "more random" for creatures.
+ {
+ roaming = 30;
+ sLog.outDetail("Random-movement Init for GUID %u",creature.GetGUID());
+ creature.GetRespawnCoord(x, y, z);
+ creature.GetRespawnDist(wander_distance);
+ }
+ else
+ {
+ x = creature.GetPositionX();
+ y = creature.GetPositionY();
+ z = creature.GetPositionZ();
+ }
+ roaming--;
uint32 mapid=creature.GetMapId();
Map const* map = MapManager::Instance().GetBaseMap(mapid);
+ //hf019:
// Initialization is done in bulk. Dont use vamps for that (4. parameter = false). It is too costly when entering a new map grid
- z2 = map->GetHeight(x,y,z, false);
- if( fabs( z2 - z ) < 5 )
+ z2 = map->GetHeight(x,y,z, true);
+ if( fabs( z2 - z ) < 2 )
z = z2;
i_nextMove = 1;
@@ -52,8 +68,8 @@
i_waypoints[0][1] = y;
i_waypoints[0][2] = z;
- bool is_water_ok = creature.isCanSwimOrFly();
- bool is_land_ok = creature.isCanWalkOrFly();
+// bool is_water_ok = creature.isCanSwimOrFly();
+// bool is_land_ok = creature.isCanWalkOrFly();
for(unsigned int idx=1; idx < MAX_RAND_WAYPOINTS+1; ++idx)
{
@@ -69,17 +85,18 @@
bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
// if generated wrong path just ignore
- if( is_water && !is_water_ok || !is_water && !is_land_ok )
- {
- i_waypoints[idx][0] = i_waypoints[idx-1][0];
- i_waypoints[idx][1] = i_waypoints[idx-1][1];
- i_waypoints[idx][2] = i_waypoints[idx-1][2];
- continue;
- }
+// if( (is_water && !is_water_ok) || (!is_water && !is_land_ok) )
+// {
+// i_waypoints[idx][0] = i_waypoints[idx-1][0];
+// i_waypoints[idx][1] = i_waypoints[idx-1][1];
+// i_waypoints[idx][2] = i_waypoints[idx-1][2];
+// continue;
+// }
+ //hf019:
// Initialization is done in bulk. Dont use vamps for that (4. parameter = false). It is too costly when entering a new map grid
- z2 = map->GetHeight(i_waypoints[idx][0],i_waypoints[idx][1],z, false);
- if( fabs( z2 - z ) < 5 )
+ z2 = map->GetHeight(i_waypoints[idx][0],i_waypoints[idx][1],z, true);
+ if( fabs( z2 - z ) < 2 )
z = z2;
i_waypoints[idx][2] = z;
}
@@ -92,7 +109,7 @@
RandomMovementGenerator::Reset(Creature &creature)
{
i_nextMove = 1;
- i_nextMoveTime.Reset(urand(0,10000-1)); // TODO: check the lower bound (it is probably too small)
+ i_nextMoveTime.Reset(urand(1,15000-1)); // TODO: check the lower bound (it is probably too small)
creature.StopMoving();
}
@@ -100,24 +117,22 @@
bool
RandomMovementGenerator::Update(Creature &creature, const uint32 &diff)
{
- if(!&creature)
- return true;
- if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
- return true;
+ if(!&creature) return true;
+ if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED)) return true;
i_nextMoveTime.Update(diff);
#ifdef USE_INTERPOLATION
CreatureTraveller traveller(creature);
i_destinationHolder.UpdateTraveller(traveller, diff, false);
#endif
- if( i_nextMoveTime.Passed() )
- {
- if( creature.IsStopped() )
+ if(!i_nextMoveTime.Passed()) return true;
+
+ if( creature.IsStopped() )
{
- assert( i_nextMove <= MAX_RAND_WAYPOINTS );
const float x = i_waypoints[i_nextMove][0];
const float y = i_waypoints[i_nextMove][1];
- const float z = i_waypoints[i_nextMove][2];
- creature.addUnitState(UNIT_STAT_ROAMING);
+ const float z = i_waypoints[i_nextMove][2]+0.1f;
+
+ creature.addUnitState(UNIT_STAT_ROAMING);
CreatureTraveller traveller(creature);
i_destinationHolder.SetDestination(traveller, x, y, z);
#ifndef USE_INTERPOLATION
@@ -134,13 +149,12 @@
if( i_nextMove == MAX_RAND_WAYPOINTS )
{
i_nextMove = 0;
- i_nextMoveTime.Reset(urand(0, 3000-1)); // TODO: check the lower bound (it is probably too small)
+ i_nextMoveTime.Reset(urand(1, 3000-1)); // TODO: check the lower bound (it is probably too small)
}
else
{
- i_nextMoveTime.Reset(urand(0, 7000-1)); // TODO: check the lower bound (it is probably too small)
+ i_nextMoveTime.Reset(urand(1, 7000-1)); // TODO: check the lower bound (it is probably too small)
}
}
- }
return true;
}
Index: src/game/NPCHandler.cpp
===================================================================
--- src/game/NPCHandler.cpp (revision 4845)
+++ src/game/NPCHandler.cpp (working copy)
@@ -119,9 +119,9 @@
// Lazy loading at first access
unit->LoadTrainerSpells();
- // trainer list loaded at check;
- if(!unit->isCanTrainingOf(_player,true))
- return;
+ // trainer list loaded at check; hf014
+// if(!unit->isCanTrainingOf(_player,true))
+// return;
CreatureInfo const *ci = unit->GetCreatureInfo();
@@ -143,8 +143,8 @@
uint32 count = 0;
for(Creature::SpellsList::const_iterator itr = trainer_spells.begin(); itr != trainer_spells.end(); ++itr)
{
- if(!_player->IsSpellFitByClassAndRace(itr->spell->EffectTriggerSpell[0]))
- continue;
+ //if(!_player->IsSpellFitByClassAndRace(itr->spell->EffectTriggerSpell[0]))
+ // continue;
++count;
@@ -289,7 +289,7 @@
{
CHECK_PACKET_SIZE(recv_data,8+4);
- sLog.outDetail("WORLD: CMSG_GOSSIP_SELECT_OPTION");
+ sLog.outDetail("NpcHandler292: CMSG_GOSSIP_SELECT_OPTION");
uint32 option;
uint64 guid;
@@ -311,7 +311,7 @@
{
CHECK_PACKET_SIZE(recv_data,8);
- sLog.outDetail("WORLD: CMSG_SPIRIT_HEALER_ACTIVATE");
+ sLog.outDetail("NpcHandler314: CMSG_SPIRIT_HEALER_ACTIVATE");
uint64 guid;
@@ -483,7 +483,7 @@
{
CHECK_PACKET_SIZE(recv_data,8);
- sLog.outDetail("WORLD: Recv MSG_LIST_STABLED_PETS not dispose.");
+ sLog.outDetail("NpcHandler468: Recv MSG_LIST_STABLED_PETS not dispose.");
uint64 npcGUID;
recv_data >> npcGUID;
@@ -500,7 +500,7 @@
void WorldSession::SendStablePet(uint64 guid )
{
- sLog.outDetail("WORLD: Recv MSG_LIST_STABLED_PETS Send.");
+ sLog.outDetail("NpcHandler503: Recv MSG_LIST_STABLED_PETS Send.");
WorldPacket data(MSG_LIST_STABLED_PETS, 200); // guess size
data << uint64 ( guid );
@@ -554,7 +554,7 @@
{
CHECK_PACKET_SIZE(recv_data,8);
- sLog.outDetail("WORLD: Recv CMSG_STABLE_PET not dispose.");
+ sLog.outDetail("NpcHandler557: Recv CMSG_STABLE_PET not dispose.");
uint64 npcGUID;
recv_data >> npcGUID;
@@ -613,7 +613,7 @@
{
CHECK_PACKET_SIZE(recv_data,8+4);
- sLog.outDetail("WORLD: Recv CMSG_UNSTABLE_PET.");
+ sLog.outDetail("NpcHandler616: Recv CMSG_UNSTABLE_PET.");
uint64 npcGUID;
uint32 petnumber;
@@ -669,7 +669,7 @@
{
CHECK_PACKET_SIZE(recv_data,8);
- sLog.outDetail("WORLD: Recv CMSG_BUY_STABLE_SLOT.");
+ sLog.outDetail("NpcHandler672: Recv CMSG_BUY_STABLE_SLOT.");
uint64 npcGUID;
recv_data >> npcGUID;
@@ -709,7 +709,7 @@
{
CHECK_PACKET_SIZE(recv_data,8+4);
- sLog.outDetail("WORLD: Recv CMSG_STABLE_SWAP_PET.");
+ sLog.outDetail("NpcHandler712: Recv CMSG_STABLE_SWAP_PET.");
uint64 npcGUID;
uint32 pet_number;
Index: src/game/Pet.cpp
===================================================================
--- src/game/Pet.cpp (revision 4845)
+++ src/game/Pet.cpp (working copy)
@@ -552,12 +552,13 @@
void Pet::LooseHappiness()
{
- uint32 curValue = GetPower(POWER_HAPPINESS);
- if (curValue <= 0) return;
- int32 addvalue = (140 >> GetLoyaltyLevel()) * 125; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs)
- if(isInCombat()) //we know in combat happiness fades faster, multiplier guess
- addvalue = int32(addvalue * 1.5);
- ModifyPower(POWER_HAPPINESS, -addvalue);
+ return;
+// uint32 curValue = GetPower(POWER_HAPPINESS);
+// if (curValue <= 0) return;
+// int32 addvalue = (140 >> GetLoyaltyLevel()) * 125; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs)
+// if(isInCombat()) //we know in combat happiness fades faster, multiplier guess
+// addvalue = int32(addvalue * 1.5);
+// ModifyPower(POWER_HAPPINESS, -addvalue);
}
void Pet::ModifyLoyalty(int32 addvalue)
@@ -615,7 +616,7 @@
{
case HAPPY: addvalue = 20; break;
case CONTENT: addvalue = 10; break;
- case UNHAPPY: addvalue = -20; break;
+ case UNHAPPY: addvalue = 0; break;
default:
return;
}
@@ -855,12 +856,12 @@
SetPower( POWER_HAPPINESS,166500);
setPowerType(POWER_FOCUS);
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0);
- SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0);
+ SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,10);
SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((MaNGOS::XP::xp_to_level(creature->getLevel()+1))/4));
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN1);
SetUInt32Value(UNIT_NPC_FLAGS , 0);
SetName(creature->GetName());
- m_loyaltyPoints = 1000;
+ m_loyaltyPoints = 10000;
if(cinfo->type == CREATURE_TYPE_BEAST)
{
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x2020100);
@@ -869,7 +870,7 @@
//SetUInt32Value(UNIT_FIELD_BYTES_1,creature->GetUInt32Value(UNIT_FIELD_BYTES_1));
SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED) );
- SetLoyaltyLevel(REBELLIOUS);
+ SetLoyaltyLevel(SUBMISSIVE);
}
return true;
}
@@ -1072,7 +1073,7 @@
return 8000;
// -15 or less
else
- return 0; //food too low level
+ return 4000; //food too low level
}
void Pet::_LoadSpellCooldowns()
Index: src/game/SharedDefines.h
===================================================================
--- src/game/SharedDefines.h (revision 4845)
+++ src/game/SharedDefines.h (working copy)
@@ -64,7 +64,8 @@
MAX_CLASSES = 12
};
-#define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1)))
+//SantaCl
+#define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_WARRIOR-1))|(1<<(CLASS_PALADIN-1))|(1<<(CLASS_HUNTER-1))|(1<<(CLASS_ROGUE-1))|(1<<(CLASS_SHAMAN-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_DRUID-1))|(1<<(CLASS_WARLOCK-1)))
#define PLAYER_MAX_BATTLEGROUND_QUEUES 3
Index: src/game/ThreatManager.cpp
===================================================================
--- src/game/ThreatManager.cpp (revision 4845)
+++ src/game/ThreatManager.cpp (working copy)
@@ -93,12 +93,11 @@
void HostilReference::addThreat(float pMod)
{
iThreat += pMod;
- // the threat is changed. Source and target unit have to be availabe
+// sLog.outDetail("ThreatManager105: Pmod: %u ThreatTotal: %u",pMod,iThreat);
+ // the threat is changed. Source and target unit have to be availabe
// if the link was cut before relink it again
- if(!isOnline())
- updateOnlineStatus();
- if(pMod != 0.0f)
- fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_THREAT_CHANGE, this, pMod));
+ if(!isOnline()) updateOnlineStatus();
+ if(pMod != 0.0f) fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_THREAT_CHANGE, this, pMod));
if(isValid())
{
Unit* victim_owner = getTarget()->GetOwner();
@@ -331,31 +330,20 @@
//mobs, NPCs, guards have ThreatList and HateOfflineList
//players and pets have only InHateListOf
//HateOfflineList is used co contain unattackable victims (in-flight, in-water, GM etc.)
+ if (!pVictim || pVictim == getOwner()) return; //dont let pets attack their owners!
+ float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, pSchool, pThreatSpell);
- if (pVictim == getOwner()) // only for same creatures :)
- return;
-
- if(!pVictim || (pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) )
- return;
-
- assert(getOwner()->GetTypeId()== TYPEID_UNIT);
-
- float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, pSchool, pThreatSpell);
-
- HostilReference* ref = iThreatContainer.addThreat(pVictim, threat);
- // Ref is not in the online refs, search the offline refs next
- if(!ref)
- ref = iThreatOfflineContainer.addThreat(pVictim, threat);
-
- if(!ref) // there was no ref => create a new one
- {
- // threat has to be 0 here
- HostilReference* hostilReference = new HostilReference(pVictim, this, 0);
- iThreatContainer.addReference(hostilReference);
- hostilReference->addThreat(threat); // now we add the real threat
- if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster())
- hostilReference->setOnlineOfflineState(false); // GM is always offline
- }
+ HostilReference* ref = iThreatContainer.addThreat(pVictim, threat);
+ // Ref is not in the online refs, search the offline refs next
+ if(!ref) ref = iThreatOfflineContainer.addThreat(pVictim, threat);
+ if(!ref) // there was no ref => create a new one
+ {
+ HostilReference* hostilReference = new HostilReference(pVictim, this, 0); // threat has to be 0 here
+ iThreatContainer.addReference(hostilReference);
+ hostilReference->addThreat(threat); // now we add the real threat
+// if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster())
+// hostilReference->setOnlineOfflineState(false); // GM is always offline
+ }
}
//============================================================
Index: src/game/AuctionHouse.cpp
===================================================================
--- src/game/AuctionHouse.cpp (revision 4845)
+++ src/game/AuctionHouse.cpp (working copy)
@@ -76,12 +76,20 @@
//this function inserts to WorldPacket auction's data
bool WorldSession::SendAuctionInfo(WorldPacket & data, AuctionEntry* auction)
{
- Item *pItem = objmgr.GetAItem(auction->item_guid);
- if (!pItem)
- {
- sLog.outError("auction to item, that doesn't exist !!!!");
- return false;
- }
+//hf002{
+ if (!auction->item_guid) return false;
+ Item *pItem = objmgr.GetAItem(auction->item_guid);
+ if (!pItem->GetCount()){
+ sLog.outError("Error>WorldSession::SendAuctionInfo: auction to item, that doesn't exist !!!!");
+ return false;
+ }
+ uint32 AHTime = auction->time;
+ uint32 CurTime = (uint32)time(NULL);
+ uint32 ExpTime = 86400000;
+ if(AHTime < CurTime){
+ sLog.outError("Error>WorldSession::SendAuctionInfo: Expired auction guid: %u CurTime: %u Auctiontime: %u",auction->item_guid,CurTime,AHTime);
+ }
+//hf002}
data << auction->Id;
data << pItem->GetUInt32Value(OBJECT_FIELD_ENTRY);
@@ -92,7 +100,7 @@
data << (uint32) pItem->GetEnchantmentCharges(EnchantmentSlot(i));
}
- data << (uint32) pItem->GetItemRandomPropertyId(); //random item property id
+ data << (uint32) pItem->GetItemRandomPropertyId(); //random item property id
data << (uint32) pItem->GetItemSuffixFactor(); //SuffixFactor
data << (uint32) pItem->GetCount(); //item->count
data << (uint32) pItem->GetSpellCharges(); //item->charge FFFFFFF
@@ -103,7 +111,7 @@
data << (uint32) ((auction->bid)? objmgr.GetAuctionOutBid(auction->bid) : 0);
//minimal outbid
data << (uint32) auction->buyout; //auction->buyout
- data << (uint32) (auction->time - time(NULL)) * 1000; //time left
+ data << (uint32) ExpTime; //time left
data << (uint32) auction->bidder; //auction->bidder current
data << (uint32) 0; //player high_guid
data << (uint32) auction->bid; //current bid
@@ -225,7 +233,8 @@
recv_data >> bid >> buyout >> etime;
Player *pl = GetPlayer();
- if (!item || !bid || !etime)
+
+ if (!item || !etime)
return; //check for cheaters
Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
@@ -264,7 +273,8 @@
}
uint32 location = AuctioneerFactionToLocation(pCreature->getFaction());
- AuctionHouseObject * mAuctions;
+ sLog.outError("WS::HandleAuctionSellItem Location: %u",location);
+ AuctionHouseObject * mAuctions;
mAuctions = objmgr.GetAuctionsMap( location );
//we have to take deposit :
@@ -283,7 +293,14 @@
pl->ModifyMoney( -int32(deposit) );
- AuctionEntry *AH = new AuctionEntry;
+//hf003-make auctionhouse add a buyout of bid+deposit+45% to items with no buyout
+ if (bid < 10) bid = 10;
+ if(buyout < bid) buyout = deposit + (bid * 1.45); // SantaCL (ensure always a buyout!
+
+ uint32 base = time(NULL);
+ uint32 AhTime = (etime * 60 * sWorld.getRate(RATE_AUCTION_TIME)) + base;
+
+ AuctionEntry *AH = new AuctionEntry;
AH->Id = objmgr.GenerateAuctionID();
AH->auctioneer = GUID_LOPART(auctioneer);
AH->item_guid = GUID_LOPART(item);
@@ -293,12 +310,12 @@
AH->bidder = 0;
AH->bid = 0;
AH->buyout = buyout;
- time_t base = time(NULL);
- AH->time = ((time_t)(etime * 60 * sWorld.getRate(RATE_AUCTION_TIME))) + base;
+ AH->time = AhTime;
AH->deposit = deposit;
AH->location = location;
- sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in minutes) in location: %u", GUID_LOPART(item), GUID_LOPART(auctioneer), bid, buyout, etime, location);
+
+ sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in minutes) in location: %u", GUID_LOPART(item), GUID_LOPART(auctioneer), bid, buyout, etime, AH->location);
mAuctions->AddAuction(AH);
objmgr.AddAItem(it);
@@ -311,8 +328,8 @@
it->DeleteFromInventoryDB();
it->SaveToDB(); // recursive and not have transaction guard into self
CharacterDatabase.PExecute("INSERT INTO `auctionhouse` (`id`,`auctioneerguid`,`itemguid`,`item_template`,`itemowner`,`buyoutprice`,`time`,`buyguid`,`lastbid`,`startbid`,`deposit`,`location`) "
- "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" I64FMTD "', '%u', '%u', '%u', '%u', '%u')",
- AH->Id, AH->auctioneer, AH->item_guid, AH->item_template, AH->owner, AH->buyout, (uint64)AH->time, AH->bidder, AH->bid, AH->startbid, AH->deposit, AH->location);
+ "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
+ AH->Id, AH->auctioneer, AH->item_guid, AH->item_template, AH->owner, AH->buyout, AH->time, AH->bidder, AH->bid, AH->startbid, AH->deposit, AH->location);
pl->SaveInventoryAndGoldToDB();
CharacterDatabase.CommitTransaction();
@@ -655,43 +672,42 @@
{
AuctionEntry *Aentry = itr->second;
Item *item = objmgr.GetAItem(Aentry->item_guid);
- if( item )
+ if(!item) continue;
+
+ ItemPrototype const *proto = item->GetProto();
+ if(!proto) continue;
+// if(levelmin == (0x00)) continue; //SantaCl Dont list lvl-0 items.(bug fix)
+
+ if( auctionMainCategory == (0xffffffff) || proto->Class == auctionMainCategory )
{
- ItemPrototype const *proto = item->GetProto();
- if( proto )
+ if( auctionSubCategory == (0xffffffff) || proto->SubClass == auctionSubCategory )
+ {
+ if( auctionSlotID == (0xffffffff) || proto->InventoryType == auctionSlotID )
{
- if( auctionMainCategory == (0xffffffff) || proto->Class == auctionMainCategory )
+ if( quality == (0xffffffff) || proto->Quality == quality )
+ {
+ if( usable == (0x00) || _player->CanUseItem( item ) == EQUIP_ERR_OK )
{
- if( auctionSubCategory == (0xffffffff) || proto->SubClass == auctionSubCategory )
+ if( ( levelmin == (0x00) || proto->RequiredLevel >= levelmin ) && ( levelmax == (0x00) || proto->RequiredLevel <= levelmax ) )
+ {
+ name = proto->Name1;
+ std::transform( name.begin(), name.end(), name.begin(), ::tolower );
+ std::transform( searchedname.begin(), searchedname.end(), searchedname.begin(), ::tolower );
+ if( searchedname.empty() || name.find( searchedname ) != std::string::npos )
{
- if( auctionSlotID == (0xffffffff) || proto->InventoryType == auctionSlotID )
- {
- if( quality == (0xffffffff) || proto->Quality == quality )
- {
- if( usable == (0x00) || _player->CanUseItem( item ) == EQUIP_ERR_OK )
- {
- if( ( levelmin == (0x00) || proto->RequiredLevel >= levelmin ) && ( levelmax == (0x00) || proto->RequiredLevel <= levelmax ) )
- {
- name = proto->Name1;
- std::transform( name.begin(), name.end(), name.begin(), ::tolower );
- std::transform( searchedname.begin(), searchedname.end(), searchedname.begin(), ::tolower );
- if( searchedname.empty() || name.find( searchedname ) != std::string::npos )
- {
- if ((count < 50) && (totalcount >= listfrom))
- {
- count++;
- SendAuctionInfo( data, Aentry);
- }
- totalcount++;
- }
- }
- }
- }
- }
+ if ((count < 50) && (totalcount >= listfrom))
+ {
+ count++;
+ SendAuctionInfo( data, Aentry);
+ }
+ totalcount++;
}
+ }
}
+ }
}
- }
+ }
+ }
}
data.put(0, count);
data << (uint32) totalcount;
Index: src/game/Creature.cpp
===================================================================
--- src/game/Creature.cpp (revision 4845)
+++ src/game/Creature.cpp (working copy)
@@ -126,8 +126,9 @@
continue;
}
- if(ObjectMgr::IsProfessionSpell(spellinfo->EffectTriggerSpell[0]))
- m_trainer_type = 2;
+//SantaCl
+// if(ObjectMgr::IsProfessionSpell(spellinfo->EffectTriggerSpell[0]))
+// m_trainer_type = 2;
TrainerSpell tspell;
tspell.spell = spellinfo;
@@ -425,71 +426,70 @@
bool Creature::isCanTrainingOf(Player* pPlayer, bool msg) const
{
- if(!isTrainer())
- return false;
+ if(!isTrainer()) return false;
+ if(m_trainer_spells.empty())
+ {
+ sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_TRAINER but have empty trainer spell list.",
+ GetGUIDLow(),GetCreatureInfo()->Entry);
+ return false;
+ }
- if(m_trainer_spells.empty())
- {
- sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_TRAINER but have empty trainer spell list.",
- GetGUIDLow(),GetCreatureInfo()->Entry);
- return false;
- }
-
+return true;//hf014:
switch(GetCreatureInfo()->trainer_type)
{
- case TRAINER_TYPE_CLASS:
- if(pPlayer->getClass()!=GetCreatureInfo()->classNum)
- {
- if(msg)
- {
- pPlayer->PlayerTalkClass->ClearMenus();
- switch(GetCreatureInfo()->classNum)
- {
- case CLASS_DRUID: pPlayer->PlayerTalkClass->SendGossipMenu( 4913,GetGUID()); break;
- case CLASS_HUNTER: pPlayer->PlayerTalkClass->SendGossipMenu(10090,GetGUID()); break;
- case CLASS_MAGE: pPlayer->PlayerTalkClass->SendGossipMenu( 328,GetGUID()); break;
- case CLASS_PALADIN:pPlayer->PlayerTalkClass->SendGossipMenu( 1635,GetGUID()); break;
- case CLASS_PRIEST: pPlayer->PlayerTalkClass->SendGossipMenu( 4436,GetGUID()); break;
- case CLASS_ROGUE: pPlayer->PlayerTalkClass->SendGossipMenu( 4797,GetGUID()); break;
- case CLASS_SHAMAN: pPlayer->PlayerTalkClass->SendGossipMenu( 5003,GetGUID()); break;
- case CLASS_WARLOCK:pPlayer->PlayerTalkClass->SendGossipMenu( 5836,GetGUID()); break;
- case CLASS_WARRIOR:pPlayer->PlayerTalkClass->SendGossipMenu( 4985,GetGUID()); break;
- }
- }
- return false;
- }
- break;
- case TRAINER_TYPE_PETS:
- if(pPlayer->getClass()!=CLASS_HUNTER)
- {
- pPlayer->PlayerTalkClass->ClearMenus();
- pPlayer->PlayerTalkClass->SendGossipMenu(3620,GetGUID());
- return false;
- }
- break;
- case TRAINER_TYPE_MOUNTS:
- if(GetCreatureInfo()->race && pPlayer->getRace() != GetCreatureInfo()->race)
- {
- if(msg)
- {
- pPlayer->PlayerTalkClass->ClearMenus();
- switch(GetCreatureInfo()->classNum)
- {
- case RACE_DWARF: pPlayer->PlayerTalkClass->SendGossipMenu(5865,GetGUID()); break;
- case RACE_GNOME: pPlayer->PlayerTalkClass->SendGossipMenu(4881,GetGUID()); break;
- case RACE_HUMAN: pPlayer->PlayerTalkClass->SendGossipMenu(5861,GetGUID()); break;
- case RACE_NIGHTELF: pPlayer->PlayerTalkClass->SendGossipMenu(5862,GetGUID()); break;
- case RACE_ORC: pPlayer->PlayerTalkClass->SendGossipMenu(5863,GetGUID()); break;
- case RACE_TAUREN: pPlayer->PlayerTalkClass->SendGossipMenu(5864,GetGUID()); break;
- case RACE_TROLL: pPlayer->PlayerTalkClass->SendGossipMenu(5816,GetGUID()); break;
- case RACE_UNDEAD_PLAYER:pPlayer->PlayerTalkClass->SendGossipMenu( 624,GetGUID()); break;
- case RACE_BLOODELF: pPlayer->PlayerTalkClass->SendGossipMenu(5862,GetGUID()); break;
- case RACE_DRAENEI: pPlayer->PlayerTalkClass->SendGossipMenu(5864,GetGUID()); break;
- }
- }
- return false;
- }
- break;
+// case TRAINER_TYPE_CLASS:
+// if(pPlayer->getClass()!=GetCreatureInfo()->classNum)
+// {
+// if(msg)
+// {
+// pPlayer->PlayerTalkClass->ClearMenus();
+// switch(GetCreatureInfo()->classNum)
+// {
+// case CLASS_DRUID: pPlayer->PlayerTalkClass->SendGossipMenu( 4913,GetGUID()); break;
+// case CLASS_HUNTER: pPlayer->PlayerTalkClass->SendGossipMenu(10090,GetGUID()); break;
+// case CLASS_MAGE: pPlayer->PlayerTalkClass->SendGossipMenu( 328,GetGUID()); break;
+// case CLASS_PALADIN:pPlayer->PlayerTalkClass->SendGossipMenu( 1635,GetGUID()); break;
+// case CLASS_PRIEST: pPlayer->PlayerTalkClass->SendGossipMenu( 4436,GetGUID()); break;
+// case CLASS_ROGUE: pPlayer->PlayerTalkClass->SendGossipMenu( 4797,GetGUID()); break;
+// case CLASS_SHAMAN: pPlayer->PlayerTalkClass->SendGossipMenu( 5003,GetGUID()); break;
+// case CLASS_WARLOCK:pPlayer->PlayerTalkClass->SendGossipMenu( 5836,GetGUID()); break;
+// case CLASS_WARRIOR:pPlayer->PlayerTalkClass->SendGossipMenu( 4985,GetGUID()); break;
+// }
+// }
+// return false;
+// }
+// break;
+// case TRAINER_TYPE_PETS:
+// if(pPlayer->getClass()!=CLASS_HUNTER)
+// {
+// pPlayer->PlayerTalkClass->ClearMenus();
+// pPlayer->PlayerTalkClass->SendGossipMenu(3620,GetGUID());
+// return false;
+// }
+// break;
+// case TRAINER_TYPE_MOUNTS:
+// if(GetCreatureInfo()->race && pPlayer->getRace() != GetCreatureInfo()->race)
+// {
+// if(msg)
+// {
+// pPlayer->PlayerTalkClass->ClearMenus();
+// switch(GetCreatureInfo()->classNum)
+// {
+// case RACE_DWARF: pPlayer->PlayerTalkClass->SendGossipMenu(5865,GetGUID()); break;
+// case RACE_GNOME: pPlayer->PlayerTalkClass->SendGossipMenu(4881,GetGUID()); break;
+// case RACE_HUMAN: pPlayer->PlayerTalkClass->SendGossipMenu(5861,GetGUID()); break;
+// case RACE_NIGHTELF: pPlayer->PlayerTalkClass->SendGossipMenu(5862,GetGUID()); break;
+// case RACE_ORC: pPlayer->PlayerTalkClass->SendGossipMenu(5863,GetGUID()); break;
+// case RACE_TAUREN: pPlayer->PlayerTalkClass->SendGossipMenu(5864,GetGUID()); break;
+// case RACE_TROLL: pPlayer->PlayerTalkClass->SendGossipMenu(5816,GetGUID()); break;
+// case RACE_UNDEAD_PLAYER:pPlayer->PlayerTalkClass->SendGossipMenu( 624,GetGUID()); break;
+// case RACE_BLOODELF: pPlayer->PlayerTalkClass->SendGossipMenu(5862,GetGUID()); break;
+// case RACE_DRAENEI: pPlayer->PlayerTalkClass->SendGossipMenu(5864,GetGUID()); break;
+ // }
+ // }
+ // return false;
+ // }
+ // break;
case TRAINER_TYPE_TRADESKILLS:
if(GetCreatureInfo()->trainer_spell && !pPlayer->HasSpell(GetCreatureInfo()->trainer_spell))
{
@@ -539,8 +539,7 @@
bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const
{
return pPlayer->getLevel() >= 10
- && GetCreatureInfo()->trainer_type == TRAINER_TYPE_CLASS
- && pPlayer->getClass() == GetCreatureInfo()->classNum;
+ && GetCreatureInfo()->trainer_type == TRAINER_TYPE_CLASS;
}
void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
@@ -607,7 +606,7 @@
cantalking=false;
break;
case GOSSIP_OPTION_UNLEARNPETSKILLS:
- if(!pPlayer->GetPet() || pPlayer->GetPet()->getPetType() != HUNTER_PET || pPlayer->GetPet()->m_spells.size() <= 1 || GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS || GetCreatureInfo()->classNum != CLASS_HUNTER)
+ if(!pPlayer->GetPet() || pPlayer->GetPet()->getPetType() != HUNTER_PET || pPlayer->GetPet()->m_spells.size() <= 1 || GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS )
cantalking=false;
break;
case GOSSIP_OPTION_TAXIVENDOR:
@@ -1306,7 +1305,7 @@
m_respawnDelay = data->spawntimesecs;
m_deathState = (DeathState)data->deathState;
- if(m_deathState == JUST_DIED) // Don't must be set to JUST_DEAD, see Creature::setDeathState JUST_DIED -> CORPSE promoting.
+ if(m_deathState == JUST_DIED) // Don't must be set to JUST_DEAD, see Creature::setDeathState JUST_DIED -> CORPSE promoting.
{
sLog.outErrorDb("Creature (GUIDLow: %u Entry: %u ) in wrong state: JUST_DEAD (1). State set to ALIVE.",GetGUIDLow(),GetEntry());
m_deathState = ALIVE;
@@ -1562,7 +1561,7 @@
SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i] );
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
+ sLog.outError("Creature: unknown spell id %i\n", m_spells[i]);
continue;
}
@@ -1610,7 +1609,7 @@
SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i] );
if(!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
+ sLog.outError("Creature: unknown spell id %i\n", m_spells[i]);
continue;
}
@@ -1645,12 +1644,7 @@
bool Creature::IsVisibleInGridForPlayer(Player* pl) const
{
// Live player (or with not release body see live creatures or death creatures with corpse disappearing time > 0
- if(pl->isAlive() || pl->GetDeathTimer() > 0)
- {
- if( GetEntry() == VISUAL_WAYPOINT && !pl->isGameMaster() )
- return false;
- return isAlive() || m_deathTimer > 0;
- }
+ if(pl->isAlive() || pl->GetDeathTimer() > 0) return isAlive() || m_deathTimer > 0;
// Dead player see live creatures near own corpse
if(isAlive())
Index: src/game/ObjectMgr.cpp
===================================================================
--- src/game/ObjectMgr.cpp (revision 4845)
+++ src/game/ObjectMgr.cpp (working copy)
@@ -1090,7 +1090,9 @@
aItem->startbid = fields[9].GetUInt32();
aItem->deposit = fields[10].GetUInt32();
aItem->location = fields[11].GetUInt8();
- //check if sold item exists
+
+
+ //check if sold item exists
if ( this->GetAItem( aItem->item_guid ) )
{
GetAuctionsMap( aItem->location )->AddAuction(aItem);
@@ -1990,8 +1992,9 @@
info->stats[STAT_INTELLECT] += (lvl > 38 ? 3: (lvl > 4 ? 1: 0));
info->stats[STAT_SPIRIT] += (lvl > 38 ? 3: (lvl > 5 ? 1: 0));
}
-
- info->mana += (_class == CLASS_WARRIOR || _class == CLASS_ROGUE) ? 0 : info->stats[STAT_SPIRIT] / 2;
+
+ //info->mana += (_class == CLASS_WARRIOR || _class == CLASS_ROGUE) ? 0 : info->stats[STAT_SPIRIT] / 2;
+ info->mana += info->stats[STAT_SPIRIT] / 2;
info->health += info->stats[STAT_STAMINA] / 2;
}
}
Index: src/bindings/universal/ScriptMgr.cpp
===================================================================
--- src/bindings/universal/ScriptMgr.cpp (revision 4845)
+++ src/bindings/universal/ScriptMgr.cpp (working copy)
@@ -319,10 +319,7 @@
void ScriptedAI::DoStopAttack()
{
- if( m_creature->getVictim() != NULL )
- {
- m_creature->AttackStop();
- }
+ if( m_creature->getVictim() != NULL ) m_creature->AttackStop();
}
void ScriptedAI::DoGoHome()
Index: win/VC80/mangosd.vcproj
===================================================================
--- win/VC80/mangosd.vcproj (revision 4845)
+++ win/VC80/mangosd.vcproj (working copy)
@@ -1,7 +1,7 @@