diff --git a/.editorconfig b/.editorconfig index 1770177310de..5e08df597a3a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,14 +1,17 @@ -[*] -indent_style = tab -indent_size = 4 -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true -end_of_line = lf - -[*.yml] -indent_style = space -indent_size = 2 - -[*.py] -indent_style = space +[*] +indent_style = tab +indent_size = 4 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +end_of_line = lf + +[*.yml] +indent_style = space +indent_size = 2 + +[*.py] +indent_style = space + +[*.json] +indent_style = space diff --git a/.gitignore b/.gitignore index 5731511cb76b..3e82ddf9387f 100644 --- a/.gitignore +++ b/.gitignore @@ -15,16 +15,14 @@ cfg/ tmp/ tools/Runtime Condenser/Input.txt tools/Runtime Condenser/Output.txt -tools/MapDaemon/logs/*.txt sound/music/*.ogg sound/music/walkman/*/*.ogg sound/music/walkman/*.txt icons/custom/* maps/**/backup -*.json *.before __pycache__ test_environment.txt - +*.json *.vscode/* !/.vscode/extensions.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 06e7edfbc64d..b50b83f5b747 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,39 +1,42 @@ image: i386/ubuntu:xenial -stages: - - build - variables: - BYOND_MAJOR: "513" - BYOND_MINOR: "1527" - SPACEMAN_DMM_VERSION: "1.6" GITLAB_CHANGELOG_PID: "21031593" GITLAB_REPO_LINK: "git@gitlab.com:cmdevs/colonial-warfare.git" +stages: + - build -before_script: - - apt-get update -qq - - apt-get --yes install build-essential unzip libc6:i386 libgcc1:i386 libstdc++6:i386 curl -qq - - curl "http://www.byond.com/download/build/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -o byond.zip - - unzip byond.zip - - cd byond - - make install - - cd .. - - curl -LJO "https://github.com/SpaceManiac/SpacemanDMM/releases/download/suite-${SPACEMAN_DMM_VERSION}/dreamchecker" -o dreamchecker - - chmod +x dreamchecker - -build: - stage: build - script: - - ./dreamchecker - - chmod +rwx ./insert_maps_in_dme.sh - - ./insert_maps_in_dme.sh - - DreamMaker ColonialMarinesALPHA.dme - artifacts: - paths: - - ColonialMarinesALPHA.dmb - - ColonialMarinesALPHA.rsc - expire_in: 20min +run_linters: + stage: build + before_script: + - apt update + - apt install -y software-properties-common + - add-apt-repository ppa:deadsnakes/ppa + - apt update + - apt install -y curl unzip build-essential libssl-dev build-essential libc6:i386 libgcc1:i386 libstdc++6:i386 python3.7 wget + - bash tools/ci/install_spaceman_dmm.sh dreamchecker + script: + - find . -name "*.json" -not -path "*/node_modules/*" -print0 | xargs -0 python3 ./tools/json_verifier.py + - ~/dreamchecker +compile_all_maps: + stage: build + before_script: + - apt update + - apt install -y software-properties-common + - add-apt-repository ppa:deadsnakes/ppa + - apt update + - apt install -y curl python3.7 unzip build-essential libc6:i386 libgcc1:i386 libstdc++6:i386 + script: + - bash tools/ci/install_byond.sh + - source $HOME/BYOND/byond/bin/byondsetup + - python3 tools/ci/template_dm_generator.py + - bash tools/ci/dm.sh -DCIBUILDING -DCITESTING -DALL_MAPS ColonialMarinesALPHA.dme + artifacts: + paths: + - ColonialMarinesALPHA.dmb + - ColonialMarinesALPHA.rsc + expire_in: 20min changelog: stage: build diff --git a/ColonialMarinesALPHA.dme b/ColonialMarinesALPHA.dme index 4ed9a9e9f363..3d6dfb0dcfc4 100644 --- a/ColonialMarinesALPHA.dme +++ b/ColonialMarinesALPHA.dme @@ -47,6 +47,7 @@ #include "code\__DEFINES\icon_source_map.dm" #include "code\__DEFINES\job.dm" #include "code\__DEFINES\layers.dm" +#include "code\__DEFINES\maps.dm" #include "code\__DEFINES\marine.dm" #include "code\__DEFINES\math_physics.dm" #include "code\__DEFINES\MC.dm" @@ -66,6 +67,7 @@ #include "code\__DEFINES\subsystem.dm" #include "code\__DEFINES\tests.dm" #include "code\__DEFINES\tgui.dm" +#include "code\__DEFINES\turf_flags.dm" #include "code\__DEFINES\urls.dm" #include "code\__DEFINES\vehicle.dm" #include "code\__DEFINES\vendors.dm" @@ -137,7 +139,6 @@ #include "code\_onclick\hud\yautja.dm" #include "code\controllers\_DynamicAreaLighting_TG.dm" #include "code\controllers\shuttle_controller.dm" -#include "code\controllers\voting.dm" #include "code\controllers\configuration\config_entry.dm" #include "code\controllers\configuration\configuration.dm" #include "code\controllers\configuration\entries\combat_config.dm" @@ -173,6 +174,7 @@ #include "code\controllers\subsystem\item_cleanup.dm" #include "code\controllers\subsystem\lighting.dm" #include "code\controllers\subsystem\machinery.dm" +#include "code\controllers\subsystem\mapping.dm" #include "code\controllers\subsystem\mapview.dm" #include "code\controllers\subsystem\midi.dm" #include "code\controllers\subsystem\mob.dm" @@ -203,7 +205,6 @@ #include "code\controllers\subsystem\init\landmarks.dm" #include "code\controllers\subsystem\init\law.dm" #include "code\controllers\subsystem\init\lobby_art.dm" -#include "code\controllers\subsystem\init\mapview.dm" #include "code\controllers\subsystem\processing\objects.dm" #include "code\controllers\subsystem\processing\processing.dm" #include "code\datums\_atmos_setup.dm" @@ -221,6 +222,7 @@ #include "code\datums\event_info_text.dm" #include "code\datums\fluff_emails.dm" #include "code\datums\global_variables.dm" +#include "code\datums\map_config.dm" #include "code\datums\matrix_editor.dm" #include "code\datums\medal_awards.dm" #include "code\datums\mind.dm" @@ -430,6 +432,7 @@ #include "code\game\sound.dm" #include "code\game\supplyshuttle.dm" #include "code\game\world.dm" +#include "code\game\area\admin_level.dm" #include "code\game\area\almayer.dm" #include "code\game\area\areas.dm" #include "code\game\area\BigRed.dm" @@ -445,7 +448,6 @@ #include "code\game\area\strata.dm" #include "code\game\area\Sulaco.dm" #include "code\game\area\WhiskeyOutpost.dm" -#include "code\game\area\Z_Holder.dm" #include "code\game\cas_manager\datums\cas_fire_envelope.dm" #include "code\game\cas_manager\datums\cas_fire_mission.dm" #include "code\game\cas_manager\datums\cas_iff_group.dm" @@ -1047,6 +1049,7 @@ #include "code\modules\admin\IsBanned.dm" #include "code\modules\admin\NewBan.dm" #include "code\modules\admin\player_notes.dm" +#include "code\modules\admin\server_verbs.dm" #include "code\modules\admin\stickyban.dm" #include "code\modules\admin\STUI.dm" #include "code\modules\admin\ToRban.dm" @@ -1120,6 +1123,7 @@ #include "code\modules\clans\ship.dm" #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" +#include "code\modules\client\player_details.dm" #include "code\modules\client\preferences.dm" #include "code\modules\client\preferences_factions.dm" #include "code\modules\client\preferences_gear.dm" @@ -1289,6 +1293,14 @@ #include "code\modules\law\laws\major_crime.dm" #include "code\modules\law\laws\minor_crime.dm" #include "code\modules\law\laws\optional.dm" +#include "code\modules\mapping\map_template.dm" +#include "code\modules\mapping\preloader.dm" +#include "code\modules\mapping\reader.dm" +#include "code\modules\mapping\verify.dm" +#include "code\modules\mapping\space_management\space_level.dm" +#include "code\modules\mapping\space_management\space_reservation.dm" +#include "code\modules\mapping\space_management\traits.dm" +#include "code\modules\mapping\space_management\zlevel_manager.dm" #include "code\modules\maps\dmm_suite.dm" #include "code\modules\maps\reader.dm" #include "code\modules\mapview\generation.dm" @@ -1815,9 +1827,5 @@ #include "code\modules\vehicles\tank\tank.dm" #include "interface\interface.dm" #include "interface\skin.dmf" -#include "maps\Z.02.Admin_Level.dm" -#include "maps\Z.01.LV624.dmm" -#include "maps\Z.02.Admin_Level.dmm" -#include "maps\Z.03.USS_Almayer.dmm" -#include "maps\Z.04.Low_Orbit.dmm" +#include "maps\_basemap.dm" // END_INCLUDE diff --git a/code/__DEFINES/__game.dm b/code/__DEFINES/__game.dm index e1a1799caf2e..dc198be191eb 100644 --- a/code/__DEFINES/__game.dm +++ b/code/__DEFINES/__game.dm @@ -37,7 +37,7 @@ #define PLAYERCOUNT_LOWPOP_MAP_LIMIT 130 // number of players before we switch to lowpop maps only (LV, BR, Prison) -#define PREROUND_TIME 240 // time before the round starts +#define PREROUND_TIME 360 // time before the round starts //A set of constants used to determine which type of mute an admin wishes to apply: //Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1) @@ -179,9 +179,6 @@ //================================================= //Game mode related defines. -var/list/accessable_z_levels = list("1" = 10, "3" = 10, "4" = 10, "5" = 70) -//This list contains the z-level numbers which can be accessed via space travel and the percentile chances to get there. - #define TRANSITIONEDGE 3 //Distance from edge to move to another z-level //Flags for zone sleeping diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index ec6a32a52f4c..3018271b6402 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -6,6 +6,8 @@ // These are signals which can be listened to by any component on any parent // start global signals with "!", this used to be necessary but now it's just a formatting choice +///from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args) +#define COMSIG_GLOB_NEW_Z "!new_z" ///from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args) #define COMSIG_GLOB_VEHICLE_ORDERED "!vehicle_ordered" ///from /datum/game_mode/proc/pre_setup @@ -16,6 +18,7 @@ #define COMSIG_GLOB_MARINE_DEATH "!marine_death" ///from /mob/living/carbon/Xenomorph/death #define COMSIG_GLOB_XENO_DEATH "!xeno_death" +#define COMSIG_GLOB_REMOVE_VOTE_BUTTON "!remove_vote_button" ////////////////////////////////////////////////////////////////// diff --git a/code/__DEFINES/equipment.dm b/code/__DEFINES/equipment.dm index 96fcaa20a423..76db7338420e 100644 --- a/code/__DEFINES/equipment.dm +++ b/code/__DEFINES/equipment.dm @@ -24,6 +24,7 @@ #define CAN_BE_SYRINGED (1<<13) // syringes can inject or drain reagents in this even if it isn't an OPENCONTAINER #define CAN_BE_DISPENSED_INTO (1<<14) // Chem dispenser can dispense in this even if it isn't an OPENCONTAINER #define INITIALIZED (1<<15) // Initialized by SSatoms. +#define ATOM_DECORATED (1<<16) // Has run Decorate() as part of subsystem init //========================================================================================== #define HANDLE_BARRIER_CHANCE 1 diff --git a/code/__DEFINES/icon_source_map.dm b/code/__DEFINES/icon_source_map.dm index 7fb782ef53f3..ca63c788f582 100644 --- a/code/__DEFINES/icon_source_map.dm +++ b/code/__DEFINES/icon_source_map.dm @@ -1,7 +1,7 @@ GLOBAL_LIST_EMPTY(icon_source_files) /proc/get_icon_from_source(source_name) - var/icon/I = null + if(GLOB.icon_source_files[source_name]) + return GLOB.icon_source_files[source_name] GLOB.icon_source_files[source_name] = file(source_name) - I = GLOB.icon_source_files[source_name] - return I + return GLOB.icon_source_files[source_name] diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm new file mode 100644 index 000000000000..4d1bc730048e --- /dev/null +++ b/code/__DEFINES/maps.dm @@ -0,0 +1,116 @@ +/* +The /tg/ codebase allows mixing of hardcoded and dynamically-loaded z-levels. +Z-levels can be reordered as desired and their properties are set by "traits". +See map_config.dm for how a particular station's traits may be chosen. +The list DEFAULT_MAP_TRAITS at the bottom of this file should correspond to +the maps that are hardcoded, as set in maps/_basemap.dm. SSmapping is +responsible for loading every non-hardcoded z-level. + + +Multi-Z stations are supported and multi-Z mining and away missions would +require only minor tweaks. +*/ + +// helpers for modifying jobs, used in various job_changes.dm files +#define MAP_JOB_CHECK if(SSmapping.configs[GROUND_MAP].map_name != JOB_MODIFICATION_MAP_NAME) { return; } +#define MAP_JOB_CHECK_BASE if(SSmapping.configs[GROUND_MAP].map_name != JOB_MODIFICATION_MAP_NAME) { return ..(); } +#define MAP_REMOVE_JOB(jobpath) /datum/job/##jobpath/map_check() { return (SSmapping.configs[GROUND_MAP].map_name != JOB_MODIFICATION_MAP_NAME) && ..() } + +#define SPACERUIN_MAP_EDGE_PAD 15 + +// traits +// boolean - marks a level as having that property if present +#define ZTRAIT_STATION "Station" +#define ZTRAIT_RESERVED "Transit/Reserved" +#define ZTRAIT_GROUND "Ground" +#define ZTRAIT_MARINE_MAIN_SHIP "Marine Main Ship" +#define ZTRAIT_ADMIN "Admin" +#define ZTRAIT_LOWORBIT "LowOrbit" +#define ZTRAIT_HUNTER_SHIP "HunterShop" +#define ZTRAIT_INTERIORS "Interiors" + +#define ZTRAIT_FOG "Fog" +#define ZTRAIT_LOCKDOWN "Lockdown" + +// boolean - weather types that occur on the level +#define ZTRAIT_SNOWSTORM "weather_snowstorm" +#define ZTRAIT_ASHSTORM "weather_ashstorm" +#define ZTRAIT_ACIDRAIN "weather_acidrain" +#define ZTRAIT_SANDSTORM "weather_sandstorm" + +// number - bombcap is multiplied by this before being applied to bombs +#define ZTRAIT_BOMBCAP_MULTIPLIER "Bombcap Multiplier" + +// number - default gravity if there's no gravity generators or area overrides present +#define ZTRAIT_GRAVITY "Gravity" + +// numeric offsets - e.g. {"Down": -1} means that chasms will fall to z - 1 rather than oblivion +#define ZTRAIT_UP "Up" +#define ZTRAIT_DOWN "Down" + +// enum - how space transitions should affect this level +#define ZTRAIT_LINKAGE "Linkage" + // UNAFFECTED if absent - no space transitions + #define UNAFFECTED null + // SELFLOOPING - space transitions always self-loop + #define SELFLOOPING "Self" + // CROSSLINKED - mixed in with the cross-linked space pool + #define CROSSLINKED "Cross" + +// string - type path of the z-level's baseturf (defaults to space) +#define ZTRAIT_BASETURF "Baseturf" + +// default trait definitions, used by SSmapping +#define ZTRAITS_MAIN_SHIP list(ZTRAIT_MARINE_MAIN_SHIP = TRUE) +#define ZTRAITS_GROUND list(ZTRAIT_GROUND = TRUE) +#define ZTRAITS_ADMIN list(ZTRAIT_ADMIN = TRUE) +#define ZTRAITS_LOWORBIT list(ZTRAIT_LOWORBIT = TRUE) +#define ZTRAITS_SPACE list(ZTRAIT_LINKAGE = CROSSLINKED, ZTRAIT_SPACE_RUINS = TRUE) +#define ZTRAITS_INTERIORS list(ZTRAIT_INTERIORS = TRUE) + +#define DL_NAME "name" +#define DL_TRAITS "traits" +#define DECLARE_LEVEL(NAME, TRAITS) list(DL_NAME = NAME, DL_TRAITS = TRAITS) + +// must correspond to _basemap.dm for things to work correctly +#define DEFAULT_MAP_TRAITS list(\ + DECLARE_LEVEL("CentCom", ZTRAITS_ADMIN),\ + DECLARE_LEVEL("LowOrbit", ZTRAITS_LOWORBIT),\ +) + +// Camera lock flags +#define CAMERA_LOCK_SHIP (1<<0) +#define CAMERA_LOCK_GROUND (1<<1) +#define CAMERA_LOCK_ADMIN (1<<2) + +//Reserved/Transit turf type +#define RESERVED_TURF_TYPE /turf/open/space/basic //What the turf is when not being used + +//Ruin Generation + +#define PLACEMENT_TRIES 100 //How many times we try to fit the ruin somewhere until giving up (really should just swap to some packing algo) + +#define PLACE_DEFAULT "random" +#define PLACE_SAME_Z "same" +#define PLACE_SPACE_RUIN "space" +#define PLACE_LAVA_RUIN "lavaland" + + +#define GROUND_MAP "ground_map" +#define SHIP_MAP "ship_map" +#define ALL_MAPTYPES list(GROUND_MAP, SHIP_MAP) +#define MAP_TO_FILENAME list(GROUND_MAP = "data/next_map.json", SHIP_MAP = "data/next_ship.json") + +// traity things +#define MAP_COLD "COLD" + +#define MAP_ARMOR_STYLE_DEFAULT "default" +#define MAP_ARMOR_STYLE_ICE "ice" +#define MAP_ARMOR_STYLE_JUNGLE "jungle" +#define MAP_ARMOR_STYLE_PRISON "prison" + +//turf-only flags +#define NOJAUNT_1 (1<<0) +#define UNUSED_RESERVATION_TURF_1 (1<<1) +/// If a turf can be made dirty at roundstart. This is also used in areas. +#define CAN_BE_DIRTY_1 (1<<2) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 924ba146fa86..3e9900c0614c 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -188,6 +188,9 @@ */ #define get_area(A) (isarea(A) ? A : get_step(A, 0)?.loc) +//Misc text define. Does 4 spaces. Used as a makeshift tabulator. +#define FOURSPACES "    " + //https://secure.byond.com/docs/ref/info.html#/atom/var/mouse_opacity #define MOUSE_OPACITY_TRANSPARENT 0 #define MOUSE_OPACITY_ICON 1 diff --git a/code/__DEFINES/subsystem.dm b/code/__DEFINES/subsystem.dm index 9febd392c513..df3c6e768e30 100644 --- a/code/__DEFINES/subsystem.dm +++ b/code/__DEFINES/subsystem.dm @@ -51,30 +51,31 @@ #define SS_INIT_TICKER_SPAWN 999 #define SS_INIT_RUST 26 #define SS_INIT_SUPPLY_SHUTTLE 25 -#define SS_INIT_GARBAGE 23 -#define SS_INIT_JOB 22 +#define SS_INIT_GARBAGE 24 +#define SS_INIT_JOB 23 +#define SS_INIT_MAPPING 22 #define SS_INIT_PLANT 21.5 #define SS_INIT_HUMANS 21 #define SS_INIT_MAP 20 #define SS_INIT_COMPONENT 19.5 #define SS_INIT_POWER 19 #define SS_INIT_OBJECT 18 -#define SS_INIT_DECORATOR 17.9 #define SS_INIT_PIPENET 17.5 #define SS_INIT_XENOARCH 17 #define SS_INIT_MORE_INIT 16 #define SS_INIT_AIR 15 -#define SS_INIT_SHUTTLE 14 #define SS_INIT_TELEPORTER 13 #define SS_INIT_LIGHTING 12 -#define SS_INIT_LANDMARK 11 #define SS_INIT_DEFCON 9 #define SS_INIT_LAW 6 #define SS_INIT_FZ_TRANSITIONS 5 #define SS_INIT_ATOMS 4 +#define SS_INIT_DECORATOR 3.7 +#define SS_INIT_SHUTTLE 3.5 +#define SS_INIT_LANDMARK 3.2 #define SS_INIT_MACHINES 3 #define SS_INIT_RADIO 2 -#define SS_INIT_TIMER 1 +#define SS_INIT_TIMER 100 #define SS_INIT_UNSPECIFIED 0 #define SS_INIT_EMERGENCY_SHUTTLE -19 #define SS_INIT_ASSETS -20 diff --git a/code/__DEFINES/turf_flags.dm b/code/__DEFINES/turf_flags.dm new file mode 100644 index 000000000000..4cf9e4d243b7 --- /dev/null +++ b/code/__DEFINES/turf_flags.dm @@ -0,0 +1,6 @@ +#define CHANGETURF_DEFER_CHANGE (1<<0) +#define CHANGETURF_IGNORE_AIR (1<<1) // This flag prevents changeturf from gathering air from nearby turfs to fill the new turf with an approximation of local air +#define CHANGETURF_FORCEOP (1<<2) +#define CHANGETURF_SKIP (1<<3) // A flag for PlaceOnTop to just instance the new turf instead of calling ChangeTurf. Used for uninitialized turfs NOTHING ELSE + +#define IS_OPAQUE_TURF(turf) (turf.directional_opacity == ALL_CARDINALS) diff --git a/code/__HELPERS/level_traits.dm b/code/__HELPERS/level_traits.dm index 6bd1a7bcc9b2..0e565e46672f 100644 --- a/code/__HELPERS/level_traits.dm +++ b/code/__HELPERS/level_traits.dm @@ -1,31 +1,12 @@ -// placeholders -#define ZTRAIT_GROUND 1 -#define ZTRAIT_ADMIN 2 -#define ZTRAIT_MARINE_MAIN_SHIP 3 -#define ZTRAIT_LOWORBITT 4 -#define ZTRAIT_HUNTER_SHIP 5 -#define is_admin_level(z) (z == ZTRAIT_ADMIN) +#define is_admin_level(z) SSmapping.level_trait(z, ZTRAIT_ADMIN) -#define is_ground_level(z) (z == ZTRAIT_GROUND) +#define is_ground_level(z) SSmapping.level_trait(z, ZTRAIT_GROUND) -#define is_mainship_level(z) (z == ZTRAIT_MARINE_MAIN_SHIP) +#define is_mainship_level(z) SSmapping.level_trait(z, ZTRAIT_MARINE_MAIN_SHIP) -#define is_loworbit_level(z) (z == ZTRAIT_LOWORBITT) +#define is_loworbit_level(z) SSmapping.level_trait(z, ZTRAIT_LOWORBIT) -#define is_huntership_level(z) (z == ZTRAIT_HUNTER_SHIP) - -// extremely placeholder -GLOBAL_REAL(SSmapping, /datum/mapping_placeholder) = new - -/datum/mapping_placeholder - -/datum/mapping_placeholder/proc/levels_by_trait(trait) - RETURN_TYPE(/list) - return list(trait) - -/datum/mapping_placeholder/proc/levels_by_any_trait(list/traits) - RETURN_TYPE(/list) - return traits +#define is_huntership_level(z) SSmapping.level_trait(z, ZTRAIT_HUNTER_SHIP) #define OBJECTS_CAN_REACH(Oa, Ob) (!(is_admin_level(Oa.z) || is_admin_level(Ob.z)) || Oa.z == Ob.z) diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index 642d461f91f5..36b4a7a805bb 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -570,3 +570,12 @@ proc/listclearnulls(list/list) right.Cut(1,2) return result + +/proc/typecache_filter_list_reverse(list/atoms, list/typecache) + RETURN_TYPE(/list) + . = list() + for(var/thing in atoms) + var/atom/A = thing + if(!typecache[A.type]) + . += A + diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 3b53e6b3b4f8..d36ecb6be604 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1153,16 +1153,22 @@ var/global/image/action_blue_power_up //Takes: Area type as text string or as typepath OR an instance of the area. //Returns: A list of all turfs in areas of that type of that type in the world. -/proc/get_area_turfs(var/areatype) - if(!areatype) return null +/proc/get_area_turfs(areatype) + if(!areatype) + return + + if(istext(areatype)) + areatype = text2path(areatype) + if(isarea(areatype)) var/area/areatemp = areatype areatype = areatemp.type - var/list/turfs = new/list() - for(var/area/N in all_areas) - if(istype(N, areatype)) - for(var/turf/T in N) turfs += T + var/list/turfs = list() + var/area/A = GLOB.areas_by_type[areatype] + for(var/turf/T in A) + turfs += T + return turfs /datum/coords //Simple datum for storing coordinates. @@ -1562,7 +1568,7 @@ var/list/WALLITEMS = list( var/turf/T = get_turf(G) if(!(T.loc.type in grenade_antigrief_exempt_areas)) var/crash_occured = (SSticker?.mode?.is_in_endgame) - if(G.harmful && (T.z in SSmapping.levels_by_any_trait(list(ZTRAIT_MARINE_MAIN_SHIP, ZTRAIT_LOWORBITT))) && (security_level < SEC_LEVEL_RED) && !crash_occured && grenade_antigrief_on) + if(G.harmful && (T.z in SSmapping.levels_by_any_trait(list(ZTRAIT_MARINE_MAIN_SHIP, ZTRAIT_LOWORBIT))) && (security_level < SEC_LEVEL_RED) && !crash_occured && grenade_antigrief_on) return TRUE return FALSE @@ -1743,3 +1749,25 @@ var/list/WALLITEMS = list( if(istype(D)) return !QDELETED(D) return FALSE + +//Repopulates sortedAreas list +/proc/repopulate_sorted_areas() + GLOB.sorted_areas = list() + + for(var/area/A in world) + GLOB.sorted_areas.Add(A) + + sortTim(GLOB.sorted_areas, /proc/cmp_name_asc) + +/atom/proc/GetAllContentsIgnoring(list/ignore_typecache) + if(!length(ignore_typecache)) + return GetAllContents() + var/list/processing = list(src) + var/list/assembled = list() + while(processing.len) + var/atom/A = processing[1] + processing.Cut(1,2) + if(!ignore_typecache[A.type]) + processing += A.contents + assembled += A + return assembled diff --git a/code/_globalvars/global_lists.dm b/code/_globalvars/global_lists.dm index c5ea676ab808..be8f9aaa9c17 100644 --- a/code/_globalvars/global_lists.dm +++ b/code/_globalvars/global_lists.dm @@ -12,10 +12,6 @@ var/list/DEFAULT_NEXT_MAP_CANDIDATES = list(MAP_LV_624, MAP_BIG_RED, MAP_WHISKEY var/list/LOWPOP_NEXT_MAP_CANDIDATES = list(MAP_LV_624, MAP_BIG_RED, MAP_PRISON_STATION, MAP_KUTJEVO) var/list/NOTVOTABLE_MAPS = list(MAP_WHISKEY_OUTPOST, MAP_ICE_COLONY) var/list/NEXT_MAP_CANDIDATES = DEFAULT_NEXT_MAP_CANDIDATES.Copy() - NOTVOTABLE_MAPS -var/list/MAPS_COLD_TEMP = list(MAP_ICE_COLONY, MAP_SOROKYNE_STRATA, MAP_CORSAT) - -//List of player votes. Name of the map from NEXT_MAP_CANDIADATES indexed by ckey -var/list/player_votes = list() // Global lists of the HUDs var/global/list/custom_huds_list = list("midnight" = new /datum/custom_hud(), diff --git a/code/_globalvars/lists/mapping_globals.dm b/code/_globalvars/lists/mapping_globals.dm index 8b284b744a9a..70140dfb57eb 100644 --- a/code/_globalvars/lists/mapping_globals.dm +++ b/code/_globalvars/lists/mapping_globals.dm @@ -1,3 +1,11 @@ + +GLOBAL_LIST_EMPTY(sorted_areas) +/// An association from typepath to area instance. Only includes areas with `unique` set. +GLOBAL_LIST_EMPTY_TYPED(areas_by_type, /area) + +GLOBAL_DATUM(supply_elevator, /turf) +GLOBAL_DATUM(vehicle_elevator, /turf) + GLOBAL_LIST_EMPTY(spawns_by_job) GLOBAL_LIST_EMPTY(queen_spawns) GLOBAL_LIST_EMPTY(xeno_spawns) diff --git a/code/_macros.dm b/code/_macros.dm index 004a28a15873..e4798583f628 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -38,6 +38,7 @@ #define LAZYREMOVE(L, I) if(L) { L -= I; if(!length(L)) { L = null; } } // Adds I to L, initalizing L if necessary #define LAZYADD(L, I) if(!L) { L = list(); } L += I; +#define LAZYOR(L, I) if(!L) { L = list(); } L |= I; // Insert I into L at position X, initalizing L if necessary #define LAZYINSERT(L, I, X) if(!L) { L = list(); } L.Insert(X, I); // Adds I to L, initalizing L if necessary, if I is not already in L diff --git a/code/controllers/_DynamicAreaLighting_TG.dm b/code/controllers/_DynamicAreaLighting_TG.dm index 90a861f4eabb..0d5e514707d0 100644 --- a/code/controllers/_DynamicAreaLighting_TG.dm +++ b/code/controllers/_DynamicAreaLighting_TG.dm @@ -98,7 +98,7 @@ changed = 0 ls_remove_effect(src) ls_add_effect(src) - + return 0 /datum/light_source/proc/changed() @@ -123,19 +123,10 @@ // We may read it, but NEVER set it directly. var/directional_lum = 0 -//Turfs with opacity when they are constructed will trigger nearby lights to update -//Turfs and atoms with luminosity when they are constructed will create a light_source automatically -/turf/New() - ..() - if(luminosity) - if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.") - trueLuminosity = luminosity * luminosity - light = new(src) - //Movable atoms with opacity when they are constructed will trigger nearby lights to update //Movable atoms with luminosity when they are constructed will create a light_source automatically -/atom/movable/New() - ..() +/atom/movable/Initialize(mapload, ...) + . = ..() if(opacity) if(isturf(loc)) if(loc:lighting_lumcount > 1) @@ -377,4 +368,4 @@ #undef LIGHTING_MAX_LUMINOSITY_MOBILE #undef LIGHTING_MAX_LUMINOSITY_TURF #undef DIRECTIONAL_LUM_OFFSET -#undef DIRECTIONAL_LUM_MULT \ No newline at end of file +#undef DIRECTIONAL_LUM_MULT diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index ef17294a7d2d..4b3cb7932d4b 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -47,12 +47,72 @@ for(var/J in legacy_configs) LoadEntries(J) break + loadmaplist(CONFIG_GROUND_MAPS_FILE, GROUND_MAP) + loadmaplist(CONFIG_SHIP_MAPS_FILE, SHIP_MAP) LoadChatFilter() if(Master) Master.OnConfigLoad() +/datum/controller/configuration/proc/loadmaplist(filename, maptype) + log_config("Loading config file [filename]...") + filename = "[directory]/[filename]" + var/list/Lines = file2list(filename) + + var/datum/map_config/currentmap + for(var/t in Lines) + if(!t) + continue + + t = trim(t) + if(length(t) == 0) + continue + else if(copytext(t, 1, 2) == "#") + continue + + var/pos = findtext(t, " ") + var/command = null + var/data = null + + if(pos) + command = lowertext(copytext(t, 1, pos)) + data = copytext(t, pos + 1) + else + command = lowertext(t) + + if(!command) + continue + + if(!currentmap && command != "map") + continue + + switch(command) + if("map") + currentmap = load_map_config("maps/[data].json") + if(currentmap.defaulted) + log_config("Failed to load map config for [data]!") + currentmap = null + if("minplayers", "minplayer") + currentmap.config_min_users = text2num(data) + if("maxplayers", "maxplayer") + currentmap.config_max_users = text2num(data) + if("weight", "voteweight") + currentmap.voteweight = text2num(data) + if("default", "defaultmap") + LAZYINITLIST(defaultmaps) + defaultmaps[maptype] = currentmap + if("endmap") + LAZYINITLIST(maplist) + LAZYINITLIST(maplist[maptype]) + maplist[maptype][currentmap.map_name] = currentmap + currentmap = null + if("disabled") + currentmap = null + else + log_config("Unknown command in map vote config: '[command]'") + + /datum/controller/configuration/proc/full_wipe() if(IsAdminAdvancedProcCall()) return diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 12006556f023..f5b476f5f0a3 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -95,7 +95,7 @@ // START: CORSAT shuttle(s).. i mean monorails, what // Added by Fourkhan, 5/31/2019 - 6/7/19 - if (map_tag == MAP_CORSAT) + if (SSmapping.configs[GROUND_MAP].map_name) shuttle1 = new shuttle1.location = 0 shuttle1.warmup_time = SECONDS_10 @@ -383,6 +383,9 @@ shuttles["Transit 2"] = shuttle process_shuttles += shuttle + for(var/obj/structure/machinery/computer/shuttle_control/S in GLOB.shuttle_controls) + S.shuttle_datum = shuttles[S.shuttle_tag] + //This is called by gameticker after all the machines and radio frequencies have been properly initialized /datum/controller/shuttle_controller/proc/setup_shuttle_docks() diff --git a/code/controllers/subsystem/communications.dm b/code/controllers/subsystem/communications.dm index fc333fe0627d..931282269ed9 100644 --- a/code/controllers/subsystem/communications.dm +++ b/code/controllers/subsystem/communications.dm @@ -251,7 +251,7 @@ SUBSYSTEM_DEF(radio) target_zs += SSmapping.levels_by_trait(ZTRAIT_GROUND) if(tcomm_machines_almayer.len > 0) target_zs += SSmapping.levels_by_trait(ZTRAIT_MARINE_MAIN_SHIP) - target_zs += SSmapping.levels_by_trait(ZTRAIT_LOWORBITT) + target_zs += SSmapping.levels_by_trait(ZTRAIT_LOWORBIT) return target_zs /datum/controller/subsystem/radio/proc/add_tcomm_machine(var/obj/machine) diff --git a/code/controllers/subsystem/decorator.dm b/code/controllers/subsystem/decorator.dm index d01412f5ca82..9c2db22316cf 100644 --- a/code/controllers/subsystem/decorator.dm +++ b/code/controllers/subsystem/decorator.dm @@ -1,15 +1,16 @@ // our atom declaration should not be hardcoded for this SS existance. // if this subsystem is deleted, stuff still works // That's why we define this here -/atom/Decorate() - if(SSdecorator && SSdecorator.registered_decorators[type]) +/atom/proc/Decorate() + if(SSdecorator.registered_decorators[type]) SSdecorator.decorate(src) + flags_atom |= ATOM_DECORATED SUBSYSTEM_DEF(decorator) - name = "Decorator" - init_order = SS_INIT_DECORATOR - priority = SS_PRIORITY_DECORATOR - flags = SS_NO_FIRE + name = "Decorator" + init_order = SS_INIT_DECORATOR + priority = SS_PRIORITY_DECORATOR + flags = SS_NO_FIRE can_fire = FALSE @@ -37,7 +38,8 @@ SUBSYSTEM_DEF(decorator) registered_decorators[i] = sortDecorators(registered_decorators[i]) for(var/atom/object in world) - object.Decorate() + if(!(object.flags_atom & ATOM_DECORATED)) + object.Decorate() CHECK_TICK return ..() diff --git a/code/controllers/subsystem/init/mapview.dm b/code/controllers/subsystem/init/mapview.dm deleted file mode 100644 index 96826f8b3dfc..000000000000 --- a/code/controllers/subsystem/init/mapview.dm +++ /dev/null @@ -1,8 +0,0 @@ -SUBSYSTEM_DEF(mapview_init) - name = "Mapview Init" - init_order = SS_INIT_MAPVIEW - flags = SS_NO_FIRE - -/datum/controller/subsystem/mapview_init/Initialize() - generate_marine_mapview() - return ..() diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm new file mode 100644 index 000000000000..adc1483b8378 --- /dev/null +++ b/code/controllers/subsystem/mapping.dm @@ -0,0 +1,300 @@ +SUBSYSTEM_DEF(mapping) + name = "Mapping" + init_order = SS_INIT_MAPPING + flags = SS_NO_FIRE + + var/list/datum/map_config/configs + var/list/datum/map_config/next_map_configs + + var/list/map_templates = list() + + var/list/areas_in_z = list() + + var/list/turf/unused_turfs = list() //Not actually unused turfs they're unused but reserved for use for whatever requests them. "[zlevel_of_turf]" = list(turfs) + var/list/datum/turf_reservations //list of turf reservations + var/list/used_turfs = list() //list of turf = datum/turf_reservation + + var/list/reservation_ready = list() + var/clearing_reserved_turfs = FALSE + + // Z-manager stuff + var/ground_start // should only be used for maploading-related tasks + var/list/z_list + var/datum/space_level/transit + var/num_of_res_levels = 1 + +//dlete dis once #39770 is resolved +/datum/controller/subsystem/mapping/proc/HACK_LoadMapConfig() + if(!configs) + configs = load_map_configs(ALL_MAPTYPES, error_if_missing = FALSE) + for(var/i in GLOB.clients) + var/client/C = i + winset(C, null, "mainwindow.title='[CONFIG_GET(string/title)] - [SSmapping.configs[SHIP_MAP].map_name]'") + +/datum/controller/subsystem/mapping/Initialize(timeofday) + HACK_LoadMapConfig() + if(initialized) + return + + for(var/i in ALL_MAPTYPES) + var/datum/map_config/MC = configs[i] + if(MC.defaulted) + var/old_config = configs[i] + configs[i] = global.config.defaultmaps[i] + if(!configs || configs[i].defaulted) + to_chat(world, "Unable to load next or default map config, defaulting.") + configs[i] = old_config + + if(configs[GROUND_MAP]) + for(var/i in config.votable_modes) + if(!(i in configs[GROUND_MAP].gamemodes)) + config.votable_modes -= i // remove invalid modes + + loadWorld() + repopulate_sorted_areas() + preloadTemplates() + // Add the transit level + transit = add_new_zlevel("Transit/Reserved", list(ZTRAIT_RESERVED = TRUE)) + initialize_reserved_level(transit.z_value) + GLOB.interior_manager = new + repopulate_sorted_areas() + return ..() + +/datum/controller/subsystem/mapping/proc/wipe_reservations(wipe_safety_delay = 100) + if(clearing_reserved_turfs || !initialized) //in either case this is just not needed. + return + clearing_reserved_turfs = TRUE + message_admins("Clearing dynamic reservation space.") + do_wipe_turf_reservations() + clearing_reserved_turfs = FALSE + +/datum/controller/subsystem/mapping/Recover() + flags |= SS_NO_INIT + initialized = SSmapping.initialized + map_templates = SSmapping.map_templates + unused_turfs = SSmapping.unused_turfs + turf_reservations = SSmapping.turf_reservations + used_turfs = SSmapping.used_turfs + + configs = SSmapping.configs + next_map_configs = SSmapping.next_map_configs + + clearing_reserved_turfs = SSmapping.clearing_reserved_turfs + + z_list = SSmapping.z_list + +#define INIT_ANNOUNCE(X) to_chat(world, "[X]"); log_world(X) +/datum/controller/subsystem/mapping/proc/LoadGroup(list/errorList, name, path, files, list/traits, list/default_traits, silent = FALSE) + . = list() + var/start_time = REALTIMEOFDAY + + if (!islist(files)) // handle single-level maps + files = list(files) + + // check that the total z count of all maps matches the list of traits + var/total_z = 0 + var/list/parsed_maps = list() + for (var/file in files) + var/full_path = "maps/[path]/[file]" + var/datum/parsed_map/pm = new(file(full_path)) + var/bounds = pm?.bounds + if (!bounds) + errorList |= full_path + continue + parsed_maps[pm] = total_z // save the start Z of this file + total_z += bounds[MAP_MAXZ] - bounds[MAP_MINZ] + 1 + + if (!length(traits)) // null or empty - default + for (var/i in 1 to total_z) + traits += list(default_traits) + else if (total_z != traits.len) // mismatch + INIT_ANNOUNCE("WARNING: [traits.len] trait sets specified for [total_z] z-levels in [path]!") + if (total_z < traits.len) // ignore extra traits + traits.Cut(total_z + 1) + while (total_z > traits.len) // fall back to defaults on extra levels + traits += list(default_traits) + + // preload the relevant space_level datums + var/start_z = world.maxz + 1 + var/i = 0 + for (var/level in traits) + add_new_zlevel("[name][i ? " [i + 1]" : ""]", level) + ++i + + // load the maps + for (var/P in parsed_maps) + var/datum/parsed_map/pm = P + if (!pm.load(1, 1, start_z + parsed_maps[P], no_changeturf = TRUE)) + errorList |= pm.original_path + if(!silent) + INIT_ANNOUNCE("Loaded [name] in [(REALTIMEOFDAY - start_time)/10]s!") + return parsed_maps + +/datum/controller/subsystem/mapping/proc/Loadship(list/errorList, name, path, files, list/traits, list/default_traits, silent = FALSE) + LoadGroup(errorList, name, path, files, traits, default_traits, silent) + +/datum/controller/subsystem/mapping/proc/Loadground(list/errorList, name, path, files, list/traits, list/default_traits, silent = FALSE) + LoadGroup(errorList, name, path, files, traits, default_traits, silent) + +/datum/controller/subsystem/mapping/proc/loadWorld() + //if any of these fail, something has gone horribly, HORRIBLY, wrong + var/list/FailedZs = list() + + // ensure we have space_level datums for compiled-in maps + InitializeDefaultZLevels() + + // load the ground level + ground_start = world.maxz + 1 + + var/datum/map_config/ground_map = configs[GROUND_MAP] + INIT_ANNOUNCE("Loading [ground_map.map_name]...") + Loadground(FailedZs, ground_map.map_name, ground_map.map_path, ground_map.map_file, ground_map.traits, ZTRAITS_GROUND) + + var/datum/map_config/ship_map = configs[SHIP_MAP] + INIT_ANNOUNCE("Loading [ship_map.map_name]...") + Loadship(FailedZs, ship_map.map_name, ship_map.map_path, ship_map.map_file, ship_map.traits, ZTRAITS_MAIN_SHIP) + + if(LAZYLEN(FailedZs)) //but seriously, unless the server's filesystem is messed up this will never happen + var/msg = "RED ALERT! The following map files failed to load: [FailedZs[1]]" + if(FailedZs.len > 1) + for(var/I in 2 to FailedZs.len) + msg += ", [FailedZs[I]]" + msg += ". Yell at your server host!" + INIT_ANNOUNCE(msg) +#undef INIT_ANNOUNCE + +/datum/controller/subsystem/mapping/proc/changemap(datum/map_config/VM, maptype = GROUND_MAP) + LAZYINITLIST(next_map_configs) + if(maptype == GROUND_MAP) + if(!VM.MakeNextMap(maptype)) + next_map_configs[GROUND_MAP] = load_map_configs(list(maptype), default = TRUE) + message_admins("Failed to set new map with next_map.json for [VM.map_name]! Using default as backup!") + return + + next_map_configs[GROUND_MAP] = VM + return TRUE + + else if(maptype == SHIP_MAP) + if(!VM.MakeNextMap(maptype)) + next_map_configs[SHIP_MAP] = load_map_configs(list(maptype), default = TRUE) + message_admins("Failed to set new map with next_map.json for [VM.map_name]! Using default as backup!") + return + + next_map_configs[SHIP_MAP] = VM + return TRUE + +/datum/controller/subsystem/mapping/proc/preloadTemplates(path = "maps/templates/") //see master controller setup + var/list/filelist = flist(path) + for(var/map in filelist) + var/datum/map_template/T = new(path = "[path][map]", rename = "[map]") + map_templates[T.name] = T + +/proc/generateMapList(filename) + . = list() + var/list/Lines = file2list(filename) + + if(!Lines.len) + return + for (var/t in Lines) + if (!t) + continue + + t = trim(t) + if (length(t) == 0) + continue + else if (t[1] == "#") + continue + + var/pos = findtext(t, " ") + var/name = null + + if (pos) + name = lowertext(copytext(t, 1, pos)) + + else + name = lowertext(t) + + if (!name) + continue + + . += t + +/datum/controller/subsystem/mapping/proc/RequestBlockReservation(width, height, z, type = /datum/turf_reservation, turf_type_override) + UNTIL(initialized && !clearing_reserved_turfs) + var/datum/turf_reservation/reserve = new type + if(turf_type_override) + reserve.turf_type = turf_type_override + if(!z) + for(var/i in levels_by_trait(ZTRAIT_RESERVED)) + if(reserve.Reserve(width, height, i)) + return reserve + //If we didn't return at this point, theres a good chance we ran out of room on the exisiting reserved z levels, so lets try a new one + log_debug("Ran out of space in existing transit levels, adding a new one") + num_of_res_levels += 1 + var/datum/space_level/newReserved = add_new_zlevel("Transit/Reserved [num_of_res_levels]", list(ZTRAIT_RESERVED = TRUE)) + initialize_reserved_level(newReserved.z_value) + for(var/i in levels_by_trait(ZTRAIT_RESERVED)) + if(reserve.Reserve(width, height, i)) + return reserve + CRASH("Despite adding a fresh reserved zlevel still failed to get a reservation") + else + if(!level_trait(z, ZTRAIT_RESERVED)) + log_debug("Cannot block reserve on a non-ZTRAIT_RESERVED level") + qdel(reserve) + return + else + if(reserve.Reserve(width, height, z)) + return reserve + log_debug("unknown reservation failure") + QDEL_NULL(reserve) + +//This is not for wiping reserved levels, use wipe_reservations() for that. +/datum/controller/subsystem/mapping/proc/initialize_reserved_level(z) + UNTIL(!clearing_reserved_turfs) //regardless, lets add a check just in case. + clearing_reserved_turfs = TRUE //This operation will likely clear any existing reservations, so lets make sure nothing tries to make one while we're doing it. + if(!level_trait(z,ZTRAIT_RESERVED)) + clearing_reserved_turfs = FALSE + CRASH("Invalid z level prepared for reservations.") + var/turf/A = get_turf(locate(8,8,z)) + var/turf/B = get_turf(locate(world.maxx - 8,world.maxy - 8,z)) + var/block = block(A, B) + for(var/t in block) + // No need to empty() these, because it's world init and they're + // already /turf/open/space/basic. + var/turf/T = t + T.flags_atom |= UNUSED_RESERVATION_TURF_1 + unused_turfs["[z]"] = block + reservation_ready["[z]"] = TRUE + clearing_reserved_turfs = FALSE + +/datum/controller/subsystem/mapping/proc/reserve_turfs(list/turfs) + for(var/i in turfs) + var/turf/T = i + T.empty(RESERVED_TURF_TYPE, RESERVED_TURF_TYPE, null, TRUE) + LAZYINITLIST(unused_turfs["[T.z]"]) + unused_turfs["[T.z]"] |= T + T.flags_atom |= UNUSED_RESERVATION_TURF_1 + GLOB.areas_by_type[world.area].contents += T + CHECK_TICK + +//DO NOT CALL THIS PROC DIRECTLY, CALL wipe_reservations(). +/datum/controller/subsystem/mapping/proc/do_wipe_turf_reservations() + UNTIL(initialized) //This proc is for AFTER init, before init turf reservations won't even exist and using this will likely break things. + for(var/i in turf_reservations) + var/datum/turf_reservation/TR = i + if(!QDELETED(TR)) + qdel(TR, TRUE) + UNSETEMPTY(turf_reservations) + var/list/clearing = list() + for(var/l in unused_turfs) //unused_turfs is a assoc list by z = list(turfs) + if(islist(unused_turfs[l])) + clearing |= unused_turfs[l] + clearing |= used_turfs //used turfs is an associative list, BUT, reserve_turfs() can still handle it. If the code above works properly, this won't even be needed as the turfs would be freed already. + unused_turfs.Cut() + used_turfs.Cut() + reserve_turfs(clearing) + +/datum/controller/subsystem/mapping/proc/reg_in_areas_in_z(list/areas) + for(var/B in areas) + var/area/A = B + A.reg_in_areas_in_z() diff --git a/code/controllers/subsystem/mapview.dm b/code/controllers/subsystem/mapview.dm index ae1dce8ac2ec..8df92dace162 100644 --- a/code/controllers/subsystem/mapview.dm +++ b/code/controllers/subsystem/mapview.dm @@ -4,9 +4,11 @@ SUBSYSTEM_DEF(mapview) wait = 2 SECONDS flags = SS_KEEP_TIMING | SS_DISABLE_FOR_TESTING priority = SS_PRIORITY_MAPVIEW + init_order = SS_INIT_MAPVIEW var/list/map_machines /datum/controller/subsystem/mapview/Initialize(start_timeofday) + generate_marine_mapview() create_map_machines() return ..() diff --git a/code/controllers/subsystem/objectives_controller.dm b/code/controllers/subsystem/objectives_controller.dm index aaae719e9ec1..d46ecd6d1538 100644 --- a/code/controllers/subsystem/objectives_controller.dm +++ b/code/controllers/subsystem/objectives_controller.dm @@ -57,11 +57,10 @@ SUBSYSTEM_DEF(objectives) var/vial_boxes = 20 //A stub of tweaking item spawns based on map - switch(map_tag) - if(MAP_CORSAT) - vial_boxes = 30 - research_papers = 30 - experimental_devices = 20 + if(SSmapping.configs[GROUND_MAP].map_name == MAP_CORSAT) + vial_boxes = 30 + research_papers = 30 + experimental_devices = 20 //Calculating document ratios so we don't end up with filing cabinets holding 10 documents because there are few filing cabinets var/relative_document_ratio_close = objective_spawn_close_documents.len / objective_spawn_close.len @@ -111,15 +110,16 @@ SUBSYSTEM_DEF(objectives) var/obj/effect/landmark/corpsespawner/spawnpoint for(var/i = 0 to corpses) - spawnpoint = pick(objective_spawn_corpse) + spawnpoint = pick_n_take(objective_spawn_corpse) //Creates a mob and checks for gear in each slot before attempting to equip it. var/mob/living/carbon/human/M = new /mob/living/carbon/human(spawnpoint.loc) M.create_hud() //Need to generate hud before we can equip anything apparently... arm_equipment(M, "Corpse - [spawnpoint.name]", TRUE, FALSE) - LAZYREMOVE(objective_spawn_corpse, spawnpoint) qdel(spawnpoint) + if(!length(objective_spawn_corpse)) + break for(var/obj/effect/landmark/corpsespawner/C in objective_spawn_corpse) qdel(C) diff --git a/code/controllers/subsystem/perf_logging.dm b/code/controllers/subsystem/perf_logging.dm index 86935c20c28f..ed49172dc671 100644 --- a/code/controllers/subsystem/perf_logging.dm +++ b/code/controllers/subsystem/perf_logging.dm @@ -23,7 +23,7 @@ SUBSYSTEM_DEF(perf_logging) while(!SSentity_manager.ready) stoplag() round = SSentity_manager.select(/datum/entity/mc_round) - round.map_name = "[map_tag]" + round.map_name = SSmapping.configs[GROUND_MAP].map_name round.save() round.sync() if(!Master) diff --git a/code/controllers/subsystem/sound.dm b/code/controllers/subsystem/sound.dm index 7f03654b6018..17a7650597fb 100644 --- a/code/controllers/subsystem/sound.dm +++ b/code/controllers/subsystem/sound.dm @@ -6,7 +6,7 @@ SUBSYSTEM_DEF(sound) runlevels = RUNLEVELS_DEFAULT|RUNLEVEL_LOBBY var/list/template_queue = list() // Full Template Queue - var/list/run_queue = list() // Queue subset being processed during this tick + var/list/run_queue = list() // Queue subset being processed during this tick var/list/run_hearers = null // Hearers for currently being processed template /datum/controller/subsystem/sound/fire(resumed = FALSE) @@ -36,10 +36,10 @@ SUBSYSTEM_DEF(sound) /datum/controller/subsystem/sound/proc/queue(datum/sound_template/template, var/list/client/hearers, list/datum/interior/extra_interiors) if(!hearers) hearers = list() - if(extra_interiors && interior_manager) + if(extra_interiors && GLOB.interior_manager) for(var/datum/interior/VI in extra_interiors) if(VI?.ready && VI?.chunk_id) - var/list/bounds = interior_manager.get_chunk_coords(VI.chunk_id) + var/list/bounds = GLOB.interior_manager.get_chunk_coords(VI.chunk_id) if(bounds.len >= 2) - hearers |= SSquadtree.players_in_range(RECT(bounds[1], bounds[2], interior_manager.chunk_size, interior_manager.chunk_size), interior_manager.interior_z) - template_queue[template] = hearers \ No newline at end of file + hearers |= SSquadtree.players_in_range(RECT(bounds[1], bounds[2], GLOB.interior_manager.chunk_size, GLOB.interior_manager.chunk_size), GLOB.interior_manager.interior_z) + template_queue[template] = hearers diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 257c06bc718d..b806a4b2c503 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -11,11 +11,13 @@ SUBSYSTEM_DEF(statpanels) /datum/controller/subsystem/statpanels/fire(resumed = FALSE) if (!resumed) -// var/datum/map_config/cached = SSmapping.next_map_config + var/datum/map_config/cached + if(SSmapping.next_map_configs) + cached = SSmapping.next_map_configs[GROUND_MAP] // var/round_time = world.time - SSticker.round_start_time var/list/global_data = list( -// "Map: [SSmapping.config?.map_name || "Loading..."]", -// cached ? "Next Map: [cached.map_name]" : null, + "Map: [SSmapping.configs[GROUND_MAP]?.map_name || "Loading..."]", + cached ? "Next Map: [cached?.map_name]" : null, // "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]", "Round Time: [duration2text()]", diff --git a/code/controllers/subsystem/teleporter.dm b/code/controllers/subsystem/teleporter.dm index 40a87862a257..858c2c7494f1 100644 --- a/code/controllers/subsystem/teleporter.dm +++ b/code/controllers/subsystem/teleporter.dm @@ -13,7 +13,7 @@ SUBSYSTEM_DEF(teleporter) //Corsat_Teleporter /datum/controller/subsystem/teleporter/Initialize() - if (map_tag != MAP_CORSAT) // Bad style, but I'm leaving it here for now until someone wants to add a teleporter to another map + if (SSmapping.configs[GROUND_MAP].map_name != MAP_CORSAT) // Bad style, but I'm leaving it here for now until someone wants to add a teleporter to another map return teleporters_by_id = list() diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 91ccf73bbdb6..9b221e9b04ee 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -110,6 +110,7 @@ SUBSYSTEM_DEF(ticker) current_state = GAME_STATE_FINISHED ooc_allowed = TRUE mode.declare_completion(force_ending) + addtimer(CALLBACK(SSvote, /datum/controller/subsystem/vote.proc/initiate_vote, "groundmap", "SERVER"), 3 SECONDS) addtimer(CALLBACK(src, .proc/Reboot), 63 SECONDS) Master.SetRunLevel(RUNLEVEL_POSTGAME) @@ -173,7 +174,6 @@ SUBSYSTEM_DEF(ticker) for(var/mob/new_player/np in GLOB.new_player_list) np.new_player_panel_proc(TRUE) - run_mapdaemon_batch() begin_game_recording() if((master_mode == "Distress Signal") && SSevents) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index dab9bd739d0f..4d836661c484 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -1,10 +1,411 @@ SUBSYSTEM_DEF(vote) - name = "Vote" - flags = SS_NO_INIT - wait = 1 SECONDS - priority = SS_PRIORITY_VOTE - flags = SS_KEEP_TIMING | SS_DISABLE_FOR_TESTING - runlevels = RUNLEVELS_DEFAULT|RUNLEVEL_LOBBY - -/datum/controller/subsystem/vote/fire(resumed = FALSE) - vote.process() + name = "Vote" + wait = 10 + + flags = SS_KEEP_TIMING|SS_NO_INIT + + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + + var/initiator = null + var/started_time = null + var/time_remaining = 0 + var/mode = null + var/question = null + var/list/choices = list() + var/list/voted = list() + var/list/voting = list() + + // mapvotes carryover + var/list/datum/entity/map_vote/votes + +/datum/controller/subsystem/vote/fire() + if(mode) + time_remaining = round((started_time + CONFIG_GET(number/vote_period) - world.time)/10) + + if(time_remaining < 0) + result() + for(var/client/C in voting) + C << browse(null, "window=vote") + reset() + else + var/datum/browser/client_popup + for(var/client/C in voting) + client_popup = new(C, "vote", "Voting Panel") + client_popup.set_window_options("can_close=0") + client_popup.set_content(interface(C)) + client_popup.open(FALSE) + + +/datum/controller/subsystem/vote/proc/reset() + initiator = null + time_remaining = 0 + mode = null + question = null + choices.Cut() + voted.Cut() + voting.Cut() + remove_action_buttons() + + +/datum/controller/subsystem/vote/proc/get_result() + var/greatest_votes = 0 + var/total_votes = 0 + for(var/option in choices) + var/votes = choices[option] + total_votes += votes + if(votes > greatest_votes) + greatest_votes = votes + if(!CONFIG_GET(flag/default_no_vote) && length(choices)) + var/list/non_voters = GLOB.directory.Copy() + non_voters -= voted + for (var/non_voter_ckey in non_voters) + var/client/C = non_voters[non_voter_ckey] + if(!C || C.is_afk()) + non_voters -= non_voter_ckey + if(length(non_voters) > 0) + if(mode == "restart") + choices["Continue Playing"] += length(non_voters) + if(choices["Continue Playing"] >= greatest_votes) + greatest_votes = choices["Continue Playing"] + . = list() + if(greatest_votes) + for(var/option in choices) + if(choices[option] == greatest_votes) + . += option + return . + + +/datum/controller/subsystem/vote/proc/announce_result() + var/list/winners = get_result() + var/text + if(length(winners) > 0) + if(question) + text += "[question]" + else + text += "[capitalize(mode)] Vote" + for(var/i = 1 to length(choices)) + var/votes = choices[choices[i]] + if(!votes) + votes = 0 + text += "
[choices[i]]: [votes]" + if(mode != "custom") + if(length(winners) > 1) + text = "
Vote Tied Between:" + for(var/option in winners) + text += "
[FOURSPACES][option]" + . = pick(winners) + text += "
Vote Result: [.]" + else + text += "
Did not vote: [length(GLOB.clients) - length(voted)]" + else + text += "Vote Result: Inconclusive - No Votes!" + log_vote(text) + remove_action_buttons() + to_chat(world, "
[text]") + return . + + +/datum/controller/subsystem/vote/proc/result() + . = announce_result() + var/restart = FALSE + if(.) + switch(mode) + if("restart") + if(. == "Restart Round") + restart = TRUE + if("groundmap") + var/datum/map_config/VM = config.maplist[GROUND_MAP][.] + SSmapping.changemap(VM, GROUND_MAP) + for(var/datum/entity/map_vote/in_vote in votes) + if(!isnull(choices[in_vote.map_name])) + in_vote.total_votes = (. == in_vote.map_name) ? 0 : choices[in_vote.map_name] + in_vote.save() + if("shipmap") + var/datum/map_config/VM = config.maplist[SHIP_MAP][.] + SSmapping.changemap(VM, SHIP_MAP) + if(restart) + var/active_admins = 0 + for(var/client/C in GLOB.admins) + if(!C.is_afk() && check_rights(R_SERVER)) + active_admins = TRUE + break + if(!active_admins) + world.Reboot("Restart vote successful.") + else + to_chat(world, "Notice:Restart vote will not restart the server automatically because there are active admins on.") + message_admins("A restart vote has passed, but there are active admins on with +SERVER, so it has been canceled. If you wish, you may restart the server.") + + return . + + +/datum/controller/subsystem/vote/proc/submit_vote(vote) + if(mode) + if(CONFIG_GET(flag/no_dead_vote) && usr.stat == DEAD && !check_rights(R_ADMIN)) + return FALSE + if(!(usr.ckey in voted)) + if(vote && 1 <= vote && vote <= length(choices)) + voted += usr.ckey + choices[choices[vote]]++ + return vote + return FALSE + + +/datum/controller/subsystem/vote/proc/carry_over_callback(list/datum/entity/map_vote/votes) + src.votes = votes + for(var/i in choices) + var/found = FALSE + var/datum/entity/map_vote/vote + for(var/datum/entity/map_vote/in_vote in votes) + if(in_vote.map_name == i) + found = TRUE + vote = in_vote + break + + if(!found) + vote = SSentity_manager.select(/datum/entity/map_vote) + vote.map_name = i + vote.total_votes = 0 + vote.save() + + choices[i] += vote.total_votes + +/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key) + if(!mode) + if(started_time) + var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay)) + if(mode) + to_chat(usr, "There is already a vote in progress! please wait for it to finish.") + return FALSE + + var/admin = FALSE + var/ckey = ckey(initiator_key) + if(initiator_key == "SERVER") + admin = TRUE + else + for(var/i in GLOB.admins) + var/client/C = i + if(C.ckey == ckey) + admin = TRUE + break + + if(next_allowed_time > world.time && !admin) + to_chat(usr, "A vote was initiated recently, you must wait [DisplayTimeText(next_allowed_time-world.time)] before a new vote can be started!") + return FALSE + + reset() + switch(vote_type) + if("restart") + choices.Add("Restart Round", "Continue Playing") + if("gamemode") + choices.Add(config.votable_modes) + if("groundmap") + var/list/maps = list() + for(var/i in config.maplist[GROUND_MAP]) + var/datum/map_config/VM = config.maplist[GROUND_MAP][i] + if(VM.map_file == SSmapping.configs[GROUND_MAP].map_file) + continue + if(!VM.voteweight) + continue + if(VM.config_max_users || VM.config_min_users) + var/players = length(GLOB.clients) + if(VM.config_max_users && players > VM.config_max_users) + continue + if(VM.config_min_users && players < VM.config_min_users) + continue + maps += i + + choices.Add(maps) + if(length(choices) < 2) + return FALSE + SSentity_manager.filter_then(/datum/entity/map_vote, null, CALLBACK(src, .proc/carry_over_callback)) + if("shipmap") + var/list/maps = list() + for(var/i in config.maplist[SHIP_MAP]) + var/datum/map_config/VM = config.maplist[SHIP_MAP][i] + if(!VM.voteweight) + continue + if(VM.config_max_users || VM.config_min_users) + var/players = length(GLOB.clients) + if(players > VM.config_max_users) + continue + if(players < VM.config_min_users) + continue + maps += i + choices.Add(maps) + if(length(choices) < 2) + return FALSE + if("custom") + question = stripped_input(usr, "What is the vote for?") + if(!question) + return FALSE + for(var/i = 1 to 10) + var/option = capitalize(stripped_input(usr, "Please enter an option or hit cancel to finish")) + if(!option || mode || !usr.client) + break + choices.Add(option) + else + return FALSE + mode = vote_type + initiator = initiator_key + started_time = world.time + var/text = "[capitalize(mode)] vote started by [initiator]." + if(mode == "custom") + text += "
[question]" + log_vote(text) + var/vp = CONFIG_GET(number/vote_period) + //SEND_SOUND(world, sound('sound/ambience/alarm4.ogg', channel = CHANNEL_NOTIFY)) + to_chat(world, "
[text]
Type vote or click here to place your votes.
You have [DisplayTimeText(vp)] to vote.
") + time_remaining = round(vp/10) + for(var/c in GLOB.clients) + var/client/C = c + var/datum/action/innate/vote/V = new + if(question) + V.name = "Vote: [question]" + C.player_details.player_actions += V + V.give_action(C.mob) + return TRUE + return FALSE + + +/datum/controller/subsystem/vote/proc/interface(client/C) + if(!C) + return + var/admin = FALSE + if(check_rights(R_ADMIN)) + admin = TRUE + voting |= C + + if(mode) + if(question) + . += "

Vote: '[question]'

" + else + . += "

Vote: [capitalize(mode)]

" + . += "Time Left: [time_remaining] s

" + if(admin) + . += "(Cancel Vote) " + else + . += "

Start a vote:



" + . += "Close" + return . + + +///datum/controller/subsystem/vote/can_interact(mob/user) // can_interact refactor TODO: +// return TRUE + + +/datum/controller/subsystem/vote/Topic(href, list/href_list, hsrc) + . = ..() + if(.) + return + + if(!usr?.client) + return + + switch(href_list["vote"]) + if("close") + voting -= usr.client + DIRECT_OUTPUT(usr, browse(null, "window=vote")) + return + if("cancel") + if(check_rights(R_ADMIN) && alert(usr, "Are you sure you want to cancel the vote?", "Cancel Vote", "Yes", "No") == "Yes") + reset() + to_chat(world, "The vote has been cancelled.") + if("toggle_restart") + if(check_rights(R_ADMIN)) + CONFIG_SET(flag/allow_vote_restart, !CONFIG_GET(flag/allow_vote_restart)) + if("toggle_gamemode") + if(check_rights(R_ADMIN)) + CONFIG_SET(flag/allow_vote_mode, !CONFIG_GET(flag/allow_vote_mode)) + if("restart") + if(CONFIG_GET(flag/allow_vote_restart) || check_rights(R_ADMIN)) + initiate_vote("restart", usr.key) + if("gamemode") + if(CONFIG_GET(flag/allow_vote_mode) || check_rights(R_ADMIN)) + initiate_vote("gamemode", usr.key) + if("custom") + if(check_rights(R_ADMIN)) + initiate_vote("custom", usr.key) + if("groundmap") + if(check_rights(R_ADMIN)) + initiate_vote("groundmap", usr.key) + if("shipmap") + if(check_rights(R_ADMIN)) + initiate_vote("shipmap", usr.key) + else + submit_vote(round(text2num(href_list["vote"]))) + usr.vote() + + +/mob/verb/vote() + set category = "OOC" + set name = "Vote" + + var/datum/browser/popup = new(src, "vote", "Voting Panel") + popup.set_window_options("can_close=0") + popup.set_content(SSvote.interface(client)) + popup.open(FALSE) + +/datum/controller/subsystem/vote/proc/remove_action_buttons() + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_REMOVE_VOTE_BUTTON) + +/datum/action/innate/vote + name = "Vote!" + action_icon_state = "vote" + +/datum/action/innate/vote/give_action(mob/M) + . = ..() + RegisterSignal(SSdcs, COMSIG_GLOB_REMOVE_VOTE_BUTTON, .proc/remove_vote_action) + +/datum/action/innate/vote/proc/remove_vote_action(datum/source) + SIGNAL_HANDLER + + if(remove_from_client()) + remove_action(owner) + qdel(src) + +/datum/action/innate/vote/action_activate() + owner.vote() + remove_vote_action() + +/datum/action/innate/vote/proc/remove_from_client() + if(!owner) + return FALSE + if(owner.client) + owner.client.player_details.player_actions -= src + else if(owner.ckey) + var/datum/player_details/P = GLOB.player_details[owner.ckey] + if(P) + P.player_actions -= src + return TRUE diff --git a/code/controllers/subsystem/weather.dm b/code/controllers/subsystem/weather.dm index 5230d28ab65f..e5bdf22d3dfe 100644 --- a/code/controllers/subsystem/weather.dm +++ b/code/controllers/subsystem/weather.dm @@ -34,9 +34,9 @@ SUBSYSTEM_DEF(weather) // Set up our map delegate datum for supported maps // The ONLY place where things should depend on map_tag // in the weather subsystem - switch(map_tag) - if (MAP_SOROKYNE_STRATA) - map_holder = new /datum/weather_ss_map_holder/sorokyne() + if(SSmapping.configs[GROUND_MAP].weather_holder) + var/weathertype = SSmapping.configs[GROUND_MAP].weather_holder + map_holder = new weathertype // Disable the weather subsystem on maps that don't currently implement it if (!map_holder) diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm deleted file mode 100644 index 9b9de5d54f69..000000000000 --- a/code/controllers/voting.dm +++ /dev/null @@ -1,468 +0,0 @@ -var/datum/controller/vote/vote = new() - -datum/controller/vote - var/initiator = null - var/started_time = null - var/time_remaining = 0 - var/mode = null - var/question = null - var/list/choices = list() - var/list/voted = list() - var/list/voting = list() - var/list/current_votes = list() - var/list/additional_text = list() - var/auto_muted = 0 - - New() - if(vote != src) - if(istype(vote)) - qdel(vote) - vote = src - - process() //called by master_controller - if(mode) - // No more change mode votes after the game has started. - // 3 is GAME_STATE_PLAYING, but that #define is undefined for some reason - if(mode == "gamemode" && SSticker.current_state >= GAME_STATE_SETTING_UP) - to_world("Voting aborted due to game start.") - src.reset() - return - - // Calculate how much time is remaining by comparing current time, to time of vote start, - // plus vote duration - time_remaining = round((started_time + CONFIG_GET(number/vote_period) - world.time)/10) - - if(time_remaining < 0) - result() - for(var/client/C in voting) - if(C) - close_browser(C,"vote") - reset() - else - for(var/client/C in voting) - if(C) - show_browser(C, vote.interface(C), "Vote", "vote", "can_close=0") - - voting.Cut() - - proc/autogamemode() - initiate_vote("gamemode","the server") - log_debug("The server has called a gamemode vote") - - proc/reset() - initiator = null - time_remaining = 0 - mode = null - question = null - choices.Cut() - voted.Cut() - voting.Cut() - current_votes.Cut() - additional_text.Cut() - - /* if(auto_muted && !ooc_allowed) - auto_muted = 0 - ooc_allowed = !( ooc_allowed ) - to_world("The OOC channel has been automatically enabled due to vote end.") - log_admin("OOC was toggled automatically due to vote end.") - message_admins("OOC has been toggled on automatically.") - */ - - proc/get_result() - //get the highest number of votes - var/greatest_votes = 0 - var/total_votes = 0 - for(var/option in choices) - var/votes = choices[option] - total_votes += votes - if(votes > greatest_votes) - greatest_votes = votes - //default-vote for everyone who didn't vote - if(!CONFIG_GET(flag/vote_no_default) && choices.len) - var/non_voters = (GLOB.clients.len - total_votes) - if(non_voters > 0) - if(mode == "restart") - choices["Continue Playing"] += non_voters - if(choices["Continue Playing"] >= greatest_votes) - greatest_votes = choices["Continue Playing"] - else if(mode == "gamemode") - if(choices[master_mode]) - choices[master_mode] += non_voters - if(choices[master_mode] >= greatest_votes) - greatest_votes = choices[master_mode] - - - //get all options with that many votes and return them in a list - . = list() - if(greatest_votes) - for(var/option in choices) - if(choices[option] == greatest_votes) - . += option - return . - - proc/announce_result() - var/list/winners = get_result() - var/text - if(winners.len > 0) - if(winners.len > 1) - if(mode != "gamemode") // Here we are making sure we don't announce potential game modes - text = "Vote Tied Between:\n" - for(var/option in winners) - text += "\t[option]\n" - . = pick(winners) - - if((mode == "gamemode" && . == "extended")) // Announce Extended gamemode, but not other gamemodes - text += "Vote Result: [.]" - else - if(mode != "gamemode") - text += "Vote Result: [.]" - else - text += "The vote has ended." // What will be shown if it is a gamemode vote that isn't extended - - else - text += "Vote Result: Inconclusive - No Votes!" - log_vote(text) - to_world("[text]") - return . - - proc/result() - . = announce_result() - var/restart = 0 - if(.) - switch(mode) - if("restart") - if(. == "Restart Round") - restart = 1 - if("gamemode") - if(master_mode != .) - world.save_mode(.) - if(SSticker && SSticker.mode) - restart = 1 - else - master_mode = . - - if(mode == "gamemode") //fire this even if the vote fails. - if(!going) - going = 1 - to_world("The round will start soon.") - - if(restart) - to_world("World restarting due to vote...") - sleep(50) - log_game("Rebooting due to restart vote") - world.Reboot() - - return . - - proc/submit_vote(var/ckey, var/vote) - if(mode) - if(CONFIG_GET(flag/vote_no_dead) && usr.stat == DEAD && (!usr.client.admin_holder || !(usr.client.admin_holder.rights & R_MOD))) - return 0 - if(current_votes[ckey]) - choices[choices[current_votes[ckey]]]-- - if(vote && 1<=vote && vote<=choices.len) - voted += usr.ckey - choices[choices[vote]]++ //check this - current_votes[ckey] = vote - return vote - return 0 - - proc/initiate_vote(var/vote_type, var/initiator_key) - if(!mode) - if(started_time != null && !check_rights(R_ADMIN)) - var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay)) - if(next_allowed_time > world.time) - return 0 - - reset() - switch(vote_type) - if("restart") - choices.Add("Restart Round","Continue Playing") - if("gamemode") - if(SSticker.current_state == GAME_STATE_SETTING_UP) - return 0 - choices.Add(config.votable_modes) - var/list/L = typesof(/datum/game_mode) - /datum/game_mode - for (var/F in choices) - for (var/T in L) - var/datum/game_mode/M = new T() - if (M.config_tag == F) - additional_text.Add("[M.required_players]") - break - if("custom") - question = stripped_input(usr,"What is the vote for?") - if(!question) return 0 - for(var/i=1,i<=10,i++) - var/option = capitalize(stripped_input(usr,"Please enter an option or hit cancel to finish")) - if(!option || mode || !usr.client) break - choices.Add(option) - else return 0 - mode = vote_type - initiator = initiator_key - started_time = world.time - var/text = "[capitalize(mode)] vote started by [initiator]." - if(mode == "custom") - text += "\n[question]" - - log_vote(text) - to_world("[text]\nType vote to place your votes.\nYou have [CONFIG_GET(number/vote_period)/10] seconds to vote.") - switch(vote_type) - if("gamemode") - world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 1) - if("custom") - world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 1) - if(mode == "gamemode" && going) - going = 0 - to_world("Round start has been delayed.") - - - - time_remaining = round(CONFIG_GET(number/vote_period)/10) - return 1 - return 0 - - proc/interface(var/client/C) - if(!C) return - var/admin = 0 - var/trialmin = 0 - if(C.admin_holder) - if(C.admin_holder.rights & R_ADMIN) - admin = 1 - trialmin = 1 // don't know why we use both of these it's really weird, but I'm 2 lasy to refactor this all to use just admin. - voting |= C - - . = "Voting Panel" - if(mode) - if(question) . += "

Vote: '[question]'

" - else . += "

Vote: [capitalize(mode)]

" - . += "Time Left: [time_remaining] s
" - . += "" - if(capitalize(mode) == "Gamemode") .+= "" - - for(var/i = 1, i <= choices.len, i++) - var/votes = choices[choices[i]] - if(!votes) votes = 0 - . += "" - if(current_votes[C.ckey] == i) - . += "" - else - . += "" - - if (additional_text.len >= i) - . += additional_text[i] - . += "" - - . += "
ChoicesVotesMinimum Players
[choices[i]][votes][choices[i]][votes]

" - if(admin) - . += "(Cancel Vote) " - else - . += "

Start a vote:



" - . += "Close" - return . - - - Topic(href,href_list[],hsrc) - if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid - switch(href_list["vote"]) - if("close") - voting -= usr.client - close_browser(usr, "vote") - return - if("cancel") - if(usr.client.admin_holder && (usr.client.admin_holder.rights & R_MOD)) - reset() - if("toggle_restart") - if(usr.client.admin_holder && (usr.client.admin_holder.rights & R_MOD)) - CONFIG_SET(flag/allow_vote_restart, !CONFIG_GET(flag/allow_vote_restart)) - if("toggle_gamemode") - if(usr.client.admin_holder && (usr.client.admin_holder.rights & R_MOD)) - CONFIG_SET(flag/allow_vote_mode, !CONFIG_GET(flag/allow_vote_mode)) - if("restart") - if(CONFIG_GET(flag/allow_vote_restart) || (usr.client.admin_holder && (usr.client.admin_holder.rights & R_MOD))) - initiate_vote("restart",usr.key) - if("gamemode") - if(CONFIG_GET(flag/allow_vote_mode) || (usr.client.admin_holder && (usr.client.admin_holder.rights & R_MOD))) - initiate_vote("gamemode",usr.key) - if("custom") - if(usr.client.admin_holder && (usr.client.admin_holder.rights & R_MOD)) - initiate_vote("custom",usr.key) - else - submit_vote(usr.ckey, round(text2num(href_list["vote"]))) - usr.vote() - -/mob/verb/vote() - set category = "OOC" - set name = "Vote" - - if(vote) - show_browser(src, vote.interface(client), "Vote", "vote", "can_close=0") - - - -var/MapDaemon_UID = -1 //-1 by default so we know when to set it -var/force_mapdaemon_vote = 0 - -//Basically, this completely ignores the voting datum etc in favor of editing a simple a simple list, player_votes -//Upon request by MapDaemon, world/Topic() will it into JSON and send it away, so we do 0 handling in DM -/client/verb/mapVote() - set category = "OOC" - set name = "Map Vote" - - if(!SSticker.mode || !SSticker.mode.round_finished) - to_chat(src, SPAN_NOTICE("Please wait until the round ends.")) - return - - var/list/L = list() - L += "Don't care" - - // For future modularity and maybe more subtle solutions here? - switch(GLOB.clients.len) - if (0 to PLAYERCOUNT_LOWPOP_MAP_LIMIT) - L += LOWPOP_NEXT_MAP_CANDIDATES.Copy() - else - L += NEXT_MAP_CANDIDATES.Copy() - L -= map_tag - var/selection = input("Vote for the next map to play on", "Vote:", "Don't care") as null|anything in L - - if(!selection || !src) return - - if(selection == "Don't care") - to_chat(src, SPAN_NOTICE("You have not voted.")) - return - - to_chat(src, SPAN_NOTICE("You have voted for [selection].")) - - player_votes[src.ckey] = selection - -/client/proc/forceMDMapVote() - set name = "Force Map Vote" - set category = "Server.MapDaemon" - - force_mapdaemon_vote = !force_mapdaemon_vote - to_chat(src, SPAN_NOTICE("The server will [force_mapdaemon_vote ? "now" : "no longer"] tell Mapdaemon to start a vote the next time possible.")) - - message_staff("[src] is attempting to force a MapDaemon vote.") - -//Uses an invalid ckey to rig the votes -//Special case for }}} handled in World/Topic() -//Set up so admins can fight over what the map will be, hurray -/client/proc/forceNextMap() - set name = "Force Map" - set category = "Server.MapDaemon" - - if(alert("Are you sure you want to force the next map?",, "Yes", "No") == "No") return - - var/selection = input("Vote for the next map to play on", "Vote:", "LV-624") as null|anything in DEFAULT_NEXT_MAP_CANDIDATES - - if(!selection || !src) return - - to_chat(src, SPAN_NOTICE("You have forced the next map to be [selection]")) - - message_staff("[src] just forced the next map to be [selection].") - - player_votes["}}}"] = selection //}}} is an invalid ckey so we won't be in risk of someone using this cheekily - - -var/enable_map_vote = 1 -/client/proc/cancelMapVote() - set name = "Toggle Map Vote" - set category = "Server.MapDaemon" - - if(alert("Are you sure you want to turn the map vote [!enable_map_vote ? "on" : "off"]?",, "Yes", "No") == "No") return - - enable_map_vote = !enable_map_vote - - to_world(SPAN_NOTICE("[src] has toggled the map vote [enable_map_vote ? "on" : "off"]")) - to_chat(src, SPAN_NOTICE("You have toggled the map vote [enable_map_vote ? "on" : "off"]")) - - message_staff("[src] just toggled the map vote [enable_map_vote ? "on" : "off"].") - -/client/proc/showVotableMaps() - set name = "List Maps" - set category = "Server.MapDaemon" - - to_chat(src, "Possible maps irrespective of pop:") - for(var/i in NEXT_MAP_CANDIDATES) - to_chat(src, SPAN_NOTICE(i)) - -/client/proc/editVotableMaps() - set name = "Edit Maps" - set category = "Server.MapDaemon" - - if(alert("Are you sure you want to edit the map voting candidates?",, "Yes", "No") == "No") return - - switch(alert("Do you want to add or remove a map?",, "Add", "Remove", "Cancel")) - if("Cancel") - return - if("Add") - var/selection = "" - switch(alert("Do you want to add one of the default map possibilities?",, "Yes", "No")) - if("Yes") - selection = input("Pick a default map.") as null|anything in DEFAULT_NEXT_MAP_CANDIDATES - if("No") - if(alert("Warning! This is a very dangerous option. If there is a typo in the map name and your choice wins, MapDaemon will crash. Please make sure you enter the exact name of the map. Are you sure you want to continue?", "WARNING", "Yes", "No") == "No") return - selection = input("Enter a map at your own risk.") - - if(!selection || !src) return - if(NEXT_MAP_CANDIDATES.Find(selection)) - alert("That option was already available.") - return - NEXT_MAP_CANDIDATES.Add(selection) - message_staff("[src] just added [selection] to the map pool.") - if("Remove") - var/selection = input("Pick a map to remove from the pool") as null|anything in NEXT_MAP_CANDIDATES - if(!selection || !src) return - NEXT_MAP_CANDIDATES.Remove(selection) - message_staff("[src] just removed [selection] from the map pool.") - -var/kill_map_daemon = 0 -/client/proc/killMapDaemon() - set name = "Kill MapDaemon" - set category = "Server.MapDaemon" - - if(alert("Are you sure you want to kill MapDaemon?",, "Yes", "No") == "No") return - - kill_map_daemon = 1 - - alert("MapDaemon will be killed on next round-end check.") - message_staff("[src] just killed MapDaemon. It may be restarted with \"Map Vote - Revive MapDaemon\".") - -/client/proc/reviveMapDaemon() - set name = "Revive MapDaemon" - set category = "Server.MapDaemon" - - kill_map_daemon = 0 - - message_staff("[src] is attempting to restart MapDaemon.") - - run_mapdaemon_batch() - -/proc/run_mapdaemon_batch() - - set waitfor = 0 - - if(world.system_type != MS_WINDOWS) return 0 //Don't know if it'll work for non-Windows, so let's just abort - - shell("run_mapdaemon.bat") diff --git a/code/datums/agents/objectives/steal.dm b/code/datums/agents/objectives/steal.dm index 007d11ce1b89..1f1bc5d6b2be 100644 --- a/code/datums/agents/objectives/steal.dm +++ b/code/datums/agents/objectives/steal.dm @@ -83,14 +83,14 @@ icon_state = "golden_health" item_state = "analyzer" -/obj/item/device/healthanalyzer/golden/New() +/obj/item/device/healthanalyzer/golden/Initialize() . = ..() - + LAZYADD(objects_of_interest, src) /obj/item/device/healthanalyzer/golden/Destroy() . = ..() - + LAZYREMOVE(objects_of_interest, src) // Medbay item @@ -100,14 +100,14 @@ icon_state = "folded_sheet_medical" item_state = "folded_sheet_medical" -/obj/item/folded_medical_sheet/New() +/obj/item/folded_medical_sheet/Initialize() . = ..() - + LAZYADD(objects_of_interest, src) /obj/item/folded_medical_sheet/Destroy() . = ..() - + LAZYREMOVE(objects_of_interest, src) // Req tally book @@ -117,14 +117,14 @@ icon = 'icons/obj/items/books.dmi' icon_state ="book" -/obj/item/tally_book/New() +/obj/item/tally_book/Initialize() . = ..() - + LAZYADD(objects_of_interest, src) /obj/item/tally_book/Destroy() . = ..() - + LAZYREMOVE(objects_of_interest, src) // CIC item @@ -134,12 +134,12 @@ icon_state = "golden_cup" item_state = "golden_cup" -/obj/item/golden_cup/New() +/obj/item/golden_cup/Initialize() . = ..() - + LAZYADD(objects_of_interest, src) - + /obj/item/golden_cup/Destroy() . = ..() - - LAZYREMOVE(objects_of_interest, src) \ No newline at end of file + + LAZYREMOVE(objects_of_interest, src) diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 7168a78ac2cc..a0dcb2aa8862 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -395,7 +395,7 @@ var/list/advance_cures = list( AD.Refresh() for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list.Copy())) - if(H.z != 1) + if(!is_ground_level(H.z)) continue if(!H.has_disease(D)) H.contract_disease(D, 1) diff --git a/code/datums/emergency_calls/cryo_marines.dm b/code/datums/emergency_calls/cryo_marines.dm index 7a6e3989f00a..a1829b9c5713 100644 --- a/code/datums/emergency_calls/cryo_marines.dm +++ b/code/datums/emergency_calls/cryo_marines.dm @@ -14,7 +14,7 @@ /datum/emergency_call/cryo_squad/create_member(datum/mind/M) set waitfor = 0 - if(map_tag == MAP_WHISKEY_OUTPOST) + if(SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST) name_of_spawn = /obj/effect/landmark/ert_spawns/distress_wo var/turf/spawn_loc = get_spawn_point() @@ -27,14 +27,14 @@ if (medics < max_medics) medics++ arm_equipment(H, "USCM (Cryo) Squad Medic", TRUE, TRUE) - to_chat(H, "\red You are a medic in the USCM, you are here to assist in the defence of the [map_tag]. Listen to the chain of command. ") + to_chat(H, "\red You are a medic in the USCM, you are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command. ") else if (heavies < max_heavies) heavies++ arm_equipment(H, "USCM (Cryo) Squad Engineer", TRUE, TRUE) - to_chat(H, "\red You are an engineer in the USCM, you are here to assist in the defence of the [map_tag]. Listen to the chain of command. ") + to_chat(H, "\red You are an engineer in the USCM, you are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command. ") else arm_equipment(H, "USCM (Cryo) Squad Marine (PFC)", TRUE, TRUE) - to_chat(H, "\red You are a private in the USCM, you are here to assist in the defence of the [map_tag]. Listen to the chain of command. ") + to_chat(H, "\red You are a private in the USCM, you are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command. ") sleep(10) to_chat(H, "Objectives: [objectives]") diff --git a/code/datums/emergency_calls/cryo_marines_heavy.dm b/code/datums/emergency_calls/cryo_marines_heavy.dm index 0ec7d9758c3a..38d679592379 100644 --- a/code/datums/emergency_calls/cryo_marines_heavy.dm +++ b/code/datums/emergency_calls/cryo_marines_heavy.dm @@ -16,7 +16,7 @@ /datum/emergency_call/cryo_squad_equipped/create_member(datum/mind/M) set waitfor = 0 - if(map_tag == MAP_WHISKEY_OUTPOST) + if(SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST) name_of_spawn = /obj/effect/landmark/ert_spawns/distress_wo var/turf/spawn_loc = get_spawn_point() @@ -29,25 +29,25 @@ if(!leader) leader = H arm_equipment(H, "USCM Cryo Squad Leader (Equipped)", TRUE, TRUE) - to_chat(H, SPAN_WARNING("You are a Squad leader in the USCM, your squad is here to assist in the defence of the [map_tag]. ")) + to_chat(H, SPAN_WARNING("You are a Squad leader in the USCM, your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. ")) else if (heavies < max_heavies) heavies++ if(prob(40)) arm_equipment(H, "USCM Cryo Smartgunner (Equipped)", TRUE, TRUE) - to_chat(H, SPAN_WARNING("You are a smartgunner in the USCM, your squad is here to assist in the defence of the [map_tag]. Listen to [leader.name] they are your (acting) squad leader. ")) + to_chat(H, SPAN_WARNING("You are a smartgunner in the USCM, your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to [leader.name] they are your (acting) squad leader. ")) else if(prob(20)) arm_equipment(H, "USCM Cryo Specialist (Equipped)", TRUE, TRUE) - to_chat(H, SPAN_WARNING("You are a specialist in the USCM, your squad is here to assist in the defence of the [map_tag]. Listen to [leader.name] they are your (acting) squad leader. ")) + to_chat(H, SPAN_WARNING("You are a specialist in the USCM, your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to [leader.name] they are your (acting) squad leader. ")) else arm_equipment(H, "USCM Cryo Engineer (Equipped)", TRUE, TRUE) - to_chat(H, SPAN_WARNING("You are an engineer in the USCM, your squad is here to assist in the defence of the [map_tag]. Listen to [leader.name] they are your (acting) squad leader. ")) + to_chat(H, SPAN_WARNING("You are an engineer in the USCM, your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to [leader.name] they are your (acting) squad leader. ")) else if (medics < max_medics) medics++ arm_equipment(H, "USCM Cryo Medic (Equipped)", TRUE, TRUE) - to_chat(H, SPAN_WARNING("You are a medic in the USCM, your squad is here to assist in the defence of the [map_tag]. Listen to [leader.name] they are your (acting) squad leader. ")) + to_chat(H, SPAN_WARNING("You are a medic in the USCM, your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to [leader.name] they are your (acting) squad leader. ")) else arm_equipment(H,"USCM Cryo Private (Equipped)", TRUE, TRUE) - to_chat(H, SPAN_WARNING("You are a private in the USCM, your squad is here to assist in the defence of [map_tag]. Listen to [leader.name] they are your (acting) squad leader. ")) + to_chat(H, SPAN_WARNING("You are a private in the USCM, your squad is here to assist in the defence of [SSmapping.configs[GROUND_MAP].map_name]. Listen to [leader.name] they are your (acting) squad leader. ")) sleep(10) to_chat(H, "Objectives: [objectives]") diff --git a/code/datums/emergency_calls/emergency_call.dm b/code/datums/emergency_calls/emergency_call.dm index 9d08de522b61..8ec07ab1f776 100644 --- a/code/datums/emergency_calls/emergency_call.dm +++ b/code/datums/emergency_calls/emergency_call.dm @@ -139,7 +139,7 @@ var/deathtime = world.time - usr.timeofdeath if(deathtime < SECONDS_60) //Nice try, ghosting right after the announcement - if(map_tag != MAP_WHISKEY_OUTPOST) // people ghost so often on whiskey outpost. + if(SSmapping.configs[GROUND_MAP].map_name != MAP_WHISKEY_OUTPOST) // people ghost so often on whiskey outpost. to_chat(usr, SPAN_WARNING("You ghosted too recently.")) return diff --git a/code/datums/emergency_calls/tank_crew.dm b/code/datums/emergency_calls/tank_crew.dm index caf343054d3e..86a258466bf8 100644 --- a/code/datums/emergency_calls/tank_crew.dm +++ b/code/datums/emergency_calls/tank_crew.dm @@ -12,7 +12,7 @@ /datum/emergency_call/tank_crew/create_member(datum/mind/M) set waitfor = 0 - if(map_tag == MAP_WHISKEY_OUTPOST) + if(SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST) name_of_spawn = /obj/effect/landmark/ert_spawns/distress_wo var/turf/spawn_loc = get_spawn_point() @@ -23,7 +23,7 @@ sleep(5) arm_equipment(H, "USCM Vehicle Crewman (CRMN)", TRUE, TRUE) - to_chat(H, "\red You are a vehicle crewman in the USCM, you are here to assist in the defence of the [map_tag]. Listen to the chain of command.") + to_chat(H, "\red You are a vehicle crewman in the USCM, you are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command.") sleep(10) to_chat(H, "Objectives: [objectives]") diff --git a/code/datums/emergency_calls/whiskey_outpost.dm b/code/datums/emergency_calls/whiskey_outpost.dm index 6746b4ec6651..fada80a8275f 100644 --- a/code/datums/emergency_calls/whiskey_outpost.dm +++ b/code/datums/emergency_calls/whiskey_outpost.dm @@ -12,7 +12,7 @@ /datum/emergency_call/wo/create_member(datum/mind/M) set waitfor = 0 - if(map_tag == MAP_WHISKEY_OUTPOST) + if(SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST) name_of_spawn = /obj/effect/landmark/ert_spawns/distress_wo var/turf/spawn_loc = get_spawn_point() @@ -25,25 +25,25 @@ if(!leader) leader = mob arm_equipment(mob, "Dust Raider Squad Leader", TRUE, TRUE) - to_chat(mob, "\red You are a Squad leader in the USCM, your squad is here to assist in the defence of the [map_tag]. ") + to_chat(mob, "\red You are a Squad leader in the USCM, your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. ") else if (heavies < max_heavies) heavies++ if(prob(40)) arm_equipment(mob, "Dust Raider Smartgunner", TRUE, TRUE) - to_chat(mob, "\red You are a smartgunner in the USCM, your squad is here to assist in the defence of the [map_tag]. Listen to [leader.name] they are your (acting) squad leader. ") + to_chat(mob, "\red You are a smartgunner in the USCM, your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to [leader.name] they are your (acting) squad leader. ") else if(prob(20)) arm_equipment(mob, "Dust Raider Specialist", TRUE, TRUE) - to_chat(mob, "\red You are a specialist in the USCM, your squad is here to assist in the defence of the [map_tag]. Listen to [leader.name] they are your (acting) squad leader. ") + to_chat(mob, "\red You are a specialist in the USCM, your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to [leader.name] they are your (acting) squad leader. ") else arm_equipment(mob, "Dust Raider Engineer", TRUE, TRUE) - to_chat(mob, "\red You are an engineer in the USCM, your squad is here to assist in the defence of the [map_tag]. Listen to [leader.name] they are your (acting) squad leader. ") + to_chat(mob, "\red You are an engineer in the USCM, your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to [leader.name] they are your (acting) squad leader. ") else if (medics < max_medics) medics++ arm_equipment(mob, "Dust Raider Medic", TRUE, TRUE) - to_chat(mob, "\red You are a medic in the USCM, your squad is here to assist in the defence of the [map_tag]. Listen to [leader.name] they are your (acting) squad leader. ") + to_chat(mob, "\red You are a medic in the USCM, your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to [leader.name] they are your (acting) squad leader. ") else arm_equipment(mob,"Dust Raider Private", TRUE, TRUE) - to_chat(mob, "\red You are a private in the USCM, your squad is here to assist in the defence of [map_tag]. Listen to [leader.name] they are your (acting) squad leader. ") + to_chat(mob, "\red You are a private in the USCM, your squad is here to assist in the defence of [SSmapping.configs[GROUND_MAP].map_name]. Listen to [leader.name] they are your (acting) squad leader. ") sleep(10) to_chat(mob, "Objectives: [objectives]") diff --git a/code/datums/entities/map_votes.dm b/code/datums/entities/map_votes.dm index f708f250d596..eaa799da71e1 100644 --- a/code/datums/entities/map_votes.dm +++ b/code/datums/entities/map_votes.dm @@ -2,7 +2,7 @@ var/map_name var/total_votes - + /datum/entity_meta/map_vote entity_type = /datum/entity/map_vote table_name = "map_vote" @@ -11,4 +11,4 @@ ) /datum/entity_meta/map_vote/on_read(var/datum/entity/map_vote/vote) - vote.total_votes = text2num("[vote.total_votes]") \ No newline at end of file + vote.total_votes = text2num("[vote.total_votes]") diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index d9140b39e51a..2ad6b232e45d 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -177,12 +177,9 @@ teleatom.visible_message(SPAN_DANGER("The [teleatom] bounces off of the portal!")) return 0 - if(is_admin_level(destination.z)) //centcomm z-level + if(is_admin_level(destination.z)) if(length(teleatom.search_contents_for(/obj/item/storage/backpack/holding))) teleatom.visible_message(SPAN_DANGER("The Bag of Holding bounces off of the portal!")) return 0 - - if(destination.z > 7) //Away mission z-levels - return 0 return 1 diff --git a/code/datums/map_config.dm b/code/datums/map_config.dm new file mode 100644 index 000000000000..27ac225c7ab8 --- /dev/null +++ b/code/datums/map_config.dm @@ -0,0 +1,264 @@ +//used for holding information about unique properties of maps +//feed it json files that match the datum layout +//defaults to box +// -Cyberboss + +/datum/map_config + // Metadata + var/config_filename = "maps/LV624.json" + var/defaulted = TRUE // set to FALSE by LoadConfig() succeeding + // Config from maps.txt + var/config_max_users = 0 + var/config_min_users = 0 + var/voteweight = 1 + + // Config actually from the JSON - default values + var/map_name = "LV624" + var/map_path = "map_files/LV624" + var/map_file = "LV624.dmm" + + var/traits = null + var/space_empty_levels = 1 + var/list/environment_traits = list() + var/armor_style = "default" + var/list/gamemodes = list() + + var/allow_custom_shuttles = TRUE + var/shuttles = list() + + var/announce_text = "" + + var/squads_max_num = 4 + + var/weather_holder + + var/list/survivor_types = list( + "Survivor - Scientist", + "Survivor - Doctor", + "Survivor - Chef", + "Survivor - Chaplain", + "Survivor - Miner", + "Survivor - Colonial Marshall", + "Survivor - Engineer" + ) + + var/list/defcon_triggers = list(5150, 4225, 2800, 1000, 0.0) + + var/survivor_message = "You are a survivor of the attack on the colony. You worked or lived in the archaeology colony, and managed to avoid the alien attacks... until now." + + var/map_item_type + + var/force_mode + + var/list/monkey_types = list(/mob/living/carbon/human/monkey) + +/proc/load_map_config(filename, default, delete_after, error_if_missing = TRUE) + var/datum/map_config/config = new + if(default) + return config + if(!config.LoadConfig(filename, error_if_missing)) + qdel(config) + config = new /datum/map_config + if(delete_after) + fdel(filename) + return config + + +/proc/load_map_configs(list/maptypes, default, delete_after, error_if_missing = TRUE) + var/list/configs = list() + + for(var/i in maptypes) + var/filename = MAP_TO_FILENAME[i] + var/datum/map_config/config = new + if(default) + configs[i] = config + continue + if(!config.LoadConfig(filename, error_if_missing, i)) + qdel(config) + config = new /datum/map_config + if(delete_after) + fdel(filename) + configs[i] = config + return configs + +#define CHECK_EXISTS(X) if(!istext(json[X])) { log_world("[##X] missing from json!"); return; } +/datum/map_config/proc/LoadConfig(filename, error_if_missing, maptype) + if(!fexists(filename)) + if(error_if_missing) + log_world("map_config not found: [filename]") + return + + var/json = file(filename) + if(!json) + log_world("Could not open map_config: [filename]") + return + + json = file2text(json) + if(!json) + log_world("map_config is not text: [filename]") + return + + json = json_decode(json) + if(!json) + log_world("map_config is not json: [filename]") + return + + config_filename = filename + + CHECK_EXISTS("map_name") + map_name = json["map_name"] + CHECK_EXISTS("map_path") + map_path = json["map_path"] + + map_file = json["map_file"] + // "map_file": "BoxStation.dmm" + if (istext(map_file)) + if (!fexists("maps/[map_path]/[map_file]")) + log_world("Map file ([map_file]) does not exist!") + return + // "map_file": ["Lower.dmm", "Upper.dmm"] + else if (islist(map_file)) + for (var/file in map_file) + if (!fexists("maps/[map_path]/[file]")) + log_world("Map file ([file]) does not exist!") + return + else + log_world("map_file missing from json!") + return + + if (islist(json["shuttles"])) + var/list/L = json["shuttles"] + for(var/key in L) + var/value = L[key] + shuttles[key] = value + else if ("shuttles" in json) + log_world("map_config shuttles is not a list!") + return + + if (islist(json["survivor_types"])) + survivor_types = json["survivor_types"] + else if ("survivor_types" in json) + log_world("map_config survivor_types is not a list!") + return + + if (islist(json["monkey_types"])) + monkey_types = list() + for(var/monkey in json["monkey_types"]) + switch(monkey) + if("farwa") + monkey_types += /mob/living/carbon/human/farwa + if("monkey") + monkey_types += /mob/living/carbon/human/monkey + if("neaera") + monkey_types += /mob/living/carbon/human/neaera + if("stok") + monkey_types += /mob/living/carbon/human/stok + if("yiren") + monkey_types += /mob/living/carbon/human/yiren + else + log_world("map_config monkey_types has invalid name!") + return + else if ("monkey_types" in json) + log_world("map_config monkey_types is not a list!") + return + + if (islist(json["defcon_triggers"])) + defcon_triggers = json["defcon_triggers"] + else if ("defcon_triggers" in json) + log_world("map_config defcon_triggers is not a list!") + return + + traits = json["traits"] + if(islist(traits)) + for(var/list/ztraits in traits) // Defaults to ground map if not specified + if(!ztraits[ZTRAIT_GROUND] && !ztraits[ZTRAIT_MARINE_MAIN_SHIP]) + ztraits[ZTRAIT_GROUND] = TRUE + else if(traits) + log_world("map_config traits is not a list!") + return + + var/temp = json["space_empty_levels"] + if (isnum(temp)) + space_empty_levels = temp + else if (!isnull(temp)) + log_world("map_config space_empty_levels is not a number!") + return + + temp = json["squads"] + if(isnum(temp)) + squads_max_num = temp + else if(!isnull(temp)) + log_world("map_config squads_max_num is not a number!") + return + + allow_custom_shuttles = json["allow_custom_shuttles"] != FALSE + + if(json["armor"]) + armor_style = json["armor"] + + if(json["survivor_message"]) + survivor_message = json["survivor_message"] + + if(json["force_mode"]) + force_mode = json["force_mode"] + + if(json["announce_text"]) + announce_text = replacetext(json["announce_text"], "###SHIPNAME###", MAIN_SHIP_NAME) + + if(json["weather_holder"]) + weather_holder = text2path(json["weather_holder"]) + if(!weather_holder) + log_world("map_config weather_holder is not a proper typepath!") + return + + if(json["map_item_type"]) + map_item_type = text2path(json["map_item_type"]) + if(!map_item_type) + log_world("map_config map_item_type is not a proper typepath!") + return + + if(islist(json["environment_traits"])) + environment_traits = json["environment_traits"] + else if(!isnull(json["environment_traits"])) + log_world("map_config environment_traits is not a list!") + return + + var/list/gamemode_names = list() + for(var/t in subtypesof(/datum/game_mode)) + var/datum/game_mode/G = t + gamemode_names += initial(G.config_tag) + + if(islist(json["gamemodes"])) + for(var/g in json["gamemodes"]) + if(!(g in gamemode_names)) + log_world("map_config has an invalid gamemode name!") + return + if(g == "Extended") // always allow extended + continue + gamemodes += g + gamemodes += "Extended" + else if(!isnull(json["gamemodes"])) + log_world("map_config gamemodes is not a list!") + return + else + for(var/a in subtypesof(/datum/game_mode)) + var/datum/game_mode/G = a + gamemodes += initial(G.config_tag) + + defaulted = FALSE + return TRUE +#undef CHECK_EXISTS + +/datum/map_config/proc/GetFullMapPaths() + if (istext(map_file)) + return list("maps/[map_path]/[map_file]") + . = list() + for (var/file in map_file) + . += "maps/[map_path]/[file]" + + +/datum/map_config/proc/MakeNextMap(maptype = GROUND_MAP) + if(maptype == GROUND_MAP) + return config_filename == "data/next_map.json" || fcopy(config_filename, "data/next_map.json") + else if(maptype == SHIP_MAP) + return config_filename == "data/next_ship.json" || fcopy(config_filename, "data/next_ship.json") diff --git a/code/datums/soundOutput.dm b/code/datums/soundOutput.dm index ae5786604445..c8be5c6f17e2 100644 --- a/code/datums/soundOutput.dm +++ b/code/datums/soundOutput.dm @@ -27,8 +27,8 @@ var/turf/owner_turf = get_turf(owner.mob) if(owner_turf) // We're in an interior and sound came from outside - if(owner_turf.z == interior_manager.interior_z && owner_turf.z != T.z) - var/datum/interior/VI = interior_manager.get_interior_by_coords(owner_turf.x, owner_turf.y) + if(owner_turf.z == GLOB.interior_manager.interior_z && owner_turf.z != T.z) + var/datum/interior/VI = GLOB.interior_manager.get_interior_by_coords(owner_turf.x, owner_turf.y) if(VI && VI.exterior) var/turf/candidate = get_turf(VI.exterior) if(!(candidate.z == T.z)) diff --git a/code/datums/weather/weather_map_holder.dm b/code/datums/weather/weather_map_holder.dm index e694ebee068b..f78a9f0b6992 100644 --- a/code/datums/weather/weather_map_holder.dm +++ b/code/datums/weather/weather_map_holder.dm @@ -1,18 +1,17 @@ -// Delegate object that holds all the map-dependent pieces of the +// Delegate object that holds all the map-dependent pieces of the // One of these is instanced into the weather subsystem when it's initialized // based on the current map_tag (should be the only map_tag dependent piece of code) /datum/weather_ss_map_holder var/name = "set this" // For VV - var/source_map_tag // Map tag that made this // Weather SS configuration options var/min_time_between_events = MINUTES_5 // Self explanatory - var/warn_time = SECONDS_30 // Warning time between the call to + var/warn_time = SECONDS_30 // Warning time between the call to var/no_weather_turf_icon_state = "" // Icon state to set on the global VFX holder // when there's no weather. var/list/potential_weather_events // List of types of possible weather events - + /datum/weather_ss_map_holder/New() potential_weather_events = list() @@ -26,12 +25,12 @@ /datum/weather_ss_map_holder/proc/should_affect_atom(var/atom/A) if (!istype(A)) return FALSE - + var/area/target_area = get_area(A) return should_affect_area(target_area) // Should we start an event? This just deals with the logic that an event is starting -// period, nothing to do with what the type of the event will be when its +// period, nothing to do with what the type of the event will be when its // eventually chosen /datum/weather_ss_map_holder/proc/should_start_event() log_debug("Weather subsystem map holder [src] is improperly configured. Code: WSSMH02") @@ -46,7 +45,7 @@ log_debug("Weather subsystem map holder [src] is improperly configured. Code: WSSMH03") return null -// Called whenever the weather SS decides to start an event, but +// Called whenever the weather SS decides to start an event, but // warn_time deciseconds before it actually starts // (think weather sirens on sorokyne) // This can do nothing safely, so you don't have to override it diff --git a/code/datums/weather/weather_map_holders/sorokyne.dm b/code/datums/weather/weather_map_holders/sorokyne.dm index 3255cc4d254f..d101e9147203 100644 --- a/code/datums/weather/weather_map_holders/sorokyne.dm +++ b/code/datums/weather/weather_map_holders/sorokyne.dm @@ -2,7 +2,6 @@ /datum/weather_ss_map_holder/sorokyne name = "Sorokyne Map Holder" - source_map_tag = MAP_SOROKYNE_STRATA min_time_between_events = MINUTES_20 no_weather_turf_icon_state = "strata_clearsky" @@ -23,4 +22,4 @@ /datum/weather_ss_map_holder/sorokyne/weather_warning() for (var/obj/structure/machinery/weather_siren/WS in weather_notify_objects) - WS.weather_warning() \ No newline at end of file + WS.weather_warning() diff --git a/code/game/area/Z_Holder.dm b/code/game/area/Z_Holder.dm deleted file mode 100644 index 0dbdf5e42d76..000000000000 --- a/code/game/area/Z_Holder.dm +++ /dev/null @@ -1,64 +0,0 @@ -//////////////////////////////////////////////////////////// -// This is the Z-holder, which will do a LOT of things to // -// handle the fact that we have a shit-ton of maps. Each // -// Layer will need to have this object in it's T-comm // -// area. If you don't, you won't be able to manage things // -// like where gibbed bodies land, where beacons go, and // -// which levels are "planets" and are unbreachable. // -// Follow the format for the example, and set the vars as // -// Needed. // -//////////////////////////////////////////////////////////// - - -/obj/item/z_holder - name = "Default" //Name of the item - var/MapName = "Default" //This should be the name of the map, without the Z.## - desc = "Something you shouldn't be fucking with while the server is running." //This shouldn't be changed - var/Planet = 0 //Set true if this is a planet, and the ground shouldn't "breach to space" - var/Station = 0 //Set true if this is a station, and it should breach to space - var/Sulaco = 0 //Set true if this is a deck of the Sulaco. - icon = 'icons/obj/structures/props/stationobjs.dmi' - icon_state = "relay" - unacidable = TRUE - anchored = 1 - -/obj/item/z_holder/LV624 //Zlayer 1 - name = "LV-624 Z-Holder" - MapName = "LV624" - Planet = 1 - - -/obj/item/z_holder/CentCom //Zlayer 2 - name = "CentCom Z-Holder" - MapName = "CentComm" - Station = 1 - - -/obj/item/z_holder/SulacoUpper //Zlayer 3 - name = "Sulaco Upper Z-Holder" - MapName = "PlaceholderSulaco" - Station = 1 - - -/obj/item/z_holder/SulacoLower //Zlayer 4 - name = "Sulaco Lower Z-Holder" - MapName = "SulacoBottom" - Station = 1 - - -/obj/item/z_holder/Space //Zlayer 5 - name = "Space Z-holder" - MapName = "Space" - - -/obj/item/z_holder/Halloween //Zlayer 6 - name = "HauntedHouse Z-holder" - MapName = "HauntedHouse" - Planet = 1 - - -/obj/item/z_holder/Prison //Zlayer 7 - name = "Prison Z-holder" - MapName = "Prison" - Station = 1 - diff --git a/maps/Z.02.Admin_Level.dm b/code/game/area/admin_level.dm similarity index 100% rename from maps/Z.02.Admin_Level.dm rename to code/game/area/admin_level.dm diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 44b6f2565d4b..dc81328e3813 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -17,6 +17,8 @@ var/flags_alarm_state = NO_FLAGS + var/unique = TRUE + var/has_gravity = 1 var/list/apc = list() var/list/area_machines = list() // list of machines only for master areas @@ -78,17 +80,24 @@ /area/New() + // This interacts with the map loader, so it needs to be set immediately + // rather than waiting for atoms to initialize. + if(unique) + GLOB.areas_by_type[type] = src ..() + master = src //moved outside the spawn(1) to avoid runtimes in lighting.dm when it references loc.loc.master ~Carn + related = list(src) + initialize_power_and_lighting() + +/area/Initialize(mapload, ...) icon_state = "" //Used to reset the icon overlay, I assume. layer = AREAS_LAYER - master = src //moved outside the spawn(1) to avoid runtimes in lighting.dm when it references loc.loc.master ~Carn uid = ++global_uid - related = list(src) + . = ..() active_areas += src all_areas += src - - initialize_power_and_lighting() + reg_in_areas_in_z() /area/proc/initialize_power_and_lighting(override_power) if(requires_power) @@ -448,3 +457,26 @@ return gas_type +// A hook so areas can modify the incoming args +/area/proc/PlaceOnTopReact(list/new_baseturfs, turf/fake_turf_type, flags) + return flags + +/area/proc/reg_in_areas_in_z() + if(!length(contents)) + return + + var/list/areas_in_z = SSmapping.areas_in_z + var/z + for(var/i in contents) + var/atom/thing = i + if(!thing) + continue + z = thing.z + break + if(!z) + WARNING("No z found for [src]") + return + if(!areas_in_z["[z]"]) + areas_in_z["[z]"] = list() + areas_in_z["[z]"] += src + diff --git a/code/game/area/space_station_13_areas.dm b/code/game/area/space_station_13_areas.dm index db342d09a708..a24bd14f43e8 100644 --- a/code/game/area/space_station_13_areas.dm +++ b/code/game/area/space_station_13_areas.dm @@ -13,23 +13,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station */ -var/list/ghostteleportlocs = list() - -/proc/setupGhostTeleportLocs() - for(var/area/AR in all_areas) - if(ghostteleportlocs.Find(AR.name)) continue - if(istype(AR, /area/tdome) || istype(AR, /area/adminlevel/bunker01/mainroom) || istype(AR, /area/adminlevel/ert_station)) - ghostteleportlocs += AR.name - ghostteleportlocs[AR.name] = AR - var/turf/picked = pick(get_area_turfs(AR.type)) - if (is_ground_level(picked.z) || is_mainship_level(picked.z) || is_loworbit_level(picked.z) || is_huntership_level(picked.z)) - ghostteleportlocs += AR.name - ghostteleportlocs[AR.name] = AR - - ghostteleportlocs = sortAssoc(ghostteleportlocs) - - return 1 - /*-----------------------------------------------------------------------------*/ /area/space name = "\improper Space" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 2f974641e5e7..e730f4f14b16 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -61,16 +61,6 @@ //we were deleted return - pass_flags = pass_flags_cache[type] - if (isnull(pass_flags)) - pass_flags = new() - initialize_pass_flags(pass_flags) - pass_flags_cache[type] = pass_flags - else - initialize_pass_flags() - - Decorate() - /* We actually care what this returns, since it can return different directives. Not specifically here, but in other variations of this. As a general safety, @@ -386,6 +376,17 @@ Parameters are passed from New. CRASH("Warning: [src]([type]) initialized multiple times!") flags_atom |= INITIALIZED + pass_flags = pass_flags_cache[type] + if (isnull(pass_flags)) + pass_flags = new() + initialize_pass_flags(pass_flags) + pass_flags_cache[type] = pass_flags + else + initialize_pass_flags() + + if(!mapload) + Decorate() + return INITIALIZE_HINT_NORMAL //called if Initialize returns INITIALIZE_HINT_LATELOAD @@ -396,9 +397,6 @@ Parameters are passed from New. /atom/process() return -/atom/proc/Decorate() - return - ///---CLONE---/// /atom/clone diff --git a/code/game/gamemodes/cm_initialize.dm b/code/game/gamemodes/cm_initialize.dm index ec31142749d7..bb52d6060ac0 100644 --- a/code/game/gamemodes/cm_initialize.dm +++ b/code/game/gamemodes/cm_initialize.dm @@ -665,71 +665,12 @@ Additional game mode variables. return survivor_non_event_transform(ghost.current, picked_spawn, is_synth) /datum/game_mode/proc/survivor_old_equipment(var/mob/living/carbon/human/H, var/is_synth = FALSE) - var/list/survivor_types + var/list/survivor_types = SSmapping.configs[GROUND_MAP].survivor_types if(is_synth) survivor_types = list( "Survivor - Synthetic", //to be expanded later ) - else - switch(map_tag) - if(MAP_PRISON_STATION) - survivor_types = list( - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Corporate Liaison", - "Survivor - Security", - "Survivor - Prisoner", - "Survivor - Prisoner", - "Survivor - Gang Leader", - "Survivor - Engineer" - ) - if(MAP_LV_624,MAP_BIG_RED,MAP_DESERT_DAM,MAP_KUTJEVO) - survivor_types = list( - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Chef", - "Survivor - Chaplain", - "Survivor - Miner", - "Survivor - Engineer", - "Survivor - Trucker", - "Survivor - Colonial Marshall", - ) - if(MAP_ICE_COLONY) - survivor_types = list( - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Security", - "Survivor - Trucker", - "Survivor - Engineer" - ) - if (MAP_SOROKYNE_STRATA) - survivor_types = list( - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Security", - "Survivor - Engineer" - ) - if(MAP_CORSAT) - survivor_types = list( - "Survivor - Scientist", - "Survivor - Scientist", - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Security", - "Survivor - Corporate Liaison", - "Survivor - Engineer" - ) - else - survivor_types = list( - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Chef", - "Survivor - Chaplain", - "Survivor - Miner", - "Survivor - Colonial Marshall", - "Survivor - Engineer" - ) //Give them proper jobs and stuff here later var/randjob = pick(survivor_types) @@ -764,15 +705,7 @@ Additional game mode variables. else spawn(4) to_chat(H, "

You are a survivor!

") - switch(map_tag) - if(MAP_PRISON_STATION) - to_chat(H, SPAN_NOTICE(" You are a survivor of the attack on Fiorina Orbital Penitentiary. You worked or lived on the prison station, and managed to avoid the alien attacks... until now.")) - if(MAP_CORSAT) - to_chat(H, SPAN_NOTICE("You are a survivor of the containment breach on the Corporate Orbital Research Station for Advanced Technology (CORSAT). You worked or lived on the station, and managed to avoid the alien attacks... until now.")) - if(MAP_ICE_COLONY) - to_chat(H, SPAN_NOTICE("You are a survivor of the attack on the ice habitat. You worked or lived on the colony, and managed to avoid the alien attacks... until now.")) - else - to_chat(H, SPAN_NOTICE("You are a survivor of the attack on the colony. You worked or lived in the archaeology colony, and managed to avoid the alien attacks... until now.")) + to_chat(H, SPAN_NOTICE(SSmapping.configs[GROUND_MAP].survivor_message)) to_chat(H, SPAN_NOTICE("You are fully aware of the xenomorph threat and are able to use this knowledge as you see fit.")) to_chat(H, SPAN_NOTICE("You are NOT aware of the marines or their intentions. ")) if(spawner.story_text) @@ -797,15 +730,7 @@ Additional game mode variables. new /datum/cm_objective/move_mob/almayer/survivor(H) spawn(4) to_chat(H, "

You are a survivor!

") - switch(map_tag) - if(MAP_PRISON_STATION) - to_chat(H, SPAN_NOTICE("You are a survivor of the attack on Fiorina Orbital Penitentiary. You worked or lived on the prison station, and managed to avoid the alien attacks.. until now.")) - if(MAP_CORSAT) - to_chat(H, SPAN_NOTICE("You are a survivor of the containment breach on the Corporate Orbital Research Station for Advanced Technology (CORSAT). You worked or lived on the station, and managed to avoid the alien attacks... until now.")) - if(MAP_ICE_COLONY) - to_chat(H, SPAN_NOTICE("You are a survivor of the attack on the ice habitat. You worked or lived on the colony, and managed to avoid the alien attacks.. until now.")) - else - to_chat(H, SPAN_NOTICE("You are a survivor of the attack on the colony. You worked or lived in the archaeology colony, and managed to avoid the alien attacks...until now.")) + to_chat(H, SPAN_NOTICE(SSmapping.configs[GROUND_MAP].survivor_message)) to_chat(H, SPAN_NOTICE("You are fully aware of the xenomorph threat and are able to use this knowledge as you see fit.")) to_chat(H, SPAN_NOTICE("You are NOT aware of the marines or their intentions.")) return 1 diff --git a/code/game/gamemodes/cm_process.dm b/code/game/gamemodes/cm_process.dm index a6f6def098ad..a1f97a521e20 100644 --- a/code/game/gamemodes/cm_process.dm +++ b/code/game/gamemodes/cm_process.dm @@ -211,7 +211,7 @@ var/nextAdminBioscan = MINUTES_30//30 minutes in var/atom/where = M if (where == 0 && M.loc) where = M.loc - if(where.z in SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBITT))) + if(where.z in SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBIT))) numXenosPlanet++ xenosPlanetLocations+=where else if(is_mainship_level(where.z)) @@ -225,7 +225,7 @@ var/nextAdminBioscan = MINUTES_30//30 minutes in var/atom/where = M if (where == 0 && M.loc) where = M.loc - if(where.z in SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBITT))) + if(where.z in SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBIT))) numHostsPlanet++ hostsPlanetLocations += where else if(is_mainship_level(where.z)) @@ -308,7 +308,7 @@ Can't be in a locker, in space, in the thunderdome, or distress. Only checks living mobs with a client attached. */ -/datum/game_mode/proc/count_xenos(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBITT, ZTRAIT_MARINE_MAIN_SHIP))) +/datum/game_mode/proc/count_xenos(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBIT, ZTRAIT_MARINE_MAIN_SHIP))) var/num_xenos = 0 for(var/i in GLOB.living_xeno_list) var/mob/M = i @@ -316,7 +316,7 @@ Only checks living mobs with a client attached. num_xenos++ return num_xenos -/datum/game_mode/proc/count_humans_and_xenos(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBITT, ZTRAIT_MARINE_MAIN_SHIP))) +/datum/game_mode/proc/count_humans_and_xenos(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBIT, ZTRAIT_MARINE_MAIN_SHIP))) var/num_humans = 0 var/num_xenos = 0 @@ -339,7 +339,7 @@ Only checks living mobs with a client attached. return list(num_humans,num_xenos) -/datum/game_mode/proc/count_marines_and_pmcs(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBITT, ZTRAIT_MARINE_MAIN_SHIP))) +/datum/game_mode/proc/count_marines_and_pmcs(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBIT, ZTRAIT_MARINE_MAIN_SHIP))) var/num_marines = 0 var/num_pmcs = 0 @@ -353,7 +353,7 @@ Only checks living mobs with a client attached. return list(num_marines,num_pmcs) -/datum/game_mode/proc/count_marines(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBITT, ZTRAIT_MARINE_MAIN_SHIP))) +/datum/game_mode/proc/count_marines(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBIT, ZTRAIT_MARINE_MAIN_SHIP))) var/num_marines = 0 for(var/i in GLOB.alive_human_list) diff --git a/code/game/gamemodes/cm_self_destruct.dm b/code/game/gamemodes/cm_self_destruct.dm index 8cafded6bbae..5997cd352408 100644 --- a/code/game/gamemodes/cm_self_destruct.dm +++ b/code/game/gamemodes/cm_self_destruct.dm @@ -78,10 +78,10 @@ var/global/datum/authority/branch/evacuation/EvacuationAuthority //This is initi /datum/authority/branch/evacuation/proc/get_affected_zlevels() //This proc returns the ship's z level list (or whatever specified), when an evac/self destruct happens. if(dest_status < NUKE_EXPLOSION_IN_PROGRESS && evac_status == EVACUATION_STATUS_COMPLETE) //Nuke is not in progress and evacuation finished, end the round on ship and low orbit (dropships in transit) only. - . = SSmapping.levels_by_any_trait(list(ZTRAIT_MARINE_MAIN_SHIP, ZTRAIT_LOWORBITT)) + . = SSmapping.levels_by_any_trait(list(ZTRAIT_MARINE_MAIN_SHIP, ZTRAIT_LOWORBIT)) else if(SSticker.mode && SSticker.mode.is_in_endgame) - . = SSmapping.levels_by_any_trait(list(ZTRAIT_MARINE_MAIN_SHIP, ZTRAIT_LOWORBITT)) + . = SSmapping.levels_by_any_trait(list(ZTRAIT_MARINE_MAIN_SHIP, ZTRAIT_LOWORBIT)) //========================================================================================= //========================================================================================= diff --git a/code/game/gamemodes/colonialmarines/colonialmarines.dm b/code/game/gamemodes/colonialmarines/colonialmarines.dm index a98497272d82..59da44d044db 100644 --- a/code/game/gamemodes/colonialmarines/colonialmarines.dm +++ b/code/game/gamemodes/colonialmarines/colonialmarines.dm @@ -16,7 +16,7 @@ return TRUE /datum/game_mode/colonialmarines/announce() - to_world("The current map is - [map_tag]!") + to_world("The current map is - [SSmapping.configs[GROUND_MAP].map_name]!") //////////////////////////////////////////////////////////////////////////////////////// //Temporary, until we sort this out properly. @@ -63,19 +63,12 @@ QDEL_LIST(GLOB.good_items) // Spawn gamemode-specific map items - for(var/i in GLOB.map_items) - var/turf/T = get_turf(i) - qdel(i) - switch(map_tag) - if(MAP_LV_624) new /obj/item/map/lazarus_landing_map(T) - if(MAP_ICE_COLONY) new /obj/item/map/ice_colony_map(T) - if(MAP_BIG_RED) new /obj/item/map/big_red_map(T) - if(MAP_PRISON_STATION) new /obj/item/map/FOP_map(T) - if(MAP_DESERT_DAM) new /obj/item/map/desert_dam(T) - if(MAP_WHISKEY_OUTPOST) new /obj/item/map/whiskey_outpost_map(T) - if(MAP_SOROKYNE_STRATA) new /obj/item/map/sorokyne_map(T) - if(MAP_CORSAT) new /obj/item/map/corsat(T) - if(MAP_KUTJEVO) new /obj/item/map/kutjevo_map(T) + if(SSmapping.configs[GROUND_MAP].map_item_type) + var/type_to_spawn = SSmapping.configs[GROUND_MAP].map_item_type + for(var/i in GLOB.map_items) + var/turf/T = get_turf(i) + qdel(i) + new type_to_spawn(T) if(!round_fog.len) round_fog = null //No blockers? @@ -125,25 +118,7 @@ if(!marines_assigned) return - switch(map_tag) - if(MAP_LV_624) - monkey_types = list(/mob/living/carbon/human/farwa, /mob/living/carbon/human/monkey, /mob/living/carbon/human/neaera, /mob/living/carbon/human/stok) - if(MAP_ICE_COLONY) - monkey_types = list(/mob/living/carbon/human/yiren) - if(MAP_BIG_RED) - monkey_types = list(/mob/living/carbon/human/neaera) - if(MAP_KUTJEVO) - monkey_types = list(/mob/living/carbon/human/neaera, /mob/living/carbon/human/stok) - if(MAP_PRISON_STATION) - monkey_types = list(/mob/living/carbon/human/monkey) - if(MAP_DESERT_DAM) - monkey_types = list(/mob/living/carbon/human/stok) - if(MAP_SOROKYNE_STRATA) - monkey_types = list(/mob/living/carbon/human/yiren) - if(MAP_CORSAT) - monkey_types = list(/mob/living/carbon/human/yiren, /mob/living/carbon/human/farwa, /mob/living/carbon/human/monkey, /mob/living/carbon/human/neaera, /mob/living/carbon/human/stok) - else - monkey_types = list(/mob/living/carbon/human/monkey) //make sure we always have a monkey type + monkey_types = SSmapping.configs[GROUND_MAP].monkey_types if(!length(monkey_types)) return @@ -161,23 +136,8 @@ shipwide_ai_announcement(input, name, 'sound/AI/ares_online.ogg') /datum/game_mode/colonialmarines/proc/map_announcement() - switch(map_tag) - if(MAP_LV_624) - marine_announcement("An automated distress signal has been received from archaeology site Lazarus Landing, on border world LV-624. A response team from the [MAIN_SHIP_NAME] will be dispatched shortly to investigate.", "[MAIN_SHIP_NAME]") - if(MAP_ICE_COLONY) - marine_announcement("An automated distress signal has been received from archaeology site \"Shiva's Snowball\", on border ice world \"Ifrit\". A response team from the [MAIN_SHIP_NAME] will be dispatched shortly to investigate.", "[MAIN_SHIP_NAME]") - if(MAP_BIG_RED) - marine_announcement("We've lost contact with the Weston-Yamada's research facility, [map_tag]. The [MAIN_SHIP_NAME] has been dispatched to assist.", "[MAIN_SHIP_NAME]") - if(MAP_PRISON_STATION) - marine_announcement("An automated distress signal has been received from maximum-security prison \"Fiorina Orbital Penitentiary\". A response team from the [MAIN_SHIP_NAME] will be dispatched shortly to investigate.", "[MAIN_SHIP_NAME]") - if(MAP_DESERT_DAM) - marine_announcement("We've lost contact with Weston-Yamada's extra-solar colony, \"[map_tag]\", on the planet \"Navarone.\" The [MAIN_SHIP_NAME] has been dispatched to assist.", "[MAIN_SHIP_NAME]") - if (MAP_SOROKYNE_STRATA) - marine_announcement("An automated distress signal has been recieved from a mining colony on border world LV-976, \"Sorokyne Outpost\". A response team from the [MAIN_SHIP_NAME] will be dispatched shortly to investigate.", "[MAIN_SHIP_NAME]") - if (MAP_CORSAT) - marine_announcement("An automated distress signal has been received from Weston-Yamada's Corporate Orbital Research Station for Advanced Technology, or CORSAT. The [MAIN_SHIP_NAME] has been dispatched to investigate.", "[MAIN_SHIP_NAME]") - if (MAP_KUTJEVO) - marine_announcement("An automated distress signal has been received from Weston-Yamada colony Kutjevo Refinery, known for botanical research, export, and raw materials processing and refinement. The [MAIN_SHIP_NAME] has been dispatched to investigate.", "[MAIN_SHIP_NAME]") + if(SSmapping.configs[GROUND_MAP].announce_text) + marine_announcement(SSmapping.configs[GROUND_MAP].announce_text, "[MAIN_SHIP_NAME]") //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// @@ -207,9 +167,9 @@ bioscan_current_interval += bioscan_ongoing_interval //Add to the interval based on our set interval time. if(++round_checkwin >= 5) //Only check win conditions every 5 ticks. - if(flags_round_type & MODE_FOG_ACTIVATED && map_tag == MAP_LV_624 && world.time >= (FOG_DELAY_INTERVAL + SSticker.round_start_time)) + if(flags_round_type & MODE_FOG_ACTIVATED && SSmapping.configs[GROUND_MAP].environment_traits[ZTRAIT_FOG] && world.time >= (FOG_DELAY_INTERVAL + SSticker.round_start_time)) disperse_fog() //Some RNG thrown in. - if(!(round_status_flags & ROUNDSTATUS_PODDOORS_OPEN) && (map_tag == MAP_CORSAT || map_tag == MAP_PRISON_STATION) && world.time >= (PODLOCKS_OPEN_WAIT + round_time_lobby)) + if(!(round_status_flags & ROUNDSTATUS_PODDOORS_OPEN) && SSmapping.configs[GROUND_MAP].environment_traits[ZTRAIT_LOCKDOWN] && world.time >= (PODLOCKS_OPEN_WAIT + round_time_lobby)) round_status_flags |= ROUNDSTATUS_PODDOORS_OPEN var/input = "Security lockdown will be lifting in 30 seconds per automated lockdown protocol." diff --git a/code/game/gamemodes/colonialmarines/whiskey_outpost.dm b/code/game/gamemodes/colonialmarines/whiskey_outpost.dm index 40d267f79e68..e49c4ad49a2e 100644 --- a/code/game/gamemodes/colonialmarines/whiskey_outpost.dm +++ b/code/game/gamemodes/colonialmarines/whiskey_outpost.dm @@ -2,7 +2,7 @@ //Global proc for checking if the game is whiskey outpost so I dont need to type if(gamemode == whiskey outpost) 50000 times /proc/Check_WO() - if(SSticker.mode == "Whiskey Outpost" || map_tag == "Whiskey Outpost" || master_mode == "Whiskey Outpost") + if(SSticker.mode == "Whiskey Outpost" || master_mode == "Whiskey Outpost") return 1 return 0 @@ -71,6 +71,8 @@ var/list/whiskey_outpost_waves = list() + hardcore = TRUE + /datum/game_mode/whiskey_outpost/announce() return 1 @@ -112,15 +114,15 @@ to_world("The current game mode is - WHISKEY OUTPOST!") to_world(SPAN_ROUNDBODY("It is the year [game_year - 5] on the planet LV-624, five years before the arrival of the USS Almayer and the 7th 'Falling Falcons' Battalion in the sector")) to_world(SPAN_ROUNDBODY("The 3rd 'Dust Raiders' Battalion is charged with establishing a USCM prescence in the Tychon's Rift sector")) - to_world(SPAN_ROUNDBODY("[map_tag], one of the Dust Raider bases being established in the sector, has come under attack from unrecognized alien forces")) - to_world(SPAN_ROUNDBODY("With casualties mounting and supplies running thin, the Dust Raiders at [map_tag] must survive for an hour to alert the rest of their battalion in the sector")) + to_world(SPAN_ROUNDBODY("[SSmapping.configs[GROUND_MAP].map_name], one of the Dust Raider bases being established in the sector, has come under attack from unrecognized alien forces")) + to_world(SPAN_ROUNDBODY("With casualties mounting and supplies running thin, the Dust Raiders at [SSmapping.configs[GROUND_MAP].map_name] must survive for an hour to alert the rest of their battalion in the sector")) to_world(SPAN_ROUNDBODY("Hold out for as long as you can.")) world << sound('sound/effects/siren.ogg') sleep(10) switch(map_locale) //Switching it up. if(0) - marine_announcement("This is Captain Hans Naiche, commander of the 3rd Battalion 'Dust Raiders' forces here on LV-624. In our attempts to establish a base on this planet, several of our patrols were wiped out by hostile creatures. We're setting up a distress call, but we need you to hold [map_tag] in order for our engineers to set up the relay. We're prepping several M402 mortar units to provide fire support. If they overrun your positon, we will be wiped out with no way to call for help. Hold the line or we all die.", "Captain Naich, 3rd Battalion Command, LV-624 Garrison") + marine_announcement("This is Captain Hans Naiche, commander of the 3rd Battalion 'Dust Raiders' forces here on LV-624. In our attempts to establish a base on this planet, several of our patrols were wiped out by hostile creatures. We're setting up a distress call, but we need you to hold [SSmapping.configs[GROUND_MAP].map_name] in order for our engineers to set up the relay. We're prepping several M402 mortar units to provide fire support. If they overrun your positon, we will be wiped out with no way to call for help. Hold the line or we all die.", "Captain Naich, 3rd Battalion Command, LV-624 Garrison") return ..() @@ -565,7 +567,7 @@ to_chat(user, "Toss it to get supplies!") return - if(user.z != 1) + if(!is_ground_level(user.z)) to_chat(user, "You have to be on the ground to use this or it won't transmit.") return @@ -682,4 +684,4 @@ var/turf/T = get_turf(src) if(T) new /obj/item/paper/crumpled(T) - qdel(src) \ No newline at end of file + qdel(src) diff --git a/code/game/gamemodes/colonialmarines/xenovsxeno.dm b/code/game/gamemodes/colonialmarines/xenovsxeno.dm index ba232c1665cb..60a771ebe012 100644 --- a/code/game/gamemodes/colonialmarines/xenovsxeno.dm +++ b/code/game/gamemodes/colonialmarines/xenovsxeno.dm @@ -72,14 +72,14 @@ /* Pre-pre-startup */ /datum/game_mode/xenovs/can_start() - setup_mapdata(map_tag) + setup_mapdata(SSmapping.configs[GROUND_MAP].map_name) xeno_starting_num = readied_players if(!initialize_starting_xenomorph_list(hives, TRUE)) return return TRUE /datum/game_mode/xenovs/announce() - to_world("The current map is - [map_tag]!") + to_world("The current map is - [SSmapping.configs[GROUND_MAP].map_name]!") /* Pre-setup */ /datum/game_mode/xenovs/pre_setup() @@ -210,7 +210,7 @@ round_checkwin = 0 -/datum/game_mode/xenovs/proc/get_xenos_hive(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBITT, ZTRAIT_MARINE_MAIN_SHIP))) +/datum/game_mode/xenovs/proc/get_xenos_hive(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_LOWORBIT, ZTRAIT_MARINE_MAIN_SHIP))) var/list/list/hivenumbers = list() for(var/datum/hive_status/H in GLOB.hive_datum) hivenumbers += list(H.name = list()) @@ -292,7 +292,7 @@ log_game("Round end result: [round_finished]") to_world("|Round Complete|") - to_world(SPAN_ROUNDBODY("Thus ends the story of the battling hives on [map_tag]. [round_finished]")) + to_world(SPAN_ROUNDBODY("Thus ends the story of the battling hives on [SSmapping.configs[GROUND_MAP].map_name]. [round_finished]")) to_world(SPAN_ROUNDBODY("The game-mode was: [master_mode]!")) to_world(SPAN_ROUNDBODY("End of Round Grief (EORG) is an IMMEDIATE 3 hour ban with no warnings, see rule #3 for more details.")) diff --git a/code/game/gamemodes/events/power_failure.dm b/code/game/gamemodes/events/power_failure.dm index a2372c050b1b..4f8c652fea99 100644 --- a/code/game/gamemodes/events/power_failure.dm +++ b/code/game/gamemodes/events/power_failure.dm @@ -1,7 +1,9 @@ /proc/power_failure(var/announce = 1) + var/ship_zlevels = SSmapping.levels_by_trait(ZTRAIT_MARINE_MAIN_SHIP) + for(var/obj/structure/machinery/power/smes/S in machines) - if(S.z != 3) // Ship only + if(!is_mainship_level(S.z)) continue S.last_charge = S.charge S.last_output = S.output @@ -13,10 +15,10 @@ S.power_change() for(var/obj/structure/machinery/power/apc/C in machines) - if(C.cell && is_mainship_level(C.z)) + if(!is_mainship_level(C.z) && C.cell) C.cell.charge = 0 - playsound_z(SSmapping.levels_by_trait(ZTRAIT_MARINE_MAIN_SHIP), 'sound/effects/powerloss.ogg') + playsound_z(ship_zlevels, 'sound/effects/powerloss.ogg') sleep(100) if(announce) @@ -24,7 +26,7 @@ /proc/power_restore(var/announce = 1) for(var/obj/structure/machinery/power/smes/S in machines) - if(S.z != 3) + if(!is_mainship_level(S.z)) continue S.charge = S.capacity S.output = S.output_level_max @@ -43,7 +45,7 @@ /proc/power_restore_quick(var/announce = 1) for(var/obj/structure/machinery/power/smes/S in machines) - if(S.z != 3) // Ship only + if(!is_mainship_level(S.z)) // Ship only continue S.charge = S.capacity S.output = S.output_level_max diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index e38905ed82bc..521084ce3ea7 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -32,6 +32,8 @@ var/global/cas_tracking_id_increment = 0 //this var used to assign unique tracki var/datum/entity/round_stats/round_stats = null var/list/roles_to_roll + + var/hardcore = FALSE /datum/game_mode/proc/announce() //to be calles when round starts to_world("Notice: [src] did not define announce()") @@ -98,7 +100,7 @@ var/global/cas_tracking_id_increment = 0 //this var used to assign unique tracki log_game("Round end result: [round_finished]") to_world("|Round Complete|") - to_world(SPAN_ROUNDBODY("Thus ends the story of the brave men and women of the [MAIN_SHIP_NAME] and their struggle on [map_tag].")) + to_world(SPAN_ROUNDBODY("Thus ends the story of the brave men and women of the [MAIN_SHIP_NAME] and their struggle on [SSmapping.configs[GROUND_MAP].map_name].")) to_world(SPAN_ROUNDBODY("The game-mode was: [master_mode]!")) to_world(SPAN_ROUNDBODY("End of Round Grief (EORG) is an IMMEDIATE 3 hour ban with no warnings, see rule #3 for more details.")) @@ -209,10 +211,6 @@ var/global/cas_tracking_id_increment = 0 //this var used to assign unique tracki heads += player.mind return heads -/datum/game_mode/New() - if(!map_tag) - to_world("MT001: No mapping tag set, tell a coder. [map_tag]") - ////////////////////////// //Reports player logouts// ////////////////////////// @@ -282,7 +280,7 @@ proc/display_roundstart_logout_report() round_stats.name = operation_name round_stats.real_time_start = world.realtime var/datum/entity/map_stats/new_map = new() - new_map.name = map_tag + new_map.name = SSmapping.configs[GROUND_MAP].map_name new_map.linked_round = round_stats new_map.death_stats_list = round_stats.death_stats_list round_stats.game_mode = name diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm deleted file mode 100644 index 984384ffa070..000000000000 --- a/code/game/gamemodes/gameticker.dm +++ /dev/null @@ -1,311 +0,0 @@ -//var/global/datum/controller/gameticker/ticker = new() - - - -/datum/controller/gameticker - var/const/restart_timeout = 600 - var/current_state = GAME_STATE_PREGAME - - var/hide_mode = FALSE - var/datum/game_mode/mode = null - var/post_game = FALSE - var/event_time = null - var/event = FALSE - - var/login_music // music played in pregame lobby - - var/list/datum/mind/minds = list()//The people in the game. Used for objective tracking. - - var/random_players = 0 // if set to nonzero, ALL players who latejoin or declare-ready join will have random appearances/genders - - var/pregame_timeleft = 0 - var/toweractive = FALSE - var/delay_end = FALSE //if set to nonzero, the round will not restart on it's own - var/automatic_delay_end = FALSE - - var/round_end_announced = FALSE // Spam Prevention. Announce round end only once. - var/datum/mind/liaison = null - -/datum/controller/gameticker/proc/pregame() - login_music = pick( - "sound/music/1.ogg", - "sound/music/2.ogg", - "sound/music/3.ogg", - "sound/music/4.ogg", - "sound/music/5.ogg", - "sound/music/6.ogg") - do - pregame_timeleft = PREROUND_TIME - if(round_statistics) - to_world("
[SPAN_BLUE("[round_statistics.name]")]
") - to_world(SPAN_NOTICE("
Welcome to the pre-game lobby of Colonial Marines!
")) - to_world(SPAN_NOTICE("
Please, setup your character and select ready. Game will start in [pregame_timeleft] seconds.
")) - while(current_state == GAME_STATE_PREGAME) - for(var/i=0, i<10, i++) - sleep(1) - vote.process() - if(going) - pregame_timeleft-- - if(pregame_timeleft == CONFIG_GET(number/vote_autogamemode_timeleft)) - if(!vote.time_remaining) - vote.autogamemode() //Quit calling this over and over and over and over. - while(vote.time_remaining) - for(var/i=0, i<10, i++) - sleep(1) - vote.process() - if(pregame_timeleft <= 0) - current_state = GAME_STATE_SETTING_UP - while (!setup()) - - -/datum/controller/gameticker/proc/setup() - //Create and announce mode - if(master_mode=="secret") - hide_mode = 1 - var/list/datum/game_mode/runnable_modes - if((master_mode=="random") || (master_mode=="secret")) - //runnable_modes = config.get_runnable_modes() - if (runnable_modes.len==0) - current_state = GAME_STATE_PREGAME - to_world("Unable to choose playable game mode. Reverting to pre-game lobby.") - return 0 - if(secret_force_mode != "secret") - var/datum/game_mode/M = config.pick_mode(secret_force_mode) - if(M.can_start()) - mode = config.pick_mode(secret_force_mode) - RoleAuthority.reset_roles() - if(!mode) - mode = pickweight(runnable_modes) - if(mode) - var/mtype = src.mode.type - mode = new mtype - else - if(map_tag == MAP_WHISKEY_OUTPOST) - mode = config.pick_mode("Whiskey Outpost") - RoleAuthority.replace_jobs(src.mode.roles_for_mode) - else - mode = config.pick_mode(master_mode) - if (!mode.can_start()) - to_world("Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby.") - QDEL_NULL(mode) - current_state = GAME_STATE_PREGAME - RoleAuthority.reset_roles() - return 0 - - var/can_continue = src.mode.pre_setup()//Setup special modes - if(!can_continue) - QDEL_NULL(mode) - current_state = GAME_STATE_PREGAME - to_world("Error setting up [master_mode]. Reverting to pre-game lobby.") - RoleAuthority.reset_roles() - return 0 - - if(hide_mode) - var/list/modes = new - for (var/datum/game_mode/M in runnable_modes) - modes+=M.name - modes = sortList(modes) - to_world("The current game mode is - Secret!") - to_world("Possibilities: [english_list(modes)]") - else - src.mode.announce() - - //Configure mode and assign player to special mode stuff - if (!(mode.flags_round_type & MODE_NO_SPAWN)) - if(mode.flags_round_type & MODE_NEW_SPAWN) - var/roles_to_roll = null - if(length(mode.roles_to_roll)) - roles_to_roll = mode.roles_to_roll - RoleAuthority.setup_candidates_and_roles(roles_to_roll) //Distribute jobs - create_characters() // Create and equip characters - else - var/roles_to_roll = null - if(length(mode.roles_to_roll)) - roles_to_roll = mode.roles_to_roll - RoleAuthority.setup_candidates_and_roles(roles_to_roll) //Distribute jobs - old_create_characters() //Create player characters and transfer them - equip_characters() - - collect_minds() - GLOB.data_core.manifest() - - spawn(2) - mode.initialize_emergency_calls() - - current_state = GAME_STATE_PLAYING - - for(var/mob/new_player/np in GLOB.new_player_list) - np.new_player_panel_proc(TRUE) - - run_mapdaemon_batch() - begin_game_recording() - - if((master_mode == "Distress Signal") && SSevents) - SSevents.Initialize() - - //here to initialize the random events nicely at round start - setup_economy() - - shuttle_controller.setup_shuttle_docks() - - spawn(0)//Forking here so we dont have to wait for this to finish - mode.post_setup() - //Cleanup some stuff - if(round_statistics) - to_world(SPAN_BLUE("Welcome to [round_statistics.name]")) - to_world(SPAN_BLUE("Enjoy the game!")) - - if(CONFIG_GET(flag/autooocmute)) - to_world(SPAN_DANGER("The OOC channel has been globally disabled due to round start!")) - ooc_allowed = !( ooc_allowed ) - - supply_controller.process() //Start the supply shuttle regenerating points -- TLE - - Master.SetRunLevel(RUNLEVEL_GAME) - - spawn(MINUTES_5) - for(var/i in GLOB.closet_list) //Set up special equipment for lockers and vendors, depending on gamemode - var/obj/structure/closet/C = i - C.select_gamemode_equipment(mode.type) - for(var/obj/structure/machinery/vending/V in machines) - V.select_gamemode_equipment(mode.type) - - return 1 - -/datum/controller/gameticker/proc/create_characters() - if(!RoleAuthority) - return - - for(var/mob/new_player/player in GLOB.player_list) - if(!player || !player.ready || !player.mind || !player.job) - continue - - INVOKE_ASYNC(src, .proc/spawn_and_equip_char, player) - -/datum/controller/gameticker/proc/spawn_and_equip_char(var/mob/new_player/player) - var/datum/job/J = RoleAuthority.roles_for_mode[player.job] - var/mob/M = J.spawn_in_player(player) - if(istype(M)) - J.equip_job(M) - EquipCustomItems(M) - - if(M.client) - var/client/C = M.client - if(C.player_data && C.player_data.playtime_loaded && length(C.player_data.playtimes) == 0) - msg_admin_niche("NEW PLAYER: [key_name(player, 1, 1, 0)] (?). IP: [player.lastKnownIP], CID: [player.computer_id]") - - QDEL_IN(player, 5) - -/datum/controller/gameticker/proc/old_create_characters() - for(var/mob/new_player/player in GLOB.player_list) - if(!(player && player.ready && player.mind)) - continue - - if(!player.job && !player.mind.roundstart_picked) - continue - - player.create_character() - qdel(player) - -/datum/controller/gameticker/proc/collect_minds() - for(var/mob/living/player in GLOB.alive_mob_list) - if(player.mind) - SSticker.minds += player.mind - -/datum/controller/gameticker/proc/equip_characters() - var/captainless=1 - if(mode && istype(mode,/datum/game_mode/huntergames)) // || istype(mode,/datum/game_mode/whiskey_outpost) - return - - for(var/mob/living/carbon/human/player in GLOB.human_mob_list) - if(player.mind) - if(player.job == "Commanding Officers") - captainless = FALSE - if(player.job) - RoleAuthority.equip_role(player, RoleAuthority.roles_by_name[player.job]) - EquipCustomItems(player) - if(player.client) - var/client/C = player.client - if(C.player_data && C.player_data.playtime_loaded && length(C.player_data.playtimes) == 0) - msg_admin_niche("NEW PLAYER: [key_name(player, 1, 1, 0)] (?). IP: [player.lastKnownIP], CID: [player.computer_id]") - if(captainless) - for(var/mob/M in GLOB.player_list) - if(!istype(M,/mob/new_player)) - to_chat(M, "Marine commanding officer position not forced on anyone.") - -/datum/controller/gameticker/process() - if(current_state != GAME_STATE_PLAYING) - return 0 - - mode.process() - - var/game_finished = 0 - var/mode_finished = 0 - if (CONFIG_GET(flag/continous_rounds)) - if(EvacuationAuthority.dest_status == NUKE_EXPLOSION_FINISHED || EvacuationAuthority.dest_status == NUKE_EXPLOSION_GROUND_FINISHED) game_finished = 1 - mode_finished = (!post_game && mode.check_finished()) - else - game_finished = (mode.check_finished() /* || (emergency_shuttle.returned() && emergency_shuttle.evac == 1)*/) - mode_finished = game_finished - - if(!EvacuationAuthority.dest_status != NUKE_EXPLOSION_IN_PROGRESS && game_finished && (mode_finished || post_game)) - current_state = GAME_STATE_FINISHED - - spawn(1) - declare_completion() - - spawn(50) - end_game_recording() - - if (EvacuationAuthority.dest_status == NUKE_EXPLOSION_FINISHED || EvacuationAuthority.dest_status == NUKE_EXPLOSION_GROUND_FINISHED) - log_game("Round ended by nuke") - else - log_game("Round ended by proper completion") - - if(CONFIG_GET(flag/autooocmute) && !ooc_allowed) - to_world(SPAN_DANGER("The OOC channel has been globally enabled due to round end!")) - ooc_allowed = 1 - - if(!delay_end && !automatic_delay_end) - sleep(restart_timeout) - if(!delay_end && !automatic_delay_end) - world.Reboot() - else - to_world({"
- [SPAN_CENTERBOLD("An admin has delayed the round end.")] -
- "}) - else - to_world({"
- [SPAN_CENTERBOLD("An admin has delayed the round end.")] -
- "}) - - else if (mode_finished) - post_game = TRUE - - mode.cleanup() - - //call a transfer shuttle vote - spawn(50) - if(!round_end_announced) // Spam Prevention. Now it should announce only once. - to_world(SPAN_WARNING("The round has ended!")) - round_end_announced = TRUE - - return 1 - -/datum/controller/gameticker/proc/calculate_end_statistics() - mode.calculate_end_statistics() - -/datum/controller/gameticker/proc/declare_completion() - mode.declare_completion()//To declare normal completion. - - //calls auto_declare_completion_* for all modes - for(var/handler in typesof(/datum/game_mode/proc)) - if (findtext("[handler]","auto_declare_completion_")) - call(mode, handler)() - - return 1 - -/world/proc/has_round_started() - return SSticker.current_state >= GAME_STATE_PLAYING diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 0e33052b4f5a..335bf8193db7 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -46,26 +46,29 @@ /obj/proc/check_access(obj/item/I) //These generations have been moved out of /obj/New() because they were slowing down the creation of objects that never even used the access system. gen_access() - var/i if(!islist(req_access)) return 1//something's very wrong var/L[] = req_access if(!L.len && (!req_one_access || !req_one_access.len)) return 1//no requirements if(!I) return - var/A[] = I.GetAccess() - for(i in req_access) - if(!(i in A)) return//doesn't have this access + var/list/A = I.GetAccess() + for(var/i in req_access) + if(!(i in A)) + return FALSE//doesn't have this access if(req_one_access && req_one_access.len) - for(i in req_one_access) - if(i in A) return 1//has an access from the single access list - return - return 1 + for(var/i in req_one_access) + if(i in A) + return TRUE//has an access from the single access list + return FALSE + return TRUE /obj/proc/check_access_list(L[]) gen_access() if(!req_access && !req_one_access) return 1 if(!islist(req_access)) return 1 + if(!req_access.len && !islist(req_one_access)) + return TRUE if(!req_access.len && (!req_one_access || !req_one_access.len)) return 1 if(!islist(L)) return var/i diff --git a/code/game/jobs/job/civilians/other/survivors.dm b/code/game/jobs/job/civilians/other/survivors.dm index 84092e545cec..d49047b42620 100644 --- a/code/game/jobs/job/civilians/other/survivors.dm +++ b/code/game/jobs/job/civilians/other/survivors.dm @@ -47,15 +47,7 @@ to_chat(H, line) else to_chat(H, "

You are a survivor!

") - switch(map_tag) - if(MAP_PRISON_STATION) - to_chat(H, SPAN_NOTICE(" You are a survivor of the attack on Fiorina Orbital Penitentiary. You worked or lived on the prison station, and managed to avoid the alien attacks... until now.")) - if(MAP_CORSAT) - to_chat(H, SPAN_NOTICE("You are a survivor of the containment breach on the Corporate Orbital Research Station for Advanced Technology (CORSAT). You worked or lived on the station, and managed to avoid the alien attacks... until now.")) - if(MAP_ICE_COLONY) - to_chat(H, SPAN_NOTICE("You are a survivor of the attack on the ice habitat. You worked or lived on the colony, and managed to avoid the alien attacks... until now.")) - else - to_chat(H, SPAN_NOTICE("You are a survivor of the attack on the colony. You worked or lived in the archaeology colony, and managed to avoid the alien attacks... until now.")) + to_chat(H, SPAN_NOTICE(SSmapping.configs[GROUND_MAP].survivor_message)) to_chat(H, SPAN_NOTICE("You are fully aware of the xenomorph threat and are able to use this knowledge as you see fit.")) to_chat(H, SPAN_NOTICE("You are NOT aware of the marines or their intentions. ")) @@ -104,66 +96,7 @@ return TRUE /datum/job/civilian/survivor/proc/survivor_old_equipment(var/mob/living/carbon/human/H) - var/list/survivor_types - switch(map_tag) - if(MAP_PRISON_STATION) - survivor_types = list( - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Corporate Liaison", - "Survivor - Security", - "Survivor - Prisoner", - "Survivor - Prisoner", - "Survivor - Gang Leader", - "Survivor - Engineer" - ) - if(MAP_LV_624, MAP_BIG_RED,MAP_DESERT_DAM, MAP_KUTJEVO) - survivor_types = list( - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Chef", - "Survivor - Chaplain", - "Survivor - Miner", - "Survivor - Engineer", - "Survivor - Trucker", - "Survivor - Colonial Marshall", - ) - if(MAP_ICE_COLONY) - survivor_types = list( - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Security", - "Survivor - Trucker", - "Survivor - Engineer" - ) - if (MAP_SOROKYNE_STRATA) - survivor_types = list( - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Security", - "Survivor - Engineer" - ) - if(MAP_CORSAT) - survivor_types = list( - "Survivor - Scientist", - "Survivor - Scientist", - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Security", - "Survivor - Corporate Liaison", - "Survivor - Engineer" - ) - else - survivor_types = list( - "Survivor - Scientist", - "Survivor - Doctor", - "Survivor - Chef", - "Survivor - Chaplain", - "Survivor - Miner", - "Survivor - Colonial Marshall", - "Survivor - Engineer" - ) - + var/list/survivor_types = SSmapping.configs[GROUND_MAP].survivor_types arm_equipment(H, pick(survivor_types), FALSE, TRUE) /datum/job/civilian/survivor/synth diff --git a/code/game/jobs/job/command/auxiliary/senior.dm b/code/game/jobs/job/command/auxiliary/senior.dm index 0d0504b0aeb3..d83bd927208e 100644 --- a/code/game/jobs/job/command/auxiliary/senior.dm +++ b/code/game/jobs/job/command/auxiliary/senior.dm @@ -9,7 +9,7 @@ return ..() /datum/job/command/senior/announce_entry_message(mob/living/carbon/human/H) - if(flags_startup_parameters & ROLE_ADD_TO_MODE && map_tag != MAP_WHISKEY_OUTPOST) + if(flags_startup_parameters & ROLE_ADD_TO_MODE && SSmapping.configs[GROUND_MAP].map_name != MAP_WHISKEY_OUTPOST) addtimer(CALLBACK(GLOBAL_PROC, .proc/ai_announcement, "Attention all hands, [H.get_paygrade(0)] [H.real_name] on deck!"), 1.5 SECONDS) ..() diff --git a/code/game/jobs/job/command/cic/captain.dm b/code/game/jobs/job/command/cic/captain.dm index 209076456ad6..e6bfdaac88aa 100644 --- a/code/game/jobs/job/command/cic/captain.dm +++ b/code/game/jobs/job/command/cic/captain.dm @@ -32,7 +32,7 @@ return ..() /datum/job/command/commander/announce_entry_message(mob/living/carbon/human/H) - if(flags_startup_parameters & ROLE_ADD_TO_MODE && map_tag != MAP_WHISKEY_OUTPOST) + if(flags_startup_parameters & ROLE_ADD_TO_MODE && SSmapping.configs[GROUND_MAP].map_name != MAP_WHISKEY_OUTPOST) addtimer(CALLBACK(src, .proc/do_announce_entry_message, H), 1.5 SECONDS) ..() diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index d6099193ac85..ca7c74bed6af 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -25,8 +25,8 @@ var/obj/structure/machinery/computer/operating/computer = null -/obj/structure/machinery/optable/New() - ..() +/obj/structure/machinery/optable/Initialize() + . = ..() for(dir in list(NORTH,EAST,SOUTH,WEST)) computer = locate(/obj/structure/machinery/computer/operating, get_step(src, dir)) if (computer) diff --git a/code/game/machinery/air_alarm.dm b/code/game/machinery/air_alarm.dm index ad7da7cc760c..f4c736ae1380 100644 --- a/code/game/machinery/air_alarm.dm +++ b/code/game/machinery/air_alarm.dm @@ -108,8 +108,8 @@ -/obj/structure/machinery/alarm/New(var/loc, var/direction, var/building = 0) - ..() +/obj/structure/machinery/alarm/Initialize(mapload, var/direction, var/building = 0) + . = ..() if(building) if(loc) diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 77b03b530f68..4fd658b81998 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -31,12 +31,13 @@ unslashable = TRUE unacidable = TRUE - New(loc, laser_name) - ..() - if(!c_tag && laser_name) - var/area/A = get_area(src) - c_tag = "[laser_name] ([A.name])" +/obj/structure/machinery/camera/laser_cam/Initialize(mapload, laser_name) + . = ..() + if(!c_tag && laser_name) + var/area/A = get_area(src) + c_tag = "[laser_name] ([A.name])" +/obj/structure/machinery/camera/laser_cam emp_act(severity) return //immune to EMPs, just in case @@ -46,8 +47,8 @@ // ALL UPGRADES -/obj/structure/machinery/camera/all/New() - ..() +/obj/structure/machinery/camera/all/Initialize(mapload, ...) + . = ..() upgradeEmpProof() upgradeXRay() upgradeMotion() @@ -72,19 +73,18 @@ var/number = 0 //camera number in area //This camera type automatically sets it's name to whatever the area that it's in is called. -/obj/structure/machinery/camera/autoname/New() - ..() - spawn(10) - number = 1 - var/area/A = get_area(src) - if(A) - for(var/obj/structure/machinery/camera/autoname/C in machines) - if(C == src) continue - var/area/CA = get_area(C) - if(CA.type == A.type) - if(C.number) - number = max(number, C.number+1) - c_tag = "[A.name] #[number]" +/obj/structure/machinery/camera/autoname/Initialize(mapload, ...) + . = ..() + number = 1 + var/area/A = get_area(src) + if(A) + for(var/obj/structure/machinery/camera/autoname/C in machines) + if(C == src) continue + var/area/CA = get_area(C) + if(CA.type == A.type) + if(C.number) + number = max(number, C.number+1) + c_tag = "[A.name] #[number]" //cameras installed inside the dropships, accessible via both cockpit monitor and Almayer camera computers /obj/structure/machinery/camera/autoname/almayer/dropship_one @@ -102,7 +102,7 @@ unslashable = TRUE unacidable = TRUE network = list("almayer", "containment") - + /obj/structure/machinery/camera/autoname/almayer/containment/attack_alien(mob/living/carbon/Xenomorph/M) return @@ -182,4 +182,4 @@ network = list("security_cameras") /obj/structure/machinery/camera/autoname/dam/medical_cameras - network = list("medical_cameras") \ No newline at end of file + network = list("medical_cameras") diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 250c88c8b7a5..96234652c8a7 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -9,8 +9,8 @@ //Disk stuff. -/obj/item/disk/data/New() - ..() +/obj/item/disk/data/Initialize() + . = ..() var/diskcolor = pick(0,1,2) src.icon_state = "datadisk[diskcolor]" @@ -49,8 +49,8 @@ name = "Diskette Box" icon_state = "disk_kit" -/obj/item/storage/box/disks/New() - ..() +/obj/item/storage/box/disks/Initialize() + . = ..() new /obj/item/disk/data(src) new /obj/item/disk/data(src) new /obj/item/disk/data(src) diff --git a/code/game/machinery/computer/area_air_control.dm b/code/game/machinery/computer/area_air_control.dm index a841d4f0a2f3..ee0caf97f4c0 100644 --- a/code/game/machinery/computer/area_air_control.dm +++ b/code/game/machinery/computer/area_air_control.dm @@ -175,4 +175,4 @@ if(!found) status = "ERROR: No scrubber found!" - src.updateUsrDialog() \ No newline at end of file + src.updateUsrDialog() diff --git a/code/game/machinery/computer/camera_console.dm b/code/game/machinery/computer/camera_console.dm index 52fcd375018d..5f8fa74b796d 100644 --- a/code/game/machinery/computer/camera_console.dm +++ b/code/game/machinery/computer/camera_console.dm @@ -46,8 +46,8 @@ return attack_hand(user) /obj/structure/machinery/computer/security/attack_hand(mob/user) - if(z > 6) - to_chat(user, SPAN_DANGER("Unable to establish a connection: \black You're too far away from the station!")) + if(is_admin_level(z)) + to_chat(user, SPAN_DANGER("Unable to establish a connection: \black You're too far away from the ship!")) return if(inoperable()) return diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 5d5324065df4..0f170df56c66 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -13,8 +13,8 @@ var/processing = FALSE //Set to true if computer needs to do /process() var/exproof = 0 -/obj/structure/machinery/computer/New() - ..() +/obj/structure/machinery/computer/Initialize() + . = ..() if(processing) start_processing() diff --git a/code/game/machinery/computer/emails.dm b/code/game/machinery/computer/emails.dm index 67abb8b006e2..fe895788366e 100644 --- a/code/game/machinery/computer/emails.dm +++ b/code/game/machinery/computer/emails.dm @@ -12,8 +12,8 @@ var/selected_mail -/obj/structure/machinery/computer/emails/New() - ..() +/obj/structure/machinery/computer/emails/Initialize() + . = ..() email_list = list() var/list/L = typesof(email_type) - email_type var/email_amt = rand(2,4) diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 0684e0f2211e..96973a86cc5c 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -18,8 +18,8 @@ var/mob/living/carbon/occupant = null var/obj/item/reagent_container/glass/beaker = null -/obj/structure/machinery/cryo_cell/New() - ..() +/obj/structure/machinery/cryo_cell/Initialize() + . = ..() start_processing() /obj/structure/machinery/cryo_cell/process() diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 4957285ed57f..70b3b21720a8 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -146,13 +146,12 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_NAME_1 = list(), SQUAD_NAME_2 = list() orient_right = 1 icon_state = "cryo_rear-r" -/obj/structure/cryofeed/New() - +/obj/structure/cryofeed/Initialize() + . = ..() if(orient_right) icon_state = "cryo_rear-r" else icon_state = "cryo_rear" - ..() diff --git a/code/game/machinery/door_display/door_display.dm b/code/game/machinery/door_display/door_display.dm index 1cddfdf51e0c..a88553ff83cb 100644 --- a/code/game/machinery/door_display/door_display.dm +++ b/code/game/machinery/door_display/door_display.dm @@ -21,9 +21,13 @@ maptext_height = 26 maptext_width = 32 -/obj/structure/machinery/door_display/New() - ..() - addtimer(CALLBACK(src, .proc/get_targets)) +/obj/structure/machinery/door_display/Initialize() + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/structure/machinery/door_display/LateInitialize() + . = ..() + get_targets() /obj/structure/machinery/door_display/proc/get_targets() for(var/obj/structure/machinery/door/D in machines) @@ -249,7 +253,7 @@ //Room Divider if(has_wall_divider) data += "
Containment Divider
" - + data += "
Close Display" data += "" @@ -334,4 +338,4 @@ if(D.density) continue INVOKE_ASYNC(D, /obj/structure/machinery/door.proc/close) - return 1 \ No newline at end of file + return 1 diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 83674a6ae47c..cd07d5d21210 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -778,8 +778,8 @@ GLOBAL_LIST_INIT(airlock_wire_descriptions, list( return TRUE return FALSE -/obj/structure/machinery/door/airlock/New() - ..() +/obj/structure/machinery/door/airlock/Initialize() + . = ..() wall_check() @@ -787,12 +787,15 @@ GLOBAL_LIST_INIT(airlock_wire_descriptions, list( var/area/A = get_area(loc) name = A.name + return INITIALIZE_HINT_LATELOAD + +/obj/structure/machinery/door/airlock/LateInitialize() + . = ..() if(closeOtherId != null) - spawn (5) - for(var/obj/structure/machinery/door/airlock/A in machines) - if(A.closeOtherId == closeOtherId && A != src) - closeOther = A - break + for(var/obj/structure/machinery/door/airlock/A in machines) + if(A.closeOtherId == closeOtherId && A != src) + closeOther = A + break // fix smoothing for(var/turf/closed/wall/W in orange(1)) W.update_connections() diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index 227f12074602..54d731675242 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -254,9 +254,13 @@ /obj/structure/window/framed/almayer, /obj/structure/machinery/door/airlock) -/obj/structure/machinery/door/airlock/almayer/New() - addtimer(CALLBACK(src, /atom.proc/relativewall_neighbours), 10) - ..() +/obj/structure/machinery/door/airlock/almayer/Initialize() + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/structure/machinery/door/airlock/almayer/LateInitialize() + . = ..() + relativewall_neighbours() /obj/structure/machinery/door/airlock/almayer/take_damage(var/dam, var/mob/M) var/damage_check = max(0, damage + dam) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 12896ede7a24..b9e61c7b3420 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -45,7 +45,7 @@ "cold" ) -/obj/structure/machinery/door/firedoor/New() +/obj/structure/machinery/door/firedoor/Initialize() . = ..() for(var/obj/structure/machinery/door/firedoor/F in loc) if(F != src) @@ -306,4 +306,4 @@ width = 2 /obj/structure/machinery/door/firedoor/border_only/almayer/antag - req_one_access = list(ACCESS_ILLEGAL_PIRATE) \ No newline at end of file + req_one_access = list(ACCESS_ILLEGAL_PIRATE) diff --git a/code/game/machinery/doors/multi_tile.dm b/code/game/machinery/doors/multi_tile.dm index 6941f5c1f5c2..a7f437034ded 100644 --- a/code/game/machinery/doors/multi_tile.dm +++ b/code/game/machinery/doors/multi_tile.dm @@ -89,9 +89,13 @@ /obj/structure/window/framed/almayer, /obj/structure/machinery/door/airlock) -/obj/structure/machinery/door/airlock/multi_tile/almayer/New() - INVOKE_ASYNC(src, /atom.proc/relativewall_neighbours) - ..() +/obj/structure/machinery/door/airlock/multi_tile/almayer/Initialize() + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/structure/machinery/door/airlock/multi_tile/almayer/LateInitialize() + . = ..() + relativewall_neighbours() /obj/structure/machinery/door/airlock/multi_tile/almayer/take_damage(var/dam, var/mob/M) var/damage_check = max(0, damage + dam) diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index ca9ac8e57416..24f345f7fb74 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -63,7 +63,7 @@ X.visible_message(SPAN_DANGER("[X] pries open [src]."), \ SPAN_XENONOTICE("You pry open [src]."), max_distance = 3) - + open() @@ -232,7 +232,7 @@ dir = NORTH icon = 'icons/obj/structures/doors/1x4blast_vert.dmi' -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened density = FALSE /obj/structure/machinery/door/poddoor/filler_object @@ -247,6 +247,9 @@ unslashable = TRUE unacidable = TRUE +/obj/structure/machinery/door/poddoor/two_tile/four_tile/secure/opened + density = FALSE + /obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/secure icon = 'icons/obj/structures/doors/1x4blast_vert_secure.dmi' openspeed = 17 @@ -295,4 +298,4 @@ /obj/structure/machinery/door/poddoor/almayer/closed density = TRUE - opacity = TRUE \ No newline at end of file + opacity = TRUE diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 021d51c539eb..9126456cf5cb 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -13,9 +13,9 @@ var/obj/item/circuitboard/airlock/electronics = null air_properties_vary_with_direction = 1 -/obj/structure/machinery/door/window/New() +/obj/structure/machinery/door/window/Initialize() . = ..() - addtimer(CALLBACK(src, .proc/update_icon), 0) + addtimer(CALLBACK(src, .proc/update_icon), 1) if (src.req_access && src.req_access.len) src.icon_state = "[src.icon_state]" src.base_state = src.icon_state diff --git a/code/game/machinery/fire_alarm.dm b/code/game/machinery/fire_alarm.dm index 7dafb8ad1f89..1de223d00d89 100644 --- a/code/game/machinery/fire_alarm.dm +++ b/code/game/machinery/fire_alarm.dm @@ -220,11 +220,8 @@ FIRE ALARM //playsound(src.loc, 'sound/ambience/signal.ogg', 50, 0) return -/obj/structure/machinery/firealarm/New(loc, dir, building) - ..() - - if(loc) - src.forceMove(loc) +/obj/structure/machinery/firealarm/Initialize(mapload, dir, building) + . = ..() if(dir) src.dir = dir diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 8b73ae43807d..6193d46cb13e 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -12,19 +12,18 @@ var/otherarea = null // luminosity = 1 -/obj/structure/machinery/light_switch/New() - ..() - spawn(5) - src.area = src.loc.loc +/obj/structure/machinery/light_switch/Initialize() + . = ..() + src.area = src.loc.loc - if(otherarea) - src.area = locate(text2path("/area/[otherarea]")) + if(otherarea) + src.area = locate(text2path("/area/[otherarea]")) - if(!name) - name = "light switch ([area.name])" + if(!name) + name = "light switch ([area.name])" - src.on = src.area.lightswitch - updateicon() + src.on = src.area.lightswitch + updateicon() diff --git a/code/game/machinery/line_nexter.dm b/code/game/machinery/line_nexter.dm index 48109f160b36..b1798124910c 100644 --- a/code/game/machinery/line_nexter.dm +++ b/code/game/machinery/line_nexter.dm @@ -11,8 +11,8 @@ var/last_use var/id -/obj/structure/machinery/line_nexter/New() - ..() +/obj/structure/machinery/line_nexter/Initialize() + . = ..() last_use = world.time /obj/structure/machinery/line_nexter/initialize_pass_flags(var/datum/pass_flags_container/PF) @@ -33,7 +33,7 @@ /obj/structure/machinery/line_nexter/proc/next() //if((last_use + 20) > world.time) // 20 seconds - for(var/mob/living/carbon/human/H in locate(x,y,z)) + for(var/mob/living/carbon/human/H in loc) step(H,dir) last_use = world.time diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index e71848a719c4..a78054bd5923 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -99,8 +99,8 @@ Class Procs: projectile_coverage = PROJECTILE_COVERAGE_MEDIUM var/power_machine = FALSE //Whether the machine should process on power, or normal processor -/obj/structure/machinery/New() - ..() +/obj/structure/machinery/Initialize(mapload, ...) + . = ..() machines += src var/area/A = get_area(src) if(A) diff --git a/code/game/machinery/mining.dm b/code/game/machinery/mining.dm index ac7d64eeffb1..924bdd6077ec 100644 --- a/code/game/machinery/mining.dm +++ b/code/game/machinery/mining.dm @@ -4,8 +4,10 @@ name = "Input area" density = 0 anchored = 1.0 - New() - icon_state = "blank" + +/obj/structure/machinery/mineral/input/Initialize(mapload, ...) + . = ..() + icon_state = "blank" /obj/structure/machinery/mineral/output icon = 'icons/mob/hud/screen1.dmi' @@ -13,8 +15,10 @@ name = "Output area" density = 0 anchored = 1.0 - New() - icon_state = "blank" + +/obj/structure/machinery/mineral/output/Initialize(mapload, ...) + . = ..() + icon_state = "blank" /obj/structure/machinery/mineral/processing_unit name = "material processor" //This isn't actually a goddamn furnace, we're in space and it's processing platinum and flammable phoron... diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index da2e2cdc0ed7..0b125b3820f2 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -58,8 +58,8 @@ Buildable meters w_class = SIZE_MEDIUM level = 2 -/obj/item/pipe/New(var/loc, var/pipe_type as num, var/dir as num, var/obj/structure/pipes/make_from = null) - ..() +/obj/item/pipe/Initialize(mapload, var/pipe_type as num, var/dir as num, var/obj/structure/pipes/make_from = null) + . = ..() if(pipe_type == null) pipe_type = 0 if (make_from) diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index 2d0b288474a4..4d0b7a69cdd0 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -83,7 +83,7 @@ if(!wait) var/p_type = text2num(href_list["make"]) var/p_dir = text2num(href_list["dir"]) - var/obj/item/pipe/P = new (/*usr.loc*/ src.loc, pipe_type=p_type, dir=p_dir) + var/obj/item/pipe/P = new (/*usr.loc*/ src.loc, p_type, p_dir) P.update() P.add_fingerprint(usr) wait = 1 diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm deleted file mode 100644 index e45f5261c426..000000000000 --- a/code/game/machinery/portable_turret.dm +++ /dev/null @@ -1,951 +0,0 @@ -/* - Portable Turrets: - - Constructed from metal, a gun of choice, and a prox sensor. - Gun can be a taser or laser or energy gun. - - This code is slightly more documented than normal, as requested by XSI on IRC. - -*/ - - -/obj/structure/machinery/porta_turret - name = "turret" - icon = 'icons/obj/turrets.dmi' - icon_state = "grey_target_prism" - anchored = 1 - layer = 3 - invisibility = INVISIBILITY_LEVEL_TWO // the turret is invisible if it's inside its cover - density = 1 - use_power = 1 // this turret uses and requires power - idle_power_usage = 50 // when inactive, this turret takes up constant 50 Equipment power - active_power_usage = 300// when active, this turret takes up constant 300 Equipment power - req_access = list(access_sulaco_engineering) - power_channel = EQUIP // drains power from the EQUIPMENT channel - - var/lasercolor = "" // Something to do with lasertag turrets, blame Sieve for not adding a comment. - var/raised = 0 // if the turret cover is "open" and the turret is raised - var/raising= 0 // if the turret is currently opening or closing its cover - health = 80 // the turret's health - var/locked = 1 // if the turret's behaviour control access is locked - - var/installation // the type of weapon installed - var/gun_charge = 0 // the charge of the gun inserted - var/projectile = null //holder for bullettype - var/eprojectile = null //holder for the shot when emagged - var/reqpower = 0 //holder for power needed - var/sound = null//So the taser can have sound - var/iconholder = null//holder for the icon_state - var/egun = null//holder to handle certain guns switching bullettypes - - var/obj/structure/machinery/porta_turret_cover/cover = null // the cover that is covering this turret - var/last_fired = 0 // 1: if the turret is cooling down from a shot, 0: turret is ready to fire - var/shot_delay = 15 // 1.5 seconds between each shot - - var/check_records = 1 // checks if it can use the security records - var/criminals = 1 // checks if it can shoot people on arrest - var/auth_weapons = 0 // checks if it can shoot people that have a weapon they aren't authorized to have - var/stun_all = 0 // if this is active, the turret shoots everything that isn't security or head of staff - var/check_anomalies = 1 // checks if it can shoot at unidentified lifeforms (ie xenos) - var/ai = 0 // if active, will shoot at anything not an AI or cyborg - - var/attacked = 0 // if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!) - - var/on = 1 // determines if the turret is on - var/disabled = 0 - - var/datum/effect/effect/system/spark_spread/spark_system // the spark system, used for generating... sparks? - - New() - ..() - icon_state = "[lasercolor]grey_target_prism" - // Sets up a spark system - spark_system = new /datum/effect/effect/system/spark_spread - spark_system.set_up(5, 0, src) - spark_system.attach(src) - sleep(10) - if(!installation)// if for some reason the turret has no gun (ie, admin spawned) it resorts to basic taser shots - projectile = /obj/item/projectile - eprojectile = /obj/item/projectile - reqpower = 200 - sound = 1 - iconholder = 1 - else - /* - var/obj/item/weapon/gun/energy/E=new installation - // All energy-based weapons are applicable - switch(E.type) - if(/obj/item/weapon/gun/energy/laser/bluetag) - projectile = /obj/item/projectile/beam/lastertag/blue - eprojectile = /obj/item/projectile/beam/lastertag/omni//This bolt will stun ERRYONE with a vest - iconholder = null - reqpower = 100 - lasercolor = "b" - req_access = list(access_sulaco_engineering) - check_records = 0 - criminals = 0 - auth_weapons = 1 - stun_all = 0 - check_anomalies = 0 - shot_delay = 30 - - if(/obj/item/weapon/gun/energy/laser/redtag) - projectile = /obj/item/projectile/beam/lastertag/red - eprojectile = /obj/item/projectile/beam/lastertag/omni - iconholder = null - reqpower = 100 - lasercolor = "r" - req_access = list(access_sulaco_engineering) - check_records = 0 - criminals = 0 - auth_weapons = 1 - stun_all = 0 - check_anomalies = 0 - shot_delay = 30 - - if(/obj/item/weapon/gun/energy/laser/practice) - projectile = /obj/item/projectile/beam/practice - eprojectile = /obj/item/projectile/beam - iconholder = null - reqpower = 100 - - if(/obj/item/weapon/gun/energy/pulse_rifle) - projectile = /obj/item/projectile/beam/pulse - eprojectile = projectile - iconholder = null - reqpower = 700 - - if(/obj/item/weapon/gun/energy/staff) - projectile = /obj/item/projectile/change - eprojectile = projectile - iconholder = 1 - reqpower = 700 - - if(/obj/item/weapon/gun/energy/ionrifle) - projectile = /obj/item/projectile/ion - eprojectile = projectile - iconholder = 1 - reqpower = 700 - - if(/obj/item/weapon/gun/energy/taser) - projectile = /obj/item/projectile/beam/stun - eprojectile = projectile - iconholder = 1 - reqpower = 200 - - if(/obj/item/weapon/gun/energy/stunrevolver) - projectile = /obj/item/projectile/energy/electrode - eprojectile = projectile - iconholder = 1 - reqpower = 200 - - if(/obj/item/weapon/gun/energy/lasercannon) - projectile = /obj/item/projectile/beam/heavylaser - eprojectile = projectile - iconholder = null - reqpower = 600 - - if(/obj/item/weapon/gun/energy/decloner) - projectile = /obj/item/projectile/energy/declone - eprojectile = projectile - iconholder = null - reqpower = 600 - - if(/obj/item/weapon/gun/energy/crossbow/largecrossbow) - projectile = /obj/item/projectile/energy/bolt/large - eprojectile = projectile - iconholder = null - reqpower = 125 - - if(/obj/item/weapon/gun/energy/crossbow) - projectile = /obj/item/projectile/energy/bolt - eprojectile = projectile - iconholder = null - reqpower = 50 - - if(/obj/item/weapon/gun/energy/laser) - projectile = /obj/item/projectile/beam - eprojectile = projectile - iconholder = null - reqpower = 500 - - else // Energy gun shots - projectile = /obj/item/projectile/beam/stun// if it hasn't been emagged, it uses normal taser shots - eprojectile = /obj/item/projectile/beam//If it has, going to kill mode - iconholder = 1 - egun = 1 - reqpower = 200 - */ - - Del() - // deletes its own cover with it - del(cover) - ..() - - -/obj/structure/machinery/porta_turret/attack_remote(mob/user as mob) - return attack_hand(user) - -/obj/structure/machinery/porta_turret/attack_hand(mob/user as mob) - . = ..() - if (.) - return - var/dat - - // The browse() text, similar to ED-209s and beepskies. - if(!(src.lasercolor))//Lasertag turrets have less options - dat += text({" -Automatic Portable Turret Installation

-Status: []
-Behaviour controls are [src.locked ? "locked" : "unlocked"]"}, - -"[src.on ? "On" : "Off"]" ) - - if(!src.locked) - dat += text({"
-Check for Weapon Authorization: []
-Check Security Records: []
-Neutralize Identified Criminals: []
-Neutralize All Non-Security and Non-Command Personnel: []
-Neutralize All Unidentified Life Signs: []
"}, - -"[src.auth_weapons ? "Yes" : "No"]", -"[src.check_records ? "Yes" : "No"]", -"[src.criminals ? "Yes" : "No"]", -"[stun_all ? "Yes" : "No"]", -"[check_anomalies ? "Yes" : "No"]" ) - else - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(((src.lasercolor) == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag))) - return - if(((src.lasercolor) == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag))) - return - dat += text({" -Automatic Portable Turret Installation

-Status: []
"}, - -"[src.on ? "On" : "Off"]" ) - - - user << browse("Automatic Portable Turret Installation[dat]", "window=autosec") - onclose(user, "autosec") - return - -/obj/structure/machinery/porta_turret/Topic(href, href_list) - if (..()) - return - usr.set_machine(src) - src.add_fingerprint(usr) - if ((href_list["power"]) && (src.allowed(usr))) - if(anchored) // you can't turn a turret on/off if it's not anchored/secured - on = !on // toggle on/off - else - to_chat(usr, SPAN_DANGER("It has to be secured first!")) - - updateUsrDialog() - return - - switch(href_list["operation"]) - // toggles customizable behavioural protocols - - if ("authweapon") - src.auth_weapons = !src.auth_weapons - if ("checkrecords") - src.check_records = !src.check_records - if ("shootcrooks") - src.criminals = !src.criminals - if("shootall") - stun_all = !stun_all - updateUsrDialog() - - -/obj/structure/machinery/porta_turret/power_change() - - if(!anchored) - icon_state = "turretCover" - return - - ..() - if(stat & BROKEN) - icon_state = "[lasercolor]destroyed_target_prism" - else - if( !(stat & NOPOWER) ) - if (on) -// if (installation == /obj/item/weapon/gun/energy/laser || installation == /obj/item/weapon/gun/energy/pulse_rifle) - // laser guns and pulse rifles have an orange icon - icon_state = "[lasercolor]orange_target_prism" - else - // anything else has a blue icon - icon_state = "[lasercolor]target_prism" - else - icon_state = "[lasercolor]grey_target_prism" - else - spawn(rand(0, 15)) - src.icon_state = "[lasercolor]grey_target_prism" - - - -/obj/structure/machinery/porta_turret/attackby(obj/item/W as obj, mob/user as mob) - if(stat & BROKEN) - if(istype(W, /obj/item/weapon/crowbar)) - - // If the turret is destroyed, you can remove it with a crowbar to - // try and salvage its components - to_chat(user, "You begin prying the metal coverings off.") - sleep(20) - if(prob(70)) - to_chat(user, "You remove the turret and salvage some components.") - if(installation) - var/obj/item/weapon/gun/energy/Gun = new installation(src.loc) - Gun.power_supply.charge=gun_charge - Gun.update_icon() - lasercolor = null - if(prob(50)) new /obj/item/stack/sheet/metal( loc, rand(1,4)) - if(prob(50)) new /obj/item/device/assembly/prox_sensor(locate(x,y,z)) - else - to_chat(user, "You remove the turret but did not manage to salvage anything.") - del(src) - - else if((istype(W, /obj/item/weapon/wrench)) && (!on)) - if(raised) return - // This code handles moving the turret around. After all, it's a portable turret! - - if(!anchored) - anchored = 1 - invisibility = INVISIBILITY_LEVEL_TWO - icon_state = "[lasercolor]grey_target_prism" - to_chat(user, "You secure the exterior bolts on the turret.") - cover=new/obj/structure/machinery/porta_turret_cover(src.loc) // create a new turret. While this is handled in process(), this is to workaround a bug where the turret becomes invisible for a split second - cover.Parent_Turret = src // make the cover's parent src - else - anchored = 0 - to_chat(user, "You unsecure the exterior bolts on the turret.") - icon_state = "turretCover" - invisibility = 0 - del(cover) // deletes the cover, and the turret instance itself becomes its own cover. - - else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - // Behavior lock/unlock mangement - if (allowed(user)) - locked = !src.locked - to_chat(user, "Controls are now [locked ? "locked." : "unlocked."]" - else - to_chat(user, SPAN_DANGER("Access denied.")) - - else - // if the turret was attacked with the intention of harming it: - src.health -= W.force * 0.5 - if (src.health <= 0) - src.die() - if ((W.force * 0.5) > 1) // if the force of impact dealt at least 1 damage, the turret gets pissed off - if(!attacked) - attacked = 1 - spawn() - sleep(60) - attacked = 0 - ..() - - - -/obj/structure/machinery/porta_turret/bullet_act(var/obj/item/projectile/Proj) - - if(Proj.ammo.damage_type == HALLOSS) - return - - if(on) - if(!attacked) - attacked = 1 - spawn() - sleep(60) - attacked = 0 - - src.health -= Proj.ammo.damage - ..() - if(prob(45) && Proj.ammo.damage > 0) src.spark_system.start() - if (src.health <= 0) - src.die() // the death process :( - return - -/obj/structure/machinery/porta_turret/emp_act(severity) - if(on) - // if the turret is on, the EMP no matter how severe disables the turret for a while - // and scrambles its settings, with a slight chance of having an emag effect - check_records=pick(0,1) - criminals=pick(0,1) - auth_weapons=pick(0,1) - stun_all=pick(0,0,0,0,1) // stun_all is a pretty big deal, so it's least likely to get turned on - on=0 - sleep(rand(60,600)) - if(!on) - on=1 - - ..() - -/obj/structure/machinery/porta_turret/ex_act(severity) - if(severity >= 0) // turret dies if an explosion touches it! - del(src) - else - src.die() - -/obj/structure/machinery/porta_turret/proc/die() // called when the turret dies, ie, health <= 0 - src.health = 0 - src.density = 0 - src.stat |= BROKEN // enables the BROKEN bit - src.icon_state = "[lasercolor]destroyed_target_prism" - invisibility=0 - src.spark_system.start() // creates some sparks because they look cool - src.density=1 - del(cover) // deletes the cover - no need on keeping it there! - - - -/obj/structure/machinery/porta_turret/process() - // the main machinery process - - set background = 1 - - if(src.cover==null && anchored) // if it has no cover and is anchored - if (stat & BROKEN) // if the turret is borked - del(cover) // delete its cover, assuming it has one. Workaround for a pesky little bug - else - - src.cover = new /obj/structure/machinery/porta_turret_cover(src.loc) // if the turret has no cover and is anchored, give it a cover - src.cover.Parent_Turret = src // assign the cover its Parent_Turret, which would be this (src) - - if(inoperable()) - // if the turret has no power or is broken, make the turret pop down if it hasn't already - popDown() - return - - if(!on) - // if the turret is off, make it pop down - popDown() - return - - var/list/targets = list() // list of primary targets - var/list/secondarytargets = list() // targets that are least important - - if(src.check_anomalies) // if its set to check for xenos/carps, check for non-mob "crittersssss"(And simple_animals) - for(var/mob/living/simple_animal/C in view(7,src)) - if(!C.stat) - targets += C - - for (var/mob/living/carbon/C in view(7,src)) // loops through all living carbon-based lifeforms in view(12) - if(istype(C, /mob/living/carbon/alien) && src.check_anomalies) // git those fukken xenos - if(!C.stat) // if it's dead/dying, there's no need to keep shooting at it. - targets += C - - else - if (C.stat || C.handcuffed) // if the perp is handcuffed or dead/dying, no need to bother really - continue // move onto next potential victim! - - var/dst = get_dist(src, C) // if it's too far away, why bother? - if (dst > 7) - continue - - if(ai) // If it's set to attack all nonsilicons, target them! - if(C.lying) - if(lasercolor) - continue - else - secondarytargets += C - continue - else - targets += C - continue - - if (istype(C, /mob/living/carbon/human)) // if the target is a human, analyze threat level - if(src.assess_perp(C)<4) - continue // if threat level < 4, keep going - - if (C.lying) // if the perp is lying down, it's still a target but a less-important target - secondarytargets += C - continue - - targets += C // if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee - - if (targets.len>0) // if there are targets to shoot - - var/atom/t = pick(targets) // pick a perp from the list of targets. Targets go first because they are the most important - - if (istype(t, /mob/living)) // if a mob - var/mob/living/M = t // simple typecasting - if (M.stat!=2) // if the target is not dead - spawn() popUp() // pop the turret up if it's not already up. - dir=get_dir(src,M) // even if you can't shoot, follow the target - spawn() shootAt(M) // shoot the target, finally - - else - if(secondarytargets.len>0) // if there are no primary targets, go for secondary targets - var/mob/t = pick(secondarytargets) - if (istype(t, /mob/living)) - if (t.stat!=2) - spawn() popUp() - dir=get_dir(src,t) - shootAt(t) - else - spawn() popDown() - -/obj/structure/machinery/porta_turret/proc - popUp() // pops the turret up - if(disabled) - return - if(raising || raised) return - if(stat & BROKEN) return - invisibility=0 - raising=1 - flick("popup",cover) - sleep(5) - sleep(5) - raising=0 - cover.icon_state="openTurretCover" - raised=1 - layer=4 - - popDown() // pops the turret down - if(disabled) - return - if(raising || !raised) return - if(stat & BROKEN) return - layer=3 - raising=1 - flick("popdown",cover) - sleep(10) - raising=0 - cover.icon_state="turretCover" - raised=0 - invisibility=2 - icon_state="[lasercolor]grey_target_prism" - - -/obj/structure/machinery/porta_turret/proc/assess_perp(mob/living/carbon/human/perp as mob) - return FALSE - - - - - -/obj/structure/machinery/porta_turret/proc/shootAt(var/atom/movable/target) // shoots at a target - if(disabled) - return - - if(lasercolor && (istype(target,/mob/living/carbon/human))) - var/mob/living/carbon/human/H = target - if(H.lying) - return - - if(last_fired || !raised) return // prevents rapid-fire shooting, unless it's been emagged - last_fired = 1 - spawn() - sleep(shot_delay) - last_fired = 0 - - var/turf/T = get_turf(src) - var/turf/U = get_turf(target) - if (!istype(T) || !istype(U)) - return - - if (!raised) // the turret has to be raised in order to fire - makes sense, right? - return - - - if(iconholder) - icon_state = "[lasercolor]target_prism" - else - icon_state = "[lasercolor]orange_target_prism" - if(sound) - playsound(src.loc, 'sound/weapons/Taser.ogg', 75, 1) - var/obj/item/projectile/A - A = new projectile(initial(name), loc) - A.original = target.loc - use_power(reqpower) - - // Shooting Code: - A.current = T - A.yo = U.y - T.y - A.xo = U.x - T.x - spawn( 1 ) - A.process() - return - - - -/* - - Portable turret constructions - - Known as "turret frame"s - -*/ - -/obj/structure/machinery/porta_turret_construct - name = "turret frame" - icon = 'icons/obj/turrets.dmi' - icon_state = "turret_frame" - density=1 - var/build_step = 0 // the current step in the building process - var/finish_name="turret" // the name applied to the product turret - var/installation = null // the gun type installed - var/gun_charge = 0 // the gun charge of the gun type installed - - - -/obj/structure/machinery/porta_turret_construct/attackby(obj/item/W as obj, mob/user as mob) - - // this is a bit unweildy but self-explanitory - switch(build_step) - if(0) // first step - if(istype(W, /obj/item/weapon/wrench) && !anchored) - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - to_chat(user, SPAN_NOTICE(" You secure the external bolts.")) - anchored = 1 - build_step = 1 - return - - else if(istype(W, /obj/item/weapon/crowbar) && !anchored) - playsound(src.loc, 'sound/items/Crowbar.ogg', 75, 1) - to_chat(user, "You dismantle the turret construction.") - new /obj/item/stack/sheet/metal( loc, 5) - del(src) - return - - if(1) - if(istype(W, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/metal/M = W - if (M.use(2)) - to_chat(user, SPAN_NOTICE("You add some metal armor to the interior frame.")) - build_step = 2 - icon_state = "turret_frame2" - else - to_chat(user, SPAN_WARNING("You need two sheets of metal to add armor ot the frame.")) - return - - else if(istype(W, /obj/item/weapon/wrench)) - playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) - to_chat(user, "You unfasten the external bolts.") - anchored = 0 - build_step = 0 - return - - - if(2) - if(istype(W, /obj/item/weapon/wrench)) - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - to_chat(user, SPAN_NOTICE(" You bolt the metal armor into place.")) - build_step = 3 - return - - else if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(!WT.isOn()) return - if (WT.get_fuel() < 5) // uses up 5 fuel. - to_chat(user, SPAN_DANGER("You need more fuel to complete this task.")) - return - - playsound(src.loc, pick('sound/items/Welder.ogg', 'sound/items/Welder2.ogg'), 50, 1) - if(do_after(user, 20)) - if(!src || !WT.remove_fuel(5, user)) return - build_step = 1 - to_chat(user, "You remove the turret's interior metal armor.") - new /obj/item/stack/sheet/metal( loc, 2) - return - - - if(3) - if(istype(W, /obj/item/weapon/gun/energy)) // the gun installation part - - var/obj/item/weapon/gun/energy/E = W // typecasts the item to an energy gun - installation = W.type // installation becomes W.type - gun_charge = E.power_supply.charge // the gun's charge is stored in src.gun_charge - to_chat(user, SPAN_NOTICE(" You add \the [W] to the turret.")) - build_step = 4 - del(W) // delete the gun :( - return - - else if(istype(W, /obj/item/weapon/wrench)) - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - to_chat(user, "You remove the turret's metal armor bolts.") - build_step = 2 - return - - if(4) - if(isprox(W)) - build_step = 5 - to_chat(user, SPAN_NOTICE(" You add the prox sensor to the turret.")) - del(W) - return - - // attack_hand() removes the gun - - if(5) - if(istype(W, /obj/item/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) - build_step = 6 - to_chat(user, SPAN_NOTICE(" You close the internal access hatch.")) - return - - // attack_hand() removes the prox sensor - - if(6) - if(istype(W, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/metal/M = W - if (M.use(2)) - to_chat(user, SPAN_NOTICE("You add some metal armor to the exterior frame.")) - build_step = 7 - else - to_chat(user, SPAN_WARNING("You need two sheets of metal to add armor to the frame.")) - return - - else if(istype(W, /obj/item/weapon/screwdriver)) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) - build_step = 5 - to_chat(user, "You open the internal access hatch.") - return - - if(7) - if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(!WT.isOn()) return - if (WT.get_fuel() < 5) - to_chat(user, SPAN_DANGER("You need more fuel to complete this task.")) - - playsound(src.loc, pick('sound/items/Welder.ogg', 'sound/items/Welder2.ogg'), 50, 1) - if(do_after(user, 30)) - if(!src || !WT.remove_fuel(5, user)) return - build_step = 8 - to_chat(user, SPAN_NOTICE(" You weld the turret's armor down.")) - - // The final step: create a full turret - var/obj/structure/machinery/porta_turret/Turret = new/obj/structure/machinery/porta_turret(locate(x,y,z)) - Turret.name = finish_name - Turret.installation = src.installation - Turret.gun_charge = src.gun_charge - -// Turret.cover=new/obj/structure/machinery/porta_turret_cover(src.loc) -// Turret.cover.Parent_Turret=Turret -// Turret.cover.name = finish_name - Turret.New() - del(src) - - else if(istype(W, /obj/item/weapon/crowbar)) - playsound(src.loc, 'sound/items/Crowbar.ogg', 75, 1) - to_chat(user, "You pry off the turret's exterior armor.") - new /obj/item/stack/sheet/metal( loc, 2) - build_step = 6 - return - - if (istype(W, /obj/item/weapon/pen)) // you can rename turrets like bots! - var/t = stripped_input(user, "Enter new turret name", src.name, src.finish_name) - if (!t) - return - if (!in_range(src, usr) && src.loc != usr) - return - - src.finish_name = t - return - ..() - - - -/obj/structure/machinery/porta_turret_construct/attack_hand(mob/user as mob) - switch(build_step) - if(4) - if(!installation) return - build_step = 3 - - var/obj/item/weapon/gun/energy/Gun = new installation(src.loc) - Gun.power_supply.charge=gun_charge - Gun.update_icon() - installation = null - gun_charge = 0 - to_chat(user, "You remove \the [Gun] from the turret frame.") - - if(5) - to_chat(user, "You remove the prox sensor from the turret frame.") - new/obj/item/device/assembly/prox_sensor(locate(x,y,z)) - build_step = 4 - - - - - - - - - - - - -/obj/structure/machinery/porta_turret_cover - name = "turret" - icon = 'icons/obj/turrets.dmi' - icon_state = "turretCover" - anchored = 1 - layer = 3.5 - density = 0 - var/obj/structure/machinery/porta_turret/Parent_Turret = null - - - -// The below code is pretty much just recoded from the initial turret object. It's necessary but uncommented because it's exactly the same! - -/obj/structure/machinery/porta_turret_cover/attack_remote(mob/user as mob) - . = ..() - if (.) - return - var/dat - if(!(Parent_Turret.lasercolor)) - dat += text({" -Automatic Portable Turret Installation

-Status: []
-Behaviour controls are [Parent_Turret.locked ? "locked" : "unlocked"]"}, - -"[Parent_Turret.on ? "On" : "Off"]" ) - - - dat += text({"
-Check for Weapon Authorization: []
-Check Security Records: []
-Neutralize Identified Criminals: []
-Neutralize All Non-Security and Non-Command Personnel: []
-Neutralize All Unidentified Life Signs: []
"}, - -"[Parent_Turret.auth_weapons ? "Yes" : "No"]", -"[Parent_Turret.check_records ? "Yes" : "No"]", -"[Parent_Turret.criminals ? "Yes" : "No"]", -"[Parent_Turret.stun_all ? "Yes" : "No"]" , -"[Parent_Turret.check_anomalies ? "Yes" : "No"]" ) - else - dat += text({" -Automatic Portable Turret Installation

-Status: []
"}, - -"[Parent_Turret.on ? "On" : "Off"]" ) - - user << browse("Automatic Portable Turret Installation[dat]", "window=autosec") - onclose(user, "autosec") - return - -/obj/structure/machinery/porta_turret_cover/attack_hand(mob/user as mob) - . = ..() - if (.) - return - var/dat - if(!(Parent_Turret.lasercolor)) - dat += text({" -Automatic Portable Turret Installation

-Status: []
-Behaviour controls are [Parent_Turret.locked ? "locked" : "unlocked"]"}, - -"[Parent_Turret.on ? "On" : "Off"]" ) - - if(!Parent_Turret.locked) - dat += text({"
-Check for Weapon Authorization: []
-Check Security Records: []
-Neutralize Identified Criminals: []
-Neutralize All Non-Security and Non-Command Personnel: []
-Neutralize All Unidentified Life Signs: []
"}, - -"[Parent_Turret.auth_weapons ? "Yes" : "No"]", -"[Parent_Turret.check_records ? "Yes" : "No"]", -"[Parent_Turret.criminals ? "Yes" : "No"]", -"[Parent_Turret.stun_all ? "Yes" : "No"]" , -"[Parent_Turret.check_anomalies ? "Yes" : "No"]" ) - else - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(((Parent_Turret.lasercolor) == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag))) - return - if(((Parent_Turret.lasercolor) == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag))) - return - dat += text({" -Automatic Portable Turret Installation

-Status: []
"}, - -"[Parent_Turret.on ? "On" : "Off"]" ) - - - - user << browse("Automatic Portable Turret Installation[dat]", "window=autosec") - onclose(user, "autosec") - return - -/obj/structure/machinery/porta_turret_cover/Topic(href, href_list) - if (..()) - return - usr.set_machine(src) - Parent_Turret.add_fingerprint(usr) - src.add_fingerprint(usr) - if ((href_list["power"]) && (Parent_Turret.allowed(usr))) - if(Parent_Turret.anchored) - if (Parent_Turret.on) - Parent_Turret.on=0 - else - Parent_Turret.on=1 - else - to_chat(usr, SPAN_DANGER("It has to be secured first!")) - - updateUsrDialog() - return - - switch(href_list["operation"]) - if ("authweapon") - Parent_Turret.auth_weapons = !Parent_Turret.auth_weapons - if ("checkrecords") - Parent_Turret.check_records = !Parent_Turret.check_records - if ("shootcrooks") - Parent_Turret.criminals = !Parent_Turret.criminals - if("shootall") - Parent_Turret.stun_all = !Parent_Turret.stun_all - if("checkxenos") - Parent_Turret.check_anomalies = !Parent_Turret.check_anomalies - - updateUsrDialog() - - - -/obj/structure/machinery/porta_turret_cover/attackby(obj/item/W as obj, mob/user as mob) - if((istype(W, /obj/item/weapon/wrench)) && (!Parent_Turret.on)) - if(Parent_Turret.raised) return - - if(!Parent_Turret.anchored) - Parent_Turret.anchored = 1 - Parent_Turret.invisibility = INVISIBILITY_LEVEL_TWO - Parent_Turret.icon_state = "grey_target_prism" - to_chat(user, "You secure the exterior bolts on the turret.") - else - Parent_Turret.anchored = 0 - to_chat(user, "You unsecure the exterior bolts on the turret.") - Parent_Turret.icon_state = "turretCover" - Parent_Turret.invisibility = 0 - del(src) - - else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if (Parent_Turret.allowed(user)) - Parent_Turret.locked = !Parent_Turret.locked - to_chat(user, "Controls are now [Parent_Turret.locked ? ")locked." : "unlocked."]" - updateUsrDialog() - else - to_chat(user, SPAN_DANGER("Access denied.")) - - else - Parent_Turret.health -= W.force * 0.5 - if (Parent_Turret.health <= 0) - Parent_Turret.die() - if ((W.force * 0.5) > 2) - if(!Parent_Turret.attacked && !Parent_Turret.emagged) - Parent_Turret.attacked = 1 - spawn() - sleep(30) - Parent_Turret.attacked = 0 - ..() - - - - -/obj/structure/machinery/porta_turret/stationary - New() - installation = new/obj/item/weapon/gun/energy/laser(src.loc) - ..() diff --git a/code/game/machinery/scoreboard.dm b/code/game/machinery/scoreboard.dm index a684c4f5e7bd..6e4407041af0 100644 --- a/code/game/machinery/scoreboard.dm +++ b/code/game/machinery/scoreboard.dm @@ -11,8 +11,8 @@ var/scoreleft = 0 var/scoreright = 0 -/obj/structure/machinery/scoreboard/New() - ..() +/obj/structure/machinery/scoreboard/Initialize() + . = ..() update_display() /obj/structure/machinery/scoreboard/proc/update_display() diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 14b1c3053a2c..bbaf72d5045f 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -14,8 +14,8 @@ flags_atom = FPRINT -/obj/structure/machinery/space_heater/New() - ..() +/obj/structure/machinery/space_heater/Initialize() + . = ..() cell = new (src) cell.charge += 500 update_icon() diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 8486bf37fa83..1b1676338aca 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -40,8 +40,8 @@ var/const/STATUS_DISPLAY_TIME = 4 var/const/STATUS_DISPLAY_CUSTOM = 99 -/obj/structure/machinery/status_display/New() - ..() +/obj/structure/machinery/status_display/Initialize() + . = ..() set_picture("default") /obj/structure/machinery/status_display/emp_act(severity) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 8983c9988676..f36f3a91fa62 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -23,8 +23,8 @@ -/obj/structure/machinery/suit_storage_unit/New() - ..() +/obj/structure/machinery/suit_storage_unit/Initialize() + . = ..() if(starting_suit_type) inserted_suit = new starting_suit_type(src) if(starting_helmet_type) diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm index 4b779461a129..f8e6d1b9349a 100644 --- a/code/game/machinery/telecomms/presets.dm +++ b/code/game/machinery/telecomms/presets.dm @@ -45,8 +45,8 @@ health = 450 tcomms_machine = TRUE -/obj/structure/machinery/telecomms/relay/preset/tower/New() - ..() +/obj/structure/machinery/telecomms/relay/preset/tower/Initialize(mapload, ...) + . = ..() playsound(src, 'sound/machines/tcomms_on.ogg', 75) add_tcomm_machine() @@ -189,10 +189,10 @@ freq_listening = list(COMM_FREQ, ENG_FREQ, SEC_FREQ, MED_FREQ, CIV_GEN_FREQ, CIV_COMM_FREQ, SUP_FREQ, ERT_FREQ, DTH_FREQ, PMC_FREQ, DUT_FREQ, YAUT_FREQ, JTAC_FREQ, INTEL_FREQ, WY_FREQ) //Common and other radio frequencies for people to freely use - New() - for(var/i = 1441, i < 1489, i += 2) - freq_listening |= i - ..() +/obj/structure/machinery/telecomms/receiver/preset/Initialize(mapload, ...) + . = ..() + for(var/i = 1441, i < 1489, i += 2) + freq_listening |= i /obj/structure/machinery/telecomms/receiver/preset_cent id = "CentComm Receiver" @@ -227,10 +227,10 @@ freq_listening = list(CIV_GEN_FREQ) autolinkers = list("processor4", "common") -/obj/structure/machinery/telecomms/bus/preset_four/New() +/obj/structure/machinery/telecomms/bus/preset_four/Initialize(mapload, ...) + . = ..() for(var/i = 1441, i < 1489, i += 2) freq_listening |= i - ..() /obj/structure/machinery/telecomms/bus/preset_cent id = "CentComm Bus" @@ -293,10 +293,10 @@ //Common and other radio frequencies for people to freely use // 1441 to 1489 -/obj/structure/machinery/telecomms/server/presets/common/New() +/obj/structure/machinery/telecomms/server/presets/common/Initialize(mapload, ...) + . = ..() for(var/i = 1441, i < 1489, i += 2) freq_listening |= i - ..() /obj/structure/machinery/telecomms/server/presets/command id = "Command Server" diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 82504d51f01d..2d594838ea4f 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -242,6 +242,6 @@ GLOBAL_LIST_EMPTY_TYPED(telecomms_list, /obj/structure/machinery/telecomms) var/language = "human" var/obj/item/device/radio/headset/server_radio = null -/obj/structure/machinery/telecomms/server/New() - ..() +/obj/structure/machinery/telecomms/server/Initialize(mapload, ...) + . = ..() server_radio = new() diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index c6e96d598e92..f0352995ce79 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -93,7 +93,7 @@ var/turf/T = get_turf(R) if (!T) continue - if(is_admin_level(T.z) || T.z > 7) + if(is_admin_level(T.z)) continue var/tmpname = T.loc.name if(areaindex[tmpname]) diff --git a/code/game/machinery/vending/vending.dm b/code/game/machinery/vending/vending.dm index e32c3735d1f1..53a00b985357 100644 --- a/code/game/machinery/vending/vending.dm +++ b/code/game/machinery/vending/vending.dm @@ -71,25 +71,21 @@ wrenchable = TRUE var/vending_dir -/obj/structure/machinery/vending/New() - ..() - spawn(4) - src.slogan_list = splittext(src.product_slogans, ";") - - // So not all machines speak at the exact same time. - // The first time this machine says something will be at slogantime + this random value, - // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. - src.last_slogan = world.time + rand(0, slogan_delay) - - src.build_inventory(products) - //Add hidden inventory - src.build_inventory(contraband, 1) - src.build_inventory(premium, 0, 1) - power_change() - start_processing() - return +/obj/structure/machinery/vending/Initialize(mapload, ...) + . = ..() + src.slogan_list = splittext(src.product_slogans, ";") - return + // So not all machines speak at the exact same time. + // The first time this machine says something will be at slogantime + this random value, + // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. + src.last_slogan = world.time + rand(0, slogan_delay) + + src.build_inventory(products) + //Add hidden inventory + src.build_inventory(contraband, 1) + src.build_inventory(premium, 0, 1) + power_change() + start_processing() /obj/structure/machinery/vending/update_icon() overlays.Cut() @@ -118,9 +114,6 @@ /obj/structure/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0) - if(delay_product_spawn) - sleep(15) //Make ABSOLUTELY SURE the seed datum is properly populated. - for(var/typepath in productlist) var/amount = productlist[typepath] var/price = prices[typepath] @@ -135,10 +128,6 @@ if(ispath(typepath,/obj/item/weapon/gun) || ispath(typepath,/obj/item/ammo_magazine) || ispath(typepath,/obj/item/explosive/grenade) || ispath(typepath,/obj/item/weapon/gun/flamer) || ispath(typepath,/obj/item/storage) ) R.display_color = "black" -// else if(ispath(typepath,/obj/item/clothing) || ispath(typepath,/obj/item/storage)) -// R.display_color = "white" -// else if(ispath(typepath,/obj/item/reagent_container) || ispath(typepath,/obj/item/stack/medical)) -// R.display_color = "blue" else R.display_color = "white" @@ -152,11 +141,7 @@ R.category=CAT_NORMAL product_records += R - if(delay_product_spawn) - sleep(5) //sleep(1) did not seem to cut it, so here we are. - R.product_name = initial(temp_path.name) - return /obj/structure/machinery/vending/get_repair_move_text(var/include_name = TRUE) if(!stat) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 2f9865d3b96b..af940ee3b4db 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -28,7 +28,6 @@ if(b_color) basecolor = b_color update_icon() - . = ..() if(src.type == /obj/effect/decal/cleanable/blood) @@ -56,20 +55,20 @@ /obj/effect/decal/cleanable/blood/splatter - random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5") - amount = 2 + random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5") + amount = 2 /obj/effect/decal/cleanable/blood/drip - name = "drips of blood" - desc = "Some small drips of blood." - gender = PLURAL - icon = 'icons/effects/drip.dmi' - icon_state = "1" - random_icon_states = list("1","2","3","4","5") - amount = 0 - var/drips + name = "drips of blood" + desc = "Some small drips of blood." + gender = PLURAL + icon = 'icons/effects/drip.dmi' + icon_state = "1" + random_icon_states = list("1","2","3","4","5") + amount = 0 + var/drips @@ -139,21 +138,21 @@ /obj/effect/decal/cleanable/blood/gibs/proc/streak(var/list/directions) - spawn (0) - var/direction = pick(directions) - for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++) - sleep(3) - if (i > 0) - var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(src.loc) - b.basecolor = src.basecolor - b.update_icon() - for(var/datum/disease/D in src.viruses) - var/datum/disease/ND = D.Copy(1) - LAZYADD(b.viruses, ND) - ND.holder = b - - if (step_to(src, get_step(src, direction), 0)) - break + spawn (0) + var/direction = pick(directions) + for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++) + sleep(3) + if (i > 0) + var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(src.loc) + b.basecolor = src.basecolor + b.update_icon() + for(var/datum/disease/D in src.viruses) + var/datum/disease/ND = D.Copy(1) + LAZYADD(b.viruses, ND) + ND.holder = b + + if (step_to(src, get_step(src, direction), 0)) + break diff --git a/code/game/objects/effects/decals/kutjevo_decals.dm b/code/game/objects/effects/decals/kutjevo_decals.dm index e66d5acc2a50..f1043b2b8dc4 100644 --- a/code/game/objects/effects/decals/kutjevo_decals.dm +++ b/code/game/objects/effects/decals/kutjevo_decals.dm @@ -2,15 +2,15 @@ icon = 'icons/effects/kutjevo_decals.dmi' layer = TURF_LAYER -/obj/effect/decal/kutjevo_decals/New() +/obj/effect/decal/kutjevo_decals/Initialize() . = ..() loc.overlays += src - qdel(src) + return INITIALIZE_HINT_QDEL /obj/effect/decal/kutjevo_decals/catwalk icon = 'icons/turf/floors/kutjevo/kutjevo_floor.dmi' icon_state = "catwalk" name = "catwalk" layer = CATWALK_LAYER - desc = "These things have no depth to them, are they just, painted on?" \ No newline at end of file + desc = "These things have no depth to them, are they just, painted on?" diff --git a/code/game/objects/effects/decals/strata_decals.dm b/code/game/objects/effects/decals/strata_decals.dm index 8e855da78fdd..4f9ddbaf585d 100644 --- a/code/game/objects/effects/decals/strata_decals.dm +++ b/code/game/objects/effects/decals/strata_decals.dm @@ -2,11 +2,11 @@ icon = 'icons/effects/strata_decals.dmi' layer = TURF_LAYER -/obj/effect/decal/strata_decals/New() +/obj/effect/decal/strata_decals/Initialize(mapload, ...) . = ..() loc.overlays += src - qdel(src) + return INITIALIZE_HINT_QDEL /obj/effect/decal/strata_decals/catwalk/prison //For finding and replacing prison catwalk objects since they nasty icon = 'icons/turf/floors/strata_floor.dmi' @@ -76,4 +76,4 @@ icon_state = "grime3" /obj/effect/decal/strata_decals/grime/grime4 - icon_state = "grime4" \ No newline at end of file + icon_state = "grime4" diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm index bcc4e4af3d98..3ff2fb7c10bb 100644 --- a/code/game/objects/effects/glowshroom.dm +++ b/code/game/objects/effects/glowshroom.dm @@ -20,9 +20,8 @@ /obj/effect/glowshroom/single -/obj/effect/glowshroom/New() - - ..() +/obj/effect/glowshroom/Initialize(mapload, ...) + . = ..() dir = CalcDir() @@ -110,4 +109,4 @@ /obj/effect/glowshroom/proc/CheckEndurance() if(endurance <= 0) - qdel(src) \ No newline at end of file + qdel(src) diff --git a/code/game/objects/effects/landmarks/landmarks.dm b/code/game/objects/effects/landmarks/landmarks.dm index 793d3249b150..66fe73296f78 100644 --- a/code/game/objects/effects/landmarks/landmarks.dm +++ b/code/game/objects/effects/landmarks/landmarks.dm @@ -11,13 +11,6 @@ invisibility = 101 switch(name) //some of these are probably obsolete - if("SupplyElevator") - SupplyElevator = loc - qdel(src) - - if("VehicleElevator") - VehicleElevator = loc - qdel(src) if("HangarUpperElevator") HangarUpperElevator = loc qdel(src) @@ -239,11 +232,3 @@ /obj/effect/landmark/late_join/Destroy() GLOB.latejoin -= src return ..() - -/obj/effect/landmark/map_tag - name = "mapping tag" - -/obj/effect/landmark/map_tag/New() - map_tag = name - qdel(src) - return diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm index c60767d38956..fc43e63e7864 100644 --- a/code/game/objects/effects/spawners/gibspawner.dm +++ b/code/game/objects/effects/spawners/gibspawner.dm @@ -22,17 +22,27 @@ icon = 'icons/landmarks.dmi' icon_state = "landmark_gibs" garbage = TRUE + var/list/viruses + var/mob/living/ml -/obj/effect/spawner/gibspawner/New(location, var/list/viruses, var/mob/living/ml, var/fleshcolor, var/bloodcolor) - ..() +/obj/effect/spawner/gibspawner/Initialize(mapload, var/list/viruses, var/mob/living/ml, var/fleshcolor, var/bloodcolor) + . = ..() if(fleshcolor) src.fleshcolor = fleshcolor if(bloodcolor) src.bloodcolor = bloodcolor if(istype(loc,/turf)) //basically if a badmin spawns it - Gib(loc,viruses,ml) + src.viruses = viruses + src.ml = ml + return INITIALIZE_HINT_LATELOAD + return INITIALIZE_HINT_QDEL -/obj/effect/spawner/gibspawner/proc/Gib(atom/location, var/list/viruses = list(), var/mob/living/ml = null) +/obj/effect/spawner/gibspawner/LateInitialize() + . = ..() + Gib(viruses,ml) + QDEL_IN(src, 1 SECONDS) + +/obj/effect/spawner/gibspawner/proc/Gib(var/list/viruses = list(), var/mob/living/ml = null) if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len) to_world(SPAN_DANGER("Gib list length mismatch!")) return @@ -45,14 +55,14 @@ if(sparks) var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(2, 1, location) + s.set_up(2, 1, loc) s.start() for(var/i = 1, i<= gibtypes.len, i++) if(gibamounts[i]) for(var/j = 1, j<= gibamounts[i], j++) var/gibType = gibtypes[i] - gib = new gibType(location) + gib = new gibType(loc) // Apply human species colouration to masks. if(fleshcolor) @@ -73,42 +83,39 @@ if(directions.len) gib.streak(directions) - qdel(src) - /obj/effect/spawner/gibspawner/generic gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core) gibamounts = list(2,2,1) -/obj/effect/spawner/gibspawner/generic/New() +/obj/effect/spawner/gibspawner/generic/Initialize(mapload, list/viruses, mob/living/ml, fleshcolor, bloodcolor) gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list()) - ..() + . = ..() + /obj/effect/spawner/gibspawner/human gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core) gibamounts = list(1,1,1) -/obj/effect/spawner/gibspawner/human/New() +/obj/effect/spawner/gibspawner/human/Initialize(mapload, list/viruses, mob/living/ml, fleshcolor, bloodcolor) gibdirections = list(alldirs, alldirs, list()) - ..() - + . = ..() /obj/effect/spawner/gibspawner/xeno gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno/limb,/obj/effect/decal/cleanable/blood/gibs/xeno/core) gibamounts = list(1,1,1) -/obj/effect/spawner/gibspawner/xeno/New() +/obj/effect/spawner/gibspawner/xeno/Initialize(mapload, list/viruses, mob/living/ml, fleshcolor, bloodcolor) gibdirections = list(alldirs, alldirs, list()) - ..() - + . = ..() /obj/effect/spawner/gibspawner/robot sparks = 1 gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/robot/up,/obj/effect/decal/cleanable/blood/gibs/robot/down,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot/limb) gibamounts = list(1,1,1,1,1,1) -/obj/effect/spawner/gibspawner/robot/New() +/obj/effect/spawner/gibspawner/robot/Initialize(mapload, list/viruses, mob/living/ml, fleshcolor, bloodcolor) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs) gibamounts[6] = pick(0,1,2) - ..() + . = ..() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 73af435b020b..f22da29ba84f 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -81,8 +81,8 @@ appearance_flags = KEEP_TOGETHER //taken from blood.dm var/global/list/blood_overlay_cache = list() //taken from blood.dm -/obj/item/New(loc) - ..() +/obj/item/Initialize(mapload, ...) + . = ..() GLOB.item_list += src for(var/path in actions_types) @@ -164,10 +164,10 @@ cases. Override_icon_state should be a list.*/ var/new_protection var/new_item_state if(override_icon_state && override_icon_state.len) - new_icon_state = override_icon_state[map_tag] + new_icon_state = override_icon_state[SSmapping.configs[GROUND_MAP].map_name] if(override_protection && override_protection.len) - new_protection = override_protection[map_tag] - switch(map_tag) + new_protection = override_protection[SSmapping.configs[GROUND_MAP].map_name] + switch(SSmapping.configs[GROUND_MAP].map_name) // maploader TODO: json if(MAP_ICE_COLONY, MAP_CORSAT, MAP_SOROKYNE_STRATA) icon_state = new_icon_state ? new_icon_state : "s_" + icon_state item_state = new_item_state ? new_item_state : "s_" + item_state diff --git a/code/game/objects/items/XMAS.dm b/code/game/objects/items/XMAS.dm index 8ff163b5f3b5..01e2fbf6813a 100644 --- a/code/game/objects/items/XMAS.dm +++ b/code/game/objects/items/XMAS.dm @@ -8,8 +8,8 @@ icon_state = "gift1" item_state = "gift1" -/obj/item/m_gift/New() - ..() +/obj/item/m_gift/Initialize() + . = ..() pixel_x = rand(-10,10) pixel_y = rand(-10,10) if(w_class > 0 && w_class < 4) @@ -128,4 +128,4 @@ M.put_in_hands(I) I.add_fingerprint(M) qdel(src) - return \ No newline at end of file + return diff --git a/code/game/objects/items/ashtray.dm b/code/game/objects/items/ashtray.dm index 9f529557a066..eed2baddcf78 100644 --- a/code/game/objects/items/ashtray.dm +++ b/code/game/objects/items/ashtray.dm @@ -8,8 +8,8 @@ icon_full = "" icon_broken = "" -/obj/item/ashtray/New() - ..() +/obj/item/ashtray/Initialize() + . = ..() src.pixel_y = rand(-5, 5) src.pixel_x = rand(-6, 6) return diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 5daa1cbd68b5..6e8580f27d1f 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -197,8 +197,8 @@ var/last_use = 0 //remembers the value of used, to delay crostasis start. var/max_uses = 1800 //15 mins of usable cryostasis -/obj/structure/closet/bodybag/cryobag/New(loc, obj/item/bodybag/cryobag/CB) - ..() +/obj/structure/closet/bodybag/cryobag/Initialize(mapload, obj/item/bodybag/cryobag/CB) + . = ..() if(CB) used = CB.used diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 8e3ff7c0727a..942b9e4b2adf 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -86,15 +86,13 @@ . = ..() screen_loc = null -/obj/item/card/id/New() - ..() - - spawn(30) - var/mob/living/carbon/human/H = loc - if(istype(H)) - blood_type = H.blood_type - if(istype(H) && isnull(faction_group)) - faction_group = H.faction_group +/obj/item/card/id/Initialize() + . = ..() + var/mob/living/carbon/human/H = loc + if(istype(H)) + blood_type = H.blood_type + if(istype(H) && isnull(faction_group)) + faction_group = H.faction_group /obj/item/card/id/attack_self(mob/user as mob) diff --git a/code/game/objects/items/devices/autopsy_scanner.dm b/code/game/objects/items/devices/autopsy_scanner.dm index 07e384e834e7..2adee62a0f22 100644 --- a/code/game/objects/items/devices/autopsy_scanner.dm +++ b/code/game/objects/items/devices/autopsy_scanner.dm @@ -8,20 +8,20 @@ icon_state = "autopsy_scanner" flags_atom = FPRINT|CONDUCT w_class = SIZE_SMALL - + var/list/datum/autopsy_data_scanner/wdata = list() var/list/datum/autopsy_data_scanner/chemtraces = list() var/target_name = null var/timeofdeath = null -/obj/item/device/autopsy_scanner/New() +/obj/item/device/autopsy_scanner/Initialize() . = ..() - + LAZYADD(objects_of_interest, src) /obj/item/device/autopsy_scanner/Destroy() . = ..() - + LAZYREMOVE(objects_of_interest, src) /datum/autopsy_data_scanner @@ -107,9 +107,9 @@ var/wname = W.pretend_weapon - if(weapon_chances[wname]) + if(weapon_chances[wname]) weapon_chances[wname] += W.damage - else + else weapon_chances[wname] = max(W.damage, 1) total_score+=W.damage diff --git a/code/game/objects/items/devices/coins.dm b/code/game/objects/items/devices/coins.dm index 9fba70da9b52..c4968910390b 100644 --- a/code/game/objects/items/devices/coins.dm +++ b/code/game/objects/items/devices/coins.dm @@ -11,8 +11,8 @@ var/string_attached var/sides = 2 -/obj/item/coin/New() - ..() +/obj/item/coin/Initialize() + . = ..() pixel_x = rand(0,16)-8 pixel_y = rand(0,8)-8 diff --git a/code/game/objects/items/devices/device.dm b/code/game/objects/items/devices/device.dm index 4af8dcac62a5..2948bec6daf3 100644 --- a/code/game/objects/items/devices/device.dm +++ b/code/game/objects/items/devices/device.dm @@ -5,8 +5,8 @@ icon = 'icons/obj/items/devices.dmi' var/serial_number -/obj/item/device/New() - ..() +/obj/item/device/Initialize() + . = ..() serial_number = "[rand(0,9)][pick(alphabet_uppercase)][rand(0,9)][rand(0,9)][rand(0,9)][rand(0,9)][pick(alphabet_uppercase)]" /obj/item/device/examine(mob/user) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 4f702d6aa947..dc53b53e439e 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -167,8 +167,8 @@ on = 0 raillight_compatible = 0 -/obj/item/device/flashlight/lamp/on/New() - ..() +/obj/item/device/flashlight/lamp/on/Initialize() + . = ..() on = 1 update_brightness() @@ -215,9 +215,9 @@ var/fuel = 0 var/on_damage = 7 -/obj/item/device/flashlight/flare/New() +/obj/item/device/flashlight/flare/Initialize() + . = ..() fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds. - ..() /obj/item/device/flashlight/flare/Destroy() STOP_PROCESSING(SSobj, src) @@ -265,17 +265,14 @@ if(istype(U) && !U.throw_mode) U.toggle_throw_mode(THROW_MODE_NORMAL) -/obj/item/device/flashlight/flare/on - - New() - - ..() - on = 1 - heat_source = 1500 - update_brightness() - force = on_damage - damtype = "fire" - START_PROCESSING(SSobj, src) +/obj/item/device/flashlight/flare/on/Initialize() + . = ..() + on = 1 + heat_source = 1500 + update_brightness() + force = on_damage + damtype = "fire" + START_PROCESSING(SSobj, src) /obj/item/device/flashlight/slime gender = PLURAL @@ -289,12 +286,11 @@ on = 1 //Bio-luminesence has one setting, on. raillight_compatible = 0 -/obj/item/device/flashlight/slime/New() - ..() +/obj/item/device/flashlight/slime/Initialize() + . = ..() SetLuminosity(brightness_on) - spawn(1) //Might be sloppy, but seems to be necessary to prevent further runtimes and make these work as intended... don't judge me! - update_brightness() - icon_state = initial(icon_state) + update_brightness() + icon_state = initial(icon_state) /obj/item/device/flashlight/slime/attack_self(mob/user) return //Bio-luminescence does not toggle. diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index b2984e9253bb..4efa1381062e 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -49,17 +49,17 @@ flags_atom = FPRINT|CONDUCT flags_equip_slot = SLOT_WAIST - + var/max_uses = 50 var/uses = 0 var/failmsg = "" var/charge = 1 -/obj/item/device/lightreplacer/New() +/obj/item/device/lightreplacer/Initialize() + . = ..() uses = max_uses failmsg = "The [name]'s refill light blinks red." - ..() /obj/item/device/lightreplacer/examine(mob/user) ..() diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index e002d2d6d641..827752b1b30d 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -15,8 +15,8 @@ var/obj/item/device/encryptionkey/keyslot3 = null maxf = 1489 -/obj/item/device/radio/headset/New() - ..() +/obj/item/device/radio/headset/Initialize() + . = ..() recalculateChannels() /obj/item/device/radio/headset/handle_message_mode(mob/living/M as mob, message, channel) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index de3bdcf0a9c7..156082eb2928 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -311,8 +311,8 @@ var/transmit_z = position.z // If the mob is inside a vehicle interior, send the message from the vehicle's z, not the interior z - if(interior_manager && transmit_z == interior_manager.interior_z) - var/datum/interior/I = interior_manager.get_interior_by_coords(position.x, position.y) + if(transmit_z == GLOB.interior_manager.interior_z) + var/datum/interior/I = GLOB.interior_manager.get_interior_by_coords(position.x, position.y) if(I && I.exterior) transmit_z = I.exterior.z @@ -347,8 +347,8 @@ var/transmit_z = position.z // If the mob is inside a vehicle interior, send the message from the vehicle's z, not the interior z - if(interior_manager && transmit_z == interior_manager.interior_z) - var/datum/interior/I = interior_manager.get_interior_by_coords(position.x, position.y) + if(transmit_z == GLOB.interior_manager.interior_z) + var/datum/interior/I = GLOB.interior_manager.get_interior_by_coords(position.x, position.y) if(I && I.exterior) transmit_z = I.exterior.z @@ -399,8 +399,8 @@ return FALSE var/receive_z = position.z // Use vehicle's z if we're inside a vehicle interior - if(interior_manager && position.z == interior_manager.interior_z) - var/datum/interior/I = interior_manager.get_interior_by_coords(position.x, position.y) + if(position.z == GLOB.interior_manager.interior_z) + var/datum/interior/I = GLOB.interior_manager.get_interior_by_coords(position.x, position.y) if(I && I.exterior) receive_z = I.exterior.z if(src.ignore_z == TRUE) diff --git a/code/game/objects/items/devices/walkman.dm b/code/game/objects/items/devices/walkman.dm index 5f1a70de68c2..d277a6a6a792 100644 --- a/code/game/objects/items/devices/walkman.dm +++ b/code/game/objects/items/devices/walkman.dm @@ -23,8 +23,8 @@ WEAR_IN_J_STORE = 'icons/mob/humans/onmob/ears.dmi' ) -/obj/item/device/walkman/New() - ..() +/obj/item/device/walkman/Initialize() + . = ..() design = rand(1, 3) update_icon() diff --git a/code/game/objects/items/explosives/plastic.dm b/code/game/objects/items/explosives/plastic.dm index e5404c2b042d..bd52daaceec7 100644 --- a/code/game/objects/items/explosives/plastic.dm +++ b/code/game/objects/items/explosives/plastic.dm @@ -159,7 +159,7 @@ return FALSE //vehicle interior stuff checks - if(interior_manager && target.z == interior_manager.interior_z) + if(target.z == GLOB.interior_manager.interior_z) if(istype(target, /obj/structure/interior_exit) || istype(target, /obj/structure/bed/chair/comfy/vehicle) || istype(target, /obj/structure/interior_viewport) || istype(target, /obj/structure/weapons_loader) || istype(target, /obj/structure/bed/chair/dropship/passenger/shuttle_chair)) return FALSE @@ -279,4 +279,4 @@ overlay_image = "custom_plastic_explosive_sensing" customizable = TRUE matter = list("metal" = 7500, "plastic" = 2000) // 2 metal and 1 plastic sheet - has_blast_wave_dampener = TRUE \ No newline at end of file + has_blast_wave_dampener = TRUE diff --git a/code/game/objects/items/fulton.dm b/code/game/objects/items/fulton.dm index 3197846bf984..d4759b84977a 100644 --- a/code/game/objects/items/fulton.dm +++ b/code/game/objects/items/fulton.dm @@ -72,7 +72,7 @@ var/global/list/deployed_fultons = list() to_chat(user, SPAN_WARNING("You can't attach [src] to something that far away.")) return - if(target_atom.z != 1) + if(!is_ground_level(target_atom.z)) to_chat(user, SPAN_WARNING("You can't attach [src] to something here.")) return diff --git a/code/game/objects/items/gift_wrappaper.dm b/code/game/objects/items/gift_wrappaper.dm index dc6bc7a0311c..d815abbaeeba 100644 --- a/code/game/objects/items/gift_wrappaper.dm +++ b/code/game/objects/items/gift_wrappaper.dm @@ -14,8 +14,8 @@ icon_state = "gift1" item_state = "gift1" -/obj/item/a_gift/New() - ..() +/obj/item/a_gift/Initialize() + . = ..() pixel_x = rand(-10,10) pixel_y = rand(-10,10) if(w_class > 0 && w_class < 4) @@ -182,4 +182,4 @@ else to_chat(user, SPAN_NOTICE(" You need more paper.")) else - to_chat(user, "They are moving around too much. A straightjacket would help.") \ No newline at end of file + to_chat(user, "They are moving around too much. A straightjacket would help.") diff --git a/code/game/objects/items/ore.dm b/code/game/objects/items/ore.dm index ec13f9b61273..014ad170f41b 100644 --- a/code/game/objects/items/ore.dm +++ b/code/game/objects/items/ore.dm @@ -7,49 +7,49 @@ /obj/item/ore/uranium name = "pitchblende" icon_state = "Uranium ore" - + oretag = "uranium" /obj/item/ore/iron name = "hematite" icon_state = "Iron ore" - + oretag = "hematite" /obj/item/ore/coal name = "carbonaceous rock" icon_state = "Coal ore" - + oretag = "coal" /obj/item/ore/glass name = "impure silicates" icon_state = "Glass ore" - + oretag = "sand" /obj/item/ore/phoron name = "phoron crystals" icon_state = "Phoron ore" - + oretag = "phoron" /obj/item/ore/silver name = "native silver ore" icon_state = "Silver ore" - + oretag = "silver" /obj/item/ore/gold name = "native gold ore" icon_state = "Gold ore" - + oretag = "gold" /obj/item/ore/diamond name = "diamonds" icon_state = "Diamond ore" - + oretag = "diamond" /obj/item/ore/osmium @@ -68,7 +68,7 @@ icon_state = "slag" oretag = "slag" -/obj/item/ore/New() +/obj/item/ore/Initialize() . = ..() pixel_x = rand(0,16)-8 pixel_y = rand(0,8)-8 diff --git a/code/game/objects/items/reagent_containers/food/drinks/jar.dm b/code/game/objects/items/reagent_containers/food/drinks/jar.dm index f506d670ca12..987cfcedca5d 100644 --- a/code/game/objects/items/reagent_containers/food/drinks/jar.dm +++ b/code/game/objects/items/reagent_containers/food/drinks/jar.dm @@ -9,23 +9,12 @@ item_state = "beaker" center_of_mass = "x=15;y=8" -/obj/item/reagent_container/food/drinks/jar/Initialize() - . = ..() - reagents.add_reagent("slime", 50) - /obj/item/reagent_container/food/drinks/jar/on_reagent_change() if(reagents.reagent_list.len > 0) - switch(reagents.get_master_reagent_id()) - if("slime") - icon_state = "jar_slime" - name = "slime jam" - desc = "A jar of slime jam. Delicious!" - else - icon_state ="jar_what" - name = "jar of something" - desc = "You can't really tell what this is." + icon_state ="jar_what" + name = "jar of something" + desc = "You can't really tell what this is." else icon_state = "jar" name = "empty jar" desc = "A jar. You're not sure what it's supposed to hold." - return diff --git a/code/game/objects/items/shards.dm b/code/game/objects/items/shards.dm index 35a9c3c903c0..84a4781f9070 100644 --- a/code/game/objects/items/shards.dm +++ b/code/game/objects/items/shards.dm @@ -24,7 +24,8 @@ playsound(loc, 'sound/weapons/bladeslice.ogg', 25, 1, 6) -/obj/item/shard/New() +/obj/item/shard/Initialize() + . = ..() shardsize = pick("large", "medium", "small") switch(shardsize) if("small") @@ -37,7 +38,6 @@ pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) icon_state += shardsize - ..() /obj/item/shard/attackby(obj/item/W, mob/user) @@ -68,7 +68,7 @@ source_sheet_type = /obj/item/stack/sheet/glass/phoronglass -// Shrapnel. +// Shrapnel. // on_embed is called from projectile.dm, bullet_act(obj/item/projectile/P). // on_embedded_movement is called from human.dm, handle_embedded_objects(). diff --git a/code/game/objects/items/stacks/cable_coil.dm b/code/game/objects/items/stacks/cable_coil.dm index d4e3f2e755f4..12ddf59b5f74 100644 --- a/code/game/objects/items/stacks/cable_coil.dm +++ b/code/game/objects/items/stacks/cable_coil.dm @@ -21,8 +21,8 @@ stack_id = "cable coil" -/obj/item/stack/cable_coil/New(loc, length = MAXCOIL, var/param_color = null) - ..() +/obj/item/stack/cable_coil/Initialize(mapload, length = MAXCOIL, var/param_color = null) + . = ..() src.amount = length if (param_color) // It should be red by default, so only recolor it if parameter was specified. color = param_color @@ -272,8 +272,8 @@ item_state = "coil2" garbage = TRUE -/obj/item/stack/cable_coil/cut/New(loc) - ..() +/obj/item/stack/cable_coil/cut/Initialize() + . = ..() src.amount = rand(1,2) pixel_x = rand(-2,2) pixel_y = rand(-2,2) @@ -301,9 +301,9 @@ /obj/item/stack/cable_coil/white color = "#FFFFFF" -/obj/item/stack/cable_coil/random/New() +/obj/item/stack/cable_coil/random/Initialize() + . = ..() color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN) - ..() /obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob) if(ishuman(M)) diff --git a/code/game/objects/items/stacks/flags.dm b/code/game/objects/items/stacks/flags.dm index 30a20f121ef1..f83e64f4d48c 100644 --- a/code/game/objects/items/stacks/flags.dm +++ b/code/game/objects/items/stacks/flags.dm @@ -11,8 +11,8 @@ var/upright = 0 var/base_state -/obj/item/stack/flag/New() - ..() +/obj/item/stack/flag/Initialize() + . = ..() base_state = icon_state /obj/item/stack/flag/red diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 44e6734b6fcf..3cec2ab94240 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -63,8 +63,8 @@ var/global/list/datum/stack_recipe/iron_recipes = list ( \ throw_speed = SPEED_VERY_FAST throw_range = 3 -/obj/item/stack/sheet/mineral/New() - ..() +/obj/item/stack/sheet/mineral/Initialize() + . = ..() pixel_x = rand(0,4)-4 pixel_y = rand(0,4)-4 @@ -79,8 +79,8 @@ var/global/list/datum/stack_recipe/iron_recipes = list ( \ perunit = 3750 stack_id = "iron" -/obj/item/stack/sheet/mineral/iron/New() - ..() +/obj/item/stack/sheet/mineral/iron/Initialize() + . = ..() recipes = iron_recipes /obj/item/stack/sheet/mineral/sandstone @@ -94,8 +94,8 @@ var/global/list/datum/stack_recipe/iron_recipes = list ( \ sheettype = "sandstone" stack_id = "sandstone" -/obj/item/stack/sheet/mineral/sandstone/New() - ..() +/obj/item/stack/sheet/mineral/sandstone/Initialize() + . = ..() recipes = sandstone_recipes /obj/item/stack/sheet/mineral/diamond @@ -109,8 +109,8 @@ var/global/list/datum/stack_recipe/iron_recipes = list ( \ stack_id = "diamond" -/obj/item/stack/sheet/mineral/diamond/New() - ..() +/obj/item/stack/sheet/mineral/diamond/Initialize() + . = ..() recipes = diamond_recipes /obj/item/stack/sheet/mineral/uranium @@ -123,8 +123,8 @@ var/global/list/datum/stack_recipe/iron_recipes = list ( \ sheettype = "uranium" stack_id = "uranium" -/obj/item/stack/sheet/mineral/uranium/New() - ..() +/obj/item/stack/sheet/mineral/uranium/Initialize() + . = ..() recipes = uranium_recipes /obj/item/stack/sheet/mineral/uranium/small_stack @@ -140,10 +140,6 @@ var/global/list/datum/stack_recipe/iron_recipes = list ( \ sheettype = "phoron" stack_id = "phoron" -/obj/item/stack/sheet/mineral/phoron/New() - ..() - // recipes = phoron_recipes // Disabled phoron doors - /obj/item/stack/sheet/mineral/phoron/small_stack amount = STACK_10 @@ -160,8 +156,8 @@ var/global/list/datum/stack_recipe/iron_recipes = list ( \ perunit = 2000 stack_id = "plastic" -/obj/item/stack/sheet/mineral/plastic/New() - ..() +/obj/item/stack/sheet/mineral/plastic/Initialize() + . = ..() recipes = plastic_recipes /obj/item/stack/sheet/mineral/plastic/small_stack @@ -184,8 +180,8 @@ var/global/list/datum/stack_recipe/iron_recipes = list ( \ sheettype = "gold" stack_id = "gold" -/obj/item/stack/sheet/mineral/gold/New() - ..() +/obj/item/stack/sheet/mineral/gold/Initialize() + . = ..() recipes = gold_recipes /obj/item/stack/sheet/mineral/gold/small_stack @@ -201,8 +197,8 @@ var/global/list/datum/stack_recipe/iron_recipes = list ( \ sheettype = "silver" stack_id = "silver" -/obj/item/stack/sheet/mineral/silver/New() - ..() +/obj/item/stack/sheet/mineral/silver/Initialize() + . = ..() recipes = silver_recipes /obj/item/stack/sheet/mineral/silver/small_stack diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index b446cee0f359..a845b31cc5d0 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -57,7 +57,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ matter = list("metal" = 3750) throwforce = 14.0 flags_atom = FPRINT|CONDUCT - + stack_id = "metal" /obj/item/stack/sheet/metal/small_stack @@ -71,7 +71,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ /obj/item/stack/sheet/metal/cyborg -/obj/item/stack/sheet/metal/New(var/loc, var/amount=null) +/obj/item/stack/sheet/metal/Initialize(mapload, amount) recipes = metal_recipes return ..() @@ -96,7 +96,7 @@ var/global/list/datum/stack_recipe/plasteel_recipes = list ( \ matter = list("metal" = 3750) throwforce = 15.0 flags_atom = FPRINT|CONDUCT - + stack_id = "plasteel" /obj/item/stack/sheet/plasteel/New(var/loc, var/amount=null) @@ -133,7 +133,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ singular_name = "wood plank" icon_state = "sheet-wood" item_state = "sheet-wood" - + stack_id = "wood plank" /obj/item/stack/sheet/wood/cyborg @@ -154,7 +154,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ desc = "This roll of cloth is made from only the finest chemicals and bunny rabbits." singular_name = "cloth roll" icon_state = "sheet-cloth" - + stack_id = "cloth" /* @@ -247,7 +247,7 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list ( \ desc = "Large sheets of card, like boxes folded flat." singular_name = "cardboard sheet" icon_state = "sheet-card" - + stack_id = "cardboard" /obj/item/stack/sheet/cardboard/New(var/loc, var/amount=null) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 393274d9b284..8b077eb4a945 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -19,8 +19,8 @@ var/stack_id //used to determine if two stacks are of the same kind. attack_speed = 3 //makes collect stacks off the floor and such less of a pain -/obj/item/stack/New(var/loc, var/amount = null) - ..() +/obj/item/stack/Initialize(mapload, var/amount = null) + . = ..() if(amount) src.amount = amount @@ -136,7 +136,7 @@ if(!OT.allow_construction) to_chat(usr, SPAN_WARNING("The [R.title] must be constructed on a proper surface!")) return - + if(AC) to_chat(usr, SPAN_WARNING("The [R.title] cannot be built here!")) //might cause some friendly fire regarding other items like barbed wire, shouldn't be a problem? return diff --git a/code/game/objects/items/stacks/tiles/plasteel.dm b/code/game/objects/items/stacks/tiles/plasteel.dm index 7f7c995be4d9..49d705f870b1 100644 --- a/code/game/objects/items/stacks/tiles/plasteel.dm +++ b/code/game/objects/items/stacks/tiles/plasteel.dm @@ -12,11 +12,10 @@ flags_atom = FPRINT|CONDUCT max_amount = 60 -/obj/item/stack/tile/plasteel/New(var/loc, var/amount=null) - ..() +/obj/item/stack/tile/plasteel/Initialize(mapload, amount) + . = ..() src.pixel_x = rand(1, 14) src.pixel_y = rand(1, 14) - return /* /obj/item/stack/tile/plasteel/attack_self(mob/user as mob) diff --git a/code/game/objects/items/stock_parts.dm b/code/game/objects/items/stock_parts.dm index edfd497fc112..3b37b92450d1 100644 --- a/code/game/objects/items/stock_parts.dm +++ b/code/game/objects/items/stock_parts.dm @@ -11,7 +11,7 @@ w_class = SIZE_SMALL var/rating = 1 -/obj/item/stock_parts/New() +/obj/item/stock_parts/Initialize() . = ..() src.pixel_x = rand(-5.0, 5) src.pixel_y = rand(-5.0, 5) @@ -22,42 +22,42 @@ name = "console screen" desc = "Used in the construction of computers and other devices with a interactive console." icon_state = "screen" - + matter = list("glass" = 200) /obj/item/stock_parts/capacitor name = "capacitor" desc = "A basic capacitor used in the construction of a variety of devices." icon_state = "capacitor" - + matter = list("metal" = 50,"glass" = 50) /obj/item/stock_parts/scanning_module name = "scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." icon_state = "scan_module" - + matter = list("metal" = 50,"glass" = 20) /obj/item/stock_parts/manipulator name = "micro-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "micro_mani" - + matter = list("metal" = 30) /obj/item/stock_parts/micro_laser name = "micro-laser" desc = "A tiny laser used in certain devices." icon_state = "micro_laser" - + matter = list("metal" = 10,"glass" = 20) /obj/item/stock_parts/matter_bin name = "matter bin" desc = "A container for hold compressed matter awaiting re-construction." icon_state = "matter_bin" - + matter = list("metal" = 80) //Rank 2 @@ -65,7 +65,7 @@ /obj/item/stock_parts/capacitor/adv name = "advanced capacitor" desc = "An advanced capacitor used in the construction of a variety of devices." - + rating = 2 matter = list("metal" = 50,"glass" = 50) @@ -73,7 +73,7 @@ name = "advanced scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." icon_state = "scan_module" - + rating = 2 matter = list("metal" = 50,"glass" = 20) @@ -81,7 +81,7 @@ name = "nano-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "nano_mani" - + rating = 2 matter = list("metal" = 30) @@ -89,7 +89,7 @@ name = "high-power micro-laser" desc = "A tiny laser used in certain devices." icon_state = "high_micro_laser" - + rating = 2 matter = list("metal" = 10,"glass" = 20) @@ -97,7 +97,7 @@ name = "advanced matter bin" desc = "A container for hold compressed matter awaiting re-construction." icon_state = "advanced_matter_bin" - + rating = 2 matter = list("metal" = 80) @@ -106,14 +106,14 @@ /obj/item/stock_parts/capacitor/super name = "super capacitor" desc = "A super-high capacity capacitor used in the construction of a variety of devices." - + rating = 3 matter = list("metal" = 50,"glass" = 50) /obj/item/stock_parts/scanning_module/phasic name = "phasic scanning module" desc = "A compact, high resolution phasic scanning module used in the construction of certain devices." - + rating = 3 matter = list("metal" = 50,"glass" = 20) @@ -121,7 +121,7 @@ name = "pico-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "pico_mani" - + rating = 3 matter = list("metal" = 30) @@ -129,7 +129,7 @@ name = "ultra-high-power micro-laser" icon_state = "ultra_high_micro_laser" desc = "A tiny laser used in certain devices." - + rating = 3 matter = list("metal" = 10,"glass" = 20) @@ -137,7 +137,7 @@ name = "super matter bin" desc = "A container for hold compressed matter awaiting re-construction." icon_state = "super_matter_bin" - + rating = 3 matter = list("metal" = 80) @@ -147,49 +147,49 @@ name = "subspace ansible" icon_state = "subspace_ansible" desc = "A compact module capable of sensing extradimensional activity." - + matter = list("metal" = 30,"glass" = 10) /obj/item/stock_parts/subspace/filter name = "hyperwave filter" icon_state = "hyperwave_filter" desc = "A tiny device capable of filtering and converting super-intense radiowaves." - + matter = list("metal" = 30,"glass" = 10) /obj/item/stock_parts/subspace/amplifier name = "subspace amplifier" icon_state = "subspace_amplifier" desc = "A compact micro-machine capable of amplifying weak subspace transmissions." - + matter = list("metal" = 30,"glass" = 10) /obj/item/stock_parts/subspace/treatment name = "subspace treatment disk" icon_state = "treatment_disk" desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves." - + matter = list("metal" = 30,"glass" = 10) /obj/item/stock_parts/subspace/analyzer name = "subspace wavelength analyzer" icon_state = "wavelength_analyzer" desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." - + matter = list("metal" = 30,"glass" = 10) /obj/item/stock_parts/subspace/crystal name = "ansible crystal" icon_state = "ansible_crystal" desc = "A crystal made from pure glass used to transmit laser databursts to subspace." - + matter = list("glass" = 50) /obj/item/stock_parts/subspace/transmitter name = "subspace transmitter" icon_state = "subspace_transmitter" desc = "A large piece of equipment used to open a window into the subspace dimension." - + matter = list("metal" = 50) diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 2a061443517b..5edaff885fc5 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -13,8 +13,8 @@ var/volume_rate = 500 //Needed for borg jetpack transfer actions_types = list(/datum/action/item_action) -/obj/item/tank/jetpack/New() - ..() +/obj/item/tank/jetpack/Initialize() + . = ..() src.ion_trail = new /datum/effect_system/ion_trail_follow() src.ion_trail.set_up(src) diff --git a/code/game/objects/items/tools/misc_tools.dm b/code/game/objects/items/tools/misc_tools.dm index 63d7b1fa406e..31eb71dc3205 100644 --- a/code/game/objects/items/tools/misc_tools.dm +++ b/code/game/objects/items/tools/misc_tools.dm @@ -99,7 +99,7 @@ playsound(user.loc, "sound/items/pen_click_[on? "on": "off"].ogg", 100, 1, 5) update_pen_state() -/obj/item/tool/pen/New() +/obj/item/tool/pen/Initialize() . = ..() update_pen_state() diff --git a/code/game/objects/items/toys/cards.dm b/code/game/objects/items/toys/cards.dm index bd97f6b48d5e..c1507f3e3e87 100644 --- a/code/game/objects/items/toys/cards.dm +++ b/code/game/objects/items/toys/cards.dm @@ -15,8 +15,8 @@ var/list/datum/playingcard/cards = list() -/obj/item/toy/deck/New() - ..() +/obj/item/toy/deck/Initialize() + . = ..() populate_deck() /obj/item/toy/deck/proc/populate_deck() diff --git a/code/game/objects/items/toys/toys.dm b/code/game/objects/items/toys/toys.dm index 3c051e90fed9..358a4c092be2 100644 --- a/code/game/objects/items/toys/toys.dm +++ b/code/game/objects/items/toys/toys.dm @@ -399,7 +399,7 @@ var/sides = 6 attack_verb = list("diced") -/obj/item/toy/dice/New() +/obj/item/toy/dice/Initialize() . = ..() icon_state = "[name][rand(sides)]" @@ -491,4 +491,4 @@ /obj/item/toy/prize/mauler = 1, /obj/item/toy/prize/odysseus = 1, /obj/item/toy/prize/phazon = 1 - ) \ No newline at end of file + ) diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index 6c224adf8d35..2b44b2bac96b 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -109,8 +109,8 @@ w_class = SIZE_TINY throwforce = 1 -/obj/item/trash/cigbutt/New() - ..() +/obj/item/trash/cigbutt/Initialize() + . = ..() pixel_x = rand(-10,10) pixel_y = rand(-10,10) apply_transform(turn(transform,rand(0,360))) @@ -161,4 +161,4 @@ name = "\improper crumbled USCM MRE" desc = "It has done its part for the USCM. Have you?" icon = 'icons/obj/items/trash.dmi' - icon_state = "mealpackempty" \ No newline at end of file + icon_state = "mealpackempty" diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 307840c124be..08068474124b 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -20,8 +20,8 @@ var/req_access_txt = null var/req_one_access_txt = null -/obj/New() - ..() +/obj/Initialize(mapload, ...) + . = ..() GLOB.object_list += src if(garbage) add_to_garbage(src) diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index c53461a78cdc..22faf138fa9f 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -16,8 +16,8 @@ projectile_coverage = PROJECTILE_COVERAGE_MEDIUM can_block_movement = TRUE -/obj/structure/New() - ..() +/obj/structure/Initialize() + . = ..() if(climbable) verbs += /obj/structure/proc/climb_on diff --git a/code/game/objects/structures/barricade/barricade.dm b/code/game/objects/structures/barricade/barricade.dm index 0eaf7f0468f7..2cc3e720aaee 100644 --- a/code/game/objects/structures/barricade/barricade.dm +++ b/code/game/objects/structures/barricade/barricade.dm @@ -30,8 +30,8 @@ var/burn_multiplier = 1 var/explosive_multiplier = 1 -/obj/structure/barricade/New(loc, mob/user) - ..(loc) +/obj/structure/barricade/Initialize(mapload, mob/user) + . = ..() if(user) user.count_niche_stat(STATISTICS_NICHE_CADES) addtimer(CALLBACK(src, .proc/update_icon), 0) diff --git a/code/game/objects/structures/bookcase.dm b/code/game/objects/structures/bookcase.dm index 8b9f93c5ba0e..eb9eacb9426c 100644 --- a/code/game/objects/structures/bookcase.dm +++ b/code/game/objects/structures/bookcase.dm @@ -73,33 +73,33 @@ /obj/structure/bookcase/manuals/medical name = "Medical Manuals bookcase" - New() - ..() - new /obj/item/book/manual/medical_cloning(src) - new /obj/item/book/manual/medical_diagnostics_manual(src) - new /obj/item/book/manual/medical_diagnostics_manual(src) - new /obj/item/book/manual/medical_diagnostics_manual(src) - update_icon() +/obj/structure/bookcase/manuals/medical/Initialize() + . = ..() + new /obj/item/book/manual/medical_cloning(src) + new /obj/item/book/manual/medical_diagnostics_manual(src) + new /obj/item/book/manual/medical_diagnostics_manual(src) + new /obj/item/book/manual/medical_diagnostics_manual(src) + update_icon() /obj/structure/bookcase/manuals/engineering name = "Engineering Manuals bookcase" - New() - ..() - new /obj/item/book/manual/engineering_construction(src) - new /obj/item/book/manual/engineering_particle_accelerator(src) - new /obj/item/book/manual/engineering_hacking(src) - new /obj/item/book/manual/engineering_guide(src) - new /obj/item/book/manual/atmospipes(src) - new /obj/item/book/manual/engineering_singularity_safety(src) - new /obj/item/book/manual/evaguide(src) - update_icon() +/obj/structure/bookcase/manuals/engineering/Initialize() + . = ..() + new /obj/item/book/manual/engineering_construction(src) + new /obj/item/book/manual/engineering_particle_accelerator(src) + new /obj/item/book/manual/engineering_hacking(src) + new /obj/item/book/manual/engineering_guide(src) + new /obj/item/book/manual/atmospipes(src) + new /obj/item/book/manual/engineering_singularity_safety(src) + new /obj/item/book/manual/evaguide(src) + update_icon() /obj/structure/bookcase/manuals/research_and_development name = "R&D Manuals bookcase" - New() - ..() - new /obj/item/book/manual/research_and_development(src) - update_icon() +/obj/structure/bookcase/manuals/research_and_development/Initialize() + . = ..() + new /obj/item/book/manual/research_and_development(src) + update_icon() diff --git a/code/game/objects/structures/crates_lockers/closets/fitness.dm b/code/game/objects/structures/crates_lockers/closets/fitness.dm index 66d4570afb80..d846b814c010 100644 --- a/code/game/objects/structures/crates_lockers/closets/fitness.dm +++ b/code/game/objects/structures/crates_lockers/closets/fitness.dm @@ -4,9 +4,8 @@ icon_state = "mixed" icon_closed = "mixed" -/obj/structure/closet/athletic_mixed/New() - ..() - sleep(2) +/obj/structure/closet/athletic_mixed/Initialize() + . = ..() new /obj/item/clothing/under/shorts/grey(src) new /obj/item/clothing/under/shorts/black(src) new /obj/item/clothing/under/shorts/red(src) @@ -28,9 +27,8 @@ name = "boxing gloves" desc = "It's a storage unit for gloves for use in the boxing ring." -/obj/structure/closet/boxinggloves/New() - ..() - sleep(2) +/obj/structure/closet/boxinggloves/Initialize() + . = ..() new /obj/item/clothing/gloves/boxing/blue(src) new /obj/item/clothing/gloves/boxing/green(src) new /obj/item/clothing/gloves/boxing/yellow(src) @@ -41,9 +39,8 @@ name = "mask closet" desc = "IT'S A STORAGE UNIT FOR FIGHTER MASKS OLE!" -/obj/structure/closet/masks/New() - ..() - sleep(2) +/obj/structure/closet/masks/Initialize() + . = ..() new /obj/item/clothing/mask/luchador(src) new /obj/item/clothing/mask/luchador/rudos(src) new /obj/item/clothing/mask/luchador/tecnicos(src) @@ -55,9 +52,8 @@ icon_state = "red" icon_closed = "red" -/obj/structure/closet/lasertag/red/New() - ..() - sleep(2) +/obj/structure/closet/lasertag/red/Initialize() + . = ..() // new /obj/item/weapon/gun/energy/laser/redtag(src) // new /obj/item/weapon/gun/energy/laser/redtag(src) new /obj/item/clothing/suit/redtag(src) @@ -70,10 +66,9 @@ icon_state = "blue" icon_closed = "blue" -/obj/structure/closet/lasertag/blue/New() - ..() - sleep(2) +/obj/structure/closet/lasertag/blue/Initialize() + . = ..() // new /obj/item/weapon/gun/energy/laser/bluetag(src) // new /obj/item/weapon/gun/energy/laser/bluetag(src) new /obj/item/clothing/suit/bluetag(src) - new /obj/item/clothing/suit/bluetag(src) \ No newline at end of file + new /obj/item/clothing/suit/bluetag(src) diff --git a/code/game/objects/structures/crates_lockers/closets/gimmick.dm b/code/game/objects/structures/crates_lockers/closets/gimmick.dm index aafd2676104e..abbf5a2e37b7 100644 --- a/code/game/objects/structures/crates_lockers/closets/gimmick.dm +++ b/code/game/objects/structures/crates_lockers/closets/gimmick.dm @@ -34,9 +34,8 @@ icon_closed = "syndicate1" icon_opened = "syndicate1open" -/obj/structure/closet/gimmick/russian/New() - ..() - sleep(2) +/obj/structure/closet/gimmick/russian/Initialize() + . = ..() new /obj/item/clothing/head/ushanka(src) new /obj/item/clothing/head/ushanka(src) new /obj/item/clothing/head/ushanka(src) @@ -56,9 +55,8 @@ icon_closed = "syndicate1" icon_opened = "syndicate1open" -/obj/structure/closet/gimmick/tacticool/New() - ..() - sleep(2) +/obj/structure/closet/gimmick/tacticool/Initialize() + . = ..() new /obj/item/clothing/glasses/eyepatch(src) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/clothing/gloves/swat(src) @@ -80,17 +78,11 @@ icon_closed = "syndicate" icon_opened = "syndicateopen" anchored = 1 - -/obj/structure/closet/thunderdome/New() - ..() - sleep(2) - /obj/structure/closet/thunderdome/tdred name = "red-team Thunderdome closet" -/obj/structure/closet/thunderdome/tdred/New() - ..() - sleep(2) +/obj/structure/closet/thunderdome/tdred/Initialize() + . = ..() new /obj/item/clothing/suit/armor/tdome/red(src) new /obj/item/clothing/suit/armor/tdome/red(src) new /obj/item/clothing/suit/armor/tdome/red(src) @@ -113,9 +105,8 @@ icon_closed = "syndicate1" icon_opened = "syndicate1open" -/obj/structure/closet/thunderdome/tdgreen/New() - ..() - sleep(2) +/obj/structure/closet/thunderdome/tdgreen/Initialize() + . = ..() new /obj/item/clothing/suit/armor/tdome/green(src) new /obj/item/clothing/suit/armor/tdome/green(src) new /obj/item/clothing/suit/armor/tdome/green(src) diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index a1994737d162..1df99dd62492 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -14,9 +14,8 @@ icon_state = "black" icon_closed = "black" -/obj/structure/closet/gmcloset/New() - ..() - sleep(2) +/obj/structure/closet/gmcloset/Initialize() + . = ..() new /obj/item/clothing/head/that(src) new /obj/item/clothing/head/that(src) new /obj/item/clothing/head/hairflower @@ -38,9 +37,8 @@ icon_state = "mixed" icon_closed = "mixed" -/obj/structure/closet/jcloset/New() - ..() - sleep(2) +/obj/structure/closet/jcloset/Initialize() + . = ..() new /obj/item/clothing/under/rank/janitor(src) new /obj/item/clothing/gloves/black(src) new /obj/item/clothing/head/soft/purple(src) @@ -63,8 +61,8 @@ icon_state = "blue" icon_closed = "blue" -/obj/structure/closet/lawcloset/New() - ..() +/obj/structure/closet/lawcloset/Initialize() + . = ..() new /obj/item/clothing/under/lawyer/female(src) new /obj/item/clothing/under/lawyer/black(src) new /obj/item/clothing/under/lawyer/red(src) @@ -73,4 +71,4 @@ new /obj/item/clothing/under/lawyer/purpsuit(src) new /obj/item/clothing/suit/storage/lawyer/purpjacket(src) new /obj/item/clothing/shoes/brown(src) - new /obj/item/clothing/shoes/black(src) \ No newline at end of file + new /obj/item/clothing/shoes/black(src) diff --git a/code/game/objects/structures/crates_lockers/closets/l3closet.dm b/code/game/objects/structures/crates_lockers/closets/l3closet.dm index 0ec2bfe1a172..fa5332c0c996 100644 --- a/code/game/objects/structures/crates_lockers/closets/l3closet.dm +++ b/code/game/objects/structures/crates_lockers/closets/l3closet.dm @@ -5,9 +5,8 @@ icon_closed = "bio" icon_opened = "bioopen" -/obj/structure/closet/l3closet/New() - ..() - sleep(2) +/obj/structure/closet/l3closet/Initialize() + . = ..() new /obj/item/clothing/suit/bio_suit/general( src ) new /obj/item/clothing/head/bio_hood/general( src ) @@ -17,9 +16,8 @@ icon_closed = "bio_general" icon_opened = "bio_generalopen" -/obj/structure/closet/l3closet/general/New() - ..() - sleep(2) +/obj/structure/closet/l3closet/general/Initialize() + . = ..() contents = list() new /obj/item/clothing/suit/bio_suit/general( src ) new /obj/item/clothing/head/bio_hood/general( src ) @@ -30,9 +28,8 @@ icon_closed = "bio_virology" icon_opened = "bio_virologyopen" -/obj/structure/closet/l3closet/virology/New() - ..() - sleep(2) +/obj/structure/closet/l3closet/virology/Initialize() + . = ..() contents = list() new /obj/item/clothing/suit/bio_suit/virology( src ) new /obj/item/clothing/head/bio_hood/virology( src ) @@ -45,9 +42,8 @@ icon_closed = "bio_security" icon_opened = "bio_securityopen" -/obj/structure/closet/l3closet/security/New() - ..() - sleep(2) +/obj/structure/closet/l3closet/security/Initialize() + . = ..() contents = list() new /obj/item/clothing/suit/bio_suit/security( src ) new /obj/item/clothing/head/bio_hood/security( src ) @@ -58,9 +54,8 @@ icon_closed = "bio_janitor" icon_opened = "bio_janitoropen" -/obj/structure/closet/l3closet/janitor/New() - ..() - sleep(2) +/obj/structure/closet/l3closet/janitor/Initialize() + . = ..() contents = list() new /obj/item/clothing/suit/bio_suit/janitor( src ) new /obj/item/clothing/head/bio_hood/janitor( src ) @@ -71,9 +66,8 @@ icon_closed = "bio_scientist" icon_opened = "bio_scientistopen" -/obj/structure/closet/l3closet/scientist/New() - ..() - sleep(2) +/obj/structure/closet/l3closet/scientist/Initialize() + . = ..() contents = list() new /obj/item/clothing/suit/bio_suit/scientist( src ) - new /obj/item/clothing/head/bio_hood/scientist( src ) \ No newline at end of file + new /obj/item/clothing/head/bio_hood/scientist( src ) diff --git a/code/game/objects/structures/crates_lockers/closets/malfunction.dm b/code/game/objects/structures/crates_lockers/closets/malfunction.dm index 60b9d11086fd..3d7e45928200 100644 --- a/code/game/objects/structures/crates_lockers/closets/malfunction.dm +++ b/code/game/objects/structures/crates_lockers/closets/malfunction.dm @@ -5,13 +5,12 @@ icon_closed = "syndicate" icon_opened = "syndicateopen" -/obj/structure/closet/malf/suits/New() - ..() - sleep(2) +/obj/structure/closet/malf/suits/Initialize() + . = ..() new /obj/item/tank/jetpack/void(src) new /obj/item/clothing/mask/breath(src) new /obj/item/clothing/head/helmet/space/uscm(src) new /obj/item/clothing/suit/space/uscm(src) new /obj/item/tool/crowbar(src) new /obj/item/cell(src) - new /obj/item/device/multitool(src) \ No newline at end of file + new /obj/item/device/multitool(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm index 53917b2bde9d..61fb7fd0e2e2 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm @@ -8,20 +8,17 @@ icon_broken = "secureqmbroken" icon_off = "secureqmoff" - New() - ..() - sleep(2) - new /obj/item/clothing/under/rank/cargo(src) - new /obj/item/clothing/shoes/brown(src) -// new /obj/item/device/radio/headset/almayer/ct(src) - new /obj/item/clothing/gloves/black(src) -// new /obj/item/cartridge/quartermaster(src) - new /obj/item/clothing/suit/fire/firefighter(src) - new /obj/item/tank/emergency_oxygen(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/clothing/glasses/meson(src) - new /obj/item/clothing/head/soft(src) - return +/obj/structure/closet/secure_closet/quartermaster/Initialize() + . = ..() + new /obj/item/clothing/under/rank/cargo(src) + new /obj/item/clothing/shoes/brown(src) + new /obj/item/clothing/gloves/black(src) + new /obj/item/clothing/suit/fire/firefighter(src) + new /obj/item/tank/emergency_oxygen(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/clothing/glasses/meson(src) + new /obj/item/clothing/head/soft(src) + return @@ -38,9 +35,8 @@ icon_off = "miningsecoff" req_access = list(ACCESS_CIVILIAN_PUBLIC) -/obj/structure/closet/secure_closet/miner/New() - ..() - sleep(2) +/obj/structure/closet/secure_closet/miner/Initialize() + . = ..() if(prob(50)) new /obj/item/storage/backpack/industrial(src) else diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cm_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/cm_closets.dm index 5b9fa075790c..2b047ee54b40 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/cm_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/cm_closets.dm @@ -14,7 +14,7 @@ GLOBAL_LIST_EMPTY(co_secure_boxes) icon_off = "secure_closed_commander" /obj/structure/closet/secure_closet/commander/Initialize() - ..() + . = ..() new /obj/item/storage/mateba_case/captain(src) new /obj/item/storage/backpack/mcommander(src) new /obj/item/clothing/glasses/sunglasses(src) @@ -122,7 +122,7 @@ GLOBAL_LIST_EMPTY(co_secure_boxes) new /obj/item/stack/fulton(src) /obj/structure/closet/secure_closet/staff_officer/intel/select_gamemode_equipment(gamemode) - if (map_tag in MAPS_COLD_TEMP) + if (SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) new /obj/item/clothing/mask/rebreather/scarf(src) /obj/structure/closet/secure_closet/pilot_officer @@ -148,7 +148,7 @@ GLOBAL_LIST_EMPTY(co_secure_boxes) new /obj/item/clothing/glasses/sunglasses(src) /obj/structure/closet/secure_closet/pilot_officer/select_gamemode_equipment(gamemode) - if (map_tag in MAPS_COLD_TEMP) + if (SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) new /obj/item/clothing/mask/rebreather/scarf(src) new /obj/item/clothing/mask/rebreather/scarf(src) @@ -255,7 +255,8 @@ GLOBAL_LIST_EMPTY(co_secure_boxes) /obj/structure/closet/secure_closet/medical_doctor/Initialize() . = ..() new /obj/item/storage/backpack/marine/satchel(src) - if(z != 1) new /obj/item/device/radio/headset/almayer/doc(src) + if(!is_ground_level(z)) + new /obj/item/device/radio/headset/almayer/doc(src) new /obj/item/clothing/shoes/white(src) new /obj/item/clothing/shoes/white(src) new /obj/item/storage/belt/medical/full(src) @@ -269,7 +270,7 @@ GLOBAL_LIST_EMPTY(co_secure_boxes) new /obj/item/clothing/glasses/hud/health(src) /obj/structure/closet/secure_closet/medical_doctor/select_gamemode_equipment(gamemode) - if (map_tag in MAPS_COLD_TEMP) + if (SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) new /obj/item/clothing/suit/storage/snow_suit/doctor(src) new /obj/item/clothing/mask/rebreather/scarf(src) @@ -360,4 +361,4 @@ GLOBAL_LIST_EMPTY(co_secure_boxes) new /obj/item/device/radio/headset/almayer/mcom(src) new /obj/item/clothing/under/marine/officer/bridge(src) new /obj/item/clothing/shoes/dress(src) - new /obj/item/storage/backpack/marine/satchel(src) \ No newline at end of file + new /obj/item/storage/backpack/marine/satchel(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index a1843d8b0099..d5b2d8ef7eee 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -116,7 +116,7 @@ if(!is_mainship_level(z) && prob(70)) new /obj/item/clothing/accessory/storage/black_vest/brown_vest(src) else new /obj/item/clothing/accessory/storage/webbing(src) new /obj/item/storage/toolbox/mechanical(src) - if(z != 1) + if(!is_ground_level(z)) new /obj/item/device/radio/headset/almayer/mt(src) new /obj/item/clothing/accessory/storage/black_vest/brown_vest(src) new /obj/item/clothing/suit/storage/hazardvest(src) @@ -130,7 +130,7 @@ new /obj/item/storage/backpack/industrial(src) /obj/structure/closet/secure_closet/engineering_personal/select_gamemode_equipment(gamemode) - if (map_tag in MAPS_COLD_TEMP) + if (SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) new /obj/item/clothing/suit/storage/snow_suit(src) new /obj/item/clothing/mask/rebreather/scarf(src) @@ -152,7 +152,7 @@ new /obj/item/storage/backpack/industrial(src) new /obj/item/device/flashlight(src) new /obj/item/tool/extinguisher(src) - if(z != 1) + if(!is_ground_level(z)) new /obj/item/device/radio/headset/almayer/mt(src) new /obj/item/clothing/accessory/storage/black_vest/brown_vest(src) new /obj/item/clothing/suit/storage/hazardvest(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm b/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm index 4fa9d30126b4..247fcd49edac 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm @@ -73,8 +73,8 @@ // req_access = list(ACCESS_MARINE_BRIG) req_level = SEC_LEVEL_RED -/obj/structure/closet/secure_closet/guncabinet/mp_armory/New() - ..() +/obj/structure/closet/secure_closet/guncabinet/mp_armory/Initialize() + . = ..() new /obj/item/weapon/gun/shotgun/combat(src) new /obj/item/weapon/gun/shotgun/combat(src) new /obj/item/ammo_magazine/shotgun/slugs(src) @@ -90,8 +90,8 @@ storage_capacity = 55 //lots of stuff to fit in req_level = SEC_LEVEL_RED -/obj/structure/closet/secure_closet/guncabinet/riot_control/New() - ..() +/obj/structure/closet/secure_closet/guncabinet/riot_control/Initialize() + . = ..() new /obj/item/weapon/gun/shotgun/pump(src, TRUE) new /obj/item/weapon/gun/shotgun/pump(src, TRUE) new /obj/item/weapon/gun/shotgun/pump(src, TRUE) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm index a0912c54ffd4..2236b026918a 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm @@ -9,19 +9,16 @@ icon_off = "hydrosecureoff" - New() - ..() - sleep(2) - switch(rand(1,2)) - if(1) - new /obj/item/clothing/suit/apron(src) - if(2) - new /obj/item/clothing/suit/storage/apron/overalls(src) - new /obj/item/storage/bag/plants(src) - new /obj/item/clothing/under/rank/hydroponics(src) - new /obj/item/device/analyzer/plant_analyzer(src) - new /obj/item/clothing/head/greenbandana(src) - new /obj/item/tool/minihoe(src) - new /obj/item/tool/hatchet(src) -// new /obj/item/tool/bee_net(src) //No more bees, March 2014 - return \ No newline at end of file +/obj/structure/closet/secure_closet/hydroponics/Initialize() + . = ..() + switch(rand(1,2)) + if(1) + new /obj/item/clothing/suit/apron(src) + if(2) + new /obj/item/clothing/suit/storage/apron/overalls(src) + new /obj/item/storage/bag/plants(src) + new /obj/item/clothing/under/rank/hydroponics(src) + new /obj/item/device/analyzer/plant_analyzer(src) + new /obj/item/clothing/head/greenbandana(src) + new /obj/item/tool/minihoe(src) + new /obj/item/tool/hatchet(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm index 0d19a35b32d0..d1515247807d 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -4,27 +4,23 @@ req_access = list(ACCESS_CIVILIAN_PUBLIC) var/registered_name = null -/obj/structure/closet/secure_closet/personal/New() - ..() - spawn(2) - if(prob(50)) - new /obj/item/storage/backpack(src) - else - new /obj/item/storage/backpack/satchel/norm(src) - new /obj/item/device/radio/headset( src ) - return +/obj/structure/closet/secure_closet/personal/Initialize() + . = ..() + if(prob(50)) + new /obj/item/storage/backpack(src) + else + new /obj/item/storage/backpack/satchel/norm(src) + new /obj/item/device/radio/headset( src ) /obj/structure/closet/secure_closet/personal/patient name = "patient's closet" -/obj/structure/closet/secure_closet/personal/patient/New() - ..() - spawn(4) - contents = list() - new /obj/item/clothing/under/color/white( src ) - new /obj/item/clothing/shoes/white( src ) - return +/obj/structure/closet/secure_closet/personal/patient/Initialize() + . = ..() + contents = list() + new /obj/item/clothing/under/color/white( src ) + new /obj/item/clothing/shoes/white( src ) @@ -48,13 +44,11 @@ else icon_state = icon_opened -/obj/structure/closet/secure_closet/personal/cabinet/New() - ..() - spawn(4) - contents = list() - new /obj/item/storage/backpack/satchel( src ) - new /obj/item/device/radio/headset( src ) - return +/obj/structure/closet/secure_closet/personal/cabinet/Initialize() + . = ..() + contents = list() + new /obj/item/storage/backpack/satchel( src ) + new /obj/item/device/radio/headset( src ) /obj/structure/closet/secure_closet/personal/attackby(obj/item/W as obj, mob/user as mob) if (src.opened) @@ -106,4 +100,4 @@ src.icon_state = src.icon_locked src.registered_name = null src.desc = "It's a secure locker for personnel. The first card swiped gains control." - return \ No newline at end of file + return diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index d5bc3bfe6de2..eba6704f92e6 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -8,18 +8,14 @@ icon_broken = "secureresbroken" icon_off = "secureresoff" - New() - ..() - sleep(2) - new /obj/item/clothing/under/marine/officer/researcher(src) - new /obj/item/clothing/under/marine/officer/researcher(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/clothing/shoes/white(src) -// new /obj/item/cartridge/signal/science(src) -// new /obj/item/device/radio/headset/headset_sci(src) - new /obj/item/tank/air(src) - new /obj/item/clothing/mask/gas(src) - return +/obj/structure/closet/secure_closet/scientist/Initialize() + . = ..() + new /obj/item/clothing/under/marine/officer/researcher(src) + new /obj/item/clothing/under/marine/officer/researcher(src) + new /obj/item/clothing/suit/storage/labcoat(src) + new /obj/item/clothing/shoes/white(src) + new /obj/item/tank/air(src) + new /obj/item/clothing/mask/gas(src) @@ -33,18 +29,15 @@ icon_broken = "rdsecurebroken" icon_off = "rdsecureoff" - New() - ..() - sleep(2) - new /obj/item/clothing/suit/bio_suit/scientist(src) - new /obj/item/clothing/head/bio_hood/scientist(src) - new /obj/item/clothing/under/rank/rdalt(src) - new /obj/item/clothing/suit/storage/labcoat(src) - new /obj/item/clothing/shoes/white(src) - new /obj/item/clothing/shoes/leather(src) - new /obj/item/clothing/gloves/latex(src) -// new /obj/item/device/radio/headset/heads/rd(src) - new /obj/item/tank/air(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/device/flash(src) - return \ No newline at end of file +/obj/structure/closet/secure_closet/RD/Initialize() + . = ..() + new /obj/item/clothing/suit/bio_suit/scientist(src) + new /obj/item/clothing/head/bio_hood/scientist(src) + new /obj/item/clothing/under/rank/rdalt(src) + new /obj/item/clothing/suit/storage/labcoat(src) + new /obj/item/clothing/shoes/white(src) + new /obj/item/clothing/shoes/leather(src) + new /obj/item/clothing/gloves/latex(src) + new /obj/item/tank/air(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/device/flash(src) diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index 0bbbad77a04b..46fa1fb63fcf 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -9,8 +9,8 @@ icon_state = "red" icon_closed = "red" -/obj/structure/closet/wardrobe/red/New() - ..() +/obj/structure/closet/wardrobe/red/Initialize() + . = ..() new /obj/item/clothing/under/rank/security(src) new /obj/item/clothing/under/rank/security(src) new /obj/item/clothing/under/rank/security(src) @@ -36,8 +36,8 @@ icon_state = "black" icon_closed = "black" -/obj/structure/closet/wardrobe/black/New() - ..() +/obj/structure/closet/wardrobe/black/Initialize() + . = ..() new /obj/item/clothing/under/color/black(src) new /obj/item/clothing/under/color/black(src) new /obj/item/clothing/under/color/black(src) @@ -56,8 +56,8 @@ icon_state = "black" icon_closed = "black" -/obj/structure/closet/wardrobe/chaplain_black/New() - ..() +/obj/structure/closet/wardrobe/chaplain_black/Initialize() + . = ..() new /obj/item/clothing/under/rank/chaplain(src) new /obj/item/clothing/shoes/black(src) new /obj/item/clothing/suit/nun(src) @@ -75,8 +75,8 @@ icon_state = "green" icon_closed = "green" -/obj/structure/closet/wardrobe/green/New() - ..() +/obj/structure/closet/wardrobe/green/Initialize() + . = ..() new /obj/item/clothing/under/color/green(src) new /obj/item/clothing/under/color/green(src) new /obj/item/clothing/under/color/green(src) @@ -90,8 +90,8 @@ icon_state = "green" icon_closed = "green" -/obj/structure/closet/wardrobe/xenos/New() - ..() +/obj/structure/closet/wardrobe/xenos/Initialize() + . = ..() new /obj/item/clothing/suit/unathi/mantle(src) new /obj/item/clothing/suit/unathi/robe(src) new /obj/item/clothing/shoes/sandal(src) @@ -106,8 +106,8 @@ icon_state = "orange" icon_closed = "orange" -/obj/structure/closet/wardrobe/orange/New() - ..() +/obj/structure/closet/wardrobe/orange/Initialize() + . = ..() new /obj/item/clothing/under/color/orange(src) new /obj/item/clothing/under/color/orange(src) new /obj/item/clothing/under/color/orange(src) @@ -122,8 +122,8 @@ icon_state = "yellow" icon_closed = "yellow" -/obj/structure/closet/wardrobe/atmospherics_yellow/New() - ..() +/obj/structure/closet/wardrobe/atmospherics_yellow/Initialize() + . = ..() new /obj/item/clothing/under/rank/atmospheric_technician(src) new /obj/item/clothing/under/rank/atmospheric_technician(src) new /obj/item/clothing/under/rank/atmospheric_technician(src) @@ -145,8 +145,8 @@ icon_state = "yellow" icon_closed = "yellow" -/obj/structure/closet/wardrobe/engineering_yellow/New() - ..() +/obj/structure/closet/wardrobe/engineering_yellow/Initialize() + . = ..() new /obj/item/clothing/under/rank/engineer(src) new /obj/item/clothing/under/rank/engineer(src) new /obj/item/clothing/under/rank/engineer(src) @@ -167,8 +167,8 @@ icon_state = "white" icon_closed = "white" -/obj/structure/closet/wardrobe/white/New() - ..() +/obj/structure/closet/wardrobe/white/Initialize() + . = ..() new /obj/item/clothing/under/color/white(src) new /obj/item/clothing/under/color/white(src) new /obj/item/clothing/under/color/white(src) @@ -183,8 +183,8 @@ icon_state = "white" icon_closed = "white" -/obj/structure/closet/wardrobe/pjs/New() - ..() +/obj/structure/closet/wardrobe/pjs/Initialize() + . = ..() new /obj/item/clothing/under/pj/red(src) new /obj/item/clothing/under/pj/red(src) new /obj/item/clothing/under/pj/blue(src) @@ -201,8 +201,8 @@ icon_state = "white" icon_closed = "white" -/obj/structure/closet/wardrobe/toxins_white/New() - ..() +/obj/structure/closet/wardrobe/toxins_white/Initialize() + . = ..() new /obj/item/clothing/under/rank/scientist(src) new /obj/item/clothing/under/rank/scientist(src) new /obj/item/clothing/under/rank/scientist(src) @@ -223,8 +223,8 @@ icon_state = "black" icon_closed = "black" -/obj/structure/closet/wardrobe/robotics_black/New() - ..() +/obj/structure/closet/wardrobe/robotics_black/Initialize() + . = ..() new /obj/item/clothing/under/rank/roboticist(src) new /obj/item/clothing/under/rank/roboticist(src) new /obj/item/clothing/suit/storage/labcoat(src) @@ -241,8 +241,8 @@ icon_state = "white" icon_closed = "white" -/obj/structure/closet/wardrobe/chemistry_white/New() - ..() +/obj/structure/closet/wardrobe/chemistry_white/Initialize() + . = ..() new /obj/item/clothing/under/rank/chemist(src) new /obj/item/clothing/under/rank/chemist(src) new /obj/item/clothing/shoes/white(src) @@ -257,8 +257,8 @@ icon_state = "white" icon_closed = "white" -/obj/structure/closet/wardrobe/genetics_white/New() - ..() +/obj/structure/closet/wardrobe/genetics_white/Initialize() + . = ..() new /obj/item/clothing/under/rank/geneticist(src) new /obj/item/clothing/under/rank/geneticist(src) new /obj/item/clothing/shoes/white(src) @@ -273,8 +273,8 @@ icon_state = "white" icon_closed = "white" -/obj/structure/closet/wardrobe/virology_white/New() - ..() +/obj/structure/closet/wardrobe/virology_white/Initialize() + . = ..() new /obj/item/clothing/under/rank/virologist(src) new /obj/item/clothing/under/rank/virologist(src) new /obj/item/clothing/shoes/white(src) @@ -291,8 +291,8 @@ icon_state = "white" icon_closed = "white" -/obj/structure/closet/wardrobe/medic_white/New() - ..() +/obj/structure/closet/wardrobe/medic_white/Initialize() + . = ..() new /obj/item/clothing/under/rank/medical(src) new /obj/item/clothing/under/rank/medical(src) new /obj/item/clothing/under/rank/medical/blue(src) @@ -312,8 +312,8 @@ icon_state = "grey" icon_closed = "grey" -/obj/structure/closet/wardrobe/grey/New() - ..() +/obj/structure/closet/wardrobe/grey/Initialize() + . = ..() new /obj/item/clothing/under/color/grey(src) new /obj/item/clothing/under/color/grey(src) new /obj/item/clothing/under/color/grey(src) @@ -331,8 +331,8 @@ icon_state = "mixed" icon_closed = "mixed" -/obj/structure/closet/wardrobe/mixed/New() - ..() +/obj/structure/closet/wardrobe/mixed/Initialize() + . = ..() new /obj/item/clothing/under/color/blue(src) new /obj/item/clothing/under/color/yellow(src) new /obj/item/clothing/under/color/green(src) @@ -352,8 +352,8 @@ icon_closed = "syndicate1" icon_opened = "syndicate1open" -/obj/structure/closet/wardrobe/tactical/New() - ..() +/obj/structure/closet/wardrobe/tactical/Initialize() + . = ..() new /obj/item/clothing/under/tactical(src) new /obj/item/clothing/suit/armor/tactical(src) new /obj/item/clothing/head/helmet/tactical(src) @@ -369,8 +369,8 @@ icon_state = "mixed" icon_closed = "mixed" -/obj/structure/closet/wardrobe/suit/New() - ..() +/obj/structure/closet/wardrobe/suit/Initialize() + . = ..() new /obj/item/clothing/under/assistantformal(src) new /obj/item/clothing/under/suit_jacket/charcoal(src) new /obj/item/clothing/under/suit_jacket/navy(src) diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index 04f6cb35669c..4f996325f013 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -98,16 +98,14 @@ /obj/item/clothing/under/marine, /obj/item/clothing/shoes/marine) -/obj/structure/largecrate/random/New() - ..() +/obj/structure/largecrate/random/Initialize() + . = ..() if(!num_things) num_things = rand(0,3) - while(num_things) - if(!num_things) - break - num_things-- + for(var/i in 1 to num_things) var/obj/item/thing = pick(stuff) new thing(src) + num_things = 0 /obj/structure/largecrate/random/case name = "storage case" diff --git a/code/game/objects/structures/crates_lockers/largecrate_supplies.dm b/code/game/objects/structures/crates_lockers/largecrate_supplies.dm index c10b2a079528..f9a6979fac52 100644 --- a/code/game/objects/structures/crates_lockers/largecrate_supplies.dm +++ b/code/game/objects/structures/crates_lockers/largecrate_supplies.dm @@ -85,14 +85,13 @@ name = "supply crate" var/list/supplies = list() -/obj/structure/largecrate/supply/New() - ..() +/obj/structure/largecrate/supply/Initialize() + . = ..() if(supplies.len) for(var/s in supplies) var/amount = supplies[s] for(var/i = 1, i <= amount, i++) new s (src) - sleep(-1) /obj/structure/largecrate/supply/weapons name = "weapons chest" diff --git a/code/game/objects/structures/crates_lockers/secure_crates.dm b/code/game/objects/structures/crates_lockers/secure_crates.dm index fbbae521f7dd..73189173ebca 100644 --- a/code/game/objects/structures/crates_lockers/secure_crates.dm +++ b/code/game/objects/structures/crates_lockers/secure_crates.dm @@ -11,8 +11,8 @@ var/broken = 0 var/locked = 1 -/obj/structure/closet/crate/secure/New() - ..() +/obj/structure/closet/crate/secure/Initialize() + . = ..() update_icon() diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm index b1c92ba6e1ad..15b1efcf78f4 100644 --- a/code/game/objects/structures/fence.dm +++ b/code/game/objects/structures/fence.dm @@ -184,8 +184,8 @@ density = 0 update_icon() //Make it appear cut through! -/obj/structure/fence/New(Loc, start_dir = null, constructed = 0) - ..() +/obj/structure/fence/Initialize(mapload, start_dir = null, constructed = 0) + . = ..() if(start_dir) dir = start_dir diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 7e6091ad1b8e..20ac39b1e793 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -39,7 +39,7 @@ PLANT_CUT_MACHETE = 3 = Needs at least a machete to be cut down var/fire_flag = FLORA_NO_BURN var/center = TRUE //Determine if we want less or more ash when burned -/obj/structure/flora/New() +/obj/structure/flora/Initialize() . = ..() if(icon_tag) icon_state = "[icon_tag]_[rand(1,variations)]" @@ -168,8 +168,8 @@ ICE GRASS unacidable = TRUE var/overlay_type = "tallgrass_overlay" -/obj/structure/flora/grass/tallgrass/New() - ..() +/obj/structure/flora/grass/tallgrass/Initialize() + . = ..() update_icon() /obj/structure/flora/grass/tallgrass/update_icon() diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 1eb8b6b7cb50..75d872e47a94 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -20,8 +20,8 @@ var/width = 3 health = 50 -/obj/structure/grille/fence/New() - ..() +/obj/structure/grille/fence/Initialize() + . = ..() if(width > 1) if(dir in list(EAST, WEST)) diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 8747e95c5fc9..52d08275e3ab 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -264,12 +264,12 @@ item_state = "syringe_kit" max_storage_space = 21 - New() - ..() - new /obj/item/inflatable/door(src) - new /obj/item/inflatable/door(src) - new /obj/item/inflatable/door(src) - new /obj/item/inflatable(src) - new /obj/item/inflatable(src) - new /obj/item/inflatable(src) - new /obj/item/inflatable(src) +/obj/item/storage/briefcase/inflatable/Initialize() + . = ..() + new /obj/item/inflatable/door(src) + new /obj/item/inflatable/door(src) + new /obj/item/inflatable/door(src) + new /obj/item/inflatable(src) + new /obj/item/inflatable(src) + new /obj/item/inflatable(src) + new /obj/item/inflatable(src) diff --git a/code/game/objects/structures/lamarr_cage.dm b/code/game/objects/structures/lamarr_cage.dm index 20803fe79019..de9a58750098 100644 --- a/code/game/objects/structures/lamarr_cage.dm +++ b/code/game/objects/structures/lamarr_cage.dm @@ -83,9 +83,6 @@ sterile = 1 gender = FEMALE -/obj/item/clothing/mask/facehugger/lamarr/New()//to prevent deleting it if aliums are disabled - return - /obj/item/clothing/mask/facehugger/lamarr/Die() if(stat == DEAD) return @@ -102,4 +99,3 @@ layer = BELOW_MOB_LAYER //so dead hugger appears below live hugger if stacked on same tile. //override function prevents Lamarr from decaying like other huggers so you can keep it in your helmet, otherwise the code is identical. return - \ No newline at end of file diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 7b06ec1bd7f9..81cdcfae0e39 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -8,10 +8,10 @@ layer = LATTICE_LAYER // flags = CONDUCT -/obj/structure/lattice/New() - ..() +/obj/structure/lattice/Initialize() + . = ..() if(!istype(src.loc, /turf/open/space)) - qdel(src) + return INITIALIZE_HINT_QDEL for(var/obj/structure/lattice/LAT in src.loc) if(LAT != src) qdel(LAT) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 832b851cf107..6b14bd24654f 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -15,8 +15,8 @@ anchored = 1 throwpass = 1 -/obj/structure/morgue/New() - ..() +/obj/structure/morgue/Initialize() + . = ..() connected = new tray_path(src) /obj/structure/morgue/Destroy() diff --git a/code/game/objects/structures/pipes/pipes.dm b/code/game/objects/structures/pipes/pipes.dm index 3cdfbe656428..dbce9b06e71d 100644 --- a/code/game/objects/structures/pipes/pipes.dm +++ b/code/game/objects/structures/pipes/pipes.dm @@ -15,7 +15,7 @@ /obj/structure/pipes/Initialize(mapload, ...) . = ..() - + if(!icon_manager) icon_manager = new() @@ -30,7 +30,7 @@ if(mapload) create_valid_directions() - + search_for_connections() /obj/structure/pipes/Destroy() @@ -59,7 +59,7 @@ playsound(loc, 'sound/items/Ratchet.ogg', 25, 1) user.visible_message(SPAN_NOTICE("[user] unfastens [src]."), SPAN_NOTICE("You unfasten [src].")) - new /obj/item/pipe(loc, make_from = src) + new /obj/item/pipe(loc, null, null, src) qdel(src) /obj/structure/pipes/proc/create_valid_directions() @@ -130,11 +130,11 @@ playsound(user, pick('sound/effects/alien_ventpass1.ogg', 'sound/effects/alien_ventpass2.ogg'), 35, 1) return - + user.forceMove(next_pipe) user.client.eye = next_pipe //if we don't do this, Byond only updates the eye every tick - required for smooth movement user.update_pipe_icons(next_pipe) - + if(world.time - user.last_played_vent > VENT_SOUND_DELAY) user.last_played_vent = world.time playsound(src, pick('sound/effects/alien_ventcrawl1.ogg', 'sound/effects/alien_ventcrawl2.ogg'), 25, 1) @@ -176,4 +176,4 @@ return node.pipe_color -#undef VENT_SOUND_DELAY \ No newline at end of file +#undef VENT_SOUND_DELAY diff --git a/code/game/objects/structures/pipes/standard/manifolds.dm b/code/game/objects/structures/pipes/standard/manifolds.dm index 5117ba610497..ddeb415cb663 100644 --- a/code/game/objects/structures/pipes/standard/manifolds.dm +++ b/code/game/objects/structures/pipes/standard/manifolds.dm @@ -35,7 +35,7 @@ alpha = 255 if(!length(connected_to)) - new /obj/item/pipe(loc, make_from = src) + new /obj/item/pipe(loc, null, null, src) qdel(src) else overlays.Cut() @@ -47,7 +47,7 @@ var/turf/T = get_turf(src) for(var/D in valid_directions) add_underlay(T, D) - + ..() /obj/structure/pipes/standard/manifold/visible @@ -192,4 +192,4 @@ color = PIPE_COLOR_GREEN /obj/structure/pipes/standard/manifold/fourway/hidden/purple - color = PIPE_COLOR_PURPLE \ No newline at end of file + color = PIPE_COLOR_PURPLE diff --git a/code/game/objects/structures/pipes/vents/vents.dm b/code/game/objects/structures/pipes/vents/vents.dm index 528c03b8f44e..34fbb212a0b8 100644 --- a/code/game/objects/structures/pipes/vents/vents.dm +++ b/code/game/objects/structures/pipes/vents/vents.dm @@ -116,11 +116,11 @@ playsound(loc, 'sound/items/Ratchet.ogg', 25, 1) user.visible_message(SPAN_NOTICE("[user] unfastens [src]."), SPAN_NOTICE("You unfasten [src].")) - new /obj/item/pipe(loc, make_from = src) + new /obj/item/pipe(loc, null, null, src) qdel(src) /obj/structure/pipes/vents/Destroy() if(initial_loc) initial_loc.air_vent_info -= id_tag initial_loc.air_vent_names -= id_tag - . = ..() \ No newline at end of file + . = ..() diff --git a/code/game/objects/structures/platforms.dm b/code/game/objects/structures/platforms.dm index 94a1bf6791d9..06bc4e452b5a 100644 --- a/code/game/objects/structures/platforms.dm +++ b/code/game/objects/structures/platforms.dm @@ -15,7 +15,8 @@ flags_atom = ON_BORDER unacidable = TRUE -/obj/structure/platform/New() +/obj/structure/platform/Initialize() + . = ..() var/image/I = image(icon, src, "platform_overlay", LADDER_LAYER, dir)//ladder layer puts us just above weeds. switch(dir) if(SOUTH) @@ -30,7 +31,6 @@ I.pixel_x = -16 layer = ABOVE_MOB_LAYER+0.1 overlays += I - ..() /obj/structure/platform/initialize_pass_flags(var/datum/pass_flags_container/PF) ..() @@ -60,7 +60,8 @@ obj/structure/platform_decoration flags_atom = ON_BORDER unacidable = TRUE -/obj/structure/platform_decoration/New() +/obj/structure/platform_decoration/Initialize() + . = ..() switch(dir) if (NORTH) layer = ABOVE_MOB_LAYER+0.1 @@ -70,7 +71,6 @@ obj/structure/platform_decoration layer = ABOVE_MOB_LAYER+0.1 if (SOUTHWEST) layer = ABOVE_MOB_LAYER+0.1 - .. () /obj/structure/platform_decoration/initialize_pass_flags(var/datum/pass_flags_container/PF) ..() diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index d347227f2493..c2ad4a6ff0fd 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -10,15 +10,18 @@ FLOOR SAFES name = "Secure Safe Combination" var/obj/structure/safe/safe = null -/obj/item/paper/safe_key/New() - ..() - spawn(10) - for(var/obj/structure/safe/safe in loc) - if(safe) - info = "This looks like a handwritten page with two numbers on it: \n\n[safe.tumbler_1_open]|[safe.tumbler_2_open]." - info_links = info - icon_state = "paper_words" - break +/obj/item/paper/safe_key/Initialize() + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/item/paper/safe_key/LateInitialize() + . = ..() + for(var/obj/structure/safe/safe in loc) + if(safe) + info = "This looks like a handwritten page with two numbers on it: \n\n[safe.tumbler_1_open]|[safe.tumbler_2_open]." + info_links = info + icon_state = "paper_words" + break /obj/structure/safe name = "safe" @@ -41,8 +44,8 @@ FLOOR SAFES var/maxspace = 24 //the maximum combined w_class of stuff in the safe -/obj/structure/safe/New() - ..() +/obj/structure/safe/Initialize() + . = ..() tumbler_1_pos = 0 tumbler_1_open = (rand(0,10) * 5) @@ -53,21 +56,15 @@ FLOOR SAFES //adding an objective for cracking open the safe new /datum/cm_objective/crack_safe(src) - spawn(5) - if(loc && spawnkey) - new /obj/item/paper/safe_key(loc) //Spawn the key on top of the safe. - -/obj/structure/safe/Initialize() - . = ..() for(var/obj/item/I in loc) - if(istype(I,/obj/item/paper/safe_key)) - continue if(space >= maxspace) return if(I.w_class + space <= maxspace) space += I.w_class I.forceMove(src) + if(spawnkey) + new /obj/item/paper/safe_key(loc) //Spawn the key on top of the safe. /obj/structure/safe/proc/check_unlocked(mob/user as mob, canhear) if(user && canhear) diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index cf202feb1b27..238cc2d596aa 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -240,8 +240,8 @@ obj/structure/bed/Destroy() icon_state = "folded" var/obj/item/roller/held -/obj/item/roller_holder/New() - ..() +/obj/item/roller_holder/Initialize() + . = ..() held = new /obj/item/roller(src) /obj/item/roller_holder/attack_self(mob/user as mob) @@ -324,7 +324,7 @@ var/global/list/activated_medevac_stretchers = list() update_icon() else - if(z != 1) + if(!is_ground_level(z)) to_chat(user, SPAN_WARNING("You can't activate [src]'s beacon here.")) return diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 64ee5173dfe7..75b1a382ff54 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -9,13 +9,11 @@ buckle_lying = FALSE var/propelled = 0 //Check for fire-extinguisher-driven chairs -/obj/structure/bed/chair/New() +/obj/structure/bed/chair/Initialize() + . = ..() if(anchored) verbs -= /atom/movable/verb/pull - ..() - spawn(3) //Sorry. i don't think there's a better way to do this. - handle_rotation() - return + handle_rotation() /obj/structure/bed/chair/handle_rotation() //Making this into a seperate proc so office chairs can call it on Move() if(src.dir == NORTH) @@ -155,15 +153,13 @@ /obj/structure/bed/chair/dropship/passenger/ex_act(severity) return -/obj/structure/bed/chair/dropship/passenger/New() +/obj/structure/bed/chair/dropship/passenger/Initialize() + . = ..() chairbar = image("icons/obj/objects.dmi", "hotseat_bars") chairbar.layer = ABOVE_MOB_LAYER - return ..() - -/obj/structure/bed/chair/dropship/passenger/shuttle_chair/New() +/obj/structure/bed/chair/dropship/passenger/shuttle_chair/Initialize() . = ..() - chairbar = image("icons/obj/objects.dmi", "hotseat_bars") chairbar.layer = ABOVE_MOB_LAYER diff --git a/code/game/smoothwall.dm b/code/game/smoothwall.dm index b999610343b3..73afca652eaa 100644 --- a/code/game/smoothwall.dm +++ b/code/game/smoothwall.dm @@ -131,7 +131,7 @@ k.relativewall() break - T = locate(x, y-1, z) + T = get_step(src, SOUTH) for(j in tiles_with) if(istype(T, j)) T.relativewall() @@ -152,7 +152,7 @@ k.relativewall() break - T = locate(x-1, y, z) + T = get_step(src, WEST) for(j in tiles_with) if(istype(T, j)) T.relativewall() @@ -252,4 +252,4 @@ turf/open/asphalt/cement_sunbleached/relativewall() junction |= i break - handle_icon_junction(junction) \ No newline at end of file + handle_icon_junction(junction) diff --git a/code/game/sound.dm b/code/game/sound.dm index adbee0049c13..2e2e6f22807d 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -67,14 +67,14 @@ S.y = turf_source.y S.z = turf_source.z - if(!interior_manager) + if(!GLOB.interior_manager) SSsound.queue(S) return S.channel var/list/datum/interior/extra_interiors = list() // If we're in an interior, range the chunk, then adjust to do so from outside instead - if(turf_source.z == interior_manager.interior_z) - var/datum/interior/VI = interior_manager.get_interior_by_coords(turf_source.x, turf_source.y) + if(turf_source.z == GLOB.interior_manager.interior_z) + var/datum/interior/VI = GLOB.interior_manager.get_interior_by_coords(turf_source.x, turf_source.y) if(VI?.ready) extra_interiors |= VI if(VI.exterior) @@ -84,7 +84,7 @@ S.z = new_turf_source.z else sound_range = 0 // Range for 'nearby interiors' aswell - for(var/datum/interior/VI in interior_manager.interiors) + for(var/datum/interior/VI in GLOB.interior_manager.interiors) if(VI?.ready && VI.exterior?.z == turf_source.z && get_dist(VI.exterior, turf_source) <= sound_range) extra_interiors |= VI diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index efc36b457a4c..787531c70bbb 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -1,6 +1,4 @@ //Config stuff -#define SUPPLY_DOCKZ 2 //Z-level of the Dock. -#define SUPPLY_STATIONZ 1 //Z-level of the Station. #define SUPPLY_STATION_AREATYPE /area/supply/station //Type of the supply shuttle area for station #define SUPPLY_STATION_AREATYPE_VEHICLE /area/supply/station/vehicle #define SUPPLY_DOCK_AREATYPE /area/supply/dock //Type of the supply shuttle area for dock @@ -224,8 +222,13 @@ var/datum/controller/supply/supply_controller = new() var/x_coord = deobfuscate_x(x_supply) var/y_coord = deobfuscate_y(y_supply) + var/z_coord = SSmapping.levels_by_trait(ZTRAIT_GROUND) + if(length(z_coord)) + z_coord = z_coord[1] + else + z_coord = 1 // fuck it - var/turf/T = locate(x_coord, y_coord, 1) + var/turf/T = locate(x_coord, y_coord, z_coord) if(!T) to_chat(usr, "[htmlicon(src, usr)] [SPAN_WARNING("Error, invalid coordinates.")]") return @@ -1053,8 +1056,14 @@ var/datum/controller/supply/supply_controller = new() if(T.y > max_y) max_y = T.y + var/z_coord = SSmapping.levels_by_trait(ZTRAIT_ADMIN) + if(length(z_coord)) + z_coord = z_coord[1] + else + z_coord = 1 //fuck it + // dunno why the +1 is needed but the vehicles spawn off-center - var/turf/middle_turf = locate(min_x + Ceiling((max_x-min_x)/2) + 1, min_y + Ceiling((max_y-min_y)/2) + 1, SUPPLY_DOCKZ) + var/turf/middle_turf = locate(min_x + Ceiling((max_x-min_x)/2) + 1, min_y + Ceiling((max_y-min_y)/2) + 1, z_coord) var/obj/vehicle/multitile/ordered_vehicle switch(href_list["get_vehicle"]) diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm index 5ab4c68a1b90..56311587bfd8 100644 --- a/code/game/turfs/closed.dm +++ b/code/game/turfs/closed.dm @@ -16,15 +16,14 @@ icon = 'icons/turf/walls/walls.dmi' icon_state = "rock" -/turf/closed/mineral/New() - ..() - spawn(2) - var/list/step_overlays = list("s" = NORTH, "n" = SOUTH, "w" = EAST, "e" = WEST) - for(var/direction in step_overlays) - var/turf/turf_to_check = get_step(src,step_overlays[direction]) +/turf/closed/mineral/Initialize(mapload) + . = ..() + var/list/step_overlays = list("s" = NORTH, "n" = SOUTH, "w" = EAST, "e" = WEST) + for(var/direction in step_overlays) + var/turf/turf_to_check = get_step(src,step_overlays[direction]) - if(istype(turf_to_check,/turf/open)) - turf_to_check.overlays += image('icons/turf/walls/walls.dmi', "rock_side_[direction]", 2.99) //Really high since it's an overhead turf and it shouldn't collide with anything else + if(istype(turf_to_check,/turf/open)) + turf_to_check.overlays += image('icons/turf/walls/walls.dmi', "rock_side_[direction]", 2.99) //Really high since it's an overhead turf and it shouldn't collide with anything else @@ -47,15 +46,14 @@ icon = 'icons/turf/ground_map.dmi' icon_state = "wall2" -/turf/closed/gm/dense/New() - ..() - spawn(1) - if(rand(0,15) == 0) - icon_state = "wall1" - else if (rand(0,20) == 0) - icon_state = "wall3" - else - icon_state = "wall2" +/turf/closed/gm/dense/Initialize(mapload) + . = ..() + if(prob(6)) + icon_state = "wall1" + else if (prob(5)) + icon_state = "wall3" + else + icon_state = "wall2" @@ -161,31 +159,33 @@ icon_state = "full_corners" //Directional walls each have 4 possible sprites and are -//randomized on New(). /turf/closed/ice_rock/northWall icon_state = "north_wall" - New() - ..() - dir = pick(NORTH,SOUTH,EAST,WEST) + +/turf/closed/ice_rock/northWall/Initialize(mapload) + . = ..() + dir = pick(NORTH,SOUTH,EAST,WEST) /turf/closed/ice_rock/southWall icon_state = "south_wall" - New() - ..() - dir = pick(NORTH,SOUTH,EAST,WEST) + +/turf/closed/ice_rock/southWall/Initialize(mapload) + . = ..() + dir = pick(NORTH,SOUTH,EAST,WEST) /turf/closed/ice_rock/westWall icon_state = "west_wall" - New() - ..() - dir = pick(NORTH,SOUTH,EAST,WEST) + +/turf/closed/ice_rock/westWall/Initialize(mapload) + . = ..() + dir = pick(NORTH,SOUTH,EAST,WEST) /turf/closed/ice_rock/eastWall icon_state = "east_wall" - New() - ..() - dir = pick(NORTH,SOUTH,EAST,WEST) +/turf/closed/ice_rock/eastWall/Initialize(mapload) + . = ..() + dir = pick(NORTH,SOUTH,EAST,WEST) /turf/closed/ice_rock/cornerOverlay icon_state = "corner_overlay" diff --git a/code/game/turfs/floor.dm b/code/game/turfs/floor.dm index e6f53798d2ca..c961643f1d94 100644 --- a/code/game/turfs/floor.dm +++ b/code/game/turfs/floor.dm @@ -23,35 +23,9 @@ //////////////////////////////////////////// - -//This is so damaged or burnt tiles or platings don't get remembered as the default tile -var/list/icons_to_ignore_at_floor_init = list("damaged1", "damaged2", "damaged3", "damaged4", - "damaged5", "panelscorched", "floorscorched1", "floorscorched2", "platingdmg1", "platingdmg2", - "platingdmg3", "plating", "light_on", "light_on_flicker1", "light_on_flicker2", - "light_on_clicker3", "light_on_clicker4", "light_on_clicker5", "light_broken", - "light_on_broken", "light_off", "wall_thermite", "grass1", "grass2", "grass3", "grass4", - "asteroid", "asteroid_dug", - "asteroid0", "asteroid1", "asteroid2", "asteroid3", "asteroid4", - "asteroid5", "asteroid6", "asteroid7", "asteroid8", "asteroid9", "asteroid10", "asteroid11", "asteroid12", - "oldburning", "light-on-r", "light-on-y", "light-on-g", "light-on-b", "wood", "wood-broken", "carpet", - "carpetcorner", "carpetside", "carpet", "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5", - "ironsand6", "ironsand7", "ironsand8", "ironsand9", "ironsand10", "ironsand11", - "ironsand12", "ironsand13", "ironsand14", "ironsand15") - -var/list/plating_icons = list("plating", "platingdmg1", "platingdmg2", "platingdmg3", "asteroid", "asteroid_dug", - "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5", "ironsand6", "ironsand7", - "ironsand8", "ironsand9", "ironsand10", "ironsand11", - "ironsand12", "ironsand13", "ironsand14", "ironsand15") var/list/wood_icons = list("wood", "wood-broken") -/turf/open/floor/New() - ..() - if(icon_state in icons_to_ignore_at_floor_init)//So damaged/burned tiles or plating icons aren't saved as the default - icon_regular_floor = "floor" - else - icon_regular_floor = icon_state - /turf/open/floor/ex_act(severity, explosion_direction) if(hull_floor) return 0 @@ -84,11 +58,7 @@ var/list/wood_icons = list("wood", "wood-broken") /turf/open/floor/update_icon() . = ..() - - if(is_plasteel_floor()) - if(!broken && !burnt) - icon_state = icon_regular_floor - else if(is_light_floor()) + if(is_light_floor()) var/obj/item/stack/tile/light/T = floor_tile if(T.on) switch(T.state) diff --git a/code/game/turfs/floor_types.dm b/code/game/turfs/floor_types.dm index f2606105a7b1..066d04b9ff36 100644 --- a/code/game/turfs/floor_types.dm +++ b/code/game/turfs/floor_types.dm @@ -9,8 +9,6 @@ icon_state = "default" - - /turf/open/floor/plating name = "plating" icon_state = "plating" @@ -24,17 +22,17 @@ icon_state = "plating" name = "airless plating" - New() - ..() - name = "plating" +/turf/open/floor/plating/airless/Initialize(mapload, ...) + . = ..() + name = "plating" /turf/open/floor/plating/icefloor icon_state = "plating" name = "ice colony plating" - New() - ..() - name = "plating" +/turf/open/floor/plating/icefloor/Initialize(mapload, ...) + . = ..() + name = "plating" /turf/open/floor/plating/plating_catwalk icon = 'icons/turf/almayer.dmi' @@ -93,9 +91,11 @@ -/turf/open/floor/plating/ironsand/New() - ..() +/turf/open/floor/plating/ironsand name = "Iron Sand" + +/turf/open/floor/plating/ironsand/Initialize(mapload, ...) + . = ..() icon_state = "ironsand[rand(1,15)]" @@ -254,17 +254,17 @@ icon_state = "floor" name = "airless floor" - New() - ..() - name = "floor" +/turf/open/floor/airless/Initialize(mapload, ...) + . = ..() + name = "floor" /turf/open/floor/icefloor icon_state = "floor" name = "ice colony floor" - New() - ..() - name = "floor" +/turf/open/floor/icefloor/Initialize(mapload, ...) + . = ..() + name = "floor" /turf/open/floor/light @@ -272,14 +272,12 @@ luminosity = 5 icon_state = "light_on" -/turf/open/floor/light/New() - floor_tile = new/obj/item/stack/tile/light +/turf/open/floor/light/Initialize(mapload, ...) var/n = name //just in case commands rename it in the ..() call - ..() - spawn(4) - if(src) - update_icon() - name = n + . = ..() + floor_tile = new/obj/item/stack/tile/light + update_icon() + name = n /turf/open/floor/wood @@ -290,9 +288,9 @@ /turf/open/floor/vault icon_state = "rockvault" - New(location,type) - ..() - icon_state = "[type]vault" +/turf/open/floor/vault/Initialize(mapload, type) + . = ..() + icon_state = "[type]vault" @@ -364,34 +362,38 @@ name = "Grass patch" icon_state = "grass1" -/turf/open/floor/grass/New() +/turf/open/floor/grass/Initialize(mapload, ...) + . = ..() floor_tile = new/obj/item/stack/tile/grass icon_state = "grass[pick("1","2","3","4")]" - ..() - spawn(4) - if(src) - update_icon() - for(var/direction in cardinal) - if(istype(get_step(src,direction),/turf/open/floor)) - var/turf/open/floor/FF = get_step(src,direction) - FF.update_icon() //so siding get updated properly + update_icon() + return INITIALIZE_HINT_LATELOAD + +/turf/open/floor/grass/LateInitialize() + . = ..() + for(var/direction in cardinal) + if(istype(get_step(src,direction),/turf/open/floor)) + var/turf/open/floor/FF = get_step(src,direction) + FF.update_icon() //so siding get updated properly /turf/open/floor/carpet name = "Carpet" icon_state = "carpet" -/turf/open/floor/carpet/New() +/turf/open/floor/carpet/Initialize(mapload, ...) + . = ..() floor_tile = new/obj/item/stack/tile/carpet if(!icon_state) icon_state = "carpet" - ..() - spawn(4) - if(src) - update_icon() - for(var/direction in list(1,2,4,8,5,6,9,10)) - if(istype(get_step(src,direction),/turf/open/floor)) - var/turf/open/floor/FF = get_step(src,direction) - FF.update_icon() //so siding get updated properly + return INITIALIZE_HINT_LATELOAD + +/turf/open/floor/carpet/LateInitialize() + . = ..() + update_icon() + for(var/direction in list(1,2,4,8,5,6,9,10)) + if(istype(get_step(src,direction),/turf/open/floor)) + var/turf/open/floor/FF = get_step(src,direction) + FF.update_icon() //so siding get updated properly // Start Prison tiles diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index 132f0c5b505f..2a46f824d41f 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -8,7 +8,7 @@ /turf/open/Initialize(mapload, ...) . = ..() - + update_icon() /turf/open/update_icon() @@ -129,8 +129,8 @@ icon_state = "water" can_bloody = FALSE -/turf/open/beach/water/New() - ..() +/turf/open/beach/water/Initialize(mapload, ...) + . = ..() overlays += image("icon"='icons/turf/floors/beach.dmi',"icon_state"="water2","layer"=MOB_LAYER+0.1) /turf/open/beach/water2 @@ -138,8 +138,8 @@ icon_state = "water" can_bloody = FALSE -/turf/open/beach/water2/New() - ..() +/turf/open/beach/water2/Initialize(mapload, ...) + . = ..() overlays += image("icon"='icons/turf/floors/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1) @@ -189,8 +189,8 @@ icon_state = "desert" baseturfs = /turf/open/gm/dirt -/turf/open/gm/dirt/New() - ..() +/turf/open/gm/dirt/Initialize(mapload, ...) + . = ..() if(rand(0,15) == 0) icon_state = "desert[pick("0","1","2","3")]" @@ -228,8 +228,8 @@ var/default_name = "river" baseturfs = /turf/open/gm/river -/turf/open/gm/river/New() - ..() +/turf/open/gm/river/Initialize(mapload, ...) + . = ..() update_icon() /turf/open/gm/river/update_icon() @@ -307,8 +307,8 @@ return !covered -/turf/open/gm/river/poison/New() - ..() +/turf/open/gm/river/poison/Initialize(mapload, ...) + . = ..() overlays += image("icon"='icons/effects/effects.dmi',"icon_state"="greenglow","layer"=MOB_LAYER+0.1) /turf/open/gm/river/poison/Entered(mob/living/M) @@ -328,8 +328,8 @@ can_bloody = FALSE baseturfs = /turf/open/gm/riverdeep -/turf/open/gm/riverdeep/New() - ..() +/turf/open/gm/riverdeep/Initialize(mapload, ...) + . = ..() overlays += image("icon"='icons/turf/ground_map.dmi',"icon_state"="water","layer"=MOB_LAYER+0.1) @@ -367,8 +367,8 @@ //Randomize ice floor sprite -/turf/open/ice/New() - ..() +/turf/open/ice/Initialize(mapload, ...) + . = ..() dir = pick(NORTH,SOUTH,EAST,WEST,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST) @@ -404,9 +404,9 @@ var/icon_spawn_state = "grass1" baseturfs = /turf/open/jungle -/turf/open/jungle/New() - ..() - +/turf/open/jungle/Initialize(mapload, ...) + . = ..() + icon_state = icon_spawn_state if(plants_spawn && prob(40)) @@ -488,8 +488,8 @@ icon_state = "grass_path" icon_spawn_state = "dirt" -/turf/open/jungle/path/New() - ..() +/turf/open/jungle/path/Initialize(mapload, ...) + . = ..() for(var/obj/structure/flora/jungle/thickbush/B in src) qdel(B) @@ -497,10 +497,11 @@ bushes_spawn = 0 icon_state = "grass_impenetrable" icon_spawn_state = "grass1" - New() - ..() - var/obj/structure/flora/jungle/thickbush/B = new(src) - B.indestructable = 1 + +/turf/open/jungle/impenetrable/Initialize(mapload, ...) + . = ..() + var/obj/structure/flora/jungle/thickbush/B = new(src) + B.indestructable = 1 /turf/open/jungle/water @@ -513,8 +514,8 @@ can_bloody = FALSE -/turf/open/jungle/water/New() - ..() +/turf/open/jungle/water/Initialize(mapload, ...) + . = ..() for(var/obj/structure/flora/jungle/thickbush/B in src) qdel(B) diff --git a/code/game/turfs/snow.dm b/code/game/turfs/snow.dm index 6857a9aef414..b614d60a9181 100644 --- a/code/game/turfs/snow.dm +++ b/code/game/turfs/snow.dm @@ -36,8 +36,8 @@ //Update icon and sides on start, but skip nearby check for turfs. -/turf/open/snow/New() - ..() +/turf/open/snow/Initialize(mapload, ...) + . = ..() update_icon(1,1) /turf/open/snow/Entered(atom/movable/AM) diff --git a/code/game/turfs/space.dm b/code/game/turfs/space.dm index 2ac4bee0529d..d0e77ecd7833 100644 --- a/code/game/turfs/space.dm +++ b/code/game/turfs/space.dm @@ -11,6 +11,9 @@ can_bloody = FALSE layer = UNDER_TURF_LAYER +/turf/open/space/basic/New() //Do not convert to Initialize + //This is used to optimize the map loader + return // override for space turfs, since they should never hide anything /turf/open/space/levelupdate() @@ -18,10 +21,10 @@ if(O.level == 1) O.hide(FALSE) -/turf/open/space/New() +/turf/open/space/Initialize(mapload, ...) + . = ..() if(!istype(src, /turf/open/space/transit)) icon_state = "[((x + y) ^ ~(x * y) + z) % 25]" - ..() /turf/open/space/attack_hand(mob/user) if ((user.is_mob_restrained() || !( user.pulling ))) @@ -117,8 +120,7 @@ var/safety = 1 while(move_to_z == src.z) - var/move_to_z_str = pickweight(accessable_z_levels) - move_to_z = text2num(move_to_z_str) + move_to_z = pick(SSmapping.levels_by_trait(ZTRAIT_GROUND)) safety++ if(safety > 10) break @@ -234,4 +236,4 @@ shuttlespace_ew14 icon_state = "speedspace_ew_14" shuttlespace_ew15 - icon_state = "speedspace_ew_15" \ No newline at end of file + icon_state = "speedspace_ew_15" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 7e47f8920d06..4ee576e9cb89 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -56,10 +56,21 @@ visibilityChanged() + pass_flags = pass_flags_cache[type] + if (isnull(pass_flags)) + pass_flags = new() + initialize_pass_flags(pass_flags) + pass_flags_cache[type] = pass_flags + else + initialize_pass_flags() + for(var/atom/movable/AM in src) Entered(AM) - Decorate() + if(luminosity) + if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.") + trueLuminosity = luminosity * luminosity + light = new(src) return INITIALIZE_HINT_NORMAL @@ -600,3 +611,69 @@ linked_pylons -= pylon return protection_level + +GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( + /turf/open/space, + /turf/baseturf_bottom, + ))) + +// Make a new turf and put it on top +// The args behave identical to PlaceOnBottom except they go on top +// Things placed on top of closed turfs will ignore the topmost closed turf +// Returns the new turf +/turf/proc/PlaceOnTop(list/new_baseturfs, turf/fake_turf_type, flags) + var/area/turf_area = loc + if(new_baseturfs && !length(new_baseturfs)) + new_baseturfs = list(new_baseturfs) + flags = turf_area.PlaceOnTopReact(new_baseturfs, fake_turf_type, flags) // A hook so areas can modify the incoming args + + var/turf/newT + if(flags & CHANGETURF_SKIP) // We haven't been initialized + if(flags_atom & INITIALIZED) + stack_trace("CHANGETURF_SKIP was used in a PlaceOnTop call for a turf that's initialized. This is a mistake. [src]([type])") + assemble_baseturfs() + if(fake_turf_type) + if(!new_baseturfs) // If no baseturfs list then we want to create one from the turf type + if(!length(baseturfs)) + baseturfs = list(baseturfs) + var/list/old_baseturfs = baseturfs.Copy() + if(!istype(src, /turf/closed)) + old_baseturfs += type + newT = ChangeTurf(fake_turf_type, null, flags) + newT.assemble_baseturfs(initial(fake_turf_type.baseturfs)) // The baseturfs list is created like roundstart + if(!length(newT.baseturfs)) + newT.baseturfs = list(baseturfs) + newT.baseturfs -= GLOB.blacklisted_automated_baseturfs + newT.baseturfs.Insert(1, old_baseturfs) // The old baseturfs are put underneath + return newT + if(!length(baseturfs)) + baseturfs = list(baseturfs) + if(!istype(src, /turf/closed)) + baseturfs += type + baseturfs += new_baseturfs + return ChangeTurf(fake_turf_type, null, flags) + if(!length(baseturfs)) + baseturfs = list(baseturfs) + if(!istype(src, /turf/closed)) + baseturfs += type + var/turf/change_type + if(length(new_baseturfs)) + change_type = new_baseturfs[new_baseturfs.len] + new_baseturfs.len-- + if(new_baseturfs.len) + baseturfs += new_baseturfs + else + change_type = new_baseturfs + return ChangeTurf(change_type, null, flags) + +/turf/proc/empty(turf_type=/turf/open/space, baseturf_type, list/ignore_typecache, flags) + // Remove all atoms except observers, landmarks, docking ports + var/static/list/ignored_atoms = typecacheof(list(/mob/dead, /obj/effect/landmark)) // shuttle TODO: + var/list/allowed_contents = typecache_filter_list_reverse(GetAllContentsIgnoring(ignore_typecache), ignored_atoms) + allowed_contents -= src + for(var/i in 1 to allowed_contents.len) + var/thing = allowed_contents[i] + qdel(thing, force=TRUE) + + if(turf_type) + ChangeTurf(turf_type, baseturf_type, flags) diff --git a/code/game/turfs/walls/walls.dm b/code/game/turfs/walls/walls.dm index c84229bac4f2..5232ee04285f 100644 --- a/code/game/turfs/walls/walls.dm +++ b/code/game/turfs/walls/walls.dm @@ -41,20 +41,15 @@ var/list/blend_objects = list(/obj/structure/machinery/door, /obj/structure/window_frame, /obj/structure/window/framed) // Objects which to blend with var/list/noblend_objects = list(/obj/structure/machinery/door/window) //Objects to avoid blending with (such as children of listed blend objects. -/turf/closed/wall/New() +/turf/closed/wall/Initialize(mapload, ...) . = ..() - - update_connections(TRUE) - - update_icon() + return INITIALIZE_HINT_LATELOAD -/turf/closed/wall/Initialize(mapload, ...) +/turf/closed/wall/LateInitialize() . = ..() - - if(mapload) - update_connections() + update_connections(TRUE) - update_icon() + update_icon() /turf/closed/wall/ChangeTurf(newtype) @@ -62,7 +57,6 @@ . = ..() if(.) //successful turf change - var/turf/T for(var/i in cardinal) T = get_step(src, i) @@ -107,7 +101,7 @@ var/turf/closed/wall/wall_south_turf = get_step(src, SOUTH) var/turf/closed/wall/wall_east_turf = get_step(src, EAST) var/turf/closed/wall/wall_west_turf = get_step(src, WEST) - + if(!istype(wall_north_turf) && !istype(wall_south_turf) && !istype(wall_east_turf) && !istype(wall_west_turf)) acided_hole_dir = dir_to & (NORTH|SOUTH) else if(!istype(wall_north_turf) && !istype(wall_south_turf)) @@ -120,7 +114,7 @@ else take_damage(damage_cap / XENO_HITS_TO_DESTROY_WALL) return - + . = ..() //Appearance @@ -259,13 +253,13 @@ if(!istype(src, /turf/closed/wall) || QDELETED(src)) break - + if(thermite > (damage_cap - damage)/100) // Thermite gains a speed buff when the amount is overkill var/timereduction = round((thermite - (damage_cap - damage)/100)/5) // Every 5 units over the required amount reduces the sleep by 0.1s sleep(max(2, 20 - timereduction)) else sleep(20) - + if(!istype(src, /turf/closed/wall) || QDELETED(src)) break @@ -274,7 +268,7 @@ if(istype(W)) W.melting = FALSE - + //Interactions /turf/closed/wall/attack_animal(mob/living/M as mob) @@ -362,7 +356,7 @@ to_chat(user, SPAN_WARNING("You need more welding fuel to complete this task.")) return - if(!istype(src, /turf/closed/wall)) + if(!istype(src, /turf/closed/wall)) return //DECONSTRUCTION @@ -373,7 +367,7 @@ playsound(src, 'sound/items/Welder.ogg', 25, 1) user.visible_message(SPAN_NOTICE("[user] begins slicing through the outer plating."), SPAN_NOTICE("You begin slicing through the outer plating.")) - if(!WT || !WT.isOn()) + if(!WT || !WT.isOn()) return if(!do_after(user, 60 * user.get_skill_duration_multiplier(SKILL_CONSTRUCTION), INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) return diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index 7896c469a0e8..acc734927039 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -174,7 +174,7 @@ var/global/normal_ooc_colour = "#1c52f5" set name = "Current Map" //Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite set desc = "Information about the current round" set category = "OOC" - to_chat(usr, SPAN_NOTICE("The current map is [map_tag]")) + to_chat(usr, SPAN_NOTICE("The current map is [SSmapping.configs[GROUND_MAP].map_name]")) // Sometimes the game fails to close NanoUIs, seemingly at random. This makes it impossible to open new ones // If this happens, let the player manually close them all diff --git a/code/game/world.dm b/code/game/world.dm index 5a348a30f330..b43da1106b90 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -52,7 +52,6 @@ var/internal_tick_usage = 0 LoadBans() load_motd() load_mode() - setupGhostTeleportLocs() loadShuttleInfoDatums() populate_gear_list() @@ -114,15 +113,12 @@ var/internal_tick_usage = 0 // Start the game ASAP SSticker.current_state = GAME_STATE_SETTING_UP - return var/world_topic_spam_protect_ip = "0.0.0.0" var/world_topic_spam_protect_time = world.timeofday /world/Topic(T, addr, master, key) - if(findtext(T, "mapdaemon") == 0) diary << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key][log_end]" - if (T == "ping") var/x = 1 for (var/client/C) @@ -191,175 +187,7 @@ var/world_topic_spam_protect_time = world.timeofday dat += "[ban_text][N.text]
by [admin_name] ([N.admin_rank])[confidential_text] on [N.date]

" return dat - - //START: MAPDAEMON PROCESSING - if(addr == "127.0.0.1") //Verify that instructions are coming from the local machine - - var/list/md_args = splittext(T,"&") - var/command = md_args[1] - var/MD_UID = md_args[2] - - if(command == "mapdaemon_get_round_status") - - if(!SSticker) return "ERROR" //Yeah yeah wrong data type, but MapDaemon.java can handle it - - if(MapDaemon_UID == -1) MapDaemon_UID = MD_UID //If we haven't seen an instance of MD yet, this is ours now - - if(kill_map_daemon || MD_UID != MapDaemon_UID) return 2 //The super secret killing code that kills it until it's been killed. - - else if(!SSticker.mode) return 0 //Before round start - - else if(SSticker.mode.round_finished || force_mapdaemon_vote) return 1 - - else return 0 //IDK what would cause this but why not, don't really want runtimes - - else if(MD_UID != MapDaemon_UID) - return 2 //kill the imposter, kill it with fire - - else if(command == "mapdaemon_delay_round") - - if(!SSticker) return "ERROR" - - addtimer(CALLBACK(src, .proc/announce_mapvote), 20 SECONDS) - - SSticker.automatic_delay_end = TRUE - message_staff("World/Topic() call (likely MapDaemon.exe) has delayed the round end.", 1) - return "SUCCESS" - - else if(command == "mapdaemon_restart_round") - - if(!SSticker) return "ERROR" - - SSticker.automatic_delay_end = FALSE - message_staff("World/Topic() call (likely MapDaemon.exe) has resumed the round end.", 1) - - //So admins have a chance to make EORG bans and do whatever - if(!SSticker.delay_end) - message_staff(FONT_SIZE_LARGE(SPAN_BOLDANNOUNCE("NOTICE: Delay round within 30 seconds in order to prevent auto-restart!")), 1) - - MapDaemonHandleRestart() //Doesn't hold - - return "WILL DO" //Yessir! - - else if(command == "mapdaemon_receive_votes") - return count_votes() - -var/list/datum/entity/map_vote/all_votes - -/world/proc/announce_mapvote() - var/text = "" - text += "

" - text += SPAN_CENTERBOLD("You have 30 seconds to vote for the next map! Use the \"Map Vote\" verb in the OOC tab or click here to select an option, or open voting window again to change your choice.") - text += "

" - - to_world(text) - world << 'sound/voice/start_your_voting.ogg' - - for(var/client/C in GLOB.clients) - C.mapVote() - - load_maps_for_vote() - -/world/proc/load_maps_for_vote() - SSentity_manager.filter_then(/datum/entity/map_vote, null, CALLBACK(world, /world.proc/load_maps_for_vote_callback)) - -/world/proc/load_maps_for_vote_callback(var/list/datum/entity/map_vote/votes) - all_votes = list() - for(var/i in DEFAULT_NEXT_MAP_CANDIDATES) - var/found = FALSE - var/datum/entity/map_vote/vote - for(var/datum/entity/map_vote/in_vote in votes) - if(in_vote.map_name == i) - found = TRUE - vote = in_vote - break - - if(!found) - vote = SSentity_manager.select(/datum/entity/map_vote) - vote.map_name = i - vote.total_votes = 0 - vote.save() - - all_votes[i] = vote - -/world/proc/count_votes() - var/list/L = list() - - var/i - for(i in NEXT_MAP_CANDIDATES) - if(all_votes && all_votes[i]) // safety check - L[i] = all_votes[i].total_votes - else - L[i] = 0 //Initialize it - - var/forced = 0 - var/force_result = "" - i = null //Sanitize for safety - var/j - for(i in player_votes) - j = player_votes[i] - if(i == "}}}") //Special invalid ckey for forcing the next map - forced = 1 - force_result = j - continue - L[j] = L[j] + 1 //Just number of votes indexed by map name - - i = null - var/most_votes = -1 - var/next_map = "" - for(i in L) - if(L[i] > most_votes && (!all_votes || !all_votes[i] || L[i] != all_votes[i].total_votes)) // so if it didn't get any new votes (due to being out of rotation or shit or broken) it is not picked - most_votes = L[i] - next_map = i - - if(!enable_map_vote && SSticker.mode) - next_map = SSticker.mode.name - else if(enable_map_vote && forced) - next_map = force_result - - var/text = "" - text += "" - - var/log_text = "" - log_text += "\[[time2text(world.realtime, "DD Month YYYY")]\] Winner: [next_map] (" - - text += "The voting results were:
" - for(var/name in L) - var/item_text = "[name] - [L[name]]" - if(!forced && all_votes && all_votes[name]) - var/new_votes = L[name] - all_votes[name].total_votes - if(!new_votes) - continue - item_text += " ([new_votes] new)" - if(next_map != name) - all_votes[name].total_votes = L[name] - else - all_votes[name].total_votes = 0 - all_votes[name].save() - - text += item_text + "
" - log_text += item_text + "," - - log_text += ")\n" - - if(forced) - text += "An admin has forced the next map.
" - else - text2file(log_text, "data/map_votes.txt") - - text += "The next map will be on [forced ? force_result : next_map]." - - text += "
" - - to_world(text) - - return next_map - /world/Reboot(var/reason) - /*spawn(0) - world << sound(pick('sound/AI/newroundsexy.ogg','sound/misc/apcdestroyed.ogg','sound/misc/bangindonk.ogg')) // random end sounds!! - LastyBatsy - */ - Master.Shutdown() var/round_extra_data = "" // Notify helper daemon of reboot, regardless of reason. @@ -406,12 +234,12 @@ var/list/datum/entity/map_vote/all_votes // s += "Wiki|Rules" if(SSticker) if(master_mode) - s += "
Map: [map_tag]" + s += "
Map: [SSmapping.configs[GROUND_MAP].map_name]" if(SSticker.mode) s += "
Mode: [SSticker.mode.name]" s += "
Round time: [duration2text()]" else - s += "
Map: [map_tag]" + s += "
Map: [SSmapping.configs[GROUND_MAP].map_name]" // s += enter_allowed ? "
Entering: Enabled" : "
Entering: Disabled" status = s @@ -436,29 +264,6 @@ proc/setup_database_connection() return . -// /hook/startup/proc/connectOldDB() -// if(!setup_old_database_connection()) -// world.log << "Your server failed to establish a connection with the SQL database." -// else -// world.log << "SQL database connection established." -// return 1 - -/proc/MapDaemonHandleRestart() - set waitfor = 0 - - SSticker.current_state = GAME_STATE_COMPILE_FINISHED - - sleep(300) - - if(SSticker.delay_end || SSticker.automatic_delay_end) - return - - to_world(SPAN_DANGER("Restarting world! \blue Initiated by MapDaemon.exe!")) - log_admin("World/Topic() call (likely MapDaemon.exe) initiated a reboot.") - - sleep(30) - world.Reboot() //Whatever this is the important part - /proc/set_global_view(view_size) world_view_size = view_size for(var/client/c in GLOB.clients) @@ -493,4 +298,8 @@ proc/setup_database_connection() on_tickrate_change() /world/proc/on_tickrate_change() - SStimer?.reset_buckets() + SStimer.reset_buckets() + +/world/proc/incrementMaxZ() + maxz++ + //SSmobs.MaxZChanged() diff --git a/code/global.dm b/code/global.dm index a005da1cb4ad..1d4193cc5a8e 100644 --- a/code/global.dm +++ b/code/global.dm @@ -79,12 +79,9 @@ var/CELLRATE = 0.002 // multiplier for watts per tick <> cell storage (eg: 0.02 //It's a conversion constant. power_used*CELLRATE = charge_provided, or charge_used/CELLRATE = power_provided var/CHARGELEVEL = 0.0005 // Cap for how fast cells charge, as a percentage-per-tick (0.01 means cellcharge is capped to 1% per second) -var/SupplyElevator -var/VehicleElevator var/VehicleElevatorConsole var/HangarUpperElevator var/HangarLowerElevator -var/global/map_tag //Spawnpoints. var/list/fallen_list = list() diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index cb01efc9dbb3..b1ffbb211908 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -77,15 +77,10 @@ var/list/admin_verbs_server = list( /datum/admins/proc/delay, /datum/admins/proc/toggleaban, /datum/admins/proc/end_round, + /datum/admins/proc/change_ground_map, + /datum/admins/proc/vote_ground_map, /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ /client/proc/cmd_debug_del_all, - /client/proc/forceNextMap, - /client/proc/cancelMapVote, - /client/proc/killMapDaemon, - /client/proc/editVotableMaps, - /client/proc/showVotableMaps, - /client/proc/forceMDMapVote, - /client/proc/reviveMapDaemon ) var/list/admin_verbs_debug = list( /client/proc/getruntimelog, /*allows us to access runtime logs to somebody*/ diff --git a/code/modules/admin/server_verbs.dm b/code/modules/admin/server_verbs.dm new file mode 100644 index 000000000000..102ae0c8dc68 --- /dev/null +++ b/code/modules/admin/server_verbs.dm @@ -0,0 +1,51 @@ +/datum/admins/proc/change_ground_map() + set category = "Server" + set name = "M: Change Ground Map" + + if(!check_rights(R_SERVER)) + return + + var/list/maprotatechoices = list() + for(var/map in config.maplist[GROUND_MAP]) + var/datum/map_config/VM = config.maplist[GROUND_MAP][map] + var/mapname = VM.map_name + if(VM == config.defaultmaps[GROUND_MAP]) + mapname += " (Default)" + + if(VM.config_min_users > 0 || VM.config_max_users > 0) + mapname += " \[" + if(VM.config_min_users > 0) + mapname += "[VM.config_min_users]" + else + mapname += "0" + mapname += "-" + if(VM.config_max_users > 0) + mapname += "[VM.config_max_users]" + else + mapname += "inf" + mapname += "\]" + + maprotatechoices[mapname] = VM + + var/chosenmap = input("Choose a ground map to change to", "Change Ground Map") as null|anything in maprotatechoices + if(!chosenmap) + return + + var/datum/map_config/VM = maprotatechoices[chosenmap] + if(!SSmapping.changemap(VM, GROUND_MAP)) + to_chat(usr, "Failed to change the ground map.") + return + + log_admin("[key_name(usr)] changed the map to [VM.map_name].") + message_admins("[key_name_admin(usr)] changed the map to [VM.map_name].") + +/datum/admins/proc/vote_ground_map() + set category = "Server" + set name = "M: Start Ground Map Vote" + + if(!check_rights(R_SERVER)) + return + + SSvote.initiate_vote("groundmap", usr.ckey) + log_admin("[key_name(usr)] started a groundmap vote.") + message_admins("[key_name_admin(usr)] started a groundmap vote.") diff --git a/code/modules/almayer/machinery.dm b/code/modules/almayer/machinery.dm index e7fa394eb55d..027161e02b4d 100644 --- a/code/modules/almayer/machinery.dm +++ b/code/modules/almayer/machinery.dm @@ -397,6 +397,7 @@ unacidable = TRUE /obj/structure/prop/almayer/name_stencil + name = MAIN_SHIP_NAME desc = "The name of the ship stenciled on the hull." icon = 'icons/obj/structures/props/almayer_props64.dmi' icon_state = "almayer0" @@ -404,10 +405,6 @@ unslashable = TRUE unacidable = TRUE - New() - ..() - name = MAIN_SHIP_NAME - /obj/structure/prop/almayer/hangar_stencil name = "floor" desc = "A large number stenciled on the hangar floor used to designate which dropship it is." @@ -491,9 +488,8 @@ icon_state = "mixed" icon_closed = "mixed" -/obj/structure/closet/basketball/New() - ..() - sleep(2) +/obj/structure/closet/basketball/Initialize() + . = ..() new /obj/item/clothing/under/shorts/grey(src) new /obj/item/clothing/under/shorts/black(src) new /obj/item/clothing/under/shorts/red(src) diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 168feb0fac93..aa3cc8c06e6e 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -191,8 +191,8 @@ /obj/item/device/assembly_holder/timer_igniter name = "timer-igniter assembly" -/obj/item/device/assembly_holder/timer_igniter/New(location, timer_time) - ..() +/obj/item/device/assembly_holder/timer_igniter/Initialize(mapload, timer_time) + . = ..() var/obj/item/device/assembly/igniter/ign = new(src) ign.secured = 1 diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index ac71411483db..e05e6c8f7a4b 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -77,6 +77,8 @@ preload_rsc = 0 // This is 0 so we can set it to an URL once the player logs in and have them download the resources from a different server. + var/datum/player_details/player_details //these persist between logins/logouts during the same round. + /// our current tab var/stat_tab diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 04691b4c3d7a..91046ee6f0ce 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -121,11 +121,6 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list( cmd_admin_pm(C,null) return - //Map voting - if(href_list["vote_for_map"]) - mapVote() - return - else if(href_list["FaxView"]) var/info = locate(href_list["FaxView"]) show_browser(usr, "[info]", "Fax Message", "Fax Message") @@ -152,6 +147,8 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list( return view_glob_var_Topic(href, href_list, hsrc) if("matrices") return matrix_editor_Topic(href, href_list, hsrc) + if("vote") + return SSvote.Topic(href, href_list) switch(href_list["action"]) if ("openLink") @@ -258,6 +255,17 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list( xeno_prefix = "XX" if(!xeno_postfix || xeno_name_ban) xeno_postfix = "" + + var/full_version = "[byond_version].[byond_build ? byond_build : "xxx"]" + + if(GLOB.player_details[ckey]) + player_details = GLOB.player_details[ckey] + player_details.byond_version = full_version + else + player_details = new + player_details.byond_version = full_version + GLOB.player_details[ckey] = player_details + . = ..() //calls mob.Login() // Macros added at runtime diff --git a/code/modules/client/player_details.dm b/code/modules/client/player_details.dm new file mode 100644 index 000000000000..e04bd3a9e25f --- /dev/null +++ b/code/modules/client/player_details.dm @@ -0,0 +1,23 @@ +GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details + +/datum/player_details + var/list/player_actions = list() + var/list/logging = list() + var/list/post_login_callbacks = list() + var/list/post_logout_callbacks = list() + var/list/played_names = list() //List of names this key played under this round + var/byond_version = "Unknown" + + +/proc/log_played_names(ckey, ...) + if(!ckey) + return + if(args.len < 2) + return + var/list/names = args.Copy(2) + var/datum/player_details/P = GLOB.player_details[ckey] + if(!P) + return + for(var/name in names) + if(name) + P.played_names |= name diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index a648d0df8a2c..bd2353773c2a 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -321,7 +321,7 @@ new_protection[] = list(MAP_ICE_COLONY = ICE_PLANET_min_cold_protection_temperature)) if(!(flags_atom & UNIQUE_ITEM_TYPE)) name = "[specialty]" - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) name += " snow helmet" else name += " helmet" @@ -974,4 +974,4 @@ qdel(src) -#undef HELMET_GARB_ACTUAL_ICON_STATE \ No newline at end of file +#undef HELMET_GARB_ACTUAL_ICON_STATE diff --git a/code/modules/clothing/spacesuits/breaches.dm b/code/modules/clothing/spacesuits/breaches.dm index 68231fc6b5bc..6719f3192888 100644 --- a/code/modules/clothing/spacesuits/breaches.dm +++ b/code/modules/clothing/spacesuits/breaches.dm @@ -19,8 +19,8 @@ var/burn_damage = 0 // Specifically burn damage. var/base_name // Used to keep the original name safe while we apply modifiers. -/obj/item/clothing/suit/space/New() - ..() +/obj/item/clothing/suit/space/Initialize() + . = ..() base_name = "[name]" //Some simple descriptors for breaches. Global because lazy, TODO: work out a better way to do this. @@ -218,4 +218,4 @@ var/global/list/breach_burn_descriptors = list( ..() if(can_breach && breaches && breaches.len) for(var/datum/breach/B in breaches) - to_chat(user, SPAN_DANGER("It has \a [B.descriptor].")) \ No newline at end of file + to_chat(user, SPAN_DANGER("It has \a [B.descriptor].")) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 69ce9b921ceb..3f294a092740 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -77,9 +77,9 @@ WEAR_JACKET = 'icons/mob/humans/onmob/suit_1.dmi' ) -/obj/item/clothing/suit/armor/vest/pilot/New() +/obj/item/clothing/suit/armor/vest/pilot/Initialize() + . = ..() select_gamemode_skin(/obj/item/clothing/suit/armor/vest/pilot) - ..() /obj/item/clothing/suit/armor/vest/dutch name = "armored jacket" @@ -457,4 +457,4 @@ item_state = "jensencoat" flags_inv_hide = NO_FLAGS siemens_coefficient = 0.6 - flags_armor_protection = BODY_FLAG_CHEST|BODY_FLAG_ARMS \ No newline at end of file + flags_armor_protection = BODY_FLAG_CHEST|BODY_FLAG_ARMS diff --git a/code/modules/clothing/suits/marine_armor.dm b/code/modules/clothing/suits/marine_armor.dm index 28dd4052e8c4..145c528bc0ca 100644 --- a/code/modules/clothing/suits/marine_armor.dm +++ b/code/modules/clothing/suits/marine_armor.dm @@ -116,10 +116,11 @@ var/list/squad_colors_chat = list(rgb(230,125,125), rgb(255,230,80), rgb(255,150 time_to_equip = 20 equip_sounds = list('sound/handling/putting_on_armor1.ogg') -/obj/item/clothing/suit/storage/marine/New(loc) +/obj/item/clothing/suit/storage/marine/Initialize() + . = ..() if(!(flags_atom & UNIQUE_ITEM_TYPE)) name = "[specialty]" - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) name += " snow armor" //Leave marine out so that armors don't have to have "Marine" appended (see: admirals). else name += " armor" @@ -129,7 +130,6 @@ var/list/squad_colors_chat = list(rgb(230,125,125), rgb(255,230,80), rgb(255,150 if(!(flags_atom & NO_SNOW_TYPE)) select_gamemode_skin(type) - ..() armor_overlays = list("lamp") //Just one for now, can add more later. update_icon() pockets.max_w_class = SIZE_SMALL //Can contain small items AND rifle magazines. @@ -413,9 +413,9 @@ var/list/squad_colors_chat = list(rgb(230,125,125), rgb(255,230,80), rgb(255,150 /obj/item/device/motiondetector, /obj/item/device/walkman) -/obj/item/clothing/suit/storage/marine/smartgunner/New(loc) +/obj/item/clothing/suit/storage/marine/smartgunner/Initialize() . = ..() - if(map_tag in MAPS_COLD_TEMP && name == "M56 combat harness") + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD] && name == "M56 combat harness") name = "M56 snow combat harness" else name = "M56 combat harness" @@ -452,17 +452,17 @@ var/list/squad_colors_chat = list(rgb(230,125,125), rgb(255,230,80), rgb(255,150 var/class = "H" //This variable should be what comes before the variation number (H6 -> H). -/obj/item/clothing/suit/storage/marine/class/New() +/obj/item/clothing/suit/storage/marine/class/Initialize() + . = ..() if(!(flags_atom & UNIQUE_ITEM_TYPE)) name = "[specialty]" - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) name += " snow armor" //Leave marine out so that armors don't have to have "Marine" appended (see: admirals). else name += " armor" if(istype(src, /obj/item/clothing/suit/storage/marine/class)) var/armor_variation = rand(1,6) icon_state = "[class]" + "[armor_variation]" - ..() armor_overlays = list("lamp") //Just one for now, can add more later. update_icon() pockets.max_w_class = SIZE_SMALL //Can contain small items AND rifle magazines. @@ -1393,8 +1393,8 @@ var/list/squad_colors_chat = list(rgb(230,125,125), rgb(255,230,80), rgb(255,150 flags_cold_protection = BODY_FLAG_CHEST|BODY_FLAG_GROIN|BODY_FLAG_LEGS|BODY_FLAG_FEET|BODY_FLAG_ARMS|BODY_FLAG_HANDS min_cold_protection_temperature = SPACE_SUIT_min_cold_protection_temperature -/obj/item/clothing/suit/storage/militia/New() - ..() +/obj/item/clothing/suit/storage/militia/Initialize() + . = ..() pockets.max_w_class = SIZE_SMALL //Can contain small items AND rifle magazines. pockets.bypass_w_limit = list( /obj/item/ammo_magazine/rifle, diff --git a/code/modules/clothing/suits/marine_coat.dm b/code/modules/clothing/suits/marine_coat.dm index 80d0d3f8396f..f05683f13d4b 100644 --- a/code/modules/clothing/suits/marine_coat.dm +++ b/code/modules/clothing/suits/marine_coat.dm @@ -29,7 +29,7 @@ /obj/item/storage/belt/gun/m44, /obj/item/storage/belt/gun/mateba, /obj/item/storage/belt/gun/smartpistol, - + /obj/item/device/flashlight, /obj/item/device/healthanalyzer, /obj/item/device/radio, @@ -40,8 +40,8 @@ valid_accessory_slots = list(ACCESSORY_SLOT_ARMBAND, ACCESSORY_SLOT_RANK, ACCESSORY_SLOT_DECOR, ACCESSORY_SLOT_MEDAL) restricted_accessory_slots = list(ACCESSORY_SLOT_ARMBAND, ACCESSORY_SLOT_RANK) -/obj/item/clothing/suit/storage/jacket/marine/New(loc) - ..() +/obj/item/clothing/suit/storage/jacket/marine/Initialize() + . = ..() if(!(flags_atom & NO_SNOW_TYPE)) select_gamemode_skin(type) diff --git a/code/modules/clothing/suits/storage.dm b/code/modules/clothing/suits/storage.dm index eafc15b4573f..4561728954ca 100644 --- a/code/modules/clothing/suits/storage.dm +++ b/code/modules/clothing/suits/storage.dm @@ -2,8 +2,8 @@ var/obj/item/storage/internal/pockets var/storage_slots = 2 -/obj/item/clothing/suit/storage/New() - ..() +/obj/item/clothing/suit/storage/Initialize() + . = ..() pockets = new/obj/item/storage/internal(src) pockets.storage_slots = storage_slots pockets.max_w_class = SIZE_SMALL //fit only small items diff --git a/code/modules/clothing/under/marine_uniform.dm b/code/modules/clothing/under/marine_uniform.dm index aed8b351be5b..54e1a30ca413 100644 --- a/code/modules/clothing/under/marine_uniform.dm +++ b/code/modules/clothing/under/marine_uniform.dm @@ -20,12 +20,11 @@ var/specialty = "USCM" //Makes it so that we can see the right name in the vendor. layer = UPPER_ITEM_LAYER -/obj/item/clothing/under/marine/New(loc, - new_protection[] = list(MAP_ICE_COLONY = ICE_PLANET_min_cold_protection_temperature), override_icon_state[] = null) - ..() +/obj/item/clothing/under/marine/Initialize(mapload, new_protection[] = list(MAP_ICE_COLONY = ICE_PLANET_min_cold_protection_temperature), override_icon_state[] = null) + . = ..() if(!(flags_atom & UNIQUE_ITEM_TYPE)) name = "[specialty]" - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) name += " snow uniform" else name += " uniform" @@ -544,4 +543,4 @@ name = "\improper Working Joe Uniform" desc = "A cheap uniform made for Synthetic labor." icon_state = "working_joe" - worn_state = "working_joe" \ No newline at end of file + worn_state = "working_joe" diff --git a/code/modules/clothing/under/ties.dm b/code/modules/clothing/under/ties.dm index 7589040dbdbc..615da50460a8 100644 --- a/code/modules/clothing/under/ties.dm +++ b/code/modules/clothing/under/ties.dm @@ -16,11 +16,8 @@ flags_equip_slot = SLOT_ACCESSORY sprite_sheets = list(SPECIES_MONKEY = 'icons/mob/humans/species/monkeys/onmob/ties_monkey.dmi') -/obj/item/clothing/accessory/proc/can_attach_to(var/mob/user, var/obj/item/clothing/C) - return TRUE - -/obj/item/clothing/accessory/New() - ..() +/obj/item/clothing/accessory/Initialize() + . = ..() inv_overlay = image("icon" = 'icons/obj/items/clothing/ties_overlay.dmi', "icon_state" = "[item_state? "[item_state]" : "[icon_state]"]") /obj/item/clothing/accessory/Destroy() @@ -29,6 +26,9 @@ QDEL_NULL(inv_overlay) . = ..() +/obj/item/clothing/accessory/proc/can_attach_to(var/mob/user, var/obj/item/clothing/C) + return TRUE + //when user attached an accessory to S /obj/item/clothing/accessory/proc/on_attached(obj/item/clothing/S, mob/living/user) if(!istype(S)) @@ -172,7 +172,7 @@ return FALSE return TRUE - + /obj/item/clothing/accessory/medal/examine(mob/user) ..() diff --git a/code/modules/clothing/under/under.dm b/code/modules/clothing/under/under.dm index bf034682d72d..faeabb4d67fe 100644 --- a/code/modules/clothing/under/under.dm +++ b/code/modules/clothing/under/under.dm @@ -37,7 +37,8 @@ equip_sounds = list('sound/handling/clothing_on.ogg') unequip_sounds = list('sound/handling/clothing_off.ogg') -/obj/item/clothing/under/New() +/obj/item/clothing/under/Initialize() + . = ..() if(worn_state) if(!item_state_slots) item_state_slots = list() @@ -49,8 +50,7 @@ if((worn_state + "_d") in icon_states(default_onmob_icons[WEAR_BODY])) rollable_sleeves = TRUE if((worn_state + "_df") in icon_states(default_onmob_icons[WEAR_BODY])) - cuttable_sleeves = TRUE - ..() + cuttable_sleeves = TRUE /obj/item/clothing/Destroy() QDEL_NULL_LIST(accessories) @@ -207,7 +207,7 @@ to_chat(user, SPAN_NOTICE("You can't cut up [src].")) if(rolled_sleeves == TRUE) to_chat(user, SPAN_NOTICE("You can't dice up [src] while its rolled.")) - else + else rollable_sleeves = FALSE cuttable_sleeves = FALSE item_state_slots[WEAR_BODY] = "[worn_state]_df" diff --git a/code/modules/cm_aliens/structures/egg.dm b/code/modules/cm_aliens/structures/egg.dm index dfcfb69c1109..72576761d6b4 100644 --- a/code/modules/cm_aliens/structures/egg.dm +++ b/code/modules/cm_aliens/structures/egg.dm @@ -17,14 +17,14 @@ var/flags_embryo = NO_FLAGS /obj/effect/alien/egg/Initialize(mapload, var/hive) - ..() + . = ..() create_egg_triggers() if (hive) hivenumber = hive - + set_hive_data(src, hivenumber) update_icon() - Grow() + INVOKE_ASYNC(src, .proc/Grow) /obj/effect/alien/egg/Destroy() . = ..() @@ -123,10 +123,10 @@ if(loc && status != EGG_DESTROYED) status = EGG_BURST var/obj/item/clothing/mask/facehugger/child = new(loc, hivenumber) - + child.flags_embryo = flags_embryo flags_embryo = NO_FLAGS // Lose the embryo flags when passed on - + if(X && X.caste.can_hold_facehuggers && (!X.l_hand || !X.r_hand)) //sanity checks X.put_in_hands(child) return @@ -138,7 +138,7 @@ /obj/effect/alien/egg/proc/replace_triggers() if(isnull(loc) || status == EGG_DESTROYED) return - + create_egg_triggers() deploy_egg_triggers() diff --git a/code/modules/cm_aliens/structures/special_structure.dm b/code/modules/cm_aliens/structures/special_structure.dm index 420fff8c1552..67fafc8ebd97 100644 --- a/code/modules/cm_aliens/structures/special_structure.dm +++ b/code/modules/cm_aliens/structures/special_structure.dm @@ -56,8 +56,7 @@ set_hive_data(src, linked_hive.hivenumber) if(!linked_hive.add_special_structure(src)) - qdel(src) - return + return INITIALIZE_HINT_QDEL fast_objects.Add(src) update_icon() diff --git a/code/modules/cm_marines/codebook.dm b/code/modules/cm_marines/codebook.dm index 38cfe9041bcf..44e1965f1b0f 100644 --- a/code/modules/cm_marines/codebook.dm +++ b/code/modules/cm_marines/codebook.dm @@ -4,7 +4,8 @@ unique = 1 dat = "" -/obj/item/book/codebook/New() +/obj/item/book/codebook/Initialize() + . = ..() var/number var/letter dat = "" diff --git a/code/modules/cm_marines/dropship_equipment.dm b/code/modules/cm_marines/dropship_equipment.dm index e5b22d28c167..2f5307634070 100644 --- a/code/modules/cm_marines/dropship_equipment.dm +++ b/code/modules/cm_marines/dropship_equipment.dm @@ -981,7 +981,7 @@ if(!selected_stretcher.stretcher_activated)//stretcher beacon was deactivated midway return - if(selected_stretcher.z != 1) //in case the stretcher was on a groundside dropship that flew away during our input() + if(!is_ground_level(selected_stretcher.z)) //in case the stretcher was on a groundside dropship that flew away during our input() return if(!selected_stretcher.buckled_mob && !selected_stretcher.buckled_bodybag) @@ -1066,7 +1066,7 @@ to_chat(user, SPAN_WARNING("There seems to be no medevac stretcher connected to [src].")) return - if(linked_stretcher.z != 1) + if(!is_ground_level(linked_stretcher.z)) linked_stretcher.linked_medevac = null linked_stretcher = null to_chat(user, SPAN_WARNING(" There seems to be no medevac stretcher connected to [src].")) @@ -1091,7 +1091,7 @@ busy_winch = FALSE var/fail - if(!linked_stretcher || linked_stretcher != old_stretcher || linked_stretcher.z != 1) + if(!linked_stretcher || linked_stretcher != old_stretcher || !is_ground_level(linked_stretcher.z)) fail = TRUE else if(!ship_base) //uninstalled midway diff --git a/code/modules/cm_marines/equipment/kit_boxes.dm b/code/modules/cm_marines/equipment/kit_boxes.dm index d307a51f2235..0e98f476e44b 100644 --- a/code/modules/cm_marines/equipment/kit_boxes.dm +++ b/code/modules/cm_marines/equipment/kit_boxes.dm @@ -96,7 +96,7 @@ new /obj/item/explosive/plastic(src) new /obj/item/explosive/plastic(src) new /obj/item/device/encryptionkey/jtac(src) - if(Check_WO()) + if(SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST) new /obj/item/device/binoculars/designator(src) else new /obj/item/device/binoculars/range/designator/scout(src) diff --git a/code/modules/cm_marines/equipment/maps.dm b/code/modules/cm_marines/equipment/maps.dm index 52b4fecaa438..0964b8b5ddc9 100644 --- a/code/modules/cm_marines/equipment/maps.dm +++ b/code/modules/cm_marines/equipment/maps.dm @@ -102,12 +102,9 @@ //used by marine equipment machines to spawn the correct map. /obj/item/map/current_map -/obj/item/map/current_map/New() - ..() - if(!map_tag) - qdel(src) - return - switch(map_tag) +/obj/item/map/current_map/Initialize(mapload, ...) + . = ..() + switch(SSmapping.configs[GROUND_MAP].map_name) if(MAP_LV_624) name = "\improper Lazarus Landing Map" desc = "A satellite printout of the Lazarus Landing colony on LV-624." @@ -149,7 +146,7 @@ html_link = "images/0/0d/Kutjevo_a1.jpg" color = "red" else - qdel(src) + return INITIALIZE_HINT_QDEL diff --git a/code/modules/cm_marines/equipment/mortars.dm b/code/modules/cm_marines/equipment/mortars.dm index 7218e69c1d3f..deaf29c754f5 100644 --- a/code/modules/cm_marines/equipment/mortars.dm +++ b/code/modules/cm_marines/equipment/mortars.dm @@ -177,7 +177,7 @@ if(busy) to_chat(user, SPAN_WARNING("Someone else is currently using [src].")) return - if(z != 1) + if(!is_ground_level(z)) to_chat(user, SPAN_WARNING("You cannot fire [src] here.")) return if(targ_x == 0 && targ_y == 0) //Mortar wasn't set @@ -315,7 +315,7 @@ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED)) to_chat(user, SPAN_WARNING("You don't have the training to deploy [src].")) return - if(user.z != 1) + if(!is_ground_level(z)) to_chat(user, SPAN_WARNING("You cannot deploy [src] here.")) return var/area/A = get_area(src) @@ -471,8 +471,8 @@ mouse_opacity = 0 brightness_on = 7 //Way brighter than most lights -/obj/item/device/flashlight/flare/on/illumination/New() - ..() +/obj/item/device/flashlight/flare/on/illumination/Initialize() + . = ..() fuel = rand(400, 500) // Half the duration of a flare, but justified since it's invincible /obj/item/device/flashlight/flare/on/illumination/turn_off() @@ -492,8 +492,8 @@ icon_unlocked = "secure_unlocked_mortar" req_one_access = list(ACCESS_MARINE_OT, ACCESS_MARINE_CARGO, ACCESS_MARINE_ENGPREP) -/obj/structure/closet/crate/secure/mortar_ammo/full/New() - ..() +/obj/structure/closet/crate/secure/mortar_ammo/full/Initialize() + . = ..() new /obj/item/mortar_shell/he(src) new /obj/item/mortar_shell/he(src) new /obj/item/mortar_shell/he(src) @@ -515,8 +515,8 @@ name = "\improper M402 mortar kit" desc = "A crate containing a basic set of a mortar and some shells, to get an engineer started." -/obj/structure/closet/crate/secure/mortar_ammo/mortar_kit/New() - ..() +/obj/structure/closet/crate/secure/mortar_ammo/mortar_kit/Initialize() + . = ..() new /obj/item/mortar_kit(src) new /obj/item/mortar_shell/he(src) new /obj/item/mortar_shell/he(src) diff --git a/code/modules/cm_marines/overwatch.dm b/code/modules/cm_marines/overwatch.dm index 9a777a018ef8..b5a50d8b5f61 100644 --- a/code/modules/cm_marines/overwatch.dm +++ b/code/modules/cm_marines/overwatch.dm @@ -39,7 +39,7 @@ if(..()) //Checks for power outages return - if(!ishighersilicon(usr) && !skillcheck(user, SKILL_LEADERSHIP, SKILL_LEAD_EXPERT) && !Check_WO()) + if(!ishighersilicon(usr) && !skillcheck(user, SKILL_LEADERSHIP, SKILL_LEAD_EXPERT) && SSmapping.configs[GROUND_MAP].map_name != MAP_WHISKEY_OUTPOST) to_chat(user, SPAN_WARNING("You don't have the training to use [src].")) return @@ -854,8 +854,13 @@ var/x_coord = deobfuscate_x(x_bomb) var/y_coord = deobfuscate_y(y_bomb) + var/z_coord = SSmapping.levels_by_trait(ZTRAIT_GROUND) + if(length(z_coord)) + z_coord = z_coord[1] + else + z_coord = 1 // fuck it - var/turf/T = locate(x_coord, y_coord, 1) + var/turf/T = locate(x_coord, y_coord, z_coord) var/area/A = get_area(T) if(protected_by_pylon(TURF_PROTECTION_OB, T)) @@ -917,8 +922,13 @@ var/x_coord = deobfuscate_x(x_supply) var/y_coord = deobfuscate_y(y_supply) + var/z_coord = SSmapping.levels_by_trait(ZTRAIT_GROUND) + if(length(z_coord)) + z_coord = z_coord[1] + else + z_coord = 1 // fuck it - var/turf/T = locate(x_coord, y_coord, 1) + var/turf/T = locate(x_coord, y_coord, z_coord) if(!T) to_chat(usr, "[htmlicon(src, usr)] [SPAN_WARNING("Error, invalid coordinates.")]") return diff --git a/code/modules/cm_marines/shuttle_backend.dm b/code/modules/cm_marines/shuttle_backend.dm index f360ef3f3313..0d08293f1004 100644 --- a/code/modules/cm_marines/shuttle_backend.dm +++ b/code/modules/cm_marines/shuttle_backend.dm @@ -398,7 +398,6 @@ qdel(src) /obj/effect/landmark/shuttle_loc/marine_src/evacuation /obj/effect/landmark/shuttle_loc/marine_src/evacuation/link_loc() - sleep(50) ..() var/datum/shuttle/ferry/marine/evacuation_pod/S = shuttle_controller.shuttles["[MAIN_SHIP_NAME] Evac [name]"] if(!S) @@ -419,7 +418,6 @@ qdel(src) /obj/effect/landmark/shuttle_loc/marine_crs/dropship /obj/effect/landmark/shuttle_loc/marine_crs/dropship/link_loc() - sleep(50) ..() // Sort the crash location into the ship section it belongs to @@ -455,7 +453,6 @@ var/targetTurf = get_turf(src);\ var/datum/shuttle/ferry/marine/S = shuttle_controller.shuttles["Ground [T] [name]"]; \ if(!S) {log_debug("ERROR CODE SO1: unable to find shuttle with the tag of: ["Ground [T] [name]"].")};\ L[targetTurf] = rotation; \ - qdel(src) // Stripped-down variant of the dropship effects. Here, we don't need crashes diff --git a/code/modules/cm_marines/smartgun_mount.dm b/code/modules/cm_marines/smartgun_mount.dm index c9bfe6c9b635..67182369b5e2 100644 --- a/code/modules/cm_marines/smartgun_mount.dm +++ b/code/modules/cm_marines/smartgun_mount.dm @@ -42,15 +42,14 @@ storage_slots = 6 can_hold = list() - New() - ..() - spawn(1) - new /obj/item/device/m56d_gun(src) //gun itself - new /obj/item/ammo_magazine/m56d(src) //ammo for the gun - new /obj/item/device/m56d_post(src) //post for the gun - new /obj/item/tool/wrench(src) //wrench to hold it down into the ground - new /obj/item/tool/screwdriver(src) //screw the gun onto the post. - new /obj/item/ammo_magazine/m56d(src) +/obj/item/storage/box/m56d_hmg/Initialize() + . = ..() + new /obj/item/device/m56d_gun(src) //gun itself + new /obj/item/ammo_magazine/m56d(src) //ammo for the gun + new /obj/item/device/m56d_post(src) //post for the gun + new /obj/item/tool/wrench(src) //wrench to hold it down into the ground + new /obj/item/tool/screwdriver(src) //screw the gun onto the post. + new /obj/item/ammo_magazine/m56d(src) @@ -109,7 +108,7 @@ return FALSE if(!has_mount) return FALSE - if(interior_manager && user.z == interior_manager.interior_z) + if(user.z == GLOB.interior_manager.interior_z) to_chat(usr, SPAN_WARNING("It's too cramped in here to deploy \a [src].")) return if(do_after(user, 1 SECOND, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) @@ -158,7 +157,7 @@ /obj/item/device/m56d_post/attack_self(mob/user) //click the tripod to unfold it. if(!ishuman(usr)) return - if(interior_manager && user.z == interior_manager.interior_z) + if(user.z == GLOB.interior_manager.interior_z) to_chat(usr, SPAN_WARNING("It's too cramped in here to deploy \a [src].")) return to_chat(user, SPAN_NOTICE("You deploy [src].")) diff --git a/code/modules/cm_preds/yaut_items.dm b/code/modules/cm_preds/yaut_items.dm index 5cb349c4c4d8..5abaadde96e8 100644 --- a/code/modules/cm_preds/yaut_items.dm +++ b/code/modules/cm_preds/yaut_items.dm @@ -56,10 +56,8 @@ unacidable = TRUE item_state_slots = list(WEAR_JACKET = "halfarmor1") -/obj/item/clothing/suit/armor/yautja/New(location, armor_number = rand(1,6), elder_restricted = 0) - ..() - forceMove(location) - +/obj/item/clothing/suit/armor/yautja/Initialize(mapload, armor_number = rand(1,6), elder_restricted = 0) + . = ..() if(elder_restricted) armor_melee = CLOTHING_ARMOR_MEDIUMHIGH armor_bullet = CLOTHING_ARMOR_HIGH @@ -129,8 +127,8 @@ /obj/item/storage/backpack/yautja, /obj/item/weapon/melee/twohanded/glaive) -/obj/item/clothing/suit/armor/yautja/full/New(location) - . = ..(location, 0) +/obj/item/clothing/suit/armor/yautja/full/Initialize(mapload, armor_number) + . = ..(mapload, 0) /obj/item/clothing/suit/armor/yautja/dropped(mob/living/user) add_to_missing_pred_gear(src) diff --git a/code/modules/decorators/weapon_map_decorator.dm b/code/modules/decorators/weapon_map_decorator.dm index 1e661279c6ff..4e4ce1589abd 100644 --- a/code/modules/decorators/weapon_map_decorator.dm +++ b/code/modules/decorators/weapon_map_decorator.dm @@ -8,7 +8,7 @@ var/icon/j_icon /datum/decorator/weapon_map_decorator/is_active_decor() - return map_array.Find(map_tag) + return map_array.Find(SSmapping.configs[GROUND_MAP].map_name) /datum/decorator/weapon_map_decorator/get_decor_types() return typesof(/obj/item/weapon/gun) - /obj/item/weapon/gun @@ -21,8 +21,8 @@ gun.icon = c_icon - gun.item_icons = list() - + gun.item_icons = list() + gun.item_icons += list(WEAR_L_HAND = l_icon) gun.item_icons += list(WEAR_R_HAND = r_icon) gun.item_icons += list(WEAR_BACK = b_icon) @@ -66,4 +66,4 @@ r_icon = 'icons/obj/items/weapons/guns/guns_by_map/urban/guns_righthand.dmi' b_icon = 'icons/obj/items/weapons/guns/guns_by_map/urban/back.dmi' j_icon = 'icons/obj/items/weapons/guns/guns_by_map/urban/suit_slot.dmi' - map_array = list() \ No newline at end of file + map_array = list() diff --git a/code/modules/defcon/defcon.dm b/code/modules/defcon/defcon.dm index fbcbe11fc4b9..019538c5ae1d 100644 --- a/code/modules/defcon/defcon.dm +++ b/code/modules/defcon/defcon.dm @@ -106,30 +106,7 @@ var/global/datum/controller/defcon/defcon_controller return TRUE /datum/controller/defcon/proc/initialize_level_triggers_by_map() - // Sometimes map_tag won't be populated - if (!map_tag) - return FALSE - - // Leaving debug messages here in case this code has bugs. - // Without these, it is -literally- impossible to debug this - // as this code can sometimes execute before world initialization. - //text2file("DEFCON lists began initialization","data/defcon_log.txt") - //text2file("Map tag: [map_tag]", "data/defcon_log.txt") - if (map_tag == MAP_PRISON_STATION || map_tag == MAP_SOROKYNE_STRATA) - defcon_level_triggers = list(3750, 2600, 1450, 875, 0.0) - else if (map_tag == MAP_ICE_COLONY || map_tag == MAP_DESERT_DAM || map_tag == MAP_CORSAT) - defcon_level_triggers = list(3300, 2100, 1450, 580, 0.0) - else if (map_tag == MAP_BIG_RED) - defcon_level_triggers = list(4750, 3500, 2000, 1000, 0.0) - else if (map_tag == MAP_KUTJEVO) - defcon_level_triggers = list(4250, 2950, 1650, 1000, 0.0) - else - // Defaults - // Currently just LV - defcon_level_triggers = list(5150, 4225, 2800, 1000, 0.0) - //text2file("Listing level triggers:","data/defcon_log.txt") - //for (var/i in defcon_level_triggers) - //text2file("Defcon level trigger: [i]","data/defcon_log.txt") + defcon_level_triggers = SSmapping.configs[GROUND_MAP].defcon_triggers lists_initialized = 1 return TRUE diff --git a/code/modules/defenses/handheld.dm b/code/modules/defenses/handheld.dm index 6ca08e032417..110b5ec8ffea 100644 --- a/code/modules/defenses/handheld.dm +++ b/code/modules/defenses/handheld.dm @@ -3,7 +3,7 @@ desc = "A compact version of the USCM defenses. Designed for quick deployment of the associated type in the field." icon = 'icons/obj/structures/machinery/defenses.dmi' icon_state = "uac_sentry_handheld" - + force = 5 throwforce = 5 throw_speed = SPEED_SLOW @@ -26,7 +26,7 @@ deploy_handheld(user) /obj/item/defenses/handheld/proc/deploy_handheld(var/mob/living/carbon/human/user) - if(interior_manager && user.z == interior_manager.interior_z) + if(user.z == GLOB.interior_manager.interior_z) to_chat(usr, SPAN_WARNING("It's too cramped in here to deploy \a [src].")) return @@ -84,4 +84,4 @@ name = "handheld JIMA planted flag" icon_state = "planted_flag_handheld" defense_type = /obj/structure/machinery/defenses/planted_flag - deployment_time = SECONDS_1 \ No newline at end of file + deployment_time = SECONDS_1 diff --git a/code/modules/desert_dam/filtration/filtration.dm b/code/modules/desert_dam/filtration/filtration.dm index 0673a194325c..45a953b21898 100644 --- a/code/modules/desert_dam/filtration/filtration.dm +++ b/code/modules/desert_dam/filtration/filtration.dm @@ -97,9 +97,12 @@ var/global/east_riverstart = 0 icon_state = "spawn_shuttle_dock" -/obj/effect/blocker/toxic_water/New() - ..() - sleep(10) +/obj/effect/blocker/toxic_water/Initialize(mapload, ...) + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/effect/blocker/toxic_water/LateInitialize() + . = ..() update_turf() icon_state = null diff --git a/code/modules/gear_presets/_select_equipment.dm b/code/modules/gear_presets/_select_equipment.dm index 8617e162aa32..8f71e3875f5c 100644 --- a/code/modules/gear_presets/_select_equipment.dm +++ b/code/modules/gear_presets/_select_equipment.dm @@ -489,7 +489,7 @@ H.equip_to_slot_or_del(new /obj/item/storage/box/MRE(H), WEAR_IN_BACK) /datum/equipment_preset/proc/add_ice_colony_survivor_equipment(var/mob/living/carbon/human/H) - if((map_tag in MAPS_COLD_TEMP) && (map_tag != MAP_CORSAT)) + if((SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) && (SSmapping.configs[GROUND_MAP].map_name != MAP_CORSAT)) H.equip_to_slot_or_del(new /obj/item/clothing/head/ushanka(H), WEAR_HEAD) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/snow_suit(H), WEAR_JACKET) H.equip_to_slot_or_del(new /obj/item/clothing/mask/rebreather(H), WEAR_FACE) @@ -533,4 +533,4 @@ H.equip_to_slot_or_del(new /obj/item/weapon/gun/revolver/small(H.back), WEAR_IN_BACK) // Guaranteed shotgun - H.equip_to_slot_or_del(new /obj/item/weapon/gun/shotgun/pump/cmb(H), WEAR_L_HAND) \ No newline at end of file + H.equip_to_slot_or_del(new /obj/item/weapon/gun/shotgun/pump/cmb(H), WEAR_L_HAND) diff --git a/code/modules/gear_presets/survivors.dm b/code/modules/gear_presets/survivors.dm index 313ab18248d2..39db01e344c1 100644 --- a/code/modules/gear_presets/survivors.dm +++ b/code/modules/gear_presets/survivors.dm @@ -40,7 +40,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/under/colonist(H), WEAR_BODY) H.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/tox(H), WEAR_BACK) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), WEAR_JACKET) @@ -69,7 +69,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), WEAR_BODY) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), WEAR_JACKET) @@ -105,7 +105,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/under/liaison_suit(H), WEAR_BODY) H.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/norm(H), WEAR_BACK) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), WEAR_FEET) @@ -138,7 +138,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security/corp(H), WEAR_BODY) H.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/sec(H), WEAR_BACK) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) H.equip_to_slot_or_del(new /obj/item/weapon/gun/revolver/cmb(H.back), WEAR_IN_BACK) @@ -161,7 +161,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(H), WEAR_BODY) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(H), WEAR_FEET) @@ -186,7 +186,7 @@ H.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/norm(H), WEAR_BACK) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), WEAR_FEET) @@ -211,7 +211,7 @@ H.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/norm(H), WEAR_BACK) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/suit/chef(H), WEAR_JACKET) @@ -242,7 +242,7 @@ H.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/hyd(H), WEAR_BACK) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(H), WEAR_JACKET) @@ -268,7 +268,7 @@ H.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/norm(H), WEAR_BACK) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) @@ -297,7 +297,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/engineer(H), WEAR_BODY) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) @@ -323,7 +323,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(H), WEAR_BODY) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(H), WEAR_FEET) @@ -348,7 +348,7 @@ H.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/norm(H), WEAR_BACK) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) @@ -374,7 +374,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/under/liaison_suit(H), WEAR_BODY) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/wcoat(H), WEAR_JACKET) @@ -404,7 +404,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/under/overalls(H), WEAR_BODY) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) @@ -439,7 +439,7 @@ H.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/sec(H), WEAR_BACK) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(H), WEAR_FEET) - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/CMB(H), WEAR_JACKET) diff --git a/code/modules/gear_presets/wy.dm b/code/modules/gear_presets/wy.dm index f2642d7ea59f..57ce087ef523 100644 --- a/code/modules/gear_presets/wy.dm +++ b/code/modules/gear_presets/wy.dm @@ -95,11 +95,11 @@ /datum/equipment_preset/wy/manager/survivor/load_skills(mob/living/carbon/human/H) . = ..() H.skills.set_skill(SKILL_ENDURANCE, SKILL_ENDURANCE_SURVIVOR) - + /datum/equipment_preset/wy/manager/survivor/load_gear(mob/living/carbon/human/H) . = ..() - if(map_tag in MAPS_COLD_TEMP) + if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) add_ice_colony_survivor_equipment(H) else H.equip_to_slot_or_del(new /obj/item/attachable/bayonet(H.back), WEAR_IN_BACK) @@ -134,4 +134,4 @@ H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/director(H), WEAR_JACKET) H.equip_to_slot_or_del(new /obj/item/clothing/head/director(H), WEAR_HEAD) H.equip_to_slot_or_del(new /obj/item/storage/belt/gun/mateba/admiral(H), WEAR_WAIST) - ..() \ No newline at end of file + ..() diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index 86f58b5eb01c..4f657d595694 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -45,20 +45,7 @@ /obj/item/seeds/cutting/update_appearance() ..() src.name = "packet of [seed.seed_name] cuttings" -/* -/obj/item/seeds/random - seed_type = null -/obj/item/seeds/random/New() - seed = new() - seed.randomize() - - seed.uid = seed_types.len + 1 - seed.name = "[seed.uid]" - seed_types[seed.name] = seed - - update_seed() -*/ /obj/item/seeds/poppyseed seed_type = "poppies" name = "pack of poppie seeds" diff --git a/code/modules/mapping/README.txt b/code/modules/mapping/README.txt new file mode 100644 index 000000000000..75e57efa8bbd --- /dev/null +++ b/code/modules/mapping/README.txt @@ -0,0 +1,52 @@ +The code in this module originally evolved from dmm_suite and has since been +specialized for SS13 and otherwise tweaked to fit /tg/station's needs. + +dmm_suite version 1.0 + Released January 30th, 2011. + +NOTE: Map saving functionality removed + +defines the object /dmm_suite + - Provides the proc load_map() + - Loads the specified map file onto the specified z-level. + - provides the proc write_map() + - Returns a text string of the map in dmm format + ready for output to a file. + - provides the proc save_map() + - Returns a .dmm file if map is saved + - Returns FALSE if map fails to save + +The dmm_suite provides saving and loading of map files in BYOND's native DMM map +format. It approximates the map saving and loading processes of the Dream Maker +and Dream Seeker programs so as to allow editing, saving, and loading of maps at +runtime. + +------------------------ + +To save a map at runtime, create an instance of /dmm_suite, and then call +write_map(), which accepts three arguments: + - A turf representing one corner of a three dimensional grid (Required). + - Another turf representing the other corner of the same grid (Required). + - Any, or a combination, of several bit flags (Optional, see documentation). + +The order in which the turfs are supplied does not matter, the /dmm_writer will +determine the grid containing both, in much the same way as DM's block() function. +write_map() will then return a string representing the saved map in dmm format; +this string can then be saved to a file, or used for any other purose. + +------------------------ + +To load a map at runtime, create an instance of /dmm_suite, and then call load_map(), +which accepts two arguments: + - A .dmm file to load (Required). + - A number representing the z-level on which to start loading the map (Optional). + +The /dmm_suite will load the map file starting on the specified z-level. If no +z-level was specified, world.maxz will be increased so as to fit the map. Note +that if you wish to load a map onto a z-level that already has objects on it, +you will have to handle the removal of those objects. Otherwise the new map will +simply load the new objects on top of the old ones. + +Also note that all type paths specified in the .dmm file must exist in the world's +code, and that the /dmm_reader trusts that files to be loaded are in fact valid +.dmm files. Errors in the .dmm format will cause runtime errors. diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm new file mode 100644 index 000000000000..5bbed01d566c --- /dev/null +++ b/code/modules/mapping/map_template.dm @@ -0,0 +1,106 @@ +/datum/map_template + var/name = "Default Template Name" + var/width = 0 + var/height = 0 + var/mappath = null + var/loaded = 0 // Times loaded this round + var/datum/parsed_map/cached_map + var/keep_cached_map = FALSE + +/datum/map_template/New(path = null, rename = null, cache = FALSE) + if(path) + mappath = path + if(mappath) + preload_size(mappath, cache) + if(rename) + name = rename + +/datum/map_template/proc/preload_size(path, cache = FALSE) + var/datum/parsed_map/parsed = new(file(path)) + var/bounds = parsed?.bounds + if(bounds) + width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1 + height = bounds[MAP_MAXY] + if(cache) + cached_map = parsed + return bounds + +/datum/parsed_map/proc/initTemplateBounds() + var/list/obj/structure/cable/cables = list() + var/list/atom/atoms = list() + var/list/area/areas = list() + + var/list/turfs = block( locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), + locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])) + for(var/L in turfs) + var/turf/B = L + atoms += B + areas |= B.loc + for(var/A in B) + atoms += A + if(istype(A, /obj/structure/cable)) + cables += A + continue + + SSmapping.reg_in_areas_in_z(areas) + SSatoms.InitializeAtoms(atoms) + //SSmachines.setup_template_powernets(cables) // mapping TODO: + +/datum/map_template/proc/load_new_z() + 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/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) + return FALSE + + repopulate_sorted_areas() + + //initialize things that are normally initialized after map load + parsed.initTemplateBounds() + log_game("Z-level [name] loaded at at [x],[y],[world.maxz]") + + return level + +/datum/map_template/proc/load(turf/T, centered, delete) + if(centered) + T = locate(T.x - round(width/2) , T.y - round(height/2) , T.z) + if(!T) + return + if(T.x + width > world.maxx) + return + if(T.y + height > world.maxy) + return + + // Accept cached maps, but don't save them automatically - we don't want + // ruins clogging up memory for the whole round. + var/datum/parsed_map/parsed = cached_map || new(file(mappath)) + cached_map = keep_cached_map ? parsed : null + if(!parsed.load(T.x, T.y, T.z, cropMap = TRUE, no_changeturf = (SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop = TRUE, delete = delete)) + return + var/list/bounds = parsed.bounds + if(!bounds) + return + + //initialize things that are normally initialized after map load + parsed.initTemplateBounds() + + log_game("[name] loaded at at [T.x],[T.y],[T.z]") + return bounds + +/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE) + var/turf/placement = T + if(centered) + var/turf/corner = locate(placement.x - round(width/2), placement.y - round(height/2), placement.z) + if(corner) + placement = corner + return block(placement, locate(placement.x+width-1, placement.y+height-1, placement.z)) + + +//for your ever biggening badminnery kevinz000 +//❤ - Cyberboss +/proc/load_new_z_level(file, name) + var/datum/map_template/template = new(file, name) + template.load_new_z() diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm new file mode 100644 index 000000000000..73ca47097362 --- /dev/null +++ b/code/modules/mapping/mapping_helpers.dm @@ -0,0 +1,210 @@ +//Landmarks and other helpers which speed up the mapping process and reduce the number of unique instances/subtypes of items/turf/ect + + + +/obj/effect/baseturf_helper //Set the baseturfs of every turf in the /area/ it is placed. + name = "baseturf editor" + icon = 'icons/effects/mapping_helpers.dmi' + icon_state = "" + + var/list/baseturf_to_replace + var/baseturf + + layer = POINT_LAYER + +/obj/effect/baseturf_helper/Initialize() + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/effect/baseturf_helper/LateInitialize() + if(!baseturf_to_replace) + baseturf_to_replace = typecacheof(/turf/open/space) + else if(!length(baseturf_to_replace)) + baseturf_to_replace = list(baseturf_to_replace = TRUE) + else if(baseturf_to_replace[baseturf_to_replace[1]] != TRUE) // It's not associative + var/list/formatted = list() + for(var/i in baseturf_to_replace) + formatted[i] = TRUE + baseturf_to_replace = formatted + + var/area/our_area = get_area(src) + for(var/i in get_area_turfs(our_area, z)) + replace_baseturf(i) + + qdel(src) + +/obj/effect/baseturf_helper/proc/replace_baseturf(turf/thing) + var/list/baseturf_cache = thing.baseturfs + if(length(baseturf_cache)) + for(var/i in baseturf_cache) + if(baseturf_to_replace[i]) + baseturf_cache -= i + if(!baseturf_cache.len) + thing.assemble_baseturfs(baseturf) + else + thing.PlaceOnBottom(null, baseturf) + else if(baseturf_to_replace[thing.baseturfs]) + thing.assemble_baseturfs(baseturf) + else + thing.PlaceOnBottom(null, baseturf) + + + +/obj/effect/baseturf_helper/space + name = "space baseturf editor" + baseturf = /turf/open/space +/* +/obj/effect/baseturf_helper/asteroid + name = "asteroid baseturf editor" + baseturf = /turf/open/floor/plating/asteroid + +/obj/effect/baseturf_helper/asteroid/airless + name = "asteroid airless baseturf editor" + baseturf = /turf/open/floor/plating/asteroid/airless + +/obj/effect/baseturf_helper/asteroid/basalt + name = "asteroid basalt baseturf editor" + baseturf = /turf/open/floor/plating/asteroid/basalt + +/obj/effect/baseturf_helper/asteroid/snow + name = "asteroid snow baseturf editor" + baseturf = /turf/open/floor/plating/asteroid/snow + +/obj/effect/baseturf_helper/beach/sand + name = "beach sand baseturf editor" + baseturf = /turf/open/floor/plating/beach/sand + +/obj/effect/baseturf_helper/beach/water + name = "water baseturf editor" + baseturf = /turf/open/floor/plating/beach/water + +/obj/effect/baseturf_helper/lava + name = "lava baseturf editor" + baseturf = /turf/open/lava/smooth + +/obj/effect/baseturf_helper/lava_land/surface + name = "lavaland baseturf editor" + baseturf = /turf/open/lava/smooth/lava_land_surface +*/ + +/obj/effect/mapping_helpers + icon = 'icons/effects/mapping_helpers.dmi' + icon_state = "" + var/late = FALSE + +/obj/effect/mapping_helpers/Initialize() + . = ..() + return late ? INITIALIZE_HINT_LATELOAD : INITIALIZE_HINT_QDEL + + +//airlock helpers +/obj/effect/mapping_helpers/airlock + layer = DOOR_HELPER_LAYER + +/obj/effect/mapping_helpers/airlock/cyclelink_helper + name = "airlock cyclelink helper" + icon_state = "airlock_cyclelink_helper" + +/obj/effect/mapping_helpers/airlock/cyclelink_helper/Initialize(mapload) + . = ..() + if(!mapload) + log_world("### MAP WARNING, [src] spawned outside of mapload!") + return + //var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc + //if(airlock) + // if(airlock.cyclelinkeddir) + // log_world("### MAP WARNING, [src] at [AREACOORD(src)] tried to set [airlock] cyclelinkeddir, but it's already set!") + // else + // airlock.cyclelinkeddir = dir + //else + //log_world("### MAP WARNING, [src] failed to find an airlock at [AREACOORD(src)]") + + +/obj/effect/mapping_helpers/airlock/locked + name = "airlock lock helper" + icon_state = "airlock_locked_helper" + +/obj/effect/mapping_helpers/airlock/locked/Initialize(mapload) + . = ..() + if(!mapload) + log_world("### MAP WARNING, [src] spawned outside of mapload!") + return + var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc + if(airlock) + if(airlock.locked) + log_world("### MAP WARNING, [src] at [AREACOORD(src)] tried to bolt [airlock] but it's already locked!") + else + airlock.locked = TRUE + else + log_world("### MAP WARNING, [src] failed to find an airlock at [AREACOORD(src)]") + +/obj/effect/mapping_helpers/airlock/unres + name = "airlock unresctricted side helper" + icon_state = "airlock_unres_helper" + +/obj/effect/mapping_helpers/airlock/unres/Initialize(mapload) + . = ..() + if(!mapload) + log_world("### MAP WARNING, [src] spawned outside of mapload!") + return +// var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc +// if(airlock) +// airlock.unres_sides ^= dir +// else +// log_world("### MAP WARNING, [src] failed to find an airlock at [AREACOORD(src)]") + + +//needs to do its thing before spawn_rivers() is called +/* +INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava) + +/obj/effect/mapping_helpers/no_lava + icon_state = "no_lava" + +/obj/effect/mapping_helpers/no_lava/Initialize() + . = ..() + var/turf/T = get_turf(src) + T.flags_1 |= NO_LAVA_GEN_1 +*/ + +/* +//This helper applies components to things on the map directly. +/obj/effect/mapping_helpers/component_injector + name = "Component Injector" + late = TRUE + var/target_type + var/target_name + var/component_type + +//Late init so everything is likely ready and loaded (no warranty) +/obj/effect/mapping_helpers/component_injector/LateInitialize() + if(!ispath(component_type,/datum/component)) + CRASH("Wrong component type in [type] - [component_type] is not a component") + var/turf/T = get_turf(src) + for(var/atom/A in T.GetAllContents()) + if(A == src) + continue + if(target_name && A.name != target_name) + continue + if(target_type && !istype(A,target_type)) + continue + var/cargs = build_args() + A.AddComponent(arglist(cargs)) + qdel(src) + return + +/obj/effect/mapping_helpers/component_injector/proc/build_args() + return list(component_type) + +/obj/effect/mapping_helpers/component_injector/infective + name = "Infective Injector" + icon_state = "component_infective" + component_type = /datum/component/infective + var/disease_type + +/obj/effect/mapping_helpers/component_injector/infective/build_args() + if(!ispath(disease_type,/datum/disease)) + CRASH("Wrong disease type passed in.") + var/datum/disease/D = new disease_type() + return list(component_type,D) + */ diff --git a/code/modules/mapping/preloader.dm b/code/modules/mapping/preloader.dm new file mode 100644 index 000000000000..039f27ecc254 --- /dev/null +++ b/code/modules/mapping/preloader.dm @@ -0,0 +1,30 @@ +// global datum that will preload variables on atoms instanciation +GLOBAL_VAR_INIT(use_preloader, FALSE) +GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new) + +/// Preloader datum +/datum/map_preloader + parent_type = /datum + var/list/attributes + var/target_path + +/datum/map_preloader/proc/setup(list/the_attributes, path) + if(the_attributes.len) + GLOB.use_preloader = TRUE + attributes = the_attributes + target_path = path + +/datum/map_preloader/proc/load(atom/what) + GLOB.use_preloader = FALSE + for(var/attribute in attributes) + var/value = attributes[attribute] + if(islist(value)) + value = deepCopyList(value) + what.vars[attribute] = value + +/area/template_noop + name = "Area Passthrough" + +/turf/template_noop + name = "Turf Passthrough" + icon_state = "noop" diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm new file mode 100644 index 000000000000..7ad85635ce37 --- /dev/null +++ b/code/modules/mapping/reader.dm @@ -0,0 +1,480 @@ +/////////////////////////////////////////////////////////////// +//SS13 Optimized Map loader +////////////////////////////////////////////////////////////// +#define SPACE_KEY "space" + +/datum/grid_set + var/xcrd + var/ycrd + var/zcrd + var/gridLines + +/datum/parsed_map + var/original_path + var/key_len = 0 + var/list/grid_models = list() + var/list/gridSets = list() + + var/list/modelCache + + /// Unoffset bounds. Null on parse failure. + var/list/parsed_bounds + /// Offset bounds. Same as parsed_bounds until load(). + var/list/bounds + + // raw strings used to represent regexes more accurately + // '' used to avoid confusing syntax highlighting + var/static/regex/dmmRegex = new(@'"([a-zA-Z]+)" = \(((?:.|\n)*?)\)\n(?!\t)|\((\d+),(\d+),(\d+)\) = \{"([a-zA-Z\n]*)"\}', "g") + var/static/regex/trimQuotesRegex = new(@'^[\s\n]+"?|"?[\s\n]+$|^"|"$', "g") + var/static/regex/trimRegex = new(@'^[\s\n]+|[\s\n]+$', "g") + + #ifdef TESTING + var/turfsSkipped = 0 + #endif + +/// Shortcut function to parse a map and apply it to the world. +/// +/// - `dmm_file`: A .dmm file to load (Required). +/// - `x_offset`, `y_offset`, `z_offset`: Positions representign where to load the map (Optional). +/// - `cropMap`: When true, the map will be cropped to fit the existing world dimensions (Optional). +/// - `measureOnly`: When true, no changes will be made to the world (Optional). +/// - `no_changeturf`: When true, [turf/AfterChange] won't be called on loaded turfs +/// - `x_lower`, `x_upper`, `y_lower`, `y_upper`: Coordinates (relative to the map) to crop to (Optional). +/// - `placeOnTop`: Whether to use [turf/PlaceOnTop] rather than [turf/ChangeTurf] (Optional). +/proc/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num, no_changeturf as num, x_lower = -INFINITY as num, x_upper = INFINITY as num, y_lower = -INFINITY as num, y_upper = INFINITY as num, placeOnTop = FALSE as num) + var/datum/parsed_map/parsed = new(dmm_file, x_lower, x_upper, y_lower, y_upper, measureOnly) + if(parsed.bounds && !measureOnly) + parsed.load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop) + return parsed + +/// Parse a map, possibly cropping it. +/datum/parsed_map/New(tfile, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper=INFINITY, measureOnly=FALSE) + if(isfile(tfile)) + original_path = "[tfile]" + tfile = file2text(tfile) + else if(isnull(tfile)) + // create a new datum without loading a map + return + + bounds = parsed_bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF) + var/stored_index = 1 + + //multiz lool + while(dmmRegex.Find(tfile, stored_index)) + stored_index = dmmRegex.next + + // "aa" = (/type{vars=blah}) + if(dmmRegex.group[1]) // Model + var/key = dmmRegex.group[1] + if(grid_models[key]) // Duplicate model keys are ignored in DMMs + continue + if(key_len != length(key)) + if(!key_len) + key_len = length(key) + else + CRASH("Inconsistent key length in DMM") + if(!measureOnly) + grid_models[key] = dmmRegex.group[2] + + // (1,1,1) = {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"} + else if(dmmRegex.group[3]) // Coords + if(!key_len) + CRASH("Coords before model definition in DMM") + + var/curr_x = text2num(dmmRegex.group[3]) + + if(curr_x < x_lower || curr_x > x_upper) + continue + + var/datum/grid_set/gridSet = new + + gridSet.xcrd = curr_x + //position of the currently processed square + gridSet.ycrd = text2num(dmmRegex.group[4]) + gridSet.zcrd = text2num(dmmRegex.group[5]) + + bounds[MAP_MINX] = min(bounds[MAP_MINX], clamp(gridSet.xcrd, x_lower, x_upper)) + bounds[MAP_MINZ] = min(bounds[MAP_MINZ], gridSet.zcrd) + bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], gridSet.zcrd) + + var/list/gridLines = splittext(dmmRegex.group[6], "\n") + gridSet.gridLines = gridLines + + var/leadingBlanks = 0 + while(leadingBlanks < gridLines.len && gridLines[++leadingBlanks] == "") + if(leadingBlanks > 1) + gridLines.Cut(1, leadingBlanks) // Remove all leading blank lines. + + if(!gridLines.len) // Skip it if only blank lines exist. + continue + + gridSets += gridSet + + if(gridLines.len && gridLines[gridLines.len] == "") + gridLines.Cut(gridLines.len) // Remove only one blank line at the end. + + bounds[MAP_MINY] = min(bounds[MAP_MINY], clamp(gridSet.ycrd, y_lower, y_upper)) + gridSet.ycrd += gridLines.len - 1 // Start at the top and work down + bounds[MAP_MAXY] = max(bounds[MAP_MAXY], clamp(gridSet.ycrd, y_lower, y_upper)) + + var/maxx = gridSet.xcrd + if(gridLines.len) //Not an empty map + maxx = max(maxx, gridSet.xcrd + length(gridLines[1]) / key_len - 1) + + bounds[MAP_MAXX] = clamp(max(bounds[MAP_MAXX], maxx), x_lower, x_upper) + CHECK_TICK + + // Indicate failure to parse any coordinates by nulling bounds + if(bounds[1] == 1.#INF) + bounds = null + parsed_bounds = bounds + +/// Load the parsed map into the world. See [/proc/load_map] for arguments. +/datum/parsed_map/proc/load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, delete) + //How I wish for RAII + Master.StartLoadingMap() + . = _load_impl(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, delete) + Master.StopLoadingMap() + +// Do not call except via load() above. +/datum/parsed_map/proc/_load_impl(x_offset = 1, y_offset = 1, z_offset = world.maxz + 1, cropMap = FALSE, no_changeturf = FALSE, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, placeOnTop = FALSE, delete = FALSE) + var/list/areaCache = list() + var/list/modelCache = build_cache(no_changeturf) + var/space_key = modelCache[SPACE_KEY] + var/list/bounds + src.bounds = bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF) + + for(var/I in gridSets) + var/datum/grid_set/gset = I + var/ycrd = gset.ycrd + y_offset - 1 + var/zcrd = gset.zcrd + z_offset - 1 + if(!cropMap && ycrd > world.maxy) + world.maxy = ycrd // Expand Y here. X is expanded in the loop below + var/zexpansion = zcrd > world.maxz + if(zexpansion) + if(cropMap) + continue + else + while (zcrd > world.maxz) //create a new z_level if needed + world.incrementMaxZ() + if(!no_changeturf) + WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called") + + for(var/line in gset.gridLines) + if((ycrd - y_offset + 1) < y_lower || (ycrd - y_offset + 1) > y_upper) //Reverse operation and check if it is out of bounds of cropping. + --ycrd + continue + if(ycrd <= world.maxy && ycrd >= 1) + var/xcrd = gset.xcrd + x_offset - 1 + for(var/tpos = 1 to length(line) - key_len + 1 step key_len) + if((xcrd - x_offset + 1) < x_lower || (xcrd - x_offset + 1) > x_upper) //Same as above. + ++xcrd + continue //X cropping. + if(xcrd > world.maxx) + if(cropMap) + break + else + world.maxx = xcrd + + if(xcrd >= 1) + var/model_key = copytext(line, tpos, tpos + key_len) + var/no_afterchange = no_changeturf || zexpansion + if(!no_afterchange || (model_key != space_key)) + var/list/cache = modelCache[model_key] + if(!cache) + CRASH("Undefined model key in DMM: [model_key]") + build_coordinate(areaCache, cache, locate(xcrd, ycrd, zcrd), no_afterchange, placeOnTop, delete) + + // only bother with bounds that actually exist + bounds[MAP_MINX] = min(bounds[MAP_MINX], xcrd) + bounds[MAP_MINY] = min(bounds[MAP_MINY], ycrd) + bounds[MAP_MINZ] = min(bounds[MAP_MINZ], zcrd) + bounds[MAP_MAXX] = max(bounds[MAP_MAXX], xcrd) + bounds[MAP_MAXY] = max(bounds[MAP_MAXY], ycrd) + bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], zcrd) + #ifdef TESTING + else + ++turfsSkipped + #endif + CHECK_TICK + ++xcrd + --ycrd + + CHECK_TICK + + //if(!no_changeturf)// mapping TODO: + // for(var/t in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ]))) + // var/turf/T = t + // //we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs + // T.AfterChange(CHANGETURF_IGNORE_AIR) + + #ifdef TESTING + if(turfsSkipped) + testing("Skipped loading [turfsSkipped] default turfs") + #endif + + return TRUE + +/datum/parsed_map/proc/build_cache(no_changeturf, bad_paths=null) + if(modelCache && !bad_paths) + return modelCache + . = modelCache = list() + var/list/grid_models = src.grid_models + for(var/model_key in grid_models) + var/model = grid_models[model_key] + var/list/members = list() //will contain all members (paths) in model (in our example : /turf/unsimulated/wall and /area/mine/explored) + var/list/members_attributes = list() //will contain lists filled with corresponding variables, if any (in our example : list(icon_state = "rock") and list()) + + ///////////////////////////////////////////////////////// + //Constructing members and corresponding variables lists + //////////////////////////////////////////////////////// + + var/index = 1 + var/old_position = 1 + var/dpos + + while(dpos != 0) + //finding next member (e.g /turf/unsimulated/wall{icon_state = "rock"} or /area/mine/explored) + dpos = find_next_delimiter_position(model, old_position, ",", "{", "}") //find next delimiter (comma here) that's not within {...} + + var/full_def = trim_text(copytext(model, old_position, dpos)) //full definition, e.g : /obj/foo/bar{variables=derp} + var/variables_start = findtext(full_def, "{") + var/path_text = trim_text(copytext(full_def, 1, variables_start)) + var/atom_def = text2path(path_text) //path definition, e.g /obj/foo/bar + if(dpos) + old_position = dpos + length(model[dpos]) + + if(!ispath(atom_def, /atom)) // Skip the item if the path does not exist. Fix your crap, mappers! + if(bad_paths) + LAZYOR(bad_paths[path_text], model_key) + continue + members.Add(atom_def) + + //transform the variables in text format into a list (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7)) + var/list/fields = list() + + if(variables_start)//if there's any variable + full_def = copytext(full_def, variables_start + length(full_def[variables_start]), -length(copytext_char(full_def, -1))) //removing the last '}' + fields = readlist(full_def, ";") + if(fields.len) + if(!trim(fields[fields.len])) + --fields.len + for(var/I in fields) + var/value = fields[I] + if(istext(value)) + fields[I] = apply_text_macros(value) + + //then fill the members_attributes list with the corresponding variables + members_attributes.len++ + members_attributes[index++] = fields + + CHECK_TICK + + //check and see if we can just skip this turf + //So you don't have to understand this horrid statement, we can do this if + // 1. no_changeturf is set + // 2. the space_key isn't set yet + // 3. there are exactly 2 members + // 4. with no attributes + // 5. and the members are world.turf and world.area + // Basically, if we find an entry like this: "XXX" = (/turf/default, /area/default) + // We can skip calling this proc every time we see XXX + if(no_changeturf \ + && !(.[SPACE_KEY]) \ + && members.len == 2 \ + && members_attributes.len == 2 \ + && length(members_attributes[1]) == 0 \ + && length(members_attributes[2]) == 0 \ + && (world.area in members) \ + && (world.turf in members)) + + .[SPACE_KEY] = model_key + continue + + + .[model_key] = list(members, members_attributes) + +/datum/parsed_map/proc/build_coordinate(list/areaCache, list/model, turf/crds, no_changeturf as num, placeOnTop as num, delete) + var/index + var/list/members = model[1] + var/list/members_attributes = model[2] + + //////////////// + //Instanciation + //////////////// + + //The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile + //first instance the /area and remove it from the members list + index = members.len + if(members[index] != /area/template_noop) + var/atype = members[index] + GLOB._preloader.setup(members_attributes[index], atype)//preloader for assigning set variables on atom creation + var/atom/instance = areaCache[atype] + if(!instance) + instance = GLOB.areas_by_type[atype] + if(!instance) + instance = new atype(null) + areaCache[atype] = instance + if(crds) + instance.contents.Add(crds) + + if(GLOB.use_preloader && instance) + GLOB._preloader.load(instance) + + //then instance the /turf and, if multiple tiles are presents, simulates the DMM underlays piling effect + + var/first_turf_index = 1 + while(!ispath(members[first_turf_index], /turf)) //find first /turf object in members + first_turf_index++ + + //turn off base new Initialization until the whole thing is loaded + SSatoms.map_loader_begin() + //instanciate the first /turf + var/turf/T + if(members[first_turf_index] != /turf/template_noop) + T = instance_atom(members[first_turf_index], members_attributes[first_turf_index], crds,no_changeturf, placeOnTop, delete) + + if(T) + //if others /turf are presents, simulates the underlays piling effect + index = first_turf_index + 1 + while(index <= members.len - 1) // Last item is an /area + var/underlay = T.appearance + T = instance_atom(members[index], members_attributes[index], crds,no_changeturf, placeOnTop, delete)//instance new turf + T.underlays += underlay + index++ + + //finally instance all remainings objects/mobs + for(index in 1 to first_turf_index-1) + instance_atom(members[index], members_attributes[index], crds, no_changeturf, placeOnTop, delete) + //Restore initialization to the previous value + SSatoms.map_loader_stop() + +//////////////// +//Helpers procs +//////////////// + +//Instance an atom at (x,y,z) and gives it the variables in attributes +/datum/parsed_map/proc/instance_atom(path,list/attributes, turf/crds, no_changeturf, placeOnTop, delete) + GLOB._preloader.setup(attributes, path) + + if(crds) + if(ispath(path, /turf)) + if(delete) + for(var/obj/O in crds.contents) + qdel(O) + + if(placeOnTop) + . = crds.PlaceOnTop(null, path, CHANGETURF_DEFER_CHANGE | (no_changeturf ? CHANGETURF_SKIP : NONE)) + else if(!no_changeturf) + . = crds.ChangeTurf(path, null, CHANGETURF_DEFER_CHANGE) + else + . = create_atom(path, crds)//first preloader pass + else + . = create_atom(path, crds)//first preloader pass + + if(GLOB.use_preloader && .)//second preloader pass, for those atoms that don't ..() in New() + GLOB._preloader.load(.) + + //custom CHECK_TICK here because we don't want things created while we're sleeping to not initialize + if(TICK_CHECK) + SSatoms.map_loader_stop() + stoplag() + SSatoms.map_loader_begin() + +/datum/parsed_map/proc/create_atom(path, crds) + set waitfor = FALSE + . = new path (crds) + +//text trimming (both directions) helper proc +//optionally removes quotes before and after the text (for variable name) +/datum/parsed_map/proc/trim_text(what as text,trim_quotes=0) + if(trim_quotes) + return trimQuotesRegex.Replace(what, "") + else + return trimRegex.Replace(what, "") + + +//find the position of the next delimiter,skipping whatever is comprised between opening_escape and closing_escape +//returns 0 if reached the last delimiter +/datum/parsed_map/proc/find_next_delimiter_position(text as text,initial_position as num, delimiter=",",opening_escape="\"",closing_escape="\"") + var/position = initial_position + var/next_delimiter = findtext(text,delimiter,position,0) + var/next_opening = findtext(text,opening_escape,position,0) + + while((next_opening != 0) && (next_opening < next_delimiter)) + position = findtext(text,closing_escape,next_opening + 1,0)+1 + next_delimiter = findtext(text,delimiter,position,0) + next_opening = findtext(text,opening_escape,position,0) + + return next_delimiter + + +//build a list from variables in text form (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7)) +//return the filled list +/datum/parsed_map/proc/readlist(text as text, delimiter=",") + . = list() + if (!text) + return + + var/position + var/old_position = 1 + + while(position != 0) + // find next delimiter that is not within "..." + position = find_next_delimiter_position(text,old_position,delimiter) + + // check if this is a simple variable (as in list(var1, var2)) or an associative one (as in list(var1="foo",var2=7)) + var/equal_position = findtext(text,"=",old_position, position) + + var/trim_left = trim_text(copytext(text,old_position,(equal_position ? equal_position : position))) + var/left_constant = delimiter == ";" ? trim_left : parse_constant(trim_left) + if(position) + old_position = position + length(text[position]) + + if(equal_position && !isnum(left_constant)) + // Associative var, so do the association. + // Note that numbers cannot be keys - the RHS is dropped if so. + var/trim_right = trim_text(copytext(text, equal_position + length(text[equal_position]), position)) + var/right_constant = parse_constant(trim_right) + .[left_constant] = right_constant + + else // simple var + . += list(left_constant) + +/datum/parsed_map/proc/parse_constant(text) + // number + var/num = text2num(text) + if(isnum(num)) + return num + + // string + if(text[1] == "\"") + return copytext(text, length(text[1]) + 1, findtext(text, "\"", length(text[1]) + 1)) + + // list + if(copytext(text, 1, 6) == "list(")//6 == length("list(") + 1 + return readlist(copytext(text, 6, -1)) + + // typepath + var/path = text2path(text) + if(ispath(path)) + return path + + // file + if(text[1] == "'") + return file(copytext_char(text, 2, -1)) + + // null + if(text == "null") + return null + + // not parsed: + // - pops: /obj{name="foo"} + // - new(), newlist(), icon(), matrix(), sound() + + // fallback: string + return text + +/datum/parsed_map/Destroy() + ..() + return QDEL_HINT_HARDDEL_NOW diff --git a/code/modules/mapping/space_management/space_level.dm b/code/modules/mapping/space_management/space_level.dm new file mode 100644 index 000000000000..86958c5b41b4 --- /dev/null +++ b/code/modules/mapping/space_management/space_level.dm @@ -0,0 +1,14 @@ +/datum/space_level + var/name = "NAME MISSING" + var/list/neigbours = list() + var/list/traits + var/z_value = 1 //actual z placement + var/linkage = SELFLOOPING + var/xi + var/yi //imaginary placements on the grid + +/datum/space_level/New(new_z, new_name, list/new_traits = list()) + z_value = new_z + name = new_name + traits = new_traits + //set_linkage(new_traits[ZTRAIT_LINKAGE]) diff --git a/code/modules/mapping/space_management/space_reservation.dm b/code/modules/mapping/space_management/space_reservation.dm new file mode 100644 index 000000000000..596773f13192 --- /dev/null +++ b/code/modules/mapping/space_management/space_reservation.dm @@ -0,0 +1,76 @@ + +//Yes, they can only be rectangular. +//Yes, I'm sorry. +/datum/turf_reservation + var/list/reserved_turfs = list() + var/width = 0 + var/height = 0 + var/bottom_left_coords[3] + var/top_right_coords[3] + var/wipe_reservation_on_release = TRUE + var/turf_type = /turf/open/space + +/datum/turf_reservation/transit + turf_type = /turf/open/space/transit + +/datum/turf_reservation/proc/Release() + var/v = reserved_turfs.Copy() + for(var/i in reserved_turfs) + reserved_turfs -= i + SSmapping.used_turfs -= i + SSmapping.reserve_turfs(v) + +/datum/turf_reservation/proc/Reserve(width, height, zlevel) + if(width > world.maxx || height > world.maxy || width < 1 || height < 1) + log_debug("turf reservation had invalid dimensions") + return FALSE + var/list/avail = SSmapping.unused_turfs["[zlevel]"] + var/turf/BL + var/turf/TR + var/list/turf/final = list() + var/passing = FALSE + for(var/i in avail) + CHECK_TICK + BL = i + if(!(BL.flags_atom & UNUSED_RESERVATION_TURF_1)) + continue + if(BL.x + width > world.maxx || BL.y + height > world.maxy) + continue + TR = locate(BL.x + width - 1, BL.y + height - 1, BL.z) + if(!(TR.flags_atom & UNUSED_RESERVATION_TURF_1)) + continue + final = block(BL, TR) + if(!final) + continue + passing = TRUE + for(var/I in final) + var/turf/checking = I + if(!(checking.flags_atom & UNUSED_RESERVATION_TURF_1)) + passing = FALSE + break + if(!passing) + continue + break + if(!passing || !istype(BL) || !istype(TR)) + log_debug("failed to pass reservation tests, [passing], [istype(BL)], [istype(TR)]") + return FALSE + bottom_left_coords = list(BL.x, BL.y, BL.z) + top_right_coords = list(TR.x, TR.y, TR.z) + for(var/i in final) + var/turf/T = i + reserved_turfs |= T + T.flags_atom &= ~UNUSED_RESERVATION_TURF_1 + SSmapping.unused_turfs["[T.z]"] -= T + SSmapping.used_turfs[T] = src + T.ChangeTurf(turf_type, turf_type) + src.width = width + src.height = height + return TRUE + +/datum/turf_reservation/New() + LAZYADD(SSmapping.turf_reservations, src) + +/datum/turf_reservation/Destroy() + INVOKE_ASYNC(src, .proc/Release) + LAZYREMOVE(SSmapping.turf_reservations, src) + return ..() diff --git a/code/modules/mapping/space_management/space_transition.dm b/code/modules/mapping/space_management/space_transition.dm new file mode 100644 index 000000000000..73970a792891 --- /dev/null +++ b/code/modules/mapping/space_management/space_transition.dm @@ -0,0 +1,143 @@ +/datum/space_level/proc/set_linkage(new_linkage) + linkage = new_linkage + if(linkage == SELFLOOPING) + neigbours = list(TEXT_NORTH,TEXT_SOUTH,TEXT_EAST,TEXT_WEST) + for(var/A in neigbours) + neigbours[A] = src + +/datum/space_level/proc/set_neigbours(list/L) + for(var/datum/space_transition_point/P in L) + if(P.x == xi) + if(P.y == yi+1) + neigbours[TEXT_NORTH] = P.spl + P.spl.neigbours[TEXT_SOUTH] = src + else if(P.y == yi-1) + neigbours[TEXT_SOUTH] = P.spl + P.spl.neigbours[TEXT_NORTH] = src + else if(P.y == yi) + if(P.x == xi+1) + neigbours[TEXT_EAST] = P.spl + P.spl.neigbours[TEXT_WEST] = src + else if(P.x == xi-1) + neigbours[TEXT_WEST] = P.spl + P.spl.neigbours[TEXT_EAST] = src + +/datum/space_transition_point //this is explicitly utilitarian datum type made specially for the space map generation and are absolutely unusable for anything else + var/list/neigbours = list() + var/x + var/y + var/datum/space_level/spl + +/datum/space_transition_point/New(nx, ny, list/point_grid) + if(!point_grid) + qdel(src) + return + var/list/L = point_grid[1] + if(nx > point_grid.len || ny > L.len) + qdel(src) + return + x = nx + y = ny + if(point_grid[x][y]) + return + point_grid[x][y] = src + +/datum/space_transition_point/proc/set_neigbours(list/grid) + var/max_X = grid.len + var/list/max_Y = grid[1] + max_Y = max_Y.len + neigbours.Cut() + if(x+1 <= max_X) + neigbours |= grid[x+1][y] + if(x-1 >= 1) + neigbours |= grid[x-1][y] + if(y+1 <= max_Y) + neigbours |= grid[x][y+1] + if(y-1 >= 1) + neigbours |= grid[x][y-1] + +/datum/controller/subsystem/mapping/proc/setup_map_transitions() //listamania + var/list/SLS = list() + var/list/cached_z_list = z_list + var/conf_set_len = 0 + for(var/A in cached_z_list) + var/datum/space_level/D = A + if (D.linkage == CROSSLINKED) + SLS.Add(D) + conf_set_len++ + var/list/point_grid[conf_set_len*2+1][conf_set_len*2+1] + var/list/grid = list() + var/datum/space_transition_point/P + for(var/i = 1, i<=conf_set_len*2+1, i++) + for(var/j = 1, j<=conf_set_len*2+1, j++) + P = new/datum/space_transition_point(i,j, point_grid) + point_grid[i][j] = P + grid.Add(P) + for(var/datum/space_transition_point/pnt in grid) + pnt.set_neigbours(point_grid) + P = point_grid[conf_set_len+1][conf_set_len+1] + var/list/possible_points = list() + var/list/used_points = list() + grid.Cut() + while(SLS.len) + var/datum/space_level/D = pick_n_take(SLS) + D.xi = P.x + D.yi = P.y + P.spl = D + possible_points |= P.neigbours + used_points |= P + possible_points.Remove(used_points) + D.set_neigbours(used_points) + P = pick(possible_points) + CHECK_TICK + + //Lists below are pre-calculated values arranged in the list in such a way to be easily accessable in the loop by the counter + //Its either this or madness with lotsa math + + var/list/x_pos_beginning = list(1, 1, world.maxx - TRANSITIONEDGE, 1) //x values of the lowest-leftest turfs of the respective 4 blocks on each side of zlevel + var/list/y_pos_beginning = list(world.maxy - TRANSITIONEDGE, 1, 1 + TRANSITIONEDGE, 1 + TRANSITIONEDGE) //y values respectively + var/list/x_pos_ending = list(world.maxx, world.maxx, world.maxx, 1 + TRANSITIONEDGE) //x values of the highest-rightest turfs of the respective 4 blocks on each side of zlevel + var/list/y_pos_ending = list(world.maxy, 1 + TRANSITIONEDGE, world.maxy - TRANSITIONEDGE, world.maxy - TRANSITIONEDGE) //y values respectively + var/list/x_pos_transition = list(1, 1, TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 1) //values of x for the transition from respective blocks on the side of zlevel, 1 is being translated into turfs respective x value later in the code + var/list/y_pos_transition = list(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 1, 1, 1) //values of y for the transition from respective blocks on the side of zlevel, 1 is being translated into turfs respective y value later in the code + + for(var/I in cached_z_list) + var/datum/space_level/D = I + if(!D.neigbours.len) + continue + var/zlevelnumber = D.z_value + for(var/side in 1 to 4) + var/turf/beginning = locate(x_pos_beginning[side], y_pos_beginning[side], zlevelnumber) + var/turf/ending = locate(x_pos_ending[side], y_pos_ending[side], zlevelnumber) + var/list/turfblock = block(beginning, ending) + var/dirside = 2**(side-1) + var/zdestination = zlevelnumber + if(D.neigbours["[dirside]"] && D.neigbours["[dirside]"] != D) + D = D.neigbours["[dirside]"] + zdestination = D.z_value + else + dirside = turn(dirside, 180) + while(D.neigbours["[dirside]"] && D.neigbours["[dirside]"] != D) + D = D.neigbours["[dirside]"] + zdestination = D.z_value + D = I + for(var/turf/open/space/S in turfblock) + S.destination_x = x_pos_transition[side] == 1 ? S.x : x_pos_transition[side] + S.destination_y = y_pos_transition[side] == 1 ? S.y : y_pos_transition[side] + S.destination_z = zdestination + + // Mirage border code + var/mirage_dir + if(S.x == 1 + TRANSITIONEDGE) + mirage_dir |= WEST + else if(S.x == world.maxx - TRANSITIONEDGE) + mirage_dir |= EAST + if(S.y == 1 + TRANSITIONEDGE) + mirage_dir |= SOUTH + else if(S.y == world.maxy - TRANSITIONEDGE) + mirage_dir |= NORTH + if(!mirage_dir) + continue + + var/turf/place = locate(S.destination_x, S.destination_y, S.destination_z) + S.AddComponent(/datum/component/mirage_border, place, mirage_dir) diff --git a/code/modules/mapping/space_management/traits.dm b/code/modules/mapping/space_management/traits.dm new file mode 100644 index 000000000000..16eac0a98cf2 --- /dev/null +++ b/code/modules/mapping/space_management/traits.dm @@ -0,0 +1,78 @@ +// Look up levels[z].traits[trait] +/datum/controller/subsystem/mapping/proc/level_trait(z, trait) + if (!isnum(z) || z < 1) + return null + if (z_list) + if (z > z_list.len) + stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], z_list.len = [z_list.len]") + return list() + var/datum/space_level/S = get_level(z) + return S.traits[trait] + else + var/list/default = DEFAULT_MAP_TRAITS + if (z > default.len) + stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], default.len = [default.len]") + return list() + return default[z][DL_TRAITS][trait] + +// Check if levels[z] has any of the specified traits +/datum/controller/subsystem/mapping/proc/level_has_any_trait(z, list/traits) + for (var/I in traits) + if (level_trait(z, I)) + return TRUE + return FALSE + +// Check if levels[z] has all of the specified traits +/datum/controller/subsystem/mapping/proc/level_has_all_traits(z, list/traits) + for (var/I in traits) + if (!level_trait(z, I)) + return FALSE + return TRUE + +// Get a list of all z which have the specified trait +/datum/controller/subsystem/mapping/proc/levels_by_trait(trait) + . = list() + var/list/_z_list = z_list + for(var/A in _z_list) + var/datum/space_level/S = A + if (S.traits[trait]) + . += S.z_value + +// Get a list of all z which have any of the specified traits +/datum/controller/subsystem/mapping/proc/levels_by_any_trait(list/traits) + . = list() + var/list/_z_list = z_list + for(var/A in _z_list) + var/datum/space_level/S = A + for (var/trait in traits) + if (S.traits[trait]) + . += S.z_value + break + +// Attempt to get the turf below the provided one according to Z traits +/datum/controller/subsystem/mapping/proc/get_turf_below(turf/T) + if (!T) + return + var/offset = level_trait(T.z, ZTRAIT_DOWN) + if (!offset) + return + return locate(T.x, T.y, T.z + offset) + +// Attempt to get the turf above the provided one according to Z traits +/datum/controller/subsystem/mapping/proc/get_turf_above(turf/T) + if (!T) + return + var/offset = level_trait(T.z, ZTRAIT_UP) + if (!offset) + return + return locate(T.x, T.y, T.z + offset) + +// Prefer not to use this one too often +/datum/controller/subsystem/mapping/proc/get_station_center() + var/station_z = levels_by_trait(ZTRAIT_STATION)[1] + return locate(round(world.maxx * 0.5, 1), round(world.maxy * 0.5, 1), station_z) + +// Prefer not to use this one too often +/datum/controller/subsystem/mapping/proc/get_mainship_center() + var/mainship_z = levels_by_trait(ZTRAIT_MARINE_MAIN_SHIP)[1] + return locate(round(world.maxx * 0.5, 1), round(world.maxy * 0.5, 1), mainship_z) diff --git a/code/modules/mapping/space_management/zlevel_manager.dm b/code/modules/mapping/space_management/zlevel_manager.dm new file mode 100644 index 000000000000..135fc2d0bd48 --- /dev/null +++ b/code/modules/mapping/space_management/zlevel_manager.dm @@ -0,0 +1,36 @@ +// Populate the space level list and prepare space transitions +/datum/controller/subsystem/mapping/proc/InitializeDefaultZLevels() + if (z_list) // subsystem/Recover or badminnery, no need + return + + z_list = list() + var/list/default_map_traits = DEFAULT_MAP_TRAITS + + if (default_map_traits.len != world.maxz) + WARNING("More or less map attributes pre-defined ([default_map_traits.len]) than existent z-levels ([world.maxz]). Ignoring the larger.") + if (default_map_traits.len > world.maxz) + default_map_traits.Cut(world.maxz + 1) + + //var/datum/space_level/LO = new(2, "Low Orbit", list(ZTRAIT_LOWORBIT)) + //z_list += LO + + for (var/I in 1 to default_map_traits.len) + var/list/features = default_map_traits[I] + var/datum/space_level/S = new(I, features[DL_NAME], features[DL_TRAITS]) + z_list += S + +/datum/controller/subsystem/mapping/proc/add_new_zlevel(name, traits = list(), z_type = /datum/space_level) + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_Z, args) + var/new_z = z_list.len + 1 + if (world.maxz < new_z) + world.incrementMaxZ() + CHECK_TICK + // TODO: sleep here if the Z level needs to be cleared + var/datum/space_level/S = new z_type(new_z, name, traits) + z_list += S + return S + +/datum/controller/subsystem/mapping/proc/get_level(z) + if (z_list && z >= 1 && z <= z_list.len) + return z_list[z] + CRASH("Unmanaged z-level [z]! maxz = [world.maxz], z_list.len = [z_list ? z_list.len : "null"]") diff --git a/code/modules/mapping/verify.dm b/code/modules/mapping/verify.dm new file mode 100644 index 000000000000..6c9d0318ef24 --- /dev/null +++ b/code/modules/mapping/verify.dm @@ -0,0 +1,99 @@ +/// An error report generated by [parsed_map/check_for_errors]. +/datum/map_report + var/original_path + var/list/bad_paths = list() + var/list/bad_keys = list() + /// Whether this map can be loaded safely despite the errors. + var/loadable = TRUE + var/crashed = TRUE + + var/static/tag_number = 0 + +/datum/map_report/New(datum/parsed_map/map) + original_path = map.original_path || "Untitled" + +/// Show a rendered version of this report to a client. +/datum/map_report/proc/show_to(client/C) + var/list/html = list() + html += "

Report for map file [original_path]

" + if(crashed) + html += "

Validation crashed: check the runtime logs.

" + if(!loadable) + html += "

Not loadable: some tiles are missing their turfs or areas.

" + + if(bad_paths.len) + html += "

Bad paths:

    " + for(var/path in bad_paths) + var/list/keys = bad_paths[path] + html += "
  1. [path]: used in ([keys.len]): [keys.Join(", ")]" + html += "

" + + if(bad_keys.len) + html += "

Bad keys:

    " + for(var/key in bad_keys) + var/list/messages = bad_keys[key] + html += "
  • [key]" + if(messages.len == 1) + html += ": [bad_keys[key][1]]" + else + html += "
    • [messages.Join("
    • ")]
    " + html += "
  • " + html += "

" + C << browse(html.Join(), "window=[tag];size=600x400") + +/datum/map_report/Topic(href, href_list) + . = ..() + if(. || !check_rights(R_ADMIN, FALSE)) // || !usr.client.holder.CheckAdminHref(href, href_list)) + return + + if (href_list["show"]) + show_to(usr) + + +/// Check a parsed but not yet loaded map for errors. +/// +/// Returns a [/datum/map_report] if there are errors or `FALSE` otherwise. +/datum/parsed_map/proc/check_for_errors() + var/datum/map_report/report = new(src) + . = report + + // build_cache will check bad paths for us + var/list/modelCache = build_cache(TRUE, report.bad_paths) + + var/static/regex/area_or_turf = regex(@"/(turf|area)/") + for(var/path in report.bad_paths) + if(area_or_turf.Find("[path]", 1, 1)) + report.loadable = FALSE + + // check for tiles with the wrong number of turfs or areas + for(var/key in modelCache) + if(key == SPACE_KEY) + continue + var/model = modelCache[key] + var/list/members = model[1] + + var/turfs = 0 + var/areas = 0 + for(var/i in 1 to members.len) + var/atom/path = members[i] + + turfs += ispath(path, /turf) + areas += ispath(path, /area) + + if(turfs == 0) + report.loadable = FALSE + LAZYADD(report.bad_keys[key], "no turf") + else if(turfs > 1) + LAZYADD(report.bad_keys[key], "[turfs] stacked turfs") + + if(areas != 1) + report.loadable = FALSE + LAZYADD(report.bad_keys[key], "[areas] areas instead of 1") + + // return the report + if(report.bad_paths.len || report.bad_keys.len || !report.loadable) + // keep the report around so it can be referenced later + report.tag = "mapreport_[++report.tag_number]" + report.crashed = FALSE + else + return FALSE diff --git a/code/modules/mapview/generation.dm b/code/modules/mapview/generation.dm index 369aa64529b5..512a21427cfa 100644 --- a/code/modules/mapview/generation.dm +++ b/code/modules/mapview/generation.dm @@ -14,12 +14,13 @@ /var/global/list/map_sizes = list(list(),list(),list()) /proc/generate_marine_mapview() - var/icon/minimap = icon('icons/minimap.dmi',map_tag) + var/icon/minimap = icon('icons/minimap.dmi',SSmapping.configs[GROUND_MAP].map_name) var/min_x = 1000 var/max_x = 0 var/min_y = 1000 var/max_y = 0 - for(var/turf/T in z1turfs) + for(var/z1 in z1turfs) + var/turf/T = z1 if(T.x < min_x && !istype(T,/turf/open/space)) min_x = T.x if(T.x > max_x && !istype(T,/turf/open/space)) @@ -29,7 +30,7 @@ if(T.y > max_y && !istype(T,/turf/open/space)) max_y = T.y var/area/A = get_area(T) - if((map_tag != MAP_PRISON_STATION || map_tag != MAP_CORSAT) && istype(T,/turf/open/space)) + if((SSmapping.configs[GROUND_MAP].map_name != MAP_PRISON_STATION || SSmapping.configs[GROUND_MAP].map_name != MAP_CORSAT) && istype(T,/turf/open/space)) minimap.DrawBox(rgb(0,0,0),T.x,T.y) continue var/obj/structure/resource_node/plasma/plasma = locate(/obj/structure/resource_node/plasma) in T @@ -91,7 +92,7 @@ var/list/tier_2 = list() var/list/tier_3 = list() for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) - if(H.z != 1 && !istype(H.loc,/mob/living/carbon/Xenomorph)) + if(!is_ground_level(H.z)) continue if(!H.has_helmet_camera()) continue @@ -140,7 +141,7 @@ newoverlay.DrawBox(rgb(128,255,128),V.x,V.y+1) if(SSticker.toweractive) for(var/mob/living/carbon/Xenomorph/X in GLOB.living_xeno_list) - if(X.loc.z != 1) continue + if(!is_ground_level(X.loc.z)) continue switch(X.tier) if(0) tier_0 += X diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 60f934688d11..c8348170c49b 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -313,12 +313,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set category = "Ghost" set name = "Teleport" set desc= "Teleport to a location" + if(!istype(usr, /mob/dead/observer)) to_chat(src, "Not when you're not dead!") return - var/A - A = input("Area to jump to", "BOOYEA", A) as null|anything in ghostteleportlocs - var/area/thearea = ghostteleportlocs[A] + + var/area/thearea = input("Area to jump to", "BOOYEA") as null|anything in GLOB.sorted_areas if(!thearea) return var/list/L = list() @@ -327,8 +327,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!L || !L.len) to_chat(src, "No area available.") + return - usr.forceMove(pick(L)) + usr.loc = pick(L) following = null /mob/dead/observer/verb/follow_local(var/mob/target) diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm index 5605ecc1a9f9..d49361609d68 100644 --- a/code/modules/mob/death.dm +++ b/code/modules/mob/death.dm @@ -3,7 +3,7 @@ /mob/proc/gib(var/cause = "gibbing") death(cause, 1) gib_animation() - if (map_tag != MAP_WHISKEY_OUTPOST) + if (!SSticker?.mode?.hardcore) spawn_gibs() // You're not coming back from being gibbed. Stop tracking here diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index 71d99e5e9c50..9dc962ca0734 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -5,8 +5,8 @@ icon = 'icons/obj/objects.dmi' flags_equip_slot = SLOT_HEAD -/obj/item/holder/New() - ..() +/obj/item/holder/Initialize() + . = ..() START_PROCESSING(SSobj, src) /obj/item/holder/Destroy() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 128c05716334..ca741c8be128 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -17,7 +17,7 @@ prev_gender = gender // Debug for plural genders - if(map_tag == MAP_WHISKEY_OUTPOST) + if(SSticker?.mode?.hardcore) hardcore = TRUE //For WO disposing of corpses /mob/living/carbon/human/initialize_pass_flags(var/datum/pass_flags_container/PF) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 656057011bf9..f1ee9e621d54 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -118,23 +118,23 @@ H.internal_organs_by_name = list() //This is a basic humanoid limb setup. - var/obj/limb/chest/C = new(null, H) + var/obj/limb/chest/C = new(H, null, H) H.limbs += C - var/obj/limb/groin/G = new(C, H) + var/obj/limb/groin/G = new(H, C, H) H.limbs += G - H.limbs += new/obj/limb/head(C, H) - var/obj/limb/arm/l_arm/LA = new(C, H) + H.limbs += new /obj/limb/head(H, C, H) + var/obj/limb/arm/l_arm/LA = new(H, C, H) H.limbs += LA - var/obj/limb/arm/r_arm/RA = new(C, H) + var/obj/limb/arm/r_arm/RA = new(H, C, H) H.limbs += RA - var/obj/limb/leg/l_leg/LL = new(G, H) + var/obj/limb/leg/l_leg/LL = new(H, G, H) H.limbs += LL - var/obj/limb/leg/r_leg/RL = new(G, H) + var/obj/limb/leg/r_leg/RL = new(H, G, H) H.limbs += RL - H.limbs += new/obj/limb/hand/l_hand(LA, H) - H.limbs += new/obj/limb/hand/r_hand(RA, H) - H.limbs += new/obj/limb/foot/l_foot(LL, H) - H.limbs += new/obj/limb/foot/r_foot(RL, H) + H.limbs += new /obj/limb/hand/l_hand(H, LA, H) + H.limbs += new /obj/limb/hand/r_hand(H, RA, H) + H.limbs += new /obj/limb/foot/l_foot(H, LL, H) + H.limbs += new /obj/limb/foot/r_foot(H, RL, H) for(var/organ in has_organ) var/organ_type = has_organ[organ] diff --git a/code/modules/mob/living/carbon/xenomorph/Powers.dm b/code/modules/mob/living/carbon/xenomorph/Powers.dm index ed51c4ecdc54..7ccc3faa053c 100644 --- a/code/modules/mob/living/carbon/xenomorph/Powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/Powers.dm @@ -9,7 +9,7 @@ return FALSE if(!check_plasma(total_resin_cost)) return FALSE - if(interior_manager && interior_manager.interior_z == z) + if(GLOB.interior_manager.interior_z == z) to_chat(src, SPAN_XENOWARNING("It's too tight in here to build.")) return FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm index fc4dc6689533..8af8bf5ff031 100644 --- a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm +++ b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm @@ -467,7 +467,7 @@ hud_set_pheromone() /mob/living/carbon/Xenomorph/proc/nocrit(var/wowave) - if(map_tag == MAP_WHISKEY_OUTPOST) + if(SSticker?.mode?.hardcore) if(wowave < 15) maxHealth = ((maxHealth+abs(crit_health))*(wowave/15)*(3/4))+((maxHealth)*1/4) //if it's wo we give xeno's less hp in lower rounds. This makes help the marines feel good. health = ((health+abs(crit_health))*(wowave/15)*(3/4))+((health)*1/4) //if it's wo we give xeno's less hp in lower rounds. This makes help the marines feel good. diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm index 92f7fe54853c..d77728ce24e0 100644 --- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm +++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm @@ -299,7 +299,7 @@ . = ..() //WO GAMEMODE - if(map_tag == MAP_WHISKEY_OUTPOST) + if(SSticker?.mode?.hardcore) hardcore = 1 //Prevents healing and queen evolution time_of_birth = world.time diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm index 817defd86f37..0d9bf011001d 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm @@ -152,7 +152,7 @@ to_chat(X, SPAN_XENOWARNING("You need to be on resin to grow an ovipositor.")) return - if(interior_manager && interior_manager.interior_z == X.z) + if(GLOB.interior_manager.interior_z == X.z) to_chat(X, SPAN_XENOWARNING("It's too tight in here to grow an ovipositor.")) return diff --git a/code/modules/mob/living/carbon/xenomorph/damage_procs.dm b/code/modules/mob/living/carbon/xenomorph/damage_procs.dm index 9c53bb9cd359..6883fc6c5bf9 100644 --- a/code/modules/mob/living/carbon/xenomorph/damage_procs.dm +++ b/code/modules/mob/living/carbon/xenomorph/damage_procs.dm @@ -169,7 +169,7 @@ updatehealth() /mob/living/carbon/Xenomorph/proc/check_blood_splash(damage = 0, damtype = BRUTE, chancemod = 0, radius = 1) - if(!damage || world.time < acid_splash_last + acid_splash_cooldown ||map_tag == MAP_WHISKEY_OUTPOST) + if(!damage || world.time < acid_splash_last + acid_splash_cooldown || SSticker?.mode?.hardcore) return FALSE var/chance = 20 //base chance if(damtype == BRUTE) chance += 5 diff --git a/code/modules/mob/living/carbon/xenomorph/death.dm b/code/modules/mob/living/carbon/xenomorph/death.dm index 87579d74eef6..13aef94c772a 100644 --- a/code/modules/mob/living/carbon/xenomorph/death.dm +++ b/code/modules/mob/living/carbon/xenomorph/death.dm @@ -11,7 +11,7 @@ if(is_zoomed) zoom_out() - if(map_tag == MAP_WHISKEY_OUTPOST) + if(SSticker?.mode?.hardcore) ghostize() SetLuminosity(0) diff --git a/code/modules/mob/living/carbon/xenomorph/say.dm b/code/modules/mob/living/carbon/xenomorph/say.dm index 50e82dc7fb69..35b9037f1ba2 100644 --- a/code/modules/mob/living/carbon/xenomorph/say.dm +++ b/code/modules/mob/living/carbon/xenomorph/say.dm @@ -23,7 +23,7 @@ if(copytext(message, 1, 2) == "*") return emote(copytext(message, 2), player_caused = TRUE) - var/datum/language/speaking = null + var/datum/language/speaking = null if(length(message) >= 2) if(copytext(message,1,2) == ";" && languages.len) for(var/datum/language/L in languages) @@ -56,7 +56,7 @@ forced = 1 break - if(speaking && !forced) + if(speaking && !forced) if (copytext(message,1,2) == ";") message = trim(copytext(message,2)) else if (copytext(message,1,3) == ":q" || copytext(message,1,3) == ":Q") @@ -88,18 +88,18 @@ if(interference) to_chat(src, SPAN_WARNING("A headhunter temporarily cut off your psychic connection!")) return - + hivemind_broadcast(message, hive) /mob/living/carbon/proc/hivemind_broadcast(var/message, var/datum/hive_status/hive) if(!message || stat || !hive) return - if(!hive.living_xeno_queen && !Check_WO() && !hive.allow_no_queen_actions) + if(!hive.living_xeno_queen && !SSticker?.mode?.hardcore && !hive.allow_no_queen_actions) to_chat(src, SPAN_WARNING("There is no Queen. You are alone.")) return - log_hivemind("[key_name(src)] : [message]") + log_hivemind("[key_name(src)] : [message]") var/track = "" var/overwatch_target = XENO_OVERWATCH_TARGET_HREF @@ -138,6 +138,6 @@ rendered = SPAN_XENOLEADER("Hivemind, Leader [src.name] [overwatch_insert] hisses, '[message]'") else rendered = SPAN_XENO("Hivemind, [src.name] [overwatch_insert] hisses, '[message]'") - + S.show_message(rendered, 2) - + diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm b/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm index 06d42f44834b..e70dca824605 100644 --- a/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm +++ b/code/modules/mob/living/carbon/xenomorph/xeno_verbs.dm @@ -7,7 +7,7 @@ if(!hive) return - if((!hive.living_xeno_queen || Check_WO()) && !hive.allow_no_queen_actions) //No Hive status on WO + if((!hive.living_xeno_queen || SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST) && !hive.allow_no_queen_actions) //No Hive status on WO to_chat(src, SPAN_WARNING("There is no Queen. You are alone.")) return diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm index dbc742210d34..1f165fd06890 100644 --- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm +++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm @@ -11,10 +11,6 @@ if(SSticker) cameranet.updateVisibility(src) -/turf/New() - ..() - visibilityChanged() - /obj/structure/machinery/door/poddoor/shutters/open() if(SSticker) cameranet.updateVisibility(src) @@ -38,8 +34,8 @@ cameranet.updateVisibility(src) . = ..() -/obj/structure/New() - ..() +/obj/structure/Initialize() + . = ..() if(SSticker) cameranet.updateVisibility(src) @@ -101,8 +97,8 @@ SetLuminosity(0) cameranet.removeCamera(src) -/obj/structure/machinery/camera/New() - ..() +/obj/structure/machinery/camera/Initialize() + . = ..() cameranet.cameras += src //Camera must be added to global list of all cameras no matter what... var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) //...but if all of camera's networks are restricted, it only works for specific camera consoles. if(open_networks.len) //If there is at least one open network, chunk is available for AI usage. diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 7ec92765bc68..15844205d823 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -66,4 +66,9 @@ else if(!isobserver(src) && faction) check_event_info(faction) + if(client.player_details) + for(var/foo in client.player_details.post_login_callbacks) + var/datum/callback/CB = foo + CB.Invoke() + client.init_verbs() diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index c4ac8b82a40d..66297b973901 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -1,6 +1,6 @@ /mob/Logout() nanomanager.user_logout(src) // this is used to clean up (remove) this user's Nano UIs - if(interactee) + if(interactee) unset_interaction() GLOB.player_list -= src log_access("Logout: [key_name(src)]") @@ -23,4 +23,9 @@ logging_ckey = null - return TRUE \ No newline at end of file + if(client) + for(var/foo in client.player_details.post_logout_callbacks) + var/datum/callback/CB = foo + CB.Invoke() + + return TRUE diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 9deabf1b308a..9fb9c4129ca7 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -13,8 +13,8 @@ var/last_upgrade = 0 //used for cooldown between grab upgrades. -/obj/item/grab/New() - ..() +/obj/item/grab/Initialize() + . = ..() last_upgrade = world.time /obj/item/grab/dropped(mob/user) @@ -55,8 +55,8 @@ var/mob/living/carbon/Xenomorph/X = user X.pull_power(grabbed_thing) return - - + + var/mob/victim = grabbed_thing if(victim.mob_size > MOB_SIZE_HUMAN || !(victim.status_flags & CANPUSH)) return //can't tighten your grip on big mobs and mobs you can't push. @@ -122,10 +122,10 @@ if(X.pulling == pulled && !pulled.buckled && (pulled.stat != DEAD || pulled.chestburst) && !X.stomach_contents.len) //make sure you've still got them in your claws, and alive if(SEND_SIGNAL(pulled, COMSIG_MOB_DEVOURED, X) & COMPONENT_CANCEL_DEVOUR) return FALSE - + X.visible_message(SPAN_WARNING("[X] devours [pulled]!"), \ SPAN_WARNING("You devour [pulled]!"), null, 5) - + //IMPORTANT CODER NOTE: Due to us using the old lighting engine, we need to hacky hack hard to get this working properly //So we're just going to get the lights out of here by forceMoving them to a far-away place //They will be recovered when regurgitating, since this also calls forceMove diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 047d7ec1b441..28f9558adbed 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -102,6 +102,9 @@ new_player_panel_proc(TRUE) if("observe") + if(!SSticker || SSticker.current_state == GAME_STATE_STARTUP) + to_chat(src, "The game is still setting up, please try again later.") + return if(alert(src,"Are you sure you wish to observe? When you observe, you will not be able to join as marine. It might also take some time to become a xeno or responder!","Player Setup","Yes","No") == "Yes") if(!client) return TRUE @@ -227,9 +230,9 @@ close_spawn_windows() var/turf/T - if(map_tag != MAP_WHISKEY_OUTPOST) + if(SSmapping.configs[GROUND_MAP].map_name != MAP_WHISKEY_OUTPOST) T = get_turf(pick(GLOB.latejoin)) - else if (map_tag == MAP_WHISKEY_OUTPOST) + else if (SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST) T = get_turf(pick(GLOB.latewhiskey)) var/mob/living/carbon/human/character = create_character() //creates the human and transfers vars and mind @@ -237,7 +240,7 @@ EquipCustomItems(character) GLOB.data_core.manifest_inject(character) - if(map_tag == MAP_WHISKEY_OUTPOST) + if(SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST) call(/datum/game_mode/whiskey_outpost/proc/spawn_player)(character) SSticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn SSticker.mode.latejoin_tally++ diff --git a/code/modules/organs/limbs.dm b/code/modules/organs/limbs.dm index 4709abc5cb38..9d01248ca9f8 100644 --- a/code/modules/organs/limbs.dm +++ b/code/modules/organs/limbs.dm @@ -68,7 +68,8 @@ var/list/bleeding_effects_list = list() -/obj/limb/New(obj/limb/P, mob/mob_owner) +/obj/limb/Initialize(mapload, obj/limb/P, mob/mob_owner) + . = ..() if(P) parent = P if(!parent.children) diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index 4066f4c3a122..87fc5b6e9f61 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -11,7 +11,7 @@ var/obj/item/toppaper //The topmost piece of paper. flags_equip_slot = SLOT_WAIST -/obj/item/clipboard/New() +/obj/item/clipboard/Initialize() . = ..() update_icon() diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index 0077b26302f8..6c9f24a9bd12 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -30,11 +30,11 @@ desc = "A black folder. It is decorated with stripes." icon_state = "folder_black_green" -/obj/item/folder/black_random/New() +/obj/item/folder/black_random/Initialize() . = ..() icon_state = "folder_black[pick("_red", "_green", "_blue", "_yellow", "_white")]" -/obj/item/folder/New() +/obj/item/folder/Initialize() . = ..() if(updateicon) update_icon() diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index dd9cf1944e91..cf8559d044c2 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -33,8 +33,8 @@ //lipstick wiping is in code/game/obj/items/weapons/cosmetics.dm! -/obj/item/paper/New() - ..() +/obj/item/paper/Initialize() + . = ..() pixel_y = rand(-8, 8) pixel_x = rand(-9, 9) stamps = "" @@ -44,10 +44,8 @@ info = replacetext(info, "\n", "
") info = parsepencode(info) - spawn(2) - update_icon() - updateinfolinks() - return + update_icon() + updateinfolinks() /obj/item/paper/update_icon() if(icon_state == "paper_talisman" || icon_state == "paper_wy_words" || icon_state == "paper_uscm") @@ -497,6 +495,11 @@ name = "paper- 'Test Log'" info = "

TEST LOG

SPECIMEN: Bioweapon candidate Kappa. Individual 3


\n

-

PROCEDURE: Observation

RESULTS: Specimen paces around cell. Appears agitated. Vocalisations.

-

PROCEDURE: Simian test subject

RESULTS: Devoured by specimen. No significant difference from last simian test.

Note: Time to amp it up

-

PROCEDURE: Human test subject (D-1). Instructed to \"pet it like a dog\"

RESULTS: Specimen and D-1 stare at each other for approximately two seconds. D-1 screams and begins pounding on observation window, begging to be released. Specimen pounces on D-1. Specimen kills D-1 with multiple slashes from its foreclaws.

Note: Promising!

-

PROCEDURE: Two human test subjects (D-2, D-3). Instructed to subdue specimen

RESULTS: D-2 and D-3 slowly approach specimen. D-3 punches specimen on forehead to no noticeable effect. Specimen pounces on D-3, then kills him with multiple slashes from its foreclaws. D-2 screams and begins pounding on observation window. Specimen pounces on D-2, then kills him with multiple slashes from its foreclaws.

Specimen begins slashing at observation access doors. Exhibiting an unexpected amount of strength, it is able to d~

" +/obj/item/paper/prison_station/interrogation_log + name = "paper- 'Test Log'" + desc = "This paper seems to have been crumpled up in dried blood, turning it nearly unreadable."; + info = "

INTERROGATION LOG

Person: (Withheld) 'Verdan' (Withheld)


\n

PROCEDURE: Wringer Technique

RESULTS: Verdan bashes head around. Appears agitated and cries, perhaps angry. Heavy Vocalisations.

-

PROCEDURE: Shocking.

RESULTS: Cries and screams in anger. No significant difference from last procedure.

Note: Pain Tolerant, must increase pain.

-

PROCEDURE: Handy Man. Instructed to \"look.\" while saw performs its work.

RESULTS: Verdan stares for approximately three seconds. Verdan screams and begins trying to break the restraints while begging to be released. The saw finally completes its work. Verdan seems to be a blabbering mess.

Note: Promising!

-

PROCEDURE: Information Gathering.

RESULTS: Verdan starts giving out information about the other cells.

Verdan starts whispering from fatigue, have to sit closer. Verdan leans in closer to me, he~

(The remaining paper is splattered in blood and unreadable.)"; + /obj/item/paper/prison_station/monkey_note name = "paper- 'Note on simian test subjects'" info = "Keep an eye on the monkeys, and keep track of the numbers. We just found out that they can crawl through air vents and into the atmospheric system.
\n
\nI'd rather not have to explain to the Warden how the prisoners managed to acquire a new \"pet\". Again." @@ -552,7 +555,11 @@ /obj/item/paper/research_notes/Initialize() . = ..() - addtimer(CALLBACK(src, .proc/generate), 7) //To make sure reagents got initialized first + return INITIALIZE_HINT_LATELOAD + +/obj/item/paper/research_notes/LateInitialize() + . = ..() + generate() /obj/item/paper/research_notes/proc/generate() if(!note_type) @@ -748,14 +755,13 @@ name = "incident report" var/datum/crime_incident/incident -/obj/item/paper/incident/New() +/obj/item/paper/incident/Initialize() + . = ..() info = {"\[center\]\[logo\]\[/center\] \[center\]\[b\]\[i\]Encoded USCM Incident Report\[/b\]\[/i\]\[hr\] \[small\]FOR USE BY MP'S ONLY\[/small\]\[br\] \[barcode\]\[/center\]"} - ..() - /obj/item/paper/incident/Destroy() incident = null @@ -765,7 +771,8 @@ /obj/item/paper/fingerprint name = "fingerprint report" -/obj/item/paper/fingerprint/New(var/criminal_name = "", var/criminal_rank = "", var/criminal_squad = "", var/description = "") +/obj/item/paper/fingerprint/Initialize(mapload, var/criminal_name = "", var/criminal_rank = "", var/criminal_squad = "", var/description = "") + . = ..() info = {"\[center\]\[logo\]\[/center\] \[center\]\[b\]\[i\]Fingerprint Sample From [criminal_name]\[/b\]\[/i\]\[hr\] \[small\] @@ -775,5 +782,3 @@ Description [description]\[br\] \[/small\] \[/center\]"} - - ..() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index cf88a432954e..52bbc69c041d 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -121,7 +121,7 @@ appearance_flags = TILE_BOUND -/obj/structure/machinery/power/apc/New(var/turf/loc, var/ndir, var/building=0) +/obj/structure/machinery/power/apc/Initialize(mapload, var/ndir, var/building=0) . = ..() //Offset 24 pixels in direction of dir @@ -146,8 +146,6 @@ start_processing() - sleep(0) //Break few ACPs on the colony - if(!start_charge && is_ground_level(z) && prob(10)) set_broken() @@ -1216,12 +1214,14 @@ //Aesthetically much better! visible_message(SPAN_WARNING("[src]'s screen flickers with warnings briefly!")) - spawn(rand(2, 5)) - visible_message(SPAN_DANGER("[src]'s screen suddenly explodes in rain of sparks and small debris!")) - stat |= BROKEN - operating = 0 - update_icon() - update() + addtimer(CALLBACK(src, .proc/do_set_broken), rand(2, 5)) + +/obj/structure/machinery/power/apc/proc/do_set_broken() + visible_message(SPAN_DANGER("[src]'s screen suddenly explodes in rain of sparks and small debris!")) + stat |= BROKEN + operating = 0 + update_icon() + update() //Overload all the lights in this APC area /obj/structure/machinery/power/apc/proc/overload_lighting() diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index ead995e586f5..75356ad55c4f 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -154,7 +154,7 @@ return 0 /obj/structure/cable/ex_act(severity) - if(Check_WO()) + if(SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST) return if(is_ground_level(z) && layer < 2) //ground map - no blowie. They are buried underground. return diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 90133dbc64ef..359a10ebc123 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -8,7 +8,7 @@ icon = 'icons/obj/structures/machinery/power.dmi' icon_state = "cell" item_state = "cell" - + force = 5.0 throwforce = 5.0 throw_speed = SPEED_VERY_FAST @@ -21,9 +21,9 @@ var/construction_time=100 matter = list("metal" = 700, "glass" = 50) -/obj/item/cell/New() - ..() - +/obj/item/cell/Initialize() + . = ..() + charge = maxcharge updateicon() @@ -114,66 +114,66 @@ /obj/item/cell/crap name = "\improper Yamada brand rechargable AA battery" desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT - + maxcharge = 500 matter = list("metal" = 700, "glass" = 40) -/obj/item/cell/crap/empty/New() - ..() +/obj/item/cell/crap/empty/Initialize() + . = ..() charge = 0 /obj/item/cell/secborg name = "security borg rechargable D battery" - + maxcharge = 600 //600 max charge / 100 charge per shot = six shots matter = list("metal" = 700, "glass" = 40) -/obj/item/cell/secborg/empty/New() - ..() +/obj/item/cell/secborg/empty/Initialize() + . = ..() charge = 0 /obj/item/cell/apc name = "heavy-duty power cell" - + maxcharge = 5000 matter = list("metal" = 700, "glass" = 50) /obj/item/cell/apc/full charge = 5000 - + /obj/item/cell/high name = "high-capacity power cell" - + icon_state = "hcell" maxcharge = 10000 matter = list("metal" = 700, "glass" = 60) -/obj/item/cell/high/empty/New() - ..() +/obj/item/cell/high/empty/Initialize() + . = ..() charge = 0 /obj/item/cell/super name = "super-capacity power cell" - + icon_state = "scell" maxcharge = 20000 matter = list("metal" = 700, "glass" = 70) construction_cost = list("metal"=750,"glass"=100) -/obj/item/cell/super/empty/New() - ..() +/obj/item/cell/super/empty/Initialize() + . = ..() charge = 0 /obj/item/cell/hyper name = "hyper-capacity power cell" - + icon_state = "hpcell" maxcharge = 30000 matter = list("metal" = 700, "glass" = 80) construction_cost = list("metal"=500,"glass"=150,"gold"=200,"silver"=200) -/obj/item/cell/hyper/empty/New() - ..() +/obj/item/cell/hyper/empty/Initialize() + . = ..() charge = 0 /obj/item/cell/infinite @@ -187,7 +187,7 @@ /obj/item/cell/potato name = "potato battery" desc = "A rechargable starch based power cell." - + icon = 'icons/obj/structures/machinery/power.dmi' //'icons/obj/items/harvest.dmi' icon_state = "potato_cell" //"potato_battery" charge = 100 diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index eab8d1cfec01..54882d4d818c 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -158,7 +158,7 @@ /obj/structure/machinery/light/containment/attack_alien(mob/living/carbon/Xenomorph/M) return - + // the smaller bulb light fixture @@ -698,8 +698,8 @@ /obj/structure/machinery/landinglight/ex_act(severity) return -/obj/structure/machinery/landinglight/New() - ..() +/obj/structure/machinery/landinglight/Initialize(mapload, ...) + . = ..() turn_off() /obj/structure/machinery/landinglight/proc/turn_off() diff --git a/code/modules/projectiles/updated_projectiles/ammunition.dm b/code/modules/projectiles/updated_projectiles/ammunition.dm index 1ada50e593bb..4601c89deb2b 100644 --- a/code/modules/projectiles/updated_projectiles/ammunition.dm +++ b/code/modules/projectiles/updated_projectiles/ammunition.dm @@ -28,8 +28,8 @@ They're all essentially identical when it comes to getting the job done. var/base_mag_icon //the default mag icon state. var/base_mag_item //the default mag item (inhand) state. -/obj/item/ammo_magazine/New(loc, spawn_empty) - ..() +/obj/item/ammo_magazine/Initialize(mapload, spawn_empty) + . = ..() GLOB.ammo_magazine_list += src base_mag_icon = icon_state base_mag_item = item_state @@ -257,8 +257,8 @@ Turn() or Shift() as there is virtually no overhead. ~N var/number_of_states = 10 //How many variations of this item there are. garbage = TRUE -/obj/item/ammo_casing/New() - ..() +/obj/item/ammo_casing/Initialize() + . = ..() pixel_x = rand(-2.0, 2) //Want to move them just a tad. pixel_y = rand(-2.0, 2) icon_state += "[rand(1,number_of_states)]" //Set the icon to it. diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index f7a47dfd8e1e..18b8f55ebdff 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -25,18 +25,17 @@ var/disposal_pressure = 0 //Create a new disposal, find the attached trunk (if present) and init gas resvr. -/obj/structure/machinery/disposal/New() - ..() - spawn(5) - trunk = locate() in loc - if(!trunk) - mode = 0 - flush = 0 - else - trunk.linked = src //Link the pipe trunk to self +/obj/structure/machinery/disposal/Initialize(mapload, ...) + . = ..() + trunk = locate() in loc + if(!trunk) + mode = 0 + flush = 0 + else + trunk.linked = src //Link the pipe trunk to self - update() - start_processing() + update() + start_processing() /obj/structure/machinery/disposal/initialize_pass_flags(var/datum/pass_flags_container/PF) ..() @@ -510,8 +509,7 @@ if(hasmob && prob(3)) for(var/mob/living/H in src) if(!istype(H, /mob/living/silicon/robot/drone)) //Drones use the mailing code to move through the disposal system, - if(map_tag != MAP_WHISKEY_OUTPOST) - H.take_overall_damage(20, 0, "Blunt Trauma") //Horribly maim any living creature jumping down disposals. c'est la vie + H.take_overall_damage(20, 0, "Blunt Trauma") //Horribly maim any living creature jumping down disposals. c'est la vie if(has_fat_guy && prob(2)) //Chance of becoming stuck per segment if contains a fat guy active = 0 @@ -606,10 +604,9 @@ var/base_icon_state //Initial icon state on map //New pipe, set the icon_state as on map - New() - ..() - base_icon_state = icon_state - return +/obj/structure/disposalpipe/Initialize(mapload, ...) + . = ..() + base_icon_state = icon_state //Pipe is deleted @@ -769,7 +766,7 @@ //Test health for brokenness /obj/structure/disposalpipe/proc/healthcheck() - if(Check_WO()) + if(SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST) return if(health < -2) broken(0) @@ -844,22 +841,22 @@ /obj/structure/disposalpipe/segment icon_state = "pipe-s" - New() - ..() - if(icon_state == "pipe-s") - dpdir = dir|turn(dir, 180) - else - dpdir = dir|turn(dir, -90) - update() +/obj/structure/disposalpipe/segment/Initialize(mapload, ...) + . = ..() + if(icon_state == "pipe-s") + dpdir = dir|turn(dir, 180) + else + dpdir = dir|turn(dir, -90) + update() //Z-Level stuff /obj/structure/disposalpipe/up icon_state = "pipe-u" - New() - ..() - dpdir = dir - update() +/obj/structure/disposalpipe/up/Initialize(mapload, ...) + . = ..() + dpdir = dir + update() /obj/structure/disposalpipe/up/nextdir(var/fromdir) var/nextdir @@ -899,10 +896,10 @@ /obj/structure/disposalpipe/down icon_state = "pipe-d" - New() - ..() - dpdir = dir - update() +/obj/structure/disposalpipe/down/Initialize(mapload, ...) + . = ..() + dpdir = dir + update() /obj/structure/disposalpipe/down/nextdir(var/fromdir) var/nextdir @@ -1028,15 +1025,15 @@ /obj/structure/disposalpipe/junction icon_state = "pipe-j1" - New() - ..() - if(icon_state == "pipe-j1") - dpdir = dir|turn(dir, -90)|turn(dir, 180) - else if(icon_state == "pipe-j2") - dpdir = dir|turn(dir, 90)|turn(dir, 180) - else //Pipe-y - dpdir = dir|turn(dir,90)|turn(dir, -90) - update() +/obj/structure/disposalpipe/junction/Initialize(mapload, ...) + . = ..() + if(icon_state == "pipe-j1") + dpdir = dir|turn(dir, -90)|turn(dir, 180) + else if(icon_state == "pipe-j2") + dpdir = dir|turn(dir, 90)|turn(dir, 180) + else //Pipe-y + dpdir = dir|turn(dir,90)|turn(dir, -90) + update() //Next direction to move, if coming in from secondary dirs, then next is primary dir, if coming in from primary dir, then next is equal chance of other dirs /obj/structure/disposalpipe/junction/nextdir(var/fromdir) @@ -1069,13 +1066,13 @@ var/sort_tag = "" var/partial = 0 - New() - . = ..() - dpdir = dir|turn(dir, 180) - if(sort_tag) tagger_locations |= sort_tag - updatename() - updatedesc() - update() +/obj/structure/disposalpipe/tagger/Initialize(mapload, ...) + . = ..() + dpdir = dir|turn(dir, 180) + if(sort_tag) tagger_locations |= sort_tag + updatename() + updatedesc() + update() /obj/structure/disposalpipe/tagger/proc/updatedesc() desc = initial(desc) @@ -1126,14 +1123,14 @@ var/negdir = 0 var/sortdir = 0 - New() - . = ..() - if(sortType) tagger_locations |= sortType +/obj/structure/disposalpipe/sortjunction/Initialize(mapload, ...) + . = ..() + if(sortType) tagger_locations |= sortType - updatedir() - updatename() - updatedesc() - update() + updatedir() + updatename() + updatedesc() + update() /obj/structure/disposalpipe/sortjunction/proc/updatedesc() desc = initial(desc) @@ -1232,12 +1229,15 @@ icon_state = "pipe-t" var/obj/linked //The linked obj/structure/machinery/disposal or obj/disposaloutlet -/obj/structure/disposalpipe/trunk/New() - ..() +/obj/structure/disposalpipe/trunk/Initialize(mapload, ...) + . = ..() dpdir = dir - spawn(1) - getlinked() update() + return INITIALIZE_HINT_LATELOAD + +/obj/structure/disposalpipe/trunk/LateInitialize() + . = ..() + getlinked() /obj/structure/disposalpipe/trunk/proc/getlinked() linked = null @@ -1312,9 +1312,9 @@ dpdir = 0 //Broken pipes have dpdir = 0 so they're not found as 'real' pipes i.e. will be treated as an empty turf desc = "A broken piece of disposal pipe." - New() - ..() - update() +/obj/structure/disposalpipe/broken/Initialize(mapload, ...) + . = ..() + update() //Called when welded, for broken pipe, remove and turn into scrap /obj/structure/disposalpipe/broken/welded() @@ -1333,14 +1333,12 @@ var/mode = 0 var/range = 10 - New() - ..() - - spawn(1) - target = get_ranged_target_turf(src, dir, range) - var/obj/structure/disposalpipe/trunk/trunk = locate() in loc - if(trunk) - trunk.linked = src //Link the pipe trunk to self +/obj/structure/disposaloutlet/Initialize(mapload, ...) + . = ..() + target = get_ranged_target_turf(src, dir, range) + var/obj/structure/disposalpipe/trunk/trunk = locate() in loc + if(trunk) + trunk.linked = src //Link the pipe trunk to self //Expel the contents of the holder object, then delete it. Called when the holder exits the outlet /obj/structure/disposaloutlet/proc/expel(var/obj/structure/disposalholder/H) diff --git a/code/modules/round_recording/round_recorder.dm b/code/modules/round_recording/round_recorder.dm index 4110e588e4bb..ea4ba8d8690b 100644 --- a/code/modules/round_recording/round_recorder.dm +++ b/code/modules/round_recording/round_recorder.dm @@ -30,7 +30,7 @@ /datum/round_recorder/proc/start_game() game_start = time2text(world.realtime, "DD.MM.YYYY@hh:mm:ss") - map = map_tag + map = SSmapping.configs[GROUND_MAP].map_name gamemode = master_mode round_name = round_statistics.name diff --git a/code/modules/shuttles/escape_pods.dm b/code/modules/shuttles/escape_pods.dm index 66cd05dd4e0f..b1fe72412a39 100644 --- a/code/modules/shuttles/escape_pods.dm +++ b/code/modules/shuttles/escape_pods.dm @@ -41,11 +41,11 @@ with the original.*/ can_launch() //Cannot launch it early before the evacuation takes place proper, and the pod must be ready. Cannot be delayed, broken, launching, or otherwise. if(..() && EvacuationAuthority.evac_status >= EVACUATION_STATUS_INITIATING) switch(evacuation_program.dock_state) - if(STATE_READY) + if(STATE_READY) return TRUE if(STATE_DELAYED) for(var/obj/structure/machinery/cryopod/evacuation/C in cryo_cells) //If all are occupied, the pod will launch anyway. - if(!C.occupant) + if(!C.occupant) return FALSE return TRUE @@ -128,7 +128,7 @@ for(var/obj/structure/machinery/cryopod/evacuation/C in cryo_cells) C.go_out() D.lock() /datum/shuttle/ferry/marine/evacuation_pod/proc/prepare_for_launch() - if(!can_launch()) + if(!can_launch()) return FALSE //Can't launch in some circumstances. evacuation_program.dock_state = STATE_LAUNCHING spawn() @@ -166,7 +166,7 @@ This can probably be done a lot more elegantly either way, but it'll suffice for for(var/obj/structure/machinery/cryopod/evacuation/C in cryo_cells) if(C.occupant) n++ - if(C.occupant.stat != DEAD && msg) + if(C.occupant.stat != DEAD && msg) to_chat(C.occupant, msg) //Hardcoded typecast, which should be changed into some weight system of some kind eventually. var/area/A = msg ? evacuation_program.master.loc.loc : staging_area //Before or after launch. @@ -175,19 +175,19 @@ This can probably be done a lot more elegantly either way, but it'll suffice for M = locate(/mob/living/carbon/human) in i if(M) n++ //No hiding in closets. - if(M.stat != DEAD && msg) + if(M.stat != DEAD && msg) to_chat(M, msg) else if(istype(i, /mob/living/carbon/human) || isrobot(i)) n++ //Dead or alive, counts as a thing. M = i - if(M.stat != DEAD && msg) + if(M.stat != DEAD && msg) to_chat(M, msg) else if(istype(i, /mob/living/carbon/Xenomorph)) var/mob/living/carbon/Xenomorph/X = i - if(X.mob_size >= MOB_SIZE_BIG) + if(X.mob_size >= MOB_SIZE_BIG) return FALSE //Huge xenomorphs will automatically fail the launch. n++ - if(X.stat != DEAD && msg) + if(X.stat != DEAD && msg) to_chat(X, msg) if(n > cryo_cells.len) . = FALSE //Default is 3 cryo cells and three people inside the pod. if(msg) @@ -213,7 +213,7 @@ As such, a new tracker datum must be constructed to follow proper child inherita //id_tag is the generic connection tag. //TODO make sure you can't C4 this. - ex_act(severity) + ex_act(severity) return FALSE ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) @@ -236,7 +236,7 @@ As such, a new tracker datum must be constructed to follow proper child inherita ui.set_auto_update(0) Topic(href, href_list) - if(..()) + if(..()) return TRUE //Has to return true to fail. For some reason. var/datum/shuttle/ferry/marine/evacuation_pod/P = shuttle_controller.shuttles[id_tag] @@ -293,7 +293,7 @@ As such, a new tracker datum must be constructed to follow proper child inherita var/being_forced = 0 //Simple variable to prevent sound spam. var/datum/computer/file/embedded_program/docking/simple/escape_pod/evacuation_program - ex_act(severity) + ex_act(severity) return FALSE attackby(obj/item/grab/G, mob/user) @@ -311,7 +311,7 @@ As such, a new tracker datum must be constructed to follow proper child inherita return FALSE var/mob/living/carbon/human/M = G.grabbed_thing - if(!istype(M)) + if(!istype(M)) return FALSE visible_message(SPAN_WARNING("[user] starts putting [M.name] into the cryo pod."), null, null, 3) @@ -326,7 +326,7 @@ As such, a new tracker datum must be constructed to follow proper child inherita set category = "Object" set src in oview(1) - if(!occupant || !usr.stat || usr.is_mob_restrained()) + if(!occupant || !usr.stat || usr.is_mob_restrained()) return FALSE if(occupant) //Once you're in, you cannot exit, and outside forces cannot eject you. @@ -349,7 +349,7 @@ As such, a new tracker datum must be constructed to follow proper child inherita var/mob/living/carbon/human/user = usr - if(!istype(user) || user.stat || user.is_mob_restrained()) + if(!istype(user) || user.stat || user.is_mob_restrained()) return FALSE if(being_forced) @@ -404,24 +404,24 @@ As such, a new tracker datum must be constructed to follow proper child inherita unslashable = TRUE unacidable = TRUE -/obj/structure/machinery/door/airlock/evacuation/New() - ..() +/obj/structure/machinery/door/airlock/evacuation/Initialize() + . = ..() INVOKE_ASYNC(src, .proc/lock) //Can't interact with them, mostly to prevent grief and meta. -/obj/structure/machinery/door/airlock/evacuation/Collided() +/obj/structure/machinery/door/airlock/evacuation/Collided() return FALSE -/obj/structure/machinery/door/airlock/evacuation/attackby() +/obj/structure/machinery/door/airlock/evacuation/attackby() return FALSE -/obj/structure/machinery/door/airlock/evacuation/attack_hand() +/obj/structure/machinery/door/airlock/evacuation/attack_hand() return FALSE -/obj/structure/machinery/door/airlock/evacuation/attack_alien() +/obj/structure/machinery/door/airlock/evacuation/attack_alien() return FALSE //Probably a better idea that these cannot be forced open. -/obj/structure/machinery/door/airlock/evacuation/attack_remote() +/obj/structure/machinery/door/airlock/evacuation/attack_remote() return FALSE #undef STATE_IDLE @@ -460,4 +460,4 @@ As such, a new tracker datum must be constructed to follow proper child inherita ui.set_initial_data(data) ui.open() ui.set_auto_update(1) -*/ \ No newline at end of file +*/ diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm index 99ee00af8aee..84aceb141bf2 100644 --- a/code/modules/shuttles/shuttle_console.dm +++ b/code/modules/shuttles/shuttle_console.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST_EMPTY(shuttle_controls) + /obj/structure/machinery/computer/shuttle_control name = "shuttle control console" icon = 'icons/obj/structures/machinery/computer.dmi' @@ -21,7 +23,11 @@ /obj/structure/machinery/computer/shuttle_control/Initialize() . = ..() - shuttle_datum = shuttle_controller.shuttles[shuttle_tag] + GLOB.shuttle_controls += src + +/obj/structure/machinery/computer/shuttle_control/Destroy() + GLOB.shuttle_controls -= src + return ..() /obj/structure/machinery/computer/shuttle_control/proc/get_shuttle() var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag] @@ -373,7 +379,7 @@ for(var/obj/structure/machinery/door/airlock/dropship_hatch/M in machines) if(M.id == ship_id) - if(M.z != 4) + if(!is_loworbit_level(M.z)) M.unlock() var/obj/structure/machinery/door/airlock/multi_tile/almayer/reardoor @@ -384,7 +390,7 @@ if("sh_dropship2") for(var/obj/structure/machinery/door/airlock/multi_tile/almayer/dropshiprear/ds2/D in machines) reardoor = D - if(reardoor.z != 4) + if(!is_loworbit_level(reardoor.z)) reardoor.unlock() if(href_list["side door"]) @@ -476,11 +482,9 @@ exproof = 1 req_one_access = list(ACCESS_MARINE_LEADER, ACCESS_MARINE_DROPSHIP, ACCESS_WY_CORPORATE) -/obj/structure/machinery/computer/shuttle_control/dropship1/New() - ..() +/obj/structure/machinery/computer/shuttle_control/dropship1/Initialize() + . = ..() shuttle_tag = "[MAIN_SHIP_NAME] Dropship 1" - if(shuttle_controller) - shuttle_datum = shuttle_controller.shuttles[shuttle_tag] /obj/structure/machinery/computer/shuttle_control/dropship1/onboard name = "\improper 'Alamo' flight controls" @@ -502,11 +506,9 @@ exproof = 1 req_one_access = list(ACCESS_MARINE_LEADER, ACCESS_MARINE_DROPSHIP, ACCESS_WY_CORPORATE) -/obj/structure/machinery/computer/shuttle_control/dropship2/New() - ..() +/obj/structure/machinery/computer/shuttle_control/dropship2/Initialize() + . = ..() shuttle_tag = "[MAIN_SHIP_NAME] Dropship 2" - if(shuttle_controller) - shuttle_datum = shuttle_controller.shuttles[shuttle_tag] /obj/structure/machinery/computer/shuttle_control/dropship2/onboard name = "\improper 'Normandy' flight controls" diff --git a/code/modules/shuttles/shuttle_supply.dm b/code/modules/shuttles/shuttle_supply.dm index 014c20040db7..7fc41fcbc673 100644 --- a/code/modules/shuttles/shuttle_supply.dm +++ b/code/modules/shuttles/shuttle_supply.dm @@ -1,7 +1,7 @@ - - - - +/obj/effect/landmark/supply_elevator/Initialize(mapload, ...) + . = ..() + GLOB.supply_elevator = get_turf(src) + return INITIALIZE_HINT_QDEL /datum/shuttle/ferry/supply iselevator = 1 @@ -20,15 +20,14 @@ var/elevator_loc /datum/shuttle/ferry/supply/proc/pick_loc() - elevator_loc = SupplyElevator + RETURN_TYPE(/turf) + return GLOB.supply_elevator /datum/shuttle/ferry/supply/New() ..() - pick_loc() - var/turf/SupplyElevatorLoc = get_turf(elevator_loc) - Elevator_x = SupplyElevatorLoc.x - Elevator_y = SupplyElevatorLoc.y - Elevator_z = SupplyElevatorLoc.z + Elevator_x = pick_loc().x + Elevator_y = pick_loc().y + Elevator_z = pick_loc().z SW = new /obj/effect/elevator/supply(locate(Elevator_x-2,Elevator_y-2,Elevator_z)) SE = new /obj/effect/elevator/supply(locate(Elevator_x+2,Elevator_y-2,Elevator_z)) SE.pixel_x = -128 @@ -179,9 +178,14 @@ spawn() M.icon_state = "gear" +/obj/effect/landmark/vehicleelevator/Initialize(mapload, ...) + . = ..() + GLOB.vehicle_elevator = get_turf(src) + return INITIALIZE_HINT_QDEL + /datum/shuttle/ferry/supply/vehicle railing_id = "vehicle_elevator_railing" gear_id = "vehicle_elevator_gears" /datum/shuttle/ferry/supply/vehicle/pick_loc() - elevator_loc = VehicleElevator + return GLOB.vehicle_elevator diff --git a/code/modules/vehicles/interior/interactable/doors.dm b/code/modules/vehicles/interior/interactable/doors.dm index 8705f7aeb02a..1c28d644913b 100644 --- a/code/modules/vehicles/interior/interactable/doors.dm +++ b/code/modules/vehicles/interior/interactable/doors.dm @@ -73,10 +73,9 @@ /obj/structure/interior_exit/vehicle name = "vehicle door" -/obj/structure/interior_exit/vehicle/New() - ..() - // See interior wall code for an explanation - addtimer(CALLBACK(src, .proc/update_icon), 10) +/obj/structure/interior_exit/vehicle/Initialize() + . = ..() + update_icon() /obj/structure/interior_exit/vehicle/update_icon() switch(dir) diff --git a/code/modules/vehicles/interior/interactable/vehicle_locker.dm b/code/modules/vehicles/interior/interactable/vehicle_locker.dm index 7d02cd7919fd..1d19e46a98fb 100644 --- a/code/modules/vehicles/interior/interactable/vehicle_locker.dm +++ b/code/modules/vehicles/interior/interactable/vehicle_locker.dm @@ -19,8 +19,8 @@ var/obj/item/storage/internal/container -/obj/structure/vehicle_locker/New() - ..() +/obj/structure/vehicle_locker/Initialize() + . = ..() container = new/obj/item/storage/internal(src) container.storage_slots = null container.max_w_class = SIZE_MEDIUM diff --git a/code/modules/vehicles/interior/interior.dm b/code/modules/vehicles/interior/interior.dm index 856cd0adb9ee..5c09652de4e2 100644 --- a/code/modules/vehicles/interior/interior.dm +++ b/code/modules/vehicles/interior/interior.dm @@ -45,7 +45,7 @@ /datum/interior/Destroy() exterior = null - interior_manager.unload_chunk(chunk_id) + GLOB.interior_manager.unload_chunk(chunk_id) QDEL_NULL(interior_data) @@ -60,7 +60,7 @@ return name = interior_map - var/list/data = interior_manager.load_interior(src) + var/list/data = GLOB.interior_manager.load_interior(src) if(!data) qdel(src) @@ -190,11 +190,11 @@ // Returns min and max turfs for the interior /datum/interior/proc/get_bound_turfs() - var/turf/min = locate(interior_data.bounds[MAP_MINX], interior_data.bounds[MAP_MINY], interior_manager.interior_z) + var/turf/min = locate(interior_data.bounds[MAP_MINX], interior_data.bounds[MAP_MINY], GLOB.interior_manager.interior_z) if(!min) return null - var/turf/max = locate(interior_data.bounds[MAP_MAXX], interior_data.bounds[MAP_MAXY], interior_manager.interior_z) + var/turf/max = locate(interior_data.bounds[MAP_MAXX], interior_data.bounds[MAP_MAXY], GLOB.interior_manager.interior_z) if(!max) return null @@ -203,7 +203,7 @@ /datum/interior/proc/get_middle_turf() var/list/turf/bounds = get_bound_turfs() var/turf/middle = locate(Floor(bounds[1].x + (bounds[2].x - bounds[1].x)/2), Floor(bounds[1].y + (bounds[2].y - bounds[1].y)/2), bounds[1].z) - + return middle // Store all entrance and exit markers diff --git a/code/modules/vehicles/interior/interior_manager.dm b/code/modules/vehicles/interior/interior_manager.dm index 0c45ae1edda0..2f7f3e9d7eb4 100644 --- a/code/modules/vehicles/interior/interior_manager.dm +++ b/code/modules/vehicles/interior/interior_manager.dm @@ -6,7 +6,7 @@ you want a new vehicle interior, who you come to? yeah, bud, you come to me */ -var/global/datum/interior_manager/interior_manager = new +GLOBAL_DATUM(interior_manager, /datum/interior_manager) /datum/interior_manager // The z level to use for storing interiors in @@ -25,8 +25,8 @@ var/global/datum/interior_manager/interior_manager = new /datum/interior_manager/New() // Create the z level for interiors - world.maxz += 1 - interior_z = world.maxz + var/datum/space_level/S = SSmapping.add_new_zlevel("interiors", ZTRAITS_INTERIORS) + interior_z = S.z_value // Create the illusion of the black "void" var/turf/z_min = locate(1, 1, interior_z) diff --git a/code/modules/vehicles/interior/interior_wall.dm b/code/modules/vehicles/interior/interior_wall.dm index df88b8f53363..9d5d50e5d75f 100644 --- a/code/modules/vehicles/interior/interior_wall.dm +++ b/code/modules/vehicles/interior/interior_wall.dm @@ -18,17 +18,10 @@ /obj/structure/interior_wall/ex_act() return -/obj/structure/interior_wall/New() +/obj/structure/interior_wall/Initialize() . = ..() - // BYOND docs fucking lie about New. dir (and other vars) is not initialized by the time this is called - // So the update icon call needs to be delayed - addtimer(CALLBACK(src, .proc/update_icon), 10) - -/obj/structure/interior_wall/update_icon() - ..() - pixel_y = 0 - alpha = 255 + //alpha = 255 layer = ABOVE_OBJ_LAYER switch(dir) @@ -36,5 +29,7 @@ pixel_y = 31 layer = INTERIOR_WALL_NORTH_LAYER if(SOUTH) - alpha = 50 + //alpha = 50 layer = INTERIOR_WALL_SOUTH_LAYER + + update_icon() diff --git a/config/.gitignore b/config/.gitignore index 845f8dbb7f9f..cc6a3e60c983 100644 --- a/config/.gitignore +++ b/config/.gitignore @@ -1,4 +1,6 @@ -#ignore everything here, except subdirectories. -/* -!example/ -!names/ +#ignore everything here, except subdirectories. +/* +!maps.txt +!shipmaps.txt +!example/ +!names/ diff --git a/config/maps.txt b/config/maps.txt new file mode 100644 index 000000000000..25e7980b3b21 --- /dev/null +++ b/config/maps.txt @@ -0,0 +1,44 @@ +This file contains a list of maps for use in map rotation. +#Lines starting with # are ignored. +Lines not inside map blocks are also ignored +Duplicated entries use the latter one. +All whitespace at the start and end of lines is ignored. (including indentation, thats just for show) +Format: +#map [map name] (name of .json file in _maps folder without the .json part) + minplayers [number] (0 or less disables this requirement) + maxplayers [number] (0 or less disables this requirement) + default (The last map with this defined will get all votes of players who have not explicitly voted for a map) + voteweight [number] (How much to count each player vote as, defaults to 1, setting to 0.5 counts each vote as half a vote, 2 as double, etc, Setting to 0 disables the map but allows players to still pick it) + disabled (disables the map) +endmap + +map lv624 + default +endmap + +map bigredv2 +endmap + +map corsat +endmap + +map desert_dam + minplayers 130 +endmap + +map ice_colony_v2 + minplayers 130 + disabled +endmap + +map kutjevo +endmap + +map sorokyne_strata + minplayers 130 +endmap + +map whiskey_outpost_v2 + minplayers 130 + disabled +endmap diff --git a/config/shipmaps.txt b/config/shipmaps.txt new file mode 100644 index 000000000000..ad2b96dab4ac --- /dev/null +++ b/config/shipmaps.txt @@ -0,0 +1,17 @@ +This file contains a list of maps for use in map rotation. +#Lines starting with # are ignored. +Lines not inside map blocks are also ignored +Duplicated entries use the latter one. +All whitespace at the start and end of lines is ignored. (including indentation, thats just for show) +Format: +#map [map name] (name of .json file in _maps folder without the .json part) + minplayers [number] (0 or less disables this requirement) + maxplayers [number] (0 or less disables this requirement) + default (The last map with this defined will get all votes of players who have not explicitly voted for a map) + voteweight [number] (How much to count each player vote as, defaults to 1, setting to 0.5 counts each vote as half a vote, 2 as double, etc, Setting to 0 disables the map but allows players to still pick it) + disabled (disables the map) +endmap + +map almayer + default +endmap diff --git a/dependencies.sh b/dependencies.sh new file mode 100644 index 000000000000..f7b975cfd873 --- /dev/null +++ b/dependencies.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +#Project dependencies file +#Final authority on what's required to fully build the project + +# byond version +export BYOND_MAJOR="513" +export BYOND_MINOR="1527" + +#node version +export NODE_VERSION=12 + +# SpacemanDMM git tag +export SPACEMAN_DMM_VERSION=suite-1.5 diff --git a/icons/mob/hud/actions.dmi b/icons/mob/hud/actions.dmi index 9add72207dcc..c13bbc4b659d 100644 Binary files a/icons/mob/hud/actions.dmi and b/icons/mob/hud/actions.dmi differ diff --git a/insert_maps_in_dme.sh b/insert_maps_in_dme.sh deleted file mode 100644 index e08c5027b3ed..000000000000 --- a/insert_maps_in_dme.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# Default maps which are already included in the dme -# Other exempt maps also go in here. Please include a comment describing why it's exempt if it's not a default map -EXEMPT_MAPS=( - "maps/Z.01.LV624.dmm" - "maps/Z.02.Admin_Level.dmm" - "maps/Z.03.USS_Almayer.dmm" - # Whiskey is broken as fuck right now. - # Remove the line when it's back in working order - "maps/Z.01.Whiskey_Outpost_v2.dmm" -) - -# Include everything but backup files and nightmare inserts -for filename in $(find maps -name '*.dmm' ! -wholename '*/backup/*.dmm' ! -wholename '*/Nightmare/*.dmm'); do - # Skip maps that are already included/exempt from CI - if [[ ${EXEMPT_MAPS[*]} =~ "$filename" ]]; then - continue - fi - - # Insert the includes - echo "#include \"$filename\"" >> ColonialMarinesALPHA.dme -done diff --git a/maps/.gitignore b/maps/.gitignore new file mode 100644 index 000000000000..b0f1dbbc03bb --- /dev/null +++ b/maps/.gitignore @@ -0,0 +1,2 @@ +!*.json +Nightmare/*.json diff --git a/maps/DesertDam.dm b/maps/DesertDam.dm deleted file mode 100644 index 7227621fc0e0..000000000000 --- a/maps/DesertDam.dm +++ /dev/null @@ -1,737 +0,0 @@ -//Base Instance -/area/desert_dam - name = "\improper Desert Dam" - icon_state = "cliff_blocked" - - -/area/ice_colony/surface/requesitions - name = "\improper Surface Requesition Warehouse" - icon_state = "quartstorage" - -//INTERIOR -// areas under rock - -//NorthEastern Lab Section -/area/desert_dam/interior/lab_northeast - name = "\improper Northeastern Lab" - icon_state = "purple" -/area/desert_dam/interior/lab_northeast/east_lab_lobby - name = "\improper East Lab Lobby" - icon_state = "green" -/area/desert_dam/interior/lab_northeast/east_lab_west_hallway - name = "\improper East Lab Western Hallway" - icon_state = "blue" -/area/desert_dam/interior/lab_northeast/east_lab_central_hallway - name = "\improper East Lab Central Hallway" - icon_state = "green" -/area/desert_dam/interior/lab_northeast/east_lab_east_hallway - name = "\improper East Lab East Hallway" - icon_state = "yellow" -/area/desert_dam/interior/lab_northeast/east_lab_workshop - name = "\improper East Lab WorkShop" - icon_state = "ass_line" -/area/desert_dam/interior/lab_northeast/east_lab_storage - name = "\improper East Lab Storage " - icon_state = "storage" -/area/desert_dam/interior/lab_northeast/east_lab_RD_office - name = "\improper East Lab Research Directors Office" - icon_state = "yellow" -/area/desert_dam/interior/lab_northeast/east_lab_maintenence - name = "\improper East Lab Maintenence " - icon_state = "maintcentral" -/area/desert_dam/interior/lab_northeast/east_lab_containment - name = "\improper East Lab Containment" - icon_state = "purple" -/area/desert_dam/interior/lab_northeast/east_lab_RND - name = "\improper East Lab Research and Developement" - icon_state = "purple" -/area/desert_dam/interior/lab_northeast/east_lab_biology - name = "\improper East Lab Biology" - icon_state = "purple" -/area/desert_dam/interior/lab_northeast/east_lab_surgury - name = "\improper East Lab Surgury" - icon_state = "red" -/area/desert_dam/interior/lab_northeast/east_lab_excavation - name = "\improper East Lab Excavation Prep" - icon_state = "blue" -/area/desert_dam/interior/lab_northeast/east_lab_west_entrance - name = "\improper East Lab West Entrance" - icon_state = "purple" -/area/desert_dam/interior/lab_northeast/east_lab_east_entrance - name = "\improper East Lab Entrance" - icon_state = "purple" -/area/desert_dam/interior/lab_northeast/east_lab_security_checkpoint - name = "\improper East Lab Sucurity Checkpoint" - icon_state = "purple" -/area/desert_dam/interior/lab_northeast/east_lab_security_office - name = "\improper East Lab Security Office" - icon_state = "security" -/area/desert_dam/interior/lab_northeast/east_lab_security_armory - name = "\improper East Lab Armory" - icon_state = "armory" -/area/desert_dam/interior/lab_northeast/east_lab_xenobiology - name = "\improper East Lab XenoBiology" - icon_state = "red" - -//Dam Interior -/area/desert_dam/interior/dam_interior/engine_room - name = "\improper Engineering Generator Room" - icon_state = "yellow" -/area/desert_dam/interior/dam_interior/control_room - name = "\improper Engineering Control Room" - icon_state = "red" -/area/desert_dam/interior/dam_interior/smes_main - name = "\improper Engineering Main Substation" - icon_state = "purple" -/area/desert_dam/interior/dam_interior/smes_backup - name = "\improper Engineering Secondary Backup Substration" - icon_state = "green" -/area/desert_dam/interior/dam_interior/engine_east_wing - name = "\improper Engineering East Engine Wing" - icon_state = "blue-red" -/area/desert_dam/interior/dam_interior/engine_west_wing - name = "\improper Engineering West Engine Wing" - icon_state = "yellow" -/area/desert_dam/interior/dam_interior/lobby - name = "\improper Engineering Lobby" - icon_state = "purple" -/area/desert_dam/interior/dam_interior/atmos_storage - name = "\improper Engineering Atmosperic Storage" - icon_state = "purple" -/area/desert_dam/interior/dam_interior/northwestern_tunnel - name = "\improper Engineering Northwestern Tunnel" - icon_state = "green" -/area/desert_dam/interior/dam_interior/north_tunnel - name = "\improper Engineering North Tunnel" - icon_state = "blue-red" -/area/desert_dam/interior/dam_interior/west_tunnel - name = "\improper Engineering West Tunnel" - icon_state = "yellow" -/area/desert_dam/interior/dam_interior/central_tunnel - name = "\improper Engineering Central Tunnel" - icon_state = "red" -/area/desert_dam/interior/dam_interior/south_tunnel - name = "\improper Engineering South Tunnel" - icon_state = "purple" -/area/desert_dam/interior/dam_interior/northeastern_tunnel - name = "\improper Engineering Northeastern Tunnel" - icon_state = "green" -/area/desert_dam/interior/dam_interior/CE_office - name = "\improper Engineering Chief Engineers Office" - icon_state = "yellow" -/area/desert_dam/interior/dam_interior/workshop - name = "\improper Engineering Workshop" - icon_state = "purple" -/area/desert_dam/interior/dam_interior/hanger - name = "\improper Engineering Hanger" - icon_state = "hangar" -/area/desert_dam/interior/dam_interior/hangar_storage - name = "\improper Engineering Hanger Storage" - icon_state = "storage" -/area/desert_dam/interior/dam_interior/auxilary_tool_storage - name = "\improper Engineering Auxilary Tool Storage" - icon_state = "red" -/area/desert_dam/interior/dam_interior/primary_tool_storage - name = "\improper Engineering Primary Tool Storage" - icon_state = "blue" -/area/desert_dam/interior/dam_interior/tech_storage - name = "\improper Engineering Secure Tech Storage" - icon_state = "dark" -/area/desert_dam/interior/dam_interior/break_room - name = "\improper Engineering Break Room" - icon_state = "yellow" -/area/desert_dam/interior/dam_interior/disposals - name = "\improper Engineering Disposals" - icon_state = "disposal" -/area/desert_dam/interior/dam_interior/western_dam_cave - name = "\improper Engineering West Entrace" - icon_state = "red" -/area/desert_dam/interior/dam_interior/office - name = "\improper Engineering Office" - icon_state = "red" -/area/desert_dam/interior/dam_interior - name = "\improper Engineering" - icon_state = "" - -/area/desert_dam/interior/dam_interior/north_tunnel_entrance - name = "\improper Engineering North Tunnel Entrance" - icon_state = "yellow" -/area/desert_dam/interior/dam_interior/east_tunnel_entrance - name = "\improper Engineering East Tunnel Entrance" - icon_state = "yellow" -/area/desert_dam/interior/dam_interior/south_tunnel_entrance - name = "\improper Engineering South Tunnel Entrance" - icon_state = "red" - -/area/desert_dam/interior/caves/northern_caves - name = "\improper Northern Caves" - icon_state = "red" -/area/desert_dam/interior/caves/east_caves - name = "\improper Eastern Caves" - icon_state = "red" - -/area/desert_dam/interior/caves/central_caves - name = "\improper Central Caves" - icon_state = "yellow" -/area/desert_dam/interior/caves/central_caves/entrances/east_tunnel_entrance - name = "\improper Eastern Central Tunnel Entrance" - icon_state = "red" -/area/desert_dam/interior/caves/central_caves/entrances/south_tunnel_entrance - name = "\improper Southern Central Tunnel Entrance" - icon_state = "red" -/area/desert_dam/interior/caves/central_caves/entrances/west_tunnel_entrance - name = "\improper Western Central Tunnel Entrance" - icon_state = "red" - -//BUILDING -//areas not under rock -// ceiling = CEILING_METAL - -//Substations -/area/desert_dam/building/substation - name = "Substation" - icon = 'icons/turf/dam_areas.dmi' - -/area/desert_dam/building/substation/northwest - name = "\improper Command Substation" - icon_state = "northewestern_ss" -/area/desert_dam/building/substation/northeast - name = "\improper Command Substation" - icon_state = "northeastern_ss" -/area/desert_dam/building/substation/east - name = "\improper Command Substation" - icon_state = "eastern_ss" -/area/desert_dam/building/substation/southeast - name = "\improper Command Substation" - icon_state = "southeastern_ss" -/area/desert_dam/building/substation/central - name = "\improper Command Substation" - icon_state = "central_ss" -/area/desert_dam/building/substation/southwest - name = "\improper Command Substation" - icon_state = "southwestern_ss" -/area/desert_dam/building/substation/west - name = "\improper Command Substation" - icon_state = "western_ss" - -//Administration -/area/desert_dam/building/administration/control_room - name = "\improper Administration Landing Control Room" - icon_state = "yellow" -/area/desert_dam/building/administration/lobby - name = "\improper Administration Lobby" - icon_state = "green" -/area/desert_dam/building/administration/hallway - name = "\improper Administration Hallway" - icon_state = "purple" -/area/desert_dam/building/administration/office - name = "\improper Administration Office" - icon_state = "blue-red" -/area/desert_dam/building/administration/overseer_office - name = "\improper Administration Overseers Office" - icon_state = "red" -/area/desert_dam/building/administration/meetingrooom - name = "\improper Administration Meeting Room" - icon_state = "yellow" -/area/desert_dam/building/administration/archives - name = "\improper Administration Archives" - icon_state = "green" - - -//Bar -/area/desert_dam/building/bar/bar - name = "\improper Bar" - icon_state = "yellow" -/area/desert_dam/building/bar/backroom - name = "\improper Bar Backroom" - icon_state = "green" -/area/desert_dam/building/bar/bar_restroom - name = "\improper Bar Restroom" - icon_state = "purple" - - -//Cafe -/area/desert_dam/building/cafeteria/cafeteria - name = "\improper Cafeteria" - icon_state = "yellow" -/area/desert_dam/building/cafeteria/backroom - name = "\improper Cafeteria Backroom" - icon_state = "green" -/area/desert_dam/building/cafeteria/restroom - name = "\improper Cafeteria Restroom" - icon_state = "purple" -/area/desert_dam/building/cafeteria/loading - name = "\improper Cafeteria Loading" - icon_state = "blue-red" -/area/desert_dam/building/cafeteria/cold_room - name = "\improper Cafeteria Coldroom" - icon_state = "red" - - -//Dorms -/area/desert_dam/building/dorms/hallway_northwing - name = "\improper Dormitory North Wing" - icon_state = "yellow" -/area/desert_dam/building/dorms/hallway_westwing - name = "\improper Dormitory West Wing" - icon_state = "green" -/area/desert_dam/building/dorms/hallway_eastwing - name = "\improper Dormitory East Wing" - icon_state = "purple" -/area/desert_dam/building/dorms/restroom - name = "\improper Dormitory Showers" - icon_state = "blue-red" -/area/desert_dam/building/dorms/pool - name = "\improper Dormitory Pool Room" - icon_state = "red" - - -//Medical -/area/desert_dam/building/medical/garage - name = "\improper Medical Garage" - icon_state = "garage" -/area/desert_dam/building/medical/emergency_room - name = "\improper Medical Emergency_Room" - icon_state = "medbay" -/area/desert_dam/building/medical/treatment_room - name = "\improper Medical Treatment Room" - icon_state = "medbay2" -/area/desert_dam/building/medical/lobby - name = "\improper Medical Lobby" - icon_state = "medbay3" -/area/desert_dam/building/medical/chemistry - name = "\improper Medical Pharmacy" - icon_state = "medbay" -/area/desert_dam/building/medical/west_wing_hallway - name = "\improper Medica West Wing " - icon_state = "medbay2" -/area/desert_dam/building/medical/north_wing_hallway - name = "\improper Medical North Wing" - icon_state = "medbay3" -/area/desert_dam/building/medical/east_wing_hallway - name = "\improper Medical East Wing" - icon_state = "medbay" -/area/desert_dam/building/medical/primary_storage - name = "\improper Medical Primary Storage" - icon_state = "red" -/area/desert_dam/building/medical/surgery_room_one - name = "\improper Medical Surgery One" - icon_state = "yellow" -/area/desert_dam/building/medical/surgery_room_two - name = "\improper Medical Surgery Two" - icon_state = "purple" -/area/desert_dam/building/medical/surgury_observation - name = "\improper Medical Surgery Observation" - icon_state = "medbay2" -/area/desert_dam/building/medical/morgue - name = "\improper Medical Morgue" - icon_state = "blue" -/area/desert_dam/building/medical/break_room - name = "\improper Medical Break Room" - icon_state = "medbay" -/area/desert_dam/building/medical/CMO - name = "\improper Medical CMOs Office" - icon_state = "CMO" -/area/desert_dam/building/medical/office1 - name = "\improper Medical Office One" - icon_state = "red" -/area/desert_dam/building/medical/office2 - name = "\improper Medical Office Two" - icon_state = "blue" -/area/desert_dam/building/medical/patient_wing - name = "\improper Medical Patient Wing" - icon_state = "medbay2" -/area/desert_dam/building/medical/virology_wing - name = "\improper Medical Virology Wing" - icon_state = "medbay3" -/area/desert_dam/building/medical/virology_isolation - name = "\improper Medical Virology Isolation" - icon_state = "medbay" -/area/desert_dam/building/medical - name = "\improper Medical" - icon_state = "medbay2" - - -//Warehouse -/area/desert_dam/building/warehouse/warehouse - name = "\improper Warehouse" - icon_state = "yellow" -/area/desert_dam/building/warehouse/loading - name = "\improper Waregouse Loading" - icon_state = "red" -/area/desert_dam/building/warehouse/breakroom - name = "\improper Warehouse Breakroom" - icon_state = "green" - - -//Hydroponics -/area/desert_dam/building/hydroponics/hydroponics - name = "\improper Hydroponics" - icon_state = "hydro" -/area/desert_dam/building/hydroponics/hydroponics_storage - name = "\improper Hydroponics Storage" - icon_state = "green" -/area/desert_dam/building/hydroponics/hydroponics_loading - name = "\improper Hydroponics Loading" - icon_state = "garage" -/area/desert_dam/building/hydroponics/hydroponics_breakroom - name = "\improper Hydroponics Breakroom" - icon_state = "red" - - -//Telecoms -/area/desert_dam/building/telecommunication - name = "\improper Telecommunications" - icon_state = "yellow" - -//Water Treatment Plant 1 -/area/desert_dam/building/water_treatment_one - name = "\improper Water Treatment One" - icon_state = "yellow" -//Water Treatment Plant 1 -/area/desert_dam/building/water_treatment_one/lobby - name = "\improper Water Treatment One Lobby" - icon_state = "red" -/area/desert_dam/building/water_treatment_one/breakroom - name = "\improper Water Treatment One Breakroom" - icon_state = "green" -/area/desert_dam/building/water_treatment_one/garage - name = "\improper Water Treatment One Garage" - icon_state = "garage" -/area/desert_dam/building/water_treatment_one/sedimentation - name = "\improper Water Treatment One Sedimentation" - icon_state = "blue" -/area/desert_dam/building/water_treatment_one/equipment - name = "\improper Water Treatment One Equipment" - icon_state = "red" -/area/desert_dam/building/water_treatment_one/hallway - name = "\improper Water Treatment One Hallway" - icon_state = "purple" -/area/desert_dam/building/water_treatment_one/control_room - name = "\improper Water Treatment One Control Room" - icon_state = "yellow" -/area/desert_dam/building/water_treatment_one/purification - name = "\improper Water Treatment One Purification" - icon_state = "green" -/area/desert_dam/building/water_treatment_one/floodgate_control - name = "\improper Water Treatment One Floodgate Control" - icon_state = "green" - -//Water Treatment Plant 2 -/area/desert_dam/building/water_treatment_two - name = "\improper Water Treatment Two" - icon_state = "yellow" -/area/desert_dam/building/water_treatment_two/lobby - name = "\improper Water Treatment Two Lobby" - icon_state = "red" -/area/desert_dam/building/water_treatment_two/breakroom - name = "\improper Water Treatment Two Breakroom" - icon_state = "green" -/area/desert_dam/building/water_treatment_two/garage - name = "\improper Water Treatment Two Garage" - icon_state = "garage" -/area/desert_dam/building/water_treatment_two/sedimentation - name = "\improper Water Treatment Two Sedimentation" - icon_state = "blue" -/area/desert_dam/building/water_treatment_two/equipment - name = "\improper Water Treatment Two Equipment" - icon_state = "red" -/area/desert_dam/building/water_treatment_two/hallway - name = "\improper Water Treatment Two Hallway" - icon_state = "purple" -/area/desert_dam/building/water_treatment_two/control_room - name = "\improper Water Treatment Two Control Room" - icon_state = "yellow" -/area/desert_dam/building/water_treatment_two/purification - name = "\improper Water Treatment Two Purification" - icon_state = "green" -/area/desert_dam/building/water_treatment_two/floodgate_control - name = "\improper Water Treatment Two Floodgate Control" - icon_state = "green" - - -//Library -/area/desert_dam/building/library/library - name = "\improper Library" - icon_state = "library" -/area/desert_dam/building/library/restroom - name = "\improper Library Restroom" - icon_state = "green" -/area/desert_dam/building/library/studyroom - name = "\improper Library Studyroom" - icon_state = "purple" - - -//Security -/area/desert_dam/building/security/prison - name = "\improper Security Prison" - icon_state = "sec_prison" -/area/desert_dam/building/security/marshals_office - name = "\improper Security Marshals Office" - icon_state = "sec_hos" -/area/desert_dam/building/security/armory - name = "\improper Security Armory" - icon_state = "armory" -/area/desert_dam/building/security/warden - name = "\improper Security Wardens Office" - icon_state = "Warden" -/area/desert_dam/building/security/interrogation - name = "\improper Security Interrogation" - icon_state = "interrogation" -/area/desert_dam/building/security/backroom - name = "\improper Security Interrogation" - icon_state = "sec_backroom" -/area/desert_dam/building/security/observation - name = "\improper Security Observation" - icon_state = "observatory" -/area/desert_dam/building/security/detective - name = "\improper Security Detectives Office" - icon_state = "detective" -/area/desert_dam/building/security/office - name = "\improper Security Office" - icon_state = "yellow" -/area/desert_dam/building/security/lobby - name = "\improper Security Lobby" - icon_state = "green" -/area/desert_dam/building/security/northern_hallway - name = "\improper Security North Hallway" - icon_state = "purple" -/area/desert_dam/building/security/courtroom - name = "\improper Security Courtroom" - icon_state = "courtroom" -/area/desert_dam/building/security/evidence - name = "\improper Security Evidence" - icon_state = "red" -/area/desert_dam/building/security/holding - name = "\improper Security Holding" - icon_state = "yellow" -/area/desert_dam/building/security/southern_hallway - name = "\improper Security SouthHallway" - icon_state = "green" -/area/desert_dam/building/security/deathrow - name = "\improper Security Death Row" - icon_state = "cells_max_n" -/area/desert_dam/building/security/execution_chamber - name = "\improper Security Execution Chamber" - icon_state = "red" -/area/desert_dam/building/security/staffroom - name = "\improper Security Staff Room" - icon_state = "security" - -//Church -/area/desert_dam/building/church - name = "\improper Churh" - icon_state = "courtroom" - - -//Mining area -/area/desert_dam/building/mining/garage - name = "\improper Mining Garage" - icon_state = "garage" -/area/desert_dam/building/mining/boxing_room - name = "\improper Mining Boxing Room" - icon_state = "red" -/area/desert_dam/building/mining/loading_room - name = "\improper Mining Loading Bay" - icon_state = "yellow" -/area/desert_dam/building/mining/break_room - name = "\improper Mining Break Room" - icon_state = "purple" -/area/desert_dam/building/mining/locker_room - name = "\improper Mining Locker Room" - icon_state = "green" -/area/desert_dam/building/mining/lobby - name = "\improper Mining Lobby" - icon_state = "red" -/area/desert_dam/building/mining/front_desk - name = "\improper Mining Front Desk" - icon_state = "green" -/area/desert_dam/building/mining/foremans_office - name = "\improper Mining Foremans Office" - icon_state = "yellow" -/area/desert_dam/building/mining/maintenance_north - name = "\improper Mining Maintenance North" - icon_state = "dark160" -/area/desert_dam/building/mining/maintenance_east - name = "\improper Mining Maintenance East" - icon_state = "dark128" -/area/desert_dam/building/mining/workshop - name = "\improper Mining Workshop" - icon_state = "yellow" -/area/desert_dam/building/mining/workshop_foyer - name = "\improper Mining Workshop Foyer" - icon_state = "purple" -/area/desert_dam/building/mining/bunkhouse - name = "\improper Mining Bunkhouse" - icon_state = "red" -/area/desert_dam/building/mining/construction_site - name = "\improper Construction Site" - icon_state = "yellow" - - -//NorthWest Lab Buildings -/area/desert_dam/building/lab_northwest/west_lab_robotics - name = "\improper West Lab Robotics" - icon_state = "ass_line" -/area/desert_dam/building/lab_northwest/west_lab_robotics_mechbay - name = "\improper West Lab Mechbay" - icon_state = "purple" -/area/desert_dam/building/lab_northwest/west_lab_east_hallway - name = "\improper West Lab Hallway" - icon_state = "red" -/area/desert_dam/building/lab_northwest/west_lab_west_hallway - name = "\improper West Lab Hallway" - icon_state = "red" -/area/desert_dam/building/lab_northwest/west_lab_maintenance - name = "\improper West Lab Maintenence" - icon_state = "purple" -/area/desert_dam/building/lab_northwest/west_lab_chemistry - name = "\improper West Lab Chemistry" - icon_state = "yellow" -/area/desert_dam/building/lab_northwest/west_lab_cafeteria - name = "\improper West Lab Cafeteria" - icon_state = "blue" -/area/desert_dam/building/lab_northwest/west_lab_kitchen - name = "\improper West Lab Kitchen" - icon_state = "kitchen" -/area/desert_dam/building/lab_northwest/west_lab_dormitory - name = "\improper West Lab Dormitory" - icon_state = "red" -/area/desert_dam/building/lab_northwest/west_lab_meeting_room - name = "\improper West Lab Meeting Room" - icon_state = "purple" -/area/desert_dam/building/lab_northwest/west_lab_xenoflora - name = "\improper West Lab Xenoflora" - icon_state = "purple" - -/area/desert_dam/building/lab_northeast/checkpoint - name = "\improper East Lab Checkpoint" - icon_state = "red" -/area/desert_dam/building/lab_northeast/garage - name = "\improper East Lab Garage" - icon_state = "garage" - - -//EXTERIOR -//under open sky -/area/desert_dam/exterior - requires_power = 1 - always_unpowered = 1 - lighting_use_dynamic = 1 - power_light = FALSE - power_equip = FALSE - power_environ = FALSE - -/area/desert_dam/exterior/rock - name = "\improper Rock" - icon_state = "cave" - -//Landing Pad for the Alamo. THIS IS NOT THE SHUTTLE AREA -/area/desert_dam/exterior/landing_pad_one - name = "\improper Airstrip Landing Pad" - icon_state = "landing_pad" -/area/desert_dam/exterior/landing_pad_one_external - name = "\improper Airstrip Landing Valley" - icon_state = "landing_pad_ext" - - -//Landing Pad for the Normandy. THIS IS NOT THE SHUTTLE AREA -/area/desert_dam/exterior/landing_pad_two - name = "\improper Aerodrome Landing Pad" - icon_state = "landing_pad" -/area/desert_dam/exterior/landing_pad_two_external - name = "\improper Aerodrome Landing Valley" - icon_state = "landing_pad_ext" - -//Valleys -//TODO: incorporate valleys and substrations for floodlight coverage - -/area/desert_dam/exterior/valley -/area/desert_dam/exterior/valley/valley_northwest - name = "\improper Northwest Valley" - icon_state = "valley_north_west" -/area/desert_dam/exterior/valley/valley_labs - name = "\improper Lab Valley" - icon_state = "valley_north" -/area/desert_dam/exterior/valley/valley_mining - name = "\improper Mining Valley" - icon_state = "valley_east" -/area/desert_dam/exterior/valley/valley_civilian - name = "\improper" - icon_state = "valley_south_excv" -/area/desert_dam/exterior/valley/valley_medical - name = "\improper Medical Valley" - icon_state = "valley" -/area/desert_dam/exterior/valley/valley_cargo - name = "\improper Shipping Valley" - icon_state = "valley_south_west" -/area/desert_dam/exterior/valley/valley_telecoms - name = "\improper Telecoms Valley" - icon_state = "valley_west" -/area/desert_dam/exterior/valley/valley_crashsite - name = "\improper Crashsite Valley" - icon_state = "yellow" -/area/desert_dam/exterior/valley/valley_dam - name = "\improper Dam Valley" - icon_state = "valley" -/area/desert_dam/exterior/valley/valley_wilderness - name = "\improper Wilderness Valley" - icon_state = "central" - - - - - -//End of the river areas, no Next -/area/desert_dam/exterior/river/riverside_northwest - name = "\improper Northwest riverbed" - icon_state = "bluenew" - -/area/desert_dam/exterior/river/riverside_central_north - name = "\improper Northern central riverbed" - icon_state = "purple" -/area/desert_dam/exterior/river/riverside_central_south - name = "\improper Southern central riverbed" - icon_state = "purple" - -/area/desert_dam/exterior/river/riverside_south - name = "\improper Southern riverbed" - icon_state = "bluenew" -/area/desert_dam/exterior/river/riverside_east - name = "\improper Eastern riverbed" - icon_state = "bluenew" -/area/desert_dam/exterior/river/riverside_northeast - name = "\improper Northeastern riverbed" - icon_state = "bluenew" -//The filtration plants - This area isn't for the WHOLE plant, but the areas that have water in them, so the water changes color as well. - -/area/desert_dam/exterior/river/filtration_a - name = "\improper Filtration Plant A" - -/area/desert_dam/exterior/river/filtration_b - name = "\improper Filtration Plant B" - -//Areas that are rivers, but will not change because they're before the floodgates -/area/desert_dam/exterior/river_mouth/southern - name = "\improper southern river mouth" - icon_state = "purple" - -/area/desert_dam/exterior/river_mouth/eastern - name = "\improper eastern river mouth" - icon_state = "purple" - - -//Transit Shuttle -/area/shuttle/tri_trans1/alpha - icon_state = "shuttle" -/area/shuttle/tri_trans1/away - icon_state = "away1" -/area/shuttle/tri_trans1/omega - icon_state = "shuttle2" - -/area/shuttle/tri_trans2/alpha - icon_state = "shuttlered" -/area/shuttle/tri_trans2/away - icon_state = "away2" -/area/shuttle/tri_trans2/omega - icon_state = "shuttle2" \ No newline at end of file diff --git a/maps/Nightmare/Z.01.Corsat/lockdown_gammacontrol.dmm b/maps/Nightmare/Z.01.Corsat/lockdown_gammacontrol.dmm index a06a0b7e31a9..75c0cdfdc87b 100644 --- a/maps/Nightmare/Z.01.Corsat/lockdown_gammacontrol.dmm +++ b/maps/Nightmare/Z.01.Corsat/lockdown_gammacontrol.dmm @@ -76,7 +76,7 @@ }, /area/corsat/gamma/airlock/control) "m" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "GammaWestD"; name = "Gamma Dome Airlock"; unacidable = 0; diff --git a/maps/Nightmare/Z.01.Corsat/lockdown_highsec.dmm b/maps/Nightmare/Z.01.Corsat/lockdown_highsec.dmm index 0ce1ce8169f5..df4f5fd259cf 100644 --- a/maps/Nightmare/Z.01.Corsat/lockdown_highsec.dmm +++ b/maps/Nightmare/Z.01.Corsat/lockdown_highsec.dmm @@ -6,7 +6,7 @@ /turf/closed/wall/r_wall/biodome/biodome_unmeltable, /area/corsat/omega/checkpoint) "c" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/secure/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/secure/opened{ id = "delta_gamma2"; name = "Gamma Checkpoint"; use_power = 0 diff --git a/maps/Nightmare/Z.01.Corsat/lockdown_thetaeast.dmm b/maps/Nightmare/Z.01.Corsat/lockdown_thetaeast.dmm index 4530afff078a..f44a5f1cebc1 100644 --- a/maps/Nightmare/Z.01.Corsat/lockdown_thetaeast.dmm +++ b/maps/Nightmare/Z.01.Corsat/lockdown_thetaeast.dmm @@ -52,7 +52,7 @@ }, /area/corsat/theta/airlock/east) "k" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "ThetaEastW"; name = "Theta East Airlock"; unacidable = 0; @@ -64,7 +64,7 @@ /area/corsat/theta/airlock/east) "l" = ( /obj/structure/pipes/vents/pump{ - dir = 1 + dir = 1 }, /turf/open/floor/corsat{ icon_state = "plate" diff --git a/maps/Nightmare/Z.01.Corsat/sigma_ice.dmm b/maps/Nightmare/Z.01.Corsat/sigma_ice.dmm index 46698fc3a42a..969ed0614d83 100644 --- a/maps/Nightmare/Z.01.Corsat/sigma_ice.dmm +++ b/maps/Nightmare/Z.01.Corsat/sigma_ice.dmm @@ -3256,7 +3256,7 @@ /turf/closed/wall/r_wall/biodome/biodome_unmeltable, /area/corsat/emergency_access) "Yf" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "SigmaWestW"; name = "Sigma West Airlock" }, @@ -3286,7 +3286,7 @@ }, /area/corsat/sigma/airlock/control) "Yu" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "SigmaWestE"; name = "Sigma West Airlock" }, diff --git a/maps/Nightmare/Z.01.LV624/hydro_original.dmm b/maps/Nightmare/Z.01.LV624/hydro_original.dmm index 5c8c8a71bf3b..2af8255c3a41 100644 --- a/maps/Nightmare/Z.01.LV624/hydro_original.dmm +++ b/maps/Nightmare/Z.01.LV624/hydro_original.dmm @@ -85,7 +85,6 @@ /area/lv624/lazarus/hydroponics) "of" = ( /obj/structure/surface/table, -/obj/item/clothing/suit/apron/overalls, /obj/item/clothing/under/colonist, /turf/open/floor{ dir = 5; diff --git a/maps/Nightmare/Z.01.LV624/hydro_overgrown.dmm b/maps/Nightmare/Z.01.LV624/hydro_overgrown.dmm index a7927645fdd6..3c9d98977690 100644 --- a/maps/Nightmare/Z.01.LV624/hydro_overgrown.dmm +++ b/maps/Nightmare/Z.01.LV624/hydro_overgrown.dmm @@ -339,7 +339,6 @@ /area/lv624/lazarus/hydroponics) "aol" = ( /obj/structure/surface/table, -/obj/item/clothing/suit/apron/overalls, /obj/item/clothing/under/colonist, /obj/structure/flora/jungle/vines/heavy{ icon_state = "heavy_6"; diff --git a/maps/Nightmare/Z.01.Prison_Station_FOP/brig_original.dmm b/maps/Nightmare/Z.01.Prison_Station_FOP/brig_original.dmm index a31712d58a5c..7ca44b7120c4 100644 --- a/maps/Nightmare/Z.01.Prison_Station_FOP/brig_original.dmm +++ b/maps/Nightmare/Z.01.Prison_Station_FOP/brig_original.dmm @@ -1577,10 +1577,7 @@ /turf/open/floor/plating, /area/prison/engineering/atmos) "bWo" = ( -/obj/structure/pipes/binary/pump/high_power{ - on = 1; - - }, +/obj/structure/pipes/binary/pump/high_power/on, /turf/open/floor/plating, /area/prison/engineering/atmos) "bWp" = ( @@ -3046,7 +3043,7 @@ /turf/closed/wall/r_wall/prison, /area/prison/execution) "cfE" = ( -/obj/structure/machinery/door/poddoor/two_tile/open{ +/obj/structure/machinery/door/poddoor/two_tile/opened{ id = "execution"; unacidable = 0 }, @@ -3605,7 +3602,8 @@ /area/prison/security/armory/riot) "cjl" = ( /obj/structure/machinery/door/poddoor/two_tile/vertical/open{ - id = "lethal_armory"unacidable = 0 + id = "lethal_armory"; + unacidable = 0 }, /turf/open/floor/prison{ tag = "icon-darkredfull2 (SOUTHWEST)"; diff --git a/maps/Nightmare/Z.01.Prison_Station_FOP/crashedship_original.dmm b/maps/Nightmare/Z.01.Prison_Station_FOP/crashedship_original.dmm index 032a0065b07a..37eb038aebaa 100644 --- a/maps/Nightmare/Z.01.Prison_Station_FOP/crashedship_original.dmm +++ b/maps/Nightmare/Z.01.Prison_Station_FOP/crashedship_original.dmm @@ -1890,7 +1890,7 @@ /turf/closed/wall/sulaco/unmeltable, /area/prison/pirate) "dy" = ( -/obj/structure/machinery/door/poddoor/two_tile/open{ +/obj/structure/machinery/door/poddoor/two_tile/opened{ id = "pirate_cargo"; name = "Rocinante Cargo Bay Door"; unacidable = 0 @@ -1907,7 +1907,7 @@ }, /area/prison/pirate) "dA" = ( -/obj/structure/machinery/door/poddoor/two_tile/open{ +/obj/structure/machinery/door/poddoor/two_tile/opened{ id = "pirate_cargo"; name = "Rocinante Cargo Bay Door"; unacidable = 0 @@ -4179,8 +4179,7 @@ /area/prison/pirate) "ic" = ( /obj/structure/pipes/standard/tank/carbon_dioxide{ - dir = 8; - start_pressure = 435 + dir = 8 }, /turf/open/floor/plating{ icon_plating = "platebot"; @@ -4623,9 +4622,7 @@ /area/prison/pirate) "iV" = ( /obj/structure/pipes/standard/tank/phoron{ - dir = 1; - start_pressure = 0; - volume = 0 + dir = 1 }, /turf/open/floor/plating{ icon_plating = "platebot"; diff --git a/maps/Nightmare/config/compression.cfg b/maps/Nightmare/config/compression.cfg index 4127cd968ac2..e9a7c1cb6cb3 100644 --- a/maps/Nightmare/config/compression.cfg +++ b/maps/Nightmare/config/compression.cfg @@ -1,6 +1,6 @@ -log -format ByondDefault --newcmd compress-map 1 "-target Z.01.##1.dmm -save Z.01.##1_tocompile.dmm" +-newcmd compress-map 1 "-target map_files\##1\##1.dmm -save ##1_tocompile.dmm" -cmd-compress-map BigRed_v2 -cmd-compress-map Corsat diff --git a/maps/_basemap.dm b/maps/_basemap.dm new file mode 100644 index 000000000000..4668bf8e5b01 --- /dev/null +++ b/maps/_basemap.dm @@ -0,0 +1,22 @@ +//#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. + +#include "map_files\generic\Admin_level.dmm" +#include "map_files\generic\Low_Orbit.dmm" + +#ifndef LOWMEMORYMODE + #ifdef ALL_MAPS + #include "map_files\BigRed_v2\BigRed_v2.dmm" + #include "map_files\Corsat\Corsat.dmm" + #include "map_files\Desert_Dam\Desert_Dam.dmm" + #include "map_files\Ice_Colony_v2\Ice_Colony_v2.dmm" + #include "map_files\Kutjevo\Kutjevo.dmm" + #include "map_files\LV624\LV624.dmm" + #include "map_files\Prison_Station_FOP\Prison_Station_FOP.dmm" + #include "map_files\Sorokyne_Strata\Sorokyne_Strata.dmm" + #include "map_files\USS_Almayer\USS_Almayer.dmm" + #include "map_files\Whiskey_Outpost_v2\Whiskey_Outpost_v2.dmm" + #ifdef CIBUILDING + #include "templates.dm" + #endif + #endif +#endif diff --git a/maps/almayer.json b/maps/almayer.json new file mode 100644 index 000000000000..ca2045e2bca8 --- /dev/null +++ b/maps/almayer.json @@ -0,0 +1,6 @@ +{ + "map_name": "USS Almayer", + "map_path": "map_files/USS_Almayer", + "map_file": "USS_Almayer.dmm", + "traits": [{"Marine Main Ship": true}] +} diff --git a/maps/bigredv2.json b/maps/bigredv2.json new file mode 100644 index 000000000000..4c4a29695114 --- /dev/null +++ b/maps/bigredv2.json @@ -0,0 +1,28 @@ +{ + "map_name": "Solaris Ridge", + "map_path": "map_files/BigRed_v2", + "map_file": "BigRed_v2.dmm", + "survivor_types": [ + "Survivor - Scientist", + "Survivor - Doctor", + "Survivor - Chef", + "Survivor - Chaplain", + "Survivor - Miner", + "Survivor - Engineer", + "Survivor - Trucker", + "Survivor - Colonial Marshall" + ], + "defcon_triggers": [ + 4750, + 3500, + 2000, + 1000, + 0.0 + ], + "map_item_type": "/obj/item/map/big_red_map", + "announce_text": "We've lost contact with the Weston-Yamada's research facility, Solaris Ridge. The ###SHIPNAME### has been dispatched to assist.", + "monkey_types": [ + "neaera" + ], + "traits": [{ "Ground": true }] +} diff --git a/maps/corsat.json b/maps/corsat.json new file mode 100644 index 000000000000..bfdbcb7775d7 --- /dev/null +++ b/maps/corsat.json @@ -0,0 +1,36 @@ +{ + "map_name": "CORSAT", + "map_path": "map_files/Corsat", + "map_file": "Corsat.dmm", + "environment_traits": { + "Lockdown": true, + "COLD": true + }, + "survivor_types": [ + "Survivor - Scientist", + "Survivor - Scientist", + "Survivor - Scientist", + "Survivor - Doctor", + "Survivor - Security", + "Survivor - Corporate Liaison", + "Survivor - Engineer" + ], + "defcon_triggers": [ + 3300, + 2100, + 1450, + 580, + 0.0 + ], + "survivor_message": "You are a survivor of the containment breach on the Corporate Orbital Research Station for Advanced Technology (CORSAT). You worked or lived on the station, and managed to avoid the alien attacks... until now.", + "map_item_type": "/obj/item/map/corsat", + "announce_text": "An automated distress signal has been received from Weston-Yamada's Corporate Orbital Research Station for Advanced Technology, or CORSAT. The ###SHIPNAME### has been dispatched to investigate.", + "monkey_types": [ + "yiren", + "farwa", + "monkey", + "neaera", + "stok" + ], + "traits": [{ "Ground": true }] +} diff --git a/maps/desert_dam.json b/maps/desert_dam.json new file mode 100644 index 000000000000..518cbfc8b0be --- /dev/null +++ b/maps/desert_dam.json @@ -0,0 +1,28 @@ +{ + "map_name": "Trijent Dam", + "map_path": "map_files/Desert_Dam", + "map_file": "Desert_Dam.dmm", + "survivor_types": [ + "Survivor - Scientist", + "Survivor - Doctor", + "Survivor - Chef", + "Survivor - Chaplain", + "Survivor - Miner", + "Survivor - Engineer", + "Survivor - Trucker", + "Survivor - Colonial Marshall" + ], + "defcon_triggers": [ + 3300, + 2100, + 1450, + 580, + 0.0 + ], + "map_item_type": "/obj/item/map/desert_dam", + "announce_text": "We've lost contact with Weston-Yamada's extra-solar colony, \"Trijent Dam\", on the planet \"Navarone.\" The ###SHIPNAME### has been dispatched to assist.", + "monkey_types": [ + "stok" + ], + "traits": [{ "Ground": true }] +} diff --git a/maps/ice_colony_v2.json b/maps/ice_colony_v2.json new file mode 100644 index 000000000000..f907d04c7222 --- /dev/null +++ b/maps/ice_colony_v2.json @@ -0,0 +1,29 @@ +{ + "map_name": "Ice Colony", + "map_path": "map_files/Ice_Colony_v2", + "map_file": "Ice_Colony_v2.dmm", + "environment_traits": { + "COLD": true + }, + "survivor_types": [ + "Survivor - Scientist", + "Survivor - Doctor", + "Survivor - Security", + "Survivor - Trucker", + "Survivor - Engineer" + ], + "defcon_triggers": [ + 3300, + 2100, + 1450, + 580, + 0.0 + ], + "survivor_message": "You are a survivor of the attack on the ice habitat. You worked or lived on the colony, and managed to avoid the alien attacks... until now.", + "map_item_type": "/obj/item/map/ice_colony_map", + "announce_text": "An automated distress signal has been received from archaeology site \"Shiva's Snowball\", on border ice world \"Ifrit\". A response team from the ###SHIPNAME### will be dispatched shortly to investigate.", + "monkey_types": [ + "yiren" + ], + "traits": [{ "Ground": true }] +} diff --git a/maps/interiors/apc.dmm b/maps/interiors/apc.dmm index d8922e6d6ee3..55b9338a87e1 100644 --- a/maps/interiors/apc.dmm +++ b/maps/interiors/apc.dmm @@ -10,7 +10,7 @@ /obj/structure/interior_wall/apc{ dir = 1; icon_state = "apc_left_1"; - pixel_y = 32 + pixel_y = 31 }, /obj/effect/landmark/interior/spawn/interior_viewport{ pixel_y = 28 @@ -27,7 +27,7 @@ /obj/structure/interior_wall/apc{ dir = 1; icon_state = "apc_left_2"; - pixel_y = 32 + pixel_y = 31 }, /obj/effect/landmark/interior/spawn/interior_viewport{ pixel_y = 28 @@ -46,7 +46,7 @@ /obj/structure/interior_wall/apc{ dir = 1; icon_state = "apc_left_3"; - pixel_y = 32 + pixel_y = 31 }, /turf/open/shuttle/dropship{ tag = "icon-rasputin3"; @@ -61,7 +61,7 @@ /obj/structure/interior_wall/apc{ dir = 1; icon_state = "apc_left_4"; - pixel_y = 32 + pixel_y = 31 }, /obj/effect/landmark/interior/spawn/vehicle_gunner_seat{ icon_state = "comfychair"; @@ -106,7 +106,7 @@ icon_state = "apc_back_1" }, /obj/structure/interior_wall/apc{ - alpha = 100; + alpha = 50; icon_state = "apc_right_1" }, /obj/effect/landmark/interior/spawn/interior_viewport{ @@ -129,7 +129,7 @@ dir = 1 }, /obj/structure/interior_wall/apc{ - alpha = 100; + alpha = 50; icon_state = "apc_right_2" }, /obj/effect/landmark/interior/spawn/interior_viewport{ @@ -147,7 +147,7 @@ tag = "right" }, /obj/structure/interior_wall/apc{ - alpha = 100; + alpha = 50; icon_state = "apc_right_3" }, /turf/open/shuttle/dropship{ @@ -163,7 +163,7 @@ /area/vehicle/apc) "l" = ( /obj/structure/interior_wall/apc{ - alpha = 100; + alpha = 50; icon_state = "apc_right_4" }, /obj/structure/interior_wall/apc{ diff --git a/maps/interiors/apc_command.dmm b/maps/interiors/apc_command.dmm index 92ba338d3f5e..4e9bcde08a0c 100644 --- a/maps/interiors/apc_command.dmm +++ b/maps/interiors/apc_command.dmm @@ -42,11 +42,10 @@ tag = "left" }, /obj/structure/interior_wall/apc{ - alpha = 255; + alpha = 50; dir = 1; icon_state = "apc_right_3"; - layer = 4; - pixel_y = 31 + layer = 4 }, /turf/open/shuttle/dropship{ icon_state = "rasputin3" diff --git a/maps/interiors/apc_med.dmm b/maps/interiors/apc_med.dmm index 60e08b5d8f64..52dbb3e7381a 100644 --- a/maps/interiors/apc_med.dmm +++ b/maps/interiors/apc_med.dmm @@ -3,7 +3,7 @@ /obj/structure/interior_wall/apc{ dir = 1; icon_state = "apc_left_1"; - pixel_y = 32 + pixel_y = 31 }, /obj/structure/interior_wall/apc{ dir = 8; @@ -21,7 +21,7 @@ /obj/structure/interior_wall/apc{ dir = 1; icon_state = "apc_left_2"; - pixel_y = 32 + pixel_y = 31 }, /obj/structure/machinery/body_scanconsole, /obj/structure/barricade/handrail{ @@ -48,7 +48,7 @@ /obj/structure/interior_wall/apc{ dir = 1; icon_state = "apc_left_3"; - pixel_y = 32 + pixel_y = 31 }, /turf/open/shuttle/dropship{ tag = "icon-rasputin3"; @@ -63,7 +63,7 @@ /obj/structure/interior_wall/apc{ dir = 1; icon_state = "apc_left_4"; - pixel_y = 32 + pixel_y = 31 }, /obj/effect/landmark/interior/spawn/vehicle_gunner_seat{ icon_state = "comfychair"; @@ -125,7 +125,7 @@ icon_state = "apc_back_1" }, /obj/structure/interior_wall/apc{ - alpha = 100; + alpha = 50; icon_state = "apc_right_1" }, /obj/structure/machinery/optable, @@ -137,7 +137,7 @@ /area/vehicle/apc) "j" = ( /obj/structure/interior_wall/apc{ - alpha = 100; + alpha = 50; icon_state = "apc_right_2" }, /obj/structure/barricade/handrail{ @@ -159,7 +159,7 @@ tag = "right" }, /obj/structure/interior_wall/apc{ - alpha = 100; + alpha = 50; icon_state = "apc_right_3" }, /turf/open/shuttle/dropship{ @@ -169,7 +169,7 @@ /area/vehicle/apc) "l" = ( /obj/structure/interior_wall/apc{ - alpha = 100; + alpha = 50; icon_state = "apc_right_4" }, /obj/structure/interior_wall/apc{ diff --git a/maps/interiors/van.dmm b/maps/interiors/van.dmm index 2fabeb46011b..cb46ffc7bae3 100644 --- a/maps/interiors/van.dmm +++ b/maps/interiors/van.dmm @@ -9,7 +9,7 @@ dir = 1; icon_state = "van_left_1"; layer = 2; - pixel_y = 30 + pixel_y = 31 }, /obj/effect/landmark/interior/spawn/entrance{ dir = 8; @@ -28,7 +28,7 @@ dir = 1; icon_state = "van_left_2"; layer = 2; - pixel_y = 30 + pixel_y = 31 }, /obj/effect/landmark/interior/spawn/interior_viewport{ pixel_y = 29 @@ -48,7 +48,11 @@ dir = 8; icon_state = "van_back_2" }, -/obj/structure/interior_wall/van, +/obj/structure/interior_wall/van{ + alpha = 50; + icon_state = "van_right_1"; + layer = 4 + }, /obj/effect/landmark/interior/spawn/entrance{ dir = 8; exit_type = /obj/structure/interior_exit/vehicle/van/backright; @@ -85,7 +89,7 @@ dir = 1; icon_state = "van_left_2"; layer = 2; - pixel_y = 30 + pixel_y = 31 }, /turf/open/shuttle/dropship{ icon_state = "rasputin14"; @@ -100,7 +104,7 @@ dir = 1; icon_state = "van_left_3"; layer = 2; - pixel_y = 30 + pixel_y = 31 }, /obj/structure/interior_wall/van{ dir = 4; diff --git a/maps/kutjevo.json b/maps/kutjevo.json new file mode 100644 index 000000000000..89bf6394c3ca --- /dev/null +++ b/maps/kutjevo.json @@ -0,0 +1,29 @@ +{ + "map_name": "Kutjevo Refinery", + "map_path": "map_files/Kutjevo", + "map_file": "Kutjevo.dmm", + "survivor_types": [ + "Survivor - Scientist", + "Survivor - Doctor", + "Survivor - Chef", + "Survivor - Chaplain", + "Survivor - Miner", + "Survivor - Engineer", + "Survivor - Trucker", + "Survivor - Colonial Marshall" + ], + "defcon_triggers": [ + 4250, + 2950, + 1650, + 1000, + 0.0 + ], + "map_item_type": "/obj/item/map/kutjevo_map", + "announce_text": "An automated distress signal has been received from Weston-Yamada colony Kutjevo Refinery, known for botanical research, export, and raw materials processing and refinement. The ###SHIPNAME### has been dispatched to investigate.", + "monkey_types": [ + "neaera", + "stok" + ], + "traits": [{ "Ground": true }] +} diff --git a/maps/lv624.json b/maps/lv624.json new file mode 100644 index 000000000000..40460d861b4d --- /dev/null +++ b/maps/lv624.json @@ -0,0 +1,25 @@ +{ + "map_name": "LV-624", + "map_path": "map_files/LV624", + "map_file": "LV624.dmm", + "survivor_types": [ + "Survivor - Scientist", + "Survivor - Doctor", + "Survivor - Chef", + "Survivor - Chaplain", + "Survivor - Miner", + "Survivor - Engineer", + "Survivor - Trucker", + "Survivor - Colonial Marshall" + ], + "map_item_type": "/obj/item/map/lazarus_landing_map", + "announce_text": "An automated distress signal has been received from archaeology site Lazarus Landing, on border world LV-624. A response team from the ###SHIPNAME### will be dispatched shortly to investigate.", + "monkey_types": [ + "farwa", + "monkey", + "neaera", + "stok" + ], + "environment_traits": { "Fog": true }, + "traits": [{ "Ground": true }] +} diff --git a/maps/Z.01.BigRed_v2.dmm b/maps/map_files/BigRed_v2/BigRed_v2.dmm similarity index 99% rename from maps/Z.01.BigRed_v2.dmm rename to maps/map_files/BigRed_v2/BigRed_v2.dmm index 5747b759ee57..ed6c36af89f0 100644 --- a/maps/Z.01.BigRed_v2.dmm +++ b/maps/map_files/BigRed_v2/BigRed_v2.dmm @@ -9,9 +9,6 @@ }, /area/space) "aac" = ( -/obj/effect/landmark/map_tag{ - name = "Solaris Ridge" - }, /turf/closed/wall/solaris/rock, /area/bigredv2/caves) "aad" = ( diff --git a/maps/Z.01.Corsat.dmm b/maps/map_files/Corsat/Corsat.dmm similarity index 99% rename from maps/Z.01.Corsat.dmm rename to maps/map_files/Corsat/Corsat.dmm index 32cddb4a4e67..19e8eb78154c 100644 --- a/maps/Z.01.Corsat.dmm +++ b/maps/map_files/Corsat/Corsat.dmm @@ -20064,7 +20064,7 @@ }, /area/corsat/omega/hangar/security) "baj" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "OmegaHangarNE"; name = "Landing Bay Omega" }, @@ -20627,7 +20627,7 @@ }, /area/corsat/theta/airlock/west) "bbt" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "ThetaEastW"; name = "Theta East Airlock" }, @@ -20641,7 +20641,7 @@ }, /area/corsat/theta/airlock/east) "bbu" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "ThetaEastE"; name = "Theta East Airlock" }, @@ -37677,7 +37677,7 @@ }, /area/corsat/sigma/airlock/control) "caM" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "SigmaWestE"; name = "Sigma West Airlock" }, @@ -45162,7 +45162,7 @@ }, /area/corsat/omega/security) "hlM" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "SigmaWestW"; name = "Sigma West Airlock" }, @@ -46374,7 +46374,7 @@ }, /area/corsat/omega/maint) "hVF" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "ThetaWestW"; name = "Theta West Airlock" }, @@ -55568,7 +55568,7 @@ }, /area/corsat/gamma/rnr/arcade) "oGf" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "ThetaWestE"; name = "Theta West Airlock" }, @@ -56734,7 +56734,7 @@ }, /area/corsat/omega/hangar/security) "pzH" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "SigmaWestD"; name = "Sigma Dome Airlock" }, @@ -60398,7 +60398,7 @@ /turf/open/auto_turf/snow/layer0, /area/corsat/gamma/biodome) "sdm" = ( -/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/open{ +/obj/structure/machinery/door/poddoor/two_tile/four_tile/vertical/opened{ id = "GammaWestD"; name = "Gamma Dome Airlock" }, @@ -68954,9 +68954,6 @@ }, /area/corsat/theta/biodome) "ylo" = ( -/obj/effect/landmark/map_tag{ - name = "CORSAT" - }, /turf/open/space, /area/space) "ylS" = ( diff --git a/maps/Z.01.Desert_Dam.dmm b/maps/map_files/Desert_Dam/Desert_Dam.dmm similarity index 99% rename from maps/Z.01.Desert_Dam.dmm rename to maps/map_files/Desert_Dam/Desert_Dam.dmm index 606a14f53095..7b4ad33959a6 100644 --- a/maps/Z.01.Desert_Dam.dmm +++ b/maps/map_files/Desert_Dam/Desert_Dam.dmm @@ -11,9 +11,6 @@ /turf/open/gm/river/desert/deep, /area/desert_dam/exterior/river/riverside_central_north) "aac" = ( -/obj/effect/landmark/map_tag{ - name = "Trijent Dam" - }, /turf/closed/shuttle{ dir = 1; icon_state = "pwall" diff --git a/maps/Z.01.Ice_Colony_v2.dmm b/maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm similarity index 99% rename from maps/Z.01.Ice_Colony_v2.dmm rename to maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm index 40ff239eae72..d7be7f3e9491 100644 --- a/maps/Z.01.Ice_Colony_v2.dmm +++ b/maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm @@ -682,9 +682,6 @@ /turf/closed/wall/r_wall, /area/ice_colony/surface/engineering/electric) "acA" = ( -/obj/effect/landmark/map_tag{ - name = "Ice Colony" - }, /turf/closed/ice_rock/corners, /area/ice_colony/exterior/surface/cliff) "acB" = ( diff --git a/maps/Z.01.Kutjevo.dmm b/maps/map_files/Kutjevo/Kutjevo.dmm similarity index 99% rename from maps/Z.01.Kutjevo.dmm rename to maps/map_files/Kutjevo/Kutjevo.dmm index c0edde79dbcc..31a86e1df949 100644 --- a/maps/Z.01.Kutjevo.dmm +++ b/maps/map_files/Kutjevo/Kutjevo.dmm @@ -1754,9 +1754,6 @@ }, /area/kutjevo/exterior/runoff_river) "fK" = ( -/obj/effect/landmark/map_tag{ - name = "Kutjevo Refinery" - }, /turf/closed/wall/kutjevo/rock, /area/kutjevo/interior/oob) "fL" = ( diff --git a/maps/Z.01.LV624.dmm b/maps/map_files/LV624/LV624.dmm similarity index 99% rename from maps/Z.01.LV624.dmm rename to maps/map_files/LV624/LV624.dmm index 77e4d869c8e5..a5cb2f587591 100644 --- a/maps/Z.01.LV624.dmm +++ b/maps/map_files/LV624/LV624.dmm @@ -167,9 +167,6 @@ /turf/open/gm/dirt, /area/lv624/ground/caves/east1) "aaM" = ( -/obj/effect/landmark/map_tag{ - name = "LV-624" - }, /turf/closed/wall/rock/brown, /area/lv624/ground/caves/west1) "aaN" = ( diff --git a/maps/Z.01.Prison_Station_FOP.dmm b/maps/map_files/Prison_Station_FOP/Prison_Station_FOP.dmm similarity index 99% rename from maps/Z.01.Prison_Station_FOP.dmm rename to maps/map_files/Prison_Station_FOP/Prison_Station_FOP.dmm index 4853954b83a9..9e392d6fb890 100644 --- a/maps/Z.01.Prison_Station_FOP.dmm +++ b/maps/map_files/Prison_Station_FOP/Prison_Station_FOP.dmm @@ -10882,9 +10882,6 @@ }, /area/prison/medbay) "aAO" = ( -/obj/effect/landmark/map_tag{ - name = "Prison Station" - }, /turf/open/space, /area/space) "aAP" = ( diff --git a/maps/Z.01.Sorokyne_Strata.dmm b/maps/map_files/Sorokyne_Strata/Sorokyne_Strata.dmm similarity index 99% rename from maps/Z.01.Sorokyne_Strata.dmm rename to maps/map_files/Sorokyne_Strata/Sorokyne_Strata.dmm index 9dadd5945253..d8f8e041dc1d 100644 --- a/maps/Z.01.Sorokyne_Strata.dmm +++ b/maps/map_files/Sorokyne_Strata/Sorokyne_Strata.dmm @@ -15,9 +15,6 @@ /turf/closed/wall/strata_ice/jungle, /area/strata/ug/interior) "aae" = ( -/obj/effect/landmark/map_tag{ - name = "Sorokyne Strata" - }, /turf/open/space, /area/space) "aaf" = ( diff --git a/maps/Z.03.USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm similarity index 99% rename from maps/Z.03.USS_Almayer.dmm rename to maps/map_files/USS_Almayer/USS_Almayer.dmm index 1e2804921d86..503afabccafb 100644 --- a/maps/Z.03.USS_Almayer.dmm +++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm @@ -23675,9 +23675,7 @@ }, /area/almayer/squads/req) "bsK" = ( -/obj/effect/landmark{ - name = "SupplyElevator" - }, +/obj/effect/landmark/supply_elevator, /turf/open/floor/almayer/empty, /area/supply/station) "bsL" = ( @@ -49275,9 +49273,7 @@ }, /area/almayer/squads/req) "oTz" = ( -/obj/effect/landmark{ - name = "VehicleElevator" - }, +/obj/effect/landmark/vehicleelevator, /turf/open/floor/almayer/empty, /area/supply/station_vehicle) "oUO" = ( @@ -50234,9 +50230,7 @@ /turf/open/floor/almayer, /area/almayer/command/cic) "pVu" = ( -/obj/item/paper/prison_station/test_log{ - desc = "This paper seems to have been crumpled up in dried blood, turning it nearly unreadable."; - info = "

INTERROGATION LOG

Person: (Withheld) 'Verdan' (Withheld)


\n

PROCEDURE: Wringer Technique

RESULTS: Verdan bashes head around. Appears agitated and cries, perhaps angry. Heavy Vocalisations.

-

PROCEDURE: Shocking.

RESULTS: Cries and screams in anger. No significant difference from last procedure.

Note: Pain Tolerant, must increase pain.

-

PROCEDURE: Handy Man. Instructed to \"look.\" while saw performs its work.

RESULTS: Verdan stares for approximately three seconds. Verdan screams and begins trying to break the restraints while begging to be released. The saw finally completes its work. Verdan seems to be a blabbering mess.

Note: Promising!

-

PROCEDURE: Information Gathering.

RESULTS: Verdan starts giving out information about the other cells.

Verdan starts whispering from fatigue, have to sit closer. Verdan leans in closer to me, he~

(The remaining paper is splattered in blood and unreadable.)"; +/obj/item/paper/prison_station/interrogation_log{ pixel_x = 10; pixel_y = 7 }, diff --git a/maps/Z.01.Whiskey_Outpost_v2.dmm b/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm similarity index 99% rename from maps/Z.01.Whiskey_Outpost_v2.dmm rename to maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm index 4f0f97b43fd9..77ba6e3becf0 100644 --- a/maps/Z.01.Whiskey_Outpost_v2.dmm +++ b/maps/map_files/Whiskey_Outpost_v2/Whiskey_Outpost_v2.dmm @@ -5078,9 +5078,6 @@ /turf/open/gm/dirt, /area/whiskey_outpost/outside/north/northwest) "mT" = ( -/obj/effect/landmark/map_tag{ - name = "Whiskey Outpost" - }, /turf/closed/wall/rock/brown, /area/whiskey_outpost/inside/caves) "mU" = ( diff --git a/maps/Z.02.Admin_Level.dmm b/maps/map_files/generic/Admin_level.dmm similarity index 100% rename from maps/Z.02.Admin_Level.dmm rename to maps/map_files/generic/Admin_level.dmm diff --git a/maps/Z.04.Low_Orbit.dmm b/maps/map_files/generic/Low_Orbit.dmm similarity index 100% rename from maps/Z.04.Low_Orbit.dmm rename to maps/map_files/generic/Low_Orbit.dmm diff --git a/maps/prison_station_fop.json b/maps/prison_station_fop.json new file mode 100644 index 000000000000..78424bd433d3 --- /dev/null +++ b/maps/prison_station_fop.json @@ -0,0 +1,27 @@ +{ + "map_name": "Prison Station", + "map_path": "map_files/Prison_Station_FOP", + "map_file": "Prison_Station_FOP.dmm", + "survivor_types": [ + "Survivor - Scientist", + "Survivor - Doctor", + "Survivor - Corporate Liaison", + "Survivor - Security", + "Survivor - Prisoner", + "Survivor - Prisoner", + "Survivor - Gang Leader", + "Survivor - Engineer" + ], + "defcon_triggers": [ + 3750, + 2600, + 1450, + 875, + 0.0 + ], + "survivor_message": "You are a survivor of the attack on Fiorina Orbital Penitentiary. You worked or lived on the prison station, and managed to avoid the alien attacks... until now.", + "map_item_type": "/obj/item/map/FOP_map", + "announce_text": "An automated distress signal has been received from maximum-security prison \"Fiorina Orbital Penitentiary\". A response team from the ###SHIPNAME### will be dispatched shortly to investigate.", + "environment_traits": { "Lockdown": true }, + "traits": [{ "Ground": true }] +} diff --git a/maps/sorokyne_strata.json b/maps/sorokyne_strata.json new file mode 100644 index 000000000000..a1b7da1de111 --- /dev/null +++ b/maps/sorokyne_strata.json @@ -0,0 +1,28 @@ +{ + "map_name": "Sorokyne Strata", + "map_path": "map_files/Sorokyne_Strata", + "map_file": "Sorokyne_Strata.dmm", + "environment_traits": { + "COLD": true + }, + "weather_holder": "/datum/weather_ss_map_holder/sorokyne", + "survivor_types": [ + "Survivor - Scientist", + "Survivor - Doctor", + "Survivor - Security", + "Survivor - Engineer" + ], + "defcon_triggers": [ + 3750, + 2600, + 1450, + 875, + 0.0 + ], + "map_item_type": "/obj/item/map/sorokyne_map", + "announce_text": "An automated distress signal has been recieved from a mining colony on border world LV-976, \"Sorokyne Outpost\". A response team from the ###SHIPNAME### will be dispatched shortly to investigate.", + "monkey_types": [ + "yiren" + ], + "traits": [{ "Ground": true }] +} diff --git a/maps/whiskey_outpost_v2.json b/maps/whiskey_outpost_v2.json new file mode 100644 index 000000000000..87802ab63b9b --- /dev/null +++ b/maps/whiskey_outpost_v2.json @@ -0,0 +1,7 @@ +{ + "map_name": "Whiskey Outpost", + "map_path": "map_files/Whiskey_Outpost_v2", + "map_file": "Whiskey_Outpost_v2.dmm", + "map_item_type": "/obj/item/map/whiskey_outpost_map", + "force_mode": "Whiskey Outpost" +} diff --git a/run_mapdaemon.bat b/run_mapdaemon.bat deleted file mode 100644 index 089f51aa3bf2..000000000000 --- a/run_mapdaemon.bat +++ /dev/null @@ -1,3 +0,0 @@ -cd tools\MapDaemon -java -cp ".;library_jar_files\json-20170516.jar;library_jar_files\byond-message-client-1.0.jar" map_daemon.MapDaemon "examples/config.json" "true" -cd ..\.. diff --git a/tgui/.gitignore b/tgui/.gitignore index 50a9a0a6fb76..2c6e18ee1a16 100644 --- a/tgui/.gitignore +++ b/tgui/.gitignore @@ -3,6 +3,7 @@ node_modules *.log package-lock.json +package.json ## Yarn stuff /.pnp.* diff --git a/tools/MapDaemon/MAPDAEMON_README.txt b/tools/MapDaemon/MAPDAEMON_README.txt deleted file mode 100644 index 8b47a1cd30c6..000000000000 --- a/tools/MapDaemon/MAPDAEMON_README.txt +++ /dev/null @@ -1,38 +0,0 @@ - - -Quick Startup guide for the MapDaemon script by MadSnailDisease - -1. Install a jre of version 1.8 or later. (as of writing this, 1.8 is the most recent) -1.5. Set up your user variables for java for easier command line use https://stackoverflow.com/questions/1672281/environment-variables-for-java-installation -2. Properly configure the config.txt file to your specifications and change it to a .json file. This will mainly include a bunch of paths and the url and port for the server. "localhost" should be used for local testing, - and "play.colonial-marines.com" for live tests. The port for colonial marines is 1400. -2.5 Edit run_mapdaemon.bat to have the proper .jar and log file locations. -4. Copy run_mapdaemon.bat to your DM project folder -5. Run the server using DD out of what you put for dest_base in config.json - -> If you haven't used MapDaemon before it's important to copy the three binaries (.dmb, .int, and .rsc) to dest_base -6. If you do not want logs dumped to console and saved no matter what (understandably), change the "true" in run_mapdaemon.bat to a "false" -7. For voting, use the Map Vote verb under the OOC tab, and select which map you want to play. - -How the MapDaemon works: -Server side: - Votes are not taken until the round is over, and there will be a minimum of 30 seconds to vote before the bot grabs the info and processes it. - The round will be delayed until the bot decides to resume it - Admins will have a chance to delay the round if they are processing bans - If you manually restart the server before MapDaemon finishes its business, the following could occur: - The map and gamemode not lining up (unlikely) - Resource conflicts, like when visual updates are pushed - Other issues that generally come along when you restart a game mid-compile - -Daemon side: - The bot will ask the server if the round ended every 5 seconds, or whatever number you put into config.json - When realizes that the round is over, it will wait 30 seconds and then retrieve the votes - Once processed, it will modify the .dme, compile, and copy the .int, .rsc, and .dmb files over to the dest_base directory - The bot will then tell the server to restart in a few seconds, telling admins to delay the round if they want to process bans - Once the world is rebooted, the new map will be loaded up and ready, with the gamemode already changed. - -If you want to run a test of a specific map, especially if it's a map or has code that is not already pulled, you'll need to pull, compile, and copy normally. - -Updating code: -All you will need to do is pull from master and the next round will have the new updates. -Git integration is planned, either in a future watchdog script or this same script. -ATM it's not necessary since the same people with write access to the repo have access to the remote (as far as I know). diff --git a/tools/MapDaemon/examples/compile_files.bat b/tools/MapDaemon/examples/compile_files.bat deleted file mode 100644 index e266cb2ef3d1..000000000000 --- a/tools/MapDaemon/examples/compile_files.bat +++ /dev/null @@ -1,2 +0,0 @@ -cd ..\source_files\ -javac -cp ".;..\library_jar_files\json-20170516.jar;..\library_jar_files\byond-message-client-1.0.jar" -d "../map_daemon/MapDaemonExecutables" *.java diff --git a/tools/MapDaemon/examples/config.txt b/tools/MapDaemon/examples/config.txt deleted file mode 100644 index a3a613d3e07b..000000000000 --- a/tools/MapDaemon/examples/config.txt +++ /dev/null @@ -1,55 +0,0 @@ -### Config file for MapDaemon - -{ -"paths" : { - ### The name of the project in DreamMaker - "project_name" : "ColonialMarinesALPHA", - ### The directory where the actual code is that needs to be compiled, including maps - "project_base" : ".", - ### The directory where DD runs out of, i.e. the destination folder when the binaries are copied from the poject base folder - "dest_base" : "tools/MapDaemon", - ### The directory to save all of the logs - "crash_logs" : "tools/MapDaemon/logs", - ### The installation directory of BYOND - "byond_base" : "C:/Program Files (x86)/BYOND" - }, -"server" : { - ### The IP address of the server, localhost works, don't know if IPv6 does - "url" : "localhost", - ### The port of the server - "port" : "59500" - }, -"game" : { - "maps" : { - ### The first part of the filename for maps, not a regex (i.e. the "." isn't short for "any character") - "map_preprocess_line" : "Z.01.", - ### CDL of maps, so the daemon knows what the options are, important for changing the gamemode text-file too. The name must be the same as the name of the relevant gamemode - "map_cdl" : "LV-624,Big-Red,Ice Colony", - ### The default name of the map to use - "default_map" : "LV-624", - ### LV624 map name (like from the file), with the option given to players on the left (also the name of the gamemode) - "LV-624" : "LV624", - ### Big Red map name - "Solaris Ridge" : "BigRed_v2", - ### Ice Colony map name - "Ice Colony" : "Ice_Colony_v2", - ### Prison Station map name - "Prison Station" : "Prison_Station_FOP", - ### Whiskey Outpost map name - "Whiskey Outpost" : "Whiskey_Outpost_v2" - } - }, -"prefs" : { - ### Whether or not the bot is to be used, in case of special admin events and stuff, run by Apop or Rahl - "enable" : "true", - ### How many seconds to wait between round-end checks. Can be a decimal. - "tick_delay" : "5.0", - ### How many times to reattempt a mapdaemon command if there it fails. - "MAX_COMMAND_RETRIES" : "5", - ###How long to wait on startup, in seconds. Can be a decimal. - "startup_delay" : "1.0", - ###By what base to increase the read timeout. For example, a value of 2 will result in delays of 1, 2, 4, 8, 16 seconds and a value of 3 will result in 1, 3, 9, 27, 81 seconds - ###Can be a decimal, but results of the exponential will be rounded down to the nearest integer. - "read_timeout_increment" : "2.0" - } -} \ No newline at end of file diff --git a/tools/MapDaemon/examples/copy_src.bat b/tools/MapDaemon/examples/copy_src.bat deleted file mode 100644 index c0c76e1e5fd2..000000000000 --- a/tools/MapDaemon/examples/copy_src.bat +++ /dev/null @@ -1 +0,0 @@ -copy "C:\Users\Sam\workspace\MapDaemon\src\map_daemon\*.java" "C:\Users\Sam\Desktop\MapDaemonExecutables\src" \ No newline at end of file diff --git a/tools/MapDaemon/examples/run_mapdaemon.bat b/tools/MapDaemon/examples/run_mapdaemon.bat deleted file mode 100644 index c29cec853322..000000000000 --- a/tools/MapDaemon/examples/run_mapdaemon.bat +++ /dev/null @@ -1,3 +0,0 @@ -cd C:\Users\Sam\Desktop\MapDaemonExecutables -java -cp ".;C:\Users\Sam\Desktop\MapDaemonExecutables\json-20170516.jar;C:\Users\Sam\Desktop\MapDaemonExecutables\byond-message-client-1.0.jar" map_daemon.MapDaemon "C:/Users/Sam/Desktop/MapDaemonExecutables/config.json" "true" -cd C:\Users\Sam\Desktop\MapDaemonExecutables \ No newline at end of file diff --git a/tools/MapDaemon/library_jar_files/byond-message-client-1.0.jar b/tools/MapDaemon/library_jar_files/byond-message-client-1.0.jar deleted file mode 100644 index db419acf5aba..000000000000 Binary files a/tools/MapDaemon/library_jar_files/byond-message-client-1.0.jar and /dev/null differ diff --git a/tools/MapDaemon/library_jar_files/json-20170516.jar b/tools/MapDaemon/library_jar_files/json-20170516.jar deleted file mode 100644 index 5033f66d4a0c..000000000000 Binary files a/tools/MapDaemon/library_jar_files/json-20170516.jar and /dev/null differ diff --git a/tools/MapDaemon/map_daemon/Config.class b/tools/MapDaemon/map_daemon/Config.class deleted file mode 100644 index 0bfa0c5521bc..000000000000 Binary files a/tools/MapDaemon/map_daemon/Config.class and /dev/null differ diff --git a/tools/MapDaemon/map_daemon/CrashLogger.class b/tools/MapDaemon/map_daemon/CrashLogger.class deleted file mode 100644 index 2ed1554a4518..000000000000 Binary files a/tools/MapDaemon/map_daemon/CrashLogger.class and /dev/null differ diff --git a/tools/MapDaemon/map_daemon/MapDaemon.class b/tools/MapDaemon/map_daemon/MapDaemon.class deleted file mode 100644 index 1085df923cd5..000000000000 Binary files a/tools/MapDaemon/map_daemon/MapDaemon.class and /dev/null differ diff --git a/tools/MapDaemon/map_daemon/ServerMessenger.class b/tools/MapDaemon/map_daemon/ServerMessenger.class deleted file mode 100644 index 0aab76d9371a..000000000000 Binary files a/tools/MapDaemon/map_daemon/ServerMessenger.class and /dev/null differ diff --git a/tools/MapDaemon/map_daemon/Tester.class b/tools/MapDaemon/map_daemon/Tester.class deleted file mode 100644 index 9e7915cf1d35..000000000000 Binary files a/tools/MapDaemon/map_daemon/Tester.class and /dev/null differ diff --git a/tools/MapDaemon/source_files/Config.java b/tools/MapDaemon/source_files/Config.java deleted file mode 100644 index 2e9568eaf56e..000000000000 --- a/tools/MapDaemon/source_files/Config.java +++ /dev/null @@ -1,94 +0,0 @@ -package map_daemon; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * TODO: Make getting other data types easy and in this class. - * @author Sam - * - */ -public class Config { - - private JSONObject info; - private int status; - - public static final int STATUS_UNUSABLE = 1; - public static final int STATUS_READY = 2; - - public static final String ERROR_UNUSABLE = "ERROR: CONFIG UNUSABLE"; - public static final String ERROR_BAD_INDEX = "ERROR: BAD INDEX PASSED"; - - public Config(String directory) { - status = STATUS_UNUSABLE; - try { - List lines = Files.readAllLines(Paths.get(directory)); - String all_data = ""; - for(String s : lines) { - String a = s.trim(); - if(a.startsWith("###")) continue; - all_data += s; - } - info = new JSONObject(all_data); - } - catch(IOException e) { - info = null; - return; - } - status = STATUS_READY; - } - - public int getStatus() { - return status; - } - - /** - * Just gets a String from the JSON file. - * @param path The json path, using double backslashes ("\\") between keys. - * @return The String - */ - public String getStringFromConfig(String path) { - if(status == STATUS_UNUSABLE) return ERROR_UNUSABLE; - - String[] keys = path.split("\\\\"); //Translates into a single "\" because fuck strings - JSONObject interim_a, interim_b = info; - - for(int i = 0; i < keys.length-1; i++) { - interim_a = interim_b; - interim_b = interim_a.getJSONObject(keys[i]); - } - String to_return = ERROR_BAD_INDEX; - try { - to_return = interim_b.getString(keys[keys.length-1]); - } - catch(JSONException e) { - throw e; - } - return to_return; - } - - public boolean getBooleanFromConfig(String path) { - if(status == STATUS_UNUSABLE) return false; - - String[] keys = path.split("\\\\"); //Translates into a single "\" because fuck strings - JSONObject interim_a, interim_b = info; - - for(int i = 0; i < keys.length-1; i++) { - interim_a = interim_b; - interim_b = interim_a.getJSONObject(keys[i]); - } - boolean to_return = false; - try { - to_return = interim_b.getBoolean(keys[keys.length-1]); - } - catch(JSONException e) { - throw e; - } - return to_return; - } -} diff --git a/tools/MapDaemon/source_files/CrashLogger.java b/tools/MapDaemon/source_files/CrashLogger.java deleted file mode 100644 index 5ab20fe90ddd..000000000000 --- a/tools/MapDaemon/source_files/CrashLogger.java +++ /dev/null @@ -1,86 +0,0 @@ -package map_daemon; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; - -public class CrashLogger { - - private String directory; - private LinkedList data; - private SimpleDateFormat line_date_format; - private SimpleDateFormat file_name_format; - private boolean closed; - private boolean verbose; - - public CrashLogger(String directory, boolean verbose) { - this.directory = directory; - this.verbose = verbose; - data = new LinkedList(); - line_date_format = new SimpleDateFormat("HH-mm-ss"); - file_name_format = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); - closed = false; - } - - public void addLine(String s, boolean important) { - if(closed || !important) return; - if(verbose) System.out.println(s); - Date date = new Date(); - data.add("[" + line_date_format.format(date) + "]: " + s); - } - - public void addLine(String s) { - addLine(s, true); - } - - private boolean writeInfo() { - cleanUpLogs(); - - Date date = new Date(); - directory += "\\" + file_name_format.format(date) + ".log"; - try { - Files.write(Paths.get(directory), data, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); - } - catch(IOException e) { - addLine(MapDaemon.returnStackTrace(e)); - return false; - } - return true; - } - - private void cleanUpLogs() { - for(int i = 0; i < data.size() - 1; i++) { - if(data.get(i).equals(data.get(i+1))) { - data.remove(i); - i--; - } - } - } - - public boolean getClosed() { - return closed; - } - - public List getData() { - return data; - } - - /** - * Doesn't allow more logs to be written. - * @param crashed true if it should actually write the logs to the file. - * @return If it succeeded in writng the logs. - */ - public boolean close(boolean crashed) { - if(closed) return true; - if(crashed) { - return writeInfo(); - } - closed = true; - return true; - } -} diff --git a/tools/MapDaemon/source_files/MapDaemon.java b/tools/MapDaemon/source_files/MapDaemon.java deleted file mode 100644 index 6c855b14a131..000000000000 --- a/tools/MapDaemon/source_files/MapDaemon.java +++ /dev/null @@ -1,708 +0,0 @@ -package map_daemon; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.nio.file.CopyOption; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.nio.file.StandardOpenOption; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.json.JSONException; -import org.json.JSONObject; - -import io.github.spair.byond.message.response.ByondResponse; -import io.github.spair.byond.message.response.ResponseType; - -public class MapDaemon { - - private static String default_config_dir = "C:\\Users\\Sam\\Desktop\\MapDaemonExecutables\\config.json"; - private static String default_log_dir = "C:\\Users\\Sam\\Desktop\\MapDaemonExecutables\\logs"; - private String byond_base; - private String project_base; - private String dest_base; - private String project_name; - private String z1_map_preprocess_line; - private String[] maps; - private String[] binary_files = new String[] {".dmb", ".rsc", ".int"}; - private String default_map; - - private boolean compile_needed; - - private long UID; //Time in millis since UNIX epoch on creation, so unique enough without using the Random() library. - - private Config config; - private CrashLogger logger; - private ServerMessenger server_msgr; - private boolean running; - private boolean verbose = false; - private String next_map; - - private float tick_delay; - private float startup_delay; - private float read_timeout_increment; - private int MAX_COMMAND_RETRIES = 5; - - private static final int PROCESS_COMMAND_SUCCESS = 1; - private static final int PROCESS_COMMAND_RETRY = 2; - private static final int PROCESS_COMMAND_TERMINATE = 3; - - private static final int ROUND_STATUS_OVER = 1; - private static final int KILL_MAPDAEMON = 2; //Do_it.gif - - /** - * - * @param args The first is a String of the config.json file and the second is a boolean for whetehr or not to enable verbose logging - */ - public static void main(String[] args) { - String config_dir = args[0]; - if(config_dir.equals("")) config_dir = default_config_dir; - boolean verbose = false; - try { - verbose = Boolean.parseBoolean(args[1]); - } - catch (Exception e) { - verbose = true; - } - try { - new MapDaemon(config_dir, verbose); - } catch (Exception e) { - e.printStackTrace(); - } - try { - Thread.sleep(10000); - } catch (Exception e) { - - } - } - - /** - * Instantiates a ton of stuff and gets info from config - * @param config_dir The path of config.json - * @param verbose Whether or not to enable verbose logging - */ - public MapDaemon(String config_dir, boolean verbose) { - UID = System.currentTimeMillis(); - - config = new Config(config_dir); - - if(!config.getBooleanFromConfig("prefs\\enable")) return; //Terminate if we are set to - - this.verbose = verbose; - String log_dir = config.getStringFromConfig("paths\\crash_logs"); - if(log_dir.indexOf("ERROR") >= 0) log_dir = default_log_dir; - logger = new CrashLogger(log_dir, verbose); - String play_url = config.getStringFromConfig("server\\url"); - int port = Integer.parseInt(config.getStringFromConfig("server\\port")); - server_msgr = new ServerMessenger(play_url, port); - running = true; - - default_map = config.getStringFromConfig("game\\maps\\default_map"); - - byond_base = config.getStringFromConfig("paths\\byond_base"); - project_base = config.getStringFromConfig("paths\\project_base"); - dest_base = config.getStringFromConfig("paths\\dest_base"); - project_name = config.getStringFromConfig("paths\\project_name"); - z1_map_preprocess_line = config.getStringFromConfig("game\\maps\\map_preprocess_line"); - - tick_delay = Float.parseFloat(config.getStringFromConfig("prefs\\tick_delay")) * 1000; - startup_delay = Float.parseFloat(config.getStringFromConfig("prefs\\startup_delay")) * 1000; - MAX_COMMAND_RETRIES = Integer.parseInt(config.getStringFromConfig("prefs\\MAX_COMMAND_RETRIES")); - read_timeout_increment = Float.parseFloat(config.getStringFromConfig("prefs\\read_timeout_increment")); - - String map_cdl = config.getStringFromConfig("game\\maps\\map_cdl"); - maps = map_cdl.split(","); - - compile_needed = true; - - try { - logger.addLine("Waiting " + startup_delay/1000 + " seconds..."); - Thread.sleep((long) startup_delay); - } - catch(Exception e) { - return; - } - logger.addLine("Finished waiting, beginning round-end checks."); - try{ - while(running) { - Thread.sleep((long) tick_delay); - if(!verifyRoundEnded(0)) continue; - logger.addLine("Round has ended, waiting 30 seconds to collect votes."); - if(!delayRound(0)) return; - Thread.sleep(50000); - if(!getNextMap(0)) return; - if(!Compile()) return; - if(!resumeRound(0)) return; - //resumeRound() ends the bot, so this will just rest for the tick delay before restarting so the user can look at logs in the console or wherever. - } - } - catch(Exception e) { - logger.addLine(returnStackTrace(e)); - crashedEndProcess("Something in the main loop threw an exception, ending process."); - } - } - - //Thanks https://stackoverflow.com/questions/1149703/how-can-i-convert-a-stack-trace-to-a-string - /** - * Takes an exception and returns it's stack trace - * @param e The exception - * @return The stack trace - */ - public static String returnStackTrace(Exception e) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); - String s = sw.toString(); - return s; - } - - /** - * Called when the bot has decided to crash for any number of reasons. This will write logs no matter what. - * @param info A crash message to write before closing the logger and writing it. - */ - private void crashedEndProcess(String info) { - logger.addLine(info); - logger.addLine("Closing program on next tick"); - if(!logger.close(true)) { - System.out.println("Failed to write logs! Crash report will be lost!"); - //System.out.println("Dumping logs to console:"); - //List data = logger.getData(); - } - else System.out.println("Successfully wrote logs! Check relevant directory for crash logs!"); - running = false; - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - - } - } - - /** - * Called when the bot decides to close but only because it thinks the round restarted properly. - * If verbose was set true, it will write the logs anyways. - */ - private void goodExitEndProcess() { - logger.addLine("Bot successfully terminated!"); - if(verbose) { - logger.addLine("Logs set to verbose, writing logs anyways"); - logger.close(true); //"Crashed, but not really - } - running = false; - } - - private void goodExitEndProcess(String message) { - logger.addLine(message); - goodExitEndProcess(); - } - - - /** - * This takes a BYOND response and processes its info. It is used only to judge success versus failure. - * It will return one of the three response codes, telling the calling method what to do. - * This is pretty messy but doesn't really need to be fixed since it works right. - * TODO: Make this better and neater. - * TODO: Think of a better name for this. - * @param obj The ByondResponse object returned by the server messenger. - * @param fails How many times the method has failed in a row - * @param info_text What the calling method was doing, used for logging purposes. - * @return One of the static response code found in this class. - */ - private int processCommandStringAttempt(ByondResponse obj, int fails, String info_text) { - - if(!obj.getResponseType().equals(ResponseType.STRING)) { - if(fails < MAX_COMMAND_RETRIES) { - logger.addLine("Recieved unexpected response type, retrying."); - return PROCESS_COMMAND_RETRY; - } - else { - crashedEndProcess("Recieved unexpected response type with too many failures. Writing logs and ending process."); - return PROCESS_COMMAND_TERMINATE; - } - } - - String resp = (String) obj.getResponseData(); - if(!(resp.indexOf("ERROR") >= 0)) { - logger.addLine("Command successfully recieved and processed"); - return PROCESS_COMMAND_SUCCESS; - } - else if(fails < MAX_COMMAND_RETRIES) { - logger.addLine(resp); - logger.addLine("Failed to "+info_text+", attempting again"); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - crashedEndProcess("Failed to sleep for 1 second. No longer attempting to "+info_text+". Writing logs and ending process."); - logger.addLine(returnStackTrace(e)); - return PROCESS_COMMAND_TERMINATE; - } - return PROCESS_COMMAND_RETRY; - } - else { - crashedEndProcess("Failed to "+info_text+" too many times. Writing logs."); - return PROCESS_COMMAND_TERMINATE; - } - } - - /** - * Tells the server to resume the round. - * @param fails The number of consecutive failures. - */ - private boolean resumeRound(int fails) { - logger.addLine("Telling server to restart the round"); - ByondResponse obj = server_msgr.RecieveByondResponse("mapdaemon_restart_round&" + UID, (int) Math.pow(read_timeout_increment, fails)*1000); - - String s = (String) obj.getResponseData(); - - if((s == null || s.contains("ERROR")) && fails < MAX_COMMAND_RETRIES) { - return resumeRound(++fails); - } - else if(s != null && s.contains("WILL DO")) { - logger.addLine("Server says it will restart, terminating program."); - goodExitEndProcess(); - } - else if(fails >= MAX_COMMAND_RETRIES) { - crashedEndProcess("Tried to restart the server but failed too many times"); - return false; - } - - return true; - } - - /** - * Gets voting JSON info from the server. This does it's own reply processing since it's actually trying to recieve info. - * TODO: Make this neater when I make processCommandStringAttempt() - * @param fails The number of consecutive failures. - */ - private boolean getNextMap(int fails) { - logger.addLine("Getting next map from server"); - ByondResponse obj = server_msgr.RecieveByondResponse("mapdaemon_receive_votes&" + UID, (int) Math.pow(read_timeout_increment, fails)*1000); - - int flag = processCommandStringAttempt(obj, fails, "get next map"); - - if(flag == PROCESS_COMMAND_SUCCESS) { - logger.addLine("Successfully received votes"); - logger.addLine("Processing recieved data"); - next_map = (String) obj.getResponseData(); - next_map = next_map.substring(0, next_map.length()-1); //Discarding \u0000 that is appended to the response body for some reason - - logger.addLine("Successfully processed and saved the next map: " + next_map); - } - else if(flag == PROCESS_COMMAND_RETRY) { - fails++; - return getNextMap(fails); - } - else if(flag != PROCESS_COMMAND_TERMINATE) { - crashedEndProcess("Received unknown response code, terminating process"); - return false; - } - - return true; - } - - /** - * Takes the JSON vote info as text and makes sure the formatting is correct. It does not actually find the winner. - * @param text The JSON text as a String - * @return Whether or not the formatting is correct. - */ - @SuppressWarnings("unused") - private boolean testVoteJSON(String text) { - JSONObject interim = null; - try { - interim = new JSONObject(text); - } - catch(JSONException e) { - return false; - } - - for(String s : maps) { - try { - Integer I = interim.getInt(s); - if(I.intValue() >= 0) continue; - else return false; - } - catch(JSONException e) { - return false; - } - } - - return true; - } - - /** - * Tells the server to delay the round. This does not toggle the round delay, but actually confirms that it will delay. - * @param fails The number of consecutive failures. - */ - private boolean delayRound(int fails) { - logger.addLine("Telling server to delay the round"); - ByondResponse obj = server_msgr.RecieveByondResponse("mapdaemon_delay_round&" + UID, (int) Math.pow(read_timeout_increment, fails)*1000); - - int flag = processCommandStringAttempt(obj, fails, "delay round"); - - //Switches are nasty - if(flag == PROCESS_COMMAND_SUCCESS) { - logger.addLine("Successfully delayed round"); - } - else if(flag == PROCESS_COMMAND_RETRY) { - fails++; - return delayRound(fails); - } - else if(flag != PROCESS_COMMAND_TERMINATE) { - crashedEndProcess("Recieved unknown response code, terminating process"); - return false; - } - - return true; - } - - /** - * Checks to see if the round has ended. - * @return Whether or not the round as ended. - */ - private boolean verifyRoundEnded(int fails) { - - boolean important = false; - - String query_string = "mapdaemon_get_round_status&" + UID; - - ByondResponse obj = server_msgr.RecieveByondResponse(query_string, (int) Math.pow(read_timeout_increment, fails)*1000); - - if(!obj.getResponseType().equals(ResponseType.FLOAT_NUMBER)) { - important = true; - - fails++; - - if(fails >= MAX_COMMAND_RETRIES) { - - logger.addLine("Received incorrect response type."); - if(obj.getResponseType().equals(ResponseType.STRING)) { - String s = (String) obj.getResponseData(); - if(s.indexOf("ERROR") >= 0) logger.addLine(s); - } - crashedEndProcess("Failed round end checks, writing logs and terminating script."); - return false; - } - else { - logger.addLine("Failed to recieve the proper response " + fails + " times consecutively."); - return verifyRoundEnded(fails); - } - } - - logger.addLine("Checking for round end.", important); - - int round_status = ((Float) obj.getResponseData()).intValue(); - - if(round_status == ROUND_STATUS_OVER) return true; - else if(round_status == KILL_MAPDAEMON) { - goodExitEndProcess("Received kill code from server. Terminating..."); - } - - return false; - } - - /* - /** - * Just pings the server, getting the number of online players +1. Called to see if the server is online. - * @return The number of online players +1 - */ - /* - private int pingServer() { - ByondResponse resp = server_msgr.RecieveByondResponse("ping"); - if(resp.getResponseType().equals(ResponseType.FLOAT_NUMBER)) { - Float F = (Float) resp.getResponseData(); - return F.intValue(); - } - return 0; - } - */ - - /** - * Calls a bunch of methods in order to compile the server. Called once the round is over, once a round. - */ - private boolean Compile() { - logger.addLine("Compiling:"); - - if(!compile_needed) { - logger.addLine("No compile needed, skipping compile stage."); - return true; - } - String map_filename = ""; - try { - map_filename = z1_map_preprocess_line + config.getStringFromConfig("game\\maps\\" + next_map) + ".dmm"; - } catch(Exception e) { - logger.addLine("Something went wrong while getting the next map, reverting to default map"); - logger.addLine(returnStackTrace(e)); - map_filename = default_map; - } - logger.addLine("Next compile will be using file: -----> " + map_filename); - String dme_path = project_base + "\\" + project_name + ".dme"; - - boolean modify_success = modifyDME(dme_path, map_filename); - if(!modify_success) { - crashedEndProcess("Failed to modify the DME."); - return false; - } - - String compile_info = compileDME(dme_path); - boolean compile_success = verifyCompileSuccess(compile_info); - if(!compile_success) { - crashedEndProcess("Failed to verify compile success."); - return false; - } - - boolean copy_success = copyBinaries(project_base, dest_base); - if(!copy_success) { - crashedEndProcess("Failed to copy binary files."); - return false; - } - /* - boolean gm_success = modifyGamemodeFile(next_map); - if(!gm_success) { - crashedEndProcess("Failed to modify the gamemode file."); - return false; - }*/ - - compile_needed = false; - - return true; - } - /* - private boolean modifyGamemodeFile(String map) { - try { - System.out.println(dest_base + "\\data\\mode.txt"); - Files.write(Paths.get(dest_base + "\\data\\mode.txt"), map.getBytes()); - return true; - } - catch(Exception e) { - logger.addLine(returnStackTrace(e)); - return false; - } - } - */ - /* - /** - * Process the saved JSON vote info to find the next map to play on. - * @return The filename (e.g. Z.01.LV624.dmm) of the map. - */ - /* - private String processVotes() { - logger.addLine("Finding next map to play on:"); - - int largest_count = 0; - String map_name = ""; - for(String s : maps) { - int votes = next_map.getInt(s); - if(votes > largest_count) { - largest_count = votes; - map_name = s; - } - } - if(map_name.equals("")) map_name = config.getStringFromConfig("game\\maps\\default_map"); - if(!map_name.equals(last_map)) compile_needed = true; - logger.addLine("Next round will be on: " + map_name); - return map_name; - } - */ - - /** - * Changes the .dme to include the proper map file. - * @param targ_dme The DME to edit. - * @param map_filename The new map to use, actually the filename gotten from processVotes() - * @return Whether or not it succeeded. - */ - private boolean modifyDME(String targ_dme, String map_filename) { - logger.addLine("Modifying project DME file:"); - - List lines = null; - try { - lines = Files.readAllLines(Paths.get(targ_dme)); - } catch (IOException e) { - crashedEndProcess("Failed to read project DME, writing logs and terminating script."); - logger.addLine(returnStackTrace(e)); - return false; - } - - String new_line = "#include \"maps\\" + map_filename + "\""; - - for(int i = 0; i < lines.size(); i ++) { - String s = lines.get(i); - if(s.indexOf(z1_map_preprocess_line) >= 0) { - lines.set(i, new_line); - break; - } - } - - try { - Files.write(Paths.get(targ_dme), lines); - } catch (IOException e) { - crashedEndProcess("Failed to write the modified DME, writing logs and terminating script"); - logger.addLine(returnStackTrace(e)); - return false; - } - - logger.addLine("Successfully modified " + targ_dme + "."); - - return true; - } - - /** - * Actually compiles the project. - * @param dme_path The path of the .dme - * @return The output from dm.exe (the compiler) or "ERROR" if it fucked up. Newline characters included and necessary. - */ - private String compileDME(String dme_path) { - logger.addLine("Executing dm.exe:"); - - String dm_exe = byond_base + "\\bin\\dm.exe"; - String command = "\"" + dm_exe + "\" \"" + dme_path + "\""; - Process p = null; - try { - p = Runtime.getRuntime().exec(command); - } catch (IOException e) { - crashedEndProcess("Failed to execute dm.exe, writing logs and terminating script"); - logger.addLine(returnStackTrace(e)); - return "ERROR"; - } - - try { - p.waitFor(5, TimeUnit.MINUTES); - } catch (InterruptedException e) { - crashedEndProcess("Process was interrupted while waiting for compile to complete"); - logger.addLine(returnStackTrace(e)); - return "ERROR"; - } - - //All on different lines so if there's a runtime it's easier to identify - String data = ""; - BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); - try { - while(reader.ready()) { - data += reader.readLine(); - data += "\n"; - } - } catch (IOException e) { - crashedEndProcess("Runtimed while reading from compiler output. Writing logs and terminating script."); - logger.addLine(returnStackTrace(e)); - return "ERROR"; - } - - return data; - } - - /** - * Whether or not the compile succeeded. The bot will end up crashing if it doesn't. - * @param data The output from dm.exe (the compiler). - * @return true for success, false for failure. - */ - private boolean verifyCompileSuccess(String data) { - logger.addLine("Verifying compile success:"); - - if(data.equals("")) { - - } - - if(data.equals("ERROR")) return false; - - if(data.equals("")) return true; //Debug stuff - - String[] lines = data.split("\n"); - String last_line = lines[lines.length-1]; - - int error_index = last_line.indexOf("error"); - int warning_index = last_line.indexOf("warning"); - - int errors = Integer.parseInt(last_line.substring(error_index-2, error_index-1)); - int warnings = Integer.parseInt(last_line.substring(warning_index-2, warning_index-1)); - - logger.addLine("Compiler output processed. Compile completed with " + errors + " errors and " + warnings + " warnings."); - - if(errors > 0 || warnings > 0) { - logger.addLine(data); - crashedEndProcess("Compile judged as a failure, writing logs and terminating script"); - return false; - } - - return true; - } - - /** - * Moves the output binary files (.rsc, .int, and .dmb) to the directory that DreamDaemon should be running out of so the restart will use the new files. - * @param base_path The path of the actually DM code that is compiled. - * @param targ_path The destination of the binaries, where DreamDaemon is running off of. Can be an empty folder plus the config directory (admins.txt etc) - * @return Success or failure, true or false respectively. - */ - private boolean copyBinaries(String base_path, String targ_path) { - logger.addLine("Copying binary files:"); - - for(int i = 0; i < binary_files.length; i++) { - String base_file = base_path + "\\" + project_name + binary_files[i]; - String targ_file = targ_path + "\\" + project_name + binary_files[i]; - - try { - CMDCopyFile(base_file, targ_file); - logger.addLine("Successfully copied " + base_file + " to " + targ_file); - } catch (Exception e) { - crashedEndProcess("Failed to copy " + base_file + " to " + targ_file); - logger.addLine(returnStackTrace(e)); - return false; - } - } - - logger.addLine("All binary files copied over, ready for next round."); - - return true; - } - - /** - * Uses CMD to copy a file. Using this instead of Files.copy() so we can force it, like in the case of the .rsc still being in use. - * @param source The source file directory as a String. Absolute path encouraged. - * @param destination The destination file directory as a String. Absolute path encouraged. - * @throws Exception Any recieved exceptions from copying or failure to copy in general. - */ - private void CMDCopyFile(String source, String destination) throws Exception { - String command = "cmd.exe /C copy \"" + source + "\" \"" + destination + "\" /Y"; - Process p = null; - try { - p = Runtime.getRuntime().exec(command); - } catch (Exception e) { - throw e; - } - - try { - p.waitFor(15, TimeUnit.SECONDS); - } catch (Exception e) { - throw e; - } - - String data = ""; - BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); - try { - while(reader.ready()) { - data += reader.readLine(); - data += "\n"; - } - } catch (Exception e) { - throw e; - } - - int index = data.indexOf(" file(s) copied"); - if(!data.substring(index-1, index).equals("1")) { - throw new Exception("Could not copy " + source + "using data:\n\n" + data); - } - } -} - - - - - - - - - - diff --git a/tools/MapDaemon/source_files/ServerMessenger.java b/tools/MapDaemon/source_files/ServerMessenger.java deleted file mode 100644 index f0be1a8b7f02..000000000000 --- a/tools/MapDaemon/source_files/ServerMessenger.java +++ /dev/null @@ -1,85 +0,0 @@ -package map_daemon; - -import io.github.spair.byond.message.ByondMessage; -import io.github.spair.byond.message.ServerAddress; -import io.github.spair.byond.message.client.ByondClient; -import io.github.spair.byond.message.client.exceptions.communicator.HostUnavailableException; -import io.github.spair.byond.message.client.exceptions.converter.EmptyResponseException; -import io.github.spair.byond.message.response.ByondResponse; -import io.github.spair.byond.message.response.ResponseType; - -/** - * This is a wrapper class for io.github.spair.byond stuff. - * Pretty simple, where it just tries to handle all exceptions before returning data. - * @author Sam - * - */ -public class ServerMessenger { - - /** - * The address to send messages to. - */ - private ServerAddress server_address; - - private static final String ERROR_HOST_UNAVAILABLE = "ERROR: HOST WAS UNAVAILABLE"; - private static final String ERROR_EMPTY_RESPONSE = "ERROR: RECIEVED AN EMPTY RESPONSE"; - private static final String ERROR_GENERAL_ERROR = "ERROR: UNANTICIPATED PROBLEM ENCOUNTERED"; - - /** - * Instatiates the object itself and the server address - * @param play_url The IP or URL - * @param port The port - */ - public ServerMessenger(String play_url, int port) { - server_address = new ServerAddress(play_url, port); - } - - /** - * Sends a command and recieves a message, returned as a ByondResponse object. - * @param command The command as a String, without the "?" delimiter. Ex: "ping" - * @param readTimeout The time, in ms, to wait before returning whatever response has been recieved. If the value is -1, then the default (1000 ms) timeout is used. - * @return The recieved message as a ByondResponse object. - */ - public ByondResponse RecieveByondResponse(String command, int readTimeout) { - String error_msg = ""; - try{ - ByondClient client = new ByondClient(); - ByondMessage message = new ByondMessage(server_address, "?" + command); - if(readTimeout == -1) { - return client.sendMessage(message); - } - else { - return client.sendMessage(message, readTimeout); - } - } - catch(HostUnavailableException e) { - error_msg = ERROR_HOST_UNAVAILABLE; - error_msg += ":\n"; - error_msg += MapDaemon.returnStackTrace(e); - } - catch(EmptyResponseException e) { - error_msg = ERROR_EMPTY_RESPONSE; - error_msg += ":\n"; - error_msg += MapDaemon.returnStackTrace(e); - } - catch(Exception e) { - error_msg = ERROR_GENERAL_ERROR; - error_msg += ":\n"; - error_msg += MapDaemon.returnStackTrace(e); - } - //If we've gotten this far, we have a magical problem - ByondResponse error_resp = new ByondResponse(); - error_resp.setResponseType(ResponseType.STRING); - error_resp.setResponseData(error_msg); - return error_resp; - } - - /** - * Calls RecieveByondResponse(command, -1), which just uses the default (1000 ms) read timeout - * @param command The command to execute server-side - * @return The recieved message as a ByondResponse object. - */ - public ByondResponse RecieveByondResponse(String command) { - return RecieveByondResponse(command, -1); //Make it use the default - } -} diff --git a/tools/MapDaemon/source_files/Tester.java b/tools/MapDaemon/source_files/Tester.java deleted file mode 100644 index e5daa296324d..000000000000 --- a/tools/MapDaemon/source_files/Tester.java +++ /dev/null @@ -1,235 +0,0 @@ -package map_daemon; - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.json.JSONObject; - -import io.github.spair.byond.message.ByondMessage; -import io.github.spair.byond.message.ServerAddress; -import io.github.spair.byond.message.client.ByondClient; -import io.github.spair.byond.message.response.ByondResponse; - -@SuppressWarnings("unused") -public class Tester { - - public static void main(String[] args) { - new Tester(); - } - - public Tester() { - //testConfigRetrieval(); - //testCrashLogger(); - //testTextReceive(); - //testCompilingFromShell(); - testMessaging(); - //testDisabler(); - //testGamemodeFile("LV-624"); - //testCopyRSC(); - //testGetIceColony(); - } - - private void testGetIceColony() { - Config config = new Config("C:\\Users\\Sam\\Desktop\\MapDaemonExecutables\\config.json"); - System.out.println(config.getStringFromConfig("game\\maps\\" + "Ice Colony ")); - } - - private void testCMDCopyFile() { - try { - CMDCopyFile("C:\\Users\\Sam\\Desktop\\CM branches\\Unfucked\\ColonialMarinesALPHA.rsc", "C:\\Users\\Sam\\Desktop\\MapDaemonExecutables\\ColonialMarinesALPHA.rsc"); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private void CMDCopyFile(String source, String destination) throws Exception { - String command = "cmd.exe /C copy \"" + source + "\" \"" + destination + "\" /Y"; - System.out.println(command); - Process p = null; - try { - p = Runtime.getRuntime().exec(command); - } catch (Exception e) { - throw e; - } - - try { - p.waitFor(15, TimeUnit.SECONDS); - } catch (Exception e) { - throw e; - } - - String data = ""; - BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); - try { - while(reader.ready()) { - data += reader.readLine(); - data += "\n"; - } - } catch (Exception e) { - throw e; - } - - int index = data.indexOf(" file(s) copied"); - if(!data.substring(index-1, index).equals("1")) { - throw new Exception("Could not copy " + source + "using data:\n\n" + data); - } - - System.out.println(data); - } - - private void testCopyRSC() { - try { - Files.copy(Paths.get("C:/Users/Sam/Desktop/CM branches/Unfucked/ColonialMarinesALPHA.rsc"), - Paths.get("C:/Users/Sam/Desktop/MapDaemonExecutables/ColonialMarinesALPHA.rsc"), - StandardCopyOption.REPLACE_EXISTING); - } - catch(Exception e) { - e.printStackTrace(); - } - } - - private void testGamemodeFile(String map) { - try { - System.out.println(Files.readAllLines(Paths.get("C:\\Users\\Sam\\Desktop\\MapDaemonExecutables\\data\\mode.txt")).get(0)); - Files.write(Paths.get("C:\\Users\\Sam\\Desktop\\MapDaemonExecutables\\data\\mode.txt"), map.getBytes()); - System.out.println(Files.readAllLines(Paths.get("C:\\Users\\Sam\\Desktop\\MapDaemonExecutables\\data\\mode.txt")).get(0)); - return; - } - catch(Exception e) { - e.printStackTrace(); - } - } - - private void testDisabler() { - List lines = null; - try { - lines = Files.readAllLines(Paths.get("C:\\Users\\Sam\\Desktop\\MapDaemonExecutables\\config.json")); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - String all_data = ""; - for(String s : lines) { - all_data += s; - } - JSONObject j = new JSONObject(all_data); - JSONObject j2 = j.getJSONObject("prefs"); - //boolean b = j2.getBoolean("enable"); - - Config config = new Config("C:\\Users\\Sam\\Desktop\\MapDaemonExecutables\\config.json"); - String yeet = config.getStringFromConfig("prefs\\enable"); - System.out.println(yeet); - boolean b = config.getBooleanFromConfig("prefs\\enable"); - System.out.println(b); - if(b) { - System.out.println("yeet was true"); - } - else { - System.out.println("yeet was false"); - } - if(yeet.equals("true")) { - System.out.println("but it was equal to true"); - } - } - - private void testCompilingFromShell() { - String command = "\"C:\\Program Files (x86)\\BYOND\\bin\\dm.exe\" \"C:\\Users\\Sam\\Desktop\\CM branches\\Unfucked\\ColonialMarinesALPHA.dme\""; - Process p = null; - try { - p = Runtime.getRuntime().exec(command); - } catch (IOException e) { - e.printStackTrace(); - } - try { - p.waitFor(5, TimeUnit.MINUTES); - } catch (InterruptedException e) { - e.printStackTrace(); - } - BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); - String data = ""; - try { - while(reader.ready()) { - data += reader.readLine(); - data += "\n"; - } - } catch (IOException e) { - e.printStackTrace(); - } - System.out.println(p.isAlive()); - System.out.println(data); - } - - private void testTextReceive() { - ByondClient client = new ByondClient(); - ByondMessage message = new ByondMessage(new ServerAddress("play.colonial-marines.com", 1400), "?status"); - ByondResponse response = client.sendMessage(message); - System.out.println(response); - } - - private void testMessaging() { - ByondClient client = new ByondClient(); - ByondMessage message = new ByondMessage(new ServerAddress("localhost", 5001), "?ping"); - ByondResponse response = client.sendMessage(message); - System.out.println(response); - } - - private void testJSONWhitespace() { - JSONObject j = new JSONObject("{ path:\"r u kiddin me bud\",vvvv:\n\"testying\"}"); - System.out.println(j.toString()); - System.out.println(j.getString("path")); - System.out.println(j.getString("vvvv")); - } - - private void testStringSplit() { - String s = "aaa\\bbb\\ccc"; - //String[] a = s.split("\\"); - String[] b = s.split("\\\\"); - //System.out.println(a); - for(String c : b) { - System.out.println(c); - } - } - - private void testConfigRetrieval() { - Config c = new Config("C:\\Users\\Sam\\Desktop\\WatchDogStorage\\config.json"); - String s = c.getStringFromConfig("paths\\a\\b\\c"); - System.out.println(s); - } - - private void testToStringLinkedList() { - LinkedList l = new LinkedList(); - l.add("a"); - l.add("b"); - l.add("c"); - l.add("d"); - System.out.println(l.toString()); - } - - private void testCrashLogger() { - //CrashLogger cl = new CrashLogger("C:\\Users\\Sam\\Desktop\\WatchDogStorage\\logs"); - //cl.addLine("Important info"); - //cl.addLine("more important stuff"); - //cl.close(true); - } -} - - - - - - - - - - - - - diff --git a/tools/ci/build_tgui.sh b/tools/ci/build_tgui.sh new file mode 100644 index 000000000000..29a05dd35ae7 --- /dev/null +++ b/tools/ci/build_tgui.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -euo pipefail + +## Change to project root relative to the script +cd "$(dirname "${0}")/../.." +base_dir="$(pwd)" + +## The final authority on what's required to fully build the project +source dependencies.sh + +## Setup NVM +if [[ -e ~/.nvm/nvm.sh ]]; then + source ~/.nvm/nvm.sh + nvm use "${NODE_VERSION}" +fi + +echo "Building 'tgui'" +cd "${base_dir}/tgui" +bash bin/tgui --ci diff --git a/tools/ci/dm.sh b/tools/ci/dm.sh new file mode 100644 index 000000000000..ea432fa5acb5 --- /dev/null +++ b/tools/ci/dm.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +dmepath="" +retval=1 + +for var +do + if [[ $var != -* && $var == *.dme ]] + then + dmepath=`echo $var | sed -r 's/.{4}$//'` + break + fi +done + +if [[ $dmepath == "" ]] +then + echo "No .dme file specified, aborting." + exit 1 +fi + +if [[ -a $dmepath.mdme ]] +then + rm $dmepath.mdme +fi + +cp $dmepath.dme $dmepath.mdme +if [[ $? != 0 ]] +then + echo "Failed to make modified dme, aborting." + exit 2 +fi + +for var +do + arg=`echo $var | sed -r 's/^.{2}//'` + if [[ $var == -D* ]] + then + sed -i '1s/^/#define '$arg'\n/' $dmepath.mdme + continue + fi +done + +#windows +if [[ `uname` == MINGW* ]] +then + dm="" + + if hash dm.exe 2>/dev/null + then + dm='dm.exe' + elif [[ -a '/c/Program Files (x86)/BYOND/bin/dm.exe' ]] + then + dm='/c/Program Files (x86)/BYOND/bin/dm.exe' + elif [[ -a '/c/Program Files/BYOND/bin/dm.exe' ]] + then + dm='/c/Program Files/BYOND/bin/dm.exe' + fi + + if [[ $dm == "" ]] + then + echo "Couldn't find the DreamMaker executable, aborting." + exit 3 + fi + + "$dm" $dmepath.mdme 2>&1 | tee result.log + retval=$? + if ! grep '\- 0 errors, 0 warnings' result.log + then + retval=1 #hard fail, due to warnings or errors + fi +else + if hash DreamMaker 2>/dev/null + then + DreamMaker -max_errors 0 $dmepath.mdme 2>&1 | tee result.log + retval=$? + if ! grep '\- 0 errors, 0 warnings' result.log + then + retval=1 #hard fail, due to warnings or errors + fi + else + echo "Couldn't find the DreamMaker executable, aborting." + exit 3 + fi +fi + +mv $dmepath.mdme.dmb $dmepath.dmb +mv $dmepath.mdme.rsc $dmepath.rsc + +rm $dmepath.mdme + +exit $retval diff --git a/tools/ci/install_build_tools.sh b/tools/ci/install_build_tools.sh new file mode 100644 index 000000000000..64d1c747ae4b --- /dev/null +++ b/tools/ci/install_build_tools.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -euo pipefail + +source dependencies.sh + +source ~/.nvm/nvm.sh +nvm install $NODE_VERSION + +echo "nvm installed node" + +nvm use $NODE_VERSION + +echo "nvm done" + +npm install --global yarn + +echo "npm done" + +pip3 install --user PyYaml +pip3 install --user beautifulsoup4 + + diff --git a/tools/ci/install_byond.sh b/tools/ci/install_byond.sh new file mode 100644 index 000000000000..4a688755d3d9 --- /dev/null +++ b/tools/ci/install_byond.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -euo pipefail + +source dependencies.sh + +if [ -d "$HOME/BYOND/byond/bin" ] && grep -Fxq "${BYOND_MAJOR}.${BYOND_MINOR}" $HOME/BYOND/version.txt; +then + echo "Using cached directory." +else + echo "Setting up BYOND." + rm -rf "$HOME/BYOND" + mkdir -p "$HOME/BYOND" + cd "$HOME/BYOND" + curl "http://www.byond.com/download/build/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -o byond.zip + unzip byond.zip + rm byond.zip + cd byond + make here + echo "$BYOND_MAJOR.$BYOND_MINOR" > "$HOME/BYOND/version.txt" + cd ~/ +fi diff --git a/tools/ci/install_spaceman_dmm.sh b/tools/ci/install_spaceman_dmm.sh new file mode 100644 index 000000000000..39464193f889 --- /dev/null +++ b/tools/ci/install_spaceman_dmm.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -euo pipefail + +source dependencies.sh + +wget -O ~/$1 "https://github.com/SpaceManiac/SpacemanDMM/releases/download/$SPACEMAN_DMM_VERSION/$1" +chmod +x ~/$1 +~/$1 --version diff --git a/tools/ci/template_dm_generator.py b/tools/ci/template_dm_generator.py new file mode 100644 index 000000000000..83c902170dcf --- /dev/null +++ b/tools/ci/template_dm_generator.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +import os +import sys + +folders = ["maps/interiors", "maps/Nightmare", "maps/predship"] + +generated = "maps/templates.dm" + +template_filenames = [] + +def find_dm(path): + L = [] + for dirpath, dirnames, filenames in os.walk(path): + for name in filenames: + if name.endswith(".dmm"): + s = os.path.join(dirpath, name) + s = s.replace("maps/","") + L.append(s) + return L + +for folder in folders: + template_filenames.extend(find_dm(folder)) + +with open(generated, 'w') as f: + for template in template_filenames: + f.write('''#include "{}"\n'''.format(template)) + diff --git a/tools/json_verifier.py b/tools/json_verifier.py new file mode 100644 index 000000000000..aa746206674c --- /dev/null +++ b/tools/json_verifier.py @@ -0,0 +1,20 @@ +import sys +import json + +if len(sys.argv) <= 1: + exit(1) + +status = 0 + +for file in sys.argv[1:]: + with open(file, encoding="ISO-8859-1") as f: + try: + json.load(f) + except ValueError as exception: + print("JSON error in {}".format(file)) + print(exception) + status = 1 + else: + print("Valid {}".format(file)) + +exit(status)
CallResponse