Bug in "game_ui" entity - How to fix?

There is a bug in the game_ui entity.

When the player is killed, it doesn’t remove the player from controlling the game_ui and doesn’t allow the player to properly spectate and let others use the game_ui. Courtesy of the question megathread I’ve gotten around this by using a trigger volume to check if the player controlling it is still there and alive, and if not, it deactivates the game_ui. That’s all working well.

However, when the player is killed while using the game_ui, it doesn’t allow the player to properly spectate. The spectate camera is stuck in one place and a red error begins spamming uncontrollably in the console: “mod_studio: MOVETYPE_FOLLOW with no model.”

Does anyone know how to fix this and make it work properly? In my new TTT map I have an awesome remote controlled gun for traitors that requires game_ui to aim and fire and I’d be super bummed if I can’t actually implement it.

A possible workaround I can think of would be to spawn an invisible func_breakable over the player when they take control of it, which should act as a shield and prevent the player from taking damage, then once the breakable breaks, disable the game_ui and kill the player inside of it? I have no idea if that would work.

Yeah idk about that… Especially because the player could be off-center from the func_breakable when he presses the button and that it wouldn’t rely on player hitboxes.

I’m hoping for some sort of a direct workaround. Thanks though!’
**
Edit:

**The only “fix” I have found so far is this: https://forums.alliedmods.net/showthread.php?p=2089129
The fix is in the form of a plugin. Not quite sure how to apply a fix in my map… Maybe it’s possible through lua_run or something?

Here’s the source of the plugin that fixes the game_ui. This post probably belongs in the developer section, but is there any chance of translating this into a lua_run to fix it when the map loads or something? Or does anyone know an alternative method?


#include <sourcemod>
#include <sdktools_entoutput>
#include <sdktools_entinput>
#include <sdktools_engine>

#pragma semicolon 1

new const String:PLUGIN_NAME[] = "Fix game_ui entity";
new const String:PLUGIN_VERSION[] = "1.0";

public Plugin:myinfo =
{
	name = PLUGIN_NAME,
	author = "hlstriker",
	description = "Fixes the game_ui entity bug.",
	version = PLUGIN_VERSION,
	url = "www.swoobles.com"
}

new g_iAttachedGameUI[MAXPLAYERS+1];


public OnPluginStart()
{
	CreateConVar("fix_gameui_entity_ver", PLUGIN_VERSION, PLUGIN_NAME, FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_NOTIFY|FCVAR_PRINTABLEONLY);
	
	HookEvent("player_death", Event_PlayerDeath, EventHookMode_Post);
	
	HookEntityOutput("game_ui", "PlayerOn", GameUI_PlayerOn);
	HookEntityOutput("game_ui", "PlayerOff", GameUI_PlayerOff);
}

public Action:Event_PlayerDeath(Handle:hEvent, const String:szName[], bool:bDontBroadcast)
{
	new iClient = GetClientOfUserId(GetEventInt(hEvent, "userid"));
	RemoveFromGameUI(iClient);
	SetClientViewEntity(iClient, iClient);
	
	new iFlags = GetEntityFlags(iClient);
	iFlags &= ~FL_ONTRAIN;
	iFlags &= ~FL_FROZEN;
	iFlags &= ~FL_ATCONTROLS;
	SetEntityFlags(iClient, iFlags);
}

public OnClientDisconnect(iClient)
{
	RemoveFromGameUI(iClient);
}

public GameUI_PlayerOn(const String:szOutput[], iCaller, iActivator, Float:fDelay)
{
	if(!(1 <= iActivator <= MaxClients))
		return;
	
	g_iAttachedGameUI[iActivator] = EntIndexToEntRef(iCaller);
}

public GameUI_PlayerOff(const String:szOutput[], iCaller, iActivator, Float:fDelay)
{
	if(!(1 <= iActivator <= MaxClients))
		return;
	
	g_iAttachedGameUI[iActivator] = 0;
}

RemoveFromGameUI(iClient)
{
	if(!g_iAttachedGameUI[iClient])
		return;
	
	new iEnt = EntRefToEntIndex(g_iAttachedGameUI[iClient]);
	if(iEnt == INVALID_ENT_REFERENCE)
		return;
	
	AcceptEntityInput(iEnt, "Deactivate", iClient, iEnt);
}

I hate to bump this once again, but I’m really having trouble getting this to work without errors. Does anyone know how to fix this?

I’m hoping the error spamming only happens to the person who is killed while using the game_ui and no one else, because it would be a fairly rare occurrence for someone to die while using it. If this is true and there’s no risk of crashing the server, I’ll probably just release my map the way things are anyway. But I really want to get rid of this error, seeing as it causes the person to be stuck in one place and their console to be uncontrollably spammed with a red error until the next round.

I’ve researched this quite a bit a few months ago (with CS:GO), couldn’t find a proper solution other than the ones you named. I used the entity for emulating vehicles, where players often die in =/

It must be a cs:go specific error related solely to the spectate function, because I’ve made tens of vehicles that my friends and I have toyed with in garrysmod and they didn’t have any issues with the game_ui after dying at the controls. Though it’s redundant for me to say that, I guess you’ve figured that out.

How about a trigger_multiple that will fire OnEndTouch output when the player dies?

BTW, I don’t think you can convert C++ (which is pretty low-level) to a high level language such as (garry’s unpure dirty) lua.

Lua is a scripting language, C++ is for programming.

It’s not just CS:GO related, I tested it on a dedicated Gmod TTT server and had that red error spam like crazy. Although it didn’t seem to impact performance besides making the console unusable until the next round. Can anyone confirm whether this happens only for the player who is killed?

That’s what I have set up already, but it doesn’t fix the spectating bugging out and the red error spamming “mod_studio: MOVETYPE_FOLLOW with no model.

Right, I knew that Lua is a scripting language, but I was hoping for a possible solution through Lua that could be packed into the map via* lua_run*, and the code could be run on each map spawn.

I also reported the issue here, but who knows if anything will be done about it. By glancing through things, the issue reporting area seems to be fairly inactive with hundreds of open issues, or slow at the very least.

Does the error replicate when you Kill the game_ui rather than deactivating it?

Well if I recall, even if you don’t deactivate the game_ui at all, the error still happens. I think it’s just something to do with the player dying while in control of it. Surprisingly it doesn’t happen when you kill yourself via the kill command though.

Okay, having looked at the plugin code, the only thing that it does to fix the issue is deactivating the game_ui, which is what you’re doing anyway, so I’m not sure why that happens.

[editline]9th May 2014[/editline]

Should’ve automerged.

[editline]9th May 2014[/editline]

Could you send me a stripped down version of the map with just the entities causing the problem? I’d like to take a look in GMod. I don’t have access to Hammer right now.

[editline]9th May 2014[/editline]

I’ve fixed a similar game_ui problem before on a Deathrun map on the old Sassilization servers, and I’ve found the code I used to do it. Although I’m not sure as to whether the two issues are exactly the same (I don’t recall getting console errors back then), it almost certainly is fixable with Lua.

Here’s a barebones test map: https://dl.dropboxusercontent.com/u/54408286/Mapping/Misc/matt_gameui_test_v1.bsp

Press the button below the monitor to use the game_ui. Press right mouse or jump to leave the game_ui. Press the button to the right of the monitor to release the combine soldier to kill you.

But if you have the code to potentially fix the game_ui could you post it here? It would be extremely useful!

If Lua can fix it that probably means it’s going to remain doomed for CSS/GO =( Looked into handeling it with Vscript as well, no luck there.

I’ve tested it in single player TTT and I haven’t been able to recreate the problem. When the soldier kills me I don’t get any errors; however, when I’m switched to spectator mode I’m only able to go up using space. If I press the other movement keys nothing happens, and not even the monitor moves.

Here’s the pertinent code from the fix. Keep in mind that it uses a Deathrun-specific OnRoundChange hook and that it only supports one game_ui (this can easily be changed). It probably won’t help you, though.
[lua]local ui

hook.Add(“OnRoundChange”, “EntityHandler”, function()
– Assigns the game_ui used to control the cannon.
ui = ents.FindByClass(“game_ui”)[1]
ui:SetKeyValue(“PlayerOn”, “!activator,AddOutput,targetname cannon_user,0,-1”)
ui:SetKeyValue(“PlayerOff”, “!activator,AddOutput,targetname ,0,-1”)
ui:SetKeyValue(“UnpressedAttack2”, “!self,Deactivate,0,-1”)
end)

– Disables the cannon once the player controlling it dies.
hook.Add(“PlayerDeath”, “InputCaller”, function(ply)
if ui and ui:IsValid() and ply == ents.FindByName(“cannon_user”)[1] then
ui:Fire(“Deactivate”)
end
end)
[/lua]

Okay, I see how that code works. I’ll give it a shot, but it looks like it’s pretty much doing the same thing as the mapping fix I have in place, right? Regardless, if it’s more streamlined I’ll definitely use it instead, thanks!

The red errors seem to only happen when playing on a dedicated server, but the spectating is messed up every time. I’m not sure how to fix that…

You could always copy the plugin code line for line and add
[lua]ply:RemoveFlags(FL_ONTRAIN)
ply:RemoveFlags(FL_FROZEN)
ply:RemoveFlags(FL_ATCONTROLS)
[/lua]
right below the Deactivate call. Also maybe ply:SetViewEntity(ply), but I’m not sure if that would help or, in fact, do anything.

Well the plugin code I posted doesn’t look like it’s in Lua, but could I try that for the code you provided? I’m no expert in coding though, I will admit.

Yes, what I have there in fact does the same thing as this C++ code:
[cpp]new iFlags = GetEntityFlags(iClient);
iFlags &= ~FL_ONTRAIN;
iFlags &= ~FL_FROZEN;
iFlags &= ~FL_ATCONTROLS;
SetEntityFlags(iClient, iFlags);
[/cpp]
Essentially what it does is remove those three bit flags from the entity. In Lua there’s a premade function for this, but in C++ you have to take a lower-level approach and work with the bits directly. Another way of writing it in Lua is ply:RemoveFlags(bit.bor(FL_ONTRAIN, FL_FROZEN, FL_ATCONTROLS)), it does the same thing.

I’d be happy to elaborate on how it works exactly if you’re interested.