LavishNav:Sample code in LavishScript

From Lavish Software Wiki
Jump to: navigation, search

waypointNavigator

waypointNavigator object

objectdef waypointNavigator
{

	variable lnavregionref WaypointSet

	variable lnavregionref LastPoint

	; We have our choice of Dijkstra's algorithm or A* for pathfinding. I'll use dijkstra here.
	; There are times when one is better than the other.
	variable dijkstrapathfinder Pathfinder

	variable lnavpath Path


	variable lnavregionref StartPoint
	variable lnavregionref EndPoint

	; Constructor 
	method Initialize(string Name)
	{
		WaypointSet:SetRegion[${LavishNav.Tree.AddChild[universe,"WaypointNavigator",-unique]}]
	}

	method Shutdown()
	{
		; Removing our universe will "unload" all of our nav data, including the universe
		WaypointSet:Remove
	}


	method Clear()
	{
		WaypointSet:Clear
	}

	; Add the next waypoint at X,Y,Z
	member:bool AddWaypoint(float X, float Y, float Z)
	{
	
		variable lnavregionref NewPoint
	
		; Add a waypoint, auto-named, at X,Y,Z
		NewPoint:SetRegion[${WaypointSet.AddChild[point,auto,${X},${Y},${Z}]}]

		; If NewPoint is not set to a valid region, obviously we failed at creating a point.
		if !${NewPoint.Region(exists)}
			return FALSE
	
		; If we had a previous point, connect it to our new point
		if ${LastPoint.Region(exists)}
		{
			LastPoint:Connect[${NewPoint}]
		}	
		else
		{
			StartPoint:SetRegion[${NewPoint}]
			echo StartPoint=${StartPoint.CenterPoint}
		}
	
		LastPoint:SetRegion[${NewPoint}]

		return TRUE
	}

	method AddWaypoint(float X, float Y, float Z)
	{
		noop ${This.AddWaypoint[${X},${Y},${Z}]}
	}

	method WaypointsFinished()
	{
		EndPoint:SetRegion[${LastPoint}]
		echo EndPoint=${EndPoint.CenterPoint}
	}

	method GetReconnectedPath(float X, float Y, float Z)
	{
		Path:Clear
		variable lnavregionref nearest=${WaypointSet.NearestChild[${X},${Y},${Z}]}
		echo nearest=${nearest.CenterPoint}
		Pathfinder:SelectPath[${nearest},${EndPoint},Path]
	}
	
	method GetPath()
	{
		Path:Clear
		Pathfinder:SelectPath[${StartPoint},${EndPoint},Path]	
	}

	; Store waypoints to file. Use LSO to store in a LSO formatted file instead of XML. 
	; LSO is like a binary formatted XML. It will load and store faster. With small files it doesn't matter.
	method Store(string filename, bool LSO)
	{
		; Add a metadata point to store custom data
		variable lnavregionref Metadata

		Metadata:SetRegion[${WaypointSet.AddChild[point,"metadata"]}]
		Metadata:SetCustom[start,"${StartPoint.Name.Escape}"]
		Metadata:SetCustom[end,"${EndPoint.Name.Escape}"]

		if ${LSO}
			WaypointSet:ExportChildren[-lso,"${filename.Escape}"]
		else
			WaypointSet:ExportChildren["${filename.Escape}"]

;		Alternatively, store it in an LSO file (which is basically a binary XML format, it loads and stores faster, but can't be edited in notepad etc)
	}

	method Restore(string filename, bool LSO)
	{
		if ${LSO}
			WaypointSet:Import[-lso,"${filename.Escape}"]
		else
			WaypointSet:Import["${filename.Escape}"]
		
		variable lnavregionref Metadata
		Metadata:SetRegion[${WaypointSet.FindRegion[metadata]}]
		echo metadata=${Metadata} start=${WaypointSet.FindRegion[${Metadata.Custom[start]}]} end=${WaypointSet.FindRegion[${Metadata.Custom[end]}]}
		StartPoint:SetRegion[${WaypointSet.FindRegion[${Metadata.Custom[start]}]}]
		EndPoint:SetRegion[${WaypointSet.FindRegion[${Metadata.Custom[end]}]}]

		; Remove the metadata point so it doesn't show up as NearestChild at 0,0,0
		Metadata:Remove
	}

}

Testing of waypointNavigator object

variable waypointNavigator navigator

function AddWaypoints()
{
	navigator:AddWaypoint[1,2,3]
	navigator:AddWaypoint[4,5,6]
	navigator:AddWaypoint[7,8,9]
	navigator:AddWaypoint[10,11,12]
	navigator:WaypointsFinished
}

function DisplayPath()
{
	echo Hops=${navigator.Path.Hops}
	

	variable lnavregionref To
	variable lnavregionref From

; Each hop is a destination. Hop 1 is the start point of the path.
	echo Start at ${navigator.Path.Region[1].CenterPoint}

	variable uint N=2
	for (${N} <= ${navigator.Path.Hops} ; N:Inc)
	{
		To:SetRegion[${navigator.Path.Region[${N}]}]

		From:SetRegion[${navigator.Path.Connection[${N}].Source}]

		echo Hop=${N} From=${From.CenterPoint} To=${To.CenterPoint}
	}
}

function main()
{
	echo \agAdding waypoints
	call AddWaypoints


	echo \agFull Path
	navigator:GetPath
	call DisplayPath


	echo \agPartial Path -- from 4,5,6
	navigator:GetReconnectedPath[4,5,6]
	call DisplayPath

	echo \agStoring to testdata.xml
	navigator:Store[testdata.xml,FALSE]
	echo \agClearing data
	navigator:Clear

	echo \agNew full path, should have 0 hops because we removed the data
	navigator:GetPath
	call DisplayPath

	echo \agRestoring from testdata.xml
	navigator:Restore[testdata.xml,FALSE]
			
	echo \agNew full path
	navigator:GetPath
	call DisplayPath
		
 }