Skip to content

Commit

Permalink
Add support for adding crates at the end of the round
Browse files Browse the repository at this point in the history
Split "sm_respawnunlocker_enable" console variable into "sm_respawnunlocker_walls" and "sm_respawnunlocker_crates".
  • Loading branch information
dronelektron committed Oct 1, 2021
1 parent 64e3215 commit b6c8347
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 12 deletions.
51 changes: 48 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,62 @@
# Respawn Unlocker

Allows to unlock respawn at the end of the round.
Allows you to remove invisible walls and add crates near the spawn zone at the end of the round.

### Supported Games

* Day of Defeat: Source

### Installation

* Download latest [release](https://github.com/Dron-elektron/respawn-unlocker/releases) (compiled for SourceMod 1.10)
* Download latest [release](https://github.com/dronelektron/respawn-unlocker/releases) (compiled for SourceMod 1.10)
* Extract "plugins" and "translations" folders to "addons/sourcemod" folder of your server

### Console Variables

* sm_respawnunlocker_enable - Enable (1) or disable (0) plugin [default: "1"]
* sm_respawnunlocker_walls - Enable (1) or disable (0) walls removing [default: "1"]
* sm_respawnunlocker_crates - Enable (1) or disable (0) crates adding [default: "1"]
* sm_respawnunlocker_notifications - Enable (1) or disable (0) notifications [default: "1"]

### How to add crates

Create a file "addons/sourcemod/configs/respawn-unlocker.txt" with the following structure:

```
"Crates"
{
"dod_gan_games" // Map name
{
"1" // Crate's number
{
"position_x" "320" // Position of the center
"position_y" "-128" // Position of the center
"position_z" "64" // Position of the bottom
}
"2"
{
"position_x" "320"
"position_y" "-108"
"position_z" "104"
}
"3"
{
"position_x" "2300"
"position_y" "-128"
"position_z" "64"
}
"4"
{
"position_x" "2300"
"position_y" "-108"
"position_z" "104"
}
}
}
```

This is how crates "3" and "4" will look like in the game:

![dod_gan_games](https://i.imgur.com/uxp9rcY.png)
108 changes: 99 additions & 9 deletions scripting/respawn-unlocker.sp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
#define MAX_WALLS_COUNT 32
#define ENTITY_NOT_FOUND -1
#define COLLISION_GROUP_IN_VEHICLE 10
#define MAX_CRATES_COUNT 8

public Plugin myinfo = {
name = "Respawn unlocker",
author = "Dron-elektron",
description = "Allows to unlock respawn at the end of the round",
version = "1.0.0",
description = "Allows you to remove invisible walls and add crates near the spawn zone at the end of the round",
version = "1.1.0",
url = ""
}

Expand All @@ -21,11 +22,16 @@ static int g_wallsCount = 0;
static int g_wallEntities[MAX_WALLS_COUNT];
static int g_wallCollisionFlags[MAX_WALLS_COUNT];

static ConVar g_pluginEnabled = null;
static int g_cratesCount = 0;
static float g_cratePositions[MAX_CRATES_COUNT][3];

static ConVar g_wallsEnabled = null;
static ConVar g_cratesEnabled = null;
static ConVar g_notificationsEnabled = null;

public void OnPluginStart() {
g_pluginEnabled = CreateConVar("sm_respawnunlocker_enable", "1", "Enable (1) or disable (0) plugin");
g_wallsEnabled = CreateConVar("sm_respawnunlocker_walls", "1", "Enable (1) or disable (0) walls removing");
g_cratesEnabled = CreateConVar("sm_respawnunlocker_crates", "1", "Enable (1) or disable (0) crates adding");
g_notificationsEnabled = CreateConVar("sm_respawnunlocker_notifications", "1", "Enable (1) or disable (0) notifications");

HookEvent("dod_round_start", Event_RoundStart);
Expand All @@ -38,21 +44,60 @@ public void OnPluginStart() {
public void OnMapStart() {
FindWallEntities();
SaveWallsCollisionFlags();
LoadCrates();
}

public Action Event_RoundStart(Event event, const char[] name, bool dontBroadcast) {
RestoreWallsCollisionFlags()
RestoreWallsCollisionFlags();

return Plugin_Continue;
}

public Action Event_RoundWin(Event event, const char[] name, bool dontBroadcast) {
RemoveWallsCollisionFlags();
NotifyAboutRespawnUnlocking();
CreateCrates();
NotifyAboutCrates();

return Plugin_Continue;
}

void LoadCrates() {
char configPath[PLATFORM_MAX_PATH];
char mapName[256];

GetCurrentMap(mapName, sizeof(mapName));
BuildPath(Path_SM, configPath, sizeof(configPath), "configs/respawn-unlocker.txt");

if (!FileExists(configPath)) {
return;
}

KeyValues kv = new KeyValues("Crates");

kv.ImportFromFile(configPath);
g_cratesCount = 0;

if (!kv.JumpToKey(mapName) || !kv.GotoFirstSubKey()) {
LogMessage("No crates for this map");

delete kv;

return;
}

do {
g_cratePositions[g_cratesCount][0] = kv.GetFloat("position_x");
g_cratePositions[g_cratesCount][1] = kv.GetFloat("position_y");
g_cratePositions[g_cratesCount][2] = kv.GetFloat("position_z");
g_cratesCount++;
} while (kv.GotoNextKey());

LogMessage("Loaded %d crates for this map", g_cratesCount);

delete kv;
}

void FindWallEntities() {
int wallIndex = 0;
int entity = ENTITY_NOT_FOUND;
Expand All @@ -75,7 +120,7 @@ void SaveWallsCollisionFlags() {
}

void RemoveWallsCollisionFlags() {
if (!IsPluginEnabled()) {
if (!IsWallsEnabled()) {
return;
}

Expand Down Expand Up @@ -103,15 +148,60 @@ void SetCollisionFlags(int entity, int flags) {
}

void NotifyAboutRespawnUnlocking() {
if (g_wallsCount == 0 || !IsPluginEnabled() || !IsNotificationsEnabled()) {
if (g_wallsCount == 0 || !IsWallsEnabled() || !IsNotificationsEnabled()) {
return;
}

CPrintToChatAll("%s%t", PREFIX_COLORED, "Respawn unlocked");
}

bool IsPluginEnabled() {
return g_pluginEnabled.IntValue == 1;
void NotifyAboutCrates() {
if (g_cratesCount == 0 || !IsCratesEnabled() || !IsNotificationsEnabled()) {
return;
}

CPrintToChatAll("%s%t", PREFIX_COLORED, "Crates created");
}

void CreateCrates() {
if (!IsCratesEnabled()) {
return;
}

for (int crateIndex = 0; crateIndex < g_cratesCount; crateIndex++) {
CreateCrate(g_cratePositions[crateIndex]);
}
}

void CreateCrate(const float position[3]) {
int crate = CreateEntityByName("prop_dynamic_override");

DispatchKeyValue(crate, "model", "models/props_junk/wood_crate001a.mdl");
DispatchKeyValue(crate, "disableshadows", "1");
DispatchKeyValue(crate, "solid", "6");
DispatchSpawn(crate);

SetEntityRenderColor(crate, 255, 255, 255, 127);
SetEntityRenderMode(crate, RENDER_TRANSCOLOR);

float minBounds[3];
float newPosition[3];

GetEntPropVector(crate, Prop_Send, "m_vecMins", minBounds);

newPosition[0] = position[0];
newPosition[1] = position[1];
newPosition[2] = position[2] - minBounds[2];

TeleportEntity(crate, newPosition, NULL_VECTOR, NULL_VECTOR);
}

bool IsWallsEnabled() {
return g_wallsEnabled.IntValue == 1;
}

bool IsCratesEnabled() {
return g_cratesEnabled.IntValue == 1;
}

bool IsNotificationsEnabled() {
Expand Down
5 changes: 5 additions & 0 deletions translations/respawn-unlocker.phrases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@
{
"en" "{default}Spawn zone walls disabled"
}

"Crates created"
{
"en" "{default}Added crates near the spawn zone"
}
}
5 changes: 5 additions & 0 deletions translations/ru/respawn-unlocker.phrases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@
{
"ru" "{default}Стены респауна отключены"
}

"Crates created"
{
"ru" "{default}Добавлены ящики возле зоны возрождения"
}
}

0 comments on commit b6c8347

Please sign in to comment.