From: LegendaryGuard Date: Sun, 9 Jul 2023 21:41:50 +0000 (+0000) Subject: New features: Ammo and Darkness nades. Improve nades. Fix turrets target and when... X-Git-Url: https://git.xonotic.org/?a=commitdiff_plain;h=4260676b1d3e4e8b7236414efb4623a91ac418a1;hp=d7e0a1d59f86db1ee3018030badefe4508f84f33;p=xonotic%2Fxonotic-data.pk3dir.git New features: Ammo and Darkness nades. Improve nades. Fix turrets target and when Tesla turret owner's friend attacks against owner --- diff --git a/effectinfo.txt b/effectinfo.txt index 81b71a579..cf05552d7 100644 --- a/effectinfo.txt +++ b/effectinfo.txt @@ -2506,6 +2506,29 @@ effect poisonfield size 1 1 tex 0 8 velocityjitter 5 5 5 +effect darkfield + type smoke + airfriction 1 + alpha 256 256 50 + bounce 1.500000 + color 0x600089 0x000000 + count 10 + gravity -0.010000 + originjitter 333 333 0 + sizeincrease 10 + size 1 1 + tex 0 8 + velocityjitter 5 5 30 +effect darkfield + type smoke + alpha 256 256 50 + color 0x600089 0x000000 + count 5 + gravity -0.001000 + originjitter 333 333 0 + sizeincrease 10 + size 1 1 + tex 48 55 effect icefield type smoke airfriction 1 @@ -6825,6 +6848,93 @@ effect nade_neutral trailspacing 16 underwater velocityjitter 16 16 16 +effect nade_green + type smoke + alpha 100 100 250 + color 0x40ff9b 0x40ff9b + sizeincrease -1 + size 3 3 + tex 65 65 + trailspacing 1 +effect nade_green + type smoke + alpha 30 30 150 + color 0xff0000 0xffa2a2 + notunderwater + sizeincrease -10 + size 15 25 + tex 65 65 + trailspacing 8 +effect nade_green + type bubble + alpha 256 256 256 + bounce 1.500000 + color 0x40ff9b 0x40ff9b + gravity -0.125000 + liquidfriction 4 + size 1 1 + tex 62 62 + trailspacing 16 + underwater + velocityjitter 16 16 16 +effect nade_brown + type smoke + alpha 100 100 250 + color 0xa85400 0xa85400 + sizeincrease -1 + size 3 3 + tex 65 65 + trailspacing 1 +effect nade_brown + type smoke + alpha 30 30 150 + color 0xff0000 0xffa2a2 + notunderwater + sizeincrease -10 + size 15 25 + tex 65 65 + trailspacing 8 +effect nade_brown + type bubble + alpha 256 256 256 + bounce 1.500000 + color 0xa85400 0xa85400 + gravity -0.125000 + liquidfriction 4 + size 1 1 + tex 62 62 + trailspacing 16 + underwater + velocityjitter 16 16 16 +effect nade_purple + type smoke + alpha 100 100 250 + color 0x540054 0x540054 + sizeincrease -1 + size 3 3 + tex 65 65 + trailspacing 1 +effect nade_purple + type smoke + alpha 30 30 150 + color 0xff0000 0xffa2a2 + notunderwater + sizeincrease -10 + size 15 25 + tex 65 65 + trailspacing 8 +effect nade_purple + type bubble + alpha 256 256 256 + bounce 1.500000 + color 0x540054 0x540054 + gravity -0.125000 + liquidfriction 4 + size 1 1 + tex 62 62 + trailspacing 16 + underwater + velocityjitter 16 16 16 effect nade_red_burn type smoke alpha 100 100 250 @@ -7025,6 +7135,126 @@ effect nade_neutral_burn tex 71 73 trailspacing 16 velocityjitter 10 10 10 +effect nade_green_burn + type smoke + alpha 100 100 250 + color 0x40ff9b 0xff3c00 + sizeincrease -1 + size 5 5 + tex 65 65 + trailspacing 1 +effect nade_green_burn + type smoke + alpha 200 200 1000 + color 0xff0000 0xffa2a2 + notunderwater + sizeincrease -30 + size 45 25 + tex 65 65 + trailspacing 64 +effect nade_green_burn + type bubble + alpha 256 256 256 + bounce 1.500000 + color 0x40ff9b 0xff3c00 + gravity -0.125000 + liquidfriction 4 + size 1 1 + tex 62 62 + trailspacing 16 + underwater + velocityjitter 16 16 16 +effect nade_green_burn + type smoke + alpha 300 900 1500 + color 0x40ff9b 0xff3c00 + originjitter 2 2 2 + rotate -180 180 20 -20 + sizeincrease -40 + size 15 25 + tex 71 73 + trailspacing 16 + velocityjitter 10 10 10 +effect nade_brown_burn + type smoke + alpha 100 100 250 + color 0xa85400 0xff3c00 + sizeincrease -1 + size 5 5 + tex 65 65 + trailspacing 1 +effect nade_brown_burn + type smoke + alpha 200 200 1000 + color 0xff0000 0xffa2a2 + notunderwater + sizeincrease -30 + size 45 25 + tex 65 65 + trailspacing 64 +effect nade_brown_burn + type bubble + alpha 256 256 256 + bounce 1.500000 + color 0xa85400 0xff3c00 + gravity -0.125000 + liquidfriction 4 + size 1 1 + tex 62 62 + trailspacing 16 + underwater + velocityjitter 16 16 16 +effect nade_brown_burn + type smoke + alpha 300 900 1500 + color 0xa85400 0xff3c00 + originjitter 2 2 2 + rotate -180 180 20 -20 + sizeincrease -40 + size 15 25 + tex 71 73 + trailspacing 16 + velocityjitter 10 10 10 +effect nade_purple_burn + type smoke + alpha 100 100 250 + color 0x540054 0xff3c00 + sizeincrease -1 + size 5 5 + tex 65 65 + trailspacing 1 +effect nade_purple_burn + type smoke + alpha 200 200 1000 + color 0xff0000 0xffa2a2 + notunderwater + sizeincrease -30 + size 45 25 + tex 65 65 + trailspacing 64 +effect nade_purple_burn + type bubble + alpha 256 256 256 + bounce 1.500000 + color 0x540054 0xff3c00 + gravity -0.125000 + liquidfriction 4 + size 1 1 + tex 62 62 + trailspacing 16 + underwater + velocityjitter 16 16 16 +effect nade_purple_burn + type smoke + alpha 300 900 1500 + color 0x540054 0xff3c00 + originjitter 2 2 2 + rotate -180 180 20 -20 + sizeincrease -40 + size 15 25 + tex 71 73 + trailspacing 16 + velocityjitter 10 10 10 effect nade_blue_explode type decal alpha 256 256 0 @@ -7575,6 +7805,336 @@ effect nade_neutral_explode size 20 40 tex 71 73 velocityjitter 324 324 324 +effect nade_green_explode + type decal + alpha 256 256 0 + countabsolute 1 + lightcolor 100 20 20 + lightradiusfade 1500 + lightradius 300 + originjitter 26 26 26 + size 88 88 + tex 8 16 +effect nade_green_explode + type smoke + alpha 80 80 650 + color 0xff0000 0xffa2a2 + countabsolute 1 + sizeincrease 1800 + size 32 32 + tex 33 33 + velocitymultiplier 44 +effect nade_green_explode + type smoke + airfriction 30 + alpha 400 656 2000 + color 0x40ff9b 0xa647d3 + count 16 + notunderwater + originjitter 50 50 50 + rotate -180 180 -9 9 + sizeincrease 555 + size 20 24 + tex 48 55 + velocityjitter 320 320 320 +effect nade_green_explode + type spark + airfriction -9 + alpha 1500 3000 13000 + color 0x40ff9b 0xff4200 + count 8 + sizeincrease 40 + size 60 90 + stretchfactor 80 + tex 48 55 + velocityjitter 30 30 30 +effect nade_green_explode + type smoke + airfriction 0.040000 + alpha 128 328 390 + blend alpha + color 0x222222 0x000000 + count 32 + gravity 0.400000 + originjitter 50 50 10 + rotate -180 180 2 -2 + sizeincrease 50 + size 60 30 + tex 0 7 + velocityjitter 200 200 200 + velocityoffset 0 0 180 +effect nade_green_explode + type bubble + alpha 128 256 64 + bounce 1.500000 + color 0x404040 0x808080 + count 32 + gravity -0.125000 + liquidfriction 0.250000 + originjitter 16 16 16 + size 3 6 + tex 62 62 + underwater + velocityjitter 196 196 196 +effect nade_green_explode + type spark + airfriction 1 + alpha 644 956 484 + bounce 1.600000 + color 0xff0000 0xffa2a2 + count 8 + gravity 1 + liquidfriction 0.800000 + notunderwater + originjitter 16 16 16 + size 1 2 + tex 40 40 + velocityjitter 424 424 624 + velocityoffset 0 0 80 +effect nade_green_explode + type spark + airfriction 0.700000 + alpha 644 956 684 + color 0xff0000 0xffa2a2 + count 16 + gravity 0.500000 + liquidfriction 0.800000 + originjitter 16 16 16 + size 1 2 + tex 40 40 + velocityjitter 424 424 624 + velocityoffset 0 0 80 +effect nade_green_explode + type smoke + alpha 644 956 2500 + color 0xff0000 0xffa2a2 + count 8 + notunderwater + originjitter 64 64 64 + rotate -180 180 -100 100 + size 20 40 + tex 71 73 + velocityjitter 324 324 324 +effect nade_brown_explode + type decal + alpha 256 256 0 + countabsolute 1 + lightcolor 100 20 20 + lightradiusfade 1500 + lightradius 300 + originjitter 26 26 26 + size 88 88 + tex 8 16 +effect nade_brown_explode + type smoke + alpha 80 80 650 + color 0xff0000 0xffa2a2 + countabsolute 1 + sizeincrease 1800 + size 32 32 + tex 33 33 + velocitymultiplier 44 +effect nade_brown_explode + type smoke + airfriction 30 + alpha 400 656 2000 + color 0xa85400 0xa647d3 + count 16 + notunderwater + originjitter 50 50 50 + rotate -180 180 -9 9 + sizeincrease 555 + size 20 24 + tex 48 55 + velocityjitter 320 320 320 +effect nade_brown_explode + type spark + airfriction -9 + alpha 1500 3000 13000 + color 0xa85400 0xff4200 + count 8 + sizeincrease 40 + size 60 90 + stretchfactor 80 + tex 48 55 + velocityjitter 30 30 30 +effect nade_brown_explode + type smoke + airfriction 0.040000 + alpha 128 328 390 + blend alpha + color 0x222222 0x000000 + count 32 + gravity 0.400000 + originjitter 50 50 10 + rotate -180 180 2 -2 + sizeincrease 50 + size 60 30 + tex 0 7 + velocityjitter 200 200 200 + velocityoffset 0 0 180 +effect nade_brown_explode + type bubble + alpha 128 256 64 + bounce 1.500000 + color 0x404040 0x808080 + count 32 + gravity -0.125000 + liquidfriction 0.250000 + originjitter 16 16 16 + size 3 6 + tex 62 62 + underwater + velocityjitter 196 196 196 +effect nade_brown_explode + type spark + airfriction 1 + alpha 644 956 484 + bounce 1.600000 + color 0xff0000 0xffa2a2 + count 8 + gravity 1 + liquidfriction 0.800000 + notunderwater + originjitter 16 16 16 + size 1 2 + tex 40 40 + velocityjitter 424 424 624 + velocityoffset 0 0 80 +effect nade_brown_explode + type spark + airfriction 0.700000 + alpha 644 956 684 + color 0xff0000 0xffa2a2 + count 16 + gravity 0.500000 + liquidfriction 0.800000 + originjitter 16 16 16 + size 1 2 + tex 40 40 + velocityjitter 424 424 624 + velocityoffset 0 0 80 +effect nade_brown_explode + type smoke + alpha 644 956 2500 + color 0xff0000 0xffa2a2 + count 8 + notunderwater + originjitter 64 64 64 + rotate -180 180 -100 100 + size 20 40 + tex 71 73 + velocityjitter 324 324 324 +effect nade_purple_explode + type decal + alpha 256 256 0 + countabsolute 1 + lightcolor 100 20 20 + lightradiusfade 1500 + lightradius 300 + originjitter 26 26 26 + size 88 88 + tex 8 16 +effect nade_purple_explode + type smoke + alpha 80 80 650 + color 0xff0000 0xffa2a2 + countabsolute 1 + sizeincrease 1800 + size 32 32 + tex 33 33 + velocitymultiplier 44 +effect nade_purple_explode + type smoke + airfriction 30 + alpha 400 656 2000 + color 0x540054 0xa647d3 + count 16 + notunderwater + originjitter 50 50 50 + rotate -180 180 -9 9 + sizeincrease 555 + size 20 24 + tex 48 55 + velocityjitter 320 320 320 +effect nade_purple_explode + type spark + airfriction -9 + alpha 1500 3000 13000 + color 0x540054 0xff4200 + count 8 + sizeincrease 40 + size 60 90 + stretchfactor 80 + tex 48 55 + velocityjitter 30 30 30 +effect nade_purple_explode + type smoke + airfriction 0.040000 + alpha 128 328 390 + blend alpha + color 0x222222 0x000000 + count 32 + gravity 0.400000 + originjitter 50 50 10 + rotate -180 180 2 -2 + sizeincrease 50 + size 60 30 + tex 0 7 + velocityjitter 200 200 200 + velocityoffset 0 0 180 +effect nade_purple_explode + type bubble + alpha 128 256 64 + bounce 1.500000 + color 0x404040 0x808080 + count 32 + gravity -0.125000 + liquidfriction 0.250000 + originjitter 16 16 16 + size 3 6 + tex 62 62 + underwater + velocityjitter 196 196 196 +effect nade_purple_explode + type spark + airfriction 1 + alpha 644 956 484 + bounce 1.600000 + color 0xff0000 0xffa2a2 + count 8 + gravity 1 + liquidfriction 0.800000 + notunderwater + originjitter 16 16 16 + size 1 2 + tex 40 40 + velocityjitter 424 424 624 + velocityoffset 0 0 80 +effect nade_purple_explode + type spark + airfriction 0.700000 + alpha 644 956 684 + color 0xff0000 0xffa2a2 + count 16 + gravity 0.500000 + liquidfriction 0.800000 + originjitter 16 16 16 + size 1 2 + tex 40 40 + velocityjitter 424 424 624 + velocityoffset 0 0 80 +effect nade_purple_explode + type smoke + alpha 644 956 2500 + color 0xff0000 0xffa2a2 + count 8 + notunderwater + originjitter 64 64 64 + rotate -180 180 -100 100 + size 20 40 + tex 71 73 + velocityjitter 324 324 324 effect shockwave_attack type spark airfriction 1 diff --git a/gfx/hud/default/nade_ammo.tga b/gfx/hud/default/nade_ammo.tga new file mode 100644 index 000000000..31cf048fd Binary files /dev/null and b/gfx/hud/default/nade_ammo.tga differ diff --git a/gfx/hud/default/nade_dark.tga b/gfx/hud/default/nade_dark.tga new file mode 100644 index 000000000..112ddcb86 Binary files /dev/null and b/gfx/hud/default/nade_dark.tga differ diff --git a/gfx/hud/luma/nade_ammo.tga b/gfx/hud/luma/nade_ammo.tga new file mode 100644 index 000000000..3f0a8f0f6 Binary files /dev/null and b/gfx/hud/luma/nade_ammo.tga differ diff --git a/gfx/hud/luma/nade_dark.tga b/gfx/hud/luma/nade_dark.tga new file mode 100644 index 000000000..fb33b341b Binary files /dev/null and b/gfx/hud/luma/nade_dark.tga differ diff --git a/mutators.cfg b/mutators.cfg index 24dc379dd..c6ea8e9c8 100644 --- a/mutators.cfg +++ b/mutators.cfg @@ -189,7 +189,7 @@ set g_random_gravity_negative 1000 "negative gravity multiplier" set g_nades 0 "enable off-hand grenades - use the 'dropweapon' (second press throws) or '+hook' (release throws) binds" set g_nades_spread 0.04 "random spread offset of throw direction" 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_onspawn 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)" set g_nades_pickup_time 2 "time until picked up nade explodes" @@ -204,11 +204,11 @@ set g_nades_nade_edgedamage 90 set g_nades_nade_radius 300 set g_nades_nade_force 650 set g_nades_nade_newton_style 0 "nade velocity: 0 is absolute, 1 is relative (takes into account player velocity), 2 is something in between" -set g_nades_nade_type 1 "Type of the off-hand grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade 8:entrap 9:veil" +set g_nades_nade_type 1 "Type of the off-hand grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade 8:entrap 9:veil, 10:ammo, 11:darkness" seta cl_nade_timer 1 "show a visual timer for nades, 1 = only circle, 2 = circle with text" -seta cl_nade_type 3 -seta cl_pokenade_type "zombie" +seta cl_nade_type 3 "selected type of the off-hand grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade 8:entrap 9:veil 10:ammo 11:darkness" +seta cl_pokenade_type "zombie" "monster to spawn" // ------------ // Nade bonus @@ -222,7 +222,7 @@ seta cl_pokenade_type "zombie" // set g_nades_bonus 0 "Enable bonus grenades" set g_nades_bonus_client_select 0 "Allow client side selection of bonus nade type" -set g_nades_bonus_type 2 "Type of the bonus grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade 8:entrap 9:veil" +set g_nades_bonus_type 2 "Type of the bonus grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade 8:entrap 9:veil 10:ammo 11:darkness" set g_nades_bonus_onstrength 1 "Always give bonus grenades to players that have the strength powerup" set g_nades_bonus_max 3 "Maximum number of bonus grenades" set g_nades_bonus_only 0 "Disallow regular nades, only bonus nades can be used" @@ -238,52 +238,77 @@ set g_nades_bonus_score_time -1 "Bonus nade score given per second (negative t set g_nades_bonus_score_time_flagcarrier 2 "Bonus nade score given per second as flag carrier (negative to have the score decay)" // Napalm (2) +set g_nades_napalm 0 "Napalm nade: spreads fire balls around the fountain and burns for a while" set g_nades_napalm_blast 1 "Whether the napalm grenades also give damage with the usual grenade explosion" set g_nades_napalm_burntime 0.5 "Time that the fire from napalm will stick to the player" set g_nades_napalm_selfdamage 1 "Whether the player that tossed the nade can be harmed by its fire" // Napalm fireballs set g_nades_napalm_ball_count 6 "Number of fireballs emitted during the explosion" set g_nades_napalm_ball_spread 500 "Maximum force which the fireballs will have on explosion" -set g_nades_napalm_ball_damageforcescale 4 -set g_nades_napalm_ball_damage 40 -set g_nades_napalm_ball_lifetime 7 +set g_nades_napalm_ball_damageforcescale 4 "How affected fireballs are by damage" +set g_nades_napalm_ball_damage 40 "Damage caused by the fireball" +set g_nades_napalm_ball_lifetime 7 "How long the fireball will last" set g_nades_napalm_ball_radius 100 "Distance from the fireball within which you may get burned" // Napalm Fire fountain set g_nades_napalm_fountain_lifetime 3 "Time period during which extra fire mines are ejected" set g_nades_napalm_fountain_delay 0.5 "Delay between emissions by the fountain" set g_nades_napalm_fountain_damage 50 "Damage caused by the center of the fountain" set g_nades_napalm_fountain_edgedamage 20 "Damage caused by the edge of the fountain" -set g_nades_napalm_fountain_radius 130 +set g_nades_napalm_fountain_radius 130 "Distance from the fountain" // Ice (3) +set g_nades_ice 1 "Ice nade: freezes and reduces health" set g_nades_ice_freeze_time 3 "How long the ice field will last" set g_nades_ice_health 0 "How much health the player will have after being unfrozen" set g_nades_ice_explode 0 "Whether the ice nade should explode again once the ice field dissipated" -set g_nades_ice_teamcheck 0 "Don't freeze teammates" +set g_nades_ice_teamcheck 2 "0: friendly fire, 1: nade owner isn't affected, 2: don't freeze teammates" + +// Translocate (4) +set g_nades_translocate 1 "Translocate nade: teleports into explosion nade location" +set g_nades_translocate_destroy_damage 25 "Damage caused when translocate nade is destroyed by some attacker" // Spawn (5) +set g_nades_spawn 1 "Spawn nade: respawns into nade explosion location after being fragged" set g_nades_spawn_count 3 "Number of times player will spawn at their spawn nade explosion location" +set g_nades_spawn_health_respawn 0 "How much health the player will have when being respawned, if 0, normal health respawn" +set g_nades_spawn_destroy_damage 25 "Damage caused when spawn nade is destroyed by some attacker" // Heal (6) +set g_nades_heal 1 "Heal nade: spawns a orb to recover health inside, enemies take the reverse effect when being inside orb" set g_nades_heal_time 5 "How long the healing field will last" set g_nades_heal_rate 30 "Health given per second" set g_nades_heal_friend 1 "Multiplier of health given to team mates" set g_nades_heal_foe -2 "Multiplier of health given to enemies" // Pokenade (7) +set g_nades_pokenade 0 "Pokenade: spawns a monster into the explosion nade location" set g_nades_pokenade_monster_lifetime 150 "How long pokenade monster will survive" set g_nades_pokenade_monster_type "zombie" "Monster to spawn" // Entrap (8) +set g_nades_entrap 0 "Entrap nade: spawns a orb to slow down movements inside" set g_nades_entrap_strength 0.01 "Strength of the orb's movement slowing powers" set g_nades_entrap_speed 0.5 "Running speed while entrapped" set g_nades_entrap_time 10 "Life time of the orb" -set g_nades_entrap_radius 500 +set g_nades_entrap_radius 500 "Distance from the entrap orb" // Veil (9) +set g_nades_veil 0 "Veil nade: spawns a orb to turn invisible inside" set g_nades_veil_time 8 "Life time of the orb" -set g_nades_veil_radius 200 - +set g_nades_veil_radius 200 "Distance from the veil orb" + +// Ammo (10) +set g_nades_ammo 0 "Ammo nade: spawns a orb to recover ammo inside, enemies take the reverse effect when being inside orb" +set g_nades_ammo_time 4 "Life time of the orb" +set g_nades_ammo_rate 30 "Ammo given per second" +set g_nades_ammo_friend 1 "Multiplier of ammo given to team mates" +set g_nades_ammo_foe -2 "Multiplier of ammo given to enemies" + +// Darkness (11) +set g_nades_dark 0 "Darkness nade: blinds enemies" +set g_nades_dark_time 4 "How long the dark field will last" +set g_nades_dark_explode 0 "Whether the darkness nade should explode again once the dark field dissipated" +set g_nades_dark_teamcheck 2 "0: friendly fire, 1: nade owner isn't affected, 2: don't blind teammates" // ============ // camp check diff --git a/qcsrc/common/effects/all.inc b/qcsrc/common/effects/all.inc index d7654f06a..1bd7ad9ed 100644 --- a/qcsrc/common/effects/all.inc +++ b/qcsrc/common/effects/all.inc @@ -161,6 +161,9 @@ EFFECT(0, SPAWN_BLUE, "spawn_event_blue") EFFECT(0, SPAWN_YELLOW, "spawn_event_yellow") EFFECT(0, SPAWN_PINK, "spawn_event_pink") EFFECT(0, SPAWN_NEUTRAL, "spawn_event_neutral") +EFFECT(0, SPAWN_GREEN, "spawn_event_green") +EFFECT(0, SPAWN_BROWN, "spawn_event_brown") +EFFECT(0, SPAWN_PURPLE, "spawn_event_purple") entity EFFECT_SPAWN(int teamid) { switch (teamid) { @@ -172,6 +175,7 @@ entity EFFECT_SPAWN(int teamid) } } +EFFECT(0, DARKFIELD, "darkfield") EFFECT(0, ICEORGLASS, "iceorglass") EFFECT(0, ICEFIELD, "icefield") EFFECT(0, FIREFIELD, "firefield") diff --git a/qcsrc/common/effects/effectinfo.inc b/qcsrc/common/effects/effectinfo.inc index e6909e4cd..7e8a06365 100644 --- a/qcsrc/common/effects/effectinfo.inc +++ b/qcsrc/common/effects/effectinfo.inc @@ -4026,6 +4026,43 @@ SUB(poisonfield) { MY(velocityjitter) = '5.0 5.0 5.0'; } +// cover small area in dark fog, spawn it once per second +DEF(darkfield); +SUB(darkfield) { + MY(airfriction) = 1; + MY(alpha_min) = 256; + MY(alpha_max) = 256; + MY(alpha_fade) = 50; + MY(bounce) = 1.500000; + MY(color_min) = "0x600089"; + MY(color_max) = "0x000000"; + MY(count) = 10; + MY(gravity) = -0.010000; + MY(originjitter) = '333.0 333.0 0.0'; + MY(sizeincrease) = 10; + MY(size_min) = 1; + MY(size_max) = 1; + MY(tex_max) = 8; + MY(type) = "smoke"; + MY(velocityjitter) = '5.0 5.0 30.0'; +} +SUB(darkfield) { + MY(alpha_min) = 256; + MY(alpha_max) = 256; + MY(alpha_fade) = 50; + MY(color_min) = "0x600089"; + MY(color_max) = "0x000000"; + MY(count) = 5; + MY(gravity) = -0.001000; + MY(originjitter) = '333.0 333.0 0.0'; + MY(sizeincrease) = 10; + MY(size_min) = 1; + MY(size_max) = 1; + MY(tex_min) = 48; + MY(tex_max) = 55; + MY(type) = "smoke"; +} + // cover small area in icy mist, spawn it once per second DEF(icefield); SUB(icefield) { diff --git a/qcsrc/common/effects/effectinfo_nades.inc b/qcsrc/common/effects/effectinfo_nades.inc index 9c655579a..b8af3fbf2 100644 --- a/qcsrc/common/effects/effectinfo_nades.inc +++ b/qcsrc/common/effects/effectinfo_nades.inc @@ -54,6 +54,9 @@ nade(red, "0xff0000", "0xff3c00", "0xff0000", "0xffa2a2") nade(yellow, "0xFFFF0F", "0xFFFF0F", "0xFFFF0F", "0xFFFF0F") nade(pink, "0xFF0FFF", "0xFF0FFF", "0xFF0FFF", "0xFF0FFF") nade(neutral, "0xFFFFFF", "0xFFFFFF", "0xFFFFFF", "0xFFFFFF") +nade(green, "0x40ff9b", "0x40ff9b", "0x40ff9b", "0xffa2a2") +nade(brown, "0xa85400", "0xa85400", "0xa85400", "0xffa2a2") +nade(purple, "0x540054", "0x540054", "0x540054", "0xffa2a2") #undef nade #define nade_burn(name, colormin1, colormax1, colormin2, colormax2) \ @@ -132,6 +135,9 @@ nade_burn(blue, "0x006cff", "0x0600ff", "0x0600ff", "0x9794ff") nade_burn(yellow, "0xFFFF0F", "0xFFFF0F", "0xFFFF0F", "0xFFFF0F") nade_burn(pink, "0xFF0FFF", "0xFF0FFF", "0xFF0FFF", "0xFF0FFF") nade_burn(neutral, "0xFFFFFF", "0xFFFFFF", "0xFFFFFF", "0xFFFFFF") +nade_burn(green, "0x40ff9b", "0x40ff9b", "0x40ff9b", "0xffa2a2") +nade_burn(brown, "0xa85400", "0xa85400", "0xa85400", "0xffa2a2") +nade_burn(purple, "0x540054", "0x540054", "0x540054", "0xffa2a2") #undef nade_burn #define nade_explode(name, colorlight, colormin1, colormax1, colormin2, colormax2, colormin3, colormax3) \ @@ -313,4 +319,7 @@ nade_explode(red, '100.0 20.0 20.0', "0xff0000", "0xffa2a2", "0xff0000", " nade_explode(yellow, '100.0 20.0 20.0', "0xff0000", "0xffa2a2", "0xFFFF0F", "0xFFFF0F", "0xff0000", "0xffa2a2") nade_explode(pink, '100.0 20.0 20.0', "0xff0000", "0xffa2a2", "0xFF0FFF", "0xFF0FFF", "0xff0000", "0xffa2a2") nade_explode(neutral, '100.0 20.0 20.0', "0xff0000", "0xffa2a2", "0xFFFFFF", "0xFFFFFF", "0xff0000", "0xffa2a2") +nade_explode(green, '100.0 20.0 20.0', "0x40ff9b", "0xffa2a2", "0x40ff9b", "0x40ff9b", "0xff0000", "0xffa2a2") +nade_explode(brown, '100.0 20.0 20.0', "0xa85400", "0xffa2a2", "0xa85400", "0xa85400", "0xff0000", "0xffa2a2") +nade_explode(purple, '100.0 20.0 20.0', "0x540054", "0xffa2a2", "0x540054", "0x540054", "0xff0000", "0xffa2a2") #undef nade_explode diff --git a/qcsrc/common/mutators/mutator/nades/effects.inc b/qcsrc/common/mutators/mutator/nades/effects.inc index 83cf74247..343acf991 100644 --- a/qcsrc/common/mutators/mutator/nades/effects.inc +++ b/qcsrc/common/mutators/mutator/nades/effects.inc @@ -5,6 +5,10 @@ EFFECT(0, NADE_EXPLODE_BLUE, "nade_blue_explode") EFFECT(0, NADE_EXPLODE_YELLOW, "nade_yellow_explode") EFFECT(0, NADE_EXPLODE_PINK, "nade_pink_explode") EFFECT(0, NADE_EXPLODE_NEUTRAL, "nade_neutral_explode") +EFFECT(0, NADE_EXPLODE_GREEN, "nade_green_explode") +EFFECT(0, NADE_EXPLODE_BROWN, "nade_brown_explode") +EFFECT(0, NADE_EXPLODE_PURPLE, "nade_purple_explode") + entity EFFECT_NADE_EXPLODE(int teamid) { switch (teamid) { @@ -21,6 +25,9 @@ EFFECT(1, NADE_TRAIL_BLUE, "nade_blue") EFFECT(1, NADE_TRAIL_YELLOW, "nade_yellow") EFFECT(1, NADE_TRAIL_PINK, "nade_pink") EFFECT(1, NADE_TRAIL_NEUTRAL, "nade_neutral") +EFFECT(1, NADE_TRAIL_GREEN, "nade_green") +EFFECT(1, NADE_TRAIL_BROWN, "nade_brown") +EFFECT(1, NADE_TRAIL_PURPLE, "nade_purple") entity EFFECT_NADE_TRAIL(int teamid) { switch (teamid) { @@ -37,6 +44,9 @@ EFFECT(1, NADE_TRAIL_BURN_BLUE, "nade_blue_burn") EFFECT(1, NADE_TRAIL_BURN_YELLOW, "nade_yellow_burn") EFFECT(1, NADE_TRAIL_BURN_PINK, "nade_pink_burn") EFFECT(1, NADE_TRAIL_BURN_NEUTRAL, "nade_neutral_burn") +EFFECT(1, NADE_TRAIL_BURN_GREEN, "nade_green_burn") +EFFECT(1, NADE_TRAIL_BURN_BROWN, "nade_brown_burn") +EFFECT(1, NADE_TRAIL_BURN_PURPLE, "nade_purple_burn") entity EFFECT_NADE_TRAIL_BURN(int teamid) { switch (teamid) { diff --git a/qcsrc/common/mutators/mutator/nades/nades.inc b/qcsrc/common/mutators/mutator/nades/nades.inc index 3270e719f..c667b0043 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.inc +++ b/qcsrc/common/mutators/mutator/nades/nades.inc @@ -93,3 +93,23 @@ REGISTER_NADE(VEIL) { NADE_PROJECTILE(1, PROJECTILE_NADE_VEIL_BURN, EFFECT_NADE_TRAIL_BURN_NEUTRAL); #endif } + +REGISTER_NADE(AMMO) { + this.m_color = '0.66 0.33 0'; + this.m_name = _("Ammo grenade"); + this.m_icon = "nade_ammo"; +#ifdef GAMEQC + NADE_PROJECTILE(0, PROJECTILE_NADE_AMMO, EFFECT_NADE_TRAIL_BROWN); + NADE_PROJECTILE(1, PROJECTILE_NADE_AMMO_BURN, EFFECT_NADE_TRAIL_BURN_BROWN); +#endif +} + +REGISTER_NADE(DARK) { + this.m_color = '0.23 0 0.23'; + this.m_name = _("Dark grenade"); + this.m_icon = "nade_dark"; +#ifdef GAMEQC + NADE_PROJECTILE(0, PROJECTILE_NADE_DARK, EFFECT_NADE_TRAIL_PURPLE); + NADE_PROJECTILE(1, PROJECTILE_NADE_DARK_BURN, EFFECT_NADE_TRAIL_BURN_PURPLE); +#endif +} \ No newline at end of file diff --git a/qcsrc/common/mutators/mutator/nades/nades.qc b/qcsrc/common/mutators/mutator/nades/nades.qc index 1707e168b..8fa8a2779 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qc +++ b/qcsrc/common/mutators/mutator/nades/nades.qc @@ -39,8 +39,45 @@ entity Nade_TrailEffect(int proj, int nade_team) } #endif +REGISTER_NET_TEMP(TE_CSQC_DARKBLINKING); #ifdef CSQC +#include +#include + +float dark_appeartime; +float dark_fadetime; +bool darkblink; + +void HUD_DarkBlinking() +{ + vector bottomright = vec2(vid_conwidth, vid_conheight); + drawfill('0 0 0', bottomright, NADE_TYPE_DARK.m_color, 0.986, DRAWFLAG_NORMAL); +} + REGISTER_MUTATOR(cl_nades, true); +MUTATOR_HOOKFUNCTION(cl_nades, HUD_Draw_overlay) +{ + if (STAT(NADE_DARK_TIME) > time) + { + M_ARGV(0, vector) = NADE_TYPE_DARK.m_color; + HUD_DarkBlinking(); + return true; + } + return false; +} + +NET_HANDLE(TE_CSQC_DARKBLINKING, bool isNew) +{ + return = true; + + if(darkblink) return; + + localcmd("play2 sound/misc/blind\n"); + darkblink = true; + dark_appeartime = time; + dark_fadetime = STAT(NADE_DARK_TIME); +} + MUTATOR_HOOKFUNCTION(cl_nades, Ent_Projectile) { entity proj = M_ARGV(0, entity); @@ -151,6 +188,7 @@ void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expan #include #include #include +#include .float nade_time_primed; .float nade_lifetime; @@ -189,6 +227,14 @@ void nade_spawn(entity _nade) CSQCProjectile(_nade, true, REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, _nade)).m_projectile[false], true); } +void normal_nade_boom(entity this) +{ + RadiusDamage(this, this.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, + autocvar_g_nades_nade_radius, this, NULL, autocvar_g_nades_nade_force, this.projectiledeathtype, DMG_NOWEP, this.enemy); + Damage_DamageInfo(this.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, + autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, this.projectiledeathtype, 0, this); +} + void napalm_damage(entity this, float dist, float damage, float edgedamage, float burntime) { entity e; @@ -393,33 +439,30 @@ void nade_ice_think(entity this) Send_Effect(expef, this.origin + '0 0 1', '0 0 0', 1); sound(this, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM); - RadiusDamage(this, this.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, - autocvar_g_nades_nade_radius, this, NULL, autocvar_g_nades_nade_force, this.projectiledeathtype, DMG_NOWEP, this.enemy); - Damage_DamageInfo(this.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, - autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, this.projectiledeathtype, 0, this); + normal_nade_boom(this); } delete(this); return; } - this.nextthink = time+0.1; + this.nextthink = time + 0.1; // gaussian float randomr; randomr = random(); - randomr = exp(-5*randomr*randomr)*autocvar_g_nades_nade_radius; + randomr = exp(-5 * randomr * randomr) * autocvar_g_nades_nade_radius; float randomw; - randomw = random()*M_PI*2; + randomw = random() * M_PI * 2; vector randomp; - randomp.x = randomr*cos(randomw); - randomp.y = randomr*sin(randomw); + randomp.x = randomr * cos(randomw); + randomp.y = randomr * sin(randomw); randomp.z = 1; Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, this.origin + randomp, '0 0 0', 1); if(time >= this.nade_special_time) { - this.nade_special_time = time+0.7; + this.nade_special_time = time + 0.7; Send_Effect(EFFECT_ELECTRO_IMPACT, this.origin, '0 0 0', 1); Send_Effect(EFFECT_ICEFIELD, this.origin, '0 0 0', 1); @@ -428,13 +471,24 @@ void nade_ice_think(entity this) float current_freeze_time = this.ltime - time - 0.1; +#define ICE_NADE_RADIUS_TEAMCHECK(checked) \ + if (checked) \ + if (!it.revival_time || ((time - it.revival_time) >= 1.5)) \ + if (!STAT(FROZEN, it)) \ + nade_ice_freeze(this, it, current_freeze_time); \ + break; + FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_nades_nade_radius, it != this && it.takedamage && !IS_DEAD(it) && GetResource(it, RES_HEALTH) > 0 && current_freeze_time > 0, { - if(!autocvar_g_nades_ice_teamcheck || (DIFF_TEAM(it, this.realowner) || it == this.realowner)) - if(!it.revival_time || ((time - it.revival_time) >= 1.5)) - if(!STAT(FROZEN, it)) - nade_ice_freeze(this, it, current_freeze_time); + switch (autocvar_g_nades_ice_teamcheck) + { + // 1: nade owner isn't affected; 2: no teammate is affected; any other number than 1 and 2: friendly fire + case 1: ICE_NADE_RADIUS_TEAMCHECK(it != this.realowner); + case 2: ICE_NADE_RADIUS_TEAMCHECK(DIFF_TEAM(it, this.realowner) && it != this.realowner); + default: ICE_NADE_RADIUS_TEAMCHECK(!autocvar_g_nades_ice_teamcheck || (DIFF_TEAM(it, this.realowner) || it == this.realowner)); + } }); +#undef ICE_NADE_RADIUS_TEAMCHECK } void nade_ice_boom(entity this) @@ -453,7 +507,7 @@ void nade_ice_boom(entity this) fountain.projectiledeathtype = DEATH_NADE_ICE.m_id; fountain.bot_dodge = false; setsize(fountain, '-16 -16 -16', '16 16 16'); - fountain.nade_special_time = time+0.3; + fountain.nade_special_time = time + 0.3; fountain.angles = this.angles; if ( autocvar_g_nades_ice_explode ) @@ -479,6 +533,14 @@ void nade_translocate_boom(entity this) if(this.realowner.vehicle) return; + setsize(this, PL_MIN_CONST-'16 16 16', PL_MAX_CONST+'16 16 16'); + + if(!move_out_of_solid(this)) + { + sprint(this.realowner, "^1Couldn't move the translocator out of solid! origin: ", vtos(this.origin), "\n"); + return; + } + vector locout = this.origin + '0 0 1' * (1 - this.realowner.mins.z - 24); tracebox(locout, this.realowner.mins, this.realowner.maxs, locout, MOVE_NOMONSTERS, this.realowner); locout = trace_endpos; @@ -597,18 +659,15 @@ void nade_heal_touch(entity this, entity toucher) { float maxhealth; float health_factor; - if(IS_PLAYER(toucher) || IS_MONSTER(toucher)) + + if(IS_PLAYER(toucher) || IS_MONSTER(toucher) || IS_VEHICLE(toucher)) if(!IS_DEAD(toucher)) if(!STAT(FROZEN, toucher)) { health_factor = autocvar_g_nades_heal_rate*frametime/2; if ( toucher != this.realowner ) - { - if ( SAME_TEAM(toucher,this) ) - health_factor *= autocvar_g_nades_heal_friend; - else - health_factor *= autocvar_g_nades_heal_foe; - } + health_factor *= (SAME_TEAM(toucher,this)) ? autocvar_g_nades_heal_friend : autocvar_g_nades_heal_foe; + if ( health_factor > 0 ) { maxhealth = (IS_MONSTER(toucher)) ? toucher.max_health : g_pickup_healthmega_max; @@ -616,17 +675,13 @@ void nade_heal_touch(entity this, entity toucher) if (hp < maxhealth) { if (this.nade_show_particles) - { Send_Effect(EFFECT_HEALING, toucher.origin, '0 0 0', 1); - } + GiveResourceWithLimit(toucher, RES_HEALTH, health_factor, maxhealth); } } else if ( health_factor < 0 ) - { Damage(toucher,this,this.realowner,-health_factor,DEATH_NADE_HEAL.m_id,DMG_NOWEP,toucher.origin,'0 0 0'); - } - } } @@ -681,61 +736,227 @@ void nade_veil_boom(entity this) orb.colormod = NADE_TYPE_VEIL.m_color; } +void nade_ammo_touch(entity this, entity toucher) +{ + float maxammo = 999; + float ammo_factor; + float amshells = GetResource(toucher, RES_SHELLS); + float ambullets = GetResource(toucher, RES_BULLETS); + float amrockets = GetResource(toucher, RES_ROCKETS); + float amcells = GetResource(toucher, RES_CELLS); + float amplasma = GetResource(toucher, RES_PLASMA); + if(IS_PLAYER(toucher) || IS_MONSTER(toucher)) + if(!IS_DEAD(toucher)) + if(!STAT(FROZEN, toucher)) + { + ammo_factor = autocvar_g_nades_ammo_rate*frametime/2; + if ( toucher != this.realowner ) + ammo_factor *= (SAME_TEAM(toucher, this)) ? autocvar_g_nades_ammo_friend : autocvar_g_nades_ammo_foe; + +#define CHECK_AMMO_RESOURCE_LIMIT(amresource, res_resource) \ + if (amresource < maxammo) \ + GiveResourceWithLimit(toucher, res_resource, ammo_factor, maxammo); + +#define DROP_AMMO_RESOURCE(amresource, res_resource) \ + if (amresource > 0) \ + SetResource(toucher, res_resource, amresource + ammo_factor); + + if ( ammo_factor > 0 ) + { + CHECK_AMMO_RESOURCE_LIMIT(amshells, RES_SHELLS); + CHECK_AMMO_RESOURCE_LIMIT(ambullets, RES_BULLETS); + CHECK_AMMO_RESOURCE_LIMIT(amrockets, RES_ROCKETS); + CHECK_AMMO_RESOURCE_LIMIT(amcells, RES_CELLS); + CHECK_AMMO_RESOURCE_LIMIT(amplasma, RES_PLASMA); + + if (this.nade_show_particles) + Send_Effect(EFFECT_HEALING, toucher.origin, '0 0 0', 1); + } + else if ( ammo_factor < 0 ) + { + //Foe drops ammo points + DROP_AMMO_RESOURCE(amshells, RES_SHELLS); + DROP_AMMO_RESOURCE(ambullets, RES_BULLETS); + DROP_AMMO_RESOURCE(amrockets, RES_ROCKETS); + DROP_AMMO_RESOURCE(amcells, RES_CELLS); + DROP_AMMO_RESOURCE(amplasma, RES_PLASMA); + + return; + } + } +#undef CHECK_AMMO_RESOURCE_LIMIT +#undef DROP_AMMO_RESOURCE + + if ( IS_REAL_CLIENT(toucher) || (IS_VEHICLE(toucher) && toucher.owner) ) + { + entity show_tint = (IS_VEHICLE(toucher) && toucher.owner) ? toucher.owner : toucher; + show_tint.nade_ammo_time = time + 0.1; + } +} + +void nade_ammo_boom(entity this) +{ + entity orb = nades_spawn_orb(this.owner, this.realowner, this.origin, autocvar_g_nades_ammo_time, autocvar_g_nades_nade_radius); + + settouch(orb, nade_ammo_touch); + orb.colormod = '0.66 0.33 0'; +} + +void DarkBlinking(entity e) +{ + if(e == NULL) return; + + int accepted = VerifyClientEntity(e, true, false); + + if(accepted > 0) + { + msg_entity = e; + WriteHeader(MSG_ONE, TE_CSQC_DARKBLINKING); + } +} + +void nade_dark_think(entity this) +{ + if(round_handler_IsActive()) + if(!round_handler_IsRoundStarted()) + { + delete(this); + return; + } + + if(time >= this.ltime) + { + if ( autocvar_g_nades_dark_explode ) + { + entity expef = EFFECT_NADE_EXPLODE(this.realowner.team); + Send_Effect(expef, this.origin + '0 0 1', '0 0 0', 1); + sound(this, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM); + + normal_nade_boom(this); + } + else + Send_Effect(EFFECT_SPAWN_PURPLE, this.origin + '0 0 1', '0 0 0', 1); + + delete(this); + return; + } + + this.nextthink = time + 0.1; + + // gaussian + float randomr; + randomr = random(); + randomr = exp(-5 * randomr * randomr) * autocvar_g_nades_nade_radius; + float randomw; + randomw = random() * M_PI * 2; + vector randomp; + randomp.x = randomr * cos(randomw); + randomp.y = randomr * sin(randomw); + randomp.z = 1; + Send_Effect(EFFECT_DARKFIELD, this.origin + randomp, '0 0 0', 1); + + if(time >= this.nade_special_time) + { + this.nade_special_time = time + 0.7; + Send_Effect(EFFECT_DARKFIELD, this.origin, '0 0 0', 1); + } + + float current_dark_time = this.ltime - time - 0.1; + +#define DARK_NADE_RADIUS_TEAMCHECK(checked) \ + if (checked) \ + if ( IS_REAL_CLIENT(it) ) \ + { \ + STAT(NADE_DARK_TIME, it) = time + 0.1; \ + DarkBlinking(it); \ + } \ + break; + + FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_nades_nade_radius, it != this && it.takedamage && !IS_DEAD(it) && GetResource(it, RES_HEALTH) > 0 && current_dark_time > 0, + { + switch (autocvar_g_nades_dark_teamcheck) + { + // 1: nade owner isn't affected; 2: no teammate is affected; any other number than 1 and 2: friendly fire + case 1: DARK_NADE_RADIUS_TEAMCHECK(it != this.realowner); + case 2: DARK_NADE_RADIUS_TEAMCHECK(DIFF_TEAM(it, this.realowner) && it != this.realowner); + default: DARK_NADE_RADIUS_TEAMCHECK(!autocvar_g_nades_dark_teamcheck || (DIFF_TEAM(it, this.realowner) && it != this.realowner)); + } + }); +#undef DARK_NADE_RADIUS_TEAMCHECK +} + +void nade_dark_boom(entity this) +{ + entity fountain = new(nade_dark_fountain); + fountain.owner = this.owner; + fountain.realowner = this.realowner; + fountain.origin = this.origin; + setorigin(fountain, fountain.origin); + setthink(fountain, nade_dark_think); + fountain.nextthink = time; + fountain.ltime = time + autocvar_g_nades_dark_time; + fountain.pushltime = fountain.wait = fountain.ltime; + fountain.team = this.team; + set_movetype(fountain, MOVETYPE_TOSS); + fountain.projectiledeathtype = DEATH_NADE.m_id; + fountain.bot_dodge = false; + setsize(fountain, '-16 -16 -16', '16 16 16'); + fountain.nade_special_time = time + 0.3; + fountain.angles = this.angles; + + if ( autocvar_g_nades_dark_explode ) + { + setmodel(fountain, MDL_PROJECTILE_GRENADE); + entity timer = new(nade_timer); + setmodel(timer, MDL_NADE_TIMER); + setattachment(timer, fountain, ""); + timer.colormap = this.colormap; + timer.glowmod = this.glowmod; + setthink(timer, nade_timer_think); + timer.nextthink = time; + timer.wait = fountain.ltime; + timer.owner = fountain; + timer.skin = 10; + } + else + setmodel(fountain, MDL_Null); +} + void nade_boom(entity this) { entity expef = NULL; bool nade_blast = true; - switch ( REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, this)) ) - { - case NADE_TYPE_NAPALM: - nade_blast = autocvar_g_nades_napalm_blast; - expef = EFFECT_EXPLOSION_MEDIUM; - break; - case NADE_TYPE_ICE: - nade_blast = false; - expef = EFFECT_ELECTRO_COMBO; // hookbomb_explode electro_combo bigplasma_impact - break; - case NADE_TYPE_TRANSLOCATE: - nade_blast = false; - break; - case NADE_TYPE_MONSTER: - if(!autocvar_g_monsters) - { - expef = EFFECT_NADE_EXPLODE(this.realowner.team); - break; // fall back to a standard nade explosion - } - case NADE_TYPE_SPAWN: - nade_blast = false; - switch(this.realowner.team) - { - case NUM_TEAM_1: expef = EFFECT_SPAWN_RED; break; - case NUM_TEAM_2: expef = EFFECT_SPAWN_BLUE; break; - case NUM_TEAM_3: expef = EFFECT_SPAWN_YELLOW; break; - case NUM_TEAM_4: expef = EFFECT_SPAWN_PINK; break; - default: expef = EFFECT_SPAWN_NEUTRAL; break; - } - break; - case NADE_TYPE_HEAL: - nade_blast = false; - expef = EFFECT_SPAWN_RED; - break; - - case NADE_TYPE_ENTRAP: - nade_blast = false; - expef = EFFECT_SPAWN_YELLOW; - break; +#define GET_NADE_TYPE_SPAWN_EFFECT(team_owner) \ + ((team_owner) == NUM_TEAM_1 ? EFFECT_SPAWN_RED : \ + ((team_owner) == NUM_TEAM_2 ? EFFECT_SPAWN_BLUE : \ + ((team_owner) == NUM_TEAM_3 ? EFFECT_SPAWN_YELLOW : \ + ((team_owner) == NUM_TEAM_4 ? EFFECT_SPAWN_PINK : \ + EFFECT_SPAWN_NEUTRAL)))) - case NADE_TYPE_VEIL: - nade_blast = false; - expef = EFFECT_SPAWN_NEUTRAL; - break; +#define SET_NADE_EFFECT(nade_type, blast, exp_effect) \ + case nade_type: \ + nade_blast = blast; \ + expef = exp_effect; \ + break; - default: - case NADE_TYPE_NORMAL: - expef = EFFECT_NADE_EXPLODE(this.realowner.team); - break; + switch ( REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, this)) ) + { + SET_NADE_EFFECT(NADE_TYPE_NAPALM, autocvar_g_nades_napalm_blast, EFFECT_EXPLOSION_MEDIUM); + SET_NADE_EFFECT(NADE_TYPE_ICE, false, EFFECT_ELECTRO_COMBO /* hookbomb_explode electro_combo bigplasma_impact */); + SET_NADE_EFFECT(NADE_TYPE_TRANSLOCATE, false, NULL); + SET_NADE_EFFECT(NADE_TYPE_MONSTER, true, (!autocvar_g_monsters) ? EFFECT_NADE_EXPLODE(this.realowner.team) : NULL); + SET_NADE_EFFECT(NADE_TYPE_SPAWN, false, GET_NADE_TYPE_SPAWN_EFFECT(this.realowner.team)); + SET_NADE_EFFECT(NADE_TYPE_HEAL, false, EFFECT_SPAWN_RED); + SET_NADE_EFFECT(NADE_TYPE_ENTRAP, false, EFFECT_SPAWN_YELLOW); + SET_NADE_EFFECT(NADE_TYPE_VEIL, false, EFFECT_SPAWN_NEUTRAL); + SET_NADE_EFFECT(NADE_TYPE_AMMO, false, EFFECT_SPAWN_BROWN); + SET_NADE_EFFECT(NADE_TYPE_DARK, false, EFFECT_EXPLOSION_MEDIUM); + SET_NADE_EFFECT(NADE_TYPE_NORMAL, true, EFFECT_NADE_EXPLODE(this.realowner.team)); + default: expef = EFFECT_NADE_EXPLODE(this.realowner.team); break; } +#undef GET_NADE_TYPE_SPAWN_EFFECT +#undef SET_NADE_EFFECT if(expef) Send_Effect(expef, findbetterlocation(this.origin, 8), '0 0 0', 1); @@ -746,23 +967,21 @@ void nade_boom(entity this) this.event_damage = func_null; // prevent somehow calling damage in the next call if(nade_blast) - { - RadiusDamage(this, this.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, - autocvar_g_nades_nade_radius, this, NULL, autocvar_g_nades_nade_force, this.projectiledeathtype, DMG_NOWEP, this.enemy); - Damage_DamageInfo(this.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, this.projectiledeathtype, 0, this); - } + normal_nade_boom(this); if(this.takedamage) switch ( REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, this)) ) { - case NADE_TYPE_NAPALM: nade_napalm_boom(this); break; - case NADE_TYPE_ICE: nade_ice_boom(this); break; - case NADE_TYPE_TRANSLOCATE: nade_translocate_boom(this); break; - case NADE_TYPE_SPAWN: nade_spawn_boom(this); break; - case NADE_TYPE_HEAL: nade_heal_boom(this); break; - case NADE_TYPE_MONSTER: nade_monster_boom(this); break; - case NADE_TYPE_ENTRAP: nade_entrap_boom(this); break; - case NADE_TYPE_VEIL: nade_veil_boom(this); break; + case NADE_TYPE_NAPALM: nade_napalm_boom(this); break; + case NADE_TYPE_ICE: nade_ice_boom(this); break; + case NADE_TYPE_TRANSLOCATE: nade_translocate_boom(this); break; + case NADE_TYPE_SPAWN: nade_spawn_boom(this); break; + case NADE_TYPE_HEAL: nade_heal_boom(this); break; + case NADE_TYPE_MONSTER: nade_monster_boom(this); break; + case NADE_TYPE_ENTRAP: nade_entrap_boom(this); break; + case NADE_TYPE_VEIL: nade_veil_boom(this); break; + case NADE_TYPE_AMMO: nade_ammo_boom(this); break; + case NADE_TYPE_DARK: nade_dark_boom(this); break; } IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this, @@ -903,12 +1122,25 @@ void nade_damage(entity this, entity inflictor, entity attacker, float damage, i hp -= damage; SetResource(this, RES_HEALTH, hp); - - if ( STAT(NADE_BONUS_TYPE, this) != NADE_TYPE_HEAL.m_id || IS_PLAYER(attacker) ) + if(STAT(NADE_BONUS_TYPE, this) != NADE_TYPE_TRANSLOCATE.m_id && STAT(NADE_BONUS_TYPE, this) != NADE_TYPE_SPAWN.m_id) + if(STAT(NADE_BONUS_TYPE, this) != NADE_TYPE_HEAL.m_id || IS_PLAYER(attacker)) this.realowner = attacker; if(hp <= 0) + { + if(autocvar_g_nades_spawn_destroy_damage > 0 && STAT(NADE_BONUS_TYPE, this) == NADE_TYPE_SPAWN.m_id) + Damage(this.realowner, attacker, attacker, autocvar_g_nades_spawn_destroy_damage, DEATH_TOUCHEXPLODE.m_id, DMG_NOWEP, this.realowner.origin, '0 0 0'); + + if(autocvar_g_nades_translocate_destroy_damage > 0 && STAT(NADE_BONUS_TYPE, this) == NADE_TYPE_TRANSLOCATE.m_id) + { + Damage(this.realowner, attacker, attacker, autocvar_g_nades_translocate_destroy_damage, DEATH_TOUCHEXPLODE.m_id, DMG_NOWEP, this.realowner.origin, '0 0 0'); + W_PrepareExplosionByDamage(this, this.realowner, nade_boom); // Don't change the owner + + return; + } + W_PrepareExplosionByDamage(this, attacker, nade_boom); + } else nade_burn_spawn(this); } @@ -1135,8 +1367,8 @@ void nade_prime(entity this) } else { - ntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_nade_type : autocvar_g_nades_nade_type); - pntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_pokenade_type : autocvar_g_nades_pokenade_monster_type); + ntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_nade_type : autocvar_g_nades_nade_type); + pntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_pokenade_type : autocvar_g_nades_pokenade_monster_type); } spawn_held_nade(this, this, autocvar_g_nades_nade_lifetime, ntype, pntype); @@ -1190,6 +1422,30 @@ void nades_Clear(entity player) STAT(NADE_TIMER, player) = 0; } +int nades_CheckTypes(entity player, int cl_ntype) +{ +#define CL_NADE_TYPE_CHECK(cl_ntype, cvar) \ + case cl_ntype.m_id: \ + if (!cvar) return NADE_TYPE_NORMAL.m_id; \ + break; + + switch (cl_ntype) + { + CL_NADE_TYPE_CHECK(NADE_TYPE_NAPALM, autocvar_g_nades_napalm); + CL_NADE_TYPE_CHECK(NADE_TYPE_ICE, autocvar_g_nades_ice); + CL_NADE_TYPE_CHECK(NADE_TYPE_TRANSLOCATE, autocvar_g_nades_translocate); + CL_NADE_TYPE_CHECK(NADE_TYPE_SPAWN, autocvar_g_nades_spawn); + CL_NADE_TYPE_CHECK(NADE_TYPE_HEAL, autocvar_g_nades_heal); + CL_NADE_TYPE_CHECK(NADE_TYPE_MONSTER, autocvar_g_nades_pokenade); + CL_NADE_TYPE_CHECK(NADE_TYPE_ENTRAP, autocvar_g_nades_entrap); + CL_NADE_TYPE_CHECK(NADE_TYPE_VEIL, autocvar_g_nades_veil); + CL_NADE_TYPE_CHECK(NADE_TYPE_AMMO, autocvar_g_nades_ammo); + CL_NADE_TYPE_CHECK(NADE_TYPE_DARK, autocvar_g_nades_dark); + } + return cl_ntype; +#undef CL_NADE_TYPE_CHECK +} + MUTATOR_HOOKFUNCTION(nades, VehicleEnter) { entity player = M_ARGV(0, entity); @@ -1297,7 +1553,7 @@ MUTATOR_HOOKFUNCTION(nades, PlayerPreThink) if(autocvar_g_nades_bonus_client_select) { - STAT(NADE_BONUS_TYPE, player) = CS_CVAR(player).cvar_cl_nade_type; + STAT(NADE_BONUS_TYPE, player) = nades_CheckTypes(player, CS_CVAR(player).cvar_cl_nade_type); player.pokenade_type = CS_CVAR(player).cvar_cl_pokenade_type; } else @@ -1415,10 +1671,9 @@ MUTATOR_HOOKFUNCTION(nades, PlayerSpawn) { entity player = M_ARGV(0, entity); - if(autocvar_g_nades_spawn) - player.nade_refire = time + autocvar_g_spawnshieldtime; - else - player.nade_refire = time + autocvar_g_nades_nade_refire; + player.nade_refire = (autocvar_g_nades_onspawn) + ? time + autocvar_g_nades_nade_refire + : time + autocvar_g_spawnshieldtime; if(autocvar_g_nades_bonus_client_select) STAT(NADE_BONUS_TYPE, player) = CS_CVAR(player).cvar_cl_nade_type; @@ -1437,6 +1692,9 @@ MUTATOR_HOOKFUNCTION(nades, PlayerSpawn) delete(player.nade_spawnloc); player.nade_spawnloc = NULL; } + + if(autocvar_g_nades_spawn_health_respawn > 0) + SetResource(player, RES_HEALTH, autocvar_g_nades_spawn_health_respawn); } } diff --git a/qcsrc/common/mutators/mutator/nades/nades.qh b/qcsrc/common/mutators/mutator/nades/nades.qh index a129c826a..a3a282754 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qh +++ b/qcsrc/common/mutators/mutator/nades/nades.qh @@ -6,8 +6,10 @@ bool autocvar_g_nades; bool autocvar_g_nades_override_dropweapon = true; vector autocvar_g_nades_throw_offset; -bool autocvar_g_nades_spawn; +bool autocvar_g_nades_onspawn; int autocvar_g_nades_spawn_count; +float autocvar_g_nades_spawn_health_respawn; +float autocvar_g_nades_spawn_destroy_damage = 25; bool autocvar_g_nades_client_select; bool autocvar_g_nades_pickup = true; float autocvar_g_nades_pickup_time = 2; @@ -21,6 +23,7 @@ float autocvar_g_nades_nade_edgedamage; float autocvar_g_nades_nade_radius; float autocvar_g_nades_nade_force; int autocvar_g_nades_nade_newton_style; +bool autocvar_g_nades_napalm; int autocvar_g_nades_napalm_ball_count; float autocvar_g_nades_napalm_ball_spread; float autocvar_g_nades_napalm_ball_damage; @@ -50,20 +53,37 @@ int autocvar_g_nades_bonus_score_low; int autocvar_g_nades_bonus_score_high; int autocvar_g_nades_bonus_score_medium; int autocvar_g_nades_bonus_score_spree; +bool autocvar_g_nades_ice = true; float autocvar_g_nades_ice_freeze_time; float autocvar_g_nades_ice_health; bool autocvar_g_nades_ice_explode; bool autocvar_g_nades_ice_teamcheck; +bool autocvar_g_nades_translocate = true; +float autocvar_g_nades_translocate_destroy_damage = 25; +bool autocvar_g_nades_spawn = true; +bool autocvar_g_nades_heal = true; float autocvar_g_nades_heal_time; float autocvar_g_nades_heal_rate; float autocvar_g_nades_heal_friend; float autocvar_g_nades_heal_foe; +bool autocvar_g_nades_entrap; float autocvar_g_nades_entrap_strength = 0.01; float autocvar_g_nades_entrap_speed = 0.5; float autocvar_g_nades_entrap_radius = 500; float autocvar_g_nades_entrap_time = 10; +bool autocvar_g_nades_veil; float autocvar_g_nades_veil_time = 8; float autocvar_g_nades_veil_radius = 300; +bool autocvar_g_nades_ammo; +float autocvar_g_nades_ammo_time; +float autocvar_g_nades_ammo_rate; +float autocvar_g_nades_ammo_friend; +float autocvar_g_nades_ammo_foe; +bool autocvar_g_nades_dark; +bool autocvar_g_nades_dark_explode; +bool autocvar_g_nades_dark_teamcheck; +float autocvar_g_nades_dark_time; +bool autocvar_g_nades_pokenade; string autocvar_g_nades_pokenade_monster_type; float autocvar_g_nades_pokenade_monster_lifetime; #endif @@ -86,6 +106,10 @@ const int PROJECTILE_NADE_ENTRAP = 84; const int PROJECTILE_NADE_ENTRAP_BURN = 85; const int PROJECTILE_NADE_VEIL = 86; const int PROJECTILE_NADE_VEIL_BURN = 87; +const int PROJECTILE_NADE_AMMO = 88; +const int PROJECTILE_NADE_AMMO_BURN = 89; +const int PROJECTILE_NADE_DARK = 90; +const int PROJECTILE_NADE_DARK_BURN = 91; REGISTRY(Nades, BITS(4)) REGISTER_REGISTRY(Nades) @@ -142,11 +166,15 @@ REPLICATE_INIT(string, cvar_cl_pokenade_type); .float nade_special_time; .string pokenade_type; .entity nade_damage_target; +.float cvar_cl_nade_type; +.string cvar_cl_pokenade_type; .float toss_time; .float nade_show_particles; .float nade_veil_time; .float nade_veil_prevalpha; .float nade_entrap_time; +.float nade_ammo_time; +.float nade_dark_time; bool orb_send(entity this, entity to, int sf); diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index 96a136cad..18808001b 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -125,6 +125,7 @@ REGISTER_STAT(MONSTERS_KILLED, int) REGISTER_STAT(NADE_BONUS, float) REGISTER_STAT(NADE_BONUS_TYPE, int) REGISTER_STAT(NADE_BONUS_SCORE, float) +REGISTER_STAT(NADE_DARK_TIME, float) REGISTER_STAT(PLASMA, int) REGISTER_STAT(FROZEN, int) REGISTER_STAT(REVIVE_PROGRESS, float) diff --git a/qcsrc/common/turrets/sv_turrets.qc b/qcsrc/common/turrets/sv_turrets.qc index 1cca9b1ca..a42005f32 100644 --- a/qcsrc/common/turrets/sv_turrets.qc +++ b/qcsrc/common/turrets/sv_turrets.qc @@ -695,7 +695,8 @@ float turret_validate_target(entity e_turret, entity e_target, float validate_fl if(!e_target) return -2; - if(e_target.owner == e_turret) + // Don't attack against owner + if(e_target.owner == e_turret || e_target == e_turret.realowner) return -0.5; if(!checkpvs(e_target.origin, e_turret)) diff --git a/qcsrc/common/turrets/turret/tesla_weapon.qc b/qcsrc/common/turrets/turret/tesla_weapon.qc index b62201eb9..f6102801d 100644 --- a/qcsrc/common/turrets/turret/tesla_weapon.qc +++ b/qcsrc/common/turrets/turret/tesla_weapon.qc @@ -73,7 +73,8 @@ entity toast(entity actor, entity from, float range, float damage) if (etarget) { te_csqc_lightningarc(from.origin, etarget.origin); - Damage(etarget, actor, actor, damage, DEATH_TURRET_TESLA.m_id, DMG_NOWEP, etarget.origin, '0 0 0'); + if (etarget != actor.realowner) + Damage(etarget, actor, actor, damage, DEATH_TURRET_TESLA.m_id, DMG_NOWEP, etarget.origin, '0 0 0'); etarget.railgunhit = true; IL_PUSH(g_railgunhit, etarget); } diff --git a/sound/misc/blind.ogg b/sound/misc/blind.ogg new file mode 100644 index 000000000..6a0bc6db6 Binary files /dev/null and b/sound/misc/blind.ogg differ