From b9b4dde36663dd924b2a273086df9c18b4aa3298 Mon Sep 17 00:00:00 2001 From: Jackz Date: Mon, 15 Jul 2024 11:38:22 -0500 Subject: [PATCH] Fix ignore --- .gitignore | 4 +- plugins/l4d2_editor.smx | Bin 79724 -> 81490 bytes scripting/include/editor/editor.sp | 1024 +++++++++++++++++ scripting/include/editor/natives.sp | 122 ++ scripting/include/editor/props/base.sp | 708 ++++++++++++ scripting/include/editor/props/cmd.sp | 139 +++ scripting/include/editor/props/db.sp | 125 ++ .../include/editor/props/menu_handlers.sp | 517 +++++++++ .../include/editor/props/menu_methods.sp | 317 +++++ scripting/include/editor/props/methods.sp | 565 +++++++++ scripting/l4d2_editor.sp | 8 +- 11 files changed, 3525 insertions(+), 4 deletions(-) create mode 100644 scripting/include/editor/editor.sp create mode 100644 scripting/include/editor/natives.sp create mode 100644 scripting/include/editor/props/base.sp create mode 100644 scripting/include/editor/props/cmd.sp create mode 100644 scripting/include/editor/props/db.sp create mode 100644 scripting/include/editor/props/menu_handlers.sp create mode 100644 scripting/include/editor/props/menu_methods.sp create mode 100644 scripting/include/editor/props/methods.sp diff --git a/.gitignore b/.gitignore index d813fe4..8ccb237 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,6 @@ scripting/include/stats scripting/ssh.sp scripting/l4d2_witch_force_attack_cmd.sp l4d2_stats_plugin/ -!sql/* \ No newline at end of file +!sql/* +!scripting/.gitignore +!plugins/.gitignore \ No newline at end of file diff --git a/plugins/l4d2_editor.smx b/plugins/l4d2_editor.smx index 41841d6ee00e267dbe160d48eecafa41fb93342f..f8c6423c0135c76b123b4cad5cd4e8722c276f9f 100644 GIT binary patch literal 81490 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�Hb6Vm;?)uoSSqR4zO1vd>Y&beMme*{T4fv!4#$ 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 y3P#(n&c&1!_!k}&NTC2@HLN_{{IJLmjvDb literal 79724 zcmYhB2UL?m)2Ku5O+-L?k=_KPhoDGPnxYgb0cj$=*CZecO7BPqK~d>NdIt%;ONY=y z4?Tnga{0dd|L5MEoioqw&Q50Moi{njzM7hbMuY?eF7gC`2Tw=<_qYiF0A51Ce_#L6 z^qqtN(%YVNHzD8%2LMptGH(YFV1*n2V7g_(ej-4}?HbNo?iwHhgc1P&g17u+ga|;a z4**EqvL-t*V22U_P`G7DL1MrV0|20L%UA_s05ur^@bZ?))QAD4w`(nLxkjBBpnI#G zZv}tLvbQ?$R%D(M143@~=Ub_`<!~fUww)gp;o~?_GxA*^>ba1kF`CoVc_2A>>Yx}>p|8D^NKXwv! zZyhBZoLv4B-+$1>$?bp9$<4w2{|^3djQ_Q8ba8)cQSp? zSla}5#hnM%31p<^Jg(|GJRzDC^xW@40Wa>C)j6Hc_x#Y&w&M9DL_kDyC%@b`w%IcF z{vYk0&o2tI{x$S29p0CHwirv#T}cqGNq%Sga{=aXQT}vmvC(mBq!sli-x=1vu;}kN zf>ZR~8p@DCW}C6ovSz@uNHOWIK=>PjlElmU>7c{vT&8IwTVUXHP5O@v?y}d3)4#Np z^R?Lwi)chAG?|{J z#^gj4RcoU$|C87CNupe#wz*-EeZ<}Ma_wl53Cg=p529+HX}l@pEz?V^Gf12+(Pn#9 z6e}|EwQIYG5qQ6W|98tB`QMFbY^ZC373IFw2qAer6=`
iI7F`vTg`XVvSxAg5IlhdcDT4{}W0gX4wyk+W% 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�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 QlX=3@!Y`=$whtu#9}q1(this.stackerDirection) + 1; + if(newDirection == view_as(Stack_Down)) newDirection = 0; + this.stackerDirection = view_as(newDirection); + + PrintToChat(this.client, "\x04[Editor]\x01 Stacker: %s\x01", STACK_DIRECTION_NAME[this.stackerDirection]); + } + + void ToggleCollision() { + this.hasCollision = !this.hasCollision + PrintToChat(this.client, "\x04[Editor]\x01 Collision: %s", ON_OFF_STRING[view_as(this.hasCollision)]); + } + + void ToggleCollisionRotate() { + this.hasCollisionRotate = !this.hasCollisionRotate + PrintToChat(this.client, "\x04[Editor]\x01 Rotate with Collision: %s", ON_OFF_STRING[view_as(this.hasCollisionRotate)]); + } + + void CycleAxis() { + // if(tick - cmdThrottle[this.client] <= 0.1) return; + if(this.axis == 0) { + this.axis = 1; + PrintToChat(this.client, "\x04[Editor]\x01 Rotate Axis: \x05ROLL (Z)\x01"); + } else { + this.axis = 0; + PrintToChat(this.client, "\x04[Editor]\x01 Rotate Axis: \x05PITCH AND HEADING (X, Y)\x01"); + } + // cmdThrottle[this.client] = tick; + } + + void IncrementAxis(int axis, int mouse) { + if(this.snapAngle == 1) { + this.angles[axis] += mouse * this.rotateSpeed; + } else { + if(mouse > 0) this.angles[axis] += this.snapAngle; + else if(mouse < 0) this.angles[axis] -= this.snapAngle; + } + } + + void CycleSnapAngle(float tick) { + if(tick - cmdThrottle[this.client] <= 0.1) return; + switch(this.snapAngle) { + case 1: this.snapAngle = 15; + case 15: this.snapAngle = 30; + case 30: this.snapAngle = 45; + case 45: this.snapAngle = 90; + case 90: this.snapAngle = 1; + } + + // this.angles[0] = SnapTo(this.angles[0], float(this.snapAngle)); + // this.angles[1] = SnapTo(this.angles[1], float(this.snapAngle)); + // this.angles[2] = SnapTo(this.angles[2], float(this.snapAngle)); + + if(this.snapAngle == 1) + PrintToChat(this.client, "\x04[Editor]\x01 Rotate Snap Degrees: \x04(OFF)\x01", this.snapAngle); + else + PrintToChat(this.client, "\x04[Editor]\x01 Rotate Snap Degrees: \x05%d\x01", this.snapAngle); + cmdThrottle[this.client] = tick; + } + + void CycleSpeed(float tick) { + if(tick - cmdThrottle[this.client] <= 0.25) return; + this.moveSpeed++; + if(this.moveSpeed > 10) this.moveSpeed = 1; + PrintToChat(this.client, "\x04[Editor]\x01 Scale Speed: \x05%d\x01", this.moveSpeed); + cmdThrottle[this.client] = tick; + } + + void CycleBuildType() { + // No tick needed, is handled externally + if(this.classname[0] != '\0') { + PrintToChat(this.client, "\x04[Editor]\x01 Spawn as: \x05%s\x01 (fixed)", this.classname); + } else if(this.buildType == Build_Physics) { + this.buildType = Build_Solid; + PrintToChat(this.client, "\x04[Editor]\x01 Spawn as: \x05Solid\x01"); + } else if(this.buildType == Build_Solid) { + this.buildType = Build_Physics; + PrintToChat(this.client, "\x04[Editor]\x01 Spawn as: \x05Physics\x01"); + } else { + this.buildType = Build_NonSolid; + PrintToChat(this.client, "\x04[Editor]\x01 Spawn as: \x05Non Solid\x01"); + } + } + + void CycleColorComponent(float tick) { + if(tick - cmdThrottle[this.client] <= 0.25) return; + this.colorIndex++; + if(this.colorIndex > 3) this.colorIndex = 0; + 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]); + else + Format(component, sizeof(component), "%s %c", component, COLOR_INDEX[i]); + } + PrintToChat(this.client, "\x04[Editor]\x01 Color: %s", component); + cmdThrottle[this.client] = tick; + } + + void IncrementSize(int axis, float amount) { + this.size[axis] += amount; + if(this.size[axis] < 0.0) { + this.size[axis] = 0.0; + } + this.CalculateMins(); + } + + void IncreaseColor(int amount) { + int newValue = this.color[this.colorIndex] + amount; + if(newValue > 255) newValue = 255; + else if(newValue < 0) newValue = 0; + this.color[this.colorIndex] = newValue; + this.UpdateEntity(); + PrintCenterText(this.client, "%d %d %d %d", this.color[0], this.color[1], this.color[2], this.color[3]); + } + + // Complete the edit, wall creation, or spawning + CompleteType Done(int& entity) { + CompleteType type; + if(this.flags & Edit_WallCreator) { + type = this._FinishWall(entity) ? Complete_WallSuccess : Complete_WallError; + } else if(this.flags & Edit_Preview) { + type = this._FinishPreview(entity) ? Complete_PropSpawned : Complete_PropError; + } else { + // Is edit, do nothing, just reset + PrintHintText(this.client, "Edit Complete"); + this.Reset(); + entity = 0; + + type = Complete_EditSuccess; + } + if(this.callback) { + Call_StartForward(this.callback); + Call_PushCell(this.client); + Call_PushCell(entity); + Call_PushCell(type); + bool result; + Call_Finish(result); + // Cancel menu: + if(this.isEditCallback) delete this.callback; + if(this.isEditCallback || !result) { + // No native way to close a menu, so open a dummy menu and close it: + // Handler doesn't matter, no options are added + Menu menu = new Menu(Spawn_RootHandler); + menu.Display(this.client, 1); + } else { + delete this.callback; + } + } + return type; + } + + bool _FinishWall(int& id) { + if(~this.flags & Edit_WallCreator) { + this.Reset(); + return false; + } + // Don't need to build a new one if we editing: + int blocker = this.entity; + bool isEdit = false; + if(blocker != INVALID_ENT_REFERENCE) { + RemoveEntity(this.entity); + isEdit = true; + } + blocker = CreateEntityByName("func_brush"); + if(blocker == -1) return false; + DispatchKeyValueVector(blocker, "mins", this.mins); + DispatchKeyValueVector(blocker, "maxs", this.size); + DispatchKeyValueVector(blocker, "boxmins", this.mins); + DispatchKeyValueVector(blocker, "boxmaxs", this.size); + DispatchKeyValue(blocker, "excludednpc", "player"); + + DispatchKeyValueVector(blocker, "angles", this.angles); + DispatchKeyValue(blocker, "model", DUMMY_MODEL); + DispatchKeyValue(blocker, "intialstate", "1"); + // DispatchKeyValueVector(blocker, "angles", this.angles); + DispatchKeyValue(blocker, "BlockType", "4"); + char name[32]; + Format(name, sizeof(name), "editor_%d", createdWalls.Length); + DispatchKeyValue(blocker, "targetname", name); + // DispatchKeyValue(blocker, "excludednpc", "player"); + TeleportEntity(blocker, this.origin, this.angles, NULL_VECTOR); + if(!DispatchSpawn(blocker)) return false; + SetEntPropVector(blocker, Prop_Send, "m_vecMins", this.mins); + SetEntPropVector(blocker, Prop_Send, "m_vecMaxs", this.size); + SetEntProp(blocker, Prop_Send, "m_nSolidType", 2); + int enteffects = GetEntProp(blocker, Prop_Send, "m_fEffects"); + enteffects |= 32; //EF_NODRAW + SetEntProp(blocker, Prop_Send, "m_fEffects", enteffects); + AcceptEntityInput(blocker, "Enable"); + SDKHook(blocker, SDKHook_Use, OnWallClicked); + + this.Draw(GLOW_GREEN, 5.0, 1.0); + this.Reset(); + if(!isEdit) { + id = createdWalls.Push(EntIndexToEntRef(blocker)); + PrintToChat(this.client, "\x04[Editor]\x01 Created wall \x05#%d\x01.", id); + } + return true; + } + + bool _FinishPreview(int& entity) { + if(StrContains(this.classname, "weapon") > -1) { + entity = this._CreateWeapon(); + } else { + entity = this._CreateProp(); + } + + DispatchKeyValue(entity, "targetname", "editor_propspawner"); + TeleportEntity(entity, this.origin, this.angles, NULL_VECTOR); + if(!DispatchSpawn(entity)) { + return false; + } + SetEntityRenderColor(entity, this.color[0], this.color[1], this.color[2], this.color[3]); + SetEntityRenderColor(this.entity, 255, 128, 255, 200); // reset ghost color + GlowEntity(entity, 1.1); + + // Confusing when we resume into freelook, so reset + if(this.mode == FREELOOK) + this.SetMode(MOVE_ORIGIN); + + // Add to spawn list and add to recent list + AddSpawnedItem(entity, this.client); + char model[128]; + GetEntPropString(entity, Prop_Data, "m_ModelName", model, sizeof(model)); + AddRecent(model, this.name); + + // Get the new position for preview with regards to this.stackerDirection + if(this.stackerDirection != Stack_Off) { + float size[3]; + GetEntityDimensions(this.entity, size); + float sign = 1.0; + if(this.stackerDirection == Stack_Left || this.stackerDirection == Stack_Right) { + if(this.stackerDirection == Stack_Left) sign = -1.0; + GetSidePositionFromOrigin(this.origin, this.angles, sign * size[1] * 0.90, this.origin); + } else if(this.stackerDirection == Stack_Forward || this.stackerDirection == Stack_Backward) { + if(this.stackerDirection == Stack_Backward) sign = -1.0; + GetHorizontalPositionFromOrigin(this.origin, this.angles, sign * size[0] * 0.90, this.origin); + } else { + if(this.stackerDirection == Stack_Down) sign = -1.0; + this.origin[2] += (size[2] * sign); + } + } + PrintHintText(this.client, "%s\n%s", this.classname, this.data); + // PrintToChat(this.client, "\x04[Editor]\x01 Editing copy \x05%d\x01 of entity \x05%d\x01. End with \x05/edit done\x01 or \x04/edit cancel\x01", entity, oldEntity); + // Don't kill preview until cancel + return true; + } + + int _CreateWeapon() { + int entity = -1; + entity = CreateEntityByName(this.classname); + if(entity == -1) return -1; + if(StrEqual(this.classname, "weapon_melee_spawn")) { + DispatchKeyValue(entity, "melee_weapon", this.data); + } + DispatchKeyValue(entity, "count", "1"); + DispatchKeyValue(entity, "spawnflags", "10"); + return entity; + } + + int _CreateProp() { + int entity = -1; + if(this.classname[0] != '\0') { + entity = CreateEntityByName(this.classname); + } else if(this.buildType == Build_Physics) + entity = CreateEntityByName("prop_physics"); + else + entity = CreateEntityByName("prop_dynamic_override"); + if(entity == -1) return false; + + char model[128]; + GetEntPropString(this.entity, Prop_Data, "m_ModelName", model, sizeof(model)); + DispatchKeyValue(entity, "model", model); + if(this.buildType == Build_NonSolid) + DispatchKeyValue(entity, "solid", "0"); + else + DispatchKeyValue(entity, "solid", "6"); + return entity; + } + + // Turns current entity into a copy (not for walls) + int Copy() { + if(this.entity == INVALID_ENT_REFERENCE) return -1; + char classname[64]; + GetEntityClassname(this.entity, classname, sizeof(classname)); + + int entity = CreateEntityByName(classname); + if(entity == -1) return -1; + GetEntPropString(this.entity, Prop_Data, "m_ModelName", classname, sizeof(classname)); + DispatchKeyValue(entity, "model", classname); + + + Format(classname, sizeof(classname), "editor_%d", this.entity); + DispatchKeyValue(entity, "targetname", classname); + + DispatchKeyValue(entity, "solid", "6"); + + DispatchSpawn(entity); + if(StrEqual(this.classname, "prop_wall_breakable")) { + DispatchKeyValue(entity, "classname", "prop_door_rotating"); + } + TeleportEntity(entity, this.origin, this.angles, NULL_VECTOR); + this.entity = entity; + this.flags |= Edit_Copy; + return entity; + } + + // Start editing a new wall entity + void StartWall() { + this.Reset(); + this.flags |= Edit_WallCreator; + } + + bool PreviewWeapon(const char[] classname, const char[] data) { + int entity; + // Melee weapons don't have weapon_ prefix + this.Reset(); + // Rotate on it's side: + this.angles[2] = 90.0; + if(StrEqual(classname, "weapon_melee_spawn")) { + // no weapon_ prefix, its a melee + entity = CreateEntityByName(classname); + if(entity == -1) return false; + DispatchKeyValue(entity, "melee_weapon", data); + this.SetData(data); + strcopy(this.classname, sizeof(this.classname), classname); + } else { + entity = CreateEntityByName(data); + if(entity == -1) return false; + strcopy(this.classname, sizeof(this.classname), data); + } + DispatchKeyValue(entity, "count", "1"); + DispatchKeyValue(entity, "spawnflags", "10"); + DispatchKeyValue(entity, "targetname", "editor_preview"); + DispatchKeyValue(entity, "rendercolor", "255 128 255"); + DispatchKeyValue(entity, "renderamt", "200"); + DispatchKeyValue(entity, "rendermode", "1"); + TeleportEntity(entity, this.origin, NULL_VECTOR, NULL_VECTOR); // MUST teleport before spawn or it crashes + if(!DispatchSpawn(entity)) { + PrintToServer("Failed to spawn"); + return false; + } + this.entity = entity; + this.flags |= (Edit_Copy | Edit_Preview); + this.SetMode(MOVE_ORIGIN); + // Seems some entities fail here: + return IsValidEntity(entity); + } + + bool PreviewModel(const char[] model, const char[] classname = "") { + // Check for an invalid model + // this.origin is not cleared by this.Reset(); + this.Reset(); + GetClientAbsOrigin(this.client, this.origin); + if(StrEqual(classname, "_weapon") || StrEqual(classname, "weapon_melee_spawn")) { + // Pass in melee ID as data: + return this.PreviewWeapon(classname, model); + } + if(PrecacheModel(model) == 0) { + PrintToServer("Invalid model: %s", model); + return false; + } + this.Reset(); + int entity = CreateEntityByName("prop_door_rotating"); + if(classname[0] == '\0') { + entity = CreateEntityByName("prop_dynamic_override"); + } else { + strcopy(this.classname, sizeof(this.classname), classname); + entity = CreateEntityByName(classname); + } + if(entity == -1) { + PrintToServer("Invalid classname: %s", classname); + return false; + } + DispatchKeyValue(entity, "model", model); + DispatchKeyValue(entity, "targetname", "editor_preview"); + DispatchKeyValue(entity, "solid", "0"); + DispatchKeyValue(entity, "rendercolor", "255 128 255"); + DispatchKeyValue(entity, "renderamt", "255"); + DispatchKeyValue(entity, "rendermode", "1"); + TeleportEntity(entity, this.origin, NULL_VECTOR, NULL_VECTOR); + if(!DispatchSpawn(entity)) { + PrintToServer("Failed to spawn"); + return false; + } + this.entity = entity; + this.flags |= (Edit_Copy | Edit_Preview); + this.SetMode(MOVE_ORIGIN); + // Seems some entities fail here: + return IsValidEntity(entity); + } + + /** + * Adds an existing entity to the editor, to move it. + * asWallCopy: to instead copy the wall's size and position (walls only) + * @deprecated + */ + void Import(int entity, bool asWallCopy = false, editMode mode = SCALE) { + this.Reset(); + GetEntPropVector(entity, Prop_Send, "m_vecOrigin", this.origin); + GetEntPropVector(entity, Prop_Send, "m_angRotation", this.angles); + this.prevOrigin = this.origin; + this.prevAngles = this.angles; + GetEntPropVector(entity, Prop_Send, "m_vecMins", this.mins); + GetEntPropVector(entity, Prop_Send, "m_vecMaxs", this.size); + if(!asWallCopy) { + this.entity = entity; + } + this.SetMode(mode); + } + + /** + * Imports an entity + */ + void ImportEntity(int entity, int flags = 0, editMode mode = SCALE) { + this.Reset(); + this.flags = flags; + GetEntPropVector(entity, Prop_Send, "m_vecOrigin", this.origin); + GetEntPropVector(entity, Prop_Send, "m_angRotation", this.angles); + this.prevOrigin = this.origin; + this.prevAngles = this.angles; + GetEntPropVector(entity, Prop_Send, "m_vecMins", this.mins); + GetEntPropVector(entity, Prop_Send, "m_vecMaxs", this.size); + this.entity = entity; + this.SetMode(mode); + } + + // Cancels the current placement. If the edit is a copy/preview, the entity is also deleted + // If entity is not a wall, it will be returned + void Cancel() { + // Delete any copies: + if(this.flags & Edit_Copy || this.flags & Edit_Preview) { + RemoveEntity(this.entity); + } else if(~this.flags & Edit_WallCreator) { + // Is an edit of a prop + TeleportEntity(this.entity, this.prevOrigin, this.prevAngles, NULL_VECTOR); + } + this.SetMode(INACTIVE); + PrintHintText(this.client, "Cancelled"); + if(this.callback) { + delete this.callback; + } + // CPrintToChat(this.client, "\x04[Editor]\x01 Cancelled."); + } +} + +void SendEditorMessage(int client, const char[] format, any ...) { + char message[256]; + VFormat(message, sizeof(message), format, 3); + CPrintToChat(client, "\x04[Editor]\x01 %s", message); +} + +stock float RoundToNearestInterval(float value, int interval) { + return float(RoundFloat(value / float(interval)) * interval); +} +EditorData Editor[MAXPLAYERS+1]; + +Action OnWallClicked(int entity, int activator, int caller, UseType type, float value) { + int wallId = FindWallId(entity); + if(wallId > 0) { + GlowWall(wallId, GLOW_BLUE); + AcceptEntityInput(entity, "Toggle"); + } else { + PrintHintText(activator, "Invalid wall entity (%d)", entity); + } + return Plugin_Continue; +} + + + +// TODO: Stacker, copy tool, new command? +public Action Command_MakeWall(int client, int args) { + if(Editor[client].IsActive()) { + ReplyToCommand(client, "\x04[Editor]\x01 You are currently editing an entity. Finish editing your current entity with with \x05/edit done\x01 or cancel with \x04/edit cancel\x01"); + } else { + Editor[client].StartWall(); + if(args > 0) { + // Get values for X, Y and Z axis (defaulting to 1.0): + char arg2[8]; + for(int i = 0; i < 3; i++) { + GetCmdArg(i + 1, arg2, sizeof(arg2)); + float value; + if(StringToFloatEx(arg2, value) == 0) { + value = 1.0; + } + Editor[client].size[i] = value; + } + + float rot[3]; + GetClientEyeAngles(client, rot); + // Flip X and Y depending on rotation + // TODO: Validate + if(rot[2] > 45 && rot[2] < 135 || rot[2] > -135 && rot[2] < -45) { + float temp = Editor[client].size[0]; + Editor[client].size[0] = Editor[client].size[1]; + Editor[client].size[1] = temp; + } + + Editor[client].CalculateMins(); + } + + Editor[client].SetMode(SCALE); + GetCursorLimited(client, 100.0, Editor[client].origin, Filter_IgnorePlayer); + PrintToChat(client, "\x04[Editor]\x01 New Wall Started. End with \x05/wall build\x01 or \x04/wall cancel\x01"); + PrintToChat(client, "\x04[Editor]\x01 Mode: \x05Scale\x01"); + } + return Plugin_Handled; +} + +// TODO: move wall ids to own subcommand +Action Command_Editor(int client, int args) { + if(args == 0) { + PrintToChat(client, "\x04[Editor]\x01 Created Walls: \x05%d\x01", createdWalls.Length); + for(int i = 1; i <= createdWalls.Length; i++) { + GlowWall(i, GLOW_WHITE, 20.0); + } + return Plugin_Handled; + } + char arg1[16], arg2[16]; + GetCmdArg(1, arg1, sizeof(arg1)); + GetCmdArg(2, arg2, sizeof(arg2)); + if(StrEqual(arg1, "build") || StrEqual(arg1, "done")) { + // Remove frozen flag from user, as some modes use this + int flags = GetEntityFlags(client) & ~FL_FROZEN; + SetEntityFlags(client, flags); + + int entity; + CompleteType result = Editor[client].Done(entity); + switch(result) { + case Complete_WallSuccess: { + if(entity > 0) + PrintToChat(client, "\x04[Editor]\x01 Wall Creation: \x05Wall #%d Created\x01", entity + 1); + else + PrintToChat(client, "\x04[Editor]\x01 Wall Edit: \x04Complete\x01"); + } + case Complete_PropSpawned: + PrintToChat(client, "\x04[Editor]\x01 Prop Spawned: \x04%d\x01", entity); + + case Complete_EditSuccess: + PrintToChat(client, "\x04[Editor]\x01 Entity Edited: \x04%d\x01", entity); + + default: + PrintToChat(client, "\x04[Editor]\x01 Unknown result"); + } + } else if(StrEqual(arg1, "cancel")) { + int flags = GetEntityFlags(client) & ~FL_FROZEN; + SetEntityFlags(client, flags); + Editor[client].Cancel(); + if(Editor[client].flags & Edit_Preview) + PrintToChat(client, "\x04[Editor]\x01 Prop Spawer: \x04Cancelled\x01"); + else if(Editor[client].flags & Edit_WallCreator) { + PrintToChat(client, "\x04[Editor]\x01 Wall Creation: \x04Cancelled\x01"); + } else { + PrintToChat(client, "\x04[Editor]\x01 Entity Edit: \x04Cancelled\x01"); + } + } else if(StrEqual(arg1, "export")) { + // TODO: support exp #id + float origin[3], angles[3], size[3]; + if(Editor[client].IsActive()) { + origin = Editor[client].origin; + angles = Editor[client].angles; + size = Editor[client].size; + Export(client, arg2, Editor[client].entity, origin, angles, size); + } else { + int id = GetWallId(client, arg2); + if(id == -1) return Plugin_Handled; + int entity = GetWallEntity(id); + GetEntPropVector(entity, Prop_Send, "m_vecOrigin", origin); + if(HasEntProp(entity, Prop_Send, "m_vecAngles")) + GetEntPropVector(entity, Prop_Send, "m_vecAngles", angles); + GetEntPropVector(entity, Prop_Send, "m_vecMaxs", size); + Export(client, arg2, entity, origin, angles, size); + } + } else if(StrEqual(arg1, "delete")) { + if(Editor[client].IsActive() && args == 1) { + int entity = Editor[client].entity; + if(IsValidEntity(entity)) { + PrintToChat(client, "\x04[Editor]\x01 You are not editing any existing entity, use \x05/wall cancel\x01 to stop or \x05/wall delete "); + } else if(entity > MaxClients) { + RemoveEntity(entity); + Editor[client].Reset(); + PrintToChat(client, "\x04[Editor]\x01 Deleted current entity"); + } else { + PrintToChat(client, "\x04[Editor]\x01 Cannot delete player entities."); + } + } else if(StrEqual(arg2, "all")) { + int walls = createdWalls.Length; + for(int i = 1; i <= createdWalls.Length; i++) { + DeleteWall(i); + } + PrintToChat(client, "\x04[Editor]\x01 Deleted \x05%d\x01 Walls", walls); + } else { + int id = GetWallId(client, arg2); + if(id > -1) { + DeleteWall(id); + PrintToChat(client, "\x04[Editor]\x01 Deleted Wall: \x05#%d\x01", id); + } + } + } else if(StrEqual(arg1, "create")) { + ReplyToCommand(client, "\x04[Editor]\x01 Syntax: /mkwall [size x] [size y] [size z]"); + } else if(StrEqual(arg1, "toggle")) { + if(StrEqual(arg2, "all")) { + int walls = createdWalls.Length; + for(int i = 1; i <= createdWalls.Length; i++) { + int entity = GetWallEntity(i); + AcceptEntityInput(entity, "Toggle"); + GlowWall(i, GLOW_BLUE); + } + PrintToChat(client, "\x04[Editor]\x01 Toggled \x05%d\x01 walls", walls); + } else { + int id = GetWallId(client, arg2); + if(id > -1) { + int entity = GetWallEntity(id); + AcceptEntityInput(entity, "Toggle"); + GlowWall(id, GLOW_BLUE); + PrintToChat(client, "\x04[Editor]\x01 Toggled Wall: \x05#%d\x01", id); + } + } + } else if(StrEqual(arg1, "filter")) { + if(args < 3) { + ReplyToCommand(client, "\x04[Editor]\x01 Syntax: \x05/walls filter \x04"); + ReplyToCommand(client, "\x04[Editor]\x01 Valid filters: \x05player"); + return Plugin_Handled; + } + + char arg3[32]; + GetCmdArg(3, arg3, sizeof(arg3)); + + SetVariantString(arg3); + if(StrEqual(arg2, "all")) { + int walls = createdWalls.Length; + for(int i = 1; i <= createdWalls.Length; i++) { + int entity = GetWallEntity(i); + AcceptEntityInput(entity, "SetExcluded"); + } + PrintToChat(client, "\x04[Editor]\x01 Set %d walls' filter to \x05%s\x01", walls, arg3); + } else { + int id = GetWallId(client, arg2); + if(id > -1) { + int entity = GetWallEntity(id); + AcceptEntityInput(entity, "SetExcluded"); + PrintToChat(client, "\x04[Editor]\x01 Set wall #%d filter to \x05%s\x01", id, arg3); + } + } + } else if(StrEqual(arg1, "edit")) { + int id = GetWallId(client, arg2); + if(id > -1) { + int entity = GetWallEntity(id); + Editor[client].Import(entity); + PrintToChat(client, "\x04[Editor]\x01 Editing wall \x05%d\x01. End with \x05/wall done\x01 or \x04/wall cancel\x01", id); + PrintToChat(client, "\x04[Editor]\x01 Mode: \x05Scale\x01"); + } + } else if(StrEqual(arg1, "edite") || (arg1[0] == 'c' && arg1[1] == 'u')) { + int index = GetLookingEntity(client, Filter_ValidHats); //GetClientAimTarget(client, false); + if(index > 0) { + Editor[client].Import(index, false, MOVE_ORIGIN); + char classname[64]; + char targetname[32]; + GetEntityClassname(index, classname, sizeof(classname)); + GetEntPropString(index, Prop_Data, "m_target", targetname, sizeof(targetname)); + PrintToChat(client, "\x04[Editor]\x01 Editing entity \x05%d (%s) [%s]\x01. End with \x05/wall done\x01", index, classname, targetname); + PrintToChat(client, "\x04[Editor]\x01 Mode: \x05Move & Rotate\x01"); + } else { + ReplyToCommand(client, "\x04[Editor]\x01 Invalid or non existent entity"); + } + } else if(StrEqual(arg1, "copy")) { + if(Editor[client].IsActive()) { + int oldEntity = Editor[client].entity; + if(oldEntity == INVALID_ENT_REFERENCE) { + PrintToChat(client, "\x04[Editor]\x01 Finish editing your wall first: \x05/wall done\x01 or \x04/wall cancel\x01"); + } else { + int entity = Editor[client].Copy(); + PrintToChat(client, "\x04[Editor]\x01 Editing copy \x05%d\x01 of entity \x05%d\x01. End with \x05/edit done\x01 or \x04/edit cancel\x01", entity, oldEntity); + } + } else { + int id = GetWallId(client, arg2); + if(id > -1) { + int entity = GetWallEntity(id); + Editor[client].Import(entity, true); + GetCursorLimited(client, 100.0, Editor[client].origin, Filter_IgnorePlayer); + PrintToChat(client, "\x04[Editor]\x01 Editing copy of wall \x05%d\x01. End with \x05/wall build\x01 or \x04/wall cancel\x01", id); + PrintToChat(client, "\x04[Editor]\x01 Mode: \x05Scale\x01"); + } + } + } else if(StrEqual(arg1, "list")) { + for(int i = 1; i <= createdWalls.Length; i++) { + int entity = GetWallEntity(i); + ReplyToCommand(client, "Wall #%d - EntIndex: %d", i, EntRefToEntIndex(entity)); + } + } else { + ReplyToCommand(client, "\x04[Editor]\x01 See console for list of commands"); + GetCmdArg(0, arg1, sizeof(arg1)); + PrintToConsole(client, "%s done / build - Finishes editing, creates wall if making wall", arg1); + PrintToConsole(client, "%s cancel - Cancels editing (for entity edits is same as done)", arg1); + PrintToConsole(client, "%s list - Lists all walls", arg1); + PrintToConsole(client, "%s filter - Sets classname filter for walls, doesnt really work", arg1); + PrintToConsole(client, "%s toggle - Toggles if wall is active (collides)", arg1); + PrintToConsole(client, "%s delete - Deletes the wall(s)", arg1); + PrintToConsole(client, "%s edit - Edits wall id", arg1); + PrintToConsole(client, "%s copy [id] - If editing creates a new copy of wall/entity, else copies wall id", arg1); + PrintToConsole(client, "%s cursor - Starts editing the entity you looking at", arg1); + } + return Plugin_Handled; +} + +int GetWallId(int client, const char[] arg) { + int id; + if(StringToIntEx(arg, id) > 0 && id > 0 && id <= createdWalls.Length) { + int entity = GetWallEntity(id); + if(!IsValidEntity(entity)) { + ReplyToCommand(client, "\x04[Editor]\x01 The wall with specified id no longer exists."); + createdWalls.Erase(id - 1); + return -2; + } + return id; + } else { + ReplyToCommand(client, "\x04[Editor]\x01 Invalid wall id, must be between 0 - %d", createdWalls.Length - 1 ); + return -1; + } +} + +int GetWallEntity(int id) { + if(id <= 0 || id > createdWalls.Length) { + ThrowError("Invalid wall id (%d)", id); + } + return createdWalls.Get(id - 1); +} + +/// Tries to find the id of the wall based off entity +int FindWallId(int entity) { + for(int i = 1; i <= createdWalls.Length; i++) { + int entRef = createdWalls.Get(i - 1); + int ent = EntRefToEntIndex(entRef); + if(ent == entity) { + return i; + } + } + return -1; +} + +void GlowWall(int id, int glowColor[4], float lifetime = 5.0) { + int ref = GetWallEntity(id); + if(IsValidEntity(ref)) { + float pos[3], mins[3], maxs[3], angles[3]; + GetEntPropVector(ref, Prop_Send, "m_angRotation", angles); + GetEntPropVector(ref, Prop_Send, "m_vecOrigin", pos); + GetEntPropVector(ref, Prop_Send, "m_vecMins", mins); + GetEntPropVector(ref, Prop_Send, "m_vecMaxs", maxs); + Effect_DrawBeamBoxRotatableToAll(pos, mins, maxs, angles, g_iLaserIndex, 0, 0, 30, lifetime, 0.4, 0.4, 0, 1.0, glowColor, 0); + } +} + +void DeleteWall(int id) { + GlowWall(id, GLOW_RED_ALPHA); + int ref = GetWallEntity(id); + if(IsValidEntity(ref)) { + RemoveEntity(ref); + } + createdWalls.Erase(id - 1); +} + + void Export(int client, const char[] expType, int entity, const float origin[3], const float angles[3], const float size[3]) { + char sPath[PLATFORM_MAX_PATH]; + char currentMap[64]; + GetCurrentMap(currentMap, sizeof(currentMap)); + + BuildPath(Path_SM, sPath, sizeof(sPath), "data/exports"); + CreateDirectory(sPath, 1406); + BuildPath(Path_SM, sPath, sizeof(sPath), "data/exports/%s.cfg", currentMap); + File file = OpenFile(sPath, "w"); + if(file == null) { + PrintToServer("[Editor] Export: Cannot open \"%s\", cant write", sPath); + } + + PrintWriteLine(client, file, "{"); + if(entity != INVALID_ENT_REFERENCE) { + char model[64]; + GetEntPropString(entity, Prop_Data, "m_ModelName", model, sizeof(model)); + if(StrEqual(expType, "json")) { + PrintWriteLine(client, file, "\t\"model\": \"%s\",", model); + } else{ + PrintWriteLine(client, file, "\t\"model\" \"%s\"", model); + } + } + + if(StrEqual(expType, "json")) { + PrintWriteLine(client, file, "\t\"origin\": [%.2f, %.2f, %.2f],", origin[0], origin[1], origin[2]); + PrintWriteLine(client, file, "\t\"angles\": [%.2f, %.2f, %.2f],", angles[0], angles[1], angles[2]); + PrintWriteLine(client, file, "\t\"size\": [%.2f, %.2f, %.2f]", size[0], size[1], size[2]); + } else { + PrintWriteLine(client, file, "\t\"origin\" \"%.2f %.2f %.2f\"", origin[0], origin[1], origin[2]); + PrintWriteLine(client, file, "\t\"angles\" \"%.2f %.2f %.2f\"", angles[0], angles[1], angles[2]); + PrintWriteLine(client, file, "\t\"size\" \"%.2f %.2f %.2f\"", size[0], size[1], size[2]); + } + PrintWriteLine(client, file, "}"); + delete file; +} + +void PrintWriteLine(int client, File file, const char[] format, any ...) { + char line[100]; + VFormat(line, sizeof(line), format, 4); + if(file != null) + file.WriteLine(line); + PrintToChat(client, line); +} \ No newline at end of file diff --git a/scripting/include/editor/natives.sp b/scripting/include/editor/natives.sp new file mode 100644 index 0000000..f2911ad --- /dev/null +++ b/scripting/include/editor/natives.sp @@ -0,0 +1,122 @@ + +int Native_StartEdit(Handle plugin, int numParams) { + int client = GetNativeCell(1); + int entity = GetNativeCell(2); + Editor[client].Import(entity, false); + PrivateForward fwd = new PrivateForward(ET_Ignore, Param_Cell, Param_Cell, Param_Cell); + fwd.AddFunction(INVALID_HANDLE, GetNativeFunction(3)); + Editor[client].SetCallback(fwd, true); + return 0; +} +int Native_StartSpawner(Handle plugin, int numParams) { + int client = GetNativeCell(1); + g_PropData[client].Selector.Cancel(); + PrivateForward fwd = new PrivateForward(ET_Ignore, Param_Cell, Param_Cell, Param_Cell); + fwd.AddFunction(INVALID_HANDLE, GetNativeFunction(2)); + Editor[client].SetCallback(fwd, false); + ShowCategoryList(client, ROOT_CATEGORY); + return 0; +} +int Native_CancelEdit(Handle plugin, int numParams) { + int client = GetNativeCell(1); + Editor[client].Cancel(); + return 0; +} +int Native_IsEditorActive(Handle plugin, int numParams) { + int client = GetNativeCell(1); + Editor[client].IsActive(); + return 0; +} + +int Native_StartSelector(Handle plugin, int numParams) { + int client = GetNativeCell(1); + int color[3] = { 0, 255, 0 }; + PrivateForward fwd = new PrivateForward(ET_Single, Param_Cell, Param_Cell); + fwd.AddFunction(plugin, GetNativeFunction(2)); + GetNativeArray(3, color, 3); + int limit = GetNativeCell(4); + g_PropData[client].Selector.Start(color, 0, limit); + g_PropData[client].Selector.SetOnEnd(fwd); + return 0; +} +int Native_CancelSelector(Handle plugin, int numParams) { + int client = GetNativeCell(1); + g_PropData[client].Selector.Cancel(); + return 0; +} +int Native_IsSelectorActive(Handle plugin, int numParams) { + int client = GetNativeCell(1); + g_PropData[client].Selector.IsActive(); + return 0; +} +int Native_Selector_Start(Handle plugin, int numParams) { + int client = GetNativeCell(1); + int color[3] = { 0, 255, 0 }; + GetNativeArray(2, color, 3); + int flags = GetNativeCell(3); + int limit = GetNativeCell(4); + g_PropData[client].Selector.Start(color, flags, limit); + return 0; +} +int Native_Selector_GetCount(Handle plugin, int numParams) { + int client = GetNativeCell(1); + if(!g_PropData[client].Selector.IsActive()) { + return -1; + } else { + return g_PropData[client].Selector.list.Length; + } +} +int Native_Selector_GetActive(Handle plugin, int numParams) { + int client = GetNativeCell(1); + return g_PropData[client].Selector.IsActive(); +} +int Native_Selector_SetOnEnd(Handle plugin, int numParams) { + int client = GetNativeCell(1); + PrivateForward fwd = new PrivateForward(ET_Ignore, Param_Cell, Param_Cell); + fwd.AddFunction(plugin, GetNativeFunction(2)); + g_PropData[client].Selector.SetOnEnd(fwd); + return 0; +} +int Native_Selector_SetOnPreSelect(Handle plugin, int numParams) { + int client = GetNativeCell(1); + PrivateForward fwd = new PrivateForward(ET_Single, Param_Cell, Param_Cell); + if(!fwd.AddFunction(plugin, GetNativeFunction(2))) return 0; + g_PropData[client].Selector.SetOnPreSelect(fwd); + return 1; +} +int Native_Selector_SetOnPostSelect(Handle plugin, int numParams) { + int client = GetNativeCell(1); + PrivateForward fwd = new PrivateForward(ET_Ignore, Param_Cell, Param_Cell); + if(!fwd.AddFunction(plugin, GetNativeFunction(2))) return 0; + g_PropData[client].Selector.SetOnPostSelect(fwd); + return 1; +} +int Native_Selector_SetOnUnselect(Handle plugin, int numParams) { + int client = GetNativeCell(1); + PrivateForward fwd = new PrivateForward(ET_Ignore, Param_Cell, Param_Cell); + if(!fwd.AddFunction(plugin, GetNativeFunction(2))) return 0; + g_PropData[client].Selector.SetOnUnselect(fwd); + return 1; +} +int Native_Selector_AddEntity(Handle plugin, int numParams) { + int client = GetNativeCell(1); + int entity = GetNativeCell(2); + g_PropData[client].Selector.AddEntity(entity, false); + return 0; +} +int Native_Selector_RemoveEntity(Handle plugin, int numParams) { + int client = GetNativeCell(1); + int entity = GetNativeCell(2); + g_PropData[client].Selector.RemoveEntity(entity); + return 0; +} +int Native_Selector_Cancel(Handle plugin, int numParams) { + int client = GetNativeCell(1); + g_PropData[client].Selector.Cancel(); + return 0; +} +int Native_Selector_End(Handle plugin, int numParams) { + int client = GetNativeCell(1); + g_PropData[client].Selector.End(); + return 0; +} \ No newline at end of file diff --git a/scripting/include/editor/props/base.sp b/scripting/include/editor/props/base.sp new file mode 100644 index 0000000..d45f337 --- /dev/null +++ b/scripting/include/editor/props/base.sp @@ -0,0 +1,708 @@ +int g_pendingSaveClient; +ArrayList g_previewItems; +CategoryData ROOT_CATEGORY; +ArrayList g_spawnedItems; // ArrayList(block=2) +ArrayList g_savedItems; // ArrayList +StringMap g_recentItems; // Key: model[128], value: RecentEntry + +/* Wish to preface this file: +* It's kinda messy. The main structs are: +* - ItemData +* - CategoryData + +The rest are kinda necessary, for sorting reasons (SearchData, RecentEntry). + +*/ +enum ChatPrompt { + Prompt_None, + Prompt_Search, + Prompt_SaveScene, + Prompt_SaveSchematic, + Prompt_SaveCollection +} +enum SaveType { + Save_None, + Save_Scene, + Save_Schematic +} + +int GLOW_MANAGER[3] = { 52, 174, 235 }; + +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 PropSelectorIterator { + ArrayList _list; + int _index; + int Entity; + + void _Init(ArrayList list) { + this._list = list; + this._index = -1; + } + + bool Next() { + this._index++; + return this._index + 1 < this._list.Length; + } + +} + + +enum struct PropSelector { + int selectColor[3]; + int limit; + ArrayList list; + PrivateForward endCallback; + PrivateForward selectPreCallback; + PrivateForward selectPostCallback; + PrivateForward unSelectCallback; + int _client; + + PropSelectorIterator Iter() { + PropSelectorIterator iter; + iter._Init(this.list); + return iter; + } + + void Reset() { + if(this.endCallback) delete this.endCallback; + if(this.selectPreCallback) delete this.selectPreCallback; + if(this.selectPostCallback) delete this.selectPostCallback; + if(this.unSelectCallback) delete this.unSelectCallback; + if(this.list) delete this.list; + } + + void Start(int color[3], int flags = 0, int limit = 0) { + this.selectColor = color; + this.limit = 0; + this.list = new ArrayList(); + SendEditorMessage(this._client, "\x05Left click\x01 to select, \x05right click\x01 to unselect"); + SendEditorMessage(this._client, "Press \x05WALK+USE\x01 to confirm, \x05DUCK+USE\x01 to cancel"); + if(Editor[this._client].IsActive()) { + Editor[this._client].Cancel(); + } + } + + void SetOnEnd(PrivateForward callback) { + this.endCallback = callback; + } + void SetOnPreSelect(PrivateForward callback) { + this.selectPreCallback = callback; + } + void SetOnPostSelect(PrivateForward callback) { + this.selectPostCallback = callback; + } + void SetOnUnselect(PrivateForward callback) { + this.unSelectCallback = callback; + } + + void StartDirect(int color[3], SelectDoneCallback callback, int limit = 0) { + PrivateForward fwd = new PrivateForward(ET_Ignore, Param_Cell, Param_Cell); + fwd.AddFunction(INVALID_HANDLE, callback); + this.Start(color, 0, limit); + this.SetOnEnd(fwd); + } + + bool IsActive() { + return this.list != null; + } + + ArrayList End() { + if(this.list == null) return null; + SendEditorMessage(this._client, "Selection completed"); + // Reset glows, remove selection from our spawned props + for(int i = 0; i < this.list.Length; i++) { + int ref = this.list.Get(i); + if(IsValidEntity(ref)) { + L4D2_RemoveEntityGlow(ref); + RemoveSpawnedProp(ref); + } + } + if(this.endCallback) { + if(GetForwardFunctionCount(this.endCallback) == 0) { + PrintToServer("[Editor] Warn: Selector.End(): callback has no functions assigned to it."); + } + Call_StartForward(this.endCallback); + Call_PushCell(this._client); + Call_PushCell(this.list.Clone()); + int result = Call_Finish(); + if(result != SP_ERROR_NONE) { + PrintToServer("[Editor] Warn: Selector.End() forward error: %d", result); + } + } + ArrayList copy = this.list; + this.list = null; + this.Reset(); + return copy; + } + + void Cancel() { + if(this.endCallback) { + Call_StartForward(this.endCallback); + Call_PushCell(this._client); + Call_PushCell(INVALID_HANDLE); + Call_Finish(); + } + if(this.list) { + for(int i = 0; i < this.list.Length; i++) { + int ref = this.list.Get(i); + L4D2_RemoveEntityGlow(ref); + } + } + PrintToChat(this._client, "\x04[Editor]\x01 Selection cancelled."); + this.Reset(); + } + + int GetEntityRefIndex(int ref) { + int index = this.list.FindValue(ref); + if(index > -1) { + return index; + } + return -1; + } + + void Clear() { + if(this.list) { + this.list.Clear(); + } + } + + /** Removes entity from list + * @return returns entity ref of entity removed + */ + int RemoveEntity(int entity) { + if(this.list == null) return -2; + + L4D2_RemoveEntityGlow(entity); + int ref = EntIndexToEntRef(entity); + int index = this.GetEntityRefIndex(ref); + if(index > -1) { + this.list.Erase(index); + if(this.unSelectCallback != null) { + Call_StartForward(this.unSelectCallback) + Call_PushCell(this._client); + Call_PushCell(EntRefToEntIndex(ref)); + Call_Finish(); + } + return ref; + } + return INVALID_ENT_REFERENCE; + } + + /** + * Adds entity to list + * @return index into list of entity + * @return -1 if already added + * @return -2 if callback rejected + */ + int AddEntity(int entity, bool useCallback = true) { + if(this.list == null) return -2; + + int ref = EntIndexToEntRef(entity); + if(this.GetEntityRefIndex(ref) == -1) { + if(this.selectPreCallback != null && useCallback) { + Call_StartForward(this.selectPreCallback) + Call_PushCell(this._client); + Call_PushCell(entity); + bool allowed = true; + PrintToServer("Selector.AddEntity: PRE CALLBACK pre finish"); + Call_Finish(allowed); + PrintToServer("Selector.AddEntity: PRE CALLBACK pre result %b", allowed); + if(!allowed) return -2; + } + + L4D2_SetEntityGlow(entity, L4D2Glow_Constant, 10000, 0, this.selectColor, false); + int index = this.list.Push(ref); + PrintToServer("Selector.AddEntity: post CALLBACK pre"); + if(this.selectPostCallback != null && useCallback) { + Call_StartForward(this.selectPostCallback) + Call_PushCell(this._client); + Call_PushCell(entity); + //Call_PushCell(index); + Call_Finish(); + } + PrintToServer("Selector.AddEntity: post CALLBACK post"); + return index; + } + return -1; + } +} +enum struct PlayerPropData { + ArrayList categoryStack; + ArrayList itemBuffer; + bool clearListBuffer; + int lastCategoryIndex; + int lastItemIndex; + // When did the user last interact with prop spawner? (Shows hints after long inactivity) + int lastActiveTime; + char classnameOverride[64]; + ChatPrompt chatPrompt; + PropSelector Selector; + SaveType pendingSaveType; + + Schematic schematic; + int highlightedEntityRef; + int managerEntityRef; + + void Init(int client) { + this.Selector._client = client; + } + // Called on PlayerDisconnect + void Reset() { + if(this.Selector.IsActive()) this.Selector.Cancel(); + this.chatPrompt = Prompt_None; + this.clearListBuffer = false; + this.lastCategoryIndex = 0; + this.lastItemIndex = 0; + this.lastActiveTime = 0; + this.classnameOverride[0] = '\0'; + this.CleanupBuffers(); + this.pendingSaveType = Save_None; + this.schematic.Reset(); + this.managerEntityRef = INVALID_ENT_REFERENCE; + this.StopHighlight(); + } + + void StartHighlight(int entity) { + this.highlightedEntityRef = EntIndexToEntRef(entity); + L4D2_SetEntityGlow(entity, L4D2Glow_Constant, 10000, 0, GLOW_MANAGER, false); + } + void StopHighlight() { + if(IsValidEntity(this.highlightedEntityRef)) { + L4D2_RemoveEntityGlow(this.highlightedEntityRef); + } + this.highlightedEntityRef = INVALID_ENT_REFERENCE; + } + + 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 + void SetItemBuffer(ArrayList list, bool cleanupAfterUse = false) { + // Cleanup previous buffer if exist + this.itemBuffer = list; + this.clearListBuffer = cleanupAfterUse; + } + void ClearItemBuffer() { + if(this.itemBuffer != null && this.clearListBuffer) { + PrintToServer("ClearItemBuffer(): arraylist deleted."); + delete this.itemBuffer; + } + this.clearListBuffer = false; + } + + void PushCategory(CategoryData category) { + if(this.categoryStack == null) this.categoryStack = new ArrayList(sizeof(CategoryData)); + this.categoryStack.PushArray(category); + } + + bool PopCategory(CategoryData data) { + if(this.categoryStack == null || this.categoryStack.Length == 0) return false; + int index = this.categoryStack.Length - 1; + this.categoryStack.GetArray(index, data); + this.categoryStack.Erase(index); + return true; + } + bool PeekCategory(CategoryData data) { + if(this.categoryStack == null || this.categoryStack.Length == 0) return false; + int index = this.categoryStack.Length - 1; + this.categoryStack.GetArray(index, data); + return true; + } + + void GetCategoryTitle(char[] title, int maxlen) { + CategoryData cat; + for(int i = 0; i < this.categoryStack.Length; i++) { + this.categoryStack.GetArray(i, cat); + if(i == 0) + Format(title, maxlen, "%s", cat.name); + else + Format(title, maxlen, "%s>[%s]", title, cat.name); + } + } + + bool HasCategories() { + return this.categoryStack != null && this.categoryStack.Length > 0; + } + + // Is currently only called on item/category handler cancel (to clear search/recents buffer) + void CleanupBuffers() { + this.ClearItemBuffer(); + if(this.categoryStack != null) { + delete this.categoryStack; + } + this.clearListBuffer = false; + } +} +PlayerPropData g_PropData[MAXPLAYERS+1]; + + +enum struct CategoryData { + // The display name of category + char name[64]; + // If set, overwrites the classname it is spawned as + char classnameOverride[64]; + bool hasItems; // true: items is ArrayList, false: items is ArrayList + ArrayList items; +} +enum struct ItemData { + char model[128]; + char name[64]; + + void FromSearchData(SearchData search) { + strcopy(this.model, sizeof(this.model), search.model); + strcopy(this.name, sizeof(this.name), search.name); + } +} +enum struct SearchData { + char model[128]; + char name[64]; + int index; + + void FromItemData(ItemData item) { + strcopy(this.model, sizeof(this.model), item.model); + strcopy(this.name, sizeof(this.name), item.name); + } +} + +methodmap ColorObject < JSONObject { + /// Creates a new Color with RGB between 0-255 + public ColorObject(int r = 255, int g = 255, int b = 255, int alpha = 255) { + JSONObject obj = new JSONObject(); + obj.SetInt("r", r); + obj.SetInt("g", g); + obj.SetInt("b", b); + obj.SetInt("alpha", alpha); + return view_as(obj); + } + + property int R { + public get() { return view_as(this).GetInt("r"); } + public set(int value) { view_as(this).SetInt("r", value); } + } + property int G { + public get() { return view_as(this).GetInt("g"); } + public set(int value) { view_as(this).SetInt("g", value); } + } + property int B { + public get() { return view_as(this).GetInt("b"); } + public set(int value) { view_as(this).SetInt("b", value); } + } + property int Alpha { + public get() { return view_as(this).GetInt("alpha"); } + public set(int value) { view_as(this).SetInt("alpha", value); } + } +} +methodmap Coordinates < JSONObject { + public Coordinates(float x = 0.0, float y = 0.0, float z = 0.0) { + JSONObject obj = new JSONObject(); + obj.SetFloat("x", x); + obj.SetFloat("y", y); + obj.SetFloat("z", z); + return view_as(obj); + } + + property float X { + public get() { return view_as(this).GetFloat("x"); } + public set(float value) { view_as(this).SetFloat("x", value); } + } + property float Y { + public get() { return view_as(this).GetFloat("y"); } + public set(float value) { view_as(this).SetFloat("y", value); } + } + property float Z { + public get() { return view_as(this).GetFloat("z"); } + public set(float value) { view_as(this).SetFloat("z", value); } + } + + public static Coordinates FromVec(const float vec[3]) { + return new Coordinates(vec[0], vec[1], vec[2]); + } + + public void ToVec(float vec[3]) { + vec[0] = this.X; + vec[1] = this.Y; + vec[2] = this.Z; + } +} + +methodmap SpawnerEntity < JSONObject { + property buildType BuildType { + public get() { + return view_as(view_as(this).GetInt("buildType")); + } + public set(buildType value) { + view_as(this).SetInt("buildType", value); + } + } + + property ColorObject Color { + public get() { return view_as(view_as(this).Get("color")); } + } + + property Coordinates Origin { + public get() { return view_as(view_as(this).Get("origin")); } + public set(Coordinates newVec) { + view_as(this).Remove("origin"); + view_as(this).Set("origin", newVec); + } + } + + property Coordinates Angles { + public get() { return view_as(view_as(this).Get("angles")); } + public set(Coordinates newVec) { + view_as(this).Remove("angles"); + view_as(this).Set("angles", newVec); + } + } + + public int GetModel(char[] output, int maxlen) { + return view_as(this).GetString("model", output, maxlen); + } + + public void SetModel(const char[] input) { + view_as(this).SetString("model", input); + } + + public static SpawnerEntity FromEntity(int entity) { + char buffer[128]; + GetEntityClassname(entity, buffer, sizeof(buffer)); + JSONObject obj = new JSONObject(); + obj.SetString("type", buffer); + GetEntPropString(entity, Prop_Data, "m_ModelName", buffer, sizeof(buffer)); + obj.SetString("model", buffer); + int color[4]; + GetEntityRenderColor(entity, color[0], color[1], color[2], color[3]); + obj.Set("color", view_as(new ColorObject(color[0], color[1], color[2], color[3]))); + // this.type = Build_Solid; + // if(StrEqual(this.model, "prop_physics")) this.type = Build_Physics; + // else if(StrEqual(this.model, "prop_dynamic")) { + // if(GetEntProp(entity, Prop_Send, "m_nSolidType") == 0) { + // this.type = Build_NonSolid; + // } + // } + SpawnerEntity se = view_as(obj); + float vec[3]; + GetEntPropVector(entity, Prop_Send, "m_vecOrigin", vec); + se.Origin = Coordinates.FromVec(vec); + GetEntPropVector(entity, Prop_Send, "m_angRotation", vec); + se.Angles = Coordinates.FromVec(vec); + return se; + } + + public int CreateEntity(const float offset[3], bool asPreview = true) { + + } +} + +enum struct SaveData { + char model[128]; + buildType type; + float origin[3]; + float angles[3]; + int color[4]; + + void FromEntity(int entity) { + // Use this.model as a buffer: + GetEntityClassname(entity, this.model, sizeof(this.model)); + this.type = Build_Solid; + if(StrEqual(this.model, "prop_physics")) this.type = Build_Physics; + else if(StrEqual(this.model, "prop_dynamic")) { + if(GetEntProp(entity, Prop_Send, "m_nSolidType") == 0) { + this.type = Build_NonSolid; + } + } + + GetEntPropString(entity, Prop_Data, "m_ModelName", this.model, sizeof(this.model)); + GetEntPropVector(entity, Prop_Send, "m_vecOrigin", this.origin); + GetEntPropVector(entity, Prop_Send, "m_angRotation", this.angles); + 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", + this.model, this.type, this.origin[0], this.origin[1], this.origin[2], + this.angles[0], this.angles[1], this.angles[2], + this.color[0], this.color[1], this.color[2], this.color[3] + ); + } + void Deserialize(const char[] input) { + char buffer[16]; + int index = SplitString(input, ",", this.model, sizeof(this.model)); + index += SplitString(input[index], ",", buffer, sizeof(buffer)); + this.type = view_as(StringToInt(buffer)); + for(int i = 0; i < 3; i++) { + index += SplitString(input[index], ",", buffer, sizeof(buffer)); + this.origin[i] = StringToFloat(buffer); + } + for(int i = 0; i < 3; i++) { + index += SplitString(input[index], ",", buffer, sizeof(buffer)); + this.angles[i] = StringToFloat(buffer); + } + for(int i = 0; i < 4; i++) { + index += SplitString(input[index], ",", buffer, sizeof(buffer)); + this.color[i] = StringToInt(buffer); + } + } +} + +enum struct RecentEntry { + char name[64]; + int count; +} + +#include +#include +#include +#include +#include \ No newline at end of file diff --git a/scripting/include/editor/props/cmd.sp b/scripting/include/editor/props/cmd.sp new file mode 100644 index 0000000..aa7d28c --- /dev/null +++ b/scripting/include/editor/props/cmd.sp @@ -0,0 +1,139 @@ +Action Command_Props(int client, int args) { + char arg[32]; + GetCmdArg(1, arg, sizeof(arg)); + if(args == 0 || StrEqual(arg, "help")) { + PrintToChat(client, "See console for available sub-commands"); + PrintToConsole(client, "help - this"); + PrintToConsole(client, "list - lists all props and their distances"); + PrintToConsole(client, "search "); + PrintToConsole(client, "edit "); + PrintToConsole(client, "del "); + PrintToConsole(client, "add "); + PrintToConsole(client, "favorite - favorites active editor entity"); + PrintToConsole(client, "controls - list all the controls"); + PrintToConsole(client, "reload - reload prop list"); + PrintToConsole(client, "schem[atic] "); + } 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)); + bool isClassname = StrEqual(arg2, "classname"); + bool isIndex = StrEqual(arg2, "index"); + bool isOwner = StrEqual(arg2, "owner"); + if(args == 1 || isClassname || isIndex || isOwner) { + PrintToChat(client, "\x04[Editor]\x01 Please specify: \x05classname, index, owner. "); + return Plugin_Handled; + } + float pos[3], propPos[3], dist; + GetAbsOrigin(client, pos); + for(int i = 0; i < g_spawnedItems.Length; i++) { + int ref = GetSpawnedItem(i); + if(ref > -1) { + GetEntPropVector(ref, Prop_Send, "m_vecOrigin", propPos); + dist = GetVectorDistance(pos, propPos, false); + if(isIndex) { + int entity = EntRefToEntIndex(ref); + PrintToConsole(client, "%d. ent #%d - %.0fu away", i, entity, dist); + } else if(isClassname) { + char classname[32]; + GetEntityClassname(ref, classname, sizeof(classname)); + PrintToConsole(client, "%d. %s - %.0fu away", i, classname, dist); + } else if(isOwner) { + int spawner = g_spawnedItems.Get(i, 1); + int player = GetClientOfUserId(spawner); + if(player > 0) { + PrintToConsole(client, "%d. %N - %.0fu away", i, player, dist); + } else { + PrintToConsole(client, "%d. (disconnected) - %.0fu away", i, dist); + } + } + } + } + PrintToChat(client, "\x04[Editor]\x01 Check console"); + } else if(StrEqual(arg, "search")) { + if(args == 1) { + PrintToChat(client, "\x04[Editor]\x01 Enter your search query:"); + g_PropData[client].chatPrompt = Prompt_Search; + } else { + char query[32]; + GetCmdArg(2, query, sizeof(query)); + DoSearch(client, query); + } + } else if(StrEqual(arg, "edit")) { + char arg2[32]; + GetCmdArg(2, arg2, sizeof(arg2)); + int index; + if(StrEqual(arg2, "last")) { + // Get last one + index = GetSpawnedIndex(client, -1); + } else { + index = StringToInt(arg2); + } + if(index >= 0 && index < g_spawnedItems.Length) { + int entity = EntRefToEntIndex(g_spawnedItems.Get(index)); + Editor[client].Import(entity); + PrintToChat(client, "\x04[Editor]\x01 Editing entity \x05%d", entity); + } else { + PrintToChat(client, "\x04[Editor]\x01 Invalid index, out of bounds. Enter a value between [0, %d]", g_spawnedItems.Length - 1); + } + } else if(StrEqual(arg, "del")) { + char arg2[32]; + GetCmdArg(2, arg2, sizeof(arg2)); + int index; + if(StrEqual(arg2, "last")) { + // Get last one + index = GetSpawnedIndex(client, -1); + } else { + index = StringToInt(arg2); + } + + if(index >= 0 && index < g_spawnedItems.Length) { + int entity = EntRefToEntIndex(g_spawnedItems.Get(index)); + if(entity > 0 && IsValidEntity(entity)) { + RemoveEntity(entity); + } + g_spawnedItems.Erase(index); + PrintToChat(client, "\x04[Editor]\x01 Deleted entity \x05%d", entity); + } else { + PrintToChat(client, "\x04[Editor]\x01 Invalid index, out of bounds. Enter a value between [0, %d]", g_spawnedItems.Length - 1); + } + } else if(StrEqual(arg, "controls")) { + PrintToChat(client, "View controls at https://admin.jackz.me/docs/props"); + } else if(StrEqual(arg, "favorite")) { + if(g_db == null) { + PrintToChat(client, "\x04[Editor]\x01 Cannot connect to database."); + } else if(Editor[client].IsActive()) { + char model[128]; + GetEntPropString(Editor[client].entity, Prop_Data, "m_ModelName", model, sizeof(model)); + ToggleFavorite(client, model, Editor[client].data); + } else { + PrintToChat(client, "\x04[Editor]\x01 Edit a prop to use this command."); + } + } else if(StrEqual(arg, "reload")) { + PrintHintText(client, "Reloading categories..."); + UnloadCategories(); + LoadCategories(); + } else { + PrintToChat(client, "\x05Not implemented"); + } + return Plugin_Handled; +} \ No newline at end of file diff --git a/scripting/include/editor/props/db.sp b/scripting/include/editor/props/db.sp new file mode 100644 index 0000000..87c3519 --- /dev/null +++ b/scripting/include/editor/props/db.sp @@ -0,0 +1,125 @@ +#define DATABASE_CONFIG_NAME "hats_editor" +Database g_db; + +bool ConnectDB() { + char error[255]; + Database db = SQL_Connect(DATABASE_CONFIG_NAME, true, error, sizeof(error)); + if (db == null) { + LogError("Database error %s", error); + return false; + } else { + PrintToServer("l4d2_hats: Connected to database %s", DATABASE_CONFIG_NAME); + db.SetCharset("utf8mb4"); + g_db = db; + return true; + } +} + +void DB_GetFavoritesCallback(Database db, DBResultSet results, const char[] error, int userid) { + if(results == null) { + PrintToServer("l4d2_hats: DB_GetFavoritesCallback returned error: \"%s\"", error); + } + int client = GetClientOfUserId(userid); + if(client > 0) { + if(results == null) { + PrintToChat(client, "\x04[Editor]\x01 Error occurred fetching favorites"); + return; + } + ArrayList list = new ArrayList(sizeof(ItemData)); + ItemData item; + while(results.FetchRow()) { + results.FetchString(0, item.model, sizeof(item.model)); + DBResult result; + results.FetchString(1, item.name, sizeof(item.name), result); + if(result == DBVal_Null) { + // No name set - use the end part of the model + int index = FindCharInString(item.model, '/', true); + strcopy(item.name, sizeof(item.name), item.model[index + 1]); + } + } + ShowTempItemMenu(client, list, "Favorites"); + } +} + +void DB_ToggleFavoriteCallback(Database db, DBResultSet results, const char[] error, DataPack pack) { + if(results == null) { + PrintToServer("l4d2_hats: DB_GetFavoriteCallback returned error: \"%s\"", error); + } + pack.Reset(); + int userid = pack.ReadCell(); + int client = GetClientOfUserId(userid); + if(client > 0) { + if(results == null) { + PrintToChat(client, "\x04[Editor]\x01 Error occurred fetching favorite data"); + delete pack; + return; + } + char query[256]; + char model[128]; + char steamid[32]; + GetClientAuthId(client, AuthId_Steam2, steamid, sizeof(steamid)); + pack.ReadString(model, sizeof(model)); + if(results.FetchRow()) { + // Model was favorited, erase it + g_db.Format(query, sizeof(query), "DELETE FROM editor_favorites WHERE steamid = '%s' AND model = '%s'", steamid, model); + g_db.Query(DB_DeleteFavoriteCallback, query, userid); + } else { + // Model is not favorited, save it. + char name[64]; + pack.ReadString(name, sizeof(name)); + // TODO: calculate next position automatically + int position = 0; + g_db.Format(query, sizeof(query), + "INSERT INTO editor_favorites (steamid, model, name, position) VALUES ('%s', '%s', '%s', %d)", + steamid, model, name, position + ); + g_db.Query(DB_InsertFavoriteCallback, query, pack); + } + } else { + // Only delete if we lost client - otherwise we will reuse it + delete pack; + } +} + +void DB_DeleteFavoriteCallback(Database db, DBResultSet results, const char[] error, DataPack pack) { + if(results == null) { + PrintToServer("l4d2_hats: DB_DeleteFavoriteCallback returned error: \"%s\"", error); + } + pack.Reset(); + char model[128]; + char name[64]; + int client = GetClientOfUserId(pack.ReadCell()); + if(client > 0) { + if(results == null) { + PrintToChat(client, "\x04[Editor]\x01 Could not delete favorite"); + delete pack; + return; + } + pack.ReadString(model, sizeof(model)); + pack.ReadString(name, sizeof(name)); + int index = FindCharInString(model, '/', true); + PrintToChat(client, "\x04[Editor]\x01 Removed favorite: \"%s\" \x05(%s)", model[index], name); + } + delete pack; +} +void DB_InsertFavoriteCallback(Database db, DBResultSet results, const char[] error, DataPack pack) { + if(results == null) { + PrintToServer("l4d2_hats: DB_InsertFavoriteCallback returned error: \"%s\"", error); + } + pack.Reset(); + char model[128]; + char name[64]; + int client = GetClientOfUserId(pack.ReadCell()); + if(client > 0) { + if(results == null) { + PrintToChat(client, "\x04[Editor]\x01 Could not add favorite"); + delete pack; + return; + } + pack.ReadString(model, sizeof(model)); + pack.ReadString(name, sizeof(name)); + int index = FindCharInString(model, '/', true); + PrintToChat(client, "\x04[Editor]\x01 Added favorite: \"%s\" \x05(%s)", model[index], name); + } + delete pack; +} \ No newline at end of file diff --git a/scripting/include/editor/props/menu_handlers.sp b/scripting/include/editor/props/menu_handlers.sp new file mode 100644 index 0000000..b8cc691 --- /dev/null +++ b/scripting/include/editor/props/menu_handlers.sp @@ -0,0 +1,517 @@ +TopMenuObject g_propSpawnerCategory; +public void OnAdminMenuReady(Handle topMenuHandle) { + TopMenu topMenu = TopMenu.FromHandle(topMenuHandle); + if(g_topMenu != topMenuHandle) { + g_propSpawnerCategory = topMenu.AddCategory("hats_editor", Category_Handler, "sm_prop"); + if(g_propSpawnerCategory != INVALID_TOPMENUOBJECT) { + topMenu.AddItem("editor_spawn", AdminMenu_Spawn, g_propSpawnerCategory, "sm_prop"); + // topMenu.AddItem("editor_edit", AdminMenu_Edit, g_propSpawnerCategory, "sm_prop"); + topMenu.AddItem("editor_delete", AdminMenu_Delete, g_propSpawnerCategory, "sm_prop"); + topMenu.AddItem("editor_saveload", AdminMenu_SaveLoad, g_propSpawnerCategory, "sm_prop"); + topMenu.AddItem("editor_manager", AdminMenu_Manager, g_propSpawnerCategory, "sm_prop"); + topMenu.AddItem("editor_selector", AdminMenu_Selector, g_propSpawnerCategory, "sm_prop"); + } + g_topMenu = topMenu; + } +} + +///////////// +// HANDLERS +///////////// +void Category_Handler(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength) { + if(action == TopMenuAction_DisplayTitle) { + Format(buffer, maxlength, "Select a task:"); + } else if(action == TopMenuAction_DisplayOption) { + Format(buffer, maxlength, "Spawn Props"); + } +} + +void AdminMenu_Selector(TopMenu topmenu, TopMenuAction action, TopMenuObject object_id, int param, char[] buffer, int maxlength) { + if(action == TopMenuAction_DisplayOption) { + Format(buffer, maxlength, "Selector"); + } else if(action == TopMenuAction_SelectOption) { + ShowManagerSelectorMenu(param); + } +} + + +void AdminMenu_Spawn(TopMenu topmenu, TopMenuAction action, TopMenuObject object_id, int param, char[] buffer, int maxlength) { + if(action == TopMenuAction_DisplayOption) { + Format(buffer, maxlength, "Spawn Props"); + } else if(action == TopMenuAction_SelectOption) { + ConVar cheats = FindConVar("sm_cheats"); + if(cheats != null && !cheats.BoolValue) { + CReplyToCommand(param, "\x04[Editor] \x01Set \x05sm_cheats\x01 to \x051\x01 to use the prop spawner"); + return; + } + ShowSpawnRoot(param); + } +} + +int Spawn_RootHandler(Menu menu, MenuAction action, int client, int param2) { + if (action == MenuAction_Select) { + char info[2]; + menu.GetItem(param2, info, sizeof(info)); + switch(info[0]) { + case 'f': Spawn_ShowFavorites(client); + case 'r': Spawn_ShowRecents(client); + case 's': Spawn_ShowSearch(client); + case 'n': ShowCategoryList(client, ROOT_CATEGORY); + } + // TODO: handle back (to top menu) + } else if (action == MenuAction_Cancel) { + if(param2 == MenuCancel_ExitBack) { + DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, client); + } + } else if (action == MenuAction_End) + delete menu; + return 0; +} +// void AdminMenu_Edit(TopMenu topmenu, TopMenuAction action, TopMenuObject object_id, int param, char[] buffer, int maxlength) { +// if(action == TopMenuAction_DisplayOption) { +// Format(buffer, maxlength, "Edit Props"); +// } else if(action == TopMenuAction_SelectOption) { +// ShowEditList(param); +// } +// } +void AdminMenu_Delete(TopMenu topmenu, TopMenuAction action, TopMenuObject object_id, int param, char[] buffer, int maxlength) { + if(action == TopMenuAction_DisplayOption) { + Format(buffer, maxlength, "Delete Props"); + } else if(action == TopMenuAction_SelectOption) { + ShowDeleteList(param); + } +} + +void AdminMenu_SaveLoad(TopMenu topmenu, TopMenuAction action, TopMenuObject object_id, int param, char[] buffer, int maxlength) { + if(action == TopMenuAction_DisplayOption) { + Format(buffer, maxlength, "Save / Load"); + } else if(action == TopMenuAction_SelectOption) { + Spawn_ShowSaveLoadMainMenu(param); + } +} + +void AdminMenu_Manager(TopMenu topmenu, TopMenuAction action, TopMenuObject object_id, int param, char[] buffer, int maxlength) { + if(action == TopMenuAction_DisplayOption) { + Format(buffer, maxlength, "Manage Props"); + } else if(action == TopMenuAction_SelectOption) { + Spawn_ShowManagerMainMenu(param); + } +} + +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(StringToInt(info)); + ShowSaves(client, type); + } else if (action == MenuAction_Cancel) { + if(param2 == MenuCancel_ExitBack) { + DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, 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(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(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 scene."); + } else { + g_pendingSaveClient = client; + 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 { + 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 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 ManagerHandler(Menu menu, MenuAction action, int client, int param2) { + if (action == MenuAction_Select) { + char info[8]; + menu.GetItem(param2, info, sizeof(info)); + if(info[0] != '\0') { + int index = StringToInt(info); + int ref = g_spawnedItems.Get(index); + // TODO: add delete confirm + if(!IsValidEntity(ref)) { + SendEditorMessage(client, "Entity has disappeared"); + } else { + int entity = EntRefToEntIndex(ref); + g_PropData[client].managerEntityRef = ref; + g_PropData[client].StartHighlight(entity); + ShowManagerEntityMenu(client, entity); + } + } + } else if (action == MenuAction_Cancel) { + if(param2 == MenuCancel_ExitBack) { + DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, client); + } + } else if (action == MenuAction_End) + delete menu; + return 0; +} +int ManagerEntityHandler(Menu menu, MenuAction action, int client, int param2) { + if (action == MenuAction_Select) { + g_PropData[client].StopHighlight(); + char info[32]; + menu.GetItem(param2, info, sizeof(info)); + int ref = g_PropData[client].managerEntityRef; + if(!IsValidEntity(ref)) { + SendEditorMessage(client, "Entity disappeared"); + } else if(StrEqual(info, "edit")) { + Editor[client].ImportEntity(EntRefToEntIndex(ref), Edit_Manager); + return 0; + } else if(StrEqual(info, "delete")) { + for(int i = 0; i < g_spawnedItems.Length; i++) { + int spawnedRef = g_spawnedItems.Get(i); + if(spawnedRef == ref) { + g_spawnedItems.Erase(i); + break; + } + } + if(IsValidEntity(ref)) { + RemoveEntity(ref); + } + return 0; + } else if(StrEqual(info, "view")) { + ReplyToCommand(client, "Maybe soon."); + } else if(StrEqual(info, "select")) { + int entity = EntRefToEntIndex(ref); + g_PropData[client].Selector.AddEntity(entity); + } else { + SendEditorMessage(client, "Unknown option / not implemented"); + } + ShowManagerSelectorMenu(client); + } else if (action == MenuAction_Cancel) { + g_PropData[client].StopHighlight(); + if(param2 == MenuCancel_ExitBack) { + Spawn_ShowManagerMainMenu(client); + } + } else if (action == MenuAction_End) + delete menu; + return 0; +} +int ManagerSelectorMainMenuHandler(Menu menu, MenuAction action, int client, int param2) { + if (action == MenuAction_Select) { + EntitySelector sel = EntitySelector.FromClient(client); + if(!sel.Active) { + return 0; + } + char info[32]; + menu.GetItem(param2, info, sizeof(info)); + if(StrEqual(info, "list")) { + SendEditorMessage(client, "Not implemented"); + } else if(StrEqual(info, "actions")) { + ShowManagerSelectorActionsMenu(client); + } else if(StrEqual(info, "add-self")) { + int userid = GetClientUserId(client); + int count; + for(int i = 0; i < g_spawnedItems.Length; i++) { + int ref = g_spawnedItems.Get(i); + int spawnedBy = g_spawnedItems.Get(i, 1); + if(spawnedBy == userid) { + sel.AddEntity(EntRefToEntIndex(ref)); + count++; + } + } + ReplyToCommand(client, "Added %d entities", count); + ShowManagerSelectorMenu(client); + } else if(StrEqual(info, "add-all")) { + int count; + for(int i = 0; i < g_spawnedItems.Length; i++) { + int ref = g_spawnedItems.Get(i); + sel.AddEntity(EntRefToEntIndex(ref)); + count++; + } + ReplyToCommand(client, "Added %d entities", count); + ShowManagerSelectorMenu(client); + } else if(StrEqual(info, "cancel")) { + g_PropData[client].Selector.Cancel(); + } + } else if (action == MenuAction_Cancel) { + g_PropData[client].Selector.Cancel(); + } else if (action == MenuAction_End) + delete menu; + return 0; +} +int ManagerSelectorActionHandler(Menu menu, MenuAction action, int client, int param2) { + if (action == MenuAction_Select) { + if(!g_PropData[client].Selector.IsActive()) { + return 0; + } + char info[32]; + menu.GetItem(param2, info, sizeof(info)); + if(StrEqual(info, "delete")) { + int count; + for(int i = 0; i < g_PropData[client].Selector.list.Length; i++) { + int ref = g_PropData[client].Selector.list.Get(i); + if(IsValidEntity(ref)) { + RemoveEntity(ref); + count++; + } + } + ArrayList list = g_PropData[client].Selector.End(); + delete list; + SendEditorMessage(client, "Deleted %d entities", count); + Spawn_ShowManagerMainMenu(client); + } else if(StrEqual(info, "clear")) { + g_PropData[client].Selector.Clear(); + SendEditorMessage(client, "Cleared selection."); + Spawn_ShowManagerMainMenu(client); + } else if(StrEqual(info, "save_scene")) { + ArrayList items = g_PropData[client].Selector.End(); + g_PropData[client].SetItemBuffer(items, true); + g_PropData[client].chatPrompt = Prompt_SaveScene; + SendEditorMessage(client, "Enter name for scene:"); + } else if(StrEqual(info, "save_collection")) { + ArrayList items = g_PropData[client].Selector.End(); + g_PropData[client].SetItemBuffer(items, true); + g_PropData[client].chatPrompt = Prompt_SaveCollection; + SendEditorMessage(client, "Enter name for collection:"); + } else { + SendEditorMessage(client, "Unknown option / not implemented"); + } + } else if (action == MenuAction_Cancel) { + if(param2 == MenuCancel_ExitBack) { + ShowManagerSelectorMenu(client); + } + } else if (action == MenuAction_End) + delete menu; + return 0; +} +int COLOR_DELETE[3] = { 255, 0, 0 } + +int DeleteHandler(Menu menu, MenuAction action, int client, int param2) { + if (action == MenuAction_Select) { + char info[128]; + menu.GetItem(param2, info, sizeof(info)); + int ref = StringToInt(info[2]); + int option = StringToInt(info); + if(option == -1) { + // Delete all (everyone) + int count = DeleteAll(); + PrintToChat(client, "\x04[Editor]\x01 Deleted \x05%d\x01 items", count); + ShowDeleteList(client); + } else if(option == -2) { + // Delete all (mine only) + int count = DeleteAll(client); + PrintToChat(client, "\x04[Editor]\x01 Deleted \x05%d\x01 items", count); + ShowDeleteList(client); + } else if(option == -3) { + if(g_PropData[client].Selector.IsActive()) { + g_PropData[client].Selector.End(); + PrintToChat(client, "\x04[Editor]\x01 Delete tool cancelled"); + } else { + g_PropData[client].Selector.StartDirect(COLOR_DELETE, OnDeleteToolEnd); + PrintToChat(client, "\x04[Editor]\x01 Delete tool active. Press \x05Left Mouse\x01 to mark props, \x05Right Mouse\x01 to undo. SHIFT+USE to spawn, CTRL+USE to cancel"); + } + ShowDeleteList(client); + } else { + int index = g_spawnedItems.FindValue(ref); + if(IsValidEntity(ref)) { + RemoveEntity(ref); + } + if(index > -1) { + g_spawnedItems.Erase(index); + index--; + } else { index = 0; } + ShowDeleteList(client, index); + } + } else if (action == MenuAction_Cancel) { + if(param2 == MenuCancel_ExitBack) { + DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, client); + } + } else if (action == MenuAction_End) + delete menu; + return 0; +} + +int SpawnCategoryHandler(Menu menu, MenuAction action, int client, int param2) { + if (action == MenuAction_Select) { + char info[8]; + menu.GetItem(param2, info, sizeof(info)); + int index = StringToInt(info); + // Reset item index when selecting new category + if(g_PropData[client].lastCategoryIndex != index) { + g_PropData[client].lastCategoryIndex = index; + g_PropData[client].lastItemIndex = 0; + } + CategoryData category; + g_PropData[client].PeekCategory(category); // Just need to get the category.items[index], don't want to pop + category.items.GetArray(index, category); + if(category.items == null) { + LogError("Category %s has null items array (index=%d)", category.name, index); + } else if(category.hasItems) { + ShowCategoryItemMenu(client, category); + } else { + // Reset the category index for nested + g_PropData[client].lastCategoryIndex = 0; + // Make the list now be the selected category's list. + ShowCategoryList(client, category); + } + } else if (action == MenuAction_Cancel) { + if(param2 == MenuCancel_ExitBack) { + CategoryData category; + // Double pop + if(g_PropData[client].PopCategory(category) && g_PropData[client].PopCategory(category)) { + // Use the last category (go back one) + ShowCategoryList(client, category); + } else { + ShowSpawnRoot(client); + } + } else { + g_PropData[client].CleanupBuffers(); + } + } else if (action == MenuAction_End) + delete menu; + return 0; +} + +int SpawnItemHandler(Menu menu, MenuAction action, int client, int param2) { + if (action == MenuAction_Select) { + char info[132]; + menu.GetItem(param2, info, sizeof(info)); + char index[4]; + char model[128]; + int nameIndex = SplitString(info, "|", index, sizeof(index)); + nameIndex += SplitString(info[nameIndex], "|", model, sizeof(model)); + g_PropData[client].lastItemIndex = StringToInt(index); + if(Editor[client].PreviewModel(model, g_PropData[client].classnameOverride)) { + Editor[client].SetName(info[nameIndex]); + PrintHintText(client, "%s\n%s", info[nameIndex], model); + ShowHint(client); + } else { + PrintToChat(client, "\x04[Editor]\x01 Error spawning preview \x01(%s)", model); + } + // Use same item menu again: + ShowItemMenu(client); + } else if(action == MenuAction_Cancel) { + g_PropData[client].ClearItemBuffer(); + if(param2 == MenuCancel_ExitBack) { + CategoryData category; + if(g_PropData[client].PopCategory(category)) { + // Use the last category (go back one) + ShowCategoryList(client, category); + } else { + // If there is no categories, it means we are in a temp menu (search / recents / favorites) + ShowSpawnRoot(client); + } + } else { + g_PropData[client].CleanupBuffers(); + } + } else if (action == MenuAction_End) { + delete menu; + } + return 0; +} + +// int EditHandler(Menu menu, MenuAction action, int client, int param2) { +// if (action == MenuAction_Select) { +// char info[8]; +// menu.GetItem(param2, info, sizeof(info)); +// int ref = StringToInt(info); +// int index = g_spawnedItems.FindValue(ref); +// int entity = EntRefToEntIndex(ref); +// if(entity > 0) { +// Editor[client].Import(entity, false); +// PrintToChat(client, "\x04[Editor]\x01 Editing entity \x05%d", entity); +// } else { +// PrintToChat(client, "\x04[Editor]\x01 Entity disappeared."); +// if(index > -1) { +// g_spawnedItems.Erase(index); +// index--; +// } else { index = 0; } +// } +// ShowEditList(client, index); +// } else if (action == MenuAction_Cancel) { +// if(param2 == MenuCancel_ExitBack) { +// DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, client); +// } +// } else if (action == MenuAction_End) +// delete menu; +// return 0; +// } diff --git a/scripting/include/editor/props/menu_methods.sp b/scripting/include/editor/props/menu_methods.sp new file mode 100644 index 0000000..dd58f38 --- /dev/null +++ b/scripting/include/editor/props/menu_methods.sp @@ -0,0 +1,317 @@ +///////////// +// METHODS +///////////// +void ShowSpawnRoot(int client) { + Menu menu = new Menu(Spawn_RootHandler); + menu.SetTitle("Choose spawn list:"); + menu.AddItem("f", "Favorites (Broken :D)"); + menu.AddItem("r", "Recently Spawned Props"); + menu.AddItem("s", "Search for Props"); + menu.AddItem("n", "Browse Props"); + menu.ExitBackButton = true; + menu.ExitButton = true; + menu.Display(client, MENU_TIME_FOREVER); +} +void Spawn_ShowRecents(int client) { + if(g_recentItems == null) LoadRecents(); + ArrayList items = GetRecentsItemList(); + if(items.Length == 0) { + CReplyToCommand(client, "\x04[Editor] \x01No recent props spawned."); + DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, client); + return; + } + ShowTempItemMenu(client, items, "Recents"); +} +void Spawn_ShowSearch(int client) { + g_PropData[client].chatPrompt = Prompt_Search; + CReplyToCommand(client, "\x04[Editor] \x01Please enter search query in chat:"); +} +void ShowDeleteList(int client, int index = -3) { + if(g_spawnedItems.Length == 0) { + SendEditorMessage(client, "No spawned items to delete"); + DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, client); + return; + } + Menu menu = new Menu(DeleteHandler); + menu.SetTitle("Delete Props"); + + menu.AddItem("-1", "Delete All"); + menu.AddItem("-2", "Delete All (Mine Only)"); + menu.AddItem("-3", "Delete Tool"); + // menu.AddItem("-4", "Delete Last Save"); + char info[8]; + char buffer[128]; + for(int i = 0; i < g_spawnedItems.Length; i++) { + int ref = GetSpawnedItem(i); + if(ref == -1) continue; + Format(info, sizeof(info), "0|%d", ref); + GetEntPropString(ref, Prop_Data, "m_ModelName", buffer, sizeof(buffer)); + index = FindCharInString(buffer, '/', true); + if(index != -1) + menu.AddItem(info, buffer[index + 1]); + } + + menu.ExitBackButton = true; + menu.ExitButton = true; + // Add +3 to the index for the 3 "Delete ..." buttons + // TODO: restore the delete index issue, use /7*7 + menu.DisplayAt(client, 0, MENU_TIME_FOREVER); +} +// void ShowEditList(int client, int index = 0) { +// if(g_spawnedItems.Length == 0) { +// SendEditorMessage(client, "No spawned items to edit"); +// DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, client); +// return; +// } +// Menu menu = new Menu(EditHandler); +// menu.SetTitle("Edit Prop"); + +// char info[8]; +// char buffer[32]; +// for(int i = 0; i < g_spawnedItems.Length; i++) { +// int ref = GetSpawnedItem(i); +// if(ref == -1) continue; +// Format(info, sizeof(info), "%d", ref); +// GetEntPropString(ref, Prop_Data, "m_ModelName", buffer, sizeof(buffer)); +// index = FindCharInString(buffer, '/', true); +// if(index != -1) +// menu.AddItem(info, buffer[index + 1]); +// } + +// menu.ExitBackButton = true; +// menu.ExitButton = true; +// // Add +2 to the index for the two "Delete ..." buttons +// menu.DisplayAt(client, index, MENU_TIME_FOREVER); +// } +void ShowCategoryList(int client, CategoryData category) { + LoadCategories(); + char info[4]; + // No category list provided, use the global one. + g_PropData[client].PushCategory(category); + Menu menu = new Menu(SpawnCategoryHandler); + char title[32]; + g_PropData[client].GetCategoryTitle(title, sizeof(title)); + menu.SetTitle(title); + CategoryData cat; + for(int i = 0; i < category.items.Length; i++) { + category.items.GetArray(i, cat); + Format(info, sizeof(info), "%d", i); + if(cat.hasItems) + menu.AddItem(info, cat.name); + else { + Format(title, sizeof(title), "[%s]", cat.name); + menu.AddItem(info, title); + } + } + menu.ExitBackButton = true; + menu.ExitButton = true; + // Round to page instead of index (int division) + int index = g_PropData[client].lastCategoryIndex / 7 * 7; + menu.DisplayAt(client, index, MENU_TIME_FOREVER); +} +void _showItemMenu(int client, ArrayList items, const char[] title = "", bool clearArray = false, const char[] classnameOverride = "") { + if(items == null) { + // Use previous list buffer + items = g_PropData[client].itemBuffer; + if(items == null) { + LogError("Previous list does not exist and no new list was provided ShowItemMenu(%N)", client); + PrintToChat(client, "\x04[Editor]\x01 An error occurred (no list)"); + return; + } + } else { + // Populate the buffer with this list + g_PropData[client].SetItemBuffer(items, clearArray); + // Reset the index, so we start on the first item + g_PropData[client].lastItemIndex = 0; + strcopy(g_PropData[client].classnameOverride, 32, classnameOverride); + } + if(items.Length == 0) { + PrintToChat(client, "\x04[Editor]\x01 No items to show."); + return; + } + Menu itemMenu = new Menu(SpawnItemHandler); + if(title[0] != '\0') + itemMenu.SetTitle(title); + ItemData item; + char info[8+128+64]; //i[8] + item.model[128] + item.name[64] + for(int i = 0; i < items.Length; i++) { + items.GetArray(i, item); + // Sadly need to duplicate item.name, for recents to work + Format(info, sizeof(info), "%d|%s|%s", i, item.model, item.name); + itemMenu.AddItem(info, item.name); + } + itemMenu.ExitBackButton = true; + itemMenu.ExitButton = true; + // We don't want to start at the index but the page of the index + int index = (g_PropData[client].lastItemIndex / 7) * 7; + itemMenu.DisplayAt(client, index, MENU_TIME_FOREVER); +} +/** + * Show a list of a category's items to spawn to the client + * + * @param client client to show menu to + * @param category the category to show items of + */ +void ShowCategoryItemMenu(int client, CategoryData category) { + char title[32]; + g_PropData[client].GetCategoryTitle(title, sizeof(title)); + Format(title, sizeof(title), "%s>%s", title, category.name); + _showItemMenu(client, category.items, title, false, category.classnameOverride); +} +/** + * Show a list of items to spawn to the client + * + * @param client client to show menu to + * @param items A list of ItemData. Optional, null to reuse last list + * @param title An optional title to show + * @param clearArray Should the items array be destroyed when menu is closed? + * @param classnameOverride Override the classname to spawn as + */ +void ShowItemMenu(int client, ArrayList items = null, const char[] title = "", const char[] classnameOverride = "") { + _showItemMenu(client, items, title, false, classnameOverride); +} +/** + * Show a list of items, deleting the arraylist on completion + * @param client client to show menu to + * @param items A list of ItemData + * @param title An optional title to show + * @param classnameOverride Override the classname to spawn as + */ +void ShowTempItemMenu(int client, ArrayList items, const char[] title = "", const char[] classnameOverride = "") { + if(items == null) { + LogError("ShowTempItemMenu: Given null item list"); + } + _showItemMenu(client, items, title, true, classnameOverride); +} + +void Spawn_ShowFavorites(int client) { + if(g_db == null) { + PrintToChat(client, "\x04[Editor]\x01 Cannot connect to database."); + return; + } + PrintCenterText(client, "Loading favorites...\nPlease wait"); + char query[256]; + GetClientAuthId(client, AuthId_Steam2, query, sizeof(query)); + g_db.Format(query, sizeof(query), "SELECT model, name FROM editor_favorites WHERE steamid = '%s' ORDER BY position DESC", query); + g_db.Query(DB_GetFavoritesCallback, query, GetClientUserId(client)); +} + +void Spawn_ShowSaveLoadMainMenu(int client) { + Menu menu = new Menu(SaveLoadMainMenuHandler); + menu.SetTitle("Save / Load"); + // Id is SaveType + menu.AddItem("1", "Map Scenes"); + menu.AddItem("2", "Schematics"); + menu.ExitBackButton = true; + menu.ExitButton = true; + menu.Display(client, MENU_TIME_FOREVER); +} + +void Spawn_ShowManagerMainMenu(int client, int index = 0) { + if(g_spawnedItems.Length == 0) { + SendEditorMessage(client, "No spawned items to manage"); + DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, client); + return; + } + Menu menu = new Menu(ManagerHandler); + menu.SetTitle("Manager"); + // Id is SaveType + char info[8]; + char buffer[128]; + for(int i = 0; i < g_spawnedItems.Length; i++) { + int ref = GetSpawnedItem(i); + if(ref == -1) continue; + IntToString(i, info, sizeof(info)); + GetEntPropString(ref, Prop_Data, "m_ModelName", buffer, sizeof(buffer)); + index = FindCharInString(buffer, '/', true); + if(index != -1) + menu.AddItem(info, buffer[index + 1]); + } + + menu.ExitBackButton = true; + menu.ExitButton = true; + menu.DisplayAt(client, index, MENU_TIME_FOREVER); +} +void ShowManagerEntityMenu(int client, int entity) { + if(!IsValidEntity(entity)) { + SendEditorMessage(client, "Item has vanished"); + Spawn_ShowManagerMainMenu(client); + return; + } + Menu menu = new Menu(ManagerEntityHandler); + menu.SetTitle("Manage %d", entity); + menu.AddItem("edit", "Edit"); + menu.AddItem("delete", "Delete"); + menu.AddItem("select", "Select"); + menu.AddItem("view", "View"); + menu.ExitBackButton = true; + menu.ExitButton = true; + menu.Display(client, MENU_TIME_FOREVER); +} +void ShowManagerSelectorMenu(int client) { + EntitySelector sel = EntitySelector.FromClient(client); + if(!sel.Active) { + sel.Start(GLOW_MANAGER); + sel.SetOnEnd(OnManagerSelectorEnd); + sel.SetOnPostSelect(OnManagerSelectorSelect); + sel.SetOnUnselect(OnManagerSelectorSelect); + } + Menu menu = new Menu(ManagerSelectorMainMenuHandler); + menu.SetTitle("Selector"); + menu.AddItem("list", "> List Entities"); + menu.AddItem("actions", "> Actions"); + menu.AddItem("add-self", "Add All Self-Spawned"); + menu.AddItem("add-all", "Add All Spawned"); + menu.ExitBackButton = false; + menu.ExitButton = true; + menu.Display(client, MENU_TIME_FOREVER); +} +void ShowManagerSelectorActionsMenu(int client) { + Menu menu = new Menu(ManagerSelectorActionHandler); + menu.SetTitle("Selector: Select action"); + char display[32]; + Format(display, sizeof(display), "Entities: %d", g_PropData[client].Selector.list.Length); + menu.AddItem("", display, ITEMDRAW_DISABLED); + + // menu.AddItem("edit", "Edit"); + menu.AddItem("delete", "Delete Entities"); + menu.AddItem("clear", "Clear Selection"); + // menu.AddItem("select", "Select"); + menu.AddItem("save_scene", "Save as Scene"); + menu.AddItem("save_collection", "Save as Collection"); + menu.ExitBackButton = true; + menu.ExitButton = true; + menu.Display(client, MENU_TIME_FOREVER); +} + +void ShowSaves(int client, SaveType type) { + ArrayList saves; + Menu newMenu; + if(type == Save_Scene) { + newMenu = new Menu(SaveLoadSceneHandler); + newMenu.SetTitle("Save & Load > Map Scenes"); + newMenu.AddItem("", "[Save New Scene]"); + saves = LoadScenes(); + } else if(type == Save_Schematic) { + newMenu = new Menu(SaveLoadSchematicHandler); + newMenu.SetTitle("Save & Load > Schematics"); + if(g_PropData[client].pendingSaveType == Save_Schematic) { + newMenu.AddItem("", "[Save Schematic]"); + } else { + newMenu.AddItem("", "[Start New Schematic]"); + // Don't load saves when in middle of creating schematic + saves = LoadSchematics(); + } + } + if(saves != null) { + char name[64]; + for(int i = 0; i < saves.Length; i++) { + saves.GetString(i, name, sizeof(name)); + newMenu.AddItem(name, name); + } + delete saves; + } + newMenu.ExitBackButton = true; + newMenu.ExitButton = true; + newMenu.Display(client, MENU_TIME_FOREVER); +} \ No newline at end of file diff --git a/scripting/include/editor/props/methods.sp b/scripting/include/editor/props/methods.sp new file mode 100644 index 0000000..cef42f1 --- /dev/null +++ b/scripting/include/editor/props/methods.sp @@ -0,0 +1,565 @@ + +ArrayList LoadScenes() { + char path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/prop_spawner/saves/%s", g_currentMap); + FileType fileType; + DirectoryListing listing = OpenDirectory(path); + if(listing == null) return null; + char buffer[64]; + ArrayList saves = new ArrayList(ByteCountToCells(64)); + while(listing.GetNext(buffer, sizeof(buffer), fileType)) { + if(buffer[0] == '.') continue; + saves.PushString(buffer); + } + delete listing; + return saves; +} + +ArrayList LoadSchematics() { + char path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/prop_spawner/schematics"); + FileType fileType; + DirectoryListing listing = OpenDirectory(path); + if(listing == null) return null; + char buffer[64]; + ArrayList saves = new ArrayList(ByteCountToCells(64)); + while(listing.GetNext(buffer, sizeof(buffer), fileType) && fileType == FileType_File) { + if(buffer[0] == '.') continue; + saves.PushString(buffer); + } + delete listing; + return saves; +} + +bool LoadScene(const char[] save, bool asPreview = false) { + char path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/prop_spawner/saves/%s/%s", g_currentMap, save); + // ArrayList savedItems = new ArrayList(sizeof(SaveData)); + File file = OpenFile(path, "r"); + if(file == null) return false; + char buffer[256]; + if(asPreview) { + // Kill any previous preview + if(g_previewItems != null) ClearSavePreview(); + g_previewItems = new ArrayList(); + } + SaveData data; + while(file.ReadLine(buffer, sizeof(buffer))) { + if(buffer[0] == '#') continue; + data.Deserialize(buffer); + int entity = data.ToEntity(NULL_VECTOR, asPreview); + if(entity == -1) { + PrintToServer("[Editor] LoadScene(\"%s\", %b): failed to create %s", save, asPreview, buffer); + continue; + } + } + delete file; + return true; +} + +void ConfirmSave(int client, const char[] name) { + Menu newMenu = new Menu(SaveLoadConfirmHandler); + newMenu.AddItem(name, "Spawn"); + newMenu.AddItem("", "Cancel"); + newMenu.ExitBackButton = false; + newMenu.ExitButton = false; + newMenu.Display(client, 0); +} +void ClearSavePreview() { + if(g_previewItems != null) { + for(int i = 0; i < g_previewItems.Length; i++) { + int ref = g_previewItems.Get(i); + if(IsValidEntity(ref)) { + RemoveEntity(ref); + } + } + delete g_previewItems; + } + g_pendingSaveClient = 0; +} + +void AddSpawnedItem(int entity, int client = 0) { + if(client > 0 && g_PropData[client].pendingSaveType == Save_Schematic) { + g_PropData[client].schematic.AddEntity(entity, client); + } + // TODO: confirm if we want it to be in list, otherwise we need to clean manually + int userid = client > 0 ? GetClientUserId(client) : 0; + int index = g_spawnedItems.Push(EntIndexToEntRef(entity)); + g_spawnedItems.Set(index, userid, 1); +} + +bool CreateCollection(const char[] folder, const char[] name, ArrayList entities, int client = 0) { + char path[PLATFORM_MAX_PATH], pathTemp[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/prop_spawner/collections", folder); + CreateDirectory(path, 509); + Format(path, sizeof(path), "%s/%s", path, folder); + CreateDirectory(path, 509); + Format(pathTemp, sizeof(pathTemp), "%s/%s.json.tmp", path, name); + Format(path, sizeof(path), "%s/%s.json", path, name); + char buffer[132]; + JSONObject root = new JSONObject(); + FormatTime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%S.%f"); + root.SetString("created", buffer); + + if(client > 0) { + GetClientAuthId(client, AuthId_Steam2, buffer, sizeof(buffer)); + root.SetString("creator_steamid", buffer); + float vec[3]; + GetClientAbsOrigin(client, vec); + JSONObject origin = view_as(Coordinates.FromVec(vec)); + root.Set("origin", origin); + + GetClientEyeAngles(client, vec); + JSONObject angles = view_as(Coordinates.FromVec(vec)); + root.Set("angles", angles); + } + JSONArray entArr = new JSONArray(); + for(int i = 0; i < entities.Length; i++) { + int ref = entities.Get(i); + if(IsValidEntity(ref)) { + SpawnerEntity ent = SpawnerEntity.FromEntity(EntRefToEntIndex(ref)); + entArr.Push(ent); + } + } + root.Set("entities", entArr); + root.ToFile(pathTemp, JSON_INDENT(4)); + RenameFile(path, pathTemp); + SetFilePermissions(path, FPERM_U_WRITE | FPERM_U_READ | FPERM_G_WRITE | FPERM_G_READ | FPERM_O_READ); + LogAction(client, -1, "created collection \"%s\" in \"%s\"", name, path); + return true; +} + +bool CreateSceneSave(const char[] name, ArrayList items = null, int client = 0) { + char path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/prop_spawner/saves/%s", g_currentMap); + CreateDirectory(path, 509); + Format(path, sizeof(path), "%s/%s.txt", path, name); + File file = OpenFile(path, "w"); + if(file == null) { + PrintToServer("[Editor] Could not save: %s", path); + return false; + } + // TODO: switch to json + char buffer[132]; + SaveData data; + if(items == null) items = g_spawnedItems; + for(int i = 0; i < items.Length; i++) { + int ref = items.Get(i); + if(IsValidEntity(ref)) { + data.FromEntity(ref); + data.Serialize(buffer, sizeof(buffer)); + file.WriteLine("%s", buffer); + } + } + file.Flush(); + delete file; + return true; +} + +void UnloadSave() { + if(g_savedItems != null) { + delete g_savedItems; + } +} + +public void LoadCategories() { + if(ROOT_CATEGORY.items != null) return; + ROOT_CATEGORY.items = new ArrayList(sizeof(CategoryData)); + char path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/prop_spawner/models"); + LoadFolder(ROOT_CATEGORY.items, path); + ROOT_CATEGORY.items.SortCustom(SortCategories); +} +int SortCategories(int index1, int index2, ArrayList array, Handle hndl) { + CategoryData cat1; + array.GetArray(index1, cat1); + CategoryData cat2; + array.GetArray(index2, cat2); + return strcmp(cat1.name, cat2.name); +} +public void UnloadCategories() { + if(ROOT_CATEGORY.items == null) return; + _UnloadCategories(ROOT_CATEGORY.items); + delete ROOT_CATEGORY.items; +} +void _UnloadCategories(ArrayList list) { + CategoryData cat; + for(int i = 0; i < list.Length; i++) { + list.GetArray(i, cat); + _UnloadCategory(cat); + } +} +void _UnloadCategory(CategoryData cat) { + // Is a sub-category: + if(!cat.hasItems) { + _UnloadCategories(cat.items); + } + delete cat.items; +} + +void LoadFolder(ArrayList parent, const char[] rootPath) { + char buffer[PLATFORM_MAX_PATH]; + FileType fileType; + DirectoryListing listing = OpenDirectory(rootPath); + if(listing == null) { + LogError("Cannot open \"%s\"", rootPath); + } + while(listing.GetNext(buffer, sizeof(buffer), fileType)) { + if(fileType == FileType_Directory) { + // TODO: support subcategory + if(buffer[0] == '.') continue; + CategoryData data; + Format(data.name, sizeof(data.name), "%s", buffer); + data.items = new ArrayList(sizeof(CategoryData)); + + Format(buffer, sizeof(buffer), "%s/%s", rootPath, buffer); + LoadFolder(data.items, buffer); + parent.PushArray(data); + } else if(fileType == FileType_File) { + Format(buffer, sizeof(buffer), "%s/%s", rootPath, buffer); + LoadProps(parent, buffer); + } + } + delete listing; +} + +void LoadProps(ArrayList parent, const char[] filePath) { + File file = OpenFile(filePath, "r"); + if(file == null) { + PrintToServer("[Props] Cannot open file \"%s\"", filePath); + return; + } + CategoryData category; + category.items = new ArrayList(sizeof(ItemData)); + category.hasItems = true; + char buffer[128]; + if(!file.ReadLine(buffer, sizeof(buffer))) { + delete file; + return; + } + ReplaceString(buffer, sizeof(buffer), "\n", ""); + ReplaceString(buffer, sizeof(buffer), "\r", ""); + Format(category.name, sizeof(category.name), "%s", buffer); + while(file.ReadLine(buffer, sizeof(buffer))) { + if(buffer[0] == '#') continue; + ReplaceString(buffer, sizeof(buffer), "\n", ""); + ReplaceString(buffer, sizeof(buffer), "\r", ""); + ItemData item; + int index = SplitString(buffer, ":", item.model, sizeof(item.model)); + if(index == -1) { + index = SplitString(buffer, " ", item.model, sizeof(item.model)); + if(index == -1) { + // No name provided, use the model's filename + index = FindCharInString(buffer, '/', true); + strcopy(item.name, sizeof(item.name), item.model[index + 1]); + } else { + strcopy(item.name, sizeof(item.name), buffer[index]); + } + category.items.PushArray(item); + } else if(StrEqual(item.model, "Classname")) { + strcopy(category.classnameOverride, sizeof(category.classnameOverride), buffer[index]); + } else if(StrEqual(item.model, "Type")) { + Format(category.classnameOverride, sizeof(category.classnameOverride), "_%s", buffer[index]); + } + } + parent.PushArray(category); + delete file; +} +bool recentsChanged = false; +bool SaveRecents() { + if(!recentsChanged) return true; // Nothing to do, nothing changed + if(g_recentItems == null) return false; + char path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/prop_spawner/recents_cache.csv"); + File file = OpenFile(path, "w"); + if(file == null) { + PrintToServer("[Editor] Could not write to %s", path); + return false; + } + StringMapSnapshot snapshot = g_recentItems.Snapshot(); + char model[128]; + RecentEntry entry; + for(int i = 0; i < snapshot.Length; i++) { + snapshot.GetKey(i, model, sizeof(model)); + g_recentItems.GetArray(model, entry, sizeof(entry)); + file.WriteLine("%s,%s,%d", model, entry.name, entry.count); + } + file.Flush(); + delete file; + delete snapshot; + recentsChanged = false; + return true; +} +bool LoadRecents() { + if(g_recentItems != null) delete g_recentItems; + char path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/prop_spawner/recents_cache.csv"); + File file = OpenFile(path, "r"); + if(file == null) return false; + g_recentItems = new StringMap(); + char buffer[128+64+16]; + char model[128]; + RecentEntry entry; + while(file.ReadLine(buffer, sizeof(buffer))) { + int index = SplitString(buffer, ",", model, sizeof(model)); + index += SplitString(buffer[index], ",", entry.name, sizeof(entry.name)); + entry.count = StringToInt(buffer[index]); + g_recentItems.SetArray(model, entry, sizeof(entry)); + } + delete file; + return true; +} + +// Returns an ArrayList of all the recents +ArrayList GetRecentsItemList() { + ArrayList items = new ArrayList(sizeof(ItemData)); + StringMapSnapshot snapshot = g_recentItems.Snapshot(); + char model[128]; + RecentEntry entry; + ItemData item; + for(int i = 0; i < snapshot.Length; i++) { + snapshot.GetKey(i, model, sizeof(model)); + g_recentItems.GetArray(model, entry, sizeof(entry)); + strcopy(item.model, sizeof(item.model), model); + strcopy(item.name, sizeof(item.name), entry.name); + } + // This is pretty expensive in terms of allocations but shrug + items.SortCustom(SortRecents); + delete snapshot; + return items; +} + +int SortRecents(int index1, int index2, ArrayList array, Handle handle) { + ItemData data1; + array.GetArray(index1, data1); + ItemData data2; + array.GetArray(index2, data2); + + int count1, count2; + RecentEntry entry; + if(g_recentItems.GetArray(data1.model, entry, sizeof(entry))) return 0; //skip if somehow no entry + count1 = entry.count; + if(g_recentItems.GetArray(data2.model, entry, sizeof(entry))) return 0; //skip if somehow no entry + count2 = entry.count; + return count2 - count1; // desc +} + +void AddRecent(const char[] model, const char[] name) { + if(g_recentItems == null) { + if(!LoadRecents()) return; + } + RecentEntry entry; + if(!g_recentItems.GetArray(model, entry, sizeof(entry))) { + entry.count = 0; + strcopy(entry.name, sizeof(entry.name), name); + } + entry.count++; + recentsChanged = true; + g_recentItems.SetArray(model, entry, sizeof(entry)); +} +public Action OnClientSayCommand(int client, const char[] command, const char[] sArgs) { + if(g_PropData[client].chatPrompt == Prompt_None) { + return Plugin_Continue; + } + switch(g_PropData[client].chatPrompt) { + case Prompt_Search: DoSearch(client, sArgs); + case Prompt_SaveScene: { + if(CreateSceneSave(sArgs, g_PropData[client].itemBuffer, client)) { + PrintToChat(client, "\x04[Editor]\x01 Saved as \x05%s/%s.txt", g_currentMap, sArgs); + } else { + PrintToChat(client, "\x04[Editor]\x01 Unable to save. Sorry."); + } + } + case Prompt_SaveCollection: { + if(CreateCollection("global", sArgs, g_PropData[client].itemBuffer, client)) { + SendEditorMessage(client, "Saved \x05%s/%s.json\x04 successfully.", "global", sArgs); + } else { + SendEditorMessage(client, "Failed to save collection."); + } + // TODO: figure out how to know which way to return + ShowManagerSelectorMenu(client); + } + default: + PrintToChat(client, "\x04[Editor]\x01 Not implemented."); + } + g_PropData[client].chatPrompt = Prompt_None; + return Plugin_Handled; +} +void DoSearch(int client, const char[] query) { + ArrayList results = SearchItems(query); + if(results.Length == 0) { + CPrintToChat(client, "\x04[Editor]\x01 No results found. :("); + } else { + char title[64]; + Format(title, sizeof(title), "Results for \"%s\"", query); + ShowTempItemMenu(client, results, title); + } +} +// Gets the index of the spawned item, starting at index. negative to go from back +int GetSpawnedIndex(int client, int index) { + int userid = GetClientUserId(client); + if(index >= 0) { + for(int i = index; i < g_spawnedItems.Length; i++) { + int spawnedBy = g_spawnedItems.Get(i, 1); + if(spawnedBy == userid) { + return i; + } + } + } else { + for(int i = g_spawnedItems.Length + index; i >= 0; i--) { + int spawnedBy = g_spawnedItems.Get(i, 1); + if(spawnedBy == userid) { + return i; + } + } + } + return -1; +} +#define MAX_SEARCH_RESULTS 10 +ArrayList SearchItems(const char[] query) { + // We have to put it into SearchData enum struct, then convert it back to ItemResult + LoadCategories(); + ArrayList results = new ArrayList(sizeof(SearchData)); + _searchCategory(results, ROOT_CATEGORY.items, query); + results.SortCustom(SortSearch); + ArrayList items = new ArrayList(sizeof(ItemData)); + ItemData item; + SearchData data; + for(int i = 0; i < results.Length; i++) { + results.GetArray(i, data); + item.FromSearchData(data); + items.PushArray(item); + } + delete results; + return items; +} + +int SortSearch(int index1, int index2, ArrayList array, Handle handle) { + SearchData data1; + array.GetArray(index1, data1); + SearchData data2; + array.GetArray(index2, data2); + return data1.index - data2.index; +} + +void _searchCategory(ArrayList results, ArrayList categories, const char[] query) { + CategoryData cat; + if(categories == null) return; + for(int i = 0; i < categories.Length; i++) { + categories.GetArray(i, cat); + if(cat.hasItems) { + //cat.items is of CatetoryData + if(!_searchItems(results, cat.items, query)) return; + } else { + //cat.items is of ItemData + _searchCategory(results, cat.items, query); + } + } +} +bool _searchItems(ArrayList results, ArrayList items, const char[] query) { + ItemData item; + SearchData search; + if(items == null) return false; + for(int i = 0; i < items.Length; i++) { + items.GetArray(i, item); + int searchIndex = StrContains(item.name, query, false); + if(searchIndex > -1) { + search.FromItemData(item); + search.index = searchIndex; + results.PushArray(search); + if(results.Length > MAX_SEARCH_RESULTS) return false; + } + } + return true; +} + +int GetSpawnedItem(int index) { + if(index < 0 || index >= g_spawnedItems.Length) return -1; + int ref = g_spawnedItems.Get(index); + if(!IsValidEntity(ref)) { + g_spawnedItems.Erase(index); + return -1; + } + return ref; +} + +bool RemoveSpawnedProp(int ref) { + // int ref = EntIndexToEntRef(entity); + int index = g_spawnedItems.FindValue(ref); + if(index > -1) { + g_spawnedItems.Erase(index); + return true; + } + return false; +} + +void OnDeleteToolEnd(int client, ArrayList entities) { + int count; + for(int i = 0; i < entities.Length; i++) { + int ref = entities.Get(i); + if(IsValidEntity(ref)) { + count++; + RemoveSpawnedProp(ref); + RemoveEntity(ref); + } + } + delete entities; + PrintToChat(client, "\x04[Editor]\x01 \x05%d\x01 entities deleted", count); +} + +void OnManagerSelectorEnd(int client, ArrayList entities) { + // TODO: implement manager selector cb + ReplyToCommand(client, "Not Implemented"); + Spawn_ShowManagerMainMenu(client); + if(entities != null) { + delete entities; + } +} +void OnManagerSelectorSelect(int client, int entity) { + // update entity count + // ShowManagerSelectorMenu(client); +} + +int DeleteAll(int onlyPlayer = 0) { + int userid = onlyPlayer > 0 ? GetClientUserId(onlyPlayer) : 0; + int count; + for(int i = 0; i < g_spawnedItems.Length; i++) { + int ref = g_spawnedItems.Get(i); + int spawnedBy = g_spawnedItems.Get(i, 1); + // Skip if wishing to only delete certain items: + if(onlyPlayer == 0 || spawnedBy == userid) { + if(IsValidEntity(ref)) { + RemoveEntity(ref); + } + // TODO: erasing while removing + g_spawnedItems.Erase(i); + i--; // go back up one + count++; + } + } + return count; +} + +#define SHOW_HINT_MIN_DURATION 600 // 600 s (10min) +void ShowHint(int client) { + int time = GetTime(); + int lastActive = g_PropData[client].lastActiveTime; + g_PropData[client].lastActiveTime = time; + if(time - lastActive < SHOW_HINT_MIN_DURATION) return; + PrintToChat(client, "\x01Change Mode: \x05ZOOM"); + PrintToChat(client, "\x01Place: \x05USE(E) \x01Cancel: \x05WALK(SHIFT) + USE(E)"); + PrintToChat(client, "\x01Rotate: \x05Hold RELOAD(R) + MOVE MOUSE\x01 Change Axis: \x05Left Click \x01Snap Angle: \x05Right Click"); + PrintToChat(client, "\x01Type \x05/prop favorite\x01 to (un)favorite."); + PrintToChat(client, "\x01More information & cheatsheat: \x05%s", "https://admin.jackz.me/docs/props"); +} + +void ToggleFavorite(int client, const char[] model, const char[] name = "") { + char query[256]; + GetClientAuthId(client, AuthId_Steam2, query, sizeof(query)); + DataPack pack; + pack.WriteCell(GetClientUserId(client)); + pack.WriteString(model); + pack.WriteString(name); + g_db.Format(query, sizeof(query), "SELECT name FROM editor_favorites WHERE steamid = '%s' AND model = '%s'", query, model); + g_db.Query(DB_ToggleFavoriteCallback, query, pack); +} \ No newline at end of file diff --git a/scripting/l4d2_editor.sp b/scripting/l4d2_editor.sp index cfc204e..fa55c29 100644 --- a/scripting/l4d2_editor.sp +++ b/scripting/l4d2_editor.sp @@ -14,6 +14,7 @@ #include #include #include +#include int g_iLaserIndex; @@ -94,7 +95,7 @@ public void OnPluginStart() { char targetName[32]; while((entity = FindEntityByClassname(entity, "func_brush")) != INVALID_ENT_REFERENCE) { GetEntPropString(entity, Prop_Data, "m_iName", targetName, sizeof(targetName)); - if(StrContains(targetName, "l4d2_hats_") == 0) { + if(StrContains(targetName, "editor") == 0) { createdWalls.Push(EntIndexToEntRef(entity)); SDKHook(entity, SDKHook_Use, OnWallClicked); } @@ -200,7 +201,8 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3 } else if(buttons & IN_USE) { if(buttons & IN_SPEED) { //Delete - g_PropData[client].Selector.End(); + ArrayList items = g_PropData[client].Selector.End(); + delete items; } else if(buttons & IN_DUCK) { //Cancel g_PropData[client].Selector.Cancel(); @@ -406,7 +408,7 @@ public void OnPluginEnd() { if(g_spawnedItems != null) { delete g_spawnedItems; } - TriggerInput("prop_preview", "Kill"); + TriggerInput("editor_preview", "Kill"); } public bool TraceEntityFilterPlayer(int entity, int contentsMask, any data) {