- wget -O data/maps/g-23.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.cache
- wget -O data/maps/g-23.waypoints.hardwired https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.hardwired
- make
- - EXPECT=74f3802009cec230bdaa3b87235368ca
+ - EXPECT=b46b7dcf27e864c2842b7436e32e24fe
- HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
| tee /dev/stderr
| grep '^:'
set g_jump_grunt 0 "Do you make a grunting noise every time you jump? Is it the same grunting noise every time?"
-seta cl_weaponpriority "vaporizer vortex fireball mortar machinegun hagar rifle arc electro devastator crylink minelayer shotgun shockwave hlac tuba blaster porto seeker hook" "weapon priority list"
+seta cl_weaponpriority "vaporizer hmg rpc vortex fireball mortar machinegun hagar rifle arc electro devastator crylink minelayer shotgun shockwave hlac tuba blaster porto seeker hook" "weapon priority list"
seta cl_weaponpriority_useforcycling 0 "when set, weapon cycling by the mouse wheel makes use of the weapon priority list (the special value 2 uses the weapon ID list for cycling)"
-seta cl_weaponpriority0 "devastator mortar hagar seeker fireball" "use weapon_priority_0_prev for prev gun from this list, weapon_priority_0_best for best gun, weapon_priority_0_next for next gun. Default value: explosives"
+seta cl_weaponpriority0 "rpc devastator mortar hagar seeker fireball" "use weapon_priority_0_prev for prev gun from this list, weapon_priority_0_best for best gun, weapon_priority_0_next for next gun. Default value: explosives"
seta cl_weaponpriority1 "vaporizer vortex crylink hlac arc electro blaster shockwave" "use weapon_priority_1_prev for prev gun from this list, weapon_priority_1_best for best gun, weapon_priority_1_next for next gun. Default value: energy"
seta cl_weaponpriority2 "vaporizer vortex rifle" "use weapon_priority_2_prev for prev gun from this list, weapon_priority_2_best for best gun, weapon_priority_2_next for next gun. Default value: hitscan exact"
-seta cl_weaponpriority3 "vaporizer vortex rifle machinegun shotgun shockwave" "use weapon_priority_3_prev for prev gun from this list, weapon_priority_3_best for best gun, weapon_priority_3_next for next gun. Default value: hitscan all"
-seta cl_weaponpriority4 "mortar minelayer hlac hagar crylink seeker shotgun shockwave" "use weapon_priority_4_prev for prev gun from this list, weapon_priority_4_best for best gun, weapon_priority_4_next for next gun. Default value: spam weapons"
+seta cl_weaponpriority3 "vaporizer hmg vortex rifle machinegun shotgun shockwave" "use weapon_priority_3_prev for prev gun from this list, weapon_priority_3_best for best gun, weapon_priority_3_next for next gun. Default value: hitscan all"
+seta cl_weaponpriority4 "mortar minelayer hlac hagar crylink seeker shotgun shockwave" "use weapon_priority_4_prev for prev gun from this list, weapon_priority_4_best for best gun, weapon_priority_4_next for next gun. Default value: spam weapons"
seta cl_weaponpriority5 "blaster shockwave hook porto" "use weapon_priority_5_prev for prev gun from this list, weapon_priority_5_best for best gun, weapon_priority_5_next for next gun. Default value: weapons for moving"
seta cl_weaponpriority6 "" "use weapon_priority_6_prev for prev gun from this list, weapon_priority_6_best for best gun, weapon_priority_6_next for next gun"
seta cl_weaponpriority7 "" "use weapon_priority_7_prev for prev gun from this list, weapon_priority_7_best for best gun, weapon_priority_7_next for next gun"
// ==========
// keepaway
// ==========
-set g_keepaway 0 "game mode which focuses around a ball, look at g_keepaway_win_mode for further details"
+set g_keepaway 0 "game mode which focuses around a ball"
set g_keepaway_score_bckill 1 "enable scoring points (y/n) for ball carrier kills (value is how many points to award)"
set g_keepaway_score_killac 1 "amount of points to give when you kill someone while you have the ball"
set g_keepaway_score_timeinterval 1 "amount of time it takes between intervals for timepoints to be added to the score"
bone_aim3 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
+hidden 1
pyria_obj.001,pyriahair
-pyria_obj,pyriafullbright
+pyria_obj,pyria
pyria_obj.001,pyriahair
-pyria_obj,pyriafullbright
+pyria_obj,pyria
pyria_obj.001,pyriahair
-pyria_obj,pyriafullbright
+pyria_obj,pyria
-ignis42,ignisfullbright
+ignis42,ignis
ignis42.002,ignishead
-ignis42,ignisfullbright
+ignis42,ignis
ignis42.002,ignishead
-ignis42,ignisfullbright
+ignis42,ignis
ignis42.002,ignishead
set g_monsters_miniboss_chance 5
set g_monsters_miniboss_healthboost 100
set g_monsters_drop_time 10
+set g_monsters_ignoretraces 1
+set g_monsters_lineofsight 1
set g_monsters_owners 1
set g_monsters_teams 1
set g_monsters_score_kill 0
return;
if (!autocvar_hud_cursormode)
- {
- mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
-
- mousepos.x = bound(0, mousepos.x, vid_conwidth);
- mousepos.y = bound(0, mousepos.y, vid_conheight);
- }
+ update_mousepos();
if(mouseClicked)
{
return;
}
- if(!autocvar_hud_cursormode)
- {
- mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
-
- mousepos.x = bound(0, mousepos.x, vid_conwidth);
- mousepos.y = bound(0, mousepos.y, vid_conheight);
- }
+ if (!autocvar_hud_cursormode)
+ update_mousepos();
+ panel = HUD_PANEL(QUICKMENU);
HUD_Panel_LoadCvars();
if(panel_bg_padding)
return;
}
- if(!autocvar_hud_cursormode)
- {
- mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
-
- mousepos_x = bound(0, mousepos_x, vid_conwidth);
- mousepos_y = bound(0, mousepos_y, vid_conheight);
- }
+ if (!autocvar_hud_cursormode)
+ update_mousepos();
+ panel = HUD_PANEL(RADAR);
HUD_Panel_LoadCvars();
// Scoreboard (#24)
+string autocvar_hud_fontsize;
+string hud_fontsize_str;
+
float sbt_bg_alpha;
float sbt_fg_alpha;
float sbt_fg_alpha_self;
}
}
- case SP_DMG:
- num = pl.(scores(SP_DMG));
- denom = 1000;
-
- str = sprintf("%.1f k", num/denom);
- return str;
-
- case SP_DMGTAKEN:
- num = pl.(scores(SP_DMGTAKEN));
- denom = 1000;
-
- str = sprintf("%.1f k", num/denom);
- return str;
+ case SP_DMG: case SP_DMGTAKEN:
+ return sprintf("%.1f k", pl.(scores(field)) / 1000);
default:
tmp = pl.(scores(field));
TC(int, i);
float f;
vector sz;
- PlayerScoreField field = sbt_field[i];
sbt_fixcolumnwidth_iconlen = 0;
else
sbt_fixcolumnwidth_marginlen = 0;
- if(field == SP_NAME) // name gets all remaining space
+ if(sbt_field[i] == SP_NAME) // name gets all remaining space
{
int j;
float namesize;
return str;
}
+void Scoreboard_initFieldSizes()
+{
+ for(int i = 0; i < sbt_num_fields; ++i)
+ sbt_field_size[i] = stringwidth(sbt_field_title[i], false, hud_fontsize);
+}
+
vector Scoreboard_DrawHeader(vector pos, vector rgb)
{
int i;
WepSet weapons_stat = WepSet_GetFromStat();
WepSet weapons_inmap = WepSet_GetFromStat_InMap();
int disownedcnt = 0;
+ int nHidden = 0;
FOREACH(Weapons, it != WEP_Null, {
int weapon_stats = weapon_accuracy[i - WEP_FIRST];
WepSet set = it.m_wepset;
- if (weapon_stats < 0 && !(weapons_stat & set || weapons_inmap & set))
- ++disownedcnt;
+ if (weapon_stats < 0)
+ {
+ if (!(weapons_stat & set) && (it.spawnflags & WEP_FLAG_HIDDEN || it.spawnflags & WEP_FLAG_MUTATORBLOCKED))
+ nHidden += 1;
+ else if (!(weapons_stat & set || weapons_inmap & set))
+ ++disownedcnt;
+ }
});
- int weapon_cnt = (Weapons_COUNT - 1) - disownedcnt;
+ int weapon_cnt = (Weapons_COUNT - 1) - disownedcnt - nHidden;
if (weapon_cnt <= 0) return pos;
int rows = 1;
- if (autocvar_hud_panel_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - 1) * 0.5))
+ if (autocvar_hud_panel_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - nHidden - 1) * 0.5))
rows = 2;
int columnns = ceil(weapon_cnt / rows);
- float height = 40;
+ float weapon_height = 29;
+ float height = hud_fontsize.y + weapon_height;
drawstring(pos + eX * panel_bg_padding, sprintf(_("Accuracy stats (average %d%%)"), average_accuracy), hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
pos.y += 1.25 * hud_fontsize.y;
pos = panel_pos;
vector tmp = panel_size;
- float fontsize = height * 1/3;
- float weapon_height = height * 2/3;
float weapon_width = tmp.x / columnns / rows;
if (sbt_bg_alpha)
// row highlighting
for (int i = 0; i < rows; ++i)
- drawfill(pos + eY * weapon_height + eY * height * i, eX * tmp.x + eY * fontsize, rgb, sbt_highlight_alpha, DRAWFLAG_NORMAL);
+ drawfill(pos + eY * weapon_height + eY * height * i, eX * tmp.x + eY * hud_fontsize.y, rgb, sbt_highlight_alpha, DRAWFLAG_NORMAL);
}
average_accuracy = 0;
s = sprintf("%d%%", weapon_stats * 100);
float padding;
- padding = (weapon_width - stringwidth(s, false, eX * fontsize)) / 2; // center the accuracy value
+ padding = (weapon_width - stringwidth(s, false, hud_fontsize)) / 2; // center the accuracy value
if(!autocvar_hud_panel_scoreboard_accuracy_nocolors)
rgb = Accuracy_GetColor(weapon_stats);
- drawstring(tmpos + eX * padding + eY * weapon_height, s, '1 1 0' * fontsize, rgb, sbt_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(tmpos + eX * padding + eY * weapon_height, s, hud_fontsize, rgb, sbt_fg_alpha, DRAWFLAG_NORMAL);
}
tmpos.x += weapon_width * rows;
pos.x += weapon_width * rows;
scoreboard_fade_alpha = min(1, scoreboard_fade_alpha + frametime * scoreboard_fadeinspeed);
else
scoreboard_fade_alpha = 1;
+ if(hud_fontsize_str != autocvar_hud_fontsize)
+ {
+ hud_fontsize = HUD_GetFontsize("hud_fontsize");
+ Scoreboard_initFieldSizes();
+ if(hud_fontsize_str)
+ strunzone(hud_fontsize_str);
+ hud_fontsize_str = strzone(autocvar_hud_fontsize);
+ }
}
else {
float scoreboard_fadeoutspeed = autocvar_hud_panel_scoreboard_fadeoutspeed;
int nHidden = 0; \
FOREACH(Weapons, it != WEP_Null, { \
if (weapons_stat & WepSet_FromWeapon(it)) continue; \
- if (it.spawnflags & WEP_FLAG_MUTATORBLOCKED) nHidden += 1; \
+ if (it.spawnflags & WEP_FLAG_HIDDEN || it.spawnflags & WEP_FLAG_MUTATORBLOCKED) nHidden += 1; \
}); \
vector table_size = HUD_GetTableSize_BestItemAR((Weapons_COUNT - 1) - nHidden, panel_size, aspect); \
columns = table_size.x; \
{
make_pure(this);
gametype = ReadRegistered(Gametypes);
+ teamplay = _MapInfo_GetTeamPlayBool(gametype);
HUD_ModIcons_SetFunc();
FOREACH(Scores, true, {
if (scores_label(it)) strunzone(scores_label(it));
float mv_top2_time;
float mv_top2_alpha;
-vector mv_mousepos;
int mv_selection;
int mv_columns;
int mv_mouse_selection;
for (r = 0; r < rows; ++r)
for (c = 0; c < columns; ++c)
{
- if (mv_mousepos.x >= topleft.x + cellsize.x * c &&
- mv_mousepos.x <= topleft.x + cellsize.x * (c + 1) &&
- mv_mousepos.y >= topleft.y + cellsize.y * r &&
- mv_mousepos.y <= topleft.y + cellsize.y * (r + 1))
+ if (mousepos.x >= topleft.x + cellsize.x * c &&
+ mousepos.x <= topleft.x + cellsize.x * (c + 1) &&
+ mousepos.y >= topleft.y + cellsize.y * r &&
+ mousepos.y <= topleft.y + cellsize.y * (r + 1))
{
mv_mouse_selection = r * columns + c;
break;
if (!autocvar_hud_cursormode)
{
- vector mpos = mv_mousepos + getmousepos();
- mpos.x = bound(0, mpos.x, vid_conwidth);
- mpos.y = bound(0, mpos.y, vid_conheight);
-
- if ( mpos.x != mv_mousepos.x || mpos.y != mv_mousepos.y )
+ vector mpos = mousepos;
+ update_mousepos();
+ if (mpos.x != mousepos.x || mpos.y != mousepos.y)
mv_selection_keyboard = 0;
- mv_mousepos = mpos;
}
center = (vid_conwidth - 1)/2;
MapVote_DrawAbstain(pos, dist.x, xmax - xmin, tmp, i);
}
- draw_cursor_normal(mv_mousepos, '1 1 1', panel_fg_alpha);
+ draw_cursor_normal(mousepos, '1 1 1', panel_fg_alpha);
}
void Cmd_MapVote_MapDownload(int argc)
void MapVote_Init()
{
mv_active = 1;
- if(autocvar_hud_cursormode) { setcursormode(1); }
- else { mv_mousepos = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight; }
+ if(autocvar_hud_cursormode) setcursormode(1);
+ else mousepos = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;
mv_selection = -1;
mv_selection_keyboard = 0;
if(bInputType == 3)
{
- mv_mousepos.x = nPrimary;
- mv_mousepos.y = nSecondary;
+ mousepos.x = nPrimary;
+ mousepos.y = nSecondary;
mv_selection_keyboard = 0;
return true;
}
drawcolorcodedstring_expanding(pos, text, '1 1 0' * sz.y, theAlpha, drawflag, fadelerp);
}
+void update_mousepos()
+{
+ mousepos += getmousepos() * autocvar_menu_mouse_speed;
+ mousepos.x = bound(0, mousepos.x, vid_conwidth);
+ mousepos.y = bound(0, mousepos.y, vid_conheight);
+}
+
// this draws the triangles of a model DIRECTLY. Don't expect high performance, really...
float PolyDrawModelSurface(entity e, float i_s)
{
void drawcolorcodedstring_aspect_expanding(vector pos, string text, vector sz, float theAlpha, float drawflag, float fadelerp);
+void update_mousepos();
+
// this draws the triangles of a model DIRECTLY. Don't expect high performance, really...
float PolyDrawModelSurface(entity e, float i_s);
void PolyDrawModel(entity e);
v = wcross_origin - wcross_oldorigin;
v.x /= vid_conwidth;
v.y /= vid_conheight;
- if(vlen(v) > 0.01)
+ if(vdist(v, >, 0.01))
shottype = SHOTTYPE_HITOBSTRUCTION;
}
if(!autocvar_crosshair_hittest_showimpact)
}
}
- if(ons_roundlost)
+ if(ons_roundlost) // TODO: move this junk to a client mutator for onslaught (possible using the WantEventchase hook)
{
- FOREACH_ENTITY_CLASS("onslaught_generator", it.health <= 0, {
+ IL_EACH(g_onsgenerators, it.health <= 0,
+ {
gen = it;
break;
});
switchweapon = Weapons_from(STAT(SWITCHWEAPON));
- f = (serverflags & SERVERFLAG_TEAMPLAY);
- if(f != teamplay)
- {
- teamplay = f;
- Scoreboard_InitScores();
- }
-
if(last_switchweapon != switchweapon)
{
weapontime = time;
#include "items/_mod.inc"
#include "weapons/_all.inc"
- #include "monsters/all.qc"
+ #include "monsters/_mod.inc"
#include "turrets/all.qc"
#include "vehicles/all.qc"
#include "animdecide.qh"
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
#if defined(SVQC)
#include "util.qh"
REGISTER_SP(END);
REGISTER_SP(PING);
+REGISTER_SP(PL);
REGISTER_SP(NAME);
REGISTER_SP(KDRATIO);
-REGISTER_SP(CLRATIO);
-REGISTER_SP(PL);
REGISTER_SP(SUM);
REGISTER_SP(SEPARATOR);
entityclass(Rubble);
class(Rubble).float creationtime;
-void RubbleLimit(string cname, float limit, void(entity) deleteproc)
+IntrusiveList g_rubble;
+STATIC_INIT(g_rubble) { g_rubble = IL_NEW(); }
+
+void RubbleLimit(string cname, int limit, void(entity) deleteproc)
{
// remove rubble of the same type if it's at the limit
// remove multiple rubble if the limit has been decreased
entity oldest = NULL;
float oldesttime = 0;
// compare to all other matching entities
- FOREACH_ENTITY_CLASS(cname, true,
+ IL_EACH(g_rubble, it.classname == cname,
{
++c;
if(!oldest || oldesttime > it.creationtime)
entity e = spawn();
e.classname = cname;
e.creationtime = time;
+ IL_PUSH(g_rubble, e);
return e;
}
#include "ent_cs.qh"
-// #define PROP(public, fld, sv, cl)
-#define ENTCS_NETPROPS(PROP) \
- PROP(true, sv_entnum, \
- { WriteByte(chan, etof(player) - 1); }, \
- { this.sv_entnum = ReadByte(); }) \
- \
- PROP(false, origin, \
+#define ENTCS_SET_NORMAL(var, x) MACRO_BEGIN \
+ var = x; \
+MACRO_END
+
+/** the engine player name strings are mutable! */
+#define ENTCS_SET_MUTABLE_STRING(var, x) MACRO_BEGIN \
+ if (var) strunzone(var); \
+ var = strzone(x); \
+MACRO_END
+
+// #define PROP(public, fld, set, sv, cl)
+#define ENTCS_NETPROPS(PROP) PROP(false, sv_entnum, ENTCS_SET_NORMAL, {}, {}) /* sentinel */ \
+ PROP(false, origin, ENTCS_SET_NORMAL, \
{ WriteShort(chan, this.origin.x); WriteShort(chan, this.origin.y); \
WriteShort(chan, this.origin.z); }, \
{ this.has_sv_origin = true; vector v; v.x = ReadShort(); v.y = ReadShort(); v.z = ReadShort(); setorigin(this, v); }) \
\
- PROP(false, angles_y, \
+ PROP(false, angles_y, ENTCS_SET_NORMAL, \
{ WriteByte(chan, this.angles.y / 360 * 256); }, \
{ vector v = '0 0 0'; v.y = ReadByte() / 256 * 360; this.angles = v; }) \
\
- PROP(false, health, \
+ PROP(false, health, ENTCS_SET_NORMAL, \
{ WriteByte(chan, bound(0, this.health / 10, 255)); /* FIXME: use a better scale? */ }, \
{ this.healthvalue = ReadByte() * 10; }) \
\
- PROP(false, armorvalue, \
+ PROP(false, armorvalue, ENTCS_SET_NORMAL, \
{ WriteByte(chan, bound(0, this.armorvalue / 10, 255)); /* FIXME: use a better scale? */ }, \
{ this.armorvalue = ReadByte() * 10; }) \
\
- PROP(true, netname, \
+ PROP(true, netname, ENTCS_SET_MUTABLE_STRING, \
{ WriteString(chan, this.netname); }, \
{ if (this.netname) strunzone(this.netname); this.netname = strzone(ReadString()); }) \
\
- PROP(true, model, \
+ PROP(true, model, ENTCS_SET_NORMAL, \
{ WriteString(chan, this.model); }, \
{ if (this.model) strunzone(this.model); this.model = strzone(ReadString()); }) \
\
- PROP(true, skin, \
+ PROP(true, skin, ENTCS_SET_NORMAL, \
{ WriteByte(chan, this.skin); }, \
{ this.skin = ReadByte(); }) \
\
- PROP(true, clientcolors, \
+ PROP(true, clientcolors, ENTCS_SET_NORMAL, \
{ WriteByte(chan, this.clientcolors); }, \
{ this.colormap = ReadByte(); }) \
\
- PROP(true, frags, \
+ PROP(true, frags, ENTCS_SET_NORMAL, \
{ WriteShort(chan, this.frags); }, \
{ this.frags = ReadShort(); }) \
\
int ENTCS_PUBLICMASK = 0;
STATIC_INIT(ENTCS_PUBLICMASK)
{
- int i = 1;
- #define X(public, fld, sv, cl) { if (public) ENTCS_PUBLICMASK |= BIT(i); } i += 1;
+ int i = 0;
+ #define X(public, fld, set, sv, cl) { \
+ if (public) { \
+ ENTCS_PUBLICMASK |= BIT(i); \
+ } \
+ i += 1; \
+ }
ENTCS_NETPROPS(X);
#undef X
if (i >= BITS(16 - 1)) LOG_FATAL("Exceeded ENTCS_NETPROPS limit");
bool _entcs_send(entity this, entity to, int sf, int chan)
{
entity player = this.owner;
- sf |= BIT(0) | BIT(1);
- if (IS_PLAYER(to) || to.caplayer) // unless spectating,
- {
- bool same_team = (to == player) || (teamplay && player.team == to.team);
- if (!same_team && !radar_showennemies) sf &= ENTCS_PUBLICMASK; // no private updates
- }
+ sf |= BIT(0); // assume private
+ do {
+ if (radar_showennemies) break;
+ if (SAME_TEAM(to, player)) break;
+ if (!(IS_PLAYER(to) || to.caplayer) && time > game_starttime) break;
+ sf &= ENTCS_PUBLICMASK; // no private updates
+ } while (0);
sf |= this.m_forceupdate;
this.m_forceupdate = 0;
- bool valid =
- time > game_starttime
- && (IS_PLAYER(player) // player must be active
- || player == to) // player is self
- ;
- if (!valid) sf = 0;
if (chan == MSG_ENTITY)
WriteHeader(chan, ENT_CLIENT_ENTCS);
else
WriteHeader(chan, CLIENT_ENTCS);
WriteByte(chan, etof(player) - 1);
WriteShort(chan, sf);
- int i = 1;
- #define X(public, fld, sv, cl) { if (sf & BIT(i)) sv; } i += 1;
+ int i = 0;
+ #define X(public, fld, set, sv, cl) { \
+ if (sf & BIT(i)) { \
+ sv; \
+ } \
+ i += 1; \
+ }
ENTCS_NETPROPS(X);
#undef X
return true;
{
this.nextthink = time + 0.033333333333; // TODO: increase this to like 0.15 once the client can do smoothing
entity o = this.owner;
- int i = 1;
- #define X(public, fld, sv, cl) \
- if (o.fld != this.fld) \
- { \
- this.fld = o.fld; \
+ int i = 0;
+ #define X(public, fld, set, sv, cl) { \
+ if (o.fld != this.fld) { \
+ set(this.fld, o.fld); \
this.SendFlags |= BIT(i); \
} \
- i += 1;
+ i += 1; \
+ }
ENTCS_NETPROPS(X);
#undef X
setorigin(this, this.origin); // relink
{
int n = ReadByte();
entity e = entcs_receiver(n);
+ #define X(e) { \
+ setthink(e, entcs_think); \
+ entcs_receiver(n, e); \
+ }
if (e == NULL)
{
- if (this)
+ if (!this)
{
- e = this;
+ // initial = temp
+ e = new_pure(entcs_receiver);
+ X(e);
}
else
{
- e = new(entcs_receiver);
- make_pure(e);
+ // initial = linked
+ e = this;
+ X(e);
}
- e.sv_entnum = n;
- setthink(e, entcs_think);
- entcs_receiver(n, e);
}
- else if (this && e != this)
+ else if (e != this && this)
{
- this.classname = "entcs_gc";
- this.sv_entnum = n;
+ // upgrade to linked
+ delete(e);
+ e = this;
+ X(e);
}
- this = e;
- InterpolateOrigin_Undo(this);
- this.sv_entnum = n;
+ #undef X
+ InterpolateOrigin_Undo(e);
+ e.sv_entnum = n;
int sf = ReadShort();
- this.has_sv_origin = false;
- this.m_entcs_private = boolean(sf & BIT(0));
- int i = 1;
- #define X(public, fld, sv, cl) { if (sf & BIT(i)) cl; } i += 1;
+ e.has_sv_origin = false;
+ e.m_entcs_private = boolean(sf & BIT(0));
+ int i = 0;
+ #define X(public, fld, set, sv, cl) { \
+ if (sf & BIT(i)) { \
+ cl; \
+ } \
+ i += 1; \
+ }
ENTCS_NETPROPS(X);
#undef X
- this.iflags |= IFLAG_ORIGIN;
- InterpolateOrigin_Note(this);
- getthink(this)(this);
+ e.iflags |= IFLAG_ORIGIN;
+ InterpolateOrigin_Note(e);
+ getthink(e)(e);
return true;
}
missile.effects = EF_BRIGHTFIELD | EF_LOWPRECISION;
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
CSQCProjectile(missile, true, PROJECTILE_ELECTRO, true);
}
setsize(this, CPICON_MIN, CPICON_MAX);
}
-void cpicon_construct(entity this)
+void cpicon_construct(entity this, bool isnew)
{
this.netname = "Control Point Icon";
this.cp_origin = this.origin;
this.cp_bob_origin = '0 0 0.1';
this.cp_bob_spd = 0;
+
+ if(isnew)
+ IL_PUSH(g_drawables, this);
}
.vector glowmod;
this.count = (this.health - this.max_health) * frametime;
cpicon_changeteam(this);
- cpicon_construct(this);
+ cpicon_construct(this, isnew);
}
if(sf & CPSF_STATUS)
setsize(this, GENERATOR_MIN, GENERATOR_MAX);
}
-void generator_construct(entity this)
+void generator_construct(entity this, bool isnew)
{
this.netname = "Generator";
this.classname = "onslaught_generator";
+ if(isnew)
+ IL_PUSH(g_onsgenerators, this);
+
setorigin(this, this.origin);
setmodel(this, MDL_ONS_GEN);
setsize(this, GENERATOR_MIN, GENERATOR_MAX);
this.count = 40;
generator_changeteam(this);
- generator_construct(this);
+ generator_construct(this, isnew);
}
if(sf & GSF_STATUS)
REGISTER_NET_LINKED(ENT_CLIENT_GENERATOR)
REGISTER_NET_LINKED(ENT_CLIENT_CONTROLPOINT_ICON)
+
+#ifdef SVQC
+IntrusiveList g_onsshields;
+STATIC_INIT(g_onsshields) { g_onsshields = IL_NEW(); }
+#endif
+
+#ifdef CSQC
+IntrusiveList g_onsgenerators;
+STATIC_INIT(g_onsgenerators) { g_onsgenerators = IL_NEW(); }
+#endif
void ons_CaptureShield_Spawn(entity generator, bool is_generator)
{
entity shield = new(ons_captureshield);
+ IL_PUSH(g_onsshields, shield);
shield.enemy = generator;
shield.team = generator.team;
{
LOG_DEBUG(etos(l), " (generator) is shielded");
l.takedamage = DAMAGE_NO;
+ if(l.bot_attack)
+ IL_REMOVE(g_bot_targets, l);
l.bot_attack = false;
}
else
{
LOG_DEBUG(etos(l), " (generator) is not shielded");
l.takedamage = DAMAGE_AIM;
+ if(!l.bot_attack)
+ IL_PUSH(g_bot_targets, l);
l.bot_attack = true;
}
if (l.goalentity)
{
l.goalentity.takedamage = DAMAGE_NO;
+ if(l.goalentity.bot_attack)
+ IL_REMOVE(g_bot_targets, l.goalentity);
l.goalentity.bot_attack = false;
}
}
if (l.goalentity)
{
l.goalentity.takedamage = DAMAGE_AIM;
+ if(!l.goalentity.bot_attack)
+ IL_PUSH(g_bot_targets, l.goalentity);
l.goalentity.bot_attack = true;
}
}
ons_ControlPoint_UpdateSprite(l);
}
- FOREACH_ENTITY_CLASS("ons_captureshield", true,
+ IL_EACH(g_onsshields, true,
{
it.team = it.enemy.team;
it.colormap = it.enemy.colormap;
e.solid = SOLID_NOT;
e.takedamage = DAMAGE_AIM;
e.bot_attack = true;
+ IL_PUSH(g_bot_targets, e);
e.event_damage = ons_ControlPoint_Icon_Damage;
e.team = player.team;
e.colormap = 1024 + (e.team - 1) * 17;
this.lasthealth = this.max_health = this.health = autocvar_g_onslaught_gen_health;
this.takedamage = DAMAGE_AIM;
this.bot_attack = true;
+ IL_PUSH(g_bot_targets, this);
this.iscaptured = true;
this.islinked = true;
this.isshielded = true;
gen.lasthealth = gen.max_health = gen.health = autocvar_g_onslaught_gen_health;
gen.takedamage = DAMAGE_AIM;
gen.bot_attack = true;
+ IL_PUSH(g_bot_targets, gen);
gen.event_damage = ons_GeneratorDamage;
gen.reset = ons_GeneratorReset;
setthink(gen, ons_GeneratorThink);
LOG_DEBUG(this.netname, " needs armor ", ftos(needarmor));
// See what is around
- FOREACH_ENTITY_FLOAT(bot_pickup, true,
+ IL_EACH(g_items, it.bot_pickup,
{
// gather health and armor only
if (it.solid)
entity ons_Nearest_ControlPoint(entity this, vector pos, float max_dist)
{
entity closest_target = NULL;
- FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
+ for(entity cp = ons_worldcplist; cp; cp = cp.ons_worldcpnext)
{
- if(SAME_TEAM(it, this))
- if(it.iscaptured)
- if(max_dist <= 0 || vdist(it.origin - pos, <=, max_dist))
- if(vlen2(it.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
- closest_target = it;
- });
- FOREACH_ENTITY_CLASS("onslaught_generator", true,
+ if(SAME_TEAM(cp, this))
+ if(cp.iscaptured)
+ if(max_dist <= 0 || vdist(cp.origin - pos, <=, max_dist))
+ if(vlen2(cp.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
+ closest_target = cp;
+ }
+ for(entity gen = ons_worldgeneratorlist; gen; gen = gen.ons_worldgeneratornext)
{
- if(SAME_TEAM(it, this))
- if(max_dist <= 0 || vdist(it.origin - pos, <, max_dist))
- if(vlen2(it.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
- closest_target = it;
- });
+ if(SAME_TEAM(gen, this))
+ if(max_dist <= 0 || vdist(gen.origin - pos, <, max_dist))
+ if(vlen2(gen.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
+ closest_target = gen;
+ }
return closest_target;
}
vector delta;
float smallest_distance = 0, distance;
- FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
+ for(entity cp = ons_worldcplist; cp; cp = cp.ons_worldcpnext)
{
- delta = it.origin - pos;
+ delta = cp.origin - pos;
delta_z = 0;
distance = vlen(delta);
- if(SAME_TEAM(it, this))
- if(it.iscaptured)
+ if(SAME_TEAM(cp, this))
+ if(cp.iscaptured)
if(max_dist <= 0 || distance <= max_dist)
if(closest_target == NULL || distance <= smallest_distance )
{
- closest_target = it;
+ closest_target = cp;
smallest_distance = distance;
}
- });
- FOREACH_ENTITY_CLASS("onslaught_generator", true,
+ }
+ for(entity gen = ons_worldgeneratorlist; gen; gen = gen.ons_worldgeneratornext)
{
- delta = it.origin - pos;
+ delta = gen.origin - pos;
delta_z = 0;
distance = vlen(delta);
- if(SAME_TEAM(it, this))
+ if(SAME_TEAM(gen, this))
if(max_dist <= 0 || distance <= max_dist)
if(closest_target == NULL || distance <= smallest_distance )
{
- closest_target = it;
+ closest_target = gen;
smallest_distance = distance;
}
- });
+ }
return closest_target;
}
int ons_Count_SelfControlPoints(entity this)
{
int n = 0;
- FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
+ for(entity cp = ons_worldcplist; cp; cp = cp.ons_worldcpnext)
{
- if(SAME_TEAM(it, this))
- if(it.iscaptured)
+ if(SAME_TEAM(cp, this))
+ if(cp.iscaptured)
n++;
- });
- FOREACH_ENTITY_CLASS("onslaught_generator", true,
+ }
+ for(entity gen = ons_worldgeneratorlist; gen; gen = gen.ons_worldgeneratornext)
{
- if(SAME_TEAM(it, this))
+ if(SAME_TEAM(gen, this))
n++;
- });
+ }
return n;
}
// list of generators on the map
entity ons_worldgeneratorlist;
.entity ons_worldgeneratornext;
-.entity ons_stalegeneratornext;
// list of control points on the map
entity ons_worldcplist;
#elif defined(MENUQC)
#elif defined(SVQC)
#include "util.qh"
- #include <common/monsters/all.qh>
+ #include <common/monsters/_mod.qh>
#endif
// generic string stuff
}
if(inWorldspawn)
{
- LOG_MAPWARN(fn, " ended still in worldspawn, BUG\n");
+ LOG_WARN(fn, " ended still in worldspawn, BUG");
return 0;
}
diameter = vlen(mapMaxs - mapMins);
if (sa == "") continue;
int p = strstrofs(sa, "=", 0);
if (p < 0) {
- LOG_MAPWARNF("Invalid gametype setting in mapinfo for gametype %s: %s\n", MapInfo_Type_ToString(pWantedType), sa);
+ LOG_WARNF("Invalid gametype setting in mapinfo for gametype %s: %s", MapInfo_Type_ToString(pWantedType), sa);
continue;
}
string k = substring(sa, 0, p);
}
FOREACH(Gametypes, true, handled |= it.m_parse_mapinfo(k, v));
if (!handled)
- LOG_MAPWARNF("Invalid gametype setting in mapinfo for gametype %s: %s\n", MapInfo_Type_ToString(pWantedType), sa);
+ LOG_WARNF("Invalid gametype setting in mapinfo for gametype %s: %s", MapInfo_Type_ToString(pWantedType), sa);
}
if (pWantedType == MAPINFO_TYPE_RACE && cvar("g_race_teams") >= 2)
#define deprecate(from, to) MACRO_BEGIN { \
if (t == #from) { \
string replacement = #to; \
- LOG_MAPWARNF("MapInfo_Type_FromString (probably %s): using deprecated name '%s'. Should use '%s'.\n", MapInfo_Map_bspname, t, replacement); \
+ LOG_WARNF("MapInfo_Type_FromString (probably %s): using deprecated name '%s'. Should use '%s'.", MapInfo_Map_bspname, t, replacement); \
t = replacement; \
} \
} MACRO_END
{
fh = fopen(s, FILE_READ);
if(fh < 0)
- LOG_MAPWARN("Map ", pFilename, " references not existing config file ", s, "\n");
+ LOG_WARN("Map ", pFilename, " references not existing config file ", s);
else
{
for (;;)
}
}
else
- LOG_MAPWARN("Map ", pFilename, " uses too many levels of inclusion\n");
+ LOG_WARN("Map ", pFilename, " uses too many levels of inclusion");
}
else if(t == "")
- LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+ LOG_WARN("Map ", pFilename, " contains a potentially harmful setting, ignored");
else if (!cvar_value_issafe(t))
- LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+ LOG_WARN("Map ", pFilename, " contains a potentially harmful setting, ignored");
else if (!cvar_value_issafe(s))
- LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+ LOG_WARN("Map ", pFilename, " contains a potentially harmful setting, ignored");
else if(matchacl(MAPINFO_SETTEMP_ACL_SYSTEM, t) <= 0)
- LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+ LOG_WARN("Map ", pFilename, " contains a potentially harmful setting, ignored");
else if(matchacl(acl, t) <= 0)
- LOG_MAPWARN("Map ", pFilename, " contains a denied setting, ignored\n");
+ LOG_WARN("Map ", pFilename, " contains a denied setting, ignored");
else
{
if(type == 0) // server set
if(strstrofs(pFilename, "/", 0) >= 0)
{
- LOG_MAPWARN("Invalid character in map name, ignored\n");
+ LOG_WARN("Invalid character in map name, ignored");
return 0;
}
error("... but I just wrote it!");
}
- LOG_MAPWARN("autogenerated mapinfo file ", fn, " has been loaded; please edit that file and move it to maps/", pFilename, ".mapinfo\n");
+ LOG_WARN("autogenerated mapinfo file ", fn, " has been loaded; please edit that file and move it to maps/", pFilename, ".mapinfo");
}
_MapInfo_Map_Reset();
else if(t == "monsters") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_MONSTERS;
else if(t == "new_toys") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_WEAPONS;
else
- LOG_MAPWARN("Map ", pFilename, " supports unknown feature ", t, ", ignored\n");
+ LOG_WARN("Map ", pFilename, " supports unknown feature ", t, ", ignored");
}
else if(t == "hidden")
{
{
t = car(s); s = cdr(s);
Gametype f = MapInfo_Type_FromString(t);
- LOG_MAPWARN("Map ", pFilename, " contains the legacy 'type' keyword which is deprecated and will be removed in the future. Please migrate the mapinfo file to 'gametype'.\n");
+ LOG_WARN("Map ", pFilename, " contains the legacy 'type' keyword which is deprecated and will be removed in the future. Please migrate the mapinfo file to 'gametype'.");
if(f)
_MapInfo_Map_ApplyGametype (s, pGametypeToSet, f, true);
else
- LOG_MAPWARN("Map ", pFilename, " supports unknown game type ", t, ", ignored\n");
+ LOG_WARN("Map ", pFilename, " supports unknown game type ", t, ", ignored");
}
else if(t == "gametype")
{
if(f)
_MapInfo_Map_ApplyGametypeEx (s, pGametypeToSet, f);
else
- LOG_MAPWARN("Map ", pFilename, " supports unknown game type ", t, ", ignored\n");
+ LOG_WARN("Map ", pFilename, " supports unknown game type ", t, ", ignored");
}
else if(t == "size")
{
t = car(s); s = cdr(s); d = stof(t);
t = car(s); s = cdr(s); e = stof(t);
if(s == "")
- LOG_MAPWARN("Map ", pFilename, " contains an incorrect size line (not enough params), syntax: size mins_x mins_y mins_z maxs_x maxs_y maxs_z\n");
+ LOG_WARN("Map ", pFilename, " contains an incorrect size line (not enough params), syntax: size mins_x mins_y mins_z maxs_x maxs_y maxs_z");
else
{
t = car(s); s = cdr(s); f = stof(t);
if(s != "")
- LOG_MAPWARN("Map ", pFilename, " contains an incorrect size line (too many params), syntax: size mins_x mins_y mins_z maxs_x maxs_y maxs_z\n");
+ LOG_WARN("Map ", pFilename, " contains an incorrect size line (too many params), syntax: size mins_x mins_y mins_z maxs_x maxs_y maxs_z");
else
{
if(a >= d || b >= e || c >= f)
- LOG_MAPWARN("Map ", pFilename, " contains an incorrect size line, mins have to be < maxs\n");
+ LOG_WARN("Map ", pFilename, " contains an incorrect size line, mins have to be < maxs");
else
{
MapInfo_Map_mins.x = a;
else if(t == "settemp_for_type")
{
t = car(s); s = cdr(s);
- Gametype f;
- if((f = MapInfo_Type_FromString(t)))
+ bool all = t == "all";
+ Gametype f = NULL;
+ if(all || (f = MapInfo_Type_FromString(t)))
{
- if(f.m_flags & pGametypeToSet.m_flags)
+ if((all ? MAPINFO_TYPE_ALL : f.m_flags) & pGametypeToSet.m_flags)
{
_MapInfo_Parse_Settemp(pFilename, acl, 0, s, 1);
}
}
else
{
- LOG_MAPWARN("Map ", pFilename, " has a setting for unknown game type ", t, ", ignored\n");
+ LOG_WARN("Map ", pFilename, " has a setting for unknown game type ", t, ", ignored");
}
}
else if(t == "clientsettemp_for_type")
{
t = car(s); s = cdr(s);
- Gametype f;
- if((f = MapInfo_Type_FromString(t)))
+ bool all = t == "all";
+ Gametype f = NULL;
+ if(all || (f = MapInfo_Type_FromString(t)))
{
- if(f.m_flags & pGametypeToSet.m_flags)
+ if((all ? MAPINFO_TYPE_ALL : f.m_flags) & pGametypeToSet.m_flags)
{
_MapInfo_Parse_Settemp(pFilename, acl, 1, s, 1);
}
}
else
{
- LOG_MAPWARN("Map ", pFilename, " has a client setting for unknown game type ", t, ", ignored\n");
+ LOG_WARN("Map ", pFilename, " has a client setting for unknown game type ", t, ", ignored");
}
}
else if(t == "fog")
{
if (!cvar_value_issafe(s))
- LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful fog setting, ignored\n");
+ LOG_WARN("Map ", pFilename, " contains a potentially harmful fog setting, ignored");
else
MapInfo_Map_fog = s;
}
if(pGametypeToSet)
{
if (!cvar_value_issafe(t))
- LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful cdtrack, ignored\n");
+ LOG_WARN("Map ", pFilename, " contains a potentially harmful cdtrack, ignored");
else
MapInfo_Map_clientstuff = strcat(
MapInfo_Map_clientstuff, "cd loop \"", t, "\"\n"
}
}
else
- LOG_MAPWARN("Map ", pFilename, " provides unknown info item ", t, ", ignored\n");
+ LOG_WARN("Map ", pFilename, " provides unknown info item ", t, ", ignored");
}
fclose(fh);
MapInfo_Cache_Store();
if(MapInfo_Map_supportedGametypes != 0)
return r;
- LOG_MAPWARN("Map ", pFilename, " supports no game types, ignored\n");
+ LOG_WARN("Map ", pFilename, " supports no game types, ignored");
return 0;
}
int MapInfo_Get_ByName(string pFilename, float pAllowGenerate, Gametype pGametypeToSet)
_t <<= 1;
MapInfo_Map_supportedGametypes = floor(MapInfo_Map_supportedGametypes >> 1);
}
+ Gametype t_prev = t;
FOREACH(Gametypes, it.m_flags == _t, { t = it; break; });
// t is now a supported mode!
- LOG_WARN("can't play the selected map in the given game mode. Falling back to a supported mode.");
+ LOG_WARNF("can't play the selected map in the given game mode (%s). Falling back to a supported mode (%s).", t_prev.mdl, t.mdl);
MapInfo_LoadMapSettings_SaveGameType(t);
}
MapInfo_Get_ByName(s, 1, t);
#pragma once
-bool autocvar_developer_mapper;
-
-#define LOG_MAPWARN(...) MACRO_BEGIN { if (autocvar_developer_mapper) LOG_WARN(__VA_ARGS__); } MACRO_END
-#define LOG_MAPWARNF(...) MACRO_BEGIN { if (autocvar_developer_mapper) LOG_WARNF(__VA_ARGS__); } MACRO_END
-
#include "util.qh"
// info about a map that MapInfo loads
CLASS(Keepaway, Gametype)
INIT(Keepaway)
{
- this.gametype_init(this, _("Keepaway"),"ka","g_keepaway",true,"","timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
+ this.gametype_init(this, _("Keepaway"),"ka","g_keepaway",false,"","timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
}
METHOD(Keepaway, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
{
if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure || mv_active )
return;
- if(!autocvar_hud_cursormode)
- {
- mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
-
- mousepos_x = bound(0, mousepos_x, vid_conwidth);
- mousepos_y = bound(0, mousepos_y, vid_conheight);
- }
+ if (!autocvar_hud_cursormode)
+ update_mousepos();
if ( HUD_MinigameMenu_IsOpened() && HUD_mouse_over(HUD_PANEL(MINIGAME_MENU)) )
HUD_MinigameMenu_MouseInput();
+++ /dev/null
-#include "_all.qh"
-#include "_mod.inc"
+++ /dev/null
-#pragma once
-#include "_mod.qh"
// generated file; do not modify
#include <common/monsters/all.qc>
-#include <common/monsters/spawn.qc>
#ifdef SVQC
#include <common/monsters/sv_monsters.qc>
#endif
+#ifdef SVQC
+ #include <common/monsters/sv_spawn.qc>
+#endif
+
+#include <common/monsters/monster/_mod.inc>
// generated file; do not modify
#include <common/monsters/all.qh>
-#include <common/monsters/spawn.qh>
#ifdef SVQC
#include <common/monsters/sv_monsters.qh>
#endif
+#ifdef SVQC
+ #include <common/monsters/sv_spawn.qh>
+#endif
+
+#include <common/monsters/monster/_mod.qh>
#include "all.qh"
-#ifndef MONSTERS_ALL_C
-#define MONSTERS_ALL_C
string M_Model(string m_mdl)
{
return output;
#endif
}
-
-#include "all.qh"
-
-#define IMPLEMENTATION
-#include "monster/_mod.inc"
-#undef IMPLEMENTATION
-
-#ifdef SVQC
-#include "spawn.qc"
-#include "sv_monsters.qc"
-#endif
-
-#endif
#pragma once
-#include "monster.qh"
-
string M_Model(string m_mdl);
REGISTRY(Monsters, BITS(5))
#define MON_LAST (Monsters_COUNT - 1)
#define REGISTER_MONSTER(id, inst) REGISTER(Monsters, MON, id, monsterid, inst)
-REGISTER_MONSTER(Null, NEW(Monster));
-
+#include "monster.qh"
-#include "monster/_mod.inc"
+REGISTER_MONSTER(Null, NEW(Monster));
#pragma once
-#ifdef SVQC
-#include "sv_monsters.qh"
-#include <server/g_damage.qh>
-#include <server/bot/api.qh>
-#include <server/weapons/common.qh>
-#include <server/weapons/tracing.qh>
-#include <server/weapons/weaponsystem.qh>
-#include <common/mutators/mutator/waypoints/waypointsprites.qh>
-#include <lib/warpzone/server.qh>
-#endif
-
-#ifdef GAMEQC
-#include "../animdecide.qh"
-#include "../anim.qh"
-vector animfixfps(entity e, vector a, vector b);
-#endif
-
// special spawn flags
const int MONSTER_RESPAWN_DEATHPOINT = 16; // re-spawn where we died
const int MONSTER_TYPE_FLY = 32;
METHOD(Monster, mr_anim, bool(Monster this, entity actor)) { TC(Monster, this); return false; }
ENDCLASS(Monster)
+
+
+#ifdef SVQC
+#include "sv_monsters.qh"
+#include <server/g_damage.qh>
+#include <server/bot/api.qh>
+#include <server/weapons/common.qh>
+#include <server/weapons/tracing.qh>
+#include <server/weapons/weaponsystem.qh>
+#include <common/mutators/mutator/waypoints/waypointsprites.qh>
+#include <lib/warpzone/server.qh>
+#endif
+
+#ifdef GAMEQC
+#include "../animdecide.qh"
+#include "../anim.qh"
+vector animfixfps(entity e, vector a, vector b);
+#endif
#include "mage.qh"
-#ifdef IMPLEMENTATION
-
#ifdef SVQC
SOUND(MageSpike_FIRE, W_Sound("electro_fire"));
set_movetype(missile, MOVETYPE_FLYMISSILE);
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
setorigin(missile, this.origin + v_forward * 14 + '0 0 30' + v_right * -14);
setsize(missile, '0 0 0', '0 0 0');
missile.velocity = dir * 400;
TC(Mage, thismon);
bool need_help = false;
- FOREACH_ENTITY_FLOAT(iscreature, true,
+ FOREACH_CLIENT(IS_PLAYER(it) && it != actor,
{
- if(it != actor)
- if(vdist(it.origin - actor.origin, <=, autocvar_g_monster_mage_heal_range))
+ if(vdist(it.origin - actor.origin, <=, autocvar_g_monster_mage_heal_range))
if(M_Mage_Defend_Heal_Check(actor, it))
{
need_help = true;
}
});
+ if(!need_help)
+ {
+ IL_EACH(g_monsters, it != actor,
+ {
+ if(vdist(it.origin - actor.origin, <=, autocvar_g_monster_mage_heal_range))
+ if(M_Mage_Defend_Heal_Check(actor, it))
+ {
+ need_help = true;
+ break;
+ }
+ });
+ }
+
if(actor.health < (autocvar_g_monster_mage_heal_minhealth) || need_help)
if(time >= actor.attack_finished_single[0])
if(random() < 0.5)
return true;
}
#endif
-
-#endif
#pragma once
+#include "../all.qh"
+
#ifdef GAMEQC
MODEL(MON_MAGE, M_Model("mage.dpm"));
#endif
#include "shambler.qh"
-#ifdef IMPLEMENTATION
-
#ifdef SVQC
float autocvar_g_monster_shambler_health;
float autocvar_g_monster_shambler_damageforcescale = 0.1;
gren.angles = vectoangles (gren.velocity);
gren.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, gren);
+ IL_PUSH(g_bot_dodge, gren);
CSQCProjectile(gren, true, PROJECTILE_SHAMBLER_LIGHTNING, true);
}
return true;
}
#endif
-
-#endif
#pragma once
+#include "../all.qh"
+
#ifdef GAMEQC
MODEL(MON_SHAMBLER, M_Model("shambler.mdl"));
#endif
#include "spider.qh"
-#ifdef IMPLEMENTATION
-
#ifdef SVQC
.float spider_slowness; // effect time of slowness inflicted by spiders
proj.event_damage = func_null;
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.damagedbycontents = true;
proj.bouncefactor = 0.3;
return true;
}
#endif
-
-#endif
#pragma once
+#include "../all.qh"
+
#ifdef GAMEQC
MODEL(MON_SPIDER, M_Model("spider.dpm"));
#endif
#include "wyvern.qh"
-#ifdef IMPLEMENTATION
-
#ifdef SVQC
float autocvar_g_monster_wyvern_attack_fireball_damage;
setorigin(missile, actor.origin + actor.view_ofs + v_forward * 14);
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
missile.velocity = w_shotdir * (autocvar_g_monster_wyvern_attack_fireball_speed);
missile.avelocity = '300 300 300';
missile.nextthink = time + 5;
RadiusDamage(this, own, autocvar_g_monster_wyvern_attack_fireball_damage, autocvar_g_monster_wyvern_attack_fireball_edgedamage, autocvar_g_monster_wyvern_attack_fireball_force, NULL, NULL, autocvar_g_monster_wyvern_attack_fireball_radius, this.projectiledeathtype, NULL);
- FOREACH_ENTITY_FLOAT(takedamage, DAMAGE_AIM,
+ FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_monster_wyvern_attack_fireball_radius, it.takedamage == DAMAGE_AIM,
{
- if(vdist(it.origin - this.origin, <=, autocvar_g_monster_wyvern_attack_fireball_radius))
- Fire_AddDamage(it, own, 5 * MONSTER_SKILLMOD(own), autocvar_g_monster_wyvern_attack_fireball_damagetime, this.projectiledeathtype);
+ Fire_AddDamage(it, own, 5 * MONSTER_SKILLMOD(own), autocvar_g_monster_wyvern_attack_fireball_damagetime, this.projectiledeathtype);
});
delete(this);
return true;
}
#endif
-
-#endif
#pragma once
+#include "../all.qh"
+
#ifdef GAMEQC
MODEL(MON_WYVERN, M_Model("wizard.mdl"));
#endif
#include "zombie.qh"
-#ifdef IMPLEMENTATION
-
#ifdef SVQC
float autocvar_g_monster_zombie_health;
float autocvar_g_monster_zombie_damageforcescale = 0.55;
return true;
}
#endif
-
-#endif
#pragma once
+#include "../all.qh"
+
#ifdef GAMEQC
MODEL(MON_ZOMBIE, M_Model("zombie.dpm"));
#endif
+++ /dev/null
-#include "spawn.qh"
-#if defined(CSQC)
-#elif defined(MENUQC)
-#elif defined(SVQC)
- #include "../util.qh"
- #include "all.qh"
- #include "sv_monsters.qh"
- #include "spawn.qh"
- #include <server/autocvars.qh>
- #include <server/defs.qh>
-#endif
-entity spawnmonster (string monster, float monster_id, entity spawnedby, entity own, vector orig, float respwn, float invincible, float moveflag)
-{
- float i;
- entity e = spawn();
-
- e.spawnflags = MONSTERFLAG_SPAWNED;
-
- if(!respwn) { e.spawnflags |= MONSTERFLAG_NORESPAWN; }
- if(invincible) { e.spawnflags |= MONSTERFLAG_INVINCIBLE; }
-
- setorigin(e, orig);
-
- if(monster == "random")
- {
- RandomSelection_Init();
- for(i = MON_FIRST; i <= MON_LAST; ++i)
- RandomSelection_Add(NULL, i, string_null, 1, 1);
-
- monster_id = RandomSelection_chosen_float;
- }
- else if(monster != "")
- {
- float found = 0;
- entity mon;
- for(i = MON_FIRST; i <= MON_LAST; ++i)
- {
- mon = get_monsterinfo(i);
- if(mon.netname == monster)
- {
- found = true;
- monster_id = mon.monsterid; // we have the monster, old monster id is no longer required
- break;
- }
- }
- if(!found)
- monster_id = ((monster_id > 0) ? monster_id : MON_FIRST);
- }
-
- e.realowner = spawnedby;
-
- if(moveflag)
- e.monster_moveflags = moveflag;
-
- if(IS_PLAYER(spawnedby))
- {
- if(teamplay && autocvar_g_monsters_teams)
- e.team = spawnedby.team; // colors handled in spawn code
-
- if(autocvar_g_monsters_owners)
- e.monster_follow = own; // using .owner makes the monster non-solid for its master
-
- e.angles_y = spawnedby.angles_y;
- }
-
- // Monster_Spawn checks if monster is valid
- Monster_Spawn(e, monster_id);
-
- return e;
-}
+++ /dev/null
-#pragma once
-
-entity spawnmonster (string monster, float monster_id, entity spawnedby, entity own, vector orig, float respwn, float invincible, float moveflag);
return false;
}
- traceline(this.origin + this.view_ofs, targ.origin, 0, this);
+ traceline(this.origin + this.view_ofs, targ.origin, MOVE_NOMONSTERS, this);
- if((trace_fraction < 1) && (trace_ent != targ))
- return false;
+ if(trace_fraction < 1)
+ return false; // solid
if(autocvar_g_monsters_target_infront || (this.spawnflags & MONSTERFLAG_INFRONT))
if(this.enemy != targ)
this.classname = "monster";
this.takedamage = DAMAGE_AIM;
this.bot_attack = true;
+ IL_PUSH(g_bot_targets, this);
this.iscreature = true;
this.teleportable = true;
this.damagedbycontents = true;
--- /dev/null
+#include "sv_spawn.qh"
+#if defined(CSQC)
+#elif defined(MENUQC)
+#elif defined(SVQC)
+ #include "../util.qh"
+ #include "all.qh"
+ #include "sv_monsters.qh"
+ #include <server/autocvars.qh>
+ #include <server/defs.qh>
+#endif
+entity spawnmonster (string monster, float monster_id, entity spawnedby, entity own, vector orig, float respwn, float invincible, float moveflag)
+{
+ float i;
+ entity e = spawn();
+
+ e.spawnflags = MONSTERFLAG_SPAWNED;
+
+ if(!respwn) { e.spawnflags |= MONSTERFLAG_NORESPAWN; }
+ if(invincible) { e.spawnflags |= MONSTERFLAG_INVINCIBLE; }
+
+ setorigin(e, orig);
+
+ if(monster == "random")
+ {
+ RandomSelection_Init();
+ for(i = MON_FIRST; i <= MON_LAST; ++i)
+ RandomSelection_Add(NULL, i, string_null, 1, 1);
+
+ monster_id = RandomSelection_chosen_float;
+ }
+ else if(monster != "")
+ {
+ float found = 0;
+ entity mon;
+ for(i = MON_FIRST; i <= MON_LAST; ++i)
+ {
+ mon = get_monsterinfo(i);
+ if(mon.netname == monster)
+ {
+ found = true;
+ monster_id = mon.monsterid; // we have the monster, old monster id is no longer required
+ break;
+ }
+ }
+ if(!found)
+ monster_id = ((monster_id > 0) ? monster_id : MON_FIRST);
+ }
+
+ e.realowner = spawnedby;
+
+ if(moveflag)
+ e.monster_moveflags = moveflag;
+
+ if(IS_PLAYER(spawnedby))
+ {
+ if(teamplay && autocvar_g_monsters_teams)
+ e.team = spawnedby.team; // colors handled in spawn code
+
+ if(autocvar_g_monsters_owners)
+ e.monster_follow = own; // using .owner makes the monster non-solid for its master
+
+ e.angles_y = spawnedby.angles_y;
+ }
+
+ // Monster_Spawn checks if monster is valid
+ Monster_Spawn(e, monster_id);
+
+ return e;
+}
--- /dev/null
+#pragma once
+
+entity spawnmonster (string monster, float monster_id, entity spawnedby, entity own, vector orig, float respwn, float invincible, float moveflag);
this.classname = "item_buff";
this.solid = SOLID_TRIGGER;
this.flags = FL_ITEM;
+ this.bot_pickup = true;
+ this.bot_pickupevalfunc = commodity_pickupevalfunc;
+ this.bot_pickupbasevalue = 1000;
+ IL_PUSH(g_items, this);
setthink(this, buff_Think);
settouch(this, buff_Touch);
this.reset = buff_Reset;
if(player.buffs & BUFF_MAGNET.m_itemid)
{
vector pickup_size;
- FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
+ IL_EACH(g_items, it.classname != "item_flag_team" && it.classname != "item_kh_key",
{
if(it.buffs)
pickup_size = '1 1 1' * autocvar_g_buffs_magnet_range_buff;
float Item_ItemsTime_UpdateTime(entity e, float t)
{
bool isavailable = (t == 0);
- FOREACH_ENTITY_FLOAT(pure_data, false,
+ IL_EACH(g_items, it != e,
{
- if(!(it.itemdef == e.itemdef || ((e.weapons & WEPSET_SUPERWEAPONS) && (it.weapons & WEPSET_SUPERWEAPONS) && clienttype(it) == CLIENTTYPE_NOTACLIENT)))
+ if(!(it.itemdef == e.itemdef || ((e.weapons & WEPSET_SUPERWEAPONS) && (it.weapons & WEPSET_SUPERWEAPONS))))
continue;
- if (e == it) continue;
if (it.scheduledrespawntime <= time)
isavailable = true;
else if (t == 0 || it.scheduledrespawntime < t)
Item_ItemsTime_ResetTimes();
// ALL the times need to be reset before .reset()ing each item
// since Item_Reset schedules respawn of superweapons and powerups
- FOREACH_ENTITY_FLOAT(pure_data, false,
+ IL_EACH(g_items, it.reset,
{
- if(IS_CLIENT(it))
- continue;
- if (it.reset) Item_ItemsTime_SetTime(it, 0);
+ Item_ItemsTime_SetTime(it, 0);
});
Item_ItemsTime_SetTimesForAllPlayers();
}
#ifdef SVQC
#include <common/gamemodes/_mod.qh>
-#include <common/monsters/spawn.qh>
+#include <common/monsters/sv_spawn.qh>
#include <common/monsters/sv_monsters.qh>
#include <server/g_subs.qh>
proj.angles = vectoangles(proj.velocity);
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
//CSQCProjectile(proj, true, PROJECTILE_NAPALM_FIRE, true);
fountain.owner = this.owner;
fountain.realowner = this.realowner;
fountain.origin = this.origin;
+ fountain.flags = FL_PROJECTILE;
+ IL_PUSH(g_projectiles, fountain);
+ IL_PUSH(g_bot_dodge, fountain);
setorigin(fountain, fountain.origin);
setthink(fountain, napalm_fountain_think);
fountain.nextthink = time;
case NADE_TYPE_ENTRAP: nade_entrap_boom(this); break;
}
- FOREACH_ENTITY_ENT(aiment, this,
+ IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
{
- if(it.classname == "grapplinghook")
- RemoveGrapplingHook(it.realowner);
+ RemoveGrapplingHook(it.realowner);
});
delete(this);
is_weapclip = 1;*/
if(ITEM_TOUCH_NEEDKILL()) // || is_weapclip)
{
- FOREACH_ENTITY_ENT(aiment, this,
+ IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
{
- if(it.classname == "grapplinghook")
- RemoveGrapplingHook(it.realowner);
+ RemoveGrapplingHook(it.realowner);
});
delete(this);
return;
_nade.angles = vectoangles(_nade.velocity);
_nade.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, _nade);
+ IL_PUSH(g_bot_dodge, _nade);
_nade.projectiledeathtype = DEATH_NADE.m_id;
_nade.toss_time = time;
_nade.solid = SOLID_CORPSE; //((_nade.nade_type == NADE_TYPE_TRANSLOCATE) ? SOLID_CORPSE : SOLID_BBOX);
missile.nextthink = time;
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
CSQCProjectile(missile, true, PROJECTILE_RPC, false);
{
// detaches any object attached to e
- FOREACH_ENTITY_ENT(owner, e,
+ IL_EACH(g_sandbox_objects, it.owner == e,
{
- if(it.classname != "object") continue;
-
- vector org;
- org = gettaginfo(it, 0);
+ vector org = gettaginfo(it, 0);
setattachment(it, NULL, "");
it.owner = NULL;
// spawn a new object with default properties
entity e = new(object);
+ IL_PUSH(g_sandbox_objects, e);
e.takedamage = DAMAGE_AIM;
e.damageforcescale = 1;
e.solid = SOLID_BBOX; // SOLID_BSP would be best, but can lag the server badly
string port_string[MAX_STORAGE_ATTACHMENTS]; // fteqcc crashes if this isn't defined as a global
-string sandbox_ObjectPort_Save(entity e, float database)
+string sandbox_ObjectPort_Save(entity e, bool database)
{
// save object properties, and return them as a string
- float i = 0;
- string s;
- entity head;
+ int o = 0;
- for(head = NULL; (head = find(head, classname, "object")); )
- {
+ // order doesn't really matter, as we're writing the file fresh
+ IL_EACH(g_sandbox_objects, it == e || it.owner == e, LAMBDA(
// the main object needs to be first in the array [0] with attached objects following
- float slot, physics, solidity;
- if(head == e) // this is the main object, place it first
+ int slot, physics, solidity;
+ if(it == e) // this is the main object, place it first
{
slot = 0;
- solidity = head.solid; // applied solidity is normal solidity for children
- physics = head.move_movetype; // applied physics are normal physics for parents
+ solidity = it.solid; // applied solidity is normal solidity for children
+ physics = it.move_movetype; // applied physics are normal physics for parents
}
- else if(head.owner == e) // child object, list them in order
+ else if(it.owner == e) // child object, list them in order
{
- i += 1; // children start from 1
- slot = i;
- solidity = head.old_solid; // persisted solidity is normal solidity for children
- physics = head.old_movetype; // persisted physics are normal physics for children
- gettaginfo(head.owner, head.tag_index); // get the name of the tag our object is attached to, used further below
+ o += 1; // children start from 1
+ slot = o;
+ solidity = it.old_solid; // persisted solidity is normal solidity for children
+ physics = it.old_movetype; // persisted physics are normal physics for children
+ gettaginfo(it.owner, it.tag_index); // get the name of the tag our object is attached to, used further below
}
else
continue;
if(slot)
{
// properties stored only for child objects
- if(gettaginfo_name) port_string[slot] = strcat(port_string[slot], "\"", gettaginfo_name, "\" "); else port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+ if(gettaginfo_name)
+ port_string[slot] = strcat(port_string[slot], "\"", gettaginfo_name, "\" ");
+ else
+ port_string[slot] = strcat(port_string[slot], "\"\" "); // none
}
else
{
// properties stored only for parent objects
if(database)
{
- port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.origin), " ");
- port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.angles), " ");
+ port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.origin), " ");
+ port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.angles), " ");
}
}
// properties stored for all objects
- port_string[slot] = strcat(port_string[slot], "\"", head.model, "\" ");
- port_string[slot] = strcat(port_string[slot], ftos(head.skin), " ");
- port_string[slot] = strcat(port_string[slot], ftos(head.alpha), " ");
- port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.colormod), " ");
- port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.glowmod), " ");
- port_string[slot] = strcat(port_string[slot], ftos(head.frame), " ");
- port_string[slot] = strcat(port_string[slot], ftos(head.scale), " ");
+ port_string[slot] = strcat(port_string[slot], "\"", it.model, "\" ");
+ port_string[slot] = strcat(port_string[slot], ftos(it.skin), " ");
+ port_string[slot] = strcat(port_string[slot], ftos(it.alpha), " ");
+ port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.colormod), " ");
+ port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.glowmod), " ");
+ port_string[slot] = strcat(port_string[slot], ftos(it.frame), " ");
+ port_string[slot] = strcat(port_string[slot], ftos(it.scale), " ");
port_string[slot] = strcat(port_string[slot], ftos(solidity), " ");
port_string[slot] = strcat(port_string[slot], ftos(physics), " ");
- port_string[slot] = strcat(port_string[slot], ftos(head.damageforcescale), " ");
- if(head.material) port_string[slot] = strcat(port_string[slot], "\"", head.material, "\" "); else port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+ port_string[slot] = strcat(port_string[slot], ftos(it.damageforcescale), " ");
+ if(it.material)
+ port_string[slot] = strcat(port_string[slot], "\"", it.material, "\" ");
+ else
+ port_string[slot] = strcat(port_string[slot], "\"\" "); // none
if(database)
{
// properties stored only for the database
- if(head.crypto_idfp) port_string[slot] = strcat(port_string[slot], "\"", head.crypto_idfp, "\" "); else port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+ if(it.crypto_idfp)
+ port_string[slot] = strcat(port_string[slot], "\"", it.crypto_idfp, "\" ");
+ else
+ port_string[slot] = strcat(port_string[slot], "\"\" "); // none
port_string[slot] = strcat(port_string[slot], "\"", e.netname, "\" ");
port_string[slot] = strcat(port_string[slot], "\"", e.message, "\" ");
port_string[slot] = strcat(port_string[slot], "\"", e.message2, "\" ");
}
- }
+ ));
// now apply the array to a simple string, with the ; symbol separating objects
- s = "";
- for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
+ string s = "";
+ for(int j = 0; j <= MAX_STORAGE_ATTACHMENTS; ++j)
{
- if(port_string[i])
- s = strcat(s, port_string[i], "; ");
- port_string[i] = string_null; // fully clear the string
+ if(port_string[j])
+ s = strcat(s, port_string[j], "; ");
+ port_string[j] = string_null; // fully clear the string
}
return s;
void sandbox_Database_Save()
{
// saves all objects to the database file
- entity head;
string file_name;
float file_get;
fputs(file_get, strcat("// sandbox storage \"", autocvar_g_sandbox_storage_name, "\" for map \"", GetMapname(), "\" last updated ", strftime(true, "%d-%m-%Y %H:%M:%S")));
fputs(file_get, strcat(" containing ", ftos(object_count), " objects\n"));
- for(head = NULL; (head = find(head, classname, "object")); )
+ IL_EACH(g_sandbox_objects, !it.owner, // attached objects are persisted separately, ignore them here
{
- // attached objects are persisted separately, ignore them here
- if(head.owner != NULL)
- continue;
-
// use a line of text for each object, listing all properties
- fputs(file_get, strcat(sandbox_ObjectPort_Save(head, true), "\n"));
- }
+ fputs(file_get, strcat(sandbox_ObjectPort_Save(it, true), "\n"));
+ });
fclose(file_get);
}
// this should show the same info as 'mesh' but for attachments
s = "";
j = 0;
- FOREACH_ENTITY_ENT(owner, e,
+ IL_EACH(g_sandbox_objects, it.owner == e,
{
- if(it.classname != "object") continue;
-
++j; // start from 1
gettaginfo(e, it.tag_index);
s = strcat(s, "^1attachment ", ftos(j), "^7 has mesh \"^3", it.model, "^7\" at animation frame ^3", ftos(it.frame));
#pragma once
+
+IntrusiveList g_sandbox_objects;
+STATIC_INIT(g_sandbox_objects) { g_sandbox_objects = IL_NEW(); }
net_notif.nent_net_name = ORDINAL(net_cpid);
Net_LinkEntity(net_notif, false, autocvar_notification_lifetime_runtime, Net_Write_Notification);
- FOREACH_ENTITY_CLASS(
- "net_notification",
+ IL_EACH(
+ g_notifications,
(it.owner.nent_type == net_type || net_type == MSG_Null) && (it.owner.nent_cpid == net_cpid || net_cpid == CPID_Null),
{
it.nent_net_name = -1;
else
{
entity net_notif = new_pure(net_notification);
+ IL_PUSH(g_notifications, net_notif);
net_notif.owner = notif;
net_notif.nent_broadcast = broadcast;
net_notif.nent_client = client;
float prev_soundtime;
#endif
+#ifdef SVQC
+IntrusiveList g_notifications;
+STATIC_INIT(g_notifications) { g_notifications = IL_NEW(); }
+#endif
+
#ifdef SVQC
ENUMCLASS(NOTIF)
/** send to one client and their spectators */
: a * pow(fabs(b / a), _lerp);
}
-#define unstick_offsets(X) \
-/* 1 no nudge (just return the original if this test passes) */ \
- X(' 0.000 0.000 0.000') \
-/* 6 simple nudges */ \
- X(' 0.000 0.000 0.125') X('0.000 0.000 -0.125') \
- X('-0.125 0.000 0.000') X('0.125 0.000 0.000') \
- X(' 0.000 -0.125 0.000') X('0.000 0.125 0.000') \
-/* 4 diagonal flat nudges */ \
- X('-0.125 -0.125 0.000') X('0.125 -0.125 0.000') \
- X('-0.125 0.125 0.000') X('0.125 0.125 0.000') \
-/* 8 diagonal upward nudges */ \
- X('-0.125 0.000 0.125') X('0.125 0.000 0.125') \
- X(' 0.000 -0.125 0.125') X('0.000 0.125 0.125') \
- X('-0.125 -0.125 0.125') X('0.125 -0.125 0.125') \
- X('-0.125 0.125 0.125') X('0.125 0.125 0.125') \
-/* 8 diagonal downward nudges */ \
- X('-0.125 0.000 -0.125') X('0.125 0.000 -0.125') \
- X(' 0.000 -0.125 -0.125') X('0.000 0.125 -0.125') \
- X('-0.125 -0.125 -0.125') X('0.125 -0.125 -0.125') \
- X('-0.125 0.125 -0.125') X('0.125 0.125 -0.125') \
-/**/
-
-void PM_ClientMovement_Unstick(entity this)
-{
- #define X(unstick_offset) \
- { \
- vector neworigin = unstick_offset + this.origin; \
- tracebox(neworigin, STAT(PL_CROUCH_MIN, NULL), STAT(PL_CROUCH_MAX, NULL), neworigin, MOVE_NORMAL, this); \
- if (!trace_startsolid) \
- { \
- setorigin(this, neworigin); \
- return; \
- } \
- }
- unstick_offsets(X);
- #undef X
-}
-
void PM_ClientMovement_UpdateStatus(entity this)
{
#ifdef CSQC
#include "triggers/subs.qh"
#include "util.qh"
- #include <common/monsters/all.qh>
+ #include <common/monsters/_mod.qh>
#include <common/weapons/_all.qh>
if(this.team)
{
RandomSelection_Init();
- FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
+ IL_EACH(g_items, it.team == this.team,
{
- if(it.team == this.team)
- if(it.classname != "item_flag_team" && it.classname != "item_key_team")
+ if(it.classname != "item_flag_team" && it.classname != "item_kh_key")
{
Item_Show(it, -1);
RandomSelection_Add(it, 0, string_null, it.cnt, 0);
// marker for item team search
LOG_TRACE("Initializing item team ", ftos(this.team));
RandomSelection_Init();
- FOREACH_ENTITY_FLOAT(team, this.team,
+ IL_EACH(g_items, it.team == this.team,
{
- if(it.flags & FL_ITEM)
- if(it.classname != "item_flag_team" && it.classname != "item_key_team")
+ if(it.classname != "item_flag_team" && it.classname != "item_kh_key")
RandomSelection_Add(it, 0, string_null, it.cnt, 0);
});
e.state = 0;
Item_Show(e, 1);
- FOREACH_ENTITY_FLOAT(team, this.team,
+ IL_EACH(g_items, it.team == this.team,
{
- if(it.flags & FL_ITEM)
- if(it.classname != "item_flag_team" && it.classname != "item_key_team")
+ if(it.classname != "item_flag_team" && it.classname != "item_kh_key")
{
if(it != e)
{
this.weapons = WepSet_FromWeapon(Weapons_from(weaponid));
this.flags = FL_ITEM | itemflags;
+ IL_PUSH(g_items, this);
if(MUTATOR_CALLHOOK(FilterItem, this)) // error means we do not want the item
{
EXACTTRIGGER_TOUCH(this, trigger);
}
- FOREACH_ENTITY_ENT(enemy, actor,
+ IL_EACH(g_items, it.enemy == actor && it.classname == "droppedweapon",
{
- if(it.classname == "droppedweapon")
- delete(it);
+ delete(it);
});
if(GiveItems(actor, 0, tokenize_console(this.netname)))
{
this.health = this.max_health;
this.takedamage = DAMAGE_NO;
+ if(this.bot_attack)
+ IL_REMOVE(g_bot_targets, this);
this.bot_attack = false;
this.event_damage = func_null;
this.state = 1;
if(!(this.spawnflags & 4))
{
this.takedamage = DAMAGE_AIM;
+ if(!this.bot_attack)
+ IL_PUSH(g_bot_targets, this);
this.bot_attack = true;
this.event_damage = func_breakable_damage;
}
this.reset = func_breakable_reset;
this.reset(this);
- this.init_for_player_needed = 1;
+ IL_PUSH(g_initforplayer, this);
this.init_for_player = func_breakable_init_for_player;
CSQCMODEL_AUTOINIT(this);
#endif
// set mythis as current conveyor where possible
- FOREACH_ENTITY_ENT(conveyor, this,
+ IL_EACH(g_conveyed, it.conveyor == this,
{
it.conveyor = NULL;
+ IL_REMOVE(g_conveyed, it);
});
if(this.state)
}
if(boxesoverlap(emin, emax, this.absmin, this.absmax)) // quick
if(WarpZoneLib_BoxTouchesBrush(emin, emax, this, it)) // accurate
+ {
+ if(!it.conveyor)
+ IL_PUSH(g_conveyed, it);
it.conveyor = this;
+ }
});
- FOREACH_ENTITY_ENT(conveyor, this,
+ IL_EACH(g_conveyed, it.conveyor == this,
{
if(IS_CLIENT(it)) // doing it via velocity has quite some advantages
continue; // done in SV_PlayerPhysics continue;
#pragma once
+
+IntrusiveList g_conveyed;
+STATIC_INIT(g_conveyed) { g_conveyed = IL_NEW(); }
string message_save;
this.health = 10000;
+ if(!this.bot_attack)
+ IL_PUSH(g_bot_targets, this);
this.bot_attack = true;
// exit if still moving around...
#ifdef SVQC
+IntrusiveList g_targetmusic_list;
+STATIC_INIT(g_targetmusic_list) { g_targetmusic_list = IL_NEW(); }
+
// values:
// volume
// noise
}
void target_music_kill()
{
- FOREACH_ENTITY_CLASS("target_music", true, {
+ IL_EACH(g_targetmusic_list, true,
+ {
it.volume = 0;
if (it.targetname == "")
target_music_sendto(it, MSG_ALL, 1);
this.reset = target_music_reset;
if(!this.volume)
this.volume = 1;
+ IL_PUSH(g_targetmusic_list, this);
if(this.targetname == "")
target_music_sendto(this, MSG_INIT, 1);
else
}
void TargetMusic_RestoreGame()
{
- FOREACH_ENTITY_CLASS("target_music", true,
+ IL_EACH(g_targetmusic_list, true,
{
if(it.targetname == "")
target_music_sendto(it, MSG_INIT, 1);
entity Teleport_Find(vector mi, vector ma)
{
- entity e;
- for(e = NULL; (e = find(e, classname, "trigger_teleport")); )
- if(WarpZoneLib_BoxTouchesBrush(mi, ma, e, NULL))
- return e;
+ IL_EACH(g_teleporters, WarpZoneLib_BoxTouchesBrush(mi, ma, it, NULL),
+ {
+ return it;
+ });
return NULL;
}
#pragma once
+IntrusiveList g_teleporters;
+STATIC_INIT(g_teleporters) { g_teleporters = IL_NEW(); }
+
.entity pusher;
const float TELEPORT_FLAG_SOUND = 1;
const float TELEPORT_FLAG_PARTICLES = 2;
return;
}
+ IL_PUSH(g_teleporters, this);
+
this.teleport_next = teleport_first;
teleport_first = this;
}
NET_HANDLE(ENT_CLIENT_TRIGGER_TELEPORT, bool isnew)
{
this.classname = "trigger_teleport";
+ if(isnew)
+ IL_PUSH(g_teleporters, this);
int mytm = ReadByte(); if(mytm) { this.team = mytm - 1; }
this.spawnflags = ReadInt24_t();
this.active = ReadByte();
proj.velocity = normalize(actor.tur_shotdir_updated + randomvec() * actor.shot_spread) * actor.shot_speed;
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.enemy = actor.enemy;
proj.totalfrags = _death;
PROJECTILE_MAKETRIGGER(proj);
if(!this.tur_head) {
tur.tr_precache(tur);
IL_PUSH(g_turrets, this);
+ IL_PUSH(g_bot_targets, this);
}
entity e = find(NULL, classname, "turret_manager");
void turret_targettrigger_touch(entity this, entity toucher)
{
if (this.cnt > time) return;
- FOREACH_ENTITY_STRING_ORDERED(targetname, this.target, {
+ IL_EACH(g_turrets, it.targetname == this.target,
+ {
if (!(it.turret_flags & TUR_FLAG_RECIEVETARGETS)) continue;
if (!it.turret_addtarget) continue;
it.turret_addtarget(it, toucher, this);
set_movetype(beam, MOVETYPE_NONE);
beam.enemy = actor.enemy;
beam.bot_dodge = true;
+ IL_PUSH(g_bot_dodge, beam);
beam.bot_dodgerating = beam.shot_dmg;
sound (beam, CH_SHOTS_SINGLE, SND_TUR_PHASER, VOL_BASE, ATTEN_NORM);
actor.fireflag = 1;
settouch(rocket, walker_rocket_touch);
rocket.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, rocket);
+ IL_PUSH(g_bot_dodge, rocket);
rocket.solid = SOLID_BBOX;
rocket.max_health = time + 9;
rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
n = tokenize_console(neworder);
for(w = to; w >= from; --w)
{
+ int wflags = Weapons_from(w).spawnflags;
+ if((wflags & WEP_FLAG_HIDDEN) && (wflags & WEP_FLAG_MUTATORBLOCKED) && !(wflags & WEP_FLAG_NORMAL))
+ continue;
for(i = 0; i < n; ++i)
if(stof(argv(i)) == w)
break;
return 0;
}
- FOREACH_ENTITY_CLASS("saved_cvar_value", it.netname == tmp_cvar,
+ IL_EACH(g_saved_cvars, it.netname == tmp_cvar,
{
created_saved_value = -1; // skip creation
break; // no need to continue
{
// creating a new entity to keep track of this cvar
entity e = new_pure(saved_cvar_value);
+ IL_PUSH(g_saved_cvars, e);
e.netname = strzone(tmp_cvar);
e.message = strzone(cvar_string(tmp_cvar));
created_saved_value = 1;
get_model_parameters_bone_aimweight[i] = 0;
}
get_model_parameters_fixbone = 0;
+ get_model_parameters_hidden = false;
#ifdef GAMEQC
MUTATOR_CALLHOOK(ClearModelParams);
}
if(c == "fixbone")
get_model_parameters_fixbone = stof(s);
+ if(c == "hidden")
+ get_model_parameters_hidden = stob(s);
}
while((s = fgets(fh)))
vector real_origin(entity ent);
#endif
+IntrusiveList g_saved_cvars;
+STATIC_INIT(g_saved_cvars) { g_saved_cvars = IL_NEW(); }
+
// this returns a tempstring containing a copy of s with additional \n newlines added, it also replaces \n in the text with a real newline
// NOTE: s IS allowed to be a tempstring
string wordwrap(string s, float l);
string get_model_parameters_sex;
float get_model_parameters_weight;
float get_model_parameters_age;
+bool get_model_parameters_hidden;
string get_model_parameters_description;
string get_model_parameters_bone_upperbody;
string get_model_parameters_bone_weapon;
set_movetype(proj, MOVETYPE_FLYMISSILE);
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.bot_dodge = true;
proj.bot_dodgerating = _dmg;
proj.velocity = _vel;
void vehicles_clearreturn(entity veh)
{
// Remove "return helper" entities, if any.
- FOREACH_ENTITY_ENT(wp00, veh,
+ IL_EACH(g_vehicle_returners, it.wp00 == veh,
{
- if(it.classname == "vehicle_return")
- {
- it.classname = "";
- setthink(it, SUB_Remove);
- it.nextthink = time + 0.1;
+ it.classname = "";
+ setthink(it, SUB_Remove);
+ it.nextthink = time + 0.1;
+ IL_REMOVE(g_vehicle_returners, it);
- if(it.waypointsprite_attached)
- WaypointSprite_Kill(it.waypointsprite_attached);
- }
+ if(it.waypointsprite_attached)
+ WaypointSprite_Kill(it.waypointsprite_attached);
});
}
vehicles_clearreturn(veh);
entity ret = new(vehicle_return);
+ IL_PUSH(g_vehicle_returners, ret);
ret.wp00 = veh;
ret.team = veh.team;
setthink(ret, vehicles_showwp);
this.solid = SOLID_SLIDEBOX;
this.takedamage = DAMAGE_AIM;
this.deadflag = DEAD_NO;
+ if(!this.bot_attack)
+ IL_PUSH(g_bot_targets, this);
this.bot_attack = true;
this.flags = FL_NOTARGET;
this.avelocity = '0 0 0';
this.tur_head.owner = this;
this.takedamage = DAMAGE_NO;
this.bot_attack = true;
+ IL_PUSH(g_bot_targets, this);
this.iscreature = true;
this.teleportable = false; // no teleporting for vehicles, too buggy
this.damagedbycontents = true;
bool vehicles_crushable(entity e);
float vehicle_altitude(entity this, float amax);
+IntrusiveList g_vehicle_returners;
+STATIC_INIT(g_vehicle_returners) { g_vehicle_returners = IL_NEW(); }
+
#endif
void raptor_flare_think(entity this)
{
this.nextthink = time + 0.1;
- FOREACH_ENTITY_ENT(enemy, this.owner,
+ IL_EACH(g_projectiles, it.enemy == this.owner,
{
- if(it.flags & FL_PROJECTILE)
if(vdist(this.origin - it.origin, <, autocvar_g_vehicle_raptor_flare_range))
if(random() > autocvar_g_vehicle_raptor_flare_chase)
it.enemy = this;
{
vector spot;
- FOREACH_ENTITY_ENT(owner, this.owner,
+ IL_EACH(g_projectiles, it.owner == this.owner && it.classname == "spiderbot_rocket",
{
- if(it.classname != "spiderbot_rocket") continue;
it.realowner = this.owner;
it.owner = NULL;
});
void spiderbot_guide_release(entity this)
{
- FOREACH_ENTITY_ENT(realowner, this.owner,
+ bool donetrace = false;
+ IL_EACH(g_projectiles, it.realowner == this.owner && getthink(it) == spiderbot_rocket_guided,
{
- if(i == 0) // something exists, let's trace!
- crosshair_trace(this.owner);
-
- if(getthink(it) == spiderbot_rocket_guided)
+ if(!donetrace) // something exists, let's trace!
{
- it.pos1 = trace_endpos;
- setthink(it, spiderbot_rocket_unguided);
+ donetrace = true;
+ crosshair_trace(this.owner);
}
+
+ it.pos1 = trace_endpos;
+ setthink(it, spiderbot_rocket_unguided);
});
}
#include "../stats.qh"
#include "../teams.qh"
#include "../util.qh"
- #include "../monsters/all.qh"
+ #include "../monsters/_mod.qh"
#include "config.qh"
#include <server/weapons/csqcprojectile.qh>
#include <server/weapons/tracing.qh>
missile = new(missile);
missile.owner = missile.realowner = actor;
missile.bot_dodge = true;
+ IL_PUSH(g_bot_dodge, missile);
missile.bot_dodgerating = WEP_CVAR(arc, bolt_damage);
missile.takedamage = DAMAGE_YES;
beam.owner = actor;
set_movetype(beam, MOVETYPE_NONE);
beam.bot_dodge = true;
+ IL_PUSH(g_bot_dodge, beam);
beam.bot_dodgerating = WEP_CVAR(arc, beam_damage);
beam.beam_bursting = burst;
Net_LinkEntity(beam, false, 0, W_Arc_Beam_Send);
settouch(missile, W_Blaster_Touch);
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
missile.missile_flags = MIF_SPLASH;
missile.projectiledeathtype = atk_deathtype;
setthink(missile, W_Blaster_Think);
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.missile_flags = MIF_SPLASH;
CSQCProjectile(proj, true, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), true);
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.missile_flags = MIF_SPLASH;
CSQCProjectile(proj, true, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), true);
missile.cnt = time + WEP_CVAR(devastator, lifetime);
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
missile.missile_flags = MIF_SPLASH;
CSQCProjectile(missile, WEP_CVAR(devastator, guiderate) == 0 && WEP_CVAR(devastator, speedaccel) == 0, PROJECTILE_ROCKET, false); // because of fly sound
MUTATOR_CALLHOOK(EditProjectile, actor, missile);
}
-#if 0
-METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
-{
- entity this = actor;
- // aim and decide to fire if appropriate
- PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
- if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
- {
- // decide whether to detonate rockets
- entity missile, targetlist, targ;
- targetlist = findchainfloat(bot_attack, true);
- for(missile = NULL; (missile = find(missile, classname, "rocket")); ) if(missile.realowner == actor)
- {
- targ = targetlist;
- while(targ)
- {
- if(targ != missile.realowner && vlen(targ.origin - missile.origin) < WEP_CVAR(devastator, radius))
- {
- PHYS_INPUT_BUTTON_ATCK2(actor) = true;
- break;
- }
- targ = targ.chain;
- }
- }
-
- if(PHYS_INPUT_BUTTON_ATCK2(actor)) PHYS_INPUT_BUTTON_ATCK(actor) = false;
- }
-}
-#else
METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
{
// aim and decide to fire if appropriate
selfdamage = 0;
teamdamage = 0;
enemydamage = 0;
- FOREACH_ENTITY_ENT(realowner, actor,
+ IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket",
{
- if(it.classname != "rocket") continue;
-
entity rocket = it;
- FOREACH_ENTITY_FLOAT(bot_attack, true,
+ IL_EACH(g_bot_targets, it.bot_attack,
{
float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - rocket.origin);
d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
desirabledamage = desirabledamage - teamdamage;
makevectors(actor.v_angle);
- FOREACH_ENTITY_ENT(realowner, actor,
+ IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket",
{
- if(it.classname != "rocket") continue;
-
if(skill > 9) // normal players only do this for the target they are tracking
{
entity rocket = it;
- FOREACH_ENTITY_FLOAT(bot_attack, true,
+ IL_EACH(g_bot_targets, it.bot_attack,
{
if((v_forward * normalize(rocket.origin - it.origin) < 0.1)
&& desirabledamage > 0.1 * coredamage
if(PHYS_INPUT_BUTTON_ATCK2(actor)) PHYS_INPUT_BUTTON_ATCK(actor) = false;
}
}
-#endif
+
METHOD(Devastator, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
if(WEP_CVAR(devastator, reload_ammo) && actor.clip_load < WEP_CVAR(devastator, ammo)) { // forced reload
if(fire & 2)
if(PS(actor).m_switchweapon == WEP_DEVASTATOR)
{
- entity rock;
bool rockfound = false;
- for(rock = NULL; (rock = find(rock, classname, "rocket")); ) if(rock.realowner == actor)
+ IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket",
{
- if(!rock.rl_detonate_later)
+ if(!it.rl_detonate_later)
{
- rock.rl_detonate_later = true;
+ it.rl_detonate_later = true;
rockfound = true;
}
- }
+ });
if(rockfound)
sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM);
}
setsize(proj, '0 0 -3', '0 0 -3');
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.missile_flags = MIF_SPLASH;
CSQCProjectile(proj, true, PROJECTILE_ELECTRO_BEAM, true);
newproj.nextthink = this.nextthink;
newproj.use = this.use;
newproj.flags = this.flags;
+ IL_PUSH(g_projectiles, newproj);
+ IL_PUSH(g_bot_dodge, newproj);
delete(this);
proj.event_damage = W_Electro_Orb_Damage;
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.damagedbycontents = (WEP_CVAR_SEC(electro, damagedbycontents));
proj.bouncefactor = WEP_CVAR_SEC(electro, bouncefactor);
setsize(proj, '-16 -16 -16', '16 16 16');
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.missile_flags = MIF_SPLASH | MIF_PROXY;
CSQCProjectile(proj, true, PROJECTILE_FIREBALL, true);
proj.angles = vectoangles(proj.velocity);
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
CSQCProjectile(proj, true, PROJECTILE_FIREMINE, true);
missile.angles = vectoangles(missile.velocity);
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
missile.missile_flags = MIF_SPLASH;
CSQCProjectile(missile, true, PROJECTILE_HAGAR, true);
missile.angles = vectoangles(missile.velocity);
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
missile.missile_flags = MIF_SPLASH;
CSQCProjectile(missile, true, PROJECTILE_HAGAR_BOUNCING, true);
missile.angles = vectoangles(missile.velocity);
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
CSQCProjectile(missile, true, PROJECTILE_HAGAR, true);
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
missile.projectiledeathtype = WEP_HLAC.m_id;
CSQCProjectile(missile, true, PROJECTILE_HLAC, true);
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
missile.missile_flags = MIF_SPLASH;
missile.projectiledeathtype = WEP_HLAC.m_id | HITTYPE_SECONDARY;
gren.angles = '0 0 0';
gren.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, gren);
+ IL_PUSH(g_bot_dodge, gren);
CSQCProjectile(gren, true, PROJECTILE_HOOKBOMB, true);
newmine.cnt = this.cnt;
newmine.flags = this.flags;
IL_PUSH(g_projectiles, newmine);
+ IL_PUSH(g_bot_dodge, newmine);
delete(this);
mine.cnt = (WEP_CVAR(minelayer, lifetime) - WEP_CVAR(minelayer, lifetime_countdown));
mine.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, mine);
+ IL_PUSH(g_bot_dodge, mine);
mine.missile_flags = MIF_SPLASH | MIF_ARC | MIF_PROXY;
if(mine.cnt > 0) { mine.cnt += time; }
IL_EACH(g_mines, it.realowner == actor,
{
entity mine = it;
- FOREACH_ENTITY_FLOAT(bot_attack, true,
+ IL_EACH(g_bot_targets, it.bot_attack,
{
float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - mine.origin);
d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
if(skill > 9) // normal players only do this for the target they are tracking
{
entity mine = it;
- FOREACH_ENTITY_FLOAT(bot_attack, true,
+ IL_EACH(g_bot_targets, it.bot_attack,
{
if((v_forward * normalize(mine.origin - it.origin) < 0.1)
&& desirabledamage > 0.1 * coredamage
gren.angles = vectoangles(gren.velocity);
gren.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, gren);
+ IL_PUSH(g_bot_dodge, gren);
if(WEP_CVAR_PRI(mortar, type) == 0 || WEP_CVAR_PRI(mortar, type) == 2)
CSQCProjectile(gren, true, PROJECTILE_GRENADE, true);
gren.angles = vectoangles(gren.velocity);
gren.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, gren);
+ IL_PUSH(g_bot_dodge, gren);
if(WEP_CVAR_SEC(mortar, type) == 0 || WEP_CVAR_SEC(mortar, type) == 2)
CSQCProjectile(gren, true, PROJECTILE_GRENADE, true);
if(WEP_CVAR_SEC(mortar, remote_detonateprimary))
{
bool nadefound = false;
- entity nade;
- for(nade = NULL; (nade = find(nade, classname, "grenade")); ) if(nade.realowner == actor)
+ IL_EACH(g_projectiles, it.realowner == actor && it.classname == "grenade",
{
- if(!nade.gl_detonate_later)
+ if(!it.gl_detonate_later)
{
- nade.gl_detonate_later = true;
+ it.gl_detonate_later = true;
nadefound = true;
}
- }
+ });
if(nadefound)
sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM);
}
if(move_out_of_solid(this))
{
this.flags = FL_ITEM;
+ IL_PUSH(g_items, this);
this.velocity = trigger_push_calculatevelocity(this.origin, this.realowner, 128);
tracetoss(this, this);
if(vdist(trace_endpos - this.realowner.origin, <, 128))
gren.angles = vectoangles(gren.velocity);
gren.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, gren);
+ IL_PUSH(g_bot_dodge, gren);
gren.portal_id = time;
actor.porto_current = gren;
set_movetype(missile, MOVETYPE_FLYMISSILE);
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
missile.missile_flags = MIF_SPLASH | MIF_GUIDED_TAG;
W_SetupProjVelocity_UP_PRE(missile, seeker, missile_);
missile.projectiledeathtype = WEP_SEEKER.m_id | HITTYPE_SECONDARY;
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
missile.missile_flags = MIF_SPLASH;
// csqc projectiles
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
//missile.missile_flags = MIF_..?;
set_movetype(missile, MOVETYPE_FLY);
setsize(proj, '0 0 -3', '0 0 -3');
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.missile_flags = MIF_SPLASH;
CSQCProjectile(proj, true, PROJECTILE_ROCKETMINSTA_LASER, true);
setsize(proj, '0 0 -3', '0 0 -3');
proj.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, proj);
+ IL_PUSH(g_bot_dodge, proj);
proj.missile_flags = MIF_SPLASH;
CSQCProjectile(proj, true, PROJECTILE_ROCKETMINSTA_LASER, true);
.int Version; // deprecated, use SendFlags
.int SendFlags;
+ IntrusiveList g_uncustomizables;
+ STATIC_INIT(g_uncustomizables) { g_uncustomizables = IL_NEW(); }
+
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
{
if (e.classname == "") e.classname = "net_linked";
setcefc(e, customizer);
e.uncustomizeentityforclient = uncustomizer;
e.uncustomizeentityforclient_set = !!uncustomizer;
+ if(uncustomizer)
+ IL_PUSH(g_uncustomizables, e);
}
void UncustomizeEntitiesRun()
{
- FOREACH_ENTITY_FLOAT(uncustomizeentityforclient_set, true, it.uncustomizeentityforclient(it));
+ IL_EACH(g_uncustomizables, it.uncustomizeentityforclient_set, it.uncustomizeentityforclient(it));
}
STRING_ITERATOR(g_buf, string_null, 0);
KEYBIND_DEF("+fire" , _("primary fire"));
KEYBIND_DEF("+fire2" , _("secondary fire"));
KEYBIND_DEF("" , "");
- KEYBIND_DEF("" , _("Weapon switching"));
+ KEYBIND_DEF("" , _("Weapons"));
KEYBIND_DEF("weapprev" , CTX(_("WEAPON^previous")));
KEYBIND_DEF("weapnext" , CTX(_("WEAPON^next")));
KEYBIND_DEF("weaplast" , CTX(_("WEAPON^previously used")));
KEYBIND_DEF("weapbest" , CTX(_("WEAPON^best")));
KEYBIND_DEF("reload" , _("reload"));
+ KEYBIND_DEF("dropweapon" , _("drop weapon / throw nade"));
int i;
for(int imp = 1; imp <= 9; ++imp)
{
string w_list = "";
- ADD_TO_W_LIST(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && !(it.spawnflags & WEP_TYPE_OTHER) && !(it.spawnflags & WEP_FLAG_HIDDEN) && !(it.spawnflags & WEP_FLAG_SUPERWEAPON));
- ADD_TO_W_LIST((it.spawnflags & WEP_FLAG_SUPERWEAPON) && !(it.spawnflags & WEP_TYPE_OTHER) && !(it.spawnflags & WEP_FLAG_HIDDEN));
- ADD_TO_W_LIST((it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && !(it.spawnflags & WEP_TYPE_OTHER) && !(it.spawnflags & WEP_FLAG_HIDDEN));
+ ADD_TO_W_LIST(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && !(it.spawnflags & WEP_FLAG_HIDDEN) && !(it.spawnflags & WEP_FLAG_SUPERWEAPON));
+ ADD_TO_W_LIST((it.spawnflags & WEP_FLAG_SUPERWEAPON) && !(it.spawnflags & WEP_FLAG_HIDDEN));
+ ADD_TO_W_LIST((it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && !(it.spawnflags & WEP_FLAG_HIDDEN));
if(w_list)
KEYBIND_DEF(strcat("weapon_group_", itos(imp)), substring(w_list, 0, -4));
if(imp == 0)
KEYBIND_DEF("+showscores" , _("show scores"));
KEYBIND_DEF("screenshot" , _("screen shot"));
KEYBIND_DEF("+hud_panel_radar_maximized" , _("maximize radar"));
+ KEYBIND_DEF("toggle chase_active" , _("3rd person view"));
+ KEYBIND_DEF("spec" , _("enter spectator mode"));
KEYBIND_DEF("" , "");
KEYBIND_DEF("" , _("Communicate"));
KEYBIND_DEF("messagemode" , _("public chat"));
KEYBIND_DEF("messagemode2" , _("team chat"));
KEYBIND_DEF("team_auto" , _("auto-join team"));
KEYBIND_DEF("menu_showteamselect" , _("team menu"));
- KEYBIND_DEF("menu_showsandboxtools" , _("sandbox menu"));
- KEYBIND_DEF("spec" , _("enter spectator mode"));
- KEYBIND_DEF("dropweapon" , _("drop weapon"));
KEYBIND_DEF("+use" , _("drop key / drop flag"));
+ KEYBIND_DEF("" , "");
+ KEYBIND_DEF("" , _("Misc"));
+ KEYBIND_DEF("quickmenu" , _("quick menu"));
+ KEYBIND_DEF("menu_showsandboxtools" , _("sandbox menu"));
KEYBIND_DEF("+button8" , _("drag object"));
- KEYBIND_DEF("toggle chase_active" , _("3rd person view"));
KEYBIND_DEF("" , "");
KEYBIND_DEF("" , _("User defined"));
fn = search_getfilename(glob, i);
if(!get_model_parameters(fn, -1))
continue;
+ if(get_model_parameters_hidden)
+ continue;
bufstr_add(sortbuf, sprintf("%-128s%s", get_model_parameters_name, fn), 1);
}
search_end(glob);
fn = substring(bufstr_get(sortbuf, i), 128, -1);
if(!get_model_parameters(fn, -1))
error("But it JUST worked!");
+ if(get_model_parameters_hidden)
+ continue;
bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_TITLE, get_model_parameters_name);
bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_IMAGE, strcat("/", substring(get_model_datafilename(get_model_parameters_modelname, get_model_parameters_modelskin, "tga"), 0, -5)));
bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_MODEL, get_model_parameters_modelname);
bool autocvar_g_monsters_respawn;
float autocvar_g_monsters_armor_blockpercent;
float autocvar_g_monsters_healthbars;
-float autocvar_g_monsters_lineofsight;
+bool autocvar_g_monsters_lineofsight = true;
+//bool autocvar_g_monsters_ignoretraces = true;
#define autocvar_g_bloodloss cvar("g_bloodloss")
bool autocvar_g_nades;
bool autocvar_g_nades_override_dropweapon = true;
entity find_bot_by_name(string name);
entity find_bot_by_number(float number);
-void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius);
void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius);
void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius);
int bestcount = 0;
int bcount = 0;
- FOREACH_ENTITY_FLOAT(isbot, true,
+ FOREACH_CLIENT(it.isbot,
{
++bcount;
entity best = NULL;
int bcount = 0;
- FOREACH_ENTITY_FLOAT(isbot, true,
+ FOREACH_CLIENT(it.isbot,
{
++bcount;
#include <common/state.qh>
#include <common/items/_mod.qh>
+#include <common/triggers/teleporters.qh>
#include <common/triggers/trigger/jumppads.qh>
#include <lib/warpzone/common.qh>
if (((dodge * v_up) < 0) && random()*frametime >= 0.5*bound(0,(10-skill-this.bot_dodgeskill)*0.1,1)) this.havocbot_ducktime=time+0.3/bound(0.1,skill+this.bot_dodgeskill,10);
}
+entity havocbot_gettarget(entity this, bool secondary)
+{
+ entity best = NULL;
+ vector eye = CENTER_OR_VIEWOFS(this);
+ IL_EACH(g_bot_targets, boolean((secondary) ? it.classname == "misc_breakablemodel" : it.classname != "misc_breakablemodel"),
+ {
+ vector v = CENTER_OR_VIEWOFS(it);
+ if(vdist(v - eye, <, autocvar_bot_ai_enemydetectionradius))
+ if(!best || vlen2(CENTER_OR_VIEWOFS(best) - eye) > vlen2(v - eye))
+ if(bot_shouldattack(this, it))
+ {
+ traceline(eye, v, true, this);
+ if (trace_ent == it || trace_fraction >= 1)
+ best = it;
+ }
+ });
+
+ return best;
+}
+
void havocbot_chooseenemy(entity this)
{
entity head, best, head2;
this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_LINKING;
// if pos is inside a teleport, then let's mark it as teleport waypoint
- FOREACH_ENTITY_CLASS("trigger_teleport", WarpZoneLib_BoxTouchesBrush(pos, pos, it, NULL),
+ IL_EACH(g_teleporters, WarpZoneLib_BoxTouchesBrush(pos, pos, it, NULL),
{
wp.wpflags |= WAYPOINTFLAG_TELEPORT;
this.lastteleporttime = 0;
vector o;
ratingscale = ratingscale * 0.0001; // items are rated around 10000 already
- FOREACH_ENTITY_FLOAT(bot_pickup, true,
+ IL_EACH(g_items, it.bot_pickup,
{
o = (it.absmin + it.absmax) * 0.5;
friend_distance = 10000; enemy_distance = 10000;
});
}
-void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius)
-{
- FOREACH_ENTITY_CLASS("dom_controlpoint", vdist((((it.absmin + it.absmax) * 0.5) - org), <, sradius),
- {
- if(it.cnt > -1) // this is just being fought
- navigation_routerating(this, it, ratingscale, 5000);
- else if(it.goalentity.cnt == 0) // unclaimed
- navigation_routerating(this, it, ratingscale * 0.5, 5000);
- else if(it.goalentity.team != this.team) // other team's point
- navigation_routerating(this, it, ratingscale * 0.2, 5000);
- });
-}
-
void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius)
{
if (autocvar_bot_nofire)
#pragma once
-void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius);
danger = 0;
m1 = it.mins;
m2 = it.maxs;
- FOREACH_ENTITY_FLOAT(bot_dodge, true,
+ IL_EACH(g_bot_dodge, it.bot_dodge,
{
v = it.origin;
v.x = bound(m1_x, v.x, m2_x);
// Returns first bot with matching name
entity find_bot_by_name(string name)
{
- entity bot;
-
- bot = findchainflags(flags, FL_CLIENT);
- while (bot)
+ FOREACH_CLIENT(IS_BOT_CLIENT(it) && it.netname == name,
{
- if(IS_BOT_CLIENT(bot))
- if(bot.netname==name)
- return bot;
-
- bot = bot.chain;
- }
+ return it;
+ });
return NULL;
}
w.solid = SOLID_TRIGGER;
setorigin(w, (m1 + m2) * 0.5);
setsize(w, m1 - w.origin, m2 - w.origin);
- if (vlen(w.size) > 0)
+ if (w.size)
w.wpisbox = true;
if(!w.wpisbox)
}
else
wp.model = "";
- wp.wpisbox = vlen(wp.size) > 0;
+ wp.wpisbox = vdist(wp.size, >, 0);
wp.enemy = NULL;
if (!(wp.wpflags & WAYPOINTFLAG_PERSONAL))
wp.owner = NULL;
void botframe_deleteuselesswaypoints()
{
- FOREACH_ENTITY_FLOAT(bot_pickup, true,
+ IL_EACH(g_items, it.bot_pickup,
{
// NOTE: this protects waypoints if they're the ONLY nearest
// waypoint. That's the intention.
entity find_bot_by_name(string name) { return NULL; }
entity find_bot_by_number(float number) { return NULL; }
-void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius) { }
void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius) { }
void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius) { }
#include <common/physics/player.qh>
-#include "../common/monsters/all.qh"
+#include "../common/monsters/_mod.qh"
#include <common/weapons/_all.qh>
break;
}
- if((draggee.flags & FL_ITEM) && (vlen(draggee.velocity) < 32))
+ if((draggee.flags & FL_ITEM) && (vdist(draggee.velocity, <, 32)))
{
draggee.velocity = '0 0 0';
SET_ONGROUND(draggee); // floating items are FUN
#include <common/effects/qc/globalsound.qh>
+#include "../common/triggers/func/conveyor.qh"
#include "../common/triggers/teleporters.qh"
#include "../common/vehicles/all.qh"
accuracy_resend(this);
this.spectatortime = time;
+ if(this.bot_attack)
+ IL_REMOVE(g_bot_targets, this);
this.bot_attack = false;
this.hud = HUD_NORMAL;
TRANSMUTE(Observer, this);
this.oldorigin = this.origin;
this.prevorigin = this.origin;
this.lastteleporttime = time; // prevent insane speeds due to changing origin
+ if(this.conveyor)
+ IL_REMOVE(g_conveyed, this);
this.conveyor = NULL; // prevent conveyors at the previous location from moving a freshly spawned player
this.hud = HUD_NORMAL;
this.event_damage = PlayerDamage;
+ if(!this.bot_attack)
+ IL_PUSH(g_bot_targets, this);
this.bot_attack = true;
this.monster_attack = true;
this.killindicator.count = bound(0, ceil(killtime), 10);
//sprint(this, strcat("^1You'll be dead in ", ftos(this.killindicator.cnt), " seconds\n"));
- FOREACH_ENTITY_ENT(enemy, this,
+ IL_EACH(g_clones, it.enemy == this && !(it.effects & CSQCMODEL_EF_RESPAWNGHOST),
{
- if(it.classname != "body")
- continue;
it.killindicator = spawn();
it.killindicator.owner = it;
it.killindicator.scale = 0.5;
if (IS_REAL_CLIENT(this))
sv_notice_join(this);
- FOREACH_ENTITY_FLOAT(init_for_player_needed, true, {
+ IL_EACH(g_initforplayer, it.init_for_player, {
it.init_for_player(it, this);
});
void ClientState_attach(entity this);
+IntrusiveList g_players;
+STATIC_INIT(g_players) { g_players = IL_NEW(); }
+
CLASS(Client, Object)
/** Client name */
ATTRIB(Client, netname, string, this.netname);
CLASS(Player, Client)
INIT(Player) {
this.classname = STR_PLAYER;
+ IL_PUSH(g_players, this);
+ }
+ DESTRUCTOR(Player) {
+ IL_REMOVE(g_players, this);
}
- DESTRUCTOR(Player) { }
ENDCLASS(Player)
METHOD(Client, m_unwind, bool(Client this))
#include <common/minigames/sv_minigames.qh>
-#include <common/monsters/all.qc>
-#include <common/monsters/spawn.qh>
+#include <common/monsters/_mod.qh>
+#include <common/monsters/sv_spawn.qh>
#include <common/monsters/sv_monsters.qh>
#include <lib/warpzone/common.qh>
#include "../scores.qh"
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
#include <common/notifications/all.qh>
#include <lib/warpzone/common.qh>
}
#include "vote.qh"
-#include <common/monsters/spawn.qh>
+#include <common/monsters/sv_spawn.qh>
#include <common/command/_mod.qh>
#include <common/mapinfo.qh>
#include <common/util.qh>
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
// =========================================================
// Reply messages for common commands, re-worked by Samual
float n, m;
n = m = 0;
- while (vlen(c - b) > 1)
+ while (vdist(c - b, >, 1))
{
++m;
.string cvar_cl_physics;
-.bool init_for_player_needed;
.void(entity this, entity player) init_for_player;
IntrusiveList g_monsters;
IntrusiveList g_projectiles;
STATIC_INIT(g_projectiles) { g_projectiles = IL_NEW(); }
+
+IntrusiveList g_items;
+STATIC_INIT(g_items) { g_items = IL_NEW(); }
+
+IntrusiveList g_initforplayer;
+STATIC_INIT(g_initforplayer) { g_initforplayer = IL_NEW(); }
+
+IntrusiveList g_clones;
+STATIC_INIT(g_clones) { g_clones = IL_NEW(); }
+
+IntrusiveList g_assault_destructibles;
+STATIC_INIT(g_assault_destructibles) { g_assault_destructibles = IL_NEW(); }
+
+IntrusiveList g_assault_objectivedecreasers;
+STATIC_INIT(g_assault_objectivedecreasers) { g_assault_objectivedecreasers = IL_NEW(); }
+
+IntrusiveList g_assault_objectives;
+STATIC_INIT(g_assault_objectives) { g_assault_objectives = IL_NEW(); }
+
+IntrusiveList g_spawnpoints;
+STATIC_INIT(g_spawnpoints) { g_spawnpoints = IL_NEW(); }
+
+IntrusiveList g_bot_targets;
+STATIC_INIT(g_bot_targets) { g_bot_targets = IL_NEW(); }
+
+IntrusiveList g_bot_dodge;
+STATIC_INIT(g_bot_dodge) { g_bot_dodge = IL_NEW(); }
targ.revive_progress = ((frozen_type == 3) ? 1 : 0);
targ.health = ((frozen_type == 3) ? targ_maxhealth : 1);
targ.revive_speed = freeze_time;
+ if(targ.bot_attack)
+ IL_REMOVE(g_bot_targets, targ);
targ.bot_attack = false;
entity ice = new(ice);
STAT(FROZEN, targ) = 0;
targ.revive_progress = 0;
targ.revival_time = time;
+ if(!targ.bot_attack)
+ IL_PUSH(g_bot_targets, targ);
targ.bot_attack = true;
WaypointSprite_Kill(targ.waypointsprite_attached);
// apply push
if (targ.damageforcescale)
- if (vlen(force))
+ if (force)
if (!IS_PLAYER(targ) || time >= targ.spawnshieldtime || targ == attacker)
{
vector farce = damage_explosion_calcpush(targ.damageforcescale * force, targ.velocity, autocvar_g_balance_damagepush_speedfactor);
UpdateCSQCProjectile(targ);
}
// apply damage
- if (damage != 0 || (targ.damageforcescale && vlen(force)))
+ if (damage != 0 || (targ.damageforcescale && force))
if (targ.event_damage)
targ.event_damage (targ, inflictor, attacker, damage, deathtype, hitloc, force);
// print(" finaldmg ", ftos(finaldmg), " force ", vtos(force));
// print(" (", ftos(a), ")\n");
//}
- if(finaldmg || vlen(force))
+ if(finaldmg || force)
{
if(targ.iscreature)
{
missile.classname = "grapplinghook";
missile.flags = FL_PROJECTILE;
IL_PUSH(g_projectiles, missile);
+ IL_PUSH(g_bot_dodge, missile);
set_movetype(missile, ((autocvar_g_balance_grapplehook_gravity) ? MOVETYPE_TOSS : MOVETYPE_FLY));
PROJECTILE_MAKETRIGGER(missile);
#include "../common/constants.qh"
#include "../common/deathtypes/all.qh"
#include "../common/mapinfo.qh"
-#include "../common/monsters/all.qh"
+#include "../common/monsters/_mod.qh"
#include "../common/monsters/sv_monsters.qh"
#include "../common/vehicles/all.qh"
#include "../common/notifications/all.qh"
static_init_late();
static_init_precache();
+ IL_PUSH(g_spawnpoints, e); // just incase
+
MapInfo_Enumerate();
MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
}
local float cyc;
// look for info_intermission first
- spot = find (NULL, classname, "info_intermission");
+ spot = find(NULL, classname, "info_intermission");
if (spot)
{ // pick a random one
cyc = random() * 4;
while (cyc > 1)
{
- spot = find (spot, classname, "info_intermission");
+ spot = find(spot, classname, "info_intermission");
if (!spot)
- spot = find (spot, classname, "info_intermission");
+ spot = find(spot, classname, "info_intermission");
cyc = cyc - 1;
}
return spot;
}
// then look for the start position
- spot = find (NULL, classname, "info_player_start");
+ spot = find(NULL, classname, "info_player_start");
if (spot)
return spot;
// testinfo_player_start is only found in regioned levels
- spot = find (NULL, classname, "testplayerstart");
+ spot = find(NULL, classname, "testplayerstart");
if (spot)
return spot;
// then look for the start position
- spot = find (NULL, classname, "info_player_deathmatch");
+ spot = find(NULL, classname, "info_player_deathmatch");
if (spot)
return spot;
}
));
- FOREACH_ENTITY_CLASS("info_player_deathmatch", true, LAMBDA(
+ IL_EACH(g_spawnpoints, true,
+ {
switch(it.team)
{
case NUM_TEAM_1: team1_score = 1; break;
case NUM_TEAM_3: team3_score = 1; break;
case NUM_TEAM_4: team4_score = 1; break;
}
- ));
+ });
ClearWinners();
if(team1_score + team2_score + team3_score + team4_score == 0)
if (m) LOG_INFOF("%d waypoints have been marked total\n", m);
j = 0;
- FOREACH_ENTITY_CLASS("info_player_deathmatch", true,
+ IL_EACH(g_spawnpoints, true,
{
vector org = it.origin;
tracebox(it.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - '0 0 512', MOVE_NOMONSTERS, NULL);
if (j) LOG_INFOF("%d spawnpoints have no nearest waypoint (marked by player model)\n", j);
j = 0;
- FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
+ IL_EACH(g_items, true,
{
it.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
it.colormod = '0.5 0.5 0.5';
});
- FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
+ IL_EACH(g_items, true,
{
if (navigation_findnearestwaypoint(it, false)) continue;
LOG_INFO("item without waypoint: ", etos(it), " ", vtos(it.origin), "\n");
if (j) LOG_INFOF("%d items have no nearest waypoint and cannot be walked away from (marked with red light)\n", j);
j = 0;
- FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
+ IL_EACH(g_items, true,
{
if (navigation_findnearestwaypoint(it, true)) continue;
LOG_INFO("item without waypoint: ", etos(it), " ", vtos(it.origin), "\n");
#include "item_key.qh"
#include "../common/triggers/subs.qh"
-#include "../common/monsters/all.qh"
+#include "../common/monsters/_mod.qh"
#include "../common/notifications/all.qh"
#include "../common/util.qh"
#include "../lib/warpzone/util_server.qh"
{
float m, i;
vector start, org, delta, end, enddown, mstart;
- entity sp;
m = e.dphitcontentsmask;
e.dphitcontentsmask = goodcontents | badcontents;
continue;
// rule 4: we must "see" some spawnpoint or item
- for(sp = NULL; (sp = find(sp, classname, "info_player_deathmatch")); )
- if(checkpvs(mstart, sp))
- if((traceline(mstart, sp.origin, MOVE_NORMAL, e), trace_fraction) >= 1)
- break;
+ entity sp = NULL;
+ IL_EACH(g_spawnpoints, checkpvs(mstart, it),
+ {
+ if((traceline(mstart, it.origin, MOVE_NORMAL, e), trace_fraction) >= 1)
+ {
+ sp = it;
+ break;
+ }
+ });
if(!sp)
{
- for(sp = NULL; (sp = findflags(sp, flags, FL_ITEM)); )
- if(checkpvs(mstart, sp))
- if((traceline(mstart, sp.origin + (sp.mins + sp.maxs) * 0.5, MOVE_NORMAL, e), trace_fraction) >= 1)
- break;
+ IL_EACH(g_items, checkpvs(mstart, it),
+ {
+ if((traceline(mstart, it.origin + (it.mins + it.maxs) * 0.5, MOVE_NORMAL, e), trace_fraction) >= 1)
+ {
+ sp = it;
+ break;
+ }
+ });
+
if(!sp)
continue;
}
#include <common/command/_mod.qh>
#include <common/net_notice.qh>
#include <common/animdecide.qh>
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
#include <common/monsters/sv_monsters.qh>
-#include <common/monsters/spawn.qh>
+#include <common/monsters/sv_spawn.qh>
#include <common/weapons/config.qh>
#include <common/weapons/_all.qh>
#include <server/weapons/accuracy.qh>
#include <server/command/_mod.qh>
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
#include <server/weapons/tracing.qh>
#include <server/weapons/weaponsystem.qh>
#include <common/stats.qh>
#include <common/teams.qh>
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
#include <lib/warpzone/anglestransform.qh>
#include <lib/warpzone/server.qh>
//print("^2Activated objective ", this.targetname, "=", etos(this), "\n");
//print("Activator is ", actor.classname, "\n");
- for (entity e = NULL; (e = find(e, target, this.targetname)); )
+ IL_EACH(g_assault_objectivedecreasers, it.target == this.targetname,
{
- if (e.classname == "target_objective_decrease")
- {
- target_objective_decrease_activate(e);
- }
- }
+ target_objective_decrease_activate(it);
+ });
}
vector target_objective_spawn_evalfunc(entity this, entity player, entity spot, vector current)
void assault_setenemytoobjective(entity this)
{
- FOREACH_ENTITY_STRING(targetname, this.target,
+ IL_EACH(g_assault_objectives, it.targetname == this.target,
{
- if(it.classname == "target_objective")
- {
- if(this.enemy == NULL)
- this.enemy = it;
- else
- objerror(this, "more than one objective as target - fix the map!");
- break;
- }
+ if(this.enemy == NULL)
+ this.enemy = it;
+ else
+ objerror(this, "more than one objective as target - fix the map!");
+ break;
});
if(this.enemy == NULL)
SUB_UseTargets(this, this, trigger);
//(Re)spawn all turrets
- FOREACH_ENTITY_CLASS("turret_main", true, LAMBDA(
+ IL_EACH(g_turrets, true,
+ {
// Swap turret teams
if(it.team == NUM_TEAM_1)
it.team = NUM_TEAM_2;
// Doubles as teamchange
turret_respawn(it);
- ));
+ });
}
void assault_roundstart_use_this(entity this)
{
if (!g_assault) { delete(this); return; }
this.classname = "target_objective";
+ IL_PUSH(g_assault_objectives, this);
this.use = assault_objective_use;
this.reset = assault_objective_reset;
this.reset(this);
if (!g_assault) { delete(this); return; }
this.classname = "target_objective_decrease";
+ IL_PUSH(g_assault_objectivedecreasers, this);
if(!this.dmg)
this.dmg = 101;
this.spawnflags = 3;
this.classname = "func_assault_destructible";
+ IL_PUSH(g_assault_destructibles, this);
if(assault_attacker_team == NUM_TEAM_1)
this.team = NUM_TEAM_2;
// legacy bot code
void havocbot_goalrating_ast_targets(entity this, float ratingscale)
{
- FOREACH_ENTITY_CLASS("func_assault_destructible", it.bot_attack,
+ IL_EACH(g_assault_destructibles, it.bot_attack,
{
if (it.target == "")
continue;
bool found = false;
- FOREACH_ENTITY_STRING(targetname, it.target,
+ entity destr = it;
+ IL_EACH(g_assault_objectivedecreasers, it.targetname == destr.target,
{
- if(it.classname != "target_objective_decrease")
- continue;
-
if(it.enemy.health > 0 && it.enemy.health < ASSAULT_VALUE_INACTIVE)
{
found = true;
flag.classname = "item_flag_team";
flag.target = "###item###"; // wut?
flag.flags = FL_ITEM | FL_NOTARGET;
+ IL_PUSH(g_items, flag);
flag.solid = SOLID_TRIGGER;
flag.takedamage = DAMAGE_NO;
flag.damageforcescale = autocvar_g_ctf_flag_damageforcescale;
void havocbot_goalrating_ctf_carrieritems(entity this, float ratingscale, vector org, float sradius)
{
- FOREACH_ENTITY_FLOAT(bot_pickup, true,
+ IL_EACH(g_items, it.bot_pickup,
{
// gather health and armor only
if (it.solid)
this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
navigation_goalrating_start(this);
- FOREACH_ENTITY_CLASS("trigger_race_checkpoint", true,
+ IL_EACH(g_racecheckpoints, true,
{
if(it.cnt == this.race_checkpoint)
navigation_routerating(this, it, 1000000, 5000);
WaypointSprite_UpdateSprites(this.sprite, msg, WP_Null, WP_Null);
total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0;
- FOREACH_ENTITY_CLASS("dom_controlpoint", true, LAMBDA(
+ IL_EACH(g_dompoints, true,
+ {
if (autocvar_g_domination_point_amt)
points = autocvar_g_domination_point_amt;
else
case NUM_TEAM_4: pps_pink += points/wait_time; break;
}
total_pps += points/wait_time;
- ));
+ });
WaypointSprite_UpdateTeamRadar(this.sprite, RADARICON_DOMPOINT, colormapPaletteColor(this.goalentity.team - 1, 0));
WaypointSprite_Ping(this.sprite);
this.nextthink = time;
settouch(this, dompointtouch);
this.solid = SOLID_TRIGGER;
+ if(!this.flags & FL_ITEM)
+ IL_PUSH(g_items, this);
this.flags = FL_ITEM;
setsize(this, '-32 -32 -32', '32 32 32');
setorigin(this, this.origin + '0 0 20');
void Domination_count_controlpoints()
{
total_controlpoints = redowned = blueowned = yellowowned = pinkowned = 0;
- FOREACH_ENTITY_CLASS("dom_controlpoint", true,
+ IL_EACH(g_dompoints, true,
{
++total_controlpoints;
redowned += (it.goalentity.team == NUM_TEAM_1);
}
//go to best items, or control points you don't own
+void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius)
+{
+ IL_EACH(g_dompoints, vdist((((it.absmin + it.absmax) * 0.5) - org), <, sradius),
+ {
+ if(it.cnt > -1) // this is just being fought
+ navigation_routerating(this, it, ratingscale, 5000);
+ else if(it.goalentity.cnt == 0) // unclaimed
+ navigation_routerating(this, it, ratingscale * 0.5, 5000);
+ else if(it.goalentity.team != this.team) // other team's point
+ navigation_routerating(this, it, ratingscale * 0.2, 5000);
+ });
+}
+
void havocbot_role_dom(entity this)
{
if(IS_DEAD(this))
this.effects = this.effects | EF_LOWPRECISION;
if (autocvar_g_domination_point_fullbright)
this.effects |= EF_FULLBRIGHT;
+
+ IL_PUSH(g_dompoints, this);
}
/*QUAKED spawnfunc_dom_team (0 .5 .8) (-32 -32 -24) (32 32 32)
float domination_teams;
void AnimateDomPoint(entity this);
+
+IntrusiveList g_dompoints;
+STATIC_INIT(g_dompoints) { g_dompoints = IL_NEW(); }
{
entity frag_attacker = M_ARGV(1, entity);
entity frag_target = M_ARGV(2, entity);
- float frag_deathtype = M_ARGV(2, float);
+ float frag_deathtype = M_ARGV(3, float);
if(round_handler_IsActive())
if(round_handler_CountdownRunning())
#include "gamemode_invasion.qh"
-#include <common/monsters/spawn.qh>
+#include <common/monsters/sv_spawn.qh>
#include <common/monsters/sv_monsters.qh>
#include <server/teamplay.qh>
+IntrusiveList g_invasion_spawns;
+STATIC_INIT(g_invasion_spawns) { g_invasion_spawns = IL_NEW(); }
float autocvar_g_invasion_round_timelimit;
float autocvar_g_invasion_spawnpoint_spawn_delay;
if(!g_invasion) { delete(this); return; }
this.classname = "invasion_spawnpoint";
+ IL_PUSH(g_invasion_spawns, this);
if(autocvar_g_invasion_zombies_only) // precache only if it hasn't been already
if(this.monsterid) {
}
}
-float invasion_PickMonster(float supermonster_count)
+int invasion_PickMonster(int supermonster_count)
{
if(autocvar_g_invasion_zombies_only)
return MON_ZOMBIE.monsterid;
- float i;
- entity mon;
-
RandomSelection_Init();
- for(i = MON_FIRST; i <= MON_LAST; ++i)
+ FOREACH(Monsters, it != MON_Null,
{
- mon = get_monsterinfo(i);
- if((mon.spawnflags & MONSTER_TYPE_FLY) || (mon.spawnflags & MONSTER_TYPE_SWIM) || ((mon.spawnflags & MON_FLAG_SUPERMONSTER) && supermonster_count >= 1))
- continue; // flying/swimming monsters not yet supported
-
- RandomSelection_Add(NULL, i, string_null, 1, 1);
- }
+ if((it.spawnflags & MONSTER_TYPE_FLY) || (it.spawnflags & MONSTER_TYPE_SWIM) || (it.spawnflags & MONSTER_SIZE_QUAKE) || ((it.spawnflags & MON_FLAG_SUPERMONSTER) && supermonster_count >= 1))
+ continue;
+ RandomSelection_Add(NULL, it.monsterid, string_null, 1, 1);
+ });
return RandomSelection_chosen_float;
}
{
RandomSelection_Init();
- FOREACH_ENTITY_CLASS("invasion_spawnpoint", true,
+ IL_EACH(g_invasion_spawns, true,
{
RandomSelection_Add(it, 0, string_null, 1, ((time >= it.spawnshieldtime) ? 0.2 : 1)); // give recently used spawnpoints a very low rating
it.spawnshieldtime = time + autocvar_g_invasion_spawnpoint_spawn_delay;
monster.spawnflags |= MONSTERFLAG_MINIBOSS; // last round spawns minibosses
}
-void invasion_SpawnMonsters(float supermonster_count)
+void invasion_SpawnMonsters(int supermonster_count)
{
- float chosen_monster = invasion_PickMonster(supermonster_count);
+ int chosen_monster = invasion_PickMonster(supermonster_count);
invasion_SpawnChosenMonster(chosen_monster);
}
-float Invasion_CheckWinner()
+bool Invasion_CheckWinner()
{
if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
{
{
entity player = M_ARGV(0, entity);
+ if(player.bot_attack)
+ IL_REMOVE(g_bot_targets, player);
player.bot_attack = false;
}
e.glow_color = autocvar_g_keepawayball_trail_color;
e.glow_trail = true;
e.flags = FL_ITEM;
+ IL_PUSH(g_items, e);
e.pushable = true;
e.reset = ka_Reset;
settouch(e, ka_TouchEvent);
key.angles_y -= key.owner.angles.y;
#endif
key.flags = 0;
+ IL_REMOVE(g_items, key);
key.solid = SOLID_NOT;
set_movetype(key, MOVETYPE_NONE);
key.team = key.owner.team;
key.angles_y += key.owner.angles.y;
#endif
key.flags = FL_ITEM;
+ IL_PUSH(g_items, key);
key.solid = SOLID_TRIGGER;
set_movetype(key, MOVETYPE_TOSS);
key.pain_finished = time + autocvar_g_balance_keyhunt_delay_return;
// immediately return is bad
// maybe start a shorter countdown?
}
- if(vlen(force) <= 0)
+ if(force == '0 0 0')
return;
if(time > this.pushltime)
if(IS_PLAYER(attacker))
float first;
entity key;
float score;
- score = (kh_teams - 1) * autocvar_g_balance_keyhunt_score_capture;
- DistributeEvenly_Init(score, kh_teams);
+ score = (NumTeams(kh_teams) - 1) * autocvar_g_balance_keyhunt_score_capture;
+ DistributeEvenly_Init(score, NumTeams(kh_teams));
// twice the score for 3 team games, three times the score for 4 team games!
// note: for a win by destroying the key, this should NOT be applied
FOR_EACH_KH_KEY(key)
firstorigin = thisorigin;
first = false;
}
- if(kh_teams > 2)
+ if(NumTeams(kh_teams) > 2)
{
te_lightning2(NULL, lastorigin, firstorigin);
}
- midpoint = midpoint * (1 / kh_teams);
+ midpoint = midpoint * (1 / NumTeams(kh_teams));
te_customflash(midpoint, 1000, 1, Team_ColorRGB(teem) * 0.5 + '0.5 0.5 0.5'); // make the color >=0.5 in each component
play2all(SND(KH_CAPTURE));
fragsleft = DistributeEvenly_Get(players);
// Now distribute these among all other teams...
- j = kh_teams - 1;
- for(i = 0; i < kh_teams; ++i)
+ j = NumTeams(kh_teams) - 1;
+ for(i = 0; i < NumTeams(kh_teams); ++i)
{
thisteam = kh_Team_ByID(i);
if(thisteam == teem) // bad boy, no cookie - this WILL happen
float keys;
teem = -1;
- keys = kh_teams;
+ keys = NumTeams(kh_teams);
FOR_EACH_KH_KEY(key)
{
if(!key.owner)
float kh_CheckPlayers(float num)
{
- if(num < kh_teams)
+ if(num < NumTeams(kh_teams))
{
float t_team = kh_Team_ByID(num);
float players = 0;
return 0;
}
-#define KH_READY_TEAMS() (!p1 + !p2 + ((kh_teams >= 3) ? !p3 : p3) + ((kh_teams >= 4) ? !p4 : p4))
-#define KH_READY_TEAMS_OK() (KH_READY_TEAMS() == kh_teams)
+#define KH_READY_TEAMS() (!p1 + !p2 + ((NumTeams(kh_teams) >= 3) ? !p3 : p3) + ((NumTeams(kh_teams) >= 4) ? !p4 : p4))
+#define KH_READY_TEAMS_OK() (KH_READY_TEAMS() == NumTeams(kh_teams))
void kh_WaitForPlayers() // delay start of the round until enough players are present
{
if(time < game_starttime)
Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_KEYHUNT);
Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_KEYHUNT_OTHER);
- for(i = 0; i < kh_teams; ++i)
+ for(i = 0; i < NumTeams(kh_teams); ++i)
{
teem = kh_Team_ByID(i);
players = 0;
my_player = it;
}
));
- kh_Key_Spawn(my_player, 360 * i / kh_teams, i);
+ kh_Key_Spawn(my_player, 360 * i / NumTeams(kh_teams), i);
}
kh_tracking_enabled = false;
if(IS_DEAD(this))
return;
- entity e;
if (this.bot_strategytime < time)
{
this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
navigation_goalrating_start(this);
- for(e = NULL; (e = find(e, classname, "trigger_race_checkpoint")) != NULL; )
+ IL_EACH(g_racecheckpoints, true,
{
- if(e.cnt == this.race_checkpoint)
+ if(it.cnt == this.race_checkpoint)
{
- navigation_routerating(this, e, 1000000, 5000);
+ navigation_routerating(this, it, 1000000, 5000);
}
else if(this.race_checkpoint == -1)
{
- navigation_routerating(this, e, 1000000, 5000);
+ navigation_routerating(this, it, 1000000, 5000);
}
- }
+ });
navigation_goalrating_end(this);
}
animdecide_load_if_needed(clone);
animdecide_setframes(clone, false, frame, frame1time, frame2, frame2time);
+ IL_PUSH(g_clones, clone);
+
MUTATOR_CALLHOOK(CopyBody, this, clone, keepvelocity);
}
race_timed_checkpoint = 255;
}
} else {
- for (entity cp = NULL; (cp = find(cp, classname, "trigger_race_checkpoint")); ) {
- if (cp.sprite) {
- if (cp.race_checkpoint == 0) {
- WaypointSprite_UpdateSprites(cp.sprite, WP_RaceStart, WP_Null, WP_Null);
- } else if (cp.race_checkpoint == race_timed_checkpoint) {
- WaypointSprite_UpdateSprites(cp.sprite, WP_RaceFinish, WP_Null, WP_Null);
- }
+ IL_EACH(g_racecheckpoints, it.sprite,
+ {
+ if (it.race_checkpoint == 0) {
+ WaypointSprite_UpdateSprites(it.sprite, WP_RaceStart, WP_Null, WP_Null);
+ } else if (it.race_checkpoint == race_timed_checkpoint) {
+ WaypointSprite_UpdateSprites(it.sprite, WP_RaceFinish, WP_Null, WP_Null);
}
- }
+ });
}
}
this.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
this.spawn_evalfunc = trigger_race_checkpoint_spawn_evalfunc;
+ IL_PUSH(g_racecheckpoints, this);
+
InitializeEntity(this, trigger_race_checkpoint_verify, INITPRIO_FINDTARGET);
}
vector o0, o1;
float bestfraction, fraction;
- entity lastcp, cp0, cp1;
+ entity lastcp;
float nextcpindex, lastcpindex;
nextcpindex = max(e.race_checkpoint, 0);
return l; // finish
bestfraction = 1;
- for(cp0 = NULL; (cp0 = find(cp0, classname, "trigger_race_checkpoint")); )
+ IL_EACH(g_racecheckpoints, true,
{
- if(cp0.race_checkpoint != lastcpindex)
+ if(it.race_checkpoint != lastcpindex)
continue;
if(lastcp)
- if(cp0 != lastcp)
+ if(it != lastcp)
continue;
- o0 = (cp0.absmin + cp0.absmax) * 0.5;
- for(cp1 = NULL; (cp1 = find(cp1, classname, "trigger_race_checkpoint")); )
+ o0 = (it.absmin + it.absmax) * 0.5;
+ IL_EACH(g_racecheckpoints, true,
{
- if(cp1.race_checkpoint != nextcpindex)
+ if(it.race_checkpoint != nextcpindex)
continue;
- o1 = (cp1.absmin + cp1.absmax) * 0.5;
+ o1 = (it.absmin + it.absmax) * 0.5;
if(o0 == o1)
continue;
fraction = bound(0.0001, vlen(e.origin - o1) / vlen(o0 - o1), 1);
if(fraction < bestfraction)
bestfraction = fraction;
- }
- }
+ });
+ });
// we are at CP "nextcpindex - bestfraction"
// race_timed_checkpoint == 4: then nextcp==4 means 0.9999x, nextcp==0 means 0.0000x
.float race_respawn_checkpoint;
.entity race_respawn_spotref; // try THIS spawn in case you respawn
+IntrusiveList g_racecheckpoints;
+STATIC_INIT(g_racecheckpoints) { g_racecheckpoints = IL_NEW(); }
+
// definitions for functions used outside race.qc
float race_PreviousCheckpoint(float f);
float race_NextCheckpoint(float f);
spawnfunc(info_player_deathmatch)
{
this.classname = "info_player_deathmatch";
+ IL_PUSH(g_spawnpoints, this);
relocate_spawnpoint(this);
}
float teamcheck;
entity spot, firstspot;
- spot = find (NULL, classname, "testplayerstart");
+ spot = find(NULL, classname, "testplayerstart");
if (spot)
return spot;
vector wander_point;
wander_point = v_forward - oldpoint;
- if (vlen(wander_point) > tresh)
+ if (vdist(wander_point, >, tresh))
return oldpoint;
range = bound(0,range,1);
void StartFrame()
{
// TODO: if move is more than 50ms, split it into two moves (this matches QWSV behavior and the client prediction)
- FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), sys_phys_update(it, frametime));
- FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), PlayerPreThink(it));
+ IL_EACH(g_players, IS_FAKE_CLIENT(it), sys_phys_update(it, frametime));
+ IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPreThink(it));
execute_next_frame();
if (autocvar_sv_autopause && !server_is_dedicated) Pause_TryPause(true);
}
#endif
- FOREACH_ENTITY_FLOAT(csqcprojectile_clientanimate, true, CSQCProjectile_Check(it));
+ IL_EACH(g_projectiles, it.csqcprojectile_clientanimate, CSQCProjectile_Check(it));
if (RedirectionThink()) return;
MUTATOR_CALLHOOK(SV_StartFrame);
FOREACH_CLIENT(true, GlobalStats_update(it));
- FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), PlayerPostThink(it));
+ IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPostThink(it));
}
.vector originjitter;
// weapon give ent from defrag
void target_give_init(entity this)
{
- entity targ;
- for (targ = NULL; (targ = find(targ, targetname, this.target)); ) {
- if (targ.classname == "weapon_rocketlauncher" || targ.classname == "weapon_devastator") {
- this.ammo_rockets += targ.count * WEP_CVAR(devastator, ammo);
+ IL_EACH(g_items, it.targetname == this.target,
+ {
+ if (it.classname == "weapon_rocketlauncher" || it.classname == "weapon_devastator") {
+ this.ammo_rockets += it.count * WEP_CVAR(devastator, ammo);
this.netname = "devastator";
}
- else if (targ.classname == "weapon_plasmagun") {
- this.ammo_rockets += targ.count * WEP_CVAR_PRI(hagar, ammo); // WEAPONTODO
+ else if (it.classname == "weapon_plasmagun") {
+ this.ammo_rockets += it.count * WEP_CVAR_PRI(hagar, ammo); // WEAPONTODO
if(this.netname == "")
this.netname = "hagar";
else
this.netname = strcat(this.netname, " hagar");
}
- else if (targ.classname == "weapon_bfg") {
- this.ammo_cells += targ.count * WEP_CVAR_PRI(crylink, ammo);
+ else if (it.classname == "weapon_bfg") {
+ this.ammo_cells += it.count * WEP_CVAR_PRI(crylink, ammo);
if(this.netname == "")
this.netname = "crylink";
else
this.netname = strcat(this.netname, " crylink");
}
- else if (targ.classname == "weapon_grenadelauncher" || targ.classname == "weapon_mortar") {
- this.ammo_rockets += targ.count * WEP_CVAR_PRI(mortar, ammo); // WEAPONTODO
+ else if (it.classname == "weapon_grenadelauncher" || it.classname == "weapon_mortar") {
+ this.ammo_rockets += it.count * WEP_CVAR_PRI(mortar, ammo); // WEAPONTODO
if(this.netname == "")
this.netname = "mortar";
else
this.netname = strcat(this.netname, " mortar");
}
- else if (targ.classname == "item_armor_body")
+ else if (it.classname == "item_armor_body")
this.armorvalue = 100;
- else if (targ.classname == "item_health_mega")
+ else if (it.classname == "item_health_mega")
this.health = 200;
- //remove(targ); // removing ents in init functions causes havoc, workaround:
- setthink(targ, SUB_Remove);
- targ.nextthink = time;
- }
+ //remove(it); // removing ents in init functions causes havoc, workaround:
+ setthink(it, SUB_Remove);
+ it.nextthink = time;
+ });
this.spawnflags = 2;
spawnfunc_target_items(this);
InitializeEntity(this, target_init_verify, INITPRIO_FINDTARGET);
void Weapon_whereis(Weapon this, entity cl)
{
if (!autocvar_g_showweaponspawns) return;
- FOREACH_ENTITY_FLOAT(weapon, this.m_id,
+ IL_EACH(g_items, it.weapon == this.m_id,
{
if (it.classname == "droppedweapon" && autocvar_g_showweaponspawns < 2)
continue;
- if (!(it.flags & FL_ITEM))
- continue;
entity wp = WaypointSprite_Spawn(
WP_Weapon,
-2, 0,
{
if (e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
{
- LOG_MAPWARNF("Attempted to spawn a mutator-blocked weapon rejected: prvm_edict server %i", this);
+ LOG_WARNF("Attempted to spawn a mutator-blocked weapon rejected: prvm_edict server %i", this);
startitem_failed = true;
return;
}
#include <common/t_items.qh>
#include <common/animdecide.qh>
#include <common/constants.qh>
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
#include <common/notifications/all.qh>
#include <common/util.qh>
#include <common/weapons/_all.qh>