mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-05 18:33:21 +00:00
Random changes hope they work
This commit is contained in:
parent
9007092afd
commit
ccc68b9935
16 changed files with 431 additions and 227 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -5,14 +5,12 @@
|
|||
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
|
||||
#define PRECACHE_SOUNDS_COUNT 6
|
||||
#define PRECACHE_SOUNDS_COUNT 4
|
||||
char PRECACHE_SOUNDS[PRECACHE_SOUNDS_COUNT][] = {
|
||||
"custom/meow1.mp3",
|
||||
"custom/xen_teleport.mp3",
|
||||
"custom/mariokartmusic.mp3",
|
||||
"custom/spookyscaryskeletons.mp3",
|
||||
"custom/wearenumberone2.mp3",
|
||||
"custom/quack.mp3"
|
||||
};
|
||||
|
||||
#include <sourcemod>
|
||||
|
@ -101,7 +99,7 @@ public void OnPluginStart() {
|
|||
if(hSVMaxPlayers != null) {
|
||||
hPlayerLimit = CreateConVar("sm_player_limit", "0", "Overrides sv_maxplayers. 0 = off, > 0: limit", FCVAR_NONE, true, 0.0, false);
|
||||
hPlayerLimit.AddChangeHook(Event_PlayerLimitChange);
|
||||
hSVMaxPlayers.IntValue = hPlayerLimit.IntValue;
|
||||
if(hPlayerLimit.IntValue > 0) hSVMaxPlayers.IntValue = hPlayerLimit.IntValue;
|
||||
}
|
||||
|
||||
hFFNotice.AddChangeHook(CVC_FFNotice);
|
||||
|
|
|
@ -9,7 +9,8 @@ public void OnMapStart() {
|
|||
PrecacheSound("custom/meow1.mp3");
|
||||
AddFileToDownloadsTable("sound/custom/woof1.mp3");
|
||||
PrecacheSound("custom/woof1.mp3");
|
||||
|
||||
AddFileToDownloadsTable("sound/custom/quack.mp3");
|
||||
PrecacheSound("custom/quack.mp3");
|
||||
|
||||
lastButtonUser = -1;
|
||||
HookEntityOutput("func_button", "OnPressed", Event_ButtonPress);
|
||||
|
@ -919,7 +920,7 @@ public Action SoundHook(int clients[MAXPLAYERS], int& numClients, char sample[PL
|
|||
strcopy(sample, sizeof(sample), "player/footsteps/clown/concrete1.wav");
|
||||
} else if(trollFlags & 2) {
|
||||
strcopy(sample, sizeof(sample), "custom/quack.mp3");
|
||||
// volume += 0.2;
|
||||
volume = 1.0;
|
||||
} else if(trollFlags & 4) {
|
||||
strcopy(sample, sizeof(sample), "custom/meow1.mp3");
|
||||
volume += 0.2;
|
||||
|
|
|
@ -211,7 +211,7 @@ enum struct EditorData {
|
|||
}
|
||||
|
||||
void CycleStacker(float tick) {
|
||||
if(tick - cmdThrottle[this.client] <= 0.20) return;
|
||||
if(tick - cmdThrottle[this.client] <= 0.10) return;
|
||||
int newDirection = view_as<int>(this.stackerDirection) + 1;
|
||||
if(newDirection == view_as<int>(Stack_Down)) newDirection = 0;
|
||||
this.stackerDirection = view_as<StackerDirection>(newDirection);
|
||||
|
@ -334,8 +334,10 @@ enum struct EditorData {
|
|||
return 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;
|
||||
}
|
||||
}
|
||||
|
@ -384,6 +386,7 @@ enum struct EditorData {
|
|||
this.Reset();
|
||||
if(!isEdit) {
|
||||
id = createdWalls.Push(EntIndexToEntRef(blocker));
|
||||
PrintToChat(this.client, "\x04[Editor]\x01 Created wall \x05#%d\x01.", id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -430,7 +433,8 @@ enum struct EditorData {
|
|||
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;
|
||||
}
|
||||
|
@ -606,7 +610,8 @@ enum struct EditorData {
|
|||
TeleportEntity(this.entity, this.prevOrigin, this.prevAngles, NULL_VECTOR);
|
||||
}
|
||||
this.SetMode(INACTIVE);
|
||||
CPrintToChat(this.client, "\x04[Editor]\x01 Cancelled.");
|
||||
PrintHintText(this.client, "Cancelled");
|
||||
// CPrintToChat(this.client, "\x04[Editor]\x01 Cancelled.");
|
||||
}
|
||||
}
|
||||
EditorData Editor[MAXPLAYERS+1];
|
||||
|
|
|
@ -372,7 +372,7 @@ Action Command_DoAHat(int client, int args) {
|
|||
if(IsFakeClient(entity) && L4D_GetIdlePlayerOfBot(entity) > 0) {
|
||||
PrintToChat(client, "[Hats] Cannot hat idle bots");
|
||||
return Plugin_Handled;
|
||||
} else if(GetClientTeam(entity) != 2 && ~cvar_sm_hats_flags.IntValue & view_as<int>(HatConfig_InfectedHats)) {
|
||||
} else if(!isForced && GetClientTeam(entity) != 2 && ~cvar_sm_hats_flags.IntValue & view_as<int>(HatConfig_InfectedHats)) {
|
||||
PrintToChat(client, "[Hats] Cannot make enemy a hat... it's dangerous");
|
||||
return Plugin_Handled;
|
||||
} else if(entity == EntRefToEntIndex(Editor[client].entity)) {
|
||||
|
@ -747,7 +747,11 @@ void EquipHat(int client, int entity, const char[] classname = "", int flags = H
|
|||
} else {
|
||||
float mins[3];
|
||||
GetEntPropVector(modifyEntity, Prop_Send, "m_vecMins", mins);
|
||||
hatData[client].offset[2] += mins[2];
|
||||
if(StrContains(classname, "weapon_molotov") > -1 || StrContains(classname, "weapon_pipe_bomb") > -1 || StrContains(classname, "weapon_vomitjar") > -1) {
|
||||
hatData[client].offset[2] += 7.2;
|
||||
} else {
|
||||
hatData[client].offset[2] += mins[2];
|
||||
}
|
||||
}
|
||||
|
||||
if(cvar_sm_hats_flags.IntValue & view_as<int>(HatConfig_ReversedHats) && flags & view_as<int>(HAT_REVERSED)) {
|
||||
|
|
|
@ -20,6 +20,21 @@ public Action Command_HideAndSeek(int client, int args) {
|
|||
ReplyToCommand(client, "Error occurred while reloading map file");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
} else if(StrEqual(subcmd, "state")) {
|
||||
int state = GetCmdArgInt(2);
|
||||
if(state < 0 || state > view_as<int>(State_Hunting)) {
|
||||
ReplyToCommand(client, "Invalid state. 0 to %d", view_as<int>(State_Hunting));
|
||||
} else {
|
||||
if(SetState(view_as<GameState>(state))) {
|
||||
ReplyToCommand(client, "State set to %s (%d)", GAME_STATE_DEBUG[state],state);
|
||||
if(view_as<GameState>(state) == State_Startup) {
|
||||
StartWaiting();
|
||||
}
|
||||
} else {
|
||||
ReplyToCommand(client, "Game not active");
|
||||
}
|
||||
}
|
||||
return Plugin_Handled;
|
||||
} else if(StrEqual(subcmd, "set", false)) {
|
||||
char set[16];
|
||||
if(args == 1) {
|
||||
|
@ -207,29 +222,6 @@ public Action Command_HideAndSeek(int client, int args) {
|
|||
} else if(StrEqual(subcmd, "stuck")) {
|
||||
TeleportEntity(client, mapConfig.spawnpoint, NULL_VECTOR, NULL_VECTOR);
|
||||
return Plugin_Handled;
|
||||
} else if(StrEqual(subcmd, "bots")) {
|
||||
if(args == 2) {
|
||||
char arg[16];
|
||||
GetCmdArg(2, arg, sizeof(arg));
|
||||
if(StrEqual(arg, "toggle")) {
|
||||
bool newValue = !IsBotsEnabled();
|
||||
SetBotsEnabled(newValue);
|
||||
if(newValue) ReplyToCommand(client, "Bots are now enabled");
|
||||
else ReplyToCommand(client, "Bots are now disabled");
|
||||
return Plugin_Handled;
|
||||
} else if(StrEqual(arg, "on") || StrEqual(arg, "true")) {
|
||||
SetBotsEnabled(true);
|
||||
ReplyToCommand(client, "Bots are now enabled");
|
||||
return Plugin_Handled;
|
||||
} else if(StrEqual(arg, "off") || StrEqual(arg, "false")) {
|
||||
SetBotsEnabled(false);
|
||||
ReplyToCommand(client, "Bots are now disabled");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
if(IsBotsEnabled()) ReplyToCommand(client, "Bots are enabled");
|
||||
else ReplyToCommand(client, "Bots are disabled");
|
||||
return Plugin_Handled;
|
||||
} else if(StrEqual(subcmd, "peekfix")) {
|
||||
if(!PeekCam.Exists()) {
|
||||
PeekCam.Target = client;
|
||||
|
@ -272,21 +264,21 @@ public Action Command_HideAndSeek(int client, int args) {
|
|||
}
|
||||
return Plugin_Handled;
|
||||
} else if(StrEqual(subcmd, "debug")) {
|
||||
ReplyToCommand(client, "- Game Info -");
|
||||
int addSlasher = GetSlasher();
|
||||
ReplyToCommand(client, "Current seeker: %N(%d) (addon says %N(%d))", currentSeeker, currentSeeker, addSlasher, addSlasher);
|
||||
ReplyToCommand(client, "State: %d | Tick: %d", view_as<int>(GetState()), GetTick());
|
||||
int mutationSlasher = GetSlasher();
|
||||
CReplyToCommand(client, "Current seeker: \x04%N(%d)", currentSeeker, currentSeeker);
|
||||
CReplyToCommand(client, "\tMutation Says: \x04%N(%d)", mutationSlasher, mutationSlasher);
|
||||
int state = view_as<int>(GetState());
|
||||
CReplyToCommand(client, "State: \x04%s(%d)\x01 | Tick: \x04%d\x01", GAME_STATE_DEBUG[state], state, GetTick());
|
||||
|
||||
ReplyToCommand(client, "- Map Info -");
|
||||
ReplyToCommand(client, "Map: %s (set %s)", g_currentMap, g_currentSet);
|
||||
CReplyToCommand(client, "Map: \x04%s\x01/\x05%s", g_currentMap, g_currentSet);
|
||||
if(mapConfig.hasSpawnpoint)
|
||||
ReplyToCommand(client, "Has Spawnpoint: yes (%f %f %f)", mapConfig.spawnpoint[0], mapConfig.spawnpoint[1], mapConfig.spawnpoint[2]);
|
||||
CReplyToCommand(client, "Has Spawnpoint: \x04yes\x01 (\x05%.1f %.1f %.1f\x01)", mapConfig.spawnpoint[0], mapConfig.spawnpoint[1], mapConfig.spawnpoint[2]);
|
||||
else
|
||||
ReplyToCommand(client, "Has Spawnpoint: no (possibly map spawn %f %f %f)", mapConfig.spawnpoint[0], mapConfig.spawnpoint[1], mapConfig.spawnpoint[2]);
|
||||
ReplyToCommand(client, "Climbing: %b", mapConfig.canClimb);
|
||||
ReplyToCommand(client, "Buttons Auto-press: %b", mapConfig.pressButtons);
|
||||
ReplyToCommand(client, "Map Time Override: %d", mapConfig.mapTime);
|
||||
ReplyToCommand(client, "Your travel distance: %f", distanceTraveled[client]);
|
||||
CReplyToCommand(client, "Has Spawnpoint: \x04no (possibly map spawn \x05%.1f %.1f %.1f\x01)", mapConfig.spawnpoint[0], mapConfig.spawnpoint[1], mapConfig.spawnpoint[2]);
|
||||
CReplyToCommand(client, "Climbing: \x04%b", mapConfig.canClimb);
|
||||
CReplyToCommand(client, "Buttons Auto-press: \x04%b", mapConfig.pressButtons);
|
||||
CReplyToCommand(client, "Map Time Override: \x04%d", mapConfig.mapTime);
|
||||
CReplyToCommand(client, "Your travel distance: \x04%f", distanceTraveled[client]);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
ReplyToCommand(client, "Unknown command");
|
||||
|
@ -303,7 +295,6 @@ public Action Command_HideAndSeek(int client, int args) {
|
|||
ReplyToCommand(client, "- Admin Commands -");
|
||||
ReplyToCommand(client, "set [new set]: Change the prop set or view current");
|
||||
ReplyToCommand(client, "setspawn: Sets the temporary spawnpoint for the map");
|
||||
ReplyToCommand(client, "bots [toggle, [value]]: View if bots are enabled, or turn them on");
|
||||
ReplyToCommand(client, "peekfix - Clear peek camera from all players");
|
||||
ReplyToCommand(client, "seeker [new seeker]: Get the active seeker, or set a new one.");
|
||||
ReplyToCommand(client, "sm_cvar hs_peekcam <0/2> - Turn the peek camera on or off");
|
||||
|
|
|
@ -183,22 +183,6 @@ bool IsGameSoloOrPlayersLoading() {
|
|||
return connecting > 0 || ingame == 1;
|
||||
}
|
||||
|
||||
//cm_NoSurvivorBots
|
||||
bool SetBotsEnabled(bool value) {
|
||||
static char buffer[64];
|
||||
if(value)
|
||||
Format(buffer, sizeof(buffer), "g_ModeScript.MutationOptions.cm_NoSurvivorBots = true");
|
||||
else
|
||||
Format(buffer, sizeof(buffer), "g_ModeScript.MutationOptions.cm_NoSurvivorBots = false");
|
||||
return L4D2_ExecVScriptCode(buffer);
|
||||
}
|
||||
|
||||
bool IsBotsEnabled() {
|
||||
static char result[8];
|
||||
L4D2_GetVScriptOutput("g_ModeScript.MutationState.cm_NoSurvivorBots", result, sizeof(result));
|
||||
return StrEqual(result, "true", false);
|
||||
}
|
||||
|
||||
stock void GetHorizontalPositionFromClient(int client, float units, float finalPosition[3]) {
|
||||
float pos[3], ang[3];
|
||||
GetClientEyeAngles(client, ang);
|
||||
|
|
|
@ -12,13 +12,15 @@ enum SocketType {
|
|||
SOCKET_RAW
|
||||
}
|
||||
|
||||
#define EMPTY_HOST 1
|
||||
#define NO_HOST 2
|
||||
#define CONNECT_ERROR 3
|
||||
#define SEND_ERROR 4
|
||||
#define BIND_ERROR 5
|
||||
#define RECV_ERROR 6
|
||||
#define LISTEN_ERROR 7
|
||||
enum {
|
||||
EMPTY_HOST = 1,
|
||||
NO_HOST,
|
||||
CONNECT_ERROR,
|
||||
SEND_ERROR,
|
||||
BIND_ERROR,
|
||||
RECV_ERROR,
|
||||
LISTEN_ERROR
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
@ -45,7 +47,7 @@ enum SocketOption {
|
|||
* @note don't forget to set your buffer sizes at least to the value passed to this function, but
|
||||
* always at least to 4096
|
||||
*
|
||||
* @param cell_t 0(=default) to disable or max. chunk size including \0 terminator in bytes
|
||||
* @param int 0(=default) to disable or max. chunk size including \0 terminator in bytes
|
||||
* @return bool true on success
|
||||
*/
|
||||
ConcatenateCallbacks = 1,
|
||||
|
@ -73,7 +75,7 @@ enum SocketOption {
|
|||
*
|
||||
* @note this option will affect all sockets from all plugins, use it with caution!
|
||||
*
|
||||
* @param cell_t maximum amount of callbacks per gameframe
|
||||
* @param int maximum amount of callbacks per gameframe
|
||||
* @return bool true on success
|
||||
*/
|
||||
CallbacksPerFrame,
|
||||
|
@ -105,7 +107,7 @@ enum SocketOption {
|
|||
* This option specifies how long a socket will wait if it's being closed and its send buffer is
|
||||
* still filled. This is a wrapper for setting SO_LINGER.
|
||||
*
|
||||
* @param cell_t 0 (=default) to disable or time in s
|
||||
* @param int 0 (=default) to disable or time in s
|
||||
* @return bool true on success
|
||||
*/
|
||||
SocketLinger,
|
||||
|
@ -121,7 +123,7 @@ enum SocketOption {
|
|||
* This option specifies how large the send buffer will be. This is a wrapper for setting
|
||||
* SO_SNDBUF.
|
||||
*
|
||||
* @param cell_t size in bytes
|
||||
* @param int size in bytes
|
||||
* @return bool true on success
|
||||
*/
|
||||
SocketSendBuffer,
|
||||
|
@ -129,7 +131,7 @@ enum SocketOption {
|
|||
* This option specifies how large the receive buffer will be. This is a wrapper for setting
|
||||
* SO_RCVBUF.
|
||||
*
|
||||
* @param cell_t size in bytes
|
||||
* @param int size in bytes
|
||||
* @return bool true on success
|
||||
*/
|
||||
SocketReceiveBuffer,
|
||||
|
@ -148,7 +150,7 @@ enum SocketOption {
|
|||
*
|
||||
* @note this can probably block the extension, use it with caution!
|
||||
*
|
||||
* @param cell_t size in bytes
|
||||
* @param int size in bytes
|
||||
* @return bool true on success
|
||||
*/
|
||||
SocketReceiveLowWatermark,
|
||||
|
@ -156,7 +158,7 @@ enum SocketOption {
|
|||
* This option specifies how long a socket will try to receive data before it times out and
|
||||
* processes the data. This is a wrapper for setting SO_RCVTIMEO.
|
||||
*
|
||||
* @param cell_t 0 (=default) to disable or time in ms
|
||||
* @param int 0 (=default) to disable or time in ms
|
||||
* @return bool true on success
|
||||
*/
|
||||
SocketReceiveTimeout,
|
||||
|
@ -166,7 +168,7 @@ enum SocketOption {
|
|||
*
|
||||
* @note this can probably block the extension, use it with caution!
|
||||
*
|
||||
* @param cell_t size in bytes
|
||||
* @param int size in bytes
|
||||
* @return bool true on success
|
||||
*/
|
||||
SocketSendLowWatermark,
|
||||
|
@ -174,7 +176,7 @@ enum SocketOption {
|
|||
* This option specifies how long a socket will try to send data before it times out and
|
||||
* retries it later. This is a wrapper for setting SO_SNDTIMEO.
|
||||
*
|
||||
* @param cell_t 0 (=default) to disable or time in ms
|
||||
* @param int 0 (=default) to disable or time in ms
|
||||
* @return bool true on success
|
||||
*/
|
||||
SocketSendTimeout,
|
||||
|
@ -187,12 +189,173 @@ enum SocketOption {
|
|||
DebugMode
|
||||
}
|
||||
|
||||
// Methodmap
|
||||
methodmap Socket < Handle {
|
||||
/**
|
||||
* Creates a new socket.
|
||||
*
|
||||
* @note this function may be relatively expensive, reuse sockets if possible
|
||||
*
|
||||
* @param SocketType protocol The protocol to use, SOCKET_TCP is default
|
||||
* @param SocketErrorCB efunc The error callback
|
||||
* @return Handle The socket handle. Returns INVALID_HANDLE on failure
|
||||
*/
|
||||
public native Socket(SocketType protocol=SOCKET_TCP, SocketErrorCB efunc);
|
||||
|
||||
/**
|
||||
* Binds the socket to a local address
|
||||
*
|
||||
* @param String hostname The hostname (or IP) to bind the socket to.
|
||||
* @param int port The port to bind the socket to.
|
||||
* @return bool true on success
|
||||
*/
|
||||
public native bool Bind(const char[] hostname, int port);
|
||||
|
||||
/**
|
||||
* Connects a socket
|
||||
*
|
||||
* @note this native is threaded, it may be still running after it executed, use the connect callback
|
||||
* @note invokes the SocketError callback with errorType = CONNECT_ERROR or EMPTY_HOST if it fails
|
||||
* @note invokes the SocketConnect callback if it succeeds
|
||||
*
|
||||
* @param SocketConnectCB cfunc The connect callback
|
||||
* @param SocketReceiveCB rfunc The receive callback
|
||||
* @param SocketDisconnectCB dfunc The disconnect callback
|
||||
* @param String hostname The hostname (or IP) to connect to.
|
||||
* @param int port The port to connect to.
|
||||
*/
|
||||
public native void Connect(SocketConnectCB cfunc, SocketReceiveCB rfunc, SocketDisconnectCB dfunc, const char[] hostname, int port);
|
||||
|
||||
/**
|
||||
* Disconnects a socket
|
||||
*
|
||||
* @note this will not close the handle, the socket will be reset to a state similar to after SocketCreate()
|
||||
* @note this won't trigger any disconnect/error callbacks
|
||||
*
|
||||
* @return bool true on success
|
||||
*/
|
||||
public native bool Disconnect();
|
||||
|
||||
/**
|
||||
* Makes a socket listen for incoming connections
|
||||
*
|
||||
* @param SocketIncomingCB ifunc The callback for incoming connections
|
||||
* @return bool true on success
|
||||
*/
|
||||
public native bool Listen(SocketIncomingCB ifunc);
|
||||
|
||||
/**
|
||||
* Sends data through the socket.
|
||||
*
|
||||
* @note specify size for binary safe operation
|
||||
* @note if size is not specified the \0 terminator will not be included
|
||||
* @note This native is threaded, it may be still running after it executed (not atomic).
|
||||
* @note Use the SendqueueEmpty callback to determine when all data has been successfully sent.
|
||||
* @note The socket extension will ensure that the data will be send in the correct order and split
|
||||
* the data if required.
|
||||
*
|
||||
* @param String data The data to send.
|
||||
*/
|
||||
public native void Send(const char[] data, int size = -1);
|
||||
|
||||
/**
|
||||
* Sends UDP data through the socket to a specific destination.
|
||||
*
|
||||
* @note specify size for binary safe operation
|
||||
* @note if size is not specified the \0 terminator will not be included
|
||||
* @note This native is threaded, it may be still running after it executed (not atomic).
|
||||
* @note Use the SendqueueEmpty callback to determine when all data has been successfully sent.
|
||||
* @note The socket extension will ensure that the data will be send in the correct order and split
|
||||
* the data if required.
|
||||
*
|
||||
* @param String data The data to send.
|
||||
* @param String hostname The hostname (or IP) to send to.
|
||||
* @param int port The port to send to.
|
||||
*/
|
||||
public native void SendTo(const char[] data, int size = -1, const char[] hostname, int port);
|
||||
|
||||
/**
|
||||
* Set a socket option.
|
||||
*
|
||||
* @param SocketOption option The option to modify (see enum SocketOption for details).
|
||||
* @param int value The value to set the option to.
|
||||
* @return int 1 on success.
|
||||
*/
|
||||
public native int SetOption(SocketOption option, int value);
|
||||
|
||||
/**
|
||||
* Defines the callback function for when the socket receives data
|
||||
*
|
||||
* @note this is only useful and required for child-sockets spawned by listen-sockets
|
||||
* (otherwise you already set it in SocketConnect())
|
||||
*
|
||||
* @param SocketReceiveCB rfunc The receive callback
|
||||
*/
|
||||
public native void SetReceiveCallback(SocketReceiveCB rfunc);
|
||||
|
||||
/**
|
||||
* Defines the callback function for when the socket sent all items in its send queue
|
||||
*
|
||||
* @note this must be called AFTER sending (queueing) the data
|
||||
* @note if no send-data is queued this will fire the callback itself
|
||||
* @note the callback is guaranteed to fire
|
||||
*
|
||||
* @param SocketDisconnectCB dfunc The disconnect callback
|
||||
*/
|
||||
public native void SetSendqueueEmptyCallback(SocketSendqueueEmptyCB sfunc);
|
||||
|
||||
/**
|
||||
* Defines the callback function for when the socket was properly disconnected by the remote side
|
||||
*
|
||||
* @note this is only useful and required for child-sockets spawned by listen-sockets
|
||||
* (otherwise you already set it in SocketConnect())
|
||||
*
|
||||
* @param SocketDisconnectCB dfunc The disconnect callback
|
||||
*/
|
||||
public native void SetDisconnectCallback(SocketDisconnectCB dfunc);
|
||||
|
||||
/**
|
||||
* Defines the callback function for when the socket triggered an error
|
||||
*
|
||||
* @note this is only useful and required for child-sockets spawned by listen-sockets
|
||||
* (otherwise you already set it in SocketCreate())
|
||||
*
|
||||
* @param SocketErrorCB efunc The error callback
|
||||
*/
|
||||
public native void SetErrorCallback(SocketErrorCB efunc);
|
||||
|
||||
/**
|
||||
* Sets the argument being passed to callbacks
|
||||
*
|
||||
* @param any arg The argument to set
|
||||
*/
|
||||
public native void SetArg(any arg);
|
||||
|
||||
/**
|
||||
* Retrieve the local system's hostname as the command "hostname" does.
|
||||
*
|
||||
* @param dest Destination string buffer to copy to.
|
||||
* @param destLen Destination buffer length (includes null terminator).
|
||||
*
|
||||
* @return 1 on success
|
||||
*/
|
||||
public static native int GetHostName(char[] dest, int destLen);
|
||||
|
||||
/**
|
||||
* Returns whether a socket is connected or not.
|
||||
*
|
||||
* @return bool The connection status
|
||||
*/
|
||||
property bool Connected {
|
||||
public native get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************************/
|
||||
/******************************************* callbacks *******************************************/
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* triggered if a normal sockets finished connecting and is ready to be used
|
||||
*
|
||||
|
@ -200,26 +363,20 @@ enum SocketOption {
|
|||
* @param arg The argument set by SocketSetArg()
|
||||
* @noreturn
|
||||
*/
|
||||
funcenum SocketConnectCB
|
||||
{
|
||||
public(Handle:socket, any:arg)
|
||||
};
|
||||
typedef SocketConnectCB = function void (Socket socket, any arg);
|
||||
|
||||
/**
|
||||
* triggered if a listening socket received an incoming connection and is ready to be used
|
||||
*
|
||||
* @note The child-socket won't work until receive-, disconnect-, and errorcallback for it are set.
|
||||
*
|
||||
* @param Handle socket The socket handle pointing to the calling listen-socket
|
||||
* @param Handle newSocket The socket handle to the newly spawned child socket
|
||||
* @param Socket socket The socket handle pointing to the calling listen-socket
|
||||
* @param Socket newSocket The socket handle to the newly spawned child socket
|
||||
* @param String remoteIP The remote IP
|
||||
* @param any arg The argument set by SocketSetArg() for the listen-socket
|
||||
* @noreturn
|
||||
*/
|
||||
funcenum SocketIncomingCB
|
||||
{
|
||||
public(Handle:socket, Handle:newSocket, const String:remoteIP[], remotePort, any:arg)
|
||||
};
|
||||
typedef SocketIncomingCB = function void (Socket socket, Socket newSocket, const char[] remoteIP, int remotePort, any arg);
|
||||
|
||||
/**
|
||||
* triggered if a socket receives data
|
||||
|
@ -229,59 +386,46 @@ funcenum SocketIncomingCB
|
|||
* @note if not set otherwise by SocketSetOption(..., ConcatenateCallbacks, ...) receiveData will
|
||||
* never be longer than 4096 characters including \0 terminator
|
||||
*
|
||||
* @param Handle socket The socket handle pointing to the calling socket
|
||||
* @param Socket socket The socket handle pointing to the calling socket
|
||||
* @param String receiveData The data which arrived, 0-terminated at receiveData[dataSize]
|
||||
* @param cell_t dataSize The length of the arrived data excluding the 0-termination
|
||||
* @param int dataSize The length of the arrived data excluding the 0-termination
|
||||
* @param any arg The argument set by SocketSetArg() for the socket
|
||||
* @noreturn
|
||||
*/
|
||||
funcenum SocketReceiveCB
|
||||
{
|
||||
public(Handle:socket, const String:receiveData[], const dataSize, any:arg)
|
||||
};
|
||||
typedef SocketReceiveCB = function void (Socket socket, const char[] receiveData, const int dataSize, any arg);
|
||||
|
||||
/**
|
||||
* called after a socket sent all items in its send queue successfully
|
||||
*
|
||||
* @param Handle socket The socket handle pointing to the calling socket
|
||||
* @param Socket socket The socket handle pointing to the calling socket
|
||||
* @param any arg The argument set by SocketSetArg() for the socket
|
||||
* @noreturn
|
||||
*/
|
||||
funcenum SocketSendqueueEmptyCB
|
||||
{
|
||||
public(Handle:socket, any:arg)
|
||||
};
|
||||
typedef SocketSendqueueEmptyCB = function void (Socket socket, any arg);
|
||||
|
||||
/**
|
||||
* called if a socket has been properly disconnected by the remote side
|
||||
*
|
||||
* @note You should call CloseHandle(socket) or reuse the socket before this function ends
|
||||
*
|
||||
* @param Handle socket The socket handle pointing to the calling socket
|
||||
* @param Socket socket The socket handle pointing to the calling socket
|
||||
* @param any arg The argument set by SocketSetArg() for the socket
|
||||
* @noreturn
|
||||
*/
|
||||
funcenum SocketDisconnectCB
|
||||
{
|
||||
public(Handle:socket, any:arg)
|
||||
};
|
||||
typedef SocketDisconnectCB = function void (Socket socket, any arg);
|
||||
|
||||
/**
|
||||
* called if an unrecoverable error occured, close the socket without an additional call to a disconnect callback
|
||||
*
|
||||
* @note You should call CloseHandle(socket) or reuse the socket before this function ends
|
||||
*
|
||||
* @param Handle socket The socket handle pointing to the calling socket
|
||||
* @param cell_t errorType The error type, see defines above
|
||||
* @param cell_t errorNum The errno, see errno.h for details
|
||||
* @param Socket socket The socket handle pointing to the calling socket
|
||||
* @param int errorType The error type, see defines above
|
||||
* @param int errorNum The errno, see errno.h for details
|
||||
* @param any arg The argument set by SocketSetArg() for the socket
|
||||
* @noreturn
|
||||
*/
|
||||
funcenum SocketErrorCB
|
||||
{
|
||||
public(Handle:socket, const errorType, const errorNum, any:arg)
|
||||
};
|
||||
|
||||
typedef SocketErrorCB = function void (Socket socket, const int errorType, const int errorNum, any arg);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/******************************************** natives ********************************************/
|
||||
|
@ -294,7 +438,7 @@ funcenum SocketErrorCB
|
|||
* @param socket Socket handle to check
|
||||
* @return bool The connection status
|
||||
*/
|
||||
native bool:SocketIsConnected(Handle:socket);
|
||||
native bool SocketIsConnected(Handle socket);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -304,18 +448,19 @@ native bool:SocketIsConnected(Handle:socket);
|
|||
*
|
||||
* @param SocketType protocol The protocol to use, SOCKET_TCP is default
|
||||
* @param SocketErrorCB efunc The error callback
|
||||
* @return Handle The socket handle. Returns INVALID_HANDLE on failure
|
||||
* @return Socket The socket handle. Returns INVALID_HANDLE on failure
|
||||
*/
|
||||
native Handle:SocketCreate(SocketType:protocol=SOCKET_TCP, SocketErrorCB:efunc);
|
||||
native Socket SocketCreate(SocketType protocol=SOCKET_TCP, SocketErrorCB efunc);
|
||||
|
||||
/**
|
||||
* Binds the socket to a local address
|
||||
*
|
||||
* @param Handle socket The handle of the socket to be used.
* @param String hostname The hostname (or IP) to bind the socket to.
|
||||
* @param cell_t port The port to bind the socket to.
|
||||
* @param Handle socket The handle of the socket to be used.
|
||||
* @param String hostname The hostname (or IP) to bind the socket to.
|
||||
* @param int port The port to bind the socket to.
|
||||
* @return bool true on success
|
||||
*/
|
||||
native bool:SocketBind(Handle:socket, const String:hostname[], port);
|
||||
native bool SocketBind(Handle socket, const char[] hostname, int port);
|
||||
|
||||
/**
|
||||
* Connects a socket
|
||||
|
@ -327,11 +472,12 @@ native bool:SocketBind(Handle:socket, const String:hostname[], port);
|
|||
* @param Handle socket The handle of the socket to be used.
|
||||
* @param SocketConnectCB cfunc The connect callback
|
||||
* @param SocketReceiveCB rfunc The receive callback
|
||||
* @param SocketDisconnectCB dfunc The disconnect callback
* @param String hostname The hostname (or IP) to connect to.
|
||||
* @param cell_t port The port to connect to.
|
||||
* @param SocketDisconnectCB dfunc The disconnect callback
|
||||
* @param String hostname The hostname (or IP) to connect to.
|
||||
* @param int port The port to connect to.
|
||||
* @noreturn
|
||||
*/
|
||||
native SocketConnect(Handle:socket, SocketConnectCB:cfunc, SocketReceiveCB:rfunc, SocketDisconnectCB:dfunc, const String:hostname[], port);
|
||||
native void SocketConnect(Handle socket, SocketConnectCB cfunc, SocketReceiveCB rfunc, SocketDisconnectCB dfunc, const char[] hostname, int port);
|
||||
|
||||
/**
|
||||
* Disconnects a socket
|
||||
|
@ -341,7 +487,7 @@ native SocketConnect(Handle:socket, SocketConnectCB:cfunc, SocketReceiveCB:rfunc
|
|||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native bool:SocketDisconnect(Handle:socket);
|
||||
native bool SocketDisconnect(Handle socket);
|
||||
|
||||
/**
|
||||
* Makes a socket listen for incoming connections
|
||||
|
@ -350,7 +496,7 @@ native bool:SocketDisconnect(Handle:socket);
|
|||
* @param SocketIncomingCB ifunc The callback for incoming connections
|
||||
* @return bool true on success
|
||||
*/
|
||||
native bool:SocketListen(Handle:socket, SocketIncomingCB:ifunc);
|
||||
native bool SocketListen(Handle socket, SocketIncomingCB ifunc);
|
||||
|
||||
/**
|
||||
* Sends data through the socket.
|
||||
|
@ -364,10 +510,12 @@ native bool:SocketListen(Handle:socket, SocketIncomingCB:ifunc);
|
|||
*
|
||||
* @param Handle socket The handle of the socket to be used.
|
||||
* @param String data The data to send.
|
||||
* @noreturn
*/
|
||||
native SocketSend(Handle:socket, const String:data[], size=-1);
|
||||
* @noreturn
|
||||
*/
|
||||
native void SocketSend(Handle socket, const char[] data, int size=-1);
|
||||
|
||||
/**
* Sends UDP data through the socket to a specific destination.
|
||||
/**
|
||||
* Sends UDP data through the socket to a specific destination.
|
||||
*
|
||||
* @note specify size for binary safe operation
|
||||
* @note if size is not specified the \0 terminator will not be included
|
||||
|
@ -379,9 +527,10 @@ native SocketSend(Handle:socket, const String:data[], size=-1);
|
|||
* @param Handle socket The handle of the socket to be used.
|
||||
* @param String data The data to send.
|
||||
* @param String hostname The hostname (or IP) to send to.
|
||||
* @param cell_t port The port to send to.
|
||||
* @noreturn
*/
|
||||
native SocketSendTo(Handle:socket, const String:data[], size=-1, const String:hostname[], port);
|
||||
* @param int port The port to send to.
|
||||
* @noreturn
|
||||
*/
|
||||
native void SocketSendTo(Handle socket, const char[] data, int size=-1, const char[] hostname, int port);
|
||||
|
||||
/**
|
||||
* Set a socket option.
|
||||
|
@ -389,8 +538,9 @@ native SocketSendTo(Handle:socket, const String:data[], size=-1, const String:ho
|
|||
* @param Handle socket The handle of the socket to be used. May be INVALID_HANDLE if not essential.
|
||||
* @param SocketOption option The option to modify (see enum SocketOption for details).
|
||||
* @param cellt_ value The value to set the option to.
|
||||
* @return cell_t 1 on success.
*/
|
||||
native SocketSetOption(Handle:socket, SocketOption:option, value);
|
||||
* @return int 1 on success.
|
||||
*/
|
||||
native int SocketSetOption(Handle socket, SocketOption option, int value);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -403,7 +553,7 @@ native SocketSetOption(Handle:socket, SocketOption:option, value);
|
|||
* @param SocketReceiveCB rfunc The receive callback
|
||||
* @noreturn
|
||||
*/
|
||||
native SocketSetReceiveCallback(Handle:socket, SocketReceiveCB:rfunc);
|
||||
native void SocketSetReceiveCallback(Handle socket, SocketReceiveCB rfunc);
|
||||
|
||||
/**
|
||||
* Defines the callback function for when the socket sent all items in its send queue
|
||||
|
@ -416,7 +566,7 @@ native SocketSetReceiveCallback(Handle:socket, SocketReceiveCB:rfunc);
|
|||
* @param SocketDisconnectCB dfunc The disconnect callback
|
||||
* @noreturn
|
||||
*/
|
||||
native SocketSetSendqueueEmptyCallback(Handle:socket, SocketSendqueueEmptyCB:sfunc);
|
||||
native void SocketSetSendqueueEmptyCallback(Handle socket, SocketSendqueueEmptyCB sfunc);
|
||||
|
||||
/**
|
||||
* Defines the callback function for when the socket was properly disconnected by the remote side
|
||||
|
@ -428,7 +578,7 @@ native SocketSetSendqueueEmptyCallback(Handle:socket, SocketSendqueueEmptyCB:sfu
|
|||
* @param SocketDisconnectCB dfunc The disconnect callback
|
||||
* @noreturn
|
||||
*/
|
||||
native SocketSetDisconnectCallback(Handle:socket, SocketDisconnectCB:dfunc);
|
||||
native void SocketSetDisconnectCallback(Handle socket, SocketDisconnectCB dfunc);
|
||||
|
||||
/**
|
||||
* Defines the callback function for when the socket triggered an error
|
||||
|
@ -440,7 +590,7 @@ native SocketSetDisconnectCallback(Handle:socket, SocketDisconnectCB:dfunc);
|
|||
* @param SocketErrorCB efunc The error callback
|
||||
* @noreturn
|
||||
*/
|
||||
native SocketSetErrorCallback(Handle:socket, SocketErrorCB:efunc);
|
||||
native void SocketSetErrorCallback(Handle socket, SocketErrorCB efunc);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -450,7 +600,7 @@ native SocketSetErrorCallback(Handle:socket, SocketErrorCB:efunc);
|
|||
* @param any arg The argument to set
|
||||
* @noreturn
|
||||
*/
|
||||
native SocketSetArg(Handle:socket, any:arg);
|
||||
native void SocketSetArg(Handle socket, any arg);
|
||||
|
||||
/**
|
||||
* Retrieve the local system's hostname as the command "hostname" does.
|
||||
|
@ -460,12 +610,12 @@ native SocketSetArg(Handle:socket, any:arg);
|
|||
*
|
||||
* @return 1 on success
|
||||
*/
|
||||
native SocketGetHostName(String:dest[], destLen);
|
||||
native int SocketGetHostName(char[] dest, int destLen);
|
||||
|
||||
/**
|
||||
* _________________Do not edit below this line!_______________________
|
||||
*/
|
||||
public Extension:__ext_smsock =
|
||||
public Extension __ext_socket =
|
||||
{
|
||||
name = "Socket",
|
||||
file = "socket.ext",
|
||||
|
@ -480,3 +630,39 @@ public Extension:__ext_smsock =
|
|||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public void __ext_socket_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("Socket.Socket");
|
||||
MarkNativeAsOptional("Socket.Bind");
|
||||
MarkNativeAsOptional("Socket.Connect");
|
||||
MarkNativeAsOptional("Socket.Disconnect");
|
||||
MarkNativeAsOptional("Socket.Listen");
|
||||
MarkNativeAsOptional("Socket.Send");
|
||||
MarkNativeAsOptional("Socket.SendTo");
|
||||
MarkNativeAsOptional("Socket.SetOption");
|
||||
MarkNativeAsOptional("Socket.SetReceiveCallback");
|
||||
MarkNativeAsOptional("Socket.SetSendqueueEmptyCallback");
|
||||
MarkNativeAsOptional("Socket.SetDisconnectCallback");
|
||||
MarkNativeAsOptional("Socket.SetErrorCallback");
|
||||
MarkNativeAsOptional("Socket.SetArg");
|
||||
MarkNativeAsOptional("Socket.GetHostName");
|
||||
MarkNativeAsOptional("Socket.Connected.get");
|
||||
MarkNativeAsOptional("SocketIsConnected");
|
||||
MarkNativeAsOptional("SocketCreate");
|
||||
MarkNativeAsOptional("SocketBind");
|
||||
MarkNativeAsOptional("SocketConnect");
|
||||
MarkNativeAsOptional("SocketDisconnect");
|
||||
MarkNativeAsOptional("SocketListen");
|
||||
MarkNativeAsOptional("SocketSend");
|
||||
MarkNativeAsOptional("SocketSendTo");
|
||||
MarkNativeAsOptional("SocketSetOption");
|
||||
MarkNativeAsOptional("SocketSetReceiveCallback");
|
||||
MarkNativeAsOptional("SocketSetSendqueueEmptyCallback");
|
||||
MarkNativeAsOptional("SocketSetDisconnectCallback");
|
||||
MarkNativeAsOptional("SocketSetErrorCallback");
|
||||
MarkNativeAsOptional("SocketSetArg");
|
||||
MarkNativeAsOptional("SocketGetHostName");
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
|
||||
#define EXTRA_TANK_MIN_SEC 2.0
|
||||
#define EXTRA_TANK_MAX_SEC 16.0
|
||||
#define MAX_RANDOM_SPAWNS 12
|
||||
// The map's max flow rate is divided by this. Parish Ch4 = ~16 items
|
||||
#define MAX_RANDOM_SPAWNS 1700.0
|
||||
#define DATE_FORMAT "%F at %I:%M %p"
|
||||
|
||||
|
||||
|
@ -348,6 +349,7 @@ public void OnPluginStart() {
|
|||
}
|
||||
}
|
||||
g_currentChapter = L4D_GetCurrentChapter();
|
||||
UpdateSurvivorCount();
|
||||
TryStartHud();
|
||||
}
|
||||
|
||||
|
@ -1097,7 +1099,7 @@ Action Timer_SetupNewClient(Handle h, int userid) {
|
|||
PrintDebug(DEBUG_SPAWNLOGIC, "Giving new client (%N) tier 1: %s", client, weaponName);
|
||||
GiveWeapon(client, weaponName, 0.6, 0);
|
||||
}
|
||||
PrintDebug(DEBUG_SPAWNLOGIC, "%N: Giving random secondary / %d", secondaryWeapons.Length, client);
|
||||
PrintDebug(DEBUG_SPAWNLOGIC, "%N: Giving random secondary / %d", client, secondaryWeapons.Length);
|
||||
if(secondaryWeapons.Length > 0) {
|
||||
secondaryWeapons.GetString(GetRandomInt(0, secondaryWeapons.Length - 1), weaponName, sizeof(weaponName));
|
||||
GiveWeapon(client, weaponName, 0.6, 1);
|
||||
|
@ -1371,54 +1373,6 @@ bool IsWallNearby(const float pos[3], WallCheck wall, float maxDistance = 80.0)
|
|||
return TR_DidHit();
|
||||
}
|
||||
|
||||
void PopulateItemSpawns() {
|
||||
ArrayList navs = new ArrayList();
|
||||
L4D_GetAllNavAreas(navs);
|
||||
navs.Sort(Sort_Random, Sort_Integer);
|
||||
float pos[3];
|
||||
float percentage = hExtraSpawnBasePercentage.FloatValue * (g_survivorCount - 4);
|
||||
PrintToServer("[EPI] Populating extra item spawns based on player count (%d-4) | Percentage %.2f%%", g_survivorCount, percentage * 100);
|
||||
int tier;
|
||||
// On first chapter, 10% chance to give tier 2
|
||||
if(g_currentChapter == 1) tier = GetRandomFloat() < 0.15 ? 1 : 0;
|
||||
else tier = DiceRoll(0, 3, 2, BIAS_LEFT);
|
||||
int count;
|
||||
for(int i = 0; i < navs.Length; i++) {
|
||||
Address nav = navs.Get(i);
|
||||
int spawnFlags = L4D_GetNavArea_SpawnAttributes(nav);
|
||||
int baseFlags = L4D_GetNavArea_AttributeFlags(nav);
|
||||
if(!(baseFlags & (NAV_BASE_FLOW_BLOCKED)) &&
|
||||
!(spawnFlags & NAV_SPAWN_ESCAPE_ROUTE|NAV_SPAWN_DESTROYED_DOOR|NAV_SPAWN_CHECKPOINT|NAV_SPAWN_NO_MOBS|NAV_SPAWN_STOP_SCAN))
|
||||
{
|
||||
L4D_FindRandomSpot(view_as<int>(nav), pos);
|
||||
bool north = IsWallNearby(pos, Wall_North);
|
||||
bool east = IsWallNearby(pos, Wall_East);
|
||||
bool south = IsWallNearby(pos, Wall_South);
|
||||
bool west = IsWallNearby(pos, Wall_West);
|
||||
// TODO: collision check (windows like c1m1)
|
||||
int wallCount = 0;
|
||||
if(north) wallCount++;
|
||||
if(east) wallCount++;
|
||||
if(south) wallCount++;
|
||||
if(west) wallCount++;
|
||||
if(wallCount >= 2) {
|
||||
if(GetURandomFloat() < percentage) {
|
||||
int wpn;
|
||||
pos[2] += 7.0;
|
||||
if(GetURandomFloat() > 0.30) {
|
||||
wpn = CreateWeaponSpawn(pos, "", tier);
|
||||
} else {
|
||||
wpn = CreateRandomMeleeSpawn(pos);
|
||||
}
|
||||
if(wpn == -1) continue;
|
||||
if(++count > MAX_RANDOM_SPAWNS) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PrintToServer("[EPI] Spawned %d/%d new item spawns (tier=%d)", count, MAX_RANDOM_SPAWNS, tier);
|
||||
delete navs;
|
||||
}
|
||||
|
||||
char WEAPON_SPAWN_CLASSNAMES[32][] = {
|
||||
"weapon_pistol_magnum_spawn","weapon_smg_spawn","weapon_smg_silenced_spawn","weapon_pumpshotgun_spawn","weapon_shotgun_chrome_spawn","weapon_pipe_bomb_spawn","weapon_upgradepack_incendiary_spawn","weapon_upgradepack_explosive_spawn","weapon_adrenaline_spawn","weapon_smg_mp5_spawn","weapon_defibrillator_spawn","weapon_propanetank_spawn","weapon_oxygentank_spawn","weapon_chainsaw_spawn","weapon_gascan_spawn","weapon_ammo_spawn","weapon_sniper_scout_spawn","weapon_hunting_rifle_spawn","weapon_pain_pills_spawn","weapon_rifle_spawn","weapon_rifle_desert_spawn","weapon_sniper_military_spawn","weapon_autoshotgun_spawn","weapon_shotgun_spas_spawn","weapon_first_aid_kit_spawn","weapon_molotov_spawn","weapon_vomitjar_spawn","weapon_rifle_ak47_spawn","weapon_rifle_sg552_spawn","weapon_grenade_launcher_spawn","weapon_sniper_awp_spawn","weapon_rifle_m60_spawn"
|
||||
|
@ -1676,7 +1630,6 @@ void UnlockDoor(int flag) {
|
|||
SetVariantString("Unlock");
|
||||
AcceptEntityInput(entity, "SetAnimation");
|
||||
g_saferoomDoorEnt = INVALID_ENT_REFERENCE;
|
||||
PopulateItems();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1709,7 +1662,7 @@ Action Timer_UpdateHud(Handle h) {
|
|||
// TODO: name scrolling
|
||||
// TODO: name cache (hook name change event), strip out invalid
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2) {
|
||||
if(IsClientInGame(i) && GetClientTeam(i) == 2) {
|
||||
data[0] = '\0';
|
||||
prefix[0] = '\0';
|
||||
int health = GetClientRealHealth(i);
|
||||
|
@ -1723,8 +1676,8 @@ Action Timer_UpdateHud(Handle h) {
|
|||
} else {
|
||||
Format(prefix, HUD_NAME_LENGTH, "%s", playerData[client].nameCache[playerData[client].scrollIndex]);
|
||||
}
|
||||
if(g_isSpeaking[i])
|
||||
Format(prefix, HUD_NAME_LENGTH, "🔊%s", prefix);
|
||||
// if(g_isSpeaking[i])
|
||||
// Format(prefix, HUD_NAME_LENGTH, "%s", prefix);
|
||||
|
||||
playerData[client].AdvanceScroll();
|
||||
|
||||
|
@ -1769,9 +1722,9 @@ Action Timer_UpdateHud(Handle h) {
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PopulateItems() {
|
||||
PrintToServer("[EPI:TEMP] PopulateItems hasRan=%b finale=%b", g_areItemsPopulated, L4D_IsMissionFinalMap(true));
|
||||
if(g_areItemsPopulated) return;
|
||||
UpdateSurvivorCount();
|
||||
PrintToServer("[EPI:TEMP] PopulateItems hasRan=%b finale=%b willRun=%b players=%d", g_areItemsPopulated, L4D_IsMissionFinalMap(true), !g_areItemsPopulated&&IsEPIActive, g_realSurvivorCount);
|
||||
if(!IsEPIActive()) return;
|
||||
|
||||
g_areItemsPopulated = true;
|
||||
|
@ -1799,6 +1752,7 @@ void PopulateItems() {
|
|||
if(count == 4) {
|
||||
// Some item spawns are only for 4 players, so here we set to # of players:
|
||||
SetEntProp(i, Prop_Data, "m_itemCount", g_survivorCount);
|
||||
++affected;
|
||||
} else if(count > 0 && GetURandomFloat() < percentage) {
|
||||
SetEntProp(i, Prop_Data, "m_itemCount", ++count);
|
||||
++affected;
|
||||
|
@ -1812,6 +1766,64 @@ void PopulateItems() {
|
|||
PopulateCabinets();
|
||||
}
|
||||
|
||||
void PopulateItemSpawns(int minWalls = 4) {
|
||||
ArrayList navs = new ArrayList();
|
||||
L4D_GetAllNavAreas(navs);
|
||||
navs.Sort(Sort_Random, Sort_Integer);
|
||||
float pos[3];
|
||||
float percentage = hExtraSpawnBasePercentage.FloatValue * (g_survivorCount - 4);
|
||||
PrintToServer("[EPI] Populating extra item spawns based on player count (%d-4) | Percentage %.2f%%", g_survivorCount, percentage * 100);
|
||||
int tier;
|
||||
// On first chapter, 10% chance to give tier 2
|
||||
if(g_currentChapter == 1) tier = GetRandomFloat() < 0.15 ? 1 : 0;
|
||||
else tier = DiceRoll(0, 3, 2, BIAS_LEFT);
|
||||
int count;
|
||||
|
||||
float mapFlowMax = L4D2Direct_GetMapMaxFlowDistance();
|
||||
PrintToServer("[EPI] PopulateItemSpawns: flow[0, %f]", mapFlowMax);
|
||||
int maxSpawns = RoundFloat(mapFlowMax / MAX_RANDOM_SPAWNS);
|
||||
for(int i = 0; i < navs.Length; i++) {
|
||||
Address nav = navs.Get(i);
|
||||
int spawnFlags = L4D_GetNavArea_SpawnAttributes(nav);
|
||||
int baseFlags = L4D_GetNavArea_AttributeFlags(nav);
|
||||
if((!(baseFlags & NAV_BASE_FLOW_BLOCKED)) &&
|
||||
!(spawnFlags & (NAV_SPAWN_ESCAPE_ROUTE|NAV_SPAWN_DESTROYED_DOOR|NAV_SPAWN_CHECKPOINT|NAV_SPAWN_NO_MOBS|NAV_SPAWN_STOP_SCAN)))
|
||||
{
|
||||
L4D_FindRandomSpot(view_as<int>(nav), pos);
|
||||
bool north = IsWallNearby(pos, Wall_North);
|
||||
bool east = IsWallNearby(pos, Wall_East);
|
||||
bool south = IsWallNearby(pos, Wall_South);
|
||||
bool west = IsWallNearby(pos, Wall_West);
|
||||
// TODO: collision check (windows like c1m1)
|
||||
int wallCount = 0;
|
||||
if(north) wallCount++;
|
||||
if(east) wallCount++;
|
||||
if(south) wallCount++;
|
||||
if(west) wallCount++;
|
||||
if(wallCount >= minWalls) {
|
||||
if(GetURandomFloat() < percentage) {
|
||||
int wpn;
|
||||
pos[2] += 7.0;
|
||||
if(GetURandomFloat() > 0.30) {
|
||||
wpn = CreateWeaponSpawn(pos, "", tier);
|
||||
} else {
|
||||
wpn = CreateRandomMeleeSpawn(pos);
|
||||
}
|
||||
if(wpn == -1) continue;
|
||||
if(++count >= maxSpawns) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PrintToServer("[EPI] Spawned %d/%d new item spawns (tier=%d)", count, maxSpawns, tier);
|
||||
delete navs;
|
||||
// Incase there was no suitable spots, try again:
|
||||
minWalls--;
|
||||
if(count == 0 && minWalls > 0) {
|
||||
PopulateItemSpawns(minWalls);
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateCabinets() {
|
||||
char classname[64];
|
||||
//Cabinet logic
|
||||
|
|
|
@ -622,24 +622,24 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
|||
|
||||
bool isRotate;
|
||||
int flags = GetEntityFlags(client);
|
||||
if(buttons & IN_RELOAD && ~buttons & IN_ZOOM) {
|
||||
if(buttons & IN_RELOAD) {
|
||||
if(!g_inRotate[client]) {
|
||||
g_inRotate[client] = true;
|
||||
}
|
||||
if(buttons & IN_JUMP) {
|
||||
buttons = buttons & ~IN_JUMP;
|
||||
if(!(oldButtons & IN_JUMP) && (buttons & IN_JUMP)) {
|
||||
buttons &= ~IN_JUMP;
|
||||
Editor[client].CycleStacker(tick);
|
||||
} if(buttons & IN_SPEED) {
|
||||
} else if(!(oldButtons & IN_SPEED) && (buttons & IN_SPEED)) {
|
||||
Editor[client].ToggleCollision(tick);
|
||||
return Plugin_Handled;
|
||||
} else if(buttons & IN_DUCK) {
|
||||
} else if(!(oldButtons & IN_DUCK) && (buttons & IN_DUCK)) {
|
||||
Editor[client].ToggleCollisionRotate(tick);
|
||||
return Plugin_Handled;
|
||||
} else {
|
||||
PrintCenterText(client, "%.1f %.1f %.1f", Editor[client].angles[0], Editor[client].angles[1], Editor[client].angles[2]);
|
||||
isRotate = true;
|
||||
SetEntityFlags(client, flags |= FL_FROZEN);
|
||||
if(buttons & IN_ATTACK) Editor[client].CycleAxis(tick);
|
||||
if(!(oldButtons & IN_ATTACK) && (buttons & IN_ATTACK)) Editor[client].CycleAxis(tick);
|
||||
else if(buttons & IN_ATTACK2) Editor[client].CycleSnapAngle(tick);
|
||||
|
||||
// Rotation control:
|
||||
|
|
|
@ -61,6 +61,12 @@ enum GameState {
|
|||
State_Restarting,
|
||||
State_Hunting
|
||||
}
|
||||
char GAME_STATE_DEBUG[4][] = {
|
||||
"Startup",
|
||||
"Hiding",
|
||||
"Restarting",
|
||||
"Hunting"
|
||||
};
|
||||
|
||||
bool isNearbyPlaying[MAXPLAYERS+1];
|
||||
bool wasThirdPersonVomitted[MAXPLAYERS+1];
|
||||
|
@ -69,6 +75,7 @@ int currentSeeker;
|
|||
int currentPlayers = 0;
|
||||
|
||||
Handle suspenseTimer, thirdPersonTimer, peekCamStopTimer, hiderCheckTimer;
|
||||
Handle startupTimer;
|
||||
|
||||
|
||||
int g_BeamSprite;
|
||||
|
@ -134,15 +141,22 @@ public void OnClientConnected(int client) {
|
|||
if(!IsFakeClient(client)) {
|
||||
currentPlayers++;
|
||||
if(isEnabled) {
|
||||
GameState state = GetState();
|
||||
// Once first player joins, wait for others to join
|
||||
if(currentPlayers == 1 && state == State_Startup) {
|
||||
CreateTimer(10.0, Timer_KeepWaiting, _, TIMER_REPEAT);
|
||||
if(currentPlayers == 1) {
|
||||
StartWaiting();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StartWaiting(bool fireInstantly = false) {
|
||||
if(GetState() == State_Startup && startupTimer != null) {
|
||||
startupTimer = CreateTimer(10.0, Timer_KeepWaiting, _, TIMER_REPEAT);
|
||||
if(fireInstantly)
|
||||
TriggerTimer(startupTimer);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClientPutInServer(int client) {
|
||||
if(isEnabled && !IsFakeClient(client)) {
|
||||
ChangeClientTeam(client, 1);
|
||||
|
@ -160,7 +174,12 @@ public Action Timer_KeepWaiting(Handle h) {
|
|||
SetTick(-40);
|
||||
SetState(State_Startup);
|
||||
PrintHintTextToAll("Waiting for players to join...");
|
||||
return IsGameSoloOrPlayersLoading() ? Plugin_Continue : Plugin_Stop;
|
||||
if(IsGameSoloOrPlayersLoading()) {
|
||||
return Plugin_Continue;
|
||||
} else {
|
||||
startupTimer = null;
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client) {
|
||||
|
@ -189,8 +208,7 @@ public void OnMapStart() {
|
|||
}
|
||||
strcopy(g_currentSet, sizeof(g_currentSet), "default");
|
||||
if(IsGameSoloOrPlayersLoading()) {
|
||||
Handle timer = CreateTimer(10.0, Timer_KeepWaiting, _, TIMER_REPEAT);
|
||||
TriggerTimer(timer);
|
||||
StartWaiting(true);
|
||||
PrintToServer("[H&S] Player(s) are connecting, or solo. Waiting...");
|
||||
SetState(State_Startup);
|
||||
}
|
||||
|
@ -595,10 +613,11 @@ public Action Timer_Music(Handle h) {
|
|||
int playerCount;
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && i != currentSeeker) {
|
||||
if(IsClientInGame(i) && i != currentSeeker) {
|
||||
playerCount++;
|
||||
// GetClientAbsOrigin(i, playerLoc);
|
||||
// float dist = GetVectorDistance(seekerLoc, playerLoc, true);
|
||||
if(currentSeeker == 0) continue;
|
||||
float dist = GetFlowDistance(currentSeeker, i);
|
||||
if(dist <= HEARTBEAT_CLOSE_DIST) {
|
||||
StopSound(i, SNDCHAN_AUTO, SOUND_SUSPENSE_1);
|
||||
|
|
|
@ -59,37 +59,41 @@ public void OnPluginStart() {
|
|||
|
||||
char currentMap[64];
|
||||
|
||||
bool hasRan;
|
||||
// TODO: on round start
|
||||
public void OnMapStart() {
|
||||
g_iLaserIndex = PrecacheModel("materials/sprites/laserbeam.vmt", true);
|
||||
GetCurrentMap(currentMap, sizeof(currentMap));
|
||||
if(cvarEnabled.BoolValue)
|
||||
CreateTimer(5.0, Timer_Run);
|
||||
}
|
||||
|
||||
public void OnMapEnd() {
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
bool hasRan;
|
||||
public void OnMapInit(const char[] map) {
|
||||
if(cvarEnabled.BoolValue) {
|
||||
if(LoadMapData(currentMap, FLAG_NONE) && g_MapData.lumpEdits.Length > 0) {
|
||||
Log("Found %d lump edits, running...", g_MapData.lumpEdits.Length);
|
||||
LumpEditData lump;
|
||||
for(int i = 0; i < g_MapData.lumpEdits.Length; i++) {
|
||||
g_MapData.lumpEdits.GetArray(i, lump);
|
||||
lump.Trigger();
|
||||
}
|
||||
}
|
||||
}
|
||||
hasRan = false;
|
||||
// if(cvarEnabled.BoolValue) {
|
||||
// if(LoadMapData(currentMap, FLAG_NONE) && g_MapData.lumpEdits.Length > 0) {
|
||||
// Log("Found %d lump edits, running...", g_MapData.lumpEdits.Length);
|
||||
// LumpEditData lump;
|
||||
// for(int i = 0; i < g_MapData.lumpEdits.Length; i++) {
|
||||
// g_MapData.lumpEdits.GetArray(i, lump);
|
||||
// lump.Trigger();
|
||||
// }
|
||||
// hasRan = true;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void OnClientPutInServer(int client) {
|
||||
if(!hasRan) {
|
||||
hasRan = true;
|
||||
if(cvarEnabled.BoolValue)
|
||||
RunMap(currentMap, FLAG_NONE);
|
||||
}
|
||||
public void OnConfigsExecuted() {
|
||||
|
||||
}
|
||||
|
||||
Action Timer_Run(Handle h) {
|
||||
if(cvarEnabled.BoolValue)
|
||||
RunMap(currentMap, FLAG_NONE);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
stock int GetLookingEntity(int client, TraceEntityFilter filter) {
|
||||
|
@ -438,7 +442,7 @@ public bool LoadMapData(const char[] map, int flags) {
|
|||
|
||||
json_cleanup_and_delete(data);
|
||||
profiler.Stop();
|
||||
Log("Parsed map file and found %d scenes in %.4f seconds", g_MapData.scenes.Length, profiler.Time);
|
||||
Log("Parsed map file for %s(%d) and found %d scenes in %.4f seconds", map, flags, g_MapData.scenes.Length, profiler.Time);
|
||||
delete profiler;
|
||||
delete file;
|
||||
return true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue