[PORT] Secret Gateways: Config loaded Away Missions + Anti-observing Z level traits (#13967)

* Secret Gateways: Config loaded Away Missions + Anti-observing Z level traits (#61719)

* Removed effect/dummy/phased_mob copypasta. Fixed squeak component triggering from abstract effects & co. (#54783)

* bonkies

* fix merge

* secret gateway update (#62003)

admins are now notified about a secret gateway load failing, also logs this
secret z levels are protected from incorporeal movement
fixes unpowered ruin areas being powered
adds a bunch of new areas for secret gateways, since var edited areas probably arent a good idea its good to have a few presets
adds cordon turfs and areas, ingame they just look like the z level border, they are completely indestructible, you cant pass them, and if you somehow do, the cordon area kills you (idea from goon but the code and sprites are mine)
adds a z level injector mapping trait, injects a z level trait into the z level its placed on, if you want to add something like ash storms or whatever to your map
adds an anti xray z level trait, you can optionally add this with the z level injector to protect your map against any xray or whatever

* yesss

* Update walks.dm

* last fixed

Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
TheGamerdk
2022-05-16 20:53:46 +02:00
committed by GitHub
parent e166301c3a
commit 1d21a4cbef
41 changed files with 403 additions and 161 deletions

View File

@@ -45,6 +45,15 @@ require only minor tweaks.
#define ZTRAIT_ASHSTORM "Weather_Ashstorm"
#define ZTRAIT_ACIDRAIN "Weather_Acidrain"
/// boolean - does this z prevent ghosts from observing it
#define ZTRAIT_SECRET "Secret"
/// boolean - does this z prevent phasing
#define ZTRAIT_NOPHASE "No Phase"
/// boolean - does this z prevent xray/meson/thermal vision
#define ZTRAIT_NOXRAY "No X-Ray"
// number - bombcap is multiplied by this before being applied to bombs
#define ZTRAIT_BOMBCAP_MULTIPLIER "Bombcap Multiplier"
@@ -68,9 +77,13 @@ require only minor tweaks.
#define ZTRAIT_BASETURF "Baseturf"
// default trait definitions, used by SSmapping
#define ZTRAITS_CENTCOM list(ZTRAIT_CENTCOM = TRUE)
///Z level traits for CentCom
#define ZTRAITS_CENTCOM list(ZTRAIT_CENTCOM = TRUE, ZTRAIT_NOPHASE = TRUE)
///Z level traits for Space Station 13
#define ZTRAITS_STATION list(ZTRAIT_LINKAGE = CROSSLINKED, ZTRAIT_STATION = TRUE)
///Z level traits for Deep Space
#define ZTRAITS_SPACE list(ZTRAIT_LINKAGE = CROSSLINKED, ZTRAIT_SPACE_RUINS = TRUE)
///Z level traits for Lavaland
#define ZTRAITS_LAVALAND list(\
ZTRAIT_MINING = TRUE, \
ZTRAIT_ASHSTORM = TRUE, \
@@ -92,6 +105,11 @@ require only minor tweaks.
ZTRAIT_BASETURF = /turf/open/lava/plasma/ice_moon)
#define ZTRAITS_REEBE list(ZTRAIT_REEBE = TRUE, ZTRAIT_BOMBCAP_MULTIPLIER = 0.60)
///Z level traits for Away Missions
#define ZTRAITS_AWAY list(ZTRAIT_AWAY = TRUE)
///Z level traits for Secret Away Missions
#define ZTRAITS_AWAY_SECRET list(ZTRAIT_AWAY = TRUE, ZTRAIT_SECRET = TRUE, ZTRAIT_NOPHASE = TRUE)
#define DL_NAME "name"
#define DL_TRAITS "traits"
#define DECLARE_LEVEL(NAME, TRAITS) list(DL_NAME = NAME, DL_TRAITS = TRAITS)

View File

@@ -12,3 +12,5 @@
#define is_reserved_level(z) SSmapping.level_trait(z, ZTRAIT_RESERVED)
#define is_away_level(z) SSmapping.level_trait(z, ZTRAIT_AWAY)
#define is_secret_level(z) SSmapping.level_trait(z, ZTRAIT_SECRET)

View File

@@ -482,6 +482,16 @@ Turf and target are separate in case you want to teleport some distance from a t
processing += A.contents
. += A
/atom/proc/get_all_contents_type(type)
var/list/processing_list = list(src)
. = list()
while(length(processing_list))
var/atom/checked_atom = processing_list[1]
processing_list.Cut(1, 2)
processing_list += checked_atom.contents
if(istype(checked_atom, type))
. += checked_atom
//Step-towards method of determining whether one atom can see another. Similar to viewers()
/proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
var/turf/current = get_turf(source)

View File

@@ -294,6 +294,11 @@
integer = FALSE
min_val = 0
/datum/config_entry/number/config_gateway_chance
integer = FALSE
min_val = 0
max_val = 100
/datum/config_entry/flag/ghost_interaction
/datum/config_entry/flag/near_death_experience //If carbons can hear ghosts when unconscious and very close to death

View File

@@ -78,7 +78,7 @@ SUBSYSTEM_DEF(mapping)
// Pick a random away mission.
if(CONFIG_GET(flag/roundstart_away))
createRandomZlevel()
createRandomZlevel(prob(CONFIG_GET(number/config_gateway_chance)))
// Load the virtual reality hub
if(CONFIG_GET(flag/virtual_reality))
@@ -465,8 +465,10 @@ GLOBAL_LIST_EMPTY(the_station_areas)
var/list/possible_options = GLOB.potentialRandomZlevels + "Custom"
var/away_name
var/datum/space_level/away_level
var/answer = input("What kind ? ","Away") as null|anything in possible_options
var/secret = FALSE
if(alert(usr, "Do you want your mission secret? (This will prevent ghosts from looking at your map in any way other than through a living player's eyes.)", "Are you $$$ekret?", list("Yes", "No")) == "Yes")
secret = TRUE
var/answer = input("What kind?","Away") as null|anything in possible_options
switch(answer)
if("Custom")
var/mapfile = input("Pick file:", "File") as null|file
@@ -475,13 +477,13 @@ GLOBAL_LIST_EMPTY(the_station_areas)
away_name = "[mapfile] custom"
to_chat(usr,span_notice("Loading [away_name]..."))
var/datum/map_template/template = new(mapfile, "Away Mission")
away_level = template.load_new_z()
away_level = template.load_new_z(secret)
else
if(answer in GLOB.potentialRandomZlevels)
away_name = answer
to_chat(usr,span_notice("Loading [away_name]..."))
var/datum/map_template/template = new(away_name, "Away Mission")
away_level = template.load_new_z()
away_level = template.load_new_z(secret)
else
return

View File

@@ -47,6 +47,15 @@ SUBSYSTEM_DEF(weather)
eligible_zlevels["[z]"][W] = probability
return ..()
/datum/controller/subsystem/weather/proc/update_z_level(datum/space_level/level)
var/z = level.z_value
for(var/datum/weather/weather as anything in subtypesof(/datum/weather))
var/probability = initial(weather.probability)
var/target_trait = initial(weather.target_trait)
if(probability && level.traits[target_trait])
LAZYINITLIST(eligible_zlevels["[z]"])
eligible_zlevels["[z]"][weather] = probability
/datum/controller/subsystem/weather/proc/run_weather(datum/weather/weather_datum_type, z_levels)
if (istext(weather_datum_type))
for (var/V in subtypesof(/datum/weather))

View File

@@ -18,7 +18,7 @@
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY), .proc/play_squeak)
if(ismovable(parent))
RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT), .proc/play_squeak)
RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT, COMSIG_PROJECTILE_BEFORE_FIRE), .proc/play_squeak)
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/play_squeak_crossed)
RegisterSignal(parent, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react)
if(isitem(parent))
@@ -60,11 +60,8 @@
var/obj/item/I = AM
if(I.item_flags & ABSTRACT)
return
else if(istype(AM, /obj/item/projectile))
var/obj/item/projectile/P = AM
if(P.original != parent)
return
if(istype(AM, /obj/effect/dummy/phased_mob)) //don't squeek if they're in a phased/jaunting container.
if(AM.movement_type & (FLYING|FLOATING) || !AM.has_gravity())
return
var/atom/current_parent = parent
if(isturf(current_parent.loc))

View File

@@ -30,7 +30,7 @@
/datum/action/innate/dash/proc/Teleport(mob/user, atom/target)
if(!IsAvailable())
return
return FALSE
var/turf/T = get_turf(target)
var/area/AU = get_area(user)
var/area/AT = get_area(T)

View File

@@ -9,6 +9,8 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
icon_state = "away"
has_gravity = STANDARD_GRAVITY
ambientsounds = AWAY_MISSION
unique = TRUE
/area/awaymission/beach
name = "Beach"
@@ -30,3 +32,28 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
var/pacifist = TRUE // if when you enter this zone, you become a pacifist or not
var/death = FALSE // if when you enter this zone, you die
/area/awaymission/secret
noteleport = TRUE
unique = TRUE
hidden = TRUE
/area/awaymission/secret/unpowered
always_unpowered = TRUE
/area/awaymission/secret/unpowered/outdoors
outdoors = TRUE
/area/awaymission/secret/unpowered/no_grav
has_gravity = FALSE
/area/awaymission/secret/fullbright
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
/area/awaymission/secret/powered
requires_power = FALSE
/area/awaymission/secret/powered/fullbright
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED

View File

@@ -10,7 +10,7 @@
/area/ruin/unpowered
always_unpowered = FALSE
always_unpowered = TRUE
power_light = FALSE
power_equip = FALSE
power_environ = FALSE

View File

@@ -492,6 +492,12 @@
/atom/movable/proc/forceMove(atom/destination)
. = FALSE
if(destination)
var/turf/new_turf = get_turf(destination)
if(ismob(src))
var/mob/M = src
if(is_secret_level(new_turf.z) && !M.client?.holder)
return
. = doMove(destination)
else
CRASH("No valid destination passed into forceMove")

View File

@@ -657,9 +657,14 @@
/obj/mecha/Bump(var/atom/obstacle)
var/turf/newloc = get_step(src,dir)
var/area/newarea = newloc.loc
if(newloc.flags_1 & NOJAUNT_1)
to_chat(occupant, span_warning("Some strange aura is blocking the way."))
return
if(newarea.noteleport || SSmapping.level_trait(newloc.z, ZTRAIT_NOPHASE))
to_chat(occupant, span_warning("Some strange aura is blocking the way."))
return
if(phasing && get_charge() >= phasing_energy_drain && !throwing)
spawn()
if(can_move)

View File

@@ -0,0 +1,68 @@
/obj/effect/dummy/phased_mob
name = "water"
anchored = TRUE
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
invisibility = INVISIBILITY_OBSERVER
movement_type = FLOATING
var/movedelay = 0
var/movespeed = 0
/obj/effect/dummy/phased_mob/Destroy()
// Eject contents if deleted somehow
var/atom/dest = drop_location()
if(!dest) //You're in nullspace you clown
return ..()
var/area/destination_area = get_area(dest)
var/failed_areacheck = FALSE
if(destination_area.noteleport)
failed_areacheck = TRUE
for(var/_phasing_in in contents)
var/atom/movable/phasing_in = _phasing_in
if(!failed_areacheck)
phasing_in.forceMove(drop_location())
else //this ONLY happens if someone uses a phasing effect to try to land in a NOTELEPORT zone after it is created, AKA trying to exploit.
if(isliving(phasing_in))
var/mob/living/living_cheaterson = phasing_in
to_chat(living_cheaterson, span_userdanger("This area has a heavy universal force occupying it, and you are scattered to the cosmos!"))
if(ishuman(living_cheaterson))
shake_camera(living_cheaterson, 20, 1)
addtimer(CALLBACK(living_cheaterson, /mob/living/carbon.proc/vomit), 2 SECONDS)
phasing_in.forceMove(find_safe_turf(z))
return ..()
/obj/effect/dummy/phased_mob/ex_act()
return FALSE
/obj/effect/dummy/phased_mob/bullet_act(blah)
return BULLET_ACT_FORCE_PIERCE
/obj/effect/dummy/phased_mob/relaymove(mob/living/user, direction)
var/turf/newloc = phased_check(user, direction)
if(!newloc)
return
setDir(direction)
forceMove(newloc)
/// Checks if the conditions are valid to be able to phase. Returns a turf destination if positive.
/obj/effect/dummy/phased_mob/proc/phased_check(mob/living/user, direction)
RETURN_TYPE(/turf)
if (movedelay > world.time || !direction)
return
var/turf/newloc = get_step(src,direction)
if(!newloc)
return
var/area/destination_area = newloc.loc
movedelay = world.time + movespeed
if(newloc.flags_1 & NOJAUNT_1)
to_chat(user, span_warning("Some strange aura is blocking the way."))
return
if(destination_area.noteleport || SSmapping.level_trait(newloc.z, ZTRAIT_NOPHASE))
to_chat(user, span_danger("Some dull, universal force is blocking the way. It's overwhelmingly oppressive force feels dangerous."))
return
return newloc
/// React to signals by deleting the effect. Used for bloodcrawl.
/obj/effect/dummy/phased_mob/proc/deleteself(mob/living/source, obj/effect/decal/cleanable/phase_in_decal)
SHOULD_NOT_SLEEP(TRUE)
qdel(src)

View File

@@ -152,7 +152,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
update_air_ref()
SSair.add_to_active(newTurf)
else
if(ispath(path,/turf/closed))
if(ispath(path,/turf/closed)|| ispath(path,/turf/cordon))
flags |= CHANGETURF_RECALC_ADJACENT
return ..()

View File

@@ -41,6 +41,7 @@ GLOBAL_LIST_INIT(admin_verbs_debug_all, list(
/client/proc/cmd_admin_test_atmos_controllers,
/datum/admins/proc/show_traitor_panel,
/client/proc/disable_communication,
/client/proc/show_map_reports,
/client/proc/cmd_show_at_list,
/client/proc/cmd_show_at_markers,
/client/proc/manipulate_organs,
@@ -189,6 +190,18 @@ GLOBAL_LIST_EMPTY(dirty_vars)
qdel(F)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Intercom Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/show_map_reports()
set category = "Mapping"
set name = "Show map report list"
set desc = "Displays a list of map reports"
var/dat = {"<b>List of all map reports:</b><br>"}
for(var/datum/map_report/report as anything in GLOB.map_reports)
dat += "[report.tag] ([report.original_path]) - <a href='?src=[REF(report)];[HrefToken()];show=1'>View</a><br>"
usr << browse(dat, "window=map_reports")
/client/proc/cmd_show_at_list()
set category = "Misc.Server Debug"
set name = "Show roundstart AT list"

View File

@@ -274,7 +274,7 @@
/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, kind = "", datum/mind/user)
var/obj/effect/dummy/crawling/holder = new /obj/effect/dummy/crawling(T) //yogs start
//var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter(T)
//var/obj/effect/dummy/phased_mob/holder = new /obj/effect/dummy/phased_mob(T)
var/mob/living/simple_animal/slaughter/S = new demon_type(holder)
//S.holder = holder //yogs end
S.key = C.key

View File

@@ -218,7 +218,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
H.set_species(/datum/species/human, 1)
H.regenerate_icons()
give_appropriate_spells()
if(istype(owner.current.loc, /obj/effect/dummy/phased_mob/slaughter/))
if(istype(owner.current.loc, /obj/effect/dummy/phased_mob))
owner.current.forceMove(get_turf(owner.current))//Fixes dying while jaunted leaving you permajaunted.
form = BASIC_DEVIL
@@ -303,7 +303,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
sound_to_playing_players('sound/hallucinations/veryfar_noise.ogg')
give_appropriate_spells()
D.convert_to_archdevil()
if(istype(D.loc, /obj/effect/dummy/phased_mob/slaughter/))
if(istype(D.loc, /obj/effect/dummy/phased_mob))
D.forceMove(get_turf(D))//Fixes dying while jaunted leaving you permajaunted.
var/area/A = get_area(owner.current)
if(A)
@@ -429,7 +429,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
update_hud()
if(body)
body.revive(TRUE, TRUE) //Adminrevive also recovers organs, preventing someone from resurrecting without a heart.
if(istype(body.loc, /obj/effect/dummy/phased_mob/slaughter/))
if(istype(body.loc, /obj/effect/dummy/phased_mob))
body.forceMove(get_turf(body))//Fixes dying while jaunted leaving you permajaunted.
if(istype(body, /mob/living/carbon/true_devil))
var/mob/living/carbon/true_devil/D = body

View File

@@ -50,7 +50,7 @@
..()
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
AddSpell(bloodspell)
if(istype(loc, /obj/effect/dummy/phased_mob/slaughter))
if(istype(loc, /obj/effect/dummy/phased_mob))
bloodspell.phased = TRUE
/obj/effect/decal/cleanable/blood/innards

View File

@@ -32,7 +32,7 @@
message_admins("No valid spawn locations found, aborting...")
return MAP_ERROR
/*var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter((pick(spawn_locs))) //yogs start - Bloodcrawl refactor
/*var/obj/effect/dummy/phased_mob/holder = new /obj/effect/dummy/phased_mob((pick(spawn_locs))) //yogs start - Bloodcrawl refactor
var/mob/living/simple_animal/slaughter/S = new (holder)
S.holder = holder*/
var/obj/effect/dummy/crawling/holder = new(pick(spawn_locs))

View File

@@ -0,0 +1,58 @@
/turf/cordon
name = "cordon"
icon = 'icons/turf/walls.dmi'
icon_state = "cordon"
invisibility = INVISIBILITY_ABSTRACT
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
explosion_block = INFINITY
rad_insulation = RAD_FULL_INSULATION
opacity = TRUE
density = TRUE
blocks_air = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
bullet_bounce_sound = null
/turf/cordon/AfterChange()
. = ..()
SSair.high_pressure_delta -= src
/turf/cordon/attack_ghost(mob/dead/observer/user)
return FALSE
/turf/cordon/rust_heretic_act()
return FALSE
/turf/cordon/acid_act(acidpwr, acid_volume, acid_id)
return FALSE
/turf/cordon/Melt()
to_be_destroyed = FALSE
return src
/turf/cordon/singularity_act()
return FALSE
/turf/cordon/ScrapeAway(amount, flags)
return src // :devilcat:
/turf/cordon/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
return BULLET_ACT_HIT
/turf/cordon/Adjacent(atom/neighbor, atom/target, atom/movable/mover)
return FALSE
/area/cordon
name = "CORDON"
icon_state = "cordon"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
unique = TRUE
noteleport = TRUE
hidden = TRUE
requires_power = FALSE
/area/cordon/Entered(atom/movable/arrived, area/old_area)
. = ..()
for(var/mob/living/enterer as anything in arrived.get_all_contents_type(/mob/living))
to_chat(enterer, span_userdanger("This was a bad idea..."))
enterer.dust(TRUE, FALSE, TRUE)

View File

@@ -1,15 +1,22 @@
// How much "space" we give the edge of the map
GLOBAL_LIST_INIT(potentialRandomZlevels, generateMapList(filename = "[global.config.directory]/awaymissionconfig.txt"))
GLOBAL_LIST_INIT(potentialConfigRandomZlevels, generateConfigMapList(directory = "[global.config.directory]/away_missions/"))
/proc/createRandomZlevel()
if(GLOB.awaydestinations.len) //crude, but it saves another var!
return
if(GLOB.potentialRandomZlevels && GLOB.potentialRandomZlevels.len)
/proc/createRandomZlevel(config_gateway = FALSE)
var/map
if(config_gateway && GLOB.potentialConfigRandomZlevels?.len)
map = pick_n_take(GLOB.potentialConfigRandomZlevels)
else if(GLOB.potentialRandomZlevels?.len)
map = pick_n_take(GLOB.potentialRandomZlevels)
else
return to_chat(world, span_boldannounce("No valid away mission files, loading aborted."))
to_chat(world, span_boldannounce("Loading away mission..."))
var/map = pick(GLOB.potentialRandomZlevels)
load_new_z_level(map, "Away Mission")
to_chat(world, span_boldannounce("Away mission loaded."))
var/loaded = load_new_z_level(map, "Away Mission", config_gateway)
to_chat(world, span_boldannounce("Away mission [loaded ? "loaded" : "aborted due to errors"]."))
if(!loaded)
message_admins("Away mission [map] loading failed due to errors.")
log_admin("Away mission [map] loading failed due to errors.")
createRandomZlevel(config_gateway)
/proc/reset_gateway_spawns(reset = FALSE)
for(var/obj/machinery/gateway/G in world)
@@ -59,3 +66,12 @@ GLOBAL_LIST_INIT(potentialRandomZlevels, generateMapList(filename = "[global.con
continue
. += t
/proc/generateConfigMapList(directory)
var/list/config_maps = list()
var/list/maps = flist(directory)
for(var/map_file in maps)
if(!findtext(map_file, ".dmm"))
continue
config_maps += (directory + map_file)
return config_maps

View File

@@ -55,11 +55,11 @@
SSmachines.setup_template_powernets(cables)
SSair.setup_template_machinery(atmos_machines)
/datum/map_template/proc/load_new_z()
/datum/map_template/proc/load_new_z(secret = FALSE)
var/x = round((world.maxx - width)/2)
var/y = round((world.maxy - height)/2)
var/datum/space_level/level = SSmapping.add_new_zlevel(name, list(ZTRAIT_AWAY = TRUE))
var/datum/space_level/level = SSmapping.add_new_zlevel(name, secret ? ZTRAITS_AWAY_SECRET : ZTRAITS_AWAY)
var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE)
var/list/bounds = parsed.bounds
if(!bounds)
@@ -114,6 +114,10 @@
//for your ever biggening badminnery kevinz000
//❤ - Cyberboss
/proc/load_new_z_level(var/file, var/name)
var/datum/map_template/template = new(file, name)
template.load_new_z()
/proc/load_new_z_level(file, name, secret)
var/datum/map_template/template = new(file, name, TRUE)
if(!template.cached_map || template.cached_map.check_for_errors())
return FALSE
template.load_new_z(secret)
return TRUE

View File

@@ -259,3 +259,17 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
. = ..()
var/area/a = get_area(loc)
a.teleport_anchors += loc
/obj/effect/mapping_helpers/ztrait_injector
name = "ztrait injector"
icon_state = "ztrait"
/// List of traits to add to this.
var/list/traits_to_add = list()
/obj/effect/mapping_helpers/ztrait_injector/Initialize()
. = ..()
var/datum/space_level/level = SSmapping.z_list[z]
if(!level || !length(traits_to_add))
return
level.traits |= traits_to_add
SSweather.update_z_level(level) //in case of someone adding a weather for the level, we want SSweather to update for that

View File

@@ -1,3 +1,6 @@
/// Global list of map report datums
GLOBAL_LIST_EMPTY(map_reports)
/// An error report generated by [parsed_map/check_for_errors].
/datum/map_report
var/original_path
@@ -11,6 +14,12 @@
/datum/map_report/New(datum/parsed_map/map)
original_path = map.original_path || "Untitled"
GLOB.map_reports += src
/datum/map_report/Destroy(force, ...)
GLOB.map_reports -= src
return ..()
/// Show a rendered version of this report to a client.
/datum/map_report/proc/show_to(client/C)

View File

@@ -3,13 +3,8 @@
if (client)
client.images -= (GLOB.ghost_images_default+GLOB.ghost_images_simple)
if(observetarget)
if(ismob(observetarget))
var/mob/target = observetarget
if(target.observers)
target.observers -= src
UNSETEMPTY(target.observers)
observetarget = null
if(observetarget && ismob(observetarget))
cleanup_observe()
..()
spawn(0)
if(src && !key) //we've transferred to another mob. This ghost should be deleted.

View File

@@ -111,7 +111,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
update_icon()
if(!T)
if(!T || is_secret_level(T.z))
var/list/turfs = get_area_turfs(/area/shuttle/arrival)
if(turfs.len)
T = pick(turfs)
@@ -444,7 +444,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
// This is the ghost's follow verb with an argument
/mob/dead/observer/proc/ManualFollow(atom/movable/target)
if (!istype(target))
if (!istype(target) || (is_secret_level(target.z) && !client?.holder))
return
var/icon/I = icon(target.icon,target.icon_state,target.dir)
@@ -808,16 +808,23 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/reset_perspective(atom/A)
if(client)
if(ismob(client.eye) && (client.eye != src))
var/mob/target = client.eye
observetarget = null
if(target.observers)
target.observers -= src
UNSETEMPTY(target.observers)
cleanup_observe()
if(..())
if(hud_used)
client.screen = list()
hud_used.show_hud(hud_used.hud_version)
/mob/dead/observer/proc/cleanup_observe()
var/mob/target = observetarget
observetarget = null
client?.perspective = initial(client.perspective)
sight = initial(sight)
UnregisterSignal(target, COMSIG_MOVABLE_Z_CHANGED)
if(target.observers)
target.observers -= src
UNSETEMPTY(target.observers)
/mob/dead/observer/verb/observe()
set name = "Observe"
set category = "OOC"
@@ -839,6 +846,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
//Istype so we filter out points of interest that are not mobs
if(client && mob_eye && istype(mob_eye))
client.eye = mob_eye
client.perspective = EYE_PERSPECTIVE
if(is_secret_level(mob_eye.z) && !client?.holder)
sight = null //we dont want ghosts to see through walls in secret areas
RegisterSignal(mob_eye, COMSIG_MOVABLE_Z_CHANGED, .proc/on_observing_z_changed)
if(mob_eye.hud_used)
client.screen = list()
LAZYINITLIST(mob_eye.observers)
@@ -846,6 +857,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
mob_eye.hud_used.show_hud(mob_eye.hud_used.hud_version, src)
observetarget = mob_eye
/mob/dead/observer/proc/on_observing_z_changed(datum/source, turf/old_turf, turf/new_turf)
SHOULD_NOT_SLEEP(TRUE)
if(is_secret_level(new_turf.z) && !client?.holder)
sight = null //we dont want ghosts to see through walls in secret areas
else
sight = initial(sight)
/mob/dead/observer/verb/register_pai_candidate()
set category = "Ghost"
set name = "pAI Setup"

View File

@@ -1,27 +1,3 @@
/obj/effect/dummy/phased_mob/slaughter //Can't use the wizard one, blocked by jaunt/slow
name = "water"
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
var/canmove = 1
density = FALSE
anchored = TRUE
invisibility = 60
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
/obj/effect/dummy/phased_mob/slaughter/relaymove(mob/user, direction)
forceMove(get_step(src,direction))
/obj/effect/dummy/phased_mob/slaughter/ex_act()
return
/obj/effect/dummy/phased_mob/slaughter/bullet_act()
return BULLET_ACT_FORCE_PIERCE
/obj/effect/dummy/phased_mob/slaughter/singularity_act()
return
/mob/living/proc/phaseout(obj/effect/decal/cleanable/B)
if(iscarbon(src))
var/mob/living/carbon/C = src
@@ -51,7 +27,7 @@
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 50, 1, -1)
// Extinguish, unbuckle, stop being pulled, set our location into the
// dummy object
var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter(mobloc)
var/obj/effect/dummy/phased_mob/holder = new /obj/effect/dummy/phased_mob(mobloc)
src.ExtinguishMob()
// Keep a reference to whatever we're pulling, because forceMove()

View File

@@ -593,6 +593,11 @@
if(!client)
return
if(stat == DEAD)
if(SSmapping.level_trait(z, ZTRAIT_NOXRAY))
sight = null
else if(is_secret_level(z))
sight = initial(sight)
else
sight = (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = 8
see_invisible = SEE_INVISIBLE_OBSERVER
@@ -636,7 +641,11 @@
if(see_override)
see_invisible = see_override
. = ..()
if(SSmapping.level_trait(z, ZTRAIT_NOXRAY))
sight = null
return ..()
//to recalculate and update the mob's total tint from tinted equipment it's wearing.

View File

@@ -1014,6 +1014,11 @@
if(!client)
return
if(stat == DEAD)
if(SSmapping.level_trait(z, ZTRAIT_NOXRAY))
sight = null
else if(is_secret_level(z))
sight = initial(sight)
else
sight = (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = 8
see_invisible = SEE_INVISIBLE_OBSERVER
@@ -1051,6 +1056,10 @@
if(see_override)
see_invisible = see_override
if(SSmapping.level_trait(z, ZTRAIT_NOXRAY))
sight = null
sync_lighting_plane_alpha()
/mob/living/silicon/robot/update_stat()

View File

@@ -18,6 +18,7 @@
minbodytemp = 0
faction = list("nether")
/mob/living/simple_animal/hostile/netherworld/migo
name = "mi-go"
desc = "A pinkish, fungoid crustacean-like creature with numerous pairs of clawed appendages and a head covered with waving antennae."

View File

@@ -476,6 +476,11 @@
if(!client)
return
if(stat == DEAD)
if(SSmapping.level_trait(z, ZTRAIT_NOXRAY))
sight = null
else if(is_secret_level(z))
sight = initial(sight)
else
sight = (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = 8
see_invisible = SEE_INVISIBLE_OBSERVER
@@ -484,7 +489,8 @@
see_invisible = initial(see_invisible)
see_in_dark = initial(see_in_dark)
sight = initial(sight)
if(SSmapping.level_trait(z, ZTRAIT_NOXRAY))
sight = null
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.

View File

@@ -106,7 +106,7 @@
/obj/effect/proc_holder/spell/targeted/infernal_jaunt/cast(list/targets, mob/living/user = usr)
if(istype(user))
if(istype(user.loc, /obj/effect/dummy/phased_mob/slaughter/))
if(istype(user.loc, /obj/effect/dummy/phased_mob))
if(valid_location(user))
to_chat(user, span_warning("You are now phasing in."))
if(do_mob(user,user,150))
@@ -147,7 +147,7 @@
spawn_dust()
visible_message(span_warning("[src] disappears in a flashfire!"))
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter(loc)
var/obj/effect/dummy/phased_mob/holder = new /obj/effect/dummy/phased_mob(loc)
ExtinguishMob()
forceMove(holder)
holder = holder

View File

@@ -70,42 +70,15 @@
playsound(get_turf(target), 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1)
/obj/effect/dummy/phased_mob/spell_jaunt
name = "water"
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
movespeed = 2 //quite slow.
var/reappearing = FALSE
var/movedelay = 0
var/movespeed = 2
density = FALSE
anchored = TRUE
invisibility = 60
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
/obj/effect/dummy/phased_mob/spell_jaunt/Destroy()
// Eject contents if deleted somehow
for(var/atom/movable/AM in src)
AM.forceMove(get_turf(src))
return ..()
/obj/effect/dummy/phased_mob/spell_jaunt/relaymove(var/mob/user, direction)
if ((movedelay > world.time) || reappearing || !direction)
/obj/effect/dummy/phased_mob/spell_jaunt/phased_check(mob/living/user, direction)
if(reappearing)
return
var/turf/newLoc = get_step(src,direction)
setDir(direction)
movedelay = world.time + movespeed
if(newLoc.flags_1 & NOJAUNT_1)
to_chat(user, span_warning("Some strange aura is blocking the way."))
. = ..()
if(!.)
return
if (locate(/obj/effect/blessing, newLoc))
to_chat(user, span_warning("Holy energies block your path!"))
return
forceMove(newLoc)
/obj/effect/dummy/phased_mob/spell_jaunt/ex_act(blah)
return
/obj/effect/dummy/phased_mob/spell_jaunt/bullet_act(blah)
return BULLET_ACT_FORCE_PIERCE
if (locate(/obj/effect/blessing, .))
to_chat(user, "<span class='warning'>Holy energies block your path!</span>")
return null

View File

@@ -35,24 +35,34 @@
to_chat(user, span_warning("It isn't dark enough here!"))
/obj/effect/dummy/phased_mob/shadow
name = "darkness"
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
var/canmove = TRUE
var/mob/living/jaunter
density = FALSE
anchored = TRUE
invisibility = 60
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
/obj/effect/dummy/phased_mob/shadow/relaymove(mob/user, direction)
var/turf/newLoc = get_step(src,direction)
if(isspaceturf(newLoc))
to_chat(user, span_warning("It really would not be wise to go into space."))
return
forceMove(newLoc)
/obj/effect/dummy/phased_mob/shadow/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
/obj/effect/dummy/phased_mob/shadow/Destroy()
jaunter = null
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/effect/dummy/phased_mob/shadow/process()
if(!jaunter || jaunter.loc != src)
qdel(src)
check_light_level()
/obj/effect/dummy/phased_mob/shadow/relaymove(mob/living/user, direction)
var/turf/oldloc = loc
. = ..()
if(loc != oldloc)
check_light_level()
/obj/effect/dummy/phased_mob/shadow/phased_check(mob/living/user, direction)
. = ..()
if(. && isspaceturf(.))
to_chat(user, "<span class='warning'>It really would not be wise to go into space.</span>")
return FALSE
/obj/effect/dummy/phased_mob/shadow/proc/check_light_level()
var/turf/T = get_turf(src)
var/light_amount = T.get_lumcount()
@@ -66,33 +76,7 @@
if(forced)
visible_message(span_boldwarning("[jaunter] is revealed by the light!"))
else
visible_message(span_boldwarning("[jaunter] emerges from the darkness!"))
jaunter.forceMove(get_turf(src))
playsound(get_turf(jaunter), 'sound/magic/ethereal_exit.ogg', 50, 1, -1)
jaunter = null
visible_message("<span class='boldwarning'>[jaunter] emerges from the darkness!</span>")
playsound(loc, 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1)
qdel(src)
/obj/effect/dummy/phased_mob/shadow/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
/obj/effect/dummy/phased_mob/shadow/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/effect/dummy/phased_mob/shadow/process()
if(!jaunter)
qdel(src)
if(jaunter.loc != src)
qdel(src)
check_light_level()
/obj/effect/dummy/phased_mob/shadow/ex_act()
return
/obj/effect/dummy/phased_mob/shadow/bullet_act()
return BULLET_ACT_FORCE_PIERCE
/obj/effect/dummy/phased_mob/shadow/singularity_act()
return

View File

@@ -0,0 +1,3 @@
Add away mission dmms here.
**These are fully cached so keep this directory empty by default.**

View File

@@ -337,13 +337,15 @@ ALLOW_AI_MULTICAM
## Uncomment to load the virtual reality hub map
#VIRTUAL_REALITY
## Uncomment to load one of the missions from awaymissionconfig.txt at roundstart.
## Uncomment to load one of the missions from awaymissionconfig.txt or away_missions/ at roundstart.
#ROUNDSTART_AWAY
## How long the delay is before the Away Mission gate opens. Default is half an hour.
## 600 is one minute.
GATEWAY_DELAY 18000
## The probability of the gateway mission being a config one
CONFIG_GATEWAY_CHANCE 0
## ACCESS ###

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -895,6 +895,7 @@
#include "code\game\objects\effects\mines.dm"
#include "code\game\objects\effects\misc.dm"
#include "code\game\objects\effects\overlays.dm"
#include "code\game\objects\effects\phased_mob.dm"
#include "code\game\objects\effects\portals.dm"
#include "code\game\objects\effects\proximity.dm"
#include "code\game\objects\effects\spiders.dm"
@@ -1701,6 +1702,7 @@
#include "code\modules\awaymissions\away_props.dm"
#include "code\modules\awaymissions\bluespaceartillery.dm"
#include "code\modules\awaymissions\capture_the_flag.dm"
#include "code\modules\awaymissions\cordon.dm"
#include "code\modules\awaymissions\corpse.dm"
#include "code\modules\awaymissions\exile.dm"
#include "code\modules\awaymissions\gateway.dm"

View File

@@ -83,7 +83,7 @@
R.reveal(20)
R.stun(20)
return MOVE_NOT_ALLOWED
if(destination.flags_1 & NOJAUNT_1)
if(destination.flags_1 & NOJAUNT_1 || is_secret_level(destination.z))
to_chat(user, span_warning("Some strange aura is blocking the way."))
return MOVE_NOT_ALLOWED
if (locate(/obj/effect/blessing, destination))