Skip to content

Commit

Permalink
biiiig shai upd
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitawastaken committed Oct 13, 2023
1 parent 2434431 commit 2d3ecea
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 41 deletions.
14 changes: 14 additions & 0 deletions lua/charactertweakdata.lua
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,15 @@ function CharacterTweakData:_presets(tweak_data, ...)
go_go = true,
}

presets.enemy_chatter.security = {
aggressive = true,
go_go = true,
contact = true,
suppress = true,
idle = true,
report = true
}

return presets
end

Expand Down Expand Up @@ -811,6 +820,11 @@ Hooks:PostHook(CharacterTweakData, "init", "eclipse_init", function(self)
self.biker_escape.chatter = self.presets.enemy_chatter.gangster
self.bolivian.chatter = self.presets.enemy_chatter.gangster
self.bolivian_indoors.chatter = self.presets.enemy_chatter.gangster
self.gensec.chatter = self.presets.enemy_chatter.security
self.security.chatter = self.presets.enemy_chatter.security
self.security_undominatable.chatter = self.presets.enemy_chatter.security
self.security_mex.chatter = self.presets.enemy_chatter.security
self.security_mex_no_pager.chatter = self.presets.enemy_chatter.security

-- if bot weapons and equipment is installed and fixed weapon balance is on don't make any further changes
if BotWeapons and BotWeapons.settings and BotWeapons.settings.weapon_balance then
Expand Down
117 changes: 117 additions & 0 deletions lua/civilianlogictravel.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
-- Improve civilian pathing by reordering checks and using direct paths if possible
Hooks:OverrideFunction(CivilianLogicTravel, "update", function (data)
local my_data = data.internal_data
local unit = data.unit
local objective = data.objective

if my_data.has_old_action then
CivilianLogicTravel._upd_stop_old_action(data, my_data)
return
elseif my_data.warp_pos then
local action_desc = {
body_part = 1,
type = "warp",
position = mvector3.copy(objective.pos),
rotation = objective.rot
}

if unit:movement():action_request(action_desc) then
CivilianLogicTravel._on_destination_reached(data)
end
return
end

if my_data.processing_advance_path or my_data.processing_coarse_path then
CivilianLogicEscort._upd_pathing(data, my_data)
end

if my_data.advancing then
return
end

if not my_data.advance_path and objective then
if not my_data.coarse_path then
local nav_seg, pos

if objective.follow_unit then
local follow_tracker = data.objective.follow_unit:movement():nav_tracker()
nav_seg = follow_tracker:nav_segment()
pos = follow_tracker:field_position()
else
nav_seg = objective.nav_seg
pos = managers.navigation._nav_segments[nav_seg].pos
end

my_data.coarse_path_index = 1
my_data.coarse_path = {
{
data.unit:movement():nav_tracker():nav_segment(),
mvector3.copy(data.m_pos)
},
{
nav_seg,
pos
}
}
end

if my_data.coarse_path_index >= #my_data.coarse_path then
objective.in_place = true

if objective.type ~= "escort" and objective.type ~= "act" and objective.type ~= "follow" and not objective.action_duration then
data.objective_complete_clbk(unit, objective)
else
CivilianLogicTravel.on_new_objective(data)
end

return
else
data.brain:rem_pos_rsrv("path")

local to_pos
if my_data.coarse_path_index == #my_data.coarse_path - 1 then
to_pos = CivilianLogicTravel._determine_exact_destination(data, objective)
else
to_pos = my_data.coarse_path[my_data.coarse_path_index + 1][2]
end

-- Check if direct path is possible
if math.abs(data.m_pos.z - to_pos.z) < 100 and not managers.navigation:raycast({ pos_from = data.m_pos, pos_to = to_pos }) then
my_data.advance_path = {
mvector3.copy(data.m_pos),
to_pos
}
else
my_data.processing_advance_path = true
unit:brain():search_for_path(my_data.advance_path_search_id, to_pos)

return
end
end
end

if my_data.advance_path then
if my_data.is_hostage then
my_data.advance_path = CivilianLogicTravel._optimize_path(my_data.advance_path)
end

my_data.starting_advance_action = true
my_data.advancing = data.unit:brain():action_request({
type = "walk",
body_part = 2,
nav_path = my_data.advance_path,
variant = objective and objective.haste or "walk",
end_rot = my_data.coarse_path_index == #my_data.coarse_path - 1 and objective and objective.rot or nil
})
my_data.starting_advance_action = false

if my_data.advancing then
my_data.advance_path = nil
data.brain:rem_pos_rsrv("path")
end

return
end

CopLogicBase._exit(data.unit, "idle")
end)
27 changes: 13 additions & 14 deletions lua/coplogicidle.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local REACT_AIM = AIAttentionObject.REACT_AIM
local REACT_ARREST = AIAttentionObject.REACT_ARREST
local REACT_COMBAT = AIAttentionObject.REACT_COMBAT


-- Make cops react more aggressively when appropriate (less stare, more shoot)
local _chk_reaction_to_attention_object_original = CopLogicIdle._chk_reaction_to_attention_object
function CopLogicIdle._chk_reaction_to_attention_object(data, attention_data, ...)
Expand Down Expand Up @@ -38,13 +39,7 @@ function CopLogicIdle._chk_reaction_to_attention_object(data, attention_data, ..

for u_key, other_crim_rec in pairs(managers.groupai:state():all_criminals()) do
local other_crim_attention_info = data.detected_attention_objects[u_key]
if
other_crim_attention_info
and (
other_crim_attention_info.is_deployable
or other_crim_attention_info.verified and other_crim_rec.assault_t and data.t - other_crim_rec.assault_t < other_crim_rec.unit:base():arrest_settings().aggression_timeout
)
then
if other_crim_attention_info and (other_crim_attention_info.is_deployable or other_crim_attention_info.verified and other_crim_rec.assault_t and data.t - other_crim_rec.assault_t < other_crim_rec.unit:base():arrest_settings().aggression_timeout) then
return attention_data.verified and REACT_COMBAT or attention_reaction
end
end
Expand All @@ -56,10 +51,12 @@ function CopLogicIdle._chk_reaction_to_attention_object(data, attention_data, ..
return math.min(attention_reaction, REACT_ARREST)
end


-- Fix defend_area objectives being force relocated to areas with players in them
-- Fix lost follow objectives not refreshing for criminals in idle logic and Jokers in attack logic
-- Use the old defend_area behavior for the hunt objective for which it makes much more sense
function CopLogicIdle._chk_relocate(data)
local my_data = data.internal_data
local objective = data.objective
local objective_type = objective and objective.type

Expand All @@ -73,7 +70,8 @@ function CopLogicIdle._chk_relocate(data)
return true
end

if objective.relocated_to and mvector3.equal(objective.relocated_to, unit_pos) then
local relocated_dis_sq = data.is_tied and my_data.advancing and objective.distance and (objective.distance * 0.5) ^ 2 or 100
if objective.relocated_to and mvector3.distance_sq(objective.relocated_to, unit_pos) < relocated_dis_sq then
return
elseif data.is_converted then
if not TeamAILogicIdle._check_should_relocate(data, data.internal_data, objective) then
Expand Down Expand Up @@ -104,10 +102,10 @@ function CopLogicIdle._chk_relocate(data)
end

local found_areas = {
[objective_area] = true,
[objective_area] = true
}
local areas_to_search = {
objective_area,
objective_area
}
local target_area

Expand Down Expand Up @@ -144,14 +142,13 @@ function CopLogicIdle._chk_relocate(data)
return
end

local my_data = data.internal_data

managers.groupai:state():on_criminal_jobless(data.unit)

return my_data ~= data.internal_data
end
end


-- Improve and simplify attention handling
-- Moved certain checks into their own functions for easier adjustments and improved target priority calculation
-- Enemies no longer put low priority on reviving players and will prefer keeping their current target if there's a priority tie
Expand Down Expand Up @@ -319,6 +316,7 @@ function CopLogicIdle._get_attention_weight(attention_data, att_unit, distance)
return 1 / weight_mul
end


-- Show hint to player when surrender is impossible
local on_intimidated_original = CopLogicIdle.on_intimidated
function CopLogicIdle.on_intimidated(data, amount, aggressor_unit, ...)
Expand Down Expand Up @@ -353,9 +351,10 @@ function CopLogicIdle.on_intimidated(data, amount, aggressor_unit, ...)
end
end


-- Play generic chatter during idle while unalerted
Hooks:PostHook(CopLogicIdle, "queued_update", "sh_queued_update", function(data)
Hooks:PostHook(CopLogicIdle, "queued_update", "sh_queued_update", function (data)
if data.cool and data.char_tweak.chatter and data.char_tweak.chatter.idle then
managers.groupai:state():chk_say_enemy_chatter(data.unit, data.m_pos, "idle")
end
end)
end)
10 changes: 8 additions & 2 deletions lua/coreunitdamage.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
-- Increase bulldozer armor health (SH)
-- Increase bulldozer armor health and increase planks durability (SH)
Hooks:PostHook(CoreBodyDamage, "init", "sh_init", function(self)
if self._body_element and self._unit:base() and self._unit:base().has_tag and (self._unit:base():has_tag("tank") or self._unit:base():has_tag("tank_elite")) then
if not self._body_element then
return
end

if self._unit:base() and self._unit:base().has_tag and (self._unit:base():has_tag("tank") or self._unit:base():has_tag("tank_elite")) then
local face_player_mul = managers.groupai:state():_get_balancing_multiplier(tweak_data.character.tank_armor_balance_mul)
if not CoreBodyDamage._tank_armor_multiplier then
CoreBodyDamage._tank_armor_multiplier = 1 / face_player_mul
end
self._body_element._damage_multiplier = self._body_element._name:find("glass") or CoreBodyDamage._tank_armor_multiplier
elseif self._body_element._name == "planks_body" then
self._body_element._damage_multiplier = 0.33
end
end)
20 changes: 20 additions & 0 deletions lua/groupaistatebase.lua
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,23 @@ Hooks:PreHook(GroupAIStateBase, "propagate_alert", "sh_propagate_alert", functio
alert_data[3] = math.max(alert_data[3], 500)
end
end)

-- Spawn events are probably not used anywhere, but for the sake of correctness, fix this function
-- All the functions that call this expect it to return true when it's used
function GroupAIStateBase:_try_use_task_spawn_event(t, target_area, task_type, target_pos, force)
target_pos = target_pos or target_area.pos

local max_dis_sq = 3000 ^ 2
for _, event_data in pairs(self._spawn_events) do
if (event_data.task_type == task_type or event_data.task_type == "any") and mvec_dis_sq(target_pos, event_data.pos) < max_dis_sq then
if force or math.random() < event_data.chance then
self._anticipated_police_force = self._anticipated_police_force + event_data.amount
self._police_force = self._police_force + event_data.amount
self:_use_spawn_event(event_data)
return true
else
event_data.chance = math.min(1, event_data.chance + event_data.chance_inc)
end
end
end
end
26 changes: 4 additions & 22 deletions lua/groupaistatebesiege.lua
Original file line number Diff line number Diff line change
Expand Up @@ -971,8 +971,10 @@ end
-- Make a generic group voice function instead of individual ones and make retiring groups play retreat lines
function GroupAIStateBesiege:_chk_say_group(group, chatter_type)
for _, unit_data in pairs(group.units) do
if unit_data.char_tweak.chatter[chatter_type] and self:chk_say_enemy_chatter(unit_data.unit, unit_data.m_pos, chatter_type) then
return true
if unit_data.char_tweak.chatter[chatter_type] and not unit_data.unit:brain():is_current_logic("intimidated") then
if self:chk_say_enemy_chatter(unit_data.unit, unit_data.m_pos, chatter_type) then
return true
end
end
end
end
Expand Down Expand Up @@ -1234,26 +1236,6 @@ Hooks:OverrideFunction(GroupAIStateBesiege, "_set_recon_objective_to_group", fun
})
end)

-- Spawn events are probably not used anywhere, but for the sake of correctness, fix this function
-- All the functions that call this expect it to return true when it's used
function GroupAIStateBase:_try_use_task_spawn_event(t, target_area, task_type, target_pos, force)
target_pos = target_pos or target_area.pos

local max_dis_sq = 3000 ^ 2
for _, event_data in pairs(self._spawn_events) do
if (event_data.task_type == task_type or event_data.task_type == "any") and mvec_dis_sq(target_pos, event_data.pos) < max_dis_sq then
if force or math.random() < event_data.chance then
self._anticipated_police_force = self._anticipated_police_force + event_data.amount
self._police_force = self._police_force + event_data.amount
self:_use_spawn_event(event_data)
return true
else
event_data.chance = math.min(1, event_data.chance + event_data.chance_inc)
end
end
end
end

-- New designated ponr ai state
GroupAIStatePonr = GroupAIStatePonr or class(GroupAIStateBesiege)

Expand Down
4 changes: 2 additions & 2 deletions lua/groupaitweakdata.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Hooks:PostHook(GroupAITweakData, "_init_chatter_data", "sh__init_chatter_data",
local duration_short = { 5, 10 }
local duration_medium = { 10, 20 }
local duration_long = { 20, 40 }
local radius_small = 800
local radius_large = 1200
local radius_small = 1000
local radius_large = 2000

for _, chatter in pairs(self.enemy_chatter) do
chatter.interval = interval_short
Expand Down
14 changes: 14 additions & 0 deletions lua/timergui.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Set an upper limit for how many times drills, saws, etc can randomly jam, based on their timers
Hooks:PreHook(TimerGui, "_set_jamming_values", "sh__set_jamming_values", function (self)
if self._can_jam then
self._jam_times = math.min(self._jam_times, math.ceil(self._timer / 60))
end
end)


-- Skip next scheduled jam if it's going to happen very shortly after unjamming
Hooks:PostHook(TimerGui, "set_jammed", "sh_set_jammed", function (self, jammed)
if not jammed and self._current_jam_timer and self._current_jam_timer < 5 / self:get_timer_multiplier() then
self._current_jam_timer = table.remove(self._jamming_intervals, 1)
end
end)
Loading

0 comments on commit 2d3ecea

Please sign in to comment.