Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spawn Delay and Responders Integrated #7

Merged
merged 20 commits into from
May 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
420 changes: 420 additions & 0 deletions Classic Heisting/managers/coreworldinstancemanager.lua

Large diffs are not rendered by default.

5,462 changes: 5,462 additions & 0 deletions Classic Heisting/managers/elementspawnenemygroupdelay.lua

Large diffs are not rendered by default.

21 changes: 19 additions & 2 deletions Classic Heisting/mod.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,27 @@
{ "hook_id" : "lib/network/matchmaking/networkmatchmakingsteam", "script_path": "network/matchmaking/networkmatchmakingsteam.lua" },
{ "hook_id" : "lib/network/matchmaking/networkmatchmakingepic", "script_path": "network/matchmaking/networkmatchmakingepic.lua" },
{ "hook_id" : "lib/network/base/networkpeer", "script_path": "network/base/networkpeer.lua" },
{ "hook_id" : "lib/network/base/basenetworksession", "script_path": "network/base/basenetworksession.lua" },
{ "hook_id" : "lib/network/base/basenetworksession", "script_path": "network/base/basenetworksession.lua" },
{ "hook_id" : "lib/units/beings/player/states/playerstandard", "script_path": "units/beings/player/states/playerstandard.lua" },
{ "hook_id" : "lib/setups/setup", "script_path": "setups/setup.lua" },
{"hook_id":"lib/units/pickups/ammoclip","script_path":"units/pickups/ammoclip.lua"}
{ "hook_id" : "lib/units/pickups/ammoclip","script_path":"units/pickups/ammoclip.lua"},
{ "hook_id" : "core/lib/managers/coreworldinstancemanager", "script_path" : "managers/coreworldinstancemanager.lua" },
{ "hook_id" : "lib/managers/mission/elementspawnenemygroup", "script_path" : "managers/elementspawnenemygroupdelay.lua" },
{ "hook_id" : "lib/tweak_data/charactertweakdata", "script_path" : "responders/charactertweakdata.lua" },
{ "hook_id" : "lib/units/civilians/logics/civilianlogicflee", "script_path" : "responders/civilianlogicflee.lua" },
{ "hook_id" : "lib/units/enemies/cop/actions/full_body/copactionhurt", "script_path" : "responders/copactionhurt.lua" },
{ "hook_id" : "lib/units/enemies/cop/copbrain", "script_path" : "responders/copbrain.lua" },
{ "hook_id" : "lib/units/enemies/cop/copdamage", "script_path" : "responders/copdamage.lua" },
{ "hook_id" : "lib/units/enemies/cop/logics/coplogicattack", "script_path" : "responders/coplogicattack.lua" },
{ "hook_id" : "lib/units/enemies/cop/logics/coplogicbase", "script_path" : "responders/coplogicbase.lua" },
{ "hook_id" : "lib/units/enemies/cop/logics/coplogictravel", "script_path" : "responders/coplogictravel.lua" },
{ "hook_id" : "lib/units/enemies/cop/copsound", "script_path" : "responders/copsound.lua" },
{ "hook_id" : "lib/units/props/carrydata", "script_path" : "responders/carrydata.lua" },
{ "hook_id" : "lib/units/props/drill", "script_path" : "responders/drill.lua" },
{ "hook_id" : "lib/units/weapons/trip_mine/tripminebase", "script_path" : "responders/tripminebase.lua" },
{ "hook_id" : "lib/managers/group_ai_states/groupaistatebase", "script_path" : "responders/groupaistatebase.lua" },
{ "hook_id" : "lib/managers/group_ai_states/groupaistatebesiege", "script_path" : "responders/groupaistatebesiege.lua" },
{ "hook_id" : "lib/tweak_data/groupaitweakdata", "script_path" : "responders/groupaitweakdata.lua" }
],
"updates" : [
{
Expand Down
3 changes: 3 additions & 0 deletions Classic Heisting/responders/carrydata.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Hooks:PostHook(CarryData, "on_pickup_SO_administered", "RR_on_pickup_SO_administered", function(self, thief)
thief:sound():say("l01", true) -- Get the loot!
end)
191 changes: 191 additions & 0 deletions Classic Heisting/responders/charactertweakdata.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
Hooks:PostHook(CharacterTweakData, "init", "RR_Set_Enemy_Chatter", function(self, tweak_data)
-- Speech prefix shit
local difficulty_index = tweak_data:difficulty_to_index(Global.game_settings and Global.game_settings.difficulty or "normal")
local job = Global.level_data and Global.level_data.level_id
if job == "nightclub" or job == "short2_stage1" or job == "jolly" or job == "spa" then
self.gangster.speech_prefix_p1 = "rt"
self.gangster.speech_prefix_p2 = nil
self.gangster.speech_prefix_count = 2
elseif job == "alex_2" then
self.gangster.speech_prefix_p1 = "ict"
self.gangster.speech_prefix_p2 = nil
self.gangster.speech_prefix_count = 2
elseif job == "welcome_to_the_jungle_1" then
self.gangster.speech_prefix_p1 = "bik"
self.gangster.speech_prefix_p2 = nil
self.gangster.speech_prefix_count = 2
else
self.gangster.speech_prefix_p1 = "lt"
self.gangster.speech_prefix_p2 = nil
self.gangster.speech_prefix_count = 2
end

-- No, they weren't supposed to sound like cops
self.mobster.speech_prefix_p1 = "rt"
self.mobster.speech_prefix_p2 = nil
self.mobster.speech_prefix_count = 2
self.biker.speech_prefix_p1 = "bik"
self.biker.speech_prefix_p2 = nil
self.biker.speech_prefix_count = 2

if tweak_data and tweak_data.levels then
local faction = tweak_data.levels:get_ai_group_type()
if faction == "america" then
-- Removed some radio filtered voices due to the player equipment lines
-- I am not interested in adding an option for the radio voices so don't bug me about it
-- These are required for the sabotaging power, drill and generic lines to play
self.heavy_swat.speech_prefix_p2 = "d"
self.fbi_heavy_swat.speech_prefix_p2 = "d"
self.shield.speech_prefix_p2 = "d"
self.shield.speech_prefix_count = 5 -- Shields can have l5d, which is a very distinctive voiceset that goes unused in vanilla
end
end

-- overkill please fix
self.gensec.speech_prefix_p1 = self._unit_prefixes.cop
self.cop.speech_prefix_p1 = self._unit_prefixes.cop -- no idea why this fucker is tied to swat
self.cop_scared.speech_prefix_p1 = self._unit_prefixes.cop -- no idea why this fucker is tied to swat
self.fbi.speech_prefix_p1 = self._unit_prefixes.cop -- no idea why this fucker is tied to swat
self.sniper.speech_prefix_p1 = self._unit_prefixes.cop -- unfiltered voice
self.shield.speech_prefix_p1 = self._unit_prefixes.heavy_swat

-- Give special enemies lines declaring they have spawned
self.tank.spawn_sound_event = self.tank.speech_prefix_p1 .. "_entrance" -- BULLDOZER, COMING THROUGH!!!
self.tank_medic.spawn_sound_event = self.tank_medic.speech_prefix_p1 .. "_entrance_elite" -- ELITE BULLDOZER, COMING THROUGH!!!
self.tank_mini.spawn_sound_event = self.tank_mini.speech_prefix_p1 .. "_entrance_elite" -- ELITE BULLDOZER, COMING THROUGH!!!
self.shield.spawn_sound_event = "shield_identification" -- knock knock, it's a cocking shield

if difficulty_index >= 8 then
self.taser.spawn_sound_event = self.taser.speech_prefix_p1 .. "_elite" -- Elite taser, coming through!
else
self.taser.spawn_sound_event = self.taser.speech_prefix_p1 .. "_entrance" -- Taser, Taser!
end

self.sniper.spawn_sound_event = "mga_deploy_snipers"

-- Security
self.gensec.chatter = {
aggressive = true,
contact = true,
clear_whisper = true
}
self.security.chatter = self.gensec.chatter
self.security_undominatable.chatter = self.gensec.chatter
self.security_mex.chatter = self.gensec.chatter
self.security_mex_no_pager.chatter = self.gensec.chatter

-- Cops
self.cop.chatter = {
aggressive = true,
contact = true,
clear = true,
clear_whisper = true,
saw = true,
ammo_bag = true,
doctor_bag = true,
first_aid_kit = true,
trip_mine = true,
sentry = true
}
-- SWAT
self.swat.chatter = {
entry = true,
aggressive = true,
retreat = true,
contact = true,
clear = true,
go_go = true,
push = true,
reload = true,
look_for_angle = true,
inpos = true,
saw = true,
ammo_bag = true,
doctor_bag = true,
first_aid_kit = true,
trip_mine = true,
sentry = true,
ready = true,
smoke = true,
flash_grenade = true,
open_fire = true
}
self.fbi.chatter = self.swat.chatter
self.fbi_swat.chatter = self.swat.chatter
self.city_swat.chatter = self.swat.chatter

-- Heavy SWAT
self.heavy_swat.chatter = {
entry = true,
aggressive = true,
retreat = true,
contact = true,
clear = true,
go_go = true,
push = true,
reload = true,
look_for_angle = true,
inpos = true,
saw = true,
trip_mine = true,
sentry = true,
ready = true,
smoke = true,
flash_grenade = true,
open_fire = true,
sabotagepower = true
}
self.fbi_heavy_swat.chatter = self.heavy_swat.chatter

-- Specials
self.tank.chatter = {
contact = true,
aggressive = true,
approachingspecial = true
}
self.tank_medic.chatter = self.tank.chatter
self.tank_mini.chatter = self.tank.chatter
self.spooc.chatter = {
cloakercontact = true,
go_go = true, --only used for russian cloaker
cloakeravoidance = true --only used for russian cloaker
}
self.shield.chatter = {
entry = true,
aggressive = true,
contact = true,
clear = true,
go_go = true,
push = true,
reload = true,
inpos = true,
look_for_angle = true,
saw = true,
trip_mine = true,
sentry = true,
ready = true,
follow_me = true,
open_fire = true
}
self.medic.chatter = {
aggressive = true,
contact = true
}
self.taser.chatter = {
contact = true,
aggressive = true,
approachingspecial = true
}

-- Gangsters
self.gangster.chatter = {
aggressive = true,
contact = true,
go_go = true
}
self.mobster.chatter = self.gangster.chatter
self.biker.chatter = self.gangster.chatter
self.biker_escape.chatter = self.gangster.chatter
self.bolivian.chatter = self.gangster.chatter
self.bolivian_indoors.chatter = self.gangster.chatter
end)
3 changes: 3 additions & 0 deletions Classic Heisting/responders/civilianlogicflee.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Hooks:PostHook(CivilianLogicFlee, "on_rescue_SO_administered", "RR_on_rescue_SO_administered", function(ignore_this, data, receiver_unit)
receiver_unit:sound():say("civ", true) -- Get the hostages!
end)
23 changes: 23 additions & 0 deletions Classic Heisting/responders/copactionhurt.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
local init_orig = CopActionHurt.init
function CopActionHurt:init(action_desc, ...)
if init_orig(self, action_desc, ...) then -- need to ensure the action actually started successfully
if not self._unit:base().nick_name then
local action_type = action_desc.hurt_type
if action_type == "counter_tased" or action_type == "taser_tased" then
if not self._unit:base():has_tag("taser") then
self._unit:sound():say("x01a_any_3p", true) -- should be fine to immediately play this after
end
elseif action_type == "hurt_sick" then
if self._unit:base():has_tag("law") and not self._unit:base():has_tag("special") or self._unit:base():has_tag("shield") then
self._unit:sound():say("ch3", true) --make cops scream in pain when affected ECM feedback
elseif self._unit:base():has_tag("medic")then
self._unit:sound():say("burndeath", true) --same for the medic with a similar sound, since they lack one
elseif self._unit:base():has_tag("taser") then
self._unit:sound():say("tasered", true) --same as his tased lines felt they fit best
end
end
end

return true
end
end
16 changes: 16 additions & 0 deletions Classic Heisting/responders/copbrain.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
local math_random = math.random
function CopBrain:on_suppressed(state)
self._logic_data.is_suppressed = state or nil

if self._current_logic.on_suppressed_state then
self._current_logic.on_suppressed_state(self._logic_data)

if state and self._logic_data.char_tweak.chatter.suppress then
if managers.groupai:state():chk_assault_active_atm() then
self._unit:sound():say(math_random() > 0.5 and "hlp" or "lk3a", true)
else
self._unit:sound():say("lk3b", true) --calmer lines for when the assault is off
end
end
end
end
13 changes: 13 additions & 0 deletions Classic Heisting/responders/copdamage.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Hooks:PreHook(CopDamage, "_on_damage_received", "RR_on_damage_received", function(self, damage_info)
local attacker_unit = damage_info and damage_info.attacker_unit
if Network:is_server() and damage_info.result.type == "death" and alive(attacker_unit) and attacker_unit:base() then -- if this gets run on clients, don't do anything
local weapon_unit = attacker_unit.inventory and attacker_unit:inventory() and attacker_unit:inventory():equipped_unit()
if weapon_unit and weapon_unit:base():is_category("saw") then
managers.groupai:state():_voice_saw(self._unit)
elseif attacker_unit:base().sentry_gun then
managers.groupai:state():_voice_sentry(self._unit)
elseif attacker_unit:base().is_tripmine then -- might not work since the tripmine might've been destroyed by now
managers.groupai:state():_voice_trip_mine(self._unit)
end
end
end)
89 changes: 89 additions & 0 deletions Classic Heisting/responders/coplogicattack.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
local math_random = math.random

local react_combat = AIAttentionObject.REACT_COMBAT

Hooks:PostHook(CopLogicAttack, "_upd_combat_movement", "RR_upd_combat_movement", function(data)
local chatter = data.char_tweak.chatter
if chatter and data.internal_data.flank_cover and chatter.look_for_angle and not data.is_converted then
managers.groupai:state():chk_say_enemy_chatter(data.unit, data.m_pos, "look_for_angle") -- I'll try and flank 'em!
end
end)

Hooks:PostHook(CopLogicAttack, "_chk_request_action_walk_to_cover_shoot_pos", "RR_chk_request_action_walk_to_cover_shoot_pos", function(data)
local chatter = data.char_tweak.chatter
if chatter and (chatter.push or chatter.go_go) and not data.is_converted and data.internal_data.advancing then
managers.groupai:state():chk_say_enemy_chatter(data.unit, data.m_pos, math_random() > 0.5 and "push" or "go_go") -- Puuuush! / Go, Go!
end
end)

Hooks:PreHook(CopLogicAttack, "action_complete_clbk", "RR_action_complete_clbk", function(data, action)
local chatter = data.char_tweak.chatter
if action:type() == "walk" and data.internal_data.moving_to_cover and action:expired() and chatter and (chatter.inpos or chatter.ready) and not data.is_converted then
managers.groupai:state():chk_say_enemy_chatter(data.unit, data.m_pos, math_random() > 0.5 and "ready" or "inpos") -- Ready! / I'm in position!
end
end)

function CopLogicAttack.aim_allow_fire(shoot, aim, data, my_data) -- doesn't really work as a posthook
local focus_enemy = data.attention_obj

if shoot then
if not my_data.firing then
data.unit:movement():set_allow_fire(true)

my_data.firing = true

local chatter = data.char_tweak.chatter
if not data.unit:in_slot(16) and not data.is_converted and chatter and chatter.aggressive then
if not data.unit:base():has_tag("special") then
if data.unit:base():has_tag("law") and data.unit:base()._tweak_table ~= "gensec" and data.unit:base()._tweak_table ~= "security" then
if managers.groupai:state():chk_assault_active_atm() and chatter.open_fire then
managers.groupai:state():chk_say_enemy_chatter(data.unit, data.m_pos, "open_fire")
else
managers.groupai:state():chk_say_enemy_chatter(data.unit, data.m_pos, "aggressive")
end
end
elseif not data.unit:base():has_tag("tank") and data.unit:base():has_tag("medic") then
managers.groupai:state():chk_say_enemy_chatter(data.unit, data.m_pos, "aggressive")
elseif data.unit:base():has_tag("shield") and (not my_data.shield_knock_cooldown or my_data.shield_knock_cooldown < data.t) then
if tweak_data:difficulty_to_index(Global.game_settings.difficulty) >= 8 then
data.unit:sound():play("hos_shield_indication_sound_terminator_style", nil, true)
else
data.unit:sound():play("shield_identification", nil, true)
end

my_data.shield_knock_cooldown = data.t + math_random(6, 12)
else
managers.groupai:state():chk_say_enemy_chatter(data.unit, data.m_pos, "contact")
end
end
end
elseif my_data.firing then
data.unit:movement():set_allow_fire(false)

my_data.firing = nil
end
end

local excluded_deployables = {
["trip_mine"] = true,
["sentry"] = true,
["sentry_gun_silent"] = true,
}

Hooks:PostHook(CopLogicAttack, "_upd_aim", "RR_upd_aim", function(data)
local focus_enemy = data.attention_obj
local chatter = data.char_tweak.chatter
if chatter and focus_enemy and react_combat <= focus_enemy.reaction and focus_enemy.verified and not data.unit:in_slot(16) and not data.is_converted then
if focus_enemy.is_person then
if chatter.reload and (focus_enemy.is_local_player and focus_enemy.unit:movement():current_state():_is_reloading() or focus_enemy.is_husk_player and focus_enemy.unit:anim_data().reload) then
managers.groupai:state():chk_say_enemy_chatter(data.unit, data.m_pos, "reload")
else
local equipment = managers.criminals:character_peer_id_by_unit(focus_enemy.unit)
equipment = equipment and managers.player:get_synced_deployable_equipment(equipment)
if equipment and equipment.deployable and equipment.amount > 0 and chatter[equipment.deployable] and not excluded_deployables[equipment.deployable] then
managers.groupai:state():chk_say_enemy_chatter(data.unit, data.m_pos, equipment.deployable)
end
end
end
end
end)
Loading
Loading