bool autocvar_hud_panel_powerups_flip;
int autocvar_hud_panel_powerups_iconalign;
bool autocvar_hud_panel_powerups_progressbar;
-bool autocvar_hud_panel_buffs;
+bool autocvar_hud_panel_buffs = 1;
+ bool autocvar_hud_panel_buffs_progressbar;
+ string autocvar_hud_panel_buffs_progressbar_name = "progressbar";
//float autocvar_hud_panel_buffs_iconalign;
string autocvar_hud_panel_powerups_progressbar_shield;
string autocvar_hud_panel_powerups_progressbar_strength;
HUD_Write_PanelCvar_q("_fade_subsequent_minfontsize");
HUD_Write_PanelCvar_q("_fade_minfontsize");
break;
+ case HUD_PANEL_QUICKMENU:
+ HUD_Write_PanelCvar_q("_align");
+ break;
+ case HUD_PANEL_BUFFS:
+ HUD_Write_PanelCvar_q("_progressbar");
+ HUD_Write_PanelCvar_q("_progressbar_name");
}
HUD_Write("\n");
}
REGISTER_BUFF(_("Jump"),jump,JUMP,10,'0.7 0.2 1');
REGISTER_BUFF(_("Flight"),flight,FLIGHT,11,'1 0.2 0.5');
REGISTER_BUFF(_("Invisible"),invisible,INVISIBLE,12,'0.9 0.9 0.9');
+ REGISTER_BUFF(_("Inferno"),inferno,INFERNO,16,'2 0 0');
+ REGISTER_BUFF(_("Swapper"),swapper,SWAPPER,17,'0.59 0 0.95');
+ REGISTER_BUFF(_("Magnet"),magnet,MAGNET,18,'0.45 0.45 0.45');
+#ifdef MONTY
+REGISTER_BUFF(_("Blessed"),blessed,BLESSED,14,'0.9 0.3 0');
+#endif
#undef REGISTER_BUFF
#ifdef SVQC
BUFF_SPAWNFUNCS(jump, BUFF_JUMP)
BUFF_SPAWNFUNCS(flight, BUFF_FLIGHT)
BUFF_SPAWNFUNCS(invisible, BUFF_INVISIBLE)
+ BUFF_SPAWNFUNCS(inferno, BUFF_INFERNO)
+ BUFF_SPAWNFUNCS(swapper, BUFF_SWAPPER)
+ BUFF_SPAWNFUNCS(magnet, BUFF_MAGNET)
+#ifdef MONTY
+BUFF_SPAWNFUNCS(blessed, BUFF_BLESSED)
+#endif
BUFF_SPAWNFUNCS(random, 0)
BUFF_SPAWNFUNC_Q3TA_COMPAT(doubler, BUFF_MEDIC)
const int STAT_PLASMA = 84;
const int STAT_OK_AMMO_CHARGE = 85;
const int STAT_OK_AMMO_CHARGEPOOL = 86;
-const int STAT_BUFF_TIME = 87;
-// 88 empty?
-// 89 empty?
-// 90 empty?
-// 91 empty?
-// 92 empty?
-// 93 empty?
-// 94 empty?
-// 95 empty?
-// 96 empty?
-// 97 empty?
-// 98 empty?
-// 99 empty?
+const int STAT_WEAPONSINMAP = 87;
+const int STAT_WEAPONSINMAP2 = 88;
+const int STAT_WEAPONSINMAP3 = 89;
+const int STAT_SUPERCELLS = 90;
+const int STAT_CAPTURE_PROGRESS = 91;
+const int STAT_PRISONED = 92;
+const int STAT_ROUNDLOST = 93;
+const int STAT_CTF_FLAGSTATUS = 94;
+const int STAT_KH_KEYSTATUS = 95;
- // 96 empty?
++const int STAT_BUFF_TIME = 96;
+const int STAT_DISCO_MODE = 97;
+const int STAT_FROZEN = 98;
+const int STAT_REVIVE_PROGRESS = 99;
/* The following stats change depending on the gamemode, so can share the same ID */
float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death;
float autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health;
float autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath;
-bool autocvar_g_buffs_effects;
+float autocvar_g_conquest_spawn_close_to_death;
+float autocvar_g_conquest_capture_distance_default;
+float autocvar_g_conquest_capture_sps;
+float autocvar_g_conquest_controlpoint_health_default;
+float autocvar_g_conquest_spawn_choose;
+float autocvar_g_conquest_teleport_radius;
+float autocvar_g_conquest_teleport_wait;
+float autocvar_g_conquest_click_radius;
+float autocvar_g_conquest_teams;
+float autocvar_g_conquest_teams_override;
+float autocvar_g_conquest_warmup;
+float autocvar_g_conquest_round_timelimit;
+float autocvar_g_conquest_point_limit;
+float autocvar_g_walljump;
+float autocvar_g_walljump_delay;
+float autocvar_g_walljump_force;
+float autocvar_g_walljump_velocity_xy_factor;
+float autocvar_g_walljump_velocity_z_factor;
+float autocvar_g_infection_teams;
+float autocvar_g_infection_warmup;
+float autocvar_g_infection_round_timelimit;
+float autocvar_g_infection_point_limit;
+float autocvar_g_infection_point_leadlimit;
+float autocvar_g_jailbreak_warmup;
+float autocvar_g_jailbreak_round_timelimit;
+float autocvar_g_jailbreak_point_limit;
+float autocvar_g_jailbreak_point_leadlimit;
+float autocvar_g_jailbreak_controlpoint_unlock_damage_pushback;
+float autocvar_g_jailbreak_jail_deathmatch;
+float autocvar_g_jailbreak_score_jbreak_neutralmultiplier;
+float autocvar_g_jailbreak_score_jbreak_perplayer;
+float autocvar_g_jailbreak_score_jbreak;
+float autocvar_g_jailbreak_controlpoint_claim_noneutral;
+float autocvar_g_jailbreak_controlpoint_unlock_speed;
+float autocvar_g_jailbreak_controlpoint_idletime_global_own;
+float autocvar_g_jailbreak_controlpoint_idletime_global;
+float autocvar_g_jailbreak_controlpoint_claim_allneutral;
+float autocvar_g_jailbreak_penalty_death;
+float autocvar_g_jailbreak_score_imprison;
+float autocvar_g_jailbreak_score_defense;
+float autocvar_g_jailbreak_penalty_teamkill;
+float autocvar_g_jailbreak_controlpoint_claim;
+float autocvar_g_jailbreak_nonjb_openjails;
+float autocvar_g_jailbreak_prisoner_health;
+float autocvar_g_jailbreak_prisoner_armor;
+float autocvar_g_jailbreak_controlpoint_idletime_neutral_initial;
+float autocvar_g_jailbreak_controlpoint_idletime_initial;
+float autocvar_g_jailbreak_controlpoint_idletime_neutral;
+float autocvar_g_jailbreak_controlpoint_idletime_neutral_power;
+float autocvar_g_jailbreak_controlpoint_idletime_neutral_factor;
+float autocvar_g_jailbreak_controlpoint_idletime;
+float autocvar_g_jailbreak_controlpoint_idletime_power;
+float autocvar_g_jailbreak_controlpoint_idletime_factor;
+float autocvar_g_jailbreak_defense_range;
+float autocvar_g_jailbreak_debug;
+float autocvar_g_jailbreak_teams;
+float autocvar_g_jailbreak_teams_override;
+float autocvar_sv_headshot;
+var float autocvar_sv_headshot_damage = 1.5;
+float autocvar_g_piggyback_ride_enemies;
+var float autocvar_g_assault_round_limit = 1;
+var float autocvar_g_assault_repair_amount = 40;
+float autocvar_g_onslaught_debug;
+float autocvar_g_onslaught_teleport_wait;
+float autocvar_g_onslaught_spawn_at_controlpoints;
+var float autocvar_g_onslaught_spawn_at_controlpoints_chance = 0.5;
+float autocvar_g_onslaught_spawn_at_controlpoints_random;
+float autocvar_g_onslaught_spawn_at_generator;
+float autocvar_g_onslaught_spawn_at_generator_chance;
+float autocvar_g_onslaught_spawn_at_generator_random;
+float autocvar_g_onslaught_cp_proxydecap;
+var float autocvar_g_onslaught_cp_proxydecap_distance = 512;
+var float autocvar_g_onslaught_cp_proxydecap_dps = 100;
+float autocvar_g_onslaught_cp_buildhealth;
+float autocvar_g_onslaught_cp_buildtime;
+float autocvar_g_onslaught_cp_health;
+float autocvar_g_onslaught_cp_regen;
+float autocvar_g_onslaught_gen_health;
+var float autocvar_g_onslaught_shield_force = 100;
+float autocvar_g_onslaught_allow_vehicle_touch;
+float autocvar_g_onslaught_round_timelimit;
+float autocvar_g_onslaught_point_limit;
+float autocvar_g_onslaught_warmup;
+float autocvar_g_onslaught_teleport_radius;
+float autocvar_g_onslaught_spawn_choose;
+float autocvar_g_onslaught_click_radius;
+float autocvar_g_observer_glowtrails;
+float autocvar_g_riflearena_withlaser;
float autocvar_g_buffs_waypoint_distance;
++bool autocvar_g_buffs_effects;
float autocvar_g_buffs_randomize;
float autocvar_g_buffs_random_lifetime;
float autocvar_g_buffs_random_location;
float autocvar_g_buffs_invisible_alpha;
float autocvar_g_buffs_flight_gravity;
float autocvar_g_buffs_jump_height;
-
+ float autocvar_g_buffs_inferno_burntime_factor;
+ float autocvar_g_buffs_inferno_burntime_min_time;
+ float autocvar_g_buffs_inferno_burntime_target_damage;
+ float autocvar_g_buffs_inferno_burntime_target_time;
+ float autocvar_g_buffs_inferno_damagemultiplier;
+ float autocvar_g_buffs_swapper_range;
+ float autocvar_g_buffs_magnet_range_item;
+// TODO float autocvar_g_buffs_replace_flags;
+bool autocvar_g_physics_clientselect;
+string autocvar_g_physics_clientselect_options;
+string autocvar_sv_announcer;
+bool autocvar_sv_minigames;
+bool autocvar_sv_minigames_observer;
+float autocvar_g_itemeditor_spawn_distance;
+bool autocvar_g_itemeditor_storage_autosave;
+bool autocvar_g_itemeditor_storage_autoload;
+bool autocvar_g_itemeditor_readonly;
+int autocvar_g_itemeditor_max;
+int autocvar_g_itemeditor_debug;
+string autocvar_g_itemeditor_storage_name = "default";
+string autocvar_sv_weapons_modeloverride;
+string autocvar_sv_weapons_sounddir;
+string autocvar_sv_items_modeloverride;
#endif
// INPUT, OUTPUT:
float weapon_rate;
+MUTATOR_HOOKABLE(WantWeapon);
+ // returns which weapon the player/bot should choose
+ // INPUT, OUTPUT:
+ //float ret_float;
+ //entity other;
+
+ MUTATOR_HOOKABLE(WeaponSpeedFactor);
+ // allows changing weapon speed (projectiles mostly)
+ // INPUT, OUTPUT:
+ //float ret_float;
+
MUTATOR_HOOKABLE(SetStartItems);
// adjusts {warmup_}start_{items,weapons,ammo_{cells,plasma,rockets,nails,shells,fuel}}
buff_Init(ent);
}
+#ifdef MONTY
+void buff_Blessed_Foot_Touch()
+{
+ if(other.iscreature && other.takedamage && other.health > 0)
+ {
+ int mydamage = 9999;
+ if(other == self.realowner)
+ mydamage = 5; // but spammed
+ Damage (other, self, world, mydamage, DEATH_FOOT, other.origin, '0 0 0');
+ }
+}
+
+void buff_Blessed_Foot_Think()
+{
+ self.nextthink = time;
+ if(self.buff_blessed_time)
+ if(time >= self.buff_blessed_time)
+ {
+ remove(self);
+ return;
+ }
+ if(self.origin_z <= self.buff_blessed_bottom_z)
+ {
+ if(!self.buff_blessed_soundplayed)
+ {
+ self.buff_blessed_time = time + 1;
+ self.velocity = '0 0 0';
+ setorigin(self, self.buff_blessed_bottom);
+ //sound(self, CH_TRIGGER_SINGLE, "monty/foot.wav", VOL_BASE, ATTEN_MAX);
+ sound(self, CH_TRIGGER_SINGLE, "monty/foot.wav", VOL_BASEVOICE, ATTEN_MIN);
+ self.buff_blessed_soundplayed = true;
+ }
+ }
+ else
+ {
+ self.velocity = '0 0 -1500';
+ //setorigin(self, self.origin - '0 0 10');
+ }
+}
+
+void buff_Blessed_SpawnFoot(entity player)
+{
+ makevectors(player.angles);
+ vector org = player.origin + (v_forward * 220) + ('0 0 1' * 32);
+ vector bottom;
+ vector top;
+ entity foot = spawn();
+
+ foot.realowner = player; // don't set owner, as we want this to crush owner
+ foot.classname = "montyfoot";
+ foot.solid = SOLID_TRIGGER;
+ foot.touch = buff_Blessed_Foot_Touch;
+ foot.think = buff_Blessed_Foot_Think;
+ foot.nextthink = time;
+ foot.movetype = MOVETYPE_NOCLIP;
+ foot.scale = 6;
+
+ setmodel(foot, "models/monty/foot.iqm");
+ setsize(foot, '-150 -150 0', '150 150 250');
+
+ //tracebox(org, foot.mins, foot.maxs, org + '0 0 800', MOVE_NORMAL, foot);
+ top = org + '0 0 800';
+ foot.dphitcontentsmask = DPCONTENTS_SOLID;
+ tracebox(org, foot.mins, foot.maxs, org - '0 0 2000', MOVE_WORLDONLY, foot);
+ foot.dphitcontentsmask = DPCONTENTS_LAVA;
+ bottom = trace_endpos;
+
+ foot.buff_blessed_bottom = bottom;
+ foot.buff_blessed_top = top;
+ setorigin(foot, top);
+
+ sound(player, CH_TRIGGER_SINGLE, "monty/ni.wav", VOL_BASEVOICE, ATTEN_NORM);
+}
+#endif
+
+ void buff_Vengeance_DelayedDamage()
+ {
+ if(self.enemy)
+ Damage(self.enemy, self.owner, self.owner, self.dmg, DEATH_BUFF, self.enemy.origin, '0 0 0');
+
+ remove(self);
+ return;
+ }
+
+ float buff_Inferno_CalculateTime(float x, float offset_x, float offset_y, float intersect_x, float intersect_y, float base)
+ {
+ return offset_y + (intersect_y - offset_y) * logn(((x - offset_x) * ((base - 1) / intersect_x)) + 1, base);
+ }
+
// mutator hooks
MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_SplitHealthArmor)
{
if(!frag_target.vehicle)
if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC)
if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
- if(frag_target.deadflag == DEAD_NO)
- if(IS_PLAYER(frag_target) || (frag_target.flags & FL_MONSTER))
+ if(IS_PLAYER(frag_target) || IS_MONSTER(frag_target))
if(frag_attacker != frag_target)
- if(!frag_target.frozen)
if(frag_target.takedamage)
+ if(!Player_Trapped(frag_target))
if(DIFF_TEAM(frag_attacker, frag_target))
+ {
frag_attacker.health = bound(0, frag_attacker.health + bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal, frag_target.health), g_pickup_healthsmall_max);
+ if(frag_target.armorvalue)
+ frag_attacker.armorvalue = bound(0, frag_attacker.armorvalue + bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal, frag_target.armorvalue), g_pickup_armorsmall_max);
+ }
return false;
}
self.buff_disability_effect_time = time + 0.5;
}
- if(Player_Trapped(self))
+ // handle buff lost status
+ // 1: notify everyone else
+ // 2: notify carrier as well
+ int buff_lost = 0;
+
+ if(self.buff_time)
+ if(time >= self.buff_time)
+ buff_lost = 2;
+
- if(self.frozen) { buff_lost = 1; }
++ if(Player_Trapped(self)) { buff_lost = 1; }
+
+ if(buff_lost)
{
if(self.buffs)
{
}
}
+#ifdef MONTY
+ if(!self.crouch)
+ self.buff_blessed_crouch_held = false;
+
+ if(self.buffs & BUFF_BLESSED)
+ if(time >= self.buff_blessed_time)
+ if(self.crouch && !self.buff_blessed_crouch_held)
+ {
+ buff_Blessed_SpawnFoot(self);
+ self.buff_blessed_time = time + 0.5;
+ self.buff_blessed_crouch_held = true;
+ }
+#endif
+
+ if(self.buffs & BUFF_MAGNET)
+ {
+ vector pickup_size = '1 1 1' * autocvar_g_buffs_magnet_range_item;
+ for(other = world; (other = findflags(other, flags, FL_ITEM)); )
+ if(boxesoverlap(self.absmin - pickup_size, self.absmax + pickup_size, other.absmin, other.absmax))
+ {
+ entity oldself = self;
+ self = other;
+ other = oldself;
+ if(self.touch)
+ self.touch();
+ other = self;
+ self = oldself;
+ }
+ }
+
+ if(self.buffs & BUFF_AMMO)
+ if(self.clip_size)
+ self.clip_load = self.(weapon_load[self.switchweapon]) = self.clip_size;
+
if((self.buffs & BUFF_INVISIBLE) && (self.oldbuffs & BUFF_INVISIBLE))
if(self.alpha != autocvar_g_buffs_invisible_alpha)
- self.alpha = autocvar_g_buffs_invisible_alpha;
+ self.alpha = autocvar_g_buffs_invisible_alpha; // powerups reset alpha, so we must enforce this (TODO)
+
+ #define BUFF_ONADD(b) if((self.buffs & (b)) && !(self.oldbuffs & (b)))
+ #define BUFF_ONREM(b) if(!(self.buffs & (b)) && (self.oldbuffs & (b)))
if(self.buffs != self.oldbuffs)
{
void buffs_Initialize()
{
- precache_model("models/relics/relic.md3");
+ precache_model(BUFF_MODEL);
+ precache_model("models/monty/foot.iqm");
precache_sound("misc/strength_respawn.wav");
precache_sound("misc/shield_respawn.wav");
precache_sound("relics/relic_effect.wav");
- precache_sound("weapons/rocket_impact.wav");
+ precache_sound(W_Sound("rocket_impact"));
precache_sound("keepaway/respawn.wav");
+ precache_sound("monty/foot.wav");
+ precache_sound("monty/ni.wav");
addstat(STAT_BUFFS, AS_INT, buffs);
- addstat(STAT_MOVEVARS_JUMPVELOCITY, AS_FLOAT, stat_jumpheight);
+ addstat(STAT_BUFF_TIME, AS_FLOAT, buff_time);
InitializeEntity(world, buffs_DelayedInit, INITPRIO_FINDTARGET);
}
MUTATOR_HOOK(PlayerRegen, buffs_PlayerRegen, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDies, buffs_PlayerDies, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerUseKey, buffs_PlayerUseKey, CBC_ORDER_FIRST);
+ MUTATOR_HOOK(ForbidThrowCurrentWeapon, buffs_PlayerThrowKey, CBC_ORDER_ANY);
MUTATOR_HOOK(MakePlayerObserver, buffs_RemovePlayer, CBC_ORDER_ANY);
MUTATOR_HOOK(ClientDisconnect, buffs_RemovePlayer, CBC_ORDER_ANY);
- MUTATOR_HOOK(OnEntityPreSpawn, buffs_OnEntityPreSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(OnEntityPreSpawn, buffs_OnEntityPreSpawn, CBC_ORDER_LAST);
MUTATOR_HOOK(CustomizeWaypoint, buffs_CustomizeWaypoint, CBC_ORDER_ANY);
MUTATOR_HOOK(WeaponRateFactor, buffs_WeaponRate, CBC_ORDER_ANY);
+ MUTATOR_HOOK(WeaponSpeedFactor, buffs_WeaponSpeed, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPreThink, buffs_PlayerThink, CBC_ORDER_ANY);
MUTATOR_HOOK(GetCvars, buffs_GetCvars, CBC_ORDER_ANY);
MUTATOR_HOOK(BuildMutatorsString, buffs_BuildMutatorsString, CBC_ORDER_ANY);
.float buff_invisible_prev_alpha;
// flight
.float buff_flight_prev_gravity;
- // disability
- .float buff_disability_time;
- .float buff_disability_effect_time;
+#ifdef MONTY
+// blessed
+.float buff_blessed_time; // a little delay to prevent super spam
+.vector buff_blessed_bottom;
+.vector buff_blessed_top;
+.bool buff_blessed_soundplayed;
+.bool buff_blessed_crouch_held;
+#endif
+ // jump
+ .float stat_jumpheight;
+ // disability
+ .float buff_disability_time;
+ .float buff_disability_effect_time;
+ // common buff variables
+ .float buff_effect_delay;
// buff definitions
.float buff_active;