Overview Package Class Source Class tree Glossary
previous class      next class frames      no frames

U2AI.U2PawnBasic


00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
//=============================================================================
// U2PawnBasic.uc
// Created By: Mike Fox
// Created On: 8/01/00
// $Author: Mfox $
// $Date: 12/18/02 4:50p $
// $Revision: 95 $
//=============================================================================

class U2PawnBasic extends U2PawnBase
	abstract;

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

struct BehaviorT
{
	var() editconst config name		StateName;		// destination state
	var() editconst config name		StateLabel;		// destination label within destination state (optional)
	var() editconst config float	Odds;			// odds for state relative to other states in the list (0.0 ==> cycled)
	var() editconst config float	EntryOdds;		// if set (not 0.0) ==> odds used when entering metastate (from a different state), (< 0.0 ==> don't use)
	var() editconst config float	TimeMin;		// min time state will be maintained before reevaluating (unless situation changes)
	var() editconst config float	TimeMax;		// max time state will be maintained before reevaluating (unless situation changes)
	var() editconst config bool		bDisabled;		// disabled (by default or internally)
	var() editconst config bool		bAvoidRepeat;	// if true, state won't be re-selected 2x in a row if there is an alternative state
	var() editconst config float    EnableTime;		// can be set in-game to Level.TimeSeconds + X to disable that behavior temporarily
	var() editconst config float    LowOddsTime;	// used to temporarily make odds of behavior being used very low for a period of time
};

// AI behaviors (BehaviorController uses these)
// Note: code that accesses these assumes the array is kept packed (no gaps)

// active attack behaviors (no orders or ignoring orders)
var(AI) editconst array<BehaviorT> AttackActiveBehaviors;
var(AI) editconst array<BehaviorT> AttackActiveCantReachBehaviors;
var(AI) editconst array<BehaviorT> AttackActiveEnemyNotVisibleBehaviors;
var(AI) editconst array<BehaviorT> AttackActiveUseCoverBehaviors;
var(AI) editconst array<BehaviorT> AttackActiveMeleeBehaviors;
var(AI) editconst array<BehaviorT> AttackActiveMeleeHitBehaviors;

// passive attack behaviors (trying to follow orders)
var(AI) editconst array<BehaviorT> AttackPassiveBehaviors;
var(AI) editconst array<BehaviorT> AttackPassiveCantReachBehaviors;
var(AI) editconst array<BehaviorT> AttackPassiveEnemyNotVisibleBehaviors;
var(AI) editconst array<BehaviorT> AttackPassiveUseCoverBehaviors;
var(AI) editconst array<BehaviorT> AttackPassiveMeleeBehaviors;
var(AI) editconst array<BehaviorT> AttackPassiveMeleeHitBehaviors;

// properties for controlling duration of specific meta states
var float AttackCantFireLockoutTime;			// time to disable a state from which firing isn't possible currently
var float AttackMeleeMinTime;					// min durarion of melee attack (when one starts)
var float AttackMeleeMaxTime;					// max
var float AttackUseCoverMinTime;				// min duration of using cover behavior (when starting to use cover)
var float AttackUseCoverMaxTime;				// diff-scaled: max
var float AttackUseCoverLockoutTime;			// time to wait before trying to find cover again after not being able to find cover
var float AttackUseCoverTimeOutTime;			// diff-scaled: time to wait before trying to use cover metastate again after it times out
var float RecoverLockOutUseCoverTime;			// time to wait before trying to find cover again after recovering enemy (e.g. after hunt)

var(AI) bool bIgnoreRelativeHealth;				//2002.12.15 (mdf) McMillan hack?

var float MaxFleeSearchDistance;
var float MaxUseCoverSearchDistance;
var bool bMonitorStanceRanges;

//-----------------------------------------------------------------------------
// combat properties

var bool	bAlwaysAttackNewEnemy;				// npc will blindly attack each newly detected enemy (via see/hear/bump/damage etc.)
var bool	bAlwaysAttackAnnoyingNewEnemy;		// NPC will blindly attack each newly detected enemy (via see/hear/bump/damage etc.)
var bool	bCanAdjustStationaryPosition;		// if true, NPC can move right/left during stationary attack if shot is blocked (usually needs to be false for full-body animation-based attacks)
var bool	bCanStrafeDuringTacticalMoves;		// (false) if false and !bCanStrafe, NPC will turn away from enemy when doing tactical moves
var bool	bCanStrafeDuringTacticalRetreat;	// (true) if false and !bCanStrafe, NPC will turn away from enemy when backing off
var bool	bCanStrafeDuringOrders;				// if true, NPC can strafe when carrying out orders
var bool	bJumpy;								
var bool	bLeadTarget;						// lead target with non-weapon based projectile attacks
var bool	bPredictChargeLocation;				// when charging head towards wherever target is headed instead of at target
var bool	bFacePredictedLocation;				// if true (default) NPC will face predicted location when moving to it
var bool	bFearPlayersMoreThanNPCs;
var bool	bFearNPCsMoreThanPlayers;
var int		CloseFaceTarget;					// 1: always -1: never 0: default (check time since acquired etc.)
var float	AttackClosingCanFireOdds;			// odds NPC will try to fire while closing (if possible)
var float	AttackClosingReachableDistSquared;	// defaults to 1200*1200 but some NPCs try to close directly from further away (increasing this means reach test will be more expensive)
var float	AttackStationaryCanFireOdds;		// odds NPC will try to fire while stationary (if possible)
var float	AttackTacticalMoveCanFireOdds;		// odds NPC will try to fire during tactical moves (if possible)
var	float   BaseAggressiveness;					
var float	BaseAlertness;						// not currently set -- established in BotInfo
var float	CampingRate;						
var float	CombatStyle;						// -1 to 1 = low means tends to stay off and snipe, high means tends to charge and melee
var float	RefireRate;							// mdf-tbd: not used much currently	(lower=faster -- opposite of UT?)
var float	StationaryStandOdds;				// odds that NPC will stand when stationary (attacking, holding etc.)
var float	StationaryCrouchOdds;				// odds that NPC will crouch when stationary (attacking, holding etc.)
var float	StationaryProneOdds;				// odds that NPC will go prone when stationary (attacking, holding etc.)
var float	StationaryStayCrouchingOdds;		// odds that NPC will stay crouching (once crouching) when stationary
var float	StationaryStayProneOdds;			// odds that NPC will stay prone (once prone) when stationary
var float	MinStayCrouchingTime;				// min time NPC will stay crouching if it crouches (e.g. before moving)
var float	MinStayProneTime;					// min time NPC will stay prone if it goes prone (e.g. before moving)
var float	MinReduceStanceAgainDelay;			// min delay after crouching/prone before going standing -> crouching/prone or crouching -> prone again
var float	BounceProjectileOdds;
var float	BounceLifespan;						// diff-scaled: with NPCs, grenades get their lifespan set to this once they bounce the first time
// acquisition
var float	MaxStationaryFiringDelay;			// leave stationary attack state if NPC won't be able to fire for at least this long
var float	MinAcquisitionDelay;				// additional delay when an enemy is acquired (after turning towards enemy, playing animation etc.).
var float	MinAlertAcquisitionDelay;			// delay before firing when re-acquiring an enemy while fairly alert (enemy detected recently, using cover etc.)
var float	MinReAcquisitionDelay;				// delay before firing when re-acquiring an enemy that is being hunted
var float   PostAcquisitionAnimationDelay;
var float	AcquisitionAnimationOdds;
var float	TauntAnimationOdds;

// leaping
var bool	bLeapRequiresLOS;					// if true, NPCs only leap at visible enemies
var bool	bTurnToEnemyAfterLeap;				// if true turns to enemy after leap completed (landing + delay)
var float	LeapHighSpeed;						// speed of high leap
var float	LeapLowSpeed;						// speed of low leap (determines range) NOTE: Pawns fall faster than other Actors...
var float	LeapHighOdds;						// odds NPC will use high projectile trajectory (if target inside range)
var float	LeapHighPredictOdds;				// odds NPC will predict target's location with high trajectory
var float	LeapLowPredictOdds;					// odds NPC will predict target's location with low trajectory
var float	LeapMaxOdds;						// odds NPC will leap at 45 degrees (max range) when target out of range
var float	LeapToMeleeOdds;					// odds NPC will go straight to melee attack if enemy bumped during leap
var float	LeapDelayFailure;					// seconds - time to wait after a failed leap attempt (e.g. something in the way)
var float	LeapDelayLand;						// delay after leaping NPC lands
var float	LeapDelayPreJump;					// delay prior to leaping including time to turn towards destination
var float	LeapDelaySuccess;					// seconds - time to wait after a successful leap before trying again
var int		LeapMaxDamage;						// max damage if target hit dead on
var float	LeapMaxMomentumTransfer;			// max MT if target hit dead on
var float	LeapNotifyTime;						// time between start of leap animation and leap notify (refined with first leap)
var float	OnlyLeapLowRange;					// distance within which NPC will only do low leaps

// dodging
//tbd var bool    bHasDodgeFinishAttack;			// can dodge into an attack
var bool	bJumpDodges;						// jump dodge (phys_falling) vs. dodge along the ground (phys_walking)
//var float	DodgeFromDamageOdds;				// odds that NPC will dodge away from damage
var float	DodgeProjectileOdds;				// odds that an NPC will dodge to avoid projectiles
var float	DodgeInsteadofStrafeOdds;			// odds of dodging projectiles rather than strafing away from them
var float   PostDodgeDelay;						// time to wait after dodge animation is complete
var vector	DodgeDestination;					// where the npc will dodge to
var float	RandomCloseDodgeOdds;				// odds of dodging during a closing attack move
var float	DodgeTime;							// duration of dodge animation (updated after first dodge occurs)
var float	DodgeDistance;						// how far NPC tries to dodge
var float	JumpyOdds;							// odds NPC will jump during tactical moves if bJumpy=false
// not editable intentionally for now (these shouldn't vary from instance to instance)
var bool	bHasMovingRangedAttack;				// if true, NPC can move while carrying out ranged attacks (has proper animation support)
var bool	bHasMovingMeleeAttack;				// if true, NPC can move while doing melee attacks (has proper animation support)
var bool	bHasRangedAttack;					// mdf-tbr? might go away if behavior lists control this instead
var bool	bInstantHitAttack;					// animation-based ranged attack is an instant hit attack
var bool	bKamikazeClosing;					// if true, NPC will head straight at enemy without pathing or reachability checks
var bool	bSplashDamageAttack;				// animation-based ranged attack causes splash damage
var float	MaxTacticalRetreatDistance;			// distance NPCs back of by when using TacticalRetreats
var float	PreferHighTrajectoryOdds;			// odds that tossed projectiles will use high vs low trajectory solution
var float	TacticalJumpOdds;					// odds of jumping during a tactical move
var float   TacticalMoveCloseOdds;				// odds NPC will use tactical moves while closing in on an enemy
var float   TacticalMoveFallbackOdds;			// odds NPC will use tactical moves during fallbacks

// Controls range within which NPC will try to fire weapon (Min..Max) and range 
// that NPC will try to close to (Ideal) during tactical moves.
var(AI) bool  bForceRanges;						//2002.12.15 hack to *force* NPCs to not fire outside min/max ranges
var(AI) float RangeMinAttack;					// min attack range to target
var(AI) float RangeIdealAttack;					// ideal attack range to target (NPC will try to maintain this distance)
var(AI) float RangeMaxAttackMobile;				// max attack range to target if NPC can move
var(AI) float RangeMaxAttackMobileNoLOS;		// max attack range to target if NPC can move and enemy can't see NPC (sneak in)
var(AI) float RangeMaxAttackStationary;			// max attack range to target if NPC can't move
var(AI) float RangeMaxAttackStationaryNoLOS;	// max attack range to target if NPC can move and enemy can't see NPC (sneak in)
//var(AI) float RangeLimitAttack;				// absolute limit of attack range to target? (tbd)
var(AI) float DefaultLookedAtCos;				// cos of default fov angle to use when checking for LOS for ranged attack range
var bool  bHasMaxAttackRanges;					// set when ranges updated

// firing control
var float	FireCheckRate;						// rate at which behavior controller checks for being able to fire
var float	FireFastDuration;					// duration for "fast" (rapid fire) shots
var float	FireFastPauseTime;					// time to wait between "fast" (rapid fire) shots
var float	FireSlowPauseTime;					// time to wait between "slow" (non-rapid fire) shots
var float	FireCheckFailedRate;				// rate at which to check for firing if previous check failed

// can be used to "fake" single notifies for melee/ranged attacks (but notifications should generally be used)
var float	MeleeNotifyTime;					// quick 'n dirty way to fake a melee notify (should use animation ultimately)
var float	RangedNotifyTime;					// quick 'n dirty way to fake a ranged notify (should use animation ultimately)

// for animation based attacks
var(AI) class<Projectile> RangedProjectileClass;
var(AI) vector FireOffset;

// basic melee attack support
var EWeaponAnimationType MeleeWeaponType;
var int Melee01MaxDamage;
var int Melee02MaxDamage;
var int Melee03MaxDamage;
var int Melee01MomentumPerUnitDamage;
var int Melee02MomentumPerUnitDamage;
var int Melee03MomentumPerUnitDamage;
var class<DamageType> Melee01DamageType;
var class<DamageType> Melee02DamageType;
var class<DamageType> Melee03DamageType;
var float MeleeDamageRangeMultiplier;			// amount to scale melee range by when checking for damage to target
var float MeleeDamageXMPPawnMultiplier;			// goose up melee damage to force fields & such
var float MeleeAccelRate;						// rate to scale Pawn's acceleration by when matching enemy's velocity during melee attack, 0.0 means use default AccelRate
var float MeleeSpeed;							// speed to scale Pawn's velocity by when matching enemy's velocity during melee attack, 0.0 means use current velocity, 1.0 means use full GroundSpeed
var float MeleeAccelerationChangeLimit;			// cosine of max angle acceleration is allowed to change by when matching enemy's acceleration
//var float MeleeShakeRadius;
//var float MeleeShakeMagnitude;
//var float MeleeShakeDuration;

// charging
var float ChargeMinDamage;
var float ChargeMaxDamage;
var float ChargeMaxMomentumTransfer;
var float ChargeMaxChangeSize;
var float ChargeHeadSize;

// stance
var float MinStationaryDistance;				// if Enemy within this distance, don't remain stationary (-1 ==> no effect)
var float MinCrouchDistance;					// if Enemy within this distance, shouldn't be crouching / prone
var float MinProneDistance;						// if Enemy within this distance, shouldn't be prone
var float MinStationaryHealth;					// if NPC health drops below this, don't remain stationary (-1 ==> ignore)

// impaling
var float ImpaleOdds;							// odds of impaling the enemy
var float ImpaleToMeleeOdds;					// odds of using impale behavior instead of melee attacks
var string ImpaleMountNode;						// node to attach victim to during impalification
// mib-tbd: use animation notifications with parameters and get rid of these?
var float ImpaleAttachDamage;					// damage to victim when impaling starts
var float ImpaleAttachShakeMag;					// how much / how long to shake the camera when sticking the victim
var float ImpaleAttachShakeSecs;
var float ImpaleDetachDamage;					// damage to victim when impaling ends
var float ImpaleDetachShakeMag;					// how much / how long to shake the camera when launching the victim
var float ImpaleDetachShakeSecs;
var float ImpaleDetachMomentum;					// velocity to impart on victim when impaling is done

var float MaxHuntFireAtLastSeenTime;			// controls how long NPC can shoot at last enemy seen position when hunting
var bool bAlertedEnemyHunted;					// set when the npc has alerted the enemy that its hunting

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

event PostBeginPlay()
{
	Super.PostBeginPlay();
	UpdateAttackRanges();
}

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

function UpdateAttackRanges()
{
	RangeMaxAttackMobile			= FMin( default.RangeMaxAttackMobile, SightRadius );
	RangeMaxAttackMobileNoLOS		= FMin( default.RangeMaxAttackMobileNoLOS, SightRadius );
	RangeMaxAttackStationary		= FMin( default.RangeMaxAttackStationary, SightRadius );
	RangeMaxAttackStationaryNoLOS	= FMin( default.RangeMaxAttackStationaryNoLOS, SightRadius );
	
	bHasMaxAttackRanges = 
		( RangeMinAttack > 0.0 ||
		  RangeMaxAttackMobile < default.RangeMaxAttackMobile  ||
		  RangeMaxAttackMobileNoLOS < default.RangeMaxAttackMobileNoLOS ||
		  RangeMaxAttackStationary < default.RangeMaxAttackStationary ||
		  RangeMaxAttackStationaryNoLOS < default.RangeMaxAttackStationaryNoLOS );
}

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

function SetSightRadius( float NewSightRadius )
{
	Super.SetSightRadius( NewSightRadius );
	UpdateAttackRanges();
}

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

function RestoreSightRadius()
{
	Super.RestoreSightRadius();
	UpdateAttackRanges();
}

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

function vector GetFireOffset()
{
	return class'UtilGame'.static.GetRotatedFireStart( Self, Location, Rotation, FireOffset );
}

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

function Projectile HandleSpawnShot( float ProjSpeed, bool bProjLeadTarget )
{
	local rotator FireRotation;
	local vector StartLocation;
	local Projectile SpawnedProjectile;
	
	/*
	DMTNS( "HandleSpawnShot:" );
	DumpAgentAnimInfo();
	AddActor( Self, ColorCyan() );
	*/

	#debug DMAIA( "HandleSpawnShot" );

	// uncomment return to disabled projectiles during testing
	//return;
	
	if( bHasRangedAttack )
	{
		StartLocation = GetFireOffset();
		
		//AddCylinder( StartLocation, 4, 4, ColorOrange() );
		
		if( Controller.AdjustAim( RangedProjectileClass, ProjSpeed, StartLocation, 0.0, bProjLeadTarget, false, (RangedProjectileClass.default.Physics == PHYS_Falling), bSplashDamageAttack ) )
		{
			FireRotation = GetAimRotation();

			/*
			#debugbegin
			if( DebugAIAttacks() )
			{
				AddCylinder( StartLocation, 16, 16, ColorCyan() );
				AddArrow( StartLocation, Controller.ControllerEnemy.Location, ColorGrey() );
				AddArrow( StartLocation, StartLocation + 1024.0*vector(FireRotation), ColorOrange() );
			}
			#debugend
			*/

			SpawnedProjectile = Spawn( RangedProjectileClass, Self, '', StartLocation, FireRotation );
			/*
			if( SpawnedProjectile == None )
			{
				DMTNS( "HandleSpawnShot -- failed to spawn projectile!" );
				class'U2GameInfo'.static.BSM( Self, "ALERT!" );
			}
			*/
			
			MakeNoise( 1.0 );
		}
		/*
		else
		{
			DMTNS( "HandleSpawnShot -- call to AdjustAim failed!" );
			class'U2GameInfo'.static.BSM( Self, "ALERT!" );
		}
		*/
	}
	
	return SpawnedProjectile;
}

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

function SpawnShot()
{
	HandleSpawnShot( RangedProjectileClass.default.Speed, bLeadTarget );
}

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

function FireAtEnemy()
{
	if( Controller != None )
        Controller.FireAt( Controller.ControllerEnemy );
}

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

function LicenseePawn.EWeaponAnimationType GetWeaponAnimationTypeW( Weapon Weap )
{
	// hack for melees which have wrong weapon extension
	if( Health > 0 && MeleeWeaponType != AT_None && U2NPCController(Controller) != None && U2NPCController(Controller).IsMeleeAttacking() )
		return MeleeWeaponType;
	else
		return Super.GetWeaponAnimationTypeW( Weap );
}

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

function HandleAcquireEnemySound()
{
	AssetsHelperClass.static.HandleAcquireEnemySound( Self );
}

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

function HandleLeapImpactSound()
{
	AssetsHelperClass.static.HandleLeapImpactSound( Self );
}

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

function HandleLeapLandSound()
{
	AssetsHelperClass.static.HandleLeapLandSound( Self );
}

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

function HandleMiscSound()
{
	AssetsHelperClass.static.HandleMiscSound( Self );
}

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

function NotifyMeleeMotionSound()
{
	AssetsHelperClass.static.HandleMeleeMotionSound( Self );
}

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

function MeleeDamagedTarget()
{
	AssetsHelperClass.static.HandleMeleeDamageSound( Self );
}

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

function float GetMeleeDamageRange()
{
	//!!mdf-tbd: this means you can damage enemy from further away than the melee range...
	//DMTNS( "GetMeleeDamageRange returning " $ MeleeDamageRangeMultiplier*MeleeRange );
	return ( MeleeDamageRangeMultiplier*MeleeRange );
}

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

function vector GetMeleeMomentumNormal( Actor TargetActor )
{
	return Normal( TargetActor.Location - Location );
}

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

function bool FilterMeleeAttack( Actor TargetActor )
{
	return false;
}

//-----------------------------------------------------------------------------
// Called by AI Controller when melee attack starts.

function NotifyMeleeBegin();

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

function MeleeDamageTarget( int Damage, int MomentumPerUnitDamage, class<DamageType> DamageType )
{
	local Actor TargetActor;
	local vector HitLocation, HitNormal;
	local Actor HitActor;
	local float DistanceToTarget;
	local float MeleeDamageRange;
	local float DamageMultiplier;

	if( Controller == None )
		return;
		
	// check if close enough to damage target
	TargetActor = Controller.GetTarget();
	MeleeDamageRange = GetMeleeDamageRange();
	//DMTNS( "MeleeDamageTarget  MeleeDamageRange: " $ MeleeDamageRange $ " Damage: " $ Damage );
	//DumpAgentAnimInfo();
	
	AssetsHelperClass.static.HandleMeleeImpactPointSound( Self );
	
	if( TargetActor != None && !FilterMeleeAttack( TargetActor ) )
	{
		if( U2NPCControllerShared(Controller).CheckMeleeAttackRange( TargetActor, MeleeDamageRange ) )
		{	
			// make sure nothing in the way
			HitActor = Trace( HitLocation, HitNormal, TargetActor.Location, Location, false );
			if( HitActor == None )
			{
				DistanceToTarget = class'Util'.static.GetDistanceBetweenActors( Self, TargetActor );
				DamageMultiplier = (MeleeDamageRange-DistanceToTarget)/MeleeDamageRange;
				Damage = FMax( 1.0, Damage * DamageMultiplier );
	
				//DMTNS( "MeleeDamageTarget damage check:" );
				//DMTNS( "   DistanceToTarget: " $ DistanceToTarget );
				//DMTNS( "   MeleeDamageRange: " $ MeleeDamageRange );
				//DMTNS( "   DamageMultiplier: " $ (MeleeDamageRange-DistanceToTarget)/MeleeDamageRange );
				//DMTNS( "   Damage:           " $ Damage );

				if( StationaryPawn(TargetActor) != None )
					Damage *= MeleeDamageXMPPawnMultiplier;

				HitLocation = TargetActor.Location; //!!mdf-tbd - ideally we'd refine this
				TargetActor.TakeDamage( Damage, Self, HitLocation, Damage*MomentumPerUnitDamage*GetMeleeMomentumNormal( TargetActor ), DamageType );
				U2NPCControllerShared(Controller).NotifyMeleeDamagedEnemy( Damage, Self, HitLocation, Damage*MomentumPerUnitDamage*GetMeleeMomentumNormal( TargetActor ), DamageType );
				
				/* !!mdf-tbd: we're doing this in the damage code already?
				if( MeleeShakeRadius > 0.0 && DamageMultiplier > 0.0 )
					class'UtilGame'.static.MakeShake( 
						Self, 
						Location, 
						MeleeShakeRadius*DamageMultiplier, 
						MeleeShakeMagnitude*DamageMultiplier, 
						MeleeShakeDuration*DamageMultiplier );
				*/
				
				MeleeDamagedTarget();
			}
		}
	}
}

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

function NotifyMelee01()
{
	MeleeDamageTarget( Melee01MaxDamage, Melee01MomentumPerUnitDamage, Melee01DamageType );
}

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

function NotifyMelee02()
{
	MeleeDamageTarget( Melee02MaxDamage, Melee02MomentumPerUnitDamage, Melee02DamageType );
}

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

function NotifyMelee03()
{
	MeleeDamageTarget( Melee03MaxDamage, Melee03MomentumPerUnitDamage, Melee03DamageType );
}

//-----------------------------------------------------------------------------
// Impale notifications - punt over to controller to manage.

function NotifyImpale()
{
	if( U2NPCControllerShared(Controller) != None )
		U2NPCControllerShared(Controller).ImpalePawn();
}

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

function NotifyUnImpale()
{
	if( U2NPCControllerShared(Controller) != None )
		U2NPCControllerShared(Controller).UnImpalePawn();
}

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

function NotifyLeapBegin()
{
	U2NPCController(Controller).ReflectNotify( U2NPCControllerBasic.LeapBeginNotify );
}

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

function NotifyStay01()
{
	U2NPCController(Controller).ReflectNotify( U2NPCControllerBasic.StayNotify );
}

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

defaultproperties
{
     AttackActiveBehaviors(0)=(StateName=AttackClose,Odds=1.000000,TimeMin=4.000000,TimeMax=4.000000)
     AttackActiveCantReachBehaviors(0)=(StateName=AttackStationary,Odds=1.000000,TimeMin=3.000000,TimeMax=3.000000)
     AttackActiveCantReachBehaviors(1)=(StateName=AttackTacticalMove,StateLabel=DontClose,Odds=1.000000,TimeMin=2.000000,TimeMax=2.000000)
     AttackActiveEnemyNotVisibleBehaviors(0)=(StateName=AttackHunt,Odds=1.000000,TimeMin=20.000000,TimeMax=20.000000)
     AttackActiveMeleeBehaviors(0)=(StateName=AttackMelee,TimeMin=3.000000,TimeMax=3.000000)
     AttackPassiveBehaviors(0)=(StateName=AttackMoveToCoverCombat,Odds=0.400000,TimeMin=7.000000,TimeMax=7.000000)
     AttackPassiveBehaviors(1)=(StateName=AttackStationary,Odds=0.060000,TimeMin=1.000000,TimeMax=3.000000)
     AttackPassiveBehaviors(2)=(StateName=AttackFallback,Odds=0.240000,TimeMin=2.500000,TimeMax=7.000000)
     AttackPassiveCantReachBehaviors(0)=(StateName=AttackStationary,Odds=0.500000,TimeMin=1.000000)
     AttackPassiveCantReachBehaviors(1)=(StateName=AttackFallback,Odds=1.000000,TimeMin=2.000000,TimeMax=7.000000)
     AttackPassiveEnemyNotVisibleBehaviors(0)=(StateName=AttackFallback,Odds=1.000000,TimeMin=20.000000,TimeMax=20.000000)
     AttackPassiveUseCoverBehaviors(0)=(StateName=AttackStakeOutCover,TimeMin=2.000000,TimeMax=5.000000)
     AttackPassiveUseCoverBehaviors(1)=(StateName=AttackRecoverEnemy,TimeMin=2.000000,TimeMax=4.000000)
     AttackPassiveUseCoverBehaviors(2)=(StateName=AttackStationary,TimeMin=1.000000,TimeMax=4.000000)
     AttackPassiveUseCoverBehaviors(3)=(StateName=AttackFallback,TimeMin=10.000000,TimeMax=20.000000)
     AttackPassiveUseCoverBehaviors(4)=(StateName=AttackMoveToCoverCombat,TimeMin=7.000000,TimeMax=7.000000)
     AttackPassiveMeleeBehaviors(0)=(StateName=AttackMelee,TimeMin=1.000000,TimeMax=2.000000)
     AttackPassiveMeleeBehaviors(1)=(StateName=AttackFallback,TimeMin=2.000000,TimeMax=5.000000)
	AttackCantFireLockoutTime=0.500000
	AttackMeleeMinTime=2.000000
	AttackMeleeMaxTime=5.000000
	AttackUseCoverMinTime=20.000000
	AttackUseCoverMaxTime=20.000000
	AttackUseCoverLockoutTime=3.000000
	AttackUseCoverTimeOutTime=10.000000
	RecoverLockOutUseCoverTime=3.000000
	MaxFleeSearchDistance=2048.000000
	MaxUseCoverSearchDistance=2048.000000
	bCanStrafeDuringTacticalRetreat=true
	bLeadTarget=true
	bFacePredictedLocation=true
	AttackClosingCanFireOdds=1.000000
	AttackClosingReachableDistSquared=1440000.000000
	AttackStationaryCanFireOdds=1.000000
	AttackTacticalMoveCanFireOdds=1.000000
	BaseAggressiveness=0.300000
	CombatStyle=0.600000
	RefireRate=0.200000
	StationaryStandOdds=1.000000
	StationaryStayCrouchingOdds=1.000000
	StationaryStayProneOdds=1.000000
	MinStayCrouchingTime=2.000000
	MinStayProneTime=3.000000
	MinReduceStanceAgainDelay=5.000000
	BounceProjectileOdds=1.000000
	BounceLifespan=2.000000
	MaxStationaryFiringDelay=0.250000
	MinAcquisitionDelay=1.000000
	MinAlertAcquisitionDelay=0.250000
	MinReAcquisitionDelay=0.500000
	bLeapRequiresLOS=true
	LeapHighPredictOdds=1.000000
	LeapLowPredictOdds=1.000000
	LeapMaxOdds=1.000000
	LeapDelayFailure=2.000000
	LeapDelayPreJump=0.250000
	LeapDelaySuccess=5.000000
	LeapNotifyTime=0.250000
	bJumpDodges=true
	PostDodgeDelay=0.250000
	DodgeTime=-0.655000
	DodgeDistance=300.000000
	JumpyOdds=0.330000
	bHasMovingRangedAttack=true
	MaxTacticalRetreatDistance=256.000000
	TacticalMoveCloseOdds=0.750000
	RangeMaxAttackMobile=65535.000000
	RangeMaxAttackMobileNoLOS=65535.000000
	RangeMaxAttackStationary=65535.000000
	RangeMaxAttackStationaryNoLOS=65535.000000
	FireCheckRate=1.000000
	FireFastDuration=1.000000
	FireFastPauseTime=1.000000
	FireSlowPauseTime=1.000000
	FireCheckFailedRate=0.500000
	Melee01MaxDamage=30
	Melee02MaxDamage=30
	Melee03MaxDamage=30
	Melee01MomentumPerUnitDamage=2500
	Melee02MomentumPerUnitDamage=2500
	Melee03MomentumPerUnitDamage=2500
	Melee01DamageType=Class'U2.DamageTypePhysical'
	Melee02DamageType=Class'U2.DamageTypePhysical'
	Melee03DamageType=Class'U2.DamageTypePhysical'
	MeleeDamageRangeMultiplier=1.400000
	MeleeAccelerationChangeLimit=-1.000000
	MinStationaryDistance=256.000000
	MinCrouchDistance=256.000000
	MinProneDistance=1024.000000
	MinStationaryHealth=30.000000
	MaxHuntFireAtLastSeenTime=3.000000
	WanderSpeedMax=1.500000
	WanderViewBlockedTurnOdds=0.500000
	bSentient=true
	bCanKnockDown=true
	MinKnockDownMomentumThreshold=200.000000
	bAmbientCreature=false
	ControllerClass=Class'U2AI.U2NPCControllerBasic'
     UseReticleOnEvents(0)="UseReticleText"
     UseReticleOnEvents(1)="UseReticleCorners"
     UseReticleOnEvents(2)="UseReticleSideBars"
     ProximityReticleOnEvents(0)="ProximityReticleCorners"
     ProximityReticleOnEvents(1)="ProximityReticleSideBars"
}

Overview Package Class Source Class tree Glossary
previous class      next class frames      no frames
Class file time: sk 3-1-2016 10:38:42.000 - Creation time: sk 3-1-2016 10:48:43.286 - Created with UnCodeX