#if defined(CSQC) #elif defined(MENUQC) #elif defined(SVQC) #include "../../constants.qh" #include "../../../server/constants.qh" #include "../../../server/defs.qh" #endif REGISTER_NET_TEMP(TE_CSQC_TARGET_MUSIC) REGISTER_NET_LINKED(ENT_CLIENT_TRIGGER_MUSIC) #ifdef SVQC // values: // volume // noise // targetname // lifetime // fade_time // fade_rate // when triggered, the music is overridden for activator until lifetime (or forever, if lifetime is 0) // when targetname is not set, THIS ONE is default void target_music_sendto(float to, float is) {SELFPARAM(); WriteHeader(to, TE_CSQC_TARGET_MUSIC); WriteShort(to, num_for_edict(self)); WriteByte(to, self.volume * 255.0 * is); WriteByte(to, self.fade_time * 16.0); WriteByte(to, self.fade_rate * 16.0); WriteByte(to, self.lifetime); WriteString(to, self.noise); } void target_music_reset(entity this) { if (this.targetname == "") target_music_sendto(MSG_ALL, 1); } void target_music_kill() { for(self = world; (self = find(self, classname, "target_music")); ) { self.volume = 0; if(self.targetname == "") target_music_sendto(MSG_ALL, 1); else target_music_sendto(MSG_ALL, 0); } } void target_music_use() { if(!activator) return; if(IS_REAL_CLIENT(activator)) { msg_entity = activator; target_music_sendto(MSG_ONE, 1); } entity head; FOR_EACH_SPEC(head) if(head.enemy == activator) { msg_entity = head; target_music_sendto(MSG_ONE, 1); } } spawnfunc(target_music) { self.use = target_music_use; self.reset = target_music_reset; if(!self.volume) self.volume = 1; if(self.targetname == "") target_music_sendto(MSG_INIT, 1); else target_music_sendto(MSG_INIT, 0); } void TargetMusic_RestoreGame() {SELFPARAM(); for(entity e = world; (e = find(e, classname, "target_music")); ) { setself(e); if(self.targetname == "") target_music_sendto(MSG_INIT, 1); else target_music_sendto(MSG_INIT, 0); } } // values: // volume // noise // targetname // fade_time // spawnflags: // 1 = START_OFF // when triggered, it is disabled/enabled for everyone bool trigger_music_SendEntity(entity this, entity to, float sf) { WriteHeader(MSG_ENTITY, ENT_CLIENT_TRIGGER_MUSIC); sf &= ~0x80; if(self.cnt) sf |= 0x80; WriteByte(MSG_ENTITY, sf); if(sf & 4) { WriteCoord(MSG_ENTITY, self.origin.x); WriteCoord(MSG_ENTITY, self.origin.y); WriteCoord(MSG_ENTITY, self.origin.z); } if(sf & 1) { if(self.model != "null") { WriteShort(MSG_ENTITY, self.modelindex); WriteCoord(MSG_ENTITY, self.mins.x); WriteCoord(MSG_ENTITY, self.mins.y); WriteCoord(MSG_ENTITY, self.mins.z); WriteCoord(MSG_ENTITY, self.maxs.x); WriteCoord(MSG_ENTITY, self.maxs.y); WriteCoord(MSG_ENTITY, self.maxs.z); } else { WriteShort(MSG_ENTITY, 0); WriteCoord(MSG_ENTITY, self.maxs.x); WriteCoord(MSG_ENTITY, self.maxs.y); WriteCoord(MSG_ENTITY, self.maxs.z); } WriteByte(MSG_ENTITY, self.volume * 255.0); WriteByte(MSG_ENTITY, self.fade_time * 16.0); WriteByte(MSG_ENTITY, self.fade_rate * 16.0); WriteString(MSG_ENTITY, self.noise); } return 1; } void trigger_music_reset(entity this) { this.cnt = !(this.spawnflags & 1); this.SendFlags |= 0x80; } void trigger_music_use() {SELFPARAM(); self.cnt = !self.cnt; self.SendFlags |= 0x80; } spawnfunc(trigger_music) { if(this.model != "") _setmodel(this, this.model); if(!this.volume) this.volume = 1; if(!this.modelindex) { setorigin(this, this.origin + this.mins); setsize(this, '0 0 0', this.maxs - this.mins); } trigger_music_reset(this); this.use = trigger_music_use; this.reset = trigger_music_reset; Net_LinkEntity(this, false, 0, trigger_music_SendEntity); } #elif defined(CSQC) entity TargetMusic_list; STATIC_INIT(TargetMusic_list) { TargetMusic_list = LL_NEW(); } void TargetMusic_Advance() { // run AFTER all the thinks! entity best = music_default; if (music_target && time < music_target.lifetime) best = music_target; if (music_trigger) best = music_trigger; LL_EACH(TargetMusic_list, it.noise, LAMBDA( const float vol0 = (getsoundtime(it, CH_BGM_SINGLE) >= 0) ? it.lastvol : -1; if (it == best) { // increase volume it.state = (it.fade_time > 0) ? bound(0, it.state + frametime / it.fade_time, 1) : 1; } else { // decrease volume it.state = (it.fade_rate > 0) ? bound(0, it.state - frametime / it.fade_rate, 1) : 0; } const float vol = it.state * it.volume * autocvar_bgmvolume; if (vol != vol0) { if(vol0 < 0) _sound(it, CH_BGM_SINGLE, it.noise, vol, ATTEN_NONE); // restart else _sound(it, CH_BGM_SINGLE, "", vol, ATTEN_NONE); it.lastvol = vol; } )); music_trigger = world; bgmtime = (best) ? getsoundtime(best, CH_BGM_SINGLE) : gettime(GETTIME_CDTRACK); } NET_HANDLE(TE_CSQC_TARGET_MUSIC, bool isNew) { Net_TargetMusic(); return true; } void Net_TargetMusic() { const int id = ReadShort(); const float vol = ReadByte() / 255.0; const float fai = ReadByte() / 16.0; const float fao = ReadByte() / 16.0; const float tim = ReadByte(); const string noi = ReadString(); entity e = NULL; LL_EACH(TargetMusic_list, it.count == id, LAMBDA(e = it; break)); if (!e) { LL_PUSH(TargetMusic_list, e = new(TargetMusic)); make_pure(e); e.count = id; } if(e.noise != noi) { if(e.noise) strunzone(e.noise); e.noise = strzone(noi); precache_sound(e.noise); _sound(e, CH_BGM_SINGLE, e.noise, 0, ATTEN_NONE); if(getsoundtime(e, CH_BGM_SINGLE) < 0) { LOG_TRACEF("Cannot initialize sound %s\n", e.noise); strunzone(e.noise); e.noise = string_null; } } e.volume = vol; e.fade_time = fai; e.fade_rate = fao; if(vol > 0) { if(tim == 0) { music_default = e; if(!music_disabled) { e.state = 2; cvar_settemp("music_playlist_index", "-1"); // don't use playlists localcmd("cd stop\n"); // just in case music_disabled = 1; } } else { music_target = e; e.lifetime = time + tim; } } } void Ent_TriggerMusic_Think() {SELFPARAM(); if(WarpZoneLib_BoxTouchesBrush(view_origin, view_origin, self, world)) { music_trigger = self; } self.nextthink = time; } void Ent_TriggerMusic_Remove() {SELFPARAM(); if(self.noise) strunzone(self.noise); self.noise = string_null; } NET_HANDLE(ENT_CLIENT_TRIGGER_MUSIC, bool isnew) { int f = ReadByte(); if(f & 4) { self.origin_x = ReadCoord(); self.origin_y = ReadCoord(); self.origin_z = ReadCoord(); } if(f & 1) { self.modelindex = ReadShort(); if(self.modelindex) { self.mins_x = ReadCoord(); self.mins_y = ReadCoord(); self.mins_z = ReadCoord(); self.maxs_x = ReadCoord(); self.maxs_y = ReadCoord(); self.maxs_z = ReadCoord(); } else { self.mins = '0 0 0'; self.maxs_x = ReadCoord(); self.maxs_y = ReadCoord(); self.maxs_z = ReadCoord(); } self.volume = ReadByte() / 255.0; self.fade_time = ReadByte() / 16.0; self.fade_rate = ReadByte() / 16.0; string s = self.noise; if(self.noise) strunzone(self.noise); self.noise = strzone(ReadString()); if(self.noise != s) { precache_sound(self.noise); _sound(self, CH_BGM_SINGLE, self.noise, 0, ATTEN_NONE); if(getsoundtime(self, CH_BGM_SINGLE) < 0) { LOG_TRACEF("Cannot initialize sound %s\n", self.noise); strunzone(self.noise); self.noise = string_null; } } } setorigin(self, self.origin); setsize(self, self.mins, self.maxs); self.cnt = 1; self.think = Ent_TriggerMusic_Think; self.nextthink = time; return true; } #endif