seta scoreboard_accuracy_border_thickness 1 "accuracy stats border thickness"
seta scoreboard_accuracy_doublerows 0 "use two rows instead of one"
seta scoreboard_accuracy_nocolors 0 "don't use colors displaying accuracy stats"
-seta scoreboard_accuracy 1 "show weapon accuracy stats panel on scoreboard; colors can be configured with accuracy_color* cvars"
+seta scoreboard_accuracy 0 "show weapon accuracy stats panel on scoreboard; colors can be configured with accuracy_color* cvars"
seta scoreboard_color_bg_r 0 "red color component of the scoreboard background"
seta scoreboard_color_bg_g 0.4 "green color component of the scoreboard background"
seta scoreboard_color_bg_b 0.6 "blue color component of the scoreboard background"
COLOR_INPUTBOX_F '1 1 1'
MARGIN_INPUTBOX_CHARS 1
+// item: clear button
+// uses "clearbutton" images
+OFFSET_CLEARBUTTON -0.3
+COLOR_CLEARBUTTON_N '1 1 1'
+COLOR_CLEARBUTTON_C '1 1 1'
+COLOR_CLEARBUTTON_F '1 1 1'
+
// item: key grabber
COLOR_KEYGRABBER_TITLES '1 1 1'
ALPHA_KEYGRABBER_TITLES 1
COLOR_INPUTBOX_F '1 1 1'
MARGIN_INPUTBOX_CHARS 1
+// item: clear button
+// uses "clearbutton" images
+OFFSET_CLEARBUTTON -0.5
+COLOR_CLEARBUTTON_N '1 1 1'
+COLOR_CLEARBUTTON_C '1 1 1'
+COLOR_CLEARBUTTON_F '1 1 1'
+
// item: key grabber
COLOR_KEYGRABBER_TITLES '1 1 1'
ALPHA_KEYGRABBER_TITLES 1
COLOR_INPUTBOX_F '1 1 1'
MARGIN_INPUTBOX_CHARS 1
+// item: clear button
+// uses "clearbutton" images
+OFFSET_CLEARBUTTON 0
+COLOR_CLEARBUTTON_N '1 1 1'
+COLOR_CLEARBUTTON_C '1 1 1'
+COLOR_CLEARBUTTON_F '1 1 1'
+
// item: key grabber
COLOR_KEYGRABBER_TITLES '1 1 1'
ALPHA_KEYGRABBER_TITLES 1
if(spectatee_status == -1)
s = sprintf(_("^1Press ^3%s^1 to spectate"), getcommandkey("primary fire", "+fire"));
else
- s = sprintf(_("^1Press ^3%s^1 for another player"), getcommandkey("primary fire", "+fire"));
+ s = sprintf(_("^1Press ^3%s^1 or ^3%s^1 for next or previous player"), getcommandkey("next weapon", "weapnext"), getcommandkey("previous weapon", "weapprev"));
drawInfoMessage(s)
if(spectatee_status == -1)
CHECK_MAX_COUNT(name, DT_MAX, DT_COUNT, "deathtypes") \
\
entity deathent = spawn(); \
- deathtypes[(name - DT_FIRST) - 1] = deathent; \
+ deathtypes[(name - DT_FIRST)] = deathent; \
deathent.classname = "deathtype"; \
deathent.nent_name = #name; \
#if (msg_death != NO_MSG) \
{
if(DEATH_ISSPECIAL(deathtype))
{
- entity deathent = deathtypes[(deathtype - DT_FIRST) - 1];
+ entity deathent = deathtypes[(deathtype - DT_FIRST)];
if not(deathent) { backtrace("Deathtype_Name: Could not find deathtype entity!\n"); return ""; }
return deathent.nent_name;
}
METHOD(InputBox, setText, void(entity, string))
METHOD(InputBox, enterText, void(entity, string))
METHOD(InputBox, keyDown, float(entity, float, float, float))
+ METHOD(InputBox, mouseMove, float(entity, vector))
METHOD(InputBox, mouseRelease, float(entity, vector))
METHOD(InputBox, mousePress, float(entity, vector))
METHOD(InputBox, mouseDrag, float(entity, vector))
METHOD(InputBox, showNotify, void(entity))
+ METHOD(InputBox, resizeNotify, void(entity, vector, vector, vector, vector))
ATTRIB(InputBox, src, string, string_null)
ATTRIB(InputBox, color, vector, '1 1 1')
ATTRIB(InputBox, colorF, vector, '1 1 1')
ATTRIB(InputBox, maxLength, float, 255) // if negative, it counts bytes, not chars
+
+ ATTRIB(InputBox, enableClearButton, float, 1)
+ ATTRIB(InputBox, clearButton, entity, NULL)
+ ATTRIB(InputBox, cb_width, float, 0)
+ ATTRIB(InputBox, cb_pressed, float, 0)
+ ATTRIB(InputBox, cb_focused, float, 0)
+ ATTRIB(InputBox, cb_color, vector, '1 1 1')
+ ATTRIB(InputBox, cb_colorF, vector, '1 1 1')
+ ATTRIB(InputBox, cb_colorC, vector, '1 1 1')
ENDCLASS(InputBox)
void InputBox_Clear_Click(entity btn, entity me);
#endif
me.src = gfx;
me.cursorPos = theCursorPos;
}
+void InputBox_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
+{
+ SUPER(InputBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
+ if (me.enableClearButton)
+ {
+ me.cb_width = absSize_y / absSize_x;
+ me.cb_offset = bound(-1, me.cb_offset, 0) * me.cb_width; // bound to range -1, 0
+ me.keepspaceRight = me.keepspaceRight - me.cb_offset + me.cb_width;
+ }
+}
void InputBox_setText(entity me, string txt)
{
me.setText(me, "");
}
+float over_ClearButton(entity me, vector pos)
+{
+ if (pos_x >= 1 + me.cb_offset - me.cb_width)
+ if (pos_x < 1 + me.cb_offset)
+ if (pos_y >= 0)
+ if (pos_y < 1)
+ return 1;
+ return 0;
+}
+
+float InputBox_mouseMove(entity me, vector pos)
+{
+ if (me.enableClearButton)
+ {
+ if (over_ClearButton(me, pos))
+ {
+ me.cb_focused = 1;
+ return 1;
+ }
+ me.cb_focused = 0;
+ }
+ return 1;
+}
+
float InputBox_mouseDrag(entity me, vector pos)
{
float p;
- me.dragScrollPos = pos;
- p = me.scrollPos + pos_x - me.keepspaceLeft;
- me.cursorPos = draw_TextLengthUpToWidth(me.text, p, 0, me.realFontSize);
- me.lastChangeTime = time;
+ if(me.pressed)
+ {
+ me.dragScrollPos = pos;
+ p = me.scrollPos + pos_x - me.keepspaceLeft;
+ me.cursorPos = draw_TextLengthUpToWidth(me.text, p, 0, me.realFontSize);
+ me.lastChangeTime = time;
+ }
+ else if (me.enableClearButton)
+ {
+ if (over_ClearButton(me, pos))
+ {
+ me.cb_pressed = 1;
+ return 1;
+ }
+ }
+ me.cb_pressed = 0;
return 1;
}
float InputBox_mousePress(entity me, vector pos)
{
+ if (me.enableClearButton)
+ if (over_ClearButton(me, pos))
+ {
+ me.cb_pressed = 1;
+ return 1;
+ }
me.dragScrollTimer = time;
me.pressed = 1;
return InputBox_mouseDrag(me, pos);
float InputBox_mouseRelease(entity me, vector pos)
{
+ if(me.cb_pressed)
+ if (over_ClearButton(me, pos))
+ {
+ me.cb_pressed = 0;
+ InputBox_Clear_Click(world, me);
+ return 1;
+ }
+ float r = InputBox_mouseDrag(me, pos);
+ //reset cb_pressed after mouseDrag, mouseDrag could set cb_pressed in this case:
+ //mouse press out of the clear button, drag and then mouse release over the clear button
+ me.cb_pressed = 0;
me.pressed = 0;
- return InputBox_mouseDrag(me, pos);
+ return r;
}
void InputBox_enterText(entity me, string ch)
draw_ClearClip();
+ if (me.enableClearButton)
+ if (me.text != "")
+ {
+ if(me.focused && me.cb_pressed)
+ draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_c"), eX * me.cb_width + eY, me.cb_colorC, 1);
+ else if(me.focused && me.cb_focused)
+ draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_f"), eX * me.cb_width + eY, me.cb_colorF, 1);
+ else
+ draw_Picture(eX * (1 + me.cb_offset - me.cb_width), strcat(me.cb_src, "_n"), eX * me.cb_width + eY, me.cb_color, 1);
+ }
+
// skipping SUPER(InputBox).draw(me);
Item_draw(me);
}
}
float InputContainer_mouseMove(entity me, vector pos)
{
+ if(me.mouseFocusedChild != me.focusedChild) // if the keyboard moved the focus away
+ me.mouseFocusedChild = NULL; // force focusing
if(me._changeFocusXY(me, pos))
if(SUPER(InputContainer).mouseMove(me, pos))
return 1;
if(me.animationState == 0)
{
if(me.mouseFocusedChild)
- if(me.mouseFocusedChild != e)
+ if(me.mouseFocusedChild != e || me.mouseFocusedChild != me.selectedChild)
me.selectedChild = me.mouseFocusedChild;
return 1;
}
SKINVECTOR(COLOR_INPUTBOX_F, '1 1 1');
SKINFLOAT(MARGIN_INPUTBOX_CHARS, 1);
+ // item: clear button
+ SKINSTRING(GFX_CLEARBUTTON, "clearbutton");
+ SKINFLOAT(OFFSET_CLEARBUTTON, 0);
+ SKINVECTOR(COLOR_CLEARBUTTON_N, '1 1 1');
+ SKINVECTOR(COLOR_CLEARBUTTON_F, '1 1 1');
+ SKINVECTOR(COLOR_CLEARBUTTON_C, '1 1 1');
+
// item: key grabber
SKINVECTOR(COLOR_KEYGRABBER_TITLES, '1 1 1');
SKINFLOAT(ALPHA_KEYGRABBER_TITLES, 1);
return 0;
}
c = y * 16 + x;
- if(c != me.mouseSelectedCharacterCell)
+ if(c != me.mouseSelectedCharacterCell || me.mouseSelectedCharacterCell != me.selectedCharacterCell)
me.mouseSelectedCharacterCell = me.selectedCharacterCell = c;
return 1;
}
}
void XonoticDemoBrowserTab_fill(entity me)
{
- entity e;
- entity btn;
- entity dlist;
+ entity e, dlist;
me.TR(me);
me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "cl_autodemo", _("Automatically record demos while playing")));
me.TR(me);
me.TR(me);
me.TD(me, 1, 0.5, e = makeXonoticTextLabel(0, _("Filter:")));
- me.TD(me, 1, 0.5, btn = makeXonoticButton(_("Clear"), '0 0 0'));
- btn.onClick = InputBox_Clear_Click;
- me.TD(me, 1, 3, e = makeXonoticInputBox(0, string_null));
+ me.TD(me, 1, 3.5, e = makeXonoticInputBox(0, string_null));
dlist = makeXonoticDemoList();
e.onChange = DemoList_Filter_Change;
e.onChangeEntity = dlist;
- btn.onClickEntity = e;
dlist.controlledTextbox = e;
me.TR(me);
}
void XonoticServerListTab_fill(entity me)
{
- entity e, slist, btn;
+ entity e, slist;
slist = makeXonoticServerList();
me.TR(me);
me.TD(me, 1, 0.4, e = makeXonoticTextLabel(0, _("Filter:")));
- me.TD(me, 1, 0.6, btn = makeXonoticButton(_("Clear"), '0 0 0'));
- btn.onClick = InputBox_Clear_Click;
- me.TD(me, 1, me.columns - 0.6 * 4 - 0.4, e = makeXonoticInputBox(0, string_null));
+ me.TD(me, 1, me.columns - 0.6 * 3 - 0.4, e = makeXonoticInputBox(0, string_null));
e.onChange = ServerList_Filter_Change;
e.onChangeEntity = slist;
- btn.onClickEntity = e;
slist.controlledTextbox = e;
me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showempty", ZCTX(_("SRVS^Empty"))));
slist.filterShowEmpty = e.checked;
box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved
box.maxLength = -127; // negative means encoded length in bytes
box.saveImmediately = 1;
+ box.enableClearButton = 0;
label.textEntity = box;
me.TR(me);
me.TD(me, 5, 1, e = makeXonoticColorpicker(box));
me.TDempty(me, 0.2);
me.TD(me, 1, 1.8, e = makeXonoticTextLabel(0, _("Client UDP port:")));
me.TD(me, 1, 1, e = makeXonoticInputBox(0, "cl_port"));
+ e.enableClearButton = 0;
me.TR(me);
me.TR(me);
me.TDempty(me, 0.2);
}
void XonoticCvarsDialog_fill(entity me) // in this dialog, use SKINCOLOR_CVARLIST_CONTROLS to color ALL controls
{
- entity e, cvarlist, btn;
-
+
+ entity e, cvarlist;
+
cvarlist = makeXonoticCvarList();
-
+
cvarlist.color =
cvarlist.colorF =
cvarlist.color2 =
cvarlist.colorC =
SKINCOLOR_CVARLIST_CONTROLS;
-
+
me.TR(me);
me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Cvar filter:")));
- me.TD(me, 1, 0.5, btn = makeXonoticButton(_("Clear"), SKINCOLOR_CVARLIST_CONTROLS));
- me.TD(me, 1, me.columns - 1.5, e = makeXonoticInputBox(0, string_null));
+ me.TD(me, 1, me.columns - 1, e = makeXonoticInputBox(0, string_null));
e.color = SKINCOLOR_CVARLIST_CONTROLS;
e.colorF = SKINCOLOR_CVARLIST_CONTROLS;
+ e.cb_color = SKINCOLOR_CVARLIST_CONTROLS;
+ e.cb_colorC = SKINCOLOR_CVARLIST_CONTROLS;
+ e.cb_colorF = SKINCOLOR_CVARLIST_CONTROLS;
e.onChange = CvarList_Filter_Change;
e.onChangeEntity = cvarlist;
- btn.onClick = InputBox_Clear_Click;
- btn.onClickEntity = e;
cvarlist.controlledTextbox = e; // this COULD also be the Value box, but this leads to accidentally editing stuff
me.TR(me);
me.TD(me, me.rows - me.currentRow - 7, me.columns, cvarlist);
cvarlist.cvarValueBox = e;
e.color = SKINCOLOR_CVARLIST_CONTROLS;
e.colorF = SKINCOLOR_CVARLIST_CONTROLS;
+ e.cb_color = SKINCOLOR_CVARLIST_CONTROLS;
+ e.cb_colorC = SKINCOLOR_CVARLIST_CONTROLS;
+ e.cb_colorF = SKINCOLOR_CVARLIST_CONTROLS;
e.onChange = CvarList_Value_Change;
e.onChangeEntity = cvarlist;
e.onEnter = CvarList_End_Editing;
ATTRIB(XonoticInputBox, alpha, float, SKINALPHA_TEXT)
+ // Clear button attributes
+ ATTRIB(XonoticInputBox, cb_offset, float, SKINOFFSET_CLEARBUTTON) // bound to range -1, 0
+ ATTRIB(XonoticInputBox, cb_src, string, SKINGFX_CLEARBUTTON)
+ ATTRIB(XonoticInputBox, cb_color, vector, SKINCOLOR_CLEARBUTTON_N)
+ ATTRIB(XonoticInputBox, cb_colorF, vector, SKINCOLOR_CLEARBUTTON_F)
+ ATTRIB(XonoticInputBox, cb_colorC, vector, SKINCOLOR_CLEARBUTTON_C)
+
ATTRIB(XonoticInputBox, cvarName, string, string_null)
METHOD(XonoticInputBox, loadCvars, void(entity))
METHOD(XonoticInputBox, saveCvars, void(entity))
WriteEntity(MSG_ONE, self);
}
- if(g_lms)
- {
- // Only if the player cannot play at all
- if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666)
- self.frags = FRAGS_SPECTATOR;
- else
- self.frags = FRAGS_LMS_LOSER;
- }
- else if((g_race && g_race_qualifying) || g_cts)
+ if((g_race && g_race_qualifying) || g_cts)
{
if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
self.frags = FRAGS_LMS_LOSER;
// reset player keys
self.itemkeys = 0;
- // player is dead and becomes observer
- // FIXME fix LMS scoring for new system
- if(g_lms)
- {
- if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0)
- self.classname = "observer";
- }
-
MUTATOR_CALLHOOK(PutClientInServer);
if(gameover)
self.colormod = '1 1 1' * autocvar_g_player_brightness;
self.exteriorweaponentity.alpha = default_weapon_alpha;
- self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval*2;
- self.lms_traveled_distance = 0;
self.speedrunning = FALSE;
race_PostSpawn(spot);
}
+float SpectateSet()
+{
+ if(self.enemy.classname != "player")
+ return FALSE;
+ /*if(self.enemy.vehicle)
+ {
+
+ msg_entity = self;
+ WriteByte(MSG_ONE, SVC_SETVIEW);
+ WriteEntity(MSG_ONE, self.enemy);
+ //stuffcmd(self, "set viewsize $tmpviewsize \n");
+
+ self.movetype = MOVETYPE_NONE;
+ accuracy_resend(self);
+ }
+ else
+ {*/
+ msg_entity = self;
+ WriteByte(MSG_ONE, SVC_SETVIEW);
+ WriteEntity(MSG_ONE, self.enemy);
+ //stuffcmd(self, "set viewsize $tmpviewsize \n");
+ self.movetype = MOVETYPE_NONE;
+ accuracy_resend(self);
+
+ if(!SpectateUpdate())
+ PutObserverInServer();
+ //}
+ return TRUE;
+}
+
+float Spectate(entity pl)
+{
+ if(g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
+ if(pl.team != self.team)
+ return 0;
+
+ self.enemy = pl;
+ return SpectateSet();
+}
+
// Returns next available player to spectate if g_ca_spectate_enemies == 0
entity CA_SpectateNext(entity start) {
if (start.team == self.team) {
return other;
}
-float SpectateNext(entity _prefer) {
-
- if(_prefer)
- other = _prefer;
- else
- other = find(self.enemy, classname, "player");
-
+float SpectateNext()
+{
+ other = find(self.enemy, classname, "player");
+
if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) {
// CA and ca players when spectating enemies is forbidden
other = CA_SpectateNext(other);
if (!other)
other = find(other, classname, "player");
}
-
+
if (other)
self.enemy = other;
- if(self.enemy.classname == "player") {
- /*if(self.enemy.vehicle)
- {
-
- msg_entity = self;
- WriteByte(MSG_ONE, SVC_SETVIEW);
- WriteEntity(MSG_ONE, self.enemy);
- //stuffcmd(self, "set viewsize $tmpviewsize \n");
-
- self.movetype = MOVETYPE_NONE;
- accuracy_resend(self);
- }
- else
- {*/
- msg_entity = self;
- WriteByte(MSG_ONE, SVC_SETVIEW);
- WriteEntity(MSG_ONE, self.enemy);
- //stuffcmd(self, "set viewsize $tmpviewsize \n");
- self.movetype = MOVETYPE_NONE;
- accuracy_resend(self);
-
- if(!SpectateUpdate())
- PutObserverInServer();
- //}
- return 1;
- } else {
- return 0;
+ return SpectateSet();
+}
+
+float SpectatePrev()
+{
+ // NOTE: chain order is from the highest to the lower entnum (unlike find)
+ other = findchain(classname, "player");
+ if not(other) // no player
+ return FALSE;
+
+ entity first = other;
+ // skip players until current spectated player
+ if(self.enemy)
+ while(other && other != self.enemy)
+ other = other.chain;
+
+ if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
+ {
+ do { other = other.chain; }
+ while(other && other.team != self.team);
+
+ if not(other)
+ {
+ other = first;
+ while(other.team != self.team)
+ other = other.chain;
+ if(other == self.enemy)
+ return TRUE;
+ }
+ }
+ else
+ {
+ if(other.chain)
+ other = other.chain;
+ else
+ other = first;
}
+ self.enemy = other;
+ return SpectateSet();
}
/*
self.flags |= FL_SPAWNING;
} else if(self.BUTTON_ATCK && !self.version_mismatch) {
self.flags &~= FL_JUMPRELEASED;
- if(SpectateNext(world) == 1) {
+ if(SpectateNext()) {
self.classname = "spectator";
}
} else {
if (self.BUTTON_JUMP && !self.version_mismatch) {
self.flags &~= FL_JUMPRELEASED;
self.flags |= FL_SPAWNING;
- } else if(self.BUTTON_ATCK) {
+ } else if(self.BUTTON_ATCK || self.impulse == 10 || self.impulse == 15 || self.impulse == 18 || self.impulse >= 200 && self.impulse <= 209) {
+ self.flags &~= FL_JUMPRELEASED;
+ if(SpectateNext()) {
+ self.classname = "spectator";
+ } else {
+ self.classname = "observer";
+ PutClientInServer();
+ }
+ self.impulse = 0;
+ } else if(self.impulse == 12 || self.impulse == 16 || self.impulse == 19 || self.impulse >= 220 && self.impulse <= 229) {
self.flags &~= FL_JUMPRELEASED;
- if(SpectateNext(world) == 1) {
+ if(SpectatePrev()) {
self.classname = "spectator";
} else {
self.classname = "observer";
PutClientInServer();
}
+ self.impulse = 0;
} else if (self.BUTTON_ATCK2) {
self.flags &~= FL_JUMPRELEASED;
self.classname = "observer";
mjumpheight = autocvar_sv_jumpvelocity;
if (self.waterlevel >= WATERLEVEL_SWIMMING)
{
- if (self.watertype == CONTENT_WATER)
- self.velocity_z = 200;
- else if (self.watertype == CONTENT_SLIME)
- self.velocity_z = 80;
- else
- self.velocity_z = 50;
-
+ self.velocity_z = self.stat_sv_maxspeed * 0.7;
return;
}
else
self.respawn_countdown = -1; // do not count down
- if(g_lms || g_cts || autocvar_g_forced_respawn)
+ if(g_cts || autocvar_g_forced_respawn)
self.respawn_flags = self.respawn_flags | RESPAWN_FORCE;
self.death_time = time;
race_ReadyRestart();
else MUTATOR_CALLHOOK(reset_map_global);
- lms_lowest_lives = 999;
- lms_next_place = player_count;
-
for(self = world; (self = nextent(self)); )
if(clienttype(self) == CLIENTTYPE_NOTACLIENT)
{
//NEW: changed behaviour so that it prevents that previous spectators/observers suddenly spawn as players
if (IS_PLAYER(self)) {
//PlayerScore_Clear(self);
- if(g_lms)
- PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives());
self.killcount = 0;
//stop the player from moving so that he stands still once he gets respawned
self.velocity = '0 0 0';
.float spawnshieldtime;
-.float lms_nextcheck;
-.float lms_traveled_distance;
-
.entity flagcarried;
.float playerid;
{
if(DEATH_ISSPECIAL(deathtype))
{
- entity deathent = deathtypes[(deathtype - DT_FIRST) - 1];
+ entity deathent = deathtypes[(deathtype - DT_FIRST)];
if not(deathent) { backtrace("Obituary_SpecialDeath: Could not find deathtype entity!\n"); return; }
if(murder)
g_pinata = 0; // incompatible
g_weapon_stay = 0; // incompatible
WEPSET_COPY_AA(start_weapons, g_weaponarena_weapons);
- if(!g_ca)
- start_items |= IT_UNLIMITED_AMMO;
+ start_items |= IT_UNLIMITED_AMMO;
}
else if (g_minstagib)
{
}
else
{
- if(g_ca)
- {
- start_ammo_shells = cvar("g_lms_start_ammo_shells");
- start_ammo_nails = cvar("g_lms_start_ammo_nails");
- start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
- start_ammo_cells = cvar("g_lms_start_ammo_cells");
- start_ammo_fuel = cvar("g_lms_start_ammo_fuel");
- }
- else
- {
- start_ammo_shells = cvar("g_start_ammo_shells");
- start_ammo_nails = cvar("g_start_ammo_nails");
- start_ammo_rockets = cvar("g_start_ammo_rockets");
- start_ammo_cells = cvar("g_start_ammo_cells");
- start_ammo_fuel = cvar("g_start_ammo_fuel");
- }
- }
-
- if (g_ca)
- {
- start_health = cvar("g_lms_start_health");
- start_armorvalue = cvar("g_lms_start_armor");
+ start_ammo_shells = cvar("g_start_ammo_shells");
+ start_ammo_nails = cvar("g_start_ammo_nails");
+ start_ammo_rockets = cvar("g_start_ammo_rockets");
+ start_ammo_cells = cvar("g_start_ammo_cells");
+ start_ammo_fuel = cvar("g_start_ammo_fuel");
}
if (inWarmupStage)
return 1;
}
+MUTATOR_HOOKFUNCTION(ca_SetStartItems)
+{
+ start_health = cvar("g_lms_start_health");
+ start_armorvalue = cvar("g_lms_start_armor");
+
+ start_ammo_shells = cvar("g_lms_start_ammo_shells");
+ start_ammo_nails = cvar("g_lms_start_ammo_nails");
+ start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
+ start_ammo_cells = cvar("g_lms_start_ammo_cells");
+ start_ammo_fuel = cvar("g_lms_start_ammo_fuel");
+
+ start_items &~= IT_UNLIMITED_AMMO;
+
+ return 0;
+}
+
void ca_Initialize()
{
allowed_to_spawn = TRUE;
MUTATOR_HOOK(ForbidPlayerScore_Clear, ca_ForbidPlayerScore_Clear, CBC_ORDER_ANY);
MUTATOR_HOOK(ForbidThrowCurrentWeapon, ca_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
MUTATOR_HOOK(GiveFragsForKill, ca_GiveFragsForKill, CBC_ORDER_FIRST);
+ MUTATOR_HOOK(SetStartItems, ca_SetStartItems, CBC_ORDER_ANY);
MUTATOR_ONADD
{
}
// mutator hooks
-MUTATOR_HOOKFUNCTION(lms_PlayerSpawn)
+MUTATOR_HOOKFUNCTION(lms_ResetMap)
+{
+ lms_lowest_lives = 999;
+ lms_next_place = player_count;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_ResetPlayers)
{
- if(IS_PLAYER(self))
if(restart_mapalreadyrestarted || (time < game_starttime))
+ FOR_EACH_CLIENT(self)
+ if(IS_PLAYER(self))
PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives());
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_PlayerPreSpawn)
+{
+ // player is dead and becomes observer
+ // FIXME fix LMS scoring for new system
+ if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0)
+ self.classname = "observer";
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(lms_PlayerSpawn)
+{
+ self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval*2;
+ self.lms_traveled_distance = 0;
return FALSE;
}
+MUTATOR_HOOKFUNCTION(lms_PlayerDies)
+{
+ self.respawn_flags |= RESPAWN_FORCE;
+
+ return FALSE;
+}
+
MUTATOR_HOOKFUNCTION(lms_RemovePlayer)
{
// Only if the player cannot play at all
return FALSE;
}
-MUTATOR_HOOKFUNCTION(lms_BotSpawn)
-{
- // temporary hack to give bots lives
- if(PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()) <= 0)
- {
- PlayerScore_Add(self, SP_LMS_RANK, 666);
- self.frags = FRAGS_SPECTATOR;
- }
-
- return FALSE;
-}
-
// scoreboard stuff
void lms_ScoreRules()
{
MUTATOR_DEFINITION(gamemode_lms)
{
+ MUTATOR_HOOK(reset_map_global, lms_ResetMap, CBC_ORDER_ANY);
+ MUTATOR_HOOK(reset_map_players, lms_ResetPlayers, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PutClientInServer, lms_PlayerPreSpawn, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerSpawn, lms_PlayerSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerDies, lms_PlayerDies, CBC_ORDER_ANY);
MUTATOR_HOOK(MakePlayerObserver, lms_RemovePlayer, CBC_ORDER_ANY);
MUTATOR_HOOK(ClientConnect, lms_ClientConnect, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPreThink, lms_PlayerThink, CBC_ORDER_ANY);
MUTATOR_HOOK(ForbidPlayerScore_Clear, lms_KeepScore, CBC_ORDER_ANY);
MUTATOR_HOOK(FilterItem, lms_FilterItem, CBC_ORDER_ANY);
MUTATOR_HOOK(ItemTouch, lms_ItemTouch, CBC_ORDER_ANY);
- MUTATOR_HOOK(HavocBot_ChooseRule, lms_BotSpawn, CBC_ORDER_ANY);
MUTATOR_ONADD
{
// lives related defs
float lms_lowest_lives;
float lms_next_place;
-float LMS_NewPlayerLives();
\ No newline at end of file
+float LMS_NewPlayerLives();
+
+// camp check
+.float lms_nextcheck;
+.float lms_traveled_distance;
\ No newline at end of file
float _spectate(entity _player)
{
- if(SpectateNext(_player) == 1)
+ if(Spectate(_player) == 1)
{
PutObserverInServer();
self.classname = "spectator";
+ (v_up * swing_factor * autocvar_g_balance_shotgun_secondary_melee_swing_up)
+ (v_right * swing_factor * autocvar_g_balance_shotgun_secondary_melee_swing_side));
- WarpZone_traceline_antilag(self.realowner, self.realowner.origin + self.realowner.view_ofs, targpos, FALSE, self.realowner, ANTILAG_LATENCY(self.realowner));
+ WarpZone_traceline_antilag(self, self.realowner.origin + self.realowner.view_ofs, targpos, FALSE, self, ANTILAG_LATENCY(self.realowner));
// draw lightning beams for debugging
//te_lightning2(world, targpos, self.realowner.origin + self.realowner.view_ofs + v_forward * 5 - v_up * 5);
entity meleetemp;
meleetemp = spawn();
- meleetemp.owner = meleetemp.realowner = self;
+ meleetemp.realowner = self;
meleetemp.think = shotgun_meleethink;
meleetemp.nextthink = time + autocvar_g_balance_shotgun_secondary_melee_delay * W_WeaponRateFactor();
W_SetupShot_Range(self, TRUE, 0, "", 0, autocvar_g_balance_shotgun_secondary_damage, autocvar_g_balance_shotgun_secondary_melee_range);