mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[9496] HomeBind fixes.
* Use area id instead zone id for home bind zone info as expected. This will for example proper show capital name in area himebinding for capital; tavern. * Clarify that player create zone in fact is area (subzone) * Implement SPELL_EFFECT_BIND for normal homebinding. Also support spell target position mode used in 53823/53821 spells * Add Spell::EffectEmpty for mark spell effects that used but not expect any code in handler. Example weapon spells that used just as known spell markers for client. Original patch idea inspirit by Sadikum patch suggestion.
This commit is contained in:
parent
aa13458b69
commit
4a051e2443
9 changed files with 116 additions and 66 deletions
|
|
@ -425,38 +425,12 @@ void WorldSession::SendBindPoint(Creature *npc)
|
|||
if(GetPlayer()->GetMap()->Instanceable())
|
||||
return;
|
||||
|
||||
uint32 bindspell = 3286;
|
||||
uint32 zone_id = _player->GetZoneId();
|
||||
|
||||
_player->SetHomebindToCurrentPos();
|
||||
|
||||
// send spell for bind 3286 bind magic
|
||||
npc->CastSpell(_player, bindspell, true);
|
||||
npc->CastSpell(_player, 3286, true); // Bind
|
||||
|
||||
WorldPacket data( SMSG_TRAINER_BUY_SUCCEEDED, (8+4));
|
||||
data << npc->GetGUID();
|
||||
data << bindspell;
|
||||
SendPacket( &data );
|
||||
|
||||
// binding
|
||||
data.Initialize( SMSG_BINDPOINTUPDATE, (4+4+4+4+4) );
|
||||
data << float(_player->GetPositionX());
|
||||
data << float(_player->GetPositionY());
|
||||
data << float(_player->GetPositionZ());
|
||||
data << uint32(_player->GetMapId());
|
||||
data << uint32(zone_id);
|
||||
SendPacket( &data );
|
||||
|
||||
DEBUG_LOG("New Home Position X is %f",_player->GetPositionX());
|
||||
DEBUG_LOG("New Home Position Y is %f",_player->GetPositionY());
|
||||
DEBUG_LOG("New Home Position Z is %f",_player->GetPositionZ());
|
||||
DEBUG_LOG("New Home MapId is %u",_player->GetMapId());
|
||||
DEBUG_LOG("New Home ZoneId is %u",zone_id);
|
||||
|
||||
// zone update
|
||||
data.Initialize( SMSG_PLAYERBOUND, 8+4 );
|
||||
data << uint64(_player->GetGUID());
|
||||
data << uint32(zone_id);
|
||||
data << uint64(npc->GetGUID());
|
||||
data << uint32(3286); // Bind
|
||||
SendPacket( &data );
|
||||
|
||||
_player->PlayerTalkClass->CloseGossip();
|
||||
|
|
|
|||
|
|
@ -2333,7 +2333,7 @@ void ObjectMgr::LoadPlayerInfo()
|
|||
uint32 current_race = fields[0].GetUInt32();
|
||||
uint32 current_class = fields[1].GetUInt32();
|
||||
uint32 mapId = fields[2].GetUInt32();
|
||||
uint32 zoneId = fields[3].GetUInt32();
|
||||
uint32 areaId = fields[3].GetUInt32();
|
||||
float positionX = fields[4].GetFloat();
|
||||
float positionY = fields[5].GetFloat();
|
||||
float positionZ = fields[6].GetFloat();
|
||||
|
|
@ -2379,7 +2379,7 @@ void ObjectMgr::LoadPlayerInfo()
|
|||
PlayerInfo* pInfo = &playerInfo[current_race][current_class];
|
||||
|
||||
pInfo->mapId = mapId;
|
||||
pInfo->zoneId = zoneId;
|
||||
pInfo->areaId = areaId;
|
||||
pInfo->positionX = positionX;
|
||||
pInfo->positionY = positionY;
|
||||
pInfo->positionZ = positionZ;
|
||||
|
|
|
|||
|
|
@ -16095,7 +16095,7 @@ bool Player::_LoadHomeBind(QueryResult *result)
|
|||
{
|
||||
Field *fields = result->Fetch();
|
||||
m_homebindMapId = fields[0].GetUInt32();
|
||||
m_homebindZoneId = fields[1].GetUInt16();
|
||||
m_homebindAreaId = fields[1].GetUInt16();
|
||||
m_homebindX = fields[2].GetFloat();
|
||||
m_homebindY = fields[3].GetFloat();
|
||||
m_homebindZ = fields[4].GetFloat();
|
||||
|
|
@ -16116,16 +16116,16 @@ bool Player::_LoadHomeBind(QueryResult *result)
|
|||
if(!ok)
|
||||
{
|
||||
m_homebindMapId = info->mapId;
|
||||
m_homebindZoneId = info->zoneId;
|
||||
m_homebindAreaId = info->areaId;
|
||||
m_homebindX = info->positionX;
|
||||
m_homebindY = info->positionY;
|
||||
m_homebindZ = info->positionZ;
|
||||
|
||||
CharacterDatabase.PExecute("INSERT INTO character_homebind (guid,map,zone,position_x,position_y,position_z) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GetGUIDLow(), m_homebindMapId, (uint32)m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ);
|
||||
CharacterDatabase.PExecute("INSERT INTO character_homebind (guid,map,zone,position_x,position_y,position_z) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GetGUIDLow(), m_homebindMapId, (uint32)m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ);
|
||||
}
|
||||
|
||||
DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f",
|
||||
m_homebindMapId, m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ);
|
||||
m_homebindMapId, m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -18901,7 +18901,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
|
|||
WorldPacket data(SMSG_BINDPOINTUPDATE, 5*4);
|
||||
data << m_homebindX << m_homebindY << m_homebindZ;
|
||||
data << (uint32) m_homebindMapId;
|
||||
data << (uint32) m_homebindZoneId;
|
||||
data << (uint32) m_homebindAreaId;
|
||||
GetSession()->SendPacket(&data);
|
||||
|
||||
// SMSG_SET_PROFICIENCY
|
||||
|
|
@ -21549,16 +21549,17 @@ bool Player::IsImmunedToSpellEffect(SpellEntry const* spellInfo, SpellEffectInde
|
|||
return Unit::IsImmunedToSpellEffect(spellInfo, index);
|
||||
}
|
||||
|
||||
void Player::SetHomebindToCurrentPos()
|
||||
void Player::SetHomebindToLocation(WorldLocation const& loc, uint32 area_id)
|
||||
{
|
||||
m_homebindMapId = GetMapId();
|
||||
m_homebindZoneId = GetZoneId();
|
||||
m_homebindX = GetPositionX();
|
||||
m_homebindY = GetPositionY();
|
||||
m_homebindZ = GetPositionZ();
|
||||
m_homebindMapId = loc.mapid;
|
||||
m_homebindAreaId = area_id;
|
||||
m_homebindX = loc.coord_x;
|
||||
m_homebindY = loc.coord_y;
|
||||
m_homebindZ = loc.coord_z;
|
||||
|
||||
// update sql homebind
|
||||
CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'",
|
||||
m_homebindMapId, m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ, GetGUIDLow());
|
||||
m_homebindMapId, m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ, GetGUIDLow());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ struct PlayerInfo
|
|||
}
|
||||
|
||||
uint32 mapId;
|
||||
uint32 zoneId;
|
||||
uint32 areaId;
|
||||
float positionX;
|
||||
float positionY;
|
||||
float positionZ;
|
||||
|
|
@ -2168,7 +2168,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
float m_recallO;
|
||||
void SaveRecallPosition();
|
||||
|
||||
void SetHomebindToCurrentPos();
|
||||
void SetHomebindToLocation(WorldLocation const& loc, uint32 area_id);
|
||||
void RelocateToHomebind() { SetLocationMapId(m_homebindMapId); Relocate(m_homebindX, m_homebindY, m_homebindZ); }
|
||||
bool TeleportToHomebind(uint32 options = 0) { return TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation(), options); }
|
||||
|
||||
|
|
@ -2533,7 +2533,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
// Homebind coordinates
|
||||
uint32 m_homebindMapId;
|
||||
uint16 m_homebindZoneId;
|
||||
uint16 m_homebindAreaId;
|
||||
float m_homebindX;
|
||||
float m_homebindY;
|
||||
float m_homebindZ;
|
||||
|
|
|
|||
|
|
@ -2258,6 +2258,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
|
|||
}
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_BIND:
|
||||
case SPELL_EFFECT_RESURRECT:
|
||||
case SPELL_EFFECT_PARRY:
|
||||
case SPELL_EFFECT_BLOCK:
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@ class Spell
|
|||
friend void Unit::SetCurrentCastedSpell( Spell * pSpell );
|
||||
public:
|
||||
|
||||
void EffectEmpty(SpellEffectIndex eff_idx);
|
||||
void EffectNULL(SpellEffectIndex eff_idx);
|
||||
void EffectUnused(SpellEffectIndex eff_idx);
|
||||
void EffectDistract(SpellEffectIndex eff_idx);
|
||||
|
|
@ -231,6 +232,7 @@ class Spell
|
|||
void EffectPowerBurn(SpellEffectIndex eff_idx);
|
||||
void EffectPowerDrain(SpellEffectIndex eff_idx);
|
||||
void EffectHeal(SpellEffectIndex eff_idx);
|
||||
void EffectBind(SpellEffectIndex eff_idx);
|
||||
void EffectHealthLeech(SpellEffectIndex eff_idx);
|
||||
void EffectQuestComplete(SpellEffectIndex eff_idx);
|
||||
void EffectCreateItem(SpellEffectIndex eff_idx);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
|||
&Spell::EffectPowerDrain, // 8 SPELL_EFFECT_POWER_DRAIN
|
||||
&Spell::EffectHealthLeech, // 9 SPELL_EFFECT_HEALTH_LEECH
|
||||
&Spell::EffectHeal, // 10 SPELL_EFFECT_HEAL
|
||||
&Spell::EffectNULL, // 11 SPELL_EFFECT_BIND
|
||||
&Spell::EffectBind, // 11 SPELL_EFFECT_BIND
|
||||
&Spell::EffectNULL, // 12 SPELL_EFFECT_PORTAL
|
||||
&Spell::EffectUnused, // 13 SPELL_EFFECT_RITUAL_BASE unused
|
||||
&Spell::EffectUnused, // 14 SPELL_EFFECT_RITUAL_SPECIALIZE unused
|
||||
|
|
@ -222,6 +222,11 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
|||
&Spell::EffectActivateSpec, //162 SPELL_EFFECT_TALENT_SPEC_SELECT activate primary/secondary spec
|
||||
};
|
||||
|
||||
void Spell::EffectEmpty(SpellEffectIndex /*eff_idx*/)
|
||||
{
|
||||
// NOT NEED ANY IMPLEMENTATION CODE, EFFECT POSISBLE USED AS MARKER OR CLIENT INFORM
|
||||
}
|
||||
|
||||
void Spell::EffectNULL(SpellEffectIndex /*eff_idx*/)
|
||||
{
|
||||
sLog.outDebug("WORLD: Spell Effect DUMMY");
|
||||
|
|
@ -7372,3 +7377,59 @@ void Spell::EffectActivateSpec(SpellEffectIndex /*eff_idx*/)
|
|||
|
||||
((Player*)unitTarget)->ActivateSpec(spec);
|
||||
}
|
||||
|
||||
void Spell::EffectBind(SpellEffectIndex eff_idx)
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player* player = (Player*)unitTarget;
|
||||
|
||||
uint32 area_id;
|
||||
WorldLocation loc;
|
||||
if (m_spellInfo->EffectImplicitTargetA[eff_idx] == TARGET_TABLE_X_Y_Z_COORDINATES ||
|
||||
m_spellInfo->EffectImplicitTargetB[eff_idx] == TARGET_TABLE_X_Y_Z_COORDINATES)
|
||||
{
|
||||
SpellTargetPosition const* st = sSpellMgr.GetSpellTargetPosition(m_spellInfo->Id);
|
||||
if (!st)
|
||||
{
|
||||
sLog.outError( "Spell::EffectBind - unknown Teleport coordinates for spell ID %u", m_spellInfo->Id );
|
||||
return;
|
||||
}
|
||||
|
||||
loc.mapid = st->target_mapId;
|
||||
loc.coord_x = st->target_X;
|
||||
loc.coord_y = st->target_Y;
|
||||
loc.coord_z = st->target_Y;
|
||||
loc.orientation = st->target_Orientation;
|
||||
area_id = sMapMgr.GetAreaId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z);
|
||||
}
|
||||
else
|
||||
{
|
||||
player->GetPosition(loc);
|
||||
area_id = player->GetAreaId();
|
||||
}
|
||||
|
||||
player->SetHomebindToLocation(loc,area_id);
|
||||
|
||||
// binding
|
||||
WorldPacket data( SMSG_BINDPOINTUPDATE, (4+4+4+4+4) );
|
||||
data << float(loc.coord_x);
|
||||
data << float(loc.coord_y);
|
||||
data << float(loc.coord_z);
|
||||
data << uint32(loc.mapid);
|
||||
data << uint32(area_id);
|
||||
player->SendDirectMessage( &data );
|
||||
|
||||
DEBUG_LOG("New Home Position X is %f", loc.coord_x);
|
||||
DEBUG_LOG("New Home Position Y is %f", loc.coord_y);
|
||||
DEBUG_LOG("New Home Position Z is %f", loc.coord_z);
|
||||
DEBUG_LOG("New Home MapId is %u", loc.mapid);
|
||||
DEBUG_LOG("New Home AreaId is %u", area_id);
|
||||
|
||||
// zone update
|
||||
data.Initialize(SMSG_PLAYERBOUND, 8+4);
|
||||
data << uint64(player->GetGUID());
|
||||
data << uint32(area_id);
|
||||
player->SendMessageToSet( &data, true );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -825,6 +825,19 @@ void SpellMgr::LoadSpellTargetPositions()
|
|||
st.target_Z = fields[4].GetFloat();
|
||||
st.target_Orientation = fields[5].GetFloat();
|
||||
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
|
||||
if (!mapEntry)
|
||||
{
|
||||
sLog.outErrorDb("Spell (ID:%u) target map (ID: %u) does not exist in `Map.dbc`.",Spell_ID,st.target_mapId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (st.target_X==0 && st.target_Y==0 && st.target_Z==0)
|
||||
{
|
||||
sLog.outErrorDb("Spell (ID:%u) target coordinates not provided.",Spell_ID);
|
||||
continue;
|
||||
}
|
||||
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(Spell_ID);
|
||||
if (!spellInfo)
|
||||
{
|
||||
|
|
@ -837,6 +850,17 @@ void SpellMgr::LoadSpellTargetPositions()
|
|||
{
|
||||
if (spellInfo->EffectImplicitTargetA[i]==TARGET_TABLE_X_Y_Z_COORDINATES || spellInfo->EffectImplicitTargetB[i]==TARGET_TABLE_X_Y_Z_COORDINATES)
|
||||
{
|
||||
// additional requirements
|
||||
if (spellInfo->Effect[i]==SPELL_EFFECT_BIND && spellInfo->EffectMiscValue[i])
|
||||
{
|
||||
uint32 zone_id = sMapMgr.GetAreaId(st.target_mapId, st.target_X, st.target_Y, st.target_Z);
|
||||
if (zone_id != spellInfo->EffectMiscValue[i])
|
||||
{
|
||||
sLog.outErrorDb("Spell (Id: %u) listed in `spell_target_position` expected point to zone %u bit point to zone %u.",Spell_ID, spellInfo->EffectMiscValue[i], zone_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -847,19 +871,6 @@ void SpellMgr::LoadSpellTargetPositions()
|
|||
continue;
|
||||
}
|
||||
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
|
||||
if(!mapEntry)
|
||||
{
|
||||
sLog.outErrorDb("Spell (ID:%u) target map (ID: %u) does not exist in `Map.dbc`.",Spell_ID,st.target_mapId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(st.target_X==0 && st.target_Y==0 && st.target_Z==0)
|
||||
{
|
||||
sLog.outErrorDb("Spell (ID:%u) target coordinates not provided.",Spell_ID);
|
||||
continue;
|
||||
}
|
||||
|
||||
mSpellTargetPositions[Spell_ID] = st;
|
||||
++count;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "9495"
|
||||
#define REVISION_NR "9496"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue