• 0

    posted a message on DragonThings - Race Courses

    I've never wrote an addon for wow but started messing around with an idea...not sure if i will continue it or not so I provided the code if anyone wants to take a look - its proof of concept so def not optimized or 'production ready' 

     

    the idea this was to be able to create race courses and utilize the in-game pins/mini map and map icons

     

    right now it just shows players location, current map, if you're mounted it will show the mount (have to be on a dragon riding mount) and an arrow that spins like crazy....you can also run the 'course' and it will say complete.

     

    the 'checkbox' is used if you want to create a route you would open the map and mark your route with the in-game pins and it gets saved...reset is for testing just to reset current waypoints and start is to kick off the race.

     

    I was going toward making this something you could do in a group etc. and compete against each other and share your routes but again not sure if I'll continue working on it unless its something people might want.

     

    *again this is a proof of concept so you cant really run it or do anything but if you have questions/ideas please feel free to post them*

     

     

    1

     

     

     

     

    -- Author      : bruce
    -- Create Date : 12/7/2022 1:50:44 AM
    local addon_name, addon = ...
    local hbd = addon.hbd
    local hbdp = LibStub("HereBeDragons-Pins-2.0")
    
    --events
    Frame1:RegisterEvent("ADDON_LOADED")
    Frame1:RegisterEvent("USER_WAYPOINT_UPDATED")
    --
    Frame1:RegisterEvent("ZONE_CHANGED_NEW_AREA")
    Frame1:RegisterEvent("ZONE_CHANGED")
    Frame1:RegisterEvent("ZONE_CHANGED_INDOORS")
    Frame1:RegisterEvent("NEW_WMO_CHUNK")
    
    DRAGON_RIDING = {
    	[1589] = "Renewed Proto-Drake",
    	[1591] = "Cliffside Wylderdrake",
    	[1563] = "Highland Drake",
    	[1590] = "Windborne Velocidrake"
    }
    
    DRAGON_ICONS = {
    	[1589] = "dragonriding-barbershop-icon-protodrake",
    	[1591] = "dragonriding-barbershop-icon-wyvernspirit",
    	[1563] = "dragonriding-barbershop-icon-drake",
    	[1590] = "dragonriding-barbershop-icon-pterrodax"
    }
    
    --used with for updating arrow - dragonthings/tom tom
    local square_half = math.sqrt(0.5)
    local rad_135 = math.rad(135)
    local PI2 = math.pi * 2
    
    
    --dragon things
    local minmapdot --minmap icon to next waypoint
    
    local x,y --player location
    local map --player map
    
    local currentMountId = 0 --current mount
    local zoneName = "" --current zone name
    
    local totalpins = 0 --waypoints for race
    local curpin = 1 --current waypoint
    local distance = 0 --player distance from current active waypoint
    local mapId = 0 -- current player mapid
    local racing = false
    
    --get player map info - register zone change event and call this there
    local function UpdateZone()
    		print("updating zone")
    		map = C_Map.GetBestMapForUnit("player")
    		local mapInfo = C_Map.GetMapInfo(map)
    		zoneName = mapInfo.name
    		mapId = mapInfo.mapID
    end
    
    --create icon for maps
    local function CreateIcon(id)
    	local mapicon = Frame1:CreateTexture()
    	mapicon:SetAtlas(DRAGON_ICONS[id])
    	mapicon:SetSize(27,24)
    	mapicon:SetPoint("CENTER")
    	return mapicon
    end
    
    
    local function EndRace()
    	totalpins = 0
    	hbdp:RemoveMinimapIcon("minmapicon",minmapdot)
    	hbdp:RemoveAllWorldMapIcons("waypoint")
    	--testing1 = { ["Dungeons"] = { Valdrakken = {} } }
    	print("race ended")
    end
    
    
    local function UpdatePosition()
    	--get the distance in yards from the player to the next waypoint
    	if C_Map.HasUserWaypoint() then
    		distance = C_Navigation.GetDistance()
    	else
    		distance = 0
    	end
    
    	--get player position
    	local position = C_Map.GetPlayerMapPosition(map, "player")
    	x,y = position:GetXY()
    
    	--update ui
    	texttest:SetFormattedText("%.2f\r\n%.2f\r\n%s\r\n%.2f", x*100, y*100,zoneName,distance)
    
    	--update map and waypoints
    	if not x or not y or totalpins == 0 or distance == 0 then
    		--unable to get player position, no waypoints available
    	else
    		--this uses dragonthings and code from tom tom
    		--sync arrow - might remove this
    		local angle,dist = hbdp:GetVectorToIcon(minmapdot)
    		if not angle then
    			return compass:Hide()
    		end
    		angle = angle + rad_135
    
    		--??? unsure about this need to double check how it works with tomtom
    		if GetCVar("rotateMinimap") == "0" then
    			local cring = GetPlayerFacing()
    			angle = angle - cring
    		end
    		
    		--update arrow to point in the right direction
    		local sin,cos = math.sin(angle) * square_half, math.cos(angle) * square_half
    		compass:SetTexCoord(0.5-sin, 0.5+cos, 0.5+cos, 0.5+sin, 0.5-cos, 0.5-sin, 0.5+sin, 0.5-cos)
    	
    		--update waypoint if player is in range
    		if distance < 60 then
    			hbdp:RemoveMinimapIcon("minmapicon",minmapdot)
    			curpin = curpin + 1
    
    			if curpin > totalpins then
    				--race completed do something fancy here..for now just reset
    				curpin = 1
    				print("race complete!")
    			end
    
    			--get next waypoint and add to minmap
    			local xx = testing1.Dungeons.Valdrakken[curpin].x
    			local yy = testing1.Dungeons.Valdrakken[curpin].y
    			hbdp:AddMinimapIconMap("minmapicon", minmapdot, mapId, xx, yy, true, true)
    		
    			local mapPoint = UiMapPoint.CreateFromVector2D(map, CreateVector2D(xx,yy))
    			C_Map.SetUserWaypoint(mapPoint)
    		end
    	end
    end
    
    --detect if player is on a dragon riding mount
    local function UpdateMount()
    	if IsMounted() then
    		for k,v in pairs(DRAGON_RIDING) do
    			_, _, _, isActive, _, _, _, _, _, _, _, _ = C_MountJournal.GetMountInfoByID(k)
    			if isActive then
    				activeMount:SetText(v)
    				mountIcon:SetAtlas(DRAGON_ICONS[k])
    				currentMountId = k
    				break
    			end
    		end
    	else
    		mountIcon:SetAtlas("BattleBar-SwapPetFrame-DeadIcon")
    		if racing then
    			EndRace()
    			currentMountId = 0
    			racing = false
    		end
    		activeMount:SetText("N/A")
    	end
    end
    
    --start race
    local function Start(self,arg1)
    
    	if currentMountId == 0 then
    		message("You need to be on a dragon riding mount")
    		return
    	end
    
    	--get waypoints
    	totalpins = #testing1.Dungeons[zoneName]
    
    	if totalpins == 0 then
    		message("No Waypoints Found")
    		return
    	end
    		--clear map
    	hbdp:RemoveAllWorldMapIcons("waypoint")
    
    	if totalpins > 0 then
    		--add icon to minmap - might remove this
    		minmapdot = CreateIcon(currentMountId)
    		local map = C_Map.GetBestMapForUnit("player")
    		local xx = testing1.Dungeons[zoneName][curpin].x
    		local yy = testing1.Dungeons[zoneName][curpin].y
    		hbdp:AddMinimapIconMap("minmapicon", minmapdot, mapId, xx, yy, true, true)
    
    
    		for i=1,totalpins do
    			local mapicon = CreateIcon(currentMountId)
    			local xxx = testing1.Dungeons[zoneName][i].x
    			local yyy = testing1.Dungeons[zoneName][i].y
    			hbdp:AddWorldMapIconMap("waypoint", mapicon, mapId, xxx, yyy)
    			print("added "..i)
    		end
    
    
    		if C_Map.CanSetUserWaypointOnMap(map) then
    			local mapPoint = UiMapPoint.CreateFromVector2D(map, CreateVector2D(xx,yy))
    			C_Map.SetUserWaypoint(mapPoint)
    			racing = true
    		else
    			print("cant set pin")
    		end
    	
    	end
    end
    
    local function Update()
    	--update position
    	UpdatePosition()
    	--update mount info
    	UpdateMount()
    	--make pin active i dont think i need to call this every update
    	C_SuperTrack.SetSuperTrackedUserWaypoint(true)
    	--delay
    	C_Timer.After(1, Update)
    end
    
    
    local function Reset(self,arg1)
    	--totalpins = 0
    	--hbdp:RemoveMinimapIcon("minmapicon",minmapdot)
    	--hbdp:RemoveAllWorldMapIcons("waypoint")
    	EndRace()
    	testing1 = { ["Dungeons"] = { Valdrakken = {} } }
    	print("reset waypoints")
    end
    
    
    Frame1:SetScript("OnEvent", function(self, event, arg1, ...)
    	if arg1 == "DragonThings" then
    		if event == "ADDON_LOADED" then
    			x = nil
    			y = nil
    			print("addon loaded")
    
    			testbutton:SetScript("OnClick",Start)
    			resetbutton:SetScript("OnClick",Reset)
    
    			UpdateZone()
    			Update()
    		end
    	end
    
    	--
    	if event == "USER_WAYPOINT_UPDATED" and checkupdate:GetChecked() then
    		local wp = C_Map.GetUserWaypoint().position
    
    		table.insert(testing1.Dungeons[zoneName],{ ["x"] = wp.x, ["y"] = wp.y })
    		print("waypoint set")
    
    		print("new wp added at "..wp.x.."/"..wp.y)
    	end
    
    	--zone change new area seems to fire in diff areas of the map like trade distrct etc...look into
    	if event == "ZONE_CHANGED_NEW_AREA" or event == "ZONE_CHANGED" then --  or event == "NEW_WMO_CHUNK"
    		UpdateZone()
    	end
    
    end)
    
    --entrypoint update
    function Testing()
    	print("race race race!")
    end

     

     

    Posted in: Addon Ideas
  • To post a comment, please or register a new account.