diff --git a/baystation12.dme b/baystation12.dme index 8d9e9b1cccc1b..72a1ad4e9fb52 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -235,6 +235,7 @@ #include "code\controllers\subsystems\initialization\culture.dm" #include "code\controllers\subsystems\initialization\customitems.dm" #include "code\controllers\subsystems\initialization\fabrication.dm" +#include "code\controllers\subsystems\initialization\icon_updates.dm" #include "code\controllers\subsystems\initialization\materials.dm" #include "code\controllers\subsystems\initialization\misc.dm" #include "code\controllers\subsystems\initialization\misc_early.dm" @@ -248,7 +249,6 @@ #include "code\controllers\subsystems\processing\disposals.dm" #include "code\controllers\subsystems\processing\fast_process.dm" #include "code\controllers\subsystems\processing\graphs.dm" -#include "code\controllers\subsystems\processing\icon_updates.dm" #include "code\controllers\subsystems\processing\nano.dm" #include "code\controllers\subsystems\processing\obj.dm" #include "code\controllers\subsystems\processing\processing.dm" @@ -3374,6 +3374,7 @@ #include "mods\_master_files\code\modules\culture_descriptor\religion\religions_vox.dm" #include "mods\_master_files\code\modules\events\gravity.dm" #include "mods\_master_files\code\modules\mob\living\life.dm" +#include "mods\_master_files\code\modules\mob\living\carbon\human\human_helpers.dm" #include "mods\_master_files\code\modules\mob\new_player\new_player.dm" #include "mods\_master_files\code\modules\overmap\distress.dm" #include "mods\_master_files\code\modules\overmap\panicbutton.dm" diff --git a/code/__defines/skills.dm b/code/__defines/skills.dm index 60e9e46b36b85..09b9ebc266632 100644 --- a/code/__defines/skills.dm +++ b/code/__defines/skills.dm @@ -39,3 +39,4 @@ #define SKILL_MEDICAL /singleton/hierarchy/skill/medical/medical #define SKILL_ANATOMY /singleton/hierarchy/skill/medical/anatomy #define SKILL_CHEMISTRY /singleton/hierarchy/skill/medical/chemistry +#define SKILL_VIROLOGY /singleton/hierarchy/skill/medical/chemistry/virology diff --git a/code/__defines/subsystem-priority.dm b/code/__defines/subsystem-priority.dm index 0ff61b820047b..648fc926998c8 100644 --- a/code/__defines/subsystem-priority.dm +++ b/code/__defines/subsystem-priority.dm @@ -12,7 +12,7 @@ // SS_TICKER #define SS_PRIORITY_TIMER 30 #define SS_PRIORITY_OVERLAYS 20 -#define SS_PRIORITY_ICON_UPDATE 10 + // Normal #define SS_PRIORITY_TICKER 100 // Gameticker. @@ -27,6 +27,7 @@ #define SS_PRIORITY_CHAT 40 // Chat #define SS_PRIORITY_AI 25 // Mob AI #define SS_PRIORITY_ALARM 20 // Alarm processing. +#define SS_PRIORITY_ICON_UPDATE 20 // Queued icon updates. Mostly used by APCs and tables. #define SS_PRIORITY_EVENT 20 // Event processing and queue handling. #define SS_PRIORITY_SHUTTLE 20 // Shuttle movement. #define SS_PRIORITY_CIRCUIT_COMP 20 // Processing circuit component do_work. diff --git a/code/_helpers/medical_scans.dm b/code/_helpers/medical_scans.dm index 23c28d1ff400f..48407da9e0daa 100644 --- a/code/_helpers/medical_scans.dm +++ b/code/_helpers/medical_scans.dm @@ -51,7 +51,10 @@ scan["paralysis"] = H.paralysis scan["immune_system"] = H.virus_immunity() scan["worms"] = H.has_brain_worms() - +//SEIRAA-ADD [VIRUSOLOGY] + if (LAZYLEN(H.virus2)) + scan["virus"] = TRUE +//SEIRAA-ADD scan["reagents"] = list() if(H.reagents.total_volume) @@ -252,7 +255,13 @@ [SPAN_BAD("
Large growth detected in frontal lobe, possibly cancerous.
")] */ dat += "Antibody levels and immune system perfomance are at [scan["immune_system"]*100]% of baseline." - +//SIERRA ADD [VIRUSOLOGY] + if (scan["virus"]) + if(skill_level >= SKILL_TRAINED) + dat += "
Viral pathogen detected in blood stream.
" + else + dat += "
Viral pathogen detected in blood stream.
" +//SIERRA ADD if(scan["worms"]) dat += "[SPAN_BAD("
Large growth detected in frontal lobe, possibly cancerous.
")]" diff --git a/code/_helpers/turfs.dm b/code/_helpers/turfs.dm index 020549f4c852b..140d7dd8a7015 100644 --- a/code/_helpers/turfs.dm +++ b/code/_helpers/turfs.dm @@ -160,18 +160,20 @@ ChangeArea(target, get_area(source)) ChangeArea(source, base_area) transport_turf_contents(source, target) - //change the old turfs for(var/turf/source in translation) - source.ChangeTurf(base_turf ? base_turf : get_base_turf_by_area(source), 1, 1) +//[SIERRA-EDIT] Advanced Landing + var/old_turf = source.prev_type || base_turf || get_base_turf_by_area(source) + source.ChangeTurf(old_turf) +//[/SIERRA-EDIT] Advanced Landing //Transports a turf from a source turf to a target turf, moving all of the turf's contents and making the target a copy of the source. /proc/transport_turf_contents(turf/source, turf/target) RETURN_TYPE(/turf) - + var/target_type = target.type //[/SIERRA-ADD] Advanced Landing var/turf/new_turf = target.ChangeTurf(source.type, 1, 1) new_turf.transport_properties_from(source) - + new_turf.prev_type = target_type //[/SIERRA-ADD] Advanced Landing for(var/obj/O in source) if (QDELETED(O)) testing("Failed to translate [O] to new turf as it was qdel'd.") diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 01c4dbf6c6c98..58e1ca37c441a 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -382,4 +382,19 @@ /obj/screen/movement/Click(location, control, params) if(istype(usr)) + var/list/modifiers = params2list(params) + if(modifiers["ctrl"]) + usr?.face_direction() + update_icon() + return + usr.set_next_usable_move_intent() + +/obj/screen/movement/on_update_icon() + . = ..() + var/image/chached_fixeye = image('packs/infinity/icons/mob/screen/facedir.dmi', icon_state = "facedir1") + if(!isnull(usr?.facing_dir)) + src.dir = usr?.facing_dir + AddOverlays(chached_fixeye) + else + ClearOverlays() diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 8e2210475c668..2011fcf541bb5 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -53,7 +53,7 @@ avoid code duplication. This includes items that may sometimes act as a standard use_call = "use" . = use_before(atom, user, click_params) - if (!. && user.a_intent == I_HURT) + if (!. && (user.a_intent == I_HURT || user.a_intent == I_DISARM)) use_call = "weapon" . = atom.use_weapon(src, user, click_params) if (!.) diff --git a/code/controllers/subsystems/initialization/icon_updates.dm b/code/controllers/subsystems/initialization/icon_updates.dm new file mode 100644 index 0000000000000..6434ad1e889e4 --- /dev/null +++ b/code/controllers/subsystems/initialization/icon_updates.dm @@ -0,0 +1,79 @@ +SUBSYSTEM_DEF(icon_update) + name = "Icon Updates" + wait = 1 + priority = SS_PRIORITY_ICON_UPDATE + init_order = SS_INIT_ICON_UPDATE + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT // If you make it not fire in lobby, you also have to remove atoms from queue in Destroy. + + // Linked lists, queue_refs[x] should have null or args stored in queue_args[x] + var/list/queue_refs = list() // Atoms + var/list/queue_args = list() // null or args + + +/datum/controller/subsystem/icon_update/UpdateStat(time) + if (PreventUpdateStat(time)) + return ..() + ..("queue: [length(queue_refs)]") + + +/datum/controller/subsystem/icon_update/Initialize(start_uptime) + fire(FALSE, TRUE) + + +/datum/controller/subsystem/icon_update/fire(resumed = FALSE, no_mc_tick = FALSE) + if(!queue_refs.len) + suspend() + return + + while (queue_refs.len) + + if(Master.map_loading) + return + + // Pops the atom and it's args + var/atom/A = queue_refs[queue_refs.len] + var/myArgs = queue_args[queue_args.len] + + queue_refs.len -= 1 + queue_args.len -= 1 + + if(QDELETED(A)) + continue + + A.icon_update_queued = FALSE + + if (islist(myArgs)) + A.update_icon(arglist(myArgs)) + else + A.update_icon() + + if (no_mc_tick) + CHECK_TICK + else if (MC_TICK_CHECK) + return + +/atom + var/icon_update_queued = FALSE + +/atom/proc/queue_icon_update(...) + // Skips if this is already queued + if(!icon_update_queued) + + icon_update_queued = TRUE + SSicon_update.queue_refs.Add(src) + + // Makes sure these are in sync, in case runtimes/badmin + var/length = length(SSicon_update.queue_refs) + SSicon_update.queue_args.len = length + SSicon_update.queue_args[length] = args.len ? args : null + + // SSicon_update sleeps when it runs out of things in its + // queue, so wake it up. + if(!Master.map_loading) // Don't wake early if we're loading a map, it'll get woken up when the map loads. + SSicon_update.wake() + +/datum/controller/subsystem/icon_update/StartLoadingMap() + suspend() + +/datum/controller/subsystem/icon_update/StopLoadingMap() + wake() diff --git a/code/controllers/subsystems/processing/icon_updates.dm b/code/controllers/subsystems/processing/icon_updates.dm deleted file mode 100644 index 6990045ef69f7..0000000000000 --- a/code/controllers/subsystems/processing/icon_updates.dm +++ /dev/null @@ -1,62 +0,0 @@ -SUBSYSTEM_DEF(icon_update) - name = "Icon Updates" - wait = 1 // ticks - flags = SS_TICKER - priority = SS_PRIORITY_ICON_UPDATE - init_order = SS_INIT_ICON_UPDATE - var/static/list/queue = list() - - -/datum/controller/subsystem/icon_update/Recover() - LIST_RESIZE(queue, 0) - queue = list() - - -/datum/controller/subsystem/icon_update/UpdateStat(time) - if (PreventUpdateStat(time)) - return ..() - ..("queue: [length(queue)]") - - -/datum/controller/subsystem/icon_update/Initialize(start_uptime) - fire(FALSE, TRUE) - - -/datum/controller/subsystem/icon_update/fire(resumed, no_mc_tick) - var/atom/atom - var/list/params - var/queue_length = length(queue) - for (var/i = 1 to queue_length) - atom = queue[i] - if (QDELETED(atom)) - continue - params = queue[atom] - if (islist(params)) - atom.update_icon(arglist(params)) - else - atom.update_icon() - if (no_mc_tick) - if (i % 100) - continue - CHECK_TICK - else if (MC_TICK_CHECK) - queue.Cut(1, i + 1) - return - if (queue_length) - queue.Cut(1, queue_length + 1) - suspend() - - -/** - * Adds the atom to the icon_update subsystem to be queued for icon updates. Use this if you're going to be pushing a - * lot of icon updates at once. - */ -/atom/proc/queue_icon_update(...) - SSicon_update.queue[src] = length(args) ? args : TRUE - if (SSicon_update.suspended) - SSicon_update.wake() - - -/hook/game_ready/proc/FlushIconUpdateQueue() - SSicon_update.fire(FALSE, TRUE) - return TRUE diff --git a/code/controllers/subsystems/supply.dm b/code/controllers/subsystems/supply.dm index ac247fdd12a42..e31b3d8f6505b 100644 --- a/code/controllers/subsystems/supply.dm +++ b/code/controllers/subsystems/supply.dm @@ -27,6 +27,11 @@ SUBSYSTEM_DEF(supply) "crate" = "From exported crates", "gep" = "From uploaded good explorer points", "anomaly" = "From scanned and categorized anomalies", + +//SIERRA-ADD VIRUSOLOGY + "virology_antibodies" = "From uploaded antibody data", + "virology_dishes" = "From exported virus dishes", +//SIERRA-ADD "animal" = "From captured exotic alien fauna", //[SIERRA-ADD] - ANOMALY - Добавляем категорию "Артефакты" "artefacts" = "From artefacts", @@ -121,13 +126,25 @@ SUBSYSTEM_DEF(supply) if(istype(A, /obj/item/disk/survey)) var/obj/item/disk/survey/D = A add_points_from_source(round(D.Value() * 0.05), "gep") +//SIERRA-ADD VIRUSOLOGY + // Sell virus dishes. + if(istype(A, /obj/item/virusdish)) + //Obviously the dish must be unique and never sold before. + var/obj/item/virusdish/dish = A + if(dish.analysed && istype(dish.virus2) && dish.virus2.uniqueID) + if(!(dish.virus2.uniqueID in sold_virus_strains)) + add_points_from_source(5, "virology_dishes") + sold_virus_strains += dish.virus2.uniqueID +//SIERRA-ADD //[SIERRA-ADD] - ANOMALY - Продажа артефактов if(istype(A, /obj/item/artefact)) var/obj/item/artefact/D = A add_points_from_source(D.cargo_price, "artefacts") + SSanom.earned_cargo_points += D.cargo_price if(istype(A, /obj/item/collector)) var/obj/item/collector/D = A add_points_from_source(D.stored_artefact.cargo_price, "artefacts") + SSanom.earned_cargo_points += D.stored_artefact.cargo_price //[SIERRA-ADD] // Sell artefacts (in anomaly cages) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 063abf86150b9..eb2441ba374a0 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -329,6 +329,13 @@ var/global/list/additional_antag_types = list() if(client.mob && client.mob.mind) client.mob.mind.show_roundend_summary(departmental_goal_summary) + //[SIERRA-ADD] - ANOMALY + //Данный отрезок кода выведет информацию об моде АНОМАЛИИ в раунде + var/anomaly_output = SSanom.give_gameover_text() + if(anomaly_output) + text += anomaly_output + //[SIERRA-ADD] + to_world(text) send2mainirc("A round of [src.name] has ended - [data["surviving_total"]] survivor\s, [data["ghosts"]] ghost\s.") diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm index 9750035bfde0c..6310436365206 100644 --- a/code/game/machinery/embedded_controller/airlock_program.dm +++ b/code/game/machinery/embedded_controller/airlock_program.dm @@ -252,6 +252,7 @@ cycleDoors(target_state) state = STATE_IDLE target_state = TARGET_NONE + playsound(master, 'sound/machines/airlockdone.ogg', 50) if(STATE_DEPRESSURIZE) @@ -271,6 +272,7 @@ cycleDoors(target_state) state = STATE_IDLE target_state = TARGET_NONE + playsound(master, 'sound/machines/airlockdone.ogg', 50) memory["processing"] = (state != target_state) @@ -283,20 +285,20 @@ state = STATE_IDLE target_state = TARGET_INOPEN memory["purge"] = cycle_to_external_air - playsound(master, 'sound/machines/warning-buzzer.ogg', 50) + playsound(master, 'sound/machines/airlockin.ogg', 50) shutAlarm() /datum/computer/file/embedded_program/airlock/proc/begin_dock_cycle() state = STATE_IDLE target_state = TARGET_INOPEN - playsound(master, 'sound/machines/warning-buzzer.ogg', 50) + playsound(master, 'sound/machines/airlockin.ogg', 50) shutAlarm() /datum/computer/file/embedded_program/airlock/proc/begin_cycle_out() state = STATE_IDLE target_state = TARGET_OUTOPEN memory["purge"] = cycle_to_external_air - playsound(master, 'sound/machines/warning-buzzer.ogg', 50) + playsound(master, 'sound/machines/airlockout.ogg', 50) shutAlarm() /datum/computer/file/embedded_program/airlock/proc/close_doors() diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index 23b1f99624145..3502bc6c8b179 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -90,8 +90,7 @@ req_access = list(access_virology) icon_contents = "chem" accepted_types = list( - /obj/item/reagent_containers/glass/beaker/vial - ) + /obj/item/reagent_containers/glass/beaker/vial, /obj/item/virusdish) //SIERRA-ADDED VIRUSOLOGY /obj/machinery/smartfridge/chemistry name = "\improper Smart Chemical Storage" diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibs.dm index 63fe2c56657b1..76918d8a27df2 100644 --- a/code/game/objects/effects/gibs.dm +++ b/code/game/objects/effects/gibs.dm @@ -9,6 +9,7 @@ var/fleshcolor //Used for gibbed humans. var/bloodcolor //Used for gibbed humans. var/datum/dna/MobDNA + var/virusProb = 20 //the chance for viruses to spread on the gibs [SIERRA-ADD] VIRUSOLOGY /obj/gibspawner/New(location, datum/dna/_MobDNA, _fleshcolor, _bloodcolor) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index c08685765ebbd..4cabaa3a2cce4 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -165,6 +165,12 @@ return TRUE return FALSE + +/obj/item/update_icon() + ..() + update_twohanding() + + /obj/item/ex_act(severity) ..() if (get_max_health()) @@ -555,6 +561,9 @@ var/global/list/slot_flags_enumeration = list( var/parry_chance = get_parry_chance(user, attacker) if(parry_chance) if(default_parry_check(user, attacker, damage_source) && prob(parry_chance)) + //[SIERRA-ADD] + user.dodge_animation(attacker = attacker) + //[SIERRA-ADD user.visible_message(SPAN_DANGER("\The [user] parries [attack_text] with \the [src]!")) admin_attack_log(attacker, user, "Attempted to attack with \a [damage_source] but was parried", "Was targeted with \a [damage_source] but parried the attack", "attmpted to use \a [damage_source] to attack but was parried by") playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1) diff --git a/code/game/objects/items/devices/oxycandle.dm b/code/game/objects/items/devices/oxycandle.dm index cfcccb79f8c9a..66b519271d9e5 100644 --- a/code/game/objects/items/devices/oxycandle.dm +++ b/code/game/objects/items/devices/oxycandle.dm @@ -47,7 +47,6 @@ STOP_PROCESSING(SSprocessing, src) on = 2 update_icon() - update_held_icon() SetName("burnt oxygen candle") desc += "This tube has exhausted its chemicals." return @@ -79,7 +78,6 @@ icon_state = "oxycandle" item_state = icon_state set_light(0) - update_held_icon() /obj/item/device/oxycandle/Destroy() QDEL_NULL(air_contents) diff --git a/code/game/objects/items/devices/paint_sprayer.dm b/code/game/objects/items/devices/paint_sprayer.dm index 27d9c5047d94e..77455ef03a83b 100644 --- a/code/game/objects/items/devices/paint_sprayer.dm +++ b/code/game/objects/items/devices/paint_sprayer.dm @@ -83,7 +83,6 @@ /obj/item/device/paint_sprayer/on_update_icon() ClearOverlays() AddOverlays(overlay_image(icon, "paint_sprayer_color", paint_color)) - update_held_icon() /obj/item/device/paint_sprayer/get_mob_overlay(mob/user_mob, slot, bodypart) var/image/ret = ..() diff --git a/code/game/objects/items/devices/scanners/health.dm b/code/game/objects/items/devices/scanners/health.dm index 4a648dd9b0852..dfd7a898621a0 100644 --- a/code/game/objects/items/devices/scanners/health.dm +++ b/code/game/objects/items/devices/scanners/health.dm @@ -287,6 +287,14 @@ chemtraces += "[initial(R.name)] ([H.chem_doses[T]])" if(length(chemtraces)) . += SPAN_CLASS("scan_notice", "Metabolism products of [english_list(chemtraces)] found in subject's system.") +//SIERRA-ADD VIRUSOLOGY + if(LAZYLEN(H.virus2)) + for (var/ID in H.virus2) + if (ID in virusDB) + print_reagent_default_message = FALSE + var/datum/computer_file/data/virus_record/V = virusDB[ID] + . += "Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]" +//SIERRA-ADD if(print_reagent_default_message) . += "No results." diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index f84331d8aca00..04f03a56ca630 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -245,7 +245,6 @@ else wielded = 0 SetName(initial(name)) - update_icon() ..() /obj/item/shockpaddles/on_update_icon() diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm index 326934d106ffd..2963bd6353692 100644 --- a/code/game/objects/items/weapons/material/twohanded.dm +++ b/code/game/objects/items/weapons/material/twohanded.dm @@ -37,7 +37,6 @@ else wielded = 0 force = force_unwielded - update_icon() ..() /obj/item/material/twohanded/update_force() diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index adb5714b28cfa..ad243fb5c701c 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -63,7 +63,6 @@ playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) add_fingerprint(user) update_icon() - update_held_icon() /obj/item/melee/telebaton/on_update_icon() if(on) diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 7b6c238a86780..d184e1373c660 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -143,6 +143,9 @@ B.blood_DNA = list() if(!B.blood_DNA[M.dna.unique_enzymes]) B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type +//SIERRA-ADD VIRUSOLOGY + B.virus2 = virus_copylist(M.virus2) +//SIERRA-ADD return 1 //we bloodied the floor blood_splatter(src,M.get_blood(M.vessel),1) return 1 //we bloodied the floor diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index f953c7baaa02e..7fd8e6ac516af 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -147,6 +147,7 @@ var/global/list/admin_verbs_spawn = list( /client/proc/spawn_chemdisp_cartridge, // [SIERRA-ADD] - CLIENT_VERBS - , /client/proc/respawn_as_self, + /client/proc/virus2_editor, // [/SIERRA-ADD] - CLIENT_VERBS , /datum/admins/proc/mass_debug_closet_icons ) diff --git a/code/modules/admin/view_variables/helpers.dm b/code/modules/admin/view_variables/helpers.dm index 971e7187adb64..b4bf22260dad7 100644 --- a/code/modules/admin/view_variables/helpers.dm +++ b/code/modules/admin/view_variables/helpers.dm @@ -44,6 +44,8 @@ + + @@ -164,7 +166,7 @@ // The following vars require R_DEBUG to edit /datum/proc/VV_locked() - return list("vars", "cuffed") + return list("vars", "virus", "viruses", "cuffed") //[SIEERA EDIT] /client/VV_locked() return list("vars", "mob") diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index aa8b6e2229d38..1c623573bde20 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -107,6 +107,18 @@ src.give_spell(M) href_list["datumrefresh"] = href_list["give_spell"] +//[SIERRA-ADD] VIRUSOLOGY + else if(href_list["give_disease2"]) + if(!check_rights(R_ADMIN|R_FUN)) return + + var/mob/M = locate(href_list["give_disease2"]) + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + src.give_disease2(M) + href_list["datumrefresh"] = href_list["give_spell"] +//[/SIERRA-ADD] VIRUSOLOGY else if(href_list["godmode"]) if(!check_rights(R_REJUVINATE)) return diff --git a/code/modules/client/preference_setup/global/preferences.dm b/code/modules/client/preference_setup/global/preferences.dm index 939c29b4cb6c9..d91a794f4eff9 100644 --- a/code/modules/client/preference_setup/global/preferences.dm +++ b/code/modules/client/preference_setup/global/preferences.dm @@ -338,6 +338,13 @@ var/global/list/_client_preferences_by_type default_value = GLOB.PREF_SHORT +/datum/client_preference/toggle_run + description = "Shift toggles run (vs hold to run)" + key = "TOGGLE_RUN" + options = list(GLOB.PREF_YES, GLOB.PREF_NO) + default_value = GLOB.PREF_NO + + /******************** * General Staff Preferences * ********************/ diff --git a/code/modules/mechs/equipment/combat.dm b/code/modules/mechs/equipment/combat.dm index 89da797082398..18a97293b1697 100644 --- a/code/modules/mechs/equipment/combat.dm +++ b/code/modules/mechs/equipment/combat.dm @@ -92,7 +92,7 @@ toggle() playsound(owner.loc,'sound/mecha/internaldmgalarm.ogg',35,1) */ - owner.add_heat(difference) + owner.add_heat(difference * 2) if(difference >= 0) toggle() OVERHEAT = TRUE diff --git a/code/modules/mob/living/bot/medibot.dm b/code/modules/mob/living/bot/medibot.dm index 8797246c3a319..b4c120879a6e5 100644 --- a/code/modules/mob/living/bot/medibot.dm +++ b/code/modules/mob/living/bot/medibot.dm @@ -20,6 +20,7 @@ var/treatment_oxy = /datum/reagent/tricordrazine var/treatment_fire = /datum/reagent/tricordrazine var/treatment_tox = /datum/reagent/tricordrazine + var/treatment_virus = /datum/reagent/spaceacillin var/treatment_emag = /datum/reagent/toxin var/declare_treatment = 0 //When attempting to treat a patient, should it notify everyone wearing medhuds? diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 451db3156ef38..723584fd49958 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -386,6 +386,10 @@ if(now_pushing || !yes) return ..() + //[SIERRA-ADD] VIRUSOLOGY + if(istype(AM, /mob/living/carbon) && prob(10)) + src.spread_disease_to(AM, "Contact") + //[/SIERRA-ADD] VIRUSOLOGY /mob/living/carbon/slip(slipped_on, stun_duration = 8) if(!has_gravity()) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 9ff7c549fabc5..8d44287a24820 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -943,6 +943,11 @@ if(H.brainmob.mind) H.brainmob.mind.transfer_to(src) qdel(H) + //[SIERRA-ADD] VIRUSOLOGY + for (var/ID in virus2) + var/datum/disease2/disease/V = virus2[ID] + V.cure(src) + //[/SIERRA-ADD] losebreath = 0 diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 03317ede2e982..c9d7ee2f069fd 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -61,6 +61,11 @@ apply_effect(4, EFFECT_WEAKEN, armor_block) return +//[SIERRA-ADD] VIRUSOLOGY + if(istype(M,/mob/living/carbon)) + M.spread_disease_to(src, "Contact") +//[/SIERRA-ADD] VIRUSOLOGY + for (var/obj/item/grab/G in H) if (G.assailant == H && G.affecting == src) if(G.resolve_openhand_attack()) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 1c4da4029e33b..b5dbd48eb60b1 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -964,8 +964,16 @@ /mob/living/carbon/human/proc/handle_hud_list() + var/foundVirus = 0 //SIERRA-ADD if (GET_BIT(hud_updateflag, HEALTH_HUD) && hud_list[HEALTH_HUD]) var/image/holder = hud_list[HEALTH_HUD] +//SIERRA-ADD VIRUSOLOGY + for (var/ID in virus2) + if (ID in virusDB) + foundVirus = 1 + break + +//SIERRA-ADD if(stat == DEAD || status_flags & FAKEDEATH) holder.icon_state = "0" // X_X else if(is_asystole()) @@ -978,6 +986,10 @@ var/image/holder = hud_list[LIFE_HUD] if(stat == DEAD || status_flags & FAKEDEATH) holder.icon_state = "huddead" +//SIERRA-ADD VIRUSOLOGY + else if(foundVirus) + holder.icon_state = "hudill" +//SIERRA-ADD else holder.icon_state = "hudhealthy" hud_list[LIFE_HUD] = holder @@ -1001,6 +1013,10 @@ holder2.icon_state = "huddead" else if(has_brain_worms()) holder2.icon_state = "hudbrainworm" +//SIERRA-ADD VIRUSOLOGY + else if(foundVirus) + holder.icon_state = "hudill" +//SIERRA-ADD else holder2.icon_state = "hudhealthy" diff --git a/code/modules/mob/living/carbon/viruses.dm b/code/modules/mob/living/carbon/viruses.dm index 9f657c52aa5cf..ca6a3b1a0fb09 100644 --- a/code/modules/mob/living/carbon/viruses.dm +++ b/code/modules/mob/living/carbon/viruses.dm @@ -1,16 +1,69 @@ /mob/living/carbon var/immunity = 100 //current immune system strength +//[SIERRA-ADD] VIRUSOLOGY var/immunity_norm = 100 //it will regenerate to this value /mob/living/carbon/proc/handle_viruses() if(status_flags & GODMODE) return 0 //godmode + if(bodytemperature > 406) + for (var/ID in virus2) + var/datum/disease2/disease/V = virus2[ID] + V.cure(src) + if(life_tick % 3) //don't spam checks over all objects in view every tick. + for(var/obj/decal/cleanable/O in view(1,src)) + if(istype(O,/obj/decal/cleanable/blood)) + var/obj/decal/cleanable/blood/B = O + if(isnull(B.virus2)) + B.virus2 = list() + if(LAZYLEN(B.virus2)) + for (var/ID in B.virus2) + var/datum/disease2/disease/V = B.virus2[ID] + infect_virus2(src,V) + + else if(istype(O,/obj/decal/cleanable/mucus)) + var/obj/decal/cleanable/mucus/M = O + if(isnull(M.virus2)) + M.virus2 = list() + if(LAZYLEN(M.virus2)) + for (var/ID in M.virus2) + var/datum/disease2/disease/V = M.virus2[ID] + infect_virus2(src,V) + + if(LAZYLEN(virus2)) + for (var/ID in virus2) + var/datum/disease2/disease/V = virus2[ID] + if(isnull(V)) // Trying to figure out a runtime error that keeps repeating + CRASH("virus2 nulled before calling activate()") + else + V.process(src) + // activate may have deleted the virus + if(!V) continue + + // check if we're immune + var/list/common_antibodies = V.antigen & src.antibodies + if(LAZYLEN(common_antibodies)) + V.dead = 1 +//[/SIERRA-ADD] VIRUSOLOGY if(immunity > 0.2 * immunity_norm && immunity < immunity_norm) immunity = min(immunity + 0.25, immunity_norm) +//[SIERRA-ADD] VIRUSOLOGY + if(life_tick % 5 && immunity < 15 && chem_effects[CE_ANTIVIRAL] < VIRUS_COMMON && !LAZYLEN(virus2)) + var/infection_prob = 5 - immunity + var/turf/simulated/T = loc + if(istype(T)) + infection_prob += T.dirt + if(T.dirt >= 50) + if(prob(infection_prob)) + infect_mob_random_greater(src) + else + if(prob(infection_prob)) + infect_mob_random_lesser(src) +//[/SIERRA-ADD] VIRUSOLOGY /mob/living/carbon/proc/virus_immunity() var/antibiotic_boost = reagents.get_reagent_amount(/datum/reagent/spaceacillin) / (REAGENTS_OVERDOSE/2) return max(immunity/100 * (1+antibiotic_boost), antibiotic_boost) /mob/living/carbon/proc/immunity_weakness() - return max(2-virus_immunity(), 0) \ No newline at end of file + return max(2-virus_immunity(), 0) diff --git a/code/modules/mob/living/simple_animal/hostile/vagrant.dm b/code/modules/mob/living/simple_animal/hostile/vagrant.dm index d0b94a707501d..42c2e35bd82f0 100644 --- a/code/modules/mob/living/simple_animal/hostile/vagrant.dm +++ b/code/modules/mob/living/simple_animal/hostile/vagrant.dm @@ -28,13 +28,22 @@ var/blood_per_tick = 3 var/health_per_tick = 0.8 pass_flags = PASS_FLAG_TABLE - + var/datum/disease2/disease/carried //[SIERRA-ADD] VIRUSOLOGY bleed_colour = "#aad9de" ai_holder = /datum/ai_holder/hostile/melee/vagrant /datum/ai_holder/hostile/melee/vagrant + +//[SIERRA-ADD] VIRUSOLOGY +/mob/living/simple_animal/hostile/vagrant/Initialize() + . = ..() + if(prob(25)) + carried = new/datum/disease2/disease() + carried.makerandom(rand(2, 4)) +//[/SIERRA-ADD] VIRUSOLOGY + /datum/ai_holder/hostile/melee/vagrant/engage_target() if(ishuman(target)) var/mob/living/carbon/human/H = target @@ -53,7 +62,10 @@ H.Stun(1) H.visible_message(SPAN_DANGER("\the [holder] latches onto \the [H], pulsating!")) V.forceMove(V.gripping.loc) - + //[SIERRA-ADD] VIRUSOLOGY + if(V.carried && length(V.gripping.virus2) == 0) + infect_virus2(V.gripping, V.carried, 1) + //[/SIERRA-ADD] VIRUSOLOGY /mob/living/simple_animal/hostile/vagrant/Process_Spacemove() return 1 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 7de3edeeac4e8..72ef605ecb7a7 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -360,27 +360,47 @@ to_chat(src, "You will now default to [default_run_intent] when moving quickly.") /client/verb/setmovingslowly() - set hidden = 1 - if(mob) + set hidden = TRUE + if (!mob) + return + if (mob.get_preference_value(/datum/client_preference/toggle_run) == GLOB.PREF_NO) mob.set_moving_slowly() + /mob/proc/set_moving_slowly() - if(!default_walk_intent) + if (!default_walk_intent) default_walk_intent = get_movement_datum_by_missing_flag(MOVE_INTENT_QUICK) - if(default_walk_intent && move_intent != default_walk_intent) + if (default_walk_intent && move_intent != default_walk_intent) set_move_intent(default_walk_intent) + /client/verb/setmovingquickly() - set hidden = 1 - if(mob) + set hidden = TRUE + if (!mob) + return + if (mob.get_preference_value(/datum/client_preference/toggle_run) == GLOB.PREF_NO) mob.set_moving_quickly() + else + mob.toggle_moving_quickly() + /mob/proc/set_moving_quickly() - if(!default_run_intent) + if (!default_run_intent) default_run_intent = get_movement_datum_by_flag(MOVE_INTENT_QUICK) - if(default_run_intent && move_intent != default_run_intent) + if (default_run_intent && move_intent != default_run_intent) set_move_intent(default_run_intent) + +/mob/proc/toggle_moving_quickly() + var/quick = get_movement_datum_by_flag(MOVE_INTENT_QUICK) + if (move_intent == quick) + var/slow = get_movement_datum_by_missing_flag(MOVE_INTENT_QUICK) + if (slow && move_intent != slow) + set_move_intent(slow) + else if (quick) + set_move_intent(quick) + + /mob/proc/can_sprint() return FALSE diff --git a/code/modules/mob/skills/skill.dm b/code/modules/mob/skills/skill.dm index 307407d401360..cf9b7a63ed44d 100644 --- a/code/modules/mob/skills/skill.dm +++ b/code/modules/mob/skills/skill.dm @@ -336,3 +336,13 @@ GLOBAL_LIST_EMPTY(skills) "Trained" = "You can accurately measure out reagents, grind powders, and perform chemical reactions. You may still lose some product on occasion, but are unlikely to endanger yourself or those around you.
- You can fully operate the chem dispenser.", "Experienced" = "You work as a chemist, or else you are a doctor with training in chemistry. If you are a research chemist, you can create most useful chemicals; if you are a pharmacist, you can make most medications. At this stage, you're working mostly by-the-book. You can weaponize your chemicals by making grenades, smoke bombs, and similar devices.
- You can examine held containers for scannable reagents.", "Master" = "You specialized in chemistry or pharmaceuticals; you are either a medical researcher or professional chemist. You can create custom mixes and make even the trickiest of medications easily. You understand how your pharmaceuticals interact with the bodies of your patients. You are probably the originator of at least one new chemical innovation.
- You can examine held containers for all reagents.") + +/singleton/hierarchy/skill/medical/chemistry/virology + ID = "virology" + name = "Virology" + desc = "Virology requires a specialist to have not only a deep knowledge of viruses, but also the ability to work with them, similar to how a chemist works with chemicals. This means not only understanding chemical reactions and their effects, but also knowing how these reactions will affect the human body. Thus, a virologist must have not only knowledge of virology, but also medical skills. An analogy can be drawn with a medical chemist, who must have experience working with chemicals and understand what effect they will have in order to use them safely in medicine." + levels = list( "Unskilled" = "You know that virologist work with viruses; you know that they can be very dangerous. You probably know basic defence against viruses..", + "Trained" = "You can engeener viruses. You have some training in safety and you won't infect yourself while work... probably. You can almost safely use the virologist equipment.") + prerequisites = list(SKILL_CHEMISTRY = SKILL_TRAINED) + default_max = SKILL_BASIC + difficulty = SKILL_AVERAGE diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index daf8a3fd3e345..f928671171217 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -28,7 +28,12 @@ "blood_DNA" = dna.unique_enzymes, "blood_colour" = species.get_blood_colour(src), "blood_type" = dna.b_type, - "trace_chem" = null + "trace_chem" = null, +//SIERRA-ADD VIRUSOLOGY + "virus2" = list(), + "antibodies" = list() +//SIERRA-ADD + ) B.color = B.data["blood_colour"] @@ -208,6 +213,12 @@ data["trace_chem"] = temp_chem data["dose_chem"] = chem_doses.Copy() data["blood_colour"] = species.get_blood_colour(src) +//SIERRA-ADD VIRUSOLOGY + if (!data["virus2"]) + data["virus2"] = list() + data["virus2"] |= virus_copylist(virus2) + data["antibodies"] = antibodies +//SIERRA-ADD return data /proc/blood_splatter(target,datum/reagent/blood/source,large,spray_dir) @@ -264,6 +275,11 @@ B.blood_DNA[source.data["blood_DNA"]] = source.data["blood_type"] else B.blood_DNA[source.data["blood_DNA"]] = "O+" +//SIERRA-ADD VIRUSOLOGY + // Update virus information. + if(source.data["virus2"]) + B.virus2 = virus_copylist(source.data["virus2"]) +//SIERRA-ADD B.fluorescent = ATOM_FLOURESCENCE_NONE B.set_invisibility(0) diff --git a/code/modules/organs/internal/appendix.dm b/code/modules/organs/internal/appendix.dm index 38495e7c9a84d..a51b0c903340e 100644 --- a/code/modules/organs/internal/appendix.dm +++ b/code/modules/organs/internal/appendix.dm @@ -13,7 +13,12 @@ /obj/item/organ/internal/appendix/Process() ..() - if(inflamed && owner) +//[SIERRA-EDIT] + if(!owner) + return + owner.immunity = min(owner.immunity + 0.025, owner.immunity_norm) + if(inflamed) +//[SIERRA-EDIT] inflamed++ if(prob(5)) if(owner.can_feel_pain()) @@ -42,3 +47,19 @@ owner.adjustToxLoss(25) removed() qdel(src) + +//[SIERRA-ADD] +/obj/item/organ/internal/appendix/removed(mob/living/user, drop_organ=1, detach=1) + if(owner) + owner.immunity_norm -= 10 + ..() + +/obj/item/organ/internal/appendix/replaced(mob/living/carbon/human/target, obj/item/organ/external/affected) + ..() + if(owner) + owner.immunity_norm += 10 + +/obj/item/organ/internal/appendix/New(mob/living/carbon/holder) + ..() + if(owner) + owner.immunity_norm += 10 diff --git a/code/modules/overmap/exoplanets/_exoplanet.dm b/code/modules/overmap/exoplanets/_exoplanet.dm index e45f1bd1161d7..f3f20814d964e 100644 --- a/code/modules/overmap/exoplanets/_exoplanet.dm +++ b/code/modules/overmap/exoplanets/_exoplanet.dm @@ -137,6 +137,8 @@ GLOBAL_VAR(planet_repopulation_disabled) //[SIERRA-ADD] - ANOMALIES if(can_spawn_anomalies) generate_anomalies() + if(monitor_effect_type) + generate_monitor_effects() //[SIERRA-ADD] generate_landing(2) update_biome() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 2ea8e97817235..cd3c8df4c1252 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -508,7 +508,7 @@ update_icon(FALSE) sleep(rand(5, 15)) on = (get_status() == LIGHT_OK) - update_icon(0) + queue_icon_update(0) flickering = FALSE // ai attack - make lights flicker, because why not diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index f02aba7877412..1f003f9e71060 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -139,11 +139,6 @@ if(scope_zoom) verbs += /obj/item/gun/proc/scope -/obj/item/gun/update_twohanding() - if(one_hand_penalty) - update_icon() // In case item_state is set somewhere else. - ..() - /obj/item/gun/on_update_icon() var/mob/living/M = loc ClearOverlays() @@ -234,11 +229,8 @@ else Fire(target, user, pointblank = TRUE) return TRUE - // Point blank shooting if (user.a_intent == I_HURT && !user.isEquipped(target)) - if (safety()) // Pistol whip instead of unsafety+fire - return ..() Fire(target, user, pointblank = TRUE) return TRUE diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 5130aab4d790e..a2177b021e23a 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -94,7 +94,6 @@ icon_state = "[modifystate][ratio]" else icon_state = "[initial(icon_state)][ratio]" - update_held_icon() /obj/item/gun/energy/handle_post_fire(mob/user, atom/target, pointblank, reflex, obj/projectile) ..() diff --git a/code/modules/projectiles/guns/launcher/pneumatic.dm b/code/modules/projectiles/guns/launcher/pneumatic.dm index 23d913aec227a..f2b0f0cce4051 100644 --- a/code/modules/projectiles/guns/launcher/pneumatic.dm +++ b/code/modules/projectiles/guns/launcher/pneumatic.dm @@ -152,8 +152,6 @@ icon_state = "pneumatic" item_state = "pneumatic" - update_held_icon() - /obj/item/gun/launcher/pneumatic/small name = "small pneumatic cannon" desc = "It looks smaller than your garden variety cannon." diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index 54d14dab730b7..83f05e88d368b 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -7,6 +7,10 @@ "blood_colour" = COLOR_BLOOD_HUMAN, "trace_chem" = null, "dose_chem" = null, + //[SIERRA-ADD] VIRUSOLOGY + "virus2" = list(), + "antibodies" = list(), + //[/SIERRA-ADD] VIRUSOLOGY "has_oxy" = 1 ) name = "Blood" @@ -41,6 +45,15 @@ /datum/reagent/blood/get_data() // Just in case you have a reagent that handles data differently. var/t = data.Copy() +//SIERRA ADD VIRUSOLOGY + if(t["virus2"]) + var/list/v = t["virus2"] + t["virus2"] = v.Copy() + + if(t["antibodies"])//... and curing + var/list/v = t["antibodies"] + t["antibodies"] |= v.Copy() +//SIERRA ADD return t /datum/reagent/blood/touch_turf(turf/simulated/T) diff --git a/code/modules/reagents/reagent_containers/ivbag.dm b/code/modules/reagents/reagent_containers/ivbag.dm index 4b705abd14d02..8ec51db5120b0 100644 --- a/code/modules/reagents/reagent_containers/ivbag.dm +++ b/code/modules/reagents/reagent_containers/ivbag.dm @@ -281,7 +281,11 @@ "blood_type" = blood_type, "trace_chem" = null, "blood_species" = blood_species, - "blood_colour" = species.blood_color + "blood_colour" = species.blood_color, +//SIERRA-ADD MODPACK VIRUSOLOGY + "virus2" = list(), + "antibodies" = list() +//SIERRA-ADD MODPACK VIRUSOLOGY )) AddLabel("[blood_species] [blood_type]") UpdateItemSize() diff --git a/html/changelog.html b/html/changelog.html index 6e7ecae2f0653..50fc35fd405d7 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -28,6 +28,127 @@

Sierra SS13

-->
+

19.11 - 2024

+

Обновления Baneuus:

+
+
Теперь введение крови в золотое ядро спаунит злого моба.
+
Теперь введение крови в лазурное ядро спаунит зелье возрождения слизня.
+
+ +

16.11 - 2024

+

Обновления Lexanx & Gfitkiit:

+
+
Дроппод для мерков
+
+ +

14.11 - 2024

+

Обновления Lexanx:

+
+
Неотстыковка некоторых подов
+
Невозможность синхронизировать консоли, после их пересборки
+
Проблема с Advanced Landing в лававой экзопланете
+
Возвращена Вирусология.
+
Добавлена подпрофессия Химика - Вирусолог
+
Возвращены Вирусы
+
+

Обновления LordNest:

+
+
Добавил отображение заблокированного хранилища скафандров
+
+

Обновления awkardlyconfusedneuralnetwork:

+
+
Добавил звуки для аирлоков
+
Increases large map loading speed
+
Добавил face direction по нажатию иконки интента движения с зажатым ctrl
+
+ +

13.11 - 2024

+

Обновления KandJX:

+
+
Добавил лестницу между бригом и мостиком.
+
Убрал шлюз в теха из комнаты капитана.
+
+ +

12.11 - 2024

+

Обновления Builder13:

+
+
Больше нельзя получить галлюцинации от суперматерии при активных мезонных очках
+
+ +

11.11 - 2024

+

Обновления BOT Eeshee:

+
+
Добавила перчатки, маски и изоли ЭК
+
+

Обновления Lexanx:

+
+
Баг взаимодействия синтетов
+
Некорректная зона меркшипа
+
Пофикшена кража тюрфов при взлете
+
+

Обновления Shegar:

+
+
Задник космоса не становится серым из-за летающих островов
+
Текст эндраунда мода аномалий не жирный
+
+

Обновления Teteshnik:

+
+
Переименовал спавнеры безбилетников
+
+ +

10.11 - 2024

+

Обновления Builder13:

+
+
Радио при событии пси сигнала больше не должно воздействовать через стены
+
+

Обновления Mucker:

+
+
You can now "hold" a humanoid mobs' hand when pulling them and targeting one of their hands.
+
Antag latespawn scaling no longer considers players that aren't alive or are offship when deciding maximum antags.
+
+

Обновления Shegar:

+
+
Трамплин теперь не всегда кидает на 5 тайтлов.
+
Генератору аномок теперь не мешает railings
+
Лава больше не может сжигать артефакты
+
БСД пролив теперь не спавнит аномки в космосе
+
БСД теперь удаляет аномки после окончания ивента (Должен по крайней мере)
+
Мех при таране цели тоже делает шаг, от чего меха теперь невозможно заблочить не мехом/адхерантом/гбсом
+
Добавил глыбы на планету лёд. Красиво!
+
Детектор не какает обработкой без нужды, теперь его нужно включать.(Контрол + ЛКМ)
+
Теперь аномалии при осмотре детектером обнаруживаются полностью, а не частично (От чего шансы обнаружения довольно таки упали)
+
Полность переписана система влияния артефактов на определённые события с персонажами, добавлены новые эффекты. Усилена важность и польза контейнеров артефактов из-за этого.
+
Добавлена анимация уворота при паррировании.
+
Переписана система процессинга артефактов на персонажа. Она должна при любых взаимодействиях понимать, кто текущий носитель и влиять на него.
+
Добавил СНЕГ на ледяную планету с эффектом на экране и звуком.
+
Добавлен Z скан уровня для детектора
+
Добавил скалолазанье на планету ЛЁД. Помогайте друг другу, используйте кирки, готовьтесь физически и преодолевайте горы.
+
Добавлен установщик маячков для более комфортного построения пути на планетах.
+
Всасывающая гравианомалия изменена сопротивляться им стало сложнее, так как и задумывал разработчик, но в то же время, вы можете помогать своим друзьям выбираться из неё. Файнд аут ин гейм!
+
Логика электр подтипа Тесла переписана, теперь вся планета не сможет одновременно бахать
+
Достаточно высокий уровень науки позволит определять тип аномалии
+
Спавн аномалий от больших артефактов выведен из ротации.
+
Спрайты для артефактов, погода
+
Выдал Деплоер на склад ЭК. Детектор, мешочек и деплоер на склад шахтёров.
+
Исправлено описание детектора аномалий
+
Погода Буран, может подлагивать клиент. Пишите чё каво.
+
Сильно увеличен размер планет. Спавнит так же, как и от админки.
+
Добавлена аномальная планета: Летающие острова.
+
Сильно увеличил расстояния насёра аномалиями при БСД проливе, увеличено количество аномок.
+
Ослаблено СТАН влияние электры на жертву
+
Добавлена возможность от атлетики сопротивляться влиянию электры
+
Нёрф энергощитов меха, генерация тепла при получении урона увеличена в 2 раза
+
Добавил трамплин в билдер админов.
+
+

Обновления Spookerton:

+
+
Corrected Masculinity.
+
+

Обновления The_Spanish_1nquisition:

+
+
Tornakov took a marker to his poster.
+
+

09.11 - 2024

Обновления Shegar:

@@ -372,54 +493,6 @@

Обновления Vipo24:

Кислота вновь очень больно обжигает, как было раньше
- -

19.09 - 2024

-

Обновления Teteshnik:

-
-
Пофиксил лодаут ниндзи, так-же удалил костыль.
-
Портировал букеты в билд
-
- -

16.09 - 2024

-

Обновления Builder13:

-
-
Портировано отображение для скана контактов у сенсоров
-
Портирована экстренная кнопка бедствия
-
- -

15.09 - 2024

-

Обновления ВашНикнейм:

-
-
Выдал детекторы для ЭК
-
- -

14.09 - 2024

-

Обновления Builder13:

-
-
Добавлена возможность вставки и вытаскивания предмета из интегральной платы без ее удаления из корпуса
-
Добавлены интегральные платы list pick, image comparsion scanner, floor magnet.
-
Сделаны дополнения для плат intelligence control circuit и examiner
-
-

Обновления ВашНикнейм:

-
-
Сбор артефактов в мехе запрещён
-
Генерация артефактов и аномалий жёстко ограничена математикой.
-
Сбор артефактов теперь работает так, как я и задумывал
-
Добавил планетарную генерацию аномалий (по всей планете), зависящая от типа планеты
-
URM (Universal Research Machine) - новое устройство на петрове для анализа артов(мелких).
-
Добавлена ледяная планета
-
Добавил спрайты маячков, детектора, URM
-
Выдал ЭК коллекторы,маячки и новые детекторы. Колония, воксы, мусорщики - получили болтики.
-
Изменил русский на английский в аномалиях там, где это неуместно
-
Дал билдер аномалий в билдер с возможностью тонкой настройки
-
- -

11.09 - 2024

-

Обновления Teteshnik:

-
-
Удалил трэйси
-
Портирован халат робототехника с инфинити.
-
Icons by Icons8
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index a2657b038b75b..646c6bce5e257 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -25941,3 +25941,279 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY sierra_genchangelog.p Shegar: - bugfix: "\u041C\u0438\u043D\u0438\u0444\u0438\u043A\u0441\u0438\u043A \u0434\u043B\ \u044F \u0433\u0438\u0442\u0445\u0430\u0431\u0430" +2024-11-10: + Builder13: + - tweak: "\u0420\u0430\u0434\u0438\u043E \u043F\u0440\u0438 \u0441\u043E\u0431\u044B\ + \u0442\u0438\u0438 \u043F\u0441\u0438 \u0441\u0438\u0433\u043D\u0430\u043B\u0430\ + \ \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u0434\u043E\u043B\u0436\ + \u043D\u043E \u0432\u043E\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u043E\u0432\ + \u0430\u0442\u044C \u0447\u0435\u0440\u0435\u0437 \u0441\u0442\u0435\u043D\u044B" + Mucker: + - rscadd: You can now "hold" a humanoid mobs' hand when pulling them and targeting + one of their hands. + - bugfix: Antag latespawn scaling no longer considers players that aren't alive + or are offship when deciding maximum antags. + Shegar: + - bugfix: "\u0422\u0440\u0430\u043C\u043F\u043B\u0438\u043D \u0442\u0435\u043F\u0435\ + \u0440\u044C \u043D\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043A\u0438\u0434\ + \u0430\u0435\u0442 \u043D\u0430 5 \u0442\u0430\u0439\u0442\u043B\u043E\u0432\ + ." + - bugfix: "\u0413\u0435\u043D\u0435\u0440\u0430\u0442\u043E\u0440\u0443 \u0430\u043D\ + \u043E\u043C\u043E\u043A \u0442\u0435\u043F\u0435\u0440\u044C \u043D\u0435 \u043C\ + \u0435\u0448\u0430\u0435\u0442 railings" + - bugfix: "\u041B\u0430\u0432\u0430 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435\ + \ \u043C\u043E\u0436\u0435\u0442 \u0441\u0436\u0438\u0433\u0430\u0442\u044C\ + \ \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u044B" + - bugfix: "\u0411\u0421\u0414 \u043F\u0440\u043E\u043B\u0438\u0432 \u0442\u0435\u043F\ + \u0435\u0440\u044C \u043D\u0435 \u0441\u043F\u0430\u0432\u043D\u0438\u0442 \u0430\ + \u043D\u043E\u043C\u043A\u0438 \u0432 \u043A\u043E\u0441\u043C\u043E\u0441\u0435" + - bugfix: "\u0411\u0421\u0414 \u0442\u0435\u043F\u0435\u0440\u044C \u0443\u0434\u0430\ + \u043B\u044F\u0435\u0442 \u0430\u043D\u043E\u043C\u043A\u0438 \u043F\u043E\u0441\ + \u043B\u0435 \u043E\u043A\u043E\u043D\u0447\u0430\u043D\u0438\u044F \u0438\u0432\ + \u0435\u043D\u0442\u0430 (\u0414\u043E\u043B\u0436\u0435\u043D \u043F\u043E\ + \ \u043A\u0440\u0430\u0439\u043D\u0435\u0439 \u043C\u0435\u0440\u0435)" + - tweak: "\u041C\u0435\u0445 \u043F\u0440\u0438 \u0442\u0430\u0440\u0430\u043D\u0435\ + \ \u0446\u0435\u043B\u0438 \u0442\u043E\u0436\u0435 \u0434\u0435\u043B\u0430\ + \u0435\u0442 \u0448\u0430\u0433, \u043E\u0442 \u0447\u0435\u0433\u043E \u043C\ + \u0435\u0445\u0430 \u0442\u0435\u043F\u0435\u0440\u044C \u043D\u0435\u0432\u043E\ + \u0437\u043C\u043E\u0436\u043D\u043E \u0437\u0430\u0431\u043B\u043E\u0447\u0438\ + \u0442\u044C \u043D\u0435 \u043C\u0435\u0445\u043E\u043C/\u0430\u0434\u0445\u0435\ + \u0440\u0430\u043D\u0442\u043E\u043C/\u0433\u0431\u0441\u043E\u043C" + - tweak: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u0433\u043B\u044B\u0431\u044B\ + \ \u043D\u0430 \u043F\u043B\u0430\u043D\u0435\u0442\u0443 \u043B\u0451\u0434\ + . \u041A\u0440\u0430\u0441\u0438\u0432\u043E!" + - tweak: "\u0414\u0435\u0442\u0435\u043A\u0442\u043E\u0440 \u043D\u0435 \u043A\u0430\ + \u043A\u0430\u0435\u0442 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u043E\ + \u0439 \u0431\u0435\u0437 \u043D\u0443\u0436\u0434\u044B, \u0442\u0435\u043F\ + \u0435\u0440\u044C \u0435\u0433\u043E \u043D\u0443\u0436\u043D\u043E \u0432\u043A\ + \u043B\u044E\u0447\u0430\u0442\u044C.(\u041A\u043E\u043D\u0442\u0440\u043E\u043B\ + \ + \u041B\u041A\u041C)" + - tweak: "\u0422\u0435\u043F\u0435\u0440\u044C \u0430\u043D\u043E\u043C\u0430\u043B\ + \u0438\u0438 \u043F\u0440\u0438 \u043E\u0441\u043C\u043E\u0442\u0440\u0435 \u0434\ + \u0435\u0442\u0435\u043A\u0442\u0435\u0440\u043E\u043C \u043E\u0431\u043D\u0430\ + \u0440\u0443\u0436\u0438\u0432\u0430\u044E\u0442\u0441\u044F \u043F\u043E\u043B\ + \u043D\u043E\u0441\u0442\u044C\u044E, \u0430 \u043D\u0435 \u0447\u0430\u0441\ + \u0442\u0438\u0447\u043D\u043E (\u041E\u0442 \u0447\u0435\u0433\u043E \u0448\ + \u0430\u043D\u0441\u044B \u043E\u0431\u043D\u0430\u0440\u0443\u0436\u0435\u043D\ + \u0438\u044F \u0434\u043E\u0432\u043E\u043B\u044C\u043D\u043E \u0442\u0430\u043A\ + \u0438 \u0443\u043F\u0430\u043B\u0438)" + - rscadd: "\u041F\u043E\u043B\u043D\u043E\u0441\u0442\u044C \u043F\u0435\u0440\u0435\ + \u043F\u0438\u0441\u0430\u043D\u0430 \u0441\u0438\u0441\u0442\u0435\u043C\u0430\ + \ \u0432\u043B\u0438\u044F\u043D\u0438\u044F \u0430\u0440\u0442\u0435\u0444\u0430\ + \u043A\u0442\u043E\u0432 \u043D\u0430 \u043E\u043F\u0440\u0435\u0434\u0435\u043B\ + \u0451\u043D\u043D\u044B\u0435 \u0441\u043E\u0431\u044B\u0442\u0438\u044F \u0441\ + \ \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u0436\u0430\u043C\u0438, \u0434\ + \u043E\u0431\u0430\u0432\u043B\u0435\u043D\u044B \u043D\u043E\u0432\u044B\u0435\ + \ \u044D\u0444\u0444\u0435\u043A\u0442\u044B. \u0423\u0441\u0438\u043B\u0435\ + \u043D\u0430 \u0432\u0430\u0436\u043D\u043E\u0441\u0442\u044C \u0438 \u043F\u043E\ + \u043B\u044C\u0437\u0430 \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440\ + \u043E\u0432 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u043E\u0432 \u0438\ + \u0437-\u0437\u0430 \u044D\u0442\u043E\u0433\u043E." + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0430 \u0430\u043D\u0438\ + \u043C\u0430\u0446\u0438\u044F \u0443\u0432\u043E\u0440\u043E\u0442\u0430 \u043F\ + \u0440\u0438 \u043F\u0430\u0440\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u0438\ + \u0438." + - rscadd: "\u041F\u0435\u0440\u0435\u043F\u0438\u0441\u0430\u043D\u0430 \u0441\u0438\ + \u0441\u0442\u0435\u043C\u0430 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0438\ + \u043D\u0433\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u043E\u0432\ + \ \u043D\u0430 \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u0436\u0430. \u041E\ + \u043D\u0430 \u0434\u043E\u043B\u0436\u043D\u0430 \u043F\u0440\u0438 \u043B\u044E\ + \u0431\u044B\u0445 \u0432\u0437\u0430\u0438\u043C\u043E\u0434\u0435\u0439\u0441\ + \u0442\u0432\u0438\u044F\u0445 \u043F\u043E\u043D\u0438\u043C\u0430\u0442\u044C\ + , \u043A\u0442\u043E \u0442\u0435\u043A\u0443\u0449\u0438\u0439 \u043D\u043E\ + \u0441\u0438\u0442\u0435\u043B\u044C \u0438 \u0432\u043B\u0438\u044F\u0442\u044C\ + \ \u043D\u0430 \u043D\u0435\u0433\u043E." + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u0421\u041D\u0415\u0413 \u043D\ + \u0430 \u043B\u0435\u0434\u044F\u043D\u0443\u044E \u043F\u043B\u0430\u043D\u0435\ + \u0442\u0443 \u0441 \u044D\u0444\u0444\u0435\u043A\u0442\u043E\u043C \u043D\u0430\ + \ \u044D\u043A\u0440\u0430\u043D\u0435 \u0438 \u0437\u0432\u0443\u043A\u043E\ + \u043C." + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D Z \u0441\u043A\u0430\ + \u043D \u0443\u0440\u043E\u0432\u043D\u044F \u0434\u043B\u044F \u0434\u0435\u0442\ + \u0435\u043A\u0442\u043E\u0440\u0430" + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u0441\u043A\u0430\u043B\u043E\ + \u043B\u0430\u0437\u0430\u043D\u044C\u0435 \u043D\u0430 \u043F\u043B\u0430\u043D\ + \u0435\u0442\u0443 \u041B\u0401\u0414. \u041F\u043E\u043C\u043E\u0433\u0430\u0439\ + \u0442\u0435 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443, \u0438\ + \u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u043A\u0438\u0440\ + \u043A\u0438, \u0433\u043E\u0442\u043E\u0432\u044C\u0442\u0435\u0441\u044C \u0444\ + \u0438\u0437\u0438\u0447\u0435\u0441\u043A\u0438 \u0438 \u043F\u0440\u0435\u043E\ + \u0434\u043E\u043B\u0435\u0432\u0430\u0439\u0442\u0435 \u0433\u043E\u0440\u044B\ + ." + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D \u0443\u0441\u0442\u0430\ + \u043D\u043E\u0432\u0449\u0438\u043A \u043C\u0430\u044F\u0447\u043A\u043E\u0432\ + \ \u0434\u043B\u044F \u0431\u043E\u043B\u0435\u0435 \u043A\u043E\u043C\u0444\ + \u043E\u0440\u0442\u043D\u043E\u0433\u043E \u043F\u043E\u0441\u0442\u0440\u043E\ + \u0435\u043D\u0438\u044F \u043F\u0443\u0442\u0438 \u043D\u0430 \u043F\u043B\u0430\ + \u043D\u0435\u0442\u0430\u0445." + - rscadd: "\u0412\u0441\u0430\u0441\u044B\u0432\u0430\u044E\u0449\u0430\u044F \u0433\ + \u0440\u0430\u0432\u0438\u0430\u043D\u043E\u043C\u0430\u043B\u0438\u044F \u0438\ + \u0437\u043C\u0435\u043D\u0435\u043D\u0430 \u0441\u043E\u043F\u0440\u043E\u0442\ + \u0438\u0432\u043B\u044F\u0442\u044C\u0441\u044F \u0438\u043C \u0441\u0442\u0430\ + \u043B\u043E \u0441\u043B\u043E\u0436\u043D\u0435\u0435, \u0442\u0430\u043A\ + \ \u043A\u0430\u043A \u0438 \u0437\u0430\u0434\u0443\u043C\u044B\u0432\u0430\ + \u043B \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A, \u043D\ + \u043E \u0432 \u0442\u043E \u0436\u0435 \u0432\u0440\u0435\u043C\u044F, \u0432\ + \u044B \u043C\u043E\u0436\u0435\u0442\u0435 \u043F\u043E\u043C\u043E\u0433\u0430\ + \u0442\u044C \u0441\u0432\u043E\u0438\u043C \u0434\u0440\u0443\u0437\u044C\u044F\ + \u043C \u0432\u044B\u0431\u0438\u0440\u0430\u0442\u044C\u0441\u044F \u0438\u0437\ + \ \u043D\u0435\u0451. \u0424\u0430\u0439\u043D\u0434 \u0430\u0443\u0442 \u0438\ + \u043D \u0433\u0435\u0439\u043C!" + - rscadd: "\u041B\u043E\u0433\u0438\u043A\u0430 \u044D\u043B\u0435\u043A\u0442\u0440\ + \ \u043F\u043E\u0434\u0442\u0438\u043F\u0430 \u0422\u0435\u0441\u043B\u0430\ + \ \u043F\u0435\u0440\u0435\u043F\u0438\u0441\u0430\u043D\u0430, \u0442\u0435\ + \u043F\u0435\u0440\u044C \u0432\u0441\u044F \u043F\u043B\u0430\u043D\u0435\u0442\ + \u0430 \u043D\u0435 \u0441\u043C\u043E\u0436\u0435\u0442 \u043E\u0434\u043D\u043E\ + \u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E \u0431\u0430\u0445\u0430\u0442\ + \u044C" + - rscadd: "\u0414\u043E\u0441\u0442\u0430\u0442\u043E\u0447\u043D\u043E \u0432\u044B\ + \u0441\u043E\u043A\u0438\u0439 \u0443\u0440\u043E\u0432\u0435\u043D\u044C \u043D\ + \u0430\u0443\u043A\u0438 \u043F\u043E\u0437\u0432\u043E\u043B\u0438\u0442 \u043E\ + \u043F\u0440\u0435\u0434\u0435\u043B\u044F\u0442\u044C \u0442\u0438\u043F \u0430\ + \u043D\u043E\u043C\u0430\u043B\u0438\u0438" + - rscdel: "\u0421\u043F\u0430\u0432\u043D \u0430\u043D\u043E\u043C\u0430\u043B\u0438\ + \u0439 \u043E\u0442 \u0431\u043E\u043B\u044C\u0448\u0438\u0445 \u0430\u0440\u0442\ + \u0435\u0444\u0430\u043A\u0442\u043E\u0432 \u0432\u044B\u0432\u0435\u0434\u0435\ + \u043D \u0438\u0437 \u0440\u043E\u0442\u0430\u0446\u0438\u0438." + - imageadd: "\u0421\u043F\u0440\u0430\u0439\u0442\u044B \u0434\u043B\u044F \u0430\ + \u0440\u0442\u0435\u0444\u0430\u043A\u0442\u043E\u0432, \u043F\u043E\u0433\u043E\ + \u0434\u0430" + - maptweak: "\u0412\u044B\u0434\u0430\u043B \u0414\u0435\u043F\u043B\u043E\u0435\ + \u0440 \u043D\u0430 \u0441\u043A\u043B\u0430\u0434 \u042D\u041A. \u0414\u0435\ + \u0442\u0435\u043A\u0442\u043E\u0440, \u043C\u0435\u0448\u043E\u0447\u0435\u043A\ + \ \u0438 \u0434\u0435\u043F\u043B\u043E\u0435\u0440 \u043D\u0430 \u0441\u043A\ + \u043B\u0430\u0434 \u0448\u0430\u0445\u0442\u0451\u0440\u043E\u0432." + - spellcheck: "\u0418\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E \u043E\ + \u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u0435\u0442\u0435\u043A\u0442\ + \u043E\u0440\u0430 \u0430\u043D\u043E\u043C\u0430\u043B\u0438\u0439" + - experiment: "\u041F\u043E\u0433\u043E\u0434\u0430 \u0411\u0443\u0440\u0430\u043D\ + , \u043C\u043E\u0436\u0435\u0442 \u043F\u043E\u0434\u043B\u0430\u0433\u0438\u0432\ + \u0430\u0442\u044C \u043A\u043B\u0438\u0435\u043D\u0442. \u041F\u0438\u0448\u0438\ + \u0442\u0435 \u0447\u0451 \u043A\u0430\u0432\u043E." + - experiment: "\u0421\u0438\u043B\u044C\u043D\u043E \u0443\u0432\u0435\u043B\u0438\ + \u0447\u0435\u043D \u0440\u0430\u0437\u043C\u0435\u0440 \u043F\u043B\u0430\u043D\ + \u0435\u0442. \u0421\u043F\u0430\u0432\u043D\u0438\u0442 \u0442\u0430\u043A\ + \ \u0436\u0435, \u043A\u0430\u043A \u0438 \u043E\u0442 \u0430\u0434\u043C\u0438\ + \u043D\u043A\u0438." + - experiment: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0430 \u0430\u043D\ + \u043E\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u043F\u043B\u0430\u043D\u0435\ + \u0442\u0430: \u041B\u0435\u0442\u0430\u044E\u0449\u0438\u0435 \u043E\u0441\u0442\ + \u0440\u043E\u0432\u0430." + - balance: "\u0421\u0438\u043B\u044C\u043D\u043E \u0443\u0432\u0435\u043B\u0438\u0447\ + \u0438\u043B \u0440\u0430\u0441\u0441\u0442\u043E\u044F\u043D\u0438\u044F \u043D\ + \u0430\u0441\u0451\u0440\u0430 \u0430\u043D\u043E\u043C\u0430\u043B\u0438\u044F\ + \u043C\u0438 \u043F\u0440\u0438 \u0411\u0421\u0414 \u043F\u0440\u043E\u043B\u0438\ + \u0432\u0435, \u0443\u0432\u0435\u043B\u0438\u0447\u0435\u043D\u043E \u043A\u043E\ + \u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0430\u043D\u043E\u043C\u043E\ + \u043A." + - balance: "\u041E\u0441\u043B\u0430\u0431\u043B\u0435\u043D\u043E \u0421\u0422\u0410\ + \u041D \u0432\u043B\u0438\u044F\u043D\u0438\u0435 \u044D\u043B\u0435\u043A\u0442\ + \u0440\u044B \u043D\u0430 \u0436\u0435\u0440\u0442\u0432\u0443" + - balance: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0430 \u0432\u043E\u0437\ + \u043C\u043E\u0436\u043D\u043E\u0441\u0442\u044C \u043E\u0442 \u0430\u0442\u043B\ + \u0435\u0442\u0438\u043A\u0438 \u0441\u043E\u043F\u0440\u043E\u0442\u0438\u0432\ + \u043B\u044F\u0442\u044C\u0441\u044F \u0432\u043B\u0438\u044F\u043D\u0438\u044E\ + \ \u044D\u043B\u0435\u043A\u0442\u0440\u044B" + - balance: "\u041D\u0451\u0440\u0444 \u044D\u043D\u0435\u0440\u0433\u043E\u0449\u0438\ + \u0442\u043E\u0432 \u043C\u0435\u0445\u0430, \u0433\u0435\u043D\u0435\u0440\u0430\ + \u0446\u0438\u044F \u0442\u0435\u043F\u043B\u0430 \u043F\u0440\u0438 \u043F\u043E\ + \u043B\u0443\u0447\u0435\u043D\u0438\u0438 \u0443\u0440\u043E\u043D\u0430 \u0443\ + \u0432\u0435\u043B\u0438\u0447\u0435\u043D\u0430 \u0432 2 \u0440\u0430\u0437\ + \u0430" + - admin: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u0442\u0440\u0430\u043C\u043F\ + \u043B\u0438\u043D \u0432 \u0431\u0438\u043B\u0434\u0435\u0440 \u0430\u0434\u043C\ + \u0438\u043D\u043E\u0432." + Spookerton: + - bugfix: Corrected Masculinity. + The_Spanish_1nquisition: + - tweak: Tornakov took a marker to his poster. +2024-11-11: + BOT Eeshee: + - maptweak: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B\u0430 \u043F\u0435\u0440\ + \u0447\u0430\u0442\u043A\u0438, \u043C\u0430\u0441\u043A\u0438 \u0438 \u0438\ + \u0437\u043E\u043B\u0438 \u042D\u041A" + Lexanx: + - bugfix: "\u0411\u0430\u0433 \u0432\u0437\u0430\u0438\u043C\u043E\u0434\u0435\u0439\ + \u0441\u0442\u0432\u0438\u044F \u0441\u0438\u043D\u0442\u0435\u0442\u043E\u0432" + - bugfix: "\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u0430\u044F\ + \ \u0437\u043E\u043D\u0430 \u043C\u0435\u0440\u043A\u0448\u0438\u043F\u0430" + - bugfix: "\u041F\u043E\u0444\u0438\u043A\u0448\u0435\u043D\u0430 \u043A\u0440\u0430\ + \u0436\u0430 \u0442\u044E\u0440\u0444\u043E\u0432 \u043F\u0440\u0438 \u0432\u0437\ + \u043B\u0435\u0442\u0435" + Shegar: + - bugfix: "\u0417\u0430\u0434\u043D\u0438\u043A \u043A\u043E\u0441\u043C\u043E\u0441\ + \u0430 \u043D\u0435 \u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0441\u044F\ + \ \u0441\u0435\u0440\u044B\u043C \u0438\u0437-\u0437\u0430 \u043B\u0435\u0442\ + \u0430\u044E\u0449\u0438\u0445 \u043E\u0441\u0442\u0440\u043E\u0432\u043E\u0432" + - tweak: "\u0422\u0435\u043A\u0441\u0442 \u044D\u043D\u0434\u0440\u0430\u0443\u043D\ + \u0434\u0430 \u043C\u043E\u0434\u0430 \u0430\u043D\u043E\u043C\u0430\u043B\u0438\ + \u0439 \u043D\u0435 \u0436\u0438\u0440\u043D\u044B\u0439" + Teteshnik: + - tweak: "\u041F\u0435\u0440\u0435\u0438\u043C\u0435\u043D\u043E\u0432\u0430\u043B\ + \ \u0441\u043F\u0430\u0432\u043D\u0435\u0440\u044B \u0431\u0435\u0437\u0431\u0438\ + \u043B\u0435\u0442\u043D\u0438\u043A\u043E\u0432" +2024-11-12: + Builder13: + - bugfix: "\u0411\u043E\u043B\u044C\u0448\u0435 \u043D\u0435\u043B\u044C\u0437\u044F\ + \ \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0433\u0430\u043B\u043B\u044E\ + \u0446\u0438\u043D\u0430\u0446\u0438\u0438 \u043E\u0442 \u0441\u0443\u043F\u0435\ + \u0440\u043C\u0430\u0442\u0435\u0440\u0438\u0438 \u043F\u0440\u0438 \u0430\u043A\ + \u0442\u0438\u0432\u043D\u044B\u0445 \u043C\u0435\u0437\u043E\u043D\u043D\u044B\ + \u0445 \u043E\u0447\u043A\u0430\u0445" +2024-11-13: + KandJX: + - maptweak: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u043B\u0435\u0441\u0442\ + \u043D\u0438\u0446\u0443 \u043C\u0435\u0436\u0434\u0443 \u0431\u0440\u0438\u0433\ + \u043E\u043C \u0438 \u043C\u043E\u0441\u0442\u0438\u043A\u043E\u043C." + - maptweak: "\u0423\u0431\u0440\u0430\u043B \u0448\u043B\u044E\u0437 \u0432 \u0442\ + \u0435\u0445\u0430 \u0438\u0437 \u043A\u043E\u043C\u043D\u0430\u0442\u044B \u043A\ + \u0430\u043F\u0438\u0442\u0430\u043D\u0430." +2024-11-14: + Lexanx: + - bugfix: "\u041D\u0435\u043E\u0442\u0441\u0442\u044B\u043A\u043E\u0432\u043A\u0430\ + \ \u043D\u0435\u043A\u043E\u0442\u043E\u0440\u044B\u0445 \u043F\u043E\u0434\u043E\ + \u0432" + - bugfix: "\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\ + \u044C \u0441\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0438\u0440\u043E\ + \u0432\u0430\u0442\u044C \u043A\u043E\u043D\u0441\u043E\u043B\u0438, \u043F\u043E\ + \u0441\u043B\u0435 \u0438\u0445 \u043F\u0435\u0440\u0435\u0441\u0431\u043E\u0440\ + \u043A\u0438" + - bugfix: "\u041F\u0440\u043E\u0431\u043B\u0435\u043C\u0430 \u0441 Advanced Landing\ + \ \u0432 \u043B\u0430\u0432\u0430\u0432\u043E\u0439 \u044D\u043A\u0437\u043E\ + \u043F\u043B\u0430\u043D\u0435\u0442\u0435" + - rscadd: "\u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0435\u043D\u0430 \u0412\u0438\ + \u0440\u0443\u0441\u043E\u043B\u043E\u0433\u0438\u044F." + - rscadd: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0430 \u043F\u043E\u0434\ + \u043F\u0440\u043E\u0444\u0435\u0441\u0441\u0438\u044F \u0425\u0438\u043C\u0438\ + \u043A\u0430 - \u0412\u0438\u0440\u0443\u0441\u043E\u043B\u043E\u0433" + - rscadd: "\u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0435\u043D\u044B \u0412\u0438\ + \u0440\u0443\u0441\u044B" + LordNest: + - imageadd: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u043E\u0442\u043E\u0431\ + \u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u0437\u0430\u0431\u043B\u043E\u043A\ + \u0438\u0440\u043E\u0432\u0430\u043D\u043D\u043E\u0433\u043E \u0445\u0440\u0430\ + \u043D\u0438\u043B\u0438\u0449\u0430 \u0441\u043A\u0430\u0444\u0430\u043D\u0434\ + \u0440\u043E\u0432" + awkardlyconfusedneuralnetwork: + - tweak: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B \u0437\u0432\u0443\u043A\u0438\ + \ \u0434\u043B\u044F \u0430\u0438\u0440\u043B\u043E\u043A\u043E\u0432" + - tweak: Increases large map loading speed + - tweak: "\u0414\u043E\u0431\u0430\u0432\u0438\u043B face direction \u043F\u043E\ + \ \u043D\u0430\u0436\u0430\u0442\u0438\u044E \u0438\u043A\u043E\u043D\u043A\u0438\ + \ \u0438\u043D\u0442\u0435\u043D\u0442\u0430 \u0434\u0432\u0438\u0436\u0435\u043D\ + \u0438\u044F \u0441 \u0437\u0430\u0436\u0430\u0442\u044B\u043C ctrl" +2024-11-16: + Lexanx & Gfitkiit: + - rscadd: "\u0414\u0440\u043E\u043F\u043F\u043E\u0434 \u0434\u043B\u044F \u043C\u0435\ + \u0440\u043A\u043E\u0432" +2024-11-19: + Baneuus: + - tweak: "\u0422\u0435\u043F\u0435\u0440\u044C \u0432\u0432\u0435\u0434\u0435\u043D\ + \u0438\u0435 \u043A\u0440\u043E\u0432\u0438 \u0432 \u0437\u043E\u043B\u043E\u0442\ + \u043E\u0435 \u044F\u0434\u0440\u043E \u0441\u043F\u0430\u0443\u043D\u0438\u0442\ + \ \u0437\u043B\u043E\u0433\u043E \u043C\u043E\u0431\u0430." + - tweak: "\u0422\u0435\u043F\u0435\u0440\u044C \u0432\u0432\u0435\u0434\u0435\u043D\ + \u0438\u0435 \u043A\u0440\u043E\u0432\u0438 \u0432 \u043B\u0430\u0437\u0443\u0440\ + \u043D\u043E\u0435 \u044F\u0434\u0440\u043E \u0441\u043F\u0430\u0443\u043D\u0438\ + \u0442 \u0437\u0435\u043B\u044C\u0435 \u0432\u043E\u0437\u0440\u043E\u0436\u0434\ + \u0435\u043D\u0438\u044F \u0441\u043B\u0438\u0437\u043D\u044F." diff --git a/html/changelogs/AutoChangeLog-sierra-pr-2660.yml b/html/changelogs/AutoChangeLog-sierra-pr-2660.yml new file mode 100644 index 0000000000000..2dde87254d399 --- /dev/null +++ b/html/changelogs/AutoChangeLog-sierra-pr-2660.yml @@ -0,0 +1,5 @@ +author: PurplePineapple +changes: + - {bugfix: Clicking a victim with an item on disarm intent calls use_weapon(). Disarm + intent/Dislocation combat for melee works again.} +delete-after: true diff --git a/html/changelogs/AutoChangeLog-sierra-pr-2674.yml b/html/changelogs/AutoChangeLog-sierra-pr-2674.yml deleted file mode 100644 index e1a39d44485a3..0000000000000 --- a/html/changelogs/AutoChangeLog-sierra-pr-2674.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: Mucker -changes: - - {bugfix: Antag latespawn scaling no longer considers players that aren't alive - or are offship when deciding maximum antags.} -delete-after: true diff --git a/html/changelogs/AutoChangeLog-sierra-pr-2675.yml b/html/changelogs/AutoChangeLog-sierra-pr-2675.yml deleted file mode 100644 index 8841c976f5bb6..0000000000000 --- a/html/changelogs/AutoChangeLog-sierra-pr-2675.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Spookerton -changes: - - {bugfix: Corrected Masculinity.} -delete-after: true diff --git a/html/changelogs/AutoChangeLog-sierra-pr-2680.yml b/html/changelogs/AutoChangeLog-sierra-pr-2680.yml deleted file mode 100644 index 0af15c32c4141..0000000000000 --- a/html/changelogs/AutoChangeLog-sierra-pr-2680.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: Mucker -changes: - - {rscadd: You can now "hold" a humanoid mobs' hand when pulling them and targeting - one of their hands.} -delete-after: true diff --git a/html/changelogs/AutoChangeLog-sierra-pr-2685.yml b/html/changelogs/AutoChangeLog-sierra-pr-2685.yml deleted file mode 100644 index d73d2910f3d75..0000000000000 --- a/html/changelogs/AutoChangeLog-sierra-pr-2685.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: The_Spanish_1nquisition -changes: - - {tweak: Tornakov took a marker to his poster.} -delete-after: true diff --git a/html/changelogs/AutoChangeLog-sierra-pr-2894.yml b/html/changelogs/AutoChangeLog-sierra-pr-2894.yml new file mode 100644 index 0000000000000..e1b59e662542a --- /dev/null +++ b/html/changelogs/AutoChangeLog-sierra-pr-2894.yml @@ -0,0 +1,5 @@ +author: Lexanx +changes: + - {tweak: Изменена форма снабжения 32} + - {rscadd: Добавил зарядник боргов на ГУП} +delete-after: true diff --git a/maps/antag_spawn/mercenary/mercenary_base.dmm b/maps/antag_spawn/mercenary/mercenary_base.dmm index 31142028162bd..39396c0e5fabe 100644 --- a/maps/antag_spawn/mercenary/mercenary_base.dmm +++ b/maps/antag_spawn/mercenary/mercenary_base.dmm @@ -186,6 +186,13 @@ /obj/catwalk_plated, /turf/simulated/floor/plating, /area/map_template/merc_spawn) +"bz" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 6 + }, +/obj/machinery/portable_atmospherics/powered/pump/filled, +/turf/simulated/floor/tiled/techfloor, +/area/map_template/merc_shuttle) "bM" = ( /obj/structure/cable{ d1 = 4; @@ -446,6 +453,15 @@ /obj/floor_decal/techfloor/corner{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) "ex" = ( @@ -467,6 +483,7 @@ /obj/machinery/disperser/back{ dir = 1 }, +/obj/structure/ship_munition/disperser_charge/emp, /turf/simulated/floor/plating, /area/map_template/merc_shuttle) "eR" = ( @@ -854,8 +871,8 @@ /turf/simulated/floor/tiled/monotile, /area/map_template/merc_spawn) "jK" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) "jQ" = ( @@ -884,11 +901,23 @@ frequency = 1380; master_tag = "merc_shuttle"; name = "interior access button"; - pixel_x = 22; + pixel_x = 29; pixel_y = -11 }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) +"ka" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5 + }, +/turf/simulated/floor/tiled/dark/monotile, +/area/map_template/merc_shuttle) "kb" = ( /turf/simulated/floor/tiled/dark, /area/map_template/merc_spawn) @@ -996,6 +1025,21 @@ d2 = 8; icon_state = "4-8" }, +/obj/item/device/binoculars, +/obj/item/device/binoculars, +/obj/item/device/binoculars, +/obj/item/device/binoculars, +/obj/item/device/binoculars, +/obj/item/device/binoculars, +/obj/item/device/binoculars, +/obj/item/crowbar/prybar, +/obj/item/crowbar/prybar, +/obj/item/crowbar/prybar, +/obj/item/crowbar/prybar, +/obj/item/crowbar/prybar, +/obj/item/crowbar/prybar, +/obj/item/crowbar/prybar, +/obj/item/crowbar/prybar, /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "lg" = ( @@ -1045,9 +1089,6 @@ /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "lz" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ - dir = 4 - }, /obj/floor_decal/industrial/warning{ dir = 4 }, @@ -1057,6 +1098,9 @@ /obj/structure/handrail{ dir = 1 }, +/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ + dir = 1 + }, /turf/simulated/floor/tiled/techfloor/grid, /area/map_template/merc_shuttle) "lB" = ( @@ -1068,6 +1112,10 @@ }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) +"lS" = ( +/obj/machinery/atmospherics/pipe/manifold4w/hidden/fuel, +/turf/simulated/floor/tiled/techfloor, +/area/map_template/merc_shuttle) "lX" = ( /obj/floor_decal/corner/blue{ dir = 10 @@ -1223,7 +1271,13 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/table/steel_reinforced, +/obj/machinery/fabricator/hacked, +/obj/floor_decal/industrial/outline/yellow, +/obj/item/stack/material/steel/ten, +/obj/item/stack/material/steel/ten, +/obj/item/stack/material/glass/ten, +/obj/item/stack/material/aluminium/ten, +/obj/item/stack/material/plastic/ten, /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "nn" = ( @@ -1317,11 +1371,12 @@ /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "oo" = ( -/obj/machinery/portable_atmospherics/canister/hydrogen, -/obj/floor_decal/industrial/outline/yellow, -/obj/item/tank/hydrogen, -/obj/item/tank/hydrogen, -/turf/simulated/floor/tiled/techfloor, +/obj/machinery/body_scanconsole{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled/white, /area/map_template/merc_shuttle) "oC" = ( /obj/machinery/door/airlock/external{ @@ -1351,6 +1406,11 @@ /obj/overmap/visitable/sector/merc_base, /turf/simulated/floor/plating, /area/map_template/merc_spawn) +"oJ" = ( +/obj/paint/sun, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel, +/turf/simulated/wall/titanium, +/area/map_template/merc_shuttle) "oK" = ( /obj/floor_decal/corner/blue/mono, /obj/structure/table/standard, @@ -1364,6 +1424,15 @@ pixel_y = -24; req_access = list("ACCESS_SYNDICATE") }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) "oW" = ( @@ -1388,35 +1457,18 @@ /turf/simulated/floor/tiled, /area/map_template/merc_spawn) "pb" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 6 - }, /obj/floor_decal/corner_techfloor_grid{ dir = 1 }, /obj/floor_decal/techfloor/corner{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) "pc" = ( -/obj/structure/table/steel, -/obj/item/crowbar/prybar, -/obj/item/crowbar/prybar, -/obj/item/crowbar/prybar, -/obj/item/crowbar/prybar, -/obj/item/crowbar/prybar, -/obj/item/crowbar/prybar, -/obj/machinery/button/blast_door{ - id_tag = "merc_airlock"; - req_access = list("ACCESS_SYNDICATE") - }, -/obj/item/device/binoculars, -/obj/item/device/binoculars, -/obj/item/device/binoculars, -/obj/item/device/binoculars, -/obj/item/device/binoculars, -/obj/item/device/binoculars, /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 }, @@ -1508,54 +1560,36 @@ /turf/simulated/floor/tiled/dark/monotile, /area/map_template/merc_shuttle) "qj" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 - }, -/obj/structure/window/reinforced/crescent{ +/obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 }, -/obj/structure/bed/chair/shuttle/black{ - dir = 8 - }, -/obj/structure/sign/poster{ - pixel_y = 32 - }, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/machinery/computer/ship/engines, +/turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "qw" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 9 }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "qy" = ( -/obj/wallframe_spawn/reinforced/titanium, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ +/obj/floor_decal/techfloor{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/machinery/button/blast_door{ + id_tag = "merc_airlock"; + req_access = list("ACCESS_SYNDICATE"); + pixel_x = 21; + pixel_y = 23 }, -/obj/paint/merc, -/turf/simulated/floor/plating, +/turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) "qA" = ( -/obj/machinery/fabricator/hacked, -/obj/floor_decal/industrial/outline/yellow, -/obj/item/stack/material/plastic/ten, -/obj/item/stack/material/aluminium/ten, -/obj/item/stack/material/steel/ten, -/obj/item/stack/material/glass/ten, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/structure/fuel_port{ + pixel_y = -30 }, -/obj/item/stack/material/steel/ten, /turf/simulated/floor/tiled/dark/monotile, /area/map_template/merc_shuttle) "qC" = ( @@ -1564,9 +1598,18 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled/steel_ridged, /area/map_template/merc_spawn) +"qQ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/fuel, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled/techfloor, +/area/map_template/merc_shuttle) "qY" = ( -/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, -/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers, +/obj/floor_decal/industrial/outline/red, +/obj/structure/railing{ + dir = 1 + }, +/obj/structure/railing, /turf/simulated/floor/tiled/dark/monotile, /area/map_template/merc_shuttle) "qZ" = ( @@ -1597,19 +1640,28 @@ /turf/simulated/floor/tiled/dark/monotile, /area/map_template/merc_spawn) "rt" = ( -/obj/machinery/atmospherics/pipe/simple/hidden, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 + dir = 5 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 + dir = 5 }, /turf/simulated/floor/tiled/dark/monotile, /area/map_template/merc_shuttle) -"rA" = ( -/obj/machinery/door/airlock/glass/civilian{ - name = "airlock" +"rx" = ( +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/turf/simulated/floor/tiled/dark/monotile, +/area/map_template/merc_shuttle) +"rA" = ( +/obj/machinery/door/airlock/glass, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -1623,26 +1675,27 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 + dir = 4 }, -/obj/machinery/alarm{ - pixel_y = 24; - req_access = list("ACCESS_SYNDICATE") +/obj/floor_decal/techfloor/corner{ + dir = 4 }, -/turf/simulated/floor/tiled/white, +/turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) "rG" = ( -/obj/machinery/body_scanconsole{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, -/obj/structure/handrail, /obj/machinery/light{ dir = 1 }, -/turf/simulated/floor/tiled/white, +/obj/floor_decal/techfloor{ + dir = 1 + }, +/turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) "rK" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -1650,47 +1703,55 @@ /turf/simulated/floor/tiled/dark/monotile, /area/map_template/merc_spawn) "rL" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/window/reinforced/crescent{ - dir = 1 +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ +/turf/simulated/floor/tiled/dark, +/area/map_template/merc_shuttle) +"rN" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/light{ dir = 4 }, /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) -"rN" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 - }, -/obj/machinery/recharger/wallcharger{ - pixel_x = 26 +"sx" = ( +/obj/paint/sun, +/obj/machinery/atmospherics/unary/engine{ + dir = 1 }, -/turf/simulated/floor/tiled/techfloor, +/turf/simulated/wall/titanium, /area/map_template/merc_shuttle) "sz" = ( -/obj/machinery/door/airlock, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/tiled/steel_ridged, +/obj/machinery/door/airlock/external, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 4 + }, +/obj/shuttle_landmark/merc_pod/merc_ship, +/turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) "sE" = ( -/obj/machinery/atmospherics/pipe/simple/hidden, /obj/paint/merc, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 4 + }, /turf/simulated/wall/titanium, /area/map_template/merc_shuttle) "sH" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 5 +/obj/structure/railing, +/obj/structure/railing{ + dir = 1 }, -/turf/simulated/floor/tiled/white, +/obj/floor_decal/industrial/outline/blue, +/turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) "sO" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 }, -/turf/simulated/floor/tiled/white, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) "sS" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ @@ -1757,37 +1818,29 @@ /turf/simulated/floor/tiled/dark/monotile, /area/map_template/merc_shuttle) "ut" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ - dir = 10 +/obj/paint/red, +/obj/paint_stripe/white, +/turf/simulated/wall/r_titanium, +/area/map_template/merc_shuttle/drop_pod) +"uv" = ( +/obj/floor_decal/techfloor/orange/corner{ + dir = 8 }, -/obj/structure/catwalk, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 4 +/obj/floor_decal/techfloor/orange/corner, +/obj/machinery/door/blast/regular{ + id_tag = "merc_pod2" }, -/obj/structure/fuel_port{ - pixel_y = 30 - }, -/turf/simulated/floor/plating, -/area/map_template/merc_shuttle) -"uv" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 5 - }, -/obj/structure/catwalk, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 +/obj/machinery/button/alternate/pod_doors_explodey{ + pixel_x = -25; + dir = 1; + pixel_y = -30 }, -/turf/simulated/floor/plating, -/area/map_template/merc_shuttle) +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) "uE" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 8 - }, -/obj/structure/catwalk, -/obj/structure/fuel_port{ - pixel_y = 30 - }, -/turf/simulated/floor/plating, +/obj/paint/merc, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel, +/turf/simulated/wall/titanium, /area/map_template/merc_shuttle) "uJ" = ( /obj/structure/closet/crate/freezer, @@ -1827,28 +1880,21 @@ /turf/simulated/wall/r_titanium, /area/map_template/merc_spawn) "uZ" = ( -/obj/structure/closet/crate{ - dir = 1; - name = "reserve equipment crate" +/obj/machinery/recharger/wallcharger{ + pixel_x = 26 }, -/obj/item/stack/material/plasteel/ten, -/obj/item/stack/material/steel/fifty, -/obj/item/stack/material/rods/fifty, -/obj/item/stack/material/glass/reinforced/fifty, -/obj/item/stack/material/glass/boron_reinforced/ten, -/obj/item/storage/briefcase/inflatable, -/obj/item/storage/briefcase/inflatable, -/obj/item/inflatable_dispenser, -/obj/item/shuttle_beacon, -/obj/item/shuttle_beacon, -/obj/item/shuttle_beacon, -/obj/machinery/light{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 }, -/obj/floor_decal/industrial/warning{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 }, -/turf/simulated/floor/tiled/techfloor/grid, +/turf/simulated/floor/tiled/techfloor, +/area/map_template/merc_shuttle) +"vb" = ( +/obj/paint/merc, +/obj/wallframe_spawn/reinforced/titanium, +/turf/simulated/floor/plating, /area/map_template/merc_shuttle) "vf" = ( /obj/machinery/light/small{ @@ -1858,6 +1904,8 @@ /area/map_template/merc_spawn) "vm" = ( /obj/machinery/door/airlock, +/obj/machinery/atmospherics/pipe/simple/hidden, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/tiled/steel_ridged, /area/map_template/merc_shuttle) @@ -1879,6 +1927,15 @@ }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) +"vz" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ + dir = 1 + }, +/obj/machinery/mech_recharger, +/obj/floor_decal/industrial/outline/yellow, +/mob/living/exosuit/premade/light, +/turf/simulated/floor/tiled/techfloor, +/area/map_template/merc_shuttle) "vA" = ( /obj/machinery/vitals_monitor, /obj/machinery/light{ @@ -1901,9 +1958,8 @@ /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "vH" = ( -/obj/machinery/atmospherics/pipe/manifold4w/hidden/fuel, -/obj/structure/catwalk, -/turf/simulated/floor/plating, +/obj/machinery/pipedispenser, +/turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "vN" = ( /obj/floor_decal/corner/purple{ @@ -1914,13 +1970,21 @@ /turf/simulated/floor/tiled/dark, /area/map_template/merc_spawn) "vO" = ( -/obj/structure/catwalk, -/obj/machinery/meter, -/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ - dir = 10 +/obj/structure/handrail{ + dir = 4 + }, +/obj/floor_decal/techfloor/orange{ + dir = 8 + }, +/obj/floor_decal/techfloor/orange{ + dir = 4 + }, +/obj/machinery/button/blast_door{ + pixel_x = 23; + id_tag = "merc_pod2" }, /turf/simulated/floor/plating, -/area/map_template/merc_shuttle) +/area/map_template/merc_shuttle/drop_pod) "wd" = ( /obj/machinery/sleeper{ dir = 4 @@ -1953,14 +2017,47 @@ /turf/simulated/floor/tiled, /area/map_template/merc_spawn) "wM" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ - dir = 6 +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 4 }, -/obj/machinery/portable_atmospherics/powered/pump/filled, +/turf/simulated/floor/tiled/techfloor, +/area/map_template/merc_shuttle) +"wS" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/obj/structure/closet{ + name = "tools" + }, +/obj/item/gun/energy/plasmacutter, +/obj/item/storage/belt/utility, +/obj/item/storage/belt/utility, +/obj/item/device/paint_sprayer, +/obj/item/device/paint_sprayer, +/obj/item/pickaxe/diamonddrill, +/obj/item/rcd, +/obj/item/rcd, +/obj/item/rcd_ammo/large, +/obj/item/rcd_ammo/large, +/obj/item/rcd_ammo/large, +/obj/item/rcd_ammo/large, +/obj/item/storage/toolbox/syndicate, +/obj/item/storage/toolbox/syndicate, +/obj/item/storage/toolbox/syndicate, +/obj/item/storage/toolbox/syndicate, +/obj/item/storage/toolbox/syndicate, /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "wW" = ( -/obj/machinery/atmospherics/pipe/simple/hidden, +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, /turf/simulated/floor/tiled/dark/monotile, /area/map_template/merc_shuttle) "xc" = ( @@ -1989,22 +2086,24 @@ /turf/simulated/floor/tiled/freezer, /area/map_template/merc_spawn) "xp" = ( +/obj/paint/merc, /obj/machinery/atmospherics/pipe/simple/hidden/fuel{ - dir = 9 + dir = 6 }, -/obj/structure/catwalk, -/turf/simulated/floor/plating, +/turf/simulated/wall/titanium, /area/map_template/merc_shuttle) "xq" = ( -/obj/structure/catwalk, -/turf/simulated/floor/plating, -/area/map_template/merc_shuttle) +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) "xt" = ( -/obj/machinery/light/small{ - dir = 1 +/obj/floor_decal/industrial/outline, +/obj/machinery/atmospherics/portables_connector{ + dir = 4 }, -/obj/decal/cleanable/blood/splatter, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/machinery/portable_atmospherics/canister/air/airlock{ + start_pressure = 1900 + }, +/turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "xA" = ( /obj/structure/closet/medical_wall/filled{ @@ -2038,6 +2137,15 @@ }, /turf/simulated/floor/tiled/steel_ridged, /area/map_template/merc_spawn) +"yh" = ( +/obj/structure/handrail{ + dir = 4 + }, +/obj/floor_decal/techfloor/orange{ + dir = 8 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) "yk" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 4 @@ -2045,45 +2153,49 @@ /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_spawn) "ym" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 }, -/obj/machinery/mech_recharger, -/obj/floor_decal/industrial/outline/yellow, -/mob/living/exosuit/premade/light, /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "ys" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/machinery/button/blast_door{ + pixel_x = -8; + id_tag = "merc_pod2"; + pixel_y = -23 }, -/obj/machinery/light, /turf/simulated/floor/tiled/dark/monotile, /area/map_template/merc_shuttle) "yt" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ - dir = 1 +/obj/structure/table/steel_reinforced, +/obj/floor_decal/techfloor/orange{ + dir = 5 }, -/obj/structure/closet{ - name = "tools" +/obj/machinery/power/apc/charon{ + dir = 1; + name = "north bump"; + pixel_y = 24; + req_access = null }, -/obj/item/storage/toolbox/syndicate, -/obj/item/storage/toolbox/syndicate, -/obj/item/storage/toolbox/syndicate, -/obj/item/storage/toolbox/syndicate, -/obj/item/rcd, -/obj/item/rcd, -/obj/item/rcd_ammo/large, -/obj/item/rcd_ammo/large, -/obj/item/gun/energy/plasmacutter, -/obj/item/pickaxe/diamonddrill, -/obj/item/device/paint_sprayer, -/obj/item/storage/belt/utility, -/obj/item/storage/belt/utility, -/turf/simulated/floor/tiled/techfloor, +/obj/random/powercell{ + pixel_y = 7 + }, +/obj/random/powercell{ + pixel_x = 3 + }, +/obj/machinery/recharger/wallcharger{ + pixel_x = 26 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) +"yw" = ( +/obj/paint/sun, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 5 + }, +/turf/simulated/wall/titanium, /area/map_template/merc_shuttle) "yD" = ( /obj/structure/cable{ @@ -2117,10 +2229,10 @@ /turf/simulated/floor/tiled/white/monotile, /area/map_template/merc_shuttle) "yW" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ - dir = 4 - }, /obj/machinery/optable, +/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ + dir = 1 + }, /turf/simulated/floor/tiled/white/monotile, /area/map_template/merc_shuttle) "yY" = ( @@ -2141,18 +2253,24 @@ /turf/simulated/floor/tiled/freezer, /area/map_template/merc_spawn) "zu" = ( -/obj/machinery/bodyscanner{ +/obj/paint/black, +/obj/paint_stripe/red, +/turf/simulated/wall/r_titanium, +/area/map_template/merc_shuttle/drop_pod) +"zw" = ( +/obj/structure/handrail{ + dir = 8; + pixel_x = 6 + }, +/obj/floor_decal/techfloor/orange/corner{ dir = 4 }, -/turf/simulated/floor/tiled/white/monotile, -/area/map_template/merc_shuttle) -"zw" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/fuel, -/obj/structure/catwalk, -/obj/machinery/light, -/obj/machinery/pipedispenser, -/turf/simulated/floor/tiled/techfloor, -/area/map_template/merc_shuttle) +/obj/floor_decal/techfloor/orange/corner{ + dir = 1 + }, +/obj/shuttle_landmark/merc_pod/start, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) "zC" = ( /obj/structure/table/steel_reinforced, /obj/item/stamp/chameleon, @@ -2183,6 +2301,15 @@ }, /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_spawn) +"zQ" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/floor_decal/techfloor/corner{ + dir = 4 + }, +/turf/simulated/floor/tiled/dark, +/area/map_template/merc_shuttle) "zT" = ( /obj/machinery/light{ dir = 4 @@ -2191,14 +2318,8 @@ /turf/simulated/floor/tiled/freezer, /area/map_template/merc_spawn) "zW" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 4 - }, -/obj/machinery/door/window/brigdoor/eastright{ - dir = 1; - health_max = 150; - name = "The Box"; - req_access = list("ACCESS_SYNDICATE") +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 10 }, /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) @@ -2213,10 +2334,16 @@ /turf/simulated/floor/tiled/white, /area/map_template/merc_spawn) "Ak" = ( -/obj/floor_decal/industrial/warning{ - dir = 1 +/obj/machinery/atmospherics/binary/pump/high_power/on{ + target_pressure = 10000 }, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "Am" = ( /obj/structure/cable{ @@ -2245,29 +2372,25 @@ /turf/simulated/wall/titanium, /area/map_template/merc_shuttle) "AO" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 10 }, +/obj/machinery/meter, /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "AR" = ( -/obj/structure/handrail{ - dir = 8 - }, /obj/machinery/recharger/wallcharger{ pixel_x = 26 }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) -"AS" = ( -/obj/machinery/portable_atmospherics/canister/air/airlock{ - start_pressure = 1900 - }, -/obj/machinery/atmospherics/portables_connector{ - dir = 1 - }, -/obj/floor_decal/industrial/outline, -/turf/simulated/floor/tiled/techfloor, +"AT" = ( +/obj/machinery/door/airlock/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled/white, /area/map_template/merc_shuttle) "AZ" = ( /obj/machinery/atmospherics/pipe/simple/hidden, @@ -2289,13 +2412,15 @@ /turf/simulated/floor/tiled/techfloor, /area/map_template/merc_shuttle) "Bj" = ( -/obj/machinery/light{ - dir = 4 +/obj/structure/shuttle/engine/propulsion{ + dir = 1 }, -/obj/machinery/portable_atmospherics/canister/oxygen, -/obj/floor_decal/industrial/outline/grey, -/turf/simulated/floor/tiled/techfloor, -/area/map_template/merc_shuttle) +/obj/structure/shuttle/engine/heater{ + dir = 1; + pixel_y = -32 + }, +/turf/simulated/floor/plating, +/area/map_template/merc_shuttle/drop_pod) "Bn" = ( /obj/machinery/atmospherics/pipe/simple/hidden/universal, /turf/simulated/floor/plating, @@ -2307,6 +2432,13 @@ }, /turf/simulated/floor/tiled/white/monotile, /area/map_template/merc_shuttle) +"Bq" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel, +/turf/simulated/floor/tiled/techfloor, +/area/map_template/merc_shuttle) "Br" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled/steel_ridged, @@ -2332,6 +2464,13 @@ }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) +"BG" = ( +/obj/paint/sun, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 9 + }, +/turf/simulated/wall/titanium, +/area/map_template/merc_shuttle) "BK" = ( /obj/floor_decal/industrial/warning/corner, /obj/floor_decal/industrial/warning{ @@ -2339,13 +2478,25 @@ }, /turf/simulated/floor/tiled/techfloor/grid, /area/map_template/merc_shuttle) +"BN" = ( +/obj/floor_decal/industrial/warning{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 5 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle) "BU" = ( -/obj/machinery/atmospherics/binary/pump/high_power/on{ - target_pressure = 10000 +/obj/floor_decal/techfloor/orange{ + dir = 8 }, -/obj/structure/catwalk, +/obj/floor_decal/techfloor/orange{ + dir = 4 + }, +/obj/machinery/door/airlock/external, /turf/simulated/floor/plating, -/area/map_template/merc_shuttle) +/area/map_template/merc_shuttle/drop_pod) "BW" = ( /obj/shuttle_landmark/merc/nav1, /turf/space, @@ -2394,8 +2545,23 @@ /obj/floor_decal/techfloor{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) +"CJ" = ( +/obj/paint/merc, +/obj/wallframe_spawn/reinforced/titanium, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel, +/obj/machinery/door/blast/regular/open{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id_tag = "merc_bsa_shutters" + }, +/turf/simulated/floor/plating, +/area/map_template/merc_shuttle) "CQ" = ( /obj/floor_decal/industrial/outline/yellow, /obj/machinery/computer/modular/preset/full/merc{ @@ -2489,6 +2655,29 @@ /obj/machinery/atmospherics/pipe/manifold4w/hidden, /turf/simulated/floor/tiled/techfloor/grid, /area/map_template/merc_spawn) +"Ey" = ( +/obj/floor_decal/techfloor/orange/corner, +/obj/floor_decal/techfloor/orange/corner{ + dir = 8 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) +"EF" = ( +/obj/floor_decal/industrial/outline/blue, +/obj/structure/ship_munition/disperser_charge/emp, +/obj/structure/railing{ + dir = 1 + }, +/obj/structure/railing, +/turf/simulated/floor/tiled/dark, +/area/map_template/merc_shuttle) +"EK" = ( +/obj/floor_decal/industrial/outline/yellow, +/obj/machinery/portable_atmospherics/canister/hydrogen, +/obj/item/tank/hydrogen, +/obj/item/tank/hydrogen, +/turf/simulated/floor/tiled/techfloor, +/area/map_template/merc_shuttle) "ER" = ( /turf/simulated/floor/tiled/white, /area/map_template/merc_spawn) @@ -2643,14 +2832,42 @@ /obj/decal/cleanable/blood/splatter, /turf/simulated/floor/tiled, /area/map_template/merc_spawn) +"IL" = ( +/obj/structure/bed/chair/shuttle/red{ + dir = 4 + }, +/obj/floor_decal/techfloor/orange{ + dir = 8 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) "IO" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/floor_decal/techfloor{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) +"IR" = ( +/obj/structure/handrail{ + dir = 4 + }, +/obj/floor_decal/techfloor/orange{ + dir = 4 + }, +/obj/floor_decal/techfloor/orange{ + dir = 8 + }, +/obj/machinery/button/blast_door{ + pixel_x = 23; + id_tag = "merc_pod1" + }, +/turf/simulated/floor/plating, +/area/map_template/merc_shuttle/drop_pod) "Jc" = ( /obj/wallframe_spawn/reinforced/titanium, /obj/machinery/door/blast/regular/open{ @@ -2703,6 +2920,24 @@ /obj/structure/reagent_dispensers/watertank, /turf/simulated/floor/plating, /area/map_template/merc_spawn) +"Lv" = ( +/obj/paint/merc, +/obj/machinery/vending/medical{ + idle_power_usage = 100; + req_access = list("ACCESS_SYNDICATE") + }, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel, +/turf/simulated/wall/titanium, +/area/map_template/merc_shuttle) +"LM" = ( +/obj/machinery/bodyscanner{ + dir = 4 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/tiled/white/monotile, +/area/map_template/merc_shuttle) "Mp" = ( /obj/floor_decal/corner/blue/mono, /obj/structure/table/standard, @@ -2728,6 +2963,15 @@ }, /turf/simulated/floor/tiled/dark/monotile, /area/map_template/merc_spawn) +"MI" = ( +/obj/structure/bed/chair/shuttle/red{ + dir = 8 + }, +/obj/floor_decal/techfloor/orange{ + dir = 4 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) "MK" = ( /obj/structure/reagent_dispensers/fueltank, /turf/simulated/floor/plating, @@ -2817,9 +3061,8 @@ /area/map_template/merc_shuttle) "Oo" = ( /obj/paint/merc, -/obj/machinery/vending/medical{ - idle_power_usage = 100; - req_access = list("ACCESS_SYNDICATE") +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 10 }, /turf/simulated/wall/titanium, /area/map_template/merc_shuttle) @@ -2845,6 +3088,25 @@ }, /turf/simulated/floor/tiled/steel_ridged, /area/map_template/merc_spawn) +"OJ" = ( +/obj/wallframe_spawn/reinforced/titanium, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel, +/obj/machinery/door/blast/regular/open{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id_tag = "merc_bsa_shutters" + }, +/turf/simulated/floor/plating, +/area/map_template/merc_shuttle) +"Pv" = ( +/obj/machinery/alarm{ + pixel_y = 24; + req_access = list("ACCESS_SYNDICATE") + }, +/obj/structure/handrail, +/turf/simulated/floor/tiled/white, +/area/map_template/merc_shuttle) "PC" = ( /obj/random/junk, /obj/floor_decal/borderfloorwhite/full, @@ -2911,6 +3173,25 @@ /obj/floor_decal/borderfloorwhite/full, /turf/simulated/floor/tiled, /area/map_template/merc_spawn) +"Re" = ( +/obj/floor_decal/techfloor/orange{ + dir = 4 + }, +/obj/floor_decal/techfloor/orange{ + dir = 8 + }, +/obj/machinery/door/airlock/external, +/turf/simulated/floor/plating, +/area/map_template/merc_shuttle/drop_pod) +"Ry" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/tiled/dark, +/area/map_template/merc_shuttle) "RH" = ( /obj/structure/cable{ d1 = 4; @@ -2941,6 +3222,13 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/tiled, /area/map_template/merc_spawn) +"Sc" = ( +/obj/paint/merc, +/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ + dir = 4 + }, +/turf/simulated/wall/titanium, +/area/map_template/merc_shuttle) "Sf" = ( /obj/structure/cable{ d1 = 4; @@ -2964,10 +3252,30 @@ /obj/paint/merc, /turf/simulated/floor/plating, /area/map_template/merc_shuttle) +"SJ" = ( +/obj/structure/bed/chair/shuttle/red{ + dir = 8 + }, +/obj/floor_decal/techfloor/orange{ + dir = 6 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) "SW" = ( /obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/tiled, /area/map_template/merc_spawn) +"Tg" = ( +/obj/overmap/visitable/ship/landable/merc_drop_pod, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) +"TC" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5 + }, +/turf/simulated/floor/tiled/white, +/area/map_template/merc_shuttle) "TF" = ( /obj/floor_decal/techfloor, /turf/simulated/floor/tiled/dark, @@ -3017,6 +3325,24 @@ }, /turf/simulated/floor/tiled, /area/map_template/merc_spawn) +"Uq" = ( +/obj/structure/bed/chair/shuttle/red{ + dir = 8 + }, +/obj/floor_decal/techfloor/orange{ + dir = 4 + }, +/obj/machinery/light/spot{ + dir = 4 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) +"UB" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 9 + }, +/turf/simulated/floor/tiled/techfloor, +/area/map_template/merc_shuttle) "UK" = ( /obj/floor_decal/corner/blue{ dir = 6 @@ -3029,6 +3355,22 @@ }, /turf/simulated/floor/tiled/white, /area/map_template/merc_spawn) +"UY" = ( +/obj/floor_decal/techfloor/orange/corner{ + dir = 4 + }, +/obj/floor_decal/techfloor/orange/corner{ + dir = 1 + }, +/obj/machinery/door/blast/regular{ + id_tag = "merc_pod1" + }, +/obj/machinery/button/alternate/pod_doors_explodey{ + pixel_x = -25; + pixel_y = 32 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) "Vt" = ( /obj/floor_decal/corner/blue/three_quarters{ dir = 4 @@ -3038,6 +3380,15 @@ }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_spawn) +"VH" = ( +/obj/floor_decal/industrial/outline/red, +/obj/structure/ship_munition/disperser_charge/explosive, +/obj/structure/railing, +/obj/structure/railing{ + dir = 1 + }, +/turf/simulated/floor/tiled/dark/monotile, +/area/map_template/merc_shuttle) "VJ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -3049,6 +3400,30 @@ }, /turf/simulated/floor/tiled/dark, /area/map_template/merc_shuttle) +"VT" = ( +/obj/structure/closet/crate{ + dir = 1; + name = "reserve equipment crate" + }, +/obj/item/stack/material/plasteel/ten, +/obj/item/stack/material/steel/fifty, +/obj/item/stack/material/rods/fifty, +/obj/item/stack/material/glass/reinforced/fifty, +/obj/item/stack/material/glass/boron_reinforced/ten, +/obj/item/storage/briefcase/inflatable, +/obj/item/storage/briefcase/inflatable, +/obj/item/inflatable_dispenser, +/obj/machinery/light{ + dir = 4 + }, +/obj/floor_decal/industrial/warning{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 4 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle) "Wr" = ( /obj/structure/table/rack{ pixel_x = -1 @@ -3061,14 +3436,16 @@ /turf/simulated/floor/tiled, /area/map_template/merc_spawn) "WX" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ - dir = 1 +/obj/structure/fuel_port{ + pixel_y = 32; + invisibility = 100 }, -/obj/machinery/computer/ship/engines{ - dir = 1 +/obj/floor_decal/techfloor/orange{ + dir = 9 }, -/turf/simulated/floor/tiled/techfloor, -/area/map_template/merc_shuttle) +/obj/machinery/computer/shuttle_control/explore/merc_shuttle/merc_drop_pod, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) "WY" = ( /obj/structure/cable{ d1 = 4; @@ -3114,6 +3491,13 @@ /obj/machinery/portable_atmospherics/powered/scrubber, /turf/simulated/floor/plating, /area/map_template/merc_spawn) +"XO" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 8 + }, +/turf/simulated/floor/tiled/dark, +/area/map_template/merc_shuttle) "XQ" = ( /obj/structure/hygiene/sink{ dir = 1; @@ -3187,6 +3571,15 @@ "Zl" = ( /turf/simulated/mineral, /area/space) +"Zn" = ( +/obj/structure/bed/chair/shuttle/red{ + dir = 4 + }, +/obj/floor_decal/techfloor/orange{ + dir = 10 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/map_template/merc_shuttle/drop_pod) "Zq" = ( /obj/structure/cable{ d1 = 4; @@ -3204,6 +3597,13 @@ }, /turf/simulated/floor/tiled/steel_ridged, /area/map_template/merc_spawn) +"Zt" = ( +/obj/structure/shuttle/engine/propulsion, +/obj/structure/shuttle/engine/heater{ + pixel_y = 32 + }, +/turf/simulated/floor/plating, +/area/map_template/merc_shuttle/drop_pod) "ZI" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 @@ -5033,6 +5433,10 @@ AF AF AF AF +AF +AF +AF +AF cC cC cC @@ -5067,10 +5471,6 @@ aa aa aa aa -aa -aa -aa -aa "} (19,1,1) = {" aa @@ -5132,11 +5532,15 @@ AF AF AF AF +xc +vC +xc +AF zC CQ Bh By -wM +bz AN aa aa @@ -5169,10 +5573,6 @@ aa aa aa aa -aa -aa -aa -aa "} (20,1,1) = {" aa @@ -5235,15 +5635,15 @@ kW AF xt zW +lS +UB +aw +wM aw ax BK lz -cC -aa -aa -aa -aa +sx aa aa aa @@ -5336,11 +5736,15 @@ mt pV AF qj -rL +aw AO Ak -ay +qQ ym +Bq +BN +ay +vz AN aa aa @@ -5373,10 +5777,6 @@ aa aa aa aa -aa -aa -aa -aa "} (22,1,1) = {" aa @@ -5435,12 +5835,16 @@ hJ jE jQ mG -uq +rx vm qw rN AR uZ +EK +wS +vH +VT wG yR cC @@ -5475,10 +5879,6 @@ aa aa aa aa -aa -aa -aa -aa "} (23,1,1) = {" aa @@ -5539,16 +5939,16 @@ vu VJ oT AF -qy -AF -AF AF -cC -yR -aa -aa -aa -aa +xp +uE +uE +CJ +uE +uE +Sc +oJ +BG aa aa aa @@ -5640,18 +6040,18 @@ tY kZ BA ew -uq +ka qA +sE AF -xc -vC -xc -yR -cC -aa -aa -aa -aa +Bj +ut +zu +zu +zu +zu +ut +Zt aa aa aa @@ -5742,19 +6142,19 @@ zK ld ne CE -gX -ys -AF +Ry +qA +sE +ut +ut ut -vH -xp WX -AN -aa -aa -aa -aa -aa +yh +IL +Zn +ut +ut +ut aa aa aa @@ -5845,18 +6245,18 @@ lq nm IO jK -qY +uq sz uv vO BU zw -cC -aa -aa -aa -aa -aa +Tg +xq +Ey +Re +IR +UY aa aa aa @@ -5946,19 +6346,19 @@ TF lx nn CE -gX +Ry ys -AF -uE -xq -xq +sE +ut +ut +ut yt -AN -aa -aa -aa -aa -aa +MI +Uq +SJ +ut +ut +ut aa aa aa @@ -6051,15 +6451,15 @@ pb wW rt sE -AS +AF Bj -oo -yR -cC -aa -aa -aa -aa +ut +zu +zu +zu +zu +ut +Zt aa aa aa @@ -6147,20 +6547,20 @@ nI nI ia jR -nI +qy Qs pc AF rA Oo -AF -AF -cC -yR -aa -aa -aa -aa +uE +uE +OJ +Lv +uE +uE +oJ +yw aa aa aa @@ -6255,6 +6655,10 @@ ph AF rB sH +EF +AF +Pv +xD uJ wd xA @@ -6272,10 +6676,6 @@ aa aa aa aa -aa -aa -aa -aa BW aa aa @@ -6357,6 +6757,10 @@ pj AF rG sO +XO +AT +oo +TC uS xD xD @@ -6393,10 +6797,6 @@ aa aa aa aa -aa -aa -aa -aa "} (32,1,1) = {" aa @@ -6457,17 +6857,17 @@ mj ob pt AF -zu +dY +zQ +rL +vb +LM sS xD xD xD yW -cC -aa -aa -aa -aa +sx aa aa aa @@ -6560,6 +6960,10 @@ oc pH AF AF +VH +qY +AF +AF ta AZ Bo @@ -6597,10 +7001,6 @@ aa aa aa aa -aa -aa -aa -aa "} (34,1,1) = {" aa @@ -6662,6 +7062,10 @@ oC mm mo AF +AF +AF +AF +AF Jc Jc Jc @@ -6699,10 +7103,6 @@ aa aa aa aa -aa -aa -aa -aa "} (35,1,1) = {" aa diff --git a/maps/sierra/datums/reports/deck.dm b/maps/sierra/datums/reports/deck.dm index c519a9316cf89..6322ad469cbd6 100644 --- a/maps/sierra/datums/reports/deck.dm +++ b/maps/sierra/datums/reports/deck.dm @@ -14,10 +14,6 @@ add_field(/datum/report_field/date, "Дата заполнения") add_field(/datum/report_field/time, "Время заполнения") add_field(/datum/report_field/simple_text, "Название шаттла", required = 1) - add_field(/datum/report_field/text_label/instruction, "Следующий пункт рекомендуется заполнить в порядке посещения пунктов назначения.") - add_field(/datum/report_field/pencode_text, "Пункт(ы) Назначения", required = 1) - add_field(/datum/report_field/simple_text, "Место Дислокации", required = 1) - add_field(/datum/report_field/simple_text, "Причина вылета", required = 1) add_field(/datum/report_field/text_label, "Предполетная подготовка") add_field(/datum/report_field/options/yes_no, "Корпус левой стороны без повреждений?", required = 1) add_field(/datum/report_field/options/yes_no, "Корпус правой стороны без повреждений?", required = 1) @@ -31,9 +27,6 @@ add_field(/datum/report_field/options/yes_no, "Давление в канистре воздушных шлюзов больше 200kPa?", required = 1) add_field(/datum/report_field/options/yes_no, "Набор первой помощи на борту?", required = 1) add_field(/datum/report_field/options/yes_no, "Набор инструментов на борту?", required = 1) - add_field(/datum/report_field/options/yes_no, "Скафандры для членов экспедиции на борту?", required = 1) - add_field(/datum/report_field/options/yes_no, "Другая необходимая экипировка на борту?", required = 1) - add_field(/datum/report_field/options/yes_no, "Все члены экспедиции на борту?", required = 1) add_field(/datum/report_field/options/yes_no, "Герметичность шлюзов с обеих сторон?", required = 1) permission_fields += add_field(/datum/report_field/options/yes_no, "Разрешение на вылет из ангара?", required = 1) permission_fields += add_field(/datum/report_field/signature, "Для разрешения на вылет, поставьте подпись либо печать здесь", required = 1) diff --git a/maps/sierra/icons/obj/suitstorage.dmi b/maps/sierra/icons/obj/suitstorage.dmi index ec9646f00bf32..84e251e2e620c 100644 Binary files a/maps/sierra/icons/obj/suitstorage.dmi and b/maps/sierra/icons/obj/suitstorage.dmi differ diff --git a/maps/sierra/job/jobs_medical.dm b/maps/sierra/job/jobs_medical.dm index 2e195741e8658..a5738a57d80e1 100644 --- a/maps/sierra/job/jobs_medical.dm +++ b/maps/sierra/job/jobs_medical.dm @@ -164,11 +164,12 @@ economic_power = 5 skill_points = 18 - total_positions = 1 - spawn_positions = 1 + total_positions = 2 //[было 1] + spawn_positions = 2 //[было 1] selection_color = "#013d3b" alt_titles = list( - "Pharmacist" = /singleton/hierarchy/outfit/job/sierra/crew/medical/doctor/chemist + "Pharmacist" = /singleton/hierarchy/outfit/job/sierra/crew/medical/doctor/chemist, + "Virologist" = /singleton/hierarchy/outfit/job/sierra/crew/medical/doctor/chemist/virologist ) outfit_type = /singleton/hierarchy/outfit/job/sierra/crew/medical/doctor/chemist allowed_branches = list(/datum/mil_branch/employee, /datum/mil_branch/contractor) @@ -183,7 +184,7 @@ ) access = list( access_medical, access_maint_tunnels, access_emergency_storage, - access_medical_equip, access_chemistry + access_medical_equip, access_chemistry, access_virology ) diff --git a/maps/sierra/job/jobs_misc.dm b/maps/sierra/job/jobs_misc.dm index d258c47c7d867..c22139b4fd407 100644 --- a/maps/sierra/job/jobs_misc.dm +++ b/maps/sierra/job/jobs_misc.dm @@ -55,6 +55,7 @@ supervisors = "самому себе" selection_color = "#515151" department_flag = CIV + is_semi_antagonist = TRUE account_allowed = FALSE create_record = FALSE announced = FALSE diff --git a/maps/sierra/job/outfits.dm b/maps/sierra/job/outfits.dm index e65770ba2049b..b54a2c92bd3b4 100644 --- a/maps/sierra/job/outfits.dm +++ b/maps/sierra/job/outfits.dm @@ -305,6 +305,17 @@ Keeping them simple for now, just spawning with basic EC uniforms, and pretty mu ..() BACKPACK_OVERRIDE_CHEMISTRY +//[SIERRA-ADD] VIROLOGY +/singleton/hierarchy/outfit/job/sierra/crew/medical/doctor/chemist/virologist + name = OUTFIT_JOB_NAME("Virologist - Sierra") + uniform = /obj/item/clothing/under/rank/virologist + id_types = list(/obj/item/card/id/sierra/crew/medical/chemist) + +/singleton/hierarchy/outfit/job/sierra/crew/medical/doctor/chemist/virologist/New() + ..() + BACKPACK_OVERRIDE_CHEMISTRY +//[/SIERRA-ADD] VIROLOGY + /singleton/hierarchy/outfit/job/sierra/crew/medical/counselor name = OUTFIT_JOB_NAME("Counselor - Sierra") uniform = /obj/item/clothing/under/rank/psych diff --git a/maps/sierra/machinery/machinery.dm b/maps/sierra/machinery/machinery.dm index 3183d681394e4..a42b9b97ec54b 100644 --- a/maps/sierra/machinery/machinery.dm +++ b/maps/sierra/machinery/machinery.dm @@ -73,20 +73,48 @@ islocked = 1 ssu_color = "#55aaaa" -/obj/machinery/suit_storage_unit/mining/Initialize() - . = ..() +/obj/machinery/suit_storage_unit/mining + name = "mining voidsuit storage unit" + suit= /obj/item/clothing/suit/space/void/mining + helmet = /obj/item/clothing/head/helmet/space/void/mining + boots = /obj/item/clothing/shoes/magboots + tank = /obj/item/tank/oxygen + mask = /obj/item/clothing/mask/breath + req_access = list(access_mining) + islocked = 1 ssu_color = "#b88a3b" -/obj/machinery/suit_storage_unit/engineering/Initialize() - . = ..() +/obj/machinery/suit_storage_unit/engineering + name = "engineering voidsuit storage unit" + suit= /obj/item/clothing/suit/space/void/engineering + helmet = /obj/item/clothing/head/helmet/space/void/engineering + boots = /obj/item/clothing/shoes/magboots + tank = /obj/item/tank/oxygen + mask = /obj/item/clothing/mask/breath + req_access = list(access_construction) + islocked = 1 ssu_color = "#ffbf00" -/obj/machinery/suit_storage_unit/atmos/Initialize() - . = ..() +/obj/machinery/suit_storage_unit/atmos + name = "atmospherics voidsuit storage unit" + suit= /obj/item/clothing/suit/space/void/atmos + helmet = /obj/item/clothing/head/helmet/space/void/atmos + boots = /obj/item/clothing/shoes/magboots + tank = /obj/item/tank/oxygen + mask = /obj/item/clothing/mask/breath + req_access = list(access_atmospherics) + islocked = 1 ssu_color = "#00cccc" -/obj/machinery/suit_storage_unit/science/Initialize() - . = ..() +/obj/machinery/suit_storage_unit/science + name = "excavation voidsuit storage unit" + suit= /obj/item/clothing/suit/space/void/excavation + helmet = /obj/item/clothing/head/helmet/space/void/excavation + boots = /obj/item/clothing/shoes/magboots + tank = /obj/item/tank/oxygen + mask = /obj/item/clothing/mask/breath + req_access = list(access_xenoarch) + islocked = 1 ssu_color = "#990000" /obj/machinery/suit_storage_unit/security/sapper diff --git a/maps/sierra/machinery/suit_storage.dm b/maps/sierra/machinery/suit_storage.dm index 54411726e38c5..2e43cd8e0010f 100644 --- a/maps/sierra/machinery/suit_storage.dm +++ b/maps/sierra/machinery/suit_storage.dm @@ -40,5 +40,7 @@ AddOverlays(overlay_image(icon,"[base_icon_state]_uvstrong", plane = EFFECTS_ABOVE_LIGHTING_PLANE, layer = ABOVE_LIGHTING_LAYER)) else AddOverlays(overlay_image(icon,"[base_icon_state]_uv", plane = EFFECTS_ABOVE_LIGHTING_PLANE, layer = ABOVE_LIGHTING_LAYER)) + if(islocked) + AddOverlays(overlay_image(icon, "[base_icon_state]_locked", plane = EFFECTS_ABOVE_LIGHTING_PLANE, layer = ABOVE_LIGHTING_LAYER)) else AddOverlays(overlay_image(icon, "[base_icon_state]_ready", plane = EFFECTS_ABOVE_LIGHTING_PLANE, layer = ABOVE_LIGHTING_LAYER)) diff --git a/maps/sierra/z1-z5_sierra.dmm b/maps/sierra/z1-z5_sierra.dmm index 2783f7e240ef6..14473fc948a2f 100644 --- a/maps/sierra/z1-z5_sierra.dmm +++ b/maps/sierra/z1-z5_sierra.dmm @@ -167,12 +167,7 @@ /turf/simulated/floor/tiled, /area/crew_quarters/docking) "abu" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/obj/structure/catwalk, +/obj/machinery/barrier, /turf/simulated/floor/plating, /area/maintenance/bridgedeck/starboard) "aby" = ( @@ -633,7 +628,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology) "aex" = ( @@ -1027,7 +1021,6 @@ pixel_x = -9 }, /obj/floor_decal/industrial/hatch/yellow, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology) "ahQ" = ( @@ -2309,7 +2302,6 @@ "arm" = ( /obj/floor_decal/corner/paleblue, /obj/machinery/vending/snack, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/ward) "arq" = ( @@ -2331,7 +2323,6 @@ pixel_x = -12 }, /obj/floor_decal/industrial/hatch/yellow, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology) "arG" = ( @@ -2634,9 +2625,6 @@ dir = 4; pixel_x = -24 }, -/obj/decal/cleanable/cobweb{ - dir = 4 - }, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology) "atF" = ( @@ -3001,6 +2989,7 @@ /obj/floor_decal/spline/fancy/black{ dir = 1 }, +/obj/random/clipboard, /turf/simulated/floor/tiled/dark/monotile, /area/bridge) "awD" = ( @@ -5343,15 +5332,14 @@ "aNR" = ( /obj/floor_decal/corner/green/diagonal, /obj/structure/table/glass, -/obj/machinery/light_construct{ - dir = 8 - }, /obj/structure/cable/green{ d1 = 1; d2 = 4; icon_state = "1-4" }, -/obj/random/maintenance, +/obj/machinery/light/spot{ + dir = 8 + }, /turf/simulated/floor/tiled/white, /area/medical/virology) "aNW" = ( @@ -6792,10 +6780,7 @@ /turf/simulated/floor/plating, /area/hallway/primary/seconddeck/fore) "aXW" = ( -/obj/structure/table/glass, /obj/machinery/atmospherics/unary/vent_scrubber/on, -/obj/decal/cleanable/dirt, -/obj/random/maintenance, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "aYb" = ( @@ -7412,6 +7397,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, +/obj/floor_decal/carpet/blue{ + dir = 10 + }, /turf/simulated/floor/carpet/blue, /area/crew_quarters/heads/captain) "bdv" = ( @@ -7961,14 +7949,9 @@ /area/shuttle/petrov/equipment) "bin" = ( /obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/cable/green{ - d1 = 1; + d1 = 2; d2 = 8; - icon_state = "1-8" + icon_state = "2-8" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 @@ -7976,6 +7959,23 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 }, +/obj/structure/filingcabinet, +/obj/item/folder/white, +/obj/item/folder/blue, +/obj/item/folder/red, +/obj/item/folder/yellow, +/obj/floor_decal/borderfloorblack{ + dir = 8 + }, +/obj/floor_decal/corner/darkblue/border{ + dir = 8 + }, +/obj/floor_decal/borderfloorblack/corner2{ + dir = 10 + }, +/obj/floor_decal/corner/darkblue/bordercorner2{ + dir = 10 + }, /turf/simulated/floor/tiled/dark, /area/crew_quarters/heads/captain) "biw" = ( @@ -8687,10 +8687,6 @@ /obj/catwalk_plated, /turf/simulated/floor/plating, /area/hallway/primary/seconddeck/aft) -"boE" = ( -/obj/structure/railing/mapped, -/turf/simulated/floor/reinforced, -/area/space) "boM" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -9815,7 +9811,10 @@ /obj/floor_decal/corner/green/mono, /obj/floor_decal/industrial/hatch/yellow, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/door/blast/regular, +/obj/machinery/door/blast/regular/open{ + id_tag = "vir_blast_enter"; + name = "Quarantine Blast Doors" + }, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology) "bwS" = ( @@ -10053,10 +10052,10 @@ d2 = 8; icon_state = "4-8" }, -/obj/structure/catwalk, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 }, +/obj/structure/catwalk, /turf/simulated/floor/plating, /area/maintenance/bridgedeck/starboard) "byK" = ( @@ -10410,9 +10409,6 @@ /obj/floor_decal/corner/darkblue/border{ dir = 6 }, -/obj/floor_decal/borderfloorblack/corner2{ - dir = 6 - }, /obj/machinery/firealarm{ dir = 1; pixel_y = -24 @@ -14223,6 +14219,18 @@ }, /turf/simulated/floor/plating, /area/maintenance/fourthdeck/aft) +"ceX" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/railing/mapped{ + dir = 4 + }, +/obj/structure/table/rack, +/obj/random/maintenance, +/obj/random/maintenance, +/turf/simulated/floor/plating, +/area/maintenance/bridgedeck/starboard) "ceZ" = ( /turf/simulated/wall/r_wall/prepainted, /area/vacant/infirmary) @@ -14422,7 +14430,7 @@ d2 = 2; icon_state = "1-2" }, -/turf/simulated/floor/tiled/techfloor/grid, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "cgu" = ( /obj/structure/closet/cabinet, @@ -14680,8 +14688,20 @@ d2 = 2; icon_state = "1-2" }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, /turf/simulated/floor/tiled/steel_grid, /area/security/sierra/hallway) +"ciI" = ( +/obj/structure/railing/mapped{ + dir = 1 + }, +/obj/random/obstruction, +/turf/simulated/floor/plating, +/area/maintenance/bridgedeck/starboard) "ciL" = ( /obj/structure/closet/crate/freezer, /obj/structure/railing/mapped, @@ -15462,6 +15482,7 @@ /obj/floor_decal/corner/darkblue/border{ dir = 4 }, +/obj/machinery/papershredder, /turf/simulated/floor/tiled/dark, /area/bridge) "cpO" = ( @@ -15921,6 +15942,7 @@ /obj/floor_decal/corner/darkblue/border{ dir = 4 }, +/obj/machinery/papershredder, /turf/simulated/floor/tiled/dark, /area/bridge) "ctD" = ( @@ -17046,17 +17068,24 @@ /turf/simulated/floor/wood/ebony, /area/crew_quarters/sleep/bunk) "cBw" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/floor_decal/steeldecal/steel_decals4{ - dir = 4 +/obj/floor_decal/borderfloorblack{ + dir = 9 }, -/obj/floor_decal/steeldecal/steel_decals4{ +/obj/floor_decal/corner/darkblue/border{ dir = 9 }, +/obj/structure/table/steel_reinforced, +/obj/item/storage/box/donut{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/hand_labeler{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/machinery/computer/guestpass{ + pixel_y = 30 + }, /turf/simulated/floor/tiled/dark, /area/crew_quarters/heads/captain) "cBz" = ( @@ -17257,12 +17286,10 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/tcommsat/chamber) "cDf" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" +/obj/structure/railing/mapped{ + dir = 4 }, -/obj/structure/catwalk, +/obj/machinery/constructable_frame, /turf/simulated/floor/plating, /area/maintenance/bridgedeck/starboard) "cDm" = ( @@ -17404,8 +17431,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/decal/cleanable/dirt, -/obj/random/maintenance, /turf/simulated/floor/tiled/white, /area/medical/virology) "cEd" = ( @@ -17674,7 +17699,7 @@ d2 = 4; icon_state = "2-4" }, -/turf/simulated/floor/tiled/techfloor/grid, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "cGe" = ( /obj/floor_decal/industrial/warning{ @@ -17927,7 +17952,6 @@ }, /obj/machinery/meter, /obj/decal/cleanable/dirt, -/obj/random/maintenance, /turf/simulated/floor/tiled/techfloor/grid, /area/medical/virology/atmos) "cHE" = ( @@ -20002,14 +20026,6 @@ }, /turf/simulated/floor/carpet/green, /area/medical/mentalhealth/therapyroom) -"cWK" = ( -/obj/structure/bed/chair/office/green{ - dir = 1 - }, -/obj/floor_decal/corner/paleblue, -/obj/decal/cleanable/dirt, -/turf/simulated/floor/tiled/white, -/area/medical/virology/lab) "cXg" = ( /obj/structure/cable/cyan{ d1 = 4; @@ -20066,7 +20082,6 @@ /obj/floor_decal/corner/green/border{ dir = 1 }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "cXt" = ( @@ -20102,6 +20117,8 @@ dir = 5 }, /obj/floor_decal/industrial/outline/yellow, +/obj/item/clothing/gloves/anomaly_detector, +/obj/item/storage/bolt_bag/full_of_beacons, /turf/simulated/floor/tiled, /area/quartermaster/expedition) "cXD" = ( @@ -20194,9 +20211,6 @@ /turf/simulated/floor/grass/cut, /area/crew_quarters/garden_room) "cYd" = ( -/obj/structure/bed/chair/shuttle/blue{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/visible/universal, /obj/machinery/firealarm{ pixel_y = 24 @@ -20204,6 +20218,7 @@ /obj/machinery/light{ dir = 8 }, +/obj/machinery/recharge_station, /turf/simulated/floor/tiled/steel_ridged, /area/guppy_hangar/start) "cYe" = ( @@ -22677,22 +22692,17 @@ /turf/simulated/floor/tiled/steel_ridged, /area/shuttle/escape_pod/escape_pod1/station) "dpX" = ( -/obj/structure/filingcabinet, -/obj/item/folder/white, -/obj/item/folder/blue, -/obj/item/folder/red, -/obj/item/folder/yellow, /obj/floor_decal/borderfloorblack{ dir = 1 }, /obj/floor_decal/corner/darkblue/border{ dir = 1 }, -/obj/floor_decal/borderfloorblack/corner2{ - dir = 4 - }, -/obj/floor_decal/corner/darkblue/bordercorner2{ - dir = 4 +/obj/structure/table/steel_reinforced, +/obj/item/storage/secure/briefcase/nukedisk/sierra, +/obj/prefab/hand_teleporter, +/obj/structure/noticeboard{ + pixel_y = 32 }, /turf/simulated/floor/tiled/dark, /area/crew_quarters/heads/captain) @@ -23237,7 +23247,7 @@ icon_state = "2-8" }, /obj/decal/cleanable/dirt, -/turf/simulated/floor/plating, +/turf/simulated/floor/tiled/white, /area/medical/virology) "dux" = ( /obj/floor_decal/borderfloor{ @@ -23497,7 +23507,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology) "dvW" = ( @@ -23645,7 +23654,13 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/borderfloor{ + dir = 1 + }, +/obj/floor_decal/corner/green/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "dxa" = ( /obj/machinery/atmospherics/pipe/simple/visible/blue{ @@ -24684,7 +24699,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology) "dDx" = ( @@ -25424,6 +25438,7 @@ /obj/floor_decal/spline/fancy/black{ dir = 4 }, +/obj/item/reagent_containers/food/drinks/glass2/coffeecup/corp, /turf/simulated/floor/tiled/dark/monotile, /area/bridge) "dJp" = ( @@ -25636,8 +25651,7 @@ /turf/simulated/floor/tiled/dark, /area/security/sierra/sergeant) "dLd" = ( -/obj/structure/table/standard, -/obj/random/maintenance, +/obj/structure/closet/l3closet/virology, /turf/simulated/floor/tiled/freezer, /area/medical/virology/lab) "dLe" = ( @@ -25793,7 +25807,9 @@ dir = 8; pixel_x = -24 }, -/obj/decal/cleanable/dirt, +/obj/machinery/computer/diseasesplicer{ + dir = 4 + }, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "dMC" = ( @@ -26044,22 +26060,24 @@ /turf/simulated/floor/tiled/monotile, /area/rnd/misc_lab) "dNR" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, /obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/floor_decal/borderfloor{ + dir = 8 + }, +/obj/floor_decal/corner/red/border{ + dir = 8 + }, +/obj/structure/railing/mapped{ + dir = 8; + init_color = "#aa5f61"; + color = "#aa5f61" + }, /turf/simulated/floor/tiled/steel_grid, /area/security/sierra/hallway) "dNT" = ( @@ -26696,7 +26714,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "dSU" = ( @@ -26982,7 +26999,6 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/engineering/engine_room) "dVc" = ( -/obj/structure/table/standard, /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 }, @@ -26990,10 +27006,8 @@ dir = 1; pixel_y = -24 }, -/obj/decal/cleanable/cobweb{ - dir = 1 - }, -/obj/random/maintenance, +/obj/structure/closet/secure_closet/virology, +/obj/item/storage/box/monkeycubes, /turf/simulated/floor/tiled/freezer, /area/medical/virology/lab) "dVj" = ( @@ -27436,14 +27450,6 @@ }, /turf/simulated/open, /area/hallway/primary/thirddeck/central_stairwell) -"dYn" = ( -/obj/structure/cable/yellow{ - d2 = 2; - icon_state = "0-2" - }, -/obj/floor_decal/solarpanel, -/turf/simulated/floor/reinforced, -/area/solar/bridge_starboard) "dYr" = ( /obj/machinery/vending/cigarette{ dir = 4 @@ -27585,8 +27591,8 @@ pixel_y = 24 }, /obj/structure/cable/green{ - d2 = 2; - icon_state = "0-2" + d2 = 8; + icon_state = "0-8" }, /turf/simulated/floor/carpet/purple, /area/crew_quarters/heads/captain/beach) @@ -27822,6 +27828,11 @@ /obj/machinery/light/small{ dir = 4 }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/substation/bridgedeck) "ebt" = ( @@ -29814,7 +29825,9 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/borderfloor/corner, +/obj/floor_decal/corner/green/bordercorner, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "epB" = ( /obj/machinery/alarm{ @@ -30422,6 +30435,7 @@ /obj/floor_decal/borderfloor, /obj/floor_decal/corner/brown/border, /obj/floor_decal/industrial/outline/yellow, +/obj/item/beacon_deployer/full, /turf/simulated/floor/tiled, /area/quartermaster/expedition) "etS" = ( @@ -30926,12 +30940,10 @@ /turf/simulated/floor/tiled/monotile, /area/shuttle/escape_pod/escape_pod1/station) "eym" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/structure/railing/mapped{ + dir = 1 }, -/obj/structure/catwalk, +/obj/structure/closet/firecloset, /turf/simulated/floor/plating, /area/maintenance/bridgedeck/starboard) "eyn" = ( @@ -31823,16 +31835,15 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/engineering/atmos) "eEA" = ( -/obj/floor_decal/corner/green{ - dir = 1 +/obj/machinery/atmospherics/unary/tank{ + color = "#ff0000"; + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 +/obj/machinery/light/spot{ + dir = 4 }, -/obj/decal/cleanable/dirt, -/turf/simulated/floor/tiled/white, -/area/medical/virology/lab) +/turf/simulated/floor/tiled/techfloor/grid, +/area/medical/virology/atmos) "eEC" = ( /obj/floor_decal/corner/darkblue, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ @@ -31947,7 +31958,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/borderfloor, +/obj/floor_decal/corner/green/border, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "eFr" = ( /obj/structure/cable/green{ @@ -35237,7 +35250,6 @@ /obj/floor_decal/corner/green/bordercorner2{ dir = 5 }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "ffd" = ( @@ -35413,6 +35425,9 @@ /obj/floor_decal/corner/red/border{ dir = 4 }, +/obj/machinery/ai_status_display{ + pixel_x = 32 + }, /turf/simulated/floor/tiled/steel_grid, /area/security/sierra/hallway) "fgo" = ( @@ -36732,18 +36747,10 @@ /turf/simulated/floor/tiled/white/monotile, /area/medical/sleeper) "fqm" = ( -/obj/floor_decal/borderfloorblack{ - dir = 8 - }, -/obj/floor_decal/corner/darkblue/border{ - dir = 8 - }, -/obj/structure/closet/emcloset, -/obj/machinery/camera/network/command{ - c_tag = "Command - Starboard Bridge Entry"; +/obj/structure/window/reinforced{ dir = 4 }, -/turf/simulated/floor/tiled/dark, +/turf/simulated/open, /area/bridge/hallway) "fqq" = ( /obj/paint/red, @@ -37058,6 +37065,7 @@ /obj/floor_decal/corner/darkblue/border{ dir = 6 }, +/obj/machinery/photocopier, /turf/simulated/floor/tiled/dark, /area/bridge) "ftw" = ( @@ -37756,12 +37764,12 @@ d2 = 8; icon_state = "4-8" }, -/obj/structure/catwalk, /obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, +/obj/structure/catwalk, /turf/simulated/floor/plating, /area/maintenance/bridgedeck/starboard) "fzo" = ( @@ -38485,8 +38493,6 @@ /turf/simulated/floor/plating, /area/engineering/engine_room) "fFd" = ( -/obj/structure/table/steel_reinforced, -/obj/prefab/hand_teleporter, /obj/floor_decal/borderfloorblack{ dir = 4 }, @@ -38499,7 +38505,7 @@ /obj/machinery/light{ dir = 4 }, -/obj/item/storage/secure/briefcase/nukedisk/sierra, +/obj/machinery/photocopier, /turf/simulated/floor/tiled/dark, /area/crew_quarters/heads/captain) "fFf" = ( @@ -39141,6 +39147,10 @@ /area/bridge/nano) "fJa" = ( /obj/structure/cable/yellow, +/obj/machinery/power/solar{ + id = "auxsolarstrbbridge"; + name = "Bridge Auxiliary Solar Array" + }, /obj/floor_decal/solarpanel, /turf/simulated/floor/reinforced, /area/solar/bridge_port) @@ -39217,8 +39227,14 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 9 }, -/obj/machinery/light/small, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/borderfloor{ + dir = 6 + }, +/obj/floor_decal/corner/green/border{ + dir = 6 + }, +/obj/machinery/light, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "fJV" = ( /obj/machinery/papershredder, @@ -39274,7 +39290,7 @@ d2 = 2; icon_state = "1-2" }, -/turf/simulated/floor/tiled/techfloor/grid, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "fKs" = ( /obj/floor_decal/corner/black/full, @@ -39844,18 +39860,12 @@ /turf/simulated/floor/plating, /area/shield/thirddeck) "fNY" = ( -/obj/floor_decal/borderfloorblack{ - dir = 10 - }, -/obj/floor_decal/corner/darkblue/border{ - dir = 10 - }, -/obj/machinery/atmospherics/unary/vent_pump/on{ +/obj/structure/railing/mapped{ dir = 4 }, -/obj/structure/closet/emcloset, -/turf/simulated/floor/tiled/dark, -/area/bridge/hallway) +/obj/random/obstruction, +/turf/simulated/floor/plating, +/area/maintenance/bridgedeck/starboard) "fOg" = ( /obj/machinery/organ_printer/robot/mapped, /obj/floor_decal/industrial/outline/yellow, @@ -40324,7 +40334,13 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/borderfloor{ + dir = 4 + }, +/obj/floor_decal/corner/green/border{ + dir = 4 + }, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "fRz" = ( /obj/floor_decal/techfloor/orange{ @@ -40513,11 +40529,6 @@ /obj/floor_decal/carpet/purple{ dir = 10 }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, /turf/simulated/floor/carpet/purple, /area/crew_quarters/heads/captain/beach) "fTe" = ( @@ -41061,6 +41072,15 @@ dir = 1 }, /obj/structure/closet/emcloset, +/obj/machinery/power/apc/high/critical{ + dir = 1; + name = "north bump"; + pixel_y = 24 + }, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, /turf/simulated/floor/tiled/steel_grid, /area/security/sierra/hallway) "fXm" = ( @@ -41285,11 +41305,11 @@ /turf/simulated/floor/tiled/techfloor, /area/quartermaster/storage) "fZo" = ( -/obj/structure/table/standard, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, -/obj/random/maintenance, +/obj/structure/closet/secure_closet/virology, +/obj/item/storage/box/monkeycubes, /turf/simulated/floor/tiled/freezer, /area/medical/virology/lab) "fZp" = ( @@ -41623,7 +41643,13 @@ /obj/floor_decal/techfloor/orange{ dir = 4 }, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/borderfloor/corner{ + dir = 8 + }, +/obj/floor_decal/corner/green/bordercorner{ + dir = 8 + }, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "gbC" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -42404,6 +42430,9 @@ /obj/machinery/light/spot{ dir = 1 }, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, /turf/simulated/floor/tiled/dark, /area/bridge/hallway) "gih" = ( @@ -42554,7 +42583,6 @@ /obj/floor_decal/corner/green/bordercorner2{ dir = 8 }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology) "gjE" = ( @@ -42662,7 +42690,7 @@ icon_state = "1-2" }, /obj/landmark/start{ - name = "Stowaway" + name = "Unknown" }, /turf/simulated/floor/plating, /area/maintenance/seconddeck/hangar) @@ -43289,7 +43317,6 @@ /turf/simulated/floor/tiled/white, /area/crew_quarters/galley) "gpA" = ( -/obj/structure/railing/mapped, /obj/floor_decal/techfloor/orange/corner, /obj/structure/reagent_dispensers/watertank, /turf/simulated/floor/plating, @@ -43589,7 +43616,7 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 }, -/obj/machinery/light_construct{ +/obj/machinery/light/spot{ dir = 4 }, /turf/simulated/floor/tiled/techfloor/grid, @@ -43623,11 +43650,7 @@ "grF" = ( /obj/floor_decal/corner/green/mono, /obj/floor_decal/industrial/outline/yellow, -/obj/machinery/smartfridge/secure/virology{ - req_access = null - }, -/obj/decal/cleanable/cobweb2, -/obj/decal/cleanable/dirt, +/obj/machinery/disease2/antibodyanalyser, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology/lab) "grI" = ( @@ -44406,10 +44429,13 @@ d2 = 8; icon_state = "4-8" }, -/obj/floor_decal/techfloor/orange{ +/obj/floor_decal/borderfloor{ dir = 8 }, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/corner/green/bordercorner{ + dir = 1 + }, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "gyY" = ( /turf/simulated/wall/prepainted{ @@ -45093,7 +45119,6 @@ d2 = 4; icon_state = "2-4" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "gFg" = ( @@ -45508,7 +45533,6 @@ "gHC" = ( /obj/floor_decal/corner/red, /obj/structure/table/standard, -/obj/random/maintenance, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "gHE" = ( @@ -45740,7 +45764,13 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/borderfloor{ + dir = 4 + }, +/obj/floor_decal/corner/green/border{ + dir = 4 + }, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "gJv" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -45929,6 +45959,7 @@ /obj/floor_decal/corner/darkblue/border{ dir = 5 }, +/obj/machinery/photocopier, /turf/simulated/floor/tiled/dark, /area/bridge) "gLb" = ( @@ -46820,7 +46851,7 @@ d2 = 4; icon_state = "2-4" }, -/turf/simulated/floor/plating, +/turf/simulated/floor/tiled/white, /area/medical/virology) "gRR" = ( /turf/simulated/wall/r_wall/hull, @@ -47027,7 +47058,6 @@ d2 = 8; icon_state = "2-8" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology) "gTl" = ( @@ -47453,16 +47483,17 @@ /turf/simulated/floor/tiled/techfloor, /area/maintenance/thirddeck/aftstarboard) "gWj" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/ai_status_display{ - pixel_x = -32 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 }, /obj/floor_decal/borderfloor{ - dir = 8 + dir = 9 }, /obj/floor_decal/corner/red/border{ - dir = 8 + dir = 9 }, /obj/floor_decal/borderfloor/corner2{ dir = 10 @@ -47470,6 +47501,9 @@ /obj/floor_decal/corner/red/bordercorner2{ dir = 10 }, +/obj/machinery/light{ + dir = 8 + }, /turf/simulated/floor/tiled/steel_grid, /area/security/sierra/hallway) "gWk" = ( @@ -50033,15 +50067,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/xenobiology/xenoflora) -"hqB" = ( -/obj/structure/railing/mapped{ - dir = 1 - }, -/obj/structure/railing/mapped, -/turf/simulated/floor/reinforced{ - map_airless = 1 - }, -/area/space) "hqH" = ( /obj/floor_decal/borderfloorblack{ dir = 5 @@ -50111,6 +50136,8 @@ c_tag = "Command - Bridge Port"; dir = 1 }, +/obj/random/clipboard, +/obj/item/reagent_containers/food/drinks/glass2/coffeecup/corp, /turf/simulated/floor/tiled/dark/monotile, /area/bridge) "hrz" = ( @@ -50224,7 +50251,7 @@ "hsY" = ( /obj/decal/cleanable/dirt, /obj/landmark/start{ - name = "Stowaway" + name = "Unknown" }, /turf/simulated/floor/tiled/monotile, /area/maintenance/abandoned_hydroponics) @@ -50460,7 +50487,7 @@ /obj/structure/bed/padded, /obj/item/bedsheet/blue, /obj/machinery/atmospherics/unary/vent_scrubber/on, -/obj/machinery/light_construct{ +/obj/machinery/light/spot{ dir = 4 }, /turf/simulated/floor/tiled/white, @@ -50480,12 +50507,10 @@ /turf/simulated/floor/bluegrid, /area/turret_protected/ai_upload) "hvh" = ( -/obj/structure/table/standard, /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, /obj/machinery/light_construct/small, -/obj/random/maintenance, /turf/simulated/floor/tiled/freezer, /area/medical/virology/lab) "hvk" = ( @@ -51279,7 +51304,8 @@ /obj/floor_decal/industrial/hatch/yellow, /obj/machinery/door/airlock/multi_tile/virology{ locked = 1; - id_tag = "virology_access_inner" + id_tag = "virology_access_inner"; + frequency = 1379 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/item/taperoll/engineering/applied, @@ -51288,7 +51314,10 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/door/blast/regular, +/obj/machinery/door/blast/regular/open{ + id_tag = "vir_blast_enter"; + name = "Quarantine Blast Doors" + }, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology) "hAJ" = ( @@ -53917,7 +53946,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology) "hWb" = ( @@ -55202,11 +55230,6 @@ /obj/floor_decal/carpet/purple{ dir = 8 }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, /turf/simulated/floor/carpet/purple, /area/crew_quarters/heads/captain/beach) "igT" = ( @@ -56626,6 +56649,7 @@ /obj/floor_decal/spline/fancy/black{ dir = 1 }, +/obj/random/clipboard, /turf/simulated/floor/tiled/dark/monotile, /area/bridge) "irZ" = ( @@ -56787,8 +56811,7 @@ /turf/simulated/floor/plating, /area/maintenance/thirddeck/aftport) "itC" = ( -/obj/structure/bed/chair/office/green, -/turf/simulated/floor/plating, +/turf/simulated/floor/tiled/white, /area/medical/virology/lab) "itG" = ( /obj/paint/nt_white, @@ -59322,6 +59345,7 @@ /obj/floor_decal/spline/fancy/black{ dir = 1 }, +/obj/random/documents, /turf/simulated/floor/tiled/dark/monotile, /area/bridge) "iMM" = ( @@ -59540,7 +59564,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/landmark/start{ - name = "Stowaway" + name = "Unknown" }, /turf/simulated/floor/tiled, /area/maintenance/seconddeck/aftstarboard) @@ -59564,14 +59588,6 @@ }, /turf/simulated/floor/reinforced/oxygen, /area/thruster/d1port) -"iOb" = ( -/obj/structure/cable/yellow{ - d2 = 2; - icon_state = "0-2" - }, -/obj/floor_decal/solarpanel, -/turf/simulated/floor/reinforced, -/area/solar/bridge_port) "iOc" = ( /obj/structure/table/steel, /obj/structure/sign/warning/nosmoking_1{ @@ -60595,7 +60611,6 @@ d2 = 8; icon_state = "1-8" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology) "iUO" = ( @@ -61613,8 +61628,7 @@ d2 = 2; icon_state = "1-2" }, -/obj/decal/cleanable/dirt, -/turf/simulated/floor/plating, +/turf/simulated/floor/tiled/white, /area/medical/virology/lab) "jdy" = ( /obj/structure/cable/green{ @@ -62389,7 +62403,7 @@ dir = 4 }, /obj/structure/bed/chair/armchair/black{ - dir = 4 + dir = 1 }, /turf/simulated/floor/tiled/dark, /area/crew_quarters/heads/captain) @@ -65106,9 +65120,6 @@ }, /area/space) "jGV" = ( -/obj/floor_decal/steeldecal/steel_decals4{ - dir = 9 - }, /obj/floor_decal/steeldecal/steel_decals4{ dir = 4 }, @@ -65119,9 +65130,15 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 4 + dir = 8 }, /obj/structure/disposalpipe/segment, +/obj/floor_decal/borderfloorblack{ + dir = 8 + }, +/obj/floor_decal/industrial/danger{ + dir = 8 + }, /turf/simulated/floor/tiled/dark, /area/bridge/hallway) "jGW" = ( @@ -65216,9 +65233,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 9 }, -/obj/machinery/light_construct{ - dir = 4 - }, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "jHu" = ( @@ -65272,7 +65286,6 @@ /obj/floor_decal/corner/green/bordercorner2{ dir = 1 }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "jHH" = ( @@ -65458,7 +65471,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8 }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "jJA" = ( @@ -65772,7 +65784,7 @@ autoset_access = 0 }, /obj/floor_decal/industrial/hatch/yellow, -/turf/simulated/floor/tiled/techfloor/grid, +/turf/simulated/floor/tiled, /area/hallway/primary/seconddeck/center) "jMp" = ( /obj/structure/cable/green{ @@ -66273,12 +66285,10 @@ /turf/simulated/floor/plating, /area/maintenance/seconddeck/forestarboard) "jQz" = ( -/obj/floor_decal/corner/green{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/decal/cleanable/dirt, -/turf/simulated/floor/tiled/white, +/obj/floor_decal/corner/green/mono, +/obj/floor_decal/industrial/outline/yellow, +/obj/machinery/disease2/incubator, +/turf/simulated/floor/tiled/white/monotile, /area/medical/virology/lab) "jQG" = ( /obj/machinery/atmospherics/pipe/manifold/hidden{ @@ -66435,10 +66445,6 @@ /obj/floor_decal/corner/green/bordercorner2{ dir = 9 }, -/obj/decal/cleanable/cobweb{ - dir = 4 - }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "jRN" = ( @@ -66847,8 +66853,7 @@ d2 = 8; icon_state = "4-8" }, -/obj/decal/cleanable/dirt, -/turf/simulated/floor/plating, +/turf/simulated/floor/tiled/white, /area/medical/virology/lab) "jTO" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ @@ -68053,28 +68058,9 @@ /turf/simulated/open, /area/maintenance/firstdeck/aftport) "kbR" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 - }, -/obj/machinery/power/apc/high/critical{ - dir = 8; - name = "south bump"; - pixel_x = -25 - }, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/floor_decal/borderfloor{ - dir = 8 - }, -/obj/floor_decal/corner/red/border{ - dir = 8 - }, -/turf/simulated/floor/tiled/steel_grid, +/obj/floor_decal/industrial/hatch/yellow, +/obj/structure/stairs/north, +/turf/simulated/floor/tiled/techfloor, /area/security/sierra/hallway) "kbW" = ( /obj/structure/cable/green{ @@ -69563,31 +69549,17 @@ /turf/simulated/floor/plating, /area/quartermaster/hangar/upper) "knr" = ( -/obj/structure/table/steel_reinforced, -/obj/item/hand_labeler{ - pixel_x = -4; - pixel_y = 4 - }, /obj/floor_decal/borderfloorblack{ dir = 4 }, /obj/floor_decal/corner/darkblue/border{ dir = 4 }, -/obj/floor_decal/borderfloorblack/corner2{ - dir = 5 - }, -/obj/floor_decal/corner/darkblue/bordercorner2{ - dir = 5 - }, /obj/machinery/camera/network/command{ c_tag = "Command - Captain's Quarters"; dir = 8 }, -/obj/item/storage/box/donut{ - pixel_x = 4; - pixel_y = -4 - }, +/obj/machinery/papershredder, /turf/simulated/floor/tiled/dark, /area/crew_quarters/heads/captain) "knv" = ( @@ -69841,7 +69813,6 @@ "kpb" = ( /obj/floor_decal/borderfloorblack, /obj/floor_decal/corner/green/border, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "kph" = ( @@ -70135,7 +70106,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 }, -/turf/simulated/floor/tiled/techfloor/grid, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "krI" = ( /obj/floor_decal/industrial/warning, @@ -70731,7 +70702,6 @@ /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, -/obj/decal/cleanable/dirt, /obj/machinery/button/blast_door{ dir = 1; pixel_y = -24; @@ -71665,6 +71635,8 @@ /obj/machinery/camera/network/command{ c_tag = "Command - Bridge Starboard" }, +/obj/random/drinkbottle, +/obj/item/reagent_containers/food/drinks/glass2/rocks, /turf/simulated/floor/tiled/dark/monotile, /area/bridge) "kCh" = ( @@ -73526,8 +73498,10 @@ /area/maintenance/thirddeck/foreport) "kPX" = ( /obj/floor_decal/corner/paleblue, -/obj/decal/cleanable/dirt, -/obj/item/camera_assembly, +/obj/machinery/camera/network/medbay{ + c_tag = "Virology - General Ward"; + dir = 4 + }, /turf/simulated/floor/tiled/white, /area/medical/virology/ward) "kQa" = ( @@ -75622,7 +75596,6 @@ dir = 1; pixel_y = -24 }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "lfV" = ( @@ -76835,6 +76808,8 @@ /obj/floor_decal/corner/grey/diagonal, /obj/structure/closet/secure_closet/explorer/medic, /obj/floor_decal/industrial/outline/yellow, +/obj/item/storage/box/nitrilegloves, +/obj/item/storage/box/masks, /turf/simulated/floor/tiled, /area/quartermaster/exploration) "lqa" = ( @@ -81265,6 +81240,12 @@ d2 = 2; icon_state = "1-2" }, +/obj/floor_decal/borderfloor/corner{ + dir = 8 + }, +/obj/floor_decal/corner/red/bordercorner{ + dir = 8 + }, /turf/simulated/floor/tiled/steel_grid, /area/security/sierra/hallway) "lXk" = ( @@ -82756,10 +82737,14 @@ d2 = 4; icon_state = "2-4" }, -/obj/floor_decal/techfloor/orange{ +/obj/floor_decal/borderfloor{ dir = 8 }, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/corner/green/bordercorner, +/obj/floor_decal/corner/green/bordercorner{ + dir = 8 + }, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "miw" = ( /obj/structure/table/steel, @@ -82855,7 +82840,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/ward) "mjf" = ( @@ -82989,6 +82973,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/substation/bridgedeck) "mkt" = ( @@ -83163,6 +83152,10 @@ dir = 1; pixel_y = -24 }, +/obj/machinery/camera/network/medbay{ + c_tag = "Virology - Enter"; + dir = 4 + }, /turf/simulated/floor/tiled/white, /area/medical/virology) "mmH" = ( @@ -83826,7 +83819,10 @@ /obj/machinery/door/firedoor, /obj/floor_decal/corner/green/mono, /obj/floor_decal/industrial/hatch/yellow, -/obj/machinery/door/blast/regular, +/obj/machinery/door/blast/regular/open{ + id_tag = "vir_blast_enter"; + name = "Quarantine Blast Doors" + }, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology) "msi" = ( @@ -84063,7 +84059,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/turf/simulated/floor/plating, +/turf/simulated/floor/tiled/white, /area/medical/virology) "mtR" = ( /obj/structure/cable/green{ @@ -87028,6 +87024,9 @@ pixel_x = -8; pixel_y = 28 }, +/obj/structure/window/reinforced{ + dir = 4 + }, /turf/simulated/floor/carpet/blue, /area/crew_quarters/heads/captain) "mPZ" = ( @@ -88424,18 +88423,10 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/maintenance/substation/thirddeck) "naC" = ( -/obj/floor_decal/industrial/hatch/yellow, -/obj/machinery/door/airlock/hatch{ - name = "Captain Dorm Maintenance"; - secured_wires = 1 - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/turf/simulated/floor/tiled/dark/monotile, -/area/crew_quarters/heads/captain) +/obj/structure/railing/mapped, +/obj/structure/table/rack, +/turf/simulated/floor/plating, +/area/maintenance/bridgedeck/starboard) "naG" = ( /obj/random/junk, /turf/simulated/floor/plating, @@ -89283,6 +89274,8 @@ /obj/floor_decal/spline/fancy/black{ dir = 5 }, +/obj/random/coin, +/obj/item/reagent_containers/food/drinks/glass2/coffeecup/corp, /turf/simulated/floor/tiled/dark/monotile, /area/bridge) "nim" = ( @@ -89812,10 +89805,6 @@ pixel_x = -5; pixel_y = 9 }, -/obj/machinery/light_construct{ - dir = 8 - }, -/obj/random/maintenance, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "nlA" = ( @@ -89952,18 +89941,6 @@ /obj/structure/lattice, /turf/simulated/open, /area/space) -"nmP" = ( -/obj/floor_decal/steeldecal/steel_decals4{ - dir = 5 - }, -/obj/floor_decal/steeldecal/steel_decals4{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/decal/cleanable/dirt, -/turf/simulated/floor/tiled/white, -/area/medical/virology/lab) "nmS" = ( /obj/machinery/atmospherics/unary/vent_pump/tank{ dir = 8; @@ -90025,15 +90002,6 @@ /obj/floor_decal/techfloor, /turf/simulated/floor/tiled/techfloor/grid, /area/maintenance/solar/bridge_starboard) -"nnH" = ( -/obj/structure/cable/yellow, -/obj/machinery/power/solar{ - id = "auxsolarsbridge"; - name = "Bridge Auxiliary Solar Array" - }, -/obj/floor_decal/solarpanel, -/turf/simulated/floor/reinforced, -/area/solar/bridge_port) "nnI" = ( /obj/machinery/door/firedoor, /obj/machinery/conveyor{ @@ -90359,7 +90327,6 @@ "npK" = ( /obj/structure/bed/padded, /obj/item/bedsheet/green, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/ward) "npL" = ( @@ -91465,7 +91432,7 @@ /area/security/sierra/armory/lobby) "nwZ" = ( /obj/landmark/start{ - name = "Stowaway" + name = "Unknown" }, /turf/simulated/floor/wood/walnut, /area/maintenance/firstdeck/aftstarboard) @@ -91776,9 +91743,6 @@ /area/maintenance/bridgedeck/starboard) "nzL" = ( /obj/machinery/portable_atmospherics/canister/empty, -/obj/machinery/light_construct{ - dir = 4 - }, /turf/simulated/floor/tiled/techfloor/grid, /area/medical/virology/atmos) "nzU" = ( @@ -91832,8 +91796,15 @@ /obj/floor_decal/corner/green/bordercorner2{ dir = 6 }, -/obj/decal/cleanable/dirt, -/obj/item/camera_assembly, +/obj/machinery/camera/network/medbay{ + c_tag = "Virology - Main"; + dir = 1 + }, +/obj/machinery/smartfridge/secure/virology{ + req_access = null; + pixel_y = -30; + density = 0 + }, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "nAg" = ( @@ -91966,6 +91937,8 @@ dir = 8; pixel_x = 24 }, +/obj/structure/mopbucket, +/obj/item/mop, /turf/simulated/floor/tiled/techfloor/grid, /area/medical/virology/atmos) "nBH" = ( @@ -92424,16 +92397,18 @@ /turf/simulated/floor/wood/ebony, /area/crew_quarters/sauna) "nFM" = ( -/obj/floor_decal/steeldecal/steel_decals4, -/obj/floor_decal/steeldecal/steel_decals4{ - dir = 10 - }, /obj/structure/table/steel_reinforced, /obj/item/modular_computer/tablet/lease/preset/command, /obj/item/toy/figure/captain{ pixel_x = 6; pixel_y = 2 }, +/obj/floor_decal/borderfloorblack{ + dir = 4 + }, +/obj/floor_decal/corner/darkblue/border{ + dir = 4 + }, /turf/simulated/floor/tiled/dark, /area/crew_quarters/heads/captain) "nGc" = ( @@ -92932,7 +92907,6 @@ d2 = 8; icon_state = "4-8" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "nJn" = ( @@ -94500,8 +94474,7 @@ d2 = 4; icon_state = "2-4" }, -/obj/decal/cleanable/dirt, -/turf/simulated/floor/plating, +/turf/simulated/floor/tiled/white, /area/medical/virology/lab) "nYD" = ( /turf/simulated/wall/r_wall/hull, @@ -95825,7 +95798,6 @@ dir = 1; pixel_y = -24 }, -/obj/random/maintenance, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "oif" = ( @@ -96029,7 +96001,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/structure/barricade, /obj/machinery/embedded_controller/radio/airlock/access_controller{ id_tag = "virology_access"; name = "Virology Lab Access Console"; @@ -96318,16 +96289,16 @@ /area/vacant/dungeon) "okN" = ( /obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/structure/catwalk, /obj/structure/cable/green{ d1 = 1; - d2 = 2; - icon_state = "1-2" + d2 = 8; + icon_state = "1-8" }, +/obj/structure/catwalk, /turf/simulated/floor/plating, /area/maintenance/bridgedeck/starboard) "okX" = ( @@ -96887,6 +96858,14 @@ }, /turf/simulated/floor/tiled/dark, /area/command/bsa) +"ooS" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/wall/r_wall/prepainted, +/area/maintenance/substation/bridgedeck) "ooV" = ( /obj/floor_decal/corner/grey/full, /obj/structure/cable/green{ @@ -97355,7 +97334,6 @@ "otk" = ( /obj/structure/closet/l3closet/virology, /obj/floor_decal/industrial/outline/yellow, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology) "otl" = ( @@ -100497,7 +100475,6 @@ /obj/structure/bed/chair/office/green{ dir = 4 }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "oQE" = ( @@ -101871,6 +101848,12 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8 }, +/obj/machinery/button/blast_door{ + id_tag = "vir_blast_enter"; + name = "Virology Enter"; + dir = 8; + pixel_x = 24 + }, /turf/simulated/floor/tiled/white, /area/medical/virology) "pbl" = ( @@ -102592,31 +102575,23 @@ /turf/simulated/floor/tiled/white, /area/rnd/xenobiology/level1) "pfE" = ( -/obj/floor_decal/borderfloorblack{ - dir = 9 +/obj/machinery/camera/network/command{ + c_tag = "Command - Starboard Bridge Entry"; + dir = 4 }, -/obj/floor_decal/corner/darkblue/border{ - dir = 9 +/obj/floor_decal/borderfloorblack{ + dir = 4 }, -/obj/floor_decal/borderfloorblack/corner2{ - dir = 1 +/obj/floor_decal/borderfloorblack{ + dir = 8 }, -/obj/floor_decal/corner/darkblue/bordercorner2{ +/obj/floor_decal/borderfloorblack{ dir = 1 }, -/obj/structure/table/steel, -/obj/item/storage/toolbox/emergency, -/obj/item/device/radio, -/obj/item/device/radio, -/obj/item/device/radio, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 4 - }, -/obj/structure/closet/hydrant{ - pixel_x = -28 - }, -/obj/machinery/recharger{ - pixel_y = 4 +/obj/floor_decal/corner/red/bordercee, +/obj/machinery/door/window/brigdoor/eastleft{ + autoset_access = 0; + req_access = list("ACCESS_BRIDGE") }, /turf/simulated/floor/tiled/dark, /area/bridge/hallway) @@ -103796,16 +103771,17 @@ }, /obj/item/shuttle_beacon, /obj/item/shuttle_beacon, -/obj/item/stack/flag/yellow, -/obj/item/stack/flag/yellow, -/obj/item/stack/flag/teal, -/obj/item/stack/flag/teal, -/obj/item/stack/flag/red, -/obj/item/stack/flag/red, -/obj/item/stack/flag/green, -/obj/item/stack/flag/green, +/obj/item/beacon_deployer/full, /obj/item/stack/flag/blue, /obj/item/stack/flag/blue, +/obj/item/stack/flag/green, +/obj/item/stack/flag/green, +/obj/item/stack/flag/red, +/obj/item/stack/flag/red, +/obj/item/stack/flag/teal, +/obj/item/stack/flag/yellow, +/obj/item/stack/flag/teal, +/obj/item/stack/flag/yellow, /turf/simulated/floor/tiled/techfloor, /area/quartermaster/exploration/eva) "pnI" = ( @@ -104067,16 +104043,16 @@ /turf/simulated/floor/tiled, /area/quartermaster/deckofficer) "pqb" = ( -/obj/structure/railing/mapped, -/obj/structure/railing/mapped{ - dir = 4 - }, /obj/floor_decal/techfloor/orange/corner{ dir = 8 }, -/obj/structure/table/rack, -/obj/random/trash, -/turf/simulated/floor/plating, +/obj/floor_decal/borderfloor{ + dir = 8 + }, +/obj/floor_decal/corner/green/border{ + dir = 8 + }, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "pqy" = ( /turf/simulated/floor/tiled/dark/monotile, @@ -104317,7 +104293,6 @@ d2 = 8; icon_state = "4-8" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "prP" = ( @@ -104599,18 +104574,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/thirddeck/port) -"psZ" = ( -/obj/structure/cable/yellow{ - d2 = 2; - icon_state = "0-2" - }, -/obj/machinery/power/solar{ - id = "auxsolarsbridge"; - name = "Bridge Auxiliary Solar Array" - }, -/obj/floor_decal/solarpanel, -/turf/simulated/floor/reinforced, -/area/solar/bridge_port) "ptb" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 @@ -104856,7 +104819,10 @@ dir = 5 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/plating, +/obj/machinery/light/spot{ + dir = 8 + }, +/turf/simulated/floor/tiled/freezer, /area/medical/virology/lab) "puV" = ( /obj/structure/railing/mapped{ @@ -106824,9 +106790,7 @@ "pLg" = ( /obj/floor_decal/corner/green/mono, /obj/floor_decal/industrial/outline/yellow, -/obj/machinery/constructable_frame/machine_frame, -/obj/decal/cleanable/dirt, -/obj/random/maintenance, +/obj/machinery/disease2/isolator, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology/lab) "pLk" = ( @@ -107320,7 +107284,13 @@ /obj/floor_decal/techfloor/orange{ dir = 4 }, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/borderfloor/corner{ + dir = 1 + }, +/obj/floor_decal/corner/green/bordercorner{ + dir = 1 + }, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "pPw" = ( /obj/machinery/atmospherics/pipe/simple/visible, @@ -107777,7 +107747,7 @@ icon_state = "4-8" }, /obj/decal/cleanable/dirt, -/turf/simulated/floor/plating, +/turf/simulated/floor/tiled/white, /area/medical/virology) "pST" = ( /obj/machinery/atmospherics/portables_connector{ @@ -108445,17 +108415,29 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/hallway/primary/fourthdeck/central_stairwell) "pYB" = ( -/obj/floor_decal/borderfloorblack, -/obj/floor_decal/corner/darkblue/border, +/obj/floor_decal/borderfloorblack{ + dir = 10 + }, +/obj/floor_decal/corner/darkblue/border{ + dir = 10 + }, /obj/floor_decal/borderfloorblack/corner2{ dir = 9 }, /obj/floor_decal/corner/darkblue/bordercorner2{ dir = 9 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9 +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/structure/table/steel, +/obj/machinery/recharger{ + pixel_y = 4 }, +/obj/item/storage/toolbox/emergency, +/obj/item/device/radio, +/obj/item/device/radio, +/obj/item/device/radio, /turf/simulated/floor/tiled/dark, /area/bridge/hallway) "pYI" = ( @@ -109647,18 +109629,14 @@ /turf/space, /area/space) "qgC" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 4; - icon_state = "1-4" +/obj/structure/railing/mapped{ + dir = 4 }, -/turf/simulated/floor/wood/walnut, -/area/crew_quarters/heads/captain/beach) +/obj/structure/largecrate, +/obj/random/maintenance, +/obj/random/maintenance, +/turf/simulated/floor/plating, +/area/maintenance/bridgedeck/starboard) "qgH" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -109947,9 +109925,6 @@ /obj/structure/railing/mapped{ dir = 1 }, -/obj/structure/railing/mapped{ - dir = 8 - }, /obj/machinery/portable_atmospherics/powered/scrubber, /turf/simulated/floor/plating, /area/maintenance/bridgedeck/starboard) @@ -111549,7 +111524,9 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/decal/cleanable/dirt, +/obj/machinery/light/spot{ + dir = 4 + }, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "qwJ" = ( @@ -113238,6 +113215,11 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, /turf/simulated/floor/wood/walnut, /area/crew_quarters/heads/captain/beach) "qKx" = ( @@ -113339,12 +113321,11 @@ /obj/floor_decal/corner/green/border{ dir = 4 }, -/obj/structure/closet/crate/freezer, /obj/item/device/radio/intercom{ dir = 8; pixel_x = 24 }, -/obj/random/maintenance, +/obj/machinery/computer/centrifuge, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "qLh" = ( @@ -113535,8 +113516,9 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 }, -/obj/decal/cleanable/dirt, -/obj/item/camera_assembly, +/obj/machinery/camera/network/medbay{ + c_tag = "Virology - Corridor" + }, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "qMm" = ( @@ -114677,7 +114659,8 @@ /obj/floor_decal/industrial/hatch/yellow, /obj/machinery/door/airlock/multi_tile/virology{ locked = 1; - id_tag = "virology_access_outer" + id_tag = "virology_access_outer"; + frequency = 1379 }, /obj/item/taperoll/engineering/applied, /obj/structure/cable/green{ @@ -114685,7 +114668,10 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/door/blast/regular, +/obj/machinery/door/blast/regular/open{ + id_tag = "vir_blast_enter"; + name = "Quarantine Blast Doors" + }, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology) "qUR" = ( @@ -115116,6 +115102,9 @@ /obj/structure/bed/chair/office/green{ dir = 1 }, +/obj/machinery/light/spot{ + dir = 4 + }, /turf/simulated/floor/tiled/white, /area/medical/virology/ward) "qXP" = ( @@ -115221,11 +115210,6 @@ }, /turf/simulated/floor/bluegrid, /area/turret_protected/ai) -"qYI" = ( -/obj/structure/cable/yellow, -/obj/floor_decal/solarpanel, -/turf/simulated/floor/reinforced, -/area/solar/bridge_starboard) "qYL" = ( /obj/floor_decal/corner/yellow/half{ dir = 8 @@ -116885,7 +116869,7 @@ }, /obj/machinery/door/firedoor, /obj/floor_decal/industrial/hatch/yellow, -/turf/simulated/floor/tiled/techfloor/grid, +/turf/simulated/floor/tiled, /area/hallway/primary/seconddeck/center) "rjN" = ( /obj/floor_decal/industrial/warning/corner{ @@ -117762,9 +117746,9 @@ name = "west bump"; pixel_x = -24 }, -/obj/decal/cleanable/dirt, -/obj/random/maintenance, -/obj/item/camera_assembly, +/obj/item/diseasedisk, +/obj/item/diseasedisk, +/obj/item/diseasedisk, /turf/simulated/floor/tiled/white, /area/medical/virology) "rsi" = ( @@ -117940,6 +117924,15 @@ /obj/catwalk_plated, /turf/simulated/floor/plating, /area/hallway/primary/seconddeck/aft) +"rtI" = ( +/obj/structure/railing/mapped{ + dir = 1 + }, +/obj/structure/largecrate, +/obj/random/maintenance, +/obj/random/maintenance, +/turf/simulated/floor/plating, +/area/maintenance/bridgedeck/starboard) "rtR" = ( /obj/machinery/computer/rdservercontrol{ dir = 1 @@ -118586,7 +118579,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/ward) "ryg" = ( @@ -118616,7 +118608,9 @@ d2 = 8; icon_state = "4-8" }, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/borderfloor, +/obj/floor_decal/corner/green/border, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "ryq" = ( /obj/structure/cable{ @@ -120737,13 +120731,13 @@ /turf/simulated/floor/plating, /area/maintenance/substation/seconddeck) "rOv" = ( -/obj/structure/railing/mapped{ - dir = 1 - }, /obj/floor_decal/techfloor/orange/corner{ dir = 4 }, /obj/machinery/shieldwallgen, +/obj/machinery/light{ + dir = 4 + }, /turf/simulated/floor/plating, /area/maintenance/seconddeck/starboard) "rOx" = ( @@ -120782,7 +120776,10 @@ /obj/floor_decal/corner/green/border{ dir = 8 }, -/obj/decal/cleanable/dirt, +/obj/structure/table/glass, +/obj/item/virusdish/random, +/obj/item/virusdish/random, +/obj/item/virusdish/random, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "rOW" = ( @@ -120801,10 +120798,13 @@ /obj/floor_decal/corner/green/border{ dir = 9 }, -/obj/machinery/light_construct{ +/obj/machinery/light/spot{ dir = 8 }, -/obj/decal/cleanable/dirt, +/obj/structure/reagent_dispensers/virusfood{ + pixel_x = -30; + density = 0 + }, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "rPc" = ( @@ -122858,18 +122858,8 @@ /turf/simulated/floor/wood/walnut, /area/security/sierra/breakroom) "sdI" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/light{ - dir = 8 - }, -/obj/floor_decal/borderfloor{ - dir = 8 - }, -/obj/floor_decal/corner/red/border{ - dir = 8 - }, -/turf/simulated/floor/tiled/steel_grid, +/obj/floor_decal/industrial/hatch/yellow, +/turf/simulated/floor/tiled/techfloor, /area/security/sierra/hallway) "sdS" = ( /obj/floor_decal/techfloor{ @@ -122980,7 +122970,7 @@ "seC" = ( /obj/structure/closet/l3closet/virology, /obj/floor_decal/industrial/outline/yellow, -/obj/machinery/light_construct{ +/obj/machinery/light/spot{ dir = 4 }, /turf/simulated/floor/tiled/white/monotile, @@ -123713,7 +123703,8 @@ /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 4 }, -/obj/decal/cleanable/cobweb{ +/obj/machinery/camera/network/medbay{ + c_tag = "Virology - Entrance"; dir = 4 }, /turf/simulated/floor/tiled/white, @@ -124292,7 +124283,10 @@ d2 = 2; icon_state = "0-2" }, -/obj/floor_decal/solarpanel, +/obj/machinery/power/solar{ + id = "auxsolarstrbbridge"; + name = "Bridge Auxiliary Solar Array" + }, /obj/floor_decal/solarpanel, /turf/simulated/floor/reinforced, /area/solar/bridge_port) @@ -124863,10 +124857,17 @@ /obj/floor_decal/industrial/danger/corner{ dir = 4 }, -/obj/machinery/light/small{ - dir = 8 +/obj/floor_decal/borderfloor{ + dir = 9 }, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/floor_decal/corner/green/border{ + dir = 9 + }, +/obj/machinery/camera/network/second_deck{ + c_tag = "Second Deck - Central Hallway - Starboard - Virology"; + dir = 4 + }, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "stp" = ( /obj/floor_decal/industrial/warning, @@ -126042,9 +126043,7 @@ /obj/structure/disposalpipe/segment, /obj/floor_decal/corner/green/mono, /obj/floor_decal/industrial/outline/yellow, -/obj/machinery/constructable_frame/machine_frame, -/obj/decal/cleanable/dirt, -/obj/random/maintenance, +/obj/machinery/disease2/diseaseanalyser, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology/lab) "sBA" = ( @@ -127128,7 +127127,6 @@ /turf/simulated/floor/reinforced, /area/rnd/xenobiology/level1) "sIq" = ( -/obj/structure/table/glass, /obj/floor_decal/borderfloorblack{ dir = 8 }, @@ -127136,8 +127134,7 @@ dir = 8 }, /obj/machinery/atmospherics/unary/vent_pump/on, -/obj/decal/cleanable/dirt, -/obj/random/maintenance, +/obj/structure/table/glass, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "sIr" = ( @@ -127830,6 +127827,7 @@ /obj/floor_decal/corner/darkblue/mono, /obj/floor_decal/industrial/outline/yellow, /obj/floor_decal/spline/fancy/black, +/obj/random/documents, /turf/simulated/floor/tiled/dark/monotile, /area/bridge) "sMY" = ( @@ -127933,8 +127931,7 @@ /area/crew_quarters/heads/office/iaa) "sNM" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/decal/cleanable/dirt, -/turf/simulated/floor/plating, +/turf/simulated/floor/tiled/white, /area/medical/virology/lab) "sNN" = ( /obj/structure/cable{ @@ -128283,6 +128280,9 @@ /obj/floor_decal/carpet/blue{ dir = 6 }, +/obj/structure/window/reinforced{ + dir = 4 + }, /turf/simulated/floor/carpet/blue, /area/crew_quarters/heads/captain) "sPO" = ( @@ -129105,6 +129105,18 @@ dir = 1; icon_state = "pipe-c" }, +/obj/floor_decal/borderfloorblack{ + dir = 8 + }, +/obj/floor_decal/corner/darkblue/border{ + dir = 8 + }, +/obj/floor_decal/borderfloorblack/corner2{ + dir = 8 + }, +/obj/floor_decal/corner/darkblue/bordercorner2{ + dir = 8 + }, /turf/simulated/floor/tiled/dark, /area/bridge/hallway) "sVq" = ( @@ -133499,14 +133511,16 @@ /turf/simulated/floor/tiled, /area/storage/primary) "tEK" = ( -/obj/structure/railing/mapped{ - dir = 4 +/obj/floor_decal/borderfloor{ + dir = 8 }, -/obj/structure/railing/mapped{ - dir = 1 +/obj/floor_decal/corner/green/border{ + dir = 8 }, -/obj/random/closet, -/turf/simulated/floor/plating, +/obj/machinery/light{ + dir = 8 + }, +/turf/simulated/floor/tiled, /area/maintenance/seconddeck/starboard) "tET" = ( /obj/structure/table/rack/dark, @@ -134487,12 +134501,10 @@ /turf/simulated/floor/plating, /area/maintenance/thirddeck/port) "tNI" = ( -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" +/obj/structure/railing/mapped{ + dir = 1 }, -/obj/structure/catwalk, +/obj/structure/closet/emcloset, /turf/simulated/floor/plating, /area/maintenance/bridgedeck/starboard) "tNN" = ( @@ -136225,15 +136237,12 @@ /turf/simulated/floor/tiled/white, /area/rnd/xenobiology/level1) "uau" = ( -/obj/structure/closet/secure_closet/virology, /obj/floor_decal/borderfloorblack{ dir = 4 }, /obj/floor_decal/corner/green/border{ dir = 4 }, -/obj/decal/cleanable/dirt, -/obj/random/maintenance, /obj/structure/cable/green{ d2 = 8; icon_state = "0-8" @@ -136243,6 +136252,10 @@ name = "east bump"; pixel_x = 24 }, +/obj/structure/table/glass, +/obj/item/device/scanner/health, +/obj/item/device/scanner/antibody_scanner, +/obj/item/storage/fancy/vials, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "uav" = ( @@ -136740,7 +136753,6 @@ /obj/machinery/atmospherics/portables_connector{ dir = 8 }, -/obj/decal/cleanable/cobweb2, /turf/simulated/floor/tiled/techfloor/grid, /area/medical/virology/atmos) "uel" = ( @@ -138472,15 +138484,18 @@ /turf/simulated/floor/tiled/white/monotile, /area/medical/locker) "usI" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/catwalk, /obj/machinery/light/small{ dir = 8 }, +/obj/structure/railing/mapped{ + dir = 4 + }, +/obj/structure/railing/mapped{ + dir = 1 + }, +/obj/structure/table/rack, +/obj/random/maintenance, +/obj/random/maintenance, /turf/simulated/floor/plating, /area/maintenance/bridgedeck/starboard) "usQ" = ( @@ -140543,10 +140558,10 @@ req_access = list("ACCESS_GUN") }, /obj/floor_decal/borderfloor{ - dir = 8 + dir = 10 }, /obj/floor_decal/corner/red/border{ - dir = 8 + dir = 10 }, /obj/floor_decal/borderfloor/corner2{ dir = 8 @@ -140554,6 +140569,10 @@ /obj/floor_decal/corner/red/bordercorner2{ dir = 8 }, +/obj/structure/railing/mapped{ + init_color = "#aa5f61"; + color = "#aa5f61" + }, /turf/simulated/floor/tiled/steel_grid, /area/security/sierra/hallway) "uIX" = ( @@ -141999,8 +142018,7 @@ pixel_y = 32 }, /obj/machinery/recharger, -/obj/decal/cleanable/dirt, -/obj/random/maintenance, +/obj/item/device/scanner/antibody_scanner, /turf/simulated/floor/tiled/white, /area/medical/virology) "uUl" = ( @@ -143205,6 +143223,7 @@ /obj/floor_decal/corner/grey/diagonal, /obj/structure/closet/secure_closet/explorer/engineer, /obj/floor_decal/industrial/outline/yellow, +/obj/item/clothing/gloves/insulated, /turf/simulated/floor/tiled, /area/quartermaster/exploration) "vdu" = ( @@ -143463,7 +143482,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "veV" = ( @@ -143637,7 +143655,6 @@ "vfY" = ( /obj/structure/closet/wardrobe/virology_white, /obj/floor_decal/industrial/outline/yellow, -/obj/decal/cleanable/dirt, /obj/machinery/camera/network/medbay{ c_tag = "Virology - Decontamination"; dir = 8 @@ -146663,10 +146680,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/machinery/light_construct{ +/obj/machinery/light/spot{ dir = 1 }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "vCI" = ( @@ -148010,13 +148026,6 @@ /obj/random/vendor, /turf/simulated/floor/tiled/techfloor, /area/maintenance/firstdeck/aftport) -"vNv" = ( -/obj/structure/bed/padded, -/obj/item/bedsheet/blue, -/obj/machinery/atmospherics/unary/vent_scrubber/on, -/obj/decal/cleanable/dirt, -/turf/simulated/floor/tiled/white, -/area/medical/virology/lab) "vNw" = ( /obj/floor_decal/steeldecal/steel_decals4{ dir = 5 @@ -149256,7 +149265,6 @@ d2 = 8; icon_state = "4-8" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "vWG" = ( @@ -152841,7 +152849,6 @@ }, /obj/item/bedsheet/green, /obj/machinery/light_construct, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/ward) "wyp" = ( @@ -155400,7 +155407,6 @@ dir = 4 }, /obj/decal/cleanable/dirt, -/obj/random/maintenance, /turf/simulated/floor/plating, /area/medical/virology/atmos) "wWb" = ( @@ -160500,7 +160506,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology) "xJc" = ( @@ -161685,9 +161690,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/decal/cleanable/cobweb{ - dir = 4 - }, /turf/simulated/floor/tiled/techfloor/grid, /area/medical/virology/atmos) "xRB" = ( @@ -162420,7 +162422,6 @@ /obj/machinery/door/airlock/glass/virology, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/item/taperoll/engineering/applied, /turf/simulated/floor/tiled/white/monotile, /area/medical/virology/lab) "xXH" = ( @@ -162582,6 +162583,18 @@ d2 = 2; icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/obj/floor_decal/borderfloor/corner{ + dir = 1 + }, +/obj/floor_decal/corner/red/bordercorner{ + dir = 1 + }, /turf/simulated/floor/tiled/steel_grid, /area/security/sierra/hallway) "xYX" = ( @@ -163162,10 +163175,6 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 }, -/obj/decal/cleanable/cobweb{ - dir = 1 - }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "ycO" = ( @@ -163651,7 +163660,6 @@ /obj/floor_decal/steeldecal/steel_decals4{ dir = 4 }, -/obj/structure/barricade, /turf/simulated/floor/tiled/white, /area/maintenance/seconddeck/starboard) "yfl" = ( @@ -164232,10 +164240,6 @@ /obj/floor_decal/corner/green/border{ dir = 1 }, -/obj/structure/bed/chair/office/green{ - dir = 1 - }, -/obj/decal/cleanable/dirt, /turf/simulated/floor/tiled/white, /area/medical/virology/lab) "yka" = ( @@ -264667,12 +264671,12 @@ ibG eME utn utn -vNv -jQz +huY +xAG eGe swA jJw -nmP +qhl grt qwC jHq @@ -265072,7 +265076,7 @@ hLJ uaW kCD ukG -cWK +bFk oie utn vCG @@ -265275,7 +265279,7 @@ uaW kCD huY xAG -eEA +eGe swA gFe veC @@ -265878,7 +265882,7 @@ tXe pzM sup kCD -pLg +jQz yjU itC aXW @@ -268103,7 +268107,7 @@ fNW fNW uek nzL -rCd +eEA rCd rCd yko @@ -292570,7 +292574,7 @@ ciF gNL lXc dNR -xYW +dNR xYW cwY hdb @@ -332769,7 +332773,7 @@ mvC xAE pfE fqm -fNY +fqm fVO ooC tyJ @@ -335794,7 +335798,7 @@ xRa dZf igN fSV -qgC +uaS eJL twd uYf @@ -335985,7 +335989,7 @@ vUq hRp hRp vXR -hRp +ooS hRp lLE lLE @@ -336189,10 +336193,10 @@ mVb fzh okN usI +qgC +fNY cDf -cDf -cDf -usI +ceX abu xZN xZN @@ -336387,7 +336391,7 @@ kAq uYw nzF xjT -fnn +naC aql byA sva @@ -336395,7 +336399,7 @@ ryq ryq ryq vTY -eym +rtI xZN ote bdj @@ -336799,7 +336803,7 @@ sXy ihT fnn qrJ -eym +ciI xZN mPX sPM @@ -337002,7 +337006,7 @@ ihT deq qrJ tNI -naC +xZN cBw bin yeN @@ -346088,10 +346092,10 @@ ehW erQ nIc sEd -boE -dYn +olf +erQ nIc -qYI +sEd jev uYw uYw @@ -346121,13 +346125,13 @@ uYw uYw uYw ehW -iOb +soX oOh fJa olf -psZ +soX oOh -nnH +fJa jev kHz atx @@ -346290,10 +346294,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -346323,13 +346327,13 @@ uYw uYw uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev tGd cFl @@ -346492,10 +346496,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -346525,13 +346529,13 @@ uYw uYw uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -346694,10 +346698,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -346727,13 +346731,13 @@ uYw uYw uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -346896,10 +346900,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -346929,13 +346933,13 @@ uYw uYw uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -347098,10 +347102,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -347131,13 +347135,13 @@ uYw uYw uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -347300,10 +347304,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -347333,13 +347337,13 @@ uYw uYw uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -347502,10 +347506,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -347535,13 +347539,13 @@ uYw uYw uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -347704,10 +347708,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -347737,13 +347741,13 @@ uYw uYw uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -347906,10 +347910,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -347939,13 +347943,13 @@ uYw uYw uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -348108,10 +348112,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -348145,9 +348149,9 @@ soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -348310,10 +348314,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -348347,9 +348351,9 @@ soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -348512,10 +348516,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -348549,9 +348553,9 @@ soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -348714,10 +348718,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -348751,211 +348755,9 @@ soX oOh fJa rip -psZ -oOh -nnH -jev -uYw -uYw -kHz -gSd -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -"} -(114,1,5) = {" -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -rtT -idA -aaI -uYw -uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev -uYw -uYw -uYw -uYw -uYw -uYw -uYw -uYw -uYw -uYw -uYw -uYw -eUH -ioc -yfs -uYw -uYw -uYw -uYw -uYw -uYw -uYw -uYw -uYw -uYw -uYw -uYw -ehW soX oOh fJa -rip -psZ -oOh -nnH jev uYw uYw @@ -349038,7 +348840,7 @@ wJN wJN wJN "} -(115,1,5) = {" +(114,1,5) = {" wJN wJN wJN @@ -349118,10 +348920,10 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw @@ -349129,21 +348931,21 @@ uYw uYw uYw uYw -tkp -tkp -tkp -tkp -tkp -tkp -pXl -vyz -fne -tkp -tkp -tkp -tkp -tkp -tkp +uYw +uYw +uYw +uYw +uYw +uYw +eUH +ioc +yfs +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -349155,9 +348957,9 @@ soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -349240,7 +349042,7 @@ wJN wJN wJN "} -(116,1,5) = {" +(115,1,5) = {" wJN wJN wJN @@ -349313,34 +349115,33 @@ rtT rtT rtT idA -uAJ +aaI uYw uYw ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw uYw uYw uYw +uYw tkp tkp tkp tkp tkp tkp -tkp -tkp -uet -tkp -tkp +pXl +vyz +fne tkp tkp tkp @@ -349352,18 +349153,19 @@ uYw uYw uYw uYw +uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw -dcy +kHz gSd rtT rtT @@ -349442,7 +349244,7 @@ wJN wJN wJN "} -(117,1,5) = {" +(116,1,5) = {" wJN wJN wJN @@ -349515,38 +349317,37 @@ rtT rtT rtT idA -aaI +uAJ uYw uYw ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw uYw uYw +uYw +tkp +tkp +tkp +tkp +tkp +tkp +tkp +tkp +uet +tkp +tkp tkp tkp tkp -qnf -qnf -qnf -qnf -swH -khP -adU -khP -swH -qnf -qnf -qnf -qnf tkp tkp tkp @@ -349554,18 +349355,19 @@ uYw uYw uYw uYw +uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw -kHz +dcy gSd rtT rtT @@ -349644,7 +349446,7 @@ wJN wJN wJN "} -(118,1,5) = {" +(117,1,5) = {" wJN wJN wJN @@ -349724,46 +349526,46 @@ ehW erQ nIc sEd -boE -dYn +rip +erQ nIc -qYI +sEd jev uYw uYw uYw +uYw tkp tkp tkp -fWe qnf -aUj -aUj -aUj -aUj -aUj -jZW -aUj -aUj -aUj -aUj -aUj qnf -sjy +qnf +qnf +swH +khP +adU +khP +swH +qnf +qnf +qnf +qnf tkp tkp tkp uYw uYw uYw +uYw ehW -iOb +soX oOh fJa rip -psZ +soX oOh -nnH +fJa jev uYw uYw @@ -349846,7 +349648,7 @@ wJN wJN wJN "} -(119,1,5) = {" +(118,1,5) = {" wJN wJN wJN @@ -349915,7 +349717,7 @@ rtT rtT rtT rtT -eML +rtT rtT rtT idA @@ -349924,48 +349726,48 @@ uYw uYw ehW erQ -nIc +iAt +sEd +rip +erQ +iAt sEd -boE -dYn -nIc -qYI jev uYw uYw +uYw tkp tkp tkp -qnf +fWe qnf aUj -mDz -mDz -mDz -mDz -mDz -lnN -mDz -mDz -mDz -mDz -mDz +aUj +aUj +aUj +aUj +jZW +aUj +aUj +aUj +aUj aUj qnf -qnf +sjy tkp tkp tkp uYw uYw +uYw ehW -iOb -oOh +soX +htf fJa rip -psZ -oOh -nnH +soX +htf +fJa jev uYw uYw @@ -350048,7 +349850,7 @@ wJN wJN wJN "} -(120,1,5) = {" +(119,1,5) = {" wJN wJN wJN @@ -350117,68 +349919,62 @@ rtT rtT rtT rtT +eML rtT rtT -rtT -aTh +idA aaI uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +ePH +ePH +ePH +uYw +ePH +ePH +ePH +uYw uYw uYw tkp tkp -hSu +tkp +qnf qnf aUj mDz mDz -uhW -uNO -oum -cXD -fIk -cXD -oum -uNO -qYE +mDz +mDz +mDz +lnN +mDz +mDz +mDz mDz mDz aUj qnf -hSu +qnf +tkp tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +ePH +ePH +ePH +uYw +ePH +ePH +ePH +uYw uYw uYw kHz -atx -rtT -rtT -rtT -rtT -rtT -rtT +gSd rtT rtT rtT @@ -350249,30 +350045,238 @@ wJN wJN wJN wJN -"} -(121,1,5) = {" -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN -wJN +wJN +wJN +wJN +wJN +wJN +wJN +"} +(120,1,5) = {" +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +aTh +aaI +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +tkp +tkp +hSu +qnf +aUj +mDz +mDz +uhW +uNO +oum +cXD +fIk +cXD +oum +uNO +qYE +mDz +mDz +aUj +qnf +hSu +tkp +tkp +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +kHz +atx +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +rtT +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +"} +(121,1,5) = {" +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN +wJN wJN wJN wJN @@ -350326,15 +350330,15 @@ iIe mYF uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -350362,15 +350366,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tGd @@ -350528,15 +350532,15 @@ aaI uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -350564,15 +350568,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -350730,15 +350734,15 @@ aaI uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -350766,15 +350770,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -350932,15 +350936,15 @@ aaI uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -350968,15 +350972,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -351134,15 +351138,15 @@ aaI uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -351170,15 +351174,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -351336,15 +351340,15 @@ uAJ uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw fne @@ -351372,15 +351376,15 @@ tkp fne uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -351538,15 +351542,15 @@ aaI uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -351574,15 +351578,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -351740,15 +351744,15 @@ aaI uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -351776,15 +351780,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -351942,15 +351946,15 @@ aaI uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -351978,15 +351982,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -352144,15 +352148,15 @@ aaI uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -352180,15 +352184,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -352346,15 +352350,15 @@ uAJ uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -352382,15 +352386,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -352548,15 +352552,15 @@ mYF uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -352584,15 +352588,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -352750,15 +352754,15 @@ uYw uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw tkp @@ -352786,15 +352790,15 @@ tkp tkp uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -352952,15 +352956,15 @@ uYw uYw uYw uYw -ehW -erQ -nIc -sEd -boE -dYn -nIc -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -352988,15 +352992,15 @@ tkp uYw uYw uYw -ehW -iOb -oOh -fJa -rip -psZ -oOh -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -353154,15 +353158,15 @@ uYw uYw uYw uYw -ehW -erQ -iAt -sEd -boE -dYn -iAt -qYI -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -353190,15 +353194,15 @@ uYw uYw uYw uYw -ehW -iOb -htf -fJa -hqB -psZ -htf -nnH -jev +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -353357,13 +353361,13 @@ uYw uYw uYw uYw -ePH -ePH -ePH uYw -ePH -ePH -ePH +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw @@ -353393,13 +353397,13 @@ uYw uYw uYw uYw -ePH -ePH -ePH uYw -ePH -ePH -ePH +uYw +uYw +uYw +uYw +uYw +uYw uYw uYw uYw diff --git a/maps/sierra/z7_transit.dmm b/maps/sierra/z7_transit.dmm index 952c4ddb5f82f..b33834158ae42 100644 --- a/maps/sierra/z7_transit.dmm +++ b/maps/sierra/z7_transit.dmm @@ -314,6 +314,14 @@ /obj/shuttle_landmark/ert/internim, /turf/space, /area/space) +"qc" = ( +/obj/shuttle_landmark/escape_pod/transit/pod11, +/turf/space/transit/north, +/area/space) +"ub" = ( +/obj/shuttle_landmark/escape_pod/transit/pod9, +/turf/space/transit/north, +/area/space) "Cm" = ( /obj/step_trigger/teleporter/random{ affect_ghosts = 0; @@ -327,6 +335,10 @@ }, /turf/space, /area/space) +"XE" = ( +/obj/shuttle_landmark/escape_pod/transit/pod10, +/turf/space/transit/north, +/area/space) (1,1,1) = {" aa @@ -2581,7 +2593,7 @@ aA aF aF aF -aF +qc ah aF aF @@ -3389,7 +3401,7 @@ aA aF aF aF -aF +XE ah aF aF @@ -4197,7 +4209,7 @@ aA aF aF aF -aF +ub ah aF aF diff --git a/mods/RnD/code/experiment.dm b/mods/RnD/code/experiment.dm index ad1a08c726a0b..8e4f5cd713a74 100644 --- a/mods/RnD/code/experiment.dm +++ b/mods/RnD/code/experiment.dm @@ -255,6 +255,7 @@ var/global/list/rnd_server_list = list() reward = artefacts.rnd_points points += reward saved_small_artefacts += artefacts + SSanom.earned_rnd_points += reward for(var/obj/item/small_artefact_scan_disk/input_disk in I.scanned_urm_interactions) if(input_disk.interaction_id in saved_urm_interactions) continue diff --git a/mods/_master_files/code/modules/mob/living/carbon/human/human_helpers.dm b/mods/_master_files/code/modules/mob/living/carbon/human/human_helpers.dm new file mode 100644 index 0000000000000..41fa05e35af51 --- /dev/null +++ b/mods/_master_files/code/modules/mob/living/carbon/human/human_helpers.dm @@ -0,0 +1,5 @@ +/mob/living/carbon/human/has_meson_effect() + . = FALSE + for(var/obj/screen/equipment_screen in equipment_overlays) // check through our overlays to see if we have any source of the meson overlay + if (equipment_screen.color == GLOB.global_hud.meson.color) + return TRUE diff --git a/mods/_master_files/code/modules/psionics/events/mini_spasm.dm b/mods/_master_files/code/modules/psionics/events/mini_spasm.dm index 5660aa2fb37f2..3ba16a65658a4 100644 --- a/mods/_master_files/code/modules/psionics/events/mini_spasm.dm +++ b/mods/_master_files/code/modules/psionics/events/mini_spasm.dm @@ -11,6 +11,18 @@ ) sound_to(world, sound(alarm_sound)) +/datum/event/minispasm/start() + var/list/victims = list() + for(var/obj/item/device/radio/radio in GLOB.listening_objects) + if(radio.on) + for(var/mob/living/victim in view(radio.canhear_range, radio.loc)) + if(isnull(victims[victim]) && victim.stat == CONSCIOUS && !victim.ear_deaf) + victims[victim] = radio + for(var/thing in victims) + var/mob/living/victim = thing + var/obj/item/device/radio/source = victims[victim] + do_spasm(victim, source) + /datum/event/minispasm/end() priority_announcement.Announce( \ "PRIORITY ALERT: SIGNAL BROADCAST HAS CEASED. Personnel are cleared to resume use of non-hardened radio transmission equipment. Have a nice day.", \ diff --git a/mods/anomaly/_anomaly.dme b/mods/anomaly/_anomaly.dme index 72169675cabb6..ccff1c98fb542 100644 --- a/mods/anomaly/_anomaly.dme +++ b/mods/anomaly/_anomaly.dme @@ -5,58 +5,74 @@ // Далее просто включай свой код // #include "code/something.dm" #include "code\anomaly_admin.dm" //Админские кнопочки -#include "code\anomaly_core.dm" //Ядро и основа аномалий -#include "code\anomaly_graphic.dm" //Графика и внешний вид -#include "code\anomaly_light.dm" //Освещение, вспышки и тому подобное -#include "code\anomaly_parts.dm" //Код, отвечающий за многотайтловость аномалий -#include "code\interact_with_items.dm" //Взаимодействие аномалий с предметами и обьектами -#include "code\anomaly_loop.dm" //Код, отвечающий за длительную обработку аномалии -#include "code\anomaly_deleting.dm" //Удаление аномалий, артефактов и вспомогательных частей -#include "code\anomaly_preload.dm" //Предзарядка аномалии -#include "code\anomaly_sound.dm" //Звуки у аномалий -#include "code\anomaly_randomize.dm" //Рандомизация параметров аномалии #include "code\anomaly_controller.dm" //Контроллер аномалий -#include "code\anomaly_walking.dm" //Бродячие аномалии -#include "code\anomaly_electrostatic.dm" //Электростатический расчёт +#include "code\anomaly_defines.dm" + + +//Аномалии +//Типы аномалий +#include "code\anomalies\single\cooler.dm" +#include "code\anomalies\single\electra.dm" +#include "code\anomalies\single\heater.dm" +#include "code\anomalies\single\rvach.dm" +#include "code\anomalies\single\tramplin.dm" +#include "code\anomalies\single\ventilyator.dm" +#include "code\anomalies\single\vspishka.dm" +#include "code\anomalies\single\zjarka.dm" +//аномалии 3 на 3 +#include "code\anomalies\threeandthree\cooler_3x3.dm" +#include "code\anomalies\threeandthree\electra_3x3.dm" +#include "code\anomalies\threeandthree\heater_3x3.dm" +#include "code\anomalies\threeandthree\rvach_3x3.dm" +//аномалии 2 на 2 +#include "code\anomalies\twoandtwo\cooler2x2.dm" +#include "code\anomalies\twoandtwo\heater2x2.dm" +//Сам код аномалий +#include "code\anomalies\anomalies_premades.dm" //Премейды аномалий +#include "code\anomalies\anomaly_core.dm"//Ядро аномок +#include "code\anomalies\anomaly_deleting.dm" //Код отвечающий за удаление аномалий +#include "code\anomalies\anomaly_electrostatic.dm" //Код отвечающий за просчёт подверженности турфа аномалией. +#include "code\anomalies\anomaly_graphic.dm" //Графика, спрайты - всё тут +#include "code\anomalies\anomaly_loop.dm" //Аномалии с длительной работой/воздействием +#include "code\anomalies\anomaly_parts.dm" //Мультитайтловость аномалий +#include "code\anomalies\anomaly_preload.dm" //Код, отвечающий за предзарядку аномалий перед ударом +#include "code\anomalies\anomaly_randomize.dm" //Рандомизация параметров и типа аномалий +#include "code\anomalies\anomaly_sound.dm" // Звуки, опять звуки - всё тут +#include "code\anomalies\anomaly_walking.dm" // [Work In Progress] - Блуждающие аномалии +#include "code\anomalies\interact_with_items.dm" // Влияние артефактов на предметы. TODO - варка артефактов и прочее + + + +//Код артефактов и всё с ними связанное +#include "code\artefacts\anomaly_artefacts.dm" //Ядро артефактов +#include "code\artefacts\artefact_external_interact.dm" //реакции на внешние события на артефакт/носителя +#include "code\artefacts\artefact_gravi.dm" +#include "code\artefacts\artefact_processing.dm" //Процессинг/постоянная обработка артефакта +#include "code\artefacts\artefact_pruzhina.dm" +#include "code\artefacts\artefact_spawn.dm" +#include "code\artefacts\artefact_svetlyak.dm" +#include "code\artefacts\artefact_zjar.dm" +//#include "code\artefacts\artefact_zjemchug.dm" +#include "code\artefacts\interact_with_artefacts.dm" //Интеракции с артефактом (Персонаж/URM) + + //Детекторы и прочее оборудование #include "code\detectors_and_etc\bolt.dm" #include "code\detectors_and_etc\detector.dm" #include "code\detectors_and_etc\collector.dm" +#include "code\detectors_and_etc\deployer.dm" #include "code\detectors_and_etc\beacon.dm" #include "code\detectors_and_etc\research_machine.dm" -//Код артефактов и всё с ними связанное -#include "code\artifacts\anomaly_artifact_spawn.dm" -#include "code\artifacts\anomaly_artifacts.dm" -#include "code\artifacts\interact_with_artefacts.dm" -#include "code\artifacts\artefact_pruzhina.dm" -#include "code\artifacts\artefact_zjar.dm" -#include "code\artifacts\artefact_svetlyak.dm" -#include "code\artifacts\artefact_gravi.dm" - - -//Все типы аномалий -#include "code\anomalies\electra.dm" -#include "code\anomalies\rvach.dm" -#include "code\anomalies\vspishka.dm" -#include "code\anomalies\single\tramplin.dm" -#include "code\anomalies\single\zjarka.dm" -#include "code\anomalies\heater.dm" -#include "code\anomalies\cooler.dm" -// #include "code\anomalies\ventilyator.dm" - -//Аномалия 2 на 2 -#include "code\anomalies\twoandtwo\heater2x2.dm" -#include "code\anomalies\twoandtwo\cooler2x2.dm" - -//Аномалия 3 на 3 -#include "code\anomalies\threeandthree\electra_3x3.dm" -#include "code\anomalies\threeandthree\rvach_3x3.dm" -#include "code\anomalies\threeandthree\heater_3x3.dm" -#include "code\anomalies\threeandthree\cooler_3x3.dm" +//Погода и эффекты на мониторе +#include "code\monitor_effects\monitor_core.dm" +#include "code\monitor_effects\monitor_vars.dm" +#include "code\monitor_effects\snow_monitor_effect.dm" +#include "code\monitor_effects\swamp_monitor_effect.dm" +#include "code\monitor_effects\vulcan_monitor_effect.dm" //Размещение аномалий в игре @@ -65,14 +81,23 @@ #include "code\spawn_anomalies_protocol\spawn_with_ruins.dm" #include "code\spawn_anomalies_protocol\bsd_event_protocol.dm" #include "code\spawn_anomalies_protocol\planet_spawn_types\vulcanic.dm" //Вулканическая планета -#include "code\spawn_anomalies_protocol\planet_spawn_types\ice.dm" //Ледяная планета -// #include "code\spawn_anomalies_protocol\planet_spawn_types\flying.dm" //Летающие острова +#include "code\spawn_anomalies_protocol\planet_spawn_types\ice.dm" //[WIP] Ледяная планета +#include "code\spawn_anomalies_protocol\planet_spawn_types\flying.dm" //[WIP] Летающие острова +// #include "code\spawn_anomalies_protocol\planet_spawn_types\sargas.dm" // [WIP] Саргасово болото #include "code\spawn_anomalies_protocol\spawn_on_planet.dm" //Спавн на планетах -#include "code\anomalies\threeandthree\anomalies_premades.dm" //"Заготовки" аномалий + //Карты, диреликты и прочее #include "maps\electra_ruins\electra_ruins.dm" #include "maps\zjarka_ruins\zjarka_ruins.dm" +//Код островов +#include "maps\flying_islands\flying_island.dm" +#include "maps\flying_islands\flying_island_ball.dm" +#include "maps\flying_islands\flying_island_2.dm" +#include "maps\flying_islands\flying_island_3.dm" +#include "maps\flying_islands\flying_island_4.dm" +#include "maps\flying_islands\flying_island_5.dm" + #endif diff --git a/mods/anomaly/code/README.md b/mods/anomaly/code/README.md deleted file mode 100644 index cb166076e874f..0000000000000 --- a/mods/anomaly/code/README.md +++ /dev/null @@ -1,10 +0,0 @@ -Привет -Прежде чем вы полезете смотреть код у меня будет к вам просьба -НЕ лезьте в код с целью подсмотреть как работает тот или определённый механ, это разрушает всю идею исследования -НЕ распростроняйте информацию о работе аномалий и прочего в общих чатах, это тоже очень плохо влияет на восприятие! - -mods\anomaly\code\anomalies <-- Все аномалии мода и их функционирование -mods\anomaly\code\artifacts <-- Все артефакты, их появление, свойства и интеракции с ними -mods\anomaly\code\detectors_and_etc <-- Различное оборудование для борьбы с аномалиями, их обнаружение и прочее -mods\anomaly\code\spawn_anomalies_protocol <-- Вся логика отвечающая за то как в игре размещаются и появляются аномалии. Более подробно рассписано в начале файлов: mods\anomaly\code\spawn_anomalies_protocol\core_spawn_protocol.dm -mods\anomaly\code\spawn_anomalies_protocol\spawn_with_ruins.dm diff --git a/mods/anomaly/code/anomalies/threeandthree/anomalies_premades.dm b/mods/anomaly/code/anomalies/anomalies_premades.dm similarity index 97% rename from mods/anomaly/code/anomalies/threeandthree/anomalies_premades.dm rename to mods/anomaly/code/anomalies/anomalies_premades.dm index eb0cc2d695d80..df5e974be8e65 100644 --- a/mods/anomaly/code/anomalies/threeandthree/anomalies_premades.dm +++ b/mods/anomaly/code/anomalies/anomalies_premades.dm @@ -20,7 +20,7 @@ .=..() -/obj/anomaly/thamplin/random +/obj/anomaly/tramplin/random random_throw_dir = TRUE /obj/anomaly/thamplin/random/always_powerfull_walking diff --git a/mods/anomaly/code/anomaly_core.dm b/mods/anomaly/code/anomalies/anomaly_core.dm similarity index 89% rename from mods/anomaly/code/anomaly_core.dm rename to mods/anomaly/code/anomalies/anomaly_core.dm index 105a0e08846bb..1d9655f28f7a1 100644 --- a/mods/anomaly/code/anomaly_core.dm +++ b/mods/anomaly/code/anomalies/anomaly_core.dm @@ -5,14 +5,10 @@ -Обработка перезарядки, КД аномалии -Инициализация аномалии в мире */ -#define LONG_ANOMALY_EFFECT 1 -#define MOMENTUM_ANOMALY_EFFECT 2 -#define DEFAULT_ANOMALY_EFFECT 0 -#define isanomaly(A) istype(A, /obj/anomaly) /obj/anomaly name = "Аномалия. Вы не должны это видеть." - anchored = TRUE //Чтоб аномалию не двигало в случае чего + anchored = TRUE //Чтоб аномалию не двигало в случае чего. //COULDOWN AND SMTH ///Аномалия уходит на КД после срабатывания? var/can_be_discharged = FALSE @@ -34,6 +30,8 @@ var/list/special_iniciators = list() ///Список этих самых специальных условий для аномалии var/list/special_iniciators_flags = list() + ///Вес на который реагирует аномалия. Если FALSE - не смотрит на вес. Если вес обьекта выше переменной - на него реагируют. Ниже - нет. + var/weight_sensity = FALSE /// Радиус, в котором бьёт аномалия. Ваша аномалия может "Чуять" на одном расстоянии, а бить на более большом! var/effect_range = 0 @@ -50,6 +48,10 @@ ///Аномалия по причине пересечения или ещё какой причине проверяет, может ли она "Взвестить от этого инициатора" /obj/anomaly/proc/can_be_activated(atom/movable/target) + if(weight_sensity && isitem(target)) + var/obj/item/detected_item = target + if(weight_sensity != detected_item.w_class || weight_sensity > detected_item.w_class) //Вес предмета ниже чем чувствительность аномалии. + return "too small weight" for(var/i in iniciators) if(istype(target, i)) return TRUE @@ -67,12 +69,13 @@ return FALSE ///Сама активация аномалии -/obj/anomaly/proc/activate_anomaly() +/obj/anomaly/proc/activate_anomaly(activate_friends = FALSE) return //Обязательно вызываем обработку результатов активации /obj/anomaly/activate_anomaly() .=..() + SSanom.anomalies_activated_times++ handle_after_activation() @@ -165,7 +168,10 @@ //Спавн аномалии, её размещение и т.д /obj/anomaly/Initialize() . = ..() - SSanom.add_anomaly_in_list(src) + if(is_helper) + SSanom.add_anomaly_in_helpers(src) + else + SSanom.add_anomaly_in_cores(src) preload_time = cooldown_time if(ranzomize_with_initialize) ranzomize_parameters() diff --git a/mods/anomaly/code/anomaly_deleting.dm b/mods/anomaly/code/anomalies/anomaly_deleting.dm similarity index 87% rename from mods/anomaly/code/anomaly_deleting.dm rename to mods/anomaly/code/anomalies/anomaly_deleting.dm index 2435c24094a05..fffcc73409271 100644 --- a/mods/anomaly/code/anomaly_deleting.dm +++ b/mods/anomaly/code/anomalies/anomaly_deleting.dm @@ -5,7 +5,7 @@ delete_anomaly() /obj/anomaly/proc/delete_anomaly() - SSanom.remove_anomaly_from_list(src) + SSanom.remove_anomaly_from_cores(src) calculate_effected_turfs_from_deleting_anomaly(src) if(multitile) for(var/obj/anomaly/part in list_of_parts) @@ -13,6 +13,7 @@ qdel(src) /obj/anomaly/part/delete_anomaly() + SSanom.remove_anomaly_from_helpers(src) qdel(src) diff --git a/mods/anomaly/code/anomaly_electrostatic.dm b/mods/anomaly/code/anomalies/anomaly_electrostatic.dm similarity index 100% rename from mods/anomaly/code/anomaly_electrostatic.dm rename to mods/anomaly/code/anomalies/anomaly_electrostatic.dm diff --git a/mods/anomaly/code/anomaly_graphic.dm b/mods/anomaly/code/anomalies/anomaly_graphic.dm similarity index 68% rename from mods/anomaly/code/anomaly_graphic.dm rename to mods/anomaly/code/anomalies/anomaly_graphic.dm index 9268417608b07..32e4a1e5d0c99 100644 --- a/mods/anomaly/code/anomaly_graphic.dm +++ b/mods/anomaly/code/anomalies/anomaly_graphic.dm @@ -7,11 +7,22 @@ var/activation_effect_type ///Эффект в идле var/idle_effect_type = "none" + ///Как видят аномалию при обнаружении plane = OBSERVER_PLANE ///Здесь вам потребуется вручную указать длинну анимации, для того чтоб игра вновь сделала её невидимой и некликабельной для игрока //Костыль, но лучше решения ещё не придумал var/momentum_animation_long = 0.6 SECONDS + + ///Сделать вспышку после активации? + var/light_after_activation = FALSE + ///Время, которое будет держаться свет от активации + var/time_of_light = 1 SECOND + ///Цвет вспышки + var/color_of_light = COLOR_WHITE + var/range_of_light = 3 + var/power_of_light = 2 + /obj/anomaly/proc/do_momentum_animation() if(activation_effect_type) invisibility = 0 @@ -37,3 +48,18 @@ plane = WARP_EFFECT_PLANE appearance_flags = DEFAULT_APPEARANCE_FLAGS | TILE_BOUND z_flags = ZMM_IGNORE + + + + +///Запускаем свет/вспышку +/obj/anomaly/proc/start_light() + set_light(3, 2, color_of_light) + addtimer(new Callback(src, PROC_REF(stop_light)), time_of_light) + +///Убираем свет/вспышку +/obj/anomaly/proc/stop_light() + set_light(0) + +/obj/anomaly/proc/get_detection_icon() + return detection_icon_state diff --git a/mods/anomaly/code/anomaly_loop.dm b/mods/anomaly/code/anomalies/anomaly_loop.dm similarity index 100% rename from mods/anomaly/code/anomaly_loop.dm rename to mods/anomaly/code/anomalies/anomaly_loop.dm diff --git a/mods/anomaly/code/anomaly_parts.dm b/mods/anomaly/code/anomalies/anomaly_parts.dm similarity index 89% rename from mods/anomaly/code/anomaly_parts.dm rename to mods/anomaly/code/anomalies/anomaly_parts.dm index 5f96b749ff8d0..9636b7acb5479 100644 --- a/mods/anomaly/code/anomaly_parts.dm +++ b/mods/anomaly/code/anomalies/anomaly_parts.dm @@ -5,6 +5,8 @@ /obj/anomaly ///Аномалия состоит из множества частей? var/multitile = FALSE + ///Означает, что обьект является вспомогательной частью. Применяется для контроллера. + var/is_helper = FALSE ///Радиус в котором спавнятся остальные части от ядра var/multititle_parts_range = 1 var/list/list_of_parts @@ -39,10 +41,15 @@ part.core = src ///Этот обьект в случае детектирования подходящих условий, передаст информацию ядру. +/obj/anomaly/part/Initialize() + . = ..() + SSanom.add_anomaly_in_helpers(src) + /obj/anomaly/part ///ЯДРО, которму и передатся информация var/obj/anomaly/core name = "Вспомогательная часть аномалии." + is_helper = TRUE ///Если какой-либо атом пересекает вспомогательную часть - передаём сигнал ядру @@ -66,3 +73,7 @@ return TRUE return FALSE + +/obj/anomaly/part/get_detection_icon() + if(core) + return core.get_detection_icon() diff --git a/mods/anomaly/code/anomaly_preload.dm b/mods/anomaly/code/anomalies/anomaly_preload.dm similarity index 100% rename from mods/anomaly/code/anomaly_preload.dm rename to mods/anomaly/code/anomalies/anomaly_preload.dm diff --git a/mods/anomaly/code/anomaly_randomize.dm b/mods/anomaly/code/anomalies/anomaly_randomize.dm similarity index 100% rename from mods/anomaly/code/anomaly_randomize.dm rename to mods/anomaly/code/anomalies/anomaly_randomize.dm diff --git a/mods/anomaly/code/anomaly_sound.dm b/mods/anomaly/code/anomalies/anomaly_sound.dm similarity index 91% rename from mods/anomaly/code/anomaly_sound.dm rename to mods/anomaly/code/anomalies/anomaly_sound.dm index 0a53359ac5cae..e877262ed2649 100644 --- a/mods/anomaly/code/anomaly_sound.dm +++ b/mods/anomaly/code/anomalies/anomaly_sound.dm @@ -5,7 +5,7 @@ ///Путь до звука var/sound_type ///Мощность аномалии - var/effect_power = DEFAULT_ANOMALY_EFFECT + var/effect_power = MOMENTUM_ANOMALY_EFFECT //У аномалии есть статичный звук var/have_static_sound = FALSE //Путь до звука статики diff --git a/mods/anomaly/code/anomaly_walking.dm b/mods/anomaly/code/anomalies/anomaly_walking.dm similarity index 100% rename from mods/anomaly/code/anomaly_walking.dm rename to mods/anomaly/code/anomalies/anomaly_walking.dm diff --git a/mods/anomaly/code/interact_with_items.dm b/mods/anomaly/code/anomalies/interact_with_items.dm similarity index 58% rename from mods/anomaly/code/interact_with_items.dm rename to mods/anomaly/code/anomalies/interact_with_items.dm index 5f7d86b7a6008..7f1927cbb80f8 100644 --- a/mods/anomaly/code/interact_with_items.dm +++ b/mods/anomaly/code/anomalies/interact_with_items.dm @@ -1,10 +1,12 @@ -//Здесь расположен код отвечающие за взаимодействие с предметами. +//Здесь расположен код отвечающие за взаимодействие аномалий с предметами. /proc/anything_in_ashes(atom/input_item) var/turf/to_place = get_turf(input_item) + input_item.visible_message(SPAN_BAD("[input_item] плавится!")) new /obj/decal/cleanable/ash (to_place) qdel(input_item) /proc/anything_in_remains(atom/input_item) var/turf/to_place = get_turf(input_item) + input_item.visible_message(SPAN_BAD("Тело [input_item] испепелило до костей!")) new /obj/item/remains (to_place) qdel(input_item) diff --git a/mods/anomaly/code/anomalies/cooler.dm b/mods/anomaly/code/anomalies/single/cooler.dm similarity index 97% rename from mods/anomaly/code/anomalies/cooler.dm rename to mods/anomaly/code/anomalies/single/cooler.dm index 0ab7a0be8c6eb..62f36ef6d81b4 100644 --- a/mods/anomaly/code/anomalies/cooler.dm +++ b/mods/anomaly/code/anomalies/single/cooler.dm @@ -1,7 +1,7 @@ /obj/anomaly/cooler name = "Refractions of light" with_sound = FALSE - can_born_artifacts = TRUE + can_born_artefacts = TRUE //Длинна эффекта подогрева effect_time = 30 SECONDS effect_type = LONG_ANOMALY_EFFECT diff --git a/mods/anomaly/code/anomalies/electra.dm b/mods/anomaly/code/anomalies/single/electra.dm similarity index 58% rename from mods/anomaly/code/anomalies/electra.dm rename to mods/anomaly/code/anomalies/single/electra.dm index 689bac90980fc..0e98bf37ed061 100644 --- a/mods/anomaly/code/anomalies/electra.dm +++ b/mods/anomaly/code/anomalies/single/electra.dm @@ -4,11 +4,12 @@ sound_type = 'mods/anomaly/sounds/electra_blast.ogg' activation_effect_type = "electra_activation" idle_effect_type = "electra_idle" + detection_icon_state = "electra_anomaly" layer = ABOVE_HUMAN_LAYER light_after_activation = TRUE color_of_light = COLOR_WHITE time_of_light = 1.5 SECONDS - can_born_artifacts = TRUE + can_born_artefacts = TRUE special_iniciators = list( /obj/item ) @@ -38,8 +39,9 @@ can_be_preloaded = TRUE being_preload_chance = 30 detectable_effect_range = TRUE + detection_skill_req = SKILL_EXPERIENCED -/obj/anomaly/electra/activate_anomaly() +/obj/anomaly/electra/activate_anomaly(activate_friends = TRUE) last_activation_time = world.time//Без этой строчки некоторые электры входят в вечный цикл зарядки и удара, костыль? Возможно if(need_preload) start_preload() @@ -55,10 +57,10 @@ for(var/atom/movable/atoms in objs) get_effect_by_anomaly(atoms) //Если электра является подтипом теслы, она должна взвести все другие теслы рядом - if(subtype_tesla) + if(subtype_tesla && activate_friends) var/list/victims_not_used = list() var/list/objs_second = list() - get_mobs_and_objs_in_view_fast(T, effect_range * 6, victims_not_used, objs_second) + get_mobs_and_objs_in_view_fast(T, 3, victims_not_used, objs_second) for(var/obj/anomaly/electra/electra_anomalies in objs_second) if(electra_anomalies.isready() && electra_anomalies.subtype_tesla) unwait_activate_anomaly(electra_anomalies) @@ -66,13 +68,14 @@ if(istype(anomaly_parts.core, /obj/anomaly/electra)) var/obj/anomaly/electra/electra_anomalies = anomaly_parts.core if(electra_anomalies.isready() && electra_anomalies.subtype_tesla) - unwait_activate_anomaly(electra_anomalies) + unwait_activate_anomaly(electra_anomalies, activate_friends) .=..() /obj/anomaly/electra/proc/unwait_activate_anomaly(obj/anomaly/electra/anomaly) + //Тесла должна взводить лишь соседние теслы за раз. set waitfor = FALSE last_activation_time = world.time - anomaly.activate_anomaly() + anomaly.activate_anomaly(FALSE) /obj/anomaly/electra/get_effect_by_anomaly(atom/movable/target) //Понадобится нам, если обьект по какой-либо причине будет удалён из-за удара, дабы "лучу" было куда идти @@ -83,56 +86,85 @@ return //Если цель подходит под критерии удара, мы рисуем молнию var/create_line = FALSE - //Если целью является адхерант, мы лишь заряжаем его батарею - if(istype(target, /mob/living/carbon/human/adherent)) + + + + + //Жертвой удара является моб или его наследник(ребёнок) + if(istype(target, /mob/living)) + var/mob/living/victim_target = target + SSanom.add_last_attack(target, "Электра") create_line = TRUE - var/mob/living/carbon/human/adherent/adherent = target - var/obj/item/cell/power_cell - var/obj/item/organ/internal/cell/cell = locate() in adherent.internal_organs - if(cell && cell.cell) - power_cell = cell.cell - if(power_cell) - power_cell.charge = power_cell.maxcharge - to_chat(target, SPAN_NOTICE("Your [power_cell] has been charged to capacity.")) - - //Цель удара - человек - else if(istype(target, /mob/living/carbon/human)) - for(var/obj/item/artefact/zjar/defense_artefact in target) - if(defense_artefact.current_integrity > 1) - defense_artefact.current_integrity-- - to_chat(target, SPAN_GOOD("[defense_artefact] вспыхивает красной вспышкой")) + var/list/result_effects = calculate_artefact_reaction(target, "Электра") + if(result_effects) + if(result_effects.Find("Впитывает электроудар")) + return + if(result_effects.Find("Уворачивается от молнии, молния идёт дальше")) + var/anomaly_to_victim_dir = get_dir(src, victim_target) + var/new_turf = get_ranged_target_turf(victim_target, anomaly_to_victim_dir, 1) + target_turf = new_turf + for(var/atom/movable/atom in new_turf) + get_effect_by_anomaly(atom) + beam = src.Beam(BeamTarget = target_turf, icon_state = "electra_long",icon='mods/anomaly/icons/effects.dmi',time = 0.3 SECONDS) + victim_target.dodge_animation() + to_chat(victim_target, SPAN_GOOD("Видя удар молнии словно в замедлении, вы умудряетесь увернуться от него") + ) + return + victim_target.inform_about_electroanomaly_act("thunderbolt") + //Если целью является адхерант, мы лишь заряжаем его батарею + if(istype(target, /mob/living/carbon/human/adherent)) + var/mob/living/carbon/human/adherent/adherent = target + var/obj/item/cell/power_cell + var/obj/item/organ/internal/cell/cell = locate() in adherent.internal_organs + if(cell && cell.cell) + power_cell = cell.cell + if(power_cell) + power_cell.charge = power_cell.maxcharge + to_chat(target, SPAN_NOTICE("Your [power_cell] has been charged to capacity.")) + + //Цель удара - человек + else if(ishuman(target)) + var/mob/living/carbon/human/victim = target + if(victim.health == 0) + SSanom.add_last_gibbed(target, "Электра") + anything_in_remains(victim) + return + + if(victim.lying) //Если цель лежит нам не нужно просчитывать путь до земли. Просто делаем удар в любую конечность + victim.electoanomaly_act(50, src) else - qdel(defense_artefact) - to_chat(target, SPAN_BAD("[defense_artefact] вспыхивает ярчайшей красной вспышкой и пропадает.")) - to_chat(target, SPAN_GOOD("Вы чувствуете сильный, но приятный ЖАР в месте удара. Но не боль.")) - return - var/mob/living/carbon/human/victim = target - var/list/organs = victim.list_organs_to_earth() - for(var/picked_organ in organs) - victim.electoanomaly_act(50, src, picked_organ) - //Если целью является борг, мы так же наносим ему электроудар - else if(istype(target, /mob/living/silicon/robot )) - create_line = TRUE - var/mob/living/silicon/robot/borg = target - borg.apply_damage(50, DAMAGE_BURN, def_zone = BP_CHEST) - to_chat(borg, SPAN_DANGER("Powerful electric shock detected!")) + var/list/organs = victim.list_organs_to_earth() + var/damage = 50/LAZYLEN(organs) + for(var/picked_organ in organs) + victim.electoanomaly_act(damage, src, picked_organ) + + //Если целью является борг, мы так же наносим ему электроудар + else if(istype(target, /mob/living/silicon/robot )) + create_line = TRUE + var/mob/living/silicon/robot/borg = target + borg.apply_damage(50, DAMAGE_BURN, def_zone = BP_CHEST) + to_chat(borg, SPAN_DANGER("Powerful electric shock detected!")) + + //Если целью является мех, мы наносим электроудар и эми удар + else if(istype(target, /mob/living/exosuit)) + create_line = TRUE + var/mob/living/exosuit/mech = target + mech.apply_damage(100, DAMAGE_BURN) + mech.emp_act(1) + + //Если целью является симплмоб, мы наносим электроудар + else if(istype(target, /mob/living)) + create_line = TRUE + var/mob/living/victim = target + if(victim.health == 0) + anything_in_remains(victim) + return + victim.electoanomaly_act(100, src) + + stun_and_jittery_by_electra(target) - //Если целью является мех, мы наносим электроудар и эми удар - else if(istype(target, /mob/living/exosuit)) - create_line = TRUE - var/mob/living/exosuit/mech = target - mech.apply_damage(100, DAMAGE_BURN) - mech.emp_act(1) else if(istype(target, /obj/structure/mech_wreckage )) qdel(target) - //Если целью является моб, мы наносим электроудар - else if(istype(target, /mob/living)) - create_line = TRUE - var/mob/living/victim = target - if(victim.health == 0) - anything_in_remains(victim) - return - victim.electoanomaly_act(100, src) //Если целью является пепел - мы его удаляем, чтоб не засорять аномалию else if(istype(target, /obj/decal/cleanable/ash)) @@ -150,13 +182,25 @@ create_line = TRUE anything_in_ashes(target) + + //Этот код и создаст саму молнию от центра аномалии до жертвы if(create_line) beam = src.Beam(BeamTarget = target_turf, icon_state = "electra_long",icon='mods/anomaly/icons/effects.dmi',time = 0.3 SECONDS) - +/obj/anomaly/electra/proc/stun_and_jittery_by_electra(mob/living/user) + if(ishuman(user) && !user.incapacitated()) //Человек в сознании + var/mob/living/carbon/human/victim = user + if(prob(14 * victim.get_skill_value(SKILL_HAULING))) //Максимально 70 + to_chat(user, SPAN_GOOD("Вы стойко переносите удар тока.")) + return + else + to_chat(user, SPAN_BAD("Сильный удар тока сбивает вас с ног!")) + user.Weaken(1) + user.make_jittery(min(50, 200)) + user.stun_effect_act(1,1) ///Отдельная функция для просчёта влияния электры @@ -165,19 +209,17 @@ return 0 apply_damage(shock_damage, DAMAGE_BURN, def_zone, used_weapon="Electrocution") + return shock_damage - stun_effect_act(1,1, def_zone) +///Выводит в чат о электроударе +/mob/living/proc/inform_about_electroanomaly_act(source) src.visible_message( SPAN_WARNING("[src] was electrocuted[source ? " by the [source]" : ""]!"), \ SPAN_DANGER("You feel a powerful shock course through your body!"), \ SPAN_WARNING("You hear a heavy electrical crack.") \ ) - Weaken(1) - make_jittery(min(shock_damage*5, 200)) - return shock_damage - //Выдаёт список конечностей от введёной конечности до земли /mob/living/carbon/human/proc/list_organs_to_earth(input_organ) var/list/result_damaged_zones = list() @@ -222,3 +264,12 @@ else if(attack_zone == BP_R_LEG) LAZYADD(result_damaged_zones, BP_R_FOOT) return result_damaged_zones + + +/obj/anomaly/electra/get_detection_icon() + if(effect_range == 1) + return "electra_detection" + else if(effect_range == 2) + return "tesla_first_detection" + else if(effect_range > 2) + return "tesla_second_detection" diff --git a/mods/anomaly/code/anomalies/heater.dm b/mods/anomaly/code/anomalies/single/heater.dm similarity index 94% rename from mods/anomaly/code/anomalies/heater.dm rename to mods/anomaly/code/anomalies/single/heater.dm index f216582d914ed..2c7b9ec5dea28 100644 --- a/mods/anomaly/code/anomalies/heater.dm +++ b/mods/anomaly/code/anomalies/single/heater.dm @@ -1,11 +1,12 @@ /obj/anomaly/heater name = "Refractions of light" with_sound = FALSE - can_born_artifacts = TRUE + can_born_artefacts = TRUE //Длинна эффекта подогрева effect_time = 30 SECONDS effect_type = LONG_ANOMALY_EFFECT cooldown_time = 30 SECONDS + detection_icon_state = "hot_anomaly" iniciators = list( /mob/living ) diff --git a/mods/anomaly/code/anomalies/rvach.dm b/mods/anomaly/code/anomalies/single/rvach.dm similarity index 65% rename from mods/anomaly/code/anomalies/rvach.dm rename to mods/anomaly/code/anomalies/single/rvach.dm index a8930b15852b2..58a7e83c14377 100644 --- a/mods/anomaly/code/anomalies/rvach.dm +++ b/mods/anomaly/code/anomalies/single/rvach.dm @@ -8,13 +8,15 @@ with_sound = TRUE sound_type = 'mods/anomaly/sounds/rvach_activation.ogg' idle_effect_type = "rvach_idle" - activation_effect_type = "rvach_activation" - can_born_artifacts = TRUE + activation_effect_type = "gravy_anomaly_down" + detection_icon_state = "hot_anomaly" + can_born_artefacts = TRUE + weight_sensity = ITEM_SIZE_LARGE ///Сколько длится первая фаза рвача(всасывание) - effect_time = 4 SECONDS + effect_time = 3.5 SECONDS effect_type = LONG_ANOMALY_EFFECT effect_power = RVACH_DAMAGE_EFFECT - cooldown_time = 15 SECONDS + cooldown_time = 25 SECONDS iniciators = list( /mob/living, /obj/item @@ -23,6 +25,7 @@ /obj/item/artefact/gravi = 1 ) artefact_spawn_chance = 20 + detection_skill_req = SKILL_EXPERIENCED //Аномалия выполняет своё финальное воздействие на все обьекты что оказались в её центре /obj/anomaly/rvach/proc/get_end_effect_by_anomaly(target) @@ -31,11 +34,21 @@ if(effect_power == RVACH_DESTROY_EFFECT) if(istype(target, /mob/living)) var/mob/living/victim = target + SSanom.add_last_gibbed(target, "Рвач") + var/list/result_effects = calculate_artefact_reaction(target, "Гиб Рвача") + if(result_effects) + if(result_effects.Find("Защищает от гиба рвачом")) + return victim.gib() playsound(src, 'mods/anomaly/sounds/rvach_gibbed.ogg', 100, FALSE ) //Если рвач обычный else if(effect_power == RVACH_DAMAGE_EFFECT) + SSanom.add_last_attack(target, "Рвач") + var/list/result_effects = calculate_artefact_reaction(target, "Гиб Рвача") + if(result_effects) + if(result_effects.Find("Защищает от гиба рвачом")) + return if(istype(target, /mob/living/carbon/human)) var/mob/living/carbon/human/victim = target if(!victim.incapacitated(INCAPACITATION_UNRESISTING) == TRUE) //Убедимся что наш чувак в сознании @@ -60,6 +73,7 @@ playsound(src, 'mods/anomaly/sounds/rvach_gibbed.ogg', 100, FALSE ) else if(istype(target, /mob/living)) var/mob/living/victim = target + SSanom.add_last_gibbed(target, "Рвач") victim.gib() playsound(src, 'mods/anomaly/sounds/rvach_gibbed.ogg', 100, FALSE ) else if(istype(target, /obj/item)) @@ -124,20 +138,41 @@ Weaken(5) /mob/living/carbon/human/rvach_anomaly_pull(turf/target, current_size) - if(target != src.loc) - adjust_stamina(-30) - to_chat(src, SPAN_BAD("Не могу, рано, меня с силой тащит обратно, тяжёло!")) - if(stamina < 30) - Paralyse(1) - to_chat(src, SPAN_BAD("Нет сил!")) - step_towards(src, target) - Weaken(1) + if(get_turf(target) != get_turf(src)) + step_towards(src, target) + Weaken(5) /obj/anomaly/rvach/Crossed(atom/movable/O) if(currently_active) return if(currently_charging_after_activation) return - if(can_be_activated(O)) + if(can_be_activated(O) == "too small weight") + O.forceMove(get_turf(src)) + else if(can_be_activated(O)) activate_anomaly() - return + +//Человек пытается выбраться из рвача FALSE - не даём вылезти, TRUE - даём +/obj/anomaly/rvach/Uncross(O) + if(currently_charging_after_activation || !currently_active) + return TRUE + if(!ishuman(O)) + return TRUE + if(do_after(O, 2 SECONDS, src, DO_PUBLIC_UNIQUE | DO_BAR_OVER_USER, INCAPACITATION_NONE)) + var/mob/living/jumper = O + jumper.forceMove(get_ranged_target_turf(jumper, jumper.dir, 1)) + //После того как игрок выпрыгнул из рвача, тот может опять его всосать если он вылез слишком рано. + //Но Игрок смотрящий на вылезшего игрока может выхватить его, если будет достаточно близко когда наша + //Жертва выпрыгнет + var/turf/helper_turf = get_ranged_target_turf(jumper, jumper.dir, 1) + for(var/mob/living/carbon/human/helper in helper_turf) + if(helper.a_intent == I_HELP && turn(jumper.dir, 180) == helper.dir && helper.incapacitated(INCAPACITATION_UNRESISTING) != TRUE) //Лезущий и помощник должны смотреть друг другу в лицо + to_chat(jumper, SPAN_GOOD("[helper] выхватывает вас за протянутую руку!")) + to_chat(helper, SPAN_GOOD("Вы дёргаете [jumper] на себя за протянутую руку!")) + jumper.forceMove(get_ranged_target_turf(jumper, jumper.dir, 1)) + jumper.Weaken(5) + helper.Weaken(5) + return TRUE + +/obj/anomaly/rvach/get_detection_icon() + return "rvach_detection" diff --git a/mods/anomaly/code/anomalies/single/tramplin.dm b/mods/anomaly/code/anomalies/single/tramplin.dm index 17b93835393c0..d2c3faf186a79 100644 --- a/mods/anomaly/code/anomalies/single/tramplin.dm +++ b/mods/anomaly/code/anomalies/single/tramplin.dm @@ -1,4 +1,4 @@ -/obj/anomaly/thamplin +/obj/anomaly/tramplin name = "Refractions of light" with_sound = TRUE sound_type = 'mods/anomaly/sounds/tramplin.ogg' @@ -15,45 +15,56 @@ ) //Рандомизация ranzomize_with_initialize = TRUE - can_born_artifacts = FALSE + can_born_artefacts = FALSE min_coldown_time = 3 SECONDS max_coldown_time = 8 SECONDS - can_be_preloaded = TRUE being_preload_chance = 10 chance_to_be_detected = 75 - can_walking = TRUE - chance_spawn_walking = 5 - walking_activity = 5 + detection_skill_req = SKILL_BASIC +/obj/anomaly/tramplin/Initialize() + . = ..() + range_of_throw = rand(2,5) -/obj/anomaly/thamplin/activate_anomaly() +/obj/anomaly/tramplin/activate_anomaly() for(var/obj/item/target in src.loc) get_effect_by_anomaly(target) for(var/mob/living/targetbam in src.loc) get_effect_by_anomaly(targetbam) .=..() -/obj/anomaly/thamplin/get_effect_by_anomaly(target) +/obj/anomaly/tramplin/get_effect_by_anomaly(target) if(ismech(target)) return + if(istype(target, /mob/living)) + SSanom.add_last_attack(target, "Трамплин") + var/list/result_effects = calculate_artefact_reaction(target, "Трамплин") + if(result_effects) + if(result_effects.Find("Не даёт кинуть")) + return + if(ishuman(target)) var/mob/living/carbon/human/victim = target if(!victim.incapacitated(INCAPACITATION_UNRESISTING) == TRUE) //Убедимся что наш чувак в сознании if(victim.skill_check(SKILL_HAULING, SKILL_EXPERIENCED)) if(prob(10 * victim.get_skill_value(SKILL_HAULING))) victim.Weaken(1) - to_chat(victim, SPAN_WARNING("Земля пропадает под ногами, но вы успеваете вцепиться в землю словно зубами.")) + to_chat(victim, SPAN_GOOD("Земля пропадает под ногами, но вы успеваете вцепиться в землю словно зубами.")) return var/turf/own_turf = get_turf(src) var/turf/target_turf = own_turf if(!random_throw_dir) - //В силу того что в билде нет нормальной функции по киданию по направлению, сперва расчитаем цель, куда будем метать обьект - for(var/i = 1, i < range_of_throw, i++) - target_turf = get_edge_target_turf(target, throw_dir) + target_turf = get_ranged_target_turf(target, throw_dir, range_of_throw) var/atom/movable/victim = target + if(isliving(victim)) + var/mob/victim_mob = victim + victim_mob.Weaken(1) if(random_throw_dir) victim.throw_at_random(own_turf, range_of_throw, speed_of_throw ) else victim.throw_at(target_turf, range_of_throw, speed_of_throw) + +/obj/anomaly/tramplin/get_detection_icon() + return "trampline_detection" diff --git a/mods/anomaly/code/anomalies/ventilyator.dm b/mods/anomaly/code/anomalies/single/ventilyator.dm similarity index 94% rename from mods/anomaly/code/anomalies/ventilyator.dm rename to mods/anomaly/code/anomalies/single/ventilyator.dm index 02e3f01d2c736..c638913399c0c 100644 --- a/mods/anomaly/code/anomalies/ventilyator.dm +++ b/mods/anomaly/code/anomalies/single/ventilyator.dm @@ -1,3 +1,4 @@ +/* Не доделано /proc/random_dir() return pick(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) @@ -20,12 +21,13 @@ ) //Рандомизация ranzomize_with_initialize = TRUE - can_born_artifacts = FALSE + can_born_artefacts = FALSE min_coldown_time = 15 SECONDS max_coldown_time = 30 SECONDS time_between_effects = 0.25 SECONDS being_preload_chance = 10 chance_to_be_detected = 75 + detection_skill_req = SKILL_EXPERIENCED /obj/anomaly/ventilyator/Initialize() . = ..() @@ -57,3 +59,4 @@ for(var/atom/atoms in list_of_effected_turfs) get_effect_by_anomaly(atoms) start_processing_long_effect() +*/ diff --git a/mods/anomaly/code/anomalies/vspishka.dm b/mods/anomaly/code/anomalies/single/vspishka.dm similarity index 79% rename from mods/anomaly/code/anomalies/vspishka.dm rename to mods/anomaly/code/anomalies/single/vspishka.dm index 3a60cfd47d373..f7faeb4eff1f9 100644 --- a/mods/anomaly/code/anomalies/vspishka.dm +++ b/mods/anomaly/code/anomalies/single/vspishka.dm @@ -10,19 +10,20 @@ range_of_light = 6 power_of_light = 10 effect_range = 5 - can_born_artifacts = FALSE + can_born_artefacts = FALSE var/datum/beam = null var/create_line = FALSE preload_sound_type = 'mods/anomaly/sounds/vspishka_preload.ogg' //Рандомизация ranzomize_with_initialize = TRUE - min_coldown_time = 15 SECONDS - max_coldown_time = 30 SECONDS + min_coldown_time = 30 SECONDS + max_coldown_time = 75 SECONDS min_preload_time = 6 max_preload_time = 12 can_be_preloaded = TRUE being_preload_chance = 80 - chance_to_be_detected = 50 + chance_to_be_detected = 75 + detection_skill_req = SKILL_MASTER /obj/anomaly/vspishka/activate_anomaly() last_activation_time = world.time @@ -42,6 +43,11 @@ create_line = FALSE //Ослепим моба if(istype(target, /mob/living)) + SSanom.add_last_attack(target, "Вспышка") + var/list/result_effects = calculate_artefact_reaction(target, "Вспышка") + if(result_effects) + if(result_effects.Find("Защищает от ослепления")) + return var/mob/living/victim = target victim.flash_eyes(FLASH_PROTECTION_MAJOR) victim.Stun(5) diff --git a/mods/anomaly/code/anomalies/single/zjarka.dm b/mods/anomaly/code/anomalies/single/zjarka.dm index cd065ac7ad454..54e7250aaf38a 100644 --- a/mods/anomaly/code/anomalies/single/zjarka.dm +++ b/mods/anomaly/code/anomalies/single/zjarka.dm @@ -3,6 +3,7 @@ with_sound = TRUE sound_type = 'mods/anomaly/sounds/zjarka.ogg' idle_effect_type = "zjarka_idle" + detection_icon_state = "hot_anomaly" layer = ABOVE_HUMAN_LAYER light_after_activation = TRUE effect_type = LONG_ANOMALY_EFFECT @@ -10,7 +11,7 @@ color_of_light = COLOR_WHITE effect_time = 5 SECONDS time_of_light = 5 SECONDS - can_born_artifacts = TRUE + can_born_artefacts = TRUE //Урон который наносит открытое пламя телу в var/burn_damage = 10 activation_effect_type = "zjarka_active" @@ -33,9 +34,7 @@ artefact_spawn_chance = 10 can_be_preloaded = FALSE being_preload_chance = 20 - can_walking = TRUE - chance_spawn_walking = 1 - walking_activity = 2 + detection_skill_req = SKILL_BASIC /obj/anomaly/zjarka/activate_anomaly() @@ -59,10 +58,12 @@ return //Поджечь человека if(istype(target, /mob/living)) + SSanom.add_last_attack(target, "Жарка") var/mob/living/victim = target if(inmech_sec(victim)) return if(victim.health == 0) + SSanom.add_last_gibbed(target, "Жарка") anything_in_remains(victim) return victim.fire_stacks = max(2, victim.fire_stacks) @@ -95,3 +96,12 @@ if(can_be_activated(O)) activate_anomaly() return + + +/obj/anomaly/zjarka/get_detection_icon() + if(effect_range == 1 || effect_range == 0) + return "zjarka_detection" + else if(effect_range == 2) + return "zjarka_first_detection" + else if(effect_range > 2) + return "zjarka_second_detection" diff --git a/mods/anomaly/code/anomaly_admin.dm b/mods/anomaly/code/anomaly_admin.dm index 3a88dce05f372..caaca04a4687e 100644 --- a/mods/anomaly/code/anomaly_admin.dm +++ b/mods/anomaly/code/anomaly_admin.dm @@ -23,8 +23,8 @@ /obj/anomaly/heater/three_and_three = "Грелка - аномалия греющая все существа находящиеся на турфе ядра и вспомогательных частей. Обнаруживается лишь детектором, никакие скафандры не защищают от её влияния.Взводятся лишь мобом.", /obj/anomaly/heater/two_and_two = "Грелка - аномалия греющая все существа находящиеся на турфе ядра и вспомогательных частей. Обнаруживается лишь детектором, никакие скафандры не защищают от её влияния.Взводятся лишь мобом.", /obj/anomaly/cooler/two_and_two = "Холодильник - аномалия охлаждающая все существа находящиеся на турфе ядра и вспомогательных частей. Обнаруживается лишь детектором, никакие скафандры не защищают от её влияния. Взводятся лишь мобом.", - /obj/anomaly/cooler/three_and_three = "Холодильник - аномалия охлаждающая все существа находящиеся на турфе ядра и вспомогательных частей. Обнаруживается лишь детектором, никакие скафандры не защищают от её влияния. Взводятся лишь мобом." - + /obj/anomaly/cooler/three_and_three = "Холодильник - аномалия охлаждающая все существа находящиеся на турфе ядра и вспомогательных частей. Обнаруживается лишь детектором, никакие скафандры не защищают от её влияния. Взводятся лишь мобом.", + /obj/anomaly/tramplin = "Трамплин - аномалия швыряющая вещи и мобов находящиеся на её турфе. Не может сдвинуть меха." ) var/help_text = {"\ ********* Build Mode: Areas ******** diff --git a/mods/anomaly/code/anomaly_controller.dm b/mods/anomaly/code/anomaly_controller.dm index 20afaf90548a5..f8549f7fc46a6 100644 --- a/mods/anomaly/code/anomaly_controller.dm +++ b/mods/anomaly/code/anomaly_controller.dm @@ -4,21 +4,67 @@ PROCESSING_SUBSYSTEM_DEF(anom) priority = SS_PRIORITY_DEFAULT init_order = SS_INIT_DEFAULT flags = SS_BACKGROUND + wait = 3 //Каждые три тика - var/list/all_anomalies = list() - var/anomalies_ammount_in_world = 0 - var/added_ammount = 0 + //[ВЫВОДИМАЯ СТАТИСТИКА] + ///Список всех ЯДЕР аномалий + var/list/all_anomalies_cores = list() + ///Список всех ВСПОМОГАТЕЛЬНЫХ ЧАСТЕЙ + var/list/all_anomalies_helpers = list() + ///Количество ядер + var/anomalies_cores_in_world_amount = 0 + ///Количество вспомогательных частей + var/anomalies_helpers_in_world_amount = 0 + ///Количество спавнов аномалий + var/spawn_ammount = 0 + ///Количество удалений. Помогает определить эффективность генератора аномалий var/removed_ammount = 0 + ///Количество процессингов + var/processing_ammount = 0 + + + + //ПОСЛЕДНИЕ ФРАЗЫ + var/last_attacked_message + var/gibbed_last_message + + + + //[ИНФА ПО АРТЕФАКТАМ] + ///Количество артефактов, успешно собранные игроками + var/collected_artefacts_by_player = 0 + var/earned_cargo_points = 0 + var/earned_rnd_points = 0 + var/list/artefacts_list_in_world = list() + var/artefacts_deleted_by_game = 0 + var/artefacts_spawned_by_game = 0 + var/interactions_with_artefacts_by_players_ammount = 0 + var/bad_interactions_with_artefacts_by_players_ammount = 0 + var/good_interactions_with_artefacts_by_players_ammount = 0 + + + + //[ИНФА ПО АНОМАЛИЯМ] + ///Количество ударов электры по гуманоидам и подобным + var/anomalies_activated_times = 0 + var/humanoids_effected_by_anomaly = 0 + var/humanoids_gibbed_by_anomaly = 0 + var/simplemobs_effected_by_anomaly = 0 + var/simplemobs_gibbed_by_anomaly = 0 + + var/list/important_logs = list() /datum/controller/subsystem/processing/anom/UpdateStat(time) if (PreventUpdateStat(time)) return ..() ..({"\ - anomalies in world: [anomalies_ammount_in_world] \ - added times: [added_ammount] \ - removed timest: [removed_ammount] \ + anomalies in world: [anomalies_cores_in_world_amount] \ + anomaly helpers in world: [anomalies_helpers_in_world_amount] \ + spawned times: [spawn_ammount] \ + removed times: [removed_ammount] \ + objects in processing: [processing_ammount] "}) /datum/controller/subsystem/processing/anom/Initialize(start_uptime) @@ -27,12 +73,109 @@ PROCESSING_SUBSYSTEM_DEF(anom) /datum/controller/subsystem/processing/anom/proc/anomalies_init() -/datum/controller/subsystem/processing/anom/proc/add_anomaly_in_list(obj/anomaly/input) - LAZYADD(all_anomalies, input) - added_ammount++ - anomalies_ammount_in_world++ +/datum/controller/subsystem/processing/anom/proc/add_anomaly_in_cores(obj/anomaly/input) + LAZYADD(all_anomalies_cores, input) + spawn_ammount++ + anomalies_cores_in_world_amount++ + +/datum/controller/subsystem/processing/anom/proc/remove_anomaly_from_cores(obj/anomaly/input) + LAZYREMOVE(all_anomalies_cores, input) + removed_ammount++ + anomalies_cores_in_world_amount-- + -/datum/controller/subsystem/processing/anom/proc/remove_anomaly_from_list(obj/anomaly/input) - LAZYREMOVE(all_anomalies, input) +/datum/controller/subsystem/processing/anom/proc/add_anomaly_in_helpers(obj/anomaly/input) + LAZYADD(all_anomalies_helpers, input) + spawn_ammount++ + anomalies_helpers_in_world_amount++ + +/datum/controller/subsystem/processing/anom/proc/remove_anomaly_from_helpers(obj/anomaly/input) + LAZYREMOVE(all_anomalies_helpers, input) removed_ammount++ - anomalies_ammount_in_world-- + anomalies_helpers_in_world_amount-- + + + +/datum/controller/subsystem/processing/anom/proc/give_gameover_text() + if(SSanom.spawn_ammount > 0) + var/anomaly_text + anomaly_text += "


ANOMALY MOD STATISTIC." + anomaly_text += "
Количество аномалий на момент окончания раунда: [anomalies_cores_in_world_amount]. Мод размещал аномалии [spawn_ammount] раз, а удалял [removed_ammount] раз." + //Арты + anomaly_text += "
Игра заспавнила [artefacts_spawned_by_game] артефактов, из них [artefacts_deleted_by_game] удалено. Собрано игроками артефактов: [collected_artefacts_by_player]. Всего артефактов на конец раунда: [LAZYLEN(artefacts_list_in_world)]" + anomaly_text += "
Заработано каргопоинтов за продажу артефактов: [earned_cargo_points], заработано РНД поинтов за изучение артефактов: [earned_rnd_points]" + anomaly_text += "
Всего попыток взаимодействия с артефактами [interactions_with_artefacts_by_players_ammount], из них [good_interactions_with_artefacts_by_players_ammount] принесли пользу, а [bad_interactions_with_artefacts_by_players_ammount] - вред." + //Сработало аномок + //Электра + anomaly_text += "
Аномалии были взведены [anomalies_activated_times] Раз. В целом, игроки подверглись влиянию аномалий [humanoids_effected_by_anomaly] раз, а [humanoids_gibbed_by_anomaly] игроков были гибнуты. [simplemobs_effected_by_anomaly] симплмобов подверглись влиянию аномалий и [simplemobs_gibbed_by_anomaly] было гибнуто." + //Раненные, умершие, гибнутые + if(last_attacked_message) + anomaly_text += "
[last_attacked_message]." + else + anomaly_text += "
Никто не пострадал от аномалий." + + if(gibbed_last_message) + anomaly_text += "
[gibbed_last_message]." + else + anomaly_text += "
Никого не порвало от аномалии." + return anomaly_text + +/datum/controller/subsystem/processing/anom/proc/add_last_attack(mob/living/user, attack_name) + if(!ishuman(user) && !isrobot(user)) + SSanom.simplemobs_effected_by_anomaly++ + return FALSE + SSanom.humanoids_effected_by_anomaly++ + if(last_attacked_message) + return FALSE //У нас уже всё записано + + var/result_text = "Первым от аномалии пострадал [user.ckey]," + //генерируем текст причины атаки + if(attack_name == "Электра") + result_text += "он получил мощный электроудар." + else if(attack_name == "Жарка") + result_text += "его сильно обожгло." + else if(attack_name == "Вспышка") + result_text += "его сильно ослепило и дезеориентировало." + else if(attack_name == "Рвач") + result_text += "ему оторвало конечность." + else if(attack_name == "Трамплин") + result_text += "его с силой швырнуло." + //а теперь генерируем последние сказанные им слова + if(user.mind.last_words) + result_text += "Перед этим он сказал: [user.mind.last_words]" + else + result_text += "Он пострадал молча." + + last_attacked_message = result_text + +/datum/controller/subsystem/processing/anom/proc/add_last_gibbed(mob/living/user, attack_name) + if(!ishuman(user) && !isrobot(user)) + SSanom.simplemobs_gibbed_by_anomaly++ + return FALSE + SSanom.humanoids_gibbed_by_anomaly++ + if(gibbed_last_message) + return FALSE //У нас уже всё записано + if(!user.ckey && !user.last_ckey) + return FALSE + + var/victim_ckey + if(!user.ckey) + victim_ckey = user.last_ckey + else + victim_ckey = user.ckey + + var/result_text = "Первым гибнуло [victim_ckey]." + //генерируем текст причины атаки + if(attack_name == "Электра") + result_text += "его испепелило до костей электроударом." + else if(attack_name == "Жарка") + result_text += "его сожгло до костей огнём." + else if(attack_name == "Рвач") + result_text += "его разорвало на куски гравианомалией." + + if(user.mind.last_words) + result_text += "его последние слова: [user.mind.last_words]" + else + result_text += "Он покинул этот мир молча." + + gibbed_last_message = result_text diff --git a/mods/anomaly/code/anomaly_defines.dm b/mods/anomaly/code/anomaly_defines.dm new file mode 100644 index 0000000000000..bd18e7a11388b --- /dev/null +++ b/mods/anomaly/code/anomaly_defines.dm @@ -0,0 +1,3 @@ +#define LONG_ANOMALY_EFFECT 2 +#define MOMENTUM_ANOMALY_EFFECT 1 +#define isanomaly(A) istype(A, /obj/anomaly) diff --git a/mods/anomaly/code/anomaly_light.dm b/mods/anomaly/code/anomaly_light.dm deleted file mode 100644 index f14abb69c8643..0000000000000 --- a/mods/anomaly/code/anomaly_light.dm +++ /dev/null @@ -1,18 +0,0 @@ -//Отвечает за вспышки и свет от аномалии -/obj/anomaly - ///Сделать вспышку после активации? - var/light_after_activation = FALSE - ///Время, которое будет держаться свет от активации - var/time_of_light = 1 SECOND - ///Цвет вспышки - var/color_of_light = COLOR_WHITE - var/range_of_light = 3 - var/power_of_light = 2 - -///Запускаем свет/вспышку -/obj/anomaly/proc/start_light() - set_light(3, 2, color_of_light) - addtimer(new Callback(src, PROC_REF(stop_light)), time_of_light) - -/obj/anomaly/proc/stop_light() - set_light(0) diff --git a/mods/anomaly/code/artifacts/anomaly_artifacts.dm b/mods/anomaly/code/artefacts/anomaly_artefacts.dm similarity index 52% rename from mods/anomaly/code/artifacts/anomaly_artifacts.dm rename to mods/anomaly/code/artefacts/anomaly_artefacts.dm index 8281a2f3e4ba3..e80db411c8967 100644 --- a/mods/anomaly/code/artifacts/anomaly_artifacts.dm +++ b/mods/anomaly/code/artefacts/anomaly_artefacts.dm @@ -2,20 +2,23 @@ name = "Что-то." desc = "Какой-то камень." icon = 'mods/anomaly/icons/artifacts.dmi' - ///Текущее количество энергии, которое хранит артефакт + ///Текущее количество энергии, которое хранит артефакт. var/stored_energy = 1000 - ///Максимальное количество ЭНЕРГИИ, которое хранит артефакт - var/max_stored_energy = 1000 + ///Максимальное количество ЭНЕРГИИ, которое хранит артефакт. + var/max_energy = 1000 var/cargo_price = 100 var/rnd_points = 2000 - var/can_be_throwed = FALSE var/obj/machinery/urm/stored_in_urm + var/mob/living/carbon/human/current_user /obj/item/artefact/use_tool(obj/item/item, mob/living/user, list/click_params) . = ..() if(istype(item, /obj/item/collector)) collector_interaction(item, user) +/obj/item/artefact/is_damage_immune() + return TRUE + /obj/item/artefact/proc/collector_interaction(obj/item/collector, mob/living/user) if(inmech_sec(user)) to_chat(user, SPAN_WARNING("Вы недотягиваетесь.")) @@ -47,61 +50,40 @@ else if(!connected_to_anomaly) input_collector.try_insert_artefact(user, src) +//Все артефакты нельзя уничтожить взрывом. /obj/item/artefact/ex_act(severity) return -/obj/item/artefact/throw_at(atom/target, range, speed, mob/thrower, spin, datum/callback/callback) - if(!can_be_throwed) - react_at_throw() - . = ..() - -///Вызывается для реагирования артефакта на тот факт, что им швыряются -/obj/item/artefact/proc/react_at_throw(atom/target, range, speed, mob/thrower, spin, datum/callback/callback) +///Добавляет указанное количество энергии к артефакту +/obj/item/artefact/proc/add_energy(amount) + stored_energy += amount + if(stored_energy >= max_energy) + react_at_max_energy() + stored_energy = clamp(stored_energy, 0, max_energy) + energy_changed() + +///Отнимает указанное количество энергии от артефакта +/obj/item/artefact/proc/sub_energy(amount) + stored_energy -= amount + if(stored_energy <= max_energy) + react_at_min_energy() + stored_energy = clamp(stored_energy, 0, max_energy) + +///Вызывается, когда энергия артефакта достигает своих минимальных значений +/obj/item/artefact/proc/react_at_min_energy() return -/obj/item/artefact/proc/react_to_touched(mob/living/user) +///Вызывается, когда энергия артефакта достигает своих максимальных значений +/obj/item/artefact/proc/react_at_max_energy() return -/obj/item/artefact/emp_act(severity) - . = ..() - react_to_emp() - -/obj/item/artefact/proc/react_to_emp() +///Энергия артефакта как-то изменилась +/obj/item/artefact/proc/energy_changed() return -/obj/item/artefact/pickup(mob/user) - . = ..() - if(!is_processing) - START_PROCESSING(SSanom, src) - -/obj/item/artefact/proc/react_to_remove_from_collector() - if(!is_processing) - START_PROCESSING(SSanom, src) - -/obj/item/artefact/proc/react_to_insert_in_collector() - if(is_processing) - STOP_PROCESSING(SSanom, src) - /obj/item/artefact/proc/delete_artefact() if(is_processing) - STOP_PROCESSING(SSanom, src) + stop_process_by_ssanom() + SSanom.artefacts_deleted_by_game++ + LAZYREMOVE(SSanom.artefacts_list_in_world , src) qdel(src) - - -//Жар -/obj/item/artefact/zjar - name = "Something" - desc = "При поднятии вы чувствуете, словно по вашему телу распростаняется приятное тепло." - icon_state = "fire_ball" - -//Грави -/obj/item/artefact/gravi - name = "Something" - desc = "При поднятии вы чувствуете, словно сам воздух вокруг вас становится плотнее." - icon_state = "gravi" - -//Светлячок -/obj/item/artefact/svetlyak - name = "Something" - desc = "Невероятно яркий, вы с трудом смотрите на него даже с зажмуренными глазами." - icon_state = "svetlyak" diff --git a/mods/anomaly/code/artefacts/artefact_external_interact.dm b/mods/anomaly/code/artefacts/artefact_external_interact.dm new file mode 100644 index 0000000000000..9b7dbc9920975 --- /dev/null +++ b/mods/anomaly/code/artefacts/artefact_external_interact.dm @@ -0,0 +1,115 @@ +/* +Просчитывание реакций артефактов + +Пример применения в коде: + + var/list/result_effects = calculate_artefact_reaction(src, "ЭМИ") <- здесь, мы получаем весь список реакций артефактов в инвентаре персонажа на событие (ЭМИ/Взрыв/Падение и прочие, вы всегда можете добавить своё!) + if(result_effects) <- Всегда проверяйте, что вам не выдало null + if(result_effects.Find("Защищает от ЭМИ")) <- Теперь, ищем нужную нам реакцию на событие. + return <- + + + +*/ +///В случае применения выдаёт список реакций артефактов внутри моба +/proc/calculate_artefact_reaction(mob/living/user, anomaly_type) +//Используем общий для всех участок кода по реакции артефакта на событие + var/list/detected_artefacts_in_victim = generate_artefacts_in_mob_list(user) + if(!LAZYLEN(detected_artefacts_in_victim)) + return FALSE + var/list/result_effects = list() //Весь список эффектов возникший при ударе + //Электровоздействие(Электра) + if(anomaly_type == "Электра") + for(var/obj/item/artefact/choosed_artefact in detected_artefacts_in_victim) + LAZYADD(result_effects, choosed_artefact.react_at_electra(user)) + return result_effects + //Воздействие трамплина(Кидание) + else if(anomaly_type == "Трамплин") + for(var/obj/item/artefact/choosed_artefact in detected_artefacts_in_victim) + LAZYADD(result_effects, choosed_artefact.react_at_tramplin(user)) + return result_effects + //Воздействие вспышки(Ослепление) + else if(anomaly_type == "Вспышка") + for(var/obj/item/artefact/choosed_artefact in detected_artefacts_in_victim) + LAZYADD(result_effects, choosed_artefact.react_at_vspishka(user)) + return result_effects + else if(anomaly_type == "Гиб Рвача") + for(var/obj/item/artefact/choosed_artefact in detected_artefacts_in_victim) + LAZYADD(result_effects, choosed_artefact.react_at_rvach_gib(user)) + return result_effects + else if(anomaly_type == "ЭМИ") + for(var/obj/item/artefact/choosed_artefact in detected_artefacts_in_victim) + LAZYADD(result_effects, choosed_artefact.react_at_emp_on_user(user)) + return result_effects + else if(anomaly_type == "Падение с высоты") + for(var/obj/item/artefact/choosed_artefact in detected_artefacts_in_victim) + LAZYADD(result_effects, choosed_artefact.react_at_failing(user)) + return result_effects + +/proc/generate_artefacts_in_mob_list(mob/living/user) + if(!istype(user, /mob/living)) + return + var/list/output_artefacts = list() + for(var/obj/item/artefact/picked_artefact in user.get_contents()) + if(!picked_artefact.artefact_in_collector()) + LAZYADD(output_artefacts, picked_artefact) + return output_artefacts + +/obj/item/artefact/proc/artefact_in_collector() + if(istype(loc, /obj/item/collector)) + return TRUE + else + return FALSE + + +/obj/item/artefact/proc/react_at_electra(mob/living/user) + return + +/obj/item/artefact/proc/react_at_tramplin(mob/living/user) + return + +/obj/item/artefact/proc/react_at_vspishka(mob/living/user) + return + +/obj/item/artefact/proc/react_at_rvach_gib(mob/living/user) + return + +/obj/item/artefact/proc/react_at_emp_on_user(mob/living/user) + return + +/obj/item/artefact/proc/react_at_failing(mob/living/user) + return + +/mob/living/emp_act(severity) + var/list/result_effects = calculate_artefact_reaction(src, "ЭМИ") + if(result_effects) + if(result_effects.Find("Защищает от ЭМИ")) + return + . = ..() + +/obj/item/artefact/throw_at(atom/target, range, speed, mob/thrower, spin, datum/callback/callback) + react_at_throw() + . = ..() + update_current_user() + +///Вызывается для реагирования артефакта на тот факт, что им швыряются +/obj/item/artefact/proc/react_at_throw(atom/target, range, speed, mob/thrower, spin, datum/callback/callback) + return + +/obj/item/artefact/proc/react_to_touched(mob/living/user) + return + +/obj/item/artefact/emp_act(severity) + . = ..() + react_at_emp() + +/obj/item/artefact/proc/react_at_emp() + return + +/obj/item/artefact/proc/react_to_remove_from_collector() + if(!is_processing) + start_process_by_ssanom() + +/obj/item/artefact/proc/react_to_insert_in_collector() + if(is_processing) + stop_process_by_ssanom() diff --git a/mods/anomaly/code/artifacts/artefact_gravi.dm b/mods/anomaly/code/artefacts/artefact_gravi.dm similarity index 52% rename from mods/anomaly/code/artifacts/artefact_gravi.dm rename to mods/anomaly/code/artefacts/artefact_gravi.dm index 3874634bd20fa..7150cf14c111e 100644 --- a/mods/anomaly/code/artifacts/artefact_gravi.dm +++ b/mods/anomaly/code/artefacts/artefact_gravi.dm @@ -2,6 +2,8 @@ name = "Something" desc = "Вы чувствуете лёгкость." icon_state = "gravi" + need_to_process = TRUE + //В артефакте нет энергии/она неограничена rect_to_interactions = list( "Lick", "Shake", @@ -10,12 +12,16 @@ "Compress", "Rub" ) - cargo_price = 75 + stored_energy = 0 + max_energy = 0 + cargo_price = 800 + rnd_points = 5000 + need_to_process = TRUE -/obj/item/artefact/gravi/lick_interaction(mob/living/user) +/obj/item/artefact/gravi/lick_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_NOTICE("На вкус как камень.")) -/obj/item/artefact/gravi/shake_interaction(mob/living/user) +/obj/item/artefact/gravi/shake_interaction(mob/living/carbon/human/user) if(isrobot(user)) to_chat(user,SPAN_NOTICE("Вы не регистрируете чего-либо необычного.")) else @@ -24,19 +30,19 @@ -/obj/item/artefact/gravi/bite_interaction(mob/living/user) +/obj/item/artefact/gravi/bite_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_NOTICE("Ощущается зубами как камень. Ничего необычного.")) -/obj/item/artefact/gravi/knock_interaction(mob/living/user) +/obj/item/artefact/gravi/knock_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_NOTICE("При попытке постучать или ударить, рука словно отпружинивает.")) -/obj/item/artefact/gravi/compress_interaction(mob/living/user) +/obj/item/artefact/gravi/compress_interaction(mob/living/carbon/human/user) if(isrobot(user)) to_chat(user,SPAN_NOTICE("Обьект не поддаётся сдавливанию.")) else to_chat(user,SPAN_NOTICE("Обьект словно камень, вообще не поддаётся сдавливанию.")) -/obj/item/artefact/gravi/rub_interaction(mob/living/user) +/obj/item/artefact/gravi/rub_interaction(mob/living/carbon/human/user) if(isrobot(user)) to_chat(user,SPAN_NOTICE("Обьект не реагирует.")) else @@ -49,7 +55,9 @@ return "Обьект не реагирует" /obj/item/artefact/gravi/urm_electro(mob/living/user) - return "Обьект не реагирует" + stored_in_urm.last_interaction_id = "gravi_jumped_electro" + stored_in_urm.last_interaction_reward = 1000 + return "Обьект отскакивает от места контакта в противоположную сторону." /obj/item/artefact/gravi/urm_plasma(mob/living/user) return "Обьект не реагирует" @@ -65,9 +73,6 @@ - - - /obj/item/artefact/gravi/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(istype(mover, /obj/item/projectile/bullet)) new /obj/item/material/shard/shrapnel/steel(get_turf(src)) @@ -76,7 +81,31 @@ /mob/living/carbon/human/handle_fall_effect(turf/landing) - var/obj/item/artefact/gravi/artefact = locate(/obj/item/artefact/gravi) in src - if (istype(artefact)) - return + var/list/result_effects = calculate_artefact_reaction(src, "Падение с высоты") + if(result_effects) + if(result_effects.Find("Защищает от падения")) + return .=..() + +/obj/item/artefact/gravi/process_artefact_effect_to_user() + if(current_user.stamina < 85) + current_user.adjust_stamina(5) + +//Грави заставляет отлететь в направление, противположное текущее. Так смешнее. +/obj/item/artefact/gravi/react_at_electra(mob/living/user) + . = ..() + var/turf/target_turf = get_turf(user) + var/throw_dir = turn(user.dir, 180) //Противоположное направление моба + for(var/i = 1, i < 2, i++) + target_turf = get_edge_target_turf(user, throw_dir) + user.throw_at(target_turf, 2, 1) + +/obj/item/artefact/gravi/react_at_tramplin(mob/living/user) + . = ..() + return "Не даёт кинуть" + +/obj/item/artefact/gravi/react_at_rvach_gib(mob/living/user) + return "Защищает от гиба рвачом" + +/obj/item/artefact/gravi/react_at_failing(mob/living/user) + return "Защищает от падения" diff --git a/mods/anomaly/code/artefacts/artefact_processing.dm b/mods/anomaly/code/artefacts/artefact_processing.dm new file mode 100644 index 0000000000000..e7afb603aa825 --- /dev/null +++ b/mods/anomaly/code/artefacts/artefact_processing.dm @@ -0,0 +1,88 @@ +/obj/item/artefact + ///КД на проверку валидности носителя в случае если носителя нет + var/user_long_check_cooldown = 3 SECONDS + var/last_long_user_check = 0 + ///КД на проверку валидности носителя в случае если носитель есть + var/user_check_cooldown = 2 SECONDS + var/last_user_check = 0 + ///Артефакт нуждается в постоянной обработке? + var/need_to_process = FALSE + ///КД на влияние артефакта на носителя + var/process_effect_cooldown = 0.5 SECONDS + var/last_process_effect = 0 + + var/additional_process_cooldown = 20 SECONDS + var/last_additional_process = 0 + +/obj/item/artefact/Initialize() + . = ..() + user_long_check_cooldown = rand(3 SECONDS, 6 SECONDS) + user_check_cooldown = rand(2 SECONDS, 4 SECONDS) + additional_process_cooldown = rand(20 SECONDS, 50 SECONDS) + start_process_by_ssanom() + +//Артефакт процессится абсолютно всегда в силу того что невозможно без изменения кор кода предотвратить ситуации, когда артефакт +//Не влият на носителя, например при скидывании на пол и поднятии рюкзака обратно (Как сообщить артефакту о этм событии? Срать в код.) +/obj/item/artefact/Process() + if(world.time - last_long_user_check >= user_long_check_cooldown) + last_long_user_check = world.time + additional_process() + if(connected_to_anomaly) + return + //Если носителя нет, то через большой промежуток времени проверим - вдруг нас кто-то всё таки взял? + if(!current_user) + if(world.time - last_long_user_check >= user_long_check_cooldown) + last_long_user_check = world.time + for(var/mob/living/user in get_turf(src)) + if(src in user.get_contents()) + update_current_user(user) + //Если носитель есть, то через более мелкий промежуток времени проверим, что носитель нас ещё носит + else if(current_user) + if(world.time - last_user_check >= user_check_cooldown) + last_user_check = world.time + update_current_user() + if(world.time - last_process_effect <= process_effect_cooldown) + return + process_artefact_effect_to_user() + +/* +Дополнительный процессинг для доп фич. Обычно не используется. +Позволяет легко добавлять новые свойства процессингу не изменяя ядро +*/ +/obj/item/artefact/proc/additional_process() + return + +/obj/item/artefact/proc/process_artefact_effect_to_user() + return + + +//Добавляем и убираем ВЛАДЕЛЬЦЕВ(кто имеем в рюкзаке арт) +/obj/item/artefact/pickup(mob/living/user) + .=..() + update_current_user(user) + +/obj/item/artefact/dropped(mob/user) + .=..() + update_current_user(user) + + +/obj/item/artefact/proc/update_current_user(mob/living/user) + // В случае перемещения предмета между contents или подбора, обновляет своего ПОЛЬЗОВАТЕЛЯ + if(current_user) //Юзер уже есть, + if(get_turf(current_user) != get_turf(src)) //проверяем, + current_user = null + else if(!current_user) + current_user = user + + +/obj/item/artefact/proc/start_process_by_ssanom() + if(!is_processing) + START_PROCESSING(SSanom, src) + SSanom.processing_ammount++ + + +/obj/item/artefact/proc/stop_process_by_ssanom() + if(is_processing) + STOP_PROCESSING(SSanom, src) + if(SSanom.processing_ammount > 0) + SSanom.processing_ammount-- diff --git a/mods/anomaly/code/artifacts/artefact_pruzhina.dm b/mods/anomaly/code/artefacts/artefact_pruzhina.dm similarity index 84% rename from mods/anomaly/code/artifacts/artefact_pruzhina.dm rename to mods/anomaly/code/artefacts/artefact_pruzhina.dm index e34598c029b57..dd64248e2d6db 100644 --- a/mods/anomaly/code/artifacts/artefact_pruzhina.dm +++ b/mods/anomaly/code/artefacts/artefact_pruzhina.dm @@ -11,42 +11,44 @@ "Compress", "Rub" ) - //артефакт обладает зарядами - var/charges = 0 - var/max_charges = 3 stored_energy = 10000 - max_stored_energy = 10000 + max_energy = 10000 + cargo_price = 750 + rnd_points = 3000 var/datum/beam = null //Артефакт скопирован с помощью URM var/copy = FALSE -/obj/item/artefact/pruzhina/lick_interaction(mob/living/user) +/obj/item/artefact/pruzhina/lick_interaction(mob/living/carbon/human/user) + SSanom.bad_interactions_with_artefacts_by_players_ammount++ to_chat(user,SPAN_NOTICE("Как только вы подносите язык чуть ближе, вы чувствуете острую боль в нём, словно от проводов.")) user.electoanomaly_act(25, src, BP_HEAD) + sub_energy(50) -/obj/item/artefact/pruzhina/shake_interaction(mob/living/user) +/obj/item/artefact/pruzhina/shake_interaction(mob/living/carbon/human/user) if(isrobot(user)) to_chat(user,SPAN_NOTICE("Ваши внешние сенсоры регистристрируют усиление электромагнитного поля.")) else to_chat(user,SPAN_GOOD("Потреся обьект, вы чувствуете, как тот начинает щёлкать и словно оживать. Чувствуете нечто, подобное мурчанию")) - add_charge(user) -/obj/item/artefact/pruzhina/bite_interaction(mob/living/user) +/obj/item/artefact/pruzhina/bite_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_NOTICE("Как только вы ухватываете обьект зубами, вы чувствуете сильнейшую боль.Глупо.")) + sub_energy(100) user.electoanomaly_act(75, src, BP_HEAD) -/obj/item/artefact/pruzhina/knock_interaction(mob/living/user) +/obj/item/artefact/pruzhina/knock_interaction(mob/living/carbon/human/user) angry_activity() -/obj/item/artefact/pruzhina/compress_interaction(mob/living/user) +/obj/item/artefact/pruzhina/compress_interaction(mob/living/carbon/human/user) if(isrobot(user)) to_chat(user,SPAN_NOTICE("При повышении напряжения в сервоприводах вашей конечности регистрируется обратная сила, возвращающая обьект в исходное состояние.")) else to_chat(user,SPAN_NOTICE("Вы чувствуете как артефакт сопротивляется вашей попытке его сжать, словно какое-то поле отталкивает его обратно.")) -/obj/item/artefact/pruzhina/rub_interaction(mob/living/user) - if(charges > 0) - sub_charge(user) +/obj/item/artefact/pruzhina/rub_interaction(mob/living/carbon/human/user) + if(stored_energy > 500) + sub_energy(500) + SSanom.good_interactions_with_artefacts_by_players_ammount++ if(isrobot(user)) to_chat(user,SPAN_NOTICE("Фиксируется электростатическое поле.")) else @@ -62,12 +64,14 @@ return "Обьект не реагирует" /obj/item/artefact/pruzhina/urm_electro(mob/living/user) + add_energy(150) stored_in_urm.last_interaction_id = "pruzhina_eated_electro" stored_in_urm.last_interaction_reward = 1000 return "Зафиксировано как обьект поглотил в себя весь переданный электрический потенциал." /obj/item/artefact/pruzhina/urm_plasma(mob/living/user) if(!copy) + SSanom.good_interactions_with_artefacts_by_players_ammount++ copy = TRUE var/obj/item/artefact/pruzhina/borned_pruzhina = new /obj/item/artefact/pruzhina(get_turf(src)) borned_pruzhina.copy = TRUE @@ -75,6 +79,7 @@ stored_in_urm.last_interaction_reward = 2000 return "При определённой концентрации потока плазмы Обьект начинает бурно реагировать. Он расширяется в обьёмах, пульсирует, и из одного выходит второй, точно такой же." else + SSanom.bad_interactions_with_artefacts_by_players_ammount++ var/obj/anomaly/electra/three_and_three/spawned = new /obj/anomaly/electra/three_and_three/tesla(get_turf(src)) spawned.kill_later(120 SECONDS) delete_artefact() @@ -98,26 +103,9 @@ /obj/item/artefact/pruzhina/react_at_throw(atom/target, range, speed, mob/thrower, spin, datum/callback/callback) create_anomaly_pruzhina(30 SECONDS) -/obj/item/artefact/react_to_emp() - angry_activity() - -/obj/item/artefact/pruzhina/proc/add_charge(mob/living/user) - if(charges >= max_charges) - ubercharge_pruzhina(user) - return FALSE - else - charges++ - return TRUE - -/obj/item/artefact/pruzhina/proc/sub_charge(user) - if(charges <= max_charges) - charges = 0 - return FALSE - else - charges-- - return TRUE /obj/item/artefact/pruzhina/proc/ubercharge_pruzhina(mob/living/user) + SSanom.bad_interactions_with_artefacts_by_players_ammount++ to_chat(user,SPAN_WARNING("Обьект вырывается из ваших рук уже с грозным грохотом и гудением.")) user.drop_item(src) anchored = TRUE @@ -147,6 +135,7 @@ /obj/item/artefact/pruzhina/angry_activity(mob/living/user) to_chat(user,SPAN_WARNING("Вас озарила вспышка.")) + sub_energy(200) var/list/victims = list() var/list/objs_not_used = list() var/turf/T = get_turf(src) @@ -179,3 +168,18 @@ /obj/item/cell/pruzhina/emp_act(severity) SHOULD_CALL_PARENT(FALSE) return + +//Пружина раздаст всем вокруг электроудары, если её носитель получит удар +/obj/item/artefact/pruzhina/react_at_electra(mob/living/user) + if(stored_energy > 8500) + angry_activity() + add_energy(1500) + +/obj/item/artefact/pruzhina/react_at_emp_on_user(mob/living/user) + if(stored_energy > 8500) + angry_activity() + add_energy(1500) + return "Защищает от ЭМИ" + +/obj/item/artefact/pruzhina/react_at_emp() + angry_activity() diff --git a/mods/anomaly/code/artifacts/anomaly_artifact_spawn.dm b/mods/anomaly/code/artefacts/artefact_spawn.dm similarity index 82% rename from mods/anomaly/code/artifacts/anomaly_artifact_spawn.dm rename to mods/anomaly/code/artefacts/artefact_spawn.dm index 230665c73eb07..52f5de4f5146b 100644 --- a/mods/anomaly/code/artifacts/anomaly_artifact_spawn.dm +++ b/mods/anomaly/code/artefacts/artefact_spawn.dm @@ -1,6 +1,6 @@ /obj/anomaly ///Аномалия может "Рожать" артефакты? - var/can_born_artifacts = FALSE + var/can_born_artefacts = FALSE //ANOTHER ///Какие артефакты порождает аномалия. Справа пишем шанс выбора этого артефакта. var/list/artefacts = list() @@ -9,20 +9,20 @@ var/artefact_spawn_chance = 25 -/obj/anomaly/proc/try_born_artifact() +/obj/anomaly/proc/try_born_artefact() //Может ли аномалия спавнить артефакты - if(can_born_artifacts && !check_artifacts_in_anomaly()) - born_artifact() + if(can_born_artefacts && !check_artifacts_in_anomaly()) + born_artefact() return TRUE else return FALSE ///Функция спавнит артефакт на территории аномалии -/obj/anomaly/proc/born_artifact() +/obj/anomaly/proc/born_artefact() var/obj/artefact = pickweight(artefacts) if(artefact) - born_artifact_in_random_title(artefact) + born_artefact_in_random_title(artefact) ///Функция проверяет, есть ли на территории аномалии артефакты /obj/anomaly/proc/check_artifacts_in_anomaly() @@ -52,7 +52,7 @@ ///Создаёт артефакт в случайном тайтле аномалии, включая вспомогательные -/obj/anomaly/proc/born_artifact_in_random_title() +/obj/anomaly/proc/born_artefact_in_random_title() var/list/possible_places = list() LAZYADD(possible_places, src.loc) if(multitile) @@ -62,4 +62,7 @@ var/result = pick(possible_places) if(LAZYLEN(artefacts)) var/artifact = pick(artefacts) - new artifact(result) + var/obj/item/artefact/spawned_artefact = new artifact(result) + spawned_artefact.connected_to_anomaly = TRUE + LAZYADD(SSanom.artefacts_list_in_world ,spawned_artefact) + SSanom.artefacts_spawned_by_game++ diff --git a/mods/anomaly/code/artifacts/artefact_svetlyak.dm b/mods/anomaly/code/artefacts/artefact_svetlyak.dm similarity index 73% rename from mods/anomaly/code/artifacts/artefact_svetlyak.dm rename to mods/anomaly/code/artefacts/artefact_svetlyak.dm index 8690e4ef1c727..f046710ad4952 100644 --- a/mods/anomaly/code/artifacts/artefact_svetlyak.dm +++ b/mods/anomaly/code/artefacts/artefact_svetlyak.dm @@ -11,18 +11,20 @@ "Rub" ) var/activated_fleshka = FALSE - var/current_heat = 0 - cargo_price = 250 + stored_energy = 1000 + max_energy = 1000 + cargo_price = 800 + rnd_points = 5000 /obj/item/artefact/svetlyak/Initialize() . = ..() set_light(5, 5, light_color) -/obj/item/artefact/svetlyak/lick_interaction(mob/living/user) +/obj/item/artefact/svetlyak/lick_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_NOTICE("Ваш язык ничего не ощущает, словно проходит насквозь..")) -/obj/item/artefact/svetlyak/shake_interaction(mob/living/user) +/obj/item/artefact/svetlyak/shake_interaction(mob/living/carbon/human/user) if(activated_fleshka) return if(isrobot(user)) @@ -30,32 +32,27 @@ else to_chat(user,SPAN_GOOD("Потреся обьект, вы видите, как тот начинает то усиливать свечение, то немного ослаблять его.")) activated_fleshka = TRUE - addtimer(new Callback(src, PROC_REF(svetlyak_fleshka)), 5 SECONDS) + addtimer(new Callback(src, PROC_REF(svetlyak_fleshka)), 2 SECONDS) -/obj/item/artefact/svetlyak/bite_interaction(mob/living/user) +/obj/item/artefact/svetlyak/bite_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_NOTICE("Вы не можете ухватиться за обьект зубами, они словно проходят насквозь.")) -/obj/item/artefact/svetlyak/knock_interaction(mob/living/user) +/obj/item/artefact/svetlyak/knock_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_NOTICE("Рука проходит сквозь обьект...")) -/obj/item/artefact/svetlyak/compress_interaction(mob/living/user) +/obj/item/artefact/svetlyak/compress_interaction(mob/living/carbon/human/user) if(isrobot(user)) to_chat(user,SPAN_NOTICE("При попытке сжать конечность обратный отклик не регистрируется, конечность проходит сквозь обьект, но обьект всё ещё остаётся на вашей руке.")) else to_chat(user,SPAN_NOTICE("Вы чувствуете словно ваша рука при попытке сжать обьект проходит сквозь него, но он всё ещё остаётся на руке.")) -/obj/item/artefact/svetlyak/rub_interaction(mob/living/user) +/obj/item/artefact/svetlyak/rub_interaction(mob/living/carbon/human/user) if(isrobot(user)) - to_chat(user,SPAN_NOTICE("Зрительные сенсоры регистрируют ослабление свечения [src].")) + to_chat(user,SPAN_NOTICE("Интенсивность свечения не меняется.")) else - to_chat(user,SPAN_NOTICE("[src] начинает светиться не так ярко, словно успокаиваясь.")) - if(current_heat > 0) - current_heat-- - else if(current_heat == 0) - visible_message(SPAN_BAD("...[src] растворяется на ваших глазах, испустив последнюю, приятную для глаз вспышку."), null, 5) - qdel(src) + to_chat(user,SPAN_NOTICE("Он всё так же светится.")) /obj/item/artefact/svetlyak/urm_radiation(mob/living/user) stored_in_urm.last_interaction_id = "svetlyak_radiation" @@ -64,7 +61,7 @@ /obj/item/artefact/svetlyak/urm_laser(mob/living/user) stored_in_urm.last_interaction_id = "svetlyak_laser" - stored_in_urm.last_interaction_reward = 1000 + stored_in_urm.last_interaction_reward = 2000 return "Зафиксировано как луч продит сквозь обьект с усиленной мощностью." /obj/item/artefact/svetlyak/urm_electro(mob/living/user) @@ -96,12 +93,17 @@ target.flash_eyes(FLASH_PROTECTION_MAJOR) target.Stun(5) target.mod_confused(10) - add_heat() + sub_energy(50) activated_fleshka = FALSE -/obj/item/artefact/svetlyak/proc/add_heat() - current_heat++ - if(current_heat >= 2) - var/obj/anomaly/vspishka/spawned = new /obj/anomaly/vspishka(get_turf(src)) - spawned.kill_later(300 SECONDS) - qdel(src) + +//Он должен передавать удар другому, по цепочке +/obj/item/artefact/svetlyak/react_at_electra(mob/living/user) + if(stored_energy > 250) + sub_energy(250) + return "Уворачивается от молнии, молния идёт дальше" + else + return "Ничего" + +/obj/item/artefact/svetlyak/react_at_vspishka(mob/living/user) + return "Защищает от ослепления" diff --git a/mods/anomaly/code/artifacts/artefact_zjar.dm b/mods/anomaly/code/artefacts/artefact_zjar.dm similarity index 51% rename from mods/anomaly/code/artifacts/artefact_zjar.dm rename to mods/anomaly/code/artefacts/artefact_zjar.dm index 0f1393d15d1ee..4ec786f2f5af3 100644 --- a/mods/anomaly/code/artifacts/artefact_zjar.dm +++ b/mods/anomaly/code/artefacts/artefact_zjar.dm @@ -1,6 +1,8 @@ /obj/item/artefact/zjar name = "Something" + icon_state = "fire_ball" desc = "Тепло растекается по вашим рукам, от одного лишь вида вам становится теплее." + need_to_process = TRUE rect_to_interactions = list( "Lick", "Shake", @@ -9,58 +11,72 @@ "Compress", "Rub" ) - //у артефакта 5 "кусков" - var/current_integrity = 5 - //Уже ремонтировался с помощью URM? + stored_energy = 1000 + max_energy = 1500 + cargo_price = 600 + rnd_points = 5000 var/repaired = FALSE - cargo_price = 350 - var/datum/beam = null -/obj/item/artefact/zjar/lick_interaction(mob/living/user) +/obj/item/artefact/zjar/lick_interaction(mob/living/carbon/human/user) if(istype(user, /mob/living/carbon/human )) to_chat(user,SPAN_GOOD("...он...вкусный...по вашему телу растекается тепло.")) user.bodytemperature += 50 -/obj/item/artefact/zjar/shake_interaction(mob/living/user) +/obj/item/artefact/zjar/shake_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_NOTICE("...По ощущениям внутри словно что-то есть, но в тоже время он монолитный...шар...или овал...")) -/obj/item/artefact/zjar/bite_interaction(mob/living/user) +/obj/item/artefact/zjar/bite_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_GOOD("...становится жарко, но голове становится куда легче, думается свободнее и проще.")) - var/mob/living/carbon/victim = user - victim.bodytemperature += 100 - victim.add_chemical_effect(CE_BRAIN_REGEN, 50) - - -/obj/item/artefact/zjar/knock_interaction(mob/living/user) + user.bodytemperature += 100 + sub_energy(100) + //Выдаёт реген мозга, обезбол, стимулятор + user.add_chemical_effect(CE_BRAIN_REGEN, 100) + user.add_chemical_effect(CE_PAINKILLER, 300) + user.add_chemical_effect(CE_STIMULANT, 50) + //Чинит все переломы + var/list/parts = list(BP_HEAD, BP_CHEST, BP_L_LEG, BP_L_FOOT, BP_R_LEG, BP_R_FOOT, BP_L_ARM, BP_L_HAND, BP_R_ARM,BP_R_HAND) + for(var/part in parts) + var/obj/item/organ/external/affecting = user.get_organ(part) + if(affecting.status &= ORGAN_BROKEN) + if(affecting.mend_fracture()) + sub_energy(25) + to_chat(user,SPAN_NOTICE("...острая боль в [affecting] проходит...")) + +/obj/item/artefact/zjar/knock_interaction(mob/living/carbon/human/user) if(istype(user, /mob/living/carbon/human )) + sub_energy(50) + SSanom.bad_interactions_with_artefacts_by_players_ammount++ to_chat(user,SPAN_BAD("Похоже, ему это не понравилось, вас неприятно ошпарило.")) user.bodytemperature += 150 user.apply_damage(15, DAMAGE_BURN, user.hand ? BP_L_HAND : BP_R_HAND) -/obj/item/artefact/zjar/compress_interaction(mob/living/user) +/obj/item/artefact/zjar/compress_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_NOTICE("..Как желе, но не желе, очень странные ощущения!")) -/obj/item/artefact/zjar/rub_interaction(mob/living/user) +/obj/item/artefact/zjar/rub_interaction(mob/living/carbon/human/user) to_chat(user,SPAN_GOOD("Тепло, и приятно. Не хочется убирать руки от него.")) /obj/item/artefact/zjar/urm_radiation(mob/living/user) return "Обьект не реагирует" /obj/item/artefact/zjar/urm_laser(mob/living/user) - if(current_integrity > 1) - current_integrity-- + if(stored_energy != 0) + sub_energy(200) + SSanom.bad_interactions_with_artefacts_by_players_ammount++ stored_in_urm.last_interaction_id = "zjar_damaged_by_laser" stored_in_urm.last_interaction_reward = 1500 return "Луч лазера прожигает обьект, явно его повреждая" else delete_artefact() + SSanom.bad_interactions_with_artefacts_by_players_ammount++ stored_in_urm.artefact_inside = null stored_in_urm.last_interaction_id = "zjar_destroyed_by_laser" stored_in_urm.last_interaction_reward = 2500 return "Обьект прожигается на сквозь, после сдувается словно воздушный шар и пропадает." /obj/item/artefact/zjar/urm_electro(mob/living/user) + sub_energy(50) stored_in_urm.last_interaction_id = "zjar_electra" stored_in_urm.last_interaction_reward = 500 return "Электрический удар был полностью поглощён обьектом." @@ -69,14 +85,15 @@ return "Обьект не реагирует" /obj/item/artefact/zjar/urm_phoron(mob/living/user) - if(current_integrity < 5 && !repaired) - current_integrity = 5 + if(stored_energy != max_energy && !repaired) + add_energy(1000) repaired = TRUE stored_in_urm.last_interaction_id = "zjar_repaired" stored_in_urm.last_interaction_reward = 2500 return "Вы наблюдаете, как недостающие часть обьекта, словно отрастают обратно" else if(repaired) delete_artefact() + SSanom.bad_interactions_with_artefacts_by_players_ammount++ stored_in_urm.artefact_inside = null stored_in_urm.last_interaction_id = "zjar_destroyed" stored_in_urm.last_interaction_reward = 3500 @@ -85,12 +102,38 @@ +/obj/item/artefact/zjar/process_artefact_effect_to_user() + if(current_user.bodytemperature < 350) + current_user.bodytemperature = 350 + for(var/thing in current_user.internal_organs) + var/obj/item/organ/internal/I = thing + if(I.damage > 0) + sub_energy(20) + I.heal_damage(rand(1,5)) + -/obj/item/artefact/zjar/Process() //чуть подогреем - for(var/mob/living/carbon/human/victim in get_turf(src)) - victim.heal_organ_damage(0, 6) - if(victim.bodytemperature < 360) - victim.bodytemperature = 360 - for(var/thing in victim.internal_organs) - var/obj/item/organ/internal/I = thing - I.heal_damage(rand(0,1)) +/obj/item/artefact/zjar/react_at_electra(mob/living/user) + if(stored_energy != 0) + sub_energy(100) + visible_message(SPAN_GOOD("[src] вспыхивает красной вспышкой"),,7) + else + delete_artefact() + visible_message(SPAN_BAD("[src] вспыхивает ярчайшей красной вспышкой и пропадает."),,7) + to_chat(current_user, SPAN_GOOD("Вы чувствуете сильный, но приятный ЖАР в месте удара. Но не боль.")) + return "Впитывает электроудар" + +/obj/item/artefact/zjar/react_at_rvach_gib(mob/living/user) + delete_artefact() + visible_message(SPAN_BAD("[src] вспыхивает ярчайшей красной вспышкой и пропадает."),,7) + return "Защищает от гиба" + +/obj/item/artefact/zjar/energy_changed() + if(stored_energy > 1000) + icon_state = icon_state = "fire_ball_active" + else if(stored_energy <= 1000) + icon_state = icon_state = "fire_ball" + +/obj/item/artefact/zjar/additional_process() + var/turf/my_turf = get_turf(src) + if(my_turf.temperature >= 500) + add_energy(100) diff --git a/mods/anomaly/code/artefacts/artefact_zjemchug.dm b/mods/anomaly/code/artefacts/artefact_zjemchug.dm new file mode 100644 index 0000000000000..7fda67470fce1 --- /dev/null +++ b/mods/anomaly/code/artefacts/artefact_zjemchug.dm @@ -0,0 +1,52 @@ +// [WIP] +/obj/item/artefact/zjemchug + name = "Something" + icon_state = "zjemchug" + desc = "Абсолютно гладкий шар с максимально правильной формой. Чем дольше смотришь на него, тем больше сознание затмевает туман. Что-то не так." + need_to_process = TRUE + rect_to_interactions = list( + "Lick", + "Shake", + "Bite", + "Knock", + "Compress", + "Rub" + ) + ///Моб, к которому привязался артефакт + var/mob/living/carbon/human/owner + stored_energy = 10000 + max_energy = 10000 + cargo_price = 1500 //Это крайне ценный и редкий артефакт + rnd_points = 10000 + +/obj/item/artefact/zjemchug/react_to_touched(mob/living/user) + . = ..() + if(!owner) + deal_make_new_owner(user) + else + to_chat(user, SPAN_BAD("...Вы чувствуете, как внутри вас что-то противится...")) + +/obj/item/artefact/zjemchug/Process() + if(!(owner in get_turf(src))) //На нашем турфе нет хозяина + for(var/mob/living/carbon/human/target in get_turf(src)) + to_chat(target, SPAN_BAD("Что-то пугает вас, заставляет отойти от [src]")) + +/obj/item/artefact/zjemchug/proc/deal_make_new_owner(mob/living/user) + //Предлагает человеку обьединить умы + var/list/choices = list("Да","Нет") + var/choice = input(usr, "Расслабить свой ум и прекратить сопротивление?") as null|anything in choices + if(choice == "Нет") + to_chat(user, SPAN_BAD("Вы решаете продолжить сопротивляться ему. Вы не поддадитесь.")) + return + if(choice == "Да") + make_new_owner(user) + +/obj/item/artefact/zjemchug/proc/make_new_owner(mob/living/user) + owner = user + icon_state = "zjemchug_active" + SSanom.good_interactions_with_artefacts_by_players_ammount++ + to_chat(user, SPAN_GOOD("Вы поддаётесь его влиянию...что-то в вас изменилось...")) + var/list/faculties = list("[PSI_COERCION]", "[PSI_REDACTION]", "[PSI_ENERGISTICS]", "[PSI_PSYCHOKINESIS]") + for(var/i = 1 to rand(2,3)) + var/mob/living/carbon/human/human_user = user + human_user.set_psi_rank(pick_n_take(faculties), 5) diff --git a/mods/anomaly/code/artifacts/interact_with_artefacts.dm b/mods/anomaly/code/artefacts/interact_with_artefacts.dm similarity index 75% rename from mods/anomaly/code/artifacts/interact_with_artefacts.dm rename to mods/anomaly/code/artefacts/interact_with_artefacts.dm index d4b71c5e90e82..a22ad22c1c595 100644 --- a/mods/anomaly/code/artifacts/interact_with_artefacts.dm +++ b/mods/anomaly/code/artefacts/interact_with_artefacts.dm @@ -1,5 +1,5 @@ /obj/item/artefact - var/connected_to_anomaly = TRUE + var/connected_to_anomaly = FALSE ///Здесь будет лист взаимодействий, но который артефакт всё таки реагирует var/list/rect_to_interactions = list() var/turf/prev_loc @@ -17,11 +17,13 @@ else if(connected_to_anomaly) if(AnomaliesAmmountInTurf(get_turf(src)) == 0) connected_to_anomaly = FALSE + SSanom.collected_artefacts_by_player++ else for(var/obj/anomaly/anomka in src.loc.contents) if(prob(25 * user.get_skill_value(SKILL_SCIENCE))) to_chat(user, SPAN_GOOD("[desc]")) connected_to_anomaly = FALSE + SSanom.collected_artefacts_by_player++ else to_chat(user, SPAN_WARNING("Обьект уплывает из ваших рук")) if(istype(anomka, /obj/anomaly/part)) @@ -57,7 +59,8 @@ var/choosed_interaction = input(usr, "What to do","It's time to chose") as null|anything in interaction_variations if(!user.Adjacent(src)) return FALSE - if(choosed_interaction == "Lick" && rect_to_interactions.Find(choosed_interaction)) + SSanom.interactions_with_artefacts_by_players_ammount++ + if(choosed_interaction == "Lick") if(!ishuman(user)) to_chat(user, SPAN_NOTICE("У меня нет рта, но я должен кричать.")) return @@ -66,12 +69,16 @@ if(blocked) to_chat(user, SPAN_NOTICE("Мой рот закрыт, я не могу лизнуть его.")) return + user.visible_message(SPAN_NOTICE("[user] лизнул [src].")) + to_chat(user, SPAN_NOTICE("Вы лизнули [src].")) lick_interaction(user) return - else if(choosed_interaction == "Shake" && rect_to_interactions.Find(choosed_interaction)) + else if(choosed_interaction == "Shake") + user.visible_message(SPAN_NOTICE("[user] потряс [src].")) + to_chat(user, SPAN_NOTICE("Вы потрясли [src].")) shake_interaction(user) return - else if(choosed_interaction == "Bite" && rect_to_interactions.Find(choosed_interaction)) + else if(choosed_interaction == "Bite") if(!ishuman(user)) to_chat(user, SPAN_NOTICE("У меня нет рта, но я должен кричать.")) return @@ -80,18 +87,25 @@ if(blocked) to_chat(user, SPAN_NOTICE("Мой рот закрыт, я не могу укусить его.")) return + user.visible_message(SPAN_NOTICE("[user] укусил [src].")) + to_chat(user, SPAN_NOTICE("Вы укусили [src].")) bite_interaction(user) return - else if(choosed_interaction == "Knock" && rect_to_interactions.Find(choosed_interaction)) + else if(choosed_interaction == "Knock") + user.visible_message(SPAN_NOTICE("[user] постучал по [src].")) + to_chat(user, SPAN_NOTICE("Вы стучите по [src].")) knock_interaction(user) return - else if(choosed_interaction == "Compress" && rect_to_interactions.Find(choosed_interaction)) + else if(choosed_interaction == "Compress") + user.visible_message(SPAN_NOTICE("[user] сжал [src].")) + to_chat(user, SPAN_NOTICE("Вы сжимаете [src].")) compress_interaction(user) return - else if(choosed_interaction == "Rub" && rect_to_interactions.Find(choosed_interaction)) + else if(choosed_interaction == "Rub") + user.visible_message(SPAN_NOTICE("[user] потёр [src].")) + to_chat(user, SPAN_NOTICE("Вы терёте [src].")) rub_interaction(user) return - to_chat(user, SPAN_NOTICE("Ничего не произошло.")) ///ВЗАИМОДЕЙСТВИЯ ОТ ЛЮДЕЙ НАПРЯМУЮ diff --git a/mods/anomaly/code/detectors_and_etc/beacon.dm b/mods/anomaly/code/detectors_and_etc/beacon.dm index 572072d30be9d..0459f26c8d839 100644 --- a/mods/anomaly/code/detectors_and_etc/beacon.dm +++ b/mods/anomaly/code/detectors_and_etc/beacon.dm @@ -6,6 +6,12 @@ w_class = ITEM_SIZE_TINY matter = list(MATERIAL_STEEL = 200) +/obj/item/advanced_bolt/Crossed(O) + . = ..() + if(ishuman(usr)) + for(var/obj/item/storage/bolt_bag/bag in usr) + if(bag.autocollect) + bag.can_be_inserted(src, usr, 0) /obj/item/advanced_bolt/Move() . = ..() @@ -27,6 +33,8 @@ /obj/item/advanced_bolt/on_update_icon() . = ..() var/turf/current_turf = get_turf(src) + if(!current_turf) + return if(LAZYLEN(current_turf.list_of_in_range_anomalies)) icon_state = "beacon_red" else @@ -46,9 +54,5 @@ /obj/item/advanced_bolt, /obj/item/advanced_bolt, /obj/item/advanced_bolt, - /obj/item/advanced_bolt, - /obj/item/advanced_bolt, - /obj/item/advanced_bolt, - /obj/item/advanced_bolt, /obj/item/advanced_bolt ) diff --git a/mods/anomaly/code/detectors_and_etc/bolt.dm b/mods/anomaly/code/detectors_and_etc/bolt.dm index 85419334dafb9..088585a89d7da 100644 --- a/mods/anomaly/code/detectors_and_etc/bolt.dm +++ b/mods/anomaly/code/detectors_and_etc/bolt.dm @@ -6,6 +6,13 @@ w_class = ITEM_SIZE_TINY matter = list(MATERIAL_STEEL = 200) +/obj/item/bolt/Crossed(O) + . = ..() + if(ishuman(usr)) + for(var/obj/item/storage/bolt_bag/bag in usr) + if(bag.autocollect) + bag.can_be_inserted(src, usr, 0) + /obj/item/storage/bolt_bag name = "Bag with bolts" @@ -14,10 +21,25 @@ icon_state = "bolt_bag" allow_quick_gather = TRUE allow_quick_empty = TRUE - w_class = ITEM_SIZE_TINY - max_w_class = ITEM_SIZE_LARGE - max_storage_space = DEFAULT_BOX_STORAGE + w_class = ITEM_SIZE_SMALL + max_w_class = ITEM_SIZE_TINY + max_storage_space = 10 + var/autocollect = FALSE + +/obj/item/storage/bolt_bag/examine(mob/user, distance, is_adjacent) + . = ..() + to_chat(user, SPAN_GOOD("Use RBM and use Toggle autocollect to toggle autocollect.")) + +/obj/item/storage/bolt_bag/verb/toggle_autocollect() + set category = "Object" + set name = "toggle autocollect" + set src in usr + autocollect = !autocollect + if(autocollect) + to_chat(usr, SPAN_NOTICE("Now you will automaticly collect bolts and beacons in this bag.")) + else + to_chat(usr, SPAN_NOTICE("Now you will NOT automaticly collect bolts and beacons in this bag.")) /obj/item/storage/bolt_bag/full_of_bolts startswith = list( @@ -30,10 +52,6 @@ /obj/item/bolt, /obj/item/bolt, /obj/item/bolt, - /obj/item/bolt, - /obj/item/bolt, - /obj/item/bolt, - /obj/item/bolt, /obj/item/bolt ) diff --git a/mods/anomaly/code/detectors_and_etc/deployer.dm b/mods/anomaly/code/detectors_and_etc/deployer.dm new file mode 100644 index 0000000000000..18fbc318c4544 --- /dev/null +++ b/mods/anomaly/code/detectors_and_etc/deployer.dm @@ -0,0 +1,112 @@ +//Всё что делает устройство - размещает маячок (световой) при использовании +/obj/item/beacon_deployer + name = "beacon deployer" + desc = "Special tool created for fast beacon deploys." + icon = 'mods/anomaly/icons/deployer.dmi' + icon_state = "beacon_deployer" + action_button_name = "Use deployer" + w_class = ITEM_SIZE_SMALL + matter = list(MATERIAL_STEEL = 2000) + var/stored_beacon_amount = 0 + var/max_beacon_amount = 50 + ///Отвечает за то, какого цвета будет размещён маячок + var/current_beacon_type = "Green" + +///Осмот +/obj/item/beacon_deployer/examine(mob/user, distance, is_adjacent) + . = ..() + to_chat(user, SPAN_NOTICE("Its [stored_beacon_amount] inside.")) + to_chat(user, SPAN_GOOD("Use Alt + LBM to swap flag color.")) + to_chat(user, SPAN_GOOD("User Cntrl + LBM to unload some flags.")) + +/obj/item/beacon_deployer/AltClick() + current_beacon_type = input(usr, "Choose flag color","Choose") as null|anything in list("Green", "Red", "Yellow", "Blue") + return TRUE + +/obj/item/beacon_deployer/CtrlClick() + deploy_beacon(usr, FALSE, 10) + return TRUE + + +///Кнопка слева сверху для деплоера +/obj/item/beacon_deployer/verb/use_deployer() + set category = "Object" + set name = "Use flag deployer" + set src in usr + + if(!usr.incapacitated()) + check_current_turf(usr) + usr.update_action_buttons() + + +/obj/item/beacon_deployer/use_tool(obj/item/item, mob/living/user, list/click_params) + . = ..() + if(istype(item,/obj/item/stack/flag)) + reload_deployer(user, item) + +///Заряжает в деплоер флаги +/obj/item/beacon_deployer/proc/reload_deployer(mob/living/user, obj/item/stack/flag/item) + if(stored_beacon_amount == max_beacon_amount) //Переполнен + to_chat(user, SPAN_NOTICE("Deployer is full.")) + return + //Определяемся, сколько передадим флажков + var/transfer_amount = item.amount + if(stored_beacon_amount + item.amount > max_beacon_amount) + transfer_amount = max_beacon_amount - stored_beacon_amount //Не позволит переполнить запас + if(transfer_amount > item.amount) + transfer_amount = item.amount //Не позволит взять больше, чем есть в стаке + item.use(transfer_amount) + stored_beacon_amount += transfer_amount + to_chat(user, SPAN_NOTICE("You inserted [transfer_amount] flags in autodeployer.")) + +/obj/item/beacon_deployer/attack_self(mob/living/user) + . = ..() + check_current_turf(user) + +///Игрок использовал деплоер. Если маяка нет - поставим. Есть - заберём. +/obj/item/beacon_deployer/proc/check_current_turf(mob/living/user) + if(locate(/obj/item/stack/flag) in get_turf(src)) + for(var/obj/item/stack/flag/picked_flag in get_turf(src)) + undeploy_beacon(user, picked_flag) + else + deploy_beacon(user) + +///Разобрать флаг и убрать в деплоер +/obj/item/beacon_deployer/proc/undeploy_beacon(mob/living/user, obj/item/stack/flag/item) + if(item.upright) + item.knock_down() + reload_deployer(user, item) + +///Установить флаг из деплоера +/obj/item/beacon_deployer/proc/deploy_beacon(mob/living/user, deploy = TRUE, deploy_amount = 1) + if(stored_beacon_amount <= 0) + to_chat(user, SPAN_BAD("Deployer is empty.")) + return + if(deploy_amount > 1) + if(deploy_amount > stored_beacon_amount) + deploy_amount = stored_beacon_amount + var/type + if(current_beacon_type == "Green") + type = /obj/item/stack/flag/green + else if(current_beacon_type == "Red") + type = /obj/item/stack/flag/red + else if(current_beacon_type == "Blue") + type = /obj/item/stack/flag/blue + else if(current_beacon_type == "Yellow") + type = /obj/item/stack/flag/yellow + if(!type) + return + var/obj/item/stack/flag/spawned_flag = new type(get_turf(src)) + spawned_flag.amount = deploy_amount + stored_beacon_amount -= deploy_amount + if(deploy) + spawned_flag.set_up() + playsound(src, 'sound/items/shuttle_beacon_complete.ogg', 50) + + + + + + +/obj/item/beacon_deployer/full + stored_beacon_amount = 50 diff --git a/mods/anomaly/code/detectors_and_etc/detector.dm b/mods/anomaly/code/detectors_and_etc/detector.dm index ef6d6150f2841..1376b46fae2f6 100644 --- a/mods/anomaly/code/detectors_and_etc/detector.dm +++ b/mods/anomaly/code/detectors_and_etc/detector.dm @@ -1,30 +1,59 @@ /obj/anomaly ///Шанс, что аномалию найдут детектором при условии что у пользователя максимальный навык науки var/chance_to_be_detected = 100 + //Спрайт обнаруженной аномалии. Смотри прок get_detection_icon(). Этот спрайт - стандартный для любых аномок. + var/detection_icon_state = "any_anomaly" + ///Уровень навыка в науке, требуемый, чтоб персонаж смог понять тип аномалии + var/detection_skill_req = SKILL_TRAINED /obj/item/clothing/gloves/anomaly_detector name = "anomaly detection device" - desc = "TEST." + desc = "A complex technological device designed taking into account all possible dangers of anomalies." icon = 'mods/anomaly/icons/detector.dmi' icon_state = "detector_idle" action_button_name = "Scan anomalies" var/last_peek_time = 0 - var/peek_delay = 0.2 SECONDS + var/peek_delay = 1 SECONDS var/show_anomalies_delay = 10 SECONDS var/in_tesla_range = FALSE var/in_scanning = FALSE var/last_scan_time = 0 var/result_tesla = FALSE + var/global_scan_cooldown = 300 SECONDS + var/last_global_scan = 0 + +/obj/item/clothing/gloves/anomaly_detector/proc/switch_toggle() + if(!is_processing) + to_chat(usr, SPAN_NOTICE("You turn on detector")) + START_PROCESSING(SSanom, src) + SSanom.processing_ammount++ + else + to_chat(usr, SPAN_NOTICE("You turn off detector")) + STOP_PROCESSING(SSanom, src) + SSanom.processing_ammount-- -/obj/item/clothing/gloves/anomaly_detector/Initialize() - . = ..() - START_PROCESSING(SSanom, src) /obj/item/clothing/gloves/anomaly_detector/attack_self(mob/living/user) . = ..() + if(!is_processing) + to_chat(usr, SPAN_BAD("Device turned off")) + return try_found_anomalies(user) + +/obj/item/clothing/gloves/anomaly_detector/AltClick() + if(!is_processing) + to_chat(usr, SPAN_BAD("Device turned off")) + return + scan_z_level_for_anomalies(usr) + return TRUE + +/obj/item/clothing/gloves/anomaly_detector/CtrlClick(mob/user) + . = ..() + switch_toggle() + return TRUE + /obj/item/clothing/gloves/anomaly_detector/Process() check_electrostatic() update_icon() @@ -41,19 +70,19 @@ icon_state = "detector_scanning_and_peak" -/obj/item/clothing/gloves/anomaly_detector/verb/scan() +/obj/item/clothing/gloves/anomaly_detector/verb/scan_anomalies() set category = "Object" - set name = "Scan anomalies with detector" + set name = "Scan anomalies" set src in usr if(!usr.incapacitated()) try_found_anomalies(usr) usr.update_action_buttons() - /obj/item/clothing/gloves/anomaly_detector/proc/check_electrostatic() - if(world.time - last_scan_time >= peek_delay ) - last_peek_time = world.time + if(world.time - last_peek_time < peek_delay ) + return + last_peek_time = world.time var/turf/cur_turf = get_turf(src) //Проверяем, турф на котором мы находимся находится в зоне поражения? if(LAZYLEN(cur_turf.list_of_in_range_anomalies)) @@ -71,6 +100,8 @@ /obj/item/clothing/gloves/anomaly_detector/examine(mob/user, distance, is_adjacent) . = ..() to_chat(user, SPAN_GOOD("Use LBM in anomaly scan mode for search anomalies, or use action button.")) + to_chat(user, SPAN_GOOD("Use Alt + LBM to use more powerfull mode.")) + to_chat(user, SPAN_GOOD("Use Cntrl + LBM to turn on/turn off device.")) ///Пользователь проводит поиск при помощи сканера /obj/item/clothing/gloves/anomaly_detector/proc/try_found_anomalies(mob/living/user) @@ -83,7 +114,7 @@ //Мы проверили, есть ли у пользователя базовый навык НАУКИ. // Снижаем 1.2 секунды сканирования за каждый пункт науки у персонажа var/user_science_lvl = user.get_skill_value(SKILL_SCIENCE) - var/time_to_scan = (10 - (1.2 * user_science_lvl)) SECONDS + var/time_to_scan = (20 - (2 * user_science_lvl)) SECONDS var/scan_radius = (4 + user_science_lvl) //макс радиус - 9 "квадратов" in_scanning = TRUE update_icon() @@ -101,11 +132,15 @@ //Список разрешённых для показа игроку аномалий var/list/allowed_anomalies = list() for(var/obj/anomaly/choosed_anomaly in objs) - var/chance_to_find = (user_science_lvl * 20) - (100 - choosed_anomaly.chance_to_be_detected) - if(prob(chance_to_find)) - LAZYADD(allowed_anomalies, choosed_anomaly) - var/flick_time = (1 + (user_science_lvl * 2))SECONDS - show_anomalies(user, flick_time, allowed_anomalies) + if(!choosed_anomaly.is_helper) //Вспомогательные части аномалий нас не интересуют + var/chance_to_find = (user_science_lvl * 20) - (100 - choosed_anomaly.chance_to_be_detected) + if(prob(chance_to_find)) + LAZYADD(allowed_anomalies, choosed_anomaly) //Добавляем саму аномалию + //Если у неё есть вспомогательные части - добавляем её вспомогательные части + if(choosed_anomaly.multitile) + for(var/obj/anomaly/choosed_part in choosed_anomaly.list_of_parts) + LAZYADD(allowed_anomalies, choosed_part) + show_anomalies(user, time_to_scan, allowed_anomalies) if(LAZYLEN(allowed_anomalies)) flick("detector_detected_anomalies", src) usr.update_action_buttons() @@ -115,29 +150,51 @@ usr.update_action_buttons() -/proc/show_anomalies(mob/viewer, flick_time, allowed_anomalies) +/obj/item/clothing/gloves/anomaly_detector/proc/scan_z_level_for_anomalies(mob/living/user) + if(in_scanning) + return + if((world.time - last_global_scan) < global_scan_cooldown) + to_chat(user, SPAN_BAD("Detector still isn't ready.")) + return + last_global_scan = world.time + var/user_science_lvl = user.get_skill_value(SKILL_SCIENCE) + var/time_to_scan = (30 - (2 * user_science_lvl)) SECONDS + in_scanning = TRUE + update_icon() + usr.update_action_buttons() + if (do_after(user, time_to_scan, src, DO_DEFAULT | DO_USER_UNIQUE_ACT) && user) + in_scanning = FALSE + update_icon() + usr.update_action_buttons() + for(var/obj/anomaly/picked_anomaly in SSanom.all_anomalies_cores) + if(picked_anomaly.z == get_z(src)) + to_chat(user, SPAN_BAD("Обнаружена аномальная активность.")) + return TRUE + to_chat(user, SPAN_GOOD("Аномалий не обнаружено.")) + return FALSE + +///Показывает игроку аномалии, которые он обнаружил детектером +/proc/show_anomalies(mob/living/viewer, flick_time, allowed_anomalies) if(!ismob(viewer) || !viewer.client) return - var/list/t_ray_images = list() + var/user_science_lvl = viewer.get_skill_value(SKILL_SCIENCE) + var/list/list_of_showed_anomalies = list() for(var/obj/anomaly/in_turf_atom in allowed_anomalies) var/turf/T = get_turf(in_turf_atom) - var/image/I = image(icon = 'mods/anomaly/icons/effects.dmi',loc = T,icon_state = "none") - var/mutable_appearance/MA = new(in_turf_atom) - MA.alpha = 255 - MA.dir = in_turf_atom.dir - MA.plane = FLOAT_PLANE - I.layer = HUD_ABOVE_ITEM_LAYER - I.appearance = MA - t_ray_images += I + var/image/I + if(user_science_lvl >= in_turf_atom.detection_skill_req) + I = image(icon = 'mods/anomaly/icons/detection_icon.dmi',loc = T, icon_state = in_turf_atom.get_detection_icon()) + else + I = image(icon = 'mods/anomaly/icons/detection_icon.dmi',loc = T, icon_state = in_turf_atom.detection_icon_state) + I.layer = EFFECTS_ABOVE_LIGHTING_PLANE + list_of_showed_anomalies += I - for(var/image/choosed_image in t_ray_images) - choosed_image.icon_state = "none" - if(length(t_ray_images)) - flick_overlay(t_ray_images, list(viewer.client), flick_time) + if(length(list_of_showed_anomalies)) + flick_overlay(list_of_showed_anomalies, list(viewer.client), flick_time) /obj/item/paper/sierra/exploration name = "new dangers" - info = "
NSV Sierra
Новые опасности
  • Одна из последних экспедиций вернулась с новой информацией, и ранениями. Согласно последнему отчёту, экспедиционный отряд наткнулся на некую аномальную активность на одной из планет. Научно исследовательский отдел выделил вашему отряду дополнительное снаряжение и модифицировал сканеры Саcпаровой, добавив им АЛЬТЕРНАТИВНЫЙ режим. Советуем проявлять огромную осторожность при работе на планетах. Удачи.

    This paper has been stamped by the Research&Development department." + info = "
    NSV Sierra
    Новые опасности
  • Одна из последних экспедиций вернулась с новой информацией, и ранениями. Согласно последнему отчёту, экспедиционный отряд наткнулся на некую аномальную активность на одной из планет. Научно исследовательский отдел выделил вашему отряду дополнительное снаряжение в виде маячков, коллекторов аномальных образований, детектора аномальной активности и раздатчика флагов. Советуем проявлять огромную осторожность при работе на планетах. Удачи.

    This paper has been stamped by the Research&Development department." icon = 'maps/sierra/icons/obj/uniques.dmi' icon_state = "paper_words" diff --git a/mods/anomaly/code/detectors_and_etc/research_machine.dm b/mods/anomaly/code/detectors_and_etc/research_machine.dm index b075672e5ebb0..ab5d324055405 100644 --- a/mods/anomaly/code/detectors_and_etc/research_machine.dm +++ b/mods/anomaly/code/detectors_and_etc/research_machine.dm @@ -4,6 +4,7 @@ icon = 'mods/anomaly/icons/urm.dmi' icon_state = "urm" anchored = TRUE + density = TRUE idle_power_usage = 5 power_channel = EQUIP var/obj/item/cell/charging = null diff --git a/mods/anomaly/code/documentation/README.md b/mods/anomaly/code/documentation/README.md new file mode 100644 index 0000000000000..68cafd1e3bcd3 --- /dev/null +++ b/mods/anomaly/code/documentation/README.md @@ -0,0 +1,105 @@ +## Disclaimer +НЕ лезьте в код с целью подсмотреть как работает тот или определённый механ с целью получения игрового преимущества, это разрушает всю идею исследования +НЕ распростроняйте информацию о работе аномалий и прочего в общих чатах, это тоже очень плохо влияет на восприятие! + +# WIP Документация в процессе написания! WIP + +Данная папка - documentation - будет содержать в себе различную документацию,пояснялки и блок схемы. + +## Небольшая карта мода: +[Аномалии] - [mods\anomaly\code\anomalies] + +[Артефакты]- [mods\anomaly\code\artifacts] + +[Оборудование_и_снаряжение] - [mods\anomaly\code\detectors_and_etc] + +[Спавн_аномалий_и_их_размещение_игры] - [mods\anomaly\code\spawn_anomalies_protocol] + +[Погода] - [mods\anomaly\code\monitor_effects] + +[Админ_билдер_аномалий] - [mods\anomaly\code\anomaly_admin.dm] + +[Сабсистема_аномалий] - [mods\anomaly\code\anomaly_controller.dm] + +## Аномалии +Вся ИДЕЯ аномалий взята с сервера Ашан, Сталкер, пикник на обочине, реализация - своя. +Игромеханически, аномалии можно сравнить с сапёром, т.к геймплей больше похож именно на это. +-Аномалия/её вспомогательные части реагируют на пересечение себя какими-либо предметами, обьектами, существами. -В случае если атом(любой обьект) указан в параметрах как ИНИЦИАТОР - аномалия реагирует, т.е ВЗВОДИТСЯ. +-Если аномалия ПРЕДЗАРЯДОЧНАЯ, need_preload, аномалия ждёт время, равное cooldown +-Для всех атомов в радиусе effect_range() выполняется get_effect_by_anomaly() +-После, выполняется handle_activate и аномалия начинает "Считать время" до следующей активации +-После того как аномалия вновь доступна и готова реагировать, мы ещё раз проверяем ядро и вспомогательные части на наличие инициаторов. Если никого нет - код закончен и аномалия больше ничего не просчитывает. Если что-то нашлось - всё по новой, и так пока инициаторов не станет. (Т.е аномалия не успокоится, пока в ней условно будет человек) + + +## Артефакты +В отличии от артефактов с ашана где крайне много бесполезных артефактов и крайне много артефактов с слишком скрытыми свойствами, где игрок исключительно СЛУЧАЙНО узнает его свойство - артефакты мода ANOMALIES хоть и малочисленны, но обладают множественными эффектами, несколько эффектов являются крайне очевидными и находятся с помощью ИНТЕРАКЦИЙ, намёки на многие находятся через интеракции с URM machine и так же находятся через обычные интеракции, и лишь малая часть - довольно спрятаны и находятся случайно. + +Артефакты спавнятся при генерации аномалий через функцию generate_anomalies_in_turfs(), их количество строго ограничено при генерации. + +[Постоянное_воздействие_на_носителя] +Артефакты обрабатываются 24/7 подсистемой SSanom, т.к невозможно предугадать кодом все движения артефакта по инвентарям/турфам и т.д +При процессинге раз в довольно большой срок (2-5 секунд) артефакт проверяет, что он всё ещё находится в мобе. +Далее, артефакт оказывает своё постоянное влияние на носителя - регенерирует стамину, лечит органы, что угодно, это указывается в +/obj/item/artefact/proc/process_artefact_effect_to_user() + return + +Готовые примеры: +Код для регенерации стамины пользователя: +/obj/item/artefact/gravi/process_artefact_effect_to_user() + if(current_user.stamina < 85) + current_user.adjust_stamina(5) +Т.е, если стамина носителя меньше 85 - добавить ему 5 единиц +Меняйте переменную process_effect_cooldown чтоб выбирать, как часто артефакт будет влиять на носителя + +[Реакция_артефатков_на_внешнее_событие_с_носителем] +Артефакты могут отслеживать внешние события происходящие с их носителем. Вот как это работает + +//У нас есть событие - персонаж проваливается на Z уровень ниже +/mob/living/carbon/human/handle_fall_effect(turf/landing) + //Мы вызываем функцию, которая опросит все артефакты находящиеся в инвентаре носителя что ОНИ думают об этом событии + var/list/result_effects = calculate_artefact_reaction(src, "Падение с высоты") + if(result_effects) + //Здесь мы добавляем, какие реакции что делают. Если мы хотим при помощи реакции "Защищает от падения" защитить персонажа от урона с падения - так и пишем. + if(result_effects.Find("Защищает от падения")) + return + .=..() + +Всё, теперь артефакт оберегает персонажа от падения с высоты. Тоже самое с ЭМИ ударом. + +/mob/living/emp_act(severity) + var/list/result_effects = calculate_artefact_reaction(src, "ЭМИ") + if(result_effects) + if(result_effects.Find("Защищает от ЭМИ")) + return + . = ..() + +Подробнее в + + +## Спавн аномалий и их размещение игры +[mods\anomaly\code\spawn_anomalies_protocol] <-- Весь код отвечающий за спавн аномалий в игре и их размещение. +ПОДРОБНЕЕ ТУТ ---> mods\anomaly\code\spawn_anomalies_protocol\core_spawn_protocol.dm , в начале файла. + +В общих чертах - разнообразые "Источники", такие как: +-Ивент "Разлив БСД", +-Появление в мире большого артефакта подходящего по условиям +-Диреликт,где мапер поставил аномалии +-Планеты которые помечены как спавнящие аномалии +Собирают вокруг себя турфы и вызывают функцию generate_anomalies_in_turfs(), которая размещает аномалии по очень +примитивному алгоритму - случайным образом выбирает из переданного списка турфов турф и ставит аномалию. Если аномалия мультитайтловая, то при пересечении аномалии с чем-то, убирает турф из списка турфов, аномалию удаляют. Технически - метод тыка. + + +## Погода +Основная задача данного кода - реагировать на вход/выход ИГРОКА(Обязателен Ckey у жертвы) и выдавать ему на экран оверлей, если потребуется. Если хотите добавить данной "Погоде" спрайт - ознакомьтесь с кодом по пути mods\anomaly\code\monitor_effects\snow_monitor_effect.dm + +Генерируется Погода при генерации аномалий на планете Лёд. Перепишу когда появится нужда в локальных участках погоды(Для условного диреликта в виде вулканической местности) + + +## Билдер аномалий +Работает точно так же как и все билдеры. Для добавления новой аномалии - добавьте её в список possible_anomalies по аналогии. Всё что идёт справа, от пути аномалии - её описание для администрации. Указывайте всю информацию, она может и БУДЕТ влиять на эффективность билдера. + + +## Сабсистема_аномалий + + +# WIP Документация в процессе написания! WIP diff --git "a/mods/anomaly/code/documentation/electra_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\215\320\273\320\265\320\272\321\202\321\200\321\213.drawio" "b/mods/anomaly/code/documentation/electra_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\215\320\273\320\265\320\272\321\202\321\200\321\213.drawio" new file mode 100644 index 0000000000000..c4563d8ffb26d --- /dev/null +++ "b/mods/anomaly/code/documentation/electra_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\215\320\273\320\265\320\272\321\202\321\200\321\213.drawio" @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git "a/mods/anomaly/code/documentation/electra_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\215\320\273\320\265\320\272\321\202\321\200\321\213.png" "b/mods/anomaly/code/documentation/electra_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\215\320\273\320\265\320\272\321\202\321\200\321\213.png" new file mode 100644 index 0000000000000..e97dda372b112 Binary files /dev/null and "b/mods/anomaly/code/documentation/electra_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\215\320\273\320\265\320\272\321\202\321\200\321\213.png" differ diff --git "a/mods/anomaly/code/documentation/rvach_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\200\320\262\320\260\321\207\320\260.drawio" "b/mods/anomaly/code/documentation/rvach_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\200\320\262\320\260\321\207\320\260.drawio" new file mode 100644 index 0000000000000..bdcebccbd299f --- /dev/null +++ "b/mods/anomaly/code/documentation/rvach_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\200\320\262\320\260\321\207\320\260.drawio" @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git "a/mods/anomaly/code/documentation/rvach_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\200\320\262\320\260\321\207\320\260.png" "b/mods/anomaly/code/documentation/rvach_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\200\320\262\320\260\321\207\320\260.png" new file mode 100644 index 0000000000000..4f19e40fff34e Binary files /dev/null and "b/mods/anomaly/code/documentation/rvach_anomaly/\320\241\321\205\320\265\320\274\320\260 \321\200\320\262\320\260\321\207\320\260.png" differ diff --git a/mods/anomaly/code/monitor_effects/monitor_core.dm b/mods/anomaly/code/monitor_effects/monitor_core.dm new file mode 100644 index 0000000000000..25a8556ad00ed --- /dev/null +++ b/mods/anomaly/code/monitor_effects/monitor_core.dm @@ -0,0 +1,53 @@ +GLOBAL_LIST_EMPTY(effected_by_weather) +GLOBAL_VAR_INIT(ambience_channel_weather, GLOB.sound_channels.RequestChannel("AMBIENCE_WEATHER")) + +///Кто-то или что-то вошло в монитор-эффект +/obj/monitor_effect_triger/Crossed(O) + react_at_enter_monitor(O) + +/obj/monitor_effect_triger/Uncrossed(O) + react_at_leave_monitor(O) + +/obj/monitor_effect_triger/proc/add_monitor_effect(mob/living/input_mob) + LAZYADD(input_mob,GLOB.effected_by_weather) + +/obj/monitor_effect_triger/proc/remove_monitor_effect(mob/living/input_mob) + LAZYREMOVE(input_mob,GLOB.effected_by_weather) + +/obj/monitor_effect_triger/proc/react_at_enter_monitor(atom/movable/atom) + if(!must_react_at_enter) + return + //Незачем накладывать эффект тому, кто уже с этим эффектом + if(atom in GLOB.effected_by_weather) + return + if(isliving(atom)) + var/mob/living/detected_mob = atom + //Если у моба есть клиент, значит есть на кого накладывать эффект на экран + if(detected_mob.client) + if(LAZYLEN(sound_type)) + var/sound = sound(pick(sound_type), repeat = TRUE, wait = 0, volume = 50, channel = GLOB.ambience_channel_weather) + detected_mob.playsound_local(get_turf(detected_mob), sound) + add_monitor_effect(detected_mob) + LAZYADD(GLOB.effected_by_weather, atom) + //Если прошло достаточно времени с предыдущего пука в чат игроку - пукнем. + if(detected_mob.last_monitor_message < world.time) + to_chat(detected_mob, SPAN_BAD(pick(trigger_messages_list))) + //Добавим время от КД + detected_mob.last_monitor_message = detected_mob.last_monitor_message + trigger_message_cooldown + +/obj/monitor_effect_triger/proc/react_at_leave_monitor(atom/movable/atom) + if(!must_react_at_enter) + return + var/mob/detected_mob = atom + if(!IsMonitorHere(get_turf(atom))) + if(atom in GLOB.effected_by_weather) + LAZYREMOVE(GLOB.effected_by_weather, atom) + remove_monitor_effect(detected_mob) + if(LAZYLEN(sound_type)) + sound_to(detected_mob, sound(null, channel = GLOB.ambience_channel_weather)) + +/proc/IsMonitorHere(turf/input_turf) + if(locate(/obj/monitor_effect_triger) in input_turf) + return TRUE + else + return FALSE diff --git a/mods/anomaly/code/monitor_effects/monitor_vars.dm b/mods/anomaly/code/monitor_effects/monitor_vars.dm new file mode 100644 index 0000000000000..9d99c62b3dd4a --- /dev/null +++ b/mods/anomaly/code/monitor_effects/monitor_vars.dm @@ -0,0 +1,18 @@ +/mob/living + var/last_monitor_message = 0 + +//Наложит игроку на экран эффект, уберёт его, а так же может дополнительно начать влиять на существо. +/obj/monitor_effect_triger + //Путь до эффекта накладываемого на экран + var/effect_icon_type + var/sound_type = list() + ///Должнен ли монитор эффект реагировать на пересечение с кем-либо или чем-либо + var/must_react_at_enter = FALSE + anchored = TRUE + invisibility = TRUE + layer = EFFECTS_LAYER + vis_flags = VIS_INHERIT_ID + //Лист сообщений выводимые в чат игроку при входе в зону + var/list/trigger_messages_list = list() + var/trigger_message_cooldown = 10 MINUTES + mouse_opacity = FALSE //Погода должна быть непрокликиваемой diff --git a/mods/anomaly/code/monitor_effects/snow_monitor_effect.dm b/mods/anomaly/code/monitor_effects/snow_monitor_effect.dm new file mode 100644 index 0000000000000..7c645cb55a72c --- /dev/null +++ b/mods/anomaly/code/monitor_effects/snow_monitor_effect.dm @@ -0,0 +1,38 @@ +//Эффект снежной вьюги +/obj/monitor_effect_triger/snow + icon_state = "snow_storm" + icon = 'mods/anomaly/icons/weather_effects.dmi' + must_react_at_enter = TRUE + sound_type = list( + 'mods/anomaly/sounds/snowstorm.ogg' + ) + +/obj/monitor_effect_triger/snow + trigger_messages_list = list( + "Мрачные облака, толстый слой инея на земле и стремительные порывы ветра делают каждый шаг испытанием.", + "Белое пространство, прерываемое лишь силуэтами ледяных скал, напоминающих причудливые формации.", + "Бесконечный буран, да и только. Паршивая планета.", + "Куда ни глянь — пустота. Ядовито-белый мрак простирается до самого горизонта, как бесконечный океан.", + "Холод, кажется, проникает не только внутрь, но и в самые глубокие уголки твоей души сквозь скафандр. Каждое движение даётся через силу, а мысли теряются среди непрекращающегося гула ветра.", + "Рокот небес, напряженный до предела, сопровождает каждое твое движение.", + "Ледяная пыль начинает шевелиться, и этот далекий гул намекает на опасность.", + "Ты поднимаешь голову, наблюдая, как пурга хлещет по ледяным вершинам.", + "Каждый шорох и треск вокруг как будто вызывают у тебя певучее предчувствие опасности.", + "Тьма нависла над тобой, как тяжелый саван. Кажется, что даже звезды в небе отдалились от этого ледяного кошмара." + ) + +//Эффект снега на экране +/obj/screen/fullscreen/snow_effect + icon = 'mods/anomaly/icons/snow_screen.dmi' + icon_state = "snow" + layer = BLIND_LAYER + scale_to_view = TRUE + + + +/obj/monitor_effect_triger/snow/add_monitor_effect(mob/living/input_mob) + input_mob.overlay_fullscreen("snow_monitor", /obj/screen/fullscreen/snow_effect) + //Логируем пользователя в глобальный список + +/obj/monitor_effect_triger/snow/remove_monitor_effect(mob/living/input_mob) + input_mob.clear_fullscreen("snow_monitor") diff --git a/mods/anomaly/code/monitor_effects/swamp_monitor_effect.dm b/mods/anomaly/code/monitor_effects/swamp_monitor_effect.dm new file mode 100644 index 0000000000000..b7906c1aad193 --- /dev/null +++ b/mods/anomaly/code/monitor_effects/swamp_monitor_effect.dm @@ -0,0 +1,2 @@ +/obj/monitor_effect_triger/swamp + name = "bam" diff --git a/mods/anomaly/code/monitor_effects/vulcan_monitor_effect.dm b/mods/anomaly/code/monitor_effects/vulcan_monitor_effect.dm new file mode 100644 index 0000000000000..ee78b8ce329cb --- /dev/null +++ b/mods/anomaly/code/monitor_effects/vulcan_monitor_effect.dm @@ -0,0 +1,5 @@ +//Эффект вулкана WIP +/obj/monitor_effect_triger/vulcan + icon_state = "light_storm" + icon = 'mods/anomaly/icons/weather_effects.dmi' + invisibility = FALSE diff --git a/mods/anomaly/code/spawn_anomalies_protocol/bsd_event_protocol.dm b/mods/anomaly/code/spawn_anomalies_protocol/bsd_event_protocol.dm index 04b408f9dff28..1949afefd9589 100644 --- a/mods/anomaly/code/spawn_anomalies_protocol/bsd_event_protocol.dm +++ b/mods/anomaly/code/spawn_anomalies_protocol/bsd_event_protocol.dm @@ -15,10 +15,10 @@ var/started_in = world.time var/list/turfs_for_spawn = list() for(var/obj/machinery/bluespacedrive/picked_drive in drives) - for(var/turf/turfs as anything in RANGE_TURFS(picked_drive.loc, 10)) - if(!TurfBlocked(turfs) || TurfBlockedByAnomaly(turfs)) - LAZYADD(turfs_for_spawn, turfs) - all_spawned_anomalies = generate_anomalies_in_turfs(possible_anomalies, turfs_for_spawn, 5, 15, 0, 0, 9, 9, "BSD event", started_in) + for(var/turf/picked_turf as anything in RANGE_TURFS(picked_drive.loc, 25)) + if(!TurfBlocked(picked_turf, space_allowed = FALSE) || TurfBlockedByAnomaly(picked_turf)) + LAZYADD(turfs_for_spawn, picked_turf) + all_spawned_anomalies = generate_anomalies_in_turfs(possible_anomalies, turfs_for_spawn, 25, 40, 0, 0, 9, 9, "BSD event", started_in) /datum/event/bsd_instability/end() diff --git a/mods/anomaly/code/spawn_anomalies_protocol/core_spawn_protocol.dm b/mods/anomaly/code/spawn_anomalies_protocol/core_spawn_protocol.dm index 82f22ec931b3e..e71859d248713 100644 --- a/mods/anomaly/code/spawn_anomalies_protocol/core_spawn_protocol.dm +++ b/mods/anomaly/code/spawn_anomalies_protocol/core_spawn_protocol.dm @@ -31,22 +31,26 @@ path_to_spawn - Путь аномалии, которую мы хотим зас else return spawned_anomaly -/proc/TurfBlocked(turf/loc) +/proc/TurfBlocked(turf/loc, space_allowed = TRUE) + if(!loc) //Если входного турфа нет - автоматом сообщаем о заблокированном турфе + return TRUE + if(!space_allowed && (isspaceturf(loc) || isspace(get_area(loc)))) + return TRUE if(loc.density) - return 1 + return TRUE for(var/obj/O in loc) - if(O.density) - return 1 - return 0 + if(O.density && !istype(O, /obj/structure/railing)) + return TRUE + return FALSE /proc/TurfBlockedByAnomaly(turf/loc) for(var/obj/O in loc) if(istype(O, /obj/anomaly)) - return 1 - return 0 + return TRUE + return FALSE /proc/AnomaliesAmmountInTurf(turf/loc) - var/output = 0 + var/output = FALSE for(var/obj/O in loc) if(istype(O, /obj/anomaly)) output++ @@ -85,21 +89,12 @@ max_anomaly_size - Максимальный размер аномалий (anoma source - Источник(Причина) генерации аномалий на турфах. Используется для отчёта */ /proc/generate_anomalies_in_turfs(list/anomalies_types, list/all_turfs_for_spawn, min_anomalies_ammout, max_anomalies_ammout, min_artefacts_ammount, max_artefacts_ammount, min_anomaly_size, max_anomaly_size, source, started_in) - //Генерация аномалий - это ОЧЕНЬ тяжёлый прок, который без проблем вешает юнит тесты. set background = 1 //Расчитываем мин и макс количество аномалий var/result_anomalies_ammout = 1 - if((!min_anomalies_ammout) || (min_anomalies_ammout * min_anomaly_size > LAZYLEN(all_turfs_for_spawn))) - min_anomalies_ammout = 1 - if(!max_anomalies_ammout) - max_anomalies_ammout = (LAZYLEN(all_turfs_for_spawn)) - max_anomalies_ammout /= max_anomaly_size - - result_anomalies_ammout = rand(min_anomalies_ammout, max_anomalies_ammout) - if(result_anomalies_ammout * max_anomaly_size > LAZYLEN(all_turfs_for_spawn)) - result_anomalies_ammout = LAZYLEN(all_turfs_for_spawn) - result_anomalies_ammout /= max_anomaly_size - result_anomalies_ammout = Round(result_anomalies_ammout) + min_anomalies_ammout = calculate_min_anomalies_ammout(min_anomaly_size, max_anomaly_size, min_anomalies_ammout, LAZYLEN(all_turfs_for_spawn)) + max_anomalies_ammout = calculate_max_anomalies_ammout(min_anomaly_size, max_anomaly_size, max_anomalies_ammout, LAZYLEN(all_turfs_for_spawn)) + result_anomalies_ammout = calculate_result_anomalies_ammout(min_anomaly_size, max_anomaly_size, min_anomalies_ammout, max_anomalies_ammout, result_anomalies_ammout, LAZYLEN(all_turfs_for_spawn)) //Собрав все турфы и определившись с числом аномалий, давайте начинать @@ -184,33 +179,67 @@ source - Источник(Причина) генерации аномалий н //Выбрав количество артов которые мы хотим заспавнить, мы начинаем спавн var/spawned_anomalies_ammount = LAZYLEN(spawned_anomalies) - var/list/output_list = spawned_anomalies - var/spawned_artifacts_ammount = generate_artefacts_in_anomalies(spawned_anomalies, min_artefacts_ammount, max_artefacts_ammount) + var/spawned_artefacts_ammount = generate_artefacts_in_anomalies(spawned_anomalies.Copy(), min_artefacts_ammount, max_artefacts_ammount) var/spended_time = world.time - started_in //Отчитаемся if(spawned_anomalies_ammount > 0) - report_progress("Spawned [spawned_anomalies_ammount] anomalies with [spawned_artifacts_ammount] artefacts by: [source], spended [spended_time] ticks ") - return output_list + report_progress("Spawned [spawned_anomalies_ammount] anomalies with [spawned_artefacts_ammount] artefacts by: [source], spended [spended_time] ticks ") + LAZYADD(SSanom.important_logs, "Spawned [spawned_anomalies_ammount] anomalies with [spawned_artefacts_ammount] artefacts by: [source], spended [spended_time] ticks ") + return spawned_anomalies ///Функция генерация артефактов в аномалиях. Спавнит количество артефактов, находящиеся в диапазоне между min_artefacts_ammoun и max_artefacts_ammount /proc/generate_artefacts_in_anomalies(list/list_of_anomalies, min_artefacts_ammount, max_artefacts_ammount) var/artefacts_ammount = rand(min_artefacts_ammount, max_artefacts_ammount) + var/list/input_list = list_of_anomalies //Санитайз, чтоб не требовали рождение артефактов от тех, кто их рожать не может физически - for(var/obj/anomaly/picked_anomaly in list_of_anomalies) - if(!picked_anomaly.can_born_artifacts || !LAZYLEN(picked_anomaly.artefacts)) - LAZYREMOVE(list_of_anomalies, picked_anomaly) + for(var/obj/anomaly/picked_anomaly in input_list) + if(!picked_anomaly.can_born_artefacts || !LAZYLEN(picked_anomaly.artefacts)) + LAZYREMOVE(input_list, picked_anomaly) //Санитайз, чтоб артефактов было не слишком много - if(artefacts_ammount > LAZYLEN(list_of_anomalies)) - artefacts_ammount = LAZYLEN(list_of_anomalies) + if(artefacts_ammount > LAZYLEN(input_list)) + artefacts_ammount = LAZYLEN(input_list) var/spawned_artefacts = 0 //Пока игра не заспавнит все треуемые артефакты while(artefacts_ammount > spawned_artefacts) - var/obj/anomaly/choosed_anomaly = pick(list_of_anomalies) + var/obj/anomaly/choosed_anomaly = pick(input_list) if(!choosed_anomaly) return spawned_artefacts - if(choosed_anomaly.try_born_artifact()) + if(choosed_anomaly.try_born_artefact()) spawned_artefacts++ else - LAZYREMOVE(list_of_anomalies, choosed_anomaly) + LAZYREMOVE(input_list, choosed_anomaly) return spawned_artefacts + + + + + + + + + + + + + +/proc/calculate_min_anomalies_ammout(min_anomaly_size, max_anomaly_size, min_anomalies_ammout, all_turfs_for_spawn_len) + if((!min_anomalies_ammout) || (min_anomalies_ammout * min_anomaly_size > all_turfs_for_spawn_len)) + min_anomalies_ammout = 1 + return min_anomalies_ammout + + + +/proc/calculate_max_anomalies_ammout(min_anomaly_size, max_anomaly_size, max_anomalies_ammout, all_turfs_for_spawn_len) + if(!max_anomalies_ammout) + max_anomalies_ammout = all_turfs_for_spawn_len + max_anomalies_ammout /= max_anomaly_size + return max_anomalies_ammout + +/proc/calculate_result_anomalies_ammout(min_anomaly_size, max_anomaly_size, min_anomalies_ammout, max_anomalies_ammout, result_anomalies_ammout, all_turfs_for_spawn_len) + result_anomalies_ammout = rand(min_anomalies_ammout, max_anomalies_ammout) + if(result_anomalies_ammout * max_anomaly_size > all_turfs_for_spawn_len) + result_anomalies_ammout = all_turfs_for_spawn_len + result_anomalies_ammout /= max_anomaly_size + result_anomalies_ammout = Round(result_anomalies_ammout) + return result_anomalies_ammout diff --git a/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/flying.dm b/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/flying.dm index e1e904a9b5885..8b2f17b0b26f6 100644 --- a/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/flying.dm +++ b/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/flying.dm @@ -1,5 +1,3 @@ -/* -Вне ротации /obj/overmap/visitable/sector/exoplanet/flying name = "flying exoplanet" desc = "Flying around a certain center of the island." @@ -7,20 +5,88 @@ rock_colors = list(COLOR_WHITE) can_spawn_anomalies = TRUE anomalies_type = list( + /obj/anomaly/tramplin = 2, + /obj/anomaly/rvach/three_and_three = 1 + ) + possible_themes = list( + /datum/exoplanet_theme = 100 ) min_anomaly_size = 1 max_anomaly_size = 9 - min_anomalies_ammout = 40 - max_anomalies_ammout = 100 + min_anomalies_ammout = 400 + max_anomalies_ammout = 500 planetary_area = /area/exoplanet/flying map_generators = list(/datum/random_map/noise/exoplanet/flying) - ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER|RUIN_HOT_ANOMALIES + ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER|RUIN_HOT_ANOMALIES|RUIN_ELECTRA_ANOMALIES surface_color = "#a46610" water_color = "#ffffff" + daycycle_range = list(2 HOURS, 3 HOURS) + daycycle = FALSE habitability_weight = HABITABILITY_EXTREME has_trees = FALSE flora_diversity = 0 +//Генерируем бэкграунд для островов. TODO: нарисовать очень красивый бэкграунд +/obj/overmap/visitable/sector/exoplanet/flying/build_level() + .=..() + var/turf/any_turf + for(var/turf/turfs in planetary_area) + any_turf = turfs + break + var/planet_z = get_z(any_turf) + var/datum/event/change_z_skybox = new /datum/event/change_z_skybox(new /datum/event_meta(EVENT_LEVEL_MAJOR)) + change_z_skybox.affecting_z = list(planet_z) + change_z_skybox.setup('mods/anomaly/icons/planet_backgrounds.dmi', "flying") + SSskybox.generate_skybox(planet_z) + + + +/obj/overmap/visitable/sector/exoplanet/flying/generate_map() + .=..() + //Находим Z планеты, создаём с ним список + var/turf/any_turf + for(var/turf/turfs in planetary_area) + any_turf = turfs + break + var/list/input_z = list() + input_z += get_z(any_turf) + + //Создаём список возможных для спавна островов путём сбора "наследников" + var/list/islands_list = list() + for (var/T in subtypesof(/datum/map_template/ruin/flying_island)) + var/datum/map_template/ruin/exoplanet/ruin = T + islands_list += new ruin + //Выполняем спавн используя существующий код спавна диреликтов на планете + var/list/list_of_turfs = list() + for(var/turf/picked_turf in planetary_area) + LAZYADD(list_of_turfs, picked_turf) + var/islands_spawn_ammount = rand(25,45) + //После того как мы определились с количеством островов, приступаем к спавну + var/failures_ammount = 0 + for(var/i = 0, i < islands_spawn_ammount) + //Выбираем случайный турф + var/turf/current_turf = pick(list_of_turfs) //Выбираем турф для спавна + var/datum/map_template/ruin = pick(islands_list) //Выбираем остров + var/failure = FALSE + for(var/turf/picked_turf in ruin.get_affected_turfs(current_turf, 1)) + if(istype(picked_turf, /turf/simulated/floor/exoplanet/grass)) + //При попытке размещения диреликта, мы наехали на другой остров + failure = TRUE + break + if(!failure) //Все турфы на которых мы хотим разместить остров - не являются островом + i++ + var/list/turfs_for_clean = ruin.get_affected_turfs(current_turf, 1) + //Удаляем заменённые турфы из списка турфов, т.к проверять их уже нет смысла + for(var/turf/cleared_turf in turfs_for_clean) + LAZYREMOVE(list_of_turfs, cleared_turf) + load_ruin(current_turf, pick(islands_list)) //Размещаем остров + else + failures_ammount++ + LAZYREMOVE(list_of_turfs, current_turf) + if(failures_ammount == 100) //Как и в генераторе аномок, аварийно выйдет из цикла при слишком большом количестве "ошибок" + break + + /obj/overmap/visitable/sector/exoplanet/flying/get_atmosphere_color() var/air_color = ..() @@ -29,19 +95,17 @@ /obj/overmap/visitable/sector/exoplanet/flying/generate_atmosphere() ..() - var/datum/species/H = all_species[SPECIES_HUMAN] - var/generator/new_temp = generator("num", H.cold_level_1 - 50, H.cold_level_3, NORMAL_RAND) - atmosphere.temperature = new_temp.Rand() + atmosphere = new + atmosphere.temperature = rand(290, 330) atmosphere.update_values() + var/good_gas = list(GAS_OXYGEN = MOLES_O2STANDARD, GAS_NITROGEN = MOLES_N2STANDARD) + atmosphere.gas = good_gas /datum/random_map/noise/exoplanet/flying - descriptor = "ice exoplanet" + descriptor = "flying islands" smoothing_iterations = 5 - land_type = /turf/simulated/floor/exoplanet/flying_rocks - water_type = /turf/simulated/floor/exoplanet/clouds - water_level_min = 5 - water_level_max = 6 + land_type = /turf/simulated/floor/exoplanet/clouds fauna_prob = 0 flora_prob = 0 large_flora_prob = 0 @@ -49,7 +113,7 @@ /area/exoplanet/flying ambience = list('sound/effects/wind/tundra0.ogg','sound/effects/wind/tundra1.ogg','sound/effects/wind/tundra2.ogg','sound/effects/wind/spooky0.ogg','sound/effects/wind/spooky1.ogg') - base_turf = /turf/simulated/floor/exoplanet/flying_rocks + base_turf = /turf/simulated/floor/exoplanet/clouds //Облачка @@ -58,13 +122,26 @@ icon_state = "clouds" icon = 'mods/anomaly/icons/planets.dmi' color = COLOR_WHITE - //TRUE - облака раскрыты (видно что внизу), FALSE - не видно - var/opened = FALSE //Обрабатывает раскрытие + var/opened = FALSE var/started_openning = FALSE /turf/simulated/floor/exoplanet/clouds/Entered(atom/movable/AM) ..() + if(locate(/obj/structure/catwalk) in src) + return + if(!isitem(AM) && !isliving(AM)) + return + if(isliving(AM)) + var/mob/living/L = AM + //Летающие существа не тревожат облака + if (L.can_overcome_gravity()) + return + //Артефакты с этим эффектом заставят облака игнорировать существо + var/list/result_effects = calculate_artefact_reaction(L, "Падение с высоты") + if(result_effects) + if(result_effects.Find("Защищает от падения")) + return if(!opened && started_openning) return if(!opened && !started_openning) @@ -74,26 +151,74 @@ check_clouds_turf(AM) /turf/simulated/floor/exoplanet/clouds/proc/open_clouds() - flick("clouds_open", src) - icon_state = "clouds_clean" + flick("clouds_opening", src) + icon_state = "clouds_open" + sleep(2.5 SECONDS) + //Заставляем облака показывать задник TODO: нарисовать красивый бэк с островами для этой планеты + appearance = SSskybox.space_appearance_cache[(((x + y) ^ ~(x * y) + z) % 25) + 1] opened = TRUE + check_clouds_turf() addtimer(new Callback(src, PROC_REF(close_clouds)), 10 SECONDS) /turf/simulated/floor/exoplanet/clouds/proc/close_clouds() - flick("clouds_closed", src) + flick("clouds_closing", src) icon_state = "clouds" + appearance = initial(appearance) opened = FALSE /turf/simulated/floor/exoplanet/clouds/proc/check_clouds_turf(atom/movable/AM) if(!AM) - for(var/atom/target in src) - visible_message("[target] со свистом улетает вниз", null, 7) - qdel(target) - -//Пол каменный -/turf/simulated/floor/exoplanet/flying_rocks - name = "flying_rock" - icon_state = "flying_rock" - icon = 'mods/anomaly/icons/flying_floor.dmi' - color = COLOR_BROWN -*/ + for(var/atom/movable/movable_atom in src) + //Если есть мостики - ничего не делаем + if(locate(/obj/structure/catwalk) in src) + return + //Если это живое существо, просчитаем дополнительно + if(isliving(AM)) + var/mob/living/L = AM + //Если существо летает - ему ничего не будет + if (L.can_overcome_gravity()) + return + //Артефакты с этим эффектом не позволят существу провалится вниз + var/list/result_effects = calculate_artefact_reaction(L, "Падение с высоты") + if(result_effects) + if(result_effects.Find("Защищает от падения")) + return + if(!movable_atom.anchored) + visible_message("[movable_atom] со свистом улетает вниз", null, 7) + //Живое существо отправляется на рандомный турф на островах + if(isliving(movable_atom)) + move_to_closest_safe_turf(movable_atom) + return + //Всё что не живое существо - исчезает + qdel(movable_atom) + +///Задача функции - телепортировать игрока на любой турф который Не является летающими остравами +/proc/move_to_closest_safe_turf(atom/movable/input_atom, bad_turf = /turf/simulated/floor/exoplanet/clouds) + if(!input_atom) + return FALSE + var/list/list_of_turfs_in_area = get_area_turfs(get_area(input_atom)) + while(LAZYLEN(list_of_turfs_in_area)) + var/turf/current_turf = pick(list_of_turfs_in_area) + if(!istype(current_turf, bad_turf)) + //Обьект/предмет/Моба вышвыривает на землю. СЖАЛИЛИСЬ. + input_atom.forceMove(current_turf) + if(isliving(input_atom)) + var/mob/living/target = input_atom + var/damage = 5 + target.Weaken(5) + target.apply_damage(damage, DAMAGE_BRUTE, BP_HEAD) + target.apply_damage(damage, DAMAGE_BRUTE, BP_CHEST) + target.apply_damage(damage, DAMAGE_BRUTE, BP_GROIN) + target.apply_damage(damage, DAMAGE_BRUTE, BP_L_LEG) + target.apply_damage(damage, DAMAGE_BRUTE, BP_R_LEG) + target.apply_damage(damage, DAMAGE_BRUTE, BP_L_FOOT) + target.apply_damage(damage, DAMAGE_BRUTE, BP_R_FOOT) + target.apply_damage(damage, DAMAGE_BRUTE, BP_L_ARM) + target.apply_damage(damage, DAMAGE_BRUTE, BP_R_ARM) + target.apply_damage(damage, DAMAGE_BRUTE, BP_L_HAND) + target.apply_damage(damage, DAMAGE_BRUTE, BP_R_HAND) + return + else + LAZYREMOVE(list_of_turfs_in_area, current_turf) + //Если игрока не скинуло на новый турф - что-то не так. + to_chat(input_atom, SPAN_BAD("Что-то не так....")) diff --git a/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/ice.dm b/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/ice.dm index fdadecea5d53f..6581258fb15d0 100644 --- a/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/ice.dm +++ b/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/ice.dm @@ -1,20 +1,27 @@ /obj/overmap/visitable/sector/exoplanet/ice name = "ice exoplanet" - desc = "A distant, abandoned and cold world, rich in artifacts and anomalous activity." + desc = "A distant, abandoned and cold world, rich in artefacts and anomalous activity." color = "#ebe3e3" rock_colors = list(COLOR_WHITE) can_spawn_anomalies = TRUE + monitor_effect_type = /obj/monitor_effect_triger/snow anomalies_type = list( - /obj/anomaly/electra/three_and_three = 5, - /obj/anomaly/electra/three_and_three/tesla = 2, - /obj/anomaly/electra/three_and_three/tesla_second = 1, + /obj/anomaly/electra/three_and_three = 2, + /obj/anomaly/electra/three_and_three/tesla = 7, + /obj/anomaly/electra/three_and_three/tesla_second = 6, /obj/anomaly/cooler/two_and_two = 3, /obj/anomaly/cooler/three_and_three = 3 ) + possible_themes = list( + /datum/exoplanet_theme = 45, + /datum/exoplanet_theme/radiation_bombing = 10, + /datum/exoplanet_theme/ruined_city = 5, + /datum/exoplanet_theme/robotic_guardians = 10 + ) min_anomaly_size = 4 max_anomaly_size = 9 - min_anomalies_ammout = 250 - max_anomalies_ammout = 400 + min_anomalies_ammout = 600 + max_anomalies_ammout = 800 planetary_area = /area/exoplanet/ice map_generators = list(/datum/random_map/automata/cave_system/mountains/ice, /datum/random_map/noise/exoplanet/ice) ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER|RUIN_HOT_ANOMALIES @@ -41,6 +48,8 @@ icon_state = "ice_wall" icon = 'mods/anomaly/icons/planets.dmi' color = COLOR_WHITE + blocks_air = FALSE + initial_gas = list(GAS_OXYGEN = MOLES_O2STANDARD, GAS_NITROGEN = MOLES_N2STANDARD) /turf/simulated/mineral/random/ice name = "Ice wall" @@ -48,10 +57,30 @@ icon = 'mods/anomaly/icons/planets.dmi' color = COLOR_WHITE +/obj/overmap/visitable/sector/exoplanet/ice/generate_map() + .=..() + //После создания карты, разместим камушки + var/list/list_of_turfs = get_area_turfs(planetary_area) + //Соберём все подходящие для нас турфы льда + for(var/turf/picked_turf in list_of_turfs) + if(density) + LAZYREMOVE(list_of_turfs, picked_turf) + else if(!istype(picked_turf, /turf/simulated/floor/exoplanet/ice)) + LAZYREMOVE(list_of_turfs, picked_turf) + var/ice_block_ammout = rand(500, 1000) + //Спавним камушки на льду + while(ice_block_ammout > 0) + var/turf/current_turf = pick(list_of_turfs) + new /obj/structure/ice_rock(current_turf) + LAZYREMOVE(list_of_turfs, current_turf) + if(!LAZYLEN(list_of_turfs)) + ice_block_ammout = 0 + ice_block_ammout-- + + /obj/overmap/visitable/sector/exoplanet/ice/generate_atmosphere() ..() - var/datum/species/H = all_species[SPECIES_HUMAN] - var/generator/new_temp = generator("num", H.cold_level_1 - 50, H.cold_level_3, NORMAL_RAND) + var/generator/new_temp = generator("num", 273, 300, NORMAL_RAND) atmosphere.temperature = new_temp.Rand() atmosphere.update_values() @@ -113,3 +142,113 @@ if(archaeo_overlay) AddOverlays(archaeo_overlay) + + +//СКАЛОЛАЗАНЬЕ +/turf/simulated/mineral/ice/examine(mob/user, distance, infix, suffix) + . = ..() + to_chat(user, SPAN_GOOD("Шагните на скалу, чтоб попытаться взабраться на неё.")) + +/turf/simulated/mineral/ice/CanPass(atom/movable/mover, turf/target, height, air_group) + if(istype(mover, /mob/living/carbon/human)) //Если пытается шагнуть человек - он может взабраться на скалу + if(!istype(mover.loc, /turf/simulated/mineral/ice)) + var/mob/living/carbon/human/user = mover + if(user.stamina < 60) + to_chat(mover, SPAN_BAD("Я слишком устал!")) + return + visible_message("[user] начинает взбираться вверх по склону.", "Вы слышите как кто-то залезает вверх по склону.", 5) + if(do_after(user, (15 SECONDS - (2 SECONDS *user.get_skill_value(SKILL_HAULING))))) + //Помощь друга даёт 25 процентов на успех и не даёт пораниться при падении + //Макс бонус от навыка составит 50 процентов + //Бонус от кирки при подьёме составит 25 процентов + var/helper_chance = 0 + var/pickaxe_chance = 0 + for(var/mob/living/carbon/human/helper in src) + if(helper.a_intent == I_HELP && turn(user.dir, 180) == helper.dir) //Лезущий и помощник должны смотреть друг другу в лицо + helper_chance = 25 + to_chat(user, SPAN_GOOD("[helper] помогает вам взобраться на скалу.")) + to_chat(helper, SPAN_GOOD("Вы помогаете [user] взобраться на скалу.")) + break //Помощник найден + if(user.IsHolding(/obj/item/pickaxe)) + to_chat(user, SPAN_NOTICE("Вам куда легче взбираться вверх с киркой.")) + pickaxe_chance = 25 + var/success_chance = (10 * user.get_skill_value(SKILL_HAULING)) + helper_chance + pickaxe_chance //Максимально - 100 процентов + if(prob(success_chance)) + user.forceMove(get_turf(src)) + to_chat(user, SPAN_GOOD("Вы успешно взбираетесь на гору.")) + else + var/list/result_effects = calculate_artefact_reaction(user, "Падение с высоты") + if(result_effects) + if(result_effects.Find("Защищает от падения")) + to_chat(user, SPAN_GOOD("Вы срываетесь вниз, но что-то ловит вас прямо у земли, оберегая от повреждений.")) + return + if(!helper_chance) //Нам никто не помог + for(var/picked_organ in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT)) + user.apply_damage(2.5, DAMAGE_BRUTE, picked_organ, used_weapon="Gravitation") + user.adjust_stamina(-50) + to_chat(user, SPAN_BAD("Вы срываетесь вниз, ударяясь в процессе.")) + else + user.adjust_stamina(-50) + to_chat(user, SPAN_COLOR("#ffa500","Вы срываетесь вниз, но стоящий сверху удерживает вас, предотвращая ранения.")) + + else + mover.forceMove(get_turf(src)) + . = ..() + +/turf/simulated/mineral/ice/Exit(O, newloc) + if(istype(O, /mob/living/carbon/human) && !istype(newloc,/turf/simulated/mineral/ice)) //Человек пытается слезть с скалы + var/mob/living/carbon/human/user = O + if(do_after(user, (15 SECONDS - (2 SECONDS * user.get_skill_value(SKILL_HAULING))))) //Чем лучше атлетика, тем быстрее спуск + //Помощь друга даёт 25 процентов на успех и не даёт пораниться при падении + //Макс бонус от навыка составит 50 процентов + //Бонус от кирки при подьёме составит 25 процентов + var/helper_chance = 0 + var/pickaxe_chance = 0 + for(var/mob/living/carbon/human/helper in newloc) + if(helper.a_intent == I_HELP && turn(user.dir, 180) == helper.dir) //Лезущий и помощник должны смотреть друг другу в лицо + helper_chance = 25 + to_chat(user, SPAN_GOOD("[helper] помогает вам взобраться на скалу.")) + to_chat(helper, SPAN_GOOD("Вы помогаете [user] взобраться на скалу.")) + break //Помощник найден + if(user.IsHolding(/obj/item/pickaxe)) + to_chat(user, SPAN_NOTICE("Вам куда легче взбираться вверх с киркой.")) + pickaxe_chance = 25 + var/success_chance = (10 * user.get_skill_value(SKILL_HAULING)) + helper_chance + pickaxe_chance //Максимально - 100 процентов + if(prob(success_chance)) + to_chat(user, SPAN_GOOD("Вы аккуратно слезаете со скалы.")) + user.forceMove(newloc) + else + var/list/result_effects = calculate_artefact_reaction(user, "Падение с высоты") + if(result_effects) + if(result_effects.Find("Защищает от падения")) + to_chat(user, SPAN_GOOD("Вы срываетесь вниз, но что-то ловит вас прямо у земли, оберегая от повреждений.")) + return + if(!helper_chance) + to_chat(user, SPAN_BAD("Вы срываетесь вниз со скалы.")) + for(var/picked_organ in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT)) + user.apply_damage(5, DAMAGE_BRUTE, picked_organ, used_weapon="Gravitation") + user.adjust_stamina(-100) + user.forceMove(newloc) + else + to_chat(user, SPAN_COLOR("#ffa500", "Вы срываетесь вниз со скалы, но вас ловят предотвращая ранения.")) + user.adjust_stamina(-100) + user.forceMove(newloc) + else + return FALSE + . = ..() + +/turf/simulated/mineral/ice/Bumped(AM) + return + +//Большие ледяные камни, красиво +/obj/structure/ice_rock + name = "ice rock" + desc = "A large block of ice, the edges of which can easily cut you. " + icon = 'mods/anomaly/icons/icerocks.dmi' + icon_state = "rock_1" + anchored = TRUE + var/icon_state_list = list("rock_1", "rock_2", "rock_3") + +/obj/structure/ice_rock/Initialize() + .=..() + icon_state = pick(icon_state_list) diff --git a/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/sargas.dm b/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/sargas.dm new file mode 100644 index 0000000000000..ee713dee2d4fc --- /dev/null +++ b/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/sargas.dm @@ -0,0 +1,64 @@ +/* Не доделан +/obj/overmap/visitable/sector/exoplanet/swamp + name = "Sargassov swamp" + desc = "Wild and mysterious planet, covered in vast swamplands and impenetrable swamps that provide both spectacular and dangerous terrain. Its unique ecosystem includes a variety of species of flora and fauna that have adapted to the conditions of such an environment." + color = "#054515" + rock_colors = list(COLOR_WHITE) + can_spawn_anomalies = TRUE + monitor_effect_type = /obj/monitor_effect_triger/swamp + anomalies_type = list() + min_anomaly_size = 4 + max_anomaly_size = 9 + min_anomalies_ammout = 250 + max_anomalies_ammout = 400 + planetary_area = /area/exoplanet/swamp + map_generators = list(/datum/random_map/noise/exoplanet/swamp) + ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER|RUIN_HOT_ANOMALIES + surface_color = "#ffffff" + water_color = "#263908" + habitability_weight = HABITABILITY_EXTREME + has_trees = FALSE + flora_diversity = 0 + + +/obj/overmap/visitable/sector/exoplanet/swamp/get_atmosphere_color() + var/air_color = ..() + return MixColors(COLOR_GRAY20, air_color) + + + +/obj/overmap/visitable/sector/exoplanet/swamp/generate_atmosphere() + ..() + var/generator/new_temp = generator("num", 250, 300, NORMAL_RAND) + atmosphere.temperature = new_temp.Rand() + atmosphere.update_values() + + +/datum/random_map/noise/exoplanet/swamp + descriptor = "ice exoplanet" + smoothing_iterations = 5 + land_type = /turf/simulated/floor/exoplanet/grass + water_type = /turf/simulated/floor/exoplanet/swamp + water_level_min = 5 + water_level_max = 6 + fauna_prob = 0 + flora_prob = 0 + large_flora_prob = 0 + + +/area/exoplanet/swamp + ambience = list('sound/effects/wind/tundra0.ogg','sound/effects/wind/tundra1.ogg','sound/effects/wind/tundra2.ogg','sound/effects/wind/spooky0.ogg','sound/effects/wind/spooky1.ogg') + base_turf = /turf/simulated/floor/exoplanet/grass + +/turf/simulated/floor/exoplanet/swamp + name = "блядская вода" + desc = "В ней немного тонешь, хуя" + +/turf/simulated/floor/exoplanet/swamp/medium + name = "Средняя вода" + desc = "По пузо" + +/turf/simulated/floor/exoplanet/swamp/deep + name = "Глубокая вода" + desc = "По горло" +*/ diff --git a/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/vulcanic.dm b/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/vulcanic.dm index 8c8c74d5202e2..57875963fdc4d 100644 --- a/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/vulcanic.dm +++ b/mods/anomaly/code/spawn_anomalies_protocol/planet_spawn_types/vulcanic.dm @@ -1,6 +1,4 @@ -//Данный код отвечает за размещение аномалий по всей планете. /obj/overmap/visitable/sector/exoplanet/volcanic - ///Спавнятся ли на подобном типе планет аномалии can_spawn_anomalies = TRUE anomalies_type = list( /obj/anomaly/zjarka = 4, diff --git a/mods/anomaly/code/spawn_anomalies_protocol/spawn_anomaly_with_big_artefact.dm b/mods/anomaly/code/spawn_anomalies_protocol/spawn_anomaly_with_big_artefact.dm index 6e398fa8c61ad..a13b4fa85bec9 100644 --- a/mods/anomaly/code/spawn_anomalies_protocol/spawn_anomaly_with_big_artefact.dm +++ b/mods/anomaly/code/spawn_anomalies_protocol/spawn_anomaly_with_big_artefact.dm @@ -12,7 +12,7 @@ var/min_artefacts_ammount = 1 var/max_artefacts_ammount = 2 ///Область в которой будет спавнить аномалии - var/range_spawn = 5 + var/range_spawn = 6 //Лист возможных аномалий для спавна var/list/possible_anomalies = list( /obj/anomaly/electra/three_and_three = 5, @@ -23,12 +23,14 @@ /obj/anomaly/rvach/three_and_three = 4 ) +/* +//Выведено из ротации, большой артефакт ничего не спавнит /obj/machinery/artifact/Initialize() . = ..() - if(icon_num == 0 || icon_num == 1 || icon_num == 7 || icon_num == 11 || icon_num == 12) + if(icon_num == 0 || icon_num == 1 || icon_num == 7 || icon_num == 11) if(can_born_anomalies) born_anomalies() - +*/ /obj/machinery/artifact/no_anomalies can_born_anomalies = FALSE diff --git a/mods/anomaly/code/spawn_anomalies_protocol/spawn_on_planet.dm b/mods/anomaly/code/spawn_anomalies_protocol/spawn_on_planet.dm index ff00342328a8b..57650beba3211 100644 --- a/mods/anomaly/code/spawn_anomalies_protocol/spawn_on_planet.dm +++ b/mods/anomaly/code/spawn_anomalies_protocol/spawn_on_planet.dm @@ -1,9 +1,33 @@ +/datum/map/build_exoplanets() + //Игра заспавнит 1 обычную планету и 1 аномальную + var/list/anomaly_planets_list = list( + /obj/overmap/visitable/sector/exoplanet/ice, + /obj/overmap/visitable/sector/exoplanet/volcanic, + /obj/overmap/visitable/sector/exoplanet/flying + ) + var/list/all_planets_list = subtypesof(/obj/overmap/visitable/sector/exoplanet) + LAZYREMOVE(all_planets_list, anomaly_planets_list) + //Я не придумал как обьяснять игре какая планета обычная, а какая аномальная без + //заранее подготовленных списков. Увы. + if(!use_overmap) + return + + for(var/i = 0, i < num_exoplanets, i++) + var/normal_planet_type = pick(all_planets_list) + var/obj/overmap/visitable/sector/exoplanet/new_planet = new normal_planet_type(null, world.maxx, world.maxy) + new_planet.build_level() + + var/anomaly_planet_type = pick(anomaly_planets_list) + var/obj/overmap/visitable/sector/exoplanet/anomaly_new_planet = new anomaly_planet_type(null, world.maxx, world.maxy) + anomaly_new_planet.build_level() + //Данный код отвечает за размещение аномалий по всей планете. /obj/overmap/visitable/sector/exoplanet ///Спавнятся ли на подобном типе планет аномалии var/can_spawn_anomalies = FALSE var/list/anomalies_type = list( ) + var/obj/monitor_effect_triger/monitor_effect_type var/min_anomaly_size = 1 var/max_anomaly_size = 3 ///Минимальное количество заспавненных артов @@ -53,3 +77,30 @@ else if(inputed_turf.y > y_limit) return FALSE return TRUE + +/obj/overmap/visitable/sector/exoplanet/proc/generate_monitor_effects() + set background = 1 + for(var/turf/choosed_turf in planetary_area) + new monitor_effect_type(choosed_turf) + + + + +///Задача ивента - сменить скайбокс Z уровня любой ценой +/datum/event/change_z_skybox + startWhen = 30 // About one minute early warning + endWhen = 999 HOURS // Adjusted automatically in tick() + has_skybox_image = TRUE + var/skybox_type = 'icons/skybox/rockbox.dmi' + var/skybox_icon_state = "rockbox" + +/datum/event/change_z_skybox/get_skybox_image() + var/image/res = overlay_image(skybox_type, skybox_icon_state, COLOR_ASTEROID_ROCK, RESET_COLOR) + res.blend_mode = BLEND_OVERLAY + return res + +/datum/event/change_z_skybox/setup(input_skybox_type, input_skybox_icon_state) + if(input_skybox_type) + skybox_type = input_skybox_type + if(input_skybox_icon_state) + skybox_icon_state = input_skybox_icon_state diff --git a/mods/anomaly/icons/artifacts.dmi b/mods/anomaly/icons/artifacts.dmi index bb20006db576f..85133c469bef2 100644 Binary files a/mods/anomaly/icons/artifacts.dmi and b/mods/anomaly/icons/artifacts.dmi differ diff --git a/mods/anomaly/icons/bolts.dmi b/mods/anomaly/icons/bolts.dmi index 3a28e56453f50..47e2f9056f7b4 100644 Binary files a/mods/anomaly/icons/bolts.dmi and b/mods/anomaly/icons/bolts.dmi differ diff --git a/mods/anomaly/icons/deployer.dmi b/mods/anomaly/icons/deployer.dmi new file mode 100644 index 0000000000000..810cf58cc8cc2 Binary files /dev/null and b/mods/anomaly/icons/deployer.dmi differ diff --git a/mods/anomaly/icons/detection_icon.dmi b/mods/anomaly/icons/detection_icon.dmi new file mode 100644 index 0000000000000..2c0dd4cd7da1c Binary files /dev/null and b/mods/anomaly/icons/detection_icon.dmi differ diff --git a/mods/anomaly/icons/flying_floor.dmi b/mods/anomaly/icons/flying_floor.dmi deleted file mode 100644 index 72b3c44f54dfe..0000000000000 Binary files a/mods/anomaly/icons/flying_floor.dmi and /dev/null differ diff --git a/mods/anomaly/icons/icerocks.dmi b/mods/anomaly/icons/icerocks.dmi new file mode 100644 index 0000000000000..e5f68fc4885e9 Binary files /dev/null and b/mods/anomaly/icons/icerocks.dmi differ diff --git a/mods/anomaly/icons/planet_backgrounds.dmi b/mods/anomaly/icons/planet_backgrounds.dmi new file mode 100644 index 0000000000000..ee3fd9d21fc14 Binary files /dev/null and b/mods/anomaly/icons/planet_backgrounds.dmi differ diff --git a/mods/anomaly/icons/planets.dmi b/mods/anomaly/icons/planets.dmi index a88b3c0369a26..d2af2fdfb52a3 100644 Binary files a/mods/anomaly/icons/planets.dmi and b/mods/anomaly/icons/planets.dmi differ diff --git a/mods/anomaly/icons/snow_screen.dmi b/mods/anomaly/icons/snow_screen.dmi new file mode 100644 index 0000000000000..7754db7476bca Binary files /dev/null and b/mods/anomaly/icons/snow_screen.dmi differ diff --git a/mods/anomaly/icons/weather_effects.dmi b/mods/anomaly/icons/weather_effects.dmi new file mode 100644 index 0000000000000..00083c464a24f Binary files /dev/null and b/mods/anomaly/icons/weather_effects.dmi differ diff --git a/mods/anomaly/maps/flying_islands/flying_island.dm b/mods/anomaly/maps/flying_islands/flying_island.dm new file mode 100644 index 0000000000000..1a3463f8cb39b --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island.dm @@ -0,0 +1,2 @@ +/datum/map_template/ruin/flying_island + mappaths = list('mods/anomaly/maps/flying_islands/flying_island_ball.dmm') diff --git a/mods/anomaly/maps/flying_islands/flying_island_2.dm b/mods/anomaly/maps/flying_islands/flying_island_2.dm new file mode 100644 index 0000000000000..cae5d6a02ff35 --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island_2.dm @@ -0,0 +1,5 @@ +/datum/map_template/ruin/flying_island/second + mappaths = list('mods/anomaly/maps/flying_islands/flying_island_2.dmm') + name = "flying island second" + id = "flying_island_second" + spawn_cost = 1 diff --git a/mods/anomaly/maps/flying_islands/flying_island_2.dmm b/mods/anomaly/maps/flying_islands/flying_island_2.dmm new file mode 100644 index 0000000000000..9c2f3e3c3aa0e --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island_2.dmm @@ -0,0 +1,1900 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"fr" = ( +/turf/simulated/floor/exoplanet/grass, +/area/template_noop) +"HI" = ( +/turf/template_noop, +/area/template_noop) + +(1,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(2,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(3,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(4,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(5,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(6,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(7,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(8,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(9,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(10,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(11,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(12,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(13,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +HI +"} +(14,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +fr +fr +fr +fr +fr +HI +"} +(15,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +fr +fr +fr +fr +fr +fr +fr +HI +"} +(16,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +"} +(17,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +"} +(18,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +"} +(19,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +"} +(20,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +"} +(21,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +"} +(22,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +"} +(23,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +"} +(24,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +"} +(25,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +"} +(26,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(27,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(28,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(29,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(30,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(31,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(32,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(33,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(34,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(35,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(36,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(37,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(38,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(39,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(40,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(41,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(42,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(43,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(44,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} diff --git a/mods/anomaly/maps/flying_islands/flying_island_3.dm b/mods/anomaly/maps/flying_islands/flying_island_3.dm new file mode 100644 index 0000000000000..baa464fbaca0a --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island_3.dm @@ -0,0 +1,5 @@ +/datum/map_template/ruin/flying_island/third + mappaths = list('mods/anomaly/maps/flying_islands/flying_island_3.dmm') + name = "flying island third" + id = "flying_island_third" + spawn_cost = 1 diff --git a/mods/anomaly/maps/flying_islands/flying_island_3.dmm b/mods/anomaly/maps/flying_islands/flying_island_3.dmm new file mode 100644 index 0000000000000..56dbcbc8e05f5 --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island_3.dmm @@ -0,0 +1,1900 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"fr" = ( +/turf/simulated/floor/exoplanet/grass, +/area/template_noop) +"HI" = ( +/turf/template_noop, +/area/template_noop) + +(1,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(2,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(3,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(4,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(5,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(6,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(7,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(8,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +HI +HI +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(9,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(10,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(11,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(12,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(13,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(14,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(15,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(16,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(17,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(18,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(19,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(20,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +"} +(21,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +"} +(22,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +"} +(23,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +"} +(24,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +"} +(25,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +"} +(26,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +"} +(27,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +"} +(28,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +"} +(29,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +fr +HI +HI +HI +"} +(30,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(31,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(32,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +"} +(33,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +"} +(34,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(35,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(36,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(37,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +HI +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(38,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +HI +HI +HI +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(39,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(40,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(41,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(42,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(43,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(44,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} diff --git a/mods/anomaly/maps/flying_islands/flying_island_4.dm b/mods/anomaly/maps/flying_islands/flying_island_4.dm new file mode 100644 index 0000000000000..b63bf08b40bbb --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island_4.dm @@ -0,0 +1,5 @@ +/datum/map_template/ruin/flying_island/fourth + mappaths = list('mods/anomaly/maps/flying_islands/flying_island_ball.dmm') + name = "flying island ball" + id = "flying_island_ball" + spawn_cost = 1 diff --git a/mods/anomaly/maps/flying_islands/flying_island_4.dmm b/mods/anomaly/maps/flying_islands/flying_island_4.dmm new file mode 100644 index 0000000000000..aff98681813c7 --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island_4.dmm @@ -0,0 +1,1900 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"fr" = ( +/turf/simulated/floor/exoplanet/grass, +/area/template_noop) +"HI" = ( +/turf/template_noop, +/area/template_noop) + +(1,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(2,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(3,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(4,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +HI +HI +HI +HI +HI +"} +(5,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +fr +fr +fr +fr +fr +HI +HI +HI +"} +(6,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +"} +(7,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +"} +(8,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +"} +(9,1,1) = {" +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +"} +(10,1,1) = {" +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +"} +(11,1,1) = {" +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +"} +(12,1,1) = {" +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(13,1,1) = {" +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(14,1,1) = {" +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(15,1,1) = {" +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(16,1,1) = {" +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(17,1,1) = {" +HI +HI +fr +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(18,1,1) = {" +HI +fr +fr +fr +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(19,1,1) = {" +HI +fr +fr +fr +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(20,1,1) = {" +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(21,1,1) = {" +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(22,1,1) = {" +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +fr +fr +fr +fr +fr +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +"} +(23,1,1) = {" +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +"} +(24,1,1) = {" +HI +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +fr +fr +fr +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +"} +(25,1,1) = {" +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +fr +fr +fr +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +"} +(26,1,1) = {" +HI +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +fr +fr +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(27,1,1) = {" +HI +fr +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(28,1,1) = {" +HI +fr +fr +fr +fr +fr +fr +fr +HI +HI +HI +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +"} +(29,1,1) = {" +HI +fr +fr +HI +fr +fr +fr +fr +HI +HI +HI +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +fr +fr +fr +HI +HI +HI +HI +HI +HI +HI +"} +(30,1,1) = {" +HI +fr +HI +HI +HI +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +fr +fr +HI +HI +HI +HI +HI +HI +HI +"} +(31,1,1) = {" +HI +HI +HI +HI +HI +fr +fr +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(32,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(33,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(34,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(35,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(36,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(37,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(38,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(39,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(40,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(41,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(42,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(43,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} +(44,1,1) = {" +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +HI +"} diff --git a/mods/anomaly/maps/flying_islands/flying_island_5.dm b/mods/anomaly/maps/flying_islands/flying_island_5.dm new file mode 100644 index 0000000000000..9fdbe53c3da69 --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island_5.dm @@ -0,0 +1,5 @@ +/datum/map_template/ruin/flying_island/fifth + mappaths = list('mods/anomaly/maps/flying_islands/flying_island_ball.dmm') + name = "flying island ball" + id = "flying_island_ball" + spawn_cost = 1 diff --git a/mods/anomaly/maps/flying_islands/flying_island_5.dmm b/mods/anomaly/maps/flying_islands/flying_island_5.dmm new file mode 100644 index 0000000000000..395f2cfdcaaad --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island_5.dmm @@ -0,0 +1,140 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"c" = ( +/turf/simulated/floor/exoplanet/grass, +/area/template_noop) + +(1,1,1) = {" +a +a +c +c +a +a +c +a +a +a +"} +(2,1,1) = {" +a +c +c +c +c +c +c +c +c +a +"} +(3,1,1) = {" +a +a +c +c +c +c +c +c +c +a +"} +(4,1,1) = {" +a +a +a +c +c +c +c +c +c +c +"} +(5,1,1) = {" +c +a +a +a +c +c +a +c +c +c +"} +(6,1,1) = {" +c +c +a +a +a +a +a +a +a +a +"} +(7,1,1) = {" +c +c +c +c +a +a +a +a +a +a +"} +(8,1,1) = {" +a +c +c +c +c +c +a +a +a +a +"} +(9,1,1) = {" +a +c +c +c +c +c +c +a +a +a +"} +(10,1,1) = {" +a +a +c +c +c +c +c +c +c +a +"} +(11,1,1) = {" +a +a +a +a +a +c +c +c +c +a +"} diff --git a/mods/anomaly/maps/flying_islands/flying_island_ball.dm b/mods/anomaly/maps/flying_islands/flying_island_ball.dm new file mode 100644 index 0000000000000..1c88e7f3f2d5b --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island_ball.dm @@ -0,0 +1,5 @@ +/datum/map_template/ruin/flying_island/ball + mappaths = list('mods/anomaly/maps/flying_islands/flying_island_ball.dmm') + name = "flying island ball" + id = "flying_island_ball" + spawn_cost = 1 diff --git a/mods/anomaly/maps/flying_islands/flying_island_ball.dmm b/mods/anomaly/maps/flying_islands/flying_island_ball.dmm new file mode 100644 index 0000000000000..f05d40839e690 --- /dev/null +++ b/mods/anomaly/maps/flying_islands/flying_island_ball.dmm @@ -0,0 +1,140 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"c" = ( +/turf/simulated/floor/exoplanet/grass, +/area/template_noop) + +(1,1,1) = {" +a +a +a +a +a +a +a +a +a +a +"} +(2,1,1) = {" +a +a +c +c +c +c +c +c +a +a +"} +(3,1,1) = {" +a +c +c +c +c +c +c +c +c +a +"} +(4,1,1) = {" +a +c +c +c +c +c +c +c +c +a +"} +(5,1,1) = {" +a +c +c +c +c +c +c +c +c +a +"} +(6,1,1) = {" +a +c +c +c +c +c +c +c +c +a +"} +(7,1,1) = {" +a +c +c +c +c +c +c +c +c +a +"} +(8,1,1) = {" +a +c +c +c +c +c +c +c +c +a +"} +(9,1,1) = {" +a +c +c +c +c +c +c +c +c +a +"} +(10,1,1) = {" +a +a +c +c +c +c +c +c +a +a +"} +(11,1,1) = {" +a +a +a +a +a +a +a +a +a +a +"} diff --git a/mods/anomaly/sounds/snowstorm.ogg b/mods/anomaly/sounds/snowstorm.ogg new file mode 100644 index 0000000000000..63ead3e2c893a Binary files /dev/null and b/mods/anomaly/sounds/snowstorm.ogg differ diff --git a/mods/antagonists/code/mercenary.dm b/mods/antagonists/code/mercenary.dm index 4026b2f71744e..f9ade5c0d39eb 100644 --- a/mods/antagonists/code/mercenary.dm +++ b/mods/antagonists/code/mercenary.dm @@ -524,3 +524,113 @@ Used for quick dress-up. Also comes with several discount /obj/item/rig_module/vision, /obj/item/rig_module/cooling_unit ) + + +//droppod stuff + +/datum/map_template/ruin/antag_spawn/mercenary/New() + . = ..() + shuttles_to_initialise += list(/datum/shuttle/autodock/overmap/merc_drop_pod) + +/obj/overmap/visitable/sector/merc_base/New() + . = ..() + initial_generic_waypoints += list( + "nav_merc_pod_start" + ) + +/datum/shuttle/autodock/overmap/merc_drop_pod + name = "Cyclopes Droppod" + shuttle_area = list(/area/map_template/merc_shuttle/drop_pod) + dock_target = "merc_drop_pod" + current_location = "nav_merc_pod_start" + landmark_transition = "nav_transit_scavshuttle" + range = 1 + fuel_consumption = 4 + ceiling_type = /turf/simulated/floor/shuttle_ceiling + defer_initialisation = TRUE + mothershuttle = "Cyclopes" + +/obj/machinery/computer/shuttle_control/explore/merc_shuttle/merc_drop_pod + name = "Pod control console" + shuttle_tag = "Cyclopes Droppod" + +/obj/overmap/visitable/ship/landable/merc_drop_pod + name = "Cyclopes Droppod" + shuttle = "Cyclopes Droppod" + desc = "A small, unmarked vessel." + fore_dir = NORTH + vessel_size = SHIP_SIZE_SMALL + vessel_mass = 2500 + +/obj/shuttle_landmark/merc_pod/start + landmark_tag = "nav_merc_pod_start" + name = "Cyclopes Drop Pod Base" + base_area = /area/map_template/merc_shuttle/drop_pod + movable_flags = MOVABLE_FLAG_EFFECTMOVE + +/obj/shuttle_landmark/merc_pod/merc_ship + landmark_tag = "nav_merc_pod_ship" + name = "Cyclopes Drop Pod Ship" + +/area/map_template/merc_shuttle/drop_pod + name = "\improper Cyclopes Droppod" + icon_state = "yellow" + area_flags = AREA_FLAG_RAD_SHIELDED | AREA_FLAG_ION_SHIELDED + req_access = list(access_syndicate) + +/obj/machinery/computer/shuttle_control/explore/merc_shuttle/merc_drop_pod + skill_req = SKILL_BASIC + + +/obj/machinery/button/alternate/pod_doors_explodey + name = "Explode pod door" + + var/burst = 4 + var/notbeenactivated = TRUE + var/last_shot = 0 + var/fire_delay = 0.2 SECONDS + +/obj/machinery/button/alternate/pod_doors_explodey/activate(mob/living/user) + if(notbeenactivated) + notbeenactivated = FALSE + door_activate() + else + to_chat(usr, SPAN_WARNING("The hullbreaker is already been used.")) + +/obj/machinery/button/alternate/pod_doors_explodey/proc/door_activate() + for(burst; burst >= 0; burst -= 1) + if((last_shot + fire_delay) <= world.time) + last_shot = world.time + for(var/i in 1 to burst) + var/obj/item/projectile/proj = new /obj/item/projectile/beam/hullbreaker(get_turf(src)) + proj.launch( get_step(loc, src.dir) ) + playsound(src.loc, 'sound/weapons/railgun.ogg', 30, 1) + if(i < burst) + sleep(fire_delay) + + +/obj/item/projectile/beam/hullbreaker + name = "hullbreaker" + icon_state = "omnilaser" + fire_sound = 'sound/weapons/railgun.ogg' + damage = 950 + armor_penetration = 100 + edge = TRUE + damage_type = DAMAGE_EXPLODE + life_span = 3 + pass_flags = PASS_FLAG_TABLE + distance_falloff = 3 + + muzzle_type = /obj/projectile/pointdefense/muzzle + tracer_type = /obj/projectile/pointdefense/tracer + impact_type = /obj/projectile/pointdefense/impact + +/obj/item/projectile/beam/hullbreaker/on_impact(atom/A) + . = ..() + if(A.density) + A.ex_act(EX_ACT_DEVASTATING) + playsound(src.loc, 'sound/effects/meteorimpact.ogg', 80, 1) + for(var/mob/H in range(20, src)) + if(!H.stat && !istype(H, /mob/living/silicon/ai))\ + shake_camera(H, 5, 2) + qdel(src) diff --git a/mods/chemtweaks/README.md b/mods/chemtweaks/README.md new file mode 100644 index 0000000000000..eccfa13d8eecb --- /dev/null +++ b/mods/chemtweaks/README.md @@ -0,0 +1,71 @@ +#### Список PRов: + +https://github.com/SierraBay/SierraBay12/pull/2823 + + +## Мод-пример + +ID мода: CHEMTWEAKS + + +### Описание мода + +Мод, служащий для более лёгкого изменения рецептов. + + +### Изменения *кор кода* + +Отсутствуют + + +### Оверрайды + +- `code/modules/reagents/Chemistry-Recipes.dm` + + +### Дефайны + +Отсутствуют + + +### Используемые файлы, не содержащиеся в модпаке + +Отсутствуют + + +### Авторы: + +Baneuus + diff --git a/mods/chemtweaks/_chemtweaks.dm b/mods/chemtweaks/_chemtweaks.dm new file mode 100644 index 0000000000000..11c0a8b3ae95a --- /dev/null +++ b/mods/chemtweaks/_chemtweaks.dm @@ -0,0 +1,4 @@ +/singleton/modpack/chemtweaks + name = "ChemTweaks" + desc = "Мод, позволяющий так или иначе изменять рецепты в билде" + author = "Baneuus" diff --git a/mods/chemtweaks/_chemtweaks.dme b/mods/chemtweaks/_chemtweaks.dme new file mode 100644 index 0000000000000..e80130ed99e97 --- /dev/null +++ b/mods/chemtweaks/_chemtweaks.dme @@ -0,0 +1,8 @@ +#ifndef MODPACK_CHEMTWEAKS +#define MODPACK_CHEMTWEAKS + +#include "_chemtweaks.dm" + +#include "code/Chemistry-Recipes.dm" + +#endif diff --git a/mods/chemtweaks/code/Chemistry-Recipes.dm b/mods/chemtweaks/code/Chemistry-Recipes.dm new file mode 100644 index 0000000000000..6e8b531b63edd --- /dev/null +++ b/mods/chemtweaks/code/Chemistry-Recipes.dm @@ -0,0 +1,30 @@ +/singleton/reaction/slime/crit_hostile + name = "Slime Crit Hostile" + result = null + required_reagents = list(/datum/reagent/blood = 1) + result_amount = 1 + required = /obj/item/slime_extract/gold + var/list/possible_mobs = list( + /mob/living/simple_animal/hostile/carp, + /mob/living/simple_animal/hostile/carp/shark, + /mob/living/simple_animal/hostile/carp/pike, + /mob/living/simple_animal/hostile/bear, + /mob/living/simple_animal/hostile/drake, + /mob/living/simple_animal/hostile/giant_spider, + /mob/living/simple_animal/hostile/retaliate/beast/antlion, + /mob/living/simple_animal/hostile/creature, + /mob/living/simple_animal/hostile/leech, + /mob/living/simple_animal/hostile/vagrant + ) + +/singleton/reaction/slime/crit_hostile/on_reaction(datum/reagents/holder) + ..() + var/type = pick(possible_mobs) + new type(get_turf(holder.my_atom)) + +/singleton/reaction/slime/grevive + name = "Slime Revive" + result = null + required_reagents = list(/datum/reagent/blood = 1) + result_amount = 1 + required = /obj/item/slime_extract/cerulean diff --git a/mods/global_modpacks.dm b/mods/global_modpacks.dm index 0b39a0f825780..f63dbd1ae927d 100644 --- a/mods/global_modpacks.dm +++ b/mods/global_modpacks.dm @@ -23,6 +23,7 @@ #include "lobbyscreen/_lobbyscreen.dme" #include "music_player/_music_player.dme" #include "ntnet/_ntnet.dme" +#include "virusology/_virusology.dme" #include "RnD/_RnD.dme" #include "nyc_posters/_nyc_posters.dme" #include "pixelshift/_pixelshift.dme" @@ -41,5 +42,6 @@ #include "ooc_notes/_ooc_notes.dme" #include "character_traits/_character_traits.dme" #include "failu_skrell_clothes/_failu_skrell_clothes.dme" +#include "chemtweaks/_chemtweaks.dme" #include "../packs/sierra-tweaks/_pack.dm" diff --git a/mods/mechs_by_shegar/code/mech_move.dm b/mods/mechs_by_shegar/code/mech_move.dm index 2ae7ea4b1e51c..54232c9c0c937 100644 --- a/mods/mechs_by_shegar/code/mech_move.dm +++ b/mods/mechs_by_shegar/code/mech_move.dm @@ -32,7 +32,7 @@ var/mob/living/pilot = pick(pilots) if(legs.bump_safety && pilot.a_intent != I_HURT) //Мы не хотим топтать и ноги могут не топтать? return //Не топчем - src.visible_message(SPAN_DANGER("forcefully tramples [target] on the floor!"), blind_message = SPAN_DANGER("You hear the loud hissing of hydraulics!")) + src.visible_message(SPAN_DANGER("[src] forcefully tramples [target] on the floor!"), blind_message = SPAN_DANGER("You hear the loud hissing of hydraulics!")) target.apply_effects(5, 5) //Чтоб не вставал var/damage = rand(5, 10) damage = 2 * (damage * (total_weight / 1000) + (legs.bump_type * 3)) // 30 урона в лучшем случае по груди и голове @@ -59,6 +59,8 @@ return Bumps = !Bumps collision_attack(target) + target.Move(get_ranged_target_turf(target, src.dir, 1)) + src.forceMove(get_ranged_target_turf(src, src.dir, 1)) return /mob/living/exosuit/proc/collision_attack(mob/living/target,bump_type) //Attack colissioned things diff --git a/mods/playable_away_yacht/maps/yacht.dmm b/mods/playable_away_yacht/maps/yacht.dmm index 76affd2130754..31eff0213b5db 100644 --- a/mods/playable_away_yacht/maps/yacht.dmm +++ b/mods/playable_away_yacht/maps/yacht.dmm @@ -2287,7 +2287,9 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/hidden/cyan, +/obj/machinery/atmospherics/binary/pump/on{ + dir = 1 + }, /turf/simulated/floor/tiled/monotile, /area/playable_yacht/left_engine) "To" = ( diff --git a/mods/utility_items/_utility_items.dme b/mods/utility_items/_utility_items.dme index b02c3a4e3eaba..7d7e1d016ed6f 100644 --- a/mods/utility_items/_utility_items.dme +++ b/mods/utility_items/_utility_items.dme @@ -16,12 +16,13 @@ #include "code/circuit.dm" #include "code/global_hud_sierra.dm" #include "code/labcoat.dm" -#include "code\ninja-map.dm" -#include "code\shuttle_feature.dm" -#include "code\craft_drugs.dm" +#include "code/ninja-map.dm" +#include "code/shuttle_feature.dm" +#include "code/craft_drugs.dm" #include "code/hair_olivka.dm" #include "code/ert_maint_helmet.dm" #include "code/tag_recipe.dm" +#include "code/dodge_animation.dm" #include "code/advanced_landing.dm" #include "code/chemistry.dm" #include "code/jobs.dm" diff --git a/mods/utility_items/code/advanced_landing.dm b/mods/utility_items/code/advanced_landing.dm index f8272931325c5..5d71054169c5c 100644 --- a/mods/utility_items/code/advanced_landing.dm +++ b/mods/utility_items/code/advanced_landing.dm @@ -1,3 +1,8 @@ +/obj/machinery/computer/shuttle_control/Initialize(mapload, init_shuttle_tag) + . = ..() + if(shuttle_tag == init_shuttle_tag) + sync_shuttle() + /obj/machinery/computer/shuttle_control/explore/handle_topic_href(datum/shuttle/autodock/overmap/shuttle, list/href_list) . = ..() if(href_list["advancedpick"]) @@ -36,6 +41,7 @@ var/y_offset = 0 var/landloc var/skilled_enough = FALSE + var/skill_req = SKILL_EXPERIENCED /obj/machinery/computer/shuttle_control/proc/update_operator_skill() if (isobserver(usr)) @@ -43,7 +49,7 @@ if(!usr) return operator_skill = usr.get_skill_value(SKILL_PILOT) - if (operator_skill >= SKILL_EXPERIENCED) + if (operator_skill >= skill_req && !(istype(usr, /mob/living/silicon/ai))) skilled_enough = TRUE else skilled_enough = FALSE @@ -62,43 +68,22 @@ density = FALSE alpha = 127 plane = OBSERVER_PLANE + simulated = FALSE + stat = CONSCIOUS invisibility = INVISIBILITY_EYE see_invisible = SEE_INVISIBLE_MINIMUM sight = SEE_TURFS - simulated = TRUE - stat = CONSCIOUS - status_flags = GODMODE ghost_image_flag = GHOST_IMAGE_NONE var/list/placement_images = list() var/obj/machinery/computer/shuttle_control/explore/console_link var/list/to_add = list() -/* -/mob/living/carbon/human/ - var/list/obscured_turfs = list() -*/ + /mob/living/carbon/human/update_dead_sight() . = ..() - /* - var/area = seen_turfs_in_range(src.eyeobj, world.view) - var/image/O = image('icons/effects/cameravis.dmi', null, "black")*/ if(eyeobj.type == /mob/observer/eye/landeye) - set_sight(BLIND|SEE_TURFS) set_see_in_dark(8) set_see_invisible(SEE_INVISIBLE_MINIMUM) - /*for(var/turf/simulated/t in area) - if(t in obscured_turfs) - return - if(!(t in list(/area/space))) - O.loc = t.loc - O.layer = TURF_LAYER - obscured_turfs[O] = t - client.images += obscured_turfs*/ - -/mob/observer/eye/landeye/proc/acquire_visible_turfs(list/visible) - for(var/turf/t in seen_turfs_in_range(src, world.view)) - if(t in typesof(/area/space)) - visible[t] = t - return visible + set_sight(BLIND|SEE_TURFS) /mob/observer/eye/landeye/possess(mob/user) if(owner && owner != user) @@ -113,6 +98,7 @@ owner.verbs |= /mob/living/proc/extra_view owner.verbs |= /mob/living/proc/cancel_landeye_view owner.client.eye = src + /mob/observer/eye/landeye/setLoc(T) if(!owner) return FALSE @@ -153,6 +139,7 @@ /obj/machinery/computer/shuttle_control/explore/pod_hand_one /obj/machinery/computer/shuttle_control/explore/pod_hand_two /obj/machinery/computer/shuttle_control/explore/graysontug/hand_two +/obj/machinery/computer/shuttle_control/explore/merc_shuttle/merc_drop_pod /area/mine name = "Mine" @@ -163,6 +150,7 @@ // ______________________________________________________________ /obj/machinery/computer/shuttle_control/explore/ + var/landmarkx_off var/landmarky_off //Лучше способа не придумал, поэтому если check_zone шаттла захватывает территории, больше чем надо, то пихаем консоль этого шаттла, в список @@ -175,7 +163,9 @@ /obj/machinery/computer/shuttle_control/explore/graysontug/hand_one, /obj/machinery/computer/shuttle_control/explore/pod_hand_one, /obj/machinery/computer/shuttle_control/explore/pod_hand_two, - /obj/machinery/computer/shuttle_control/explore/graysontug/hand_two + /obj/machinery/computer/shuttle_control/explore/graysontug/hand_two, + /obj/machinery/computer/shuttle_control/explore/merc_shuttle, + /obj/machinery/computer/shuttle_control/explore/merc_shuttle/merc_drop_pod, ) //Списки куда разрешена посадка @@ -201,7 +191,6 @@ /obj/machinery/computer/shuttle_control/explore/proc/create_zone() var/area/area_oko = get_area(src) - //var/obj/overmap/visitable/ship/landable/shuttle_landmark = locate(/obj/overmap/visitable/ship/landable) in area_oko var/turf/origin = locate(src.x + x_offset, src.y + y_offset, src.z) var/turf/turf var/obj/shuttle_landmark/shuttle_landmark @@ -236,9 +225,16 @@ var/list/coords = image_cache[I] var/turf/T = locate(eyeturf.x + coords[1], eyeturf.y + coords[2], eyeturf.z) var/area/A = get_area(T) + var/zone_good = FALSE I.loc = T - if(!(T.density) && ((A.type in accesible_areas))) - I.icon_state = "blue" + if(!(T.density)) + for(var/type in accesible_areas) + if(A.type in typesof(type)) + zone_good = TRUE + if(zone_good) + I.icon_state = "blue" + else + I.icon_state = "red" else I.icon_state = "red" landable = FALSE @@ -275,7 +271,6 @@ SetName(initial(name)) - /obj/shuttle_landmark/ship/advancedlandmark/Initialize(mapload, obj/shuttle_landmark/ship/master, _name) landmark_tag = "_[shuttle_name] [rand(1,99999)]" . = ..() @@ -295,3 +290,11 @@ var/turf/T = locate(eyeturf.x + c.landmarkx_off, eyeturf.y + c.landmarky_off , eyeturf.z) landmark = new (T, src) c.shuttle_type.set_destination(landmark) + +/turf + var/prev_type + +/turf/ChangeTurf(turf/N, tell_universe = TRUE, force_lighting_update = FALSE, keep_air = FALSE) + .=..() + var/old_prev_type = prev_type + prev_type = old_prev_type diff --git a/mods/utility_items/code/dodge_animation.dm b/mods/utility_items/code/dodge_animation.dm new file mode 100644 index 0000000000000..70e033ec0f160 --- /dev/null +++ b/mods/utility_items/code/dodge_animation.dm @@ -0,0 +1,46 @@ +//Анимация уворота для мобиков. +/mob/proc/dodge_animation(input_animation_time = 0.4 SECONDS, atom/attacker = null) + //Выставляем нулевые значения + pixel_x = 0 + pixel_y = 0 + //Сперва создаём список направлений, куда будет уклонятся кукла + var/list/directions = list(NORTH, EAST, WEST, SOUTH) + //Теперь удалим 1 лишние направление, т.к для уклонения нельзя сдвигаться навстречу противнику(Не красиво) + if(attacker) + //берём противоположное направление атакующего + var/enemy_dir = turn(attacker.dir, 180) + if(enemy_dir == NORTHWEST || enemy_dir == SOUTHWEST) + enemy_dir = WEST + else if(enemy_dir == SOUTHWEST || enemy_dir == SOUTHEAST) + enemy_dir = EAST + LAZYREMOVE(directions, enemy_dir) + var/dodge_direction = pick(directions) + //определяемся с временем анимации уворота + var/result_animation_time = input_animation_time + var/middle_number = result_animation_time/2 + //Обычный цикл + for(var/current_iteration = 1, current_iteration <= result_animation_time, current_iteration++) + sleep(1) + if(dodge_direction == NORTH) + if(current_iteration <= middle_number) + pixel_y += 2 + else + pixel_y -= 2 + + else if(dodge_direction == SOUTH) + if(current_iteration <= middle_number) + pixel_y -= 2 + else + pixel_y += 2 + + else if(dodge_direction == WEST) + if(current_iteration <= middle_number) + pixel_x -= 2 + else + pixel_x += 2 + + else if(dodge_direction == EAST) + if(current_iteration <= middle_number) + pixel_x += 2 + else + pixel_x -= 2 diff --git a/mods/virusology/README.md b/mods/virusology/README.md new file mode 100644 index 0000000000000..0f32408d2d170 --- /dev/null +++ b/mods/virusology/README.md @@ -0,0 +1,79 @@ + +#### Список PRов: + +- https://github.com/SierraBay/SierraBay12/pull/##### + + + +## Мод-пример + +ID мода: EXAMPLE + + +### Описание мода + +Этот мод служит примером для разработчиков и существует лишь для того, +чтобы его можно было легко скопировать и вставить в другое место. + + +### Изменения *кор кода* + +- `code/modules/mob/living.dm`: `proc/overriden_proc`, `var/overriden_var` + + +### Оверрайды + +- `mods/_master_files/sound/my_cool_sound.ogg` +- `mods/_master_files/code/my_modular_override.dm`: `proc/overriden_proc`, `var/overriden_var` + + +### Дефайны + +- `code/__defines/~mods/example.dm`: `EXAMPLE_SPEED_MULTIPLIER`, `EXAMPLE_SPEED_BASE` + + +### Используемые файлы, не содержащиеся в модпаке + +- `mods/_master_files/icons/obj/alien.dmi` + + +### Авторы: + +Твой никнейм + diff --git a/mods/virusology/_virusology.dm b/mods/virusology/_virusology.dm new file mode 100644 index 0000000000000..bb4b93bbd70c9 --- /dev/null +++ b/mods/virusology/_virusology.dm @@ -0,0 +1,4 @@ +/singleton/modpack/virus + name = "Мод с Вирусологией" + desc = "Вирусология." + author = "Lexanx" diff --git a/mods/virusology/_virusology.dme b/mods/virusology/_virusology.dme new file mode 100644 index 0000000000000..f7dc8fbb0364b --- /dev/null +++ b/mods/virusology/_virusology.dme @@ -0,0 +1,21 @@ +#ifndef MODPACK_VIRUSOLOGY +#define MODPACK_VIRUSOLOGY + +#include "_virusology.dm" +#include "code\admin.dm" +#include "code\analyser.dm" +#include "code\antibodies.dm" +#include "code\antibodyanalyser.dm" +#include "code\centrifuge.dm" +#include "code\curer.dm" +#include "code\disease2.dm" +#include "code\diseasesplicer.dm" +#include "code\dishincubator.dm" +#include "code\effect.dm" +#include "code\helpers.dm" +#include "code\isolator.dm" +#include "code\items_devices.dm" +#include "code\general.dm" +#include "code\lar_maria.dm" +#include "code\pre_made_viruses.dm" +#endif diff --git a/mods/virusology/code/admin.dm b/mods/virusology/code/admin.dm new file mode 100644 index 0000000000000..81eabebb1904a --- /dev/null +++ b/mods/virusology/code/admin.dm @@ -0,0 +1,243 @@ +/datum/disease2/disease/Topic(href, href_list) + . = ..() + if(.) return + + if(href_list["info"]) + // spawn or admin privileges to see info about viruses + if(!check_rights(R_ADMIN|R_SPAWN)) return + + to_chat(usr, "Infection chance: [infectionchance]; Speed: [speed]; Spread type: [spreadtype]") + to_chat(usr, "Affected species: [english_list(affected_species)]") + to_chat(usr, "Effects:") + for(var/datum/disease2/effect/E in effects) + to_chat(usr, "[E.stage]: [E.name]; chance=[E.chance]; multiplier=[E.multiplier]") + to_chat(usr, "Antigens: [antigens2string(antigen)]") + + return 1 + +/datum/disease2/disease/get_view_variables_header() + . = list() + for(var/datum/disease2/effect/E in effects) + . += "[E.stage]: [E.name]" + return {" + [name()]
    + [jointext(., "
    ")]
    + "} + +/datum/disease2/disease/get_view_variables_options() + return ..() + {" + + "} + +/datum/admins/var/datum/virus2_editor/virus2_editor_datum = new +/client/proc/virus2_editor() + set name = "Virus Editor" + set category = "Admin" + if(!holder || !check_rights(R_SPAWN)) return // spawn privileges to create viruses + + holder.virus2_editor_datum.show_ui(src) + +/datum/virus2_editor + var/list/s = list(/datum/disease2/effect/invisible,/datum/disease2/effect/invisible,/datum/disease2/effect/invisible,/datum/disease2/effect/invisible) + var/list/s_chance = list(1,1,1,1) + var/list/s_multiplier = list(1,1,1,1) + var/species = list() + var/infectionchance = 70 + var/spreadtype = "Contact" + var/list/antigens = list() + var/speed = 1 + var/mob/living/carbon/infectee = null + + // this holds spawned viruses so that the "Info" links work after the proc exits + var/list/spawned_viruses = list() + +/datum/virus2_editor/proc/select(mob/user, stage) + if(stage < 1 || stage > 4) return + + var/list/L = list() + + for(var/e in (typesof(/datum/disease2/effect) - /datum/disease2/effect)) + var/datum/disease2/effect/f = e + if(initial(f.stage) <= stage) + L[initial(f.name)] = e + + var/datum/disease2/effect/Eff = s[stage] + + var/C = input("Select effect for stage [stage]:", "Stage [stage]", initial(Eff.name)) as null|anything in L + if(!C) return + return L[C] + +/datum/virus2_editor/proc/show_ui(mob/user) + var/H = {" +

    Virus2 Virus Editor


    + Effects:
    + "} + for(var/i = 1 to 4) + var/datum/disease2/effect/Eff = s[i] + H += {" + [initial(Eff.name)] + Chance: [s_chance[i]] + Multiplier: [s_multiplier[i]] +
    + "} + H += {" +
    + Infectable Species:
    + "} + var/f = 1 + for(var/k in all_species) + var/datum/species/S = all_species[k] + if(S.get_virus_immune()) + continue + if(!f) H += " | " + else f = 0 + H += "[k]" + H += {" + Reset +
    + Infection Chance: [infectionchance]
    + Spread Type: [spreadtype]
    + Speed: [speed]
    +
    + "} + f = 1 + for(var/k in ALL_ANTIGENS) + if(!f) H += " | " + else f = 0 + H += "[k]" + H += {" + Reset +
    +
    + Initial infectee: [infectee ? infectee : "(choose)"] + RELEASE + "} + +/datum/virus2_editor/Topic(href, href_list) + switch(href_list["what"]) + if("effect") + var/stage = text2num(href_list["stage"]) + if(href_list["effect"]) + var/datum/disease2/effect/E = select(usr,stage) + if(!E) return + s[stage] = E + // set a default chance and multiplier of half the maximum (roughly average) + s_chance[stage] = max(1, round(initial(E.chance_max)/2)) + s_multiplier[stage] = max(1, round(initial(E.multiplier_max)/2)) + else if(href_list["chance"]) + var/datum/disease2/effect/Eff = s[stage] + var/I = input("Chance, per tick, of this effect happening (min 0, max [initial(Eff.chance_max)])", "Effect Chance", s_chance[stage]) as null|num + if(!I || I < 0 || I > initial(Eff.chance_max)) return + s_chance[stage] = I + else if(href_list["multiplier"]) + var/datum/disease2/effect/Eff = s[stage] + var/I = input("Multiplier for this effect (min 1, max [initial(Eff.multiplier_max)])", "Effect Multiplier", s_multiplier[stage]) as null|num + if(!I || I < 1 || I > initial(Eff.multiplier_max)) return + s_multiplier[stage] = I + if("species") + if(href_list["toggle"]) + var/T = href_list["toggle"] + if(T in species) + species -= T + else + species |= T + else if(href_list["reset"]) + species = list() + if(infectee) + if(!infectee.species || !(infectee.species.get_bodytype(infectee) in species)) + infectee = null + if("ichance") + var/I = input("Input infection chance", "Infection Chance", infectionchance) as null|num + if(!I) return + infectionchance = I + if("stype") + var/S = alert("Which spread type?", "Spread Type", "Cancel", "Contact", "Airborne") + if(!S || S == "Cancel") return + spreadtype = S + if("speed") + var/S = input("Input speed", "Speed", speed) as null|num + if(!S) return + speed = S + if("antigen") + if(href_list["toggle"]) + var/T = href_list["toggle"] + if(length(T) != 1) return + if(T in antigens) + antigens -= T + else + antigens |= T + else if(href_list["reset"]) + antigens = list() + if("infectee") + var/list/candidates = list() + for(var/mob/living/carbon/G in SSmobs.mob_list) + if(G.stat != DEAD && G.species) + if(G.species.get_bodytype(G) in species) + candidates["[G.name][G.client ? "" : " (no client)"]"] = G + else + candidates["[G.name] ([G.species.get_bodytype(G)])[G.client ? "" : " (no client)"]"] = G + if(!LAZYLEN(candidates)) to_chat(usr, "No possible candidates found!") + + var/I = input("Choose initial infectee", "Infectee", infectee) as null|anything in candidates + if(!I || !candidates[I]) return + infectee = candidates[I] + species |= infectee.species.get_bodytype(infectee) + if("go") + if(!LAZYLEN(antigens)) + var/a = alert("This disease has no antigens; it will be impossible to permanently immunise anyone without them.\ + It is strongly recommended to set at least one antigen. Do you want to go back and edit your virus?", "Antigens", "Yes", "Yes", "No") + if(a == "Yes") return + var/datum/disease2/disease/D = new + D.infectionchance = infectionchance + D.spreadtype = spreadtype + D.antigen = antigens + D.affected_species = species + D.speed = speed + for(var/i in 1 to 4) + var/datum/disease2/effect/E = new + var/Etype = s[i] + E = new Etype() + E.generate() + E.chance = s_chance[i] + E.multiplier = s_multiplier[i] + E.stage = i + + D.effects += E + + spawned_viruses += D + + message_admins("[key_name_admin(usr)] infected [key_name_admin(infectee)] with a virus (Info)") + log_admin("[key_name_admin(usr)] infected [key_name_admin(infectee)] with a virus!") + infect_virus2(infectee, D, forced=1) + + show_ui(usr) + + +/client/proc/give_disease2(mob/T as mob in SSmobs.mob_list) // -- Giacom + set category = "Fun" + set name = "Give Disease" + set desc = "Gives a Disease to a mob." + + var/datum/disease2/disease/D = new /datum/disease2/disease() + + var/severity = 1 + var/greater = input("Is this a lesser, greater, or badmin disease?", "Give Disease") in list("Lesser", "Greater", "Badmin") + switch(greater) + if ("Lesser") severity = 1 + if ("Greater") severity = 2 + if ("Badmin") severity = 99 + + D.makerandom(severity) + D.infectionchance = input("How virulent is this disease? (1-100)", "Give Disease", D.infectionchance) as num + + if(istype(T,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = T + if (H.species) + D.affected_species = list(H.species.get_bodytype(H)) + if(H.species.primitive_form) + D.affected_species |= H.species.primitive_form + if(H.species.greater_form) + D.affected_species |= H.species.greater_form + infect_virus2(T,D,1) + + log_and_message_admins("gave [key_name(T)] a [greater] disease2 with infection chance [D.infectionchance].") diff --git a/mods/virusology/code/analyser.dm b/mods/virusology/code/analyser.dm new file mode 100644 index 0000000000000..1e1f3dd074591 --- /dev/null +++ b/mods/virusology/code/analyser.dm @@ -0,0 +1,80 @@ +/obj/machinery/disease2/diseaseanalyser + name = "disease analyser" + icon = 'mods/virusology/icons/virology.dmi' + icon_state = "analyser" + density = TRUE + + var/scanning = 0 + var/pause = 0 + + var/obj/item/virusdish/dish = null + +/obj/machinery/disease2/diseaseanalyser/use_tool(obj/item/O, mob/living/user, list/click_params) + . = ..() + if(!istype(O,/obj/item/virusdish)) return + + if(dish) + to_chat(user, "\The [src] is already loaded.") + return + if(!user.unEquip(O, src)) + return + dish = O + operator_skill = user.get_skill_value(core_skill) + + user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") + +/obj/machinery/disease2/diseaseanalyser/Process() + if(stat & (MACHINE_STAT_NOPOWER|MACHINE_IS_BROKEN(src))) + return + + if(scanning) + scanning -= 1 + if(scanning == 0) + if (dish.virus2.addToDB()) + ping("\The [src] pings, \"New pathogen added to data bank.\"") + + var/list/effects = get_fake_effects(dish.virus2) + var/r = dish.virus2.get_info(operator_skill, 1, effects) + var/title = "paper - [dish.virus2.name()]" + var/info = {" + [virology_letterhead("Post-Analysis Memo")] + [r] +
    + Additional Notes:  + "} + new /obj/item/paper(loc, info, title) + + dish.basic_info = dish.virus2.get_info(operator_skill, 0, effects) + dish.info = r + dish.SetName("[initial(dish.name)] ([dish.virus2.name()])") + dish.analysed = 1 + dish.forceMove(loc) + dish = null + operator_skill = null + + icon_state = "analyser" + src.state("\The [src] prints a sheet of paper.") + + else if(dish && !scanning && !pause) + if(dish.virus2 && dish.growth > 50) + dish.growth -= 10 + scanning = 5 + icon_state = "analyser_processing" + else + pause = 1 + addtimer(new Callback(src, PROC_REF(dishmove)), 25) + +/obj/machinery/disease2/diseaseanalyser/proc/dishmove() + dish.forceMove(loc) + dish = null + + src.state("\The [src] buzzes, \"Insufficient growth density to complete analysis.\"") + pause = 0 + +/obj/machinery/disease2/diseaseanalyser/proc/get_fake_effects() + . = list() + for(var/datum/disease2/effect/E in dish.virus2.effects) + if(operator_skill >= HAS_PERK || prob(60)) + . += E //Passed skill check, use real effect + else + . += get_random_virus2_effect(E.stage, VIRUS_ENGINEERED) //Failed check, get a fake effect diff --git a/mods/virusology/code/antibodies.dm b/mods/virusology/code/antibodies.dm new file mode 100644 index 0000000000000..e48de876d8209 --- /dev/null +++ b/mods/virusology/code/antibodies.dm @@ -0,0 +1,26 @@ +//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33 + +var/global/list/ALL_ANTIGENS = list( + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" + ) + +/hook/startup/proc/randomise_antigens_order() + ALL_ANTIGENS = shuffle(ALL_ANTIGENS) + return 1 + +// iterate over the list of antigens and see what matches +/proc/antigens2string(list/antigens, none="None") + if(!istype(antigens)) + CRASH("Illegal type!") + if(!LAZYLEN(antigens)) + return none + + var/code = "" + for(var/V in ALL_ANTIGENS) + if(V in antigens) + code += V + + if(!code) + return none + + return code diff --git a/mods/virusology/code/antibodyanalyser.dm b/mods/virusology/code/antibodyanalyser.dm new file mode 100644 index 0000000000000..90cd903e96836 --- /dev/null +++ b/mods/virusology/code/antibodyanalyser.dm @@ -0,0 +1,70 @@ +/obj/machinery/disease2/antibodyanalyser + name = "antibody analyser" + desc = "An advanced machine that analyses pure antibody samples and stores the structure of them on the ExoNet in exchange for cargo points." + icon = 'mods/virusology/icons/virology.dmi' + icon_state = "analyser" + density = TRUE + + var/scanning = 0 + var/pause = 0 + var/list/known_antibodies = list() + + var/obj/item/reagent_containers/container = null + +/obj/machinery/disease2/antibodyanalyser/on_update_icon() + if(scanning) + icon_state = "analyser_processing" + else + icon_state = "analyser" + +/obj/machinery/disease2/antibodyanalyser/use_tool(obj/item/I, mob/living/user, list/click_params) + . = ..() + if(istype(I,/obj/item/reagent_containers)) + if(!container && user.unEquip(I)) + container = I + I.forceMove(src) + user.visible_message("[user] adds a sample to \the [src]!", "You add a sample to \the [src]!") + return + +/obj/machinery/disease2/antibodyanalyser/Process() + if(stat & (MACHINE_STAT_NOPOWER|MACHINE_IS_BROKEN(src))) + return + + if(scanning) + scanning -= 1 + if(scanning == 0) + if(!container.reagents.has_reagent(/datum/reagent/antibodies)) //if there are no antibody reagents, return false + return 0 + + else + var/list/data = container.reagents.get_data(/datum/reagent/antibodies) //now that we know there are antibody reagents, get the data + var/list/given_antibodies = data["antibodies"] //now check what specific antibodies it's holding + var/list/common_antibodies = known_antibodies & given_antibodies + var/list/unknown_antibodies = common_antibodies ^ given_antibodies + if(LAZYLEN(unknown_antibodies)) + var/payout = LAZYLEN(unknown_antibodies) * 45 + SSsupply.add_points_from_source(payout, "virology_antibodies") + ping("\The [src] pings, \"Successfully uploaded new antibodies to the ExoNet.\"") + known_antibodies |= unknown_antibodies //Add the new antibodies to list + else + src.state("\The [src] buzzes, \"Failed to identify any new antibodies.\"") + + container.dropInto(loc) + container = null + + on_update_icon() + + else if(container && !scanning && !pause) + if(container.reagents.has_reagent(/datum/reagent/antibodies)) + scanning = 5 + on_update_icon() + else + container.dropInto(loc) + container = null + + src.state("\The [src] buzzes, \"Failed to identify a pure sample of antibodies in the solution.\"") + return + +/obj/machinery/disease2/antibodyanalyser/Destroy() + QDEL_NULL(container) + . = ..() diff --git a/mods/virusology/code/centrifuge.dm b/mods/virusology/code/centrifuge.dm new file mode 100644 index 0000000000000..d89e6cedc7754 --- /dev/null +++ b/mods/virusology/code/centrifuge.dm @@ -0,0 +1,222 @@ +/obj/machinery/computer/centrifuge + name = "isolation centrifuge" + desc = "Used to separate things with different weights. Spin 'em round, round, right round." + icon = 'mods/virusology/icons/virology.dmi' + icon_state = "centrifuge" + var/curing + var/isolating + + var/obj/item/reagent_containers/glass/beaker/vial/sample = null + var/datum/disease2/disease/virus2 = null + core_skill = SKILL_SCIENCE//SKILL_VIROLOGY + +/obj/machinery/computer/centrifuge/use_tool(obj/item/O, mob/living/user, list/click_params) + . = ..() + if(isScrewdriver(O)) + return ..(O,user) + + if(istype(O,/obj/item/reagent_containers/glass/beaker/vial)) + if(sample) + to_chat(user, "\The [src] is already loaded.") + return + if(!user.unEquip(O, src)) + return + sample = O + + user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") + SSnano.update_uis(src) + + src.attack_hand(user) + +/obj/machinery/computer/centrifuge/on_update_icon() + ..() + if(stat && (MACHINE_STAT_NOPOWER)) + icon_state = "centrifuge0" + if(stat && (MACHINE_IS_BROKEN(src))) + icon_state = "centrifugeb" + if(curing | isolating) + icon_state = "centrifuge_moving" + else + icon_state = "centrifuge" + +/obj/machinery/computer/centrifuge/interface_interact(mob/user) + ui_interact(user) + return TRUE + +/obj/machinery/computer/centrifuge/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) + user.set_machine(src) + + var/data[0] + data["antibodies"] = null + data["pathogens"] = null + data["is_antibody_sample"] = null + + if (curing) + data["busy"] = "Isolating antibodies..." + else if (isolating) + data["busy"] = "Isolating pathogens..." + else + data["sample_inserted"] = !!sample + + if (sample) + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list + if (B) + data["antibodies"] = antigens2string(B.data["antibodies"], none=null) + + var/list/pathogens[0] + var/list/virus = B.data["virus2"] + for (var/ID in virus) + var/datum/disease2/disease/V = virus[ID] + pathogens.Add(list(list("name" = V.name(), "spread_type" = V.spreadtype, "reference" = "\ref[V]"))) + + if (LAZYLEN(pathogens) > 0) + data["pathogens"] = pathogens + + else + var/datum/reagent/antibodies/A = locate(/datum/reagent/antibodies) in sample.reagents.reagent_list + if(A) + data["antibodies"] = antigens2string(A.data["antibodies"], none=null) + data["is_antibody_sample"] = 1 + + ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "mods-isolation_centrifuge.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() + +/obj/machinery/computer/centrifuge/Process() + if(stat & (MACHINE_STAT_NOPOWER|MACHINE_IS_BROKEN(src))) return + + if (curing) + curing -= 1 + if (curing == 0) + cure() + + if (isolating) + isolating -= 1 + if(isolating == 0) + isolate() + + if(virus2) + infect_nearby(virus2) + +/obj/machinery/computer/centrifuge/OnTopic(mob/user, href_list) + if (href_list["close"]) + SSnano.close_user_uis(user, src, "main") + return TOPIC_HANDLED + + if (href_list["print"]) + print(user) + return TOPIC_HANDLED + + if(href_list["isolate"]) + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list + if (B) + var/datum/disease2/disease/virus = locate(href_list["isolate"]) + virus2 = virus.getcopy() + isolating = 40 + on_update_icon() + operator_skill = user.get_skill_value(core_skill) + return TOPIC_REFRESH + + switch(href_list["action"]) + if ("antibody") + var/delay = 20 + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list + if (!B) + state("\The [src] buzzes, \"No antibody carrier detected.\"", "blue") + return TOPIC_HANDLED + + var/list/viruses = B.data["virus2"] + if(length(viruses)) + var/ID = pick(viruses) + var/datum/disease2/disease/V = viruses[ID] + virus2 = V.getcopy() + operator_skill = user.get_skill_value(core_skill) + var/has_toxins = locate(/datum/reagent/toxin) in sample.reagents.reagent_list + var/has_radium = sample.reagents.has_reagent(/datum/reagent/radium) + if (has_toxins || has_radium) + state("\The [src] beeps, \"Pathogen purging speed above nominal.\"", "blue") + if (has_toxins) + delay = delay/2 + if (has_radium) + delay = delay/2 + + curing = round(delay) + playsound(src.loc, 'sound/machines/juicer_old.ogg', 50, 1) + on_update_icon() + return TOPIC_REFRESH + + if("sample") + if(sample) + sample.dropInto(loc) + sample = null + return TOPIC_REFRESH + +/obj/machinery/computer/centrifuge/proc/cure() + if (!sample) return + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list + if (!B) return + + var/list/data = list("antibodies" = B.data["antibodies"]) + var/amt= sample.reagents.get_reagent_amount(/datum/reagent/blood) + sample.reagents.remove_reagent(/datum/reagent/blood, amt) + sample.reagents.add_reagent(/datum/reagent/antibodies, amt, data) + operator_skill = null + + SSnano.update_uis(src) + on_update_icon() + ping("\The [src] pings, \"Antibody isolated.\"") + +/obj/machinery/computer/centrifuge/proc/isolate() + if (!sample) return + var/obj/item/virusdish/dish = new/obj/item/virusdish(loc) + dish.virus2 = virus2 + virus2 = null + operator_skill = null + + SSnano.update_uis(src) + on_update_icon() + ping("\The [src] pings, \"Pathogen isolated.\"") + +/obj/machinery/computer/centrifuge/proc/print(mob/user) + var/obj/item/paper/P = new /obj/item/paper(loc) + P.SetName("paper - Pathology Report") + P.info = {" + [virology_letterhead("Pathology Report")] + Sample: [sample.name]
    +"} + + if (user) + P.info += "Generated By: [user.name]
    " + + P.info += "
    " + + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list + if (B) + P.info += "Antibodies: " + P.info += antigens2string(B.data["antibodies"]) + P.info += "
    " + + var/list/virus = B.data["virus2"] + P.info += "Pathogens:
    " + if (LAZYLEN(virus) > 0) + for (var/ID in virus) + var/datum/disease2/disease/V = virus[ID] + P.info += "[V.name()]
    " + else + P.info += "None
    " + + else + var/datum/reagent/antibodies/A = locate(/datum/reagent/antibodies) in sample.reagents.reagent_list + if (A) + P.info += "The following antibodies have been isolated from the blood sample: " + P.info += antigens2string(A.data["antibodies"]) + P.info += "
    " + + P.info += {" +
    + Additional Notes: +"} + + state("The nearby computer prints out a pathology report.") diff --git a/mods/virusology/code/curer.dm b/mods/virusology/code/curer.dm new file mode 100644 index 0000000000000..522d77564e47a --- /dev/null +++ b/mods/virusology/code/curer.dm @@ -0,0 +1,90 @@ +/obj/machinery/computer/curer + name = "cure research machine" + icon = 'icons/obj/machines/computer.dmi' + icon_keyboard = "med_key" + icon_screen = "dna" + idle_power_usage = 500 + var/curing + var/virusing + + var/obj/item/reagent_containers/container = null + +/obj/machinery/computer/curer/use_tool(obj/item/I, mob/living/user, list/click_params) + . = ..() + if(istype(I,/obj/item/reagent_containers)) + if(!container) + if(!user.unEquip(I, src)) + return + container = I + return + ..() + return + +/obj/machinery/computer/curer/interface_interact(mob/user) + interact(user) + return TRUE + +/obj/machinery/computer/curer/interact(mob/user) + user.machine = src + var/dat + if(curing) + dat = "Antibody production in progress" + else if(container) + // check to see if we have the required reagents + if(container.reagents.get_reagent_amount(/datum/reagent/blood) >= 5 && container.reagents.get_reagent_amount(/datum/reagent/radium) >= 15 && container.reagents.get_reagent_amount(/datum/reagent/spaceacillin) >= 10) + + dat = "Blood sample inserted." + dat += "
    Begin antibody production" + else + dat += "
    Please check container contents." + dat += "
    Eject container" + else + dat = "Please insert a container." + + show_browser(user, "[dat]", "window=computer;size=400x500") + onclose(user, "computer") + return + +/obj/machinery/computer/curer/Process() + if(stat & (MACHINE_STAT_NOPOWER|MACHINE_IS_BROKEN(src))) + return + + if(curing) + curing -= 1 + if(curing == 0) + if(container) + createcure(container) + return + +/obj/machinery/computer/curer/OnTopic(user, href_list) + if (href_list["antibody"]) + curing = 10 + . = TOPIC_REFRESH + else if(href_list["eject"]) + container.dropInto(loc) + container = null + . = TOPIC_REFRESH + + if(. == TOPIC_REFRESH) + attack_hand(user) + +/obj/machinery/computer/curer/proc/createcure(obj/item/reagent_containers/container) + var/obj/item/reagent_containers/C = container + var/antibodies + C.dropInto(loc) + var/mob/living/carbon/M = new /mob/living/carbon + var/datum/reagent/blood/B = locate() in container.reagents.reagent_list + var/data + if(B.data && B.data["virus2"]) + var/list/vlist = B.data["virus2"] + if(LAZYLEN(vlist)) + for(var/ID in vlist) + var/datum/disease2/disease/V = vlist[ID] + data = V.getcopy() + + for(var/ID in data) + var/datum/disease2/disease/V = data[ID] + antibodies |= V.antigen + C.reagents.clear_reagents() + C.reagents.add_reagent(/datum/reagent/antibodies, 10, antibodies) + qdel(M) diff --git a/mods/virusology/code/disease2.dm b/mods/virusology/code/disease2.dm new file mode 100644 index 0000000000000..3a665425a2c7d --- /dev/null +++ b/mods/virusology/code/disease2.dm @@ -0,0 +1,268 @@ +LEGACY_RECORD_STRUCTURE(virus_records, virus_record) + +#define DISEASE_SPREAD_AIRBORNE "Airborne" +#define DISEASE_SPREAD_CONTACT "Contact" +#define DISEASE_SPREAD_BLOOD "Blood" + +/datum/disease2/disease + var/infectionchance = 60 + var/speed = 1 + var/spreadtype = DISEASE_SPREAD_CONTACT // Can also be "Airborne" + var/stage = 1 + var/dead = 0 + var/clicks = 0 + var/uniqueID = 0 + var/list/datum/disease2/effect/effects = list() + var/antigen = list() //A list of characters that represent antigens that cure this virus. + var/max_stage = 4 + var/list/affected_species = list(SPECIES_HUMAN,SPECIES_UNATHI,SPECIES_SKRELL) + var/list/spread_types = list(DISEASE_SPREAD_AIRBORNE = 2, DISEASE_SPREAD_CONTACT = 2, DISEASE_SPREAD_BLOOD = 6) + +/datum/disease2/disease/New() + uniqueID = rand(0,10000) + ..() + +/datum/disease2/disease/proc/makerandom(severity=2) + var/list/excludetypes = list() + for(var/i=1 ; i <= max_stage ; i++ ) + var/datum/disease2/effect/E = get_random_virus2_effect(i, severity, excludetypes) + E.stage = i + if(!E.allow_multiple) + excludetypes += E.type + effects += E + uniqueID = rand(0,10000) + switch(severity) + if(1,2) + infectionchance = rand(10,20) + else + infectionchance = rand(60,90) + + antigen = list(pick(ALL_ANTIGENS)) + antigen |= pick(ALL_ANTIGENS) + spreadtype = prob(70) ? DISEASE_SPREAD_AIRBORNE : DISEASE_SPREAD_CONTACT + + if(LAZYLEN(all_species)) + affected_species = get_infectable_species() + +/proc/get_infectable_species() + var/list/meat = list() + var/list/res = list() + for (var/specie in all_species) + var/datum/species/S = all_species[specie] + if((S.spawn_flags & SPECIES_CAN_JOIN) && !S.get_virus_immune() && !S.greater_form) + meat += S + if(LAZYLEN(meat)) + var/num = rand(1,LAZYLEN(meat)) + for(var/i=0,i 70) + if((mob.species.name == SPECIES_DIONA) && prob(mob.radiation/25)) + cure(mob) + else if(prob(1)) + majormutate() + + if(prob(mob.virus_immunity()) && prob(stage)) // Increasing chance of curing as the virus progresses + cure(mob,1) + //Waiting out the disease the old way + if(stage == max_stage && clicks > max(stage*100, 300)) + if(prob(mob.virus_immunity() * 0.05 + 100-infectionchance)) + cure(mob, 1) + + var/top_badness = 1 + for(var/datum/disease2/effect/e in effects) + if(e.stage == stage) + top_badness = max(top_badness, e.badness) + + //Space antibiotics might stop disease completely + if(mob.chem_effects[CE_ANTIVIRAL] > top_badness) + if(stage == 1 && prob(20)) + cure(mob) + return + + clicks += speed + //Virus food speeds up disease progress + if(mob.reagents.has_reagent(/datum/reagent/nutriment/virus_food)) + mob.reagents.remove_reagent(/datum/reagent/nutriment/virus_food, REM) + clicks += 10 + + //Moving to the next stage + if(clicks > max(stage*100, 300)) + if(stage < max_stage && prob(10)) + stage++ + clicks = 0 + + //Do nasty effects + for(var/datum/disease2/effect/e in effects) + e.fire(mob,stage) + + //fever + if(!mob.chem_effects[CE_ANTIVIRAL]) + mob.bodytemperature = max(mob.bodytemperature, min(310+5*min(stage,max_stage) ,mob.bodytemperature+5*min(stage,max_stage))) + +/datum/disease2/disease/proc/cure(mob/living/carbon/mob, mob_gains_antigens) + for(var/datum/disease2/effect/e in effects) + e.deactivate(mob) + + mob.virus2.Remove("[uniqueID]") + + //Tries to remove the virus also from the bloodstream (only for human-like lifeforms). + if(istype(mob, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = mob + H.cure_virus(uniqueID) + H.immunity = min(H.immunity + 25, H.immunity_norm) + // On virus cure, give a small boost to immunity to help prevent instant reinfection with another virus + + if (mob_gains_antigens) + mob.antibodies |= antigen + + SET_BIT(mob.hud_updateflag, STATUS_HUD) + +/datum/disease2/disease/proc/minormutate() + var/datum/disease2/effect/E = pick(effects) + E.minormutate() + +/datum/disease2/disease/proc/majormutate(badness = VIRUS_ENGINEERED) + uniqueID = rand(0,10000) + var/datum/disease2/effect/E = pick(effects) + var/list/exclude = list() + for(var/datum/disease2/effect/D in effects) + if(D != E) + exclude += D.type + + var/effect_stage = E.stage + E.deactivate() + effects -= E + qdel(E) + + effects += get_random_virus2_effect(effect_stage, badness, exclude) + + antigen = list(pick(ALL_ANTIGENS)) + antigen |= pick(ALL_ANTIGENS) + + if (prob(5) && LAZYLEN(all_species)) + affected_species = get_infectable_species() + +/datum/disease2/disease/proc/getcopy() + var/datum/disease2/disease/disease = new /datum/disease2/disease + disease.infectionchance = infectionchance + disease.spreadtype = spreadtype + disease.speed = speed + disease.antigen = antigen + disease.uniqueID = uniqueID + disease.affected_species = affected_species.Copy() + for(var/datum/disease2/effect/effect in effects) + var/datum/disease2/effect/neweffect = new effect.type + neweffect.generate(effect.data) + neweffect.chance = effect.chance + neweffect.multiplier = effect.multiplier + neweffect.oneshot = effect.oneshot + neweffect.stage = effect.stage + disease.effects += neweffect + return disease + +/datum/disease2/disease/proc/issame(datum/disease2/disease/disease) + . = 1 + + var/list/types = list() + for(var/datum/disease2/effect/d in effects) + types += d.type + for(var/datum/disease2/effect/d in disease.effects) + if(!(d.type in types)) + return 0 + + if (antigen != disease.antigen) + return 0 + +/proc/virus_copylist(list/datum/disease2/disease/viruses) + var/list/res = list() + for (var/ID in viruses) + var/datum/disease2/disease/V = viruses[ID] + res["[V.uniqueID]"] = V.getcopy() + return res + + +var/global/list/virusDB = list() +/datum/disease2/disease/proc/add_zero(t, u) + return pad_left(t, u, "0") + +/datum/disease2/disease/proc/name() + .= "strain #[add_zero("[uniqueID]", 4)]" + if ("[uniqueID]" in virusDB) + var/datum/computer_file/data/virus_record/V = virusDB["[uniqueID]"] + .= V.fields["name"] + +/datum/disease2/disease/proc/get_info(skill = HAS_PERK, verbose = 1, given_effects) + if(!given_effects) + given_effects = effects + var/r = list() + if(verbose) + r += "Analysis determined the existence of a GNAv2-based viral lifeform.
    " + r += "Designation: [name()]
    " + r += "Antigen: [antigens2string(antigen)]
    " + r += "Transmitted By: [spreadtype]
    " + else + r = "[name()]" + + var/list/dat = list() + if(skill >= HAS_PERK) + if(verbose) + r += "Rate of Progression: [speed * 100]%
    " + var/species = affected_species.Copy() + r += "Species Affected: [jointext(species, ", ")]
    " + r += "Symptoms:
    " + + for(var/datum/disease2/effect/E in given_effects) + dat += E.get_effect_info(verbose) + + . = verbose ? JOINTEXT(r + dat) : "[r] ([jointext(dat, ", ")])" + + +/datum/disease2/disease/proc/addToDB() + if ("[uniqueID]" in virusDB) + return 0 + var/datum/computer_file/data/virus_record/v = new() + v.fields["id"] = uniqueID + v.fields["name"] = name() + v.fields["description"] = get_info() + v.fields["antigen"] = antigens2string(antigen) + v.fields["spread type"] = spreadtype + virusDB["[uniqueID]"] = v + return 1 + + +/proc/virology_letterhead(report_name) + return {" +

    [report_name]

    +
    [station_name()] Virology Lab
    +
    +"} + +/datum/disease2/disease/proc/can_add_symptom(type) + for(var/datum/disease2/effect/H in effects) + if(H.type == type && !H.allow_multiple) + return 0 + + return 1 diff --git a/mods/virusology/code/diseasesplicer.dm b/mods/virusology/code/diseasesplicer.dm new file mode 100644 index 0000000000000..abbbfd780cc77 --- /dev/null +++ b/mods/virusology/code/diseasesplicer.dm @@ -0,0 +1,188 @@ +/obj/machinery/computer/diseasesplicer + name = "disease splicer" + icon = 'icons/obj/machines/computer.dmi' + icon_keyboard = "med_key" + icon_screen = "crew" + + var/datum/disease2/effect/memorybank = null + var/list/species_buffer = null + var/analysed = 0 + var/obj/item/virusdish/dish = null + var/burning = 0 + var/splicing = 0 + var/scanning = 0 + +/obj/machinery/computer/diseasesplicer/use_tool(obj/item/I, mob/living/user, list/click_params) + . = ..() + if(isScrewdriver(I)) + return ..(I,user) + + if(istype(I,/obj/item/virusdish)) + if (dish) + to_chat(user, "\The [src] is already loaded.") + return + if(!user.unEquip(I, src)) + return + dish = I + + if(istype(I,/obj/item/diseasedisk)) + to_chat(user, "You upload the contents of the disk onto the buffer.") + var/obj/item/diseasedisk/disk = I + memorybank = disk.effect + species_buffer = disk.species + analysed = disk.analysed + + src.attack_hand(user) + +/obj/machinery/computer/diseasesplicer/interface_interact(mob/user) + ui_interact(user) + return TRUE + +/obj/machinery/computer/diseasesplicer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) + user.set_machine(src) + + var/data[0] + data["dish_inserted"] = !!dish + data["growth"] = 0 + data["affected_species"] = null + + if (memorybank) + data["buffer"] = list("name" = (analysed ? memorybank.name : "Unknown Symptom"), "stage" = memorybank.stage) + if (species_buffer) + data["species_buffer"] = analysed ? jointext(species_buffer, ", ") : "Unknown Species" + + if (splicing) + data["busy"] = "Splicing..." + else if (scanning) + data["busy"] = "Scanning..." + else if (burning) + data["busy"] = "Copying data to disk..." + else if (dish) + data["growth"] = min(dish.growth, 100) + + if (dish.virus2) + if (dish.virus2.affected_species) + data["affected_species"] = dish.analysed ? jointext(dish.virus2.affected_species, ", ") : "Unknown" + + if (dish.growth >= 50) + var/list/effects[0] + for (var/datum/disease2/effect/e in dish.virus2.effects) + effects.Add(list(list("name" = (dish.analysed ? e.name : "Unknown"), "stage" = (e.stage), "reference" = "\ref[e]"))) + data["effects"] = effects + else + data["info"] = "Insufficient cell growth for gene splicing." + else + data["info"] = "No virus detected." + else + data["info"] = "No dish loaded." + + ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "mods-disease_splicer.tmpl", src.name, 400, 600) + ui.set_initial_data(data) + ui.open() + +/obj/machinery/computer/diseasesplicer/Process() + if(stat & (MACHINE_STAT_NOPOWER|MACHINE_IS_BROKEN(src))) + return + + if(scanning) + scanning -= 1 + if(!scanning) + ping("\The [src] pings, \"Analysis complete.\"") + SSnano.update_uis(src) + if(splicing) + splicing -= 1 + if(!splicing) + ping("\The [src] pings, \"Splicing operation complete.\"") + SSnano.update_uis(src) + if(burning) + burning -= 1 + if(!burning) + var/obj/item/diseasedisk/d = new /obj/item/diseasedisk(src.loc) + d.analysed = analysed + if(analysed) + if (memorybank) + d.SetName("[memorybank.name] GNA disk (Stage: [memorybank.stage])") + d.effect = memorybank + else if (species_buffer) + d.SetName("[jointext(species_buffer, ", ")] GNA disk") + d.species = species_buffer + else + if (memorybank) + d.SetName("Unknown GNA disk (Stage: [memorybank.stage])") + d.effect = memorybank + else if (species_buffer) + d.SetName("Unknown Species GNA disk") + d.species = species_buffer + + ping("\The [src] pings, \"Backup disk saved.\"") + SSnano.update_uis(src) + + if((scanning || splicing || burning) && dish && dish.virus2) + infect_nearby(dish.virus2, 80) + +/obj/machinery/computer/diseasesplicer/OnTopic(mob/user, href_list) + operator_skill = user.get_skill_value(core_skill) + if (href_list["close"]) + SSnano.close_user_uis(user, src, "main") + return TOPIC_HANDLED + + if (href_list["grab"]) + if (dish) + memorybank = locate(href_list["grab"]) + species_buffer = null + analysed = dish.analysed + dish = null + scanning = 10 + return TOPIC_REFRESH + + if (href_list["affected_species"]) + if (dish) + memorybank = null + species_buffer = dish.virus2.affected_species + analysed = dish.analysed + dish = null + scanning = 10 + return TOPIC_REFRESH + + if(href_list["eject"]) + if (dish) + dish.dropInto(loc) + dish = null + return TOPIC_REFRESH + + if(href_list["splice"]) + if(dish) + var/target = text2num(href_list["splice"]) // target = 1+ for effects, -1 for species + if(memorybank && target > 0) + if(target < memorybank.stage) + return // too powerful, catching this for href exploit prevention + + var/datum/disease2/effect/target_effect + var/list/illegal_types = list() + for(var/datum/disease2/effect/e in dish.virus2.effects) + if(e.stage == target) + target_effect = e + if(!e.allow_multiple) + illegal_types += e.type + if(memorybank.type in illegal_types) + to_chat(user, "Virus DNA can't hold more than one [memorybank]") + return 1 + dish.virus2.effects -= target_effect + dish.virus2.effects += memorybank + qdel(target_effect) + + else if(species_buffer && target == -1) + dish.virus2.affected_species = species_buffer + + else + return TOPIC_HANDLED + + splicing = 10 + dish.virus2.uniqueID = rand(0,10000) + return TOPIC_REFRESH + + if(href_list["disk"]) + burning = 10 + return TOPIC_REFRESH diff --git a/mods/virusology/code/dishincubator.dm b/mods/virusology/code/dishincubator.dm new file mode 100644 index 0000000000000..48c5a4aa46da2 --- /dev/null +++ b/mods/virusology/code/dishincubator.dm @@ -0,0 +1,199 @@ +/obj/machinery/disease2/incubator/ + name = "pathogenic incubator" + icon = 'mods/virusology/icons/virology.dmi' + icon_state = "incubator" + var/obj/item/virusdish/dish + var/obj/item/reagent_containers/glass/beaker = null + var/radiation = 0 + density = TRUE + var/on = 0 + var/power = 0 + + var/foodsupply = 0 + var/toxins = 0 + +/obj/machinery/disease2/incubator/use_tool(obj/item/O, mob/living/user, list/click_params) + . = ..() + if(istype(O, /obj/item/reagent_containers/glass) || istype(O, /obj/item/reagent_containers/syringe)) + + if(beaker) + to_chat(user, "\The [src] is already loaded.") + return + if(!user.unEquip(O, src)) + return + beaker = O + + user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") + SSnano.update_uis(src) + + src.attack_hand(user) + return + + if(istype(O, /obj/item/virusdish)) + + if(dish) + to_chat(user, "The dish tray is already full!") + return + if(!user.unEquip(O, src)) + return + dish = O + + user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") + SSnano.update_uis(src) + + src.attack_hand(user) + +/obj/machinery/disease2/incubator/interface_interact(mob/user) + ui_interact(user) + return TRUE + +/obj/machinery/disease2/incubator/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) + user.set_machine(src) + + var/data[0] + data["chemicals_inserted"] = !!beaker + data["dish_inserted"] = !!dish + data["food_supply"] = foodsupply + data["radiation"] = radiation + data["toxins"] = min(toxins, 100) + data["on"] = on + data["system_in_use"] = foodsupply > 0 || radiation > 0 || toxins > 0 + data["chemical_volume"] = beaker ? beaker.reagents.total_volume : 0 + data["max_chemical_volume"] = beaker ? beaker.volume : 1 + data["virus"] = dish ? dish.virus2 : null + data["growth"] = dish ? min(dish.growth, 100) : 0 + data["infection_rate"] = dish && dish.virus2 ? dish.virus2.infectionchance * 10 : 0 + data["analysed"] = dish && dish.analysed ? 1 : 0 + data["can_breed_virus"] = null + data["blood_already_infected"] = null + + if (beaker) + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in beaker.reagents.reagent_list + data["can_breed_virus"] = dish && dish.virus2 && B + + if (B) + if (!B.data["virus2"]) + B.data["virus2"] = list() + + var/list/virus = B.data["virus2"] + for (var/ID in virus) + data["blood_already_infected"] = virus[ID] + + ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "mods-dish_incubator.tmpl", src.name, 400, 600) + ui.set_initial_data(data) + ui.open() + +/obj/machinery/disease2/incubator/Process() + ..() + if(dish && on && dish.virus2) + use_power_oneoff(50,EQUIP) + if(!powered(EQUIP)) + on = 0 + icon_state = "incubator" + + var/threshold_mod = 0 + + if(foodsupply) + if(dish.growth + 3 >= 100 && dish.growth < 100) + ping("\The [src] pings, \"Sufficient viral growth density achieved.\"") + + foodsupply -= 1 + dish.growth += 3 + SSnano.update_uis(src) + + if(radiation) + threshold_mod++ + if(radiation > 50 & prob(5)) + dish.virus2.majormutate() + if(dish.info) + dish.info = "OUTDATED : [dish.info]" + dish.basic_info = "OUTDATED: [dish.basic_info]" + dish.analysed = 0 + ping("\The [src] pings, \"Mutant viral strain detected.\"") + else if(prob(5)) + dish.virus2.minormutate() + radiation -= 1 + SSnano.update_uis(src) + if(toxins && prob(5)) + dish.virus2.infectionchance -= 1 + SSnano.update_uis(src) + if(toxins > 50) + dish.growth = 0 + dish.virus2 = null + SSnano.update_uis(src) + infect_nearby(dish.virus2, 20 * 2**threshold_mod) + else if(!dish) + on = 0 + icon_state = "incubator" + SSnano.update_uis(src) + + if(beaker) + if (foodsupply < 100 && beaker.reagents.has_reagent(/datum/reagent/nutriment/virus_food)) + var/food_needed = min(10, 100 - foodsupply) / 2 + var/food_taken = min(food_needed, beaker.reagents.get_reagent_amount(/datum/reagent/nutriment/virus_food)) + + beaker.reagents.remove_reagent(/datum/reagent/nutriment/virus_food, food_taken) + foodsupply = min(100, foodsupply+(food_taken * 2)) + SSnano.update_uis(src) + + if ((locate(/datum/reagent/toxin) in beaker.reagents.reagent_list) && toxins < 100) + for(var/datum/reagent/toxin/T in beaker.reagents.reagent_list) + toxins += max(T.strength,1) + beaker.reagents.remove_reagent(T.type,1) + if(toxins > 100) + toxins = 100 + break + SSnano.update_uis(src) + +/obj/machinery/disease2/incubator/OnTopic(mob/user, href_list) + operator_skill = user.get_skill_value(core_skill) + if (href_list["close"]) + SSnano.close_user_uis(user, src, "main") + return TOPIC_HANDLED + + if (href_list["ejectchem"]) + if(beaker) + beaker.dropInto(loc) + beaker = null + return TOPIC_REFRESH + + if (href_list["power"]) + if (dish) + on = !on + icon_state = on ? "incubator_on" : "incubator" + return TOPIC_REFRESH + + if (href_list["ejectdish"]) + if(dish) + dish.dropInto(loc) + dish = null + return TOPIC_REFRESH + + if (href_list["rad"]) + radiation = min(100, radiation + 10) + return TOPIC_REFRESH + + if (href_list["flush"]) + radiation = 0 + toxins = 0 + foodsupply = 0 + return TOPIC_REFRESH + + if(href_list["virus"]) + if (!dish) + return TOPIC_HANDLED + + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in beaker.reagents.reagent_list + if (!B) + return TOPIC_HANDLED + + if (!B.data["virus2"]) + B.data["virus2"] = list() + + var/list/virus = list("[dish.virus2.uniqueID]" = dish.virus2.getcopy()) + B.data["virus2"] += virus + + ping("\The [src] pings, \"Injection complete.\"") + return TOPIC_REFRESH diff --git a/mods/virusology/code/effect.dm b/mods/virusology/code/effect.dm new file mode 100644 index 0000000000000..461d6584e6f32 --- /dev/null +++ b/mods/virusology/code/effect.dm @@ -0,0 +1,341 @@ +//////////////////////////////////////////////////////////////// +////////////////////////EFFECTS///////////////////////////////// +//////////////////////////////////////////////////////////////// +/proc/get_random_virus2_effect(stage, badness, exclude) + var/list/datum/disease2/effect/candidates = list() + for(var/T in subtypesof(/datum/disease2/effect)) + var/datum/disease2/effect/E = T + if(E in exclude) + continue + if(initial(E.badness) > badness) //we don't want such strong effects + continue + if(initial(E.stage) <= stage) + candidates += T + var/type = pick(candidates) + var/datum/disease2/effect/effect = new type + effect.generate() + effect.chance = rand(0,effect.chance_max) + effect.multiplier = rand(1,effect.multiplier_max) + return effect + +/datum/disease2/effect + var/name = "Blanking effect" + var/chance //probality to fire every tick + var/chance_max = 50 + var/multiplier = 1 //effect magnitude multiplier + var/multiplier_max = 1 + var/stage = 4 //minimal stage + var/badness = VIRUS_MILD //Used in random generation to limit how bad result should come out. + var/data = null //For semi-procedural effects; this should be generated in generate() if used + var/oneshot + var/delay = 5 SECONDS //minimal time between activations + var/hold_until //can only fire after this worldtime + var/allow_multiple //allow to have more than 1 effect of this type in the same virus + +/datum/disease2/effect/proc/get_effect_info(verbose = 1) + . = list() + if(verbose) + . += "([stage]) [name] " + . += "Strength: [multiplier >= 3 ? "Severe" : multiplier > 1 ? "Above Average" : "Average"] " + . += "Verosity: [chance * 10]
    " + else + . += name + return JOINTEXT(.) + +/datum/disease2/effect/proc/fire(mob/living/carbon/human/mob,current_stage) + if(oneshot == -1) + return + if(hold_until > world.time) + return + if(mob.chem_effects[CE_ANTIVIRAL] >= badness) + return + if(stage <= current_stage && prob(chance)) + hold_until = world.time + delay + activate(mob) + if(oneshot == 1) + oneshot = -1 + +/datum/disease2/effect/proc/minormutate() + switch(pick(1,2,3,4,5)) + if(1) + chance = rand(0,chance_max) + if(2) + multiplier = rand(1,multiplier_max) + +/datum/disease2/effect/proc/activate(mob/living/carbon/human/mob) +/datum/disease2/effect/proc/deactivate(mob/living/carbon/human/mob) +/datum/disease2/effect/proc/generate(copy_data) // copy_data will be non-null if this is a copy; it should be used to initialise the data for this effect if present + +/datum/disease2/effect/invisible + name = "Waiting Syndrome" + stage = 1 + +/datum/disease2/effect/killertoxins + name = "Toxification Syndrome" + stage = 4 + badness = VIRUS_COMMON +/datum/disease2/effect/killertoxins/activate(mob/living/carbon/human/mob, multiplier) + mob.adjustToxLoss(15*multiplier) + +/datum/disease2/effect/dna + name = "Reverse Pattern Syndrome" + stage = 4 + badness = VIRUS_ENGINEERED +/datum/disease2/effect/dna/activate(mob/living/carbon/human/mob, multiplier) + mob.bodytemperature = max(mob.bodytemperature, 350) + scramble(0,mob,10) + mob.apply_damage(10, DAMAGE_GENETIC) + +/datum/disease2/effect/organs + name = "Shutdown Syndrome" + stage = 4 + badness = VIRUS_ENGINEERED +/datum/disease2/effect/organs/activate(mob/living/carbon/human/mob, multiplier) + var/organ = pick(list(BP_R_ARM,BP_L_ARM,BP_R_LEG,BP_L_LEG)) + var/obj/item/organ/external/E = mob.organs_by_name[organ] + if (!(E.status & ORGAN_DEAD)) + E.status |= ORGAN_DEAD + to_chat(mob, "You can't feel your [E.name] anymore...") + for (var/obj/item/organ/external/C in E.children) + C.status |= ORGAN_DEAD + mob.update_body(1) + mob.adjustToxLoss(15*multiplier) + +/datum/disease2/effect/organs/deactivate(mob/living/carbon/human/mob, multiplier) + for (var/obj/item/organ/external/E in mob.organs) + E.status &= ~ORGAN_DEAD + for (var/obj/item/organ/external/C in E.children) + C.status &= ~ORGAN_DEAD + mob.update_body(1) + +/datum/disease2/effect/immortal + name = "Longevity Syndrome" + stage = 4 + badness = VIRUS_ENGINEERED +/datum/disease2/effect/immortal/activate(mob/living/carbon/human/mob, multiplier) + for (var/external in mob.organs) + var/obj/item/organ/external/E = external + if (E.status & ORGAN_BROKEN && prob(30)) + to_chat(mob, "Your [E.name] suddenly feels much better!") + E.status ^= ORGAN_BROKEN + break + for (var/internal in mob.internal_organs) + var/obj/item/organ/internal/I = internal + if (I.damage && prob(30)) + to_chat(mob, "Your [mob.get_organ(I.parent_organ)] feels a bit warm...") + I.take_internal_damage(-2*multiplier) + break + var/heal_amt = -5*multiplier + mob.apply_damages(heal_amt,heal_amt,heal_amt,heal_amt) + +/datum/disease2/effect/immortal/deactivate(mob/living/carbon/human/mob, multiplier) + to_chat(mob, "You suddenly feel hurt and old...") + mob.age += 8 + var/backlash_amt = 5*multiplier + mob.apply_damages(backlash_amt,backlash_amt,backlash_amt,backlash_amt) + +/datum/disease2/effect/bones + name = "Fragile Bones Syndrome" + stage = 4 + badness = VIRUS_ENGINEERED +/datum/disease2/effect/bones/activate(mob/living/carbon/human/mob, multiplier) + for (var/obj/item/organ/external/E in mob.organs) + E.min_broken_damage = max(5, E.min_broken_damage - 30) + +/datum/disease2/effect/bones/deactivate(mob/living/carbon/human/mob, multiplier) + for (var/obj/item/organ/external/E in mob.organs) + E.min_broken_damage = initial(E.min_broken_damage) + +////////////////////////STAGE 3///////////////////////////////// + +/datum/disease2/effect/toxins + name = "Hyperacidity" + stage = 3 + multiplier_max = 3 + badness = VIRUS_COMMON +/datum/disease2/effect/toxins/activate(mob/living/carbon/human/mob, multiplier) + mob.adjustToxLoss((2*multiplier)) + +/datum/disease2/effect/shakey + name = "World Shaking Syndrome" + stage = 3 + multiplier_max = 3 +/datum/disease2/effect/shakey/activate(mob/living/carbon/human/mob, multiplier) + shake_camera(mob,5*multiplier) + +/datum/disease2/effect/mind + name = "Lazy Mind Syndrome" + stage = 3 + badness = VIRUS_COMMON +/datum/disease2/effect/mind/activate(mob/living/carbon/human/mob, multiplier) + var/obj/item/organ/internal/brain/B = mob.internal_organs_by_name[BP_BRAIN] + if (B && B.damage < B.min_broken_damage) + B.take_internal_damage(5) + +/datum/disease2/effect/deaf + name = "Hard of Hearing Syndrome" + stage = 3 +/datum/disease2/effect/deaf/activate(mob/living/carbon/human/mob, multiplier) + mob.ear_deaf = 5 + +/datum/disease2/effect/confusion + name = "Topographical Cretinism" + stage = 3 +/datum/disease2/effect/confusion/activate(mob/living/carbon/human/M, multiplier) + to_chat(M, "You have trouble telling right and left apart all of a sudden.") + M.mod_confused(40) + +/datum/disease2/effect/mutation + name = "DNA Degradation" + stage = 3 + badness = VIRUS_COMMON +/datum/disease2/effect/mutation/activate(mob/living/carbon/human/mob, multiplier) + mob.apply_damage(2, DAMAGE_GENETIC) + +/datum/disease2/effect/chem_synthesis + name = "Chemical Synthesis" + stage = 3 + badness = VIRUS_COMMON + chance_max = 25 + +/datum/disease2/effect/chem_synthesis/generate(c_data) + if(c_data) + data = c_data + else + data = pick(/datum/reagent/bicaridine, /datum/reagent/kelotane, /datum/reagent/dylovene, /datum/reagent/inaprovaline, /datum/reagent/drugs/psilocybin, /datum/reagent/sugar, + /datum/reagent/tramadol, /datum/reagent/dexalin, /datum/reagent/drugs/cryptobiolin, /datum/reagent/impedrezene, /datum/reagent/hyperzine, /datum/reagent/ethylredoxrazine, + /datum/reagent/drugs/mindbreaker, /datum/reagent/nutriment/glucose) + var/datum/reagent/R = data + name = "[initial(name)] ([initial(R.name)])" + +/datum/disease2/effect/chem_synthesis/activate(mob/living/carbon/human/mob, multiplier) + if (mob.reagents.get_reagent_amount(data) < 5) + mob.reagents.add_reagent(data, 2) + +/datum/disease2/effect/nothing + name = "Nil Syndrome" + stage = 1 + badness = VIRUS_MILD + chance_max = 0 + allow_multiple = 1 + +////////////////////////STAGE 2///////////////////////////////// +/datum/disease2/effect/drowsness + name = "Automated Sleeping Syndrome" + stage = 2 +/datum/disease2/effect/drowsness/activate(mob/living/carbon/human/mob, multiplier) + mob.drowsyness = min(mob.drowsyness + 10, 50) + +/datum/disease2/effect/sleepy + name = "Resting Syndrome" + stage = 2 + chance_max = 15 + delay = 35 SECONDS +/datum/disease2/effect/sleepy/activate(mob/living/carbon/human/mob, multiplier) + mob.emote("collapse") + +/datum/disease2/effect/blind + name = "Blackout Syndrome" + stage = 2 + badness = VIRUS_COMMON +/datum/disease2/effect/blind/activate(mob/living/carbon/human/mob, multiplier) + mob.eye_blind = max(mob.eye_blind, 4) + +/datum/disease2/effect/cough + name = "Anima Syndrome" + stage = 2 + delay = 25 SECONDS +/datum/disease2/effect/cough/activate(mob/living/carbon/human/mob, multiplier) + mob.emote("cough") + if (mob.wear_mask) + return + for(var/mob/living/carbon/human/M in oview(2,mob)) + mob.spread_disease_to(M) + +/datum/disease2/effect/hungry + name = "Appetiser Effect" + stage = 2 +/datum/disease2/effect/hungry/activate(mob/living/carbon/human/mob, multiplier) + mob.adjust_nutrition(-200) + +/datum/disease2/effect/fridge + name = "Refridgerator Syndrome" + stage = 2 + chance_max = 25 + delay = 25 SECONDS +/datum/disease2/effect/fridge/activate(mob/living/carbon/human/mob, multiplier) + mob.emote("shiver") + +/datum/disease2/effect/stimulant + name = "Adrenaline Extra" + stage = 2 + badness = VIRUS_COMMON +/datum/disease2/effect/stimulant/activate(mob/living/carbon/human/mob, multiplier) + to_chat(mob, "You feel a rush of energy inside you!") + if (mob.reagents.get_reagent_amount(/datum/reagent/hyperzine) < 10) + mob.reagents.add_reagent(/datum/reagent/hyperzine, 4) + if (prob(30)) + mob.jitteriness = min(mob.jitteriness + 10, 500) + +////////////////////////STAGE 1///////////////////////////////// + +/datum/disease2/effect/sneeze + name = "Coldingtons Effect" + stage = 1 + delay = 15 SECONDS + +/datum/disease2/effect/sneeze/activate(mob/living/carbon/human/mob, multiplier) + if (prob(30)) + to_chat(mob, "You feel like you are about to sneeze!") + sleep(5) + mob.emote("sneeze") + for(var/mob/living/carbon/human/M in get_step(mob,mob.dir)) + mob.spread_disease_to(M) + if (prob(50) && !mob.wear_mask) + var/obj/decal/cleanable/mucus/M = new(get_turf(mob)) + M.virus2 = virus_copylist(mob.virus2) + +/datum/disease2/effect/gunck + name = "Flemmingtons" + stage = 1 + delay = 25 SECONDS +/datum/disease2/effect/gunck/activate(mob/living/carbon/human/mob, multiplier) + to_chat(mob, "Mucous runs down the back of your throat.") + +/datum/disease2/effect/drool + name = "Saliva Effect" + stage = 1 + chance_max = 25 + delay = 25 SECONDS +/datum/disease2/effect/drool/activate(mob/living/carbon/human/mob, multiplier) + mob.emote("drool") + +/datum/disease2/effect/twitch + name = "Twitcher" + stage = 1 + chance_max = 25 + delay = 25 SECONDS +/datum/disease2/effect/twitch/activate(mob/living/carbon/human/mob, multiplier) + mob.emote("twitch") + +/datum/disease2/effect/headache + name = "Headache" + stage = 1 + delay = 25 SECONDS +/datum/disease2/effect/headache/activate(mob/living/carbon/human/mob, multiplier) + mob.custom_pain("Your head hurts a bit.", 20) + +/datum/disease2/effect/itch + name = "Itches" + stage = 1 + delay = 25 SECONDS +/datum/disease2/effect/itch/activate(mob/living/carbon/human/mob, multiplier) + var/obj/O = pick(mob.organs) + to_chat(mob, "Your [O.name] itches like hell.") + +/datum/disease2/effect/stomach + name = "Upset stomach" + stage = 1 + delay = 25 SECONDS +/datum/disease2/effect/stomach/activate(mob/living/carbon/human/mob, multiplier) + to_chat(mob, "Your stomach feels heavy.") diff --git a/mods/virusology/code/general.dm b/mods/virusology/code/general.dm new file mode 100644 index 0000000000000..18d2b5f4dd779 --- /dev/null +++ b/mods/virusology/code/general.dm @@ -0,0 +1,236 @@ +/datum/species + var/virus_immune + +/datum/species/adherent + virus_immune = 1 + +/datum/species/machine + virus_immune = 1 + +/datum/species/shapeshifter/promethean + virus_immune = 1 + +/datum/species/proc/get_virus_immune(mob/living/carbon/human/H) + return ((H && H.isSynthetic()) ? 1 : virus_immune) + +/// +// pure concentrated antibodies +/datum/reagent/antibodies + data = list("antibodies"=list()) + name = "Antibodies" + taste_description = "slime" + reagent_state = LIQUID + color = "#0050f0" + value = 6 + +/datum/reagent/antibodies/affect_blood(mob/living/carbon/M, alien, removed) + if(src.data) + M.antibodies |= src.data["antibodies"] + ..() + +/datum/reagent/radium/affect_blood(mob/living/carbon/M, alien, removed) + .=..() + if(LAZYLEN(M.virus2)) + for(var/ID in M.virus2) + var/datum/disease2/disease/V = M.virus2[ID] + if(prob(5)) + M.antibodies |= V.antigen + if(prob(50)) + M.apply_damage(50, DAMAGE_RADIATION, armor_pen = 100) // curing it that way may kill you instead + var/absorbed = 0 + var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in M.internal_organs + if(rad_organ && !rad_organ.is_broken()) + absorbed = 1 + if(!absorbed) + M.adjustToxLoss(100) + + +/datum/reagent/nutriment/virus_food + name = "Virus Food" + description = "A mixture of water, milk, and oxygen. Virus cells can use this mixture to reproduce." + taste_description = "vomit" + taste_mult = 2 + reagent_state = LIQUID + nutriment_factor = 2 + color = "#899613" + + + +/singleton/reaction/virus_food + name = "Virus Food" + result = /datum/reagent/nutriment/virus_food + required_reagents = list(/datum/reagent/water = 1, /datum/reagent/drink/milk = 1) + result_amount = 5 + mix_message = "The water dilutes the milk into a thin white solution." + + +/obj/structure/reagent_dispensers/virusfood + name = "virus food dispenser" + desc = "A dispenser of virus food." + icon = 'mods/virusology/icons/virology.dmi' + icon_state = "virusfoodtank" + amount_per_transfer_from_this = 10 + initial_reagent_types = list(/datum/reagent/nutriment/virus_food = 1) + + + +/obj/item/stock_parts/circuitboard/curefab + name = "circuit board (cure fabricator)" + build_path = /obj/machinery/computer/curer + +/obj/item/stock_parts/circuitboard/splicer + name = "circuit board (disease splicer)" + build_path = /obj/machinery/computer/diseasesplicer + origin_tech = list(TECH_DATA = 5, TECH_BIO = 5) + +/obj/item/stock_parts/circuitboard/centrifuge + name = "circuit board (isolation centrifuge)" + build_path = /obj/machinery/computer/centrifuge + origin_tech = list(TECH_DATA = 2, TECH_BIO = 3) + +/datum/design/circuit/curefab + name = "cure fabricator" + id = "curefab" + req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 5) + build_path = /obj/item/stock_parts/circuitboard/curefab + sort_string = "FACAI" + +/datum/design/circuit/centrifuge + name = "isolation centrifuge console" + id = "iso_centrifuge" + req_tech = list(TECH_DATA = 2, TECH_BIO = 3) + build_path = /obj/item/stock_parts/circuitboard/centrifuge + sort_string = "FACAG" + +/datum/design/circuit/splicer + name = "disease splicer" + id = "isplicer" + req_tech = list(TECH_DATA = 5, TECH_BIO = 5) + build_path = /obj/item/stock_parts/circuitboard/splicer + sort_string = "FACAH" + +/mob/living/carbon/ + var/list/datum/disease2/disease/virus2 = list() + var/list/antibodies = list() + + +/datum/goal/sickness + description = "Don't get sick! Avoid catching any viruses during the shift." + var/got_sick + var/announced + +/datum/goal/sickness/check_success() + return !got_sick + +/datum/goal/sickness/update_progress(progress) + if(!got_sick) + got_sick = progress + if(got_sick) + addtimer(new Callback(src, PROC_REF(on_completion), rand(30,40))) + +/datum/goal/sickness/on_completion() + if(!announced) + announced = TRUE + var/datum/mind/mind = owner + to_chat(mind.current, SPAN_DANGER("You don't feel so good...")) + +/obj/decal/cleanable/blood + var/list/viruses = list() + var/list/datum/disease2/disease/virus2 = list() + +/obj/decal/cleanable/vomit + var/list/viruses = list() + +/obj/decal/cleanable/mucus + name = "mucus" + desc = "Disgusting mucus." + gender = PLURAL + density = FALSE + anchored = TRUE + layer = 2 + icon = 'icons/effects/blood.dmi' + icon_state = "mucus" + var/list/datum/disease2/disease/virus2 = list() + + +/obj/decal/cleanable/mucus/New() + . = ..() + addtimer(new Callback(src, PROC_REF(set_dry), 1), DRYING_TIME * 2) + +/mob/living/carbon/human/proc/cure_virus(virus_uuid) + if(vessel && virus_uuid) + for(var/datum/reagent/blood/B in vessel.reagent_list) + var/list/viruses = list() + viruses = B.data["virus2"] + viruses.Remove("[virus_uuid]") + B.data["virus2"] = viruses + + +/singleton/hierarchy/supply_pack/science/virus + name = "Samples - Virus (BIOHAZARD)" + contains = list(/obj/item/virusdish/random = 4) + cost = 25 + containertype = /obj/structure/closet/crate/secure + containername = "virus sample crate" + access = access_virology + + +/datum/controller/subsystem/supply + var/list/sold_virus_strains = list() + +/datum/reagent/blood/affect_touch(mob/living/carbon/M, alien, removed) + .=..() + if(data && data["virus2"]) + var/list/vlist = data["virus2"] + if(LAZYLEN(vlist)) + for(var/ID in vlist) + var/datum/disease2/disease/V = vlist[ID] + if(V.spreadtype == "Contact") + infect_virus2(M, V.getcopy()) + if(data && data["antibodies"]) + M.antibodies |= data["antibodies"] + +/datum/reagent/blood/affect_ingest(mob/living/carbon/M, removed) + .=..() + if(data && data["virus2"]) + var/list/vlist = data["virus2"] + if(LAZYLEN(vlist)) + for(var/ID in vlist) + var/datum/disease2/disease/V = vlist[ID] + if(V && V.spreadtype == "Contact") + infect_virus2(M, V.getcopy()) + +/datum/reagent/blood/mix_data(newdata, newamount) + if(!islist(newdata)) + return + if(!data["virus2"]) + data["virus2"] = list() + data["virus2"] |= newdata["virus2"] + if(!data["antibodies"]) + data["antibodies"] = list() + data["antibodies"] |= newdata["antibodies"] + +/mob/living/carbon/take_blood(obj/item/reagent_containers/container, amount) + .=..() + var/datum/reagent/blood/B = get_blood(container.reagents) + if (!B.data["virus2"]) + B.data["virus2"] = list() + B.data["virus2"] |= virus_copylist(virus2) + B.data["antibodies"] = antibodies + +/mob/living/carbon/inject_blood(datum/reagent/blood/injected, amount) + .=..() + var/list/sniffles = virus_copylist(injected.data["virus2"]) + for(var/ID in sniffles) + var/datum/disease2/disease/sniffle = sniffles[ID] + infect_virus2(src, sniffle, 1) + + if(injected.data["antibodies"] && prob(5)) + antibodies |= injected.data["antibodies"] + +/mob/living/carbon/human/handle_post_breath(datum/gas_mixture/breath) + .=..() + //spread some viruses while we are at it + if(breath && !internal && LAZYLEN(virus2) > 0 && prob(10)) + for(var/mob/living/carbon/M in view(1,src)) + src.spread_disease_to(M) diff --git a/mods/virusology/code/helpers.dm b/mods/virusology/code/helpers.dm new file mode 100644 index 0000000000000..fd670b03c9374 --- /dev/null +++ b/mods/virusology/code/helpers.dm @@ -0,0 +1,201 @@ +/obj/machinery/disease2 + core_skill = SKILL_VIROLOGY + +/obj/machinery/proc/infect_nearby(datum/disease2/disease/disease, base_chance = 20, dist = 2) + if(istype(disease) && operator_skill <= HAS_PERK) + for(var/mob/living/carbon/victim in range(dist, src)) + if(prob(base_chance)) + if(victim.skill_check(SKILL_VIROLOGY, HAS_PERK)) + if(prob(50)) + infect_virus2(victim, disease) + else + return + else + infect_virus2(victim, disease) + +//Returns 1 if mob can be infected, 0 otherwise. +/proc/infection_chance(mob/living/carbon/M, vector = "Airborne") + if (!istype(M)) + return 0 + + var/mob/living/carbon/human/H = M + if(istype(H) && H.species.get_virus_immune(H)) + return 0 + + var/protection = M.get_blocked_ratio(null, DAMAGE_BIO, damage_flags = DAMAGE_FLAG_DISPERSED | DAMAGE_FLAG_BIO) //gets the full body bio armour value, weighted by body part coverage. + var/score = round(6 * protection) //scales 100% protection to 6. + + switch(vector) + if("Airborne") + if(M.internal) //not breathing infected air helps greatly + return 0 + var/obj/item/I = M.wear_mask + //masks provide a small bonus and can replace overall bio protection + if(I) + var/datum/extension/armor/armor_datum = get_extension(I, /datum/extension/armor) + if(armor_datum) + score = max(score, round(0.06*armor_datum.get_value("bio"))) + if (istype(I, /obj/item/clothing/mask)) + score += 1 //this should be added after + + if("Contact") + if(istype(H)) + //gloves provide a larger bonus + if (istype(H.gloves, /obj/item/clothing/gloves)) + score += 2 + + switch(score) + if (6 to INFINITY) + return 0 + if (5) + return 1 + if (4) + return 5 + if (3) + return 25 + if (2) + return 45 + if (1) + return 65 + else + return 100 + +//Similar to infection check, but used for when M is spreading the virus. +/proc/infection_spreading_check(mob/living/carbon/M, vector = "Airborne") + if (!istype(M)) + return 0 + + var/protection = M.get_blocked_ratio(null, DAMAGE_BIO, damage_flags = DAMAGE_FLAG_BIO | DAMAGE_FLAG_DISPERSED) //gets the full body bio armour value, weighted by body part coverage. + + if (vector == "Airborne") //for airborne infections face-covering items give non-weighted protection value. + if(M.internal) + return 1 + protection = max(protection, M.get_blocked_ratio(BP_HEAD, DAMAGE_BIO, damage_flags = DAMAGE_FLAG_BIO)) + + return prob(100 * protection + 15*M.chem_effects[CE_ANTIVIRAL]) + +/proc/airborne_can_reach(turf/simulated/source, turf/simulated/target) + //Can't ariborne without air + if(is_below_sound_pressure(source) || is_below_sound_pressure(target)) + return FALSE + //no infecting from other side of the hallway + if(get_dist(source,target) > 4) + return FALSE + if(istype(source) && istype(target)) + return source.zone == target.zone + +//Attemptes to infect mob M with virus. Set forced to 1 to ignore protective clothnig +/proc/infect_virus2(mob/living/carbon/M, datum/disease2/disease/disease, forced = 0) + if(!istype(disease)) +// log_debug("Bad virus") + return + if(!istype(M)) +// log_debug("Bad mob") + return + if ("[disease.uniqueID]" in M.virus2) + return + if(LAZYLEN(M.virus2) >= 3) // cap the number of viruses a mob can have to 3 + return + // if one of the antibodies in the mob's body matches one of the disease's antigens, don't infect + var/list/antibodies_in_common = M.antibodies & disease.antigen + if(LAZYLEN(antibodies_in_common)) + return + if(prob(100 * M.reagents.get_reagent_amount(/datum/reagent/spaceacillin) / (REAGENTS_OVERDOSE/2))) + return + + if(!LAZYLEN(disease.affected_species)) + return + + if (!(M.species.get_bodytype(M) in disease.affected_species)) + if (forced) + disease.affected_species[1] = M.species.get_bodytype(M) + else + return //not compatible with this species + +// log_debug("Infecting [M]") + var/mob_infection_prob = infection_chance(M, disease.spreadtype) * M.immunity_weakness() + if(forced || (prob(disease.infectionchance) && prob(mob_infection_prob))) + var/datum/disease2/disease/D = disease.getcopy() + if(rand(1, 50) == 1) + D.minormutate() +// log_debug("Adding virus") + M.virus2["[D.uniqueID]"] = D + SET_BIT(M.hud_updateflag, STATUS_HUD) + M.update_personal_goal(/datum/goal/sickness, TRUE) + +//Infects mob M with random lesser disease, if he doesn't have one +/proc/infect_mob_random_lesser(mob/living/carbon/M) + var/datum/disease2/disease/D = new /datum/disease2/disease + + D.makerandom(VIRUS_MILD) + infect_virus2(M, D, 1) + +//Infects mob M with random greated disease, if he doesn't have one +/proc/infect_mob_random_greater(mob/living/carbon/M) + var/datum/disease2/disease/D = new /datum/disease2/disease + + D.makerandom(VIRUS_COMMON) + infect_virus2(M, D, 1) + +//Fancy prob() function. +/proc/dprob(p) + return(prob(sqrt(p)) && prob(sqrt(p))) + +/mob/living/carbon/proc/spread_disease_to(mob/living/carbon/victim, vector = "Airborne") + if (src == victim) + return "retardation" + +// log_debug("Spreading [vector] diseases from [src] to [victim]") + if (LAZYLEN(virus2) > 0) + for (var/ID in virus2) +// log_debug("Attempting virus [ID]") + var/datum/disease2/disease/V = virus2[ID] + if(V.spreadtype != vector) continue + + //It's hard to get other people sick if you're in an airtight suit. + if(!infection_spreading_check(src, V.spreadtype)) continue + + if (vector == "Airborne") + if(airborne_can_reach(get_turf(src), get_turf(victim))) +// log_debug("In range, infecting") + infect_virus2(victim,V) +// else +// log_debug("Could not reach target") + + if (vector == "Contact") + if (Adjacent(victim)) +// log_debug("In range, infecting") + infect_virus2(victim,V) + + //contact goes both ways + if (LAZYLEN(victim.virus2) > 0 && vector == "Contact" && Adjacent(victim)) +// log_debug("Spreading [vector] diseases from [victim] to [src]") + var/nudity = 1 + + if (ishuman(victim)) + var/mob/living/carbon/human/H = victim + + //Allow for small chance of touching other zones. + //This is proc is also used for passive spreading so just because they are targeting + //that zone doesn't mean that's necessarily where they will touch. + var/touch_zone = zone_sel ? zone_sel.selecting : "chest" + touch_zone = ran_zone(touch_zone, 80) + var/obj/item/organ/external/select_area = H.get_organ(touch_zone) + if(!select_area) + //give it one more chance, since this is also called for passive spreading + select_area = H.get_organ(ran_zone()) + + if(!select_area) + nudity = 0 //cant contact a missing body part + else + var/list/clothes = list(H.head, H.wear_mask, H.wear_suit, H.w_uniform, H.gloves, H.shoes) + for(var/obj/item/clothing/C in clothes) + if(C && istype(C)) + if(C.body_parts_covered & select_area.body_part) + nudity = 0 + if (nudity) + for (var/ID in victim.virus2) + var/datum/disease2/disease/V = victim.virus2[ID] + if(V && V.spreadtype != vector) continue + if(!infection_spreading_check(victim, V.spreadtype)) continue + infect_virus2(src,V) diff --git a/mods/virusology/code/isolator.dm b/mods/virusology/code/isolator.dm new file mode 100644 index 0000000000000..e395f040e5ded --- /dev/null +++ b/mods/virusology/code/isolator.dm @@ -0,0 +1,227 @@ +// UI menu navigation +#define HOME "home" +#define LIST "list" +#define ENTRY "entry" + +/obj/machinery/disease2/isolator/ + name = "pathogenic isolator" + icon = 'mods/virusology/icons/virology.dmi' + icon_state = "isolator" + var/isolating = 0 + var/state = HOME + var/datum/disease2/disease/virus2 = null + var/datum/computer_file/data/virus_record/entry = null + var/obj/item/reagent_containers/syringe/sample = null + density = TRUE + +/obj/machinery/disease2/isolator/on_update_icon() + if(stat & (MACHINE_STAT_NOPOWER|MACHINE_IS_BROKEN(src))) + icon_state = "isolator" + return + + if (isolating) + icon_state = "isolator_processing" + else if (sample) + icon_state = "isolator_in" + else + icon_state = "isolator" + +/obj/machinery/disease2/isolator/use_tool(obj/item/O, mob/living/user, list/click_params) + . = ..() + if(!istype(O,/obj/item/reagent_containers/syringe)) return + if(sample) + to_chat(user, "\The [src] is already loaded.") + return + if(!user.unEquip(O, src)) + return + sample = O + + user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") + SSnano.update_uis(src) + update_icon() + + src.attack_hand(user) + +/obj/machinery/disease2/isolator/interface_interact(mob/user) + ui_interact(user) + return TRUE + +/obj/machinery/disease2/isolator/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) + user.set_machine(src) + + var/data[0] + data["syringe_inserted"] = !!sample + data["isolating"] = isolating + data["pathogen_pool"] = null + data["state"] = state + data["entry"] = entry + data["can_print"] = (state != HOME || sample) && !isolating + + switch (state) + if (HOME) + if (sample) + var/list/pathogen_pool[0] + for(var/datum/reagent/blood/B in sample.reagents.reagent_list) + var/list/virus = B.data["virus2"] + for (var/ID in virus) + var/datum/disease2/disease/V = virus[ID] + var/datum/computer_file/data/virus_record/R = null + if (ID in virusDB) + R = virusDB[ID] + + var/weakref/W = B.data["donor"] + var/mob/living/carbon/human/D = W.resolve() + pathogen_pool.Add(list(list(\ + "name" = "[D ? D.get_species() : "Unidentified"] [B.name]", \ + "dna" = B.data["blood_DNA"], \ + "unique_id" = V.uniqueID, \ + "reference" = "\ref[V]", \ + "is_in_database" = !!R, \ + "record" = "\ref[R]"))) + + if (LAZYLEN(pathogen_pool) > 0) + data["pathogen_pool"] = pathogen_pool + + if (LIST) + var/list/db[0] + for (var/ID in virusDB) + var/datum/computer_file/data/virus_record/r = virusDB[ID] + db.Add(list(list("name" = r.fields["name"], "record" = "\ref[r]"))) + + if (LAZYLEN(db) > 0) + data["database"] = db + + if (ENTRY) + if (entry) + var/desc = entry.fields["description"] + data["entry"] = list(\ + "name" = entry.fields["name"], \ + "description" = replacetext(desc, "\n", "")) + + ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "mods-pathogenic_isolator.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() + +/obj/machinery/disease2/isolator/Process() + if (isolating > 0) + isolating -= 1 + if(virus2) + infect_nearby(virus2) + if (isolating == 0) + if (virus2) + var/obj/item/virusdish/d = new /obj/item/virusdish(src.loc) + d.virus2 = virus2.getcopy() + virus2 = null + ping("\The [src] pings, \"Viral strain isolated.\"") + + SSnano.update_uis(src) + update_icon() + +/obj/machinery/disease2/isolator/OnTopic(mob/user, href_list) + if (href_list["close"]) + SSnano.close_user_uis(user, src, "main") + return TOPIC_HANDLED + + if (href_list[HOME]) + state = HOME + return TOPIC_REFRESH + + if (href_list[LIST]) + state = LIST + return TOPIC_REFRESH + + if (href_list[ENTRY]) + if (istype(locate(href_list["view"]), /datum/computer_file/data/virus_record)) + entry = locate(href_list["view"]) + + state = ENTRY + return TOPIC_REFRESH + + if (href_list["print"]) + print(user) + return TOPIC_REFRESH + + if(!sample) return TOPIC_HANDLED + + if (href_list["isolate"]) + operator_skill = user.get_skill_value(core_skill) + var/datum/disease2/disease/V = locate(href_list["isolate"]) + if (V) + virus2 = V + isolating = 20 + update_icon() + return TOPIC_REFRESH + + if (href_list["eject"]) + sample.dropInto(loc) + sample = null + update_icon() + return TOPIC_REFRESH + +/obj/machinery/disease2/isolator/proc/print(mob/user) + var/obj/item/paper/P = new /obj/item/paper(loc) + + switch (state) + if (HOME) + if (!sample) return + P.SetName("paper - Patient Diagnostic Report") + P.info = {" + [virology_letterhead("Patient Diagnostic Report")] +
    CONFIDENTIAL MEDICAL REPORT

    + Sample: [sample.name]
    +"} + + if (user) + P.info += "Generated By: [user.name]
    " + + P.info += "
    " + + for(var/datum/reagent/blood/B in sample.reagents.reagent_list) + var/weakref/W = B.data["donor"] + var/mob/living/carbon/human/D = W.resolve() + P.info += "[D ? D.get_species() : "Unidentified"] [B.name]:
    [B.data["blood_DNA"]]
    " + + var/list/virus = B.data["virus2"] + P.info += "Pathogens:
    " + if (LAZYLEN(virus) > 0) + for (var/ID in virus) + var/datum/disease2/disease/V = virus[ID] + P.info += "[V.name()]
    " + else + P.info += "None
    " + + P.info += {" +
    + Additional Notes:  +"} + + if (LIST) + P.SetName("paper - Virus List") + P.info = {" + [virology_letterhead("Virus List")] +"} + + var/i = 0 + for (var/ID in virusDB) + i++ + var/datum/computer_file/data/virus_record/r = virusDB[ID] + P.info += "[i]. " + r.fields["name"] + P.info += "
    " + + P.info += {" +
    + Additional Notes:  +"} + + if (ENTRY) + P.SetName("paper - Viral Profile") + P.info = {" + [virology_letterhead("Viral Profile")] + [entry.fields["description"]] +
    + Additional Notes:  +"} + + state("The nearby computer prints out a report.") diff --git a/mods/virusology/code/items_devices.dm b/mods/virusology/code/items_devices.dm new file mode 100644 index 0000000000000..0383a57b050d7 --- /dev/null +++ b/mods/virusology/code/items_devices.dm @@ -0,0 +1,144 @@ +///////////////ANTIBODY SCANNER/////////////// + +/obj/item/device/scanner/antibody_scanner + name = "antibody scanner" + desc = "Scans living beings for antibodies in their blood." + icon = 'icons/obj/tools/health_analyzer.dmi' + icon_state = "health" + item_state = "analyzer" + w_class = ITEM_SIZE_SMALL + item_state = "electronic" + obj_flags = OBJ_FLAG_CONDUCTIBLE + +/obj/item/device/scanner/antibody_scanner/use_before(mob/living/M, mob/living/user) + . = FALSE + if(!istype(M,/mob/living/carbon)) + report("Scan aborted: Incompatible target.", user) + return + + var/mob/living/carbon/C = M + if (istype(C,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = C + if(!H.should_have_organ(BP_HEART)) + report("Scan aborted: The target does not have blood.", user) + return + + if(!LAZYLEN(C.antibodies)) + report("Scan Complete: No antibodies detected.", user) + return + + if (MUTATION_CLUMSY in user.mutations && prob(50)) + // I was tempted to be really evil and rot13 the output. + report("Antibodies detected: [reverse_text(antigens2string(C.antibodies))]", user) + else + report("Antibodies detected: [antigens2string(C.antibodies)]", user) + +/obj/item/device/scanner/antibody_scanner/proc/report(text, mob/user as mob) + to_chat(user, "\icon[src] \The [src] beeps, \"[text]\"") + +///////////////VIRUS DISH/////////////// + +/obj/item/virusdish + name = "virus dish" + icon = 'mods/virusology/icons/virology.dmi' + icon_state = "implantcase-b" + var/datum/disease2/disease/virus2 = null + var/growth = 0 + var/basic_info = null + var/info = 0 + var/analysed = 0 + +/obj/item/virusdish/random + name = "virus sample" + +/obj/item/virusdish/random/New() + ..() + src.virus2 = new /datum/disease2/disease + src.virus2.makerandom() + growth = rand(5, 50) + +/obj/item/virusdish/use_tool(obj/item/W, mob/living/user, list/click_params) + . = ..() + if(istype(W, /obj/item/hand_labeler) || istype(W, /obj/item/reagent_containers/syringe)) + return + ..() + if(prob(50)) + to_chat(user, "\The [src] shatters!") + if(virus2.infectionchance > 0) + for(var/mob/living/carbon/target in view(1, get_turf(src))) + if(airborne_can_reach(get_turf(src), get_turf(target))) + infect_virus2(target, src.virus2) + qdel(src) + +/obj/item/virusdish/examine(mob/user) + . = ..() + if(basic_info) + to_chat(user, "[basic_info] : More Information") + +/obj/item/virusdish/OnTopic(user, href_list) + if(href_list["info"]) + show_browser(user, info, "window=info_\ref[src]") + return TOPIC_HANDLED + +/obj/item/ruinedvirusdish + name = "ruined virus sample" + icon = 'mods/virusology/icons/virology.dmi' + icon_state = "implantcase-b" + desc = "The bacteria in the dish are completely dead." + +/obj/item/ruinedvirusdish/use_tool(obj/item/W, mob/living/user, list/click_params) + . = ..() + if(istype(W,/obj/item/hand_labeler) || istype(W,/obj/item/reagent_containers/syringe)) + return ..() + + if(prob(50)) + to_chat(user, "\The [src] shatters!") + qdel(src) + +///////////////GNA DISK/////////////// + +/obj/item/diseasedisk + name = "blank GNA disk" + icon = 'mods/virusology/icons/virology.dmi' + icon_state = "datadisk0" + w_class = ITEM_SIZE_TINY + var/datum/disease2/effect/effect = null + var/list/species = null + var/stage = 1 + var/analysed = 1 + +/obj/item/diseasedisk/premade/Initialize() + . = ..() + name = "blank GNA disk (stage: [stage])" + effect = new /datum/disease2/effect/invisible + effect.stage = stage + + +/obj/item/stock_parts/circuitboard/curefab + name = "circuit board (cure fabricator)" + build_path = /obj/machinery/computer/curer + +/obj/item/stock_parts/circuitboard/splicer + name = "circuit board (disease splicer)" + build_path = /obj/machinery/computer/diseasesplicer + origin_tech = list(TECH_DATA = 5, TECH_BIO = 5) + +/obj/item/stock_parts/circuitboard/centrifuge + name = "circuit board (isolation centrifuge)" + build_path = /obj/machinery/computer/centrifuge + origin_tech = list(TECH_DATA = 2, TECH_BIO = 3) + + +/datum/design/circuit/centrifuge + name = "isolation centrifuge console" + id = "iso_centrifuge" + req_tech = list(TECH_DATA = 2, TECH_BIO = 3) + build_path = /obj/item/stock_parts/circuitboard/centrifuge + sort_string = "FACAG" + +/datum/design/circuit/splicer + name = "disease splicer" + id = "isplicer" + req_tech = list(TECH_DATA = 5, TECH_BIO = 5) + build_path = /obj/item/stock_parts/circuitboard/splicer + sort_string = "FACAH" diff --git a/mods/virusology/code/lar_maria.dm b/mods/virusology/code/lar_maria.dm new file mode 100644 index 0000000000000..f9d081f6c5b97 --- /dev/null +++ b/mods/virusology/code/lar_maria.dm @@ -0,0 +1,99 @@ +/datum/disease2/disease/lar_maria + infectionchance = 90//very aggressive + speed = 10 + spreadtype = "Airborne" + + affected_species = list(HUMAN_SPECIES,SPECIES_UNATHI,SPECIES_SKRELL,SPECIES_UNATHI,SPECIES_YEOSA,SPECIES_TRITONIAN,SPECIES_RESOMI,SPECIES_NABBER,SPECIES_MONKEY) + +/datum/disease2/disease/lar_maria/New() + ..() + antigen = list(pick(ALL_ANTIGENS)) + antigen |= pick(ALL_ANTIGENS) + var/datum/disease2/effect/sneeze/E1 = new() + E1.stage = 1 + E1.chance = 3 + effects += E1 + E1.multiplier = rand(1,E1.multiplier_max) + var/datum/disease2/effect/stimulant/E2 = new() + E2.stage = 2 + E2.chance = 3 + effects += E2 + E2.multiplier = rand(1,E2.multiplier_max) + var/datum/disease2/effect/stimulant/E3 = new() + E3.stage = 3 + E3.chance = 3 + effects += E3 + E3.multiplier = rand(1,E3.multiplier_max) + var/datum/disease2/effect/rage/E4 = new() + E4.stage = 4 + E4.chance = 3 + effects += E4 + E4.multiplier = rand(1,E4.multiplier_max) + +/datum/disease2/effect/rage //custom effect, fills PC with uncontrollable rage + name = "Rampage Syndrome" + stage = 4 + badness = VIRUS_EXOTIC + delay = 20 SECONDS + var/first_message_shown = FALSE + +/datum/disease2/effect/rage/activate(mob/living/carbon/human/mob, multiplier) + if (!first_message_shown) + first_message_shown = TRUE + to_chat(mob, "Your muscles start tensing up, and you can feel your pulse rising, throbbing at the back of your head. Your breathing increases, and you feel... angry. An urge wells up inside you. Everything is making you angry, and you want it to pay for it.") + return //nothing else happens first time giving chance to adjust RP + if(prob(50)) + to_chat(mob, "You feel uncontrollable rage filling you! You want to hurt and destroy!") + if (mob.reagents.get_reagent_amount(/datum/reagent/hyperzine) < 10) + mob.reagents.add_reagent(/datum/reagent/hyperzine, 4) + if(prob(50) && mob.check_has_mouth())//go crazy and bite someone + var/list/mouth_status = mob.can_eat_status() + if (mouth_status[1] == 1)//if no mouth HUMAN_EATING_NBP_MOUTH + to_chat(mob, "You angrily attempt to bite someone but you can't without a mouth!") + return + if (mouth_status[1] == 2)//if something covers mouth HUMAN_EATING_BLOCKED_MOUTH + to_chat(mob, "You angrily chew \the [mouth_status[2]] covering your mouth!") + return + var/list/mobs_to_bite = list() + for (var/mob/living/carbon/human/L in range(1)) + if (L == mob) + continue + mobs_to_bite += L + if (LAZYLEN(mobs_to_bite) < 1)//nobody to bite + return + var/mob/living/carbon/human/Target = pick(mobs_to_bite) + mob.visible_message("[mob] violently bites [Target]!") + Target.adjustBruteLoss(5) + if (prob(50)) + infect_virus2(Target, src, 1) + + +/mob/living/simple_animal/hostile/lar_maria + var/datum/disease2/disease/lar_maria/LMD = new() + special_attack_min_range = 0 + special_attack_max_range = 1 + special_attack_cooldown = 1 SECONDS + +/mob/living/simple_animal/hostile/lar_maria/Destroy() + . = ..() + QDEL_NULL(LMD) + + +/mob/living/simple_animal/hostile/lar_maria/death(gibbed, deathmessage, show_dead_message) + var/list/victims = list() + var/list/objs = list() + var/turf/T = get_turf(src) + get_mobs_and_objs_in_view_fast(T, 3, victims, objs) + for(var/mob/living/M in victims) + if(ishuman(M)) + if(prob(infection_chance(M, "Airborne"))) + infect_virus2(M, LMD, 1) + .=..() + qdel(src) + +/mob/living/simple_animal/hostile/lar_maria/do_special_attack(atom/A) + if(ishuman(A))//if it's human who can be infected standing nearby + var/mob/living/L = A + if (prob(12)) + visible_message("[src] violently bites [L]!") + infect_virus2(L, LMD, 1) diff --git a/mods/virusology/code/misc.dm b/mods/virusology/code/misc.dm new file mode 100644 index 0000000000000..48e3d209119ca --- /dev/null +++ b/mods/virusology/code/misc.dm @@ -0,0 +1,19 @@ +/datum/goal/sickness + description = "Don't get sick! Avoid catching any viruses during the shift." + var/got_sick + var/announced + +/datum/goal/sickness/check_success() + return !got_sick + +/datum/goal/sickness/update_progress(progress) + if(!got_sick) + got_sick = progress + if(got_sick) + addtimer(CALLBACK(src, /datum/goal/sickness/on_completion), rand(30,40)) + +/datum/goal/sickness/on_completion() + if(!announced) + announced = TRUE + var/datum/mind/mind = owner + to_chat(mind.current, SPAN_DANGER("You don't feel so good...")) diff --git a/mods/virusology/code/pre_made_viruses.dm b/mods/virusology/code/pre_made_viruses.dm new file mode 100644 index 0000000000000..3a38498e293d6 --- /dev/null +++ b/mods/virusology/code/pre_made_viruses.dm @@ -0,0 +1,110 @@ +///Premade Viruses +/datum/disease2/disease/cold + infectionchance = 50 + speed = 1 + spreadtype = "Airborne" + max_stage = 3 + + +/datum/disease2/disease/cold/New() + ..() + antigen = list(pick(ALL_ANTIGENS)) + antigen |= pick(ALL_ANTIGENS) + var/datum/disease2/effect/sneeze/E1 = new() + E1.stage = 1 + effects += E1 + E1.multiplier = rand(1,E1.multiplier_max) + var/datum/disease2/effect/fridge/E2 = new() + E2.stage = 2 + effects += E2 + E2.multiplier = rand(1,E2.multiplier_max) + var/datum/disease2/effect/shakey/E3 = new() + E3.stage = 3 + effects += E3 + E3.multiplier = rand(1,E3.multiplier_max) + +/datum/disease2/disease/spider + infectionchance = 60 + speed = 5 + spreadtype = "Contact" + max_stage = 3 + affected_species = list(HUMAN_SPECIES,SPECIES_UNATHI,SPECIES_SKRELL,SPECIES_UNATHI,SPECIES_YEOSA,SPECIES_TRITONIAN,SPECIES_RESOMI,SPECIES_NABBER,SPECIES_MONKEY) + +/datum/disease2/disease/spider/New() + ..() + antigen = list(pick(ALL_ANTIGENS)) + antigen |= pick(ALL_ANTIGENS) + infectionchance = rand(10,50) + var/datum/disease2/effect/headache/E1 = new() + E1.chance = 2 + E1.stage = 1 + effects += E1 + E1.multiplier = rand(1,E1.multiplier_max) + var/datum/disease2/effect/blind/E2 = new() + E2.chance = 2 + E2.stage = 2 + effects += E2 + E2.multiplier = rand(1,E2.multiplier_max) + var/datum/disease2/effect/confusion/E3 = new() + E3.stage = 3 + E3.chance = 2 + effects += E3 + E3.multiplier = rand(1,E3.multiplier_max) + + +/mob/living/simple_animal/hostile/giant_spider + var/datum/disease2/disease/spider/spider = new() + + +/mob/living/simple_animal/hostile/giant_spider/Destroy() + . = ..() + QDEL_NULL(spider) + +/mob/living/simple_animal/hostile/giant_spider/apply_melee_effects(mob/living/carbon/human/M) + . = ..() + if(Adjacent(M))//if it's human who can be infected standing nearby + if (prob(3)) + infect_virus2(M, spider, 0) + + +/datum/disease2/disease/livingmeat + + infectionchance = 70 + speed = 3 + spreadtype = "Contact" + max_stage = 3 + affected_species = list(HUMAN_SPECIES,SPECIES_UNATHI,SPECIES_SKRELL,SPECIES_UNATHI,SPECIES_YEOSA,SPECIES_TRITONIAN,SPECIES_RESOMI,SPECIES_NABBER,SPECIES_MONKEY) + +/mob/living/simple_animal/hostile/meatstation + var/datum/disease2/disease/livingmeat/livingmeat = new() + +/mob/living/simple_animal/hostile/meatstation/Destroy() + . = ..() + QDEL_NULL(livingmeat) + +/mob/living/simple_animal/hostile/meatstation/apply_melee_effects(mob/living/carbon/human/M) + . = ..() + if(Adjacent(M))//if it's human who can be infected standing nearby + if (prob(10)) + infect_virus2(M, livingmeat, 0) + +/datum/disease2/disease/livingmeat/New() + ..() + antigen = list(pick(ALL_ANTIGENS)) + antigen |= pick(ALL_ANTIGENS) + infectionchance = rand(10,50) + var/datum/disease2/effect/stomach/E1 = new() + E1.stage = 1 + E1.chance = 2 + effects += E1 + E1.multiplier = rand(1,E1.multiplier_max) + var/datum/disease2/effect/hungry/E2 = new() + E2.stage = 2 + E1.chance = 2 + effects += E2 + E2.multiplier = rand(1,E2.multiplier_max) + var/datum/disease2/effect/mutation/E3 = new() + E3.stage = 3 + E1.chance = 2 + effects += E3 + E3.multiplier = rand(1,E3.multiplier_max) diff --git a/mods/virusology/icons/virology.dmi b/mods/virusology/icons/virology.dmi new file mode 100644 index 0000000000000..93369d83f42a5 Binary files /dev/null and b/mods/virusology/icons/virology.dmi differ diff --git a/nano/templates/mods/disease_splicer.tmpl b/nano/templates/mods/disease_splicer.tmpl new file mode 100644 index 0000000000000..4a1701a0fc007 --- /dev/null +++ b/nano/templates/mods/disease_splicer.tmpl @@ -0,0 +1,125 @@ +
    +
    + {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}} +
    +
    + +{{if data.busy}} +
    The Splicer is currently busy.
    +
    +
    {{:data.busy}}
    +
    +

    + Thank you for your patience! +

    +{{else}} +
    +

    Virus Dish

    +
    +
    + {{:helper.link('Eject Dish', 'eject', { 'eject' : 1 }, data.dish_inserted ? null : 'disabled')}} +
    + +
    +
    + Growth Density: +
    +
    + {{:helper.displayBar(data.growth, 0, 100, (data.growth >= 50) ? 'good' : data.growth >= 25 ? 'average' : 'bad', data.growth + '%' )}} +
    +
    + +
    +
    + {{if !data.info}} +
    + Symptoms: +
    + {{/if}} +
    + {{if data.info}} + {{:data.info}} + {{else}} + {{for data.effects}} +
    +
    + ({{:value.stage}}) {{:value.name}} + {{if value.badness > 1}} + Dangerous + {{/if}} +
    +
    + {{/for}} + {{/if}} +
    +
    + {{if data.affected_species && !data.info}} +
    +
    + Affected Species: +
    +
    + {{:data.affected_species}} +
    +
    + {{/if}} +
    + {{if data.effects}} +
    + CAUTION: Reverse engineering will destroy the viral sample. +
    +
    +
    + Reverse Engineering: +
    +
    + {{for data.effects}} + {{:helper.link(value.stage, 'transferthick-e-w', { 'grab' : value.reference })}} + {{/for}} +
    +
    + {{:helper.link('Species', 'transferthick-e-w', { 'affected_species' : 1 })}} +
    +
    + {{/if}} + +
    +

    Storage

    +
    + +
    +
    + Memory Buffer: +
    +
    + {{if data.buffer}} + {{:data.buffer.name}} ({{:data.buffer.stage}}) + {{else}} + {{if data.species_buffer}} + {{:data.species_buffer}} + {{else}} + Empty + {{/if}} + {{/if}} +
    +
    + {{:helper.link('Save To Disk', 'disk', { 'disk' : 1 }, (data.buffer || data.species_buffer) ? null : 'disabled')}} + {{if data.species_buffer}} + {{:helper.link('Splice Species', 'pencil', { 'splice' : -1 }, (data.species_buffer && !data.info) ? null : 'disabled')}} + {{else data.buffer}} + {{:helper.link('Splice #1', 'pencil', { 'splice' : 1 }, data.buffer.stage > 1 ? 'disabled' : null)}} + {{:helper.link('Splice #2', 'pencil', { 'splice' : 2 }, data.buffer.stage > 2 ? 'disabled' : null)}} + {{:helper.link('Splice #3', 'pencil', { 'splice' : 3 }, data.buffer.stage > 3 ? 'disabled' : null)}} + {{:helper.link('Splice #4', 'pencil', { 'splice' : 4 }, data.buffer.stage > 4 ? 'disabled' : null)}} + {{/if}} +{{/if}} + + + + + + + + + + diff --git a/nano/templates/mods/dish_incubator.tmpl b/nano/templates/mods/dish_incubator.tmpl new file mode 100644 index 0000000000000..ae887e6986e67 --- /dev/null +++ b/nano/templates/mods/dish_incubator.tmpl @@ -0,0 +1,123 @@ +
    +
    + {{:helper.link('Close', 'gear', {'close' : '1'}, null, 'fixedLeft')}} +
    +
    + +
    +

    Environmental Conditions

    +
    +
    +
    + Power: +
    +
    + {{:helper.link('On', 'power', { 'power' : 1 }, !data.dish_inserted ? 'disabled' : data.on ? 'selected' : null)}}{{:helper.link('Off', 'close', { 'power' : 1 }, data.on ? null : 'selected')}} +
    +
    +
    + {{:helper.link('Add Radiation', 'radiation', {'rad' : 1})}} + {{:helper.link('Flush System', 'trash', {'flush' : 1}, data.system_in_use ? null : 'disabled')}} +
    + +
    +
    +
    + Virus Food: +
    +
    + {{:helper.displayBar(data.food_supply, 0, 100, 'good', data.food_supply)}} +
    +
    +
    +
    + Radiation Level: +
    +
    + {{:helper.displayBar(data.radiation, 0, 100, (data.radiation >= 50) ? 'bad' : (data.growth >= 25) ? 'average' : 'good')}} +
    + {{:helper.formatNumber(data.radiation * 10000)}} µSv +
    +
    +
    +
    + Toxicity: +
    +
    + {{:helper.displayBar(data.toxins, 0, 100, (data.toxins >= 50) ? 'bad' : (data.toxins >= 25) ? 'average' : 'good', data.toxins + '%')}} +
    +
    +
    + +
    +

    Chemicals

    +
    +
    + {{:helper.link('Eject Chemicals', 'eject', { 'ejectchem' : 1 }, data.chemicals_inserted ? null : 'disabled')}} + {{:helper.link('Breed Virus', 'circle-arrow-s', { 'virus' : 1 }, data.can_breed_virus ? null : 'disabled')}} +
    + +{{if data.chemicals_inserted}} +
    +
    + Volume: +
    +
    + {{:helper.displayBar(data.chemical_volume, 0, data.max_chemical_volume, 'good', data.chemical_volume + ' / ' + data.max_chemical_volume)}} +
    +
    +
    +
    + Breeding Environment: +
    +
    + + {{:!data.dish_inserted ? 'N/A' : data.can_breed_virus ? 'Suitable' : 'No hemolytic samples detected'}} + + {{if data.blood_already_infected}} +
    + CAUTION: Viral infection detected in blood sample. + {{/if}} +
    +
    +{{else}} +
    + No chemicals inserted. +
    +{{/if}} + +
    +

    Virus Dish

    +
    +
    + {{:helper.link('Eject Dish', 'eject', {'ejectdish' : 1}, data.dish_inserted ? null : 'disabled')}} +
    + +{{if data.dish_inserted}} + {{if data.virus}} +
    +
    + Growth Density: +
    +
    + {{:helper.displayBar(data.growth, 0, 100, (data.growth >= 50) ? 'good' : (data.growth >= 25) ? 'average' : 'bad', data.growth + '%' )}} +
    +
    +
    +
    + Infection Rate: +
    +
    + {{:data.analysed ? data.infection_rate : "Unknown"}} +
    +
    + {{else}} +
    + No virus detected. +
    + {{/if}} +{{else}} +
    + No dish loaded. +
    +{{/if}} diff --git a/nano/templates/mods/isolation_centrifuge.tmpl b/nano/templates/mods/isolation_centrifuge.tmpl new file mode 100644 index 0000000000000..4ff0272df02b8 --- /dev/null +++ b/nano/templates/mods/isolation_centrifuge.tmpl @@ -0,0 +1,81 @@ +
    + {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}} + {{:helper.link('Print', 'print', { 'print' : 1 }, data.antibodies || data.pathogens ? null : 'disabled', 'fixedLeft')}} +
    + +{{if data.busy}} +
    The Centrifuge is currently busy.
    +
    +
    {{:data.busy}}
    +
    +

    + Thank you for your patience! +

    +{{else}} +
    +

    {{:data.is_antibody_sample ? 'Antibody Sample' : 'Blood Sample'}}

    +
    +
    + {{:helper.link('Eject Vial', 'eject', { 'action' : 'sample' }, data.sample_inserted ? null : 'disabled')}} +
    + {{if data.sample_inserted}} + {{if data.antibodies || data.pathogens}} +
    + {{if data.antibodies}} +
    +
    + Antibodies: +
    +
    + {{:data.antibodies}} +
    +
    + {{/if}} + {{if data.pathogens}} +
    +
    + Pathogens: +
    +
    + {{for data.pathogens}} +
    + {{:value.name}} ({{:value.spread_type}}) +
    + {{/for}} +
    +
    + {{/if}} +
    + {{else}} +
    + No antibodies or viral strains detected. +
    + {{/if}} + {{else}} +
    + No vial detected. +
    + {{/if}} + {{if data.antibodies && !data.is_antibody_sample}} +
    +
    + Isolate Antibodies: +
    +
    + {{:helper.link(data.antibodies, 'pencil', { 'action' : 'antibody' })}} +
    +
    + {{/if}} + {{if data.pathogens}} +
    +
    + Isolate Strain: +
    +
    + {{for data.pathogens}} + {{:helper.link(value.name, 'pencil', { 'isolate' : value.reference })}} + {{/for}} +
    +
    + {{/if}} +{{/if}} diff --git a/nano/templates/mods/pathogenic_isolator.tmpl b/nano/templates/mods/pathogenic_isolator.tmpl new file mode 100644 index 0000000000000..69411d858fc3e --- /dev/null +++ b/nano/templates/mods/pathogenic_isolator.tmpl @@ -0,0 +1,107 @@ +
    +

    Menu

    +
    +
    + {{if !data.isolating}} + {{:helper.link('Home', 'home', {'home' : 1}, data.state == 'home' ? 'disabled' : null, 'fixedLeft')}} + {{:helper.link('List', 'note', {'list' : 1}, data.state == 'list' ? 'disabled' : null, 'fixedLeft')}} + {{:helper.link('Pathogen', 'folder-open', {'entry' : 1}, data.state == 'entry' ? 'disabled' : null, 'fixedLeft')}} + {{/if}} +
    + {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}} + {{:helper.link('Print', 'print', { 'print' : 1 }, data.can_print ? null : 'disabled', 'fixedLeft')}} +
    + +{{if data.isolating}} +
    The Isolator is currently busy.
    +
    +
    Isolating pathogens...
    +
    +

    + Thank you for your patience! +

    +{{else}} + {{if data.state =="home"}} +
    +

    Blood Sample

    +
    +
    + {{:helper.link('Eject Syringe', 'eject', { 'eject' : 1 }, data.syringe_inserted ? null : 'disabled')}} +
    + + {{if data.syringe_inserted}} +
    + Pathogens: + {{if data.pathogen_pool}} + {{for data.pathogen_pool}} +
    + {{:index + 1}}. #{{:value.unique_id}} {{:value.is_in_database ? "(Analysed)" : ""}}
    + {{:value.name}}: {{:value.dna}} +
    + {{/for}} + {{else}} + No pathogens detected. + {{/if}} +
    + {{else}} +
    + No syringe loaded. +
    + {{/if}} + {{if data.pathogen_pool}} +
    +
    + Isolate Pathogens: +
    +
    + {{for data.pathogen_pool}} + {{:helper.link('#' + value.unique_id, 'pencil', { 'isolate' : value.reference }, null, 'fixedLeft')}} + {{/for}} +
    +
    +
    +
    + Database Lookup: +
    +
    + {{for data.pathogen_pool}} + {{if value.is_in_database}} + {{:helper.link('#' + value.unique_id, 'info', { 'entry' : 1, 'view' : value.record }, null, 'fixedLeft')}} + {{/if}} + {{/for}} +
    +
    + {{/if}} + {{else}} + {{if data.state == "list"}} +
    +

    View Database

    +
    +
    + {{if data.database}} + {{for data.database}} +
    +
    {{:value.name}}
    + {{:helper.link('Details', 'circle-arrow-s', { 'entry' : 1, 'view' : value.record }, null, 'fixedLeft')}} +
    + {{/for}} + {{else}} + The viral database is empty. + {{/if}} +
    + {{else}} + {{if data.state == "entry"}} + {{if data.entry}} +
    +

    {{:data.entry.name}}

    +
    +
    + {{:data.entry.description}} +
    + {{else}} + No virus selected. + {{/if}} + {{/if}} + {{/if}} + {{/if}} +{{/if}} diff --git a/packs/infinity/icons/mob/screen/facedir.dmi b/packs/infinity/icons/mob/screen/facedir.dmi new file mode 100644 index 0000000000000..44a9eb14ab05d Binary files /dev/null and b/packs/infinity/icons/mob/screen/facedir.dmi differ diff --git a/sound/machines/airlockdone.ogg b/sound/machines/airlockdone.ogg new file mode 100644 index 0000000000000..eef291a2d375b Binary files /dev/null and b/sound/machines/airlockdone.ogg differ diff --git a/sound/machines/airlockin.ogg b/sound/machines/airlockin.ogg new file mode 100644 index 0000000000000..66a78128d9f92 Binary files /dev/null and b/sound/machines/airlockin.ogg differ diff --git a/sound/machines/airlockout.ogg b/sound/machines/airlockout.ogg new file mode 100644 index 0000000000000..d4f03f446f00e Binary files /dev/null and b/sound/machines/airlockout.ogg differ diff --git a/test/check-paths.sh b/test/check-paths.sh index e2e61d73926fb..17cf2be3b3275 100755 --- a/test/check-paths.sh +++ b/test/check-paths.sh @@ -45,7 +45,7 @@ exactly 2 "<< uses" '(?> uses" '(?)>>(?!>)' -P exactly 0 "incorrect indentations" '^( {4,})' -P exactly 25 "text2path uses" 'text2path' -exactly 4 "update_icon() override" '/update_icon\((.*)\)' -P +exactly 5 "update_icon() override" '/update_icon\((.*)\)' -P exactly 4 "goto use" 'goto ' exactly 1 "NOOP match" 'NOOP' exactly 332 "spawn uses" '^\s*spawn\s*\(\s*(-\s*)?\d*\s*\)' -P @@ -56,7 +56,7 @@ exactly 0 "emagged = 0/1" 'emagged\s*=\s*\d' -P exactly 0 "simulated = 0/1" 'simulated\s*=\s*\d' -P exactly 2 "var/ in proc arguments" '(^/[^/].+/.+?\(.*?)var/' -P exactly 0 "tmp/ vars" 'var.*/tmp/' -P -exactly 7 "uses of .len" '\.len\b' -P +exactly 15 "uses of .len" '\.len\b' -P exactly 15 "uses of examine()" '[.|\s]examine\(' -P # If this fails it's likely because you used '/atom/proc/examine(mob)' instead of '/proc/examinate(mob, atom)' - Exception: An examine()-proc may call other examine()-procs exactly 13 "direct modifications of overlays list" '\boverlays((\s*[|^=+&-])|(\.(Cut)|(Add)|(Copy)|(Remove)|(Remove)))' -P exactly 0 "new/list list instantiations" 'new\s*/list' -P