From: Martin Taibr Date: Fri, 25 Aug 2017 15:08:43 +0000 (+0200) Subject: Merge branch 'master' into martin-t/okc X-Git-Tag: xonotic-v0.8.5~2497^2~4 X-Git-Url: http://git.xonotic.org/?a=commitdiff_plain;h=f67b2effcc9360ae443fc7da413d37b84e060e19;hp=e57fd111a3279a4aa4789e2c72f9c819a56c7be9;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'master' into martin-t/okc --- diff --git a/defaultOverkill.cfg b/defaultOverkill.cfg index 634943c58..1dc68c70d 100644 --- a/defaultOverkill.cfg +++ b/defaultOverkill.cfg @@ -8,6 +8,13 @@ exec physicsOverkill.cfg // general gameplay set g_overkill 1 + +// hack - eventually, we should be able to choose overkill models in menu like for vanilla +set sv_defaultcharacter 1 +set sv_defaultplayermodel "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm" +set sv_defaultplayermodel_red "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm" +set sv_defaultplayermodel_blue "models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm" + set g_respawn_ghosts 0 set g_nades 1 diff --git a/defaultServer.cfg b/defaultServer.cfg index ed24832d1..596576a09 100644 --- a/defaultServer.cfg +++ b/defaultServer.cfg @@ -185,6 +185,9 @@ set g_weapon_throwable 1 "if set to 1, weapons can be dropped" set g_powerups -1 "if set to 0 the strength and shield (invincibility) will not spawn on the map, if 1 they will spawn in all game modes, -1 is game mode default" set g_use_ammunition 1 "if set to 0 all weapons have unlimited ammunition" set g_pickup_items -1 "if set to 0 all items (health, armor, ammo, weapons...) are removed from the map, if 1 they are forced to spawn" +set g_pickup_respawntime_scaling_reciprocal 0 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `reciprocal` (with `offset` and `linear` set to 0) can be used to achieve a constant number of items spawned *per player*" +set g_pickup_respawntime_scaling_offset 0 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `offset` offsets the curve left or right - the results are not intuitive and I recommend plotting the respawn time and the number of items per player to see what's happening" +set g_pickup_respawntime_scaling_linear 1 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `linear` can be used to simply scale the respawn time linearly" set g_weaponarena "0" "put in a list of weapons to enable a weapon arena mode, or try \"all\" or \"most\"" set g_weaponarena_random "0" "if set to a number, only that weapon count is given on every spawn (randomly)" set g_weaponarena_random_with_blaster "1" "additionally, always provide the blaster in random weapon arena games" diff --git a/mutators.cfg b/mutators.cfg index 9e8460da1..23c72435c 100644 --- a/mutators.cfg +++ b/mutators.cfg @@ -176,7 +176,7 @@ set g_random_gravity_negative 1000 "negative gravity multiplier" // ======= set g_nades 0 "enable off-hand grenades" set g_nades_spread 0.04 "random spread offset of throw direction" -set g_nades_throw_offset "0 0 0" "nade throwing offset" +set g_nades_throw_offset "0 -25 0" "nade throwing offset" set g_nades_spawn 1 "give nades right away when player spawns rather than delaying entire refire" set g_nades_client_select 0 "allow client side selection of nade type" set g_nades_pickup 0 "allow picking up thrown nades (not your own)" diff --git a/qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc b/qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc index fbb6bcb75..53042b8ef 100644 --- a/qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc +++ b/qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc @@ -158,13 +158,9 @@ CLASS(DamageText, Object) if (this.text) strunzone(this.text); this.text = strzone(s); - float size_range = autocvar_cl_damagetext_size_max - autocvar_cl_damagetext_size_min; - float damage_range = autocvar_cl_damagetext_size_max_damage - autocvar_cl_damagetext_size_min_damage; - float scale_factor = size_range / damage_range; - this.m_size = bound( - autocvar_cl_damagetext_size_min, - (potential - autocvar_cl_damagetext_size_min_damage) * scale_factor + autocvar_cl_damagetext_size_min, - autocvar_cl_damagetext_size_max); + this.m_size = map_bound_ranges(potential, + autocvar_cl_damagetext_size_min_damage, autocvar_cl_damagetext_size_max_damage, + autocvar_cl_damagetext_size_min, autocvar_cl_damagetext_size_max); } CONSTRUCTOR(DamageText, int _group, vector _origin, bool _screen_coords, int _health, int _armor, int _potential_damage, int _deathtype, bool _friendlyfire) { diff --git a/qcsrc/common/mutators/mutator/dodging/sv_dodging.qc b/qcsrc/common/mutators/mutator/dodging/sv_dodging.qc index d62aa42c4..70aac4d9a 100644 --- a/qcsrc/common/mutators/mutator/dodging/sv_dodging.qc +++ b/qcsrc/common/mutators/mutator/dodging/sv_dodging.qc @@ -104,19 +104,20 @@ REGISTER_MUTATOR(dodging, true); .int pressedkeys; #endif -// returns 1 if the player is close to a wall +// returns true if the player is close to a wall bool check_close_to_wall(entity this, float threshold) { if (PHYS_DODGING_WALL == 0) { return false; } -#define X(OFFSET) \ - tracebox(this.origin, this.mins, this.maxs, this.origin + OFFSET, true, this); \ - if(trace_fraction < 1 && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY) && vdist(this.origin - trace_endpos, <, threshold)) \ +#define X(dir) \ + tracebox(this.origin, this.mins, this.maxs, this.origin + threshold * dir, true, this); \ + if (trace_fraction < 1 && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)) \ return true; - X(1000*v_right); - X(-1000*v_right); - X(1000*v_forward); - X(-1000*v_forward); + + X(v_right); + X(-v_right); + X(v_forward); + X(-v_forward); #undef X return false; diff --git a/qcsrc/common/mutators/mutator/nades/nades.qc b/qcsrc/common/mutators/mutator/nades/nades.qc index ae1bbff65..11926b36d 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qc +++ b/qcsrc/common/mutators/mutator/nades/nades.qc @@ -889,20 +889,18 @@ void toss_nade(entity e, bool set_owner, vector _velocity, float _time) delete(e.fake_nade); e.fake_nade = NULL; + Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER, CPID_NADES); + makevectors(e.v_angle); // NOTE: always throw from first weapon entity? W_SetupShot(e, _nade.weaponentity_fld, false, false, SND_Null, CH_WEAPON_A, 0); - Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER, CPID_NADES); - vector offset = (v_forward * autocvar_g_nades_throw_offset.x) - + (v_right * autocvar_g_nades_throw_offset.y) - + (v_up * autocvar_g_nades_throw_offset.z); - if(autocvar_g_nades_throw_offset == '0 0 0') - offset = '0 0 0'; + + (v_right * autocvar_g_nades_throw_offset.y) + + (v_up * autocvar_g_nades_throw_offset.z); - setorigin(_nade, w_shotorg + offset + (v_right * 25) * -1); + setorigin(_nade, w_shotorg + offset); //setmodel(_nade, MDL_PROJECTILE_NADE); //setattachment(_nade, NULL, ""); PROJECTILE_MAKETRIGGER(_nade); diff --git a/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc b/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc index f39c4fc0f..d2a7308de 100644 --- a/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc +++ b/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc @@ -303,19 +303,8 @@ MUTATOR_HOOKFUNCTION(ok, SetModname) return true; } -void ok_SetCvars() -{ - // hack to force overkill playermodels - cvar_settemp("sv_defaultcharacter", "1"); - cvar_settemp("sv_defaultplayermodel", "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm"); - cvar_settemp("sv_defaultplayermodel_red", "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm"); - cvar_settemp("sv_defaultplayermodel_blue", "models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm"); -} - void ok_Initialize() { - ok_SetCvars(); - precache_all_playermodels("models/ok_player/*.dpm"); WEP_RPC.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED; diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index f5b3b2c19..2c42e4728 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -631,12 +631,35 @@ void Item_ScheduleRespawnIn(entity e, float t) } } +AUTOCVAR(g_pickup_respawntime_scaling_reciprocal, float, 0.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `reciprocal` (with `offset` and `linear` set to 0) can be used to achieve a constant number of items spawned *per player*"); +AUTOCVAR(g_pickup_respawntime_scaling_offset, float, 0.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `offset` offsets the curve left or right - the results are not intuitive and I recommend plotting the respawn time and the number of items per player to see what's happening"); +AUTOCVAR(g_pickup_respawntime_scaling_linear, float, 1.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `linear` can be used to simply scale the respawn time linearly"); void Item_ScheduleRespawn(entity e) { if(e.respawntime > 0) { Item_Show(e, 0); - Item_ScheduleRespawnIn(e, ITEM_RESPAWNTIME(e)); + + CheckAllowedTeams(NULL); + GetTeamCounts(NULL); + int players = 0; + if (c1 != -1) players += c1; + if (c2 != -1) players += c2; + if (c3 != -1) players += c3; + if (c4 != -1) players += c4; + float adjusted_respawntime; + if (players >= 2) { + float a = autocvar_g_pickup_respawntime_scaling_reciprocal; + float b = autocvar_g_pickup_respawntime_scaling_offset; + float c = autocvar_g_pickup_respawntime_scaling_linear; + adjusted_respawntime = e.respawntime * (a / (players + b) + c); + } else { + adjusted_respawntime = e.respawntime; + } + //LOG_INFOF("item %s will respawn in %f\n", e.classname, adjusted_respawntime); + // range: adjusted_respawntime - respawntimejitter .. adjusted_respawntime + respawntimejitter + float actual_time = adjusted_respawntime + crandom() * e.respawntimejitter; + Item_ScheduleRespawnIn(e, actual_time); } else // if respawntime is -1, this item does not respawn Item_Show(e, -1); diff --git a/qcsrc/common/t_items.qh b/qcsrc/common/t_items.qh index e52604d99..b92aceb8d 100644 --- a/qcsrc/common/t_items.qh +++ b/qcsrc/common/t_items.qh @@ -67,8 +67,6 @@ bool have_pickup_item(entity this); const float ITEM_RESPAWN_TICKS = 10; -#define ITEM_RESPAWNTIME(i) ((i).respawntime + crandom() * (i).respawntimejitter) - // range: respawntime - respawntimejitter .. respawntime + respawntimejitter #define ITEM_RESPAWNTIME_INITIAL(i) (ITEM_RESPAWN_TICKS + random() * ((i).respawntime + (i).respawntimejitter - ITEM_RESPAWN_TICKS)) // range: 10 .. respawntime + respawntimejitter diff --git a/qcsrc/lib/math.qh b/qcsrc/lib/math.qh index 8ba31516d..f20b1c66e 100644 --- a/qcsrc/lib/math.qh +++ b/qcsrc/lib/math.qh @@ -322,3 +322,25 @@ vector solve_quadratic(float a, float b, float c) } return v; } + +/// Maps values between the src and dest range: src_min to dest_min, src_max to dest_max, values between them +/// to the curresponding values between and extrapolates for values outside the range. +/// +/// src_min and src_max must not be the same or division by zero accurs. +/// +/// dest_max can be smaller than dest_min if you want the resulting range to be inverted, all values can be negative. +ERASEABLE +float map_ranges(float value, float src_min, float src_max, float dest_min, float dest_max) { + float src_diff = src_max - src_min; + float dest_diff = dest_max - dest_min; + float ratio = (value - src_min) / src_diff; + return dest_min + dest_diff * ratio; +} + +/// Same as `map_ranges` except that values outside the source range are clamped to min or max. +ERASEABLE +float map_bound_ranges(float value, float src_min, float src_max, float dest_min, float dest_max) { + if (value <= src_min) return dest_min; + if (value >= src_max) return dest_max; + return map_ranges(value, src_min, src_max, dest_min, dest_max); +}