From: terencehill Date: Sat, 27 Oct 2018 10:51:37 +0000 (+0200) Subject: Merge branch 'terencehill/bot_waypoints' X-Git-Tag: xonotic-v0.8.5~1742 X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=8639f042c5ef61287b2f7e0dbf17f8c08a2c0ebf;hp=a692581c23cc689f1f695dd04b6b2a2b27a567f0 Merge branch 'terencehill/bot_waypoints' --- diff --git a/qcsrc/client/csqcmodel_hooks.qc b/qcsrc/client/csqcmodel_hooks.qc index 522859c8b1..0b62704c5b 100644 --- a/qcsrc/client/csqcmodel_hooks.qc +++ b/qcsrc/client/csqcmodel_hooks.qc @@ -18,8 +18,6 @@ .float death_time; .int modelflags; -.bool isplayermodel; - // FEATURE: LOD .int lodmodelindex0; .int lodmodelindex1; @@ -415,7 +413,7 @@ void CSQCModel_AutoTagIndex_Apply(entity this) // recursive predraw call to fix issues with forcemodels and LOD if bone indexes mismatch if(this.tag_entity.classname == "csqcmodel") { - CSQCModel_Hook_PreDraw(this.tag_entity, (this.tag_entity.entnum >= 1 && this.tag_entity.entnum <= maxclients)); + CSQCModel_Hook_PreDraw(this.tag_entity, (this.tag_entity.isplayermodel & ISPLAYER_CLIENT)); } if(this.tag_entity.modelindex != this.tag_entity_lastmodelindex) @@ -610,7 +608,7 @@ void CSQCModel_Hook_PreDraw(entity this, bool isplayer) if(this.isplayermodel && this.drawmask) // this checks if it's a player MODEL! { - CSQCPlayer_ModelAppearance_Apply(this, this.entnum == player_localnum + 1); + CSQCPlayer_ModelAppearance_Apply(this, (this.isplayermodel & ISPLAYER_LOCAL)); CSQCPlayer_LOD_Apply(this); if(!isplayer) @@ -710,7 +708,9 @@ void CSQCModel_Hook_PreUpdate(entity this, bool isnew, bool isplayer, bool isloc void CSQCModel_Hook_PostUpdate(entity this, bool isnew, bool isplayer, bool islocalplayer) { // is it a player model? (shared state) - this.isplayermodel = (substring(this.model, 0, 14) == "models/player/" || substring(this.model, 0, 17) == "models/ok_player/" || (substring(this.model, 0, 16) == "models/monsters/" && (this.entnum >= 1 && this.entnum <= maxclients))); + bool is_playermodel = (substring(this.model, 0, 14) == "models/player/" || substring(this.model, 0, 17) == "models/ok_player/" || + (substring(this.model, 0, 16) == "models/monsters/" && (this.isplayermodel & BIT(1)))); + this.isplayermodel = BITSET(this.isplayermodel, ISPLAYER_MODEL, is_playermodel); // save values set by server if(this.isplayermodel) diff --git a/qcsrc/client/csqcmodel_hooks.qh b/qcsrc/client/csqcmodel_hooks.qh index 8ed256379f..f952d0b0a0 100644 --- a/qcsrc/client/csqcmodel_hooks.qh +++ b/qcsrc/client/csqcmodel_hooks.qh @@ -23,6 +23,8 @@ const int MF_TRACER3 = BIT(7); // purple trail .int csqcmodel_modelflags; .int csqcmodel_traileffect; +.int isplayermodel; + void CSQCModel_Effects_Apply(entity this); void CSQCModel_Hook_PreDraw(entity this, bool isplayer); diff --git a/qcsrc/common/effects/qc/damageeffects.qc b/qcsrc/common/effects/qc/damageeffects.qc index 1fc64d1d25..7ab6697c34 100644 --- a/qcsrc/common/effects/qc/damageeffects.qc +++ b/qcsrc/common/effects/qc/damageeffects.qc @@ -53,7 +53,6 @@ void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad .float cnt; .int state; -.bool isplayermodel; void DamageEffect_Think(entity this) { @@ -79,7 +78,7 @@ void DamageEffect_Think(entity this) return; } this.state = this.owner.csqcmodel_isdead; - if(this.owner.isplayermodel && (this.owner.entnum == player_localentnum) && !autocvar_chase_active) + if(this.owner.isplayermodel && (this.owner.isplayermodel & ISPLAYER_LOCAL) && !autocvar_chase_active) return; // if we aren't using a third person camera, hide our own effects // now generate the particles diff --git a/qcsrc/common/ent_cs.qc b/qcsrc/common/ent_cs.qc index 86acdc1540..7b4c54f9f6 100644 --- a/qcsrc/common/ent_cs.qc +++ b/qcsrc/common/ent_cs.qc @@ -164,23 +164,23 @@ ENTCS_PROP(FRAGS, true, frags, ENTCS_SET_NORMAL, void entcs_attach(entity player) { - entity e = player.entcs = new(entcs_sender); + entity e = CS(player).entcs = new(entcs_sender); e.owner = player; setthink(e, entcs_think); e.nextthink = time; Net_LinkEntity(e, false, 0, entcs_send); if (!IS_REAL_CLIENT(player)) return; FOREACH_CLIENT(true, { - assert(it.entcs); - _entcs_send(it.entcs, msg_entity = player, BITS(23), MSG_ONE); + assert(CS(it).entcs); + _entcs_send(CS(it).entcs, msg_entity = player, BITS(23), MSG_ONE); }); } void entcs_detach(entity player) { - if (!player.entcs) return; - delete(player.entcs); - player.entcs = NULL; + if (!CS(player).entcs) return; + delete(CS(player).entcs); + CS(player).entcs = NULL; } #endif diff --git a/qcsrc/common/ent_cs.qh b/qcsrc/common/ent_cs.qh index 0180fea784..3a9f084bcf 100644 --- a/qcsrc/common/ent_cs.qh +++ b/qcsrc/common/ent_cs.qh @@ -43,7 +43,7 @@ REGISTER_NET_TEMP(CLIENT_ENTCS) .int m_forceupdate; /** Force an origin update, for player sounds */ - #define entcs_force_origin(e) ((e).entcs.m_forceupdate = BIT(2)) + #define entcs_force_origin(e) (CS(e).entcs.m_forceupdate = BIT(2)) #endif diff --git a/qcsrc/common/items/inventory.qh b/qcsrc/common/items/inventory.qh index ba824f40b4..2ec0cdb7b1 100644 --- a/qcsrc/common/items/inventory.qh +++ b/qcsrc/common/items/inventory.qh @@ -106,20 +106,23 @@ bool Inventory_Send(Inventory this, Client to, int sf) { TC(Inventory, this); WriteHeader(MSG_ENTITY, ENT_CLIENT_INVENTORY); - entity e = this.owner; - if (IS_SPEC(e)) e = PS(e.enemy); // TODO: how can this *ever* be the case? - TC(Player, e); - Inventory data = e.inventory; - Inventory_Write(data); + TC(PlayerState, this.owner); + Inventory_Write(this); return true; } -void Inventory_new(entity e) +bool Inventory_customize(entity this, entity client) +{ + // sends to spectators too! + return (PS(client) && PS(client).inventory == this); +} + +void Inventory_new(PlayerState this) { Inventory inv = NEW(Inventory), bak = NEW(Inventory); inv.inventory = bak; - inv.drawonlytoclient = IS_CLIENT(e) ? e : e.m_client; - Net_LinkEntity((inv.owner = e).inventory = inv, false, 0, Inventory_Send); + setcefc(inv, Inventory_customize); + Net_LinkEntity((inv.owner = this).inventory = inv, false, 0, Inventory_Send); } void Inventory_delete(entity e) { delete(e.inventory.inventory); delete(e.inventory); } void Inventory_update(entity e) { e.inventory.SendFlags = 0xFFFFFF; } diff --git a/qcsrc/common/physics/player.qh b/qcsrc/common/physics/player.qh index 29c028f032..9ecf7eab71 100644 --- a/qcsrc/common/physics/player.qh +++ b/qcsrc/common/physics/player.qh @@ -190,8 +190,8 @@ STATIC_INIT(PHYS_INPUT_BUTTON) .entity hook; // TODO - #define IS_CLIENT(s) ((s).isplayermodel || (s) == csqcplayer) - #define IS_PLAYER(s) ((s).isplayermodel) + #define IS_CLIENT(s) (((s).isplayermodel & ISPLAYER_CLIENT) || (s) == csqcplayer) + #define IS_PLAYER(s) ((s).isplayermodel & ISPLAYER_PLAYER) #define IS_NOT_A_CLIENT(s) (!(s).isplayermodel && (s) != csqcplayer) #define isPushable(s) ((s).isplayermodel || (s).pushable || ((s).flags & FL_PROJECTILE)) diff --git a/qcsrc/common/state.qc b/qcsrc/common/state.qc index 2e3a262a59..2a1168eae0 100644 --- a/qcsrc/common/state.qc +++ b/qcsrc/common/state.qc @@ -1,6 +1,6 @@ #include "state.qh" -void Inventory_new(entity this); +void Inventory_new(PlayerState this); void Inventory_delete(entity this); void PlayerState_attach(entity this) @@ -68,12 +68,11 @@ void ClientState_detach(entity this) PlayerScore_Detach(this); // what ^they^ said W_HitPlotClose(this); ClientData_Detach(this); + entcs_detach(this); delete(CS(this)); this._cs = NULL; - bot_clientdisconnect(this); anticheat_report_to_eventlog(this); - entcs_detach(this); } diff --git a/qcsrc/lib/csqcmodel/cl_model.qc b/qcsrc/lib/csqcmodel/cl_model.qc index 05aba388c4..12be0dbaa4 100644 --- a/qcsrc/lib/csqcmodel/cl_model.qc +++ b/qcsrc/lib/csqcmodel/cl_model.qc @@ -179,7 +179,7 @@ void CSQCModel_InterpolateAnimation_Do(entity this) void CSQCModel_Draw(entity this) { // some nice flags for CSQCMODEL_IF and the hooks - bool isplayer = (this.entnum >= 1 && this.entnum <= maxclients); + bool isplayer = (this.isplayermodel & ISPLAYER_CLIENT); noref bool islocalplayer = (this.entnum == player_localnum + 1); noref bool isnolocalplayer = (isplayer && (this.entnum != player_localnum + 1)); @@ -223,9 +223,10 @@ void CSQCModel_remove(entity this) NET_HANDLE(ENT_CLIENT_MODEL, bool isnew) { int sf = ReadInt24_t(); + int psf = ReadByte(); // some nice flags for CSQCMODEL_IF and the hooks - bool isplayer = ReadByte() || (this.entnum >= 1 && this.entnum <= maxclients); + bool isplayer = (psf & ISPLAYER_CLIENT) || (this.entnum >= 1 && this.entnum <= maxclients); if (isnew && isplayer) { CSQCModel_players[this.entnum - 1] = this; @@ -234,6 +235,10 @@ NET_HANDLE(ENT_CLIENT_MODEL, bool isnew) bool islocalplayer = (this.entnum == player_localnum + 1); noref bool isnolocalplayer = (isplayer && !islocalplayer); + this.isplayermodel = BITSET(this.isplayermodel, ISPLAYER_CLIENT, isplayer); + this.isplayermodel = BITSET(this.isplayermodel, ISPLAYER_LOCAL, islocalplayer); + this.isplayermodel = BITSET(this.isplayermodel, ISPLAYER_PLAYER, (psf & ISPLAYER_PLAYER)); + this.classname = "csqcmodel"; this.iflags |= IFLAG_ORIGIN; // interpolate origin too this.iflags |= IFLAG_ANGLES; // interpolate angles too diff --git a/qcsrc/lib/csqcmodel/common.qh b/qcsrc/lib/csqcmodel/common.qh index f8375d09e8..a2c9e68e55 100644 --- a/qcsrc/lib/csqcmodel/common.qh +++ b/qcsrc/lib/csqcmodel/common.qh @@ -53,6 +53,11 @@ IN THE SOFTWARE.\ .float frame2time; .float lerpfrac; +const int ISPLAYER_MODEL = BIT(0); // using a player model +const int ISPLAYER_CLIENT = BIT(1); // is a client +const int ISPLAYER_LOCAL = BIT(2); // is the local player +const int ISPLAYER_PLAYER = BIT(3); // is a player in the match + const int CSQCMODEL_PROPERTY_FRAME = BIT(23); const int CSQCMODEL_PROPERTY_TELEPORTED = BIT(22); // the "teleport bit" cancelling interpolation const int CSQCMODEL_PROPERTY_MODELINDEX = BIT(21); diff --git a/qcsrc/lib/csqcmodel/sv_model.qc b/qcsrc/lib/csqcmodel/sv_model.qc index 0ff4389944..584bfc23ff 100644 --- a/qcsrc/lib/csqcmodel/sv_model.qc +++ b/qcsrc/lib/csqcmodel/sv_model.qc @@ -32,9 +32,14 @@ bool CSQCModel_Send(entity this, entity to, int sf) noref bool islocalplayer = (this == to); noref bool isnolocalplayer = (isplayer && (this != to)); + int psf = 0; + psf = BITSET(psf, ISPLAYER_CLIENT, isplayer); + psf = BITSET(psf, ISPLAYER_LOCAL, islocalplayer); + psf = BITSET(psf, ISPLAYER_PLAYER, IS_PLAYER(this)); + WriteHeader(MSG_ENTITY, ENT_CLIENT_MODEL); WriteInt24_t(MSG_ENTITY, sf); - WriteByte(MSG_ENTITY, isplayer); + WriteByte(MSG_ENTITY, psf); #define CSQCMODEL_IF(cond) if(cond) { #define CSQCMODEL_ENDIF } diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index e9ab3d79ac..1b8f838aa4 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -689,12 +689,9 @@ void Damage(entity targ, entity inflictor, entity attacker, float damage, int de } } - if(STAT(FROZEN, targ)) - if(deathtype != DEATH_HURTTRIGGER.m_id && deathtype != DEATH_TEAMCHANGE.m_id && deathtype != DEATH_AUTOTEAMCHANGE.m_id) + if(deathtype != DEATH_HURTTRIGGER.m_id && deathtype != DEATH_TEAMCHANGE.m_id && deathtype != DEATH_AUTOTEAMCHANGE.m_id && STAT(FROZEN, targ)) { - if(autocvar_g_frozen_revive_falldamage > 0) - if(deathtype == DEATH_FALL.m_id) - if(damage >= autocvar_g_frozen_revive_falldamage) + if(autocvar_g_frozen_revive_falldamage > 0 && deathtype == DEATH_FALL.m_id && damage >= autocvar_g_frozen_revive_falldamage) { Unfreeze(targ, false); SetResourceAmount(targ, RESOURCE_HEALTH, autocvar_g_frozen_revive_falldamage_health); @@ -707,7 +704,7 @@ void Damage(entity targ, entity inflictor, entity attacker, float damage, int de force *= autocvar_g_frozen_force; } - if(STAT(FROZEN, targ) && deathtype == DEATH_HURTTRIGGER.m_id && !autocvar_g_frozen_damage_trigger) + if(IS_PLAYER(targ) && STAT(FROZEN, targ) && deathtype == DEATH_HURTTRIGGER.m_id && !autocvar_g_frozen_damage_trigger) { Send_Effect(EFFECT_TELEPORT, targ.origin, '0 0 0', 1);