Working code!....? Weapon Jump Node

Discussions about Coding and Scripting
Post Reply
User avatar
Gustavo6046
Godlike
Posts: 1462
Joined: Mon Jun 01, 2015 7:08 pm
Personal rank: Resident Wallaby
Location: Porto Alegre, Brazil
Contact:

Working code!....? Weapon Jump Node

Post by Gustavo6046 »

So for a long time I though I would never make a single working f*-script.

But today a miracle happened!

For some reason, I decided to just keep working in my previous, non-working code of Weapon Jump. I decided to call it WeaponJumpSpot -- pawns jump and shoot beneath themselves to gain thrust.

With the edited code:

Code: Select all

///////////////////////////////////////////////////////////////////////////
// WeaponJumpSpot.                                                       //   
//																           //
// Makes the bot fire the weapon beneath it to gain boost to the target. //
///////////////////////////////////////////////////////////////////////////
class WeaponJumpSpot expands LiftCenter;

//The weapon the pawn will relize the jump with.
var()	class<Weapon>	WeaponToJump;

//Two variables that enables transmitting the pawn and aim rotator from SpecialHandling to Timer.
var		pawn			rstt;
var		rotator			IAim;

//This variable defines the delay between the jump and the shoot.
var()	float			ShootDelay;

//Used in state code
var		float			OldCost;
var		Pawn			SeekerBot;
var		Weapon			We;

//How much time the bot will ignore the route if he doesn't has the weapon to do the jump
var()	float			IgnoreTime;

//SpecialCost changes the cost of the path depending on certain conditions.
//
//Returns the new cost value.
//
event int SpecialCost(Pawn Seeker)
{
	if ( !Seeker.IsA('Bot') || WeaponToJump == None )
		return 10000000;
	return 300;
}

//Calculates the aim for the jump.
function rotator CalculateJumpAim(Actor Other, Actor Target)
{
	local	rotator	Aiming; //the result
	local	vector	Distance; //the vector of offset between Other and the target
	local	float	YawFactor; //the factor that the yaw of Aiming will be modified by

	if ( Other == None || Target == None )
		return rot(0, 0, 0);

	//Calculation algorithm: The aim points to the instead of the target,
	//and the further the target is horizontally, the shallower is the
	//aim, and te further the target is vertically, the steeper is the
	//aim.
	Distance = Target.Location - Other.Location;
	YawFactor = (Distance.Z * VSize(Distance)) / (sqrt((Distance.X ^ 2) + (Distance.Y ^ 2)));
	Aiming = Rotator(-Distance);
	Aiming.Yaw += YawFactor;
	return Aiming;
}

//Calculates the closest actor of type Type from vector Origin, in a maximum distance of MaxDistance.
//
//Returns the closest actor, of course.
function Actor ClosestActor(class<Actor> Type, vector Origin, float MaxDistance)
{
	local float MaxDist;
	local float Distance;
	local Actor	A;
	local Actor C;

	MaxDist = MaxDistance;

	//Sanity check
	if ( Type == None || MaxDistance == 0 )
		return None;

	foreach AllActors(Type, A)
	{
		Distance = VSize(A.Location - Origin);

		if ( Distance < MaxDist )
		{
			MaxDist = Distance;
			C = A;
		}
	}

	return C;
}

//SpecialHandling changes the path of the bot depending in conditions.
//
//Returns where the bot must go.
//
function Actor SpecialHandling(Pawn Other)
{
	local	LiftExit	Target; //the target LiftExit the bot wants to go to

	local	Weapon		W, XW, YW;
	local	float		WX, np;

	WX = 4096;
	Target = LiftExit(Other.MoveTarget);

	//finds out whether the pawn has the weapon in their inventory
	if ( WeaponToJump != None )
		W = Weapon(Other.FindInventoryType(WeaponToJump));

	//makes the jump and calls SetTimer so the bot fires
	if ( (Target != None) && (Target.LiftTag == LiftTag) && (W != None) )
	{
		We = W;
		SeekerBot = Other;
		GoToState('Botjump');
	}

	//if it doesn't has the weapon to do the jump acquires a weapon before realizing the jump.
	//it does a ForEach for all weapons and determine the closer one from the bot that is the weapon for the Weapon Jump.
	else if ( ( W == None ) && ( WeaponToJump != None ) )
	{
		YW = Weapon(ClosestActor(WeaponToJump, Other.Location, 4096));

		if ( YW != None )
			return YW; //acquires the weapon before trying again.
		
		GoToState('IgnoreRoute');
		return ClosestActor(class'PathNode', Other.Location, 2048); //goes to the closest path node and temporarily ignores the route
	}
}

function Timer()
{
	//makes the pawn fire it's weapon
	rstt.ViewRotation = IAim;
	rstt.FireWeapon();
}

auto state() Idle
{
}

//Performs the jump and calls SetTimer()
state() Botjump
{
	Begin:
		IAim = CalculateJumpAim(SeekerBot, Target);
		SeekerBot.AddVelocity(vect(0, 0, 10));
		Sleep(0.05);
		SeekerBot.AddVelocity(vect(0, 0, 400));
		SeekerBot.Weapon = We;
		rstt = SeekerBot;
		SetTimer(ShootDelay, false);
		GoToState('Idle');
}

//Makes bots temporarily ignore the route
state() IgnoreRoute
{
	Begin:
		OldCost = ExtraCost;
		ExtraCost = 10000000;
		Sleep(IgnoreTime);
		ExtraCost = OldCost;	
		GoToState('Idle');
}
Pawns jumped as usual (but maybe a little too high?), shooted somewhere very inacurately between the wall and beneath themselves, but at least reached the ledge! Yay! I was so surprised-- it WORKS!

How do I make it shoot more accurately?

Maybe it only reached because of large initial momentum given, but I am pretty sure it wasn't just the momentum (other attempts where he missed the missile, had failed).

Yes, this is a actual test I performed at DM-WeaponJump-Test: (paste this at your UnrealEd of preference then rebuild all and test)

Code: Select all

Begin Map
Begin Actor Class=Brush Name=Brush0
    MainScale=(SheerAxis=SHEER_ZX)
    PostScale=(SheerAxis=SHEER_ZX)
    Group=Cube
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=Brush
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',ZoneNumber=1)
    Location=(X=256.000000,Z=-16.000000)
    bSelected=True
    Brush=Model'MyLevel.Brush'
    PrePivot=(Y=-4.000000)
    Name=Brush0
End Actor
Begin Actor Class=Brush Name=Brush1
    CsgOper=CSG_Subtract
    MainScale=(SheerAxis=SHEER_ZX)
    PostScale=(SheerAxis=SHEER_ZX)
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=Brush
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',iLeaf=1,ZoneNumber=1)
    bSelected=True
    Brush=Model'MyLevel.Model2'
    Name=Brush1
End Actor
Begin Actor Class=Brush Name=Brush2
    CsgOper=CSG_Subtract
    MainScale=(SheerAxis=SHEER_ZX)
    PostScale=(SheerAxis=SHEER_ZX)
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=Brush
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',ZoneNumber=1)
    Location=(X=256.000000,Y=4.000000,Z=128.000000)
    bSelected=True
    Brush=Model'MyLevel.Model3'
    Name=Brush2
End Actor
Begin Actor Class=PlayerStart Name=PlayerStart0
    upstreamPaths(0)=32
    Paths(0)=3
    PrunedPaths(0)=1
    PrunedPaths(1)=2
    PrunedPaths(2)=0
    PrunedPaths(3)=4
    VisNoReachPaths(0)=LiftExit'MyLevel.LiftExit0'
    visitedWeight=10000000
    bestPathWeight=27
    cost=1000000
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=PlayerStart
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',iLeaf=1,ZoneNumber=1)
    Location=(X=-93.143211,Y=1.940552,Z=-215.899261)
    OldLocation=(X=-93.143211,Y=1.940552,Z=-215.899261)
    bSelected=True
    Name=PlayerStart0
End Actor
Begin Actor Class=Brush Name=Brush3
    CsgOper=CSG_Subtract
    MainScale=(SheerAxis=SHEER_ZX)
    PostScale=(SheerAxis=SHEER_ZX)
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=Brush
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',ZoneNumber=1)
    Location=(X=256.000000,Z=-16.000000)
    bSelected=True
    Brush=Model'MyLevel.Model4'
    PrePivot=(Y=-4.000000)
    Name=Brush3
End Actor
Begin Actor Class=LiftExit Name=LiftExit0
    LiftTag=wjump
    upstreamPaths(0)=13
    upstreamPaths(1)=39
    Paths(0)=14
    Paths(1)=12
    Paths(2)=8
    Paths(3)=7
    Paths(4)=11
    PrunedPaths(0)=5
    PrunedPaths(1)=9
    PrunedPaths(2)=6
    PrunedPaths(3)=10
    nextNavigationPoint=PlayerStart'MyLevel.PlayerStart0'
    nextOrdered=InventorySpot'MyLevel.InventorySpot38'
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=LiftExit
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',ZoneNumber=1)
    Location=(X=150.445526,Y=1.130080,Z=-117.900635)
    OldLocation=(X=320.445557,Y=58.463409,Z=-93.900642)
    bSelected=True
    Name=LiftExit0
End Actor
Begin Actor Class=Light Name=Light0
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=Light
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',iLeaf=1,ZoneNumber=1)
    Location=(X=85.006508,Y=-46.100006,Z=29.651428)
    OldLocation=(X=26.006508,Y=103.900002,Z=-73.348564)
    bSelected=True
    Name=Light0
End Actor
Begin Actor Class=Translocator Name=Translocator0
    myMarker=InventorySpot'MyLevel.InventorySpot36'
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=Translocator
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',iLeaf=1,ZoneNumber=1)
    Location=(X=-98.535027,Y=-10.566757,Z=-252.899597)
    OldLocation=(X=47.464973,Y=-25.566757,Z=-252.899597)
    bSelected=True
    Name=Translocator0
End Actor
Begin Actor Class=WarheadLauncher Name=WarheadLauncher0
    myMarker=InventorySpot'MyLevel.InventorySpot37'
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=WarheadLauncher
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',ZoneNumber=1)
    Location=(X=316.782104,Y=-10.651268,Z=-168.899658)
    OldLocation=(X=316.782104,Y=-10.651268,Z=-168.899658)
    bSelected=True
    Name=WarheadLauncher0
End Actor
Begin Actor Class=UT_FlakCannon Name=UT_FlakCannon2
    myMarker=InventorySpot'MyLevel.InventorySpot38'
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=UT_FlakCannon
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',ZoneNumber=1)
    Location=(X=258.478760,Y=34.836811,Z=-168.900330)
    OldLocation=(X=258.478760,Y=34.836811,Z=-168.900330)
    bSelected=True
    Name=UT_FlakCannon2
End Actor
Begin Actor Class=WeaponJumpSpot Name=WeaponJumpSpot0
    ShootDelay=0.320000
    OldCost=0.000000
    IgnoreTime=1.000000
    LiftTag=wjump
    MaxZDiffAdd=500.000000
    upstreamPaths(0)=16
    upstreamPaths(1)=14
    Paths(0)=15
    Paths(1)=13
    visitedWeight=900
    bestPathWeight=500
    nextNavigationPoint=LiftExit'MyLevel.LiftExit0'
    nextOrdered=TranslocStart'MyLevel.TranslocStart0'
    prevOrdered=InventorySpot'MyLevel.InventorySpot37'
    previousPath=LiftExit'MyLevel.LiftExit0'
    cost=400
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=WeaponJumpSpot
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',iLeaf=1,ZoneNumber=1)
    Location=(X=66.736313,Y=1.318844,Z=-205.900452)
    OldLocation=(X=49.147278,Y=-20.040691,Z=-205.900452)
    bSelected=True
    Name=WeaponJumpSpot0
End Actor
Begin Actor Class=UT_Eightball Name=UT_Eightball0
    myMarker=InventorySpot'MyLevel.InventorySpot39'
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=UT_Eightball
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',iLeaf=1,ZoneNumber=1)
    Location=(X=-4.293289,Y=-5.388702,Z=-245.899719)
    OldLocation=(X=-4.293289,Y=-5.388702,Z=-245.899719)
    bSelected=True
    Name=UT_Eightball0
End Actor
Begin Actor Class=TranslocStart Name=TranslocStart0
    LiftTag=wjump
    upstreamPaths(0)=15
    upstreamPaths(1)=28
    upstreamPaths(2)=42
    Paths(0)=16
    Paths(1)=19
    Paths(2)=21
    PrunedPaths(0)=18
    PrunedPaths(1)=17
    PrunedPaths(2)=20
    VisNoReachPaths(0)=LiftExit'MyLevel.LiftExit0'
    visitedWeight=1400
    bestPathWeight=56
    nextNavigationPoint=WeaponJumpSpot'MyLevel.WeaponJumpSpot0'
    nextOrdered=InventorySpot'MyLevel.InventorySpot39'
    prevOrdered=WeaponJumpSpot'MyLevel.WeaponJumpSpot0'
    previousPath=WeaponJumpSpot'MyLevel.WeaponJumpSpot0'
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=TranslocStart
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',iLeaf=1,ZoneNumber=1)
    Location=(X=-0.644429,Y=4.432288,Z=-205.900574)
    OldLocation=(X=2.915493,Y=18.024719,Z=-205.900574)
    bSelected=True
    Name=TranslocStart0
End Actor
Begin Actor Class=PathNode Name=PathNode0
    upstreamPaths(0)=7
    upstreamPaths(1)=43
    Paths(0)=26
    PrunedPaths(0)=22
    PrunedPaths(1)=25
    PrunedPaths(2)=24
    PrunedPaths(3)=23
    VisNoReachPaths(0)=LiftExit'MyLevel.LiftExit0'
    visitedWeight=1503
    bestPathWeight=92
    nextNavigationPoint=TranslocStart'MyLevel.TranslocStart0'
    nextOrdered=InventorySpot'MyLevel.InventorySpot36'
    prevOrdered=PathNode'MyLevel.PathNode1'
    previousPath=InventorySpot'MyLevel.InventorySpot39'
    bDynamicLight=True
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=PathNode
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',iLeaf=1,ZoneNumber=1)
    Location=(X=50.363708,Y=-79.200005,Z=-205.899750)
    OldLocation=(X=-8.636292,Y=-79.200005,Z=-205.899750)
    bSelected=True
    Name=PathNode0
End Actor
Begin Actor Class=PathNode Name=PathNode1
    upstreamPaths(0)=8
    upstreamPaths(1)=19
    Paths(0)=28
    PrunedPaths(0)=29
    PrunedPaths(1)=27
    PrunedPaths(2)=30
    PrunedPaths(3)=31
    VisNoReachPaths(0)=LiftExit'MyLevel.LiftExit0'
    visitedWeight=1456
    bestPathWeight=56
    nextNavigationPoint=PathNode'MyLevel.PathNode0'
    nextOrdered=PathNode'MyLevel.PathNode0'
    prevOrdered=InventorySpot'MyLevel.InventorySpot39'
    previousPath=TranslocStart'MyLevel.TranslocStart0'
    Level=LevelInfo'MyLevel.LevelInfo0'
    Tag=PathNode
    Region=(Zone=LevelInfo'MyLevel.LevelInfo0',iLeaf=1,ZoneNumber=1)
    Location=(X=25.556366,Y=53.933331,Z=-205.899719)
    OldLocation=(X=25.556366,Y=53.933331,Z=-205.899719)
    bSelected=True
    Name=PathNode1
End Actor
End Map
Don't mind the size of the map's code :P Imagine if it were AS-FoT-OrionsCurse XD

Edit:
_4TMrX-G3XE
Last edited by Gustavo6046 on Fri Feb 26, 2016 10:21 pm, edited 2 times in total.
"Everyone is an idea man. Everybody thinks they have a revolutionary new game concept that no one else has ever thought of. Having cool ideas will rarely get you anywhere in the games industry. You have to be able to implement your ideas or provide some useful skill. Never join a project whose idea man or leader has no obvious development skills. Never join a project that only has a web designer. You have your own ideas. Focus on them carefully and in small chunks and you will be able to develop cool projects."

Weapon of Destruction
User avatar
FXANBSS
Skilled
Posts: 231
Joined: Thu Dec 26, 2013 7:03 pm

Re: Working code! Weapon Jump Node

Post by FXANBSS »

still bugged
User avatar
Gustavo6046
Godlike
Posts: 1462
Joined: Mon Jun 01, 2015 7:08 pm
Personal rank: Resident Wallaby
Location: Porto Alegre, Brazil
Contact:

Re: Working code! Weapon Jump Node

Post by Gustavo6046 »

FXANBSS wrote:still bugged
fixed :noidea

Code: Select all

///////////////////////////////////////////////////////////////////////////
// WeaponJumpSpot.                                                       //   
//																           //
// Makes the bot fire the weapon beneath it to gain boost to the target. //
///////////////////////////////////////////////////////////////////////////
class WeaponJumpSpot expands LiftCenter;

//The weapon the pawn will relize the jump with.
var()	class<Weapon>	WeaponToJump;

//Two variables that enables transmitting the pawn and aim rotator from SpecialHandling to Timer.
var		pawn			rstt;
var		rotator			IAim;

//This variable defines the delay between the jump and the shoot.
var()	float			ShootDelay;

//Used in state code
var		float			OldCost;
var		Pawn			SeekerBot;
var		Weapon			We;

//How much time the bot will ignore the route if he doesn't has the weapon to do the jump
var()	float			IgnoreTime;

//SpecialCost changes the cost of the path depending on certain conditions.
//
//Returns the new cost value.
//
event int SpecialCost(Pawn Seeker)
{
	if ( !Seeker.IsA('Bot') || WeaponToJump == None )
		return 10000000;
	return 300;
}

//Calculates the aim for the jump.
function rotator CalculateJumpAim(Actor Other, Actor Target)
{
	local	rotator	Aiming; //the result
	local	vector	Distance; //the vector of offset between Other and the target
	local	float	YawFactor; //the factor that the yaw of Aiming will be modified by

	if ( Other == None || Target == None )
		return rot(0, 0, 0);

	//Calculation algorithm: The aim points to the instead of the target,
	//and the further the target is horizontally, the shallower is the
	//aim, and te further the target is vertically, the steeper is the
	//aim.
	Distance = Target.Location - Other.Location;
	YawFactor = (Distance.Z * VSize(Distance)) / (sqrt((Distance.X ^ 2) + (Distance.Y ^ 2)));
	Aiming = Rotator(-Distance);
	Aiming.Yaw += YawFactor;
	return Aiming;
}

//Calculates the closest actor of type Type from vector Origin, in a maximum distance of MaxDistance.
//
//Returns the closest actor, of course.
function Actor ClosestActor(class<Actor> Type, vector Origin, float MaxDistance)
{
	local float MaxDist;
	local float Distance;
	local Actor	A;
	local Actor C;

	MaxDist = MaxDistance;

	//Sanity check
	if ( Type == None || MaxDistance == 0 )
		return None;

	foreach AllActors(Type, A)
	{
		Distance = VSize(A.Location - Origin);

		if ( Distance < MaxDist )
		{
			MaxDist = Distance;
			C = A;
		}
	}

	return C;
}

//SpecialHandling changes the path of the bot depending in conditions.
//
//Returns where the bot must go.
//
function Actor SpecialHandling(Pawn Other)
{
	local	LiftExit	Target; //the target LiftExit the bot wants to go to

	local	Weapon		W, XW, YW;
	local	float		WX, np;

	WX = 4096;
	Target = LiftExit(Other.MoveTarget);

	//finds out whether the pawn has the weapon in their inventory
	if ( WeaponToJump != None )
		W = Weapon(Other.FindInventoryType(WeaponToJump));

	//makes the jump and calls SetTimer so the bot fires
	if ( (Target != None) && (Target.LiftTag == LiftTag) && (W != None) )
	{
		We = W;
		SeekerBot = Other;
		GoToState('Botjump');
	}

	//if it doesn't has the weapon to do the jump acquires a weapon before realizing the jump.
	//it does a ForEach for all weapons and determine the closer one from the bot that is the weapon for the Weapon Jump.
	else if ( ( W == None ) && ( WeaponToJump != None ) )
	{
		YW = Weapon(ClosestActor(WeaponToJump, Other.Location, 4096));

		if ( YW != None )
			return YW; //acquires the weapon before trying again.
		
		GoToState('IgnoreRoute');
		return ClosestActor(class'PathNode', Other.Location, 2048); //goes to the closest path node and temporarily ignores the route
	}
}

function Timer()
{
	//makes the pawn fire it's weapon
	rstt.ViewRotation = IAim;
	rstt.FireWeapon();
}

auto state() Idle
{
}

//Performs the jump and calls SetTimer()
state() Botjump
{
	Begin:
		IAim = CalculateJumpAim(SeekerBot, Target);
		SeekerBot.AddVelocity(vect(0, 0, 10));
		Sleep(0.05);
		SeekerBot.AddVelocity(vect(0, 0, 400));
		SeekerBot.Weapon = We;
		rstt = SeekerBot;
		SetTimer(ShootDelay, false);
		GoToState('Idle');
}

//Makes bots temporarily ignore the route
state() IgnoreRoute
{
	Begin:
		OldCost = ExtraCost;
		ExtraCost = 10000000;
		Sleep(IgnoreTime);
		ExtraCost = OldCost;	
		GoToState('Idle');
}
"Everyone is an idea man. Everybody thinks they have a revolutionary new game concept that no one else has ever thought of. Having cool ideas will rarely get you anywhere in the games industry. You have to be able to implement your ideas or provide some useful skill. Never join a project whose idea man or leader has no obvious development skills. Never join a project that only has a web designer. You have your own ideas. Focus on them carefully and in small chunks and you will be able to develop cool projects."

Weapon of Destruction
User avatar
Gustavo6046
Godlike
Posts: 1462
Joined: Mon Jun 01, 2015 7:08 pm
Personal rank: Resident Wallaby
Location: Porto Alegre, Brazil
Contact:

Re: Working code!....? Weapon Jump Node

Post by Gustavo6046 »

Had to bump this since I tried to fix it and now bots won't aim correctly to the rotation specified by CalculateShootAim() function:

Code: Select all

///////////////////////////////////////////////////////////////////////////
// WeaponJumpSpot.                                                       //   
//																           //
// Makes the bot fire the weapon beneath it to gain boost to the target. //
///////////////////////////////////////////////////////////////////////////
class WeaponJumpSpot expands LiftCenter;

//The weapon the pawn will relize the jump with.
var()	class<Weapon>		WeaponToJump;

//The variable that enables transmitting the pawn from SpecialHandling to Timer.
var		pawn				rstt;

//This variable is the aim of the bot upon firing. Seriously.
var		Rotator				ShootRotation;

//This variable defines the delay between the jump and the shoot.
var()	float				ShootDelay;

//Used in state code
var		float				OldCost;
var		Pawn				SeekerBot;
var		Weapon				We;
var		LiftExit			Le;
var		Pawn				TickPawn;

//How much time the bot will ignore the route if he doesn't has the weapon to do the jump
var()	float				IgnoreTime;

//Minimum health needed to perform the leap.
var()	int					MinHealth;

//SpecialCost changes the cost of the path depending on certain conditions.
//
//Returns the new cost value.
//
event int SpecialCost(Pawn Seeker)
{
	if ( !Seeker.IsA('Bot') || WeaponToJump == None || Seeker.Health < MinHealth )
		return 10000000;
	return 300;
}

//Calculates the closest actor of type Type from vector Origin, in a maximum distance of MaxDistance.
//
//Returns the closest actor, of course.
function Actor ClosestActor(class<Actor> Type, vector Origin, float MaxDistance)
{
	local float MaxDist;
	local float Distance;
	local Actor	A;
	local Actor C;

	MaxDist = MaxDistance;

	//Sanity check
	if ( Type == None || MaxDistance == 0 )
		return None;

	foreach AllActors(Type, A)
	{
		Distance = VSize(A.Location - Origin);

		if ( Distance < MaxDist )
		{
			MaxDist = Distance;
			C = A;
		}
	}

	return C;
}

// The algorithm that calculates jump aim.
function Rotator CalculateShootAim(Pawn Other, LiftExit Target)
{
	// Local variables
	local Vector Difference;

	// Sanity checks
	if ( Target == None )
	{
		log("Warning:" @ Name @ "had no target and had to be destructed!");
		Destroy();
	}

	if ( Other == None )
		return rot(0, 0, 0);

	// The algorithm itself
	Difference = Target.Location - Other.Location;
	Difference.x *= -1;
	Difference.y *= -1;

	return rotator(Difference);
}

//SpecialHandling changes the path of the bot depending in conditions.
//
//Returns where the bot must go after the SpecialHandling call.
//
function Actor SpecialHandling(Pawn Other)
{
	local	LiftExit	Target; //the target LiftExit the bot wants to go to

	local	Weapon		W, XW, YW;
	local	float		WX, np;

	WX = 4096;
	Target = LiftExit(Other.MoveTarget);

	//finds out whether the pawn has the weapon in their inventory
	if ( WeaponToJump != None )
		W = Weapon(Other.FindInventoryType(WeaponToJump));

	//makes the jump and calls SetTimer so the bot fires
	if ( (Target != None) && (Target.LiftTag == LiftTag) && (W != None) )
	{
		We = W;
		SeekerBot = Other;
		Le = Target;
		GoToState('Botjump');
	}

	//if it doesn't has the weapon to do the jump acquires a weapon before realizing the jump.
	//it does a ForEach for all weapons and determine the closer one from the bot that is the weapon for the Weapon Jump.
	else if ( ( W == None ) && ( WeaponToJump != None ) )
	{
		YW = Weapon(ClosestActor(WeaponToJump, Other.Location, 4096));

		if ( YW != None )
			if ( YW.bActive && YW.IsInState('Pickup') )
				return YW; //acquires the weapon before trying again.
		
		GoToState('IgnoreRoute');
	}

	return ClosestActor(class'PathNode', Other.Location, 2048); //goes to the closest path node and temporarily ignores the route
																  //if there is no path node, goes to None
}

function Timer()
{
	//makes the pawn fire it's weapon
	GoToState('Fire');
}

auto state() Idle
{
}

//Performs the jump and calls SetTimer()
state() Botjump
{
	Begin:
		if ( SeekerBot == None )
			GoToState('Idle');

		SeekerBot.TurnToward(Target);
		ShootRotation = CalculateShootAim(SeekerBot, Le);
		Bot(SeekerBot).BigJump(Le);
		SeekerBot.Weapon = We;
		rstt = SeekerBot;
		SetTimer(ShootDelay, false);
		SeekerBot = None;
		GoToState('Idle');
}

//Makes bots temporarily ignore the route
state() IgnoreRoute
{
	Begin:
		OldCost = ExtraCost;
		ExtraCost = 10000000;
		Sleep(IgnoreTime);
		ExtraCost = OldCost;	
		GoToState('Idle');
}

//Makes bots perform the fire beneath themselves
state() Fire
{
	Begin:
		Sleep(0.1);
		rstt.TurnTo(vector(ShootRotation));
		rstt.FireWeapon();
		GoToState('Idle');
}
"Everyone is an idea man. Everybody thinks they have a revolutionary new game concept that no one else has ever thought of. Having cool ideas will rarely get you anywhere in the games industry. You have to be able to implement your ideas or provide some useful skill. Never join a project whose idea man or leader has no obvious development skills. Never join a project that only has a web designer. You have your own ideas. Focus on them carefully and in small chunks and you will be able to develop cool projects."

Weapon of Destruction
Post Reply