mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-07 14:23:20 +00:00
Bug fixes
This commit is contained in:
parent
c51aa6533c
commit
6a15c9c196
5 changed files with 176 additions and 91 deletions
|
@ -1,3 +1,27 @@
|
||||||
|
#define WINDSHIELD_LIST_COUNT 1
|
||||||
|
char VEHICLE_MODEL_WINDSHIELD_KEY[WINDSHIELD_LIST_COUNT][] = {
|
||||||
|
"models/props_vehicles/cement_truck01.mdl"
|
||||||
|
};
|
||||||
|
char VEHICLE_MODEL_WINDSHIELD_VAL[WINDSHIELD_LIST_COUNT][] = {
|
||||||
|
"models/props_vehicles/cement_truck01_windows.mdl"
|
||||||
|
};
|
||||||
|
|
||||||
|
bool GetWindshieldModel(const char[] vehicleModel, char[] model, int modelSize) {
|
||||||
|
bool found = false;
|
||||||
|
for(int i = 0; i < WINDSHIELD_LIST_COUNT; i++) {
|
||||||
|
if(StrEqual(VEHICLE_MODEL_WINDSHIELD_KEY[i], vehicleModel)) {
|
||||||
|
strcopy(model, modelSize, VEHICLE_MODEL_WINDSHIELD_VAL[i]);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found) {
|
||||||
|
strcopy(model, modelSize, vehicleModel);
|
||||||
|
ReplaceString(model, modelSize, ".mdl", "_glass.mdl");
|
||||||
|
}
|
||||||
|
return PrecacheModel(model);
|
||||||
|
}
|
||||||
|
|
||||||
int SpawnCar(VariantEntityData entity) {
|
int SpawnCar(VariantEntityData entity) {
|
||||||
if(entity.model[0] == '\0') {
|
if(entity.model[0] == '\0') {
|
||||||
LogError("Missing model for entity with type \"%s\"", entity.type);
|
LogError("Missing model for entity with type \"%s\"", entity.type);
|
||||||
|
@ -12,14 +36,12 @@ int SpawnCar(VariantEntityData entity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char glassModel[64];
|
char glassModel[64];
|
||||||
strcopy(glassModel, sizeof(glassModel), entity.model);
|
|
||||||
ReplaceString(glassModel, sizeof(glassModel), ".mdl", "_glass.mdl");
|
|
||||||
if(StrEqual(entity.type, "_car_physics")) {
|
if(StrEqual(entity.type, "_car_physics")) {
|
||||||
vehicle = CreateProp("prop_physics", entity.model, entity.origin, entity.angles);
|
vehicle = CreateProp("prop_physics", entity.model, entity.origin, entity.angles);
|
||||||
} else {
|
} else {
|
||||||
vehicle = CreateProp("prop_dynamic", entity.model, entity.origin, entity.angles);
|
vehicle = CreateProp("prop_dynamic", entity.model, entity.origin, entity.angles);
|
||||||
}
|
}
|
||||||
if(PrecacheModel(glassModel)) {
|
if(GetWindshieldModel(entity.model, glassModel, sizeof(glassModel))) {
|
||||||
int glass = CreateProp("prop_dynamic", glassModel, entity.origin, entity.angles);
|
int glass = CreateProp("prop_dynamic", glassModel, entity.origin, entity.angles);
|
||||||
if(glass != -1) {
|
if(glass != -1) {
|
||||||
SetVariantString("!activator");
|
SetVariantString("!activator");
|
||||||
|
|
|
@ -6,7 +6,7 @@ int DEFAULT_COLOR[4] = { 255, 255, 255, 255 };
|
||||||
MapData g_MapData; // The global map data
|
MapData g_MapData; // The global map data
|
||||||
SceneSelection g_selection; // The selected scenes from the global map data
|
SceneSelection g_selection; // The selected scenes from the global map data
|
||||||
BuilderData g_builder; // The global instance of the builder
|
BuilderData g_builder; // The global instance of the builder
|
||||||
StringMap g_mapTraverseSelections; // For maps that traverse backwards, holds record of the selected scenes so they can be re-applied
|
ArrayList g_mapTraverseSelectionStack; // For maps that traverse backwards, holds record of the selected scenes so they can be re-applied
|
||||||
|
|
||||||
int g_ropeIndex; // Unique id for ropes on spawn, is reset to 0 for every new spawn attempt
|
int g_ropeIndex; // Unique id for ropes on spawn, is reset to 0 for every new spawn attempt
|
||||||
ArrayList g_gascanRespawnQueue; // Queue that gascan respawns pop from to respawn to
|
ArrayList g_gascanRespawnQueue; // Queue that gascan respawns pop from to respawn to
|
||||||
|
@ -16,7 +16,97 @@ int g_iLaserIndex;
|
||||||
|
|
||||||
public void InitGlobals() {
|
public void InitGlobals() {
|
||||||
g_gascanSpawners = new AnyMap();
|
g_gascanSpawners = new AnyMap();
|
||||||
g_mapTraverseSelections = new StringMap();
|
g_mapTraverseSelectionStack = new ArrayList(sizeof(TraverseData));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum struct TraverseData {
|
||||||
|
char map[64];
|
||||||
|
ArrayList selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
methodmap SceneSelection < ArrayList {
|
||||||
|
public SceneSelection() {
|
||||||
|
ArrayList selectedScenes = new ArrayList(sizeof(SelectedSceneData));
|
||||||
|
return view_as<SceneSelection>(selectedScenes);
|
||||||
|
}
|
||||||
|
|
||||||
|
property int Count {
|
||||||
|
public get() {
|
||||||
|
return (view_as<ArrayList>(this)).Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Cleanup() {
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Activate(MapData data, int flags = 0) {
|
||||||
|
g_ropeIndex = 0;
|
||||||
|
SelectedSceneData aScene;
|
||||||
|
SceneData scene;
|
||||||
|
SceneVariantData choice;
|
||||||
|
ArrayList list = view_as<ArrayList>(this);
|
||||||
|
for(int i = 0; i < list.Length; i++) {
|
||||||
|
list.GetArray(i, aScene);
|
||||||
|
Log("Activating scene \"%s\" with %d variants", aScene.name, aScene.selectedVariantIndexes.Length);
|
||||||
|
|
||||||
|
// Fetch the scene that aScene marks
|
||||||
|
if(!data.scenesKv.GetArray(aScene.name, scene, sizeof(scene))) {
|
||||||
|
Log("WARN: Selected scene \"%s\" not found, skipping", aScene.name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int v = 0; v < aScene.selectedVariantIndexes.Length; v++) {
|
||||||
|
int variantIndex = aScene.selectedVariantIndexes.Get(v);
|
||||||
|
|
||||||
|
|
||||||
|
scene.variants.GetArray(variantIndex, choice);
|
||||||
|
activateVariant(choice, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Get(int sceneIndex, SelectedSceneData scene) {
|
||||||
|
(view_as<ArrayList>(this)).GetArray(sceneIndex, scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
property ArrayList List {
|
||||||
|
public get() {
|
||||||
|
return view_as<ArrayList>(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddScene(SelectedSceneData aScene) {
|
||||||
|
view_as<ArrayList>(this).PushArray(aScene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreTraverseSelection(const char[] name, SceneSelection selection) {
|
||||||
|
// Pushes selection and map to the stack
|
||||||
|
TraverseData data;
|
||||||
|
strcopy(data.map, sizeof(data.map), name);
|
||||||
|
data.selection = selection.List.Clone();
|
||||||
|
g_mapTraverseSelectionStack.PushArray(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PopTraverseSelection(TraverseData data) {
|
||||||
|
if(g_mapTraverseSelectionStack.Length == 0) {
|
||||||
|
Log("WARN: PopTraverseSelection() called but stack is empty");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int index = g_mapTraverseSelectionStack.Length - 1;
|
||||||
|
g_mapTraverseSelectionStack.GetArray(index, data);
|
||||||
|
g_mapTraverseSelectionStack.Erase(index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearTraverseStack() {
|
||||||
|
TraverseData trav;
|
||||||
|
for(int i = 0; i < g_mapTraverseSelectionStack.Length; i++) {
|
||||||
|
g_mapTraverseSelectionStack.GetArray(i, trav, sizeof(trav));
|
||||||
|
delete trav.selection;
|
||||||
|
}
|
||||||
|
g_mapTraverseSelectionStack.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
enum struct SelectedSceneData {
|
enum struct SelectedSceneData {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
public bool LoadGlobalMapData(const char[] map, int flags) {
|
public bool LoadGlobalMapData(const char[] map, int flags) {
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
g_selection = null;
|
||||||
return ParseMapData(g_MapData, map, flags);
|
return ParseMapData(g_MapData, map, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,30 @@
|
||||||
|
bool IsTraverseMapA(const char[] map) {
|
||||||
|
return String_EndsWith(map, "_a");
|
||||||
|
}
|
||||||
|
bool IsTraverseMapB(const char[] map) {
|
||||||
|
// c4m1_milltown_a was added twice so _escape can pop it off and re-use
|
||||||
|
return StrEqual(map, "c4m5_milltown_escape") || String_EndsWith(map, "_b");
|
||||||
|
}
|
||||||
|
|
||||||
public bool LoadRunGlobalMap(const char[] map, int flags) {
|
public bool LoadRunGlobalMap(const char[] map, int flags) {
|
||||||
// Unless FLAG_IGNORE_TRAVERSE_STORE, if the map is the _b variant, then load the stored _a value
|
// Unless FLAG_IGNORE_TRAVERSE_STORE, if the map is the _b variant, then load the stored _a value
|
||||||
SceneSelection selection;
|
SceneSelection selection;
|
||||||
// Only load map data if we don't already have it
|
// Only load map data if we don't already have it
|
||||||
if(g_MapData.scenes == null || g_selection == null || flags & view_as<int>(FLAG_REFRESH)) {
|
if(g_MapData.scenes == null || g_selection == null || flags & view_as<int>(FLAG_REFRESH)) {
|
||||||
if(~flags & view_as<int>(FLAG_IGNORE_TRAVERSE_STORE) && String_EndsWith(map, "_b")) {
|
if(~flags & view_as<int>(FLAG_IGNORE_TRAVERSE_STORE) && IsTraverseMapB(map) ) {
|
||||||
// Switch _b to _a
|
Log("LoadRunGlobal: Trying to load traverse selection");
|
||||||
char buffer[64];
|
TraverseData traverse;
|
||||||
int len = strcopy(buffer, sizeof(buffer), map);
|
if(PopTraverseSelection(traverse)) {
|
||||||
buffer[len-1] = 'a';
|
Debug("traverse map: %s", traverse.map);
|
||||||
|
// Try Load the A variant
|
||||||
// Load the A variant
|
if(LoadGlobalMapData(traverse.map, flags)) {
|
||||||
if(!LoadGlobalMapData(buffer, flags)) {
|
selection = view_as<SceneSelection>(traverse.selection);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load selection from the traverse store, if it exists
|
|
||||||
ArrayList list;
|
|
||||||
if(g_mapTraverseSelections.GetValue(buffer, list)) {
|
|
||||||
Log("Loaded previously traversed map selection (c:%s p:%s)", map, buffer);
|
|
||||||
selection = view_as<SceneSelection>(list);
|
|
||||||
} else {
|
|
||||||
Log("Tried to load previously traversed map selection, but nothing stored (c:%s p:%s)", map, buffer);
|
|
||||||
}
|
}
|
||||||
} else if(selection == null) {
|
}
|
||||||
|
if(selection == null) {
|
||||||
// This is called if not traverse map or previous data not found
|
// This is called if not traverse map or previous data not found
|
||||||
|
Log("LoadRunGlobal: Loading & generating selection");
|
||||||
if(!LoadGlobalMapData(map, flags)) {
|
if(!LoadGlobalMapData(map, flags)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -163,62 +164,6 @@ void selectForcedScenes(SceneSelection selection, MapData data, int flags) {
|
||||||
delete forcedScenes;
|
delete forcedScenes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: the scenes that are selected need variant index set
|
|
||||||
methodmap SceneSelection < ArrayList {
|
|
||||||
public SceneSelection() {
|
|
||||||
ArrayList selectedScenes = new ArrayList(sizeof(SelectedSceneData));
|
|
||||||
return view_as<SceneSelection>(selectedScenes);
|
|
||||||
}
|
|
||||||
|
|
||||||
property int Count {
|
|
||||||
public get() {
|
|
||||||
return (view_as<ArrayList>(this)).Length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Cleanup() {
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Activate(MapData data, int flags = 0) {
|
|
||||||
g_ropeIndex = 0;
|
|
||||||
SelectedSceneData aScene;
|
|
||||||
SceneData scene;
|
|
||||||
SceneVariantData choice;
|
|
||||||
ArrayList list = view_as<ArrayList>(this);
|
|
||||||
for(int i = 0; i < list.Length; i++) {
|
|
||||||
list.GetArray(i, aScene);
|
|
||||||
Log("Activating scene \"%s\" with %d variants", aScene.name, aScene.selectedVariantIndexes.Length);
|
|
||||||
|
|
||||||
// Fetch the scene that aScene marks
|
|
||||||
if(!data.scenesKv.GetArray(aScene.name, scene, sizeof(scene))) {
|
|
||||||
Log("WARN: Selected scene \"%s\" not found, skipping", aScene.name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int v = 0; v < aScene.selectedVariantIndexes.Length; v++) {
|
|
||||||
int variantIndex = aScene.selectedVariantIndexes.Get(v);
|
|
||||||
|
|
||||||
|
|
||||||
scene.variants.GetArray(variantIndex, choice);
|
|
||||||
activateVariant(choice, flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Get(int sceneIndex, SelectedSceneData scene) {
|
|
||||||
(view_as<ArrayList>(this)).GetArray(sceneIndex, scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList AsList() {
|
|
||||||
return view_as<ArrayList>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddScene(SelectedSceneData aScene) {
|
|
||||||
view_as<ArrayList>(this).PushArray(aScene);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Selects what scenes and its variants to apply and returns list - does not activate
|
// Selects what scenes and its variants to apply and returns list - does not activate
|
||||||
SceneSelection selectScenes(MapData data, int flags = 0) {
|
SceneSelection selectScenes(MapData data, int flags = 0) {
|
||||||
SceneData scene;
|
SceneData scene;
|
||||||
|
|
|
@ -72,8 +72,8 @@ public void OnPluginStart() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Event_GameEnd(Event event, const char[] name ,bool dontBroadcast) {
|
void Event_GameEnd(Event event, const char[] name ,bool dontBroadcast) {
|
||||||
// Purge the traverse list after a campaign is played
|
// Purge the traverse stack after a campaign is played
|
||||||
g_mapTraverseSelections.Clear();
|
ClearTraverseStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,7 +97,6 @@ public void OnMapStart() {
|
||||||
// We wait a while before running to prevent some edge cases i don't remember
|
// We wait a while before running to prevent some edge cases i don't remember
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void OnMapEnd() {
|
public void OnMapEnd() {
|
||||||
randomizerRan = false;
|
randomizerRan = false;
|
||||||
g_builder.Cleanup();
|
g_builder.Cleanup();
|
||||||
|
@ -105,9 +104,15 @@ public void OnMapEnd() {
|
||||||
// For maps that players traverse backwards, like hard rain (c4m1_milltown_a -> c4m3_milltown_b )
|
// For maps that players traverse backwards, like hard rain (c4m1_milltown_a -> c4m3_milltown_b )
|
||||||
// We store the selection of the _a map, to later be loaded for _b maps
|
// We store the selection of the _a map, to later be loaded for _b maps
|
||||||
// This is done at end of map just in case a user re-runs the cycle and generates a different selection
|
// This is done at end of map just in case a user re-runs the cycle and generates a different selection
|
||||||
if(g_selection != null && String_EndsWith(currentMap, "_a")) {
|
if(g_selection != null) {
|
||||||
|
if(IsTraverseMapA(currentMap)) {
|
||||||
Log("Storing %s in map traversal store", currentMap);
|
Log("Storing %s in map traversal store", currentMap);
|
||||||
g_mapTraverseSelections.SetValue(currentMap, g_selection.AsList());
|
StoreTraverseSelection(currentMap, g_selection);
|
||||||
|
}
|
||||||
|
// We want to store milltown_a twice, so the c4m5_milltown_escape can also pop it off
|
||||||
|
if(StrEqual(currentMap, "c4m1_milltown_a")) {
|
||||||
|
StoreTraverseSelection(currentMap, g_selection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// don't clear entities because they will be deleted anyway (and errors if you tryq)
|
// don't clear entities because they will be deleted anyway (and errors if you tryq)
|
||||||
Cleanup(false);
|
Cleanup(false);
|
||||||
|
@ -176,6 +181,25 @@ Action Command_Debug(int client, int args) {
|
||||||
ReplyToCommand(client, "No map data loaded");
|
ReplyToCommand(client, "No map data loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} if(StrEqual(arg, "traverse")) {
|
||||||
|
TraverseData trav;
|
||||||
|
for(int i = 0; i < g_mapTraverseSelectionStack.Length; i++) {
|
||||||
|
g_mapTraverseSelectionStack.GetArray(i, trav, sizeof(trav));
|
||||||
|
if(trav.selection == null) {
|
||||||
|
ReplyToCommand(client, " #%d - %s: ERROR", i, trav.map);
|
||||||
|
} else {
|
||||||
|
ReplyToCommand(client, " #%d - %s: %d scenes", i, trav.map, trav.selection.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(StrEqual(arg, "store")) {
|
||||||
|
char buffer[64];
|
||||||
|
if(args == 1) {
|
||||||
|
strcopy(buffer, sizeof(buffer), currentMap);
|
||||||
|
} else {
|
||||||
|
GetCmdArg(2, buffer, sizeof(buffer));
|
||||||
|
}
|
||||||
|
StoreTraverseSelection(buffer, g_selection);
|
||||||
|
ReplyToCommand(client, "Stored current selection as %s", buffer);
|
||||||
} /*else if(StrEqual(arg, "identify")) {
|
} /*else if(StrEqual(arg, "identify")) {
|
||||||
if(args == 1) {
|
if(args == 1) {
|
||||||
ReplyToCommand(client, "Specify scene name");
|
ReplyToCommand(client, "Specify scene name");
|
||||||
|
@ -200,7 +224,7 @@ Action Command_Debug(int client, int args) {
|
||||||
ReplyToCommand(client, "Scene Selection: -");
|
ReplyToCommand(client, "Scene Selection: -");
|
||||||
}
|
}
|
||||||
ReplyToCommand(client, "Builder Data: %s", g_builder.IsLoaded() ? "Loaded" : "-");
|
ReplyToCommand(client, "Builder Data: %s", g_builder.IsLoaded() ? "Loaded" : "-");
|
||||||
ReplyToCommand(client, "Traverse Store: count=%d", g_mapTraverseSelections.Size);
|
ReplyToCommand(client, "Traverse Store: count=%d", g_mapTraverseSelectionStack.Length);
|
||||||
if(g_gascanRespawnQueue != null) {
|
if(g_gascanRespawnQueue != null) {
|
||||||
ReplyToCommand(client, "Gascan Spawners: count=%d queue_size=%d", g_gascanSpawners.Size, g_gascanRespawnQueue.Length);
|
ReplyToCommand(client, "Gascan Spawners: count=%d queue_size=%d", g_gascanSpawners.Size, g_gascanRespawnQueue.Length);
|
||||||
} else {
|
} else {
|
||||||
|
@ -213,11 +237,13 @@ public Action Command_CycleRandom(int client, int args) {
|
||||||
if(args > 0) {
|
if(args > 0) {
|
||||||
DeleteCustomEnts();
|
DeleteCustomEnts();
|
||||||
int flags = GetCmdArgInt(1);
|
int flags = GetCmdArgInt(1);
|
||||||
if(flags != -1) {
|
if(flags < 0) {
|
||||||
|
ReplyToCommand(client, "Invalid flags");
|
||||||
|
} else {
|
||||||
LoadRunGlobalMap(currentMap, flags | view_as<int>(FLAG_REFRESH));
|
LoadRunGlobalMap(currentMap, flags | view_as<int>(FLAG_REFRESH));
|
||||||
}
|
|
||||||
if(client > 0)
|
if(client > 0)
|
||||||
PrintCenterText(client, "Cycled flags=%d", flags);
|
PrintCenterText(client, "Cycled flags=%d", flags);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(g_selection == null) {
|
if(g_selection == null) {
|
||||||
ReplyToCommand(client, "No map selection active");
|
ReplyToCommand(client, "No map selection active");
|
||||||
|
@ -705,6 +731,7 @@ int CreateLight(const float origin[3], const float angles[3], const int color[4]
|
||||||
TeleportEntity(entity, origin, NULL_VECTOR, NULL_VECTOR);
|
TeleportEntity(entity, origin, NULL_VECTOR, NULL_VECTOR);
|
||||||
if(!DispatchSpawn(entity)) return -1;
|
if(!DispatchSpawn(entity)) return -1;
|
||||||
SetEntityRenderColor(entity, color[0], color[1], color[2], color[3]);
|
SetEntityRenderColor(entity, color[0], color[1], color[2], color[3]);
|
||||||
|
SetEntityRenderMode(entity, RENDER_TRANSCOLOR);
|
||||||
AcceptEntityInput(entity, "TurnOn");
|
AcceptEntityInput(entity, "TurnOn");
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue