Skip to content

Commit

Permalink
Merge branch 'cmss13-devs:master' into OT-ROCKET-REBALANCE
Browse files Browse the repository at this point in the history
  • Loading branch information
iloveloopers authored Apr 6, 2024
2 parents 4773f76 + 422f06e commit 1b01125
Show file tree
Hide file tree
Showing 140 changed files with 5,195 additions and 4,494 deletions.
1 change: 1 addition & 0 deletions code/__DEFINES/ARES.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define ARES_RECORD_MAINTENANCE "Maintenance Ticket"
#define ARES_RECORD_ACCESS "Access Ticket"
#define ARES_RECORD_FLIGHT "Flight Record"
#define ARES_RECORD_TECH "Tech Control Record"

/// Not by ARES logged through marine_announcement()
#define ARES_LOG_NONE 0
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/mob_hud.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define STATUS_HUD_XENO_CULTIST "24" // Whether they are a xeno cultist or not
#define HUNTER_CLAN "25" //Displays a colored icon to represent ingame Hunter Clans
#define HUNTER_HUD "26" //Displays various statuses on mobs for Hunters to identify targets
#define HOLOCARD_HUD "27" //Displays the holocards set by medical personnel

//data HUD (medhud, sechud) defines
#define MOB_HUD_SECURITY_BASIC 1
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@
// HIVE TRAITS
/// If the Hive is a Xenonid Hive
#define TRAIT_XENONID "t_xenonid"
/// If the hive or xeno can use objects.
#define TRAIT_OPPOSABLE_THUMBS "t_thumbs"
/// If the Hive delays round end (this is overridden for some hives). Does not occur naturally. Must be applied in events.
#define TRAIT_NO_HIVE_DELAY "t_no_hive_delay"
/// If the Hive uses it's colors on the mobs. Does not occur naturally, excepting the Mutated hive.
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/weapon_stats.dm
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ As such, don't expect any values assigned to common firearms to even consider ho
//How many ticks you have to wait between firing. Burst delay uses the same variable!
*/

#define FIRE_DELAY_TIER_AMR 30
#define FIRE_DELAY_TIER_VULTURE 20
#define FIRE_DELAY_TIER_SNIPER 15
#define FIRE_DELAY_TIER_1 12
#define FIRE_DELAY_TIER_2 10
#define FIRE_DELAY_TIER_3 9
Expand Down
2 changes: 1 addition & 1 deletion code/__DEFINES/xeno.dm
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@
// target_hive integer the target hive to see if the source_hive is allied to it.
#define HIVE_ALLIED_TO_HIVE(source_hive, target_hive) ((source_hive) == (target_hive) || GLOB.hive_datum[source_hive]?.faction_is_ally(GLOB.hive_datum[target_hive]?.internal_faction))

#define QUEEN_SPAWN_TIMEOUT (2 MINUTES)
#define QUEEN_SPAWN_TIMEOUT (1 MINUTES)

#define FIRE_IMMUNITY_NONE 0
#define FIRE_IMMUNITY_NO_DAMAGE (1<<0)
Expand Down
2 changes: 2 additions & 0 deletions code/_globalvars/global_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ GLOBAL_LIST_EMPTY(timelocks)
GLOBAL_LIST_INIT(available_specialist_sets, list(
"Scout Set",
"Sniper Set",
"Anti-materiel Sniper Set",
"Demolitionist Set",
"Heavy Grenadier Set",
"Pyro Set"
Expand All @@ -502,6 +503,7 @@ GLOBAL_LIST_INIT(available_specialist_kit_boxes, list(
"Sniper" = 2,
"Scout" = 2,
"Demo" = 2,
"Anti-materiel Sniper" = 2,
))

/proc/init_global_referenced_datums()
Expand Down
8 changes: 4 additions & 4 deletions code/controllers/subsystem/minimap.dm
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ SUBSYSTEM_DEF(minimaps)
data["canDraw"] = FALSE
data["canViewTacmap"] = TRUE
data["canViewCanvas"] = FALSE
data["isXeno"] = FALSE
data["isxeno"] = FALSE

return data

Expand All @@ -781,7 +781,7 @@ SUBSYSTEM_DEF(minimaps)
var/is_xeno = istype(xeno)
var/faction = is_xeno ? xeno.hivenumber : user.faction

data["isXeno"] = is_xeno
data["isxeno"] = is_xeno
data["canViewTacmap"] = is_xeno
data["canViewCanvas"] = faction == FACTION_MARINE || faction == XENO_HIVE_NORMAL

Expand All @@ -799,7 +799,7 @@ SUBSYSTEM_DEF(minimaps)
data["canDraw"] = FALSE
data["canViewTacmap"] = FALSE
data["canViewCanvas"] = TRUE
data["isXeno"] = FALSE
data["isxeno"] = FALSE

return data

Expand All @@ -811,7 +811,7 @@ SUBSYSTEM_DEF(minimaps)
data["canDraw"] = FALSE
data["canViewTacmap"] = FALSE
data["canViewCanvas"] = TRUE
data["isXeno"] = TRUE
data["isxeno"] = TRUE

return data

Expand Down
1 change: 1 addition & 0 deletions code/controllers/subsystem/objectives_controller.dm
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ SUBSYSTEM_DEF(objectives)

ai_silent_announcement(message, ":v", TRUE)
ai_silent_announcement(message, ":t", TRUE)
log_ares_tech(MAIN_AI_SYSTEM, FALSE, "TECH REPORT", "[round(tree.points, 0.1)] points available.", 0)
tree.total_points_last_sitrep = tree.total_points

next_sitrep = world.time + SITREP_INTERVAL
Expand Down
2 changes: 2 additions & 0 deletions code/datums/action.dm
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@
var/mob/living/carbon/human/human = owner
if(human.body_position == STANDING_UP)
return TRUE
if((HAS_TRAIT(owner, TRAIT_OPPOSABLE_THUMBS)) && !owner.is_mob_incapacitated())
return TRUE

/datum/action/item_action/update_button_icon()
button.overlays.Cut()
Expand Down
1 change: 1 addition & 0 deletions code/datums/ammo/ammo.dm
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@
P.generate_bullet(GLOB.ammo_list[bonus_projectiles_type]) //No bonus damage or anything.
P.accuracy = round(P.accuracy * original_P.accuracy/initial(original_P.accuracy)) //if the gun changes the accuracy of the main projectile, it also affects the bonus ones.
original_P.give_bullet_traits(P)
P.bonus_projectile_check = 2 //It's a bonus projectile!

var/total_scatter_angle = P.scatter
final_angle += rand(-total_scatter_angle, total_scatter_angle)
Expand Down
111 changes: 98 additions & 13 deletions code/datums/ammo/bullet/sniper.dm
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,104 @@
damage = 125
shell_speed = AMMO_SPEED_TIER_6

/datum/ammo/bullet/sniper/anti_materiel/on_hit_mob(mob/M,obj/projectile/P)
if((P.projectile_flags & PROJECTILE_BULLSEYE) && M == P.original)
var/mob/living/L = M
var/size_damage_mod = 0.8
if(isxeno(M))
var/mob/living/carbon/xenomorph/target = M
if(target.mob_size >= MOB_SIZE_XENO)
size_damage_mod += 0.6
if(target.mob_size >= MOB_SIZE_BIG)
size_damage_mod += 0.6
L.apply_armoured_damage(damage*size_damage_mod, ARMOR_BULLET, BRUTE, null, penetration)
// 180% damage to all targets (225), 240% (300) against non-Runner xenos, and 300% against Big xenos (375). -Kaga
to_chat(P.firer, SPAN_WARNING("Bullseye!"))
/datum/ammo/bullet/sniper/anti_materiel/on_hit_mob(mob/target_mob,obj/projectile/aimed_projectile)

var/mob/living/living_target = target_mob

if((aimed_projectile.projectile_flags & PROJECTILE_BULLSEYE) && target_mob == aimed_projectile.original)

var/amr_counter = 0
var/datum/weakref/old_target = null // This is used to let xenos know when they're no longer targeted.

var/mob/living/carbon/human/human_firer
var/image/focused_fire_marker_temp = image('icons/mob/hud/hud.dmi', target_mob, "hudeye")

if(istype(aimed_projectile.firer, /mob/living/carbon/human)) // Preps the Focused Fire marker.
human_firer = aimed_projectile.firer
focused_fire_marker_temp.color = human_firer.assigned_squad?.chat_color

if(target_mob.icon_size > world.icon_size) // Centers marker on their tile.
focused_fire_marker_temp.pixel_x = (target_mob.icon_size / 4)

if(istype(aimed_projectile.shot_from, /obj/item/weapon/gun/rifle/sniper/XM43E1)) // Calculates the Focus Counter.
var/obj/item/weapon/gun/rifle/sniper/XM43E1/amr = aimed_projectile.shot_from

old_target = amr.focused_fire_target

if(target_mob == (amr.focused_fire_target?.resolve()))
if(amr.focused_fire_counter < 2) // Can stack up to twice.
amr.focused_fire_counter += 1
else
amr.focused_fire_counter = 2
else // If it's a new target
amr.focused_fire_counter = 0 // Stacks to 0
if(human_firer && !(target_mob.is_dead()))
human_firer.client?.images -= human_firer.focused_fire_marker // Remove old marker
qdel(human_firer.focused_fire_marker)
human_firer.focused_fire_marker = focused_fire_marker_temp // Store new marker ref
human_firer.client?.images += focused_fire_marker_temp // Add new marker

amr_counter = amr.focused_fire_counter + 1
amr.focused_fire_target = WEAKREF(target_mob)

var/size_damage_mod = 0.8 // 1.8x vs Non-Xenos (225)
var/size_current_health_damage = 0 // % Current Health calculation, only used for Xeno calculations at the moment.
var/focused_fire_active = 0 // Whether to try and use focused fire calculations or not, for that kind of target.

if(isxeno(target_mob))
var/mob/living/carbon/xenomorph/target = target_mob
size_damage_mod -= 0.2 // Down to 1.6x damage, 200.
size_current_health_damage = 0.1 // 1.6x Damage + 10% current health (200 + 10%, 223 vs Runners)

if(target.mob_size >= MOB_SIZE_XENO && (target.caste_type != XENO_CASTE_DEFENDER))
size_current_health_damage += 0.1 // 1.6x Damage + 20% current health
focused_fire_active = 1 // Focus Fire Required. Only deals 50% bonus damage on a first Aimed Shot, then 75%, then 100%. Resets with a successful aimed shot on another target.

if(target.mob_size >= MOB_SIZE_BIG && (target.caste_type != XENO_CASTE_DEFENDER))
size_damage_mod -= 0.6 // Down to 1x Damage.
size_current_health_damage += 0.1 // 1x Damage + 30% current health.
focused_fire_active = 1
// Most T3s have around 650 to 700 HP, meaning the health modifier grants a MAXIMUM of around 195-210 damage for a total max of 320-335. This is fully focused (3 shots) and at max HP.
// Queen takes around 275 at max health and unfocused, 425 fully focused. Defender only takes 200 damage, even while fortified, but still causes falloff like a Big Xeno.
// At low health, does little more than a normal shot. Does WORSE than a normal shot if unfocused and hitting through blockers, all of which stack to reduce it.

var/final_xeno_damage = ((damage * size_damage_mod) + ((target.health + damage) * size_current_health_damage))

if(focused_fire_active && amr_counter) // If this is a target that needs to be focus-fired and the gun supports it, reduce bonus damage to 50%, then 75%, then 100%
// If amr_counter is 0, then the gun likely doesn't have the tracker functions, so skip this and deal normal damage.
final_xeno_damage *= (0.25 + (0.25 * amr_counter))

living_target.apply_armoured_damage((final_xeno_damage), ARMOR_BULLET, BRUTE, null, penetration)

else
living_target.apply_armoured_damage((damage*size_damage_mod), ARMOR_BULLET, BRUTE, null, penetration)

// Base 1.8x damage to non-xeno targets (225), 1.6x + 10% current against Runners and Defenders (223), 1.6x + 20% current health against most non-Runner xenos, and +30% current health against Big xenos. -Kaga
// This applies after pen reductions. After hitting 1 other thing, it deals 80% damage, or 40% after hitting a dense wall or big xeno.

if((focused_fire_active || isxeno(target_mob)) && !(target_mob.is_dead()))
switch(amr_counter)
if(1)
to_chat(aimed_projectile.firer, SPAN_WARNING("One hit! You begin to carefully track the target's movements."))
if(isxeno(target_mob) && isxeno(old_target?.resolve()))
var/mob/living/carbon/xenomorph/old_xeno = old_target.resolve()
var/mob/living/carbon/xenomorph/new_xeno = target_mob
if((old_xeno.hive == new_xeno.hive) && !(old_xeno.stat)) // Must be in same hive and conscious
to_chat(old_xeno,SPAN_XENOLEADER("The feeling of looming danger fades as we sense that another sister has been targeted instead."))
if(2)
to_chat(aimed_projectile.firer, SPAN_WARNING("Two hits! You're starting to get a good read on the target's patterns."))
if(3)
to_chat(aimed_projectile.firer, SPAN_WARNING("Bullseye! You're fully focused on the target."))
else
to_chat(aimed_projectile.firer, SPAN_WARNING("Bullseye!"))
else
to_chat(aimed_projectile.firer, SPAN_WARNING("Bullseye!"))

/datum/ammo/bullet/sniper/anti_materiel/set_bullet_traits()
. = ..()
LAZYADD(traits_to_give, list(
BULLET_TRAIT_ENTRY(/datum/element/bullet_trait_penetrating/weak)
))

/datum/ammo/bullet/sniper/anti_materiel/vulture
damage = 400 // Fully intended to vaporize anything smaller than a mini cooper
Expand Down
50 changes: 25 additions & 25 deletions code/datums/elements/bullet_trait/damage_boost.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,10 @@ GLOBAL_LIST_INIT(damage_boost_vehicles, typecacheof(/obj/vehicle/multitile))
/// A typecache of objs or turfs that, upon being hit, boost the damage of the attached projectile
var/list/damage_boosted_atoms

//vars for dealing with interaction issues with the Penetrating trait
var/boosted_hits
var/last_damage_mult

//allows for nuance in Breaching-Resistant interactions
var/active_damage_mult
var/atom_type

//var for dealing with bonus projectiles
var/bonus_projectile_check

/**
* vars:
* * damage_mult - the damage multiplier to be applied if the bullet hits an atom whose type is in `breaching_objs`
Expand All @@ -51,11 +44,8 @@ GLOBAL_LIST_INIT(damage_boost_vehicles, typecacheof(/obj/vehicle/multitile))

src.damage_mult = damage_mult
src.damage_boosted_atoms = damage_boosted_atoms
src.boosted_hits = 0
src.last_damage_mult = 1
src.active_damage_mult = 1
src.atom_type = 0
src.bonus_projectile_check = 0

RegisterSignal(target, list(
COMSIG_BULLET_PRE_HANDLE_OBJ,
Expand All @@ -68,17 +58,17 @@ GLOBAL_LIST_INIT(damage_boost_vehicles, typecacheof(/obj/vehicle/multitile))
//add more cases for other interactions (switch doesn't seem to work with istype)
else return 0

/datum/element/bullet_trait_damage_boost/proc/handle_bullet(obj/projectile/P, atom/A)
/datum/element/bullet_trait_damage_boost/proc/handle_bullet(obj/projectile/boosted_projectile, atom/hit_atom)
SIGNAL_HANDLER

atom_type = check_type(A)
atom_type = check_type(hit_atom)

switch(atom_type)
if("door")
var/obj/structure/machinery/door/D = A
if(D.masterkey_resist)
if(D.masterkey_mod)
active_damage_mult = damage_mult * D.masterkey_mod
var/obj/structure/machinery/door/hit_door = hit_atom
if(hit_door.masterkey_resist)
if(hit_door.masterkey_mod)
active_damage_mult = damage_mult * hit_door.masterkey_mod
else
active_damage_mult = 1 //no bonus damage
else
Expand All @@ -87,12 +77,22 @@ GLOBAL_LIST_INIT(damage_boost_vehicles, typecacheof(/obj/vehicle/multitile))
else
active_damage_mult = damage_mult

if(boosted_hits > 0)
if(bonus_projectile_check == P.damage)
P.damage = P.damage / last_damage_mult
boosted_hits--
if(damage_boosted_atoms[A.type])
P.damage = round(P.damage * active_damage_mult)
last_damage_mult = active_damage_mult
boosted_hits++
bonus_projectile_check = P.damage

if(boosted_projectile.damage_boosted && ((boosted_projectile.last_atom_signaled?.resolve()) != hit_atom) && (!boosted_projectile.bonus_projectile_check))
//If this is after a boosted hit, the last atom that procced this isn't the same as the current target, and this isn't a bonus projectile sharing the same damage_boost
if(!boosted_projectile.last_damage_mult) //Make sure stored mult isn't 0
boosted_projectile.last_damage_mult = 1

boosted_projectile.damage = boosted_projectile.damage / boosted_projectile.last_damage_mult //Reduce the damage back to normal
boosted_projectile.damage_boosted-- //Mark that damage has been returned to normal.

if(damage_boosted_atoms[hit_atom.type]) //If hitting a valid atom for damage boost
boosted_projectile.damage = round(boosted_projectile.damage * active_damage_mult) //Modify Damage by multiplier

if (active_damage_mult)
boosted_projectile.last_damage_mult = active_damage_mult //Save multiplier for next check
else
boosted_projectile.last_damage_mult = 1

boosted_projectile.damage_boosted++ //Mark that a boosted hit occurred.
boosted_projectile.last_atom_signaled = WEAKREF(hit_atom) //Save the current triggering atom to the projectile
60 changes: 60 additions & 0 deletions code/datums/elements/bullet_trait/penetrating/weak.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/datum/element/bullet_trait_penetrating/weak
// Generic bullet trait vars
element_flags = ELEMENT_DETACH|ELEMENT_BESPOKE
id_arg_index = 4

/// For each thing this hits, how much damage it loses normally. This can be modified by what it penetrates later.
var/damage_percent_lost_per_hit = 20
// XM43E1 AMR: First target takes full damage, each subsequent target takes at least 20% less damage (increased for large mobs and dense turfs), 25 from base 125 damage.

/// For each thing this hits, how much distance it loses normally.
distance_loss_per_hit = 4
// XM43E1 AMR: Hits 7 things at most, at point blank, with no additional modifiers. This greatly increases at actual sniping ranges.

/// How many times more effective turfs are at slowing down the projectile normally, reducing both range and damage.
var/turf_hit_slow_mult = 3
// XM43E1 AMR: Unable to hit anything through more than 2 walls, less at maximum ranges. Pens 2 walls at 8 tiles or less, 1 at 20 tiles or less, and can't wallbang through normal walls at maximum range.
// Also loses 75 damage with each normal wall pen.

/datum/element/bullet_trait_penetrating/weak/Attach(datum/target, distance_loss_per_hit = 4, damage_percent_lost_per_hit = 20, turf_hit_slow_mult = 3)
. = ..()
if(. == ELEMENT_INCOMPATIBLE)
return

src.damage_percent_lost_per_hit = damage_percent_lost_per_hit
src.turf_hit_slow_mult = turf_hit_slow_mult

/datum/element/bullet_trait_penetrating/weak/handle_passthrough_movables(obj/projectile/bullet, atom/movable/hit_movable, did_hit)
if(did_hit)
var/slow_mult = 1
if(ismob(hit_movable))
var/mob/mob = hit_movable
if(mob.mob_size >= MOB_SIZE_BIG) // Big Xenos (including fortified Defender) can soak hits and greatly reduce penetration.
slow_mult = 2 // 8 tiles of range lost per Big hit. At point blank, this comes out to only 3 targets. At sniping ranges, even a single one can stop the bullet dead.

bullet.distance_travelled += (distance_loss_per_hit * slow_mult)

bullet.damage -= (damage_percent_lost_per_hit * slow_mult)

return COMPONENT_BULLET_PASS_THROUGH


/datum/element/bullet_trait_penetrating/weak/handle_passthrough_turf(obj/projectile/bullet, turf/closed/wall/hit_wall)
var/slow_mult = turf_hit_slow_mult

// Better penetration against Membranes to still be able to counter Boilers at most ranges. Still loses 4 tiles of range and 25 damage per.
if(istype(hit_wall, /turf/closed/wall/resin/membrane))
if(istype(hit_wall, /turf/closed/wall/resin/membrane/thick))
slow_mult = 1.5
else
slow_mult = 1

bullet.distance_travelled += (distance_loss_per_hit * slow_mult)

bullet.damage *= (1 - (damage_percent_lost_per_hit * slow_mult * 0.01))

if(!istype(hit_wall))
return COMPONENT_BULLET_PASS_THROUGH

if(!hit_wall.hull)
return COMPONENT_BULLET_PASS_THROUGH
Loading

0 comments on commit 1b01125

Please sign in to comment.