MyLevels helping or bugging

Tutorials and discussions about Mapping - Introduce your own ones!
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

MyLevels helping or bugging

Post by sektor2111 »

As titled MyLevel might help lack of stuff or will bug people which cannot deal with such "toys".

Here Is a kind of selfie, I did a few small things for me when I did not loved A.I. in certain moments or when player can be hinted with direct images from level. Maybe you have seen such cams but... not very helped when 8 players were playing around.
Showing me the threat, objective or whatever - triggered, dispatched, etc.

Code: Select all

class CamView expands Triggers;

var Keypoint MyCam;
var() name CamTag;
var() float ViewTime;

event postbeginplay()
{
	local Keypoint K;

	if (CamTag == '')
	{
		log(Self$" report unconfigured SpectatorCam... Cya !");
		Destroy();
		return;
	}
	if (ViewTime <= 0.5) 
		ViewTime = 0.5;
	foreach AllActors (class 'Keypoint',K,CamTag )
	{
		if (K != None && K.IsA('SpectatorCam'))
		{
			MyCam = K;
			break;
		}
	}
}

singular event timer()
{
	local PlayerPawn Player;
	local Pawn P;

	for ( P=Level.PawnList; P!=None; P=P.nextPawn )
	{
		Player = Playerpawn(P);
		if ( Player != None )
		{
			Player.bFixedCamera = False;
			Player.ViewTarget = None;
			Player.bBehindView = false;
		}
	}
	Enable('Trigger');
}

event Trigger( Actor Other, Pawn EventInstigator )
{
	local PlayerPawn Player;
	local Pawn P;
	for ( P=Level.PawnList; P!=None; P=P.nextPawn )
	{
		Player = Playerpawn(P);
		if ( Player != None )
		{
			Player.ViewTarget = MyCam;
			Player.bBehindView = false;
			Player.bFixedCamera = True;
		}
	}
	SetTimer(ViewTime,False);
	Disable('Trigger');
}
defaultproperties
{
     bHidden=True
}
When gets triggered will point player to a default camera having tag mentioned, is about all player not only instigators counting 4 people.
Hint: Camera can be movable attached properly to an AttachMover.

A.I. stuff. A Bidirectional BlockedPath - blocking or unblocking path by triggering

Code: Select all

class PathSwitcher extends BlockedPath;

var() bool bInitialEnabled;

event PostBeginPlay()
{
	if (bInitialEnabled)
		Extracost = 100000000;
	else
		Extracost = 0;
}

function Trigger( actor Other, pawn EventInstigator )
{
	if ( ExtraCost > 0 )
		ExtraCost = 0;
	else
		ExtraCost = 100000000;
}

defaultproperties
{
     bInitialEnabled=True
}
When gets triggered will react properly.
Hint: You can implement lightning - Green = Free = Extracost = 0, Red = Blocked = Busy = Extracost 100000000.

Lost Bot - recover Navigation Networks after a previous nasty boost in wild area

Code: Select all

class NoLost extends Actor;

var() float Interval;
var() int RangeRun;

event PostBeginPlay()
{
	if ( Interval > 2.00 )
		SetTimer(Interval,True);
	else log (Self$" don't mock with settings, loser!");
}

singular event timer()
{
	local Bot aBotyMan;
	local NavigationPoint N, N1;
	local int BestPointDist;

	BestPointDist = RangeRun;
	foreach AllActors (class 'Bot', aBotyMan)
	{
		if ( aBotyMan != None && aBotyMan.Health > 0 )
		{
			if ( aBotyMan.Enemy == None && !NearbyNode(aBotyMan) )
			{
				if ( aBotyMan.MoveTarget == None )
				foreach aBotyMan.RadiusActors ( class 'NavigationPoint', N, RangeRun )
				{
					if ( N != None )
					{
						if (VSize(N.Location-aBotyMan.Location) <= BestPointDist && FastTrace(N.Location,aBotyMan.Location))
						{
							N1 = N;
							BestPointDist = Vsize(N.Location - aBotyMan.Location);
						}
					}
				}
				if ( N1 != None && aBotyMan.CanSee(N1))
				{
					aBotyMan.Target = N1;
					aBotyMan.RoamTarget = N1;
					aBotyMan.MoveTarget = N1;
					aBotyMan.bCamping = False;
					aBotyMan.TweenToRunning(0.1);
					aBotyMan.GotoState('Roaming','SpecialNavig');
				}
			}
		}
	}
}

function bool NearbyNode(Bot aBotyMan)
{
	local bool bIsNearby;
	local Pathnode P;

	bIsNearby = False;

	foreach aBotyMan.RadiusActors( class 'Pathnode', P , 710 )
	{
		if ( P != None && FastTrace(P.Location,aBotyMan.Location) )
		{
			bIsNearby = True;
			break;
		}
	}
	return bIsNearby;
}

defaultproperties
{
     Interval=3.800000
     RangeRun=2000
}
In given Interval you have time between such checks in order to not mess up constantly. In this configuration a Bot is checked each 3.8 seconds. If Bot can see a PathNode at 1700 UU (of course can see but is UnReachable) will run there as long as is doing nothing being lost if is at more than 710 UU from any Node. It can be modified as needed.
Hint: Normally should not be a problem in Water as long as default Bot turns into Swimming from running automatically, else except WaterZones - also you can fix Bot stuck in water due to physics bugs putting it into swim mode and pointing it to a Visible node.

"Moron" is not jumping near a ledge and run in place constantly. Simon says: Jump!

Code: Select all

class Bot_Jumper expands Triggers;

var() bool bOnceOnly, bEnabled;
var() class<Bot> LimitedToClass;
var Bot Pending;
var() float Frequency;
var() int JumpZ;

event Timer()
{
	Pending.SetPhysics(PHYS_Falling);
	Pending.Velocity = Pending.GroundSpeed * Vector(Rotation);
	if ( JumpZ != 0 )
		Pending.Velocity.Z = JumpZ;
	else
		Pending.Velocity.Z = FMax(200, Pending.JumpZ);
	Pending.DesiredRotation = Rotation;
	Pending.Acceleration = Vector(Rotation) * Pending.AccelRate;
	Pending.bJumpOffPawn = true;
	Pending.SetFall();
}

function Touch( actor Other )
{
	if ( bEnabled )
	if ( Other.IsA('Bot') 
			&& ((LimitedToClass == None) || (Other.Class == LimitedToClass)) )
	{
		Pending = Bot(Other);
		SetTimer(Frequency, false);
		if ( bOnceOnly )
		{
			Disable('Touch');
			Disable('Trigger');
		}
	}
}

function Trigger( actor Other, pawn EventInstigator )
{
	if ( bEnabled )
	{
		bEnabled = False;
		Disable('Touch');
	}
	else
	{
		bEnabled = True;
		Enable('Touch');
	}
}

defaultproperties
{
     bOnceOnly=False
     bDirectional=True
     JumpZ=324
     Frequency=0.1
}
Optional can be disabled when it doesn't need to work anymore, and it is a bDirectional one
Hint: Make it jump from a ramp when it needs to walk around for an enemy and turn it off when enemy died.

Simulated Fear

Code: Select all

class Bot_Runner expands Triggers;

var() bool bOnceOnly, bEnabled;
var() class<Bot> LimitedToClass;
var Bot Pending;
var() float Frequency;
var NavigationPoint MyPoint;
var() name PointTag;

event PostBeginPlay()
{
	FindMyPoint();
}

function FindMyPoint()
{
	local NavigationPoint N;

	if ( PointTag != '' )
	foreach RadiusActors(class'NavigationPoint',N,3000)
	{
		if ( N != None && N.Tag == PointTag )
		{
			MyPoint = N;
			break;
			log ("Point Set "$N);
		}
	}
}

singular event Timer()
{
	if ( MyPoint!=None && bEnabled && Pending.health > 0 )
	{
		Pending.Velocity = Pending.GroundSpeed * Vector(Rotation);
		if ( Level.Game.IsA('TeamGamePlus') )
			TeamGamePlus(Level.Game).FindSpecialAttractionFor(Pending)==False;
		Pending.MoveTarget = MyPoint;
		Pending.MoveTimer = 1.00;
		Pending.GotoState('Roaming', 'SpecialNavig');
	}
}

function Touch( actor Other )
{
	if ( bEnabled ) //for first usage active
	if ( Other.IsA('Bot') && ((LimitedToClass == None) || (Other.Class == LimitedToClass)) )
	{
		Pending = Bot(Other);
		SetTimer(Frequency, false);
		if ( bOnceOnly )
		{
			Disable('Touch');
			Disable('Trigger');
		}
	}
}

function Trigger( actor Other, pawn EventInstigator )
{
	if ( bEnabled )
	{
		Disable('Touch');
		bEnabled = False;
	}
	else
	{
		bEnabled = True;
		Enable('Touch');
	}
}

defaultproperties
{
     bEnabled=True
     bOnceOnly=False
     bDirectional=True
     Frequency=0.1
}
When Bot touch this thing will run to a NavigationPoint matching Tag configured. It might include "LastAttractCheck" if needs.
Hint: Combined with a crappy sound might return the feeling of a Bot scared running away.

Shoot that...

Code: Select all

class Bot_Hunter expands Triggers;

var() bool bOnceOnly, bEnabled;
var() class<Bot> LimitedToClass;
var Bot Pending;
var() float Frequency;
var Actor MyPoint;
var() name PointTag;

event PostBeginPlay()
{
	FindMyPoint();
}

function FindMyPoint()
{
	local Actor A;

	if ( PointTag != '' )
	foreach RadiusActors(class'Actor',A,700)
	{
		if ( A != None && A.Tag == PointTag )
		{
			MyPoint = A;
			break;
			log ("Point Set "$A);
		}
	}
}

event Timer()
{
	if ( MyPoint != None && bEnabled && Pending.health > 0 )
	{
		if ( Level.Game.IsA('TeamGamePlus') )
			TeamGamePlus(Level.Game).FindSpecialAttractionFor(Pending)==False;
		if ( MyPoint.bIsPawn )
		{
			Pending.DesiredRotation = Rotation;
			Pending.Velocity=Vect(0,0,0);
			Pending.Target=MyPoint;
			Pending.Enemy=Pawn(MyPoint);
			Pending.GotoState('RangedAttack');
		}
		else
		{
			Pending.DesiredRotation = Rotation;
			Pending.Velocity=Vect(0,0,0);
			Pending.Target=MyPoint;
			Pending.RoamTarget=MyPoint;
			Pending GotoState('Roaming','ShootDecoration');
/*
			Pending.bShootSpecial=True;
			Pending.FireWeapon();
			Pending.bFire = 0;
			Pending.bAltFire = 0;
*/
		}
	}
}

function Touch( actor Other )
{
	if ( bEnabled )
	if ( Other.IsA('Bot') && ((LimitedToClass == None) || (Other.Class == LimitedToClass)) )
	{
		Pending = Bot(Other);
		SetTimer(Frequency, false);
		if ( bOnceOnly )
		{
			Disable('Touch');
			Disable('Trigger');
		}
	}
}

function Trigger( actor Other, pawn EventInstigator )
{
	if ( bEnabled )
	{
		Disable('Touch');
		bEnabled = False;
	}
	else
	{
		bEnabled = True;
		Enable('Touch');
	}
}

defaultproperties
{
     bEnabled=True
     bOnceOnly=True
     bDirectional=True
     Frequency=0.1
}
It is addressing to a certain target that needs damage - MH doesn't include Assault stuff but we can have some clone -
Bot touching this thing will attack that if is pawn or will shot it if is other thing (there are 2 options in here).
Hint: Fire a decoration to spawn a better weapon, else kill a pawn FortStandard like.

Wait...

Code: Select all

class Bot_Pauser expands Triggers;

var() bool bOnceOnly, bEnabled;
var() class<Bot> LimitedToClass;
var Bot Pending;
var() float Frequency;

event Timer()
{
	Pending.SetPhysics(PHYS_Falling);
	Pending.MoveTarget = None;
	Pending.MoveTimer = -1.00;
	Pending.Acceleration = vect(0,0,0);
	Pending.Velocity = vect(0,0,0);
	Pending.SpecialPause = 1.00;
}

function Touch( actor Other )
{
	if ( bEnabled )
	if ( Other.IsA('Bot') 
			&& ((LimitedToClass == None) || (Other.Class == LimitedToClass)) )
	{
		Pending = Bot(Other);
		SetTimer(Frequency, false);
		if ( bOnceOnly )
		{
			Disable('Touch');
			Disable('Trigger');
		}
	}
}

function Trigger( actor Other, pawn EventInstigator )
{
	if ( bEnabled )
	{
		bEnabled = False;
		Disable('Touch');
	}
	else
	{
		bEnabled = True;
		Enable('Touch');
	}
}

defaultproperties
{
     bOnceOnly=False
     Frequency=0.1
}
If in a moment Bot jumps too far and fail to reach to target you might break it a bit to have a refresh. It simply looks like is taking a break to breath for a while.
Hint: If a previous Jumper makes it too jumpy just block it when it needs to avoid falling.

We can debate more as needed.

Edit:
FraGnBraG wrote: The camera "selfie" code - is this what they did in ONP?
It is not really ONP based on touchers (only 4 touchers holds UT), I was writing that code without Cut, without adds in HUD to spread errors, is based on Camera used into Assault and you can toy with ShowTime dispatching mission (specific to MH)
MH-Tomoko_vs_Sayuri_R14.zip
(1.33 MiB) Downloaded 94 times
Here is a redone of an initially Unsigned map, No Bot Support, no many playerstarts, nothing too interesting. I have set a few tiny custom things. If you try it with 3 Bots probably will run as supposed, it might work with many - is about FearSpot at begining. If touchers are filled up then the rest of team will be ignored - is more an experiment but is playable in living-room.
Content: Runner, Monster Teamer, Jumper, Camera, Bot Pathing, stuff added to balance difficulty, is a kind of work at home not very intended for highly loaded servers but you might have ideas from this one.

HuntNode:
How works ? It simply lock path if Bot encounter an enemy in purpose to not race like an idiot and to mind the enemy more properly. If doesn't have enemy will continue to move - recommended for MH v5.03 in order "Freelance", in the rest of fixed MH-s will work normally.

Code: Select all

class HuntNode expands PathNode;

var Bot PendingBot;

event int SpecialCost(Pawn Seeker)
{
	local Bot B;
	B = Bot(Seeker);
	if ( !Seeker.bIsPlayer ) //Monster Not allowed
		return 100000000;
	if ( B == None ) //Human support
		return 0;
	if ( B != None )
	{
		if ( B.Enemy == None )
			return 0; //No enemy = Move
		else
			return 100000000; //else see whatever habits
	}
	return 100000000;
}
To mention:
Previous Enhanced PathNode can be in MyLevel without to be abused. It is recommended around lasts Nodes to Waypoint blocking entire road if enemy is on sight. Else 12 Waypoints = 12 Nodes. It must be bSpecialCost = True (using Editor's Console). Mention no. 2 - I set default properties 46 height and 22 radius - smaller than common PathNode and it's able to link smaller places than usual PathNode (which might address Monsters too) and a thin Bot can use such paths correctly. I've been toying with such stuff and looks like works like a charm.
Last edited by sektor2111 on Mon May 04, 2015 11:49 pm, edited 4 times in total.
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: MyLevels helping or bugging

Post by Higor »

Additional mapping resources, while most have been designed with Siege in mind they're still extremely useful for most environments.

From the readme, I'll bold the most useful stuff:
Useful mapping resources to Siege and any other mod.
A small description about the insertable actors:
(Any actor not mentioned here shouldn't be added into a map)

There's also a few effect textures in it that might be of use.


--- (Info) SiegeMapInfo
Inserting this actor into a map and setting bRandomizeCores to True will
cause SiegeIV to make cores not appear in their preset order, useful for
randomizing the locations of teams in non symmetric maps.

--- (XC_NotifyActor) XC_BuildFilter
Contains various methods of preventing sgBuildings from being constructed at
certain BSP areas, check actor code for more details on filtering method.
It is recommended to use this as a 'bGlobalNotify=True'

--- (NavigationPoint) XC_CleanPath
Toggle BlockedPath.
If bIsBlocked is on, make sure you set a high ExtraCost as well.
Siege won't spawn RU crystals on these paths.

--- (Mover) XC_CoreAttacher.
This mover will attach any Siege core within 150 uu radius.
It will only try for 20 seconds, and will trigger an event after attaching.

--- XC_InventorySpawner.
Works in a TriggerToggle fashion.
If the item stays too long without being picked up, the spawner will
be able to spawn another one 2 seconds after the pickup.
This spawner will attach the item to an empty InventorySpot marker in a
100 unit radius if present.
Use this to spawn items in Siege, or spawn them in a UT3 fashion.

--- (XC_InventorySpawner) XC_ComplexSpawner
Will add objects randomly and at configurable rates.
Timer factor is the multiplier at which the timer counts down
so increasing it when the number of triggers increases makes the item respawn
a lot faster, making the spawner have a gradually progressive effect.
- Conditions block:
- GAME=gameclass
- ANYGAME=gameclass
If game class loads, then proceed to load item, if item has no DOT in string
then add the gameclass.Package name before the item string
ANYGAME performs wide search, looking for a word or expression in the game name

--- (Teleporter) XC_LinkedNavs.
Dummy collisionless teleporter
All it does is generate a forced connection between two nodes.

--- (Triggers) XC_LiftTrigger.
Trigger is enabled as long as it's lift isn't moving.
This variation doesn't send UnTrigger commands, meaning that movers must not
be used with TriggerControl state.
LiftTag is the associated lift, if bTriggerLift is on, then the lift will
receive a Trigger command on its own.
- bTriggerLift; //Trigger the lift directly (don't do actor search)
- MinDistance; //Don't function if distance below this
- MaxDistance; //Don't function if distance greater than this

--- (Triggers) XC_MultiTrigger_Control.
In order to push an event, all triggers pointing here must be enabled at the time.
Can disable an event given one of the trigger returns to untriggered.

--- (Triggers) XC_PulseCharger.
Pulse gun charger, this trigger needs the pulse gun's alt fire to charge it
Once charged, it will discharge and trigger an event.
It also includes a particle generator to indicate progress.

--- (Triggers) XC_sgB_Trigger.
Detects visible buildings in specified radius, team is optional.
- sgKeyword; //If building class has this string in it, it qualifies
- bToggleMechanics; //Call Trigger instead of UnTrigger on disable

--- (Trigger) XC_TeamTrigger.
Triggers only for the specified team
Continuous mode, ideal for TT_TriggerControl actors and big trigger spots.

--- (Kicker) XC_TargetedKicker.
Kick towards KickDest, using the Z velocity.

--- (Light) XC_TeamLight.
Picks a light hue based on team conditions.
EXCL_PowerNode and EXCL_Projectile are not functional.
- bReturnIfNull; //Return to index 4 if null
- bWhiteIfNull; //255 saturation if null

- XC_MusicController
- XC_PowerNode.
- XC_PowerNodeBase (Triggers).
- XC_NodeTeleporter (Teleporter).
- XC_TeamWall (Mover)
These are advanced actor, only attempt to use them if you manage to
understand the code.

--- XC_NotifyZone
This is a zone that will notify a set of handlers when something enters.
The handlers are the XC_NotifyActor derivates on said zone.

--- XC_NotifyActor.
This processes zone notifications (enter, exit).

--- (XC_NotifyActor) XC_LiftBuilds.
All Siege buildings in this zone will be attached to a lift below them

--- (XC_NotifyActor) XC_MeshFX_Attacher.
Always use this if you're using a core attacher, or a LiftBuilds notify.
Otherwise clients will see 3d models for buildings at erroneous positions.

--- (XC_NotifyActor) XC_PlayerAddVel.
Makes players and their translocators be pushed in a certain velocity
Attachments
XC_Siege_r3.u
(192.98 KiB) Downloaded 71 times
User avatar
FraGnBraG
Inhuman
Posts: 930
Joined: Sun Jun 13, 2010 5:13 pm
Personal rank: Good news everyone!
Location: Canada
Contact:

Re: MyLevels helping or bugging

Post by FraGnBraG »

@sektor2111 -

The camera "selfie" code - is this what they did in ONP?
You sometimes see these little cut-scenes just before a fight.. And do all players see these scenes (at the same time)?

I am wondering because I'm thinking a cutscene at the end of an MH match would be pretty cool if it could be done ;)
(like you can in Assault maps using EndCam dispatcher)
-=FraGnBraG Level Design=- ***UPDATED! even works on your phone!***
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: MyLevels helping or bugging

Post by sektor2111 »

FraGnBraG wrote:I am wondering because I'm thinking a cutscene at the end of an MH match would be pretty cool if it could be done ;)
(like you can in Assault maps using EndCam dispatcher)
Be my guest to copy things needed from here - it is a re-portation to MH matching Assault Part 1. Do not cry for Sniper with redeemer - Skaarj can use it in MH 5.04, for MH 5.03 is just default wacky original coding.
MH-Frigate_R14.zip
(1.05 MiB) Downloaded 89 times
It includes paths switching, custom cannons, MHFort, End Camera (no cut scene because I hate to mess up display problems).
Tell me what you think.
User avatar
FraGnBraG
Inhuman
Posts: 930
Joined: Sun Jun 13, 2010 5:13 pm
Personal rank: Good news everyone!
Location: Canada
Contact:

Re: MyLevels helping or bugging

Post by FraGnBraG »

Okay, I'll check this one out -- soon-ish....

Right now I am getting two large MH maps ready for early BETA...

These are large maps (filesize) larger than most:

1. MH-OrionsCurse(BETA) - 43.4 MB - moderate/high detail map - 3200+ brushes, 3000+ lights
Approx 30 objectives, 60 factories for 1500+ monsters
Uses the MH expansion pack that gives more monsters classes and more guns etc.
Status: Build is stable, last three boss battles at the end are currently malfunctioning
(MH triggering seems to stop working so you can't finish the match)
BOTs are also broken - pathes are way too long...

2. MH-TempleOfDragons(BETA) = 28.9 MB - moderate detail map - 3800+ brushes, 1500+ lights
Approx 25 objectives, ?? factories for ?? monsters - monsters are currently being determined.
Uses the MH expansion pack that gives more monsters classes and more guns etc.
Status: Build is stable, no bots yet, minimal monsters as of right now ...
BOT pathes will be a problem in this map due to length/complexity of the layout ..

I will open some threads for both of these very soon ...
-=FraGnBraG Level Design=- ***UPDATED! even works on your phone!***
Red_Fist
Godlike
Posts: 2166
Joined: Sun Oct 05, 2008 3:31 am

Re: MyLevels helping or bugging

Post by Red_Fist »

I been debating to put a cutseen in to see the Nali entering the factory. But for MH I think cutseens just T off the players. It has got to be quick, just not sure what to think about that. In SP I want cutseens.

all those things you made up there should have been built in the game, at least a few more useful actors for AI would have been nice.
Binary Space Partitioning
User avatar
FraGnBraG
Inhuman
Posts: 930
Joined: Sun Jun 13, 2010 5:13 pm
Personal rank: Good news everyone!
Location: Canada
Contact:

Re: MyLevels helping or bugging

Post by FraGnBraG »

FraGnBraG wrote: ... Okay, I'll check this one out -- soon-ish....
oops, sorry for pimping my projects here, sektor2111, i thought i was in my own thread ...
-=FraGnBraG Level Design=- ***UPDATED! even works on your phone!***
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: MyLevels helping or bugging

Post by sektor2111 »

FraGnBraG wrote:
FraGnBraG wrote: ... Okay, I'll check this one out -- soon-ish....
oops, sorry for pimping my projects here, sektor2111, i thought i was in my own thread ...
That's not a problem. And because we talk about some action into MH it will be better to take in account a few factors:
A SP episode in original was not ever done in a single Level having 200MB+ as now days people are doing with the same old engine. To gain functionality about everything it is recommended split in Levels using server-travel triggers (as long as default MH does not work). You can even quit idea to have a great level bigger than 10 MB because is a heavy job for this engine and certain things are going to lose timing.
Reconsider an important factor: monster when dies and triggers something will iterate a "foreach AllActors...". The job is more hard as more actors are added. Now imagine a scenario: You are firing rockets killing 4 pupaes.
1) Each pupae will foreach in order to hit a counter and factory if are spawned by a Factory;
2) MonsterHunt 5.03 will foreach immediately in ScoreKill to count Monsters;
3) If Bot is alive and "killed" gets called will attempt to keep moving foreach-ing for MonsterWayPoint;
4) If by chance you are using a mutator making other foreach-es then... Hey is still alive ???
YES, it might be alive but some doors are going to be rammed as happened in KrogaarSE in NitrogenSlith zone underwater. Such slow iterators make things nasty in giant Levels - these levels doesn't help at all.
I have hit my head when I was testing a hammer, why the heck I'm bleeding ? This how are acting such levels. Did I mention large rooms where weapons and everything are tracing a lot of points? No? My bad then... To summarize, a good level for UT'99 is not based on XX MB size on disk to not forget default engine "trigger" and "touching" which works for 4 Candidates. Yes, some default CoopGame was scanning for PlayerStart sorting from a list with 4 pieces. There things were chained using a perfect a logic, later, in UT'99 logic has been lost and went ahead with fixing engine in 2004, 0 mapping logic in 2008-2010 and -100 logic in 2014+. And that's all about "Levels" new computers fooling people about what can be done in UT'99. Touchers called doesn't match the numbers of CPU cores - are the same 4 touchers like many other things Engine related.

The competition 512k mapping was a perfect thing happening here. And not only perfect, it was a bless. Such job is for Unreal Engine. Of course in MH we don't need a Level finished in 5 minutes but neither in 2 days.
__________
Keep going to MyLeveling. These things presented by me using even timers are going to work nice if level has a decent size. Even I convinced Bot to load all weaponry from Level before to advance mission using a 3 custom PowerNodes which were simply stop freelancing to mission pointing Bot to weapons in range and allowing it to continue when the desired number of weapons has been achieved.
PowerNode

Code: Select all

class PowerNode expands PathNode;

var() int MinNumWep;
var() int RangeBlocked;
var() bool bLogMe;

event int SpecialCost(Pawn Seeker) //called if bSpecialCost = True
{
	local Bot B;
	local Inventory Inv;
	local int I;

	B = Bot(Seeker); //define a pawn seeker
	I = 0; //make sure about internal counter
	if ( !Seeker.bIsPlayer ) //Monster, eh... slow it down or block it
		return 1000; //Pick a value or leave it 0 if we are using patrols and alarms
	if ( B != None ) //If Have Bot
	{
		for( Inv=B.Inventory; Inv!=None; Inv=Inv.Inventory ) 
		{
			if ( Inv.IsA('Weapon') ) //check weapons owned by this pawn and if exist one
			{
				I++; //simply count it
			}
		}
		if ( I > MinNumWep || VSize(Location-B.Location) > RangeBlocked) //2 logic assets
		{ //if Number of weapons is bigger than desired OR Bot is far away out of our range
			if (bLogMe) //It is called almost each second or often depending on situation but helps while debugging
			{
				log (Self@"accepted"@B.GetHumanName());
				log (B.GetHumanName()@"has"@I@"weapons and accepted being at"@RangeBlocked@"UU away.");
			}
			return 0; //DON'T block path
		}
		else //Else if we are out of these 2 logic assets
		{
			if (bLogMe)
			{ //report rejection for debugging
				log (Self@"rejected"@B.GetHumanName());
				log (B.GetHumanName()@"has"@I@"weapons and rejected at"@RangeBlocked@"UU away.");
			}
			B.LastAttractCheck=Level.TimeSeconds; //try to set out a deal with game-core attraction
			return 100000000; //and BLOCK the path instantly - will mock for weapons nearby ONLY in range
		}
	}
	return 0; //Else is a free way for other seekers players
}

defaultproperties
{
   bSpecialCost=True
   MinNumWep=3
   RangeBlocked=1000
   bLogMe=False
}
bSPecialCost is not a property to be accessed directly so it can be done VIA console in Editor (or in PostBeginPlay ?). Current default configuration works as follows:
- Bot races to Waypoint as long as it has a path found;
- Bot enter in 1000 UU radius of this node - suddenly there is no path to Waypoint;
- while has weaponry desired under this 1000 radius will get some of them;
- if has 4 weapons (1 default enforcer + 1 retarded chainsaw + 2 others collected) Bot will suddenly find the path again moving, it is simply armed now;
- This can be repeated later for other additional 2 weapons placed nearby and which usually are not collected - Bot when roams around will look for stuff which is not collected yet.
Cons:
- Launching Bot in attack might lead in "run in place" in MH5.03 - freelance will solve problem much better;
- Mutators removing weaponry will develop 0 A.I. play - MH is not for Mutators, it is for hunting monsters;
- Mutators loading Bot with all weapons will help Bot racing.
Hints: It can be developed to work for some range while some Boss is not dead by blocking next node out of room and releasing path after monster's death keeping Bot in combat.
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: MyLevels helping or bugging

Post by Higor »

That PowerNode's gonna be slow as hell as you increase node/bot count, in a factor of (bot * nodes).
Might as well recode the Bot attacker AI in MH to allow weapon picking periods the same way FerBotz does, this way you get bots to perfectly coordinate when to grab stuff and when to push forward together and it would work for all maps.

PD: Native FerBotz lets you path maps with broken/inexistent pathing, as long as you keep the mutator loaded (0 botz) it will help monsters AND normal bots as well.
PD2: Submit the .botz path files if you use that feature, they'll definetely go in the next release.

The code below is the botz plugin for MonsterHunt, ignore the botz specific code and focus on the state/wave counters and directives.
It will also send botz towards big fat monsters if there's no path to waypoint.
It's a mix of new and ancient code, so some things might not make sense at all, slow or simply be in another language.
EDIT: Will account for XC_GameEngine's monster targeting, so forcing Enemy is disabled as well if detected!

Code: Select all

//=============================================================================
// MonsterHuntUBZSupport.
//=============================================================================
class MonsterHuntUBZSupport expands BotzTargetAdder;

var MonsterWaypoint WPList[64]; //lo ampliare solo si veo pantallas excesivamente grandes
var int CurrentWP;
var MonsterEnd WPEnd;
var int AtWaveCounter, ForceCounter;
var bool bTrue;
var bool bInit;
var bool bNoMonsterCheck; //UnrealShare.SetEnemy targets bots, XC_GameEngine patch
var ScriptedPawn CachedMonster;
var Object TestObj;

function name InitialOrders( Botz CheckFor)
{
	return 'Attack';
}

function name ModifyState( Botz CheckFor)
{
	if ( CheckFor.Orders == 'Defend' || CheckFor.Orders == 'FreeLance' )
		return 'Attacking';
}

//Wait one second for this, allow map plugin to create new MonsterWaypoints if necessary
function InitPoints()
{
	local int i, j;
	local MonsterWaypoint WPSearch;
	local bool SortedAlready, dagun;

	ForEach AllActors (class'MonsterHunt.MonsterWaypoint', WPSearch)
	{
		WPList[i] = WPSearch;
		i++;
	}
	WPSearch = none;
	dagun = false;
	CurrentWP = 0;
	AtWaveCounter = 0;

	//Sort
	While (!SortedAlready)
	{
		dagun = true;

		For ( j=0 ; j<i ; j++ )
			if ( (WPList[j] != none) && (WPList[j+1] != none) && (WPList[j].Position > WPList[j+1].Position) )
			{
				WPSearch = WPList[j];
				WPList[j] = WPList[j+1];
				WPList[j+1] = WPSearch;
				WPSearch = none;
				dagun = false;
			}

		if ( dagun )
			SortedAlready = True;

	}

	ForEach AllActors (class'MonsterHunt.MonsterEnd', WPEnd)
		break;

	Log("Detectados:"@string(i)@"Waypoints,"@string(WPEnd)@"como End");
	For ( j=0 ; j<i ; j++ )
		Log("====> Waypoint"@string(j)@"="@string(WPList[j]) );
	bInit = true;
}

event PostBeginPlay()
{
	SetTimer( 1.0, true);
	SetPropertyText( "TestObj", XLevel.GetPropertyText("Engine") );
	if ( (TestObj != none) && TestObj.IsA('XC_GameEngine') && (TestObj.GetPropertyText("bSetEnemy") == GetPropertyText("bTrue")) )
	{
		bNoMonsterCheck = true;
		TestObj = none;
		Log("XC_GameEngine detectado", 'FerBotz');
	}
}

event Timer()
{
	if ( !bInit )
		InitPoints();

	AtWaveCounter++;  //En ciclos de 15 segundos, se cumplen varios comportamientos generalizados
	if ( AtWaveCounter > 15 )
		AtWaveCounter = 0;

	if ( ForceCounter > 0 )
		AtWaveCounter = ForceCounter;

	if ( WPList[CurrentWP] == none )
		return;
	if (CurrentWP >= 64)
	{	CurrentWP = 0;
		WPList[0] = none;
		Log("Alcanzada etapa de MonsterEnd");
		return;
	}

	if ( WPList[CurrentWP].bVisited )
	{
		CurrentWP++;
		Log("Nuevo punto a atacar");
	}
}

// CICLOS DE ATAQUE
//Ciclos 0 - 1, restock masivo
//Ciclos 2 - 7, restock decremental, precaucion de 3 a 0.5, salados esperan y protegen
//Ciclos 8 - 15, ataque seguro
function actor SuggestAttack( Botz CheckFor, optional bool bOnlyTest)
{
	local actor Nager;
	local float Gagardi;
	local PlayerPawn HumanPlayer;

	Gagardi = fClamp(abs(AtWaveCounter - 7), 0, 7) * 0.5;
	CheckFor.Precaucion = Gagardi;
	Nager = SendToAttackPoint( CheckFor, Gagardi * FRand() < 0.7);
	if ( bOnlyTest )
		return Nager;

	if ( Nager == self )
	{
		CheckFor.ForceState = 'Attacking';
		CheckFor.ForceLabel = 'Wait';
	}
	else if ( MonsterEnd(Nager) != none )
	{
		CheckFor.CostJumpSpots(false);
		if ( CheckFor.FindPathToward(Nager) == none )
			Nager = PickStrongMonster( CheckFor);
		CheckFor.CostJumpSpots(true);
	}
	else if ( Nager == none )
	{
		Nager = PickStrongMonster( CheckFor);
	}
	else if ( MonsterWaypoint(Nager) != none )
	{
		Gagardi = CheckFor.HSize( CheckFor.Location - Nager.Location);
		Gagardi = Gagardi - (CheckFor.CollisionRadius + Nager.CollisionRadius);
		if ( (Gagardi < 0) && CheckFor.FastTrace(Nager.Location) )
		{
			BotzTouchedWP(CheckFor, MonsterWaypoint(Nager));
			CheckFor.SendTeamMessage(None, 'OTHER', 16, 15);
			Timer();
			return none;
		}
		return Nager;
	}

	return Nager;
}


function actor OldItemOfInterest( botz Interested)
{// Ignorar interes si el bot tiene un movetarget definido durante PickLocalInventory()
	local actor Nager;
	local float Gagardi;
	local PlayerPawn HumanPlayer;

	if ( Interested.SavedState != 'Attacking' )
		Interested.Precaucion = 0.7;

	if ( !bNoMonsterCheck )
		MonstersCheck( Interested);

	return none;
}

function ScriptedPawn PickStrongMonster( botz CheckFor)
{
	local ScriptedPawn S;
	local float aDist;

	CheckFor.CostJumpSpots( false);

	if ( CachedMonster != none && !CachedMonster.bDeleteMe && (CheckFor.FindPathToward(CachedMonster) != none) )
	{
		CheckFor.CostJumpSpots( true);
		return CachedMonster;
	}

	CachedMonster = none;
	aDist = 99999;

	ForEach AllActors (class'ScriptedPawn', S)
	{
		if ( (S.Health > 700) && ValidNear(CheckFor,S,aDist) && CheckFor.SetEnemy(S, true) && CheckFor.FindPathToward(S) != none )
		{
			CachedMonster = S;
			aDist = VSize(CheckFor.Location - S.Location);
			break;
		}
	}
	CheckFor.CostJumpSpots( false);
	return CachedMonster;
}

function bool ValidNear( actor A, actor B, float CloserThan)
{
	return VSize(A.Location - B.Location) < CloserThan;
}

function MonstersCheck( pawn Victim)
{
	local scriptedpawn S;

	if ( Victim.Enemy != none )
	{
		if ( FRand() < 0.2 )
			return;
		else if ( Victim.Enemy.Enemy == Victim )
			return;
	}
	

	ForEach VisibleCollidingActors( class'ScriptedPawn', S, 2500, Victim.Location)
	{
		if ( S.CanSee(Victim) )
			if ( ((S.Enemy == None) || (S.Enemy.IsA('PlayerPawn') && (FRand() >= 0.50)) || (S.Enemy.IsA('Bot') && (FRand() >= 0.05))) && (S.Health >= 1) )
			{
				S.Hated=Victim;
				S.Enemy=Victim;
				if ( Victim.Enemy == none )
					Victim.Enemy=S;
				S.GotoState('Attacking');
			}
	}
}

function actor SendToAttackPoint( botz Attacker, bool bWaitForBackup )
{
	local PlayerPawn HumanPlayer;
	local Pawn aPawn;
	local bool Gandar;
	local actor Gedar;

	if ( bWaitForBackup )
	{
		Gandar = True;
		ForEach Attacker.VisibleCollidingActors (class'Pawn', aPawn, 450)
			if ( aPawn.bIsPlayer && (aPawn.Health > 0) )
			{	Gandar = False; break;
			}
		if ( Gandar )
			return self;
	}


	if ( WPList[CurrentWP] != none )
		Gedar = WPList[CurrentWP];
	else if ( WPEnd != none )
		Gedar = WPEnd;


	return Gedar;
}


function BotzTouchedWP( botz Other, MonsterWaypoint TheWP)
{
	if ( !TheWP.bVisited && TheWP.bEnabled )
	{
		if ( TheWP.TriggerActor1 != None )
		{
			if ( TheWP.TriggerActor1.IsA('Mover') )
			{
				TheWP.TriggerActor1.Bump(Other);
			}
			TheWP.TriggerActor1.Trigger(TheWP, Other);
		}
		if ( TheWP.TriggerActor2 != None )
		{
			if ( TheWP.TriggerActor2.IsA('Mover') )
			{
				TheWP.TriggerActor2.Bump(Other);
			}
			TheWP.TriggerActor2.Trigger( TheWP, Other );
		}
		if ( TheWP.TriggerActor3 != None )
		{
			if ( TheWP.TriggerActor3.IsA('Mover') )
			{
				TheWP.TriggerActor3.Bump(Other);
			}
			TheWP.TriggerActor3.Trigger( TheWP ,Other);
		}
		if ( TheWP.TriggerActor4 != None )
		{
			if ( TheWP.TriggerActor4.IsA('Mover') )
			{
				TheWP.TriggerActor4.Bump(Other);
			}
			TheWP.TriggerActor4.Trigger( TheWP , Other );
		}
		if ( TheWP.TriggerItem != None )
		{
			if ( TheWP.TriggerItem.IsA('Mover') )
			{
				TheWP.TriggerItem.Bump(Other);
			}
			TheWP.TriggerItem.Trigger( TheWP , Other );
		}
		MonsterHunt(Level.Game).LastPoint=TheWP.Position;
		TheWP.bVisited=True;
		TheWP.bEnabled=False;
	}

}
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: MyLevels helping or bugging

Post by sektor2111 »

Higor wrote:That PowerNode's gonna be slow as hell as you increase node/bot count, in a factor of (bot * nodes).
I'm totally agree with you but...:
- I'm using only 3 Nodes in a map which is not 50 MB+;
- I did an update even using a Pawnlist (Releasing path if monsters = 0 - No longer need weapons, right? ) still runs smoother;
- For maps having 5000 Actors probably more mutators are going to ruin game so I won't cry and neither to override 1000 paths
- I'm using log to see how often gets called and... for sure not 100 Bots.

Don't forget to wrap Waypoint touching, it doesn't need to break touching order as it does 5.03, heh.
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: MyLevels helping or bugging

Post by Higor »

For some reason every single coder goes with:
IsA('PlayerPawn') || IsA('Bot')

Instead of:
bIsPlayer && (PlayerReplicationInfo != none) && !PlayerReplicationInfo.bIsSpectator

When they want to do player checks, causing monster waypoints not support any generic 'player' pawn UNLIKE ASSAULT FORTS DO.
If you can fix that for MH please do it.
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: MyLevels helping or bugging

Post by sektor2111 »

If we talk about MonsterWaypoint earlier triggered Let's see Original touch

Code: Select all

function Touch( actor Other )
{
	if ( !bVisited && bEnabled && ( Other.IsA('PlayerPawn') || Other.IsA('Bot') ) )
	{
		if ((TriggerActor1 != None) && Other.IsA('Bot'))
		{
			if (TriggerActor1.IsA('Mover'))
				TriggerActor1.Bump(Other);
			TriggerActor1.Trigger(Self, Pawn(Other));
		}
		if ((TriggerActor2 != None) && Other.IsA('Bot'))
		{
			if (TriggerActor2.IsA('Mover'))
				TriggerActor2.Bump(Other);
			TriggerActor2.Trigger(Self, Pawn(Other));
		}
		if ((TriggerActor3 != None) && Other.IsA('Bot'))
		{
			if (TriggerActor3.IsA('Mover'))
				TriggerActor3.Bump(Other);
			TriggerActor3.Trigger(Self, Pawn(Other));
		}
		if ((TriggerActor4 != None) && Other.IsA('Bot'))
		{
			if (TriggerActor4.IsA('Mover'))
				TriggerActor4.Bump(Other);
			TriggerActor4.Trigger(Self, Pawn(Other));
		}
		if ((TriggerItem != None) && Other.IsA('Bot'))
		{
			if (TriggerItem.IsA('Mover'))
				TriggerItem.Bump(Other);
			TriggerItem.Trigger(Self, Pawn(Other));
		}
		MonsterHunt(Level.Game).LastPoint = Position;
		bVisited = True;
		bEnabled = False;
	}
}
My whinning: //getting mad turned on
WHY Was a need to be used two values and why we can touch Position 4 before Position 3 ? BOT has a touch problem and that's why was worked like this but... Incomplete
//getting mad turned off - Cut of whinning - because MH 5.04 is more interesting with this chapter

Code: Select all

function Touch( actor Other )
{
	if ( !bVisited && bEnabled && ( Other.IsA('PlayerPawn') || (Other.IsA('Bot') && Bot(Other).Enemy == None ) ) ) //restrict racing dumbness
	{
		if ( MonsterHunt(Level.Game).LastPoint + 1 == Position ) //Extreme rule - No more bullshit happening earlier
		{
			if ((TriggerActor1 != None) && Other.IsA('Bot'))
			{
				if (TriggerActor1.IsA('Mover'))
					TriggerActor1.Bump(Other);
				TriggerActor1.Trigger(Self, Pawn(Other));
			}
			if ((TriggerActor2 != None) && Other.IsA('Bot'))
			{
				if (TriggerActor2.IsA('Mover'))
					TriggerActor2.Bump(Other);
				TriggerActor2.Trigger(Self, Pawn(Other));
			}
			if ((TriggerActor3 != None) && Other.IsA('Bot'))
			{
				if (TriggerActor3.IsA('Mover'))
					TriggerActor3.Bump(Other);
				TriggerActor3.Trigger(Self, Pawn(Other));
			}
			if ((TriggerActor4 != None) && Other.IsA('Bot'))
			{
				if (TriggerActor4.IsA('Mover'))
					TriggerActor4.Bump(Other);
				TriggerActor4.Trigger(Self, Pawn(Other));
			}
			if ((TriggerItem != None) && Other.IsA('Bot'))
			{
				if (TriggerItem.IsA('Mover'))
					TriggerItem.Bump(Other);
				TriggerItem.Trigger(Self, Pawn(Other));
			}
			MonsterHunt(Level.Game).LastPoint = Position;
			MonsterHunt(Level.Game).MHTarget = None; //We have a stable defined target against constant foreaching and now it is time for next sorted
			MonsterHunt(Level.Game).PointToTarget = None; //No navigation helper because we wait to get next one
			bVisited = True; //1) value
			bEnabled = False; //2) Second crap useless
			if ( MonsterHunt(Level.Game).bDumbDown ) //ADDON - no worry it doesn't include Accessed Nones
			{
				if ( Other.IsA('Bot'))
					Bot(Other).SendTeamMessage(None, 'OTHER', 11, 15);
				BroadcastMessage("Position"@Position@"has been visited."); //We know where we need to keep moving
			}
		}
	}
}
You are my guest to do 5.05 if you want to debate all player (probably MR. Titan Too !) - YEAH, people calls this modding, and if fact is just a mess to cry for MH bugs:
- ScriptedPawn is not hunter;
- MonsterMadness doesn't include new stupid hunters - is trash stuff even known by Shrimp and the man put something cool which I did not removed he, he...
- Bots - well is not Bot, is Bots (those ugly faces and losers as hell) - I cannot detect their attraction code, they can hunt only guided by enhanced Navigation - I'm doubt about a common mapper to handle this part.
- SkaarjPlayerBot - well...
- NPC type Alice touching my WayPoints ? - Oops I forgot to clamp touching at team 0 ? - my bad. :loool:

I did not removed those 2 values (if some mutator deals with them will make things nasty). Else I can do anytime a MH able to deal generally with pawns. By example Monsters will attack all player non-monster - including Monster-Player. I have such a controler into a custom DM. Monsters simply attack everything which moves - but breaking rules was not in purpose.

The rest of Scorekill, ReduceDamage, Killed, probably are supporting some "hunters", but not mission completed by a MONSTER, LOL.

OTHER pawns aren't really in my sight as long as I did not see one error-free else I could debate a more advanced support.
So to speak, even a MH2 can debate attaching new WayPoints able to handle an attached external MH mod. It works. You can reconsider spawning some personal stuff BOTZ related (Not very KeyPoints) which are going to be cool in MH.

See? That's why I'm not making Pawns I'm making ScriptedPawn and Bot. Almost All AIRating stuff and special handling is granted to Bot, JumpSpot is Bot specific feature, eh you know what I mean... Other pawn just makes the life harder to live for mapping...

And to complete the -200 logic stuff possible for next years I have a proposal for some pawn makers: Doing some FlockPawns, FlockMasterPawns, XPawns, Cannons, FortStandard as Bots and keep asking why monsters ignores them, LOL. But it will be called Development. And will be amazing to see people laughing at garbage and during this time I'll setup stuff to make stock things functional.

In December 15 2014 I was almost to do a check for "cool" pawns at let's say each 10 seconds, and if some "creature" would crawl MH and is not a stock one, in purpose to destroy it. But I was quitting idea because people love crashes and stuff, so it wasn't in purpose ruining their fun. But in my MH2 rules are mine.

Tech part:
A MH5.04_lite might increase chances to have... action. ScriptedPawn will be almighty enemy attacking everything. Then I wanna see complains.
Last edited by sektor2111 on Tue Feb 17, 2015 7:19 pm, edited 1 time in total.
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: MyLevels helping or bugging

Post by Higor »

It just annoys me that there's two code instances by things that interact with both players and AI, the JumpSpot thing is justified as players don't use it but scoreboards (SmartCTF), MH waypoints, and a load of other things.
FortStandards count all player types, default Scoreboard takes all player types, team cannons attack all enemy player types and I can keep going... thing is, those things worked with Botz right from the beginning and some mods didn't mainly because of the lazy IsA checks.

If something is broken by design, rewrite it.
Done that on Siege in multiple occasions and it's paid off greatly, and will do so on XCGE soonish given the v451 fiasco.
User avatar
Wises
Godlike
Posts: 1089
Joined: Sun Sep 07, 2008 10:59 am
Personal rank: ...

Re: MyLevels helping or bugging

Post by Wises »

Higor wrote:For some reason every single coder goes with:
IsA('PlayerPawn') || IsA('Bot')

Instead of:
bIsPlayer && (PlayerReplicationInfo != none) && !PlayerReplicationInfo.bIsSpectator

When they want to do player checks, causing monster waypoints not support any generic 'player' pawn UNLIKE ASSAULT FORTS DO.
If you can fix that for MH please do it.
I see what you are saying.. should maybe make that ^ your Sig so that everyone gets the point .
problem is... I assume that this lazy code was passed down through the wiki Gods and worked for the purpose (humans & bots) excluding monsters° ehem.

perhaps someone just patch these "popular mods" as it sounds fairly simple to do.

decompile > append fix > rename > recompile ver.xx ?

and most are not obfuscated as well.
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: MyLevels helping or bugging

Post by sektor2111 »

Higor wrote:team cannons attack all enemy player types and I can keep going...
There... you are the right guy for explanations. SeenPlayer gets called for pawn bIsPlayer that's why sometimes Skaarj attack themselves (speaking about that timer problem where they fail weapons) as long as default SetEnemy won't ever except ScriptedPawns.

I can except those timer problems because I know in big parts what's the problem with Skaarj and I can spawn an A.I. Karma making monsters more intensive and quitting Bot related attraction load.

Now I was writing a new counter, looks fine at this moment but I wanna see what it might break...
Post Reply