Bugzy
11-04-2014, 19:10
I want to create control points in maps that don't have them. To explain, in order to have a proper-functioning control point in Team Fortress 2, you need these entities:
team_control_point_master
team_control_point
trigger_capture_area
prop_dynamic (optional)
I can spawn these entities using Stripper:Source (http://www.bailopan.net/stripper/), except for the trigger_capture_area which is a brush-based entity. Instead, I need to use this method (https://forums.alliedmods.net/showthread.php?t=129597) to spawn them. This set-up would work, however, the most important keyvalue "area_cap_point" doesn't register in-game.
For example, I set this keyvalue like so:
DispatchKeyValue(ent, "area_cap_point", strName);
And despite strName correctly referencing the target name of the relevant team_control_point, the game behaves as if this keyvalue was never set.
Is there any way to get around this? I've attached below the test script/map I've been using to try to get this working. The relevant code is inside the function called "AssignControlPoint".
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#define MDL_NO_MODEL "models/error.mdl"
static Float:g_vOrigin[3] = {192.0, 64.0, 108.0},
Float:g_vDimensions[3] = {256.0, 256.0, 200.0};
public OnPluginStart()
{
HookEventEx("teamplay_round_start", round);
HookEventEx("teamplay_restart_round", round);
ServerCommand("sm_cvar mp_waitingforplayers_time 0");
}
public OnMapStart()
{
PrecacheModel(MDL_NO_MODEL, true);
}
public round(Handle:event, const String:name[], bool:dontBroadcast)
{
if (GetEntityCount() >= GetMaxEntities() - 64) {
PrintToServer("[SM] Entity limit is reached. Can't spawn anymore ents. Change maps.");
return;
}
new ent = CreateEntityByName("trigger_capture_area");
if (!IsValidEntity(ent)) {
PrintToServer("[SM] Could not spawn trigger_capture_area");
return;
}
DispatchKeyValue(ent, "spawnflags", "64");
DispatchKeyValue(ent, "wait", "0");
DispatchKeyValue(ent, "team_startcap_3", "2");
DispatchKeyValue(ent, "team_startcap_2", "2");
DispatchKeyValue(ent, "team_spawn_3", "0");
DispatchKeyValue(ent, "team_spawn_2", "0");
DispatchKeyValue(ent, "team_numcap_3", "1");
DispatchKeyValue(ent, "team_numcap_2", "1");
DispatchKeyValue(ent, "team_cancap_3", "1");
DispatchKeyValue(ent, "team_cancap_2", "1");
DispatchKeyValue(ent, "StartDisabled", "0");
DispatchKeyValue(ent, "area_time_to_cap", "5");
AssignControlPoint(ent, "control_point");
DispatchSpawn(ent);
ActivateEntity(ent);
// set datamap spawnflags to allow (only) clients
SetEntProp(ent, Prop_Data, "m_spawnflags", 1);
// move ent entity to the origin
TeleportEntity(ent, g_vOrigin, NULL_VECTOR, NULL_VECTOR);
SetEntityModel(ent, MDL_NO_MODEL);
// set mins and maxs for entity
decl Float:vecMins[3],
Float:vecMaxs[3];
vecMins[0] = -(g_vDimensions[0] / 2);
vecMins[1] = -(g_vDimensions[1] / 2);
vecMins[2] = -(g_vDimensions[2] / 2);
vecMaxs[0] = (g_vDimensions[0] / 2);
vecMaxs[1] = (g_vDimensions[1] / 2);
vecMaxs[2] = (g_vDimensions[2] / 2);
SetEntPropVector(ent, Prop_Send, "m_vecMins", vecMins);
SetEntPropVector(ent, Prop_Send, "m_vecMaxs", vecMaxs);
// enable touch functions and set it as non-solid for everything
SetEntProp(ent, Prop_Send, "m_usSolidFlags", 152);
SetEntProp(ent, Prop_Send, "m_CollisionGroup", 11);
// make the ent visible by removing EF_NODRAW flag
new m_fEffects = GetEntProp(ent, Prop_Send, "m_fEffects");
m_fEffects |= 0x020;
SetEntProp(ent, Prop_Send, "m_fEffects", m_fEffects);
// proof the entity can be touched
HookSingleEntityOutput(ent, "OnStartTouch", TouchCheck);
}
public TouchCheck(const String:output[], caller, activator, Float:delay)
{
PrintToChat(activator, "%s, %d, %d, %0.2f", output, caller, activator, delay);
}
stock AssignControlPoint(ent, const String:strName[])
{
// appears to work ...
DispatchKeyValue(ent, "area_cap_point", strName);
// and it will report it has changed ... but it still doesn't recognise the control point
decl String:strCheck[128];
GetEntPropString(ent, Prop_Data, "m_iszCapPointName", strCheck, sizeof(strCheck));
PrintToServer("[DEBUG] (AssignControlPoint) Entity: %d now refers to control point '%s'", ent, strCheck);
}
team_control_point_master
team_control_point
trigger_capture_area
prop_dynamic (optional)
I can spawn these entities using Stripper:Source (http://www.bailopan.net/stripper/), except for the trigger_capture_area which is a brush-based entity. Instead, I need to use this method (https://forums.alliedmods.net/showthread.php?t=129597) to spawn them. This set-up would work, however, the most important keyvalue "area_cap_point" doesn't register in-game.
For example, I set this keyvalue like so:
DispatchKeyValue(ent, "area_cap_point", strName);
And despite strName correctly referencing the target name of the relevant team_control_point, the game behaves as if this keyvalue was never set.
Is there any way to get around this? I've attached below the test script/map I've been using to try to get this working. The relevant code is inside the function called "AssignControlPoint".
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#define MDL_NO_MODEL "models/error.mdl"
static Float:g_vOrigin[3] = {192.0, 64.0, 108.0},
Float:g_vDimensions[3] = {256.0, 256.0, 200.0};
public OnPluginStart()
{
HookEventEx("teamplay_round_start", round);
HookEventEx("teamplay_restart_round", round);
ServerCommand("sm_cvar mp_waitingforplayers_time 0");
}
public OnMapStart()
{
PrecacheModel(MDL_NO_MODEL, true);
}
public round(Handle:event, const String:name[], bool:dontBroadcast)
{
if (GetEntityCount() >= GetMaxEntities() - 64) {
PrintToServer("[SM] Entity limit is reached. Can't spawn anymore ents. Change maps.");
return;
}
new ent = CreateEntityByName("trigger_capture_area");
if (!IsValidEntity(ent)) {
PrintToServer("[SM] Could not spawn trigger_capture_area");
return;
}
DispatchKeyValue(ent, "spawnflags", "64");
DispatchKeyValue(ent, "wait", "0");
DispatchKeyValue(ent, "team_startcap_3", "2");
DispatchKeyValue(ent, "team_startcap_2", "2");
DispatchKeyValue(ent, "team_spawn_3", "0");
DispatchKeyValue(ent, "team_spawn_2", "0");
DispatchKeyValue(ent, "team_numcap_3", "1");
DispatchKeyValue(ent, "team_numcap_2", "1");
DispatchKeyValue(ent, "team_cancap_3", "1");
DispatchKeyValue(ent, "team_cancap_2", "1");
DispatchKeyValue(ent, "StartDisabled", "0");
DispatchKeyValue(ent, "area_time_to_cap", "5");
AssignControlPoint(ent, "control_point");
DispatchSpawn(ent);
ActivateEntity(ent);
// set datamap spawnflags to allow (only) clients
SetEntProp(ent, Prop_Data, "m_spawnflags", 1);
// move ent entity to the origin
TeleportEntity(ent, g_vOrigin, NULL_VECTOR, NULL_VECTOR);
SetEntityModel(ent, MDL_NO_MODEL);
// set mins and maxs for entity
decl Float:vecMins[3],
Float:vecMaxs[3];
vecMins[0] = -(g_vDimensions[0] / 2);
vecMins[1] = -(g_vDimensions[1] / 2);
vecMins[2] = -(g_vDimensions[2] / 2);
vecMaxs[0] = (g_vDimensions[0] / 2);
vecMaxs[1] = (g_vDimensions[1] / 2);
vecMaxs[2] = (g_vDimensions[2] / 2);
SetEntPropVector(ent, Prop_Send, "m_vecMins", vecMins);
SetEntPropVector(ent, Prop_Send, "m_vecMaxs", vecMaxs);
// enable touch functions and set it as non-solid for everything
SetEntProp(ent, Prop_Send, "m_usSolidFlags", 152);
SetEntProp(ent, Prop_Send, "m_CollisionGroup", 11);
// make the ent visible by removing EF_NODRAW flag
new m_fEffects = GetEntProp(ent, Prop_Send, "m_fEffects");
m_fEffects |= 0x020;
SetEntProp(ent, Prop_Send, "m_fEffects", m_fEffects);
// proof the entity can be touched
HookSingleEntityOutput(ent, "OnStartTouch", TouchCheck);
}
public TouchCheck(const String:output[], caller, activator, Float:delay)
{
PrintToChat(activator, "%s, %d, %d, %0.2f", output, caller, activator, delay);
}
stock AssignControlPoint(ent, const String:strName[])
{
// appears to work ...
DispatchKeyValue(ent, "area_cap_point", strName);
// and it will report it has changed ... but it still doesn't recognise the control point
decl String:strCheck[128];
GetEntPropString(ent, Prop_Data, "m_iszCapPointName", strCheck, sizeof(strCheck));
PrintToServer("[DEBUG] (AssignControlPoint) Entity: %d now refers to control point '%s'", ent, strCheck);
}