Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "ScriptPCH.h"
- #include "MapManager.h"
- #include "Language.h"
- #define SIZE(objectId) sObjectMgr->GetGameObjectTemplate(objectId)->size // lazy macro to get size for testing
- struct PlayerData
- {
- bool Snap;
- bool Intersect;
- };
- static UNORDERED_MAP<uint32, PlayerData> DataMap;
- class GOSnap_commandscript : public CommandScript
- {
- public:
- GOSnap_commandscript() : CommandScript("GOSnap_commandscript")
- {
- }
- ChatCommand* GetCommands() const
- {
- static ChatCommand GOSnapCommandTable[] =
- {
- // Fix RBAC crap :|
- { "gosnap", SEC_GAMEMASTER, false, &GOSnap_Command, "", NULL },
- { "gointersect", SEC_GAMEMASTER, false, &GOintersect_command, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
- return GOSnapCommandTable;
- }
- static bool GOSnap_Command(ChatHandler* handler, const char* args)
- {
- DataMap[handler->GetSession()->GetGuidLow()].Snap = !DataMap[handler->GetSession()->GetGuidLow()].Snap;
- if(DataMap[handler->GetSession()->GetGuidLow()].Snap)
- handler->GetSession()->SendNotification("On");
- return true;
- }
- static bool GOintersect_command(ChatHandler* handler, const char* args)
- {
- DataMap[handler->GetSession()->GetGuidLow()].Intersect = !DataMap[handler->GetSession()->GetGuidLow()].Intersect;
- if(DataMap[handler->GetSession()->GetGuidLow()].Intersect)
- handler->GetSession()->SendNotification("On");
- return true;
- }
- };
- // possible spells:
- // 27651, 897
- class AOE_Placer_Script : public SpellScriptLoader
- {
- public:
- AOE_Placer_Script() : SpellScriptLoader("AOE_Placer_Script")
- {
- }
- class spell_AOE_Placer_Script : public SpellScript
- {
- PrepareSpellScript(spell_AOE_Placer_Script);
- uint32 objectId;
- WorldLocation summonPos;
- typedef std::list<GameObject*> BlockList;
- uint32 GetObjectEntry()
- {
- return 178442;
- Item* item = GetCastItem();
- if (!item)
- return 0;
- switch (item->GetEntry())
- {
- // item entry is 123, spawn object entry 345
- case 123: return 345;
- case 435: return 567;
- }
- return 0;
- }
- void HandleAfterCast()
- {
- if (!GetCaster() || !GetCaster()->ToPlayer())
- return;
- if (!GetExplTargetDest())
- return;
- summonPos.WorldRelocate(*GetExplTargetDest());
- summonPos.SetOrientation(GetCaster()->GetOrientation());
- objectId = GetObjectEntry();
- if (!objectId)
- return;
- const GameObjectTemplate* objectInfo = sObjectMgr->GetGameObjectTemplate(objectId);
- if (!objectInfo)
- return;
- if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId))
- return;
- FixSnap();
- if (DoesIntersect3D())
- ;//return;
- SpawnObject();
- }
- // made it so the orientations can be anything and width and height can be anything
- // this assumes the spawn point is the center of the object
- // This does not check ground intersecting, so checking from center doesnt matter, but the width and height need to be according to center.
- bool DoesIntersect3D()
- {
- BlockList list = GetNearGameobjects();
- if (list.empty())
- return false;
- Position* spawn = GetCorners(GetExplTargetDest(), SIZE(objectId), SIZE(objectId)); // actually an array[5] | !memory management!
- for (BlockList::const_iterator it = list.begin(); it != list.end(); ++it)
- {
- if (!(*it) || !(*it)->IsInWorld())
- continue; // no need to check
- if (fabs((*it)->GetPositionZ() - summonPos.GetPositionZ()) > (*it)->GetObjectSize() + SIZE(objectId))
- continue; // doesnt interserct, too high apart (Z) | Fix the object heights above! Atm uses object size (size = height from center, so ObjectHeight = 2xSize)
- Position* target = GetCorners((*it), SIZE((*it)->GetEntry()), SIZE((*it)->GetEntry())); // funny thing about gameobjects etc .. they ARE Position objects :3
- for (uint8 i = 0; i < 4; ++i)
- for (uint8 j = 0; j < 4; ++j)
- if (DoesCross(spawn[i], spawn[i+1], target[j], target[j+1]))
- {
- delete spawn; // !memory management!
- return true;
- }
- }
- delete spawn; // !memory management!
- return false;
- }
- // a and b are lines, 1 and 2 are start and end points
- bool DoesCross(Position a1, Position a2, Position b1, Position b2)
- {
- float a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y;
- a1.GetPosition(a1x, a1y);
- a2.GetPosition(a2x, a2y);
- b1.GetPosition(b1x, b1y);
- b2.GetPosition(b2x, b2y);
- float a = (a1x - a2x)*(b1y - a1y) - (a1y - a2y)*(b1x - a1x);
- float b = (a1x - a2x)*(b2y - a1y) - (a1y - a2y)*(b2x - a1x);
- return a < 0 != b < 0; // a and b have different sign -> crosses
- }
- // returns array[5]
- static Position* GetCorners(const Position* pos, float width, float height)
- {
- Position * ret = new Position[5]; // 4 corners and one twice | !memory management!
- for (uint8 i = 0; i < 5; ++i)
- {
- float o = Position::NormalizeOrientation(pos->GetOrientation()+i*M_PI/2);
- float x = std::cos(o)*height; // wow uses Y,X coordinates?
- float y = -std::sin(o)*width;
- ret[i].Relocate(x,y,o);
- }
- return ret;
- }
- BlockList GetNearGameobjects()
- {
- // SIZE_OF_GRIDS || 2*sqrt(2*pow(MAX_RADIUS, 2)) // max radius for any object x2 (more efficency)
- float x,y,z;
- summonPos.GetPosition(x,y,z);
- BlockList objects;
- Trinity::GameObjectInRangeCheck checker(x,y,z, SIZE_OF_GRIDS);
- Trinity::GameObjectListSearcher<Trinity::GameObjectInRangeCheck> searcher(GetCaster(), objects, checker);
- GetCaster()->VisitNearbyGridObject(SIZE_OF_GRIDS, searcher);
- return objects;
- }
- // tries to snap to a predefined grid (2D grid, not 3D atm)
- void FixSnap()
- {
- static const float gridsize = 4.0f;
- float x,y,z;
- summonPos.GetPosition(x,y,z);
- float fract, whole;
- fract = modf(x / gridsize, &whole);
- x = (fract < 0.5f ? whole : whole+1)*gridsize+gridsize/2;
- fract = modf(y / gridsize, &whole);
- y = (fract < 0.5f ? whole : whole+1)*gridsize+gridsize/2;
- float newZ = GetCaster()->GetMap()->GetHeight(GetCaster()->ToPlayer()->GetPhaseMaskForSpawn(), x, y, MAX_HEIGHT);
- if (newZ != INVALID_HEIGHT)
- z = newZ;
- summonPos.Relocate(x, y, z);
- }
- void SpawnObject()
- {
- Player* player = GetCaster()->ToPlayer();
- float x, y, z, o;
- summonPos.GetPosition(x,y,z,o);
- Map* map = player->GetMap();
- GameObject* object = new GameObject;
- uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT);
- if (!object->Create(guidLow, objectId, map, player->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
- {
- delete object;
- return;
- }
- object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn());
- if (!object->LoadGameObjectFromDB(guidLow, map))
- {
- delete object;
- return;
- }
- sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGOData(guidLow));
- return;
- }
- void Register()
- {
- AfterCast += SpellCastFn(spell_AOE_Placer_Script::HandleAfterCast);
- }
- };
- SpellScript* GetSpellScript() const
- {
- return new spell_AOE_Placer_Script();
- }
- };
- void AddSC_AOE_Placer_Script()
- {
- new AOE_Placer_Script();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement