Add custom property support

This commit is contained in:
Jackzie 2025-01-22 23:24:58 -06:00
parent 6a15c9c196
commit e343fc0346
4 changed files with 196 additions and 5 deletions

View file

@ -46,7 +46,7 @@ stock int CreateEnvBlockerScaled(const char[] entClass, const float pos[3], cons
int entity = CreateEntityByName(entClass);
DispatchKeyValue(entity, "targetname", ENT_BLOCKER_NAME);
DispatchKeyValue(entity, "initialstate", "1");
DispatchKeyValue(entity, "BlockType", "0");
DispatchKeyValueInt(entity, "BlockType", StrEqual(entClass, "env_physics_blocker") ? 4 : 0);
static float mins[3];
mins = scale;
NegateVector(mins);
@ -160,10 +160,11 @@ stock void ClearPortalData() {
portals.Clear();
}
stock int StartPropCreate(const char[] entClass, const char[] model, const float pos[3], const float ang[3] = NULL_VECTOR, const float vel[3] = NULL_VECTOR) {
stock int StartPropCreate(const char[] entClass, const char[] model, const float pos[3], const float ang[3] = NULL_VECTOR, const float vel[3] = NULL_VECTOR, bool hasCollision = true) {
int entity = CreateEntityByName(entClass);
if(entity == -1) return -1;
DispatchKeyValue(entity, "model", model);
if(hasCollision)
DispatchKeyValue(entity, "solid", "6");
DispatchKeyValue(entity, "targetname", ENT_PROP_NAME);
DispatchKeyValue(entity, "disableshadows", "1");

View file

@ -266,11 +266,124 @@ enum struct SceneVariantData {
void Cleanup() {
delete this.inputsList;
VariantEntityData entity;
for(int i = 0; i < this.entities.Length; i++) {
this.entities.GetArray(i, entity, sizeof(entity));
entity.Cleanup();
}
delete this.entities;
delete this.forcedScenes;
}
}
enum propertyType {
PROPERTY_NONE = -1,
PROPERTY_STRING,
PROPERTY_INTEGER,
PROPERTY_FLOAT
}
// This is horrible but we need a way to know what the type of the netprop to set is
enum struct PropertyStore {
JSONObject intKv;
JSONObject stringKv;
JSONObject floatKv;
void Cleanup() {
if(this.intKv != null) delete this.intKv;
if(this.stringKv != null) delete this.stringKv;
if(this.floatKv != null) delete this.floatKv;
}
bool GetInt(const char[] name, int &value) {
if(this.intKv == null) return false;
if(!this.intKv.HasKey(name)) return false;
value = this.intKv.GetInt(name);
return true;
}
bool GetString(const char[] name, char[] buffer, int maxlen) {
if(this.stringKv == null) return false;
if(!this.stringKv.HasKey(name)) return false;
this.stringKv.GetString(name, buffer, maxlen);
return true;
}
bool GetFloat(const char[] name, float &value) {
if(this.floatKv == null) return false;
if(!this.floatKv.HasKey(name)) return false;
value = this.floatKv.GetFloat(name);
return true;
}
propertyType GetPropertyType(const char[] key) {
if(this.intKv != null && this.intKv.HasKey(key)) return PROPERTY_INTEGER;
if(this.floatKv != null && this.floatKv.HasKey(key)) return PROPERTY_FLOAT;
if(this.stringKv != null && this.stringKv.HasKey(key)) return PROPERTY_STRING;
return PROPERTY_NONE;
}
bool HasAny() {
return this.intKv != null || this.floatKv != null || this.stringKv != null;
}
ArrayList Keys() {
char key[128];
ArrayList list = new ArrayList(ByteCountToCells(128));
JSONObjectKeys keys;
if(this.stringKv != null) {
keys = this.stringKv.Keys()
while(keys.ReadKey(key, sizeof(key))) {
list.PushString(key);
}
delete keys;
}
if(this.intKv != null) {
keys = this.intKv.Keys()
while(keys.ReadKey(key, sizeof(key))) {
list.PushString(key);
}
delete keys;
}
if(this.floatKv != null) {
keys = this.floatKv.Keys()
while(keys.ReadKey(key, sizeof(key))) {
list.PushString(key);
}
delete keys;
}
return list;
}
StringMap Entries() {
char key[128];
StringMap kv = new StringMap();
JSONObjectKeys keys;
if(this.stringKv != null) {
keys = this.stringKv.Keys()
while(keys.ReadKey(key, sizeof(key))) {
kv.SetValue(key, PROPERTY_STRING);
}
delete keys;
}
if(this.intKv != null) {
keys = this.intKv.Keys()
while(keys.ReadKey(key, sizeof(key))) {
kv.SetValue(key, PROPERTY_INTEGER);
}
delete keys;
}
if(this.floatKv != null) {
keys = this.floatKv.Keys()
while(keys.ReadKey(key, sizeof(key))) {
kv.SetValue(key, PROPERTY_FLOAT);
}
delete keys;
}
return kv;
}
}
enum struct VariantEntityData {
char type[32];
char model[128];
@ -281,6 +394,54 @@ enum struct VariantEntityData {
int color[4];
ArrayList keyframes;
PropertyStore properties;
JSONObject propertiesInt;
JSONObject propertiesString;
JSONObject propertiesFloat;
void Cleanup() {
if(this.keyframes != null) {
delete this.keyframes;
}
this.properties.Cleanup();
}
void ApplyProperties(int entity) {
if(!this.properties.HasAny()) return;
char key[64], buffer[128];
ArrayList keys = this.properties.Keys();
for(int i = 0; i < keys.Length; i++) {
keys.GetString(i, key, sizeof(key));
// Only want to apply netprops (m_ prefix)
if(key[0] == 'm' && key[1] == '_') {
propertyType type = this.properties.GetPropertyType(key);
Debug("netprop %s type %d", key, type);
switch(type) {
case PROPERTY_STRING: {
this.properties.GetString(key, buffer, sizeof(buffer));
Debug("Applying netprop %s (val=%s) on %d", key, buffer, entity);
SetEntPropString(entity, Prop_Send, key, buffer);
break;
}
case PROPERTY_INTEGER: {
int val;
this.properties.GetInt(key, val);
Debug("Applying netprop %s (val=%d) on %d", key, val, entity);
SetEntProp(entity, Prop_Send, key, val);
break;
}
case PROPERTY_FLOAT: {
float val;
this.properties.GetFloat(key, val);
Debug("Applying netprop %s (val=%f) on %d", key, val, entity);
SetEntPropFloat(entity, Prop_Send, key, val);
break;
}
}
}
}
delete keys;
}
}
enum InputType {

View file

@ -258,5 +258,11 @@ void loadChoiceEntity(ArrayList list, JSONObject entityData) {
GetVector(entityData, "angles", entity.angles);
GetVector(entityData, "scale", entity.scale);
GetColor(entityData, "color", entity.color, DEFAULT_COLOR);
if(entityData.HasKey("properties")) {
JSONObject propRoot = view_as<JSONObject>(entityData.Get("properties"));
if(propRoot.HasKey("int")) entity.properties.intKv = view_as<JSONObject>(propRoot.Get("int"));
if(propRoot.HasKey("float")) entity.properties.floatKv = view_as<JSONObject>(propRoot.Get("float"));
if(propRoot.HasKey("string")) entity.properties.stringKv = view_as<JSONObject>(propRoot.Get("string"));
}
list.PushArray(entity);
}

View file

@ -239,8 +239,15 @@ public Action Command_CycleRandom(int client, int args) {
int flags = GetCmdArgInt(1);
if(flags < 0) {
ReplyToCommand(client, "Invalid flags");
} else {
if(args > 1) {
char buffer[64];
GetCmdArg(2, buffer, sizeof(buffer));
LoadRunGlobalMap(buffer, flags | view_as<int>(FLAG_REFRESH));
PrintCenterText(client, "Cycled %s flags=%d", buffer, flags);
} else {
LoadRunGlobalMap(currentMap, flags | view_as<int>(FLAG_REFRESH));
}
if(client > 0)
PrintCenterText(client, "Cycled flags=%d", flags);
}
@ -461,7 +468,7 @@ Action Command_RandomizerBuild(int client, int args) {
}
float pos[3];
float scale[3] = { 15.0, 30.0, 100.0 };
GetLookingPosition(client, Filter_IgnorePlayer, pos);
GetClientAbsOrigin(client, pos);
JSONObject obj = new JSONObject();
obj.SetString("type", "env_player_blocker");
obj.Set("origin", FromFloatArray(pos, 3));
@ -749,6 +756,11 @@ void AddGascanSpawner(VariantEntityData data) {
}
void spawnEntity(VariantEntityData entity) {
// if(entity.type[0] == '_') {
// if(StrEqual(entity.type, "_gascan")) {
// AddGascanSpawner(entity);
// }
// }
if(StrEqual(entity.type, "_gascan")) {
AddGascanSpawner(entity);
} else if(StrEqual(entity.type, "env_fire")) {
@ -772,6 +784,17 @@ void spawnEntity(VariantEntityData entity) {
}
int prop = CreateProp(entity.type, entity.model, entity.origin, entity.angles);
SetEntityRenderColor(prop, entity.color[0], entity.color[1], entity.color[2], entity.color[3]);
entity.ApplyProperties(prop);
} else if(StrContains(entity.type, "weapon_") == 0) {
if(entity.model[0] == '\0') {
LogError("Missing model for entity with type \"%s\"", entity.type);
return;
} else if(!PrecacheModel(entity.model)) {
LogError("Precache of entity model \"%s\" with type \"%s\" failed", entity.model, entity.type);
return;
}
int prop = CreateProp(entity.type, entity.model, entity.origin, entity.angles);
SetEntityRenderColor(prop, entity.color[0], entity.color[1], entity.color[2], entity.color[3]);
} else if(StrEqual(entity.type, "hammerid")) {
int targetId = StringToInt(entity.model);
if(targetId > 0) {