set g_ctf_oneflag 1 "Allow oneflag CTF mode on maps that support it"
set g_ctf_oneflag_reverse 0 "apply reverse mode to oneflag CTF (take flag to enemy bases to cap), overrides g_ctf_reverse only in oneflag, g_ctf_reverse still affects oneflag"
set g_ctf_flag_return 1 "auto return the flag to base when touched by a teammate"
+set g_ctf_flag_return_carrying 0 "(manual return mode) auto return the flag to base if touched by a flag carrier"
set g_ctf_flag_return_carried_radius 100 "allow flags to be returned by carrier if base is within this radius"
set g_ctf_flag_return_time 15
set g_ctf_flag_return_dropped 100
return ret;
}
+entity announcer_countdown;
+
void Announcer_Countdown()
{
SELFPARAM();
{
Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_ROUNDSTOP);
remove(this);
+ announcer_countdown = NULL;
return;
}
if(roundstarttime >= starttime)
Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_BEGIN);
Local_Notification(MSG_MULTI, MULTI_COUNTDOWN_BEGIN);
remove(this);
+ announcer_countdown = NULL;
return;
}
else // countdown is still going
{
if(time < startTime)
{
- static entity announcer_countdown;
if (!announcer_countdown)
{
announcer_countdown = new(announcer_countdown);
// only if this failed, find it out on our own
entity e = spawn();
+ precache_model(autocvar__cl_playermodel);
_setmodel(e, autocvar__cl_playermodel); // this is harmless, see below
forceplayermodels_modelisgoodmodel = fexists(e.model);
forceplayermodels_model = e.model;
#include "scoreboard.qh"
#include "teamradar.qh"
#include "t_items.qh"
-#include "../common/buffs/all.qh"
#include "../common/deathtypes/all.qh"
#include "../common/items/all.qc"
#include "../common/mapinfo.qh"
#include "../common/mutators/mutator/waypoints/all.qh"
-#include "../common/nades/all.qh"
#include "../common/stats.qh"
#include "../lib/csqcmodel/cl_player.qh"
// TODO: remove
REGISTRY(hud_panels, BITS(6))
#define hud_panels_from(i) _hud_panels_from(i, NULL)
-REGISTER_REGISTRY(Registerhud_panels)
+REGISTER_REGISTRY(hud_panels)
#define REGISTER_HUD_PANEL(id, draw_func, name, configflags, showflags) \
void draw_func(); \
- REGISTER(Registerhud_panels, HUD_PANEL, hud_panels, id, m_id, new(hud_panel)) { \
+ REGISTER(hud_panels, HUD_PANEL, id, m_id, new(hud_panel)) { \
make_pure(this); \
this.panel_id = this.m_id; \
this.panel_draw = draw_func; \
autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
}
-void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expand_time)
-{
- float bonusNades = getstatf(STAT_NADE_BONUS);
- float bonusProgress = getstatf(STAT_NADE_BONUS_SCORE);
- float bonusType = getstati(STAT_NADE_BONUS_TYPE);
- Nade def = Nades_from(bonusType);
- vector nadeColor = def.m_color;
- string nadeIcon = def.m_icon;
-
- vector iconPos, textPos;
-
- if(autocvar_hud_panel_ammo_iconalign)
- {
- iconPos = myPos + eX * 2 * mySize.y;
- textPos = myPos;
- }
- else
- {
- iconPos = myPos;
- textPos = myPos + eX * mySize.y;
- }
-
- if(bonusNades > 0 || bonusProgress > 0)
- {
- DrawNadeProgressBar(myPos, mySize, bonusProgress, nadeColor);
-
- if(autocvar_hud_panel_ammo_text)
- drawstring_aspect(textPos, ftos(bonusNades), eX * (2/3) * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
-
- if(draw_expanding)
- drawpic_aspect_skin_expanding(iconPos, nadeIcon, '1 1 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, expand_time);
-
- drawpic_aspect_skin(iconPos, nadeIcon, '1 1 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- }
-}
+void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expand_time); // TODO: mutator
void DrawAmmoItem(vector myPos, vector mySize, .int ammoType, bool isCurrent, bool isInfinite)
{
if(superTime)
addPowerupItem("Superweapons", "superweapons", autocvar_hud_progressbar_superweapons_color, superTime, 30);
- FOREACH(Buffs, it.m_itemid & allBuffs, LAMBDA(
- addPowerupItem(it.m_prettyName, strcat("buff_", it.m_name), it.m_color, bound(0, getstatf(STAT_BUFF_TIME) - time, 99), 60);
- ));
+ MUTATOR_CALLHOOK(HUD_Powerups_add);
if(!powerupItemsCount)
return;
// CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
// The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS.
-void CSQC_Ent_Update(float bIsNewEntity)
+void CSQC_Ent_Update(bool isnew)
{
SELFPARAM();
this.sourceLocLine = __LINE__;
}
#ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
- if(this.enttype)
+ if (this.enttype)
{
- if(t != this.enttype || bIsNewEntity)
+ if (t != this.enttype || isnew)
{
LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(this), this.entnum, this.enttype, t);
Ent_Remove();
clearentity(this);
- bIsNewEntity = 1;
+ isnew = true;
}
}
else
{
- if(!bIsNewEntity)
+ if (!isnew)
{
LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(this), this.entnum, t);
- bIsNewEntity = 1;
+ isnew = true;
}
}
#endif
this.enttype = t;
bool done = false;
FOREACH(LinkedEntities, it.m_id == t, LAMBDA(
- this.classname = it.netname;
+ if (isnew) this.classname = it.netname;
if (autocvar_developer_csqcentities)
- LOG_INFOF("CSQC_Ent_Update(%d) with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)\n", bIsNewEntity, this, this.entnum, this.enttype, it.netname, t);
- done = it.m_read(this, bIsNewEntity);
+ LOG_INFOF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)\n", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
+ done = it.m_read(this, isnew);
break;
));
time = savetime;
if (!done)
{
- //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), this.enttype));
- error(sprintf("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n", this.enttype, num_for_edict(this), this.classname));
+ LOG_FATALF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)\n", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
}
}
MUTATOR_HOOKABLE(AnnouncerOption, EV_AnnouncerOption);
MUTATOR_HOOKABLE(Ent_Init, EV_NO_ARGS);
+
+#define EV_HUD_Draw_overlay(i, o) \
+ /**/ o(vector, MUTATOR_ARGV_0_vector) \
+ /**/ o(float, MUTATOR_ARGV_0_float) \
+ /**/
+MUTATOR_HOOKABLE(HUD_Draw_overlay, EV_HUD_Draw_overlay);
+
+MUTATOR_HOOKABLE(HUD_Powerups_add, EV_NO_ARGS);
+
+/** Return true to not draw any vortex beam */
+#define EV_Particles_VortexBeam(i, o) \
+ /**/ i(vector, vbeam_shotorg) \
+ /**/ i(vector, vbeam_endpos) \
+ /**/
+vector vbeam_shotorg;
+vector vbeam_endpos;
+MUTATOR_HOOKABLE(Particles_VortexBeam, EV_Particles_VortexBeam);
+
+/** Return true to not draw any impact effect */
+#define EV_Weapon_ImpactEffect(i, o) \
+ /**/ i(entity, w_hitwep) \
+ /**/
+entity w_hitwep;
+MUTATOR_HOOKABLE(Weapon_ImpactEffect, EV_Weapon_ImpactEffect);
+
#endif
#include "../common/minigames/minigames.qc"
#include "../common/minigames/cl_minigames.qc"
-#include "../common/buffs/all.qc"
#include "../common/deathtypes/all.qc"
#include "../common/effects/all.qc"
#include "../common/gamemodes/all.qc"
#include "../common/items/all.qc"
#include "../common/monsters/all.qc"
#include "../common/mutators/all.qc"
-#include "../common/nades/all.qc"
#include "../common/turrets/all.qc"
#include "../common/vehicles/all.qc"
#include "../common/weapons/all.qc"
-#include "../common/buffs/all.qh"
#include "../common/movetypes/movetypes.qh"
#include "../common/weapons/all.qh"
#include "../lib/csqcmodel/cl_model.qh"
#include "../common/debug.qh"
#include "../common/mapinfo.qh"
#include "../common/gamemodes/all.qh"
-#include "../common/nades/all.qh"
#include "../common/stats.qh"
#include "../common/triggers/target/music.qh"
#include "../common/teams.qh"
void HUD_Draw()
{
- if(getstati(STAT_FROZEN))
- drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, ((getstatf(STAT_REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * getstatf(STAT_REVIVE_PROGRESS)) + ('0 1 1' * getstatf(STAT_REVIVE_PROGRESS) * -1)) : '0.25 0.90 1'), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
- else if (getstatf(STAT_HEALING_ORB)>time)
- drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, NADE_TYPE_HEAL.m_color, autocvar_hud_colorflash_alpha*getstatf(STAT_HEALING_ORB_ALPHA), DRAWFLAG_ADDITIVE);
+ vector rgb = '0 0 0';
+ float a = 1;
+ if (MUTATOR_CALLHOOK(HUD_Draw_overlay))
+ {
+ rgb = MUTATOR_ARGV(0, vector);
+ a = MUTATOR_ARGV(0, float);
+ }
+ else if(getstati(STAT_FROZEN))
+ {
+ rgb = ((getstatf(STAT_REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * getstatf(STAT_REVIVE_PROGRESS)) + ('0 1 1' * getstatf(STAT_REVIVE_PROGRESS) * -1)) : '0.25 0.90 1');
+ }
+ drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, rgb, autocvar_hud_colorflash_alpha * a, DRAWFLAG_ADDITIVE);
if(!intermission)
if(getstatf(STAT_NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death
{
#include "../../common/constants.qh"
#include "../../common/movetypes/movetypes.qh"
-#include "../../common/nades/all.qh"
#include "../../lib/csqcmodel/interpolate.qh"
}
}
+bool Projectile_isnade(int proj); // TODO: remove
+
void Projectile_Draw(entity this)
{
vector rot;
break;
}
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
+ if (Projectile_isnade(self.cnt))
rot = self.avelocity;
self.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(self.angles), rot * (t - self.spawntime)));
break;
}
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
+ if (Projectile_isnade(self.cnt))
trailorigin += v_up * 4;
if (drawn)
CASE(HOOKBOMB) self.traileffect = EFFECT_TR_KNIGHTSPIKE.m_id; break;
CASE(HAGAR) self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
CASE(HAGAR_BOUNCING) self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
- CASE(NAPALM_FOUNTAIN) // fallthrough // sself.modelindex = 0; self.traileffect = _particleeffectnum("torch_small"); break;
CASE(FIREBALL) self.modelindex = 0; self.traileffect = EFFECT_FIREBALL.m_id; break; // particle effect is good enough
CASE(FIREMINE) self.modelindex = 0; self.traileffect = EFFECT_FIREMINE.m_id; break; // particle effect is good enough
CASE(TAG) self.traileffect = EFFECT_TR_ROCKET.m_id; break;
if (MUTATOR_CALLHOOK(Ent_Projectile, self))
break;
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
- {
- setmodel(self, MDL_PROJECTILE_NADE);
- entity trail = Nade_TrailEffect(self.cnt, self.team);
- if (trail.eent_eff_name) self.traileffect = trail.m_id;
- break;
- }
error("Received invalid CSQC projectile, can't work with this!");
break;
}
self.move_movetype = MOVETYPE_BOUNCE;
self.move_touch = func_null;
break;
- case PROJECTILE_NAPALM_FOUNTAIN:
case PROJECTILE_FIREBALL:
loopsound(self, CH_SHOTS_SINGLE, SND(FIREBALL_FLY2), VOL_BASE, ATTEN_NORM);
self.mins = '-16 -16 -16';
break;
}
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
- {
- entity nade_type = Nade_FromProjectile(self.cnt);
- self.mins = '-16 -16 -16';
- self.maxs = '16 16 16';
- self.colormod = nade_type.m_color;
- self.move_movetype = MOVETYPE_BOUNCE;
- self.move_touch = func_null;
- self.scale = 1.5;
- self.avelocity = randomvec() * 720;
-
- if (nade_type == NADE_TYPE_TRANSLOCATE || nade_type == NADE_TYPE_SPAWN)
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
- else
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
- }
-
MUTATOR_CALLHOOK(EditProjectile, self);
setsize(self, self.mins, self.maxs);
+++ /dev/null
-REGISTER_BUFF(AMMO) {
- this.m_prettyName = _("Ammo");
- this.m_name = "ammo";
- this.m_skin = 3;
- this.m_color = '0.76 1 0.1';
-}
-BUFF_SPAWNFUNCS(ammo, BUFF_AMMO)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(ammoregen, BUFF_AMMO)
-
-REGISTER_BUFF(RESISTANCE) {
- this.m_prettyName = _("Resistance");
- this.m_name = "resistance";
- this.m_skin = 0;
- this.m_color = '0.36 1 0.07';
-}
-BUFF_SPAWNFUNCS(resistance, BUFF_RESISTANCE)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(resistance, BUFF_RESISTANCE)
-
-REGISTER_BUFF(SPEED) {
- this.m_prettyName = _("Speed");
- this.m_name = "speed";
- this.m_skin = 9;
- this.m_color = '0.1 1 0.84';
-}
-BUFF_SPAWNFUNCS(speed, BUFF_SPEED)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(haste, BUFF_SPEED)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(scout, BUFF_SPEED)
-
-REGISTER_BUFF(MEDIC) {
- this.m_prettyName = _("Medic");
- this.m_name = "medic";
- this.m_skin = 1;
- this.m_color = '1 0.12 0';
-}
-BUFF_SPAWNFUNCS(medic, BUFF_MEDIC)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(doubler, BUFF_MEDIC)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(medic, BUFF_MEDIC)
-
-REGISTER_BUFF(BASH) {
- this.m_prettyName = _("Bash");
- this.m_name = "bash";
- this.m_skin = 5;
- this.m_color = '1 0.39 0';
-}
-BUFF_SPAWNFUNCS(bash, BUFF_BASH)
-
-REGISTER_BUFF(VAMPIRE) {
- this.m_prettyName = _("Vampire");
- this.m_name = "vampire";
- this.m_skin = 2;
- this.m_color = '1 0 0.24';
-}
-BUFF_SPAWNFUNCS(vampire, BUFF_VAMPIRE)
-
-REGISTER_BUFF(DISABILITY) {
- this.m_prettyName = _("Disability");
- this.m_name = "disability";
- this.m_skin = 7;
- this.m_color = '0.94 0.3 1';
-}
-BUFF_SPAWNFUNCS(disability, BUFF_DISABILITY)
-
-REGISTER_BUFF(VENGEANCE) {
- this.m_prettyName = _("Vengeance");
- this.m_name = "vengeance";
- this.m_skin = 15;
- this.m_color = '1 0.23 0.61';
-}
-BUFF_SPAWNFUNCS(vengeance, BUFF_VENGEANCE)
-
-REGISTER_BUFF(JUMP) {
- this.m_prettyName = _("Jump");
- this.m_name = "jump";
- this.m_skin = 10;
- this.m_color = '0.24 0.78 1';
-}
-BUFF_SPAWNFUNCS(jump, BUFF_JUMP)
-
-REGISTER_BUFF(FLIGHT) {
- this.m_prettyName = _("Flight");
- this.m_name = "flight";
- this.m_skin = 11;
- this.m_color = '0.33 0.56 1';
-}
-BUFF_SPAWNFUNCS(flight, BUFF_FLIGHT)
-
-REGISTER_BUFF(INVISIBLE) {
- this.m_prettyName = _("Invisible");
- this.m_name = "invisible";
- this.m_skin = 12;
- this.m_color = '0.5 0.5 1';
-}
-BUFF_SPAWNFUNCS(invisible, BUFF_INVISIBLE)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(invis, BUFF_INVISIBLE)
-
-REGISTER_BUFF(INFERNO) {
- this.m_prettyName = _("Inferno");
- this.m_name = "inferno";
- this.m_skin = 16;
- this.m_color = '1 0.62 0';
-}
-BUFF_SPAWNFUNCS(inferno, BUFF_INFERNO)
-
-REGISTER_BUFF(SWAPPER) {
- this.m_prettyName = _("Swapper");
- this.m_name = "swapper";
- this.m_skin = 17;
- this.m_color = '0.63 0.36 1';
-}
-BUFF_SPAWNFUNCS(swapper, BUFF_SWAPPER)
-
-REGISTER_BUFF(MAGNET) {
- this.m_prettyName = _("Magnet");
- this.m_name = "magnet";
- this.m_skin = 18;
- this.m_color = '1 0.95 0.18';
-}
-BUFF_SPAWNFUNCS(magnet, BUFF_MAGNET)
+++ /dev/null
-#if defined(CSQC)
- #include "../../client/defs.qh"
-#elif defined(MENUQC)
-#elif defined(SVQC)
-#endif
-#include "all.qh"
-
+++ /dev/null
-#ifndef BUFFS_ALL_H
-#define BUFFS_ALL_H
-// Welcome to the stuff behind the scenes
-// Below, you will find the list of buffs
-// Add new buffs here!
-// Note: Buffs also need spawnfuncs, which are set below
-
-#include "../teams.qh"
-#include "../util.qh"
-
-REGISTRY(Buffs, BITS(4))
-#define Buffs_from(i) _Buffs_from(i, BUFF_Null)
-REGISTER_REGISTRY(RegisterBuffs)
-REGISTRY_CHECK(Buffs)
-
-#define REGISTER_BUFF(id) \
- REGISTER(RegisterBuffs, BUFF, Buffs, id, m_id, NEW(Buff)); \
- REGISTER_INIT_POST(BUFF, id) { \
- this.netname = this.m_name; \
- this.m_itemid = BIT(this.m_id - 1); \
- this.m_sprite = strzone(strcat("buff-", this.m_name)); \
- } \
- REGISTER_INIT(BUFF, id)
-
-#include "../items/item/pickup.qh"
-CLASS(Buff, Pickup)
- /** bit index */
- ATTRIB(Buff, m_itemid, int, 0)
- ATTRIB(Buff, m_name, string, "buff")
- ATTRIB(Buff, m_color, vector, '1 1 1')
- ATTRIB(Buff, m_prettyName, string, "Buff")
- ATTRIB(Buff, m_skin, int, 0)
- ATTRIB(Buff, m_sprite, string, "")
- METHOD(Buff, display, void(entity this, void(string name, string icon) returns)) {
- returns(this.m_prettyName, sprintf("/gfx/hud/%s/buff_%s", cvar_string("menu_skin"), this.m_name));
- }
-#ifdef SVQC
- METHOD(Buff, m_time, float(entity));
- float Buff_m_time(entity this) { return cvar(strcat("g_buffs_", this.netname, "_time")); }
-#endif
-ENDCLASS(Buff)
-
-#ifdef SVQC
- .int buffs;
- void buff_Init(entity ent);
- void buff_Init_Compat(entity ent, entity replacement);
- #define BUFF_SPAWNFUNC(e, b, t) spawnfunc(item_buff_##e) { \
- self.buffs = b.m_itemid; \
- self.team = t; \
- buff_Init(self); \
- }
- #define BUFF_SPAWNFUNCS(e, b) \
- BUFF_SPAWNFUNC(e, b, 0) \
- BUFF_SPAWNFUNC(e##_team1, b, NUM_TEAM_1) \
- BUFF_SPAWNFUNC(e##_team2, b, NUM_TEAM_2) \
- BUFF_SPAWNFUNC(e##_team3, b, NUM_TEAM_3) \
- BUFF_SPAWNFUNC(e##_team4, b, NUM_TEAM_4)
- #define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r) spawnfunc(item_##o) { buff_Init_Compat(self, r); }
-#else
- #define BUFF_SPAWNFUNC(e, b, t)
- #define BUFF_SPAWNFUNCS(e, b)
- #define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r)
-#endif
-
-REGISTER_BUFF(Null);
-BUFF_SPAWNFUNCS(random, BUFF_Null)
-
-#include "all.inc"
-
-#endif
#include "command.qh"
REGISTRY(GENERIC_COMMANDS, BITS(7))
#define GENERIC_COMMANDS_from(i) _GENERIC_COMMANDS_from(i, NULL)
-REGISTER_REGISTRY(RegisterGENERIC_COMMANDS)
-REGISTRY_SORT(GENERIC_COMMANDS, 0)
+REGISTER_REGISTRY(GENERIC_COMMANDS)
+REGISTRY_SORT(GENERIC_COMMANDS)
#define GENERIC_COMMAND(id, description) \
CLASS(genericcommand_##id, Command) \
ATTRIB(genericcommand_##id, m_name, string, #id); \
ATTRIB(genericcommand_##id, m_description, string, description); \
ENDCLASS(genericcommand_##id) \
- REGISTER(RegisterGENERIC_COMMANDS, CMD_G, GENERIC_COMMANDS, id, m_id, NEW(genericcommand_##id)); \
+ REGISTER(GENERIC_COMMANDS, CMD_G, id, m_id, NEW(genericcommand_##id)); \
METHOD(genericcommand_##id, m_invokecmd, void(int request, int arguments, string command))
STATIC_INIT(GENERIC_COMMANDS_aliases) {
REGISTRY(Deathtypes, BITS(8))
#define Deathtypes_from(i) _Deathtypes_from(i, NULL)
-REGISTER_REGISTRY(RegisterDeathtypes)
+REGISTER_REGISTRY(Deathtypes)
REGISTRY_CHECK(Deathtypes)
.entity death_msgself;
.string death_msgextra;
#define REGISTER_DEATHTYPE(id, msg_death, msg_death_by, extra) \
- REGISTER(RegisterDeathtypes, DEATH, Deathtypes, id, m_id, new(deathtype)) { \
+ REGISTER(Deathtypes, DEATH, id, m_id, new(deathtype)) { \
make_pure(this); \
this.m_id += DT_FIRST; \
this.nent_name = #id; \
EFFECT(0, SPAWNPOINT_NEUTRAL, "spawn_point_neutral")
EFFECT(0, SPAWN_NEUTRAL, "spawn_event_neutral")
-EFFECT(0, NADE_EXPLODE_RED, "nade_red_explode")
-EFFECT(0, NADE_EXPLODE_BLUE, "nade_blue_explode")
-EFFECT(0, NADE_EXPLODE_YELLOW, "nade_yellow_explode")
-EFFECT(0, NADE_EXPLODE_PINK, "nade_pink_explode")
-EFFECT(0, NADE_EXPLODE_NEUTRAL, "nade_neutral_explode")
-entity EFFECT_NADE_EXPLODE(int teamid)
-{
- switch (teamid) {
- case NUM_TEAM_1: return EFFECT_NADE_EXPLODE_RED;
- case NUM_TEAM_2: return EFFECT_NADE_EXPLODE_BLUE;
- case NUM_TEAM_3: return EFFECT_NADE_EXPLODE_YELLOW;
- case NUM_TEAM_4: return EFFECT_NADE_EXPLODE_PINK;
- default: return EFFECT_NADE_EXPLODE_NEUTRAL;
- }
-}
-
-EFFECT(1, NADE_TRAIL_RED, "nade_red")
-EFFECT(1, NADE_TRAIL_BLUE, "nade_blue")
-EFFECT(1, NADE_TRAIL_YELLOW, "nade_yellow")
-EFFECT(1, NADE_TRAIL_PINK, "nade_pink")
-EFFECT(1, NADE_TRAIL_NEUTRAL, "nade_neutral")
-entity EFFECT_NADE_TRAIL(int teamid)
-{
- switch (teamid) {
- case NUM_TEAM_1: return EFFECT_NADE_TRAIL_RED;
- case NUM_TEAM_2: return EFFECT_NADE_TRAIL_BLUE;
- case NUM_TEAM_3: return EFFECT_NADE_TRAIL_YELLOW;
- case NUM_TEAM_4: return EFFECT_NADE_TRAIL_PINK;
- default: return EFFECT_NADE_TRAIL_NEUTRAL;
- }
-}
-
-EFFECT(1, NADE_TRAIL_BURN_RED, "nade_red_burn")
-EFFECT(1, NADE_TRAIL_BURN_BLUE, "nade_blue_burn")
-EFFECT(1, NADE_TRAIL_BURN_YELLOW, "nade_yellow_burn")
-EFFECT(1, NADE_TRAIL_BURN_PINK, "nade_pink_burn")
-EFFECT(1, NADE_TRAIL_BURN_NEUTRAL, "nade_neutral_burn")
-entity EFFECT_NADE_TRAIL_BURN(int teamid)
-{
- switch (teamid) {
- case NUM_TEAM_1: return EFFECT_NADE_TRAIL_BURN_RED;
- case NUM_TEAM_2: return EFFECT_NADE_TRAIL_BURN_BLUE;
- case NUM_TEAM_3: return EFFECT_NADE_TRAIL_BURN_YELLOW;
- case NUM_TEAM_4: return EFFECT_NADE_TRAIL_BURN_PINK;
- default: return EFFECT_NADE_TRAIL_BURN_NEUTRAL;
- }
-}
-
EFFECT(0, ICEORGLASS, "iceorglass")
EFFECT(0, ICEFIELD, "icefield")
EFFECT(0, FIREFIELD, "firefield")
REGISTRY(Effects, BITS(8))
#define Effects_from(i) _Effects_from(i, EFFECT_Null)
-REGISTER_REGISTRY(RegisterEffects)
+REGISTER_REGISTRY(Effects)
REGISTRY_CHECK(Effects)
#define EFFECT(istrail, name, realname) \
- REGISTER(RegisterEffects, EFFECT, Effects, name, m_id, Create_Effect_Entity(realname, istrail));
+ REGISTER(Effects, EFFECT, name, m_id, Create_Effect_Entity(realname, istrail));
EFFECT(0, Null, string_null)
#include "all.inc"
REGISTRY(EffectInfos, BITS(9))
#define EffectInfos_from(i) _EffectInfos_from(i, NULL)
-REGISTER_REGISTRY(RegisterEffectInfos)
+REGISTER_REGISTRY(EffectInfos)
#define EFFECTINFO(name) \
[[accumulate]] void effectinfo_##name(EffectInfoGroup parent, EffectInfo this) { } \
- REGISTER(RegisterEffectInfos, EFFECTINFO, EffectInfos, name, m_id, NEW(EffectInfoGroup)) { \
+ REGISTER(EffectInfos, EFFECTINFO, name, m_id, NEW(EffectInfoGroup)) { \
effectinfo_##name(this, NULL); \
}
#ifdef CSQC
#include "../../deathtypes/all.qh"
#include "../../movetypes/movetypes.qh"
+#include "../../../client/mutators/events.qh"
#include "../../vehicles/all.qh"
#include "../../weapons/all.qh"
#endif
w_backoff = -1 * normalize(force);
setorigin(self, w_org + w_backoff * 2); // for sound() calls
- if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)) {
- hitwep.wr_impacteffect(hitwep);
+ if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY))
+ {
+ if(!MUTATOR_CALLHOOK(Weapon_ImpactEffect, hitwep))
+ hitwep.wr_impacteffect(hitwep);
}
}
}
GameLogEcho(s);
}
-void ball_restart()
-{SELFPARAM();
- if(self.owner)
- DropBall(self, self.owner.origin, '0 0 0');
+void ball_restart(entity this)
+{
+ if(this.owner)
+ DropBall(this, this.owner.origin, '0 0 0');
ResetBall();
}
W_SetupProjVelocity_Basic(missile, autocvar_g_balance_nexball_secondary_speed, 0);
missile.angles = vectoangles(missile.velocity);
missile.touch = W_Nexball_Touch;
- missile.think = SUB_Remove;
+ missile.think = SUB_Remove_self;
missile.nextthink = time + autocvar_g_balance_nexball_secondary_lifetime; //FIXME: use a distance instead?
missile.effects = EF_BRIGHTFIELD | EF_LOWPRECISION;
}
}
-void ons_CaptureShield_Reset()
-{SELFPARAM();
- self.colormap = self.enemy.colormap;
- self.team = self.enemy.team;
+void ons_CaptureShield_Reset(entity this)
+{
+ this.colormap = this.enemy.colormap;
+ this.team = this.enemy.team;
}
void ons_CaptureShield_Spawn(entity generator, bool is_generator)
CSQCMODEL_AUTOUPDATE(self);
}
-void ons_ControlPoint_Reset()
-{SELFPARAM();
- if(self.goalentity)
- remove(self.goalentity);
-
- self.goalentity = world;
- self.team = 0;
- self.colormap = 1024;
- self.iscaptured = false;
- self.islinked = false;
- self.isshielded = true;
- self.think = ons_ControlPoint_Think;
- self.ons_toucher = world;
- self.nextthink = time + ONS_CP_THINKRATE;
- setmodel_fixsize(self, MDL_ONS_CP_PAD1);
-
- WaypointSprite_UpdateMaxHealth(self.sprite, 0);
- WaypointSprite_UpdateRule(self.sprite,self.team,SPRITERULE_TEAMPLAY);
+void ons_ControlPoint_Reset(entity this)
+{
+ if(this.goalentity)
+ remove(this.goalentity);
+
+ this.goalentity = world;
+ this.team = 0;
+ this.colormap = 1024;
+ this.iscaptured = false;
+ this.islinked = false;
+ this.isshielded = true;
+ this.think = ons_ControlPoint_Think;
+ this.ons_toucher = world;
+ this.nextthink = time + ONS_CP_THINKRATE;
+ setmodel_fixsize(this, MDL_ONS_CP_PAD1);
+
+ WaypointSprite_UpdateMaxHealth(this.sprite, 0);
+ WaypointSprite_UpdateRule(this.sprite,this.team,SPRITERULE_TEAMPLAY);
onslaught_updatelinks();
- activator = self;
+ activator = this;
SUB_UseTargets(); // to reset the structures, playerspawns etc.
- CSQCMODEL_AUTOUPDATE(self);
+ CSQCMODEL_AUTOUPDATE(this);
}
void ons_DelayedControlPoint_Setup()
}
}
-void ons_GeneratorReset()
-{SELFPARAM();
- self.team = self.team_saved;
- self.lasthealth = self.max_health = self.health = autocvar_g_onslaught_gen_health;
- self.takedamage = DAMAGE_AIM;
- self.bot_attack = true;
- self.iscaptured = true;
- self.islinked = true;
- self.isshielded = true;
- self.event_damage = ons_GeneratorDamage;
- self.think = ons_GeneratorThink;
- self.nextthink = time + GEN_THINKRATE;
-
- Net_LinkEntity(self, false, 0, generator_send);
-
- self.SendFlags = GSF_SETUP; // just incase
- self.SendFlags |= GSF_STATUS;
-
- WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
- WaypointSprite_UpdateHealth(self.sprite, self.health);
- WaypointSprite_UpdateRule(self.sprite,self.team,SPRITERULE_TEAMPLAY);
+void ons_GeneratorReset(entity this)
+{
+ this.team = this.team_saved;
+ this.lasthealth = this.max_health = this.health = autocvar_g_onslaught_gen_health;
+ this.takedamage = DAMAGE_AIM;
+ this.bot_attack = true;
+ this.iscaptured = true;
+ this.islinked = true;
+ this.isshielded = true;
+ this.event_damage = ons_GeneratorDamage;
+ this.think = ons_GeneratorThink;
+ this.nextthink = time + GEN_THINKRATE;
+
+ Net_LinkEntity(this, false, 0, generator_send);
+
+ this.SendFlags = GSF_SETUP; // just incase
+ this.SendFlags |= GSF_STATUS;
+
+ WaypointSprite_UpdateMaxHealth(this.sprite, this.max_health);
+ WaypointSprite_UpdateHealth(this.sprite, this.health);
+ WaypointSprite_UpdateRule(this.sprite,this.team,SPRITERULE_TEAMPLAY);
onslaught_updatelinks();
}
REGISTRY(Items, BITS(5))
#define Items_from(i) _Items_from(i, NULL)
-REGISTER_REGISTRY(RegisterItems)
+REGISTER_REGISTRY(Items)
/** If you register a new item, make sure to add it to all.inc */
-#define REGISTER_ITEM(id, class) REGISTER(RegisterItems, ITEM, Items, id, m_id, NEW(class))
+#define REGISTER_ITEM(id, class) REGISTER(Items, ITEM, id, m_id, NEW(class))
-REGISTRY_SORT(Items, 0)
+REGISTRY_SORT(Items)
REGISTRY_CHECK(Items)
STATIC_INIT(Items) { FOREACH(Items, true, LAMBDA(it.m_id = i)); }
#if defined(CSQC)
#include "../client/defs.qh"
#include "util.qh"
- #include "buffs/all.qh"
#include "weapons/all.qh"
#include "mapinfo.qh"
#elif defined(MENUQC)
#elif defined(SVQC)
#include "util.qh"
- #include "buffs/all.qh"
#include "monsters/all.qh"
#include "mapinfo.qh"
#endif
{
MapInfo_Map_flags |= MAPINFO_FLAG_NOAUTOMAPLIST;
}
+ else if(t == "gameversion_min")
+ {
+ if (cvar("gameversion") < stof(s))
+ MapInfo_Map_flags |= MAPINFO_FLAG_NOAUTOMAPLIST;
+ }
else if(t == "type")
{
t = car(s); s = cdr(s);
REGISTRY(Gametypes, BITS(4))
#define Gametypes_from(i) _Gametypes_from(i, NULL)
-REGISTER_REGISTRY(RegisterGametypes)
+REGISTER_REGISTRY(Gametypes)
REGISTRY_CHECK(Gametypes)
int MAPINFO_TYPE_ALL;
#define REGISTER_GAMETYPE(hname, sname, g_name, NAME, gteamplay, mutators, defaults, gdescription) \
int MAPINFO_TYPE_##NAME; \
bool NAME##_mapinfo(string k, string v) { return = false; } \
- REGISTER(RegisterGametypes, MAPINFO_TYPE, Gametypes, g_name, m_id, \
+ REGISTER(Gametypes, MAPINFO_TYPE, g_name, m_id, \
NEW(Gametype, hname, #sname, #g_name, gteamplay, #sname " " mutators, defaults, gdescription) \
) { \
/* same as `1 << m_id` */ \
deactivate_minigame();
}
-vector ReadVector2D() { vector v; v_x = ReadCoord(); v_y = ReadCoord(); v_z = 0; return v; }
-vector ReadVector() { vector v; v_x = ReadCoord(); v_y = ReadCoord(); v_z = ReadCoord(); return v; }
string() ReadString_Raw = #366;
string ReadString_Zoned() { return strzone(ReadString_Raw()); }
#define ReadString ReadString_Zoned
REGISTRY(Minigames, BITS(3))
#define Minigames_from(i) _Minigames_from(i, NULL)
-REGISTER_REGISTRY(RegisterMinigames)
+REGISTER_REGISTRY(Minigames)
REGISTRY_CHECK(Minigames)
#define REGISTER_MINIGAME(name,nicename) \
- REGISTER(RegisterMinigames, MINIGAME, Minigames, name, m_id, new(minigame_descriptor)); \
+ REGISTER(Minigames, MINIGAME_##name, m_id, new(minigame_descriptor)); \
void name##_hud_board(vector, vector); \
void name##_hud_status(vector, vector); \
int name##_client_event(entity, string, ...); \
- REGISTER_INIT_POST(MINIGAME, name) { \
+ REGISTER_INIT_POST(MINIGAME_##name) { \
make_pure(this); \
this.netname = strzone(strtolower(#name)); \
this.message = nicename; \
this.minigame_hud_status = name##_hud_status; \
this.minigame_event = name##_client_event; \
} \
- REGISTER_INIT(MINIGAME, name)
+ REGISTER_INIT(MINIGAME_##name)
#endif
#define FIELD(Flags, Type,Name) if ( sf & (Flags) ) Write##Type(MSG_ENTITY, self.Name);
-#define WriteVector(to,Name) WriteCoord(to,Name##_x); WriteCoord(to,Name##_y); WriteCoord(to,Name##_z)
-#define WriteVector2D(to,Name) WriteCoord(to,Name##_x); WriteCoord(to,Name##_y)
#define MSLE(Name,Fields) \
else if ( self.classname == #Name ) { \
if ( sf & MINIG_SF_CREATE ) WriteString(MSG_ENTITY,self.owner.netname); \
REGISTRY(Minigames, BITS(3))
#define Minigames_from(i) _Minigames_from(i, NULL)
-REGISTER_REGISTRY(RegisterMinigames)
+REGISTER_REGISTRY(Minigames)
REGISTRY_CHECK(Minigames)
#define REGISTER_MINIGAME(name,nicename) \
- REGISTER(RegisterMinigames, MINIGAME, Minigames, name, m_id, new(minigame_descriptor)); \
+ REGISTER(Minigames, MINIGAME_##name, m_id, new(minigame_descriptor)); \
int name##_server_event(entity, string, ...); \
- REGISTER_INIT_POST(MINIGAME, name) { \
+ REGISTER_INIT_POST(MINIGAME_##name) { \
make_pure(this); \
this.netname = strzone(strtolower(#name)); \
this.message = nicename; \
this.minigame_event = name##_server_event; \
} \
- REGISTER_INIT(MINIGAME, name)
+ REGISTER_INIT(MINIGAME_##name)
#endif
REGISTRY(Models, BITS(9))
#define Models_from(i) _Models_from(i, MDL_Null)
-REGISTER_REGISTRY(RegisterModels)
+REGISTER_REGISTRY(Models)
#define MODEL(name, path) \
string MDL_##name##_get() { return path; } \
- REGISTER(RegisterModels, MDL, Models, name, m_id, NEW(Model, MDL_##name##_get))
+ REGISTER(Models, MDL, name, m_id, NEW(Model, MDL_##name##_get))
PRECACHE(Models) {
FOREACH(Models, true, LAMBDA({
REGISTRY(Monsters, BITS(5))
#define Monsters_from(i) _Monsters_from(i, MON_Null)
#define get_monsterinfo(i) Monsters_from(i)
-REGISTER_REGISTRY(RegisterMonsters)
+REGISTER_REGISTRY(Monsters)
REGISTRY_CHECK(Monsters)
const int MON_FIRST = 1;
#define MON_LAST (Monsters_COUNT - 1)
/** If you register a new monster, make sure to add it to all.inc */
-#define REGISTER_MONSTER(id, inst) REGISTER(RegisterMonsters, MON, Monsters, id, monsterid, inst)
+#define REGISTER_MONSTER(id, inst) REGISTER(Monsters, MON, id, monsterid, inst)
REGISTER_MONSTER(Null, NEW(Monster));
Damage(head, self, self.realowner, (autocvar_g_monster_shambler_attack_lightning_damage_zap) * MONSTER_SKILLMOD(self), DEATH_MONSTER_SHAMBLER_ZAP.m_id, head.origin, '0 0 0');
}
- self.think = SUB_Remove;
+ self.think = SUB_Remove_self;
self.nextthink = time + 0.2;
}
}
else
{
- oldself.think = SUB_Remove;
+ oldself.think = SUB_Remove_self;
oldself.nextthink = time;
}
}
return true;
}
-void Monster_Reset()
-{SELFPARAM();
- setorigin(self, self.pos1);
- self.angles = self.pos2;
+void Monster_Reset(entity this)
+{
+ setorigin(this, this.pos1);
+ this.angles = this.pos2;
- Unfreeze(self); // remove any icy remains
+ Unfreeze(this); // remove any icy remains
- self.health = self.max_health;
- self.velocity = '0 0 0';
- self.enemy = world;
- self.goalentity = world;
- self.attack_finished_single[0] = 0;
- self.moveto = self.origin;
+ this.health = this.max_health;
+ this.velocity = '0 0 0';
+ this.enemy = world;
+ this.goalentity = world;
+ this.attack_finished_single[0] = 0;
+ this.moveto = this.origin;
}
void Monster_Dead_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
// number of monsters spawned with mobspawn command
totalspawned -= 1;
- self.think = SUB_Remove;
+ self.think = SUB_Remove_self;
self.nextthink = time + 0.1;
self.event_damage = func_null;
}
{
Violence_GibSplash(self, 1, 0.5, attacker);
- self.think = SUB_Remove;
+ self.think = SUB_Remove_self;
self.nextthink = time + 0.1;
}
}
-#include "mutator/buffs/module.inc"
+#include "mutator/waypoints/module.inc"
+
#include "mutator/itemstime.qc"
#include "mutator/multijump/module.inc"
#include "mutator/nades/module.inc"
#include "mutator/superspec/module.inc"
-#include "mutator/waypoints/module.inc"
// completely self contained
#include "mutator/bloodloss/module.inc"
#include "mutator/breakablehook/module.inc"
+#include "mutator/buffs/module.inc"
#include "mutator/campcheck/module.inc"
#include "mutator/cloaked/module.inc"
#include "mutator/damagetext/module.inc"
bool ret = MUTATORFUNCTION_##id##_hooks(mode); if (ret) return ret; \
} \
bool MUTATOR_##id##_check() { return dependence; } \
- REGISTER(RegisterMutators, MUTATOR, Mutators, id, m_id, NEW(Mutator, #id, MUTATORFUNCTION_##id)) \
+ REGISTER(Mutators, MUTATOR, id, m_id, NEW(Mutator, #id, MUTATORFUNCTION_##id)) \
{ this.mutatorcheck = MUTATOR_##id##_check; } \
[[accumulate]] bool MUTATORFUNCTION_##id(int mode)
/**/
MUTATOR_HOOKABLE(BuildGameplayTipsString, EV_BuildGameplayTipsString);
+#define EV_IsFlying(i, o) \
+ /**/ i(entity, MUTATOR_ARGV_0_entity) \
+ /**/
+MUTATOR_HOOKABLE(IsFlying, EV_IsFlying);
+
+#define EV_WP_Format(i, o) \
+ /**/ i(entity, MUTATOR_ARGV_0_entity) \
+ /**/ i(string, MUTATOR_ARGV_0_string) \
+ /**/ o(vector, MUTATOR_ARGV_0_vector) \
+ /**/ o(string, MUTATOR_ARGV_0_string) \
+ /**/
+MUTATOR_HOOKABLE(WP_Format, EV_WP_Format);
+
#endif
--- /dev/null
+REGISTER_BUFF(AMMO) {
+ this.m_prettyName = _("Ammo");
+ this.m_name = "ammo";
+ this.m_skin = 3;
+ this.m_color = '0.76 1 0.1';
+}
+BUFF_SPAWNFUNCS(ammo, BUFF_AMMO)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(ammoregen, BUFF_AMMO)
+
+REGISTER_BUFF(RESISTANCE) {
+ this.m_prettyName = _("Resistance");
+ this.m_name = "resistance";
+ this.m_skin = 0;
+ this.m_color = '0.36 1 0.07';
+}
+BUFF_SPAWNFUNCS(resistance, BUFF_RESISTANCE)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(resistance, BUFF_RESISTANCE)
+
+REGISTER_BUFF(SPEED) {
+ this.m_prettyName = _("Speed");
+ this.m_name = "speed";
+ this.m_skin = 9;
+ this.m_color = '0.1 1 0.84';
+}
+BUFF_SPAWNFUNCS(speed, BUFF_SPEED)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(haste, BUFF_SPEED)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(scout, BUFF_SPEED)
+
+REGISTER_BUFF(MEDIC) {
+ this.m_prettyName = _("Medic");
+ this.m_name = "medic";
+ this.m_skin = 1;
+ this.m_color = '1 0.12 0';
+}
+BUFF_SPAWNFUNCS(medic, BUFF_MEDIC)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(doubler, BUFF_MEDIC)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(medic, BUFF_MEDIC)
+
+REGISTER_BUFF(BASH) {
+ this.m_prettyName = _("Bash");
+ this.m_name = "bash";
+ this.m_skin = 5;
+ this.m_color = '1 0.39 0';
+}
+BUFF_SPAWNFUNCS(bash, BUFF_BASH)
+
+REGISTER_BUFF(VAMPIRE) {
+ this.m_prettyName = _("Vampire");
+ this.m_name = "vampire";
+ this.m_skin = 2;
+ this.m_color = '1 0 0.24';
+}
+BUFF_SPAWNFUNCS(vampire, BUFF_VAMPIRE)
+
+REGISTER_BUFF(DISABILITY) {
+ this.m_prettyName = _("Disability");
+ this.m_name = "disability";
+ this.m_skin = 7;
+ this.m_color = '0.94 0.3 1';
+}
+BUFF_SPAWNFUNCS(disability, BUFF_DISABILITY)
+
+REGISTER_BUFF(VENGEANCE) {
+ this.m_prettyName = _("Vengeance");
+ this.m_name = "vengeance";
+ this.m_skin = 15;
+ this.m_color = '1 0.23 0.61';
+}
+BUFF_SPAWNFUNCS(vengeance, BUFF_VENGEANCE)
+
+REGISTER_BUFF(JUMP) {
+ this.m_prettyName = _("Jump");
+ this.m_name = "jump";
+ this.m_skin = 10;
+ this.m_color = '0.24 0.78 1';
+}
+BUFF_SPAWNFUNCS(jump, BUFF_JUMP)
+
+REGISTER_BUFF(FLIGHT) {
+ this.m_prettyName = _("Flight");
+ this.m_name = "flight";
+ this.m_skin = 11;
+ this.m_color = '0.33 0.56 1';
+}
+BUFF_SPAWNFUNCS(flight, BUFF_FLIGHT)
+
+REGISTER_BUFF(INVISIBLE) {
+ this.m_prettyName = _("Invisible");
+ this.m_name = "invisible";
+ this.m_skin = 12;
+ this.m_color = '0.5 0.5 1';
+}
+BUFF_SPAWNFUNCS(invisible, BUFF_INVISIBLE)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(invis, BUFF_INVISIBLE)
+
+REGISTER_BUFF(INFERNO) {
+ this.m_prettyName = _("Inferno");
+ this.m_name = "inferno";
+ this.m_skin = 16;
+ this.m_color = '1 0.62 0';
+}
+BUFF_SPAWNFUNCS(inferno, BUFF_INFERNO)
+
+REGISTER_BUFF(SWAPPER) {
+ this.m_prettyName = _("Swapper");
+ this.m_name = "swapper";
+ this.m_skin = 17;
+ this.m_color = '0.63 0.36 1';
+}
+BUFF_SPAWNFUNCS(swapper, BUFF_SWAPPER)
+
+REGISTER_BUFF(MAGNET) {
+ this.m_prettyName = _("Magnet");
+ this.m_name = "magnet";
+ this.m_skin = 18;
+ this.m_color = '1 0.95 0.18';
+}
+BUFF_SPAWNFUNCS(magnet, BUFF_MAGNET)
--- /dev/null
+#include "all.qh"
--- /dev/null
+#ifndef BUFFS_ALL_H
+#define BUFFS_ALL_H
+// Welcome to the stuff behind the scenes
+// Below, you will find the list of buffs
+// Add new buffs here!
+// Note: Buffs also need spawnfuncs, which are set below
+
+#include "../../../teams.qh"
+#include "../../../util.qh"
+
+REGISTER_WAYPOINT(Buff, _("Buff"), '1 0.5 0', 1);
+REGISTER_RADARICON(Buff, 1);
+
+REGISTRY(Buffs, BITS(4))
+#define Buffs_from(i) _Buffs_from(i, BUFF_Null)
+REGISTER_REGISTRY(Buffs)
+REGISTRY_CHECK(Buffs)
+
+#define REGISTER_BUFF(id) \
+ REGISTER(Buffs, BUFF_##id, m_id, NEW(Buff)); \
+ REGISTER_INIT_POST(BUFF_##id) { \
+ this.netname = this.m_name; \
+ this.m_itemid = BIT(this.m_id - 1); \
+ this.m_sprite = strzone(strcat("buff-", this.m_name)); \
+ } \
+ REGISTER_INIT(BUFF_##id)
+
+#include "../../../items/item/pickup.qh"
+CLASS(Buff, Pickup)
+ /** bit index */
+ ATTRIB(Buff, m_itemid, int, 0)
+ ATTRIB(Buff, m_name, string, "buff")
+ ATTRIB(Buff, m_color, vector, '1 1 1')
+ ATTRIB(Buff, m_prettyName, string, "Buff")
+ ATTRIB(Buff, m_skin, int, 0)
+ ATTRIB(Buff, m_sprite, string, "")
+ METHOD(Buff, display, void(entity this, void(string name, string icon) returns)) {
+ returns(this.m_prettyName, sprintf("/gfx/hud/%s/buff_%s", cvar_string("menu_skin"), this.m_name));
+ }
+#ifdef SVQC
+ METHOD(Buff, m_time, float(Buff this))
+ { return cvar(strcat("g_buffs_", this.netname, "_time")); }
+#endif
+ENDCLASS(Buff)
+
+#ifdef SVQC
+ .int buffs;
+ void buff_Init(entity ent);
+ void buff_Init_Compat(entity ent, entity replacement);
+ #define BUFF_SPAWNFUNC(e, b, t) spawnfunc(item_buff_##e) { \
+ self.buffs = b.m_itemid; \
+ self.team = t; \
+ buff_Init(self); \
+ }
+ #define BUFF_SPAWNFUNCS(e, b) \
+ BUFF_SPAWNFUNC(e, b, 0) \
+ BUFF_SPAWNFUNC(e##_team1, b, NUM_TEAM_1) \
+ BUFF_SPAWNFUNC(e##_team2, b, NUM_TEAM_2) \
+ BUFF_SPAWNFUNC(e##_team3, b, NUM_TEAM_3) \
+ BUFF_SPAWNFUNC(e##_team4, b, NUM_TEAM_4)
+ #define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r) spawnfunc(item_##o) { buff_Init_Compat(self, r); }
+#else
+ #define BUFF_SPAWNFUNC(e, b, t)
+ #define BUFF_SPAWNFUNCS(e, b)
+ #define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r)
+#endif
+
+REGISTER_BUFF(Null);
+BUFF_SPAWNFUNCS(random, BUFF_Null)
+
+#include "all.inc"
+
+#endif
#include "../../../triggers/target/music.qh"
#include "../../../gamemodes/all.qh"
-#include "../../../buffs/all.qh"
.float buff_time;
void buffs_DelayedInit();
if(self.buff_activetime) { buff_Waypoint_Spawn(self); }
}
-void buff_Reset()
-{SELFPARAM();
+void buff_Reset(entity this)
+{
if(autocvar_g_buffs_randomize)
- buff_NewType(self, self.buffs);
- self.owner = world;
+ buff_NewType(this, this.buffs);
+ this.owner = world;
buff_SetCooldown(autocvar_g_buffs_cooldown_activate);
buff_Waypoint_Reset();
- self.buff_activetime_updated = false;
+ this.buff_activetime_updated = false;
- if(autocvar_g_buffs_random_location || (self.spawnflags & 64))
- buff_Respawn(self);
+ if(autocvar_g_buffs_random_location || (this.spawnflags & 64))
+ buff_Respawn(this);
}
float buff_Customize()
MUTATOR_HOOKFUNCTION(buffs, OnEntityPreSpawn, CBC_ORDER_LAST)
{SELFPARAM();
+ if (self.classname == "item_flight" && cvar("g_buffs") && cvar("g_buffs_flight"))
+ {
+ buff_Init_Compat(self, BUFF_FLIGHT);
+ return true;
+ }
if(autocvar_g_buffs_replace_powerups)
switch(self.classname)
{
+#include "all.qc"
#ifdef SVQC
#include "buffs.qc"
#endif
+
+#ifdef IMPLEMENTATION
+
+string BUFF_NAME(int i)
+{
+ Buff b = Buffs_from(i);
+ return sprintf("%s%s", rgb_to_hexcolor(b.m_color), b.m_prettyName);
+}
+
+#ifndef MENUQC
+REGISTER_MUTATOR(buffs_flight, true);
+MUTATOR_HOOKFUNCTION(buffs_flight, IsFlying)
+{
+ noref entity e = MUTATOR_ARGV(0, entity);
+ return BUFFS_STAT(e) & BUFF_FLIGHT.m_itemid;
+}
+#endif
+
+#ifdef CSQC
+REGISTER_MUTATOR(cl_buffs, true);
+MUTATOR_HOOKFUNCTION(cl_buffs, HUD_Powerups_add)
+{
+ int allBuffs = getstati(STAT_BUFFS, 0, 24);
+ FOREACH(Buffs, it.m_itemid & allBuffs, LAMBDA(
+ addPowerupItem(it.m_prettyName, strcat("buff_", it.m_name), it.m_color, bound(0, getstatf(STAT_BUFF_TIME) - time, 99), 60);
+ ));
+}
+MUTATOR_HOOKFUNCTION(cl_buffs, WP_Format)
+{
+ entity this = MUTATOR_ARGV(0, entity);
+ string s = MUTATOR_ARGV(0, string);
+ if (s == WP_Buff.netname || s == RADARICON_Buff.netname)
+ {
+ Buff b = Buffs_from(this.wp_extra);
+ MUTATOR_ARGV(0, vector) = b.m_color;
+ MUTATOR_ARGV(0, string) = b.m_prettyName;
+ return true;
+ }
+}
+
+#endif
+#endif
float autocvar_g_instagib_speed_highspeed;
#include "../../../../server/cl_client.qh"
-#include "../../../buffs/all.qh"
#include "../../../items/all.qc"
frag_mirrordamage = 0;
}
- if((frag_target.buffs & BUFF_INVISIBLE.m_itemid) || (frag_target.items & ITEM_Invisibility.m_itemid))
+ if(frag_target.alpha && frag_target.alpha < 1)
yoda = 1;
return false;
--- /dev/null
+EFFECT(0, NADE_EXPLODE_RED, "nade_red_explode")
+EFFECT(0, NADE_EXPLODE_BLUE, "nade_blue_explode")
+EFFECT(0, NADE_EXPLODE_YELLOW, "nade_yellow_explode")
+EFFECT(0, NADE_EXPLODE_PINK, "nade_pink_explode")
+EFFECT(0, NADE_EXPLODE_NEUTRAL, "nade_neutral_explode")
+entity EFFECT_NADE_EXPLODE(int teamid)
+{
+ switch (teamid) {
+ case NUM_TEAM_1: return EFFECT_NADE_EXPLODE_RED;
+ case NUM_TEAM_2: return EFFECT_NADE_EXPLODE_BLUE;
+ case NUM_TEAM_3: return EFFECT_NADE_EXPLODE_YELLOW;
+ case NUM_TEAM_4: return EFFECT_NADE_EXPLODE_PINK;
+ default: return EFFECT_NADE_EXPLODE_NEUTRAL;
+ }
+}
+
+EFFECT(1, NADE_TRAIL_RED, "nade_red")
+EFFECT(1, NADE_TRAIL_BLUE, "nade_blue")
+EFFECT(1, NADE_TRAIL_YELLOW, "nade_yellow")
+EFFECT(1, NADE_TRAIL_PINK, "nade_pink")
+EFFECT(1, NADE_TRAIL_NEUTRAL, "nade_neutral")
+entity EFFECT_NADE_TRAIL(int teamid)
+{
+ switch (teamid) {
+ case NUM_TEAM_1: return EFFECT_NADE_TRAIL_RED;
+ case NUM_TEAM_2: return EFFECT_NADE_TRAIL_BLUE;
+ case NUM_TEAM_3: return EFFECT_NADE_TRAIL_YELLOW;
+ case NUM_TEAM_4: return EFFECT_NADE_TRAIL_PINK;
+ default: return EFFECT_NADE_TRAIL_NEUTRAL;
+ }
+}
+
+EFFECT(1, NADE_TRAIL_BURN_RED, "nade_red_burn")
+EFFECT(1, NADE_TRAIL_BURN_BLUE, "nade_blue_burn")
+EFFECT(1, NADE_TRAIL_BURN_YELLOW, "nade_yellow_burn")
+EFFECT(1, NADE_TRAIL_BURN_PINK, "nade_pink_burn")
+EFFECT(1, NADE_TRAIL_BURN_NEUTRAL, "nade_neutral_burn")
+entity EFFECT_NADE_TRAIL_BURN(int teamid)
+{
+ switch (teamid) {
+ case NUM_TEAM_1: return EFFECT_NADE_TRAIL_BURN_RED;
+ case NUM_TEAM_2: return EFFECT_NADE_TRAIL_BURN_BLUE;
+ case NUM_TEAM_3: return EFFECT_NADE_TRAIL_BURN_YELLOW;
+ case NUM_TEAM_4: return EFFECT_NADE_TRAIL_BURN_PINK;
+ default: return EFFECT_NADE_TRAIL_BURN_NEUTRAL;
+ }
+}
-#ifdef SVQC
#include "nades.qc"
+#ifndef MENUQC
+#include "net.qc"
#endif
--- /dev/null
+#ifndef MENUQC
+#define NADE_PROJECTILE(i, projectile, trail) do { \
+ this.m_projectile[i] = projectile; \
+ this.m_trail[i] = trail; \
+} while (0)
+#else
+#define NADE_PROJECTILE(i, projectile, trail)
+#endif
+
+REGISTER_NADE(NORMAL) {
+ this.m_color = '1 1 1';
+ NADE_PROJECTILE(0, PROJECTILE_NADE, EFFECT_Null);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_BURN, EFFECT_Null);
+}
+
+REGISTER_NADE(NAPALM) {
+ this.m_color = '2 0.5 0';
+ this.m_name = _("Napalm grenade");
+ this.m_icon = "nade_napalm";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_NAPALM, EFFECT_TR_ROCKET);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_NAPALM_BURN, EFFECT_SPIDERBOT_ROCKET_TRAIL);
+}
+
+REGISTER_NADE(ICE) {
+ this.m_color = '0 0.5 2';
+ this.m_name = _("Ice grenade");
+ this.m_icon = "nade_ice";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_ICE, EFFECT_TR_NEXUIZPLASMA);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_ICE_BURN, EFFECT_RACER_ROCKET_TRAIL);
+}
+
+REGISTER_NADE(TRANSLOCATE) {
+ this.m_color = '1 0 1';
+ this.m_name = _("Translocate grenade");
+ this.m_icon = "nade_translocate";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_TRANSLOCATE, EFFECT_TR_CRYLINKPLASMA);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_TRANSLOCATE, EFFECT_TR_CRYLINKPLASMA);
+}
+
+REGISTER_NADE(SPAWN) {
+ this.m_color = '1 0.9 0';
+ this.m_name = _("Spawn grenade");
+ this.m_icon = "nade_spawn";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_SPAWN, EFFECT_NADE_TRAIL_YELLOW);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_SPAWN, EFFECT_NADE_TRAIL_YELLOW);
+}
+
+REGISTER_NADE(HEAL) {
+ this.m_color = '1 0 0';
+ this.m_name = _("Heal grenade");
+ this.m_icon = "nade_heal";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_HEAL, EFFECT_NADE_TRAIL_RED);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_HEAL_BURN, EFFECT_NADE_TRAIL_BURN_RED);
+}
+
+REGISTER_NADE(MONSTER) {
+ this.m_color = '0.25 0.75 0';
+ this.m_name = _("Monster grenade");
+ this.m_icon = "nade_monster";
+ NADE_PROJECTILE(0, PROJECTILE_NADE_MONSTER, EFFECT_NADE_TRAIL_RED);
+ NADE_PROJECTILE(1, PROJECTILE_NADE_MONSTER_BURN, EFFECT_NADE_TRAIL_BURN_RED);
+}
-#ifndef MUTATOR_NADES_H
-#define MUTATOR_NADES_H
+#include "nades.qh"
-#ifdef SVQC
-#include "../../../../server/mutators/mutator/gamemode_freezetag.qc"
+#ifdef IMPLEMENTATION
+
+#ifndef MENUQC
+entity Nade_TrailEffect(int proj, int nade_team)
+{
+ switch (proj)
+ {
+ case PROJECTILE_NADE: return EFFECT_NADE_TRAIL(nade_team);
+ case PROJECTILE_NADE_BURN: return EFFECT_NADE_TRAIL_BURN(nade_team);
+ }
+
+ FOREACH(Nades, true, LAMBDA(
+ for (int j = 0; j < 2; j++)
+ {
+ if (it.m_projectile[j] == proj)
+ {
+ string trail = it.m_trail[j].eent_eff_name;
+ if (trail) return it.m_trail[j];
+ break;
+ }
+ }
+ ));
+
+ return EFFECT_Null;
+}
#endif
-.entity nade;
-.entity fake_nade;
-.float nade_timer;
-.float nade_refire;
-.float bonus_nades;
-.float nade_special_time;
-.float bonus_nade_score;
-.float nade_type;
-.string pokenade_type;
-.entity nade_damage_target;
-.float cvar_cl_nade_type;
-.string cvar_cl_pokenade_type;
-.float toss_time;
-.float stat_healing_orb;
-.float stat_healing_orb_alpha;
-.float nade_show_particles;
-
-// Remove nades that are being thrown
-void nades_Clear(entity player);
-
-// Give a bonus grenade to a player
-void(entity player, float score) nades_GiveBonus;
-
-/**
- * called to adjust nade damage and force on hit
- */
-#define EV_Nade_Damage(i, o) \
- /** weapon */ i(entity, MUTATOR_ARGV_0_entity) \
- /** force */ i(vector, MUTATOR_ARGV_0_vector) \
- /**/ o(vector, MUTATOR_ARGV_0_vector) \
- /** damage */ i(float, MUTATOR_ARGV_0_float) \
- /**/ o(float, MUTATOR_ARGV_0_float) \
- /**/
-MUTATOR_HOOKABLE(Nade_Damage, EV_Nade_Damage);
+#ifdef CSQC
+REGISTER_MUTATOR(cl_nades, true);
+MUTATOR_HOOKFUNCTION(cl_nades, HUD_Draw_overlay)
+{
+ if (getstatf(STAT_HEALING_ORB) <= time) return false;
+ MUTATOR_ARGV(0, vector) = NADE_TYPE_HEAL.m_color;
+ MUTATOR_ARGV(0, float) = getstatf(STAT_HEALING_ORB_ALPHA);
+ return true;
+}
+MUTATOR_HOOKFUNCTION(cl_nades, Ent_Projectile)
+{
+ if (self.cnt == PROJECTILE_NAPALM_FOUNTAIN)
+ {
+ self.modelindex = 0;
+ self.traileffect = EFFECT_FIREBALL.m_id;
+ return true;
+ }
+ if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
+ {
+ setmodel(self, MDL_PROJECTILE_NADE);
+ entity trail = Nade_TrailEffect(self.cnt, self.team);
+ if (trail.eent_eff_name) self.traileffect = trail.m_id;
+ return true;
+ }
+}
+MUTATOR_HOOKFUNCTION(cl_nades, EditProjectile)
+{
+ if (self.cnt == PROJECTILE_NAPALM_FOUNTAIN)
+ {
+ loopsound(self, CH_SHOTS_SINGLE, SND(FIREBALL_FLY2), VOL_BASE, ATTEN_NORM);
+ self.mins = '-16 -16 -16';
+ self.maxs = '16 16 16';
+ }
+
+ entity nade_type = Nade_FromProjectile(self.cnt);
+ if (nade_type == NADE_TYPE_Null) return;
+ self.mins = '-16 -16 -16';
+ self.maxs = '16 16 16';
+ self.colormod = nade_type.m_color;
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ self.scale = 1.5;
+ self.avelocity = randomvec() * 720;
+
+ if (nade_type == NADE_TYPE_TRANSLOCATE || nade_type == NADE_TYPE_SPAWN)
+ self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+ else
+ self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
+}
+bool Projectile_isnade(int p)
+{
+ return Nade_FromProjectile(p) != NADE_TYPE_Null;
+}
+void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expand_time)
+{
+ float bonusNades = getstatf(STAT_NADE_BONUS);
+ float bonusProgress = getstatf(STAT_NADE_BONUS_SCORE);
+ float bonusType = getstati(STAT_NADE_BONUS_TYPE);
+ Nade def = Nades_from(bonusType);
+ vector nadeColor = def.m_color;
+ string nadeIcon = def.m_icon;
+
+ vector iconPos, textPos;
+
+ if(autocvar_hud_panel_ammo_iconalign)
+ {
+ iconPos = myPos + eX * 2 * mySize.y;
+ textPos = myPos;
+ }
+ else
+ {
+ iconPos = myPos;
+ textPos = myPos + eX * mySize.y;
+ }
+
+ if(bonusNades > 0 || bonusProgress > 0)
+ {
+ DrawNadeProgressBar(myPos, mySize, bonusProgress, nadeColor);
+
+ if(autocvar_hud_panel_ammo_text)
+ drawstring_aspect(textPos, ftos(bonusNades), eX * (2/3) * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ if(draw_expanding)
+ drawpic_aspect_skin_expanding(iconPos, nadeIcon, '1 1 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, expand_time);
+ drawpic_aspect_skin(iconPos, nadeIcon, '1 1 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
+}
#endif
-#ifdef IMPLEMENTATION
+#ifdef SVQC
-#include "../../../nades/all.qh"
#include "../../../gamemodes/all.qh"
#include "../../../monsters/spawn.qh"
#include "../../../monsters/sv_monsters.qh"
fn.colormod = Nades_from(n.nade_type).m_color;
fn.colormap = self.colormap;
fn.glowmod = self.glowmod;
- fn.think = SUB_Remove;
+ fn.think = SUB_Remove_self;
fn.nextthink = n.wait;
self.nade = n;
return false;
}
#endif
+#endif
--- /dev/null
+#ifndef NADES_ALL_H
+#define NADES_ALL_H
+
+#include "../../../teams.qh"
+
+// use slots 70-100
+const int PROJECTILE_NADE = 71;
+const int PROJECTILE_NADE_BURN = 72;
+const int PROJECTILE_NADE_NAPALM = 73;
+const int PROJECTILE_NADE_NAPALM_BURN = 74;
+const int PROJECTILE_NAPALM_FOUNTAIN = 75;
+const int PROJECTILE_NADE_ICE = 76;
+const int PROJECTILE_NADE_ICE_BURN = 77;
+const int PROJECTILE_NADE_TRANSLOCATE = 78;
+const int PROJECTILE_NADE_SPAWN = 79;
+const int PROJECTILE_NADE_HEAL = 80;
+const int PROJECTILE_NADE_HEAL_BURN = 81;
+const int PROJECTILE_NADE_MONSTER = 82;
+const int PROJECTILE_NADE_MONSTER_BURN = 83;
+
+REGISTRY(Nades, BITS(4))
+#define Nades_from(i) _Nades_from(i, NADE_TYPE_Null)
+REGISTER_REGISTRY(Nades)
+REGISTRY_CHECK(Nades)
+
+#define REGISTER_NADE(id) REGISTER(Nades, NADE_TYPE, id, m_id, NEW(Nade))
+
+CLASS(Nade, Object)
+ ATTRIB(Nade, m_id, int, 0)
+ ATTRIB(Nade, m_color, vector, '0 0 0')
+ ATTRIB(Nade, m_name, string, _("Grenade"))
+ ATTRIB(Nade, m_icon, string, "nade_normal")
+ ATTRIBARRAY(Nade, m_projectile, int, 2)
+ ATTRIBARRAY(Nade, m_trail, entity, 2)
+ METHOD(Nade, display, void(entity this, void(string name, string icon) returns)) {
+ returns(this.m_name, sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.m_icon));
+ }
+ENDCLASS(Nade)
+
+REGISTER_NADE(Null);
+
+Nade Nade_FromProjectile(int proj)
+{
+ FOREACH(Nades, true, LAMBDA(
+ for (int j = 0; j < 2; j++)
+ {
+ if (it.m_projectile[j] == proj) return it;
+ }
+ ));
+ return NADE_TYPE_Null;
+}
+
+#ifndef MENUQC
+#include "effects.inc"
+#endif
+
+#include "nades.inc"
+
+.float healer_lifetime;
+.float healer_radius;
+
+#ifdef SVQC
+
+.entity nade;
+.entity fake_nade;
+.float nade_timer;
+.float nade_refire;
+.float bonus_nades;
+.float nade_special_time;
+.float bonus_nade_score;
+.float nade_type;
+.string pokenade_type;
+.entity nade_damage_target;
+.float cvar_cl_nade_type;
+.string cvar_cl_pokenade_type;
+.float toss_time;
+.float stat_healing_orb;
+.float stat_healing_orb_alpha;
+.float nade_show_particles;
+
+bool healer_send(entity this, entity to, int sf);
+
+// Remove nades that are being thrown
+void nades_Clear(entity player);
+
+// Give a bonus grenade to a player
+void(entity player, float score) nades_GiveBonus;
+
+/**
+ * called to adjust nade damage and force on hit
+ */
+#define EV_Nade_Damage(i, o) \
+ /** weapon */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** force */ i(vector, MUTATOR_ARGV_0_vector) \
+ /**/ o(vector, MUTATOR_ARGV_0_vector) \
+ /** damage */ i(float, MUTATOR_ARGV_0_float) \
+ /**/ o(float, MUTATOR_ARGV_0_float) \
+ /**/
+MUTATOR_HOOKABLE(Nade_Damage, EV_Nade_Damage);
+
+#endif
+
+#endif
--- /dev/null
+#include "nades.qh"
+
+#ifdef IMPLEMENTATION
+
+#ifdef CSQC
+.float ltime;
+void healer_draw(entity this)
+{
+ float dt = time - self.move_time;
+ self.move_time = time;
+ if(dt <= 0)
+ return;
+
+ self.alpha = (self.ltime - time) / self.healer_lifetime;
+ self.scale = min((1 - self.alpha)*self.healer_lifetime*4,1)*self.healer_radius;
+}
+
+void healer_setup(entity e)
+{
+ setmodel(e, MDL_NADE_HEAL);
+
+ setorigin(e, e.origin);
+
+ float model_radius = e.maxs.x;
+ vector size = '1 1 1' * e.healer_radius / 2;
+ setsize(e,-size,size);
+ e.healer_radius = e.healer_radius/model_radius*0.6;
+
+ e.draw = healer_draw;
+ e.health = 255;
+ e.movetype = MOVETYPE_NONE;
+ e.solid = SOLID_NOT;
+ e.drawmask = MASK_NORMAL;
+ e.scale = 0.01;
+ e.avelocity = e.move_avelocity = '7 0 11';
+ e.colormod = '1 0 0';
+ e.renderflags |= RF_ADDITIVE;
+}
+#endif
+
+REGISTER_NET_LINKED(Nade_Heal)
+
+#ifdef CSQC
+NET_HANDLE(Nade_Heal, bool isNew)
+{
+ Net_Accept(Nade_Heal);
+ int sf = ReadByte();
+ if (sf & 1) {
+ this.origin_x = ReadCoord();
+ this.origin_y = ReadCoord();
+ this.origin_z = ReadCoord();
+ setorigin(this, this.origin);
+ this.healer_lifetime = ReadByte();
+ this.healer_radius = ReadShort();
+ this.ltime = time + ReadByte()/10.0;
+ // this.ltime = time + this.healer_lifetime;
+ healer_setup(this);
+ }
+ return true;
+}
+#endif
+
+#ifdef SVQC
+bool healer_send(entity this, entity to, int sf)
+{
+ int channel = MSG_ENTITY;
+ WriteHeader(channel, Nade_Heal);
+ WriteByte(channel, sf);
+ if (sf & 1) {
+ WriteCoord(channel, this.origin.x);
+ WriteCoord(channel, this.origin.y);
+ WriteCoord(channel, this.origin.z);
+
+ WriteByte(channel, this.healer_lifetime);
+ //WriteByte(MSG_ENTITY, this.ltime - time + 1);
+ WriteShort(channel, this.healer_radius);
+ // round time delta to a 1/10th of a second
+ WriteByte(channel, (this.ltime - time)*10.0+0.5);
+ }
+ return true;
+}
+#endif
+
+#endif
return false;
}
-void _spawnfunc_weapon_hmg() { SELFPARAM(); spawnfunc_weapon_hmg(this); }
-void _spawnfunc_weapon_rpc() { SELFPARAM(); spawnfunc_weapon_rpc(this); }
+void self_spawnfunc_weapon_hmg() { SELFPARAM(); spawnfunc_weapon_hmg(this); }
+void self_spawnfunc_weapon_rpc() { SELFPARAM(); spawnfunc_weapon_rpc(this); }
MUTATOR_HOOKFUNCTION(ok, OnEntityPreSpawn)
{SELFPARAM();
wep.team = self.team;
wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
wep.pickup_anyway = true;
- wep.think = _spawnfunc_weapon_hmg;
+ wep.think = self_spawnfunc_weapon_hmg;
wep.nextthink = time + 0.1;
return true;
}
wep.team = self.team;
wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
wep.pickup_anyway = true;
- wep.think = _spawnfunc_weapon_rpc;
+ wep.think = self_spawnfunc_weapon_rpc;
wep.nextthink = time + 0.1;
return true;
}
REGISTER_WAYPOINT(OnsGen, _("Generator"), '1 0.5 0', 1);
REGISTER_WAYPOINT(OnsGenShielded, _("Generator"), '1 0.5 0', 1);
-REGISTER_WAYPOINT(Buff, _("Buff"), '1 0.5 0', 1);
-
REGISTER_WAYPOINT(Weapon, _("Weapon"), '0 0 0', 1);
REGISTER_WAYPOINT(Monster, _("Monster"), '1 0 0', 1);
REGISTRY(Waypoints, BITS(6))
#define Waypoints_from(i) _Waypoints_from(i, WP_Null)
-REGISTER_REGISTRY(RegisterWaypoints)
+REGISTER_REGISTRY(Waypoints)
REGISTRY_CHECK(Waypoints)
/** If you register a new waypoint, make sure to add it to all.inc */
-#define REGISTER_WAYPOINT_(id, init) REGISTER(RegisterWaypoints, WP, Waypoints, id, m_id, init)
+#define REGISTER_WAYPOINT_(id, init) REGISTER(Waypoints, WP, id, m_id, init)
CLASS(Waypoint, Object)
ATTRIB(Waypoint, m_id, int, 0)
REGISTRY(RadarIcons, BITS(7))
#define RadarIcons_from(i) _RadarIcons_from(i, RADARICON_NONE)
-REGISTER_REGISTRY(RegisterRadarIcons)
+REGISTER_REGISTRY(RadarIcons)
REGISTRY_CHECK(RadarIcons)
.int m_radaricon;
-#define REGISTER_RADARICON(id, num) REGISTER(RegisterRadarIcons, RADARICON, RadarIcons, id, m_id, new(RadarIcon)) { make_pure(this); this.m_radaricon = num; this.netname = #id; }
+#define REGISTER_RADARICON(id, num) REGISTER(RadarIcons, RADARICON, id, m_id, new(RadarIcon)) { make_pure(this); this.m_radaricon = num; this.netname = #id; }
REGISTER_WAYPOINT(Null, "", '0 0 0', 1);
REGISTER_RADARICON(DOMPOINT, 1);
REGISTER_RADARICON(TAGGED, 1);
-REGISTER_RADARICON(Buff, 1);
REGISTER_RADARICON(Item, 1);
REGISTER_RADARICON(Vehicle, 1);
REGISTER_RADARICON(Weapon, 1);
{
if (s == WP_Weapon.netname || s == RADARICON_Weapon.netname) return get_weaponinfo(this.wp_extra).wpcolor;
if (s == WP_Item.netname || s == RADARICON_Item.netname) return Items_from(this.wp_extra).m_color;
- if (s == WP_Buff.netname || s == RADARICON_Buff.netname) return Buffs_from(this.wp_extra).m_color;
+ if (MUTATOR_CALLHOOK(WP_Format, this, s))
+ {
+ return MUTATOR_ARGV(0, vector);
+ }
return def;
}
if (s == WP_RaceStartFinish.netname) return (race_checkpointtime || race_mycheckpointtime) ? _("Finish") : _("Start");
if (s == WP_Weapon.netname) return get_weaponinfo(self.wp_extra).m_name;
if (s == WP_Item.netname) return Items_from(self.wp_extra).m_waypoint;
- if (s == WP_Buff.netname) return Buffs_from(self.wp_extra).m_prettyName;
if (s == WP_Monster.netname) return get_monsterinfo(self.wp_extra).monster_name;
+ if (MUTATOR_CALLHOOK(WP_Format, this, s))
+ {
+ return MUTATOR_ARGV(0, string);
+ }
// need to loop, as our netname could be one of three
FOREACH(Waypoints, it.netname == s, LAMBDA(
if (fabs(sa) > fabs(ca))
{
algnx = (sa < 0);
- algny = 0.5 - 0.5 * ca / fabs(sa);
+ float f = fabs(sa);
+ algny = 0.5 - 0.5 * (f ? (ca / f) : 0);
}
else
{
- algnx = 0.5 - 0.5 * sa / fabs(ca);
+ float f = fabs(ca);
+ algnx = 0.5 - 0.5 * (f ? (sa / f) : 0);
algny = (ca < 0);
}
+++ /dev/null
-#define NADE_PROJECTILE(i, projectile, trail) do { \
- this.m_projectile[i] = projectile; \
- this.m_trail[i] = trail; \
-} while (0)
-
-REGISTER_NADE(NORMAL) {
- this.m_color = '1 1 1';
- NADE_PROJECTILE(0, PROJECTILE_NADE, EFFECT_Null);
- NADE_PROJECTILE(1, PROJECTILE_NADE_BURN, EFFECT_Null);
-}
-
-REGISTER_NADE(NAPALM) {
- this.m_color = '2 0.5 0';
- this.m_name = _("Napalm grenade");
- this.m_icon = "nade_napalm";
- NADE_PROJECTILE(0, PROJECTILE_NADE_NAPALM, EFFECT_TR_ROCKET);
- NADE_PROJECTILE(1, PROJECTILE_NADE_NAPALM_BURN, EFFECT_SPIDERBOT_ROCKET_TRAIL);
-}
-
-REGISTER_NADE(ICE) {
- this.m_color = '0 0.5 2';
- this.m_name = _("Ice grenade");
- this.m_icon = "nade_ice";
- NADE_PROJECTILE(0, PROJECTILE_NADE_ICE, EFFECT_TR_NEXUIZPLASMA);
- NADE_PROJECTILE(1, PROJECTILE_NADE_ICE_BURN, EFFECT_RACER_ROCKET_TRAIL);
-}
-
-REGISTER_NADE(TRANSLOCATE) {
- this.m_color = '1 0 1';
- this.m_name = _("Translocate grenade");
- this.m_icon = "nade_translocate";
- NADE_PROJECTILE(0, PROJECTILE_NADE_TRANSLOCATE, EFFECT_TR_CRYLINKPLASMA);
- NADE_PROJECTILE(1, PROJECTILE_NADE_TRANSLOCATE, EFFECT_TR_CRYLINKPLASMA);
-}
-
-REGISTER_NADE(SPAWN) {
- this.m_color = '1 0.9 0';
- this.m_name = _("Spawn grenade");
- this.m_icon = "nade_spawn";
- NADE_PROJECTILE(0, PROJECTILE_NADE_SPAWN, EFFECT_NADE_TRAIL_YELLOW);
- NADE_PROJECTILE(1, PROJECTILE_NADE_SPAWN, EFFECT_NADE_TRAIL_YELLOW);
-}
-
-REGISTER_NADE(HEAL) {
- this.m_color = '1 0 0';
- this.m_name = _("Heal grenade");
- this.m_icon = "nade_heal";
- NADE_PROJECTILE(0, PROJECTILE_NADE_HEAL, EFFECT_NADE_TRAIL_RED);
- NADE_PROJECTILE(1, PROJECTILE_NADE_HEAL_BURN, EFFECT_NADE_TRAIL_BURN_RED);
-}
-
-REGISTER_NADE(MONSTER) {
- this.m_color = '0.25 0.75 0';
- this.m_name = _("Monster grenade");
- this.m_icon = "nade_monster";
- NADE_PROJECTILE(0, PROJECTILE_NADE_MONSTER, EFFECT_NADE_TRAIL_RED);
- NADE_PROJECTILE(1, PROJECTILE_NADE_MONSTER_BURN, EFFECT_NADE_TRAIL_BURN_RED);
-}
+++ /dev/null
-#include "all.qh"
-
-#if defined(CSQC)
- #include "../../client/defs.qh"
- #include "../buffs/all.qh"
- #include "../movetypes/movetypes.qh"
- #include "../../client/main.qh"
- #include "../../lib/csqcmodel/cl_model.qh"
-#elif defined(MENUQC)
-#elif defined(SVQC)
- #include "../constants.qh"
- #include "../../server/constants.qh"
- #include "../turrets/sv_turrets.qh"
-#endif
-
-
-#ifdef CSQC
-.float ltime;
-void healer_draw(entity this)
-{
- float dt = time - self.move_time;
- self.move_time = time;
- if(dt <= 0)
- return;
-
- self.alpha = (self.ltime - time) / self.healer_lifetime;
- self.scale = min((1 - self.alpha)*self.healer_lifetime*4,1)*self.healer_radius;
-}
-
-void healer_setup(entity e)
-{
- setmodel(e, MDL_NADE_HEAL);
-
- setorigin(e, e.origin);
-
- float model_radius = e.maxs.x;
- vector size = '1 1 1' * e.healer_radius / 2;
- setsize(e,-size,size);
- e.healer_radius = e.healer_radius/model_radius*0.6;
-
- e.draw = healer_draw;
- e.health = 255;
- e.movetype = MOVETYPE_NONE;
- e.solid = SOLID_NOT;
- e.drawmask = MASK_NORMAL;
- e.scale = 0.01;
- e.avelocity = e.move_avelocity = '7 0 11';
- e.colormod = '1 0 0';
- e.renderflags |= RF_ADDITIVE;
-}
-#endif // CSQC
-
-REGISTER_NET_LINKED(Nade_Heal)
-#ifdef CSQC
-NET_HANDLE(Nade_Heal, bool isNew)
-{
- Net_Accept(Nade_Heal);
- int sf = ReadByte();
- if (sf & 1) {
- this.origin_x = ReadCoord();
- this.origin_y = ReadCoord();
- this.origin_z = ReadCoord();
- setorigin(this, this.origin);
- this.healer_lifetime = ReadByte();
- this.healer_radius = ReadShort();
- this.ltime = time + ReadByte()/10.0;
- // this.ltime = time + this.healer_lifetime;
- healer_setup(this);
- }
- return true;
-}
-#endif
-
-#ifdef SVQC
-bool healer_send(entity this, entity to, int sf)
-{
- int channel = MSG_ENTITY;
- WriteHeader(channel, Nade_Heal);
- WriteByte(channel, sf);
- if (sf & 1) {
- WriteCoord(channel, this.origin.x);
- WriteCoord(channel, this.origin.y);
- WriteCoord(channel, this.origin.z);
-
- WriteByte(channel, this.healer_lifetime);
- //WriteByte(MSG_ENTITY, this.ltime - time + 1);
- WriteShort(channel, this.healer_radius);
- // round time delta to a 1/10th of a second
- WriteByte(channel, (this.ltime - time)*10.0+0.5);
- }
- return true;
-}
-#endif // SVQC
+++ /dev/null
-#ifndef NADES_ALL_H
-#define NADES_ALL_H
-
-#include "../teams.qh"
-
-.float healer_lifetime;
-.float healer_radius;
-
-// use slots 70-100
-const int PROJECTILE_NADE = 71;
-const int PROJECTILE_NADE_BURN = 72;
-const int PROJECTILE_NADE_NAPALM = 73;
-const int PROJECTILE_NADE_NAPALM_BURN = 74;
-const int PROJECTILE_NAPALM_FOUNTAIN = 75;
-const int PROJECTILE_NADE_ICE = 76;
-const int PROJECTILE_NADE_ICE_BURN = 77;
-const int PROJECTILE_NADE_TRANSLOCATE = 78;
-const int PROJECTILE_NADE_SPAWN = 79;
-const int PROJECTILE_NADE_HEAL = 80;
-const int PROJECTILE_NADE_HEAL_BURN = 81;
-const int PROJECTILE_NADE_MONSTER = 82;
-const int PROJECTILE_NADE_MONSTER_BURN = 83;
-
-REGISTRY(Nades, BITS(4))
-#define Nades_from(i) _Nades_from(i, NADE_TYPE_Null)
-REGISTER_REGISTRY(RegisterNades)
-REGISTRY_CHECK(Nades)
-
-#define REGISTER_NADE(id) REGISTER(RegisterNades, NADE_TYPE, Nades, id, m_id, NEW(Nade))
-
-CLASS(Nade, Object)
- ATTRIB(Nade, m_id, int, 0)
- ATTRIB(Nade, m_color, vector, '0 0 0')
- ATTRIB(Nade, m_name, string, _("Grenade"))
- ATTRIB(Nade, m_icon, string, "nade_normal")
- ATTRIBARRAY(Nade, m_projectile, int, 2)
- ATTRIBARRAY(Nade, m_trail, entity, 2)
- METHOD(Nade, display, void(entity this, void(string name, string icon) returns)) {
- returns(this.m_name, sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.m_icon));
- }
-ENDCLASS(Nade)
-
-REGISTER_NADE(Null);
-
-#ifdef SVQC
-bool healer_send(entity this, entity to, int sf);
-#endif
-
-entity Nade_FromProjectile(float proj)
-{
- FOREACH(Nades, true, LAMBDA(
- for (int j = 0; j < 2; j++)
- {
- if (it.m_projectile[j] == proj) return it;
- }
- ));
- return NADE_TYPE_Null;
-}
-
-entity Nade_TrailEffect(int proj, int nade_team)
-{
- switch (proj)
- {
- case PROJECTILE_NADE: return EFFECT_NADE_TRAIL(nade_team);
- case PROJECTILE_NADE_BURN: return EFFECT_NADE_TRAIL_BURN(nade_team);
- }
-
- FOREACH(Nades, true, LAMBDA(
- for (int j = 0; j < 2; j++)
- {
- if (it.m_projectile[j] == proj)
- {
- string trail = it.m_trail[j].eent_eff_name;
- if (trail) return it.m_trail[j];
- break;
- }
- }
- ));
-
- return EFFECT_Null;
-}
-
-#include "all.inc"
-
-#endif
_notes = findchain(classname, "sv_notice");
if(!_notes)
return false;
- #define M1 30
- #define M2 10
+ const int M1 = 30;
+ const int M2 = 10;
vector v1, v2 = '0 0 0', v3;
v1 = '1 1 0' * M1;
if(_notes.alpha <= time)
{
- _notes.think = SUB_Remove;
+ _notes.think = SUB_Remove_self;
_notes.nextthink = time;
}
}
#undef OUT
- #undef M1
- #undef M2
return m;
}
// todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input
// this way, we don't need to have duplicates like i.e. s2loc and s3loc?
+string BUFF_NAME(int i);
+
#define NOTIF_ARGUMENT_LIST \
ARG_CASE(ARG_CS_SV_HA, "s1", s1) \
ARG_CASE(ARG_CS_SV_HA, "s2", s2) \
ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
ARG_CASE(ARG_CS_SV, "spree_lost", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \
ARG_CASE(ARG_CS_SV, "item_wepname", WEP_NAME(f1)) \
- ARG_CASE(ARG_CS_SV, "item_buffname", sprintf("%s%s", rgb_to_hexcolor(Buffs_from(f1).m_color), Buffs_from(f1).m_prettyName)) \
- ARG_CASE(ARG_CS_SV, "f3buffname", sprintf("%s%s", rgb_to_hexcolor(Buffs_from(f3).m_color), Buffs_from(f3).m_prettyName)) \
+ ARG_CASE(ARG_CS_SV, "item_buffname", BUFF_NAME(f1)) \
+ ARG_CASE(ARG_CS_SV, "f3buffname", BUFF_NAME(f3)) \
ARG_CASE(ARG_CS_SV, "item_wepammo", (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \
ARG_CASE(ARG_DC, "item_centime", ftos(autocvar_notification_item_centerprinttime)) \
ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \
RaceCarPhysics();
#endif
- else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY || self.movetype == MOVETYPE_FLY_WORLDONLY || (BUFFS_STAT(self) & BUFF_FLIGHT.m_itemid))
+ else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY || self.movetype == MOVETYPE_FLY_WORLDONLY || MUTATOR_CALLHOOK(IsFlying, self))
PM_fly(maxspeed_mod);
else if (self.waterlevel >= WATERLEVEL_SWIMMING)
REGISTRY(Sounds, BITS(8))
#define Sounds_from(i) _Sounds_from(i, SND_Null)
-REGISTER_REGISTRY(RegisterSounds)
+REGISTER_REGISTRY(Sounds)
#define SOUND(name, path) \
string SND_##name##_get() { return path; } \
- REGISTER(RegisterSounds, SND, Sounds, name, m_id, NEW(Sound, SND_##name##_get))
+ REGISTER(Sounds, SND, name, m_id, NEW(Sound, SND_##name##_get))
// Used in places where a string is required
#define SND(id) Sound_fixpath(SND_##id)
}
}
-void func_breakable_reset()
-{SELFPARAM();
- self.team = self.team_saved;
+void func_breakable_reset(entity this)
+{
+ this.team = this.team_saved;
func_breakable_look_restore();
- if(self.spawnflags & 1)
+ if(this.spawnflags & 1)
func_breakable_behave_destroyed();
else
func_breakable_behave_restore();
- CSQCMODEL_AUTOUPDATE(self);
+ CSQCMODEL_AUTOUPDATE(this);
}
// destructible walls that can be used to trigger target_objective_decrease
spawnfunc(func_breakable)
{
float n, i;
- if(!self.health)
- self.health = 100;
- self.max_health = self.health;
+ if(!this.health)
+ this.health = 100;
+ this.max_health = this.health;
// yes, I know, MOVETYPE_NONE is not available here, not that one would want it here anyway
- if(!self.debrismovetype) self.debrismovetype = MOVETYPE_BOUNCE;
- if(!self.debrissolid) self.debrissolid = SOLID_NOT;
- if(self.debrisvelocity == '0 0 0') self.debrisvelocity = '0 0 140';
- if(self.debrisvelocityjitter == '0 0 0') self.debrisvelocityjitter = '70 70 70';
- if(self.debrisavelocityjitter == '0 0 0') self.debrisavelocityjitter = '600 600 600';
- if(!self.debristime) self.debristime = 3.5;
- if(!self.debristimejitter) self.debristime = 2.5;
-
- if(self.mdl != "")
- self.cnt = _particleeffectnum(self.mdl);
- if(self.count == 0)
- self.count = 1;
-
- if(self.message == "")
- self.message = "got too close to an explosion";
- if(self.message2 == "")
- self.message2 = "was pushed into an explosion by";
- if(!self.dmg_radius)
- self.dmg_radius = 150;
- if(!self.dmg_force)
- self.dmg_force = 200;
-
- self.mdl = self.model;
+ if(!this.debrismovetype) this.debrismovetype = MOVETYPE_BOUNCE;
+ if(!this.debrissolid) this.debrissolid = SOLID_NOT;
+ if(this.debrisvelocity == '0 0 0') this.debrisvelocity = '0 0 140';
+ if(this.debrisvelocityjitter == '0 0 0') this.debrisvelocityjitter = '70 70 70';
+ if(this.debrisavelocityjitter == '0 0 0') this.debrisavelocityjitter = '600 600 600';
+ if(!this.debristime) this.debristime = 3.5;
+ if(!this.debristimejitter) this.debristime = 2.5;
+
+ if(this.mdl != "")
+ this.cnt = _particleeffectnum(this.mdl);
+ if(this.count == 0)
+ this.count = 1;
+
+ if(this.message == "")
+ this.message = "got too close to an explosion";
+ if(this.message2 == "")
+ this.message2 = "was pushed into an explosion by";
+ if(!this.dmg_radius)
+ this.dmg_radius = 150;
+ if(!this.dmg_force)
+ this.dmg_force = 200;
+
+ this.mdl = this.model;
SetBrushEntityModel();
- if(self.spawnflags & 4)
- self.use = func_breakable_destroy;
+ if(this.spawnflags & 4)
+ this.use = func_breakable_destroy;
else
- self.use = func_breakable_restore;
+ this.use = func_breakable_restore;
- if(self.spawnflags & 4)
+ if(this.spawnflags & 4)
{
- self.takedamage = DAMAGE_NO;
- self.event_damage = func_null;
- self.bot_attack = false;
+ this.takedamage = DAMAGE_NO;
+ this.event_damage = func_null;
+ this.bot_attack = false;
}
// precache all the models
- if (self.mdl_dead)
- precache_model(self.mdl_dead);
- n = tokenize_console(self.debris);
+ if (this.mdl_dead)
+ precache_model(this.mdl_dead);
+ n = tokenize_console(this.debris);
for(i = 0; i < n; ++i)
precache_model(argv(i));
- if(self.noise)
- precache_sound(self.noise);
- if(self.noise1)
- precache_sound(self.noise1);
+ if(this.noise)
+ precache_sound(this.noise);
+ if(this.noise1)
+ precache_sound(this.noise1);
- self.team_saved = self.team;
- self.dropped_origin = self.origin;
+ this.team_saved = this.team;
+ this.dropped_origin = this.origin;
- self.reset = func_breakable_reset;
- func_breakable_reset();
+ this.reset = func_breakable_reset;
+ this.reset(this);
- self.init_for_player_needed = 1;
- self.init_for_player = func_breakable_init_for_player;
+ this.init_for_player_needed = 1;
+ this.init_for_player = func_breakable_init_for_player;
- CSQCMODEL_AUTOINIT(self);
+ CSQCMODEL_AUTOINIT(this);
}
// for use in maps with a "model" key set
self.SendFlags |= 2;
}
-void conveyor_reset()
-{SELFPARAM();
- self.state = (self.spawnflags & 1);
+void conveyor_reset(entity this)
+{
+ this.state = (this.spawnflags & 1);
- self.SendFlags |= 2;
+ this.SendFlags |= 2;
}
bool conveyor_send(entity this, entity to, int sf)
void conveyor_init()
{SELFPARAM();
- if (!self.speed)
- self.speed = 200;
- self.movedir = self.movedir * self.speed;
- self.think = conveyor_think;
- self.nextthink = time;
+ if (!this.speed) this.speed = 200;
+ this.movedir *= this.speed;
+ this.think = conveyor_think;
+ this.nextthink = time;
IFTARGETED
{
- self.use = conveyor_use;
- self.reset = conveyor_reset;
- conveyor_reset();
+ this.use = conveyor_use;
+ this.reset = conveyor_reset;
+ this.reset(this);
}
else
- self.state = 1;
+ this.state = 1;
- FixSize(self);
+ FixSize(this);
- Net_LinkEntity(self, 0, false, conveyor_send);
+ Net_LinkEntity(this, 0, false, conveyor_send);
- self.SendFlags |= 1;
+ this.SendFlags |= 1;
}
spawnfunc(trigger_conveyor)
#endif
}
-void door_reset()
-{SELFPARAM();
- SUB_SETORIGIN(self, self.pos1);
- self.SUB_VELOCITY = '0 0 0';
- self.state = STATE_BOTTOM;
- self.SUB_THINK = func_null;
- self.SUB_NEXTTHINK = 0;
+void door_reset(entity this)
+{
+ SUB_SETORIGIN(this, this.pos1);
+ this.SUB_VELOCITY = '0 0 0';
+ this.state = STATE_BOTTOM;
+ this.SUB_THINK = func_null;
+ this.SUB_NEXTTHINK = 0;
#ifdef SVQC
- self.SendFlags |= SF_TRIGGER_RESET;
+ this.SendFlags |= SF_TRIGGER_RESET;
#endif
}
if(sf & SF_TRIGGER_INIT)
{
- self.classname = strzone(ReadString());
- self.spawnflags = ReadByte();
+ this.classname = strzone(ReadString());
+ this.spawnflags = ReadByte();
- self.mdl = strzone(ReadString());
- _setmodel(self, self.mdl);
+ this.mdl = strzone(ReadString());
+ _setmodel(this, this.mdl);
trigger_common_read(true);
- self.pos1_x = ReadCoord();
- self.pos1_y = ReadCoord();
- self.pos1_z = ReadCoord();
- self.pos2_x = ReadCoord();
- self.pos2_y = ReadCoord();
- self.pos2_z = ReadCoord();
-
- self.size_x = ReadCoord();
- self.size_y = ReadCoord();
- self.size_z = ReadCoord();
-
- self.wait = ReadShort();
- self.speed = ReadShort();
- self.lip = ReadByte();
- self.state = ReadByte();
- self.SUB_LTIME = ReadCoord();
-
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- self.trigger_touch = door_touch;
- self.draw = door_draw;
- self.drawmask = MASK_NORMAL;
- self.use = door_use;
+ vector v;
+
+ v.x = ReadCoord();
+ v.y = ReadCoord();
+ v.z = ReadCoord();
+ this.pos1 = v;
+
+ v.x = ReadCoord();
+ v.y = ReadCoord();
+ v.z = ReadCoord();
+ this.pos2 = v;
+
+ v.x = ReadCoord();
+ v.y = ReadCoord();
+ v.z = ReadCoord();
+ this.size = v;
+
+ this.wait = ReadShort();
+ this.speed = ReadShort();
+ this.lip = ReadByte();
+ this.state = ReadByte();
+ this.SUB_LTIME = ReadCoord();
+
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ this.trigger_touch = door_touch;
+ this.draw = door_draw;
+ this.drawmask = MASK_NORMAL;
+ this.use = door_use;
LinkDoors();
- if(self.spawnflags & DOOR_START_OPEN)
+ if(this.spawnflags & DOOR_START_OPEN)
door_init_startopen();
- self.move_time = time;
- self.move_origin = self.origin;
- self.move_movetype = MOVETYPE_PUSH;
- self.move_angles = self.angles;
- self.move_blocked = door_blocked;
+ this.move_time = time;
+ this.move_origin = this.origin;
+ this.move_movetype = MOVETYPE_PUSH;
+ this.move_angles = this.angles;
+ this.move_blocked = door_blocked;
}
if(sf & SF_TRIGGER_RESET)
{
- door_reset();
+ door_reset(this);
}
if(sf & SF_TRIGGER_UPDATE)
{
- self.origin_x = ReadCoord();
- self.origin_y = ReadCoord();
- self.origin_z = ReadCoord();
- setorigin(self, self.origin);
- self.move_origin = self.origin;
-
- self.pos1_x = ReadCoord();
- self.pos1_y = ReadCoord();
- self.pos1_z = ReadCoord();
- self.pos2_x = ReadCoord();
- self.pos2_y = ReadCoord();
- self.pos2_z = ReadCoord();
+ this.origin_x = ReadCoord();
+ this.origin_y = ReadCoord();
+ this.origin_z = ReadCoord();
+ setorigin(this, this.origin);
+ this.move_origin = this.origin;
+
+ this.pos1_x = ReadCoord();
+ this.pos1_y = ReadCoord();
+ this.pos1_z = ReadCoord();
+ this.pos2_x = ReadCoord();
+ this.pos2_y = ReadCoord();
+ this.pos2_z = ReadCoord();
}
return true;
}
FIXME: only one sound set available at the time being
*/
-void door_rotating_reset()
-{SELFPARAM();
- self.angles = self.pos1;
- self.avelocity = '0 0 0';
- self.state = STATE_BOTTOM;
- self.think = func_null;
- self.nextthink = 0;
+void door_rotating_reset(entity this)
+{
+ this.angles = this.pos1;
+ this.avelocity = '0 0 0';
+ this.state = STATE_BOTTOM;
+ this.think = func_null;
+ this.nextthink = 0;
}
void door_rotating_init_startopen()
}
}
-void secret_reset()
-{SELFPARAM();
- if (self.spawnflags&SECRET_YES_SHOOT)
+void secret_reset(entity this)
+{
+ if (this.spawnflags & SECRET_YES_SHOOT)
{
- self.health = 10000;
- self.takedamage = DAMAGE_YES;
+ this.health = 10000;
+ this.takedamage = DAMAGE_YES;
}
- setorigin(self, self.oldorigin);
- self.think = func_null;
- self.SUB_NEXTTHINK = 0;
+ setorigin(this, this.oldorigin);
+ this.think = func_null;
+ this.SUB_NEXTTHINK = 0;
}
/*QUAKED spawnfunc_func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot
spawnfunc(func_door_secret)
{
- /*if (!self.deathtype) // map makers can override this
- self.deathtype = " got in the way";*/
+ /*if (!this.deathtype) // map makers can override this
+ this.deathtype = " got in the way";*/
- if (!self.dmg)
- self.dmg = 2;
+ if (!this.dmg) this.dmg = 2;
// Magic formula...
- self.mangle = self.angles;
- self.angles = '0 0 0';
- self.classname = "door";
- if (!InitMovingBrushTrigger())
- return;
- self.effects |= EF_LOWPRECISION;
-
- if(self.noise == "")
- self.noise = "misc/talk.wav";
- precache_sound(self.noise);
-
- self.touch = secret_touch;
- self.blocked = secret_blocked;
- self.speed = 50;
- self.use = fd_secret_use;
+ this.mangle = this.angles;
+ this.angles = '0 0 0';
+ this.classname = "door";
+ if (!InitMovingBrushTrigger()) return;
+ this.effects |= EF_LOWPRECISION;
+
+ if (this.noise == "") this.noise = "misc/talk.wav";
+ precache_sound(this.noise);
+
+ this.touch = secret_touch;
+ this.blocked = secret_blocked;
+ this.speed = 50;
+ this.use = fd_secret_use;
IFTARGETED
{
}
else
- self.spawnflags |= SECRET_YES_SHOOT;
+ this.spawnflags |= SECRET_YES_SHOOT;
- if(self.spawnflags&SECRET_YES_SHOOT)
+ if (this.spawnflags & SECRET_YES_SHOOT)
{
- self.health = 10000;
- self.takedamage = DAMAGE_YES;
- self.event_damage = fd_secret_damage;
+ this.health = 10000;
+ this.takedamage = DAMAGE_YES;
+ this.event_damage = fd_secret_damage;
}
- self.oldorigin = self.origin;
- if (!self.wait)
- self.wait = 5; // 5 seconds before closing
+ this.oldorigin = this.origin;
+ if (!this.wait) this.wait = 5; // seconds before closing
- self.reset = secret_reset;
- secret_reset();
+ this.reset = secret_reset;
+ this.reset(this);
}
#endif
spawnfunc(func_plat)
{
- if (self.sounds == 0)
- self.sounds = 2;
+ if (this.sounds == 0) this.sounds = 2;
- if(self.spawnflags & 4)
- self.dmg = 10000;
+ if (this.spawnflags & 4) this.dmg = 10000;
- if(self.dmg && (self.message == ""))
- self.message = "was squished";
- if(self.dmg && (self.message2 == ""))
- self.message2 = "was squished by";
+ if (this.dmg && (this.message == "")) this.message = "was squished";
+ if (this.dmg && (this.message2 == "")) this.message2 = "was squished by";
- if (self.sounds == 1)
+ if (this.sounds == 1)
{
precache_sound ("plats/plat1.wav");
precache_sound ("plats/plat2.wav");
- self.noise = "plats/plat1.wav";
- self.noise1 = "plats/plat2.wav";
+ this.noise = "plats/plat1.wav";
+ this.noise1 = "plats/plat2.wav";
}
- if (self.sounds == 2)
+ if (this.sounds == 2)
{
precache_sound ("plats/medplat1.wav");
precache_sound ("plats/medplat2.wav");
- self.noise = "plats/medplat1.wav";
- self.noise1 = "plats/medplat2.wav";
+ this.noise = "plats/medplat1.wav";
+ this.noise1 = "plats/medplat2.wav";
}
- if (self.sound1)
+ if (this.sound1)
{
- precache_sound (self.sound1);
- self.noise = self.sound1;
+ precache_sound (this.sound1);
+ this.noise = this.sound1;
}
- if (self.sound2)
+ if (this.sound2)
{
- precache_sound (self.sound2);
- self.noise1 = self.sound2;
+ precache_sound (this.sound2);
+ this.noise1 = this.sound2;
}
- self.mangle = self.angles;
- self.angles = '0 0 0';
+ this.mangle = this.angles;
+ this.angles = '0 0 0';
- self.classname = "plat";
+ this.classname = "plat";
if (!InitMovingBrushTrigger())
return;
- self.effects |= EF_LOWPRECISION;
- setsize (self, self.mins , self.maxs);
+ this.effects |= EF_LOWPRECISION;
+ setsize (this, this.mins , this.maxs);
- self.blocked = plat_crush;
+ this.blocked = plat_crush;
- if (!self.speed)
- self.speed = 150;
- if (!self.lip)
- self.lip = 16;
- if (!self.height)
- self.height = self.size_z - self.lip;
+ if (!this.speed) this.speed = 150;
+ if (!this.lip) this.lip = 16;
+ if (!this.height) this.height = this.size.z - this.lip;
- self.pos1 = self.origin;
- self.pos2 = self.origin;
- self.pos2_z = self.origin_z - self.height;
+ this.pos1 = this.origin;
+ this.pos2 = this.origin;
+ this.pos2_z = this.origin.z - this.height;
- self.reset = plat_reset;
- plat_reset();
+ this.reset = plat_reset;
+ this.reset(this);
- InitializeEntity(self, plat_delayedinit, INITPRIO_FINDTARGET);
+ InitializeEntity(this, plat_delayedinit, INITPRIO_FINDTARGET);
}
#elif defined(CSQC)
void plat_draw(entity this)
if(sf & SF_TRIGGER_INIT)
{
- self.platmovetype_start = ReadByte();
- self.platmovetype_turn = ReadByte();
- self.platmovetype_end = ReadByte();
- self.spawnflags = ReadByte();
+ this.platmovetype_start = ReadByte();
+ this.platmovetype_turn = ReadByte();
+ this.platmovetype_end = ReadByte();
+ this.spawnflags = ReadByte();
- self.model = strzone(ReadString());
- _setmodel(self, self.model);
+ this.model = strzone(ReadString());
+ _setmodel(this, this.model);
trigger_common_read(true);
- self.pos1_x = ReadCoord();
- self.pos1_y = ReadCoord();
- self.pos1_z = ReadCoord();
- self.pos2_x = ReadCoord();
- self.pos2_y = ReadCoord();
- self.pos2_z = ReadCoord();
+ this.pos1_x = ReadCoord();
+ this.pos1_y = ReadCoord();
+ this.pos1_z = ReadCoord();
+ this.pos2_x = ReadCoord();
+ this.pos2_y = ReadCoord();
+ this.pos2_z = ReadCoord();
- self.size_x = ReadCoord();
- self.size_y = ReadCoord();
- self.size_z = ReadCoord();
+ this.size_x = ReadCoord();
+ this.size_y = ReadCoord();
+ this.size_z = ReadCoord();
- self.mangle_x = ReadAngle();
- self.mangle_y = ReadAngle();
- self.mangle_z = ReadAngle();
+ this.mangle_x = ReadAngle();
+ this.mangle_y = ReadAngle();
+ this.mangle_z = ReadAngle();
- self.speed = ReadShort();
- self.height = ReadShort();
- self.lip = ReadByte();
- self.state = ReadByte();
+ this.speed = ReadShort();
+ this.height = ReadShort();
+ this.lip = ReadByte();
+ this.state = ReadByte();
- self.dmg = ReadShort();
+ this.dmg = ReadShort();
- self.classname = "plat";
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- self.drawmask = MASK_NORMAL;
- self.draw = plat_draw;
- self.use = plat_use;
- self.entremove = trigger_remove_generic;
+ this.classname = "plat";
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ this.drawmask = MASK_NORMAL;
+ this.draw = plat_draw;
+ this.use = plat_use;
+ this.entremove = trigger_remove_generic;
- plat_reset(); // also called here
+ plat_reset(this); // also called here
- self.move_movetype = MOVETYPE_PUSH;
- self.move_origin = self.origin;
- self.move_angles = self.angles;
- self.move_time = time;
+ this.move_movetype = MOVETYPE_PUSH;
+ this.move_origin = this.origin;
+ this.move_angles = this.angles;
+ this.move_time = time;
plat_spawn_inside_trigger();
}
if(sf & SF_TRIGGER_RESET)
{
- plat_reset();
+ plat_reset(this);
- self.move_origin = self.origin;
- self.move_angles = self.angles;
- self.move_time = time;
+ this.move_origin = this.origin;
+ this.move_angles = this.angles;
+ this.move_time = time;
}
return true;
}
self.nextthink = time;
}
-void pointparticles_reset()
-{SELFPARAM();
- if(self.spawnflags & 1)
- self.state = 1;
+void pointparticles_reset(entity this)
+{
+ if(this.spawnflags & 1)
+ this.state = 1;
else
- self.state = 0;
+ this.state = 0;
}
spawnfunc(func_pointparticles)
{
- if(self.model != "")
- _setmodel(self, self.model);
- if(self.noise != "")
- precache_sound (self.noise);
+ if(this.model != "") _setmodel(this, this.model);
+ if(this.noise != "") precache_sound(this.noise);
- if(!self.bgmscriptsustain)
- self.bgmscriptsustain = 1;
- else if(self.bgmscriptsustain < 0)
- self.bgmscriptsustain = 0;
+ if(!this.bgmscriptsustain) this.bgmscriptsustain = 1;
+ else if(this.bgmscriptsustain < 0) this.bgmscriptsustain = 0;
- if(!self.atten)
- self.atten = ATTEN_NORM;
- else if(self.atten < 0)
- self.atten = 0;
- if(!self.volume)
- self.volume = 1;
- if(!self.count)
- self.count = 1;
- if(!self.impulse)
- self.impulse = 1;
+ if(!this.atten) this.atten = ATTEN_NORM;
+ else if(this.atten < 0) this.atten = 0;
+ if(!this.volume) this.volume = 1;
+ if(!this.count) this.count = 1;
+ if(!this.impulse) this.impulse = 1;
- if(!self.modelindex)
+ if(!this.modelindex)
{
- setorigin(self, self.origin + self.mins);
- setsize(self, '0 0 0', self.maxs - self.mins);
+ setorigin(this, this.origin + this.mins);
+ setsize(this, '0 0 0', this.maxs - this.mins);
}
- if(!self.cnt)
- self.cnt = _particleeffectnum(self.mdl);
+ if(!this.cnt) this.cnt = _particleeffectnum(this.mdl);
- Net_LinkEntity(self, (self.spawnflags & 4), 0, pointparticles_SendEntity);
+ Net_LinkEntity(this, (this.spawnflags & 4), 0, pointparticles_SendEntity);
IFTARGETED
{
- self.use = pointparticles_use;
- self.reset = pointparticles_reset;
- self.reset();
+ this.use = pointparticles_use;
+ this.reset = pointparticles_reset;
+ this.reset(this);
}
else
- self.state = 1;
- self.think = pointparticles_think;
- self.nextthink = time;
+ this.state = 1;
+ this.think = pointparticles_think;
+ this.nextthink = time;
}
spawnfunc(func_sparks)
#if defined(CSQC)
- #include "../../buffs/all.qh"
#include "../../../lib/csqcmodel/interpolate.qh"
#include "../../../client/main.qh"
#include "../../../lib/csqcmodel/cl_model.qh"
misc_laser_aim();
}
-void laser_reset()
-{SELFPARAM();
- if(self.spawnflags & 1)
- self.state = 1;
+void laser_reset(entity this)
+{
+ if(this.spawnflags & 1)
+ this.state = 1;
else
- self.state = 0;
+ this.state = 0;
}
spawnfunc(misc_laser)
{
- if(self.mdl)
+ if(this.mdl)
{
- if(self.mdl == "none")
- self.cnt = -1;
+ if(this.mdl == "none")
+ this.cnt = -1;
else
{
- self.cnt = _particleeffectnum(self.mdl);
- if(self.cnt < 0)
- if(self.dmg)
- self.cnt = particleeffectnum(EFFECT_LASER_DEADLY);
+ this.cnt = _particleeffectnum(this.mdl);
+ if(this.cnt < 0 && this.dmg)
+ this.cnt = particleeffectnum(EFFECT_LASER_DEADLY);
}
}
- else if(!self.cnt)
+ else if(!this.cnt)
{
- if(self.dmg)
- self.cnt = particleeffectnum(EFFECT_LASER_DEADLY);
+ if(this.dmg)
+ this.cnt = particleeffectnum(EFFECT_LASER_DEADLY);
else
- self.cnt = -1;
+ this.cnt = -1;
}
- if(self.cnt < 0)
- self.cnt = -1;
+ if(this.cnt < 0)
+ this.cnt = -1;
- if(self.colormod == '0 0 0')
- if(!self.alpha)
- self.colormod = '1 0 0';
- if(self.message == "")
- self.message = "saw the light";
- if (self.message2 == "")
- self.message2 = "was pushed into a laser by";
- if(!self.scale)
- self.scale = 1;
- if(!self.modelscale)
- self.modelscale = 1;
- else if(self.modelscale < 0)
- self.modelscale = 0;
- self.think = misc_laser_think;
- self.nextthink = time;
- InitializeEntity(self, misc_laser_init, INITPRIO_FINDTARGET);
+ if(this.colormod == '0 0 0')
+ if(!this.alpha)
+ this.colormod = '1 0 0';
+ if(this.message == "") this.message = "saw the light";
+ if (this.message2 == "") this.message2 = "was pushed into a laser by";
+ if(!this.scale) this.scale = 1;
+ if(!this.modelscale) this.modelscale = 1;
+ else if(this.modelscale < 0) this.modelscale = 0;
+ this.think = misc_laser_think;
+ this.nextthink = time;
+ InitializeEntity(this, misc_laser_init, INITPRIO_FINDTARGET);
- self.mangle = self.angles;
+ this.mangle = this.angles;
- Net_LinkEntity(self, false, 0, laser_SendEntity);
+ Net_LinkEntity(this, false, 0, laser_SendEntity);
IFTARGETED
{
- self.reset = laser_reset;
- laser_reset();
- self.use = laser_use;
+ this.reset = laser_reset;
+ this.reset(this);
+ this.use = laser_use;
}
else
- self.state = 1;
+ this.state = 1;
}
#elif defined(CSQC)
.string sound1, sound2;
-void plat_reset()
-{SELFPARAM();
+void plat_reset(entity this)
+{
IFTARGETED
{
- setorigin (self, self.pos1);
- self.state = 4;
- self.use = plat_use;
+ setorigin (this, this.pos1);
+ this.state = 4;
+ this.use = plat_use;
}
else
{
- setorigin (self, self.pos2);
- self.state = 2;
- self.use = plat_trigger_use;
+ setorigin (this, this.pos2);
+ this.state = 2;
+ this.use = plat_trigger_use;
}
#ifdef SVQC
- self.SendFlags |= SF_TRIGGER_RESET;
+ this.SendFlags |= SF_TRIGGER_RESET;
#endif
}
#endif
-void SUB_Remove();
void SUB_SetFade (entity ent, float when, float fading_time);
void SUB_VanishOrRemove (entity ent);
WriteByte(to, self.lifetime);
WriteString(to, self.noise);
}
-void target_music_reset()
-{SELFPARAM();
- if(self.targetname == "")
- target_music_sendto(MSG_ALL, 1);
+void target_music_reset(entity this)
+{
+ if (this.targetname == "") target_music_sendto(MSG_ALL, 1);
}
void target_music_kill()
{
}
return 1;
}
-void trigger_music_reset()
-{SELFPARAM();
- self.cnt = !(self.spawnflags & 1);
- self.SendFlags |= 0x80;
+void trigger_music_reset(entity this)
+{
+ this.cnt = !(this.spawnflags & 1);
+ this.SendFlags |= 0x80;
}
void trigger_music_use()
{SELFPARAM();
}
spawnfunc(trigger_music)
{
- if(self.model != "")
- _setmodel(self, self.model);
- if(!self.volume)
- self.volume = 1;
- if(!self.modelindex)
+ if(this.model != "") _setmodel(this, this.model);
+ if(!this.volume) this.volume = 1;
+ if(!this.modelindex)
{
- setorigin(self, self.origin + self.mins);
- setsize(self, '0 0 0', self.maxs - self.mins);
+ setorigin(this, this.origin + this.mins);
+ setsize(this, '0 0 0', this.maxs - this.mins);
}
- trigger_music_reset();
+ trigger_music_reset(this);
- self.use = trigger_music_use;
- self.reset = trigger_music_reset;
+ this.use = trigger_music_use;
+ this.reset = trigger_music_reset;
- Net_LinkEntity(self, false, 0, trigger_music_SendEntity);
+ Net_LinkEntity(this, false, 0, trigger_music_SendEntity);
}
#elif defined(CSQC)
sound(self, CH_TRIGGER_SINGLE, SND_Null, VOL_BASE * self.volume, self.atten);
self.use = target_speaker_use_on;
}
-void target_speaker_reset()
-{SELFPARAM();
- if(self.spawnflags & 1) // LOOPED_ON
+void target_speaker_reset(entity this)
+{
+ if(this.spawnflags & 1) // LOOPED_ON
{
- if(self.use == target_speaker_use_on)
+ if(this.use == target_speaker_use_on)
target_speaker_use_on();
}
- else if(self.spawnflags & 2)
+ else if(this.spawnflags & 2)
{
- if(self.use == target_speaker_use_off)
+ if(this.use == target_speaker_use_off)
target_speaker_use_off();
}
}
}
}
-void counter_reset()
-{SELFPARAM();
- self.count = self.cnt;
- multi_reset();
+void counter_reset(entity this)
+{
+ this.count = this.cnt;
+ multi_reset(this);
}
/*QUAKED spawnfunc_trigger_counter (.5 .5 .5) ? nomessage
self.nextthink = self.wait;
}
-void delay_reset()
-{SELFPARAM();
- self.think = func_null;
- self.nextthink = 0;
+void delay_reset(entity this)
+{
+ this.think = func_null;
+ this.nextthink = 0;
}
spawnfunc(trigger_delay)
SUB_UseTargets();
}
-void _spawnfunc_trigger_flipflop();
spawnfunc(trigger_flipflop)
{
- if(self.spawnflags & 1)
- self.state = 1;
- self.use = flipflop_use;
- self.reset = _spawnfunc_trigger_flipflop; // perfect resetter
+ if(this.spawnflags & 1)
+ this.state = 1;
+ this.use = flipflop_use;
+ this.reset = spawnfunc_trigger_flipflop; // perfect resetter
}
-void _spawnfunc_trigger_flipflop() { SELFPARAM(); spawnfunc_trigger_flipflop(this); }
#endif
remove(self);
}
-void _spawnfunc_trigger_gamestart();
+void self_spawnfunc_trigger_gamestart();
spawnfunc(trigger_gamestart)
{
- self.use = gamestart_use;
- self.reset2 = _spawnfunc_trigger_gamestart;
+ this.use = gamestart_use;
+ this.reset2 = self_spawnfunc_trigger_gamestart;
- if(self.wait)
+ if(this.wait)
{
- self.think = self.use;
- self.nextthink = game_starttime + self.wait;
+ this.think = this.use;
+ this.nextthink = game_starttime + this.wait;
}
else
- InitializeEntity(self, gamestart_use, INITPRIO_FINDTARGET);
+ InitializeEntity(this, gamestart_use, INITPRIO_FINDTARGET);
}
-void _spawnfunc_trigger_gamestart() { SELFPARAM(); spawnfunc_trigger_gamestart(this); }
+void self_spawnfunc_trigger_gamestart() { SELFPARAM(); spawnfunc_trigger_gamestart(this); }
#endif
void trigger_push_touch()
{SELFPARAM();
- if (self.active == ACTIVE_NOT)
+ if (this.active == ACTIVE_NOT)
return;
#ifdef SVQC
return;
#endif
- if(self.team)
- if(((self.spawnflags & 4) == 0) == (DIFF_TEAM(self, other)))
+ if(this.team)
+ if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, other)))
return;
EXACTTRIGGER_TOUCH;
- if(self.enemy)
+ if(this.enemy)
{
- other.velocity = trigger_push_calculatevelocity(other.origin, self.enemy, self.height);
+ other.velocity = trigger_push_calculatevelocity(other.origin, this.enemy, this.height);
other.move_velocity = other.velocity;
}
- else if(self.target)
+ else if(this.target)
{
entity e;
RandomSelection_Init();
- for(e = world; (e = find(e, targetname, self.target)); )
+ for(e = world; (e = find(e, targetname, this.target)); )
{
if(e.cnt)
RandomSelection_Add(e, 0, string_null, e.cnt, 1);
else
RandomSelection_Add(e, 0, string_null, 1, 1);
}
- other.velocity = trigger_push_calculatevelocity(other.origin, RandomSelection_chosen_ent, self.height);
+ other.velocity = trigger_push_calculatevelocity(other.origin, RandomSelection_chosen_ent, this.height);
other.move_velocity = other.velocity;
}
else
{
- other.velocity = self.movedir;
+ other.velocity = this.movedir;
other.move_velocity = other.velocity;
}
// reset tracking of oldvelocity for impact damage (sudden velocity changes)
other.oldvelocity = other.velocity;
- if(self.pushltime < time) // prevent "snorring" sound when a player hits the jumppad more than once
+ if(this.pushltime < time) // prevent "snorring" sound when a player hits the jumppad more than once
{
// flash when activated
Send_Effect(EFFECT_JUMPPAD, other.origin, other.velocity, 1);
- _sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
- self.pushltime = time + 0.2;
+ _sound (other, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
+ this.pushltime = time + 0.2;
}
if(IS_REAL_CLIENT(other) || IS_BOT_CLIENT(other))
{
bool found = false;
for(int i = 0; i < other.jumppadcount && i < NUM_JUMPPADSUSED; ++i)
- if(other.(jumppadsused[i]) == self)
+ if(other.(jumppadsused[i]) == this)
found = true;
if(!found)
{
- other.(jumppadsused[other.jumppadcount % NUM_JUMPPADSUSED]) = self;
+ other.(jumppadsused[other.jumppadcount % NUM_JUMPPADSUSED]) = this;
other.jumppadcount = other.jumppadcount + 1;
}
if(IS_REAL_CLIENT(other))
{
- if(self.message)
- centerprint(other, self.message);
+ if(this.message)
+ centerprint(other, this.message);
}
else
other.lastteleporttime = time;
other.istypefrag = 0;
}
- if(self.enemy.target)
+ if(this.enemy.target)
{
activator = other;
- WITH(entity, self, self.enemy, SUB_UseTargets());
+ WITH(entity, self, this.enemy, SUB_UseTargets());
}
if (other.flags & FL_PROJECTILE)
UpdateCSQCProjectile(other);
}
- if (self.spawnflags & PUSH_ONCE)
+ if (this.spawnflags & PUSH_ONCE)
{
- self.touch = func_null;
- self.think = SUB_Remove;
- self.nextthink = time;
+ this.touch = func_null;
+ this.think = SUB_Remove_self;
+ this.nextthink = time;
}
#endif
}
SUB_UseTargets();
}
-void monoflop_reset()
-{SELFPARAM();
- self.state = 0;
- self.nextthink = 0;
+void monoflop_reset(entity this)
+{
+ this.state = 0;
+ this.nextthink = 0;
}
spawnfunc(trigger_monoflop)
}
}
-void multi_reset()
-{SELFPARAM();
- if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) )
- self.touch = multi_touch;
- if (self.max_health)
+void multi_reset(entity this)
+{
+ if ( !(this.spawnflags & SPAWNFLAG_NOTOUCH) )
+ this.touch = multi_touch;
+ if (this.max_health)
{
- self.health = self.max_health;
- self.takedamage = DAMAGE_YES;
- self.solid = SOLID_BBOX;
+ this.health = this.max_health;
+ this.takedamage = DAMAGE_YES;
+ this.solid = SOLID_BBOX;
}
- self.think = func_null;
- self.nextthink = 0;
- self.team = self.team_saved;
+ this.think = func_null;
+ this.nextthink = 0;
+ this.team = this.team_saved;
}
/*QUAKED spawnfunc_trigger_multiple (.5 .5 .5) ? notouch
#ifdef SVQC
void multi_trigger();
-void multi_reset();
+void multi_reset(entity this);
spawnfunc(trigger_once);
#endif
#ifdef SVQC
-void _spawnfunc_trigger_relay();
/*QUAKED spawnfunc_trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)
This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages.
*/
spawnfunc(trigger_relay)
{
- self.use = SUB_UseTargets;
- self.reset = _spawnfunc_trigger_relay; // this spawnfunc resets fully
+ this.use = SUB_UseTargets;
+ this.reset = spawnfunc_trigger_relay; // this spawnfunc resets fully
}
-void _spawnfunc_trigger_relay() { SELFPARAM(); spawnfunc_trigger_relay(this); }
#endif
}
}
-void trigger_relay_teamcheck_reset()
-{SELFPARAM();
- self.team = self.team_saved;
+void trigger_relay_teamcheck_reset(entity this)
+{
+ this.team = this.team_saved;
}
spawnfunc(trigger_relay_teamcheck)
{
- self.team_saved = self.team;
- self.use = trigger_relay_teamcheck_use;
- self.reset = trigger_relay_teamcheck_reset;
+ this.team_saved = this.team;
+ this.use = trigger_relay_teamcheck_use;
+ this.reset = trigger_relay_teamcheck_reset;
}
#endif
REGISTRY(Turrets, BITS(5))
#define Turrets_from(i) _Turrets_from(i, TUR_Null)
#define get_turretinfo(i) Turrets_from(i)
-REGISTER_REGISTRY(RegisterTurrets)
+REGISTER_REGISTRY(Turrets)
REGISTRY_CHECK(Turrets)
const int TUR_FIRST = 1;
#define TUR_LAST (Turrets_COUNT - 1)
-#define REGISTER_TURRET(id, inst) REGISTER(RegisterTurrets, TUR, Turrets, id, m_id, inst)
+#define REGISTER_TURRET(id, inst) REGISTER(Turrets, TUR, id, m_id, inst)
REGISTER_TURRET(Null, NEW(Turret));
}
#ifdef TURRET_DEBUG
-void SUB_Remove();
void marker_think()
{SELFPARAM();
if(self.cnt)
REGISTRY(Vehicles, BITS(3))
#define Vehicles_from(i) _Vehicles_from(i, VEH_Null)
#define get_vehicleinfo(i) Vehicles_from(i)
-REGISTER_REGISTRY(RegisterVehicles)
+REGISTER_REGISTRY(Vehicles)
REGISTRY_CHECK(Vehicles)
const int VEH_FIRST = 1;
#define VEH_LAST (Vehicles_COUNT - 1)
/** If you register a new vehicle, make sure to add it to all.inc */
-#define REGISTER_VEHICLE(id, inst) REGISTER(RegisterVehicles, VEH, Vehicles, id, vehicleid, inst)
+#define REGISTER_VEHICLE(id, inst) REGISTER(Vehicles, VEH, id, vehicleid, inst)
#if defined(SVQC)
#include "sv_vehicles.qh"
proj.use = vehicles_projectile_explode;
proj.owner = self;
proj.realowner = _owner;
- proj.think = SUB_Remove;
+ proj.think = SUB_Remove_self;
proj.nextthink = time + 30;
if(_health)
if(ret.wp00 == veh)
{
ret.classname = "";
- ret.think = SUB_Remove;
+ ret.think = SUB_Remove_self;
ret.nextthink = time + 0.1;
if(ret.waypointsprite_attached)
#include "../../lib/warpzone/common.qh"
#include "../../lib/warpzone/client.qh"
#include "../util.qh"
- #include "../buffs/all.qh"
#include "../../client/autocvars.qh"
#include "../deathtypes/all.qh"
#include "../../lib/csqcmodel/interpolate.qh"
#include "../stats.qh"
#include "../teams.qh"
#include "../util.qh"
- #include "../buffs/all.qh"
#include "../monsters/all.qh"
#include "config.qh"
#include "../../server/weapons/csqcprojectile.qh"
REGISTRY(Weapons, 72) // Increase as needed. Can be up to 72.
#define Weapons_from(i) _Weapons_from(i, WEP_Null)
#define get_weaponinfo(i) Weapons_from(i)
-REGISTER_REGISTRY(RegisterWeapons)
+REGISTER_REGISTRY(Weapons)
STATIC_INIT(WeaponPickup) { FOREACH(Weapons, true, LAMBDA(it.m_pickup = NEW(WeaponPickup, it))); }
#define REGISTER_WEAPON(id, inst) \
/* WepSet WEPSET_##id; */ \
- REGISTER(RegisterWeapons, WEP, Weapons, id, m_id, inst)
+ REGISTER(Weapons, WEP, id, m_id, inst)
// create cvars for weapon settings
#define WEP_ADD_CVAR_NONE(wepname,name) [[last]] float autocvar_g_balance_##wepname##_##name;
void W_Blaster_Think()
{SELFPARAM();
- self.movetype = MOVETYPE_FLY;
- self.think = SUB_Remove;
- self.nextthink = time + self.blaster_lifetime;
- CSQCProjectile(self, true, PROJECTILE_BLASTER, true);
+ this.movetype = MOVETYPE_FLY;
+ this.think = SUB_Remove_self;
+ this.nextthink = time + this.blaster_lifetime;
+ CSQCProjectile(this, true, PROJECTILE_BLASTER, true);
}
void W_Blaster_Attack(
W_Crylink_Dequeue_Raw(e.realowner, e.queueprev, e, e.queuenext);
}
-void W_Crylink_Reset()
-{SELFPARAM();
- W_Crylink_Dequeue(self);
- remove(self);
+void W_Crylink_Reset(entity this)
+{
+ W_Crylink_Dequeue(this);
+ remove(this);
}
// force projectile to explode
//missile.angles = vectoangles(missile.velocity); // csqc
missile.touch = W_HLAC_Touch;
- missile.think = SUB_Remove;
+ missile.think = SUB_Remove_self;
missile.nextthink = time + WEP_CVAR_PRI(hlac, lifetime);
//missile.angles = vectoangles(missile.velocity); // csqc
missile.touch = W_HLAC_Touch;
- missile.think = SUB_Remove;
+ missile.think = SUB_Remove_self;
missile.nextthink = time + WEP_CVAR_SEC(hlac, lifetime);
void W_MachineGun_MuzzleFlash_Think()
{SELFPARAM();
- self.frame = self.frame + 2;
- self.scale = self.scale * 0.5;
- self.alpha = self.alpha - 0.25;
- self.nextthink = time + 0.05;
+ this.frame += 2;
+ this.scale *= 0.5;
+ this.alpha -= 0.25;
+ this.nextthink = time + 0.05;
- if(self.alpha <= 0)
+ if(this.alpha <= 0)
{
- self.think = SUB_Remove;
- self.nextthink = time;
- self.realowner.muzzle_flash = world;
+ this.think = SUB_Remove_self;
+ this.nextthink = time;
+ this.realowner.muzzle_flash = world;
return;
}
missile.bot_dodge = true;
missile.bot_dodgerating = 50;
missile.touch = W_Seeker_Tag_Touch;
- missile.think = SUB_Remove;
+ missile.think = SUB_Remove_self;
missile.nextthink = time + WEP_CVAR(seeker, tag_lifetime);
missile.movetype = MOVETYPE_FLY;
missile.solid = SOLID_BBOX;
// muzzle flash for 1st person view
flash = spawn();
setmodel(flash, MDL_SHOTGUN_MUZZLEFLASH); // precision set below
- flash.think = SUB_Remove;
+ flash.think = SUB_Remove_self;
flash.nextthink = time + 0.06;
flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
W_AttachToShotorg(self, flash, '5 0 0');
#endif
#endif
#ifdef IMPLEMENTATION
+
+REGISTER_NET_TEMP(TE_CSQC_VAPORBEAMPARTICLE)
+
+#if defined(SVQC)
+void SendCSQCVaporizerBeamParticle(entity player, int hit) {
+ vector v;
+ v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+ WriteHeader(MSG_BROADCAST, TE_CSQC_VAPORBEAMPARTICLE);
+ WriteCoord(MSG_BROADCAST, w_shotorg.x);
+ WriteCoord(MSG_BROADCAST, w_shotorg.y);
+ WriteCoord(MSG_BROADCAST, w_shotorg.z);
+ WriteCoord(MSG_BROADCAST, v.x);
+ WriteCoord(MSG_BROADCAST, v.y);
+ WriteCoord(MSG_BROADCAST, v.z);
+ WriteByte(MSG_BROADCAST, hit);
+ WriteShort(MSG_BROADCAST, num_for_edict(player));
+ WriteByte(MSG_BROADCAST, player.team);
+}
+#elif defined(CSQC)
+bool autocvar_cl_vaporizerbeam_particle = false;
+float autocvar_cl_vaporizerbeam_lifetime = 0.8;
+float autocvar_cl_vaporizerbeam_colorboost = 0.7;
+
+string Draw_VaporizerBeam_trace_callback_tex;
+float Draw_VaporizerBeam_trace_callback_rnd;
+vector Draw_VaporizerBeam_trace_callback_rgb;
+float Draw_VaporizerBeam_trace_callback_a;
+void Draw_VaporizerBeam_trace_callback(vector start, vector hit, vector end)
+{
+ float i;
+ vector vorg;
+ vorg = WarpZone_TransformOrigin(WarpZone_trace_transform, view_origin);
+ for(i = 0; i < Draw_VaporizerBeam_trace_callback_a; ++i)
+ Draw_CylindricLine(hit, start, 8, Draw_VaporizerBeam_trace_callback_tex, 0.25, Draw_VaporizerBeam_trace_callback_rnd, Draw_VaporizerBeam_trace_callback_rgb, min(1, Draw_VaporizerBeam_trace_callback_a - i), DRAWFLAG_NORMAL, vorg);
+ Draw_VaporizerBeam_trace_callback_rnd += 0.25 * vlen(hit - start) / 8;
+}
+
+.vector vorg1, vorg2;
+.float spawn_time;
+void VaporizerBeam_Draw(entity this)
+{
+ //draw either the old v2.3 beam or the new beam
+ particles_alphamin = particles_alphamax = particles_fade = 1;
+
+ string tex = "particles/lgbeam";
+ if(this.cnt)
+ tex = "particles/gauntletbeam";
+ vector rgb = getcsqcplayercolor(this.sv_entnum);
+ rgb *= (1 + autocvar_cl_vaporizerbeam_colorboost);
+
+ float fail = (self.nextthink - time);
+
+ Draw_VaporizerBeam_trace_callback_tex = tex;
+ Draw_VaporizerBeam_trace_callback_rnd = 0;
+ Draw_VaporizerBeam_trace_callback_rgb = rgb;
+ Draw_VaporizerBeam_trace_callback_a = bound(0, fail, 1);
+ WarpZone_TraceBox_ThroughZone(this.vorg1, '0 0 0', '0 0 0', this.vorg2, MOVE_NOTHING, world, world, Draw_VaporizerBeam_trace_callback);
+ Draw_VaporizerBeam_trace_callback_tex = string_null;
+
+ /*if(!MUTATOR_CALLHOOK(Particles_VaporizerBeam, this.vorg1, this.vorg2))
+ if(autocvar_cl_particles_oldvortexbeam && (getstati(STAT_ALLOW_OLDVORTEXBEAM) || isdemo()))
+ WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum(EFFECT_VORTEX_BEAM_OLD), this.vorg1, this.vorg2, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);
+ else
+ WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum(EFFECT_VORTEX_BEAM), this.vorg1, this.vorg2, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);*/
+}
+
+NET_HANDLE(TE_CSQC_VAPORBEAMPARTICLE, bool isNew)
+{
+ Net_Accept(vortex_beam);
+ this.think = SUB_Remove_self;
+ this.nextthink = time + bound(0, autocvar_cl_vaporizerbeam_lifetime, 10);
+ this.draw = VaporizerBeam_Draw;
+ this.drawmask = MASK_NORMAL;
+
+ this.vorg1_x = ReadCoord(); this.vorg1_y = ReadCoord(); this.vorg1_z = ReadCoord();
+ this.vorg2_x = ReadCoord(); this.vorg2_y = ReadCoord(); this.vorg2_z = ReadCoord();
+ this.cnt = ReadByte();
+ this.sv_entnum = ReadShort();
+ this.team = ReadByte() - 1;
+
+ if(autocvar_cl_vaporizerbeam_particle)
+ {
+ WarpZone_TrailParticles(world, particleeffectnum(((this.cnt) ? EFFECT_VAPORIZER_HIT(this.team) : EFFECT_VAPORIZER(this.team))), this.vorg1, this.vorg2);
+ this.draw = func_null;
+ this.drawmask = MASK_NORMAL;
+ remove(this);
+ }
+
+ pointparticles(EFFECT_VORTEX_MUZZLEFLASH, this.vorg1, normalize(this.vorg2 - this.vorg1) * 1000, 1);
+ return true;
+}
+#endif
+
#ifdef SVQC
spawnfunc(weapon_vaporizer) { weapon_defaultspawnfunc(this, WEP_VAPORIZER); }
spawnfunc(weapon_minstanex) { spawnfunc_weapon_vaporizer(this); }
damage_goodhits = 0;
FireRailgunBullet(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, vaporizer_damage, 800, 0, 0, 0, 0, WEP_VAPORIZER.m_id);
+ // do this now, as goodhits is disabled below
+ SendCSQCVaporizerBeamParticle(self, damage_goodhits);
+
if(yoda && flying)
Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
if(damage_goodhits && self.vaporizer_lasthit)
self.vaporizer_lasthit = damage_goodhits;
- Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
-
- // teamcolor / hit beam effect
- vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
- Send_Effect((damage_goodhits ? EFFECT_VAPORIZER_HIT(self.team) : EFFECT_VAPORIZER(self.team)), w_shotorg, v, 1);
-
if(autocvar_g_rm)
if(!(trace_dphitq3surfaceflags & (Q3SURFACEFLAG_SKY | Q3SURFACEFLAG_NOIMPACT)))
W_RocketMinsta_Explosion(trace_endpos);
charge = sqrt(charge); // divide evenly among trail spacing and alpha
particles_alphamin = particles_alphamax = particles_fade = charge;
- if (autocvar_cl_particles_oldvortexbeam && (getstati(STAT_ALLOW_OLDVORTEXBEAM) || isdemo()))
+ if(!MUTATOR_CALLHOOK(Particles_VortexBeam, shotorg, endpos))
+ if(autocvar_cl_particles_oldvortexbeam && (getstati(STAT_ALLOW_OLDVORTEXBEAM) || isdemo()))
WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum(EFFECT_VORTEX_BEAM_OLD), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);
else
WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum(EFFECT_VORTEX_BEAM), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);
#pragma noref 0
-#define ReadFloat() ReadCoord()
-
#endif
#pragma noref 0
-#define WriteFloat(to, f) WriteCoord(to, f)
-
#endif
class(Defer).void() think;
class(Defer).float nextthink;
-/*
-==================
-SUB_Remove
+ /** Remove self */
+ void SUB_Remove(entity this)
+ {
+ remove(this);
+ }
-Remove self
-==================
-*/
- void SUB_Remove()
+ /** Remove self */
+ void SUB_Remove_self()
{
SELFPARAM();
- remove(self);
+ remove(this);
}
void defer_think()
{
SELFPARAM();
- self.think = SUB_Remove;
+ self.think = SUB_Remove_self;
self.nextthink = time;
WITH(entity, self, self.owner, self.use());
}
#define MAP_H
// Databases (hash tables)
-const float DB_BUCKETS = 8192;
-void db_save(float db, string pFilename)
+const int DB_BUCKETS = 8192;
+void db_save(int db, string filename)
{
- int fh = fopen(pFilename, FILE_WRITE);
+ int fh = fopen(filename, FILE_WRITE);
if (fh < 0)
{
- LOG_INFO(strcat("^1Can't write DB to ", pFilename));
+ LOG_WARNINGF("^1Can't write DB to %s\n", filename);
return;
}
- int n = buf_getsize(db);
fputs(fh, strcat(ftos(DB_BUCKETS), "\n"));
- for (int i = 0; i < n; ++i)
+ for (int i = 0, n = buf_getsize(db); i < n; ++i)
fputs(fh, strcat(bufstr_get(db, i), "\n"));
fclose(fh);
}
return buf_create();
}
-void db_put(float db, string pKey, string pValue);
+void db_put(int db, string key, string value);
-int db_load(string pFilename)
+int db_load(string filename)
{
int db = buf_create();
if (db < 0) return -1;
- int fh = fopen(pFilename, FILE_READ);
+ int fh = fopen(filename, FILE_READ);
if (fh < 0) return db;
string l = fgets(fh);
- if (stof(l) == DB_BUCKETS)
+ if (stoi(l) == DB_BUCKETS)
{
for (int i = 0; (l = fgets(fh)); ++i)
{
return db;
}
-void db_dump(float db, string pFilename)
+void db_dump(int db, string filename)
{
- int fh = fopen(pFilename, FILE_WRITE);
- if (fh < 0) error(strcat("Can't dump DB to ", pFilename));
- int n = buf_getsize(db);
+ int fh = fopen(filename, FILE_WRITE);
+ if (fh < 0) LOG_FATALF("Can't dump DB to %s\n");
fputs(fh, "0\n");
- for (int i = 0; i < n; ++i)
+ for (int i = 0, n = buf_getsize(db); i < n; ++i)
{
int m = tokenizebyseparator(bufstr_get(db, i), "\\");
for (int j = 2; j < m; j += 2)
fclose(fh);
}
-void db_close(float db)
+void db_close(int db)
{
buf_del(db);
}
-string db_get(float db, string pKey)
+string db_get(int db, string key)
{
- int h = crc16(false, pKey) % DB_BUCKETS;
- return uri_unescape(infoget(bufstr_get(db, h), pKey));
+ int h = crc16(false, key) % DB_BUCKETS;
+ return uri_unescape(infoget(bufstr_get(db, h), key));
}
-void db_put(float db, string pKey, string pValue)
+#define db_remove(db, key) db_put(db, key, "")
+
+void db_put(int db, string key, string value)
{
- int h = crc16(false, pKey) % DB_BUCKETS;
- bufstr_set(db, h, infoadd(bufstr_get(db, h), pKey, uri_escape(pValue)));
+ int h = crc16(false, key) % DB_BUCKETS;
+ bufstr_set(db, h, infoadd(bufstr_get(db, h), key, uri_escape(value)));
}
void db_test()
if (dt)
{
e.nextthink = time + dt;
- e.think = SUB_Remove;
+ e.think = SUB_Remove_self;
}
}
this.sourceLocFile = __FILE__; \
this.sourceLocLine = __LINE__; \
} \
- REGISTER(RegisterLinkedEntities, NET, LinkedEntities, id, m_id, new(net_linked_packet)) \
+ REGISTER(LinkedEntities, NET, id, m_id, new(net_linked_packet)) \
{ \
make_pure(this); \
this.netname = #id; \
#else
#define REGISTER_NET_LINKED(id) \
const bool NET_##id##_istemp = false; \
- REGISTER(RegisterLinkedEntities, NET, LinkedEntities, id, m_id, new(net_linked_packet)) \
+ REGISTER(LinkedEntities, NET, id, m_id, new(net_linked_packet)) \
{ \
make_pure(this); \
this.netname = #id; \
REGISTRY(LinkedEntities, BITS(8) - 1)
#define LinkedEntities_from(i) _LinkedEntities_from(i, NULL)
-REGISTER_REGISTRY(RegisterLinkedEntities)
-REGISTRY_SORT(LinkedEntities, 0)
+REGISTER_REGISTRY(LinkedEntities)
+REGISTRY_SORT(LinkedEntities)
REGISTRY_CHECK(LinkedEntities)
STATIC_INIT(RegisterLinkedEntities_renumber)
{
#ifdef CSQC
#define REGISTER_NET_TEMP(id) \
NET_HANDLE(id, bool); \
- REGISTER(RegisterTempEntities, NET, TempEntities, id, m_id, new(net_temp_packet)) \
+ REGISTER(TempEntities, NET, id, m_id, new(net_temp_packet)) \
{ \
make_pure(this); \
this.netname = #id; \
#else
#define REGISTER_NET_TEMP(id) \
const bool NET_##id##_istemp = true; \
- REGISTER(RegisterTempEntities, NET, TempEntities, id, m_id, new(net_temp_packet)) \
+ REGISTER(TempEntities, NET, id, m_id, new(net_temp_packet)) \
{ \
make_pure(this); \
this.netname = #id; \
REGISTRY(TempEntities, BITS(8) - 80)
#define TempEntities_from(i) _TempEntities_from(i, NULL)
-REGISTER_REGISTRY(RegisterTempEntities)
-REGISTRY_SORT(TempEntities, 0)
+REGISTER_REGISTRY(TempEntities)
+REGISTRY_SORT(TempEntities)
REGISTRY_CHECK(TempEntities)
STATIC_INIT(RegisterTempEntities_renumber)
{
return v;
}
+ #define ReadFloat() ReadCoord()
+ vector ReadVector() { vector v; v.x = ReadFloat(); v_y = ReadFloat(); v.z = ReadFloat(); return v; }
+ vector ReadVector2D() { vector v; v.x = ReadFloat(); v.y = ReadFloat(); v.z = 0; return v; }
+
float ReadApproxPastTime()
{
float dt = ReadByte();
WriteInt24_t(dst, val.z);
}
+ #define WriteFloat(to, f) WriteCoord(to, f)
+ #define WriteVector(to, v) do { WriteFloat(to, v.x); WriteFloat(to, v.y); WriteFloat(to, v.z); } while (0)
+ #define WriteVector2D(to, v) do { WriteFloat(to, v.x); WriteFloat(to, v.y); } while (0)
+
// this will use the value:
// 128
// accuracy near zero is APPROXPASTTIME_MAX/(256*255)
#include "oo.qh"
-#define REGISTER_REGISTRY(func) ACCUMULATE_FUNCTION(__static_init, func)
-
-#define REGISTER_INIT(ns, id) [[accumulate]] void Register_##ns##_##id##_init(entity this)
-#define REGISTER_INIT_POST(ns, id) [[accumulate]] void Register_##ns##_##id##_init_post(entity this)
-
+/**
+ * Declare a new registry.
+ *
+ * Don't forget to call `REGISTER_REGISTRY`:
+ * REGISTER_REGISTRY(Foos)
+ */
#define REGISTRY(id, max) \
void Register##id() {} \
const int id##_MAX = max; \
int id##_COUNT; \
entity _##id##_from(int i, entity null) { if (i >= 0 && i < id##_COUNT) { entity e = _##id[i]; if (e) return e; } return null; }
+REGISTRY(Registries, BITS(8))
+
/** registered item identifier */
.string registered_id;
/**
- * Register a new entity with a global constructor.
+ * Register a new entity with a registry.
* Must be followed by a semicolon or a function body with a `this` parameter.
* Wrapper macros may perform actions after user initialization like so:
* #define REGISTER_FOO(id) \
- * REGISTER(RegisterFoos, FOO, FOOS, id, m_id, NEW(Foo)); \
+ * REGISTER(Foos, FOO, id, m_id, NEW(Foo)); \
* REGISTER_INIT_POST(FOO, id) { \
* print("Registering foo #", this.m_id + 1, "\n"); \
* } \
* REGISTER_INIT(FOO, id)
*
- * Don't forget to forward declare `initfunc` and call `REGISTER_REGISTRY`:
- * void RegisterFoos();
- * REGISTER_REGISTRY(RegisterFoos)
*
- * @param initfunc The global constructor to accumulate into
+ * @param registry The registry to add each entity to.
* @param ns Short for namespace, prefix for each global (ns##_##id)
- * @param array The array to add each entity to. Also requires `array##_first` and `array##_last` to be defined
* @param id The identifier of the current entity being registered
- * @param fld The field to store the current count into
+ * @param fld The field to store the locally unique unique entity id
* @param inst An expression to create a new instance, invoked for every registration
*/
-#define REGISTER(initfunc, ns, array, id, fld, inst) \
- entity ns##_##id; \
- REGISTER_INIT(ns, id) {} \
- REGISTER_INIT_POST(ns, id) {} \
- void Register_##ns##_##id() \
+#define REGISTER(...) EVAL(OVERLOAD(REGISTER, __VA_ARGS__))
+#define REGISTER_5(registry, ns, id, fld, inst) REGISTER_4(registry, ns##_##id, fld, inst)
+#define REGISTER_4(registry, id, fld, inst) \
+ entity id; \
+ REGISTER_INIT(id) {} \
+ REGISTER_INIT_POST(id) {} \
+ void Register_##id() \
{ \
- if (array##_COUNT >= array##_MAX) LOG_FATALF("Registry capacity exceeded (%s)", ftos(array##_MAX)); \
- entity this = inst; \
- ns##_##id = this; \
+ if (registry##_COUNT >= registry##_MAX) LOG_FATALF("Registry capacity exceeded (%s)", ftos(registry##_MAX)); \
+ entity this = id = inst; \
this.registered_id = #id; \
- this.fld = array##_COUNT; \
- _##array[array##_COUNT++] = this; \
- if (!array##_first) array##_first = this; \
- if (array##_last) array##_last.REGISTRY_NEXT = this; \
- array##_last = this; \
- Register_##ns##_##id##_init(this); \
- Register_##ns##_##id##_init_post(this); \
+ this.fld = registry##_COUNT; \
+ _##registry[registry##_COUNT] = this; \
+ ++registry##_COUNT; \
+ if (!registry##_first) registry##_first = this; \
+ if (registry##_last) registry##_last.REGISTRY_NEXT = this; \
+ registry##_last = this; \
+ Register_##id##_init(this); \
+ Register_##id##_init_post(this); \
} \
- ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id) \
- REGISTER_INIT(ns, id)
+ ACCUMULATE_FUNCTION(Register##registry, Register_##id) \
+ REGISTER_INIT(id)
+
+#define REGISTER_INIT(id) [[accumulate]] void Register_##id##_init(entity this)
+#define REGISTER_INIT_POST(id) [[accumulate]] void Register_##id##_init_post(entity this)
/** internal next pointer */
#define REGISTRY_NEXT enemy
.entity REGISTRY_NEXT;
-#define REGISTRY_SORT(id, skip) \
+#define REGISTRY_SORT(...) EVAL(OVERLOAD(REGISTRY_SORT, __VA_ARGS__))
+#define REGISTRY_SORT_1(id) REGISTRY_SORT_2(id, 0)
+#define REGISTRY_SORT_2(id, skip) \
void _REGISTRY_SWAP_##id(int i, int j, entity pass) \
{ \
i += skip; j += skip; \
string h = REGISTRY_HASH(id) = strzone(digest_hex(algo, s)); \
LOG_TRACEF(#id ": %s\n[%s]\n", h, s); \
} \
- [[accumulate]] void Registry_check(string r, string sv) \
+ void Registry_check(string r, string sv) \
{ \
if (r == #id) \
{ \
} \
} \
} \
- [[accumulate]] void Registry_send_all() { Registry_send(#id, REGISTRY_HASH(id)); } \
+ void Registry_send_all() { Registry_send(#id, REGISTRY_HASH(id)); } \
+
+#define REGISTER_REGISTRY(...) EVAL(OVERLOAD(REGISTER_REGISTRY, __VA_ARGS__))
+#define REGISTER_REGISTRY_1(id) REGISTER_REGISTRY_2(id, #id)
+#define REGISTER_REGISTRY_2(id, str) \
+ ACCUMULATE_FUNCTION(__static_init, Register##id) \
+ CLASS(id##Registry, Object) \
+ ATTRIB(id##Registry, m_name, string, str) \
+ ATTRIB(id##Registry, REGISTRY_NEXT, entity, id##_first) \
+ ENDCLASS(id##Registry) \
+ REGISTER(Registries, REGISTRY, id, m_id, NEW(id##Registry));
+
#endif
#define _spawnfunc_check(fld) \
if (fieldname == #fld) continue;
- #define spawnfunc_1(id, whitelist) spawnfunc_2(id, whitelist)
+ bool __spawnfunc_unreachable_workaround = true;
+
+ #define spawnfunc_1(id) spawnfunc_2(id, FIELDS_UNION)
#define spawnfunc_2(id, whitelist) \
- void spawnfunc_##id(entity this) \
+ void __spawnfunc_##id(entity this); \
+ [[accumulate]] void spawnfunc_##id(entity this) \
{ \
this = self; \
if (!this.sourceLocFile) \
} \
this.spawnfunc_checked = true; \
} \
+ __spawnfunc_##id(this); \
+ if (__spawnfunc_unreachable_workaround) return; \
} \
- [[accumulate]] void spawnfunc_##id(entity this)
+ void __spawnfunc_##id(entity this)
#define FIELD_SCALAR(fld, n) \
fld(n)
FIELD_VEC(fld, velocity) \
/**/
- #define spawnfunc(...) EVAL(OVERLOAD(spawnfunc, __VA_ARGS__, FIELDS_UNION))
+ #define spawnfunc(...) EVAL(OVERLOAD(spawnfunc, __VA_ARGS__))
#endif
#define _STAT(id) g_stat_##id
#define REGISTER_STAT(id, type) \
type _STAT(id); \
- REGISTER(RegisterStats, STAT, Stats, id, m_id, new(stat)) \
+ REGISTER(Stats, STAT, id, m_id, new(stat)) \
{ \
make_pure(this); \
} \
#define _STAT(id) stat_##id
#define REGISTER_STAT(id, type) \
.type _STAT(id); \
- REGISTER(RegisterStats, STAT, Stats, id, m_id, new(stat)) \
+ REGISTER(Stats, STAT, id, m_id, new(stat)) \
{ \
make_pure(this); \
} \
const int STATS_ENGINE_RESERVE = 32 + (8 * 3); // Not sure how to handle vector stats yet, reserve them too
REGISTRY(Stats, 220 - STATS_ENGINE_RESERVE)
-REGISTER_REGISTRY(RegisterStats)
-REGISTRY_SORT(Stats, 0)
+REGISTER_REGISTRY(Stats)
+REGISTRY_SORT(Stats)
REGISTRY_CHECK(Stats)
STATIC_INIT(RegisterStats_renumber)
{
#ifndef VECTOR_H
#define VECTOR_H
+#define cross(a, b) ((a) >< (b))
+/*
+vector cross(vector a, vector b)
+{
+ return
+ '1 0 0' * (a.y * b.z - a.z * b.y)
+ + '0 1 0' * (a.z * b.x - a.x * b.z)
+ + '0 0 1' * (a.x * b.y - a.y * b.x);
+}
+*/
+
const vector eX = '1 0 0';
const vector eY = '0 1 0';
const vector eZ = '0 0 1';
{
return !(x < y || x == y || x > y);
}
-
-vector cross(vector a, vector b)
-{
- return
- '1 0 0' * (a.y * b.z - a.z * b.y)
- + '0 1 0' * (a.z * b.x - a.x * b.z)
- + '0 0 1' * (a.x * b.y - a.y * b.x);
-}
const float M_SQRT2 = 1.41421356237309504880; /* sqrt(2) */
const float M_SQRT1_2 = 0.70710678118654752440; /* 1/sqrt(2) */
-// Non-<math.h> stuff follows here.
-vector cross(vector a, vector b);
-
#endif
ts.SendEntity = WarpZone_Teleported_Send;
ts.SendFlags = 0xFFFFFF;
ts.drawonlytoclient = player;
- ts.think = SUB_Remove;
+ ts.think = SUB_Remove_self;
ts.nextthink = time + 1;
ts.owner = player;
ts.enemy = wz;
REGISTRY(Settings, BITS(3))
#define Settings_from(i) _Settings_from(i, NULL)
-REGISTER_REGISTRY(RegisterSettings)
+REGISTER_REGISTRY(Settings)
#define REGISTER_SETTINGS(id, impl) \
LAZY_NEW(id, impl) \
- REGISTER(RegisterSettings, MENU, Settings, id, m_id, NEW(Lazy, LAZY(id)))
+ REGISTER(Settings, MENU, id, m_id, NEW(Lazy, LAZY(id)))
#endif
#endif
void XonoticCrosshairPicker_cellDraw(entity me, vector cell, vector cellPos)
{
- vector sz;
- string cross = strcat("/gfx/crosshair", crosshairpicker_cellToCrosshair(me, cell));
- sz = draw_PictureSize(cross);
+ string s = strcat("/gfx/crosshair", crosshairpicker_cellToCrosshair(me, cell));
+ vector sz = draw_PictureSize(s);
sz = globalToBoxSize(sz, me.size);
float ar = sz.x / sz.y;
sz.x = me.realCellSize.x;
sz.y = sz.x / ar;
- sz = sz * 0.95;
+ sz *= 0.95;
vector crosshairPos = cellPos + 0.5 * me.realCellSize;
- draw_Picture(crosshairPos - 0.5 * sz, cross, sz, SKINCOLOR_CROSSHAIRPICKER_CROSSHAIR, SKINALPHA_CROSSHAIRPICKER_CROSSHAIR);
+ draw_Picture(crosshairPos - 0.5 * sz, s, sz, SKINCOLOR_CROSSHAIRPICKER_CROSSHAIR, SKINALPHA_CROSSHAIRPICKER_CROSSHAIR);
if(cvar("crosshair_dot"))
draw_Picture(crosshairPos - 0.5 * sz * cvar("crosshair_dot_size"), "/gfx/crosshairdot", sz * cvar("crosshair_dot_size"), SKINCOLOR_CROSSHAIRPICKER_CROSSHAIR, SKINALPHA_CROSSHAIRPICKER_CROSSHAIR);
me.currentServerNumFreeSlots = strzone(s);
me.numFreeSlotsLabel.setText(me.numFreeSlotsLabel, me.currentServerNumFreeSlots);
- me.currentServerMod = ((modname == "Xonotic") ? _("Default") : modname);
+ me.currentServerMod = ((modname == "Xonotic") ? ZCTX(_("MOD^Default")) : modname);
me.currentServerMod = strzone(me.currentServerMod);
me.modLabel.setText(me.modLabel, me.currentServerMod);
topics.onChangeEntity = this;
int
- col = 0, width = 1.5;
+ col = 0, width = 1;
this.gotoRC(this, 0, col);
this.TD(this, this.rows, width, topics);
METHOD(XonoticServerList, toggleFavorite, void(entity, string));
ATTRIB(XonoticServerList, iconsSizeFactor, float, 0.85)
+ METHOD(XonoticServerList, mouseMove, float(entity, vector));
+ ATTRIB(XonoticServerList, mouseOverIcons, bool, false)
+ METHOD(XonoticServerList, focusedItemChangeNotify, void(entity));
ATTRIB(XonoticServerList, realFontSize, vector, '0 0 0')
ATTRIB(XonoticServerList, realUpperMargin, float, 0)
#ifdef COMPAT_NO_MOD_IS_XONOTIC
if(modname == "")
- modname = "xonotic";
+ modname = "Xonotic";
#endif
+ string original_modname = modname;
modname = strtolower(modname);
/*
if(modname != "cts")
if(modname != "nix")
if(modname != "newtoys")
- pure = false;
+ pure_available = false;
if(gethostcachenumber(SLIST_FIELD_FREESLOTS, i) <= 0)
theAlpha = SKINALPHA_SERVERLIST_FULL;
if(sflags >= 0 && (sflags & SERVERFLAG_PLAYERSTATS))
draw_Picture(iconPos, "icon_stats1", iconSize, '1 1 1', 1);
+ if(isFocused && me.mouseOverIcons && !me.tooltip)
+ {
+ string t = "";
+ if(me.seenIPv4 && me.seenIPv6)
+ t = strcat(t, (isv6) ? "IPv6, " : "IPv4, ");
+ t = strcat(t, _("encryption:"), " ", (q ? sprintf(_("AES level %d"), q) : ZCTX(_("ENC^none"))), ", ");
+ t = strcat(t, sprintf(_("mod: %s"), ((modname == "xonotic") ? ZCTX(_("MOD^Default")) : original_modname)));
+ if(pure_available)
+ t = strcat(t, sprintf(_(" (%s)"), (pure) ? _("official settings") : _("modified settings")));
+ t = strcat(t, ", ");
+ t = strcat(t, ((sflags >= 0 && (sflags & SERVERFLAG_PLAYERSTATS)) ? _("stats enabled") : _("stats disabled")));
+ setZonedTooltip(me, t, string_null);
+ }
// --------------
// RENDER TEXT
// --------------
draw_Text(me.realUpperMargin * eY + (me.columnPlayersOrigin + (me.columnPlayersSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
}
+void XonoticServerList_focusedItemChangeNotify(entity me)
+{
+ clearTooltip(me);
+}
+
+float XonoticServerList_mouseMove(entity me, vector pos)
+{
+ if(!SUPER(XonoticServerList).mouseMove(me, pos))
+ {
+ me.mouseOverIcons = false;
+ clearTooltip(me);
+ return 1;
+ }
+
+ me.mouseOverIcons = (pos_x <= me.columnIconsSize);
+ if(!me.mouseOverIcons)
+ clearTooltip(me);
+ return 1;
+}
+
bool XonoticServerList_keyDown(entity me, int scan, bool ascii, bool shift)
{
vector org, sz;
void saveCvarsMulti(entity me)
{
float n, i;
- string s;
+ string s, cvarname;
me.saveCvars_Multi(me);
s = cvar_string(me.cvarName);
n = tokenize_console(me.cvarNames_Multi);
for(i = 0; i < n; ++i)
{
+ // cvars prefixed with ! get saved with the inverted value
if(substring(argv(i), 0, 1) == "!")
- cvar_set(substring(argv(i), 1, strlen(argv(i))), ((s == "0") ? "1" : "0"));
+ {
+ cvarname = substring(argv(i), 1, strlen(argv(i)));
+ cvar_set(cvarname, ((s == "0") ? "1" : "0"));
+ }
else
- cvar_set(argv(i), s);
+ {
+ cvarname = argv(i);
+ cvar_set(cvarname, s);
+ }
- CheckSendCvars(me, argv(i));
+ CheckSendCvars(me, cvarname);
}
}
void makeMulti(entity e, string otherCvars)
REGISTRY(GlobalSounds, BITS(8) - 1)
#define GlobalSounds_from(i) _GlobalSounds_from(i, NULL)
#define REGISTER_GLOBALSOUND(id, str) \
- REGISTER(RegisterGlobalSounds, GS, GlobalSounds, id, m_id, new(GlobalSound)) \
+ REGISTER(GlobalSounds, GS, id, m_id, new(GlobalSound)) \
{ \
make_pure(this); \
this.m_globalsoundstr = str; \
}
-REGISTER_REGISTRY(RegisterGlobalSounds)
-REGISTRY_SORT(GlobalSounds, 0)
+REGISTER_REGISTRY(GlobalSounds)
+REGISTRY_SORT(GlobalSounds)
REGISTRY_CHECK(GlobalSounds)
PRECACHE(GlobalSounds)
{
// =======================
// Resets the state of all clients, items, weapons, waypoints, ... of the map.
-void reset_map(float dorespawn)
+void reset_map(bool dorespawn)
{
SELFPARAM();
for (entity e = world; (e = nextent(e)); )
{
- setself(e);
- if (IS_NOT_A_CLIENT(self))
+ if (IS_NOT_A_CLIENT(e))
{
- if (self.reset)
+ if (e.reset)
{
- self.reset();
+ WITH(entity, self, e, e.reset(e));
continue;
}
-
- if (self.team_saved) self.team = self.team_saved;
-
- if (self.flags & FL_PROJECTILE) // remove any projectiles left
- remove(self);
+ if (e.team_saved) e.team = e.team_saved;
+ if (e.flags & FL_PROJECTILE) remove(e); // remove any projectiles left
}
}
entity e;
FOR_EACH_PLAYER(e)
- if (e.frozen) WITH(entity, self, e, Unfreeze(self));
+ if (e.frozen) WITH(entity, self, e, Unfreeze(e));
// Moving the player reset code here since the player-reset depends
// on spawnpoint entities which have to be reset first --blub
void ReadyRestart_think()
{
SELFPARAM();
- restart_mapalreadyrestarted = 1;
+ restart_mapalreadyrestarted = true;
reset_map(true);
Score_ClearAll();
- remove(self);
+ remove(this);
}
// Forces a restart of the game without actually reloading the map // this is a mess...
void ReadyRestart_force()
{
- entity tmp_player, restart_timer;
-
bprint("^1Server is restarting...\n");
VoteReset();
// clear overtime, we have to decrease timelimit to its original value again.
- if (checkrules_overtimesadded > 0 && g_race_qualifying != 2) cvar_set("timelimit", ftos(autocvar_timelimit - (checkrules_overtimesadded * autocvar_timelimit_overtime)));
+ if (checkrules_overtimesadded > 0 && g_race_qualifying != 2)
+ cvar_set("timelimit", ftos(autocvar_timelimit - (checkrules_overtimesadded * autocvar_timelimit_overtime)));
checkrules_suddendeathend = checkrules_overtimesadded = checkrules_suddendeathwarning = 0;
- readyrestart_happened = 1;
+ readyrestart_happened = true;
game_starttime = time + RESTART_COUNTDOWN;
+ entity tmp_player;
+
// clear player attributes
FOR_EACH_CLIENT(tmp_player)
{
PS_GR_P_ADDVAL(tmp_player, PLAYERSTATS_ALIVETIME, -PS_GR_P_ADDVAL(tmp_player, PLAYERSTATS_ALIVETIME, 0));
}
- restart_mapalreadyrestarted = 0; // reset this var, needed when cvar sv_ready_restart_repeatable is in use
+ restart_mapalreadyrestarted = false; // reset this var, needed when cvar sv_ready_restart_repeatable is in use
// disable the warmup global for the server
warmup_stage = 0; // once the game is restarted the game is in match stage
// reset the .ready status of all players (also spectators)
FOR_EACH_REALCLIENT(tmp_player)
{
- tmp_player.ready = 0;
+ tmp_player.ready = false;
}
readycount = 0;
Nagger_ReadyCounted(); // NOTE: this causes a resend of that entity, and will also turn off warmup state on the client
// lock teams with lockonrestart
if (autocvar_teamplay_lockonrestart && teamplay)
{
- lockteams = 1;
+ lockteams = true;
bprint("^1The teams are now locked.\n");
}
// initiate the restart-countdown-announcer entity
if (autocvar_sv_ready_restart_after_countdown)
{
- restart_timer = spawn();
+ entity restart_timer = new(restart_timer);
+ make_pure(restart_timer);
restart_timer.think = ReadyRestart_think;
restart_timer.nextthink = game_starttime;
}
{
tmp_player.allowed_timeouts = autocvar_sv_timeout_number;
}
- // reset map immediately if this cvar is not set
- if (!autocvar_sv_ready_restart_after_countdown) reset_map(true); }
- if (autocvar_sv_eventlog) GameLogEcho(":restart"); }
+ }
+ // reset map immediately if this cvar is not set
+ if (!autocvar_sv_ready_restart_after_countdown) reset_map(true);
+ if (autocvar_sv_eventlog) GameLogEcho(":restart");
+}
void ReadyRestart()
{
// Reset ALL scores, but only do that at the beginning of the countdown if sv_ready_restart_after_countdown is off!
// Otherwise scores could be manipulated during the countdown.
- if (!autocvar_sv_ready_restart_after_countdown) Score_ClearAll();
+ if (!autocvar_sv_ready_restart_after_countdown) Score_ClearAll();
ReadyRestart_force();
}
void SUB_DontUseTargets();
void SUB_UseTargets();
-.void() reset; // if set, an entity is reset using this
+.void(entity this) reset; // if set, an entity is reset using this
.void() reset2; // if set, an entity is reset using this (after calling ALL the reset functions for other entities)
void ClientData_Touch(entity e);
#include "weapons/accuracy.qh"
#include "weapons/csqcprojectile.qh"
#include "weapons/selection.qh"
-#include "../common/buffs/all.qh"
#include "../common/constants.qh"
#include "../common/deathtypes/all.qh"
#include "../common/notifications.qh"
return false;
}
+.int buffs; // TODO: remove
+
void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
{
// Sanity check
farcent.origin = hitloc;
farcent.forcetype = FORCETYPE_FORCEATPOS;
farcent.nextthink = time + 0.1;
- farcent.think = SUB_Remove;
+ farcent.think = SUB_Remove_self;
}
else
{
//pl.disableclientprediction = false;
}
-void GrapplingHookReset()
-{SELFPARAM();
- if(self.realowner.hook == self)
- RemoveGrapplingHook(self.owner);
+void GrapplingHookReset(entity this)
+{
+ if(this.realowner.hook == this)
+ RemoveGrapplingHook(this.owner);
else // in any case:
- remove(self);
+ remove(this);
}
void GrapplingHookThink();
void() SUB_CalcMoveDone;
void() SUB_CalcAngleMoveDone;
//void() SUB_UseTargets;
-void() SUB_Remove;
spawnfunc(info_null);
void updateanim(entity e);
-/*
-==================
-SUB_Remove
-Remove self
-==================
-*/
-void SUB_Remove ();
/*
==================
#include "scores.qh"
#include "teamplay.qh"
#include "weapons/weaponstats.qh"
-#include "../common/buffs/all.qh"
#include "../common/constants.qh"
#include "../common/deathtypes/all.qh"
#include "../common/mapinfo.qh"
if(s != "")
{
db_put(ServerProgsDB, strcat("/uid2name/", myuid), s);
- db_put(ServerProgsDB, strcat("uid2name", myuid), "");
+ db_remove(ServerProgsDB, strcat("uid2name", myuid));
}
}
void objerror(string s);
void droptofloor();
-void() SUB_Remove;
void attach_sameorigin(entity e, entity to, string tag);
#include "../../common/stats.qh"
#include "../../common/teams.qh"
#include "../../common/util.qh"
- #include "../../common/nades/all.qh"
- #include "../../common/buffs/all.qh"
#include "../../common/command/markup.qh"
#include "../../common/command/rpn.qh"
#include "../../common/command/generic.qh"
// reset this objective. Used when spawning an objective
// and when a new round starts
-void assault_objective_reset()
-{SELFPARAM();
- self.health = ASSAULT_VALUE_INACTIVE;
+void assault_objective_reset(entity this)
+{
+ this.health = ASSAULT_VALUE_INACTIVE;
}
// decrease the health of targeted objectives
assault_setenemytoobjective();
}
-void target_assault_roundend_reset()
-{SELFPARAM();
+void target_assault_roundend_reset(entity this)
+{
//print("round end reset\n");
- self.cnt = self.cnt + 1; // up round counter
- self.winning = 0; // up round
+ ++this.cnt; // up round counter
+ this.winning = false; // up round
}
void target_assault_roundend_use()
spawnfunc(target_objective)
{
- if (!g_assault) { remove(self); return; }
+ if (!g_assault) { remove(this); return; }
- self.classname = "target_objective";
- self.use = assault_objective_use;
- assault_objective_reset();
- self.reset = assault_objective_reset;
- self.spawn_evalfunc = target_objective_spawn_evalfunc;
+ this.classname = "target_objective";
+ this.use = assault_objective_use;
+ this.reset = assault_objective_reset;
+ this.reset(this);
+ this.spawn_evalfunc = target_objective_spawn_evalfunc;
}
spawnfunc(target_objective_decrease)
bool autocvar_g_ctf_flag_glowtrails;
int autocvar_g_ctf_flag_health;
bool autocvar_g_ctf_flag_return;
+bool autocvar_g_ctf_flag_return_carrying;
float autocvar_g_ctf_flag_return_carried_radius;
float autocvar_g_ctf_flag_return_time;
bool autocvar_g_ctf_flag_return_when_unreachable;
case FLAG_DROPPED:
{
- if(CTF_SAMETEAM(toucher, flag) && (autocvar_g_ctf_flag_return || num_perteam <= 1) && flag.team) // automatically return if there's only 1 player on the team
+ if(CTF_SAMETEAM(toucher, flag) && (autocvar_g_ctf_flag_return || num_perteam <= 1 || (autocvar_g_ctf_flag_return_carrying && toucher.flagcarried)) && flag.team) // automatically return if there's only 1 player on the team
ctf_Handle_Return(flag, toucher); // toucher just returned his own flag
else if(is_not_monster && (!toucher.flagcarried) && ((toucher != flag.ctf_dropper) || (time > flag.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
ctf_Handle_Pickup(flag, toucher, PICKUP_DROPPED); // toucher just picked up a dropped enemy flag
ctf_CheckStalemate();
}
-void ctf_Reset()
-{SELFPARAM();
- if(self.owner)
- if(IS_PLAYER(self.owner))
- ctf_Handle_Throw(self.owner, world, DROP_RESET);
+void ctf_Reset(entity this)
+{
+ if(this.owner && IS_PLAYER(this.owner))
+ ctf_Handle_Throw(this.owner, world, DROP_RESET);
- ctf_RespawnFlag(self);
+ ctf_RespawnFlag(this);
}
void ctf_DelayedFlagSetup() // called after a flag is placed on a map by ctf_FlagSetup()
dompoint_captured();
}
-void dom_controlpoint_setup()
-{SELFPARAM();
+void dom_controlpoint_setup(entity this);
+void dom_controlpoint_setup_self() { SELFPARAM(); dom_controlpoint_setup(this); }
+void dom_controlpoint_setup(entity this)
+{
entity head;
// find the spawnfunc_dom_team representing unclaimed points
head = find(world, classname, "dom_team");
remove(self);
return;
}
- self.think = dom_controlpoint_setup;
+ self.think = dom_controlpoint_setup_self;
self.nextthink = time + 0.1;
self.reset = dom_controlpoint_setup;
setself(this);
}
-void _spawnfunc_dom_controlpoint() { SELFPARAM(); spawnfunc_dom_controlpoint(self); }
+void self_spawnfunc_dom_controlpoint() { SELFPARAM(); spawnfunc_dom_controlpoint(self); }
void dom_spawnpoint(vector org)
{SELFPARAM();
setself(spawn());
self.classname = "dom_controlpoint";
- self.think = _spawnfunc_dom_controlpoint;
+ self.think = self_spawnfunc_dom_controlpoint;
self.nextthink = time;
setorigin(self, org);
spawnfunc_dom_controlpoint(this);
monster = spawnmonster("", mon, world, world, e.origin, false, false, 2);
else return;
- e.think = SUB_Remove;
+ e.think = SUB_Remove_self;
e.nextthink = time + 0.1;
}
else
WaypointSprite_Kill(plyr.waypointsprite_attachedforcarrier);
}
-void ka_Reset() // used to clear the ballcarrier whenever the match switches from warmup to normal
-{SELFPARAM();
- if((self.owner) && (IS_PLAYER(self.owner)))
- ka_DropEvent(self.owner);
+/** used to clear the ballcarrier whenever the match switches from warmup to normal */
+void ka_Reset(entity this)
+{
+ if((this.owner) && (IS_PLAYER(this.owner)))
+ ka_DropEvent(this.owner);
if(time < game_starttime)
{
- self.think = ka_RespawnBall;
- self.touch = func_null;
- self.nextthink = game_starttime;
+ this.think = ka_RespawnBall;
+ this.touch = func_null;
+ this.nextthink = game_starttime;
}
else
ka_RespawnBall();
self.nextthink = time + 0.05;
}
-void key_reset()
-{SELFPARAM();
- kh_Key_AssignTo(self, world);
- kh_Key_Remove(self);
+void key_reset(entity this)
+{
+ kh_Key_AssignTo(this, world);
+ kh_Key_Remove(this);
}
const string STR_ITEM_KH_KEY = "item_kh_key";
}
}
-void SUB_Remove();
-
void pathlib_showsquare(vector where,float goodsquare,float _lifetime)
{
entity s;
s = spawn();
s.alpha = 0.25;
- s.think = SUB_Remove;
+ s.think = SUB_Remove_self;
s.nextthink = _lifetime;
s.scale = pathlib_gridsize / 512.001;
s.solid = SOLID_NOT;
e = spawn();
e.alpha = 0.25;
- e.think = SUB_Remove;
+ e.think = SUB_Remove_self;
e.nextthink = _lifetime;
e.scale = pathlib_gridsize / 512;
e.solid = SOLID_NOT;
e = findchainentity(owner, start);
while(e)
{
- e.think = SUB_Remove;
+ e.think = SUB_Remove_self;
e.nextthink = time;
e = e.chain;
}
void dumpnode(entity n)
{
n.is_path_node = false;
- n.think = SUB_Remove;
+ n.think = SUB_Remove_self;
n.nextthink = time;
}
node = spawn();
- node.think = SUB_Remove;
+ node.think = SUB_Remove_self;
node.nextthink = time + PATHLIB_NODEEXPIRE;
node.is_path_node = true;
node.owner = openlist;
#include "../common/viewloc.qc"
#include "../common/deathtypes/all.qc"
-#include "../common/buffs/all.qc"
#include "../common/effects/all.qc"
#include "../common/gamemodes/all.qc"
#include "../common/items/all.qc"
#include "../common/monsters/all.qc"
-#include "../common/nades/all.qc"
#include "../common/turrets/all.qc"
#include "../common/vehicles/all.qc"
#include "../common/weapons/all.qc"
{
if (i == RANKINGS_CNT)
{
- db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), string_null);
- db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), string_null);
+ db_remove(ServerProgsDB, strcat(map, rr, "time", ftos(i)));
+ db_remove(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)));
}
else
{
if(this.angles != '0 0 0')
this.SendFlags |= ISF_ANGLES;
- this.reset = Item_Reset_self;
+ this.reset = Item_Reset;
// it's a level item
if(this.spawnflags & 1)
this.noalign = 1;
#include "../common/weapons/all.qh"
-#include "../common/buffs/all.qh"
spawnfunc(weapon_crylink);
spawnfunc(weapon_electro);
else if (targ.classname == "item_health_mega")
self.health = 200;
//remove(targ); // removing ents in init functions causes havoc, workaround:
- targ.think = SUB_Remove;
+ targ.think = SUB_Remove_self;
targ.nextthink = time;
}
self.spawnflags = 2;
spawnfunc(item_flight)
{
- if(!cvar("g_buffs") || !cvar("g_buffs_flight"))
- spawnfunc_item_jetpack(this);
- else
- buff_Init_Compat(self, BUFF_FLIGHT);
+ spawnfunc_item_jetpack(this);
}
.float notteam;
// since this is an engine function, and gamecode doesn't have any calls earlier than this, do the connecting message here
if(!IS_CLIENT(self))
- Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_CONNECTING, self.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_CONNECTING, self.netname);
SetPlayerTeam(self, dteam, steam, !IS_CLIENT(self));