mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 16:43:21 +00:00
Update things
This commit is contained in:
parent
9590ceb207
commit
d4f9241b3c
25 changed files with 650 additions and 345 deletions
|
@ -155,7 +155,7 @@ enum struct EditorData {
|
|||
|
||||
bool CheckEntity() {
|
||||
if(this.entity != INVALID_ENT_REFERENCE) {
|
||||
if(!IsValidEntity(this.entity)) {
|
||||
if(this.entity == -1 && !IsValidEntity(this.entity)) {
|
||||
PrintToChat(this.client, "\x04[Editor]\x01 Entity has vanished, editing cancelled.");
|
||||
this.Reset();
|
||||
return false;
|
||||
|
@ -301,7 +301,7 @@ enum struct EditorData {
|
|||
char component[16];
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(this.colorIndex == i)
|
||||
Format(component, sizeof(component), "%s \x05 %c \x01", component, COLOR_INDEX[i]);
|
||||
Format(component, sizeof(component), "%s \x05%c\x01", component, COLOR_INDEX[i]);
|
||||
else
|
||||
Format(component, sizeof(component), "%s %c", component, COLOR_INDEX[i]);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
char g_pendingSaveName[64];
|
||||
int g_pendingSaveClient;
|
||||
ArrayList g_previewItems;
|
||||
CategoryData ROOT_CATEGORY;
|
||||
ArrayList g_spawnedItems; // ArrayList(block=2)<entRef, [creator]>
|
||||
ArrayList g_savedItems; // ArrayList<entRef>
|
||||
StringMap g_recentItems; // Key: model[128], value: RecentEntry
|
||||
|
||||
/* Wish to preface this file:
|
||||
* It's kinda messy. The main structs are:
|
||||
|
@ -12,7 +16,123 @@ The rest are kinda necessary, for sorting reasons (SearchData, RecentEntry).
|
|||
enum ChatPrompt {
|
||||
Prompt_None,
|
||||
Prompt_Search,
|
||||
Prompt_Save
|
||||
Prompt_SaveScene,
|
||||
Prompt_SaveSchematic
|
||||
}
|
||||
enum SaveType {
|
||||
Save_None,
|
||||
Save_Scene,
|
||||
Save_Schematic
|
||||
}
|
||||
|
||||
enum struct Schematic {
|
||||
char name[64];
|
||||
char creatorSteamid[32];
|
||||
char creatorName[32];
|
||||
ArrayList entities;
|
||||
|
||||
void Reset() {
|
||||
this.name[0] = '\0';
|
||||
this.creatorSteamid[0] = '\0';
|
||||
this.creatorName[0] = '\0';
|
||||
if(this.entities != null) delete this.entities;
|
||||
}
|
||||
|
||||
void AddEntity(int entity, int client) {
|
||||
SaveData save;
|
||||
save.FromEntity(entity);
|
||||
this.entities.PushArray(save);
|
||||
}
|
||||
|
||||
void New(int client, const char[] name) {
|
||||
if(client > 0) {
|
||||
GetClientName(client, this.creatorName, sizeof(this.creatorName));
|
||||
GetClientAuthId(client, AuthId_Steam2, this.creatorSteamid, sizeof(this.creatorSteamid));
|
||||
}
|
||||
strcopy(this.name, sizeof(this.name), name);
|
||||
this.entities = new ArrayList(sizeof(SaveData));
|
||||
}
|
||||
|
||||
bool Save() {
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, path, sizeof(path), "data/prop_spawner/schematics/%s.schem", this.name);
|
||||
CreateDirectory("data/prop_spawner/schematics", 0775);
|
||||
KeyValues kv = new KeyValues(this.name);
|
||||
kv.SetString("creator_steamid", this.creatorSteamid);
|
||||
kv.SetString("creator_name", this.creatorName);
|
||||
kv.JumpToKey("entities");
|
||||
this.entities = new ArrayList(sizeof(SaveData));
|
||||
SaveData ent;
|
||||
while(kv.GotoNextKey()) {
|
||||
kv.GetVector("offset", ent.origin);
|
||||
kv.GetVector("angles", ent.angles);
|
||||
kv.GetColor4("color", ent.color);
|
||||
kv.GetString("model", ent.model, sizeof(ent.model));
|
||||
this.entities.PushArray(ent);
|
||||
}
|
||||
kv.ExportToFile(path);
|
||||
delete kv;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Import(const char[] name) {
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, path, sizeof(path), "data/prop_spawner/schematics/%s.schem", name);
|
||||
KeyValues kv = new KeyValues("root");
|
||||
if(kv.ImportFromFile(path)) {
|
||||
delete kv;
|
||||
return false;
|
||||
}
|
||||
strcopy(this.name, sizeof(this.name), name);
|
||||
kv.GetString("creator_steamid", this.creatorSteamid, sizeof(this.creatorSteamid));
|
||||
kv.GetString("creator_name", this.creatorName, sizeof(this.creatorName));
|
||||
kv.JumpToKey("entities");
|
||||
this.entities = new ArrayList(sizeof(SaveData));
|
||||
SaveData ent;
|
||||
while(kv.GotoNextKey()) {
|
||||
kv.GetVector("offset", ent.origin);
|
||||
kv.GetVector("angles", ent.angles);
|
||||
kv.GetColor4("color", ent.color);
|
||||
kv.GetString("model", ent.model, sizeof(ent.model));
|
||||
this.entities.PushArray(ent);
|
||||
}
|
||||
delete kv;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Spawns all schematics entities, returns list of entities, first being parent.
|
||||
ArrayList SpawnEntities(const float origin[3], bool asPreview = true) {
|
||||
if(this.entities == null) return null;
|
||||
SaveData ent;
|
||||
int parent = -1;
|
||||
ArrayList spawnedEntities = new ArrayList();
|
||||
for(int i = 0; i < this.entities.Length; i++) {
|
||||
this.entities.GetArray(i, ent, sizeof(ent));
|
||||
int entity = ent.ToEntity(origin, asPreview);
|
||||
spawnedEntities.Push(EntIndexToEntRef(entity));
|
||||
if(i == 0) {
|
||||
SetParent(entity, parent)
|
||||
} else {
|
||||
parent = entity;
|
||||
}
|
||||
}
|
||||
return spawnedEntities;
|
||||
}
|
||||
}
|
||||
public any Native_SpawnSchematic(Handle plugin, int numParams) {
|
||||
char name[32];
|
||||
float pos[3];
|
||||
float ang[3];
|
||||
GetNativeString(0, name, sizeof(name));
|
||||
GetNativeArray(1, pos, 3);
|
||||
GetNativeArray(1, ang, 3);
|
||||
Schematic schem;
|
||||
if(!schem.Import(name)) {
|
||||
return false;
|
||||
}
|
||||
ArrayList list = schem.SpawnEntities(pos, false);
|
||||
delete list;
|
||||
return true;
|
||||
}
|
||||
enum struct PlayerPropData {
|
||||
ArrayList categoryStack;
|
||||
|
@ -25,6 +145,9 @@ enum struct PlayerPropData {
|
|||
char classnameOverride[64];
|
||||
ChatPrompt chatPrompt;
|
||||
ArrayList markedProps;
|
||||
SaveType pendingSaveType;
|
||||
|
||||
Schematic schematic;
|
||||
|
||||
// Called on PlayerDisconnect
|
||||
void Reset() {
|
||||
|
@ -36,6 +159,15 @@ enum struct PlayerPropData {
|
|||
this.lastActiveTime = 0;
|
||||
this.classnameOverride[0] = '\0';
|
||||
this.CleanupBuffers();
|
||||
this.pendingSaveType = Save_None;
|
||||
this.schematic.Reset();
|
||||
}
|
||||
|
||||
void StartSchematic(int client, const char[] name) {
|
||||
this.schematic.New(client, name);
|
||||
this.pendingSaveType = Save_Schematic;
|
||||
PrintToChat(client, "\x04[Editor]\x01 Started new schematic: \x05%s", name);
|
||||
ShowCategoryList(client, ROOT_CATEGORY);
|
||||
}
|
||||
|
||||
// Sets the list buffer
|
||||
|
@ -97,6 +229,7 @@ enum struct PlayerPropData {
|
|||
}
|
||||
PlayerPropData g_PropData[MAXPLAYERS+1];
|
||||
|
||||
|
||||
enum struct CategoryData {
|
||||
// The display name of category
|
||||
char name[64];
|
||||
|
@ -124,6 +257,8 @@ enum struct SearchData {
|
|||
strcopy(this.name, sizeof(this.name), item.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum struct SaveData {
|
||||
char model[128];
|
||||
buildType type;
|
||||
|
@ -148,6 +283,43 @@ enum struct SaveData {
|
|||
GetEntityRenderColor(entity, this.color[0],this.color[1],this.color[2],this.color[3]);
|
||||
}
|
||||
|
||||
int ToEntity(const float offset[3], bool asPreview = true) {
|
||||
int entity = -1;
|
||||
if(this.type == Build_Physics)
|
||||
entity = CreateEntityByName("prop_physics");
|
||||
else
|
||||
entity = CreateEntityByName("prop_dynamic_override");
|
||||
if(entity == -1) {
|
||||
return -1;
|
||||
}
|
||||
PrecacheModel(this.model);
|
||||
DispatchKeyValue(entity, "model", this.model);
|
||||
DispatchKeyValue(entity, "targetname", "saved_prop");
|
||||
if(asPreview) {
|
||||
DispatchKeyValue(entity, "rendermode", "1");
|
||||
DispatchKeyValue(entity, "solid", "0");
|
||||
} else {
|
||||
DispatchKeyValue(entity, "solid", this.type == Build_NonSolid ? "0" : "6");
|
||||
}
|
||||
float pos[3];
|
||||
for(int i = 0; i < 3; i++)
|
||||
pos[i] = this.origin[i] + offset[i];
|
||||
|
||||
TeleportEntity(entity, pos, this.angles, NULL_VECTOR);
|
||||
if(!DispatchSpawn(entity)) {
|
||||
return -1;
|
||||
}
|
||||
int alpha = asPreview ? 200 : this.color[3];
|
||||
SetEntityRenderColor(entity, this.color[0], this.color[1], this.color[2], alpha);
|
||||
|
||||
if(asPreview)
|
||||
g_previewItems.Push(EntIndexToEntRef(entity));
|
||||
else
|
||||
AddSpawnedItem(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
void Serialize(char[] output, int maxlen) {
|
||||
Format(
|
||||
output, maxlen, "%s,%d,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%d,%d,%d,%d",
|
||||
|
@ -181,10 +353,6 @@ enum struct RecentEntry {
|
|||
char name[64];
|
||||
int count;
|
||||
}
|
||||
CategoryData ROOT_CATEGORY;
|
||||
ArrayList g_spawnedItems; // ArrayList(block=2)<entRef, [creator]>
|
||||
ArrayList g_savedItems; // ArrayList<entRef>
|
||||
StringMap g_recentItems; // Key: model[128], value: RecentEntry
|
||||
|
||||
#include <hats/props/db.sp>
|
||||
#include <hats/props/methods.sp>
|
||||
|
|
|
@ -12,6 +12,27 @@ Action Command_Props(int client, int args) {
|
|||
PrintToConsole(client, "favorite - favorites active editor entity");
|
||||
PrintToConsole(client, "controls - list all the controls");
|
||||
PrintToConsole(client, "reload - reload prop list");
|
||||
PrintToConsole(client, "schem[atic] <new/save/edit/delete/load> <name>");
|
||||
} else if(StrEqual(arg, "schem") || StrEqual(arg, "schematic")) {
|
||||
char arg2[16];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if(StrEqual(arg2, "new")) {
|
||||
char name[32];
|
||||
GetCmdArg(3, name, sizeof(name));
|
||||
if(name[0] == '\0') {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Please enter a name");
|
||||
} else {
|
||||
g_PropData[client].StartSchematic(client, name);
|
||||
}
|
||||
} else if(StrEqual(arg2, "save")) {
|
||||
if(g_PropData[client].pendingSaveType == Save_Schematic) {
|
||||
g_PropData[client].schematic.Save();
|
||||
} else {
|
||||
PrintToChat(client, "\x04[Editor]\x01 No schematic to save.");
|
||||
}
|
||||
} else {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Unknown option: %s", arg2);
|
||||
}
|
||||
} else if(StrEqual(arg, "list")) {
|
||||
char arg2[16];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
|
|
|
@ -75,44 +75,89 @@ void AdminMenu_SaveLoad(TopMenu topmenu, TopMenuAction action, TopMenuObject obj
|
|||
if(action == TopMenuAction_DisplayOption) {
|
||||
Format(buffer, maxlength, "Save / Load");
|
||||
} else if(action == TopMenuAction_SelectOption) {
|
||||
Menu menu = new Menu(SaveLoadHandler);
|
||||
menu.SetTitle("Save / Load");
|
||||
char name[64];
|
||||
// TODO: possibly let you overwrite saves?
|
||||
menu.AddItem("", "[New Save]");
|
||||
ArrayList saves = LoadSaves();
|
||||
if(saves != null) {
|
||||
for(int i = 0; i < saves.Length; i++) {
|
||||
saves.GetString(i, name, sizeof(name));
|
||||
menu.AddItem(name, name);
|
||||
}
|
||||
delete saves;
|
||||
}
|
||||
menu.ExitBackButton = true;
|
||||
menu.ExitButton = true;
|
||||
menu.Display(param, MENU_TIME_FOREVER);
|
||||
Spawn_ShowSaveLoadMainMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
int SaveLoadHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
int SaveLoadMainMenuHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
char info[2];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
SaveType type = view_as<SaveType>(StringToInt(info));
|
||||
ShowSaves(client, type);
|
||||
} else if (action == MenuAction_Cancel) {
|
||||
if(param2 == MenuCancel_ExitBack) {
|
||||
Spawn_ShowSaveLoadMainMenu(client);
|
||||
}
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SaveLoadSceneHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
char saveName[64];
|
||||
menu.GetItem(param2, saveName, sizeof(saveName));
|
||||
if(saveName[0] == '\0') {
|
||||
// Save new
|
||||
FormatTime(saveName, sizeof(saveName), "%Y-%m-%d_%H-%I-%M");
|
||||
if(CreateSave(saveName)) {
|
||||
if(CreateSceneSave(saveName)) {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Saved as \x05%s/%s.txt", g_currentMap, saveName);
|
||||
} else {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Unable to save. Sorry.");
|
||||
}
|
||||
} else if(LoadSave(saveName, true)) {
|
||||
strcopy(g_pendingSaveName, sizeof(g_pendingSaveName), saveName);
|
||||
} else if(g_pendingSaveClient != 0 && g_pendingSaveClient != client) {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Another user is currently loading a save.");
|
||||
} else if(g_PropData[client].pendingSaveType == Save_Schematic) {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Please complete or cancel current schematic to continue.");
|
||||
} else if(LoadScene(saveName, true)) {
|
||||
ConfirmSave(client, saveName);
|
||||
g_pendingSaveClient = client;
|
||||
PrintToChat(client, "\x04[Editor]\x01 Previewing save \x05%s", saveName);
|
||||
PrintToChat(client, "\x04[Editor]\x01 Press \x05Shift + Middle Mouse\x01 to spawn, \x05Middle Mouse\x01 to cancel");
|
||||
} else {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Could not load save file.");
|
||||
}
|
||||
} else if (action == MenuAction_Cancel) {
|
||||
if(param2 == MenuCancel_ExitBack) {
|
||||
Spawn_ShowSaveLoadMainMenu(client);
|
||||
}
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SaveLoadSchematicHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
char saveName[64];
|
||||
menu.GetItem(param2, saveName, sizeof(saveName));
|
||||
Schematic schem;
|
||||
if(saveName[0] == '\0') {
|
||||
if(g_PropData[client].pendingSaveType == Save_Schematic) {
|
||||
if(g_PropData[client].schematic.Save()) {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Saved schematic as \x05%s", g_PropData[client].schematic.name);
|
||||
} else {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Failed to save schematic.");
|
||||
}
|
||||
g_PropData[client].schematic.Reset();
|
||||
g_PropData[client].pendingSaveType = Save_None;
|
||||
} else {
|
||||
g_PropData[client].chatPrompt = Prompt_SaveSchematic;
|
||||
PrintToChat(client, "\x04[Editor]\x01 Enter in chat a name for schematic");
|
||||
}
|
||||
} else if(schem.Import(saveName)) {
|
||||
float pos[3];
|
||||
GetCursorLocation(client, pos);
|
||||
ArrayList list = schem.SpawnEntities(pos, true);
|
||||
SaveData save;
|
||||
int parent = list.GetArray(0, save);
|
||||
delete list;
|
||||
Editor[client].Import(parent);
|
||||
if(g_pendingSaveClient != 0 && g_pendingSaveClient != client) {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Another user is currently loading a save.");
|
||||
PrintToChat(client, "\x04[Editor]\x01 Another user is currently loading a scene.");
|
||||
} else {
|
||||
g_pendingSaveClient = client;
|
||||
PrintToChat(client, "\x04[Editor]\x01 Previewing save \x05%s", saveName);
|
||||
PrintToChat(client, "\x04[Editor]\x01 Previewing schematic \x05%s", saveName);
|
||||
PrintToChat(client, "\x04[Editor]\x01 Press \x05Shift + Middle Mouse\x01 to spawn, \x05Middle Mouse\x01 to cancel");
|
||||
}
|
||||
} else {
|
||||
|
@ -120,12 +165,31 @@ int SaveLoadHandler(Menu menu, MenuAction action, int client, int param2) {
|
|||
}
|
||||
} else if (action == MenuAction_Cancel) {
|
||||
if(param2 == MenuCancel_ExitBack) {
|
||||
DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, client);
|
||||
Spawn_ShowSaveLoadMainMenu(client);
|
||||
}
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SaveLoadConfirmHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
ClearSavePreview();
|
||||
char info[64];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
if(info[0] != '\0') {
|
||||
PrintToChat(client, "\x04[Editor]\x01 Loaded scene \x05%s", info);
|
||||
LoadScene(info, false);
|
||||
}
|
||||
} else if (action == MenuAction_Cancel) {
|
||||
if(param2 == MenuCancel_ExitBack) {
|
||||
Spawn_ShowSaveLoadMainMenu(client);
|
||||
}
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DeleteHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
char info[8];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue