eluna-scripts-ornfelt/lua/WowEmulationScriptPack/Lua/finished/gobtp.lua

227 lines
12 KiB
Lua
Raw Permalink Normal View History

2023-08-16 00:50:59 +02:00
print "--- D.I.D.R.I.K - DIGITAL INTERCHANGEABLE GEOGRAPHICAL DEFERRED REAL-TIME INTUITIVE KARPUS (or gobtp for short) has been LOADED! ---"
-- Owner: Didrik
-- This script allows for: Creating teleports on click for gameobjects. The gameobjects are required to be clickable.
-- It does this by applying a hook to every entryID of every gameobject that has a teleport, but in the script it checks for the specific gob (DB)GUID.
-- commands:
-- .gobtp connect (GUID1) (GUID2) -optional (xOffset) (yOffset) (zOffset) - 2 required params, 3 optional
-- .gobtp manual (GUID1) (mapid) (x) (y) (z) (orientation) -- 6 params
-- .gobtp simple (GUID1) -- 1 param
-- .gobtp delete (GUID1) -- 1 param, deletes all links for that ID.
local Teleporter = {}
local ACCOUNT_LEVEL = 2 -- equal and above account levels can use this command.
--- Commands ---
local function TeleporterCommandHandler(event, player, command)
if (player:GetGMRank() < ACCOUNT_LEVEL) then
return
elseif (command:find("gobtp") ~= 1) then
return
else
local parameters = {}
local parameters = getCommandParameters(command)
-- .gobtp connect (GUID1) (GUID2) -optional (xOffset) (yOffset) (zOffset) - 2 required params, 3 optional
if (parameters[2] == "connect" and isNumber(parameters[3]) and isNumber(parameters[4])) then -- Make sure the two GUID parameters are ints.
local guid = tonumber(parameters[3])
local target = tonumber(parameters[4])
local entry = GetGameObjectEntryID(guid)
local targetCoords = GetGameObjectXYZ(target) -- Add coordinates of target GUID to variable targetCoords
local xOffset = tonumber(parameters[5]) or 0
local yOffset = tonumber(parameters[6]) or 0
local zOffset = tonumber(parameters[7]) or 0
if Teleporter.CheckIfGUIDHasLink(guid) then -- Checks if GUID1 has a link defined in the DB already.
PrintInfo("[D.I.D.R.I.K Teleporter]: " .. player:GetName() .. " tried to create a link for a GOB GUID that already exists: ".. guid)
player:SendBroadcastMessage("A link for that GOB GUID already exists.")
return false
else
player:SendBroadcastMessage("Creating connected link...")
local query = "INSERT INTO eluna_teleporter (guid,target,entry,map,x,y,z,o) VALUES(".. guid ..", ".. target ..", " .. entry ..", ".. targetCoords["map"] ..", ".. tonumber(targetCoords["x"])+xOffset ..", " .. tonumber(targetCoords["y"])+yOffset ..", " .. tonumber(targetCoords["z"])+zOffset ..", " .. targetCoords["o"] .. ");"
PrintInfo("[D.I.D.R.I.K Teleporter]: " .. player:GetName() .. " is creating a connected link with query: " .. query)
WorldDBQuery(query)
ReloadGobTPEvents()
player:SendBroadcastMessage("Successfully created a connected link for GOB GUID " .. guid .. "!")
return false
end
-- .gobtp manual (GUID1) (mapid) (x) (y) (z) (orientation) -- 6 params
elseif (parameters[2] == "manual" and isNumber(parameters[3]) and isNumber(parameters[4]) and isNumber(parameters[5]) and isNumber(parameters[6]) and isNumber(parameters[7]) and isNumber(parameters[8])) then -- Make sure the two GUID parameters are ints.
local guid = tonumber(parameters[3])
local entry = GetGameObjectEntryID(guid)
local targetCoords = {
map = tonumber(parameters[4]),
x = tonumber(parameters[5]),
y = tonumber(parameters[6]),
z = tonumber(parameters[7]),
o = tonumber(parameters[8]),
};
if Teleporter.CheckIfGUIDHasLink(guid) then
PrintInfo("[D.I.D.R.I.K Teleporter]: " .. player:GetName() .. " tried to create a link for a GOB GUID that already exists: ".. guid)
player:SendBroadcastMessage("A link for that GOB GUID already exists.")
return false
else
player:SendBroadcastMessage("Creating manual link...")
local query = "INSERT INTO eluna_teleporter (guid,target,entry,map,x,y,z,o) VALUES(".. guid ..", ".."0" ..", ".. entry ..", ".. targetCoords["map"] ..", ".. targetCoords["x"] ..", " .. targetCoords["y"] ..", " .. targetCoords["z"] ..", " .. targetCoords["o"] .. ");"
PrintInfo("[D.I.D.R.I.K Teleporter]: " .. player:GetName() .. " is creating a manual link with query: " .. query)
WorldDBQuery(query)
ReloadGobTPEvents()
player:SendBroadcastMessage("Succesfully created a manual link for GOB GUID " .. guid .. "!")
return false
end
-- .gobtp simple (GUID1) -- 1 param - takes players current position and links it to GUID1.
elseif (parameters[2] == "simple" and isNumber(parameters[3])) then -- Make sure the two GUID parameters are ints.
local guid = tonumber(parameters[3])
local entry = GetGameObjectEntryID(guid)
local map = player:GetMap()
local map = map:GetMapId()
local x, y, z, o = player:GetLocation()
if Teleporter.CheckIfGUIDHasLink(guid) then
PrintInfo("[D.I.D.R.I.K Teleporter]: " .. player:GetName() .. " tried to create a link for a GOB GUID that already exists: ".. guid)
player:SendBroadcastMessage("A link for that GOB GUID already exists.")
return false
else
player:SendBroadcastMessage("Creating simple link...")
local query = "INSERT INTO eluna_teleporter (guid,target,entry,map,x,y,z,o) VALUES(".. guid ..", ".."0" ..", ".. entry ..", ".. map ..", ".. x ..", " .. y ..", " .. z ..", " .. o .. ");"
PrintInfo("[D.I.D.R.I.K Teleporter]: " .. player:GetName() .. " is creating a simple link with query: " .. query)
WorldDBQuery(query)
ReloadGobTPEvents()
player:SendBroadcastMessage("Succesfully created a simple link for GOB GUID " .. guid .. "!")
return false
end
elseif (parameters[2] == "delete" and isNumber(parameters[3])) then
local guid = tonumber(parameters[3])
if not Teleporter.CheckIfGUIDHasLink(guid) then
PrintInfo("[D.I.D.R.I.K Teleporter]: " .. player:GetName() .. " tried to delete a link for a GOB GUID that doesn't exist: ".. guid)
player:SendBroadcastMessage("A link for that GOB GUID doesn't exist.")
return false
else
player:SendBroadcastMessage("Deleting link...")
local query = "DELETE FROM eluna_teleporter WHERE guid=" .. guid .. ";"
PrintInfo("[D.I.D.R.I.K Teleporter]: " .. player:GetName() .. " is deleting a link with query: " .. query)
WorldDBQuery(query)
ReloadGobTPEvents()
player:SendBroadcastMessage("Succesfully deleted a link for GOB GUID " .. guid .. "!")
return false
end
else
player:SendBroadcastMessage("You did something wrong when trying to create or delete a GOB link. Try again!")
return false
end
end
end
--- END COMMANDS ---
--- GameObjectGossipEvent Handler ---
function Teleporter.OnClick(event, player, object)
local t = Teleporter["Options"]
local objectguid = object:GetDBTableGUIDLow()
-- object:UseDoorOrButton() -- Opens the door or pushes the button, otherwise nothing happens since we overwrite the "default" behavior. It won't TP you to chairs though.
for _, v in ipairs(Teleporter["GUIDs"]) do
if v == objectguid then
player:Teleport(t[objectguid]["map"], t[objectguid]["x"], t[objectguid]["y"], t[objectguid]["z"], t[objectguid]["o"])
-- return true -- SEE BELOW
end
-- return false -- TEST THIS! Maybe we won't overwrite the behavior of "non" linked objects with this.
end
end
--- END GameObjectGossipEvent Handler ---
--- SQL ---
function Teleporter.CheckIfGUIDHasLink(objguid)
local guid = tonumber(objguid)
local query = "SELECT COUNT(*) from eluna_teleporter WHERE guid = " .. guid
local queryresult = WorldDBQuery(query)
if (queryresult:GetUInt32(0) >= 1) then
return true
else
return false
end
end
function Teleporter.LoadEntryIDs()
Teleporter["EntryIDs"] = {}
local Query = WorldDBQuery("SELECT DISTINCT entry FROM eluna_teleporter;")
if(Query) then
repeat
table.insert(Teleporter["EntryIDs"], Query:GetUInt32(0))
until not Query:NextRow()
PrintInfo("[D.I.D.R.I.K Teleporter]: Entry list initialized. Loaded "..Query:GetRowCount().." results.")
else
PrintInfo("[D.I.D.R.I.K Teleporter]: Entry list initialized. No results found.")
end
end
function Teleporter.LoadGUIDs()
Teleporter["GUIDs"] = {}
local Query = WorldDBQuery("SELECT DISTINCT guid FROM eluna_teleporter;")
if(Query) then
repeat
table.insert(Teleporter["GUIDs"], Query:GetUInt32(0))
until not Query:NextRow()
PrintInfo("[D.I.D.R.I.K Teleporter]: GUID list initialized. Loaded "..Query:GetRowCount().." results.")
else
PrintInfo("[D.I.D.R.I.K Teleporter]: GUID list initialized. No results found.")
end
end
function Teleporter.LoadCache() -- Loads the entire eluna_teleporter table from the world DB and 'caches' the locations into an array called Teleporter.
Teleporter["Options"] = {}
if not(WorldDBQuery("SHOW TABLES LIKE 'eluna_teleporter';")) then -- Create table if it doesn't exist. Doesn't work, I think?
PrintInfo("[D.I.D.R.I.K Teleporter]: eluna_teleporter table missing from world database.")
PrintInfo("[D.I.D.R.I.K Teleporter]: Inserting table structure, initializing cache.")
WorldDBQuery("CREATE TABLE `eluna_teleporter` (`guid` int(8) NOT NULL,`target` int(8) NOT NULL,`entry` int(8) NOT NULL,`map` int(8) DEFAULT NULL,`x` decimal(10,3) DEFAULT NULL,`y` decimal(10,3) DEFAULT NULL,`z` decimal(10,3) DEFAULT NULL,`o` decimal(10,3) DEFAULT NULL,`offsetx` decimal(10,3) DEFAULT NULL,`offsety` decimal(10,3) DEFAULT NULL,`offsetz` decimal(10,3) DEFAULT NULL,PRIMARY KEY (`guid`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;")
return Teleporter.LoadCache();
end
local Query = WorldDBQuery("SELECT * FROM eluna_teleporter;")
if(Query) then
repeat
Teleporter["Options"][Query:GetUInt32(0)] = {
target = Query:GetUInt32(1),
entry = Query:GetUInt32(2),
map = Query:GetUInt32(3),
x = Query:GetFloat(4),
y = Query:GetFloat(5),
z = Query:GetFloat(6),
o = Query:GetFloat(7),
offsetx = Query:GetFloat(8),
offsety = Query:GetFloat(9),
offsetz = Query:GetFloat(10),
};
until not Query:NextRow()
PrintInfo("[D.I.D.R.I.K Teleporter]: Cache initialized. Loaded "..Query:GetRowCount().." results.")
else
PrintInfo("[D.I.D.R.I.K Teleporter]: Cache initialized. No results found.")
end
end
--- END SQL ---
--- Reloader ---
function ReloadGobTPEvents()
Teleporter.LoadGUIDs()
Teleporter.LoadEntryIDs()
Teleporter.LoadCache()
--
for i, entry in ipairs(Teleporter["EntryIDs"]) do ClearGameObjectGossipEvents(entry, 1) end -- Clear all events.
--
for i, entry in ipairs(Teleporter["EntryIDs"]) do RegisterGameObjectGossipEvent(entry, 1, Teleporter.OnClick) end -- Re-create all the events.
--
end
--- END Reloader ---
--- Cleanup ---
function CleanupGobTP(eventId, delay, repeats)
local Query = "DELETE FROM eluna_teleporter WHERE guid IN (SELECT eluna_teleporter.guid FROM eluna_teleporter LEFT JOIN gameobject ON eluna_teleporter.guid = gameobject.guid WHERE gameobject.guid IS NULL);"
--- ^ Deletes any teleport rows where the guid (of the object you click) doesn't exist in the gameobject table anymore.
WorldDBExecute(Query)
PrintInfo("[D.I.D.R.I.K Teleporter]: Ran cleanup.")
end
--- END Cleanup ---
CreateLuaEvent(CleanupGobTP, 1800000, 0) -- we'll run cleanup every 30 minutes.
CleanupGobTP()
RegisterPlayerEvent(42, TeleporterCommandHandler)
ReloadGobTPEvents()