Thought Id post this poor example of my navObj.
Seen a few craft/diplo bots out there but none of those have any movement.
Since the bot Im using is pulse based, Ive moved the navObj into its own pulse system.
Main Program example..
navObj.iss
This should be seen as a work in progress, so use at your own risk ! =P
Note this version uses Spheres to keep track of the path.
Also inter Chunk_mapping isnt tested either.
Afk working on my c# bot... :toast:
Selu989/pelle
Seen a few craft/diplo bots out there but none of those have any movement.
Since the bot Im using is pulse based, Ive moved the navObj into its own pulse system.
Main Program example..
Code:
#include navObj.iss
function main()
{
echo "script start"
declarevariable RealmMap ObjMap script
while 1
{
waitframe
}
}
atom(global) gotoloc(int cx,int cy,int cz)
{
RealmMap:GotoLoc[${cx}, ${cy}, ${cz}]
}
atom(global) addpoint(string name)
{
RealmMap:AddPoint[${name}]
}
atom(global) gotopoint(string name)
{
RealmMap:GotoPoint[${name}]
}
atom(global) gotopoint2(string name)
{
RealmMap:GotoPoint[${name},1]
}
function atexit()
{
echo "script End"
}
Code:
objectdef ObjMap
{
#define STATE_MAP_NONE 0
#define STATE_MAP_ZONE_CHANGED 1
#define STATE_MAP_PLOT 2
#define STATE_MAP_CONNECT 3
#define STATE_RUN_HOP 4
#define STATE_RUN_ARRIVED 5
#define STATE_MAP_CHUNKCHANGE 6
#define MAP_Radius 80
#define ConnectRange 100
#define MOVE_SPLINE 1
#define MOVE_NORM 0
variable string navigationDir = "${LavishScript.HomeDirectory}/Scripts/VgMaps/"
variable lnavregionref ChunkRegion
variable lnavregionref ZoneRegion
variable lnavregionref CurrentRegion
variable lnavregionref PreviousRegion
variable int CurrentState = 0
variable string tempA
variable string tempB
variable float splinex[30]
variable float spliney[30]
variable int a1[12]
variable int b1[12]
variable point3f p[4]
variable lnavpath CurrentPath
variable int CurrentHop
variable int smooth
variable int splineHop
variable bool pauseMove = TRUE
variable bool AutoRun = FALSE
variable bool WaitForChunkChange = false
; Max Interpolation.
; Number of generated locations between waypoints.
variable int Interpolation = 5
;NOTE VG dont really play nice with the interpol function since it was written from eq1/WoW..
variable int range = 50
variable float zpx1
variable float zpx2
variable float zpy1
variable float zpy2
variable int interpol
method Initialize()
{
;called when object is initialized
Event[OnFrame]:AttachAtom[This:Pulse]
This:Load
;This:ZoneRegionChanged
}
method Shutdown()
{
Event[OnFrame]:DetachAtom[This:Pulse]
This:Save
}
method Load()
{
;Load map data from zone files.
declare HomeDir filepath script ${Script.CurrentDirectory}
variable filepath navDir = "${navigationDir}"
if !${HomeDir.FileExists["VGMaps"]}
{
mkdir "${HomeDir}/VGMaps"
echo "folder:${HomeDir}/VGMaps has been created."
}
LavishNav:Clear
if ${navDir.FileExists[${This.ChunkName}.xml]}
{
LavishNav.Tree:AddChild[universe,Telon,-unique]
LNavRegion[Telon]:Import["${navigationDir}${This.ChunkName}.xml"]
echo "Chunk data imported from:${navigationDir}${This.ChunkName}.xml"
}
if !${LNavRegion[Telon](exists)} || !${LNavRegion[${This.ChunkName}](exists)} || ${LNavRegion[${Me.Chunk.DisplayName}](exists)}
{
This:InitializeRegion
;This:Save
}
}
method Save()
{
;save zone data to file
variable lnavregionref old
variable lnavregionref curr
curr:SetRegion[${LNavRegion[Telon].Children.FQN}]
old:SetRegion[${curr.Region.FQN}]
do
{
echo ObjMap:${curr.Region.Name} saved to ${navigationDir}${curr.Region.Name}.xml
curr:Export["${navigationDir}${curr.Region.Name}.xml"]
old:SetRegion[${curr.Region.FQN}]
curr:SetRegion[${curr.Region.Next.FQN}]
}
while ${curr.Region.ID} != ${old.Region.ID} && ${curr.Region.ID}>0
}
method InitializeRegion()
{
;new zone adding it to Telon universe
if !${LNavRegion[Telon](exists)}
LavishNav.Tree:AddChild[universe,Telon,-unique]
if !${LNavRegion[Telon].FindRegion[${This.ChunkName}](exists)}
LNavRegion[Telon]:AddChild[universe,${This.ChunkName},-unique,-coordinatesystem]
if !${LNavRegion[${This.ChunkName}](exists)}
LNavRegion[Telon].FindRegion[${This.ChunkName}]:AddCild[universe,${Me.Chunk.DisplayName},-unique]
This.ChunkRegion:SetRegion[${This.ChunkName}]
This.ZoneRegion:SetRegion[${Me.Chunk.DisplayName}]
}
method ZoneRegionChanged()
{
This.ZoneRegion:SetRegion[${Me.Chunk.DisplayName}]
if !${This.ZoneRegion.ID}
{
LNavRegion[Telon].FindRegion[${This.ChunkName}]:AddChild[universe,${Me.Chunk.DisplayName},-unique]
This.ZoneRegion:SetRegion[${LNavRegion[Telon].FindRegion[${This.ChunkName}].FindRegion[${Me.Chunk.DisplayName}].FQN}]
}
echo "ObjMap: Zone region changed to ${This.ZoneRegion.FQN}"
}
method ChunkRegionChanged()
{
variable filepath navDir = "${navigationDir}"
variable lnavregionref curr
echo currRegion ${CurrentRegion.Name} prev:${PreviousRegion.Name} currChunk: ${This.ChunkName} prevChunk:${ChunkRegion.Name}
This:Save
if ${navDir.FileExists[${This.ChunkName}.xml]}
{
LNavRegion[Telon]:Import["${navigationDir}${This.ChunkName}.xml"]
echo "Chunk data imported from:${navigationDir}${This.ChunkName}.xml"
}
if !${LNavRegion[${This.ChunkName}].ID}
{
LNavRegion[Telon]:AddChild[universe,${This.ChunkName},-unique,-coordinatesystem]
This.ChunkRegion:SetRegion[${LNavRegion[Telon].FindRegion[${This.ChunkName}].FQN}]
}
curr:SetRegion[${LNavRegion[${Me.Chunk.DisplayName}].BestContainer[${Me.X},${Me.Y},${Me.Z}].FQN}]
curr:Connect[${PreviousRegion.FQN}]
PreviousRegion:Connect[${curr.Region.FQN}]
curr:SetCustom[WaitForChunkChange,TRUE]
PreviousRegion:SetCustom[WaitForChunkChange,TRUE]
curr:SetRegion[${LNavRegion[${This.ChunkName].FQN}]
curr:Connect[${ChunkRegion.FQN}]
ChunkRegion:Connect[${curr.FQN}]
This.ChunkRegion:SetRegion[${LNavRegion[${This.ChunkName}].FQN}]
if ${WaitForChunkChange}
WaitForChunkChange:Set[FALSE]
echo "ObjMap: Chunk region changed to ${This.ChunkRegion.FQN}"
}
member State()
{
if !${ChunkRegion.Region.Name.Equal[${This.ChunkName}]}
return STATE_MAP_CHUNKCHANGE
if !${This.ZoneRegion.Name.Equal[${Me.Chunk.DisplayName}]}
{
return STATE_MAP_ZONE_CHANGED
}
;if ${Math.Distance[${This.ZoneRegion.NearestChild[${Me.X},${Me.Y},${Me.Z}].Point},${Me.X},${Me.Y},${Me.Z}]}>110
; return STATE_MAP_PLOT
if (${This.ZoneRegion.ID} == ${This.CurrentRegion.ID})
{
return STATE_MAP_PLOT
}
if (${This.CurrentRegion.Region.ID} != ${This.PreviousRegion.Region.ID}) && ${This.ZoneRegion.Region.ID} != ${This.PreviousRegion.Region.ID} && ${This.ZoneRegion.Region.ID} != ${This.CurrentRegion.Region.ID} && ${This.This.PreviousRegion.Region.ID} >0 && ${This.CurrentRegion.Region.ID} > 0
{
return STATE_MAP_CONNECT
}
if ${CurrentHop}>0 &&${CurrentHop}<${CurrentPath.Hops}
return STATE_RUN_HOP
if ${CurrentHop}>0 && ${CurrentHop}==${CurrentPath.Hops}
return STATE_RUN_ARRIVED
return STATE_MAP_NONE
}
method Pulse()
{
This.PreviousRegion:SetRegion[${This.CurrentRegion.Region.ID}]
This.CurrentRegion:SetRegion[${This.ZoneRegion.Region.BestContainer[${Me.X},${Me.Y},${Me.Z}].ID}]
This.CurrentState:Set[${This.State}]
switch ${This.CurrentState}
{
case STATE_MAP_CHUNKCHANGE
This:ChunkRegionChanged
break
case STATE_MAP_ZONE_CHANGED
This:ZoneRegionChanged
break
case STATE_MAP_PLOT
This:PlotSphere[${Me.X}, ${Me.Y}, ${Me.Z}}]
break
case STATE_MAP_CONNECT
This:ConnectNeighbours[${This.CurrentRegion.Region.FQN}]
break
case STATE_RUN_HOP
if ${smooth}
This:SplineMove
else
This:Move
break
case STATE_RUN_ARRIVED
This:MoveStop
break
case default
break
}
}
method PlotSphere(float cX, float cY, float cZ)
{
variable int PointIdx = 1
variable int regions
variable string PointName = "R${Time.Timestamp}${This.ZoneRegion.ChildCount}"
LNavRegion[Telon].FindRegion[${This.ChunkName}].FindRegion[${Me.Chunk.DisplayName}]:AddChild[sphere, ${PointName}, -unique, MAP_Radius, ${cX}, ${cY}, ${cZ}]
LNavRegion[${This.PreviousRegion.Region.FQN}]:Connect[${PointName}]
LNavRegion[${PointName}]:Connect[${This.PreviousRegion.Region.FQN}]
;This:ConnectNeighbours[${PointName}]
echo "${PointName} plotted at X:${cX}, Y:${cY}, Z:${cZ}"
}
;----------------------------------------------------------------------------------------------------------------------------------------------
; Taken from AVBot
;----------------------------------------------------------------------------------------------------------------------------------------------
method ConnectNeighbours(string RegionName)
{
variable index:lnavregionref SurroundingRegions
variable lnavregionref Region
variable int RegionsFound
variable int Index = 1
variable int TEST = 0
Region:SetRegion[${RegionName}]
RegionsFound:Set[${ZoneRegion.DescendantsWithin[SurroundingRegions,ConnectRange,${Region.CenterPoint.X},${Region.CenterPoint.Y},${Region.CenterPoint.Z}]}]
if ${RegionsFound} > 0
{
do
{
if ${This.ShouldConnect[${Region.FQN},${SurroundingRegions.Get[${Index}].FQN}]}
{
echo Connection Region1: ${Region.Name} -> ${SurroundingRegions.Get[${Index}].Name}
Region:Connect[${SurroundingRegions.Get[${Index}].FQN}]
SurroundingRegions.Get[${Index}]:Connect[${Region.FQN}]
}
}
while ${SurroundingRegions.Get[${Index:Inc}](exists)}
}
}
member ShouldConnect(string RegionA, string RegionB)
{
variable lnavregionref RegionRefA
variable lnavregionref RegionRefB
if ${RegionA.Equal[${RegionB}]}
{
return FALSE
}
RegionRefA:SetRegion[${RegionA}]
RegionRefB:SetRegion[${RegionB}]
if ${This.RegionsIntersect[${RegionA},${RegionB}]} || ${This.RegionsIntersect[${RegionB},${RegionA}]}
{
return TRUE
}
return FALSE
}
member RegionsIntersect(string RegionA, string RegionB)
{
variable point3f P1
variable point3f P2
variable point3f P3
variable point3f P4
variable point3f P5
variable point3f P6
variable point3f P7
variable point3f P8
variable lnavregionref RA
variable lnavregionref RB
RA:SetRegion[${RegionA}]
RB:SetRegion[${RegionB}]
if ${RA.Type.Equal["Universe"]} || ${RB.Type.Equal["Universe"]}
{
return FALSE
}
P1.X:Set[${RA.Region.CenterPoint.X}]
P1.Y:Set[${RA.Region.CenterPoint.Y}]
P1.Z:Set[${RA.Region.CenterPoint.Z}]
P2.X:Set[${RB.Region.CenterPoint.X}]
P2.Y:Set[${RB.Region.CenterPoint.Y}]
P2.Z:Set[${RB.Region.CenterPoint.Z}]
if ${Math.Distance[${P1.X},${P1.Y},${P1.Z},${P2.X},${P2.Y},${P2.Z}]}<ConnectRange && ${Math.Abs[${P1.Z}-${P2.Z}]}<250
{
return TRUE
}
;echo
return FALSE
}
;----------------------------------------------------------------------------------------------------------------------------------------------
member:string ChunkName()
{
variable string d1
variable string d2
variable string final
if ${Me.Chunk.X}<0
{
d1:Set[n${Math.Abs[${Me.Chunk.X}].Int}]
}
else
d1:Set[${Me.Chunk.Y}]
if ${Me.Chunk.Y}<0
{
d2:Set[n${Math.Abs[${Me.Chunk.Y}].Int}]
}
else
d2:Set[${Me.Chunk.Y}]
final:Set[Chunk_${d1}_${d2}]
return ${final}
}
method GotoLoc(float cx,float cy,float cz, int temp = 0)
{
echo GotoLoc: X:${cx} Y:${cy} Z:${cz}
variable dijkstrapathfinder PathFinder
CurrentPath:Clear
CurrentHop:Set[0]
echo From Region:${This.NearestRegion[${Me.X},${Me.Y},${Me.Z}]} to Region: ${This.NearestRegion[${cx},${cy},${cz}]}
PathFinder:SelectPath[${This.NearestRegion[${Me.X},${Me.Y},${Me.Z}]},${This.NearestRegion[${cx},${cy},${cz}]},CurrentPath]
if (${CurrentPath.Hops} == 0)
{
echo "ObjMap: Could not map to ${cx}, ${cy}, ${cz} "
return
}
else
echo "Path found and it's ${CurrentPath.Hops} hops long."
smooth:Set[${temp}]
if ${temp}
echo Using BSpline smoother..
CurrentHop:Set[2]
return
}
member NearestSphere(float x,float y,float z)
{
variable lnavregionref region
region:SetRegion[Telon]
while ${region.Region.NearestChild[${x},${y},${z}].Type.NotEqual[Sphere]}
{
echo RegionSearch:${region.Region.Name}
region:SetRegion[${region.Region.NearestChild[${x},${y},${z}].FQN}]
}
if ${region.Region.Type.Equal[Sphere]}
return ${region.Region.FQN}
}
member NearestRegion(float X, float Y, float Z)
{
variable string Container
Container:Set[${ZoneRegion.BestContainer[${X},${Y},${Z}].FQN}]
return ${Container}
}
method MoveStop()
{
;echo MoveStop Called!
VG:ExecBinding[AutoRun,"Release"]
CurrentHop:Set[0]
splineHop:Set[0]
CurrentPath:Clear
AutoRun:Set[FALSE]
}
method Move()
{
if !${AutoRun}
{
VG:ExecBinding[AutoRun]
AutoRun:Set[TRUE]
}
variable float tempX = ${CurrentPath.Region[${CurrentHop}].CenterPoint.X}
variable float tempY = ${CurrentPath.Region[${CurrentHop}].CenterPoint.Y}
if !${WaitForChunkChange}
face ${tempX} ${tempY}
;echo MovePulse Hop ${CurrentHop}
if ${Math.Distance[${Me.X},${Me.Y},${tempX},${tempY}]}<${range}
{
CurrentHop:Inc
}
if ${CurrentHop}<=${CurrenPath.Hops} && ${CurrentPath.Region[${CurrentHop}].Custom[WaitForChunkChange].Equal[TRUE]}
WaitForChunkChange:Set[TRUE]
}
method SplineMove()
{
if !${AutoRun}
{
VG:ExecBinding[AutoRun]
AutoRun:Set[TRUE]
}
if ${CurrentHop}<=${CurrentPath.Hops}-5
{
if ${splineHop}==${interpol}
{
zpx1:Set[${CurrentPath.Region[${Math.Calc[${CurrentHop}+3]}].CenterPoint.X}]
zpx2:Set[${CurrentPath.Region[${Math.Calc[${CurrentHop}+4]}].CenterPoint.X}]
zpy1:Set[${CurrentPath.Region[${Math.Calc[${CurrentHop}+3]}].CenterPoint.Y}]
zpy2:Set[${CurrentPath.Region[${Math.Calc[${CurrentHop}+4]}].CenterPoint.Y}]
p[1]:Set[${CurrentPath.Region[${Math.Calc[${CurrentHop}+2]}].CenterPoint}]
p[2]:Set[${CurrentPath.Region[${Math.Calc[${CurrentHop}+3]}].CenterPoint}]
p[3]:Set[${CurrentPath.Region[${Math.Calc[${CurrentHop}+4]}].CenterPoint}]
p[4]:Set[${CurrentPath.Region[${Math.Calc[${CurrentHop}+5]}].CenterPoint}]
interpol:Set[${Math.Sqrt[${Math.Calc[(${zpx2}-${zpx1})^^2 + (${zpy2}-${zpy1})^^2]}]}]
if ${interpol}> ${Interpolation}
interpol:Set[${Interpolation}]
This:CalcBSpline[${interpol}]
CurrentHop:Inc
splineHop:Set[1]
}
if ${splinex[${splineHop}]} == 0 && ${spliney[${splineHop}]} == 0
{
splineHop:Set[${interpol}]
return
}
face ${splinex[${splineHop}]} ${spliney[${splineHop}]}
if ${Math.Distance[${Me.X},${Me.Y},${splinex[${splineHop}]}, ${spliney[${splineHop}]}]}<${range}
splineHop:Inc
if ${CurrentHop}==${Math.Calc[${CurrentPath.Hops}-5].Int} && ${splineHop}<=${interpol}
{
CurrentHop:Inc[4]
}
}
else
{
echo CurrHop: ${CurrentHop} MaxHops: ${CurrentPath.Hops}
face ${CurrentPath.Region[${CurrentHop}].CenterPoint.X} ${CurrentPath.Region[${CurrentHop}].CenterPoint.Y}
if ${Math.Distance[${Me.X},${Me.Y},${CurrentPath.Region[${CurrentHop}].CenterPoint.X},${CurrentPath.Region[${CurrentHop}].CenterPoint.Y}]}<${range}
CurrentHop:Inc
}
;wait 1
}
method CalcBSpline(int interpol)
{
variable float a[6]
variable float b[6]
variable int i
a[1]:Set[${Math.Calc[(-${p[1].X} + 3*${p[2].X} - 3*${p[3].X} + ${p[4].X})/6.0]}]
a[2]:Set[${Math.Calc[(3*${p[1].X} - 6*${p[2].X} + 3*${p[3].X})/6.0]}]
a[3]:Set[${Math.Calc[(-3*${p[1].X} + 3*${p[3].X})/6.0]}]
a[4]:Set[${Math.Calc[(${p[1].X} + 4*${p[2].X} + ${p[3].X})/6.0]}]
b[1]:Set[${Math.Calc[(-${p[1].Y} + 3*${p[2].Y} - 3*${p[3].Y} + ${p[4].Y})/6.0]}]
b[2]:Set[${Math.Calc[(3*${p[1].Y} - 6*${p[2].Y} + 3*${p[3].Y})/6.0]}]
b[3]:Set[${Math.Calc[(-3*${p[1].Y} + 3*${p[3].Y})/6.0]}]
b[4]:Set[${Math.Calc[(${p[1].Y} + 4*${p[2].Y} + ${p[3].Y})/6.0]}]
splinex[1]:Set[${a[4]}]
spliney[1]:Set[${b[4]}]
variable float t
for(i:Set[2]; ${i} <= ${interpol} ; i:Inc)
{
t:Set[${Math.Calc[${i}/${interpol}]}]
splinex[${i}]:Set[${Math.Calc[(${a[3]} + ${t}*(${a[2]} + ${t}*${a[1]}))*${t} + ${a[4]}]}]
spliney[${i}]:Set[${Math.Calc[(${b[3]} + ${t}*(${b[2]} + ${t}*${b[1]}))*${t} + ${b[4]}]}]
}
}
method AddPoint(string name)
{
variable lnavregionref region
variable lnavregionref point
if ${LNavRegion[${name}].ID}>0
{
echo Error:Name Already exists. pick another.
return
}
region:SetRegion[${LNavRegion[Telon].FindRegion[${This.ChunkName}].FindRegion[${Me.Chunk.DisplayName}].BestContainer[${Me.X},${Me.Y},${Me.Z}].FQN}]
region.Region:AddChild[point,${name},-unique,${Me.X}, ${Me.Y}, ${Me.Z}]
This:ConnectNeighbours[${name}]
echo Added : ${name} to ${region.Region.FQN}
}
method GotoPoint(string name, int temp = 0)
{
variable point3f point
point:Set[${LNavRegion[${name}].Point}]
echo X:${point.X} Y:${point.Y} Z:${point.Z}
;This:GotoLoc[${point.X},${point.Y},${point.Z},${spline}]
variable dijkstrapathfinder PathFinder
CurrentPath:Clear
CurrentHop:Set[0]
echo From Region:${This.NearestRegion[${Me.X},${Me.Y},${Me.Z}]} to Region: ${LNavRegion[${name}].FQN}
PathFinder:SelectPath[${This.NearestRegion[${Me.X},${Me.Y},${Me.Z}]},${LNavRegion[${name}].FQN},CurrentPath]
if (${CurrentPath.Hops} == 0)
{
echo "ObjMap: Could not find a path."
return
}
else
echo "Path found and it's ${CurrentPath.Hops} hops long."
smooth:Set[${temp}]
if ${temp}
echo Using BSpline smoother..
CurrentHop:Set[2]
return
}
member PauseMovement()
{
if ${pauseMove}
pauseMove:Set[FALSE]
else
pauseMove:Set[TRUE]
}
method FreeMoveLoc(float x,float y, float z)
{
}
; end of ObjMap
}
Note this version uses Spheres to keep track of the path.
Also inter Chunk_mapping isnt tested either.
Afk working on my c# bot... :toast:
Selu989/pelle
Last edited: