mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 03:03:21 +00:00
Updates
This commit is contained in:
parent
fd2367f41f
commit
79d37bdd34
45 changed files with 5587 additions and 3877 deletions
|
@ -50,7 +50,9 @@ stock void EntFire(const char[] name, const char[] input) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void CreateCoinEntity(float pos[3]) {
|
||||
// int ent = CreateProp("prop_dynamic", "")
|
||||
}
|
||||
|
||||
void SetupEntities(bool blockers = true, bool props = true, bool portals = true) {
|
||||
#if defined DEBUG_BLOCKERS
|
||||
|
|
|
@ -125,6 +125,12 @@ methodmap GuessWhoGame < BaseGame {
|
|||
}
|
||||
}
|
||||
|
||||
property int TargetCoinCount {
|
||||
public get() {
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
public void Start() {
|
||||
|
||||
}
|
||||
|
@ -301,6 +307,14 @@ methodmap GuessWhoGame < BaseGame {
|
|||
SDKUnhook(client, SDKHook_OnTakeDamageAlive, OnTakeDamageAlive);
|
||||
SDKUnhook(client, SDKHook_WeaponEquip, OnWeaponEquip);
|
||||
}
|
||||
|
||||
public void PopulateCoins() {
|
||||
float pos[3];
|
||||
for(int i = 0; i < this.TargetCoinCount; i++) {
|
||||
movePoints.GetRandomPoint(pos);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stock bool ArePlayersJoining() {
|
||||
|
|
|
@ -13,13 +13,18 @@ Action Timer_RecordPoints(Handle h, int i) {
|
|||
vecLastLocation[i] = meta.pos;
|
||||
}
|
||||
}
|
||||
Game.MapTime++;
|
||||
PrintHintText(i, "Points: %d / %d", movePoints.Length, MAX_VALID_LOCATIONS);
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
|
||||
bool firstCheckDone = false;
|
||||
Action Timer_WaitForPlayers(Handle h) {
|
||||
if(!isEnabled) return Plugin_Stop;
|
||||
if(!isEnabled) {
|
||||
waitTimer = null;
|
||||
return Plugin_Stop;
|
||||
}
|
||||
if(!ArePlayersJoining()) {
|
||||
Game.Debug("No players pending, ready to go");
|
||||
if(!firstCheckDone) {
|
||||
|
@ -28,6 +33,7 @@ Action Timer_WaitForPlayers(Handle h) {
|
|||
} else {
|
||||
firstCheckDone = false;
|
||||
InitGamemode();
|
||||
waitTimer = null;
|
||||
return Plugin_Stop;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
native bool SpawnSchematic(const char name[32], const float pos[3], const float angles[3] = NULL_VECTOR);
|
|
@ -1,7 +1,6 @@
|
|||
int BUILDER_COLOR[4] = { 0, 255, 0, 235 };
|
||||
int GLOW_BLUE[4] = { 3, 148, 252 };
|
||||
int GLOW_RED_ALPHA[4] = { 255, 0, 0, 235 };
|
||||
int GLOW_RED[3] = { 255, 0, 0};
|
||||
int GLOW_WHITE[4] = { 255, 255, 255, 255 };
|
||||
int GLOW_GREEN[4] = { 3, 252, 53 };
|
||||
float ORIGIN_SIZE[3] = { 2.0, 2.0, 2.0 };
|
||||
|
@ -27,26 +26,21 @@ char MODE_NAME[5][] = {
|
|||
"Freelook"
|
||||
}
|
||||
|
||||
enum editFlag {
|
||||
enum {
|
||||
Edit_None,
|
||||
Edit_Copy = 1,
|
||||
Edit_Preview = 2,
|
||||
Edit_WallCreator = 4
|
||||
Edit_WallCreator = 4,
|
||||
Edit_Manager = 8
|
||||
}
|
||||
|
||||
enum buildType {
|
||||
Build_Solid,
|
||||
Build_Physics,
|
||||
Build_NonSolid,
|
||||
// TODO: Build_Weapon (spawn as weapon?)
|
||||
}
|
||||
|
||||
enum CompleteType {
|
||||
Complete_WallSuccess,
|
||||
Complete_WallError,
|
||||
Complete_PropSpawned,
|
||||
Complete_PropError,
|
||||
Complete_EditSuccess
|
||||
}
|
||||
|
||||
enum StackerDirection {
|
||||
Stack_Off,
|
||||
|
@ -88,6 +82,7 @@ enum struct EditorData {
|
|||
int colorIndex;
|
||||
int axis;
|
||||
int snapAngle;
|
||||
float rotateSpeed;
|
||||
int moveSpeed;
|
||||
float moveDistance;
|
||||
int entity;
|
||||
|
@ -97,11 +92,14 @@ enum struct EditorData {
|
|||
|
||||
editMode mode;
|
||||
buildType buildType;
|
||||
editFlag flags;
|
||||
int flags;
|
||||
|
||||
PrivateForward callback;
|
||||
bool isEditCallback;
|
||||
|
||||
void Reset(bool initial = false) {
|
||||
// Clear preview entity
|
||||
if(this.entity != INVALID_ENT_REFERENCE && this.flags & Edit_Preview && IsValidEntity(this.entity)) {
|
||||
if(this.entity != INVALID_ENT_REFERENCE && (this.flags & Edit_Preview) && IsValidEntity(this.entity)) {
|
||||
RemoveEntity(this.entity);
|
||||
}
|
||||
this.stackerDirection = Stack_Off;
|
||||
|
@ -111,12 +109,13 @@ enum struct EditorData {
|
|||
this.size[0] = this.size[1] = this.size[2] = 5.0;
|
||||
this.angles[0] = this.angles[1] = this.angles[2] = 0.0;
|
||||
this.colorIndex = 0;
|
||||
this.axis = 1;
|
||||
this.axis = 0;
|
||||
this.moveDistance = 200.0;
|
||||
this.flags = Edit_None;
|
||||
this.classname[0] = '\0';
|
||||
this.CalculateMins();
|
||||
this.SetMode(INACTIVE);
|
||||
this.rotateSpeed = 0.1;
|
||||
// Settings that don't get reset on new spawns:
|
||||
if(initial) {
|
||||
this.color[0] = this.color[1] = this.color[2] = this.color[3] = 255;
|
||||
|
@ -138,6 +137,12 @@ enum struct EditorData {
|
|||
if(this.flags & Edit_WallCreator || this.entity == INVALID_ENT_REFERENCE) {
|
||||
Effect_DrawBeamBoxRotatableToAll(this.origin, this.mins, this.size, this.angles, g_iLaserIndex, 0, 0, 30, lifetime, 0.4, 0.4, 0, amplitude, color, 0);
|
||||
} else {
|
||||
if(this.snapAngle != 1) {
|
||||
this.angles[0] = RoundToNearestInterval(this.angles[0], this.snapAngle);
|
||||
this.angles[1] = RoundToNearestInterval(this.angles[1], this.snapAngle);
|
||||
this.angles[2] = RoundToNearestInterval(this.angles[2], this.snapAngle);
|
||||
|
||||
}
|
||||
TeleportEntity(this.entity, this.origin, this.angles, NULL_VECTOR);
|
||||
}
|
||||
Effect_DrawAxisOfRotationToAll(this.origin, this.angles, ORIGIN_SIZE, g_iLaserIndex, 0, 0, 30, 0.2, 0.1, 0.1, 0, 0.0, 0);
|
||||
|
@ -147,9 +152,6 @@ enum struct EditorData {
|
|||
void UpdateEntity() {
|
||||
int alpha = this.color[3];
|
||||
// Keep previews transparent
|
||||
if(this.flags & Edit_Preview) {
|
||||
alpha = 200;
|
||||
}
|
||||
SetEntityRenderColor(this.entity, this.color[0], this.color[1], this.color[2], alpha);
|
||||
}
|
||||
|
||||
|
@ -178,6 +180,10 @@ enum struct EditorData {
|
|||
void SetName(const char[] name) {
|
||||
strcopy(this.name, sizeof(this.name), name);
|
||||
}
|
||||
void SetCallback(PrivateForward callback, bool isEditCallback) {
|
||||
this.callback = callback;
|
||||
this.isEditCallback = isEditCallback;
|
||||
}
|
||||
|
||||
void CycleMode() {
|
||||
// Remove frozen state when cycling
|
||||
|
@ -210,43 +216,43 @@ enum struct EditorData {
|
|||
PrintToChat(this.client, "\x04[Editor]\x01 Mode: \x05%s\x01 (Press \x04RELOAD\x01 to change)", MODE_NAME[this.mode]);
|
||||
}
|
||||
|
||||
void CycleStacker(float tick) {
|
||||
if(tick - cmdThrottle[this.client] <= 0.10) return;
|
||||
void CycleStacker() {
|
||||
int newDirection = view_as<int>(this.stackerDirection) + 1;
|
||||
if(newDirection == view_as<int>(Stack_Down)) newDirection = 0;
|
||||
this.stackerDirection = view_as<StackerDirection>(newDirection);
|
||||
|
||||
PrintToChat(this.client, "\x04[Editor]\x01 Stacker: %s\x01", STACK_DIRECTION_NAME[this.stackerDirection]);
|
||||
cmdThrottle[this.client] = tick;
|
||||
}
|
||||
|
||||
void ToggleCollision(float tick) {
|
||||
if(tick - cmdThrottle[this.client] <= 0.25) return;
|
||||
void ToggleCollision() {
|
||||
this.hasCollision = !this.hasCollision
|
||||
PrintToChat(this.client, "\x04[Editor]\x01 Collision: %s", ON_OFF_STRING[view_as<int>(this.hasCollision)]);
|
||||
cmdThrottle[this.client] = tick;
|
||||
}
|
||||
|
||||
void ToggleCollisionRotate(float tick) {
|
||||
if(tick - cmdThrottle[this.client] <= 0.20) return;
|
||||
void ToggleCollisionRotate() {
|
||||
this.hasCollisionRotate = !this.hasCollisionRotate
|
||||
PrintToChat(this.client, "\x04[Editor]\x01 Rotate with Collision: %s", ON_OFF_STRING[view_as<int>(this.hasCollisionRotate)]);
|
||||
cmdThrottle[this.client] = tick;
|
||||
}
|
||||
|
||||
void CycleAxis(float tick) {
|
||||
if(tick - cmdThrottle[this.client] <= 0.1) return;
|
||||
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: \x05HEADING (Y)\x01");
|
||||
} else if(this.axis == 1) {
|
||||
this.axis = 2;
|
||||
PrintToChat(this.client, "\x04[Editor]\x01 Rotate Axis: \x05PITCH (X)\x01");
|
||||
PrintToChat(this.client, "\x04[Editor]\x01 Rotate Axis: \x05ROLL (Z)\x01");
|
||||
} else {
|
||||
this.axis = 0;
|
||||
PrintToChat(this.client, "\x04[Editor]\x01 Rotate Axis: \x05ROLL (Z)\x01");
|
||||
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;
|
||||
}
|
||||
cmdThrottle[this.client] = tick;
|
||||
}
|
||||
|
||||
void CycleSnapAngle(float tick) {
|
||||
|
@ -328,18 +334,38 @@ enum struct EditorData {
|
|||
|
||||
// Complete the edit, wall creation, or spawning
|
||||
CompleteType Done(int& entity) {
|
||||
CompleteType type;
|
||||
if(this.flags & Edit_WallCreator) {
|
||||
return this._FinishWall(entity) ? Complete_WallSuccess : Complete_WallError;
|
||||
type = this._FinishWall(entity) ? Complete_WallSuccess : Complete_WallError;
|
||||
} else if(this.flags & Edit_Preview) {
|
||||
return this._FinishPreview(entity) ? Complete_PropSpawned : Complete_PropError;
|
||||
type = this._FinishPreview(entity) ? Complete_PropSpawned : Complete_PropError;
|
||||
} else {
|
||||
// Is edit, do nothing, just reset
|
||||
PrintHintText(this.client, "Edit Complete");
|
||||
this.Reset();
|
||||
entity = 0;
|
||||
|
||||
return Complete_EditSuccess;
|
||||
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) {
|
||||
|
@ -569,7 +595,7 @@ enum struct EditorData {
|
|||
DispatchKeyValue(entity, "targetname", "prop_preview");
|
||||
DispatchKeyValue(entity, "solid", "0");
|
||||
DispatchKeyValue(entity, "rendercolor", "255 128 255");
|
||||
DispatchKeyValue(entity, "renderamt", "200");
|
||||
DispatchKeyValue(entity, "renderamt", "255");
|
||||
DispatchKeyValue(entity, "rendermode", "1");
|
||||
TeleportEntity(entity, this.origin, NULL_VECTOR, NULL_VECTOR);
|
||||
if(!DispatchSpawn(entity)) {
|
||||
|
@ -583,8 +609,11 @@ enum struct EditorData {
|
|||
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)
|
||||
/**
|
||||
* 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);
|
||||
|
@ -599,6 +628,22 @@ enum struct EditorData {
|
|||
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() {
|
||||
|
@ -611,9 +656,22 @@ enum struct EditorData {
|
|||
}
|
||||
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) {
|
||||
|
|
|
@ -43,7 +43,7 @@ int lastHatRequestTime[MAXPLAYERS+1];
|
|||
HatInstance hatData[MAXPLAYERS+1];
|
||||
StringMap g_HatPresets;
|
||||
|
||||
#define MAX_FORBIDDEN_CLASSNAMES 14
|
||||
#define MAX_FORBIDDEN_CLASSNAMES 15
|
||||
char FORBIDDEN_CLASSNAMES[MAX_FORBIDDEN_CLASSNAMES][] = {
|
||||
"prop_door_rotating_checkpoint",
|
||||
"env_physics_blocker",
|
||||
|
@ -59,7 +59,8 @@ char FORBIDDEN_CLASSNAMES[MAX_FORBIDDEN_CLASSNAMES][] = {
|
|||
// "infected",
|
||||
"func_lod",
|
||||
"func_door",
|
||||
"prop_ragdoll"
|
||||
"prop_ragdoll",
|
||||
"move_rope"
|
||||
};
|
||||
|
||||
#define MAX_FORBIDDEN_MODELS 2
|
||||
|
@ -73,7 +74,7 @@ char FORBIDDEN_MODELS[MAX_FORBIDDEN_MODELS][] = {
|
|||
// Classnames that should automatically trigger reverse infected
|
||||
static char REVERSE_CLASSNAMES[MAX_REVERSE_CLASSNAMES][] = {
|
||||
"infected",
|
||||
"func_movelinear"
|
||||
"func_movelinear",
|
||||
};
|
||||
|
||||
Action Command_DoAHat(int client, int args) {
|
||||
|
|
122
scripting/include/hats/natives.sp
Normal file
122
scripting/include/hats/natives.sp
Normal file
|
@ -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;
|
||||
}
|
|
@ -25,6 +25,8 @@ enum SaveType {
|
|||
Save_Schematic
|
||||
}
|
||||
|
||||
int GLOW_MANAGER[3] = { 52, 174, 235 };
|
||||
|
||||
enum struct Schematic {
|
||||
char name[64];
|
||||
char creatorSteamid[32];
|
||||
|
@ -134,6 +136,197 @@ public any Native_SpawnSchematic(Handle plugin, int numParams) {
|
|||
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, "Left click to select, right click to unselect");
|
||||
SendEditorMessage(this._client, "Press WALK+USE to confirm, DUCK+USE to 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;
|
||||
}
|
||||
|
||||
void End() {
|
||||
if(this.list == null) return;
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
PrintToServer("[Editor] Warn: Selector.End() called but no callback assigned, voiding list");
|
||||
}
|
||||
this.Reset();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/** 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) {
|
||||
PrintToServer("Selector.AddEntity: PRE CALLBACK");
|
||||
// FIXME: crashes server, sourcemod bug
|
||||
/*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");
|
||||
//FIXME: crashes server, sourcemod bug
|
||||
/*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;
|
||||
|
@ -144,14 +337,19 @@ enum struct PlayerPropData {
|
|||
int lastActiveTime;
|
||||
char classnameOverride[64];
|
||||
ChatPrompt chatPrompt;
|
||||
ArrayList markedProps;
|
||||
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.markedProps != null) delete this.markedProps;
|
||||
if(this.Selector.IsActive()) this.Selector.Cancel();
|
||||
this.chatPrompt = Prompt_None;
|
||||
this.clearListBuffer = false;
|
||||
this.lastCategoryIndex = 0;
|
||||
|
@ -161,6 +359,19 @@ enum struct PlayerPropData {
|
|||
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) {
|
||||
|
|
|
@ -8,6 +8,8 @@ public void OnAdminMenuReady(Handle topMenuHandle) {
|
|||
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;
|
||||
}
|
||||
|
@ -24,6 +26,15 @@ void Category_Handler(TopMenu topmenu, TopMenuAction action, TopMenuObject topob
|
|||
}
|
||||
}
|
||||
|
||||
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");
|
||||
|
@ -79,6 +90,14 @@ void AdminMenu_SaveLoad(TopMenu topmenu, TopMenuAction action, TopMenuObject obj
|
|||
}
|
||||
}
|
||||
|
||||
void AdminMenu_Manager(TopMenu topmenu, TopMenuAction action, TopMenuObject object_id, int param, char[] buffer, int maxlength) {
|
||||
if(action == TopMenuAction_DisplayOption) {
|
||||
Format(buffer, maxlength, "Manager (ALPHA)");
|
||||
} 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];
|
||||
|
@ -87,7 +106,7 @@ int SaveLoadMainMenuHandler(Menu menu, MenuAction action, int client, int param2
|
|||
ShowSaves(client, type);
|
||||
} else if (action == MenuAction_Cancel) {
|
||||
if(param2 == MenuCancel_ExitBack) {
|
||||
Spawn_ShowSaveLoadMainMenu(client);
|
||||
DisplayTopMenuCategory(g_topMenu, g_propSpawnerCategory, client);
|
||||
}
|
||||
} else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
|
@ -127,6 +146,7 @@ int SaveLoadSceneHandler(Menu menu, MenuAction action, int client, int param2) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SaveLoadSchematicHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
char saveName[64];
|
||||
|
@ -189,40 +209,160 @@ int SaveLoadConfirmHandler(Menu menu, MenuAction action, int client, int param2)
|
|||
delete menu;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DeleteHandler(Menu menu, MenuAction action, int client, int param2) {
|
||||
int ManagerHandler(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);
|
||||
if(index == -1) {
|
||||
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) {
|
||||
Spawn_ShowSaveLoadMainMenu(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");
|
||||
return 0;
|
||||
}
|
||||
if(StrEqual(info, "edit")) {
|
||||
Editor[client].ImportEntity(EntRefToEntIndex(ref), Edit_Manager);
|
||||
Spawn_ShowManagerMainMenu(client);
|
||||
} 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);
|
||||
}
|
||||
Spawn_ShowManagerMainMenu(client);
|
||||
} else if(StrEqual(info, "view")) {
|
||||
ReplyToCommand(client, "Maybe soon.");
|
||||
} else if(StrEqual(info, "select")) {
|
||||
ShowManagerSelectorMenu(client);
|
||||
int entity = EntRefToEntIndex(ref);
|
||||
g_PropData[client].Selector.AddEntity(entity);
|
||||
} else {
|
||||
SendEditorMessage(client, "Unknown option / not implemented");
|
||||
}
|
||||
} 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) {
|
||||
if(!EntitySelector.FromClient(client).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, "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")) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
g_PropData[client].Selector.End();
|
||||
Spawn_ShowManagerMainMenu(client);
|
||||
} else if(StrEqual(info, "save")) {
|
||||
// TODO: implement
|
||||
SendEditorMessage(client, "Not implemented");
|
||||
} else {
|
||||
SendEditorMessage(client, "Unknown option / not implemented");
|
||||
}
|
||||
} else if (action == MenuAction_Cancel) {
|
||||
if(param2 == MenuCancel_ExitBack) {
|
||||
Spawn_ShowSaveLoadMainMenu(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(index == -2) {
|
||||
} 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(index == -3) {
|
||||
if(g_PropData[client].markedProps != null) {
|
||||
EndDeleteTool(client, false);
|
||||
} 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].markedProps = new ArrayList();
|
||||
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 ref = g_spawnedItems.Get(index);
|
||||
// TODO: add delete confirm
|
||||
int index = g_spawnedItems.FindValue(ref);
|
||||
if(IsValidEntity(ref)) {
|
||||
RemoveEntity(ref);
|
||||
}
|
||||
g_spawnedItems.Erase(index);
|
||||
if(index > 0) {
|
||||
if(index > -1) {
|
||||
g_spawnedItems.Erase(index);
|
||||
index--;
|
||||
}
|
||||
} else { index = 0; }
|
||||
ShowDeleteList(client, index);
|
||||
}
|
||||
} else if (action == MenuAction_Cancel) {
|
||||
|
@ -317,16 +457,18 @@ int EditHandler(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);
|
||||
int ref = g_spawnedItems.Get(index);
|
||||
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.");
|
||||
g_spawnedItems.Erase(index);
|
||||
index--;
|
||||
if(index > -1) {
|
||||
g_spawnedItems.Erase(index);
|
||||
index--;
|
||||
} else { index = 0; }
|
||||
}
|
||||
ShowEditList(client, index);
|
||||
} else if (action == MenuAction_Cancel) {
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
/////////////
|
||||
void ShowSpawnRoot(int client) {
|
||||
Menu menu = new Menu(Spawn_RootHandler);
|
||||
menu.SetTitle("Choose list:");
|
||||
menu.AddItem("f", "Favorites (WIP)");
|
||||
menu.AddItem("r", "Recents");
|
||||
menu.AddItem("s", "Search");
|
||||
menu.AddItem("n", "Prop List");
|
||||
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);
|
||||
|
@ -17,6 +17,7 @@ void Spawn_ShowRecents(int client) {
|
|||
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");
|
||||
|
@ -26,6 +27,11 @@ void Spawn_ShowSearch(int client) {
|
|||
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");
|
||||
|
||||
|
@ -38,7 +44,7 @@ void ShowDeleteList(int client, int index = -3) {
|
|||
for(int i = 0; i < g_spawnedItems.Length; i++) {
|
||||
int ref = GetSpawnedItem(i);
|
||||
if(ref == -1) continue;
|
||||
IntToString(i, info, sizeof(info));
|
||||
Format(info, sizeof(info), "0|%d", ref);
|
||||
GetEntPropString(ref, Prop_Data, "m_ModelName", buffer, sizeof(buffer));
|
||||
index = FindCharInString(buffer, '/', true);
|
||||
if(index != -1)
|
||||
|
@ -52,6 +58,11 @@ void ShowDeleteList(int client, int index = -3) {
|
|||
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");
|
||||
|
||||
|
@ -60,7 +71,7 @@ void ShowEditList(int client, int index = 0) {
|
|||
for(int i = 0; i < g_spawnedItems.Length; i++) {
|
||||
int ref = GetSpawnedItem(i);
|
||||
if(ref == -1) continue;
|
||||
IntToString(i, info, sizeof(info));
|
||||
Format(info, sizeof(info), "%d", ref);
|
||||
GetEntPropString(ref, Prop_Data, "m_ModelName", buffer, sizeof(buffer));
|
||||
index = FindCharInString(buffer, '/', true);
|
||||
if(index != -1)
|
||||
|
@ -104,6 +115,8 @@ void _showItemMenu(int client, ArrayList items, const char[] title = "", bool cl
|
|||
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
|
||||
|
@ -194,6 +207,81 @@ void Spawn_ShowSaveLoadMainMenu(int client) {
|
|||
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");
|
||||
// menu.AddItem("select", "Select");
|
||||
menu.AddItem("save", "Save");
|
||||
menu.ExitBackButton = true;
|
||||
menu.ExitButton = true;
|
||||
menu.Display(client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
void ShowSaves(int client, SaveType type) {
|
||||
ArrayList saves;
|
||||
Menu newMenu;
|
||||
|
|
|
@ -378,9 +378,7 @@ ArrayList SearchItems(const char[] query) {
|
|||
SearchData data;
|
||||
for(int i = 0; i < results.Length; i++) {
|
||||
results.GetArray(i, data);
|
||||
PrintToConsoleAll("%d | data=\"%s\"", i, data.model);
|
||||
item.FromSearchData(data);
|
||||
PrintToConsoleAll("%d | item=\"%s\"", i, item.model);
|
||||
items.PushArray(item);
|
||||
}
|
||||
delete results;
|
||||
|
@ -446,26 +444,28 @@ bool RemoveSpawnedProp(int ref) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void EndDeleteTool(int client, bool deleteEntities = false) {
|
||||
if(g_PropData[client].markedProps != null) {
|
||||
int count;
|
||||
for(int i = 0; i < g_PropData[client].markedProps.Length; i++) {
|
||||
int ref = g_PropData[client].markedProps.Get(i);
|
||||
if(IsValidEntity(ref)) {
|
||||
count++;
|
||||
if(deleteEntities) {
|
||||
RemoveSpawnedProp(ref);
|
||||
RemoveEntity(ref);
|
||||
}
|
||||
else L4D2_RemoveEntityGlow(EntRefToEntIndex(ref));
|
||||
}
|
||||
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 g_PropData[client].markedProps;
|
||||
if(deleteEntities)
|
||||
PrintToChat(client, "\x04[Editor]\x01 \x05%d\x01 entities deleted", count);
|
||||
else
|
||||
PrintToChat(client, "\x04[Editor]\x01 Delete tool cancelled");
|
||||
}
|
||||
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");
|
||||
delete entities;
|
||||
}
|
||||
void OnManagerSelectorSelect(int client, int entity) {
|
||||
// update entity count
|
||||
ShowManagerSelectorMenu(client);
|
||||
}
|
||||
|
||||
int DeleteAll(int onlyPlayer = 0) {
|
||||
|
|
155
scripting/include/hats_editor.inc
Normal file
155
scripting/include/hats_editor.inc
Normal file
|
@ -0,0 +1,155 @@
|
|||
#if defined _editor_included_
|
||||
#endinput
|
||||
#endif
|
||||
#define _editor_included_
|
||||
|
||||
public SharedPlugin __pl_editor_ = {
|
||||
name = "editor",
|
||||
file = "hats.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_PLUGIN
|
||||
public void __pl_editor__SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("SpawnSchematic");
|
||||
MarkNativeAsOptional("StartEdit");
|
||||
MarkNativeAsOptional("StartSpawner");
|
||||
MarkNativeAsOptional("CancelEdit");
|
||||
MarkNativeAsOptional("IsEditorActive");
|
||||
|
||||
MarkNativeAsOptional("StartSelector");
|
||||
MarkNativeAsOptional("CancelSelector");
|
||||
MarkNativeAsOptional("IsSelectorActive");
|
||||
|
||||
MarkNativeAsOptional("Selector.Count.get");
|
||||
MarkNativeAsOptional("Selector.Active.get");
|
||||
MarkNativeAsOptional("Selector.Start");
|
||||
MarkNativeAsOptional("Selector.SetOnEnd");
|
||||
MarkNativeAsOptional("Selector.SetOnPreSelect");
|
||||
MarkNativeAsOptional("Selector.SetOnPostSelect");
|
||||
MarkNativeAsOptional("Selector.SetOnUnselect");
|
||||
MarkNativeAsOptional("Selector.AddEntity");
|
||||
MarkNativeAsOptional("Selector.RemoveEntity");
|
||||
MarkNativeAsOptional("Selector.Cancel");
|
||||
MarkNativeAsOptional("Selector.End");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
native bool SpawnSchematic(const char name[32], const float pos[3], const float angles[3] = NULL_VECTOR);
|
||||
|
||||
/** Called when edit is done or cancelled
|
||||
* @param client - client doing the edit
|
||||
* @param entity - The entity edited
|
||||
* @param result - Result of the edit, or cancelled
|
||||
* @return boolean - only for StartSpawner, true to continue, false to end spawning
|
||||
*/
|
||||
typeset EditorDoneCallback {
|
||||
function void (int client, int entity, CompleteType result);
|
||||
function bool (int client, int entity, CompleteType result);
|
||||
}
|
||||
|
||||
/** Called when an item is to be selected.
|
||||
* @return boolean - TRUE to allow item to be selected, FALSE to reject
|
||||
*/
|
||||
typedef SelectPreAddCallback = function bool (int client, int entity);
|
||||
/** Called when an item has been selected */
|
||||
typedef SelectPostAddCallback = function void (int client, int entity);
|
||||
|
||||
/** Called when an item is to be unselected. */
|
||||
typedef SelectRemoveCallback = function void (int client, int entity);
|
||||
/** Called when a user is done selecting items
|
||||
* @param client - client doing the selection
|
||||
* @param entities - if null, selection was cancelled. if not null, contains list of entity references, must be deleted.
|
||||
*/
|
||||
typedef SelectDoneCallback = function void (int client, ArrayList entities);
|
||||
|
||||
/** Starts editing an entity
|
||||
* @param client - The client that is editing
|
||||
* @param entity - The entity to edit
|
||||
* @param doneCallback - Called when edit is done
|
||||
*/
|
||||
native void StartEdit(int client, int entity, EditorDoneCallback doneCallback);
|
||||
/** Let client pick prop(s) to spawn
|
||||
* @param client - The client that is editing
|
||||
* @param entity - The entity to edit
|
||||
* @param doneCallback - Called when edit is done
|
||||
*/
|
||||
native void StartSpawner(int client, EditorDoneCallback doneCallback);
|
||||
native void CancelEdit(int client);
|
||||
// Includes non-plugin started edits
|
||||
native bool IsEditorActive(int client);
|
||||
|
||||
/** Starts a selection, where the client can click on entities to select or deselect them.
|
||||
* @param client - the client that can select
|
||||
* @param callback - called when user is done seleting or cancelled
|
||||
* @param highlightColor - the color to highlight selected items, default solid green
|
||||
* @param maxEntities - the max number of selections, 0 for infinite
|
||||
*/
|
||||
native void StartSelector(int client, SelectDoneCallback callback, int highlightColor[3] = { 0, 255, 0 }, int maxEntities = 0);
|
||||
|
||||
methodmap EntitySelector {
|
||||
public EntitySelector(int client) {
|
||||
return view_as<EntitySelector>(client);
|
||||
}
|
||||
|
||||
public static EntitySelector FromClient(int client) {
|
||||
return view_as<EntitySelector>(client);
|
||||
}
|
||||
|
||||
/** Starts a new selector for client
|
||||
* @param highlightColor - the color to highlight selected items, default solid green
|
||||
* @param flags - not used.
|
||||
* @param maxEntities - the max number of selections, 0 for infinite
|
||||
*/
|
||||
public native EntitySelector Start(int highlightColor[3], int flags = 0, int maxEntities = 0);
|
||||
|
||||
|
||||
property int Count {
|
||||
/** Returns the number of entities in selector. Returns -1 if not active */
|
||||
public native get();
|
||||
}
|
||||
|
||||
property bool Active {
|
||||
public native get();
|
||||
}
|
||||
|
||||
/** Sets the callback for when the selector is ended (or cancelled) */
|
||||
public native void SetOnEnd(SelectDoneCallback callback);
|
||||
|
||||
/** Sets the callback for when an item is to be added to the selector. */
|
||||
public native void SetOnPreSelect(SelectPreAddCallback callback);
|
||||
|
||||
/** Sets the callback for when an item has been added to the selector. */
|
||||
public native void SetOnPostSelect(SelectPostAddCallback callback);
|
||||
|
||||
/** Sets the callback for when an item is removed from selector. */
|
||||
public native void SetOnUnselect(SelectRemoveCallback callback);
|
||||
|
||||
/** Adds an entity to selection. Does not call SelectAddCallback */
|
||||
public native void AddEntity(int entity);
|
||||
|
||||
/** Removes an entity from selection. Does not call SelectAddCallback */
|
||||
public native void RemoveEntity(int entity);
|
||||
|
||||
public native void Cancel();
|
||||
|
||||
public native void End();
|
||||
}
|
||||
|
||||
|
||||
native void CancelSelector(int client);
|
||||
native bool IsSelectorActive(int client);
|
||||
|
||||
enum CompleteType {
|
||||
Complete_WallSuccess,
|
||||
Complete_WallError,
|
||||
Complete_PropSpawned,
|
||||
Complete_PropError,
|
||||
Complete_EditSuccess
|
||||
}
|
|
@ -2,21 +2,50 @@
|
|||
#endinput
|
||||
#endif
|
||||
#define _overlay_included
|
||||
#include <ripext>
|
||||
|
||||
native bool SendTempUI(int client, const char[] id, int lifetime, JSONObject element);
|
||||
public SharedPlugin __pl_overlay = {
|
||||
name = "overlay",
|
||||
file = "overlay.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
native bool ShowUI(int client, const char[] elemNamespace, const char[] elemId, JSONObject variables);
|
||||
#define ACTION_ARG_LENGTH 128 // The length each arg (separated by space) can be
|
||||
|
||||
native bool HideUI(int client, const char[] elemNamespace, const char[] elemId);
|
||||
// typedef ActionFallbackHandlerCallback = function void (const char[] actionName, const char[][] args, int numArgs);
|
||||
// typedef ActionHandlerCallback = function void (const char[][] args, int numArgs);
|
||||
typedef ActionFallbackHandlerCallback = function void (const char[] actionName, UIActionEvent event, int client);
|
||||
typedef ActionHandlerCallback = function void (UIActionEvent event, int client);
|
||||
|
||||
native bool PlayAudio(int client, const char[] url);
|
||||
|
||||
native bool IsOverlayConnected();
|
||||
|
||||
forward void OnUIAction(const char[] elemNamespace, const char[] elemId, const char[] action);
|
||||
// myplugin:action_name
|
||||
// Handles any action for actionNamespace and actionName
|
||||
native void RegisterActionHandler(const char[] actionNamespace, const char[] actionName, ActionFallbackHandlerCallback cb);
|
||||
// Handles all actions for namespace that were not caught by RegisterActionHandler
|
||||
native void RegisterActionAnyHandler(const char[] actionNamespace, ActionHandlerCallback cb);
|
||||
|
||||
typedef UIActionCallback = function void (const char[][] args, int numArgs);
|
||||
methodmap UIActionEvent {
|
||||
public UIActionEvent(ArrayList list) {
|
||||
return view_as<UIActionEvent>(list);
|
||||
}
|
||||
|
||||
public void GetArg(int argNum, char[] output, int maxlen) {
|
||||
view_as<ArrayList>(this).GetString(argNum, output, maxlen);
|
||||
}
|
||||
|
||||
public void _Delete() {
|
||||
delete view_as<ArrayList>(this);
|
||||
}
|
||||
|
||||
property int Args {
|
||||
public get() { return view_as<ArrayList>(this).Length; }
|
||||
}
|
||||
}
|
||||
|
||||
methodmap UIElement < JSONObject {
|
||||
public UIElement(const char[] elemNamespace, const char[] elemId) {
|
||||
|
@ -24,6 +53,7 @@ methodmap UIElement < JSONObject {
|
|||
obj.SetString("namespace", elemNamespace);
|
||||
obj.SetString("elem_id", elemId);
|
||||
obj.SetBool("visibility", false);
|
||||
obj.Set("steamids", new JSONArray());
|
||||
obj.Set("variables", new JSONObject());
|
||||
|
||||
return view_as<UIElement>(obj);
|
||||
|
@ -35,16 +65,6 @@ methodmap UIElement < JSONObject {
|
|||
}
|
||||
public set(bool value) {
|
||||
view_as<JSONObject>(this).SetBool("visibility", value);
|
||||
this.Send();
|
||||
}
|
||||
}
|
||||
|
||||
/** Is the UI element globally sent to all connected players?
|
||||
* Specify players with .AddClient() or clear with .ClearClients()
|
||||
*/
|
||||
property bool Global {
|
||||
public get() {
|
||||
return !view_as<JSONObject>(this).HasKey("steamids")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,35 +88,13 @@ methodmap UIElement < JSONObject {
|
|||
view_as<JSONObject>(this).SetBool(id, value);
|
||||
}
|
||||
|
||||
public void SetActionCallback(UIActionCallback callback) {}
|
||||
|
||||
public void AddClient(const char[] steamid) {
|
||||
// if(!IsClientInGame(client) || steamidCache[client][0] == '\0') ThrowError("Client %d is not connected, ingame, or authorized");
|
||||
JSONObject obj = view_as<JSONObject>(this);
|
||||
JSONArray steamids = view_as<JSONArray>(obj.Get("steamids"));
|
||||
if(steamids == null) {
|
||||
steamids = new JSONArray();
|
||||
obj.Set("steamids", steamids)
|
||||
public native bool SendAll();
|
||||
public native bool SendTo(int client);
|
||||
public bool SendToMultiple(int[] clientIds, int numClients) {
|
||||
for(int i = 0; i < numClients; i++) {
|
||||
this.SendTo(clientIds[i]);
|
||||
}
|
||||
steamids.PushString(steamid);
|
||||
}
|
||||
|
||||
public void ClearClients() {
|
||||
view_as<JSONObject>(this).Remove("steamids");
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
view_as<JSONObject>(this).Clear();
|
||||
}
|
||||
|
||||
public void Hide() {
|
||||
this.Visibility = false;
|
||||
}
|
||||
public void Show() {
|
||||
this.Visibility = true;
|
||||
}
|
||||
|
||||
public native bool Send();
|
||||
}
|
||||
|
||||
methodmap UIPosition < JSONObject {
|
||||
|
@ -118,6 +116,25 @@ methodmap UIPosition < JSONObject {
|
|||
}
|
||||
}
|
||||
|
||||
methodmap UISize < JSONObject {
|
||||
public UISize(int width, int height) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.SetInt("width", width);
|
||||
obj.SetInt("height", height);
|
||||
return view_as<UISize>(obj);
|
||||
}
|
||||
|
||||
property int Width {
|
||||
public get() { return view_as<JSONObject>(this).GetInt("width"); }
|
||||
public set(int value) { view_as<JSONObject>(this).SetInt("height", value); }
|
||||
}
|
||||
|
||||
property int Height {
|
||||
public get() { return view_as<JSONObject>(this).GetInt("height"); }
|
||||
public set(int value) { view_as<JSONObject>(this).SetInt("height", value); }
|
||||
}
|
||||
}
|
||||
|
||||
methodmap UIColor < JSONObject {
|
||||
/// Creates a new UIColor with RGB between 0-255, alpha is normalized 0.0-1.0
|
||||
public UIColor(int r = 255, int g = 255, int b = 255) {
|
||||
|
@ -168,11 +185,15 @@ methodmap TempUIElementDefaults < JSONObject {
|
|||
}
|
||||
property UIPosition Position {
|
||||
public get() { return view_as<UIPosition>(view_as<JSONObject>(this).Get("position")); }
|
||||
public set(UIPosition pos) { view_as<JSONObject>(this).Set("position", view_as<JSON>(pos)); }
|
||||
// public set(UIPosition pos) { view_as<JSONObject>(this).Set("position", view_as<JSON>(pos)); }
|
||||
}
|
||||
property UIColor BackgroundColor {
|
||||
public get() { return view_as<UIColor>(view_as<JSONObject>(this).Get("bgColor")); }
|
||||
public set(UIColor color) { view_as<JSONObject>(this).Set("bgColor", view_as<JSON>(color)); }
|
||||
// public set(UIColor color) { view_as<JSONObject>(this).Set("bgColor", view_as<JSON>(color)); }
|
||||
}
|
||||
property UISize Size {
|
||||
public get() { return view_as<UISize>(view_as<JSONObject>(this).Get("size")); }
|
||||
// public set(UISize size) { view_as<JSONObject>(this).Set("size", view_as<JSON>(size)); }
|
||||
}
|
||||
/// Returns or sets opacity, -1 is not set
|
||||
property int Opacity {
|
||||
|
@ -203,6 +224,7 @@ enum UIType {
|
|||
Element_Unknown = -1,
|
||||
Element_Text,
|
||||
Element_List,
|
||||
Element_Audio
|
||||
}
|
||||
enum UIFlags {
|
||||
Element_None
|
||||
|
@ -287,27 +309,29 @@ methodmap TempUI {
|
|||
public TempUI(const char[] elemId, const char[] type, int lifetime = 0) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.SetString("elem_id", elemId);
|
||||
obj.Set("steamids", new JSONArray());
|
||||
obj.SetInt("expires_seconds", 0);
|
||||
TempUIElement element = new TempUIElement(type);
|
||||
obj.Set("element", element);
|
||||
return view_as<TempUI>(obj);
|
||||
}
|
||||
|
||||
/// How long the temp UI lasts, 0 for never.
|
||||
property int Duration {
|
||||
public get() {
|
||||
return view_as<JSONObject>(this).GetInt("expires_seconds");
|
||||
}
|
||||
public set(int value) {
|
||||
view_as<JSONObject>(this).SetInt("expires_seconds", value);
|
||||
}
|
||||
}
|
||||
|
||||
property bool Visible {
|
||||
public get() {
|
||||
return view_as<JSONObject>(this).GetBool("visibility");
|
||||
}
|
||||
public set(bool value) {
|
||||
view_as<JSONObject>(this).SetBool("visibility", value);
|
||||
this.Send();
|
||||
}
|
||||
}
|
||||
|
||||
/** Is the UI element globally sent to all connected players?
|
||||
* Specify players with .AddClient() or clear with .ClearClients()
|
||||
*/
|
||||
property bool Global {
|
||||
public get() {
|
||||
return !view_as<JSONObject>(this).HasKey("steamids")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,38 +340,127 @@ methodmap TempUI {
|
|||
return view_as<TempUIElement>(view_as<JSONObject>(this).Get("element"));
|
||||
}
|
||||
public set(TempUIElement newElement) {
|
||||
// Delete old element
|
||||
JSON elem = view_as<JSONObject>(this).Get("element");
|
||||
if(elem != null) delete elem;
|
||||
|
||||
view_as<JSONObject>(this).Set("element", view_as<JSON>(newElement));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetActionCallback(UIActionCallback callback) {}
|
||||
|
||||
public void AddClient(const char[] steamid) {
|
||||
// if(!IsClientInGame(client) || steamidCache[client][0] == '\0') ThrowError("Client %d is not connected, ingame, or authorized");
|
||||
JSONObject obj = view_as<JSONObject>(this);
|
||||
JSONArray steamids = view_as<JSONArray>(obj.Get("steamids"));
|
||||
if(steamids == null) {
|
||||
steamids = new JSONArray();
|
||||
obj.Set("steamids", steamids)
|
||||
}
|
||||
steamids.PushString(steamid);
|
||||
}
|
||||
|
||||
public void ClearClients() {
|
||||
view_as<JSONObject>(this).Remove("steamids");
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
view_as<JSONObject>(this).Clear();
|
||||
}
|
||||
|
||||
public void Hide() {
|
||||
this.Visibility = false;
|
||||
public void Hide() {
|
||||
this.Visible = false;
|
||||
}
|
||||
public void Show() {
|
||||
this.Visibility = true;
|
||||
this.Visible = true;
|
||||
}
|
||||
|
||||
public native bool Send();
|
||||
public native bool SendAll();
|
||||
public native bool SendTo(int client);
|
||||
public bool SendToMultiple(int[] clientIds, int numClients) {
|
||||
for(int i = 0; i < numClients; i++) {
|
||||
this.SendTo(clientIds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
enum AudioState {
|
||||
// Audio stopped, reset to startTime
|
||||
Audio_Stopped,
|
||||
// Pauses audio at current time
|
||||
Audio_Paused,
|
||||
Audio_Play
|
||||
}
|
||||
|
||||
methodmap ClientList < JSONArray {
|
||||
public ClientList() {
|
||||
return view_as<ClientList>(new JSONArray());
|
||||
}
|
||||
|
||||
property int Length {
|
||||
public get() { return view_as<JSONArray>(this).Length; }
|
||||
}
|
||||
|
||||
public native void AddClient(int client);
|
||||
|
||||
public native bool HasClient(int client);
|
||||
|
||||
public void Clear() {
|
||||
view_as<JSONArray>(this).Clear();
|
||||
}
|
||||
}
|
||||
|
||||
methodmap AudioResource < JSONObject {
|
||||
public AudioResource(const char[] url, float volume = 0.5) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.SetString("source", url);
|
||||
obj.SetFloat("volume", volume);
|
||||
obj.SetInt("state", 0);
|
||||
obj.Set("steamids", new JSONArray());
|
||||
obj.SetBool("repeat", false)
|
||||
return view_as<AudioResource>(obj);
|
||||
}
|
||||
|
||||
property AudioState State {
|
||||
public get() {
|
||||
return view_as<AudioState>(view_as<JSONObject>(this).GetInt("state"));
|
||||
}
|
||||
public set(AudioState state) {
|
||||
view_as<JSONObject>(this).SetInt("state", view_as<int>(state));
|
||||
}
|
||||
}
|
||||
|
||||
property float Volume {
|
||||
public get() {
|
||||
return view_as<JSONObject>(this).GetFloat("volume");
|
||||
}
|
||||
public set(float volume) {
|
||||
view_as<JSONObject>(this).SetFloat("volume", volume);
|
||||
}
|
||||
}
|
||||
|
||||
property bool Repeat {
|
||||
public get() {
|
||||
return view_as<JSONObject>(this).GetBool("repeat");
|
||||
}
|
||||
public set(bool repeat) {
|
||||
view_as<JSONObject>(this).SetBool("repeat", repeat);
|
||||
}
|
||||
}
|
||||
|
||||
property ClientList Clients {
|
||||
public get() {
|
||||
return view_as<ClientList>(view_as<JSONObject>(this).Get("steamids"));
|
||||
}
|
||||
}
|
||||
/// Plays or resumes playing
|
||||
public native void Play();
|
||||
/// Stops playing audio, clients will reset to beginning
|
||||
public native void Stop();
|
||||
/// Pauses audio, resuming to current play duration
|
||||
public native void Pause();
|
||||
|
||||
public void Clear() {
|
||||
view_as<JSONObject>(this).Clear();
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined REQUIRE_PLUGIN
|
||||
public void __pl_overlay_SetNTVOptional() {
|
||||
MarkNativeAsOptional("IsOverlayConnected");
|
||||
MarkNativeAsOptional("RegisterActionAnyHandler");
|
||||
MarkNativeAsOptional("RegisterActionHandler");
|
||||
|
||||
MarkNativeAsOptional("UIElement.SendAll");
|
||||
MarkNativeAsOptional("UIElement.SendTo");
|
||||
MarkNativeAsOptional("TempUI.SendAll");
|
||||
MarkNativeAsOptional("TempUI.SendTo");
|
||||
MarkNativeAsOptional("AudioResource.Play");
|
||||
MarkNativeAsOptional("AudioResource.Stop");
|
||||
MarkNativeAsOptional("AudioResource.Pause");
|
||||
}
|
||||
#endif
|
135
scripting/include/randomizer/rbuild.sp
Normal file
135
scripting/include/randomizer/rbuild.sp
Normal file
|
@ -0,0 +1,135 @@
|
|||
/// MENUS
|
||||
public void OpenMainMenu(int client) {
|
||||
Menu menu = new Menu(BuilderHandler_MainMenu);
|
||||
menu.SetTitle("Randomizer Builder");
|
||||
if(g_builder.mapData == null) {
|
||||
menu.AddItem("load", "Load Map Data");
|
||||
menu.AddItem("new", "New Map Data");
|
||||
} else {
|
||||
menu.AddItem("save", "Save Map Data");
|
||||
menu.AddItem("selector", "Start Selector");
|
||||
menu.AddItem("spawner", "Start Spawner");
|
||||
menu.AddItem("cursor", "Add Entity At Cursor");
|
||||
menu.AddItem("scenes", "Scenes");
|
||||
}
|
||||
menu.Display(client, 0);
|
||||
}
|
||||
|
||||
void OpenScenesMenu(int client) {
|
||||
Menu menu = new Menu(BuilderHandler_ScenesMenu);
|
||||
menu.SetTitle("Select a scene");
|
||||
char id[64], display[32];
|
||||
JSONObjectKeys iterator = g_builder.mapData.Keys();
|
||||
while(iterator.ReadKey(id, sizeof(id))) {
|
||||
if(StrEqual(id, g_builder.selectedSceneId)) {
|
||||
Format(display, sizeof(display), "%s (selected)", id);
|
||||
} else {
|
||||
Format(display, sizeof(display), "%s", id);
|
||||
}
|
||||
menu.AddItem(id, display);
|
||||
}
|
||||
menu.Display(client, 0);
|
||||
}
|
||||
|
||||
void OpenVariantsMenu(int client) {
|
||||
Menu menu = new Menu(BuilderHandler_VariantsMenu);
|
||||
menu.SetTitle("%s > Variants", g_builder.selectedSceneId);
|
||||
char id[8], display[32];
|
||||
menu.AddItem("new", "New");
|
||||
menu.AddItem("-1", "None (Shared Scene)");
|
||||
|
||||
JSONArray variants = view_as<JSONArray>(g_builder.selectedSceneData.Get("variants"));
|
||||
JSONObject varObj;
|
||||
JSONArray entities;
|
||||
for(int i = 0; i < variants.Length; i++) {
|
||||
varObj = view_as<JSONObject>(variants.Get(i));
|
||||
entities = view_as<JSONArray>(varObj.Get("entities"));
|
||||
if(i == g_builder.selectedVariantIndex) {
|
||||
Format(display, sizeof(display), "%d entities (selected)", entities.Length);
|
||||
} else {
|
||||
Format(display, sizeof(display), "%d entities", entities.Length);
|
||||
}
|
||||
IntToString(i, id, sizeof(id));
|
||||
menu.AddItem(id, display);
|
||||
}
|
||||
menu.Display(client, 0);
|
||||
}
|
||||
|
||||
/// HANDLERS
|
||||
|
||||
int BuilderHandler_MainMenu(Menu menu, MenuAction action, int client, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
char info[32];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
if(StrEqual(info, "new")) {
|
||||
JSONObject temp = LoadMapJson(currentMap);
|
||||
GetCmdArg(2, info, sizeof(info));
|
||||
if(temp != null) {
|
||||
Menu nMenu = new Menu(BuilderHandler_MainMenu);
|
||||
nMenu.SetTitle("Existing map data exists");
|
||||
nMenu.AddItem("new_confirm", "Overwrite");
|
||||
nMenu.Display(client, 0);
|
||||
delete temp;
|
||||
return 0;
|
||||
} else {
|
||||
FakeClientCommand(client, "sm_rbuild new");
|
||||
}
|
||||
} else if(StrEqual(info, "new_confirm")) {
|
||||
FakeClientCommand(client, "sm_rbuild new confirm");
|
||||
} else if(StrEqual(info, "scenes")) {
|
||||
OpenScenesMenu(client);
|
||||
return 0;
|
||||
} else {
|
||||
FakeClientCommand(client, "sm_rbuild %s", info);
|
||||
} /*else if(StrEqual(info, "cursor")) {
|
||||
Menu menu = new Menu(BuilderHandler_)
|
||||
}*/
|
||||
OpenMainMenu(client);
|
||||
} else if(action == MenuAction_Cancel) {
|
||||
if(param2 == MenuCancel_ExitBack) {
|
||||
}
|
||||
} else if (action == MenuAction_End) {
|
||||
delete menu;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BuilderHandler_ScenesMenu(Menu menu, MenuAction action, int client, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
char info[64];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
if(StrEqual(info, "new")) {
|
||||
FakeClientCommand(client, "sm_rbuild scenes new");
|
||||
OpenScenesMenu(client);
|
||||
} else {
|
||||
FakeClientCommand(client, "sm_rbuild scenes select %s", info);
|
||||
OpenVariantsMenu(client);
|
||||
}
|
||||
} else if(action == MenuAction_Cancel) {
|
||||
if(param2 == MenuCancel_ExitBack) {
|
||||
}
|
||||
} else if (action == MenuAction_End) {
|
||||
delete menu;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BuilderHandler_VariantsMenu(Menu menu, MenuAction action, int client, int param2) {
|
||||
if (action == MenuAction_Select) {
|
||||
char info[64];
|
||||
menu.GetItem(param2, info, sizeof(info));
|
||||
if(StrEqual(info, "new")) {
|
||||
FakeClientCommand(client, "sm_rbuild scenes variants new");
|
||||
} else {
|
||||
FakeClientCommand(client, "sm_rbuild scenes variants select %s", info);
|
||||
}
|
||||
OpenVariantsMenu(client);
|
||||
} else if(action == MenuAction_Cancel) {
|
||||
if(param2 == MenuCancel_ExitBack) {
|
||||
}
|
||||
} else if (action == MenuAction_End) {
|
||||
delete menu;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue