From c347f1ede298c7f8af67a24ef46ef2c9032c93fe Mon Sep 17 00:00:00 2001 From: div0 Date: Wed, 11 Nov 2009 20:24:43 +0000 Subject: [PATCH] WAY better tuba thanks to CSQC magic. Try exec input-tuba.cfg, then tuba_staccato, then play with MIDI keyboard. Now all I need is splitting up the tuba samples into start+loop- and end-files, and we can hold notes for any time we want :P but even now it's already way better, as you can hit notes at (almost) any speed you want. Still no polyphony yet, but CSQC side supports it :P Also fix a warning in mathlib. git-svn-id: svn://svn.icculus.org/nexuiz/trunk@8270 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/balance.cfg | 4 +- data/balance25.cfg | 4 +- data/balanceHavoc.cfg | 4 +- data/balanceNexrun.cfg | 4 +- data/balanceSamual.cfg | 4 +- data/qcsrc/client/Main.qc | 2 + data/qcsrc/client/progs.src | 1 + data/qcsrc/client/tuba.qc | 47 +++++++++++++++++++ data/qcsrc/common/constants.qh | 1 + data/qcsrc/common/mathlib.qc | 2 +- data/qcsrc/server/w_tuba.qc | 85 ++++++++++++++++++++++++++++++---- 11 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 data/qcsrc/client/tuba.qc diff --git a/data/balance.cfg b/data/balance.cfg index 7b18e9ad1..14e9f9238 100644 --- a/data/balance.cfg +++ b/data/balance.cfg @@ -535,8 +535,8 @@ set g_balance_campingrifle_secondary_bulletconstant 130 // 18.3qu set g_balance_campingrifle_secondary_burstcost 0.35 // }}} // {{{ tuba -set g_balance_tuba_refire 0.25 -set g_balance_tuba_animtime 0.25 +set g_balance_tuba_refire 0.05 +set g_balance_tuba_animtime 0.05 set g_balance_tuba_attenuation 0.5 set g_balance_tuba_volume 1 set g_balance_tuba_damage 25 diff --git a/data/balance25.cfg b/data/balance25.cfg index cc350319d..151aab96e 100644 --- a/data/balance25.cfg +++ b/data/balance25.cfg @@ -535,8 +535,8 @@ set g_balance_campingrifle_secondary_bulletconstant 130 // 18.3qu set g_balance_campingrifle_secondary_burstcost 0 // }}} // {{{ tuba -set g_balance_tuba_refire 0.25 -set g_balance_tuba_animtime 0.25 +set g_balance_tuba_refire 0.05 +set g_balance_tuba_animtime 0.05 set g_balance_tuba_attenuation 0.5 set g_balance_tuba_volume 1 set g_balance_tuba_damage 25 diff --git a/data/balanceHavoc.cfg b/data/balanceHavoc.cfg index 00140740c..705cf282a 100644 --- a/data/balanceHavoc.cfg +++ b/data/balanceHavoc.cfg @@ -535,8 +535,8 @@ set g_balance_campingrifle_secondary_bulletconstant 130 // 18.3qu set g_balance_campingrifle_secondary_burstcost 0.35 // }}} // {{{ tuba -set g_balance_tuba_refire 0.25 -set g_balance_tuba_animtime 0.25 +set g_balance_tuba_refire 0.05 +set g_balance_tuba_animtime 0.05 set g_balance_tuba_attenuation 0.5 set g_balance_tuba_volume 1 set g_balance_tuba_damage 25 diff --git a/data/balanceNexrun.cfg b/data/balanceNexrun.cfg index f50cc722e..b0ca62fc1 100644 --- a/data/balanceNexrun.cfg +++ b/data/balanceNexrun.cfg @@ -536,8 +536,8 @@ set g_balance_campingrifle_secondary_bulletconstant 130 // 18.3qu set g_balance_campingrifle_secondary_burstcost 0.35 // }}} // {{{ tuba -set g_balance_tuba_refire 0.25 -set g_balance_tuba_animtime 0.25 +set g_balance_tuba_refire 0.05 +set g_balance_tuba_animtime 0.05 set g_balance_tuba_attenuation 0.5 set g_balance_tuba_volume 1 set g_balance_tuba_damage 25 diff --git a/data/balanceSamual.cfg b/data/balanceSamual.cfg index 2fd0bcdfc..1f7a025e0 100644 --- a/data/balanceSamual.cfg +++ b/data/balanceSamual.cfg @@ -536,8 +536,8 @@ set g_balance_campingrifle_secondary_bulletconstant 130 // 18.3qu set g_balance_campingrifle_secondary_burstcost 0.35 // }}} // {{{ tuba -set g_balance_tuba_refire 0.25 -set g_balance_tuba_animtime 0.25 +set g_balance_tuba_refire 0.05 +set g_balance_tuba_animtime 0.05 set g_balance_tuba_attenuation 0.5 set g_balance_tuba_volume 1 set g_balance_tuba_damage 25 diff --git a/data/qcsrc/client/Main.qc b/data/qcsrc/client/Main.qc index e8e141086..5222e917a 100644 --- a/data/qcsrc/client/Main.qc +++ b/data/qcsrc/client/Main.qc @@ -134,6 +134,7 @@ void CSQC_Init(void) Casings_Precache(); DamageInfo_Precache(); Announcer_Precache(); + Tuba_Precache(); get_mi_min_max_texcoords(1); // try the CLEVER way first minimapname = strcat("gfx/", mi_shortname, "_radar.tga"); @@ -825,6 +826,7 @@ void(float bIsNewEntity) CSQC_Ent_Update = case ENT_CLIENT_RANDOMSEED: Ent_RandomSeed(); break; case ENT_CLIENT_WALL: Ent_Wall(); break; case ENT_CLIENT_MODELEFFECT: Ent_ModelEffect(bIsNewEntity); break; + case ENT_CLIENT_TUBANOTE: Ent_TubaNote(bIsNewEntity); break; default: error(strcat("unknown entity type in CSQC_Ent_Update: ", ftos(self.enttype), "\n")); break; diff --git a/data/qcsrc/client/progs.src b/data/qcsrc/client/progs.src index e7be8c8ff..0221bfc8e 100644 --- a/data/qcsrc/client/progs.src +++ b/data/qcsrc/client/progs.src @@ -40,6 +40,7 @@ casings.qc effects.qc wall.qc modeleffects.qc +tuba.qc //vehicles/spiderbot.qc Main.qc diff --git a/data/qcsrc/client/tuba.qc b/data/qcsrc/client/tuba.qc new file mode 100644 index 000000000..deec78fc1 --- /dev/null +++ b/data/qcsrc/client/tuba.qc @@ -0,0 +1,47 @@ +//#define TUBA_STARTNOTE(n) strcat("weapons/tuba_startnote", ftos(n), ".wav") +//#define TUBA_STOPNOTE(n) strcat("weapons/tuba_stopnote", ftos(n), ".wav") +#define TUBA_STARTNOTE(n) strcat("weapons/tuba_note", ftos(n), ".wav") +#define TUBA_STOPNOTE(n) "" +.float cnt; // note + +void Ent_TubaNote_UpdateSound() +{ + sound(self, CHAN_PROJECTILE, TUBA_STARTNOTE(self.cnt), bound(0, VOL_BASE * cvar("g_balance_tuba_volume"), 1), cvar("g_balance_tuba_attenuation")); +} + +void Ent_TubaNote_StopSound() +{ + sound(self, CHAN_PROJECTILE, TUBA_STOPNOTE(self.cnt), bound(0, VOL_BASE * cvar("g_balance_tuba_volume"), 1), cvar("g_balance_tuba_attenuation")); +} + +void Ent_TubaNote(float bIsNew) +{ + float f, n; + f = ReadByte(); + n = floor(f / 2) - 42; + if(f & 1) + { + self.origin_x = ReadCoord(); + self.origin_y = ReadCoord(); + self.origin_z = ReadCoord(); + setorigin(self, self.origin); + } + self.think = Ent_TubaNote_StopSound; + self.entremove = Ent_TubaNote_StopSound; + self.nextthink = time + 10; + if(n != self.cnt || bIsNew) + { + self.cnt = n; + Ent_TubaNote_UpdateSound(); + } +} + +void Tuba_Precache() +{ + float i; + for(i = -18; i <= +27; ++i) + { + precache_sound(TUBA_STARTNOTE(i)); + //precache_sound(TUBA_STOPNOTE(i)); + } +} diff --git a/data/qcsrc/common/constants.qh b/data/qcsrc/common/constants.qh index 4e9fe23a3..f07309dec 100644 --- a/data/qcsrc/common/constants.qh +++ b/data/qcsrc/common/constants.qh @@ -88,6 +88,7 @@ const float ENT_CLIENT_RANDOMSEED = 19; const float ENT_CLIENT_WALL = 20; const float ENT_CLIENT_SPIDERBOT = 21; const float ENT_CLIENT_MODELEFFECT = 22; +const float ENT_CLIENT_TUBANOTE = 23; const float ENT_CLIENT_TURRET = 40; diff --git a/data/qcsrc/common/mathlib.qc b/data/qcsrc/common/mathlib.qc index 99d70c948..e96c62488 100644 --- a/data/qcsrc/common/mathlib.qc +++ b/data/qcsrc/common/mathlib.qc @@ -40,7 +40,7 @@ int isinf(float x) } int isnan(float x) { - return !(x == x); + return !(x + x == x + x); } int isnormal(float x) { diff --git a/data/qcsrc/server/w_tuba.qc b/data/qcsrc/server/w_tuba.qc index 89f8ad37c..1d8a1425c 100644 --- a/data/qcsrc/server/w_tuba.qc +++ b/data/qcsrc/server/w_tuba.qc @@ -1,5 +1,7 @@ -#define TUBA_NOTE(n) strcat("weapons/tuba_note", ftos(n), ".wav") +//#define TUBA_NOTE(n) strcat("weapons/tuba_note", ftos(n), ".wav") .float tuba_notecount; +.entity tuba_note; +.float tuba_smoketime; float Tuba_GetNote(entity pl, float hittype) { @@ -68,10 +70,29 @@ float Tuba_GetNote(entity pl, float hittype) return note; } +float W_Tuba_NoteSendEntity(entity to, float sf) +{ + WriteByte(MSG_ENTITY, ENT_CLIENT_TUBANOTE); + WriteByte(MSG_ENTITY, (sf & 1) | ((self.cnt + 42) * 2)); + if(sf & 1) + { + WriteCoord(MSG_ENTITY, self.origin_x); + WriteCoord(MSG_ENTITY, self.origin_y); + WriteCoord(MSG_ENTITY, self.origin_z); + } + return TRUE; +} + +void W_Tuba_NoteThink() +{ + self.owner.tuba_note = world; + remove(self); +} + void W_Tuba_Attack(float hittype) { vector o; - float c; + float c, n; W_SetupShot(self, FALSE, 2, "", cvar("g_balance_tuba_damage")); if(self.tuba_notecount) { @@ -83,11 +104,47 @@ void W_Tuba_Attack(float hittype) self.tuba_notecount = TRUE; c = CHAN_WEAPON2; } - sound(self, c, TUBA_NOTE(Tuba_GetNote(self, hittype)), bound(0, VOL_BASE * cvar("g_balance_tuba_volume"), 1), cvar("g_balance_tuba_attenuation")); + + n = Tuba_GetNote(self, hittype); + + if(self.tuba_note) + { + if(self.tuba_note.cnt != n) + { + /* + self.tuba_note.cnt = n; + self.tuba_note.SendFlags |= 2; + */ + remove(self.tuba_note); + self.tuba_note = world; + } + } + + if not(self.tuba_note) + { + self.tuba_note = spawn(); + self.tuba_note.owner = self; + self.tuba_note.cnt = n; + self.tuba_note.think = W_Tuba_NoteThink; + Net_LinkEntity(self.tuba_note, FALSE, 0, W_Tuba_NoteSendEntity); + } + + self.tuba_note.nextthink = time + cvar("g_balance_tuba_refire") * 2; // so it can get prolonged safely + if(self.origin != self.tuba_note.origin) + { + setorigin(self.tuba_note, self.origin); + self.tuba_note.SendFlags |= 1; + } + + //sound(self, c, TUBA_NOTE(n), bound(0, VOL_BASE * cvar("g_balance_tuba_volume"), 1), cvar("g_balance_tuba_attenuation")); RadiusDamage(self, self, cvar("g_balance_tuba_damage"), cvar("g_balance_tuba_edgedamage"), cvar("g_balance_tuba_radius"), world, cvar("g_balance_tuba_force"), hittype | WEP_TUBA, world); o = gettaginfo(self.exteriorweaponentity, 0); - pointparticles(particleeffectnum("smoke_ring"), o + v_up * 45 + v_right * -6 + v_forward * 8, v_up * 100, 1); + if(time > self.tuba_smoketime) + { + pointparticles(particleeffectnum("smoke_ring"), o + v_up * 45 + v_right * -6 + v_forward * 8, v_up * 100, 1); + self.tuba_smoketime = time + 0.25; + } } void spawnfunc_weapon_tuba (void) @@ -121,13 +178,23 @@ float w_tuba(float req) if (weapon_prepareattack(0, cvar("g_balance_tuba_refire"))) { W_Tuba_Attack(0); - weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_tuba_animtime"), w_ready); + //weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_tuba_animtime"), w_ready); + weapon_thinkf(WFRAME_IDLE, cvar("g_balance_tuba_animtime"), w_ready); } if (self.BUTTON_ATCK2) if (weapon_prepareattack(1, cvar("g_balance_tuba_refire"))) { W_Tuba_Attack(HITTYPE_SECONDARY); - weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_tuba_animtime"), w_ready); + //weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_tuba_animtime"), w_ready); + weapon_thinkf(WFRAME_IDLE, cvar("g_balance_tuba_animtime"), w_ready); + } + if(self.tuba_note) + { + if(!self.BUTTON_ATCK && !self.BUTTON_ATCK2) + { + remove(self.tuba_note); + self.tuba_note = world; + } } } else if (req == WR_PRECACHE) @@ -136,9 +203,9 @@ float w_tuba(float req) precache_model ("models/weapons/v_tuba.md3"); precache_model ("models/weapons/h_tuba.dpm"); - float i; - for(i = -18; i <= +27; ++i) - precache_sound(TUBA_NOTE(i)); + //float i; + //for(i = -18; i <= +27; ++i) + // precache_sound(TUBA_NOTE(i)); } else if (req == WR_SETUP) weapon_setup(WEP_TUBA); -- 2.39.2