diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/collision/DynamicTree.cpp | 48 | ||||
| -rw-r--r-- | src/server/collision/DynamicTree.h | 2 | ||||
| -rwxr-xr-x | src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp | 2 | ||||
| -rwxr-xr-x | src/server/game/Conditions/ConditionMgr.cpp | 29 | ||||
| -rwxr-xr-x | src/server/game/Conditions/ConditionMgr.h | 4 | ||||
| -rwxr-xr-x | src/server/game/Entities/Object/Object.cpp | 15 | ||||
| -rwxr-xr-x | src/server/game/Maps/Map.cpp | 20 | ||||
| -rwxr-xr-x | src/server/game/Maps/Map.h | 11 | ||||
| -rwxr-xr-x | src/server/game/Quests/QuestDef.cpp | 4 | ||||
| -rwxr-xr-x | src/server/game/Spells/SpellEffects.cpp | 5 | ||||
| -rw-r--r-- | src/server/scripts/World/npcs_special.cpp | 47 |
11 files changed, 124 insertions, 63 deletions
diff --git a/src/server/collision/DynamicTree.cpp b/src/server/collision/DynamicTree.cpp index 1d6877d1209..89e76d426fe 100644 --- a/src/server/collision/DynamicTree.cpp +++ b/src/server/collision/DynamicTree.cpp @@ -176,6 +176,54 @@ struct DynamicTreeIntersectionCallback_WithLogger bool didHit() const { return did_hit;} }; +bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray, const Vector3& endPos, float& maxDist) const +{ + float distance = maxDist; + DynamicTreeIntersectionCallback callback(phasemask); + impl.intersectRay(ray, callback, distance, endPos); + if (callback.didHit()) + maxDist = distance; + return callback.didHit(); +} + +bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& startPos, const Vector3& endPos, Vector3& resultHit, float modifyDist) const +{ + bool result = false; + float maxDist = (endPos - startPos).magnitude(); + // valid map coords should *never ever* produce float overflow, but this would produce NaNs too + ASSERT(maxDist < std::numeric_limits<float>::max()); + // prevent NaN values which can cause BIH intersection to enter infinite loop + if (maxDist < 1e-10f) + { + resultHit = endPos; + return false; + } + Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1 + G3D::Ray ray(startPos, dir); + float dist = maxDist; + if (getIntersectionTime(phasemask, ray, endPos, dist)) + { + resultHit = startPos + dir * dist; + if (modifyDist < 0) + { + if ((resultHit - startPos).magnitude() > -modifyDist) + resultHit = resultHit + dir*modifyDist; + else + resultHit = startPos; + } + else + resultHit = resultHit + dir*modifyDist; + + result = true; + } + else + { + resultHit = endPos; + result = false; + } + return result; +} + bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const { Vector3 v1(x1,y1,z1), v2(x2,y2,z2); diff --git a/src/server/collision/DynamicTree.h b/src/server/collision/DynamicTree.h index ab28641b6ad..0b4f5908c04 100644 --- a/src/server/collision/DynamicTree.h +++ b/src/server/collision/DynamicTree.h @@ -46,6 +46,8 @@ public: ~DynamicMapTree(); bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const; + bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray, const Vector3& endPos, float& maxDist) const; + bool getObjectHitPos(uint32 phasemask, const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const; float getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const; void insert(const GameObjectModel&); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp index 54ee22c7a05..ea3bd3e4be9 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp @@ -239,7 +239,7 @@ void BattlegroundRV::TogglePillarCollision(bool apply) gob->SetGoState(apply ? (GOState)_state : (GOState)(!_state)); if (gob->GetGOInfo()->door.startOpen) - gob->EnableCollision(apply); // Forced collision toggle + gob->EnableCollision(!apply); // Forced collision toggle } for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 7f47b282a1d..6f380bb5d8a 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -312,6 +312,16 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) condMeets = CompareValues(static_cast<ComparisionType>(mConditionValue2), unit->GetHealthPct(), static_cast<float>(mConditionValue1)); break; } + case CONDITION_WORLD_STATE: + { + condMeets = mConditionValue2 == sWorld->getWorldState(mConditionValue1); + break; + } + case CONDITION_PHASEMASK: + { + condMeets = object->GetPhaseMask() & mConditionValue1; + break; + } default: condMeets = false; break; @@ -1673,6 +1683,25 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) case CONDITION_AREAID: case CONDITION_INSTANCE_DATA: break; + case CONDITION_WORLD_STATE: + { + if (!sWorld->getWorldState(cond->mConditionValue1)) + { + sLog->outErrorDb("World state condition has non existing world state in value1 (%u), skipped", cond->mConditionValue1); + return false; + } + if (cond->mConditionValue3) + sLog->outErrorDb("World state condition has useless data in value3 (%u)!", cond->mConditionValue3); + break; + } + case CONDITION_PHASEMASK: + { + if (cond->mConditionValue2) + sLog->outErrorDb("Phasemask condition has useless data in value2 (%u)!", cond->mConditionValue2); + if (cond->mConditionValue3) + sLog->outErrorDb("Phasemask condition has useless data in value3 (%u)!", cond->mConditionValue3); + break; + } default: break; } diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 8e133d31a82..f3e9c728ac1 100755 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -41,7 +41,7 @@ enum ConditionType CONDITION_QUESTREWARDED = 8, // quest_id 0 0 true if quest_id was rewarded before CONDITION_QUESTTAKEN = 9, // quest_id 0, 0 true while quest active CONDITION_DRUNKENSTATE = 10, // DrunkenState 0, 0 true if player is drunk enough - CONDITION_UNUSED_11 = 11, + CONDITION_WORLD_STATE = 11, // index value 0 true if world has the value for the index CONDITION_ACTIVE_EVENT = 12, // event_id 0 0 true if event is active CONDITION_INSTANCE_DATA = 13, // entry data 0 true if data is set in current instance CONDITION_QUEST_NONE = 14, // quest_id 0 0 true if doesn't have quest saved @@ -56,7 +56,7 @@ enum ConditionType CONDITION_AREAID = 23, // area_id 0 0 true if in area_id CONDITION_ITEM_TARGET = 24, // ItemRequiredTargetType, TargetEntry, 0 CONDITION_SPELL = 25, // spell_id 0 0 true if player has learned spell - CONDITION_UNUSED_26 = 26, + CONDITION_PHASEMASK = 26, // phasemask 0 0 true if object is in phasemask CONDITION_LEVEL = 27, // level ComparisonType 0 true if unit's level is equal to param1 (param2 can modify the statement) CONDITION_QUEST_COMPLETE = 28, // quest_id 0 0 true if player has quest_id with all objectives complete, but not yet rewarded CONDITION_NEAR_CREATURE = 29, // creature entry distance 0 true if there is a creature of entry in range diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 3ab91e9582f..aadf9f44b0b 100755 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2671,7 +2671,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float { angle += m_orientation; float destx, desty, destz, ground, floor; - + pos.m_positionZ += 2.0f; destx = pos.m_positionX + dist * cos(angle); desty = pos.m_positionY + dist * sin(angle); ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true); @@ -2689,6 +2689,17 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float dist = sqrt((pos.m_positionX - destx)*(pos.m_positionX - destx) + (pos.m_positionY - desty)*(pos.m_positionY - desty)); } + // check dynamic collision + col = GetMap()->getObjectHitPos(GetPhaseMask(), pos.m_positionX, pos.m_positionY, pos.m_positionZ+0.5f, destx, desty, destz+0.5f, destx, desty, destz, -0.5f); + + // Collided with a gameobject + if (col) + { + destx -= CONTACT_DISTANCE * cos(angle); + desty -= CONTACT_DISTANCE * sin(angle); + dist = sqrt((pos.m_positionX - destx)*(pos.m_positionX - destx) + (pos.m_positionY - desty)*(pos.m_positionY - desty)); + } + float step = dist/10.0f; for (uint8 j = 0; j < 10; ++j) @@ -2712,7 +2723,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float Trinity::NormalizeMapCoord(pos.m_positionX); Trinity::NormalizeMapCoord(pos.m_positionY); - UpdateGroundPositionZ(pos.m_positionX, pos.m_positionY, pos.m_positionZ); + UpdateAllowedPositionZ(pos.m_positionX, pos.m_positionY, pos.m_positionZ); pos.m_orientation = m_orientation; } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 6e13e70d1cd..b8c35d45e98 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -500,7 +500,7 @@ void Map::VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::Obj void Map::Update(const uint32 t_diff) { - m_dyn_tree.update(t_diff); + _dynamicTree.update(t_diff); /// update worldsessions for existing players for (m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter) { @@ -1800,12 +1800,26 @@ void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 area bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const { return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2) - && m_dyn_tree.isInLineOfSight(x1, y1, z1, x2, y2, z2, phasemask); + && _dynamicTree.isInLineOfSight(x1, y1, z1, x2, y2, z2, phasemask); +} + +bool Map::getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist) +{ + Vector3 startPos = Vector3(x1, y1, z1); + Vector3 dstPos = Vector3(x2, y2, z2); + + Vector3 resultPos; + bool result = _dynamicTree.getObjectHitPos(phasemask, startPos, dstPos, resultPos, modifyDist); + + rx = resultPos.x; + ry = resultPos.y; + rz = resultPos.z; + return result; } float Map::GetHeight(uint32 phasemask, float x, float y, float z, bool vmap/*=true*/, float maxSearchDist/*=DEFAULT_HEIGHT_SEARCH*/) const { - return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), m_dyn_tree.getHeight(x, y, z, maxSearchDist, phasemask)); + return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), _dynamicTree.getHeight(x, y, z, maxSearchDist, phasemask)); } bool Map::IsInWater(float x, float y, float pZ, LiquidData* data) const diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 7d234d5f75a..148a55d4691 100755 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -429,10 +429,11 @@ class Map : public GridRefManager<NGridType> float GetWaterOrGroundLevel(float x, float y, float z, float* ground = NULL, bool swim = false) const; float GetHeight(uint32 phasemask, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const; - void Balance() { m_dyn_tree.balance(); } - void Remove(const GameObjectModel& mdl) { m_dyn_tree.remove(mdl); } - void Insert(const GameObjectModel& mdl) { m_dyn_tree.insert(mdl); } - bool Contains(const GameObjectModel& mdl) const { return m_dyn_tree.contains(mdl);} + void Balance() { _dynamicTree.balance(); } + void Remove(const GameObjectModel& mdl) { _dynamicTree.remove(mdl); } + void Insert(const GameObjectModel& mdl) { _dynamicTree.insert(mdl); } + bool Contains(const GameObjectModel& mdl) const { return _dynamicTree.contains(mdl);} + bool getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist); private: void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); @@ -488,7 +489,7 @@ class Map : public GridRefManager<NGridType> uint32 i_InstanceId; uint32 m_unloadTimer; float m_VisibleDistance; - DynamicMapTree m_dyn_tree; + DynamicMapTree _dynamicTree; MapRefManager m_mapRefManager; MapRefManager::iterator m_mapRefIter; diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 18340ea224b..173df8dc809 100755 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -212,12 +212,12 @@ int32 Quest::GetRewOrReqMoney() const bool Quest::IsAutoAccept() const { - return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_ACCEPT) ? false : Flags & QUEST_FLAGS_AUTO_ACCEPT; + return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_ACCEPT) ? false : (Flags & QUEST_FLAGS_AUTO_ACCEPT); } bool Quest::IsAutoComplete() const { - return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_COMPLETE) ? false : Method == 0 || HasFlag(QUEST_FLAGS_AUTOCOMPLETE); + return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_COMPLETE) ? false : (Method == 0 || HasFlag(QUEST_FLAGS_AUTOCOMPLETE)); } bool Quest::IsAllowedInRaid() const diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 6802cbdd90d..ef5f32b5575 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -6076,7 +6076,10 @@ void Spell::EffectLeap(SpellEffIndex /*effIndex*/) if (!m_targets.HasDst()) return; - unitTarget->NearTeleportTo(m_targets.GetDst()->GetPositionX(), m_targets.GetDst()->GetPositionY(), m_targets.GetDst()->GetPositionZ(), m_targets.GetDst()->GetOrientation(), unitTarget == m_caster); + Position pos; + m_targets.GetDst()->GetPosition(&pos); + unitTarget->GetFirstCollisionPosition(pos, unitTarget->GetDistance(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 2.0f), 0.0f); + unitTarget->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), unitTarget == m_caster); } void Spell::EffectReputation(SpellEffIndex effIndex) diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 13609a490e5..1e1e34431a2 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -33,7 +33,6 @@ npc_guardian 100% guardianAI used to prevent players from accessin npc_garments_of_quests 80% NPC's related to all Garments of-quests 5621, 5624, 5625, 5648, 565 npc_injured_patient 100% patients for triage-quests (6622 and 6624) npc_doctor 100% Gustaf Vanhowzen and Gregory Victor, quest 6622 and 6624 (Triage) -npc_kingdom_of_dalaran_quests Misc NPC's gossip option related to quests 12791, 12794 and 12796 npc_mount_vendor 100% Regular mount vendors all over the world. Display gossip if player doesn't meet the requirements to buy npc_rogue_trainer 80% Scripted trainers, so they are able to offer item 17126 for class quest 6681 npc_sayge 100% Darkmoon event fortune teller, buff player based on answers given @@ -1137,50 +1136,6 @@ public: }; /*###### -## npc_kingdom_of_dalaran_quests -######*/ - -enum eKingdomDalaran -{ - SPELL_TELEPORT_DALARAN = 53360, - ITEM_KT_SIGNET = 39740, - QUEST_MAGICAL_KINGDOM_A = 12794, - QUEST_MAGICAL_KINGDOM_H = 12791, - QUEST_MAGICAL_KINGDOM_N = 12796 -}; - -#define GOSSIP_ITEM_TELEPORT_TO "I am ready to be teleported to Dalaran." - -class npc_kingdom_of_dalaran_quests : public CreatureScript -{ -public: - npc_kingdom_of_dalaran_quests() : CreatureScript("npc_kingdom_of_dalaran_quests") { } - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->HasItemCount(ITEM_KT_SIGNET, 1) && (!player->GetQuestRewardStatus(QUEST_MAGICAL_KINGDOM_A) || - !player->GetQuestRewardStatus(QUEST_MAGICAL_KINGDOM_H) || !player->GetQuestRewardStatus(QUEST_MAGICAL_KINGDOM_N))) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TELEPORT_TO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF + 1) - { - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_TELEPORT_DALARAN, false); - } - return true; - } -}; - -/*###### ## npc_mount_vendor ######*/ @@ -3154,7 +3109,6 @@ void AddSC_npcs_special() new npc_injured_patient; new npc_garments_of_quests; new npc_guardian; - new npc_kingdom_of_dalaran_quests; new npc_mount_vendor; new npc_rogue_trainer; new npc_sayge; @@ -3179,4 +3133,3 @@ void AddSC_npcs_special() new npc_firework; new npc_spring_rabbit(); } - |
