mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 16:47:13 +01:00
Is this even working Oooough ok I'll crack at this couple more fixes Probably the worst of all my commits so far Seriously, someone needs to check this. It compiles update atmos stuff update paths snakes linters 1 linters again more CI whoops Update map_previews.dmi Kills loose limbs The component it used no longer exists. podperson CI Fixes(?) Linters
393 lines
11 KiB
Plaintext
393 lines
11 KiB
Plaintext
#define CORE_RETALIATION_COOLDOWN (5 SECONDS)
|
|
#define MOLD_BULB_ALPHA 100
|
|
|
|
/obj/structure/mold
|
|
anchored = TRUE
|
|
|
|
/// The controller controlling the mold's expansion
|
|
var/datum/mold_controller/mold_controller
|
|
/// The type of mold
|
|
var/datum/mold_type/mold_type
|
|
|
|
/obj/structure/mold/Destroy()
|
|
if(!mold_controller)
|
|
qdel(mold_type)
|
|
mold_controller = null
|
|
mold_type = null
|
|
playsound(src.loc, 'sound/effects/splat.ogg', 30, TRUE)
|
|
return ..()
|
|
|
|
/obj/structure/mold/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
|
switch(damage_type)
|
|
if(BRUTE)
|
|
playsound(loc, 'sound/effects/blob/attackblob.ogg', 100, TRUE)
|
|
if(BURN)
|
|
playsound(loc, 'sound/items/tools/welder.ogg', 100, TRUE)
|
|
|
|
/obj/structure/mold/Initialize(mapload, passed_type)
|
|
. = ..()
|
|
if(!mold_type)
|
|
mold_type = mold_controller?.mold_type || passed_type
|
|
|
|
color = mold_type.mold_color
|
|
resistance_flags = mold_type.resistance_flags
|
|
name = "[mold_type.name] [name]"
|
|
update_appearance()
|
|
|
|
/obj/structure/mold/structure
|
|
density = TRUE
|
|
/// Does the structure emit light?
|
|
var/emits_light = FALSE
|
|
|
|
/obj/structure/mold/structure/Initialize(mapload, passed_type)
|
|
. = ..()
|
|
if(emits_light)
|
|
light_range = 2
|
|
light_power = 1
|
|
if(mold_type.structure_light_color)
|
|
light_color = mold_type.structure_light_color
|
|
|
|
/datum/looping_sound/core_heartbeat
|
|
mid_length = 3 SECONDS
|
|
mid_sounds = list('modular_zubbers/sound/effects/heart_beat_loop3.ogg' = 1)
|
|
volume = 20
|
|
|
|
/**
|
|
* The core
|
|
*/
|
|
/obj/structure/mold/structure/core
|
|
name = "core"
|
|
icon = 'modular_skyrat/modules/mold/icons/blob_core.dmi'
|
|
icon_state = "blob_core"
|
|
layer = TABLE_LAYER
|
|
max_integrity = 600
|
|
|
|
/// The soundloop played by the core
|
|
var/datum/looping_sound/core_heartbeat/soundloop
|
|
/// The time to the next attack
|
|
var/next_retaliation = 0
|
|
|
|
/obj/structure/mold/structure/core/Initialize(mapload, passed_type)
|
|
if(mold_type)
|
|
passed_type = new mold_type
|
|
new /datum/mold_controller(src, passed_type)
|
|
. = ..()
|
|
soundloop = new(src, TRUE)
|
|
update_overlays(UPDATE_OVERLAYS)
|
|
|
|
/obj/structure/mold/structure/core/Destroy()
|
|
if(mold_controller)
|
|
mold_controller.our_core = null
|
|
soundloop.stop()
|
|
QDEL_NULL(soundloop)
|
|
return ..()
|
|
|
|
/obj/structure/mold/structure/core/run_atom_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
|
|
if(!(damage_amount > 10) || !(world.time > next_retaliation) || !prob(40))
|
|
return ..()
|
|
|
|
mold_controller?.core_retaliated()
|
|
next_retaliation = world.time + CORE_RETALIATION_COOLDOWN
|
|
|
|
mold_type.core_defense(src)
|
|
|
|
/obj/structure/mold/structure/core/update_overlays()
|
|
. = ..()
|
|
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
|
|
SSvis_overlays.add_vis_overlay(src, icon, "blob_core_overlay", layer, plane, dir, alpha)
|
|
SSvis_overlays.add_vis_overlay(src, icon, "blob_core_overlay", 0, EMISSIVE_PLANE, dir, alpha)
|
|
var/obj/effect/overlay/vis/overlay1 = managed_vis_overlays[1]
|
|
var/obj/effect/overlay/vis/overlay2 = managed_vis_overlays[2]
|
|
overlay1.appearance_flags = PIXEL_SCALE | TILE_BOUND | RESET_COLOR
|
|
overlay2.appearance_flags = PIXEL_SCALE | TILE_BOUND | RESET_COLOR
|
|
|
|
/**
|
|
* Preset types
|
|
* Useful for admins
|
|
*/
|
|
/obj/structure/mold/structure/core/fire
|
|
mold_type = /datum/mold_type/fire
|
|
|
|
/obj/structure/mold/structure/core/disease
|
|
mold_type = /datum/mold_type/disease
|
|
|
|
/obj/structure/mold/structure/core/emp
|
|
mold_type = /datum/mold_type/emp
|
|
|
|
/obj/structure/mold/structure/core/toxic
|
|
mold_type = /datum/mold_type/toxic
|
|
|
|
/obj/structure/mold/structure/core/radioactive
|
|
mold_type = /datum/mold_type/radioactive
|
|
|
|
|
|
|
|
/**
|
|
* Mold resin
|
|
*/
|
|
/obj/structure/mold/resin
|
|
name = "mold"
|
|
desc = "It looks like mold, but it seems alive."
|
|
icon = 'modular_skyrat/modules/mold/icons/blob_resin.dmi'
|
|
icon_state = "blob_floor"
|
|
density = FALSE
|
|
plane = GAME_PLANE
|
|
layer = LOW_SIGIL_LAYER
|
|
max_integrity = 25
|
|
var/blooming = FALSE
|
|
/// Are we a floor resin? If not then we're a wall resin
|
|
var/floor = TRUE
|
|
|
|
/obj/structure/mold/resin/examine(mob/user)
|
|
. = ..()
|
|
. += mold_type.examine_text
|
|
|
|
/obj/structure/mold/resin/update_overlays()
|
|
. = ..()
|
|
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
|
|
if(blooming)
|
|
SSvis_overlays.add_vis_overlay(src, icon, "[icon_state]_overlay", layer, plane, dir, alpha)
|
|
SSvis_overlays.add_vis_overlay(src, icon, "[icon_state]_overlay", 0, EMISSIVE_PLANE, dir, alpha)
|
|
var/obj/effect/overlay/vis/overlay1 = managed_vis_overlays[1]
|
|
var/obj/effect/overlay/vis/overlay2 = managed_vis_overlays[2]
|
|
overlay1.appearance_flags = PIXEL_SCALE | TILE_BOUND | RESET_COLOR
|
|
overlay2.appearance_flags = PIXEL_SCALE | TILE_BOUND | RESET_COLOR
|
|
|
|
/obj/structure/mold/resin/proc/calculate_direction()
|
|
var/direction = 16
|
|
var/turf/location = loc
|
|
for(var/wallDir in GLOB.cardinals)
|
|
var/turf/newTurf = get_step(location,wallDir)
|
|
if(newTurf && newTurf.density)
|
|
direction |= wallDir
|
|
|
|
for(var/obj/structure/mold/resin/tomato in location)
|
|
if(tomato == src)
|
|
continue
|
|
if(tomato.floor) //special
|
|
direction &= ~16
|
|
else
|
|
direction &= ~tomato.dir
|
|
|
|
var/list/dirList = list()
|
|
|
|
for(var/i=1,i<=16,i <<= 1)
|
|
if(direction & i)
|
|
dirList += i
|
|
|
|
if(dirList.len)
|
|
var/newDir = pick(dirList)
|
|
if(newDir == 16)
|
|
setDir(pick(GLOB.cardinals))
|
|
else
|
|
floor = FALSE
|
|
setDir(newDir)
|
|
switch(dir) //offset to make it be on the wall rather than on the floor
|
|
if(NORTH)
|
|
pixel_y = 32
|
|
if(SOUTH)
|
|
pixel_y = -32
|
|
if(EAST)
|
|
pixel_x = 32
|
|
if(WEST)
|
|
pixel_x = -32
|
|
icon_state = "blob_wall"
|
|
plane = GAME_PLANE
|
|
layer = LOW_SIGIL_LAYER
|
|
|
|
if(prob(7))
|
|
blooming = TRUE
|
|
set_light(2, 1, LIGHT_COLOR_LAVA)
|
|
update_overlays(UPDATE_OVERLAYS)
|
|
|
|
/obj/structure/mold/resin/Destroy()
|
|
if(mold_controller)
|
|
mold_controller.activate_adjacent_resin(get_turf(src))
|
|
mold_controller.all_resin -= src
|
|
mold_controller.active_resin -= src
|
|
return ..()
|
|
|
|
/obj/structure/mold/resin/test
|
|
mold_type = /datum/mold_type
|
|
|
|
/**
|
|
* Bulbs
|
|
*/
|
|
/obj/structure/mold/structure/bulb
|
|
name = "bulb"
|
|
icon = 'modular_skyrat/modules/mold/icons/blob_bulb.dmi'
|
|
icon_state = "blob_bulb_empty"
|
|
density = FALSE
|
|
layer = TABLE_LAYER
|
|
light_range = 2
|
|
light_power = 1
|
|
light_color = LIGHT_COLOR_LAVA
|
|
var/is_full = FALSE
|
|
var/list/registered_turfs = list()
|
|
max_integrity = 50
|
|
|
|
/obj/structure/mold/structure/bulb/Initialize(mapload)
|
|
. = ..()
|
|
make_full()
|
|
for(var/adjacent_turf in get_adjacent_open_turfs(src))
|
|
registered_turfs += adjacent_turf
|
|
RegisterSignal(adjacent_turf, COMSIG_ATOM_ENTERED, PROC_REF(proximity_trigger))
|
|
|
|
/obj/structure/mold/structure/bulb/proc/proximity_trigger(datum/source, atom/movable/nearby_atom)
|
|
SIGNAL_HANDLER
|
|
if(!isliving(nearby_atom))
|
|
return
|
|
var/mob/living/nearby_mob = nearby_atom
|
|
if(!(nearby_mob.has_faction(FACTION_MOLD)))
|
|
INVOKE_ASYNC(src, PROC_REF(discharge))
|
|
|
|
/obj/structure/mold/structure/bulb/proc/make_full()
|
|
//Called by a timer, check if we exist
|
|
if(QDELETED(src))
|
|
return
|
|
is_full = TRUE
|
|
icon_state = "blob_bulb_full"
|
|
set_light(2, 1, LIGHT_COLOR_LAVA)
|
|
density = TRUE
|
|
update_overlays(UPDATE_OVERLAYS)
|
|
|
|
|
|
/obj/structure/mold/structure/bulb/proc/discharge()
|
|
if(!is_full)
|
|
return
|
|
|
|
mold_type.bulb_discharge(src)
|
|
|
|
is_full = FALSE
|
|
icon_state = "blob_bulb_empty"
|
|
playsound(src, 'sound/effects/bamf.ogg', 100, TRUE)
|
|
set_light(0)
|
|
update_overlays(UPDATE_OVERLAYS)
|
|
density = FALSE
|
|
addtimer(CALLBACK(src, PROC_REF(make_full)), 1 MINUTES, TIMER_UNIQUE|TIMER_NO_HASH_WAIT)
|
|
|
|
/obj/structure/mold/structure/bulb/attack_generic(mob/user, damage_amount, damage_type, damage_flag, sound_effect, armor_penetration)
|
|
if(user.has_faction(FACTION_MOLD))
|
|
return ..()
|
|
discharge()
|
|
. = ..()
|
|
|
|
/obj/structure/mold/structure/bulb/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit = FALSE)
|
|
. = ..()
|
|
if(istype(hitting_projectile, /obj/projectile/energy/nuclear_particle) || . != BULLET_ACT_HIT)
|
|
return
|
|
discharge()
|
|
|
|
/obj/structure/mold/structure/bulb/Destroy()
|
|
if(mold_controller)
|
|
mold_controller.other_structures -= src
|
|
for(var/checked_turfs in registered_turfs)
|
|
UnregisterSignal(checked_turfs, COMSIG_ATOM_ENTERED)
|
|
registered_turfs = null
|
|
return ..()
|
|
|
|
/obj/structure/mold/structure/bulb/update_overlays()
|
|
. = ..()
|
|
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
|
|
if(is_full)
|
|
SSvis_overlays.add_vis_overlay(src, icon, "blob_bulb_overlay", layer, plane, dir, MOLD_BULB_ALPHA)
|
|
SSvis_overlays.add_vis_overlay(src, icon, "blob_bulb_overlay", 0, EMISSIVE_PLANE, dir, alpha)
|
|
var/obj/effect/overlay/vis/overlay1 = managed_vis_overlays[1]
|
|
var/obj/effect/overlay/vis/overlay2 = managed_vis_overlays[2]
|
|
overlay1.appearance_flags = PIXEL_SCALE | TILE_BOUND | RESET_COLOR
|
|
overlay2.appearance_flags = PIXEL_SCALE | TILE_BOUND | RESET_COLOR
|
|
|
|
|
|
/**
|
|
* Wall
|
|
*/
|
|
/obj/structure/mold/structure/wall
|
|
name = "mold wall"
|
|
desc = "Looks like some kind of thick resin."
|
|
icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi'
|
|
icon_state = "resin_wall-0"
|
|
base_icon_state = "resin_wall"
|
|
opacity = TRUE
|
|
smoothing_flags = SMOOTH_BITMASK
|
|
smoothing_groups = SMOOTH_GROUP_ALIEN_RESIN
|
|
canSmoothWith = SMOOTH_GROUP_ALIEN_RESIN
|
|
max_integrity = 100
|
|
can_atmos_pass = ATMOS_PASS_DENSITY
|
|
|
|
/obj/structure/mold/wall/Destroy()
|
|
if(mold_controller)
|
|
mold_controller.activate_adjacent_resin(get_turf(src))
|
|
mold_controller.other_structures -= src
|
|
return ..()
|
|
|
|
|
|
/**
|
|
* Conditioner
|
|
*/
|
|
/obj/structure/mold/structure/conditioner
|
|
name = "pulsating vent"
|
|
desc = "An unsightly vent, it appears to be puffing something out."
|
|
density = FALSE
|
|
icon = 'modular_skyrat/modules/mold/icons/blob_spawner.dmi'
|
|
icon_state = "blob_vent"
|
|
density = FALSE
|
|
layer = SIGIL_LAYER
|
|
max_integrity = 75
|
|
/// The mold atmosphere conditioner will spawn the mold's preferred atmosphere every so often.
|
|
var/happy_atmos = null
|
|
/// The time between injections of that mold type's preferred atmos
|
|
var/puff_cooldown = 30 SECONDS
|
|
/// Tracks the status of the cooldown
|
|
var/puff_delay = 0
|
|
|
|
/obj/structure/mold/structure/conditioner/Destroy()
|
|
STOP_PROCESSING(SSobj, src)
|
|
if(mold_controller)
|
|
mold_controller.other_structures -= src
|
|
return ..()
|
|
|
|
/obj/structure/mold/structure/conditioner/Initialize(mapload)
|
|
. = ..()
|
|
happy_atmos = mold_type.preferred_atmos_conditions
|
|
START_PROCESSING(SSobj, src)
|
|
|
|
/obj/structure/mold/structure/conditioner/process(seconds_per_tick)
|
|
if(!happy_atmos)
|
|
return
|
|
if(puff_delay > world.time)
|
|
return
|
|
puff_delay = world.time + puff_cooldown
|
|
var/turf/holder_turf = get_turf(src)
|
|
holder_turf.atmos_spawn_air(happy_atmos)
|
|
mold_type.bonus_conditioner_effects(src)
|
|
|
|
|
|
/**
|
|
* Hatchery
|
|
*/
|
|
/obj/structure/mold/structure/spawner
|
|
name = "hatchery"
|
|
icon = 'modular_skyrat/modules/mold/icons/blob_spawner.dmi'
|
|
icon_state = "blob_spawner"
|
|
density = FALSE
|
|
layer = SIGIL_LAYER
|
|
max_integrity = 75
|
|
|
|
/obj/structure/mold/structure/spawner/Destroy()
|
|
if(mold_controller)
|
|
mold_controller.other_structures -= src
|
|
return ..()
|
|
|
|
/obj/structure/mold/structure/spawner/Initialize(mapload)
|
|
. = ..()
|
|
AddComponent(/datum/component/spawner, \
|
|
spawn_types = mold_type.mob_types, \
|
|
spawn_time = mold_type.spawn_cooldown, \
|
|
max_spawned = mold_type.max_spawns, \
|
|
faction = list(FACTION_MOLD), \
|
|
spawn_text = "emerges from", \
|
|
)
|
|
|
|
#undef CORE_RETALIATION_COOLDOWN
|
|
#undef MOLD_BULB_ALPHA
|