mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-19 19:18:50 +01:00
About The Pull Request Permanent portals no longer randomly select a portal to use as their exit, and instead stick with the first one they find, they're supposed to only have one linked portal anyways. Adds a portal exit landmark, one-way portals use this to define their exit as opposed to the weird as hell and pointless portal deletion system I was using before, also nice for mapping since they have different icons so you can more easily tell which is which. Adds One-Use portals, they're just one-way portals that delete after they're used, was requested for a reference off-station thing someone was making, probably also useful for things like mobs that die and spawn portals to an area, most likely will be used in ice moon. Goat ruin was the only thing using the permanent portal system for ruins so far since VR hub got removed, so I just moved that over to use the landmarks. Why It's Good For The Game The old code is garbage I wrote like a year ago because it was packaged with VR hub, and someone added copy-pasta at some point, absolutely terrible. This cuts down on a lot. Changelog 🆑 refactor: Permanent Portal fixes and One-Way Portal improvements for mapping. /🆑
229 lines
7.1 KiB
Plaintext
229 lines
7.1 KiB
Plaintext
|
|
/proc/create_portal_pair(turf/source, turf/destination, _lifespan = 300, accuracy = 0, newtype = /obj/effect/portal, atmos_link_override)
|
|
if(!istype(source) || !istype(destination))
|
|
return
|
|
var/turf/actual_destination = get_teleport_turf(destination, accuracy)
|
|
var/obj/effect/portal/P1 = new newtype(source, _lifespan, null, FALSE, null, atmos_link_override)
|
|
var/obj/effect/portal/P2 = new newtype(actual_destination, _lifespan, P1, TRUE, null, atmos_link_override)
|
|
if(!istype(P1)||!istype(P2))
|
|
return
|
|
P1.link_portal(P2)
|
|
P1.hardlinked = TRUE
|
|
return list(P1, P2)
|
|
|
|
/obj/effect/portal
|
|
name = "portal"
|
|
desc = "Looks unstable. Best to test it with the clown."
|
|
icon = 'icons/obj/stationobjs.dmi'
|
|
icon_state = "portal"
|
|
anchored = TRUE
|
|
var/mech_sized = FALSE
|
|
var/obj/effect/portal/linked
|
|
var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted.
|
|
var/teleport_channel = TELEPORT_CHANNEL_BLUESPACE
|
|
var/turf/hard_target //For when a portal needs a hard target and isn't to be linked.
|
|
var/atmos_link = FALSE //Link source/destination atmos.
|
|
var/turf/open/atmos_source //Atmos link source
|
|
var/turf/open/atmos_destination //Atmos link destination
|
|
var/allow_anchored = FALSE
|
|
var/innate_accuracy_penalty = 0
|
|
var/last_effect = 0
|
|
var/force_teleport = FALSE
|
|
|
|
/obj/effect/portal/anom
|
|
name = "wormhole"
|
|
icon = 'icons/obj/objects.dmi'
|
|
icon_state = "anom"
|
|
layer = RIPPLE_LAYER
|
|
mech_sized = TRUE
|
|
teleport_channel = TELEPORT_CHANNEL_WORMHOLE
|
|
|
|
/obj/effect/portal/Move(newloc)
|
|
for(var/T in newloc)
|
|
if(istype(T, /obj/effect/portal))
|
|
return FALSE
|
|
return ..()
|
|
|
|
/obj/effect/portal/attackby(obj/item/W, mob/user, params)
|
|
if(user && Adjacent(user))
|
|
user.forceMove(get_turf(src))
|
|
return TRUE
|
|
|
|
/obj/effect/portal/Crossed(atom/movable/AM, oldloc, force_stop = 0)
|
|
if(force_stop)
|
|
return ..()
|
|
if(isobserver(AM))
|
|
return ..()
|
|
if(linked && (get_turf(oldloc) == get_turf(linked)))
|
|
return ..()
|
|
if(!teleport(AM))
|
|
return ..()
|
|
|
|
/obj/effect/portal/attack_tk(mob/user)
|
|
return
|
|
|
|
/obj/effect/portal/attack_hand(mob/user)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
if(get_turf(user) == get_turf(src))
|
|
teleport(user)
|
|
if(Adjacent(user))
|
|
user.forceMove(get_turf(src))
|
|
|
|
/obj/effect/portal/Initialize(mapload, _lifespan = 0, obj/effect/portal/_linked, automatic_link = FALSE, turf/hard_target_override, atmos_link_override)
|
|
. = ..()
|
|
GLOB.portals += src
|
|
if(!istype(_linked) && automatic_link)
|
|
. = INITIALIZE_HINT_QDEL
|
|
CRASH("Somebody fucked up.")
|
|
if(_lifespan > 0)
|
|
QDEL_IN(src, _lifespan)
|
|
if(!isnull(atmos_link_override))
|
|
atmos_link = atmos_link_override
|
|
link_portal(_linked)
|
|
hardlinked = automatic_link
|
|
if(isturf(hard_target_override))
|
|
hard_target = hard_target_override
|
|
|
|
/obj/effect/portal/singularity_pull()
|
|
return
|
|
|
|
/obj/effect/portal/singularity_act()
|
|
return
|
|
|
|
/obj/effect/portal/proc/link_portal(obj/effect/portal/newlink)
|
|
linked = newlink
|
|
if(atmos_link)
|
|
link_atmos()
|
|
|
|
/obj/effect/portal/proc/link_atmos()
|
|
if(atmos_source || atmos_destination)
|
|
unlink_atmos()
|
|
if(!isopenturf(get_turf(src)))
|
|
return FALSE
|
|
if(linked)
|
|
if(isopenturf(get_turf(linked)))
|
|
atmos_source = get_turf(src)
|
|
atmos_destination = get_turf(linked)
|
|
else if(hard_target)
|
|
if(isopenturf(hard_target))
|
|
atmos_source = get_turf(src)
|
|
atmos_destination = hard_target
|
|
else
|
|
return FALSE
|
|
if(!istype(atmos_source) || !istype(atmos_destination))
|
|
return FALSE
|
|
LAZYINITLIST(atmos_source.atmos_adjacent_turfs)
|
|
LAZYINITLIST(atmos_destination.atmos_adjacent_turfs)
|
|
if(atmos_source.atmos_adjacent_turfs[atmos_destination] || atmos_destination.atmos_adjacent_turfs[atmos_source]) //Already linked!
|
|
return FALSE
|
|
atmos_source.atmos_adjacent_turfs[atmos_destination] = TRUE
|
|
atmos_destination.atmos_adjacent_turfs[atmos_source] = TRUE
|
|
atmos_source.air_update_turf(FALSE)
|
|
atmos_destination.air_update_turf(FALSE)
|
|
|
|
/obj/effect/portal/proc/unlink_atmos()
|
|
if(istype(atmos_source))
|
|
if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !CANATMOSPASS(atmos_destination, atmos_source))
|
|
LAZYREMOVE(atmos_source.atmos_adjacent_turfs, atmos_destination)
|
|
atmos_source = null
|
|
if(istype(atmos_destination))
|
|
if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !CANATMOSPASS(atmos_source, atmos_destination))
|
|
LAZYREMOVE(atmos_destination.atmos_adjacent_turfs, atmos_source)
|
|
atmos_destination = null
|
|
|
|
/obj/effect/portal/Destroy()
|
|
GLOB.portals -= src
|
|
unlink_atmos()
|
|
if(hardlinked && !QDELETED(linked))
|
|
QDEL_NULL(linked)
|
|
else
|
|
linked = null
|
|
return ..()
|
|
|
|
/obj/effect/portal/attack_ghost(mob/dead/observer/O)
|
|
if(!teleport(O, TRUE))
|
|
return ..()
|
|
|
|
/obj/effect/portal/proc/teleport(atom/movable/M, force = FALSE)
|
|
if(!force && (!istype(M) || iseffect(M) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M)))) //Things that shouldn't teleport.
|
|
return
|
|
var/turf/real_target = get_link_target_turf()
|
|
if(!istype(real_target))
|
|
return FALSE
|
|
if(!force && (!ismecha(M) && !istype(M, /obj/projectile) && M.anchored && !allow_anchored))
|
|
return
|
|
if(ismegafauna(M))
|
|
message_admins("[M] has used a portal at [ADMIN_VERBOSEJMP(src)] made by [usr].")
|
|
var/no_effect = FALSE
|
|
if(last_effect == world.time)
|
|
no_effect = TRUE
|
|
else
|
|
last_effect = world.time
|
|
if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect, channel = teleport_channel, forced = force_teleport))
|
|
if(istype(M, /obj/projectile))
|
|
var/obj/projectile/P = M
|
|
P.ignore_source_check = TRUE
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/obj/effect/portal/proc/get_link_target_turf()
|
|
var/turf/real_target
|
|
if(!istype(linked) || QDELETED(linked))
|
|
if(hardlinked)
|
|
qdel(src)
|
|
if(!istype(hard_target) || QDELETED(hard_target))
|
|
hard_target = null
|
|
return
|
|
else
|
|
real_target = hard_target
|
|
linked = null
|
|
else
|
|
real_target = get_turf(linked)
|
|
return real_target
|
|
|
|
/obj/effect/portal/permanent
|
|
name = "permanent portal"
|
|
desc = "An unwavering portal that will never fade."
|
|
hardlinked = FALSE // dont qdel my portal nerd
|
|
force_teleport = TRUE // force teleports because they're a mapmaker tool
|
|
var/id // var edit or set id in map editor
|
|
|
|
/obj/effect/portal/permanent/proc/set_linked()
|
|
if(!id)
|
|
return
|
|
for(var/obj/effect/portal/permanent/P in GLOB.portals - src)
|
|
if(P.id == id)
|
|
P.linked = src
|
|
linked = P
|
|
break
|
|
|
|
/obj/effect/portal/permanent/teleport(atom/movable/M, force = FALSE)
|
|
set_linked() // update portal links
|
|
. = ..()
|
|
|
|
/obj/effect/portal/permanent/one_way // doesn't have a return portal, can have multiple exits, /obj/effect/landmark/portal_exit to mark them
|
|
name = "one-way portal"
|
|
desc = "You get the feeling that this might not be the safest thing you've ever done."
|
|
|
|
/obj/effect/portal/permanent/one_way/set_linked()
|
|
if(!id)
|
|
return
|
|
var/list/possible_turfs = list()
|
|
for(var/obj/effect/landmark/portal_exit/PE in GLOB.landmarks_list)
|
|
if(PE.id == id)
|
|
var/turf/T = get_turf(PE)
|
|
if(T)
|
|
possible_turfs |= T
|
|
if(possible_turfs.len)
|
|
hard_target = pick(possible_turfs)
|
|
|
|
/obj/effect/portal/permanent/one_way/one_use
|
|
name = "one-use portal"
|
|
desc = "This is probably the worst decision you'll ever make in your life."
|
|
|
|
/obj/effect/portal/permanent/one_way/one_use/teleport(atom/movable/M, force = FALSE)
|
|
. = ..()
|
|
qdel(src)
|