aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_faces.gnut
diff options
context:
space:
mode:
Diffstat (limited to 'Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_faces.gnut')
-rw-r--r--Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_faces.gnut226
1 files changed, 226 insertions, 0 deletions
diff --git a/Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_faces.gnut b/Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_faces.gnut
new file mode 100644
index 000000000..e6d3bcf0a
--- /dev/null
+++ b/Northstar.CustomServers/scripts/vscripts/ai/_ai_marvin_faces.gnut
@@ -0,0 +1,226 @@
+untyped
+
+global function MarvinFaces_Init
+
+global function MarvinFace
+global function MarvinThinksAwhile
+global function MarvinFaceExists
+global function SetMarvinBodyType
+global function MarvinSetFace
+
+function MarvinFaces_Init()
+{
+
+ RegisterSignal( "StopThinking" )
+
+ AddSpawnCallback( "npc_marvin", MarvinSpawnCallback )
+
+ SetupMarvinFaces()
+}
+
+function SetupMarvinFaces()
+{
+ // setup marvin face mappings
+ level.marvinFaces <- {}
+ level.marvinFaces[ MARVIN_TYPE_WORKER ] <-
+ {
+ none = 0
+ happy = 1
+ sad = 2
+ angry = 3
+ think1 = 4
+ think2 = 5
+ question = 6
+ }
+
+ // Use the yellow worker marvin skins since shooters are from SP and shooter value = 0 which is LevelEd's default.
+ // Real shooter skins are 7-13. If we want real skins, we can add them here and adjust the marvin spawn points per level.
+ level.marvinFaces[ MARVIN_TYPE_SHOOTER ] <-
+ {
+ none = 0
+ happy = 1
+ sad = 2
+ angry = 3
+ think1 = 4
+ think2 = 5
+ question = 6
+ }
+
+ level.marvinFaces[ MARVIN_TYPE_FIREFIGHTER ] <-
+ {
+ none = 14
+ happy = 15
+ sad = 16
+ angry = 17
+ think1 = 18
+ think2 = 19
+ question = 20
+ }
+
+ // No idea what this type of marvin is...legacy stuff. Just make them yellow.
+ level.marvinFaces[ MARVIN_TYPE_MARVINONE ] <-
+ {
+ none = 0
+ happy = 1
+ sad = 2
+ angry = 3
+ think1 = 4
+ think2 = 5
+ question = 6
+ }
+
+// Nothing uses this except debug statements that are commented out
+/*
+ level.marvinFaceNames <- {}
+ // invert map for tests
+ foreach ( key, val in level.marvinFace )
+ {
+ level.marvinFaceNames[ val ] <- key
+ }
+*/
+}
+
+void function MarvinFace( entity marvin )
+{
+ thread MarvinFaceThink( marvin )
+}
+
+void function MarvinFaceThink( entity marvin )
+{
+ //printl( "Setting up marvin face for " + marvin )
+ for ( ;; )
+ {
+ waitthread MarvinUndamagedFacePicker( marvin )
+
+// printl( "damaged " + marvin )
+ if ( !IsAlive( marvin ) )
+ break
+
+ waitthread MarvinWounded( marvin )
+
+ if ( !IsAlive( marvin ) )
+ break
+ }
+
+ if ( IsValid_ThisFrame( marvin ) )
+ MarvinSetFace( marvin, "none" )
+}
+
+function MarvinWounded( marvin )
+{
+ marvin.EndSignal( "OnDeath" )
+ MarvinSetFace( marvin, "sad" )
+ wait 2.3
+ waitthread MarvinThinksAwhile( marvin, RandomFloatRange( 2, 4 ) )
+}
+
+void function EntSignals( entity ent, string signal )
+{
+ if ( IsValid_ThisFrame( ent ) )
+ ent.Signal( signal )
+}
+
+function MarvinThinksAwhile( marvin, time )
+{
+ expect entity( marvin )
+
+ marvin.EndSignal( "StopThinking" )
+ delaythread( time ) EntSignals( marvin, "StopThinking" )
+
+ // think for a bit
+ for ( ;; )
+ {
+ MarvinSetFace( marvin, "think1" )
+ wait 0.4
+ MarvinSetFace( marvin, "think2" )
+ wait 0.4
+ }
+}
+
+function MarvinUndamagedFacePicker( marvin )
+{
+ marvin.EndSignal( "OnDeath" )
+ marvin.EndSignal( "OnDamaged" )
+ local i
+
+ for ( ;; )
+ {
+ if ( !marvin.GetEnemy() )
+ {
+ MarvinSetFace( marvin, "happy" )
+ marvin.WaitSignal( "OnFoundEnemy" )
+ }
+
+ waitthread MarvinThinksAwhile( marvin, RandomFloatRange( 2, 4 ) )
+
+ if ( marvin.GetEnemy() )
+ {
+ MarvinSetFace( marvin, "angry" )
+ marvin.WaitSignal( "OnLostEnemy" )
+ }
+ }
+}
+
+function MarvinSetFace( self, face )
+{
+// printl( self + " got face " + face )
+ Assert( MarvinFaceExists( self, face ), "No face " + face + " in level.marvinFace" )
+
+ //prin( "Changing " + self + " face from " + level.marvinFaceNames[ skin ] + " to " + face )
+ self.SetSkin( GetMarvinFace( self, face ) )
+ self.Signal( "StopThinking" )
+}
+
+function MarvinFaceExists( npc_marvin, face )
+{
+ local marvinType = GetMarvinBodyType( npc_marvin )
+
+ if ( marvinType in level.marvinFaces )
+ return true
+
+// return ( face in level.marvinFaces[ marvinType ] )
+}
+
+function GetMarvinFace( npc_marvin, face )
+{
+ local marvinType = GetMarvinBodyType( npc_marvin )
+
+ Assert( MarvinFaceExists( npc_marvin, face ), "No face " + face + " in level.marvinFace" )
+
+ local faceID = level.marvinFaces[ marvinType ][ face ]
+
+ return faceID
+}
+
+function SetMarvinBodyType( npc_marvin )
+{
+ if( "bodytype" in npc_marvin.s )
+ {
+ Assert( npc_marvin.s.bodytype >= MARVIN_TYPE_SHOOTER && npc_marvin.s.bodytype <= MARVIN_TYPE_FIREFIGHTER, "Specified invalid body type index " + npc_marvin.s.bodytype + ", Use values from 0-2 instead." )
+
+ switch( npc_marvin.s.bodytype )
+ {
+ case MARVIN_TYPE_FIREFIGHTER:
+ local index = npc_marvin.FindBodyGroup( "firefighter" )
+ local state = 1
+ npc_marvin.SetBodygroup( index, state )
+ break
+ }
+ }
+}
+
+function GetMarvinBodyType( npc_marvin )
+{
+ local bodyType = MARVIN_TYPE_WORKER
+
+ if( "bodytype" in npc_marvin.s )
+ bodyType = npc_marvin.s.bodytype
+
+ return bodyType
+}
+
+void function MarvinSpawnCallback( entity npc_marvin )
+{
+ SetMarvinBodyType( npc_marvin )
+ npc_marvin.SetDeathNotifications( true ) //Primarily so we can do HandleDeathPackage for Marvins. Can just add a deathcallback if this is too expensive
+}