- wget -O data/maps/g-23.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.cache
- wget -O data/maps/g-23.waypoints.hardwired https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.hardwired
- make
- - EXPECT=81f90da8c88646dcce300fdcc31113d1
+ - EXPECT=c35a668d31d76df2bcbc503c3ac7b0aa
- HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
| tee /dev/stderr
| grep '^:'
if(IS_DEAD(player) || !IS_PLAYER(player) || STAT(FROZEN, player))
return;
- if(player.ok_lastwep)
- {
- Weapon newwep = Weapons_from(player.ok_lastwep);
- if(player.ok_lastwep == WEP_HMG.m_id)
- newwep = WEP_MACHINEGUN;
- if(player.ok_lastwep == WEP_RPC.m_id)
- newwep = WEP_VORTEX;
- PS(player).m_switchweapon = newwep;
- player.ok_lastwep = 0;
- }
-
ok_IncreaseCharge(player, PS(player).m_weapon.m_id);
if(PHYS_INPUT_BUTTON_ATCK2(player))
}
else
player.ok_use_ammocharge = 0;
+}
- // if player changed their weapon while dead, don't switch to their death weapon
- if(player.impulse)
+MUTATOR_HOOKFUNCTION(ok, PlayerWeaponSelect)
+{
+ entity player = M_ARGV(0, entity);
+
+ if(player.ok_lastwep)
+ {
+ Weapon newwep = Weapons_from(player.ok_lastwep);
+ if(player.ok_lastwep == WEP_HMG.m_id)
+ newwep = WEP_MACHINEGUN;
+ if(player.ok_lastwep == WEP_RPC.m_id)
+ newwep = WEP_VORTEX;
+ PS(player).m_switchweapon = newwep;
player.ok_lastwep = 0;
+ }
}
void self_spawnfunc_weapon_hmg(entity this) { spawnfunc_weapon_hmg(this); }
else { PlayerStats_GameReport_DelayMapVote = false; }
}
+// this... is a hack, a temporary one until we get a proper duel gametype
+string PlayerStats_GetGametype()
+{
+ return ((IS_GAMETYPE(DEATHMATCH) && autocvar_g_maxplayers == 2) ? "duel" : GetGametype());
+}
+
void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
{
string t, tn;
#ifdef WATERMARK
url_fputs(fh, sprintf("R %s\n", WATERMARK));
#endif
- url_fputs(fh, sprintf("G %s\n", GetGametype()));
+ url_fputs(fh, sprintf("G %s\n", PlayerStats_GetGametype()));
url_fputs(fh, sprintf("O %s\n", modname));
url_fputs(fh, sprintf("M %s\n", GetMapname()));
url_fputs(fh, sprintf("I %s\n", matchid));
case "e":
LOG_TRACE("G: ", gt);
LOG_TRACE("e: ", data);
- if (gt == GetGametype()) {
+ if (gt == PlayerStats_GetGametype()) {
handled = true;
float e = stof(data);
PlayerScore_Add(p, SP_ELO, +1 + e);
RemoveItem(this);
}
+void item_use(entity this, entity actor, entity trigger)
+{
+ // use the touch function to handle collection
+ gettouch(this)(this, actor);
+}
+
void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter)
{
string itemname = def.m_name;
}
*/
+ if(this.targetname != "" && (this.spawnflags & 16))
+ this.use = item_use;
+
if(autocvar_spawn_debug >= 2)
{
// why not flags & fl_item?
}
if(this.enemy.target)
- SUB_UseTargets(this.enemy, targ, targ); // TODO: do we need targ as trigger too?
+ SUB_UseTargets(this.enemy, targ, this);
if (targ.flags & FL_PROJECTILE)
{
void target_push_use(entity this, entity actor, entity trigger)
{
+ if(trigger.classname == "trigger_push" || trigger == this)
+ return; // WTF, why is this a thing
+
jumppad_push(this, actor);
}
CLASS(Crylink, Weapon)
/* ammotype */ ATTRIB(Crylink, ammo_field, .int, ammo_cells);
/* impulse */ ATTRIB(Crylink, impulse, int, 6);
-/* flags */ ATTRIB(Crylink, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
+/* flags */ ATTRIB(Crylink, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_CANCLIMB);
/* rating */ ATTRIB(Crylink, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
/* color */ ATTRIB(Crylink, wpcolor, vector, '1 0.5 1');
/* modelname */ ATTRIB(Crylink, mdl, string, "crylink");
}
break;
}
- if(trace_ent == wz)
+ /*if(trace_ent == wz)
{
// FIXME can this check be removed? Do we really need it?
LOG_TRACE("I transformed into the same zone again, wtf, aborting the trace");
trace_ent = NULL;
break;
- }
+ }*/
wz = trace_ent;
if(!WarpZone_trace_firstzone)
WarpZone_trace_firstzone = wz;
this.weaponname = "";
PS(this).m_switchingweapon = WEP_Null;
+ MUTATOR_CALLHOOK(PlayerWeaponSelect, this);
+
if (!warmup_stage && !this.alivetime)
this.alivetime = time;
/**/
MUTATOR_HOOKABLE(PlayerSpawn, EV_PlayerSpawn);
+/** called after a player's weapon is chosen so it can be overriden here */
+#define EV_PlayerWeaponSelect(i, o) \
+ /** player spawning */ i(entity, MUTATOR_ARGV_0_entity) \
+ /**/
+MUTATOR_HOOKABLE(PlayerWeaponSelect, EV_PlayerWeaponSelect);
+
/** called in reset_map */
#define EV_reset_map_global(i, o) \
/**/
}
if(sound_allowed(MSG_BROADCAST, attacker))
- if((this.health < 2 * WEP_CVAR_PRI(blaster, damage) * autocvar_g_balance_selfdamagepercent + 1) || !(DEATH_WEAPONOF(deathtype).spawnflags & WEP_FLAG_CANCLIMB) || attacker != this) // WEAPONTODO: create separate limit for pain notification with laser
+ if(this.health < 25 || !(DEATH_WEAPONOF(deathtype).spawnflags & WEP_FLAG_CANCLIMB) || take > 20 || attacker != this)
if(this.health > 1)
// exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two
{
string GetClientVersionMessage(entity this)
{
- string versionmsg;
if (this.version_mismatch) {
if(this.version < autocvar_gameversion) {
- versionmsg = "^3Your client version is outdated.\n\n\n### YOU WON'T BE ABLE TO PLAY ON THIS SERVER ###\n\n\nPlease update!!!^8";
+ return strcat("This is Xonotic ", autocvar_g_xonoticversion,
+ "\n^3Your client version is outdated.\n\n\n### YOU WON'T BE ABLE TO PLAY ON THIS SERVER ###\n\n\nPlease update!!!^8");
} else {
- versionmsg = "^3This server is using an outdated Xonotic version.\n\n\n ### THIS SERVER IS INCOMPATIBLE AND THUS YOU CANNOT JOIN ###.^8";
+ return strcat("This is Xonotic ", autocvar_g_xonoticversion,
+ "\n^3This server is using an outdated Xonotic version.\n\n\n ### THIS SERVER IS INCOMPATIBLE AND THUS YOU CANNOT JOIN ###.^8");
}
} else {
- versionmsg = "^2client version and server version are compatible.^8";
+ return strcat("Welcome to Xonotic ", autocvar_g_xonoticversion);
}
- return versionmsg;
}
string getwelcomemessage(entity this)
{
- string s, modifications, motd;
-
MUTATOR_CALLHOOK(BuildMutatorsPrettyString, "");
- modifications = M_ARGV(0, string);
+ string modifications = M_ARGV(0, string);
if(g_weaponarena)
{
modifications = substring(modifications, 2, strlen(modifications) - 2);
string versionmessage = GetClientVersionMessage(this);
-
- s = strcat("This is Xonotic ", autocvar_g_xonoticversion, "\n", versionmessage);
- s = strcat(s, "^8\n\nmatch type is ^1", gamemode_name, "^8\n");
+ string s = strcat(versionmessage, "^8\n^8\nmatch type is ^1", gamemode_name, "^8\n");
if(modifications != "")
s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
s = strcat(s, mutator_msg); // trust that the mutator will do proper formatting
- motd = autocvar_sv_motd;
+ string motd = autocvar_sv_motd;
if (motd != "") {
s = strcat(s, "\n\n^8MOTD: ^7", strreplace("\\n", "\n", motd));
}