{
return false;
}
+ METHOD(Gametype, m_isForcedSupported, bool(Gametype this))
+ {
+ return false;
+ }
METHOD(Gametype, describe, string(Gametype this))
{
return true;
return false;
}
+ METHOD(TeamDeathmatch, m_isForcedSupported, bool(Gametype this))
+ {
+ if(cvar("g_tdm_on_dm_maps"))
+ {
+ // if this is set, all DM maps support TDM too
+ if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags))
+ return true; // TODO: references another gametype (alternatively, we could check which gamemodes are always enabled and append this if any are supported)
+ }
+ return false;
+ }
METHOD(TeamDeathmatch, m_setTeams, void(string sa))
{
cvar_set("g_tdm_teams", sa);
ENDCLASS(Invasion)
REGISTER_GAMETYPE(INVASION, NEW(Invasion));
- return (diameter < 8192);
+CLASS(Duel, Gametype)
+ INIT(Duel)
+ {
+ this.gametype_init(this, _("Duel"),"duel","g_duel",false,"","timelimit=10 pointlimit=0 leadlimit=0",_("Fight in a one versus one arena battle to decide the winner"));
+ }
+ METHOD(Duel, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
+ {
++ return (diameter < 16384);
++ }
++ METHOD(Duel, m_isForcedSupported, bool(Gametype this))
++ {
++ // force all DM maps to work in duel?!
++ // TODO: we should really check the size of maps, some DM maps do not work for duel!
++ if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags))
++ return true;
++ return false;
+ }
+ENDCLASS(Duel)
+REGISTER_GAMETYPE(DUEL, NEW(Duel));
++#define g_duel IS_GAMETYPE(DUEL)
+
const int MAPINFO_FEATURE_WEAPONS = 1; // not defined for instagib-only maps
const int MAPINFO_FEATURE_VEHICLES = 2;
const int MAPINFO_FEATURE_TURRETS = 4;
RemoveGrapplingHooks(this);
Portal_ClearAll(this);
- Unfreeze(this);
+ Unfreeze(this, false);
SetSpectatee(this, NULL);
if (this.alivetime)
this.crouch = false;
STAT(REVIVE_PROGRESS, this) = 0;
this.revival_time = 0;
+ this.draggable = drag_undraggable;
this.items = 0;
STAT(WEAPONS, this) = '0 0 0';
this.event_damage = PlayerDamage;
this.event_heal = PlayerHeal;
+ this.draggable = func_null;
+
if(!this.bot_attack)
IL_PUSH(g_bot_targets, this);
this.bot_attack = true;
//spot.target = s;
}
- Unfreeze(this);
+ Unfreeze(this, false);
MUTATOR_CALLHOOK(PlayerSpawn, this, spot);
if (IS_REAL_CLIENT(this))
sv_notice_join(this);
+ this.move_qcphysics = true;
+
// update physics stats (players can spawn before physics runs)
Physics_UpdateStats(this);
Portal_ClearAll(this);
- Unfreeze(this);
+ Unfreeze(this, false);
RemoveGrapplingHooks(this);
if ( !IS_DEAD(this.owner) && IS_PLAYER(this.owner) )
{
- if ( CS(this.owner).active_minigame )
+ if ( CS(this.owner).active_minigame && PHYS_INPUT_BUTTON_MINIGAME(this.owner) )
this.mdl = "models/sprites/minigame_busy.iqm";
else if (PHYS_INPUT_BUTTON_CHAT(this.owner))
this.mdl = "models/misc/chatbubble.spr";
this.team_selected = false;
}
+int GetPlayerLimit()
+{
+ int player_limit = autocvar_g_maxplayers;
+ MUTATOR_CALLHOOK(GetPlayerLimit, player_limit);
+ player_limit = M_ARGV(0, int);
+ return player_limit;
+}
+
/**
* Determines whether the player is allowed to join. This depends on cvar
* g_maxplayers, if it isn't used this function always return true, otherwise
++currentlyPlaying;
});
+ int player_limit = GetPlayerLimit();
+
float free_slots = 0;
- if (!autocvar_g_maxplayers)
+ if (!player_limit)
free_slots = maxclients - totalClients;
- else if(currentlyPlaying < autocvar_g_maxplayers)
- free_slots = min(maxclients - totalClients, autocvar_g_maxplayers - currentlyPlaying);
+ else if(currentlyPlaying < player_limit)
+ free_slots = min(maxclients - totalClients, player_limit - currentlyPlaying);
static float join_prevent_msg_time = 0;
if(this && ignore && !free_slots && time > join_prevent_msg_time)
if(IS_PLAYER(this))
{
- if (STAT(FROZEN, this) == 2)
+ if (STAT(FROZEN, this) == FROZEN_TEMP_REVIVING)
{
STAT(REVIVE_PROGRESS, this) = bound(0, STAT(REVIVE_PROGRESS, this) + frametime * this.revive_speed, 1);
SetResourceAmountExplicit(this, RESOURCE_HEALTH, max(1, STAT(REVIVE_PROGRESS, this) * start_health));
this.iceblock.alpha = bound(0.2, 1 - STAT(REVIVE_PROGRESS, this), 1);
if (STAT(REVIVE_PROGRESS, this) >= 1)
- Unfreeze(this);
+ Unfreeze(this, false);
}
- else if (STAT(FROZEN, this) == 3)
+ else if (STAT(FROZEN, this) == FROZEN_TEMP_DYING)
{
STAT(REVIVE_PROGRESS, this) = bound(0, STAT(REVIVE_PROGRESS, this) - frametime * this.revive_speed, 1);
SetResourceAmountExplicit(this, RESOURCE_HEALTH, max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * STAT(REVIVE_PROGRESS, this)));
this.event_damage(this, this, this.frozen_by, 1, DEATH_NADE_ICE_FREEZE.m_id, DMG_NOWEP, this.origin, '0 0 0');
}
else if (STAT(REVIVE_PROGRESS, this) <= 0)
- Unfreeze(this);
+ Unfreeze(this, false);
}
}
void Player_Physics(entity this)
{
- set_movetype(this, this.move_movetype);
+ this.movetype = (this.move_qcphysics) ? MOVETYPE_QCPLAYER : this.move_movetype;
if(!this.move_qcphysics)
return;
store.impulse = this.impulse;
this.impulse = 0;
- bool typing = this.buttonchat;
+ bool typing = this.buttonchat || this.button14;
store.button0 = (typing) ? 0 : this.button0;
//button1?!