From a4f187ac38de5ea2c22dad0a6c858cd61e207f98 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Tue, 27 Aug 2019 16:04:54 -0400 Subject: [PATCH] Adds Book of Babel and Jacob's Ladder --- code/_globalvars/lists/objects.dm | 1 + code/game/objects/structures/ladders.dm | 210 ++++++++++++------ .../mining/lavaland/loot/tendril_loot.dm | 39 ++++ .../mining/lavaland/necropolis_chests.dm | 4 +- code/modules/mob/language.dm | 4 +- code/modules/shuttle/on_move.dm | 8 + 6 files changed, 195 insertions(+), 71 deletions(-) diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index d9d21c60e1e..ad3798a010e 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -42,6 +42,7 @@ GLOBAL_LIST_INIT(global_radios, list()) //list of all radios, across all z-le GLOBAL_LIST_INIT(meteor_list, list()) //list of all meteors GLOBAL_LIST_INIT(poi_list, list()) //list of points of interest for observe/follow GLOBAL_LIST_INIT(active_jammers, list()) // List of active radio jammers +GLOBAL_LIST_EMPTY(ladders) GLOBAL_LIST_INIT(active_diseases, list()) //List of Active disease in all mobs; purely for quick referencing. diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index 97bd986ceb9..2d4baf14121 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -1,33 +1,58 @@ +// Basic ladder. By default links to the z-level above/below. /obj/structure/ladder name = "ladder" desc = "A sturdy metal ladder." icon = 'icons/obj/structures.dmi' icon_state = "ladder11" - anchored = 1 - var/id = null - var/height = 0 //the 'height' of the ladder. higher numbers are considered physically higher - var/obj/structure/ladder/down = null //the ladder below this one - var/obj/structure/ladder/up = null //the ladder above this one - var/use_verb = "climbs" + anchored = TRUE + var/obj/structure/ladder/down //the ladder below this one + var/obj/structure/ladder/up //the ladder above this one -/obj/structure/ladder/New() - spawn(8) - for(var/obj/structure/ladder/L in world) - if(L.id == id) - if(L.height == (height - 1)) - down = L - if(isnull(L.up)) - L.up = src - continue - if(L.height == (height + 1)) - up = L - if(isnull(L.down)) - L.down = src - continue +/obj/structure/ladder/Initialize(mapload, obj/structure/ladder/up, obj/structure/ladder/down) + . = ..() + if (up) + src.up = up + up.down = src + up.update_icon() + if (down) + src.down = down + down.up = src + down.update_icon() + return INITIALIZE_HINT_LATELOAD - if(up && down) //if both our connections are filled - break - update_icon() +/obj/structure/ladder/Destroy(force) + if((resistance_flags & INDESTRUCTIBLE) && !force) + return QDEL_HINT_LETMELIVE + disconnect() + return ..() + +/obj/structure/ladder/LateInitialize() + // By default, discover ladders above and below us vertically + var/turf/T = get_turf(src) + + if(!down) + for(var/obj/structure/ladder/L in locate(T.x, T.y, T.z - 1)) + down = L + L.up = src // Don't waste effort looping the other way + L.update_icon() + break + if(!up) + for (var/obj/structure/ladder/L in locate(T.x, T.y, T.z + 1)) + up = L + L.down = src // Don't waste effort looping the other way + L.update_icon() + break + + update_icon() + +/obj/structure/ladder/proc/disconnect() + if(up && up.down == src) + up.down = null + up.update_icon() + if(down && down.up == src) + down.up = null + down.update_icon() + up = down = null /obj/structure/ladder/update_icon() if(up && down) @@ -42,62 +67,109 @@ else //wtf make your ladders properly assholes icon_state = "ladder00" -/obj/structure/ladder/attack_hand(mob/user as mob) +/obj/structure/ladder/singularity_pull() + if(!(resistance_flags & INDESTRUCTIBLE)) + visible_message("[src] is torn to pieces by the gravitational pull!") + qdel(src) + +/obj/structure/ladder/proc/travel(going_up, mob/user, is_ghost, obj/structure/ladder/ladder) + if(!is_ghost) + show_fluff_message(going_up, user) + ladder.add_fingerprint(user) + + var/turf/T = get_turf(ladder) + var/atom/movable/AM + if(user.pulling) + AM = user.pulling + AM.forceMove(T) + user.forceMove(T) + if(AM) + user.start_pulling(AM) + +/obj/structure/ladder/proc/use(mob/user, is_ghost = FALSE) + if(!is_ghost && !in_range(src, user)) + return + if(up && down) - switch( alert("Go up or down the ladder?", "Ladder", "Up", "Down", "Cancel") ) + var/result = alert("Go up or down [src]?", "Ladder", "Up", "Down", "Cancel") + if (!is_ghost && !in_range(src, user)) + return // nice try + switch(result) if("Up") - user.visible_message("[user] climbs up \the [src]!", \ - "You climb up \the [src]!") - user.forceMove(get_turf(up)) - up.add_fingerprint(user) + travel(TRUE, user, is_ghost, up) if("Down") - user.visible_message("[user] climbs down \the [src]!", \ - "You climb down \the [src]!") - user.forceMove(get_turf(down)) - down.add_fingerprint(user) + travel(FALSE, user, is_ghost, down) if("Cancel") return - else if(up) - user.visible_message("[user] climbs up \the [src]!", \ - "You climb up \the [src]!") - user.forceMove(get_turf(up)) - up.add_fingerprint(user) - + travel(TRUE, user, is_ghost, up) else if(down) - user.visible_message("[user] climbs down \the [src]!", \ - "You climb down \the [src]!") - user.forceMove(get_turf(down)) - down.add_fingerprint(user) + travel(FALSE, user, is_ghost, down) + else + to_chat(user, "[src] doesn't seem to lead anywhere!") - add_fingerprint(user) + if(!is_ghost) + add_fingerprint(user) -/obj/structure/ladder/attackby(obj/item/W, mob/user as mob, params) - return attack_hand(user) +/obj/structure/ladder/attack_hand(mob/user) + use(user) -/obj/structure/ladder/dive_point/buoy - name = "diving point buoy" - desc = "A buoy marking the location of an underwater dive area." - icon = 'icons/misc/beach.dmi' - icon_state = "buoy" - id = "dive" - height = 2 - use_verb = "dives" - layer = MOB_LAYER + 0.2 //0.1 higher than the water overlay, this also means people can "swim" behind/under it +/obj/structure/ladder/attackby(obj/item/W, mob/user, params) + return use(user) -/obj/structure/ladder/dive_point/anchor - name = "diving point anchor" - desc = "An anchor tethered to the buoy at the surface, to keep the dive area marked." - icon = 'icons/misc/beach.dmi' - icon_state = "anchor" - id = "dive" - height = 1 - use_verb = "ascends" - light_range = 5 +/obj/structure/ladder/attack_robot(mob/living/silicon/robot/R) + if(R.Adjacent(src)) + return use(R) -/obj/structure/ladder/dive_point/New() - ..() - set_light(light_range, light_power) //magical glowing anchor +//ATTACK GHOST IGNORING PARENT RETURN VALUE +/obj/structure/ladder/attack_ghost(mob/dead/observer/user) + use(user, TRUE) -/obj/structure/ladder/dive_point/update_icon() - return \ No newline at end of file +/obj/structure/ladder/proc/show_fluff_message(going_up, mob/user) + if(going_up) + user.visible_message("[user] climbs up [src].","You climb up [src].") + else + user.visible_message("[user] climbs down [src].","You climb down [src].") + + +// Indestructible away mission ladders which link based on a mapped ID and height value rather than X/Y/Z. +/obj/structure/ladder/unbreakable + name = "sturdy ladder" + desc = "An extremely sturdy metal ladder." + resistance_flags = INDESTRUCTIBLE + var/id + var/height = 0 // higher numbers are considered physically higher + +/obj/structure/ladder/unbreakable/Initialize(mapload) + GLOB.ladders += src + return ..() + +/obj/structure/ladder/unbreakable/Destroy() + . = ..() + if(. != QDEL_HINT_LETMELIVE) + GLOB.ladders -= src + +/obj/structure/ladder/unbreakable/LateInitialize() + // Override the parent to find ladders based on being height-linked + if(!id || (up && down)) + update_icon() + return + + for(var/O in GLOB.ladders) + var/obj/structure/ladder/unbreakable/L = O + if(L.id != id) + continue // not one of our pals + if(!down && L.height == height - 1) + down = L + L.up = src + L.update_icon() + if (up) + break // break if both our connections are filled + else if(!up && L.height == height + 1) + up = L + L.down = src + L.update_icon() + if (down) + break // break if both our connections are filled + + update_icon() \ No newline at end of file diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm index c8579fbec65..3727c103a64 100644 --- a/code/modules/mining/lavaland/loot/tendril_loot.dm +++ b/code/modules/mining/lavaland/loot/tendril_loot.dm @@ -77,6 +77,21 @@ add_fingerprint(M) +//Book of Babel + +/obj/item/book_of_babel + name = "Book of Babel" + desc = "An ancient tome written in countless tongues." + icon = 'icons/obj/library.dmi' + icon_state = "book1" + w_class = 2 + +/obj/item/book_of_babel/attack_self(mob/user) + to_chat(user, "You flip through the pages of the book, quickly and conveniently learning every language in existence. Somewhat less conveniently, the aging book crumbles to dust in the process. Whoops.") + user.grant_all_languages() + new /obj/effect/decal/cleanable/ash(get_turf(user)) + qdel(src) + //Potion of Flight: as we do not have the "Angel" species this currently does not work. /obj/item/reagent_containers/glass/bottle/potion @@ -117,6 +132,30 @@ H.emote("scream") ..()*/ +/obj/item/jacobs_ladder + name = "jacob's ladder" + desc = "A celestial ladder that violates the laws of physics." + icon = 'icons/obj/structures.dmi' + icon_state = "ladder00" + +/obj/item/jacobs_ladder/attack_self(mob/user) + var/turf/T = get_turf(src) + var/ladder_x = T.x + var/ladder_y = T.y + to_chat(user, "You unfold the ladder. It extends much farther than you were expecting.") + var/last_ladder = null + for(var/i in 1 to world.maxz) + if(is_admin_level(i) || is_away_level(i)) + continue + var/turf/T2 = locate(ladder_x, ladder_y, i) + last_ladder = new /obj/structure/ladder/unbreakable/jacob(T2, null, last_ladder) + qdel(src) + +// Inherit from unbreakable but don't set ID, to suppress the default Z linkage +/obj/structure/ladder/unbreakable/jacob + name = "jacob's ladder" + desc = "An indestructible celestial ladder that violates the laws of physics." + //Boat /obj/vehicle/lavaboat diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index a2ee237c659..e742a66f48c 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -48,7 +48,7 @@ if(11) new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/berserker(src) if(12) - new /obj/item/sord(src) + new /obj/item/jacobs_ladder(src) if(13) new /obj/item/nullrod/scythe/talking(src) if(14) @@ -78,6 +78,8 @@ if(24) new /obj/item/spellbook/oneuse/summonitem(src) if(25) + new /obj/item/book_of_babel(src) + if(26) new /obj/item/borg/upgrade/modkit/lifesteal(src) new /obj/item/bedsheet/cult(src) diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 57725da8eb2..9391f24035a 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -762,6 +762,8 @@ desc = "Bark bark bark." key = "vu" - +/mob/proc/grant_all_languages() + for(var/la in GLOB.all_languages) + add_language(la) #undef SCRAMBLE_CACHE_LEN diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 42e710d0cf6..0a11a4397ad 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -65,3 +65,11 @@ . = ..() if(!S1.lock_shuttle_doors && id_tag == "s_docking_airlock") INVOKE_ASYNC(src, .proc/unlock) + +/obj/structure/ladder/onShuttleMove() + if(resistance_flags & INDESTRUCTIBLE) + // simply don't be moved + return FALSE + disconnect() + LateInitialize() + return ..() \ No newline at end of file