TTS mode spawnshield - -maniac|Su- - 11-24-2012
hi folks
is it possible to implement a spawnshield mode in Xonotic like the TTS mode in Nexuiz ...
The TTS mode was created by Fish
The code was nearly:
Code: Index: data/qcsrc/server/g_damage.qc
===================================================================
--- data/qcsrc/server/g_damage.qc (revision 8003)
+++ data/qcsrc/server/g_damage.qc (working copy)
@@ -370,12 +370,38 @@
}
}
+ ///MODIFICATION///
+ local float fragsup, spawnfrag;
+ fragsup = 1;
+ spawnfrag = FALSE;
+ if (tts_spawnshield_mode != 0)
+ if(time < targ.tts_spawnshieldfinished || (tts_spawnshield_mode == 2 && time < attacker.tts_spawnshieldfinished)) {
+ fragsup = 0;
+ spawnfrag = TRUE;
+ }
+ if (targ.classname=="corpse")
+ fragsup = 0;
+
+ local string typefragremark;
+ local string spawnfragremark;
+
+ if (targ.buttonchat) typefragremark = "^7type";
+ else typefragremark = "";
+ if (spawnfrag) spawnfragremark = "^2spawn";
+ else spawnfragremark = "";
+
+
if(sv_gentle > 0) {
- centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, "^4You scored against ^7", s));
+ centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, blood_message, "^4You scored against ^7", s));
centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, a,"^1 scored against you ^7"));
} else {
- centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, blood_message, "^4You fragged ^7", s));
- centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, victim_message, "^1You were fragged by ^7", a));
+ if((cvar("sv_fragmessage_information_typefrag")) && (targ.BUTTON_CHAT)) {
+ centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, blood_message, "^4You ^1typefragged ^7", s));
+ centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, victim_message, "^1You were typefragged by ^7", a));
+ } else {
+ centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, blood_message, "^4You ",spawnfragremark, typefragremark,"^4fragged ^7", s));
+ centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, victim_message, "^1You were ",spawnfragremark, typefragremark, "^1fragged by ^7", a));
+ }
attacker.taunt_soundtime = time + 1;
}
@@ -435,7 +461,7 @@
GiveFrags(attacker, targ, 0); // for logging
}
else
- GiveFrags(attacker, targ, 1);
+ GiveFrags(attacker, targ, fragsup);
if (targ.killcount > 2) {
if(sv_gentle)
@@ -713,6 +739,12 @@
self = oldself;
return;
}
+
+ ///MODIFICATION///
+ if ((deathtype == WEP_MINSTANEX) && damage) {
+ attacker.tts_hits ++;
+ }
+
if (targ.armorvalue && (deathtype == WEP_MINSTANEX) && damage)
{
targ.armorvalue -= 1;
Index: data/qcsrc/server/defs.qh
===================================================================
--- data/qcsrc/server/defs.qh (revision 8003)
+++ data/qcsrc/server/defs.qh (working copy)
@@ -623,3 +623,15 @@
.entity clientdata;
.entity personal;
+
+
+///MODIFICATION///
+.float tts_powerups_invis_fire_recoverfinished;
+.float tts_powerups_invis_fire_recoverduration;
+.float tts_powerups_invis_started;
+.float tts_spawnshieldfinished;
+.float tts_powerups_invis_nextflicker;
+.float tts_hits;
+.float tts_shotsfired;
+float tts_lockedgame;
+float tts_gamefrozen;
Index: data/qcsrc/server/w_minstanex.qc
===================================================================
--- data/qcsrc/server/w_minstanex.qc (revision 8003)
+++ data/qcsrc/server/w_minstanex.qc (working copy)
@@ -179,10 +179,27 @@
{
if (self.BUTTON_ATCK)
{
- if (weapon_prepareattack(0, cvar("g_balance_minstanex_refire")))
+ ///MODIFICATION///
+ local float refire_factor;
+ refire_factor = 1.0;
+
+ local float actual_refire;
+ actual_refire = cvar("g_balance_minstanex_refire") * refire_factor;
+
+ if (tts_spawnshield_mode == 1 && time < self.tts_spawnshieldfinished)
+ self.tts_spawnshieldfinished = time;
+
+ if (weapon_prepareattack(0, actual_refire))
{
W_MinstaNex_Attack();
weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_minstanex_animtime"), w_ready);
+ ///MODIFICATION///
+ if(g_minstagib && (self.items & IT_STRENGTH) && tts_powerups_invis_fire_recovertime>0) {
+ self.tts_powerups_invis_fire_recoverfinished =
+ time + tts_powerups_invis_fire_recovertime;
+ self.tts_powerups_invis_fire_recoverduration = tts_powerups_invis_fire_recovertime;
+ }
+ self.tts_shotsfired ++;
}
}
else if (self.BUTTON_ATCK2)
Index: data/qcsrc/server/miscfunctions.qc
===================================================================
--- data/qcsrc/server/miscfunctions.qc (revision 8003)
+++ data/qcsrc/server/miscfunctions.qc (working copy)
@@ -1042,6 +1042,30 @@
float sv_autotaunt;
float sv_taunt;
+
+
+///MODIFICATION///
+// Not all tts_ cvars have a declarator here, but most do.
+// Some are read on the fly, especially the welcomemessage ones
+float tts_powerups_reuse;
+float tts_powerups_invis_claim;
+float tts_powerups_speed_claim;
+
+float tts_powerups_invis_cloaktime;
+float tts_powerups_invis_fire_recovertime;
+float tts_powerups_invis_fire_alpha;
+float tts_powerups_invis_flicker_average;
+float tts_powerups_invis_flicker_deviation;
+float tts_powerups_invis_flicker_duration;
+
+float tts_spawnshield_time;
+float tts_spawnshield_mode;
+
+float tts_laser_jumpinterval;
+
+
+
+
void readlevelcvars(void)
{
g_bugrigs = cvar("g_bugrigs");
@@ -1168,6 +1192,24 @@
if not(inWarmupStage)
game_starttime = cvar("g_start_delay");
+
+ ///MODIFICATION///
+ tts_powerups_reuse = cvar("tts_powerups_reuse");
+ tts_powerups_invis_claim = cvar("tts_powerups_invis_claim");
+ tts_powerups_speed_claim = cvar("tts_powerups_speed_claim");
+
+ tts_powerups_invis_cloaktime = cvar("tts_powerups_invis_cloaktime");
+ tts_powerups_invis_fire_recovertime = cvar("tts_powerups_invis_fire_recovertime");
+ tts_powerups_invis_fire_alpha = cvar("tts_powerups_invis_fire_alpha");
+ tts_powerups_invis_flicker_average = cvar("tts_powerups_invis_flicker_average");
+ tts_powerups_invis_flicker_deviation = cvar("tts_powerups_invis_flicker_deviation");
+ tts_powerups_invis_flicker_duration = cvar("tts_powerups_invis_flicker_duration");
+
+ tts_spawnshield_time = cvar("tts_spawnshield_time");
+ tts_spawnshield_mode = cvar("tts_spawnshield_mode");
+
+ tts_laser_jumpinterval = cvar("tts_laser_jumpinterval");
+
readplayerstartcvars();
}
Index: data/qcsrc/server/cl_client.qc
===================================================================
--- data/qcsrc/server/cl_client.qc (revision 8003)
+++ data/qcsrc/server/cl_client.qc (working copy)
@@ -660,6 +660,10 @@
}
else
self.frags = FRAGS_SPECTATOR;
+
+ ///MODIFICATION///
+ self.tts_hits = 0;
+ self.tts_shotsfired = 0;
}
float RestrictSkin(float s)
@@ -671,6 +675,104 @@
return mod(s, 3);
}
+
+
+///MODIFICATION///
+
+float CountActivePlayers() {
+ local entity pl;
+ local float plcnt;
+ local float countbots;
+ if(cvar("tts_gamecommencing_botsareplayers")) {
+ FOR_EACH_PLAYER(pl) plcnt+=1;
+ } else {
+ FOR_EACH_REALPLAYER(pl) plcnt+=1;
+ }
+ return plcnt;
+}
+
+void GameCommencing_Think() {
+ local float plcnt;
+ local entity pl;
+ local entity oldself;
+
+ // Count number of players again, as they may have
+ // changed since the entity was created.
+ plcnt = CountActivePlayers();
+
+ //bprint("^1DEBUG: ^3GameCommencing entity think\n");
+
+ if(plcnt >= 2) {
+ // Output an info message in the console
+ print("^3Second player joined, starting game.\n");
+
+ // Respawn each player and reset their score
+ FOR_EACH_PLAYER(pl) {
+ oldself = self;
+ self = pl;
+ if(self.flagcarried)
+ DropFlag(self.flagcarried, world, world);
+ self.frags = 0;
+ //self.deaths = 0;
+ self.killcount = 0;
+ //self.tts_kills = 0;
+ //self.tts_suicides = 0;
+ self.tts_hits = 0;
+ self.tts_shotsfired = 0;
+ PlayerScore_Clear(self);
+ PutClientInServer();
+ self = oldself;
+ }
+
+ // Respawn all items
+ local entity it;
+ for(it=find(world,classname,"minstagib");it!=world;it=find(it,classname,"minstagib")) {
+ // NOTE: Checking for think is paramount! If think is not set,
+ // but nextthink is changed, the server ABORTS!
+ if(it.think)
+ it.nextthink = time;
+ }
+
+ // Remove dropped weapons
+ for(it=find(world,classname,"droppedweapon");it!=world;it=find(it,classname,"droppedweapon")) {
+ it.think = RemoveItem;
+ it.nextthink = time;
+ }
+ }
+
+ // Were no longer needed.
+ remove(self);
+}
+
+// Well, I tried to be as descriptive as possible in the function's name
+// It's supposed to be called on player join. If it counts 2 active players,
+// it respawns all players. (Counter-Strike style "Game Commencing")
+void OnJoinCheckAndRespawn() {
+ if(!cvar("tts_gamecommencing") || !g_minstagib) return;
+
+ local float plcnt;
+
+ // Count active players
+ plcnt = CountActivePlayers();
+
+ //bprint(strcat("^1DEBUG: ^3Player count now ",ftos(plcnt),"\n"));
+
+ if(plcnt==2) {
+ bcenterprint("^3Game commencing...\n");
+ local entity gamecommencing;
+
+ // Do not spawn game-commencing entity if one already exists
+ if( (gamecommencing=find(world,classname,"gamecommencing_entity")) == world )
+ gamecommencing = spawn();
+
+ gamecommencing.owner = world;
+ gamecommencing.classname = "gamecommencing_entity";
+ gamecommencing.think = GameCommencing_Think;
+ gamecommencing.nextthink = time + cvar("tts_gamecommencing_delay");
+ }
+}
+
+
void FixPlayermodel()
{
local string defaultmodel;
@@ -985,12 +1087,22 @@
for (j = WEP_FIRST; j <= WEP_LAST; ++j)
weapon_action(j, WR_RESETPLAYER);
+ ///MODIFICATION///
+ self.tts_powerups_invis_fire_recoverfinished = -1;
+ if (tts_spawnshield_mode != 0) {
+ self.tts_spawnshieldfinished = time + tts_spawnshield_time;
+ } else {
+ self.tts_spawnshieldfinished = 0;
+ }
+ self.tts_powerups_invis_nextflicker = -1;
+
oldself = self;
self = spot;
activator = oldself;
SUB_UseTargets();
activator = world;
self = oldself;
+
} else if(self.classname == "observer") {
PutObserverInServer ();
}
@@ -2116,6 +2228,9 @@
bprint ("^4", self.netname, "^4 is playing now\n");
if(!cvar("g_campaign"))
centerprint(self,""); // clear MOTD
+ ///MODIFICATION///
+ OnJoinCheckAndRespawn();
+
return;
} else {
stuffcmd(self,"menu_showteamselect\n");
It is very useful in duel matches
When a player connect match the games starts on 0:0 and spawnfrags dosn.t count ...
okidoki - what you all think about ?
GreetZ Su
RE: TTS mode spawnshield - Mr. Bougo - 11-24-2012
What's TTS?
RE: TTS mode spawnshield - Debugger - 11-24-2012
If the code you posted here is working properly, someone could definitely implement this.
Personally, I dislike the idea of a spawnshield.
Even though it helps the weaker player not to get raped via spawnkills, spawnkilling always was a part of this game. An option could be to implement this but not to enable it by default so the server admin can decide about this.
However, I would rather improve the spawning system itself than work on a spawnshield
RE: TTS mode spawnshield - rafallus - 11-24-2012
Ummm, there already is one, eg. on overkill servers, IIRC it works for 0.5s.
RE: TTS mode spawnshield - hutty - 11-24-2012
What's TTS?
RE: TTS mode spawnshield - asyyy - 11-24-2012
I agree, the current spawnshield sucks for minstagib. You can't kill the opponent but he kills you - very frustrating at times and it punishes most notably quick aimers. Maybe ask fish if he ports the TTS mod to Xonotic?
RE: TTS mode spawnshield - kojn^ - 11-24-2012
Yes, I dislike the spawn shield also, bloody annoying!
RE: TTS mode spawnshield - Mario - 11-24-2012
Rather than making the spawning player invincible, they could be semi transparent for the spawnshield time.
RE: TTS mode spawnshield - -maniac|Su- - 11-24-2012
The TTS mod was very useful in both Nexuiz Minsta Tournaments in 2009/2010 ..
Here some dokumentation facts by Fish aka <o()))>< :
Code: ========== Documentation of the TTS features =============
History:
TTS started as a small server-side mod for Nexuiz 2.4
specifically tailored to host minstagib tournament matches
(allowing the umpire to modify a player's score, for example).
Since Nexuiz doesn't provide any interface for external mods
or mutators, TTS was implemented by altering the source code
directly.
TTS never grew beyond a small server-side mod. On the contrary,
it shrunk.
When Nexuiz 2.5 was released, I ported TTS to the newer
version (meaning I applied the patch and worked through the
rejects), dropping features that were already present in some
form in the newer Nexuiz version or seemed obsolete or
unpopular to me.
The 2.5.1 release was just a minor step up, but 2.5.2 introduced
some changes to the code which cause the patch from 2.5.1 to
produce a lot of rejects again when applying to Nexuiz 2.5.2
or newer.
Nevertheless, some servers are still running whatever code you
get when you check out upstream Nexuiz from SVN and apply the
TTS patch for 2.5.1, ignoring rejects. This leaves you with
a very small feature set.
This rewrite of TTS starts as a clean(er) re-implementation of these
few features, using Nexuiz SVN revision 8770 as a basis (which will
likely remain the latest revision, as Nexuiz has been discontinued
and is being developed further as the Xonotic fork). Missing
features (or new features) will be (re-)implemented as requested
by the community.
Many, but not all, of the features documented below are only effective
if g_minstagib is set.
FIXME: Document for each feature if it requires g_minstagib.
================ Configuration variables =================
tts_welcomemessage
type: string
valid range: any string
default value: ""
description:
If not the empty string, this will be displayed to
every player when they connect.
tts_welcomemessage_delay
type: number
valid range: non-negative real number
default value: 10
description:
Sets the delay for tts_welcomemessage
tts_gamecommencing
type: flag
valid range: 0 or 1
default value: 0
description:
Enables or disables automatic score reset on join. If this
feature is enabled, when a player is playing alone and a
second player joins, the players' scores are reset and
the players are respawned.
tts_gamecommencing_delay
type: number
valid range: non-negative real
default value: 3
description:
Delay, in seconds, for automatic score reset.
tts_spawnshield_time
type: number
valid range: non-negative real
default value: 2
description:
Sets the time, in seconds, for the spawn shield.
The way spawn shield works is controlled with the
tts_spawnshield_mode cvar.
tts_spawnshield_mode
type: number
valid range: 0, 1 or 2
default value: 1
description:
If spawn shield is enabled, players get a grace period
after spawning during which they can be killed, but
the attacker doesnt score.
0: Disable spawn shield feature
1: Enable spawn shield. If a player fires
their gun during the spawn shield period,
they lose the spawn shield immediately, but score the
frag normally.
2: Enable spawn shield. If a player wearing spawn shield
kills another player, they dont score, but the shield
stays (meaning a player can never score during their own
spawn shield period).
========================= MUSEUM =========================
Everything from here down is NOT IMPLEMENTED anymore.
Note that you will NOT get any of the functionality by
applying the 2.5.1 TTS patch to 2.5.2 or newer and just
ignoring the rejects.
================ Configuration variables =================
tts_powerups_reuse
type: flag
valid range: 0 or 1
default value: 1
description:
Whether or not players drop powerup items when they die.
tts_powerups_invis_claim
type: number
valid range: nonnegative real number
default value: 20
description:
Time, in seconds, before a dropped invisibility powerup
disappears.
tts_powerups_speed_claim
type: number
valid range: nonnegative real number
default value: 20
description:
Time, in seconds, before a dropped speed powerup
disappears.
tts_powerups_invis_cloaktime
type: number
valid range: nonnegative real
default value: 2.0
description:
Time, in seconds, it takes a player to cloak and decloak.
tts_logprivatemessages
type: flag
valid range: 0 or 1
default value: 1
description:
Whether private messages appear in the server log
(i.e. they are printed to the server console)
The messages themselves are censored. Only the sender,
receiver and message length are logged.
tts_powerups_invis_fire_recovertime
type: number
valid range: nonnegative real
default value: 0
description:
Time, in seconds, it takes for a player to recloak
when they fire a shot while wearing invisibility.
tts_powerups_invis_fire_alpha
type: number
valid range: nonnegative real
default value: 0.1
description:
How much to increase alpha level when the player fires a shot.
This is added to the base alpha level set through
g_minstagib_invis_alpha
tts_powerups_invis_flicker_average
type: number
valid range: real number
default value: 4.0
description:
If nonnegative, specifies the average time between
invisibility failures (see tts_powerups_invis_flicker_deviation)
If negative, disables the flicker feature.
tts_powerups_invis_flicker_deviation
type: number
valid range: nonnegative real
default value: 1.5
description:
If tts_powerups_invis_flicker_average is nonnegative, invisibility
will "fail" from time to time, temporarily decloaking the player.
The time interval between successive failures is a random number
evenly distributed on the interval
(_average - _deviation, _average + _deviation)
tts_powerups_invis_flicker_duration
type: number
valid range: nonnegative real
default value: 0.8
description:
The time, in seconds, it takes invisibility to recover from
a failure.
[removed] tts_gamecommencing_botsareplayers
[removed] type: flag
[removed] valid range: 0 or 1
[removed] default value: 0
[removed] description:
[removed] Whether or not bots count as players for the purpose of the
[removed] tts_gamecommencing facility. This is a case where i promoted
[removed] a bug to a feature. Set to 1 to restore the old ("buggy")
[removed] behavior.
Removed these because i was too lazy to adapt them to 2.5.1. They're not really
important anyway. I might reintroduce them when someone asks.
[removed] tts_emptyservernomapchange
[removed] type: flag
[removed] valid range: 0 or 1
[removed] default value: 0
[removed] description:
[removed] If this flag is set, the server refrains from changing the
[removed] map when it is empty.
[removed] When the time limit for the current map expires and the
[removed] server is empty, the match time is extended by whatever
[removed] the initial time limit was, provided no player has connected
[removed] since the map has been on, and the maximum time limit set through
[removed] tts_emptyservernomapchange_maxtime has not yet been exceeded.
[removed] tts_emptyservernomapchange_maxtime
[removed] type: number
[removed] valid range: real number
[removed] default value: -1
[removed] description:
[removed] Sets the maximum time limit for mapchange prevention (see
[removed] tts_emptyservernomapchange)
[removed] Nonnegative values are interpreted as the maximum time limit,
[removed] in minutes. Negative values are interpreted as infinity, thus
[removed] allowing postponing the mapchange forever.
Nexuiz 2.5.1 now has the sv_vote_master_commands cvar, which fulfills the exact same
purpose as tts_vote_mastercommands.
[removed] tts_vote_mastercommands
[removed] type: string
[removed] valid range: any string
[removed] default value: ""
[removed] description:
[removed] A list of commands (just like sv_vote_commands) which can
[removed] only be executed by masters (using vdo), but cannot be issued
[removed] in a vcall.
tts_laser_jumpinterval
type: number
valid range: positive real number
default value: 0.9
description:
Refire time, in seconds, for the laser in minstagib.
This is hard-coded as 0.9 in vanilla Nexuiz.
tts_master_kickimmunity
type: flag
valid range: 0 or 1
default value: 0
description:
Whether or not, players logged in as masters are immune to
kicks and kickbans issued through vcall. This is only effective
if the player is already logged in as master at the time
the vote is called.
NEW: Also affects kicks issued through vdo, i.e. masters cannot
kick one another anymore. So disable this if you allow votes
to become master.
Maybe reintroduce this or something similar at a later time.
[removed] tts_master_referee
[removed] type: flag
[removed] valid range: 0 or 1
[removed] default value: 0
[removed] description:
[removed] Whether masters are considered "referees". This causes the
[removed] word "referee" to be displayed instead of "master" when a
[removed] master logs in or issues commands, but has no other effect.
tts_lockedgame_init
type: flag
valid range: 0 or 1
default value: 0
description:
Whether the game is initially "locked" after each mapchange.
See the lockgame server command for more info.
tts_noautomapchange
type: flag
valid range: 0 or 1
default value: 0
description:
If this flag is set, the map is not changed after a match has
ended. It has to be changed manually using gotomap each time.
A similar cvar now exists in Nexuiz 2.5.1, g_chat_nospectators. The semantics of
vanilla g_chat_nospectators has been altered, in that it is rendered ineffective
when the game ends.
[removed] tts_specchat_restricted
[removed] type: flag
[removed] valid range: 0 or 1
[removed] default value: 0
[removed] description:
[removed] If this flag is set, players do not see chat messages from spectators
[removed] until the match is over.
The functionality of tts_maxactiveplayers is now provided by g_maxplayers.
[removed] tts_maxactiveplayers
[removed] type: number
[removed] valid range: integer
[removed] default value: -1
[removed] description:
[removed] Specifies the maximum number of players that can play
[removed] simultaneously. Negative values are interpreted as infinity.
tts_printplayerstats
type: number
valid range: 0, 1 or 2
default value: 0
description:
When the match ends, player statistics can be printed into
the main chat. This variable controls how.
0: No stats are printed.
1: Each player only sees their own stats.
2: All stats are printed.
tts_defaultpowerupmode
type: string
valid range: "off", "on", "map", "ammo" or "noammo"
default value: "on"
description:
Sets the initial powerup mode. The powerup mode can be changed on the fly
using the powerupmode server command. See there.
tts_powerups_likelihood_invis
tts_powerups_likelihood_speed
tts_powerups_likelihood_lives
type: number
valid range: positive real number
default value: 1
description:
Each of these variables controls the probability of a powerup being
invisibility, speed or extra lives, respectively.
The sum does not have to be 1. The actual likelihood for a specific
type of powerup is the value of its controlling variable, divided by
the total.
============== Server commands ================
freezegame SWITCH
Freezes (if SWITCH is "on") or unfreezes the game (if SWITCH is "off").
While the game is frozen, players cannot move or shoot.
forcespec # NUM_1 ... NUM_N
Forces N players into spectator mode simultaneously.
NUM_1 through NUM_N are player numbers according to status.
The space after the pound sign (#) is mandatory.
forcejoin # NUM_1 ... NUM_N
Forces N spectators into the game simultaneously.
NUM_1 through NUM_N are player numbers according to status.
The space after the pound sign (#) is mandatory.
lockgame SWITCH
Locks or unlocks the game according to SWITCH (which can be
"on" or "off").
While the game is locked, players cannot leave the game and
spectators cannot join.
The initial state of the lock can be set with the
tts_lockedgame_init cvar.
awardfrags # PLNUM FRAGS
Adjusts a player's score.
PLNUM is the client number of a player according to status.
FRAGS is an integer that is added to the player's current
score.
powerupmode MODE
Changes the powerup mode in a minstagib game.
Possible values for MODE are:
"off": Removes all powerup items (invis, speed, lives) from the map.
"on": Randomly spawns invis, speed or lives in the powerup locations.
This the normal behavior of Nexuiz.
"map": The type of powerups is determined by the map. More to the point,
this spawns the respective MinstaGib items of normal powerups,
i.e. mega health becomes extra lives, strength becomes invisibility,
and invincibility becomes speed.
"ammo": Replaces powerups with ammunition.
"noammo": Removes all powerup items AND ammunition from the map.
NOTE: You cannot execute this command in your server.cfg in order to
set the initial powerup mode. The initial mode is controlled by the
tts_defaultpowerupmode variable.
removepowerups
This is an alias for powerupmode off
addpowerups
This is an alias for powerupmode on
assassinate # PLNUM
Assassinates the player with number PLNUM, according to status.
The player is killed and loses a frag, just like if they committed
suicide.
awarditem # PLNUM ITEM
Gives an item to the player with number PLNUM, according to status.
ITEM can be one of "ammo", "invis", "speed" and "lives".
============== Client commands ================
cmd mastermsg MESSAGE
Sends a master message, MESSAGE, to the chat. The message
is visible to all players connected to the server, regardless
of chat restrictions.
A player must be logged in as master to use this command.
[removed] cmd force_reset_view
[removed] Resets the player's camera.
Found here the orginal code:
Code: Index: data/qcsrc/server/g_damage.qc
===================================================================
--- data/qcsrc/server/g_damage.qc (revision 8003)
+++ data/qcsrc/server/g_damage.qc (working copy)
@@ -370,12 +370,38 @@
}
}
+ ///MODIFICATION///
+ local float fragsup, spawnfrag;
+ fragsup = 1;
+ spawnfrag = FALSE;
+ if (tts_spawnshield_mode != 0)
+ if(time < targ.tts_spawnshieldfinished || (tts_spawnshield_mode == 2 && time < attacker.tts_spawnshieldfinished)) {
+ fragsup = 0;
+ spawnfrag = TRUE;
+ }
+ if (targ.classname=="corpse")
+ fragsup = 0;
+
+ local string typefragremark;
+ local string spawnfragremark;
+
+ if (targ.buttonchat) typefragremark = "^7type";
+ else typefragremark = "";
+ if (spawnfrag) spawnfragremark = "^2spawn";
+ else spawnfragremark = "";
+
+
if(sv_gentle > 0) {
- centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, "^4You scored against ^7", s));
+ centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, blood_message, "^4You scored against ^7", s));
centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, a,"^1 scored against you ^7"));
} else {
- centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, blood_message, "^4You fragged ^7", s));
- centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, victim_message, "^1You were fragged by ^7", a));
+ if((cvar("sv_fragmessage_information_typefrag")) && (targ.BUTTON_CHAT)) {
+ centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, blood_message, "^4You ^1typefragged ^7", s));
+ centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, victim_message, "^1You were typefragged by ^7", a));
+ } else {
+ centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, blood_message, "^4You ",spawnfragremark, typefragremark,"^4fragged ^7", s));
+ centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, victim_message, "^1You were ",spawnfragremark, typefragremark, "^1fragged by ^7", a));
+ }
attacker.taunt_soundtime = time + 1;
}
@@ -435,7 +461,7 @@
GiveFrags(attacker, targ, 0); // for logging
}
else
- GiveFrags(attacker, targ, 1);
+ GiveFrags(attacker, targ, fragsup);
if (targ.killcount > 2) {
if(sv_gentle)
@@ -713,6 +739,12 @@
self = oldself;
return;
}
+
+ ///MODIFICATION///
+ if ((deathtype == WEP_MINSTANEX) && damage) {
+ attacker.tts_hits ++;
+ }
+
if (targ.armorvalue && (deathtype == WEP_MINSTANEX) && damage)
{
targ.armorvalue -= 1;
Index: data/qcsrc/server/defs.qh
===================================================================
--- data/qcsrc/server/defs.qh (revision 8003)
+++ data/qcsrc/server/defs.qh (working copy)
@@ -623,3 +623,15 @@
.entity clientdata;
.entity personal;
+
+
+///MODIFICATION///
+.float tts_powerups_invis_fire_recoverfinished;
+.float tts_powerups_invis_fire_recoverduration;
+.float tts_powerups_invis_started;
+.float tts_spawnshieldfinished;
+.float tts_powerups_invis_nextflicker;
+.float tts_hits;
+.float tts_shotsfired;
+float tts_lockedgame;
+float tts_gamefrozen;
Index: data/qcsrc/server/w_minstanex.qc
===================================================================
--- data/qcsrc/server/w_minstanex.qc (revision 8003)
+++ data/qcsrc/server/w_minstanex.qc (working copy)
@@ -179,10 +179,27 @@
{
if (self.BUTTON_ATCK)
{
- if (weapon_prepareattack(0, cvar("g_balance_minstanex_refire")))
+ ///MODIFICATION///
+ local float refire_factor;
+ refire_factor = 1.0;
+
+ local float actual_refire;
+ actual_refire = cvar("g_balance_minstanex_refire") * refire_factor;
+
+ if (tts_spawnshield_mode == 1 && time < self.tts_spawnshieldfinished)
+ self.tts_spawnshieldfinished = time;
+
+ if (weapon_prepareattack(0, actual_refire))
{
W_MinstaNex_Attack();
weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_minstanex_animtime"), w_ready);
+ ///MODIFICATION///
+ if(g_minstagib && (self.items & IT_STRENGTH) && tts_powerups_invis_fire_recovertime>0) {
+ self.tts_powerups_invis_fire_recoverfinished =
+ time + tts_powerups_invis_fire_recovertime;
+ self.tts_powerups_invis_fire_recoverduration = tts_powerups_invis_fire_recovertime;
+ }
+ self.tts_shotsfired ++;
}
}
else if (self.BUTTON_ATCK2)
Index: data/qcsrc/server/miscfunctions.qc
===================================================================
--- data/qcsrc/server/miscfunctions.qc (revision 8003)
+++ data/qcsrc/server/miscfunctions.qc (working copy)
@@ -1042,6 +1042,30 @@
float sv_autotaunt;
float sv_taunt;
+
+
+///MODIFICATION///
+// Not all tts_ cvars have a declarator here, but most do.
+// Some are read on the fly, especially the welcomemessage ones
+float tts_powerups_reuse;
+float tts_powerups_invis_claim;
+float tts_powerups_speed_claim;
+
+float tts_powerups_invis_cloaktime;
+float tts_powerups_invis_fire_recovertime;
+float tts_powerups_invis_fire_alpha;
+float tts_powerups_invis_flicker_average;
+float tts_powerups_invis_flicker_deviation;
+float tts_powerups_invis_flicker_duration;
+
+float tts_spawnshield_time;
+float tts_spawnshield_mode;
+
+float tts_laser_jumpinterval;
+
+
+
+
void readlevelcvars(void)
{
g_bugrigs = cvar("g_bugrigs");
@@ -1168,6 +1192,24 @@
if not(inWarmupStage)
game_starttime = cvar("g_start_delay");
+
+ ///MODIFICATION///
+ tts_powerups_reuse = cvar("tts_powerups_reuse");
+ tts_powerups_invis_claim = cvar("tts_powerups_invis_claim");
+ tts_powerups_speed_claim = cvar("tts_powerups_speed_claim");
+
+ tts_powerups_invis_cloaktime = cvar("tts_powerups_invis_cloaktime");
+ tts_powerups_invis_fire_recovertime = cvar("tts_powerups_invis_fire_recovertime");
+ tts_powerups_invis_fire_alpha = cvar("tts_powerups_invis_fire_alpha");
+ tts_powerups_invis_flicker_average = cvar("tts_powerups_invis_flicker_average");
+ tts_powerups_invis_flicker_deviation = cvar("tts_powerups_invis_flicker_deviation");
+ tts_powerups_invis_flicker_duration = cvar("tts_powerups_invis_flicker_duration");
+
+ tts_spawnshield_time = cvar("tts_spawnshield_time");
+ tts_spawnshield_mode = cvar("tts_spawnshield_mode");
+
+ tts_laser_jumpinterval = cvar("tts_laser_jumpinterval");
+
readplayerstartcvars();
}
Index: data/qcsrc/server/cl_client.qc
===================================================================
--- data/qcsrc/server/cl_client.qc (revision 8003)
+++ data/qcsrc/server/cl_client.qc (working copy)
@@ -660,6 +660,10 @@
}
else
self.frags = FRAGS_SPECTATOR;
+
+ ///MODIFICATION///
+ self.tts_hits = 0;
+ self.tts_shotsfired = 0;
}
float RestrictSkin(float s)
@@ -671,6 +675,104 @@
return mod(s, 3);
}
+
+
+///MODIFICATION///
+
+float CountActivePlayers() {
+ local entity pl;
+ local float plcnt;
+ local float countbots;
+ if(cvar("tts_gamecommencing_botsareplayers")) {
+ FOR_EACH_PLAYER(pl) plcnt+=1;
+ } else {
+ FOR_EACH_REALPLAYER(pl) plcnt+=1;
+ }
+ return plcnt;
+}
+
+void GameCommencing_Think() {
+ local float plcnt;
+ local entity pl;
+ local entity oldself;
+
+ // Count number of players again, as they may have
+ // changed since the entity was created.
+ plcnt = CountActivePlayers();
+
+ //bprint("^1DEBUG: ^3GameCommencing entity think\n");
+
+ if(plcnt >= 2) {
+ // Output an info message in the console
+ print("^3Second player joined, starting game.\n");
+
+ // Respawn each player and reset their score
+ FOR_EACH_PLAYER(pl) {
+ oldself = self;
+ self = pl;
+ if(self.flagcarried)
+ DropFlag(self.flagcarried, world, world);
+ self.frags = 0;
+ //self.deaths = 0;
+ self.killcount = 0;
+ //self.tts_kills = 0;
+ //self.tts_suicides = 0;
+ self.tts_hits = 0;
+ self.tts_shotsfired = 0;
+ PlayerScore_Clear(self);
+ PutClientInServer();
+ self = oldself;
+ }
+
+ // Respawn all items
+ local entity it;
+ for(it=find(world,classname,"minstagib");it!=world;it=find(it,classname,"minstagib")) {
+ // NOTE: Checking for think is paramount! If think is not set,
+ // but nextthink is changed, the server ABORTS!
+ if(it.think)
+ it.nextthink = time;
+ }
+
+ // Remove dropped weapons
+ for(it=find(world,classname,"droppedweapon");it!=world;it=find(it,classname,"droppedweapon")) {
+ it.think = RemoveItem;
+ it.nextthink = time;
+ }
+ }
+
+ // Were no longer needed.
+ remove(self);
+}
+
+// Well, I tried to be as descriptive as possible in the function's name
+// It's supposed to be called on player join. If it counts 2 active players,
+// it respawns all players. (Counter-Strike style "Game Commencing")
+void OnJoinCheckAndRespawn() {
+ if(!cvar("tts_gamecommencing") || !g_minstagib) return;
+
+ local float plcnt;
+
+ // Count active players
+ plcnt = CountActivePlayers();
+
+ //bprint(strcat("^1DEBUG: ^3Player count now ",ftos(plcnt),"\n"));
+
+ if(plcnt==2) {
+ bcenterprint("^3Game commencing...\n");
+ local entity gamecommencing;
+
+ // Do not spawn game-commencing entity if one already exists
+ if( (gamecommencing=find(world,classname,"gamecommencing_entity")) == world )
+ gamecommencing = spawn();
+
+ gamecommencing.owner = world;
+ gamecommencing.classname = "gamecommencing_entity";
+ gamecommencing.think = GameCommencing_Think;
+ gamecommencing.nextthink = time + cvar("tts_gamecommencing_delay");
+ }
+}
+
+
void FixPlayermodel()
{
local string defaultmodel;
@@ -985,12 +1087,22 @@
for (j = WEP_FIRST; j <= WEP_LAST; ++j)
weapon_action(j, WR_RESETPLAYER);
+ ///MODIFICATION///
+ self.tts_powerups_invis_fire_recoverfinished = -1;
+ if (tts_spawnshield_mode != 0) {
+ self.tts_spawnshieldfinished = time + tts_spawnshield_time;
+ } else {
+ self.tts_spawnshieldfinished = 0;
+ }
+ self.tts_powerups_invis_nextflicker = -1;
+
oldself = self;
self = spot;
activator = oldself;
SUB_UseTargets();
activator = world;
self = oldself;
+
} else if(self.classname == "observer") {
PutObserverInServer ();
}
@@ -2116,6 +2228,9 @@
bprint ("^4", self.netname, "^4 is playing now\n");
if(!cvar("g_campaign"))
centerprint(self,""); // clear MOTD
+ ///MODIFICATION///
+ OnJoinCheckAndRespawn();
+
return;
} else {
stuffcmd(self,"menu_showteamselect\n");
Maybe a dev should take a look at this ...
Without this mode minsta tournaments even not conceivably ...
GreetZ Su
RE: TTS mode spawnshield - Mr. Bougo - 11-25-2012
Note that Xonotic has a mutator API of some sort now, so the best way to port this would be to restructure it using that.
|