MAJOR bot-pathing request

Discussions about UT99

Re: MAJOR bot-pathing request

Postby Higor » Thu Feb 02, 2017 7:47 pm

I found that bots will jump off said lift if they're following a player.
Try ordering to attack and let them go on their own.

Also, FerBotz don't have proper lift handling on that case.
I'll put a new version fixing that later.
Higor
Godlike
 
Posts: 1698
Joined: Sun Mar 04, 2012 6:47 pm

Re: MAJOR bot-pathing request

Postby EvilGrins » Sun Feb 05, 2017 4:31 pm

This is the "ski-lift" in question:
Image

Once all the SkaarjSnipers around there (and anything else that can shoot you) are dead, bots still won't ride that lift all the way to the end without jumping over the side.
http://unreal-games.livejournal.com/
Image
medor wrote:Replace Skaarj with EvilGrins :mrgreen:
User avatar
EvilGrins
Godlike
 
Posts: 6147
Joined: Thu Jun 30, 2011 8:12 pm
Location: Palo Alto, CA
Personal rank: God of Fudge

Re: MAJOR bot-pathing request

Postby Gustavo6046 » Sun Feb 05, 2017 7:56 pm

sektor2111 wrote:you cannot force a retard to drive a plane, else Editor will not add paths on Lifts which seems a problem for more people nowadays because it's so... "hard" :loool: .


You know what? You inspired me to work on BotMovers. Basically an Info actor which takes the tag of the mover, and then traces from the center of the mover + CenterOffset and it traces diagonally downwards at a distance of WalkOffDistance. And inserts a LiftExit at the end.

Basicaslly automated lift pathing C:

P.S.: for movers like a donut, use two of these BotMovers, one for each side of the desired diameter for the bots to get in.
Terrain apprentice.
User avatar
Gustavo6046
Inhuman
 
Posts: 771
Joined: Mon Jun 01, 2015 7:08 pm
Personal rank: Typing ghost

Re: MAJOR bot-pathing request

Postby sektor2111 » Sun Feb 05, 2017 9:12 pm

I understand you. In other case Higor has some XC stuff for fixing Lifts but that thing will not work for mapper.... Technically Horizontal Lifts are a problem for default Bot (it was for MBot too) but not version E which... have a more normal patience, they simply won't jump out of lift as long as lift is moving and they are free of duty (no enemy to hunt).
I see that EG still have problems, testing MBot is simple, easy to add, easy to remove, easy for skinning, preferences menu added and... with that option can be configured any Bot prototype, default Bot will not fix itself in how was hard-coded defined, there are no INI options at this point. NOt to mention that MBot doesn't love MH controller making it to run in place like a dumbass, it is simple stopping after a while trying to get into Path-Net from a longer range than common Bot...
I don't have this issue at this moment (I'm busy with other nasty things) with horizontal lifts, I'm gonna do some full revision to this map if... I consider that it worth efforts, for me doesn't run smoother and I don't like this Engine blast...
For default Bot of course things are not easy because Bot will not wait that much for a mover-lift with many keys...

But... positives are usable for general mapping, here we have a teleporterfix solution operational with no XCGE - a sort of smarty PlayerStart, and if I'm completing my HuntNodes (different formats), triggers, etc. such a map can be fully operational by Bot (not only MBot/FerBotz), to not forget the most important thing: XC_PathBuilder - a treasure after all.
The problem is decreasing performance in attempting a forced Bot Control embedded in map... this is not that helpful.
User avatar
sektor2111
Godlike
 
Posts: 3825
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: MAJOR bot-pathing request

Postby Gustavo6046 » Sun Feb 05, 2017 11:19 pm

I've just coded some prototype. This just lays down a few Lift* NavigationPoints in PreBeginPlay. I hope they get linked in the end :P

But I fear it won't work since bNoDelete is true for LiftCenter and LiftExit. Would doing a subclass of those with bNoDelete false work then? :P

Code: Select all
//=============================================================================
// BotMovers.
//=============================================================================
class BotMovers expands Info;

struct KeyPath
{
   var()   int      KeyBegin;
   var()   byte   KeyOffset;
   var()   name   PathTag;
};

/*
Automating pathing might be still far from being true.
But here is a possible solution for automating LIFT
pathing.

By Gustavo6046
*/

var(Pathing)   Vector   CenterOffset;
var(Pathing)   float   WalkOffDistance;
var(Pathing)   float   WalkHeight;
var(Pathing)   int      NumPathes;
var(Pathing)   KeyPath   KeyPathes[8];
var(Pathing)   float   MaxWalkingPitch;
var(Pathing)   bool   bDebug;
var(Pathing)   byte   ExitDirs;
var(Pathing)   name   TriggerTag;
var(Pathing)   bool   bRetagMover;

// DegToRot = 182.0444444444444444444
// RotToDeg = 0.0054931640625

final operator(25) float # (Actor A, Actor B)
{
   return VSize(Location - A.Location) - VSize(Location - B.Location);
}

function Vector FullOffs()
{
   local Vector V;
   V = CenterOffset;
   V.Z += WalkHeight;

   return V;
}

function bool MoverPathable(Mover Other)
{
   return Other.bBlockActors;
}

function Mover GetMover()
{
   local Mover m, cm;

   if ( Tag != '' )
      foreach AllActors(class'Mover', m)
         if ( m.Tag == Tag && MoverPathable(m) )
            return m;

   else
   {
      foreach AllActors(class'Mover', m)
         if ( MoverPathable(m) && (cm != None || ((m # cm) < 0)) )
            cm = m;

      return cm;
   }

   return None;
}

function Vector MoverLocWithOffs(Mover Other, optional byte MoverKey)
{
   local Vector ML;

   ML = Other.KeyPos[MoverKey];

   return ML + FullOffs();
}

function Vector MyMoverLocWithOffs(optional byte MoverKey)
{
   local Vector ML;

   ML = GetMover().KeyPos[MoverKey];

   return ML + FullOffs();
}

function bool SurfaceWalkable(vector HitNormal)
{
   return abs(Rotator(HitNormal).Pitch) / 16384.0 < MaxWalkingPitch;
}

function bool TraceWalk(out Vector HitLoct, out Vector HitNorm, vector Start, float YawDeg) // helper function for other modders
{
   local Rotator FinalDir;
   local Vector DirOff;
   
   FinalDir.Yaw += YawDeg * 182.044444444444444444444444444;

   DirOff = Vector(FinalDir);
   DirOff *= WalkOffDistance;
   DirOff.Z -= WalkHeight;

   return Trace(HitLoct, HitNorm, Start + DirOff, Start, false) != None;
}

function bool TraceWalk2(out Vector HitLoct, out Vector HitNorm, vector Start, float YawStep, optional int Steps)
{
   local Rotator FinalDir;
   local Vector DirOff;

   if ( Steps == 0 )
      Steps = 8;
   
   FinalDir.Yaw += YawStep * (65536 / Steps);

   DirOff = Vector(FinalDir);
   DirOff *= WalkOffDistance;
   DirOff.Z -= WalkHeight;

   return Trace(HitLoct, HitNorm, Start + DirOff, Start, false) != None;
}

function ProcessPath(Mover Other, KeyPath Path)
{
   local Vector InPos, OutPos, OutNrm;
   local LiftCenter LC;
   local LiftExit LE;
   local byte st;

   if ( bRetagMover )
      Other.Tag = Path.PathTag;

   InPos = MoverLocWithOffs(Other, Path.KeyBegin);

   LC = Spawn(class'LiftCenter', self,, InPos);
   LC.LiftTag = Path.PathTag;
   LC.LiftTrigger = TriggerTag;
   LC.bHidden = !bDebug;

   for ( st = 0; st < ExitDirs; st++ )
   {
      TraceWalk2(OutPos, OutNrm, InPos, st, ExitDirs);
      
      if ( !SurfaceWalkable(OutNrm) )
         continue;

      OutPos.Z += WalkHeight;

      LE = Spawn(class'LiftExit', self,, OutPos);
      LE.LiftTag = Path.PathTag;
      LE.LiftTrigger = TriggerTag;
      LE.bHidden = !bDebug;
   }

   InPos = MoverLocWithOffs(Other, Path.KeyBegin);

   for ( st = 0; st < ExitDirs; st++ )
   {
      TraceWalk2(OutPos, OutNrm, InPos, st, ExitDirs);
      
      if ( !SurfaceWalkable(OutNrm) )
         continue;

      OutPos.Z += WalkHeight;

      LE = Spawn(class'LiftExit', self,, OutPos);
      LE.LiftTag = Path.PathTag;
      LE.LiftTrigger = TriggerTag;
      LE.bHidden = !bDebug;
   }
}

function PathMover()
{
   local Mover MyMover;
   local int i;
   local KeyPath KP;

   MyMover = GetMover();
   
   for ( i = 0; i < NumPathes; i++ )
   {
      ProcessPath(MyMover, KeyPathes[i]);

      KP.KeyBegin = KeyPathes[i].KeyOffset;
      KP.KeyOffset = KeyPathes[i].KeyBegin;

      ProcessPath(MyMover, KP);
   }
}

function PreBeginPlay()
{
   PathMover();
}


And a subclass which sets the offsets automatically:
Code: Select all
//=============================================================================
// QuickBotMover.
//=============================================================================
class QuickBotMover expands BotMovers;

var(Pathing)   bool   bResetWalkHeight;

// This class deprecates CenterOffset (and if desired WalkHeight) by using this actor's relative position to the mover instead.

function PreBeginPlay()
{
   local Mover MyMover;
   local Vector Offset;

   MyMover = GetMover();

   Offset = Location - MyMover.Location;

   if ( bResetWalkHeight )
      WalkHeight = Offset.Z;

   CenterOffset = Offset;

   if ( bResetWalkHeight )
      CenterOffset.Z = 0;
   
   Super.PreBeginPlay();
}


I should do sanity checks later, but this is a prototype and I'm testing it :P

SO yeah, I just speedcoded :mrgreen:

EDIT: Seems to work now:

Code: Select all
//=============================================================================
// BotMovers.
//=============================================================================
class BotMovers expands Info;

/*
Automating pathing might be still far from being true.
But here is a possible solution for automating LIFT
pathing.

By Gustavo6046
*/

struct KeyPath
{
   var()   int      KeyBegin;
   var()   byte   KeyOffset;
   var()   name   PathTag;
};

var(Pathing)   Vector   CenterOffset;
var(Pathing)   float   WalkOffDistance;
var(Pathing)   float   WalkHeight;
var(Pathing)   int      NumPathes;
var(Pathing)   KeyPath   KeyPathes[8];
var(Pathing)   float   MaxWalkingPitch;
var(Pathing)   bool   bDebug;
var(Pathing)   byte   ExitDirs;
var(Pathing)   name   TriggerTag;
var(Pathing)   bool   bRetagMover;

// DegToRot = 182.0444444444444444444
// RotToDeg = 0.0054931640625

final operator(25) float # (Actor A, Actor B)
{
   if ( A == None || B == None )
      return 0;

   return VSize(Location - A.Location) - VSize(Location - B.Location);
}

function Vector FullOffs()
{
   local Vector V;
   V = CenterOffset;
   V.Z += WalkHeight;

   return V;
}

function bool MoverPathable(Mover Other)
{
   return Other.bBlockActors;
}

function Mover GetMover()
{
   local Mover m, cm;

   if ( Tag != 'None' )
      foreach AllActors(class'Mover', m)
         if ( m.Tag == Tag && MoverPathable(m) )
            return m;

   else
   {
      foreach AllActors(class'Mover', m)
         if ( MoverPathable(m) && (cm != None || ((m # cm) < 0)) )
            cm = m;

      return cm;
   }

   return None;
}

function Vector MoverLocWithOffs(Mover Other, optional byte MoverKey)
{
   local Vector ML;

   ML = Other.KeyPos[MoverKey];

   return ML + FullOffs();
}

function Vector MyMoverLocWithOffs(optional byte MoverKey)
{
   local Vector ML;

   ML = GetMover().KeyPos[MoverKey];

   return ML + FullOffs();
}

function bool SurfaceWalkable(vector HitNormal)
{
   return abs(Rotator(HitNormal).Pitch) / 16384.0 < MaxWalkingPitch;
}

function bool TraceWalk(out Vector HitLoct, out Vector HitNorm, vector Start, float YawDeg) // helper function for other modders
{
   local Rotator FinalDir;
   local Vector DirOff;
   
   FinalDir.Yaw += YawDeg * 182.044444444444444444444444444;

   DirOff = Vector(FinalDir);
   DirOff *= WalkOffDistance;
   DirOff.Z -= WalkHeight;

   return Trace(HitLoct, HitNorm, Start + DirOff, Start, false) != None;
}

function bool TraceWalk2(out Vector HitLoct, out Vector HitNorm, vector Start, float YawStep, optional int Steps)
{
   local Rotator FinalDir;
   local Vector DirOff;

   if ( Steps == 0 )
      Steps = 8;
   
   FinalDir.Yaw += YawStep * (65536 / Steps);

   DirOff = Vector(FinalDir);
   DirOff *= WalkOffDistance;
   DirOff.Z -= WalkHeight;

   return Trace(HitLoct, HitNorm, Start + DirOff, Start, false) != None;
}

function bool ProcessPath(Mover Other, KeyPath Path)
{
   local Vector InPos, OutPos, OutNrm;
   local LiftCenter LC;
   local LiftExit LE;
   local byte st;

   if ( bRetagMover )
      Other.Tag = Path.PathTag;

   InPos = MoverLocWithOffs(Other, Path.KeyBegin);

   LC = Spawn(class'AutoLiftCenter', self,, InPos);

   if ( LC == None )
      return False;

   LC.LiftTag = Path.PathTag;
   LC.LiftTrigger = TriggerTag;
   LC.bHidden = !bDebug;

   for ( st = 0; st < ExitDirs; st++ )
   {
      TraceWalk2(OutPos, OutNrm, InPos, st, ExitDirs);
      
      if ( !SurfaceWalkable(OutNrm) )
         continue;

      OutPos.Z += WalkHeight;

      LE = Spawn(class'LiftExit', self,, OutPos);

      if ( LE == None )
         return False;

      LE.LiftTag = Path.PathTag;
      LE.LiftTrigger = TriggerTag;
      LE.bHidden = !bDebug;
   }

   InPos = MoverLocWithOffs(Other, Path.KeyBegin);

   for ( st = 0; st < ExitDirs; st++ )
   {
      TraceWalk2(OutPos, OutNrm, InPos, st, ExitDirs);
      
      if ( !SurfaceWalkable(OutNrm) )
         continue;

      OutPos.Z += WalkHeight;

      LE = Spawn(class'LiftExit', self,, OutPos);

      if ( LE == None )
         return False;

      LE.LiftTag = Path.PathTag;
      LE.LiftTrigger = TriggerTag;
      LE.bHidden = !bDebug;
   }

   return True;
}

function PathMover()
{
   local Mover MyMover;
   local int i;
   local KeyPath KP;

   MyMover = GetMover();
   
   for ( i = 0; i < NumPathes; i++ )
   {
      ProcessPath(MyMover, KeyPathes[i]);

      KP.KeyBegin = KeyPathes[i].KeyOffset;
      KP.KeyOffset = KeyPathes[i].KeyBegin;

      ProcessPath(MyMover, KP);
   }
}

function PreBeginPlay()
{
   if ( GetMover() == None )
      return;

   PathMover();
}


And AutoLiftCenter is just an empty LiftCenter subclass with like no changes other than bNoDelete = false.

I could also do class'LiftCenter'.default.bNoDelete = false; before and class'LiftCenter'.default.bNoDelete = true; after. But that would be hackish :P

EDIT: Damnit, I didn't see LiftExit bStatic! I'm doing such an awful job :C

EDIT: I just did this, but those LiftExit's just won't spawn in the ground where the lifts start! >.<
Code: Select all
//=============================================================================
// BotMovers.
//=============================================================================
class BotMovers expands Info;

/*
Automating pathing might be still far from being true.
But here is a possible solution for automating LIFT
pathing.

By Gustavo6046
*/

struct KeyPath
{
   var()   int      KeyBegin;
   var()   byte   KeyOffset;
   var()   name   PathTag;
   var()   float   InDistance;
   var()   float   OutDistance;
};

var(Pathing)   Vector   CenterOffset;
var(Pathing)   float   WalkHeight;
var(Pathing)   int      NumPathes;
var(Pathing)   KeyPath   KeyPathes[8];
var(Pathing)   float   MaxWalkingPitch;
var(Pathing)   bool   bDebug;
var(Pathing)   byte   ExitDirs;
var(Pathing)   name   TriggerTag;
var(Pathing)   bool   bRetagMover;
var(Pathing)   float   MoverHeight;

// DegToRot = 182.0444444444444444444
// RotToDeg = 0.0054931640625

function CheckLog(string s)
{
   if ( bDebug )
      Log(s);
}

final operator(25) float # (Actor A, Actor B)
{
   if ( A == None || B == None )
      return 0;

   return VSize(Location - A.Location) - VSize(Location - B.Location);
}

function Vector FullOffs(optional bool bAddHeight)
{
   local Vector V;
   V = CenterOffset;
   V.Z += WalkHeight;

   if ( bAddHeight )
      V.Z += MoverHeight;

   return V;
}

function bool MoverPathable(Mover Other)
{
   return Other.bBlockActors;
}

function Mover GetMover()
{
   local Mover m, cm;

   foreach AllActors(class'Mover', m, Tag)
      if ( MoverPathable(m) && (cm == None || ((m # cm) < 0)) )
         cm = m;

   return cm;
}

function Vector MoverLocWithOffs(Mover Other, optional byte MoverKey, optional bool bAddHeight)
{
   local Vector ML;

   ML = Other.KeyPos[MoverKey];

   return ML + Other.Location + FullOffs(bAddHeight);
}

function Vector MyMoverLocWithOffs(optional byte MoverKey, optional bool bAddHeight)
{
   local Vector ML;
   local Mover M;

   M = GetMover();
   ML = M.KeyPos[MoverKey];

   return ML + M.Location + FullOffs(bAddHeight);
}

function bool SurfaceWalkable(vector HitNormal)
{
   return abs(Rotator(HitNormal).Pitch) / 16384.0 < MaxWalkingPitch;
}

function bool TraceWalk(out Vector HitLoct, out Vector HitNorm, vector Start, float WalkDistance, float YawDeg) // helper function for other modders
{
   local Rotator FinalDir;
   local Vector DirOff;
   
   FinalDir.Yaw += YawDeg * 182.044444444444444444444444444;

   DirOff = Vector(FinalDir);
   DirOff *= WalkDistance;
   DirOff.Z -= WalkHeight * 2 + MoverHeight;

   return Trace(HitLoct, HitNorm, Start + DirOff, Start, false) != None;
}

function bool TraceWalk2(out Vector HitLoct, out Vector HitNorm, vector Start, float WalkDistance, float YawStep, optional int Steps)
{
   local Rotator FinalDir;
   local Vector DirOff;
   local bool b;

   if ( Steps == 0 )
      Steps = 8;
   
   FinalDir.Yaw = YawStep * (65536 / Steps);

   DirOff = Vector(FinalDir);
   DirOff.X *= WalkDistance;
   DirOff.Y *= WalkDistance;
   DirOff.Z -= WalkHeight * 2 + MoverHeight;

   b = Trace(HitLoct, HitNorm, Start + DirOff, Start, false) != None || !FastTrace(Start + DirOff, Start);
      
   CheckLog(Start@+@DirOff@=@Start + DirOff@o@FinalDir.Yaw@^@Rotator(HitNorm).Pitch@->@HitLoct@==@b);
   
   return b;
}   

function ProcessPath(Mover Other, KeyPath Path)
{
   local Vector InPos, OutPos, OutNrm, _, v1, v2;
   local LiftCenter LC;
   local LiftExit LE;
   local byte st;

   if ( bRetagMover )
      Other.Tag = Path.PathTag;

   InPos = MoverLocWithOffs(Other, Path.KeyBegin, true);

   LC = Spawn(class'AutoLiftCenter', self,, InPos);
   LogActor(LC);

   if ( LC == None )
      return;

   LC.LiftTag = Path.PathTag;
   LC.LiftTrigger = TriggerTag;
   LC.bHidden = !bDebug;

   for ( st = 0; st < ExitDirs; st++ )
   {
      InPos = MoverLocWithOffs(Other, Path.KeyBegin, false);

      if ( !TraceWalk2(OutPos, OutNrm, InPos, Path.InDistance, st, ExitDirs) )
         continue;
      
      v1 = OutPos;
      v1.z -= 24;

      v2 = OutPos;
      v2.z += WalkHeight;

      Trace(_, OutNrm, v1, v2, false);

      if ( !SurfaceWalkable(OutNrm) )
         continue;

      OutPos.Z += WalkHeight * 2 + class'AutoLiftExit'.default.CollisionHeight;

      LE = Spawn(class'AutoLiftExit', self,, OutPos);
      LogActor(LE);

      LE.LiftTag = Path.PathTag;
      LE.LiftTrigger = TriggerTag;
      LE.bHidden = !bDebug;
   }

   InPos = MoverLocWithOffs(Other, Path.KeyBegin + Path.KeyOffset, true);

   LC = Spawn(class'AutoLiftCenter', self,, InPos);
   LogActor(LC);

   if ( LC == None )
      return;

   LC.LiftTag = Path.PathTag;
   LC.LiftTrigger = TriggerTag;
   LC.bHidden = !bDebug;

   for ( st = 0; st < ExitDirs; st++ )
   {
      InPos = MoverLocWithOffs(Other, Path.KeyBegin + Path.KeyOffset, false);

      if ( !TraceWalk2(OutPos, OutNrm, InPos, Path.OutDistance, st, ExitDirs) )
         continue;

      
      v1 = OutPos;
      v1.z -= 24;

      v2 = OutPos;
      v2.z += WalkHeight;

      Trace(_, OutNrm, v1, v2, false);
      
      if ( !SurfaceWalkable(OutNrm) )
         continue;

      OutPos.Z += WalkHeight * 2 + class'AutoLiftExit'.default.CollisionHeight;

      LE = Spawn(class'AutoLiftExit', self,, OutPos);
      LogActor(LE);

      LE.LiftTag = Path.PathTag;
      LE.LiftTrigger = TriggerTag;
      LE.bHidden = !bDebug;
   }
}

function string LogActor(Actor Other)
{
   local string res;

   if ( Other == None )
      return "";

   res = "<"$Other.Class.Name@'$Other$"' at x="$Other.Location.X$",y="$Other.Location.Y$",z="$Other.Location.Z$">";

   CheckLog(res);

   return res;
}

function PathMover()
{
   local Mover MyMover;
   local int i;
   local KeyPath KP;

   MyMover = GetMover();
   
   for ( i = 0; i < NumPathes; i++ )
   {
      ProcessPath(MyMover, KeyPathes[i]);
   }
}

function PreBeginPlay()
{
   if ( GetMover() == None )
      return;

   PathMover();
}
Terrain apprentice.
User avatar
Gustavo6046
Inhuman
 
Posts: 771
Joined: Mon Jun 01, 2015 7:08 pm
Personal rank: Typing ghost

Re: MAJOR bot-pathing request

Postby sektor2111 » Mon Feb 06, 2017 7:48 am

Is not more simple to use Botz mutator already done ?
I don't see where do you add ReachSpecs and all that stuff for attaching them in Path-Net (- and good luck with bStatic things). I'm curious when you'll get them ready... At this moment in UT'99 by only using XC_Engine paths can be changed, without XC_Engine or other similar natives, this is just a GUESS heading nowhere, because dropping Navigation points will not link them using magic. I'm not asking how do you know differences between a door and a lift since nowadays doors are lifts and there are maps where lifts are moving like doors. Then, Bot has issues at Horizontal lifts.
Edit:I might go to prepare a small DM Demo map where a Mover is Door and Lift in the same time - and probably Map will be called DM-Modolif (aka Mover is Door and Lift) - a Mapping contest idea ? :ironic: .
User avatar
sektor2111
Godlike
 
Posts: 3825
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: MAJOR bot-pathing request

Postby Gustavo6046 » Mon Feb 06, 2017 10:15 pm

sektor2111 wrote:Is not more simple to use Botz mutator already done ?
I don't see where do you add ReachSpecs and all that stuff for attaching them in Path-Net (- and good luck with bStatic things).


Seems that my bots are capable of using the lifts with the nodes that are placed in PreBeginPlay. But I don't think the nodes are placed correctly since there are no starting LiftExits in the bottom :P
Terrain apprentice.
User avatar
Gustavo6046
Inhuman
 
Posts: 771
Joined: Mon Jun 01, 2015 7:08 pm
Personal rank: Typing ghost

Re: MAJOR bot-pathing request

Postby EvilGrins » Tue Feb 07, 2017 1:04 am

Gustavo6046 wrote:Seems that my bots are capable of using the lifts with the nodes

My bots use the vertical lifts going up fine, but they seem to prefer jumping over the side rather than take them down.

Admittedly I've been following their example. With all that water down there, it really is faster.

It's that sideways going ski-lift that's still the issue, though.
http://unreal-games.livejournal.com/
Image
medor wrote:Replace Skaarj with EvilGrins :mrgreen:
User avatar
EvilGrins
Godlike
 
Posts: 6147
Joined: Thu Jun 30, 2011 8:12 pm
Location: Palo Alto, CA
Personal rank: God of Fudge

Re: MAJOR bot-pathing request

Postby Gustavo6046 » Tue Feb 07, 2017 1:20 am

EvilGrins wrote:
Gustavo6046 wrote:Seems that my bots are capable of using the lifts with the nodes

My bots use the vertical lifts going up fine, but they seem to prefer jumping over the side rather than take them down.


I've heard that bots take only the vertical difference between their position and their destination LiftExit's position to jump, so the solution here would be to instead attach the LIftExit's in the end to a Mover, that is normally out of reach, and moves the LiftExit back into position only once the bot's lift is near the end.

P.S. When I talked about my bots capable of using the lifts I was talking about vertical maps with vertical lifts, in another topic, about automatic lift pathing. :P
Terrain apprentice.
User avatar
Gustavo6046
Inhuman
 
Posts: 771
Joined: Mon Jun 01, 2015 7:08 pm
Personal rank: Typing ghost

Re: MAJOR bot-pathing request

Postby sektor2111 » Tue Feb 07, 2017 7:35 am

EvilGrins wrote:My bots use the vertical lifts going up fine, but they seem to prefer jumping over the side rather than take them down.
Admittedly I've been following their example. With all that water down there, it really is faster.
Then read again here:
Higor wrote:PD: Added a small Jeronimo shortcut which becomes available once someone uses the lift at least once so bots don't get stuck waiting one after another.

HIGOR ADDED A DIRECT PATH in case you have failed my latest posts about those said "hyper-paths" - now there are solutions cute and handy for mapping things. Already described....
XC_PB.PNG
An Editor check never hurts.

That's the jump - in my old version they never jump because I did not use nothing, but later I added an extra-path there for doing the same thing, is water down there after all...

PS:That one from water is the node which I moved a bit because I see Bots hitting bridge many times and dying crushed. I have checked code from falling state, they might adjust fall to a nearest node, then after trying that far node they switch to a nearby one but they hit ground badly (at least this is what my Bots were doing - not all time but... hey !).

As for posts with "they did it" and loading 30+ Bots, that's not what I want - ALL Bots should be able to recover hunting status and not camping down in water and all of them traveling to ALL objectives not only 4 or 5 or 2 because of "faith".
User avatar
sektor2111
Godlike
 
Posts: 3825
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: MAJOR bot-pathing request

Postby EvilGrins » Tue Feb 07, 2017 8:59 am

If nobody minds me being just a little evil, at the start of this thread I linked 2 maps... both part of the same mission in Unreal1.

The 2nd link has basic pathing just for the very beginning area.

Anybody wanna take a shot at pathing the 2nd link?
http://unreal-games.livejournal.com/
Image
medor wrote:Replace Skaarj with EvilGrins :mrgreen:
User avatar
EvilGrins
Godlike
 
Posts: 6147
Joined: Thu Jun 30, 2011 8:12 pm
Location: Palo Alto, CA
Personal rank: God of Fudge

Re: MAJOR bot-pathing request

Postby sektor2111 » Tue Feb 07, 2017 5:28 pm

The same problem: LIFTS - not even a singe lift is pathed. This second one needs lifts pathed, waypoints set, probably triggers/movers corrections... but primary check must be done to see if DevPath is friendly, given map's load...
There is also a bridge having no single link. In old way Could be used a combo but since Lift Stuff is unknown even in version F I'm not expecting to see any wild tricky link, not even in old style of pathing. That's why Bot stay there in first path-net - yes, map is divided in multiple path-zones not a single path-net as it should be.
User avatar
sektor2111
Godlike
 
Posts: 3825
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: MAJOR bot-pathing request

Postby EvilGrins » Wed Mar 01, 2017 7:04 am

If this hasn't already been addressed:
Image

Where that blast mark is left of the door is a BSP-hole. If you get too close you fall in and die.

thought it was cool when monsters got stuck in it
Image


If that's not clear, it's the 1st castle you come to doing the map.
http://unreal-games.livejournal.com/
Image
medor wrote:Replace Skaarj with EvilGrins :mrgreen:
User avatar
EvilGrins
Godlike
 
Posts: 6147
Joined: Thu Jun 30, 2011 8:12 pm
Location: Palo Alto, CA
Personal rank: God of Fudge

Re: MAJOR bot-pathing request

Postby Higor » Wed Mar 01, 2017 8:01 pm

Just cluster a few BlockAll actors to simulate a wall.
Higor
Godlike
 
Posts: 1698
Joined: Sun Mar 04, 2012 6:47 pm

Re: MAJOR bot-pathing request

Postby sektor2111 » Wed Mar 01, 2017 8:23 pm

I think I solved that but I cannot be sure if other zone did not went screwed up, lol map.
User avatar
sektor2111
Godlike
 
Posts: 3825
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

PreviousNext

Return to General Discussions

Who is online

Users browsing this forum: No registered users and 3 guests