aboutsummaryrefslogtreecommitdiff
path: root/Northstar.CustomServers/mod/scripts/vscripts/ai/_ai_marvins.gnut
blob: fc8b7d1ee9de0f98a70f487ef77c4c1179d08d7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
untyped

global function AiMarvins_Init


function AiMarvins_Init()
{
	FlagInit( "Disable_Marvins" )
	FlagSet( "Disable_Marvins" )

	level.livingMarvins <- {}
	AddSpawnCallback( "npc_marvin", LivingMarvinSpawned )

	AddCallback_EntitiesDidLoad( EntitiesDidLoad )
}

void function EntitiesDidLoad()
{
	if ( IsAutoPopulateEnabled() == false )
		return

	FlagEnd( "disable_npcs" )

	array<entity> marvin_spawners = GetEntArrayByClass_Expensive( "info_spawnpoint_marvin" )

	if ( !marvin_spawners.len() )
		return

	for ( ;; )
	{
		wait 3

		if ( !Flag( "Disable_Marvins" ) )
		{
			if ( TotalLivingMarvins() < 5 )
			{
				SpawnRandomMarvin( marvin_spawners )
			}
		}
	}
}

void function LivingMarvinSpawned( entity self )
{
	level.livingMarvins[ self ] <- self
}

function TotalLivingMarvins()
{
	local count = 0
	foreach ( entity marvin in clone level.livingMarvins )
	{
		if ( IsAlive( marvin ) )
		{
			count++
			continue
		}

		// cleanup dead marvins
		delete level.livingMarvins[ marvin ]
	}
	return count
}

entity function SpawnRandomMarvin( array<entity> marvin_spawners )
{
	marvin_spawners.randomize()
	entity spawnpoint = marvin_spawners[0] // if no valid spawn is found use this one
	for ( int i = 0; i < marvin_spawners.len(); i++ )
	{
		if ( IsMarvinSpawnpointValid( marvin_spawners[ i ] ) )
		{
			spawnpoint = marvin_spawners[ i ]
			break
		}
	}

	entity marvin = SpawnAmbientMarvin( spawnpoint )
	return marvin
}

bool function IsMarvinSpawnpointValid( entity spawnpoint )
{
	// ensure spawnpoint is not occupied (i.e. would spawn inside another player or object )
	if ( spawnpoint.IsOccupied() )
		return false

	bool visible = spawnpoint.IsVisibleToEnemies( TEAM_IMC ) || spawnpoint.IsVisibleToEnemies( TEAM_MILITIA )
	if ( visible )
		return false

	return true
}

entity function SpawnAmbientMarvin( entity spawnpoint )
{
	entity npc_marvin = CreateEntity( "npc_marvin" )
	SetTargetName( npc_marvin, UniqueString( "mp_random_marvin") )
	npc_marvin.SetOrigin( spawnpoint.GetOrigin() )
	npc_marvin.SetAngles( spawnpoint.GetAngles() )
	//npc_marvin.kv.rendercolor = "255 255 255"
	npc_marvin.kv.health = -1
	npc_marvin.kv.max_health = -1
	npc_marvin.kv.spawnflags = 516  // Fall to ground, Fade Corpse
	//npc_marvin.kv.FieldOfView = 0.5
	//npc_marvin.kv.FieldOfViewAlert = 0.2
	npc_marvin.kv.AccuracyMultiplier = 1.0
	npc_marvin.kv.physdamagescale = 1.0
	npc_marvin.kv.WeaponProficiency = eWeaponProficiency.GOOD

	Marvin_SetModels( npc_marvin, spawnpoint )

	DispatchSpawn( npc_marvin )

	SetTeam( npc_marvin, TEAM_UNASSIGNED )

	return npc_marvin
}

function Marvin_SetModels( entity npc_marvin, entity spawnpoint )
{
	//default
	npc_marvin.s.bodytype <- MARVIN_TYPE_WORKER

	// set body and head based on KVP
	if ( spawnpoint.HasKey( "bodytype" ) )
	{
		local bodytype = spawnpoint.GetValueForKey( "bodytype" ).tointeger()

		Assert( bodytype >= MARVIN_TYPE_SHOOTER && bodytype <= MARVIN_TYPE_FIREFIGHTER, "Specified invalid body type index " + bodytype + " for info_spawnpoint_marvin " + spawnpoint + ", Use values from 0-2 instead." )

		npc_marvin.s.bodytype = bodytype
	}


	if ( spawnpoint.HasKey( "headtype" ) )
	{
		local headtype = spawnpoint.GetValueForKey( "headtype" )
		npc_marvin.kv.body = headtype
	}
}