set g_balance_tuba_pitchstep 6
// }}}
// {{{ fireball // this is a superweapon -- lets make it behave as one.
-set g_balance_fireball_primary_animtime 0.4
+set g_balance_fireball_primary_animtime 0.2
set g_balance_fireball_primary_bfgdamage 100
set g_balance_fireball_primary_bfgforce 0
set g_balance_fireball_primary_bfgradius 1000
// campaign internal, set when loading a campaign map1G
set _campaign_index ""
set _campaign_name ""
+set _campaign_testrun 0 "To verify the campaign file, set this to 1, then start the first campaign level from the menu. If you end up in the menu again, it's good, if you get a QC crash, it's bad."
// debug
set _independent_players 0 "DO NOT TOUCH"
nl Dutch "Nederlands"
pt Portuguese "Português"
ro Romanian "Romana"
-ru Russian "Русский (INCOMPLETE)"
+ru Russian "Русский"
fi Finnish "Suomi"
uk Ukrainian "Українська"
if(i >= bgmscriptbufsize)
{
print(sprintf("ERROR: bgmscript does not define %s\n", e.bgmscript));
- e.bgmscript = "";
+ strunzone(e.bgmscript);
+ e.bgmscript = string_null;
}
}
}
}
// recursive predraw call to fix issues with forcemodels and LOD if bone indexes mismatch
+ if(self.tag_entity.classname == "csqcmodel")
{
entity oldself = self;
self = self.tag_entity;
float islocalplayer = (self.entnum == player_localnum + 1);
float isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1));
+ self.classname = "csqcmodel";
self.iflags |= IFLAG_ANGLES; // interpolate angles too
{ CSQCMODEL_HOOK_PREUPDATE }
vector gettaginfo_forward;
vector gettaginfo_right;
vector gettaginfo_up;
+float checkpvs(vector viewpos, entity viewee) = #240;
entity e, s, sl;
me.TR(me);
- s = makeXonoticDecibelsSlider(-20, 0, 0.5, "mastervolume");
+ s = makeXonoticDecibelsSlider(-40, 0, 1, "mastervolume");
me.TD(me, 1, 1, e = makeXonoticSliderCheckBox(-1000000, 1, s, _("Master:")));
if(s.value != e.savedValue)
e.savedValue = 0; // default
me.TD(me, 1, 2, s);
me.TR(me);
me.TDempty(me, 0.2);
- s = makeXonoticDecibelsSlider(-20, 0, 0.5, "bgmvolume");
+ s = makeXonoticDecibelsSlider(-40, 0, 1, "bgmvolume");
makeMulti(s, "snd_channel8volume");
me.TD(me, 1, 0.8, e = makeXonoticSliderCheckBox(-1000000, 1, s, _("Music:")));
if(s.value != e.savedValue)
setDependentStringNotEqual(s, "mastervolume", "0");
me.TR(me);
me.TDempty(me, 0.2);
- s = makeXonoticDecibelsSlider(-20, 0, 0.5, "snd_staticvolume");
+ s = makeXonoticDecibelsSlider(-40, 0, 1, "snd_staticvolume");
makeMulti(s, "snd_channel9volume");
me.TD(me, 1, 0.8, e = makeXonoticSliderCheckBox(-1000000, 1, s, ZCTX(_("VOL^Ambient:"))));
if(s.value != e.savedValue)
setDependentStringNotEqual(s, "mastervolume", "0");
me.TR(me);
me.TDempty(me, 0.2);
- s = makeXonoticDecibelsSlider(-20, 0, 0.5, "snd_channel0volume");
+ s = makeXonoticDecibelsSlider(-40, 0, 1, "snd_channel0volume");
me.TD(me, 1, 0.8, e = makeXonoticSliderCheckBox(-1000000, 1, s, _("Info:")));
if(s.value != e.savedValue)
e.savedValue = 0; // default
setDependentStringNotEqual(s, "mastervolume", "0");
me.TR(me);
me.TDempty(me, 0.2);
- s = makeXonoticDecibelsSlider(-20, 0, 0.5, "snd_channel3volume");
+ s = makeXonoticDecibelsSlider(-40, 0, 1, "snd_channel3volume");
me.TD(me, 1, 0.8, e = makeXonoticSliderCheckBox(-1000000, 1, s, _("Items:")));
if(s.value != e.savedValue)
e.savedValue = 0; // default
setDependentStringNotEqual(s, "mastervolume", "0");
me.TR(me);
me.TDempty(me, 0.2);
- s = makeXonoticDecibelsSlider(-20, 0, 0.5, "snd_channel6volume");
+ s = makeXonoticDecibelsSlider(-40, 0, 1, "snd_channel6volume");
me.TD(me, 1, 0.8, e = makeXonoticSliderCheckBox(-1000000, 1, s, _("Pain:")));
if(s.value != e.savedValue)
e.savedValue = 0; // default
setDependentStringNotEqual(s, "mastervolume", "0");
me.TR(me);
me.TDempty(me, 0.2);
- s = makeXonoticDecibelsSlider(-20, 0, 0.5, "snd_channel7volume");
+ s = makeXonoticDecibelsSlider(-40, 0, 1, "snd_channel7volume");
me.TD(me, 1, 0.8, e = makeXonoticSliderCheckBox(-1000000, 1, s, _("Player:")));
if(s.value != e.savedValue)
e.savedValue = 0; // default
setDependentStringNotEqual(s, "mastervolume", "0");
me.TR(me);
me.TDempty(me, 0.2);
- s = makeXonoticDecibelsSlider(-20, 0, 0.5, "snd_channel4volume");
+ s = makeXonoticDecibelsSlider(-40, 0, 1, "snd_channel4volume");
me.TD(me, 1, 0.8, e = makeXonoticSliderCheckBox(-1000000, 1, s, _("Shots:")));
if(s.value != e.savedValue)
e.savedValue = 0; // default
setDependentStringNotEqual(s, "mastervolume", "0");
me.TR(me);
me.TDempty(me, 0.2);
- s = makeXonoticDecibelsSlider(-20, 0, 0.5, "snd_channel2volume");
+ s = makeXonoticDecibelsSlider(-40, 0, 1, "snd_channel2volume");
me.TD(me, 1, 0.8, e = makeXonoticSliderCheckBox(-1000000, 1, s, _("Voice:")));
if(s.value != e.savedValue)
e.savedValue = 0; // default
setDependentStringNotEqual(s, "mastervolume", "0");
me.TR(me);
me.TDempty(me, 0.2);
- s = makeXonoticDecibelsSlider(-20, 0, 0.5, "snd_channel1volume");
+ s = makeXonoticDecibelsSlider(-40, 0, 1, "snd_channel1volume");
makeMulti(s, "snd_channel5volume"); // @!#%'n Tuba
me.TD(me, 1, 0.8, e = makeXonoticSliderCheckBox(-1000000, 1, s, _("Weapons:")));
if(s.value != e.savedValue)
#ifdef IMPLEMENTATION
+float toDecibelOfSquare(float f)
+{
+ return 20.0 * log10(f);
+}
+
+float fromDecibelOfSquare(float f)
+{
+ return pow(10, f / 20.0);
+}
+
entity makeXonoticDecibelsSlider(float theValueMin, float theValueMax, float theValueStep, string theCvar)
{
entity me;
return;
v = cvar(me.cvarName);
- if(v >= 0.98)
- Slider_setValue( me, 0 );
- else if(v < 0.0005)
- Slider_setValue( me, -1000000 );
+
+ // snapping
+ if(v > fromDecibelOfSquare(me.valueMax - 0.5 * me.valueStep))
+ Slider_setValue(me, me.valueMax);
+ else if(v < fromDecibelOfSquare(me.valueMin - 0.5 * me.valueStep))
+ Slider_setValue(me, -1000000); // virtually infinite
else
- Slider_setValue( me, 0.1 * floor(0.5 + 10.0 * log10(cvar(me.cvarName)) * 10) );
+ Slider_setValue(me, me.valueStep * floor(0.5 + toDecibelOfSquare(v) / me.valueStep) );
}
void XonoticDecibelsSlider_saveCvars(entity me)
{
if not(me.cvarName)
return;
- if(me.value >= -0.1)
- cvar_set(me.cvarName, "1");
- if(me.value < -33)
+ if(me.value > me.valueMax - 0.5 * me.valueStep)
+ cvar_set(me.cvarName, ftos(fromDecibelOfSquare(me.valueMax)));
+ else if(me.value < me.valueMin - 0.5 * me.valueStep)
cvar_set(me.cvarName, "0");
else
- cvar_set(me.cvarName, ftos(pow(10, me.value / 10)));
+ cvar_set(me.cvarName, ftos(fromDecibelOfSquare(me.value)));
}
string XonoticDecibelsSlider_valueToText(entity me, float v)
{
- if(v < -33)
- return CTX(_("VOL^OFF"));
- else if(v >= -0.1)
+ if(v > me.valueMax - 0.5 * me.valueStep)
return CTX(_("VOL^MAX"));
+ else if(v < me.valueMin - 0.5 * me.valueStep)
+ return CTX(_("VOL^OFF"));
return sprintf(_("%s dB"), SUPER(XonoticDecibelsSlider).valueToText(me, v));
}
float autocvar__notarget;
float autocvar__independent_players;
+float autocvar__campaign_testrun;
float autocvar__campaign_index;
string autocvar__campaign_name;
float autocvar__sv_init;
float autocvar_g_sandbox_object_material_velocity_min;
float autocvar_g_sandbox_object_material_velocity_factor;
float autocvar_g_max_info_autoscreenshot;
+float autocvar_physics_ode;
cvar_string = cvar_string_normal;
cvar_set = cvar_set_normal;
cvar_set("g_campaign", "0");
- print("campaign initialization failed: ", s, "\n");
+ print("^4campaign initialization failed: ", s, "\n");
+ if(autocvar__campaign_testrun)
+ error("CAMPAIGN FAIL AHAHAHAHAHAHAHAHAH))");
return 1;
}
// now some sanity checks
if(Campaign_Invalid())
return;
- cvar_set("fraglimit", ftos(campaign_fraglimit[0]));
- cvar_set("timelimit", ftos(campaign_timelimit[0]));
- cvar_set_normal("fraglimit", ftos(campaign_fraglimit[0]));
- cvar_set_normal("timelimit", ftos(campaign_timelimit[0]));
+ if(autocvar__campaign_testrun)
+ {
+ cvar_set("fraglimit", "0");
+ cvar_set("timelimit", "0.01");
+ cvar_set_normal("fraglimit", "0");
+ cvar_set_normal("timelimit", "0.01");
+ }
+ else
+ {
+ cvar_set("fraglimit", ftos(campaign_fraglimit[0]));
+ cvar_set("timelimit", ftos(campaign_timelimit[0]));
+ cvar_set_normal("fraglimit", ftos(campaign_fraglimit[0]));
+ cvar_set_normal("timelimit", ftos(campaign_timelimit[0]));
+ }
}
void CampaignSaveCvar(string cvarname, float value)
head = head.chain;
}
- if(won == 1 && lost == 0 && checkrules_equality == 0 && cheatcount_total == 0)
+ if(autocvar__campaign_testrun)
+ {
+ campaign_won = 1;
+ bprint("Campaign test run, advancing level.\n");
+ }
+ else if(won == 1 && lost == 0 && checkrules_equality == 0)
{
if(autocvar_timelimit != 0 && autocvar_fraglimit != 0 && time > autocvar_timelimit * 60) // checks if the timelimit has expired.
{
// sound!
}
- if(campaign_won)
+ if(campaign_won && cheatcount_total == 0 && !autocvar__campaign_testrun)
{
- if(campaign_entries < 2)
+ if(campaign_level == cvar_normal(campaign_index_var))
{
- // I have won
- if(campaign_level == cvar_normal(campaign_index_var))
+ if(campaign_entries < 2)
{
+ // I have won
savevar = strcat("g_campaign", campaign_name, "_won");
CampaignSaveCvar(savevar, 1);
// advance level (for menu to show it right)
CampaignSaveCvar(campaign_index_var, campaign_level + 1);
}
- }
- else if(campaign_level == cvar_normal(campaign_index_var))
- {
- // advance level
- CampaignSaveCvar(campaign_index_var, campaign_level + 1);
+ else
+ {
+ // advance level
+ CampaignSaveCvar(campaign_index_var, campaign_level + 1);
+ }
}
}
}
if(campaign_won && campaign_entries < 2)
{
// last map won!
+ print("^2test run: campaign looks GOOD\n");
localcmd("togglemenu 1\n");
CampaignFile_Unload();
return;
if (vlen(force))
if (self.classname != "player" || time >= self.spawnshieldtime || g_midair)
{
- self.velocity = self.velocity + damage_explosion_calcpush(self.damageforcescale * force, self.velocity, autocvar_g_balance_damagepush_speedfactor);
+ vector farce = damage_explosion_calcpush(self.damageforcescale * force, self.velocity, autocvar_g_balance_damagepush_speedfactor);
+ if(self.movetype == MOVETYPE_PHYSICS)
+ {
+ entity farcent;
+ farcent = spawn();
+ farcent.classname = "farce";
+ farcent.enemy = self;
+ farcent.movedir = farce * 10;
+ if(self.mass)
+ farcent.movedir = farcent.movedir * self.mass;
+ farcent.origin = hitloc;
+ farcent.forcetype = FORCETYPE_FORCEATPOS;
+ farcent.nextthink = time + 0.1;
+ farcent.think = SUB_Remove;
+ }
+ else
+ self.velocity = self.velocity + farce;
self.flags &~= FL_ONGROUND;
UpdateCSQCProjectile(self);
}
#define G_MODEL_INIT(sol) \
+ if(self.geomtype) if(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) self.movetype = MOVETYPE_PHYSICS; \
if(!self.scale) self.scale = self.modelscale; \
SetBrushEntityModel(); \
self.use = g_model_setcolormaptoactivator; \
if(!self.solid) self.solid = (sol); else if(self.solid < 0) self.solid = SOLID_NOT;
#define G_CLIENTMODEL_INIT(sol) \
+ if(self.geomtype) if(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) self.movetype = MOVETYPE_PHYSICS; \
if(!self.scale) self.scale = self.modelscale; \
SetBrushEntityModel(); \
self.use = g_clientmodel_setcolormaptoactivator; \
// - for this timelimit_overtime needs to be >0 of course
// - also check the winning condition calculated in the previous frame and only add normal overtime
// again, if at the point at which timelimit would be extended again, still no winner was found
- if ((checkrules_overtimesadded >= 0) && (checkrules_overtimesadded < autocvar_timelimit_overtimes) && autocvar_timelimit_overtime && !(g_race && !g_race_qualifying))
+ if (!autocvar_g_campaign && (checkrules_overtimesadded >= 0) && (checkrules_overtimesadded < autocvar_timelimit_overtimes) && autocvar_timelimit_overtime && !(g_race && !g_race_qualifying))
{
return 1; // need to call InitiateOvertime later
}
{
if(!checkrules_suddendeathend)
{
- checkrules_suddendeathend = time + 60 * autocvar_timelimit_suddendeath;
+ if(autocvar_g_campaign)
+ checkrules_suddendeathend = time; // no suddendeath in campaign
+ else
+ checkrules_suddendeathend = time + 60 * autocvar_timelimit_suddendeath;
if(g_race && !g_race_qualifying)
race_StartCompleting();
}
leadlimit = 0; // no leadlimit for now
}
- if(g_onslaught)
- timelimit = 0; // ONS has its own overtime rule
-
if(timelimit > 0)
{
timelimit += game_starttime;
return;
}
+ if(g_onslaught)
+ timelimit = 0; // ONS has its own overtime rule
+
float wantovertime;
wantovertime = 0;
d = d + 1;
e = e.chain;
}
- d = d * self.max_health / 300;
+ if(autocvar_g_campaign && autocvar__campaign_testrun)
+ d = d * self.max_health;
+ else
+ d = d * self.max_health / max(30, 60 * autocvar_timelimit_suddendeath);
Damage(self, self, self, d, DEATH_HURTTRIGGER, self.origin, '0 0 0');
}
else if (overtime_msg_time)
void WarpZone_Fade_PreDraw()
{
- if(self.warpzone_fadestart)
- {
- vector org;
- org = getpropertyvec(VF_ORIGIN);
+ vector org;
+ org = getpropertyvec(VF_ORIGIN);
+ if(!checkpvs(org, self)) // this makes sense as long as we don't support recursive warpzones
+ self.alpha = 0;
+ else if(self.warpzone_fadestart)
self.alpha = bound(0, (self.warpzone_fadeend - vlen(org - self.origin - 0.5 * (self.mins + self.maxs))) / (self.warpzone_fadeend - self.warpzone_fadestart), 1);
- }
else
self.alpha = 1;
//print(sprintf("%v <-> %v\n", view_origin, self.origin + 0.5 * (self.mins + self.maxs)));
// how to draw
// engine currently wants this
- if(self.warpzone_fadestart)
- self.predraw = WarpZone_Fade_PreDraw;
- else
- self.drawmask = MASK_NORMAL;
+ self.predraw = WarpZone_Fade_PreDraw;
}
void WarpZone_Camera_Read(float isnew)
// how to draw
// engine currently wants this
- if(self.warpzone_fadestart)
- self.predraw = WarpZone_Fade_PreDraw;
- else
- self.drawmask = MASK_NORMAL;
+ self.predraw = WarpZone_Fade_PreDraw;
}
void CL_RotateMoves(vector ang) = #638;