Core.Object | +--Engine.Actor | +--Engine.Pawn | +--UnrealShare.ScriptedPawn | +--UnrealShare.DevilFish
float
AirTime
bool
bAttackBump
var()
byte
eAttitude
AttitudeToCreature(Pawn Other)
void
Landed(vector HitNormal)
PlayDying(name DamageType, vector HitLocation)
PlayInAir()
PlayLanded(float impactVel)
PlayMeleeAttack()
PlayPatrolStop()
PlayRunning()
PlayTakeHit(float tweentime, vector HitLoc, int damage)
PlayThreatening()
PlayTurning()
PlayVictoryDance()
PlayWaiting()
PlayWaitingAmbush()
PlayWalking()
PreSetMovement()
SetMovementPhysics()
TweenToFalling()
TweenToFighter(float tweentime)
TweenToPatrolStop(float tweentime)
TweenToRunning(float tweentime)
TweenToWaiting(float tweentime)
TweenToWalking(float tweentime)
WhatToDoNext(name LikelyState, name LikelyLabel)
//----------------------------------------------------------------------------- // RazorFish functions.
ZoneChange(ZoneInfo newZone)
Bump(Actor Other)
PickDestination(bool bNoCharge)
AnimEnd()
ZoneChange(ZoneInfo NewZone)
Timer()
KeepAttacking()
00001 //============================================================================= 00002 // DevilFish. 00003 //============================================================================= 00004 class DevilFish extends ScriptedPawn; 00005 00006 #exec MESH IMPORT MESH=fish ANIVFILE=MODELS\fish_a.3D DATAFILE=MODELS\fish_d.3D X=0 Y=0 Z=0 00007 #exec MESH ORIGIN MESH=fish X=0 Y=30 Z=0 YAW=64 PITCH=0 ROLL=-64 00008 00009 #exec MESH SEQUENCE MESH=fish SEQ=All STARTFRAME=0 NUMFRAMES=102 00010 #exec MESH SEQUENCE MESH=fish SEQ=bite1 STARTFRAME=0 NUMFRAMES=10 RATE=45 Group=Attack 00011 #exec MESH SEQUENCE MESH=fish SEQ=bite2 STARTFRAME=10 NUMFRAMES=10 RATE=45 Group=Attack 00012 #exec MESH SEQUENCE MESH=fish SEQ=bite3 STARTFRAME=20 NUMFRAMES=10 RATE=45 Group=Attack 00013 #exec MESH SEQUENCE MESH=fish SEQ=breathing STARTFRAME=30 NUMFRAMES=6 RATE=6 00014 #exec MESH SEQUENCE MESH=fish SEQ=dead1 STARTFRAME=36 NUMFRAMES=18 RATE=15 00015 #exec MESH SEQUENCE MESH=fish SEQ=flopping STARTFRAME=54 NUMFRAMES=20 00016 #exec MESH SEQUENCE MESH=fish SEQ=grab1 STARTFRAME=74 NUMFRAMES=5 Group=Attack 00017 #exec MESH SEQUENCE MESH=fish SEQ=ripper STARTFRAME=79 NUMFRAMES=13 RATE=25 Group=Attack 00018 #exec MESH SEQUENCE MESH=fish SEQ=Swimming STARTFRAME=92 NUMFRAMES=10 RATE=20 00019 #exec MESH SEQUENCE MESH=fish SEQ=fighter STARTFRAME=0 NUMFRAMES=10 00020 #exec MESH SEQUENCE MESH=fish SEQ=takehit STARTFRAME=36 NUMFRAMES=1 00021 00022 #exec TEXTURE IMPORT NAME=Jfish1 FILE=MODELS\shark.PCX GROUP=Skins 00023 #exec MESHMAP SCALE MESHMAP=fish X=0.085 Y=0.085 Z=0.17 00024 #exec MESHMAP SETTEXTURE MESHMAP=fish NUM=1 TEXTURE=Jfish1 00025 00026 #exec AUDIO IMPORT FILE="Sounds\Devilfish\ambfs.WAV" NAME="ambfs" GROUP="Razorfish" 00027 #exec AUDIO IMPORT FILE="Sounds\Devilfish\chomp1fs.WAV" NAME="chomp1fs" GROUP="Razorfish" 00028 #exec AUDIO IMPORT FILE="Sounds\Devilfish\death1fs.WAV" NAME="death1fs" GROUP="Razorfish" 00029 #exec AUDIO IMPORT FILE="Sounds\Devilfish\flop1fs.WAV" NAME="flop1fs" GROUP="Razorfish" 00030 #exec AUDIO IMPORT FILE="Sounds\Devilfish\tear1fs.WAV" NAME="tear1fs" GROUP="Razorfish" 00031 #exec AUDIO IMPORT FILE="Sounds\Devilfish\miss1fs.WAV" NAME="miss1fs" GROUP="Razorfish" 00032 #exec AUDIO IMPORT FILE="Sounds\Devilfish\breath1fs.WAV" NAME="breath1fs" GROUP="Razorfish" 00033 00034 //----------------------------------------------------------------------------- 00035 // RazorFish variables. 00036 00037 // Attack damage. 00038 var() byte 00039 BiteDamage, // Basic damage done by bite. 00040 RipDamage; 00041 var bool bAttackBump; 00042 var(Sounds) sound bite; 00043 var(Sounds) sound rip; 00044 var float AirTime; 00045 00046 //----------------------------------------------------------------------------- 00047 // RazorFish functions. 00048 00049 function WhatToDoNext(name LikelyState, name LikelyLabel) 00050 { 00051 bStasis = true; 00052 Super.WhatToDoNext(LikelyState, LikelyLabel); 00053 } 00054 00055 function ZoneChange(ZoneInfo newZone) 00056 { 00057 local vector start, checkpoint, HitNormal, HitLocation; 00058 local actor HitActor; 00059 00060 if ( newZone.bWaterZone ) 00061 { 00062 AirTime = 0; 00063 setPhysics(PHYS_Swimming); 00064 } 00065 else 00066 { 00067 SetPhysics(PHYS_Falling); 00068 MoveTimer = -1.0; 00069 } 00070 } 00071 00072 function Landed(vector HitNormal) 00073 { 00074 GotoState('Flopping'); 00075 Landed(HitNormal); 00076 } 00077 00078 function PreSetMovement() 00079 { 00080 bCanJump = true; 00081 bCanWalk = false; 00082 bCanSwim = true; 00083 bCanFly = false; 00084 MinHitWall = -0.6; 00085 bCanOpenDoors = false; 00086 bCanDoSpecial = false; 00087 } 00088 00089 function SetMovementPhysics() 00090 { 00091 if (Region.Zone.bWaterZone) 00092 SetPhysics(PHYS_Swimming); 00093 else 00094 { 00095 SetPhysics(PHYS_Falling); 00096 MoveTimer = -1.0; 00097 GotoState('Flopping'); 00098 } 00099 } 00100 00101 function eAttitude AttitudeToCreature(Pawn Other) 00102 { 00103 if ( Other.IsA('Devilfish') ) 00104 return ATTITUDE_Friendly; 00105 else if ( Other.IsA('ScriptedPawn') ) 00106 return ATTITUDE_Hate; 00107 else 00108 return ATTITUDE_Ignore; 00109 } 00110 00111 function PlayWaiting() 00112 { 00113 LoopAnim('Swimming', 0.1 + 0.3 * FRand()); 00114 } 00115 00116 function PlayPatrolStop() 00117 { 00118 LoopAnim('Swimming', 0.1 + 0.3 * FRand()); 00119 } 00120 00121 function PlayWaitingAmbush() 00122 { 00123 LoopAnim('Swimming', 0.1 + 0.3 * FRand()); 00124 } 00125 00126 function TweenToFighter(float tweentime) 00127 { 00128 TweenAnim('Fighter', tweentime); 00129 } 00130 00131 function TweenToRunning(float tweentime) 00132 { 00133 if ( (AnimSequence != 'Swimming') || !bAnimLoop ) 00134 TweenAnim('Swimming', tweentime); 00135 } 00136 00137 function TweenToWalking(float tweentime) 00138 { 00139 if ( (AnimSequence != 'Swimming') || !bAnimLoop ) 00140 TweenAnim('Swimming', tweentime); 00141 } 00142 00143 function TweenToWaiting(float tweentime) 00144 { 00145 PlayAnim('Swimming', 0.2 + 0.8 * FRand()); 00146 } 00147 00148 function TweenToPatrolStop(float tweentime) 00149 { 00150 TweenAnim('Swimming', tweentime); 00151 } 00152 00153 function PlayRunning() 00154 { 00155 LoopAnim('Swimming', -0.8/WaterSpeed,, 0.4); 00156 } 00157 00158 function PlayWalking() 00159 { 00160 LoopAnim('Swimming', -0.8/WaterSpeed,, 0.4); 00161 } 00162 00163 function PlayThreatening() 00164 { 00165 if ( FRand() < 0.5 ) 00166 PlayAnim('Swimming', 0.4); 00167 else 00168 PlayAnim('Fighter', 0.4); 00169 } 00170 00171 function PlayTurning() 00172 { 00173 LoopAnim('Swimming', 0.8); 00174 } 00175 00176 function PlayDying(name DamageType, vector HitLocation) 00177 { 00178 if ( Region.Zone.bWaterZone ) 00179 { 00180 PlaySound(Die, SLOT_Talk, 4 * TransientSoundVolume); 00181 PlayAnim('Dead1', 0.7, 0.1); 00182 } 00183 else 00184 TweenAnim('Breathing', 0.35); 00185 } 00186 00187 function PlayTakeHit(float tweentime, vector HitLoc, int damage) 00188 { 00189 TweenAnim('TakeHit', tweentime); 00190 } 00191 00192 function TweenToFalling() 00193 { 00194 TweenAnim('Flopping', 0.2); 00195 } 00196 00197 function PlayInAir() 00198 { 00199 LoopAnim('Flopping', 0.7); 00200 } 00201 00202 function PlayLanded(float impactVel) 00203 { 00204 TweenAnim('breathing', 0.2); 00205 } 00206 00207 00208 function PlayVictoryDance() 00209 { 00210 PlayAnim('ripper', 0.6, 0.1); 00211 } 00212 00213 function PlayMeleeAttack() 00214 { 00215 local vector adjust; 00216 local float decision; 00217 adjust = vect(0,0,0.5) * FRand() * Target.CollisionHeight; 00218 Acceleration = AccelRate * Normal(Target.Location - Location + adjust); 00219 bAttackBump = false; 00220 if (AnimSequence == 'Grab1') 00221 { 00222 PlayAnim('ripper', 0.5 + 0.5 * FRand()); 00223 PlaySound(rip,SLOT_Interact,,,500); 00224 MeleeDamageTarget(RipDamage, vect(0,0,0)); 00225 Disable('Bump'); 00226 return; 00227 } 00228 decision = FRand(); 00229 PlaySound(bite,SLOT_Interact,,,500); 00230 if (decision < 0.3) 00231 { 00232 Disable('Bump'); 00233 PlayAnim('Grab1', 0.3); 00234 return; 00235 } 00236 00237 Enable('Bump'); 00238 //log("Start Melee Attack"); 00239 if (decision < 0.55) 00240 { 00241 PlayAnim('Bite1', 0.3); 00242 } 00243 else if (decision < 0.8) 00244 { 00245 PlayAnim('Bite2', 0.3); 00246 } 00247 else 00248 { 00249 PlayAnim('Bite3', 0.3); 00250 } 00251 } 00252 00253 state Waiting 00254 { 00255 function Landed(vector HitNormal) 00256 { 00257 GotoState('Flopping'); 00258 Landed(HitNormal); 00259 } 00260 } 00261 00262 state TakeHit 00263 { 00264 ignores seeplayer, hearnoise, bump, hitwall; 00265 00266 function Landed(vector HitNormal) 00267 { 00268 GotoState('Flopping'); 00269 Landed(HitNormal); 00270 } 00271 } 00272 00273 state FallingState 00274 { 00275 ignores Bump, Hitwall, HearNoise, WarnTarget; 00276 00277 function Landed(vector HitNormal) 00278 { 00279 GotoState('Flopping'); 00280 Landed(HitNormal); 00281 } 00282 } 00283 00284 state Ambushing 00285 { 00286 function Landed(vector HitNormal) 00287 { 00288 GotoState('Flopping'); 00289 Landed(HitNormal); 00290 } 00291 } 00292 00293 state MeleeAttack 00294 { 00295 ignores SeePlayer, HearNoise; 00296 00297 singular function Bump(actor Other) 00298 { 00299 Disable('Bump'); 00300 if ( (AnimSequence == 'Bite1') || (AnimSequence == 'Bite2') || (AnimSequence == 'Bite3') ) 00301 MeleeDamageTarget(BiteDamage, (BiteDamage * 1000.0 * Normal(Target.Location - Location))); 00302 else 00303 return; 00304 bAttackBump = true; 00305 Velocity *= -0.5; 00306 Acceleration *= -1; 00307 if (Acceleration.Z < 0) 00308 Acceleration.Z *= -1; 00309 } 00310 00311 function KeepAttacking() 00312 { 00313 if ( (Target == None) || 00314 ((Pawn(Target) != None) && (Pawn(Target).Health == 0)) ) 00315 GotoState('Attacking'); 00316 else if ( bAttackBump && (FRand() < 0.5) ) 00317 { 00318 SetTimer(TimeBetweenAttacks, false); 00319 GotoState('TacticalMove', 'NoCharge'); 00320 } 00321 } 00322 } 00323 00324 00325 State Flopping 00326 { 00327 ignores seeplayer, hearnoise, enemynotvisible, hitwall; 00328 00329 function Timer() 00330 { 00331 AirTime += 1; 00332 if ( AirTime > 25 + 15 * FRand() ) 00333 { 00334 Health = -1; 00335 Died(None, 'suffocated', Location); 00336 return; 00337 } 00338 SetPhysics(PHYS_Falling); 00339 Velocity = 200 * VRand(); 00340 Velocity.Z = 170 + 200 * FRand(); 00341 DesiredRotation.Pitch = Rand(8192) - 4096; 00342 DesiredRotation.Yaw = Rand(65535); 00343 TweenAnim('Flopping', 0.1); 00344 } 00345 00346 function ZoneChange( ZoneInfo NewZone ) 00347 { 00348 local rotator newRotation; 00349 if (NewZone.bWaterZone) 00350 { 00351 newRotation = Rotation; 00352 newRotation.Roll = 0; 00353 SetRotation(newRotation); 00354 SetPhysics(PHYS_Swimming); 00355 AirTime = 0; 00356 GotoState('Attacking'); 00357 } 00358 else 00359 SetPhysics(PHYS_Falling); 00360 } 00361 00362 function Landed(vector HitNormal) 00363 { 00364 local rotator newRotation; 00365 SetPhysics(PHYS_None); 00366 SetTimer(0.3 + 0.3 * AirTime * FRand(), false); 00367 newRotation = Rotation; 00368 newRotation.Pitch = 0; 00369 newRotation.Roll = Rand(16384) - 8192; 00370 DesiredRotation.Pitch = 0; 00371 SetRotation(newRotation); 00372 PlaySound(land,SLOT_Interact,,,400); 00373 TweenAnim('Breathing', 0.3); 00374 } 00375 00376 function AnimEnd() 00377 { 00378 if (Physics == PHYS_None) 00379 { 00380 if (AnimSequence == 'Breathing') 00381 { 00382 PlaySound(sound'breath1fs',SLOT_Interact,,,300); 00383 PlayAnim('Breathing'); 00384 } 00385 else 00386 TweenAnim('Breathing', 0.2); 00387 } 00388 else 00389 PlayAnim('Flopping', 0.7); 00390 } 00391 } 00392 00393 00394 state TacticalMove 00395 { 00396 function PickDestination(bool bNoCharge) 00397 { 00398 local vector pick, pickdir, enemydir,Y, minDest; 00399 local float Aggression, enemydist, minDist, strafeSize; 00400 local bool success; 00401 00402 success = false; 00403 enemyDist = VSize(Location - Enemy.Location); 00404 Aggression = 2 * (CombatStyle + FRand()) - 1.0; 00405 00406 if (enemyDist < CollisionRadius + Enemy.CollisionRadius + MeleeRange) 00407 Aggression -= 1; 00408 else if (enemyDist > FMax(VSize(OldLocation - Enemy.OldLocation), 240)) 00409 Aggression += 0.4 * FRand(); 00410 00411 enemydir = (Enemy.Location - Location)/enemyDist; 00412 if ( !enemy.Region.Zone.bWaterZone ) 00413 enemydir.Z *= 0.5; 00414 minDist = FMin(160.0, 3*CollisionRadius); 00415 00416 Y = (enemydir Cross vect(0,0,1)); 00417 00418 strafeSize = FMin(1.0, (2 * Abs(Aggression) * FRand() - 0.2)); 00419 if (Aggression < 0) 00420 strafeSize *= -1; 00421 enemydir = enemydir * strafeSize; 00422 enemydir.Z = FMax(0,enemydir.Z); 00423 strafeSize = FMax(0.0, 1 - Abs(strafeSize)); 00424 pickdir = strafeSize * Y; 00425 pick = Location + (pickdir + enemydir) * (minDist + 500 * FRand()); 00426 minDest = Location + minDist * (pickdir + enemydir); 00427 if (pointReachable(minDest)) 00428 { 00429 success = true; 00430 Destination = pick; 00431 } 00432 00433 if (!success) 00434 { 00435 pick = Location + (enemydir - pickdir) * (minDist + 500 * FRand()); 00436 pick.Z = Location.Z; 00437 minDest = Location + minDist * (enemydir - pickdir); 00438 if (pointReachable(minDest)) 00439 { 00440 success = true; 00441 Destination = pick; 00442 } 00443 } 00444 00445 if (!success) 00446 { 00447 pick = Location - enemydir * (minDist + 500 * FRand()); 00448 pick.Z = Location.Z + 200 * FRand() - 100; 00449 } 00450 } 00451 00452 00453 function Bump(Actor Other) 00454 { 00455 Disable('Bump'); 00456 if (bAttackBump == true) 00457 bAttackBump = false; 00458 else if (Other == Enemy) 00459 { 00460 bReadyToAttack = true; 00461 Target = Enemy; 00462 GotoState('MeleeAttack'); 00463 } 00464 else if (Enemy.Health <= 0) 00465 GotoState('Attacking'); 00466 } 00467 } 00468 00469 defaultproperties 00470 { 00471 BiteDamage=15 00472 RipDamage=25 00473 rip=Sound'UnrealShare.Razorfish.tear1fs' 00474 CarcassType=Class'UnrealShare.DevilfishCarcass' 00475 TimeBetweenAttacks=0.500000 00476 Aggressiveness=1.000000 00477 MeleeRange=40.000000 00478 WaterSpeed=250.000000 00479 Visibility=120 00480 SightRadius=1250.000000 00481 Health=70 00482 UnderWaterTime=-1.000000 00483 Intelligence=BRAINS_NONE 00484 HitSound1=Sound'UnrealShare.Razorfish.chomp1fs' 00485 HitSound2=Sound'UnrealShare.Razorfish.miss1fs' 00486 Land=Sound'UnrealShare.Razorfish.flop1fs' 00487 Die=Sound'UnrealShare.Razorfish.death1fs' 00488 CombatStyle=1.000000 00489 AmbientSound=Sound'UnrealShare.Razorfish.ambfs' 00490 DrawType=DT_Mesh 00491 Mesh=LodMesh'UnrealShare.fish' 00492 CollisionRadius=35.000000 00493 CollisionHeight=20.000000 00494 Mass=60.000000 00495 Buoyancy=60.000000 00496 RotationRate=(Pitch=8192,Roll=8192) 00497 }