diff --git a/.github/workflows/autowiki.yml b/.github/workflows/autowiki.yml
new file mode 100644
index 000000000000..82d0ac76f32f
--- /dev/null
+++ b/.github/workflows/autowiki.yml
@@ -0,0 +1,52 @@
+name: Autowiki
+on:
+ schedule:
+ - cron: "5 4 * * *"
+ workflow_dispatch:
+permissions:
+ contents: read
+
+jobs:
+ autowiki:
+ runs-on: ubuntu-20.04
+ steps:
+ - name: "Check for AUTOWIKI_USERNAME"
+ id: secrets_set
+ env:
+ ENABLER_SECRET: ${{ secrets.AUTOWIKI_USERNAME }}
+ run: |
+ unset SECRET_EXISTS
+ if [ -n "$ENABLER_SECRET" ]; then SECRET_EXISTS=true ; fi
+ echo "SECRETS_ENABLED=$SECRET_EXISTS" >> $GITHUB_OUTPUT
+ - name: Checkout
+ if: steps.secrets_set.outputs.SECRETS_ENABLED
+ uses: actions/checkout@v3
+ - name: Restore BYOND cache
+ if: steps.secrets_set.outputs.SECRETS_ENABLED
+ uses: actions/cache@v3
+ with:
+ path: ~/BYOND
+ key: ${{ runner.os }}-byond-${{ secrets.CACHE_PURGE_KEY }}
+ - name: Install rust-g
+ if: steps.secrets_set.outputs.SECRETS_ENABLED
+ run: |
+ sudo dpkg --add-architecture i386
+ sudo apt update || true
+ sudo apt install -o APT::Immediate-Configure=false libssl1.1:i386
+ bash tools/ci/install_rust_g.sh
+ - name: Compile and generate Autowiki files
+ if: steps.secrets_set.outputs.SECRETS_ENABLED
+ run: |
+ bash tools/ci/install_byond.sh
+ source $HOME/BYOND/byond/bin/byondsetup
+ tools/build/build --ci autowiki
+ - name: Run Autowiki
+ if: steps.secrets_set.outputs.SECRETS_ENABLED
+ env:
+ USERNAME: ${{ secrets.AUTOWIKI_USERNAME }}
+ PASSWORD: ${{ secrets.AUTOWIKI_PASSWORD }}
+ run: |
+ cd tools/autowiki
+ npm install
+ cd ../..
+ node tools/autowiki/autowiki.js data/autowiki_edits.txt data/autowiki_files/
diff --git a/code/__DEFINES/__game.dm b/code/__DEFINES/__game.dm
index 3116d7f19555..113b78dbada1 100644
--- a/code/__DEFINES/__game.dm
+++ b/code/__DEFINES/__game.dm
@@ -39,6 +39,7 @@ block( \
#define MAP_RUNTIME "USS Runtime"
#define MAP_LV522_CHANCES_CLAIM "LV-522 Chance's Claim" // Highpop Only
#define MAP_NEW_VARADERO "New Varadero"//ice colony underground but as its own map
+#define MAP_CHINOOK "Chinook 91 GSO" //admin level
#define GAMEMODE_WHISKEY_OUTPOST "Whiskey Outpost"
#define GAMEMODE_HIVE_WARS "Hive Wars"
diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm
index ac050e467a71..5a4ba7676233 100644
--- a/code/__DEFINES/lighting.dm
+++ b/code/__DEFINES/lighting.dm
@@ -1,3 +1,5 @@
#define LIGHTING_PLANE_ALPHA_VISIBLE 255
+///The dim natural vision of Yautja
+#define LIGHTING_PLANE_ALPHA_YAUTJA 235
#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 127
#define LIGHTING_PLANE_ALPHA_INVISIBLE 0
diff --git a/code/__DEFINES/mode.dm b/code/__DEFINES/mode.dm
index 131cf1c2d703..636a0330f6fc 100644
--- a/code/__DEFINES/mode.dm
+++ b/code/__DEFINES/mode.dm
@@ -185,7 +185,7 @@ var/global/list/whitelist_hierarchy = list(WHITELIST_NORMAL, WHITELIST_COUNCIL,
#define WHITELIST_EVERYTHING (WHITELISTS_GENERAL|WHITELISTS_COUNCIL|WHITELISTS_LEADER)
-#define isCouncil(A) (RoleAuthority.roles_whitelist[A.ckey] & (WHITELIST_YAUTJA_COUNCIL | WHITELIST_SYNTHETIC_COUNCIL | WHITELIST_COMMANDER_COUNCIL))
+#define isCouncil(A) (RoleAuthority.roles_whitelist[A.ckey] & WHITELIST_YAUTJA_COUNCIL) || (RoleAuthority.roles_whitelist[A.ckey] & WHITELIST_SYNTHETIC_COUNCIL) || (RoleAuthority.roles_whitelist[A.ckey] & WHITELIST_COMMANDER_COUNCIL)
//=================================================
diff --git a/code/__DEFINES/skills.dm b/code/__DEFINES/skills.dm
index 8e1bde82c839..fdd1a8f083ad 100644
--- a/code/__DEFINES/skills.dm
+++ b/code/__DEFINES/skills.dm
@@ -39,14 +39,24 @@
//spec_weapons skill
//hidden. who can and can't use specialist weapons
#define SKILL_SPEC_DEFAULT 0
-#define SKILL_SPEC_ROCKET 1 //can use the demolitionist specialist gear
-#define SKILL_SPEC_SCOUT 2
-#define SKILL_SPEC_SNIPER 3
-#define SKILL_SPEC_GRENADIER 4
-#define SKILL_SPEC_PYRO 5
-#define SKILL_SPEC_SMARTGUN 6 //for smartgunners
-#define SKILL_SPEC_UPP 7 //for upp
-#define SKILL_SPEC_ALL 8 //can use all specialist gear
+/// Is trained to use specialist gear, but hasn't picked a kit.
+#define SKILL_SPEC_TRAINED 1
+/// Can use RPG
+#define SKILL_SPEC_ROCKET 2
+/// Can use thermal cloaks and custom M4RA rifle
+#define SKILL_SPEC_SCOUT 3
+/// Can use sniper rifles and camo suits
+#define SKILL_SPEC_SNIPER 4
+/// Can use the rotary grenade launcher and heavy armor
+#define SKILL_SPEC_GRENADIER 5
+/// Can use heavy flamers
+#define SKILL_SPEC_PYRO 6
+/// Can use smartguns
+#define SKILL_SPEC_SMARTGUN 7
+/// UPP special training
+#define SKILL_SPEC_UPP 8
+/// Can use ALL specialist weapons
+#define SKILL_SPEC_ALL 9
//construction skill
#define SKILL_CONSTRUCTION_DEFAULT 0
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 288604434e34..1aaf3714182e 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -127,6 +127,8 @@
#define TRAIT_INTENT_EYES "t_intent_eyes"
/// Masked synthetic biology. Basic medHUDs will percieve the mob as human. (Infiltrator Synths)
#define TRAIT_INFILTRATOR_SYNTH "t_infiltrator_synth"
+/// Makes it impossible to strip the inventory of this mob.
+#define TRAIT_UNSTRIPPABLE "t_unstrippable"
// HIVE TRAITS
/// If the Hive is a Xenonid Hive
@@ -251,6 +253,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_FOREIGN_BIO" = TRAIT_FOREIGN_BIO,
"TRAIT_INTENT_EYES" = TRAIT_INTENT_EYES,
"TRAIT_INFILTRATOR_SYNTH" = TRAIT_INFILTRATOR_SYNTH,
+ "TRAIT_UNSTRIPPABLE" = TRAIT_UNSTRIPPABLE,
"TRAIT_NESTED" = TRAIT_NESTED,
"TRAIT_CRAWLER" = TRAIT_CRAWLER,
"TRAIT_SIMPLE_DESC" = TRAIT_SIMPLE_DESC,
diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm
index 7988ff6d1a95..976256cb6c97 100644
--- a/code/controllers/configuration/entries/general.dm
+++ b/code/controllers/configuration/entries/general.dm
@@ -621,3 +621,5 @@ This maintains a list of ip addresses that are able to bypass topic filtering.
/datum/config_entry/string/instance_name
config_entry_value = "game"
protection = CONFIG_ENTRY_HIDDEN|CONFIG_ENTRY_LOCKED
+
+/datum/config_entry/flag/guest_ban
diff --git a/code/datums/diseases/black_goo.dm b/code/datums/diseases/black_goo.dm
index 97aec074d2d3..38a26f3648c7 100644
--- a/code/datums/diseases/black_goo.dm
+++ b/code/datums/diseases/black_goo.dm
@@ -124,7 +124,7 @@
icon = 'icons/mob/humans/species/r_zombie.dmi'
icon_state = "claw_l"
flags_item = NODROP|DELONDROP|ITEM_ABSTRACT
- force = 40
+ force = MELEE_FORCE_TIER_6 //slightly higher than normal
w_class = SIZE_MASSIVE
sharp = 1
attack_verb = list("slashed", "torn", "scraped", "gashed", "ripped")
@@ -135,8 +135,9 @@
return FALSE
. = ..()
- if(.)
- playsound(loc, 'sound/weapons/bladeslice.ogg', 25, 1, 5)
+ if(!.)
+ return FALSE
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 25, 1, 5)
if(ishuman_strict(target))
var/mob/living/carbon/human/human = target
@@ -149,10 +150,7 @@
target.AddDisease(new /datum/disease/black_goo)
to_chat(user, SPAN_XENOWARNING("You sense your target is now infected."))
- if(issynth(target))
- target.apply_effect(2, SLOW)
- else
- target.apply_effect(2, SUPERSLOW)
+ target.apply_effect(2, SLOW)
/obj/item/weapon/zombie_claws/afterattack(obj/O as obj, mob/user as mob, proximity)
if(get_dist(src, O) > 1)
diff --git a/code/datums/emergency_calls/cryo_marines.dm b/code/datums/emergency_calls/cryo_marines.dm
index fb4a0d94e177..e7dcba08ed61 100644
--- a/code/datums/emergency_calls/cryo_marines.dm
+++ b/code/datums/emergency_calls/cryo_marines.dm
@@ -12,15 +12,17 @@
name_of_spawn = /obj/effect/landmark/ert_spawns/distress_cryo
shuttle_id = ""
var/leaders = 0
+ spawn_max_amount = TRUE
/datum/emergency_call/cryo_squad/spawn_candidates(announce, override_spawn_loc, announce_dispatch_message)
var/datum/squad/marine/cryo/cryo_squad = RoleAuthority.squads_by_type[/datum/squad/marine/cryo]
leaders = cryo_squad.num_leaders
. = ..()
- if(length(members))
- shipwide_ai_announcement("Successfully deployed [length(members)] Foxtrot marines.")
+ shipwide_ai_announcement("Successfully deployed [mob_max] Foxtrot marines, of which [length(members)] are ready for duty.")
+ if(mob_max > length(members))
+ announce_dchat("Some cryomarines were not taken, use the Join As Freed Mob verb to take one of them.")
-/datum/emergency_call/cryo_squad/create_member(datum/mind/M, turf/override_spawn_loc)
+/datum/emergency_call/cryo_squad/create_member(datum/mind/mind, turf/override_spawn_loc)
set waitfor = 0
if(SSmapping.configs[GROUND_MAP].map_name == MAP_WHISKEY_OUTPOST)
name_of_spawn = /obj/effect/landmark/ert_spawns/distress_wo
@@ -28,49 +30,61 @@
if(!istype(spawn_loc)) return //Didn't find a useable spawn point.
- var/mob/living/carbon/human/H = new(spawn_loc)
- M.transfer_to(H, TRUE)
+ var/mob/living/carbon/human/human = new(spawn_loc)
+
+ if(mind)
+ mind.transfer_to(human, TRUE)
+ else
+ human.create_hud()
+
+ if(!mind)
+ for(var/obj/structure/machinery/cryopod/pod in view(7,human))
+ if(pod && !pod.occupant)
+ pod.go_in_cryopod(human, silent = TRUE)
+ break
sleep(5)
var/datum/squad/marine/cryo/cryo_squad = RoleAuthority.squads_by_type[/datum/squad/marine/cryo]
- if(leaders < cryo_squad.max_leaders && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(H.client, JOB_SQUAD_LEADER, time_required_for_job))
- leader = H
+ if(leaders < cryo_squad.max_leaders && (!mind || (HAS_FLAG(human.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(human.client, JOB_SQUAD_LEADER, time_required_for_job))))
+ leader = human
leaders++
- H.client.prefs.copy_all_to(H, JOB_SQUAD_LEADER, TRUE, TRUE)
- arm_equipment(H, /datum/equipment_preset/uscm/leader/cryo, FALSE, TRUE)
- to_chat(H, SPAN_ROLE_HEADER("You are a Squad Leader in the USCM"))
- to_chat(H, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command."))
- to_chat(H, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced."))
- else if (heavies < max_heavies && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_HEAVY) && check_timelock(H.client, JOB_SQUAD_SPECIALIST, time_required_for_job))
+ human.client?.prefs.copy_all_to(human, JOB_SQUAD_LEADER, TRUE, TRUE)
+ arm_equipment(human, /datum/equipment_preset/uscm/leader/cryo, mind == null, TRUE)
+ to_chat(human, SPAN_ROLE_HEADER("You are a Squad Leader in the USCM"))
+ to_chat(human, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command."))
+ to_chat(human, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced."))
+ else if (heavies < max_heavies && (!mind || (HAS_FLAG(human.client.prefs.toggles_ert, PLAY_HEAVY) && check_timelock(human.client, JOB_SQUAD_SPECIALIST, time_required_for_job))))
heavies++
- H.client.prefs.copy_all_to(H, JOB_SQUAD_SPECIALIST, TRUE, TRUE)
- arm_equipment(H, /datum/equipment_preset/uscm/spec/cryo, FALSE, TRUE)
- to_chat(H, SPAN_ROLE_HEADER("You are a Weapons Specialist in the USCM"))
- to_chat(H, SPAN_ROLE_BODY("Your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command."))
- to_chat(H, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced."))
- else if (medics < max_medics && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_MEDIC) && check_timelock(H.client, JOB_SQUAD_MEDIC, time_required_for_job))
+ human.client?.prefs.copy_all_to(human, JOB_SQUAD_SPECIALIST, TRUE, TRUE)
+ arm_equipment(human, /datum/equipment_preset/uscm/spec/cryo, mind == null, TRUE)
+ to_chat(human, SPAN_ROLE_HEADER("You are a Weapons Specialist in the USCM"))
+ to_chat(human, SPAN_ROLE_BODY("Your squad is here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command."))
+ to_chat(human, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced."))
+ else if (medics < max_medics && (!mind || (HAS_FLAG(human.client.prefs.toggles_ert, PLAY_MEDIC) && check_timelock(human.client, JOB_SQUAD_MEDIC, time_required_for_job))))
medics++
- H.client.prefs.copy_all_to(H, JOB_SQUAD_MEDIC, TRUE, TRUE)
- arm_equipment(H, /datum/equipment_preset/uscm/medic/cryo, FALSE, TRUE)
- to_chat(H, SPAN_ROLE_HEADER("You are a Hospital Corpsman in the USCM"))
- to_chat(H, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command."))
- to_chat(H, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced."))
- else if (engineers < max_engineers && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_ENGINEER) && check_timelock(H.client, JOB_SQUAD_ENGI, time_required_for_job))
+ human.client?.prefs.copy_all_to(human, JOB_SQUAD_MEDIC, TRUE, TRUE)
+ arm_equipment(human, /datum/equipment_preset/uscm/medic/cryo, mind == null, TRUE)
+ to_chat(human, SPAN_ROLE_HEADER("You are a Hospital Corpsman in the USCM"))
+ to_chat(human, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command."))
+ to_chat(human, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced."))
+ else if (engineers < max_engineers && (!mind || (HAS_FLAG(human.client.prefs.toggles_ert, PLAY_ENGINEER) && check_timelock(human.client, JOB_SQUAD_ENGI, time_required_for_job))))
engineers++
- H.client.prefs.copy_all_to(H, JOB_SQUAD_ENGI, TRUE, TRUE)
- arm_equipment(H, /datum/equipment_preset/uscm/engineer/cryo, FALSE, TRUE)
- to_chat(H, SPAN_ROLE_HEADER("You are an Engineer in the USCM"))
- to_chat(H, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command."))
- to_chat(H, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced."))
+ human.client?.prefs.copy_all_to(human, JOB_SQUAD_ENGI, TRUE, TRUE)
+ arm_equipment(human, /datum/equipment_preset/uscm/engineer/cryo, mind == null, TRUE)
+ to_chat(human, SPAN_ROLE_HEADER("You are an Engineer in the USCM"))
+ to_chat(human, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command."))
+ to_chat(human, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced."))
else
- H.client.prefs.copy_all_to(H, JOB_SQUAD_MARINE, TRUE, TRUE)
- arm_equipment(H, /datum/equipment_preset/uscm/pfc/cryo, FALSE, TRUE)
- to_chat(H, SPAN_ROLE_HEADER("You are a Rifleman in the USCM"))
- to_chat(H, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command."))
- to_chat(H, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced."))
+ human.client?.prefs.copy_all_to(human, JOB_SQUAD_MARINE, TRUE, TRUE)
+ arm_equipment(human, /datum/equipment_preset/uscm/pfc/cryo, mind == null, TRUE)
+ to_chat(human, SPAN_ROLE_HEADER("You are a Rifleman in the USCM"))
+ to_chat(human, SPAN_ROLE_BODY("You are here to assist in the defence of the [SSmapping.configs[GROUND_MAP].map_name]. Listen to the chain of command."))
+ to_chat(human, SPAN_BOLDWARNING("If you wish to cryo or ghost upon spawning in, you must ahelp and inform staff so you can be replaced."))
sleep(10)
- to_chat(H, SPAN_BOLD("Objectives: [objectives]"))
+ if(!mind)
+ human.free_for_ghosts()
+ to_chat(human, SPAN_BOLD("Objectives: [objectives]"))
/datum/emergency_call/cryo_squad/platoon
name = "Marine Cryo Reinforcements (Platoon)"
diff --git a/code/datums/medal_awards.dm b/code/datums/medal_awards.dm
index a7db6f7bd6e3..54af48fd3345 100644
--- a/code/datums/medal_awards.dm
+++ b/code/datums/medal_awards.dm
@@ -20,9 +20,10 @@ GLOBAL_LIST_EMPTY(jelly_awards)
var/recipient_rank
var/recipient_ckey
var/mob/recipient_mob
- var/list/giver_name // Actually key for xenos
- var/list/giver_rank // Actually name for xenos
+ var/list/giver_name // Designation for xenos
+ var/list/giver_rank // "Name" for xenos
var/list/giver_mob
+ var/list/giver_ckey
/datum/recipient_awards/New()
medal_names = list()
@@ -32,6 +33,7 @@ GLOBAL_LIST_EMPTY(jelly_awards)
giver_name = list()
giver_rank = list()
giver_mob = list()
+ giver_ckey = list()
/proc/give_medal_award(medal_location, as_admin = FALSE)
@@ -116,12 +118,13 @@ GLOBAL_LIST_EMPTY(jelly_awards)
recipient_award.medal_names += medal_type
recipient_award.medal_citations += citation
recipient_award.posthumous += posthumous
+ recipient_award.giver_ckey += usr.ckey
if(!as_admin)
recipient_award.giver_rank += recipient_ranks[usr.real_name] // Currently not used in marine award message
recipient_award.giver_name += usr.real_name // Currently not used in marine award message
else
- recipient_award.giver_rank += "([usr.ckey])" // Just because it'll be displayed in the panel
+ recipient_award.giver_rank += null
recipient_award.giver_name += null
// Create an actual medal item
@@ -258,15 +261,21 @@ GLOBAL_LIST_EMPTY(jelly_awards)
recipient_award.medal_names += medal_type
recipient_award.medal_citations += citation
recipient_award.posthumous += posthumous
+ recipient_award.giver_ckey += usr.ckey
+
if(!admin_attribution)
recipient_award.giver_rank += usr.name
- recipient_award.giver_name += usr.key
+ var/mob/living/carbon/xenomorph/giving_xeno = usr
+ if(istype(giving_xeno))
+ recipient_award.giver_name += giving_xeno.full_designation
+ else
+ recipient_award.giver_name += null
else if(admin_attribution == "none")
recipient_award.giver_rank += null
recipient_award.giver_name += null
else
recipient_award.giver_rank += admin_attribution
- recipient_award.giver_name += null // If not null, rescinding it will take stats away from a mob with this key
+ recipient_award.giver_name += null
recipient_award.medal_items += null // TODO: Xeno award item?
@@ -337,6 +346,7 @@ GLOBAL_LIST_EMPTY(jelly_awards)
recipient_award.giver_name.Cut(index, index + 1)
recipient_award.giver_rank.Cut(index, index + 1)
recipient_award.giver_mob.Cut(index, index + 1)
+ recipient_award.giver_ckey.Cut(index, index + 1)
recipient_award.medal_items.Cut(index, index + 1)
// Remove giver's stat
diff --git a/code/datums/redis/callbacks/asay.dm b/code/datums/redis/callbacks/asay.dm
index 2ccbca08fb6c..9c60a394a4ac 100644
--- a/code/datums/redis/callbacks/asay.dm
+++ b/code/datums/redis/callbacks/asay.dm
@@ -7,10 +7,10 @@
if(data["source"] == SSredis.instance_name)
return
- var/msg = SPAN_ADMINSAY("[data["rank"]]: [data["author"]]@[data["source"]]: [strip_html(data["message"])]")
+ var/msg = SPAN_MOD("[data["rank"]]: [data["author"]]@[data["source"]]: [strip_html(data["message"])]")
for(var/client/client in GLOB.admins)
- if(!(R_ADMIN & client.admin_holder.rights))
+ if(!(R_ADMIN & client.admin_holder.rights) && !(R_MOD & client.admin_holder.rights))
continue
to_chat(client, msg)
diff --git a/code/datums/skills.dm b/code/datums/skills.dm
index 48f622309a19..2cc66c7afc12 100644
--- a/code/datums/skills.dm
+++ b/code/datums/skills.dm
@@ -1009,7 +1009,7 @@ United States Colonial Marines
SKILL_CQC = SKILL_CQC_TRAINED,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_TRAINED,
SKILL_ENGINEER = SKILL_ENGINEER_TRAINED, //to use c4 in demo set.
- SKILL_SPEC_WEAPONS = SKILL_SPEC_ALL,
+ SKILL_SPEC_WEAPONS = SKILL_SPEC_TRAINED,
SKILL_MELEE_WEAPONS = SKILL_MELEE_TRAINED,
SKILL_ENDURANCE = SKILL_ENDURANCE_TRAINED,
SKILL_JTAC = SKILL_JTAC_BEGINNER
diff --git a/code/datums/statistics/random_facts/random_fact.dm b/code/datums/statistics/random_facts/random_fact.dm
index 2a83c7b2c1ad..76c6e82f776d 100644
--- a/code/datums/statistics/random_facts/random_fact.dm
+++ b/code/datums/statistics/random_facts/random_fact.dm
@@ -41,6 +41,8 @@
list_to_check += GLOB.living_xeno_list
for(var/mob/checked_mob as anything in list_to_check)
+ if(!checked_mob?.persistent_ckey)
+ continue // We don't care about NPCs
if(living_stat_gotten < life_grab_stat(checked_mob))
mob_to_report = checked_mob
living_stat_gotten = life_grab_stat(checked_mob)
diff --git a/code/game/gamemodes/cm_initialize.dm b/code/game/gamemodes/cm_initialize.dm
index efb92dd1678e..becee89adb6d 100644
--- a/code/game/gamemodes/cm_initialize.dm
+++ b/code/game/gamemodes/cm_initialize.dm
@@ -969,7 +969,7 @@ Additional game mode variables.
log_debug("Null client attempted to transform_joe")
return
- var/turf/spawn_point = get_turf(pick(GLOB.latejoin))
+ var/turf/spawn_point = get_turf(pick(GLOB.latejoin_by_job[JOB_WORKING_JOE]))
var/mob/living/carbon/human/synthetic/new_joe = new(spawn_point)
joe_candidate.mind.transfer_to(new_joe, TRUE)
var/datum/job/joe_job = RoleAuthority.roles_by_name[JOB_WORKING_JOE]
diff --git a/code/game/gamemodes/cm_process.dm b/code/game/gamemodes/cm_process.dm
index 82f0902e2f8c..33377f7dc6fd 100644
--- a/code/game/gamemodes/cm_process.dm
+++ b/code/game/gamemodes/cm_process.dm
@@ -58,18 +58,18 @@ of predators), but can be added to include variant game modes (like humans vs. h
if(LAZYLEN(xenomorphs) || LAZYLEN(dead_queens))
var/dat = "
"
dat += SPAN_ROUNDBODY("
The xenomorph Queen(s) were:")
- var/mob/M
+ var/mob/living/carbon/xenomorph/xeno_mob
for (var/msg in dead_queens)
dat += msg
- for(var/datum/mind/X in xenomorphs)
- if(!istype(X))
+ for(var/datum/mind/xeno_mind in xenomorphs)
+ if(!istype(xeno_mind))
continue
- M = X.current
- if(!M || !M.loc)
- M = X.original
- if(M && M.loc && isqueen(M) && M.stat != DEAD) // Dead queens handled separately
- dat += "
[X.key] was [M] [SPAN_BOLDNOTICE("(SURVIVED)")]"
+ xeno_mob = xeno_mind.current
+ if(!xeno_mob || !xeno_mob.loc)
+ xeno_mob = xeno_mind.original
+ if(xeno_mob && xeno_mob.loc && isqueen(xeno_mob) && xeno_mob.stat != DEAD) // Dead queens handled separately
+ dat += "
[xeno_mob.full_designation] was [xeno_mob] [SPAN_BOLDNOTICE("(SURVIVED)")]"
to_world("[dat]")
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 9c0a227008c3..ed7335ea8778 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -193,7 +193,7 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
//Lifted from Unity stasis.dm and refactored. ~Zuhayr
/obj/structure/machinery/cryopod/process()
- if(occupant)
+ if(occupant && !(WEAKREF(occupant) in GLOB.freed_mob_list)) //ignore freed mobs
//if occupant ghosted, time till despawn is severely shorter
if(!occupant.key && time_till_despawn == 10 MINUTES)
time_till_despawn -= 8 MINUTES
diff --git a/code/game/machinery/vending/cm_vending.dm b/code/game/machinery/vending/cm_vending.dm
index 57d0e49a58bc..bf7c4fffee65 100644
--- a/code/game/machinery/vending/cm_vending.dm
+++ b/code/game/machinery/vending/cm_vending.dm
@@ -472,7 +472,7 @@ GLOBAL_LIST_EMPTY(vending_products)
to_chat(user, SPAN_WARNING("Only specialists can take specialist sets."))
vend_fail()
return FALSE
- else if(!user.skills || user.skills.get_skill_level(SKILL_SPEC_WEAPONS) != SKILL_SPEC_ALL)
+ else if(!user.skills || user.skills.get_skill_level(SKILL_SPEC_WEAPONS) != SKILL_SPEC_TRAINED)
to_chat(user, SPAN_WARNING("You already have a specialization."))
vend_fail()
return FALSE
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index 0399d0996411..43c3500813a4 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -169,7 +169,7 @@
/obj/effect/decal/cleanable/blackgoo/Crossed(mob/living/carbon/human/H)
if(!istype(H)) return
if(H.species.name == "Human")
- if(!H.shoes || prob(25))
+ if(!H.shoes && prob(50))
H.contract_disease(new /datum/disease/black_goo)
diff --git a/code/game/objects/items/backpack_sprayers.dm b/code/game/objects/items/backpack_sprayers.dm
index 09f620c345d5..427a1dd597c7 100644
--- a/code/game/objects/items/backpack_sprayers.dm
+++ b/code/game/objects/items/backpack_sprayers.dm
@@ -8,6 +8,7 @@
w_class = SIZE_LARGE
flags_equip_slot = SLOT_BACK
flags_atom = OPENCONTAINER
+ possible_transfer_amounts = null//no point giving it possibility when mister can't it just confuse people
volume = 500
var/fill_reagent = "water"
var/spawn_empty = FALSE
@@ -83,8 +84,10 @@
/obj/item/reagent_container/glass/watertank/verb/toggle_mister_verb()
set name = "Toggle Mister"
set category = "Object"
+ set src in usr
toggle_mister(usr)
+
/obj/item/reagent_container/glass/watertank/MouseDrop(obj/over_object as obj)
if(!CAN_PICKUP(usr, src))
return ..()
@@ -132,7 +135,7 @@
item_state = "nozzle"
w_class = SIZE_LARGE
flags_equip_slot = null
- amount_per_transfer_from_this = 50
+ amount_per_transfer_from_this = 5
possible_transfer_amounts = null
spray_size = 5
volume = 500
diff --git a/code/game/objects/structures/props.dm b/code/game/objects/structures/props.dm
index 296e0497c9be..c9fb2fcd1197 100644
--- a/code/game/objects/structures/props.dm
+++ b/code/game/objects/structures/props.dm
@@ -1023,13 +1023,6 @@
icon_state = "arcadeb"
name = "Spirit Phone, The Game, The Movie: II"
-/obj/structure/prop/maintenance_hatch
- name = "\improper Maintenance Hatch"
- icon = 'icons/obj/structures/structures.dmi'
- icon_state = "hatchclosed"
- desc = "Looks like it's rusted shut. Creepy."
- layer = HATCH_LAYER
-
//INVULNERABLE PROPS
/obj/structure/prop/invuln
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index 1c94eb485300..3c964cf4011b 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -57,24 +57,38 @@
display_colour = CONFIG_GET(string/ooc_color_default)
msg = process_chat_markup(msg, list("*"))
-
+ var/ooc_prefix = handle_ooc_prefix()
for(var/client/C in GLOB.clients)
if(C.prefs.toggles_chat & CHAT_OOC)
var/display_name = src.key
- if(prefs.unlock_content)
- if(prefs.toggle_prefs & TOGGLE_MEMBER_PUBLIC)
- var/byond = icon('icons/effects/effects.dmi', "byondlogo")
- display_name = "[icon2html(byond, GLOB.clients)][display_name]"
- if(CONFIG_GET(flag/ooc_country_flags))
- if(prefs.toggle_prefs & TOGGLE_OOC_FLAG)
- display_name = "[country2chaticon(src.country, GLOB.clients)][display_name]"
- to_chat(C, "[src.donator ? "\[D\] " : ""]OOC: [display_name]: [msg]")
+ to_chat(C, "[ooc_prefix]OOC: [display_name]: [msg]")
+
/client/proc/set_ooc_color_global(newColor as color)
set name = "OOC Text Color - Global"
set desc = "Set to yellow for eye burning goodness."
set category = "OOC.OOC"
GLOB.ooc_color_override = newColor
+///Used by OOC chat to generate icons for player prefix. Intended to make it easy to see at a glance if someone is staff, WL Council or Mentor.
+/client/proc/handle_ooc_prefix()
+ var/prefix = ""
+ if(prefs.unlock_content && (prefs.toggle_prefs & TOGGLE_MEMBER_PUBLIC))
+ var/byond = icon('icons/effects/effects.dmi', "byondlogo")
+ prefix += "[icon2html(byond, GLOB.clients)]"
+ if(CONFIG_GET(flag/ooc_country_flags) && (prefs.toggle_prefs & TOGGLE_OOC_FLAG))
+ prefix += "[country2chaticon(src.country, GLOB.clients)]"
+ if(donator)
+ prefix += "[icon2html('icons/ooc.dmi', GLOB.clients, "Donator")]"
+ if(isCouncil(src))
+ prefix += "[icon2html('icons/ooc.dmi', GLOB.clients, "WhitelistCouncil")]"
+ if(admin_holder)
+ var/list/rank_icons = icon_states('icons/ooc.dmi')
+ var/rankname = admin_holder.rank
+ if(rankname in rank_icons)
+ prefix += "[icon2html('icons/ooc.dmi', GLOB.clients, admin_holder.rank)]"
+ if(prefix)
+ prefix = "[prefix] "
+ return prefix
/client/verb/looc(msg as text)
set name = "LOOC" //Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite
diff --git a/code/game/world.dm b/code/game/world.dm
index 25cd609646da..cff799800a49 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -61,7 +61,7 @@ var/list/reboot_sfx = file2list("config/reboot_sfx.txt")
var/testing_locally = (world.params && world.params["local_test"])
var/running_tests = (world.params && world.params["run_tests"])
- #ifdef UNIT_TESTS
+ #if defined(AUTOWIKI) || defined(UNIT_TESTS)
running_tests = TRUE
#endif
// Only do offline sleeping when the server isn't running unit tests or hosting a local dev test
@@ -84,6 +84,10 @@ var/list/reboot_sfx = file2list("config/reboot_sfx.txt")
HandleTestRun()
#endif
+ #ifdef AUTOWIKI
+ setup_autowiki()
+ #endif
+
update_status()
//Scramble the coords obsfucator
diff --git a/code/global.dm b/code/global.dm
index 28a8926cade4..bdde529a9af8 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -32,6 +32,7 @@
#define CLIENT_HAS_RIGHTS(cli, flags) ((cli?.admin_holder?.rights & flags) == flags)
#define CLIENT_IS_STAFF(cli) (cli?.admin_holder?.rights & (R_MOD|R_ADMIN))
+#define CLIENT_IS_MENTOR(cli) CLIENT_HAS_RIGHTS(cli, R_MENTOR)
#define AHOLD_IS_MOD(ahold) (ahold && (ahold.rights & R_MOD))
#define AHOLD_IS_ADMIN(ahold) (ahold && (ahold.rights & R_ADMIN))
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index 36e70d311ac0..bf6d8e261ab3 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -12,7 +12,7 @@
return //don't recheck connected clients.
//Guest Checking
- if(IsGuestKey(key))
+ if(!real_bans_only && CONFIG_GET(flag/guest_ban) && IsGuestKey(key))
log_access("Failed Login: [key] - Guests not allowed")
message_admins("Failed Login: [key] - Guests not allowed")
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 05e27625daeb..368e2766ccfc 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -344,7 +344,7 @@ var/list/roundstart_mod_verbs = list(
add_verb(src, clan_verbs)
/client/proc/add_admin_whitelists()
- if(CLIENT_HAS_RIGHTS(src, R_MENTOR))
+ if(CLIENT_IS_MENTOR(src))
RoleAuthority.roles_whitelist[ckey] |= WHITELIST_MENTOR
if(CLIENT_IS_STAFF(src))
RoleAuthority.roles_whitelist[ckey] |= WHITELIST_JOE
diff --git a/code/modules/admin/medal_panel/medals_panel_tgui.dm b/code/modules/admin/medal_panel/medals_panel_tgui.dm
index ee8728670544..49c4bb5f96ad 100644
--- a/code/modules/admin/medal_panel/medals_panel_tgui.dm
+++ b/code/modules/admin/medal_panel/medals_panel_tgui.dm
@@ -19,22 +19,22 @@ GLOBAL_DATUM_INIT(medals_panel, /datum/medals_panel_tgui, new)
var/list/xeno_awards = list()
var/list/uscm_award_ckeys = list()
var/list/xeno_award_ckeys = list()
-
+
// Break the medals up by recipient and then pack each medal into a string
for(var/recipient_name as anything in GLOB.medal_awards)
var/datum/recipient_awards/recipient_award = GLOB.medal_awards[recipient_name]
uscm_awards[recipient_name] = list()
uscm_award_ckeys[recipient_name] = recipient_award.recipient_ckey ? " ([recipient_award.recipient_ckey])" : ""
for(var/i in 1 to recipient_award.medal_names.len) // We're assuming everything is same length
- uscm_awards[recipient_name] += "[recipient_award.medal_names[i]]: \'[recipient_award.medal_citations[i]]\' by [recipient_award.giver_rank[i]] [recipient_award.giver_name[i]]."
-
+ uscm_awards[recipient_name] += "[recipient_award.medal_names[i]]: \'[recipient_award.medal_citations[i]]\' by [recipient_award.giver_rank[i] ? "[recipient_award.giver_rank[i]] " : ""][recipient_award.giver_name[i] ? "[recipient_award.giver_name[i]] " : ""]([recipient_award.giver_ckey[i]])."
+
for(var/recipient_name as anything in GLOB.jelly_awards)
var/datum/recipient_awards/recipient_award = GLOB.jelly_awards[recipient_name]
xeno_awards[recipient_name] = list()
xeno_award_ckeys[recipient_name] = recipient_award.recipient_ckey ? " ([recipient_award.recipient_ckey])" : ""
for(var/i in 1 to recipient_award.medal_names.len) // We're assuming everything is same length
- xeno_awards[recipient_name] += "[recipient_award.medal_names[i]]: \'[recipient_award.medal_citations[i]]\'[recipient_award.giver_rank[i] ? " by [recipient_award.giver_rank[i]]" : ""][recipient_award.giver_name[i] ? " ([recipient_award.giver_name[i]])" : ""]."
-
+ xeno_awards[recipient_name] += "[recipient_award.medal_names[i]]: \'[recipient_award.medal_citations[i]]\' by [recipient_award.giver_rank[i] ? "[recipient_award.giver_rank[i]] " : ""][recipient_award.giver_name[i] ? "[recipient_award.giver_name[i]] " : ""]([recipient_award.giver_ckey[i]])."
+
data["uscm_awards"] = uscm_awards
data["xeno_awards"] = xeno_awards
data["uscm_award_ckeys"] = uscm_award_ckeys
@@ -61,8 +61,8 @@ GLOBAL_DATUM_INIT(medals_panel, /datum/medals_panel_tgui, new)
if("delete_medal")
remove_award(params["recipient"], TRUE, params["index"] + 1) // Why is byond not 0 indexed?
return TRUE
-
+
if("delete_jelly")
- remove_award(params["recipient"], FALSE, params["index"] + 1) // Why is byond not 0 indexed?
+ remove_award(params["recipient"], FALSE, params["index"] + 1) // Why is byond not 0 indexed?
return TRUE
-
+
diff --git a/code/modules/admin/tabs/admin_tab.dm b/code/modules/admin/tabs/admin_tab.dm
index 6dc08c63e5de..1298d6150036 100644
--- a/code/modules/admin/tabs/admin_tab.dm
+++ b/code/modules/admin/tabs/admin_tab.dm
@@ -255,9 +255,9 @@
log_adminpm("ADMIN: [key_name(src)] : [msg]")
- var/color = "adminsay"
- if(ishost(usr))
- color = "headminsay"
+ var/color = "mod"
+ if(check_rights(R_PERMISSIONS, show_msg = FALSE))
+ color = "adminmod"
var/channel = "ADMIN:"
channel = "[admin_holder.rank]:"
diff --git a/code/modules/admin/tabs/event_tab.dm b/code/modules/admin/tabs/event_tab.dm
index fdf70d314c21..32eaeb674b8d 100644
--- a/code/modules/admin/tabs/event_tab.dm
+++ b/code/modules/admin/tabs/event_tab.dm
@@ -218,21 +218,22 @@
if(!istype(chosen_ert))
return
- var/is_announcing = TRUE
- switch(alert(src, "Would you like to announce the distress beacon to the server population? This will reveal the distress beacon to all players.", "Announce distress beacon?", "Yes", "No", "Cancel"))
- if("Cancel")
- qdel(chosen_ert)
- return
- if("No")
- is_announcing = FALSE
+ var/is_announcing = tgui_alert(usr, "Would you like to announce the distress beacon to the server population? This will reveal the distress beacon to all players.", "Announce distress beacon?", list("Yes", "No"), 20 SECONDS)
+ if(!is_announcing)
+ qdel(chosen_ert)
+ return
+ if(is_announcing == "No")
+ is_announcing = FALSE
+ if (is_announcing == "Yes")
+ is_announcing = TRUE
var/turf/override_spawn_loc
- switch(alert(usr, "Spawn at their assigned spawnpoints, or at your location?", "Spawnpoint Selection", "Assigned Spawnpoint", "Current Location", "Cancel"))
- if("Cancel")
- qdel(chosen_ert)
- return
- if("Current Location")
- override_spawn_loc = get_turf(usr)
+ var/prompt = tgui_alert(usr, "Spawn at their assigned spawn, or at your location?", "Spawnpoint Selection", list("Spawn", "Current Location"), 0)
+ if(!prompt)
+ qdel(chosen_ert)
+ return
+ if(prompt == "Current Location")
+ override_spawn_loc = get_turf(usr)
chosen_ert.activate(is_announcing, override_spawn_loc)
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index d73a69f3eb95..4a4f6fa830a9 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -12,7 +12,7 @@
return
if(!CLIENT_IS_STAFF(src))
- if(!CLIENT_HAS_RIGHTS(src, R_MENTOR))
+ if(!CLIENT_IS_MENTOR(src))
to_chat(src, "Only staff members have permission to use this.")
return
if(!CONFIG_GET(flag/mentor_tools))
diff --git a/code/modules/autowiki/autowiki.dm b/code/modules/autowiki/autowiki.dm
new file mode 100644
index 000000000000..8b38ec76706b
--- /dev/null
+++ b/code/modules/autowiki/autowiki.dm
@@ -0,0 +1,36 @@
+/// When the `AUTOWIKI` define is enabled, will generate an output file for tools/autowiki/autowiki.js to consume.
+/// Autowiki code intentionally still *exists* even without the define, to ensure developers notice
+/// when they break it immediately, rather than until CI or worse, call time.
+#if defined(AUTOWIKI) || defined(UNIT_TESTS)
+/proc/setup_autowiki()
+ Master.sleep_offline_after_initializations = FALSE
+ UNTIL(SSticker.current_state == GAME_STATE_PREGAME)
+
+ //trigger things to run the whole process
+ SSticker.request_start()
+ CONFIG_SET(number/round_end_countdown, 0)
+ SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(generate_autowiki)))
+
+/proc/generate_autowiki()
+ var/output = generate_autowiki_output()
+ rustg_file_write(output, "data/autowiki_edits.txt")
+ qdel(world)
+#endif
+
+/// Returns a string of the autowiki output file
+/proc/generate_autowiki_output()
+ var/total_output = ""
+
+ for (var/datum/autowiki/autowiki_type as anything in subtypesof(/datum/autowiki))
+ var/datum/autowiki/autowiki = new autowiki_type
+ var/output = autowiki.generate()
+
+ if (!istext(output))
+ CRASH("[autowiki_type] does not generate a proper output!")
+
+ total_output += json_encode(list(
+ "title" = autowiki.page,
+ "text" = output,
+ )) + "\n"
+
+ return total_output
diff --git a/code/modules/autowiki/pages/_page.dm b/code/modules/autowiki/pages/_page.dm
new file mode 100644
index 000000000000..8e745ace61c2
--- /dev/null
+++ b/code/modules/autowiki/pages/_page.dm
@@ -0,0 +1,54 @@
+/// A representation of an automated wiki page.
+/datum/autowiki
+ /// The page on the wiki to be replaced.
+ /// This should never be a user-facing page, like "Guide to circuits".
+ /// It should always be a template that only Autowiki should touch.
+ /// For example: "Template:Autowiki/CircuitInfo".
+ var/page
+
+/// Override and return the new text of the page.
+/// This proc can be impure, usually to call `upload_file`.
+/datum/autowiki/proc/generate()
+ SHOULD_CALL_PARENT(FALSE)
+ CRASH("[type] does not implement generate()!")
+
+/// Generates an auto formatted template user.
+/// Your autowiki should ideally be a *lot* of these.
+/// It lets wiki editors edit it much easier later, without having to enter repo.
+/// Parameters will be passed in by name. That means your template should expect
+/// something that looks like `{{ Autowiki_Circuit|name=Combiner|description=This combines }}`
+/// Lists, which must be array-like (no keys), will be turned into a flat list with their key and a number,
+/// such that list("food" = list("fruit", "candy")) -> food1=fruit|food2=candy
+/datum/autowiki/proc/include_template(name, parameters)
+ var/template_text = "{{[name]"
+
+ var/list/prepared_parameters = list()
+ for (var/key in parameters)
+ var/value = parameters[key]
+ if (islist(value))
+ for (var/index in 1 to length(value))
+ prepared_parameters["[key][index]"] = "[value[index]]"
+ else
+ prepared_parameters[key] = value
+
+ for (var/parameter_name in prepared_parameters)
+ template_text += "|[parameter_name]="
+ template_text += "[prepared_parameters[parameter_name]]"
+
+ template_text += "}}"
+
+ return template_text
+
+/// Takes an icon and uploads it to Autowiki-name.png.
+/// Do your best to make sure this is unique, so it doesn't clash with other autowiki icons.
+/datum/autowiki/proc/upload_icon(icon/icon, name)
+ // Fuck you
+ if (IsAdminAdvancedProcCall())
+ return
+
+ fcopy(icon, "data/autowiki_files/[name].png")
+
+/// Escape a parameter such that it can be correctly put inside a wiki output
+/datum/autowiki/proc/escape_value(parameter)
+ // | is a special character in MediaWiki, and must be escaped by...using another template.
+ return replacetextEx(parameter, "|", "{{!}}")
diff --git a/code/modules/autowiki/pages/guns.dm b/code/modules/autowiki/pages/guns.dm
new file mode 100644
index 000000000000..0946b552fe31
--- /dev/null
+++ b/code/modules/autowiki/pages/guns.dm
@@ -0,0 +1,118 @@
+/datum/autowiki/guns
+ page = "Template:Autowiki/Content/GunData"
+
+
+/datum/autowiki/guns/generate()
+ var/output = ""
+
+ var/list/gun_to_ammo = list()
+
+ for(var/obj/item/ammo_magazine/typepath as anything in subtypesof(/obj/item/ammo_magazine) - subtypesof(/obj/item/ammo_magazine/internal))
+ LAZYADD(gun_to_ammo[initial(typepath.gun_type)], typepath)
+
+ for(var/typepath in sort_list(subtypesof(/obj/item/weapon/gun), GLOBAL_PROC_REF(cmp_typepaths_asc)))
+ var/obj/item/weapon/gun/generating_gun = new typepath()
+
+ var/filename = SANITIZE_FILENAME(escape_value(format_text(generating_gun.name)))
+
+ var/list/gun_data = generating_gun.ui_data()
+
+ var/list/valid_mag_types = list()
+ for(var/path in gun_to_ammo)
+ if(!istype(generating_gun, path))
+ continue
+
+ valid_mag_types += gun_to_ammo[path]
+
+ var/ammo = ""
+ var/damage_table = ""
+ for(var/ammo_typepath in valid_mag_types)
+ var/obj/item/ammo_magazine/generating_mag = new ammo_typepath()
+
+ var/ammo_filename = SANITIZE_FILENAME(escape_value(format_text(generating_mag.name)))
+
+ if(!fexists("data/autowiki_files/[ammo_filename].png"))
+ upload_icon(getFlatIcon(generating_mag, no_anim = TRUE), ammo_filename)
+
+ var/datum/ammo/current_ammo = GLOB.ammo_list[generating_mag.default_ammo]
+
+ ammo += include_template("Autowiki/AmmoMagazine", list(
+ "icon" = escape_value(ammo_filename),
+ "name" = escape_value(generating_mag.name),
+ "capacity" = escape_value(generating_mag.max_rounds),
+ "damage" = escape_value(current_ammo.damage),
+ "max_range" = escape_value(current_ammo.max_range),
+ "fall_off" = escape_value(current_ammo.damage_falloff),
+ "penetration" = escape_value(current_ammo.penetration),
+ "punch" = escape_value(current_ammo.pen_armor_punch),
+ ))
+
+ generating_gun.current_mag = generating_mag
+
+ var/list/gun_ammo_data = generating_gun.ui_data()
+ var/list/armor_data = list()
+
+ var/iterator = 1
+ for(var/header in gun_ammo_data["damage_armor_profile_headers"])
+ var/damage = gun_ammo_data["damage_armor_profile_marine"][iterator]
+ armor_data["armor-[header]"] = damage
+ iterator++
+
+ var/list/damage = list("ammo_name" = escape_value(generating_mag.name))
+ damage += armor_data
+
+ damage_table += include_template("Autowiki/DamageVersusArmorRow", damage)
+
+ qdel(generating_mag)
+
+ gun_data["ammo_types"] = ammo
+ gun_data["damage_table"] = damage_table
+
+ var/list/attachments_by_slot = list()
+ for(var/obj/item/attachable/attachment_typepath as anything in generating_gun.attachable_allowed)
+ LAZYADD(attachments_by_slot[capitalize(initial(attachment_typepath.slot))], attachment_typepath)
+
+ var/attachments = ""
+ for(var/slot in attachments_by_slot)
+ var/list/attachments_in_slot = ""
+
+ for(var/attachment_typepath in attachments_by_slot[slot])
+ var/obj/item/attachable/generating_attachment = new attachment_typepath()
+
+ var/attachment_filename = SANITIZE_FILENAME(escape_value(format_text(generating_attachment.name)))
+
+ if(!fexists("data/autowiki_files/[attachment_filename].png"))
+ upload_icon(getFlatIcon(generating_attachment, no_anim = TRUE), attachment_filename)
+
+ attachments_in_slot += include_template("Autowiki/AvailableAttachment", list(
+ "icon" = escape_value(attachment_filename),
+ "name" = escape_value(generating_attachment.name),
+ ))
+
+ qdel(generating_attachment)
+
+ attachments += include_template("Autowiki/AttachmentsBySlot", list(
+ "slot" = escape_value(slot),
+ "attachments" = attachments_in_slot,
+ ))
+ gun_data["attachments"] = attachments
+
+
+ upload_icon(getFlatIcon(generating_gun, no_anim = TRUE), filename)
+ gun_data["icon"] = filename
+
+ output += include_template("Autowiki/Gun", gun_data)
+
+ qdel(generating_gun)
+
+ return output
+
+/datum/autowiki/guns/proc/wiki_sanitize_assoc(list/sanitizing_list)
+ var/list/sanitized = list()
+
+ for(var/key in sanitizing_list)
+ var/value = sanitizing_list[key]
+
+ sanitized[escape_value(key)] = escape_value(value)
+
+ return sanitized
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index 8f0939474427..2facce7c3a59 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -27,7 +27,7 @@
var/area = null
var/time_died_as_mouse = null //when the client last died as a mouse
- var/donator = 0
+ var/donator = FALSE
var/adminhelped = 0
var/datum/click_intercept = null
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index ad0b6e1d89fb..3722b32fb2b4 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -287,11 +287,6 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list(
if(!(connection in list("seeker", "web"))) //Invalid connection type.
return null
- if(IsGuestKey(key))
- alert(src,"This server doesn't allow guest accounts to play. Please go to http://www.byond.com/ and register for a key.","Guest","OK")
- qdel(src)
- return
-
GLOB.clients += src
GLOB.directory[ckey] = src
@@ -435,7 +430,7 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list(
for(var/line in lines)
if(src.ckey == line)
- src.donator = 1
+ src.donator = TRUE
add_verb(src, /client/proc/set_ooc_color_self)
//if(prefs.window_skin & TOGGLE_WINDOW_SKIN)
diff --git a/code/modules/client/tgui_macro.dm b/code/modules/client/tgui_macro.dm
index 684cf90942ea..f245f1d657d4 100644
--- a/code/modules/client/tgui_macro.dm
+++ b/code/modules/client/tgui_macro.dm
@@ -45,6 +45,7 @@ GLOBAL_LIST_EMPTY(ui_data_keybindings)
if(!ui)
ui = new(user, src, "KeyBinds", "Keybind Preference")
ui.open()
+ ui.set_autoupdate(FALSE)
/datum/tgui_macro/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
diff --git a/code/modules/clothing/glasses/meson.dm b/code/modules/clothing/glasses/meson.dm
index 859368cd7afc..b0823910365d 100644
--- a/code/modules/clothing/glasses/meson.dm
+++ b/code/modules/clothing/glasses/meson.dm
@@ -16,19 +16,6 @@
desc = "Used for shield the user's eyes from harmful electromagnetic emissions, can also be used as safety googles. Contains prescription lenses."
prescription = TRUE
-/obj/item/clothing/glasses/meson/yautja
- name = "bio-mask x-ray"
- desc = "A vision overlay generated by the Bio-Mask. Used to see through objects."
- icon = 'icons/obj/items/hunter/pred_gear.dmi'
- icon_state = "visor_meson"
- item_state = "securityhud"
- darkness_view = 12
- lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
- vision_flags = SEE_TURFS
- flags_inventory = COVEREYES
- flags_item = NODROP|DELONDROP
- actions_types = null
-
/obj/item/clothing/glasses/meson/refurbished
name = "refurbished meson scanner"
desc = "Used to shield the user's eyes from harmful electromagnetic emissions, also used as general safety goggles. A special version with upgraded optics."
diff --git a/code/modules/clothing/glasses/thermal.dm b/code/modules/clothing/glasses/thermal.dm
index 607e53cf65f1..bfc60d271724 100644
--- a/code/modules/clothing/glasses/thermal.dm
+++ b/code/modules/clothing/glasses/thermal.dm
@@ -70,18 +70,6 @@
item_state = "syringe_kit"
toggleable = FALSE
-/obj/item/clothing/glasses/thermal/yautja
- name = "bio-mask thermal"
- desc = "A vision overlay generated by the Bio-Mask. Used to sense the heat of prey."
- icon = 'icons/obj/items/hunter/pred_gear.dmi'
- icon_state = "visor_thermal"
- item_state = "securityhud"
- vision_flags = SEE_MOBS
- invisa_view = 2
- flags_inventory = COVEREYES
- flags_item = NODROP|DELONDROP
- toggleable = FALSE
-
/obj/item/clothing/glasses/thermal/empproof
desc = "Thermals in the shape of glasses. This one is EMP proof."
blinds_on_emp = FALSE
diff --git a/code/modules/cm_aliens/structures/tunnel.dm b/code/modules/cm_aliens/structures/tunnel.dm
index a5d623bff189..0e1008cfbf12 100644
--- a/code/modules/cm_aliens/structures/tunnel.dm
+++ b/code/modules/cm_aliens/structures/tunnel.dm
@@ -254,3 +254,12 @@
else
to_chat(M, SPAN_WARNING("\The [src] ended unexpectedly, so you return back up."))
return XENO_NO_DELAY_ACTION
+
+/obj/structure/tunnel/maint_tunnel
+ name = "\improper Maintenance Hatch"
+ desc = "An entrance to a maintenance tunnel. You can see bits of slime and resin within. Pieces of debris keep you from getting a closer look."
+ icon = 'icons/obj/structures/structures.dmi'
+ icon_state = "hatchclosed"
+
+/obj/structure/tunnel/maint_tunnel/no_xeno_desc
+ desc = "An entrance to a maintenance tunnel. Pieces of debris keep you from getting a closer look."
diff --git a/code/modules/cm_marines/equipment/kit_boxes.dm b/code/modules/cm_marines/equipment/kit_boxes.dm
index 4ce6be802f3d..a552b8eb0927 100644
--- a/code/modules/cm_marines/equipment/kit_boxes.dm
+++ b/code/modules/cm_marines/equipment/kit_boxes.dm
@@ -207,7 +207,7 @@
for(var/allowed_role in allowed_roles_list)
if(user.job == allowed_role)
- if(!skillcheckexplicit(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_DEFAULT) && !skillcheckexplicit(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_ALL))
+ if(!skillcheckexplicit(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_TRAINED) && !skillcheckexplicit(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_ALL))
to_chat(user, SPAN_WARNING("You already have specialization, give this kit to someone else!"))
return FALSE
return TRUE
@@ -216,7 +216,7 @@
var/selection = tgui_input_list(user, "Pick your specialist equipment type.", "Specialist Kit Selection", available_specialist_kit_boxes)
if(!selection || QDELETED(src))
return FALSE
- if(!skillcheckexplicit(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_DEFAULT) && !skillcheckexplicit(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_ALL))
+ if(!skillcheckexplicit(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_TRAINED) && !skillcheckexplicit(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_ALL))
to_chat(user, SPAN_WARNING("You already unwrapped your [name], give this one to someone else!"))
return
if(!available_specialist_kit_boxes[selection] || available_specialist_kit_boxes[selection] <= 0)
diff --git a/code/modules/cm_marines/equipment/maps.dm b/code/modules/cm_marines/equipment/maps.dm
index 98ad238fe055..f41c8d6f971b 100644
--- a/code/modules/cm_marines/equipment/maps.dm
+++ b/code/modules/cm_marines/equipment/maps.dm
@@ -82,7 +82,7 @@
/obj/item/map/big_red_map
name = "\improper Solaris Ridge Map"
desc = "A censored blueprint of the Solaris Ridge facility"
- html_link = "images/c/c5/Big_Red.png"
+ html_link = "images/9/9e/Solaris_Ridge.png"
color = "#e88a10"
/obj/item/map/FOP_map
@@ -104,10 +104,11 @@
color = "#ad8d0e"
/obj/item/map/sorokyne_map
- name = "\improper Sorokyne Outpost Map"
- desc = "A labelled schematic of the Sorokyne Outpost and the surrounding caves."
+ name = "\improper Sorokyne Strata map"
+ desc = "A map of the Weyland-Yutani colony Sorokyne Outpost, commonly known as Sorokyne Strata."
html_link = "images/2/21/Sorokyne_Wiki_Map.jpg" //The fact that this is just a wiki-link makes me sad and amused.
color = "cyan"
+
/obj/item/map/corsat
name = "\improper CORSAT map"
desc = "A blueprint of CORSAT station"
@@ -125,83 +126,46 @@
desc = "An overview of LV-522 schematics."
html_link = "images/b/bb/C_claim.png"
color = "cyan"
+
/obj/item/map/new_varadero
name = "\improper New Varadero map"
desc = "A labeled blueprint of the UA outpost New Varadero"
html_link = "images/9/94/New_Varadero.png"
color = "red"
+GLOBAL_LIST_INIT_TYPED(map_type_list, /obj/item/map, setup_all_maps())
+
+/proc/setup_all_maps()
+ return list(
+ MAP_LV_624 = new /obj/item/map/lazarus_landing_map(),
+ MAP_ICE_COLONY = new /obj/item/map/ice_colony_map(),
+ MAP_ICE_COLONY_V3 = new /obj/item/map/ice_colony_map_v3(),
+ MAP_WHISKEY_OUTPOST = new /obj/item/map/whiskey_outpost_map(),
+ MAP_BIG_RED = new /obj/item/map/big_red_map(),
+ MAP_PRISON_STATION = new /obj/item/map/FOP_map(),
+ MAP_PRISON_STATION_V3 = new /obj/item/map/FOP_map_v3(),
+ MAP_DESERT_DAM = new /obj/item/map/desert_dam(),
+ MAP_SOROKYNE_STRATA = new /obj/item/map/sorokyne_map(),
+ MAP_CORSAT = new /obj/item/map/corsat(),
+ MAP_KUTJEVO = new /obj/item/map/kutjevo_map(),
+ MAP_LV522_CHANCES_CLAIM = new /obj/item/map/lv522_map(),
+ MAP_NEW_VARADERO = new /obj/item/map/new_varadero()
+ )
+
//used by marine equipment machines to spawn the correct map.
/obj/item/map/current_map
/obj/item/map/current_map/Initialize(mapload, ...)
. = ..()
- switch(SSmapping.configs[GROUND_MAP].map_name)
- if(MAP_LV_624)
- name = "\improper Lazarus Landing Map"
- desc = "A satellite printout of the Lazarus Landing colony on LV-624."
- html_link = "images/6/6f/LV624.png"
- if(MAP_ICE_COLONY)
- name = "\improper Ice Colony map"
- desc = "A satellite printout of the Ice Colony."
- html_link = "images/1/18/Map_icecolony.png"
- color = "cyan"
- if(MAP_ICE_COLONY_V3)
- name = "\improper Shivas Snowball map"
- desc = "A labelled print out of the anterior scan of the UA colony Shivas Snowball."
- html_link = "images/1/18/Map_icecolony.png"//needs to be replaced at some point
- color = "cyan"
- if(MAP_BIG_RED)
- name = "\improper Solaris Ridge Map"
- desc = "A censored blueprint of the Solaris Ridge facility"
- html_link = "images/9/9e/Solaris_Ridge.png"
- color = "#e88a10"
- if(MAP_PRISON_STATION)
- name = "\improper Fiorina Orbital Penitentiary Map"
- desc = "A labelled interior scan of Fiorina Orbital Penitentiary"
- html_link = "images/4/4c/Map_Prison.png"
- color = "#e88a10"
- if(MAP_PRISON_STATION_V3)
- name = "\improper Fiorina Orbital Penitentiary Map"
- desc = "A scan produced by the Almayer's sensor array of the Fiorina Orbital Penitentiary Civilian Annex. It appears to have broken off from the rest of the station and is now in free geo-sync orbit around the planet."
- html_link = "images/e/e0/Prison_Station_Science_Annex.png"
- color = "#e88a10"
- if(MAP_DESERT_DAM)
- name = "\improper Trijent Dam map"
- desc = "A map of Trijent Dam"
- html_link = "images/9/92/Trijent_Dam.png"
- color = "#cec13f"
- //did only the basics todo change later
- if(MAP_SOROKYNE_STRATA)
- name = "\improper Sorokyne Strata map"
- desc = "A map of the Weyland-Yutani colony Sorokyne Outpost, commonly known as Sorokyne Strata."
- html_link = "images/1/1c/Sorokyne_map.png"
- color = "cyan"
- if (MAP_CORSAT)
- name = "\improper CORSAT map"
- desc = "A blueprint of CORSAT station"
- html_link = "images/8/8e/CORSAT_Satellite.png"
- color = "red"
- if (MAP_KUTJEVO)
- name = "\improper Kutjevo Refinery map"
- desc = "An orbital scan of Kutjevo Refinery"
- html_link = "images/0/0d/Kutjevo_a1.jpg"
- color = "red"
- if (MAP_LV522_CHANCES_CLAIM)
- name = "\improper LV-522 Map"
- desc = "An overview of LV-522 schematics."
- html_link = "images/b/bb/C_claim.png"
- color = "cyan"
- if (MAP_NEW_VARADERO)
- name = "\improper New Varadero map"
- desc = "The blueprint and readout of the UA outpost New Varadero"
- html_link = "images/9/94/New_Varadero.png"//replace later
- color = "red"
-
- else
- return INITIALIZE_HINT_QDEL
-
+ var/map_name = SSmapping.configs[GROUND_MAP].map_name
+ var/obj/item/map/map = GLOB.map_type_list[map_name]
+ if (!map && (map_name == MAP_RUNTIME || map_name == MAP_CHINOOK || map_name == MAIN_SHIP_DEFAULT_NAME))
+ return // "Maps" we don't have maps for so we don't need to throw a runtime for (namely in unit_testing)
+ name = map.name
+ desc = map.desc
+ html_link = map.html_link
+ color = map.color
// Landmark - Used for mapping. Will spawn the appropriate map for each gamemode (LV map items will spawn when LV is the gamemode, etc)
/obj/effect/landmark/map_item
diff --git a/code/modules/cm_preds/yaut_mask.dm b/code/modules/cm_preds/yaut_mask.dm
index 5d4d21c46c80..be0aa8ed761a 100644
--- a/code/modules/cm_preds/yaut_mask.dm
+++ b/code/modules/cm_preds/yaut_mask.dm
@@ -1,7 +1,5 @@
#define VISION_MODE_OFF 0
#define VISION_MODE_NVG 1
-#define VISION_MODE_THERMAL 2
-#define VISION_MODE_MESON 3
///parent type
/obj/item/clothing/mask/gas/yautja
@@ -65,8 +63,32 @@
/obj/item/clothing/mask/gas/yautja/Destroy()
remove_from_missing_pred_gear(src)
+ STOP_PROCESSING(SSobj, src)
return ..()
+/obj/item/clothing/mask/gas/yautja/process()
+ if(!ishuman(loc))
+ return PROCESS_KILL
+ var/mob/living/carbon/human/human_holder = loc
+
+ if(current_goggles && !drain_power(human_holder, 3))
+ to_chat(human_holder, SPAN_WARNING("Your bracers lack sufficient power to operate the visor."))
+ current_goggles = VISION_MODE_OFF
+ var/obj/item/visor = human_holder.glasses
+ if(istype(visor, /obj/item/clothing/glasses/night/yautja))//To change if any new vision modes are made
+ human_holder.temp_drop_inv_item(visor)
+ qdel(visor)
+ human_holder.update_inv_glasses()
+ human_holder.update_sight()
+
+/obj/item/clothing/mask/gas/yautja/proc/drain_power(mob/living/carbon/human/human_holder, drain_amount)
+ var/obj/item/clothing/gloves/yautja/bracer = human_holder.gloves
+ if(!bracer || !istype(bracer))
+ return FALSE
+ if(!(bracer.drain_power(human_holder, drain_amount)))
+ return FALSE
+ return TRUE
+
/obj/item/clothing/mask/gas/yautja/verb/toggle_zoom()
set name = "Toggle Mask Zoom"
set desc = "Toggle your mask's zoom function."
@@ -82,40 +104,36 @@
set src in usr
if(!usr || usr.stat)
return
- var/mob/living/carbon/human/M = usr
- if(!istype(M))
+ var/mob/living/carbon/human/user = usr
+ if(!istype(user))
return
- if(!HAS_TRAIT(M, TRAIT_YAUTJA_TECH) && !M.hunter_data.thralled)
- to_chat(M, SPAN_WARNING("You have no idea how to work this thing!"))
+ if(!HAS_TRAIT(user, TRAIT_YAUTJA_TECH) && !user.hunter_data.thralled)
+ to_chat(user, SPAN_WARNING("You have no idea how to work this thing!"))
return
- if(src != M.wear_mask) //sanity
- to_chat(M, SPAN_WARNING("You must wear \the [src]!"))
+ if(src != user.wear_mask) //sanity
+ to_chat(user, SPAN_WARNING("You must wear \the [src]!"))
return
- var/obj/item/clothing/gloves/yautja/Y = M.gloves //Doesn't actually reduce power, but needs the bracers anyway.
- if(!Y || !istype(Y))
- to_chat(M, SPAN_WARNING("You must be wearing your bracers, as they have the power source."))
+ var/obj/item/clothing/gloves/yautja/bracer = user.gloves
+ if(!bracer || !istype(bracer))
+ to_chat(user, SPAN_WARNING("You must be wearing your bracers, as they have the power source."))
return
- var/obj/item/G = M.glasses
- if(G)
- if(!istype(G,/obj/item/clothing/glasses/night/yautja) && !istype(G,/obj/item/clothing/glasses/meson/yautja) && !istype(G,/obj/item/clothing/glasses/thermal/yautja))
- to_chat(M, SPAN_WARNING("You need to remove your glasses first. Why are you even wearing these?"))
+ var/obj/item/visor = user.glasses
+ if(visor)
+ if(!istype(visor, /obj/item/clothing/glasses/night/yautja))
+ to_chat(user, SPAN_WARNING("You need to remove your glasses first. Why are you even wearing these?"))
return
- M.temp_drop_inv_item(G) //Get rid of ye existing maicerinho goggles
- qdel(G)
- M.update_inv_glasses()
- M.update_sight()
+ user.temp_drop_inv_item(visor) //Get rid of ye existing maicerinho goggles
+ qdel(visor)
+ user.update_inv_glasses()
+ user.update_sight()
switch_vision_mode()
- add_vision(M)
+ add_vision(user)
/obj/item/clothing/mask/gas/yautja/proc/switch_vision_mode() //switches to the next one
switch(current_goggles)
if(VISION_MODE_OFF)
current_goggles = VISION_MODE_NVG
if(VISION_MODE_NVG)
- current_goggles = VISION_MODE_THERMAL
- if(VISION_MODE_THERMAL)
- current_goggles = VISION_MODE_MESON
- if(VISION_MODE_MESON)
current_goggles = VISION_MODE_OFF
/obj/item/clothing/mask/gas/yautja/proc/add_vision(mob/living/carbon/human/user) //applies current_goggles
@@ -123,38 +141,40 @@
if(VISION_MODE_NVG)
user.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/yautja(user), WEAR_EYES)
to_chat(user, SPAN_NOTICE("Low-light vision module: activated."))
- if(VISION_MODE_THERMAL)
- user.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/yautja(user), WEAR_EYES)
- to_chat(user, SPAN_NOTICE("Thermal vision module: activated."))
- if(VISION_MODE_MESON)
- user.equip_to_slot_or_del(new /obj/item/clothing/glasses/meson/yautja(user), WEAR_EYES)
- to_chat(user, SPAN_NOTICE("Material vision module: activated."))
if(VISION_MODE_OFF)
to_chat(user, SPAN_NOTICE("You deactivate your visor."))
playsound(src, 'sound/effects/pred_vision.ogg', 15, 1)
user.update_inv_glasses()
+#undef VISION_MODE_OFF
+#undef VISION_MODE_NVG
+
/obj/item/clothing/mask/gas/yautja/dropped(mob/living/carbon/human/user) //Clear the gogglors if the helmet is removed.
+ STOP_PROCESSING(SSobj, src)
if(istype(user) && user.wear_mask == src) //inventory reference is only cleared after dropped().
for(var/listed_hud in mask_huds)
var/datum/mob_hud/H = huds[listed_hud]
H.remove_hud_from(user)
- var/obj/item/G = user.glasses
- if(G) //make your hud fuck off
- if(istype(G,/obj/item/clothing/glasses/night/yautja) || istype(G,/obj/item/clothing/glasses/meson/yautja) || istype(G,/obj/item/clothing/glasses/thermal/yautja))
- user.temp_drop_inv_item(G)
- qdel(G)
+ var/obj/item/visor = user.glasses
+ if(visor) //make your hud fuck off
+ if(istype(visor, /obj/item/clothing/glasses/night/yautja))
+ user.temp_drop_inv_item(visor)
+ qdel(visor)
user.update_inv_glasses()
user.update_sight()
..()
/obj/item/clothing/mask/gas/yautja/equipped(mob/living/carbon/human/user, slot)
if(slot == WEAR_FACE)
+ START_PROCESSING(SSobj, src)
for(var/listed_hud in mask_huds)
var/datum/mob_hud/H = huds[listed_hud]
H.add_hud_to(user)
if(current_goggles)
+ var/obj/item/clothing/gloves/yautja/bracer = user.gloves
+ if(!bracer || !istype(bracer))
+ return FALSE
add_vision(user)
..()
@@ -205,30 +225,6 @@
name = "ancient alien mask"
desc = "A beautifully designed metallic face mask, both ornate and functional. This one seems to be old and degraded."
-/obj/item/clothing/mask/gas/yautja/damaged/switch_vision_mode()
- switch(current_goggles)
- if(VISION_MODE_OFF)
- current_goggles = VISION_MODE_NVG
- if(VISION_MODE_NVG)
- current_goggles = VISION_MODE_OFF
-
-/obj/item/clothing/mask/gas/yautja/damaged/add_vision(mob/living/carbon/human/user)
- switch(current_goggles)
- if(VISION_MODE_NVG)
- user.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/yautja(user), WEAR_EYES)
- to_chat(user, SPAN_NOTICE("You activate your visor."))
- if(VISION_MODE_OFF)
- to_chat(user, SPAN_NOTICE("You deactivate your visor."))
-
- playsound(src, 'sound/effects/pred_vision.ogg', 15, 1)
- user.update_inv_glasses()
-
-#undef VISION_MODE_OFF
-#undef VISION_MODE_NVG
-#undef VISION_MODE_THERMAL
-#undef VISION_MODE_MESON
-
-
//flavor, not a subtype
/obj/item/clothing/mask/yautja_flavor
name = "alien stone mask"
diff --git a/code/modules/hydroponics/hydro_tray.dm b/code/modules/hydroponics/hydro_tray.dm
index 65cf76b19a4a..9549b8fa59c1 100644
--- a/code/modules/hydroponics/hydro_tray.dm
+++ b/code/modules/hydroponics/hydro_tray.dm
@@ -210,11 +210,14 @@
// Make sure the plant is not starving or thirsty. Adequate
// water and nutrients will cause a plant to become healthier.
+ // Checks if there are sufficient enough nutrients, if not the plant dies.
var/healthmod = rand(1,3) * HYDRO_SPEED_MULTIPLIER
if(seed.requires_nutrients && prob(35))
plant_health += (nutrilevel < 2 ? -healthmod : healthmod)
if(seed.requires_water && prob(35))
plant_health += (waterlevel < 10 ? -healthmod : healthmod)
+ if(nutrilevel < 1)
+ plant_health = 0
// Check that pressure, heat and light are all within bounds.
// First, handle an open system or an unconnected closed system.
diff --git a/code/modules/mentor/mentorhelp.dm b/code/modules/mentor/mentorhelp.dm
index 84dacf4f8bfb..9aaf1cae517b 100644
--- a/code/modules/mentor/mentorhelp.dm
+++ b/code/modules/mentor/mentorhelp.dm
@@ -64,7 +64,7 @@
if(to_thread_mentor && mentor)
hitlist |= mentor
for(var/client/candidate in GLOB.admins)
- if(to_mentors && CLIENT_HAS_RIGHTS(candidate, R_MENTOR))
+ if(to_mentors && CLIENT_IS_MENTOR(candidate))
hitlist |= candidate
else if(to_staff && CLIENT_IS_STAFF(candidate))
hitlist |= candidate
@@ -137,7 +137,7 @@
if(!sender || !check_open(sender))
return
if(sender != author)
- if(!CLIENT_HAS_RIGHTS(sender, R_MENTOR))
+ if(!CLIENT_IS_MENTOR(sender))
return
// If the mentor forgot to mark the mentorhelp, mark it for them
@@ -201,7 +201,7 @@
return
// Not a mentor/staff
- if(!CLIENT_HAS_RIGHTS(thread_mentor, R_MENTOR))
+ if(!CLIENT_IS_MENTOR(thread_mentor))
return
mentor = thread_mentor
@@ -294,7 +294,7 @@
if(!check_open(responder))
return
- if(!CLIENT_HAS_RIGHTS(responder, R_MENTOR))
+ if(!CLIENT_IS_MENTOR(responder))
return
// If the mentor forgot to mark the mentorhelp, mark it for them
@@ -314,7 +314,7 @@
if(!check_open(responder))
return
- if(!CLIENT_HAS_RIGHTS(responder, R_MENTOR))
+ if(!CLIENT_IS_MENTOR(responder))
return
// Re-mark if they unmarked it while the dialog was open (???)
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index 72a95074e574..a6062276bd8e 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -41,7 +41,7 @@
/// The limit of the oxyloss gained, ignoring oxyloss from the switch statement
var/maximum_oxyloss = Clamp((100 - blood_percentage) / 2, oxyloss, 100)
if(oxyloss < maximum_oxyloss)
- oxyloss += max(additional_oxyloss, 0)
+ oxyloss += round(max(additional_oxyloss, 0))
//Bloodloss effects on nutrition
if(nutrition >= 300)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index d01416b2443f..0d67e7cafd74 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -509,8 +509,11 @@
if(U == w_uniform)
U.remove_accessory(usr, A)
else
+ if(HAS_TRAIT(src, TRAIT_UNSTRIPPABLE) && !is_mob_incapacitated()) //Can't strip the unstrippable!
+ to_chat(usr, SPAN_DANGER("[src] has an unbreakable grip on their equipment!"))
+ return
visible_message(SPAN_DANGER("[usr] is trying to take off \a [A] from [src]'s [U]!"), null, null, 5)
- if(do_after(usr, HUMAN_STRIP_DELAY, INTERRUPT_ALL, BUSY_ICON_GENERIC, src, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
+ if(do_after(usr, get_strip_delay(usr, src), INTERRUPT_ALL, BUSY_ICON_GENERIC, src, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
if(U == w_uniform)
U.remove_accessory(usr, A)
@@ -529,7 +532,7 @@
else
var/oldsens = U.has_sensor
visible_message(SPAN_DANGER("[usr] is trying to modify [src]'s sensors!"), null, null, 4)
- if(do_after(usr, HUMAN_STRIP_DELAY, INTERRUPT_ALL, BUSY_ICON_GENERIC, src, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
+ if(do_after(usr, get_strip_delay(usr, src), INTERRUPT_ALL, BUSY_ICON_GENERIC, src, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
if(U == w_uniform)
if(U.has_sensor >= UNIFORM_FORCED_SENSORS)
to_chat(usr, "The controls are locked.")
@@ -1387,6 +1390,7 @@
lighting_alpha = default_lighting_alpha
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = species.darksight
+ sight |= species.flags_sight
if(glasses)
process_glasses(glasses)
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 835e03c8e042..45fb65771069 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -486,63 +486,82 @@
return WEAR_LEGCUFFS
return ..()
-
-
-/mob/living/carbon/human/stripPanelUnequip(obj/item/I, mob/M, slot_to_process)
- if(I.flags_item & ITEM_ABSTRACT)
+/mob/living/carbon/human/proc/get_strip_delay(mob/living/carbon/human/user, mob/living/carbon/human/target)
+ /// Default delay
+ var/target_delay = HUMAN_STRIP_DELAY
+ /// Multiplier for how quickly the user can strip things.
+ var/user_speed = user.get_skill_duration_multiplier(SKILL_CQC)
+ /// The total skill level of CQC & Police
+ var/target_skills = (target.skills.get_skill_level(SKILL_CQC) + target.skills.get_skill_level(SKILL_POLICE))
+
+ /// Delay then gets + 0.5s per skill level, so long as not dead or cuffed.
+ if(!(target.stat || target.handcuffed))
+ target_delay += (target_skills * 5)
+
+ /// Final result is overall delay * speed multiplier
+ return target_delay * user_speed
+
+/mob/living/carbon/human/stripPanelUnequip(obj/item/interact_item, mob/target_mob, slot_to_process)
+ if(HAS_TRAIT(target_mob, TRAIT_UNSTRIPPABLE) && !target_mob.is_mob_incapacitated()) //Can't strip the unstrippable!
+ to_chat(src, SPAN_DANGER("[target_mob] has an unbreakable grip on their equipment!"))
+ return
+ if(interact_item.flags_item & ITEM_ABSTRACT)
+ return
+ if(interact_item.flags_item & NODROP)
+ to_chat(src, SPAN_WARNING("You can't remove \the [interact_item.name], it appears to be stuck!"))
return
- if(I.flags_item & NODROP)
- to_chat(src, SPAN_WARNING("You can't remove \the [I.name], it appears to be stuck!"))
+ if(interact_item.flags_inventory & CANTSTRIP)
+ to_chat(src, SPAN_WARNING("You're having difficulty removing \the [interact_item.name]."))
return
- if(I.flags_inventory & CANTSTRIP)
- to_chat(src, SPAN_WARNING("You're having difficulty removing \the [I.name]."))
+ target_mob.attack_log += "\[[time_stamp()]\] Has had their [interact_item.name] ([slot_to_process]) attempted to be removed by [key_name(src)]"
+ attack_log += "\[[time_stamp()]\] Attempted to remove [key_name(target_mob)]'s [interact_item.name] ([slot_to_process])"
+ log_interact(src, target_mob, "[key_name(src)] tried to remove [key_name(target_mob)]'s [interact_item.name] ([slot_to_process]).")
+
+ src.visible_message(SPAN_DANGER("[src] tries to remove [target_mob]'s [interact_item.name]."), \
+ SPAN_DANGER("You are trying to remove [target_mob]'s [interact_item.name]."), null, 5)
+ interact_item.add_fingerprint(src)
+ if(do_after(src, get_strip_delay(src, target_mob), INTERRUPT_ALL, BUSY_ICON_GENERIC, target_mob, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
+ if(interact_item && Adjacent(target_mob) && interact_item == target_mob.get_item_by_slot(slot_to_process))
+ target_mob.drop_inv_item_on_ground(interact_item)
+ log_interact(src, target_mob, "[key_name(src)] removed [key_name(target_mob)]'s [interact_item.name] ([slot_to_process]) successfully.")
+
+ if(target_mob)
+ if(interactee == target_mob && Adjacent(target_mob))
+ target_mob.show_inv(src)
+
+
+/mob/living/carbon/human/stripPanelEquip(obj/item/interact_item, mob/target_mob, slot_to_process)
+ if(HAS_TRAIT(target_mob, TRAIT_UNSTRIPPABLE) && !target_mob.is_mob_incapacitated())
+ to_chat(src, SPAN_DANGER("[target_mob] is too strong to force [interact_item.name] onto them!"))
return
- M.attack_log += "\[[time_stamp()]\] Has had their [I.name] ([slot_to_process]) attempted to be removed by [key_name(src)]"
- attack_log += "\[[time_stamp()]\] Attempted to remove [key_name(M)]'s [I.name] ([slot_to_process])"
- log_interact(src, M, "[key_name(src)] tried to remove [key_name(M)]'s [I.name] ([slot_to_process]).")
-
- src.visible_message(SPAN_DANGER("[src] tries to remove [M]'s [I.name]."), \
- SPAN_DANGER("You are trying to remove [M]'s [I.name]."), null, 5)
- I.add_fingerprint(src)
- if(do_after(src, HUMAN_STRIP_DELAY * src.get_skill_duration_multiplier(SKILL_CQC), INTERRUPT_ALL, BUSY_ICON_GENERIC, M, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
- if(I && Adjacent(M) && I == M.get_item_by_slot(slot_to_process))
- M.drop_inv_item_on_ground(I)
- log_interact(src, M, "[key_name(src)] removed [key_name(M)]'s [I.name] ([slot_to_process]) successfully.")
-
- if(M)
- if(interactee == M && Adjacent(M))
- M.show_inv(src)
-
-
-/mob/living/carbon/human/stripPanelEquip(obj/item/I, mob/M, slot_to_process)
- if(I && !(I.flags_item & ITEM_ABSTRACT))
- if(I.flags_item & NODROP)
- to_chat(src, SPAN_WARNING("You can't put \the [I.name] on [M], it's stuck to your hand!"))
+ if(interact_item && !(interact_item.flags_item & ITEM_ABSTRACT))
+ if(interact_item.flags_item & NODROP)
+ to_chat(src, SPAN_WARNING("You can't put \the [interact_item.name] on [target_mob], it's stuck to your hand!"))
return
- if(I.flags_inventory & CANTSTRIP)
- to_chat(src, SPAN_WARNING("You're having difficulty putting \the [I.name] on [M]."))
+ if(interact_item.flags_inventory & CANTSTRIP)
+ to_chat(src, SPAN_WARNING("You're having difficulty putting \the [interact_item.name] on [target_mob]."))
return
- if(I.flags_item & WIELDED)
- I.unwield(src)
- if(!I.mob_can_equip(M, slot_to_process, TRUE))
- to_chat(src, SPAN_WARNING("You can't put \the [I.name] on [M]!"))
+ if(interact_item.flags_item & WIELDED)
+ interact_item.unwield(src)
+ if(!interact_item.mob_can_equip(target_mob, slot_to_process, TRUE))
+ to_chat(src, SPAN_WARNING("You can't put \the [interact_item.name] on [target_mob]!"))
return
- visible_message(SPAN_NOTICE("[src] tries to put \the [I.name] on [M]."), null, null, 5)
- if(do_after(src, HUMAN_STRIP_DELAY * src.get_skill_duration_multiplier(SKILL_CQC), INTERRUPT_ALL, BUSY_ICON_GENERIC, M, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
- if(I == get_active_hand() && !M.get_item_by_slot(slot_to_process) && Adjacent(M))
- if(I.flags_item & WIELDED) //to prevent re-wielding it during the do_after
- I.unwield(src)
- if(I.mob_can_equip(M, slot_to_process, TRUE))//Placing an item on the mob
- drop_inv_item_on_ground(I)
- if(I && !QDELETED(I)) //Might be self-deleted?
- M.equip_to_slot_if_possible(I, slot_to_process, 1, 0, 1, 1)
- if(ishuman(M) && M.stat == DEAD)
- var/mob/living/carbon/human/H = M
- H.disable_lights() // take that powergamers -spookydonut
-
- if(M)
- if(interactee == M && Adjacent(M))
- M.show_inv(src)
+ visible_message(SPAN_NOTICE("[src] tries to put \the [interact_item.name] on [target_mob]."), null, null, 5)
+ if(do_after(src, get_strip_delay(src, target_mob), INTERRUPT_ALL, BUSY_ICON_GENERIC, target_mob, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
+ if(interact_item == get_active_hand() && !target_mob.get_item_by_slot(slot_to_process) && Adjacent(target_mob))
+ if(interact_item.flags_item & WIELDED) //to prevent re-wielding it during the do_after
+ interact_item.unwield(src)
+ if(interact_item.mob_can_equip(target_mob, slot_to_process, TRUE))//Placing an item on the mob
+ drop_inv_item_on_ground(interact_item)
+ if(interact_item && !QDELETED(interact_item)) //Might be self-deleted?
+ target_mob.equip_to_slot_if_possible(interact_item, slot_to_process, 1, 0, 1, 1)
+ if(ishuman(target_mob) && target_mob.stat == DEAD)
+ var/mob/living/carbon/human/human_target = target_mob
+ human_target.disable_lights() // take that powergamers -spookydonut
+
+ if(target_mob)
+ if(interactee == target_mob && Adjacent(target_mob))
+ target_mob.show_inv(src)
/mob/living/carbon/human/drop_inv_item_on_ground(obj/item/I, nomoveupdate, force)
remember_dropped_object(I)
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index b6eeb68e95d3..f6487d1faf1c 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -63,6 +63,7 @@
var/darksight = 2
var/default_lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
+ var/flags_sight = 0
var/brute_mod = null // Physical damage reduction/malus.
var/burn_mod = null // Burn damage reduction/malus.
diff --git a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm
index 139b339fbfd7..292c302f9317 100644
--- a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm
@@ -4,7 +4,7 @@
death_message = "violently gargles fluid and seizes up, the glow in their eyes dimming..."
uses_ethnicity = FALSE
burn_mod = 0.65 // made for hazardous environments, withstanding temperatures up to 1210 degrees
- mob_inherent_traits = list(TRAIT_SUPER_STRONG, TRAIT_INTENT_EYES, TRAIT_EMOTE_CD_EXEMPT, TRAIT_CANNOT_EAT)
+ mob_inherent_traits = list(TRAIT_SUPER_STRONG, TRAIT_INTENT_EYES, TRAIT_EMOTE_CD_EXEMPT, TRAIT_CANNOT_EAT, TRAIT_UNSTRIPPABLE)
slowdown = 0.45
hair_color = "#000000"
diff --git a/code/modules/mob/living/carbon/human/species/yautja/_species.dm b/code/modules/mob/living/carbon/human/species/yautja/_species.dm
index 8e8849f5ad4c..f8ecb3e0591b 100644
--- a/code/modules/mob/living/carbon/human/species/yautja/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/yautja/_species.dm
@@ -25,6 +25,8 @@
speech_chance = 100
death_message = "clicks in agony and falls still, motionless and completely lifeless..."
darksight = 5
+ default_lighting_alpha = LIGHTING_PLANE_ALPHA_YAUTJA
+ flags_sight = SEE_MOBS
slowdown = -0.5
total_health = 175 //more health than regular humans
timed_hug = FALSE
diff --git a/code/modules/mob/living/carbon/human/species/zombie.dm b/code/modules/mob/living/carbon/human/species/zombie.dm
index 532d9413102c..07fe8f5e1255 100644
--- a/code/modules/mob/living/carbon/human/species/zombie.dm
+++ b/code/modules/mob/living/carbon/human/species/zombie.dm
@@ -1,8 +1,12 @@
+// DEFINES
+///Time until a zombie rises from the dead
+#define ZOMBIE_REVIVE_TIME 1 MINUTES
+
/datum/species/zombie
group = SPECIES_HUMAN
name = SPECIES_ZOMBIE
name_plural = "Zombies"
- slowdown = 1
+ slowdown = 0.75
blood_color = BLOOD_COLOR_ZOMBIE
icobase = 'icons/mob/humans/species/r_goo_zed.dmi'
deform = 'icons/mob/humans/species/r_goo_zed.dmi'
@@ -12,7 +16,7 @@
death_message = "seizes up and falls limp..."
flags = NO_BREATHE|NO_CLONE_LOSS|NO_POISON|NO_NEURO|NO_SHRAPNEL
mob_inherent_traits = list(TRAIT_FOREIGN_BIO)
- brute_mod = 0.25 //EXTREME BULLET RESISTANCE
+ brute_mod = 0.6 //Minor bullet resistance
burn_mod = 0.8 //Lowered burn damage since it would 1-shot zombies from 2 to 0.8.
speech_chance = 5
cold_level_1 = -1 //zombies don't mind the cold
@@ -96,7 +100,7 @@
zombie.play_screen_text("You are dead...
You will rise again in one minute.", /atom/movable/screen/text/screen_text/command_order, rgb(155, 0, 200))
to_chat(zombie, SPAN_XENOWARNING("You fall... but your body is slowly regenerating itself."))
var/weak_ref = WEAKREF(zombie)
- to_revive[weak_ref] = addtimer(CALLBACK(src, PROC_REF(revive_from_death), zombie, "[REF(zombie)]"), 1 MINUTES, TIMER_STOPPABLE|TIMER_OVERRIDE|TIMER_UNIQUE|TIMER_NO_HASH_WAIT)
+ to_revive[weak_ref] = addtimer(CALLBACK(src, PROC_REF(revive_from_death), zombie, "[REF(zombie)]"), ZOMBIE_REVIVE_TIME, TIMER_STOPPABLE|TIMER_OVERRIDE|TIMER_UNIQUE|TIMER_NO_HASH_WAIT)
revive_times[weak_ref] = world.time + 1 MINUTES
else
if(zombie.client)
diff --git a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm
index 667367339698..37b0aa037cd1 100644
--- a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm
@@ -18,7 +18,7 @@
if(SSticker.mode && SSticker.mode.xenomorphs.len) //Send to only xenos in our gamemode list. This is faster than scanning all mobs
for(var/datum/mind/L in SSticker.mode.xenomorphs)
var/mob/living/carbon/M = L.current
- if(M && istype(M) && !M.stat && M.client && (!hivenumber || M.ally_of_hivenumber(hivenumber))) //Only living and connected xenos
+ if(M && istype(M) && !M.stat && M.client && (!hivenumber || M.hivenumber == hivenumber)) //Only living and connected xenos
to_chat(M, SPAN_XENODANGER(" [message]"))
//Sends a maptext alert to our currently selected squad. Does not make sound.
diff --git a/code/modules/mob/living/carbon/xenomorph/death.dm b/code/modules/mob/living/carbon/xenomorph/death.dm
index 12c9b3e37c9b..56f9460f5c71 100644
--- a/code/modules/mob/living/carbon/xenomorph/death.dm
+++ b/code/modules/mob/living/carbon/xenomorph/death.dm
@@ -69,10 +69,11 @@
if(!QDELETED(Q) && Q != src && Q.hivenumber == hivenumber)
hive.set_living_xeno_queen(Q)
break
+ hive.on_queen_death()
hive.handle_xeno_leader_pheromones()
if(SSticker.mode)
INVOKE_ASYNC(SSticker.mode, TYPE_PROC_REF(/datum/game_mode, check_queen_status), hivenumber)
- LAZYADD(SSticker.mode.dead_queens, "
[!isnull(src.key) ? src.key : "?"] was [src] [SPAN_BOLDNOTICE("(DIED)")]")
+ LAZYADD(SSticker.mode.dead_queens, "
[!isnull(full_designation) ? full_designation : "?"] was [src] [SPAN_BOLDNOTICE("(DIED)")]")
else if(ispredalien(src))
playsound(loc,'sound/voice/predalien_death.ogg', 25, TRUE)
diff --git a/code/modules/mob/living/carbon/xenomorph/hive_faction.dm b/code/modules/mob/living/carbon/xenomorph/hive_faction.dm
index 10af37b8d8e8..e16a5cccd915 100644
--- a/code/modules/mob/living/carbon/xenomorph/hive_faction.dm
+++ b/code/modules/mob/living/carbon/xenomorph/hive_faction.dm
@@ -56,6 +56,5 @@ GLOBAL_LIST_INIT(hive_alliable_factions, generate_alliable_factions())
return
var/should_ally = text2num(params["should_ally"])
- assoc_hive.allies[params["target_faction"]] = should_ally
- assoc_hive.on_stance_change(params["target_faction"])
+ assoc_hive.change_stance(params["target_faction"], should_ally)
. = TRUE
diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
index 8a1f0ce00f3b..c2bf91edde6e 100644
--- a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
@@ -1390,13 +1390,32 @@
/datum/hive_status/corrupted/renegade/faction_is_ally(faction, ignore_queen_check = TRUE)
return ..()
-/datum/hive_status/proc/on_stance_change(faction)
- if(!living_xeno_queen)
+/datum/hive_status/proc/on_queen_death() //break alliances on queen's death
+ if(allow_no_queen_actions || living_xeno_queen)
return
- if(allies[faction])
- xeno_message(SPAN_XENOANNOUNCE("Your Queen set up an alliance with [faction]!"), 3, hivenumber)
- else
- xeno_message(SPAN_XENOANNOUNCE("Your Queen broke the alliance with [faction]!"), 3, hivenumber)
+ var/broken_alliances = FALSE
+ for(var/faction in allies)
+ if(!allies[faction])
+ continue
+ change_stance(faction, FALSE)
+ broken_alliances = TRUE
+
+
+ if(broken_alliances)
+ xeno_message(SPAN_XENOANNOUNCE("With the death of the Queen, all alliances have been broken."), 3, hivenumber)
+
+/datum/hive_status/proc/change_stance(faction, should_ally)
+ if(faction == name)
+ return
+ if(allies[faction] == should_ally)
+ return
+ allies[faction] = should_ally
+
+ if(living_xeno_queen)
+ if(allies[faction])
+ xeno_message(SPAN_XENOANNOUNCE("Your Queen set up an alliance with [faction]!"), 3, hivenumber)
+ else
+ xeno_message(SPAN_XENOANNOUNCE("Your Queen broke the alliance with [faction]!"), 3, hivenumber)
for(var/number in GLOB.hive_datum)
var/datum/hive_status/target_hive = GLOB.hive_datum[number]
@@ -1405,12 +1424,15 @@
if(!target_hive.living_xeno_queen && !target_hive.allow_no_queen_actions)
return
if(allies[faction])
- xeno_message(SPAN_XENOANNOUNCE("You sense that [name] Queen set up an alliance with us!"), 3, target_hive.hivenumber)
+ xeno_message(SPAN_XENOANNOUNCE("You sense that [name] [living_xeno_queen ? "Queen " : ""]set up an alliance with us!"), 3, target_hive.hivenumber)
return
- xeno_message(SPAN_XENOANNOUNCE("You sense that [name] Queen broke the alliance with us!"), 3, target_hive.hivenumber)
+ xeno_message(SPAN_XENOANNOUNCE("You sense that [name] [living_xeno_queen ? "Queen " : ""]broke the alliance with us!"), 3, target_hive.hivenumber)
+ if(target_hive.allies[name]) //autobreak alliance on betrayal
+ target_hive.change_stance(name, FALSE)
+
-/datum/hive_status/corrupted/on_stance_change(faction)
+/datum/hive_status/corrupted/change_stance(faction, should_ally)
. = ..()
if(allies[faction])
return
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 352b1d2a6be5..832f243a9602 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -616,7 +616,7 @@ As sniper rifles have both and weapon mods can change them as well. ..() deals w
if(in_chamber && in_chamber.ammo)
in_ammo = in_chamber.ammo
else if(current_mag && current_mag.current_rounds > 0)
- if(istype(current_mag) && current_mag.chamber_contents[current_mag.chamber_position] != "empty")
+ if(istype(current_mag) && length(current_mag.chamber_contents) && current_mag.chamber_contents[current_mag.chamber_position] != "empty")
in_ammo = GLOB.ammo_list[current_mag.chamber_contents[current_mag.chamber_position]]
if(!istype(in_ammo))
in_ammo = GLOB.ammo_list[current_mag.default_ammo]
diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm
index 7e620b6bc1fa..9ed3183e5b3d 100644
--- a/code/modules/unit_tests/_unit_tests.dm
+++ b/code/modules/unit_tests/_unit_tests.dm
@@ -74,6 +74,7 @@
/// A trait source when adding traits through unit tests
#define TRAIT_SOURCE_UNIT_TESTS "unit_tests"
+#include "autowiki.dm"
#include "create_and_destroy.dm"
#include "focus_only_tests.dm"
#include "missing_icons.dm"
diff --git a/code/modules/unit_tests/autowiki.dm b/code/modules/unit_tests/autowiki.dm
new file mode 100644
index 000000000000..65ec2e228dd2
--- /dev/null
+++ b/code/modules/unit_tests/autowiki.dm
@@ -0,0 +1,35 @@
+/// Tests that all autowikis generate something without runtiming
+/datum/unit_test/autowiki
+
+/datum/unit_test/autowiki/Run()
+ TEST_ASSERT(istext(generate_autowiki_output()), "generate_autowiki_output() did not finish successfully!")
+
+/// Test that `include_template` produces reasonable results
+/datum/unit_test/autowiki_include_template
+
+/datum/unit_test/autowiki_include_template/Run()
+ var/datum/autowiki/autowiki_api = new
+
+ TEST_ASSERT_EQUAL( \
+ autowiki_api.include_template("Template"), \
+ "{{Template}}", \
+ "Basic template did not format correctly" \
+ )
+
+ TEST_ASSERT_EQUAL( \
+ autowiki_api.include_template("Template", list("name" = "Mothblocks")), \
+ "{{Template|name=Mothblocks}}", \
+ "Template with basic arguments did not format correctly" \
+ )
+
+ TEST_ASSERT_EQUAL( \
+ autowiki_api.include_template("Template", list("name" = autowiki_api.escape_value("P|peline"))), \
+ "{{Template|name=P{{!}}peline}}", \
+ "Template with escaped arguments did not format correctly" \
+ )
+
+ TEST_ASSERT_EQUAL( \
+ autowiki_api.include_template("Template", list("food" = list("fruit", "candy"))), \
+ "{{Template|food1=fruit|food2=candy}}", \
+ "Template with array arguments did not format correctly" \
+ )
diff --git a/code/span_macros.dm b/code/span_macros.dm
index 1eca82ea563f..77e57f2077a0 100644
--- a/code/span_macros.dm
+++ b/code/span_macros.dm
@@ -46,6 +46,7 @@
#define SPAN_ADMIN(X) "[X]"
#define SPAN_ADMINHELP(X) ("" + X + "")
#define SPAN_ADMINSAY(str) ("" + str + "")
+#define SPAN_MOD(str) ("" + str + "")
#define SPAN_MENTORHELP(X) ("" + X + "")
#define SPAN_MENTORSAY(X) ("" + X + "")
#define SPAN_MENTORBODY(X) ("" + X + "")
diff --git a/colonialmarines.dme b/colonialmarines.dme
index de88183b3734..a3045760a2f7 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -1402,6 +1402,9 @@
#include "code\modules\asset_cache\assets\vending.dm"
#include "code\modules\asset_cache\transports\asset_transport.dm"
#include "code\modules\asset_cache\transports\webroot_transport.dm"
+#include "code\modules\autowiki\autowiki.dm"
+#include "code\modules\autowiki\pages\_page.dm"
+#include "code\modules\autowiki\pages\guns.dm"
#include "code\modules\buildmode\bm-mode.dm"
#include "code\modules\buildmode\buildmode.dm"
#include "code\modules\buildmode\buttons.dm"
diff --git a/config/example/config.txt b/config/example/config.txt
index 1fee5c898574..181e10e8e150 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -131,7 +131,7 @@ GUEST_BAN
FORUMURL https://forum.cm-ss13.com/
## Wiki address
-WIKIURL https://cm-ss13/wiki/
+WIKIURL https://cm-ss13.com/w
## Rules address
RULESURL https://cm-ss13.com/viewtopic.php?f=57&t=5094
diff --git a/html/changelogs/AutoChangeLog-pr-4073.yml b/html/changelogs/AutoChangeLog-pr-4073.yml
deleted file mode 100644
index aca9a327dd6c..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4073.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Huffie56"
-delete-after: True
-changes:
- - spellcheck: "fix typo mistake from matchs to matches."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4192.yml b/html/changelogs/AutoChangeLog-pr-4192.yml
new file mode 100644
index 000000000000..cf75c5562e04
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4192.yml
@@ -0,0 +1,5 @@
+author: "Drathek"
+delete-after: True
+changes:
+ - bugfix: "Fixed mapped in maps for solaris ridge not opening correctly."
+ - refactor: "Refactored current_map to use a global list instead to remove the need for duplicate definitions."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4196.yml b/html/changelogs/AutoChangeLog-pr-4196.yml
new file mode 100644
index 000000000000..70f42836a8de
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4196.yml
@@ -0,0 +1,4 @@
+author: "Drathek"
+delete-after: True
+changes:
+ - ui: "Fix Hotkeys TGUI lag and the inability to map Ctrl + R. Also now offers a little bit more time to map combinations of keys."
\ No newline at end of file
diff --git a/html/changelogs/archive/2023-08.yml b/html/changelogs/archive/2023-08.yml
index 7908913b8d9d..097cc288fa17 100644
--- a/html/changelogs/archive/2023-08.yml
+++ b/html/changelogs/archive/2023-08.yml
@@ -193,3 +193,82 @@
Steelpoint:
- bugfix: Synthetic Breaching Hammer will now properly appear on the user's back
when holstered.
+2023-08-13:
+ Huffie56:
+ - spellcheck: fix typo mistake from matchs to matches.
+ Morrow:
+ - rscadd: At end of round it now shows a Queen's prefix/postfix rather than their
+ ckey
+ blackdragonTOW:
+ - admin: Adjustment of ASay color
+ ihatethisengine:
+ - rscadd: All hive's alliances break on Queen's death.
+ - qol: If a hive breaks an alliance with another, the second hive also breaks the
+ alliance.
+ - bugfix: xeno_message no longer sends the message to allied hives
+ mothblocks, harry:
+ - rscadd: added the backend functionality for autowiki, alongside automating much
+ of the work of maintaining guns on the wiki
+ realforest2001:
+ - bugfix: Picking up a Yautja mask now correctly checks for bracers to apply the
+ visor.
+ - rscadd: Added backend for species datums to hold inherent vision flags.
+ - rscadd: Added proc for Yautja mask to pass power drain back to bracers. Added
+ small power drain on use of mask visor.
+ - rscadd: Added natural thermal vision and very weak night vision to Yautja species,
+ to fit with our wiki lore.
+ - rscdel: Removed Thermal and Meson visors from Yautja mask.
+ - bugfix: Squad Specialists can no longer bypass restrictions by not selecting a
+ kit to use.
+2023-08-14:
+ Morrow:
+ - rscadd: Rounded oxyloss from bloodloss
+ SpartanBobby:
+ - maptweak: Fixes use of wrong areas inside LV522 reactor
+2023-08-15:
+ Drathek:
+ - rscadd: Queen jellies now use designation rather than ckey for attribution
+ - bugfix: Random facts now only check players.
+ Huffie56:
+ - bugfix: spraying with the hose will no cost 5u of water while spaying 5u of water.
+ - bugfix: fixed the verb to take out the hose.
+ - bugfix: remove the option to change the output as it was confusing for people.
+ MikeKuwait:
+ - bugfix: The plant dies if no nutriment is available
+ realforest2001:
+ - rscadd: Added a proc to calculate item strip delay, taking into account the target's
+ skills and adding 0.5s per level in Policing and CQC.
+ - rscadd: Added an unstrippable mob trait to prevent inventory manipulation. Gave
+ this trait to Working Joes.
+2023-08-17:
+ realforest2001:
+ - bugfix: Players joining as Working Joe after round start now spawn in correct
+ place.
+2023-08-18:
+ Ben10083:
+ - bugfix: Prompt allowing staff to call for ERT with an announcement fixed to actually
+ appear
+ - ui: Prompts for admin-calling ERT converted to TGUI.
+ - maptweak: Combat Information Center pens now use black ink
+ - balance: Zombie attacks deal less damage and only slow down targets (not superslow
+ as they currently do)
+ - balance: Zombie resistances have been reduced heavily, making them far more susceptible
+ to brute damage. Their speed has been doubled to compensate
+ - balance: Black goo on tiles now requires you to not wear shoes to have chance
+ for infection
+ - bugfix: Zombie attacks now only apply effects such as slow and infection if the
+ attack is valid (if the zombie is able to attack)
+ SpartanBobby gdifirehawk:
+ - rscadd: Subtype of tunnel added "Maintenance Tunnel" currently only on LV522 these
+ tunnels act the same as regular tunnels but look different, keep an eye out
+ marines. Description by GDIFIREHAWK
+ ihatethisengine:
+ - rscadd: foxtrot cryomarines spawn as freed mobs if not taken.
+ realforest2001:
+ - rscadd: Added prefixes in OOC for Staff and Mentors. Created a proc to check for
+ these prefixes and Donator.
+ - bugfix: Fixed isCouncil check.
+ spartanbobby:
+ - maptweak: Replaces some cave walls on LV624 with junglewalls (nothing will change
+ gameplay wise)
+ - maptweak: Adds bin to Research Chem/Req room and moves item blocking pillbox
diff --git a/icons/ooc.dmi b/icons/ooc.dmi
new file mode 100644
index 000000000000..8b15b1e49239
Binary files /dev/null and b/icons/ooc.dmi differ
diff --git a/maps/map_files/LV522_Chances_Claim/LV522_Chances_Claim.dmm b/maps/map_files/LV522_Chances_Claim/LV522_Chances_Claim.dmm
index a961b1aa6ddb..f8b678e825dd 100644
--- a/maps/map_files/LV522_Chances_Claim/LV522_Chances_Claim.dmm
+++ b/maps/map_files/LV522_Chances_Claim/LV522_Chances_Claim.dmm
@@ -9673,13 +9673,12 @@
/turf/closed/wall/mineral/bone_resin,
/area/lv522/oob)
"evu" = (
-/obj/structure/prop/maintenance_hatch{
+/obj/structure/tunnel/maint_tunnel{
pixel_y = 6
},
/obj/structure/machinery/light/small{
dir = 1
},
-/obj/structure/barricade/handrail,
/turf/open/floor/plating,
/area/lv522/landing_zone_1/tunnel)
"evv" = (
@@ -9814,13 +9813,10 @@
},
/area/lv522/atmos/east_reactor)
"exQ" = (
-/obj/structure/prop/maintenance_hatch{
- pixel_y = 6
- },
/obj/structure/machinery/light/small{
dir = 1
},
-/obj/structure/barricade/handrail,
+/obj/structure/largecrate,
/obj/effect/landmark/lv624/fog_blocker/short,
/turf/open/floor/plating,
/area/lv522/landing_zone_1/tunnel)
@@ -14472,7 +14468,7 @@
/turf/open/floor/plating,
/area/lv522/landing_zone_1/tunnel)
"gul" = (
-/obj/structure/prop/maintenance_hatch{
+/obj/structure/tunnel/maint_tunnel{
pixel_y = 6
},
/turf/open/floor/prison{
@@ -20477,14 +20473,10 @@
},
/area/lv522/landing_zone_2)
"iGD" = (
-/obj/structure/prop/maintenance_hatch{
+/obj/structure/tunnel/maint_tunnel{
pixel_y = 6
},
/obj/structure/machinery/light/small,
-/obj/structure/barricade/handrail{
- dir = 1;
- pixel_y = 9
- },
/turf/open/floor/plating,
/area/lv522/landing_zone_1/tunnel)
"iGF" = (
@@ -23654,9 +23646,6 @@
icon_state = "brown"
},
/area/lv522/atmos/reactor_garage)
-"jMN" = (
-/turf/open/floor/corsat,
-/area/lv522/oob)
"jMZ" = (
/obj/structure/surface/table/almayer,
/obj/item/tool/pen/blue/clicky{
@@ -24211,7 +24200,7 @@
/turf/open/floor/corsat,
/area/lv522/atmos/east_reactor)
"jYp" = (
-/obj/structure/prop/maintenance_hatch{
+/obj/structure/tunnel/maint_tunnel{
pixel_y = 6
},
/turf/open/floor/prison{
@@ -29360,7 +29349,7 @@
"lTi" = (
/obj/structure/girder,
/turf/open/floor/corsat,
-/area/lv522/oob)
+/area/lv522/atmos/east_reactor/south)
"lTj" = (
/obj/structure/prop/invuln/minecart_tracks,
/obj/structure/prop/invuln/minecart_tracks{
@@ -29877,10 +29866,6 @@
},
/turf/open/floor/plating/plating_catwalk/prison,
/area/lv522/atmos/filt)
-"mdZ" = (
-/obj/structure/window/framed/corsat,
-/turf/open/floor/corsat,
-/area/lv522/oob)
"meb" = (
/obj/structure/largecrate/random{
layer = 2.9
@@ -36946,10 +36931,6 @@
icon_state = "floor_plate"
},
/area/lv522/atmos/reactor_garage)
-"oLU" = (
-/obj/effect/landmark/structure_spawner/setup/distress/xeno_door,
-/turf/open/floor/corsat,
-/area/lv522/oob)
"oLW" = (
/obj/structure/pipes/standard/simple/hidden/green{
dir = 4
@@ -37360,7 +37341,7 @@
/obj/effect/landmark/structure_spawner/setup/distress/xeno_door,
/obj/structure/pipes/standard/simple/hidden/green,
/turf/open/floor/corsat,
-/area/lv522/oob)
+/area/lv522/atmos/east_reactor/south)
"oVA" = (
/obj/structure/surface/table/reinforced/almayer_B,
/obj/item/reagent_container/food/drinks/coffee,
@@ -56350,7 +56331,7 @@
"vKP" = (
/obj/item/stack/sheet/metal,
/turf/open/floor/corsat,
-/area/lv522/oob)
+/area/lv522/atmos/east_reactor/south)
"vKR" = (
/obj/structure/pipes/standard/simple/hidden/green{
dir = 5
@@ -56804,7 +56785,7 @@
/area/lv522/indoors/a_block/executive)
"vSV" = (
/obj/effect/decal/cleanable/dirt,
-/obj/structure/prop/maintenance_hatch{
+/obj/structure/tunnel/maint_tunnel{
pixel_y = 6
},
/turf/open/floor/prison{
@@ -82573,8 +82554,8 @@ saC
saC
tiQ
iBI
-uFG
-nbD
+xmD
+xCS
tiQ
tiQ
tiQ
@@ -83479,7 +83460,7 @@ tjg
tjg
hJB
qUQ
-eLV
+vlq
xmD
hna
yiu
@@ -83933,7 +83914,7 @@ fsC
kbV
hJB
qUQ
-oLU
+pwX
knt
qjG
yiu
@@ -83949,7 +83930,7 @@ xmD
xmD
tiQ
kEA
-mdZ
+seF
tiQ
saC
saC
@@ -84160,7 +84141,7 @@ tjg
tjg
hJB
qUQ
-oLU
+pwX
knt
qjG
yiu
@@ -84387,7 +84368,7 @@ tjg
tjg
hJB
qUQ
-eLV
+vlq
knt
hna
yiu
@@ -90553,7 +90534,7 @@ jjl
hLY
vDw
rbZ
-jMN
+qjG
bjd
rMD
eZF
@@ -90780,7 +90761,7 @@ iFk
jef
pfj
qjG
-jMN
+qjG
bjd
nRy
pqQ
@@ -91234,7 +91215,7 @@ hna
wea
hLY
dpz
-jMN
+qjG
bjd
lfj
pqQ
diff --git a/maps/map_files/LV624/LV624.dmm b/maps/map_files/LV624/LV624.dmm
index a8aac22505c8..c0babffe0d94 100644
--- a/maps/map_files/LV624/LV624.dmm
+++ b/maps/map_files/LV624/LV624.dmm
@@ -2515,6 +2515,9 @@
/obj/structure/flora/jungle/alienplant1,
/turf/open/gm/grass/grass1,
/area/lv624/ground/barrens/south_eastern_jungle_barrens)
+"amk" = (
+/turf/closed/wall/strata_ice/jungle,
+/area/lv624/ground/caves/north_west_caves)
"aml" = (
/obj/structure/disposalpipe/segment,
/obj/structure/grille,
@@ -15370,6 +15373,9 @@
/obj/structure/xenoautopsy/tank/broken,
/turf/open/gm/dirt,
/area/lv624/lazarus/crashed_ship_containers)
+"iIB" = (
+/turf/closed/wall/strata_ice/jungle,
+/area/lv624/ground/caves/south_central_caves)
"iIF" = (
/turf/open/gm/dirtgrassborder/grassdirt_corner2/north_east,
/area/lv624/ground/barrens/south_eastern_barrens)
@@ -17144,6 +17150,9 @@
icon_state = "whiteyellowfull"
},
/area/lv624/ground/barrens/south_eastern_barrens)
+"ntr" = (
+/turf/closed/wall/strata_ice/jungle,
+/area/lv624/ground/barrens/north_east_barrens)
"ntL" = (
/obj/structure/fence,
/turf/open/gm/dirtgrassborder/south,
@@ -17649,6 +17658,9 @@
"omK" = (
/turf/open/gm/coast/beachcorner/south_east,
/area/lv624/ground/barrens/west_barrens)
+"onU" = (
+/turf/closed/wall/strata_ice/jungle,
+/area/lv624/ground/caves/west_caves)
"oov" = (
/obj/structure/flora/bush/ausbushes/lavendergrass,
/turf/open/gm/dirt,
@@ -20141,6 +20153,9 @@
/obj/effect/landmark/structure_spawner/setup/distress/xeno_membrane,
/turf/open/gm/dirt,
/area/lv624/ground/caves/east_caves)
+"unp" = (
+/turf/closed/wall/strata_ice/jungle,
+/area/lv624/ground/caves/south_east_caves)
"uns" = (
/obj/item/stack/sheet/wood{
amount = 2
@@ -20196,6 +20211,9 @@
/obj/effect/landmark/lv624/fog_blocker,
/turf/open/gm/coast/east,
/area/lv624/ground/river/east_river)
+"uxU" = (
+/turf/closed/wall/strata_ice/jungle,
+/area/lv624/ground/caves/central_caves)
"uya" = (
/turf/open/gm/dirt,
/area/lv624/lazarus/crashed_ship_containers)
@@ -20379,6 +20397,9 @@
icon_state = "dark"
},
/area/lv624/lazarus/corporate_dome)
+"uWJ" = (
+/turf/closed/wall/strata_ice/jungle,
+/area/lv624/ground/caves/south_west_caves)
"uXW" = (
/obj/structure/barricade/sandbags/wired,
/turf/open/floor/wood{
@@ -20733,6 +20754,9 @@
icon_state = "asteroidwarning"
},
/area/lv624/ground/colony/telecomm/sw_lz2)
+"vVC" = (
+/turf/closed/wall/strata_ice/jungle,
+/area/lv624/ground/caves/east_caves)
"vVD" = (
/obj/structure/flora/jungle/vines/light_3,
/turf/closed/wall/rock/brown,
@@ -21313,6 +21337,9 @@
/obj/structure/platform_decoration/mineral/sandstone/runed,
/turf/open/gm/dirtgrassborder/grassdirt_corner2/north_east,
/area/lv624/ground/caves/sand_temple)
+"xpR" = (
+/turf/closed/wall/strata_ice/jungle,
+/area/lv624/ground/caves/north_east_caves)
"xqV" = (
/obj/structure/surface/rack,
/obj/effect/landmark/objective_landmark/medium,
@@ -24041,8 +24068,8 @@ gwP
gwP
mdQ
mdQ
-mdQ
-mdQ
+onU
+onU
gwP
gwP
gwP
@@ -24269,8 +24296,8 @@ gwP
mdQ
mdQ
mdQ
-mdQ
-mdQ
+onU
+onU
mdQ
gwP
tOS
@@ -24495,9 +24522,9 @@ gwP
gwP
mdQ
mdQ
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
mdQ
mdQ
gwP
@@ -24722,9 +24749,9 @@ gwP
gwP
mdQ
mdQ
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
mdQ
mdQ
gwP
@@ -24949,9 +24976,9 @@ gwP
gwP
gwP
gwP
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
mdQ
mdQ
gwP
@@ -25179,7 +25206,7 @@ gwP
gwP
gwP
gwP
-mdQ
+onU
mdQ
gwP
gwP
@@ -26274,8 +26301,8 @@ abM
abM
abM
abM
-abM
-mdQ
+amk
+onU
mdQ
mdQ
mdQ
@@ -26343,7 +26370,7 @@ ahF
ahF
ahF
ahF
-ane
+uWJ
ahF
ahF
ahF
@@ -26470,10 +26497,10 @@ abN
abN
abN
abN
-abM
-abM
-abM
-abM
+amk
+amk
+amk
+amk
abM
abM
abM
@@ -26501,10 +26528,10 @@ abN
abM
abM
abM
-abM
-abM
-mdQ
-mdQ
+amk
+amk
+onU
+onU
mdQ
tOS
gwP
@@ -26570,9 +26597,9 @@ ahF
ahF
ahF
ahF
-ane
-ane
-ane
+uWJ
+uWJ
+uWJ
ahF
ahF
ahF
@@ -26699,11 +26726,11 @@ abN
abN
abN
abN
-abM
-abM
-abM
-abM
-abM
+amk
+amk
+amk
+amk
+amk
abM
abN
abN
@@ -26731,9 +26758,9 @@ abN
abN
abN
abN
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
gwP
gwP
gwP
@@ -26797,9 +26824,9 @@ ahF
ahF
ahF
ahF
-ane
-ane
-ane
+uWJ
+uWJ
+uWJ
ahF
ahF
ahH
@@ -26929,8 +26956,8 @@ abN
abN
abN
abN
-abM
-abM
+amk
+amk
abN
abN
abN
@@ -27435,9 +27462,9 @@ gwP
gwP
mdQ
mdQ
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
xZE
xZE
xZE
@@ -27640,7 +27667,7 @@ abN
abN
abN
abN
-abM
+amk
abM
abM
mdQ
@@ -27664,10 +27691,10 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
+onU
xZE
xZE
xZE
@@ -27716,9 +27743,9 @@ ahF
ahF
ahF
ahF
-ane
-ane
-ane
+uWJ
+uWJ
+uWJ
ane
ane
afV
@@ -27868,8 +27895,8 @@ abN
abN
abN
abN
-abM
-abM
+amk
+amk
abM
mdQ
mdQ
@@ -27894,10 +27921,10 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
+onU
xZE
xZE
gwP
@@ -27944,7 +27971,7 @@ ahF
ahF
ahF
ahF
-ane
+uWJ
ane
ane
ane
@@ -28061,10 +28088,10 @@ abN
abN
abN
abN
-abM
-abM
-abM
-abM
+amk
+amk
+amk
+amk
abN
abN
abN
@@ -28095,9 +28122,9 @@ abN
abN
abN
abN
-abM
-abM
-abM
+amk
+amk
+amk
abM
mdQ
mdQ
@@ -28123,10 +28150,10 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
+onU
mdQ
gwP
gwP
@@ -28288,12 +28315,12 @@ abN
abN
abM
abM
-abM
-abM
-abM
-abM
-abM
-abM
+amk
+amk
+amk
+amk
+amk
+amk
abM
abM
abM
@@ -28322,10 +28349,10 @@ abN
abN
abN
abN
-abM
-abM
-abM
-abM
+amk
+amk
+amk
+amk
abM
mdQ
mdQ
@@ -28352,8 +28379,8 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
+onU
+onU
mdQ
mdQ
mdQ
@@ -28517,9 +28544,9 @@ abN
abM
abM
abM
-abM
-abM
-abM
+amk
+amk
+amk
abM
abM
abM
@@ -28549,10 +28576,10 @@ abM
abM
abM
abM
-abM
-abM
-abM
-abM
+amk
+amk
+amk
+amk
abM
abM
mdQ
@@ -28623,8 +28650,8 @@ ahF
afV
ahF
ahF
-ane
-ane
+uWJ
+uWJ
ane
ane
ane
@@ -28746,7 +28773,7 @@ abM
abM
abM
abM
-abM
+amk
abM
abM
abM
@@ -28778,8 +28805,8 @@ abM
abM
abM
abM
-abM
-abM
+amk
+amk
abM
abM
mdQ
@@ -28850,8 +28877,8 @@ ahF
ahF
afV
afV
-ane
-ane
+uWJ
+uWJ
ane
ane
ane
@@ -29072,7 +29099,7 @@ vMV
vMV
vMV
vMV
-ane
+uWJ
ahF
ahF
ahF
@@ -29300,7 +29327,7 @@ ahF
ahF
ahF
ahF
-ane
+uWJ
ahF
ahF
ahF
@@ -29424,7 +29451,7 @@ abN
abN
abN
abN
-abM
+amk
abM
abM
abM
@@ -29528,8 +29555,8 @@ ahF
ahF
ahH
ahF
-ane
-ane
+uWJ
+uWJ
ahF
ahF
ahF
@@ -29652,8 +29679,8 @@ abN
abN
abQ
abN
-abM
-abM
+amk
+amk
abM
abM
abM
@@ -29756,8 +29783,8 @@ ahF
ahF
ahF
ahF
-ane
-ane
+uWJ
+uWJ
ahF
ahF
ahF
@@ -29879,9 +29906,9 @@ abN
abN
tgL
abN
-abM
-abM
-abM
+amk
+amk
+amk
abM
abM
abM
@@ -29985,7 +30012,7 @@ ahF
ahF
ahF
ahF
-ane
+uWJ
ahF
ahF
ahF
@@ -30107,8 +30134,8 @@ abN
abN
abN
abN
-abM
-abM
+amk
+amk
abM
abM
abM
@@ -30213,9 +30240,9 @@ ahF
ahF
ahF
ahF
+uWJ
ane
-ane
-ane
+uWJ
ahF
ahF
ahF
@@ -30336,7 +30363,7 @@ abN
abN
abN
abN
-abM
+amk
abM
abM
abM
@@ -30441,9 +30468,9 @@ ahF
ahF
ahF
ahF
+uWJ
ane
-ane
-ane
+uWJ
ahF
ahF
ahF
@@ -30671,7 +30698,7 @@ ahH
ahF
ane
ane
-ane
+uWJ
ahF
ahF
ahF
@@ -30899,8 +30926,8 @@ ahF
ahF
ahF
ahF
-ane
-ane
+uWJ
+uWJ
ane
ahF
ahF
@@ -31128,7 +31155,7 @@ ahF
ahF
ahF
ahF
-ane
+uWJ
ane
ane
ahF
@@ -31318,7 +31345,7 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
+onU
gwP
gwP
gwP
@@ -31357,9 +31384,9 @@ ahF
ahF
ahF
ahF
-ane
-ane
-ane
+uWJ
+uWJ
+uWJ
ahF
ahF
ahF
@@ -31545,8 +31572,8 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
+onU
+onU
gwP
gwP
sMx
@@ -31585,8 +31612,8 @@ ahF
ahF
ahH
ahF
-ane
-ane
+uWJ
+uWJ
ahF
ahF
ahF
@@ -31773,8 +31800,8 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
+onU
+onU
gwP
gwP
sMx
@@ -31813,7 +31840,7 @@ ahF
ahF
ahF
ahF
-ane
+uWJ
ane
ahF
ahF
@@ -32001,7 +32028,7 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
+onU
gwP
gwP
gwP
@@ -32223,8 +32250,8 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
+onU
+onU
gwP
gwP
xZE
@@ -32451,7 +32478,7 @@ mdQ
mdQ
gwP
gwP
-mdQ
+onU
gwP
gwP
gwP
@@ -33371,8 +33398,8 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
+onU
+onU
xZE
xZE
xZE
@@ -33545,7 +33572,7 @@ abN
abM
abM
abM
-abM
+amk
abM
abM
abM
@@ -33600,8 +33627,8 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
+onU
+onU
acK
gwP
gwP
@@ -33772,9 +33799,9 @@ tdX
tdX
abm
abM
-abM
-abM
-abM
+amk
+amk
+amk
abM
abM
abM
@@ -33829,8 +33856,8 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
+onU
+onU
gwP
gwP
gwP
@@ -33999,11 +34026,11 @@ aaW
aaW
aaW
abm
-abm
-abm
-abM
-abM
-abM
+aaF
+aaF
+amk
+amk
+amk
abM
abM
abM
@@ -34058,11 +34085,11 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
-mdQ
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
+onU
+onU
xZE
eGD
eGD
@@ -34228,11 +34255,11 @@ aaw
aaw
aaw
aaw
-abm
-abm
-abm
-abm
-abM
+aaF
+aaF
+aaF
+aaF
+amk
abM
abM
abM
@@ -34289,10 +34316,10 @@ mdQ
abS
abS
abS
-abS
-abS
-abS
-abS
+iIB
+iIB
+iIB
+iIB
eGD
eGD
eGD
@@ -34459,9 +34486,9 @@ aaw
aaw
aaw
aaw
-abm
-abm
-abm
+aaF
+aaF
+aaF
abm
abm
abM
@@ -34518,9 +34545,9 @@ abS
abS
abS
abS
-abS
-abS
-abS
+iIB
+iIB
+iIB
eGD
adc
eGD
@@ -34688,8 +34715,8 @@ aaw
aaw
aaw
aaw
-abm
-abm
+aaF
+aaF
abm
abm
abm
@@ -34747,8 +34774,8 @@ abS
abS
abS
abS
-abS
-abS
+iIB
+iIB
eGD
eGD
eGD
@@ -34917,7 +34944,7 @@ aaw
aaw
aaw
aaw
-abm
+aaF
abm
abm
abm
@@ -34976,7 +35003,7 @@ abS
abS
abS
abS
-abS
+iIB
eGD
eGD
eGD
@@ -35167,7 +35194,7 @@ mdQ
mdQ
mdQ
mdQ
-mdQ
+onU
tOS
gwP
acu
@@ -35394,8 +35421,8 @@ acf
mdQ
mdQ
mdQ
-mdQ
-mdQ
+onU
+onU
gwP
gwP
acp
@@ -35621,9 +35648,9 @@ acf
acf
acf
acf
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
gwP
gwP
xZE
@@ -35849,9 +35876,9 @@ acf
acf
acf
acf
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
gwP
gwP
xZE
@@ -36078,7 +36105,7 @@ acf
acf
acf
mdQ
-mdQ
+onU
mdQ
gwP
gwP
@@ -36285,7 +36312,7 @@ aah
aaH
aaw
aaw
-abm
+aaF
abm
abm
abm
@@ -36513,8 +36540,8 @@ aah
aaH
aaw
aaw
-abm
-abm
+aaF
+aaF
abm
abm
abm
@@ -36740,9 +36767,9 @@ aah
aah
aaH
aaw
-abm
-abm
-abm
+aaF
+aaF
+aaF
abm
abm
abm
@@ -36806,9 +36833,9 @@ adP
adP
eGD
eGD
-abS
-abS
-abS
+iIB
+iIB
+iIB
eGD
eGD
abS
@@ -36968,8 +36995,8 @@ aaU
aah
aaz
aay
-abm
-abm
+aaF
+aaF
abm
abm
abm
@@ -36995,9 +37022,9 @@ acf
mdQ
mdQ
mdQ
-mdQ
-mdQ
-mdQ
+onU
+onU
+onU
gwP
gwP
gwP
@@ -37033,8 +37060,8 @@ eGD
eGD
eGD
eGD
-abS
-abS
+iIB
+iIB
abS
abS
abS
@@ -37196,7 +37223,7 @@ aah
aah
aah
aaH
-abm
+aaF
abm
abm
abm
@@ -37224,10 +37251,10 @@ acf
acf
acf
acf
-acf
-acf
-acf
-acf
+uxU
+uxU
+uxU
+uxU
dGQ
any
dGQ
@@ -37259,9 +37286,9 @@ eGD
eGD
eGD
abS
-abS
-abS
-abS
+iIB
+iIB
+iIB
abS
abS
abS
@@ -38576,7 +38603,7 @@ aaw
aaw
aaw
aaw
-abm
+aaF
abm
abm
acf
@@ -38804,8 +38831,8 @@ aaw
aaw
aaw
aaw
-abm
-abm
+aaF
+aaF
acf
acf
acf
@@ -38843,8 +38870,8 @@ dGQ
eGD
eGD
eGD
-abS
-abS
+iIB
+iIB
abS
eGD
acO
@@ -39031,8 +39058,8 @@ aaw
aaw
abm
abm
-abm
-abm
+aaF
+aaF
abm
acf
acf
@@ -39070,8 +39097,8 @@ abl
izh
abS
abS
-abS
-abS
+iIB
+iIB
abS
abS
abS
@@ -39258,8 +39285,8 @@ aaw
aaw
aaw
abm
-abm
-abm
+aaF
+aaF
abm
abm
acf
@@ -39486,7 +39513,7 @@ aaw
aaw
aaw
abm
-abm
+aaF
abm
acf
acf
@@ -39713,8 +39740,8 @@ aaw
aaw
aaw
aaw
-abm
-abm
+aaF
+aaF
abm
acf
acf
@@ -39941,7 +39968,7 @@ aaw
aaw
aaw
aaw
-abm
+aaF
abm
abm
acf
@@ -40169,8 +40196,8 @@ aaw
aaw
aaw
aaw
-abm
-abm
+aaF
+aaF
abm
acf
acf
@@ -40397,8 +40424,8 @@ aax
aaE
aaw
aaw
-abm
-abm
+aaF
+aaF
abm
acf
acf
@@ -40446,7 +40473,7 @@ abS
abS
abS
abS
-abS
+iIB
eGD
eGD
eGD
@@ -40625,8 +40652,8 @@ aaw
aaw
aaw
aaw
-abm
-abm
+aaF
+aaF
abm
acf
acf
@@ -40673,8 +40700,8 @@ abS
abS
abS
abS
-abS
-abS
+iIB
+iIB
eGD
eGD
eGD
@@ -40853,7 +40880,7 @@ aaw
aaw
aaw
aaw
-abm
+aaF
abm
abm
acf
@@ -40900,9 +40927,9 @@ abS
abS
abS
abS
-abS
-abS
-abS
+iIB
+iIB
+iIB
eGD
eGD
eGD
@@ -41128,7 +41155,7 @@ abS
abS
abS
abS
-abS
+iIB
eGD
eGD
eGD
@@ -41814,7 +41841,7 @@ abS
abS
abS
abS
-abS
+iIB
eGD
eGD
eGD
@@ -42042,8 +42069,8 @@ abS
abS
abS
abS
-abS
-abS
+iIB
+iIB
eGD
eGD
eGD
@@ -42271,7 +42298,7 @@ abS
abS
abS
abS
-abS
+iIB
eGD
eGD
eGD
@@ -42499,7 +42526,7 @@ abS
abS
abS
abS
-abS
+iIB
eGD
eGD
eGD
@@ -43836,7 +43863,7 @@ abl
abl
acf
acf
-acf
+uxU
dGQ
uMz
dGQ
@@ -44064,8 +44091,8 @@ acf
acf
acf
acf
-acf
-acf
+uxU
+uxU
abl
abl
abl
@@ -44094,7 +44121,7 @@ abS
abS
abS
abS
-abS
+iIB
eGD
eGD
acq
@@ -44293,7 +44320,7 @@ acf
acf
acf
acf
-acf
+uxU
abl
abl
abl
@@ -44321,8 +44348,8 @@ abS
abS
abS
abS
-abS
-abS
+iIB
+iIB
eGD
eGD
eGD
@@ -44521,14 +44548,14 @@ acf
acf
acf
acf
-acf
+uxU
abl
abv
abl
abl
acf
acf
-acf
+uxU
abl
acf
acf
@@ -44548,9 +44575,9 @@ abS
abS
abS
abS
-abS
-abS
-abS
+iIB
+iIB
+iIB
eGD
eGD
eGD
@@ -44754,9 +44781,9 @@ abl
abl
abl
abl
-acf
-acf
-acf
+uxU
+uxU
+uxU
abl
abl
abl
@@ -44777,8 +44804,8 @@ abS
abS
abS
abS
-abS
-abS
+iIB
+iIB
cIU
cIU
cIU
@@ -44983,8 +45010,8 @@ abl
abl
abl
abl
-acf
-acf
+uxU
+uxU
abl
abl
abl
@@ -45211,7 +45238,7 @@ acf
abl
abl
abl
-acf
+uxU
izh
abl
abv
@@ -45225,7 +45252,7 @@ abl
abl
abl
abl
-abS
+iIB
abS
abS
abS
@@ -45452,14 +45479,14 @@ abl
abl
abl
abl
+iIB
+iIB
abS
abS
abS
abS
-abS
-abS
-abS
-abS
+iIB
+iIB
abS
abS
abS
@@ -45685,8 +45712,8 @@ pDt
pDt
pDt
pDt
-abS
-abS
+iIB
+iIB
pDt
pDt
abS
@@ -46121,7 +46148,7 @@ acf
acf
acf
acf
-acf
+uxU
abl
abl
dGQ
@@ -46347,9 +46374,9 @@ acf
acf
acf
acf
-acf
-acf
-acf
+uxU
+uxU
+uxU
abl
abl
acf
@@ -46574,8 +46601,8 @@ acf
acf
acf
acf
-acf
-acf
+uxU
+uxU
abl
abl
abl
@@ -46585,8 +46612,8 @@ acf
abl
abl
abl
-acf
-acf
+uxU
+uxU
abl
abl
abl
@@ -46802,7 +46829,7 @@ acf
abl
abl
acf
-acf
+uxU
abl
abl
abl
@@ -46813,20 +46840,20 @@ acf
abl
abl
abl
-acf
+uxU
acf
acf
abl
abl
-acf
-acf
+uxU
+uxU
acf
pDt
pDt
pDt
pDt
pDt
-nbw
+ntr
iZG
pDt
pDt
@@ -47037,7 +47064,7 @@ abl
abl
acf
acf
-acf
+uxU
abl
abl
abl
@@ -47046,15 +47073,15 @@ acf
acf
abl
abl
-acf
+uxU
acf
acf
nbw
pDt
pDt
nbw
-nbw
-nbw
+ntr
+ntr
pDt
pDt
pDt
@@ -47265,16 +47292,16 @@ abl
abl
abl
acf
-acf
-acf
+uxU
+uxU
abl
abl
abl
acf
acf
acf
-acf
-acf
+uxU
+uxU
acf
acf
nbw
@@ -47493,7 +47520,7 @@ abv
abl
abl
acf
-acf
+uxU
abl
abl
abv
@@ -47688,9 +47715,9 @@ aaE
aaw
aaw
aaw
-aaF
-aaF
-aaF
+abm
+abm
+abm
aaF
aaF
abm
@@ -47918,7 +47945,7 @@ aaw
aaw
aaF
aaF
-aaF
+abm
aaF
aaF
abm
@@ -48144,10 +48171,10 @@ aaw
aaw
aaw
aaw
-abm
-abm
-abm
-abm
+aaF
+aaF
+aaF
+aaF
abm
abm
abm
@@ -48171,7 +48198,7 @@ acf
acf
acf
acf
-acf
+uxU
abl
abl
abl
@@ -48373,8 +48400,8 @@ aaw
aaw
aaw
abm
-abm
-abm
+aaF
+aaF
abm
abm
abm
@@ -48398,8 +48425,8 @@ acf
acf
acf
acf
-acf
-acf
+uxU
+uxU
izh
abl
abl
@@ -48601,7 +48628,7 @@ aaw
aaw
aaw
abm
-abm
+aaF
acf
acf
acf
@@ -48626,8 +48653,8 @@ acf
acf
acf
acf
-acf
-acf
+uxU
+uxU
izh
abl
abl
@@ -48828,8 +48855,8 @@ aaw
aaw
aaw
aaw
-abm
-abm
+aaF
+aaF
acf
acf
acf
@@ -48854,7 +48881,7 @@ acf
acf
acf
acf
-acf
+uxU
acf
izh
abl
@@ -49056,7 +49083,7 @@ aaw
aaw
aaw
aaw
-abm
+aaF
abm
acf
acf
@@ -51135,7 +51162,7 @@ pUm
pUm
pUm
pUm
-pUm
+vVC
acg
acg
acg
@@ -51352,7 +51379,7 @@ acf
acf
acf
acf
-pUm
+vVC
pUm
pUm
acg
@@ -51362,8 +51389,8 @@ pUm
pUm
pUm
pUm
-pUm
-pUm
+vVC
+vVC
acg
acg
acg
@@ -51579,9 +51606,9 @@ acf
acf
acf
acf
-acf
-pUm
-pUm
+uxU
+vVC
+vVC
acg
acg
acg
@@ -51590,8 +51617,8 @@ pUm
pUm
pUm
pUm
-pUm
-pUm
+vVC
+vVC
acg
acg
acg
@@ -51806,10 +51833,10 @@ acf
acf
acf
acf
-pUm
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
+vVC
acg
acg
acg
@@ -51818,7 +51845,7 @@ pUm
pUm
pUm
pUm
-pUm
+vVC
acg
acg
aaN
@@ -52034,9 +52061,9 @@ pZb
acf
acf
pUm
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
acg
acg
acg
@@ -52046,7 +52073,7 @@ pUm
pUm
pUm
pUm
-pUm
+vVC
acg
acg
acg
@@ -52262,9 +52289,9 @@ pZb
pZb
pUm
pUm
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
acg
aaN
acg
@@ -52286,7 +52313,7 @@ whU
whU
whU
whU
-whU
+unp
fTM
fTM
fTM
@@ -52478,6 +52505,8 @@ pZb
pZb
pZb
pZb
+xpR
+xpR
pZb
pZb
pZb
@@ -52486,12 +52515,10 @@ pZb
pZb
pZb
pZb
-pZb
-pZb
-pUm
pUm
pUm
pUm
+vVC
acg
acg
acg
@@ -52514,9 +52541,9 @@ whU
whU
whU
whU
-whU
-whU
-whU
+unp
+unp
+unp
fTM
fTM
fTM
@@ -52705,11 +52732,11 @@ pZb
pZb
pZb
aag
-pZb
-pZb
-pZb
-pZb
-pZb
+xpR
+xpR
+xpR
+xpR
+xpR
pZb
pZb
pZb
@@ -52744,8 +52771,8 @@ whU
whU
whU
whU
-whU
-whU
+unp
+unp
fTM
fTM
fTM
@@ -52753,8 +52780,8 @@ fTM
fTM
fTM
whU
-whU
-whU
+unp
+unp
whU
whU
pDt
@@ -52936,9 +52963,9 @@ aag
aag
aag
aag
-pZb
-pZb
-pZb
+xpR
+xpR
+xpR
pZb
pZb
pZb
@@ -52981,7 +53008,7 @@ fTM
fTM
whU
whU
-whU
+unp
whU
whU
whU
@@ -53607,7 +53634,7 @@ aag
aag
aag
aag
-pZb
+xpR
aag
aag
aag
@@ -53834,8 +53861,8 @@ aag
aag
aag
aag
-pZb
-pZb
+xpR
+xpR
aag
aag
aag
@@ -54061,9 +54088,9 @@ aag
aag
aag
aab
-pZb
-pZb
-pZb
+xpR
+xpR
+xpR
aag
aag
aag
@@ -54122,7 +54149,7 @@ whU
whU
whU
whU
-whU
+unp
fTM
fTM
fTM
@@ -54289,8 +54316,8 @@ aai
aag
aab
aab
-pZb
-pZb
+xpR
+xpR
aab
aag
aag
@@ -54350,8 +54377,8 @@ whU
whU
whU
whU
-whU
-whU
+unp
+unp
fTM
fTM
fTM
@@ -54517,7 +54544,7 @@ aag
aab
aab
pZb
-pZb
+xpR
pZb
aab
aag
@@ -54540,10 +54567,10 @@ aag
aag
aag
aci
-pUm
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
+vVC
acg
acg
acg
@@ -54579,7 +54606,7 @@ whU
whU
whU
whU
-whU
+unp
fTM
fTM
akL
@@ -54769,10 +54796,10 @@ aag
aag
pZb
pUm
-pUm
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
+vVC
xSA
nzw
gkC
@@ -54807,7 +54834,7 @@ whU
whU
whU
whU
-whU
+unp
fTM
fTM
fTM
@@ -54998,8 +55025,8 @@ aag
pZb
pUm
pUm
-pUm
-pUm
+vVC
+vVC
pUm
acg
acg
@@ -55414,7 +55441,7 @@ pZb
pZb
pZb
pZb
-pZb
+xpR
aab
aag
aai
@@ -55642,8 +55669,8 @@ pZb
pZb
pZb
pZb
-pZb
-pZb
+xpR
+xpR
aag
aag
aag
@@ -55870,8 +55897,8 @@ pZb
pZb
pZb
pZb
-pZb
-pZb
+xpR
+xpR
aag
aag
aag
@@ -55913,7 +55940,7 @@ pUm
pUm
pUm
pUm
-pUm
+vVC
acg
acg
acg
@@ -56099,7 +56126,7 @@ pZb
pZb
pZb
pZb
-pZb
+xpR
aag
aag
aag
@@ -56140,8 +56167,8 @@ pUm
pUm
pUm
pUm
-pUm
-pUm
+vVC
+vVC
acg
acg
acg
@@ -56368,8 +56395,8 @@ pUm
pUm
pUm
pUm
-pUm
-pUm
+vVC
+vVC
acg
acg
acg
@@ -56596,8 +56623,8 @@ pUm
pUm
pUm
pUm
-pUm
-pUm
+vVC
+vVC
acg
acg
acg
@@ -56638,7 +56665,7 @@ vCG
whU
fTM
fTM
-ahv
+pRT
ahv
ahv
ahv
@@ -56864,9 +56891,9 @@ wEO
fTM
akL
whU
-whU
-whU
-ahv
+unp
+unp
+pRT
ahv
ahv
afS
@@ -57309,9 +57336,9 @@ whU
whU
whU
whU
-whU
-whU
-whU
+unp
+unp
+unp
fTM
fTM
fTM
@@ -57539,9 +57566,9 @@ whU
whU
whU
whU
-whU
-whU
-whU
+unp
+unp
+unp
wEO
wEO
wEO
@@ -58189,7 +58216,7 @@ pZb
pZb
pZb
pUm
-pUm
+vVC
aaQ
aaR
aaR
@@ -58416,8 +58443,8 @@ pZb
pZb
pZb
pZb
-pUm
-pUm
+vVC
+vVC
nzw
aaQ
aaR
@@ -58613,11 +58640,11 @@ pZb
pZb
pZb
pZb
-pZb
-pZb
-pZb
-pZb
-pZb
+xpR
+xpR
+xpR
+xpR
+xpR
aab
aab
aag
@@ -58644,8 +58671,8 @@ pZb
pZb
pZb
pZb
-pUm
-pUm
+vVC
+vVC
nzw
nzw
aaQ
@@ -58842,11 +58869,11 @@ pZb
pZb
pZb
pZb
-pZb
-pZb
-pZb
-pZb
-pZb
+xpR
+xpR
+xpR
+xpR
+xpR
aab
aab
aab
@@ -58872,8 +58899,8 @@ pZb
pZb
pZb
pZb
-pUm
-pUm
+vVC
+vVC
acg
nzw
nzw
@@ -59071,6 +59098,9 @@ pZb
pZb
pZb
pZb
+xpR
+xpR
+xpR
pZb
pZb
pZb
@@ -59097,11 +59127,8 @@ pZb
pZb
pZb
pZb
-pZb
-pZb
-pZb
-pUm
-pUm
+vVC
+vVC
acg
acg
acg
@@ -59328,9 +59355,9 @@ pZb
pZb
pZb
pZb
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
acg
acg
acg
@@ -59557,8 +59584,8 @@ pZb
pZb
pZb
pUm
-pUm
-pUm
+vVC
+vVC
acg
acg
aaN
@@ -59574,7 +59601,7 @@ iyr
eZC
nzw
pUm
-pUm
+vVC
acg
nzw
acg
@@ -59785,9 +59812,9 @@ pZb
pZb
pZb
pUm
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
acg
acg
acg
@@ -59801,8 +59828,8 @@ gkC
acg
jAo
nzw
-pUm
-pUm
+vVC
+vVC
aaQ
nzw
acg
@@ -60014,9 +60041,9 @@ pZb
pZb
pUm
pUm
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
pUm
acg
acg
@@ -60029,9 +60056,9 @@ umb
umb
umb
nzw
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
nzw
acg
acg
@@ -60243,9 +60270,9 @@ pZb
pUm
pUm
pUm
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
acg
acg
nzw
@@ -60258,8 +60285,8 @@ acg
dfJ
nzw
pUm
-pUm
-pUm
+vVC
+vVC
nzw
acg
acg
@@ -60472,9 +60499,9 @@ pUm
pUm
pUm
pUm
-pUm
-pUm
-pUm
+vVC
+vVC
+vVC
pUm
nzw
rPK
@@ -60487,7 +60514,7 @@ rPK
nzw
pUm
pUm
-pUm
+vVC
nzw
acg
aaN
@@ -60701,7 +60728,7 @@ pUm
pUm
pUm
pUm
-pUm
+vVC
pUm
pUm
nzw
diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm
index 828e406cc28b..ea33700eb433 100644
--- a/maps/map_files/USS_Almayer/USS_Almayer.dmm
+++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm
@@ -8144,6 +8144,9 @@
/obj/structure/machinery/light{
dir = 1
},
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
/turf/open/floor/almayer{
icon_state = "dark_sterile"
},
@@ -9835,6 +9838,10 @@
pixel_x = 5;
pixel_y = 3
},
+/obj/item/reagent_container/glass/beaker/cryoxadone{
+ pixel_x = -6;
+ pixel_y = 8
+ },
/turf/open/floor/almayer{
icon_state = "mono"
},
@@ -34237,20 +34244,10 @@
/turf/open/floor/almayer,
/area/almayer/living/chapel)
"eVT" = (
-/obj/structure/surface/table/almayer,
-/obj/item/paper_bin/wy{
- pixel_x = 6;
- pixel_y = 5
- },
-/obj/item/tool/pen{
- pixel_x = 8
- },
-/obj/item/clipboard{
- pixel_x = -8
- },
-/obj/item/folder/white{
- pixel_x = -8
+/obj/structure/disposalpipe/trunk{
+ dir = 1
},
+/obj/structure/machinery/disposal,
/turf/open/floor/almayer{
icon_state = "sterile_green_side"
},
@@ -35071,6 +35068,12 @@
icon_state = "plate"
},
/area/almayer/engineering/starboard_atmos)
+"fpT" = (
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/almayer{
+ icon_state = "dark_sterile"
+ },
+/area/almayer/medical/medical_science)
"fpW" = (
/obj/structure/sign/safety/bulkhead_door{
pixel_x = 32
@@ -35810,7 +35813,9 @@
/turf/open/floor/almayer,
/area/almayer/lifeboat_pumps/south1)
"fGu" = (
-/obj/structure/disposalpipe/segment,
+/obj/structure/disposalpipe/junction{
+ dir = 1
+ },
/obj/structure/machinery/door_control{
dir = 1;
id = "researchlockdownext";
@@ -36859,6 +36864,19 @@
/area/almayer/medical/containment/cell/cl)
"ger" = (
/obj/structure/surface/table/almayer,
+/obj/item/paper_bin/wy{
+ pixel_x = 6;
+ pixel_y = 5
+ },
+/obj/item/tool/pen{
+ pixel_x = 8
+ },
+/obj/item/clipboard{
+ pixel_x = -8
+ },
+/obj/item/folder/white{
+ pixel_x = -8
+ },
/turf/open/floor/almayer{
icon_state = "dark_sterile"
},
@@ -37226,13 +37244,11 @@
},
/area/almayer/medical/lower_medical_medbay)
"glB" = (
-/obj/structure/machinery/chem_master{
- vial_maker = 1
- },
/obj/structure/sign/safety/chem_lab{
pixel_x = 5;
pixel_y = 29
},
+/obj/structure/machinery/chem_master,
/turf/open/floor/almayer{
icon_state = "mono"
},
@@ -39712,6 +39728,9 @@
id = "Containment Breach";
name = "\improper Secure Airlock"
},
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
/turf/open/floor/almayer{
icon_state = "test_floor4"
},
@@ -39827,7 +39846,7 @@
/obj/item/paper{
pixel_x = 5
},
-/obj/item/tool/pen/blue{
+/obj/item/tool/pen{
pixel_x = 5
},
/obj/structure/surface/table/reinforced/black,
@@ -57519,6 +57538,7 @@
/obj/structure/bed/chair/comfy{
dir = 4
},
+/obj/structure/disposalpipe/segment,
/turf/open/floor/almayer{
icon_state = "dark_sterile"
},
@@ -59912,6 +59932,9 @@
pixel_x = 1;
pixel_y = 1
},
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
/turf/open/floor/almayer{
dir = 5;
icon_state = "sterile_green_side"
@@ -61949,6 +61972,16 @@
icon_state = "dark_sterile"
},
/area/almayer/medical/lower_medical_medbay)
+"rmc" = (
+/obj/structure/pipes/standard/simple/hidden/supply,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/almayer{
+ dir = 4;
+ icon_state = "sterile_green_side"
+ },
+/area/almayer/medical/medical_science)
"rmv" = (
/obj/structure/machinery/door/airlock/almayer/security{
dir = 2;
@@ -66714,6 +66747,20 @@
},
/turf/open/floor/wood/ship,
/area/almayer/command/corporateliason)
+"tsM" = (
+/obj/effect/decal/warning_stripes{
+ icon_state = "N";
+ pixel_y = 1
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 2;
+ icon_state = "pipe-c"
+ },
+/turf/open/floor/almayer{
+ dir = 1;
+ icon_state = "sterile_green_side"
+ },
+/area/almayer/medical/medical_science)
"tsX" = (
/turf/closed/wall/almayer/reinforced,
/area/almayer/shipboard/brig/lobby)
@@ -67853,8 +67900,8 @@
/area/almayer/squads/req)
"tUo" = (
/obj/item/clipboard,
-/obj/item/tool/pen/blue,
/obj/structure/surface/table/reinforced/black,
+/obj/item/tool/pen,
/turf/open/floor/almayer,
/area/almayer/command/cic)
"tUv" = (
@@ -70828,21 +70875,21 @@
/area/almayer/medical/hydroponics)
"vgB" = (
/obj/structure/surface/table/almayer,
-/obj/item/reagent_container/glass/beaker/cryoxadone{
- pixel_x = -6;
- pixel_y = 8
- },
/obj/item/storage/box/autoinjectors{
pixel_x = -6;
pixel_y = -1
},
-/obj/item/storage/box/pillbottles{
- pixel_x = 6;
- pixel_y = 7
- },
/obj/item/device/mass_spectrometer{
pixel_x = 8
},
+/obj/item/storage/box/pillbottles{
+ pixel_x = -6;
+ pixel_y = 9
+ },
+/obj/item/reagent_container/glass/beaker/cryoxadone{
+ pixel_x = 8;
+ pixel_y = 10
+ },
/turf/open/floor/almayer{
icon_state = "sterile_green_side"
},
@@ -110049,7 +110096,7 @@ hec
gNp
hVf
dVu
-dVu
+rmc
lON
dVu
oDR
@@ -110861,9 +110908,9 @@ mWs
lmw
vOy
dyb
-vkp
+tsM
prx
-aoM
+fpT
eVT
kgs
ayT
diff --git a/tgui/packages/tgui-say/styles/colors.scss b/tgui/packages/tgui-say/styles/colors.scss
index e0abb717edf3..318cd481f7ab 100644
--- a/tgui/packages/tgui-say/styles/colors.scss
+++ b/tgui/packages/tgui-say/styles/colors.scss
@@ -15,7 +15,7 @@ $me: #5975da;
$ooc: #1c52f5;
$looc: #e362b4;
$mentor: #b5850d;
-$asay: #9611d4;
+$asay: #74471b;
////////////////////////////////////////////////
// Subchannel chat colors
diff --git a/tgui/packages/tgui/events.js b/tgui/packages/tgui/events.js
index a0bc2ab2da32..6eb4351194b7 100644
--- a/tgui/packages/tgui/events.js
+++ b/tgui/packages/tgui/events.js
@@ -203,7 +203,7 @@ document.addEventListener('keydown', (e) => {
if (canStealFocus(e.target)) {
return;
}
- const code = e.keyCode;
+ const code = e.code;
const key = new KeyEvent(e, 'keydown', keyHeldByCode[code]);
globalEvents.emit('keydown', key);
globalEvents.emit('key', key);
@@ -214,7 +214,7 @@ document.addEventListener('keyup', (e) => {
if (canStealFocus(e.target)) {
return;
}
- const code = e.keyCode;
+ const code = e.code;
const key = new KeyEvent(e, 'keyup');
globalEvents.emit('keyup', key);
globalEvents.emit('key', key);
diff --git a/tgui/packages/tgui/hotkeys.ts b/tgui/packages/tgui/hotkeys.ts
index f7176bd00300..2f6579a377f4 100644
--- a/tgui/packages/tgui/hotkeys.ts
+++ b/tgui/packages/tgui/hotkeys.ts
@@ -73,7 +73,10 @@ const keyCodeToByond = (keyCode: number) => {
const handlePassthrough = (key: KeyEvent) => {
const keyString = String(key);
// In addition to F5, support reloading with Ctrl+R and Ctrl+F5
- if (keyString === 'Ctrl+F5' || keyString === 'Ctrl+R') {
+ if (
+ !key.event.defaultPrevented &&
+ (keyString === 'Ctrl+F5' || keyString === 'Ctrl+R')
+ ) {
location.reload();
return;
}
diff --git a/tgui/packages/tgui/interfaces/KeyBinds.js b/tgui/packages/tgui/interfaces/KeyBinds.js
index 6f3841ceb0ab..f3319b725456 100644
--- a/tgui/packages/tgui/interfaces/KeyBinds.js
+++ b/tgui/packages/tgui/interfaces/KeyBinds.js
@@ -3,7 +3,6 @@ import { useBackend, useLocalState } from '../backend';
import { Button, Flex, Section, Box, Input, Dropdown } from '../components';
import { Window } from '../layouts';
import { globalEvents } from '../events.js';
-import { createLogger } from '../logging';
const KEY_MODS = {
'SHIFT': true,
@@ -34,10 +33,6 @@ export const KeyBinds = (props, context) => {
? getAllKeybinds(glob_keybinds)
: glob_keybinds[selectedTab];
- const logger = createLogger('waa');
-
- logger.warn(keybinds_to_use);
-
const filteredKeybinds = keybinds_to_use.filter((val) =>
val.full_name.toLowerCase().match(searchTerm)
);
@@ -255,7 +250,7 @@ export class ButtonKeybind extends Component {
let pressedKey = e.key.toUpperCase();
- this.finishTimerStart(200);
+ this.finishTimerStart(600);
// Prevents repeating
if (keysDown[pressedKey] && e.type === 'keydown') {
@@ -284,6 +279,8 @@ export class ButtonKeybind extends Component {
});
this.finishTimerStart(2000);
globalEvents.on('keydown', this.preventPassthrough);
+ globalEvents.on('key', this.preventPassthrough);
+ globalEvents.on('keyup', this.preventPassthrough);
}
doBlur() {
@@ -292,6 +289,8 @@ export class ButtonKeybind extends Component {
keysDown: {},
});
globalEvents.off('keydown', this.preventPassthrough);
+ globalEvents.off('key', this.preventPassthrough);
+ globalEvents.off('keyup', this.preventPassthrough);
}
render() {
diff --git a/tools/autowiki/autowiki.js b/tools/autowiki/autowiki.js
new file mode 100644
index 000000000000..a9a2ab29eb1f
--- /dev/null
+++ b/tools/autowiki/autowiki.js
@@ -0,0 +1,89 @@
+const fs = require("fs").promises;
+const MWBot = require("mwbot");
+
+const { USERNAME, PASSWORD } = process.env;
+
+if (!USERNAME) {
+ console.error("USERNAME was not set.");
+ process.exit(1);
+}
+
+if (!PASSWORD) {
+ console.error("PASSWORD was not set.");
+ process.exit(1);
+}
+
+const PAGE_EDIT_FILENAME = process.argv[2];
+
+if (!PAGE_EDIT_FILENAME) {
+ console.error("No filename specified to edit pages");
+ process.exit(1);
+}
+
+const FILE_EDIT_FILENAME = process.argv[3];
+
+if (!FILE_EDIT_FILENAME) {
+ console.error("No filename specified to edit files");
+ process.exit(1);
+}
+
+async function main() {
+ console.log(`Reading from ${PAGE_EDIT_FILENAME}`);
+ const editFile = await (
+ await fs.readFile(PAGE_EDIT_FILENAME, "utf8")
+ ).split("\n");
+
+ console.log(`Logging in as ${USERNAME}`);
+
+ const bot = new MWBot();
+
+ await bot.loginGetEditToken({
+ apiUrl: "https://cm-ss13.com/w/api.php",
+ username: USERNAME,
+ password: PASSWORD,
+ });
+
+ console.log("Logged in");
+
+ // This is not Promise.all as to not flood with a bunch of traffic at once
+ for (const editLine of editFile) {
+ if (editLine.length === 0) {
+ continue;
+ }
+
+ let { title, text } = JSON.parse(editLine);
+ text =
+ "This page is automated by Autowiki. Do NOT edit it manually." +
+ text;
+
+ console.log(`Editing ${title}...`);
+ await bot.edit(
+ title,
+ text,
+ `Autowiki edit @ ${new Date().toISOString()}`
+ );
+ }
+
+ // Same here
+ for (const asset of await fs.readdir(FILE_EDIT_FILENAME)) {
+ const assetPath = `${FILE_EDIT_FILENAME}/${asset}`;
+ const assetName = `Autowiki-${asset}`;
+
+ console.log(`Replacing ${assetName}...`);
+ await bot
+ .upload(
+ assetName,
+ assetPath,
+ `Autowiki upload @ ${new Date().toISOString()}`
+ )
+ .catch((error) => {
+ if (error.code === "fileexists-no-change") {
+ console.log(`${assetName} is an exact duplicate`);
+ } else {
+ return Promise.reject(error);
+ }
+ });
+ }
+}
+
+main().catch(console.error);
diff --git a/tools/autowiki/package-lock.json b/tools/autowiki/package-lock.json
new file mode 100644
index 000000000000..ab2b4493025e
--- /dev/null
+++ b/tools/autowiki/package-lock.json
@@ -0,0 +1,1043 @@
+{
+ "name": "autowiki",
+ "version": "1.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "autowiki",
+ "version": "1.0.0",
+ "dependencies": {
+ "mwbot": "^2.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/asn1": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+ "dependencies": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "node_modules/assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "node_modules/aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/aws4": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
+ },
+ "node_modules/bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "dependencies": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
+ },
+ "node_modules/caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "node_modules/chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dependencies": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/colors": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "node_modules/dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "dependencies": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "node_modules/extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "engines": [
+ "node >=0.6.0"
+ ]
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ },
+ "node_modules/forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 0.12"
+ }
+ },
+ "node_modules/getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "node_modules/har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/har-validator": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+ "deprecated": "this library is no longer supported",
+ "dependencies": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ },
+ "engines": {
+ "node": ">=0.8",
+ "npm": ">=1.3.7"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "node_modules/isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "node_modules/jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+ },
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "node_modules/jsprim": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+ "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+ "dependencies": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.51.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
+ "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.34",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
+ "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
+ "dependencies": {
+ "mime-db": "1.51.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/mwbot": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mwbot/-/mwbot-2.0.0.tgz",
+ "integrity": "sha512-9iTx8oFMntC60yyaPJjN4GEgiQlal7i03jATu7kq5b9BGW5aNz7YbrpjaciLNr0Z33PTdQe0hRTJ0JdUJi2WQg==",
+ "dependencies": {
+ "bluebird": "^3.7.2",
+ "request": "^2.88.2",
+ "semlog": "^0.6.10",
+ "semver": "7.3.4"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "node_modules/prettyjson": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.5.tgz",
+ "integrity": "sha512-rksPWtoZb2ZpT5OVgtmy0KHVM+Dca3iVwWY9ifwhcexfjebtgjg3wmrUt9PvJ59XIYBcknQeYHD8IAnVlh9lAw==",
+ "dependencies": {
+ "colors": "1.4.0",
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "prettyjson": "bin/prettyjson"
+ }
+ },
+ "node_modules/psl": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
+ },
+ "node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/request": {
+ "version": "2.88.2",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+ "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
+ "dependencies": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "node_modules/semlog": {
+ "version": "0.6.10",
+ "resolved": "https://registry.npmjs.org/semlog/-/semlog-0.6.10.tgz",
+ "integrity": "sha1-DyJa6o6zwvJM6TWNhnjQ9Bp/4Fs=",
+ "dependencies": {
+ "chalk": "^1.1.3",
+ "prettyjson": "^1.1.3"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/sshpk": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
+ "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+ "dependencies": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ },
+ "bin": {
+ "sshpk-conv": "bin/sshpk-conv",
+ "sshpk-sign": "bin/sshpk-sign",
+ "sshpk-verify": "bin/sshpk-verify"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "dependencies": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
+ "node_modules/verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ }
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+ },
+ "asn1": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "colors": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+ "requires": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+ },
+ "json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "jsprim": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+ "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ }
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "mime-db": {
+ "version": "1.51.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
+ "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g=="
+ },
+ "mime-types": {
+ "version": "2.1.34",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
+ "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
+ "requires": {
+ "mime-db": "1.51.0"
+ }
+ },
+ "minimist": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g=="
+ },
+ "mwbot": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mwbot/-/mwbot-2.0.0.tgz",
+ "integrity": "sha512-9iTx8oFMntC60yyaPJjN4GEgiQlal7i03jATu7kq5b9BGW5aNz7YbrpjaciLNr0Z33PTdQe0hRTJ0JdUJi2WQg==",
+ "requires": {
+ "bluebird": "^3.7.2",
+ "request": "^2.88.2",
+ "semlog": "^0.6.10",
+ "semver": "7.3.4"
+ }
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "prettyjson": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.5.tgz",
+ "integrity": "sha512-rksPWtoZb2ZpT5OVgtmy0KHVM+Dca3iVwWY9ifwhcexfjebtgjg3wmrUt9PvJ59XIYBcknQeYHD8IAnVlh9lAw==",
+ "requires": {
+ "colors": "1.4.0",
+ "minimist": "^1.2.0"
+ }
+ },
+ "psl": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ },
+ "qs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA=="
+ },
+ "request": {
+ "version": "2.88.2",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "semlog": {
+ "version": "0.6.10",
+ "resolved": "https://registry.npmjs.org/semlog/-/semlog-0.6.10.tgz",
+ "integrity": "sha1-DyJa6o6zwvJM6TWNhnjQ9Bp/4Fs=",
+ "requires": {
+ "chalk": "^1.1.3",
+ "prettyjson": "^1.1.3"
+ }
+ },
+ "semver": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "sshpk": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
+ "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ },
+ "tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "requires": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ }
+ }
+}
diff --git a/tools/autowiki/package.json b/tools/autowiki/package.json
new file mode 100644
index 000000000000..39ac2bc7d5d6
--- /dev/null
+++ b/tools/autowiki/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "autowiki",
+ "version": "1.0.0",
+ "description": "Automatically publish generated pages to the tg wiki",
+ "main": "autowiki.js",
+ "author": "Mothblocks",
+ "dependencies": {
+ "mwbot": "^2.0.0"
+ }
+}