r2233 - in trunk/data: . qcsrc/server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Fri Mar 16 04:20:49 EDT 2007
Author: div0
Date: 2007-03-16 04:20:49 -0400 (Fri, 16 Mar 2007)
New Revision: 2233
Modified:
trunk/data/default.cfg
trunk/data/qcsrc/server/cl_weaponsystem.qc
trunk/data/qcsrc/server/clientcommands.qc
trunk/data/qcsrc/server/g_world.qc
trunk/data/qcsrc/server/w_crylink.qc
trunk/data/qcsrc/server/w_electro.qc
trunk/data/qcsrc/server/w_grenadelauncher.qc
trunk/data/qcsrc/server/w_hagar.qc
trunk/data/qcsrc/server/w_laser.qc
trunk/data/qcsrc/server/w_rocketlauncher.qc
Log:
added: g_projectiles_newton_style
selects different styles of projectile velocity physics:
0 = Quake
1 = Newton
2 = Newton + aimfix
3 = Quake + Newton-like velocity addition (actually not correct, but may have better gameplay)
4 = tZorkian
Modified: trunk/data/default.cfg
===================================================================
--- trunk/data/default.cfg 2007-03-15 17:49:07 UTC (rev 2232)
+++ trunk/data/default.cfg 2007-03-16 08:20:49 UTC (rev 2233)
@@ -788,3 +788,11 @@
seta _alientrap_net_banlist ""
set g_waypoints_for_items 1 // make waypoints out of items; values: 0 = never, 1 = unless the mapper prevents it by worldspawn.spawnflags & 1, 2 = always
+
+set g_projectiles_newton_style 0
+// possible values:
+// 0: absolute velocity projectiles (like Quake)
+// 1: relative velocity projectiles, "Newtonian" (like Tribes 2)
+// 2: relative velocity projectiles, but aim is precorrected so projectiles hit the crosshair (note: strafe rockets then are SLOWER than ones shot while standing; happens in 1 too when aiming correctly which is hard)
+// 3: absolute velocity + player velocity component in shot direction (note: does NOT yield the right relative velocity, but may be good enough)
+// 4: just add the player velocity length to the absolute velocity (tZork's sniper rockets)
Modified: trunk/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weaponsystem.qc 2007-03-15 17:49:07 UTC (rev 2232)
+++ trunk/data/qcsrc/server/cl_weaponsystem.qc 2007-03-16 08:20:49 UTC (rev 2233)
@@ -393,3 +393,81 @@
// VorteX: haste can be added here
};
+void(entity missile) W_SetupProjectileVelocity =
+{
+ vector pvelocity;
+ vector mdirection;
+ float mspeed;
+ float outspeed;
+ float nstyle;
+ vector mvelocity;
+ vector outvelocity;
+
+ if(missile.owner == world)
+ error("Unowned missile");
+ pvelocity = missile.owner.velocity;
+ mvelocity = missile.velocity;
+ mdirection = normalize(mvelocity);
+ mspeed = vlen(mvelocity);
+
+ nstyle = cvar("g_projectiles_newton_style");
+ if(nstyle == 0)
+ {
+ // absolute velocity
+ outvelocity = mvelocity;
+ }
+ else if(nstyle == 1)
+ {
+ // true Newtonian projectiles
+ outvelocity = pvelocity + mvelocity;
+ }
+ else if(nstyle == 2)
+ {
+ // true Newtonian projectiles with automatic aim adjustment
+ //
+ // solve: |outspeed * mdirection - pvelocity| = mspeed
+ // outspeed^2 - 2 * outspeed * (mdirection * pvelocity) + pvelocity^2 - mspeed^2 = 0
+ // outspeed = (mdirection * pvelocity) +- sqrt((mdirection * pvelocity)^2 - pvelocity^2 + mspeed^2)
+ // PLUS SIGN!
+ // not defined?
+ // then...
+ // pvelocity^2 - (mdirection * pvelocity)^2 > mspeed^2
+ // velocity without mdirection component > mspeed
+ // fire at smallest possible mspeed that works?
+ // |(mdirection * pvelocity) * pvelocity - pvelocity| = mspeed
+
+ float D;
+ float p;
+ float q;
+ p = mdirection * pvelocity;
+ q = pvelocity * pvelocity - mspeed * mspeed;
+ D = p * p - q;
+ if(D < 0)
+ {
+ dprint("impossible shot, adjusting\n");
+ D = 0;
+ }
+ outspeed = p + sqrt(D);
+ outspeed = bound(mspeed * 0.7, outspeed, mspeed * 5.0);
+ outvelocity = mdirection * outspeed;
+ }
+ else if(nstyle == 3)
+ {
+ // pseudo-Newtonian:
+ outspeed = mspeed + mdirection * pvelocity;
+ outspeed = bound(mspeed * 0.7, outspeed, mspeed * 5.0);
+ outvelocity = mdirection * outspeed;
+ }
+ else if(nstyle == 4)
+ {
+ // tZorkian:
+ outspeed = mspeed + vlen(pvelocity);
+ outvelocity = mdirection * outspeed;
+ }
+ else
+ error("g_projectiles_newton_style must be 0 (absolute), 1 (Newtonian), 2 (Newtonian + aimfix), 3 (pseudo Newtonian) or 4 (tZorkian)!");
+
+ dprint("Adjusted from ", vtos(missile.velocity));
+ missile.velocity = outvelocity;
+ dprint(" to ", vtos(missile.velocity), "\n");
+}
Modified: trunk/data/qcsrc/server/clientcommands.qc
===================================================================
--- trunk/data/qcsrc/server/clientcommands.qc 2007-03-15 17:49:07 UTC (rev 2232)
+++ trunk/data/qcsrc/server/clientcommands.qc 2007-03-16 08:20:49 UTC (rev 2233)
@@ -79,7 +79,6 @@
}
void SV_ParseClientCommand(string s) {
- local float index;
local string cmd;
tokenize(s);
Modified: trunk/data/qcsrc/server/g_world.qc
===================================================================
--- trunk/data/qcsrc/server/g_world.qc 2007-03-15 17:49:07 UTC (rev 2232)
+++ trunk/data/qcsrc/server/g_world.qc 2007-03-16 08:20:49 UTC (rev 2233)
@@ -3,6 +3,8 @@
string GetMapname();
void GotoNextMap();
void HandleMaplistShuffleCommands();
+void MapVote_Start(float n);
+float MapVote_Think();
void SetDefaultAlpha()
{
@@ -648,6 +650,29 @@
// isn't chosen in the first pass that should have been
}
+float() MapListMethod =
+{
+ float nextMap;
+
+ nextMap = -1;
+
+ if(nextMap == -1)
+ if(cvar("g_maplist_shuffle") > 0)
+ nextMap = MaplistMethod_Shuffle(cvar("g_maplist_shuffle") + 1);
+
+ if(nextMap == -1)
+ if(cvar("g_maplist_selectrandom"))
+ nextMap = MaplistMethod_Random();
+
+ if(nextMap == -1)
+ nextMap = MaplistMethod_Iterate();
+
+ if(nextMap == -1)
+ nextMap = MaplistMethod_Repeat();
+
+ return nextMap;
+}
+
void() GotoNextMap =
{
//local string nextmap;
@@ -709,40 +734,33 @@
return;
}
- for(allowReset = 1; allowReset >= 0; --allowReset)
+ if(cvar("g_vote_maps"))
{
- Maplist_Init();
- nextMap = -1;
+ MapVote_Start(cvar("g_vote_maps"));
+ }
+ else
+ {
+ for(allowReset = 1; allowReset >= 0; --allowReset)
+ {
+ Maplist_Init();
+ nextMap = MapListMethod();
- if(nextMap == -1)
- if(cvar("g_maplist_shuffle") > 0)
- nextMap = MaplistMethod_Shuffle(cvar("g_maplist_shuffle") + 1);
-
- if(nextMap == -1)
- if(cvar("g_maplist_selectrandom"))
- nextMap = MaplistMethod_Random();
-
- if(nextMap == -1)
- nextMap = MaplistMethod_Iterate();
-
- if(nextMap == -1)
- nextMap = MaplistMethod_Repeat();
-
- if(nextMap >= 0)
- {
- Map_Goto(nextMap);
- break;
- }
- else // PERMANENT FAILURE
- {
- if(allowReset)
+ if(nextMap >= 0)
{
- bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" );
- cvar_set("g_maplist", cvar_string("g_maplist_defaultlist"));
+ Map_Goto(nextMap);
+ break;
}
- else
+ else // PERMANENT FAILURE
{
- error("Everything is broken - not even the default map list works. Please report this to the developers.");
+ if(allowReset)
+ {
+ bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" );
+ cvar_set("g_maplist", cvar_string("g_maplist_defaultlist"));
+ }
+ else
+ {
+ error("Everything is broken - not even the default map list works. Please report this to the developers.");
+ }
}
}
}
@@ -760,6 +778,9 @@
.float autoscreenshot;
void() IntermissionThink =
{
+ if(MapVote_Think())
+ return;
+
if(cvar("sv_autoscreenshot"))
if(self.autoscreenshot)
if(time > self.autoscreenshot)
@@ -1590,3 +1611,206 @@
if(status == WINNING_YES)
NextLevel();
};
+
+float MapVote_starttime;
+float MapVote_nexttime;
+string MapVote_maps[10];
+float MapVote_votes[10];
+float MapVote_nmaps;
+float MapVote_round;
+.float MapVote_selected;
+
+void MapVote_Clear()
+{
+ entity e;
+ for(e = world; (e = findflags(e, flags, FL_CLIENT)) != world; ) if(clienttype(e) == CLIENTTYPE_REAL)
+ e.MapVote_selected = 0;
+}
+
+void MapVote_Start(float n)
+{
+ float m;
+ float i;
+ float j;
+ float k;
+ string ms;
+
+ MapVote_starttime = time;
+
+ Maplist_Init();
+ for(i = 0; i < n; ++i)
+ {
+ for(j = 0; j < 41; ++j)
+ {
+ m = MapListMethod();
+ if(m < 0)
+ goto out;
+ ms = strzone(argv(m));
+ for(k = 0; k < i; ++k)
+ {
+ if(MapVote_maps[k] == ms)
+ goto tryagain;
+ }
+ MapVote_maps[i] = ms;
+ goto next;
+:tryagain
+ }
+ // failed to find a new map in 42 attempts?
+ // give up
+ goto out;
+:next
+ }
+:out
+ MapVote_nmaps = i;
+ MapVote_Clear();
+}
+
+float RandomSelection_value;
+float RandomSelection_prio;
+float RandomSelection_n;
+void RandomSelection_init()
+{
+ RandomSelection_n = 0;
+ RandomSelection_prio = 0;
+}
+void RandomSelection_store(float value, float prio)
+{
+ if(prio > RandomSelection_prio)
+ {
+ RandomSelection_prio = prio;
+ RandomSelection_n = 1;
+ RandomSelection_value = value;
+ }
+ else if(prio == RandomSelection_prio)
+ {
+ RandomSelection_n += 1;
+ if(ceil(random() * RandomSelection_n) == 1)
+ RandomSelection_value = value;
+ }
+}
+
+void MapVote_Decide(float n)
+{
+ localcmd(strcat("exec \"maps/", MapVote_maps[n], ".mapcfg\"\n"));
+}
+
+float MapVote_Update()
+{
+ if(MapVote_nmaps == 0)
+ {
+ error("No maps found.");
+ return 0;
+ }
+ else if(MapVote_nmaps == 1)
+ {
+ MapVote_Decide(0);
+ return 1;
+ }
+ else
+ {
+ // check if we have a winner...
+ float firstPlace;
+ float firstPlaceVotes;
+ float secondPlace;
+ float secondPlaceVotes;
+ float votesTotal;
+ float notVoted;
+ entity e;
+ float i;
+
+ votesTotal = 0;
+ notVoted = 0;
+
+ for(i = 0; i < MapVote_nmaps; ++i)
+ MapVote_votes[i] = 0;
+ for(e = world; (e = findflags(e, flags, FL_CLIENT)) != world; ) if(clienttype(e) == CLIENTTYPE_REAL)
+ {
+ if(e.MapVote_selected == 0)
+ {
+ ++notVoted;
+ }
+ else
+ {
+ MapVote_votes[e.MapVote_selected - 1] = MapVote_votes[e.MapVote_selected - 1] + 1;
+ ++votesTotal;
+ }
+ }
+
+ RandomSelection_init();
+ for(i = 0; i < MapVote_nmaps; ++i)
+ RandomSelection_store(i, MapVote_votes[i]);
+ firstPlace = RandomSelection_value;
+ firstPlaceVotes = RandomSelection_prio;
+
+ RandomSelection_init();
+ for(i = 0; i < MapVote_nmaps; ++i)
+ if(i != firstPlace)
+ RandomSelection_store(i, MapVote_votes[i]);
+ secondPlace = RandomSelection_value;
+ secondPlaceVotes = RandomSelection_prio;
+
+ // absolute majority?
+ if(2 * firstPlaceVotes >= votesTotal + notVoted)
+ {
+ MapVote_Decide(firstPlace);
+ return 1;
+ }
+
+ if(time > MapVote_starttime + 10)
+ if(MapVote_round == 0)
+ {
+ MapVote_round = 1;
+ if(MapVote_nmaps > 2)
+ {
+ // clear all others
+ for(e = world; (e = findflags(e, flags, FL_CLIENT)) != world; ) if(clienttype(e) == CLIENTTYPE_REAL)
+ if(e.MapVote_selected != firstPlace)
+ if(e.MapVote_selected != secondPlace)
+ e.MapVote_selected = 0;
+ for(i = 0; i < MapVote_nmaps; ++i) if(i != firstPlace) if(i != secondPlace)
+ {
+ strunzone(MapVote_maps[i]);
+ MapVote_maps[i] = "";
+ }
+ }
+ }
+
+ if(time > MapVote_starttime + 15)
+ {
+ // simple majority suffices
+ MapVote_Decide(firstPlace);
+ return 1;
+ }
+
+ return 0;
+ }
+}
+
+void MapVote_Display()
+{
+}
+
+void MapVote_Keypressed(float k)
+{
+ // self pressed k
+}
+
+float MapVote_Think()
+{
+ if(!MapVote_starttime)
+ return 0;
+
+ if(time > MapVote_nexttime)
+ {
+ if(MapVote_Update())
+ return 1;
+ MapVote_nexttime = time + 5;
+ }
+
+ if(self.impulse >= 1 && self.impulse <= 10)
+ MapVote_Keypressed(self.impulse);
+
+ MapVote_Display();
+
+ return 1;
+}
Modified: trunk/data/qcsrc/server/w_crylink.qc
===================================================================
--- trunk/data/qcsrc/server/w_crylink.qc 2007-03-15 17:49:07 UTC (rev 2232)
+++ trunk/data/qcsrc/server/w_crylink.qc 2007-03-16 08:20:49 UTC (rev 2233)
@@ -96,6 +96,7 @@
setorigin (proj, w_shotorg);
proj.velocity = (w_shotdir + randomvec() * cvar("g_balance_crylink_primary_spread")) * cvar("g_balance_crylink_primary_speed");
+ W_SetupProjectileVelocity(proj);
proj.touch = W_Crylink_Touch;
proj.think = SUB_Remove;
proj.nextthink = time + cvar("g_balance_crylink_primary_lifetime");
@@ -140,6 +141,7 @@
setorigin (proj, w_shotorg);
proj.velocity = (w_shotdir + (((counter + 0.5) / shots) * 2 - 1) * v_right * cvar("g_balance_crylink_secondary_spread")) * cvar("g_balance_crylink_secondary_speed");
+ W_SetupProjectileVelocity(proj);
proj.touch = W_Crylink_Touch2;
proj.think = SUB_Remove;
proj.nextthink = time + cvar("g_balance_crylink_secondary_lifetime");
Modified: trunk/data/qcsrc/server/w_electro.qc
===================================================================
--- trunk/data/qcsrc/server/w_electro.qc 2007-03-15 17:49:07 UTC (rev 2232)
+++ trunk/data/qcsrc/server/w_electro.qc 2007-03-16 08:20:49 UTC (rev 2233)
@@ -103,6 +103,7 @@
proj.effects = EF_BRIGHTFIELD | EF_FULLBRIGHT | EF_NOSHADOW | EF_LOWPRECISION;
proj.movetype = MOVETYPE_FLY;
proj.velocity = w_shotdir * cvar("g_balance_electro_primary_speed");
+ W_SetupProjectileVelocity(proj);
proj.angles = vectoangles(proj.velocity);
proj.touch = W_Plasma_TouchExplode;
proj.flags = FL_PROJECTILE;
@@ -136,6 +137,7 @@
//proj.glow_color = 45;
proj.movetype = MOVETYPE_BOUNCE;
proj.velocity = v_forward * cvar("g_balance_electro_secondary_speed") + v_up * cvar("g_balance_electro_secondary_speed_up");
+ W_SetupProjectileVelocity(proj);
proj.touch = W_Plasma_Touch;
setmodel(proj, "models/ebomb.mdl");
setsize(proj, '0 0 -3', '0 0 -3');
Modified: trunk/data/qcsrc/server/w_grenadelauncher.qc
===================================================================
--- trunk/data/qcsrc/server/w_grenadelauncher.qc 2007-03-15 17:49:07 UTC (rev 2232)
+++ trunk/data/qcsrc/server/w_grenadelauncher.qc 2007-03-16 08:20:49 UTC (rev 2233)
@@ -99,6 +99,7 @@
gren.think = W_Grenade_Explode;
gren.touch = W_Grenade_Touch1;
gren.velocity = v_forward * cvar("g_balance_grenadelauncher_primary_speed") + v_up * cvar("g_balance_grenadelauncher_primary_speed_up");
+ W_SetupProjectileVelocity(gren);
gren.avelocity_x = random () * -500 - 500;
gren.angles = vectoangles (gren.velocity);
@@ -133,6 +134,7 @@
gren.damageforcescale = 4;
gren.event_damage = W_Grenade_Damage;
gren.velocity = v_forward * cvar("g_balance_grenadelauncher_secondary_speed") + v_up * cvar("g_balance_grenadelauncher_secondary_speed_up");
+ W_SetupProjectileVelocity(gren);
gren.avelocity = '100 150 100';
gren.angles = vectoangles (gren.velocity);
Modified: trunk/data/qcsrc/server/w_hagar.qc
===================================================================
--- trunk/data/qcsrc/server/w_hagar.qc 2007-03-15 17:49:07 UTC (rev 2232)
+++ trunk/data/qcsrc/server/w_hagar.qc 2007-03-16 08:20:49 UTC (rev 2233)
@@ -104,6 +104,7 @@
missile.movetype = MOVETYPE_FLY;
missile.velocity = (w_shotdir + randomvec() * cvar("g_balance_hagar_primary_spread")) * cvar("g_balance_hagar_primary_speed");
+ W_SetupProjectileVelocity(missile);
missile.angles = vectoangles (missile.velocity);
missile.flags = FL_PROJECTILE;
@@ -139,6 +140,7 @@
missile.movetype = MOVETYPE_BOUNCEMISSILE;
missile.velocity = (w_shotdir + randomvec() * cvar("g_balance_hagar_secondary_spread")) * cvar("g_balance_hagar_secondary_speed");
+ W_SetupProjectileVelocity(missile);
missile.avelocity = '100 10 10';
missile.angles = vectoangles (missile.velocity);
Modified: trunk/data/qcsrc/server/w_laser.qc
===================================================================
--- trunk/data/qcsrc/server/w_laser.qc 2007-03-15 17:49:07 UTC (rev 2232)
+++ trunk/data/qcsrc/server/w_laser.qc 2007-03-16 08:20:49 UTC (rev 2233)
@@ -48,6 +48,7 @@
setorigin (missile, w_shotorg);
missile.velocity = w_shotdir * cvar("g_balance_laser_speed");
+ W_SetupProjectileVelocity(missile);
missile.angles = vectoangles (missile.velocity);
//missile.glow_color = 250; // 244, 250
//missile.glow_size = 120;
Modified: trunk/data/qcsrc/server/w_rocketlauncher.qc
===================================================================
--- trunk/data/qcsrc/server/w_rocketlauncher.qc 2007-03-15 17:49:07 UTC (rev 2232)
+++ trunk/data/qcsrc/server/w_rocketlauncher.qc 2007-03-16 08:20:49 UTC (rev 2233)
@@ -210,6 +210,7 @@
missile.velocity = w_shotdir * cvar("g_balance_rocketlauncher_laserguided_speed");
else
missile.velocity = w_shotdir * cvar("g_balance_rocketlauncher_speed");
+ W_SetupProjectileVelocity(missile);
missile.angles = vectoangles (missile.velocity);
missile.touch = W_Rocket_Touch;
More information about the nexuiz-commits
mailing list