//============================================================================= // SchlonzLivingBioGlob. //============================================================================= class SchlonzLivingBioGlob expands UT_BioGel; var int NumSplash; var() int MaxSplash; var() int detectionRadius; var int splashDamage; singular function TakeDamage( int NDamage, Pawn instigatedBy, Vector hitlocation, vector momentum, name damageType ) { /* no damage for now +++ if ( damageType == MyDamageType ) numBio = 3; GoToState('Exploding'); */ } function SetCharge( float charge ) { local int n; NumSplash = 0; n = charge * MaxSplash / 4.5 + MaxSplash / 10; if( n > MaxSplash ) { n = MaxSplash; } AddSplash( n ); } function AddSplash( int n ) { local float ds; NumSplash += n; if( NumSplash <= 0 ) { Destroy(); } else if( NumSplash > MaxSplash ) { BigBadaboom(); } else { DrawScale = 0.3 + 1.1 * sqrt(NumSplash); log( "### NS=" $ NumSplash $ " -> DS=" $ DrawScale ); SetCollisionSize( DrawScale, DrawScale ); } } function BigBadaboom() { local int i; local Vector dir; local SchlonzLivingBioGlob glob; i = 0; while( i < 50 ) { dir = VRand(); if( (dir dot SurfaceNormal) > 0.02 ) { if( i < 25 ) { glob = Spawn( class'SchlonzLivingBioGlob',,, Location + dir*20, Rotator(dir) ); glob.SetCharge( 0.0 ); } else { Spawn( class'SchlonzLivingBioSplash',,, Location + dir*20, Rotator(dir) ); } i++; } } GotoState( 'Exploding' ); } auto state Flying { function ProcessTouch (Actor Other, vector HitLocation) { if( Other.IsA('UT_BioGel') || Other.IsA('ut_GreenGelPuff') ) // +++++ can we add the load to the one at the wall ? return; if( Pawn(Other)!=Instigator || bOnGround) Global.Timer(); } simulated function HitWall( vector HitNormal, actor Wall ) { SetPhysics(PHYS_None); MakeNoise(1); bOnGround = True; PlaySound(ImpactSound); SetWall(HitNormal, Wall); splashDamage = Damage; AddSplash( 0 ); GoToState('OnSurface'); } } function SpawnSplash( Pawn p ) { local vector Start; local vector rot; local SchlonzLivingBioSplash splash; Start = Normal(p.Location - Location) * 10 + 2 * VRand(); splash = Spawn(class'SchlonzLivingBioSplash',,,Location+Start,Rotator(Start)); splash.setTarget( p ); if( Damage > splashDamage ) Damage -= splashDamage; } state OnSurface { function BeginState() { WallTime = 120.0; SetTimer(0.25, true); Disable( 'Tick' ); } function Timer() { local Pawn p; local int n; n = 0; foreach VisibleActors( class 'Pawn', p, detectionRadius ) { if( p != Instigator && NumSplash > 0 && p.Health > 0 && ( !Level.Game.bTeamGame || p.PlayerReplicationInfo == None || Instigator.PlayerReplicationInfo.Team != p.PlayerReplicationInfo.Team ) ) { SpawnSplash( p ); n++; } } AddSplash( -n ); } function ProcessTouch (Actor Other, vector HitLocation) { // log( "### touch " $ other.class.name $ " ###" ); if( Other.isA( 'SchlonzLivingBioGlob' ) ) { AddSplash( SchlonzLivingBioGlob(Other).NumSplash ); Other.Destroy(); return; } if ( Other.IsA('UT_BioGel') || Other.IsA('ut_GreenGelPuff') ) { // +++++ can we add the load to the one at the wall ? return; } if( Other.isA( 'Mover' ) ) { GoToState( 'Exploding' ); } if ( Pawn(Other)!=Instigator || bOnGround) { Global.Timer(); } } } defaultproperties { speed=2000.00000 detectionRadius=600 MaxSplash=250 LifeSpan=600.000000 }