Skip to content

Commit

Permalink
Merge branch 'master' into upstream-mirror-1547
Browse files Browse the repository at this point in the history
  • Loading branch information
ReezeBL authored Mar 22, 2024
2 parents 1506d42 + f0d5494 commit d7c9871
Show file tree
Hide file tree
Showing 73 changed files with 2,576 additions and 4 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/icon_smoothing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ DEFINE_BITFIELD(smoothing_junction, list(
#define SMOOTH_GROUP_SHUTTERS S_OBJ(75)

#define SMOOTH_GROUP_WATER S_OBJ(76) ///obj/effect/abstract/liquid_turf

#define SMOOTH_GROUP_WIREWEED S_OBJ(77)
//NOVA EDIT END

/// Performs the work to set smoothing_groups and canSmoothWith.
Expand Down
13 changes: 13 additions & 0 deletions code/__DEFINES/~nova_defines/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,16 @@

/// Whenever we need to get the soul of the mob inside of the soulcatcher.
#define COMSIG_SOULCATCHER_SCAN_BODY "soulcatcher_scan_body"

// CORRUPTION SIGNALS

/// From /obj/structure/fleshmind/structure/proc/activate_ability() (src)
#define COMSIG_CORRUPTION_STRUCTURE_ABILITY_TRIGGERED "corruption_structure_ability_triggered"

/// From /mob/living/simple_animal/hostile/fleshmind/phaser/proc/phase_move_to(atom/target, nearby = FALSE)
#define COMSIG_PHASER_PHASE_MOVE "phaser_phase_move"
/// from /mob/living/simple_animal/hostile/fleshmind/phaser/proc/enter_nearby_closet()
#define COMSIG_PHASER_ENTER_CLOSET "phaser_enter_closet"

/// from /obj/structure/fleshmind/structure/core/proc/rally_troops()
#define COMSIG_FLESHMIND_CORE_RALLY "fleshmind_core_rally"
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
//no scanning if its a husk, DNA-less Species or DNA that isn't able to be copied by a changeling/disease
if (!HAS_TRAIT(interacting_with, TRAIT_GENELESS) && !HAS_TRAIT(interacting_with, TRAIT_BADDNA) && !HAS_TRAIT(interacting_with, TRAIT_NO_DNA_COPY))
user.visible_message(span_warning("[user] is scanning [interacting_with]'s genetic makeup."))
if(!do_after(user, 3 SECONDS))
if(!do_after(user, 3 SECONDS, interacting_with))
balloon_alert(user, "scan failed!")
user.visible_message(span_warning("[user] fails to scan [interacting_with]'s genetic makeup."))
return ITEM_INTERACT_BLOCKING
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
var/progression_objectives_minimum = 20 MINUTES

/datum/traitor_objective/hack_comm_console/can_generate_objective(datum/mind/generating_for, list/possible_duplicates)
if(length(possible_duplicates) > 0)
return FALSE
if(SStraitor.get_taken_count(/datum/traitor_objective/hack_comm_console) > 0)
return FALSE
if(handler.get_completion_progression(/datum/traitor_objective) < progression_objectives_minimum)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
var/area/weakpoint_area

/datum/traitor_objective/locate_weakpoint/can_generate_objective(datum/mind/generating_for, list/possible_duplicates)
if(length(possible_duplicates) > 0)
return FALSE
if(handler.get_completion_progression(/datum/traitor_objective) < progression_objectives_minimum)
return FALSE
if(SStraitor.get_taken_count(/datum/traitor_objective/locate_weakpoint) > 0)
Expand Down
4 changes: 2 additions & 2 deletions code/modules/mob/living/basic/trooper/pirate.dm
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
r_hand = /obj/item/gun/energy/laser
ai_controller = /datum/ai_controller/basic_controller/trooper/ranged
/// Type of bullet we use
var/casingtype = /obj/item/ammo_casing/energy/laser
var/projectiletype = /obj/projectile/beam/laser
/// Sound to play when firing weapon
var/projectilesound = 'sound/weapons/laser.ogg'
/// number of burst shots
Expand All @@ -67,7 +67,7 @@
. = ..()
AddComponent(\
/datum/component/ranged_attacks,\
casing_type = casingtype,\
projectile_type = projectiletype,\
projectile_sound = projectilesound,\
cooldown_time = ranged_cooldown,\
burst_shots = burst_shots,\
Expand Down
11 changes: 11 additions & 0 deletions code/modules/unit_tests/simple_animal_freeze.dm
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,17 @@
/mob/living/simple_animal/hostile/zombie/nocorpse,
/mob/living/simple_animal/pet/gondola/funky,
/mob/living/simple_animal/pet/poppy,
/mob/living/simple_animal/hostile/fleshmind/slicer,
/mob/living/simple_animal/hostile/fleshmind/floater,
/mob/living/simple_animal/hostile/fleshmind/globber,
/mob/living/simple_animal/hostile/fleshmind/stunner,
/mob/living/simple_animal/hostile/fleshmind/hiborg,
/mob/living/simple_animal/hostile/fleshmind/himan,
/mob/living/simple_animal/hostile/fleshmind/treader,
/mob/living/simple_animal/hostile/fleshmind/phaser,
/mob/living/simple_animal/hostile/fleshmind/mechiver,
/mob/living/simple_animal/hostile/fleshmind/mauler_monkey,
/mob/living/simple_animal/hostile/fleshmind,

// DO NOT ADD NEW ENTRIES TO THIS LIST
// READ THE COMMENT ABOVE
Expand Down
2 changes: 1 addition & 1 deletion code/modules/vending/_vending.dm
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
if(isnull(refill_canister))
return // you can add the comment here instead
if((total_loaded_stock() / total_max_stock()) < 1)
. += span_notice("\The [src] can be restocked with [span_boldnotice("\a [refill_canister]")] with the panel open.")
. += span_notice("\The [src] can be restocked with [span_boldnotice("\a [initial(refill_canister.machine_name)] [initial(refill_canister.name)]")] with the panel open.")
else
. += span_notice("\The [src] is fully stocked.")
if(credits_contained < CREDITS_DUMP_THRESHOLD && credits_contained > 0)
Expand Down
4 changes: 4 additions & 0 deletions html/changelogs/AutoChangeLog-pr-2367.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
author: "Iajret"
delete-after: True
changes:
- balance: "Entombed and Underworld Connections are moved to veteran only quirks"
4 changes: 4 additions & 0 deletions html/changelogs/AutoChangeLog-pr-2483.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
author: "Zergspower"
delete-after: True
changes:
- rscadd: "ah shit"
103 changes: 103 additions & 0 deletions modular_nova/modules/space_ruin_specifics/code/_fleshmind_defines.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// GENERAL DEFINES

/// A list of objects that are considered part of a door, used to determine if a wireweed should attack it.
#define DOOR_OBJECT_LIST list(/obj/machinery/door/airlock, /obj/structure/door_assembly, /obj/machinery/door/firedoor, /obj/machinery/door/window)

#define FACTION_FLESHMIND "fleshmind"

#define MALFUNCTION_RESET_TIME 3 SECONDS

#define MALFUNCTION_CORE_DEATH_RESET_TIME 20 SECONDS

#define STRUCTURE_EMP_LIGHT_DISABLE_TIME 3 SECONDS
#define STRUCTURE_EMP_HEAVY_DISABLE_TIME 7 SECONDS

#define STRUCTURE_EMP_LIGHT_DAMAGE 30
#define STRUCTURE_EMP_HEAVY_DAMAGE 50

#define MOB_EMP_LIGHT_DAMAGE 5
#define MOB_EMP_HEAVY_DAMAGE 10

#define FLESHMIND_NAME_MODIFIER_LIST list ("Warped", "Altered", "Modified", "Upgraded", "Abnormal")

/// The range at which most of our objects, mobs and structures activate at. 7 seems to be the perfect number.
#define DEFAULT_VIEW_RANGE 7

#define MALFUNCTION_CHANCE_LOW 0.5
#define MALFUNCTION_CHANCE_MEDIUM 1
#define MALFUNCTION_CHANCE_HIGH 2

#define SPECIES_MONKEY_MAULER "monkey_mauler"

#define MECHIVER_CONSUME_HEALTH_THRESHOLD 0.7

#define FLESHMIND_LIGHT_BLUE "#50edd9"

/// Core is in danger, engage turboboosters
#define MOB_RALLY_SPEED 1

/// The max spread distance a wireweed can spread thru a vent.
#define MAX_VENT_SPREAD_DISTANCE 6

#define CONTROLLED_MOB_POLICY "You are part of the fleshmind, this means any fleshmind entities, structures, mobs are your ally. You must not attack them. \n \
You must roleplay that you are part of the fleshmind. Your number one goal is converting other hosts and spreading the flesh."

#define FLESHMIND_EVENT_MAKE_CORRUPTION_CHANCE 2

#define FLESHMIND_EVENT_MAKE_CORRUPT_MOB 1

// CONTROLLER RELATED DEFINES

#define AI_FORENAME_LIST list("Von Neumann", "Lazarus", "Abattoir", "Tra-Sentience", \
"Vivisector", "Ex Costa", "Apostasy", "Gnosis", "Balaam", "Ophite", \
"Sarif", "VersaLife", "Obsidian", "SHODAN", "Pandora", "Master Controller", "Xerxes")

#define AI_SURNAME_LIST list("Mk I", "Mk II", "Mk III", "Mk IV", "Mk V", "Mk X", \
"v0.9", "v1.0", "v1.1", "v2.0", "2418-B", "Open Beta", \
"Pre-Release", "Commercial Release", "Closed Alpha", "Hivebuilt")

/// The controller must reach this before it can level up to the next level.
#define CONTROLLER_LEVEL_UP_THRESHOLD 300

#define CONTROLLER_LEVEL_1 1
#define CONTROLLER_LEVEL_2 2
#define CONTROLLER_LEVEL_3 3
#define CONTROLLER_LEVEL_4 4
#define CONTROLLER_LEVEL_5 5
#define CONTROLLER_LEVEL_MAX 6

// Balance specific defines
#define FLESHCORE_SPREAD_PROGRESS_REQUIRED 200 // How much progress is required to spread?
#define FLESHCORE_SPREADS_FOR_STRUCTURE 50 // How many times do we need to spread until we can create a new structure?
#define FLESHCORE_INITIAL_EXPANSION_SPREADS 30 // Upon creation, how many times do we spread instantly?
#define FLESHCORE_INITIAL_EXPANSION_STRUCTURES 5 // Upon creation, how many structures do we spawn instantly?
#define FLESHCORE_SPREAD_PROGRESS_PER_SUBSYSTEM_FIRE 40 // Every subsystem fire, how much progress do we gain?
#define FLESHCORE_BASE_SPREAD_PROGRESS_PER_SUBSYSTEM_FIRE 40 // The baseline of the above.
#define FLESHCORE_ATTACK_PROB 20 // How likely are we to attack every SS fire?
#define FLESHCORE_WALL_PROB 30 // How likely are we to spawn a wall to seal a gap every SS fire?
#define FLESHCORE_NEXT_CORE_DAMAGE_WIREWEED_ACTIVATION_COOLDOWN 10 SECONDS // The amount of time until we can activate nearby wireweed again.

#define CONTROLLER_DEATH_DO_NOTHING 1
#define CONTROLLER_DEATH_SLOW_DECAY 2
#define CONTROLLER_DEATH_DELETE_ALL 3

#define CONTROLLER_LEVEL_UP_CORE_INTEGRITY_AMOUNT 300 // How much integrity the cores get when leveling up

// WIREWEED RELATED DEFINES

#define CORE_DAMAGE_WIREWEED_ACTIVATION_RANGE 6
#define GENERAL_DAMAGE_WIREWEED_ACTIVATION_RANGE 2

#define WIREWEED_WIRECUTTER_KILL_TIME 0.5 SECONDS

#define WIREWEED_HEAL_CHANCE 10

#define WIREWEED_REPLACE_BODYPART_CHANCE 5

#define WIREWEED_HEAL_AMOUNT 3

// MECHIVER RELATED DEFINES
#define MECHIVER_INTERNAL_MOB_DAMAGE_UPPER 60 // Upder damage done to internal mob
#define MECHIVER_INTERNAL_MOB_DAMAGE_LOWER 30 // Lower damage done to internal mob
#define MECHIVER_CONVERSION_TIME 20 SECONDS // Time to convert someone inside
#define MECHIVER_CONSUME_COOLDOWN 1 MINUTES // How long it takes to be ready to consume again
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#define is_corrupt_mob(A) (istype(A, /mob/living/simple_animal/hostile/fleshmind))
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/**
* fleshmind basetype(abstract)
*/
/obj/structure/fleshmind
icon = 'modular_nova/modules/space_ruin_specifics/icons/fleshmind_structures.dmi'
icon_state = "wires"
anchored = TRUE
/// Our faction
var/faction_types = list(FACTION_FLESHMIND)
/// A reference to our controller.
var/datum/fleshmind_controller/our_controller
/// The minimum core level for us to spawn at
var/required_controller_level = CONTROLLER_LEVEL_1
/// A list of possible rewards for destroying this thing.
var/list/possible_rewards

/obj/structure/fleshmind/Destroy()
our_controller = null
if(possible_rewards)
var/thing_to_spawn = pick(possible_rewards)
new thing_to_spawn(drop_location())
return ..()

/**
* Deletion cleanup
*
*/
/obj/structure/fleshmind/proc/controller_destroyed(datum/fleshmind_controller/dying_controller, force)
SIGNAL_HANDLER

our_controller = null

/**
* Wireweed
*
* These are the arteries of the fleshmind, they are required for spreading and support machine life.
*/
/obj/structure/fleshmind/wireweed
name = "wireweed"
desc = "A strange pulsating mass of organic wires."
icon = 'modular_nova/modules/space_ruin_specifics/icons/wireweed_floor.dmi'
icon_state = "wires-0"
base_icon_state = "wires"
anchored = TRUE
layer = BELOW_OPEN_DOOR_LAYER
smoothing_flags = SMOOTH_BITMASK
smoothing_groups = SMOOTH_GROUP_WIREWEED + SMOOTH_GROUP_WALLS
canSmoothWith = SMOOTH_GROUP_WIREWEED + SMOOTH_GROUP_WALLS
max_integrity = 40
/// The chance we have to ensnare a mob
var/ensnare_chance = 15
/// The amount of damage we do when attacking something.
var/object_attack_damage = 150
/// Are we active?
var/active = FALSE
/// Are we a vent burrow?
var/vent_burrow = FALSE
/// ZOnes we passively replace
var/static/list/replacement_zones = list(
BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/robot,
BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/robot,
BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/robot,
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/robot,
)

/obj/structure/fleshmind/wireweed/Initialize(mapload, starting_alpha = 255, datum/fleshmind_controller/incoming_controller)
. = ..()
alpha = starting_alpha
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
)
AddElement(/datum/element/connect_loc, loc_connections)
our_controller = incoming_controller

/obj/structure/fleshmind/wireweed/wirecutter_act(mob/living/user, obj/item/tool)
. = ..()
loc.balloon_alert(user, "cutting...")
if(!tool.use_tool(src, user, WIREWEED_WIRECUTTER_KILL_TIME, volume = 50))
return
loc.balloon_alert(user, "cut!")
qdel(src)
return TRUE


/obj/structure/fleshmind/wireweed/update_icon(updates)
. = ..()

if(QDELETED(src))
return

if((updates & UPDATE_SMOOTHING) && (smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK)))
if(!vent_burrow)
QUEUE_SMOOTH(src)
QUEUE_SMOOTH_NEIGHBORS(src)

/obj/structure/fleshmind/wireweed/update_icon_state()
. = ..()
if(vent_burrow)
icon_state = "vent_burrow"

/obj/structure/fleshmind/wireweed/emp_act(severity)
. = ..()
switch(severity)
if(EMP_LIGHT)
take_damage(20)
if(EMP_HEAVY)
take_damage(40)

/obj/structure/fleshmind/wireweed/update_overlays()
. = ..()
if(active)
. += "active"
for(var/wall_dir in GLOB.cardinals)
var/turf/new_turf = get_step(src, wall_dir)
if(new_turf && new_turf.density) // Assume we are a wall!
var/image/new_wall_overlay = image(icon, icon_state = "wall_hug", dir = wall_dir)
switch(wall_dir) //offset to make it be on the wall rather than on the floor
if(NORTH)
new_wall_overlay.pixel_y = 32
if(SOUTH)
new_wall_overlay.pixel_y = -32
if(EAST)
new_wall_overlay.pixel_x = 32
if(WEST)
new_wall_overlay.pixel_x = -32
. += new_wall_overlay

/obj/structure/fleshmind/wireweed/proc/visual_finished()
SIGNAL_HANDLER
alpha = 255

/obj/structure/fleshmind/wireweed/proc/on_entered(datum/source, atom/movable/moving_atom)
SIGNAL_HANDLER
if(!isliving(moving_atom))
return
var/mob/living/entered_mob = moving_atom
if(!faction_check(entered_mob.faction, faction_types))
return
if(prob(WIREWEED_HEAL_CHANCE))
entered_mob.heal_overall_damage(WIREWEED_HEAL_AMOUNT, WIREWEED_HEAL_AMOUNT)
to_chat(entered_mob, span_green("[src] heals you as you cross over it!"))
if(ishuman(entered_mob) && prob(WIREWEED_REPLACE_BODYPART_CHANCE))
var/mob/living/carbon/human/human_mob = moving_atom
for(var/zone as anything in replacement_zones)
if(human_mob.get_bodypart(zone))
continue
var/bodypart_type = replacement_zones[zone]
var/obj/item/bodypart/new_bodypart = new bodypart_type()
new_bodypart.replace_limb(human_mob, TRUE)
human_mob.update_body(TRUE)
to_chat(human_mob, span_green("[src] shoots a mechanical limb right into your missing limb!"))

/obj/effect/temp_visual/wireweed_spread
icon = 'modular_nova/modules/space_ruin_specifics/icons/wireweed_floor.dmi'
icon_state = "spread_anim"
duration = 1.7 SECONDS
Loading

0 comments on commit d7c9871

Please sign in to comment.