From: Mircea Kitsune Date: Sat, 2 Apr 2011 15:07:26 +0000 (+0300) Subject: Attempt (once again) to implement constant player damage effects. eg: If the player... X-Git-Tag: xonotic-v0.6.0~110^2^2~192 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=e189b041a83858d7b8f02d673ae2cb58cac893df;p=xonotic%2Fxonotic-data.pk3dir.git Attempt (once again) to implement constant player damage effects. eg: If the player is shot with the uzi, blood will fall out of him for a few seconds. If he's shot with the electro, blue steam will come out of him instead. While if shot with a rocket, fire will come out of him. This is an effect only, and is not functional yet (just basic code in place). How it works: It uses the same system as blood and gibs. When the player is damaged, the server creates an entity that will constantly send a client entity with info (such as origin and damage weapon). The client then receives it, and spawns particles at the player's origin each time the entity is sent. Once the lifetime of the server-side sender expires, the effect stops. The reason the repeater can't be client side is because we can't track an individual player's origin there (or at least not that I know of). --- diff --git a/qcsrc/client/Main.qc b/qcsrc/client/Main.qc index 91ce46479..325cc409d 100644 --- a/qcsrc/client/Main.qc +++ b/qcsrc/client/Main.qc @@ -967,6 +967,7 @@ void(float bIsNewEntity) CSQC_Ent_Update = case ENT_CLIENT_LGBEAM: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_LGBEAM); break; case ENT_CLIENT_GAUNTLET: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_GAUNTLET); break; case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break; + case ENT_CLIENT_WEAPONDAMAGE: Ent_WeaponDamage(); break; default: error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype)); break; diff --git a/qcsrc/client/gibs.qc b/qcsrc/client/gibs.qc index 1f8af46ca..a6520d53d 100644 --- a/qcsrc/client/gibs.qc +++ b/qcsrc/client/gibs.qc @@ -274,3 +274,19 @@ void GibSplash_Precache() precache_sound ("misc/gib_splat03.wav"); precache_sound ("misc/gib_splat04.wav"); } + +void Ent_WeaponDamage() +{ + float type, specnum1, specnum2; + vector org; + string specstr; + + type = ReadByte(); // damage weapon + specnum1 = ReadByte(); // player species + org_x = ReadCoord(); + org_y = ReadCoord(); + org_z = ReadCoord(); + + specnum2 = (specnum1 & 0x78) / 8; // blood type: using four bits (0..7, bit indexes 3,4,5) + specstr = species_prefix(specnum2); +} diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index 419ab73e8..141ff000b 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -113,6 +113,7 @@ const float ENT_CLIENT_HOOK = 27; const float ENT_CLIENT_LGBEAM = 28; const float ENT_CLIENT_GAUNTLET = 29; const float ENT_CLIENT_ACCURACY = 30; +const float ENT_CLIENT_WEAPONDAMAGE = 31; const float ENT_CLIENT_TURRET = 40; diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 29fc297d5..b062ec32a 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -497,6 +497,8 @@ entity damage_attacker; void Damage (entity targ, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) { + dprint(strcat(ftos(DEATH_WEAPONOF(deathtype)), "--\n")); + float mirrordamage; float mirrorforce; float teamdamage0; diff --git a/qcsrc/server/g_violence.qc b/qcsrc/server/g_violence.qc index f5def6a7d..ba1ae0d9c 100644 --- a/qcsrc/server/g_violence.qc +++ b/qcsrc/server/g_violence.qc @@ -37,3 +37,59 @@ void Violence_GibSplash(entity source, float type, float amount, entity attacker { Violence_GibSplash_At(source.origin + source.view_ofs, source.velocity, type, amount, source, attacker); } + +float Violence_WeaponDamage_SendEntity(entity to, float sf) +{ + WriteByte(MSG_ENTITY, ENT_CLIENT_WEAPONDAMAGE); + WriteByte(MSG_ENTITY, self.cnt); // the damage weapon + WriteByte(MSG_ENTITY, self.state); // species + WriteCoord(MSG_ENTITY, floor(self.origin_x)); + WriteCoord(MSG_ENTITY, floor(self.origin_y)); + WriteCoord(MSG_ENTITY, floor(self.origin_z)); + return TRUE; +} + +void Violence_WeaponDamage(entity pl, float type) +{ + entity e; + + e = spawn(); + e.classname = "weapondamage"; + e.cnt = type; + e.state |= 8 * pl.species; // gib type, ranges from 0 to 15 + setorigin(e, pl.origin); + + Net_LinkEntity(e, FALSE, 0.2, Violence_WeaponDamage_SendEntity); +} + +.float lifetime; +.float weapondamage_counter; + +void Violence_WeaponDamage_DoRepeat() +{ + if(time > self.lifetime) + { + self.nextthink = 0; + remove(self); + return; + } + + if(time > self.weapondamage_counter) + { + Violence_WeaponDamage(self.owner, self.cnt); + self.weapondamage_counter = time + 0.5; // TO BE CVARED + } +} + +void Violence_WeaponDamage_SetRepeat(entity pl, float type) +{ + entity repeater; + repeater = spawn(); + repeater.classname = "weapondamage_repeater"; + repeater.owner = pl; + repeater.origin = pl.origin; + repeater.cnt = type; + repeater.lifetime = time + 3; // TO BE CVARED + repeater.think = Violence_WeaponDamage_DoRepeat; + repeater.nextthink = time; +}