set g_spawnshieldtime 1 "number of seconds you are invincible after you spawned, this shield is lost after you fire"
set g_antilag 2 "AntiLag (0 = no AntiLag, 1 = verified client side hit scan, 2 = server side hit scan in the past, 3 = unverified client side hit scan)"
set g_antilag_nudge 0 "don't touch"
-set g_shootfromclient 2 "let client decide if it has the gun left or right; if set to 2, center handedness is allowed; see also cl_gunalign"
set g_shootfromeye 0 "shots are fired from your eye/crosshair; visual gun position can still be influenced by cl_gunalign 1 and 2"
set g_shootfromcenter 0 "weapon gets moved to the center, shots still come from the barrel of your weapon; visual gun position can still be influenced by cl_gunalign 1 and 2"
set g_shootfromfixedorigin "" "if set to a string like 0 y z, the gun is moved to the given y and z coordinates. If set to a string like x y z, the whole shot origin is used"
string tex;
vector rgb;
float t;
- int s;
vector vs;
float intensity, offset;
InterpolateOrigin_Do();
- s = autocvar_cl_gunalign;
- if(s != 1 && s != 2 && s != 4)
- s = 3; // default value
- --s;
+ int s = W_GetGunAlignment(world);
+
switch(self.HookType)
{
default:
#define IS_GAMETYPE(NAME) \
(MapInfo_LoadedGametype == MAPINFO_TYPE_##NAME)
-REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,false,"","timelimit=20 pointlimit=30 leadlimit=0",_("Score as many frags as you can."));
+REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,false,"","timelimit=20 pointlimit=30 leadlimit=0",_("Score as many frags as you can"));
-REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,false,"","timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left."));
+REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,false,"","timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left"));
-REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,false,"","timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line."))
+REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,false,"","timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line"))
{
if (!k) {
cvar_set("g_race_qualifying_timelimit", cvar_defstring("g_race_qualifying_timelimit"));
REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,false,"","timelimit=20",_("Race for fastest time."));
#define g_cts IS_GAMETYPE(CTS)
-REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,true,"","timelimit=20 pointlimit=50 teams=2 leadlimit=0",_("Help your team score the most frags against the enemy team."))
+REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,true,"","timelimit=20 pointlimit=50 teams=2 leadlimit=0",_("Help your team score the most frags against the enemy team"))
{
if (!k) {
cvar_set("g_tdm_teams", cvar_defstring("g_tdm_teams"));
}
#define g_tdm IS_GAMETYPE(TEAM_DEATHMATCH)
-REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,true,"","timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it, defend your base from the other team."));
+REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,true,"","timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it, defend your base from the other team"));
#define g_ctf IS_GAMETYPE(CTF)
-REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,true,"","timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round."))
+REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,true,"","timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round"))
{
if (!k) {
cvar_set("g_ca_teams", cvar_defstring("g_ca_teams"));
}
#define g_ca IS_GAMETYPE(CA)
-REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,true,"","timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture and defend all the control points to win."))
+REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,true,"","timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture and defend all the control points to win"))
{
if (!k) {
cvar_set("g_domination_default_teams", cvar_defstring("g_domination_default_teams"));
}
}
-REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,true,"","timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round."))
+REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,true,"","timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round"))
{
if (!k) {
cvar_set("g_keyhunt_teams", cvar_defstring("g_keyhunt_teams"));
}
}
-REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,true,"","timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out."));
+REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,true,"","timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out"));
#define g_assault IS_GAMETYPE(ASSAULT)
-REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,true,"","pointlimit=1 timelimit=20",_("Capture control points to reach and destroy the enemy generator."));
+REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,true,"","pointlimit=1 timelimit=20",_("Capture control points to reach and destroy the enemy generator"));
-REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,true,"","timelimit=20 pointlimit=5 leadlimit=0",_("Shoot and kick the ball into the enemies goal, keep your goal clean."));
+REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,true,"","timelimit=20 pointlimit=5 leadlimit=0",_("Shoot and kick the ball into the enemies goal, keep your goal clean"));
#define g_nexball IS_GAMETYPE(NEXBALL)
-REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,true,"","timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to teammates to revive them, freeze the most enemies to win."))
+REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,true,"","timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to teammates to revive them, freeze the most enemies to win"))
{
if (!k) {
cvar_set("g_freezetag_teams", cvar_defstring("g_freezetag_teams"));
}
#define g_freezetag IS_GAMETYPE(FREEZETAG)
-REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,true,"","timelimit=20 pointlimit=30",_("Hold the ball to get points for kills."));
+REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,true,"","timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
-REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,false,"","pointlimit=50 teams=0",_("Survive against waves of monsters."))
+REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,false,"","pointlimit=50 teams=0",_("Survive against waves of monsters"))
{
switch (k) {
case "teams":
#include "monster.qh"
-REGISTRY(Monsters, BIT(3))
+REGISTRY(Monsters, BIT(4))
REGISTER_REGISTRY(RegisterMonsters)
const int MON_FIRST = 1;
#define MON_LAST (Monsters_COUNT - 1)
if(self.targetname == "")
target_music_sendto(MSG_ALL, 1);
}
+void target_music_kill()
+{
+ for(self = world; (self = find(self, classname, "target_music")); )
+ {
+ self.volume = 0;
+ if(self.targetname == "")
+ target_music_sendto(MSG_ALL, 1);
+ else
+ target_music_sendto(MSG_ALL, 0);
+ }
+}
void target_music_use()
{
if(!activator)
void Ent_TriggerMusic_Remove();
void Ent_ReadTriggerMusic();
+
+#elif defined(SVQC)
+void target_music_kill();
#endif
#endif
return; // allready been triggered
}
+ if(self.spawnflags & 16384)
+ if(!IS_PLAYER(self.enemy))
+ return; // only players
+
if (self.classname == "trigger_secret")
{
if (!IS_PLAYER(self.enemy))
return normalize(cliptoplane(p, v));
}
+int W_GetGunAlignment(entity player)
+{
+#ifdef SVQC
+ int gunalign = player.cvar_cl_gunalign;
+#else
+ int gunalign = autocvar_cl_gunalign;
+#endif
+ if(gunalign < 1 || gunalign > 4)
+ gunalign = 3; // default value
+ --gunalign;
+
+ return gunalign;
+}
+
vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle)
{
float sigma;
#define CALCULATIONS_H
vector damage_explosion_calcpush(vector explosion_f, vector target_v, float speedfactor);
vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle);
+int W_GetGunAlignment(entity player);
#endif
if(isnew)
{
- // calculate shot origin offset from gun alignment
- int gunalign = autocvar_cl_gunalign;
- if(gunalign != 1 && gunalign != 2 && gunalign != 4)
- gunalign = 3; // default value
- --gunalign;
+ int gunalign = W_GetGunAlignment(world);
self.beam_shotorigin = arc_shotorigin[gunalign];
#include "int.qh"
#include "iter.qh"
#include "lazy.qh"
+#include "linkedlist.qh"
#include "log.qh"
#include "math.qh"
#include "misc.qh"
--- /dev/null
+#ifndef LINKEDLIST_H
+#define LINKEDLIST_H
+
+CLASS(LinkedListNode, Object)
+ ATTRIB(LinkedListNode, ll_data, entity, NULL)
+ ATTRIB(LinkedListNode, ll_prev, LinkedListNode, NULL)
+ ATTRIB(LinkedListNode, ll_next, LinkedListNode, NULL)
+ENDCLASS(LinkedListNode)
+
+CLASS(LinkedList, Object)
+ ATTRIB(LinkedList, ll_head, LinkedListNode, NULL);
+ ATTRIB(LinkedList, ll_tail, LinkedListNode, NULL);
+ENDCLASS(LinkedList)
+
+#define LL_NEW() NEW(LinkedList)
+
+/**
+ * Push to tail
+ */
+entity LL_PUSH(LinkedList this, entity e) {
+ LinkedListNode n = NEW(LinkedListNode);
+ n.ll_data = e;
+ n.ll_prev = this.ll_tail;
+ LinkedListNode tail = this.ll_tail;
+ if (tail) {
+ tail.ll_next = n;
+ } else {
+ this.ll_head = this.ll_tail = n;
+ }
+ return e;
+}
+
+/**
+ * Pop from tail
+ */
+entity LL_POP(LinkedList this) {
+ if (!this.ll_tail) return NULL;
+ LinkedListNode n = this.ll_tail;
+ entity e = n.ll_data;
+ LinkedListNode prev = n.ll_prev;
+ if (prev) {
+ prev.ll_next = NULL;
+ } else {
+ this.ll_head = this.ll_tail = NULL;
+ }
+ return e;
+}
+
+#define LL_EACH(list, cond, body) do { \
+ noref int i = 0; \
+ for (entity _it = list.ll_head; _it; (_it = _it.ll_next, ++i)) { \
+ noref entity it = _it.ll_data; \
+ if (cond) { body } \
+ } \
+} while(0)
+
+#endif
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
{
- if (!e.classname) e.classname = "net_linked";
+ if (e.classname == "") e.classname = "net_linked";
- if (!e.model || !self.modelindex) {
+ if (e.model == "" || self.modelindex == 0) {
vector mi = e.mins;
vector ma = e.maxs;
_setmodel(e, "null");
ATTRIB(ListBox, focusable, float, 1)
ATTRIB(ListBox, focusedItem, int, -1)
ATTRIB(ListBox, focusedItemAlpha, float, 0.3)
+ METHOD(ListBox, setFocusedItem, void(entity, int));
ATTRIB(ListBox, mouseMoveOffset, float, -1) // let know where the cursor is when the list scrolls without moving the cursor
ATTRIB(ListBox, allowFocusSound, float, 1)
ATTRIB(ListBox, selectedItem, int, 0)
ATTRIB(ListBox, origin, vector, '0 0 0')
ATTRIB(ListBox, scrollPos, float, 0) // measured in window heights, fixed when needed
ATTRIB(ListBox, scrollPosTarget, float, 0)
+ METHOD(ListBox, isScrolling, bool(entity));
ATTRIB(ListBox, needScrollToItem, float, -1)
METHOD(ListBox, scrollToItem, void(entity, int));
ATTRIB(ListBox, previousValue, float, 0)
METHOD(ListBox, clickListBoxItem, void(entity, float, vector)); // item number, relative clickpos
METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector)); // item number, relative clickpos
METHOD(ListBox, setSelected, void(entity, float));
+ METHOD(ListBox, focusedItemChangeNotify, void(entity));
METHOD(ListBox, getLastFullyVisibleItemAtScrollPos, float(entity, float));
METHOD(ListBox, getFirstFullyVisibleItemAtScrollPos, float(entity, float));
#endif
#ifdef IMPLEMENTATION
+bool ListBox_isScrolling(entity me)
+{
+ return (me.scrollPos != me.scrollPosTarget);
+}
+
void ListBox_scrollToItem(entity me, int i)
{
// scroll doesn't work properly until itemHeight is set to the correct value
}
else if(key == K_MWHEELDOWN)
{
- me.scrollPosTarget = min(me.scrollPosTarget + 0.5, me.getTotalHeight(me) - 1);
+ me.scrollPosTarget = min(me.scrollPosTarget + 0.5, max(0, me.getTotalHeight(me) - 1));
}
else if(key == K_PGUP || key == K_KP_PGUP)
{
me.mouseMoveOffset = pos.y;
else
{
- me.focusedItem = -1;
+ me.setFocusedItem(me, -1);
me.mouseMoveOffset = -1;
}
return 1;
else if(me.pressed == 2)
{
me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y));
- me.focusedItem = me.selectedItem;
+ me.setFocusedItem(me, me.selectedItem);
me.mouseMoveOffset = -1;
}
return 1;
me.pressed = 2;
// an item has been clicked. Select it, ...
me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y));
- me.focusedItem = me.selectedItem;
+ me.setFocusedItem(me, me.selectedItem);
}
return 1;
}
+void ListBox_setFocusedItem(entity me, int item)
+{
+ float focusedItem_save = me.focusedItem;
+ me.focusedItem = (item < me.nItems) ? item : -1;
+ if(focusedItem_save != me.focusedItem)
+ {
+ me.focusedItemChangeNotify(me);
+ if(me.focusedItem >= 0)
+ me.focusedItemAlpha = SKINALPHA_LISTBOX_FOCUSED;
+ }
+}
float ListBox_mouseRelease(entity me, vector pos)
{
if(me.pressed == 1)
// item dragging mode
// select current one one last time...
me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y));
- me.focusedItem = me.selectedItem;
+ me.setFocusedItem(me, me.selectedItem);
// and give it a nice click event
if(me.nItems > 0)
{
// by a mouse click on an item of the list
// for example showing a dialog on right click
me.pressed = 0;
- me.focusedItem = -1;
+ me.setFocusedItem(me, -1);
me.mouseMoveOffset = -1;
}
void ListBox_updateControlTopBottom(entity me)
vector oldshift, oldscale;
// we can't do this in mouseMove as the list can scroll without moving the cursor
- float focusedItem_save = me.focusedItem;
if(me.mouseMoveOffset != -1)
- me.focusedItem = me.getItemAtPos(me, me.scrollPos + me.mouseMoveOffset);
- if(me.focusedItem >= 0)
- if(focusedItem_save != me.focusedItem)
- me.focusedItemAlpha = SKINALPHA_LISTBOX_FOCUSED;
+ me.setFocusedItem(me, me.getItemAtPos(me, me.scrollPos + me.mouseMoveOffset));
if(me.needScrollToItem >= 0)
{
SUPER(ListBox).draw(me);
}
+void ListBox_focusedItemChangeNotify(entity me)
+{
+}
+
void ListBox_clickListBoxItem(entity me, float i, vector where)
{
// template method
vector menuTooltipSize;
float menuTooltipAlpha;
string menuTooltipText;
-float menuTooltipState; // 0: static, 1: fading in, 2: fading out
+float menuTooltipState; // 0: static, 1: fading in, 2: fading out, 3: forced fading out
float m_testmousetooltipbox(vector pos)
{
if(pos.x >= menuTooltipOrigin.x && pos.x < menuTooltipOrigin.x + menuTooltipSize.x)
}
return menuTooltipItem.tooltip;
}
+string prev_tooltip;
void m_tooltip(vector pos)
{
float f, i, w;
menuTooltipAveragedMousePos = menuTooltipAveragedMousePos * (1 - f) + pos * f;
f = vlen(pos - menuTooltipAveragedMousePos);
if(f < 0.01)
+ {
it = m_findtooltipitem(main, pos);
+
+ if(it.instanceOfListBox && it.isScrolling(it))
+ it = world;
+
+ if(it && prev_tooltip != it.tooltip)
+ {
+ // fade out if tooltip of a certain item has changed
+ menuTooltipState = 3;
+ if(prev_tooltip)
+ strunzone(prev_tooltip);
+ prev_tooltip = strzone(it.tooltip);
+ }
+ else if(menuTooltipItem && !m_testmousetooltipbox(pos))
+ menuTooltipState = 3; // fade out if mouse touches it
+
+ }
else
it = NULL;
}
fontsize = '1 0 0' * (SKINFONTSIZE_TOOLTIP / conwidth) + '0 1 0' * (SKINFONTSIZE_TOOLTIP / conheight);
- // float menuTooltipState; // 0: static, 1: fading in, 2: fading out
+ // float menuTooltipState; // 0: static, 1: fading in, 2: fading out, 3: forced fading out
if(it != menuTooltipItem)
{
switch(menuTooltipState)
else if(menuTooltipState == 2) // re-fade in?
menuTooltipState = 1;
- if(menuTooltipItem)
- if(!m_testmousetooltipbox(pos))
- menuTooltipState = 2; // fade out if mouse touches it
-
switch(menuTooltipState)
{
- case 1:
+ case 1: // fade in
menuTooltipAlpha = bound(0, menuTooltipAlpha + 5 * frametime, 1);
if(menuTooltipAlpha == 1)
menuTooltipState = 0;
break;
- case 2:
+ case 2: // fade out
+ case 3: // forced fade out
menuTooltipAlpha = bound(0, menuTooltipAlpha - 2 * frametime, 1);
if(menuTooltipAlpha == 0)
{
if (returns) returns(it.title, string_null);
return it;
}
+ METHOD(SettingSource, getEntryTooltip, entity(entity this, int i, void(string theTooltip) returns))
+ {
+ Lazy l = Settings[i];
+ entity it = l.m_get();
+ if (returns) returns(it.tooltip);
+ return it;
+ }
METHOD(SettingSource, reload, int(entity this, string filter)) { return Settings_COUNT; }
ENDCLASS(SettingSource)
ATTRIB(XonoticRegisteredSettingsList, source, DataSource, NULL)
ATTRIB(XonoticRegisteredSettingsList, onChange, void(entity, entity), func_null)
ATTRIB(XonoticRegisteredSettingsList, onChangeEntity, entity, NULL)
+ METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity));
+
string XonoticRegisteredSettingsList_cb_name;
- void XonoticRegisteredSettingsList_cb(string _name, string _icon)
+ string XonoticRegisteredSettingsList_cb_tooltip;
+ void XonoticRegisteredSettingsList_getNameIcon_cb(string _name, string _icon)
{
XonoticRegisteredSettingsList_cb_name = _name;
}
+ void XonoticRegisteredSettingsList_getTooltip_cb(string _tooltip)
+ {
+ XonoticRegisteredSettingsList_cb_tooltip = _tooltip;
+ }
+
METHOD(XonoticRegisteredSettingsList, drawListBoxItem, void(entity this, int i, vector absSize, bool isSelected, bool isFocused))
{
if (!this.source) return;
- if (!this.source.getEntry(this.source, i, XonoticRegisteredSettingsList_cb)) return;
+ if (!this.source.getEntry(this.source, i, XonoticRegisteredSettingsList_getNameIcon_cb)) return;
string name = XonoticRegisteredSettingsList_cb_name;
if (isSelected) {
draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
string s = draw_TextShortenToWidth(strdecolorize(name), 1, 0, this.realFontSize);
draw_Text(this.realUpperMargin * eY + (0.5 * this.realFontSize.x) * eX, s, this.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
}
+
+ METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity this))
+ {
+ if (this.focusedItem == -1 || !this.source)
+ {
+ clearTooltip(this);
+ return;
+ }
+ if (!this.source.getEntryTooltip(this, this.focusedItem, XonoticRegisteredSettingsList_getTooltip_cb))
+ {
+ clearTooltip(this);
+ return;
+ }
+ string theTooltip = XonoticRegisteredSettingsList_cb_tooltip;
+ if(theTooltip != "")
+ setZonedTooltip(this, theTooltip, string_null);
+ else
+ clearTooltip(this);
+ }
+
METHOD(XonoticRegisteredSettingsList, refilter, void(entity this))
{
if (!this.source) {
METHOD(XonoticGameModelSettingsTab, fill, void(entity));
METHOD(XonoticGameModelSettingsTab, showNotify, void(entity));
ATTRIB(XonoticGameModelSettingsTab, title, string, _("Models"))
+ ATTRIB(XonoticGameModelSettingsTab, tooltip, string, _("Customize how players and items are displayed in game"))
ATTRIB(XonoticGameModelSettingsTab, intendedWidth, float, 0.9)
ATTRIB(XonoticGameModelSettingsTab, rows, float, 13)
ATTRIB(XonoticGameModelSettingsTab, columns, float, 5)
METHOD(XonoticGametypeList, saveCvars, void(entity));
METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float));
METHOD(XonoticGametypeList, clickListBoxItem, void(entity, float, vector));
+ METHOD(XonoticGametypeList, focusedItemChangeNotify, void(entity));
ATTRIB(XonoticGametypeList, realFontSize, vector, '0 0 0')
ATTRIB(XonoticGametypeList, realUpperMargin, float, 0)
{
m_play_click_sound(MENU_SOUND_SELECT);
}
+void XonoticGametypeList_focusedItemChangeNotify(entity me)
+{
+ if(me.focusedItem >= 0)
+ setZonedTooltip(me, MapInfo_Type_Description(GameType_GetID(me.focusedItem)), string_null);
+ else
+ clearTooltip(me);
+}
#endif
CLASS(XonoticSlider, Slider)
METHOD(XonoticSlider, configureXonoticSlider, void(entity, float, float, float, string, string));
METHOD(XonoticSlider, setValue, void(entity, float));
+ METHOD(XonoticSlider, setValue_noAnim, void(entity, float));
ATTRIB(XonoticSlider, fontSize, float, SKINFONTSIZE_NORMAL)
ATTRIB(XonoticSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT)
ATTRIB(XonoticSlider, image, string, SKINGFX_SLIDER)
me.saveCvars(me);
}
}
+void XonoticSlider_setValue_noAnim(entity me, float val)
+{
+ if(val != me.value)
+ {
+ SUPER(XonoticSlider).setValue_noAnim(me, val);
+ me.saveCvars(me);
+ }
+}
void XonoticSlider_loadCvars(entity me)
{
if (!me.cvarName)
CLASS(XonoticTextSlider, TextSlider)
METHOD(XonoticTextSlider, configureXonoticTextSlider, void(entity, string, string));
METHOD(XonoticTextSlider, setValue, void(entity, float));
+ METHOD(XonoticTextSlider, setValue_noAnim, void(entity, float));
METHOD(XonoticTextSlider, configureXonoticTextSliderValues, void(entity));
ATTRIB(XonoticTextSlider, fontSize, float, SKINFONTSIZE_NORMAL)
ATTRIB(XonoticTextSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT)
me.saveCvars(me);
}
}
+void XonoticTextSlider_setValue_noAnim(entity me, float val)
+{
+ if(val != me.value)
+ {
+ SUPER(XonoticTextSlider).setValue_noAnim(me, val);
+ me.saveCvars(me);
+ }
+}
void XonoticTextSlider_loadCvars(entity me)
{
if (!me.cvarName)
int autocvar_g_respawn_waves;
bool autocvar_g_running_guns;
bool autocvar_g_shootfromcenter;
-int autocvar_g_shootfromclient;
bool autocvar_g_shootfromeye;
string autocvar_g_shootfromfixedorigin;
int autocvar_g_showweaponspawns;
{
// initialize parms for a new player
parm1 = -(86400 * 366);
+
+ MUTATOR_CALLHOOK(SetNewParms);
}
/*
{SELFPARAM();
// save parms for level change
parm1 = self.parm_idlesince - time;
+
+ MUTATOR_CALLHOOK(SetChangeParms);
}
/*
// whatever happens, allow 60 seconds of idling directly after connect for map loading
self.parm_idlesince = max(self.parm_idlesince, time - sv_maxidle + 60);
+
+ MUTATOR_CALLHOOK(DecodeLevelParms);
}
/*
self.nextthink = time;
- int s = self.realowner.cvar_cl_gunalign;
- if(s != 1 && s != 2 && s != 4)
- s = 3; // default value
- --s;
+ int s = W_GetGunAlignment(self.realowner);
vs = hook_shotorigin[s];
makevectors(self.realowner.v_angle);
makevectors(self.v_angle);
- int s = self.cvar_cl_gunalign;
- if(s != 1 && s != 2 && s != 4)
- s = 3; // default value
- --s;
+ int s = W_GetGunAlignment(self);
vs = hook_shotorigin[s];
// UGLY WORKAROUND: play this on CH_WEAPON_B so it can't cut off fire sounds
#include "../common/stats.qh"
#include "../common/teams.qh"
#include "../common/triggers/trigger/secret.qh"
+#include "../common/triggers/target/music.qh"
#include "../common/util.qh"
#include "../common/items/all.qh"
#include "../common/weapons/all.qh"
bprint(other.netname, " ^7wins.\n");
}
+ entity oldself = self;
+ target_music_kill();
+ self = oldself;
+
if(autocvar_g_campaign)
CampaignPreIntermission();
" ", ftos(tstart), " ", ftos(dt), "\n"));
}
-vector shotorg_adjustfromclient(vector vecs, float y_is_right, float allowcenter, float algn)
-{
- switch(algn)
- {
- default:
- case 3: // right
- break;
-
- case 4: // left
- vecs.y = -vecs.y;
- break;
-
- case 1:
- if(allowcenter) // 2: allow center handedness
- {
- // center
- vecs.y = 0;
- vecs.z -= 2;
- }
- else
- {
- // right
- }
- break;
-
- case 2:
- if(allowcenter) // 2: allow center handedness
- {
- // center
- vecs.y = 0;
- vecs.z -= 2;
- }
- else
- {
- // left
- vecs.y = -vecs.y;
- }
- break;
- }
- return vecs;
-}
-
-vector shotorg_adjust_values(vector vecs, float y_is_right, float visual, float algn)
-{
- string s;
- vector v;
-
- if (autocvar_g_shootfromeye)
- {
- if (visual)
- {
- if (autocvar_g_shootfromclient) { vecs = shotorg_adjustfromclient(vecs, y_is_right, (autocvar_g_shootfromclient >= 2), algn); }
- else { vecs.y = 0; vecs.z -= 2; }
- }
- else
- {
- vecs.y = 0;
- vecs.z = 0;
- }
- }
- else if (autocvar_g_shootfromcenter)
- {
- vecs.y = 0;
- vecs.z -= 2;
- }
- else if ((s = autocvar_g_shootfromfixedorigin) != "")
- {
- v = stov(s);
- if (y_is_right)
- v.y = -v.y;
- if (v.x != 0)
- vecs.x = v.x;
- vecs.y = v.y;
- vecs.z = v.z;
- }
- else if (autocvar_g_shootfromclient)
- {
- vecs = shotorg_adjustfromclient(vecs, y_is_right, (autocvar_g_shootfromclient >= 2), algn);
- }
- return vecs;
-}
-
-vector shotorg_adjust(vector vecs, float y_is_right, float visual)
-{SELFPARAM();
- return shotorg_adjust_values(vecs, y_is_right, visual, self.owner.cvar_cl_gunalign);
-}
-
-
void attach_sameorigin(entity e, entity to, string tag)
{
vector org, t_forward, t_left, t_up, e_forward, e_up;
void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float _atten);
float ExponentialFalloff(float mindist, float maxdist, float halflifedist, float d);
-vector shotorg_adjust(vector vecs, float y_is_right, float visual);
-
float DistributeEvenly_amount;
float DistributeEvenly_totalweight;
void objerror(string s);
void SetMovetypeFollow(entity ent, entity e);
-vector shotorg_adjust_values(vector vecs, float y_is_right, float visual, float algn);
-
void soundto(float dest, entity e, float chan, string samp, float vol, float atten);
void stopsound(entity e, float chan);
/**/
MUTATOR_HOOKABLE(BuffTouch, EV_BuffTouch);
+MUTATOR_HOOKABLE(SetNewParms, EV_NO_ARGS);
+
+MUTATOR_HOOKABLE(SetChangeParms, EV_NO_ARGS);
+
+MUTATOR_HOOKABLE(DecodeLevelParms, EV_NO_ARGS);
+
#define EV_GetRecords(i, o) \
/**/ i(int, record_page) \
/**/ i(string, ret_string) \
return true;
}
-
-MUTATOR_HOOKFUNCTION(sandbox, SetModname)
-{
- modname = "Sandbox";
- return true;
-}
#endif
if (item.spawnshieldtime)
{
- if ((player.(ammotype) < ammomax) || item.pickup_anyway)
+ if ((player.(ammotype) < ammomax) || item.pickup_anyway > 0)
{
player.(ammotype) = bound(player.(ammotype), ammomax, player.(ammotype) + item.(ammotype));
goto YEAH;
it = item.weapons;
it &= ~player.weapons;
- if (it || (item.spawnshieldtime && item.pickup_anyway))
+ if (it || (item.spawnshieldtime && item.pickup_anyway > 0))
{
pickedup = true;
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
// it's a level item
if(self.spawnflags & 1)
self.noalign = 1;
- if (self.noalign)
+ if (self.noalign > 0)
self.movetype = MOVETYPE_NONE;
else
self.movetype = MOVETYPE_TOSS;
// do item filtering according to game mode and other things
- if (!self.noalign)
+ if (self.noalign <= 0)
{
// first nudge it off the floor a little bit to avoid math errors
setorigin(self, self.origin + '0 0 1');
setsize (self, '-16 -16 0', '16 16 32');
self.SendFlags |= ISF_SIZE;
// note droptofloor returns false if stuck/or would fall too far
- droptofloor();
+ if(!self.noalign)
+ droptofloor();
waypoint_spawnforitem(self);
}
self.SendFlags |= ISF_SIZE;
- if(itemflags & FL_POWERUP)
- self.ItemStatus |= ITS_ANIMATE1;
+ if(!(self.spawnflags & 1024))
+ {
+ if(itemflags & FL_POWERUP)
+ self.ItemStatus |= ITS_ANIMATE1;
- if(self.armorvalue || self.health)
- self.ItemStatus |= ITS_ANIMATE2;
+ if(self.armorvalue || self.health)
+ self.ItemStatus |= ITS_ANIMATE2;
+ }
if(itemflags & FL_WEAPON)
{
else
self.gravity = 1;
- self.ItemStatus |= ITS_ANIMATE1;
+ if(!(self.spawnflags & 1024))
+ self.ItemStatus |= ITS_ANIMATE1;
self.ItemStatus |= ISF_COLORMAP;
}
#include "../../common/weapons/all.qh"
#include "../../lib/csqcmodel/sv_model.qh"
-/*
-===========================================================================
+vector shotorg_adjustfromclient(vector vecs, float y_is_right, float algn)
+{
+ switch(algn)
+ {
+ default: case 3: break; // right alignment
+ case 4: vecs.y = -vecs.y; break; // left
+ case 1: case 2: vecs.y = 0; vecs.z -= 2; break; // center
+ }
+
+ return vecs;
+}
+
+vector shotorg_adjust_values(vector vecs, bool y_is_right, bool visual, int algn)
+{
+ string s;
- CLIENT WEAPONSYSTEM CODE
- Bring back W_Weaponframe
+ if(visual)
+ vecs = shotorg_adjustfromclient(vecs, y_is_right, algn);
+ else if(autocvar_g_shootfromeye)
+ vecs.y = vecs.z = 0;
+ else if(autocvar_g_shootfromcenter)
+ {
+ vecs.y = 0;
+ vecs.z -= 2;
+ }
+ else if((s = autocvar_g_shootfromfixedorigin) != "")
+ {
+ vector v = stov(s);
+ if(y_is_right) { v.y = -v.y; }
+ if(v.x != 0) { vecs.x = v.x; }
+ vecs.y = v.y;
+ vecs.z = v.z;
+ }
+ else // just do the same as top
+ vecs = shotorg_adjustfromclient(vecs, y_is_right, algn);
-===========================================================================
-*/
+ return vecs;
+}
+
+vector shotorg_adjust(vector vecs, bool y_is_right, bool visual, int algn)
+{
+ return shotorg_adjust_values(vecs, y_is_right, visual, algn);
+}
.int state;
{
vector v0;
v0 = self.movedir;
- self.movedir = shotorg_adjust(v0, false, false);
- self.view_ofs = shotorg_adjust(v0, false, true) - v0;
+ self.movedir = shotorg_adjust(v0, false, false, self.owner.cvar_cl_gunalign);
+ self.view_ofs = shotorg_adjust(v0, false, true, self.owner.cvar_cl_gunalign) - v0;
}
self.owner.stat_shotorg = compressShotOrigin(self.movedir);
self.movedir = decompressShotOrigin(self.owner.stat_shotorg); // make them match perfectly
const float WFRAME_IDLE = 2;
const float WFRAME_RELOAD = 3;
+vector shotorg_adjust(vector vecs, bool y_is_right, bool visual, int algn);
+
+vector shotorg_adjust_values(vector vecs, bool y_is_right, bool visual, int algn);
+
void CL_SpawnWeaponentity(entity e);
vector CL_Weapon_GetShotOrg(float wpn);