diff --git a/addons/sourcemod/configs/zombie_riot/challenges/boss_battle_roulette/vote.cfg b/addons/sourcemod/configs/zombie_riot/challenges/boss_battle_roulette/vote.cfg index efc4bec2fd..50f6ffa3e1 100644 --- a/addons/sourcemod/configs/zombie_riot/challenges/boss_battle_roulette/vote.cfg +++ b/addons/sourcemod/configs/zombie_riot/challenges/boss_battle_roulette/vote.cfg @@ -24,6 +24,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/challenges/bossrush/vote.cfg b/addons/sourcemod/configs/zombie_riot/challenges/bossrush/vote.cfg index 99891ce8f5..c0e0c7311c 100644 --- a/addons/sourcemod/configs/zombie_riot/challenges/bossrush/vote.cfg +++ b/addons/sourcemod/configs/zombie_riot/challenges/bossrush/vote.cfg @@ -48,6 +48,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/challenges/defense/vote.cfg b/addons/sourcemod/configs/zombie_riot/challenges/defense/vote.cfg index fd8bd68a39..c7b1c10720 100644 --- a/addons/sourcemod/configs/zombie_riot/challenges/defense/vote.cfg +++ b/addons/sourcemod/configs/zombie_riot/challenges/defense/vote.cfg @@ -30,6 +30,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/challenges/freeplay/advanced.cfg b/addons/sourcemod/configs/zombie_riot/challenges/freeplay/advanced.cfg index 62ea1e3c48..ca2e58ff63 100644 --- a/addons/sourcemod/configs/zombie_riot/challenges/freeplay/advanced.cfg +++ b/addons/sourcemod/configs/zombie_riot/challenges/freeplay/advanced.cfg @@ -4111,6 +4111,70 @@ "plugin" "npc_skilled_crossbowman" "danger_level" "5" } + "2.5" + { + "count" "10" + "health" "100000" + "extra_damage" "1.26" + "plugin" "npc_airraider" + "danger_level" "5" + } + "2.5" + { + "count" "10" + "health" "100000" + "extra_damage" "1.26" + "plugin" "npc_resource_collector" + "danger_level" "5" + } + "2.5" + { + "count" "10" + "health" "100000" + "extra_damage" "1.26" + "plugin" "npc_chemical_spreader" + "danger_level" "5" + } + "2.5" + { + "count" "10" + "health" "100000" + "extra_damage" "1.26" + "plugin" "npc_chemical_specialist" + "danger_level" "5" + } + "2.5" + { + "count" "10" + "health" "300000" + "extra_damage" "1.26" + "plugin" "npc_demolitionist" + "danger_level" "5" + } + "2.5" + { + "count" "10" + "health" "150000" + "extra_damage" "1.26" + "plugin" "npc_giant_armored_medic" + "danger_level" "1" + } + "2.5" + { + "count" "10" + "health" "100000" + "extra_damage" "1.26" + "plugin" "npc_protector" + "danger_level" "5" + } + "2.5" + { + "count" "10" + "health" "100000" + "extra_damage" "1.26" + "plugin" "npc_headhunter" + "danger_level" "5" + } //bosses "2.5" @@ -4123,6 +4187,15 @@ "is_boss" "1" } "2.5" + { + "count" "0" + "health" "3500000" + "plugin" "npc_gasleader" + "extra_damage" "1.26" + "danger_level" "4" + "is_boss" "1" + } + "2.5" { "count" "0" "health" "3500000" diff --git a/addons/sourcemod/configs/zombie_riot/challenges/laststand/vote.cfg b/addons/sourcemod/configs/zombie_riot/challenges/laststand/vote.cfg index 7827015cf5..7d58cca1fd 100644 --- a/addons/sourcemod/configs/zombie_riot/challenges/laststand/vote.cfg +++ b/addons/sourcemod/configs/zombie_riot/challenges/laststand/vote.cfg @@ -30,6 +30,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/challenges/melee/vote.cfg b/addons/sourcemod/configs/zombie_riot/challenges/melee/vote.cfg index af38b39aa8..1d8bde27ca 100644 --- a/addons/sourcemod/configs/zombie_riot/challenges/melee/vote.cfg +++ b/addons/sourcemod/configs/zombie_riot/challenges/melee/vote.cfg @@ -30,6 +30,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/challenges/rebeloutpost/vote.cfg b/addons/sourcemod/configs/zombie_riot/challenges/rebeloutpost/vote.cfg index 9992ddbeed..9b0af5119d 100644 --- a/addons/sourcemod/configs/zombie_riot/challenges/rebeloutpost/vote.cfg +++ b/addons/sourcemod/configs/zombie_riot/challenges/rebeloutpost/vote.cfg @@ -30,6 +30,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/challenges/spybattle/vote.cfg b/addons/sourcemod/configs/zombie_riot/challenges/spybattle/vote.cfg index b2f508a779..bf39b9b654 100644 --- a/addons/sourcemod/configs/zombie_riot/challenges/spybattle/vote.cfg +++ b/addons/sourcemod/configs/zombie_riot/challenges/spybattle/vote.cfg @@ -30,6 +30,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/challenges/survival/vote.cfg b/addons/sourcemod/configs/zombie_riot/challenges/survival/vote.cfg index 4af729545e..56a5f74ef6 100644 --- a/addons/sourcemod/configs/zombie_riot/challenges/survival/vote.cfg +++ b/addons/sourcemod/configs/zombie_riot/challenges/survival/vote.cfg @@ -25,6 +25,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/classic.cfg b/addons/sourcemod/configs/zombie_riot/classic.cfg index 414c6de85d..f848b1538a 100644 --- a/addons/sourcemod/configs/zombie_riot/classic.cfg +++ b/addons/sourcemod/configs/zombie_riot/classic.cfg @@ -108,6 +108,17 @@ "desc" "Paranormal Activity Desc" "level" "0.75" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/construction/3_2.cfg b/addons/sourcemod/configs/zombie_riot/construction/3_2.cfg index 7f260bfec9..3a2dcd9c08 100644 --- a/addons/sourcemod/configs/zombie_riot/construction/3_2.cfg +++ b/addons/sourcemod/configs/zombie_riot/construction/3_2.cfg @@ -50,6 +50,14 @@ "count" "2" "plugin" "npc_payback" } + "0.01" + { + //Retreat All Factory + "count" "0" + "health" "19721121" + "data" "factory_emergency_extraction" + "plugin" "npc_invisible_trigger" + } } "Freeplay" { diff --git a/addons/sourcemod/configs/zombie_riot/construction/4_1.cfg b/addons/sourcemod/configs/zombie_riot/construction/4_1.cfg index 0c4a136034..3d494a7426 100644 --- a/addons/sourcemod/configs/zombie_riot/construction/4_1.cfg +++ b/addons/sourcemod/configs/zombie_riot/construction/4_1.cfg @@ -60,6 +60,14 @@ "count" "10" "plugin" "npc_blocker" } + "0.01" + { + //Retreat All Factory + "count" "0" + "health" "19721121" + "data" "factory_emergency_extraction" + "plugin" "npc_invisible_trigger" + } } "Freeplay" { diff --git a/addons/sourcemod/configs/zombie_riot/construction/6_2.cfg b/addons/sourcemod/configs/zombie_riot/construction/6_2.cfg index 086b23cc7a..a4daed9758 100644 --- a/addons/sourcemod/configs/zombie_riot/construction/6_2.cfg +++ b/addons/sourcemod/configs/zombie_riot/construction/6_2.cfg @@ -80,6 +80,14 @@ "health" "60000" "plugin" "npc_assaulter" } + "0.01" + { + //Retreat All Factory + "count" "0" + "health" "19721121" + "data" "factory_emergency_extraction" + "plugin" "npc_invisible_trigger" + } } "Freeplay" { diff --git a/addons/sourcemod/configs/zombie_riot/construction/9_7.cfg b/addons/sourcemod/configs/zombie_riot/construction/9_7.cfg index 1e9fb3bb64..4ed6c480c1 100644 --- a/addons/sourcemod/configs/zombie_riot/construction/9_7.cfg +++ b/addons/sourcemod/configs/zombie_riot/construction/9_7.cfg @@ -39,6 +39,14 @@ "health" "200000" "plugin" "npc_medival_monk" } + "0.01" + { + //Retreat All Factory + "count" "0" + "health" "19721121" + "data" "factory_emergency_extraction" + "plugin" "npc_invisible_trigger" + } } "Freeplay" { diff --git a/addons/sourcemod/configs/zombie_riot/construction/ending1_final.cfg b/addons/sourcemod/configs/zombie_riot/construction/ending1_final.cfg index 7140b59e3b..a9740c5127 100644 --- a/addons/sourcemod/configs/zombie_riot/construction/ending1_final.cfg +++ b/addons/sourcemod/configs/zombie_riot/construction/ending1_final.cfg @@ -1,7 +1,5 @@ "Waves" { - "complete_item" "Foreign Expidonsan Chip" - "1" { "music_1" diff --git a/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_1.cfg b/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_1.cfg index 68a4ded027..1ca886d497 100644 --- a/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_1.cfg +++ b/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_1.cfg @@ -4,24 +4,38 @@ { "1.0" { - "count" "4" + "count" "2" "health" "30000" "extra_damage" "1.5" - "plugin" "npc_mechafist" + "plugin" "npc_protector" } "1.0" { - "count" "4" + "count" "2" + "health" "30000" + "extra_damage" "1.0" + "plugin" "npc_airraider" + } + "1.0" + { + "count" "2" + "health" "30000" + "extra_damage" "1.5" + "plugin" "npc_zapmarker" + } + "1.0" + { + "count" "2" "health" "50000" "extra_damage" "1.5" - "plugin" "npc_blocker" + "plugin" "npc_chemical_specialist" } "1.0" { "count" "2" "health" "90000" "extra_damage" "1.5" - "plugin" "npc_payback" + "plugin" "npc_demolitionist" } } "Freeplay" diff --git a/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_2.cfg b/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_2.cfg index e4836e431c..618463079f 100644 --- a/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_2.cfg +++ b/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_2.cfg @@ -18,11 +18,18 @@ } "1.0" { - "count" "4" + "count" "2" "health" "30000" "extra_damage" "1.0" "plugin" "npc_scorcher" } + "1.0" + { + "count" "2" + "health" "30000" + "extra_damage" "1.0" + "plugin" "npc_resource_collector" + } } "Freeplay" { diff --git a/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_3.cfg b/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_3.cfg index 171715bd17..35bdd0d175 100644 --- a/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_3.cfg +++ b/addons/sourcemod/configs/zombie_riot/dungeon/base_spawners/difficulty_4/variant_3.cfg @@ -7,21 +7,21 @@ "count" "4" "health" "30000" "extra_damage" "1.5" - "plugin" "npc_mechafist" + "plugin" "npc_resource_collector" } "1.0" { "count" "4" - "health" "50000" - "extra_damage" "1.5" - "plugin" "npc_blocker" + "health" "40000" + "extra_damage" "1.0" + "plugin" "npc_airraider" } "1.0" { - "count" "2" - "health" "90000" + "count" "1" + "health" "100000" "extra_damage" "1.5" - "plugin" "npc_payback" + "plugin" "npc_giant_armored_medic" } "1.0" { @@ -42,28 +42,29 @@ "count" "4" "health" "30000" "extra_damage" "1.0" - "plugin" "npc_scorcher" + "plugin" "npc_zapmarker" } "1.0" { "count" "4" "health" "30000" "extra_damage" "1.5" - "plugin" "npc_mechafist" + "plugin" "npc_resource_collector" + } "1.0" { "count" "4" "health" "50000" "extra_damage" "1.5" - "plugin" "npc_blocker" + "plugin" "npc_zapmarker" } "1.0" { "count" "2" "health" "90000" "extra_damage" "1.5" - "plugin" "npc_payback" + "plugin" "npc_demolitionist" } "1.0" { @@ -84,14 +85,14 @@ "count" "4" "health" "30000" "extra_damage" "1.0" - "plugin" "npc_scorcher" + "plugin" "npc_protector" } "1.0" { - "count" "4" - "health" "30000" - "extra_damage" "1.5" - "plugin" "npc_mechafist" + "count" "2" + "health" "20000" + "extra_damage" "1.0" + "plugin" "npc_headhunter" } "1.0" { @@ -104,16 +105,17 @@ "1.0" { "count" "4" - "health" "50000" + "health" "124000" "extra_damage" "1.5" - "plugin" "npc_blocker" + "plugin" "npc_demolitionist" } "1.0" { "count" "2" "health" "90000" "extra_damage" "1.5" - "plugin" "npc_payback" + "data" "only" + "plugin" "npc_avangard" } "1.0" { @@ -127,14 +129,14 @@ "count" "2" "health" "120000" "extra_damage" "1.25" - "plugin" "npc_mowdown" + "plugin" "npc_giant_armored_medic" } "1.0" { "count" "4" "health" "30000" "extra_damage" "1.0" - "plugin" "npc_scorcher" + "plugin" "npc_protector" } } "Freeplay" diff --git a/addons/sourcemod/configs/zombie_riot/dungeon/final_expidonsa.cfg b/addons/sourcemod/configs/zombie_riot/dungeon/final_expidonsa.cfg index cc37dca45e..f365925e22 100644 --- a/addons/sourcemod/configs/zombie_riot/dungeon/final_expidonsa.cfg +++ b/addons/sourcemod/configs/zombie_riot/dungeon/final_expidonsa.cfg @@ -1,7 +1,5 @@ "Waves" { - "complete_item" "Foreign Expidonsan Chip" - "1" { "0.11" @@ -250,7 +248,7 @@ "0.5" // a little teeny tiny time. { "count" "0" - "health" "8000000" + "health" "16000000" "is_boss" "3" "is_immune_to_nuke" "1" "is_health_scaling" "1" diff --git a/addons/sourcemod/configs/zombie_riot/dungeon/final_space.cfg b/addons/sourcemod/configs/zombie_riot/dungeon/final_space.cfg index 9f9745dee0..4fa31e4699 100644 --- a/addons/sourcemod/configs/zombie_riot/dungeon/final_space.cfg +++ b/addons/sourcemod/configs/zombie_riot/dungeon/final_space.cfg @@ -1,7 +1,5 @@ "Waves" { - "complete_item" "Almagest Data Card" - "1" { diff --git a/addons/sourcemod/configs/zombie_riot/dungeon/raid_2_2.cfg b/addons/sourcemod/configs/zombie_riot/dungeon/raid_2_2.cfg index 1be932fe54..bfff738bc2 100644 --- a/addons/sourcemod/configs/zombie_riot/dungeon/raid_2_2.cfg +++ b/addons/sourcemod/configs/zombie_riot/dungeon/raid_2_2.cfg @@ -15,6 +15,7 @@ "2" { "give_rogue_artifact" "Xeno Resurgance" + "music_1" { "file" "#zombiesurvival/dungeon/raid_attack_2.mp3" diff --git a/addons/sourcemod/configs/zombie_riot/dungeon/raid_3_4.cfg b/addons/sourcemod/configs/zombie_riot/dungeon/raid_3_4.cfg new file mode 100644 index 0000000000..226017aa7a --- /dev/null +++ b/addons/sourcemod/configs/zombie_riot/dungeon/raid_3_4.cfg @@ -0,0 +1,445 @@ +"Waves" +{ + "1" + { + + } + "2" + { + "music_1" + { + "file" "#zombiesurvival/dungeon/raid_attack_3.mp3" + "time" "72" + "volume" "1.4" + "download" "1" + "name" "Stealth Blades" + "author" "Galaxy On Fire 2" + } + + "1.5" + { + "count" "3" + "health" "30000" + "extra_damage" "3.0" + "plugin" "npc_blocker" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "25000" + "extra_damage" "3.0" + "plugin" "npc_resource_collector" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "15000" + "extra_damage" "1.0" + "plugin" "npc_chaos_gunmen" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "4" + "health" "50000" + "extra_damage" "2.0" + "plugin" "npc_contracted_motivator" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "50000" + "extra_damage" "2.0" + "extra_speed" "1.0" + "plugin" "npc_mechafist" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "30000" + "extra_damage" "1.0" + "plugin" "npc_headhunter" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "50000" + "extra_damage" "1.35" + "plugin" "npc_ambusher" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "55000" + "extra_damage" "1.0" + "plugin" "npc_mortar" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "250000" + "extra_damage" "1.75" + "extra_thinkspeed" "0.5" + "data" "only" + "plugin" "npc_avangard" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "45000" + "extra_damage" "1.0" + "plugin" "npc_chemical_specialist" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "40000" + "extra_damage" "1.25" + "plugin" "npc_zapmarker" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "25000" + "extra_damage" "1.35" + "plugin" "npc_hardener" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "30000" + "extra_damage" "2.0" + "plugin" "npc_agent_61" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "55000" + "extra_damage" "1.5" + "plugin" "npc_mortar" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "15000" + "extra_damage" "1.0" + "plugin" "npc_chaos_gunmen" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "60000" + "extra_damage" "2.0" + "plugin" "npc_catapult" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "35000" + "extra_damage" "1.0" + "plugin" "npc_airraider" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "4" + "health" "55000" + "extra_damage" "4.0" + "plugin" "npc_antiarmor_infantry" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "30000" + "extra_damage" "1.0" + "plugin" "npc_protector" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "40000" + "extra_damage" "1.5" + "extra_speed" "1.15" + "plugin" "npc_tanker" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "8" + "health" "50000" + "extra_damage" "3.0" + "plugin" "npc_barbaric_teardown" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "75000" + "extra_damage" "1.35" + "plugin" "npc_giant_armored_medic" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "35000" + "extra_damage" "1.25" + "plugin" "npc_taser" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "40000" + "extra_damage" "2.5" + "plugin" "npc_victorian_artillerist" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "200000" + "extra_damage" "2.00" + "plugin" "npc_ironshield" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "0" + "health" "2000000" + "is_boss" "1" + "extra_damage" "1.25" + "plugin" "npc_gasleader" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "0" + "health" "90000" + "extra_damage" "1.75" + "plugin" "npc_signaller" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "4" + "health" "35000" + "extra_damage" "1.0" + "plugin" "npc_airraider" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "30000" + "extra_damage" "1.0" + "plugin" "npc_headhunter" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "150000" + "extra_damage" "1.35" + "plugin" "npc_demon_possesed_armor" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "25000" + "extra_damage" "2.00" + "plugin" "npc_hardener" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "275000" + "extra_damage" "1.5" + "plugin" "npc_demolitionist" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "35000" + "extra_damage" "1.25" + "plugin" "npc_protector" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "8" + "health" "50000" + "extra_damage" "3.0" + "plugin" "npc_barbaric_teardown" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "50000" + "extra_damage" "4.0" + "plugin" "npc_supplier" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "25000" + "extra_damage" "1.25" + "plugin" "npc_resource_collector" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "32500" + "extra_damage" "2.2" + "plugin" "npc_victorian_artillerist" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "1" + "health" "75000" + "extra_damage" "1.25" + "plugin" "npc_victorian_tank" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "45000" + "extra_damage" "1.35" + "plugin" "npc_chemical_specialist" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "40000" + "extra_damage" "1.35" + "plugin" "npc_zapmarker" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "60000" + "extra_damage" "2.0" + "plugin" "npc_catapult" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "75000" + "extra_damage" "1.0" + "plugin" "npc_giant_armored_medic" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "30000" + "extra_damage" "2.0" + "plugin" "npc_agent_61" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "0" + "health" "90000" + "extra_damage" "1.75" + "plugin" "npc_signaller" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "4" + "health" "35000" + "extra_damage" "1.5" + "plugin" "npc_ambusher" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "150000" + "extra_damage" "1.35" + "plugin" "npc_demon_possesed_armor" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "35000" + "extra_damage" "1.5" + "plugin" "npc_protector" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "4" + "health" "50000" + "extra_damage" "2.0" + "plugin" "npc_contracted_motivator" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "3" + "health" "25000" + "extra_damage" "1.35" + "plugin" "npc_hardener" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "4" + "health" "50000" + "extra_damage" "4.0" + "plugin" "npc_supplier" + "spawn" "home_attackerspawn" + } + "1.5" + { + "count" "2" + "health" "275000" + "extra_damage" "1.5" + "plugin" "npc_demolitionist" + "spawn" "home_attackerspawn" + } + "0.0" + { + "count" "3" + "health" "35000" + "extra_damage" "1.0" + "plugin" "npc_airraider" + "spawn" "home_attackerspawn" + } + } + "Freeplay" + { + // Needed key + } +} \ No newline at end of file diff --git a/addons/sourcemod/configs/zombie_riot/fastmode.cfg b/addons/sourcemod/configs/zombie_riot/fastmode.cfg index 020c363244..24d575ce4b 100644 --- a/addons/sourcemod/configs/zombie_riot/fastmode.cfg +++ b/addons/sourcemod/configs/zombie_riot/fastmode.cfg @@ -117,6 +117,17 @@ "desc" "Paranormal Activity Desc" "level" "0.75" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/maps/vsh_.cfg b/addons/sourcemod/configs/zombie_riot/maps/vsh_.cfg index 5c3685245f..b4465f2974 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/vsh_.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/vsh_.cfg @@ -54,6 +54,17 @@ "desc" "Paranormal Activity Desc" "level" "0.75" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Turbulance" { "func_collect" "Modifier_Collect_Turbolences" diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_1city.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_1city.cfg index e860ef0046..44aef53e16 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_1city.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_1city.cfg @@ -34,6 +34,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_abandoned_lab_surv.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_abandoned_lab_surv.cfg index 23dcc056ff..b6e4b1d960 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_abandoned_lab_surv.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_abandoned_lab_surv.cfg @@ -48,6 +48,17 @@ "desc" "Paranormal Activity Desc" "level" "0.75" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_const2_headquarters.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_const2_headquarters.cfg index 862a164f90..5f612b9d59 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_const2_headquarters.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_const2_headquarters.cfg @@ -74,6 +74,7 @@ "dungeon/raid_3_1" "" "dungeon/raid_3_2" "" "dungeon/raid_3_3" "" + "dungeon/raid_3_4" "" } "4" { diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_defense.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_defense.cfg index cfffb393a4..adc42f5421 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_defense.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_defense.cfg @@ -45,6 +45,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_frigidplace.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_frigidplace.cfg index a9e1cb772c..b5d32b04cc 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_frigidplace.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_frigidplace.cfg @@ -39,6 +39,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_mansion.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_mansion.cfg index 6c5d2fbb75..544e9eecca 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_mansion.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_mansion.cfg @@ -38,6 +38,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_matrix.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_matrix.cfg index 3e966102d5..797644686a 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_matrix.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_matrix.cfg @@ -22,6 +22,64 @@ "level" "70" } } + "Modifiers" + { + "Chaos Intrusion" + { + "func_collect" "Modifier_Collect_ChaosIntrusion" + "func_remove" "Modifier_Remove_ChaosIntrusion" + "func_ally" "" + "func_enemy" "ZRModifs_ChaosIntrusionNPC" + "func_weapon" "" + + "desc" "Chaos Intrusion Desc" + "level" "0.5" + } + "Paranormal Activity" + { + "func_collect" "Modifier_Collect_ParanormalActivity" + "func_remove" "Modifier_Remove_ParanormalActivity" + "func_ally" "" + "func_enemy" "ZRModifs_ParanormalActivityNPC" + "func_weapon" "" + + "desc" "Paranormal Activity Desc" + "level" "0.75" + } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } + "Secondary Mercs" + { + "func_collect" "Modifier_Collect_SecondaryMercs" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "Modifier_RecolourAlly_SecondaryMercs" + "func_enemy" "ZRModifs_SecondaryMercsNPC" + "func_weapon" "" + + "desc" "Secondary Mercs Desc" + "level" "2.0" + } + "Old Times" + { + "func_collect" "Modifier_Collect_OldTimes" + "func_remove" "Modifier_Remove_OldTimes" + "func_ally" "" + "func_enemy" "ZRModifs_OldTimesNPC" + "func_weapon" "" + + "desc" "Old Times Desc" + "level" "3.0" + } + } } "MiniBoss" { diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_nova/vote.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_nova/vote.cfg index 70bf6178af..0288824f32 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_nova/vote.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_nova/vote.cfg @@ -30,6 +30,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Paranormal Activity" { "func_collect" "Modifier_Collect_ParanormalActivity" diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_novaprospekt_new.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_novaprospekt_new.cfg index 01902f6e3e..6c6351193d 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_novaprospekt_new.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_novaprospekt_new.cfg @@ -32,6 +32,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_respawn.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_respawn.cfg index 0deebdf5a9..4472925ce1 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_respawn.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_respawn.cfg @@ -31,6 +31,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_summercamp.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_summercamp.cfg index b977fd61db..b64af772fc 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_summercamp.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_summercamp.cfg @@ -28,6 +28,64 @@ "level" "0000" } } + "Modifiers" + { + "Chaos Intrusion" + { + "func_collect" "Modifier_Collect_ChaosIntrusion" + "func_remove" "Modifier_Remove_ChaosIntrusion" + "func_ally" "" + "func_enemy" "ZRModifs_ChaosIntrusionNPC" + "func_weapon" "" + + "desc" "Chaos Intrusion Desc" + "level" "0.5" + } + "Paranormal Activity" + { + "func_collect" "Modifier_Collect_ParanormalActivity" + "func_remove" "Modifier_Remove_ParanormalActivity" + "func_ally" "" + "func_enemy" "ZRModifs_ParanormalActivityNPC" + "func_weapon" "" + + "desc" "Paranormal Activity Desc" + "level" "0.75" + } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } + "Secondary Mercs" + { + "func_collect" "Modifier_Collect_SecondaryMercs" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "Modifier_RecolourAlly_SecondaryMercs" + "func_enemy" "ZRModifs_SecondaryMercsNPC" + "func_weapon" "" + + "desc" "Secondary Mercs Desc" + "level" "2.0" + } + "Old Times" + { + "func_collect" "Modifier_Collect_OldTimes" + "func_remove" "Modifier_Remove_OldTimes" + "func_ally" "" + "func_enemy" "ZRModifs_OldTimesNPC" + "func_weapon" "" + + "desc" "Old Times Desc" + "level" "3.0" + } + } } "MiniBoss" { diff --git a/addons/sourcemod/configs/zombie_riot/maps/zr_xfactor.cfg b/addons/sourcemod/configs/zombie_riot/maps/zr_xfactor.cfg index fa51a1838a..54ebcc9c66 100644 --- a/addons/sourcemod/configs/zombie_riot/maps/zr_xfactor.cfg +++ b/addons/sourcemod/configs/zombie_riot/maps/zr_xfactor.cfg @@ -36,6 +36,17 @@ "desc" "Chaos Intrusion Desc" "level" "0.5" } + "Prefixes Galore" + { + "func_collect" "Modifier_Collect_Prefix_Galore" + "func_remove" "Modifier_Remove_SecondaryMercs" + "func_ally" "" + "func_enemy" "ZRModifs_ModifEnemyPrefixDuff" + "func_weapon" "" + + "desc" "Prefixes Galore Desc" + "level" "2.0" + } "Secondary Mercs" { "func_collect" "Modifier_Collect_SecondaryMercs" diff --git a/addons/sourcemod/scripting/shared/sdkhooks.sp b/addons/sourcemod/scripting/shared/sdkhooks.sp index 333c004a21..7d016c576e 100644 --- a/addons/sourcemod/scripting/shared/sdkhooks.sp +++ b/addons/sourcemod/scripting/shared/sdkhooks.sp @@ -2485,6 +2485,7 @@ public Action SDKHook_AmbientSoundHook(char sample[PLATFORM_MAX_PATH], int &enti return Plugin_Continue; } +bool LouderSoundStop = false; public Action SDKHook_NormalSHook(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH], int &entity, int &channel, float &volume, int &level, int &pitch, int &flags, char soundEntry[PLATFORM_MAX_PATH], int &seed) @@ -2517,6 +2518,26 @@ public Action SDKHook_NormalSHook(int clients[MAXPLAYERS], int &numClients, char */ #if defined ZR + + if(StrContains(sample, "#", true) != -1) + { + + } + else + { + if(!LouderSoundStop && HasSpecificBuff(entity, "Loud Prefix")) + { + level += 20; + LouderSoundStop = true; + for(int loop1=0; loop1 MaxClients && entity < MAXENTITIES && !b_NpcHasDied[entity] && !(flags & SND_STOP)) { diff --git a/addons/sourcemod/scripting/shared/status_effects.sp b/addons/sourcemod/scripting/shared/status_effects.sp index eb90888a95..2538c40488 100644 --- a/addons/sourcemod/scripting/shared/status_effects.sp +++ b/addons/sourcemod/scripting/shared/status_effects.sp @@ -149,6 +149,14 @@ static const char XenoInfect[][] = { "items/powerup_pickup_plague_infected.wav", }; +static const char BoingSound[][] = +{ + "player/taunt_springrider_squeak1.wav", + "player/taunt_springrider_squeak2.wav", + "player/taunt_springrider_squeak3.wav", + "player/taunt_springrider_squeak4.wav", + "player/taunt_springrider_squeak5.wav", +}; void ResetExplainBuffStatus(int client) { DisplayChatBuffCD[client] = 0.0; @@ -171,6 +179,7 @@ void InitStatusEffects() AL_StatusEffects = new ArrayList(sizeof(StatusEffect)); PrecacheSoundArray(MissSound); PrecacheSoundArray(XenoInfect); + PrecacheSoundArray(BoingSound); DeleteStatusEffectsFromAll(); //clear all existing ones @@ -3353,6 +3362,20 @@ void StatusEffects_Victoria() data.SlotPriority = 0; data.HudDisplay_Func = AmmoTM_Visual_Hud_Func; StatusEffect_AddGlobal(data); + + strcopy(data.BuffName, sizeof(data.BuffName), "Buffweiser"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), "BEER"); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), "BEER"); //BEEEEEERRRRR + //-1.0 means unused + data.DamageTakenMulti = 0.5; //50% less damage taken + data.DamageDealMulti = 1.0; //x2 dmg + data.Positive = true; + data.ShouldScaleWithPlayerCount = true; + data.ElementalLogic = false; + data.HudDisplay_Func = INVALID_FUNCTION; + data.Slot = 0; //0 means ignored + data.SlotPriority = 0; //if its higher, then the lower version is entirely ignored. + StatusEffect_AddGlobal(data); } stock bool NpcStats_VictorianCallToArms(int victim) @@ -7406,8 +7429,8 @@ void StatusEffects_Construct2_EnemyModifs() //-1.0 means unused data.DamageTakenMulti = -1.0; data.DamageDealMulti = -1.0; - data.MovementspeedModif = 1.15; - data.AttackspeedBuff = (1.0 / 3.0); + data.MovementspeedModif = 1.1; + data.AttackspeedBuff = (1.0 / 2.0); data.Positive = true; data.ShouldScaleWithPlayerCount = false; data.OnBuffStarted = Const2Modifs_Haste_Start; @@ -7420,7 +7443,7 @@ void StatusEffects_Construct2_EnemyModifs() strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Big"); //-1.0 means unused - data.DamageTakenMulti = 0.25; + data.DamageTakenMulti = 0.5; data.DamageDealMulti = -1.0; data.MovementspeedModif = -1.0; data.AttackspeedBuff = -1.0; @@ -7436,7 +7459,7 @@ void StatusEffects_Construct2_EnemyModifs() strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Strong"); //-1.0 means unused data.DamageTakenMulti = -1.0; - data.DamageDealMulti = 3.0; + data.DamageDealMulti = 1.75; data.MovementspeedModif = -1.0; data.AttackspeedBuff = -1.0; data.Positive = true; @@ -7536,7 +7559,7 @@ void StatusEffects_Construct2_EnemyModifs() //-1.0 means unused data.DamageTakenMulti = -1.0; data.DamageDealMulti = -1.0; - data.MovementspeedModif = -1.0; + data.MovementspeedModif = -1.0; data.AttackspeedBuff = -1.0; data.Positive = true; data.ShouldScaleWithPlayerCount = false; @@ -7577,6 +7600,22 @@ void StatusEffects_Construct2_EnemyModifs() data.TimerRepeatCall_Func = Const2_SefHeal_Timer; StatusEffect_AddGlobal(data); + strcopy(data.BuffName, sizeof(data.BuffName), "Armoring Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Armoring"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = INVALID_FUNCTION; + data.OnBuffEndOrDeleted = INVALID_FUNCTION; + data.TimerRepeatCall_Func = Const2_Armoring_Timer; + StatusEffect_AddGlobal(data); + strcopy(data.BuffName, sizeof(data.BuffName), "Laggy"); strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty @@ -7662,10 +7701,10 @@ void StatusEffects_Construct2_EnemyModifs() strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), "TF"); //dont display above head, so empty strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "The First"); //-1.0 means unused - data.DamageTakenMulti = 0.3; - data.DamageDealMulti = 2.0; + data.DamageTakenMulti = 0.6; + data.DamageDealMulti = 0.7; data.MovementspeedModif = -1.0; - data.AttackspeedBuff = (1.0 / 2.0); + data.AttackspeedBuff = (1.0 / 1.5); data.Positive = true; data.ShouldScaleWithPlayerCount = false; data.OnBuffStarted = INVALID_FUNCTION; @@ -7674,15 +7713,15 @@ void StatusEffects_Construct2_EnemyModifs() StatusEffect_AddGlobal(data); - strcopy(data.BuffName, sizeof(data.BuffName), "Xeno Infection"); + strcopy(data.BuffName, sizeof(data.BuffName), "Xeno Infection Buff"); strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Xeno"); //-1.0 means unused - data.DamageTakenMulti = 0.75; - data.DamageDealMulti = 0.3; + data.DamageTakenMulti = 0.65; + data.DamageDealMulti = 0.4; data.MovementspeedModif = -1.0; - data.AttackspeedBuff = (1.0 / 0.85); + data.AttackspeedBuff = (1.0 / 0.9); data.Positive = true; data.ShouldScaleWithPlayerCount = false; data.OnBuffStarted = Const2Modifs_Xeno_Start; @@ -7695,10 +7734,10 @@ void StatusEffects_Construct2_EnemyModifs() strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), ""); //-1.0 means unused - data.DamageTakenMulti = 0.7; + data.DamageTakenMulti = 0.65; data.DamageDealMulti = 0.4; data.MovementspeedModif = -1.0; - data.AttackspeedBuff = (1.0 / 0.85); + data.AttackspeedBuff = (1.0 / 0.9); data.Positive = true; data.ShouldScaleWithPlayerCount = false; data.OnBuffStarted = Const2Modifs_Xeno_Start_Already; @@ -7711,8 +7750,8 @@ void StatusEffects_Construct2_EnemyModifs() strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Perfected Instinct"); //-1.0 means unused - data.DamageTakenMulti = 0.3; - data.DamageDealMulti = 2.0; + data.DamageTakenMulti = 0.75; + data.DamageDealMulti = 0.4; data.MovementspeedModif = -1.0; data.AttackspeedBuff = (1.0 / 1.5); data.Positive = true; @@ -7730,7 +7769,7 @@ void StatusEffects_Construct2_EnemyModifs() //-1.0 means unused data.DamageTakenMulti = -1.0; data.DamageDealMulti = -1.0; - data.MovementspeedModif = 4.0; + data.MovementspeedModif = 3.0; data.AttackspeedBuff = -1.0; data.Positive = true; data.ShouldScaleWithPlayerCount = false; @@ -7739,48 +7778,334 @@ void StatusEffects_Construct2_EnemyModifs() data.OnBuffEndOrDeleted = INVALID_FUNCTION; data.TimerRepeatCall_Func = INVALID_FUNCTION; StatusEffect_AddGlobal(data); -} + + strcopy(data.BuffName, sizeof(data.BuffName), "Motivating Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Motivating"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnTakeDamage_TakenFunc = INVALID_FUNCTION; + data.OnBuffStarted = INVALID_FUNCTION; + data.OnBuffEndOrDeleted = INVALID_FUNCTION; + data.TimerRepeatCall_Func = Const2_Motivation_Do; + StatusEffect_AddGlobal(data); -void Const2Modifs_Haste_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) -{ - //not an npc, ignore. - if(!b_ThisWasAnNpc[victim]) - return; + strcopy(data.BuffName, sizeof(data.BuffName), "Invisible Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Invisible"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = Const2Modifs_Paranormal_Start; + data.OnBuffEndOrDeleted = INVALID_FUNCTION; + data.TimerRepeatCall_Func = INVALID_FUNCTION; + StatusEffect_AddGlobal(data); - SetEntityRenderColor_NpcAll(victim, 1.5, 1.5, 0.25); -} -void Const2Modifs_Haste_End(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) -{ - //not an npc, ignore. - if(!IsValidEntity(victim) || !b_ThisWasAnNpc[victim]) - return; + strcopy(data.BuffName, sizeof(data.BuffName), "Asexual Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Asexual"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = INVALID_FUNCTION; + data.OnBuffEndOrDeleted = Const2Modifs_Asexual_End; + data.TimerRepeatCall_Func = INVALID_FUNCTION; + StatusEffect_AddGlobal(data); + + strcopy(data.BuffName, sizeof(data.BuffName), "Glug Infested Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Glug Infested"); + //-1.0 means unused + data.DamageTakenMulti = 0.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = Const2Modifs_Glug_Start; + data.OnBuffEndOrDeleted = Const2Modifs_Glug_End; + data.OnTakeDamage_TakenFunc = Glug_TakeDamage_Spread; + StatusEffect_AddGlobal(data); - SetEntityRenderColor_NpcAll(victim, (1.0 / 1.5), (1.0 / 1.5), (1.0 / 0.25)); -} + strcopy(data.BuffName, sizeof(data.BuffName), "Explosive Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Explosive"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = Const2Modifs_Explosive_Start; + data.OnBuffEndOrDeleted = Const2Modifs_Explosive_End; + data.OnTakeDamage_TakenFunc = INVALID_FUNCTION; + StatusEffect_AddGlobal(data); + + strcopy(data.BuffName, sizeof(data.BuffName), "Stalker Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Stalker"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = 5.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = Const2Modifs_Stalker_Start; + data.OnBuffEndOrDeleted = INVALID_FUNCTION; + data.OnTakeDamage_TakenFunc = INVALID_FUNCTION; + StatusEffect_AddGlobal(data); + + strcopy(data.BuffName, sizeof(data.BuffName), "Stalker Prefix Nerf"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), ""); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = 0.85; + data.AttackspeedBuff = -1.0; + data.Positive = false; + data.ElementalLogic = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = INVALID_FUNCTION; + data.OnBuffEndOrDeleted = INVALID_FUNCTION; + data.OnTakeDamage_TakenFunc = INVALID_FUNCTION; + StatusEffect_AddGlobal(data); + data.ElementalLogic = false; + + strcopy(data.BuffName, sizeof(data.BuffName), "Disco Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Disco"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = Disco_Start; + data.OnBuffEndOrDeleted = Perfected_InstinctEnd; + data.TimerRepeatCall_Func = Disco_Timer; + StatusEffect_AddGlobal(data); + + + strcopy(data.BuffName, sizeof(data.BuffName), "Toxic Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Toxic"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = Toxic_Start; + data.OnBuffEndOrDeleted = Perfected_InstinctEnd; + data.TimerRepeatCall_Func = Toxic_Think_Do; + StatusEffect_AddGlobal(data); + + strcopy(data.BuffName, sizeof(data.BuffName), "Boing Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Boing"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = INVALID_FUNCTION; + data.OnBuffEndOrDeleted = INVALID_FUNCTION; + data.TimerRepeatCall_Func = Boing_Think_Do; + StatusEffect_AddGlobal(data); + data.TimerRepeatCall_Func = INVALID_FUNCTION; -void Const2Modifs_Big_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) -{ - //not an npc, ignore. - if(!b_ThisWasAnNpc[victim]) - return; + + strcopy(data.BuffName, sizeof(data.BuffName), "Knockback Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Knockback"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = INVALID_FUNCTION; + data.OnBuffEndOrDeleted = INVALID_FUNCTION; + data.OnTakeDamage_PostAttacker = Knocback_Prefix_TakeDamageAttackerPost; + StatusEffect_AddGlobal(data); + + data.OnTakeDamage_PostAttacker = INVALID_FUNCTION; + + strcopy(data.BuffName, sizeof(data.BuffName), "Loud Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Loud"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = INVALID_FUNCTION; + data.OnBuffEndOrDeleted = INVALID_FUNCTION; + data.TimerRepeatCall_Func = INVALID_FUNCTION; + StatusEffect_AddGlobal(data); + + strcopy(data.BuffName, sizeof(data.BuffName), "Legendary Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Legendary"); + //-1.0 means unused + data.DamageTakenMulti = 0.0; + data.DamageDealMulti = 0.0; + data.MovementspeedModif = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = Legendary_Prefix_Start; + data.OnBuffEndOrDeleted = Perfected_InstinctEnd; + data.OnTakeDamage_TakenFunc = Legendary_Prefix_DamageTakenFunc; + data.OnTakeDamage_DealFunc = Legendary_Prefix_DamageDealFunc; + StatusEffect_AddGlobal(data); - SetEntPropFloat(victim, Prop_Send, "m_flModelScale", GetEntPropFloat(victim, Prop_Send, "m_flModelScale") * 1.25); -} -void Const2Modifs_Big_End(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) -{ - //not an npc, ignore. - if(!IsValidEntity(victim) || !b_ThisWasAnNpc[victim]) - return; + data.OnTakeDamage_TakenFunc = INVALID_FUNCTION; + data.OnTakeDamage_DealFunc = INVALID_FUNCTION; - SetEntPropFloat(victim, Prop_Send, "m_flModelScale", GetEntPropFloat(victim, Prop_Send, "m_flModelScale") * (1.0 / 1.25)); -} + strcopy(data.BuffName, sizeof(data.BuffName), "Ragebaiter Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Ragebaiter"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = INVALID_FUNCTION; + data.OnBuffEndOrDeleted = INVALID_FUNCTION; + data.TimerRepeatCall_Func = Ragebaiter_Think_Do; + StatusEffect_AddGlobal(data); -void Const2Modifs_Strong_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) -{ - //not an npc, ignore. - if(!b_ThisWasAnNpc[victim]) + strcopy(data.BuffName, sizeof(data.BuffName), "Semi Healthy Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Semi Healthy"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = -1.0; + data.AttackspeedBuff = -1.0; + data.Positive = true; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = SemiHealthy_Start; + data.OnBuffEndOrDeleted = SemiHealthy_End; + data.TimerRepeatCall_Func = INVALID_FUNCTION; + StatusEffect_AddGlobal(data); + + strcopy(data.BuffName, sizeof(data.BuffName), "Fat Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Fat"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = 0.25; + data.AttackspeedBuff = -1.0; + data.Positive = false; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = Const2Modifs_Fat_Start; + data.OnBuffEndOrDeleted = Const2Modifs_Fat_End; + data.TimerRepeatCall_Func = INVALID_FUNCTION; + StatusEffect_AddGlobal(data); + + strcopy(data.BuffName, sizeof(data.BuffName), "Modifier+ Prefix"); + strcopy(data.HudDisplay, sizeof(data.HudDisplay), ""); + strcopy(data.AboveEnemyDisplay, sizeof(data.AboveEnemyDisplay), ""); //dont display above head, so empty + strcopy(data.PrefixEnemyName, sizeof(data.PrefixEnemyName), "Modifier+"); + //-1.0 means unused + data.DamageTakenMulti = -1.0; + data.DamageDealMulti = -1.0; + data.MovementspeedModif = 0.25; + data.AttackspeedBuff = -1.0; + data.Positive = false; + data.ShouldScaleWithPlayerCount = false; + data.OnBuffStarted = Const2Modifs_Modifier_Start; + data.OnBuffEndOrDeleted = INVALID_FUNCTION; + data.TimerRepeatCall_Func = INVALID_FUNCTION; + StatusEffect_AddGlobal(data); + +} + + +void Const2Modifs_Haste_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!b_ThisWasAnNpc[victim]) + return; + + SetEntityRenderColor_NpcAll(victim, 1.5, 1.5, 0.25); +} +void Const2Modifs_Haste_End(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!IsValidEntity(victim) || !b_ThisWasAnNpc[victim]) + return; + + SetEntityRenderColor_NpcAll(victim, (1.0 / 1.5), (1.0 / 1.5), (1.0 / 0.25)); +} + + +void Const2Modifs_Big_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!b_ThisWasAnNpc[victim]) + return; + + SetEntPropFloat(victim, Prop_Send, "m_flModelScale", GetEntPropFloat(victim, Prop_Send, "m_flModelScale") * 1.25); +} +void Const2Modifs_Big_End(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!IsValidEntity(victim) || !b_ThisWasAnNpc[victim]) + return; + + SetEntPropFloat(victim, Prop_Send, "m_flModelScale", GetEntPropFloat(victim, Prop_Send, "m_flModelScale") * (1.0 / 1.25)); +} + +void Const2Modifs_Strong_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!b_ThisWasAnNpc[victim]) return; SetEntityRenderColor_NpcAll(victim, 1.5, 0.25, 0.25); @@ -7863,8 +8188,13 @@ void Const2Modifs_Vampire_TakeDamageAttackerPost(int attacker, int victim, float { if(attacker == victim) return; - - HealEntityGlobal(attacker, attacker, damage * 10, 2.0, 0.0, HEAL_SELFHEAL); + float HealBy = damage * 10.0; + float maxhealth = float(ReturnEntityMaxHealth(attacker)); + maxhealth *= 0.25; + if(HealBy >= maxhealth) + HealBy = maxhealth; + + HealEntityGlobal(attacker, attacker, HealBy, 2.0, 0.0, HEAL_SELFHEAL); } @@ -7923,11 +8253,11 @@ static void Const2_Sprayer_Timer(int entity, StatusEffect Apply_MasterStatusEffe int ArrayPosition = E_AL_StatusEffects[entity].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); Apply_StatusEffect.DataForUse = GetGameTime() + 2.0; E_AL_StatusEffects[entity].SetArray(ArrayPosition, Apply_StatusEffect); - float DamageDeal = 1000.0; + float DamageDeal = 250.0; #if defined ZR DamageDeal = float(CurrentCash); #endif - DamageDeal *= 0.01; + DamageDeal *= 0.0025; if(DamageDeal <= 50.0) DamageDeal = 50.0; @@ -7951,7 +8281,7 @@ static void Const2_Sprayer_Timer(int entity, StatusEffect Apply_MasterStatusEffe Initiate_HomingProjectile(projectile, projectile, 90.0, // float lockonAngleMax, - 13.0, //float homingaSec, + 10.0, //float homingaSec, false, // bool LockOnlyOnce, true, // bool changeAngles, angles); // float AnglesInitiate[3]); @@ -8038,10 +8368,25 @@ static void Const2_SefHeal_Timer(int entity, StatusEffect Apply_MasterStatusEffe E_AL_StatusEffects[entity].SetArray(ArrayPosition, Apply_StatusEffect); float maxhealth = float(ReturnEntityMaxHealth(entity)); + if(b_thisNpcIsARaid[entity] || b_thisNpcIsABoss[entity]) + maxhealth *= 0.01; HealEntityGlobal(entity, entity, maxhealth / 5.0, 1.0, 0.0, HEAL_SELFHEAL); } +static void Const2_Armoring_Timer(int entity, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + if(Apply_StatusEffect.DataForUse > GetGameTime()) + { + return; + } + int ArrayPosition = E_AL_StatusEffects[entity].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); + Apply_StatusEffect.DataForUse = GetGameTime() + 3.0; + E_AL_StatusEffects[entity].SetArray(ArrayPosition, Apply_StatusEffect); - + float maxhealth = float(ReturnEntityMaxHealth(entity)); + if(b_thisNpcIsARaid[entity] || b_thisNpcIsABoss[entity]) + maxhealth *= 0.025; + GrantEntityArmor(entity, false, 1.0, 0.25, 0, maxhealth / 4.0); +} static void Const2_Laggy_Timer(int entity, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) { @@ -8172,9 +8517,12 @@ void Const2_XenoInfect(int entity, int victim, float &healingammount) if(GetTeam(victim) != TFTeam_Red) { - if(HasSpecificBuff(victim, "Xeno Infection") || HasSpecificBuff(victim, "Xeno Infection Buff Only")) + if(HasSpecificBuff(victim, "Xeno Infection Buff") || HasSpecificBuff(victim, "Xeno Infection Buff Only")) return; //infects all teams except red + float maxhealth = float(ReturnEntityMaxHealth(victim)); + if(float(GetEntProp(victim, Prop_Data, "m_iHealth")) >= maxhealth * 0.5) + return; #if defined ZR Xeno_Resurgance_Enemy(victim); #endif @@ -8255,6 +8603,11 @@ float Perfected_Instinct_Dodge(int attacker, int victim, StatusEffect Apply_Mast TE_SendToAll(); int Rand = GetRandomInt(0, sizeof(MissSound) - 1); EmitSoundToAll(MissSound[Rand], victim, _, 80); + if(Apply_StatusEffect.DataForUse > GetGameTime()) + return 0.0; + int ArrayPosition = E_AL_StatusEffects[victim].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); + Apply_StatusEffect.DataForUse = GetGameTime() + 1.0; + E_AL_StatusEffects[victim].SetArray(ArrayPosition, Apply_StatusEffect); ApplyStatusEffect(victim, victim, "Perfected Instinct Speed", 0.35); return 0.0; } @@ -8301,4 +8654,508 @@ void Const2Modifs_Xeno_End(int victim, StatusEffect Apply_MasterStatusEffect, E_ CClotBody npc = view_as(victim); npc.m_iBleedType = RoundToNearest(Apply_StatusEffect.DataForUse); SetEntityRenderColor_NpcAll(victim, (1.0 / 0.15), (1.0 / 0.15), (1.0 / 0.15)); +} + + +static void Const2_Motivation_Do(int entity, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + if(Apply_StatusEffect.DataForUse > GetGameTime()) + { + return; + } + int ArrayPosition = E_AL_StatusEffects[entity].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); + Apply_StatusEffect.DataForUse = GetGameTime() + 0.5; + E_AL_StatusEffects[entity].SetArray(ArrayPosition, Apply_StatusEffect); + + //infect + ContractedMotivatorEffect2(entity, 300.0); + ExpidonsaGroupHeal(entity, + 300.0, + 99, + 0.0, + 1.0, + false, + ConstractedMotivatorBuffs , + _, + true); +} + +void ContractedMotivatorEffect2(int entity, float range) +{ + float ProjectileLoc[3]; + GetEntPropVector(entity, Prop_Data, "m_vecAbsOrigin", ProjectileLoc); + spawnRing_Vectors(ProjectileLoc, 0.1, 0.0, 0.0, 10.0, "materials/sprites/laserbeam.vmt", 200, 200, 65, 100, 1, 0.5, 5.0, 0.1, 3, range * 2.0); +} + + + +void Const2Modifs_Paranormal_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!b_ThisWasAnNpc[victim]) + return; + ZRModifs_ParanormalActivityNPC(victim); +} +void Const2Modifs_Asexual_End(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!IsValidEntity(victim) || !b_ThisWasAnNpc[victim]) + return; + + float maxhealth = float(ReturnEntityMaxHealth(victim)); + maxhealth *= 0.5; + float pos[3]; GetEntPropVector(victim, Prop_Data, "m_vecAbsOrigin", pos); + pos[2] += 50.0; + float ang[3]; GetEntPropVector(victim, Prop_Data, "m_angRotation", ang); + int summon = NPC_CreateById(i_NpcInternalId[victim], -1, pos, ang, GetTeam(victim)); + if(summon > MaxClients) + { + fl_Extra_Damage[summon] = fl_Extra_Damage[victim]; + fl_Extra_Speed[summon] = fl_Extra_Speed[victim]; + fl_Extra_RangedArmor[summon] = fl_Extra_RangedArmor[victim]; + fl_Extra_MeleeArmor[summon] = fl_Extra_MeleeArmor[victim]; + SetEntProp(summon, Prop_Data, "m_iHealth", RoundToNearest(maxhealth)); + SetEntProp(summon, Prop_Data, "m_iMaxHealth", RoundToNearest(maxhealth)); + float flPos[3]; + flPos = pos; + flPos[2] += 300.0; + flPos[0] += GetRandomInt(0,1) ? GetRandomFloat(-200.0, -100.0) : GetRandomFloat(100.0, 200.0); + flPos[1] += GetRandomInt(0,1) ? GetRandomFloat(-200.0, -100.0) : GetRandomFloat(200.0, 200.0); + CClotBody npc = view_as(summon); + npc.SetVelocity({0.0,0.0,0.0}); + PluginBot_Jump(summon, flPos); + ApplyStatusEffect(summon, summon, "Unstoppable Force", 2.0); + ZRModifs_GiveRandomPrefix(summon); + } +} + + +void Const2Modifs_Glug_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!b_ThisWasAnNpc[victim]) + return; + + SetEntityRenderColor_NpcAll(victim, 1.5, 1.5, 0.15); +} +void Const2Modifs_Glug_End(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!IsValidEntity(victim) || !b_ThisWasAnNpc[victim]) + return; + + SetEntityRenderColor_NpcAll(victim, (1.0 / 1.5), (1.0 / 0.15), (1.0 / 0.15)); +} + + +float Glug_TakeDamage_Spread(int attacker, int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect, int damagetype) +{ + if(CheckInHud()) + return 1.0; + + if(Apply_StatusEffect.DataForUse > GetGameTime()) + { + return 1.0; + } + int ArrayPosition = E_AL_StatusEffects[victim].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); + Apply_StatusEffect.DataForUse = GetGameTime() + 10.0; + E_AL_StatusEffects[victim].SetArray(ArrayPosition, Apply_StatusEffect); + + float maxhealth = float(ReturnEntityMaxHealth(victim)); + maxhealth *= 0.25; + if(b_thisNpcIsARaid[victim] || b_thisNpcIsABoss[victim]) + maxhealth *= 0.025; + + float pos[3]; GetEntPropVector(victim, Prop_Data, "m_vecAbsOrigin", pos); + float ang[3]; GetEntPropVector(victim, Prop_Data, "m_angRotation", ang); + int summon = NPC_CreateByName("npc_glug", -1, pos, ang, GetTeam(victim), ""); + if(summon > MaxClients) + { + float DamageDeal = 10.0; +#if defined ZR + DamageDeal = float(CurrentCash); +#endif + DamageDeal *= 0.01; + if(DamageDeal <= 1.0) + DamageDeal = 1.0; + + if(DamageDeal > 100.0) + DamageDeal = 100.0; + fl_Extra_Damage[summon] *= DamageDeal; + fl_Extra_Speed[summon] = fl_Extra_Speed[victim]; + fl_Extra_RangedArmor[summon] = fl_Extra_RangedArmor[victim]; + fl_Extra_MeleeArmor[summon] = fl_Extra_MeleeArmor[victim]; + SetEntProp(summon, Prop_Data, "m_iHealth", RoundToNearest(maxhealth)); + SetEntProp(summon, Prop_Data, "m_iMaxHealth", RoundToNearest(maxhealth)); + float flPos[3]; + flPos = pos; + flPos[2] += 300.0; + flPos[0] += GetRandomInt(0,1) ? GetRandomFloat(-200.0, -100.0) : GetRandomFloat(100.0, 200.0); + flPos[1] += GetRandomInt(0,1) ? GetRandomFloat(-200.0, -100.0) : GetRandomFloat(200.0, 200.0); + CClotBody npc = view_as(summon); + npc.SetVelocity({0.0,0.0,0.0}); + PluginBot_Jump(summon, flPos); + } + return 1.0; +} + + + +void Const2Modifs_Explosive_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!b_ThisWasAnNpc[victim]) + return; + + SetEntityRenderColor_NpcAll(victim, 2.5, 0.15, 0.15); +} +void Const2Modifs_Explosive_End(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!IsValidEntity(victim) || !b_ThisWasAnNpc[victim]) + return; + float DamageDeal = 10000.0; +#if defined ZR + DamageDeal = float(CurrentCash); +#endif + DamageDeal *= 0.25; + if(DamageDeal <= 100.0) + DamageDeal = 100.0; + + b_NpcIsTeamkiller[victim] = true; + Explode_Logic_Custom(DamageDeal, + victim, + victim, + -1, + _, + 350.0, + _, + _, + true, + 99, + false, + 0.01, + _, + BeheadedKamiBoomInternal); + b_NpcIsTeamkiller[victim] = true; + ObjectVintulumBomb npc = view_as(victim); + npc.PlayExplodeDo(true, true); +} + + +void Const2Modifs_Stalker_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!b_ThisWasAnNpc[victim]) + return; + + float maxhealth = float(ReturnEntityMaxHealth(victim)); + maxhealth *= 100.0; + SetEntProp(victim, Prop_Data, "m_iHealth", RoundToNearest(maxhealth)); + SetEntProp(victim, Prop_Data, "m_iMaxHealth", RoundToNearest(maxhealth)); + SetEntityRenderColor_NpcAll(victim, 0.0, 0.0, 0.0); + b_StaticNPC[victim] = true; + AddNpcToAliveList(victim, b_StaticNPC[victim] ? 1 : 0); +} +void Disco_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + if(IsValidEntity(Apply_StatusEffect.WearableUse)) + return; + + float flPos[3]; + GetEntPropVector(victim, Prop_Data, "m_vecAbsOrigin", flPos); + + int entity = CreateEntityByName("light_dynamic"); + if(entity != -1) + { + TeleportEntity(entity, flPos, {0.0,0.0,0.0}, NULL_VECTOR); + + DispatchKeyValue(entity, "brightness", "6"); + DispatchKeyValue(entity, "spotlight_radius", "300"); + DispatchKeyValue(entity, "distance", "300"); + DispatchKeyValue(entity, "_light", "255 255 0 255"); + DispatchSpawn(entity); + ActivateEntity(entity); + AcceptEntityInput(entity, "LightOn"); + b_EntityCantBeColoured[entity] = true; + SetParent(victim, entity); + SDKCall_SetLocalOrigin(entity, {0.0,0.0,80.0}); + int ArrayPosition = E_AL_StatusEffects[victim].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); + Apply_StatusEffect.WearableUse = EntIndexToEntRef(entity); + E_AL_StatusEffects[victim].SetArray(ArrayPosition, Apply_StatusEffect); + } + + +} + + + + +static void Disco_Timer(int entity, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + if(Apply_StatusEffect.DataForUse > GetGameTime()) + { + return; + } + if(!IsValidEntity(Apply_StatusEffect.WearableUse)) + return; + + int ArrayPosition = E_AL_StatusEffects[entity].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); + Apply_StatusEffect.DataForUse = GetGameTime() + 0.0; + E_AL_StatusEffects[entity].SetArray(ArrayPosition, Apply_StatusEffect); + int color[4]; + color[0] = GetRandomInt(0,255); + color[1] = GetRandomInt(0,255); + color[2] = GetRandomInt(0,255); + color[3] = 255; + + SetEntityRenderColor(entity, color[0], color[1], color[2], color[3]); + for(int WearableSlot=0; WearableSlot GetGameTime()) + { + return; + } + int ArrayPosition = E_AL_StatusEffects[entity].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); + Apply_StatusEffect.DataForUse = GetGameTime() + 0.5; + E_AL_StatusEffects[entity].SetArray(ArrayPosition, Apply_StatusEffect); + + float DamageDeal = 10000.0; +#if defined ZR + DamageDeal = float(CurrentCash); +#endif + DamageDeal *= 0.005; + Explode_Logic_Custom(DamageDeal, + entity, + entity, + -1, + _, + 200.0, + _, + _, + true, + 99, + false, + 0.01, + _); +} + + +static void Boing_Think_Do(int entity, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + if(Apply_StatusEffect.DataForUse > GetGameTime()) + { + return; + } + int ArrayPosition = E_AL_StatusEffects[entity].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); + Apply_StatusEffect.DataForUse = GetGameTime() + 3.0; + E_AL_StatusEffects[entity].SetArray(ArrayPosition, Apply_StatusEffect); + + float pos[3]; GetEntPropVector(entity, Prop_Data, "m_vecAbsOrigin", pos); + float flPos[3]; + flPos = pos; + flPos[2] += 400.0; + flPos[0] += GetRandomInt(0,1) ? GetRandomFloat(-200.0, -100.0) : GetRandomFloat(100.0, 200.0); + flPos[1] += GetRandomInt(0,1) ? GetRandomFloat(-200.0, -100.0) : GetRandomFloat(200.0, 200.0); + CClotBody npc = view_as(entity); + npc.SetVelocity({0.0,0.0,0.0}) + PluginBot_Jump(entity, flPos); + fl_GravityMulti[entity] = 3.0; + int Rand = GetRandomInt(0, sizeof(BoingSound) - 1); + EmitSoundToAll(BoingSound[Rand], entity, SNDCHAN_AUTO, 80,_,0.85); +} + + +void Knocback_Prefix_TakeDamageAttackerPost(int attacker, int victim, float damage, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect, int damagetype) +{ + if(attacker == victim) + return; + + Custom_Knockback(attacker, victim, 800.0, true); +} + + +#define LEGENDARY_MAXTIME 30.0 +void Legendary_Prefix_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + if(IsValidEntity(Apply_StatusEffect.WearableUse)) + return; + + float flPos[3]; + GetEntPropVector(victim, Prop_Data, "m_vecAbsOrigin", flPos); + int ParticleEffect = ParticleEffectAt_Parent(flPos, "utaunt_poweraura_green_parent", victim, "", {0.0,0.0,0.0}) + if(b_thisNpcIsABoss[victim] || b_thisNpcIsARaid[victim]) + Apply_StatusEffect.DataForUse = GetGameTime() + (LEGENDARY_MAXTIME * 2.0); //Time passed since, after 30 seconds , max power + else + Apply_StatusEffect.DataForUse = GetGameTime() + LEGENDARY_MAXTIME; //Time passed since, after 30 seconds , max power + + int ArrayPosition = E_AL_StatusEffects[victim].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); + Apply_StatusEffect.WearableUse = EntIndexToEntRef(ParticleEffect); + E_AL_StatusEffects[victim].SetArray(ArrayPosition, Apply_StatusEffect); + + +} + + +float Legendary_Prefix_DamageTakenFunc(int attacker, int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect, int damagetype) +{ + float CurrentTime = Apply_StatusEffect.DataForUse; + CurrentTime -= GetGameTime(); + if(CurrentTime <= 0.1) + CurrentTime = 0.1; + + static float MinBuff = 0.5; + static float MaxBuff = 0.85; + float MaxTime = LEGENDARY_MAXTIME; + if(b_thisNpcIsABoss[victim] || b_thisNpcIsARaid[victim]) + MaxTime *= 2.0; + float buffreturn = MinBuff + ((MaxBuff - MinBuff) / (MaxTime / CurrentTime)); + return buffreturn; +} + +float Legendary_Prefix_DamageDealFunc(int attacker, int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect, int damagetype, float basedamage, float DamageBuffExtraScaling) +{ + float CurrentTime = Apply_StatusEffect.DataForUse; + CurrentTime -= GetGameTime(); + if(CurrentTime <= 1.0) + CurrentTime = 1.0; + + static float MinBuff = 2.0; + static float MaxBuff = 0.1; + float MaxTime = LEGENDARY_MAXTIME; + if(b_thisNpcIsABoss[attacker] || b_thisNpcIsARaid[attacker]) + MaxTime *= 2.0; + float buffreturn = MinBuff + ((MaxBuff - MinBuff) / (MaxTime / CurrentTime)); + + float damagereturn = 0.0; + + damagereturn += basedamage * buffreturn; + return damagereturn; +} + +static void Ragebaiter_Think_Do(int entity, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + if(Apply_StatusEffect.DataForUse > GetGameTime()) + { + return; + } + int ArrayPosition = E_AL_StatusEffects[entity].FindValue(Apply_StatusEffect.BuffIndex, E_StatusEffect::BuffIndex); + Apply_StatusEffect.DataForUse = GetGameTime() + GetRandomFloat(10.0, 30.0); + E_AL_StatusEffects[entity].SetArray(ArrayPosition, Apply_StatusEffect); + + + char RageText[255]; + static int MaxEntries; + if(!MaxEntries) + { + MaxEntries++; + Format(RageText, sizeof(RageText), "Rage Prefix Text %i", MaxEntries); + while(TranslationPhraseExists(RageText)) + { + MaxEntries++; + Format(RageText, sizeof(RageText), "Rage Prefix Text %i", MaxEntries); + } + } + Format(RageText, sizeof(RageText), "Rage Prefix Text %i", GetRandomInt(1,MaxEntries- 1)); + + for(int client = 1; client <= MaxClients; client++) + { + if (IsClientInGame(client) && GetTeam(client) == TFTeam_Red) + { + char NamePrefix[255]; + StatusEffects_PrefixName(entity, client, NamePrefix, sizeof(NamePrefix)); + if(!b_NameNoTranslation[entity]) + { + CPrintToChat(client,"{crimson}%s%s {default}: %t",NamePrefix, c_NpcName[entity], RageText); + } + else + { + CPrintToChat(client,"{crimson}%s%t {default}: %t",NamePrefix, c_NpcName[entity], RageText) + } + } + } +} + + + +void SemiHealthy_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + float maxhealth = float(ReturnEntityMaxHealth(victim)); + maxhealth *= 5.0; + SetEntProp(victim, Prop_Data, "m_iMaxHealth", RoundToNearest(maxhealth)); +} +void SemiHealthy_End(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + float maxhealth = float(ReturnEntityMaxHealth(victim)); + maxhealth /= 5.0; + SetEntProp(victim, Prop_Data, "m_iMaxHealth", RoundToNearest(maxhealth)); +} + + +void Const2Modifs_Fat_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!b_ThisWasAnNpc[victim]) + return; + + float maxhealth = float(ReturnEntityMaxHealth(victim)); + maxhealth *= 2.0; + SetEntProp(victim, Prop_Data, "m_iHealth", RoundToNearest(maxhealth)); + SetEntProp(victim, Prop_Data, "m_iMaxHealth", RoundToNearest(maxhealth)); + SetEntPropFloat(victim, Prop_Send, "m_flModelScale", GetEntPropFloat(victim, Prop_Send, "m_flModelScale") * 1.35); +} +void Const2Modifs_Fat_End(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!IsValidEntity(victim) || !b_ThisWasAnNpc[victim]) + return; + + float maxhealth = float(ReturnEntityMaxHealth(victim)); + maxhealth /= 2.0; + SetEntProp(victim, Prop_Data, "m_iHealth", RoundToNearest(maxhealth)); + SetEntProp(victim, Prop_Data, "m_iMaxHealth", RoundToNearest(maxhealth)); + SetEntPropFloat(victim, Prop_Send, "m_flModelScale", GetEntPropFloat(victim, Prop_Send, "m_flModelScale") * (1.0 / 1.35)); +} + +void Const2Modifs_Modifier_Start(int victim, StatusEffect Apply_MasterStatusEffect, E_StatusEffect Apply_StatusEffect) +{ + //not an npc, ignore. + if(!b_ThisWasAnNpc[victim]) + return; + + ZRModifs_GiveRandomPrefix(victim); + ZRModifs_GiveRandomPrefix(victim); } \ No newline at end of file diff --git a/addons/sourcemod/scripting/shared/stocks.sp b/addons/sourcemod/scripting/shared/stocks.sp index bc0560d875..44a277a515 100644 --- a/addons/sourcemod/scripting/shared/stocks.sp +++ b/addons/sourcemod/scripting/shared/stocks.sp @@ -3202,7 +3202,7 @@ void Projectile_DealElementalDamage(int victim, int attacker, float Scale = 1.0) } } -bool OnlyWarnOnceEver = true; +//bool OnlyWarnOnceEver = true; stock void Explode_Logic_Custom(float damage, int client, //To get attributes from and to see what is my enemy! int entity, //Entity that gets forwarded or traced from/Distance checked. @@ -3239,6 +3239,7 @@ int inflictor = 0) explosion_range_dmg_falloff = Attributes_Get(weapon, Attrib_OverrideExplodeDmgRadiusFalloff, EXPLOSION_RANGE_FALLOFF); } #endif +/* if(explosionRadius >= 2100.0) { if(OnlyWarnOnceEver) @@ -3251,6 +3252,7 @@ int inflictor = 0) //at that point it could just be global too. explosionRadius = 2000.0; } +*/ //this should make explosives during raids more usefull. if(!FromBlueNpc) //make sure that there even is any valid npc before we do these huge calcs. { diff --git a/addons/sourcemod/scripting/zombie_riot/dungeons.sp b/addons/sourcemod/scripting/zombie_riot/dungeons.sp index 467a465527..f0720b29e7 100644 --- a/addons/sourcemod/scripting/zombie_riot/dungeons.sp +++ b/addons/sourcemod/scripting/zombie_riot/dungeons.sp @@ -1985,7 +1985,23 @@ static void StartBattle(const RoomInfo room, float time = 0.1) snap.GetKey(length, buffer, sizeof(buffer)); room.Fights.GetValue(buffer, scale); - EnemyScaling = ScaleBasedOnRound(round) / ScaleBasedOnRound(scale); + //we will scale down round linearly + if(round >= 25) + { + //we lessen scaling number + round += 1; + } + if(round >= 30) + { + //we lessen scaling number + round += 1; + } + if(round >= 40) + { + //we lessen scaling number + round += 1; + } + EnemyScaling = ScaleBasedOnRound((round - 6)) / ScaleBasedOnRound(scale); PrintToConsoleAll("Dungeon Enemy Scaling: %.2f%%", EnemyScaling * 100.0); BuildPath(Path_SM, buffer, sizeof(buffer), CONFIG_CFG, buffer); @@ -2194,7 +2210,7 @@ bool Dungeon_AtLimitNotice() static float ScaleBasedOnRound(int round) { - return (500.0 + Pow(float(round), 2.7)); + return (750.0 + Pow(float(round), 2.8)); } void Dungeon_EnemySpawned(int entity) @@ -2225,7 +2241,7 @@ void Dungeon_EnemySpawned(int entity) if(EnemyScaling > 0.0) { - fl_Extra_Damage[entity] *= 1.0 + ((EnemyScaling - 1.0) / 3.0); + fl_Extra_Damage[entity] *= 1.0 + ((EnemyScaling - 1.0) / 4.0); SetEntProp(entity, Prop_Data, "m_iHealth", RoundToCeil(float(GetEntProp(entity, Prop_Data, "m_iHealth")) * EnemyScaling)); SetEntProp(entity, Prop_Data, "m_iMaxHealth", RoundToCeil(float(ReturnEntityMaxHealth(entity)) * EnemyScaling)); @@ -2416,36 +2432,41 @@ stock int FindByEntityName(const char[] name) return -1; } -public void ZRModifs_ModifEnemyChaos(int iNpc) +public void ZRModifs_ModifEnemyPrefixDuff(int iNpc) { - if(i_NpcInternalId[iNpc] == DungeonLoot_Id() ||i_NpcInternalId[iNpc] == Const2Spawner_Id()) - return; - - fl_Extra_Damage[iNpc] *= 1.10; - int Health = GetEntProp(iNpc, Prop_Data, "m_iMaxHealth"); - SetEntProp(iNpc, Prop_Data, "m_iHealth", RoundToCeil(float(Health) * 1.10)); - SetEntProp(iNpc, Prop_Data, "m_iMaxHealth", RoundToCeil(float(Health) * 1.10)); - + bool DontBuffBaseStats = false; if(b_thisNpcIsABoss[iNpc]) - return; + DontBuffBaseStats = true; + if(b_thisNpcIsARaid[iNpc]) + { + DontBuffBaseStats = true; + RaidModeTime = FAR_FUTURE; + } if(i_IsABuilding[iNpc]) return; if(i_NpcIsABuilding[iNpc]) return; -// if(Dungeon_GetEntityZone(iNpc) != Zone_Dungeon && Dungeon_GetEntityZone(iNpc) != Zone_RivalBase) -// return; - //Rare - if(GetRandomInt(0,RoundToCeil(75.0 * MultiGlobalEnemy)) != 0) + + if(!DontBuffBaseStats && GetRandomInt(0,RoundToCeil(15.0 * MultiGlobalEnemy)) != 0) return; - b_thisNpcHasAnOutline[iNpc] = true; - GiveNpcOutLineLastOrBoss(iNpc, true); - SetEntProp(iNpc, Prop_Data, "m_iHealth", RoundToCeil(float(ReturnEntityMaxHealth(iNpc)) * 3.0)); - SetEntProp(iNpc, Prop_Data, "m_iMaxHealth", RoundToCeil(float(ReturnEntityMaxHealth(iNpc)) * 3.0)); - fl_Extra_Damage[iNpc] *= 1.2; + + if(!DontBuffBaseStats) + { + b_thisNpcHasAnOutline[iNpc] = true; + GiveNpcOutLineLastOrBoss(iNpc, true); + SetEntProp(iNpc, Prop_Data, "m_iHealth", RoundToCeil(float(ReturnEntityMaxHealth(iNpc)) * 3.0)); + SetEntProp(iNpc, Prop_Data, "m_iMaxHealth", RoundToCeil(float(ReturnEntityMaxHealth(iNpc)) * 3.0)); + fl_Extra_Damage[iNpc] *= 1.25; + } + ZRModifs_GiveRandomPrefix(iNpc); + //This is a unique enemy, give mega buffs +} +public void ZRModifs_GiveRandomPrefix(int iNpc) +{ bool RetryBuffGiving = false; bool GiveOneGuranteed = true; int MaxHits = 0; - while(GiveOneGuranteed || RetryBuffGiving || GetRandomInt(1,4) == 1) + while(GiveOneGuranteed || RetryBuffGiving || GetRandomInt(1,3) == 1) { MaxHits++; if(MaxHits >= 1000) @@ -2454,7 +2475,7 @@ public void ZRModifs_ModifEnemyChaos(int iNpc) } GiveOneGuranteed = false; RetryBuffGiving = false; - switch(GetRandomInt(1,18)) + switch(GetRandomInt(1,35)) { case 1: { @@ -2555,7 +2576,7 @@ public void ZRModifs_ModifEnemyChaos(int iNpc) } case 15: { - if(Elemental_DamageRatio(iNpc, Element_Warped) > 0.0) + if(RaidBossActive == EntIndexToEntRef(iNpc) || b_thisNpcIsARaid[iNpc] || Elemental_DamageRatio(iNpc, Element_Warped) > 0.0) { RetryBuffGiving = true; } @@ -2585,15 +2606,175 @@ public void ZRModifs_ModifEnemyChaos(int iNpc) else ApplyStatusEffect(iNpc, iNpc, "Perfected Instinct", 999999.9); } + case 18: { - if(HasSpecificBuff(iNpc, "Xeno Infection") || HasSpecificBuff(iNpc, "Xeno Infection Buff Only")) + if(HasSpecificBuff(iNpc, "Xeno Infection Buff") || HasSpecificBuff(iNpc, "Xeno Infection Buff Only")) RetryBuffGiving = true; Xeno_Resurgance_Enemy(iNpc); } + case 19: + { + if(HasSpecificBuff(iNpc, "Armoring Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Armoring Prefix", 999999.9); + } + case 20: + { + if(HasSpecificBuff(iNpc, "Motivating Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Motivating Prefix", 999999.9); + } + case 21: + { + if(HasSpecificBuff(iNpc, "Invisible Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Invisible Prefix", 999999.9); + } + case 22: + { + if(HasSpecificBuff(iNpc, "Asexual Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Asexual Prefix", 999999.9); + } + case 23: + { + if(HasSpecificBuff(iNpc, "Glug Infested Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Glug Infested Prefix", 999999.9); + } + case 24: + { + if(HasSpecificBuff(iNpc, "Explosive Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Explosive Prefix", 999999.9); + } + case 25: + { + if(RaidBossActive == EntIndexToEntRef(iNpc) || b_thisNpcIsARaid[iNpc] || HasSpecificBuff(iNpc, "Stalker Prefix")) + RetryBuffGiving = true; + else + { + if(GetRandomInt(1,4) == 1) + { + ApplyStatusEffect(iNpc, iNpc, "Stalker Prefix", 999999.9); + ApplyStatusEffect(iNpc, iNpc, "Stalker Prefix Nerf", 999999.9); + } + else + { + //make it really really rare + RetryBuffGiving = true; + } + } + } + case 26: + { + if(HasSpecificBuff(iNpc, "Disco Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Disco Prefix", 999999.9); + } + case 27: + { + if(HasSpecificBuff(iNpc, "Toxic Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Toxic Prefix", 999999.9); + } + case 28: + { + if(HasSpecificBuff(iNpc, "Boing Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Boing Prefix", 999999.9); + } + case 29: + { + if(HasSpecificBuff(iNpc, "Knockback Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Knockback Prefix", 999999.9); + } + case 30: + { + if(HasSpecificBuff(iNpc, "Loud Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Loud Prefix", 999999.9); + } + case 31: + { + if(HasSpecificBuff(iNpc, "Legendary Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Legendary Prefix", 999999.9); + } + case 32: + { + if(HasSpecificBuff(iNpc, "Ragebaiter Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Ragebaiter Prefix", 999999.9); + } + case 33: + { + if(HasSpecificBuff(iNpc, "Semi Healthy Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Semi Healthy Prefix", 999999.9); + } + case 34: + { + if(HasSpecificBuff(iNpc, "Fat Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Fat Prefix", 999999.9); + } + case 35: + { + if(HasSpecificBuff(iNpc, "Modifier+ Prefix")) + RetryBuffGiving = true; + else + ApplyStatusEffect(iNpc, iNpc, "Modifier+ Prefix", 999999.9); + } } } +} +public void ZRModifs_ModifEnemyChaos(int iNpc) +{ + if(i_NpcInternalId[iNpc] == DungeonLoot_Id() ||i_NpcInternalId[iNpc] == Const2Spawner_Id()) + return; + + fl_Extra_Damage[iNpc] *= 1.10; + int Health = GetEntProp(iNpc, Prop_Data, "m_iMaxHealth"); + SetEntProp(iNpc, Prop_Data, "m_iHealth", RoundToCeil(float(Health) * 1.10)); + SetEntProp(iNpc, Prop_Data, "m_iMaxHealth", RoundToCeil(float(Health) * 1.10)); + + if(b_thisNpcIsABoss[iNpc]) + return; + if(i_IsABuilding[iNpc]) + return; + if(i_NpcIsABuilding[iNpc]) + return; +// if(Dungeon_GetEntityZone(iNpc) != Zone_Dungeon && Dungeon_GetEntityZone(iNpc) != Zone_RivalBase) +// return; + //Rare + if(GetRandomInt(0,RoundToCeil(35.0 * MultiGlobalEnemy)) != 0) + return; + + b_thisNpcHasAnOutline[iNpc] = true; + GiveNpcOutLineLastOrBoss(iNpc, true); + SetEntProp(iNpc, Prop_Data, "m_iHealth", RoundToCeil(float(ReturnEntityMaxHealth(iNpc)) * 3.0)); + SetEntProp(iNpc, Prop_Data, "m_iMaxHealth", RoundToCeil(float(ReturnEntityMaxHealth(iNpc)) * 3.0)); + fl_Extra_Damage[iNpc] *= 1.2; + ZRModifs_GiveRandomPrefix(iNpc); //This is a unique enemy, give mega buffs } diff --git a/addons/sourcemod/scripting/zombie_riot/modifiers.sp b/addons/sourcemod/scripting/zombie_riot/modifiers.sp index c5f4eb5517..5ae1e42dd0 100644 --- a/addons/sourcemod/scripting/zombie_riot/modifiers.sp +++ b/addons/sourcemod/scripting/zombie_riot/modifiers.sp @@ -9,6 +9,7 @@ static int CurrentModifActive = 0; #define OLD_TIMES 3 #define TURBOLENCES 4 #define PARANORMAL_ACTIVITY 5 +#define PREFIX_GALORE 6 void Modifier_MiniBossSpawn(bool &spawns) { @@ -54,6 +55,10 @@ public void Modifier_Collect_SecondaryMercs() { CurrentModifActive = SECONDARY_MERCS; } +public void Modifier_Collect_Prefix_Galore() +{ + CurrentModifActive = PREFIX_GALORE; +} public void Modifier_Remove_SecondaryMercs() { @@ -374,6 +379,10 @@ void ZRModifs_CharBuffToAdd(char[] data) { FormatEx(data, 6, "P"); } + case PREFIX_GALORE: + { + FormatEx(data, 6, "PG"); + } } } diff --git a/addons/sourcemod/scripting/zombie_riot/npc.sp b/addons/sourcemod/scripting/zombie_riot/npc.sp index 3031cd4258..4bc49d9762 100644 --- a/addons/sourcemod/scripting/zombie_riot/npc.sp +++ b/addons/sourcemod/scripting/zombie_riot/npc.sp @@ -711,6 +711,18 @@ void NPC_ConfigSetup() TrueCyberWarrior_OnMapStart(); VillageAlaxios_OnMapStart(); +//construction2 Victorians + Demolitionist_OnMapStart_NPC(); + Chemical_Specialist_OnMapStart_NPC(); + Victorian_Protector_OnMapStart_NPC(); + ChemicalSpreader_OnMapStart_NPC(); + Zapmarker_OnMapStart_NPC(); + ArmoredMedic_OnMapStart_NPC(); + Airraider_OnMapStart_NPC(); + Victorian_Headhunter_OnMapStart_NPC(); + Victorian_Resource_Collector_OnMapStart_NPC(); + Gasleader_OnMapStart_NPC(); + //special Invisible_TRIGGER_OnMapStart_NPC();//It is currently used as a trigger for the Victoria Factory. CaptinoBaguettus_OnMapStart_NPC();//Captino Meinus Follower @@ -2449,6 +2461,18 @@ Action NpcSpecificOnTakeDamage(int victim, int &attacker, int &inflictor, float #include "npc/baka/raidbosses/npc_true_cyber_warrior.sp" #include "npc/baka/raidbosses/npc_village_god_alaxios.sp" +//construction2 Victorian +#include "npc/construction/construction2/victorians/npc_demolitionist.sp" +#include "npc/construction/construction2/victorians/npc_chemical_specialist.sp" +#include "npc/construction/construction2/victorians/npc_protector.sp" +#include "npc/construction/construction2/victorians/npc_chemical_spreader.sp" +#include "npc/construction/construction2/victorians/npc_zapmarker.sp" +#include "npc/construction/construction2/victorians/npc_giant_armored_medic.sp" +#include "npc/construction/construction2/victorians/npc_airraider.sp" +#include "npc/construction/construction2/victorians/npc_headhunter.sp" +#include "npc/construction/construction2/victorians/npc_boltbag.sp" +#include "npc/construction/construction2/victorians/npc_gasleader.sp" + //Matrix Enemies #include "npc/matrix/15/npc_agentalan.sp" #include "npc/matrix/15/npc_agentalexander.sp" diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_chaos_bladethrower.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_chaos_bladethrower.sp index 2e00e29c60..90522b1932 100644 --- a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_chaos_bladethrower.sp +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_chaos_bladethrower.sp @@ -322,9 +322,10 @@ public void ArrowStartTouchPierce(int arrow, int entity) return; Set_HitDetectionCooldown(arrow,entity, FAR_FUTURE); + float DamageGet = f_ArrowDamage[arrow]; if(ShouldNpcDealBonusDamage(entity)) { - f_ArrowDamage[arrow] *= 3.0; + DamageGet *= 3.0; } int owner = GetEntPropEnt(arrow, Prop_Send, "m_hOwnerEntity"); @@ -340,7 +341,7 @@ public void ArrowStartTouchPierce(int arrow, int entity) if(inflictor == -1) inflictor = owner; - SDKHooks_TakeDamage(entity, owner, inflictor, f_ArrowDamage[arrow], DMG_BULLET|DMG_PREVENT_PHYSICS_FORCE, -1); + SDKHooks_TakeDamage(entity, owner, inflictor, DamageGet, DMG_BULLET|DMG_PREVENT_PHYSICS_FORCE, -1); Projectile_DealElementalDamage(entity, arrow); EmitSoundToAll(g_ArrowHitSoundSuccess[GetRandomInt(0, sizeof(g_ArrowHitSoundSuccess) - 1)], arrow, _, 80, _, 0.8, 100); diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_lantean_drone_projectile.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_lantean_drone_projectile.sp index c4e4896e54..b8fa17311d 100644 --- a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_lantean_drone_projectile.sp +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_lantean_drone_projectile.sp @@ -87,10 +87,12 @@ methodmap LanteanProjectile < CClotBody if(StrContains(data, "red") != -1) { npc.m_iWearable1 = ParticleEffectAt_Parent(Origin, "flaregun_energyfield_red", npc.index, "", {0.0,0.0,0.0}); + npc.m_iWearable2 = ParticleEffectAt_Parent(Origin, "raygun_projectile_red_trail", npc.index, "", {0.0,0.0,0.0}); } else if(StrContains(data, "blue") != -1) { npc.m_iWearable1 = ParticleEffectAt_Parent(Origin, "flaregun_energyfield_blue", npc.index, "", {0.0,0.0,0.0}); + npc.m_iWearable2 = ParticleEffectAt_Parent(Origin, "raygun_projectile_blue_trail", npc.index, "", {0.0,0.0,0.0}); } //is always static AddNpcToAliveList(npc.index, 1); @@ -450,6 +452,8 @@ static void LanteanNPC_Death(int iNPC) if(IsValidEntity(npc.m_iWearable1)) RemoveEntity(npc.m_iWearable1); + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); SetEntityRenderMode(npc.index, RENDER_NORMAL); SetEntityRenderColor(npc.index, 255, 255, 255, 255); diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_starship_beacon.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_starship_beacon.sp index 363f21b4e3..1e9c2f1e58 100644 --- a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_starship_beacon.sp +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_starship_beacon.sp @@ -282,7 +282,7 @@ static void HandleSummoning(Starship_Beacon npc) int health = ReturnEntityMaxHealth(npc.index); int SpwanIndex = NPC_CreateByName("npc_almagest_proxima", npc.index, Loc, {0.0, 0.0, 0.0}, GetTeam(npc.index)); - + health /= 4; if(SpwanIndex > MaxClients) { SetEntProp(SpwanIndex, Prop_Data, "m_iHealth", health); diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_starship_regalia.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_starship_regalia.sp index 19dc4039ca..2f95bda550 100644 --- a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_starship_regalia.sp +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/npc_starship_regalia.sp @@ -1328,7 +1328,7 @@ methodmap RegaliaClass < CClotBody for(int i=0 ; i < 2 ; i ++) { - int particle_1 = ParticleEffectAt({0.0,0.0,0.0}, skin == 1 ? "raygun_projectile_blue_crit" : "raygun_projectile_red_crit", 0.0); + int particle_1 = ParticleEffectAt({0.0,0.0,0.0}, skin == 1 ? "raygun_projectile_blue_trail" : "raygun_projectile_red_trail", 0.0); SetParent(this.index, particle_1, Sections[i]); this.AddAttachedEntity(particle_1); } @@ -1347,7 +1347,7 @@ methodmap RegaliaClass < CClotBody for(int i=0 ; i < 2 ; i ++) { - int particle_1 = ParticleEffectAt({0.0,0.0,0.0}, skin == 1 ? "raygun_projectile_blue_crit" : "raygun_projectile_red_crit", 0.0); + int particle_1 = ParticleEffectAt({0.0,0.0,0.0}, skin == 1 ? "raygun_projectile_blue_trail" : "raygun_projectile_red_trail", 0.0); SetParent(this.index, particle_1, Sections[i]); this.AddAttachedEntity(particle_1); } @@ -2963,6 +2963,11 @@ static void HandleDroneSystem(RegaliaClass npc) float ShipAngles[3]; ShipAngles = npc.GetAngles(); + int iTargetList[MAXPLAYERS]; + UnderTides npcGetInfo = view_as(npc.index); + GetHighDefTargets(npcGetInfo, iTargetList, sizeof(iTargetList), false, false); + int target_loop = 0; + if(TopSection) { for(int i=0 ; i < 2 ; i++) @@ -2974,7 +2979,8 @@ static void HandleDroneSystem(RegaliaClass npc) Angles[2] = 0.0; Angles[1] += (360.0 / SpawnAmt) * loop; Angles[0] = -45.0; - FireDrones(npc, Loc, Angles); + FireDrones(npc, Loc, Angles, iTargetList[target_loop]); + target_loop++; } } } @@ -2989,12 +2995,13 @@ static void HandleDroneSystem(RegaliaClass npc) Angles[2] = 0.0; Angles[1] += (360.0 / SpawnAmt) * loop; Angles[0] = 45.0; - FireDrones(npc, Loc, Angles); + FireDrones(npc, Loc, Angles, iTargetList[target_loop]); + target_loop++; } } } } -static void FireDrones(CClotBody npc, float Loc[3], float Angles[3]) +static void FireDrones(CClotBody npc, float Loc[3], float Angles[3], int target = -1) { int Drone = NPC_CreateByName("npc_lantean_drone_projectile", npc.index, Loc, Angles, GetTeam(npc.index), "blue;raidmodescaling_damage"); int health = RoundToFloor(ReturnEntityMaxHealth(npc.index) * 0.0005); //like 0.05% hp of ship @@ -3011,6 +3018,9 @@ static void FireDrones(CClotBody npc, float Loc[3], float Angles[3]) drone_npc.m_flTimeTillDeath = GetGameTime() + 10.0 + GetRandomFloat(0.5, 5.0); drone_npc.m_flSpeed = DroneSpeed + 600.0 * GetRandomFloat(0.8, 1.2); + if(target > 0) + drone_npc.m_iTarget = target; + switch(GetRandomInt(1, 2)) { case 1: @@ -3742,6 +3752,16 @@ static void NPC_Death(int iNPC) { Waves_ClearWaves(); ForcePlayerWin(); + for (int client = 1; client <= MaxClients; client++) + { + if(IsValidClient(client) && GetClientTeam(client) == 2 && TeutonType[client] != TEUTON_WAITING && PlayerPoints[client] > 500) + { + if(Items_GiveNamedItem(client, "Almagest Data Card")) + { + CPrintToChat(client, "{green}Obtained{yellow} ''Almagest Data Card''"); + } + } + } for(int i; i < i_MaxcountNpcTotal; i++) { int entitynpc = EntRefToEntIndexFast(i_ObjectsNpcsTotal[i]); diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_airraider.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_airraider.sp new file mode 100644 index 0000000000..5388beaa18 --- /dev/null +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_airraider.sp @@ -0,0 +1,545 @@ +#pragma semicolon 1 +#pragma newdecls required + +static const char g_DeathSounds[][] = { + ")vo/soldier_negativevocalization01.mp3", + ")vo/soldier_negativevocalization02.mp3", + ")vo/soldier_negativevocalization03.mp3", + ")vo/soldier_negativevocalization04.mp3", + ")vo/soldier_negativevocalization05.mp3", + ")vo/soldier_negativevocalization06.mp3", +}; + +static const char g_HurtSounds[][] = { + "vo/soldier_painsharp01.mp3", + "vo/soldier_painsharp02.mp3", + "vo/soldier_painsharp03.mp3", + "vo/soldier_painsharp04.mp3", + "vo/soldier_painsharp05.mp3", + "vo/soldier_painsharp06.mp3", + "vo/soldier_painsharp07.mp3", + "vo/soldier_painsharp08.mp3" +}; + + +static const char g_IdleAlertedSounds[][] = { + "vo/soldier_dominationsniper13.mp3", + "vo/soldier_dominationsniper01.mp3", + "vo/compmode/cm_soldier_pregamefirst_04.mp3", + "vo/compmode/cm_soldier_pregamefirst_05.mp3", + "vo/compmode/cm_soldier_pregamefirst_06.mp3", +}; + +static const char g_RangedAttackSounds[][] = { + "weapons/airstrike_fire_01.wav", + "weapons/airstrike_fire_02.wav", + "weapons/airstrike_fire_03.wav", +}; +static const char g_MeleeAttackSounds[][] = { + "weapons/shotgun_shoot.wav", +}; + +void Airraider_OnMapStart_NPC() +{ + for (int i = 0; i < (sizeof(g_DeathSounds)); i++) { PrecacheSound(g_DeathSounds[i]); } + for (int i = 0; i < (sizeof(g_HurtSounds)); i++) { PrecacheSound(g_HurtSounds[i]); } + for (int i = 0; i < (sizeof(g_IdleAlertedSounds)); i++) { PrecacheSound(g_IdleAlertedSounds[i]); } + for (int i = 0; i < (sizeof(g_RangedAttackSounds)); i++) { PrecacheSound(g_RangedAttackSounds[i]); } + for (int i = 0; i < (sizeof(g_MeleeAttackSounds)); i++) { PrecacheSound(g_MeleeAttackSounds[i]); } + PrecacheModel("models/player/soldier.mdl"); + NPCData data; + strcopy(data.Name, sizeof(data.Name), "Airraider"); + strcopy(data.Plugin, sizeof(data.Plugin), "npc_airraider"); + strcopy(data.Icon, sizeof(data.Icon), "soldine"); + data.IconCustom = true; + data.Flags = 0; + data.Category = Type_Victoria; + data.Func = ClotSummon; + NPC_Add(data); +} + +static any ClotSummon(int client, float vecPos[3], float vecAng[3], int team) +{ + return Airraider(vecPos, vecAng, team); +} + +methodmap Airraider < CClotBody +{ + property int i_GunMode + { + public get() { return i_TimesSummoned[this.index]; } + public set(int TempValueForProperty) { i_TimesSummoned[this.index] = TempValueForProperty; } + } + property float f_AirraiderRocketJumpCD_Wearoff + { + public get() { return fl_AttackHappensMaximum[this.index]; } + public set(float TempValueForProperty) { fl_AttackHappensMaximum[this.index] = TempValueForProperty; } + } + property bool b_AirraiderRocketJump + { + public get() { return b_NextRangedBarrage_OnGoing[this.index]; } + public set(bool TempValueForProperty) { b_NextRangedBarrage_OnGoing[this.index] = TempValueForProperty; } + } + public void PlayIdleAlertSound() + { + if(this.m_flNextIdleSound > GetGameTime(this.index)) + return; + + EmitSoundToAll(g_IdleAlertedSounds[GetRandomInt(0, sizeof(g_IdleAlertedSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME); + this.m_flNextIdleSound = GetGameTime(this.index) + GetRandomFloat(12.0, 24.0); + + } + + public void PlayHurtSound() + { + if(this.m_flNextHurtSound > GetGameTime(this.index)) + return; + + this.m_flNextHurtSound = GetGameTime(this.index) + 0.4; + + EmitSoundToAll(g_HurtSounds[GetRandomInt(0, sizeof(g_HurtSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME); + + } + + public void PlayDeathSound() + { + EmitSoundToAll(g_DeathSounds[GetRandomInt(0, sizeof(g_DeathSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME); + } + + public void PlayRangedSound() + { + EmitSoundToAll(g_RangedAttackSounds[GetRandomInt(0, sizeof(g_RangedAttackSounds) - 1)], this.index, SNDCHAN_AUTO, BOSS_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME); + } + public void PlayShotgunSound() + { + EmitSoundToAll(g_MeleeAttackSounds[GetRandomInt(0, sizeof(g_MeleeAttackSounds) - 1)], this.index, SNDCHAN_AUTO, NORMAL_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME); + } + + + public Airraider(float vecPos[3], float vecAng[3], int ally) + { + Airraider npc = view_as(CClotBody(vecPos, vecAng, "models/player/soldier.mdl", "1.0", "7500", ally)); + + i_NpcWeight[npc.index] = 1; + FormatEx(c_HeadPlaceAttachmentGibName[npc.index], sizeof(c_HeadPlaceAttachmentGibName[]), "head"); + + int iActivity = npc.LookupActivity("ACT_MP_RUN_PRIMARY"); + if(iActivity > 0) npc.StartActivity(iActivity); + + SetVariantInt(2); + AcceptEntityInput(npc.index, "SetBodyGroup"); + + npc.m_flNextMeleeAttack = 0.0; + + npc.m_iBleedType = BLEEDTYPE_NORMAL; + npc.m_iStepNoiseType = STEPSOUND_NORMAL; + npc.m_iNpcStepVariation = STEPTYPE_NORMAL; + + func_NPCDeath[npc.index] = Airraider_NPCDeath; + func_NPCOnTakeDamage[npc.index] = Airraider_OnTakeDamage; + func_NPCThink[npc.index] = Airraider_ClotThink; + + npc.StartPathing(); + npc.m_flSpeed = 250.0; + npc.i_GunMode = 1; + npc.m_flGravityMulti = 0.35; + + npc.Anger = true; + npc.b_AirraiderRocketJump = true; + + npc.m_flNextRangedAttack = GetGameTime(npc.index) + 3.0; + npc.f_AirraiderRocketJumpCD_Wearoff = GetGameTime(npc.index) + 1.0; + b_NpcIsInvulnerable[npc.index] = true; + npc.m_bTeamGlowDefault = false; + + int skin = 1; + SetEntProp(npc.index, Prop_Send, "m_nSkin", skin); + + // Weapon + npc.m_iWearable1 = npc.EquipItem("head", "models/weapons/c_models/c_rocketlauncher/c_rocketlauncher.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable1, "SetModelScale"); + + npc.m_iWearable2 = npc.EquipItem("head", "models/workshop/weapons/c_models/c_paratooper_pack/c_paratrooper_parachute.mdl"); + SetVariantString("3.0"); + AcceptEntityInput(npc.m_iWearable2, "SetModelScale"); + + npc.m_iWearable3 = npc.EquipItem("head", "models/workshop/player/items/soldier/dec2014_skullcap/dec2014_skullcap.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable3, "SetModelScale"); + + npc.m_iWearable4 = npc.EquipItem("head", "models/workshop/player/items/all_class/dec15_gift_bringer/dec15_gift_bringer_soldier.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable4, "SetModelScale"); + + npc.m_iWearable5 = npc.EquipItem("head", "models/workshop/player/items/soldier/fall17_attack_packs/fall17_attack_packs.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable5, "SetModelScale"); + + npc.m_iWearable6 = npc.EquipItem("head", "models/workshop/player/items/soldier/hwn2025_seamanns/hwn2025_seamanns.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable6, "SetModelScale"); + + npc.m_iWearable7 = npc.EquipItem("head", "models/workshop/weapons/c_models/c_paratooper_pack/c_paratrooper_pack.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable7, "SetModelScale"); + + SetEntProp(npc.m_iWearable2, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable3, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable4, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable5, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable6, Prop_Send, "m_nSkin", skin); + + NpcColourCosmetic_ViaPaint(npc.m_iWearable3, 1581885); + NpcColourCosmetic_ViaPaint(npc.m_iWearable4, 1581885); + NpcColourCosmetic_ViaPaint(npc.m_iWearable5, 1581885); + + SetEntPropFloat(npc.index, Prop_Send, "m_fadeMinDist", 1.0); + SetEntPropFloat(npc.index, Prop_Send, "m_fadeMaxDist", 1.0); + SetEntPropFloat(npc.m_iWearable1, Prop_Send, "m_fadeMinDist", 1.0); + SetEntPropFloat(npc.m_iWearable1, Prop_Send, "m_fadeMaxDist", 1.0); + SetEntPropFloat(npc.m_iWearable2, Prop_Send, "m_fadeMinDist", 1.0); + SetEntPropFloat(npc.m_iWearable2, Prop_Send, "m_fadeMaxDist", 1.0); + SetEntPropFloat(npc.m_iWearable3, Prop_Send, "m_fadeMinDist", 1.0); + SetEntPropFloat(npc.m_iWearable3, Prop_Send, "m_fadeMaxDist", 1.0); + SetEntPropFloat(npc.m_iWearable4, Prop_Send, "m_fadeMinDist", 1.0); + SetEntPropFloat(npc.m_iWearable4, Prop_Send, "m_fadeMaxDist", 1.0); + SetEntPropFloat(npc.m_iWearable5, Prop_Send, "m_fadeMinDist", 1.0); + SetEntPropFloat(npc.m_iWearable5, Prop_Send, "m_fadeMaxDist", 1.0); + SetEntPropFloat(npc.m_iWearable6, Prop_Send, "m_fadeMinDist", 1.0); + SetEntPropFloat(npc.m_iWearable6, Prop_Send, "m_fadeMaxDist", 1.0); + SetEntPropFloat(npc.m_iWearable7, Prop_Send, "m_fadeMinDist", 1.0); + SetEntPropFloat(npc.m_iWearable7, Prop_Send, "m_fadeMaxDist", 1.0); + + SetVariantString("deploy_idle"); + AcceptEntityInput(npc.m_iWearable2, "SetAnimation"); + + return npc; + } +} + +public void Airraider_ClotThink(int iNPC) +{ + Airraider npc = view_as(iNPC); + if(npc.m_flNextDelayTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextDelayTime = GetGameTime(npc.index) + DEFAULT_UPDATE_DELAY_FLOAT; + npc.Update(); + + if(!npc.IsOnGround()) + { + npc.m_flRangedArmor = 2.0; + } + else + { + npc.m_flRangedArmor = 1.0; + } + + if(npc.b_AirraiderRocketJump) + { + if(IsValidEntity(npc.m_iTeamGlow)) + RemoveEntity(npc.m_iTeamGlow); + npc.StopPathing(); + if(npc.f_AirraiderRocketJumpCD_Wearoff < GetGameTime(npc.index)) + { + TeleportDiversioToRandLocation(npc.index); + static float flPos[3]; + GetEntPropVector(npc.index, Prop_Data, "m_vecAbsOrigin", flPos); + flPos[2] += 3000.0; + PluginBot_Jump(npc.index, flPos); + SetEntPropFloat(npc.m_iWearable1, Prop_Send, "m_fadeMinDist", 1.0); + SetEntPropFloat(npc.m_iWearable1, Prop_Send, "m_fadeMaxDist", 1.0); + npc.f_AirraiderRocketJumpCD_Wearoff = GetGameTime(npc.index) + 1.0; + npc.b_AirraiderRocketJump = false; + } + return; + } + else if(npc.IsOnGround()) + { + if(npc.f_AirraiderRocketJumpCD_Wearoff < GetGameTime(npc.index)) + { + npc.Anger = false; + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); + npc.i_GunMode = 0; + npc.m_flGravityMulti = 1.0; + } + } + else + { + if(npc.Anger && npc.f_AirraiderRocketJumpCD_Wearoff < GetGameTime(npc.index)) + { + b_NpcIsInvulnerable[npc.index] = false; + npc.m_bTeamGlowDefault = true; + SetEntPropFloat(npc.index, Prop_Send, "m_fadeMinDist", 0.0); + SetEntPropFloat(npc.index, Prop_Send, "m_fadeMaxDist", 0.0); + SetEntPropFloat(npc.m_iWearable1, Prop_Send, "m_fadeMinDist", 0.0); + SetEntPropFloat(npc.m_iWearable1, Prop_Send, "m_fadeMaxDist", 0.0); + if(IsValidEntity(npc.m_iWearable2)) + { + SetEntPropFloat(npc.m_iWearable2, Prop_Send, "m_fadeMinDist", 0.0); + SetEntPropFloat(npc.m_iWearable2, Prop_Send, "m_fadeMaxDist", 0.0); + } + SetEntPropFloat(npc.m_iWearable3, Prop_Send, "m_fadeMinDist", 0.0); + SetEntPropFloat(npc.m_iWearable3, Prop_Send, "m_fadeMaxDist", 0.0); + SetEntPropFloat(npc.m_iWearable4, Prop_Send, "m_fadeMinDist", 0.0); + SetEntPropFloat(npc.m_iWearable4, Prop_Send, "m_fadeMaxDist", 0.0); + SetEntPropFloat(npc.m_iWearable5, Prop_Send, "m_fadeMinDist", 0.0); + SetEntPropFloat(npc.m_iWearable5, Prop_Send, "m_fadeMaxDist", 0.0); + SetEntPropFloat(npc.m_iWearable6, Prop_Send, "m_fadeMinDist", 0.0); + SetEntPropFloat(npc.m_iWearable6, Prop_Send, "m_fadeMaxDist", 0.0); + SetEntPropFloat(npc.m_iWearable7, Prop_Send, "m_fadeMinDist", 0.0); + SetEntPropFloat(npc.m_iWearable7, Prop_Send, "m_fadeMaxDist", 0.0); + } + } + + if(npc.m_blPlayHurtAnimation) + { + npc.AddGesture("ACT_MP_GESTURE_FLINCH_CHEST", false); + npc.m_blPlayHurtAnimation = false; + npc.PlayHurtSound(); + } + + + if(npc.m_flNextThinkTime > GetGameTime(npc.index)) + { + return; + } + + npc.m_flNextThinkTime = GetGameTime(npc.index) + 0.1; + + if(npc.m_flGetClosestTargetTime < GetGameTime(npc.index)) + { + npc.m_iTarget = GetClosestTarget(npc.index); + npc.m_flGetClosestTargetTime = GetGameTime(npc.index) + GetRandomRetargetTime(); + } + + if(IsValidEnemy(npc.index, npc.m_iTarget)) + { + float vecTarget[3]; WorldSpaceCenter(npc.m_iTarget, vecTarget ); + float VecSelfNpc[3]; WorldSpaceCenter(npc.index, VecSelfNpc); + float flDistanceToTarget = GetVectorDistance(vecTarget, VecSelfNpc, true); + if(flDistanceToTarget < npc.GetLeadRadius()) + { + float vPredictedPos[3]; + PredictSubjectPosition(npc, npc.m_iTarget,_,_, vPredictedPos); + npc.SetGoalVector(vPredictedPos); + } + else + { + npc.SetGoalEntity(npc.m_iTarget); + } + AirraiderSelfDefense(npc,GetGameTime(npc.index), npc.m_iTarget, flDistanceToTarget); + } + else + { + npc.m_flGetClosestTargetTime = 0.0; + npc.m_iTarget = GetClosestTarget(npc.index); + } + + AirraiderAnimationChange(npc); + npc.PlayIdleAlertSound(); +} + +public Action Airraider_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + Airraider npc = view_as(victim); + + if(attacker <= 0) + return Plugin_Continue; + + if (npc.m_flHeadshotCooldown < GetGameTime(npc.index)) + { + npc.m_flHeadshotCooldown = GetGameTime(npc.index) + DEFAULT_HURTDELAY; + npc.m_blPlayHurtAnimation = true; + } + + return Plugin_Changed; +} + +public void Airraider_NPCDeath(int entity) +{ + Airraider npc = view_as(entity); + if(!npc.m_bGib) + { + npc.PlayDeathSound(); + } + + if(IsValidEntity(npc.m_iWearable7)) + RemoveEntity(npc.m_iWearable7); + if(IsValidEntity(npc.m_iWearable6)) + RemoveEntity(npc.m_iWearable6); + if(IsValidEntity(npc.m_iWearable8)) + RemoveEntity(npc.m_iWearable8); + if(IsValidEntity(npc.m_iWearable5)) + RemoveEntity(npc.m_iWearable5); + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + if(IsValidEntity(npc.m_iWearable3)) + RemoveEntity(npc.m_iWearable3); + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); + +} +/* + + +*/ +void AirraiderAnimationChange(Airraider npc) +{ + switch(npc.i_GunMode) + { + case 1: //primary + { + if (npc.IsOnGround()) + { + if(npc.m_iChanged_WalkCycle != 1) + { + ResetAirraiderWeapon(npc, 1); + SetVariantInt(2); + AcceptEntityInput(npc.index, "SetBodyGroup"); + npc.m_bisWalking = true; + npc.m_iChanged_WalkCycle = 1; + npc.SetActivity("ACT_MP_RUN_PRIMARY"); + npc.StartPathing(); + } + } + else + { + if(npc.m_iChanged_WalkCycle != 2) + { + ResetAirraiderWeapon(npc, 1); + SetVariantInt(2); + AcceptEntityInput(npc.index, "SetBodyGroup"); + npc.m_bisWalking = false; + npc.m_iChanged_WalkCycle = 2; + npc.SetActivity("ACT_MP_JUMP_FLOAT_PRIMARY"); + npc.StartPathing(); + } + } + } + case 0: //Secondary + { + if (npc.IsOnGround()) + { + if(npc.m_iChanged_WalkCycle != 3) + { + ResetAirraiderWeapon(npc, 0); + SetVariantInt(2); + AcceptEntityInput(npc.index, "SetBodyGroup"); + npc.m_bisWalking = true; + npc.m_iChanged_WalkCycle = 3; + npc.SetActivity("ACT_MP_RUN_SECONDARY"); + npc.StartPathing(); + } + } + else + { + if(npc.m_iChanged_WalkCycle != 4) + { + ResetAirraiderWeapon(npc, 0); + SetVariantInt(2); + AcceptEntityInput(npc.index, "SetBodyGroup"); + npc.m_bisWalking = false; + npc.m_iChanged_WalkCycle = 4; + npc.SetActivity("ACT_MP_JUMP_FLOAT_SECONDARY"); + npc.StartPathing(); + } + } + } + } + +} + +void AirraiderSelfDefense(Airraider npc, float gameTime, int target, float distance) +{ + if(!npc.Anger) + { + npc.i_GunMode = 0; //Imma use my shotgun now + if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 3.0)) + { + int Enemy_I_See = Can_I_See_Enemy(npc.index, npc.m_iTarget); + if(IsValidEnemy(npc.index, Enemy_I_See) && gameTime > npc.m_flNextRangedAttack) + { + npc.AddGesture("ACT_MP_ATTACK_STAND_SECONDARY"); + npc.m_iTarget = Enemy_I_See; + npc.PlayShotgunSound(); + float vecTarget[3]; WorldSpaceCenter(target, vecTarget); + npc.FaceTowards(vecTarget, 20000.0); + Handle swingTrace; + if(npc.DoSwingTrace(swingTrace, target, { 9999.0, 9999.0, 9999.0 })) + { + target = TR_GetEntityIndex(swingTrace); + float vecHit[3]; + TR_GetEndPosition(vecHit, swingTrace); + float origin[3], angles[3]; + view_as(npc.m_iWearable1).GetAttachment("muzzle", origin, angles); + ShootLaser(npc.m_iWearable1, "bullet_tracer02_blue", origin, vecHit, false ); + npc.m_flNextMeleeAttack = gameTime + 0.75; + + if(IsValidEnemy(npc.index, target)) + { + float damageDealt = 90.0; + if(ShouldNpcDealBonusDamage(target)) + damageDealt *= 2.0; + + SDKHooks_TakeDamage(target, npc.index, npc.index, damageDealt, DMG_BULLET, -1, _, vecHit); + } + npc.m_flNextRangedAttack = gameTime + 0.50; + } + delete swingTrace; + } + } + return; + } + npc.i_GunMode = 1; //rocket! + if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 900.0)) + { + if(gameTime > npc.m_flNextRangedAttack) + { + if(Can_I_See_Enemy_Only(npc.index, target)) + { + float projectile_speed = 1000.0; + float DamageRocket = 30.0; + float vPredictedPos[3]; + PredictSubjectPositionForProjectiles(npc, target, projectile_speed, _,vPredictedPos); + + npc.FaceTowards(vPredictedPos, 20000.0); + //Play attack anim + npc.AddGesture("ACT_MP_ATTACK_STAND_PRIMARY"); + + npc.PlayRangedSound(); + npc.FireRocket(vPredictedPos, DamageRocket, projectile_speed, "models/weapons/w_models/w_rocket_airstrike/w_rocket_airstrike.mdl"); + npc.m_flNextRangedAttack = gameTime + 0.30; + } + } + } + return; +} + +void ResetAirraiderWeapon(Airraider npc, int weapon_Type) +{ + if(IsValidEntity(npc.m_iWearable1)) + { + RemoveEntity(npc.m_iWearable1); + } + switch(weapon_Type) + { + case 1: + { + npc.m_iWearable1 = npc.EquipItem("head", "models/workshop/weapons/c_models/c_atom_launcher/c_atom_launcher.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable1, "SetModelScale"); + } + case 0: + { + npc.m_iWearable1 = npc.EquipItem("head", "models/weapons/c_models/c_reserve_shooter/c_reserve_shooter.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable1, "SetModelScale"); + } + } +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_boltbag.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_boltbag.sp new file mode 100644 index 0000000000..a529055273 --- /dev/null +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_boltbag.sp @@ -0,0 +1,297 @@ +#pragma semicolon 1 +#pragma newdecls required + +static const char g_DeathSounds[][] = { + ")physics/metal/metal_canister_impact_hard1.wav", + ")physics/metal/metal_canister_impact_hard2.wav", + ")physics/metal/metal_canister_impact_hard3.wav", +}; + +static const char g_HurtSounds[][] = { + "weapons/sentry_damage1.wav", + "weapons/sentry_damage2.wav", + "weapons/sentry_damage3.wav", + "weapons/sentry_damage4.wav" +}; + +static const char g_IdleAlertedSounds[][] = { + "npc/scanner/scanner_alert1.wav" +}; + +static const char g_MeleeAttackSounds[][] = { + "weapons/machete_swing.wav", +}; + +static const char g_MeleeHitSounds[][] = { + "weapons/neon_sign_hit_01.wav", + "weapons/neon_sign_hit_02.wav", + "weapons/neon_sign_hit_03.wav", + "weapons/neon_sign_hit_04.wav" +}; + +static const char g_SapperHitSounds[][] = { + "weapons/rescue_ranger_charge_01.wav", + "weapons/rescue_ranger_charge_02.wav", +}; + +void Victorian_Resource_Collector_OnMapStart_NPC() +{ + NPCData data; + strcopy(data.Name, sizeof(data.Name), "Resource Collector"); + strcopy(data.Plugin, sizeof(data.Plugin), "npc_resource_collector"); + strcopy(data.Icon, sizeof(data.Icon), "victoria_ironshield"); + data.IconCustom = false; + data.Flags = 0; + data.Category = Type_Victoria; + data.Precache = ClotPrecache; + data.Func = ClotSummon; + NPC_Add(data); +} + +static void ClotPrecache() +{ + PrecacheSoundArray(g_DeathSounds); + PrecacheSoundArray(g_HurtSounds); + PrecacheSoundArray(g_IdleAlertedSounds); + PrecacheSoundArray(g_MeleeAttackSounds); + PrecacheSoundArray(g_MeleeHitSounds); + PrecacheSoundArray(g_SapperHitSounds); + PrecacheModel("models/bots/bot_worker/bot_worker.mdl"); +} + +static any ClotSummon(int client, float vecPos[3], float vecAng[3], int ally) +{ + return ResourceCollector(vecPos, vecAng, ally); +} + +methodmap ResourceCollector < CClotBody +{ + public void PlayIdleAlertSound() + { + if(this.m_flNextIdleSound > GetGameTime(this.index)) + return; + + EmitSoundToAll(g_IdleAlertedSounds[GetRandomInt(0, sizeof(g_IdleAlertedSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 150); + this.m_flNextIdleSound = GetGameTime(this.index) + GetRandomFloat(12.0, 24.0); + } + public void PlayHurtSound() + { + if(this.m_flNextHurtSound > GetGameTime(this.index)) + return; + + this.m_flNextHurtSound = GetGameTime(this.index) + 0.4; + + EmitSoundToAll(g_HurtSounds[GetRandomInt(0, sizeof(g_HurtSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 125); + } + public void PlayDeathSound() + { + EmitSoundToAll(g_DeathSounds[GetRandomInt(0, sizeof(g_DeathSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 130); + } + public void PlayMeleeSound() + { + EmitSoundToAll(g_MeleeAttackSounds[GetRandomInt(0, sizeof(g_MeleeAttackSounds) - 1)], this.index, SNDCHAN_AUTO, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + public void PlayMeleeHitSound() + { + EmitSoundToAll(g_MeleeHitSounds[GetRandomInt(0, sizeof(g_MeleeHitSounds) - 1)], this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + public void PlaySapperHitSound() + { + EmitSoundToAll(g_SapperHitSounds[GetRandomInt(0, sizeof(g_SapperHitSounds) - 1)], this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + + } + + public ResourceCollector(float vecPos[3], float vecAng[3], int ally) + { + ResourceCollector npc = view_as(CClotBody(vecPos, vecAng, "models/bots/bot_worker/bot_worker.mdl", "0.8", "9500", ally)); + + i_NpcWeight[npc.index] = 1; + + npc.m_flNextMeleeAttack = 0.0; + + npc.m_iBleedType = BLEEDTYPE_METAL; + npc.m_iNpcStepVariation = 0; + + func_NPCDeath[npc.index] = view_as(ResourceCollector_NPCDeath); + func_NPCOnTakeDamage[npc.index] = view_as(ResourceCollector_OnTakeDamage); + func_NPCThink[npc.index] = view_as(ResourceCollector_ClotThink); + + b_DoGibThisNpc[npc.index] = true; + b_DissapearOnDeath[npc.index] = true; + + //IDLE + npc.m_iState = 0; + npc.m_flGetClosestTargetTime = 0.0; + npc.StartPathing(); + npc.m_flSpeed = 300.0; + + npc.m_flRangedArmor = 0.7; + + int skin = 1; + SetEntProp(npc.index, Prop_Send, "m_nSkin", skin); + + //npc.m_iWearable1 = npc.EquipItemSeperate("models/workshop/player/items/engineer/sum19_brain_interface/sum19_brain_interface.mdl",_,skin,1.9,-120.0); + + return npc; + } +} + +static void ResourceCollector_ClotThink(int iNPC) +{ + ResourceCollector npc = view_as(iNPC); + if(npc.m_flNextDelayTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextDelayTime = GetGameTime(npc.index) + DEFAULT_UPDATE_DELAY_FLOAT; + npc.Update(); + + if(npc.m_blPlayHurtAnimation) + { + npc.PlayHurtSound(); + } + + if(npc.m_flNextThinkTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextThinkTime = GetGameTime(npc.index) + 0.1; + + if(npc.m_flGetClosestTargetTime < GetGameTime(npc.index)) + { + npc.m_iTarget = GetClosestTarget(npc.index); + npc.m_flGetClosestTargetTime = GetGameTime(npc.index) + GetRandomRetargetTime(); + } + if(NpcStats_VictorianCallToArms(npc.index)) + { + npc.m_flSpeed = 400.0; + } + else + { + npc.m_flSpeed = 300.0; + } + + if(IsValidEnemy(npc.index, npc.m_iTarget)) + { + float vecTarget[3]; WorldSpaceCenter(npc.m_iTarget, vecTarget ); + + float VecSelfNpc[3]; WorldSpaceCenter(npc.index, VecSelfNpc); + float flDistanceToTarget = GetVectorDistance(vecTarget, VecSelfNpc, true); + if(flDistanceToTarget < npc.GetLeadRadius()) + { + float vPredictedPos[3]; + PredictSubjectPosition(npc, npc.m_iTarget,_,_, vPredictedPos); + npc.SetGoalVector(vPredictedPos); + } + else + { + npc.SetGoalEntity(npc.m_iTarget); + } + ResourceCollectorSelfDefense(npc,GetGameTime(npc.index), npc.m_iTarget, flDistanceToTarget); + } + else + { + npc.m_flGetClosestTargetTime = 0.0; + npc.m_iTarget = GetClosestTarget(npc.index); + } + + + npc.PlayIdleAlertSound(); +} + +static Action ResourceCollector_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + ResourceCollector npc = view_as(victim); + + if(attacker <= 0) + return Plugin_Continue; + + if (npc.m_flHeadshotCooldown < GetGameTime(npc.index)) + { + npc.m_flHeadshotCooldown = GetGameTime(npc.index) + DEFAULT_HURTDELAY; + npc.m_blPlayHurtAnimation = true; + } + + return Plugin_Changed; +} + +static void ResourceCollector_NPCDeath(int entity) +{ + ResourceCollector npc = view_as(entity); + if(!npc.m_bGib) + { + npc.PlayDeathSound(); + } + float VecDeath[3]; WorldSpaceCenter(npc.index, VecDeath); + ParticleEffectAt(VecDeath, "ExplosionCore_buildings", 0.5); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); +} + +static void ResourceCollectorSelfDefense(ResourceCollector npc, float gameTime, int target, float distance) +{ + if(npc.m_flAttackHappens) + { + if(npc.m_flAttackHappens < gameTime) + { + npc.m_flAttackHappens = 0.0; + + Handle swingTrace; + float VecEnemy[3]; WorldSpaceCenter(npc.m_iTarget, VecEnemy); + npc.FaceTowards(VecEnemy, 15000.0); + if(npc.DoSwingTrace(swingTrace, npc.m_iTarget)) + { + + target = TR_GetEntityIndex(swingTrace); + + float vecHit[3]; + TR_GetEndPosition(vecHit, swingTrace); + + if(IsValidEnemy(npc.index, target)) + { + float damageDealt = 50.0; + + if(ShouldNpcDealBonusDamage(target)) + { + damageDealt *= 5.0; + if(NpcStats_VictorianCallToArms(npc.index)) + damageDealt *= 2.0; + } + + + int DamageType = DMG_CLUB; + + SDKHooks_TakeDamage(target, npc.index, npc.index, damageDealt, DamageType, -1, _, vecHit); + + // Hit sound + if(ShouldNpcDealBonusDamage(target)) + npc.PlaySapperHitSound(); + else + npc.PlayMeleeHitSound(); + } + } + delete swingTrace; + } + } + + if(gameTime > npc.m_flNextMeleeAttack) + { + if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED)) + { + int Enemy_I_See; + + Enemy_I_See = Can_I_See_Enemy(npc.index, npc.m_iTarget); + + if(IsValidEnemy(npc.index, Enemy_I_See)) + { + npc.m_iTarget = Enemy_I_See; + npc.PlayMeleeSound(); + npc.AddGesture("panic",_,_,_,1.0); + + npc.m_flAttackHappens = gameTime + 0.15; + npc.m_flDoingAnimation = gameTime + 0.15; + npc.m_flNextMeleeAttack = gameTime + 1.0; + } + } + } +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_chemical_specialist.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_chemical_specialist.sp new file mode 100644 index 0000000000..e1d4dfc0d6 --- /dev/null +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_chemical_specialist.sp @@ -0,0 +1,351 @@ +#pragma semicolon 1 +#pragma newdecls required + +static const char g_DeathSounds[][] = { + ")vo/engineer_negativevocalization01.mp3", + ")vo/engineer_negativevocalization02.mp3", + ")vo/engineer_negativevocalization03.mp3", + ")vo/engineer_negativevocalization04.mp3", + ")vo/engineer_negativevocalization05.mp3", + ")vo/engineer_negativevocalization06.mp3", + ")vo/engineer_negativevocalization07.mp3", + ")vo/engineer_negativevocalization08.mp3", + ")vo/engineer_negativevocalization09.mp3", + ")vo/engineer_negativevocalization10.mp3", + ")vo/engineer_negativevocalization11.mp3", + ")vo/engineer_negativevocalization12.mp3", +}; + +static const char g_HurtSounds[][] = { + "vo/engineer_painsharp01.mp3", + "vo/engineer_painsharp02.mp3", + "vo/engineer_painsharp03.mp3", + "vo/engineer_painsharp04.mp3", + "vo/engineer_painsharp05.mp3", + "vo/engineer_painsharp06.mp3", + "vo/engineer_painsharp07.mp3", + "vo/engineer_painsharp08.mp3" +}; + + +static const char g_IdleAlertedSounds[][] = { + "vo/engineer_mvm_mannhattan_gate_atk01.mp3", + "vo/engineer_mvm_mannhattan_gate_atk02.mp3", + "vo/engineer_mvm_mannhattan_gate_atk03.mp3", +}; + +static const char g_RangeAttackSounds[] = "weapons/ar2/fire1.wav"; + +void Chemical_Specialist_OnMapStart_NPC() +{ + NPCData data; + strcopy(data.Name, sizeof(data.Name), "Chemical Specialist"); + strcopy(data.Plugin, sizeof(data.Plugin), "npc_chemical_specialist"); + strcopy(data.Icon, sizeof(data.Icon), "victoria_shotgunner"); + data.IconCustom = true; + data.Flags = 0; + data.Category = Type_Victoria; + data.Precache = ClotPrecache; + data.Func = ClotSummon; + int id = NPC_Add(data); + Rogue_Paradox_AddWinterNPC(id); +} + +static void ClotPrecache() +{ + PrecacheSoundArray(g_DeathSounds); + PrecacheSoundArray(g_HurtSounds); + PrecacheSoundArray(g_IdleAlertedSounds); + PrecacheSound(g_RangeAttackSounds); + PrecacheModel("models/player/engineer.mdl"); +} + +static any ClotSummon(int client, float vecPos[3], float vecAng[3], int ally) +{ + return Chemical_Specialist(vecPos, vecAng, ally); +} + +methodmap Chemical_Specialist < CClotBody +{ + public void PlayIdleAlertSound() + { + if(this.m_flNextIdleSound > GetGameTime(this.index)) + return; + EmitSoundToAll(g_IdleAlertedSounds[GetRandomInt(0, sizeof(g_IdleAlertedSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + this.m_flNextIdleSound = GetGameTime(this.index) + GetRandomFloat(12.0, 24.0); + } + public void PlayHurtSound() + { + if(this.m_flNextHurtSound > GetGameTime(this.index)) + return; + EmitSoundToAll(g_HurtSounds[GetRandomInt(0, sizeof(g_HurtSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + this.m_flNextHurtSound = GetGameTime(this.index) + 0.4; + } + public void PlayDeathSound() + { + EmitSoundToAll(g_DeathSounds[GetRandomInt(0, sizeof(g_DeathSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + public void PlayRangeSound() + { + EmitSoundToAll(g_RangeAttackSounds[GetRandomInt(0, sizeof(g_RangeAttackSounds) - 1)], this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 85); + } + + public Chemical_Specialist(float vecPos[3], float vecAng[3], int ally) + { + Chemical_Specialist npc = view_as(CClotBody(vecPos, vecAng, "models/player/engineer.mdl", "1.0", "7500", ally)); + + i_NpcWeight[npc.index] = 2; + FormatEx(c_HeadPlaceAttachmentGibName[npc.index], sizeof(c_HeadPlaceAttachmentGibName[]), "head"); + + int iActivity = npc.LookupActivity("ACT_MP_RUN_SECONDARY"); + if(iActivity > 0) npc.StartActivity(iActivity); + + SetVariantInt(3); + AcceptEntityInput(npc.index, "SetBodyGroup"); + + npc.m_flRangedArmor = 0.9; + npc.m_flMeleeArmor = 0.7; + + npc.m_flNextMeleeAttack = 0.0; + + npc.m_iBleedType = BLEEDTYPE_NORMAL; + npc.m_iStepNoiseType = STEPSOUND_NORMAL; + npc.m_iNpcStepVariation = STEPTYPE_NORMAL; + + func_NPCDeath[npc.index] = Chemical_Specialist_NPCDeath; + func_NPCOnTakeDamage[npc.index] = Chemical_Specialist_OnTakeDamage; + func_NPCThink[npc.index] = Chemical_Specialist_ClotThink; + + //IDLE + KillFeed_SetKillIcon(npc.index, "panic_attack"); + npc.m_iState = 0; + npc.m_flGetClosestTargetTime = 0.0; + npc.StartPathing(); + npc.m_flSpeed = 230.0; + + int skin = 1; + SetEntProp(npc.index, Prop_Send, "m_nSkin", skin); + + npc.m_iWearable1 = npc.EquipItem("head", "models/workshop/weapons/c_models/c_pro_smg/c_pro_smg.mdl"); + npc.m_iWearable2 = npc.EquipItem("head", "models/workshop/weapons/c_models/c_uberneedle/c_uberneedle.mdl"); + SetEntProp(npc.m_iWearable2, Prop_Send, "m_nSkin", 1); + npc.m_iWearable3 = npc.EquipItem("head", "models/workshop/player/items/engineer/invasion_life_support_system/invasion_life_support_system.mdl"); + SetEntProp(npc.m_iWearable3, Prop_Send, "m_nSkin", 1); + npc.m_iWearable4 = npc.EquipItem("head", "models/workshop/player/items/engineer/hwn2024_mannhattan_protect/hwn2024_mannhattan_protect.mdl"); + SetEntProp(npc.m_iWearable4, Prop_Send, "m_nSkin", 1); + npc.m_iWearable5 = npc.EquipItem("head", "models/workshop/player/items/engineer/hwn2024_nuclear_necessity/hwn2024_nuclear_necessity.mdl"); + SetEntProp(npc.m_iWearable5, Prop_Send, "m_nSkin", 1); + npc.m_iWearable6 = npc.EquipItem("head", "models/workshop/player/items/engineer/hwn2024_contaminated_carryall/hwn2024_contaminated_carryall.mdl"); + SetEntProp(npc.m_iWearable6, Prop_Send, "m_nSkin", 1); + + return npc; + } +} + +static void Chemical_Specialist_ClotThink(int iNPC) +{ + Chemical_Specialist npc = view_as(iNPC); + if(npc.m_flNextDelayTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextDelayTime = GetGameTime(npc.index) + DEFAULT_UPDATE_DELAY_FLOAT; + npc.Update(); + + if(npc.m_bAllowBackWalking) + { + if(IsValidEnemy(npc.index, npc.m_iTarget)) + { + float WorldSpaceVec[3]; WorldSpaceCenter(npc.m_iTarget, WorldSpaceVec); + npc.FaceTowards(WorldSpaceVec, 150.0); + } + } + + if(npc.m_blPlayHurtAnimation) + { + npc.AddGesture("ACT_MP_GESTURE_FLINCH_CHEST", false); + npc.m_blPlayHurtAnimation = false; + npc.PlayHurtSound(); + } + + if(npc.m_flNextThinkTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextThinkTime = GetGameTime(npc.index) + 0.1; + + if(npc.m_flGetClosestTargetTime < GetGameTime(npc.index)) + { + npc.m_iTarget = GetClosestTarget(npc.index); + npc.m_flGetClosestTargetTime = GetGameTime(npc.index) + GetRandomRetargetTime(); + } + + Elemental_ClearDamage(npc.index); + + if(IsValidEnemy(npc.index, npc.m_iTarget)) + { + float vecTarget[3]; WorldSpaceCenter(npc.m_iTarget, vecTarget ); + + float VecSelfNpc[3]; WorldSpaceCenter(npc.index, VecSelfNpc); + float flDistanceToTarget = GetVectorDistance(vecTarget, VecSelfNpc, true); + switch(Chemical_SpecialistSelfDefense(npc,GetGameTime(npc.index), npc.m_iTarget, flDistanceToTarget)) + { + case 0: + { + npc.m_bAllowBackWalking = false; + //Get the normal prediction code. + if(flDistanceToTarget < npc.GetLeadRadius()) + { + float vPredictedPos[3]; + PredictSubjectPosition(npc, npc.m_iTarget,_,_, vPredictedPos); + npc.SetGoalVector(vPredictedPos); + } + else + { + npc.SetGoalEntity(npc.m_iTarget); + } + } + case 1: + { + npc.m_bAllowBackWalking = true; + float vBackoffPos[3]; + BackoffFromOwnPositionAndAwayFromEnemy(npc, npc.m_iTarget,_,vBackoffPos); + npc.SetGoalVector(vBackoffPos, true); //update more often, we need it + } + } + } + else + { + npc.m_flGetClosestTargetTime = 0.0; + npc.m_iTarget = GetClosestTarget(npc.index); + } + npc.PlayIdleAlertSound(); +} + +static Action Chemical_Specialist_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + Chemical_Specialist npc = view_as(victim); + + if(attacker <= 0) + return Plugin_Continue; + + if (npc.m_flHeadshotCooldown < GetGameTime(npc.index)) + { + npc.m_flHeadshotCooldown = GetGameTime(npc.index) + DEFAULT_HURTDELAY; + npc.m_blPlayHurtAnimation = true; + } + + return Plugin_Changed; +} + +static void Chemical_Specialist_NPCDeath(int entity) +{ + Chemical_Specialist npc = view_as(entity); + if(!npc.m_bGib) + npc.PlayDeathSound(); + + if(IsValidEntity(npc.m_iWearable6)) + RemoveEntity(npc.m_iWearable6); + if(IsValidEntity(npc.m_iWearable5)) + RemoveEntity(npc.m_iWearable5); + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + if(IsValidEntity(npc.m_iWearable3)) + RemoveEntity(npc.m_iWearable3); + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); +} + +static int Chemical_SpecialistSelfDefense(Chemical_Specialist npc, float gameTime, int target, float distance) +{ + if(gameTime > npc.m_flNextMeleeAttack) + { + if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 2.5)) + { + int Enemy_I_See = Can_I_See_Enemy(npc.index, target); + if(IsValidEnemy(npc.index, Enemy_I_See)) + { + npc.AddGesture("ACT_MP_ATTACK_STAND_SECONDARY"); + npc.m_iTarget = Enemy_I_See; + npc.PlayRangeSound(); + float vecTarget[3]; WorldSpaceCenter(target, vecTarget); + npc.FaceTowards(vecTarget, 20000.0); + Handle swingTrace; + if(npc.DoSwingTrace(swingTrace, target, { 9999.0, 9999.0, 9999.0 })) + { + target = TR_GetEntityIndex(swingTrace); + + float vecHit[3]; + TR_GetEndPosition(vecHit, swingTrace); + float origin[3], angles[3]; + view_as(npc.index).GetAttachment("effect_hand_r", origin, angles); + ShootLaser(npc.index, "bullet_tracer02_blue", origin, vecHit, false ); + npc.m_flNextMeleeAttack = gameTime + 0.5; + + if(IsValidEnemy(npc.index, target)) + { + float damageDealt = 35.0; + if(ShouldNpcDealBonusDamage(target)) + damageDealt *= 3.0; + int ElementalDamge = 25; + if(NpcStats_VictorianCallToArms(npc.index)) + ElementalDamge *= 2; + Elemental_AddNervousDamage(target, npc.index, ElementalDamge); + + SDKHooks_TakeDamage(target, npc.index, npc.index, damageDealt, DMG_BULLET, -1, _, vecHit); + } + } + delete swingTrace; + } + if(distance > (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 3.5)) + { + //target is too far, try to close in + return 0; + } + else if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 1.5)) + { + if(Can_I_See_Enemy_Only(npc.index, target)) + { + //target is too close, try to keep distance + return 1; + } + } + return 0; + } + else + { + if(distance > (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 3.5)) + { + //target is too far, try to close in + return 0; + } + else if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 1.5)) + { + if(Can_I_See_Enemy_Only(npc.index, target)) + { + //target is too close, try to keep distance + return 1; + } + } + } + } + else + { + if(distance > (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 3.5)) + { + //target is too far, try to close in + return 0; + } + else if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 1.5)) + { + if(Can_I_See_Enemy_Only(npc.index, target)) + { + //target is too close, try to keep distance + return 1; + } + } + } + return 0; +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_chemical_spreader.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_chemical_spreader.sp new file mode 100644 index 0000000000..0d2eec1fe2 --- /dev/null +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_chemical_spreader.sp @@ -0,0 +1,341 @@ +#pragma semicolon 1 +#pragma newdecls required + + +static const char g_DeathSounds[][] = { + "vo/pyro_paincrticialdeath01.mp3", + "vo/pyro_paincrticialdeath02.mp3", + "vo/pyro_paincrticialdeath03.mp3", +}; + +static const char g_HurtSounds[][] = { + "vo/pyro_painsharp01.mp3", + "vo/pyro_painsharp02.mp3", + "vo/pyro_painsharp03.mp3", + "vo/pyro_painsharp04.mp3", + "vo/pyro_painsharp05.mp3", +}; +static const char g_IdleAlertedSounds[][] = { + "vo/taunts/pyro_taunts01.mp3", + "vo/taunts/pyro_taunts02.mp3", + "vo/taunts/pyro_taunts03.mp3", +}; + + +void ChemicalSpreader_OnMapStart_NPC() +{ + for (int i = 0; i < (sizeof(g_DeathSounds)); i++) { PrecacheSound(g_DeathSounds[i]); } + for (int i = 0; i < (sizeof(g_HurtSounds)); i++) { PrecacheSound(g_HurtSounds[i]); } + for (int i = 0; i < (sizeof(g_IdleAlertedSounds)); i++) { PrecacheSound(g_IdleAlertedSounds[i]); } + PrecacheSound("weapons/flame_thrower_loop.wav"); + PrecacheSound("weapons/flame_thrower_pilot.wav"); + NPCData data; + strcopy(data.Name, sizeof(data.Name), "Chemical Spreader"); + strcopy(data.Plugin, sizeof(data.Plugin), "npc_chemical_spreader"); + strcopy(data.Icon, sizeof(data.Icon), "victoria_pulverizer"); + data.IconCustom = true; + data.Flags = 0; + data.Category = Type_Victoria; + data.Func = ClotSummon; + int id = NPC_Add(data); + Rogue_Paradox_AddWinterNPC(id); +} + +static any ClotSummon(int client, float vecPos[3], float vecAng[3], int team) +{ + return ChemicalSpreader(vecPos, vecAng, team); +} + +methodmap ChemicalSpreader < CClotBody +{ + + property int i_GunMode + { + public get() { return i_TimesSummoned[this.index]; } + public set(int TempValueForProperty) { i_TimesSummoned[this.index] = TempValueForProperty; } + } + public void PlayIdleAlertSound() + { + if(this.m_flNextIdleSound > GetGameTime(this.index)) + return; + + EmitSoundToAll(g_IdleAlertedSounds[GetRandomInt(0, sizeof(g_IdleAlertedSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + this.m_flNextIdleSound = GetGameTime(this.index) + GetRandomFloat(12.0, 24.0); + + } + + public void PlayHurtSound() + { + if(this.m_flNextHurtSound > GetGameTime(this.index)) + return; + + this.m_flNextHurtSound = GetGameTime(this.index) + 0.4; + + EmitSoundToAll(g_HurtSounds[GetRandomInt(0, sizeof(g_HurtSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + + } + + property float m_flPulveriserAttackDelay + { + public get() { return fl_AbilityOrAttack[this.index][1]; } + public set(float TempValueForProperty) { fl_AbilityOrAttack[this.index][1] = TempValueForProperty; } + } + public void PlayDeathSound() + { + EmitSoundToAll(g_DeathSounds[GetRandomInt(0, sizeof(g_DeathSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + public void PlayMinigunSound(bool Shooting) + { + if(Shooting) + { + if(this.i_GunMode != 0) + { + StopSound(this.index, SNDCHAN_STATIC, "weapons/flame_thrower_pilot.wav"); + EmitSoundToAll("weapons/flame_thrower_loop.wav", this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, 1.20); + } + this.i_GunMode = 0; + } + else + { + if(this.i_GunMode != 1) + { + StopSound(this.index, SNDCHAN_STATIC, "weapons/flame_thrower_loop.wav"); + EmitSoundToAll("weapons/flame_thrower_pilot.wav", this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, 1.20); + } + this.i_GunMode = 1; + } + } + + public ChemicalSpreader(float vecPos[3], float vecAng[3], int ally) + { + ChemicalSpreader npc = view_as(CClotBody(vecPos, vecAng, "models/player/pyro.mdl", "1.0", "3000", ally)); + + i_NpcWeight[npc.index] = 1; + FormatEx(c_HeadPlaceAttachmentGibName[npc.index], sizeof(c_HeadPlaceAttachmentGibName[]), "head"); + + int iActivity = npc.LookupActivity("ACT_MP_RUN_PRIMARY"); + if(iActivity > 0) npc.StartActivity(iActivity); + + SetVariantInt(0); + AcceptEntityInput(npc.index, "SetBodyGroup"); + + npc.m_flNextMeleeAttack = 0.0; + + npc.m_iBleedType = BLEEDTYPE_NORMAL; + npc.m_iStepNoiseType = STEPSOUND_NORMAL; + npc.m_iNpcStepVariation = STEPTYPE_NORMAL; + + func_NPCDeath[npc.index] = view_as(ChemicalSpreader_NPCDeath); + func_NPCOnTakeDamage[npc.index] = view_as(ChemicalSpreader_OnTakeDamage); + func_NPCThink[npc.index] = view_as(ChemicalSpreader_ClotThink); + + + + npc.StartPathing(); + npc.m_flSpeed = 280.0; + + + int skin = 1; + SetEntProp(npc.index, Prop_Send, "m_nSkin", skin); + + npc.m_iWearable1 = npc.EquipItem("head", "models/weapons/c_models/c_drg_phlogistinator/c_drg_phlogistinator.mdl"); + npc.m_iWearable2 = npc.EquipItem("head", "models/player/items/pyro/drg_pyro_fueltank.mdl"); + npc.m_iWearable3 = npc.EquipItem("head", "models/workshop/player/items/all_class/dec15_patriot_peak/dec15_patriot_peak_pyro.mdl"); + npc.m_iWearable4 = npc.EquipItem("head", "models/workshop/player/items/pyro/spr18_hot_case/spr18_hot_case.mdl"); + npc.m_iWearable5 = npc.EquipItem("head", "models/workshop/player/items/pyro/dec25_veterans_visor/dec25_veterans_visor.mdl"); + + SetEntProp(npc.m_iWearable1, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable2, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable3, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable4, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable5, Prop_Send, "m_nSkin", skin); + + SetVariantString("1.5"); + AcceptEntityInput(npc.m_iWearable1, "SetModelScale"); + SetVariantString("2.0"); + AcceptEntityInput(npc.m_iWearable2, "SetModelScale"); + + NpcColourCosmetic_ViaPaint(npc.m_iWearable3, 6637376); + NpcColourCosmetic_ViaPaint(npc.m_iWearable4, 1581885); + NpcColourCosmetic_ViaPaint(npc.m_iWearable5, 15787660); + + return npc; + } +} + +public void ChemicalSpreader_ClotThink(int iNPC) +{ + ChemicalSpreader npc = view_as(iNPC); + if(npc.m_flNextDelayTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextDelayTime = GetGameTime(npc.index) + DEFAULT_UPDATE_DELAY_FLOAT; + npc.Update(); + + if(npc.m_blPlayHurtAnimation) + { + npc.AddGesture("ACT_MP_GESTURE_FLINCH_CHEST", false); + npc.m_blPlayHurtAnimation = false; + npc.PlayHurtSound(); + } + + if(npc.m_flNextThinkTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextThinkTime = GetGameTime(npc.index) + 0.1; + + if(npc.m_flGetClosestTargetTime < GetGameTime(npc.index)) + { + npc.m_iTarget = GetClosestTarget(npc.index); + npc.m_flGetClosestTargetTime = GetGameTime(npc.index) + GetRandomRetargetTime(); + } + + if(IsValidEnemy(npc.index, npc.m_iTarget)) + { + float vecTarget[3]; WorldSpaceCenter(npc.m_iTarget, vecTarget ); + + float VecSelfNpc[3]; WorldSpaceCenter(npc.index, VecSelfNpc); + float flDistanceToTarget = GetVectorDistance(vecTarget, VecSelfNpc, true); + if(flDistanceToTarget < npc.GetLeadRadius()) + { + float vPredictedPos[3]; + PredictSubjectPosition(npc, npc.m_iTarget,_,_, vPredictedPos); + npc.SetGoalVector(vPredictedPos); + } + else + { + npc.SetGoalEntity(npc.m_iTarget); + } + ChemicalSpreaderSelfDefense(npc); + } + else + { + npc.PlayMinigunSound(false); + npc.m_flGetClosestTargetTime = 0.0; + npc.m_iTarget = GetClosestTarget(npc.index); + } + npc.PlayIdleAlertSound(); +} + +public Action ChemicalSpreader_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + ChemicalSpreader npc = view_as(victim); + + if(attacker <= 0) + return Plugin_Continue; + + if (npc.m_flHeadshotCooldown < GetGameTime(npc.index)) + { + npc.m_flHeadshotCooldown = GetGameTime(npc.index) + DEFAULT_HURTDELAY; + npc.m_blPlayHurtAnimation = true; + } + + return Plugin_Changed; +} + +public void ChemicalSpreader_NPCDeath(int entity) +{ + ChemicalSpreader npc = view_as(entity); + if(!npc.m_bGib) + { + npc.PlayDeathSound(); + } + + StopSound(npc.index, SNDCHAN_STATIC, "weapons/flame_thrower_loop.wav"); + StopSound(npc.index, SNDCHAN_STATIC, "weapons/flame_thrower_pilot.wav"); + StopSound(npc.index, SNDCHAN_STATIC, "weapons/flame_thrower_loop.wav"); + StopSound(npc.index, SNDCHAN_STATIC, "weapons/flame_thrower_pilot.wav"); + + if(IsValidEntity(npc.m_iWearable5)) + RemoveEntity(npc.m_iWearable5); + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + if(IsValidEntity(npc.m_iWearable3)) + RemoveEntity(npc.m_iWearable3); + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); + +} + +void ChemicalSpreaderSelfDefense(ChemicalSpreader npc) +{ + if(npc.m_flPulveriserAttackDelay > GetGameTime(npc.index)) + { + return; + } + npc.m_flPulveriserAttackDelay = GetGameTime(npc.index) + 0.2; + int target; + target = npc.m_iTarget; + //some Ranged units will behave differently. + //not this one. + float vecTarget[3]; WorldSpaceCenter(target, vecTarget); + bool SpinSound = true; + float VecSelfNpc[3]; WorldSpaceCenter(npc.index, VecSelfNpc); + float flDistanceToTarget = GetVectorDistance(vecTarget, VecSelfNpc, true); + if(flDistanceToTarget < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 5.0)) + { + npc.PlayMinigunSound(true); + SpinSound = false; + npc.FaceTowards(vecTarget, 20000.0); + int projectile = npc.FireParticleRocket(vecTarget, 8.0, 1000.0, 150.0, "unusual_icetornado_blue_parent", true); + SDKUnhook(projectile, SDKHook_StartTouch, Rocket_Particle_StartTouch); + int particle = EntRefToEntIndex(i_WandParticle[projectile]); + CreateTimer(0.5, Timer_RemoveEntity, EntIndexToEntRef(projectile), TIMER_FLAG_NO_MAPCHANGE); + CreateTimer(0.5, Timer_RemoveEntity, EntIndexToEntRef(particle), TIMER_FLAG_NO_MAPCHANGE); + + SDKHook(projectile, SDKHook_StartTouch, ChemicalSpreader_Rocket_Particle_StartTouch); + } + if(SpinSound) + npc.PlayMinigunSound(false); +} + + + +public void ChemicalSpreader_Rocket_Particle_StartTouch(int entity, int target) +{ + if(target > 0 && target < MAXENTITIES) //did we hit something??? + { + int owner = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity"); + if(!IsValidEntity(owner)) + { + owner = 0; + } + + int inflictor = h_ArrowInflictorRef[entity]; + if(inflictor != -1) + inflictor = EntRefToEntIndex(h_ArrowInflictorRef[entity]); + + if(inflictor == -1) + inflictor = owner; + + float ProjectileLoc[3]; + GetEntPropVector(entity, Prop_Data, "m_vecAbsOrigin", ProjectileLoc); + float DamageDeal = fl_rocket_particle_dmg[entity]; + if(ShouldNpcDealBonusDamage(target)) + DamageDeal *= h_BonusDmgToSpecialArrow[entity]; + + + SDKHooks_TakeDamage(target, owner, inflictor, DamageDeal, DMG_BULLET|DMG_PREVENT_PHYSICS_FORCE, -1); //acts like a kinetic rocket + + Elemental_AddNervousDamage(target, owner, 25, true); + int particle = EntRefToEntIndex(i_WandParticle[entity]); + if(IsValidEntity(particle)) + { + RemoveEntity(particle); + } + } + else + { + int particle = EntRefToEntIndex(i_WandParticle[entity]); + //we uhh, missed? + if(IsValidEntity(particle)) + { + RemoveEntity(particle); + } + } + RemoveEntity(entity); +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_demolitionist.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_demolitionist.sp new file mode 100644 index 0000000000..0119c91680 --- /dev/null +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_demolitionist.sp @@ -0,0 +1,330 @@ +#pragma semicolon 1 +#pragma newdecls required + +static const char g_DeathSounds[][] = { + "vo/heavy_negativevocalization01.mp3", + "vo/heavy_negativevocalization02.mp3", + "vo/heavy_negativevocalization03.mp3" +}; + +static const char g_HurtSounds[][] = { + "vo/heavy_cartmovingforwardoffense14.mp3", +}; + +static const char g_IdleAlertedSounds[][] = { + "vo/heavy_specialcompleted03.mp3", + "vo/heavy_specialcompleted02.mp3", + "vo/taunts/heavy_taunts13.mp3", + "vo/taunts/heavy_taunts17.mp3", +}; + +static const char g_MeleeAttackSounds[][] = { + "weapons/demo_sword_swing1.wav", + "weapons/demo_sword_swing2.wav", + "weapons/demo_sword_swing3.wav" +}; + +static const char g_MeleeHitSounds[] = "weapons/bat_baseball_hit_flesh.wav"; + +static const char g_ExplosionSounds[] = "weapons/explode1.wav"; + + +void Demolitionist_OnMapStart_NPC() +{ + NPCData data; + strcopy(data.Name, sizeof(data.Name), "Demolitionist"); + strcopy(data.Plugin, sizeof(data.Plugin), "npc_demolitionist"); + strcopy(data.Icon, sizeof(data.Icon), "victoria_bulldozer"); + data.IconCustom = true; + data.Flags = 0; + data.Category = Type_Victoria; + data.Precache = ClotPrecache; + data.Func = ClotSummon; + NPC_Add(data); +} + +static void ClotPrecache() +{ + PrecacheSoundArray(g_DeathSounds); + PrecacheSoundArray(g_HurtSounds); + PrecacheSoundArray(g_IdleAlertedSounds); + PrecacheSoundArray(g_MeleeAttackSounds); + PrecacheSound(g_MeleeHitSounds); + PrecacheModel("models/player/heavy.mdl"); +} + +static any ClotSummon(int client, float vecPos[3], float vecAng[3], int ally) +{ + return Demolitionist(vecPos, vecAng, ally); +} + +methodmap Demolitionist < CClotBody +{ + public void PlayIdleAlertSound() + { + if(this.m_flNextIdleSound > GetGameTime(this.index)) + return; + + EmitSoundToAll(g_IdleAlertedSounds[GetRandomInt(0, sizeof(g_IdleAlertedSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 80); + this.m_flNextIdleSound = GetGameTime(this.index) + GetRandomFloat(12.0, 24.0); + } + public void PlayHurtSound() + { + if(this.m_flNextHurtSound > GetGameTime(this.index)) + return; + + this.m_flNextHurtSound = GetGameTime(this.index) + 0.4; + + EmitSoundToAll(g_HurtSounds[GetRandomInt(0, sizeof(g_HurtSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 80); + } + public void PlayDeathSound() + { + EmitSoundToAll(g_DeathSounds[GetRandomInt(0, sizeof(g_DeathSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 80); + } + public void PlayMeleeSound() + { + EmitSoundToAll(g_MeleeAttackSounds[GetRandomInt(0, sizeof(g_MeleeAttackSounds) - 1)], this.index, SNDCHAN_AUTO, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 80); + } + public void PlayMeleeHitSound() + { + EmitSoundToAll(g_MeleeHitSounds, this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 90); + } + public void PlayExplosionSound() + { + EmitSoundToAll(g_ExplosionSounds, this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 80); + } + + + public Demolitionist(float vecPos[3], float vecAng[3], int ally) + { + Demolitionist npc = view_as(CClotBody(vecPos, vecAng, "models/player/heavy.mdl", "1.4", "12000", ally, .isGiant = true)); + + i_NpcWeight[npc.index] = 3; + FormatEx(c_HeadPlaceAttachmentGibName[npc.index], sizeof(c_HeadPlaceAttachmentGibName[]), "head"); + + int iActivity = npc.LookupActivity("ACT_MP_RUN_MELEE_ALLCLASS"); + if(iActivity > 0) npc.StartActivity(iActivity); + + func_NPCDeath[npc.index] = Demolitionist_NPCDeath; + func_NPCOnTakeDamage[npc.index] = Demolitionist_OnTakeDamage; + func_NPCThink[npc.index] = Demolitionist_ClotThink; + npc.m_flNextMeleeAttack = 0.0; + + npc.m_iBleedType = BLEEDTYPE_NORMAL; + npc.m_iStepNoiseType = STEPSOUND_NORMAL; + npc.m_iNpcStepVariation = STEPTYPE_NORMAL; + + SetVariantInt(4); + AcceptEntityInput(npc.index, "SetBodyGroup"); + + npc.m_flRangedArmor = 1.0; + npc.m_flMeleeArmor = 0.75; + + //IDLE + KillFeed_SetKillIcon(npc.index, "the_maul"); + npc.m_iState = 0; + npc.m_flGetClosestTargetTime = 0.0; + npc.StartPathing(); + npc.m_flSpeed = 150.0; + + int skin = 1; + SetEntProp(npc.index, Prop_Send, "m_nSkin", skin); + + npc.m_iWearable1 = npc.EquipItem("head", "models/workshop/weapons/c_models/c_powerjack/c_powerjack.mdl"); + SetVariantString("1.25"); + AcceptEntityInput(npc.m_iWearable1, "SetModelScale"); + + npc.m_iWearable2 = npc.EquipItem("head", "models/weapons/c_models/c_sr3_punch/c_sr3_punch.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable2, "SetModelScale"); + + npc.m_iWearable3 = npc.EquipItem("head", "models/workshop/player/items/heavy/sbox2014_leftover_trap/sbox2014_leftover_trap.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable3, "SetModelScale"); + + npc.m_iWearable4 = npc.EquipItem("head", "models/workshop/player/items/soldier/soldier_warpig/soldier_warpig.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable4, "SetModelScale"); + SetEntProp(npc.m_iWearable4, Prop_Send, "m_nSkin", skin); + + npc.m_iWearable5 = npc.EquipItem("head", "models/player/items/heavy/heavy_wolf_chest.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable5, "SetModelScale"); + SetEntProp(npc.m_iWearable5, Prop_Send, "m_nSkin", skin); + + npc.m_iWearable6 = npc.EquipItem("head", "models/workshop/player/items/heavy/dec25_punchers_polar_style3/dec25_punchers_polar_style3.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable5, "SetModelScale"); + SetEntProp(npc.m_iWearable6, Prop_Send, "m_nSkin", skin); + + return npc; + } +} + +static void Demolitionist_ClotThink(int iNPC) +{ + Demolitionist npc = view_as(iNPC); + if(npc.m_flNextDelayTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextDelayTime = GetGameTime(npc.index) + DEFAULT_UPDATE_DELAY_FLOAT; + npc.Update(); + + if(npc.m_blPlayHurtAnimation) + { + npc.AddGesture("ACT_MP_GESTURE_FLINCH_CHEST", false); + npc.m_blPlayHurtAnimation = false; + npc.PlayHurtSound(); + } + + if(npc.m_flNextThinkTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextThinkTime = GetGameTime(npc.index) + 0.1; + + if(npc.m_flGetClosestTargetTime < GetGameTime(npc.index)) + { + npc.m_iTarget = GetClosestTarget(npc.index); + npc.m_flGetClosestTargetTime = GetGameTime(npc.index) + GetRandomRetargetTime(); + } + + if(IsValidEnemy(npc.index, npc.m_iTarget)) + { + float vecTarget[3]; WorldSpaceCenter(npc.m_iTarget, vecTarget ); + + float VecSelfNpc[3]; WorldSpaceCenter(npc.index, VecSelfNpc); + float flDistanceToTarget = GetVectorDistance(vecTarget, VecSelfNpc, true); + if(flDistanceToTarget < npc.GetLeadRadius()) + { + float vPredictedPos[3]; + PredictSubjectPosition(npc, npc.m_iTarget,_,_, vPredictedPos); + npc.SetGoalVector(vPredictedPos); + } + else + { + npc.SetGoalEntity(npc.m_iTarget); + } + DemolitionistSelfDefense(npc,GetGameTime(npc.index), npc.m_iTarget, flDistanceToTarget); + } + else + { + npc.m_flGetClosestTargetTime = 0.0; + npc.m_iTarget = GetClosestTarget(npc.index); + } + npc.PlayIdleAlertSound(); +} + +static Action Demolitionist_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + Demolitionist npc = view_as(victim); + + if(attacker <= 0) + return Plugin_Continue; + + if (npc.m_flHeadshotCooldown < GetGameTime(npc.index)) + { + npc.m_flHeadshotCooldown = GetGameTime(npc.index) + DEFAULT_HURTDELAY; + npc.m_blPlayHurtAnimation = true; + } + return Plugin_Changed; +} + +static void Demolitionist_NPCDeath(int entity) +{ + Demolitionist npc = view_as(entity); + if(!npc.m_bGib) + { + npc.PlayDeathSound(); + } + + if(IsValidEntity(npc.m_iWearable6)) + RemoveEntity(npc.m_iWearable6); + if(IsValidEntity(npc.m_iWearable5)) + RemoveEntity(npc.m_iWearable5); + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + if(IsValidEntity(npc.m_iWearable3)) + RemoveEntity(npc.m_iWearable3); + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); + +} + +static void DemolitionistSelfDefense(Demolitionist npc, float gameTime, int target, float distance) +{ + if(npc.m_flAttackHappens) + { + if(npc.m_flAttackHappens < gameTime) + { + npc.m_flAttackHappens = 0.0; + Handle swingTrace; + float VecEnemy[3]; WorldSpaceCenter(npc.m_iTarget, VecEnemy); + npc.FaceTowards(VecEnemy, 15000.0); + if(npc.DoSwingTrace(swingTrace, npc.m_iTarget,_,_,_,1)) //Big range, but dont ignore buildings if somehow this doesnt count as a raid to be sure. + { + target = TR_GetEntityIndex(swingTrace); + + float vecHit[3]; + TR_GetEndPosition(vecHit, swingTrace); + + if(IsValidEnemy(npc.index, target)) + { + float damageDealt = 75.0; + if(ShouldNpcDealBonusDamage(target)) + damageDealt *= 8.0; + + SDKHooks_TakeDamage(target, npc.index, npc.index, damageDealt, DMG_CLUB, -1, _, vecHit); + Explode_Logic_Custom(40.0, -1, npc.index, -1, VecEnemy, 125.0, _, 0.75, true, _, false, _, Demolitionist_ExplodeHit); + ParticleEffectAt(VecEnemy, "ExplosionCore_buildings", 0.5); + + // Hit sound + npc.PlayMeleeHitSound(); + npc.PlayExplosionSound(); + } + } + delete swingTrace; + } + } + + if(gameTime > npc.m_flNextMeleeAttack) + { + if(distance < (GIANT_ENEMY_MELEE_RANGE_FLOAT_SQUARED)) + { + int Enemy_I_See; + Enemy_I_See = Can_I_See_Enemy(npc.index, npc.m_iTarget); + if(IsValidEnemy(npc.index, Enemy_I_See)) + { + npc.m_iTarget = Enemy_I_See; + npc.PlayMeleeSound(); + npc.AddGesture("ACT_MP_ATTACK_STAND_MELEE_ALLCLASS",_,_,_,0.5); + npc.m_flAttackHappens = gameTime + 0.45; + npc.m_flDoingAnimation = gameTime + 0.45; + npc.m_flNextMeleeAttack = gameTime + 1.5; + } + } + } +} + +static void Demolitionist_ExplodeHit(int entity, int victim, float damage, int weapon) +{ + float vecHit[3]; WorldSpaceCenter(victim, vecHit); + if(GetTeam(entity) != GetTeam(victim)) + { + int inflictor = h_ArrowInflictorRef[entity]; + if(inflictor != -1) + inflictor = EntRefToEntIndex(h_ArrowInflictorRef[entity]); + + if(inflictor == -1) + inflictor = entity; + damage = 200.0; + if(ShouldNpcDealBonusDamage(victim)) + damage *= 8.0; + if(NpcStats_VictorianCallToArms(entity)) + damage *= 2.0; + SDKHooks_TakeDamage(victim, entity, inflictor, damage, DMG_BLAST, -1, _, vecHit); + } +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_gasleader.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_gasleader.sp new file mode 100644 index 0000000000..e39610d183 --- /dev/null +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_gasleader.sp @@ -0,0 +1,770 @@ +#pragma semicolon 1 +#pragma newdecls required + +static char g_DeathSounds[][] = { + "npc/combine_soldier/die1.wav", + "npc/combine_soldier/die2.wav", + "npc/combine_soldier/die3.wav", +}; + +static char g_HurtSound[][] = { + "npc/combine_soldier/pain1.wav", + "npc/combine_soldier/pain2.wav", + "npc/combine_soldier/pain3.wav", +}; + +static const char g_IdleAlertedSounds[][] = { + "npc/combine_soldier/vo/alert1.wav", + "npc/combine_soldier/vo/bouncerbouncer.wav", + "npc/combine_soldier/vo/boomer.wav", + "npc/combine_soldier/vo/contactconfim.wav", +}; + +static const char g_MeleeHitSounds[][] = { + "weapons/blade_slice_2.wav", + "weapons/blade_slice_3.wav", + "weapons/blade_slice_4.wav", +}; + +static const char g_MegaMeleeHitSounds[][] = { + "items/cart_explode.wav", +}; + +static const char g_RangeAttackSounds[] = "weapons/pistol/pistol_fire2.wav"; + +static const char g_MeleeAttackSounds[] = "weapons/demo_sword_swing1.wav"; + +void Gasleader_OnMapStart_NPC() +{ + NPCData data; + strcopy(data.Name, sizeof(data.Name), "Victoria Gasleader"); + strcopy(data.Plugin, sizeof(data.Plugin), "npc_gasleader"); + strcopy(data.Icon, sizeof(data.Icon), "victoria_aviator"); + data.IconCustom = true; + data.Flags = 0; + data.Category = Type_Victoria; + data.Precache = ClotPrecache; + data.Func = ClotSummon; + NPC_Add(data); +} + +static void ClotPrecache() +{ + PrecacheSoundArray(g_DeathSounds); + PrecacheSoundArray(g_HurtSound); + PrecacheSoundArray(g_IdleAlertedSounds); + PrecacheSoundArray(g_MeleeHitSounds); + PrecacheSoundArray(g_MegaMeleeHitSounds); + PrecacheSound(g_RangeAttackSounds); + PrecacheSound(g_MeleeAttackSounds); + PrecacheModel(COMBINE_CUSTOM_MODEL); +} + +static any ClotSummon(int client, float vecPos[3], float vecAng[3], int team) +{ + return Gasleader(vecPos, vecAng, team); +} +methodmap Gasleader < CClotBody +{ + property int m_iAlliesDied + { + public get() { return i_OverlordComboAttack[this.index]; } + public set(int TempValueForProperty) { i_OverlordComboAttack[this.index] = TempValueForProperty; } + } + property int m_iAlliesMaxDeath + { + public get() { return i_TimesSummoned[this.index]; } + public set(int TempValueForProperty) { i_TimesSummoned[this.index] = TempValueForProperty; } + } + property float m_flPercentageAngry + { + public get() { return fl_Charge_delay[this.index]; } + public set(float TempValueForProperty) { fl_Charge_delay[this.index] = TempValueForProperty; } + } + public void PlayIdleAlertSound() + { + if(this.m_flNextIdleSound > GetGameTime(this.index)) + return; + + EmitSoundToAll(g_IdleAlertedSounds[GetRandomInt(0, sizeof(g_IdleAlertedSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + this.m_flNextIdleSound = GetGameTime(this.index) + GetRandomFloat(12.0, 24.0); + } + public void PlayHurtSound() + { + if(this.m_flNextHurtSound > GetGameTime(this.index)) + return; + + this.m_flNextHurtSound = GetGameTime(this.index) + 0.4; + + EmitSoundToAll(g_HurtSound[GetRandomInt(0, sizeof(g_HurtSound) - 1)], this.index, SNDCHAN_VOICE, BOSS_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME); + } + public void PlayDeathSound() + { + EmitSoundToAll(g_DeathSounds[GetRandomInt(0, sizeof(g_DeathSounds) - 1)], this.index, SNDCHAN_VOICE, BOSS_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME); + } + public void PlayMeleeSound() + { + EmitSoundToAll(g_MeleeAttackSounds, this.index, SNDCHAN_AUTO, BOSS_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME); + } + public void PlayRangedSound() { + EmitSoundToAll(g_RangeAttackSounds, this.index, _, BOSS_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME); + } + public void PlayMeleeHitSound() + { + EmitSoundToAll(g_MeleeHitSounds[GetRandomInt(0, sizeof(g_MeleeHitSounds) - 1)], this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME); + } + public void PlayMegaMeleeHitSound() + { + EmitSoundToAll(g_MegaMeleeHitSounds[GetRandomInt(0, sizeof(g_MegaMeleeHitSounds) - 1)], this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, BOSS_ZOMBIE_VOLUME, 80); + } + + property int i_GunMode + { + public get() { return i_TimesSummoned[this.index]; } + public set(int TempValueForProperty) { i_TimesSummoned[this.index] = TempValueForProperty; } + } + + public Gasleader(float vecPos[3], float vecAng[3], int ally) + { + Gasleader npc = view_as(CClotBody(vecPos, vecAng, COMBINE_CUSTOM_MODEL, "1.55", "50000", ally)); + + i_NpcWeight[npc.index] = 3; + FormatEx(c_HeadPlaceAttachmentGibName[npc.index], sizeof(c_HeadPlaceAttachmentGibName[]), "head"); + + SetVariantInt(3); + AcceptEntityInput(npc.index, "SetBodyGroup"); + + npc.SetActivity("ACT_CUSTOM_WALK_EAGLE"); + npc.m_iChanged_WalkCycle = 2; + + npc.m_flNextMeleeAttack = 0.0; + npc.m_flNextRangedAttack = 0.0; + + npc.m_iBleedType = BLEEDTYPE_NORMAL; + npc.m_iStepNoiseType = STEPSOUND_NORMAL; + npc.m_iNpcStepVariation = STEPTYPE_NORMAL; + + func_NPCDeath[npc.index] = view_as(Gasleader_NPCDeath); + func_NPCOnTakeDamage[npc.index] = view_as(Gasleader_OnTakeDamage); + func_NPCThink[npc.index] = view_as(Gasleader_ClotThink); + //func_NPCDeathForward[npc.index] = Gasleader_AllyDeath; + + npc.i_GunMode = 0; + + npc.StartPathing(); + npc.m_flSpeed = 250.0; + float MaxAlliesDeath = 50.0; + MaxAlliesDeath *= MultiGlobalEnemy; + npc.m_iAlliesMaxDeath = RoundToCeil(MaxAlliesDeath); + npc.m_flRangedSpecialDelay = GetGameTime(npc.index) + 0.5; + + npc.m_flPercentageAngry = 0.0; + npc.m_iAlliesDied = 0; + npc.Anger = false; + + if(!IsValidEntity(RaidBossActive)) + { + RaidModeScaling = 0.0; //just a safety net + RaidBossActive = EntIndexToEntRef(npc.index); + RaidModeTime = GetGameTime(npc.index) + 9000.0; + RaidAllowsBuildings = true; + } + + int skin = 1; + SetEntProp(npc.index, Prop_Send, "m_nSkin", skin); + + npc.m_iWearable1 = npc.EquipItem("weapon_bone", "models/weapons/w_pistol.mdl"); + SetVariantString("1.5"); + AcceptEntityInput(npc.m_iWearable1, "SetModelScale"); + + npc.m_iWearable2 = npc.EquipItem("thorns_backpack_1", "models/weapons/c_models/c_claymore/c_claymore_xmas.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable2, "SetModelScale"); + + npc.m_iWearable3 = npc.EquipItem("head", "models/workshop/player/items/engineer/hwn2024_contaminated_carryall/hwn2024_contaminated_carryall.mdl"); + SetVariantString("3.0"); + AcceptEntityInput(npc.m_iWearable3, "SetModelScale"); + + npc.m_iWearable4 = npc.EquipItem("head", "models/workshop/player/items/soldier/tw_soldierbot_armor/tw_soldierbot_armor.mdl"); + SetVariantString("1.33"); + AcceptEntityInput(npc.m_iWearable4, "SetModelScale"); + + npc.m_iWearable5 = npc.EquipItem("head","models/workshop/player/items/soldier/thief_soldier_helmet/thief_soldier_helmet.mdl"); + SetVariantString("1.25"); + AcceptEntityInput(npc.m_iWearable5, "SetModelScale"); + + npc.m_iWearable6 = ParticleEffectAt_Parent(vecPos, "utaunt_tarotcard_blue_glow", npc.index, "m_vecAbsOrigin", {0.0,0.0,0.0}); + + npc.m_iWearable9 = ParticleEffectAt_Parent(vecPos, "utaunt_poweraura_blue_beam", npc.index, "m_vecAbsOrigin", {0.0,0.0,0.0}); + + SetEntProp(npc.m_iWearable2, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable3, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable4, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable5, Prop_Send, "m_nSkin", skin); + + npc.m_iOverlordComboAttack = 0; + + + return npc; + } +} + +static void Gasleader_ClotThink(int iNPC) +{ + Gasleader npc = view_as(iNPC); + float gametime = GetGameTime(npc.index); + if(npc.m_flNextDelayTime > gametime) + return; + npc.m_flNextDelayTime = GetGameTime(npc.index) + DEFAULT_UPDATE_DELAY_FLOAT; + npc.Update(); + + if(npc.m_blPlayHurtAnimation) + { + npc.AddGesture("ACT_MP_GESTURE_FLINCH_CHEST", false); + npc.m_blPlayHurtAnimation = false; + npc.PlayHurtSound(); + } + + GrantEntityArmor(iNPC, true, 0.33, 0.5, 0); //50% res armor + + if(npc.Anger == false) + { + float vecMe[3]; WorldSpaceCenter(npc.index, vecMe); + float radius = 500.0; + GasleaderEffect(npc.index, radius); + if(gametime > npc.m_flRangedSpecialDelay) + { + Explode_Logic_Custom(10.0, -1, npc.index, -1, vecMe, radius, _, 0.75, true, _, false, _, Gasleader_ExplodePost); + npc.m_flRangedSpecialDelay = gametime + 0.5; + } + float VecI[3]; WorldSpaceCenter(npc.index, VecI); + for(int entitycount; entitycount gametime) + return; + npc.m_flNextThinkTime = gametime + 0.1; + + if(npc.m_flGetClosestTargetTime (victim); + + if(attacker <= 0) + return Plugin_Continue; + + if(npc.m_flArmorCount <= 0.0 && npc.Anger == false) + { + npc.Anger = true; + npc.m_iChanged_WalkCycle = 2; + if(IsValidEntity(npc.m_iWearable3)) + RemoveEntity(npc.m_iWearable3); + } + + if (npc.m_flHeadshotCooldown < GetGameTime(npc.index)) + { + npc.m_flHeadshotCooldown = GetGameTime(npc.index) + DEFAULT_HURTDELAY; + npc.m_blPlayHurtAnimation = true; + } + + return Plugin_Changed; +} + +static void Gasleader_NPCDeath(int entity) +{ + Gasleader npc = view_as(entity); + if(!npc.m_bGib) + npc.PlayDeathSound(); + + if(IsValidEntity(npc.m_iWearable9)) + RemoveEntity(npc.m_iWearable9); + if(IsValidEntity(npc.m_iWearable8)) + RemoveEntity(npc.m_iWearable8); + if(IsValidEntity(npc.m_iWearable7)) + RemoveEntity(npc.m_iWearable7); + if(IsValidEntity(npc.m_iWearable6)) + RemoveEntity(npc.m_iWearable6); + if(IsValidEntity(npc.m_iWearable5)) + RemoveEntity(npc.m_iWearable5); + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + if(IsValidEntity(npc.m_iWearable3)) + RemoveEntity(npc.m_iWearable3); + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); +} + +static int GasleaderSelfDefense(Gasleader npc, float gameTime, float distance) +{ + if(distance < NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED *3.0 || npc.m_flAttackHappenswillhappen) + { + if(npc.m_flNextMeleeAttack < gameTime) + { + if(!npc.m_flAttackHappenswillhappen) + { + if(npc.m_iOverlordComboAttack <= 2) + { + /* + switch(GetRandomInt(0,1)) + { + case 0: + { + npc.AddGesture("ACT_BLADEDANCE_ATTACK_LEFT"); + } + case 1: + { + npc.AddGesture("ACT_MILITIA_ATTACK"); + } + } + */ + npc.AddGesture("ACT_MILITIA_ATTACK"); + } + else + { + npc.AddGesture("ACT_SEABORN_ATTACK_TOOL_1"); + } + npc.PlayMeleeSound(); + npc.m_flAttackHappens = gameTime +0.25; + npc.m_flDoingAnimation = gameTime + 0.25; + npc.m_flAttackHappens_bullshit = gameTime + 0.35; + npc.m_flAttackHappenswillhappen = true; + } + if(npc.m_flAttackHappens < gameTime && npc.m_flAttackHappens_bullshit >= gameTime && npc.m_flAttackHappenswillhappen) + { + int HowManyEnemeisAoeMelee = 64; + Handle swingTrace; + float VecEnemy[3]; WorldSpaceCenter(npc.m_iTarget, VecEnemy); + npc.FaceTowards(VecEnemy, 20000.0); + npc.DoSwingTrace(swingTrace, npc.m_iTarget,_,_,_,1,_,HowManyEnemeisAoeMelee); + delete swingTrace; + for (int counter = 1; counter <= HowManyEnemeisAoeMelee; counter++) + { + if (i_EntitiesHitAoeSwing_NpcSwing[counter] > 0) + { + if(IsValidEntity(i_EntitiesHitAoeSwing_NpcSwing[counter])) + { + int target = i_EntitiesHitAoeSwing_NpcSwing[counter]; + float damageDealt = 115.0; + int ElementalDamage = 30; + if(NpcStats_VictorianCallToArms(npc.index)) + ElementalDamage *= 2; + if(ShouldNpcDealBonusDamage(target)) + damageDealt*=10.0; + if(npc.m_iOverlordComboAttack <= 2) + { + npc.m_iOverlordComboAttack++; + Elemental_AddNervousDamage(target, npc.index, ElementalDamage, true); + npc.PlayMeleeHitSound(); + npc.m_flNextMeleeAttack = gameTime + 0.65; + } + else + { + damageDealt *= 3.0; + npc.m_iOverlordComboAttack = 0; + ElementalDamage *= 3; + Elemental_AddNervousDamage(target, npc.index, ElementalDamage, true); + if(IsValidClient(target) && !HasSpecificBuff(target, "Fluid Movement")) + { + TF2_StunPlayer(target, 1.5, 0.5, TF_STUNFLAG_SLOWDOWN); + Client_Shake(target, 0, 25.0, 12.5, 1.5); + } + ParticleEffectAt(VecEnemy, "Explosion_ShockWave_01", 0.5); + npc.m_flNextMeleeAttack = gameTime + 1.0; + } + //damageDealt *= (npc.m_flPercentageAngry * 5.0) + 1.0; + float vecHit[3]; + WorldSpaceCenter(target, vecHit); + SDKHooks_TakeDamage(target, npc.index, npc.index, damageDealt, DMG_CLUB, -1, _, vecHit); + } + } + } + /* + int HowManyEnemeisAoeMelee = 64; + Handle swingTrace; + float vecTarget[3]; WorldSpaceCenter(npc.m_iTarget, vecTarget); + npc.FaceTowards(vecTarget, 20000.0); + if(npc.DoSwingTrace(swingTrace, npc.m_iTarget,_,_,_,1,_,HowManyEnemeisAoeMelee)) + { + for (int counter = 1; counter <= HowManyEnemeisAoeMelee; counter++) + { + int target = TR_GetEntityIndex(swingTrace); + float vecHit[3]; + TR_GetEndPosition(vecHit, swingTrace); + if(IsValidEnemy(npc.index, target)) + { + float damageDealt = 100.0; + int ElementalDamage = 30; + if(NpcStats_VictorianCallToArms(npc.index)) + ElementalDamage *= 2; + if(ShouldNpcDealBonusDamage(target)) + damageDealt*=10.0; + if(npc.m_iOverlordComboAttack <= 2) + { + npc.m_iOverlordComboAttack++; + Elemental_AddNervousDamage(target, npc.index, ElementalDamage, true); + npc.PlayMeleeHitSound(); + npc.m_flNextMeleeAttack = gameTime + 0.5; + } + else + { + damageDealt *= 3.0; + npc.m_iOverlordComboAttack = 0; + ElementalDamage *= 3.1; + Elemental_AddNervousDamage(target, npc.index, ElementalDamage, true); + if(IsValidClient(target) && !HasSpecificBuff(target, "Fluid Movement")) + { + TF2_StunPlayer(target, 1.5, 0.5, TF_STUNFLAG_SLOWDOWN); + Client_Shake(target, 0, 25.0, 12.5, 1.5); + } + npc.m_flNextMeleeAttack = gameTime + 1.0; + } + damageDealt *= (npc.m_flPercentageAngry * 5.0) + 1.0; + SDKHooks_TakeDamage(target, npc.index, npc.index, damageDealt, DMG_CLUB, -1, _, vecHit); + } + } + } + */ + npc.m_flAttackHappenswillhappen = false; + } + else if(npc.m_flAttackHappens_bullshit < gameTime && npc.m_flAttackHappenswillhappen) + { + npc.m_flAttackHappenswillhappen = false; + npc.m_flNextMeleeAttack = gameTime + 0.1; + } + } + return 2; + } + + + if(npc.m_flNextRangedAttack < gameTime) + { + if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 25.0)) + { + int Enemy_I_See = Can_I_See_Enemy(npc.index, npc.m_iTarget); + + if(IsValidEnemy(npc.index, Enemy_I_See)) + { + npc.AddGesture("ACT_DARIO_ATTACK_GUN_1"); + npc.m_iTarget = Enemy_I_See; + npc.PlayRangedSound(); + float vecTarget[3]; WorldSpaceCenter(npc.m_iTarget, vecTarget); + npc.FaceTowards(vecTarget, 30000.0); + Handle swingTrace; + if(npc.DoSwingTrace(swingTrace, npc.m_iTarget, { 9999.0, 9999.0, 9999.0 })) + { + int target = TR_GetEntityIndex(swingTrace); + + float vecHit[3]; + TR_GetEndPosition(vecHit, swingTrace); + float origin[3], angles[3]; + view_as(npc.m_iWearable1).GetAttachment("muzzle", origin, angles); + ShootLaser(npc.m_iWearable1, "bullet_tracer02_blue", origin, vecHit, false ); + + if(IsValidEnemy(npc.index, target)) + { + float damageDealt = 80.0; + if(ShouldNpcDealBonusDamage(target)) + damageDealt *= 10.0; + SDKHooks_TakeDamage(target, npc.index, npc.index, damageDealt, DMG_BULLET, -1, _, vecHit); + if(IsValidEnemy(npc.index, target)) + ApplyStatusEffect(npc.index, target, "Cripple", NpcStats_VictorianCallToArms(npc.index) ? 7.5 : 5.0); + + } + npc.m_flNextRangedAttack = gameTime + 1.0; + } + delete swingTrace; + } + if(distance > (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 8.0)) + return 0; + else if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 5.0)) + { + if(Can_I_See_Enemy_Only(npc.index, npc.m_iTarget)) + return 1; + } + return 0; + } + else + { + if(distance > (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 8.0)) + return 0; + else if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 5.0)) + { + if(Can_I_See_Enemy_Only(npc.index, npc.m_iTarget)) + return 1; + } + } + } + else + { + if(distance > (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 8.0)) + return 0; + else if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 5.0)) + { + if(Can_I_See_Enemy_Only(npc.index, npc.m_iTarget)) + return 1; + } + } + return 0; +} + +void GasleaderEffect(int entity, float range) +{ + float ProjectileLoc[3]; + GetEntPropVector(entity, Prop_Data, "m_vecAbsOrigin", ProjectileLoc); + spawnRing_Vectors(ProjectileLoc, range * 2.0, 0.0, 0.0, 10.0, "materials/sprites/laserbeam.vmt", 100, 150, 255, 175, 1, 0.1, 5.0, 0.1, 3); +} + +static void Gasleader_ExplodePost(int attacker, int victim, float damage, int weapon) +{ + Elemental_AddNervousDamage(victim, attacker, 3, true); +} + +/* +public void Gasleader_AllyDeath(int self, int ally) +{ + Gasleader npc = view_as(self); + + if(GetTeam(ally) != GetTeam(self)) + { + return; + } + + float AllyPos[3]; + GetEntPropVector(ally, Prop_Data, "m_vecAbsOrigin", AllyPos); + float SelfPos[3]; + GetEntPropVector(self, Prop_Data, "m_vecAbsOrigin", SelfPos); + float flDistanceToTarget = GetVectorDistance(SelfPos, AllyPos, true); + if(flDistanceToTarget < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 25.0)) + { + npc.m_iAlliesDied += 1; + + if(npc.m_iAlliesDied >= npc.m_iAlliesMaxDeath) + { + npc.m_flPercentageAngry = 1.0; + } + else + { + npc.m_flPercentageAngry = float(npc.m_iAlliesDied) / float(npc.m_iAlliesMaxDeath); + } + } + float flPos[3]; // original + float flAng[3]; // original + if(npc.m_flPercentageAngry == 1.0) + { + if(IsValidEntity(npc.m_iWearable7)) + { + RemoveEntity(npc.m_iWearable7); + } + if(!IsValidEntity(npc.m_iWearable7)) + { + npc.GetAttachment("m_vecAbsOrigin", flPos, flAng); + npc.m_iWearable7 = ParticleEffectAt_Parent(flPos, "utaunt_poweraura_red_beam", npc.index, "m_vecAbsOrigin", {0.0,0.0,0.0}); + } + } + else if(npc.m_flPercentageAngry > 0.5) + { + if(!IsValidEntity(npc.m_iWearable7)) + { + npc.GetAttachment("m_vecAbsOrigin", flPos, flAng); + + npc.m_iWearable7 = ParticleEffectAt_Parent(flPos, "utaunt_poweraura_blue_beam", npc.index, "m_vecAbsOrigin", {0.0,0.0,0.0}); + } + } +} +*/ \ No newline at end of file diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_giant_armored_medic.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_giant_armored_medic.sp new file mode 100644 index 0000000000..1baf14db7f --- /dev/null +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_giant_armored_medic.sp @@ -0,0 +1,375 @@ +#pragma semicolon 1 +#pragma newdecls required + + +static const char g_DeathSounds[][] = { + "vo/mvm/norm/medic_mvm_paincrticialdeath01.mp3", + "vo/mvm/norm/medic_mvm_paincrticialdeath02.mp3", + "vo/mvm/norm/medic_mvm_paincrticialdeath03.mp3" +}; + +static const char g_HurtSounds[][] = { + "vo/mvm/norm/medic_mvm_painsharp01.mp3", + "vo/mvm/norm/medic_mvm_painsharp02.mp3", + "vo/mvm/norm/medic_mvm_painsharp03.mp3", + "vo/mvm/norm/medic_mvm_painsharp04.mp3" +}; + +static const char g_IdleAlertedSounds[][] = { + "vo/mvm/norm/medic_mvm_battlecry01.mp3", + "vo/mvm/norm/medic_mvm_battlecry02.mp3", + "vo/mvm/norm/medic_mvm_battlecry03.mp3", + "vo/mvm/norm/medic_mvm_battlecry04.mp3" +}; + +void ArmoredMedic_OnMapStart_NPC() +{ + for (int i = 0; i < (sizeof(g_DeathSounds)); i++) { PrecacheSound(g_DeathSounds[i]); } + for (int i = 0; i < (sizeof(g_HurtSounds)); i++) { PrecacheSound(g_HurtSounds[i]); } + for (int i = 0; i < (sizeof(g_IdleAlertedSounds)); i++) { PrecacheSound(g_IdleAlertedSounds[i]); } + PrecacheModel(LASERBEAM); + NPCData data; + strcopy(data.Name, sizeof(data.Name), "Giant Armored Medibot"); + strcopy(data.Plugin, sizeof(data.Plugin), "npc_giant_armored_medic"); + strcopy(data.Icon, sizeof(data.Icon), "medic_uber"); + data.IconCustom = false; + data.Flags = MVM_CLASS_FLAG_MINIBOSS; + data.Category = Type_Expidonsa; + data.Precache = ClotPrecache; + data.Func = ClotSummon; + NPC_Add(data); +} + +static void ClotPrecache() +{ + PrecacheSoundArray(g_DeathSounds); + PrecacheSoundArray(g_HurtSounds); + PrecacheSoundArray(g_IdleAlertedSounds); + PrecacheModel("models/bots/medic/bot_medic.mdl"); + PrecacheModel(LASERBEAM); +} + +static any ClotSummon(int client, float vecPos[3], float vecAng[3], int team) +{ + return ArmoredMedic(vecPos, vecAng, team); +} + +methodmap ArmoredMedic < CClotBody +{ + public void PlayIdleAlertSound() { + if(this.m_flNextIdleSound > GetGameTime(this.index)) + return; + + EmitSoundToAll(g_IdleAlertedSounds[GetRandomInt(0, sizeof(g_IdleAlertedSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 80); + this.m_flNextIdleSound = GetGameTime(this.index) + GetRandomFloat(12.0, 24.0); + + + } + + public void PlayHurtSound() { + if(this.m_flNextHurtSound > GetGameTime(this.index)) + return; + + this.m_flNextHurtSound = GetGameTime(this.index) + 0.4; + + EmitSoundToAll(g_HurtSounds[GetRandomInt(0, sizeof(g_HurtSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 80); + + + + } + + public void PlayDeathSound() { + + EmitSoundToAll(g_DeathSounds[GetRandomInt(0, sizeof(g_DeathSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 80); + + + } + + public ArmoredMedic(float vecPos[3], float vecAng[3], int ally) + { + ArmoredMedic npc = view_as(CClotBody(vecPos, vecAng, "models/bots/medic/bot_medic.mdl", "1.35", "50000", ally, .isGiant = true)); + + i_NpcWeight[npc.index] = 3; + SetVariantInt(1); + AcceptEntityInput(npc.index, "SetBodyGroup"); + + FormatEx(c_HeadPlaceAttachmentGibName[npc.index], sizeof(c_HeadPlaceAttachmentGibName[]), "head"); + + int iActivity = npc.LookupActivity("ACT_MP_RUN_SECONDARY"); + if(iActivity > 0) npc.StartActivity(iActivity); + + + func_NPCDeath[npc.index] = ArmoredMedic_NPCDeath; + func_NPCOnTakeDamage[npc.index] = ArmoredMedic_OnTakeDamage; + func_NPCThink[npc.index] = ArmoredMedic_ClotThink; + npc.m_flNextMeleeAttack = 0.0; + + npc.m_iBleedType = BLEEDTYPE_METAL; + npc.m_iNpcStepVariation = 0; + + npc.m_flRangedArmor = 0.8; + npc.m_flMeleeArmor = 0.7; + + + //IDLE + npc.m_flSpeed = 150.0; + npc.m_iWearable5 = INVALID_ENT_REFERENCE; + Is_a_Medic[npc.index] = true; + + npc.m_bnew_target = false; + npc.StartPathing(); + + + int skin = 1; + SetEntProp(npc.index, Prop_Send, "m_nSkin", skin); + + ApplyStatusEffect(npc.index, npc.index, "Clear Head", 999999.0); + ApplyStatusEffect(npc.index, npc.index, "Solid Stance", 999999.0); + ApplyStatusEffect(npc.index, npc.index, "Fluid Movement", 999999.0); + + npc.m_iWearable1 = npc.EquipItem("head", "models/workshop/player/items/engineer/spr18_cold_case/spr18_cold_case.mdl"); + SetVariantString("1.75"); + AcceptEntityInput(npc.m_iWearable1, "SetModelScale"); + + SetEntProp(npc.m_iWearable1, Prop_Send, "m_nSkin", 1); + + npc.m_iWearable3 = npc.EquipItem("head", "models/weapons/c_models/c_proto_medigun/c_proto_medigun.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable3, "SetModelScale"); + + npc.m_iWearable2 = npc.EquipItem("head", "models/workshop/player/items/medic/robo_medic_physician_mask/robo_medic_physician_mask.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable2, "SetModelScale"); + + npc.m_iWearable6 = npc.EquipItem("head", "models/workshop/player/items/demo/sum20_hazard_headgear/sum20_hazard_headgear.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable6, "SetModelScale"); + + npc.m_iWearable7 = npc.EquipItem("head", "models/workshop/player/items/engineer/hwn2020_wavefinder/hwn2020_wavefinder.mdl"); + SetVariantString("1.0"); + AcceptEntityInput(npc.m_iWearable7, "SetModelScale"); + + SetEntProp(npc.m_iWearable3, Prop_Send, "m_nSkin", 1); + SetEntProp(npc.m_iWearable6, Prop_Send, "m_nSkin", 1); + SetEntProp(npc.m_iWearable7, Prop_Send, "m_nSkin", 1); + + NpcColourCosmetic_ViaPaint(npc.m_iWearable2, 15132390); + NpcColourCosmetic_ViaPaint(npc.m_iWearable6, 15132390); + NpcColourCosmetic_ViaPaint(npc.m_iWearable7, 15132390); + npc.StartPathing(); + + return npc; + } + public void StartHealing() + { + int im_iWearable3 = this.m_iWearable3; + if(im_iWearable3 != INVALID_ENT_REFERENCE) + { + this.Healing = true; + + // EmitSoundToAll("m_iWearable3s/medigun_heal.wav", this.index, SNDCHAN_m_iWearable3); + } + } + public void StopHealing() + { + int iBeam = this.m_iWearable5; + if(iBeam != INVALID_ENT_REFERENCE) + { + int iBeamTarget = GetEntPropEnt(iBeam, Prop_Send, "m_hOwnerEntity"); + if(IsValidEntity(iBeamTarget)) + { + AcceptEntityInput(iBeamTarget, "ClearParent"); + RemoveEntity(iBeamTarget); + } + + AcceptEntityInput(iBeam, "ClearParent"); + RemoveEntity(iBeam); + + EmitSoundToAll("weapons/medigun_no_target.wav", this.index, SNDCHAN_WEAPON); + + // StopSound(this.index, SNDCHAN_m_iWearable3, "m_iWearable3s/medigun_heal.wav"); + + this.Healing = false; + } + } +} + + +public void ArmoredMedic_ClotThink(int iNPC) +{ + ArmoredMedic npc = view_as(iNPC); + + if(npc.m_flNextDelayTime > GetGameTime(npc.index)) + { + return; + } + + npc.m_flNextDelayTime = GetGameTime(npc.index) + DEFAULT_UPDATE_DELAY_FLOAT; + + npc.Update(); + + if(npc.m_blPlayHurtAnimation) + { + npc.AddGesture("ACT_MP_GESTURE_FLINCH_CHEST", false); + npc.m_blPlayHurtAnimation = false; + npc.PlayHurtSound(); + } + + if(npc.m_flNextThinkTime > GetGameTime(npc.index)) + { + return; + } + + if(!IsValidAlly(npc.index, GetClosestAlly(npc.index))) + { + //there is no more valid ally, suicide. + SmiteNpcToDeath(npc.index); + return; + } + + npc.m_flNextThinkTime = GetGameTime(npc.index) + 0.1; + + if(npc.m_flGetClosestTargetTime < GetGameTime(npc.index)) + { + int OldAlly = npc.m_iTargetAlly; + npc.m_iTargetAlly = GetClosestAlly(npc.index,_,_,ArmoredMedic_HealCheck); + if(!IsValidAlly(npc.index, npc.m_iTargetAlly)) + npc.m_iTargetAlly = GetClosestAlly(npc.index); + + if(OldAlly != npc.m_iTargetAlly) + npc.m_bnew_target = false; + + npc.m_flGetClosestTargetTime = GetGameTime(npc.index) + 1.0; + } + + int PrimaryThreatIndex = npc.m_iTargetAlly; + if(IsValidAlly(npc.index, PrimaryThreatIndex)) + { + npc.SetGoalEntity(PrimaryThreatIndex); + float vecTarget[3]; WorldSpaceCenter(PrimaryThreatIndex, vecTarget); + + float VecSelfNpc[3]; WorldSpaceCenter(npc.index, VecSelfNpc); + float flDistanceToTarget = GetVectorDistance(vecTarget, VecSelfNpc, true); + + if(flDistanceToTarget < 400000 && Can_I_See_Enemy_Only(npc.index, PrimaryThreatIndex)) + { + if(flDistanceToTarget < 72500) + { + npc.StopPathing(); + } + else + { + npc.StartPathing(); + } + if(!npc.m_bnew_target) + { + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + npc.StartHealing(); + npc.m_iWearable4 = ConnectWithBeam(npc.m_iWearable3, PrimaryThreatIndex, 255, 215, 0, 3.0, 3.0, 1.35, LASERBEAM); + npc.Healing = true; + npc.m_bnew_target = true; + } + + if(IsValidEntity(npc.m_iWearable4)) + { + SetEntityRenderColor(npc.m_iWearable4, 255, 215, 0, 255); + } + int MaxHealth = ReturnEntityMaxHealth(PrimaryThreatIndex); + if(b_thisNpcIsABoss[PrimaryThreatIndex]) + MaxHealth = RoundToCeil(float(MaxHealth) * 0.00001); + + HealEntityGlobal(npc.index, PrimaryThreatIndex, float(MaxHealth), 1.0); + + ApplyStatusEffect(PrimaryThreatIndex, PrimaryThreatIndex, "Buffweiser", 1.1); + if(NpcStats_VictorianCallToArms(npc.index)) + { + ApplyStatusEffect(npc.index, PrimaryThreatIndex, "Taurine", 1.1); + } + float WorldSpaceVec[3]; WorldSpaceCenter(PrimaryThreatIndex, WorldSpaceVec); + npc.FaceTowards(WorldSpaceVec, 2000.0); + } + else + { + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + + npc.StartPathing(); + + npc.m_bnew_target = false; + } + } + else + { + //find new target to heal rapidly + npc.m_flGetClosestTargetTime = 0.0; + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + + npc.StartPathing(); + + npc.m_bnew_target = false; + } + + if(npc.m_flGetClosestTargetTime < GetGameTime(npc.index)) + { + npc.m_iTargetAlly = GetClosestAlly(npc.index,_,_,ArmoredMedic_HealCheck); + if(!IsValidAlly(npc.index, npc.m_iTargetAlly)) + npc.m_iTargetAlly = GetClosestAlly(npc.index); + npc.m_flGetClosestTargetTime = GetGameTime(npc.index) + 1.0; + } + npc.PlayIdleAlertSound(); +} + +public Action ArmoredMedic_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &m_iWearable3, float damageForce[3], float damagePosition[3], int damagecustom) +{ + ArmoredMedic npc = view_as(victim); + + if(attacker <= 0) + return Plugin_Continue; + + if (npc.m_flHeadshotCooldown < GetGameTime(npc.index)) + { + npc.m_flHeadshotCooldown = GetGameTime(npc.index) + DEFAULT_HURTDELAY; + npc.m_blPlayHurtAnimation = true; + } + + return Plugin_Changed; +} + +public void ArmoredMedic_NPCDeath(int entity) +{ + ArmoredMedic npc = view_as(entity); + if(!npc.m_bGib) + { + npc.PlayDeathSound(); + } + + Is_a_Medic[npc.index] = false; + if(IsValidEntity(npc.m_iWearable7)) + RemoveEntity(npc.m_iWearable7); + if(IsValidEntity(npc.m_iWearable6)) + RemoveEntity(npc.m_iWearable6); + if(IsValidEntity(npc.m_iWearable5)) + RemoveEntity(npc.m_iWearable5); + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + if(IsValidEntity(npc.m_iWearable3)) + RemoveEntity(npc.m_iWearable3); + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); + npc.StopHealing(); +} + +public bool ArmoredMedic_HealCheck(int provider, int entity) +{ + int MaxHealth = ReturnEntityMaxHealth(entity); + MaxHealth = RoundToNearest(float(MaxHealth) * 1.49); + int Health = GetEntProp(entity, Prop_Data, "m_iHealth"); + if(MaxHealth <= Health) + return false; + + return true; +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_headhunter.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_headhunter.sp new file mode 100644 index 0000000000..2f794f7c51 --- /dev/null +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_headhunter.sp @@ -0,0 +1,449 @@ +#pragma semicolon 1 +#pragma newdecls required + +static const char g_DeathSounds[][] = { + "vo/sniper_negativevocalization01.mp3", + "vo/sniper_negativevocalization02.mp3", + "vo/sniper_negativevocalization03.mp3", + "vo/sniper_negativevocalization04.mp3", + "vo/sniper_negativevocalization05.mp3", + "vo/sniper_negativevocalization06.mp3", + "vo/sniper_negativevocalization07.mp3", + "vo/sniper_negativevocalization08.mp3", + "vo/sniper_negativevocalization09.mp3" +}; + +static const char g_HurtSounds[][] = { + "vo/sniper_painsharp01.mp3", + "vo/sniper_painsharp02.mp3", + "vo/sniper_painsharp03.mp3", + "vo/sniper_painsharp04.mp3", +}; +static const char g_IdleAlertedSounds[][] = { + "vo/sniper_specialcompleted01.mp3", + "vo/sniper_specialcompleted02.mp3", + "vo/sniper_specialcompleted03.mp3", + "vo/sniper_specialcompleted04.mp3", + "vo/sniper_specialcompleted05.mp3", + "vo/sniper_specialcompleted06.mp3", + "vo/sniper_specialcompleted07.mp3", + "vo/sniper_specialcompleted08.mp3", + "vo/sniper_specialcompleted09.mp3", + "vo/sniper_specialcompleted10.mp3", + "vo/sniper_specialcompleted11.mp3", + "vo/sniper_specialcompleted12.mp3", + "vo/sniper_specialcompleted13.mp3", + "vo/sniper_specialcompleted14.mp3", + "vo/sniper_specialcompleted15.mp3", + "vo/sniper_specialcompleted16.mp3", + "vo/sniper_specialcompleted17.mp3", + "vo/sniper_specialcompleted18.mp3", + "vo/sniper_specialcompleted19.mp3", + "vo/sniper_specialcompleted20.mp3", + "vo/sniper_specialcompleted21.mp3", + "vo/sniper_specialcompleted22.mp3", + "vo/sniper_specialcompleted23.mp3", + "vo/sniper_specialcompleted24.mp3", + "vo/sniper_specialcompleted25.mp3", + "vo/sniper_specialcompleted26.mp3", + "vo/sniper_specialcompleted27.mp3", + "vo/sniper_specialcompleted28.mp3", + "vo/sniper_specialcompleted29.mp3", + "vo/sniper_specialcompleted30.mp3", + "vo/sniper_specialcompleted31.mp3", + "vo/sniper_specialcompleted32.mp3", + "vo/sniper_specialcompleted33.mp3", + "vo/sniper_specialcompleted34.mp3", + "vo/sniper_specialcompleted35.mp3", + "vo/sniper_specialcompleted36.mp3", + "vo/sniper_specialcompleted37.mp3", + "vo/sniper_specialcompleted38.mp3", + "vo/sniper_specialcompleted39.mp3", + "vo/sniper_specialcompleted40.mp3", + "vo/sniper_specialcompleted41.mp3", + "vo/sniper_specialcompleted42.mp3", + "vo/sniper_specialcompleted43.mp3", + "vo/sniper_specialcompleted44.mp3", + "vo/sniper_specialcompleted45.mp3", + "vo/sniper_specialcompleted46.mp3" +}; + +static const char g_MeleeAttackSounds[][] = { + "weapons/doom_sniper_rifle.wav", +}; + + +void Victorian_Headhunter_OnMapStart_NPC() +{ + for (int i = 0; i < (sizeof(g_DeathSounds)); i++) { PrecacheSound(g_DeathSounds[i]); } + for (int i = 0; i < (sizeof(g_HurtSounds)); i++) { PrecacheSound(g_HurtSounds[i]); } + for (int i = 0; i < (sizeof(g_IdleAlertedSounds)); i++) { PrecacheSound(g_IdleAlertedSounds[i]); } + for (int i = 0; i < (sizeof(g_MeleeAttackSounds)); i++) { PrecacheSound(g_MeleeAttackSounds[i]); } + PrecacheModel("models/player/medic.mdl"); + NPCData data; + strcopy(data.Name, sizeof(data.Name), "Victorian Headhunter"); + strcopy(data.Plugin, sizeof(data.Plugin), "npc_headhunter"); + strcopy(data.Icon, sizeof(data.Icon), "sniper_headshot"); + data.IconCustom = false; + data.Flags = MVM_CLASS_FLAG_SUPPORT; + data.Category = Type_Victoria; + data.Func = ClotSummon; + NPC_Add(data); +} + + +static any ClotSummon(int client, float vecPos[3], float vecAng[3], int team) +{ + return Victorian_Headhunter(vecPos, vecAng, team); +} + +methodmap Victorian_Headhunter < CClotBody +{ + public void PlayIdleAlertSound() + { + if(this.m_flNextIdleSound > GetGameTime(this.index)) + return; + + EmitSoundToAll(g_IdleAlertedSounds[GetRandomInt(0, sizeof(g_IdleAlertedSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + this.m_flNextIdleSound = GetGameTime(this.index) + GetRandomFloat(12.0, 24.0); + + } + + public void PlayHurtSound() + { + if(this.m_flNextHurtSound > GetGameTime(this.index)) + return; + + this.m_flNextHurtSound = GetGameTime(this.index) + 0.4; + + EmitSoundToAll(g_HurtSounds[GetRandomInt(0, sizeof(g_HurtSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + + } + + public void PlayDeathSound() + { + EmitSoundToAll(g_DeathSounds[GetRandomInt(0, sizeof(g_DeathSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + + public void PlayMeleeSound() + { + EmitSoundToAll(g_MeleeAttackSounds[GetRandomInt(0, sizeof(g_MeleeAttackSounds) - 1)], this.index, SNDCHAN_AUTO, 60, _, BOSS_ZOMBIE_VOLUME); + } + + public Victorian_Headhunter(float vecPos[3], float vecAng[3], int ally) + { + Victorian_Headhunter npc = view_as(CClotBody(vecPos, vecAng, "models/player/sniper.mdl", "1.0", "4000", ally)); + + i_NpcWeight[npc.index] = 1; + FormatEx(c_HeadPlaceAttachmentGibName[npc.index], sizeof(c_HeadPlaceAttachmentGibName[]), "head"); + + int iActivity = npc.LookupActivity("ACT_MP_RUN_PRIMARY"); + if(iActivity > 0) npc.StartActivity(iActivity); + + SetVariantInt(2); + AcceptEntityInput(npc.index, "SetBodyGroup"); + + func_NPCDeath[npc.index] = view_as(Victorian_Headhunter_NPCDeath); + func_NPCOnTakeDamage[npc.index] = view_as(Victorian_Headhunter_OnTakeDamage); + func_NPCThink[npc.index] = view_as(Victorian_Headhunter_ClotThink); + + npc.m_iChanged_WalkCycle = 0; + + if(npc.m_iChanged_WalkCycle != 1) + { + npc.m_bisWalking = true; + npc.m_iChanged_WalkCycle = 1; + npc.SetActivity("ACT_MP_RUN_PRIMARY"); + npc.StartPathing(); + npc.m_flSpeed = 200.0; + } + npc.m_flNextMeleeAttack = GetGameTime() + 1.0; + + npc.m_iBleedType = BLEEDTYPE_NORMAL; + npc.m_iStepNoiseType = STEPSOUND_NORMAL; + npc.m_iNpcStepVariation = STEPTYPE_NORMAL; + + + int skin = 1; + SetEntProp(npc.index, Prop_Send, "m_nSkin", skin); + + npc.m_iWearable1 = npc.EquipItem("head", "models/weapons/c_models/c_bazaar_sniper/c_bazaar_sniper.mdl"); + npc.m_iWearable2 = npc.EquipItem("head", "models/workshop/player/items/all_class/riflemans_rallycap/riflemans_rallycap_sniper.mdl"); + npc.m_iWearable3 = npc.EquipItem("head", "models/workshop/weapons/c_models/c_uberneedle/c_uberneedle.mdl"); + npc.m_iWearable4 = npc.EquipItem("head", "models/workshop/player/items/sniper/xms2013_sniper_beard/xms2013_sniper_beard.mdl"); + npc.m_iWearable5 = npc.EquipItem("head", "models/workshop/player/items/sniper/sum20_jarmaments/sum20_jarmaments.mdl"); + npc.m_iWearable6 = npc.EquipItem("head", "models/workshop/player/items/sniper/dec25_sydney_shearling/dec25_sydney_shearling.mdl"); + SetEntProp(npc.m_iWearable1, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable2, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable3, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable4, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable5, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable6, Prop_Send, "m_nSkin", skin); + + NpcColourCosmetic_ViaPaint(npc.m_iWearable2, 1581885); + NpcColourCosmetic_ViaPaint(npc.m_iWearable6, 8626083); + + + TeleportDiversioToRandLocation(npc.index,_,1750.0, 1250.0); + + return npc; + } +} + +public void Victorian_Headhunter_ClotThink(int iNPC) +{ + Victorian_Headhunter npc = view_as(iNPC); + if(npc.m_flNextDelayTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextDelayTime = GetGameTime(npc.index) + DEFAULT_UPDATE_DELAY_FLOAT; + npc.Update(); + + if(npc.m_blPlayHurtAnimation) + { + npc.AddGesture("ACT_MP_GESTURE_FLINCH_CHEST", false); + npc.m_blPlayHurtAnimation = false; + npc.PlayHurtSound(); + } + + if(npc.m_flNextThinkTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextThinkTime = GetGameTime(npc.index) + 0.1; + + if(npc.m_flGetClosestTargetTime < GetGameTime(npc.index)) + { + npc.m_iTargetWalkTo = GetClosestTarget(npc.index); + npc.m_flGetClosestTargetTime = GetGameTime(npc.index) + GetRandomRetargetTime(); + } + + if(IsValidEnemy(npc.index, npc.m_iTargetWalkTo)) + { + float vecTarget[3]; WorldSpaceCenter(npc.m_iTargetWalkTo, vecTarget); + + float VecSelfNpc[3]; WorldSpaceCenter(npc.index, VecSelfNpc); + float flDistanceToTarget = GetVectorDistance(vecTarget, VecSelfNpc, true); + int ExtraBehavior = Victorian_HeadhunterSelfDefense(npc,GetGameTime(npc.index)); + + switch(ExtraBehavior) + { + case 0: + { + if(npc.m_iChanged_WalkCycle != 1) + { + npc.m_bisWalking = true; + npc.m_iChanged_WalkCycle = 1; + npc.SetActivity("ACT_MP_RUN_PRIMARY"); + npc.StartPathing(); + npc.m_flSpeed = 200.0; + } + } + case 1: + { + if(npc.m_iChanged_WalkCycle != 2) + { + npc.m_bisWalking = false; + npc.m_iChanged_WalkCycle = 2; + npc.SetActivity("ACT_MP_CROUCH_DEPLOYED_IDLE"); + npc.StopPathing(); + npc.m_flSpeed = 0.0; + } + } + } + + if(flDistanceToTarget < npc.GetLeadRadius()) + { + float vPredictedPos[3]; + PredictSubjectPosition(npc, npc.m_iTargetWalkTo,_,_, vPredictedPos); + npc.SetGoalVector(vPredictedPos); + } + else + { + npc.SetGoalEntity(npc.m_iTargetWalkTo); + } + } + else + { + npc.m_flGetClosestTargetTime = 0.0; + npc.m_iTargetWalkTo = GetClosestTarget(npc.index); + } + npc.PlayIdleAlertSound(); +} + +public Action Victorian_Headhunter_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + Victorian_Headhunter npc = view_as(victim); + + if(attacker <= 0) + return Plugin_Continue; + + if (npc.m_flHeadshotCooldown < GetGameTime(npc.index)) + { + npc.m_flHeadshotCooldown = GetGameTime(npc.index) + DEFAULT_HURTDELAY; + npc.m_blPlayHurtAnimation = true; + } + + return Plugin_Changed; +} + +public void Victorian_Headhunter_NPCDeath(int entity) +{ + Victorian_Headhunter npc = view_as(entity); + if(!npc.m_bGib) + { + npc.PlayDeathSound(); + } + + if(IsValidEntity(npc.m_iWearable7)) + RemoveEntity(npc.m_iWearable7); + if(IsValidEntity(npc.m_iWearable6)) + RemoveEntity(npc.m_iWearable6); + if(IsValidEntity(npc.m_iWearable5)) + RemoveEntity(npc.m_iWearable5); + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + if(IsValidEntity(npc.m_iWearable3)) + RemoveEntity(npc.m_iWearable3); + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); + +} + +int Victorian_HeadhunterSelfDefense(Victorian_Headhunter npc, float gameTime) +{ + if(!npc.m_flAttackHappens) + { + if(IsValidEnemy(npc.index,npc.m_iTarget)) + { + if(!Can_I_See_Enemy_Only(npc.index, npc.m_iTarget)) + { + npc.m_iTarget = GetClosestTarget(npc.index,_,_,_,_,_,_,true,_,_,true); + } + } + else + { + npc.m_iTarget = GetClosestTarget(npc.index,_,_,_,_,_,_,true,_,_,true); + if(!IsValidEnemy(npc.index,npc.m_iTarget)) + { + return 0; + } + } + if(!IsValidEnemy(npc.index,npc.m_iTarget)) + { + return 0; + } + } + + float VecEnemy[3]; WorldSpaceCenter(npc.m_iTarget, VecEnemy); + npc.FaceTowards(VecEnemy, 15000.0); + + static float ThrowPos[MAXENTITIES][3]; + float origin[3], angles[3]; + view_as(npc.m_iWearable1).GetAttachment("muzzle", origin, angles); + if(npc.m_flDoingAnimation > gameTime) + { + if(Can_I_See_Enemy_Only(npc.index, npc.m_iTarget)) + { + WorldSpaceCenter(npc.m_iTarget, ThrowPos[npc.index]); + float pos_npc[3]; + WorldSpaceCenter(npc.index, pos_npc); + float AngleAim[3]; + GetVectorAnglesTwoPoints(pos_npc, ThrowPos[npc.index], AngleAim); + Handle hTrace = TR_TraceRayFilterEx(pos_npc, AngleAim, MASK_SOLID, RayType_Infinite, BulletAndMeleeTrace, npc.index); + if(TR_DidHit(hTrace)) + { + TR_GetEndPosition(ThrowPos[npc.index], hTrace); + } + delete hTrace; + } + } + else + { + if(npc.m_flAttackHappens) + { + float pos_npc[3]; + WorldSpaceCenter(npc.index, pos_npc); + float AngleAim[3]; + GetVectorAnglesTwoPoints(pos_npc, ThrowPos[npc.index], AngleAim); + Handle hTrace = TR_TraceRayFilterEx(pos_npc, AngleAim, MASK_SOLID, RayType_Infinite, BulletAndMeleeTrace, npc.index); + if(TR_DidHit(hTrace)) + { + TR_GetEndPosition(ThrowPos[npc.index], hTrace); + } + delete hTrace; + } + } + if(npc.m_flAttackHappens) + { + TE_SetupBeamPoints(origin, ThrowPos[npc.index], Shared_BEAM_Laser, 0, 0, 0, 0.11, 5.0, 5.0, 0, 0.0, {0,125,125,100}, 3); + TE_SendToAll(0.0); + } + + npc.FaceTowards(ThrowPos[npc.index], 15000.0); + if(npc.m_flAttackHappens) + { + if(npc.m_flAttackHappens < gameTime) + { + npc.m_flAttackHappens = 0.0; + ShootLaser(npc.m_iWearable1, "bullet_tracer02_blue_crit", origin, ThrowPos[npc.index], false ); + float pos_npc[3]; + WorldSpaceCenter(npc.index, pos_npc); + float AngleAim[3]; + GetVectorAnglesTwoPoints(pos_npc, ThrowPos[npc.index], AngleAim); + Handle hTrace = TR_TraceRayFilterEx(pos_npc, AngleAim, MASK_SOLID, RayType_Infinite, BulletAndMeleeTrace, npc.index); + int Traced_Target = TR_GetEntityIndex(hTrace); + if(Traced_Target > 0) + { + WorldSpaceCenter(Traced_Target, ThrowPos[npc.index]); + } + else if(TR_DidHit(hTrace)) + { + TR_GetEndPosition(ThrowPos[npc.index], hTrace); + } + delete hTrace; + + int target = Can_I_See_Enemy(npc.index, npc.m_iTarget,_ ,ThrowPos[npc.index]); + npc.PlayMeleeSound(); + npc.AddGesture("ACT_MP_ATTACK_CROUCH_PRIMARY_DEPLOYED"); + if(IsValidEnemy(npc.index, target)) + { + float damageDealt = 100.0; + int elementaldamage = 50; + if(ShouldNpcDealBonusDamage(target)) + damageDealt *= 5.0; + + int weapon = GetEntPropEnt(target, Prop_Send, "m_hActiveWeapon"); + switch(i_CustomWeaponEquipLogic[weapon]) + { + case WEAPON_BATTILONS,WEAPON_OCEAN,WEAPON_ANCIENT_BANNER,WEAPON_SEABORN_MISC,WEAPON_BUFF_BANNER,WEAPON_OCEAN_PAP,WEAPON_ZEALOT_POTION,WEAPON_BUFFPOTION,WEAPON_KRITZKRIEG: + { + damageDealt *= 2.0; + elementaldamage *= 2; + } + } + + SDKHooks_TakeDamage(target, npc.index, npc.index, damageDealt, DMG_BULLET, -1, _, ThrowPos[npc.index]); + Elemental_AddNervousDamage(target, npc.index, elementaldamage); + } + } + } + + if(gameTime > npc.m_flNextMeleeAttack) + { + if(NpcStats_VictorianCallToArms(npc.index)) + { + npc.m_flAttackHappens = gameTime + 0.65; + } + else if(!NpcStats_VictorianCallToArms(npc.index)) + { + npc.m_flAttackHappens = gameTime + 1.00; + } + npc.m_flDoingAnimation = gameTime + 0.95; + npc.m_flNextMeleeAttack = gameTime + 2.00; + } + return 1; +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_protector.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_protector.sp new file mode 100644 index 0000000000..08dd48bd42 --- /dev/null +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_protector.sp @@ -0,0 +1,374 @@ +#pragma semicolon 1 +#pragma newdecls required + +static const char g_DeathSounds[][] = { + "vo/engineer_paincrticialdeath01.mp3", + "vo/engineer_paincrticialdeath02.mp3", + "vo/engineer_paincrticialdeath03.mp3", +}; + +static const char g_HurtSounds[][] = { + "vo/engineer_painsharp01.mp3", + "vo/engineer_painsharp02.mp3", + "vo/engineer_painsharp03.mp3", + "vo/engineer_painsharp04.mp3", + "vo/engineer_painsharp05.mp3", + "vo/engineer_painsharp06.mp3", + "vo/engineer_painsharp07.mp3", + "vo/engineer_painsharp08.mp3", +}; + +static const char g_IdleAlertedSounds[][] = { + "vo/engineer_battlecry01.mp3", + "vo/engineer_battlecry03.mp3", + "vo/engineer_battlecry04.mp3", + "vo/engineer_battlecry05.mp3", +}; + +static const char g_MeleeAttackSounds[][] = { + "weapons/pickaxe_swing1.wav", + "weapons/pickaxe_swing2.wav", + "weapons/pickaxe_swing3.wav", +}; + +static const char g_MeleeHitSounds[][] = { + "weapons/cleaver_hit_02.wav", + "weapons/cleaver_hit_03.wav", + "weapons/cleaver_hit_05.wav", + "weapons/cleaver_hit_06.wav", + "weapons/cleaver_hit_07.wav", +}; +static const char g_BuildSound[][] = { + "weapons/medi_shield_deploy.wav", +}; + +void Victorian_Protector_OnMapStart_NPC() +{ + for (int i = 0; i < (sizeof(g_DeathSounds)); i++) { PrecacheSound(g_DeathSounds[i]); } + for (int i = 0; i < (sizeof(g_HurtSounds)); i++) { PrecacheSound(g_HurtSounds[i]); } + for (int i = 0; i < (sizeof(g_IdleAlertedSounds)); i++) { PrecacheSound(g_IdleAlertedSounds[i]); } + for (int i = 0; i < (sizeof(g_MeleeAttackSounds)); i++) { PrecacheSound(g_MeleeAttackSounds[i]); } + for (int i = 0; i < (sizeof(g_MeleeHitSounds)); i++) { PrecacheSound(g_MeleeHitSounds[i]); } + for (int i = 0; i < (sizeof(g_BuildSound)); i++) { PrecacheSound(g_BuildSound[i]); } + NPCData data; + strcopy(data.Name, sizeof(data.Name), "Victorian Protector"); + strcopy(data.Plugin, sizeof(data.Plugin), "npc_protector"); + strcopy(data.Icon, sizeof(data.Icon), "engineer"); + data.IconCustom = false; + data.Flags = 0; + data.Category = Type_Victoria; + data.Func = ClotSummon; + NPC_Add(data); +} + + +static any ClotSummon(int client, float vecPos[3], float vecAng[3], int team, const char[] data) +{ + return Victorian_Protector(vecPos, vecAng, team, data); +} +methodmap Victorian_Protector < CClotBody +{ + property float m_flArmorToGive + { + public get() { return fl_AbilityOrAttack[this.index][0]; } + public set(float TempValueForProperty) { fl_AbilityOrAttack[this.index][0] = TempValueForProperty; } + } + public void PlayIdleAlertSound() + { + if(this.m_flNextIdleSound > GetGameTime(this.index)) + return; + + EmitSoundToAll(g_IdleAlertedSounds[GetRandomInt(0, sizeof(g_IdleAlertedSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + this.m_flNextIdleSound = GetGameTime(this.index) + GetRandomFloat(12.0, 24.0); + + } + + public void PlayHurtSound() + { + if(this.m_flNextHurtSound > GetGameTime(this.index)) + return; + + this.m_flNextHurtSound = GetGameTime(this.index) + 0.4; + + EmitSoundToAll(g_HurtSounds[GetRandomInt(0, sizeof(g_HurtSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + + } + + public void PlayDeathSound() + { + EmitSoundToAll(g_DeathSounds[GetRandomInt(0, sizeof(g_DeathSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + + public void PlayMeleeSound() + { + EmitSoundToAll(g_MeleeAttackSounds[GetRandomInt(0, sizeof(g_MeleeAttackSounds) - 1)], this.index, SNDCHAN_AUTO, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + public void PlayMeleeHitSound() + { + EmitSoundToAll(g_MeleeHitSounds[GetRandomInt(0, sizeof(g_MeleeHitSounds) - 1)], this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + public void PlayBuildSound() + { + EmitSoundToAll(g_BuildSound[GetRandomInt(0, sizeof(g_BuildSound) - 1)], this.index, SNDCHAN_STATIC, BOSS_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + EmitSoundToAll(g_BuildSound[GetRandomInt(0, sizeof(g_BuildSound) - 1)], this.index, SNDCHAN_STATIC, BOSS_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + + + public Victorian_Protector(float vecPos[3], float vecAng[3], int ally, const char[] data) + { + Victorian_Protector npc = view_as(CClotBody(vecPos, vecAng, "models/player/engineer.mdl", "1.0", "10000", ally)); + + i_NpcWeight[npc.index] = 1; + FormatEx(c_HeadPlaceAttachmentGibName[npc.index], sizeof(c_HeadPlaceAttachmentGibName[]), "head"); + + npc.SetActivity("ACT_MP_RUN_BUILDING"); + SetVariantInt(1); + AcceptEntityInput(npc.index, "SetBodyGroup"); + + npc.m_flNextMeleeAttack = 0.0; + + npc.m_iBleedType = BLEEDTYPE_NORMAL; + npc.m_iStepNoiseType = STEPSOUND_NORMAL; + npc.m_iNpcStepVariation = STEPTYPE_NORMAL; + + npc.m_flArmorToGive = StringToFloat(data); + + func_NPCDeath[npc.index] = view_as(Victorian_Protector_NPCDeath); + func_NPCOnTakeDamage[npc.index] = view_as(Victorian_Protector_OnTakeDamage); + func_NPCThink[npc.index] = view_as(Victorian_Protector_ClotThink); + + + //IDLE + npc.m_iState = 0; + npc.m_iChanged_WalkCycle = 1; + npc.m_flGetClosestTargetTime = 0.0; + npc.StartPathing(); + npc.m_flSpeed = 225.0; + npc.Anger = false; + + + int skin = 1; + SetEntProp(npc.index, Prop_Send, "m_nSkin", skin); + + npc.m_iWearable1 = npc.EquipItem("head", "models/weapons/c_models/c_toolbox/c_toolbox.mdl"); + + npc.m_iWearable2 = npc.EquipItem("head", "models/player/items/engineer/bet_pb.mdl"); + npc.m_iWearable3 = npc.EquipItem("head", "models/workshop/player/items/engineer/sbox2014_antarctic_researcher/sbox2014_antarctic_researcher.mdl"); + npc.m_iWearable4 = npc.EquipItem("head", "models/workshop/player/items/sniper/dec2014_hunter_ushanka/dec2014_hunter_ushanka.mdl"); + npc.m_iWearable5 = npc.EquipItem("head", "models/workshop/player/items/engineer/hwn2015_western_beard/hwn2015_western_beard.mdl"); + SetEntProp(npc.m_iWearable1, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable2, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable3, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable4, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable5, Prop_Send, "m_nSkin", skin); + + return npc; + } +} + +public void Victorian_Protector_ClotThink(int iNPC) +{ + Victorian_Protector npc = view_as(iNPC); + if(npc.m_flNextDelayTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextDelayTime = GetGameTime(npc.index) + DEFAULT_UPDATE_DELAY_FLOAT; + npc.Update(); + + if(npc.m_blPlayHurtAnimation) + { + npc.AddGesture("ACT_MP_GESTURE_FLINCH_CHEST", false); + npc.m_blPlayHurtAnimation = false; + npc.PlayHurtSound(); + } + + GrantEntityArmor(iNPC, true, 0.5, 0.0, 0); + + if(npc.m_flNextThinkTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextThinkTime = GetGameTime(npc.index) + 0.1; + + if(npc.m_flGetClosestTargetTime < GetGameTime(npc.index)) + { + npc.m_iTarget = GetClosestTarget(npc.index); + npc.m_flGetClosestTargetTime = GetGameTime(npc.index) + GetRandomRetargetTime(); + } + + if(IsValidEnemy(npc.index, npc.m_iTarget)) + { + float vecTarget[3]; WorldSpaceCenter(npc.m_iTarget, vecTarget ); + + float VecSelfNpc[3]; WorldSpaceCenter(npc.index, VecSelfNpc); + float flDistanceToTarget = GetVectorDistance(vecTarget, VecSelfNpc, true); + if(flDistanceToTarget < npc.GetLeadRadius()) + { + float vPredictedPos[3]; + PredictSubjectPosition(npc, npc.m_iTarget,_,_, vPredictedPos); + npc.SetGoalVector(vPredictedPos); + } + else + { + npc.SetGoalEntity(npc.m_iTarget); + } + if(npc.m_iChanged_WalkCycle == 1 && npc.Anger == false) + { + Victorian_ProtectorBuildObject(npc, flDistanceToTarget); + } + else + { + Victorian_ProtectorSelfDefense(npc,GetGameTime(npc.index), npc.m_iTarget, flDistanceToTarget); + } + } + else + { + npc.m_flGetClosestTargetTime = 0.0; + npc.m_iTarget = GetClosestTarget(npc.index); + } + npc.PlayIdleAlertSound(); +} + +public Action Victorian_Protector_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + Victorian_Protector npc = view_as(victim); + + if(attacker <= 0) + return Plugin_Continue; + + if(npc.m_flArmorCount <= 0.0 && npc.Anger == false) + { + npc.Anger = true; + npc.m_iChanged_WalkCycle = 2; + npc.SetActivity("ACT_MP_RUN_MELEE"); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); + npc.m_iWearable1 = npc.EquipItem("head", "models/workshop/weapons/c_models/C_Crossing_Guard/C_Crossing_Guard.mdl"); + SetVariantString("0.75"); + AcceptEntityInput(npc.m_iWearable1, "SetModelScale"); + } + else + { + if (npc.m_flHeadshotCooldown < GetGameTime(npc.index)) + { + npc.m_flHeadshotCooldown = GetGameTime(npc.index) + DEFAULT_HURTDELAY; + npc.m_blPlayHurtAnimation = true; + } + } + + return Plugin_Changed; +} + +public void Victorian_Protector_NPCDeath(int entity) +{ + Victorian_Protector npc = view_as(entity); + if(!npc.m_bGib) + { + npc.PlayDeathSound(); + } + + if(IsValidEntity(npc.m_iWearable7)) + RemoveEntity(npc.m_iWearable7); + if(IsValidEntity(npc.m_iWearable6)) + RemoveEntity(npc.m_iWearable6); + if(IsValidEntity(npc.m_iWearable5)) + RemoveEntity(npc.m_iWearable5); + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + if(IsValidEntity(npc.m_iWearable3)) + RemoveEntity(npc.m_iWearable3); + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); +} + +void Victorian_ProtectorBuildObject(Victorian_Protector npc, float distance) +{ + if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 3.5)) + { + int Enemy_I_See = Can_I_See_Enemy(npc.index, npc.m_iTarget); + + if(IsValidEnemy(npc.index, Enemy_I_See)) + { + npc.m_iChanged_WalkCycle = 2; + npc.SetActivity("ACT_MP_RUN_MELEE"); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); + + float pos[3]; GetEntPropVector(npc.index, Prop_Data, "m_vecAbsOrigin", pos); + float ang[3]; GetEntPropVector(npc.index, Prop_Data, "m_angRotation", ang); + npc.m_iWearable1 = npc.EquipItem("head", "models/workshop/weapons/c_models/C_Crossing_Guard/C_Crossing_Guard.mdl"); + SetVariantString("0.75"); + AcceptEntityInput(npc.m_iWearable1, "SetModelScale"); + SetEntProp(npc.m_iWearable1, Prop_Send, "m_nSkin", 1); + float timeup = 5.0; + if(NpcStats_VictorianCallToArms(npc.index)) + timeup *= 2.0; + npc.m_iWearable7 = npc.SpawnShield(timeup, "models/props_mvm/mvm_player_shield.mdl",40.0, false); + SetEntProp(npc.m_iWearable7, Prop_Send, "m_nSkin", 1); + npc.PlayBuildSound(); + npc.m_flSpeed = 300.0; + npc.m_flArmorCount = 0.0; + } + } +} +void Victorian_ProtectorSelfDefense(Victorian_Protector npc, float gameTime, int target, float distance) +{ + if(npc.m_flAttackHappens) + { + if(npc.m_flAttackHappens < gameTime) + { + npc.m_flAttackHappens = 0.0; + + Handle swingTrace; + float VecEnemy[3]; WorldSpaceCenter(npc.m_iTarget, VecEnemy); + npc.FaceTowards(VecEnemy, 15000.0); + if(npc.DoSwingTrace(swingTrace, npc.m_iTarget)) + { + + target = TR_GetEntityIndex(swingTrace); + + float vecHit[3]; + TR_GetEndPosition(vecHit, swingTrace); + + if(IsValidEnemy(npc.index, target)) + { + float damageDealt = 50.0; + + if(ShouldNpcDealBonusDamage(target)) + damageDealt *= 1.5; + + int DamageType = DMG_CLUB; + SDKHooks_TakeDamage(target, npc.index, npc.index, damageDealt, DamageType, -1, _, vecHit); + + // Hit sound + npc.PlayMeleeHitSound(); + } + } + delete swingTrace; + } + } + + if(gameTime > npc.m_flNextMeleeAttack) + { + if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED)) + { + int Enemy_I_See; + + Enemy_I_See = Can_I_See_Enemy(npc.index, npc.m_iTarget); + + if(IsValidEnemy(npc.index, Enemy_I_See)) + { + npc.m_iTarget = Enemy_I_See; + npc.PlayMeleeSound(); + npc.AddGesture("ACT_MP_ATTACK_STAND_MELEE",_,_,_,1.0); + + npc.m_flAttackHappens = gameTime + 0.25; + npc.m_flDoingAnimation = gameTime + 0.25; + npc.m_flNextMeleeAttack = gameTime + 1.0; + } + } + } +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_zapmarker.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_zapmarker.sp new file mode 100644 index 0000000000..ebed9f1989 --- /dev/null +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/construction2/victorians/npc_zapmarker.sp @@ -0,0 +1,395 @@ +#pragma semicolon 1 +#pragma newdecls required + +static const char g_DeathSounds[][] = { + "vo/heavy_negativevocalization01.mp3", + "vo/heavy_negativevocalization02.mp3", + "vo/heavy_negativevocalization03.mp3" +}; + +static const char g_HurtSounds[][] = { + "vo/heavy_domination09.mp3", +}; + +static const char g_IdleAlertedSounds[][] = { + "vo/heavy_domination01.mp3", + "vo/heavy_domination02.mp3", + "vo/heavy_domination03.mp3", + "vo/heavy_domination04.mp3", + "vo/heavy_domination05.mp3", + "vo/heavy_domination06.mp3", + "vo/heavy_domination07.mp3", + "vo/heavy_domination08.mp3", +}; + +static const char g_MeleeAttackSounds[][] = { + "vo/heavy_meleeing01.mp3", + "vo/heavy_meleeing02.mp3", + "vo/heavy_meleeing03.mp3", + "vo/heavy_meleeing04.mp3", + "vo/heavy_meleeing05.mp3", + "vo/heavy_meleeing06.mp3", + "vo/heavy_meleeing07.mp3", + "vo/heavy_meleeing08.mp3", +}; + + +static const char g_MeleeHitSounds[][] = { + "weapons/cbar_hitbod1.wav", + "weapons/cbar_hitbod2.wav", + "weapons/cbar_hitbod3.wav", +}; + +static const char g_RangedAttackSounds[][] = { + "weapons/cleaver_throw.wav", +}; + +void Zapmarker_OnMapStart_NPC() +{ + for (int i = 0; i < (sizeof(g_DeathSounds)); i++) { PrecacheSound(g_DeathSounds[i]); } + for (int i = 0; i < (sizeof(g_HurtSounds)); i++) { PrecacheSound(g_HurtSounds[i]); } + for (int i = 0; i < (sizeof(g_IdleAlertedSounds)); i++) { PrecacheSound(g_IdleAlertedSounds[i]); } + for (int i = 0; i < (sizeof(g_MeleeAttackSounds)); i++) { PrecacheSound(g_MeleeAttackSounds[i]); } + for (int i = 0; i < (sizeof(g_MeleeHitSounds)); i++) { PrecacheSound(g_MeleeHitSounds[i]); } + + NPCData data; + strcopy(data.Name, sizeof(data.Name), "Zapmarker"); + strcopy(data.Plugin, sizeof(data.Plugin), "npc_zapmarker"); + strcopy(data.Icon, sizeof(data.Icon), "victoria_zapper"); //leaderboard_class_(insert the name) + data.IconCustom = false; //download needed? + data.Flags = 0; //example: MVM_CLASS_FLAG_MINIBOSS|MVM_CLASS_FLAG_ALWAYSCRIT;, forces these flags. + data.Category = Type_Victoria; + data.Func = ClotSummon; + NPC_Add(data); +} + +static any ClotSummon(int client, float vecPos[3], float vecAng[3], int team) +{ + return Zapmaker(vecPos, vecAng, team); +} + +methodmap Zapmaker < CClotBody +{ + public void PlayIdleAlertSound() + { + if(this.m_flNextIdleSound > GetGameTime(this.index)) + return; + + EmitSoundToAll(g_IdleAlertedSounds[GetRandomInt(0, sizeof(g_IdleAlertedSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + this.m_flNextIdleSound = GetGameTime(this.index) + GetRandomFloat(12.0, 24.0); + + } + + public void PlayHurtSound() + { + if(this.m_flNextHurtSound > GetGameTime(this.index)) + return; + + this.m_flNextHurtSound = GetGameTime(this.index) + 0.4; + + EmitSoundToAll(g_HurtSounds[GetRandomInt(0, sizeof(g_HurtSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + + } + + public void PlayDeathSound() + { + EmitSoundToAll(g_DeathSounds[GetRandomInt(0, sizeof(g_DeathSounds) - 1)], this.index, SNDCHAN_VOICE, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + + public void PlayMeleeSound() + { + EmitSoundToAll(g_MeleeAttackSounds[GetRandomInt(0, sizeof(g_MeleeAttackSounds) - 1)], this.index, SNDCHAN_AUTO, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + } + public void PlayMeleeHitSound() + { + EmitSoundToAll(g_MeleeHitSounds[GetRandomInt(0, sizeof(g_MeleeHitSounds) - 1)], this.index, SNDCHAN_STATIC, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME); + + } + public void PlayRangedSound() + { + EmitSoundToAll(g_RangedAttackSounds[GetRandomInt(0, sizeof(g_RangedAttackSounds) - 1)], this.index, SNDCHAN_AUTO, NORMAL_ZOMBIE_SOUNDLEVEL, _, NORMAL_ZOMBIE_VOLUME, 80); + } + + public Zapmaker(float vecPos[3], float vecAng[3], int ally) + { + Zapmaker npc = view_as(CClotBody(vecPos, vecAng, "models/player/heavy.mdl", "1.0", "5000", ally)); + + i_NpcWeight[npc.index] = 1; + FormatEx(c_HeadPlaceAttachmentGibName[npc.index], sizeof(c_HeadPlaceAttachmentGibName[]), "head"); + + int iActivity = npc.LookupActivity("ACT_MP_RUN_MELEE_ALLCLASS"); + if(iActivity > 0) npc.StartActivity(iActivity); + + SetVariantInt(4); + AcceptEntityInput(npc.index, "SetBodyGroup"); + + + + npc.m_flNextMeleeAttack = 0.0; + npc.m_flNextRangedAttack = 0.0; + npc.m_flNextRangedAttackHappening = 0.0; + + npc.m_iBleedType = BLEEDTYPE_NORMAL; + npc.m_iStepNoiseType = STEPSOUND_NORMAL; + npc.m_iNpcStepVariation = STEPTYPE_NORMAL; + + func_NPCDeath[npc.index] = view_as(Internal_NPCDeath); + func_NPCOnTakeDamage[npc.index] = view_as(Internal_OnTakeDamage); + func_NPCThink[npc.index] = view_as(Internal_ClotThink); + + + npc.StartPathing(); + npc.m_flSpeed = 200.0; + + int skin = 1; + SetEntProp(npc.index, Prop_Send, "m_nSkin", skin); + + npc.m_iWearable1 = npc.EquipItem("head", "models/weapons/c_models/c_drg_thirddegree/c_drg_thirddegree.mdl"); + + npc.m_iWearable2 = npc.EquipItem("head", "models/workshop/player/items/all_class/dec15_patriot_peak/dec15_patriot_peak_heavy.mdl"); + + npc.m_iWearable3 = npc.EquipItem("head", "models/workshop/player/items/heavy/fall17_siberian_tigerstripe/fall17_siberian_tigerstripe.mdl"); + + npc.m_iWearable4 = npc.EquipItem("head", "models/workshop/player/items/heavy/dec24_battle_balaclava_style1/dec24_battle_balaclava_style1.mdl"); + + npc.m_iWearable5 = npc.EquipItem("head", "models/workshop/player/items/heavy/sf14_heavy_robo_chest/sf14_heavy_robo_chest.mdl"); + + npc.m_iWearable6 = npc.EquipItem("head", "models/workshop/player/items/all_class/dec25_lazer_gazers/dec25_lazer_gazers_heavy.mdl"); + + SetVariantString("0.75"); + AcceptEntityInput(npc.m_iWearable1, "SetModelScale"); + SetEntProp(npc.m_iWearable1, Prop_Send, "m_nSkin", 1); + SetEntityRenderColor(npc.m_iWearable1, 50, 80, 0, 255); + SetEntProp(npc.m_iWearable2, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable3, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable4, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable5, Prop_Send, "m_nSkin", skin); + SetEntProp(npc.m_iWearable6, Prop_Send, "m_nSkin", skin); + + return npc; + } +} + +static void Internal_ClotThink(int iNPC) +{ + Zapmaker npc = view_as(iNPC); + if(npc.m_flNextDelayTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextDelayTime = GetGameTime(npc.index) + DEFAULT_UPDATE_DELAY_FLOAT; + npc.Update(); + + if(npc.m_blPlayHurtAnimation) + { + npc.AddGesture("ACT_MP_GESTURE_FLINCH_CHEST", false); + npc.m_blPlayHurtAnimation = false; + npc.PlayHurtSound(); + } + + if(npc.m_flNextThinkTime > GetGameTime(npc.index)) + { + return; + } + npc.m_flNextThinkTime = GetGameTime(npc.index) + 0.1; + + if(npc.m_flGetClosestTargetTime < GetGameTime(npc.index)) + { + npc.m_iTarget = GetClosestTarget(npc.index); + npc.m_flGetClosestTargetTime = GetGameTime(npc.index) + GetRandomRetargetTime(); + } + + if(IsValidEnemy(npc.index, npc.m_iTarget)) + { + float vecTarget[3]; WorldSpaceCenter(npc.m_iTarget, vecTarget ); + + float VecSelfNpc[3]; WorldSpaceCenter(npc.index, VecSelfNpc); + float flDistanceToTarget = GetVectorDistance(vecTarget, VecSelfNpc, true); + if(flDistanceToTarget < npc.GetLeadRadius()) + { + float vPredictedPos[3]; + PredictSubjectPosition(npc, npc.m_iTarget,_,_, vPredictedPos); + npc.SetGoalVector(vPredictedPos); + } + else + { + npc.SetGoalEntity(npc.m_iTarget); + } + ZapmakerSelfDefense(npc,GetGameTime(npc.index), npc.m_iTarget, flDistanceToTarget); + } + else + { + npc.m_flGetClosestTargetTime = 0.0; + npc.m_iTarget = GetClosestTarget(npc.index); + } + npc.PlayIdleAlertSound(); +} + +static void Internal_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + Zapmaker npc = view_as(victim); + + if(attacker <= 0) + return; + + if (npc.m_flHeadshotCooldown < GetGameTime(npc.index)) + { + npc.m_flHeadshotCooldown = GetGameTime(npc.index) + DEFAULT_HURTDELAY; + npc.m_blPlayHurtAnimation = true; + } +} + +static void Internal_NPCDeath(int entity) +{ + Zapmaker npc = view_as(entity); + if(!npc.m_bGib) + { + npc.PlayDeathSound(); + } + + if(IsValidEntity(npc.m_iWearable6)) + RemoveEntity(npc.m_iWearable6); + if(IsValidEntity(npc.m_iWearable5)) + RemoveEntity(npc.m_iWearable5); + if(IsValidEntity(npc.m_iWearable4)) + RemoveEntity(npc.m_iWearable4); + if(IsValidEntity(npc.m_iWearable3)) + RemoveEntity(npc.m_iWearable3); + if(IsValidEntity(npc.m_iWearable2)) + RemoveEntity(npc.m_iWearable2); + if(IsValidEntity(npc.m_iWearable1)) + RemoveEntity(npc.m_iWearable1); + +} + +void ZapmakerSelfDefense(Zapmaker npc, float gameTime, int target, float distance) +{ + if(!npc.m_flNextRangedAttackHappening) + { + if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED * 12.0)) + { + int Enemy_I_See; + + Enemy_I_See = Can_I_See_Enemy(npc.index, npc.m_iTarget); + + if(IsValidEnemy(npc.index, Enemy_I_See)) + { + npc.m_flNextRangedAttack = gameTime + 0.25; + npc.m_flNextRangedAttackHappening = 1.0; + npc.AddGesture("ACT_MP_ATTACK_STAND_MELEE_ALLCLASS"); + npc.m_flDoingAnimation = gameTime + 0.25; + npc.m_flNextMeleeAttack = gameTime + 1.2; + } + } + return; + } + if(npc.m_flNextRangedAttack && npc.m_flNextRangedAttack != 5.0) + { + if(npc.m_flNextRangedAttack < gameTime) + { + float EnemyPos[3]; + WorldSpaceCenter(npc.m_iTarget, EnemyPos); + npc.FaceTowards(EnemyPos, 15000.0); + int projectile = npc.FireArrow(EnemyPos, 250.0, 1200.0, "models/weapons/c_models/c_drg_thirddegree/c_drg_thirddegree.mdl", 0.75); + WandProjectile_ApplyFunctionToEntity(projectile, Zapmarker_Axe_StartTouch); + + if(IsValidEntity(npc.m_iWearable1)) + { + RemoveEntity(npc.m_iWearable1); + } + npc.m_flNextRangedAttack = 5.0; + npc.PlayRangedSound(); + npc.m_flDoingAnimation = gameTime + 0.25; + } + } + if(npc.m_flNextRangedAttack && npc.m_flNextRangedAttack == 5.0) + { + npc.m_flNextRangedAttack = 0.0; + npc.m_iWearable1 = npc.EquipItem("head", "models/weapons/c_models/c_eviction_notice/c_eviction_notice.mdl"); + npc.SetActivity("ACT_MP_RUN_MELEE"); + npc.m_flSpeed = 275.0; + return; + } + + if(npc.m_flAttackHappens) + { + if(npc.m_flAttackHappens < gameTime) + { + npc.m_flAttackHappens = 0.0; + + Handle swingTrace; + float VecEnemy[3]; WorldSpaceCenter(npc.m_iTarget, VecEnemy); + npc.FaceTowards(VecEnemy, 15000.0); + if(npc.DoSwingTrace(swingTrace, npc.m_iTarget)) + { + + target = TR_GetEntityIndex(swingTrace); + + float vecHit[3]; + TR_GetEndPosition(vecHit, swingTrace); + + if(IsValidEnemy(npc.index, target)) + { + float damageDealt = 35.0; + if(ShouldNpcDealBonusDamage(target)) + damageDealt *= 2.5; + + SDKHooks_TakeDamage(target, npc.index, npc.index, damageDealt, DMG_CLUB, -1, _, vecHit); + if(NpcStats_VictorianCallToArms(npc.index)) + Elemental_AddNervousDamage(target, npc.index, 5); + StartBleedingTimer(target, npc.index, 3.0, 2, -1, DMG_TRUEDAMAGE, 0); + + // Hit sound + npc.PlayMeleeHitSound(); + } + } + delete swingTrace; + } + } + + if(gameTime > npc.m_flNextMeleeAttack) + { + if(distance < (NORMAL_ENEMY_MELEE_RANGE_FLOAT_SQUARED)) + { + int Enemy_I_See; + + Enemy_I_See = Can_I_See_Enemy(npc.index, npc.m_iTarget); + + if(IsValidEnemy(npc.index, Enemy_I_See)) + { + npc.m_iTarget = Enemy_I_See; + npc.PlayMeleeSound(); + npc.AddGesture("ACT_MP_ATTACK_STAND_MELEE"); + + npc.m_flAttackHappens = gameTime + 0.1; + npc.m_flDoingAnimation = gameTime + 0.1; + npc.m_flNextMeleeAttack = gameTime + 0.15; + } + } + } +} + +public void Zapmarker_Axe_StartTouch(int entity, int target) +{ + if(target > 0 && target < MAXENTITIES) //did we hit something??? + { + int owner = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity"); + if(!IsValidEntity(owner)) + { + owner = 0; + } + + int inflictor = h_ArrowInflictorRef[entity]; + if(inflictor != -1) + inflictor = EntRefToEntIndex(h_ArrowInflictorRef[entity]); + + if(inflictor == -1) + inflictor = owner; + + + EmitSoundToAll("weapons/3rd_degree_hit_01.wav", entity, _, 80, _, 0.8, 100); + if(IsValidEnemy(owner, target)) + ApplyStatusEffect(owner, target, "Teslar Electricution", NpcStats_VictorianCallToArms(owner) ? 7.5 : 5.0); + } + RemoveEntity(entity); +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/zombie_riot/npc/construction/enemies/npc_zilius.sp b/addons/sourcemod/scripting/zombie_riot/npc/construction/enemies/npc_zilius.sp index 70abbd4cc5..261591d4b9 100644 --- a/addons/sourcemod/scripting/zombie_riot/npc/construction/enemies/npc_zilius.sp +++ b/addons/sourcemod/scripting/zombie_riot/npc/construction/enemies/npc_zilius.sp @@ -639,6 +639,16 @@ static void Internal_ClotThink(int iNPC) } default: { + for (int client = 1; client <= MaxClients; client++) + { + if(IsValidClient(client) && GetClientTeam(client) == 2 && TeutonType[client] != TEUTON_WAITING && PlayerPoints[client] > 500) + { + if(Items_GiveNamedItem(client, "Foreign Expidonsan Chip")) + { + CPrintToChat(client, "{green}Obtained{yellow} ''Foreign Expidonsan Chip''"); + } + } + } ForcePlayerWin(); npc.m_flWinAnimationSay = 0.0; npc.m_flWinAnimation = 0.0; diff --git a/addons/sourcemod/scripting/zombie_riot/object/obj_vintulum_bomb.sp b/addons/sourcemod/scripting/zombie_riot/object/obj_vintulum_bomb.sp index 94cd65a53c..eb73560e46 100644 --- a/addons/sourcemod/scripting/zombie_riot/object/obj_vintulum_bomb.sp +++ b/addons/sourcemod/scripting/zombie_riot/object/obj_vintulum_bomb.sp @@ -69,7 +69,7 @@ methodmap ObjectVintulumBomb < ObjectGeneric { EmitSoundToAll(g_ExplosionRightBefore[GetRandomInt(0, sizeof(g_ExplosionRightBefore) - 1)], this.index, SNDCHAN_AUTO, 80, _, 0.8, 100); } - public void PlayExplodeDo(bool alreadydead) + public void PlayExplodeDo(bool alreadydead, bool VisualOnly = false) { EmitSoundToAll(g_ExplosionSound[GetRandomInt(0, sizeof(g_ExplosionSound) - 1)], this.index, SNDCHAN_AUTO, 80, _, 1.0, 100); EmitSoundToAll(g_ExplosionSound[GetRandomInt(0, sizeof(g_ExplosionSound) - 1)], this.index, SNDCHAN_AUTO, 80, _, 1.0, 100); @@ -84,24 +84,27 @@ methodmap ObjectVintulumBomb < ObjectGeneric TE_Particle("grenade_smoke_cycle", pos, NULL_VECTOR, NULL_VECTOR, _, _, _, _, _, _, _, _, _, _, 0.0); - int Owner = GetEntPropEnt(this.index, Prop_Send, "m_hOwnerEntity"); - if(!IsValidClient(Owner)) + if(!VisualOnly) { - return; + int Owner = GetEntPropEnt(this.index, Prop_Send, "m_hOwnerEntity"); + if(!IsValidClient(Owner)) + { + return; + } + float damage = 10.0; + damage *= 30.0; + float attack_speed; + float sentry_range; + attack_speed = 1.0 / Attributes_GetOnPlayer(Owner, 343, true, true); //Sentry attack speed bonus + damage = attack_speed * damage * Attributes_GetOnPlayer(Owner, 287, true, true); //Sentry damage bonus + sentry_range = Attributes_GetOnPlayer(Owner, 344, true, true); //Sentry Range bonus + float AOE_range = 350.0 * sentry_range; + + damage *= 5.0; + //its like 5 mortars at once. + Explode_Logic_Custom(damage, Owner, Owner, -1, pos, AOE_range, 0.75, _, false); + ExpidonsaGroupHeal(Owner, AOE_range, 99, 1.0, 1.0, true, VintulumBombSelf, .LOS = true, .VecDoAt = pos); } - float damage = 10.0; - damage *= 30.0; - float attack_speed; - float sentry_range; - attack_speed = 1.0 / Attributes_GetOnPlayer(Owner, 343, true, true); //Sentry attack speed bonus - damage = attack_speed * damage * Attributes_GetOnPlayer(Owner, 287, true, true); //Sentry damage bonus - sentry_range = Attributes_GetOnPlayer(Owner, 344, true, true); //Sentry Range bonus - float AOE_range = 350.0 * sentry_range; - - damage *= 5.0; - //its like 5 mortars at once. - Explode_Logic_Custom(damage, Owner, Owner, -1, pos, AOE_range, 0.75, _, false); - ExpidonsaGroupHeal(Owner, AOE_range, 99, 1.0, 1.0, true, VintulumBombSelf, .LOS = true, .VecDoAt = pos); int entity = CreateEntityByName("light_dynamic"); if(entity != -1) @@ -119,8 +122,9 @@ methodmap ObjectVintulumBomb < ObjectGeneric CreateTimer(2.0, Timer_RemoveEntity, EntIndexToEntRef(entity), TIMER_FLAG_NO_MAPCHANGE); CreateTimer(0.1, Timer_ReduceLighting, EntIndexToEntRef(entity), TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT); } - if(!alreadydead) - DestroyBuildingDo(this.index); + if(!VisualOnly) + if(!alreadydead) + DestroyBuildingDo(this.index); } property float m_flBombExplodeTill @@ -149,7 +153,6 @@ methodmap ObjectVintulumBomb < ObjectGeneric return npc; } } - static void ClotThink(ObjectVintulumBomb npc) { int Owner = GetEntPropEnt(npc.index, Prop_Send, "m_hOwnerEntity"); diff --git a/addons/sourcemod/scripting/zombie_riot/roguelike/construction_items.sp b/addons/sourcemod/scripting/zombie_riot/roguelike/construction_items.sp index dfd9c5207b..507ef28d90 100644 --- a/addons/sourcemod/scripting/zombie_riot/roguelike/construction_items.sp +++ b/addons/sourcemod/scripting/zombie_riot/roguelike/construction_items.sp @@ -368,7 +368,7 @@ public void Xeno_Resurgance_Enemy(int entity) return; if(view_as(entity).m_iBleedType != BLEEDTYPE_XENO) - ApplyStatusEffect(entity, entity, "Xeno Infection", 9999.9); + ApplyStatusEffect(entity, entity, "Xeno Infection Buff", 9999.9); else ApplyStatusEffect(entity, entity, "Xeno Infection Buff Only", 9999.9); } diff --git a/addons/sourcemod/translations/zombieriot.phrases.item.gift.desc.txt b/addons/sourcemod/translations/zombieriot.phrases.item.gift.desc.txt index ee8ccf74e8..7cac14f0be 100644 --- a/addons/sourcemod/translations/zombieriot.phrases.item.gift.desc.txt +++ b/addons/sourcemod/translations/zombieriot.phrases.item.gift.desc.txt @@ -2521,6 +2521,14 @@ "it" "Il primo gruppo di mercenari ha già fallito.\n 35 nemici in più, si riproducono 33% più velocemente, 15% in più sono vivi contemporaneamente. infliggono +15% dmg, +25% dmg ai cad, hanno 50% + HP, +4% più velocemente. i nemici guariscono 50% in più." "ko" "최초로 출격한 용병들은 실패했습니다.\n웨이브 적 수량 +35%, 생성 속도 +33%, 한번에 존재하는 적의 수 +15%\n적 피해량 +15%, 구조물 대상 피해량 +25%, 체력 +50%, 이동 속도 +4%\n적들의 체력 회복량 +50%" } + "Prefixes Galore" + { + "en" "Prefixes Galore" + } + "Prefixes Galore Desc" + { + "en" "Prepare for aboslute hell!\nEnemies have a chance to obtain prefixes, if they do, they gain massive buffs aswell.\nBosses and raids gain prefixes guranteed but arent extra buffed\nRaids have infinite time.\nPrefixes can stack." + } "Paranormal Activity" { "en" "Paranormal Activity" @@ -3562,7 +3570,42 @@ { "en" " `Did you really thought you could get out this mess that easily?` \nColonel of Victoria's Army. He has mastered skill for explosives and command \nHe wants your death for the amends of Radiotower's destruction. Do we really have to fight him while we got same enemeis in common? \nHe will utilize all of the abilites that previous raidbosses used and often call in for support" } - + "Zapmarker Desc" + { + "en" "An elite melee unit of victoria \nThrows Zapper's axe to apply teslar debuff to its victim and rush in with melee that applies heavy bleed" + } + "Resource Collector Desc" + { + "en" "A robotic unit designed to collect nearby minerals \nFast and applied more damage to buildings" + } + "Victoria Gasleader Desc" + { + "en" "Victorian Chemical Platoon leader. \n applies armor corrosion elemental damage near while his armor is up \nPulls out a sword that applies more armor corrosion damage on 3rd hit when its target gets close \nBecomes stronger as near allies die" + } + "Demolitionist Desc" + { + "en" "Heavy melee unit of Victorian Chemical Platoon \nSwings a massive hammer to create and explosion that deals MASSIVE damage to buildings" + } + "Victorian Protector Desc" + { + "en" "Carrier unit holding a portable shield \n spawns with an armor and when it gets closer to its target, deployys an energy shield \nIt's shield carrier will be destroyed if its armor runs out" + } + "Airraider Desc" + { + "en" "A surprise assault unit of Victorian Chemical Platoon. \nParachutes in when it spawns and fire its rocket while falling down. \n continues with shotgun when on the ground" + } + "Victorian Headhunter Desc" + { + "en" "An elite sniper of Victorian Chemical Platoon. \n Appears quietly and deals armor corrsion damage \n Deals more damage and elemental damage to enemies with support weapon out" + } + "Chemical Specialist Desc" + { + "en" "A Chemical expert of Victorian Chemical Platoon \n Always head all of its elemental damage taken \n fire bullets coated with armor corrosion liquid" + } + "Giant Armored Medibot Desc" + { + "en" "A Giant support unit of Victorian Chemical Platoon designed only for defense \n its patient receives massive buff and never dies unless oneshot \nIt moves very slowly" + } "Avangard's Processing Core-B" { "en" "Avangard's Processing Core-B" diff --git a/addons/sourcemod/translations/zombieriot.phrases.status_effects.txt b/addons/sourcemod/translations/zombieriot.phrases.status_effects.txt index 5af59ea6b0..78d0bf8763 100644 --- a/addons/sourcemod/translations/zombieriot.phrases.status_effects.txt +++ b/addons/sourcemod/translations/zombieriot.phrases.status_effects.txt @@ -783,6 +783,16 @@ "en" "Ammo Visualization" "ko" "탄약 시각화" } + "Buffweiser" + { + "en" "Buffweiser" + "ko" "버프와이저" + } + "Buffweiser Desc" + { + "en" "Boosts damage dealt by 100%\nReduces damage taken by 50%" + "ko" "공격 피해량이 100% 증가합니다.\n받는 피해량이 50% 감소합니다." + } "False Therapy" { "en" "False Therapy" @@ -2621,8 +2631,8 @@ } "The Big Desc" { - "en" "Enlarges by 25%\nIncreases Resistance by 75%" - "ko" "크기가 75% 증가합니다\n저항력이 75% 증가합니다" + "en" "Enlarges by 25%\nIncreases Resistance by 65%" + "ko" "크기가 75% 증가합니다\n저항력이 65% 증가합니다" } "Big" { @@ -2636,8 +2646,8 @@ } "The Strong Desc" { - "en" "Increases Damage by 400%" - "ko" "공격 피해량이 400% 증가합니다" + "en" "Increases Damage by 250%" + "ko" "공격 피해량이 250% 증가합니다" } "Strong" { @@ -2791,18 +2801,18 @@ } "The First Desc" { - "en" "Npc Gains 30% Resistance, 300% Damage, 2x Thinkspeed" - "ko" "NPC의 저항력이 30%, 공격 피해량이 300%, 생각하는 속도가 2배 증가합니다." + "en" "Npc Gains 50% Resistance, 100% Damage, 2x Thinkspeed" + "ko" "NPC의 저항력이 50%, 공격 피해량이 100%, 생각하는 속도가 2배 증가합니다." } - "Xeno Infection" + "Xeno Infection Buff" { "en" "Xeno Infection" "ko" "제노에 감염된" } - "Xeno Infection Desc" + "Xeno Infection Buff Desc" { - "en" "Npc Gains 25% Resistance, 30% Damage, but thinks 15% slower, and regens over time upto 1.35x max health, if above 25% max health, gain immensive buffs untill below\ninfects any enemy with xeno aswell." - "ko" "NPC 저항력 25%, 피해량 30% 증가. 생각 속도 15% 감소. 최대 체력의 1.35배까지 재생. 체력이 25% 이상이라면 그 이하가 될 때까지 강력한 버프 획득\n다른 적에게도 제노를 감염시킴" + "en" "Npc Gains 35% Resistance, 40% Damage, but thinks 10% slower, and regens over time upto 1.35x max health, if above 25% max health, gain immensive buffs untill below\ninfects any enemy with xeno aswell." + "ko" "NPC 저항력 35%, 피해량 40% 증가. 생각 속도 10% 감소. 최대 체력의 1.35배까지 재생. 체력이 25% 이상이라면 그 이하가 될 때까지 강력한 버프 획득\n다른 적에게도 제노를 감염시킴" } "Xeno" { @@ -2816,7 +2826,357 @@ } "Perfected Instinct Desc" { - "en" "Npc Gains 30% Resistance, 300% Damage, 1.5x Thinkspeed, Gains a high chance to dodge attacks, the lower the hp, the higher the chance. On dodge, gain an immensive short speed bonus" - "ko" "NPC 저항력 30%, 피해량 300% 증가. 생각 속도 1.5배. 높은 확률로 공격을 회피, 체력이 감소할 수록 확률 증가. 회피 시 짧은 시간 동안 이동 속도 대폭 증가" + "en" "Npc Gains 40% Resistance, 175% Damage, 1.5x Thinkspeed, Gains a high chance to dodge attacks, the lower the hp, the higher the chance. On dodge, gain an immensive short speed bonus" + "ko" "NPC 저항력 40%, 피해량 175% 증가. 생각 속도 1.5배. 높은 확률로 공격을 회피, 체력이 감소할 수록 확률 증가. 회피 시 짧은 시간 동안 이동 속도 대폭 증가" + } + "Motivating Prefix" + { + "en" "Motivating Prefix" + } + "Motivating" + { + "en" "Motivating" + } + "Motivating Prefix Desc" + { + "en" "Buffs allies with Warcry around itself." + } + "Invisible Prefix" + { + "en" "Invisible Prefix" + } + "Invisible" + { + "en" "Invisible" + } + "Invisible Prefix Desc" + { + "en" "Enemies get invisible at far ranges and get stronger." + } + + "Asexual Prefix" + { + "en" "Asexual Prefix" + } + "Asexual" + { + "en" "Asexual" + } + "Asexual Prefix Desc" + { + "en" "On Death, Splits up into 2 that guranteed get modifiers" + } + "Legendary Prefix" + { + "en" "Legendary Prefix" + } + "Legendary" + { + "en" "Legendary" + } + "Legendary Prefix Desc" + { + "en" "Gets stronger overtime, at 30 seconds gains max power!" + } + "Glug Infested Prefix" + { + "en" "Glug Infested Prefix" + } + "Glug Infested" + { + "en" "Glug Infested" + } + "Glug Infested Desc" + { + "en" "When hurt, everyso often, spawns a glug on their side" + } + "Armoring Prefix" + { + "en" "Armoring Prefix" + } + "Armoring" + { + "en" "Armoring" + } + "Armoring Prefix Desc" + { + "en" "Regenerate armor 20% of max health every 3 seconds" + } + "Explosive Prefix" + { + "en" "Explosive Prefix" + } + "Explosive" + { + "en" "Explosive" + } + "Explosive Prefix Desc" + { + "en" "When dead, explodes into a nuke, damaging everyone" + } + "Stalker Prefix" + { + "en" "Stalker Prefix" + } + "Stalker" + { + "en" "Stalker" + } + "Stalker Prefix Desc" + { + "en" "Bypasses waves and gains insane buffs but much slower walkspeed" + } + "Disco Prefix" + { + "en" "Disco Prefix" + } + "Disco" + { + "en" "Disco" + } + "Disco Prefix Desc" + { + "en" "Flickers lights, partey!!!" + } + "Toxic Prefix" + { + "en" "Toxic Prefix" + } + "Toxic" + { + "en" "Toxic" + } + "Toxic Prefix Desc" + { + "en" "Deals damage to enemies around itself" + } + "Boing Prefix" + { + "en" "Boing Prefix" + } + "Boing" + { + "en" "Boing" + } + "Boing Prefix Desc" + { + "en" "Bounces around like a trampoline" + } + "Knockback Prefix" + { + "en" "Knockback Prefix" + } + "Knockback" + { + "en" "Knockback" + } + "Knockback Prefix Desc" + { + "en" "Enemies on dealin damage recieve knockback" + } + "Loud Prefix" + { + "en" "Loud Prefix" + } + "Loud" + { + "en" "Loud" + } + "Loud Prefix Desc" + { + "en" "Makes all sounds you create 3x as loud" + } + "Ragebaiter Prefix" + { + "en" "Ragebaiter Prefix" + } + "Ragebaiter" + { + "en" "Ragebaiter" + } + "Ragebaiter Prefix Desc" + { + "en" "Makes you forcefully type nasty stuff in chat" + } + "Rage Prefix Text 1" + { + "en" "I WILL KILL YOU" + } + "Rage Prefix Text 2" + { + "en" "ok." + } + "Rage Prefix Text 3" + { + "en" "Youre welcome" + } + "Rage Prefix Text 4" + { + "en" "My favorite toast is your BLOOD" + } + "Rage Prefix Text 5" + { + "en" "FUCKING ASSHOLE" + } + "Rage Prefix Text 6" + { + "en" "I HATE EVERYTHING" + } + "Rage Prefix Text 7" + { + "en" "RAAAAAAAAAAAAAAAAAAAAHHHHHH!!!!!!!!!!" + } + "Rage Prefix Text 8" + { + "en" "RFHSGDGTWF ZJHEHMTZMBHJTEMNVUETH" + } + "Rage Prefix Text 9" + { + "en" "Owned BITCH" + } + "Rage Prefix Text 10" + { + "en" "Let me touch you boy" + } + "Rage Prefix Text 11" + { + "en" "My hand + your head = Match made in heaven" + } + "Rage Prefix Text 12" + { + "en" "Guess what? Chicken butt" + } + "Rage Prefix Text 13" + { + "en" "This is getting pretty serious." + } + "Rage Prefix Text 14" + { + "en" "These hands are rated E for everyone" + } + "Rage Prefix Text 15" + { + "en" "I just took a shit" + } + "Rage Prefix Text 16" + { + "en" "I found out i have work tomorrow, day ruined" + } + "Rage Prefix Text 17" + { + "en" "I can't win with these kings gg ." + //This joke only works in english, for your own languge, make some other national joke + } + "Rage Prefix Text 18" + { + "en" "Just browsed 4chan, it was very good, my head enlightened." + } + "Rage Prefix Text 19" + { + "en" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + } + "Rage Prefix Text 20" + { + "en" ":trolley:" + } + "Rage Prefix Text 21" + { + "en" "bruh" + } + "Rage Prefix Text 22" + { + "en" "i hope no one looks at my plans while im sleeping" + } + "Rage Prefix Text 23" + { + "en" "HOO HAA" + } + "Rage Prefix Text 24" + { + "en" "Feeling like snorting cocain rn ngl fr fr" + } + "Rage Prefix Text 25" + { + "en" "I played minecraft" + } + "Rage Prefix Text 26" + { + "en" "I am like, super evil, dude, just kidding go kill yourself." + } + "Rage Prefix Text 27" + { + "en" "I hope youre lactose intollerant cus im about to milk someone." + } + "Rage Prefix Text 28" + { + "en" "Old times interitus is my bitch" + } + "Rage Prefix Text 29" + { + "en" "☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺☻☺" + } + "Rage Prefix Text 30" + { + "en" "♅ is looking mighty today. Let me grab that." + } + "Rage Prefix Text 31" + { + "en" "If you think liking a guy is gay, youre wrong, imagine liking a woman and putting up with their bullshit. now thats gay." + } + "Rage Prefix Text 32" + { + "en" "Niko sucks" + } + "Rage Prefix Text 33" + { + "en" "Zombie riot is full of SHIT!!" + } + "Rage Prefix Text 34" + { + "en" "Shoutout to my homies, they up in this bitch" + } + "Rage Prefix Text 35" + { + "en" "wat u want bitch" + } + "Rage Prefix Text 36" + { + "en" "You ever had gay thoughts? Act on them." + } + "Semi Healthy Prefix" + { + "en" "Semi Healthy Prefix" + } + "Semi Healthy" + { + "en" "Semi Healthy" + } + "Semi Healthy Prefix Desc" + { + "en" "Increases Max health by 5x, does not immedietly heal" + } + "Fat Prefix" + { + "en" "Fat Prefix" + } + "Fat" + { + "en" "Fat" + } + "Fat Prefix Desc" + { + "en" "Increases health by 2x, increases size by 1.35x, slows down npcs by 1.25x" + } + "Modifier+ Prefix" + { + "en" "Modifier+ Prefix" + } + "Modifier+" + { + "en" "Modifier+" + } + "Modifier+ Prefix Desc" + { + "en" "Gives 2 modifier chances to get additional chances" } } diff --git a/addons/sourcemod/translations/zombieriot.phrases.zombienames.txt b/addons/sourcemod/translations/zombieriot.phrases.zombienames.txt index a868576e0e..9fdf720ef2 100644 --- a/addons/sourcemod/translations/zombieriot.phrases.zombienames.txt +++ b/addons/sourcemod/translations/zombieriot.phrases.zombienames.txt @@ -5868,6 +5868,46 @@ "en" "Captino Menius" "ko" "캡티노 메니우스" } + "Zapmarker" + { + "en" "Zapmarker" + } + "Resource Collector" + { + "en" "Resource Collector" + } + "Victoria Gasleader" + { + "en" "Victorian Chemical Squad Leader" + } + "Demolitionist" + { + "en" "Demolitionist" + } + "Victorian Protector" + { + "en" "Victorian Protector" + } + "Airraider" + { + "en" "Airraider" + } + "Victorian Headhunter" + { + "en" "Victorian Headhunter" + } + "Chemical Specialist" + { + "en" "Chemical Specialist" + } + "Chemical Spreader" + { + "en" "Chemical Spreader" + } + "Giant Armored Medibot" + { + "en" "Giant Armored Medibot" + } "0h No it's Not Fair" { "en" "=Failed name="