{
int n = ReadByte();
entity e = entcs_receiver(n);
- #define X(e) { \
- setthink(e, entcs_think); \
- entcs_receiver(n, e); \
- }
if (e == NULL)
{
if (!this)
- {
// initial = temp
e = new_pure(entcs_receiver);
- X(e);
- }
else
- {
// initial = linked
e = this;
- X(e);
- }
+ setthink(e, entcs_think);
+ entcs_receiver(n, e);
}
else if (e != this && this)
{
// upgrade to linked
delete(e);
e = this;
- X(e);
+ setthink(e, entcs_think);
+ entcs_receiver(n, e);
}
- #undef X
+
InterpolateOrigin_Undo(e);
e.sv_entnum = n;
int sf = ReadShort();
#pragma once
+#include <common/t_items.qh>
const int IT_UNLIMITED_WEAPON_AMMO = BIT(0); // when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup.
const int IT_UNLIMITED_SUPERWEAPONS = BIT(1); // when this bit is set, superweapons don't expire. Checkpoints can give this powerup.
ATTRIB(GameItem, m_color, vector, '1 1 1');
ATTRIB(GameItem, m_waypoint, string);
ATTRIB(GameItem, m_waypointblink, int, 1);
+#ifdef GAMEQC
+ ATTRIB(GameItem, m_glow, bool, false);
+ ATTRIB(GameItem, m_respawnsound, Sound, SND_ITEMRESPAWN);
+#endif
METHOD(GameItem, display, void(GameItem this, void(string name, string icon) returns))
{
TC(GameItem, this);
#ifdef GAMEQC
this.m_model = MDL_Strength_ITEM;
this.m_sound = SND_Strength;
+ this.m_glow = true;
+ this.m_respawnsound = SND_STRENGTH_RESPAWN;
#endif
this.m_name = "Strength Powerup";
this.m_icon = "strength";
#ifdef GAMEQC
this.m_model = MDL_Shield_ITEM;
this.m_sound = SND_Shield;
+ this.m_glow = true;
+ this.m_respawnsound = SND_SHIELD_RESPAWN;
#endif
this.m_name = "Shield";
this.m_icon = "shield";
#define DAMAGETEXT_PRECISION_MULTIPLIER 128
#define DAMAGETEXT_SHORT_LIMIT 256 // the smallest value that we can't send as short - 2^15 (signed short) / DAMAGETEXT_PRECISION_MULTIPLIER
+const int DTFLAG_SAMETEAM = BIT(0);
+const int DTFLAG_BIG_HEALTH = BIT(1);
+const int DTFLAG_BIG_ARMOR = BIT(2);
+const int DTFLAG_BIG_POTENTIAL = BIT(3);
+const int DTFLAG_NO_ARMOR = BIT(4);
+const int DTFLAG_NO_POTENTIAL = BIT(5);
+
REGISTER_MUTATOR(damagetext, true);
#if defined(CSQC) || defined(MENUQC)
// no translatable cvar description please
AUTOCVAR_SAVE(cl_damagetext, bool, true, "Draw damage dealt where you hit the enemy");
-AUTOCVAR_SAVE(cl_damagetext_format, string, "-{total}", "How to format the damage text. {health}, {armor}, {total}, {potential}, {potential_health}");
+AUTOCVAR_SAVE(cl_damagetext_format, string, "-{total}", "How to format the damage text. {health}, {armor}, {total}, {potential}, {potential_health}");
STATIC_INIT(DamageText_LegacyFormat) {
if (strstrofs(autocvar_cl_damagetext_format, "{", 0) < 0) autocvar_cl_damagetext_format = "-{total}";
}
(SV_DAMAGETEXT_SPECTATORS_ONLY() && IS_SPEC(it) && it.enemy == attacker) ||
(SV_DAMAGETEXT_SPECTATORS_ONLY() && IS_OBSERVER(it))
) {
- int flags = SAME_TEAM(hit, attacker); // BIT(0)
- if (health >= DAMAGETEXT_SHORT_LIMIT) flags |= BIT(1);
- if (armor >= DAMAGETEXT_SHORT_LIMIT) flags |= BIT(2);
- if (potential_damage >= DAMAGETEXT_SHORT_LIMIT) flags |= BIT(3);
+ int flags = 0;
+ if (SAME_TEAM(hit, attacker)) flags |= DTFLAG_SAMETEAM;
+ if (health >= DAMAGETEXT_SHORT_LIMIT) flags |= DTFLAG_BIG_HEALTH;
+ if (armor >= DAMAGETEXT_SHORT_LIMIT) flags |= DTFLAG_BIG_ARMOR;
+ if (potential_damage >= DAMAGETEXT_SHORT_LIMIT) flags |= DTFLAG_BIG_POTENTIAL;
+ if (!armor) flags |= DTFLAG_NO_ARMOR;
+ if (fabs((armor + health) - potential_damage) < 0.0001) flags |= DTFLAG_NO_POTENTIAL;
msg_entity = it;
WriteHeader(MSG_ONE, damagetext);
// we need to send a few decimal places to minimize errors when accumulating damage
// sending them multiplied saves bandwidth compared to using WriteCoord,
// however if the multiplied damage would be too much for (signed) short, we send an int24
- if (health >= DAMAGETEXT_SHORT_LIMIT) WriteInt24_t(MSG_ONE, health * DAMAGETEXT_PRECISION_MULTIPLIER);
+ if (flags & DTFLAG_BIG_HEALTH) WriteInt24_t(MSG_ONE, health * DAMAGETEXT_PRECISION_MULTIPLIER);
else WriteShort(MSG_ONE, health * DAMAGETEXT_PRECISION_MULTIPLIER);
- if (armor >= DAMAGETEXT_SHORT_LIMIT) WriteInt24_t(MSG_ONE, armor * DAMAGETEXT_PRECISION_MULTIPLIER);
- else WriteShort(MSG_ONE, armor * DAMAGETEXT_PRECISION_MULTIPLIER);
- if (potential_damage >= DAMAGETEXT_SHORT_LIMIT) WriteInt24_t(MSG_ONE, potential_damage * DAMAGETEXT_PRECISION_MULTIPLIER);
- else WriteShort(MSG_ONE, potential_damage * DAMAGETEXT_PRECISION_MULTIPLIER);
+ if (!(flags & DTFLAG_NO_ARMOR))
+ {
+ if (flags & DTFLAG_BIG_ARMOR) WriteInt24_t(MSG_ONE, armor * DAMAGETEXT_PRECISION_MULTIPLIER);
+ else WriteShort(MSG_ONE, armor * DAMAGETEXT_PRECISION_MULTIPLIER);
+ }
+ if (!(flags & DTFLAG_NO_POTENTIAL))
+ {
+ if (flags & DTFLAG_BIG_POTENTIAL) WriteInt24_t(MSG_ONE, potential_damage * DAMAGETEXT_PRECISION_MULTIPLIER);
+ else WriteShort(MSG_ONE, potential_damage * DAMAGETEXT_PRECISION_MULTIPLIER);
+ }
}
));
}
vector location = vec3(ReadCoord(), ReadCoord(), ReadCoord());
int deathtype = ReadInt24_t();
int flags = ReadByte();
- bool friendlyfire = flags & 1;
+ bool friendlyfire = flags & DTFLAG_SAMETEAM;
int health, armor, potential_damage;
- if (flags & BIT(1)) health = ReadInt24_t();
+ if (flags & DTFLAG_BIG_HEALTH) health = ReadInt24_t();
else health = ReadShort();
- if (flags & BIT(2)) armor = ReadInt24_t();
+ if (flags & DTFLAG_NO_ARMOR) armor = 0;
+ else if (flags & DTFLAG_BIG_ARMOR) armor = ReadInt24_t();
else armor = ReadShort();
- if (flags & BIT(3)) potential_damage = ReadInt24_t();
+ if (flags & DTFLAG_NO_POTENTIAL) potential_damage = health + armor;
+ else if (flags & DTFLAG_BIG_POTENTIAL) potential_damage = ReadInt24_t();
else potential_damage = ReadShort();
return = true;
{
entity item = M_ARGV(0, entity);
- switch (item.items)
+ switch (item.itemdef)
{
- case ITEM_HealthSmall.m_itemid:
- case ITEM_ArmorSmall.m_itemid:
+ case ITEM_HealthSmall:
+ case ITEM_ArmorSmall:
return false;
}
{
entity item = M_ARGV(0, entity);
- switch (item.items)
+ if(item.itemdef.instanceOfHealth || item.itemdef.instanceOfArmor)
{
- case ITEM_HealthSmall.m_itemid:
- case ITEM_HealthMedium.m_itemid:
- case ITEM_HealthLarge.m_itemid:
- case ITEM_HealthMega.m_itemid:
- case ITEM_ArmorSmall.m_itemid:
- case ITEM_ArmorMedium.m_itemid:
- case ITEM_ArmorLarge.m_itemid:
- case ITEM_ArmorMega.m_itemid:
- if (autocvar_g_nix_with_healtharmor)
- return false;
- break;
- case ITEM_Strength.m_itemid:
- case ITEM_Shield.m_itemid:
- if (autocvar_g_nix_with_powerups)
- return false;
- break;
+ return !autocvar_g_nix_with_healtharmor;
+ }
+ else if(item.itemdef.instanceOfPowerup)
+ {
+ return !autocvar_g_nix_with_powerups;
}
return true; // delete all other items
if(this.ItemStatus & ITS_ALLOWFB)
this.effects |= EF_FULLBRIGHT;
- if(this.ItemStatus & ITS_POWERUP)
+ if(this.ItemStatus & ITS_GLOW)
{
if(this.ItemStatus & ITS_AVAILABLE)
this.effects |= (EF_ADDITIVE | EF_FULLBRIGHT);
{
e.effects &= ~(EF_ADDITIVE | EF_STARDUST | EF_FULLBRIGHT | EF_NODEPTHTEST);
e.ItemStatus &= ~ITS_STAYWEP;
+ entity def = e.itemdef;
if (mode > 0)
{
// make the item look normal, and be touchable
e.ItemStatus &= ~ITS_AVAILABLE;
}
else {
- entity def = e.itemdef;
bool nostay = def.instanceOfWeaponPickup ? !!(def.m_weapon.weapons & WEPSET_SUPERWEAPONS) : false // no weapon-stay on superweapons
|| e.team // weapon stay isn't supported for teamed weapons
;
e.ItemStatus &= ~ITS_AVAILABLE;
}}
- if (e.items & ITEM_Strength.m_itemid || e.items & ITEM_Shield.m_itemid)
- e.ItemStatus |= ITS_POWERUP;
+ if (def.m_glow)
+ e.ItemStatus |= ITS_GLOW;
if (autocvar_g_nodepthtestitems)
e.effects |= EF_NODEPTHTEST;
void Item_Respawn (entity this)
{
Item_Show(this, 1);
- // this is ugly...
- if(this.items == ITEM_Strength.m_itemid)
- sound (this, CH_TRIGGER, SND_STRENGTH_RESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound
- else if(this.items == ITEM_Shield.m_itemid)
- sound (this, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound
- else
- sound (this, CH_TRIGGER, SND_ITEMRESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound
+ sound(this, CH_TRIGGER, this.itemdef.m_respawnsound, VOL_BASE, ATTEN_NORM); // play respawn sound
setorigin(this, this.origin);
if (Item_ItemsTime_Allow(this.itemdef) || this.weapons & WEPSET_SUPERWEAPONS)
const int ITS_AVAILABLE = BIT(3);
const int ITS_ALLOWFB = BIT(4);
const int ITS_ALLOWSI = BIT(5);
- const int ITS_POWERUP = BIT(6);
+ const int ITS_GLOW = BIT(6);
const int ISF_COLORMAP = BIT(4);
const int ISF_DROP = BIT(5);
const int ISF_ANGLES = BIT(6);