Stupid Thing_Factory

Discussions about Coding and Scripting
Post Reply
Red_Fist
Godlike
Posts: 2163
Joined: Sun Oct 05, 2008 3:31 am

Stupid Thing_Factory

Post by Red_Fist »

Man that thing really tees me off I wish someone could do a final fix-version once and for all.

OK, stand on mover using trigger control.

Thing factory spawns stuff

Get off of mover ThingFactory stops spawning.

Get on mover, thing factory starts again.

I want a mover event-bump event to be able to do the same function as touch-untouch.

Here is the code for Unreal2 if it helps.

Code: Select all

/=============================================================================
// ActorFactory.uc
// $Author: Mfox $
// $Date: 12/04/02 4:25p $
// $Revision: 17 $
//=============================================================================
class ActorFactory extends Keypoint;

enum EDistribution
{
	DIST_Constant,
	DIST_Uniform,
	DIST_Gaussian
};

var() class<Actor> Prototype; 				// the template class
var() int MaxItems;							// max number of items from this factory at any time
var() int Capacity;							// max number of items ever buildable (-1 = no limit)
var() float Interval;						// average time interval between spawnings
var() name ItemTag;							// tag given to items produced at this factory
var() name DepletedEvent;					// event to trigger when factory has been depleted

var() bool bTouchEnabled;					// (true) if false, factory not triggered via touch
var() bool bTriggerManually;				// spawn maxitems when triggered and then go back to waiting
var() bool bNonPrototypeTriggerShutdown;	// trigger from anything but spawned type shuts down the factory
var() bool bNonPrototypeTriggerKillAll;		// trigger from anything but spawned type kills all the spawned objects
var() EDistribution TimeDistribution;		// randomisation of time interval

var() bool bOnlyPlayerTouched; 				// only player can trigger it
var() bool bCovert;							// only do hidden spawns
var() bool bStoppable;						// stops producing when untouched
var() bool bCanRestart;						// if true factory will restock itself when empty and can be triggered again
var() bool bCycleSpawnPoints;				// if true, tries to use each spawn point in order (instead of randomly)
var() int FlipCovertCount;					// after this many NPCs are spawned, flips the covertness of the factory (permanently)

var private int NumSpawnPoints;				// number of spawnspots
var private int NumSpawnedItems;			// current number of items from this factory
var private SpawnPoint SpawnSpots[16];	 	// possible start locations
var private int NextSpawnPoint;				// next spawn point to use if bCycleSpawnPoints
var int InitialCapacity;

//-----------------------------------------------------------------------------

event PostBeginPlay()
{
	local SpawnPoint NewSpot;
	local Actor A;
	
	Super.PostBeginPlay();
	
	// count and store spawn points
	NumSpawnPoints = 0;
	foreach AllActors( class'SpawnPoint', NewSpot, tag )
	{
		if( NumSpawnPoints < 16 )
		{
			SpawnSpots[NumSpawnPoints] = NewSpot;
			NewSpot.Factory = Self;
			NumSpawnPoints += 1;
		}
	}

	if( NumSpawnPoints == 0 )
	{
		warn( Self $ " has no spawn points!" );
	}
	
	// count pre-existing matching items (item event = factory tag)
	NumSpawnedItems = 0;
	foreach AllActors( Prototype, A, tag )
	{
		NumSpawnedItems++;
	}
	
	if( ItemTag == '' )
	{
		ItemTag = 'BallPiensRock';
	}

	if( Capacity > 0 )
		InitialCapacity = Capacity;   // save initial capacity so that we can reset the factory later
}	

//-----------------------------------------------------------------------------

function SpawnPoint GetSpawnSpot( int Index )
{
	if( Index >= 0 && Index<NumSpawnPoints )
		return SpawnSpots[ Index ];
	else
		return None;
}

//-----------------------------------------------------------------------------

function StartBuilding()
{
}

//-----------------------------------------------------------------------------

function KillAll()
{
	local int i;

	for( i=0; i < ArrayCount(SpawnSpots); i++ )
	{
		if( SpawnSpots[i] != None )
			SpawnSpots[i].DestroyAllSpawnees();
	}
	NumSpawnedItems = 0;
}


//-----------------------------------------------------------------------------

function bool HandleSpawneeDeath( Actor Other )
{
	local Pawn P;

	P = Pawn(Other);

	// Spawned pawn has died (actor deaths don't trigger events)
	if( P != None && P.class == Prototype && P.Health <= 0 )
	{
		NumSpawnedItems--;
		return true;
	}
	return false;
}

//-----------------------------------------------------------------------------

auto state Waiting
{
	function Trigger( Actor Other, Pawn EventInstigator, optional name EventName )
	{
		if( !HandleSpawneeDeath( Other ) )
		{
			// Factory has been triggered, start spawning
			TriggerEvent( Event, Other, EventInstigator );
			GotoState( 'Spawning' );
		}
	}
		
	event Touch( Actor Other )
	{
		local Pawn OtherPawn;

		if( bTouchEnabled )
		{	
			OtherPawn = Pawn(Other);
			if( OtherPawn != None && (!bOnlyPlayerTouched || OtherPawn.IsPlayer()) )
				Trigger( Other, otherPawn );
		}
	}
}

//-----------------------------------------------------------------------------

state Spawning
{
	// Disabled in BeginState if !bStoppable
	event UnTouch( Actor Other )
	{
		local Pawn P;

		if( bTouchEnabled )
		{
			// check if some other pawn still touching, ignore the untouching actor and dead stuff
			foreach TouchingActors( class'Pawn', P )
				if( P != Other && P.Health > 0 && (!bOnlyPlayerTouched || P.IsPlayer()) )
					return;

			GotoState( 'Waiting' );
		}
	}

	function Trigger( Actor Other, Pawn EventInstigator, optional name EventName )
	{
		local int i;

		if( bTriggerManually )
			return;
		else if( HandleSpawneeDeath( Other ) )
		{
			if( NumSpawnedItems < MaxItems )
				StartBuilding();
		}
		else
		{
			// trigger from anything but creatures belonging to 
			// this factory shuts down the factory
			if( bNonPrototypeTriggerKillAll )
			{
				KillAll();
			}

			if( bCanRestart )
			{
				Capacity = InitialCapacity;
				GotoState( 'Waiting' );
			}
			else if( bNonPrototypeTriggerShutdown )
			{
				GotoState( 'Finished' );
			}
			else
			{
				GotoState( 'Waiting' );
			}
		}
	}

	function bool TrySpawn( int Start, int End )
	{
		local int i;
		local bool bDone;

		bDone = false;
		i = Start;
		while( i < End )
		{
			if( SpawnSpots[i].Create() )
			{
				bDone = true;
				i = End;
				if( Capacity > 0 )
				{
					Capacity--;
				}
					
				NumSpawnedItems++;
				
				if( FlipCovertCount > 0 && NumSpawnedItems == FlipCovertCount )
				{
					bCovert = !bCovert;
					FlipCovertCount = 0;
				}
				
				if( Capacity == 0 )
					GotoState( 'Finished' );
			}
			i++;
		}
		
		return bDone;
	}
		
	event Timer()
	{
		local int Start;
		
		if( NumSpawnedItems < MaxItems )
		{
			//pick a spawn point
			if( bCycleSpawnPoints )
			{
				Start = NextSpawnPoint;
				NextSpawnPoint++;
				if( NextSpawnPoint >= NumSpawnPoints )
					NextSpawnPoint = 0;
			}
			else
				Start = Rand( NumSpawnPoints );
				
			if( !TrySpawn( Start, NumSpawnPoints ) )
				TrySpawn( 0, Start );
				
			StartBuilding();
		}
		else if( bTriggerManually )
		{
			// forget about the spawned items
			// wait to be manually triggered again
			NumSpawnedItems = 0;
			GotoState('Waiting');
		}
	}

	function StartBuilding()
	{
		local float NextTime;
		
		if( Capacity == -1 || Capacity > 0 )
		{
			if( TimeDistribution == DIST_Constant )
			{
				NextTime = Interval;
			}
			else if( TimeDistribution == DIST_Uniform )
			{
				NextTime = 2 * FRand() * Interval;
			}
			else //TimeDistribution is gaussian
			{
				NextTime = 0.5 * (FRand() + FRand() + FRand() + FRand()) * Interval;
			}
			
			SetTimer( NextTime, false );
		}
	}

	event BeginState()
	{
		if( !bStoppable )
		{
			Disable( 'UnTouch' );
		}
	}

Begin:
	Timer();
}

//-----------------------------------------------------------------------------

state Finished
{
	function Trigger( Actor Other, Pawn EventInstigator, optional name EventName )
	{
		if( !HandleSpawneeDeath( Other ) )
		{
			// trigger from anything but creatures belonging to 
			// this factory shuts down the factory
			if( bNonPrototypeTriggerKillAll )
			{
				KillAll();
			}
		}
		if( bCanRestart )
		{
			Capacity = InitialCapacity;
			GotoState( 'Waiting' );
		}
	}
}	

//-----------------------------------------------------------------------------

function DumpInfo( PlayerController P )
{
	local SpawnPoint SP;
	local Actor A;
	local int Count;

	P.log( "   " );

	P.log( "ActorFactory:    " $ Name );
	P.log( "  State:         " $ GetStateName() );
	P.log( "  Prototype:     " $ Prototype );
	P.log( "  Capacity:      " $ Capacity );
	P.log( "  MaxItems:      " $ MaxItems );
	P.log( "  Spawn spots:   " $ NumSpawnPoints );
	P.log( "  Spawned items: " $ NumSpawnedItems );
	P.log( "  Event:         " $ Event );
	P.log( "  Tag:           " $ Tag );
	P.log( "  ItemTag:       " $ ItemTag );
	P.log( "  bTouchEnabled: " $ bTouchEnabled );

	// dump SpawnPoint info
	Count=0;
	P.log( "   " );
	P.log( "  SpawnPoints:" );
	foreach AllActors( class'SpawnPoint', SP, Tag )
	{
		SP.DumpInfo( P.Pawn );
		Count++;
		P.log( "   " );
	}
	P.log( "    " $ Count $ " SpawnPoints found." );

	// dump Trigger info
	Count=0;
	P.log( "   " );
	P.log( "  Existing Triggers:" );
	foreach AllActors( class'Actor', A )
	{
		if( A.Event == Tag )
		{
			P.log( "    " $ A.Name );
			Count++;
		}
	}
	P.log( "    " $ Count $ " Triggers found." );
}

//-----------------------------------------------------------------------------

Including the reset if empty, I see Barbie has something but this factory thing just tees me off.
Binary Space Partitioning
User avatar
Leo(T.C.K.)
Inhuman
Posts: 868
Joined: Sat Aug 13, 2011 10:26 pm

Re: Stupid Thing_Factory

Post by Leo(T.C.K.) »

What happens if you use thing factory with triggercontrol state trigger?

I never tried but you could do that and have that triggercontrol trigger attached to a mover.
Red_Fist
Godlike
Posts: 2163
Joined: Sun Oct 05, 2008 3:31 am

Re: Stupid Thing_Factory

Post by Red_Fist »

Because I want a floor plate to set off traps as you stand on the floor with a mover embedded into the floor.

But I can use geometric shapes as opposed to radius of triggers.
Binary Space Partitioning
User avatar
Leo(T.C.K.)
Inhuman
Posts: 868
Joined: Sat Aug 13, 2011 10:26 pm

Re: Stupid Thing_Factory

Post by Leo(T.C.K.) »

True, well it could even be solved by a triggercontrol state mover (a mylevel subclass) for example.
That's more direct approach rather than having a modified thing factory.
Red_Fist
Godlike
Posts: 2163
Joined: Sun Oct 05, 2008 3:31 am

Re: Stupid Thing_Factory

Post by Red_Fist »

No, the mover is just a trigger, but you have to "touch" the thingfactory to shut it off.

Then I go back to the mover and trigger another one, using -1 as capacity.
So it does work now but the mover "event" can't stop the spawning.

So I step off the mover and it will stop, if can work like that.
Binary Space Partitioning
User avatar
Leo(T.C.K.)
Inhuman
Posts: 868
Joined: Sat Aug 13, 2011 10:26 pm

Re: Stupid Thing_Factory

Post by Leo(T.C.K.) »

I will try to test this myself, what are you trying to spawn exactly?
Red_Fist
Godlike
Posts: 2163
Joined: Sun Oct 05, 2008 3:31 am

Re: Stupid Thing_Factory

Post by Red_Fist »

Projectiles for traps in hallways.

This is the way Quake 1 did it, they had trigger brushes, as soon as you stand in area things happen, not rows and rows of triggeres.
Binary Space Partitioning
User avatar
Leo(T.C.K.)
Inhuman
Posts: 868
Joined: Sat Aug 13, 2011 10:26 pm

Re: Stupid Thing_Factory

Post by Leo(T.C.K.) »

I see.
Post Reply