mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-25 21:19:00 +01:00
Adds the alien cache ruin and a PTL terminal (#30367)
* Make the cache room * adds alien cache machine * adds the cache properly * adds multitile component * adds terminal building and reward selection procs * adds laser receptacle file * Refactors ptl targetting code * more work on the ptl terminal * change file name to laser_terminal * changes area to powered makes laser terminal work properly * makes a new pickweight function because the old one is bad * Update alien_cache.dm * Update canister.dm * Update alien_cache.dm * adds a template of the ruin * adds some spawners to the reward pool * adjusts agent b amount * adjustments to loot table and changes to spawner comments * new placeholder sprite for the cache * randomizes reward spawn location and makes a PTL terminal sprite * updates alien cache sprite and examine proc * Adds overlays to the cache to indicate the current progress * fixes mob capsule spawner and laser terminal * Adds animations to PTL terminal * new box part of the sprite for the PTL terminal. Adds glow * fixes untargetting the PTL terminal and adds a little light overlay to the receiving dish * changes PTL terminal id generation slightly * adds simon says. incomplete * Update paradise.dme * simon says works now * adds more rhythms * Adds success and failure sounds * Makes the ptl terminal board printable * Update secure_alien_airlock.dm * undo changes to preferences.dm * undefs things * removes identical to parent vars * Update alien_cache_random_spawners.dm * replaces animation end loop flag so open dream CI doesn't give errors * changes centre platform colour and adds a fan to the entrance * more pads more sounds * better sprites * remove old sprite * adds the cache to example config * makes it not always spawn * Update simon_says_32x32.dmi * adds some flavor to the ruin * Update alien_cache_site.dmm * adds a signal to the ruin
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -209,8 +209,11 @@
|
||||
|
||||
#define LORENTZ_DISTRIBUTION(x, s) ( s*tan(TODEGREES(PI*(rand()-0.5))) + x )
|
||||
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*TORADIANS(arctan((x-y)/s)) + 1/2 )
|
||||
|
||||
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
|
||||
|
||||
/// Returns probability based on deviation from the mean(m) and sigma(s)
|
||||
#define normal_distribution(x, m, s) ((1 / ((2 * PI * s**2)**0.5)) * NUM_E ** -(((x - m) ** 2) / (2 * s ** 2)))
|
||||
|
||||
// )
|
||||
|
||||
/proc/RaiseToPower(num, power)
|
||||
|
||||
@@ -293,6 +293,28 @@
|
||||
|
||||
return null
|
||||
|
||||
/**
|
||||
* Picks an element based on its weight. Weight can be any real number
|
||||
* L - The input list
|
||||
*
|
||||
* example: list("a" = 0.33, "b" = 0.67) will have a 67% chance to pick "b"
|
||||
*/
|
||||
/proc/pickweight_fraction(list/L)
|
||||
var/total = 0
|
||||
var/item
|
||||
for(item in L)
|
||||
if(L[item] < 0)
|
||||
continue
|
||||
total += L[item]
|
||||
|
||||
total = rand() * total
|
||||
for(item in L)
|
||||
total -=L [item]
|
||||
if(total <= 0)
|
||||
return item
|
||||
|
||||
return null
|
||||
|
||||
//Pick a random element from the list and remove it from the list.
|
||||
/proc/pick_n_take(list/listfrom)
|
||||
if(length(listfrom) > 0)
|
||||
|
||||
@@ -400,3 +400,11 @@
|
||||
description = "Nanotrasen uses relays like these to further extend telecommunications around an area of space, as well as long range beacons for easier deployment in the future. \
|
||||
Unfortunately, the anomalous activity around Epsilon Eridani, along with orbital debris and space-faring hostiles, has rendered many of these relay stations inoperable, leaving their communications and teleportation systems offline."
|
||||
never_spawn_on_the_same_level = list("bluespace_relay_beacon")
|
||||
|
||||
/datum/map_template/ruin/space/alien_cache_site
|
||||
id = "alien_cache_site"
|
||||
suffix = "alien_cache_site.dmm"
|
||||
name = "Alien Cache Site"
|
||||
description = "A site containing a cache of alien design, who knows what valuable technology is hiding inside?"
|
||||
never_spawn_on_the_same_level = list("alien_cache_site")
|
||||
allow_duplicates = FALSE
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/area/ruin/powered/alien_cache_site
|
||||
name = "Alien Cache Site"
|
||||
report_alerts = FALSE
|
||||
dynamic_lighting = FALSE
|
||||
|
||||
/area/ruin/powered/alien_cache_site/cache_room
|
||||
name = "Alien Cache Chamber"
|
||||
@@ -1510,3 +1510,38 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
attack_info.last_attacker_ckey = attacker.ckey
|
||||
if(istype(weapon))
|
||||
attack_info.last_attacker_weapon = "[weapon] ([weapon.type])"
|
||||
|
||||
// MARK: PTL PROCS
|
||||
|
||||
// Called when the target is selected
|
||||
/atom/proc/on_ptl_target(obj/machinery/power/transmission_laser/ptl)
|
||||
if(ptl.firing)
|
||||
on_ptl_fire()
|
||||
return
|
||||
|
||||
// Called for each process of the PTL
|
||||
/atom/proc/on_ptl_tick(obj/machinery/power/transmission_laser/ptl, output_level)
|
||||
return
|
||||
|
||||
// Called when no longer targeted by the ptl
|
||||
/atom/proc/on_ptl_untarget(obj/machinery/power/transmission_laser/ptl)
|
||||
return
|
||||
|
||||
// Called when the PTL starts firing on the target
|
||||
/atom/proc/on_ptl_fire(obj/machinery/power/transmission_laser/ptl)
|
||||
return
|
||||
|
||||
// Called when the PTL stops firing on the target
|
||||
/atom/proc/on_ptl_stop(obj/machinery/power/transmission_laser/ptl)
|
||||
return
|
||||
|
||||
// Used in the PTL ui
|
||||
/atom/proc/ptl_data()
|
||||
return name
|
||||
|
||||
// Called if an atom untargets itself
|
||||
/atom/proc/untarget_self(obj/machinery/power/transmission_laser/ptl)
|
||||
on_ptl_untarget(ptl)
|
||||
if(ptl)
|
||||
ptl.target = null
|
||||
return
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
// Canister
|
||||
#define COMPRESSED_GAS_AMOUNT 300000
|
||||
#define AGENT_B_AMOUNT 100000
|
||||
#define NAME_O2 "O2"
|
||||
#define NAME_CO2 "CO2"
|
||||
#define NAME_N2 "N2"
|
||||
#define NAME_N2O "N2O"
|
||||
#define NAME_TOX "Plasma"
|
||||
#define NAME_AGENT_B "Agent B"
|
||||
// Lazarus Capsule
|
||||
#define MOB_TYPE (1 << 0)
|
||||
#define MOB_PROTOTYPE (1 << 1)
|
||||
|
||||
// MARK: Random Spanwers
|
||||
|
||||
/obj/effect/spawner/random/alien_cache
|
||||
name = "alien cache loot spawner"
|
||||
|
||||
// Random alien tools
|
||||
/obj/effect/spawner/random/alien_cache/alien_tool
|
||||
name = "alien tool spawner"
|
||||
loot = list(
|
||||
/obj/item/screwdriver/abductor,
|
||||
/obj/item/wrench/abductor,
|
||||
/obj/item/multitool/abductor,
|
||||
/obj/item/wirecutters/abductor,
|
||||
/obj/item/crowbar/abductor,
|
||||
|
||||
)
|
||||
|
||||
// Random alien surgical tools
|
||||
/obj/effect/spawner/random/alien_cache/alien_surgical_tool
|
||||
name = "alien surgical tool spawner"
|
||||
loot = list(
|
||||
/obj/item/bonegel/alien,
|
||||
/obj/item/scalpel/laser/alien,
|
||||
/obj/item/bonesetter/alien,
|
||||
/obj/item/circular_saw/alien,
|
||||
/obj/item/hemostat/alien,
|
||||
/obj/item/fix_o_vein/alien,
|
||||
/obj/item/retractor/alien,
|
||||
)
|
||||
|
||||
// Random alien tool implant
|
||||
/obj/effect/spawner/random/alien_cache/alien_tool_implant
|
||||
name = "alien tool implant spawner"
|
||||
loot = list(
|
||||
/obj/item/organ/internal/cyberimp/arm/toolset_abductor,
|
||||
/obj/item/organ/internal/cyberimp/arm/toolset_abductor/l,
|
||||
/obj/item/organ/internal/cyberimp/arm/janitorial_abductor,
|
||||
/obj/item/organ/internal/cyberimp/arm/janitorial_abductor/l,
|
||||
/obj/item/organ/internal/cyberimp/arm/surgical_abductor,
|
||||
/obj/item/organ/internal/cyberimp/arm/surgical_abductor/l,
|
||||
)
|
||||
|
||||
// Random alien tool borg upgrade
|
||||
/obj/effect/spawner/random/alien_cache/alien_tool_borg
|
||||
name = "alien borg tool upgrade"
|
||||
loot = list(
|
||||
/obj/item/borg/upgrade/abductor_engi,
|
||||
/obj/item/borg/upgrade/abductor_medi,
|
||||
/obj/item/borg/upgrade/abductor_jani,
|
||||
)
|
||||
|
||||
//MARK: Canister Spawners
|
||||
|
||||
// Gas canister with random gas
|
||||
/obj/effect/spawner/alien_cache/gas_canister
|
||||
name = "random gas canister spawner"
|
||||
var/list/gasses = list(
|
||||
NAME_O2 = COMPRESSED_GAS_AMOUNT,
|
||||
NAME_N2 = COMPRESSED_GAS_AMOUNT,
|
||||
NAME_CO2 = COMPRESSED_GAS_AMOUNT,
|
||||
NAME_TOX = COMPRESSED_GAS_AMOUNT,
|
||||
NAME_N2O = COMPRESSED_GAS_AMOUNT)
|
||||
|
||||
// Agent B canister
|
||||
/obj/effect/spawner/alien_cache/gas_canister/agent_b
|
||||
name = "agent b canister spawner"
|
||||
gasses = list(NAME_AGENT_B = AGENT_B_AMOUNT)
|
||||
|
||||
/obj/effect/spawner/alien_cache/gas_canister/proc/add_gas(obj/machinery/atmospherics/portable/canister/spawned)
|
||||
var/picked = pick(gasses)
|
||||
switch(picked)
|
||||
if(NAME_O2)
|
||||
spawned.air_contents.set_oxygen(gasses["[picked]"])
|
||||
if(NAME_N2)
|
||||
spawned.air_contents.set_nitrogen(gasses["[picked]"])
|
||||
if(NAME_N2O)
|
||||
spawned.air_contents.set_sleeping_agent(gasses["[picked]"])
|
||||
if(NAME_CO2)
|
||||
spawned.air_contents.set_carbon_dioxide(gasses["[picked]"])
|
||||
if(NAME_TOX)
|
||||
spawned.air_contents.set_toxins(gasses["[picked]"])
|
||||
if(NAME_AGENT_B)
|
||||
spawned.air_contents.set_agent_b(gasses["[picked]"])
|
||||
|
||||
/obj/effect/spawner/alien_cache/gas_canister/Initialize(mapload)
|
||||
. = ..()
|
||||
var/obj/machinery/atmospherics/portable/canister/spawned = new(get_turf(src))
|
||||
add_gas(spawned)
|
||||
update_icon()
|
||||
qdel(src)
|
||||
|
||||
// MARK: Lazarus Spawners
|
||||
// Lazarus Capsule with a mob inside
|
||||
/obj/effect/spawner/alien_cache/mob_capsule
|
||||
var/list/mob_types = list()
|
||||
|
||||
// Lazarus Capsule with a megafauna inside
|
||||
/obj/effect/spawner/alien_cache/mob_capsule/megafauna
|
||||
mob_types = list(/mob/living/simple_animal/hostile/megafauna = MOB_PROTOTYPE)
|
||||
|
||||
/obj/effect/spawner/alien_cache/mob_capsule/Initialize(mapload)
|
||||
. = ..()
|
||||
var/obj/item/mobcapsule/capsule = new(get_turf(src))
|
||||
var/type
|
||||
if(length(mob_types))
|
||||
var/list/pool = list()
|
||||
for(var/mob_type in mob_types)
|
||||
if(mob_types[mob_type] & MOB_TYPE)
|
||||
pool += mob_type
|
||||
if(mob_types[mob_type] & MOB_PROTOTYPE)
|
||||
pool += subtypesof(mob_type)
|
||||
type = pick(pool)
|
||||
else
|
||||
type = pick(subtypesof(/mob/living/simple_animal))
|
||||
var/mob/living/simple_animal/my_mob = new type(loc)
|
||||
my_mob.faction = list("neutral")
|
||||
capsule.captured = my_mob
|
||||
my_mob.forceMove(capsule)
|
||||
|
||||
// TEG crate for the cache
|
||||
/obj/structure/closet/crate/teg
|
||||
|
||||
/obj/structure/closet/crate/teg/populate_contents()
|
||||
new /obj/machinery/power/teg(src)
|
||||
new /obj/item/pipe/circulator(src)
|
||||
new /obj/item/pipe/circulator(src)
|
||||
|
||||
#undef COMPRESSED_GAS_AMOUNT
|
||||
#undef AGENT_B_AMOUNT
|
||||
#undef NAME_O2
|
||||
#undef NAME_CO2
|
||||
#undef NAME_N2
|
||||
#undef NAME_N2O
|
||||
#undef NAME_TOX
|
||||
#undef NAME_AGENT_B
|
||||
#undef MOB_TYPE
|
||||
#undef MOB_PROTOTYPE
|
||||
@@ -71,10 +71,8 @@
|
||||
/area/mine/outpost,
|
||||
/area/shuttle/mining,
|
||||
)
|
||||
/// Megafauna being targeted
|
||||
var/mob/living/simple_animal/hostile/megafauna/target
|
||||
/// Overlay that goes over the mob that gets beamed
|
||||
var/image/orbital_strike
|
||||
/// PTL target
|
||||
var/atom/target
|
||||
|
||||
/obj/machinery/power/transmission_laser/north
|
||||
pixel_x = -64
|
||||
@@ -276,7 +274,7 @@
|
||||
data["accepting_power"] = turned_on
|
||||
data["sucking_power"] = inputting
|
||||
data["firing"] = firing
|
||||
data["target"] = target ? target.internal_gps.gpstag : ""
|
||||
data["target"] = target ? target.ptl_data() : ""
|
||||
|
||||
data["power_format"] = power_format_multi
|
||||
data["input_number"] = input_number
|
||||
@@ -338,23 +336,24 @@
|
||||
for(var/area_type in targetable_areas)
|
||||
if(istype(boss_loc, area_type))
|
||||
target_list[monster.internal_gps.gpstag] = monster
|
||||
for(var/obj/machinery/power/laser_terminal/receptacle in GLOB.laser_terminals)
|
||||
target_list["[receptacle.name]: [receptacle.id]"] = receptacle
|
||||
// Target CC to sell power
|
||||
target_list["Collection Terminal"] = null
|
||||
|
||||
var/choose = tgui_input_list(user, "Select target", "Target", target_list)
|
||||
if(!choose)
|
||||
return
|
||||
untarget()
|
||||
target = target_list[choose]
|
||||
RegisterSignal(target, COMSIG_MOB_DEATH, PROC_REF(untarget))
|
||||
if(firing && target)
|
||||
orbital_strike = image(target.icon, target, "orbital_strike", FLY_LAYER, SOUTH)
|
||||
target.add_overlay(orbital_strike)
|
||||
if(target)
|
||||
target.on_ptl_target(src)
|
||||
|
||||
/// Stop targeting a mob once it dies
|
||||
/obj/machinery/power/transmission_laser/proc/untarget()
|
||||
SIGNAL_HANDLER
|
||||
target.cut_overlay(orbital_strike)
|
||||
UnregisterSignal(target, COMSIG_MOB_DEATH)
|
||||
SIGNAL_HANDLER // This can be called via various signals depending on what we register on the a target
|
||||
if(target)
|
||||
target.on_ptl_untarget(src)
|
||||
target = null
|
||||
|
||||
/obj/machinery/power/transmission_laser/process()
|
||||
@@ -394,14 +393,8 @@
|
||||
if(!target)
|
||||
sell_power(output_level * WATT_TICK_TO_JOULE)
|
||||
else
|
||||
if(!QDELETED(target)) // Just for safety.
|
||||
target.loot = list() // disable loot drops form the target to prevent cheese
|
||||
if(10 * output_level * target.damage_coeff[BURN] / (1 MW) > target.health) // If we would kill the target dust it.
|
||||
target.health = 0 // We need this so can_die() won't prevent dusting
|
||||
visible_message("<span class='danger'>\The [src] is reduced to dust by the beam!</span>")
|
||||
target.dust()
|
||||
else
|
||||
target.adjustFireLoss(10 * output_level / (1 MW))
|
||||
if(!QDELETED(target)) // Make sure our target still exists
|
||||
INVOKE_ASYNC(target, TYPE_PROC_REF(/atom, on_ptl_tick), src, output_level)
|
||||
else
|
||||
target = null
|
||||
if(output_level > EYE_DAMAGE_THRESHOLD)
|
||||
@@ -481,8 +474,7 @@
|
||||
|
||||
/obj/machinery/power/transmission_laser/proc/setup_lasers()
|
||||
if(target)
|
||||
orbital_strike = image(target.icon, target, "orbital_strike", FLY_LAYER, SOUTH)
|
||||
target.add_overlay(orbital_strike)
|
||||
target.on_ptl_fire()
|
||||
var/turf/last_step = get_step(get_front_turf(), dir)
|
||||
for(var/num in 1 to range)
|
||||
if(!(locate(/obj/effect/transmission_beam) in last_step))
|
||||
@@ -495,7 +487,7 @@
|
||||
|
||||
/obj/machinery/power/transmission_laser/proc/destroy_lasers()
|
||||
if(target)
|
||||
target.cut_overlay(orbital_strike)
|
||||
target.on_ptl_stop()
|
||||
for(var/obj/effect/transmission_beam/listed_beam as anything in laser_effects)
|
||||
laser_effects -= listed_beam
|
||||
qdel(listed_beam)
|
||||
|
||||
@@ -439,12 +439,12 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
|
||||
name = "Canister \[Air\]"
|
||||
icon_state = "grey" //See Initialize()
|
||||
can_label = FALSE
|
||||
|
||||
/obj/machinery/atmospherics/portable/canister/custom_mix
|
||||
name = "Canister \[Custom\]"
|
||||
icon_state = "whiters" //See Initialize()
|
||||
can_label = FALSE
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/portable/canister/toxins/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -193,6 +193,36 @@
|
||||
difficulty_ore_modifier -= 4
|
||||
enraged = FALSE
|
||||
|
||||
// MARK: PTL Interaction
|
||||
/mob/living/simple_animal/hostile/megafauna/on_ptl_target(obj/machinery/power/transmission_laser/ptl)
|
||||
ptl.RegisterSignal(src, COMSIG_MOB_DEATH, TYPE_PROC_REF(/obj/machinery/power/transmission_laser, untarget), ptl)
|
||||
if(ptl?.firing)
|
||||
on_ptl_fire(ptl)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/on_ptl_tick(obj/machinery/power/transmission_laser/ptl, output_level)
|
||||
loot = list() // disable loot drops form the target to prevent cheese
|
||||
if(10 * output_level * damage_coeff[BURN] / (1 MW) > health) // If we would kill the target dust it.
|
||||
health = 0 // We need this so can_die() won't prevent dusting
|
||||
visible_message("<span class='danger'>\The [src] is reduced to dust by the beam!</span>")
|
||||
dust()
|
||||
else
|
||||
adjustFireLoss(10 * output_level / (1 MW))
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/on_ptl_untarget(obj/machinery/power/transmission_laser/ptl)
|
||||
on_ptl_stop(ptl)
|
||||
if(ptl)
|
||||
ptl.UnregisterSignal(src, COMSIG_MOB_DEATH)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/on_ptl_fire(obj/machinery/power/transmission_laser/ptl)
|
||||
var/orbital_strike = image(icon, src, "orbital_strike", FLY_LAYER, SOUTH)
|
||||
add_overlay(orbital_strike)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/on_ptl_stop(obj/machinery/power/transmission_laser/ptl)
|
||||
for(var/image/overlay in overlays)
|
||||
if(overlay.name == "orbital_strike")
|
||||
cut_overlay(overlay)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/DestroySurroundings()
|
||||
. = ..()
|
||||
for(var/turf/simulated/floor/chasm/C in circlerangeturfs(src, 1))
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
#define CACHE_MAX_LEVEL 10
|
||||
#define LEVEL_DISTRIBUTION_SIGMA 0.5
|
||||
#define LEVEL_REQUIREMENT(level) ((300 MJ) * ((level) ** 3))
|
||||
|
||||
/obj/machinery/alien_cache
|
||||
name = "Alien Cache"
|
||||
desc = "A strange storage device of alien design"
|
||||
icon = 'icons/obj/machines/alien_cache.dmi'
|
||||
icon_state = "cache_0"
|
||||
base_icon_state = "cache_0"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
// Alien stuff is pretty tough
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
/// The maximum reachable level
|
||||
var/max_level = CACHE_MAX_LEVEL
|
||||
/// The deepest level we opened
|
||||
var/level_reached = 0
|
||||
/// The total amount of energy consumed
|
||||
var/total_energy = 0
|
||||
/// Assoc list of level to rewards found at that level with a weight for each
|
||||
var/list/random_rewards = list(
|
||||
// level 1
|
||||
list(
|
||||
/obj/item/stack/sheet/mineral/abductor/fifty = 1,
|
||||
/obj/machinery/the_singularitygen/tesla = 0.3,
|
||||
/obj/machinery/the_singularitygen = 0.3,
|
||||
/obj/item/stack/sheet/mineral/bananium/thirty = 1,
|
||||
/obj/item/stack/sheet/mineral/tranquillite/thirty = 1,
|
||||
),
|
||||
// level 2
|
||||
list(
|
||||
/obj/effect/spawner/random/alien_cache/alien_surgical_tool = 1,
|
||||
/obj/item/mod/module/dispenser = 1,
|
||||
/obj/effect/spawner/alien_cache/mob_capsule = 1,
|
||||
/obj/item/storage/pill_bottle/random_meds/labelled = 1,
|
||||
),
|
||||
// level 3
|
||||
list(
|
||||
/obj/item/mod/module/jetpack/advanced = 1,
|
||||
/obj/effect/spawner/alien_cache/gas_canister = 1,
|
||||
/obj/effect/spawner/random/alien_cache/alien_tool_borg = 1,
|
||||
),
|
||||
// level 4
|
||||
list(
|
||||
/obj/effect/spawner/random/alien_cache/alien_tool = 1,
|
||||
/obj/item/assembly/signaler/anomaly/random = 1,
|
||||
/obj/effect/spawner/alien_cache/gas_canister/agent_b = 1,
|
||||
),
|
||||
// level 5
|
||||
list(
|
||||
/obj/item/storage/belt/military/abductor/full = 1,
|
||||
/obj/item/guardiancreator/biological = 1,
|
||||
),
|
||||
)
|
||||
/// List of guaranteed rewards you get from the last stage
|
||||
var/list/open_rewards = list(
|
||||
/obj/item/circuitboard/machine/bluespace_tap = 1,
|
||||
)
|
||||
/// Terminal for receiving power through
|
||||
var/obj/machinery/power/terminal/terminal
|
||||
|
||||
/obj/machinery/alien_cache/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/multitile, list(
|
||||
list(1, MACH_CENTER, 1),
|
||||
list(1, 0, 1),
|
||||
))
|
||||
|
||||
/obj/machinery/alien_cache/update_overlays()
|
||||
. = ..()
|
||||
var/my_alpha = 0
|
||||
for(var/cache_level in 1 to CACHE_MAX_LEVEL)
|
||||
if(total_energy <= 0 || cache_level > level_reached + 1)
|
||||
break
|
||||
if(cache_level < level_reached + 1)
|
||||
my_alpha = 255
|
||||
if(cache_level == level_reached + 1)
|
||||
my_alpha = clamp(1 - ((LEVEL_REQUIREMENT(cache_level) - total_energy) / (LEVEL_REQUIREMENT(cache_level + 1) - LEVEL_REQUIREMENT(cache_level))), 0, 1)
|
||||
my_alpha *= 255
|
||||
. += mutable_appearance(icon, "cache_level_[cache_level]", alpha = my_alpha)
|
||||
|
||||
/obj/machinery/alien_cache/examine(mob/user)
|
||||
. = ..()
|
||||
if(panel_open)
|
||||
. += "<span class='notice'>The panel is open, revealing unterminated internal wiring.</span>"
|
||||
else
|
||||
. += "<span class='notice'>There's a loose panel on the front that could be pried open with a screwdriver</span>"
|
||||
|
||||
/obj/machinery/alien_cache/display_parts(user)
|
||||
return list("<span class='warning'>ERROR: UNIDENTIFIED MACHINE DESIGN</span>")
|
||||
|
||||
/// generate a list with weights for tiers of loot depending on the reached level
|
||||
/obj/machinery/alien_cache/proc/tier_weights()
|
||||
var/list/tiers = list()
|
||||
// Generate a weighted list of all possible tiers using normal distribution
|
||||
var/avg_tier = (length(random_rewards) * level_reached / max_level)
|
||||
for(var/i in 1 to length(random_rewards))
|
||||
var/tier_prob = normal_distribution(i, avg_tier, LEVEL_DISTRIBUTION_SIGMA)
|
||||
if(tier_prob > 0)
|
||||
tiers["[i]"] = tier_prob
|
||||
|
||||
return tiers
|
||||
|
||||
/// Returns a list of rewards with length equal to amount
|
||||
/obj/machinery/alien_cache/proc/pick_rewards(amount = 1)
|
||||
. = list()
|
||||
if(!amount || amount < 1)
|
||||
return
|
||||
|
||||
var/list/tiers = tier_weights()
|
||||
|
||||
for(var/i in 1 to amount)
|
||||
var/selected_level = text2num(pickweight_fraction(tiers))
|
||||
if(length(random_rewards[selected_level]))
|
||||
. += pickweight_fraction(random_rewards[selected_level])
|
||||
else
|
||||
. += "no rewards in level [selected_level]"
|
||||
|
||||
/obj/machinery/alien_cache/process()
|
||||
if(terminal && level_reached < max_level)
|
||||
var/available = terminal.get_surplus()
|
||||
terminal.consume_direct_power(available)
|
||||
total_energy += available * WATT_TICK_TO_JOULE
|
||||
if(total_energy >= LEVEL_REQUIREMENT(level_reached + 1))
|
||||
level_reached++
|
||||
var/list/rewards = pick_rewards(3)
|
||||
to_chat(world, "Level: [level_reached]\nRewards: [english_list(rewards)]")
|
||||
spawn_loot(rewards)
|
||||
if(level_reached >= max_level)
|
||||
spawn_loot(open_rewards)
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
|
||||
/obj/machinery/alien_cache/proc/spawn_loot(list/loot)
|
||||
var/spawn_side = prob(50) ? WEST : EAST
|
||||
if(dir & (EAST | WEST))
|
||||
// We can turn EAST/WEST into NORTH/SOUTH simply by right shifting
|
||||
spawn_side = spawn_side >> 2
|
||||
var/turf/spawnloc = get_step(get_step(get_step(src, dir), dir), spawn_side)
|
||||
new /obj/effect/portal(spawnloc, null, src, 10)
|
||||
for(var/lootpath in loot)
|
||||
new lootpath(spawnloc)
|
||||
|
||||
/// Items interaction mostly stolen from SMES
|
||||
/obj/machinery/alien_cache/item_interaction(mob/living/user, obj/item/used, list/modifiers)
|
||||
// Building and linking a terminal
|
||||
if(istype(used, /obj/item/stack/cable_coil))
|
||||
var/dir = get_dir(user, src)
|
||||
if(dir & (dir - 1)) // Checks for diagonal interaction
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(terminal) // Checks for an existing terminal
|
||||
to_chat(user, "<span class='alert'>[src] already has a terminal!</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(!panel_open) // Checks to see if the panel is closed
|
||||
to_chat(user, "<span class='alert'>You must open the panel first!</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
var/turf/T = get_turf(user)
|
||||
if(T.intact) // Checks to see if floor plating is present
|
||||
to_chat(user, "<span class='alert'>You must first remove the floor plating!</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
var/obj/item/stack/cable_coil/C = used
|
||||
if(C.get_amount() < 10)
|
||||
to_chat(user, "<span class='alert'>You need more wires.</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(user.loc == loc)
|
||||
to_chat(user, "<span class='warning'>You must not be on the same tile as [src].</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
// Direction the terminal will face to
|
||||
var/turf/temporary_location = get_step(src, REVERSE_DIR(dir))
|
||||
|
||||
if(isspaceturf(temporary_location))
|
||||
to_chat(user, "<span class='warning'>You can't build a terminal on space.</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
else if(istype(temporary_location))
|
||||
if(temporary_location.intact)
|
||||
to_chat(user, "<span class='warning'>You must remove the floor plating first.</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
to_chat(user, "<span class='notice'>You try to connect the cable to [src]</span>")
|
||||
playsound(loc, C.usesound, 50, TRUE)
|
||||
|
||||
if(do_after(user, 5 SECONDS, target = get_turf(src)))
|
||||
if(!terminal && panel_open)
|
||||
T = get_turf(user)
|
||||
var/obj/structure/cable/N = T.get_cable_node() //get the connecting node cable, if there's one
|
||||
if(prob(50) && electrocute_mob(usr, N, N, 1, TRUE)) //animate the electrocution if uncautious and unlucky
|
||||
do_sparks(5, TRUE, src)
|
||||
return
|
||||
|
||||
C.use(10) // make sure the cable gets used up
|
||||
user.visible_message(\
|
||||
"<span class='notice'>[user.name] adds the cables and connects the power terminal.</span>",\
|
||||
"<span class='notice'>You add the cables and connect the power terminal.</span>")
|
||||
|
||||
make_terminal(user, temporary_location)
|
||||
terminal.connect_to_network()
|
||||
stat &= ~BROKEN
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/alien_cache/multitool_act(mob/living/user, obj/item/I)
|
||||
. = TRUE
|
||||
to_chat(user, chat_box_examine("<span class='notice'>Total energy: [DisplayJoules(total_energy)]<br>Levels opened: [level_reached]</span>"))
|
||||
|
||||
/obj/machinery/alien_cache/screwdriver_act(mob/living/user, obj/item/I)
|
||||
// Opening using screwdriver
|
||||
return default_deconstruction_screwdriver(user, "[icon_state]-o", initial(icon_state), I)
|
||||
|
||||
/obj/machinery/alien_cache/wirecutter_act(mob/living/user, obj/item/I)
|
||||
// No terminal to cut, just bonk
|
||||
if(!terminal)
|
||||
return FALSE
|
||||
// If we have a terminal assume we are trying to disassemble it
|
||||
. = TRUE
|
||||
var/turf/T = get_turf(terminal)
|
||||
if(T.intact) //is the floor plating removed ?
|
||||
to_chat(user, "<span class='alert'>You must first expose the power terminal!</span>")
|
||||
return
|
||||
if(!panel_open)
|
||||
to_chat(user, "<span class='alert'>You must first open the panel</span>")
|
||||
to_chat(user, "<span class='notice'>You begin to dismantle the power terminal...</span>")
|
||||
playsound(src.loc, I.usesound, 50, TRUE)
|
||||
|
||||
if(do_after(user, 5 SECONDS * I.toolspeed, target = src))
|
||||
if(terminal && panel_open)
|
||||
if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal, 1, TRUE)) // Animate the electrocution if uncautious and unlucky
|
||||
do_sparks(5, TRUE, src)
|
||||
return
|
||||
|
||||
// Returns wires on deletion of the terminal
|
||||
new /obj/item/stack/cable_coil(T, 10)
|
||||
user.visible_message(\
|
||||
"<span class='alert'>[user.name] cuts the cables and dismantles the power terminal.</span>",\
|
||||
"<span class='notice'>You cut the cables and dismantle the power terminal.</span>")
|
||||
qdel(terminal)
|
||||
return
|
||||
|
||||
/// Terminal creation proc stolen from SMES
|
||||
/obj/machinery/alien_cache/proc/make_terminal(user, temporary_location)
|
||||
// Create a terminal object at the same position as original turf loc
|
||||
// Wires will attach to this
|
||||
terminal = new /obj/machinery/power/terminal(temporary_location)
|
||||
terminal.master = src
|
||||
terminal.dir = REVERSE_DIR(dir)
|
||||
|
||||
#undef CACHE_MAX_LEVEL
|
||||
#undef LEVEL_DISTRIBUTION_SIGMA
|
||||
#undef LEVEL_REQUIREMENT
|
||||
@@ -0,0 +1,108 @@
|
||||
GLOBAL_LIST_EMPTY(laser_terminals)
|
||||
|
||||
/obj/machinery/power/laser_terminal
|
||||
name = "Laser Terminal"
|
||||
desc = "A terminal designed to capture power sent by the power transmission laser"
|
||||
icon = 'icons/obj/machines/ptl_terminal.dmi'
|
||||
icon_state = "ptl_terminal_0"
|
||||
base_icon_state = "ptl_terminal_0"
|
||||
pixel_y = 10
|
||||
density = TRUE
|
||||
/// How much of the received energy we end up outputting to the grid
|
||||
var/conversion_efficiency = 0.5
|
||||
/// List of lasers targetting us
|
||||
var/list/lasers = list()
|
||||
/// The amount of power coming into the PTL
|
||||
var/total_input
|
||||
/// id of the terminal so you know which one you're targetting
|
||||
var/id = 0
|
||||
|
||||
/obj/item/circuitboard/machine/laser_terminal
|
||||
board_name = "Laser Terminal"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/power/laser_terminal
|
||||
origin_tech = "plasmatech=3; powerstorage=4"
|
||||
req_components = list(
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
/obj/item/stock_parts/capacitor = 2,
|
||||
)
|
||||
|
||||
/obj/machinery/power/laser_terminal/Initialize(mapload)
|
||||
. = ..()
|
||||
id = copytext(UID(), findlasttext(UID(), "_") + 1)
|
||||
GLOB.laser_terminals += src
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/machine/laser_terminal(null)
|
||||
component_parts += new /obj/item/stock_parts/capacitor(null)
|
||||
component_parts += new /obj/item/stock_parts/capacitor(null)
|
||||
component_parts += new /obj/item/stack/cable_coil(null, 5)
|
||||
RefreshParts()
|
||||
connect_to_network()
|
||||
|
||||
/obj/machinery/power/laser_terminal/Destroy()
|
||||
GLOB.laser_terminals -= src
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/power/laser_terminal/RefreshParts()
|
||||
var/cap_rating = 0
|
||||
for(var/obj/item/stock_parts/capacitor/cap in component_parts)
|
||||
cap_rating += cap.rating
|
||||
// Goes from half to full conversion depending on capacitor level
|
||||
conversion_efficiency = cap_rating / 8
|
||||
|
||||
/obj/machinery/power/laser_terminal/on_ptl_target(obj/machinery/power/transmission_laser/ptl)
|
||||
lasers |= ptl
|
||||
|
||||
/obj/machinery/power/laser_terminal/on_ptl_untarget(obj/machinery/power/transmission_laser/ptl)
|
||||
lasers -= ptl
|
||||
|
||||
/obj/machinery/power/laser_terminal/update_overlays()
|
||||
. = ..()
|
||||
if(total_input > 0)
|
||||
. += "ptl_terminal_graph"
|
||||
. += "ptl_terminal_blinkers"
|
||||
. += "ptl_terminal_light"
|
||||
switch(total_input)
|
||||
if(1 MW to 10 MW)
|
||||
. += "ptl_terminal_bar_1"
|
||||
if(10 MW to 20 MW)
|
||||
. += "ptl_terminal_bar_2"
|
||||
if(20 MW to 50 MW)
|
||||
. += "ptl_terminal_bar_3"
|
||||
if(50 MW to 100 MW)
|
||||
. += "ptl_terminal_bar_4"
|
||||
if(100 MW to 1 GW)
|
||||
. += "ptl_terminal_bar_5"
|
||||
if(1 GW to INFINITY)
|
||||
. += "ptl_terminal_bar_6"
|
||||
|
||||
/obj/machinery/power/laser_terminal/process()
|
||||
var/tick_input = 0
|
||||
for(var/obj/machinery/power/transmission_laser/ptl in lasers)
|
||||
if(ptl.firing)
|
||||
tick_input += ptl.output_level
|
||||
// We use another var so we don't zero total input since it's also used for other things that could potentially happen mid-process
|
||||
total_input = tick_input
|
||||
produce_direct_power(total_input * conversion_efficiency)
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/power/laser_terminal/screwdriver_act(mob/living/user, obj/item/I)
|
||||
return default_deconstruction_screwdriver(user, initial(icon_state), initial(icon_state), I)
|
||||
|
||||
/obj/machinery/power/laser_terminal/wrench_act(mob/living/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(panel_open)
|
||||
to_chat(user, "<span class='warning'>Close the maintenance panel first!</span>")
|
||||
return
|
||||
. = default_unfasten_wrench(user, I, 2)
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
else
|
||||
disconnect_from_network()
|
||||
|
||||
/obj/machinery/power/laser_terminal/crowbar_act(mob/living/user, obj/item/I)
|
||||
return default_deconstruction_crowbar(user, I, FALSE)
|
||||
|
||||
/obj/machinery/power/laser_terminal/multitool_act(mob/living/user, obj/item/I)
|
||||
. = TRUE
|
||||
to_chat(user, chat_box_examine("<span class='notice'>Unit ID: [id]<br>Input Power: [DisplayPower(total_input)]<br>Output Power: [DisplayPower(total_input * conversion_efficiency)]</span>"))
|
||||
@@ -12,6 +12,16 @@
|
||||
build_path = /obj/item/circuitboard/thermomachine
|
||||
category = list ("Engineering Machinery")
|
||||
|
||||
/datum/design/laser_terminal
|
||||
name = "Machine Board (Laser Terminal)"
|
||||
desc = "The circuit board for a PTL terminal."
|
||||
id = "thermomachine"
|
||||
req_tech = list("powerstorage" = 4, "plasmatech" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 1000)
|
||||
build_path = /obj/item/circuitboard/machine/laser_terminal
|
||||
category = list ("Engineering Machinery")
|
||||
|
||||
/datum/design/space_heater
|
||||
name = "Machine Board (Space Heater)"
|
||||
desc = "The circuit board for a space heater"
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/obj/machinery/door/airlock/abductor/secure
|
||||
security_level = 6
|
||||
autoclose = FALSE
|
||||
flags = INDESTRUCTIBLE
|
||||
locked = TRUE
|
||||
req_access = list()
|
||||
|
||||
/obj/machinery/door/airlock/abductor/secure/Initialize(mapload)
|
||||
. = ..()
|
||||
// Randomize the wires so they aren't the same as the station
|
||||
wires.randomize()
|
||||
|
||||
/// Always returns false since you aren't supposed to open it normally
|
||||
/obj/machinery/door/airlock/abductor/secure/check_access(obj/item/I)
|
||||
return FALSE
|
||||
@@ -0,0 +1,184 @@
|
||||
/obj/effect/simon_says
|
||||
name = "strange platform"
|
||||
desc = "A strange platform of alien design."
|
||||
icon = 'icons/effects/simon_says_32x32.dmi'
|
||||
icon_state = "pad"
|
||||
var/fail_sound = 'sound/effects/simon_says_wrong.ogg'
|
||||
var/success_sound = 'sound/effects/simon_says_success.ogg'
|
||||
/// The chosen rhythm to play
|
||||
var/list/rhythm = list()
|
||||
/// List of all rhythms to choose from, made from lists of time from the start in deciseconds
|
||||
var/static/list/rhythms = list(
|
||||
// 7 Elevens are like the greatest thing
|
||||
list(0, 7, 11, 14, 21, 22, 28, 33, 35, 42, 44, 49, 55, 56, 63, 66, 70),
|
||||
list(0, 2.5, 7.5, 10, 15, 17.5, 22.5, 27.5, 30, 35, 40),
|
||||
list(0, 8, 10, 16, 20, 24, 30, 32, 40),
|
||||
list(0, 6, 10, 12, 18, 20, 24, 30),
|
||||
list(0, 3, 6, 12, 18, 30, 33, 36, 39, 45, 51),
|
||||
)
|
||||
var/static/list/pad_colors = list(
|
||||
"#b45e5e",
|
||||
"#3c6474",
|
||||
"#8a7d44",
|
||||
"#b45e5e",
|
||||
"#3c6474",
|
||||
"#8a7d44",
|
||||
)
|
||||
var/static/list/pad_sounds = list(
|
||||
'sound/effects/simon_says_1.ogg',
|
||||
'sound/effects/simon_says_2.ogg',
|
||||
'sound/effects/simon_says_3.ogg',
|
||||
'sound/effects/simon_says_4.ogg',
|
||||
'sound/effects/simon_says_5.ogg',
|
||||
'sound/effects/simon_says_6.ogg',)
|
||||
/// The time at which we should finish playing the sequence
|
||||
var/playing_until = 0
|
||||
/// Buttons pressed by the player so far
|
||||
var/list/pressed_buttons = list()
|
||||
/// The sequence we generated
|
||||
var/list/sequence = list()
|
||||
/// List of connected pads(normally generated on init)
|
||||
var/list/pads = list()
|
||||
/// current index in the sequence we check our pressed button against
|
||||
var/current_index = 0
|
||||
/// ID for autolinking an airlock on init
|
||||
var/autolink_id
|
||||
/// UID of the linked airlock
|
||||
var/airlock_uid
|
||||
|
||||
/obj/effect/simon_says/Initialize(mapload)
|
||||
. = ..()
|
||||
var/turf/place = get_turf(src)
|
||||
place = locate(place.x, place.y + 4, place.z)
|
||||
if(place.x >= world.maxx - 1 || place.x <= 2 || place.y >= world.maxy - 1 || place.y <= 2)
|
||||
qdel(src)
|
||||
return
|
||||
var/id = 1
|
||||
for(var/cardinal in list(NORTHWEST, NORTHEAST, EAST, SOUTHEAST, SOUTHWEST, WEST))
|
||||
var/turf/curr_place = place
|
||||
if(cardinal & (NORTH | SOUTH))
|
||||
curr_place = get_step(place, cardinal & (NORTH | SOUTH))
|
||||
else
|
||||
curr_place = get_step(place, cardinal & (EAST | WEST))
|
||||
pads += new /obj/effect/simon_says_pad(get_step(curr_place, cardinal), id++, src)
|
||||
|
||||
/obj/effect/simon_says/Destroy()
|
||||
for(var/obj/effect/simon_says_pad/pad in pads)
|
||||
qdel(pad)
|
||||
return ..()
|
||||
|
||||
/obj/effect/simon_says/Cross(atom/movable/crossed_atom)
|
||||
. = ..()
|
||||
if(!ismob(crossed_atom) || (playing_until >= world.time))
|
||||
return
|
||||
play_music()
|
||||
|
||||
/obj/effect/simon_says/proc/reset_buttons()
|
||||
pressed_buttons = list()
|
||||
current_index = 0
|
||||
|
||||
/obj/effect/simon_says/proc/play_music()
|
||||
if(!length(sequence))
|
||||
generate_sequence()
|
||||
playing_until = world.time + rhythm[length(rhythm)]
|
||||
reset_buttons()
|
||||
for(var/i in 1 to length(sequence))
|
||||
var/obj/effect/simon_says_pad/curr_pad = pads[sequence[i]]
|
||||
addtimer(CALLBACK(curr_pad, TYPE_PROC_REF(/obj/effect/simon_says_pad, play_note)), rhythm[i])
|
||||
for(var/obj/machinery/door/airlock/to_link in range(10, get_turf(src)))
|
||||
if(to_link.id_tag == autolink_id)
|
||||
airlock_uid = to_link.UID()
|
||||
|
||||
/obj/effect/simon_says/proc/generate_sequence()
|
||||
sequence = list()
|
||||
if(!length(rhythm))
|
||||
rhythm = pick(rhythms)
|
||||
var/list/pad_options = list()
|
||||
|
||||
// The reason we do all this instead of just rand(1, length(pads)) is so we can exclude pads that were played too recently
|
||||
for(var/i in 1 to length(pads))
|
||||
pad_options += list(list(i, -5))
|
||||
|
||||
for(var/beat in rhythm)
|
||||
// Exclude pads that have played too recently
|
||||
var/list/excluded = list()
|
||||
for(var/option in pad_options)
|
||||
if(beat - option[2] < 3)
|
||||
excluded += list(option)
|
||||
pad_options -= excluded
|
||||
var/picked = pick(pad_options)
|
||||
sequence += picked[1]
|
||||
picked[2] = beat
|
||||
pad_options += excluded
|
||||
|
||||
/obj/effect/simon_says/proc/check_completion()
|
||||
if(!sequence || !length(sequence))
|
||||
return
|
||||
if(sequence[current_index] != pressed_buttons[current_index])
|
||||
do_failure()
|
||||
return
|
||||
if(current_index == length(sequence))
|
||||
do_success()
|
||||
|
||||
|
||||
/obj/effect/simon_says/proc/play_sound(sound, blink_color)
|
||||
animate_flash(src, blink_color, 2)
|
||||
playsound(src, sound, 100, FALSE, falloff_exponent = SOUND_FALLOFF_EXPONENT / 4)
|
||||
|
||||
/obj/effect/simon_says/proc/do_failure()
|
||||
reset_buttons()
|
||||
play_sound(fail_sound, "#ff1100")
|
||||
|
||||
/obj/effect/simon_says/proc/do_success()
|
||||
reset_buttons()
|
||||
play_sound(success_sound, "#00e600")
|
||||
var/obj/machinery/door/airlock/activated = locateUID(airlock_uid)
|
||||
activated.airlock_cycle_callback("secure_open")
|
||||
|
||||
|
||||
/obj/effect/simon_says_pad
|
||||
name = "strange platform"
|
||||
desc = "A strange platform of alien design, it looks like something will happen if you stand on it"
|
||||
icon = 'icons/effects/simon_says_32x32.dmi'
|
||||
icon_state = "pad"
|
||||
//pixel_x = -8
|
||||
//pixel_y = -8
|
||||
/// The simon says minigame we are a part of
|
||||
var/obj/effect/simon_says/owner
|
||||
/// Sound we make when playing
|
||||
var/sound = 'sound/effects/simon_says_1.ogg'
|
||||
/// ID used for comparing what we pressed against the sequence
|
||||
var/id = 1
|
||||
/// Time the pad was last played
|
||||
var/last_played = 0
|
||||
|
||||
/obj/effect/simon_says_pad/Initialize(mapload, _id, _owner)
|
||||
. = ..()
|
||||
owner = _owner
|
||||
id = _id
|
||||
if(owner)
|
||||
color = owner.pad_colors[id]
|
||||
sound = owner.pad_sounds[id]
|
||||
|
||||
/obj/effect/simon_says_pad/proc/play_note()
|
||||
last_played = world.time
|
||||
var/list/hsl = rgb2num(color, COLORSPACE_HSL)
|
||||
hsl[3] = hsl[3] + (100 - hsl[3]) * 0.7
|
||||
var/target = rgb(hsl[1], hsl[2], hsl[3], space= COLORSPACE_HSL)
|
||||
playsound(src, sound, 100, FALSE, falloff_exponent = SOUND_FALLOFF_EXPONENT / 4)
|
||||
animate_flash(src, target, 1.5)
|
||||
|
||||
/obj/effect/simon_says_pad/Cross(atom/movable/crossed_atom)
|
||||
. = ..()
|
||||
if(!ismob(crossed_atom) || (owner.playing_until >= world.time) || world.time < last_played + 3)
|
||||
return
|
||||
play_note()
|
||||
owner.pressed_buttons += id
|
||||
owner.current_index++
|
||||
owner.check_completion()
|
||||
|
||||
/proc/animate_flash(atom/to_flash , color, length)
|
||||
var/my_color = to_flash.color
|
||||
animate(to_flash, color = color, time = length, easing = SINE_EASING)
|
||||
spawn(length)
|
||||
animate(to_flash, color = my_color, time = length, easing = SINE_EASING)
|
||||
@@ -674,6 +674,7 @@ active_space_ruins = [
|
||||
"_maps/map_files/RandomRuins/SpaceRuins/way_home.dmm",
|
||||
"_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm",
|
||||
"_maps/map_files/RandomRuins/SpaceRuins/wreckedcargoship.dmm",
|
||||
"_maps/map_files/RandomRuins/SpaceRuins/alien_cache_site.dmm",
|
||||
|
||||
### The following ruins are based from past pre-spawned Zlevel content ###
|
||||
"_maps/map_files/RandomRuins/SpaceRuins/abandonedtele.dmm",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 423 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@@ -850,6 +850,7 @@
|
||||
#include "code\game\area\shuttle_areas.dm"
|
||||
#include "code\game\area\areas\depot-areas.dm"
|
||||
#include "code\game\area\areas\mining_areas.dm"
|
||||
#include "code\game\area\areas\ruins\alien_cache_site_areas.dm"
|
||||
#include "code\game\area\areas\ruins\blackmarketpackers.dm"
|
||||
#include "code\game\area\areas\ruins\lavaland_areas.dm"
|
||||
#include "code\game\area\areas\ruins\space_areas.dm"
|
||||
@@ -1194,6 +1195,7 @@
|
||||
#include "code\game\objects\effects\spawners\random_barrier.dm"
|
||||
#include "code\game\objects\effects\spawners\vaultspawner.dm"
|
||||
#include "code\game\objects\effects\spawners\windowspawner.dm"
|
||||
#include "code\game\objects\effects\spawners\random\alien_cache_random_spawners.dm"
|
||||
#include "code\game\objects\effects\spawners\random\bluespace_tap_spawners.dm"
|
||||
#include "code\game\objects\effects\spawners\random\decal_spawners.dm"
|
||||
#include "code\game\objects\effects\spawners\random\engineering_spawners.dm"
|
||||
@@ -2874,8 +2876,10 @@
|
||||
#include "code\modules\pda\games\minesweeper.dm"
|
||||
#include "code\modules\persistence\persistence.dm"
|
||||
#include "code\modules\point\point.dm"
|
||||
#include "code\modules\power\alien_cache.dm"
|
||||
#include "code\modules\power\cell.dm"
|
||||
#include "code\modules\power\gravitygenerator.dm"
|
||||
#include "code\modules\power\laser_terminal.dm"
|
||||
#include "code\modules\power\lights.dm"
|
||||
#include "code\modules\power\power_machine.dm"
|
||||
#include "code\modules\power\smes.dm"
|
||||
@@ -3087,6 +3091,8 @@
|
||||
#include "code\modules\ruins\objects_and_mobs\gym.dm"
|
||||
#include "code\modules\ruins\objects_and_mobs\id_upgrader.dm"
|
||||
#include "code\modules\ruins\objects_and_mobs\necropolis_gate.dm"
|
||||
#include "code\modules\ruins\objects_and_mobs\secure_alien_airlock.dm"
|
||||
#include "code\modules\ruins\objects_and_mobs\simon_says.dm"
|
||||
#include "code\modules\ruins\spaceruin_code\voyager.dm"
|
||||
#include "code\modules\security_levels\keycard_authentication.dm"
|
||||
#include "code\modules\security_levels\security_level_datums.dm"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user