diff --git a/plugins/l4d2_randomizer.smx b/plugins/l4d2_randomizer.smx index def22d1..001f8a7 100644 Binary files a/plugins/l4d2_randomizer.smx and b/plugins/l4d2_randomizer.smx differ diff --git a/scripting/include/randomizer/defs.sp b/scripting/include/randomizer/defs.sp index 44a32ea..6d622b1 100644 --- a/scripting/include/randomizer/defs.sp +++ b/scripting/include/randomizer/defs.sp @@ -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(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(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; diff --git a/scripting/include/randomizer/loader_functions.sp b/scripting/include/randomizer/loader_functions.sp index dcf8b93..2c73cac 100644 --- a/scripting/include/randomizer/loader_functions.sp +++ b/scripting/include/randomizer/loader_functions.sp @@ -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(entityData.Get("properties")); - if(propRoot.HasKey("int")) entity.properties.intKv = view_as(propRoot.Get("int")); - if(propRoot.HasKey("float")) entity.properties.floatKv = view_as(propRoot.Get("float")); - if(propRoot.HasKey("string")) entity.properties.stringKv = view_as(propRoot.Get("string")); + entity.properties = view_as(entityData.Get("properties")); + // JSONObject propRoot = view_as(entityData.Get("properties")); + // if(propRoot.HasKey("int")) entity.properties.intKv = view_as(propRoot.Get("int")); + // if(propRoot.HasKey("float")) entity.properties.floatKv = view_as(propRoot.Get("float")); + // if(propRoot.HasKey("string")) entity.properties.stringKv = view_as(propRoot.Get("string")); } list.PushArray(entity); } \ No newline at end of file diff --git a/scripting/include/randomizer/spawn_functions.sp b/scripting/include/randomizer/spawn_functions.sp new file mode 100644 index 0000000..0862645 --- /dev/null +++ b/scripting/include/randomizer/spawn_functions.sp @@ -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; +} \ No newline at end of file diff --git a/scripting/l4d2_randomizer.sp b/scripting/l4d2_randomizer.sp index 6e60c7a..275ef10 100644 --- a/scripting/l4d2_randomizer.sp +++ b/scripting/l4d2_randomizer.sp @@ -39,6 +39,7 @@ bool randomizerRan = false; #include #include #include +#include #include #include @@ -725,24 +726,6 @@ void AssignGascan(int gascan, GascanSpawnerData spawner) { Debug("Assigning gascan %d to spawner at %.0f %.0f %.0f", gascan, spawner.origin[0], spawner.origin[1], spawner.origin[2]); } -int CreateLight(const float origin[3], const float angles[3], const int color[4] = { 255, 255, 255, 1 }, float distance = 100.0) { - int entity = CreateEntityByName("light_dynamic"); - if(entity == -1) return -1; - DispatchKeyValue(entity, "targetname", ENT_PROP_NAME); - DispatchKeyValueInt(entity, "brightness", color[3]); - DispatchKeyValueFloat(entity, "distance", distance); - DispatchKeyValueFloat(entity, "_inner_cone", angles[0]); - DispatchKeyValueFloat(entity, "_cone", angles[1]); - DispatchKeyValueFloat(entity, "pitch", angles[2]); - // DispatchKeyValueInt() - TeleportEntity(entity, origin, NULL_VECTOR, NULL_VECTOR); - if(!DispatchSpawn(entity)) return -1; - SetEntityRenderColor(entity, color[0], color[1], color[2], color[3]); - SetEntityRenderMode(entity, RENDER_TRANSCOLOR); - AcceptEntityInput(entity, "TurnOn"); - return entity; -} - void AddGascanSpawner(VariantEntityData data) { if(g_MapData.gascanSpawners == null) { g_MapData.gascanSpawners = new ArrayList(sizeof(GascanSpawnerData)); @@ -756,45 +739,14 @@ 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")) { - Debug("spawning \"%s\" at (%.1f %.1f %.1f) rot (%.0f %.0f %.0f)", entity.type, entity.origin[0], entity.origin[1], entity.origin[2], entity.angles[0], entity.angles[1], entity.angles[2]); - CreateFire(entity.origin, 20.0, 100.0, 1.0); - } else if(StrEqual(entity.type, "light_dynamic")) { - CreateLight(entity.origin, entity.angles, entity.color, entity.scale[0]); - Effect_DrawBeamBoxRotatableToAll(entity.origin, { -5.0, -5.0, -5.0}, { 5.0, 5.0, 5.0}, NULL_VECTOR, g_iLaserIndex, 0, 0, 0, 40.0, 0.1, 0.1, 0, 0.0, {255, 255, 0, 255}, 0); - } else if(StrEqual(entity.type, "env_physics_blocker") || StrEqual(entity.type, "env_player_blocker")) { - CreateEnvBlockerScaled(entity.type, entity.origin, entity.scale); - } else if(StrEqual(entity.type, "infodecal")) { - Effect_DrawBeamBoxRotatableToAll(entity.origin, { -1.0, -5.0, -5.0}, { 1.0, 5.0, 5.0}, NULL_VECTOR, g_iLaserIndex, 0, 0, 0, 40.0, 0.1, 0.1, 0, 0.0, {73, 0, 130, 255}, 0); - CreateDecal(entity.model, entity.origin); - } else if(StrContains(entity.type, "prop_") == 0 || StrEqual(entity.type, "prop_fuel_barrel")) { - 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; + if(entity.type[0] == '_') { + if(StrEqual(entity.type, "_gascan")) { + AddGascanSpawner(entity); + } else if(StrContains(entity.type, "_car") != -1) { + SpawnCar(entity); + } else { + Log("WARN: Unknown custom entity type \"%s\", skipped", entity.type); } - 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) { @@ -834,8 +786,26 @@ void spawnEntity(VariantEntityData entity) { } if(!found) Debug("Warn: Could not find entity (classname=%s)", entity.model); - } else if(StrContains(entity.type, "_car") != -1) { - SpawnCar(entity); + } else if(StrEqual(entity.type, "env_fire")) { + Debug("spawning \"%s\" at (%.1f %.1f %.1f) rot (%.0f %.0f %.0f)", entity.type, entity.origin[0], entity.origin[1], entity.origin[2], entity.angles[0], entity.angles[1], entity.angles[2]); + R_CreateFire(entity); + } else if(StrEqual(entity.type, "light_dynamic")) { + R_CreateLight(entity); + Effect_DrawBeamBoxRotatableToAll(entity.origin, { -5.0, -5.0, -5.0}, { 5.0, 5.0, 5.0}, NULL_VECTOR, g_iLaserIndex, 0, 0, 0, 40.0, 0.1, 0.1, 0, 0.0, {255, 255, 0, 255}, 0); + } else if(StrEqual(entity.type, "env_physics_blocker") || StrEqual(entity.type, "env_player_blocker")) { + R_CreateEnvBlockerScaled(entity); + } else if(StrEqual(entity.type, "infodecal")) { + Effect_DrawBeamBoxRotatableToAll(entity.origin, { -1.0, -5.0, -5.0}, { 1.0, 5.0, 5.0}, NULL_VECTOR, g_iLaserIndex, 0, 0, 0, 40.0, 0.1, 0.1, 0, 0.0, {73, 0, 130, 255}, 0); + R_CreateDecal(entity); + } else if(StrContains(entity.type, "weapon_") == 0 || StrContains(entity.type, "prop_") == 0 || StrEqual(entity.type, "prop_fuel_barrel")) { + 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; + } + R_CreateProp(entity); } else if(StrEqual(entity.type, "move_rope")) { if(!PrecacheModel(entity.model)) { LogError("Precache of entity model \"%s\" with type \"%s\" failed", entity.model, entity.type); @@ -847,7 +817,7 @@ void spawnEntity(VariantEntityData entity) { } CreateRope(entity); } else { - LogError("Unknown entity type \"%s\"", entity.type); + LogError("Unsupported entity type \"%s\"", entity.type); } } @@ -897,6 +867,10 @@ int _CreateRope(const char[] type, const char[] targetname, const char[] nextKey return entity; } +// void DebugBox(const float origin[3], const float scale[3], int color[4]) { +// Effect_DrawBeamBoxRotatableToAll(entity.origin, { -5.0, -5.0, -5.0}, { 5.0, 5.0, 5.0}, NULL_VECTOR, g_iLaserIndex, 0, 0, 0, 40.0, 0.1, 0.1, 0, 0.0, {255, 255, 0, 255}, 0); +// } + void Debug(const char[] format, any ...) { #if defined DEBUG_SCENE_PARSE char buffer[192];