From: TimePath Date: Sat, 7 Nov 2015 11:29:36 +0000 (+1100) Subject: sound8 X-Git-Tag: xonotic-v0.8.2~1690 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=05d2ce7189cf77c3f5b997a972ea12370abd479e;p=xonotic%2Fxonotic-data.pk3dir.git sound8 --- diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index 80468a62b..8d8e8df19 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -164,34 +164,6 @@ const int SP_DMG = 10; const int SP_DMGTAKEN = 11; // game mode specific indices are not in common/, but in server/scores_rules.qc! -const int CH_INFO = 0; -const int CH_TRIGGER = -3; -const int CH_WEAPON_A = -1; -const int CH_WEAPON_SINGLE = 1; -const int CH_VOICE = -2; -const int CH_BGM_SINGLE = 8; -const int CH_AMBIENT = -9; -const int CH_TRIGGER_SINGLE = 3; -const int CH_SHOTS = -4; -const int CH_SHOTS_SINGLE = 4; -const int CH_WEAPON_B = -1; -const int CH_PAIN = -6; -const int CH_PAIN_SINGLE = 6; -const int CH_PLAYER = -7; -const int CH_PLAYER_SINGLE = 7; -const int CH_TUBA_SINGLE = 5; - -const float ATTEN_NONE = 0; -const float ATTEN_MIN = 0.015625; -const float ATTEN_NORM = 0.5; -const float ATTEN_LARGE = 1; -const float ATTEN_IDLE = 2; -const float ATTEN_STATIC = 3; -const float ATTEN_MAX = 3.984375; - -const float VOL_BASE = 0.7; -const float VOL_BASEVOICE = 1.0; - // WEAPONTODO: move this into separate/new projectile handling code // this sets sounds and other properties of the projectiles in csqc const int PROJECTILE_ELECTRO = 1; const int PROJECTILE_ROCKET = 2; diff --git a/qcsrc/common/items/inventory.qh b/qcsrc/common/items/inventory.qh index 4ea378994..f748dda88 100644 --- a/qcsrc/common/items/inventory.qh +++ b/qcsrc/common/items/inventory.qh @@ -48,7 +48,7 @@ bool Inventory_Send(entity this, entity to, int sf) { WriteHeader(MSG_ENTITY, ENT_CLIENT_INVENTORY); entity e = self.owner; - if (/*IS_SPEC(e)*/ (e.classname == "spectator")) e = e.enemy; + if (IS_SPEC(e)) e = e.enemy; Inventory data = e.inventory; Inventory_Write(data); return true; diff --git a/qcsrc/common/mutators/mutator/superspec/superspec.qc b/qcsrc/common/mutators/mutator/superspec/superspec.qc index 416df75b4..887b18423 100644 --- a/qcsrc/common/mutators/mutator/superspec/superspec.qc +++ b/qcsrc/common/mutators/mutator/superspec/superspec.qc @@ -102,7 +102,7 @@ MUTATOR_HOOKFUNCTION(superspec, ItemTouch) entity _item = self; entity e; - FOR_EACH_SPEC(e) + FOR_EACH_CLIENT(e) if (IS_SPEC(e) || IS_OBSERVER(e)) { setself(e); if(self.superspec_flags & SSF_ITEMMSG) diff --git a/qcsrc/common/sounds/all.qc b/qcsrc/common/sounds/all.qc new file mode 100644 index 000000000..92c5ef059 --- /dev/null +++ b/qcsrc/common/sounds/all.qc @@ -0,0 +1,144 @@ +#ifdef SVQC + +bool autocvar_bot_sound_monopoly; + +.entity realowner; +bool sound_allowed(int to, entity e) +{ + for ( ; ; ) + { + if (e.classname == "body") e = e.enemy; + else if (e.realowner && e.realowner != e) e = e.realowner; + else if (e.owner && e.owner != e) e = e.owner; + else break; + } + // sounds to self may always pass + if (to == MSG_ONE && e == msg_entity) return true; + // sounds by players can be removed + if (autocvar_bot_sound_monopoly && IS_REAL_CLIENT(e)) return false; + // anything else may pass + return true; +} + +/** hack: string precache_sound(string s) = #19; */ +int precache_sound_index(string s) = #19; + +const int SVC_SOUND = 6; +const int SVC_STOPSOUND = 16; + +const int SND_VOLUME = BIT(0); +const int SND_ATTENUATION = BIT(1); +const int SND_LARGEENTITY = BIT(3); +const int SND_LARGESOUND = BIT(4); + +void soundtoat(int to, entity e, vector o, int chan, string samp, float vol, float attenu) +{ + if (!sound_allowed(to, e)) return; + int entno = etof(e); + int idx = precache_sound_index(samp); + attenu = floor(attenu * 64); + vol = floor(vol * 255); + int sflags = 0; + if (vol != 255) sflags |= SND_VOLUME; + if (attenu != 64) sflags |= SND_ATTENUATION; + if (entno >= 8192 || chan < 0 || chan > 7) sflags |= SND_LARGEENTITY; + if (idx >= 256) sflags |= SND_LARGESOUND; + WriteByte(to, SVC_SOUND); + WriteByte(to, sflags); + if (sflags & SND_VOLUME) WriteByte(to, vol); + if (sflags & SND_ATTENUATION) WriteByte(to, attenu); + if (sflags & SND_LARGEENTITY) + { + WriteShort(to, entno); + WriteByte(to, chan); + } + else + { + WriteShort(to, (entno << 3) | chan); + } + if (sflags & SND_LARGESOUND) WriteShort(to, idx); + else WriteByte(to, idx); + WriteCoord(to, o.x); + WriteCoord(to, o.y); + WriteCoord(to, o.z); +} + +void soundto(int _dest, entity e, int chan, string samp, float vol, float _atten) +{ + if (!sound_allowed(_dest, e)) return; + vector o = e.origin + 0.5 * (e.mins + e.maxs); + soundtoat(_dest, e, o, chan, samp, vol, _atten); +} +void soundat(entity e, vector o, int chan, string samp, float vol, float _atten) +{ + soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, _atten); +} +void stopsoundto(int _dest, entity e, int chan) +{ + if (!sound_allowed(_dest, e)) return; + int entno = num_for_edict(e); + if (entno >= 8192 || chan < 0 || chan > 7) + { + int idx = precache_sound_index(SND(Null)); + int sflags = SND_LARGEENTITY; + if (idx >= 256) sflags |= SND_LARGESOUND; + WriteByte(_dest, SVC_SOUND); + WriteByte(_dest, sflags); + WriteShort(_dest, entno); + WriteByte(_dest, chan); + if (sflags & SND_LARGESOUND) WriteShort(_dest, idx); + else WriteByte(_dest, idx); + WriteCoord(_dest, e.origin.x); + WriteCoord(_dest, e.origin.y); + WriteCoord(_dest, e.origin.z); + } + else + { + WriteByte(_dest, SVC_STOPSOUND); + WriteShort(_dest, entno * 8 + chan); + } +} +void stopsound(entity e, int chan) +{ + if (!sound_allowed(MSG_BROADCAST, e)) return; + stopsoundto(MSG_BROADCAST, e, chan); // unreliable, gets there fast + stopsoundto(MSG_ALL, e, chan); // in case of packet loss +} + +void play2(entity e, string filename) +{ + msg_entity = e; + soundtoat(MSG_ONE, world, '0 0 0', CH_INFO, filename, VOL_BASE, ATTEN_NONE); +} + +.float spamtime; +/** use this one if you might be causing spam (e.g. from touch functions that might get called more than once per frame) */ +float spamsound(entity e, int chan, string samp, float vol, float _atten) +{ + if (!sound_allowed(MSG_BROADCAST, e)) return false; + if (time > e.spamtime) + { + e.spamtime = time; + _sound(e, chan, samp, vol, _atten); + return true; + } + return false; +} + +void play2team(float t, string filename) +{ + if (autocvar_bot_sound_monopoly) return; + entity head; + FOR_EACH_REALPLAYER(head) + { + if (head.team == t) play2(head, filename); + } +} + +void play2all(string samp) +{ + if (autocvar_bot_sound_monopoly) return; + _sound(world, CH_INFO, samp, VOL_BASE, ATTEN_NONE); +} + +#endif diff --git a/qcsrc/common/sounds/all.qh b/qcsrc/common/sounds/all.qh index 4ad0e9b10..e81206cd1 100644 --- a/qcsrc/common/sounds/all.qh +++ b/qcsrc/common/sounds/all.qh @@ -22,5 +22,5 @@ PRECACHE(Sounds) { SOUND(Null, "misc/null"); #include "all.inc" - +#include "all.qc" #endif diff --git a/qcsrc/common/sounds/sound.qh b/qcsrc/common/sounds/sound.qh index dfc80e390..36bdaa833 100644 --- a/qcsrc/common/sounds/sound.qh +++ b/qcsrc/common/sounds/sound.qh @@ -1,6 +1,34 @@ #ifndef SOUND_H #define SOUND_H +const int CH_INFO = 0; +const int CH_TRIGGER = -3; +const int CH_WEAPON_A = -1; +const int CH_WEAPON_SINGLE = 1; +const int CH_VOICE = -2; +const int CH_BGM_SINGLE = 8; +const int CH_AMBIENT = -9; +const int CH_TRIGGER_SINGLE = 3; +const int CH_SHOTS = -4; +const int CH_SHOTS_SINGLE = 4; +const int CH_WEAPON_B = -1; +const int CH_PAIN = -6; +const int CH_PAIN_SINGLE = 6; +const int CH_PLAYER = -7; +const int CH_PLAYER_SINGLE = 7; +const int CH_TUBA_SINGLE = 5; + +const float ATTEN_NONE = 0; +const float ATTEN_MIN = 0.015625; +const float ATTEN_NORM = 0.5; +const float ATTEN_LARGE = 1; +const float ATTEN_IDLE = 2; +const float ATTEN_STATIC = 3; +const float ATTEN_MAX = 3.984375; + +const float VOL_BASE = 0.7; +const float VOL_BASEVOICE = 1.0; + // Play all sounds via sound7, for access to the extra channels. // Otherwise, channels 8 to 15 would be blocked for a weird QW feature. #ifdef SVQC @@ -17,6 +45,33 @@ #endif #define sound(e, c, s, v, a) _sound(e, c, Sound_fixpath(s), v, a) +/** + * because sound7 didn't have origin + * + * @param e sound owner + * @param o sound origin + * @param chan sound channel + * @param samp sound filename + * @param vol sound volume + * @param atten sound attenuation + * @param speed + * @param sf + */ +#define sound8(e, o, chan, samp, vol, atten, speed, sf) \ + do \ + { \ + entity __e = e; \ + vector old_origin = __e.origin; \ + vector old_mins = __e.mins; \ + vector old_maxs = __e.maxs; \ + setorigin(__e, o); \ + setsize(__e, '0 0 0', '0 0 0'); \ + sound7(__e, chan, samp, vol, atten, speed, sf); \ + setorigin(__e, old_origin); \ + setsize(__e, old_mins, old_maxs); \ + } \ + while (0) + CLASS(Sound, Object) ATTRIB(Sound, m_id, int, 0) ATTRIB(Sound, sound_str, string(), func_null) @@ -28,24 +83,24 @@ CLASS(Sound, Object) #define Sound_fixpath(this) _Sound_fixpath((this).sound_str()) string _Sound_fixpath(string base) { - if (base == "") return string_null; - #define extensions(x) \ - x(wav) \ - x(ogg) \ - x(flac) \ - /**/ - string full, relative; - #define tryext(ext) { if (fexists(full = strcat("sound/", relative = strcat(base, "." #ext)))) break; } - do - { - extensions(tryext); + if (base == "") return string_null; + #define extensions(x) \ + x(wav) \ + x(ogg) \ + x(flac) \ + /**/ + string full, relative; + #define tryext(ext) { if (fexists(full = strcat("sound/", relative = strcat(base, "." #ext)))) break; } + do + { + extensions(tryext); #undef tryext #undef extensions - LOG_WARNINGF("Missing sound: \"%s\"\n", full); - return string_null; - } - while (0); - return relative; + LOG_WARNINGF("Missing sound: \"%s\"\n", full); + return string_null; + } + while (0); + return relative; } METHOD(Sound, sound_precache, void(entity this)) { diff --git a/qcsrc/server/_all.qh b/qcsrc/server/_all.qh index 3693726bb..cbda56873 100644 --- a/qcsrc/server/_all.qh +++ b/qcsrc/server/_all.qh @@ -1,6 +1,36 @@ #ifndef SERVER_ALL_H #define SERVER_ALL_H +int maxclients; + +const string STR_PLAYER = "player"; +const string STR_SPECTATOR = "spectator"; +const string STR_OBSERVER = "observer"; + +#define IS_PLAYER(v) ((v).classname == STR_PLAYER) +#define IS_SPEC(v) ((v).classname == STR_SPECTATOR) +#define IS_OBSERVER(v) ((v).classname == STR_OBSERVER) + +#define IS_CLIENT(v) (v.flags & FL_CLIENT) +#define IS_BOT_CLIENT(v) (clienttype(v) == CLIENTTYPE_BOT) +#define IS_REAL_CLIENT(v) (clienttype(v) == CLIENTTYPE_REAL) +#define IS_NOT_A_CLIENT(v) (clienttype(v) == CLIENTTYPE_NOTACLIENT) + +#define IS_MONSTER(v) (v.flags & FL_MONSTER) +#define IS_VEHICLE(v) (v.vehicle_flags & VHF_ISVEHICLE) +#define IS_TURRET(v) (v.turret_flags & TUR_FLAG_ISTURRET) + +#define FOR_EACH_CLIENTSLOT(v) for (v = world; (v = nextent(v)) && (num_for_edict(v) <= maxclients); ) +#define FOR_EACH_CLIENT(v) FOR_EACH_CLIENTSLOT(v) if (IS_CLIENT(v)) +#define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if (IS_REAL_CLIENT(v)) + +#define FOR_EACH_PLAYER(v) FOR_EACH_CLIENT(v) if (IS_PLAYER(v)) +#define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if (IS_SPEC(v)) +#define FOR_EACH_OBSERVER(v) FOR_EACH_CLIENT(v) if (IS_OBSERVER(v)) +#define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if (IS_PLAYER(v)) + +#define FOR_EACH_MONSTER(v) for (v = world; (v = findflags(v, flags, FL_MONSTER)) != world; ) + #include "../common/effects/all.qh" #include "../common/models/all.qh" #include "../common/sounds/all.qh" diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index 2910eb9bb..6cd7e2395 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -55,7 +55,6 @@ bool autocvar_bot_navigation_ignoreplayers; bool autocvar_bot_nofire; #define autocvar_bot_number cvar("bot_number") #define autocvar_bot_prefix cvar_string("bot_prefix") -bool autocvar_bot_sound_monopoly; #define autocvar_bot_suffix cvar_string("bot_suffix") bool autocvar_bot_usemodelnames; int autocvar_bot_vs_human; diff --git a/qcsrc/server/constants.qh b/qcsrc/server/constants.qh index 95b13f1c7..c1ea1c6c6 100644 --- a/qcsrc/server/constants.qh +++ b/qcsrc/server/constants.qh @@ -9,8 +9,6 @@ const int FL_NO_WEAPON_STAY = BIT(17); const int FL_SPAWNING = BIT(18); const int FL_PICKUPITEMS = BIT(19); -const int SVC_SOUND = 6; -const int SVC_STOPSOUND = 16; const int SVC_SETVIEW = 5; const int RESPAWN_FORCE = 1; diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index 64157162c..094eb4531 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -54,8 +54,6 @@ void UpdateFrags(entity player, float f); float team1_score, team2_score, team3_score, team4_score; -float maxclients; - // flag set on worldspawn so that the code knows if it is dedicated or not float server_is_dedicated; diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 2b00fbffa..d12a90377 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -703,183 +703,6 @@ void readplayerstartcvars() warmup_start_ammo_fuel = max(0, warmup_start_ammo_fuel); } -float sound_allowed(float destin, entity e) -{ - // sounds from world may always pass - for (;;) - { - if (e.classname == "body") - e = e.enemy; - else if (e.realowner && e.realowner != e) - e = e.realowner; - else if (e.owner && e.owner != e) - e = e.owner; - else - break; - } - // sounds to self may always pass - if (destin == MSG_ONE) - if (e == msg_entity) - return true; - // sounds by players can be removed - if (autocvar_bot_sound_monopoly) - if (IS_REAL_CLIENT(e)) - return false; - // anything else may pass - return true; -} - -void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float attenu) -{ - float entno, idx; - - if (!sound_allowed(_dest, e)) - return; - - entno = num_for_edict(e); - idx = precache_sound_index(samp); - - int sflags; - sflags = 0; - - attenu = floor(attenu * 64); - vol = floor(vol * 255); - - if (vol != 255) - sflags |= SND_VOLUME; - if (attenu != 64) - sflags |= SND_ATTENUATION; - if (entno >= 8192 || chan < 0 || chan > 7) - sflags |= SND_LARGEENTITY; - if (idx >= 256) - sflags |= SND_LARGESOUND; - - WriteByte(_dest, SVC_SOUND); - WriteByte(_dest, sflags); - if (sflags & SND_VOLUME) - WriteByte(_dest, vol); - if (sflags & SND_ATTENUATION) - WriteByte(_dest, attenu); - if (sflags & SND_LARGEENTITY) - { - WriteShort(_dest, entno); - WriteByte(_dest, chan); - } - else - { - WriteShort(_dest, entno * 8 + chan); - } - if (sflags & SND_LARGESOUND) - WriteShort(_dest, idx); - else - WriteByte(_dest, idx); - - WriteCoord(_dest, o.x); - WriteCoord(_dest, o.y); - WriteCoord(_dest, o.z); -} -void soundto(float _dest, entity e, float chan, string samp, float vol, float _atten) -{ - vector o; - - if (!sound_allowed(_dest, e)) - return; - - o = e.origin + 0.5 * (e.mins + e.maxs); - soundtoat(_dest, e, o, chan, samp, vol, _atten); -} -void soundat(entity e, vector o, float chan, string samp, float vol, float _atten) -{ - soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, _atten); -} -void stopsoundto(float _dest, entity e, float chan) -{ - float entno; - - if (!sound_allowed(_dest, e)) - return; - - entno = num_for_edict(e); - - if (entno >= 8192 || chan < 0 || chan > 7) - { - float idx, sflags; - idx = precache_sound_index(SND(Null)); - sflags = SND_LARGEENTITY; - if (idx >= 256) - sflags |= SND_LARGESOUND; - WriteByte(_dest, SVC_SOUND); - WriteByte(_dest, sflags); - WriteShort(_dest, entno); - WriteByte(_dest, chan); - if (sflags & SND_LARGESOUND) - WriteShort(_dest, idx); - else - WriteByte(_dest, idx); - WriteCoord(_dest, e.origin.x); - WriteCoord(_dest, e.origin.y); - WriteCoord(_dest, e.origin.z); - } - else - { - WriteByte(_dest, SVC_STOPSOUND); - WriteShort(_dest, entno * 8 + chan); - } -} -void stopsound(entity e, float chan) -{ - if (!sound_allowed(MSG_BROADCAST, e)) - return; - - stopsoundto(MSG_BROADCAST, e, chan); // unreliable, gets there fast - stopsoundto(MSG_ALL, e, chan); // in case of packet loss -} - -void play2(entity e, string filename) -{ - //stuffcmd(e, strcat("play2 ", filename, "\n")); - msg_entity = e; - soundtoat(MSG_ONE, world, '0 0 0', CH_INFO, filename, VOL_BASE, ATTEN_NONE); -} - -// use this one if you might be causing spam (e.g. from touch functions that might get called more than once per frame) -.float spamtime; -float spamsound(entity e, float chan, string samp, float vol, float _atten) -{ - if (!sound_allowed(MSG_BROADCAST, e)) - return false; - - if (time > e.spamtime) - { - e.spamtime = time; - _sound(e, chan, samp, vol, _atten); - return true; - } - return false; -} - -void play2team(float t, string filename) -{ - entity head; - - if (autocvar_bot_sound_monopoly) - return; - - FOR_EACH_REALPLAYER(head) - { - if (head.team == t) - play2(head, filename); - } -} - -void play2all(string samp) -{ - if (autocvar_bot_sound_monopoly) - return; - - _sound(world, CH_INFO, samp, VOL_BASE, ATTEN_NONE); -} - void PrecachePlayerSounds(string f); void precache_playermodel(string m) { diff --git a/qcsrc/server/miscfunctions.qh b/qcsrc/server/miscfunctions.qh index ae0aa0e0a..4193ff29a 100644 --- a/qcsrc/server/miscfunctions.qh +++ b/qcsrc/server/miscfunctions.qh @@ -124,32 +124,6 @@ void WarpZone_traceline_antilag (entity source, vector v1, vector v2, float nomo #define PROJECTILE_TOUCH if(WarpZone_Projectile_Touch()) return -const string STR_PLAYER = "player"; -const string STR_SPECTATOR = "spectator"; -const string STR_OBSERVER = "observer"; - -#define IS_PLAYER(v) ((v).classname == STR_PLAYER) -#define IS_SPEC(v) ((v).classname == STR_SPECTATOR) -#define IS_OBSERVER(v) ((v).classname == STR_OBSERVER) -#define IS_CLIENT(v) (v.flags & FL_CLIENT) -#define IS_BOT_CLIENT(v) (clienttype(v) == CLIENTTYPE_BOT) -#define IS_REAL_CLIENT(v) (clienttype(v) == CLIENTTYPE_REAL) -#define IS_NOT_A_CLIENT(v) (clienttype(v) == CLIENTTYPE_NOTACLIENT) - -#define IS_MONSTER(v) (v.flags & FL_MONSTER) -#define IS_VEHICLE(v) (v.vehicle_flags & VHF_ISVEHICLE) -#define IS_TURRET(v) (v.turret_flags & TUR_FLAG_ISTURRET) - -#define FOR_EACH_CLIENTSLOT(v) for(v = world; (v = nextent(v)) && (num_for_edict(v) <= maxclients); ) -#define FOR_EACH_CLIENT(v) FOR_EACH_CLIENTSLOT(v) if(IS_CLIENT(v)) -#define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(IS_REAL_CLIENT(v)) - -#define FOR_EACH_PLAYER(v) FOR_EACH_CLIENT(v) if(IS_PLAYER(v)) -#define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if (!IS_PLAYER(v)) // Samual: shouldn't this be IS_SPEC(v)? and rather create a separate macro to include observers too -#define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if(IS_PLAYER(v)) - -#define FOR_EACH_MONSTER(v) for(v = world; (v = findflags(v, flags, FL_MONSTER)) != world; ) - #define CENTER_OR_VIEWOFS(ent) (ent.origin + (IS_PLAYER(ent) ? ent.view_ofs : ((ent.mins + ent.maxs) * 0.5))) // copies a string to a tempstring (so one can strunzone it) @@ -408,17 +382,6 @@ void readlevelcvars() //#NO AUTOCVARS END - -// Sound functions -//string precache_sound (string s) = #19; -// hack -float precache_sound_index (string s) = #19; - -const float SND_VOLUME = BIT(0); -const float SND_ATTENUATION = BIT(1); -const float SND_LARGEENTITY = BIT(3); -const float SND_LARGESOUND = BIT(4); - const float INITPRIO_FIRST = 0; const float INITPRIO_GAMETYPE = 0; const float INITPRIO_GAMETYPE_FALLBACK = 1;