mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-22 12:29:46 +01:00
Teleporter Safety (#9879)
* Teleporter Safety * better keyword * initialize can't handle skips
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/obj/effect/portal
|
||||
name = "portal"
|
||||
desc = "Looks unstable. Best to test it carefully."
|
||||
desc = "A bluespace tear in space, reaching directly to another point within this region. Looks unstable. Best to test it carefully."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "portal"
|
||||
density = TRUE
|
||||
@@ -8,61 +8,69 @@
|
||||
var/does_teleport = TRUE // Some portals might just be visual
|
||||
var/has_lifespan = TRUE // Whether we want to directly control the lifespan or not
|
||||
var/failchance = 5
|
||||
var/has_failed = FALSE
|
||||
var/obj/target
|
||||
var/creator
|
||||
var/precision = TRUE
|
||||
var/precision = 1
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/portal/CollidedWith(mob/M as mob|obj)
|
||||
set waitfor = FALSE
|
||||
|
||||
if(does_teleport)
|
||||
src.teleport(M)
|
||||
|
||||
/obj/effect/portal/Crossed(AM as mob|obj)
|
||||
set waitfor = FALSE
|
||||
|
||||
if(does_teleport)
|
||||
src.teleport(AM)
|
||||
|
||||
/obj/effect/portal/attack_hand(mob/user as mob)
|
||||
set waitfor = FALSE
|
||||
|
||||
if(does_teleport)
|
||||
src.teleport(user)
|
||||
|
||||
/obj/effect/portal/New(loc, turf/target, creator=null, lifespan=300, precise = 1)
|
||||
..()
|
||||
if(target)
|
||||
src.target = target
|
||||
if(creator)
|
||||
src.creator = creator
|
||||
/obj/effect/portal/Initialize(mapload, turf/set_target, set_creator, lifespan = 300, precise = 1)
|
||||
. = ..()
|
||||
|
||||
if(set_target)
|
||||
target = set_target
|
||||
if(set_creator)
|
||||
creator = set_creator
|
||||
if(has_lifespan && lifespan > 0)
|
||||
QDEL_IN(src, lifespan)
|
||||
if(prob(failchance))
|
||||
has_failed = TRUE
|
||||
|
||||
precision = precise
|
||||
|
||||
/obj/effect/portal/proc/teleport(atom/movable/M as mob|obj)
|
||||
/obj/effect/portal/CollidedWith(mob/M)
|
||||
set waitfor = FALSE
|
||||
|
||||
if(does_teleport)
|
||||
teleport(M)
|
||||
|
||||
/obj/effect/portal/Crossed(AM)
|
||||
set waitfor = FALSE
|
||||
|
||||
if(does_teleport)
|
||||
teleport(AM)
|
||||
|
||||
/obj/effect/portal/attack_hand(mob/user)
|
||||
set waitfor = FALSE
|
||||
|
||||
if(does_teleport)
|
||||
teleport(user)
|
||||
|
||||
/obj/effect/portal/proc/teleport(atom/movable/M)
|
||||
if(!does_teleport) // just to be safe
|
||||
return
|
||||
if(istype(M, /obj/effect)) //sparks don't teleport
|
||||
return
|
||||
if (icon_state == "portal1")
|
||||
return
|
||||
if (!( target ))
|
||||
if(!target)
|
||||
qdel(src)
|
||||
return
|
||||
if (istype(M, /atom/movable))
|
||||
if(prob(failchance)) //oh dear a problem, put em in deep space
|
||||
src.icon_state = "portal1"
|
||||
if(istype(M, /atom/movable))
|
||||
if(has_failed) //oh dear a problem, put em in deep space
|
||||
icon_state = "portal1" // only tell people the portal failed after a teleport has been done
|
||||
desc = "A bluespace tear in space, reaching directly to another point within this region. Definitely unstable."
|
||||
do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0)
|
||||
else
|
||||
do_teleport(M, target, precision)
|
||||
|
||||
/obj/effect/portal/Destroy()
|
||||
if(istype(creator, /obj/item/hand_tele))
|
||||
var/obj/item/hand_tele/HT = creator
|
||||
HT.remove_portal(src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/portal/spawner
|
||||
name = "portal"
|
||||
desc = "Looks like a one-way portal, don't come too close."
|
||||
desc = "A bluespace tear in space, reaching directly to another point within this region. This one looks like a one-way portal to here, don't come too close."
|
||||
desc_info = "This portal is a spawner portal. You cannot enter it to teleport, but it will periodically spawn things."
|
||||
does_teleport = FALSE
|
||||
has_lifespan = FALSE
|
||||
|
||||
@@ -164,4 +164,4 @@
|
||||
|
||||
/obj/item/syndie/teleporter/pickup()
|
||||
..()
|
||||
addtimer(CALLBACK(src, .proc/check_maptext), 1)
|
||||
addtimer(CALLBACK(src, .proc/check_maptext), 1) // invoke async does not work here
|
||||
|
||||
@@ -125,7 +125,7 @@ Frequency:
|
||||
*/
|
||||
/obj/item/hand_tele
|
||||
name = "hand tele"
|
||||
desc = "A portable item using blue-space technology."
|
||||
desc = "A hand-held bluespace teleporter that can rip open portals to a random nearby location, or lock onto a teleporter with a selected teleportation beacon."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "hand_tele"
|
||||
item_state = "electronic"
|
||||
@@ -135,62 +135,85 @@ Frequency:
|
||||
throw_range = 5
|
||||
origin_tech = list(TECH_MAGNET = 1, TECH_BLUESPACE = 3)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 10000)
|
||||
var/list/active_teleporters = list()
|
||||
var/held_maptext = "<span style=\"font-family: 'Small Fonts'; -dm-text-outline: 1 black; font-size: 7px;\">Ready</span>"
|
||||
|
||||
/obj/item/hand_tele/attack_self(mob/user as mob)
|
||||
/obj/item/hand_tele/Initialize()
|
||||
. = ..()
|
||||
if(ismob(loc) || ismob(loc.loc))
|
||||
maptext = held_maptext
|
||||
|
||||
/obj/item/hand_tele/attack_self(mob/user)
|
||||
var/turf/current_location = get_turf(user)//What turf is the user on?
|
||||
if(!current_location||current_location.z==2||current_location.z>=7)//If turf was not found or they're on z level 2 or >7 which does not currently exist.
|
||||
to_chat(user, "<span class='notice'>\The [src] is malfunctioning.</span>")
|
||||
if(!current_location || isNotStationLevel(current_location.z))
|
||||
to_chat(user, SPAN_WARNING("\The [src] can't get a bearing on anything right now."))
|
||||
return
|
||||
var/list/L = list( )
|
||||
|
||||
var/list/teleport_options = list()
|
||||
for(var/obj/machinery/teleport/hub/R in SSmachinery.all_machines)
|
||||
var/obj/machinery/computer/teleporter/com = locate(/obj/machinery/computer/teleporter, locate(R.x - 2, R.y, R.z))
|
||||
if (istype(com, /obj/machinery/computer/teleporter) && com.locked && !com.one_time_use)
|
||||
var/obj/machinery/computer/teleporter/com = R.com
|
||||
if(com?.locked && !com.one_time_use)
|
||||
if(R.icon_state == "tele1")
|
||||
L["[com.id] (Active)"] = com.locked
|
||||
teleport_options["[com.id] (Active)"] = com.locked
|
||||
else
|
||||
L["[com.id] (Inactive)"] = com.locked
|
||||
var/list/turfs = list( )
|
||||
teleport_options["[com.id] (Inactive)"] = com.locked
|
||||
|
||||
var/list/potential_turfs = list()
|
||||
for(var/turf/T in orange(10))
|
||||
if(T.x>world.maxx-8 || T.x<8)
|
||||
if(T.x > world.maxx-8 || T.x < 8)
|
||||
continue //putting them at the edge is dumb
|
||||
|
||||
if(T.y>world.maxy-8 || T.y<8)
|
||||
if(T.y > world.maxy-8 || T.y < 8)
|
||||
continue
|
||||
|
||||
if(T.density)
|
||||
if(T.density || turf_contains_dense_objects(T))
|
||||
continue
|
||||
potential_turfs += T
|
||||
|
||||
var/breakcheck = 0
|
||||
for(var/atom/movable/A in T)
|
||||
if(A.density && A.opacity && A.anchored)
|
||||
breakcheck = 1
|
||||
break
|
||||
if(length(potential_turfs))
|
||||
teleport_options["None (Dangerous)"] = pick(potential_turfs)
|
||||
|
||||
if(breakcheck)
|
||||
continue
|
||||
|
||||
turfs += T
|
||||
|
||||
if(turfs.len)
|
||||
L["None (Dangerous)"] = pick(turfs)
|
||||
var/t1 = input(user, "Please select a teleporter to lock in on.", "Hand Teleporter") in L
|
||||
if ((user.get_active_hand() != src || user.stat || user.restrained()))
|
||||
var/teleport_choice = input(user, "Please select a teleporter to lock in on.", "Hand Teleporter") as null|anything in teleport_options
|
||||
if(!teleport_choice || user.get_active_hand() != src || use_check_and_message(user))
|
||||
return
|
||||
var/count = 0 //num of portals from this teleport in world
|
||||
for(var/obj/effect/portal/PO in world)
|
||||
if(PO.creator == src) count++
|
||||
if(count >= 3)
|
||||
user.show_message("<span class='notice'>\The [src] is recharging!</span>")
|
||||
|
||||
if(length(active_teleporters) >= 3)
|
||||
user.show_message(SPAN_WARNING("\The [src] is recharging!"))
|
||||
return
|
||||
var/T = L[t1]
|
||||
for(var/mob/O in hearers(user, null))
|
||||
O.show_message("<span class='notice'>Locked In.</span>", 2)
|
||||
var/obj/effect/portal/P = new /obj/effect/portal( get_turf(src) )
|
||||
P.target = T
|
||||
P.creator = src
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
var/T = teleport_options[teleport_choice]
|
||||
audible_message(SPAN_NOTICE("Locked in."), hearing_distance = 3)
|
||||
var/obj/effect/portal/P = new /obj/effect/portal(get_turf(src), T, src)
|
||||
active_teleporters += P
|
||||
if(length(active_teleporters) >= 3)
|
||||
check_maptext("<span style=\"font-family: 'Small Fonts'; -dm-text-outline: 1 black; font-size: 6px;\">Charge</span>")
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/hand_tele/proc/remove_portal(var/obj/effect/portal/P)
|
||||
active_teleporters -= P
|
||||
if(length(active_teleporters) < 3)
|
||||
check_maptext("<span style=\"font-family: 'Small Fonts'; -dm-text-outline: 1 black; font-size: 7px;\">Ready</span>")
|
||||
|
||||
/obj/item/hand_tele/proc/check_maptext(var/new_maptext)
|
||||
if(new_maptext)
|
||||
held_maptext = new_maptext
|
||||
if(ismob(loc) || ismob(loc.loc))
|
||||
maptext = held_maptext
|
||||
else
|
||||
maptext = ""
|
||||
|
||||
/obj/item/hand_tele/throw_at()
|
||||
..()
|
||||
check_maptext()
|
||||
|
||||
/obj/item/hand_tele/dropped()
|
||||
..()
|
||||
check_maptext()
|
||||
|
||||
/obj/item/hand_tele/on_give()
|
||||
check_maptext()
|
||||
|
||||
/obj/item/hand_tele/pickup()
|
||||
..()
|
||||
addtimer(CALLBACK(src, .proc/check_maptext), 1) // invoke async does not work here
|
||||
|
||||
/obj/item/closet_teleporter
|
||||
name = "closet teleporter"
|
||||
|
||||
Reference in New Issue
Block a user