mirror of
https://github.com/id-Software/quake2-rerelease-dll.git
synced 2026-03-20 17:09:35 +01:00
Update 1 changes
This commit is contained in:
@@ -858,14 +858,14 @@ void InitClientPersistant(edict_t *ent, gclient_t *client)
|
||||
client->pers.max_ammo[AMMO_TESLA] = 5;
|
||||
// ROGUE
|
||||
|
||||
if (!g_instagib->integer)
|
||||
if (!deathmatch->integer || !g_instagib->integer)
|
||||
client->pers.inventory[IT_WEAPON_BLASTER] = 1;
|
||||
|
||||
// [Kex]
|
||||
// start items!
|
||||
if (*g_start_items->string)
|
||||
Player_GiveStartItems(ent, g_start_items->string);
|
||||
else if (g_instagib->integer)
|
||||
else if (deathmatch->integer && g_instagib->integer)
|
||||
{
|
||||
client->pers.inventory[IT_WEAPON_RAILGUN] = 1;
|
||||
client->pers.inventory[IT_AMMO_SLUGS] = 99;
|
||||
@@ -924,11 +924,6 @@ void InitClientResp(gclient_t *client)
|
||||
|
||||
client->resp.entertime = level.time;
|
||||
client->resp.coop_respawn = client->pers;
|
||||
|
||||
// ZOID
|
||||
if (G_TeamplayEnabled() && client->pers.connected && client->resp.ctf_team < CTF_TEAM1)
|
||||
CTFAssignTeam(client);
|
||||
// ZOID
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1051,7 +1046,9 @@ select_spawn_result_t SelectDeathmatchSpawnPoint(bool farthest, bool force_spawn
|
||||
if (spawn_points.size() == 0)
|
||||
{
|
||||
spot = G_FindByString<&edict_t::classname>(nullptr, "info_player_start");
|
||||
spawn_points.push_back({ spot, PlayersRangeFromSpot(spot) });
|
||||
|
||||
if (spot)
|
||||
spawn_points.push_back({ spot, PlayersRangeFromSpot(spot) });
|
||||
|
||||
// map is malformed
|
||||
if (spawn_points.size() == 0)
|
||||
@@ -1231,30 +1228,46 @@ static edict_t *SelectSingleSpawnPoint(edict_t *ent)
|
||||
}
|
||||
|
||||
// [Paril-KEX]
|
||||
static edict_t *G_UnsafeSpawnPosition(vec3_t spot)
|
||||
static edict_t *G_UnsafeSpawnPosition(vec3_t spot, bool check_players)
|
||||
{
|
||||
trace_t tr = gi.trace(spot, PLAYER_MINS, PLAYER_MAXS, spot, nullptr, MASK_PLAYERSOLID);
|
||||
contents_t mask = MASK_PLAYERSOLID;
|
||||
|
||||
if (!check_players)
|
||||
mask &= ~CONTENTS_PLAYER;
|
||||
|
||||
trace_t tr = gi.trace(spot, PLAYER_MINS, PLAYER_MAXS, spot, nullptr, mask);
|
||||
|
||||
// sometimes the spot is too close to the ground, give it a bit of slack
|
||||
if (tr.startsolid && !tr.ent->client)
|
||||
{
|
||||
spot[2] += 1;
|
||||
tr = gi.trace(spot, PLAYER_MINS, PLAYER_MAXS, spot, nullptr, MASK_PLAYERSOLID);
|
||||
tr = gi.trace(spot, PLAYER_MINS, PLAYER_MAXS, spot, nullptr, mask);
|
||||
}
|
||||
|
||||
// no idea why this happens in some maps..
|
||||
if (tr.startsolid && !tr.ent->client)
|
||||
return tr.ent;
|
||||
{
|
||||
// try a nudge
|
||||
if (G_FixStuckObject_Generic(spot, PLAYER_MINS, PLAYER_MAXS, [mask] (const vec3_t &start, const vec3_t &mins, const vec3_t &maxs, const vec3_t &end) {
|
||||
return gi.trace(start, mins, maxs, end, nullptr, mask);
|
||||
}) == stuck_result_t::NO_GOOD_POSITION)
|
||||
return tr.ent; // what do we do here...?
|
||||
|
||||
trace_t tr = gi.trace(spot, PLAYER_MINS, PLAYER_MAXS, spot, nullptr, mask);
|
||||
|
||||
if (tr.startsolid && !tr.ent->client)
|
||||
return tr.ent; // what do we do here...?
|
||||
}
|
||||
|
||||
if (tr.fraction == 1.f)
|
||||
return nullptr;
|
||||
else if (tr.ent->client)
|
||||
else if (check_players && tr.ent && tr.ent->client)
|
||||
return tr.ent;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
edict_t *SelectCoopSpawnPoint(edict_t *ent, bool force_spawn)
|
||||
edict_t *SelectCoopSpawnPoint(edict_t *ent, bool force_spawn, bool check_players)
|
||||
{
|
||||
edict_t *spot = nullptr;
|
||||
const char *target;
|
||||
@@ -1268,7 +1281,7 @@ edict_t *SelectCoopSpawnPoint(edict_t *ent, bool force_spawn)
|
||||
// try the main spawn point first
|
||||
spot = SelectSingleSpawnPoint(ent);
|
||||
|
||||
if (spot && !G_UnsafeSpawnPosition(spot->s.origin))
|
||||
if (spot && !G_UnsafeSpawnPosition(spot->s.origin, check_players))
|
||||
return spot;
|
||||
|
||||
spot = nullptr;
|
||||
@@ -1289,7 +1302,7 @@ edict_t *SelectCoopSpawnPoint(edict_t *ent, bool force_spawn)
|
||||
{ // this is a coop spawn point for one of the clients here
|
||||
num_valid_spots++;
|
||||
|
||||
if (!G_UnsafeSpawnPosition(spot->s.origin))
|
||||
if (!G_UnsafeSpawnPosition(spot->s.origin, check_players))
|
||||
return spot; // this is it
|
||||
}
|
||||
}
|
||||
@@ -1314,7 +1327,7 @@ edict_t *SelectCoopSpawnPoint(edict_t *ent, bool force_spawn)
|
||||
// this is a coop spawn point for one of the clients here
|
||||
num_valid_spots++;
|
||||
|
||||
if (!G_UnsafeSpawnPosition(spot->s.origin))
|
||||
if (!G_UnsafeSpawnPosition(spot->s.origin, check_players))
|
||||
return spot; // this is it
|
||||
}
|
||||
}
|
||||
@@ -1392,7 +1405,7 @@ bool TryLandmarkSpawn(edict_t* ent, vec3_t& origin, vec3_t& angles)
|
||||
// sometimes, landmark spawns can cause slight inconsistencies in collision;
|
||||
// we'll do a bit of tracing to make sure the bbox is clear
|
||||
if (G_FixStuckObject_Generic(origin, PLAYER_MINS, PLAYER_MAXS, [ent] (const vec3_t &start, const vec3_t &mins, const vec3_t &maxs, const vec3_t &end) {
|
||||
return gi.trace(start, mins, maxs, end, ent, MASK_PLAYERSOLID);
|
||||
return gi.trace(start, mins, maxs, end, ent, MASK_PLAYERSOLID & ~CONTENTS_PLAYER);
|
||||
}) == stuck_result_t::NO_GOOD_POSITION)
|
||||
{
|
||||
origin = old_origin;
|
||||
@@ -1451,11 +1464,26 @@ bool SelectSpawnPoint(edict_t *ent, vec3_t &origin, vec3_t &angles, bool force_s
|
||||
|
||||
if (coop->integer)
|
||||
{
|
||||
spot = SelectCoopSpawnPoint(ent, force_spawn);
|
||||
spot = SelectCoopSpawnPoint(ent, force_spawn, true);
|
||||
|
||||
if (!spot)
|
||||
spot = SelectCoopSpawnPoint(ent, force_spawn, false);
|
||||
|
||||
// no open spot yet
|
||||
if (!spot)
|
||||
{
|
||||
// in worst case scenario in coop during intermission, just spawn us at intermission
|
||||
// spot. this only happens for a single frame, and won't break
|
||||
// anything if they come back.
|
||||
if (level.intermissiontime)
|
||||
{
|
||||
origin = level.intermission_origin;
|
||||
angles = level.intermission_angle;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2227,15 +2255,20 @@ void PutClientInServer(edict_t *ent)
|
||||
{
|
||||
if (coop->integer)
|
||||
{
|
||||
if (edict_t *collision = G_UnsafeSpawnPosition(ent->s.origin); collision && collision->client)
|
||||
edict_t *collision = G_UnsafeSpawnPosition(ent->s.origin, true);
|
||||
|
||||
if (collision)
|
||||
{
|
||||
// link us early so that the other player sees us there
|
||||
gi.linkentity(ent);
|
||||
|
||||
// we spawned in somebody else, so we're going to change their spawn position
|
||||
bool lm = false;
|
||||
SelectSpawnPoint(collision, spawn_origin, spawn_angles, true, lm);
|
||||
PutClientOnSpawnPoint(collision, spawn_origin, spawn_angles);
|
||||
if (collision->client)
|
||||
{
|
||||
// we spawned in somebody else, so we're going to change their spawn position
|
||||
bool lm = false;
|
||||
SelectSpawnPoint(collision, spawn_origin, spawn_angles, true, lm);
|
||||
PutClientOnSpawnPoint(collision, spawn_origin, spawn_angles);
|
||||
}
|
||||
// else, no choice but to accept where ever we spawned :(
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2285,6 +2318,11 @@ void ClientBeginDeathmatch(edict_t *ent)
|
||||
|
||||
InitClientResp(ent->client);
|
||||
|
||||
// ZOID
|
||||
if (G_TeamplayEnabled() && ent->client->resp.ctf_team < CTF_TEAM1)
|
||||
CTFAssignTeam(ent->client);
|
||||
// ZOID
|
||||
|
||||
// PGM
|
||||
if (gamerules->integer && DMGame.ClientBegin)
|
||||
{
|
||||
@@ -2433,6 +2471,9 @@ void ClientBegin(edict_t *ent)
|
||||
ent->client->awaiting_respawn = false;
|
||||
ent->client->respawn_timeout = 0_ms;
|
||||
|
||||
// [Paril-KEX] we're always connected by this point...
|
||||
ent->client->pers.connected = true;
|
||||
|
||||
if (deathmatch->integer)
|
||||
{
|
||||
ClientBeginDeathmatch(ent);
|
||||
@@ -2732,7 +2773,7 @@ inline edict_t *ClientChooseSlot_Coop(const char *userinfo, const char *social_i
|
||||
// make sure we have a known default
|
||||
matches[i].slot->svflags |= SVF_PLAYER;
|
||||
|
||||
matches[i].slot->sv.init = true;
|
||||
matches[i].slot->sv.init = false;
|
||||
matches[i].slot->classname = "player";
|
||||
matches[i].slot->client->pers.connected = true;
|
||||
matches[i].slot->client->pers.spawned = true;
|
||||
@@ -2872,6 +2913,9 @@ bool ClientConnect(edict_t *ent, char *userinfo, const char *social_id, bool isB
|
||||
}
|
||||
|
||||
ent->client->pers.connected = true;
|
||||
|
||||
// [Paril-KEX] force a state update
|
||||
ent->sv.init = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3190,7 +3234,9 @@ void ClientThink(edict_t *ent, usercmd_t *ucmd)
|
||||
client->ps.pmove.pm_type = PM_NORMAL;
|
||||
|
||||
// [Paril-KEX]
|
||||
if (!G_ShouldPlayersCollide(false))
|
||||
if (!G_ShouldPlayersCollide(false) ||
|
||||
(coop->integer && !(ent->clipmask & CONTENTS_PLAYER)) // if player collision is on and we're temporarily ghostly...
|
||||
)
|
||||
client->ps.pmove.pm_flags |= PMF_IGNORE_PLAYER_COLLISION;
|
||||
else
|
||||
client->ps.pmove.pm_flags &= ~PMF_IGNORE_PLAYER_COLLISION;
|
||||
@@ -3248,7 +3294,8 @@ void ClientThink(edict_t *ent, usercmd_t *ucmd)
|
||||
|
||||
if (pm.s.pm_flags & PMF_ON_LADDER)
|
||||
{
|
||||
if (client->last_ladder_sound < level.time)
|
||||
if (!deathmatch->integer &&
|
||||
client->last_ladder_sound < level.time)
|
||||
{
|
||||
ent->s.event = EV_LADDER_STEP;
|
||||
client->last_ladder_sound = level.time + LADDER_SOUND_TIME;
|
||||
@@ -3407,12 +3454,15 @@ inline bool G_MonstersSearchingFor(edict_t *player)
|
||||
{
|
||||
for (auto ent : active_monsters())
|
||||
{
|
||||
// check for *any* player target
|
||||
if (player == nullptr && ent->enemy && !ent->enemy->client)
|
||||
continue;
|
||||
// they're not targeting us, so who cares
|
||||
if (ent->enemy != player)
|
||||
else if (player != nullptr && ent->enemy != player)
|
||||
continue;
|
||||
|
||||
// they lost sight of us
|
||||
if (ent->monsterinfo.aiflags & AI_LOST_SIGHT && level.time > ent->monsterinfo.trail_time + 5_sec)
|
||||
if ((ent->monsterinfo.aiflags & AI_LOST_SIGHT) && level.time > ent->monsterinfo.trail_time + 5_sec)
|
||||
continue;
|
||||
|
||||
// no sir
|
||||
@@ -3524,6 +3574,8 @@ inline bool G_FindRespawnSpot(edict_t *player, vec3_t &spot)
|
||||
// respawn target & position
|
||||
inline std::tuple<edict_t *, vec3_t> G_FindSquadRespawnTarget()
|
||||
{
|
||||
bool monsters_searching_for_anybody = G_MonstersSearchingFor(nullptr);
|
||||
|
||||
for (auto player : active_players())
|
||||
{
|
||||
// no dead players
|
||||
@@ -3545,6 +3597,14 @@ inline std::tuple<edict_t *, vec3_t> G_FindSquadRespawnTarget()
|
||||
continue;
|
||||
}
|
||||
|
||||
// check firing state; if any enemies are mad at any players,
|
||||
// don't respawn until everybody has cooled down
|
||||
if (monsters_searching_for_anybody && player->client->last_firing_time >= level.time)
|
||||
{
|
||||
player->client->coop_respawn_state = COOP_RESPAWN_IN_COMBAT;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check positioning; we must be on world ground
|
||||
if (player->groundentity != world)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user