Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Aim Barriers #46

Merged
merged 5 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions cstrike/addons/amxmodx/configs/redm/gamemode_deathmatch.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@
"redm_spawn_preset": "preset",

// ReDM: Features
/* Enable a barrier in the middle of the map (`anti-rush' system).
It dont work on `de_`, `cs_` `css_` maps. */
"redm_aim_barrier": "1",

/* Barrier display mode
`0` - disable,
`1` - display permanently (beta),
`2` - display only when touched. */
"redm_aim_barrier_always_show": "2",

// Open equip menu by pressing `G` (drop command).
"redm_open_equip_menu_by_g": "1",

Expand Down
2 changes: 2 additions & 0 deletions cstrike/addons/amxmodx/scripting/ReDeathmatch.sma
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <reapi>
#include <redm>

#tryinclude <msgstocks>

#include "ReDeathmatch/ReDM_config.inc"
#include "ReDeathmatch/ReDM_cvars_handler.inc"
#include "ReDeathmatch/ReDM_spawn_manager.inc"
Expand Down
204 changes: 204 additions & 0 deletions cstrike/addons/amxmodx/scripting/ReDeathmatch/Features/AimBarriers.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
static const Float: BARRIER_REDRAW_TIME = 5.0

static g_spriteLaserbeam
static g_spriteBubble

static bool: redm_aim_barrier
static redm_aim_barrier_always_show

AimBarriers_Precache() {
g_spriteLaserbeam = precache_model("sprites/laserbeam.spr")
g_spriteBubble = precache_model("sprites/bubble.spr")
}

AimBarriers_Init() {
bind_pcvar_num(
create_cvar(
"redm_aim_barrier", "1",
.has_min = true, .min_val = 0.0,
.has_max = true, .max_val = 1.0,
.description = "Enable a barrier in the middle of the map (`anti-rush' system). \
It does not work on `de_`, `cs_` `css_` maps."
),
redm_aim_barrier
)
bind_pcvar_num(
create_cvar(
"redm_aim_barrier_always_show", "2",
.has_min = true, .min_val = 0.0,
.has_max = true, .max_val = 2.0,
.description = "Barrier display mode. \
`0` - disable, \
`1` - display permanently (beta), \
`2` - display only when touched."
),
redm_aim_barrier_always_show
)

new const prefixBlocklist[][] = { "de_", "cs_", "css_" }
if (!IsMapCompatible(prefixBlocklist))
return

CreateBarrier()

RegisterHam(Ham_Touch, "trigger_push", "CTriggerPush_Touch", .Post = false)
}

static CreateBarrier() {
new Float: middle[3], longerAxis
CWorld_GetCenter(middle, longerAxis)

new Float: mins[3] = { -10.0, -10.0, -8192.0 }
new Float: maxs[3] = { 10.0, 10.0, 8192.0 }

mins[!longerAxis] *= 500
maxs[!longerAxis] *= 500

new ent = CBarrier_Spawn(middle, mins, maxs, 2.0)
set_task_ex(BARRIER_REDRAW_TIME, "BarrierRedraw", ent, .flags = SetTask_Repeat)

return ent
}

static bool: GetAvgOrigin(const classname[], Float: out[3], bool: simple = false) {
new count

new ent = MaxClients
while ((ent = fm_find_ent_by_class(ent, classname))) {
new Float: origin[3]
pev(ent, pev_origin, origin)

xs_vec_add(out, origin, out)
++count

if (simple)
break
}

if (!count)
return false

for (new i; i < sizeof out; i++) {
out[i] /= float(count)
}

return true
}

static CWorld_GetCenter(Float: out[3], &longerAxis) {
new const startEntClassname[] = "info_player_deathmatch"
new const endEntClassname[] = "info_player_start"

new Float: start[3], Float: end[3]
GetAvgOrigin(startEntClassname, start)
GetAvgOrigin(endEntClassname, end)

_xs_vec_lerp(start, end, out, 0.5)

longerAxis = floatabs(out[XS_X] - start[XS_X]) < floatabs(out[XS_Y] - start[XS_Y])

set_pev(0, pev_origin, out, sizeof(out)) // TODO: hacky ?!
}

static CBarrier_Spawn(const Float: origin[3], const Float: mins[3], const Float: maxs[3], const Float: pushForce = 2.0) {
new ent = fm_create_entity("trigger_push")
set_pev(ent, pev_origin, origin)
set_pev(ent, pev_speed, -pushForce)

dllfunc(DLLFunc_Spawn, ent)
engfunc(EngFunc_SetSize, ent, mins, maxs)

return ent
}

public CTriggerPush_Touch(const entity, const other) {
if (!IsActive())
return HAM_SUPERCEDE

if (pev_valid(other) != 2)
return HAM_IGNORED

return CBarrier_Touch(entity, other)
}

static CBarrier_Touch(const entity, const other) {
if (!redm_aim_barrier)
return HAM_SUPERCEDE

static Float: velocity[3]
pev(other, pev_velocity, velocity)

set_pev(entity, pev_movedir, velocity)

if (redm_aim_barrier_always_show == 2) {
new Float: gameTime = get_gametime()

static Float: nextEffctsTime
if (nextEffctsTime > gameTime)
return HAM_IGNORED

const Float: drawDelay = 0.5
nextEffctsTime = gameTime + drawDelay

CBarrier_Draw(entity, other, drawDelay)
}

return HAM_IGNORED
}

static CBarrier_Draw(const entity, const toucher, const Float: drawDelay) {
static Float: origin[3]
pev(entity, pev_origin, origin)

static Float: tourcherOrigin[3]
tourcherOrigin = origin
if (toucher) {
pev(toucher, pev_absmin, tourcherOrigin)
tourcherOrigin[XS_Z] += 10
}

static Float: mins[3]
pev(entity, pev_mins, mins)

static Float: maxs[3]
pev(entity, pev_maxs, maxs)

static Float: start[3]
xs_vec_copy(origin, start)

static Float: end[3]
xs_vec_copy(origin, end)

new longerAxis = floatabs(origin[XS_X] - mins[XS_X]) > floatabs(origin[XS_Y] - mins[XS_Y])

start[!longerAxis] -= mins[!longerAxis]
end[!longerAxis] -= maxs[!longerAxis]
start[XS_Z] = end[XS_Z] = ((tourcherOrigin[XS_Z]) + (mins[XS_Z] * 2))

new s[3], e[3]
FVecIVec(start, s)
FVecIVec(end, e)

new Float: overlap = 0.0 // -0.8
new lifeTime = floatround((drawDelay + overlap) * 10, floatround_ceil)
te_create_beam_between_points(
s, e,
g_spriteLaserbeam,
0,
30,
lifeTime,
255,
.r = 100, .g = 0, .b = 0,
.speed = 3,
.noise = 0
)

te_create_bubble_line(s, e, g_spriteBubble, 255, .height = 1000, .randomness = true)
}

public BarrierRedraw(const entity) {
if (redm_aim_barrier_always_show != 1)
return

CBarrier_Draw(entity, 0, BARRIER_REDRAW_TIME)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include "ReDeathmatch/Features/AimBarriers.inc"

static g_fwdPrecacheEvent = -1
static g_gunsEventsId
static g_oldGroupinfo[MAX_PLAYERS + 1]
Expand All @@ -19,6 +21,8 @@ static redm_protection_color_ct[32]
static bool: mp_respawn_immunity_effects

Features_Precache() {
AimBarriers_Precache()

g_fwdPrecacheEvent = register_forward(FM_PrecacheEvent , "PrecacheEvent_Post", ._post = true)
}

Expand All @@ -40,6 +44,8 @@ Features_Init() {
RegisterHookChain(RG_CBasePlayer_RemoveSpawnProtection, "CBasePlayer_RemoveSpawnProtection", .post = true)
RegisterHookChain(RG_CBasePlayer_DropPlayerItem, "CBasePlayer_DropPlayerItem", .post = false)

AimBarriers_Init()

bind_pcvar_num(
create_cvar(
"redm_open_equip_menu_by_g", "1",
Expand Down
Loading
Loading