set g_mh_not_dm_maps 0 "when this is set, DM maps will NOT be listed in MH"
set g_mh_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any"
set g_mh_point_limit -1 "MH point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
-set g_mh_warmup 10 //10 "time players get to run around before the round starts"
-set g_mh_round_timelimit 120 //180 "round time limit in seconds"
+set g_mh_warmup 10 "time players get to run around before the round starts" //10
+set g_mh_round_timelimit 120 "round time limit in seconds" //180
set g_mh_how_many_rounds_before_shuffle 1 "how many rounds are played before teams are shuffled automatically"
set g_mh_enable_tagging_on_touch 1 "are runners killed when touching hunters?"
set g_mh_player_waypoints 1 "0: no waypoints, 1: waypoints on runners, 2: waypoints on everyone"
set g_mh_weaponarena " " "starting weapons - takes the same options as g_weaponarena"
-set g_mh_weapons_damage 0 "0: no damage, 1: only self-damage for runners, 2: only damage opposing team, 3: only allow hunters to damage runners, 4: self-damage and opposing team damage"
+set g_mh_weapons_damage 3 "0: no damage, 1: only self-damage for runners, 2: only damage opposing team, 3: only allow hunters to damage runners, 4: self-damage and opposing team damage"
set g_mh_weapons_force 1 "0: no force, 1: only self-force, 2: self-force and opposing team force"
set g_mh_limited_ammunition 0 "do players consume ammunition when firing"
set g_mh_hunterblind 1 "when this is set, hunters can't see anything until the round starts"
set g_mh_autotaunt_runner 1 "when this is set, runners play automatically a sound being noticed by everyone"
set g_mh_autotaunt_runner_time 35 "runner automatic taunt time, plays a sound automatically when time is over, and restarts taunt time"
-set g_mh_propmode 1 "when this is set, runners are spawned as props"
\ No newline at end of file
+set g_mh_propmode 1 "when this is set, runners are spawned as props"
+set g_mh_random_props_count 30 "props are spawned randomly around map"
+set g_mh_random_props_tries 20 "Try to place a prop this many times before giving up"
+set g_mh_random_props_droptofloor 0 "Drop the props instantly so they don't appear to fall from the sky"
+set g_mh_random_props_droptofloor_maxdepth -1 "Maximum depth for the trace in props (use negative value for the map size)"
\ No newline at end of file
.vector taggedplayervelocity;
.vector taggedplayerviewangles;
.float RunnerSoundTaunt_time;
+.entity mh_prop; // TODO: to be checked
+.bool modelchecked;
+.entity original;
+
+bool first_time_props_spawn;
void MH_FakeTimeLimit(entity e, float t)
{
#endif
}
+void prop_think(entity this)
+{
+ this.nextthink = time + 0.15; // don't need to update often, very unlikely for these to move
+ CSQCMODEL_AUTOUPDATE(this);
+}
+
+void PropSetup(entity ent)
+{
+ setmodel(ent, MDL_RUNNER_PROP_RANDOM());
+ setsize(ent, '-16 -16 -16', '16 16 16'); //ent.mins, ent.maxs);
+ setthink(ent, prop_think);
+ ent.nextthink = time + 0.25;
+ CSQCMODEL_AUTOINIT(ent);
+
+ if(!ent.bot_attack)
+ IL_PUSH(g_bot_targets, ent);
+ ent.bot_attack = true;
+
+ //ent.pickup_anyway = true;
+ ent.scale = 1.4;
+ ent.angles_y = floor(random() * 180);
+ //ent.takedamage = DAMAGE_AIM;
+ //SetResourceExplicit(ent, RES_HEALTH, 100);
+
+ ent.solid = SOLID_BBOX;
+ ent.mass = 5;
+ ent.bouncefactor = 0.2;
+ ent.bouncestop = 0.3;
+ ent.friction = 1;
+ set_movetype(ent, MOVETYPE_STEP); //test with MOVETYPE_TOSS or MOVETYPE_WALK (it's like sliding object) or MOVETYPE_BOUNCE (maybe not good)
+ //setorigin(ent, org);
+ ent.velocity = randomvec() * 150 + '0 0 325';
+ ent.reset = SUB_Remove;
+
+ ent.mh_prop.model = ent.model; // assigns prop model if this is the case when runners shot it
+}
+
+void prop_droptofloor(entity e)
+{
+ float max_depth = ((autocvar_g_mh_random_props_droptofloor_maxdepth < 0) ? max_shot_distance : autocvar_g_mh_random_props_droptofloor_maxdepth);
+ tracebox(e.origin, e.mins, e.maxs, e.origin - ('0 0 1' * max_depth), MOVE_NORMAL, e);
+ setorigin(e, trace_endpos);
+}
+
+void SpawnProps(int pcount)
+{
+ pcount = autocvar_g_mh_random_props_count;
+ for(int j = 0; j < pcount; ++j)
+ {
+ entity e = spawn();
+ if(MoveToRandomMapLocation(e, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, autocvar_g_mh_random_props_tries, 1024, 256))
+ {
+ if(autocvar_g_mh_random_props_droptofloor)
+ droptofloor(e);
+ else
+ prop_droptofloor(e);
+
+ e.angles = '0 0 0';
+ e.gravity = 1;
+ e.spawnfunc_checked = true;
+ PropSetup(e);
+ }
+ else
+ delete(e); // removes entity
+ }
+}
+
MUTATOR_HOOKFUNCTION(mh, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
{
M_ARGV(1, string) = "mh_team";
}
// Prop feature
-.entity mh_prop; // TODO: to be checked
-.bool modelchecked;
+
MUTATOR_HOOKFUNCTION(mh, FixPlayermodel)
{
entity player = M_ARGV(2, entity);
{
//string defaultmodel = M_ARGV(0, string);
// TODO: to be checked
- if (!player.mh_prop.modelchecked)
+ if (!IS_DEAD(player) && !player.mh_prop.modelchecked) // to brake the loop
{
- //PrintToChatAll("PROPMODEL CHECKED");
+ player.original.model = player.model;
+ player.original.skin = player.skin;
+
player.mh_prop.model = MDL_RUNNER_PROP_RANDOM().model_str();
+
+ player.mh_prop.solid = SOLID_BBOX;
+ setsize(player, '-16 -16 -16', '16 16 16');
+
M_ARGV(0, string) = player.mh_prop.model;
M_ARGV(1, int) = player.mh_prop.skin;
- player.playermodel = M_ARGV(0,string);
+
//setmodel(player, MDL_RUNNER_PROP_RANDOM());
+ player.playermodel = M_ARGV(0, string);
+
player.mh_prop.modelchecked = true;
}
{
entity player = M_ARGV(0, entity);
- if(autocvar_g_mh_enable_tagging_on_touch && round_handler_IsRoundStarted() && player.team == Team_IndexToTeam(1) && !game_stopped && !IS_DEAD(player) && IS_PLAYER(player) && !IS_INDEPENDENT_PLAYER(player))
+ if(!autocvar_g_mh_propmode && autocvar_g_mh_enable_tagging_on_touch && round_handler_IsRoundStarted() && player.team == Team_IndexToTeam(1) && !game_stopped && !IS_DEAD(player) && IS_PLAYER(player) && !IS_INDEPENDENT_PLAYER(player))
{
FOREACH_CLIENT(IS_PLAYER(it) && it != player && it.team == Team_IndexToTeam(2), {
if(!IS_DEAD(it) && !IS_INDEPENDENT_PLAYER(it))
MOVE_NORMAL,
player,
ANTILAG_LATENCY(player)
- );*/
+ ); crosshair_trace(player);*/
// Autotaunt feature
if(autocvar_g_mh_autotaunt_runner)
{
entity player = M_ARGV(0, entity);
+ // if it's the first time that starts the gamemode for the props
+ if (autocvar_g_mh_propmode)
+ {
+ if (!first_time_props_spawn)
+ {
+ SpawnProps(autocvar_g_mh_random_props_count);
+ first_time_props_spawn = true;
+ }
+ }
+
if (!allowed_to_spawn_untagged && IS_PLAYER(player) && round_handler_IsRoundStarted()){ // this can be true even when player is trying to join
if (CS(player).jointime != time){ // not when connecting
MH_FakeTimeLimit(player, round_handler_GetEndTime() - CS(player).jointime); // set HUD with current round time
Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_MH_JOIN_LATE);
}
+
+ // if(player.mh_prop) // TOFIX: only spawns per one and not for all
+ //player.mh_prop = player;
+ /*if (player.team == Team_IndexToTeam(2))
+ player.mh_prop.modelchecked = false;*/
}
}
if (frag_target.waypointsprite_attachedforcarrier)
WaypointSprite_Kill(frag_target.waypointsprite_attachedforcarrier);
+
+ /*if (IS_DEAD(frag_target) && frag_target.playermodel == frag_target.mh_prop.model) // return player original model to avoid spamming errors
+ {
+ frag_target.skin = frag_target.original.skin;
+ frag_target.playermodel = frag_target.original.model;
+ }*/
mh_LastPlayerForTeam_Notify(frag_target);
if (!allowed_to_spawn_untagged)
entity player = M_ARGV(0, entity);
player.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP;
MH_count_players();
-
+
if(autocvar_g_mh_hunterblind)
{
if(player.team == Team_IndexToTeam(1))
if(autocvar_g_mh_propmode)
{
+ if(player.team == Team_IndexToTeam(1)) // Hunter needs weapons
+ {
+ //GiveWeapon(player, WEP_BLASTER.m_id, OP_PLUS, 1);
+ GiveWeapon(player, WEP_SHOTGUN.m_id, OP_PLUS, 1);
+ GiveWeapon(player, WEP_SHOCKWAVE.m_id, OP_PLUS, 1);
+ GiveWeapon(player, WEP_MACHINEGUN.m_id, OP_PLUS, 1);
+ GiveWeapon(player, WEP_MORTAR.m_id, OP_PLUS, 1);
+ }
+
if(player.team == Team_IndexToTeam(2) && !IS_DEAD(player))
{
//setmodel(player, MDL_RUNNER_PROP2);
//setplayermodel(player, MDL_RUNNER_PROP_RANDOM().model_str());//prop_setup(player);
//setmodel(player, MDL_RUNNER_PROP_RANDOM());
LOG_INFOF("Spawned prop");
-
- if(player.mh_prop) // TOFIX: only spawns per one and not for all
- player.mh_prop.modelchecked = false;
+ //player.mh_prop.model = MDL_RUNNER_PROP_RANDOM().model_str();
+ //player.playermodel = player.mh_prop.model;
+ player.mh_prop.modelchecked = false;
}
}
//reset kill streaks and respawn players on round reset
MUTATOR_HOOKFUNCTION(mh, reset_map_players)
{
+ if (autocvar_g_mh_propmode)
+ SpawnProps(autocvar_g_mh_random_props_count);
+
FOREACH_CLIENT(true, {
CS(it).killcount = 0;
MH_FakeTimeLimit(it, -1);
// to change
// ===========
-
-
//idk if this function is needed
MUTATOR_HOOKFUNCTION(mh, reset_map_global)
{