Commit b202bab4 authored by Mikleo's avatar Mikleo
Browse files

Added handles mode to select invisible entities.

Added bootybay battle royale scenario.
parent f7c8fc56
Pipeline #12241 passed with stages
in 39 seconds
......@@ -10,7 +10,7 @@
#include <SteamWorks>
#define PluginVersion "1.31"
#define PluginVersion "1.32"
float pVersion;
// note linearmap field is unstable
......@@ -74,6 +74,8 @@ char VehicleFolderPath[] = "scenarios/_prefabs/vehicles";
char lastLevelOverride[64];
int lastLevelOverrideTime;
......@@ -113,9 +115,11 @@ enum classdataenum {
bool:data_respawnOnMove,
bool:data_customOnly,
bool:data_isMovable,
bool:data_isHandleOnly,
bool:data_isRemovable,
bool:data_isBrushEntity,
ArrayList:data_keys
ArrayList:data_keys,
String:data_handle_color[14]
}
bool displayHandles = false;
......@@ -176,7 +180,7 @@ public void OnPluginStart()
RegConsoleCmd("sm_snapangle", Command_Snap_Angle);
RegConsoleCmd("sm_lockgrabaxis", Command_Lock_Grab_Axis);
RegConsoleCmd("sm_lockgrabrotation", Command_Lock_Grab_Rotation);
RegConsoleCmd("sm_handles", Command_Handles);
RegConsoleCmd("sm_editorinfo", Command_Editor_info);
......@@ -369,6 +373,12 @@ public OnMapStart()
AddFileToDownloadsTable("models/empfun/platform8.phy");
AddFileToDownloadsTable("models/empfun/platform8.vvd");
AddFileToDownloadsTable("models/empfun/cube4.dx90.vtx");
AddFileToDownloadsTable("models/empfun/cube4.mdl");
AddFileToDownloadsTable("models/empfun/cube4.phy");
AddFileToDownloadsTable("models/empfun/cube4.vvd");
AddFileToDownloadsTable("materials/models/empfun/platform.vmt");
AddFileToDownloadsTable("materials/models/empfun/platform2.vmt");
AddFileToDownloadsTable("materials/models/empfun/platform3.vmt");
......@@ -380,6 +390,7 @@ public OnMapStart()
AddFileToDownloadsTable("materials/models/empfun/platform9.vmt");
AddFileToDownloadsTable("materials/models/empfun/platform10.vmt");
AddFileToDownloadsTable("materials/models/empfun/platform11.vmt");
AddFileToDownloadsTable("materials/models/empfun/platform12.vmt");
}
PrecacheSound("weapons/mortar/mortar_explode2.wav");
......@@ -392,6 +403,8 @@ public OnMapStart()
ScenarioVoteMenu = null;
displayHandles = false;
}
......@@ -399,6 +412,7 @@ public OnMapStart()
public OnGameStart()
{
DisableHandles();
for(int i=1; i< MaxClients; i++)
{
if(selectedEntities[i] != null)
......@@ -949,21 +963,22 @@ public Action Command_Action(int client,int args)
if(entity <= 0)
{
entity = FindClosestEditableEntity(position,60.0);
if(entity <= 0)
entity = FindClosestHandlelessEntity(position,60.0);
}
// check if entity is a handle
if(entity > 0)
{
char entityName[64];
GetEntPropString(entity,Prop_Data,"m_iName",entityName,sizeof(entityName));
if(StrContains(entityName,"HANDLE_") >= 0)
{
// find directly in front of player.
float fwd[3],right[3],up[3];
GetAngleVectors(clientAngles,fwd,right,up);
for(int i = 0;i<3;i++)
{
fwd[i] = clientOrigin[i] + fwd[i] * 60.0;
}
entity = FindClosestEditableEntity(fwd,60.0);
}
entity = FindHandleTarget(entity);
}
}
char arg[128];
bool releasedGrab = false;
......@@ -1221,7 +1236,7 @@ int Create_Prop(bool physprop, int client,float position[3], float angles[3])
IntToString(skin,skinBuffer,sizeof(skinBuffer));
DispatchKeyValue(entindex, "skin", skinBuffer);
DispatchKeyValue(entindex, "solid", "6");
DispatchKeyValue(entindex, "solid", "2");
DispatchKeyValue(entindex, "StartDisabled", "false");
......@@ -1527,6 +1542,8 @@ public int Load_Prefab(int client,char[] presetName,bool isVehicle,float positio
return -2;
}
int overrideTeam = -1;
char arg3[128];
if(GetCmdArg(3, arg3, sizeof(arg3)))
......@@ -1632,8 +1649,9 @@ bool BaseSpawnPrefab(int client,char[] presetName,bool isVehicle,float position[
int newEntity = LoadPrefab(kv);
if(client > 0 && IsValidEntity(newEntity))
{
AddToSelection(client,newEntity);
OnCustomEntityCreated(newEntity);
AddToSelection(client,newEntity);
}
......@@ -1652,7 +1670,13 @@ void KVAddIDStamp(KeyValues kv,char[] key,int IDStamp)
kv.GetString(key,nameBuffer,sizeof(nameBuffer));
if(strlen(nameBuffer) > 0)
{
Format(nameBuffer,sizeof(nameBuffer),"%s%X",nameBuffer,IDStamp);
if(nameBuffer[0] == '*')
ReplaceString(nameBuffer,sizeof(nameBuffer),"*","");
else
{
Format(nameBuffer,sizeof(nameBuffer),"%s_%X",nameBuffer,IDStamp);
}
kv.SetString(key,nameBuffer);
}
}
......@@ -2043,6 +2067,7 @@ public Action Edit_Entity(int client, int entity,float position[3],bool editExis
kv.Rewind();
kv.SetString(arg1,arg2);
int newEntity = RestoreEntity(-1,kv,classInfo,className);
OnCustomEntityCreated(newEntity);
PrintToChat(client,"set %s to %s",arg1,arg2);
......@@ -2473,6 +2498,14 @@ StartGlowing(int entity)
SetEntityRenderColor(entity, 160, 255, 160,a);
}
int handle = FindEntityHandle(entity);
if(handle >= 0)
{
int r,g,b,a;
GetEntityRenderColor(handle, r, g, b, a);
SetEntityRenderColor(handle, r, g, b,255);
}
}
}
StopGlowing(int entity)
......@@ -2490,11 +2523,21 @@ StopGlowing(int entity)
SetEntityRenderColor(entity, 255, 255, 255,a);
}
int handle = FindEntityHandle(entity);
if(handle >= 0)
{
int r,g,b,a;
GetEntityRenderColor(handle, r, g, b, a);
SetEntityRenderColor(handle, r, g, b,220);
}
}
}
bool IsEditableEntity(int entity)
bool IsHandlelessEntity(int entity)
{
if(!IsValidEntity(entity))
{
......@@ -2506,7 +2549,10 @@ bool IsEditableEntity(int entity)
char className[64];
GetEntityClassname(entity, className, sizeof(className));
any classInfo[classdataenum];
return GetEntityData(className,classInfo);
if(GetEntityData(className,classInfo) && classInfo[data_isHandleOnly] == false)
return true;
else
return false;
}
......@@ -2579,6 +2625,8 @@ public Action Move_Entity(int client,float position[3],bool clone)
// Automatically respawn to recreate vehicle physbox correctly.
selectedEnt = RespawnEntity(selectedEnt,className);
// we have to add the entity at this exact index.
AddToSelection(client,selectedEnt,i);
}
......@@ -2968,12 +3016,16 @@ public Action:Hook_Grab(grabbingClient,client)
return Plugin_Continue;
}
// respawn if we are selected to the old one reselect it.
// do handles as well.
int RespawnEntity(int entity,char [] className)
{
float position[3];
GetEntPropVector( entity, Prop_Send, "m_vecOrigin", position );
int newEntity = CloneEntity(entity,className,position);
ExecuteRemoveEntity(entity);
OnCustomEntityCreated(newEntity);
return newEntity;
}
int CloneEntity(int entity,char [] className, float[3] position, int timeID = -1)
......@@ -4329,11 +4381,6 @@ void SaveEntities(KeyValues kv)
int hammerID = GetOrAddHammerID(entity);
// do not save Hammer IDs
if(hammerID == -1)
{
continue;
}
if((n == 0 && hammerID < BASEHAMMERID) || (n ==1 && hammerID >= BASEHAMMERID))
{
......@@ -4415,7 +4462,7 @@ LoadEntities(KeyValues kv,float version,int hMin,int hLimit)
int entity = -1;
// if they are not a custom element just reload them regardless.
if( hammer_id <= hLimit && hammer_id >= hMin)
entity = findEntityWithHammerID(hammer_id,className);
entity = FindEntityByHammerID(hammer_id,className);
entity = RestoreEntity(entity,kv,classInfo,className);
......@@ -4425,6 +4472,8 @@ LoadEntities(KeyValues kv,float version,int hMin,int hLimit)
// restore back hammer id
SetEntProp(entity,Prop_Data,"m_iHammerID",hammer_id);
includedEntities.Push(entity);
AddHandle(entity,classInfo[data_handle_color]);
}
}
......@@ -4499,13 +4548,24 @@ SaveEntity(int entity,KeyValues kv,any[] classInfo,char[] className)
kv.SetVector("position",position);
kv.SetVector("angles",angles);
char parentName[32];
GetEntPropString(entity, Prop_Data, "m_iParent", parentName,sizeof(parentName));
if(strlen(parentName) > 1)
int parent = GetEntPropEnt(entity, Prop_Data, "m_hMoveParent");
if(IsValidEntity(parent))
{
kv.SetString("parent",parentName);
char parentid[16];
Format(parentid,sizeof(parentid),"#%d",GetOrAddHammerID(parent));
kv.SetString("parent",parentid);
}
//char parentName[32];
//GetEntPropString(entity, Prop_Data, "m_iParent", parentName,sizeof(parentName));
//if(strlen(parentName) > 1)
//{
//kv.SetString("parent",parentName);
//}
// helpful for manual editing.
char coordinates[10];
EU_GetMapCoordinates(position,coordinates);
......@@ -4768,7 +4828,7 @@ RestoreEntity(int entity,KeyValues kv,any[] classInfo ,char[] className)
char parentName[32];
kv.GetString("parent",parentName,sizeof(parentName));
if(strlen(parentName) > 1)
if(strlen(parentName) >= 1)
{
SetEntPropString(entity, Prop_Data, "m_iParent", parentName);
CreateTimer(0.1, Timer_ParentEntity,entity);
......@@ -4815,8 +4875,14 @@ RestoreEntity(int entity,KeyValues kv,any[] classInfo ,char[] className)
{
// cant remove because old scenarios dont have the movetype field to load this.
SetEntityMoveType(entity, MOVETYPE_NONE);
AcceptEntityInput(entity, "TurnOn", entity, entity, 0);
AcceptEntityInput(entity, "EnableCollision");
if(kv.GetNum("SolidType") != 0)
{
AcceptEntityInput(entity, "TurnOn", entity, entity, 0);
AcceptEntityInput(entity, "EnableCollision");
}
}
else if(StrEqual(className,"prop_physics",true) )
......@@ -5057,25 +5123,7 @@ RestoreKeys(KeyValues kv,int entity, ArrayList keys,bool wasSpawned,bool postSpa
int findEntityWithHammerID(int hammerID,char [] className)
{
int maxEntities = GetMaxEntities();
char edictClassName[64];
for (int entity=MaxClients+1; entity<=maxEntities; entity++) {
if (!IsValidEntity(entity)) {
continue;
}
GetEntityClassname(entity, edictClassName, sizeof(edictClassName));
if(GetEntProp(entity, Prop_Data, "m_iHammerID") == hammerID && StrEqual(className,edictClassName,true))
{
return entity;
}
}
return -1;
}
......@@ -5112,8 +5160,11 @@ bool ShouldSave(int entity,char[] classname,any[] classInfo)
{
int hammerID = GetEntProp(entity,Prop_Data,"m_iHammerID");
if(hammerID == -1)
return false;
// if the entity is customonly, don't save any non-custom entities.
if(hammerID > 0 && hammerID < BASEHAMMERID && classInfo[data_customOnly])
if( hammerID < BASEHAMMERID && classInfo[data_customOnly])
{
return false;
}
......@@ -5218,7 +5269,7 @@ int FindClosestEnt(char[] classname,float position[3], float maxDistance = 500.0
}
return closestEnt;
}
int FindClosestEditableEntity(float position[3], float maxDistance = 500.0)
int FindClosestHandlelessEntity(float position[3], float maxDistance = 500.0)
{
int closestEnt = 0;
float closestDist = maxDistance;
......@@ -5227,7 +5278,7 @@ int FindClosestEditableEntity(float position[3], float maxDistance = 500.0)
int maxEntities = GetMaxEntities();
for (int ent=MaxClients+1; ent<=maxEntities; ent++)
{
if ( IsEditableEntity(ent) && IsValidEntity(ent))
if ( IsHandlelessEntity(ent) && IsValidEntity(ent))
{
GetEntPropVector(ent, Prop_Send, "m_vecOrigin", entPosition);
......@@ -5279,7 +5330,46 @@ int FindEntByName(char[] name,char[] classname)
return -1;
}
int FindEntityByName(char[] name)
{
int maxEntities = GetMaxEntities();
char entityName[64];
for (int entity=MaxClients+1; entity<=maxEntities; entity++)
{
if (!IsValidEdict(entity)) {
continue;
}
GetEntPropString(entity, Prop_Data, "m_iName", entityName,sizeof(entityName));
if(StrEqual(entityName,name,false))
{
return entity;
}
}
// also search target entities
return FindEntByName(name,"info_target");
}
int FindEntityByHammerID(int hammerID,char [] className)
{
int maxEntities = GetMaxEntities();
char edictClassName[64];
for (int entity=MaxClients+1; entity<=maxEntities; entity++) {
if (!IsValidEntity(entity)) {
continue;
}
GetEntityClassname(entity, edictClassName, sizeof(edictClassName));
if(GetEntProp(entity, Prop_Data, "m_iHammerID") == hammerID && (strlen(className) == 0 || StrEqual(className,edictClassName,true)))
{
return entity;
}
}
return -1;
}
// resources, tickets and research.
......@@ -6143,9 +6233,9 @@ int SwitchFaction(int entity,char[] classname)
bool GetModelName(char[] shortcut,char[] output,int outputSize,float[3] offset, float[3] offsetAngles, bool &disableShadows)
{
if(!GetModelNameFromShortcut(shortcut,"scenarios/custom_modelshortcuts.txt",output,outputSize,offset,offsetAngles,disableShadows))
if(!GetModelNameFromShortcut(shortcut,"scenarios/_modelshortcuts/custom_modelshortcuts.txt",output,outputSize,offset,offsetAngles,disableShadows))
{
return GetModelNameFromShortcut(shortcut,"scenarios/core_modelshortcuts.txt",output,outputSize,offset,offsetAngles,disableShadows);
return GetModelNameFromShortcut(shortcut,"scenarios/_modelshortcuts/core_modelshortcuts.txt",output,outputSize,offset,offsetAngles,disableShadows);
}
return true;
}
......@@ -6637,25 +6727,24 @@ public Action Timer_ParentEntity(Handle timer,int childEntity)
GetEntPropString(childEntity, Prop_Data, "m_iParent", parentName,sizeof(parentName));
if(strlen(parentName) > 1)
{
int maxEntities = GetMaxEntities();
char entityName[32];
for (int entity=MaxClients+1; entity<=maxEntities; entity++)
int entity = -1;
if(parentName[0] == '#')
{
if (!IsValidEdict(entity)) {
continue;
}
GetEntPropString(entity, Prop_Data, "m_iName", entityName,sizeof(entityName));
if(StrEqual(parentName,entityName))
{
// teleport to the position of
SetVariantString("!activator");
AcceptEntityInput(childEntity, "SetParent", entity);
return;
}
ReplaceString(parentName,sizeof(parentName),"#","");
int hammerid = StringToInt(parentName);
entity = FindEntityByHammerID(hammerid,"");
}
else
{
entity = FindEntityByName(parentName);
}
if(entity != -1)
{
SetVariantString("!activator");
AcceptEntityInput(childEntity, "SetParent", entity);
}
}
......@@ -6712,6 +6801,16 @@ public Action:UMC_OnDetermineMapExclude(Handle:kv, const String:map[], const Str
void OnCustomEntityCreated(int entity)
{
GetOrAddHammerID(entity);
char className[64];
any classInfo[classdataenum];
GetEntityClassname(entity, className, sizeof(className));
if(GetEntitySavingKeys(className,pVersion,classInfo))
{
AddHandle(entity,classInfo[data_handle_color]);
}
}
public void LoadEntData()
......@@ -6745,9 +6844,11 @@ public void LoadEntData()
data[data_respawnOnMove] = extendGameData[data_respawnOnMove];
data[data_customOnly] = extendGameData[data_customOnly];
data[data_isMovable] = extendGameData[data_isMovable];
data[data_isHandleOnly] = extendGameData[data_isHandleOnly];
data[data_isRemovable] = extendGameData[data_isRemovable];
data[data_isBrushEntity] = extendGameData[data_isBrushEntity];
data[data_version] = extendGameData[data_version];
strcopy(extendGameData[data_handle_color],14,data[data_handle_color]);
extended = true;
}
......@@ -6756,6 +6857,7 @@ public void LoadEntData()
data[data_group] = 0;
data[data_respawnOnMove] = false;
data[data_customOnly] = false;
data[data_isHandleOnly] = false;
data[data_isMovable] = true;
data[data_isRemovable] = true;
data[data_isBrushEntity] = false;
......@@ -6790,6 +6892,12 @@ public void LoadEntData()
data[data_isMovable] = kv.GetNum("moveable", 1) == 1;
data[data_isHandleOnly] = kv.GetNum("handleOnly", 0) == 1;
kv.GetString("handle_color",data[data_handle_color],14,"100 100 100");
kv.GetString("removable",buffer,sizeof(buffer),"");
if(StrEqual(buffer,"false",true))
{
......@@ -6942,17 +7050,186 @@ public Action Command_Command_Log(int client, int args)
AddCommandListener(Listener);
return Plugin_Handled;
}
public Action Command_Handles(int client, int args)
{
if(!CanEditMap(client))
{
return Plugin_Handled;
}
if(displayHandles)
DisableHandles();
else
EnableHandles();
return Plugin_Handled;
}
public void EnableHandles()
{
if(displayHandles == true)
return;
displayHandles = true;
// look for savable entities that should have handles
// this can be all entities because even some props need stuff.
int maxEntities = GetMaxEntities();
char className[64];
any classInfo[classdataenum];
for (int entity=MaxClients+1; entity<=maxEntities; entity++)
{
if (!IsValidEntity(entity)) {
continue;
}
GetEntityClassname(entity, className, sizeof(className));
if(GetEntitySavingKeys(className,pVersion,classInfo) && ShouldSave(entity,className,classInfo))
{
// create a handle entity here
// when selected will select main entity instead.
AddHandle(entity,classInfo[data_handle_color]);
}
}
PrintToChatAll("Entity Handles Enabled");
}
public void AddHandle(int target,char[] color)
{
if(!displayHandles)
return;
char tempcolor[32];
strcopy(tempcolor,sizeof(tempcolor),color);
int r = 255;
int g = 255;
int b = 255;
char arg[32];
int argIndex;
if(BreakArg(tempcolor,arg,sizeof(arg),argIndex))
r = StringToInt(arg);
if(BreakArg(tempcolor,arg,sizeof(arg),argIndex))
g = StringToInt(arg);
if(BreakArg(tempcolor,arg,sizeof(arg),argIndex))
b = StringToInt(arg);
int entindex = CreateEntityByName("prop_dynamic_override");
if(entindex < 0)
return;
DispatchKeyValue(entindex, "model", "models/props_junk/cardboard_box001a.mdl");
char name[32];
Format(name,sizeof(name),"HANDLE_%d",entindex);
DispatchKeyValue(entindex, "targetname", name);
DispatchKeyValue(entindex, "solid", "6");
SetEntityMoveType(entindex, MOVETYPE_NONE);
float origin[3];
float angles[3];
GetEntPropVector( target, Prop_Data, "m_vecOrigin", origin );
GetEntPropVector(target, Prop_Data, "m_angRotation", angles);
// randomize so its more selectable
for(int i = 0;i<3;i++)
{
origin[i] += GetRandomFloat(-2.0, 2.0);
angles[i] += GetRandomFloat(-2.0, 2.0);
}
TeleportEntity(entindex, origin, angles , NULL_VECTOR);
DispatchSpawn(entindex);
ActivateEntity(entindex);
// set parent to the target
SetVariantString("!activator");
AcceptEntityInput(entindex, "SetParent", target);
// prevent saving.
SetEntProp(entindex,Prop_Data,"m_iHammerID",-1);
SetEntityRenderMode(entindex, RENDER_TRANSCOLOR);
SetEntityRenderColor(entindex, r, g, b,220);
}
public void DisableHandles()
// its simpler to use find rather than entity refs.