Commit 50d8efb8 authored by Mario's avatar Mario

Merge branch 'master' into Mario/wepent_experimental

# Conflicts:
#	qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
parents cd76ea22 f0a82d2b
Pipeline #5638066 failed with stage
in 11 minutes and 26 seconds
......@@ -30,7 +30,7 @@ test_sv_game:
- 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 '^:'
......
......@@ -418,7 +418,9 @@ set g_keepawayball_respawntime 10 "if no one picks up the ball, how long to wait
// key hunt
// ==========
set g_keyhunt 0 "Key Hunt: collect all keys from the enemies and bring them together to score"
set g_balance_keyhunt_delay_return 60
set g_balance_keyhunt_return_when_unreachable 1 "automatically destroy a key if it falls into lava/slime/trigger hurt"
set g_balance_keyhunt_delay_damage_return 5 "time a key takes to automatically destroy itself if it falls into lava/slime/trigger hurt"
set g_balance_keyhunt_delay_return 60 "time a key takes to destroy itself if dropped"
set g_balance_keyhunt_delay_round 5
set g_balance_keyhunt_delay_tracking 10
set g_balance_keyhunt_delay_fadeout 2
......
......@@ -102,7 +102,7 @@ seta notification_ANNCE_VOTE_ACCEPT "2" "0 = disabled, 1 = enabled if gentle mod
seta notification_ANNCE_VOTE_CALL "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
seta notification_ANNCE_VOTE_FAIL "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
// MSG_INFO notifications (count = 320):
// MSG_INFO notifications (count = 328):
seta notification_INFO_CA_JOIN_LATE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_CA_LEAVE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_CHAT_NOSPECTATORS "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
......@@ -295,6 +295,10 @@ seta notification_INFO_KEYHUNT_CAPTURE_BLUE "1" "0 = off, 1 = print to console,
seta notification_INFO_KEYHUNT_CAPTURE_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_CAPTURE_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_CAPTURE_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_DESTROYED_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_DESTROYED_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_DESTROYED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_DESTROYED_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_DROP_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_DROP_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_DROP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
......@@ -307,6 +311,10 @@ seta notification_INFO_KEYHUNT_PICKUP_BLUE "1" "0 = off, 1 = print to console, 2
seta notification_INFO_KEYHUNT_PICKUP_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_PICKUP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_PICKUP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_PUSHED_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_PUSHED_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_PUSHED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_KEYHUNT_PUSHED_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_LMS_FORFEIT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_LMS_NOLIVES "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_MINIGAME_INVITE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
......@@ -424,7 +432,7 @@ seta notification_INFO_WEAPON_TUBA_SUICIDE "1" "0 = off, 1 = print to console, 2
seta notification_INFO_WEAPON_VAPORIZER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_WEAPON_VORTEX_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
// MSG_CENTER notifications (count = 231):
// MSG_CENTER notifications (count = 235):
seta notification_CENTER_ALONE "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ASSAULT_ATTACKING "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ASSAULT_DEFENDING "1" "0 = off, 1 = centerprint"
......@@ -629,6 +637,10 @@ seta notification_CENTER_POWERUP_STRENGTH "1" "0 = off, 1 = centerprint"
seta notification_CENTER_RACE_FINISHLAP "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ROUND_OVER "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ROUND_PLAYER_WIN "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ROUND_TEAM_LOSS_BLUE "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ROUND_TEAM_LOSS_PINK "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ROUND_TEAM_LOSS_RED "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ROUND_TEAM_LOSS_YELLOW "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ROUND_TEAM_WIN_BLUE "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ROUND_TEAM_WIN_PINK "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ROUND_TEAM_WIN_RED "1" "0 = off, 1 = centerprint"
......@@ -887,4 +899,4 @@ seta notification_show_sprees_info "3" "Show spree information in MSG_INFO messa
seta notification_show_sprees_info_newline "1" "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself"
seta notification_show_sprees_info_specialonly "1" "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement"
// Notification counts (total = 821): MSG_ANNCE = 89, MSG_INFO = 320, MSG_CENTER = 231, MSG_MULTI = 153, MSG_CHOICE = 28
// Notification counts (total = 833): MSG_ANNCE = 89, MSG_INFO = 328, MSG_CENTER = 235, MSG_MULTI = 153, MSG_CHOICE = 28
......@@ -6,7 +6,7 @@
.float buff_time = _STAT(BUFF_TIME);
void buffs_DelayedInit(entity this);
AUTOCVAR(g_buffs, int, -1, _("Enable buffs, -1: enabled but no auto location or replacing powerups, 1: enabled and can replace them"));
AUTOCVAR(g_buffs, int, -1, "Enable buffs, -1: enabled but no auto location or replacing powerups, 1: enabled and can replace them");
REGISTER_MUTATOR(buffs, autocvar_g_buffs)
{
......
......@@ -117,7 +117,7 @@ ENDCLASS(DamageText)
REGISTER_NET_TEMP(damagetext)
#ifdef SVQC
AUTOCVAR(sv_damagetext, int, 2, _("<= 0: disabled, >= 1: spectators, >= 2: players, >= 3: all players"));
AUTOCVAR(sv_damagetext, int, 2, "<= 0: disabled, >= 1: spectators, >= 2: players, >= 3: all players");
#define SV_DAMAGETEXT_DISABLED() (autocvar_sv_damagetext <= 0 /* disabled */)
#define SV_DAMAGETEXT_SPECTATORS_ONLY() (autocvar_sv_damagetext >= 1 /* spectators only */)
#define SV_DAMAGETEXT_PLAYERS() (autocvar_sv_damagetext >= 2 /* players */)
......
#include "sv_hook.qh"
AUTOCVAR(g_grappling_hook, bool, false, _("let players spawn with the grappling hook which allows them to pull themselves up"));
// can't use the autocvar as it doesn't work in the campaign
//AUTOCVAR(g_grappling_hook, bool, false, "let players spawn with the grappling hook which allows them to pull themselves up");
#ifdef SVQC
REGISTER_MUTATOR(hook, autocvar_g_grappling_hook) {
REGISTER_MUTATOR(hook, cvar("g_grappling_hook")) {
MUTATOR_ONADD {
g_grappling_hook = true;
WEP_HOOK.ammo_factor = 0;
......
......@@ -118,23 +118,6 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink)
if(IS_DEAD(player) || !IS_PLAYER(player) || STAT(FROZEN, player))
return;
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
.entity weaponentity = weaponentities[slot];
entity thiswep = player.(weaponentity);
if(player.ok_lastwep[slot] && player.ok_lastwep[slot] != WEP_Null)
{
Weapon newwep = player.ok_lastwep[slot];
if(player.ok_lastwep[slot] == WEP_HMG)
newwep = WEP_MACHINEGUN;
if(player.ok_lastwep[slot] == WEP_RPC)
newwep = WEP_VORTEX;
thiswep.m_switchweapon = newwep;
player.ok_lastwep[slot] = WEP_Null;
}
}
if(PHYS_INPUT_BUTTON_ATCK2(player))
if( !forbidWeaponUse(player) || player.weapon_blocked // allow if weapon is blocked
|| (round_handler_IsActive() && !round_handler_IsRoundStarted()) )
......@@ -173,15 +156,23 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink)
PHYS_INPUT_BUTTON_ATCK2(player) = false;
}
MUTATOR_HOOKFUNCTION(ok, PlayerSpawn)
MUTATOR_HOOKFUNCTION(ok, PlayerWeaponSelect)
{
entity player = M_ARGV(0, entity);
// if player changed their weapon while dead, don't switch to their death weapon
if(player.impulse)
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
.entity weaponentity = weaponentities[slot];
entity thiswep = player.(weaponentity);
if(player.ok_lastwep[slot] && player.ok_lastwep[slot] != WEP_Null)
{
Weapon newwep = player.ok_lastwep[slot];
if(player.ok_lastwep[slot] == WEP_HMG)
newwep = WEP_MACHINEGUN;
if(player.ok_lastwep[slot] == WEP_RPC)
newwep = WEP_VORTEX;
thiswep.m_switchweapon = newwep;
player.ok_lastwep[slot] = WEP_Null;
}
}
......
......@@ -380,6 +380,8 @@
MULTITEAM_INFO(KEYHUNT_CAPTURE, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG captured the keys for the ^TC^TT team"), "", NAME)
MULTITEAM_INFO(KEYHUNT_DROP, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG dropped the ^TC^TT Key"), "", KEY)
MULTITEAM_INFO(KEYHUNT_LOST, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG lost the ^TC^TT Key"), "", KEY)
MULTITEAM_INFO(KEYHUNT_PUSHED, 4, 1, 2, 0, "s1 s2", "", "", _("^BG%s^BG pushed %s^BG causing the ^TC^TT Key ^BGdestruction"), "", KEY)
MULTITEAM_INFO(KEYHUNT_DESTROYED, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG destroyed the ^TC^TT Key"), "", KEY)
MULTITEAM_INFO(KEYHUNT_PICKUP, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG picked up the ^TC^TT Key"), "", KEY)
MSG_INFO_NOTIF(LMS_FORFEIT, 1, 1, 0, "s1", "", "", _("^BG%s^F3 forfeited"), "")
......@@ -649,6 +651,7 @@
MSG_CENTER_NOTIF(GENERATOR_UNDERATTACK, 1, 0, 0, "", CPID_Null, "0 0", _("^BGThe generator is under attack!"), "")
MULTITEAM_CENTER(ROUND_TEAM_LOSS, 4, 1, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team loses the round"), "", NAME)
MULTITEAM_CENTER(ROUND_TEAM_WIN, 4, 1, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team wins the round"), "", NAME)
MSG_CENTER_NOTIF(ROUND_PLAYER_WIN, 1, 1, 0, "s1", CPID_ROUND, "0 0", _("^BG%s^BG wins the round"), "")
......
......@@ -257,6 +257,12 @@ void PlayerStats_GameReport_Init() // initiated before InitGameplayMode so that
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;
......@@ -313,7 +319,7 @@ void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
#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));
......@@ -556,7 +562,7 @@ void PlayerStats_PlayerBasic_Handler(entity fh, entity p, float status)
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);
......
......@@ -1084,6 +1084,12 @@ void Item_Damage(entity this, entity inflictor, entity attacker, float damage, i
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;
......@@ -1205,6 +1211,9 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
}
*/
if(this.targetname != "" && (this.spawnflags & 16))
this.use = item_use;
if(autocvar_spawn_debug >= 2)
{
// why not flags & fl_item?
......
......@@ -222,7 +222,7 @@ bool jumppad_push(entity this, entity targ)
}
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)
{
......@@ -418,6 +418,9 @@ bool target_push_send(entity this, entity to, float sf)
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);
}
......
......@@ -3,7 +3,7 @@
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");
......
......@@ -298,13 +298,13 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end,
}
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;
......
......@@ -707,6 +707,8 @@ void PutClientInServer(entity this)
this.(weaponentity).cnt = -1;
}
MUTATOR_CALLHOOK(PlayerWeaponSelect, this);
if (!warmup_stage && !this.alivetime)
this.alivetime = time;
......
......@@ -31,6 +31,12 @@ MUTATOR_HOOKABLE(ForbidSpawn, EV_ForbidSpawn);
/**/
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) \
/**/
......
......@@ -2,9 +2,11 @@
float autocvar_g_balance_keyhunt_damageforcescale;
float autocvar_g_balance_keyhunt_delay_collect;
float autocvar_g_balance_keyhunt_delay_damage_return;
float autocvar_g_balance_keyhunt_delay_return;
float autocvar_g_balance_keyhunt_delay_round;
float autocvar_g_balance_keyhunt_delay_tracking;
float autocvar_g_balance_keyhunt_return_when_unreachable;
float autocvar_g_balance_keyhunt_dropvelocity;
float autocvar_g_balance_keyhunt_maxdist;
float autocvar_g_balance_keyhunt_protecttime;
......@@ -418,10 +420,8 @@ void kh_Key_Damage(entity this, entity inflictor, entity attacker, float damage,
return;
if(ITEM_DAMAGE_NEEDKILL(deathtype))
{
// touching lava, or hurt trigger
// what shall we do?
// immediately return is bad
// maybe start a shorter countdown?
this.pain_finished = bound(time, time + autocvar_g_balance_keyhunt_delay_damage_return, this.pain_finished);
return;
}
if(force == '0 0 0')
return;
......@@ -456,10 +456,8 @@ void kh_Key_Touch(entity this, entity toucher) // runs many, many times when a
if(ITEM_TOUCH_NEEDKILL())
{
// touching sky, or nodrop
// what shall we do?
// immediately return is bad
// maybe start a shorter countdown?
this.pain_finished = bound(time, time + autocvar_g_balance_keyhunt_delay_damage_return, this.pain_finished);
return;
}
if (!IS_PLAYER(toucher))
......@@ -547,6 +545,7 @@ void kh_WinnerTeam(int winner_team) // runs when a team wins
first = false;
}
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN));
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_KEYHUNT_CAPTURE), keyowner);
first = true;
......@@ -649,7 +648,11 @@ void kh_LoserTeam(int loser_team, entity lostkey) // runs when a player pushes
}
int realteam = kh_Team_ByID(lostkey.count);
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(realteam, INFO_KEYHUNT_LOST), lostkey.kh_previous_owner.netname);
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(loser_team, CENTER_ROUND_TEAM_LOSS));
if(attacker)
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(realteam, INFO_KEYHUNT_PUSHED), attacker.netname, lostkey.kh_previous_owner.netname);
else
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(realteam, INFO_KEYHUNT_DESTROYED), lostkey.kh_previous_owner.netname);
play2all(SND(KH_DESTROY));
te_tarexplosion(lostkey.origin);
......@@ -730,6 +733,8 @@ void kh_Key_Spawn(entity initial_owner, float _angle, float i) // runs every ti
key.angles = '0 360 0' * random();
key.event_damage = kh_Key_Damage;
key.takedamage = DAMAGE_YES;
key.damagedbytriggers = autocvar_g_balance_keyhunt_return_when_unreachable;
key.damagedbycontents = autocvar_g_balance_keyhunt_return_when_unreachable;
key.modelindex = kh_key_dropped;
key.model = "key";
key.kh_dropperteam = 0;
......@@ -860,13 +865,16 @@ int kh_GetMissingTeams()
void kh_WaitForPlayers() // delay start of the round until enough players are present
{
static int prev_missing_teams_mask;
if(time < game_starttime)
{
if (prev_missing_teams_mask > 0)
Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_MISSING_TEAMS);
prev_missing_teams_mask = -1;
kh_Controller_SetThink(game_starttime - time + 0.1, kh_WaitForPlayers);
return;
}
static int prev_missing_teams_mask;
int missing_teams_mask = kh_GetMissingTeams();
if(!missing_teams_mask)
{
......@@ -1309,5 +1317,5 @@ MUTATOR_HOOKFUNCTION(kh, DropSpecialItems)
MUTATOR_HOOKFUNCTION(kh, reset_map_global)
{
kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round + (game_starttime - time), kh_StartRound);
kh_WaitForPlayers(); // takes care of killing the "missing teams" message
}
......@@ -436,7 +436,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
}
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
{
......
......@@ -87,25 +87,23 @@ void InitGameplayMode()
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)
{
......@@ -129,9 +127,7 @@ string getwelcomemessage(entity this)
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");
......@@ -156,7 +152,7 @@ string getwelcomemessage(entity this)
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));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment