Skip to content

Commit

Permalink
fix shotgunbase crash & remove obsolete drill code
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitawastaken committed Dec 2, 2023
1 parent 683645f commit ef49011
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 88 deletions.
32 changes: 0 additions & 32 deletions lua/drill.lua

This file was deleted.

145 changes: 90 additions & 55 deletions lua/raycastweaponbase.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ local mvec_to = Vector3()
local mvec_right_ax = Vector3()
local mvec_up_ay = Vector3()
local mvec_spread_direction = Vector3()
local mvec3_norm = mvector3.normalize
local mvec3_set = mvector3.set
local mvec3_mul = mvector3.multiply
local mvec3_add = mvector3.add
local math_clamp = math.clamp

-- lower damage on shield pen
function RaycastWeaponBase:_fire_raycast(user_unit, from_pos, direction, dmg_mul, shoot_player, spread_mul, autohit_mul, suppr_mul)
Expand All @@ -43,54 +48,56 @@ function RaycastWeaponBase:_fire_raycast(user_unit, from_pos, direction, dmg_mul
spread_mul = spread_mul or 1

mvector3.cross(mvec_right_ax, direction, math.UP)
mvector3.normalize(mvec_right_ax)
mvec3_norm(mvec_right_ax)
mvector3.cross(mvec_up_ay, direction, mvec_right_ax)
mvector3.normalize(mvec_up_ay)
mvector3.set(mvec_spread_direction, direction)
mvec3_norm(mvec_up_ay)
mvec3_set(mvec_spread_direction, direction)

local theta = math.random() * 360

mvector3.multiply(mvec_right_ax, math.rad(math.sin(theta) * math.random() * spread_x * spread_mul))
mvector3.multiply(mvec_up_ay, math.rad(math.cos(theta) * math.random() * spread_y * spread_mul))
mvector3.add(mvec_spread_direction, mvec_right_ax)
mvector3.add(mvec_spread_direction, mvec_up_ay)
mvector3.set(mvec_to, mvec_spread_direction)
mvector3.multiply(mvec_to, ray_distance)
mvector3.add(mvec_to, from_pos)
mvec3_mul(mvec_right_ax, math.rad(math.sin(theta) * math.random() * spread_x * spread_mul))
mvec3_mul(mvec_up_ay, math.rad(math.cos(theta) * math.random() * spread_y * spread_mul))
mvec3_add(mvec_spread_direction, mvec_right_ax)
mvec3_add(mvec_spread_direction, mvec_up_ay)
mvec3_set(mvec_to, mvec_spread_direction)
mvec3_mul(mvec_to, ray_distance)
mvec3_add(mvec_to, from_pos)

local ray_hits, hit_enemy = self:_collect_hits(from_pos, mvec_to)
local auto_hit_candidate, suppression_enemies = self:check_autoaim(from_pos, direction)
local ray_hits, hit_enemy, enemies_hit = self:_collect_hits(from_pos, mvec_to)

if suppression_enemies and self._suppression then
result.enemies_in_cone = suppression_enemies
end

if self._autoaim then
if self._autoaim and self._autohit_data then
local weight = 0.1

if auto_hit_candidate and not hit_enemy then
local autohit_chance = 1 - math.clamp((self._autohit_current - self._autohit_data.MIN_RATIO) / (self._autohit_data.MAX_RATIO - self._autohit_data.MIN_RATIO), 0, 1)
if hit_enemy then
self._autohit_current = (self._autohit_current + weight) / (1 + weight)
else
local auto_hit_candidate, enemies_to_suppress = self:check_autoaim(from_pos, direction, nil, nil, nil, true)
result.enemies_in_cone = enemies_to_suppress or false

if autohit_mul then
autohit_chance = autohit_chance * autohit_mul
end
if auto_hit_candidate then
local autohit_chance = self:get_current_autohit_chance_for_roll()

if math.random() < autohit_chance then
self._autohit_current = (self._autohit_current + weight) / (1 + weight)
if autohit_mul then
autohit_chance = autohit_chance * autohit_mul
end

if math.random() < autohit_chance then
self._autohit_current = (self._autohit_current + weight) / (1 + weight)

mvector3.set(mvec_spread_direction, auto_hit_candidate.ray)
mvector3.set(mvec_to, mvec_spread_direction)
mvector3.multiply(mvec_to, ray_distance)
mvector3.add(mvec_to, from_pos)
mvec3_set(mvec_spread_direction, auto_hit_candidate.ray)
mvec3_set(mvec_to, mvec_spread_direction)
mvec3_mul(mvec_to, ray_distance)
mvec3_add(mvec_to, from_pos)

ray_hits, hit_enemy = self:_collect_hits(from_pos, mvec_to)
ray_hits, hit_enemy, enemies_hit = self:_collect_hits(from_pos, mvec_to)
end
end
end

if hit_enemy then
self._autohit_current = (self._autohit_current + weight) / (1 + weight)
elseif auto_hit_candidate then
self._autohit_current = self._autohit_current / (1 + weight)
if hit_enemy then
self._autohit_current = (self._autohit_current + weight) / (1 + weight)
elseif auto_hit_candidate then
self._autohit_current = self._autohit_current / (1 + weight)
end
end
end

Expand All @@ -115,25 +122,25 @@ function RaycastWeaponBase:_fire_raycast(user_unit, from_pos, direction, dmg_mul
end

if dmg > 0 then
local hit_result = self._bullet_class:on_collision(hit, self._unit, user_unit, dmg)
local hit_result = self:bullet_class():on_collision(hit, self._unit, user_unit, dmg)
hit_through_wall = hit_through_wall or hit.unit:in_slot(self.wall_mask)
hit_through_shield = hit_through_shield or hit.unit:in_slot(self.shield_mask) and alive(hit.unit:parent())

if hit_result then
hit.damage_result = hit_result
hit_anyone = true
hit_count = hit_count + 1

if hit_result.type == "death" then
local unit_type = hit.unit:base() and hit.unit:base()._tweak_table
local unit_base = hit.unit:base()
local unit_type = unit_base and unit_base._tweak_table
local is_civilian = unit_type and is_civ_f(unit_type)

if not is_civilian then
cop_kill_count = cop_kill_count + 1
end

hit_through_wall = hit_through_wall or hit.unit:in_slot(self.wall_mask)
hit_through_shield = hit_through_shield or hit.unit:in_slot(self.shield_mask) and alive(hit.unit:parent())

self:_check_kill_achievements(cop_kill_count, unit_type, is_civilian, hit_through_wall, hit_through_shield)
self:_check_kill_achievements(cop_kill_count, unit_base, unit_type, is_civilian, hit_through_wall, hit_through_shield)
end
end
end
Expand All @@ -147,7 +154,7 @@ function RaycastWeaponBase:_fire_raycast(user_unit, from_pos, direction, dmg_mul
self._shot_fired_stats_table.hit = hit_anyone
self._shot_fired_stats_table.hit_count = hit_count

if (not self._ammo_data or not self._ammo_data.ignore_statistic) and not self._rays then
if not self._ammo_data or not self._ammo_data.ignore_statistic then
managers.statistics:shot_fired(self._shot_fired_stats_table)
end
end
Expand All @@ -156,12 +163,28 @@ function RaycastWeaponBase:_fire_raycast(user_unit, from_pos, direction, dmg_mul

if (not furthest_hit or furthest_hit.distance > 600) and alive(self._obj_fire) then
self._obj_fire:m_position(self._trail_effect_table.position)
mvector3.set(self._trail_effect_table.normal, mvec_spread_direction)
mvec3_set(self._trail_effect_table.normal, mvec_spread_direction)

local trail = World:effect_manager():spawn(self._trail_effect_table)

if furthest_hit then
World:effect_manager():set_remaining_lifetime(trail, math.clamp((furthest_hit.distance - 600) / 10000, 0, furthest_hit.distance))
World:effect_manager():set_remaining_lifetime(trail, math_clamp((furthest_hit.distance - 600) / 10000, 0, furthest_hit.distance))
end
end

if result.enemies_in_cone == nil then
result.enemies_in_cone = self._suppression and self:check_suppression(from_pos, direction, enemies_hit) or nil
elseif enemies_hit and self._suppression then
result.enemies_in_cone = result.enemies_in_cone or {}
local all_enemies = managers.enemy:all_enemies()

for u_key, enemy in pairs(enemies_hit) do
if all_enemies[u_key] then
result.enemies_in_cone[u_key] = {
error_mul = 1,
unit = enemy
}
end
end
end

Expand Down Expand Up @@ -191,7 +214,9 @@ function RaycastWeaponBase.collect_hits(from, to, setup_data)
hit_enemy = hit.unit:in_slot(enemy_mask)
end

return ray_hits, hit_enemy
return ray_hits, hit_enemy, hit_enemy and {
[hit.unit:key()] = hit.unit
} or nil
end

local can_shoot_through_wall = setup_data.can_shoot_through_wall
Expand All @@ -208,31 +233,41 @@ function RaycastWeaponBase.collect_hits(from, to, setup_data)
ray_hits = World:raycast_all("ray", from, to, "slot_mask", bullet_slotmask, "ignore_unit", ignore_unit)
end

local units_hit = {}
local unique_hits = {}
local enemies_hit = {}
local unit, u_key, is_enemy = nil
local units_hit = {}
local in_slot_func = Unit.in_slot
local has_ray_type_func = Body.has_ray_type

for i, hit in ipairs(ray_hits) do
if not units_hit[hit.unit:key()] then
units_hit[hit.unit:key()] = true
unit = hit.unit
u_key = unit:key()

if not units_hit[u_key] then
units_hit[u_key] = true
unique_hits[#unique_hits + 1] = hit
hit.hit_position = hit.position
hit_enemy = hit_enemy or hit.unit:in_slot(enemy_mask)
local weak_body = hit.body:has_ray_type(ai_vision_ids)
weak_body = weak_body or hit.body:has_ray_type(bulletproof_ids)
is_enemy = in_slot_func(unit, enemy_mask)

if is_enemy then
enemies_hit[u_key] = unit
hit_enemy = true
end

if not can_shoot_through_enemy and hit_enemy then
if not can_shoot_through_enemy and is_enemy then
break
elseif not can_shoot_through_wall and hit.unit:in_slot(wall_mask) and weak_body then
elseif not can_shoot_through_shield and in_slot_func(unit, shield_mask) then
break
elseif not can_shoot_through_shield and hit.unit:in_slot(shield_mask) then
elseif not can_shoot_through_wall and in_slot_func(unit, wall_mask) and (has_ray_type_func(hit.body, ai_vision_ids) or has_ray_type_func(hit.body, bulletproof_ids)) then
break
elseif hit.unit:in_slot(shield_mask) and (hit.unit:name():key() == "af254947f0288a6c" or hit.unit:name():key() == "15cbabccf0841ff8") and not can_shoot_through_titan_shield then -- hi thanks resmod if you're reading this :)
elseif hit.unit:in_slot(shield_mask) and (hit.unit:name():key() == "af254947f0288a6c" or hit.unit:name():key() == "15cbabccf0841ff8") then -- hi thanks resmod if you're reading this :)
break
end
end
end

return unique_hits, hit_enemy
return unique_hits, hit_enemy, hit_enemy and enemies_hit or nil
end

-- Auto Fire Sound Fix
Expand Down
1 change: 0 additions & 1 deletion supermod.xml
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@
<post :hook_id="incendiarygrenade"/>
<post :hook_id="grenadebase"/>
</group>
<post :hook_id="props/drill"/>
<post :hook_id="projectiles/projectilebase"/>
<post :hook_id="shotgun/shotgunbase"/>
<post :hook_id="akimboweaponbase"/>
Expand Down

0 comments on commit ef49011

Please sign in to comment.