Merge branch 'master' into upstream-merge-8298

This commit is contained in:
Novacat
2022-03-04 09:57:28 -05:00
committed by GitHub
825 changed files with 158690 additions and 79022 deletions
+6 -1
View File
@@ -4,7 +4,7 @@
/obj/structure/ladder_assembly
name = "ladder assembly"
icon = 'icons/obj/structures.dmi'
icon = 'icons/obj/structures_vr.dmi'
icon_state = "ladder00"
density = FALSE
opacity = 0
@@ -21,6 +21,9 @@
created_name = t
return
else if(istype(get_area(src), /area/shuttle))
to_chat(user, "<span class='warning'>\The [src] cannot be constructed on a shuttle.</span>")
return
if(W.is_wrench())
switch(state)
if(CONSTRUCTION_UNANCHORED)
@@ -86,6 +89,8 @@
if(!T) continue
var/obj/structure/ladder_assembly/LA = locate(/obj/structure/ladder_assembly, T)
if(!LA) continue
if(direction == DOWN && (src.z in using_map.below_blocked_levels)) continue
if(direction == UP && (LA.z in using_map.below_blocked_levels)) continue
if(LA.state != CONSTRUCTION_WELDED)
to_chat(user, "<span class='warning'>\The [LA] [direction == UP ? "above" : "below"] must be secured and welded.</span>")
return
+7
View File
@@ -37,6 +37,13 @@
target_up = null
return ..()
/obj/structure/ladder/attack_generic(mob/user)
//Simple Animal
if(isanimal(user))
attack_hand(user)
else
return ..()
/obj/structure/ladder/attackby(obj/item/C as obj, mob/user as mob)
attack_hand(user)
return
-122
View File
@@ -1,122 +0,0 @@
/obj/structure/portal_subtle
name = "portal"
desc = "Looks unstable. Best to test it with the clown."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "portal"
density = TRUE
unacidable = TRUE//Can't destroy energy portals.
var/failchance = 0
anchored = TRUE
var/obj/structure/portal_subtle/target
/obj/structure/portal_subtle/Destroy()
if(target)
target.target = null
target = null
return ..()
/obj/structure/portal_subtle/Bumped(mob/M as mob|obj)
if(istype(M,/mob) && !(istype(M,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(M)
return
return
/obj/structure/portal_subtle/Crossed(AM as mob|obj)
if(istype(AM,/mob) && !(istype(AM,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(AM)
return
return
/obj/structure/portal_subtle/attack_hand(mob/user as mob)
if(istype(user) && !(istype(user,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(user)
return
return
/obj/structure/portal_subtle/proc/teleport(atom/movable/M as mob|obj)
if(istype(M, /obj/effect)) //sparks don't teleport
return
if (M.anchored&&istype(M, /obj/mecha))
return
if (icon_state == "portal1")
return
if (!( target ))
qdel(src)
return
if (istype(target, /obj/structure/portal_subtle))
qdel(src)
return
if (istype(M, /atom/movable))
if(prob(failchance)) //oh dear a problem, put em in deep space
src.icon_state = "portal1"
do_noeffect_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0)
else
do_noeffect_teleport(M, target, 0) ///You will appear on the beacon
/obj/structure/portal_gateway
name = "portal"
desc = "Looks unstable. Best to test it with the clown."
icon = 'icons/obj/stationobjs_vr.dmi'
icon_state = "portalgateway"
density = TRUE
unacidable = TRUE//Can't destroy energy portals.
anchored = TRUE
/obj/structure/portal_gateway/Bumped(mob/M as mob|obj)
if(istype(M,/mob) && !(istype(M,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
var/obj/effect/landmark/dest = pick(eventdestinations)
if(dest)
M << 'sound/effects/phasein.ogg'
playsound(src, 'sound/effects/phasein.ogg', 100, 1)
M.forceMove(dest.loc)
if(istype(M, /mob/living) && dest.abductor)
var/mob/living/L = M
//Situations to get the mob out of
if(L.buckled)
L.buckled.unbuckle_mob()
if(istype(L.loc,/obj/mecha))
var/obj/mecha/ME = L.loc
ME.go_out()
else if(istype(L.loc,/obj/machinery/sleeper))
var/obj/machinery/sleeper/SL = L.loc
SL.go_out()
else if(istype(L.loc,/obj/machinery/recharge_station))
var/obj/machinery/recharge_station/RS = L.loc
RS.go_out()
if(!issilicon(L)) //Don't drop borg modules...
var/list/mob_contents = list() //Things which are actually drained as a result of the above not being null.
mob_contents |= L // The recursive check below does not add the object being checked to its list.
mob_contents |= recursive_content_check(L, mob_contents, recursion_limit = 3, client_check = 0, sight_check = 0, include_mobs = 1, include_objects = 1, ignore_show_messages = 1)
for(var/obj/item/weapon/holder/I in mob_contents)
var/obj/item/weapon/holder/H = I
var/mob/living/MI = H.held_mob
MI.forceMove(get_turf(H))
if(!issilicon(MI)) //Don't drop borg modules...
for(var/obj/item/II in MI)
if(istype(II,/obj/item/weapon/implant) || istype(II,/obj/item/device/nif))
continue
MI.drop_from_inventory(II, dest.loc)
var/obj/effect/landmark/finaldest = pick(awayabductors)
MI.forceMove(finaldest.loc)
sleep(1)
MI.Paralyse(10)
MI << 'sound/effects/bamf.ogg'
to_chat(MI,"<span class='warning'>You're starting to come to. You feel like you've been out for a few minutes, at least...</span>")
for(var/obj/item/I in L)
if(istype(I,/obj/item/weapon/implant) || istype(I,/obj/item/device/nif))
continue
L.drop_from_inventory(I, dest.loc)
var/obj/effect/landmark/finaldest = pick(awayabductors)
L.forceMove(finaldest.loc)
sleep(1)
L.Paralyse(10)
L << 'sound/effects/bamf.ogg'
to_chat(L,"<span class='warning'>You're starting to come to. You feel like you've been out for a few minutes, at least...</span>")
return
+8 -4
View File
@@ -59,7 +59,7 @@
if(lattice)
var/pull_up_time = max(5 SECONDS + (src.movement_delay() * 10), 1)
to_chat(src, "<span class='notice'>You grab \the [lattice] and start pulling yourself upward...</span>")
destination.audible_message("<span class='notice'>You hear something climbing up \the [lattice].</span>", runemessage = "clank clang")
src.audible_message("<span class='notice'>[src] begins climbing up \the [lattice].</span>", runemessage = "clank clang")
if(do_after(src, pull_up_time))
to_chat(src, "<span class='notice'>You pull yourself up.</span>")
else
@@ -74,14 +74,14 @@
if(!destination?.Enter(src, old_dest))
to_chat(src, "<span class='notice'>There's something in the way up above in that direction, try another.</span>")
return 0
destination.audible_message("<span class='notice'>You hear something climbing up \the [catwalk].</span>", runemessage = "clank clang")
src.audible_message("<span class='notice'>[src] begins climbing up \the [lattice].</span>", runemessage = "clank clang")
if(do_after(src, pull_up_time))
to_chat(src, "<span class='notice'>You pull yourself up.</span>")
else
to_chat(src, "<span class='warning'>You gave up on pulling yourself up.</span>")
return 0
else if(ismob(src)) //VOREStation Edit Start. Are they a mob, and are they currently flying??
else if(isliving(src)) //VOREStation Edit Start. Are they a mob, and are they currently flying??
var/mob/living/H = src
if(H.flying)
if(H.incapacitated(INCAPACITATION_ALL))
@@ -90,7 +90,6 @@
return 0
var/fly_time = max(7 SECONDS + (H.movement_delay() * 10), 1) //So it's not too useful for combat. Could make this variable somehow, but that's down the road.
to_chat(src, "<span class='notice'>You begin to fly upwards...</span>")
destination.audible_message("<span class='notice'>You hear the flapping of wings.</span>", runemessage = "flap flap")
H.audible_message("<span class='notice'>[H] begins to flap \his wings, preparing to move upwards!</span>", runemessage = "flap flap")
if(do_after(H, fly_time) && H.flying)
to_chat(src, "<span class='notice'>You fly upwards.</span>")
@@ -111,6 +110,11 @@
return 0
if(!Move(destination))
return 0
if(isliving(src))
if(direction == UP)
src.audible_message("<span class='notice'>[src] moves up.</span>")
else if(direction == DOWN)
src.audible_message("<span class='notice'>[src] moves down.</span>")
return 1
/mob/proc/can_overcome_gravity()
+227
View File
@@ -0,0 +1,227 @@
/obj/structure/portal_event
name = "portal"
desc = "It leads to someplace else!"
icon = 'icons/obj/stationobjs_vr.dmi'
icon_state = "type-d-portal"
density = TRUE
unacidable = TRUE//Can't destroy energy portals.
var/failchance = 0
anchored = TRUE
var/obj/structure/portal_event/target
/obj/structure/portal_event/Destroy()
if(target)
target.target = null
target = null
return ..()
/obj/structure/portal_event/Bumped(mob/M as mob|obj)
if(istype(M,/mob) && !(istype(M,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(M)
return
return
/obj/structure/portal_event/Crossed(AM as mob|obj)
if(istype(AM,/mob) && !(istype(AM,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(AM)
return
return
/obj/structure/portal_event/attack_hand(mob/user as mob)
if(!istype(user))
return
if(!target)
if(isliving(user))
to_chat(user, "<span class='notice'>Your hand scatters \the [src]...</span>")
qdel(src) //Delete portals which aren't set that people mess with.
else return //do not send ghosts, zshadows, ai eyes, etc
else if(isliving(user) || istype(user, /mob/observer/dead) && user?.client?.holder) //unless they're staff
spawn(0)
src.teleport(user)
/obj/structure/portal_event/attack_ghost(var/mob/observer/dead/user)
if(!target && user?.client?.holder)
to_chat(user, "<span class='notice'>Selecting 'Portal Here' will create and link a portal at your location, while 'Target Here' will create an object that is only visible to ghosts which will act as the target, again at your location. Each option will give you the ability to change portal types, but for all options except 'Select Type' you only get one shot at it, so be sure to experiment with 'Select Type' first if you're not familiar with them.</span>")
var/response = tgui_alert(user, "You appear to be staff. This portal has no exit point. If you want to make one, move to where you want it to go, and click the appropriate option, see chat for more info, otherwise click 'Cancel'", "Unbound Portal", list("Cancel","Portal Here","Target Here", "Select Type"))
if(response == "Portal Here")
target = new type(get_turf(user), src)
target.target = src
target.icon_state = icon_state
var/letsportal = tgui_alert(user, "Would you like to select a different portal type for these portals?", "Change portal", list("No","Yes"))
if(letsportal == "Yes")
var/portal_icon_selection = select_portal_subtype(user)
icon_state = portal_icon_selection
target.icon_state = portal_icon_selection
if(response == "Target Here")
var/obj/structure/portal_target/newtarg = new(get_turf(user))
target = newtarg
newtarg.target = src
var/letsportal = tgui_alert(user, "Would you like to select a different portal type?", "Change portal", list("No","Yes"))
if(letsportal == "Yes")
user.forceMove(src)
icon_state = select_portal_subtype(user)
if(response == "Select Type")
icon_state = select_portal_subtype(user)
return
message_admins("The [src]([x],[y],[z]) was given [target]([target.x],[target.y],[target.z]) as a target, and should be ready to use.")
else if(user?.client?.holder)
src.teleport(user)
else return
/obj/structure/portal_event/proc/select_portal_subtype(user)
var/portal_type = tgui_alert(user, "What kind of portal would you like it to be?", "Type Selection", list("Tech (Default)","Star","Weird Green","Pulsing"))
var/portal_icon_selection = "type-d-portal"
if(portal_type == "Tech (Default)")
portal_icon_selection = "type-d-portal"
if(portal_type == "Star")
var/portal_subtype = tgui_alert(user, "Which subtype would you prefer?", "Subtype Selection", list("Blue","Blue Pulse","Blue Unstable","Red","Red Unstable"))
if(portal_subtype == "Blue")
portal_icon_selection = "type-a-blue-portal"
if(portal_subtype == "Blue Pulse")
portal_icon_selection = "type-a-blue-portal-b"
if(portal_subtype == "Blue Unstable")
portal_icon_selection = "type-a-blue-portal-c"
if(portal_subtype == "Red")
portal_icon_selection = "type-a-red-portal"
if(portal_subtype == "Red Unstable")
portal_icon_selection = "type-a-red-portal-b"
if(portal_type == "Weird Green")
portal_icon_selection = "type-b-portal"
if(portal_type == "Pulsing")
var/portal_subtype = tgui_alert(user, "Which subtype would you prefer?", "Subtype Selection", list("Blue","Red","Blue/Red Mix", "Yellow"))
if(portal_subtype == "Blue")
portal_icon_selection = "type-c-blue-portal"
if(portal_subtype == "Red")
portal_icon_selection = "type-c-red-portal"
if(portal_subtype == "Blue/Red Mix")
portal_icon_selection = "type-c-mix-portal"
if(portal_subtype == "Yellow")
portal_icon_selection = "type-c-yellow-portal"
return portal_icon_selection
/obj/structure/portal_event/proc/teleport(atom/movable/M as mob|obj)
if(istype(M, /obj/effect)) //sparks don't teleport
return
if (M.anchored&&istype(M, /obj/mecha))
return
if (!target)
to_chat(M, "<span class='notice'>\The [src] scatters as you pass through it...</span>")
qdel(src)
return
if (!istype(M, /atom/movable))
return
var/turf/place
if(isturf(target))
place = src
else
place = target.loc
var/portalfind = FALSE
for(var/obj/structure/S in place.contents)
if(istype(S, /obj/structure/portal_event))
portalfind = TRUE
else if (S.density)
portalfind = TRUE
var/temptarg
if(portalfind)
var/possible_turfs = place.AdjacentTurfs()
if(isemptylist(possible_turfs))
to_chat(M, "<span class='notice'>Something blocks your way.</span>")
return
temptarg = pick(possible_turfs)
do_noeffect_teleport(M, temptarg, 0)
else if (istype(M, /atom/movable))
do_noeffect_teleport(M, target, 0)
/obj/structure/portal_event/Destroy()
if(target)
if(istype(target, /obj/structure/portal_event))
var/obj/structure/portal_event/P = target
P.target = null
if(istype(target, /obj/structure/portal_target))
var/obj/structure/portal_target/P = target
P.target = null
qdel_null(target)
. = ..()
/obj/structure/portal_target
name = "portal destination"
desc = "you shouldn't see this unless you're a ghost"
icon = 'icons/obj/stationobjs_vr.dmi'
icon_state = "type-b-portal"
density = 0
alpha = 100
invisibility = INVISIBILITY_OBSERVER
var/target
/obj/structure/portal_target/Destroy()
if(target)
var/obj/structure/portal_event/T = target
T.target = null
target = null
. = ..()
/obj/structure/portal_gateway
name = "portal"
desc = "It leads to someplace else!"
icon = 'icons/obj/stationobjs_vr.dmi'
icon_state = "portalgateway"
density = TRUE
unacidable = TRUE//Can't destroy energy portals.
anchored = TRUE
/obj/structure/portal_gateway/Bumped(mob/M as mob|obj)
if(istype(M,/mob) && !(istype(M,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
var/obj/effect/landmark/dest = pick(eventdestinations)
if(dest)
M << 'sound/effects/phasein.ogg'
playsound(src, 'sound/effects/phasein.ogg', 100, 1)
M.forceMove(dest.loc)
if(istype(M, /mob/living) && dest.abductor)
var/mob/living/L = M
//Situations to get the mob out of
if(L.buckled)
L.buckled.unbuckle_mob()
if(istype(L.loc,/obj/mecha))
var/obj/mecha/ME = L.loc
ME.go_out()
else if(istype(L.loc,/obj/machinery/sleeper))
var/obj/machinery/sleeper/SL = L.loc
SL.go_out()
else if(istype(L.loc,/obj/machinery/recharge_station))
var/obj/machinery/recharge_station/RS = L.loc
RS.go_out()
if(!issilicon(L)) //Don't drop borg modules...
var/list/mob_contents = list() //Things which are actually drained as a result of the above not being null.
mob_contents |= L // The recursive check below does not add the object being checked to its list.
mob_contents |= recursive_content_check(L, mob_contents, recursion_limit = 3, client_check = 0, sight_check = 0, include_mobs = 1, include_objects = 1, ignore_show_messages = 1)
for(var/obj/item/weapon/holder/I in mob_contents)
var/obj/item/weapon/holder/H = I
var/mob/living/MI = H.held_mob
MI.forceMove(get_turf(H))
if(!issilicon(MI)) //Don't drop borg modules...
for(var/obj/item/II in MI)
if(istype(II,/obj/item/weapon/implant) || istype(II,/obj/item/device/nif))
continue
MI.drop_from_inventory(II, dest.loc)
var/obj/effect/landmark/finaldest = pick(awayabductors)
MI.forceMove(finaldest.loc)
sleep(1)
MI.Paralyse(10)
MI << 'sound/effects/bamf.ogg'
to_chat(MI,"<span class='warning'>You're starting to come to. You feel like you've been out for a few minutes, at least...</span>")
for(var/obj/item/I in L)
if(istype(I,/obj/item/weapon/implant) || istype(I,/obj/item/device/nif))
continue
L.drop_from_inventory(I, dest.loc)
var/obj/effect/landmark/finaldest = pick(awayabductors)
L.forceMove(finaldest.loc)
sleep(1)
L.Paralyse(10)
L << 'sound/effects/bamf.ogg'
to_chat(L,"<span class='warning'>You're starting to come to. You feel like you've been out for a few minutes, at least...</span>")
return
+17 -8
View File
@@ -152,10 +152,12 @@
// Or if we fell down the openspace
if((top in oldloc) || oldloc == GetAbove(src))
return
//VOREStation Addition Start
if(istype(AM, /obj/effect/plant))
return
//VOREStation Addition End
if(isobserver(AM)) // Ghosts have their own methods for going up and down
return
if(AM.pulledby) // Animating the movement of pulled things is handled when the puller goes up the stairs
return
@@ -203,7 +205,10 @@
/obj/structure/stairs/bottom/use_stairs_instant(var/atom/movable/AM)
if(isobserver(AM)) // Ghosts have their own methods for going up and down
return
//VOREStation Addition Start
if(istype(AM, /obj/effect/plant))
return
//VOREStation Addition End
if(isliving(AM))
var/mob/living/L = AM
@@ -396,7 +401,7 @@
/obj/structure/stairs/top/Uncrossed(var/atom/movable/AM)
// Going down stairs from the topstair piece
if(AM.dir == turn(dir, 180) && check_integrity())
if(AM.dir == turn(dir, 180) && isturf(AM.loc) && check_integrity())
use_stairs_instant(AM)
return
@@ -405,10 +410,12 @@
// Or if we climb up the middle
if((bottom in oldloc) || oldloc == GetBelow(src))
return
//VOREStation Addition Start
if(istype(AM, /obj/effect/plant))
return
//VOREStation Addition End
if(isobserver(AM)) // Ghosts have their own methods for going up and down
return
if(AM.pulledby) // Animating the movement of pulled things is handled when the puller goes up the stairs
return
@@ -454,10 +461,12 @@
/obj/structure/stairs/top/use_stairs_instant(var/atom/movable/AM)
if(isobserver(AM)) // Ghosts have their own methods for going up and down
return
//VOREStation Addition Start
if(istype(AM, /obj/effect/plant))
return
//VOREStation Addition End
if(isliving(AM))
var/mob/living/L = AM
if(L.grabbed_by.len) // Same as pulledby, whoever's holding you will keep you from going down stairs.
return