Change property system

This commit is contained in:
Jackzie 2025-02-01 15:14:06 -06:00
parent 28a4346e8d
commit 61698e20c4
5 changed files with 244 additions and 235 deletions

View file

@ -41,6 +41,7 @@ methodmap SceneSelection < ArrayList {
}
public void Activate(MapData data, int flags = 0) {
if(this == null) return;
g_ropeIndex = 0;
SelectedSceneData aScene;
SceneData scene;
@ -276,114 +277,6 @@ enum struct SceneVariantData {
}
}
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];
@ -394,53 +287,108 @@ enum struct VariantEntityData {
int color[4];
ArrayList keyframes;
PropertyStore properties;
JSONObject propertiesInt;
JSONObject propertiesString;
JSONObject propertiesFloat;
// PropertyStore properties;
// JSONObject propertiesInt;
// JSONObject propertiesString;
// JSONObject propertiesFloat;
JSONArray properties;
void Cleanup() {
if(this.keyframes != null) {
delete this.keyframes;
// if(this.keyframes != null) {
// delete this.keyframes;
// }
// this.properties.Cleanup();
if(this.properties != null) {
JSONObject obj;
for(int i = 0; i < this.properties.Length; i++) {
obj = view_as<JSONObject>(this.properties.Get(i));
delete obj;
}
delete this.properties;
}
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;
// if(!this.properties.HasAny()) return;
// char key[64];
// 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] == '_') {
// this._ApplyNetprop(entity, key);
// } else if(key[0] == "_") {
// this._ApplyCustom(entity, key);
// } else {
// this._ApplyKeyvalue(entity, key);
// }
// }
// delete keys;
if(this.properties != null) {
JSONObject obj;
char type[64], key[64];
for(int i = 0; i < this.properties.Length; i++) {
obj = view_as<JSONObject>(this.properties.Get(i));
if(!obj.HasKey("key")) {
LogError("Missing \"key\" in property object for entity %d", entity);
} else {
obj.GetString("type", type, sizeof(type));
obj.GetString("key", key, sizeof(key));
if(StrEqual(type, "netprop")) {
this._ApplyProperty(Prop_Send, entity, key, obj);
} else if(StrEqual(type, "datamap")) {
this._ApplyProperty(Prop_Data, entity, key, obj);
} else if(StrEqual(type, "keyvalue")) {
this._ApplyKeyvalue(entity, key, obj);
} else if(StrEqual(type, "input")) {
this._ApplyInput(entity, key, obj);
} else {
this._ApplyCustom(entity, key, obj);
}
}
}
}
delete keys;
}
void _ApplyProperty(PropType propType, int entity, const char[] key, JSONObject obj) {
char buffer[128];
if(obj.HasKey("string")) {
obj.GetString("string", buffer, sizeof(buffer));
Debug("Setting property %s (val=%s) on %d", key, buffer, entity);
SetEntPropString(entity, propType, key, buffer);
} else if(obj.HasKey("integer")) {
int val = obj.GetInt("integer");
Debug("Setting property %s (val=%d) on %d", key, val, entity);
SetEntProp(entity, propType, key, val);
} else if(obj.HasKey("float")) {
float val = obj.GetFloat("float");
Debug("Setting property %s (val=%f) on %d", key, val, entity);
SetEntPropFloat(entity, propType, key, val);
} else {
LogError("no value provided for entity %d with key %s", entity, key);
}
}
void _ApplyInput(int entity, const char[] key, JSONObject obj) {
Debug("Applying input %s on %d", key, entity);
TriggerEntityInput(entity, key);
}
void _ApplyCustom(int entity, const char[] key, JSONObject obj) {
Debug("_ApplyCustom(%d, \"%s\"): unknown custom key", entity, key);
}
void _ApplyKeyvalue(int entity, const char[] key, JSONObject obj) {
if(obj.HasKey("buffer")) {
char buffer[255];
obj.GetString("string", buffer, sizeof(buffer));
Debug("Dispatching kv %s: %s on %d", key, buffer, entity);
DispatchKeyValue(entity, key, buffer);
} else {
LogError("no value provided for entity %d with key %s", entity, key);
}
}
}
@ -496,37 +444,41 @@ enum struct VariantInputData {
void _trigger(int entity) {
if(entity > 0 && IsValidEntity(entity)) {
if(StrEqual(this.input, "_allow_ladder")) {
if(HasEntProp(entity, Prop_Send, "m_iTeamNum")) {
SetEntProp(entity, Prop_Send, "m_iTeamNum", 0);
} else {
Log("Warn: Entity (%d) with id \"%s\" has no teamnum for \"_allow_ladder\"", entity, this.name);
}
} else if(StrEqual(this.input, "_lock")) {
AcceptEntityInput(entity, "Close");
AcceptEntityInput(entity, "Lock");
} else if(StrEqual(this.input, "_lock_nobreak")) {
AcceptEntityInput(entity, "Close");
AcceptEntityInput(entity, "Lock");
AcceptEntityInput(entity, "SetUnbreakable");
} else {
char cmd[32];
// Split input "a b" to a with variant "b"
int len = SplitString(this.input, " ", cmd, sizeof(cmd));
if(len > -1) {
SetVariantString(this.input[len]);
AcceptEntityInput(entity, cmd);
Debug("_trigger(%d): %s (v=%s)", entity, cmd, this.input[len]);
} else {
Debug("_trigger(%d): %s", entity, this.input);
AcceptEntityInput(entity, this.input);
}
}
TriggerEntityInput(entity, this.input);
}
}
}
void TriggerEntityInput(int entity, const char[] input) {
if(StrEqual(input, "_allow_ladder")) {
if(HasEntProp(entity, Prop_Send, "m_iTeamNum")) {
SetEntProp(entity, Prop_Send, "m_iTeamNum", 0);
} else {
Log("Warn: Entity (%d) has no teamnum for \"_allow_ladder\"", entity);
}
} else if(StrEqual(input, "_lock")) {
AcceptEntityInput(entity, "Close");
AcceptEntityInput(entity, "Lock");
} else if(StrEqual(input, "_lock_nobreak")) {
AcceptEntityInput(entity, "Close");
AcceptEntityInput(entity, "Lock");
AcceptEntityInput(entity, "SetUnbreakable");
} else {
char cmd[32];
// Split input "a b" to a with variant "b"
int len = SplitString(input, " ", cmd, sizeof(cmd));
if(len > -1) {
SetVariantString(input[len]);
AcceptEntityInput(entity, cmd);
Debug("_trigger(%d): %s (v=%s)", entity, cmd, input[len]);
} else {
Debug("_trigger(%d): %s", entity, input);
AcceptEntityInput(entity, input);
}
}
}
enum struct LumpEditData {
char name[MAX_INPUTS_CLASSNAME_LENGTH];
InputType type;

View file

@ -259,10 +259,11 @@ void loadChoiceEntity(ArrayList list, JSONObject entityData) {
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"));
entity.properties = view_as<JSONArray>(entityData.Get("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

@ -0,0 +1,82 @@
int R_CreateFire(VariantEntityData data) {
int entity = CreateEntityByName("env_fire");
if(entity == -1) return -1;
DispatchKeyValue(entity, "spawnflags", "13");
DispatchKeyValue(entity, "targetname", ENT_ENV_NAME);
DispatchKeyValueFloat(entity, "firesize", 20.0);
DispatchKeyValueFloat(entity, "fireattack", 100.0);
DispatchKeyValueFloat(entity, "damagescale", 1.0);
TeleportEntity(entity, data.origin, NULL_VECTOR, NULL_VECTOR);
data.ApplyProperties(entity);
DispatchSpawn(entity);
AcceptEntityInput(entity, "Enable");
AcceptEntityInput(entity, "StartFire");
#if defined DEBUG_LOG_MAPSTART
PrintToServer("spawn env_fire at %.1f %.1f %.1f", pos[0], pos[1], pos[2]);
#endif
return entity;
}
int R_CreateLight(VariantEntityData data) {
int entity = CreateEntityByName("light_dynamic");
if(entity == -1) return -1;
DispatchKeyValue(entity, "targetname", ENT_PROP_NAME);
DispatchKeyValueInt(entity, "brightness", data.color[3]);
DispatchKeyValueFloat(entity, "distance", data.scale[0]);
DispatchKeyValueFloat(entity, "_inner_cone", data.angles[0]);
DispatchKeyValueFloat(entity, "_cone", data.angles[1]);
DispatchKeyValueFloat(entity, "pitch", data.angles[2]);
// DispatchKeyValueInt()
TeleportEntity(entity, data.origin, NULL_VECTOR, NULL_VECTOR);
data.ApplyProperties(entity);
if(!DispatchSpawn(entity)) return -1;
SetEntityRenderColor(entity, data.color[0], data.color[1], data.color[2], data.color[3]);
SetEntityRenderMode(entity, RENDER_TRANSCOLOR);
AcceptEntityInput(entity, "TurnOn");
return entity;
}
int R_CreateEnvBlockerScaled(VariantEntityData data) {
int entity = CreateEntityByName(data.type);
DispatchKeyValue(entity, "targetname", ENT_BLOCKER_NAME);
DispatchKeyValue(entity, "initialstate", "1");
DispatchKeyValueInt(entity, "BlockType", StrEqual(data.type, "env_physics_blocker") ? 4 : 0);
static float mins[3];
mins = data.scale;
NegateVector(mins);
DispatchKeyValueVector(entity, "boxmins", mins);
DispatchKeyValueVector(entity, "boxmaxs", data.scale);
DispatchKeyValueVector(entity, "mins", mins);
DispatchKeyValueVector(entity, "maxs", data.scale);
TeleportEntity(entity, data.origin, NULL_VECTOR, NULL_VECTOR);
data.ApplyProperties(entity);
if(DispatchSpawn(entity)) {
#if defined DEBUG_LOG_MAPSTART
PrintToServer("spawn blocker scaled %.1f %.1f %.1f scale [%.0f %.0f %.0f]", pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
#endif
SetEntPropVector(entity, Prop_Send, "m_vecMaxs", data.scale);
SetEntPropVector(entity, Prop_Send, "m_vecMins", mins);
AcceptEntityInput(entity, "Enable");
#if defined DEBUG_BLOCKERS
Effect_DrawBeamBoxRotatableToAll(data.origin, mins, data.scale, NULL_VECTOR, g_iLaserIndex, 0, 0, 0, 150.0, 0.1, 0.1, 0, 0.0, {255, 0, 0, 255}, 0);
#endif
return entity;
}
return -1;
}
void R_CreateDecal(VariantEntityData data) {
CreateDecal(data.model, data.origin);
}
int R_CreateProp(VariantEntityData data) {
int entity = StartPropCreate(data.type, data.model, data.origin, data.angles, NULL_VECTOR);
if(entity == -1) return -1;
data.ApplyProperties(entity);
if(DispatchSpawn(entity)) {
return entity;
}
return -1;
}