From: bones_was_here Date: Mon, 2 Jan 2023 16:02:47 +0000 (+0000) Subject: Merge branch 'Mario/no_engine_physics' into 'master' X-Git-Tag: xonotic-v0.8.6~230 X-Git-Url: https://git.xonotic.org/?a=commitdiff_plain;h=353708c4dcf610a8c0eb80e56bac8408dcc45225;hp=718da47ae88b22ec3f2cdf2191c9c66d4da95677;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'Mario/no_engine_physics' into 'master' Make all entities (such as monsters and turrets) use physics logic handled by Xonotic rather than the engine, allowing for future advancements in movement and gameplay See merge request xonotic/xonotic-data.pk3dir!1044 --- diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 8f919b556..a9ad0a76b 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -269,7 +269,6 @@ void viewmodel_animate(entity this) this.origin += bobmodel_ofs(view); } -.vector viewmodel_origin, viewmodel_angles; .float weapon_nextthink; .float weapon_eta_last; .float weapon_switchdelay; @@ -278,8 +277,6 @@ void viewmodel_animate(entity this) void viewmodel_draw(entity this) { - if(!this.activeweapon || !autocvar_r_drawviewmodel) - return; int mask = (intermission || (STAT(HEALTH) <= 0) || autocvar_chase_active) ? 0 : MASK_NORMAL; float a = ((autocvar_cl_viewmodel_alpha) ? bound(-1, autocvar_cl_viewmodel_alpha, this.m_alpha) : this.m_alpha); int wepskin = this.m_skin; @@ -313,8 +310,7 @@ void viewmodel_draw(entity this) { this.name_last = name; CL_WeaponEntity_SetModel(this, name, swap); - this.viewmodel_origin = this.origin; - this.viewmodel_angles = this.angles; + this.origin += autocvar_cl_gunoffset; } anim_update(this); if ((!this.animstate_override && !this.animstate_looping) || time > this.animstate_endtime) @@ -343,8 +339,6 @@ void viewmodel_draw(entity this) } } this.weapon_eta_last = f; - this.origin = this.viewmodel_origin; - this.angles = this.viewmodel_angles; this.angles_x = (-90 * f * f); viewmodel_animate(this); MUTATOR_CALLHOOK(DrawViewModel, this); @@ -917,6 +911,7 @@ void HUD_Draw(entity this) UpdateDamage(); HUD_Crosshair(this); HitSound(); + Local_Notification_Queue_Process(); } void ViewLocation_Mouse() @@ -1608,8 +1603,10 @@ void CSQC_UpdateView(entity this, float w, float h) // run viewmodel_draw before updating view_angles to the angles calculated by WarpZone_FixView // viewmodel_draw needs to use the view_angles set by the engine on every CSQC_UpdateView call - for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) - viewmodel_draw(viewmodels[slot]); + if(autocvar_r_drawviewmodel) + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + if(viewmodels[slot].activeweapon) + viewmodel_draw(viewmodels[slot]); // Render the Scene view_origin = getpropertyvec(VF_ORIGIN); diff --git a/qcsrc/client/view.qh b/qcsrc/client/view.qh index 45959383b..cd33ebfb6 100644 --- a/qcsrc/client/view.qh +++ b/qcsrc/client/view.qh @@ -92,6 +92,7 @@ vector autocvar_cl_eventchase_viewoffset = '0 0 20'; string autocvar__togglezoom; int autocvar_cl_nade_timer; bool autocvar_r_drawviewmodel; +vector autocvar_cl_gunoffset; void calc_followmodel_ofs(entity view); diff --git a/qcsrc/common/effects/qc/casings.qc b/qcsrc/common/effects/qc/casings.qc index c0c7f5ac9..b49ff60fa 100644 --- a/qcsrc/common/effects/qc/casings.qc +++ b/qcsrc/common/effects/qc/casings.qc @@ -14,7 +14,7 @@ REPLICATE(cvar_cl_casings, bool, "cl_casings"); REPLICATE(cvar_r_drawviewmodel, int, "r_drawviewmodel"); #ifdef SVQC -void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner, .entity weaponentity) +void SpawnCasing(vector vel, vector ang, int casingtype, entity casingowner, .entity weaponentity) { vector org = casingowner.(weaponentity).spawnorigin; org = casingowner.origin + casingowner.view_ofs + org.x * v_forward - org.y * v_right + org.z * v_up; @@ -22,10 +22,20 @@ void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float ran FOREACH_CLIENT(true, { if (!(CS_CVAR(it).cvar_cl_casings)) continue; - if (it == casingowner && !(CS_CVAR(it).cvar_r_drawviewmodel)) + + casingtype &= 0x3F; // reset any bitflags that were set for the previous client + + if (it == casingowner || (IS_SPEC(it) && it.enemy == casingowner)) + { + if (!(CS_CVAR(it).cvar_r_drawviewmodel)) + continue; + + casingtype |= 0x40; // client will apply autocvar_cl_gunoffset in first person + } + else if (1 & ~checkpvs(it.origin + it.view_ofs, casingowner)) // 1 or 3 means visible continue; - msg_entity = it; + msg_entity = it; // sound_allowed checks this if (!sound_allowed(MSG_ONE, it)) casingtype |= 0x80; // silent @@ -35,7 +45,7 @@ void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float ran WriteShort(MSG_ONE, compressShortVector(vel)); // actually compressed velocity WriteByte(MSG_ONE, ang.x * 256 / 360); WriteByte(MSG_ONE, ang.y * 256 / 360); - WriteByte(MSG_ONE, ang.z * 256 / 360); + // weapons only have pitch and yaw, so no need to send ang.z }); } #endif @@ -47,6 +57,7 @@ classfield(Casing) .bool silent; classfield(Casing) .int state; classfield(Casing) .float cnt; +// this is only needed because LimitedChildrenRubble() takes a func pointer void Casing_Delete(entity this) { delete(this); @@ -66,14 +77,24 @@ void Casing_Draw(entity this) if (this.alpha < ALPHA_MIN_VISIBLE) { - Casing_Delete(this); + delete(this); this.drawmask = 0; return; } + trace_startsolid = 0; // due to cl_casings_ticrate, traces are not always performed Movetype_Physics_MatchTicrate(this, autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy); //if (wasfreed(this)) // return; // deleted by touch function + + // prevent glitchy casings when the gun model is poking into a wall + // doing this here is cheaper than doing it on the server as the client performs the trace anyway + if (trace_startsolid) + { + delete(this); + this.drawmask = 0; + return; + } } SOUND(BRASS1, W_Sound("brass1")); @@ -93,7 +114,7 @@ void Casing_Touch(entity this, entity toucher) { if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) { - Casing_Delete(this); + delete(this); return; } @@ -133,30 +154,30 @@ void Casing_Damage(entity this, float thisdmg, int hittype, vector org, vector t NET_HANDLE(casings, bool isNew) { - int _state = ReadByte(); - vector org = ReadVector(); - vector vel = decompressShortVector(ReadShort()); - vector ang; - ang_x = ReadByte() * 360 / 256; - ang_y = ReadByte() * 360 / 256; - ang_z = ReadByte() * 360 / 256; + Casing casing = ListNewChildRubble(CasingsNGibs, new(casing)); + + casing.state = ReadByte(); + casing.origin = ReadVector(); + casing.velocity = decompressShortVector(ReadShort()); + casing.angles_x = ReadByte() * 360 / 256; + casing.angles_y = ReadByte() * 360 / 256; + return = true; - Casing casing = ListNewChildRubble(CasingsNGibs, new(casing)); - casing.silent = (_state & 0x80); - casing.state = (_state & 0x7F); - casing.origin = org; + casing.silent = casing.state & 0x80; + if (casing.state & 0x40 && !autocvar_chase_active) + casing.origin += autocvar_cl_gunoffset.x * v_forward + - autocvar_cl_gunoffset.y * v_right + + autocvar_cl_gunoffset.z * v_up; + casing.state &= 0x3F; // the 2 most significant bits are reserved for the silent and casingowner bitflags + setorigin(casing, casing.origin); - casing.velocity = vel; - casing.angles = ang; casing.drawmask = MASK_NORMAL; - casing.draw = Casing_Draw; if (isNew) IL_PUSH(g_drawables, casing); - casing.velocity = casing.velocity + 2 * prandomvec(); - casing.avelocity = '0 250 0' + 100 * prandomvec(); + casing.velocity += 2 * prandomvec(); + casing.avelocity = '0 10 0' + 100 * prandomvec(); set_movetype(casing, MOVETYPE_BOUNCE); - casing.bouncefactor = 0.25; settouch(casing, Casing_Touch); casing.move_time = time; casing.event_damage = Casing_Damage; @@ -166,16 +187,16 @@ NET_HANDLE(casings, bool isNew) { case 1: setmodel(casing, MDL_CASING_SHELL); + casing.bouncefactor = 0.25; casing.cnt = time + autocvar_cl_casings_shell_time; break; default: setmodel(casing, MDL_CASING_BULLET); + casing.bouncefactor = 0.5; casing.cnt = time + autocvar_cl_casings_bronze_time; break; } - setsize(casing, '0 0 -1', '0 0 -1'); - LimitedChildrenRubble(CasingsNGibs, "casing", autocvar_cl_casings_maxcount, Casing_Delete, NULL); } diff --git a/qcsrc/common/effects/qc/casings.qh b/qcsrc/common/effects/qc/casings.qh index f4884cb23..5e2c0a5ec 100644 --- a/qcsrc/common/effects/qc/casings.qh +++ b/qcsrc/common/effects/qc/casings.qh @@ -5,7 +5,7 @@ float autocvar_cl_casings_bronze_time; int autocvar_cl_casings_maxcount = 100; float autocvar_cl_casings_shell_time; bool autocvar_cl_casings_sloppy = 1; -float autocvar_cl_casings_ticrate = 0.1; +float autocvar_cl_casings_ticrate; #endif #ifdef GAMEQC @@ -16,5 +16,5 @@ REPLICATE_INIT(int, cvar_r_drawviewmodel); #ifdef SVQC int autocvar_g_casings; -void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner, .entity weaponentity); +void SpawnCasing(vector vel, vector ang, int casingtype, entity casingowner, .entity weaponentity); #endif diff --git a/qcsrc/common/items/item/ammo.qh b/qcsrc/common/items/item/ammo.qh index bf22a7e81..802922cc4 100644 --- a/qcsrc/common/items/item/ammo.qh +++ b/qcsrc/common/items/item/ammo.qh @@ -26,160 +26,172 @@ CLASS(Ammo, Pickup) ENDCLASS(Ammo) +// NOTE: ammo resource registration order should match ammo (as item) registration order +// see REGISTER_RESOURCE calls order + +// ammo type #1: shells #ifdef GAMEQC -MODEL(Bullets_ITEM, Item_Model("a_bullets.mdl")); +MODEL(Shells_ITEM, Item_Model("a_shells.md3")); #endif #ifdef SVQC -PROPERTY(int, g_pickup_nails); -void ammo_bullets_init(Pickup this, entity item) +PROPERTY(int, g_pickup_shells); +void ammo_shells_init(Pickup this, entity item) { - if(!GetResource(item, RES_BULLETS)) - SetResourceExplicit(item, RES_BULLETS, g_pickup_nails); + if(!GetResource(item, RES_SHELLS)) + SetResourceExplicit(item, RES_SHELLS, g_pickup_shells); } #endif -CLASS(Bullets, Ammo) -ENDCLASS(Bullets) +CLASS(Shells, Ammo) +ENDCLASS(Shells) -REGISTER_ITEM(Bullets, Bullets) { - this.m_canonical_spawnfunc = "item_bullets"; +REGISTER_ITEM(Shells, Shells) { + this.m_canonical_spawnfunc = "item_shells"; #ifdef GAMEQC - this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE; - this.m_model = MDL_Bullets_ITEM; + this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE; + this.m_model = MDL_Shells_ITEM; #endif - this.netname = "bullets"; - this.m_name = _("bullets"); - this.m_icon = "ammo_bullets"; + this.netname = "shells"; + this.m_name = _("shells"); + this.m_icon = "ammo_shells"; #ifdef SVQC - this.m_botvalue = 1500; - this.m_itemid = IT_RESOURCE; - this.m_iteminit = ammo_bullets_init; + this.m_botvalue = 1000; + this.m_itemid = IT_RESOURCE; + this.m_iteminit = ammo_shells_init; #endif } -SPAWNFUNC_ITEM(item_bullets, ITEM_Bullets) +SPAWNFUNC_ITEM(item_shells, ITEM_Shells) + +// ammo type #2: bullets #ifdef GAMEQC -MODEL(Cells_ITEM, Item_Model("a_cells.md3")); +MODEL(Bullets_ITEM, Item_Model("a_bullets.mdl")); #endif #ifdef SVQC -PROPERTY(int, g_pickup_cells); -void ammo_cells_init(Pickup this, entity item) +PROPERTY(int, g_pickup_nails); +void ammo_bullets_init(Pickup this, entity item) { - if(!GetResource(item, RES_CELLS)) - SetResourceExplicit(item, RES_CELLS, g_pickup_cells); + if(!GetResource(item, RES_BULLETS)) + SetResourceExplicit(item, RES_BULLETS, g_pickup_nails); } #endif -REGISTER_ITEM(Cells, Ammo) { - this.m_canonical_spawnfunc = "item_cells"; + +CLASS(Bullets, Ammo) +ENDCLASS(Bullets) + +REGISTER_ITEM(Bullets, Bullets) { + this.m_canonical_spawnfunc = "item_bullets"; #ifdef GAMEQC - this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE; - this.m_model = MDL_Cells_ITEM; + this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE; + this.m_model = MDL_Bullets_ITEM; #endif - this.netname = "cells"; - this.m_name = _("cells"); - this.m_icon = "ammo_cells"; + this.netname = "bullets"; + this.m_name = _("bullets"); + this.m_icon = "ammo_bullets"; #ifdef SVQC - this.m_botvalue = 1500; - this.m_itemid = IT_RESOURCE; - this.m_iteminit = ammo_cells_init; + this.m_botvalue = 1500; + this.m_itemid = IT_RESOURCE; + this.m_iteminit = ammo_bullets_init; #endif } -SPAWNFUNC_ITEM(item_cells, ITEM_Cells) +SPAWNFUNC_ITEM(item_bullets, ITEM_Bullets) + +// ammo type #3: rockets #ifdef GAMEQC -MODEL(Plasma_ITEM, Item_Model("a_cells.md3")); +MODEL(Rockets_ITEM, Item_Model("a_rockets.md3")); #endif #ifdef SVQC -PROPERTY(int, g_pickup_plasma); -void ammo_plasma_init(Pickup this, entity item) +PROPERTY(int, g_pickup_rockets); +void ammo_rockets_init(Pickup this, entity item) { - if(!GetResource(item, RES_PLASMA)) - SetResourceExplicit(item, RES_PLASMA, g_pickup_plasma); + if(!GetResource(item, RES_ROCKETS)) + SetResourceExplicit(item, RES_ROCKETS, g_pickup_rockets); } #endif -REGISTER_ITEM(Plasma, Ammo) { - this.m_canonical_spawnfunc = "item_plasma"; +REGISTER_ITEM(Rockets, Ammo) { + this.m_canonical_spawnfunc = "item_rockets"; #ifdef GAMEQC - this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE; - this.m_model = MDL_Plasma_ITEM; + this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE; + this.m_model = MDL_Rockets_ITEM; #endif - this.netname = "plasma"; - this.m_name = _("plasma"); - this.m_icon = "ammo_plasma"; + this.netname = "rockets"; + this.m_name = _("rockets"); + this.m_icon = "ammo_rockets"; #ifdef SVQC - this.m_botvalue = 1500; - this.m_itemid = IT_RESOURCE; - this.m_iteminit = ammo_plasma_init; + this.m_botvalue = 1500; + this.m_itemid = IT_RESOURCE; + this.m_iteminit = ammo_rockets_init; #endif } -SPAWNFUNC_ITEM(item_plasma, ITEM_Plasma) +SPAWNFUNC_ITEM(item_rockets, ITEM_Rockets) + +// ammo type #4: cells #ifdef GAMEQC -MODEL(Rockets_ITEM, Item_Model("a_rockets.md3")); +MODEL(Cells_ITEM, Item_Model("a_cells.md3")); #endif #ifdef SVQC -PROPERTY(int, g_pickup_rockets); -void ammo_rockets_init(Pickup this, entity item) +PROPERTY(int, g_pickup_cells); +void ammo_cells_init(Pickup this, entity item) { - if(!GetResource(item, RES_ROCKETS)) - SetResourceExplicit(item, RES_ROCKETS, g_pickup_rockets); + if(!GetResource(item, RES_CELLS)) + SetResourceExplicit(item, RES_CELLS, g_pickup_cells); } #endif -REGISTER_ITEM(Rockets, Ammo) { - this.m_canonical_spawnfunc = "item_rockets"; +REGISTER_ITEM(Cells, Ammo) { + this.m_canonical_spawnfunc = "item_cells"; #ifdef GAMEQC - this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE; - this.m_model = MDL_Rockets_ITEM; + this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE; + this.m_model = MDL_Cells_ITEM; #endif - this.netname = "rockets"; - this.m_name = _("rockets"); - this.m_icon = "ammo_rockets"; + this.netname = "cells"; + this.m_name = _("cells"); + this.m_icon = "ammo_cells"; #ifdef SVQC - this.m_botvalue = 1500; - this.m_itemid = IT_RESOURCE; - this.m_iteminit = ammo_rockets_init; + this.m_botvalue = 1500; + this.m_itemid = IT_RESOURCE; + this.m_iteminit = ammo_cells_init; #endif } -SPAWNFUNC_ITEM(item_rockets, ITEM_Rockets) +SPAWNFUNC_ITEM(item_cells, ITEM_Cells) + +// ammo type #5: plasma #ifdef GAMEQC -MODEL(Shells_ITEM, Item_Model("a_shells.md3")); +MODEL(Plasma_ITEM, Item_Model("a_cells.md3")); #endif #ifdef SVQC -PROPERTY(int, g_pickup_shells); -void ammo_shells_init(Pickup this, entity item) +PROPERTY(int, g_pickup_plasma); +void ammo_plasma_init(Pickup this, entity item) { - if(!GetResource(item, RES_SHELLS)) - SetResourceExplicit(item, RES_SHELLS, g_pickup_shells); + if(!GetResource(item, RES_PLASMA)) + SetResourceExplicit(item, RES_PLASMA, g_pickup_plasma); } #endif - -CLASS(Shells, Ammo) -ENDCLASS(Shells) - -REGISTER_ITEM(Shells, Shells) { - this.m_canonical_spawnfunc = "item_shells"; +REGISTER_ITEM(Plasma, Ammo) { + this.m_canonical_spawnfunc = "item_plasma"; #ifdef GAMEQC - this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE; - this.m_model = MDL_Shells_ITEM; + this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE; + this.m_model = MDL_Plasma_ITEM; #endif - this.netname = "shells"; - this.m_name = _("shells"); - this.m_icon = "ammo_shells"; + this.netname = "plasma"; + this.m_name = _("plasma"); + this.m_icon = "ammo_plasma"; #ifdef SVQC - this.m_botvalue = 1000; - this.m_itemid = IT_RESOURCE; - this.m_iteminit = ammo_shells_init; + this.m_botvalue = 1500; + this.m_itemid = IT_RESOURCE; + this.m_iteminit = ammo_plasma_init; #endif } -SPAWNFUNC_ITEM(item_shells, ITEM_Shells) +SPAWNFUNC_ITEM(item_plasma, ITEM_Plasma) diff --git a/qcsrc/common/mutators/mutator/overkill/okhmg.qc b/qcsrc/common/mutators/mutator/overkill/okhmg.qc index d5a2ba2e3..1d8c5e87f 100644 --- a/qcsrc/common/mutators/mutator/overkill/okhmg.qc +++ b/qcsrc/common/mutators/mutator/overkill/okhmg.qc @@ -45,7 +45,7 @@ void W_OverkillHeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity if (autocvar_g_casings >= 2) // casing code { makevectors(actor.v_angle); // for some reason, this is lost - SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity); + SpawnCasing(((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity); } ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR_PRI(okhmg, refire) * W_WeaponRateFactor(actor); diff --git a/qcsrc/common/mutators/mutator/overkill/okmachinegun.qc b/qcsrc/common/mutators/mutator/overkill/okmachinegun.qc index 20db8d961..a86cdc519 100644 --- a/qcsrc/common/mutators/mutator/overkill/okmachinegun.qc +++ b/qcsrc/common/mutators/mutator/overkill/okmachinegun.qc @@ -39,7 +39,7 @@ void W_OverkillMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weap if(autocvar_g_casings >= 2) // casing code { makevectors(actor.v_angle); // for some reason, this is lost - SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity); + SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity); } ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR_PRI(okmachinegun, refire) * W_WeaponRateFactor(actor); diff --git a/qcsrc/common/notifications/all.inc b/qcsrc/common/notifications/all.inc index 360a3439a..9a7845a16 100644 --- a/qcsrc/common/notifications/all.inc +++ b/qcsrc/common/notifications/all.inc @@ -98,6 +98,14 @@ #define N_GNTLOFF 1 #define N__ALWAYS 2 +// default time for announcer queue (time to wait before the next announcer is played) +// -1 = bypass queue and play the announcer immediately +// 0 = use the announcer sound length +// >0 = use the specified time in seconds +#define ANNCE_INSTANT -1 +#define ANNCE_LENGTH 0 +#define ANNCE_DEFTIME 2 + #define MULTITEAM_ANNCE(prefix, defaultvalue, sound, channel, volume, position) \ NOTIF_ADD_AUTOCVAR(ANNCE_##prefix, defaultvalue) \ MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_1, prefix##_RED, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), channel, volume, position) \ @@ -106,101 +114,101 @@ MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_4, prefix##_PINK, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_4)), channel, volume, position) // MSG_ANNCE_NOTIFICATIONS - MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT, N_GNTLOFF, "airshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING, N_GNTLOFF, "amazing", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME, N_GNTLOFF, "awesome", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE, N_GNTLOFF, "botlike", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH, N__ALWAYS, "electrobitch", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE, N_GNTLOFF, "impressive", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(ACHIEVEMENT_YODA, N_GNTLOFF, "yoda", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(BEGIN, N__ALWAYS, "begin", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(HEADSHOT, N__ALWAYS, "headshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(KILLSTREAK_03, N_GNTLOFF, "03kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_05, N_GNTLOFF, "05kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_10, N_GNTLOFF, "10kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_15, N_GNTLOFF, "15kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_20, N_GNTLOFF, "20kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_25, N_GNTLOFF, "25kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(KILLSTREAK_30, N_GNTLOFF, "30kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND, N_GNTLOFF, "lastsecond", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY, N_GNTLOFF, "narrowly", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(INSTAGIB_TERMINATED, N_GNTLOFF, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(MULTIFRAG, N___NEVER, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_6, N__ALWAYS, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_7, N__ALWAYS, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_8, N__ALWAYS, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_9, N__ALWAYS, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_10, N__ALWAYS, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_GAMESTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_GAMESTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_KILL_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_KILL_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_RESPAWN_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_RESPAWN_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(PREPARE, N__ALWAYS, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(REMAINING_FRAG_1, N_GNTLOFF, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(REMAINING_FRAG_2, N_GNTLOFF, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(REMAINING_FRAG_3, N_GNTLOFF, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(REMAINING_MIN_1, N__ALWAYS, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(REMAINING_MIN_5, N__ALWAYS, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(TIMEOUT, N__ALWAYS, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - - MSG_ANNCE_NOTIF(VOTE_ACCEPT, N__ALWAYS, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(VOTE_CALL, N__ALWAYS, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(VOTE_FAIL, N__ALWAYS, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT, N_GNTLOFF, "airshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING, N_GNTLOFF, "amazing", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME, N_GNTLOFF, "awesome", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE, N_GNTLOFF, "botlike", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH, N__ALWAYS, "electrobitch", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE, N_GNTLOFF, "impressive", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(ACHIEVEMENT_YODA, N_GNTLOFF, "yoda", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + + MSG_ANNCE_NOTIF(BEGIN, N__ALWAYS, "begin", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + + MSG_ANNCE_NOTIF(HEADSHOT, N__ALWAYS, "headshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + + MSG_ANNCE_NOTIF(KILLSTREAK_03, N_GNTLOFF, "03kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(KILLSTREAK_05, N_GNTLOFF, "05kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(KILLSTREAK_10, N_GNTLOFF, "10kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(KILLSTREAK_15, N_GNTLOFF, "15kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(KILLSTREAK_20, N_GNTLOFF, "20kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(KILLSTREAK_25, N_GNTLOFF, "25kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(KILLSTREAK_30, N_GNTLOFF, "30kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + + MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND, N_GNTLOFF, "lastsecond", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY, N_GNTLOFF, "narrowly", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(INSTAGIB_TERMINATED, N_GNTLOFF, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + + MSG_ANNCE_NOTIF(MULTIFRAG, N___NEVER, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + + MSG_ANNCE_NOTIF(NUM_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_6, N__ALWAYS, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_7, N__ALWAYS, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_8, N__ALWAYS, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_9, N__ALWAYS, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_10, N__ALWAYS, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + + MSG_ANNCE_NOTIF(NUM_GAMESTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_GAMESTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_GAMESTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_GAMESTART_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_GAMESTART_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_GAMESTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_GAMESTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_GAMESTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_GAMESTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_GAMESTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + + MSG_ANNCE_NOTIF(NUM_KILL_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_KILL_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_KILL_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_KILL_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_KILL_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_KILL_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_KILL_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_KILL_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_KILL_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_KILL_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + + MSG_ANNCE_NOTIF(NUM_RESPAWN_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_RESPAWN_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_RESPAWN_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_RESPAWN_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_RESPAWN_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_RESPAWN_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_RESPAWN_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_RESPAWN_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_RESPAWN_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_RESPAWN_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + + MSG_ANNCE_NOTIF(PREPARE, N__ALWAYS, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + + MSG_ANNCE_NOTIF(REMAINING_FRAG_1, N_GNTLOFF, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(REMAINING_FRAG_2, N_GNTLOFF, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(REMAINING_FRAG_3, N_GNTLOFF, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + + MSG_ANNCE_NOTIF(REMAINING_MIN_1, N__ALWAYS, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(REMAINING_MIN_5, N__ALWAYS, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + + MSG_ANNCE_NOTIF(TIMEOUT, N__ALWAYS, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT) + + MSG_ANNCE_NOTIF(VOTE_ACCEPT, N__ALWAYS, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(VOTE_CALL, N__ALWAYS, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) + MSG_ANNCE_NOTIF(VOTE_FAIL, N__ALWAYS, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME) #undef N___NEVER #undef N_GNTLOFF diff --git a/qcsrc/common/notifications/all.qc b/qcsrc/common/notifications/all.qc index 98b0f18e1..58910887e 100644 --- a/qcsrc/common/notifications/all.qc +++ b/qcsrc/common/notifications/all.qc @@ -450,7 +450,8 @@ void Create_Notification_Entity_Annce(entity notif, float channel, string snd, float vol, - float position) + float position, + float queuetime) { // Set MSG_ANNCE information and handle precaching #ifdef CSQC @@ -466,6 +467,7 @@ void Create_Notification_Entity_Annce(entity notif, notif.nent_snd = strzone(snd); notif.nent_vol = vol; notif.nent_position = position; + notif.nent_queuetime = queuetime; } } else @@ -1177,6 +1179,58 @@ void Local_Notification_centerprint_Add( #endif centerprint_Add(ORDINAL(cpid), input, stof(arg_slot[0]), stof(arg_slot[1])); } + +void Local_Notification_Queue_Run(MSG net_type, entity notif) +{ + switch (net_type) + { + case MSG_ANNCE: + { + Local_Notification_sound(notif.nent_channel, notif.nent_snd, notif.nent_vol, notif.nent_position); + break; + } + } +} + +void Local_Notification_Queue_Add(MSG net_type, entity notif, float queue_time) +{ + // Guess length if required + if(queue_time == 0) + queue_time = soundlength(AnnouncerFilename(notif.nent_snd)); + + if(queue_time == -1 || time > notif_queue_next_time) { + // Run immediately + Local_Notification_Queue_Run(net_type, notif); + notif_queue_next_time = time + queue_time; + } else { + // Put in queue + if(notif_queue_length >= NOTIF_QUEUE_MAX) return; + + notif_queue_type[notif_queue_length] = net_type; + notif_queue_entity[notif_queue_length] = notif; + notif_queue_time[notif_queue_length] = notif_queue_next_time; + + notif_queue_next_time += queue_time; + ++notif_queue_length; + } +} + +void Local_Notification_Queue_Process() +{ + if(!notif_queue_length || notif_queue_time[0] > time) + return; + + Local_Notification_Queue_Run(notif_queue_type[0], notif_queue_entity[0]); + + // Shift queue to the left + --notif_queue_length; + for (int j = 0; j < notif_queue_length; j++) { + notif_queue_type[j] = notif_queue_type[j+1]; + notif_queue_entity[j] = notif_queue_entity[j+1]; + notif_queue_time[j] = notif_queue_time[j+1]; + } +} + #endif void Local_Notification(MSG net_type, Notification net_name, ...count) @@ -1249,7 +1303,7 @@ void Local_Notification(MSG net_type, Notification net_name, ...count) case MSG_ANNCE: { #ifdef CSQC - Local_Notification_sound(notif.nent_channel, notif.nent_snd, notif.nent_vol, notif.nent_position); + Local_Notification_Queue_Add(net_type, notif, notif.nent_queuetime); #else backtrace("MSG_ANNCE on server?... Please notify Samual immediately!\n"); #endif @@ -1357,6 +1411,7 @@ void Local_Notification(MSG net_type, Notification net_name, ...count) found_choice.nent_floatcount, s1, s2, s3, s4, f1, f2, f3, f4); + break; } } } diff --git a/qcsrc/common/notifications/all.qh b/qcsrc/common/notifications/all.qh index 74e313dce..2a7e68ad8 100644 --- a/qcsrc/common/notifications/all.qh +++ b/qcsrc/common/notifications/all.qh @@ -123,7 +123,8 @@ void Create_Notification_Entity_Annce(entity notif, float channel, string snd, float vol, - float position); + float position, + float queuetime); void Create_Notification_Entity_InfoCenter(entity notif, float var_cvar, @@ -384,6 +385,18 @@ const float NOTIF_MAX_ARGS = 7; const float NOTIF_MAX_HUDARGS = 2; const float NOTIF_MAX_DURCNT = 2; +#ifdef CSQC +const int NOTIF_QUEUE_MAX = 10; +entity notif_queue_entity[NOTIF_QUEUE_MAX]; +MSG notif_queue_type[NOTIF_QUEUE_MAX]; +float notif_queue_time[NOTIF_QUEUE_MAX]; + +float notif_queue_next_time; +int notif_queue_length; + +void Local_Notification_Queue_Process(); +#endif + string arg_slot[NOTIF_MAX_ARGS]; const float ARG_CS_SV_HA = 1; // enabled on CSQC, SVQC, and Hudargs @@ -665,6 +678,7 @@ string notif_arg_item_wepammo(float f1, float f2) .string nent_snd; .float nent_vol; .float nent_position; +.float nent_queuetime; // MSG_INFO and MSG_CENTER entity values .string nent_args; // used by both @@ -743,21 +757,22 @@ Notification Get_Notif_Ent(MSG net_type, int net_name) return it; } -#define MSG_ANNCE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position) \ - MSG_ANNCE_NOTIF_(teamnum, ANNCE_##name, ANNCE_##cvarname, defaultvalue, sound, channel, volume, position) +#define MSG_ANNCE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \ + MSG_ANNCE_NOTIF_(teamnum, ANNCE_##name, ANNCE_##cvarname, defaultvalue, sound, channel, volume, position, queuetime) -#define MSG_ANNCE_NOTIF(name, defaultvalue, sound, channel, volume, position) \ +#define MSG_ANNCE_NOTIF(name, defaultvalue, sound, channel, volume, position, queuetime) \ NOTIF_ADD_AUTOCVAR(ANNCE_##name, defaultvalue) \ - MSG_ANNCE_NOTIF_(0, ANNCE_##name, ANNCE_##name, defaultvalue, sound, channel, volume, position) + MSG_ANNCE_NOTIF_(0, ANNCE_##name, ANNCE_##name, defaultvalue, sound, channel, volume, position, queuetime) -#define MSG_ANNCE_NOTIF_(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position) \ +#define MSG_ANNCE_NOTIF_(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \ REGISTER(Notifications, name, m_id, new_pure(msg_annce_notification)) { \ Create_Notification_Entity (this, defaultvalue, ACVNN(cvarname), MSG_ANNCE, strtoupper(#name), teamnum); \ Create_Notification_Entity_Annce(this, ACVNN(cvarname), strtoupper(#name), \ - channel, /* channel */ \ - sound, /* snd */ \ - volume, /* vol */ \ - position); /* position */ \ + channel, /* channel */ \ + sound, /* snd */ \ + volume, /* vol */ \ + position, /* position */ \ + queuetime); /* queuetime */ \ } #define MSG_INFO_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle) \ diff --git a/qcsrc/common/resources/all.inc b/qcsrc/common/resources/all.inc index 51e0bccad..0ad9ba31e 100644 --- a/qcsrc/common/resources/all.inc +++ b/qcsrc/common/resources/all.inc @@ -17,6 +17,9 @@ CLASS(AmmoResource, Resource) #endif ENDCLASS(AmmoResource) +// NOTE: ammo resource registration order should match ammo (item) registration order +// see REGISTER_ITEM calls order + REGISTER_RESOURCE(SHELLS, NEW(AmmoResource)) { this.netname = "shells"; #ifdef GAMEQC diff --git a/qcsrc/common/weapons/all.qc b/qcsrc/common/weapons/all.qc index 07c51f18d..709377164 100644 --- a/qcsrc/common/weapons/all.qc +++ b/qcsrc/common/weapons/all.qc @@ -378,6 +378,7 @@ vector shotorg_adjust_values(vector vecs, bool y_is_right, bool visual, int algn * this.origin, this.angles * this.weaponchild * this.movedir, this.view_ofs, this.movedir_aligned + * this.spawnorigin (SVQC only) * attachment stuff * anim stuff * to free: @@ -394,7 +395,9 @@ void CL_WeaponEntity_SetModel(entity this, string name, bool _anim) if (this.weaponchild) delete(this.weaponchild); this.weaponchild = NULL; this.movedir = '0 0 0'; +#ifdef SVQC this.spawnorigin = '0 0 0'; +#endif this.oldorigin = '0 0 0'; this.anim_fire1 = '0 1 0.01'; this.anim_fire2 = '0 1 0.01'; @@ -466,6 +469,7 @@ void CL_WeaponEntity_SetModel(entity this, string name, bool _anim) this.movedir = '0 0 0'; } } +#ifdef SVQC { int idx = 0; // v_ model attached to invisible h_ model @@ -485,6 +489,7 @@ void CL_WeaponEntity_SetModel(entity this, string name, bool _anim) this.spawnorigin = this.movedir; } } +#endif if (v_shot_idx) { this.oldorigin = '0 0 0'; // use regular attachment @@ -531,7 +536,7 @@ void CL_WeaponEntity_SetModel(entity this, string name, bool _anim) vector v = this.movedir; this.movedir = shotorg_adjust(v, false, false, algn); this.movedir_aligned = shotorg_adjust(v, false, true, algn); - this.view_ofs = shotorg_adjust(v, false, true, algn) - v; + this.view_ofs = this.movedir_aligned - v; } int compressed_shotorg = compressShotOrigin(this.movedir); // make them match perfectly @@ -541,7 +546,9 @@ void CL_WeaponEntity_SetModel(entity this, string name, bool _anim) #endif this.movedir = decompressShotOrigin(compressed_shotorg); +#ifdef SVQC this.spawnorigin += this.view_ofs; // offset the casings origin by the same amount +#endif // check if an instant weapon switch occurred setorigin(this, this.view_ofs); diff --git a/qcsrc/common/weapons/all.qh b/qcsrc/common/weapons/all.qh index acf436659..141b8b5ee 100644 --- a/qcsrc/common/weapons/all.qh +++ b/qcsrc/common/weapons/all.qh @@ -356,7 +356,9 @@ vector weaponentity_glowmod(Weapon wep, int c, entity wepent) //.int weapon; // current weapon .string weaponname; // name of .weapon +#ifdef SVQC .vector spawnorigin; // for casings +#endif .vector movedir_aligned; // shot origin based on weapon alignment (unaffected by shootfromeye) diff --git a/qcsrc/common/weapons/weapon/machinegun.qc b/qcsrc/common/weapons/weapon/machinegun.qc index 15a4d6a3c..62b2a09ea 100644 --- a/qcsrc/common/weapons/weapon/machinegun.qc +++ b/qcsrc/common/weapons/weapon/machinegun.qc @@ -24,7 +24,7 @@ void W_MachineGun_Attack(Weapon thiswep, int deathtype, entity actor, .entity we if(autocvar_g_casings >= 2) { makevectors(actor.v_angle); // for some reason, this is lost - SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity); + SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity); } if(actor.(weaponentity).misc_bulletcounter == 1) @@ -96,7 +96,7 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity if(autocvar_g_casings >= 2) // casing code { makevectors(actor.v_angle); // for some reason, this is lost - SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity); + SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity); } ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR(machinegun, first_refire) * W_WeaponRateFactor(actor); @@ -119,7 +119,7 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit if(autocvar_g_casings >= 2) // casing code { makevectors(actor.v_angle); // for some reason, this is lost - SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity); + SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity); } actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1; diff --git a/qcsrc/common/weapons/weapon/rifle.qc b/qcsrc/common/weapons/weapon/rifle.qc index 803930cc0..aa4a98062 100644 --- a/qcsrc/common/weapons/weapon/rifle.qc +++ b/qcsrc/common/weapons/weapon/rifle.qc @@ -24,7 +24,7 @@ void W_Rifle_FireBullet(Weapon thiswep, .entity weaponentity, float pSpread, flo if(autocvar_g_casings >= 2) { makevectors(actor.v_angle); // for some reason, this is lost - SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity); + SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity); } } diff --git a/qcsrc/common/weapons/weapon/shotgun.qc b/qcsrc/common/weapons/weapon/shotgun.qc index e304c4c2b..65cc0d9d9 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qc +++ b/qcsrc/common/weapons/weapon/shotgun.qc @@ -29,7 +29,7 @@ void W_Shotgun_Attack(Weapon thiswep, entity actor, .entity weaponentity, float { makevectors(actor.v_angle); // for some reason, this is lost //for(int sc = 0;sc < WEP_CVAR_PRI(shotgun, ammo);sc = sc + 1) - SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 30) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 1, actor, weaponentity); + SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 30) * v_up), vectoangles(v_forward), 1, actor, weaponentity); } } diff --git a/qcsrc/server/items/items.qc b/qcsrc/server/items/items.qc index 33e6edc01..347e956a3 100644 --- a/qcsrc/server/items/items.qc +++ b/qcsrc/server/items/items.qc @@ -821,24 +821,21 @@ float weapon_pickupevalfunc(entity player, entity item) float ammo_pickupevalfunc(entity player, entity item) { - bool need_shells = false, need_nails = false, need_rockets = false, need_cells = false, need_plasma = false, need_fuel = false; + entity item_resource = NULL; // pointer to the resource that may be associated with the given item entity wpn = NULL; float c = 0; float rating = 0; - // Detect needed ammo + // detect needed ammo if(item.itemdef.instanceOfWeaponPickup) { - entity ammo = NULL; - if(GetResource(item, RES_SHELLS)) { need_shells = true; ammo = ITEM_Shells; } - else if(GetResource(item, RES_BULLETS)) { need_nails = true; ammo = ITEM_Bullets; } - else if(GetResource(item, RES_ROCKETS)) { need_rockets = true; ammo = ITEM_Rockets; } - else if(GetResource(item, RES_CELLS)) { need_cells = true; ammo = ITEM_Cells; } - else if(GetResource(item, RES_PLASMA)) { need_plasma = true; ammo = ITEM_Plasma; } - else if(GetResource(item, RES_FUEL)) { need_fuel = true; ammo = ITEM_JetpackFuel; } - + entity res = item.itemdef.m_weapon.ammo_type; + entity ammo = (res != RES_NONE) ? GetAmmoItem(res) : NULL; if(!ammo) return 0; + if(res != RES_NONE && GetResource(item, res)) + item_resource = res; + wpn = item; rating = ammo.m_botvalue; } @@ -847,15 +844,13 @@ float ammo_pickupevalfunc(entity player, entity item) FOREACH(Weapons, it != WEP_Null, { if(!(STAT(WEAPONS, player) & (it.m_wepset))) continue; + if(it.ammo_type == RES_NONE) + continue; - switch(it.ammo_type) + if(GetResource(item, it.ammo_type)) { - case RES_SHELLS: need_shells = true; break; - case RES_BULLETS: need_nails = true; break; - case RES_ROCKETS: need_rockets = true; break; - case RES_CELLS: need_cells = true; break; - case RES_PLASMA: need_plasma = true; break; - case RES_FUEL: need_fuel = true; break; + item_resource = it.ammo_type; + break; } }); rating = item.bot_pickupbasevalue; @@ -863,23 +858,8 @@ float ammo_pickupevalfunc(entity player, entity item) float noammorating = 0.5; - if ((need_shells) && GetResource(item, RES_SHELLS) && (GetResource(player, RES_SHELLS) < g_pickup_shells_max)) - c = GetResource(item, RES_SHELLS) / max(noammorating, GetResource(player, RES_SHELLS)); - - if ((need_nails) && GetResource(item, RES_BULLETS) && (GetResource(player, RES_BULLETS) < g_pickup_nails_max)) - c = GetResource(item, RES_BULLETS) / max(noammorating, GetResource(player, RES_BULLETS)); - - if ((need_rockets) && GetResource(item, RES_ROCKETS) && (GetResource(player, RES_ROCKETS) < g_pickup_rockets_max)) - c = GetResource(item, RES_ROCKETS) / max(noammorating, GetResource(player, RES_ROCKETS)); - - if ((need_cells) && GetResource(item, RES_CELLS) && (GetResource(player, RES_CELLS) < g_pickup_cells_max)) - c = GetResource(item, RES_CELLS) / max(noammorating, GetResource(player, RES_CELLS)); - - if ((need_plasma) && GetResource(item, RES_PLASMA) && (GetResource(player, RES_PLASMA) < g_pickup_plasma_max)) - c = GetResource(item, RES_PLASMA) / max(noammorating, GetResource(player, RES_PLASMA)); - - if ((need_fuel) && GetResource(item, RES_FUEL) && (GetResource(player, RES_FUEL) < g_pickup_fuel_max)) - c = GetResource(item, RES_FUEL) / max(noammorating, GetResource(player, RES_FUEL)); + if(item_resource && (GetResource(player, item_resource) < GetResourceLimit(player, item_resource))) + c = GetResource(item, item_resource) / max(noammorating, GetResource(player, item_resource)); rating *= min(c, 2); if(wpn) diff --git a/xonotic-client.cfg b/xonotic-client.cfg index f73713338..fce5f0b06 100644 --- a/xonotic-client.cfg +++ b/xonotic-client.cfg @@ -307,6 +307,7 @@ r_shadow_realtime_world_importlightentitiesfrommap 0 // Whether build process us cl_decals_fadetime 5 cl_decals_time 1 seta cl_gunalign 3 "Gun alignment; 1 = center, 3 = right, 4 = left; requires reconnect" +seta cl_gunoffset "0 0 0" "Adjust the weapon viewmodel position, applies only to your own first person view and is relative to cl_gunalign" seta cl_nogibs 0 "reduce number of violence effects, or remove them totally" seta cl_particlegibs 0 "simpler gibs" seta cl_gibs_damageforcescale 3.5 "force to push around gibs" @@ -320,7 +321,7 @@ seta cl_gibs_avelocity_scale 1 "how much angular velocity to use on gibs" seta cl_casings 1 "enable or disable bullet casings" seta cl_casings_shell_time 30 "shell casing lifetime" seta cl_casings_bronze_time 10 "bullet casings lifetime" -seta cl_casings_ticrate 0.1 "ticrate for casings" +seta cl_casings_ticrate 0.03125 "ticrate for casings" seta cl_casings_sloppy 1 "sloppy casings, may temporarily penetrate walls" seta cl_projectiles_sloppy 1 "sloppy projectiles, may temporarily penetrate walls" cl_stainmaps 0