mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
[MIRROR] Adds a Bluespace Connection component (#11860)
Co-authored-by: Guti <32563288+TheCaramelion@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
committed by
GitHub
parent
80a413f675
commit
62dd29255b
@@ -10,3 +10,6 @@
|
||||
|
||||
/// from base of [/atom/proc/extinguish]
|
||||
#define COMSIG_ATOM_EXTINGUISH "atom_extinguish"
|
||||
|
||||
/// From base atom/hitby(atom/movable/AM)
|
||||
#define COMSIG_ATOM_HITBY "atom_hitby"
|
||||
|
||||
@@ -2,3 +2,5 @@
|
||||
#define COMSIG_ARCADE_PRIZEVEND "arcade_prizevend"
|
||||
///from /obj/machinery/rnd/destructive_analyzer/proc/destroy_item_individual(gain_research_points = FALSE): Runs when the destructive scanner scans a group of objects. (obj/item)
|
||||
#define COMSIG_MACHINERY_DESTRUCTIVE_SCAN "machinery_destructive_scan"
|
||||
///from /obj/structure/closet/close()
|
||||
#define COMSIG_CLOSET_CLOSED "closet_closed"
|
||||
|
||||
@@ -63,3 +63,5 @@ GLOBAL_LIST_EMPTY(verminstart)
|
||||
GLOBAL_LIST_EMPTY(awayabductors) // List of scatter landmarks for Abductors in Gateways
|
||||
GLOBAL_LIST_EMPTY(eventdestinations) // List of scatter landmarks for VOREStation event portals
|
||||
GLOBAL_LIST_EMPTY(eventabductors) // List of scatter landmarks for VOREStation abductor portals
|
||||
|
||||
GLOBAL_LIST_EMPTY(bslockers) // List of (roundstart) bluespace lockers
|
||||
|
||||
127
code/datums/components/structures/bluespace_connection.dm
Normal file
127
code/datums/components/structures/bluespace_connection.dm
Normal file
@@ -0,0 +1,127 @@
|
||||
/// Bluespace connection component.
|
||||
/// Given to lockers to make them into portals.
|
||||
/datum/component/bluespace_connection
|
||||
/// Assigned closet
|
||||
VAR_PROTECTED/obj/structure/closet/assigned_closet = null
|
||||
/// List of possible exits
|
||||
var/list/connections = list()
|
||||
/// Exit sound that it'll make upon exiting
|
||||
var/exit_sound
|
||||
// How far things gets thrown
|
||||
var/throw_range
|
||||
// Turf range when exiting, x
|
||||
var/throw_range_x
|
||||
// Turf range when exiting, y
|
||||
var/throw_range_y
|
||||
|
||||
/// Use this one when using a global list of exits
|
||||
/// Giving this to any locker will connect it to the network, allowing extra or none at any given point.
|
||||
/datum/component/bluespace_connection/permanent_network
|
||||
|
||||
/datum/component/bluespace_connection/Initialize(var/list/connections, exit_sound = 'sound/effects/clang.ogg', throw_range = 3, throw_range_x = 5, throw_range_y = 5)
|
||||
assigned_closet = parent
|
||||
|
||||
if(!istype(assigned_closet, /obj/structure/closet)) // Might expand this in the future? For now, it only goes on closets.
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
src.connections = connections
|
||||
src.exit_sound = exit_sound
|
||||
src.throw_range = throw_range
|
||||
src.throw_range_x = throw_range_x
|
||||
src.throw_range_y = throw_range_y
|
||||
|
||||
/datum/component/bluespace_connection/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_CLOSET_CLOSED, PROC_REF(on_close))
|
||||
RegisterSignal(parent, COMSIG_ATOM_HITBY, PROC_REF(on_hit))
|
||||
|
||||
/datum/component/bluespace_connection/UnregisterFromParent()
|
||||
UnregisterSignal(parent, list(COMSIG_CLOSET_CLOSED, COMSIG_ATOM_HITBY))
|
||||
|
||||
/datum/component/bluespace_connection/Destroy()
|
||||
assigned_closet = null
|
||||
. = ..()
|
||||
|
||||
/datum/component/bluespace_connection/proc/on_close()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(isemptylist(assigned_closet.contents))
|
||||
return
|
||||
|
||||
var/exit_point = pick(connections)
|
||||
|
||||
if(exit_point == assigned_closet)
|
||||
sever_connection(exit_point)
|
||||
return
|
||||
|
||||
if(istype(exit_point, /obj/structure/closet))
|
||||
var/obj/structure/closet/exit_closet = exit_point
|
||||
exit_closet.visible_message(span_notice("\The [exit_closet] rumbles..."), span_notice("Something rumbles..."))
|
||||
exit_closet.animate_shake()
|
||||
addtimer(CALLBACK(exit_closet, TYPE_PROC_REF(/obj/structure/closet, open)), 1 SECONDS)
|
||||
|
||||
playsound(exit_point, exit_sound, 50, TRUE)
|
||||
addtimer(CALLBACK(src, PROC_REF(exit_connection), exit_point, assigned_closet.contents), 1.3 SECONDS)
|
||||
|
||||
/datum/component/bluespace_connection/proc/exit_connection(var/atom/exit_point, var/list/contents)
|
||||
// Nope, must be closed.
|
||||
if(assigned_closet.opened)
|
||||
return
|
||||
|
||||
if(QDELETED(exit_point))
|
||||
sever_connection(exit_point)
|
||||
return
|
||||
|
||||
// Now the fun begins
|
||||
if(istype(exit_point, /obj/structure/closet))
|
||||
var/obj/structure/closet/exit_closet = exit_point
|
||||
if(!exit_closet.can_open()) // Bwomp. You're locked now. :)
|
||||
for(var/atom/movable/AM in contents)
|
||||
do_noeffect_teleport(AM, exit_closet, 0, 1)
|
||||
return
|
||||
exit_closet.open()
|
||||
|
||||
var/turf/target = throw_target()
|
||||
|
||||
if(contents.len)
|
||||
for(var/atom/movable/AM in contents)
|
||||
if(QDELETED(AM))
|
||||
continue
|
||||
do_noeffect_teleport(AM, get_turf(exit_point), 0, 1)
|
||||
if(!isbelly(exit_point))
|
||||
AM.throw_at(target, throw_range, 1)
|
||||
contents.Cut()
|
||||
return
|
||||
|
||||
/datum/component/bluespace_connection/proc/on_hit()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(assigned_closet.opened)
|
||||
assigned_closet.close()
|
||||
return
|
||||
|
||||
/datum/component/bluespace_connection/proc/throw_target()
|
||||
return get_offset_target_turf(get_turf(assigned_closet), rand(throw_range_x)-rand(throw_range_x), rand(throw_range_y)-rand(throw_range_y))
|
||||
|
||||
/datum/component/bluespace_connection/proc/add_exit(var/exit_point)
|
||||
connections.Add(exit_point)
|
||||
return TRUE
|
||||
|
||||
/datum/component/bluespace_connection/proc/sever_connection(var/removed_exit)
|
||||
connections -= removed_exit
|
||||
|
||||
do_sparks()
|
||||
|
||||
if(!connections.len) // No exit points left, bluespace connection severed.
|
||||
qdel(src)
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/component/bluespace_connection/permanent_network/sever_connection(removed_exit)
|
||||
do_sparks()
|
||||
return TRUE
|
||||
|
||||
/datum/component/bluespace_connection/proc/do_sparks()
|
||||
playsound(assigned_closet, 'sound/effects/sparks6.ogg', 100, TRUE)
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread
|
||||
sparks.set_up(2, 1, assigned_closet.loc)
|
||||
sparks.start()
|
||||
@@ -298,6 +298,7 @@
|
||||
|
||||
|
||||
/atom/proc/hitby(atom/movable/source)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_HITBY, source)
|
||||
if (density)
|
||||
source.throwing = 0
|
||||
return
|
||||
|
||||
@@ -295,3 +295,11 @@
|
||||
/// In landmarks.dm and not unit_test.dm so it is always active in the mapping tools.
|
||||
/obj/effect/landmark/unit_test_top_right
|
||||
name = "unit test zone top right"
|
||||
|
||||
/obj/effect/landmark/bslocker
|
||||
name = "bslocker spawn"
|
||||
|
||||
/obj/effect/landmark/bslocker/Initialize(mapload)
|
||||
. = ..()
|
||||
var/obj/structure/closet/closet = new /obj/structure/closet/bluespace(loc)
|
||||
GLOB.bslockers.Add(closet)
|
||||
|
||||
@@ -168,6 +168,7 @@
|
||||
if(initial(density))
|
||||
density = !density
|
||||
animate_door(TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_CLOSET_CLOSED, contents)
|
||||
return 1
|
||||
|
||||
//Cham Projector Exception
|
||||
@@ -585,3 +586,7 @@
|
||||
var/mob/living/M = usr
|
||||
if(isliving(M))
|
||||
M.begin_instant_nom(M,target,M,M.vore_selected)
|
||||
|
||||
/obj/structure/closet/bluespace/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/bluespace_connection/permanent_network, GLOB.bslockers)
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
AddElement(/datum/element/climbable)
|
||||
AddElement(/datum/element/rotatable)
|
||||
|
||||
/obj/structure/closet/crate/can_open()
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/crate/can_close()
|
||||
return 1
|
||||
|
||||
@@ -42,6 +39,8 @@
|
||||
playsound(src, open_sound, 50, 1, -3)
|
||||
for(var/obj/O in src)
|
||||
O.forceMove(get_turf(src))
|
||||
for(var/mob/M in src)
|
||||
M.forceMove(get_turf(src))
|
||||
src.opened = 1
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_CLIMBABLE_SHAKE_CLIMBERS, null)
|
||||
@@ -75,6 +74,8 @@
|
||||
/obj/structure/closet/crate/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(W.has_tool_quality(TOOL_WRENCH) && istype(src,/obj/structure/closet/crate/bin))
|
||||
return ..()
|
||||
else if(W.has_tool_quality(TOOL_WELDER))
|
||||
return ..()
|
||||
else if(opened)
|
||||
if(isrobot(user))
|
||||
return
|
||||
@@ -129,6 +130,11 @@
|
||||
return
|
||||
return
|
||||
|
||||
/obj/structure/closet/req_breakout()
|
||||
if(opened || !sealed)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/crate/secure
|
||||
desc = "A secure crate."
|
||||
name = "Secure crate"
|
||||
@@ -136,6 +142,11 @@
|
||||
var/broken = 0
|
||||
var/locked = 1
|
||||
|
||||
/obj/structure/closet/crate/secure/req_breakout()
|
||||
if(opened || !locked || !sealed)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/crate/secure/can_open()
|
||||
return !locked
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -686,6 +686,7 @@
|
||||
#include "code\datums\components\species\shadekin\powers\regenerate_other.dm"
|
||||
#include "code\datums\components\species\shadekin\powers\dark_tunnel\dark_tunnel_structures.dm"
|
||||
#include "code\datums\components\species\shadekin\powers\dark_tunnel\dark_tunneling.dm"
|
||||
#include "code\datums\components\structures\bluespace_connection.dm"
|
||||
#include "code\datums\components\traits\burninlight.dm"
|
||||
#include "code\datums\components\traits\crowd_detection.dm"
|
||||
#include "code\datums\components\traits\drippy.dm"
|
||||
|
||||
Reference in New Issue
Block a user