aboutsummaryrefslogtreecommitdiff
path: root/Northstar.Custom/mod/scripts/vscripts/sh_3psequence_to_1p_hacks.gnut
blob: 202e199a8c21ad46a64d5658dda75907d8411b49 (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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
global function FirstPersonSequenceForce1P_Init
global function FirstPersonSequenceForce1P_InitPlaylistVars

#if SERVER
	global function FirstPersonSequenceForce1P
#endif

#if CLIENT
	global function ServerCallback_HideHudForFPHackAnim
#endif

global const string FORCE1P_PILOT_1P_ATTACHMENT = "HEADFOCUS"
global const string FORCE1P_TITAN_1P_ATTACHMENT = "HATCH_HEAD" // CHEST_LASER could be better, but is only on atlas titans

global const string FORCE1P_PILOT_1P_HIDDEN_BODYGROUP = "head"
global const string FORCE1P_TITAN_1P_HIDDEN_BODYGROUP = "torso"

global const string FORCE1P_PILOT_ENTITYCLASS = "npc_pilot_elite"
global const string FORCE1P_TITAN_ENTITYCLASS = "npc_titan"

global struct Forced1PSequenceData
{
	entity player
	entity camera
	entity ownerProxy
	entity thirdPersonProxy
}

void function FirstPersonSequenceForce1P_Init()
{
	// atm do this no matter what playlist we're on since playlist overrides seem to get sent to clients after networkvar registration
	// not nice but whatever lol
	AddCallback_OnRegisteringCustomNetworkVars( FirstPersonSequenceForce1P_RegisterCustomNetworkFunctions )
}

void function FirstPersonSequenceForce1P_InitPlaylistVars()
{
	AddPrivateMatchModeSettingEnum( "#MODE_SETTING_CATEGORY_RIFF", "fp_embark_enabled", [ "Disabled", "Enabled" ], "0" )
}

void function FirstPersonSequenceForce1P_RegisterCustomNetworkFunctions()
{
	Remote_RegisterFunction( "ServerCallback_HideHudForFPHackAnim" )
}

#if SERVER
Forced1PSequenceData function FirstPersonSequenceForce1P( FirstPersonSequenceStruct sequence, entity player, entity other = null )
{
	string attachment = FORCE1P_PILOT_1P_ATTACHMENT
	string hiddenBodygroup = FORCE1P_PILOT_1P_HIDDEN_BODYGROUP
	string entityclass = FORCE1P_PILOT_ENTITYCLASS

	if ( player.IsTitan() )
	{
		attachment = FORCE1P_TITAN_1P_ATTACHMENT
		hiddenBodygroup = FORCE1P_TITAN_1P_HIDDEN_BODYGROUP	
		entityclass	= FORCE1P_TITAN_ENTITYCLASS
	}
			
	// hide player from everyone, unlike VisibilityFlags, this won't hide children, which is way easier to deal with
	player.Hide()
	
	Forced1PSequenceData cleanupData
	cleanupData.player = player
	
	// for some melee sequences, player.GetAngles() will be the angles the player had before they began the melee, which can cause desyncs
	// eyeangles are fine though
	vector angles = player.GetAngles()
	angles.y = player.EyeAngles().y
	
	// create the first proxy entity, this should visually be identical to the player, but only visible to them, and with head/torso hidden
	// this is an npc because some firstpersonsequences use animation features that only work on npcs and pilots, not props, so need to do this
	entity ownerProxy = CreateEntity( entityclass ) //CreatePropDynamic( player.GetModelName(), player.GetOrigin(), player.GetAngles() )
	ownerProxy.SetModel( player.GetModelName() )
	ownerProxy.SetValueForModelKey( player.GetModelName() )
	ownerProxy.SetOrigin( player.GetOrigin() )
	ownerProxy.SetAngles( angles )
	ownerProxy.kv.VisibilityFlags = ENTITY_VISIBLE_TO_OWNER
	ownerProxy.kv.solid = 0 // nonsolid
	SetTeam( ownerProxy, player.GetTeam() )
	ownerProxy.SetOwner( player )
	ownerProxy.SetSkin( player.GetSkin() )
	ownerProxy.SetCamo( player.GetCamo() ) // note: this seems weird, doesn't set right
	DispatchSpawn( ownerProxy )
	ownerProxy.SetModel( player.GetModelName() )
	ownerProxy.SetValueForModelKey( player.GetModelName() )
	ownerProxy.SetInvulnerable()
	HideName( ownerProxy )
	cleanupData.ownerProxy = ownerProxy
	
	int bodygroupValue = 1
	if ( hiddenBodygroup == "torso" )
		bodygroupValue = 2
	
	// hide annoying bodygroup
	ownerProxy.SetBodygroup( ownerProxy.FindBodyGroup( hiddenBodygroup ), bodygroupValue )
	// don't play anim until later so we can do cleanup stuff
		
	// create the second proxy entity, this visible to everyone else
	entity thirdPersonProxy = CreateEntity( entityclass ) //CreatePropDynamic( player.GetModelName(), player.GetOrigin(), player.GetAngles() )
	thirdPersonProxy.SetModel( player.GetModelName() )
	thirdPersonProxy.SetValueForModelKey( player.GetModelName() )
	thirdPersonProxy.SetOrigin( player.GetOrigin() )
	thirdPersonProxy.SetAngles( angles )
	thirdPersonProxy.kv.VisibilityFlags = ENTITY_VISIBLE_TO_EVERYONE & ~ENTITY_VISIBLE_TO_OWNER
	thirdPersonProxy.kv.solid = 0 // nonsolid
	SetTeam( thirdPersonProxy, player.GetTeam() )
	thirdPersonProxy.SetOwner( player )
	thirdPersonProxy.SetSkin( player.GetSkin() )
	thirdPersonProxy.SetCamo( player.GetCamo() ) // note: this seems weird, doesn't set right
	DispatchSpawn( thirdPersonProxy	)
	thirdPersonProxy.SetModel( player.GetModelName() )
	thirdPersonProxy.SetValueForModelKey( player.GetModelName() )
	thirdPersonProxy.SetInvulnerable()
	HideName( thirdPersonProxy )
	cleanupData.thirdPersonProxy = thirdPersonProxy
	
	if ( player.IsTitan() )
		Highlight_SetEnemyHighlight( thirdPersonProxy, "enemy_titan" )
	else
		Highlight_SetEnemyHighlight( thirdPersonProxy, "enemy_player" )
	
	thread FirstPersonSequence( sequence, thirdPersonProxy, other )
	
	// create the viewpoint entity
	entity camera = CreateEntity( "point_viewcontrol" )
	camera.SetParent( ownerProxy, attachment )
	camera.kv.spawnflags = 56
	DispatchSpawn( camera )
	player.SetViewEntity( camera, true )
	cleanupData.camera = camera
	
	// note for potential thing that could be done
	// entity e = CreatePropDynamic($"models/weapons/arms/pov_titan_light_cockpit.mdl"); e.SetParent(GetPlayerArray()[0].GetPetTitan(), "HATCH_HEAD"); e.SetOrigin(<0.75,0,-195>)
	// this is so we get a cockpit in these anims, issue with it is that the cockpit seems to break alot of rendering stuff
	// which really sucks since it'd be awesome to have a cockpit over these anims, really makes them better, even the client func to render through cockpits doesn't seem to work for it, just makes stuff rendering through the cockpit invisible rather than rendering in a broken way
	
	Remote_CallFunction_NonReplay( player, "ServerCallback_HideHudForFPHackAnim" )
	// play this anim now, so we can cleanup after it's done
	thread CleanupForced1PSequenceAfterAnimDone( sequence, ownerProxy, other, cleanupData )
	return cleanupData
}

void function CleanupForced1PSequenceAfterAnimDone( FirstPersonSequenceStruct sequence, entity player, entity other, Forced1PSequenceData cleanupData )
{
	player.EndSignal( "OnDestroy" )
	player.EndSignal( "OnAnimationDone" )

	OnThreadEnd( function() : ( cleanupData )
	{
		CleanupForced1PSequence( cleanupData )
	})

	FirstPersonSequence( sequence, player, other )
}

void function CleanupForced1PSequence( Forced1PSequenceData cleanupData )
{
	cleanupData.player.Show()
	cleanupData.player.ClearViewEntity()
	cleanupData.camera.Destroy()
	cleanupData.ownerProxy.Destroy()
	cleanupData.thirdPersonProxy.Destroy()
}
#endif

#if CLIENT
void function ServerCallback_HideHudForFPHackAnim()
{
	// these functions just set hud positions to infront of/behind the camera, manually set them up here so they'll be far enough away so we don't see them in these anims
	// in an ideal world we wouldn't even have to turn off this rui stuff because it would be parented to our camera but unfortunately we do not live in an ideal world
	//thread MainHud_TurnOff_RUI( true )
	//HidePermanentCockpitRui()
	RuiTopology_UpdatePos( clGlobal.topoCockpitHud, < -1000, -1000, -1000 >, < -1000, -1000, -1000 >, < -1000, -1000, -1000 > )
	RuiTopology_UpdatePos( clGlobal.topoCockpitHudPermanent, < -1000, -1000, -1000 >, < -1000, -1000, -1000 >, < -1000, -1000, -1000 > )
		
	thread EnableHudOnViewRestored()
}

void function EnableHudOnViewRestored()
{
	while ( GetViewEntity() != GetLocalClientPlayer() )
		WaitFrame()
	
	thread MainHud_TurnOn_RUI( true )
	ShowPermanentCockpitRui()
}
#endif