+*.q[ch] linguist-language=C
+*.inc linguist-language=C
+
* -crlf
*.0 -diff -crlf
*.1 crlf=input
# this will also influence the order of the classes in the class list.
# The default value is: NO.
-SORT_BRIEF_DOCS = NO
+SORT_BRIEF_DOCS = YES
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
# (brief and detailed) documentation of class members so that constructors and
# detailed member documentation.
# The default value is: NO.
-SORT_MEMBERS_CTORS_1ST = NO
+SORT_MEMBERS_CTORS_1ST = YES
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
# of group names into alphabetical order. If set to NO the group names will
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-MACRO_EXPANSION = NO
+MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-EXPAND_ONLY_PREDEF = NO
+EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
# preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
-INCLUDE_PATH =
+INCLUDE_PATH = .
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-PREDEFINED =
+PREDEFINED = \
+ "USING(name, T)=using name = T" \
+ "CLASS(name, base)=class name : public base { public:" \
+ "CONSTRUCTOR(class)=class::class(" \
+ "DESTRUCTOR(class)=class::~class()" \
+ "ATTRIB(class, name, T, val)=T name = val;" \
+ "ATTRIB_STRZONE(class, name, T, val)=T name = val;" \
+ "STATIC_ATTRIB(class, name, T, val)=static T name = val;" \
+ "STATIC_ATTRIB_STRZONE(class, name, T, val)=static T name = val;" \
+ "METHOD(class, name, prototype)=virtual void class::name()" \
+ "ENDCLASS(class)=};" \
+ __STDC__
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
# definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-EXPAND_AS_DEFINED =
+EXPAND_AS_DEFINED = \
+ USING \
+ CLASS \
+ CONSTRUCTOR \
+ DESTRUCTOR \
+ ATTRIB ATTRIB_STRZONE \
+ STATIC_ATTRIB STATIC_ATTRIB_STRZONE \
+ METHOD \
+ ENDCLASS \
+ LABEL \
+ __STDC__
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have
void LocalCommand_blurtest(int request)
{
+ TC(int, request);
// Simple command to work with postprocessing temporarily... possibly completely pointless, the glsl shader is used for a real feature now...
// Anyway, to enable it, just compile the client with -DBLURTEST and then you can use the command.
void LocalCommand_boxparticles(int request, int argc)
{
+ TC(int, request); TC(int, argc);
switch (request)
{
case CMD_REQUEST_COMMAND:
void LocalCommand_create_scrshot_ent(int request)
{
+ TC(int, request);
switch (request)
{
case CMD_REQUEST_COMMAND:
void LocalCommand_debugmodel(int request, int argc)
{
+ TC(int, request); TC(int, argc);
switch (request)
{
case CMD_REQUEST_COMMAND:
void LocalCommand_handlevote(int request, int argc)
{
+ TC(int, request); TC(int, argc);
switch (request)
{
case CMD_REQUEST_COMMAND:
void LocalCommand_hud(int request, int argc)
{
+ TC(int, request); TC(int, argc);
switch (request)
{
case CMD_REQUEST_COMMAND:
void LocalCommand_localprint(int request, int argc)
{
+ TC(int, request); TC(int, argc);
switch (request)
{
case CMD_REQUEST_COMMAND:
void LocalCommand_mv_download(int request, int argc)
{
+ TC(int, request); TC(int, argc);
switch (request)
{
case CMD_REQUEST_COMMAND:
void LocalCommand_sendcvar(int request, int argc)
{
+ TC(int, request); TC(int, argc);
switch (request)
{
case CMD_REQUEST_COMMAND:
{
string c = strtolower(argv(0));
FOREACH(CLIENT_COMMANDS, it.m_name == c, {
- it.m_invokecmd(CMD_REQUEST_COMMAND, NULL, argc, command);
+ it.m_invokecmd(it, CMD_REQUEST_COMMAND, NULL, argc, command);
return true;
});
return false;
{
string c = strtolower(argv(1));
FOREACH(CLIENT_COMMANDS, it.m_name == c, {
- it.m_invokecmd(CMD_REQUEST_USAGE, NULL, argc, "");
+ it.m_invokecmd(it, CMD_REQUEST_USAGE, NULL, argc, "");
return true;
});
return false;
ATTRIB(clientcommand_##id, m_description, string, description); \
ENDCLASS(clientcommand_##id) \
REGISTER(CLIENT_COMMANDS, CMD_CL, id, m_id, NEW(clientcommand_##id)); \
- METHOD(clientcommand_##id, m_invokecmd, void(int request, entity caller, int arguments, string command))
+ METHOD(clientcommand_##id, m_invokecmd, void(clientcommand_##id this, int request, entity caller, int arguments, string command))
STATIC_INIT(CLIENT_COMMANDS_aliases) {
FOREACH(CLIENT_COMMANDS, true, localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_cl")));
}
int CSQCPlayer_FallbackFrame(entity this, int f)
{
+ TC(int, f);
if(frameduration(this.modelindex, f) > 0)
return f; // goooooood
if(frameduration(this.modelindex, 1) <= 0)
float HUD_GetRowCount(int item_count, vector size, float item_aspect)
{
+ TC(int, item_count);
float aspect = size_y / size_x;
return bound(1, floor((sqrt(4 * item_aspect * aspect * item_count + aspect * aspect) + aspect + 0.5) / 2), item_count);
}
vector HUD_GetTableSize_BestItemAR(int item_count, vector psize, float item_aspect)
{
+ TC(int, item_count);
float columns, rows;
float ratio, best_ratio = 0;
float best_columns = 1, best_rows = 1;
// return the string of the onscreen race timer
string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, string theirname)
{
+ TC(int, cp);
string col;
string timestr;
string cpname;
//basically the same code of draw_ButtonPicture and draw_VertButtonPicture for the menu
void HUD_Panel_DrawProgressBar(vector theOrigin, vector theSize, string pic, float length_ratio, bool vertical, float baralign, vector theColor, float theAlpha, int drawflag)
{
+ TC(bool, vertical); TC(int, drawflag);
if(!length_ratio || !theAlpha)
return;
if(length_ratio > 1)
void HUD_Panel_DrawHighlight(vector pos, vector mySize, vector color, float theAlpha, int drawflag)
{
+ TC(int, drawflag);
if(!theAlpha)
return;
void DrawNumIcon_expanding(vector myPos, vector mySize, float x, string icon, bool vertical, bool icon_right_align, vector color, float theAlpha, float fadelerp)
{
+ TC(bool, vertical); TC(bool, icon_right_align);
vector newPos = '0 0 0', newSize = '0 0 0';
vector picpos, numpos;
void DrawNumIcon(vector myPos, vector mySize, float x, string icon, bool vertical, bool icon_right_align, vector color, float theAlpha)
{
+ TC(bool, vertical); TC(bool, icon_right_align);
DrawNumIcon_expanding(myPos, mySize, x, icon, vertical, icon_right_align, color, theAlpha, 0);
}
bool HUD_Panel_CheckFlags(int showflags)
{
+ TC(int, showflags);
if ( HUD_Minigame_Showpanels() )
return showflags & PANEL_SHOW_MINIGAME;
if(intermission == 2)
void HUD_Panel_FirstInDrawQ(float id);
void reset_tab_panels()
{
- int i;
- for(i = 0; i < hud_panels_COUNT; ++i)
+ for (int i = 0; i < hud_panels_COUNT; ++i)
tab_panels[i] = world;
}
float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
vector candidate_pos = '0 0 0';
const float LEVELS_NUM = 4;
float level_height = vid_conheight / LEVELS_NUM;
-:find_tab_panel
+LABEL(find_tab_panel)
level = floor(tab_panel_pos.y / level_height) * level_height; //starting level
candidate_pos.x = (!tab_backward) ? vid_conwidth : 0;
start_posX = tab_panel_pos.x;
void DrawAmmoItem(vector myPos, vector mySize, .int ammoType, bool isCurrent, bool isInfinite)
{
+ TC(bool, isCurrent); TC(bool, isInfinite);
if(ammoType == ammo_none)
return;
void centerprint_generic(int new_id, string strMessage, float duration, int countdown_num)
{
+ TC(int, new_id); TC(int, countdown_num);
//printf("centerprint_generic(%d, '%s^7', %d, %d);\n", new_id, strMessage, duration, countdown_num);
int i, j;
centerprint_countdown_num[j] = countdown_num;
}
-void centerprint_kill(float id)
+void centerprint_kill(int id)
{
+ TC(int, id);
centerprint_generic(id, "", 0, 0);
}
void reset_centerprint_messages()
{
- int i;
- for (i=0; i<CENTERPRINT_MAX_MSGS; ++i)
+ for (int i=0; i<CENTERPRINT_MAX_MSGS; ++i)
{
centerprint_expire_time[i] = 0;
centerprint_time[i] = 1;
void DrawCAItem(vector myPos, vector mySize, float aspect_ratio, int layout, int i)
{
+ TC(int, layout); TC(int, i);
int stat = -1;
string pic = "";
vector color = '0 0 0';
void DrawDomItem(vector myPos, vector mySize, float aspect_ratio, int layout, int i)
{
+ TC(int, layout); TC(int, i);
float stat = -1;
string pic = "";
vector color = '0 0 0';
int getPowerupItemAlign(int align, int column, int row, int columns, int rows, bool isVertical)
{
+ TC(int, align); TC(int, column); TC(int, row); TC(int, columns); TC(int, rows); TC(bool, isVertical);
if(align < 2)
return align;
void HUD_Radar_Show_Maximized(bool doshow,float clickable)
{
+ TC(bool, doshow);
hud_panel_radar_maximized = doshow;
hud_panel_radar_temp_hidden = 0;
}
-float HUD_Radar_InputEvent(float bInputType, float nPrimary, float nSecondary)
+float HUD_Radar_InputEvent(int bInputType, float nPrimary, float nSecondary)
{
+ TC(int, bInputType);
if(!hud_panel_radar_maximized || !hud_panel_radar_mouse ||
autocvar__hud_configure || mv_active)
return false;
entity weaponorder[Weapons_MAX];
void weaponorder_swap(int i, int j, entity pass)
{
+ TC(int, i); TC(int, j);
entity h = weaponorder[i];
weaponorder[i] = weaponorder[j];
weaponorder[j] = h;
string weaponorder_cmp_str;
int weaponorder_cmp(int i, int j, entity pass)
{
+ TC(int, i); TC(int, j);
int ai = strstrofs(weaponorder_cmp_str, sprintf(" %d ", weaponorder[i].m_id), 0);
int aj = strstrofs(weaponorder_cmp_str, sprintf(" %d ", weaponorder[j].m_id), 0);
return aj - ai; // the string is in REVERSE order (higher prio at the right is what we want, but higher prio first is the string)
void HUD_Weapons()
{
- SELFPARAM();
// declarations
WepSet weapons_stat = WepSet_GetFromStat();
int i;
.float has_team;
float SetTeam(entity o, int Team)
{
+ TC(int, Team);
devassert_once(Team);
entity tm;
if(teamplay)
// In the case of keyboard input, nPrimary is the ascii code, and nSecondary is 0.
// In the case of mouse input, nPrimary is xdelta, nSecondary is ydelta.
// In the case of mouse input after a setcursormode(1) call, nPrimary is xpos, nSecondary is ypos.
-float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
+float CSQC_InputEvent(int bInputType, float nPrimary, float nSecondary)
{
+ TC(int, bInputType);
if (HUD_Panel_InputEvent(bInputType, nPrimary, nSecondary))
return true;
string MapVote_FormatMapItem(int id, string map, float _count, float maxwidth, vector fontsize)
{
+ TC(int, id);
string pre, post;
pre = sprintf("%d. ", id+1);
if(mv_detail)
vector MapVote_RGB(int id)
{
+ TC(int, id);
if(!(mv_flags[id] & GTV_AVAILABLE))
return '1 1 1';
if(id == mv_ownvote)
void GameTypeVote_DrawGameTypeItem(vector pos, float maxh, float tsize, string gtype, string pic, float _count, int id)
{
+ TC(int, id);
// Find the correct alpha
float alpha;
if(!(mv_flags_start[id] & GTV_AVAILABLE))
void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, string pic, float _count, int id)
{
+ TC(int, id);
vector img_size = '0 0 0';
string label;
float text_size;
void MapVote_DrawAbstain(vector pos, float isize, float tsize, float _count, int id)
{
+ TC(int, id);
vector rgb;
float text_size;
string label;
vector MapVote_GridVec(vector gridspec, int i, int m)
{
+ TC(int, i); TC(int, m);
int r = i % m;
return
'1 0 0' * (gridspec.x * r)
draw_cursor_normal(mv_mousepos, '1 1 1', 1 - autocvar__menu_alpha);
}
-void Cmd_MapVote_MapDownload(float argc)
+void Cmd_MapVote_MapDownload(int argc)
{
+ TC(int, argc);
entity pak;
if(argc != 2 || !mv_pk3list)
void MapVote_CheckPK3(string pic, string pk3, int id)
{
+ TC(int, id);
entity pak;
pak = spawn();
pak.netname = pk3;
void MapVote_CheckPic(string pic, string pk3, int id)
{
+ TC(int, id);
// never try to retrieve a pic for the "don't care" 'map'
if(mv_abstain && id == mv_num_maps - 1)
return;
void MapVote_ReadOption(int i)
{
+ TC(int, i);
string map = strzone(ReadString());
string pk3 = strzone(ReadString());
int j = bound(0, ReadByte(), n_ssdirs - 1);
void GameTypeVote_ReadOption(int i)
{
+ TC(int, i);
string gt = strzone(ReadString());
mv_maps[i] = gt;
n_ssdirs = 0;
}
-void MapVote_SendChoice(float index)
+void MapVote_SendChoice(int index)
{
+ TC(int, index);
localcmd(strcat("\nimpulse ", ftos(index+1), "\n"));
}
int MapVote_MoveLeft(int pos)
{
+ TC(int, pos);
int imp;
if ( pos < 0 )
imp = mv_num_maps - 1;
}
int MapVote_MoveRight(int pos)
{
+ TC(int, pos);
int imp;
if ( pos < 0 )
imp = 0;
}
int MapVote_MoveUp(int pos)
{
+ TC(int, pos);
int imp;
if ( pos < 0 )
imp = mv_num_maps - 1;
}
int MapVote_MoveDown(int pos)
{
+ TC(int, pos);
int imp;
if ( pos < 0 )
imp = 0;
return imp;
}
-float MapVote_InputEvent(float bInputType, float nPrimary, float nSecondary)
+float MapVote_InputEvent(int bInputType, float nPrimary, float nSecondary)
{
+ TC(int, bInputType);
float imp;
if (!mv_active)
entity GetTeam(int Team, bool add)
{
+ TC(int, Team); TC(bool, add);
int num = (Team == NUM_SPECTATOR) ? 16 : Team;
if(teamslots[num])
return teamslots[num];
// decolorizes and team colors the player name when needed
string playername(string thename, float teamid)
{
+ TC(int, teamid);
string t;
if (teamplay)
{
}
/** engine callback */
-void URI_Get_Callback(int id, float status, string data)
+void URI_Get_Callback(int id, int status, string data)
{
+ TC(int, id); TC(int, status);
if(url_URI_Get_Callback(id, status, data))
{
// handled
}
}
-void skel_set_boneabs(float s, float bone, vector absorg)
+void skel_set_boneabs(float s, int bone, vector absorg)
{
+ TC(int, bone);
vector absang = fixedvectoangles2(v_forward, v_up);
vector parentorg = skel_get_boneabs(s, skel_get_boneparent(s, bone));
}
}
-void skeleton_from_frames(entity e, float is_dead)
-{SELFPARAM();
+void skeleton_from_frames(entity e, bool is_dead)
+{
+ TC(bool, is_dead);
float m = e.modelindex;
if(!e.skeletonindex)
{
// if s1 is not empty s will be displayed as command otherwise as submenu
void QuickMenu_Page_LoadEntry(int i, string s, string s1)
{
+ TC(int, i);
//printf("^xc80 entry %d: %s, %s\n", i, s, s1);
if (QuickMenu_Page_Description[i])
strunzone(QuickMenu_Page_Description[i]);
void QuickMenu_Page_ClearEntry(int i)
{
+ TC(int, i);
if (QuickMenu_Page_Description[i])
strunzone(QuickMenu_Page_Description[i]);
QuickMenu_Page_Description[i] = string_null;
return (QuickMenu_Page_Entries > 0);
}
-void HUD_Quickmenu_PlayerListEntries(string cmd, int teamplayers, float without_me);
-bool HUD_Quickmenu_PlayerListEntries_Create(string cmd, int teamplayers, float without_me)
+void HUD_Quickmenu_PlayerListEntries(string cmd, int teamplayers, bool without_me);
+bool HUD_Quickmenu_PlayerListEntries_Create(string cmd, int teamplayers, bool without_me)
{
+ TC(int, teamplayers); TC(bool, without_me);
int i;
for(i = 0; i < QUICKMENU_MAXLINES; ++i)
QuickMenu_Page_ClearEntry(i);
// new_page 0 means page 0, new_page != 0 means next page
int QuickMenu_Buffer_Index_Prev;
-bool QuickMenu_Page_Load(string target_submenu, int new_page)
+bool QuickMenu_Page_Load(string target_submenu, bool new_page)
{
+ TC(bool, new_page);
string s = string_null, cmd = string_null, z_submenu;
if (new_page == 0)
bool QuickMenu_ActionForNumber(int num)
{
+ TC(int, num);
if (!QuickMenu_IsLastPage)
{
if (num < 0 || num >= QUICKMENU_MAXLINES)
return false;
}
-void QuickMenu_Page_ActiveEntry(float entry_num)
+void QuickMenu_Page_ActiveEntry(int entry_num)
{
+ TC(int, entry_num);
QuickMenu_Page_ActivatedEntry = entry_num;
QuickMenu_Page_ActivatedEntry_Time = time + 0.1;
if(QuickMenu_Page_Command[QuickMenu_Page_ActivatedEntry])
QuickMenu_Page_ActivatedEntry_Close = (!(hudShiftState & S_CTRL));
}
-bool QuickMenu_InputEvent(float bInputType, float nPrimary, float nSecondary)
+bool QuickMenu_InputEvent(int bInputType, float nPrimary, float nSecondary)
{
+ TC(int, bInputType);
// we only care for keyboard events
if(bInputType == 2)
return false;
QUICKMENU_ENTRY(strcat("(", prvm_language, ")", title), sprintf(command, translated_text)) \
}
-void HUD_Quickmenu_PlayerListEntries(string cmd, float teamplayers, float without_me)
+void HUD_Quickmenu_PlayerListEntries(string cmd, int teamplayers, bool without_me)
{
+ TC(int, teamplayers); TC(bool, without_me);
entity pl;
if(teamplayers && !team_count)
return;
*/
}
-int HUD_CompareScore(float vl, float vr, int f)
+int HUD_CompareScore(int vl, int vr, int f)
{
+ TC(int, vl); TC(int, vr); TC(int, f);
if(f & SFL_ZERO_IS_WORST)
{
if(vl == 0 && vr != 0)
"+as/objectives +nb/faults +nb/goals +ka/pickups +ka/bckills +ka/bctime +ft/revivals " \
"-lms,rc,nb/score"
-void Cmd_HUD_SetFields(float argc)
+void Cmd_HUD_SetFields(int argc)
{
+ TC(int, argc);
int i, j, slash;
string str, pattern;
float have_name = 0, have_primary = 0, have_secondary = 0, have_separator = 0;
if(str == strtolower(scores_label[j]))
goto found; // sorry, but otherwise fteqcc -O3 miscompiles this and warns about "unreachable code"
-:notfound
+LABEL(notfound)
if(str == "frags")
j = SP_FRAGS;
else
LOG_INFOF("^1Error:^7 Unknown score field: '%s'\n", str);
continue;
}
-:found
+LABEL(found)
hud_field[hud_num_fields] = j;
if(j == ps_primary)
have_primary = 1;
float hud_field_icon2_alpha;
string HUD_GetField(entity pl, int field)
{
+ TC(int, field);
float tmp, num, denom;
int f;
string str;
string HUD_FixScoreboardColumnWidth(int i, string str)
{
+ TC(int, i);
float field, f;
vector sz;
field = hud_field[i];
return str;
}
-void HUD_PrintScoreboardItem(vector pos, vector item_size, entity pl, float is_self, int pl_number)
+void HUD_PrintScoreboardItem(vector pos, vector item_size, entity pl, bool is_self, int pl_number)
{
+ TC(bool, is_self); TC(int, pl_number);
vector tmp, rgb;
rgb = Team_ColorRGB(pl.team);
string str;
float average_accuracy;
vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
{
- SELFPARAM();
WepSet weapons_stat = WepSet_GetFromStat();
WepSet weapons_inmap = WepSet_GetFromStat_InMap();
float initial_posx = pos.x;
void Draw_ShowNames_All()
{
+ SELFPARAM();
if (!autocvar_hud_shownames) return;
LL_EACH(shownames_ent, true, {
entity entcs = entcs_receiver(i);
void draw_teamradar_link(vector start, vector end, int colors)
{
+ TC(int, colors);
vector c0, c1, norm;
start = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(start));
wcross_color = rainbow_prev_color;
break;
}
- :normalcolor
+LABEL(normalcolor)
default: { wcross_color = stov(autocvar_crosshair_color); break; }
}
void WaypointSprite_Load();
void CSQC_UpdateView(float w, float h)
{SELFPARAM();
+ TC(int, w); TC(int, h);
entity e;
float fov;
float f;
void loopsound(entity e, int ch, string samp, float vol, float attn)
{
+ TC(int, ch);
if (e.silent)
return;
ATTRIB(genericcommand_##id, m_description, string, description); \
ENDCLASS(genericcommand_##id) \
REGISTER(GENERIC_COMMANDS, CMD_G, id, m_id, NEW(genericcommand_##id)); \
- METHOD(genericcommand_##id, m_invokecmd, void(int request, entity caller, int arguments, string command))
+ METHOD(genericcommand_##id, m_invokecmd, void(genericcommand_##id this, int request, entity caller, int arguments, string command))
STATIC_INIT(GENERIC_COMMANDS_aliases) {
FOREACH(GENERIC_COMMANDS, true, localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_svmenu")));
CLASS(Command, Object)
ATTRIB(Command, m_name, string, string_null);
ATTRIB(Command, m_description, string, string_null);
- METHOD(Command, m_invokecmd, void(int request, entity caller, int arguments, string command)) { }
+ METHOD(Command, m_invokecmd, void(Command this, int request, entity caller, int arguments, string command))
+ {
+ TC(Command, this);
+ }
ENDCLASS(Command)
#endif
{
string c = strtolower(argv(0));
FOREACH(GENERIC_COMMANDS, it.m_name == c, {
- it.m_invokecmd(CMD_REQUEST_COMMAND, NULL, argc, command);
+ it.m_invokecmd(it, CMD_REQUEST_COMMAND, NULL, argc, command);
return true;
});
return false;
{
string c = strtolower(argv(1));
FOREACH(GENERIC_COMMANDS, it.m_name == c, {
- it.m_invokecmd(CMD_REQUEST_USAGE, NULL, argc, "");
+ it.m_invokecmd(it, CMD_REQUEST_USAGE, NULL, argc, "");
return true;
});
return false;
if(argv(i) == argv(j))
goto skip_union;
s = strcat(s, " ", argv(i));
- :skip_union
+LABEL(skip_union)
}
if(substring(s, 0, 1) == " ")
s = substring(s, 1, 99999);
if(argv(i) == argv(j))
goto skip_difference;
s = strcat(s, " ", argv(i));
- :skip_difference
+LABEL(skip_difference)
}
if(substring(s, 0, 1) == " ")
s = substring(s, 1, 99999);
FIELDS(MY)
#undef MY
- METHOD(EffectInfo, describe, string(EffectInfo this)) {
+ METHOD(EffectInfo, describe, string(EffectInfo this))
+ {
+ TC(EffectInfo, this);
string s = sprintf("SUB(%s) {\n", this.effectinfo_name);
#define str_bool(it) (it ? "true" : "false")
#define str_float(it) ftos(it)
return strcat(s, "}\n");
}
- METHOD(EffectInfo, dump, string(EffectInfo this)) {
+ METHOD(EffectInfo, dump, string(EffectInfo this))
+ {
+ TC(EffectInfo, this);
string s = sprintf("effect %s\n", this.effectinfo_name);
#define MY(f) this.effectinfo_##f
#define p(k, isset, parse, unparse) if (isset) { s = strcat(s, "\t", #k, unparse, "\n"); }
void SUB_RemoveOnNoImpact()
{
+ SELFPARAM();
if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
Gib_Delete(self);
}
string GlobalSound_sample(string pair, float r);
#ifdef SVQC
- /** Use new sound handling. TODO: use when sounds play correctly on clients */
- bool autocvar_g_debug_globalsounds = false;
/**
* @param from the source entity, its position is sent
* @param gs the global sound def
#ifndef GLOBALSOUND_H
#define GLOBALSOUND_H
+#ifdef SVQC
+ /** Use new sound handling. TODO: use when sounds play correctly on clients */
+ bool autocvar_g_debug_globalsounds = false;
+#endif
+
// player sounds, voice messages
.string m_playersoundstr;
void RubbleLimit(string cname, float limit, void(entity) deleteproc)
{
- SELFPARAM();
entity e;
entity oldest;
float c;
if(!(ball = self.ballcarried))
return;
- W_SetupShot(self, false, 4, SND(NB_SHOOT1), CH_WEAPON_A, 0);
+ W_SetupShot(self, false, 4, SND_NB_SHOOT1, CH_WEAPON_A, 0);
tracebox(w_shotorg, BALL_MINS, BALL_MAXS, w_shotorg, MOVE_WORLDONLY, world);
if(trace_startsolid)
{
if(self.ballcarried.enemy)
{
entity _ball = self.ballcarried;
- W_SetupShot(self, false, 4, SND(NB_SHOOT1), CH_WEAPON_A, 0);
+ W_SetupShot(self, false, 4, SND_NB_SHOOT1, CH_WEAPON_A, 0);
DropBall(_ball, w_shotorg, trigger_push_calculatevelocity(_ball.origin, _ball.enemy, 32));
_ball.think = W_Nexball_Think;
_ball.nextthink = time;
if(!autocvar_g_nexball_tackling)
return;
- W_SetupShot(self, false, 2, SND(NB_SHOOT2), CH_WEAPON_A, 0);
+ W_SetupShot(self, false, 2, SND_NB_SHOOT2, CH_WEAPON_A, 0);
entity missile = new(ballstealer);
missile.owner = self;
METHOD(BallStealer, wr_think, void(BallStealer thiswep, entity actor, .entity weaponentity, int fire))
{
+ SELFPARAM();
+ TC(BallStealer, thiswep);
if(fire & 1)
if(weapon_prepareattack(thiswep, actor, weaponentity, false, autocvar_g_balance_nexball_primary_refire))
if(autocvar_g_nexball_basketball_meter)
}
}
-METHOD(BallStealer, wr_setup, void(BallStealer thiswep))
+METHOD(BallStealer, wr_setup, void(BallStealer this))
{
+ TC(BallStealer, this);
//weapon_setup(WEP_PORTO.m_id);
}
-METHOD(BallStealer, wr_checkammo1, bool(BallStealer thiswep))
+METHOD(BallStealer, wr_checkammo1, bool(BallStealer this))
{
+ TC(BallStealer, this);
return true;
}
-METHOD(BallStealer, wr_checkammo2, bool(BallStealer thiswep))
+METHOD(BallStealer, wr_checkammo2, bool(BallStealer this))
{
+ TC(BallStealer, this);
return true;
}
.int havocbot_role_flags;
.float havocbot_attack_time;
-void havocbot_role_ons_defense();
-void havocbot_role_ons_offense();
-void havocbot_role_ons_assistant();
+void havocbot_role_ons_defense(entity this);
+void havocbot_role_ons_offense(entity this);
+void havocbot_role_ons_assistant(entity this);
-void havocbot_ons_reset_role(entity bot);
-void havocbot_goalrating_items(float ratingscale, vector org, float sradius);
-void havocbot_goalrating_enemyplayers(float ratingscale, vector org, float sradius);
+void havocbot_ons_reset_role(entity this);
+void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius);
+void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius);
// score rule declarations
const int ST_ONS_CAPS = 1;
// NOTE: LEGACY CODE, needs to be re-written!
-void havocbot_goalrating_ons_offenseitems(float ratingscale, vector org, float sradius)
-{SELFPARAM();
+void havocbot_goalrating_ons_offenseitems(entity this, float ratingscale, vector org, float sradius)
+{
entity head;
float t, c;
bool needarmor = false, needweapons = false;
// Needs armor/health?
- if(self.health<100)
+ if(this.health<100)
needarmor = true;
// Needs weapons?
c = 0;
FOREACH(Weapons, it != WEP_Null, {
- if(self.weapons & (it.m_wepset))
+ if(this.weapons & (it.m_wepset))
if(++c >= 4)
break;
});
if(!needweapons && !needarmor)
return;
- LOG_DEBUG(strcat(self.netname, " needs weapons ", ftos(needweapons) , "\n"));
- LOG_DEBUG(strcat(self.netname, " needs armor ", ftos(needarmor) , "\n"));
+ LOG_DEBUG(strcat(this.netname, " needs weapons ", ftos(needweapons) , "\n"));
+ LOG_DEBUG(strcat(this.netname, " needs armor ", ftos(needarmor) , "\n"));
// See what is around
head = findchainfloat(bot_pickup, true);
if ( ((head.health || head.armorvalue) && needarmor) || (head.weapons && needweapons ) )
if (vlen(head.origin - org) < sradius)
{
- t = head.bot_pickupevalfunc(self, head);
+ t = head.bot_pickupevalfunc(this, head);
if (t > 0)
- navigation_routerating(head, t * ratingscale, 500);
+ navigation_routerating(this, head, t * ratingscale, 500);
}
head = head.chain;
}
}
-void havocbot_role_ons_setrole(entity bot, int role)
+void havocbot_role_ons_setrole(entity this, int role)
{
- LOG_DEBUG(strcat(bot.netname," switched to "));
+ LOG_DEBUG(strcat(this.netname," switched to "));
switch(role)
{
case HAVOCBOT_ONS_ROLE_DEFENSE:
LOG_DEBUG("defense");
- bot.havocbot_role = havocbot_role_ons_defense;
- bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_DEFENSE;
- bot.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_ons_defense;
+ this.havocbot_role_flags = HAVOCBOT_ONS_ROLE_DEFENSE;
+ this.havocbot_role_timeout = 0;
break;
case HAVOCBOT_ONS_ROLE_ASSISTANT:
LOG_DEBUG("assistant");
- bot.havocbot_role = havocbot_role_ons_assistant;
- bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_ASSISTANT;
- bot.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_ons_assistant;
+ this.havocbot_role_flags = HAVOCBOT_ONS_ROLE_ASSISTANT;
+ this.havocbot_role_timeout = 0;
break;
case HAVOCBOT_ONS_ROLE_OFFENSE:
LOG_DEBUG("offense");
- bot.havocbot_role = havocbot_role_ons_offense;
- bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_OFFENSE;
- bot.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_ons_offense;
+ this.havocbot_role_flags = HAVOCBOT_ONS_ROLE_OFFENSE;
+ this.havocbot_role_timeout = 0;
break;
}
LOG_DEBUG("\n");
}
-void havocbot_goalrating_ons_controlpoints_attack(float ratingscale)
-{SELFPARAM();
+void havocbot_goalrating_ons_controlpoints_attack(entity this, float ratingscale)
+{
entity cp, cp1, cp2, best, wp;
float radius, bestvalue;
int c;
continue;
// Ignore owned controlpoints
- if(!(cp2.isgenneighbor[self.team] || cp2.iscpneighbor[self.team]))
+ if(!(cp2.isgenneighbor[this.team] || cp2.iscpneighbor[this.team]))
continue;
// Count team mates interested in this control point
// (easier and cleaner than keeping counters per cp and teams)
FOREACH_CLIENT(IS_PLAYER(it), {
- if(SAME_TEAM(it, self))
+ if(SAME_TEAM(it, this))
if(it.havocbot_role_flags & HAVOCBOT_ONS_ROLE_OFFENSE)
if(it.havocbot_ons_target == cp2)
++c;
{
bestvalue = cp1.wpcost;
cp = cp1;
- self.havocbot_ons_target = cp1;
+ this.havocbot_ons_target = cp1;
}
}
if (!cp)
return;
- LOG_DEBUG(strcat(self.netname, " chose cp ranked ", ftos(bestvalue), "\n"));
+ LOG_DEBUG(strcat(this.netname, " chose cp ranked ", ftos(bestvalue), "\n"));
if(cp.goalentity)
{
if(best)
{
- navigation_routerating(best, ratingscale, 10000);
+ navigation_routerating(this, best, ratingscale, 10000);
best.cnt += 1;
- self.havocbot_attack_time = 0;
- if(checkpvs(self.view_ofs,cp))
- if(checkpvs(self.view_ofs,best))
- self.havocbot_attack_time = time + 2;
+ this.havocbot_attack_time = 0;
+ if(checkpvs(this.view_ofs,cp))
+ if(checkpvs(this.view_ofs,best))
+ this.havocbot_attack_time = time + 2;
}
else
{
- navigation_routerating(cp, ratingscale, 10000);
+ navigation_routerating(this, cp, ratingscale, 10000);
}
- LOG_DEBUG(strcat(self.netname, " found an attackable controlpoint at ", vtos(cp.origin) ,"\n"));
+ LOG_DEBUG(strcat(this.netname, " found an attackable controlpoint at ", vtos(cp.origin) ,"\n"));
}
else
{
// Should be touched
- LOG_DEBUG(strcat(self.netname, " found a touchable controlpoint at ", vtos(cp.origin) ,"\n"));
+ LOG_DEBUG(strcat(this.netname, " found a touchable controlpoint at ", vtos(cp.origin) ,"\n"));
found = false;
// Look for auto generated waypoint
{
if(wp.classname=="waypoint")
{
- navigation_routerating(wp, ratingscale, 10000);
+ navigation_routerating(this, wp, ratingscale, 10000);
found = true;
}
}
// Nothing found, rate the controlpoint itself
if (!found)
- navigation_routerating(cp, ratingscale, 10000);
+ navigation_routerating(this, cp, ratingscale, 10000);
}
}
-bool havocbot_goalrating_ons_generator_attack(float ratingscale)
-{SELFPARAM();
+bool havocbot_goalrating_ons_generator_attack(entity this, float ratingscale)
+{
entity g, wp, bestwp;
bool found;
int best;
for(g = ons_worldgeneratorlist; g; g = g.ons_worldgeneratornext)
{
- if(SAME_TEAM(g, self) || g.isshielded)
+ if(SAME_TEAM(g, this) || g.isshielded)
continue;
// Should be attacked
if(bestwp)
{
LOG_DEBUG("waypoints found around generator\n");
- navigation_routerating(bestwp, ratingscale, 10000);
+ navigation_routerating(this, bestwp, ratingscale, 10000);
bestwp.cnt += 1;
- self.havocbot_attack_time = 0;
- if(checkpvs(self.view_ofs,g))
- if(checkpvs(self.view_ofs,bestwp))
- self.havocbot_attack_time = time + 5;
+ this.havocbot_attack_time = 0;
+ if(checkpvs(this.view_ofs,g))
+ if(checkpvs(this.view_ofs,bestwp))
+ this.havocbot_attack_time = time + 5;
return true;
}
{
LOG_DEBUG("generator found without waypoints around\n");
// if there aren't waypoints near the generator go straight to it
- navigation_routerating(g, ratingscale, 10000);
- self.havocbot_attack_time = 0;
+ navigation_routerating(this, g, ratingscale, 10000);
+ this.havocbot_attack_time = 0;
return true;
}
}
return false;
}
-void havocbot_role_ons_offense()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_ons_offense(entity this)
+{
+ if(IS_DEAD(this))
{
- self.havocbot_attack_time = 0;
- havocbot_ons_reset_role(self);
+ this.havocbot_attack_time = 0;
+ havocbot_ons_reset_role(this);
return;
}
// Set the role timeout if necessary
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + 120;
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + 120;
- if (time > self.havocbot_role_timeout)
+ if (time > this.havocbot_role_timeout)
{
- havocbot_ons_reset_role(self);
+ havocbot_ons_reset_role(this);
return;
}
- if(self.havocbot_attack_time>time)
+ if(this.havocbot_attack_time>time)
return;
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- navigation_goalrating_start();
- havocbot_goalrating_enemyplayers(20000, self.origin, 650);
- if(!havocbot_goalrating_ons_generator_attack(20000))
- havocbot_goalrating_ons_controlpoints_attack(20000);
- havocbot_goalrating_ons_offenseitems(10000, self.origin, 10000);
- navigation_goalrating_end();
+ navigation_goalrating_start(this);
+ havocbot_goalrating_enemyplayers(this, 20000, this.origin, 650);
+ if(!havocbot_goalrating_ons_generator_attack(this, 20000))
+ havocbot_goalrating_ons_controlpoints_attack(this, 20000);
+ havocbot_goalrating_ons_offenseitems(this, 10000, this.origin, 10000);
+ navigation_goalrating_end(this);
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
}
}
-void havocbot_role_ons_assistant()
-{SELFPARAM();
- havocbot_ons_reset_role(self);
+void havocbot_role_ons_assistant(entity this)
+{
+ havocbot_ons_reset_role(this);
}
-void havocbot_role_ons_defense()
-{SELFPARAM();
- havocbot_ons_reset_role(self);
+void havocbot_role_ons_defense(entity this)
+{
+ havocbot_ons_reset_role(this);
}
-void havocbot_ons_reset_role(entity bot)
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_ons_reset_role(entity this)
+{
+ if(IS_DEAD(this))
return;
- bot.havocbot_ons_target = world;
+ this.havocbot_ons_target = world;
// TODO: Defend control points or generator if necessary
- havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE);
+ havocbot_role_ons_setrole(this, HAVOCBOT_ONS_ROLE_OFFENSE);
}
}
MUTATOR_HOOKFUNCTION(ons, PlayerDies)
-{SELFPARAM();
+{
frag_target.ons_deathloc = frag_target.origin;
entity l;
for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext)
MUTATOR_HOOKFUNCTION(ons, SendWaypoint)
{
+ SELFPARAM();
if(wp_sendflags & 16)
{
if(self.owner.classname == "onslaught_controlpoint")
MUTATOR_HOOKFUNCTION(ons, TurretThink)
{
+ SELFPARAM();
// ONS uses somewhat backwards linking.
if(self.target)
{
ATTRIB(GameItem, m_color, vector, '1 1 1')
ATTRIB(GameItem, m_waypoint, string, string_null)
ATTRIB(GameItem, m_waypointblink, int, 1)
- METHOD(GameItem, display, void(GameItem this, void(string name, string icon) returns)) {
+ METHOD(GameItem, display, void(GameItem this, void(string name, string icon) returns))
+ {
+ TC(GameItem, this);
returns(this.m_name, this.m_icon ? sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.m_icon) : string_null);
}
- METHOD(GameItem, show, void(GameItem this)) { LOG_INFO("A game item\n"); }
+ METHOD(GameItem, show, void(GameItem this))
+ {
+ TC(GameItem, this);
+ LOG_INFO("A game item\n");
+ }
void ITEM_HANDLE(Show, GameItem this) { this.show(this); }
ENDCLASS(GameItem)
ATTRIB(Pickup, m_sound, Sound, SND_ITEMPICKUP)
#endif
ATTRIB(Pickup, m_name, string, string_null)
- METHOD(Pickup, show, void(Pickup this)) { LOG_INFOF("%s: %s\n", etos(this), this.m_name); }
+ METHOD(Pickup, show, void(Pickup this))
+ {
+ TC(Pickup, this);
+ LOG_INFOF("%s: %s\n", etos(this), this.m_name);
+ }
#ifdef SVQC
ATTRIB(Pickup, m_mins, vector, '-16 -16 0')
ATTRIB(Pickup, m_maxs, vector, '16 16 32')
float Item_GiveTo(entity item, entity player);
METHOD(Pickup, giveTo, bool(Pickup this, entity item, entity player))
{
+ TC(Pickup, this);
bool b = Item_GiveTo(item, player);
if (b) {
LOG_TRACEF("entity %i picked up %s\n", player, this.m_name);
ATTRIB(Gametype, m_mutators, string, string_null)
ATTRIB(Gametype, m_parse_mapinfo, bool(string k, string v), func_null)
- METHOD(Gametype, describe, string(entity this)) { return this.gametype_description; }
+ METHOD(Gametype, describe, string(Gametype this))
+ {
+ TC(Gametype, this);
+ return this.gametype_description;
+ }
- METHOD(Gametype, display, void(entity this, void(string name, string icon) returns)) {
+ METHOD(Gametype, display, void(Gametype this, void(string name, string icon) returns))
+ {
+ TC(Gametype, this);
returns(this.message, strcat("gametype_", this.mdl));
}
void name##_hud_board(vector, vector); \
void name##_hud_status(vector, vector); \
int name##_client_event(entity, string, ...); \
- REGISTER_INIT_POST(MINIGAME_##name) { \
+ REGISTER_INIT(MINIGAME_##name) { \
this.netname = strzone(strtolower(#name)); \
this.message = nicename; \
this.minigame_hud_board = name##_hud_board; \
void snake_move_head(entity minigame, entity head);
void snake_head_think()
{
+ SELFPARAM();
entity minigame = self.owner;
if(minigame.minigame_flags & SNAKE_TURN_MOVE)
#define REGISTER_MINIGAME(name,nicename) \
REGISTER(Minigames, MINIGAME_##name, m_id, new_pure(minigame_descriptor)); \
int name##_server_event(entity, string, ...); \
- REGISTER_INIT_POST(MINIGAME_##name) { \
+ REGISTER_INIT(MINIGAME_##name) { \
this.netname = strzone(strtolower(#name)); \
this.message = nicename; \
this.minigame_event = name##_server_event; \
CONSTRUCT(Model);
this.model_str = path;
}
- METHOD(Model, model_precache, void(entity this)) {
+ METHOD(Model, model_precache, void(Model this))
+ {
+ TC(Model, this);
string s = this.model_str();
if (s != "" && s != "null" && !fexists(s)) {
LOG_WARNINGF("Missing model: \"%s\"\n", s);
ATTRIB(Monster, maxs, vector, '0 0 0')
/** (SERVER) setup monster data */
- METHOD(Monster, mr_setup, bool(Monster this, entity actor)) { return false; }
+ METHOD(Monster, mr_setup, bool(Monster this, entity actor)) { TC(Monster, this); return false; }
/** (SERVER) logic to run every frame */
- METHOD(Monster, mr_think, bool(Monster this, entity actor)) { return false; }
+ METHOD(Monster, mr_think, bool(Monster this, entity actor)) { TC(Monster, this); return false; }
/** (SERVER) called when monster dies */
- METHOD(Monster, mr_death, bool(Monster this, entity actor)) { return false; }
+ METHOD(Monster, mr_death, bool(Monster this, entity actor)) { TC(Monster, this); return false; }
/** (BOTH) precaches models/sounds used by this monster */
- METHOD(Monster, mr_precache, bool(Monster this)) { return false; }
+ METHOD(Monster, mr_precache, bool(Monster this)) { TC(Monster, this); return false; }
/** (SERVER) called when monster is damaged */
- METHOD(Monster, mr_pain, bool(Monster this, entity actor)) { return false; }
+ METHOD(Monster, mr_pain, bool(Monster this, entity actor)) { TC(Monster, this); return false; }
/** (BOTH?) sets animations for monster */
- METHOD(Monster, mr_anim, bool(Monster this, entity actor)) { return false; }
+ METHOD(Monster, mr_anim, bool(Monster this, entity actor)) { TC(Monster, this); return false; }
ENDCLASS(Monster)
SOUND(MageSpike_FIRE, W_Sound("electro_fire"));
void M_Mage_Attack_Spike(entity this, vector dir);
void M_Mage_Attack_Push(entity this);
-METHOD(MageSpike, wr_think, void(MageSpike thiswep, entity actor, .entity weaponentity, int fire)) {
+METHOD(MageSpike, wr_think, void(MageSpike thiswep, entity actor, .entity weaponentity, int fire))
+{
+ TC(MageSpike, thiswep);
if (fire & 1)
if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, weaponentity, false, 0.2)) {
if (!actor.target_range) actor.target_range = autocvar_g_monsters_target_range;
actor.enemy = Monster_FindTarget(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(MageSpike_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_MageSpike_FIRE, CH_WEAPON_B, 0);
if (!IS_PLAYER(actor)) w_shotdir = normalize((actor.enemy.origin + '0 0 10') - actor.origin);
M_Mage_Attack_Spike(actor, w_shotdir);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, w_ready);
.bool OffhandMageTeleport_key_pressed;
METHOD(OffhandMageTeleport, offhand_think, void(OffhandMageTeleport this, entity player, bool key_pressed))
{
+ TC(OffhandMageTeleport, this);
if (key_pressed && !player.OffhandMageTeleport_key_pressed)
M_Mage_Attack_Teleport(player, player.enemy);
player.OffhandMageTeleport_key_pressed = key_pressed;
void M_Mage_Attack_Spike_Touch()
{
+ SELFPARAM();
PROJECTILE_TOUCH;
M_Mage_Attack_Spike_Explode(self);
#ifdef SVQC
METHOD(Mage, mr_think, bool(Mage thismon, entity actor))
{
+ TC(Mage, thismon);
bool need_help = false;
FOREACH_ENTITY_FLOAT(iscreature, true,
return true;
}
-METHOD(Mage, mr_pain, bool(Mage thismon, entity actor))
+METHOD(Mage, mr_pain, bool(Mage this, entity actor))
{
+ TC(Mage, this);
return true;
}
-METHOD(Mage, mr_death, bool(Mage thismon, entity actor))
+METHOD(Mage, mr_death, bool(Mage this, entity actor))
{
+ TC(Mage, this);
setanim(actor, actor.anim_die1, false, true, true);
return true;
}
#endif
#ifndef MENUQC
-METHOD(Mage, mr_anim, bool(Mage thismon, entity actor))
+METHOD(Mage, mr_anim, bool(Mage this, entity actor))
{
+ TC(Mage, this);
vector none = '0 0 0';
actor.anim_die1 = animfixfps(actor, '4 1 0.5', none); // 2 seconds
actor.anim_walk = animfixfps(actor, '1 1 1', none);
#ifdef SVQC
.float speed;
spawnfunc(item_health_large);
-METHOD(Mage, mr_setup, bool(Mage thismon, entity actor))
+METHOD(Mage, mr_setup, bool(Mage this, entity actor))
{
+ TC(Mage, this);
if(!actor.health) actor.health = (autocvar_g_monster_mage_health);
if(!actor.speed) { actor.speed = (autocvar_g_monster_mage_speed_walk); }
if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_mage_speed_run); }
return true;
}
-METHOD(Mage, mr_precache, bool(Mage thismon))
+METHOD(Mage, mr_precache, bool(Mage this))
{
+ TC(Mage, this);
return true;
}
#endif
#endif // SVQC
#ifdef SVQC
-METHOD(Shambler, mr_think, bool(Shambler thismon, entity actor))
+METHOD(Shambler, mr_think, bool(Shambler this, entity actor))
{
+ TC(Shambler, this);
return true;
}
-METHOD(Shambler, mr_pain, bool(Shambler thismon, entity actor))
+METHOD(Shambler, mr_pain, bool(Shambler this, entity actor))
{
+ TC(Shambler, this);
actor.pain_finished = time + 0.5;
setanim(actor, actor.anim_pain1, true, true, false);
return true;
}
-METHOD(Shambler, mr_death, bool(Shambler thismon, entity actor))
+METHOD(Shambler, mr_death, bool(Shambler this, entity actor))
{
+ TC(Shambler, this);
setanim(actor, actor.anim_die1, false, true, true);
return true;
}
#endif
#ifndef MENUQC
-METHOD(Shambler, mr_anim, bool(Shambler thismon, entity actor))
+METHOD(Shambler, mr_anim, bool(Shambler this, entity actor))
{
+ TC(Shambler, this);
vector none = '0 0 0';
actor.anim_die1 = animfixfps(actor, '8 1 0.5', none); // 2 seconds
actor.anim_walk = animfixfps(actor, '1 1 1', none);
#ifdef SVQC
spawnfunc(item_health_mega);
.float animstate_endtime;
-METHOD(Shambler, mr_setup, bool(Shambler thismon, entity actor))
+METHOD(Shambler, mr_setup, bool(Shambler this, entity actor))
{
+ TC(Shambler, this);
if(!actor.health) actor.health = (autocvar_g_monster_shambler_health);
if(!actor.attack_range) actor.attack_range = 150;
if(!actor.speed) { actor.speed = (autocvar_g_monster_shambler_speed_walk); }
return true;
}
-METHOD(Shambler, mr_precache, bool(Shambler thismon))
+METHOD(Shambler, mr_precache, bool(Shambler this))
{
+ TC(Shambler, this);
return true;
}
#endif
MUTATOR_HOOKFUNCTION(spiderweb, PlayerPhysics)
{
+ SELFPARAM();
if (time >= self.spider_slowness)
return false;
PHYS_MAXSPEED(self) *= 0.5; // half speed while slow from spider
MUTATOR_HOOKFUNCTION(spiderweb, MonsterMove)
{
+ SELFPARAM();
if(time < self.spider_slowness)
{
monster_speed_run *= 0.5;
MUTATOR_HOOKFUNCTION(spiderweb, PlayerSpawn)
{
+ SELFPARAM();
self.spider_slowness = 0;
return false;
}
MUTATOR_HOOKFUNCTION(spiderweb, MonsterSpawn)
{
+ SELFPARAM();
self.spider_slowness = 0;
return false;
}
SOUND(SpiderAttack_FIRE, W_Sound("electro_fire"));
-METHOD(SpiderAttack, wr_think, void(SpiderAttack thiswep, entity actor, .entity weaponentity, int fire)) {
+METHOD(SpiderAttack, wr_think, void(SpiderAttack thiswep, entity actor, .entity weaponentity, int fire))
+{
+ SELFPARAM();
+ TC(SpiderAttack, thiswep);
bool isPlayer = IS_PLAYER(actor);
if (fire & 1)
if ((!isPlayer && time >= actor.spider_web_delay) || weapon_prepareattack(thiswep, actor, weaponentity, false, autocvar_g_monster_spider_attack_web_delay)) {
actor.anim_finished = time + 1;
}
if (isPlayer) actor.enemy = Monster_FindTarget(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(SpiderAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_SpiderAttack_FIRE, CH_WEAPON_B, 0);
if (!isPlayer) w_shotdir = normalize((actor.enemy.origin + '0 0 10') - actor.origin);
M_Spider_Attack_Web(actor);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, w_ready);
#endif // SVQC
#ifdef SVQC
-METHOD(Spider, mr_think, bool(Spider thismon, entity actor))
+METHOD(Spider, mr_think, bool(Spider this, entity actor))
{
+ TC(Spider, this);
return true;
}
-METHOD(Spider, mr_pain, bool(Spider thismon, entity actor))
+METHOD(Spider, mr_pain, bool(Spider this, entity actor))
{
+ TC(Spider, this);
return true;
}
-METHOD(Spider, mr_death, bool(Spider thismon, entity actor))
+METHOD(Spider, mr_death, bool(Spider this, entity actor))
{
+ TC(Spider, this);
setanim(actor, actor.anim_melee, false, true, true);
actor.angles_x = 180;
return true;
}
#endif
#ifndef MENUQC
-METHOD(Spider, mr_anim, bool(Spider thismon, entity actor))
+METHOD(Spider, mr_anim, bool(Spider this, entity actor))
{
+ TC(Spider, this);
vector none = '0 0 0';
actor.anim_walk = animfixfps(actor, '1 1 1', none);
actor.anim_idle = animfixfps(actor, '0 1 1', none);
#endif
#ifdef SVQC
spawnfunc(item_health_medium);
-METHOD(Spider, mr_setup, bool(Spider thismon, entity actor))
+METHOD(Spider, mr_setup, bool(Spider this, entity actor))
{
+ TC(Spider, this);
if(!actor.health) actor.health = (autocvar_g_monster_spider_health);
if(!actor.speed) { actor.speed = (autocvar_g_monster_spider_speed_walk); }
if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_spider_speed_run); }
return true;
}
-METHOD(Spider, mr_precache, bool(Spider thismon))
+METHOD(Spider, mr_precache, bool(Spider this))
{
+ TC(Spider, this);
return true;
}
#endif
void M_Wyvern_Attack_Fireball_Touch();
SOUND(WyvernAttack_FIRE, W_Sound("electro_fire"));
-METHOD(WyvernAttack, wr_think, void(WyvernAttack thiswep, entity actor, .entity weaponentity, int fire)) {
+METHOD(WyvernAttack, wr_think, void(WyvernAttack thiswep, entity actor, .entity weaponentity, int fire))
+{
+ TC(WyvernAttack, thiswep);
if (fire & 1)
if (time > actor.attack_finished_single[0] || weapon_prepareattack(thiswep, actor, weaponentity, false, 1.2)) {
- if (IS_PLAYER(actor)) W_SetupShot_Dir(actor, v_forward, false, 0, SND(WyvernAttack_FIRE), CH_WEAPON_B, 0);
+ if (IS_PLAYER(actor)) W_SetupShot_Dir(actor, v_forward, false, 0, SND_WyvernAttack_FIRE, CH_WEAPON_B, 0);
if (IS_MONSTER(actor)) {
actor.attack_finished_single[0] = time + 1.2;
actor.anim_finished = time + 1.2;
}
}
-METHOD(WyvernAttack, wr_checkammo1, bool(WyvernAttack thiswep)) {
+METHOD(WyvernAttack, wr_checkammo1, bool(WyvernAttack this)) {
+ TC(WyvernAttack, this);
return true;
}
#endif // SVQC
#ifdef SVQC
-METHOD(Wyvern, mr_think, bool(Wyvern thismon, entity actor))
+METHOD(Wyvern, mr_think, bool(Wyvern this, entity actor))
{
+ TC(Wyvern, this);
return true;
}
-METHOD(Wyvern, mr_pain, bool(Wyvern thismon, entity actor))
+METHOD(Wyvern, mr_pain, bool(Wyvern this, entity actor))
{
+ TC(Wyvern, this);
actor.pain_finished = time + 0.5;
setanim(actor, actor.anim_pain1, true, true, false);
return true;
}
-METHOD(Wyvern, mr_death, bool(Wyvern thismon, entity actor))
+METHOD(Wyvern, mr_death, bool(Wyvern this, entity actor))
{
+ TC(Wyvern, this);
setanim(actor, actor.anim_die1, false, true, true);
actor.velocity_x = -200 + 400 * random();
actor.velocity_y = -200 + 400 * random();
}
#endif
#ifndef MENUQC
-METHOD(Wyvern, mr_anim, bool(Wyvern thismon, entity actor))
+METHOD(Wyvern, mr_anim, bool(Wyvern this, entity actor))
{
+ TC(Wyvern, this);
vector none = '0 0 0';
actor.anim_die1 = animfixfps(actor, '4 1 0.5', none); // 2 seconds
actor.anim_walk = animfixfps(actor, '1 1 1', none);
#endif
#ifdef SVQC
spawnfunc(item_cells);
-METHOD(Wyvern, mr_setup, bool(Wyvern thismon, entity actor))
+METHOD(Wyvern, mr_setup, bool(Wyvern this, entity actor))
{
+ TC(Wyvern, this);
if(!actor.health) actor.health = (autocvar_g_monster_wyvern_health);
if(!actor.speed) { actor.speed = (autocvar_g_monster_wyvern_speed_walk); }
if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_wyvern_speed_run); }
return true;
}
-METHOD(Wyvern, mr_precache, bool(Wyvern thismon))
+METHOD(Wyvern, mr_precache, bool(Wyvern this))
{
+ TC(Wyvern, this);
return true;
}
#endif
#endif // SVQC
#ifdef SVQC
-METHOD(Zombie, mr_think, bool(Zombie thismon, entity actor))
+METHOD(Zombie, mr_think, bool(Zombie this, entity actor))
{
+ TC(Zombie, this);
if(time >= actor.spawn_time)
actor.damageforcescale = autocvar_g_monster_zombie_damageforcescale;
return true;
}
-METHOD(Zombie, mr_pain, bool(Zombie thismon, entity actor))
+METHOD(Zombie, mr_pain, bool(Zombie this, entity actor))
{
+ TC(Zombie, this);
actor.pain_finished = time + 0.34;
setanim(actor, ((random() > 0.5) ? actor.anim_pain1 : actor.anim_pain2), true, true, false);
return true;
}
-METHOD(Zombie, mr_death, bool(Zombie thismon, entity actor))
+METHOD(Zombie, mr_death, bool(Zombie this, entity actor))
{
+ TC(Zombie, this);
actor.armorvalue = autocvar_g_monsters_armor_blockpercent;
setanim(actor, ((random() > 0.5) ? actor.anim_die1 : actor.anim_die2), false, true, true);
}
#endif
#ifndef MENUQC
-METHOD(Zombie, mr_anim, bool(Zombie thismon, entity actor))
+METHOD(Zombie, mr_anim, bool(Zombie this, entity actor))
{
+ TC(Zombie, this);
vector none = '0 0 0';
actor.anim_die1 = animfixfps(actor, '9 1 0.5', none); // 2 seconds
actor.anim_die2 = animfixfps(actor, '12 1 0.5', none); // 2 seconds
}
#endif
#ifdef SVQC
-METHOD(Zombie, mr_setup, bool(Zombie thismon, entity actor))
+METHOD(Zombie, mr_setup, bool(Zombie this, entity actor))
{
+ TC(Zombie, this);
if(!actor.health) actor.health = (autocvar_g_monster_zombie_health);
if(!actor.speed) { actor.speed = (autocvar_g_monster_zombie_speed_walk); }
if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_zombie_speed_run); }
return true;
}
-METHOD(Zombie, mr_precache, bool(Zombie thismon))
+METHOD(Zombie, mr_precache, bool(Zombie this))
{
+ TC(Zombie, this);
return true;
}
#endif
#include <server/defs.qh>
#endif
entity spawnmonster (string monster, float monster_id, entity spawnedby, entity own, vector orig, float respwn, float invincible, float moveflag)
-{SELFPARAM();
+{
float i;
entity e = spawn();
void Monster_Delay_Action_self()
{
+ SELFPARAM();
Monster_Delay_Action(self);
}
#define _MUTATOR_HANDLE_NOP(type, id)
#define _MUTATOR_HANDLE_PARAMS(type, id) , type in_##id
#define _MUTATOR_HANDLE_PREPARE(type, id) id = in_##id;
-#define _MUTATOR_HANDLE_PUSHTMP(type, id) type tmp_##id = id;
+#define _MUTATOR_HANDLE_PUSHTMP(type, id) TC(type, id); type tmp_##id = id;
#define _MUTATOR_HANDLE_PUSHOUT(type, id) type out_##id = id;
#define _MUTATOR_HANDLE_POPTMP(type, id) id = tmp_##id;
#define _MUTATOR_HANDLE_POPOUT(type, id) id = out_##id;
MUTATOR_ROLLING_BACK
};
-typedef bool(int) mutatorfunc_t;
+USING(mutatorfunc_t, bool(int));
CLASS(Mutator, Object)
ATTRIB(Mutator, m_id, int, 0)
REGISTRY_CHECK(Buffs)
#define REGISTER_BUFF(id) \
- REGISTER(Buffs, BUFF_##id, m_id, NEW(Buff)); \
- REGISTER_INIT_POST(BUFF_##id) { \
- this.netname = this.m_name; \
- this.m_itemid = BIT(this.m_id - 1); \
- this.m_sprite = strzone(strcat("buff-", this.m_name)); \
- } \
- REGISTER_INIT(BUFF_##id)
+ REGISTER(Buffs, BUFF_##id, m_id, NEW(Buff))
#include <common/items/item/pickup.qh>
CLASS(Buff, Pickup)
#endif
ENDCLASS(Buff)
+STATIC_INIT(REGISTER_BUFFS) {
+ FOREACH(Buffs, true, {
+ it.netname = it.m_name; \
+ it.m_itemid = BIT(it.m_id - 1); \
+ it.m_sprite = strzone(strcat("buff-", it.m_name)); \
+ });
+}
+
#ifdef SVQC
// .int buffs = _STAT(BUFFS);
void buff_Init(entity ent);
return false;
}
-MUTATOR_HOOKFUNCTION(buffs, MakePlayerObserver) { return buffs_RemovePlayer(self); }
-MUTATOR_HOOKFUNCTION(buffs, ClientDisconnect) { return buffs_RemovePlayer(self); }
+MUTATOR_HOOKFUNCTION(buffs, MakePlayerObserver) { SELFPARAM(); return buffs_RemovePlayer(self); }
+MUTATOR_HOOKFUNCTION(buffs, ClientDisconnect) { SELFPARAM(); return buffs_RemovePlayer(self); }
MUTATOR_HOOKFUNCTION(buffs, CustomizeWaypoint)
{SELFPARAM();
#endif
MUTATOR_HOOKFUNCTION(bugrigs, PM_Physics)
{
+ SELFPARAM();
if(!PHYS_BUGRIGS(self) || !IS_PLAYER(self)) { return false; }
#ifdef SVQC
MUTATOR_HOOKFUNCTION(bugrigs, PlayerPhysics)
{
+#ifdef SVQC
+ SELFPARAM();
+#endif
if(!PHYS_BUGRIGS(self)) { return false; }
#ifdef SVQC
self.bugrigs_prevangles = self.angles;
MUTATOR_HOOKFUNCTION(bugrigs, ClientConnect)
{
+ SELFPARAM();
stuffcmd(self, "cl_cmd settemp chase_active 1\n");
return false;
}
MUTATOR_HOOKFUNCTION(dodging, PlayerPhysics)
{
+ SELFPARAM();
// print("dodging_PlayerPhysics\n");
PM_dodging_GetPressedKeys(self);
PM_dodging(self);
MUTATOR_HOOKFUNCTION(dodging, GetPressedKeys)
{
+ SELFPARAM();
PM_dodging_checkpressedkeys(self);
return false;
}
MUTATOR_HOOKFUNCTION(doublejump, PlayerJump)
{
+ SELFPARAM();
if (PHYS_DOUBLEJUMP(self))
{
tracebox(self.origin + '0 0 0.01', self.mins, self.maxs, self.origin - '0 0 0.01', MOVE_NORMAL, self);
MUTATOR_HOOKFUNCTION(hook, FilterItem)
{
+ SELFPARAM();
return self.weapon == WEP_HOOK.m_id;
}
if (self.items & ITEM_Invisibility.m_itemid)
{
- play_countdown(self.strength_finished, SND(POWEROFF));
+ play_countdown(self.strength_finished, SND_POWEROFF);
if (time > self.strength_finished)
{
self.alpha = default_player_alpha;
if (self.items & ITEM_Speed.m_itemid)
{
- play_countdown(self.invincible_finished, SND(POWEROFF));
+ play_countdown(self.invincible_finished, SND_POWEROFF);
if (time > self.invincible_finished)
{
self.items &= ~ITEM_Speed.m_itemid;
}
MUTATOR_HOOKFUNCTION(itemstime, reset_map_global)
-{SELFPARAM();
+{
Item_ItemsTime_ResetTimes();
// ALL the times need to be reset before .reset()ing each item
// since Item_Reset schedules respawn of superweapons and powerups
id = it.m_id;
icon = it.m_icon;
- :iteration
+LABEL(iteration)
float item_time = ItemsTime_time[id];
if (item_time < -1)
{
.float midair_shieldtime;
MUTATOR_HOOKFUNCTION(midair, PlayerDamage_Calculate)
-{SELFPARAM();
+{
if(IS_PLAYER(frag_attacker))
if(IS_PLAYER(frag_target))
if(time < frag_target.midair_shieldtime)
MUTATOR_HOOKFUNCTION(multijump, PlayerPhysics)
{
+ SELFPARAM();
#ifdef CSQC
self.multijump_count = PHYS_MULTIJUMP_COUNT(self);
#endif
MUTATOR_HOOKFUNCTION(multijump, PlayerJump)
{
+ SELFPARAM();
return PM_multijump_checkjump(self);
}
}
MUTATOR_HOOKFUNCTION(cl_nades, Ent_Projectile)
{
+ SELFPARAM();
if (self.cnt == PROJECTILE_NAPALM_FOUNTAIN)
{
self.modelindex = 0;
}
MUTATOR_HOOKFUNCTION(cl_nades, EditProjectile)
{
+ SELFPARAM();
if (self.cnt == PROJECTILE_NAPALM_FOUNTAIN)
{
loopsound(self, CH_SHOTS_SINGLE, SND(FIREBALL_FLY2), VOL_BASE, ATTEN_NORM);
makevectors(e.v_angle);
- W_SetupShot(e, false, false, "", CH_WEAPON_A, 0);
+ W_SetupShot(e, false, false, SND_Null, CH_WEAPON_A, 0);
Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER, CPID_NADES);
MUTATOR_HOOKFUNCTION(nades, PutClientInServer)
{
+ SELFPARAM();
nades_RemoveBonus(self);
}
MUTATOR_HOOKFUNCTION(nades, ForbidThrowCurrentWeapon, CBC_ORDER_LAST)
{
+ SELFPARAM();
if (self.offhand != OFFHAND_NADE || (self.weapons & WEPSET(HOOK)) || autocvar_g_nades_override_dropweapon) {
nades_CheckThrow();
return true;
REGISTER_MUTATOR(nix, cvar("g_nix") && !cvar("g_instagib") && !cvar("g_overkill"))
{
+ SELFPARAM();
MUTATOR_ONADD
{
g_nix_with_blaster = autocvar_g_nix_with_blaster;
MUTATOR_ONREMOVE
{
// as the PlayerSpawn hook will no longer run, NIX is turned off by this!
- FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it), LAMBDA(
+ FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it), {
it.ammo_cells = start_ammo_cells;
it.ammo_plasma = start_ammo_plasma;
it.ammo_shells = start_ammo_shells;
it.weapons = start_weapons;
if(!client_hasweapon(it, PS(it).m_weapon, true, false))
PS(it).m_switchweapon = w_getbestweapon(self);
- ));
+ });
}
return 0;
REGISTER_MUTATOR(hmg_nadesupport, true);
MUTATOR_HOOKFUNCTION(hmg_nadesupport, Nade_Damage)
{
+ SELFPARAM();
if (MUTATOR_ARGV(0, entity) != WEP_HMG) return;
return = true;
MUTATOR_ARGV(0, float) /* damage */ = self.max_health * 0.1;
void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity, int fire)
{
+ SELFPARAM();
if (!PHYS_INPUT_BUTTON_ATCK(actor))
{
w_ready(thiswep, actor, weaponentity, fire);
W_DecreaseAmmo(WEP_HMG, self, WEP_CVAR(hmg, ammo));
- W_SetupShot (actor, true, 0, SND(UZI_FIRE), CH_WEAPON_A, WEP_CVAR(hmg, damage));
+ W_SetupShot (actor, true, 0, SND_UZI_FIRE, CH_WEAPON_A, WEP_CVAR(hmg, damage));
if(!autocvar_g_norecoil)
{
METHOD(HeavyMachineGun, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
if(vdist(self.origin - self.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, 1000000, 0, 0.001, false);
else
- PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(self, 1000000, 0, 0.001, false);
}
METHOD(HeavyMachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
METHOD(HeavyMachineGun, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo);
if(autocvar_g_balance_hmg_reload_ammo)
METHOD(HeavyMachineGun, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo);
if(autocvar_g_balance_hmg_reload_ammo)
METHOD(HeavyMachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, WEP_CVAR(hmg, ammo), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, WEP_CVAR(hmg, ammo), SND_RELOAD);
}
METHOD(HeavyMachineGun, wr_suicidemessage, Notification(entity thiswep))
METHOD(HeavyMachineGun, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 2;
pointparticles(EFFECT_MACHINEGUN_IMPACT, org2, w_backoff * 1000, 1);
entity flash = spawn ();
W_DecreaseAmmo(thiswep, self, WEP_CVAR(rpc, ammo));
- W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', false, 5, SND(ROCKET_FIRE), CH_WEAPON_A, WEP_CVAR(rpc, damage));
+ W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', false, 5, SND_ROCKET_FIRE, CH_WEAPON_A, WEP_CVAR(rpc, damage));
Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
PROJECTILE_MAKETRIGGER(missile);
METHOD(RocketPropelledChainsaw, wr_aim, void(entity thiswep))
{
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(rpc, speed), 0, WEP_CVAR(rpc, lifetime), false);
+ SELFPARAM();
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR(rpc, speed), 0, WEP_CVAR(rpc, lifetime), false);
}
METHOD(RocketPropelledChainsaw, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
METHOD(RocketPropelledChainsaw, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(rpc, ammo);
ammo_amount += self.(weapon_load[WEP_RPC.m_id]) >= WEP_CVAR(rpc, ammo);
return ammo_amount;
METHOD(RocketPropelledChainsaw, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, WEP_CVAR(rpc, ammo), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, WEP_CVAR(rpc, ammo), SND_RELOAD);
}
METHOD(RocketPropelledChainsaw, wr_suicidemessage, Notification(entity thiswep))
METHOD(RocketPropelledChainsaw, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 12;
pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1);
MUTATOR_HOOKFUNCTION(superspec, PlayerDies)
{
+ SELFPARAM();
FOREACH_CLIENT(IS_SPEC(it), LAMBDA(
setself(it);
if(self.autospec_flags & ASF_FOLLOWKILLER && IS_PLAYER(frag_attacker) && self.enemy == frag_target)
CASE(CPID, LAST)
ENUMCLASS_END(CPID)
-typedef entity Notification;
+USING(Notification, entity);
// used for notification system multi-team identifiers
#define APP_TEAM_NUM(num, prefix) ((num == NUM_TEAM_1) ? prefix##_RED : ((num == NUM_TEAM_2) ? prefix##_BLUE : ((num == NUM_TEAM_3) ? prefix##_YELLOW : prefix##_PINK)))
{
if (playerdemo_read(this))
return;
- WITH(entity, self, this, bot_think());
+ bot_think(this);
}
#endif
else
PM_air(this, buttons_prev, maxspeed_mod);
-:end
+LABEL(end)
if (IS_ONGROUND(this))
this.lastground = time;
return string_null;
#endif
}
- METHOD(Sound, sound_precache, void(entity this))
+ METHOD(Sound, sound_precache, void(Sound this))
{
+ TC(Sound, this);
string s = Sound_fixpath(this);
if (!s) return;
LOG_DEBUGF("precache_sound(\"%s\")\n", s);
bot_clientconnect(this);
}
-void bot_clientdisconnect();
+void bot_clientdisconnect(entity this);
void W_HitPlotClose(entity this);
-void anticheat_report();
+void anticheat_report(entity this);
void playerdemo_shutdown();
void entcs_detach(entity this);
void accuracy_free(entity this);
GetCvars(-1); // free cvars
- bot_clientdisconnect();
+ bot_clientdisconnect(this);
W_HitPlotClose(this);
- anticheat_report();
+ anticheat_report(this);
playerdemo_shutdown();
entcs_detach(this);
accuracy_free(self);
ATTRIB(PlayerState, m_weapon, Weapon, Weapons_from(-1))
METHOD(PlayerState, ps_push, void(PlayerState this, entity cl))
{
+ TC(PlayerState, this);
STAT(ACTIVEWEAPON, cl) = this.m_weapon.m_id;
STAT(SWITCHINGWEAPON, cl) = this.m_switchingweapon.m_id;
STAT(SWITCHWEAPON, cl) = this.m_switchweapon.m_id;
ENDCLASS(PlayerState)
.PlayerState _ps;
-#if NDEBUG
- #define PS(this) (this._ps)
-#else
- PlayerState PS(entity this) { assert(IS_CLIENT(this)); return this._ps; }
-#endif
+#define PS(this) (this._ps)
// TODO: renew on death
void PlayerState_attach(entity this);
return false;
-:YEAH
+LABEL(YEAH)
switch(mode)
{
case ITEM_MODE_FUEL:
player.superweapons_finished = max(player.superweapons_finished, time) + item.superweapons_finished;
}
-:skip
+LABEL(skip)
// always eat teamed entities
if(item.team)
return;
}
- :pickup
+LABEL(pickup)
other.last_pickup = time;
void func_ladder_link()
{
+ SELFPARAM();
self.SendEntity = func_ladder_send;
self.SendFlags = 0xFFFFFF;
//self.model = "null";
void func_ladder_init()
{
+ SELFPARAM();
self.touch = func_ladder_touch;
trigger_init(self);
}
}
WriteShort(MSG_ENTITY, self.cnt);
+ WriteString(MSG_ENTITY, self.mdl);
if(fl & 0x20)
{
WriteShort(MSG_ENTITY, compressShortVector(self.velocity));
spawnfunc(func_pointparticles)
{
- if(this.model != "") _setmodel(this, this.model);
+ if(this.model != "") { precache_model(this.model); _setmodel(this, this.model); }
if(this.noise != "") precache_sound(this.noise);
+ if(this.mdl != "") this.cnt = 0; // use a good handler
if(!this.bgmscriptsustain) this.bgmscriptsustain = 1;
else if(this.bgmscriptsustain < 0) this.bgmscriptsustain = 0;
setorigin(this, this.origin + this.mins);
setsize(this, '0 0 0', this.maxs - this.mins);
}
- if(!this.cnt) this.cnt = _particleeffectnum(this.mdl);
+ //if(!this.cnt) this.cnt = _particleeffectnum(this.mdl);
Net_LinkEntity(this, (this.spawnflags & 4), 0, pointparticles_SendEntity);
{
traceline(p, p + normalize(self.movedir) * 4096, 0, world);
p = trace_endpos;
- __pointparticles(self.cnt, p, trace_plane_normal * vlen(self.movedir) + self.velocity + randomvec() * self.waterlevel, self.count);
+ int eff_num;
+ if(self.cnt)
+ eff_num = self.cnt;
+ else
+ eff_num = _particleeffectnum(self.mdl);
+ __pointparticles(eff_num, p, trace_plane_normal * vlen(self.movedir) + self.velocity + randomvec() * self.waterlevel, self.count);
}
else
{
- __pointparticles(self.cnt, p, self.velocity + randomvec() * self.waterlevel, self.count);
+ int eff_num;
+ if(self.cnt)
+ eff_num = self.cnt;
+ else
+ eff_num = _particleeffectnum(self.mdl);
+ __pointparticles(eff_num, p, self.velocity + randomvec() * self.waterlevel, self.count);
}
if(self.noise != "")
{
if(this.bgmscript)
strunzone(this.bgmscript);
this.bgmscript = string_null;
+ if(this.mdl)
+ strunzone(this.mdl);
+ this.mdl = string_null;
}
NET_HANDLE(ENT_CLIENT_POINTPARTICLES, bool isnew)
if(f & 2)
{
i = ReadCoord(); // density (<0: point, >0: volume)
- if(i && !self.impulse && self.cnt) // self.cnt check is so it only happens if the ent already existed
+ if(i && !self.impulse && (self.cnt || self.mdl)) // self.cnt check is so it only happens if the ent already existed
self.just_toggled = 1;
self.impulse = i;
}
}
self.cnt = ReadShort(); // effect number
+ self.mdl = strzone(ReadString()); // effect string
if(f & 0x20)
{
void train_use()
{
+ SELFPARAM();
self.SUB_NEXTTHINK = self.SUB_LTIME + 1;
self.SUB_THINK = train_next;
self.use = func_null; // not again
void teleport_dest_link()
{SELFPARAM();
- //Net_LinkEntity(self, false, 0, teleport_dest_send);
- //self.SendFlags |= 1; // update
+ Net_LinkEntity(self, false, 0, teleport_dest_send);
+ self.SendFlags |= 1; // update
}
spawnfunc(info_teleport_destination)
void generic_plat_blocked()
-{SELFPARAM();
+{
#ifdef SVQC
+ SELFPARAM();
if(self.dmg && other.takedamage != DAMAGE_NO)
{
if(self.dmgtime2 < time)
.vector move_origin;
void SUB_SETORIGIN(entity s, vector v)
- {SELFPARAM();
+ {
s.move_origin = v;
_Movetype_LinkEdict(s, true);
}
#ifdef SVQC
+void target_push_init(entity this);
+
spawnfunc(target_location)
{
self.classname = "target_location";
// location name in netname
// eventually support: count, teamgame selectors, line of sight?
+
+ target_push_init(this);
}
spawnfunc(info_location)
{
- self.classname = "target_location";
- self.message = self.netname;
+ this.classname = "target_location";
+ this.message = this.netname;
+
+ target_push_init(this);
}
#endif
}
void target_music_kill()
{
+ SELFPARAM();
for(self = world; (self = find(self, classname, "target_music")); )
{
self.volume = 0;
#endif
void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags)
-{SELFPARAM();
+{
entity telefragger;
vector from;
makevectors (to_angles);
#ifdef SVQC
+ SELFPARAM();
if(player.teleportable == TELEPORT_NORMAL) // don't play sounds or show particles for anything that isn't a player, maybe change later to block only observers
{
if(self.pushltime < time) // only show one teleport effect per teleporter per 0.2 seconds, for better fps
void teleport_findtarget()
{
+ SELFPARAM();
int n = 0;
entity e;
for(e = world; (e = find(e, targetname, self.target)); )
}
void WarpZone_PostTeleportPlayer_Callback(entity pl)
-{SELFPARAM();
+{
#ifdef SVQC
makevectors(pl.angles);
Reset_ArcBeam(pl, v_forward);
void trigger_impulse_link()
{
+ SELFPARAM();
trigger_link(self, trigger_impulse_send);
}
void trigger_push_link()
{
+ SELFPARAM();
trigger_link(self, trigger_push_send);
}
WITH(entity, self, this, W_PrepareExplosionByDamage(this.owner, turret_projectile_explode));
}
-entity turret_projectile(string _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim)
+entity turret_projectile(Sound _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim)
{SELFPARAM();
+ TC(Sound, _snd);
entity proj;
- _sound (self, CH_WEAPON_A, _snd, VOL_BASE, ATTEN_NORM);
+ sound (self, CH_WEAPON_A, _snd, VOL_BASE, ATTEN_NORM);
proj = spawn ();
setorigin(proj, self.tur_shotorg);
setsize(proj, '-0.5 -0.5 -0.5' * _size, '0.5 0.5 0.5' * _size);
#ifndef SV_TURRETS_H
#define SV_TURRETS_H
-entity turret_projectile(string _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim);
+entity turret_projectile(Sound _snd, float _size, float _health, float _death, float _proj_type, float _cull, float _cli_anim);
void turret_projectile_explode();
float turret_validate_target(entity e_turret, entity e_target, float validate_flags);
float turret_firecheck();
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire))) {
if (isPlayer) {
turret_initparams(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(EWheelAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_EWheelAttack_FIRE, CH_WEAPON_B, 0);
actor.tur_shotdir_updated = w_shotdir;
actor.tur_shotorg = w_shotorg;
actor.tur_head = actor;
turret_do_updates(actor);
- entity missile = turret_projectile(SND(LASERGUN_FIRE), 1, 0, DEATH_TURRET_EWHEEL.m_id, PROJECTILE_BLASTER, true, true);
+ entity missile = turret_projectile(SND_LASERGUN_FIRE, 1, 0, DEATH_TURRET_EWHEEL.m_id, PROJECTILE_BLASTER, true, true);
missile.missile_flags = MIF_SPLASH;
Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, actor.tur_shotorg, actor.tur_shotdir_updated * 1000, 1);
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire))) {
if (isPlayer) {
turret_initparams(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(FlacAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_FlacAttack_FIRE, CH_WEAPON_B, 0);
actor.tur_shotdir_updated = w_shotdir;
actor.tur_shotorg = w_shotorg;
actor.tur_head = actor;
turret_tag_fire_update();
- entity proj = turret_projectile(SND(HAGAR_FIRE), 5, 0, DEATH_TURRET_FLAC.m_id, PROJECTILE_HAGAR, true, true);
+ entity proj = turret_projectile(SND_HAGAR_FIRE, 5, 0, DEATH_TURRET_FLAC.m_id, PROJECTILE_HAGAR, true, true);
proj.missile_flags = MIF_SPLASH | MIF_PROXY;
proj.think = turret_flac_projectile_think_explode;
proj.nextthink = time + actor.tur_impacttime + (random() * 0.01 - random() * 0.01);
}
METHOD(FusionReactor, tr_think, void(FusionReactor thistur, entity it))
{
+ SELFPARAM();
self.tur_head.avelocity = '0 250 0' * (self.ammo / self.ammo_max);
}
METHOD(FusionReactor, tr_setup, void(FusionReactor this, entity it))
METHOD(Hellion, tr_think, void(Hellion thistur, entity it))
{
+ SELFPARAM();
if (self.tur_head.frame != 0)
self.tur_head.frame += 1;
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire))) {
if (isPlayer) {
turret_initparams(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(HellionAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_HellionAttack_FIRE, CH_WEAPON_B, 0);
actor.tur_shotdir_updated = w_shotdir;
actor.tur_shotorg = w_shotorg;
actor.tur_head = actor;
actor.tur_shotorg = gettaginfo(actor.tur_head, gettagindex(actor.tur_head, "tag_fire2"));
}
- entity missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HELLION.m_id, PROJECTILE_ROCKET, false, false);
+ entity missile = turret_projectile(SND_ROCKET_FIRE, 6, 10, DEATH_TURRET_HELLION.m_id, PROJECTILE_ROCKET, false, false);
te_explosion (missile.origin);
missile.think = turret_hellion_missile_think;
missile.nextthink = time;
METHOD(HunterKiller, tr_think, void(HunterKiller thistur, entity it))
{
+ SELFPARAM();
if (self.tur_head.frame != 0)
self.tur_head.frame = self.tur_head.frame + 1;
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire))) {
if (isPlayer) {
turret_initparams(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(HunterKillerAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_HunterKillerAttack_FIRE, CH_WEAPON_B, 0);
actor.tur_shotdir_updated = w_shotdir;
actor.tur_shotorg = w_shotorg;
actor.tur_head = actor;
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
}
- entity missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HK.m_id, PROJECTILE_ROCKET, false, false);
+ entity missile = turret_projectile(SND_ROCKET_FIRE, 6, 10, DEATH_TURRET_HK.m_id, PROJECTILE_ROCKET, false, false);
te_explosion (missile.origin);
missile.think = turret_hk_missile_think;
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(machinegun, sustained_refire))) {
if (isPlayer) {
turret_initparams(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(MachineGunTurretAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_MachineGunTurretAttack_FIRE, CH_WEAPON_B, 0);
actor.tur_shotdir_updated = w_shotdir;
actor.tur_shotorg = w_shotorg;
actor.tur_head = actor;
METHOD(MLRSTurret, tr_think, void(MLRSTurret thistur, entity it))
{
+ SELFPARAM();
// 0 = full, 6 = empty
self.tur_head.frame = bound(0, 6 - floor(0.1 + self.ammo / self.shot_dmg), 6);
if(self.tur_head.frame < 0)
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(machinegun, sustained_refire))) {
if (isPlayer) {
turret_initparams(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(MLRSTurretAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_MLRSTurretAttack_FIRE, CH_WEAPON_B, 0);
actor.tur_shotdir_updated = w_shotdir;
actor.tur_shotorg = w_shotorg;
actor.tur_head = actor;
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, w_ready);
}
turret_tag_fire_update();
- entity missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_MLRS.m_id, PROJECTILE_ROCKET, true, true);
+ entity missile = turret_projectile(SND_ROCKET_FIRE, 6, 10, DEATH_TURRET_MLRS.m_id, PROJECTILE_ROCKET, true, true);
missile.nextthink = time + max(actor.tur_impacttime,(actor.shot_radius * 2) / actor.shot_speed);
missile.missile_flags = MIF_SPLASH;
te_explosion (missile.origin);
METHOD(PhaserTurret, tr_think, void(PhaserTurret thistur, entity it))
{
+ SELFPARAM();
if (self.tur_head.frame != 0)
{
if (self.fireflag == 1)
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire))) {
if (isPlayer) {
turret_initparams(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(PhaserTurretAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_PhaserTurretAttack_FIRE, CH_WEAPON_B, 0);
actor.tur_shotdir_updated = w_shotdir;
actor.tur_shotorg = w_shotorg;
actor.tur_head = actor;
}
METHOD(PlasmaTurret, tr_think, void(PlasmaTurret thistur, entity it))
{
+ SELFPARAM();
if (self.tur_head.frame != 0)
self.tur_head.frame = self.tur_head.frame + 1;
spawnfunc(turret_plasma_dual) { if (!turret_initialize(TUR_PLASMA_DUAL)) remove(self); }
-METHOD(DualPlasmaTurret, tr_attack, void(DualPlasmaTurret this, entity it))
+METHOD(DualPlasmaTurret, tr_attack, void(DualPlasmaTurret thistur, entity it))
{
+ SELFPARAM();
if (g_instagib) {
FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
800, 0, 0, 0, 0, DEATH_TURRET_PLASMA.m_id);
vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
WarpZone_TrailParticles(world, particleeffectnum(EFFECT_VAPORIZER(self.team)), self.tur_shotorg, v);
} else {
- SUPER(PlasmaTurret).tr_attack(this, it);
+ SUPER(PlasmaTurret).tr_attack(thistur, it);
}
self.tur_head.frame += 1;
}
METHOD(DualPlasmaTurret, tr_think, void(DualPlasmaTurret thistur, entity it))
{
+ SELFPARAM();
if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3))
self.tur_head.frame = self.tur_head.frame + 1;
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire))) {
if (isPlayer) {
turret_initparams(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(PlasmaAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_PlasmaAttack_FIRE, CH_WEAPON_B, 0);
actor.tur_shotdir_updated = w_shotdir;
actor.tur_shotorg = w_shotorg;
actor.tur_head = actor;
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready);
}
- entity missile = turret_projectile(SND(HAGAR_FIRE), 1, 0, DEATH_TURRET_PLASMA.m_id, PROJECTILE_ELECTRO_BEAM, true, true);
+ entity missile = turret_projectile(SND_HAGAR_FIRE, 1, 0, DEATH_TURRET_PLASMA.m_id, PROJECTILE_ELECTRO_BEAM, true, true);
missile.missile_flags = MIF_SPLASH;
Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, actor.tur_shotorg, actor.tur_shotdir_updated * 1000, 1);
}
METHOD(TeslaCoil, tr_think, void(TeslaCoil thistur, entity it))
{
+ SELFPARAM();
if(!self.active)
{
self.tur_head.avelocity = '0 0 0';
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire))) {
if (isPlayer) {
turret_initparams(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(TeslaCoilTurretAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_TeslaCoilTurretAttack_FIRE, CH_WEAPON_B, 0);
actor.tur_shotdir_updated = w_shotdir;
actor.tur_shotorg = w_shotorg;
actor.tur_head = actor;
METHOD(WalkerTurret, tr_think, void(WalkerTurret thistur, entity it))
{
+ SELFPARAM();
fixedmakevectors(self.angles);
if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent)
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire))) {
if (isPlayer) {
turret_initparams(actor);
- W_SetupShot_Dir(actor, v_forward, false, 0, SND(WalkerTurretAttack_FIRE), CH_WEAPON_B, 0);
+ W_SetupShot_Dir(actor, v_forward, false, 0, SND_WalkerTurretAttack_FIRE, CH_WEAPON_B, 0);
actor.tur_shotdir_updated = w_shotdir;
actor.tur_shotorg = w_shotorg;
actor.tur_head = actor;
float boxesoverlap(vector m1, vector m2, vector m3, vector m4);
float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs);
-typedef float(string s, vector size) textLengthUpToWidth_widthFunction_t;
-typedef float(string s) textLengthUpToLength_lenFunction_t;
+USING(textLengthUpToWidth_widthFunction_t, float(string s, vector size));
+USING(textLengthUpToLength_lenFunction_t, float(string s));
float textLengthUpToWidth(string theText, float maxWidth, vector size, textLengthUpToWidth_widthFunction_t tw);
string textShortenToWidth(string theText, float maxWidth, vector size, textLengthUpToWidth_widthFunction_t tw);
float textLengthUpToLength(string theText, float maxWidth, textLengthUpToLength_lenFunction_t tw);
// as it may exceed 0..1 bounds, or go in reverse
float cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor);
-typedef entity(entity cur, entity near, entity pass) findNextEntityNearFunction_t;
-typedef float(entity a, entity b, entity pass) isConnectedFunction_t;
+USING(findNextEntityNearFunction_t, entity(entity cur, entity near, entity pass));
+USING(isConnectedFunction_t, float(entity a, entity b, entity pass));
void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass);
// expand multiple arguments into one argument by stripping parenthesis
float alarm1time;
float alarm2time;
-void vehicle_alarm(entity e, int ch, string s0und)
+void vehicle_alarm(entity e, int ch, Sound s0und)
{
+ TC(Sound, s0und);
if(!autocvar_cl_vehicles_alarm)
return;
- _sound(e, ch, s0und, VOL_BASEVOICE, ATTEN_NONE);
+ sound(e, ch, s0und, VOL_BASEVOICE, ATTEN_NONE);
}
void AuxiliaryXhair_Draw2D(entity this)
if(alarm1time < time)
{
alarm1time = time + 2;
- vehicle_alarm(self, CH_PAIN_SINGLE, SND(VEH_ALARM));
+ vehicle_alarm(self, CH_PAIN_SINGLE, SND_VEH_ALARM);
}
drawpic_skin(tmpPos, "vehicle_icon_health", tmpSize, '1 1 1', hudAlpha * blinkValue, DRAWFLAG_NORMAL);
}
{
if(alarm1time)
{
- vehicle_alarm(self, CH_PAIN_SINGLE, SND(Null));
+ vehicle_alarm(self, CH_PAIN_SINGLE, SND_Null);
alarm1time = 0;
}
drawpic_skin(tmpPos, "vehicle_icon_health", tmpSize, '1 1 1', hudAlpha, DRAWFLAG_NORMAL);
if(alarm2time < time)
{
alarm2time = time + 1;
- vehicle_alarm(self, CH_TRIGGER_SINGLE, SND(VEH_ALARM_SHIELD));
+ vehicle_alarm(self, CH_TRIGGER_SINGLE, SND_VEH_ALARM_SHIELD);
}
drawpic_skin(tmpPos, "vehicle_icon_shield", tmpSize, '1 1 1', hudAlpha * blinkValue, DRAWFLAG_NORMAL);
}
{
if(alarm2time)
{
- vehicle_alarm(self, CH_TRIGGER_SINGLE, SND(Null));
+ vehicle_alarm(self, CH_TRIGGER_SINGLE, SND_Null);
alarm2time = 0;
}
drawpic_skin(tmpPos, "vehicle_icon_shield", tmpSize, '1 1 1', hudAlpha, DRAWFLAG_NORMAL);
void Vehicles_drawCrosshair(string crosshair)
{
- SELFPARAM();
vector tmpSize = '0 0 0';
vector tmpPos = '0 0 0';
remove (self);
}
-entity vehicles_projectile(string _mzlfx, string _mzlsound,
+entity vehicles_projectile(string _mzlfx, Sound _mzlsound,
vector _org, vector _vel,
float _dmg, float _radi, float _force, float _size,
int _deahtype, float _projtype, float _health,
bool _cull, bool _clianim, entity _owner)
{SELFPARAM();
+ TC(Sound, _mzlsound);
entity proj;
proj = spawn();
else
proj.flags = FL_PROJECTILE | FL_NOTARGET;
- if(_mzlsound)
- _sound (self, CH_WEAPON_A, _mzlsound, VOL_BASE, ATTEN_NORM);
+ if(_mzlsound != SND_Null)
+ sound (self, CH_WEAPON_A, _mzlsound, VOL_BASE, ATTEN_NORM);
if(_mzlfx)
Send_Effect_(_mzlfx, proj.origin, proj.velocity, 1);
}
METHOD(Bumblebee, vr_death, void(Bumblebee thisveh, entity instance))
{
+ SELFPARAM();
entity oldself = self;
setself(instance);
void bumblebee_fire_cannon(entity _gun, string _tagname, entity _owner)
{
vector v = gettaginfo(_gun, gettagindex(_gun, _tagname));
- vehicles_projectile(EFFECT_BIGPLASMA_MUZZLEFLASH.eent_eff_name, SND(VEH_BUMBLEBEE_FIRE),
+ vehicles_projectile(EFFECT_BIGPLASMA_MUZZLEFLASH.eent_eff_name, SND_VEH_BUMBLEBEE_FIRE,
v, normalize(v_forward + randomvec() * autocvar_g_vehicle_bumblebee_cannon_spread) * autocvar_g_vehicle_bumblebee_cannon_speed,
autocvar_g_vehicle_bumblebee_cannon_damage, autocvar_g_vehicle_bumblebee_cannon_radius, autocvar_g_vehicle_bumblebee_cannon_force, 0,
DEATH_VH_BUMB_GUN.m_id, PROJECTILE_BUMBLE_GUN, 0, true, true, _owner);
METHOD(Racer, vr_enter, void(Racer thisveh, entity instance))
{
#ifdef SVQC
+ SELFPARAM();
self.movetype = MOVETYPE_BOUNCE;
self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_racer_health) * 100;
self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_racer_shield) * 100;
if(self.owner.flagcarried)
setorigin(self.owner.flagcarried, '-190 0 96');
#elif defined(CSQC)
-
+ SELFPARAM();
self.move_movetype = MOVETYPE_BOUNCE;
#endif
}
METHOD(Racer, vr_spawn, void(Racer thisveh, entity instance))
{
#ifdef SVQC
+ SELFPARAM();
if(self.scale != 0.5)
{
if(autocvar_g_vehicle_racer_hovertype != 0)
METHOD(Racer, vr_setup, void(Racer thisveh, entity instance))
{
#ifdef SVQC
+ SELFPARAM();
self.vehicle_exit = racer_exit;
#endif
veh.vehicle_energy -= autocvar_g_vehicle_racer_cannon_cost;
veh.wait = time;
}
- if (isPlayer) W_SetupShot_Dir(player, v_forward, false, 0, SND(Null), CH_WEAPON_B, 0);
+ if (isPlayer) W_SetupShot_Dir(player, v_forward, false, 0, SND_Null, CH_WEAPON_B, 0);
vector org = w_shotorg;
vector dir = w_shotdir;
- entity bolt = vehicles_projectile(EFFECT_RACER_MUZZLEFLASH.eent_eff_name, SND(LASERGUN_FIRE),
+ entity bolt = vehicles_projectile(EFFECT_RACER_MUZZLEFLASH.eent_eff_name, SND_LASERGUN_FIRE,
org, normalize(v_forward + randomvec() * autocvar_g_vehicle_racer_cannon_spread) * autocvar_g_vehicle_racer_cannon_speed,
autocvar_g_vehicle_racer_cannon_damage, autocvar_g_vehicle_racer_cannon_radius, autocvar_g_vehicle_racer_cannon_force, 0,
DEATH_VH_WAKI_GUN.m_id, PROJECTILE_WAKICANNON, 0, true, true, player);
}
if (fire & 2)
if (!isPlayer || weapon_prepareattack(thiswep, actor, weaponentity, false, 0.2)) {
- if (isPlayer) W_SetupShot_Dir(actor, v_forward, false, 0, SND(Null), CH_WEAPON_B, 0);
+ if (isPlayer) W_SetupShot_Dir(actor, v_forward, false, 0, SND_Null, CH_WEAPON_B, 0);
racer_fire_rocket(player, w_shotorg, w_shotdir, NULL);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, 0, w_ready);
}
void racer_rocket_groundhugger();
void racer_fire_rocket(entity player, vector org, vector dir, entity trg)
-{SELFPARAM();
- entity rocket = vehicles_projectile(EFFECT_RACER_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
+{
+ entity rocket = vehicles_projectile(EFFECT_RACER_ROCKETLAUNCH.eent_eff_name, SND_ROCKET_FIRE,
org, dir * autocvar_g_vehicle_racer_rocket_speed,
autocvar_g_vehicle_racer_rocket_damage, autocvar_g_vehicle_racer_rocket_radius, autocvar_g_vehicle_racer_rocket_force, 3,
DEATH_VH_WAKI_ROCKET.m_id, PROJECTILE_WAKIROCKET, 20, false, false, player);
}
METHOD(Raptor, vr_enter, void(Raptor thisveh, entity instance))
{
+ SELFPARAM();
self.vehicle_weapon2mode = RSM_BOMB;
self.owner.PlayerPhysplug = raptor_takeoff;
self.movetype = MOVETYPE_BOUNCEMISSILE;
}
METHOD(Raptor, vr_spawn, void(Raptor thisveh, entity instance))
{
+ SELFPARAM();
if(!self.gun1)
{
entity spinner;
}
METHOD(Raptor, vr_setup, void(Raptor thisveh, entity instance))
{
+ SELFPARAM();
if(autocvar_g_vehicle_raptor_shield)
self.vehicle_flags |= VHF_HASSHIELD;
}
METHOD(Raptor, vr_crosshair, void(Raptor thisveh))
{
+ SELFPARAM();
string crosshair;
switch(weapon2mode)
float t = autocvar_g_vehicle_raptor_cannon_refire * (1 + veh.misc_bulletcounter == 4);
if (fire & 1)
if (weapon_prepareattack(thiswep, player, weaponentity, false, t)) {
- if (isPlayer) W_SetupShot_Dir(player, v_forward, false, 0, SND(Null), CH_WEAPON_B, 0);
+ if (isPlayer) W_SetupShot_Dir(player, v_forward, false, 0, SND_Null, CH_WEAPON_B, 0);
vector org = w_shotorg;
vector dir = w_shotdir;
if (veh) {
veh.vehicle_energy -= autocvar_g_vehicle_raptor_cannon_cost;
actor.cnt = time;
}
- vehicles_projectile(EFFECT_RAPTOR_MUZZLEFLASH.eent_eff_name, SND(LASERGUN_FIRE),
+ vehicles_projectile(EFFECT_RAPTOR_MUZZLEFLASH.eent_eff_name, SND_LASERGUN_FIRE,
org, normalize(dir + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed,
autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force, 0,
DEATH_VH_RAPT_CANNON.m_id, PROJECTILE_RAPTORCANNON, 0, true, true, player);
}
METHOD(Spiderbot, vr_enter, void(Spiderbot thisveh, entity instance))
{
+ SELFPARAM();
self.vehicle_weapon2mode = SBRM_GUIDE;
self.movetype = MOVETYPE_WALK;
CSQCVehicleSetup(self.owner, 0);
}
METHOD(Spiderbot, vr_think, void(Spiderbot thisveh, entity instance))
{
+ SELFPARAM();
if(IS_ONGROUND(self))
movelib_brake_simple(self, autocvar_g_vehicle_spiderbot_speed_stop);
}
}
METHOD(Spiderbot, vr_spawn, void(Spiderbot thisveh, entity instance))
{
+ SELFPARAM();
if(!self.gun1)
{
self.vehicles_impulse = spiderbot_impulse;
}
METHOD(Spiderbot, vr_setup, void(Spiderbot thisveh, entity instance))
{
+ SELFPARAM();
if(autocvar_g_vehicle_spiderbot_shield)
self.vehicle_flags |= VHF_HASSHIELD;
switch(self.vehicle_weapon2mode)
{
case SBRM_VOLLY:
- rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
+ rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND_ROCKET_FIRE,
v, normalize(randomvec() * autocvar_g_vehicle_spiderbot_rocket_spread + v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
DEATH_VH_SPID_ROCKET.m_id, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, false, true, self.owner);
self.wait = -10;
break;
case SBRM_GUIDE:
- rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
+ rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND_ROCKET_FIRE,
v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
DEATH_VH_SPID_ROCKET.m_id, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, false, false, self.owner);
break;
case SBRM_ARTILLERY:
- rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
+ rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND_ROCKET_FIRE,
v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
DEATH_VH_SPID_ROCKET.m_id, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, false, true, self.owner);
#include "config.qh"
// weapon sets
-typedef vector WepSet;
+USING(WepSet, vector);
#ifdef SVQC
void WriteWepSet(float dest, WepSet w);
#endif
}
STATIC_INIT_LATE(W_PROP_reloader)
{
+ SELFPARAM();
entity e = W_PROP_reloader = new_pure(W_PROP_reloader);
WITH(entity, self, e, (e.think = W_PROP_think)());
}
W_DecreaseAmmo(thiswep, self, WEP_CVAR(arc, bolt_ammo));
- W_SetupShot(self, false, 2, SND(LASERGUN_FIRE), CH_WEAPON_A, WEP_CVAR(arc, bolt_damage));
+ W_SetupShot(self, false, 2, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR(arc, bolt_damage));
Send_Effect(EFFECT_ARC_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
self.owner,
true,
0,
- "",
+ SND_Null,
0,
WEP_CVAR(arc, beam_damage) * coefficient,
WEP_CVAR(arc, beam_range)
void Arc_Smoke()
{SELFPARAM();
makevectors(self.v_angle);
- W_SetupShot_Range(self,true,0,"",0,0,0);
+ W_SetupShot_Range(self,true,0,SND_Null,0,0,0);
vector smoke_origin = w_shotorg + self.velocity*frametime;
if ( self.arc_overheat > time )
if(WEP_CVAR(arc, beam_botaimspeed))
{
PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(
+ self,
WEP_CVAR(arc, beam_botaimspeed),
0,
WEP_CVAR(arc, beam_botaimlifetime),
else
{
PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(
+ self,
1000000,
0,
0.001,
}
METHOD(Arc, wr_drop, void(entity thiswep))
{
+ SELFPARAM();
weapon_dropevent_item.arc_overheat = self.arc_overheat;
weapon_dropevent_item.arc_cooldown = self.arc_cooldown;
self.arc_overheat = 0;
}
METHOD(Arc, wr_pickup, void(entity thiswep))
{
+ SELFPARAM();
if ( !client_hasweapon(self, thiswep, false, false) &&
weapon_dropevent_item.arc_overheat > time )
{
METHOD(Arc, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
if(w_deathtype & HITTYPE_SECONDARY)
{
vector org2;
{SELFPARAM();
vector s_forward = v_forward * cos(atk_shotangle * DEG2RAD) + v_up * sin(atk_shotangle * DEG2RAD);
- W_SetupShot_Dir(actor, s_forward, false, 3, SND(LASERGUN_FIRE), CH_WEAPON_B, atk_damage);
+ W_SetupShot_Dir(actor, s_forward, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_B, atk_damage);
Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
entity missile = new(blasterbolt);
METHOD(Blaster, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
if(WEP_CVAR(blaster, secondary))
{
if((random() * (WEP_CVAR_PRI(blaster, damage) + WEP_CVAR_SEC(blaster, damage))) > WEP_CVAR_PRI(blaster, damage))
- { PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); }
+ { PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(self, WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); }
else
- { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
+ { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
}
else
- { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
+ { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
}
METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponentity, int fire))
METHOD(Blaster, wr_setup, void(entity thiswep))
{
+ SELFPARAM();
self.ammo_field = ammo_none;
}
METHOD(Blaster, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 6;
pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1);
if(WEP_CVAR_PRI(crylink, joinexplode))
maxdmg += WEP_CVAR_PRI(crylink, joinexplode_damage);
- W_SetupShot(self, false, 2, SND(CRYLINK_FIRE), CH_WEAPON_A, maxdmg);
+ W_SetupShot(self, false, 2, SND_CRYLINK_FIRE, CH_WEAPON_A, maxdmg);
forward = v_forward;
right = v_right;
up = v_up;
if(WEP_CVAR_SEC(crylink, joinexplode))
maxdmg += WEP_CVAR_SEC(crylink, joinexplode_damage);
- W_SetupShot(self, false, 2, SND(CRYLINK_FIRE2), CH_WEAPON_A, maxdmg);
+ W_SetupShot(self, false, 2, SND_CRYLINK_FIRE2, CH_WEAPON_A, maxdmg);
forward = v_forward;
right = v_right;
up = v_up;
{
SELFPARAM();
if(random() < 0.10)
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false);
else
- PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(self, WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false);
}
METHOD(Crylink, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
}
METHOD(Crylink, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo)), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo)), SND_RELOAD);
}
METHOD(Crylink, wr_suicidemessage, Notification(entity thiswep))
{
W_DecreaseAmmo(thiswep, self, WEP_CVAR(devastator, ammo));
- W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 5, SND(ROCKET_FIRE), CH_WEAPON_A, WEP_CVAR(devastator, damage));
+ W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 5, SND_ROCKET_FIRE, CH_WEAPON_A, WEP_CVAR(devastator, damage));
Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
missile = WarpZone_RefSys_SpawnSameRefSys(self);
METHOD(Devastator, wr_aim, void(entity thiswep))
{
// aim and decide to fire if appropriate
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, 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
#else
METHOD(Devastator, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
// aim and decide to fire if appropriate
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, 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
selfdamage = selfdamage + d;
else if(targ.team == self.team && teamplay)
teamdamage = teamdamage + d;
- else if(bot_shouldattack(targ))
+ else if(bot_shouldattack(self, targ))
enemydamage = enemydamage + d;
targ = targ.chain;
}
}
METHOD(Devastator, wr_setup, void(entity thiswep))
{
+ SELFPARAM();
self.rl_release = 1;
}
METHOD(Devastator, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
#if 0
// don't switch while guiding a missile
if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_DEVASTATOR)
}
METHOD(Devastator, wr_resetplayer, void(entity thiswep))
{
+ SELFPARAM();
self.lastrocket = NULL; // stop rocket guiding, no revenge from the grave!
self.rl_release = 0;
}
METHOD(Devastator, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, WEP_CVAR(devastator, ammo), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, WEP_CVAR(devastator, ammo), SND_RELOAD);
}
METHOD(Devastator, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(Devastator, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 12;
pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1);
'0 0 -3',
false,
2,
- SND(ELECTRO_FIRE),
+ SND_ELECTRO_FIRE,
CH_WEAPON_A,
WEP_CVAR_PRI(electro, damage)
);
'0 0 -4',
false,
2,
- SND(ELECTRO_FIRE2),
+ SND_ELECTRO_FIRE2,
CH_WEAPON_A,
WEP_CVAR_SEC(electro, damage)
);
METHOD(Electro, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
PHYS_INPUT_BUTTON_ATCK(self) = PHYS_INPUT_BUTTON_ATCK2(self) = false;
if(vdist(self.origin - self.enemy.origin, >, 1000)) { self.bot_secondary_electromooth = 0; }
if(self.bot_secondary_electromooth == 0)
float shoot;
if(WEP_CVAR_PRI(electro, speed))
- shoot = bot_aim(WEP_CVAR_PRI(electro, speed), 0, WEP_CVAR_PRI(electro, lifetime), false);
+ shoot = bot_aim(self, WEP_CVAR_PRI(electro, speed), 0, WEP_CVAR_PRI(electro, lifetime), false);
else
- shoot = bot_aim(1000000, 0, 0.001, false);
+ shoot = bot_aim(self, 1000000, 0, 0.001, false);
if(shoot)
{
}
else
{
- if(bot_aim(WEP_CVAR_SEC(electro, speed), WEP_CVAR_SEC(electro, speed_up), WEP_CVAR_SEC(electro, lifetime), true))
+ if(bot_aim(self, WEP_CVAR_SEC(electro, speed), WEP_CVAR_SEC(electro, speed_up), WEP_CVAR_SEC(electro, lifetime), true))
{
PHYS_INPUT_BUTTON_ATCK2(self) = true;
if(random() < 0.03) self.bot_secondary_electromooth = 0;
}
METHOD(Electro, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(electro, ammo);
ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_PRI(electro, ammo);
return ammo_amount;
}
METHOD(Electro, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount;
if(WEP_CVAR(electro, combo_safeammocheck)) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false.
{
}
METHOD(Electro, wr_resetplayer, void(entity thiswep))
{
+ SELFPARAM();
self.electro_secondarytime = time;
}
METHOD(Electro, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, min(WEP_CVAR_PRI(electro, ammo), WEP_CVAR_SEC(electro, ammo)), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, min(WEP_CVAR_PRI(electro, ammo), WEP_CVAR_SEC(electro, ammo)), SND_RELOAD);
}
METHOD(Electro, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(Electro, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 6;
if(w_deathtype & HITTYPE_SECONDARY)
{SELFPARAM();
entity proj;
- W_SetupShot_ProjectileSize(self, '-16 -16 -16', '16 16 16', false, 2, SND(FIREBALL_FIRE2), CH_WEAPON_A, WEP_CVAR_PRI(fireball, damage) + WEP_CVAR_PRI(fireball, bfgdamage));
+ W_SetupShot_ProjectileSize(self, '-16 -16 -16', '16 16 16', false, 2, SND_FIREBALL_FIRE2, CH_WEAPON_A, WEP_CVAR_PRI(fireball, damage) + WEP_CVAR_PRI(fireball, bfgdamage));
Send_Effect(EFFECT_FIREBALL_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
void W_Fireball_AttackEffect(float i, vector f_diff)
{SELFPARAM();
- W_SetupShot_ProjectileSize(self, '-16 -16 -16', '16 16 16', false, 0, "", 0, 0);
+ W_SetupShot_ProjectileSize(self, '-16 -16 -16', '16 16 16', false, 0, SND_Null, 0, 0);
w_shotorg += f_diff.x * v_up + f_diff.y * v_right;
Send_Effect(EFFECT_FIREBALL_PRE_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
}
f_diff = '+1.25 +3.75 0';
break;
}
- W_SetupShot_ProjectileSize(self, '-4 -4 -4', '4 4 4', false, 2, SND(FIREBALL_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(fireball, damage));
+ W_SetupShot_ProjectileSize(self, '-4 -4 -4', '4 4 4', false, 2, SND_FIREBALL_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(fireball, damage));
traceline(w_shotorg, w_shotorg + f_diff_x * v_up + f_diff_y * v_right, MOVE_NORMAL, self);
w_shotorg = trace_endpos;
METHOD(Fireball, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
PHYS_INPUT_BUTTON_ATCK(self) = false;
PHYS_INPUT_BUTTON_ATCK2(self) = false;
if(self.bot_primary_fireballmooth == 0)
{
- if(bot_aim(WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), false))
+ if(bot_aim(self, WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), false))
{
PHYS_INPUT_BUTTON_ATCK(self) = true;
if(random() < 0.02) self.bot_primary_fireballmooth = 0;
}
else
{
- if(bot_aim(WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), true))
+ if(bot_aim(self, WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), true))
{
PHYS_INPUT_BUTTON_ATCK2(self) = true;
if(random() < 0.01) self.bot_primary_fireballmooth = 1;
}
METHOD(Fireball, wr_setup, void(entity thiswep))
{
+ SELFPARAM();
self.ammo_field = ammo_none;
}
METHOD(Fireball, wr_checkammo1, bool(entity thiswep))
}
METHOD(Fireball, wr_resetplayer, void(entity thiswep))
{
+ SELFPARAM();
self.fireball_primarytime = time;
}
METHOD(Fireball, wr_suicidemessage, Notification(entity thiswep))
METHOD(Fireball, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
if(w_deathtype & HITTYPE_SECONDARY)
{
W_DecreaseAmmo(thiswep, self, WEP_CVAR_PRI(hagar, ammo));
- W_SetupShot(self, false, 2, SND(HAGAR_FIRE), CH_WEAPON_A, WEP_CVAR_PRI(hagar, damage));
+ W_SetupShot(self, false, 2, SND_HAGAR_FIRE, CH_WEAPON_A, WEP_CVAR_PRI(hagar, damage));
Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
W_DecreaseAmmo(thiswep, self, WEP_CVAR_SEC(hagar, ammo));
- W_SetupShot(self, false, 2, SND(HAGAR_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage));
+ W_SetupShot(self, false, 2, SND_HAGAR_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage));
Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
weapon_prepareattack_do(self, weaponentity, true, WEP_CVAR_SEC(hagar, refire));
- W_SetupShot(self, false, 2, SND(HAGAR_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage));
+ W_SetupShot(self, false, 2, SND_HAGAR_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage));
Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
forward = v_forward;
METHOD(Hagar, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
if(random()>0.15)
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
else // not using secondary_speed since these are only 15% and should cause some ricochets without re-aiming
- PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(self, WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false);
}
METHOD(Hagar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
}
METHOD(Hagar, wr_gonethink, void(entity thiswep))
{
+ SELFPARAM();
// we lost the weapon and want to prepare switching away
if(self.hagar_load)
{
}
METHOD(Hagar, wr_setup, void(entity thiswep))
{
+ SELFPARAM();
self.hagar_loadblock = false;
if(self.hagar_load)
}
METHOD(Hagar, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(hagar, ammo);
ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_PRI(hagar, ammo);
return ammo_amount;
}
METHOD(Hagar, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(hagar, ammo);
ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
return ammo_amount;
}
METHOD(Hagar, wr_resetplayer, void(entity thiswep))
{
+ SELFPARAM();
self.hagar_load = 0;
}
METHOD(Hagar, wr_playerdeath, void(entity thiswep))
{
+ SELFPARAM();
.entity weaponentity = weaponentities[0]; // TODO: unhardcode
// if we have any rockets loaded when we die, release them
if(self.hagar_load && WEP_CVAR_SEC(hagar, load_releasedeath))
}
METHOD(Hagar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
+ SELFPARAM();
if(!self.hagar_load) // require releasing loaded rockets first
- W_Reload(self, min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo)), SND(RELOAD));
+ W_Reload(self, min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo)), SND_RELOAD);
}
METHOD(Hagar, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(Hagar, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 6;
pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1);
if(self.crouch)
spread = spread * WEP_CVAR_PRI(hlac, spread_crouchmod);
- W_SetupShot(self, false, 3, SND(LASERGUN_FIRE), CH_WEAPON_A, WEP_CVAR_PRI(hlac, damage));
+ W_SetupShot(self, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR_PRI(hlac, damage));
Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
if(!autocvar_g_norecoil)
{
if(self.crouch)
spread = spread * WEP_CVAR_SEC(hlac, spread_crouchmod);
- W_SetupShot(self, false, 3, SND(LASERGUN_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(hlac, damage));
+ W_SetupShot(self, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(hlac, damage));
Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
missile = new(hlacbolt);
METHOD(HLAC, wr_aim, void(entity thiswep))
{
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false);
+ SELFPARAM();
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false);
}
METHOD(HLAC, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
}
METHOD(HLAC, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(hlac, ammo);
ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_PRI(hlac, ammo);
return ammo_amount;
}
METHOD(HLAC, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(hlac, ammo);
ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_SEC(hlac, ammo);
return ammo_amount;
}
METHOD(HLAC, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo)), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo)), SND_RELOAD);
}
METHOD(HLAC, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(HLAC, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 6;
pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1);
void W_Hook_Attack2(Weapon thiswep, entity actor)
{
//W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hook, ammo)); // WEAPONTODO: Figure out how to handle ammo with hook secondary (gravitybomb)
- W_SetupShot(actor, false, 4, SND(HOOKBOMB_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(hook, damage));
+ W_SetupShot(actor, false, 4, SND_HOOKBOMB_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(hook, damage));
entity gren = new(hookbomb);
gren.owner = gren.realowner = actor;
METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
+ SELFPARAM();
if (fire & 1) {
if(!actor.hook)
if(!(actor.hook_state & HOOK_WAITING_FOR_RELEASE))
}
METHOD(Hook, wr_setup, void(entity thiswep))
{
+ SELFPARAM();
self.hook_state &= ~HOOK_WAITING_FOR_RELEASE;
}
METHOD(Hook, wr_checkammo1, bool(Hook thiswep))
{
+ SELFPARAM();
if (!thiswep.ammo_factor) return true;
if(self.hook)
return self.ammo_fuel > 0;
}
METHOD(Hook, wr_resetplayer, void(entity thiswep))
{
+ SELFPARAM();
RemoveGrapplingHook(self);
self.hook_time = 0;
self.hook_refire = time;
METHOD(Hook, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 2;
pointparticles(EFFECT_HOOK_EXPLODE, org2, '0 0 0', 1);
void W_MachineGun_Attack(Weapon thiswep, int deathtype, .entity weaponentity)
{SELFPARAM();
- W_SetupShot(self, true, 0, SND(UZI_FIRE), CH_WEAPON_A, ((self.misc_bulletcounter == 1) ? WEP_CVAR(machinegun, first_damage) : WEP_CVAR(machinegun, sustained_damage)));
+ W_SetupShot(self, true, 0, SND_UZI_FIRE, CH_WEAPON_A, ((self.misc_bulletcounter == 1) ? WEP_CVAR(machinegun, first_damage) : WEP_CVAR(machinegun, sustained_damage)));
if(!autocvar_g_norecoil)
{
self.punchangle_x = random() - 0.5;
W_DecreaseAmmo(WEP_MACHINEGUN, actor, WEP_CVAR(machinegun, sustained_ammo));
- W_SetupShot(actor, true, 0, SND(UZI_FIRE), CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage));
+ W_SetupShot(actor, true, 0, SND_UZI_FIRE, CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage));
if(!autocvar_g_norecoil)
{
actor.punchangle_x = random() - 0.5;
void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentity, int fire)
{
- W_SetupShot(actor, true, 0, SND(UZI_FIRE), CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage));
+ W_SetupShot(actor, true, 0, SND_UZI_FIRE, CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage));
if(!autocvar_g_norecoil)
{
actor.punchangle_x = random() - 0.5;
METHOD(MachineGun, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
if(vdist(self.origin - self.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, 1000000, 0, 0.001, false);
else
- PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(self, 1000000, 0, 0.001, false);
}
METHOD(MachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
}
METHOD(MachineGun, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount;
if(WEP_CVAR(machinegun, mode) == 1)
ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, sustained_ammo);
}
METHOD(MachineGun, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount;
if(WEP_CVAR(machinegun, mode) == 1)
ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, burst_ammo);
}
METHOD(MachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo)), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo)), SND_RELOAD);
}
METHOD(MachineGun, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(MachineGun, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 2;
pointparticles(EFFECT_MACHINEGUN_IMPACT, org2, w_backoff * 1000, 1);
W_DecreaseAmmo(thiswep, self, WEP_CVAR(minelayer, ammo));
- W_SetupShot_ProjectileSize(self, '-4 -4 -4', '4 4 4', false, 5, SND(MINE_FIRE), CH_WEAPON_A, WEP_CVAR(minelayer, damage));
+ W_SetupShot_ProjectileSize(self, '-4 -4 -4', '4 4 4', false, 5, SND_MINE_FIRE, CH_WEAPON_A, WEP_CVAR(minelayer, damage));
Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
mine = WarpZone_RefSys_SpawnSameRefSys(self);
METHOD(MineLayer, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
// aim and decide to fire if appropriate
if(self.minelayer_mines >= WEP_CVAR(minelayer, limit))
PHYS_INPUT_BUTTON_ATCK(self) = false;
else
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(minelayer, speed), 0, WEP_CVAR(minelayer, lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR(minelayer, speed), 0, WEP_CVAR(minelayer, lifetime), false);
if(skill >= 2) // skill 0 and 1 bots won't detonate mines!
{
// decide whether to detonate mines
selfdamage = selfdamage + d;
else if(targ.team == self.team && teamplay)
teamdamage = teamdamage + d;
- else if(bot_shouldattack(targ))
+ else if(bot_shouldattack(self, targ))
enemydamage = enemydamage + d;
targ = targ.chain;
}
}
METHOD(MineLayer, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
int slot = 0; // TODO: unhardcode
// don't switch while placing a mine
if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_MINE_LAYER)
}
METHOD(MineLayer, wr_resetplayers, void(entity thiswep))
{
+ SELFPARAM();
self.minelayer_mines = 0;
}
METHOD(MineLayer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, WEP_CVAR(minelayer, ammo), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, WEP_CVAR(minelayer, ammo), SND_RELOAD);
}
METHOD(MineLayer, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(MineLayer, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 12;
pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1);
W_DecreaseAmmo(thiswep, self, WEP_CVAR_PRI(mortar, ammo));
- W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 4, SND(GRENADE_FIRE), CH_WEAPON_A, WEP_CVAR_PRI(mortar, damage));
+ W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 4, SND_GRENADE_FIRE, CH_WEAPON_A, WEP_CVAR_PRI(mortar, damage));
w_shotdir = v_forward; // no TrueAim for grenades please
Send_Effect(EFFECT_GRENADE_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
W_DecreaseAmmo(thiswep, self, WEP_CVAR_SEC(mortar, ammo));
- W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 4, SND(GRENADE_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(mortar, damage));
+ W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 4, SND_GRENADE_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(mortar, damage));
w_shotdir = v_forward; // no TrueAim for grenades please
Send_Effect(EFFECT_GRENADE_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
METHOD(Mortar, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
PHYS_INPUT_BUTTON_ATCK(self) = false;
PHYS_INPUT_BUTTON_ATCK2(self) = false;
if(self.bot_secondary_grenademooth == 0) // WEAPONTODO: merge this into using WEP_CVAR_BOTH
{
- if(bot_aim(WEP_CVAR_PRI(mortar, speed), WEP_CVAR_PRI(mortar, speed_up), WEP_CVAR_PRI(mortar, lifetime), true))
+ if(bot_aim(self, WEP_CVAR_PRI(mortar, speed), WEP_CVAR_PRI(mortar, speed_up), WEP_CVAR_PRI(mortar, lifetime), true))
{
PHYS_INPUT_BUTTON_ATCK(self) = true;
if(random() < 0.01) self.bot_secondary_grenademooth = 1;
}
else
{
- if(bot_aim(WEP_CVAR_SEC(mortar, speed), WEP_CVAR_SEC(mortar, speed_up), WEP_CVAR_SEC(mortar, lifetime), true))
+ if(bot_aim(self, WEP_CVAR_SEC(mortar, speed), WEP_CVAR_SEC(mortar, speed_up), WEP_CVAR_SEC(mortar, lifetime), true))
{
PHYS_INPUT_BUTTON_ATCK2(self) = true;
if(random() < 0.02) self.bot_secondary_grenademooth = 0;
}
METHOD(Mortar, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(mortar, ammo);
ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_PRI(mortar, ammo);
return ammo_amount;
}
METHOD(Mortar, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(mortar, ammo);
ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_SEC(mortar, ammo);
return ammo_amount;
}
METHOD(Mortar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo)), SND(RELOAD)); // WEAPONTODO
+ SELFPARAM();
+ W_Reload(self, min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo)), SND_RELOAD); // WEAPONTODO
}
METHOD(Mortar, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(Mortar, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 12;
pointparticles(EFFECT_GRENADE_EXPLODE, org2, '0 0 0', 1);
{SELFPARAM();
entity gren;
- W_SetupShot(self, false, 4, SND(PORTO_FIRE), CH_WEAPON_A, 0);
+ W_SetupShot(self, false, 4, SND_PORTO_FIRE, CH_WEAPON_A, 0);
// always shoot from the eye
w_shotdir = v_forward;
w_shotorg = self.origin + self.view_ofs + ((w_shotorg - self.origin - self.view_ofs) * v_forward) * v_forward;
PHYS_INPUT_BUTTON_ATCK(self) = false;
PHYS_INPUT_BUTTON_ATCK2(self) = false;
if(!WEP_CVAR(porto, secondary))
- if(bot_aim(WEP_CVAR_PRI(porto, speed), 0, WEP_CVAR_PRI(porto, lifetime), false))
+ if(bot_aim(self, WEP_CVAR_PRI(porto, speed), 0, WEP_CVAR_PRI(porto, lifetime), false))
PHYS_INPUT_BUTTON_ATCK(self) = true;
}
METHOD(PortoLaunch, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
spawnfunc(weapon_campingrifle) { spawnfunc_weapon_rifle(this); }
spawnfunc(weapon_sniperrifle) { spawnfunc_weapon_rifle(this); }
-void W_Rifle_FireBullet(Weapon thiswep, float pSpread, float pDamage, float pForce, float pSolidPenetration, float pAmmo, int deathtype, float pTracer, float pShots, string pSound)
+void W_Rifle_FireBullet(Weapon thiswep, float pSpread, float pDamage, float pForce, float pSolidPenetration, float pAmmo, int deathtype, float pTracer, float pShots, Sound pSound)
{SELFPARAM();
float i;
void W_Rifle_Attack()
{
- W_Rifle_FireBullet(WEP_RIFLE, WEP_CVAR_PRI(rifle, spread), WEP_CVAR_PRI(rifle, damage), WEP_CVAR_PRI(rifle, force), WEP_CVAR_PRI(rifle, solidpenetration), WEP_CVAR_PRI(rifle, ammo), WEP_RIFLE.m_id, WEP_CVAR_PRI(rifle, tracer), WEP_CVAR_PRI(rifle, shots), SND(CAMPINGRIFLE_FIRE));
+ W_Rifle_FireBullet(WEP_RIFLE, WEP_CVAR_PRI(rifle, spread), WEP_CVAR_PRI(rifle, damage), WEP_CVAR_PRI(rifle, force), WEP_CVAR_PRI(rifle, solidpenetration), WEP_CVAR_PRI(rifle, ammo), WEP_RIFLE.m_id, WEP_CVAR_PRI(rifle, tracer), WEP_CVAR_PRI(rifle, shots), SND_CAMPINGRIFLE_FIRE);
}
void W_Rifle_Attack2()
{
- W_Rifle_FireBullet(WEP_RIFLE, WEP_CVAR_SEC(rifle, spread), WEP_CVAR_SEC(rifle, damage), WEP_CVAR_SEC(rifle, force), WEP_CVAR_SEC(rifle, solidpenetration), WEP_CVAR_SEC(rifle, ammo), WEP_RIFLE.m_id | HITTYPE_SECONDARY, WEP_CVAR_SEC(rifle, tracer), WEP_CVAR_SEC(rifle, shots), SND(CAMPINGRIFLE_FIRE2));
+ W_Rifle_FireBullet(WEP_RIFLE, WEP_CVAR_SEC(rifle, spread), WEP_CVAR_SEC(rifle, damage), WEP_CVAR_SEC(rifle, force), WEP_CVAR_SEC(rifle, solidpenetration), WEP_CVAR_SEC(rifle, ammo), WEP_RIFLE.m_id | HITTYPE_SECONDARY, WEP_CVAR_SEC(rifle, tracer), WEP_CVAR_SEC(rifle, shots), SND_CAMPINGRIFLE_FIRE2);
}
.void() rifle_bullethail_attackfunc;
METHOD(Rifle, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
PHYS_INPUT_BUTTON_ATCK(self) = false;
PHYS_INPUT_BUTTON_ATCK2(self) = false;
if(vdist(self.origin - self.enemy.origin, >, 1000))
self.bot_secondary_riflemooth = 0;
if(self.bot_secondary_riflemooth == 0)
{
- if(bot_aim(1000000, 0, 0.001, false))
+ if(bot_aim(self, 1000000, 0, 0.001, false))
{
PHYS_INPUT_BUTTON_ATCK(self) = true;
if(random() < 0.01) self.bot_secondary_riflemooth = 1;
}
else
{
- if(bot_aim(1000000, 0, 0.001, false))
+ if(bot_aim(self, 1000000, 0, 0.001, false))
{
PHYS_INPUT_BUTTON_ATCK2(self) = true;
if(random() < 0.03) self.bot_secondary_riflemooth = 0;
}
METHOD(Rifle, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(rifle, ammo);
ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_PRI(rifle, ammo);
return ammo_amount;
}
METHOD(Rifle, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(rifle, ammo);
ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_SEC(rifle, ammo);
return ammo_amount;
}
METHOD(Rifle, wr_resetplayer, void(entity thiswep))
{
+ SELFPARAM();
self.rifle_accumulator = time - WEP_CVAR(rifle, bursttime);
}
METHOD(Rifle, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo)), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo)), SND_RELOAD);
}
METHOD(Rifle, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(Rifle, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 2;
pointparticles(EFFECT_RIFLE_IMPACT, org2, w_backoff * 1000, 1);
W_DecreaseAmmo(thiswep, self, WEP_CVAR(seeker, missile_ammo));
makevectors(self.v_angle);
- W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND(SEEKER_FIRE), CH_WEAPON_A, 0);
+ W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND_SEEKER_FIRE, CH_WEAPON_A, 0);
w_shotorg += f_diff;
Send_Effect(EFFECT_SEEKER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
f_diff = '+1.25 +3.75 0';
break;
}
- W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND(FLAC_FIRE), CH_WEAPON_A, WEP_CVAR(seeker, flac_damage));
+ W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND_FLAC_FIRE, CH_WEAPON_A, WEP_CVAR(seeker, flac_damage));
w_shotorg += f_diff;
Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
entity missile;
W_DecreaseAmmo(thiswep, self, WEP_CVAR(seeker, tag_ammo));
- W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND(TAG_FIRE), CH_WEAPON_A, WEP_CVAR(seeker, missile_damage) * WEP_CVAR(seeker, missile_count));
+ W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND_TAG_FIRE, CH_WEAPON_A, WEP_CVAR(seeker, missile_damage) * WEP_CVAR(seeker, missile_count));
missile = new(seeker_tag);
missile.owner = missile.realowner = self;
METHOD(Seeker, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
if(WEP_CVAR(seeker, type) == 1)
if(W_Seeker_Tagged_Info(self, self.enemy) != world)
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false);
else
- PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(self, WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
else
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false);
}
METHOD(Seeker, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
}
METHOD(Seeker, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount;
if(WEP_CVAR(seeker, type) == 1)
{
}
METHOD(Seeker, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount;
if(WEP_CVAR(seeker, type) == 1)
{
}
METHOD(Seeker, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), SND_RELOAD);
}
METHOD(Seeker, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(Seeker, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2;
org2 = w_org + w_backoff * 6;
if(w_deathtype & HITTYPE_BOUNCE)
meleetemp.owner = meleetemp.realowner = actor;
meleetemp.think = W_Shockwave_Melee_Think;
meleetemp.nextthink = time + WEP_CVAR(shockwave, melee_delay) * W_WeaponRateFactor();
- W_SetupShot_Range(actor, true, 0, "", 0, WEP_CVAR(shockwave, melee_damage), WEP_CVAR(shockwave, melee_range));
+ W_SetupShot_Range(actor, true, 0, SND_Null, 0, WEP_CVAR(shockwave, melee_damage), WEP_CVAR(shockwave, melee_range));
}
// SHOCKWAVE ATTACK MODE
float i, queue = 0;
// set up the shot direction
- W_SetupShot(self, false, 3, SND(LASERGUN_FIRE), CH_WEAPON_B, WEP_CVAR(shockwave, blast_damage));
+ W_SetupShot(self, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_B, WEP_CVAR(shockwave, blast_damage));
vector attack_endpos = (w_shotorg + (w_shotdir * WEP_CVAR(shockwave, blast_distance)));
WarpZone_TraceLine(w_shotorg, attack_endpos, MOVE_NOMONSTERS, self);
vector attack_hitpos = trace_endpos;
METHOD(Shockwave, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
if(vlen(self.origin - self.enemy.origin) <= WEP_CVAR(shockwave, melee_range))
- { PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false); }
+ { PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(self, 1000000, 0, 0.001, false); }
else
- { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false); }
+ { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, 1000000, 0, 0.001, false); }
}
METHOD(Shockwave, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
W_DecreaseAmmo(thiswep, self, WEP_CVAR_PRI(shotgun, ammo));
- W_SetupShot(self, true, 5, SND(SHOTGUN_FIRE), ((isprimary) ? CH_WEAPON_A : CH_WEAPON_SINGLE), WEP_CVAR_PRI(shotgun, damage) * WEP_CVAR_PRI(shotgun, bullets));
+ W_SetupShot(self, true, 5, SND_SHOTGUN_FIRE, ((isprimary) ? CH_WEAPON_A : CH_WEAPON_SINGLE), WEP_CVAR_PRI(shotgun, damage) * WEP_CVAR_PRI(shotgun, bullets));
for(sc = 0;sc < WEP_CVAR_PRI(shotgun, bullets);sc = sc + 1)
fireBullet(w_shotorg, w_shotdir, WEP_CVAR_PRI(shotgun, spread), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, damage), WEP_CVAR_PRI(shotgun, force), WEP_SHOTGUN.m_id, 0);
meleetemp.realowner = actor;
meleetemp.think = W_Shotgun_Melee_Think;
meleetemp.nextthink = time + WEP_CVAR_SEC(shotgun, melee_delay) * W_WeaponRateFactor();
- W_SetupShot_Range(actor, true, 0, "", 0, WEP_CVAR_SEC(shotgun, damage), WEP_CVAR_SEC(shotgun, melee_range));
+ W_SetupShot_Range(actor, true, 0, SND_Null, 0, WEP_CVAR_SEC(shotgun, damage), WEP_CVAR_SEC(shotgun, melee_range));
}
// alternate secondary weapon frames
METHOD(Shotgun, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
if(vdist(self.origin - self.enemy.origin, <=, WEP_CVAR_SEC(shotgun, melee_range)))
- PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(self, 1000000, 0, 0.001, false);
else
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, 1000000, 0, 0.001, false);
}
METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
}
METHOD(Shotgun, wr_setup, void(entity thiswep))
{
+ SELFPARAM();
self.ammo_field = ammo_none;
}
METHOD(Shotgun, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo);
ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo);
return ammo_amount;
}
METHOD(Shotgun, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
if(IS_BOT_CLIENT(self))
if(vdist(self.origin - self.enemy.origin, >, WEP_CVAR_SEC(shotgun, melee_range)))
return false; // bots cannot use secondary out of range (fixes constant melee when out of ammo)
}
METHOD(Shotgun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, WEP_CVAR_PRI(shotgun, ammo), SND(RELOAD)); // WEAPONTODO
+ SELFPARAM();
+ W_Reload(self, WEP_CVAR_PRI(shotgun, ammo), SND_RELOAD); // WEAPONTODO
}
METHOD(Shotgun, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(Shotgun, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2 = w_org + w_backoff * 2;
pointparticles(EFFECT_SHOTGUN_IMPACT, org2, w_backoff * 1000, 1);
if(!w_issilent && time - self.prevric > 0.25)
vector o;
float n;
- W_SetupShot(self, false, 2, "", 0, WEP_CVAR(tuba, damage));
+ W_SetupShot(self, false, 2, SND_Null, 0, WEP_CVAR(tuba, damage));
n = W_Tuba_GetNote(self, hittype);
break;
}
tuba_instrument_send(actor, actor.tuba_instrument);
- W_SetupShot(actor, false, 0, "", 0, 0);
+ W_SetupShot(actor, false, 0, SND_Null, 0, 0);
Send_Effect(EFFECT_TELEPORT, w_shotorg, '0 0 0', 1);
actor.(weaponentity).state = WS_INUSE;
weapon_thinkf(actor, weaponentity, WFRAME_RELOAD, 0.5, w_ready);
this.enemy = NULL;
}
-void Ent_TubaNote_StopSound_self() { Ent_TubaNote_StopSound(self); }
+void Ent_TubaNote_StopSound_self() { SELFPARAM(); Ent_TubaNote_StopSound(self); }
NET_HANDLE(ENT_CLIENT_TUBANOTE, bool isNew)
{
bool flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
float vaporizer_damage = ((WEP_CVAR_PRI(vaporizer, damage) > 0) ? WEP_CVAR_PRI(vaporizer, damage) : 10000);
- W_SetupShot(self, true, 0, "", CH_WEAPON_A, vaporizer_damage);
+ W_SetupShot(self, true, 0, SND_Null, CH_WEAPON_A, vaporizer_damage);
// handle sound separately so we can change the volume
// added bonus: no longer plays the strength sound (strength gives no bonus to instakill anyway)
sound (self, CH_WEAPON_A, SND_MINSTANEXFIRE, VOL_BASE * 0.8, ATTEN_NORM);
Weapon w = PS(self).m_weapon;
PS(self).m_weapon = WEP_ELECTRO;
- W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', false, 2, SND(CRYLINK_FIRE), CH_WEAPON_A, autocvar_g_rm_laser_damage);
+ W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', false, 2, SND_CRYLINK_FIRE, CH_WEAPON_A, autocvar_g_rm_laser_damage);
PS(self).m_weapon = w;
Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
Weapon w = PS(self).m_weapon;
PS(self).m_weapon = WEP_ELECTRO;
- W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', false, 2, SND(ELECTRO_FIRE2), CH_WEAPON_A, autocvar_g_rm_laser_damage);
+ W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', false, 2, SND_ELECTRO_FIRE2, CH_WEAPON_A, autocvar_g_rm_laser_damage);
PS(self).m_weapon = w;
Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
METHOD(Vaporizer, wr_aim, void(entity thiswep))
{
+ SELFPARAM();
if(self.(thiswep.ammo_field) > 0)
- PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 1, false);
+ PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, 1000000, 0, 1, false);
else
- PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_SEC(vaporizer, speed), 0, WEP_CVAR_SEC(vaporizer, lifetime), false); // WEAPONTODO: replace with proper vaporizer cvars
+ PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(self, WEP_CVAR_SEC(vaporizer, speed), 0, WEP_CVAR_SEC(vaporizer, lifetime), false); // WEAPONTODO: replace with proper vaporizer cvars
}
METHOD(Vaporizer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
}
METHOD(Vaporizer, wr_setup, void(entity thiswep))
{
+ SELFPARAM();
self.ammo_field = (thiswep.ammo_field);
self.vaporizer_lasthit = 0;
}
METHOD(Vaporizer, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
float ammo_amount = self.(thiswep.ammo_field) >= vaporizer_ammo;
ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= vaporizer_ammo;
}
METHOD(Vaporizer, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
if(!WEP_CVAR_SEC(vaporizer, ammo))
return true;
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(vaporizer, ammo);
}
METHOD(Vaporizer, wr_resetplayer, void(entity thiswep))
{
+ SELFPARAM();
self.vaporizer_lasthit = 0;
}
METHOD(Vaporizer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
+ SELFPARAM();
float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo));
float used_ammo;
if(WEP_CVAR_SEC(vaporizer, ammo))
else
used_ammo = vaporizer_ammo;
- W_Reload(self, used_ammo, SND(RELOAD));
+ W_Reload(self, used_ammo, SND_RELOAD);
}
METHOD(Vaporizer, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(Vaporizer, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2 = w_org + w_backoff * 6;
if(w_deathtype & HITTYPE_SECONDARY)
{
mydmg *= charge;
myforce *= charge;
- W_SetupShot(self, true, 5, SND(NEXFIRE), CH_WEAPON_A, mydmg);
+ W_SetupShot(self, true, 5, SND_NEXFIRE, CH_WEAPON_A, mydmg);
if(charge > WEP_CVAR(vortex, charge_animlimit) && WEP_CVAR(vortex, charge_animlimit)) // if the Vortex is overcharged, we play an extra sound
{
sound(self, CH_WEAPON_B, SND_NEXCHARGE, VOL_BASE * (charge - 0.5 * WEP_CVAR(vortex, charge_animlimit)) / (1 - 0.5 * WEP_CVAR(vortex, charge_animlimit)), ATTN_NORM);
METHOD(Vortex, wr_aim, void(entity thiswep))
{
- if(bot_aim(1000000, 0, 1, false))
+ SELFPARAM();
+ if(bot_aim(self, 1000000, 0, 1, false))
PHYS_INPUT_BUTTON_ATCK(self) = true;
else
{
}
METHOD(Vortex, wr_setup, void(entity thiswep))
{
+ SELFPARAM();
self.vortex_lasthit = 0;
}
METHOD(Vortex, wr_checkammo1, bool(entity thiswep))
{
+ SELFPARAM();
float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(vortex, ammo);
ammo_amount += (autocvar_g_balance_vortex_reload_ammo && self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_PRI(vortex, ammo));
return ammo_amount;
}
METHOD(Vortex, wr_checkammo2, bool(entity thiswep))
{
+ SELFPARAM();
if(WEP_CVAR(vortex, secondary))
{
// don't allow charging if we don't have enough ammo
}
METHOD(Vortex, wr_resetplayer, void(entity thiswep))
{
+ SELFPARAM();
if (WEP_CVAR(vortex, charge)) {
if (WEP_CVAR_SEC(vortex, chargepool)) {
self.vortex_chargepool_ammo = 1;
}
METHOD(Vortex, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
{
- W_Reload(self, min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo)), SND(RELOAD));
+ SELFPARAM();
+ W_Reload(self, min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo)), SND_RELOAD);
}
METHOD(Vortex, wr_suicidemessage, Notification(entity thiswep))
{
METHOD(Vortex, wr_impacteffect, void(entity thiswep))
{
+ SELFPARAM();
vector org2 = w_org + w_backoff * 6;
pointparticles(EFFECT_VORTEX_IMPACT, org2, '0 0 0', 1);
if(!w_issilent)
#include <dpdefs/keycodes.qh>
#endif
+#define USING(name, T) typedef T name
+
+#include "bool.qh"
+#include "int.qh"
+
#include "macro.qh"
+#if NDEBUG
+ #define TC(T, sym) MACRO_BEGIN MACRO_END
+#else
+ #define TC(T, sym) MACRO_BEGIN \
+ if (!is_##T(sym)) LOG_WARNINGF("Type check failed: " #sym " :: " #T); \
+ MACRO_END
+#endif
+
+bool is_float (float this) { return true; }
+bool is_vector(vector this) { return true; }
+bool is_string(string this) { return true; }
+bool is_entity(entity this) { return true; }
+bool is_int (float this) { return this == floor(this); }
+bool is_bool (float this) { return this == true || this == false; }
+
#include "warpzone/mathlib.qc"
#include "accumulate.qh"
#include "angle.qc"
#include "arraylist.qh"
#include "bits.qh"
-#include "bool.qh"
#include "color.qh"
#include "counting.qh"
#include "cvar.qh"
#include "file.qh"
#include "functional.qh"
#include "i18n.qh"
-#include "int.qh"
#include "iter.qh"
#include "lazy.qh"
#include "linkedlist.qh"
#pragma once
-typedef entity ArrayList;
+USING(ArrayList, entity);
.int al_buf;
.int al_len;
#define QCC_SUPPORT_NIL
#endif
#endif
+
+#ifdef GMQCC
+ #define LABEL(id) :id
+#else
+ #define LABEL(id) id:
+#endif
bool CSQCModel_Send(entity to, int sf)
{
+ SELFPARAM();
// some nice flags for CSQCMODEL_IF
float isplayer = (IS_CLIENT(self));
float islocalplayer = (self == to);
// zero overhead mode, use this for releases
-#define ENUMCLASS(id) typedef int id; enum { CASE(id, Null)
+#define ENUMCLASS(id) USING(id, int); enum { CASE(id, Null)
#define CASE(class, id) class##_##id,
#define ENUMCLASS_END(id) };
#define ORDINAL(it) (it)
fclose(fh);
}
-typedef int HashMap;
+USING(HashMap, int);
int db_create()
{
/** return false to remove from the client */
.bool(entity this, entity to, int sendflags) SendEntity3;
- bool SendEntity_self(entity to, int sendflags) { return self.SendEntity3(self, to, sendflags); }
+ bool SendEntity_self(entity to, int sendflags) { SELFPARAM(); return this.SendEntity3(this, to, sendflags); }
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
{
void UncustomizeEntitiesRun()
{
+ SELFPARAM();
FOREACH_ENTITY_FLOAT(uncustomizeentityforclient_set, true, WITH(entity, self, it, it.uncustomizeentityforclient()));
}
.vector origin;
.bool pure_data;
-/** @deprecated, use new_pure or NEW(class) */
+/** @deprecated use new_pure or NEW(class) */
#define make_pure(e) \
MACRO_BEGIN \
{ \
#define EVAL_entityclass(...) __VA_ARGS__
#define entityclass_1(name) entityclass_2(name, Object)
#ifndef QCC_SUPPORT_ENTITYCLASS
- #define entityclass_2(name, base) typedef entity name
+ #define entityclass_2(name, base) USING(name, entity)
#define class(name)
#define _new(class, pure) __spawn( #class, __FILE__ ":" STR(__LINE__), pure)
#else
}
#define VTBL(cname, base) \
- INIT_STATIC(cname); \
+ _INIT_STATIC(cname); \
entity cname##_vtbl; \
void cname##_vtbl_init() \
{ \
} \
ACCUMULATE_FUNCTION(RegisterClasses, cname##_vtbl_init)
-#define INIT_STATIC(cname) [[accumulate]] void spawn##cname##_static(cname this)
+#define _INIT_STATIC(cname) [[accumulate]] void spawn##cname##_static(cname this)
#define INIT(cname) [[accumulate]] cname spawn##cname##_1(cname this)
#define CLASS(cname, base) \
entityclass(cname, base); \
class(cname).bool instanceOf##cname; \
+ bool is_##cname(entity e) { return e.instanceOf##cname; } \
VTBL(cname, base) \
- INIT_STATIC(cname) \
+ _INIT_STATIC(cname) \
{ \
if (cname##_vtbl) \
{ \
#define METHOD(cname, name, prototype) \
STATIC_METHOD(cname, name, prototype); \
class(cname) .prototype name; \
- INIT_STATIC(cname) \
+ _INIT_STATIC(cname) \
{ \
this.name = METHOD_REFERENCE(cname, name); \
} \
this.name = val; \
}
+#define STATIC_ATTRIB(cname, name, type, val) \
+ type cname##_##name; \
+ _INIT_STATIC(cname) \
+ { \
+ noref bool strzone; /* Error on strzone() calls. */ \
+ cname##_##name = val; \
+ }
+
+// cleanup potentially zoned strings from base classes
+
#define ATTRIB_STRZONE(cname, name, type, val) \
class(cname).type name; \
INIT(cname) \
this.name = strzone(val); \
}
+#define STATIC_ATTRIB_STRZONE(cname, name, type, val) \
+ type cname##_##name; \
+ _INIT_STATIC(cname) \
+ { \
+ if (cname##_##name) \
+ strunzone(cname##_##name); \
+ cname##_##name = val; \
+ }
+
#define ATTRIBARRAY(cname, name, type, cnt) \
class(cname).type name[cnt];
#define remove(this) delete(this)
METHOD(Object, describe, string(Object this))
{
+ TC(Object, this);
string s = _("No description");
if (cvar("developer"))
{
}
METHOD(Object, display, void(Object this, void(string name, string icon) returns))
{
+ TC(Object, this);
returns(sprintf("entity %i", this), "nopreview_map");
}
ENDCLASS(Object)
* Must be followed by a semicolon or a function body with a `this` parameter.
* Wrapper macros may perform actions after user initialization like so:
* #define REGISTER_FOO(id) \
- * REGISTER(Foos, FOO, id, m_id, NEW(Foo)); \
- * REGISTER_INIT_POST(FOO, id) { \
+ * REGISTER(Foos, FOO, id, m_id, NEW(Foo)) { \
* print("Registering foo #", this.m_id + 1, "\n"); \
* } \
* REGISTER_INIT(FOO, id)
#define REGISTER_4(registry, id, fld, inst) \
entity id; \
REGISTER_INIT(id) {} \
- REGISTER_INIT_POST(id) {} \
void Register_##id() \
{ \
if (registry##_COUNT >= registry##_MAX) LOG_FATALF("Registry capacity exceeded (%d)", registry##_MAX); \
this.registered_id = #id; \
REGISTRY_PUSH(registry, fld, this); \
Register_##id##_init(this); \
- Register_##id##_init_post(this); \
} \
ACCUMULATE_FUNCTION(_Register##registry, Register_##id) \
REGISTER_INIT(id)
} MACRO_END
#define REGISTER_INIT(id) [[accumulate]] void Register_##id##_init(entity this)
-#define REGISTER_INIT_POST(id) [[accumulate]] void Register_##id##_init_post(entity this)
/** internal next pointer */
#define REGISTRY_NEXT enemy
#pragma once
/** is only ever called for i1 < i2 */
-typedef void (int i1, int i2, entity pass) swapfunc_t;
+USING(swapfunc_t, void (int i1, int i2, entity pass));
/** <0 for <, ==0 for ==, >0 for > (like strcmp) */
-typedef int (int i1, int i2, entity pass) comparefunc_t;
+USING(comparefunc_t, int (int i1, int i2, entity pass));
void heapsort(int n, swapfunc_t swap, comparefunc_t cmp, entity pass)
{
#include "sort.qh"
.int m_id;
-typedef vector vectori;
+USING(vectori, vector);
#define REGISTER_STAT(...) EVAL_REGISTER_STAT(OVERLOAD(REGISTER_STAT, __VA_ARGS__))
#define EVAL_REGISTER_STAT(...) __VA_ARGS__
X(float)
X(entity)
X(string)
-typedef float(...) rawfunc;
+USING(rawfunc, float(...));
X(rawfunc)
#undef X
const float URL_READY_CANWRITE = 1;
const float URL_READY_CANREAD = 2;
// errors: -1, or negative HTTP status code
-typedef void (entity handle, entity pass, float status) url_ready_func;
+USING(url_ready_func, void (entity handle, entity pass, float status));
void url_single_fopen(string url, float mode, url_ready_func rdy, entity pass);
void url_fclose(entity e);
org = trace_endpos;
}
WarpZone_MakeAllOther();
-:fail
+LABEL(fail)
if(contentshack)
BITCLR_ASSIGN(WarpZone_trace_forent.dphitcontentsmask, DPCONTENTS_SOLID);
trace_startsolid = sol;
e.velocity = -e.velocity;
}
WarpZone_MakeAllOther();
-:fail
+LABEL(fail)
WarpZone_tracetoss_velocity = e.velocity;
v_forward = vf;
v_right = vr;
#define MOVE_NOTHING -1
entity WarpZone_trace_forent; // temp, callback is allowed to change it
-typedef void(vector start, vector hit, vector end) WarpZone_trace_callback_t; // called on every elementary trace
+USING(WarpZone_trace_callback_t, void(vector start, vector hit, vector end)); // called on every elementary trace
var WarpZone_trace_callback_t WarpZone_trace_callback_t_null;
entity WarpZone_trace_transform; // transform accumulator during a trace
entity WarpZone_trace_firstzone; // first warpzone hit by a trace (can differ from the requested zone in case of _ThroughZone, the trace is aborted then)
}
break;
- : have_overlap
+LABEL(have_overlap)
}
scale *= 0.95;
draw_Picture_Aligned(v, scalemode, strcat(img, "_l", ftos(l + 1)), a);
}
++l;
- : nopic
+LABEL(nopic)
}
}
}
}
goto nottoolong;
-:toolong
+LABEL(toolong)
while(substring(r, strlen(r) - 1, 1) == "\n")
r = substring(r, 0, strlen(r) - 1);
r = strcat(r, "...\n");
-:nottoolong
+LABEL(nottoolong)
campaign_longdesc_wrapped[i] = strzone(substring(r, 0, strlen(r) - 1));
}
}
#pragma once
CLASS(DataSource, Object)
- entity DataSource_true;
- entity DataSource_false;
- INIT_STATIC(DataSource) {
- DataSource_true = NEW(Object);
- DataSource_false = NULL;
- }
+ STATIC_ATTRIB(DataSource, true, entity, NEW(Object));
+ STATIC_ATTRIB(DataSource, false, entity, NULL);
/**
* get entry `i` passing `name` and `icon` through `returns` if it is not null
* returns `DataSource_false` if out of bounds
#define IS_OBSERVER(v) ((v).classname == STR_OBSERVER)
#define IS_CLIENT(v) (v.flags & FL_CLIENT)
+#define is_Client IS_CLIENT
#define IS_BOT_CLIENT(v) (clienttype(v) == CLIENTTYPE_BOT)
#define IS_REAL_CLIENT(v) (clienttype(v) == CLIENTTYPE_REAL)
#define IS_NOT_A_CLIENT(v) (clienttype(v) == CLIENTTYPE_NOTACLIENT)
}
}
-void anticheat_spectatecopy(entity spectatee)
-{SELFPARAM();
+void anticheat_spectatecopy(entity this, entity spectatee)
+{
// div0_evade -> SPECTATORS
- self.angles = CS(spectatee).anticheat_div0_evade_v_angle;
+ this.angles = CS(spectatee).anticheat_div0_evade_v_angle;
}
-void anticheat_prethink()
+void anticheat_prethink(entity this)
{
- SELFPARAM();
// div0_evade -> SPECTATORS
CS(this).anticheat_div0_evade_offset = 0;
}
return strcat(s, ":-");
}
-void anticheat_report()
-{SELFPARAM();
+void anticheat_report(entity this)
+{
if(!autocvar_sv_eventlog)
return;
// TODO(divVerent): Use xonstat to acquire good thresholds.
- GameLogEcho(strcat(":anticheat:_time:", ftos(self.playerid), ":", ftos(servertime - CS(self).anticheat_jointime)));
- GameLogEcho(strcat(":anticheat:speedhack:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack), 240, 0, 9999))); // Actually this one seems broken.
- GameLogEcho(strcat(":anticheat:speedhack_m1:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack_m1), 240, 1.01, 1.25)));
- GameLogEcho(strcat(":anticheat:speedhack_m2:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack_m2), 240, 1.01, 1.25)));
- GameLogEcho(strcat(":anticheat:speedhack_m3:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack_m3), 240, 1.01, 1.25)));
- GameLogEcho(strcat(":anticheat:speedhack_m4:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack_m4), 240, 1.01, 1.25)));
- GameLogEcho(strcat(":anticheat:speedhack_m5:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack_m5), 240, 1.01, 1.25)));
- GameLogEcho(strcat(":anticheat:div0_strafebot_old:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_div0_strafebot_old), 120, 0.15, 0.4)));
- GameLogEcho(strcat(":anticheat:div0_strafebot_new:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_div0_strafebot_new), 120, 0.25, 0.8)));
- GameLogEcho(strcat(":anticheat:div0_evade:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_div0_evade), 120, 0.2, 0.5)));
- GameLogEcho(strcat(":anticheat:idle_snapaim:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_signal) - MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_noise), 120, 0, 9999)));
- GameLogEcho(strcat(":anticheat:idle_snapaim_signal:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_signal), 120, 0, 9999)));
- GameLogEcho(strcat(":anticheat:idle_snapaim_noise:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_noise), 120, 0, 9999)));
- GameLogEcho(strcat(":anticheat:idle_snapaim_m2:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m2), 120, 0, 9999)));
- GameLogEcho(strcat(":anticheat:idle_snapaim_m3:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m3), 120, 0, 9999)));
- GameLogEcho(strcat(":anticheat:idle_snapaim_m4:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m4), 120, 0, 9999)));
- GameLogEcho(strcat(":anticheat:idle_snapaim_m7:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m7), 120, 0, 9999)));
- GameLogEcho(strcat(":anticheat:idle_snapaim_m10:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m10), 120, 0, 9999)));
+ GameLogEcho(strcat(":anticheat:_time:", ftos(this.playerid), ":", ftos(servertime - CS(this).anticheat_jointime)));
+ GameLogEcho(strcat(":anticheat:speedhack:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_speedhack), 240, 0, 9999))); // Actually this one seems broken.
+ GameLogEcho(strcat(":anticheat:speedhack_m1:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_speedhack_m1), 240, 1.01, 1.25)));
+ GameLogEcho(strcat(":anticheat:speedhack_m2:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_speedhack_m2), 240, 1.01, 1.25)));
+ GameLogEcho(strcat(":anticheat:speedhack_m3:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_speedhack_m3), 240, 1.01, 1.25)));
+ GameLogEcho(strcat(":anticheat:speedhack_m4:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_speedhack_m4), 240, 1.01, 1.25)));
+ GameLogEcho(strcat(":anticheat:speedhack_m5:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_speedhack_m5), 240, 1.01, 1.25)));
+ GameLogEcho(strcat(":anticheat:div0_strafebot_old:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_div0_strafebot_old), 120, 0.15, 0.4)));
+ GameLogEcho(strcat(":anticheat:div0_strafebot_new:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_div0_strafebot_new), 120, 0.25, 0.8)));
+ GameLogEcho(strcat(":anticheat:div0_evade:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_div0_evade), 120, 0.2, 0.5)));
+ GameLogEcho(strcat(":anticheat:idle_snapaim:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_signal) - MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_noise), 120, 0, 9999)));
+ GameLogEcho(strcat(":anticheat:idle_snapaim_signal:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_signal), 120, 0, 9999)));
+ GameLogEcho(strcat(":anticheat:idle_snapaim_noise:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_noise), 120, 0, 9999)));
+ GameLogEcho(strcat(":anticheat:idle_snapaim_m2:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_m2), 120, 0, 9999)));
+ GameLogEcho(strcat(":anticheat:idle_snapaim_m3:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_m3), 120, 0, 9999)));
+ GameLogEcho(strcat(":anticheat:idle_snapaim_m4:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_m4), 120, 0, 9999)));
+ GameLogEcho(strcat(":anticheat:idle_snapaim_m7:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_m7), 120, 0, 9999)));
+ GameLogEcho(strcat(":anticheat:idle_snapaim_m10:", ftos(this.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_m10), 120, 0, 9999)));
}
-float anticheat_getvalue(string id)
-{SELFPARAM();
+float anticheat_getvalue(entity this, string id)
+{
switch(id) {
- case "_time": return servertime - CS(self).anticheat_jointime;
- case "speedhack": return MEAN_EVALUATE(CS(self), anticheat_speedhack);
- case "speedhack_m1": return MEAN_EVALUATE(CS(self), anticheat_speedhack_m1);
- case "speedhack_m2": return MEAN_EVALUATE(CS(self), anticheat_speedhack_m2);
- case "speedhack_m3": return MEAN_EVALUATE(CS(self), anticheat_speedhack_m3);
- case "speedhack_m4": return MEAN_EVALUATE(CS(self), anticheat_speedhack_m4);
- case "speedhack_m5": return MEAN_EVALUATE(CS(self), anticheat_speedhack_m5);
- case "div0_strafebot_old": return MEAN_EVALUATE(CS(self), anticheat_div0_strafebot_old);
- case "div0_strafebot_new": return MEAN_EVALUATE(CS(self), anticheat_div0_strafebot_new);
- case "div0_evade": return MEAN_EVALUATE(CS(self), anticheat_div0_evade);
- case "idle_snapaim": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_signal) - MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_noise);
- case "idle_snapaim_signal": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_signal);
- case "idle_snapaim_noise": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_noise);
- case "idle_snapaim_m2": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m2);
- case "idle_snapaim_m3": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m3);
- case "idle_snapaim_m4": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m4);
- case "idle_snapaim_m7": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m7);
- case "idle_snapaim_m10": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m10);
+ case "_time": return servertime - CS(this).anticheat_jointime;
+ case "speedhack": return MEAN_EVALUATE(CS(this), anticheat_speedhack);
+ case "speedhack_m1": return MEAN_EVALUATE(CS(this), anticheat_speedhack_m1);
+ case "speedhack_m2": return MEAN_EVALUATE(CS(this), anticheat_speedhack_m2);
+ case "speedhack_m3": return MEAN_EVALUATE(CS(this), anticheat_speedhack_m3);
+ case "speedhack_m4": return MEAN_EVALUATE(CS(this), anticheat_speedhack_m4);
+ case "speedhack_m5": return MEAN_EVALUATE(CS(this), anticheat_speedhack_m5);
+ case "div0_strafebot_old": return MEAN_EVALUATE(CS(this), anticheat_div0_strafebot_old);
+ case "div0_strafebot_new": return MEAN_EVALUATE(CS(this), anticheat_div0_strafebot_new);
+ case "div0_evade": return MEAN_EVALUATE(CS(this), anticheat_div0_evade);
+ case "idle_snapaim": return MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_signal) - MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_noise);
+ case "idle_snapaim_signal": return MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_signal);
+ case "idle_snapaim_noise": return MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_noise);
+ case "idle_snapaim_m2": return MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_m2);
+ case "idle_snapaim_m3": return MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_m3);
+ case "idle_snapaim_m4": return MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_m4);
+ case "idle_snapaim_m7": return MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_m7);
+ case "idle_snapaim_m10": return MEAN_EVALUATE(CS(this), anticheat_idle_snapaim_m10);
}
return -1;
}
}
void anticheat_endframe()
-{SELFPARAM();
+{
FOREACH_CLIENT(it.fixangle, anticheat_fixangle(it));
anticheat_div0_evade_evasion_delta += frametime * (0.5 + random());
}
#pragma once
void anticheat_init(entity this);
-void anticheat_report();
+void anticheat_report(entity this);
void anticheat_physics(entity this);
-void anticheat_spectatecopy(entity spectatee);
-void anticheat_prethink();
+void anticheat_spectatecopy(entity this, entity spectatee);
+void anticheat_prethink(entity this);
-float anticheat_getvalue(string name);
+float anticheat_getvalue(entity this, string name);
void anticheat_startframe();
void anticheat_endframe();
return false;
}
-void lag_update()
-{SELFPARAM();
- if (self.lag1_time) if (time > self.lag1_time) {self.lag_func(self.lag1_time, self.lag1_float1, self.lag1_float2, self.lag1_entity1, self.lag1_vec1, self.lag1_vec2, self.lag1_vec3, self.lag1_vec4);self.lag1_time = 0;}
- if (self.lag2_time) if (time > self.lag2_time) {self.lag_func(self.lag2_time, self.lag2_float1, self.lag2_float2, self.lag2_entity1, self.lag2_vec1, self.lag2_vec2, self.lag2_vec3, self.lag2_vec4);self.lag2_time = 0;}
- if (self.lag3_time) if (time > self.lag3_time) {self.lag_func(self.lag3_time, self.lag3_float1, self.lag3_float2, self.lag3_entity1, self.lag3_vec1, self.lag3_vec2, self.lag3_vec3, self.lag3_vec4);self.lag3_time = 0;}
- if (self.lag4_time) if (time > self.lag4_time) {self.lag_func(self.lag4_time, self.lag4_float1, self.lag4_float2, self.lag4_entity1, self.lag4_vec1, self.lag4_vec2, self.lag4_vec3, self.lag4_vec4);self.lag4_time = 0;}
- if (self.lag5_time) if (time > self.lag5_time) {self.lag_func(self.lag5_time, self.lag5_float1, self.lag5_float2, self.lag5_entity1, self.lag5_vec1, self.lag5_vec2, self.lag5_vec3, self.lag5_vec4);self.lag5_time = 0;}
+void lag_update(entity this)
+{
+ if (this.lag1_time) if (time > this.lag1_time) {this.lag_func(this, this.lag1_time, this.lag1_float1, this.lag1_float2, this.lag1_entity1, this.lag1_vec1, this.lag1_vec2, this.lag1_vec3, this.lag1_vec4);this.lag1_time = 0;}
+ if (this.lag2_time) if (time > this.lag2_time) {this.lag_func(this, this.lag2_time, this.lag2_float1, this.lag2_float2, this.lag2_entity1, this.lag2_vec1, this.lag2_vec2, this.lag2_vec3, this.lag2_vec4);this.lag2_time = 0;}
+ if (this.lag3_time) if (time > this.lag3_time) {this.lag_func(this, this.lag3_time, this.lag3_float1, this.lag3_float2, this.lag3_entity1, this.lag3_vec1, this.lag3_vec2, this.lag3_vec3, this.lag3_vec4);this.lag3_time = 0;}
+ if (this.lag4_time) if (time > this.lag4_time) {this.lag_func(this, this.lag4_time, this.lag4_float1, this.lag4_float2, this.lag4_entity1, this.lag4_vec1, this.lag4_vec2, this.lag4_vec3, this.lag4_vec4);this.lag4_time = 0;}
+ if (this.lag5_time) if (time > this.lag5_time) {this.lag_func(this, this.lag5_time, this.lag5_float1, this.lag5_float2, this.lag5_entity1, this.lag5_vec1, this.lag5_vec2, this.lag5_vec3, this.lag5_vec4);this.lag5_time = 0;}
}
-float lag_additem(float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4)
-{SELFPARAM();
- if (self.lag1_time == 0) {self.lag1_time = t;self.lag1_float1 = f1;self.lag1_float2 = f2;self.lag1_entity1 = e1;self.lag1_vec1 = v1;self.lag1_vec2 = v2;self.lag1_vec3 = v3;self.lag1_vec4 = v4;return true;}
- if (self.lag2_time == 0) {self.lag2_time = t;self.lag2_float1 = f1;self.lag2_float2 = f2;self.lag2_entity1 = e1;self.lag2_vec1 = v1;self.lag2_vec2 = v2;self.lag2_vec3 = v3;self.lag2_vec4 = v4;return true;}
- if (self.lag3_time == 0) {self.lag3_time = t;self.lag3_float1 = f1;self.lag3_float2 = f2;self.lag3_entity1 = e1;self.lag3_vec1 = v1;self.lag3_vec2 = v2;self.lag3_vec3 = v3;self.lag3_vec4 = v4;return true;}
- if (self.lag4_time == 0) {self.lag4_time = t;self.lag4_float1 = f1;self.lag4_float2 = f2;self.lag4_entity1 = e1;self.lag4_vec1 = v1;self.lag4_vec2 = v2;self.lag4_vec3 = v3;self.lag4_vec4 = v4;return true;}
- if (self.lag5_time == 0) {self.lag5_time = t;self.lag5_float1 = f1;self.lag5_float2 = f2;self.lag5_entity1 = e1;self.lag5_vec1 = v1;self.lag5_vec2 = v2;self.lag5_vec3 = v3;self.lag5_vec4 = v4;return true;}
+float lag_additem(entity this, float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4)
+{
+ if (this.lag1_time == 0) {this.lag1_time = t;this.lag1_float1 = f1;this.lag1_float2 = f2;this.lag1_entity1 = e1;this.lag1_vec1 = v1;this.lag1_vec2 = v2;this.lag1_vec3 = v3;this.lag1_vec4 = v4;return true;}
+ if (this.lag2_time == 0) {this.lag2_time = t;this.lag2_float1 = f1;this.lag2_float2 = f2;this.lag2_entity1 = e1;this.lag2_vec1 = v1;this.lag2_vec2 = v2;this.lag2_vec3 = v3;this.lag2_vec4 = v4;return true;}
+ if (this.lag3_time == 0) {this.lag3_time = t;this.lag3_float1 = f1;this.lag3_float2 = f2;this.lag3_entity1 = e1;this.lag3_vec1 = v1;this.lag3_vec2 = v2;this.lag3_vec3 = v3;this.lag3_vec4 = v4;return true;}
+ if (this.lag4_time == 0) {this.lag4_time = t;this.lag4_float1 = f1;this.lag4_float2 = f2;this.lag4_entity1 = e1;this.lag4_vec1 = v1;this.lag4_vec2 = v2;this.lag4_vec3 = v3;this.lag4_vec4 = v4;return true;}
+ if (this.lag5_time == 0) {this.lag5_time = t;this.lag5_float1 = f1;this.lag5_float2 = f2;this.lag5_entity1 = e1;this.lag5_vec1 = v1;this.lag5_vec2 = v2;this.lag5_vec3 = v3;this.lag5_vec4 = v4;return true;}
// no room for it (what is the best thing to do here??)
return false;
}
-float bot_shouldattack(entity e)
-{SELFPARAM();
- if (e.team == self.team)
+bool bot_shouldattack(entity this, entity targ)
+{
+ if (targ.team == this.team)
{
- if (e == self)
+ if (targ == this)
return false;
if (teamplay)
- if (e.team != 0)
+ if (targ.team != 0)
return false;
}
- if(STAT(FROZEN, e))
+ if(STAT(FROZEN, targ))
return false;
if(teamplay)
{
- if(e.team==0)
+ if(targ.team==0)
return false;
}
else if(bot_ignore_bots)
- if(IS_BOT_CLIENT(e))
+ if(IS_BOT_CLIENT(targ))
return false;
- if (!e.takedamage)
+ if (!targ.takedamage)
return false;
- if (IS_DEAD(e))
+ if (IS_DEAD(targ))
return false;
- if (PHYS_INPUT_BUTTON_CHAT(e))
+ if (PHYS_INPUT_BUTTON_CHAT(targ))
return false;
- if(e.flags & FL_NOTARGET)
+ if(targ.flags & FL_NOTARGET)
return false;
- if(MUTATOR_CALLHOOK(BotShouldAttack, e))
+ if(MUTATOR_CALLHOOK(BotShouldAttack, this, targ))
return false;
return true;
}
-void bot_lagfunc(float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4)
-{SELFPARAM();
- if(self.flags & FL_INWATER)
+void bot_lagfunc(entity this, float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4)
+{
+ if(this.flags & FL_INWATER)
{
- self.bot_aimtarg = world;
+ this.bot_aimtarg = world;
return;
}
- self.bot_aimtarg = e1;
- self.bot_aimlatency = self.ping; // FIXME? Shouldn't this be in the lag item?
- self.bot_aimselforigin = v1;
- self.bot_aimselfvelocity = v2;
- self.bot_aimtargorigin = v3;
- self.bot_aimtargvelocity = v4;
+ this.bot_aimtarg = e1;
+ this.bot_aimlatency = this.ping; // FIXME? Shouldn't this be in the lag item?
+ this.bot_aimselforigin = v1;
+ this.bot_aimselfvelocity = v2;
+ this.bot_aimtargorigin = v3;
+ this.bot_aimtargvelocity = v4;
if(skill <= 0)
- self.bot_canfire = (random() < 0.8);
+ this.bot_canfire = (random() < 0.8);
else if(skill <= 1)
- self.bot_canfire = (random() < 0.9);
+ this.bot_canfire = (random() < 0.9);
else if(skill <= 2)
- self.bot_canfire = (random() < 0.95);
+ this.bot_canfire = (random() < 0.95);
else
- self.bot_canfire = 1;
+ this.bot_canfire = 1;
}
-float bot_aimdir(vector v, float maxfiredeviation)
-{SELFPARAM();
+float bot_aimdir(entity this, vector v, float maxfiredeviation)
+{
float dist, delta_t, blend;
vector desiredang, diffang;
- //dprint("aim ", self.netname, ": old:", vtos(self.v_angle));
+ //dprint("aim ", this.netname, ": old:", vtos(this.v_angle));
// make sure v_angle is sane first
- self.v_angle_y = self.v_angle.y - floor(self.v_angle.y / 360) * 360;
- self.v_angle_z = 0;
+ this.v_angle_y = this.v_angle.y - floor(this.v_angle.y / 360) * 360;
+ this.v_angle_z = 0;
// get the desired angles to aim at
//dprint(" at:", vtos(v));
v = normalize(v);
- //te_lightning2(world, self.origin + self.view_ofs, self.origin + self.view_ofs + v * 200);
- if (time >= self.bot_badaimtime)
+ //te_lightning2(world, this.origin + this.view_ofs, this.origin + this.view_ofs + v * 200);
+ if (time >= this.bot_badaimtime)
{
- self.bot_badaimtime = max(self.bot_badaimtime + 0.3, time);
- self.bot_badaimoffset = randomvec() * bound(0, 5 - 0.5 * (skill+self.bot_offsetskill), 5) * autocvar_bot_ai_aimskill_offset;
+ this.bot_badaimtime = max(this.bot_badaimtime + 0.3, time);
+ this.bot_badaimoffset = randomvec() * bound(0, 5 - 0.5 * (skill+this.bot_offsetskill), 5) * autocvar_bot_ai_aimskill_offset;
}
- desiredang = vectoangles(v) + self.bot_badaimoffset;
+ desiredang = vectoangles(v) + this.bot_badaimoffset;
//dprint(" desired:", vtos(desiredang));
if (desiredang.x >= 180)
desiredang.x = desiredang.x - 360;
desiredang.x = bound(-90, 0 - desiredang.x, 90);
- desiredang.z = self.v_angle.z;
+ desiredang.z = this.v_angle.z;
//dprint(" / ", vtos(desiredang));
//// pain throws off aim
- //if (self.bot_painintensity)
+ //if (this.bot_painintensity)
//{
// // shake from pain
- // desiredang = desiredang + randomvec() * self.bot_painintensity * 0.2;
+ // desiredang = desiredang + randomvec() * this.bot_painintensity * 0.2;
//}
// calculate turn angles
- diffang = (desiredang - self.bot_olddesiredang);
+ diffang = (desiredang - this.bot_olddesiredang);
// wrap yaw turn
diffang.y = diffang.y - floor(diffang.y / 360) * 360;
if (diffang.y >= 180)
diffang.y = diffang.y - 360;
- self.bot_olddesiredang = desiredang;
+ this.bot_olddesiredang = desiredang;
//dprint(" diff:", vtos(diffang));
- delta_t = time-self.bot_prevaimtime;
- self.bot_prevaimtime = time;
+ delta_t = time-this.bot_prevaimtime;
+ this.bot_prevaimtime = time;
// Here we will try to anticipate the comming aiming direction
- self.bot_1st_order_aimfilter= self.bot_1st_order_aimfilter
- + (diffang * (1 / delta_t) - self.bot_1st_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_1st,1);
- self.bot_2nd_order_aimfilter= self.bot_2nd_order_aimfilter
- + (self.bot_1st_order_aimfilter - self.bot_2nd_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_2nd,1);
- self.bot_3th_order_aimfilter= self.bot_3th_order_aimfilter
- + (self.bot_2nd_order_aimfilter - self.bot_3th_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_3th,1);
- self.bot_4th_order_aimfilter= self.bot_4th_order_aimfilter
- + (self.bot_3th_order_aimfilter - self.bot_4th_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_4th,1);
- self.bot_5th_order_aimfilter= self.bot_5th_order_aimfilter
- + (self.bot_4th_order_aimfilter - self.bot_5th_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_5th,1);
+ this.bot_1st_order_aimfilter= this.bot_1st_order_aimfilter
+ + (diffang * (1 / delta_t) - this.bot_1st_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_1st,1);
+ this.bot_2nd_order_aimfilter= this.bot_2nd_order_aimfilter
+ + (this.bot_1st_order_aimfilter - this.bot_2nd_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_2nd,1);
+ this.bot_3th_order_aimfilter= this.bot_3th_order_aimfilter
+ + (this.bot_2nd_order_aimfilter - this.bot_3th_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_3th,1);
+ this.bot_4th_order_aimfilter= this.bot_4th_order_aimfilter
+ + (this.bot_3th_order_aimfilter - this.bot_4th_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_4th,1);
+ this.bot_5th_order_aimfilter= this.bot_5th_order_aimfilter
+ + (this.bot_4th_order_aimfilter - this.bot_5th_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_5th,1);
//blend = (bound(0,skill,10)*0.1)*pow(1-bound(0,skill,10)*0.05,2.5)*5.656854249; //Plot formule before changing !
- blend = bound(0,skill+self.bot_aimskill,10)*0.1;
+ blend = bound(0,skill+this.bot_aimskill,10)*0.1;
desiredang = desiredang + blend *
(
- self.bot_1st_order_aimfilter * autocvar_bot_ai_aimskill_order_mix_1st
- + self.bot_2nd_order_aimfilter * autocvar_bot_ai_aimskill_order_mix_2nd
- + self.bot_3th_order_aimfilter * autocvar_bot_ai_aimskill_order_mix_3th
- + self.bot_4th_order_aimfilter * autocvar_bot_ai_aimskill_order_mix_4th
- + self.bot_5th_order_aimfilter * autocvar_bot_ai_aimskill_order_mix_5th
+ this.bot_1st_order_aimfilter * autocvar_bot_ai_aimskill_order_mix_1st
+ + this.bot_2nd_order_aimfilter * autocvar_bot_ai_aimskill_order_mix_2nd
+ + this.bot_3th_order_aimfilter * autocvar_bot_ai_aimskill_order_mix_3th
+ + this.bot_4th_order_aimfilter * autocvar_bot_ai_aimskill_order_mix_4th
+ + this.bot_5th_order_aimfilter * autocvar_bot_ai_aimskill_order_mix_5th
);
// calculate turn angles
- diffang = desiredang - self.bot_mouseaim;
+ diffang = desiredang - this.bot_mouseaim;
// wrap yaw turn
diffang.y = diffang.y - floor(diffang.y / 360) * 360;
if (diffang.y >= 180)
diffang.y = diffang.y - 360;
//dprint(" diff:", vtos(diffang));
- if (time >= self.bot_aimthinktime)
+ if (time >= this.bot_aimthinktime)
{
- self.bot_aimthinktime = max(self.bot_aimthinktime + 0.5 - 0.05*(skill+self.bot_thinkskill), time);
- self.bot_mouseaim = self.bot_mouseaim + diffang * (1-random()*0.1*bound(1,10-(skill+self.bot_thinkskill),10));
+ this.bot_aimthinktime = max(this.bot_aimthinktime + 0.5 - 0.05*(skill+this.bot_thinkskill), time);
+ this.bot_mouseaim = this.bot_mouseaim + diffang * (1-random()*0.1*bound(1,10-(skill+this.bot_thinkskill),10));
}
- //self.v_angle = self.v_angle + diffang * bound(0, r * frametime * (skill * 0.5 + 2), 1);
+ //this.v_angle = this.v_angle + diffang * bound(0, r * frametime * (skill * 0.5 + 2), 1);
- diffang = self.bot_mouseaim - desiredang;
+ diffang = this.bot_mouseaim - desiredang;
// wrap yaw turn
diffang.y = diffang.y - floor(diffang.y / 360) * 360;
if (diffang.y >= 180)
desiredang = desiredang + diffang * bound(0,autocvar_bot_ai_aimskill_think,1);
// calculate turn angles
- diffang = desiredang - self.v_angle;
+ diffang = desiredang - this.v_angle;
// wrap yaw turn
diffang.y = diffang.y - floor(diffang.y / 360) * 360;
if (diffang.y >= 180)
fixedrate = autocvar_bot_ai_aimskill_fixedrate / bound(1,dist,1000);
blendrate = autocvar_bot_ai_aimskill_blendrate;
r = max(fixedrate, blendrate);
- //self.v_angle = self.v_angle + diffang * bound(frametime, r * frametime * (2+skill*skill*0.05-random()*0.05*(10-skill)), 1);
- self.v_angle = self.v_angle + diffang * bound(delta_t, r * delta_t * (2+pow(skill+self.bot_mouseskill,3)*0.005-random()), 1);
- self.v_angle = self.v_angle * bound(0,autocvar_bot_ai_aimskill_mouse,1) + desiredang * bound(0,(1-autocvar_bot_ai_aimskill_mouse),1);
- //self.v_angle = self.v_angle + diffang * bound(0, r * frametime * (skill * 0.5 + 2), 1);
- //self.v_angle = self.v_angle + diffang * (1/ blendrate);
- self.v_angle_z = 0;
- self.v_angle_y = self.v_angle.y - floor(self.v_angle.y / 360) * 360;
- //dprint(" turn:", vtos(self.v_angle));
-
- makevectors(self.v_angle);
- shotorg = self.origin + self.view_ofs;
+ //this.v_angle = this.v_angle + diffang * bound(frametime, r * frametime * (2+skill*skill*0.05-random()*0.05*(10-skill)), 1);
+ this.v_angle = this.v_angle + diffang * bound(delta_t, r * delta_t * (2+pow(skill+this.bot_mouseskill,3)*0.005-random()), 1);
+ this.v_angle = this.v_angle * bound(0,autocvar_bot_ai_aimskill_mouse,1) + desiredang * bound(0,(1-autocvar_bot_ai_aimskill_mouse),1);
+ //this.v_angle = this.v_angle + diffang * bound(0, r * frametime * (skill * 0.5 + 2), 1);
+ //this.v_angle = this.v_angle + diffang * (1/ blendrate);
+ this.v_angle_z = 0;
+ this.v_angle_y = this.v_angle.y - floor(this.v_angle.y / 360) * 360;
+ //dprint(" turn:", vtos(this.v_angle));
+
+ makevectors(this.v_angle);
+ shotorg = this.origin + this.view_ofs;
shotdir = v_forward;
//dprint(" dir:", vtos(v_forward));
//te_lightning2(world, shotorg, shotorg + shotdir * 100);
// calculate turn angles again
- //diffang = desiredang - self.v_angle;
+ //diffang = desiredang - this.v_angle;
//diffang_y = diffang_y - floor(diffang_y / 360) * 360;
//if (diffang_y >= 180)
// diffang_y = diffang_y - 360;
// note the maxfiredeviation is in degrees so this has to convert to radians first
//if ((normalize(v) * shotdir) >= cos(maxfiredeviation * (3.14159265358979323846 / 180)))
if ((normalize(v) * shotdir) >= cos(maxfiredeviation * (3.14159265358979323846 / 180)))
- if(vdist(trace_endpos-shotorg, <, 500 + 500 * bound(0, skill + self.bot_aggresskill, 10)) || random()*random()>bound(0,(skill+self.bot_aggresskill)*0.05,1))
- self.bot_firetimer = time + bound(0.1, 0.5-(skill+self.bot_aggresskill)*0.05, 0.5);
+ if(vdist(trace_endpos-shotorg, <, 500 + 500 * bound(0, skill + this.bot_aggresskill, 10)) || random()*random()>bound(0,(skill+this.bot_aggresskill)*0.05,1))
+ this.bot_firetimer = time + bound(0.1, 0.5-(skill+this.bot_aggresskill)*0.05, 0.5);
//traceline(shotorg,shotorg+shotdir*1000,false,world);
//dprint(ftos(maxfiredeviation),"\n");
//dprint(" diff:", vtos(diffang), "\n");
- return self.bot_canfire && (time < self.bot_firetimer);
+ return this.bot_canfire && (time < this.bot_firetimer);
}
vector bot_shotlead(vector targorigin, vector targvelocity, float shotspeed, float shotdelay)
return targorigin + targvelocity * (shotdelay + vlen(targorigin - shotorg) / shotspeed);
}
-float bot_aim(float shotspeed, float shotspeedupward, float maxshottime, float applygravity)
-{SELFPARAM();
+bool bot_aim(entity this, float shotspeed, float shotspeedupward, float maxshottime, bool applygravity)
+{
float f, r, hf, distanceratio;
vector v;
/*
- eprint(self);
+ eprint(this);
dprint("bot_aim(", ftos(shotspeed));
dprint(", ", ftos(shotspeedupward));
dprint(", ", ftos(maxshottime));
dprint(");\n");
*/
- hf = self.dphitcontentsmask;
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
+ hf = this.dphitcontentsmask;
+ this.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
shotspeed *= W_WeaponSpeedFactor();
shotspeedupward *= W_WeaponSpeedFactor();
if (!shotspeed)
{
- LOG_TRACE("bot_aim: WARNING: weapon ", PS(self).m_weapon.m_name, " shotspeed is zero!\n");
+ LOG_TRACE("bot_aim: WARNING: weapon ", PS(this).m_weapon.m_name, " shotspeed is zero!\n");
shotspeed = 1000000;
}
if (!maxshottime)
{
- LOG_TRACE("bot_aim: WARNING: weapon ", PS(self).m_weapon.m_name, " maxshottime is zero!\n");
+ LOG_TRACE("bot_aim: WARNING: weapon ", PS(this).m_weapon.m_name, " maxshottime is zero!\n");
maxshottime = 1;
}
- makevectors(self.v_angle);
- shotorg = self.origin + self.view_ofs;
+ makevectors(this.v_angle);
+ shotorg = this.origin + this.view_ofs;
shotdir = v_forward;
- v = bot_shotlead(self.bot_aimtargorigin, self.bot_aimtargvelocity, shotspeed, self.bot_aimlatency);
+ v = bot_shotlead(this.bot_aimtargorigin, this.bot_aimtargvelocity, shotspeed, this.bot_aimlatency);
distanceratio = sqrt(bound(0,skill,10000))*0.3*(vlen(v-shotorg)-100)/autocvar_bot_ai_aimskill_firetolerance_distdegrees;
distanceratio = bound(0,distanceratio,1);
r = (autocvar_bot_ai_aimskill_firetolerance_maxdegrees-autocvar_bot_ai_aimskill_firetolerance_mindegrees)
* (1-distanceratio) + autocvar_bot_ai_aimskill_firetolerance_mindegrees;
- if (applygravity && self.bot_aimtarg)
+ if (applygravity && this.bot_aimtarg)
{
- if (!findtrajectorywithleading(shotorg, '0 0 0', '0 0 0', self.bot_aimtarg, shotspeed, shotspeedupward, maxshottime, 0, self))
+ if (!findtrajectorywithleading(shotorg, '0 0 0', '0 0 0', this.bot_aimtarg, shotspeed, shotspeedupward, maxshottime, 0, this))
{
- self.dphitcontentsmask = hf;
+ this.dphitcontentsmask = hf;
return false;
}
- f = bot_aimdir(findtrajectory_velocity - shotspeedupward * '0 0 1', r);
+ f = bot_aimdir(this, findtrajectory_velocity - shotspeedupward * '0 0 1', r);
}
else
{
- f = bot_aimdir(v - shotorg, r);
- //dprint("AIM: ");dprint(vtos(self.bot_aimtargorigin));dprint(" + ");dprint(vtos(self.bot_aimtargvelocity));dprint(" * ");dprint(ftos(self.bot_aimlatency + vlen(self.bot_aimtargorigin - shotorg) / shotspeed));dprint(" = ");dprint(vtos(v));dprint(" : aimdir = ");dprint(vtos(normalize(v - shotorg)));dprint(" : ");dprint(vtos(shotdir));dprint("\n");
- //traceline(shotorg, shotorg + shotdir * 10000, false, self);
+ f = bot_aimdir(this, v - shotorg, r);
+ //dprint("AIM: ");dprint(vtos(this.bot_aimtargorigin));dprint(" + ");dprint(vtos(this.bot_aimtargvelocity));dprint(" * ");dprint(ftos(this.bot_aimlatency + vlen(this.bot_aimtargorigin - shotorg) / shotspeed));dprint(" = ");dprint(vtos(v));dprint(" : aimdir = ");dprint(vtos(normalize(v - shotorg)));dprint(" : ");dprint(vtos(shotdir));dprint("\n");
+ //traceline(shotorg, shotorg + shotdir * 10000, false, this);
//if (trace_ent.takedamage)
//if (trace_fraction < 1)
- //if (!bot_shouldattack(trace_ent))
+ //if (!bot_shouldattack(this, trace_ent))
// return false;
- traceline(shotorg, self.bot_aimtargorigin, false, self);
+ traceline(shotorg, this.bot_aimtargorigin, false, this);
if (trace_fraction < 1)
- if (trace_ent != self.enemy)
- if (!bot_shouldattack(trace_ent))
+ if (trace_ent != this.enemy)
+ if (!bot_shouldattack(this, trace_ent))
{
- self.dphitcontentsmask = hf;
+ this.dphitcontentsmask = hf;
return false;
}
}
//if (r > maxshottime * shotspeed)
// return false;
- self.dphitcontentsmask = hf;
+ this.dphitcontentsmask = hf;
return true;
}
* Functions
*/
-float lag_additem(float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4);
-void lag_update();
-void bot_lagfunc(float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4);
+float lag_additem(entity this, float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4);
+void lag_update(entity this);
+void bot_lagfunc(entity this, float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4);
-float bot_shouldattack(entity e);
-float bot_aimdir(vector v, float maxfiredeviation);
-float bot_aim(float shotspeed, float shotspeedupward, float maxshottime, float applygravity);
+float bot_shouldattack(entity this, entity targ);
+float bot_aimdir(entity this, vector v, float maxfiredeviation);
+bool bot_aim(entity this, float shotspeed, float shotspeedupward, float maxshottime, bool applygravity);
float findtrajectorywithleading(vector org, vector m1, vector m2, entity targ, float shotspeed, float shotspeedupward, float maxtime, float shotdelay, entity ignore);
vector bot_shotlead(vector targorigin, vector targvelocity, float shotspeed, float shotdelay);
-.void(float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4) lag_func;
+.void(entity this, float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4) lag_func;
#include <lib/warpzone/util_server.qh>
entity bot_spawn()
-{SELFPARAM();
+{
entity bot = spawnclient();
if (bot)
{
currentbots = currentbots + 1;
- setself(bot);
- bot_setnameandstuff();
- ClientConnect();
- PutClientInServer();
- setself(this);
+ bot_setnameandstuff(bot);
+ WITH(entity, self, bot, ClientConnect());
+ WITH(entity, self, bot, PutClientInServer());
}
return bot;
}
-void bot_think()
-{SELFPARAM();
- if (self.bot_nextthink > time)
+void bot_think(entity this)
+{
+ if (this.bot_nextthink > time)
return;
- self.flags &= ~FL_GODMODE;
+ this.flags &= ~FL_GODMODE;
if(autocvar_bot_god)
- self.flags |= FL_GODMODE;
+ this.flags |= FL_GODMODE;
- self.bot_nextthink = self.bot_nextthink + autocvar_bot_ai_thinkinterval * pow(0.5, self.bot_aiskill);
- //if (self.bot_painintensity > 0)
- // self.bot_painintensity = self.bot_painintensity - (skill + 1) * 40 * frametime;
+ this.bot_nextthink = this.bot_nextthink + autocvar_bot_ai_thinkinterval * pow(0.5, this.bot_aiskill);
+ //if (this.bot_painintensity > 0)
+ // this.bot_painintensity = this.bot_painintensity - (skill + 1) * 40 * frametime;
- //self.bot_painintensity = self.bot_painintensity + self.bot_oldhealth - self.health;
- //self.bot_painintensity = bound(0, self.bot_painintensity, 100);
+ //this.bot_painintensity = this.bot_painintensity + this.bot_oldhealth - this.health;
+ //this.bot_painintensity = bound(0, this.bot_painintensity, 100);
- if (!IS_PLAYER(self) || (autocvar_g_campaign && !campaign_bots_may_start))
+ if (!IS_PLAYER(this) || (autocvar_g_campaign && !campaign_bots_may_start))
{
- self.bot_nextthink = time + 0.5;
+ this.bot_nextthink = time + 0.5;
return;
}
- if (self.fixangle)
+ if (this.fixangle)
{
- self.v_angle = self.angles;
- self.v_angle_z = 0;
- self.fixangle = false;
+ this.v_angle = this.angles;
+ this.v_angle_z = 0;
+ this.fixangle = false;
}
- self.dmg_take = 0;
- self.dmg_save = 0;
- self.dmg_inflictor = world;
+ this.dmg_take = 0;
+ this.dmg_save = 0;
+ this.dmg_inflictor = world;
// calculate an aiming latency based on the skill setting
// (simulated network latency + naturally delayed reflexes)
- //self.ping = 0.7 - bound(0, 0.05 * skill, 0.5); // moved the reflexes to bot_aimdir (under the name 'think')
+ //this.ping = 0.7 - bound(0, 0.05 * skill, 0.5); // moved the reflexes to bot_aimdir (under the name 'think')
// minimum ping 20+10 random
- self.ping = bound(0,0.07 - bound(0, (skill + self.bot_pingskill) * 0.005,0.05)+random()*0.01,0.65); // Now holds real lag to server, and higer skill players take a less laggy server
+ this.ping = bound(0,0.07 - bound(0, (skill + this.bot_pingskill) * 0.005,0.05)+random()*0.01,0.65); // Now holds real lag to server, and higer skill players take a less laggy server
// skill 10 = ping 0.2 (adrenaline)
// skill 0 = ping 0.7 (slightly drunk)
// clear buttons
- PHYS_INPUT_BUTTON_ATCK(self) = false;
- PHYS_INPUT_BUTTON_JUMP(self) = false;
- PHYS_INPUT_BUTTON_ATCK2(self) = false;
- PHYS_INPUT_BUTTON_ZOOM(self) = false;
- PHYS_INPUT_BUTTON_CROUCH(self) = false;
- PHYS_INPUT_BUTTON_HOOK(self) = false;
- PHYS_INPUT_BUTTON_INFO(self) = false;
- PHYS_INPUT_BUTTON_DRAG(self) = false;
- PHYS_INPUT_BUTTON_CHAT(self) = false;
- PHYS_INPUT_BUTTON_USE(self) = false;
+ PHYS_INPUT_BUTTON_ATCK(this) = false;
+ PHYS_INPUT_BUTTON_JUMP(this) = false;
+ PHYS_INPUT_BUTTON_ATCK2(this) = false;
+ PHYS_INPUT_BUTTON_ZOOM(this) = false;
+ PHYS_INPUT_BUTTON_CROUCH(this) = false;
+ PHYS_INPUT_BUTTON_HOOK(this) = false;
+ PHYS_INPUT_BUTTON_INFO(this) = false;
+ PHYS_INPUT_BUTTON_DRAG(this) = false;
+ PHYS_INPUT_BUTTON_CHAT(this) = false;
+ PHYS_INPUT_BUTTON_USE(this) = false;
if (time < game_starttime)
{
// block the bot during the countdown to game start
- self.movement = '0 0 0';
- self.bot_nextthink = game_starttime;
+ this.movement = '0 0 0';
+ this.bot_nextthink = game_starttime;
return;
}
// if dead, just wait until we can respawn
- if (IS_DEAD(self))
+ if (IS_DEAD(this))
{
- if (self.deadflag == DEAD_DEAD)
+ if (this.deadflag == DEAD_DEAD)
{
- PHYS_INPUT_BUTTON_JUMP(self) = true; // press jump to respawn
- self.bot_strategytime = 0;
+ PHYS_INPUT_BUTTON_JUMP(this) = true; // press jump to respawn
+ this.bot_strategytime = 0;
}
}
- else if(self.aistatus & AI_STATUS_STUCK)
- navigation_unstuck();
+ else if(this.aistatus & AI_STATUS_STUCK)
+ navigation_unstuck(this);
// now call the current bot AI (havocbot for example)
- self.bot_ai();
+ this.bot_ai(this);
}
-void bot_setnameandstuff()
-{SELFPARAM();
+void bot_setnameandstuff(entity this)
+{
string readfile, s;
float file, tokens, prio;
if(argv(4) != "" && stof(argv(4)) >= 0) bot_pants = argv(4);
else bot_pants = ftos(floor(random() * 15));
- self.bot_forced_team = stof(argv(5));
+ this.bot_forced_team = stof(argv(5));
prio = 6;
- #define READSKILL(f,w,r) if(argv(prio) != "") self.f = stof(argv(prio)) * (w); else self.f = (!autocvar_g_campaign) * (2 * random() - 1) * (r) * (w); ++prio
+ #define READSKILL(f,w,r) if(argv(prio) != "") this.f = stof(argv(prio)) * (w); else this.f = (!autocvar_g_campaign) * (2 * random() - 1) * (r) * (w); ++prio
//print(bot_name, ": ping=", argv(9), "\n");
READSKILL(havocbot_keyboardskill, 0.5, 0.5); // keyboard skill
READSKILL(bot_thinkskill, 1, 0.5); // think skill
READSKILL(bot_aiskill, 2, 0); // "ai" skill
- self.bot_config_loaded = true;
+ this.bot_config_loaded = true;
// this is really only a default, JoinBestTeam is called later
- setcolor(self, stof(bot_shirt) * 16 + stof(bot_pants));
- self.bot_preferredcolors = self.clientcolors;
+ setcolor(this, stof(bot_shirt) * 16 + stof(bot_pants));
+ this.bot_preferredcolors = this.clientcolors;
// pick the name
if (autocvar_bot_usemodelnames)
++j;
));
if (j)
- self.netname = self.netname_freeme = strzone(strcat(prefix, name, "(", ftos(j), ")", suffix));
+ this.netname = this.netname_freeme = strzone(strcat(prefix, name, "(", ftos(j), ")", suffix));
else
- self.netname = self.netname_freeme = strzone(strcat(prefix, name, suffix));
+ this.netname = this.netname_freeme = strzone(strcat(prefix, name, suffix));
- self.cleanname = strzone(name);
+ this.cleanname = strzone(name);
// pick the model and skin
if(substring(bot_model, -4, 1) != ".")
bot_model = strcat(bot_model, ".iqm");
- self.playermodel = self.playermodel_freeme = strzone(strcat("models/player/", bot_model));
- self.playerskin = self.playerskin_freeme = strzone(bot_skin);
+ this.playermodel = this.playermodel_freeme = strzone(strcat("models/player/", bot_model));
+ this.playerskin = this.playerskin_freeme = strzone(bot_skin);
- self.cvar_cl_accuracy_data_share = 1; // share the bots weapon accuracy data with the world
- self.cvar_cl_accuracy_data_receive = 0; // don't receive any weapon accuracy data
+ this.cvar_cl_accuracy_data_share = 1; // share the bots weapon accuracy data with the world
+ this.cvar_cl_accuracy_data_receive = 0; // don't receive any weapon accuracy data
}
void bot_custom_weapon_priority_setup()
bot_strategytoken_taken = true;
}
-void bot_clientdisconnect()
-{SELFPARAM();
- if (!IS_BOT_CLIENT(self))
+void bot_clientdisconnect(entity this)
+{
+ if (!IS_BOT_CLIENT(this))
return;
- bot_clearqueue(self);
- if(self.cleanname)
- strunzone(self.cleanname);
- if(self.netname_freeme)
- strunzone(self.netname_freeme);
- if(self.playermodel_freeme)
- strunzone(self.playermodel_freeme);
- if(self.playerskin_freeme)
- strunzone(self.playerskin_freeme);
- self.cleanname = string_null;
- self.netname_freeme = string_null;
- self.playermodel_freeme = string_null;
- self.playerskin_freeme = string_null;
- if(self.bot_cmd_current)
- remove(self.bot_cmd_current);
- if(bot_waypoint_queue_owner==self)
+ bot_clearqueue(this);
+ if(this.cleanname)
+ strunzone(this.cleanname);
+ if(this.netname_freeme)
+ strunzone(this.netname_freeme);
+ if(this.playermodel_freeme)
+ strunzone(this.playermodel_freeme);
+ if(this.playerskin_freeme)
+ strunzone(this.playerskin_freeme);
+ this.cleanname = string_null;
+ this.netname_freeme = string_null;
+ this.playermodel_freeme = string_null;
+ this.playerskin_freeme = string_null;
+ if(this.bot_cmd_current)
+ remove(this.bot_cmd_current);
+ if(bot_waypoint_queue_owner==this)
bot_waypoint_queue_owner = world;
}
void bot_clientconnect(entity this)
{
if (!IS_BOT_CLIENT(this)) return;
- self.bot_preferredcolors = self.clientcolors;
- self.bot_nextthink = time - random();
- self.lag_func = bot_lagfunc;
- self.isbot = true;
- self.createdtime = self.bot_nextthink;
-
- if(!self.bot_config_loaded) // This is needed so team overrider doesn't break between matches
- bot_setnameandstuff();
-
- if(self.bot_forced_team==1)
- self.team = NUM_TEAM_1;
- else if(self.bot_forced_team==2)
- self.team = NUM_TEAM_2;
- else if(self.bot_forced_team==3)
- self.team = NUM_TEAM_3;
- else if(self.bot_forced_team==4)
- self.team = NUM_TEAM_4;
+ this.bot_preferredcolors = this.clientcolors;
+ this.bot_nextthink = time - random();
+ this.lag_func = bot_lagfunc;
+ this.isbot = true;
+ this.createdtime = this.bot_nextthink;
+
+ if(!this.bot_config_loaded) // This is needed so team overrider doesn't break between matches
+ bot_setnameandstuff(this);
+
+ if(this.bot_forced_team==1)
+ this.team = NUM_TEAM_1;
+ else if(this.bot_forced_team==2)
+ this.team = NUM_TEAM_2;
+ else if(this.bot_forced_team==3)
+ this.team = NUM_TEAM_3;
+ else if(this.bot_forced_team==4)
+ this.team = NUM_TEAM_4;
else
- JoinBestTeam(self, false, true);
+ JoinBestTeam(this, false, true);
- havocbot_setupbot();
+ havocbot_setupbot(this);
}
void bot_removefromlargestteam()
entity bot_spawn();
float bot_fixcount();
-void bot_think();
-void bot_setnameandstuff();
+void bot_think(entity this);
+void bot_setnameandstuff(entity this);
void bot_custom_weapon_priority_setup();
void bot_endgame();
void bot_relinkplayerlist();
-void bot_clientdisconnect();
+void bot_clientdisconnect(entity this);
void bot_clientconnect(entity this);
void bot_removefromlargestteam();
void bot_removenewest();
void autoskill(float factor);
void bot_serverframe();
-.void() bot_ai;
+.void(entity this) bot_ai;
.float(entity player, entity item) bot_pickupevalfunc;
/*
* Imports
*/
-void() havocbot_setupbot;
+void(entity this) havocbot_setupbot;
void bot_calculate_stepheightvec();
.float speed;
-void havocbot_ai()
-{SELFPARAM();
- if(self.draggedby)
+void havocbot_ai(entity this)
+{
+ if(this.draggedby)
return;
- if(bot_execute_commands())
+ if(bot_execute_commands(this))
return;
- if (bot_strategytoken == self)
+ if (bot_strategytoken == this)
if (!bot_strategytoken_taken)
{
- if(self.havocbot_blockhead)
+ if(this.havocbot_blockhead)
{
- self.havocbot_blockhead = false;
+ this.havocbot_blockhead = false;
}
else
{
- if (!self.jumppadcount)
- self.havocbot_role();
+ if (!this.jumppadcount)
+ this.havocbot_role(this); // little too far down the rabbit hole
}
// TODO: tracewalk() should take care of this job (better path finding under water)
// if we don't have a goal and we're under water look for a waypoint near the "shore" and push it
- if(IS_DEAD(self))
- if(self.goalcurrent==world)
- if(self.waterlevel==WATERLEVEL_SWIMMING || (self.aistatus & AI_STATUS_OUT_WATER))
+ if(IS_DEAD(this))
+ if(this.goalcurrent==world)
+ if(this.waterlevel==WATERLEVEL_SWIMMING || (this.aistatus & AI_STATUS_OUT_WATER))
{
// Look for the closest waypoint out of water
entity newgoal, head;
bestdistance = 10000;
for (head = findchain(classname, "waypoint"); head; head = head.chain)
{
- distance = vlen(head.origin - self.origin);
+ distance = vlen(head.origin - this.origin);
if(distance>10000)
continue;
- if(head.origin.z < self.origin.z)
+ if(head.origin.z < this.origin.z)
continue;
- if(head.origin.z - self.origin.z - self.view_ofs.z > 100)
+ if(head.origin.z - this.origin.z - this.view_ofs.z > 100)
continue;
if (pointcontents(head.origin + head.maxs + '0 0 1') != CONTENT_EMPTY)
continue;
- traceline(self.origin + self.view_ofs , head.origin, true, head);
+ traceline(this.origin + this.view_ofs , head.origin, true, head);
if(trace_fraction<1)
continue;
if(newgoal)
{
// te_wizspike(newgoal.origin);
- navigation_pushroute(newgoal);
+ navigation_pushroute(this, newgoal);
}
}
bot_strategytoken_taken = true;
}
- if(IS_DEAD(self))
+ if(IS_DEAD(this))
return;
- havocbot_chooseenemy();
- if (self.bot_chooseweapontime < time )
+ havocbot_chooseenemy(this);
+ if (this.bot_chooseweapontime < time )
{
- self.bot_chooseweapontime = time + autocvar_bot_ai_chooseweaponinterval;
- havocbot_chooseweapon();
+ this.bot_chooseweapontime = time + autocvar_bot_ai_chooseweaponinterval;
+ havocbot_chooseweapon(this);
}
- havocbot_aim();
- lag_update();
- if (self.bot_aimtarg)
+ havocbot_aim(this);
+ lag_update(this);
+ if (this.bot_aimtarg)
{
- self.aistatus |= AI_STATUS_ATTACKING;
- self.aistatus &= ~AI_STATUS_ROAMING;
+ this.aistatus |= AI_STATUS_ATTACKING;
+ this.aistatus &= ~AI_STATUS_ROAMING;
- if(self.weapons)
+ if(this.weapons)
{
- Weapon w = PS(self).m_weapon;
+ Weapon w = PS(this).m_weapon;
w.wr_aim(w);
- if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
+ if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(this))
{
- PHYS_INPUT_BUTTON_ATCK(self) = false;
- PHYS_INPUT_BUTTON_ATCK2(self) = false;
+ PHYS_INPUT_BUTTON_ATCK(this) = false;
+ PHYS_INPUT_BUTTON_ATCK2(this) = false;
}
else
{
- if(PHYS_INPUT_BUTTON_ATCK(self) || PHYS_INPUT_BUTTON_ATCK2(self))
- self.lastfiredweapon = PS(self).m_weapon.m_id;
+ if(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_ATCK2(this))
+ this.lastfiredweapon = PS(this).m_weapon.m_id;
}
}
else
{
- if(IS_PLAYER(self.bot_aimtarg))
- bot_aimdir(self.bot_aimtarg.origin + self.bot_aimtarg.view_ofs - self.origin - self.view_ofs , -1);
+ if(IS_PLAYER(this.bot_aimtarg))
+ bot_aimdir(this, this.bot_aimtarg.origin + this.bot_aimtarg.view_ofs - this.origin - this.view_ofs , -1);
}
}
- else if (self.goalcurrent)
+ else if (this.goalcurrent)
{
- self.aistatus |= AI_STATUS_ROAMING;
- self.aistatus &= ~AI_STATUS_ATTACKING;
+ this.aistatus |= AI_STATUS_ROAMING;
+ this.aistatus &= ~AI_STATUS_ATTACKING;
vector now,v,next;//,heading;
float aimdistance,skillblend,distanceblend,blend;
- next = now = ( (self.goalcurrent.absmin + self.goalcurrent.absmax) * 0.5) - (self.origin + self.view_ofs);
+ next = now = ( (this.goalcurrent.absmin + this.goalcurrent.absmax) * 0.5) - (this.origin + this.view_ofs);
aimdistance = vlen(now);
- //heading = self.velocity;
- //dprint(self.goalstack01.classname,etos(self.goalstack01),"\n");
+ //heading = this.velocity;
+ //dprint(this.goalstack01.classname,etos(this.goalstack01),"\n");
if(
- self.goalstack01 != self && self.goalstack01 != world && ((self.aistatus & AI_STATUS_RUNNING) == 0) &&
- !(self.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
+ this.goalstack01 != this && this.goalstack01 != world && ((this.aistatus & AI_STATUS_RUNNING) == 0) &&
+ !(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
)
- next = ((self.goalstack01.absmin + self.goalstack01.absmax) * 0.5) - (self.origin + self.view_ofs);
+ next = ((this.goalstack01.absmin + this.goalstack01.absmax) * 0.5) - (this.origin + this.view_ofs);
- skillblend=bound(0,(skill+self.bot_moveskill-2.5)*0.5,1); //lower skill player can't preturn
+ skillblend=bound(0,(skill+this.bot_moveskill-2.5)*0.5,1); //lower skill player can't preturn
distanceblend=bound(0,aimdistance/autocvar_bot_ai_keyboard_distance,1);
blend = skillblend * (1-distanceblend);
//v = (now * (distanceblend) + next * (1-distanceblend)) * (skillblend) + now * (1-skillblend);
//v = now * (distanceblend) * (skillblend) + next * (1-distanceblend) * (skillblend) + now * (1-skillblend);
//v = now * ((1-skillblend) + (distanceblend) * (skillblend)) + next * (1-distanceblend) * (skillblend);
v = now + blend * (next - now);
- //dprint(etos(self), " ");
+ //dprint(etos(this), " ");
//dprint(vtos(now), ":", vtos(next), "=", vtos(v), " (blend ", ftos(blend), ")\n");
//v = now * (distanceblend) + next * (1-distanceblend);
- if (self.waterlevel < WATERLEVEL_SWIMMING)
+ if (this.waterlevel < WATERLEVEL_SWIMMING)
v.z = 0;
//dprint("walk at:", vtos(v), "\n");
- //te_lightning2(world, self.origin, self.goalcurrent.origin);
- bot_aimdir(v, -1);
+ //te_lightning2(world, this.origin, this.goalcurrent.origin);
+ bot_aimdir(this, v, -1);
}
- havocbot_movetogoal();
+ havocbot_movetogoal(this);
// if the bot is not attacking, consider reloading weapons
- if (!(self.aistatus & AI_STATUS_ATTACKING))
+ if (!(this.aistatus & AI_STATUS_ATTACKING))
{
// we are currently holding a weapon that's not fully loaded, reload it
if(skill >= 2) // bots can only reload the held weapon on purpose past this skill
- if(self.clip_load < self.clip_size)
- self.impulse = 20; // "press" the reload button, not sure if this is done right
+ if(this.clip_load < this.clip_size)
+ this.impulse = 20; // "press" the reload button, not sure if this is done right
// if we're not reloading a weapon, switch to any weapon in our invnetory that's not fully loaded to reload it next
// the code above executes next frame, starting the reloading then
if(skill >= 5) // bots can only look for unloaded weapons past this skill
- if(self.clip_load >= 0) // only if we're not reloading a weapon already
+ if(this.clip_load >= 0) // only if we're not reloading a weapon already
{
FOREACH(Weapons, it != WEP_Null, LAMBDA(
- if((self.weapons & (it.m_wepset)) && (it.spawnflags & WEP_FLAG_RELOADABLE) && (self.weapon_load[it.m_id] < it.reloading_ammo))
- PS(self).m_switchweapon = it;
+ if((this.weapons & (it.m_wepset)) && (it.spawnflags & WEP_FLAG_RELOADABLE) && (this.weapon_load[it.m_id] < it.reloading_ammo))
+ PS(this).m_switchweapon = it;
));
}
}
}
-void havocbot_keyboard_movement(vector destorg)
-{SELFPARAM();
+void havocbot_keyboard_movement(entity this, vector destorg)
+{
vector keyboard;
float blend, maxspeed;
float sk;
- sk = skill + self.bot_moveskill;
+ sk = skill + this.bot_moveskill;
maxspeed = autocvar_sv_maxspeed;
- if (time < self.havocbot_keyboardtime)
+ if (time < this.havocbot_keyboardtime)
return;
- self.havocbot_keyboardtime =
+ this.havocbot_keyboardtime =
max(
- self.havocbot_keyboardtime
- + 0.05/max(1, sk+self.havocbot_keyboardskill)
- + random()*0.025/max(0.00025, skill+self.havocbot_keyboardskill)
+ this.havocbot_keyboardtime
+ + 0.05/max(1, sk+this.havocbot_keyboardskill)
+ + random()*0.025/max(0.00025, skill+this.havocbot_keyboardskill)
, time);
- keyboard = self.movement * (1.0 / maxspeed);
+ keyboard = this.movement * (1.0 / maxspeed);
float trigger, trigger1;
blend = bound(0,sk*0.1,1);
else
keyboard.z = 0;
- self.havocbot_keyboard = keyboard * maxspeed;
- if (self.havocbot_ducktime>time) PHYS_INPUT_BUTTON_CROUCH(self) = true;
+ this.havocbot_keyboard = keyboard * maxspeed;
+ if (this.havocbot_ducktime>time) PHYS_INPUT_BUTTON_CROUCH(this) = true;
- keyboard = self.havocbot_keyboard;
- blend = bound(0,vlen(destorg-self.origin)/autocvar_bot_ai_keyboard_distance,1); // When getting close move with 360 degree
- //dprint("movement ", vtos(self.movement), " keyboard ", vtos(keyboard), " blend ", ftos(blend), "\n");
- self.movement = self.movement + (keyboard - self.movement) * blend;
+ keyboard = this.havocbot_keyboard;
+ blend = bound(0,vlen(destorg-this.origin)/autocvar_bot_ai_keyboard_distance,1); // When getting close move with 360 degree
+ //dprint("movement ", vtos(this.movement), " keyboard ", vtos(keyboard), " blend ", ftos(blend), "\n");
+ this.movement = this.movement + (keyboard - this.movement) * blend;
}
-void havocbot_bunnyhop(vector dir)
-{SELFPARAM();
+void havocbot_bunnyhop(entity this, vector dir)
+{
float bunnyhopdistance;
vector deviation;
float maxspeed;
vector gco, gno;
// Don't jump when attacking
- if(self.aistatus & AI_STATUS_ATTACKING)
+ if(this.aistatus & AI_STATUS_ATTACKING)
return;
- if(IS_PLAYER(self.goalcurrent))
+ if(IS_PLAYER(this.goalcurrent))
return;
maxspeed = autocvar_sv_maxspeed;
- if(self.aistatus & AI_STATUS_DANGER_AHEAD)
+ if(this.aistatus & AI_STATUS_DANGER_AHEAD)
{
- self.aistatus &= ~AI_STATUS_RUNNING;
- PHYS_INPUT_BUTTON_JUMP(self) = false;
- self.bot_canruntogoal = 0;
- self.bot_timelastseengoal = 0;
+ this.aistatus &= ~AI_STATUS_RUNNING;
+ PHYS_INPUT_BUTTON_JUMP(this) = false;
+ this.bot_canruntogoal = 0;
+ this.bot_timelastseengoal = 0;
return;
}
- if(self.waterlevel > WATERLEVEL_WETFEET)
+ if(this.waterlevel > WATERLEVEL_WETFEET)
{
- self.aistatus &= ~AI_STATUS_RUNNING;
+ this.aistatus &= ~AI_STATUS_RUNNING;
return;
}
- if(self.bot_lastseengoal != self.goalcurrent && !(self.aistatus & AI_STATUS_RUNNING))
+ if(this.bot_lastseengoal != this.goalcurrent && !(this.aistatus & AI_STATUS_RUNNING))
{
- self.bot_canruntogoal = 0;
- self.bot_timelastseengoal = 0;
+ this.bot_canruntogoal = 0;
+ this.bot_timelastseengoal = 0;
}
- gco = (self.goalcurrent.absmin + self.goalcurrent.absmax) * 0.5;
- bunnyhopdistance = vlen(self.origin - gco);
+ gco = (this.goalcurrent.absmin + this.goalcurrent.absmax) * 0.5;
+ bunnyhopdistance = vlen(this.origin - gco);
// Run only to visible goals
- if(IS_ONGROUND(self))
- if(self.speed==maxspeed)
- if(checkpvs(self.origin + self.view_ofs, self.goalcurrent))
+ if(IS_ONGROUND(this))
+ if(this.speed==maxspeed)
+ if(checkpvs(this.origin + this.view_ofs, this.goalcurrent))
{
- self.bot_lastseengoal = self.goalcurrent;
+ this.bot_lastseengoal = this.goalcurrent;
// seen it before
- if(self.bot_timelastseengoal)
+ if(this.bot_timelastseengoal)
{
// for a period of time
- if(time - self.bot_timelastseengoal > autocvar_bot_ai_bunnyhop_firstjumpdelay)
+ if(time - this.bot_timelastseengoal > autocvar_bot_ai_bunnyhop_firstjumpdelay)
{
float checkdistance;
checkdistance = true;
// don't run if it is too close
- if(self.bot_canruntogoal==0)
+ if(this.bot_canruntogoal==0)
{
if(bunnyhopdistance > autocvar_bot_ai_bunnyhop_startdistance)
- self.bot_canruntogoal = 1;
+ this.bot_canruntogoal = 1;
else
- self.bot_canruntogoal = -1;
+ this.bot_canruntogoal = -1;
}
- if(self.bot_canruntogoal != 1)
+ if(this.bot_canruntogoal != 1)
return;
- if(self.aistatus & AI_STATUS_ROAMING)
- if(self.goalcurrent.classname=="waypoint")
- if (!(self.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL))
- if(fabs(gco.z - self.origin.z) < self.maxs.z - self.mins.z)
- if(self.goalstack01!=world)
+ if(this.aistatus & AI_STATUS_ROAMING)
+ if(this.goalcurrent.classname=="waypoint")
+ if (!(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL))
+ if(fabs(gco.z - this.origin.z) < this.maxs.z - this.mins.z)
+ if(this.goalstack01!=world)
{
- gno = (self.goalstack01.absmin + self.goalstack01.absmax) * 0.5;
- deviation = vectoangles(gno - self.origin) - vectoangles(gco - self.origin);
+ gno = (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5;
+ deviation = vectoangles(gno - this.origin) - vectoangles(gco - this.origin);
while (deviation.y < -180) deviation.y = deviation.y + 360;
while (deviation.y > 180) deviation.y = deviation.y - 360;
if(fabs(deviation.y) < 20)
- if(bunnyhopdistance < vlen(self.origin - gno))
- if(fabs(gno.z - gco.z) < self.maxs.z - self.mins.z)
+ if(bunnyhopdistance < vlen(this.origin - gno))
+ if(fabs(gno.z - gco.z) < this.maxs.z - this.mins.z)
{
- if(vlen(gco - gno) > autocvar_bot_ai_bunnyhop_startdistance)
- if(checkpvs(self.origin + self.view_ofs, self.goalstack01))
+ if(vdist(gco - gno, >, autocvar_bot_ai_bunnyhop_startdistance))
+ if(checkpvs(this.origin + this.view_ofs, this.goalstack01))
{
checkdistance = false;
}
if(checkdistance)
{
- self.aistatus &= ~AI_STATUS_RUNNING;
+ this.aistatus &= ~AI_STATUS_RUNNING;
if(bunnyhopdistance > autocvar_bot_ai_bunnyhop_stopdistance)
- PHYS_INPUT_BUTTON_JUMP(self) = true;
+ PHYS_INPUT_BUTTON_JUMP(this) = true;
}
else
{
- self.aistatus |= AI_STATUS_RUNNING;
- PHYS_INPUT_BUTTON_JUMP(self) = true;
+ this.aistatus |= AI_STATUS_RUNNING;
+ PHYS_INPUT_BUTTON_JUMP(this) = true;
}
}
}
else
{
- self.bot_timelastseengoal = time;
+ this.bot_timelastseengoal = time;
}
}
else
{
- self.bot_timelastseengoal = 0;
+ this.bot_timelastseengoal = 0;
}
#if 0
// Release jump button
if(!cvar("sv_pogostick"))
- if((IS_ONGROUND(self)) == 0)
+ if((IS_ONGROUND(this)) == 0)
{
- if(self.velocity.z < 0 || vlen(self.velocity)<maxspeed)
- PHYS_INPUT_BUTTON_JUMP(self) = false;
+ if(this.velocity.z < 0 || vlen(this.velocity)<maxspeed)
+ PHYS_INPUT_BUTTON_JUMP(this) = false;
// Strafe
- if(self.aistatus & AI_STATUS_RUNNING)
- if(vlen(self.velocity)>maxspeed)
+ if(this.aistatus & AI_STATUS_RUNNING)
+ if(vlen(this.velocity)>maxspeed)
{
- deviation = vectoangles(dir) - vectoangles(self.velocity);
+ deviation = vectoangles(dir) - vectoangles(this.velocity);
while (deviation.y < -180) deviation.y = deviation.y + 360;
while (deviation.y > 180) deviation.y = deviation.y - 360;
if(fabs(deviation.y)>10)
- self.movement_x = 0;
+ this.movement_x = 0;
if(deviation.y>10)
- self.movement_y = maxspeed * -1;
+ this.movement_y = maxspeed * -1;
else if(deviation.y<10)
- self.movement_y = maxspeed;
+ this.movement_y = maxspeed;
}
}
#endif
}
-void havocbot_movetogoal()
-{SELFPARAM();
+void havocbot_movetogoal(entity this)
+{
vector destorg;
vector diff;
vector dir;
vector gco;
//float dist;
vector dodge;
- //if (self.goalentity)
- // te_lightning2(self, self.origin, (self.goalentity.absmin + self.goalentity.absmax) * 0.5);
- self.movement = '0 0 0';
+ //if (this.goalentity)
+ // te_lightning2(this, this.origin, (this.goalentity.absmin + this.goalentity.absmax) * 0.5);
+ this.movement = '0 0 0';
maxspeed = autocvar_sv_maxspeed;
// Jetpack navigation
- if(self.goalcurrent)
- if(self.navigation_jetpack_goal)
- if(self.goalcurrent==self.navigation_jetpack_goal)
- if(self.ammo_fuel)
+ if(this.goalcurrent)
+ if(this.navigation_jetpack_goal)
+ if(this.goalcurrent==this.navigation_jetpack_goal)
+ if(this.ammo_fuel)
{
if(autocvar_bot_debug_goalstack)
{
- debuggoalstack();
- te_wizspike(self.navigation_jetpack_point);
+ debuggoalstack(this);
+ te_wizspike(this.navigation_jetpack_point);
}
// Take off
- if (!(self.aistatus & AI_STATUS_JETPACK_FLYING))
+ if (!(this.aistatus & AI_STATUS_JETPACK_FLYING))
{
// Brake almost completely so it can get a good direction
- if(vlen(self.velocity)>10)
+ if(vdist(this.velocity, >, 10))
return;
- self.aistatus |= AI_STATUS_JETPACK_FLYING;
+ this.aistatus |= AI_STATUS_JETPACK_FLYING;
}
- makevectors(self.v_angle.y * '0 1 0');
- dir = normalize(self.navigation_jetpack_point - self.origin);
+ makevectors(this.v_angle.y * '0 1 0');
+ dir = normalize(this.navigation_jetpack_point - this.origin);
// Landing
- if(self.aistatus & AI_STATUS_JETPACK_LANDING)
+ if(this.aistatus & AI_STATUS_JETPACK_LANDING)
{
// Calculate brake distance in xy
float db, v, d;
vector dxy;
- dxy = self.origin - ( ( self.goalcurrent.absmin + self.goalcurrent.absmax ) * 0.5 ); dxy.z = 0;
+ dxy = this.origin - ( ( this.goalcurrent.absmin + this.goalcurrent.absmax ) * 0.5 ); dxy.z = 0;
d = vlen(dxy);
- v = vlen(self.velocity - self.velocity.z * '0 0 1');
+ v = vlen(this.velocity - this.velocity.z * '0 0 1');
db = (pow(v,2) / (autocvar_g_jetpack_acceleration_side * 2)) + 100;
// dprint("distance ", ftos(ceil(d)), " velocity ", ftos(ceil(v)), " brake at ", ftos(ceil(db)), "\n");
if(d < db || d < 500)
{
// Brake
- if(fabs(self.velocity.x)>maxspeed*0.3)
+ if(fabs(this.velocity.x)>maxspeed*0.3)
{
- self.movement_x = dir * v_forward * -maxspeed;
+ this.movement_x = dir * v_forward * -maxspeed;
return;
}
// Switch to normal mode
- self.navigation_jetpack_goal = world;
- self.aistatus &= ~AI_STATUS_JETPACK_LANDING;
- self.aistatus &= ~AI_STATUS_JETPACK_FLYING;
+ this.navigation_jetpack_goal = world;
+ this.aistatus &= ~AI_STATUS_JETPACK_LANDING;
+ this.aistatus &= ~AI_STATUS_JETPACK_FLYING;
return;
}
}
- else if(checkpvs(self.origin,self.goalcurrent))
+ else if(checkpvs(this.origin,this.goalcurrent))
{
// If I can see the goal switch to landing code
- self.aistatus &= ~AI_STATUS_JETPACK_FLYING;
- self.aistatus |= AI_STATUS_JETPACK_LANDING;
+ this.aistatus &= ~AI_STATUS_JETPACK_FLYING;
+ this.aistatus |= AI_STATUS_JETPACK_LANDING;
return;
}
// Flying
- PHYS_INPUT_BUTTON_HOOK(self) = true;
- if(self.navigation_jetpack_point.z - STAT(PL_MAX, NULL).z + STAT(PL_MIN, NULL).z < self.origin.z)
+ PHYS_INPUT_BUTTON_HOOK(this) = true;
+ if(this.navigation_jetpack_point.z - STAT(PL_MAX, NULL).z + STAT(PL_MIN, NULL).z < this.origin.z)
{
- self.movement_x = dir * v_forward * maxspeed;
- self.movement_y = dir * v_right * maxspeed;
+ this.movement_x = dir * v_forward * maxspeed;
+ this.movement_y = dir * v_right * maxspeed;
}
return;
}
// Handling of jump pads
- if(self.jumppadcount)
+ if(this.jumppadcount)
{
// If got stuck on the jump pad try to reach the farthest visible waypoint
- if(self.aistatus & AI_STATUS_OUT_JUMPPAD)
+ if(this.aistatus & AI_STATUS_OUT_JUMPPAD)
{
- if(fabs(self.velocity.z)<50)
+ if(fabs(this.velocity.z)<50)
{
entity head, newgoal = world;
float distance, bestdistance = 0;
for (head = findchain(classname, "waypoint"); head; head = head.chain)
{
- distance = vlen(head.origin - self.origin);
+ distance = vlen(head.origin - this.origin);
if(distance>1000)
continue;
- traceline(self.origin + self.view_ofs , ( ( head.absmin + head.absmax ) * 0.5 ), true, world);
+ traceline(this.origin + this.view_ofs , ( ( head.absmin + head.absmax ) * 0.5 ), true, world);
if(trace_fraction<1)
continue;
if(newgoal)
{
- self.ignoregoal = self.goalcurrent;
- self.ignoregoaltime = time + autocvar_bot_ai_ignoregoal_timeout;
- navigation_clearroute();
- navigation_routetogoal(newgoal, self.origin);
- self.aistatus &= ~AI_STATUS_OUT_JUMPPAD;
+ this.ignoregoal = this.goalcurrent;
+ this.ignoregoaltime = time + autocvar_bot_ai_ignoregoal_timeout;
+ navigation_clearroute(this);
+ navigation_routetogoal(this, newgoal, this.origin);
+ this.aistatus &= ~AI_STATUS_OUT_JUMPPAD;
}
}
else
}
else
{
- if(self.velocity.z>0)
+ if(this.velocity.z>0)
{
- float threshold, sxy;
- vector velxy = self.velocity; velxy_z = 0;
- sxy = vlen(velxy);
+ float threshold;
+ vector velxy = this.velocity; velxy_z = 0;
threshold = maxspeed * 0.2;
- if(sxy < threshold)
+ if(vdist(velxy, <, threshold))
{
- LOG_TRACE("Warning: ", self.netname, " got stuck on a jumppad (velocity in xy is ", ftos(sxy), "), trying to get out of it now\n");
- self.aistatus |= AI_STATUS_OUT_JUMPPAD;
+ LOG_TRACE("Warning: ", this.netname, " got stuck on a jumppad (velocity in xy is ", vtos(velxy), "), trying to get out of it now\n");
+ this.aistatus |= AI_STATUS_OUT_JUMPPAD;
}
return;
}
// Don't chase players while using a jump pad
- if(IS_PLAYER(self.goalcurrent) || IS_PLAYER(self.goalstack01))
+ if(IS_PLAYER(this.goalcurrent) || IS_PLAYER(this.goalstack01))
return;
}
}
- else if(self.aistatus & AI_STATUS_OUT_JUMPPAD)
- self.aistatus &= ~AI_STATUS_OUT_JUMPPAD;
+ else if(this.aistatus & AI_STATUS_OUT_JUMPPAD)
+ this.aistatus &= ~AI_STATUS_OUT_JUMPPAD;
// If there is a trigger_hurt right below try to use the jetpack or make a rocketjump
if(skill>6)
- if (!(IS_ONGROUND(self)))
+ if (!(IS_ONGROUND(this)))
{
- tracebox(self.origin, self.mins, self.maxs, self.origin + '0 0 -65536', MOVE_NOMONSTERS, self);
- if(tracebox_hits_trigger_hurt(self.origin, self.mins, self.maxs, trace_endpos ))
- if(self.items & IT_JETPACK)
+ tracebox(this.origin, this.mins, this.maxs, this.origin + '0 0 -65536', MOVE_NOMONSTERS, this);
+ if(tracebox_hits_trigger_hurt(this.origin, this.mins, this.maxs, trace_endpos ))
+ if(this.items & IT_JETPACK)
{
- tracebox(self.origin, self.mins, self.maxs, self.origin + '0 0 65536', MOVE_NOMONSTERS, self);
- if(tracebox_hits_trigger_hurt(self.origin, self.mins, self.maxs, trace_endpos + '0 0 1' ))
+ tracebox(this.origin, this.mins, this.maxs, this.origin + '0 0 65536', MOVE_NOMONSTERS, this);
+ if(tracebox_hits_trigger_hurt(this.origin, this.mins, this.maxs, trace_endpos + '0 0 1' ))
{
- if(self.velocity.z<0)
+ if(this.velocity.z<0)
{
- PHYS_INPUT_BUTTON_HOOK(self) = true;
+ PHYS_INPUT_BUTTON_HOOK(this) = true;
}
}
else
- PHYS_INPUT_BUTTON_HOOK(self) = true;
+ PHYS_INPUT_BUTTON_HOOK(this) = true;
// If there is no goal try to move forward
- if(self.goalcurrent==world)
+ if(this.goalcurrent==world)
dir = v_forward;
else
- dir = normalize(( ( self.goalcurrent.absmin + self.goalcurrent.absmax ) * 0.5 ) - self.origin);
+ dir = normalize(( ( this.goalcurrent.absmin + this.goalcurrent.absmax ) * 0.5 ) - this.origin);
- vector xyvelocity = self.velocity; xyvelocity_z = 0;
+ vector xyvelocity = this.velocity; xyvelocity_z = 0;
float xyspeed = xyvelocity * dir;
if(xyspeed < (maxspeed / 2))
{
- makevectors(self.v_angle.y * '0 1 0');
- tracebox(self.origin, self.mins, self.maxs, self.origin + (dir * maxspeed * 3), MOVE_NOMONSTERS, self);
+ makevectors(this.v_angle.y * '0 1 0');
+ tracebox(this.origin, this.mins, this.maxs, this.origin + (dir * maxspeed * 3), MOVE_NOMONSTERS, this);
if(trace_fraction==1)
{
- self.movement_x = dir * v_forward * maxspeed;
- self.movement_y = dir * v_right * maxspeed;
+ this.movement_x = dir * v_forward * maxspeed;
+ this.movement_y = dir * v_right * maxspeed;
if (skill < 10)
- havocbot_keyboard_movement(self.origin + dir * 100);
+ havocbot_keyboard_movement(this, this.origin + dir * 100);
}
}
- self.havocbot_blockhead = true;
+ this.havocbot_blockhead = true;
return;
}
- else if(self.health>WEP_CVAR(devastator, damage)*0.5)
+ else if(this.health>WEP_CVAR(devastator, damage)*0.5)
{
- if(self.velocity.z < 0)
- if(client_hasweapon(self, WEP_DEVASTATOR, true, false))
+ if(this.velocity.z < 0)
+ if(client_hasweapon(this, WEP_DEVASTATOR, true, false))
{
- self.movement_x = maxspeed;
+ this.movement_x = maxspeed;
- if(self.rocketjumptime)
+ if(this.rocketjumptime)
{
- if(time > self.rocketjumptime)
+ if(time > this.rocketjumptime)
{
- PHYS_INPUT_BUTTON_ATCK2(self) = true;
- self.rocketjumptime = 0;
+ PHYS_INPUT_BUTTON_ATCK2(this) = true;
+ this.rocketjumptime = 0;
}
return;
}
- PS(self).m_switchweapon = WEP_DEVASTATOR;
- self.v_angle_x = 90;
- PHYS_INPUT_BUTTON_ATCK(self) = true;
- self.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
+ PS(this).m_switchweapon = WEP_DEVASTATOR;
+ this.v_angle_x = 90;
+ PHYS_INPUT_BUTTON_ATCK(this) = true;
+ this.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
return;
}
}
else
{
// If there is no goal try to move forward
- if(self.goalcurrent==world)
- self.movement_x = maxspeed;
+ if(this.goalcurrent==world)
+ this.movement_x = maxspeed;
}
}
// If we are under water with no goals, swim up
- if(self.waterlevel)
- if(self.goalcurrent==world)
+ if(this.waterlevel)
+ if(this.goalcurrent==world)
{
dir = '0 0 0';
- if(self.waterlevel>WATERLEVEL_SWIMMING)
+ if(this.waterlevel>WATERLEVEL_SWIMMING)
dir.z = 1;
- else if(self.velocity.z >= 0 && !(self.waterlevel == WATERLEVEL_WETFEET && self.watertype == CONTENT_WATER))
- PHYS_INPUT_BUTTON_JUMP(self) = true;
+ else if(this.velocity.z >= 0 && !(this.waterlevel == WATERLEVEL_WETFEET && this.watertype == CONTENT_WATER))
+ PHYS_INPUT_BUTTON_JUMP(this) = true;
else
- PHYS_INPUT_BUTTON_JUMP(self) = false;
- makevectors(self.v_angle.y * '0 1 0');
- self.movement_x = dir * v_forward * maxspeed;
- self.movement_y = dir * v_right * maxspeed;
- self.movement_z = dir * v_up * maxspeed;
+ PHYS_INPUT_BUTTON_JUMP(this) = false;
+ makevectors(this.v_angle.y * '0 1 0');
+ this.movement_x = dir * v_forward * maxspeed;
+ this.movement_y = dir * v_right * maxspeed;
+ this.movement_z = dir * v_up * maxspeed;
}
// if there is nowhere to go, exit
- if (self.goalcurrent == world)
+ if (this.goalcurrent == world)
return;
- if (self.goalcurrent)
- navigation_poptouchedgoals();
+ if (this.goalcurrent)
+ navigation_poptouchedgoals(this);
// if ran out of goals try to use an alternative goal or get a new strategy asap
- if(self.goalcurrent == world)
+ if(this.goalcurrent == world)
{
- self.bot_strategytime = 0;
+ this.bot_strategytime = 0;
return;
}
if(autocvar_bot_debug_goalstack)
- debuggoalstack();
+ debuggoalstack(this);
- m1 = self.goalcurrent.origin + self.goalcurrent.mins;
- m2 = self.goalcurrent.origin + self.goalcurrent.maxs;
- destorg = self.origin;
+ m1 = this.goalcurrent.origin + this.goalcurrent.mins;
+ m2 = this.goalcurrent.origin + this.goalcurrent.maxs;
+ destorg = this.origin;
destorg.x = bound(m1_x, destorg.x, m2_x);
destorg.y = bound(m1_y, destorg.y, m2_y);
destorg.z = bound(m1_z, destorg.z, m2_z);
- diff = destorg - self.origin;
+ diff = destorg - this.origin;
//dist = vlen(diff);
dir = normalize(diff);
flatdir = diff;flatdir.z = 0;
flatdir = normalize(flatdir);
- gco = (self.goalcurrent.absmin + self.goalcurrent.absmax) * 0.5;
+ gco = (this.goalcurrent.absmin + this.goalcurrent.absmax) * 0.5;
- //if (self.bot_dodgevector_time < time)
+ //if (this.bot_dodgevector_time < time)
{
- // self.bot_dodgevector_time = time + cvar("bot_ai_dodgeupdateinterval");
- // self.bot_dodgevector_jumpbutton = 1;
+ // this.bot_dodgevector_time = time + cvar("bot_ai_dodgeupdateinterval");
+ // this.bot_dodgevector_jumpbutton = 1;
evadeobstacle = '0 0 0';
evadelava = '0 0 0';
- if (self.waterlevel)
+ if (this.waterlevel)
{
- if(self.waterlevel>WATERLEVEL_SWIMMING)
+ if(this.waterlevel>WATERLEVEL_SWIMMING)
{
// flatdir_z = 1;
- self.aistatus |= AI_STATUS_OUT_WATER;
+ this.aistatus |= AI_STATUS_OUT_WATER;
}
else
{
- if(self.velocity.z >= 0 && !(self.watertype == CONTENT_WATER && gco.z < self.origin.z) &&
- ( !(self.waterlevel == WATERLEVEL_WETFEET && self.watertype == CONTENT_WATER) || self.aistatus & AI_STATUS_OUT_WATER))
- PHYS_INPUT_BUTTON_JUMP(self) = true;
+ if(this.velocity.z >= 0 && !(this.watertype == CONTENT_WATER && gco.z < this.origin.z) &&
+ ( !(this.waterlevel == WATERLEVEL_WETFEET && this.watertype == CONTENT_WATER) || this.aistatus & AI_STATUS_OUT_WATER))
+ PHYS_INPUT_BUTTON_JUMP(this) = true;
else
- PHYS_INPUT_BUTTON_JUMP(self) = false;
+ PHYS_INPUT_BUTTON_JUMP(this) = false;
}
dir = normalize(flatdir);
- makevectors(self.v_angle.y * '0 1 0');
+ makevectors(this.v_angle.y * '0 1 0');
}
else
{
- if(self.aistatus & AI_STATUS_OUT_WATER)
- self.aistatus &= ~AI_STATUS_OUT_WATER;
+ if(this.aistatus & AI_STATUS_OUT_WATER)
+ this.aistatus &= ~AI_STATUS_OUT_WATER;
// jump if going toward an obstacle that doesn't look like stairs we
// can walk up directly
- tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 0.2, false, self);
+ tracebox(this.origin, this.mins, this.maxs, this.origin + this.velocity * 0.2, false, this);
if (trace_fraction < 1)
if (trace_plane_normal.z < 0.7)
{
s = trace_fraction;
- tracebox(self.origin + stepheightvec, self.mins, self.maxs, self.origin + self.velocity * 0.2 + stepheightvec, false, self);
+ tracebox(this.origin + stepheightvec, this.mins, this.maxs, this.origin + this.velocity * 0.2 + stepheightvec, false, this);
if (trace_fraction < s + 0.01)
if (trace_plane_normal.z < 0.7)
{
s = trace_fraction;
- tracebox(self.origin + jumpstepheightvec, self.mins, self.maxs, self.origin + self.velocity * 0.2 + jumpstepheightvec, false, self);
+ tracebox(this.origin + jumpstepheightvec, this.mins, this.maxs, this.origin + this.velocity * 0.2 + jumpstepheightvec, false, this);
if (trace_fraction > s)
- PHYS_INPUT_BUTTON_JUMP(self) = true;
+ PHYS_INPUT_BUTTON_JUMP(this) = true;
}
}
// avoiding dangers and obstacles
vector dst_ahead, dst_down;
- makevectors(self.v_angle.y * '0 1 0');
- dst_ahead = self.origin + self.view_ofs + (self.velocity * 0.4) + (v_forward * 32 * 3);
+ makevectors(this.v_angle.y * '0 1 0');
+ dst_ahead = this.origin + this.view_ofs + (this.velocity * 0.4) + (v_forward * 32 * 3);
dst_down = dst_ahead - '0 0 1500';
// Look ahead
- traceline(self.origin + self.view_ofs, dst_ahead, true, world);
+ traceline(this.origin + this.view_ofs, dst_ahead, true, world);
// Check head-banging against walls
- if(vlen(self.origin + self.view_ofs - trace_endpos) < 25 && !(self.aistatus & AI_STATUS_OUT_WATER))
+ if(vlen(this.origin + this.view_ofs - trace_endpos) < 25 && !(this.aistatus & AI_STATUS_OUT_WATER))
{
- PHYS_INPUT_BUTTON_JUMP(self) = true;
- if(self.facingwalltime && time > self.facingwalltime)
+ PHYS_INPUT_BUTTON_JUMP(this) = true;
+ if(this.facingwalltime && time > this.facingwalltime)
{
- self.ignoregoal = self.goalcurrent;
- self.ignoregoaltime = time + autocvar_bot_ai_ignoregoal_timeout;
- self.bot_strategytime = 0;
+ this.ignoregoal = this.goalcurrent;
+ this.ignoregoaltime = time + autocvar_bot_ai_ignoregoal_timeout;
+ this.bot_strategytime = 0;
return;
}
else
{
- self.facingwalltime = time + 0.05;
+ this.facingwalltime = time + 0.05;
}
}
else
{
- self.facingwalltime = 0;
+ this.facingwalltime = 0;
- if(self.ignoregoal != world && time > self.ignoregoaltime)
+ if(this.ignoregoal != world && time > this.ignoregoaltime)
{
- self.ignoregoal = world;
- self.ignoregoaltime = 0;
+ this.ignoregoal = world;
+ this.ignoregoaltime = 0;
}
}
// Check for water/slime/lava and dangerous edges
// (only when the bot is on the ground or jumping intentionally)
- self.aistatus &= ~AI_STATUS_DANGER_AHEAD;
+ this.aistatus &= ~AI_STATUS_DANGER_AHEAD;
- if(trace_fraction == 1 && self.jumppadcount == 0 && !self.goalcurrent.wphardwired )
- if((IS_ONGROUND(self)) || (self.aistatus & AI_STATUS_RUNNING) || PHYS_INPUT_BUTTON_JUMP(self))
+ if(trace_fraction == 1 && this.jumppadcount == 0 && !this.goalcurrent.wphardwired )
+ if((IS_ONGROUND(this)) || (this.aistatus & AI_STATUS_RUNNING) || PHYS_INPUT_BUTTON_JUMP(this))
{
// Look downwards
traceline(dst_ahead , dst_down, true, world);
- // te_lightning2(world, self.origin, dst_ahead); // Draw "ahead" look
+ // te_lightning2(world, this.origin, dst_ahead); // Draw "ahead" look
// te_lightning2(world, dst_ahead, dst_down); // Draw "downwards" look
- if(trace_endpos.z < self.origin.z + self.mins.z)
+ if(trace_endpos.z < this.origin.z + this.mins.z)
{
s = pointcontents(trace_endpos + '0 0 1');
if (s != CONTENT_SOLID)
if (s == CONTENT_LAVA || s == CONTENT_SLIME)
- evadelava = normalize(self.velocity) * -1;
+ evadelava = normalize(this.velocity) * -1;
else if (s == CONTENT_SKY)
- evadeobstacle = normalize(self.velocity) * -1;
- else if (!boxesoverlap(dst_ahead - self.view_ofs + self.mins, dst_ahead - self.view_ofs + self.maxs,
- self.goalcurrent.absmin, self.goalcurrent.absmax))
+ evadeobstacle = normalize(this.velocity) * -1;
+ else if (!boxesoverlap(dst_ahead - this.view_ofs + this.mins, dst_ahead - this.view_ofs + this.maxs,
+ this.goalcurrent.absmin, this.goalcurrent.absmax))
{
// if ain't a safe goal with "holes" (like the jumpad on soylent)
// and there is a trigger_hurt below
- if(tracebox_hits_trigger_hurt(dst_ahead, self.mins, self.maxs, trace_endpos))
+ if(tracebox_hits_trigger_hurt(dst_ahead, this.mins, this.maxs, trace_endpos))
{
// Remove dangerous dynamic goals from stack
- LOG_TRACE("bot ", self.netname, " avoided the goal ", self.goalcurrent.classname, " ", etos(self.goalcurrent), " because it led to a dangerous path; goal stack cleared\n");
- navigation_clearroute();
+ LOG_TRACE("bot ", this.netname, " avoided the goal ", this.goalcurrent.classname, " ", etos(this.goalcurrent), " because it led to a dangerous path; goal stack cleared\n");
+ navigation_clearroute(this);
return;
}
}
dir = flatdir;
evadeobstacle.z = 0;
evadelava.z = 0;
- makevectors(self.v_angle.y * '0 1 0');
+ makevectors(this.v_angle.y * '0 1 0');
if(evadeobstacle!='0 0 0'||evadelava!='0 0 0')
- self.aistatus |= AI_STATUS_DANGER_AHEAD;
+ this.aistatus |= AI_STATUS_DANGER_AHEAD;
}
dodge = havocbot_dodge();
- dodge = dodge * bound(0,0.5+(skill+self.bot_dodgeskill)*0.1,1);
- evadelava = evadelava * bound(1,3-(skill+self.bot_dodgeskill),3); //Noobs fear lava a lot and take more distance from it
- traceline(self.origin, ( ( self.enemy.absmin + self.enemy.absmax ) * 0.5 ), true, world);
+ dodge = dodge * bound(0,0.5+(skill+this.bot_dodgeskill)*0.1,1);
+ evadelava = evadelava * bound(1,3-(skill+this.bot_dodgeskill),3); //Noobs fear lava a lot and take more distance from it
+ traceline(this.origin, ( ( this.enemy.absmin + this.enemy.absmax ) * 0.5 ), true, world);
if(IS_PLAYER(trace_ent))
- dir = dir * bound(0,(skill+self.bot_dodgeskill)/7,1);
+ dir = dir * bound(0,(skill+this.bot_dodgeskill)/7,1);
dir = normalize(dir + dodge + evadeobstacle + evadelava);
- // self.bot_dodgevector = dir;
- // self.bot_dodgevector_jumpbutton = PHYS_INPUT_BUTTON_JUMP(self);
+ // this.bot_dodgevector = dir;
+ // this.bot_dodgevector_jumpbutton = PHYS_INPUT_BUTTON_JUMP(this);
}
- if(time < self.ladder_time)
+ if(time < this.ladder_time)
{
- if(self.goalcurrent.origin.z + self.goalcurrent.mins.z > self.origin.z + self.mins.z)
+ if(this.goalcurrent.origin.z + this.goalcurrent.mins.z > this.origin.z + this.mins.z)
{
- if(self.origin.z + self.mins.z < self.ladder_entity.origin.z + self.ladder_entity.maxs.z)
+ if(this.origin.z + this.mins.z < this.ladder_entity.origin.z + this.ladder_entity.maxs.z)
dir.z = 1;
}
else
{
- if(self.origin.z + self.mins.z > self.ladder_entity.origin.z + self.ladder_entity.mins.z)
+ if(this.origin.z + this.mins.z > this.ladder_entity.origin.z + this.ladder_entity.mins.z)
dir.z = -1;
}
}
- //dir = self.bot_dodgevector;
- //if (self.bot_dodgevector_jumpbutton)
- // PHYS_INPUT_BUTTON_JUMP(self) = true;
- self.movement_x = dir * v_forward * maxspeed;
- self.movement_y = dir * v_right * maxspeed;
- self.movement_z = dir * v_up * maxspeed;
+ //dir = this.bot_dodgevector;
+ //if (this.bot_dodgevector_jumpbutton)
+ // PHYS_INPUT_BUTTON_JUMP(this) = true;
+ this.movement_x = dir * v_forward * maxspeed;
+ this.movement_y = dir * v_right * maxspeed;
+ this.movement_z = dir * v_up * maxspeed;
// Emulate keyboard interface
if (skill < 10)
- havocbot_keyboard_movement(destorg);
+ havocbot_keyboard_movement(this, destorg);
// Bunnyhop!
-// if(self.aistatus & AI_STATUS_ROAMING)
- if(self.goalcurrent)
- if(skill+self.bot_moveskill >= autocvar_bot_ai_bunnyhop_skilloffset)
- havocbot_bunnyhop(dir);
-
- if ((dir * v_up) >= autocvar_sv_jumpvelocity*0.5 && (IS_ONGROUND(self))) PHYS_INPUT_BUTTON_JUMP(self) = true;
- if (((dodge * v_up) > 0) && random()*frametime >= 0.2*bound(0,(10-skill-self.bot_dodgeskill)*0.1,1)) PHYS_INPUT_BUTTON_JUMP(self) = true;
- if (((dodge * v_up) < 0) && random()*frametime >= 0.5*bound(0,(10-skill-self.bot_dodgeskill)*0.1,1)) self.havocbot_ducktime=time+0.3/bound(0.1,skill+self.bot_dodgeskill,10);
+// if(this.aistatus & AI_STATUS_ROAMING)
+ if(this.goalcurrent)
+ if(skill+this.bot_moveskill >= autocvar_bot_ai_bunnyhop_skilloffset)
+ havocbot_bunnyhop(this, dir);
+
+ if ((dir * v_up) >= autocvar_sv_jumpvelocity*0.5 && (IS_ONGROUND(this))) PHYS_INPUT_BUTTON_JUMP(this) = true;
+ if (((dodge * v_up) > 0) && random()*frametime >= 0.2*bound(0,(10-skill-this.bot_dodgeskill)*0.1,1)) PHYS_INPUT_BUTTON_JUMP(this) = true;
+ 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);
}
-void havocbot_chooseenemy()
-{SELFPARAM();
+void havocbot_chooseenemy(entity this)
+{
entity head, best, head2;
float rating, bestrating, hf;
vector eye, v;
- if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
+ if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(this))
{
- self.enemy = world;
+ this.enemy = world;
return;
}
- if (self.enemy)
+ if (this.enemy)
{
- if (!bot_shouldattack(self.enemy))
+ if (!bot_shouldattack(this, this.enemy))
{
// enemy died or something, find a new target
- self.enemy = world;
- self.havocbot_chooseenemy_finished = time;
+ this.enemy = world;
+ this.havocbot_chooseenemy_finished = time;
}
- else if (self.havocbot_stickenemy)
+ else if (this.havocbot_stickenemy)
{
// tracking last chosen enemy
// if enemy is visible
// and not really really far away
// and we're not severely injured
// then keep tracking for a half second into the future
- traceline(self.origin+self.view_ofs, ( self.enemy.absmin + self.enemy.absmax ) * 0.5,false,world);
- if (trace_ent == self.enemy || trace_fraction == 1)
- if (vlen((( self.enemy.absmin + self.enemy.absmax ) * 0.5) - self.origin) < 1000)
- if (self.health > 30)
+ traceline(this.origin+this.view_ofs, ( this.enemy.absmin + this.enemy.absmax ) * 0.5,false,world);
+ if (trace_ent == this.enemy || trace_fraction == 1)
+ if (vdist(((this.enemy.absmin + this.enemy.absmax) * 0.5) - this.origin, <, 1000))
+ if (this.health > 30)
{
// remain tracking him for a shot while (case he went after a small corner or pilar
- self.havocbot_chooseenemy_finished = time + 0.5;
+ this.havocbot_chooseenemy_finished = time + 0.5;
return;
}
// enemy isn't visible, or is far away, or we're injured severely
// so stop preferring this enemy
// (it will still take a half second until a new one is chosen)
- self.havocbot_stickenemy = 0;
+ this.havocbot_stickenemy = 0;
}
}
- if (time < self.havocbot_chooseenemy_finished)
+ if (time < this.havocbot_chooseenemy_finished)
return;
- self.havocbot_chooseenemy_finished = time + autocvar_bot_ai_enemydetectioninterval;
- eye = self.origin + self.view_ofs;
+ this.havocbot_chooseenemy_finished = time + autocvar_bot_ai_enemydetectioninterval;
+ eye = this.origin + this.view_ofs;
best = world;
bestrating = 100000000;
head = head2 = findchainfloat(bot_attack, true);
// Backup hit flags
- hf = self.dphitcontentsmask;
+ hf = this.dphitcontentsmask;
// Search for enemies, if no enemy can be seen directly try to look through transparent objects
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
+ this.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
bool scan_transparent = false;
bool scan_secondary_targets = false;
while(true)
{
scan_secondary_targets = false;
- :scan_targets
+LABEL(scan_targets)
for( ; head; head = head.chain)
{
if(!scan_secondary_targets)
rating = vlen(v - eye);
if (rating<autocvar_bot_ai_enemydetectionradius)
if (bestrating > rating)
- if (bot_shouldattack(head))
+ if (bot_shouldattack(this, head))
{
- traceline(eye, v, true, self);
+ traceline(eye, v, true, this);
if (trace_ent == head || trace_fraction >= 1)
{
best = head;
// I want to do a second scan if no enemy was found or I don't have weapons
// TODO: Perform the scan when using the rifle (requires changes on the rifle code)
- if(best || self.weapons) // || self.weapon == WEP_RIFLE.m_id
+ if(best || this.weapons) // || this.weapon == WEP_RIFLE.m_id
break;
if(scan_transparent)
break;
// Set flags to see through transparent objects
- self.dphitcontentsmask |= DPCONTENTS_OPAQUE;
+ this.dphitcontentsmask |= DPCONTENTS_OPAQUE;
head = head2;
scan_transparent = true;
}
// Restore hit flags
- self.dphitcontentsmask = hf;
+ this.dphitcontentsmask = hf;
- self.enemy = best;
- self.havocbot_stickenemy = true;
+ this.enemy = best;
+ this.havocbot_stickenemy = true;
if(best && best.classname == "misc_breakablemodel")
- self.havocbot_stickenemy = false;
+ this.havocbot_stickenemy = false;
}
-float havocbot_chooseweapon_checkreload(int new_weapon)
-{SELFPARAM();
+float havocbot_chooseweapon_checkreload(entity this, int new_weapon)
+{
// bots under this skill cannot find unloaded weapons to reload idly when not in combat,
// so skip this for them, or they'll never get to reload their weapons at all.
// this also allows bots under this skill to be more stupid, and reload more often during combat :)
return false;
// if this weapon is scheduled for reloading, don't switch to it during combat
- if (self.weapon_load[new_weapon] < 0)
+ if (this.weapon_load[new_weapon] < 0)
{
bool other_weapon_available = false;
FOREACH(Weapons, it != WEP_Null, LAMBDA(
return false;
}
-void havocbot_chooseweapon()
-{SELFPARAM();
+void havocbot_chooseweapon(entity this)
+{
int i;
// ;)
if(g_weaponarena_weapons == WEPSET(TUBA))
{
- PS(self).m_switchweapon = WEP_TUBA;
+ PS(this).m_switchweapon = WEP_TUBA;
return;
}
// TODO: clean this up by moving it to weapon code
- if(self.enemy==world)
+ if(this.enemy==world)
{
// If no weapon was chosen get the first available weapon
- if(PS(self).m_weapon==WEP_Null)
+ if(PS(this).m_weapon==WEP_Null)
FOREACH(Weapons, it != WEP_Null, LAMBDA(
- if(client_hasweapon(self, it, true, false))
+ if(client_hasweapon(this, it, true, false))
{
- PS(self).m_switchweapon = it;
+ PS(this).m_switchweapon = it;
return;
}
));
}
// Do not change weapon during the next second after a combo
- float f = time - self.lastcombotime;
+ float f = time - this.lastcombotime;
if(f < 1)
return;
float w;
- float distance; distance=bound(10,vlen(self.origin-self.enemy.origin)-200,10000);
+ float distance; distance=bound(10,vlen(this.origin-this.enemy.origin)-200,10000);
// Should it do a weapon combo?
float af, ct, combo_time, combo;
- af = ATTACK_FINISHED(self, 0);
+ af = ATTACK_FINISHED(this, 0);
ct = autocvar_bot_ai_weapon_combo_threshold;
// Bots with no skill will be 4 times more slower than "godlike" bots when doing weapon combos
// Ideally this 4 should be calculated as longest_weapon_refire / bot_ai_weapon_combo_threshold
- combo_time = time + ct + (ct * ((-0.3*(skill+self.bot_weaponskill))+3));
+ combo_time = time + ct + (ct * ((-0.3*(skill+this.bot_weaponskill))+3));
combo = false;
if(autocvar_bot_ai_weapon_combo)
- if(PS(self).m_weapon.m_id == self.lastfiredweapon)
+ if(PS(this).m_weapon.m_id == this.lastfiredweapon)
if(af > combo_time)
{
combo = true;
- self.lastcombotime = time;
+ this.lastcombotime = time;
}
- distance *= pow(2, self.bot_rangepreference);
+ distance *= pow(2, this.bot_rangepreference);
// Custom weapon list based on distance to the enemy
if(bot_custom_weapon){
if ( distance > bot_distance_far ) {
for(i=0; i < Weapons_COUNT && bot_weapons_far[i] != -1 ; ++i){
w = bot_weapons_far[i];
- if ( client_hasweapon(self, Weapons_from(w), true, false) )
+ if ( client_hasweapon(this, Weapons_from(w), true, false) )
{
- if ((PS(self).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(w))
+ if ((PS(this).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w))
continue;
- PS(self).m_switchweapon = Weapons_from(w);
+ PS(this).m_switchweapon = Weapons_from(w);
return;
}
}
if ( distance > bot_distance_close) {
for(i=0; i < Weapons_COUNT && bot_weapons_mid[i] != -1 ; ++i){
w = bot_weapons_mid[i];
- if ( client_hasweapon(self, Weapons_from(w), true, false) )
+ if ( client_hasweapon(this, Weapons_from(w), true, false) )
{
- if ((PS(self).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(w))
+ if ((PS(this).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w))
continue;
- PS(self).m_switchweapon = Weapons_from(w);
+ PS(this).m_switchweapon = Weapons_from(w);
return;
}
}
// Choose weapons for close distance
for(i=0; i < Weapons_COUNT && bot_weapons_close[i] != -1 ; ++i){
w = bot_weapons_close[i];
- if ( client_hasweapon(self, Weapons_from(w), true, false) )
+ if ( client_hasweapon(this, Weapons_from(w), true, false) )
{
- if ((PS(self).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(w))
+ if ((PS(this).m_weapon.m_id == w && combo) || havocbot_chooseweapon_checkreload(this, w))
continue;
- PS(self).m_switchweapon = Weapons_from(w);
+ PS(this).m_switchweapon = Weapons_from(w);
return;
}
}
}
}
-void havocbot_aim()
-{SELFPARAM();
+void havocbot_aim(entity this)
+{
vector selfvel, enemyvel;
-// if(self.flags & FL_INWATER)
+// if(this.flags & FL_INWATER)
// return;
- if (time < self.nextaim)
+ if (time < this.nextaim)
return;
- self.nextaim = time + 0.1;
- selfvel = self.velocity;
- if (!self.waterlevel)
+ this.nextaim = time + 0.1;
+ selfvel = this.velocity;
+ if (!this.waterlevel)
selfvel.z = 0;
- if (self.enemy)
+ if (this.enemy)
{
- enemyvel = self.enemy.velocity;
- if (!self.enemy.waterlevel)
+ enemyvel = this.enemy.velocity;
+ if (!this.enemy.waterlevel)
enemyvel.z = 0;
- lag_additem(time + self.ping, 0, 0, self.enemy, self.origin, selfvel, (self.enemy.absmin + self.enemy.absmax) * 0.5, enemyvel);
+ lag_additem(this, time + this.ping, 0, 0, this.enemy, this.origin, selfvel, (this.enemy.absmin + this.enemy.absmax) * 0.5, enemyvel);
}
else
- lag_additem(time + self.ping, 0, 0, world, self.origin, selfvel, ( self.goalcurrent.absmin + self.goalcurrent.absmax ) * 0.5, '0 0 0');
+ lag_additem(this, time + this.ping, 0, 0, world, this.origin, selfvel, ( this.goalcurrent.absmin + this.goalcurrent.absmax ) * 0.5, '0 0 0');
}
-float havocbot_moveto_refresh_route()
-{SELFPARAM();
+bool havocbot_moveto_refresh_route(entity this)
+{
// Refresh path to goal if necessary
entity wp;
- wp = self.havocbot_personal_waypoint;
- navigation_goalrating_start();
- navigation_routerating(wp, 10000, 10000);
- navigation_goalrating_end();
- return self.navigation_hasgoals;
+ wp = this.havocbot_personal_waypoint;
+ navigation_goalrating_start(this);
+ navigation_routerating(this, wp, 10000, 10000);
+ navigation_goalrating_end(this);
+ return this.navigation_hasgoals;
}
-float havocbot_moveto(vector pos)
-{SELFPARAM();
+float havocbot_moveto(entity this, vector pos)
+{
entity wp;
- if(self.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
+ if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
{
// Step 4: Move to waypoint
- if(self.havocbot_personal_waypoint==world)
+ if(this.havocbot_personal_waypoint==world)
{
- LOG_TRACE("Error: ", self.netname, " trying to walk to a non existent personal waypoint\n");
- self.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
+ LOG_TRACE("Error: ", this.netname, " trying to walk to a non existent personal waypoint\n");
+ this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
return CMD_STATUS_ERROR;
}
if (!bot_strategytoken_taken)
- if(self.havocbot_personal_waypoint_searchtime<time)
+ if(this.havocbot_personal_waypoint_searchtime<time)
{
bot_strategytoken_taken = true;
- if(havocbot_moveto_refresh_route())
+ if(havocbot_moveto_refresh_route(this))
{
- LOG_TRACE(self.netname, " walking to its personal waypoint (after ", ftos(self.havocbot_personal_waypoint_failcounter), " failed attempts)\n");
- self.havocbot_personal_waypoint_searchtime = time + 10;
- self.havocbot_personal_waypoint_failcounter = 0;
+ LOG_TRACE(this.netname, " walking to its personal waypoint (after ", ftos(this.havocbot_personal_waypoint_failcounter), " failed attempts)\n");
+ this.havocbot_personal_waypoint_searchtime = time + 10;
+ this.havocbot_personal_waypoint_failcounter = 0;
}
else
{
- self.havocbot_personal_waypoint_failcounter += 1;
- self.havocbot_personal_waypoint_searchtime = time + 2;
- if(self.havocbot_personal_waypoint_failcounter >= 30)
+ this.havocbot_personal_waypoint_failcounter += 1;
+ this.havocbot_personal_waypoint_searchtime = time + 2;
+ if(this.havocbot_personal_waypoint_failcounter >= 30)
{
- LOG_TRACE("Warning: can't walk to the personal waypoint located at ", vtos(self.havocbot_personal_waypoint.origin),"\n");
- self.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_LINKING;
- remove(self.havocbot_personal_waypoint);
+ LOG_TRACE("Warning: can't walk to the personal waypoint located at ", vtos(this.havocbot_personal_waypoint.origin),"\n");
+ this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_LINKING;
+ remove(this.havocbot_personal_waypoint);
return CMD_STATUS_ERROR;
}
else
- LOG_TRACE(self.netname, " can't walk to its personal waypoint (after ", ftos(self.havocbot_personal_waypoint_failcounter), " failed attempts), trying later\n");
+ LOG_TRACE(this.netname, " can't walk to its personal waypoint (after ", ftos(this.havocbot_personal_waypoint_failcounter), " failed attempts), trying later\n");
}
}
if(autocvar_bot_debug_goalstack)
- debuggoalstack();
+ debuggoalstack(this);
// Heading
- vector dir = ( ( self.goalcurrent.absmin + self.goalcurrent.absmax ) * 0.5 ) - (self.origin + self.view_ofs);
+ vector dir = ( ( this.goalcurrent.absmin + this.goalcurrent.absmax ) * 0.5 ) - (this.origin + this.view_ofs);
dir.z = 0;
- bot_aimdir(dir, -1);
+ bot_aimdir(this, dir, -1);
// Go!
- havocbot_movetogoal();
+ havocbot_movetogoal(this);
- if(self.aistatus & AI_STATUS_WAYPOINT_PERSONAL_REACHED)
+ if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_REACHED)
{
// Step 5: Waypoint reached
- LOG_TRACE(self.netname, "'s personal waypoint reached\n");
- remove(self.havocbot_personal_waypoint);
- self.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_REACHED;
+ LOG_TRACE(this.netname, "'s personal waypoint reached\n");
+ remove(this.havocbot_personal_waypoint);
+ this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_REACHED;
return CMD_STATUS_FINISHED;
}
}
// Step 2: Linking waypoint
- if(self.aistatus & AI_STATUS_WAYPOINT_PERSONAL_LINKING)
+ if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_LINKING)
{
// Wait until it is linked
- if(!self.havocbot_personal_waypoint.wplinked)
+ if(!this.havocbot_personal_waypoint.wplinked)
{
- LOG_TRACE(self.netname, " waiting for personal waypoint to be linked\n");
+ LOG_TRACE(this.netname, " waiting for personal waypoint to be linked\n");
return CMD_STATUS_EXECUTING;
}
- self.havocbot_personal_waypoint_searchtime = time; // so we set the route next frame
- self.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_LINKING;
- self.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_GOING;
+ this.havocbot_personal_waypoint_searchtime = time; // so we set the route next frame
+ this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_LINKING;
+ this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_GOING;
// Step 3: Route to waypoint
- LOG_TRACE(self.netname, " walking to its personal waypoint\n");
+ LOG_TRACE(this.netname, " walking to its personal waypoint\n");
return CMD_STATUS_EXECUTING;
}
// Step 1: Spawning waypoint
- wp = waypoint_spawnpersonal(pos);
+ wp = waypoint_spawnpersonal(this, pos);
if(wp==world)
{
LOG_TRACE("Error: Can't spawn personal waypoint at ",vtos(pos),"\n");
return CMD_STATUS_ERROR;
}
- self.havocbot_personal_waypoint = wp;
- self.havocbot_personal_waypoint_failcounter = 0;
- self.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_LINKING;
+ this.havocbot_personal_waypoint = wp;
+ this.havocbot_personal_waypoint_failcounter = 0;
+ this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_LINKING;
// if pos is inside a teleport, then let's mark it as teleport waypoint
entity head;
if(WarpZoneLib_BoxTouchesBrush(pos, pos, head, world))
{
wp.wpflags |= WAYPOINTFLAG_TELEPORT;
- self.lastteleporttime = 0;
+ this.lastteleporttime = 0;
}
}
return CMD_STATUS_EXECUTING;
}
-float havocbot_resetgoal()
+float havocbot_resetgoal(entity this)
{
- navigation_clearroute();
+ navigation_clearroute(this);
return CMD_STATUS_FINISHED;
}
-void havocbot_setupbot()
-{SELFPARAM();
- self.bot_ai = havocbot_ai;
- self.cmd_moveto = havocbot_moveto;
- self.cmd_resetgoal = havocbot_resetgoal;
+void havocbot_setupbot(entity this)
+{
+ this.bot_ai = havocbot_ai;
+ this.cmd_moveto = havocbot_moveto;
+ this.cmd_resetgoal = havocbot_resetgoal;
- havocbot_chooserole();
+ havocbot_chooserole(this);
}
vector havocbot_dodge()
-{SELFPARAM();
+{
// LordHavoc: disabled because this is too expensive
return '0 0 0';
#if 0
* Functions
*/
-void havocbot_ai();
-void havocbot_aim();
-void havocbot_setupbot();
-void havocbot_movetogoal();
-void havocbot_chooserole();
-void havocbot_chooseenemy();
-void havocbot_chooseweapon();
-void havocbot_bunnyhop(vector dir);
-void havocbot_keyboard_movement(vector destorg);
+void havocbot_ai(entity this);
+void havocbot_aim(entity this);
+void havocbot_setupbot(entity this);
+void havocbot_movetogoal(entity this);
+void havocbot_chooserole(entity this);
+void havocbot_chooseenemy(entity this);
+void havocbot_chooseweapon(entity this);
+void havocbot_bunnyhop(entity this, vector dir);
+void havocbot_keyboard_movement(entity this, vector destorg);
-float havocbot_resetgoal();
-float havocbot_moveto(vector pos);
-float havocbot_moveto_refresh_route();
+float havocbot_resetgoal(entity this);
+float havocbot_moveto(entity this, vector pos);
+float havocbot_moveto_refresh_route(entity this);
vector havocbot_dodge();
-.void() havocbot_role;
-.void() havocbot_previous_role;
+.void(entity this) havocbot_role;
+.void(entity this) havocbot_previous_role;
-void(float ratingscale, vector org, float sradius) havocbot_goalrating_items;
-void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
+void(entity this, float ratingscale, vector org, float sradius) havocbot_goalrating_items;
+void(entity this, float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
/*
* Imports
.float max_armorvalue;
.float havocbot_role_timeout;
-.void() havocbot_previous_role;
-.void() havocbot_role;
+.void(entity this) havocbot_previous_role;
+.void(entity this) havocbot_role;
-void havocbot_goalrating_items(float ratingscale, vector org, float sradius)
-{SELFPARAM();
+void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius)
+{
entity head;
float rating, d, discard, distance, friend_distance, enemy_distance;
vector o;
friend_distance = 10000; enemy_distance = 10000;
rating = 0;
- if(!head.solid || distance > sradius || (head == self.ignoregoal && time < self.ignoregoaltime) )
+ if(!head.solid || distance > sradius || (head == this.ignoregoal && time < this.ignoregoaltime) )
{
head = head.chain;
continue;
{
discard = false;
- FOREACH_CLIENT(IS_PLAYER(it) && it != self && !IS_DEAD(it), LAMBDA(
+ FOREACH_CLIENT(IS_PLAYER(it) && it != this && !IS_DEAD(it), LAMBDA(
d = vlen(it.origin - o); // distance between player and item
- if ( it.team == self.team )
+ if ( it.team == this.team )
{
if ( !IS_REAL_CLIENT(it) || discard )
continue;
discard = true;
- if( head.health && it.health > self.health )
+ if( head.health && it.health > this.health )
continue;
- if( head.armorvalue && it.armorvalue > self.armorvalue)
+ if( head.armorvalue && it.armorvalue > this.armorvalue)
continue;
if( head.weapons )
if( head.weapons & ~it.weapons )
continue;
- if (head.ammo_shells && it.ammo_shells > self.ammo_shells)
+ if (head.ammo_shells && it.ammo_shells > this.ammo_shells)
continue;
- if (head.ammo_nails && it.ammo_nails > self.ammo_nails)
+ if (head.ammo_nails && it.ammo_nails > this.ammo_nails)
continue;
- if (head.ammo_rockets && it.ammo_rockets > self.ammo_rockets)
+ if (head.ammo_rockets && it.ammo_rockets > this.ammo_rockets)
continue;
- if (head.ammo_cells && it.ammo_cells > self.ammo_cells)
+ if (head.ammo_cells && it.ammo_cells > this.ammo_cells)
continue;
- if (head.ammo_plasma && it.ammo_plasma > self.ammo_plasma)
+ if (head.ammo_plasma && it.ammo_plasma > this.ammo_plasma)
continue;
discard = false;
// Rate the item only if no one needs it, or if an enemy is closer to it
if ( (enemy_distance < friend_distance && distance < enemy_distance) ||
(friend_distance > autocvar_bot_ai_friends_aware_pickup_radius ) || !discard )
- rating = head.bot_pickupevalfunc(self, head);
+ rating = head.bot_pickupevalfunc(this, head);
}
else
- rating = head.bot_pickupevalfunc(self, head);
+ rating = head.bot_pickupevalfunc(this, head);
if(rating > 0)
- navigation_routerating(head, rating * ratingscale, 2000);
+ navigation_routerating(this, head, rating * ratingscale, 2000);
head = head.chain;
}
}
-void havocbot_goalrating_controlpoints(float ratingscale, vector org, float sradius)
-{SELFPARAM();
+void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius)
+{
entity head;
head = findchain(classname, "dom_controlpoint");
while (head)
{
- if (vlen(( ( head.absmin + head.absmax ) * 0.5 ) - org) < sradius)
+ if(vdist((((head.absmin + head.absmax) * 0.5) - org), <, sradius))
{
if(head.cnt > -1) // this is just being fought for
- navigation_routerating(head, ratingscale, 5000);
+ navigation_routerating(this, head, ratingscale, 5000);
else if(head.goalentity.cnt == 0) // unclaimed point
- navigation_routerating(head, ratingscale * 0.5, 5000);
- else if(head.goalentity.team != self.team) // other team's point
- navigation_routerating(head, ratingscale * 0.2, 5000);
+ navigation_routerating(this, head, ratingscale * 0.5, 5000);
+ else if(head.goalentity.team != this.team) // other team's point
+ navigation_routerating(this, head, ratingscale * 0.2, 5000);
}
head = head.chain;
}
}
-void havocbot_goalrating_enemyplayers(float ratingscale, vector org, float sradius)
-{SELFPARAM();
+void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius)
+{
if (autocvar_bot_nofire)
return;
// don't chase players if we're under water
- if(self.waterlevel>WATERLEVEL_WETFEET)
+ if(this.waterlevel>WATERLEVEL_WETFEET)
return;
- float distance;
int t;
- FOREACH_CLIENT(IS_PLAYER(it) && bot_shouldattack(it), LAMBDA(
+ FOREACH_CLIENT(IS_PLAYER(it) && bot_shouldattack(this, it), LAMBDA(
// TODO: Merge this logic with the bot_shouldattack function
- distance = vlen(it.origin - org);
- if (distance < 100 || distance > sradius)
+ if(vdist(it.origin - org, <, 100) || vdist(it.origin - org, >, sradius))
continue;
// rate only visible enemies
/*
- traceline(self.origin + self.view_ofs, it.origin, MOVE_NOMONSTERS, self);
+ traceline(this.origin + this.view_ofs, it.origin, MOVE_NOMONSTERS, this);
if (trace_fraction < 1 || trace_ent != it)
continue;
*/
continue;
}
- // TODO: rate waypoints near the targetted player at that moment, instead of the player itself
+ // TODO: rate waypoints near the targetted player at that moment, instead of the player itthis
// adding a player as a goal seems to be quite dangerous, especially on space maps
// remove hack in navigation_poptouchedgoals() after performing this change
- t = (self.health + self.armorvalue ) / (it.health + it.armorvalue );
- navigation_routerating(it, t * ratingscale, 2000);
+ t = (this.health + this.armorvalue ) / (it.health + it.armorvalue );
+ navigation_routerating(this, it, t * ratingscale, 2000);
));
}
// legacy bot role for standard gamemodes
// go to best items
-void havocbot_role_generic()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_generic(entity this)
+{
+ if(IS_DEAD(this))
return;
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
- havocbot_goalrating_items(10000, self.origin, 10000);
- havocbot_goalrating_enemyplayers(20000, self.origin, 10000);
- //havocbot_goalrating_waypoints(1, self.origin, 1000);
- navigation_goalrating_end();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
+ havocbot_goalrating_items(this, 10000, this.origin, 10000);
+ havocbot_goalrating_enemyplayers(this, 20000, this.origin, 10000);
+ //havocbot_goalrating_waypoints(1, this.origin, 1000);
+ navigation_goalrating_end(this);
}
}
-void havocbot_chooserole_generic()
-{SELFPARAM();
- self.havocbot_role = havocbot_role_generic;
+void havocbot_chooserole_generic(entity this)
+{
+ this.havocbot_role = havocbot_role_generic;
}
-void havocbot_chooserole()
-{SELFPARAM();
+void havocbot_chooserole(entity this)
+{
LOG_TRACE("choosing a role...\n");
- self.bot_strategytime = 0;
- if(!MUTATOR_CALLHOOK(HavocBot_ChooseRole, self))
- havocbot_chooserole_generic();
+ this.bot_strategytime = 0;
+ if(!MUTATOR_CALLHOOK(HavocBot_ChooseRole, this))
+ havocbot_chooserole_generic(this);
}
#pragma once
-void havocbot_goalrating_controlpoints(float ratingscale, vector org, float sradius);
+void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius);
if(autocvar_bot_debug_tracewalk)
{
debugresetnodes();
- debugnode(start);
+ debugnode(self, start);
}
move = end - start;
return true;
}
if(autocvar_bot_debug_tracewalk)
- debugnode(org);
+ debugnode(self, org);
if (dist <= 0)
break;
tracebox(org, m1, m2, org + move * stepdist, movemode, e);
if(autocvar_bot_debug_tracewalk)
- debugnode(trace_endpos);
+ debugnode(self, trace_endpos);
if (trace_fraction < 1)
{
for (; org.z < end.z + self.maxs.z; org.z += stepdist)
{
if(autocvar_bot_debug_tracewalk)
- debugnode(org);
+ debugnode(self, org);
if(pointcontents(org) == CONTENT_EMPTY)
break;
tracebox(org, m1, m2, move, movemode, e);
if(autocvar_bot_debug_tracewalk)
- debugnode(trace_endpos);
+ debugnode(self, trace_endpos);
// hit something
if (trace_fraction < 1)
/////////////////////////////////////////////////////////////////////////////
// completely empty the goal stack, used when deciding where to go
-void navigation_clearroute()
-{SELFPARAM();
- //print("bot ", etos(self), " clear\n");
- self.navigation_hasgoals = false;
- self.goalcurrent = world;
- self.goalstack01 = world;
- self.goalstack02 = world;
- self.goalstack03 = world;
- self.goalstack04 = world;
- self.goalstack05 = world;
- self.goalstack06 = world;
- self.goalstack07 = world;
- self.goalstack08 = world;
- self.goalstack09 = world;
- self.goalstack10 = world;
- self.goalstack11 = world;
- self.goalstack12 = world;
- self.goalstack13 = world;
- self.goalstack14 = world;
- self.goalstack15 = world;
- self.goalstack16 = world;
- self.goalstack17 = world;
- self.goalstack18 = world;
- self.goalstack19 = world;
- self.goalstack20 = world;
- self.goalstack21 = world;
- self.goalstack22 = world;
- self.goalstack23 = world;
- self.goalstack24 = world;
- self.goalstack25 = world;
- self.goalstack26 = world;
- self.goalstack27 = world;
- self.goalstack28 = world;
- self.goalstack29 = world;
- self.goalstack30 = world;
- self.goalstack31 = world;
+void navigation_clearroute(entity this)
+{
+ //print("bot ", etos(this), " clear\n");
+ this.navigation_hasgoals = false;
+ this.goalcurrent = world;
+ this.goalstack01 = world;
+ this.goalstack02 = world;
+ this.goalstack03 = world;
+ this.goalstack04 = world;
+ this.goalstack05 = world;
+ this.goalstack06 = world;
+ this.goalstack07 = world;
+ this.goalstack08 = world;
+ this.goalstack09 = world;
+ this.goalstack10 = world;
+ this.goalstack11 = world;
+ this.goalstack12 = world;
+ this.goalstack13 = world;
+ this.goalstack14 = world;
+ this.goalstack15 = world;
+ this.goalstack16 = world;
+ this.goalstack17 = world;
+ this.goalstack18 = world;
+ this.goalstack19 = world;
+ this.goalstack20 = world;
+ this.goalstack21 = world;
+ this.goalstack22 = world;
+ this.goalstack23 = world;
+ this.goalstack24 = world;
+ this.goalstack25 = world;
+ this.goalstack26 = world;
+ this.goalstack27 = world;
+ this.goalstack28 = world;
+ this.goalstack29 = world;
+ this.goalstack30 = world;
+ this.goalstack31 = world;
}
// add a new goal at the beginning of the stack
// next-closest WP on the shortest path to the WP
// That means, if the stack overflows, the bot will know how to do the FIRST 32
// steps to the goal, and then recalculate the path.
-void navigation_pushroute(entity e)
-{SELFPARAM();
- //print("bot ", etos(self), " push ", etos(e), "\n");
- self.goalstack31 = self.goalstack30;
- self.goalstack30 = self.goalstack29;
- self.goalstack29 = self.goalstack28;
- self.goalstack28 = self.goalstack27;
- self.goalstack27 = self.goalstack26;
- self.goalstack26 = self.goalstack25;
- self.goalstack25 = self.goalstack24;
- self.goalstack24 = self.goalstack23;
- self.goalstack23 = self.goalstack22;
- self.goalstack22 = self.goalstack21;
- self.goalstack21 = self.goalstack20;
- self.goalstack20 = self.goalstack19;
- self.goalstack19 = self.goalstack18;
- self.goalstack18 = self.goalstack17;
- self.goalstack17 = self.goalstack16;
- self.goalstack16 = self.goalstack15;
- self.goalstack15 = self.goalstack14;
- self.goalstack14 = self.goalstack13;
- self.goalstack13 = self.goalstack12;
- self.goalstack12 = self.goalstack11;
- self.goalstack11 = self.goalstack10;
- self.goalstack10 = self.goalstack09;
- self.goalstack09 = self.goalstack08;
- self.goalstack08 = self.goalstack07;
- self.goalstack07 = self.goalstack06;
- self.goalstack06 = self.goalstack05;
- self.goalstack05 = self.goalstack04;
- self.goalstack04 = self.goalstack03;
- self.goalstack03 = self.goalstack02;
- self.goalstack02 = self.goalstack01;
- self.goalstack01 = self.goalcurrent;
- self.goalcurrent = e;
+void navigation_pushroute(entity this, entity e)
+{
+ //print("bot ", etos(this), " push ", etos(e), "\n");
+ this.goalstack31 = this.goalstack30;
+ this.goalstack30 = this.goalstack29;
+ this.goalstack29 = this.goalstack28;
+ this.goalstack28 = this.goalstack27;
+ this.goalstack27 = this.goalstack26;
+ this.goalstack26 = this.goalstack25;
+ this.goalstack25 = this.goalstack24;
+ this.goalstack24 = this.goalstack23;
+ this.goalstack23 = this.goalstack22;
+ this.goalstack22 = this.goalstack21;
+ this.goalstack21 = this.goalstack20;
+ this.goalstack20 = this.goalstack19;
+ this.goalstack19 = this.goalstack18;
+ this.goalstack18 = this.goalstack17;
+ this.goalstack17 = this.goalstack16;
+ this.goalstack16 = this.goalstack15;
+ this.goalstack15 = this.goalstack14;
+ this.goalstack14 = this.goalstack13;
+ this.goalstack13 = this.goalstack12;
+ this.goalstack12 = this.goalstack11;
+ this.goalstack11 = this.goalstack10;
+ this.goalstack10 = this.goalstack09;
+ this.goalstack09 = this.goalstack08;
+ this.goalstack08 = this.goalstack07;
+ this.goalstack07 = this.goalstack06;
+ this.goalstack06 = this.goalstack05;
+ this.goalstack05 = this.goalstack04;
+ this.goalstack04 = this.goalstack03;
+ this.goalstack03 = this.goalstack02;
+ this.goalstack02 = this.goalstack01;
+ this.goalstack01 = this.goalcurrent;
+ this.goalcurrent = e;
}
// remove first goal from stack
// (in other words: remove a prerequisite for reaching the later goals)
// (used when a spawnfunc_waypoint is reached)
-void navigation_poproute()
-{SELFPARAM();
- //print("bot ", etos(self), " pop\n");
- self.goalcurrent = self.goalstack01;
- self.goalstack01 = self.goalstack02;
- self.goalstack02 = self.goalstack03;
- self.goalstack03 = self.goalstack04;
- self.goalstack04 = self.goalstack05;
- self.goalstack05 = self.goalstack06;
- self.goalstack06 = self.goalstack07;
- self.goalstack07 = self.goalstack08;
- self.goalstack08 = self.goalstack09;
- self.goalstack09 = self.goalstack10;
- self.goalstack10 = self.goalstack11;
- self.goalstack11 = self.goalstack12;
- self.goalstack12 = self.goalstack13;
- self.goalstack13 = self.goalstack14;
- self.goalstack14 = self.goalstack15;
- self.goalstack15 = self.goalstack16;
- self.goalstack16 = self.goalstack17;
- self.goalstack17 = self.goalstack18;
- self.goalstack18 = self.goalstack19;
- self.goalstack19 = self.goalstack20;
- self.goalstack20 = self.goalstack21;
- self.goalstack21 = self.goalstack22;
- self.goalstack22 = self.goalstack23;
- self.goalstack23 = self.goalstack24;
- self.goalstack24 = self.goalstack25;
- self.goalstack25 = self.goalstack26;
- self.goalstack26 = self.goalstack27;
- self.goalstack27 = self.goalstack28;
- self.goalstack28 = self.goalstack29;
- self.goalstack29 = self.goalstack30;
- self.goalstack30 = self.goalstack31;
- self.goalstack31 = world;
+void navigation_poproute(entity this)
+{
+ //print("bot ", etos(this), " pop\n");
+ this.goalcurrent = this.goalstack01;
+ this.goalstack01 = this.goalstack02;
+ this.goalstack02 = this.goalstack03;
+ this.goalstack03 = this.goalstack04;
+ this.goalstack04 = this.goalstack05;
+ this.goalstack05 = this.goalstack06;
+ this.goalstack06 = this.goalstack07;
+ this.goalstack07 = this.goalstack08;
+ this.goalstack08 = this.goalstack09;
+ this.goalstack09 = this.goalstack10;
+ this.goalstack10 = this.goalstack11;
+ this.goalstack11 = this.goalstack12;
+ this.goalstack12 = this.goalstack13;
+ this.goalstack13 = this.goalstack14;
+ this.goalstack14 = this.goalstack15;
+ this.goalstack15 = this.goalstack16;
+ this.goalstack16 = this.goalstack17;
+ this.goalstack17 = this.goalstack18;
+ this.goalstack18 = this.goalstack19;
+ this.goalstack19 = this.goalstack20;
+ this.goalstack20 = this.goalstack21;
+ this.goalstack21 = this.goalstack22;
+ this.goalstack22 = this.goalstack23;
+ this.goalstack23 = this.goalstack24;
+ this.goalstack24 = this.goalstack25;
+ this.goalstack25 = this.goalstack26;
+ this.goalstack26 = this.goalstack27;
+ this.goalstack27 = this.goalstack28;
+ this.goalstack28 = this.goalstack29;
+ this.goalstack29 = this.goalstack30;
+ this.goalstack30 = this.goalstack31;
+ this.goalstack31 = world;
}
float navigation_waypoint_will_link(vector v, vector org, entity ent, float walkfromwp, float bestdist)
}
// finds the waypoints near the bot initiating a navigation query
-float navigation_markroutes_nearestwaypoints(entity waylist, float maxdist)
-{SELFPARAM();
+float navigation_markroutes_nearestwaypoints(entity this, entity waylist, float maxdist)
+{
entity head;
vector v, m1, m2, diff;
float c;
{
m1 = head.origin + head.mins;
m2 = head.origin + head.maxs;
- v = self.origin;
+ v = this.origin;
v.x = bound(m1_x, v.x, m2_x);
v.y = bound(m1_y, v.y, m2_y);
v.z = bound(m1_z, v.z, m2_z);
}
else
v = head.origin;
- diff = v - self.origin;
+ diff = v - this.origin;
diff.z = max(0, diff.z);
- if (vlen(diff) < maxdist)
+ if(vdist(diff, <, maxdist))
{
head.wpconsidered = true;
- if (tracewalk(self, self.origin, self.mins, self.maxs, v, bot_navigation_movemode))
+ entity oldself = self;
+ setself(this);
+ if (tracewalk(this, this.origin, this.mins, this.maxs, v, bot_navigation_movemode))
{
head.wpnearestpoint = v;
- head.wpcost = vlen(v - self.origin) + head.dmg;
+ head.wpcost = vlen(v - this.origin) + head.dmg;
head.wpfire = 1;
head.enemy = world;
c = c + 1;
}
+ setself(oldself);
}
}
head = head.chain;
}
// queries the entire spawnfunc_waypoint network for pathes leading away from the bot
-void navigation_markroutes(entity fixed_source_waypoint)
-{SELFPARAM();
+void navigation_markroutes(entity this, entity fixed_source_waypoint)
+{
entity w, wp, waylist;
float searching, cost, cost2;
vector p;
// try a short range search for the nearest waypoints, and expand the search repeatedly if none are found
// as this search is expensive we will use lower values if the bot is on the air
float i, increment, maxdistance;
- if(IS_ONGROUND(self))
+ if(IS_ONGROUND(this))
{
increment = 750;
maxdistance = 50000;
maxdistance = 1500;
}
- for(i=increment;!navigation_markroutes_nearestwaypoints(waylist, i)&&i<maxdistance;i+=increment);
+ for(i=increment;!navigation_markroutes_nearestwaypoints(this, waylist, i)&&i<maxdistance;i+=increment);
}
searching = true;
}
// updates the best goal according to a weighted calculation of travel cost and item value of a new proposed item
-void navigation_routerating(entity e, float f, float rangebias)
-{SELFPARAM();
+void navigation_routerating(entity this, entity e, float f, float rangebias)
+{
entity nwp;
vector o;
if (!e)
// Evaluate path using jetpack
if(g_jetpack)
- if(self.items & IT_JETPACK)
+ if(this.items & IT_JETPACK)
if(autocvar_bot_ai_navigation_jetpack)
- if(vlen(self.origin - o) > autocvar_bot_ai_navigation_jetpack_mindistance)
+ if(vlen(this.origin - o) > autocvar_bot_ai_navigation_jetpack_mindistance)
{
vector pointa, pointb;
LOG_DEBUG("jetpack ai: evaluating path for ", e.classname, "\n");
// Point A
- traceline(self.origin, self.origin + '0 0 65535', MOVE_NORMAL, self);
+ traceline(this.origin, this.origin + '0 0 65535', MOVE_NORMAL, this);
pointa = trace_endpos - '0 0 1';
// Point B
pointb = trace_endpos - '0 0 1';
// Can I see these two points from the sky?
- traceline(pointa, pointb, MOVE_NORMAL, self);
+ traceline(pointa, pointb, MOVE_NORMAL, this);
if(trace_fraction==1)
{
npa = pointa + down;
npb = pointb + down;
- if(npa.z<=self.absmax.z)
+ if(npa.z<=this.absmax.z)
break;
if(npb.z<=e.absmax.z)
break;
- traceline(npa, npb, MOVE_NORMAL, self);
+ traceline(npa, npb, MOVE_NORMAL, this);
if(trace_fraction==1)
{
pointa = npa;
// Rough estimation of fuel consumption
// (ignores acceleration and current xyz velocity)
xydistance = vlen(pointa - pointb);
- zdistance = fabs(pointa.z - self.origin.z);
+ zdistance = fabs(pointa.z - this.origin.z);
t = zdistance / autocvar_g_jetpack_maxspeed_up;
t += xydistance / autocvar_g_jetpack_maxspeed_side;
fuel = t * autocvar_g_jetpack_fuel * 0.8;
- LOG_DEBUG(strcat("jetpack ai: required fuel ", ftos(fuel), " self.ammo_fuel ", ftos(self.ammo_fuel), "\n"));
+ LOG_DEBUG(strcat("jetpack ai: required fuel ", ftos(fuel), " this.ammo_fuel ", ftos(this.ammo_fuel), "\n"));
// enough fuel ?
- if(self.ammo_fuel>fuel)
+ if(this.ammo_fuel>fuel)
{
// Estimate cost
// (as onground costs calculation is mostly based on distances, here we do the same establishing some relationship
LOG_DEBUG(strcat("jetpack path: added goal ", e.classname, " (with rating ", ftos(f), ")\n"));
navigation_bestrating = f;
navigation_bestgoal = e;
- self.navigation_jetpack_goal = e;
- self.navigation_jetpack_point = pointb;
+ this.navigation_jetpack_goal = e;
+ this.navigation_jetpack_point = pointb;
}
return;
}
}
// adds an item to the the goal stack with the path to a given item
-float navigation_routetogoal(entity e, vector startposition)
-{SELFPARAM();
- self.goalentity = e;
+bool navigation_routetogoal(entity this, entity e, vector startposition)
+{
+ this.goalentity = e;
// if there is no goal, just exit
if (!e)
return false;
- self.navigation_hasgoals = true;
+ this.navigation_hasgoals = true;
// put the entity on the goal stack
//print("routetogoal ", etos(e), "\n");
- navigation_pushroute(e);
+ navigation_pushroute(this, e);
if(g_jetpack)
- if(e==self.navigation_jetpack_goal)
+ if(e==this.navigation_jetpack_goal)
return true;
// if it can reach the goal there is nothing more to do
- if (tracewalk(self, startposition, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), (e.absmin + e.absmax) * 0.5, bot_navigation_movemode))
+ if (tracewalk(this, startposition, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), (e.absmin + e.absmax) * 0.5, bot_navigation_movemode))
return true;
// see if there are waypoints describing a path to the item
for (;;)
{
// add the spawnfunc_waypoint to the path
- navigation_pushroute(e);
+ navigation_pushroute(this, e);
e = e.enemy;
if(e==world)
// removes any currently touching waypoints from the goal stack
// (this is how bots detect if they reached a goal)
-void navigation_poptouchedgoals()
-{SELFPARAM();
+void navigation_poptouchedgoals(entity this)
+{
vector org, m1, m2;
- org = self.origin;
- m1 = org + self.mins;
- m2 = org + self.maxs;
+ org = this.origin;
+ m1 = org + this.mins;
+ m2 = org + this.maxs;
- if(self.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
+ if(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
{
- if(self.lastteleporttime>0)
- if(time-self.lastteleporttime<(self.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL)?2:0.15)
+ if(this.lastteleporttime>0)
+ if(time-this.lastteleporttime<(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL)?2:0.15)
{
- if(self.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
- if(self.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && self.goalcurrent.owner==self)
+ if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
+ if(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && this.goalcurrent.owner==this)
{
- self.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
- self.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
+ this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
+ this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
}
- navigation_poproute();
+ navigation_poproute(this);
return;
}
}
// If for some reason the bot is closer to the next goal, pop the current one
- if(self.goalstack01)
- if(vlen(self.goalcurrent.origin - self.origin) > vlen(self.goalstack01.origin - self.origin))
- if(checkpvs(self.origin + self.view_ofs, self.goalstack01))
- if(tracewalk(self, self.origin, self.mins, self.maxs, (self.goalstack01.absmin + self.goalstack01.absmax) * 0.5, bot_navigation_movemode))
+ if(this.goalstack01)
+ if(vlen(this.goalcurrent.origin - this.origin) > vlen(this.goalstack01.origin - this.origin))
+ if(checkpvs(this.origin + this.view_ofs, this.goalstack01))
+ if(tracewalk(this, this.origin, this.mins, this.maxs, (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5, bot_navigation_movemode))
{
- LOG_DEBUG(strcat("path optimized for ", self.netname, ", removed a goal from the queue\n"));
- navigation_poproute();
+ LOG_DEBUG(strcat("path optimized for ", this.netname, ", removed a goal from the queue\n"));
+ navigation_poproute(this);
// TODO this may also be a nice idea to do "early" (e.g. by
// manipulating the vlen() comparisons) to shorten paths in
// general - this would make bots walk more "on rails" than
}
// HACK: remove players/bots as goals, they can lead a bot to unexpected places (cliffs, lava, etc)
- // TODO: rate waypoints near the targetted player at that moment, instead of the player itself
- if(IS_PLAYER(self.goalcurrent))
- navigation_poproute();
+ // TODO: rate waypoints near the targetted player at that moment, instead of the player itthis
+ if(IS_PLAYER(this.goalcurrent))
+ navigation_poproute(this);
// aid for detecting jump pads better (distance based check fails sometimes)
- if(self.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT && self.jumppadcount > 0 )
- navigation_poproute();
+ if(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT && this.jumppadcount > 0 )
+ navigation_poproute(this);
// Loose goal touching check when running
- if(self.aistatus & AI_STATUS_RUNNING)
- if(self.speed >= autocvar_sv_maxspeed) // if -really- running
- if(self.goalcurrent.classname=="waypoint")
+ if(this.aistatus & AI_STATUS_RUNNING)
+ if(this.speed >= autocvar_sv_maxspeed) // if -really- running
+ if(this.goalcurrent.classname=="waypoint")
{
- if(vlen(self.origin - self.goalcurrent.origin)<150)
+ if(vlen(this.origin - this.goalcurrent.origin)<150)
{
- traceline(self.origin + self.view_ofs , self.goalcurrent.origin, true, world);
+ traceline(this.origin + this.view_ofs , this.goalcurrent.origin, true, world);
if(trace_fraction==1)
{
// Detect personal waypoints
- if(self.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
- if(self.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && self.goalcurrent.owner==self)
+ if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
+ if(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && this.goalcurrent.owner==this)
{
- self.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
- self.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
+ this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
+ this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
}
- navigation_poproute();
+ navigation_poproute(this);
}
}
}
- while (self.goalcurrent && boxesoverlap(m1, m2, self.goalcurrent.absmin, self.goalcurrent.absmax))
+ while (this.goalcurrent && boxesoverlap(m1, m2, this.goalcurrent.absmin, this.goalcurrent.absmax))
{
// Detect personal waypoints
- if(self.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
- if(self.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && self.goalcurrent.owner==self)
+ if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
+ if(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && this.goalcurrent.owner==this)
{
- self.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
- self.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
+ this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
+ this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
}
- navigation_poproute();
+ navigation_poproute(this);
}
}
// begin a goal selection session (queries spawnfunc_waypoint network)
-void navigation_goalrating_start()
-{SELFPARAM();
- if(self.aistatus & AI_STATUS_STUCK)
+void navigation_goalrating_start(entity this)
+{
+ if(this.aistatus & AI_STATUS_STUCK)
return;
- self.navigation_jetpack_goal = world;
+ this.navigation_jetpack_goal = world;
navigation_bestrating = -1;
- self.navigation_hasgoals = false;
- navigation_clearroute();
+ this.navigation_hasgoals = false;
+ navigation_clearroute(this);
navigation_bestgoal = world;
- navigation_markroutes(world);
+ navigation_markroutes(this, world);
}
// ends a goal selection session (updates goal stack to the best goal)
-void navigation_goalrating_end()
-{SELFPARAM();
- if(self.aistatus & AI_STATUS_STUCK)
+void navigation_goalrating_end(entity this)
+{
+ if(this.aistatus & AI_STATUS_STUCK)
return;
- navigation_routetogoal(navigation_bestgoal, self.origin);
- LOG_DEBUG(strcat("best goal ", self.goalcurrent.classname , "\n"));
+ navigation_routetogoal(this, navigation_bestgoal, this.origin);
+ LOG_DEBUG(strcat("best goal ", this.goalcurrent.classname , "\n"));
// If the bot got stuck then try to reach the farthest waypoint
- if (!self.navigation_hasgoals)
+ if (!this.navigation_hasgoals)
if (autocvar_bot_wander_enable)
{
- if (!(self.aistatus & AI_STATUS_STUCK))
+ if (!(this.aistatus & AI_STATUS_STUCK))
{
- LOG_DEBUG(strcat(self.netname, " cannot walk to any goal\n"));
- self.aistatus |= AI_STATUS_STUCK;
+ LOG_DEBUG(strcat(this.netname, " cannot walk to any goal\n"));
+ this.aistatus |= AI_STATUS_STUCK;
}
- self.navigation_hasgoals = false; // Reset this value
+ this.navigation_hasgoals = false; // Reset this value
}
}
}
}
-void navigation_unstuck()
-{SELFPARAM();
+void navigation_unstuck(entity this)
+{
float search_radius = 1000;
if (!autocvar_bot_wander_enable)
if (!bot_waypoint_queue_owner)
{
- LOG_DEBUG(strcat(self.netname, " sutck, taking over the waypoints queue\n"));
- bot_waypoint_queue_owner = self;
+ LOG_DEBUG(strcat(this.netname, " sutck, taking over the waypoints queue\n"));
+ bot_waypoint_queue_owner = this;
bot_waypoint_queue_bestgoal = world;
bot_waypoint_queue_bestgoalrating = 0;
}
- if(bot_waypoint_queue_owner!=self)
+ if(bot_waypoint_queue_owner!=this)
return;
if (bot_waypoint_queue_goal)
{
// evaluate the next goal on the queue
- float d = vlen(self.origin - bot_waypoint_queue_goal.origin);
- LOG_DEBUG(strcat(self.netname, " evaluating ", bot_waypoint_queue_goal.classname, " with distance ", ftos(d), "\n"));
- if(tracewalk(bot_waypoint_queue_goal, self.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), bot_waypoint_queue_goal.origin, bot_navigation_movemode))
+ float d = vlen(this.origin - bot_waypoint_queue_goal.origin);
+ LOG_DEBUG(strcat(this.netname, " evaluating ", bot_waypoint_queue_goal.classname, " with distance ", ftos(d), "\n"));
+ entity oldself = self;
+ setself(this); // tracewalk has questionable use of self
+ if(tracewalk(bot_waypoint_queue_goal, this.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), bot_waypoint_queue_goal.origin, bot_navigation_movemode))
{
if( d > bot_waypoint_queue_bestgoalrating)
{
bot_waypoint_queue_bestgoal = bot_waypoint_queue_goal;
}
}
+ setself(oldself);
bot_waypoint_queue_goal = bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal;
if (!bot_waypoint_queue_goal)
{
if (bot_waypoint_queue_bestgoal)
{
- LOG_DEBUG(strcat(self.netname, " stuck, reachable waypoint found, heading to it\n"));
- navigation_routetogoal(bot_waypoint_queue_bestgoal, self.origin);
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- self.aistatus &= ~AI_STATUS_STUCK;
+ LOG_DEBUG(strcat(this.netname, " stuck, reachable waypoint found, heading to it\n"));
+ navigation_routetogoal(this, bot_waypoint_queue_bestgoal, this.origin);
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ this.aistatus &= ~AI_STATUS_STUCK;
}
else
{
- LOG_DEBUG(strcat(self.netname, " stuck, cannot walk to any waypoint at all\n"));
+ LOG_DEBUG(strcat(this.netname, " stuck, cannot walk to any waypoint at all\n"));
}
bot_waypoint_queue_owner = world;
}
else
{
- if(bot_strategytoken!=self)
+ if(bot_strategytoken!=this)
return;
// build a new queue
- LOG_DEBUG(strcat(self.netname, " stuck, scanning reachable waypoints within ", ftos(search_radius)," qu\n"));
+ LOG_DEBUG(strcat(this.netname, " stuck, scanning reachable waypoints within ", ftos(search_radius)," qu\n"));
entity head, first;
first = world;
- head = findradius(self.origin, search_radius);
+ head = findradius(this.origin, search_radius);
while(head)
{
bot_waypoint_queue_goal = first;
else
{
- LOG_DEBUG(strcat(self.netname, " stuck, cannot walk to any waypoint at all\n"));
+ LOG_DEBUG(strcat(this.netname, " stuck, cannot walk to any waypoint at all\n"));
bot_waypoint_queue_owner = world;
}
}
debuglastnode = '0 0 0';
}
-void debugnode(vector node)
-{SELFPARAM();
- if (!IS_PLAYER(self))
+void debugnode(entity this, vector node)
+{
+ if (!IS_PLAYER(this))
return;
if(debuglastnode=='0 0 0')
.vector lastposition;
// Debug the goal stack visually
-void debuggoalstack()
-{SELFPARAM();
+void debuggoalstack(entity this)
+{
entity goal;
vector org, go;
- if(self.goalcounter==0)goal=self.goalcurrent;
- else if(self.goalcounter==1)goal=self.goalstack01;
- else if(self.goalcounter==2)goal=self.goalstack02;
- else if(self.goalcounter==3)goal=self.goalstack03;
- else if(self.goalcounter==4)goal=self.goalstack04;
- else if(self.goalcounter==5)goal=self.goalstack05;
- else if(self.goalcounter==6)goal=self.goalstack06;
- else if(self.goalcounter==7)goal=self.goalstack07;
- else if(self.goalcounter==8)goal=self.goalstack08;
- else if(self.goalcounter==9)goal=self.goalstack09;
- else if(self.goalcounter==10)goal=self.goalstack10;
- else if(self.goalcounter==11)goal=self.goalstack11;
- else if(self.goalcounter==12)goal=self.goalstack12;
- else if(self.goalcounter==13)goal=self.goalstack13;
- else if(self.goalcounter==14)goal=self.goalstack14;
- else if(self.goalcounter==15)goal=self.goalstack15;
- else if(self.goalcounter==16)goal=self.goalstack16;
- else if(self.goalcounter==17)goal=self.goalstack17;
- else if(self.goalcounter==18)goal=self.goalstack18;
- else if(self.goalcounter==19)goal=self.goalstack19;
- else if(self.goalcounter==20)goal=self.goalstack20;
- else if(self.goalcounter==21)goal=self.goalstack21;
- else if(self.goalcounter==22)goal=self.goalstack22;
- else if(self.goalcounter==23)goal=self.goalstack23;
- else if(self.goalcounter==24)goal=self.goalstack24;
- else if(self.goalcounter==25)goal=self.goalstack25;
- else if(self.goalcounter==26)goal=self.goalstack26;
- else if(self.goalcounter==27)goal=self.goalstack27;
- else if(self.goalcounter==28)goal=self.goalstack28;
- else if(self.goalcounter==29)goal=self.goalstack29;
- else if(self.goalcounter==30)goal=self.goalstack30;
- else if(self.goalcounter==31)goal=self.goalstack31;
+ if(this.goalcounter==0)goal=this.goalcurrent;
+ else if(this.goalcounter==1)goal=this.goalstack01;
+ else if(this.goalcounter==2)goal=this.goalstack02;
+ else if(this.goalcounter==3)goal=this.goalstack03;
+ else if(this.goalcounter==4)goal=this.goalstack04;
+ else if(this.goalcounter==5)goal=this.goalstack05;
+ else if(this.goalcounter==6)goal=this.goalstack06;
+ else if(this.goalcounter==7)goal=this.goalstack07;
+ else if(this.goalcounter==8)goal=this.goalstack08;
+ else if(this.goalcounter==9)goal=this.goalstack09;
+ else if(this.goalcounter==10)goal=this.goalstack10;
+ else if(this.goalcounter==11)goal=this.goalstack11;
+ else if(this.goalcounter==12)goal=this.goalstack12;
+ else if(this.goalcounter==13)goal=this.goalstack13;
+ else if(this.goalcounter==14)goal=this.goalstack14;
+ else if(this.goalcounter==15)goal=this.goalstack15;
+ else if(this.goalcounter==16)goal=this.goalstack16;
+ else if(this.goalcounter==17)goal=this.goalstack17;
+ else if(this.goalcounter==18)goal=this.goalstack18;
+ else if(this.goalcounter==19)goal=this.goalstack19;
+ else if(this.goalcounter==20)goal=this.goalstack20;
+ else if(this.goalcounter==21)goal=this.goalstack21;
+ else if(this.goalcounter==22)goal=this.goalstack22;
+ else if(this.goalcounter==23)goal=this.goalstack23;
+ else if(this.goalcounter==24)goal=this.goalstack24;
+ else if(this.goalcounter==25)goal=this.goalstack25;
+ else if(this.goalcounter==26)goal=this.goalstack26;
+ else if(this.goalcounter==27)goal=this.goalstack27;
+ else if(this.goalcounter==28)goal=this.goalstack28;
+ else if(this.goalcounter==29)goal=this.goalstack29;
+ else if(this.goalcounter==30)goal=this.goalstack30;
+ else if(this.goalcounter==31)goal=this.goalstack31;
else goal=world;
if(goal==world)
{
- self.goalcounter = 0;
- self.lastposition='0 0 0';
+ this.goalcounter = 0;
+ this.lastposition='0 0 0';
return;
}
- if(self.lastposition=='0 0 0')
- org = self.origin;
+ if(this.lastposition=='0 0 0')
+ org = this.origin;
else
- org = self.lastposition;
+ org = this.lastposition;
go = ( goal.absmin + goal.absmax ) * 0.5;
te_lightning2(world, org, go);
- self.lastposition = go;
+ this.lastposition = go;
- self.goalcounter++;
+ this.goalcounter++;
}
*/
void debugresetnodes();
-void debugnode(vector node);
+void debugnode(entity this, vector node);
void debugnodestatus(vector position, float status);
-void debuggoalstack();
+void debuggoalstack(entity this);
float tracewalk(entity e, vector start, vector m1, vector m2, vector end, float movemode);
-float navigation_markroutes_nearestwaypoints(entity waylist, float maxdist);
-float navigation_routetogoal(entity e, vector startposition);
+float navigation_markroutes_nearestwaypoints(entity this, entity waylist, float maxdist);
+float navigation_routetogoal(entity this, entity e, vector startposition);
-void navigation_clearroute();
-void navigation_pushroute(entity e);
-void navigation_poproute();
+void navigation_clearroute(entity this);
+void navigation_pushroute(entity this, entity e);
+void navigation_poproute(entity this);
void navigation_markroutes_checkwaypoint(entity w, entity wp, float cost2, vector p);
-void navigation_markroutes(entity fixed_source_waypoint);
+void navigation_markroutes(entity this, entity fixed_source_waypoint);
void navigation_markroutes_inverted(entity fixed_source_waypoint);
-void navigation_routerating(entity e, float f, float rangebias);
-void navigation_poptouchedgoals();
-void navigation_goalrating_start();
-void navigation_goalrating_end();
-void navigation_unstuck();
+void navigation_routerating(entity this, entity e, float f, float rangebias);
+void navigation_poptouchedgoals(entity this);
+void navigation_goalrating_start(entity this);
+void navigation_goalrating_end(entity this);
+void navigation_unstuck(entity this);
void botframe_updatedangerousobjects(float maxupdate);
return bufstr_get(bot.bot_cmdqueuebuf, idx);
}
-float bot_havecommand(entity bot, float idx)
+bool bot_havecommand(entity this, int idx)
{
- if(!bot.bot_cmdqueuebuf_allocated)
- return 0;
- if(idx < bot.bot_cmdqueuebuf_start)
- return 0;
- if(idx >= bot.bot_cmdqueuebuf_end)
- return 0;
- return 1;
+ if(!this.bot_cmdqueuebuf_allocated)
+ return false;
+ if(idx < this.bot_cmdqueuebuf_start)
+ return false;
+ if(idx >= this.bot_cmdqueuebuf_end)
+ return false;
+ return true;
}
const int MAX_BOT_PLACES = 4;
.float bot_places_count;
.entity bot_places[MAX_BOT_PLACES];
.string bot_placenames[MAX_BOT_PLACES];
-entity bot_getplace(string placename)
-{SELFPARAM();
+entity bot_getplace(entity this, string placename)
+{
entity e;
if(substring(placename, 0, 1) == "@")
{
int i, p;
placename = substring(placename, 1, -1);
string s, s2;
- for(i = 0; i < self.bot_places_count; ++i)
- if(self.(bot_placenames[i]) == placename)
- return self.(bot_places[i]);
- // now: i == self.bot_places_count
+ for(i = 0; i < this.bot_places_count; ++i)
+ if(this.(bot_placenames[i]) == placename)
+ return this.(bot_places[i]);
+ // now: i == this.bot_places_count
s = s2 = cvar_string(placename);
p = strstrofs(s2, " ", 0);
if(p >= 0)
LOG_INFO("invalid place ", s, "\n");
if(i < MAX_BOT_PLACES)
{
- self.(bot_placenames[i]) = strzone(placename);
- self.(bot_places[i]) = e;
- self.bot_places_count += 1;
+ this.(bot_placenames[i]) = strzone(placename);
+ this.(bot_places[i]) = e;
+ this.bot_places_count += 1;
}
return e;
}
.int bot_exec_status;
void SV_ParseClientCommand(string s);
-float bot_cmd_cc()
+float bot_cmd_cc(entity this)
{
- SV_ParseClientCommand(bot_cmd.bot_cmd_parm_string);
+ WITH(entity, self, this, SV_ParseClientCommand(bot_cmd.bot_cmd_parm_string));
return CMD_STATUS_FINISHED;
}
-float bot_cmd_impulse()
-{SELFPARAM();
- self.impulse = bot_cmd.bot_cmd_parm_float;
+float bot_cmd_impulse(entity this)
+{
+ this.impulse = bot_cmd.bot_cmd_parm_float;
return CMD_STATUS_FINISHED;
}
-float bot_cmd_continue()
-{SELFPARAM();
- self.bot_exec_status &= ~BOT_EXEC_STATUS_PAUSED;
+float bot_cmd_continue(entity this)
+{
+ this.bot_exec_status &= ~BOT_EXEC_STATUS_PAUSED;
return CMD_STATUS_FINISHED;
}
.float bot_cmd_wait_time;
-float bot_cmd_wait()
-{SELFPARAM();
- if(self.bot_exec_status & BOT_EXEC_STATUS_WAITING)
+float bot_cmd_wait(entity this)
+{
+ if(this.bot_exec_status & BOT_EXEC_STATUS_WAITING)
{
- if(time>=self.bot_cmd_wait_time)
+ if(time>=this.bot_cmd_wait_time)
{
- self.bot_exec_status &= ~BOT_EXEC_STATUS_WAITING;
+ this.bot_exec_status &= ~BOT_EXEC_STATUS_WAITING;
return CMD_STATUS_FINISHED;
}
else
return CMD_STATUS_EXECUTING;
}
- self.bot_cmd_wait_time = time + bot_cmd.bot_cmd_parm_float;
- self.bot_exec_status |= BOT_EXEC_STATUS_WAITING;
+ this.bot_cmd_wait_time = time + bot_cmd.bot_cmd_parm_float;
+ this.bot_exec_status |= BOT_EXEC_STATUS_WAITING;
return CMD_STATUS_EXECUTING;
}
-float bot_cmd_wait_until()
-{SELFPARAM();
+float bot_cmd_wait_until(entity this)
+{
if(time < bot_cmd.bot_cmd_parm_float + bot_barriertime)
{
- self.bot_exec_status |= BOT_EXEC_STATUS_WAITING;
+ this.bot_exec_status |= BOT_EXEC_STATUS_WAITING;
return CMD_STATUS_EXECUTING;
}
- self.bot_exec_status &= ~BOT_EXEC_STATUS_WAITING;
+ this.bot_exec_status &= ~BOT_EXEC_STATUS_WAITING;
return CMD_STATUS_FINISHED;
}
-float bot_cmd_barrier()
-{SELFPARAM();
+float bot_cmd_barrier(entity this)
+{
// 0 = no barrier, 1 = waiting, 2 = waiting finished
- if(self.bot_barrier == 0) // initialization
+ if(this.bot_barrier == 0) // initialization
{
- self.bot_barrier = 1;
+ this.bot_barrier = 1;
- //self.colormod = '4 4 0';
+ //this.colormod = '4 4 0';
}
- if(self.bot_barrier == 1) // find other bots
+ if(this.bot_barrier == 1) // find other bots
{
FOREACH_CLIENT(it.isbot, LAMBDA(
if(it.bot_cmdqueuebuf_allocated)
// if we get here, the barrier is finished
// so end it...
- self.bot_barrier = 0;
- //self.colormod = '0 0 0';
+ this.bot_barrier = 0;
+ //this.colormod = '0 0 0';
return CMD_STATUS_FINISHED;
}
-float bot_cmd_turn()
-{SELFPARAM();
- self.v_angle_y = self.v_angle.y + bot_cmd.bot_cmd_parm_float;
- self.v_angle_y = self.v_angle.y - floor(self.v_angle.y / 360) * 360;
+float bot_cmd_turn(entity this)
+{
+ this.v_angle_y = this.v_angle.y + bot_cmd.bot_cmd_parm_float;
+ this.v_angle_y = this.v_angle.y - floor(this.v_angle.y / 360) * 360;
return CMD_STATUS_FINISHED;
}
-float bot_cmd_select_weapon()
-{SELFPARAM();
+float bot_cmd_select_weapon(entity this)
+{
float id = bot_cmd.bot_cmd_parm_float;
if(id < WEP_FIRST || id > WEP_LAST)
return CMD_STATUS_ERROR;
- if(client_hasweapon(self, Weapons_from(id), true, false))
- PS(self).m_switchweapon = Weapons_from(id);
+ if(client_hasweapon(this, Weapons_from(id), true, false))
+ PS(this).m_switchweapon = Weapons_from(id);
else
return CMD_STATUS_ERROR;
const int CMD_CONDITION_true_BLOCK = 4;
const int CMD_CONDITION_false_BLOCK = 8;
-float bot_cmd_eval(string expr)
-{SELFPARAM();
+float bot_cmd_eval(entity this, string expr)
+{
// Search for numbers
if(strstrofs("0123456789", substring(expr, 0, 1), 0) >= 0)
{
switch(expr)
{
case "health":
- return self.health;
+ return this.health;
case "speed":
- return vlen(self.velocity);
+ return vlen(this.velocity);
case "flagcarrier":
- return ((self.flagcarried!=world));
+ return ((this.flagcarried!=world));
}
LOG_INFO(strcat("ERROR: Unable to convert the expression '",expr,"' into a numeric value\n"));
return 0;
}
-float bot_cmd_if()
-{SELFPARAM();
+float bot_cmd_if(entity this)
+{
string expr, val_a, val_b;
float cmpofs;
- if(self.bot_cmd_condition_status != CMD_CONDITION_NONE)
+ if(this.bot_cmd_condition_status != CMD_CONDITION_NONE)
{
// Only one "if" block is allowed at time
LOG_INFO("ERROR: Only one conditional block can be processed at time");
- bot_clearqueue(self);
+ bot_clearqueue(this);
return CMD_STATUS_ERROR;
}
- self.bot_cmd_condition_status |= CMD_CONDITION_true_BLOCK;
+ this.bot_cmd_condition_status |= CMD_CONDITION_true_BLOCK;
// search for operators
expr = bot_cmd.bot_cmd_parm_string;
val_a = substring(expr,0,cmpofs);
val_b = substring(expr,cmpofs+1,strlen(expr));
- if(bot_cmd_eval(val_a)==bot_cmd_eval(val_b))
- self.bot_cmd_condition_status |= CMD_CONDITION_true;
+ if(bot_cmd_eval(this, val_a)==bot_cmd_eval(this, val_b))
+ this.bot_cmd_condition_status |= CMD_CONDITION_true;
else
- self.bot_cmd_condition_status |= CMD_CONDITION_false;
+ this.bot_cmd_condition_status |= CMD_CONDITION_false;
return CMD_STATUS_FINISHED;
}
val_a = substring(expr,0,cmpofs);
val_b = substring(expr,cmpofs+1,strlen(expr));
- if(bot_cmd_eval(val_a)>bot_cmd_eval(val_b))
- self.bot_cmd_condition_status |= CMD_CONDITION_true;
+ if(bot_cmd_eval(this, val_a)>bot_cmd_eval(this, val_b))
+ this.bot_cmd_condition_status |= CMD_CONDITION_true;
else
- self.bot_cmd_condition_status |= CMD_CONDITION_false;
+ this.bot_cmd_condition_status |= CMD_CONDITION_false;
return CMD_STATUS_FINISHED;
}
val_a = substring(expr,0,cmpofs);
val_b = substring(expr,cmpofs+1,strlen(expr));
- if(bot_cmd_eval(val_a)<bot_cmd_eval(val_b))
- self.bot_cmd_condition_status |= CMD_CONDITION_true;
+ if(bot_cmd_eval(this, val_a)<bot_cmd_eval(this, val_b))
+ this.bot_cmd_condition_status |= CMD_CONDITION_true;
else
- self.bot_cmd_condition_status |= CMD_CONDITION_false;
+ this.bot_cmd_condition_status |= CMD_CONDITION_false;
return CMD_STATUS_FINISHED;
}
- if(bot_cmd_eval(expr))
- self.bot_cmd_condition_status |= CMD_CONDITION_true;
+ if(bot_cmd_eval(this, expr))
+ this.bot_cmd_condition_status |= CMD_CONDITION_true;
else
- self.bot_cmd_condition_status |= CMD_CONDITION_false;
+ this.bot_cmd_condition_status |= CMD_CONDITION_false;
return CMD_STATUS_FINISHED;
}
-float bot_cmd_else()
-{SELFPARAM();
- self.bot_cmd_condition_status &= ~CMD_CONDITION_true_BLOCK;
- self.bot_cmd_condition_status |= CMD_CONDITION_false_BLOCK;
+float bot_cmd_else(entity this)
+{
+ this.bot_cmd_condition_status &= ~CMD_CONDITION_true_BLOCK;
+ this.bot_cmd_condition_status |= CMD_CONDITION_false_BLOCK;
return CMD_STATUS_FINISHED;
}
-float bot_cmd_fi()
-{SELFPARAM();
- self.bot_cmd_condition_status = CMD_CONDITION_NONE;
+float bot_cmd_fi(entity this)
+{
+ this.bot_cmd_condition_status = CMD_CONDITION_NONE;
return CMD_STATUS_FINISHED;
}
-float bot_cmd_resetaim()
-{SELFPARAM();
- self.v_angle = '0 0 0';
+float bot_cmd_resetaim(entity this)
+{
+ this.v_angle = '0 0 0';
return CMD_STATUS_FINISHED;
}
.vector bot_cmd_aim_begin;
.vector bot_cmd_aim_end;
-float bot_cmd_aim()
-{SELFPARAM();
+float bot_cmd_aim(entity this)
+{
// Current direction
- if(self.bot_cmd_aim_endtime)
+ if(this.bot_cmd_aim_endtime)
{
float progress;
- progress = min(1 - (self.bot_cmd_aim_endtime - time) / (self.bot_cmd_aim_endtime - self.bot_cmd_aim_begintime),1);
- self.v_angle = self.bot_cmd_aim_begin + ((self.bot_cmd_aim_end - self.bot_cmd_aim_begin) * progress);
+ progress = min(1 - (this.bot_cmd_aim_endtime - time) / (this.bot_cmd_aim_endtime - this.bot_cmd_aim_begintime),1);
+ this.v_angle = this.bot_cmd_aim_begin + ((this.bot_cmd_aim_end - this.bot_cmd_aim_begin) * progress);
- if(time>=self.bot_cmd_aim_endtime)
+ if(time>=this.bot_cmd_aim_endtime)
{
- self.bot_cmd_aim_endtime = 0;
+ this.bot_cmd_aim_endtime = 0;
return CMD_STATUS_FINISHED;
}
else
if(step == 0)
{
- self.v_angle_x -= stof(argv(1));
- self.v_angle_y += stof(argv(0));
+ this.v_angle_x -= stof(argv(1));
+ this.v_angle_y += stof(argv(0));
return CMD_STATUS_FINISHED;
}
- self.bot_cmd_aim_begin = self.v_angle;
+ this.bot_cmd_aim_begin = this.v_angle;
- self.bot_cmd_aim_end_x = self.v_angle.x - stof(argv(1));
- self.bot_cmd_aim_end_y = self.v_angle.y + stof(argv(0));
- self.bot_cmd_aim_end_z = 0;
+ this.bot_cmd_aim_end_x = this.v_angle.x - stof(argv(1));
+ this.bot_cmd_aim_end_y = this.v_angle.y + stof(argv(0));
+ this.bot_cmd_aim_end_z = 0;
- self.bot_cmd_aim_begintime = time;
- self.bot_cmd_aim_endtime = time + step;
+ this.bot_cmd_aim_begintime = time;
+ this.bot_cmd_aim_endtime = time + step;
return CMD_STATUS_EXECUTING;
}
-float bot_cmd_aimtarget()
-{SELFPARAM();
- if(self.bot_cmd_aim_endtime)
+float bot_cmd_aimtarget(entity this)
+{
+ if(this.bot_cmd_aim_endtime)
{
- return bot_cmd_aim();
+ return bot_cmd_aim(this);
}
entity e;
tokens = tokenizebyseparator(parms, " ");
- e = bot_getplace(argv(0));
+ e = bot_getplace(this, argv(0));
if(!e)
return CMD_STATUS_ERROR;
if(tokens==1)
{
- self.v_angle = vectoangles(v - (self.origin + self.view_ofs));
- self.v_angle_x = -self.v_angle.x;
+ this.v_angle = vectoangles(v - (this.origin + this.view_ofs));
+ this.v_angle_x = -this.v_angle.x;
return CMD_STATUS_FINISHED;
}
step = stof(argv(1));
- self.bot_cmd_aim_begin = self.v_angle;
- self.bot_cmd_aim_end = vectoangles(v - (self.origin + self.view_ofs));
- self.bot_cmd_aim_end_x = -self.bot_cmd_aim_end.x;
+ this.bot_cmd_aim_begin = this.v_angle;
+ this.bot_cmd_aim_end = vectoangles(v - (this.origin + this.view_ofs));
+ this.bot_cmd_aim_end_x = -this.bot_cmd_aim_end.x;
- self.bot_cmd_aim_begintime = time;
- self.bot_cmd_aim_endtime = time + step;
+ this.bot_cmd_aim_begintime = time;
+ this.bot_cmd_aim_endtime = time + step;
return CMD_STATUS_EXECUTING;
}
const int BOT_CMD_KEY_CROUCH = BIT(9);
const int BOT_CMD_KEY_CHAT = BIT(10);
-float bot_presskeys()
-{SELFPARAM();
- self.movement = '0 0 0';
- PHYS_INPUT_BUTTON_JUMP(self) = false;
- PHYS_INPUT_BUTTON_CROUCH(self) = false;
- PHYS_INPUT_BUTTON_ATCK(self) = false;
- PHYS_INPUT_BUTTON_ATCK2(self) = false;
- PHYS_INPUT_BUTTON_USE(self) = false;
- PHYS_INPUT_BUTTON_HOOK(self) = false;
- PHYS_INPUT_BUTTON_CHAT(self) = false;
-
- if(self.bot_cmd_keys == BOT_CMD_KEY_NONE)
+bool bot_presskeys(entity this)
+{
+ this.movement = '0 0 0';
+ PHYS_INPUT_BUTTON_JUMP(this) = false;
+ PHYS_INPUT_BUTTON_CROUCH(this) = false;
+ PHYS_INPUT_BUTTON_ATCK(this) = false;
+ PHYS_INPUT_BUTTON_ATCK2(this) = false;
+ PHYS_INPUT_BUTTON_USE(this) = false;
+ PHYS_INPUT_BUTTON_HOOK(this) = false;
+ PHYS_INPUT_BUTTON_CHAT(this) = false;
+
+ if(this.bot_cmd_keys == BOT_CMD_KEY_NONE)
return false;
- if(self.bot_cmd_keys & BOT_CMD_KEY_FORWARD)
- self.movement_x = autocvar_sv_maxspeed;
- else if(self.bot_cmd_keys & BOT_CMD_KEY_BACKWARD)
- self.movement_x = -autocvar_sv_maxspeed;
+ if(this.bot_cmd_keys & BOT_CMD_KEY_FORWARD)
+ this.movement_x = autocvar_sv_maxspeed;
+ else if(this.bot_cmd_keys & BOT_CMD_KEY_BACKWARD)
+ this.movement_x = -autocvar_sv_maxspeed;
- if(self.bot_cmd_keys & BOT_CMD_KEY_RIGHT)
- self.movement_y = autocvar_sv_maxspeed;
- else if(self.bot_cmd_keys & BOT_CMD_KEY_LEFT)
- self.movement_y = -autocvar_sv_maxspeed;
+ if(this.bot_cmd_keys & BOT_CMD_KEY_RIGHT)
+ this.movement_y = autocvar_sv_maxspeed;
+ else if(this.bot_cmd_keys & BOT_CMD_KEY_LEFT)
+ this.movement_y = -autocvar_sv_maxspeed;
- if(self.bot_cmd_keys & BOT_CMD_KEY_JUMP)
- PHYS_INPUT_BUTTON_JUMP(self) = true;
+ if(this.bot_cmd_keys & BOT_CMD_KEY_JUMP)
+ PHYS_INPUT_BUTTON_JUMP(this) = true;
- if(self.bot_cmd_keys & BOT_CMD_KEY_CROUCH)
- PHYS_INPUT_BUTTON_CROUCH(self) = true;
+ if(this.bot_cmd_keys & BOT_CMD_KEY_CROUCH)
+ PHYS_INPUT_BUTTON_CROUCH(this) = true;
- if(self.bot_cmd_keys & BOT_CMD_KEY_ATTACK1)
- PHYS_INPUT_BUTTON_ATCK(self) = true;
+ if(this.bot_cmd_keys & BOT_CMD_KEY_ATTACK1)
+ PHYS_INPUT_BUTTON_ATCK(this) = true;
- if(self.bot_cmd_keys & BOT_CMD_KEY_ATTACK2)
- PHYS_INPUT_BUTTON_ATCK2(self) = true;
+ if(this.bot_cmd_keys & BOT_CMD_KEY_ATTACK2)
+ PHYS_INPUT_BUTTON_ATCK2(this) = true;
- if(self.bot_cmd_keys & BOT_CMD_KEY_USE)
- PHYS_INPUT_BUTTON_USE(self) = true;
+ if(this.bot_cmd_keys & BOT_CMD_KEY_USE)
+ PHYS_INPUT_BUTTON_USE(this) = true;
- if(self.bot_cmd_keys & BOT_CMD_KEY_HOOK)
- PHYS_INPUT_BUTTON_HOOK(self) = true;
+ if(this.bot_cmd_keys & BOT_CMD_KEY_HOOK)
+ PHYS_INPUT_BUTTON_HOOK(this) = true;
- if(self.bot_cmd_keys & BOT_CMD_KEY_CHAT)
- PHYS_INPUT_BUTTON_CHAT(self) = true;
+ if(this.bot_cmd_keys & BOT_CMD_KEY_CHAT)
+ PHYS_INPUT_BUTTON_CHAT(this) = true;
return true;
}
-float bot_cmd_keypress_handler(string key, float enabled)
-{SELFPARAM();
+float bot_cmd_keypress_handler(entity this, string key, float enabled)
+{
switch(key)
{
case "all":
if(enabled)
- self.bot_cmd_keys = power2of(20) - 1; // >:)
+ this.bot_cmd_keys = power2of(20) - 1; // >:)
else
- self.bot_cmd_keys = BOT_CMD_KEY_NONE;
+ this.bot_cmd_keys = BOT_CMD_KEY_NONE;
case "forward":
if(enabled)
{
- self.bot_cmd_keys |= BOT_CMD_KEY_FORWARD;
- self.bot_cmd_keys &= ~BOT_CMD_KEY_BACKWARD;
+ this.bot_cmd_keys |= BOT_CMD_KEY_FORWARD;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_BACKWARD;
}
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_FORWARD;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_FORWARD;
break;
case "backward":
if(enabled)
{
- self.bot_cmd_keys |= BOT_CMD_KEY_BACKWARD;
- self.bot_cmd_keys &= ~BOT_CMD_KEY_FORWARD;
+ this.bot_cmd_keys |= BOT_CMD_KEY_BACKWARD;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_FORWARD;
}
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_BACKWARD;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_BACKWARD;
break;
case "left":
if(enabled)
{
- self.bot_cmd_keys |= BOT_CMD_KEY_LEFT;
- self.bot_cmd_keys &= ~BOT_CMD_KEY_RIGHT;
+ this.bot_cmd_keys |= BOT_CMD_KEY_LEFT;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_RIGHT;
}
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_LEFT;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_LEFT;
break;
case "right":
if(enabled)
{
- self.bot_cmd_keys |= BOT_CMD_KEY_RIGHT;
- self.bot_cmd_keys &= ~BOT_CMD_KEY_LEFT;
+ this.bot_cmd_keys |= BOT_CMD_KEY_RIGHT;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_LEFT;
}
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_RIGHT;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_RIGHT;
break;
case "jump":
if(enabled)
- self.bot_cmd_keys |= BOT_CMD_KEY_JUMP;
+ this.bot_cmd_keys |= BOT_CMD_KEY_JUMP;
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_JUMP;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_JUMP;
break;
case "crouch":
if(enabled)
- self.bot_cmd_keys |= BOT_CMD_KEY_CROUCH;
+ this.bot_cmd_keys |= BOT_CMD_KEY_CROUCH;
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_CROUCH;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_CROUCH;
break;
case "attack1":
if(enabled)
- self.bot_cmd_keys |= BOT_CMD_KEY_ATTACK1;
+ this.bot_cmd_keys |= BOT_CMD_KEY_ATTACK1;
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_ATTACK1;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_ATTACK1;
break;
case "attack2":
if(enabled)
- self.bot_cmd_keys |= BOT_CMD_KEY_ATTACK2;
+ this.bot_cmd_keys |= BOT_CMD_KEY_ATTACK2;
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_ATTACK2;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_ATTACK2;
break;
case "use":
if(enabled)
- self.bot_cmd_keys |= BOT_CMD_KEY_USE;
+ this.bot_cmd_keys |= BOT_CMD_KEY_USE;
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_USE;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_USE;
break;
case "hook":
if(enabled)
- self.bot_cmd_keys |= BOT_CMD_KEY_HOOK;
+ this.bot_cmd_keys |= BOT_CMD_KEY_HOOK;
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_HOOK;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_HOOK;
break;
case "chat":
if(enabled)
- self.bot_cmd_keys |= BOT_CMD_KEY_CHAT;
+ this.bot_cmd_keys |= BOT_CMD_KEY_CHAT;
else
- self.bot_cmd_keys &= ~BOT_CMD_KEY_CHAT;
+ this.bot_cmd_keys &= ~BOT_CMD_KEY_CHAT;
break;
default:
break;
return CMD_STATUS_FINISHED;
}
-float bot_cmd_presskey()
+float bot_cmd_presskey(entity this)
{
string key;
key = bot_cmd.bot_cmd_parm_string;
- bot_cmd_keypress_handler(key,true);
+ bot_cmd_keypress_handler(this, key,true);
return CMD_STATUS_FINISHED;
}
-float bot_cmd_releasekey()
+float bot_cmd_releasekey(entity this)
{
string key;
key = bot_cmd.bot_cmd_parm_string;
- return bot_cmd_keypress_handler(key,false);
+ return bot_cmd_keypress_handler(this, key,false);
}
-float bot_cmd_pause()
-{SELFPARAM();
- PHYS_INPUT_BUTTON_DRAG(self) = false;
- PHYS_INPUT_BUTTON_USE(self) = false;
- PHYS_INPUT_BUTTON_ATCK(self) = false;
- PHYS_INPUT_BUTTON_JUMP(self) = false;
- PHYS_INPUT_BUTTON_HOOK(self) = false;
- PHYS_INPUT_BUTTON_CHAT(self) = false;
- PHYS_INPUT_BUTTON_ATCK2(self) = false;
- PHYS_INPUT_BUTTON_CROUCH(self) = false;
-
- self.movement = '0 0 0';
- self.bot_cmd_keys = BOT_CMD_KEY_NONE;
-
- self.bot_exec_status |= BOT_EXEC_STATUS_PAUSED;
+float bot_cmd_pause(entity this)
+{
+ PHYS_INPUT_BUTTON_DRAG(this) = false;
+ PHYS_INPUT_BUTTON_USE(this) = false;
+ PHYS_INPUT_BUTTON_ATCK(this) = false;
+ PHYS_INPUT_BUTTON_JUMP(this) = false;
+ PHYS_INPUT_BUTTON_HOOK(this) = false;
+ PHYS_INPUT_BUTTON_CHAT(this) = false;
+ PHYS_INPUT_BUTTON_ATCK2(this) = false;
+ PHYS_INPUT_BUTTON_CROUCH(this) = false;
+
+ this.movement = '0 0 0';
+ this.bot_cmd_keys = BOT_CMD_KEY_NONE;
+
+ this.bot_exec_status |= BOT_EXEC_STATUS_PAUSED;
return CMD_STATUS_FINISHED;
}
-float bot_cmd_moveto()
-{SELFPARAM();
- return self.cmd_moveto(bot_cmd.bot_cmd_parm_vector);
+float bot_cmd_moveto(entity this)
+{
+ return this.cmd_moveto(this, bot_cmd.bot_cmd_parm_vector);
}
-float bot_cmd_movetotarget()
-{SELFPARAM();
+float bot_cmd_movetotarget(entity this)
+{
entity e;
- e = bot_getplace(bot_cmd.bot_cmd_parm_string);
+ e = bot_getplace(this, bot_cmd.bot_cmd_parm_string);
if(!e)
return CMD_STATUS_ERROR;
- return self.cmd_moveto(e.origin + (e.mins + e.maxs) * 0.5);
+ return this.cmd_moveto(this, e.origin + (e.mins + e.maxs) * 0.5);
}
-float bot_cmd_resetgoal()
-{SELFPARAM();
- return self.cmd_resetgoal();
+float bot_cmd_resetgoal(entity this)
+{
+ return this.cmd_resetgoal(this);
}
-float bot_cmd_sound()
-{SELFPARAM();
+float bot_cmd_sound(entity this)
+{
string f;
f = bot_cmd.bot_cmd_parm_string;
atten = stof(argv(2));
precache_sound(f);
- _sound(self, chan, sample, vol, atten);
+ _sound(this, chan, sample, vol, atten);
return CMD_STATUS_FINISHED;
}
.entity tuba_note;
-float bot_cmd_debug_assert_canfire()
-{SELFPARAM();
+float bot_cmd_debug_assert_canfire(entity this)
+{
float f = bot_cmd.bot_cmd_parm_float;
int slot = 0;
.entity weaponentity = weaponentities[slot];
- if(self.(weaponentity).state != WS_READY)
+ if(this.(weaponentity).state != WS_READY)
{
if(f)
{
- self.colormod = '0 8 8';
- LOG_INFO("Bot ", self.netname, " using ", self.weaponname, " wants to fire, inhibited by weaponentity state\n");
+ this.colormod = '0 8 8';
+ LOG_INFO("Bot ", this.netname, " using ", this.weaponname, " wants to fire, inhibited by weaponentity state\n");
}
}
- else if(ATTACK_FINISHED(self, slot) > time)
+ else if(ATTACK_FINISHED(this, slot) > time)
{
if(f)
{
- self.colormod = '8 0 8';
- LOG_INFO("Bot ", self.netname, " using ", self.weaponname, " wants to fire, inhibited by ATTACK_FINISHED (", ftos(ATTACK_FINISHED(self, slot) - time), " seconds left)\n");
+ this.colormod = '8 0 8';
+ LOG_INFO("Bot ", this.netname, " using ", this.weaponname, " wants to fire, inhibited by ATTACK_FINISHED (", ftos(ATTACK_FINISHED(this, slot) - time), " seconds left)\n");
}
}
- else if(self.tuba_note)
+ else if(this.tuba_note)
{
if(f)
{
- self.colormod = '8 0 0';
- LOG_INFO("Bot ", self.netname, " using ", self.weaponname, " wants to fire, bot still has an active tuba note\n");
+ this.colormod = '8 0 0';
+ LOG_INFO("Bot ", this.netname, " using ", this.weaponname, " wants to fire, bot still has an active tuba note\n");
}
}
else
{
if(!f)
{
- self.colormod = '8 8 0';
- LOG_INFO("Bot ", self.netname, " using ", self.weaponname, " thinks it has fired, but apparently did not; ATTACK_FINISHED says ", ftos(ATTACK_FINISHED(self, slot) - time), " seconds left\n");
+ this.colormod = '8 8 0';
+ LOG_INFO("Bot ", this.netname, " using ", this.weaponname, " thinks it has fired, but apparently did not; ATTACK_FINISHED says ", ftos(ATTACK_FINISHED(this, slot) - time), " seconds left\n");
}
}
//
-void bot_command_executed(float rm)
-{SELFPARAM();
+void bot_command_executed(entity this, bool rm)
+{
entity cmd;
cmd = bot_cmd;
if(rm)
- bot_dequeuecommand(self, self.bot_cmd_execution_index);
+ bot_dequeuecommand(this, this.bot_cmd_execution_index);
- self.bot_cmd_execution_index++;
+ this.bot_cmd_execution_index++;
}
-void bot_setcurrentcommand()
-{SELFPARAM();
+void bot_setcurrentcommand(entity this)
+{
bot_cmd = world;
- if(!self.bot_cmd_current)
+ if(!this.bot_cmd_current)
{
- self.bot_cmd_current = new_pure(bot_cmd);
- self.bot_cmd_current.is_bot_cmd = true;
+ this.bot_cmd_current = new_pure(bot_cmd);
+ this.bot_cmd_current.is_bot_cmd = true;
}
- bot_cmd = self.bot_cmd_current;
- if(bot_cmd.bot_cmd_index != self.bot_cmd_execution_index || self.bot_cmd_execution_index == 0)
+ bot_cmd = this.bot_cmd_current;
+ if(bot_cmd.bot_cmd_index != this.bot_cmd_execution_index || this.bot_cmd_execution_index == 0)
{
- if(bot_havecommand(self, self.bot_cmd_execution_index))
+ if(bot_havecommand(this, this.bot_cmd_execution_index))
{
string cmdstring;
- cmdstring = bot_readcommand(self, self.bot_cmd_execution_index);
+ cmdstring = bot_readcommand(this, this.bot_cmd_execution_index);
if(bot_decodecommand(cmdstring))
{
- bot_cmd.owner = self;
- bot_cmd.bot_cmd_index = self.bot_cmd_execution_index;
+ bot_cmd.owner = this;
+ bot_cmd.bot_cmd_index = this.bot_cmd_execution_index;
}
else
{
// Invalid command, remove from queue
bot_cmd = world;
- bot_dequeuecommand(self, self.bot_cmd_execution_index);
- self.bot_cmd_execution_index++;
+ bot_dequeuecommand(this, this.bot_cmd_execution_index);
+ this.bot_cmd_execution_index++;
}
}
else
// Here we map commands to functions and deal with complex interactions between commands and execution states
// NOTE: Of course you need to include your commands here too :)
-float bot_execute_commands_once()
-{SELFPARAM();
+float bot_execute_commands_once(entity this)
+{
float status, ispressingkey;
// Find command
- bot_setcurrentcommand();
+ bot_setcurrentcommand(this);
// if we have no bot command, better return
// old logic kept pressing previously pressed keys, but that has problems
return false;
// Ignore all commands except continue when the bot is paused
- if(self.bot_exec_status & BOT_EXEC_STATUS_PAUSED)
+ if(this.bot_exec_status & BOT_EXEC_STATUS_PAUSED)
if(bot_cmd.bot_cmd_type!=BOT_CMD_CONTINUE)
{
if(bot_cmd.bot_cmd_type!=BOT_CMD_NULL)
{
- bot_command_executed(true);
+ bot_command_executed(this, true);
LOG_INFO( "WARNING: Commands are ignored while the bot is paused. Use the command 'continue' instead.\n");
}
return 1;
}
// Keep pressing keys raised by the "presskey" command
- ispressingkey = boolean(bot_presskeys());
+ ispressingkey = boolean(bot_presskeys(this));
// Handle conditions
if (!(bot_cmd.bot_cmd_type==BOT_CMD_FI||bot_cmd.bot_cmd_type==BOT_CMD_ELSE))
- if(self.bot_cmd_condition_status & CMD_CONDITION_true && self.bot_cmd_condition_status & CMD_CONDITION_false_BLOCK)
+ if(this.bot_cmd_condition_status & CMD_CONDITION_true && this.bot_cmd_condition_status & CMD_CONDITION_false_BLOCK)
{
- bot_command_executed(true);
+ bot_command_executed(this, true);
return -1;
}
- else if(self.bot_cmd_condition_status & CMD_CONDITION_false && self.bot_cmd_condition_status & CMD_CONDITION_true_BLOCK)
+ else if(this.bot_cmd_condition_status & CMD_CONDITION_false && this.bot_cmd_condition_status & CMD_CONDITION_true_BLOCK)
{
- bot_command_executed(true);
+ bot_command_executed(this, true);
return -1;
}
return ispressingkey;
//break;
case BOT_CMD_PAUSE:
- status = bot_cmd_pause();
+ status = bot_cmd_pause(this);
break;
case BOT_CMD_CONTINUE:
- status = bot_cmd_continue();
+ status = bot_cmd_continue(this);
break;
case BOT_CMD_WAIT:
- status = bot_cmd_wait();
+ status = bot_cmd_wait(this);
break;
case BOT_CMD_WAIT_UNTIL:
- status = bot_cmd_wait_until();
+ status = bot_cmd_wait_until(this);
break;
case BOT_CMD_TURN:
- status = bot_cmd_turn();
+ status = bot_cmd_turn(this);
break;
case BOT_CMD_MOVETO:
- status = bot_cmd_moveto();
+ status = bot_cmd_moveto(this);
break;
case BOT_CMD_MOVETOTARGET:
- status = bot_cmd_movetotarget();
+ status = bot_cmd_movetotarget(this);
break;
case BOT_CMD_RESETGOAL:
- status = bot_cmd_resetgoal();
+ status = bot_cmd_resetgoal(this);
break;
case BOT_CMD_CC:
- status = bot_cmd_cc();
+ status = bot_cmd_cc(this);
break;
case BOT_CMD_IF:
- status = bot_cmd_if();
+ status = bot_cmd_if(this);
break;
case BOT_CMD_ELSE:
- status = bot_cmd_else();
+ status = bot_cmd_else(this);
break;
case BOT_CMD_FI:
- status = bot_cmd_fi();
+ status = bot_cmd_fi(this);
break;
case BOT_CMD_RESETAIM:
- status = bot_cmd_resetaim();
+ status = bot_cmd_resetaim(this);
break;
case BOT_CMD_AIM:
- status = bot_cmd_aim();
+ status = bot_cmd_aim(this);
break;
case BOT_CMD_AIMTARGET:
- status = bot_cmd_aimtarget();
+ status = bot_cmd_aimtarget(this);
break;
case BOT_CMD_PRESSKEY:
- status = bot_cmd_presskey();
+ status = bot_cmd_presskey(this);
break;
case BOT_CMD_RELEASEKEY:
- status = bot_cmd_releasekey();
+ status = bot_cmd_releasekey(this);
break;
case BOT_CMD_SELECTWEAPON:
- status = bot_cmd_select_weapon();
+ status = bot_cmd_select_weapon(this);
break;
case BOT_CMD_IMPULSE:
- status = bot_cmd_impulse();
+ status = bot_cmd_impulse(this);
break;
case BOT_CMD_BARRIER:
- status = bot_cmd_barrier();
+ status = bot_cmd_barrier(this);
break;
case BOT_CMD_CONSOLE:
localcmd(strcat(bot_cmd.bot_cmd_parm_string, "\n"));
status = CMD_STATUS_FINISHED;
break;
case BOT_CMD_SOUND:
- status = bot_cmd_sound();
+ status = bot_cmd_sound(this);
break;
case BOT_CMD_DEBUG_ASSERT_CANFIRE:
- status = bot_cmd_debug_assert_canfire();
+ status = bot_cmd_debug_assert_canfire(this);
break;
default:
LOG_INFO(strcat("ERROR: Invalid command on queue with id '",ftos(bot_cmd.bot_cmd_type),"'\n"));
parms = "";
break;
}
- clientcommand(self,strcat("say ^7", bot_cmd_string[bot_cmd.bot_cmd_type]," ",parms,"\n"));
+ clientcommand(this,strcat("say ^7", bot_cmd_string[bot_cmd.bot_cmd_type]," ",parms,"\n"));
}
- bot_command_executed(true);
+ bot_command_executed(this, true);
}
if(status == CMD_STATUS_FINISHED)
}
// This function should be (the only) called directly from the bot ai loop
-float bot_execute_commands()
+int bot_execute_commands(entity this)
{
- float f;
+ int f;
do
{
- f = bot_execute_commands_once();
+ f = bot_execute_commands_once(this);
}
while(f < 0);
return f;
// NOTE: Following commands should be implemented on the bot ai
// If a new command should be handled by the target ai(s) please declare it here
-.float(vector) cmd_moveto;
-.float() cmd_resetgoal;
+.float(entity, vector) cmd_moveto;
+.float(entity) cmd_resetgoal;
//
const int BOT_CMD_PARAMETER_NONE = 0;
void bot_queuecommand(entity bot, string cmdstring);
void bot_cmdhelp(string scmd);
void bot_list_commands();
-float bot_execute_commands();
+float bot_execute_commands(entity this);
entity find_bot_by_name(string name);
entity find_bot_by_number(float number);
ev.z = bound(em1_z, ev.z, em2_z);
dv = ev - sv;
dv.z = 0;
- if (vlen(dv) >= 1050) // max search distance in XY
+ if(vdist(dv, >=, 1050)) // max search distance in XY
{
++relink_lengthculled;
continue;
// spawnfunc_waypoint map entity
spawnfunc(waypoint)
{
- setorigin(self, self.origin);
+ setorigin(this, this.origin);
// schedule a relink after other waypoints have had a chance to spawn
- waypoint_clearlinks(self);
- //waypoint_schedulerelink(self);
+ waypoint_clearlinks(this);
+ //waypoint_schedulerelink(this);
}
// remove a spawnfunc_waypoint, and schedule all neighbors to relink
waypoint_spawnforteleporter_boxes(e, e.absmin, e.absmax, destination, destination, timetaken);
}
-entity waypoint_spawnpersonal(vector position)
-{SELFPARAM();
+entity waypoint_spawnpersonal(entity this, vector position)
+{
entity w;
// drop the waypoint to a proper location:
w = waypoint_spawn(position, position, WAYPOINTFLAG_GENERATED | WAYPOINTFLAG_PERSONAL);
w.nearestwaypoint = world;
w.nearestwaypointtimeout = 0;
- w.owner = self;
+ w.owner = this;
waypoint_schedulerelink(w);
goto next;
}
}
-:next
+LABEL(next)
}
}
// d) The waypoint is a dead end. Dead end waypoints must be kept as
float waypoint_load_links();
entity waypoint_spawn(vector m1, vector m2, float f);
-entity waypoint_spawnpersonal(vector position);
+entity waypoint_spawnpersonal(entity this, vector position);
vector waypoint_fixorigin(vector position);
// arguments:
// effectname
effectnum = _particleeffectnum(argv(1));
- W_SetupShot(self, false, false, "", CH_WEAPON_A, 0);
+ W_SetupShot(self, false, false, SND_Null, CH_WEAPON_A, 0);
traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, self);
__trailparticles(self, effectnum, w_shotorg, trace_endpos);
DID_CHEAT();
// arguments:
// modelname mode
f = stof(argv(2));
- W_SetupShot(self, false, false, "", CH_WEAPON_A, 0);
+ W_SetupShot(self, false, false, SND_Null, CH_WEAPON_A, 0);
traceline(w_shotorg, w_shotorg + w_shotdir * 2048, MOVE_NORMAL, self);
if((trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) || trace_fraction == 1)
{
}
void ClientInit_misc()
{
+ SELFPARAM();
int channel = MSG_ONE;
WriteHeader(channel, ENT_CLIENT_INIT);
WriteByte(channel, g_nexball_meter_period * 32);
PutClientInServer();
}
-void play_countdown(float finished, string samp)
+void play_countdown(float finished, Sound samp)
{SELFPARAM();
+ TC(Sound, samp);
if(IS_REAL_CLIENT(self))
if(floor(finished - time - frametime) != floor(finished - time))
if(finished - time < 6)
- _sound (self, CH_INFO, samp, VOL_BASE, ATTEN_NORM);
+ sound (self, CH_INFO, samp, VOL_BASE, ATTEN_NORM);
}
void player_powerups ()
{
if (self.items & ITEM_Strength.m_itemid)
{
- play_countdown(self.strength_finished, SND(POWEROFF));
+ play_countdown(self.strength_finished, SND_POWEROFF);
self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
if (time > self.strength_finished)
{
}
if (self.items & ITEM_Shield.m_itemid)
{
- play_countdown(self.invincible_finished, SND(POWEROFF));
+ play_countdown(self.invincible_finished, SND_POWEROFF);
self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
if (time > self.invincible_finished)
{
}
else
{
- play_countdown(self.superweapons_finished, SND(POWEROFF));
+ play_countdown(self.superweapons_finished, SND_POWEROFF);
if (time > self.superweapons_finished)
{
self.items = self.items - (self.items & IT_SUPERWEAPON);
void SpectateCopy(entity this, entity spectatee)
{
+ TC(Client, this); TC(Client, spectatee);
+
MUTATOR_CALLHOOK(SpectateCopy, spectatee, this);
PS(this) = PS(spectatee);
this.armortype = spectatee.armortype;
setsize(this, spectatee.mins, spectatee.maxs);
SetZoomState(spectatee.zoomstate);
- anticheat_spectatecopy(spectatee);
+ anticheat_spectatecopy(this, spectatee);
this.hud = spectatee.hud;
if(spectatee.vehicle)
{
if(frametime)
{
// physics frames: update anticheat stuff
- anticheat_prethink();
+ anticheat_prethink(self);
}
if(blockSpectators && frametime)
float c1, c2, c3, c4;
-void play_countdown(float finished, string samp);
+void play_countdown(float finished, Sound samp);
float CalcRotRegen(float current, float regenstable, float regenfactor, float regenlinear, float regenframetime, float rotstable, float rotfactor, float rotlinear, float rotframetime, float limit);
e.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
}
entity e2 = navigation_findnearestwaypoint(this, false);
- navigation_markroutes(e2);
+ navigation_markroutes(this, e2);
int i, m;
ATTRIB(servercommand_##id, m_description, string, description); \
ENDCLASS(servercommand_##id) \
REGISTER(SERVER_COMMANDS, CMD_SV, id, m_id, NEW(servercommand_##id)); \
- METHOD(servercommand_##id, m_invokecmd, void(int request, entity caller, int arguments, string command))
+ METHOD(servercommand_##id, m_invokecmd, void(servercommand_##id this, int request, entity caller, int arguments, string command))
STATIC_INIT(SERVER_COMMANDS_aliases) {
FOREACH(SERVER_COMMANDS, true, LAMBDA(localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_sv"))));
void CommonCommand_editmob(int request, entity caller, int argc)
{
- SELFPARAM();
switch (request)
{
case CMD_REQUEST_COMMAND:
ATTRIB(commoncommand_##id, m_description, string, description); \
ENDCLASS(commoncommand_##id) \
REGISTER(COMMON_COMMANDS, CMD_SV, id, m_id, NEW(commoncommand_##id)); \
- METHOD(commoncommand_##id, m_invokecmd, void(int request, entity caller, int arguments, string command))
+ METHOD(commoncommand_##id, m_invokecmd, void(commoncommand_##id this, int request, entity caller, int arguments, string command))
STATIC_INIT(COMMON_COMMANDS_aliases) {
FOREACH(COMMON_COMMANDS, true, LAMBDA(localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_svcmd"))));
{
string c = strtolower(argv(0));
FOREACH(COMMON_COMMANDS, it.m_name == c, LAMBDA(
- it.m_invokecmd(CMD_REQUEST_COMMAND, caller, argc, command);
+ it.m_invokecmd(it, CMD_REQUEST_COMMAND, caller, argc, command);
return true;
));
return false;
{
string c = strtolower(argv(1));
FOREACH(COMMON_COMMANDS, it.m_name == c, LAMBDA(
- it.m_invokecmd(CMD_REQUEST_USAGE, caller, argc, "");
+ it.m_invokecmd(it, CMD_REQUEST_USAGE, caller, argc, "");
return true;
));
return false;
void GameCommand_anticheat(float request, float argc)
{
- SELFPARAM();
switch (request)
{
case CMD_REQUEST_COMMAND:
if (accepted > 0)
{
- WITH(entity, self, client, anticheat_report());
+ anticheat_report(client);
return;
}
else
{
string c = strtolower(argv(0));
FOREACH(SERVER_COMMANDS, it.m_name == c, LAMBDA(
- it.m_invokecmd(CMD_REQUEST_COMMAND, NULL, argc, command);
+ it.m_invokecmd(it, CMD_REQUEST_COMMAND, NULL, argc, command);
return true;
));
return false;
{
string c = strtolower(argv(1));
FOREACH(SERVER_COMMANDS, it.m_name == c, LAMBDA(
- it.m_invokecmd(CMD_REQUEST_USAGE, NULL, argc, "");
+ it.m_invokecmd(it, CMD_REQUEST_USAGE, NULL, argc, "");
return true;
));
return false;
void PlayerUseKey();
-typedef vector(entity player, entity spot, vector current) spawn_evalfunc_t;
+USING(spawn_evalfunc_t, vector(entity player, entity spot, vector current));
.spawn_evalfunc_t spawn_evalfunc;
string modname;
void Unfreeze (entity targ)
{
+ SELFPARAM();
if(!STAT(FROZEN, targ))
return;
*/
void NextLevel()
{
+ SELFPARAM();
gameover = true;
intermission_running = 1;
LOG_INFO("Ban list syncing: accepted ban of ", ip, " by ", serverip, " at ", uri, ": ");
LOG_INFO(reason, "\n");
-:skip
+LABEL(skip)
}
}
goto killme;
return;
-:killme
+LABEL(killme)
remove(self);
}
ban_ip4 = strcat1(s); // 32
return true;
-:ipv6
+LABEL(ipv6)
i1 = strstrofs(s, ":", 0);
if(i1 < 0)
return false;
}
void precache()
-{SELFPARAM();
+{
// gamemode related things
// Precache all player models if desired
/** called when a bot checks a target to attack */
#define EV_BotShouldAttack(i, o) \
+ /**/ i(entity, __self) \
/**/ i(entity, checkentity) \
/**/
entity checkentity;
.int havocbot_role_flags;
.float havocbot_attack_time;
-.void() havocbot_role;
-.void() havocbot_previous_role;
+.void(entity this) havocbot_role;
+.void(entity this) havocbot_previous_role;
-void() havocbot_role_ast_defense;
-void() havocbot_role_ast_offense;
+void(entity this) havocbot_role_ast_defense;
+void(entity this) havocbot_role_ast_offense;
.entity havocbot_ast_target;
void(entity bot) havocbot_ast_reset_role;
-void(float ratingscale, vector org, float sradius) havocbot_goalrating_items;
-void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
+void(entity this, float ratingscale, vector org, float sradius) havocbot_goalrating_items;
+void(entity this, float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
// scoreboard stuff
const float ST_ASSAULT_OBJECTIVES = 1;
// they win. Otherwise the defending team wins once the timelimit passes.
int WinningCondition_Assault()
{
+ SELFPARAM();
WinningConditionHelper(); // set worldstatus
int status = WINNING_NO;
}
// legacy bot code
-void havocbot_goalrating_ast_targets(float ratingscale)
-{SELFPARAM();
+void havocbot_goalrating_ast_targets(entity this, float ratingscale)
+{
entity ad, best, wp, tod;
float radius, found, bestvalue;
vector p;
// te_lightning2(world, '0 0 0', best.origin);
// te_knightspike(best.origin);
- navigation_routerating(best, ratingscale, 4000);
+ navigation_routerating(this, best, ratingscale, 4000);
best.cnt += 1;
- self.havocbot_attack_time = 0;
+ this.havocbot_attack_time = 0;
- if(checkpvs(self.view_ofs,ad))
- if(checkpvs(self.view_ofs,best))
+ if(checkpvs(this.view_ofs,ad))
+ if(checkpvs(this.view_ofs,best))
{
// dprint("increasing attack time for this target\n");
- self.havocbot_attack_time = time + 2;
+ this.havocbot_attack_time = time + 2;
}
}
}
}
-void havocbot_role_ast_offense()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_ast_offense(entity this)
+{
+ if(IS_DEAD(this))
{
- self.havocbot_attack_time = 0;
- havocbot_ast_reset_role(self);
+ this.havocbot_attack_time = 0;
+ havocbot_ast_reset_role(this);
return;
}
// Set the role timeout if necessary
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + 120;
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + 120;
- if (time > self.havocbot_role_timeout)
+ if (time > this.havocbot_role_timeout)
{
- havocbot_ast_reset_role(self);
+ havocbot_ast_reset_role(this);
return;
}
- if(self.havocbot_attack_time>time)
+ if(this.havocbot_attack_time>time)
return;
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- navigation_goalrating_start();
- havocbot_goalrating_enemyplayers(20000, self.origin, 650);
- havocbot_goalrating_ast_targets(20000);
- havocbot_goalrating_items(15000, self.origin, 10000);
- navigation_goalrating_end();
+ navigation_goalrating_start(this);
+ havocbot_goalrating_enemyplayers(this, 20000, this.origin, 650);
+ havocbot_goalrating_ast_targets(this, 20000);
+ havocbot_goalrating_items(this, 15000, this.origin, 10000);
+ navigation_goalrating_end(this);
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
}
}
-void havocbot_role_ast_defense()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_ast_defense(entity this)
+{
+ if(IS_DEAD(this))
{
- self.havocbot_attack_time = 0;
- havocbot_ast_reset_role(self);
+ this.havocbot_attack_time = 0;
+ havocbot_ast_reset_role(this);
return;
}
// Set the role timeout if necessary
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + 120;
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + 120;
- if (time > self.havocbot_role_timeout)
+ if (time > this.havocbot_role_timeout)
{
- havocbot_ast_reset_role(self);
+ havocbot_ast_reset_role(this);
return;
}
- if(self.havocbot_attack_time>time)
+ if(this.havocbot_attack_time>time)
return;
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- navigation_goalrating_start();
- havocbot_goalrating_enemyplayers(20000, self.origin, 3000);
- havocbot_goalrating_ast_targets(20000);
- havocbot_goalrating_items(15000, self.origin, 10000);
- navigation_goalrating_end();
+ navigation_goalrating_start(this);
+ havocbot_goalrating_enemyplayers(this, 20000, this.origin, 3000);
+ havocbot_goalrating_ast_targets(this, 20000);
+ havocbot_goalrating_items(this, 15000, this.origin, 10000);
+ navigation_goalrating_end(this);
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
}
}
-void havocbot_role_ast_setrole(entity bot, float role)
+void havocbot_role_ast_setrole(entity this, float role)
{
switch(role)
{
case HAVOCBOT_AST_ROLE_DEFENSE:
- bot.havocbot_role = havocbot_role_ast_defense;
- bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_DEFENSE;
- bot.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_ast_defense;
+ this.havocbot_role_flags = HAVOCBOT_AST_ROLE_DEFENSE;
+ this.havocbot_role_timeout = 0;
break;
case HAVOCBOT_AST_ROLE_OFFENSE:
- bot.havocbot_role = havocbot_role_ast_offense;
- bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_OFFENSE;
- bot.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_ast_offense;
+ this.havocbot_role_flags = HAVOCBOT_AST_ROLE_OFFENSE;
+ this.havocbot_role_timeout = 0;
break;
}
}
-void havocbot_ast_reset_role(entity bot)
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_ast_reset_role(entity this)
+{
+ if(IS_DEAD(this))
return;
- if(bot.team == assault_attacker_team)
- havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_OFFENSE);
+ if(this.team == assault_attacker_team)
+ havocbot_role_ast_setrole(this, HAVOCBOT_AST_ROLE_OFFENSE);
else
- havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_DEFENSE);
+ havocbot_role_ast_setrole(this, HAVOCBOT_AST_ROLE_DEFENSE);
}
// mutator hooks
MUTATOR_HOOKFUNCTION(as, OnEntityPreSpawn)
{
+ SELFPARAM();
switch(self.classname)
{
case "info_player_team1":
MUTATOR_HOOKFUNCTION(ca, reset_map_players)
{
+ SELFPARAM();
FOREACH_CLIENT(true, {
it.killcount = 0;
if (!it.caplayer && IS_BOT_CLIENT(it))
.bool pushable;
void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
-{SELFPARAM();
+{
// declarations
setself(flag); // for later usage with droptofloor()
return c;
}
-void havocbot_goalrating_ctf_ourflag(float ratingscale)
-{SELFPARAM();
+void havocbot_goalrating_ctf_ourflag(entity this, float ratingscale)
+{
entity head;
head = ctf_worldflaglist;
while (head)
{
- if (CTF_SAMETEAM(self, head))
+ if (CTF_SAMETEAM(this, head))
break;
head = head.ctf_worldflagnext;
}
if (head)
- navigation_routerating(head, ratingscale, 10000);
+ navigation_routerating(this, head, ratingscale, 10000);
}
-void havocbot_goalrating_ctf_ourbase(float ratingscale)
-{SELFPARAM();
+void havocbot_goalrating_ctf_ourbase(entity this, float ratingscale)
+{
entity head;
head = ctf_worldflaglist;
while (head)
{
- if (CTF_SAMETEAM(self, head))
+ if (CTF_SAMETEAM(this, head))
break;
head = head.ctf_worldflagnext;
}
if (!head)
return;
- navigation_routerating(head.bot_basewaypoint, ratingscale, 10000);
+ navigation_routerating(this, head.bot_basewaypoint, ratingscale, 10000);
}
-void havocbot_goalrating_ctf_enemyflag(float ratingscale)
-{SELFPARAM();
+void havocbot_goalrating_ctf_enemyflag(entity this, float ratingscale)
+{
entity head;
head = ctf_worldflaglist;
while (head)
{
if(ctf_oneflag)
{
- if(CTF_DIFFTEAM(self, head))
+ if(CTF_DIFFTEAM(this, head))
{
if(head.team)
{
- if(self.flagcarried)
+ if(this.flagcarried)
break;
}
- else if(!self.flagcarried)
+ else if(!this.flagcarried)
break;
}
}
- else if(CTF_DIFFTEAM(self, head))
+ else if(CTF_DIFFTEAM(this, head))
break;
head = head.ctf_worldflagnext;
}
if (head)
- navigation_routerating(head, ratingscale, 10000);
+ navigation_routerating(this, head, ratingscale, 10000);
}
-void havocbot_goalrating_ctf_enemybase(float ratingscale)
-{SELFPARAM();
+void havocbot_goalrating_ctf_enemybase(entity this, float ratingscale)
+{
if (!bot_waypoints_for_items)
{
- havocbot_goalrating_ctf_enemyflag(ratingscale);
+ havocbot_goalrating_ctf_enemyflag(this, ratingscale);
return;
}
entity head;
- head = havocbot_ctf_find_enemy_flag(self);
+ head = havocbot_ctf_find_enemy_flag(this);
if (!head)
return;
- navigation_routerating(head.bot_basewaypoint, ratingscale, 10000);
+ navigation_routerating(this, head.bot_basewaypoint, ratingscale, 10000);
}
-void havocbot_goalrating_ctf_ourstolenflag(float ratingscale)
-{SELFPARAM();
+void havocbot_goalrating_ctf_ourstolenflag(entity this, float ratingscale)
+{
entity mf;
- mf = havocbot_ctf_find_flag(self);
+ mf = havocbot_ctf_find_flag(this);
if(mf.ctf_status == FLAG_BASE)
return;
if(mf.tag_entity)
- navigation_routerating(mf.tag_entity, ratingscale, 10000);
+ navigation_routerating(this, mf.tag_entity, ratingscale, 10000);
}
-void havocbot_goalrating_ctf_droppedflags(float ratingscale, vector org, float df_radius)
+void havocbot_goalrating_ctf_droppedflags(entity this, float ratingscale, vector org, float df_radius)
{
entity head;
head = ctf_worldflaglist;
if(df_radius)
{
if(vlen(org-head.origin)<df_radius)
- navigation_routerating(head, ratingscale, 10000);
+ navigation_routerating(self, head, ratingscale, 10000);
}
else
- navigation_routerating(head, ratingscale, 10000);
+ navigation_routerating(self, head, ratingscale, 10000);
}
head = head.ctf_worldflagnext;
}
}
-void havocbot_goalrating_ctf_carrieritems(float ratingscale, vector org, float sradius)
-{SELFPARAM();
+void havocbot_goalrating_ctf_carrieritems(entity this, float ratingscale, vector org, float sradius)
+{
entity head;
float t;
head = findchainfloat(bot_pickup, true);
if (vlen(head.origin - org) < sradius)
{
// get the value of the item
- t = head.bot_pickupevalfunc(self, head) * 0.0001;
+ t = head.bot_pickupevalfunc(this, head) * 0.0001;
if (t > 0)
- navigation_routerating(head, t * ratingscale, 500);
+ navigation_routerating(this, head, t * ratingscale, 500);
}
head = head.chain;
}
}
-void havocbot_ctf_reset_role(entity bot)
+void havocbot_ctf_reset_role(entity this)
{
float cdefense, cmiddle, coffense;
entity mf, ef;
float c;
- if(IS_DEAD(bot))
+ if(IS_DEAD(this))
return;
- if(vlen(havocbot_ctf_middlepoint)==0)
+ if(havocbot_ctf_middlepoint == '0 0 0')
havocbot_calculate_middlepoint();
// Check ctf flags
- if (bot.flagcarried)
+ if (this.flagcarried)
{
- havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_CARRIER);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_CARRIER);
return;
}
- mf = havocbot_ctf_find_flag(bot);
- ef = havocbot_ctf_find_enemy_flag(bot);
+ mf = havocbot_ctf_find_flag(this);
+ ef = havocbot_ctf_find_enemy_flag(this);
// Retrieve stolen flag
if(mf.ctf_status!=FLAG_BASE)
{
- havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_RETRIEVER);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_RETRIEVER);
return;
}
// If enemy flag is taken go to the middle to intercept pursuers
if(ef.ctf_status!=FLAG_BASE)
{
- havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_MIDDLE);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_MIDDLE);
return;
}
// if there is only me on the team switch to offense
c = 0;
- FOREACH_CLIENT(IS_PLAYER(it) && SAME_TEAM(it, bot), LAMBDA(++c));
+ FOREACH_CLIENT(IS_PLAYER(it) && SAME_TEAM(it, this), LAMBDA(++c));
if(c==1)
{
- havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_OFFENSE);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_OFFENSE);
return;
}
// Evaluate best position to take
// Count mates on middle position
- cmiddle = havocbot_ctf_teamcount(bot, havocbot_ctf_middlepoint, havocbot_ctf_middlepoint_radius * 0.5);
+ cmiddle = havocbot_ctf_teamcount(this, havocbot_ctf_middlepoint, havocbot_ctf_middlepoint_radius * 0.5);
// Count mates on defense position
- cdefense = havocbot_ctf_teamcount(bot, mf.dropped_origin, havocbot_ctf_middlepoint_radius * 0.5);
+ cdefense = havocbot_ctf_teamcount(this, mf.dropped_origin, havocbot_ctf_middlepoint_radius * 0.5);
// Count mates on offense position
- coffense = havocbot_ctf_teamcount(bot, ef.dropped_origin, havocbot_ctf_middlepoint_radius);
+ coffense = havocbot_ctf_teamcount(this, ef.dropped_origin, havocbot_ctf_middlepoint_radius);
if(cdefense<=coffense)
- havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_DEFENSE);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_DEFENSE);
else if(coffense<=cmiddle)
- havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_OFFENSE);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_OFFENSE);
else
- havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_MIDDLE);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_MIDDLE);
}
-void havocbot_role_ctf_carrier()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_ctf_carrier(entity this)
+{
+ if(IS_DEAD(this))
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.flagcarried == world)
+ if (this.flagcarried == world)
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
+ navigation_goalrating_start(this);
if(ctf_oneflag)
- havocbot_goalrating_ctf_enemybase(50000);
+ havocbot_goalrating_ctf_enemybase(this, 50000);
else
- havocbot_goalrating_ctf_ourbase(50000);
+ havocbot_goalrating_ctf_ourbase(this, 50000);
- if(self.health<100)
- havocbot_goalrating_ctf_carrieritems(1000, self.origin, 1000);
+ if(this.health<100)
+ havocbot_goalrating_ctf_carrieritems(this, 1000, this.origin, 1000);
- navigation_goalrating_end();
+ navigation_goalrating_end(this);
- if (self.navigation_hasgoals)
- self.havocbot_cantfindflag = time + 10;
- else if (time > self.havocbot_cantfindflag)
+ if (this.navigation_hasgoals)
+ this.havocbot_cantfindflag = time + 10;
+ else if (time > this.havocbot_cantfindflag)
{
// Can't navigate to my own base, suicide!
// TODO: drop it and wander around
- Damage(self, self, self, 100000, DEATH_KILL.m_id, self.origin, '0 0 0');
+ Damage(this, this, this, 100000, DEATH_KILL.m_id, this.origin, '0 0 0');
return;
}
}
}
-void havocbot_role_ctf_escort()
-{SELFPARAM();
+void havocbot_role_ctf_escort(entity this)
+{
entity mf, ef;
- if(IS_DEAD(self))
+ if(IS_DEAD(this))
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.flagcarried)
+ if (this.flagcarried)
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_CARRIER);
return;
}
// If enemy flag is back on the base switch to previous role
- ef = havocbot_ctf_find_enemy_flag(self);
+ ef = havocbot_ctf_find_enemy_flag(this);
if(ef.ctf_status==FLAG_BASE)
{
- self.havocbot_role = self.havocbot_previous_role;
- self.havocbot_role_timeout = 0;
+ this.havocbot_role = this.havocbot_previous_role;
+ this.havocbot_role_timeout = 0;
return;
}
// If the flag carrier reached the base switch to defense
- mf = havocbot_ctf_find_flag(self);
+ mf = havocbot_ctf_find_flag(this);
if(mf.ctf_status!=FLAG_BASE)
if(vlen(ef.origin - mf.dropped_origin) < 300)
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_DEFENSE);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_DEFENSE);
return;
}
// Set the role timeout if necessary
- if (!self.havocbot_role_timeout)
+ if (!this.havocbot_role_timeout)
{
- self.havocbot_role_timeout = time + random() * 30 + 60;
+ this.havocbot_role_timeout = time + random() * 30 + 60;
}
// If nothing happened just switch to previous role
- if (time > self.havocbot_role_timeout)
+ if (time > this.havocbot_role_timeout)
{
- self.havocbot_role = self.havocbot_previous_role;
- self.havocbot_role_timeout = 0;
+ this.havocbot_role = this.havocbot_previous_role;
+ this.havocbot_role_timeout = 0;
return;
}
// Chase the flag carrier
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
- havocbot_goalrating_ctf_enemyflag(30000);
- havocbot_goalrating_ctf_ourstolenflag(40000);
- havocbot_goalrating_items(10000, self.origin, 10000);
- navigation_goalrating_end();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
+ havocbot_goalrating_ctf_enemyflag(this, 30000);
+ havocbot_goalrating_ctf_ourstolenflag(this, 40000);
+ havocbot_goalrating_items(this, 10000, this.origin, 10000);
+ navigation_goalrating_end(this);
}
}
-void havocbot_role_ctf_offense()
-{SELFPARAM();
+void havocbot_role_ctf_offense(entity this)
+{
entity mf, ef;
vector pos;
- if(IS_DEAD(self))
+ if(IS_DEAD(this))
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.flagcarried)
+ if (this.flagcarried)
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_CARRIER);
return;
}
// Check flags
- mf = havocbot_ctf_find_flag(self);
- ef = havocbot_ctf_find_enemy_flag(self);
+ mf = havocbot_ctf_find_flag(this);
+ ef = havocbot_ctf_find_enemy_flag(this);
// Own flag stolen
if(mf.ctf_status!=FLAG_BASE)
pos = mf.origin;
// Try to get it if closer than the enemy base
- if(vlen(self.origin-ef.dropped_origin)>vlen(self.origin-pos))
+ if(vlen(this.origin-ef.dropped_origin)>vlen(this.origin-pos))
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_RETRIEVER);
return;
}
}
if(vlen(pos-mf.dropped_origin)>700)
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_ESCORT);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_ESCORT);
return;
}
}
// About to fail, switch to middlefield
- if(self.health<50)
+ if(this.health<50)
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_MIDDLE);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_MIDDLE);
return;
}
// Set the role timeout if necessary
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + 120;
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + 120;
- if (time > self.havocbot_role_timeout)
+ if (time > this.havocbot_role_timeout)
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
- havocbot_goalrating_ctf_ourstolenflag(50000);
- havocbot_goalrating_ctf_enemybase(20000);
- havocbot_goalrating_items(5000, self.origin, 1000);
- havocbot_goalrating_items(1000, self.origin, 10000);
- navigation_goalrating_end();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
+ havocbot_goalrating_ctf_ourstolenflag(this, 50000);
+ havocbot_goalrating_ctf_enemybase(this, 20000);
+ havocbot_goalrating_items(this, 5000, this.origin, 1000);
+ havocbot_goalrating_items(this, 1000, this.origin, 10000);
+ navigation_goalrating_end(this);
}
}
// Retriever (temporary role):
-void havocbot_role_ctf_retriever()
-{SELFPARAM();
+void havocbot_role_ctf_retriever(entity this)
+{
entity mf;
- if(IS_DEAD(self))
+ if(IS_DEAD(this))
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.flagcarried)
+ if (this.flagcarried)
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_CARRIER);
return;
}
// If flag is back on the base switch to previous role
- mf = havocbot_ctf_find_flag(self);
+ mf = havocbot_ctf_find_flag(this);
if(mf.ctf_status==FLAG_BASE)
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + 20;
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + 20;
- if (time > self.havocbot_role_timeout)
+ if (time > this.havocbot_role_timeout)
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
float rt_radius;
rt_radius = 10000;
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
- havocbot_goalrating_ctf_ourstolenflag(50000);
- havocbot_goalrating_ctf_droppedflags(40000, self.origin, rt_radius);
- havocbot_goalrating_ctf_enemybase(30000);
- havocbot_goalrating_items(500, self.origin, rt_radius);
- navigation_goalrating_end();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
+ havocbot_goalrating_ctf_ourstolenflag(this, 50000);
+ havocbot_goalrating_ctf_droppedflags(this, 40000, this.origin, rt_radius);
+ havocbot_goalrating_ctf_enemybase(this, 30000);
+ havocbot_goalrating_items(this, 500, this.origin, rt_radius);
+ navigation_goalrating_end(this);
}
}
-void havocbot_role_ctf_middle()
-{SELFPARAM();
+void havocbot_role_ctf_middle(entity this)
+{
entity mf;
- if(IS_DEAD(self))
+ if(IS_DEAD(this))
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.flagcarried)
+ if (this.flagcarried)
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_CARRIER);
return;
}
- mf = havocbot_ctf_find_flag(self);
+ mf = havocbot_ctf_find_flag(this);
if(mf.ctf_status!=FLAG_BASE)
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_RETRIEVER);
return;
}
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + 10;
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + 10;
- if (time > self.havocbot_role_timeout)
+ if (time > this.havocbot_role_timeout)
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
vector org;
org = havocbot_ctf_middlepoint;
- org.z = self.origin.z;
+ org.z = this.origin.z;
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
- havocbot_goalrating_ctf_ourstolenflag(50000);
- havocbot_goalrating_ctf_droppedflags(30000, self.origin, 10000);
- havocbot_goalrating_enemyplayers(10000, org, havocbot_ctf_middlepoint_radius * 0.5);
- havocbot_goalrating_items(5000, org, havocbot_ctf_middlepoint_radius * 0.5);
- havocbot_goalrating_items(2500, self.origin, 10000);
- havocbot_goalrating_ctf_enemybase(2500);
- navigation_goalrating_end();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
+ havocbot_goalrating_ctf_ourstolenflag(this, 50000);
+ havocbot_goalrating_ctf_droppedflags(this, 30000, this.origin, 10000);
+ havocbot_goalrating_enemyplayers(this, 10000, org, havocbot_ctf_middlepoint_radius * 0.5);
+ havocbot_goalrating_items(this, 5000, org, havocbot_ctf_middlepoint_radius * 0.5);
+ havocbot_goalrating_items(this, 2500, this.origin, 10000);
+ havocbot_goalrating_ctf_enemybase(this, 2500);
+ navigation_goalrating_end(this);
}
}
-void havocbot_role_ctf_defense()
-{SELFPARAM();
+void havocbot_role_ctf_defense(entity this)
+{
entity mf;
- if(IS_DEAD(self))
+ if(IS_DEAD(this))
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.flagcarried)
+ if (this.flagcarried)
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_CARRIER);
return;
}
// If own flag was captured
- mf = havocbot_ctf_find_flag(self);
+ mf = havocbot_ctf_find_flag(this);
if(mf.ctf_status!=FLAG_BASE)
{
- havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER);
+ havocbot_role_ctf_setrole(this, HAVOCBOT_CTF_ROLE_RETRIEVER);
return;
}
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + 30;
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + 30;
- if (time > self.havocbot_role_timeout)
+ if (time > this.havocbot_role_timeout)
{
- havocbot_ctf_reset_role(self);
+ havocbot_ctf_reset_role(this);
return;
}
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
float mp_radius;
vector org;
org = mf.dropped_origin;
mp_radius = havocbot_ctf_middlepoint_radius;
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
// if enemies are closer to our base, go there
entity closestplayer = world;
));
if(closestplayer)
- if(DIFF_TEAM(closestplayer, self))
- if(vlen(org - self.origin)>1000)
- if(checkpvs(self.origin,closestplayer)||random()<0.5)
- havocbot_goalrating_ctf_ourbase(30000);
+ if(DIFF_TEAM(closestplayer, this))
+ if(vlen(org - this.origin)>1000)
+ if(checkpvs(this.origin,closestplayer)||random()<0.5)
+ havocbot_goalrating_ctf_ourbase(this, 30000);
- havocbot_goalrating_ctf_ourstolenflag(20000);
- havocbot_goalrating_ctf_droppedflags(20000, org, mp_radius);
- havocbot_goalrating_enemyplayers(15000, org, mp_radius);
- havocbot_goalrating_items(10000, org, mp_radius);
- havocbot_goalrating_items(5000, self.origin, 10000);
- navigation_goalrating_end();
+ havocbot_goalrating_ctf_ourstolenflag(this, 20000);
+ havocbot_goalrating_ctf_droppedflags(this, 20000, org, mp_radius);
+ havocbot_goalrating_enemyplayers(this, 15000, org, mp_radius);
+ havocbot_goalrating_items(this, 10000, org, mp_radius);
+ havocbot_goalrating_items(this, 5000, this.origin, 10000);
+ navigation_goalrating_end(this);
}
}
void superspec_msg(string _center_title, string _con_title, entity _to, string _msg, float _spamlevel); // TODO
MUTATOR_HOOKFUNCTION(ctf, SV_ParseClientCommand)
{
+ SELFPARAM();
if(IS_PLAYER(self) || MUTATOR_RETURNVALUE || !cvar("g_superspectate")) { return false; }
if(cmd_name == "followfc")
// legacy bot roles
.float race_checkpoint;
-void havocbot_role_cts()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_cts(entity this)
+{
+ if(IS_DEAD(this))
return;
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
FOREACH_ENTITY_CLASS("trigger_race_checkpoint", true,
{
- if(it.cnt == self.race_checkpoint)
- navigation_routerating(it, 1000000, 5000);
- else if(self.race_checkpoint == -1)
- navigation_routerating(it, 1000000, 5000);
+ if(it.cnt == this.race_checkpoint)
+ navigation_routerating(this, it, 1000000, 5000);
+ else if(this.race_checkpoint == -1)
+ navigation_routerating(this, it, 1000000, 5000);
});
- navigation_goalrating_end();
+ navigation_goalrating_end(this);
}
}
void ClientKill_Now();
MUTATOR_HOOKFUNCTION(cts, ClientKill)
{
+ SELFPARAM();
ret_float = 0;
if(self.killindicator && self.killindicator.health == 1) // self.killindicator.health == 1 means that the kill indicator was spawned by CTS_ClientKill
}
//go to best items, or control points you don't own
-void havocbot_role_dom()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_dom(entity this)
+{
+ if(IS_DEAD(this))
return;
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
- havocbot_goalrating_controlpoints(10000, self.origin, 15000);
- havocbot_goalrating_items(8000, self.origin, 8000);
- //havocbot_goalrating_enemyplayers(3000, self.origin, 2000);
- //havocbot_goalrating_waypoints(1, self.origin, 1000);
- navigation_goalrating_end();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
+ havocbot_goalrating_controlpoints(this, 10000, this.origin, 15000);
+ havocbot_goalrating_items(this, 8000, this.origin, 8000);
+ //havocbot_goalrating_enemyplayers(this, 3000, this.origin, 2000);
+ //havocbot_goalrating_waypoints(1, this.origin, 1000);
+ navigation_goalrating_end(this);
}
}
}
// code from here on is just to support maps that don't have control point and team entities
-void dom_spawnteam (string teamname, float teamcolor, string pointmodel, float pointskin, string capsound, string capnarration, string capmessage)
+void dom_spawnteam (string teamname, float teamcolor, string pointmodel, float pointskin, Sound capsound, string capnarration, string capmessage)
{SELFPARAM();
+ TC(Sound, capsound);
setself(spawn());
self.classname = "dom_team";
self.netname = strzone(teamname);
self.cnt = teamcolor;
self.model = pointmodel;
self.skin = pointskin;
- self.noise = strzone(capsound);
+ self.noise = strzone(Sound_fixpath(capsound));
self.noise1 = strzone(capnarration);
self.message = strzone(capmessage);
}
// spawn some default teams if the map is not set up for domination
-void dom_spawnteams(float teams)
+void dom_spawnteams(int teams)
{
- dom_spawnteam(Team_ColoredFullName(NUM_TEAM_1), NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, SND(DOM_CLAIM), "", "Red team has captured a control point");
- dom_spawnteam(Team_ColoredFullName(NUM_TEAM_2), NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, SND(DOM_CLAIM), "", "Blue team has captured a control point");
+ TC(int, teams);
+ dom_spawnteam(Team_ColoredFullName(NUM_TEAM_1), NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, SND_DOM_CLAIM, "", "Red team has captured a control point");
+ dom_spawnteam(Team_ColoredFullName(NUM_TEAM_2), NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, SND_DOM_CLAIM, "", "Blue team has captured a control point");
if(teams >= 3)
- dom_spawnteam(Team_ColoredFullName(NUM_TEAM_3), NUM_TEAM_3-1, "models/domination/dom_yellow.md3", 0, SND(DOM_CLAIM), "", "Yellow team has captured a control point");
+ dom_spawnteam(Team_ColoredFullName(NUM_TEAM_3), NUM_TEAM_3-1, "models/domination/dom_yellow.md3", 0, SND_DOM_CLAIM, "", "Yellow team has captured a control point");
if(teams >= 4)
- dom_spawnteam(Team_ColoredFullName(NUM_TEAM_4), NUM_TEAM_4-1, "models/domination/dom_pink.md3", 0, SND(DOM_CLAIM), "", "Pink team has captured a control point");
- dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, "", "", "");
+ dom_spawnteam(Team_ColoredFullName(NUM_TEAM_4), NUM_TEAM_4-1, "models/domination/dom_pink.md3", 0, SND_DOM_CLAIM, "", "Pink team has captured a control point");
+ dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, SND_Null, "", "");
}
void dom_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
// Bot player logic
// ================
-void() havocbot_role_ft_freeing;
-void() havocbot_role_ft_offense;
+void(entity this) havocbot_role_ft_freeing;
+void(entity this) havocbot_role_ft_offense;
-void havocbot_goalrating_freeplayers(float ratingscale, vector org, float sradius)
-{SELFPARAM();
- float distance;
-
- FOREACH_CLIENT(IS_PLAYER(it) && it != self && SAME_TEAM(it, self), LAMBDA(
+void havocbot_goalrating_freeplayers(entity this, float ratingscale, vector org, float sradius)
+{
+ FOREACH_CLIENT(IS_PLAYER(it) && it != this && SAME_TEAM(it, this), LAMBDA(
if (STAT(FROZEN, it) == 1)
{
- distance = vlen(it.origin - org);
- if (distance > sradius)
+ if(vdist(it.origin - org, >, sradius))
continue;
- navigation_routerating(it, ratingscale, 2000);
+ navigation_routerating(this, it, ratingscale, 2000);
}
else
{
// If teamate is not frozen still seek them out as fight better
// in a group.
- navigation_routerating(it, ratingscale/3, 2000);
+ navigation_routerating(this, it, ratingscale/3, 2000);
}
));
}
-void havocbot_role_ft_offense()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_ft_offense(entity this)
+{
+ if(IS_DEAD(this))
return;
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + random() * 10 + 20;
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + random() * 10 + 20;
// Count how many players on team are unfrozen.
int unfrozen = 0;
- FOREACH_CLIENT(IS_PLAYER(it) && SAME_TEAM(it, self) && !(STAT(FROZEN, it) != 1), LAMBDA(unfrozen++));
+ FOREACH_CLIENT(IS_PLAYER(it) && SAME_TEAM(it, this) && !(STAT(FROZEN, it) != 1), LAMBDA(unfrozen++));
// If only one left on team or if role has timed out then start trying to free players.
- if (((unfrozen == 0) && (!STAT(FROZEN, self))) || (time > self.havocbot_role_timeout))
+ if (((unfrozen == 0) && (!STAT(FROZEN, this))) || (time > this.havocbot_role_timeout))
{
LOG_TRACE("changing role to freeing\n");
- self.havocbot_role = havocbot_role_ft_freeing;
- self.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_ft_freeing;
+ this.havocbot_role_timeout = 0;
return;
}
- if (time > self.bot_strategytime)
+ if (time > this.bot_strategytime)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-
- navigation_goalrating_start();
- havocbot_goalrating_items(10000, self.origin, 10000);
- havocbot_goalrating_enemyplayers(20000, self.origin, 10000);
- havocbot_goalrating_freeplayers(9000, self.origin, 10000);
- //havocbot_goalrating_waypoints(1, self.origin, 1000);
- navigation_goalrating_end();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+
+ navigation_goalrating_start(this);
+ havocbot_goalrating_items(this, 10000, this.origin, 10000);
+ havocbot_goalrating_enemyplayers(this, 20000, this.origin, 10000);
+ havocbot_goalrating_freeplayers(this, 9000, this.origin, 10000);
+ //havocbot_goalrating_waypoints(1, this.origin, 1000);
+ navigation_goalrating_end(this);
}
}
-void havocbot_role_ft_freeing()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_ft_freeing(entity this)
+{
+ if(IS_DEAD(this))
return;
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + random() * 10 + 20;
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + random() * 10 + 20;
- if (time > self.havocbot_role_timeout)
+ if (time > this.havocbot_role_timeout)
{
LOG_TRACE("changing role to offense\n");
- self.havocbot_role = havocbot_role_ft_offense;
- self.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_ft_offense;
+ this.havocbot_role_timeout = 0;
return;
}
- if (time > self.bot_strategytime)
+ if (time > this.bot_strategytime)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-
- navigation_goalrating_start();
- havocbot_goalrating_items(8000, self.origin, 10000);
- havocbot_goalrating_enemyplayers(10000, self.origin, 10000);
- havocbot_goalrating_freeplayers(20000, self.origin, 10000);
- //havocbot_goalrating_waypoints(1, self.origin, 1000);
- navigation_goalrating_end();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+
+ navigation_goalrating_start(this);
+ havocbot_goalrating_items(this, 8000, this.origin, 10000);
+ havocbot_goalrating_enemyplayers(this, 10000, this.origin, 10000);
+ havocbot_goalrating_freeplayers(this, 20000, this.origin, 10000);
+ //havocbot_goalrating_waypoints(1, this.origin, 1000);
+ navigation_goalrating_end(this);
}
}
}
MUTATOR_HOOKFUNCTION(ft, ClientDisconnect)
-{SELFPARAM();
+{
ft_RemovePlayer();
return 1;
}
MUTATOR_HOOKFUNCTION(ft, MakePlayerObserver)
-{SELFPARAM();
+{
ft_RemovePlayer();
return false;
}
MUTATOR_HOOKFUNCTION(ft, PlayerDies)
{
+ SELFPARAM();
if(round_handler_IsActive())
if(round_handler_CountdownRunning())
{
}
MUTATOR_HOOKFUNCTION(ft, reset_map_players)
-{SELFPARAM();
+{
FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
it.killcount = 0;
it.freezetag_frozen_timeout = -1;
const float SP_KEEPAWAY_CARRIERKILLS = 5;
const float SP_KEEPAWAY_BCTIME = 6;
-void() havocbot_role_ka_carrier;
-void() havocbot_role_ka_collector;
+void(entity this) havocbot_role_ka_carrier;
+void(entity this) havocbot_role_ka_collector;
void ka_DropEvent(entity plyr);
#endif
// Bot player logic
// ================
-void havocbot_goalrating_ball(float ratingscale, vector org)
-{SELFPARAM();
+void havocbot_goalrating_ball(entity this, float ratingscale, vector org)
+{
float t;
entity ball_owner;
ball_owner = ka_ball.owner;
- if (ball_owner == self)
+ if (ball_owner == this)
return;
// If ball is carried by player then hunt them down.
if (ball_owner)
{
- t = (self.health + self.armorvalue) / (ball_owner.health + ball_owner.armorvalue);
- navigation_routerating(ball_owner, t * ratingscale, 2000);
+ t = (this.health + this.armorvalue) / (ball_owner.health + ball_owner.armorvalue);
+ navigation_routerating(this, ball_owner, t * ratingscale, 2000);
}
else // Ball has been dropped so collect.
- navigation_routerating(ka_ball, ratingscale, 2000);
+ navigation_routerating(this, ka_ball, ratingscale, 2000);
}
-void havocbot_role_ka_carrier()
-{SELFPARAM();
- if (IS_DEAD(self))
+void havocbot_role_ka_carrier(entity this)
+{
+ if (IS_DEAD(this))
return;
- if (time > self.bot_strategytime)
+ if (time > this.bot_strategytime)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
- havocbot_goalrating_items(10000, self.origin, 10000);
- havocbot_goalrating_enemyplayers(20000, self.origin, 10000);
- //havocbot_goalrating_waypoints(1, self.origin, 1000);
- navigation_goalrating_end();
+ navigation_goalrating_start(this);
+ havocbot_goalrating_items(this, 10000, this.origin, 10000);
+ havocbot_goalrating_enemyplayers(this, 20000, this.origin, 10000);
+ //havocbot_goalrating_waypoints(1, this.origin, 1000);
+ navigation_goalrating_end(this);
}
- if (!self.ballcarried)
+ if (!this.ballcarried)
{
- self.havocbot_role = havocbot_role_ka_collector;
- self.bot_strategytime = 0;
+ this.havocbot_role = havocbot_role_ka_collector;
+ this.bot_strategytime = 0;
}
}
-void havocbot_role_ka_collector()
-{SELFPARAM();
- if (IS_DEAD(self))
+void havocbot_role_ka_collector(entity this)
+{
+ if (IS_DEAD(this))
return;
- if (time > self.bot_strategytime)
+ if (time > this.bot_strategytime)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
- havocbot_goalrating_items(10000, self.origin, 10000);
- havocbot_goalrating_enemyplayers(1000, self.origin, 10000);
- havocbot_goalrating_ball(20000, self.origin);
- navigation_goalrating_end();
+ navigation_goalrating_start(this);
+ havocbot_goalrating_items(this, 10000, this.origin, 10000);
+ havocbot_goalrating_enemyplayers(this, 1000, this.origin, 10000);
+ havocbot_goalrating_ball(this, 20000, this.origin);
+ navigation_goalrating_end(this);
}
- if (self.ballcarried)
+ if (this.ballcarried)
{
- self.havocbot_role = havocbot_role_ka_carrier;
- self.bot_strategytime = 0;
+ this.havocbot_role = havocbot_role_ka_carrier;
+ this.bot_strategytime = 0;
}
}
.entity kh_next;
float kh_Key_AllOwnedByWhichTeam();
-typedef void() kh_Think_t;
+USING(kh_Think_t, void());
void kh_StartRound();
void kh_Controller_SetThink(float t, kh_Think_t func);
if(vlen(key.owner.origin - p) > autocvar_g_balance_keyhunt_maxdist)
goto not_winning;
kh_WinnerTeam(self.team);
-:not_winning
+LABEL(not_winning)
}
if(kh_interferemsg_time && time > kh_interferemsg_time)
// legacy bot role
-void() havocbot_role_kh_carrier;
-void() havocbot_role_kh_defense;
-void() havocbot_role_kh_offense;
-void() havocbot_role_kh_freelancer;
+void(entity this) havocbot_role_kh_carrier;
+void(entity this) havocbot_role_kh_defense;
+void(entity this) havocbot_role_kh_offense;
+void(entity this) havocbot_role_kh_freelancer;
-void havocbot_goalrating_kh(float ratingscale_team, float ratingscale_dropped, float ratingscale_enemy)
-{SELFPARAM();
+void havocbot_goalrating_kh(entity this, float ratingscale_team, float ratingscale_dropped, float ratingscale_enemy)
+{
entity head;
for (head = kh_worldkeylist; head; head = head.kh_worldkeynext)
{
- if(head.owner == self)
+ if(head.owner == this)
continue;
if(!kh_tracking_enabled)
{
// if it's carried by our team we know about it
// otherwise we have to see it to know about it
- if(!head.owner || head.team != self.team)
+ if(!head.owner || head.team != this.team)
{
- traceline(self.origin + self.view_ofs, head.origin, MOVE_NOMONSTERS, self);
+ traceline(this.origin + this.view_ofs, head.origin, MOVE_NOMONSTERS, this);
if (trace_fraction < 1 && trace_ent != head)
continue; // skip what I can't see
}
}
if(!head.owner)
- navigation_routerating(head, ratingscale_dropped * BOT_PICKUP_RATING_HIGH, 100000);
- else if(head.team == self.team)
- navigation_routerating(head.owner, ratingscale_team * BOT_PICKUP_RATING_HIGH, 100000);
+ navigation_routerating(this, head, ratingscale_dropped * BOT_PICKUP_RATING_HIGH, 100000);
+ else if(head.team == this.team)
+ navigation_routerating(this, head.owner, ratingscale_team * BOT_PICKUP_RATING_HIGH, 100000);
else
- navigation_routerating(head.owner, ratingscale_enemy * BOT_PICKUP_RATING_HIGH, 100000);
+ navigation_routerating(this, head.owner, ratingscale_enemy * BOT_PICKUP_RATING_HIGH, 100000);
}
- havocbot_goalrating_items(1, self.origin, 10000);
+ havocbot_goalrating_items(this, 1, this.origin, 10000);
}
-void havocbot_role_kh_carrier()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_kh_carrier(entity this)
+{
+ if(IS_DEAD(this))
return;
- if (!(self.kh_next))
+ if (!(this.kh_next))
{
LOG_TRACE("changing role to freelancer\n");
- self.havocbot_role = havocbot_role_kh_freelancer;
- self.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_kh_freelancer;
+ this.havocbot_role_timeout = 0;
return;
}
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
- if(kh_Key_AllOwnedByWhichTeam() == self.team)
- havocbot_goalrating_kh(10, 0.1, 0.1); // bring home
+ if(kh_Key_AllOwnedByWhichTeam() == this.team)
+ havocbot_goalrating_kh(this, 10, 0.1, 0.1); // bring home
else
- havocbot_goalrating_kh(4, 4, 1); // play defensively
+ havocbot_goalrating_kh(this, 4, 4, 1); // play defensively
- navigation_goalrating_end();
+ navigation_goalrating_end(this);
}
}
-void havocbot_role_kh_defense()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_kh_defense(entity this)
+{
+ if(IS_DEAD(this))
return;
- if (self.kh_next)
+ if (this.kh_next)
{
LOG_TRACE("changing role to carrier\n");
- self.havocbot_role = havocbot_role_kh_carrier;
- self.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_kh_carrier;
+ this.havocbot_role_timeout = 0;
return;
}
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + random() * 10 + 20;
- if (time > self.havocbot_role_timeout)
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + random() * 10 + 20;
+ if (time > this.havocbot_role_timeout)
{
LOG_TRACE("changing role to freelancer\n");
- self.havocbot_role = havocbot_role_kh_freelancer;
- self.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_kh_freelancer;
+ this.havocbot_role_timeout = 0;
return;
}
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
float key_owner_team;
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
key_owner_team = kh_Key_AllOwnedByWhichTeam();
- if(key_owner_team == self.team)
- havocbot_goalrating_kh(10, 0.1, 0.1); // defend key carriers
+ if(key_owner_team == this.team)
+ havocbot_goalrating_kh(this, 10, 0.1, 0.1); // defend key carriers
else if(key_owner_team == -1)
- havocbot_goalrating_kh(4, 1, 0.1); // play defensively
+ havocbot_goalrating_kh(this, 4, 1, 0.1); // play defensively
else
- havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK ANYWAY
+ havocbot_goalrating_kh(this, 0.1, 0.1, 10); // ATTACK ANYWAY
- navigation_goalrating_end();
+ navigation_goalrating_end(this);
}
}
-void havocbot_role_kh_offense()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_kh_offense(entity this)
+{
+ if(IS_DEAD(this))
return;
- if (self.kh_next)
+ if (this.kh_next)
{
LOG_TRACE("changing role to carrier\n");
- self.havocbot_role = havocbot_role_kh_carrier;
- self.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_kh_carrier;
+ this.havocbot_role_timeout = 0;
return;
}
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + random() * 10 + 20;
- if (time > self.havocbot_role_timeout)
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + random() * 10 + 20;
+ if (time > this.havocbot_role_timeout)
{
LOG_TRACE("changing role to freelancer\n");
- self.havocbot_role = havocbot_role_kh_freelancer;
- self.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_kh_freelancer;
+ this.havocbot_role_timeout = 0;
return;
}
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
float key_owner_team;
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
key_owner_team = kh_Key_AllOwnedByWhichTeam();
- if(key_owner_team == self.team)
- havocbot_goalrating_kh(10, 0.1, 0.1); // defend anyway
+ if(key_owner_team == this.team)
+ havocbot_goalrating_kh(this, 10, 0.1, 0.1); // defend anyway
else if(key_owner_team == -1)
- havocbot_goalrating_kh(0.1, 1, 4); // play offensively
+ havocbot_goalrating_kh(this, 0.1, 1, 4); // play offensively
else
- havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK! EMERGENCY!
+ havocbot_goalrating_kh(this, 0.1, 0.1, 10); // ATTACK! EMERGENCY!
- navigation_goalrating_end();
+ navigation_goalrating_end(this);
}
}
-void havocbot_role_kh_freelancer()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_kh_freelancer(entity this)
+{
+ if(IS_DEAD(this))
return;
- if (self.kh_next)
+ if (this.kh_next)
{
LOG_TRACE("changing role to carrier\n");
- self.havocbot_role = havocbot_role_kh_carrier;
- self.havocbot_role_timeout = 0;
+ this.havocbot_role = havocbot_role_kh_carrier;
+ this.havocbot_role_timeout = 0;
return;
}
- if (!self.havocbot_role_timeout)
- self.havocbot_role_timeout = time + random() * 10 + 10;
- if (time > self.havocbot_role_timeout)
+ if (!this.havocbot_role_timeout)
+ this.havocbot_role_timeout = time + random() * 10 + 10;
+ if (time > this.havocbot_role_timeout)
{
if (random() < 0.5)
{
LOG_TRACE("changing role to offense\n");
- self.havocbot_role = havocbot_role_kh_offense;
+ this.havocbot_role = havocbot_role_kh_offense;
}
else
{
LOG_TRACE("changing role to defense\n");
- self.havocbot_role = havocbot_role_kh_defense;
+ this.havocbot_role = havocbot_role_kh_defense;
}
- self.havocbot_role_timeout = 0;
+ this.havocbot_role_timeout = 0;
return;
}
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
float key_owner_team;
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
key_owner_team = kh_Key_AllOwnedByWhichTeam();
- if(key_owner_team == self.team)
- havocbot_goalrating_kh(10, 0.1, 0.1); // defend anyway
+ if(key_owner_team == this.team)
+ havocbot_goalrating_kh(this, 10, 0.1, 0.1); // defend anyway
else if(key_owner_team == -1)
- havocbot_goalrating_kh(1, 10, 4); // prefer dropped keys
+ havocbot_goalrating_kh(this, 1, 10, 4); // prefer dropped keys
else
- havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK ANYWAY
+ havocbot_goalrating_kh(this, 0.1, 0.1, 10); // ATTACK ANYWAY
- navigation_goalrating_end();
+ navigation_goalrating_end(this);
}
}
MUTATOR_HOOKFUNCTION(kh, HavocBot_ChooseRole)
{
+ SELFPARAM();
if(IS_DEAD(self))
return true;
MUTATOR_HOOKFUNCTION(lms, ClientCommand_Spectate)
{
+ SELFPARAM();
if(self.lms_spectate_warning)
{
// for the forfeit message...
// legacy bot roles
.float race_checkpoint;
-void havocbot_role_race()
-{SELFPARAM();
- if(IS_DEAD(self))
+void havocbot_role_race(entity this)
+{
+ if(IS_DEAD(this))
return;
entity e;
- if (self.bot_strategytime < time)
+ if (this.bot_strategytime < time)
{
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start(this);
for(e = world; (e = find(e, classname, "trigger_race_checkpoint")) != world; )
{
- if(e.cnt == self.race_checkpoint)
+ if(e.cnt == this.race_checkpoint)
{
- navigation_routerating(e, 1000000, 5000);
+ navigation_routerating(this, e, 1000000, 5000);
}
- else if(self.race_checkpoint == -1)
+ else if(this.race_checkpoint == -1)
{
- navigation_routerating(e, 1000000, 5000);
+ navigation_routerating(this, e, 1000000, 5000);
}
}
- navigation_goalrating_end();
+ navigation_goalrating_end(this);
}
}
void WinningConditionHelper()
{
+ SELFPARAM();
float c;
string s;
float fullstatus;
.vector spawnpoint_prevorigin;
void spawnpoint_think()
{
+ SELFPARAM();
self.nextthink = time + 0.1;
if(self.origin != self.spawnpoint_prevorigin)
{
float RedirectionThink();
void StartFrame()
{
- SELFPARAM();
execute_next_frame();
if (autocvar_sv_autopause && !server_is_dedicated) Pause_TryPause(true);
}
}
inv = !inv;
-:cvar_fail
+LABEL(cvar_fail)
// now inv is 1 if we want to keep the item, and 0 if we want to get rid of it
if (!inv)
{
bool client_hasweapon(entity cl, Weapon wpn, float andammo, bool complain)
{
+ SELFPARAM();
float f = 0;
if (time < cl.hasweapon_complain_spam)
// this function calculates w_shotorg and w_shotdir based on the weapon model
// offset, trueaim and antilag, and won't put w_shotorg inside a wall.
// make sure you call makevectors first (FIXME?)
-void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, string snd, float chan, float maxdamage, float range)
+void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, Sound snd, float chan, float maxdamage, float range)
{
+ TC(Sound, snd);
float nudge = 1; // added to traceline target and subtracted from result TOOD(divVerent): do we still need this? Doesn't the engine do this now for us?
float oldsolid;
vector vecs, dv;
if (!autocvar_g_norecoil)
ent.punchangle_x = recoil * -1;
- if (snd != "")
- {
- _sound (ent, chan, snd, VOL_BASE, ATTN_NORM);
+ if (snd != SND_Null) {
+ sound (ent, chan, snd, VOL_BASE, ATTN_NORM);
W_PlayStrengthSound(ent);
}
// this function calculates w_shotorg and w_shotdir based on the weapon model
// offset, trueaim and antilag, and won't put w_shotorg inside a wall.
// make sure you call makevectors first (FIXME?)
-void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, string snd, float chan, float maxdamage, float range);
+void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, Sound snd, float chan, float maxdamage, float range);
#define W_SetupShot_Dir_ProjectileSize(ent,s_forward,mi,ma,antilag,recoil,snd,chan,maxdamage) W_SetupShot_Dir_ProjectileSize_Range(ent, s_forward, mi, ma, antilag, recoil, snd, chan, maxdamage, MAX_SHOT_DISTANCE)
#define W_SetupShot_ProjectileSize(ent,mi,ma,antilag,recoil,snd,chan,maxdamage) W_SetupShot_Dir_ProjectileSize(ent, v_forward, mi, ma, antilag, recoil, snd, chan, maxdamage)
else if (this.owner.alpha != 0) this.alpha = this.owner.alpha;
else this.alpha = 1;
- this.glowmod = weaponentity_glowmod(PS(this.owner).m_weapon, this.owner.clientcolors);
+ Weapon wep = PS(this.owner).m_weapon;
+ if (wep) this.glowmod = weaponentity_glowmod(wep, this.owner.clientcolors);
this.colormap = this.owner.colormap;
CSQCMODEL_AUTOUPDATE(this);
.float prevwarntime;
bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary)
{
+ SELFPARAM();
if ((actor.items & IT_UNLIMITED_WEAPON_AMMO)) return true;
bool ammo = false;
if (secondary) WITH(entity, self, actor, ammo = thiswep.wr_checkammo2(thiswep));
w_ready(wpn, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1));
}
-void W_Reload(entity actor, float sent_ammo_min, string sent_sound)
+void W_Reload(entity actor, float sent_ammo_min, Sound sent_sound)
{
+ TC(Sound, sent_sound);
.entity weaponentity = weaponentities[0];
// set global values to work with
Weapon e = PS(actor).m_weapon;
actor.reload_ammo_min = sent_ammo_min;
actor.reload_ammo_amount = e.reloading_ammo;
actor.reload_time = e.reloading_time;
- actor.reload_sound = sent_sound;
+ if (actor.reload_sound) strunzone(actor.reload_sound);
+ actor.reload_sound = strzone(Sound_fixpath(sent_sound));
// don't reload weapons that don't have the RELOADABLE flag
if (!(e.spawnflags & WEP_FLAG_RELOADABLE))
void W_DropEvent(.void(Weapon) event, entity player, float weapon_type, entity weapon_item)
{
+ SELFPARAM();
Weapon w = Weapons_from(weapon_type);
weapon_dropevent_item = weapon_item;
WITH(entity, self, player, w.event(w));
void W_DropEvent(.void(Weapon) event, entity player, float weapon_type, entity weapon_item);
-void W_Reload(entity actor, float sent_ammo_min, string sent_sound);
+void W_Reload(entity actor, float sent_ammo_min, Sound sent_sound);
void W_WeaponFrame(entity actor);