One of variables deciding movement it's called MoveTarget. This variable it's not exactly only a NavigationPoint, it can be an Actor from map.
If we are using a sort of code (called by me "push-code") we can setup a few conditions (no visible enemy, nothing as MoveTarget already set) and we can assign this variable in a small code (another sort of actor from map) causing state Roaming and MoveTarget to be accomplished. Bot will move there without to ask questions.
I know that it sounds like a myth and then I feel that I want to demonstrate what I'm talking about. This was a stupid duplicated map in two (maybe more names for the same map), having flipped textures. I wrapped things a bit and here it's my first attempt in making a map with Bot Support without paths - read well - no paths are heading to MonsterEnd... but other things... Monster Gaming Server if it's ON-Line demonstrates a working map without any patch plugin - freelancer Bots as goal. This actor does a check in certain range if a Bot which is not dead and having no enemy and not moving anywhere it will be oriented to some small non-colliding "knife" actor. Step by step each Bot which is accomplishing condition will move to said "knife" actor. These have a logic placement for not being moved in two directions but tracking a good knife to follow. We do have a few paths isolated created when map was build, but which are not connected properly up to the end of map, map being very poor in paths - year 2015 in stage when I used this strategy...
Actor was compiled with a proper MonsterHunt version - but can be compiled without MonsterHunt package loaded for preventing headaches granted by original MonsterHunt package v503.
For clarification you can delete all RadiusMove actors and see what's the deal in a temporary saved map.
Actor can be copied and compiled as follows:
Code: Select all
class RadiusMove expands Actor;
var() Int RadiusRange;
var() Float TimePush;
var() Name PointTag;
event PostBeginPlay()
{
if (RadiusRange < 50)
{
log (Self$" > Unable to react at your Shit Range. Increase Range!");
Destroy();
return;
}
SetTimer(TimePush,False);
}
event Timer()
{
local Bot B;
local Actor A;
if (Level.Game.bGameEnded)
{
Destroy();
return;
}
foreach RadiusActors (class 'Bot', B, RadiusRange)
{
if ( B != None && !B.bHidden )
{
if ( B.Health > 0 && B.Enemy == None && (B.MoveTarget == None || InventorySpot(B.MoveTarget) != None ) )
foreach AllActors (class 'Actor', A)
{
if ( A.Tag == PointTag && FastTrace(B.Location,A.Location))
{
B.MoveTimer = 1.00;
B.MoveTarget = A;
B.GotoState('Roaming','SpecialNavig');
B.TweenToRunning(0.1);
break;
}
}
}
}
SetTimer(TimePush,False);
}