From fdd8d2f3cc7108043f6bad036b994770f904866f Mon Sep 17 00:00:00 2001 From: click Date: Sun, 18 Apr 2010 23:20:07 +0200 Subject: Move around and do some changes to homebinding, thanks to Vladimir * Adds support for spelltarget-positions * Uses areaname instead of zonename on hearthstone Add homebind animation to player, with cast from innkeeper --HG-- branch : trunk --- src/game/NPCHandler.cpp | 35 ++++++---------------------- src/game/ObjectMgr.cpp | 4 ++-- src/game/Player.cpp | 26 ++++++++++++++++----- src/game/Player.h | 6 +++-- src/game/Spell.cpp | 1 + src/game/Spell.h | 1 + src/game/SpellEffects.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++-- src/game/SpellMgr.cpp | 44 ++++++++++++++++++++++++----------- 8 files changed, 123 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index f6380016af0..e2ce4652b5b 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -463,43 +463,22 @@ void WorldSession::SendBindPoint(Creature *npc) return; uint32 bindspell = 3286; - uint32 zone_id = _player->GetZoneId(); // 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'", _player->GetMapId(), zone_id, _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow()); + CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", + _player->GetMapId(), _player->GetAreaId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow()); _player->m_homebindMapId = _player->GetMapId(); - _player->m_homebindZoneId = zone_id; + _player->m_homebindAreaId = _player->GetAreaId(); _player->m_homebindX = _player->GetPositionX(); _player->m_homebindY = _player->GetPositionY(); _player->m_homebindZ = _player->GetPositionZ(); - // send spell for bind 3286 bind magic - _player->CastSpell(_player, bindspell, true); + // send spell for homebinding (3286) + npc->CastSpell(_player, bindspell, true); 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(bindspell); SendPacket(&data); _player->PlayerTalkClass->CloseGossip(); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index d1b2b1c525b..340507045cf 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -2657,7 +2657,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(); @@ -2703,7 +2703,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; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 60b7252baa8..bb7e0f8157f 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -15484,6 +15484,19 @@ bool Player::LoadPositionFromDB(uint32& mapid, float& x,float& y,float& z,float& return true; } +void Player::SetHomebind(WorldLocation const& loc, uint32 area_id) +{ + m_homebindMapId = GetMapId(); + m_homebindAreaId = GetAreaId(); + m_homebindX = GetPositionX(); + m_homebindY = GetPositionY(); + m_homebindZ = GetPositionZ(); + + // 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_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ, GetGUIDLow()); +} + uint32 Player::GetUInt32ValueFromArray(Tokens const& data, uint16 index) { if (index >= data.size()) @@ -17236,7 +17249,7 @@ bool Player::_LoadHomeBind(QueryResult_AutoPtr 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(); @@ -17254,16 +17267,17 @@ bool Player::_LoadHomeBind(QueryResult_AutoPtr 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, 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); + DEBUG_LOG("Setting player home position - mapid: %u, areaid: %u, X: %f, Y: %f, Z: %f", + m_homebindMapId, m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ); return true; } @@ -20515,7 +20529,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 diff --git a/src/game/Player.h b/src/game/Player.h index 7b47b0d7c0f..27d152fbd95 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -245,7 +245,7 @@ struct PlayerInfo } uint32 mapId; - uint32 zoneId; + uint32 areaId; float positionX; float positionY; float positionZ; @@ -2190,9 +2190,11 @@ class Player : public Unit, public GridObject float m_recallO; void SaveRecallPosition(); + void SetHomebind(WorldLocation const& loc, uint32 area_id); + // Homebind coordinates uint32 m_homebindMapId; - uint16 m_homebindZoneId; + uint16 m_homebindAreaId; float m_homebindX; float m_homebindY; float m_homebindZ; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 05c8b2a4d6f..8c45cc3313f 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -622,6 +622,7 @@ void Spell::SelectSpellTargets() } break; } + case SPELL_EFFECT_BIND: case SPELL_EFFECT_RESURRECT: case SPELL_EFFECT_CREATE_ITEM: case SPELL_EFFECT_TRIGGER_SPELL: diff --git a/src/game/Spell.h b/src/game/Spell.h index 2793a31ba16..a9f73adb13f 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -283,6 +283,7 @@ class Spell void EffectPowerBurn(uint32 i); void EffectPowerDrain(uint32 i); void EffectHeal(uint32 i); + void EffectBind(uint32 i); void EffectHealthLeech(uint32 i); void EffectQuestComplete(uint32 i); void EffectCreateItem(uint32 i); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 3cccf86712e..161ad24d5e2 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -76,7 +76,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::EffectUnused, // 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 @@ -3069,7 +3069,7 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype) } // set the "Crafted by ..." property of the item - if (pItem->GetProto()->Class != ITEM_CLASS_CONSUMABLE && pItem->GetProto()->Class != ITEM_CLASS_QUEST && newitemid != 6265) + if (pItem->GetProto()->Class != ITEM_CLASS_CONSUMABLE && pItem->GetProto()->Class != ITEM_CLASS_QUEST && newitemid != 6265 && newitemid != 6948) pItem->SetUInt32Value(ITEM_FIELD_CREATOR, player->GetGUIDLow()); // send info to the client @@ -7640,3 +7640,58 @@ void Spell::EffectRechargeManaGem(uint32 i) pItem->SetState(ITEM_CHANGED,player); } } + +void Spell::EffectBind(uint32 i) +{ + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + Player* player = (Player*)unitTarget; + + uint32 area_id; + WorldLocation loc; + if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_DST_DB || m_spellInfo->EffectImplicitTargetB[i] == TARGET_DST_DB) + { + SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id); + if (!st) + { + sLog.outError( "Spell::EffectBind - unknown teleport coordinates for spell ID %u", m_spellInfo->Id ); + return; + } + + loc.m_mapId = st->target_mapId; + loc.m_positionX = st->target_X; + loc.m_positionY = st->target_Y; + loc.m_positionZ = st->target_Y; + loc.m_orientation = st->target_Orientation; + area_id = player->GetAreaId(); + } + else + { + player->GetPosition(&loc); + area_id = player->GetAreaId(); + } + + player->SetHomebind(loc, area_id); + + // binding + WorldPacket data( SMSG_BINDPOINTUPDATE, (4+4+4+4+4) ); + data << float(loc.m_positionX); + data << float(loc.m_positionY); + data << float(loc.m_positionZ); + data << uint32(loc.m_mapId); + data << uint32(area_id); + player->SendDirectMessage( &data ); + + DEBUG_LOG("New homebind X : %f", loc.m_positionX); + DEBUG_LOG("New homebind Y : %f", loc.m_positionY); + DEBUG_LOG("New homebind Z : %f", loc.m_positionZ); + DEBUG_LOG("New homebind MapId : %u", loc.m_mapId); + DEBUG_LOG("New homebind AreaId : %u", area_id); + + // zone update + data.Initialize(SMSG_PLAYERBOUND, 8+4); + data << uint64(player->GetGUID()); + data << uint32(area_id); + player->SendDirectMessage( &data ); +} diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index d433a9917c0..de06727be8b 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -28,6 +28,7 @@ #include "Spell.h" #include "BattleGroundMgr.h" #include "CreatureAI.h" +#include "MapManager.h" bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS]; SpellEffectTargetTypes EffectTargetType[TOTAL_SPELL_EFFECTS]; @@ -1105,6 +1106,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) { @@ -1117,6 +1131,17 @@ void SpellMgr::LoadSpellTargetPositions() { if (spellInfo->EffectImplicitTargetA[i] == TARGET_DST_DB || spellInfo->EffectImplicitTargetB[i] == TARGET_DST_DB) { + // additional requirements + if (spellInfo->Effect[i]==SPELL_EFFECT_BIND && spellInfo->EffectMiscValue[i]) + { + uint32 area_id = MapManager::Instance().GetAreaId(st.target_mapId, st.target_X, st.target_Y, st.target_Z); + if (area_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], area_id); + break; + } + } + found = true; break; } @@ -1127,19 +1152,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; @@ -3566,6 +3578,12 @@ void SpellMgr::LoadSpellCustomAttr() switch(i) { + // Bind + case 3286: + spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ENEMY; + spellInfo->EffectImplicitTargetA[1] = TARGET_UNIT_TARGET_ENEMY; + count++; + break; // Heroism case 32182: spellInfo->excludeCasterAuraSpell = 57723; // Exhaustion -- cgit v1.2.3