Skip to content

Instantly share code, notes, and snippets.

@rsKliPPy
Created December 25, 2015 01:14
Show Gist options
  • Save rsKliPPy/72535fa2a81e1eba99c0 to your computer and use it in GitHub Desktop.
Save rsKliPPy/72535fa2a81e1eba99c0 to your computer and use it in GitHub Desktop.
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <engine>
#if AMXX_VERSION_NUM < 183
#include <dhudmessage>
#endif
#if AMXX_VERSION_NUM >= 175
#pragma reqlib cq_ents
#if !defined AMXMODX_NOAUTOLOAD
#pragma loadlib cq_ents
#endif
#else
#pragma library cq_ents
#endif
#pragma semicolon true
#pragma ctrlchar '\'
#define String: _:
#define pev_range pev_fuser1
#define pev_points pev_iuser2
#define pev_uncap pev_iuser3
#define pev_basecolors pev_iuser4
/* ----- SETTINGS ------ */
const Float: g_BaseThinkRate = 0.5; // How often do base points get evaluated (tickrate)
const g_BaseMaxPoints = 100; // Points required for a base to be captured
const g_PointsPerTick = 5; // Points per player per tick
const Float: g_BaseHUDPosX = -1.0; // Base points HUD X coordinate
const Float: g_BaseHUDPosY = 0.02; // Base points HUD Y coordinate
const Float: g_HUDMessageRate = 1.0; // How often does info HUD message get shown and team points get evaluated
const Float: g_MessageHUDPosX = 0.02; // Info HUD message X coordinate
const Float: g_MessageHUDPosY = 0.23; // Info HUD message Y coordinate
const g_PointsToWin = 1500; // Points to win the game
const g_PointsPerBase = 1; // Points per owned base per tick
/* --------------------- */
new const PLUGIN_NAME[] = "Conquest Mode";
new const PLUGIN_VERSION[] = "v1.0.0beta";
new const PLUGIN_AUTHOR[] = "KliPPy";
new const Float: g_TeamColors[3][3] = {
{255.0, 255.0, 255.0},
{255.0, 0.0, 0.0},
{0.0, 0.0, 255.0}
};
const g_TenthMaxPoints = g_BaseMaxPoints / 10;
new Array: colorsArrayTracker = Invalid_Array;
new Array: baseEntities = Invalid_Array;
new g_CTPoints = 0;
new g_TTPoints = 0;
public plugin_init() {
register_plugin(
PLUGIN_NAME,
PLUGIN_VERSION,
PLUGIN_AUTHOR
);
log_amx("The server is running %s %s by %s.", PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
register_cvar("conquest_mode", PLUGIN_VERSION, FCVAR_SERVER | FCVAR_SPONLY);
InitializeBases();
}
public plugin_precache() {
new szMapName[10];
get_mapname(szMapName, charsmax(szMapName));
if(!equali(szMapName, "conquest_")) {
pause("ad");
}
new ent = FM_NULLENT;
if(!pev_valid((ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))))) {
log_amx("Failed to create conquest_hudmessage entity... Pausing the plugin.");
pause("ad");
}
set_pev(ent, pev_classname, "conquest_hudmessage");
set_pev(ent, pev_nextthink, get_gametime() + g_HUDMessageRate);
register_forward(FM_KeyValue, "OnDispatchKeyValue", false);
RegisterHam(Ham_Spawn, "conquest_base"/*, "conquest_base_spawn"*/, "CqBase_Spawn", true);
RegisterHam(Ham_Spawn, "conquest_base_color", "CqBaseColor_Spawn", true);
register_think("conquest_base", "CqBase_Think");
register_think("conquest_hudmessage", "CqHUDMessage_Think");
colorsArrayTracker = ArrayCreate();
baseEntities = ArrayCreate();
}
public OnDispatchKeyValue(ent, pkvd) {
if(!pev_valid(ent) || !pkvd) {
return FMRES_IGNORED;
}
new String: className[32];
get_kvd(pkvd, KV_ClassName, className, charsmax(className));
if(equali(className, "conquest_base")) {
new String: key[16];
get_kvd(pkvd, KV_KeyName, key, charsmax(key));
if(equali(key, "range")) {
new String: value[16];
get_kvd(pkvd, KV_Value, value, charsmax(value));
set_pev(ent, pev_range, str_to_float(value));
set_kvd(pkvd, KV_fHandled, true);
return FMRES_SUPERCEDE;
}
else if(equali(key, "uncap")) {
new String: value[16];
new uncap;
get_kvd(pkvd, KV_Value, value, charsmax(value));
uncap = str_to_num(value);
set_pev(ent, pev_uncap, uncap);
set_kvd(pkvd, KV_fHandled, true);
return FMRES_SUPERCEDE;
}
}
return FMRES_IGNORED;
}
public CqBase_Spawn(this) {
if(!pev_valid(this)) {
return HAM_IGNORED;
}
new String: className[32];
pev(this, pev_classname, className, charsmax(className));
if(equal(className, "conquest_base")) {
set_pev(this, pev_nextthink, get_gametime() + g_BaseThinkRate);
switch(pev(this, pev_team)) {
case 1: set_pev(this, pev_points, g_BaseMaxPoints);
case 2: set_pev(this, pev_points, g_BaseMaxPoints * (-1)); // (-g_BaseMaxPoints) doesn't work O.o Compiler bug...
default: set_pev(this, pev_points, 0);
}
new uncap = pev(this, pev_uncap);
if(uncap != 0) {
set_pev(this, pev_team, uncap);
}
ArrayPushCell(baseEntities, this);
}
else if(equal(className, "conquest_base_spawn")) {
}
return HAM_IGNORED;
}
public CqBaseColor_Spawn(this) {
if(!pev_valid(this)) {
return HAM_IGNORED;
}
new String: className[32];
pev(this, pev_classname, className, charsmax(className));
if(equal(className, "conquest_base_color")) {
set_pev(this, pev_rendermode, kRenderTransColor);
set_pev(this, pev_renderamt, 255.0);
}
return HAM_IGNORED;
}
public CqBase_Think(this) {
if(!pev_valid(this)) {
return PLUGIN_CONTINUE;
}
if(pev(this, pev_uncap) != 0) {
return PLUGIN_CONTINUE;
}
new String: progressBar[] = "----------|----------";
new players[32], num;
new Float: pOrigin[3];
new Float: bOrigin[3];
new Float: baseRange;
new oldPoints;
new id;
new pointsToAdd = 0;
get_players(players, num, "a");
pev(this, pev_origin, bOrigin);
pev(this, pev_range, baseRange);
if(num > 0) {
oldPoints = pev(this, pev_points);
new baseTeam = pev(this, pev_team);
new charsToSet = 10 + (oldPoints / g_TenthMaxPoints);
if(charsToSet > 10) {
for(new i = 11; i <= charsToSet; i++) {
progressBar[i] = '=';
}
}
else {
for(new i = 9; i >= charsToSet; i--) {
progressBar[i] = '=';
}
}
set_dhudmessage(floatround(g_TeamColors[baseTeam][0]), floatround(g_TeamColors[baseTeam][1]), floatround(g_TeamColors[baseTeam][2]),
g_BaseHUDPosX, g_BaseHUDPosY, 0, 0.0, g_BaseThinkRate, 0.0, 0.1);
for(new i = 0; i < num; i++) {
id = players[i];
pev(id, pev_origin, pOrigin);
if(get_distance_f(bOrigin, pOrigin) < baseRange) {
if(get_user_team(id) == 1) {
pointsToAdd += g_PointsPerTick;
}
else {
pointsToAdd -= g_PointsPerTick;
}
show_dhudmessage(id, "CT [%s] TT", progressBar);
}
}
// Update only if the state changed
if(pointsToAdd != 0) {
new points = clamp(oldPoints + pointsToAdd, -g_BaseMaxPoints, g_BaseMaxPoints);
if(oldPoints != points) {
set_pev(this, pev_points, points);
new Array: colorsArray = Array: pev(this, pev_basecolors);
new size = ArraySize(colorsArray);
new colorToSet;
for(new i = 0; i < size; i++) {
if(points == g_BaseMaxPoints) {
colorToSet = 1;
}
else if(points == -g_BaseMaxPoints) {
colorToSet = 2;
}
else {
colorToSet = 0;
}
set_pev(ArrayGetCell(colorsArray, i), pev_rendercolor, g_TeamColors[colorToSet]);
set_pev(this, pev_team, colorToSet);
}
}
}
}
set_pev(this, pev_nextthink, get_gametime() + g_BaseThinkRate);
return PLUGIN_CONTINUE;
}
public CqHUDMessage_Think(this) {
if(!pev_valid(this)) {
return PLUGIN_CONTINUE;
}
new CTBaseCount, TTBaseCount, BaseCount;
new baseEnt = FM_NULLENT;
new baseTeam;
BaseCount = ArraySize(baseEntities);
for(new i = 0; i < BaseCount; i++) {
baseEnt = ArrayGetCell(baseEntities, i);
baseTeam = pev(baseEnt, pev_team);
if(baseTeam == 1) {
TTBaseCount++;
}
else if(baseTeam == 2) {
CTBaseCount++;
}
}
g_CTPoints = min(g_CTPoints + CTBaseCount * g_PointsPerBase, g_PointsToWin);
g_TTPoints = min(g_TTPoints + TTBaseCount * g_PointsPerBase, g_PointsToWin);
CheckForWin();
set_dhudmessage(floatround(g_TeamColors[0][0]), floatround(g_TeamColors[0][1]), floatround(g_TeamColors[0][2]),
g_MessageHUDPosX, g_MessageHUDPosY, 0, 0.0, g_HUDMessageRate, 0.0, 0.1);
show_dhudmessage(0, "CT Bases: %i / %i\nCT Points: %i / %i\nTT Bases: %i / %i\nTT Points: %i / %i",
CTBaseCount, BaseCount, g_CTPoints, g_PointsToWin, TTBaseCount, BaseCount, g_TTPoints, g_PointsToWin);
set_pev(this, pev_nextthink, get_gametime() + g_HUDMessageRate);
return PLUGIN_CONTINUE;
}
InitializeBases() {
new entBase = FM_NULLENT;
new entColor = FM_NULLENT;
new String: colorName[32];
new Array: baseColors = Invalid_Array; // We use this to remember bases' colors, so we don't have to search every time
while((entBase = engfunc(EngFunc_FindEntityByString, entBase, "classname", "conquest_base"))) {
pev(entBase, pev_target, colorName, charsmax(colorName));
baseColors = ArrayCreate();
while((entColor = engfunc(EngFunc_FindEntityByString, entColor, "targetname", colorName))) {
set_pev(entColor, pev_rendercolor, g_TeamColors[pev(entBase, pev_team)]);
ArrayPushCell(baseColors, entColor);
}
if(ArraySize(baseColors) != 0) {
ArrayPushCell(colorsArrayTracker, baseColors);
set_pev(entBase, pev_basecolors, baseColors);
}
else {
ArrayDestroy(baseColors);
}
}
}
CheckForWin() {
new bool: win = false;
if(g_TTPoints >= g_PointsToWin) {
// Terrorist win
win = true;
}
else if(g_CTPoints >= g_PointsToWin) {
// CT Win
win = true;
}
if(win) {
new szMapName[32];
get_cvar_string("amx_nextmap", szMapName, charsmax(szMapName));
if(!szMapName[0]) {
get_mapname(szMapName, charsmax(szMapName));
}
server_cmd("changelevel %s", szMapName);
}
}
public plugin_end() {
new size = ArraySize(colorsArrayTracker);
new Array: arr;
for(new i = 0; i < size; i++) {
// We have to store it into a variable, ArrayDestroy takes a reference... bleh
arr = ArrayGetCell(colorsArrayTracker, i);
ArrayDestroy(arr);
}
ArrayDestroy(colorsArrayTracker);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment