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/job.dm b/code/__DEFINES/job.dm
index 9b8dd45a6938..eac5121f173e 100644
--- a/code/__DEFINES/job.dm
+++ b/code/__DEFINES/job.dm
@@ -347,11 +347,12 @@ var/global/list/job_command_roles = JOB_COMMAND_ROLES_LIST
#define JOB_PLAYTIME_TIER_4 (175 HOURS)
#define XENO_NO_AGE -1
-#define XENO_NORMAL 0
-#define XENO_MATURE 1
-#define XENO_ELDER 2
-#define XENO_ANCIENT 3
-#define XENO_PRIME 4
+#define XENO_YOUNG 0
+#define XENO_NORMAL 1
+#define XENO_MATURE 2
+#define XENO_ELDER 3
+#define XENO_ANCIENT 4
+#define XENO_PRIME 5
/// For monthly time tracking
#define JOB_OBSERVER "Observer"
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/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/weapon_stats.dm b/code/__DEFINES/weapon_stats.dm
index bef8413e9615..590223426a66 100644
--- a/code/__DEFINES/weapon_stats.dm
+++ b/code/__DEFINES/weapon_stats.dm
@@ -136,19 +136,21 @@ As such, don't expect any values assigned to common firearms to even consider ho
//How many ticks you have to wait between firing. Burst delay uses the same variable!
*/
-#define FIRE_DELAY_TIER_1 10
-#define FIRE_DELAY_TIER_2 9
-#define FIRE_DELAY_TIER_3 8
-#define FIRE_DELAY_TIER_4 7
-#define FIRE_DELAY_TIER_5 6
-#define FIRE_DELAY_TIER_6 5
-#define FIRE_DELAY_TIER_7 4
-#define FIRE_DELAY_TIER_8 3
-#define FIRE_DELAY_TIER_9 2
-#define FIRE_DELAY_TIER_LMG 1.5
-#define FIRE_DELAY_TIER_SG 1.5
-#define FIRE_DELAY_TIER_SMG 1.3
-#define FIRE_DELAY_TIER_10 1
+#define FIRE_DELAY_TIER_1 12
+#define FIRE_DELAY_TIER_2 10
+#define FIRE_DELAY_TIER_3 9
+#define FIRE_DELAY_TIER_4 8
+#define FIRE_DELAY_TIER_5 7
+#define FIRE_DELAY_TIER_6 6
+#define FIRE_DELAY_TIER_7 5
+#define FIRE_DELAY_TIER_8 4
+#define FIRE_DELAY_TIER_9 3.5
+#define FIRE_DELAY_TIER_10 3
+#define FIRE_DELAY_TIER_11 2.5
+#define FIRE_DELAY_TIER_LMG 2
+#define FIRE_DELAY_TIER_SG 2
+#define FIRE_DELAY_TIER_SMG 1.5
+#define FIRE_DELAY_TIER_12 1
/*
////RANGE RELATED////
diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm
index 222222a09d54..0f822385ad13 100644
--- a/code/__DEFINES/xeno.dm
+++ b/code/__DEFINES/xeno.dm
@@ -168,6 +168,12 @@
/// The amount of time after round start before buried larva spawns are disallowed
#define XENO_BURIED_LARVA_TIME_LIMIT (30 MINUTES)
+/// The time when xenos can start taking over comm towers
+#define XENO_COMM_ACQUISITION_TIME (90 MINUTES)
+
+/// The time it takes for a pylon to give one larva while activated
+#define XENO_PYLON_ACTIVATION_COOLDOWN (5 MINUTES)
+
/// The time against away_timer when an AFK xeno larva can be replaced
#define XENO_LEAVE_TIMER_LARVA 80 //80 seconds
/// The time against away_timer when an AFK xeno (not larva) can be replaced
diff --git a/code/datums/mob_hud.dm b/code/datums/mob_hud.dm
index c1f67e93a53c..aa1bc9b40783 100644
--- a/code/datums/mob_hud.dm
+++ b/code/datums/mob_hud.dm
@@ -441,9 +441,9 @@ var/list/datum/mob_hud/huds = list(
holder2_set = 1
return
- holder.icon_state = "huddead"
+ holder.icon_state = HAS_TRAIT(src, TRAIT_HARDCORE) || MODE_HAS_TOGGLEABLE_FLAG(MODE_HARDCORE_PERMA) ? "hudhcdead" : "huddead"
if(!holder2_set)
- holder2.icon_state = "huddead"
+ holder2.icon_state = holder.icon_state
holder3.icon_state = "huddead"
holder2_set = 1
diff --git a/code/datums/skills.dm b/code/datums/skills.dm
index 584d466d948c..9bc53007173d 100644
--- a/code/datums/skills.dm
+++ b/code/datums/skills.dm
@@ -597,6 +597,7 @@ COMMAND STAFF
SKILL_SURGERY = SKILL_SURGERY_NOVICE,
SKILL_POLICE = SKILL_POLICE_SKILLED,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
+ SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_SPEC_WEAPONS = SKILL_SPEC_SMARTGUN,
SKILL_POWERLOADER = SKILL_POWERLOADER_MASTER,
@@ -616,6 +617,7 @@ COMMAND STAFF
SKILL_MEDICAL = SKILL_MEDICAL_DOCTOR,
SKILL_SURGERY = SKILL_SURGERY_NOVICE,
SKILL_POLICE = SKILL_POLICE_FLASH,
+ SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
SKILL_FIREMAN = SKILL_FIREMAN_SKILLED,
SKILL_CQC = SKILL_CQC_SKILLED,
SKILL_POWERLOADER = SKILL_POWERLOADER_MASTER,
@@ -709,6 +711,7 @@ COMMAND STAFF
SKILL_SURGERY = SKILL_SURGERY_NOVICE,
SKILL_JTAC = SKILL_JTAC_EXPERT,
SKILL_INTEL = SKILL_INTEL_EXPERT,
+ SKILL_VEHICLE = SKILL_VEHICLE_SMALL,
SKILL_ENGINEER = SKILL_ENGINEER_ENGI,
SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI,
SKILL_POLICE = SKILL_POLICE_FLASH,
@@ -1006,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/supply_packs/attachments.dm b/code/datums/supply_packs/attachments.dm
index 2a812e94cfc1..b685e5c3c37f 100644
--- a/code/datums/supply_packs/attachments.dm
+++ b/code/datums/supply_packs/attachments.dm
@@ -84,17 +84,6 @@
containername = "extended barrel attachment crate"
group = "Attachments"
-/datum/supply_packs/muzzle_heavy
- name = "barrel charger attachment crate (x2)"
- contains = list(
- /obj/item/attachable/heavy_barrel,
- /obj/item/attachable/heavy_barrel,
- )
- cost = 30
- containertype = /obj/structure/closet/crate
- containername = "heavy barrel attachment crate"
- group = "Attachments"
-
/datum/supply_packs/muzzle_compensator
name = "compensator attachment crate (x6)"
contains = list(
diff --git a/code/game/area/Sulaco.dm b/code/game/area/Sulaco.dm
index ffc087ad9851..851025e1b63a 100644
--- a/code/game/area/Sulaco.dm
+++ b/code/game/area/Sulaco.dm
@@ -13,6 +13,7 @@
is_resin_allowed = FALSE
flags_area = AREA_NOTUNNEL
is_landing_zone = TRUE
+ ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop1/Enter(atom/movable/O, atom/oldloc)
if(istype(O, /obj/structure/barricade))
@@ -23,36 +24,30 @@
name = "\improper Dropship Alamo"
icon_state = "shuttlered"
base_muffle = MUFFLE_HIGH
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop1/LV624
name = "\improper Dropship Alamo"
ambience_exterior = AMBIENCE_LV624
icon_state = "shuttle"
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop1/prison
name = "\improper Dropship Alamo"
ambience_exterior = AMBIENCE_PRISON
icon_state = "shuttle"
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop1/BigRed
name = "\improper Dropship Alamo"
ambience_exterior = AMBIENCE_BIGRED
icon_state = "shuttle"
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop1/ice_colony
name = "\improper Dropship Alamo"
icon_state = "shuttle"
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop1/DesertDam
name = "\improper Dropship Alamo"
ambience_exterior = AMBIENCE_TRIJENT
icon_state = "shuttle"
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop1/transit
ambience_exterior = 'sound/ambience/dropship_ambience_loop.ogg'
@@ -75,41 +70,36 @@
is_resin_allowed = FALSE
flags_area = AREA_NOTUNNEL
is_landing_zone = TRUE
+ ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop2/sulaco
name = "\improper Dropship Normandy"
icon_state = "shuttle"
base_muffle = MUFFLE_HIGH
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop2/LV624
name = "\improper Dropship Normandy"
ambience_exterior = AMBIENCE_LV624
icon_state = "shuttle2"
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop2/prison
name = "\improper Dropship Normandy"
ambience_exterior = AMBIENCE_PRISON
icon_state = "shuttle2"
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop2/BigRed
name = "\improper Dropship Normandy"
ambience_exterior = AMBIENCE_BIGRED
icon_state = "shuttle2"
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop2/ice_colony
name = "\improper Dropship Normandy"
icon_state = "shuttle2"
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop2/DesertDam
name = "\improper Dropship Normandy"
ambience_exterior = AMBIENCE_TRIJENT
icon_state = "shuttle2"
- ceiling = CEILING_REINFORCED_METAL
/area/shuttle/drop2/transit
ambience_exterior = 'sound/ambience/dropship_ambience_loop.ogg'
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/iv_drip.dm b/code/game/machinery/iv_drip.dm
index b538f55292c1..ef6c74a052cd 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -11,6 +11,8 @@
var/mode = 1 // 1 is injecting, 0 is taking blood.
var/obj/item/reagent_container/beaker = null
var/datum/beam/current_beam
+ //make it so that IV doesn't require power to function.
+ use_power = USE_POWER_NONE
/obj/structure/machinery/iv_drip/update_icon()
if(attached)
@@ -39,38 +41,31 @@
overlays += filling
/obj/structure/machinery/iv_drip/proc/update_beam()
- if(current_beam)
+ if(current_beam && !attached)
QDEL_NULL(current_beam)
- else if(!QDELETED(src) && attached)
+ else if(!current_beam && attached && !QDELETED(src))
current_beam = beam(attached, "iv_tube")
-/obj/structure/machinery/iv_drip/power_change()
- . = ..()
- if(stat & NOPOWER && attached)
- visible_message("\The [src] retracts its IV tube and shuts down.")
- attached.active_transfusions -= src
- attached = null
- update_beam()
- update_icon()
-
/obj/structure/machinery/iv_drip/Destroy()
attached?.active_transfusions -= src
+ attached = null
update_beam()
. = ..()
/obj/structure/machinery/iv_drip/MouseDrop(over_object, src_location, over_location)
..()
- if(inoperable())
- visible_message("\The [src] is not powered.")
- return
if(ishuman(usr))
- var/mob/living/carbon/human/H = usr
- if(H.stat || get_dist(H, src) > 1 || H.blinded || H.lying)
+ var/mob/living/carbon/human/user = usr
+ if(user.stat || get_dist(user, src) > 1 || user.blinded || user.lying)
+ return
+
+ if(!skillcheck(user, SKILL_SURGERY, SKILL_SURGERY_NOVICE))
+ to_chat(user, SPAN_WARNING("You don't know how to [attached ? "disconnect" : "connect"] this!"))
return
if(attached)
- H.visible_message("[H] detaches \the [src] from \the [attached].", \
+ user.visible_message("[user] detaches \the [src] from \the [attached].", \
"You detach \the [src] from \the [attached].")
attached.active_transfusions -= src
attached = null
@@ -80,7 +75,7 @@
return
if(in_range(src, usr) && iscarbon(over_object) && get_dist(over_object, src) <= 1)
- H.visible_message("[H] attaches \the [src] to \the [over_object].", \
+ user.visible_message("[user] attaches \the [src] to \the [over_object].", \
"You attach \the [src] to \the [over_object].")
attached = over_object
attached.active_transfusions += src
@@ -88,27 +83,27 @@
update_icon()
start_processing()
-
-/obj/structure/machinery/iv_drip/attackby(obj/item/W, mob/living/user)
- if (istype(W, /obj/item/reagent_container))
+/obj/structure/machinery/iv_drip/attackby(obj/item/container, mob/living/user)
+ if (istype(container, /obj/item/reagent_container))
if(beaker)
to_chat(user, SPAN_WARNING("There is already a reagent container loaded!"))
return
- if((!istype(W, /obj/item/reagent_container/blood) && !istype(W, /obj/item/reagent_container/glass)) || istype(W, /obj/item/reagent_container/glass/bucket))
+ if((!istype(container, /obj/item/reagent_container/blood) && !istype(container, /obj/item/reagent_container/glass)) || istype(container, /obj/item/reagent_container/glass/bucket))
to_chat(user, SPAN_WARNING("That won't fit!"))
return
- if(user.drop_inv_item_to_loc(W, src))
- beaker = W
+ if(user.drop_inv_item_to_loc(container, src))
+ beaker = container
var/reagentnames = ""
- for(var/datum/reagent/R in beaker.reagents.reagent_list)
- reagentnames += ";[R.name]"
+
+ for(var/datum/reagent/chem in beaker.reagents.reagent_list)
+ reagentnames += ";[chem.name]"
log_admin("[key_name(user)] put a [beaker] into [src], containing [reagentnames] at ([src.loc.x],[src.loc.y],[src.loc.z]).")
- to_chat(user, "You attach \the [W] to \the [src].")
+ to_chat(user, "You attach \the [container] to \the [src].")
update_beam()
update_icon()
return
@@ -151,20 +146,20 @@
if(prob(5)) visible_message("\The [src] pings.")
return
- var/mob/living/carbon/T = attached
+ var/mob/living/carbon/patient = attached
- if(!istype(T))
+ if(!istype(patient))
return
- if(ishuman(T))
- var/mob/living/carbon/human/H = T
- if(H.species && H.species.flags & NO_BLOOD)
+ if(ishuman(patient))
+ var/mob/living/carbon/human/human_patient = patient
+ if(human_patient.species && human_patient.species.flags & NO_BLOOD)
return
// If the human is losing too much blood, beep.
- if(T.blood_volume < BLOOD_VOLUME_SAFE) if(prob(5))
+ if(patient.blood_volume < BLOOD_VOLUME_SAFE) if(prob(5))
visible_message("\The [src] beeps loudly.")
- T.take_blood(beaker,amount)
+ patient.take_blood(beaker,amount)
update_icon()
/obj/structure/machinery/iv_drip/attack_hand(mob/user as mob)
diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm
index c56360953650..47d4bb20849b 100644
--- a/code/game/machinery/telecomms/presets.dm
+++ b/code/game/machinery/telecomms/presets.dm
@@ -212,12 +212,27 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)
freq_listening = list(COLONY_FREQ)
var/toggle_cooldown = 0
+ /// Tower has been taken over by xenos, is not usable
+ var/corrupted = FALSE
+
+ /// Held image for the current overlay on the tower from xeno corruption
+ var/image/corruption_image
+
+/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/Initialize()
+ . = ..()
+
+ RegisterSignal(src, COMSIG_ATOM_TURF_CHANGE, PROC_REF(register_with_turf))
+ register_with_turf()
+
/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/attack_hand(mob/user)
if(user.action_busy)
return
if(toggle_cooldown > world.time) //cooldown only to prevent spam toggling
to_chat(user, SPAN_WARNING("\The [src]'s processors are still cooling! Wait before trying to flip the switch again."))
return
+ if(corrupted)
+ to_chat(user, SPAN_WARNING("[src] is entangled in resin. Impossible to interact with."))
+ return
var/current_state = on
if(!do_after(user, 20, INTERRUPT_NO_NEEDHAND|BEHAVIOR_IMMOBILE, BUSY_ICON_FRIENDLY, src))
return
@@ -282,6 +297,84 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)
else
update_icon()
+/// Handles xenos corrupting the tower when weeds touch the turf it is located on
+/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/proc/handle_xeno_acquisition(turf/weeded_turf)
+ SIGNAL_HANDLER
+
+ if(corrupted)
+ return
+
+ if(!weeded_turf.weeds)
+ return
+
+ if(weeded_turf.weeds.weed_strength < WEED_LEVEL_HIVE)
+ return
+
+ if(!weeded_turf.weeds.parent)
+ return
+
+ if(!istype(weeded_turf.weeds.parent, /obj/effect/alien/weeds/node/pylon/cluster))
+ return
+
+ if(SSticker.mode.is_in_endgame)
+ return
+
+ if(ROUND_TIME < XENO_COMM_ACQUISITION_TIME)
+ addtimer(CALLBACK(src, PROC_REF(handle_xeno_acquisition), weeded_turf), (XENO_COMM_ACQUISITION_TIME - ROUND_TIME))
+ return
+
+ var/obj/effect/alien/weeds/node/pylon/cluster/parent_node = weeded_turf.weeds.parent
+
+ var/obj/effect/alien/resin/special/cluster/cluster_parent = parent_node.resin_parent
+
+ var/list/held_children_weeds = parent_node.children
+ var/cluster_loc = cluster_parent.loc
+ var/linked_hive = cluster_parent.linked_hive
+
+ parent_node.children = list()
+
+ qdel(cluster_parent)
+
+ var/obj/effect/alien/resin/special/pylon/endgame/new_pylon = new(cluster_loc, linked_hive)
+ new_pylon.node.children = held_children_weeds
+
+ for(var/obj/effect/alien/weeds/weed in new_pylon.node.children)
+ weed.parent = new_pylon.node
+
+ RegisterSignal(new_pylon, COMSIG_PARENT_QDELETING, PROC_REF(uncorrupt))
+
+ corrupted = TRUE
+
+ corruption_image = image(icon, icon_state = "resin_growing")
+
+ flick_overlay(src, corruption_image, (2 SECONDS))
+ addtimer(CALLBACK(src, PROC_REF(switch_to_idle_corruption)), (2 SECONDS))
+
+ new_pylon.comms_relay_connection()
+
+/// Handles removing corruption effects from the comms relay
+/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/proc/uncorrupt(datum/deleting_datum)
+ SIGNAL_HANDLER
+
+ corrupted = FALSE
+
+ overlays -= corruption_image
+
+/// Handles moving the overlay from growing to idle
+/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/proc/switch_to_idle_corruption()
+ if(!corrupted)
+ return
+
+ corruption_image = image(icon, icon_state = "resin_idle")
+
+ overlays += corruption_image
+
+/// Handles re-registering signals on new turfs if changed
+/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/proc/register_with_turf()
+ SIGNAL_HANDLER
+
+ RegisterSignal(get_turf(src), COMSIG_WEEDNODE_GROWTH, PROC_REF(handle_xeno_acquisition))
+
/obj/structure/machinery/telecomms/relay/preset/telecomms
id = "Telecomms Relay"
autolinkers = list("relay")
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/machinery/vending/vendor_types/crew/commanding_officer.dm b/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm
index 3d6a48b45daa..fac4182ea5fe 100644
--- a/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm
+++ b/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm
@@ -42,7 +42,6 @@ GLOBAL_LIST_INIT(cm_vending_gear_commanding_officer, list(
list("Underbarrel Flamethrower", 15, /obj/item/attachable/attached_gun/flamer, null, VENDOR_ITEM_REGULAR),
list("BARREL ATTACHMENTS", 0, null, null, null),
- list("Barrel Charger", 25, /obj/item/attachable/heavy_barrel, null, VENDOR_ITEM_RECOMMENDED),
list("Suppressor", 15, /obj/item/attachable/suppressor, null, VENDOR_ITEM_REGULAR),
list("Extended Barrel", 15, /obj/item/attachable/extended_barrel, null, VENDOR_ITEM_REGULAR),
list("Recoil Compensator", 15, /obj/item/attachable/compensator, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/crew/mp.dm b/code/game/machinery/vending/vendor_types/crew/mp.dm
index cdf374249211..b63a02248168 100644
--- a/code/game/machinery/vending/vendor_types/crew/mp.dm
+++ b/code/game/machinery/vending/vendor_types/crew/mp.dm
@@ -1,38 +1,50 @@
//------------ MP CLOTHING VENDOR---------------
GLOBAL_LIST_INIT(cm_vending_clothing_military_police, list(
+ list("POLICE SET (MANDATORY)", 0, null, null, null),
+ list("Essential Police Set", 0, /obj/effect/essentials_set/police, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY),
+
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Gloves", 0, /obj/item/clothing/gloves/marine, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Uniform", 0, /obj/item/clothing/under/marine/mp, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/almayer/mmpo, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
- list("Satchel", 0, /obj/item/storage/backpack/satchel/sec, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
-
- list("PERSONAL SIDEARM (CHOOSE 1)", 0, null, null, null),
- list("M44 Revolver", 0, /obj/item/storage/belt/gun/m44/mp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M4A3 Pistol", 0, /obj/item/storage/belt/gun/m4a3/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("Mod 88 Pistol", 0, /obj/item/storage/belt/gun/m4a3/mod88, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("Marine Combat Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("ARMOR (TAKE ALL)", 0, null, null, null),
list("Military Police M2 Armor", 0, /obj/item/clothing/suit/storage/marine/MP, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
+ list("MP Beret", 0, /obj/item/clothing/head/beret/marine/mp, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
- list("COMBAT EQUIPMENT (TAKE ALL)", 0, null, null, null),
- list("Military Police M10 Helmet", 0, /obj/item/clothing/head/helmet/marine/MP, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
- list("Marine Combat Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
+ list("HANDGUN CASE (CHOOSE 1)", 0, null, null, null),
+ list("88 mod 4 Combat Pistol Case", 0, /obj/item/storage/box/guncase/mod88, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_MANDATORY),
+ list("M44 Combat Revolver Case", 0, /obj/item/storage/box/guncase/m44, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_MANDATORY),
+ list("M4A3 Service Pistol Case", 0, /obj/item/storage/box/guncase/m4a3, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_MANDATORY),
- list("EYEWEAR (TAKE ALL)", 0, null, null, null),
- list("Security HUD Glasses", 0, /obj/item/clothing/glasses/sunglasses/sechud, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_REGULAR),
+ list("BACKPACK (CHOOSE 1)", 0, null, null, null),
+ list("Military Police Satchel", 0, /obj/item/storage/backpack/satchel/sec, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
+
+ list("BELT (CHOOSE 1)", 0, null, null, null),
+ list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
- list("First-Aid Pouch (Full)", 0, /obj/item/storage/pouch/firstaid/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
list("Medium General Pouch", 0, /obj/item/storage/pouch/general/medium, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("First-Aid Pouch (Refillable Injectors)", 0, /obj/item/storage/pouch/firstaid/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("First-Aid Pouch (Splints, Gauze, Ointment)", 0, /obj/item/storage/pouch/firstaid/full/alternate, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("First-Aid Pouch (Pill Packets)", 0, /obj/item/storage/pouch/firstaid/full/pills, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("Pistol Magazine Pouch", 0, /obj/item/storage/pouch/magazine/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Pistol Pouch", 0, /obj/item/storage/pouch/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+
+ list("MASK (CHOOSE 1)", 0, null, null, null),
+ list("Gas Mask", 0, /obj/item/clothing/mask/gas, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
+ list("Heat Absorbent Coif", 0, /obj/item/clothing/mask/rebreather/scarf, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
+ list("Rebreather", 0, /obj/item/clothing/mask/rebreather, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
list("ACCESSORIES (CHOOSE 1)", 0, null, null, null),
+ list("Brown Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest/brown_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_RECOMMENDED),
+ list("Black Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Shoulder Holster", 0, /obj/item/clothing/accessory/storage/holster, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Webbing", 0, /obj/item/clothing/accessory/storage/webbing, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
-
- list("HAT (CHOOSE 1)", 0, null, null, null),
- list("MP Beret", 0, /obj/item/clothing/head/beret/marine/mp, MARINE_CAN_BUY_MASK, VENDOR_ITEM_MANDATORY),
-
))
/obj/structure/machinery/cm_vending/clothing/military_police
@@ -47,38 +59,50 @@ GLOBAL_LIST_INIT(cm_vending_clothing_military_police, list(
//------------ Warden CLOTHING VENDOR---------------
GLOBAL_LIST_INIT(cm_vending_clothing_military_police_warden, list(
+ list("POLICE SET (MANDATORY)", 0, null, null, null),
+ list("Essential Police Set", 0, /obj/effect/essentials_set/police, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY),
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Gloves", 0, /obj/item/clothing/gloves/marine, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Warden Uniform", 0, /obj/item/clothing/under/marine/warden, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/almayer/cmpcom, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
- list("Satchel", 0, /obj/item/storage/backpack/satchel/sec, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
-
- list("PERSONAL SIDEARM (Take ALL)", 0, null, null, null),
- list("M4A3 Service Pistol ", 0, /obj/item/storage/belt/gun/m4a3/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("Mod 88 Pistol", 0, /obj/item/storage/belt/gun/m4a3/mod88, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M44 Revolver", 0, /obj/item/storage/belt/gun/m44/mp, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
+ list("Marine Combat Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("ARMOR (TAKE ALL)", 0, null, null, null),
list("Military Warden M3 Armor", 0, /obj/item/clothing/suit/storage/marine/MP/warden, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
+ list("Warden Peaked Cap", 0, /obj/item/clothing/head/beret/marine/mp/warden, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
- list("COMBAT EQUIPMENT (TAKE ALL)", 0, null, null, null),
- list("Military Police M10 Helmet", 0, /obj/item/clothing/head/helmet/marine/MP, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
- list("Marine Combat Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
+ list("HANDGUN CASE (CHOOSE 1)", 0, null, null, null),
+ list("88 mod 4 Combat Pistol Case", 0, /obj/item/storage/box/guncase/mod88, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_MANDATORY),
+ list("M44 Combat Revolver Case", 0, /obj/item/storage/box/guncase/m44, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_MANDATORY),
+ list("M4A3 Service Pistol Case", 0, /obj/item/storage/box/guncase/m4a3, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_MANDATORY),
+
+ list("BACKPACK (CHOOSE 1)", 0, null, null, null),
+ list("Military Police Satchel", 0, /obj/item/storage/backpack/satchel/sec, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
- list("EYEWEAR (TAKE ALL)", 0, null, null, null),
- list("Security HUD Glasses", 0, /obj/item/clothing/glasses/sunglasses/sechud, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_REGULAR),
+ list("BELT (CHOOSE 1)", 0, null, null, null),
+ list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
- list("First-Aid Pouch (Full)", 0, /obj/item/storage/pouch/firstaid/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
list("Medium General Pouch", 0, /obj/item/storage/pouch/general/medium, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("First-Aid Pouch (Refillable Injectors)", 0, /obj/item/storage/pouch/firstaid/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("First-Aid Pouch (Splints, Gauze, Ointment)", 0, /obj/item/storage/pouch/firstaid/full/alternate, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("First-Aid Pouch (Pill Packets)", 0, /obj/item/storage/pouch/firstaid/full/pills, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("Pistol Magazine Pouch", 0, /obj/item/storage/pouch/magazine/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Pistol Pouch", 0, /obj/item/storage/pouch/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+
+ list("MASK (CHOOSE 1)", 0, null, null, null),
+ list("Gas Mask", 0, /obj/item/clothing/mask/gas, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
+ list("Heat Absorbent Coif", 0, /obj/item/clothing/mask/rebreather/scarf, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
+ list("Rebreather", 0, /obj/item/clothing/mask/rebreather, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
list("ACCESSORIES (CHOOSE 1)", 0, null, null, null),
+ list("Brown Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest/brown_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_RECOMMENDED),
+ list("Black Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Shoulder Holster", 0, /obj/item/clothing/accessory/storage/holster, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Webbing", 0, /obj/item/clothing/accessory/storage/webbing, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
-
- list("HAT (CHOOSE 1)", 0, null, null, null),
- list("Warden Peaked Cap", 0, /obj/item/clothing/head/beret/marine/mp/warden, MARINE_CAN_BUY_MASK, VENDOR_ITEM_MANDATORY),
))
/obj/structure/machinery/cm_vending/clothing/military_police_warden
@@ -89,3 +113,10 @@ GLOBAL_LIST_INIT(cm_vending_clothing_military_police_warden, list(
/obj/structure/machinery/cm_vending/clothing/military_police_warden/get_listed_products(mob/user)
return GLOB.cm_vending_clothing_military_police_warden
+
+/obj/effect/essentials_set/police
+ spawned_gear_list = list(
+ /obj/item/clothing/glasses/sunglasses/sechud,
+ /obj/item/storage/belt/security/MP/full,
+ /obj/item/clothing/head/helmet/marine/MP,
+ )
diff --git a/code/game/machinery/vending/vendor_types/crew/pilot_officer.dm b/code/game/machinery/vending/vendor_types/crew/pilot_officer.dm
index 231e02bb5118..8d86669a1f70 100644
--- a/code/game/machinery/vending/vendor_types/crew/pilot_officer.dm
+++ b/code/game/machinery/vending/vendor_types/crew/pilot_officer.dm
@@ -65,11 +65,11 @@ GLOBAL_LIST_INIT(cm_vending_clothing_pilot_officer, list(
list("M30 Tactical Helmet", 0, /obj/item/clothing/head/helmet/marine/pilot, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
list("Leather Satchel", 0, /obj/item/storage/backpack/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
-
+
list("ARMOR (CHOOSE 1)", 0, null, null, null),
list("M70 Flak Jacket", 0, /obj/item/clothing/suit/armor/vest/pilot, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("M3-VL Pattern Flak Vest", 0, /obj/item/clothing/suit/storage/marine/light/vest/dcc, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
-
+
list("PERSONAL SIDEARM (CHOOSE 1)", 0, null, null, null),
list("88 Mod 4 Combat Pistol", 0, /obj/item/weapon/gun/pistol/mod88, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_REGULAR),
list("VP78 Pistol", 0, /obj/item/weapon/gun/pistol/vp78, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_REGULAR),
@@ -79,7 +79,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_pilot_officer, list(
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Lifesaver Bag (Full)", 0, /obj/item/storage/belt/medical/lifesaver/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 Medical Storage Rig (Full)", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
@@ -153,8 +153,8 @@ GLOBAL_LIST_INIT(cm_vending_clothing_dropship_crew_chief, list(
list("Gloves", 0, /obj/item/clothing/gloves/yellow, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Patrol Cap", 0, /obj/item/clothing/head/cmcap, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
list("Leather Satchel", 0, /obj/item/storage/backpack/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
- list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
-
+ list("MRE", 0, /obj/item/storage/box/MRE, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
+
list("ARMOR (CHOOSE 1)", 0, null, null, null),
list("M70 Flak Jacket", 0, /obj/item/clothing/suit/armor/vest/pilot, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
list("M3-VL Pattern Flak Vest", 0, /obj/item/clothing/suit/storage/marine/light/vest/dcc, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY),
@@ -168,7 +168,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_dropship_crew_chief, list(
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Lifesaver Bag (Full)", 0, /obj/item/storage/belt/medical/lifesaver/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 Medical Storage Rig (Full)", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/crew/senior_officers.dm b/code/game/machinery/vending/vendor_types/crew/senior_officers.dm
index 99947e0a3daa..55053bd724bd 100644
--- a/code/game/machinery/vending/vendor_types/crew/senior_officers.dm
+++ b/code/game/machinery/vending/vendor_types/crew/senior_officers.dm
@@ -28,50 +28,57 @@
return ..()
-
//------------ CHIEF MP ---------------
GLOBAL_LIST_INIT(cm_vending_clothing_military_police_chief, list(
+ list("POLICE SET (MANDATORY)", 0, null, null, null),
+ list("Essential Police Set", 0, /obj/effect/essentials_set/chiefmilitarypolice, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY),
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Gloves", 0, /obj/item/clothing/gloves/marine, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("CMP Uniform", 0, /obj/item/clothing/under/marine/officer/warrant, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/almayer/cmpcom, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
- list("Satchel", 0, /obj/item/storage/backpack/satchel/sec, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
- list("Gear Belt", 0, /obj/item/storage/belt/security/MP/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_MANDATORY),
-
- list("PERSONAL SIDEARM (CHOOSE 1)", 0, null, null, null),
- list("M4A3 Service Pistol", 0, /obj/item/storage/belt/gun/m4a3/full, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_REGULAR),
- list("Mod 88 Pistol", 0, /obj/item/storage/belt/gun/m4a3/mod88, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_REGULAR),
- list("M44 Revolver", 0, /obj/item/storage/belt/gun/m44/mp, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_RECOMMENDED),
+ list("Marine Combat Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
list("ARMOR (TAKE ALL)", 0, null, null, null),
list("Military Police Chief M3 Armor", 0, /obj/item/clothing/suit/storage/marine/MP/WO, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_RECOMMENDED),
-
- list("COMBAT EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Chief MP M10 Helmet", 0, /obj/item/clothing/head/helmet/marine/MP/WO, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
- list("Marine Combat Boots", 0, /obj/item/clothing/shoes/marine/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY),
+ list("CMP Beret", 0, /obj/item/clothing/head/beret/marine/mp/cmp, MARINE_CAN_BUY_HELMET, VENDOR_ITEM_MANDATORY),
+
+ list("HANDGUN CASE (CHOOSE 1)", 0, null, null, null),
+ list("88 mod 4 Combat Pistol Case", 0, /obj/item/storage/box/guncase/mod88, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_MANDATORY),
+ list("M44 Combat Revolver Case", 0, /obj/item/storage/box/guncase/m44, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_MANDATORY),
+ list("M4A3 Service Pistol Case", 0, /obj/item/storage/box/guncase/m4a3, MARINE_CAN_BUY_SECONDARY, VENDOR_ITEM_MANDATORY),
+
+ list("BACKPACK (CHOOSE 1)", 0, null, null, null),
+ list("Military Police Satchel", 0, /obj/item/storage/backpack/satchel/sec, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_MANDATORY),
- list("EYEWEAR (TAKE ALL)", 0, null, null, null),
- list("Security HUD Glasses", 0, /obj/item/clothing/glasses/sunglasses/sechud, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_MANDATORY),
+ list("BELT (CHOOSE 1)", 0, null, null, null),
+ list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("POUCHES (CHOOSE 2)", 0, null, null, null),
- list("First-Aid Pouch (Refillable Injectors)", 0, /obj/item/storage/pouch/firstaid/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
- list("First-Aid Pouch (Splints, Gauze, Ointment)", 0, /obj/item/storage/pouch/firstaid/full/alternate, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Medium General Pouch", 0, /obj/item/storage/pouch/general/medium, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("First-Aid Pouch (Refillable Injectors)", 0, /obj/item/storage/pouch/firstaid/full, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("First-Aid Pouch (Splints, Gauze, Ointment)", 0, /obj/item/storage/pouch/firstaid/full/alternate, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
list("First-Aid Pouch (Pill Packets)", 0, /obj/item/storage/pouch/firstaid/full/pills, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_RECOMMENDED),
+ list("Pistol Magazine Pouch", 0, /obj/item/storage/pouch/magazine/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("Pistol Pouch", 0, /obj/item/storage/pouch/pistol, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
list("Large General Pouch", 0, /obj/item/storage/pouch/general/large, MARINE_CAN_BUY_POUCH, VENDOR_ITEM_REGULAR),
+ list("MASK (CHOOSE 1)", 0, null, null, null),
+ list("Gas Mask", 0, /obj/item/clothing/mask/gas, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
+ list("Heat Absorbent Coif", 0, /obj/item/clothing/mask/rebreather/scarf, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
+ list("Rebreather", 0, /obj/item/clothing/mask/rebreather, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
+
list("ACCESSORIES (CHOOSE 1)", 0, null, null, null),
- list("Shoulder Holster", 0, /obj/item/clothing/accessory/storage/holster, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
+ list("Brown Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest/brown_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_RECOMMENDED),
list("Black Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
- list("Brown Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest/brown_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
+ list("Shoulder Holster", 0, /obj/item/clothing/accessory/storage/holster, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
list("Webbing", 0, /obj/item/clothing/accessory/storage/webbing, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
-
- list("HAT (CHOOSE 1)", 0, null, null, null),
- list("CMP Beret", 0, /obj/item/clothing/head/beret/marine/mp/cmp, MARINE_CAN_BUY_MASK, VENDOR_ITEM_MANDATORY),
))
-
//------------ CHIEF ENGINEER ---------------
GLOBAL_LIST_INIT(cm_vending_clothing_chief_engineer, list(
@@ -203,9 +210,12 @@ GLOBAL_LIST_INIT(cm_vending_clothing_cmo, list(
list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null),
list("Gloves", 0, /obj/item/clothing/gloves/latex, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY),
list("Headset", 0, /obj/item/device/radio/headset/almayer/cmo, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY),
- list("Medical HUD Glasses", 0, /obj/item/clothing/glasses/hud/health, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_MANDATORY),
list("Labcoat", 0, /obj/item/clothing/suit/storage/labcoat, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY),
+ list("EYEWARE (CHOOSE 1)", 0, null, null, null),
+ list("Medical HUD Glasses", 0, /obj/item/clothing/glasses/hud/health, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_MANDATORY),
+ list("Reagent Scanner HUD Goggles", 0, /obj/item/clothing/glasses/science, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_REGULAR),
+
list("UNIFORM (CHOOSE 1)", 0, null, null, null),
list("Green Scrubs", 0, /obj/item/clothing/under/rank/medical/green, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_RECOMMENDED),
list("Blue Scrubs", 0, /obj/item/clothing/under/rank/medical/blue, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_REGULAR),
@@ -311,6 +321,8 @@ GLOBAL_LIST_INIT(cm_vending_clothing_xo, list(
list("Officer Cap", 0, /obj/item/clothing/head/cmcap/ro, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
))
+
+
//------------ AUXILIARY SUPPORT OFFICER ---------------
GLOBAL_LIST_INIT(cm_vending_clothing_auxiliary_officer, list(
@@ -345,3 +357,10 @@ GLOBAL_LIST_INIT(cm_vending_clothing_auxiliary_officer, list(
list("Brown Webbing Vest", 0, /obj/item/clothing/accessory/storage/black_vest/brown_vest, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_RECOMMENDED),
list("Webbing", 0, /obj/item/clothing/accessory/storage/webbing, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_REGULAR),
))
+
+/obj/effect/essentials_set/chiefmilitarypolice
+ spawned_gear_list = list(
+ /obj/item/clothing/glasses/sunglasses/sechud,
+ /obj/item/storage/belt/security/MP/full,
+ /obj/item/clothing/head/helmet/marine/MP/WO,
+ )
diff --git a/code/game/machinery/vending/vendor_types/crew/staff_officer.dm b/code/game/machinery/vending/vendor_types/crew/staff_officer.dm
index 103efeedde61..3edbee6bbc47 100644
--- a/code/game/machinery/vending/vendor_types/crew/staff_officer.dm
+++ b/code/game/machinery/vending/vendor_types/crew/staff_officer.dm
@@ -41,7 +41,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_staff_officer, list(
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 Lifesaver Bag (Full)", 0, /obj/item/storage/belt/medical/lifesaver/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Medical Storage Rig (Full)", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M40 Grenade Rig", 0, /obj/item/storage/belt/grenade, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/crew/synthetic.dm b/code/game/machinery/vending/vendor_types/crew/synthetic.dm
index 5dddff051b50..0496530be861 100644
--- a/code/game/machinery/vending/vendor_types/crew/synthetic.dm
+++ b/code/game/machinery/vending/vendor_types/crew/synthetic.dm
@@ -21,6 +21,7 @@
list("Industrial Blowtorch", 2, /obj/item/tool/weldingtool/largetank, null, VENDOR_ITEM_REGULAR),
list("High-Capacity Industrial Blowtorch", 4, /obj/item/tool/weldingtool/hugetank, null, VENDOR_ITEM_REGULAR),
list("Plastic Explosive", 3, /obj/item/explosive/plastic, null, VENDOR_ITEM_REGULAR),
+ list("Toolkit", 1, /obj/item/storage/firstaid/toolkit/empty, null, VENDOR_ITEM_REGULAR),
list("FIRSTAID KITS", 0, null, null, null),
list("Advanced Firstaid Kit", 12, /obj/item/storage/firstaid/adv, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/crew/vehicle_crew.dm b/code/game/machinery/vending/vendor_types/crew/vehicle_crew.dm
index 023bbe390bfc..fb9b662be1bc 100644
--- a/code/game/machinery/vending/vendor_types/crew/vehicle_crew.dm
+++ b/code/game/machinery/vending/vendor_types/crew/vehicle_crew.dm
@@ -319,7 +319,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_vehicle_crew, list(
list("M103 Vehicle-Ammo Rig", 0, /obj/item/storage/belt/tank, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/engineering.dm b/code/game/machinery/vending/vendor_types/engineering.dm
index 83f69ae09889..2fe6962e93bb 100644
--- a/code/game/machinery/vending/vendor_types/engineering.dm
+++ b/code/game/machinery/vending/vendor_types/engineering.dm
@@ -25,6 +25,7 @@
list("Utility Tool Belt", round(scale * 2), /obj/item/storage/belt/utility, VENDOR_ITEM_REGULAR),
list("Welding Goggles", round(scale * 2), /obj/item/clothing/glasses/welding, VENDOR_ITEM_REGULAR),
list("Welding Helmet", round(scale * 2), /obj/item/clothing/head/welding, VENDOR_ITEM_REGULAR),
+ list("Toolkit", round(scale * 4), /obj/item/storage/firstaid/toolkit/empty, VENDOR_ITEM_REGULAR),
list("SCANNERS", -1, null, null),
list("Atmos Scanner", round(scale * 2), /obj/item/device/analyzer, VENDOR_ITEM_REGULAR),
@@ -54,6 +55,8 @@
list("EQUIPMENT", -1, null, null),
list("Utility Tool Belt", round(scale * 4), /obj/item/storage/belt/utility, VENDOR_ITEM_REGULAR),
list("Cable Coil", round(scale * 4), /obj/item/stack/cable_coil/random, VENDOR_ITEM_REGULAR),
+ list("Welding Goggles", round(scale * 2), /obj/item/clothing/glasses/welding, VENDOR_ITEM_REGULAR),
+ list("Toolkit", round(scale * 12), /obj/item/storage/firstaid/toolkit/empty, VENDOR_ITEM_REGULAR),
list("TOOLS", -1, null, null),
list("Blowtorch", round(scale * 4), /obj/item/tool/weldingtool, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/intelligence_officer.dm b/code/game/machinery/vending/vendor_types/intelligence_officer.dm
index 829c542f6b26..a2afe897b495 100644
--- a/code/game/machinery/vending/vendor_types/intelligence_officer.dm
+++ b/code/game/machinery/vending/vendor_types/intelligence_officer.dm
@@ -73,7 +73,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_intelligence_officer, list(
list("G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Toolbelt Rig (Full)", 0, /obj/item/storage/belt/utility/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
diff --git a/code/game/machinery/vending/vendor_types/requisitions.dm b/code/game/machinery/vending/vendor_types/requisitions.dm
index f85657e887a8..b979fe4a03a9 100644
--- a/code/game/machinery/vending/vendor_types/requisitions.dm
+++ b/code/game/machinery/vending/vendor_types/requisitions.dm
@@ -82,7 +82,7 @@
list("M276 Ammo Load Rig", round(scale * 15), /obj/item/storage/belt/marine, VENDOR_ITEM_REGULAR),
list("M276 General Pistol Holster Rig", round(scale * 10), /obj/item/storage/belt/gun/m4a3, VENDOR_ITEM_REGULAR),
list("M276 Knife Rig", round(scale * 5), /obj/item/storage/belt/knifepouch, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", round(scale * 5), /obj/item/storage/large_holster/m39, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", round(scale * 5), /obj/item/storage/belt/gun/m39, VENDOR_ITEM_REGULAR),
list("M276 M40 Grenade Rig", round(scale * 2), /obj/item/storage/belt/grenade, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", round(scale * 5), /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", round(scale * 2), /obj/item/storage/belt/gun/flaregun, VENDOR_ITEM_REGULAR),
@@ -342,7 +342,6 @@
/obj/structure/machinery/cm_vending/sorted/attachments/populate_product_list(scale)
listed_products = list(
list("BARREL", -1, null, null),
- list("Barrel Charger", round(scale * 2.5), /obj/item/attachable/heavy_barrel, VENDOR_ITEM_REGULAR),
list("Extended Barrel", round(scale * 6.5), /obj/item/attachable/extended_barrel, VENDOR_ITEM_REGULAR),
list("M5 Bayonet", round(scale * 10.5), /obj/item/attachable/bayonet, VENDOR_ITEM_REGULAR),
list("Recoil Compensator", round(scale * 6.5), /obj/item/attachable/compensator, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm
index 445ae80d401c..faff01f7f299 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm
@@ -116,7 +116,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_engi, list(
list("G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm
index fdfdabd8335e..9757576e6d0b 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm
@@ -127,7 +127,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_leader, list(
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Lifesaver Bag", 0, /obj/item/storage/belt/medical/lifesaver, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Medical Storage Rig", 0, /obj/item/storage/belt/medical, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm
index 532c8e58dd02..7c9682985298 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm
@@ -130,7 +130,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_medic, list(
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Lifesaver Bag (Full)", 0, /obj/item/storage/belt/medical/lifesaver/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 Medical Storage Rig (Full)", 0, /obj/item/storage/belt/medical/full, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm
index 4f10d956ee3c..d2e50aee9042 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm
@@ -55,6 +55,7 @@
//------------SQUAD PREP UNIFORM VENDOR---------------
+
/obj/structure/machinery/cm_vending/sorted/uniform_supply/squad_prep
name = "\improper ColMarTech Surplus Uniform Vendor"
desc = "An automated supply rack hooked up to a small storage of standard marine uniforms."
@@ -68,46 +69,92 @@
/obj/structure/machinery/cm_vending/sorted/uniform_supply/squad_prep/populate_product_list(scale)
listed_products = list(
- list("UNIFORM & STORAGE", -1, null, null),
- list("Lightweight IMP Backpack", 10, /obj/item/storage/backpack/marine, VENDOR_ITEM_REGULAR),
- list("Marine Radio Headset", 10, /obj/item/device/radio/headset/almayer, VENDOR_ITEM_REGULAR),
- list("Marine Combat Gloves", 10, /obj/item/clothing/gloves/marine, VENDOR_ITEM_REGULAR),
- list("Marine Black Combat Gloves", 10, /obj/item/clothing/gloves/marine/black, VENDOR_ITEM_REGULAR),
- list("Marine Combat Boots", 20, /obj/item/clothing/shoes/marine, VENDOR_ITEM_REGULAR),
- list("Shotgun Scabbard", 5, /obj/item/storage/large_holster/m37, VENDOR_ITEM_REGULAR),
- list("USCM Satchel", 10, /obj/item/storage/backpack/marine/satchel, VENDOR_ITEM_REGULAR),
- list("USCM Technical Satchel", 10, /obj/item/storage/backpack/marine/satchel/tech, VENDOR_ITEM_REGULAR),
- list("USCM Technical Chestrig", 10, /obj/item/storage/backpack/marine/engineerpack/welder_chestrig, VENDOR_ITEM_REGULAR),
- list("USCM Uniform", 20, /obj/item/clothing/under/marine, VENDOR_ITEM_REGULAR),
+ list("STANDARD EQUIPMENT", -1, null, null, null),
+ list("Marine Combat Boots", round(scale * 15), /obj/item/clothing/shoes/marine, VENDOR_ITEM_REGULAR),
+ list("USCM Uniform", round(scale * 15), /obj/item/clothing/under/marine, VENDOR_ITEM_REGULAR),
+ list("Marine Combat Gloves", round(scale * 15), /obj/item/clothing/gloves/marine, VENDOR_ITEM_REGULAR),
+ list("Marine Black Combat Gloves", round(scale * 15), /obj/item/clothing/gloves/marine/black, VENDOR_ITEM_REGULAR),
+ list("Marine Radio Headset", round(scale * 15), /obj/item/device/radio/headset/almayer, VENDOR_ITEM_REGULAR),
+ list("M10 Pattern Marine Helmet", round(scale * 15), /obj/item/clothing/head/helmet/marine, VENDOR_ITEM_REGULAR),
- list("BELTS", -1, null, null),
- list("M276 Pattern Ammo Load Rig", 10, /obj/item/storage/belt/marine, VENDOR_ITEM_REGULAR),
- list("M276 Pattern M40 Grenade Rig", 8, /obj/item/storage/belt/grenade, VENDOR_ITEM_REGULAR),
- list("M276 Pattern Shotgun Shell Loading Rig", 10, /obj/item/storage/belt/shotgun, VENDOR_ITEM_REGULAR),
- list("M276 Pattern General Pistol Holster Rig", 10, /obj/item/storage/belt/gun/m4a3, VENDOR_ITEM_REGULAR),
- list("M276 Pattern M39 Holster Rig", 10, /obj/item/storage/large_holster/m39, VENDOR_ITEM_REGULAR),
- list("M276 Pattern M44 Holster Rig", 10, /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
- list("M276 Pattern M82F Holster Rig", 5, /obj/item/storage/belt/gun/flaregun, VENDOR_ITEM_REGULAR),
+ list("WEBBINGS", -1, null, null),
+ list("Brown Webbing Vest", round(scale * 1.25), /obj/item/clothing/accessory/storage/black_vest/brown_vest, VENDOR_ITEM_REGULAR),
+ list("Black Webbing Vest", round(scale * 0.5), /obj/item/clothing/accessory/storage/black_vest, VENDOR_ITEM_REGULAR),
+ list("Webbing", round(scale * 2), /obj/item/clothing/accessory/storage/webbing, VENDOR_ITEM_REGULAR),
+ list("Drop Pouch", round(scale * 0.5), /obj/item/clothing/accessory/storage/droppouch, VENDOR_ITEM_REGULAR),
+ list("Shoulder Holster", round(scale * 0.5), /obj/item/clothing/accessory/storage/holster, VENDOR_ITEM_REGULAR),
list("ARMOR", -1, null, null),
- list("M10 Pattern Marine Helmet", 20, /obj/item/clothing/head/helmet/marine, VENDOR_ITEM_REGULAR),
- list("M3 Pattern Carrier Marine Armor", 20, /obj/item/clothing/suit/storage/marine/carrier, VENDOR_ITEM_REGULAR),
- list("M3 Pattern Padded Marine Armor", 20, /obj/item/clothing/suit/storage/marine/padded, VENDOR_ITEM_REGULAR),
- list("M3 Pattern Padless Marine Armor", 20, /obj/item/clothing/suit/storage/marine/padless, VENDOR_ITEM_REGULAR),
- list("M3 Pattern Ridged Marine Armor", 20, /obj/item/clothing/suit/storage/marine/padless_lines, VENDOR_ITEM_REGULAR),
- list("M3 Pattern Skull Marine Armor", 20, /obj/item/clothing/suit/storage/marine/skull, VENDOR_ITEM_REGULAR),
- list("M3 Pattern Smooth Marine Armor", 20, /obj/item/clothing/suit/storage/marine/smooth, VENDOR_ITEM_REGULAR),
- list("M3-EOD Pattern Heavy Armor", 10, /obj/item/clothing/suit/storage/marine/heavy, VENDOR_ITEM_REGULAR),
- list("M3-L Pattern Light Armor", 10, /obj/item/clothing/suit/storage/marine/light, VENDOR_ITEM_REGULAR),
+ list("M3 Pattern Carrier Marine Armor", round(scale * 15), /obj/item/clothing/suit/storage/marine/carrier, VENDOR_ITEM_REGULAR),
+ list("M3 Pattern Padded Marine Armor", round(scale * 15), /obj/item/clothing/suit/storage/marine/padded, VENDOR_ITEM_REGULAR),
+ list("M3 Pattern Padless Marine Armor", round(scale * 15), /obj/item/clothing/suit/storage/marine/padless, VENDOR_ITEM_REGULAR),
+ list("M3 Pattern Ridged Marine Armor", round(scale * 15), /obj/item/clothing/suit/storage/marine/padless_lines, VENDOR_ITEM_REGULAR),
+ list("M3 Pattern Skull Marine Armor", round(scale * 15), /obj/item/clothing/suit/storage/marine/skull, VENDOR_ITEM_REGULAR),
+ list("M3 Pattern Smooth Marine Armor", round(scale * 15), /obj/item/clothing/suit/storage/marine/smooth, VENDOR_ITEM_REGULAR),
+ list("M3-EOD Pattern Heavy Armor", round(scale * 10), /obj/item/clothing/suit/storage/marine/heavy, VENDOR_ITEM_REGULAR),
+ list("M3-L Pattern Light Armor", round(scale * 10), /obj/item/clothing/suit/storage/marine/light, VENDOR_ITEM_REGULAR),
+
+ list("BACKPACK", -1, null, null, null),
+ list("Lightweight IMP Backpack", round(scale * 15), /obj/item/storage/backpack/marine, VENDOR_ITEM_REGULAR),
+ list("Technician Backpack", round(scale * 15), /obj/item/storage/backpack/marine/tech, VENDOR_ITEM_REGULAR),
+ list("Medical Backpack", round(scale * 15), /obj/item/storage/backpack/marine/medic, VENDOR_ITEM_REGULAR),
+ list("USCM Satchel", round(scale * 15), /obj/item/storage/backpack/marine/satchel, VENDOR_ITEM_REGULAR),
+ list("USCM Technical Satchel", round(scale * 15), /obj/item/storage/backpack/marine/satchel/tech, VENDOR_ITEM_REGULAR),
+ list("USCM Technical Chestrig", round(scale * 15), /obj/item/storage/backpack/marine/engineerpack/welder_chestrig, VENDOR_ITEM_REGULAR),
+ list("Medical Satchel", round(scale * 15), /obj/item/storage/backpack/marine/satchel/medic, VENDOR_ITEM_REGULAR),
+ list("Shotgun Scabbard", round(scale * 5), /obj/item/storage/large_holster/m37, VENDOR_ITEM_REGULAR),
+
+ list("RESTRICTED BACKPACKS", -1, null, null),
+ list("USCM Technician Welderpack", round(scale * 1.25), /obj/item/storage/backpack/marine/engineerpack, VENDOR_ITEM_REGULAR),
+ list("Technician Welder-Satchel", round(scale * 2), /obj/item/storage/backpack/marine/engineerpack/satchel, VENDOR_ITEM_REGULAR),
+ list("Radio Telephone Backpack", round(scale * 0.5), /obj/item/storage/backpack/marine/satchel/rto, VENDOR_ITEM_REGULAR),
+
+ list("BELTS", -1, null, null),
+ list("M276 Pattern Ammo Load Rig", round(scale * 15), /obj/item/storage/belt/marine, VENDOR_ITEM_REGULAR),
+ list("M276 Pattern M40 Grenade Rig", round(scale * 10), /obj/item/storage/belt/grenade, VENDOR_ITEM_REGULAR),
+ list("M276 Pattern Shotgun Shell Loading Rig", round(scale * 15), /obj/item/storage/belt/shotgun, VENDOR_ITEM_REGULAR),
+ list("M276 Pattern General Pistol Holster Rig", round(scale * 15), /obj/item/storage/belt/gun/m4a3, VENDOR_ITEM_REGULAR),
+ list("M276 Pattern M39 Holster Rig", round(scale * 15), /obj/item/storage/large_holster/m39, VENDOR_ITEM_REGULAR),
+ list("M276 Pattern M39 Holster Rig And Pouch", round(scale * 10), /obj/item/storage/belt/gun/m39, VENDOR_ITEM_REGULAR),
+ list("M276 Pattern M44 Holster Rig", round(scale * 15), /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
+ list("M276 Pattern M82F Holster Rig", round(scale * 5), /obj/item/storage/belt/gun/flaregun, VENDOR_ITEM_REGULAR),
+ list("M276 Knife Rig (Full)", round(scale * 15), /obj/item/storage/belt/knifepouch, VENDOR_ITEM_REGULAR),
+ list("M276 G8-A General Utility Pouch", round(scale * 15), /obj/item/storage/backpack/general_belt, VENDOR_ITEM_REGULAR),
+
+ list("POUCHES", -1, null, null, null),
+ list("Bayonet Sheath (Full)",round(scale * 15), /obj/item/storage/pouch/bayonet, VENDOR_ITEM_REGULAR),
+ list("First-Aid Pouch (Splints, Gauze, Ointment)", round(scale * 15), /obj/item/storage/pouch/firstaid/full/alternate, VENDOR_ITEM_REGULAR),
+ list("First-Aid Pouch (Pill Packets)", round(scale * 15), /obj/item/storage/pouch/firstaid/full/pills, VENDOR_ITEM_REGULAR),
+ list("Flare Pouch (Full)", round(scale * 15), /obj/item/storage/pouch/flare/full, VENDOR_ITEM_REGULAR),
+ list("Small Document Pouch", round(scale * 15), /obj/item/storage/pouch/document/small, VENDOR_ITEM_REGULAR),
+ list("Magazine Pouch", round(scale * 15), /obj/item/storage/pouch/magazine, VENDOR_ITEM_REGULAR),
+ list("Shotgun Shell Pouch", round(scale * 15), /obj/item/storage/pouch/shotgun, VENDOR_ITEM_REGULAR),
+ list("Medium General Pouch", round(scale * 15), /obj/item/storage/pouch/general/medium, VENDOR_ITEM_REGULAR),
+ list("Pistol Magazine Pouch", round(scale * 15), /obj/item/storage/pouch/magazine/pistol, VENDOR_ITEM_REGULAR),
+ list("Pistol Pouch", round(scale * 15), /obj/item/storage/pouch/pistol, VENDOR_ITEM_REGULAR),
+
+ list("RESTRICTED POUCHES", -1, null, null, null),
+ list("Construction Pouch", round(scale * 1.25), /obj/item/storage/pouch/construction, VENDOR_ITEM_REGULAR),
+ list("Explosive Pouch", round(scale * 1.25), /obj/item/storage/pouch/explosive, VENDOR_ITEM_REGULAR),
+ list("First Responder Pouch (Empty)", round(scale * 2.5), /obj/item/storage/pouch/first_responder, VENDOR_ITEM_REGULAR),
+ list("Large Pistol Magazine Pouch", round(scale * 2), /obj/item/storage/pouch/magazine/pistol/large, VENDOR_ITEM_REGULAR),
+ list("Tools Pouch", round(scale * 1.25), /obj/item/storage/pouch/tools, VENDOR_ITEM_REGULAR),
+ list("Sling Pouch", round(scale * 1.25), /obj/item/storage/pouch/sling, VENDOR_ITEM_REGULAR),
+
+ list("MASK", -1, null, null, null),
+ list("Gas Mask", round(scale * 15), /obj/item/clothing/mask/gas, VENDOR_ITEM_REGULAR),
+ list("Heat Absorbent Coif", round(scale * 10), /obj/item/clothing/mask/rebreather/scarf, VENDOR_ITEM_REGULAR),
+ list("Rebreather", round(scale * 10), /obj/item/clothing/mask/rebreather, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR),
list("MISCELLANEOUS", -1, null, null, null),
- list("Gas Mask", 20, /obj/item/clothing/mask/gas, VENDOR_ITEM_REGULAR),
- list("Heat Absorbent Coif", 10, /obj/item/clothing/mask/rebreather/scarf, VENDOR_ITEM_REGULAR),
- list("M5 Integrated Gas Mask", 10, /obj/item/prop/helmetgarb/helmet_gasmask, VENDOR_ITEM_REGULAR),
- list("M10 Helmet Netting", 10, /obj/item/prop/helmetgarb/netting, VENDOR_ITEM_REGULAR),
- list("M10 Helmet Rain Cover", 10, /obj/item/prop/helmetgarb/raincover, VENDOR_ITEM_REGULAR),
- list("Firearm Lubricant", 20, /obj/item/prop/helmetgarb/gunoil, VENDOR_ITEM_REGULAR),
- list("USCM Flair", 20, /obj/item/prop/helmetgarb/flair_uscm, VENDOR_ITEM_REGULAR),
+ list("Ballistic goggles", round(scale * 10), /obj/item/clothing/glasses/mgoggles, VENDOR_ITEM_REGULAR),
+ list("Prescription ballistic goggles", round(scale * 10), /obj/item/clothing/glasses/mgoggles/prescription, VENDOR_ITEM_REGULAR),
+ list("Marine RPG glasses", round(scale * 10), /obj/item/clothing/glasses/regular, VENDOR_ITEM_REGULAR),
+ list("M5 Integrated Gas Mask", round(scale * 10), /obj/item/prop/helmetgarb/helmet_gasmask, VENDOR_ITEM_REGULAR),
+ list("M10 Helmet Netting", round(scale * 10), /obj/item/prop/helmetgarb/netting, VENDOR_ITEM_REGULAR),
+ list("M10 Helmet Rain Cover", round(scale * 10), /obj/item/prop/helmetgarb/raincover, VENDOR_ITEM_REGULAR),
+ list("Firearm Lubricant", round(scale * 15), /obj/item/prop/helmetgarb/gunoil, VENDOR_ITEM_REGULAR),
+ list("USCM Flair", round(scale * 15), /obj/item/prop/helmetgarb/flair_uscm, VENDOR_ITEM_REGULAR),
)
//--------------SQUAD SPECIFIC VERSIONS--------------
@@ -172,7 +219,6 @@
/obj/structure/machinery/cm_vending/sorted/cargo_ammo/squad/populate_product_list(scale)
listed_products = list(
-
list("ARMOR-PIERCING AMMUNITION", -1, null, null),
list("M4RA AP Magazine (10x24mm)", round(scale * 3.5), /obj/item/ammo_magazine/rifle/m4ra/ap, VENDOR_ITEM_REGULAR),
list("M39 AP Magazine (10x20mm)", round(scale * 3), /obj/item/ammo_magazine/smg/m39/ap, VENDOR_ITEM_REGULAR),
@@ -201,8 +247,8 @@
//--------------SQUAD ARMAMENTS VENDOR--------------
/obj/structure/machinery/cm_vending/sorted/cargo_guns/squad
- name = "\improper ColMarTech Automated Armaments Squad Vendor"
- desc = "An automated supply rack hooked up to a small storage of various firearms and explosives. Can be accessed by any Marine Rifleman."
+ name = "\improper ColMarTech Automated Utilities Squad Vendor"
+ desc = "An automated supply rack hooked up to a small storage of various utilities and tools. Can be accessed by any Marine Rifleman."
req_access = list(ACCESS_MARINE_ALPHA)
req_one_access = list(ACCESS_MARINE_LEADER, ACCESS_MARINE_SPECPREP, ACCESS_MARINE_RO)
hackable = TRUE
@@ -216,47 +262,30 @@
/obj/structure/machinery/cm_vending/sorted/cargo_guns/squad/populate_product_list(scale)
listed_products = list(
- list("WEBBINGS", -1, null, null),
- list("Brown Webbing Vest", round(scale * 2), /obj/item/clothing/accessory/storage/black_vest/brown_vest, VENDOR_ITEM_REGULAR),
- list("Black Webbing Vest", round(scale * 1), /obj/item/clothing/accessory/storage/black_vest, VENDOR_ITEM_REGULAR),
- list("Webbing", round(scale * 3), /obj/item/clothing/accessory/storage/webbing, VENDOR_ITEM_REGULAR),
- list("Drop Pouch", round(scale * 1), /obj/item/clothing/accessory/storage/droppouch, VENDOR_ITEM_REGULAR),
- list("Shoulder Holster", round(scale * 1), /obj/item/clothing/accessory/storage/holster, VENDOR_ITEM_REGULAR),
+ list("FOOD", -1, null, null),
+ list("MRE", round(scale * 5), /obj/item/storage/box/MRE, VENDOR_ITEM_REGULAR),
+ list("MRE Box", round(scale * 1), /obj/item/ammo_box/magazine/misc/mre, VENDOR_ITEM_REGULAR),
- list("BACKPACKS", -1, null, null),
- list("Lightweight IMP Backpack", round(scale * 15), /obj/item/storage/backpack/marine, VENDOR_ITEM_REGULAR),
- list("Shotgun Scabbard", round(scale * 5), /obj/item/storage/large_holster/m37, VENDOR_ITEM_REGULAR),
- list("USCM Technician Welderpack", round(scale * 2), /obj/item/storage/backpack/marine/engineerpack, VENDOR_ITEM_REGULAR),
- list("Technician Welder-Satchel", round(scale * 3), /obj/item/storage/backpack/marine/engineerpack/satchel, VENDOR_ITEM_REGULAR),
- list("Radio Telephone Backpack", round(scale * 1), /obj/item/storage/backpack/marine/satchel/rto, VENDOR_ITEM_REGULAR),
-
- list("BELTS", -1, null, null),
- list("G8-A General Utility Pouch", round(scale * 2), /obj/item/storage/backpack/general_belt, VENDOR_ITEM_REGULAR),
- list("M276 General Pistol Holster Rig", round(scale * 10), /obj/item/storage/belt/gun/m4a3, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", round(scale * 2), /obj/item/storage/large_holster/m39, VENDOR_ITEM_REGULAR),
- list("M276 M44 Holster Rig", round(scale * 5), /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
- list("M276 M82F Holster Rig", round(scale * 2), /obj/item/storage/belt/gun/flaregun, VENDOR_ITEM_REGULAR),
- list("M276 M40 Grenade Rig", round(scale * 3), /obj/item/storage/belt/grenade, VENDOR_ITEM_REGULAR),
-
- list("POUCHES", -1, null, null),
- list("Construction Pouch", round(scale * 2), /obj/item/storage/pouch/construction, VENDOR_ITEM_REGULAR),
- list("Document Pouch", round(scale * 2), /obj/item/storage/pouch/document/small, VENDOR_ITEM_REGULAR),
- list("Explosive Pouch", round(scale * 2), /obj/item/storage/pouch/explosive, VENDOR_ITEM_REGULAR),
- list("First-Aid Pouch (Full)", round(scale * 5), /obj/item/storage/pouch/firstaid/full/alternate, VENDOR_ITEM_REGULAR),
- list("First Responder Pouch (Empty)", round(scale * 4), /obj/item/storage/pouch/first_responder, VENDOR_ITEM_REGULAR),
- list("Flare Pouch", round(scale * 5), /obj/item/storage/pouch/flare/full, VENDOR_ITEM_REGULAR),
- list("Large Pistol Magazine Pouch", round(scale * 3), /obj/item/storage/pouch/magazine/pistol/large, VENDOR_ITEM_REGULAR),
- list("Magazine Pouch", round(scale * 5), /obj/item/storage/pouch/magazine, VENDOR_ITEM_REGULAR),
- list("Medium General Pouch", round(scale * 2), /obj/item/storage/pouch/general/medium, VENDOR_ITEM_REGULAR),
- list("Shotgun Shell Pouch", round(scale *5), /obj/item/storage/pouch/shotgun, VENDOR_ITEM_REGULAR),
- list("Sidearm Pouch", round(scale * 15), /obj/item/storage/pouch/pistol, VENDOR_ITEM_REGULAR),
- list("Tools Pouch", round(scale * 2), /obj/item/storage/pouch/tools, VENDOR_ITEM_REGULAR),
- list("Sling Pouch", round(scale * 2), /obj/item/storage/pouch/sling, VENDOR_ITEM_REGULAR),
+ list("TOOLS", -1, null, null),
+ list("Entrenching Tool (ET)", round(scale * 2), /obj/item/tool/shovel/etool/folded, VENDOR_ITEM_REGULAR),
+ list("Screwdriver", round(scale * 5), /obj/item/tool/screwdriver, VENDOR_ITEM_REGULAR),
+ list("Wirecutters", round(scale * 5), /obj/item/tool/wirecutters, VENDOR_ITEM_REGULAR),
+ list("Crowbar", round(scale * 5), /obj/item/tool/crowbar, VENDOR_ITEM_REGULAR),
+ list("Wrench", round(scale * 5), /obj/item/tool/wrench, VENDOR_ITEM_REGULAR),
+ list("ME3 hand welder", round(scale * 2), /obj/item/tool/weldingtool/simple, VENDOR_ITEM_REGULAR),
- list("MISCELLANEOUS", -1, null, null),
+ list("FLARE AND LIGHT", -1, null, null),
list("Combat Flashlight", round(scale * 5), /obj/item/device/flashlight/combat, VENDOR_ITEM_REGULAR),
- list("Entrenching Tool (ET)", round(scale * 2), /obj/item/tool/shovel/etool/folded, VENDOR_ITEM_REGULAR),
+ list("Flashlight", round(scale * 5), /obj/item/device/flashlight/combat, VENDOR_ITEM_REGULAR),
+ list("Box of Flashlight", round(scale * 1), /obj/item/ammo_box/magazine/misc/flashlight, VENDOR_ITEM_REGULAR),
+ list("Box of Flares", round(scale * 1), /obj/item/ammo_box/magazine/misc/flares, VENDOR_ITEM_REGULAR),
+ list("M94 Marking Flare Pack", round(scale * 10), /obj/item/storage/box/m94, VENDOR_ITEM_REGULAR),
list("M89-S Signal Flare Pack", round(scale * 1), /obj/item/storage/box/m94/signal, VENDOR_ITEM_REGULAR),
+
+ list("MISCELLANEOUS", -1, null, null),
+ list("Toolkit", round(scale * 1), /obj/item/storage/firstaid/toolkit/empty, VENDOR_ITEM_REGULAR),
+ list("Map", round(scale * 5), /obj/item/map/current_map, VENDOR_ITEM_REGULAR),
+ list("Extinguisher", round(scale * 5), /obj/item/tool/extinguisher, VENDOR_ITEM_REGULAR),
list("Machete Scabbard (Full)", round(scale * 5), /obj/item/storage/large_holster/machete/full, VENDOR_ITEM_REGULAR),
list("Binoculars", round(scale * 1), /obj/item/device/binoculars, VENDOR_ITEM_REGULAR),
list("MB-6 Folding Barricades (x3)", round(scale * 2), /obj/item/stack/folding_barricade/three, VENDOR_ITEM_REGULAR),
@@ -281,7 +310,6 @@
/obj/structure/machinery/cm_vending/sorted/attachments/squad/populate_product_list(scale)
listed_products = list(
list("BARREL", -1, null, null),
- list("Barrel Charger", round(scale * 0.9), /obj/item/attachable/heavy_barrel, VENDOR_ITEM_REGULAR),
list("Extended Barrel", round(scale * 2.5), /obj/item/attachable/extended_barrel, VENDOR_ITEM_REGULAR),
list("Recoil Compensator", round(scale * 2.5), /obj/item/attachable/compensator, VENDOR_ITEM_REGULAR),
list("Suppressor", round(scale * 2.5), /obj/item/attachable/suppressor, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm
index 543288c71706..d92eaabf52c1 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm
@@ -20,7 +20,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_marine, list(
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Knife Rig (Full)", 0, /obj/item/storage/belt/knifepouch, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm
index 6b763936fdc8..e0900c3fd3c8 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm
@@ -90,7 +90,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_specialist, list(
list("G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm
index 4311a3982c86..ceef80ab6952 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm
@@ -84,7 +84,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_tl, list(
list("G8-A General Utility Pouch", 0, /obj/item/storage/backpack/general_belt, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED),
list("M276 General Pistol Holster Rig", 0, /obj/item/storage/belt/gun/m4a3, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", 0, /obj/item/storage/large_holster/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 0, /obj/item/storage/belt/gun/m39, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 0, /obj/item/storage/belt/gun/m44, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 0, /obj/item/storage/belt/gun/flaregun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 0, /obj/item/storage/belt/shotgun, MARINE_CAN_BUY_BELT, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/wo_vendors.dm b/code/game/machinery/vending/vendor_types/wo_vendors.dm
index bdba638c577e..645640f9dc84 100644
--- a/code/game/machinery/vending/vendor_types/wo_vendors.dm
+++ b/code/game/machinery/vending/vendor_types/wo_vendors.dm
@@ -12,7 +12,7 @@
list("Lightweight IMP Backpack", 10, /obj/item/storage/backpack/marine, VENDOR_ITEM_REGULAR),
list("M276 Ammo Load Rig", 10, /obj/item/storage/belt/marine, VENDOR_ITEM_REGULAR),
list("M276 General Pistol Holster Rig", 10, /obj/item/storage/belt/gun/m4a3, VENDOR_ITEM_REGULAR),
- list("M276 M39 Holster Rig", 10, /obj/item/storage/large_holster/m39, VENDOR_ITEM_REGULAR),
+ list("M276 M39 Holster Rig", 10, /obj/item/storage/belt/gun/m39, VENDOR_ITEM_REGULAR),
list("M276 M44 Holster Rig", 10, /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", 10, /obj/item/storage/belt/gun/flaregun, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", 10, /obj/item/storage/belt/shotgun, VENDOR_ITEM_REGULAR),
@@ -236,7 +236,7 @@
list("G8-A General Utility Pouch", round(scale * 3), /obj/item/storage/backpack/general_belt, VENDOR_ITEM_REGULAR),
list("M276 Pattern Ammo Load Rig", round(scale * 15), /obj/item/storage/belt/marine, VENDOR_ITEM_REGULAR),
list("M276 Pattern General Pistol Holster Rig", round(scale * 10), /obj/item/storage/belt/gun/m4a3, VENDOR_ITEM_REGULAR),
- list("M276 Pattern M39 Holster Rig", round(scale * 5), /obj/item/storage/large_holster/m39, VENDOR_ITEM_REGULAR),
+ list("M276 Pattern M39 Holster Rig", round(scale * 5), /obj/item/storage/belt/gun/m39, VENDOR_ITEM_REGULAR),
list("M276 Pattern M44 Holster Rig", round(scale * 5), /obj/item/storage/belt/gun/m44, VENDOR_ITEM_REGULAR),
list("M276 M82F Holster Rig", round(scale * 2), /obj/item/storage/belt/gun/flaregun, VENDOR_ITEM_REGULAR),
list("M276 Pattern Shotgun Shell Loading Rig", round(scale * 10), /obj/item/storage/belt/shotgun, VENDOR_ITEM_REGULAR),
diff --git a/code/game/objects/effects/spawners/wo_spawners/supplies.dm b/code/game/objects/effects/spawners/wo_spawners/supplies.dm
index f2ef887d076c..28f9936b972f 100644
--- a/code/game/objects/effects/spawners/wo_spawners/supplies.dm
+++ b/code/game/objects/effects/spawners/wo_spawners/supplies.dm
@@ -175,7 +175,7 @@
/obj/effect/landmark/wo_supplies/storage/belts/m39holster
icon_state = "m39_holster"
amount = list(1,5)
- stuff = list(/obj/item/storage/large_holster/m39)
+ stuff = list(/obj/item/storage/belt/gun/m39)
diff --git a/code/game/objects/items/devices/defibrillator.dm b/code/game/objects/items/devices/defibrillator.dm
index 0596ae9d14b8..30d0467a9b76 100644
--- a/code/game/objects/items/devices/defibrillator.dm
+++ b/code/game/objects/items/devices/defibrillator.dm
@@ -11,7 +11,10 @@
w_class = SIZE_MEDIUM
var/blocked_by_suit = TRUE
- var/heart_damage_to_deal = 5
+ /// Min damage defib deals to victims' heart
+ var/min_heart_damage_dealt = 3
+ /// Max damage defib deals to victims' heart
+ var/max_heart_damage_dealt = 5
var/ready = 0
var/damage_heal_threshold = 12 //This is the maximum non-oxy damage the defibrillator will heal to get a patient above -100, in all categories
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
@@ -191,8 +194,11 @@
shock_cooldown = world.time + 10 //1 second cooldown before you can shock again
var/datum/internal_organ/heart/heart = H.internal_organs_by_name["heart"]
+ /// Has the defib already caused the chance of heart damage, to not potentially double up later
+ var/heart_already_damaged = FALSE
if(heart && prob(25))
- heart.take_damage(heart_damage_to_deal, TRUE) //Allow the defibrillator to possibly worsen heart damage. Still rare enough to just be the "clone damage" of the defib
+ heart.take_damage(rand(min_heart_damage_dealt, max_heart_damage_dealt), TRUE) // Make death and revival leave lasting consequences
+ heart_already_damaged = TRUE
if(!H.is_revivable())
playsound(get_turf(src), 'sound/items/defib_failed.ogg', 25, 0)
@@ -230,6 +236,9 @@
user.track_life_saved(user.job)
user.life_revives_total++
H.handle_revive()
+ if(heart && !heart_already_damaged)
+ heart.take_damage(rand(min_heart_damage_dealt, max_heart_damage_dealt), TRUE) // Make death and revival leave lasting consequences
+
to_chat(H, SPAN_NOTICE("You suddenly feel a spark and your consciousness returns, dragging you back to the mortal plane."))
if(H.client?.prefs.toggles_flashing & FLASH_CORPSEREVIVE)
window_flash(H.client)
@@ -239,13 +248,14 @@
/obj/item/device/defibrillator/compact_adv
name = "advanced compact defibrillator"
- desc = "An advanced compact defibrillator that trades capacity for strong immediate power. Ignores armor and heals strongly and quickly, at the cost of very low charge."
+ desc = "An advanced compact defibrillator that trades capacity for strong immediate power. Ignores armor and heals strongly and quickly, at the cost of very low charge. It does not damage the heart."
icon = 'icons/obj/items/experimental_tools.dmi'
icon_state = "compact_defib"
item_state = "defib"
w_class = SIZE_MEDIUM
blocked_by_suit = FALSE
- heart_damage_to_deal = 0
+ min_heart_damage_dealt = 0
+ max_heart_damage_dealt = 0
damage_heal_threshold = 40
charge_cost = 198
diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm
index d43883dc3156..d724e1cec10f 100644
--- a/code/game/objects/items/devices/radio/encryptionkey.dm
+++ b/code/game/objects/items/devices/radio/encryptionkey.dm
@@ -88,7 +88,7 @@
/obj/item/device/encryptionkey/cmo
name = "Chief Medical Officer's Encryption Key"
icon_state = "cmo_key"
- channels = list(RADIO_CHANNEL_MEDSCI = TRUE, RADIO_CHANNEL_COMMAND = TRUE)
+ channels = list(RADIO_CHANNEL_MEDSCI = TRUE, RADIO_CHANNEL_COMMAND = TRUE, RADIO_CHANNEL_INTEL = TRUE)
/obj/item/device/encryptionkey/med
name = "Medical Radio Encryption Key"
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index d12e5b2808a1..66efb08bedec 100644
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -1146,6 +1146,22 @@
for(var/i = 1 to storage_slots - 1)
new /obj/item/ammo_magazine/pistol/highpower/black(src)
+/obj/item/storage/belt/gun/m39
+ name = "\improper M276 pattern M39 holster rig"
+ desc = "Special issue variant of the M276 designed to holster a M39 submachine gun and two spare magazines. Uncommonly issued to USCM support and specialist personnel."
+ icon_state = "m39_armor"
+ item_state = "s_marinebelt"
+ storage_slots = 3
+ max_w_class = 5
+ can_hold = list(
+ /obj/item/weapon/gun/smg/m39,
+ /obj/item/ammo_magazine/smg,
+ )
+ holster_slots = list(
+ "1" = list(
+ "icon_x" = -11,
+ "icon_y" = -5))
+
/obj/item/storage/belt/gun/m44
name = "\improper M276 pattern M44 holster rig"
desc = "The M276 is the standard load-bearing equipment of the USCM. It consists of a modular belt with various clips. This version is for the M44 magnum revolver, along with six small pouches for speedloaders. It smells faintly of hay."
diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm
index 2e54d725511d..ea43d6b074b9 100644
--- a/code/game/objects/items/storage/fancy.dm
+++ b/code/game/objects/items/storage/fancy.dm
@@ -12,6 +12,8 @@
* Crayon Box
* Cigarette Box
* Cigar Box
+ * Match Box
+ * Vial Box
*/
/obj/item/storage/fancy
@@ -20,9 +22,10 @@
name = "donut box"
desc = "A box where round, heavenly, holey pastries reside."
var/icon_type = "donut"
+ var/plural = "s"
/obj/item/storage/fancy/update_icon()
- icon_state = "[icon_type]box[contents.len]"
+ icon_state = "[icon_type]box[length(contents)]"
/obj/item/storage/fancy/remove_from_storage(obj/item/W, atom/new_location)
. = ..()
@@ -32,17 +35,14 @@
/obj/item/storage/fancy/get_examine_text(mob/user)
. = ..()
- if(contents.len <= 0)
- . += "There are no [src.icon_type]s left in the box."
- else if(contents.len == 1)
+ if(!length(contents))
+ . += "There are no [src.icon_type][plural] left in the box."
+ else if(length(contents) == 1)
. += "There is one [src.icon_type] left in the box."
else
- . += "There are [src.contents.len] [src.icon_type]s in the box."
-
+ . += "There are [length(src.contents)] [src.icon_type][plural] in the box."
-/*
- * Egg Box
- */
+// EGG BOX
/obj/item/storage/fancy/egg_box
icon = 'icons/obj/items/food.dmi'
@@ -59,9 +59,7 @@
new /obj/item/reagent_container/food/snacks/egg(src)
return
-/*
- * Candle Box
- */
+// CANDLE BOX
/obj/item/storage/fancy/candle_box
name = "candle pack"
@@ -80,9 +78,7 @@
new /obj/item/tool/candle(src)
return
-/*
- * Crayon Box
- */
+// CRAYON BOX
/obj/item/storage/fancy/crayons
name = "box of crayons"
@@ -120,9 +116,8 @@
return
..()
-////////////
-//CIG PACK//
-////////////
+// CIGARETTES BOX
+
/obj/item/storage/fancy/cigarettes
icon = 'icons/obj/items/cigarettes.dmi'
icon_state = "cigpacket"
@@ -153,14 +148,14 @@
icon_state = "[initial(icon_state)]"
/obj/item/storage/fancy/cigarettes/update_icon()
- icon_state = "[initial(icon_state)][contents.len]"
+ icon_state = "[initial(icon_state)][length(contents)]"
return
/obj/item/storage/fancy/cigarettes/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M, /mob))
return
- if(M == user && user.zone_selected == "mouth" && contents.len > 0 && !user.wear_mask)
+ if(M == user && user.zone_selected == "mouth" && length(contents) > 0 && !user.wear_mask)
var/obj/item/clothing/mask/cigarette/C = locate() in src
if(C)
remove_from_storage(C, get_turf(user))
@@ -223,9 +218,7 @@
default_cig_type = /obj/item/clothing/mask/cigarette/ucigarette
storage_slots = 4
-/////////////
-//CIGAR BOX//
-/////////////
+// CIGAR BOX
/obj/item/storage/fancy/cigar
name = "cigar case"
@@ -253,14 +246,14 @@
icon_state = "[initial(icon_state)]"
/obj/item/storage/fancy/cigar/update_icon()
- icon_state = "[initial(icon_state)][contents.len]"
+ icon_state = "[initial(icon_state)][length(contents)]"
return
/obj/item/storage/fancy/cigar/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M, /mob))
return
- if(M == user && user.zone_selected == "mouth" && contents.len > 0 && !user.wear_mask)
+ if(M == user && user.zone_selected == "mouth" && length(contents) > 0 && !user.wear_mask)
var/obj/item/clothing/mask/cigarette/cigar/C = locate() in src
if(C)
remove_from_storage(C, get_turf(user))
@@ -286,6 +279,8 @@
storage_slots = 1
default_cigar_type = /obj/item/clothing/mask/cigarette/cigar/tarbacks
+// MATCH BOX
+
/obj/item/storage/fancy/cigar/matchbook
name = "\improper Lucky Strikes matchbook"
desc = "A small book of cheap paper matches. Good luck getting them to light. Made by Lucky Strikes, but you'll be anything but lucky when you burn your hand trying to light a match on this."
@@ -298,6 +293,7 @@
w_class = SIZE_TINY
var/light_chance = 70 //how likely you are to light the match on the book
var/burn_chance = 20 //how likely you are to burn yourself once you light it
+ plural = "es"
/obj/item/storage/fancy/cigar/matchbook/attackby(obj/item/tool/match/W as obj, mob/living/carbon/human/user as mob)
if(!istype(user))
@@ -340,9 +336,7 @@
light_chance = 60
burn_chance = 40
-/*
- * Vial Box
- */
+// VIAL BOX
/obj/item/storage/fancy/vials
icon = 'icons/obj/items/vialbox.dmi'
@@ -401,7 +395,7 @@
req_access = list(ACCESS_MARINE_MEDBAY)
/obj/item/storage/lockbox/vials/update_icon(itemremoved = 0)
- var/total_contents = src.contents.len - itemremoved
+ var/total_contents = length(src.contents) - itemremoved
src.icon_state = "vialbox[total_contents]"
src.overlays.Cut()
if (!broken)
diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm
index ccab1bf3dfc7..0d976b4cdf57 100644
--- a/code/game/objects/items/storage/firstaid.dm
+++ b/code/game/objects/items/storage/firstaid.dm
@@ -212,6 +212,22 @@
/obj/item/storage/firstaid/surgical/empty/fill_preset_inventory()
return
+//---------TOOLKIT---------
+
+/obj/item/storage/firstaid/toolkit
+ name = "toolkit"
+ desc = "An combat engineering toolkit intended to carry electrical and mechanical supplies into combat."
+ icon_state = "toolkit"
+ item_state = "fulton"
+
+/obj/item/storage/firstaid/toolkit/update_icon()
+ if(content_watchers || !length(contents))
+ icon_state = "toolkit_empty"
+ else
+ icon_state = icon_full
+
+/obj/item/storage/firstaid/toolkit/empty/fill_preset_inventory()
+ return
//---------SYRINGE CASE---------
@@ -265,7 +281,14 @@
/obj/item/storage/surgical_case
name = "surgical case"
- desc = "It's a medical case for storing basic surgical tools."
+ desc = "It's a medical case for storing basic surgical tools. It comes with a brief description for treating common internal bleeds.\
+ \nBefore surgery: Verify correct location and patient is adequately numb to pain.\
+ \nStep one: Open an incision at the site with the scalpel.\
+ \nStep two: Clamp bleeders with the hemostat.\
+ \nStep three: Draw back the skin with the retracter.\
+ \nStep four: Patch the damaged vein with a surgical line.\
+ \nStep five: Close the incision with a surgical line."
+
icon_state = "surgical_case"
throw_speed = SPEED_FAST
throw_range = 8
diff --git a/code/game/objects/items/tools/shovel_tools.dm b/code/game/objects/items/tools/shovel_tools.dm
index 29bc19f65bbf..008b37705fe3 100644
--- a/code/game/objects/items/tools/shovel_tools.dm
+++ b/code/game/objects/items/tools/shovel_tools.dm
@@ -233,7 +233,7 @@
/obj/item/tool/shovel/etool/attack_self(mob/user as mob)
folded = !folded
if(folded)
- w_class = SIZE_MEDIUM
+ w_class = SIZE_SMALL
force = 2
else
w_class = SIZE_LARGE
@@ -242,7 +242,7 @@
/obj/item/tool/shovel/etool/folded
folded = TRUE
- w_class = SIZE_MEDIUM
+ w_class = SIZE_SMALL
force = 2
icon_state = "etool_c"
item_state = "etool_c"
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cm_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/cm_closets.dm
index fbd476e2bfe5..5772db33198d 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/cm_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/cm_closets.dm
@@ -134,7 +134,7 @@ GLOBAL_LIST_EMPTY(co_secure_boxes)
new /obj/item/clothing/under/marine/officer/pilot(src)
new /obj/item/clothing/shoes/marine(src)
new /obj/item/clothing/suit/armor/vest/pilot(src)
- new /obj/item/storage/large_holster/m39(src)
+ new /obj/item/storage/belt/gun/m39(src)
new /obj/item/storage/backpack/marine/satchel(src)
new /obj/item/clothing/gloves/yellow(src)
new /obj/item/clothing/glasses/sunglasses(src)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm b/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm
index c8f5a7f82c0f..7a4274c2c16e 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm
@@ -20,8 +20,6 @@
var/force_nest = FALSE
/// counterpart to buckling_y --> offsets the buckled mob when it buckles
var/list/buckling_x
- /// saves the density of the buckled_mob
- var/buckled_mob_density
/obj/structure/bed/nest/Initialize(mapload, hive)
. = ..()
@@ -52,7 +50,6 @@
resisting_ready = FALSE
if(buckled_mob == current_mob)
- buckled_mob_density = current_mob.density
current_mob.pixel_y = buckling_y["[dir]"]
current_mob.pixel_x = buckling_x["[dir]"]
current_mob.dir = turn(dir, 180)
@@ -70,7 +67,7 @@
current_mob.pixel_y = initial(buckled_mob.pixel_y)
current_mob.pixel_x = initial(buckled_mob.pixel_x)
- current_mob.density = buckled_mob_density
+ current_mob.density = !(current_mob.lying || current_mob.stat == DEAD)
if(dir == SOUTH)
current_mob.layer = initial(current_mob.layer)
if(!ishuman(current_mob))
@@ -281,8 +278,6 @@
buckled_mob.old_y = 0
REMOVE_TRAIT(buckled_mob, TRAIT_NESTED, TRAIT_SOURCE_BUCKLE)
var/mob/living/carbon/human/buckled_human = buckled_mob
- if(buckled_human.stat == DEAD )
- buckled_mob_density = FALSE
var/mob/dead/observer/G = ghost_of_buckled_mob
var/datum/mind/M = G?.mind
@@ -311,7 +306,6 @@
/obj/structure/bed/nest/proc/healthcheck()
if(health <= 0)
- buckled_mob_density = FALSE
deconstruct()
/obj/structure/bed/nest/fire_act()
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/modules/admin/player_panel/actions/transform.dm b/code/modules/admin/player_panel/actions/transform.dm
index 185165357e05..91a62b1a1d02 100644
--- a/code/modules/admin/player_panel/actions/transform.dm
+++ b/code/modules/admin/player_panel/actions/transform.dm
@@ -127,7 +127,7 @@ GLOBAL_LIST_INIT(pp_transformables, list(
"Alien Tier 4" = list(
list(
- name = XENO_CASTE_QUEEN+" (Young)",
+ name = XENO_CASTE_QUEEN+" (Immature)",
key = /mob/living/carbon/xenomorph/queen,
color = "purple"
),
diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm
index f5f1122fa795..3f0775c0b65d 100644
--- a/code/modules/asset_cache/asset_list_items.dm
+++ b/code/modules/asset_cache/asset_list_items.dm
@@ -205,10 +205,10 @@
/datum/asset/spritesheet/playtime_rank/register()
var/icon_file = 'icons/mob/hud/hud.dmi'
- var/tier1_state = "hudxenoupgrade1"
- var/tier2_state = "hudxenoupgrade2"
- var/tier3_state = "hudxenoupgrade3"
- var/tier4_state = "hudxenoupgrade4"
+ var/tier1_state = "hudxenoupgrade2"
+ var/tier2_state = "hudxenoupgrade3"
+ var/tier3_state = "hudxenoupgrade4"
+ var/tier4_state = "hudxenoupgrade5"
var/icon/tier1_icon = icon(icon_file, tier1_state, SOUTH)
var/icon/tier2_icon = icon(icon_file, tier2_state, SOUTH)
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/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/clothing/suits/marine_armor.dm b/code/modules/clothing/suits/marine_armor.dm
index 20004e0367fb..910bb032349e 100644
--- a/code/modules/clothing/suits/marine_armor.dm
+++ b/code/modules/clothing/suits/marine_armor.dm
@@ -75,6 +75,7 @@
/obj/item/storage/belt/gun/flaregun,
/obj/item/device/motiondetector,
/obj/item/device/walkman,
+ /obj/item/storage/belt/gun/m39,
)
valid_accessory_slots = list(ACCESSORY_SLOT_MEDAL, ACCESSORY_SLOT_PONCHO)
diff --git a/code/modules/cm_aliens/structures/special/pylon_core.dm b/code/modules/cm_aliens/structures/special/pylon_core.dm
index 993d4f833fa6..068ffeb659eb 100644
--- a/code/modules/cm_aliens/structures/special/pylon_core.dm
+++ b/code/modules/cm_aliens/structures/special/pylon_core.dm
@@ -12,6 +12,7 @@
block_range = 0
var/cover_range = WEED_RANGE_PYLON
var/node_type = /obj/effect/alien/weeds/node/pylon
+ var/obj/effect/alien/weeds/node/node
var/linked_turfs = list()
var/damaged = FALSE
@@ -25,7 +26,7 @@
/obj/effect/alien/resin/special/pylon/Initialize(mapload, hive_ref)
. = ..()
- place_node()
+ node = place_node()
for(var/turf/A in range(round(cover_range*PYLON_COVERAGE_MULT), loc))
LAZYADD(A.linked_pylons, src)
linked_turfs += A
@@ -34,9 +35,8 @@
for(var/turf/A as anything in linked_turfs)
LAZYREMOVE(A.linked_pylons, src)
- var/obj/effect/alien/weeds/node/pylon/W = locate() in loc
- if(W)
- qdel(W)
+ if(node)
+ QDEL_NULL(node)
. = ..()
/obj/effect/alien/resin/special/pylon/attack_alien(mob/living/carbon/xenomorph/M)
@@ -87,8 +87,78 @@
playsound(loc, "alien_resin_build", 25)
/obj/effect/alien/resin/special/pylon/proc/place_node()
- var/obj/effect/alien/weeds/node/pylon/W = new node_type(loc, null, null, linked_hive)
- W.resin_parent = src
+ var/obj/effect/alien/weeds/node/pylon/pylon_node = new node_type(loc, null, null, linked_hive)
+ pylon_node.resin_parent = src
+ return pylon_node
+
+/obj/effect/alien/resin/special/pylon/endgame
+ cover_range = WEED_RANGE_CORE
+ var/activated = FALSE
+
+/obj/effect/alien/resin/special/pylon/endgame/Destroy()
+ if(activated)
+ activated = FALSE
+
+ if(hijack_delete)
+ return ..()
+
+ marine_announcement("ALERT.\n\nEnergy build up around communication relay at [get_area(src)] halted.", "[MAIN_AI_SYSTEM] Biological Scanner")
+
+ for(var/hivenumber in GLOB.hive_datum)
+ var/datum/hive_status/checked_hive = GLOB.hive_datum[hivenumber]
+ if(!length(checked_hive.totalXenos))
+ continue
+
+ if(checked_hive == linked_hive)
+ xeno_announcement(SPAN_XENOANNOUNCE("We have lost our control of the tall's communication relay at [get_area(src)]."), hivenumber, XENO_GENERAL_ANNOUNCE)
+ else
+ xeno_announcement(SPAN_XENOANNOUNCE("Another hive has lost control of the tall's communication relay at [get_area(src)]."), hivenumber, XENO_GENERAL_ANNOUNCE)
+
+ return ..()
+
+/// Checks if all comms towers are connected and then starts end game content on all pylons if they are
+/obj/effect/alien/resin/special/pylon/endgame/proc/comms_relay_connection()
+ marine_announcement("ALERT.\n\nIrregular build up of energy around communication relays at [get_area(src)].", "[MAIN_AI_SYSTEM] Biological Scanner")
+
+ for(var/hivenumber in GLOB.hive_datum)
+ var/datum/hive_status/checked_hive = GLOB.hive_datum[hivenumber]
+ if(!length(checked_hive.totalXenos))
+ continue
+
+ if(checked_hive == linked_hive)
+ xeno_announcement(SPAN_XENOANNOUNCE("We have harnessed the tall's communication relay at [get_area(src)]. Hold it!"), hivenumber, XENO_GENERAL_ANNOUNCE)
+ else
+ xeno_announcement(SPAN_XENOANNOUNCE("Another hive has harnessed the tall's communication relay at [get_area(src)].[linked_hive.faction_is_ally(checked_hive.name) ? "" : " Stop them!"]"), hivenumber, XENO_GENERAL_ANNOUNCE)
+
+ activated = TRUE
+ addtimer(CALLBACK(src, PROC_REF(give_larva)), XENO_PYLON_ACTIVATION_COOLDOWN, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_LOOP|TIMER_DELETE_ME)
+
+#define ENDGAME_LARVA_CAP_MULTIPLIER 0.4
+#define LARVA_ADDITION_MULTIPLIER 0.10
+
+/// Looped proc via timer to give larva after time
+/obj/effect/alien/resin/special/pylon/endgame/proc/give_larva()
+ if(!activated)
+ return
+
+ if(!linked_hive.hive_location || !linked_hive.living_xeno_queen)
+ return
+
+ var/list/hive_xenos = linked_hive.totalXenos
+
+ for(var/mob/living/carbon/xenomorph/xeno in hive_xenos)
+ if(!xeno.counts_for_slots)
+ hive_xenos -= xeno
+
+ if(length(hive_xenos) > (length(GLOB.alive_human_list) * ENDGAME_LARVA_CAP_MULTIPLIER))
+ return
+
+ linked_hive.partial_larva += length(hive_xenos) * LARVA_ADDITION_MULTIPLIER
+ linked_hive.convert_partial_larva_to_full_larva()
+ linked_hive.hive_ui.update_burrowed_larva()
+
+#undef ENDGAME_LARVA_CAP_MULTIPLIER
+#undef LARVA_ADDITION_MULTIPLIER
//Hive Core - Generates strong weeds, supports other buildings
/obj/effect/alien/resin/special/pylon/core
diff --git a/code/modules/cm_aliens/structures/special_structure.dm b/code/modules/cm_aliens/structures/special_structure.dm
index caa729f1df87..69bdcc2438ac 100644
--- a/code/modules/cm_aliens/structures/special_structure.dm
+++ b/code/modules/cm_aliens/structures/special_structure.dm
@@ -39,6 +39,9 @@
plane = FLOOR_PLANE
+ /// Tells the structure if they are being deleted because of hijack
+ var/hijack_delete = FALSE
+
/obj/effect/alien/resin/special/Initialize(mapload, hive_ref)
. = ..()
maxhealth = health
diff --git a/code/modules/cm_aliens/weeds.dm b/code/modules/cm_aliens/weeds.dm
index f20fa842e446..01140beae304 100644
--- a/code/modules/cm_aliens/weeds.dm
+++ b/code/modules/cm_aliens/weeds.dm
@@ -55,7 +55,7 @@
linked_hive = GLOB.hive_datum[hivenumber]
set_hive_data(src, hivenumber)
- if(spread_on_semiweedable)
+ if(spread_on_semiweedable && weed_strength < WEED_LEVEL_HIVE)
if(color)
var/list/RGB = ReadRGB(color)
RGB[1] = Clamp(RGB[1] + 35, 0, 255)
@@ -588,9 +588,13 @@
weed_strength = WEED_LEVEL_HIVE
node_range = WEED_RANGE_PYLON
overlay_node = FALSE
+ spread_on_semiweedable = TRUE
var/obj/effect/alien/resin/special/resin_parent
/obj/effect/alien/weeds/node/pylon/proc/set_parent_damaged()
+ if(!resin_parent)
+ return
+
var/obj/effect/alien/resin/special/pylon/parent_pylon = resin_parent
parent_pylon.damaged = TRUE
@@ -616,7 +620,13 @@
/obj/effect/alien/weeds/node/pylon/acid_spray_act()
return
+/obj/effect/alien/weeds/node/pylon/cluster
+ spread_on_semiweedable = FALSE
+
/obj/effect/alien/weeds/node/pylon/cluster/set_parent_damaged()
+ if(!resin_parent)
+ return
+
var/obj/effect/alien/resin/special/cluster/parent_cluster = resin_parent
parent_cluster.damaged = TRUE
diff --git a/code/modules/cm_marines/equipment/guncases.dm b/code/modules/cm_marines/equipment/guncases.dm
index 8538af7ca90e..a9a3855a53e4 100644
--- a/code/modules/cm_marines/equipment/guncases.dm
+++ b/code/modules/cm_marines/equipment/guncases.dm
@@ -295,3 +295,47 @@
new /obj/item/weapon/gun/shotgun/double/cane(src)
new /obj/item/ammo_magazine/handful/revolver/marksman/six_rounds(src)
new /obj/item/ammo_magazine/handful/revolver/marksman/six_rounds(src)
+
+//Handgun case for Military police vendor three mag , a railflashligh and the handgun.
+
+//88 Mod 4 Combat Pistol
+/obj/item/storage/box/guncase/mod88
+ name = "\improper 88 Mod 4 Combat Pistol case"
+ desc = "A gun case containing an 88 Mod 4 Combat Pistol."
+ storage_slots = 5
+ can_hold = list(/obj/item/attachable/flashlight, /obj/item/weapon/gun/pistol/mod88, /obj/item/ammo_magazine/pistol/mod88)
+
+/obj/item/storage/box/guncase/mod88/fill_preset_inventory()
+ new /obj/item/attachable/flashlight(src)
+ new /obj/item/weapon/gun/pistol/mod88(src)
+ new /obj/item/ammo_magazine/pistol/mod88(src)
+ new /obj/item/ammo_magazine/pistol/mod88(src)
+ new /obj/item/ammo_magazine/pistol/mod88(src)
+
+//M44 Combat Revolver
+/obj/item/storage/box/guncase/m44
+ name = "\improper M44 Combat Revolver case"
+ desc = "A gun case containing an M44 Combat Revolver."
+ storage_slots = 5
+ can_hold = list(/obj/item/attachable/flashlight, /obj/item/weapon/gun/revolver/m44, /obj/item/ammo_magazine/revolver)
+
+/obj/item/storage/box/guncase/m44/fill_preset_inventory()
+ new /obj/item/attachable/flashlight(src)
+ new /obj/item/weapon/gun/revolver/m44(src)
+ new /obj/item/ammo_magazine/revolver(src)
+ new /obj/item/ammo_magazine/revolver(src)
+ new /obj/item/ammo_magazine/revolver(src)
+
+//M4A3 Service Pistol
+/obj/item/storage/box/guncase/m4a3
+ name = "\improper M4A3 Service Pistol case"
+ desc = "A gun case containing an M4A3 Service Pistol."
+ storage_slots = 5
+ can_hold = list(/obj/item/attachable/flashlight, /obj/item/weapon/gun/pistol/m4a3, /obj/item/ammo_magazine/pistol)
+
+/obj/item/storage/box/guncase/m4a3/fill_preset_inventory()
+ new /obj/item/attachable/flashlight(src)
+ new /obj/item/weapon/gun/pistol/m4a3(src)
+ new /obj/item/ammo_magazine/pistol(src)
+ new /obj/item/ammo_magazine/pistol(src)
+ new /obj/item/ammo_magazine/pistol(src)
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_preds/yaut_bracers.dm b/code/modules/cm_preds/yaut_bracers.dm
index 305badf6fceb..a94cde9887c3 100644
--- a/code/modules/cm_preds/yaut_bracers.dm
+++ b/code/modules/cm_preds/yaut_bracers.dm
@@ -997,19 +997,10 @@
if(.)
return
- for(var/obj/item/weapon/yautja/combistick/C in range(7))
- if(C in caller.contents) //Can't yank if they are wearing it
- return FALSE
- if(caller.put_in_active_hand(C))//Try putting it in our active hand, or, if it's full...
- if(!drain_power(caller, 70)) //We should only drain power if we actually yank the chain back. Failed attempts can quickly drain the charge away.
- return TRUE
- caller.visible_message(SPAN_WARNING("[caller] yanks [C]'s chain back!"), SPAN_WARNING("You yank [C]'s chain back!"))
- else if(caller.put_in_inactive_hand(C))///...Try putting it in our inactive hand.
- if(!drain_power(caller, 70)) //We should only drain power if we actually yank the chain back. Failed attempts can quickly drain the charge away.
- return TRUE
- caller.visible_message(SPAN_WARNING("[caller] yanks [C]'s chain back!"), SPAN_WARNING("You yank [C]'s chain back!"))
- else //If neither hand can hold it, you must not have a free hand.
- to_chat(caller, SPAN_WARNING("You need a free hand to do this!"))
+ for(var/datum/effects/tethering/tether in caller.effects_list)
+ if(istype(tether.tethered.affected_atom, /obj/item/weapon/yautja/combistick))
+ var/obj/item/weapon/yautja/combistick/stick = tether.tethered.affected_atom
+ stick.recall()
/obj/item/clothing/gloves/yautja/hunter/verb/translate()
set name = "Translator"
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/cm_preds/yaut_weapons.dm b/code/modules/cm_preds/yaut_weapons.dm
index fbbe6c183aaa..5ff13c843ee3 100644
--- a/code/modules/cm_preds/yaut_weapons.dm
+++ b/code/modules/cm_preds/yaut_weapons.dm
@@ -254,6 +254,17 @@
var/force_wielded = MELEE_FORCE_TIER_6
var/force_unwielded = MELEE_FORCE_TIER_2
var/force_storage = MELEE_FORCE_TIER_1
+ /// Ref to the tether effect when thrown
+ var/datum/effects/tethering/chain
+
+/obj/item/weapon/yautja/combistick/Destroy()
+ cleanup_chain()
+ return ..()
+
+/obj/item/weapon/yautja/combistick/dropped(mob/user)
+ . = ..()
+ if(on && isturf(loc))
+ setup_chain(user)
/obj/item/weapon/yautja/combistick/try_to_throw(mob/living/user)
if(!charged)
@@ -262,8 +273,66 @@
charged = FALSE
remove_filter("combistick_charge")
unwield(user) //Otherwise stays wielded even when thrown
+ if(on)
+ setup_chain(user)
return TRUE
+/obj/item/weapon/yautja/combistick/proc/setup_chain(mob/living/user)
+ var/list/tether_effects = apply_tether(user, src, range = 6, resistable = FALSE)
+ chain = tether_effects["tetherer_tether"]
+ RegisterSignal(chain, COMSIG_PARENT_QDELETING, PROC_REF(cleanup_chain))
+ RegisterSignal(src, COMSIG_ITEM_PICKUP, PROC_REF(on_pickup))
+ RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
+
+/// The chain normally breaks if it's put into a container, so let's yank it back if that's the case
+/obj/item/weapon/yautja/combistick/proc/on_move(datum/source, atom/moved, dir, forced)
+ SIGNAL_HANDLER
+ if(!z && !is_type_in_list(loc, list(/obj/structure/surface, /mob))) // I rue for the day I can remove the surface snowflake check
+ recall()
+
+/// Clean up the chain, deleting/nulling/unregistering as needed
+/obj/item/weapon/yautja/combistick/proc/cleanup_chain()
+ SIGNAL_HANDLER
+ if(!QDELETED(chain))
+ QDEL_NULL(chain)
+
+ else
+ chain = null
+
+ UnregisterSignal(src, COMSIG_ITEM_PICKUP)
+ UnregisterSignal(src, COMSIG_MOVABLE_MOVED)
+
+/obj/item/weapon/yautja/combistick/proc/on_pickup(datum/source, mob/user)
+ SIGNAL_HANDLER
+ if(user != chain.affected_atom)
+ to_chat(chain.affected_atom, SPAN_WARNING("You feel the chain of [src] be torn from your grasp!")) // Recall the fuckin combi my man
+
+ cleanup_chain()
+
+/// recall the combistick to the pred's hands or to be at their feet
+/obj/item/weapon/yautja/combistick/proc/recall()
+ SIGNAL_HANDLER
+ if(!chain)
+ return
+
+ var/mob/living/carbon/human/user = chain.affected_atom
+ if((src in user.contents) || !istype(user.gloves, /obj/item/clothing/gloves/yautja/hunter))
+ cleanup_chain()
+ return
+
+ var/obj/item/clothing/gloves/yautja/hunter/pred_gloves = user.gloves
+
+ if(user.put_in_hands(src, TRUE))
+ if(!pred_gloves.drain_power(user, 70))
+ return TRUE
+ user.visible_message(SPAN_WARNING("[user] yanks [src]'s chain back, catching it in [user.p_their()] hand!"), SPAN_WARNING("You yank [src]'s chain back, catching it inhand!"))
+ cleanup_chain()
+
+ else
+ if(!pred_gloves.drain_power(user, 70))
+ return TRUE
+ user.visible_message(SPAN_WARNING("[user] yanks [src]'s chain back, letting [src] fall at [user.p_their()]!"), SPAN_WARNING("You yank [src]'s chain back, letting it drop at your feet!"))
+ cleanup_chain()
/obj/item/weapon/yautja/combistick/IsShield()
return on
@@ -823,7 +892,7 @@
/obj/item/weapon/gun/energy/yautja/plasmarifle
name = "plasma rifle"
- desc = "A long-barreled heavy plasma weapon capable of taking down large game. It has a mounted scope for distant shots and an integrated battery."
+ desc = "A long-barreled heavy plasma weapon. Intended for combat, not hunting. Has an integrated battery that allows for a functionally unlimited amount of shots to be discharged. Equipped with an internal gyroscopic stabilizer allowing its operator to fire the weapon one-handed if desired"
icon_state = "plasmarifle"
item_state = "plasmarifle"
unacidable = TRUE
@@ -836,7 +905,7 @@
var/charge_time = 0
var/last_regen = 0
flags_gun_features = GUN_UNUSUAL_DESIGN
- flags_item = ITEM_PREDATOR
+ flags_item = ITEM_PREDATOR|TWOHANDED
/obj/item/weapon/gun/energy/yautja/plasmarifle/Initialize(mapload, spawn_empty)
. = ..()
@@ -889,12 +958,8 @@
return ..()
/obj/item/weapon/gun/energy/yautja/plasmarifle/load_into_chamber()
- if(charge_time >= 80)
- ammo = GLOB.ammo_list[/datum/ammo/energy/yautja/rifle/blast]
- charge_time -= 80
- else
- ammo = GLOB.ammo_list[/datum/ammo/energy/yautja/rifle/bolt]
- charge_time -= 10
+ ammo = GLOB.ammo_list[/datum/ammo/energy/yautja/rifle/bolt]
+ charge_time -= 10
var/obj/item/projectile/projectile = create_bullet(ammo, initial(name))
projectile.SetLuminosity(1)
in_chamber = projectile
diff --git a/code/modules/cm_tech/implements/medical_czsp.dm b/code/modules/cm_tech/implements/medical_czsp.dm
index e0b00ebf5afd..3eed2fc9f619 100644
--- a/code/modules/cm_tech/implements/medical_czsp.dm
+++ b/code/modules/cm_tech/implements/medical_czsp.dm
@@ -83,10 +83,11 @@
/obj/item/device/defibrillator/upgraded
name = "upgraded emergency defibrillator"
icon_state = "adv_defib"
- desc = "An advanced rechargeable defibrillator using induction to deliver shocks through metallic objects, such as armor, and does so with much greater efficiency than the standard variant."
+ desc = "An advanced rechargeable defibrillator using induction to deliver shocks through metallic objects, such as armor, and does so with much greater efficiency than the standard variant, not damaging the heart."
blocked_by_suit = FALSE
- heart_damage_to_deal = 0
+ min_heart_damage_dealt = 0
+ max_heart_damage_dealt = 0
damage_heal_threshold = 35
/obj/item/ammo_magazine/internal/pillgun
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 9e8fa264af1d..ee36d25fc687 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -544,6 +544,27 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(!istype(target))
return
+ if(check_client_rights(client, R_MOD, FALSE))
+ view_health_scan(target)
+ return
+
+ if(!mind.original)
+ view_health_scan(target)
+ return
+
+ if(!ishuman(mind.original))
+ view_health_scan(target)
+ return
+
+ var/mob/living/carbon/human/original_human = mind.original
+
+ if(!original_human.check_tod() || !original_human.is_revivable() || !can_reenter_corpse)
+ view_health_scan(target)
+ return
+
+ to_chat(src, SPAN_NOTICE("You must be permanently unrevivable or unable to reenter your body to use the scan health verb."))
+
+/mob/dead/observer/proc/view_health_scan(mob/living/target)
if (!last_health_display)
last_health_display = new(target)
else
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index 61848eda251c..72a95074e574 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -29,27 +29,35 @@
b_volume = 0
else if(chem_effect_flags & CHEM_EFFECT_ORGAN_STASIS)
b_volume *= 1
- else if(heart.damage > 1 && heart.damage < heart.min_bruised_damage)
- b_volume *= 0.8
- else if(heart.damage >= heart.min_bruised_damage && heart.damage < heart.min_broken_damage)
- b_volume *= 0.6
- else if(heart.damage >= heart.min_broken_damage && heart.damage < INFINITY)
- b_volume *= 0.3
+ else if(heart.damage >= heart.organ_status >= ORGAN_BRUISED)
+ b_volume *= Clamp(100 - (2 * heart.damage), 30, 100) / 100
//Effects of bloodloss
+ if(b_volume <= BLOOD_VOLUME_SAFE)
+ /// The blood volume turned into a %, with BLOOD_VOLUME_NORMAL being 100%
+ var/blood_percentage = b_volume / (BLOOD_VOLUME_NORMAL / 100)
+ /// How much oxyloss will there be from the next time blood processes
+ var/additional_oxyloss = (100 - blood_percentage) / 5
+ /// 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)
+
+ //Bloodloss effects on nutrition
+ if(nutrition >= 300)
+ nutrition -= 10
+ else if(nutrition >= 200)
+ nutrition -= 3
+
switch(b_volume)
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
if(prob(1))
var/word = pick("dizzy","woozy","faint")
to_chat(src, SPAN_DANGER("You feel [word]."))
- if(oxyloss < 20)
- oxyloss += 3
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
if(eye_blurry < 50)
AdjustEyeBlur(6)
- if(oxyloss < 50)
- oxyloss += 10
- oxyloss += 2
+ oxyloss += 3
if(prob(15))
apply_effect(rand(1,3), PARALYZE)
var/word = pick("dizzy","woozy","faint")
@@ -57,7 +65,7 @@
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
if(eye_blurry < 50)
AdjustEyeBlur(6)
- oxyloss += 5
+ oxyloss += 8
toxloss += 3
if(prob(15))
apply_effect(rand(1,3), PARALYZE)
@@ -66,13 +74,6 @@
if(0 to BLOOD_VOLUME_SURVIVE)
death(create_cause_data("blood loss"))
- // Without enough blood you slowly go hungry.
- if(blood_volume < BLOOD_VOLUME_SAFE)
- if(nutrition >= 300)
- nutrition -= 10
- else if(nutrition >= 200)
- nutrition -= 3
-
// Xeno blood regeneration
/mob/living/carbon/xenomorph/handle_blood()
if(stat != DEAD) //Only living xenos regenerate blood
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index d01416b2443f..c5de5bda0fa1 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1387,6 +1387,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/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/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/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/XenoUpgrade.dm b/code/modules/mob/living/carbon/xenomorph/XenoUpgrade.dm
index a89a3ad32e85..ae03d0646657 100644
--- a/code/modules/mob/living/carbon/xenomorph/XenoUpgrade.dm
+++ b/code/modules/mob/living/carbon/xenomorph/XenoUpgrade.dm
@@ -3,6 +3,7 @@
return
age = XENO_NORMAL
+ var/hours_as_xeno = client.get_total_xeno_playtime()
var/hours_as_caste = get_job_playtime(client, caste.caste_type)
switch(hours_as_caste)
@@ -15,11 +16,16 @@
if(JOB_PLAYTIME_TIER_4 to INFINITY)
age = XENO_PRIME
+ if(hours_as_xeno < JOB_PLAYTIME_TIER_1)
+ age = XENO_YOUNG
+
// For people who wish to remain anonymous
if(!client.prefs.playtime_perks)
age = XENO_NORMAL
switch(age)
+ if(XENO_YOUNG)
+ age_prefix = "Young "
if(XENO_NORMAL)
age_prefix = ""
if(XENO_MATURE)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm
index 53e30d374b2c..8a7425e2071a 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm
@@ -413,17 +413,24 @@
if(queen_aged)
age_xeno()
switch(age)
- if(XENO_NORMAL) name = "[name_prefix]Queen" //Young
- if(XENO_MATURE) name = "[name_prefix]Elder Queen" //Mature
- if(XENO_ELDER) name = "[name_prefix]Elder Empress" //Elite
- if(XENO_ANCIENT) name = "[name_prefix]Ancient Empress" //Ancient
- if(XENO_PRIME) name = "[name_prefix]Prime Empress" //Primordial
+ if(XENO_YOUNG)
+ name = "[name_prefix]Young Queen" //Young
+ if(XENO_NORMAL)
+ name = "[name_prefix]Queen" //Regular
+ if(XENO_MATURE)
+ name = "[name_prefix]Elder Queen" //Mature
+ if(XENO_ELDER)
+ name = "[name_prefix]Elder Empress" //Elite
+ if(XENO_ANCIENT)
+ name = "[name_prefix]Ancient Empress" //Ancient
+ if(XENO_PRIME)
+ name = "[name_prefix]Prime Empress" //Primordial
else
age = XENO_NORMAL
if(client)
hud_update()
- name = "[name_prefix]Young Queen"
+ name = "[name_prefix]Immature Queen"
var/name_client_prefix = ""
var/name_client_postfix = ""
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 cfca16f70a51..c2bf91edde6e 100644
--- a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
@@ -317,6 +317,7 @@
XENO_STRUCTURE_EGGMORPH = 6,
XENO_STRUCTURE_EVOPOD = 2,
XENO_STRUCTURE_RECOVERY = 6,
+ XENO_STRUCTURE_PYLON = 2,
)
var/global/list/hive_structure_types = list(
@@ -370,17 +371,25 @@
if(hivenumber != XENO_HIVE_NORMAL)
return
- RegisterSignal(SSdcs, COMSIG_GLOB_POST_SETUP, PROC_REF(setup_evolution_announcements))
+ RegisterSignal(SSdcs, COMSIG_GLOB_POST_SETUP, PROC_REF(post_setup))
-/datum/hive_status/proc/setup_evolution_announcements()
+/datum/hive_status/proc/post_setup()
SIGNAL_HANDLER
+ setup_evolution_announcements()
+ setup_pylon_limits()
+
+/datum/hive_status/proc/setup_evolution_announcements()
for(var/time in GLOB.xeno_evolve_times)
if(time == "0")
continue
addtimer(CALLBACK(src, PROC_REF(announce_evolve_available), GLOB.xeno_evolve_times[time]), text2num(time))
+/// Sets up limits on pylons in New() for potential futureproofing with more static comms
+/datum/hive_status/proc/setup_pylon_limits()
+ hive_structures_limit[XENO_STRUCTURE_PYLON] = length(GLOB.all_static_telecomms_towers) || 2
+
/datum/hive_status/proc/announce_evolve_available(list/datum/caste_datum/available_castes)
var/list/castes_available = list()
@@ -883,6 +892,7 @@
for(var/obj/effect/alien/resin/special/S in hive_structures[name_ref])
if(get_area(S) == hijacked_dropship)
continue
+ S.hijack_delete = TRUE
hive_structures[name_ref] -= S
qdel(S)
for(var/mob/living/carbon/xenomorph/xeno as anything in totalXenos)
@@ -920,10 +930,14 @@
embryo.hivenumber = XENO_HIVE_FORSAKEN
potential_host.update_med_icon()
for(var/mob/living/carbon/human/current_human as anything in GLOB.alive_human_list)
- if((isspecieshuman(current_human) || isspeciessynth(current_human)) && current_human.job)
- var/turf/turf = get_turf(current_human)
- if(is_mainship_level(turf?.z))
- shipside_humans_weighted_count += RoleAuthority.calculate_role_weight(current_human.job)
+ if(!(isspecieshuman(current_human) || isspeciessynth(current_human)))
+ continue
+ var/datum/job/job = RoleAuthority.roles_for_mode[current_human.job]
+ if(!job)
+ continue
+ var/turf/turf = get_turf(current_human)
+ if(is_mainship_level(turf?.z))
+ shipside_humans_weighted_count += RoleAuthority.calculate_role_weight(job)
hijack_burrowed_surge = TRUE
hijack_burrowed_left = max(n_ceil(shipside_humans_weighted_count * 0.5) - xenos_count, 5)
hivecore_cooldown = FALSE
@@ -1122,6 +1136,10 @@
/datum/hive_status/proc/increase_larva_after_burst()
var/extra_per_burst = CONFIG_GET(number/extra_larva_per_burst)
partial_larva += extra_per_burst
+ convert_partial_larva_to_full_larva()
+
+///Called after times when partial larva are added to process them to stored larva
+/datum/hive_status/proc/convert_partial_larva_to_full_larva()
for(var/i = 1 to partial_larva)
partial_larva--
stored_larva++
@@ -1372,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]
@@ -1387,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/ammo_datums.dm b/code/modules/projectiles/ammo_datums.dm
index f97195d5ac32..d09c7ad7bb26 100644
--- a/code/modules/projectiles/ammo_datums.dm
+++ b/code/modules/projectiles/ammo_datums.dm
@@ -2367,32 +2367,7 @@
flags_ammo_behavior = AMMO_IGNORE_RESIST
damage = 55
-
-/datum/ammo/energy/yautja/rifle/blast
- name = "plasma shatterer"
- icon_state = "bluespace"
- damage_type = BURN
-
- shell_speed = AMMO_SPEED_TIER_4
- damage = 40
-
-/datum/ammo/energy/yautja/rifle/blast/on_hit_mob(mob/M, obj/item/projectile/P)
- var/L = get_turf(M)
- cell_explosion(L, 90, 30, EXPLOSION_FALLOFF_SHAPE_LINEAR, null, P.weapon_cause_data)
- ..()
-
-/datum/ammo/energy/yautja/rifle/blast/on_hit_turf(turf/T, obj/item/projectile/P)
- cell_explosion(T, 90, 30, EXPLOSION_FALLOFF_SHAPE_LINEAR, null, P.weapon_cause_data)
- ..()
-
-/datum/ammo/energy/yautja/rifle/blast/on_hit_obj(obj/O, obj/item/projectile/P)
- cell_explosion(get_turf(O), 100, 30, EXPLOSION_FALLOFF_SHAPE_LINEAR, null, P.weapon_cause_data)
- ..()
-
-/datum/ammo/energy/yautja/rifle/blast/do_at_max_range(obj/item/projectile/P)
- cell_explosion(get_turf(P), 100, 30, EXPLOSION_FALLOFF_SHAPE_LINEAR, null, P.weapon_cause_data)
- ..()
-
+ penetration = 50
/*
//======
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 7a2a5f85c5b3..832f243a9602 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -314,7 +314,7 @@
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
burst_scatter_mult = SCATTER_AMOUNT_TIER_7
- set_burst_amount(BURST_AMOUNT_TIER_5)
+ set_burst_amount(BURST_AMOUNT_TIER_1)
scatter_unwielded = SCATTER_AMOUNT_TIER_6
damage_mult = BASE_BULLET_DAMAGE_MULT
damage_falloff_mult = DAMAGE_FALLOFF_TIER_10
@@ -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]
@@ -705,7 +705,7 @@ As sniper rifles have both and weapon mods can change them as well. ..() deals w
data["recoil_max"] = RECOIL_AMOUNT_TIER_1
data["scatter_max"] = SCATTER_AMOUNT_TIER_1
- data["firerate_max"] = 1 MINUTES / FIRE_DELAY_TIER_10
+ data["firerate_max"] = 1 MINUTES / FIRE_DELAY_TIER_12
data["damage_max"] = 100
data["accuracy_max"] = 32
data["range_max"] = 32
@@ -1775,13 +1775,11 @@ not all weapons use normal magazines etc. load_into_chamber() itself is designed
/obj/item/weapon/gun/proc/set_burst_amount(value, mob/user)
burst_amount = value
SEND_SIGNAL(src, COMSIG_GUN_BURST_SHOTS_TO_FIRE_MODIFIED, burst_amount)
- setup_firemodes()
/// adder for burst_amount
/obj/item/weapon/gun/proc/modify_burst_amount(value, mob/user)
burst_amount += value
SEND_SIGNAL(src, COMSIG_GUN_BURST_SHOTS_TO_FIRE_MODIFIED, burst_amount)
- setup_firemodes()
/// Adder for burst_delay
/obj/item/weapon/gun/proc/modify_burst_delay(value, mob/user)
diff --git a/code/modules/projectiles/gun_attachables.dm b/code/modules/projectiles/gun_attachables.dm
index 2a77a6ba6a68..7d2dbf5288be 100644
--- a/code/modules/projectiles/gun_attachables.dm
+++ b/code/modules/projectiles/gun_attachables.dm
@@ -368,6 +368,7 @@ Defined in conflicts.dm of the #defines folder.
icon_state = "ebarrel"
attach_icon = "ebarrel_a"
hud_offset_mod = -3
+ wield_delay_mod = WIELD_DELAY_FAST
/obj/item/attachable/extended_barrel/New()
..()
@@ -387,7 +388,7 @@ Defined in conflicts.dm of the #defines folder.
..()
accuracy_mod = -HIT_ACCURACY_MULT_TIER_3
damage_mod = BULLET_DAMAGE_MULT_TIER_6
- delay_mod = FIRE_DELAY_TIER_9
+ delay_mod = FIRE_DELAY_TIER_11
accuracy_unwielded_mod = -HIT_ACCURACY_MULT_TIER_7
@@ -842,13 +843,13 @@ Defined in conflicts.dm of the #defines folder.
/obj/item/attachable/scope/New()
..()
- delay_mod = FIRE_DELAY_TIER_10
+ delay_mod = FIRE_DELAY_TIER_12
accuracy_mod = -HIT_ACCURACY_MULT_TIER_1
movement_onehanded_acc_penalty_mod = MOVEMENT_ACCURACY_PENALTY_MULT_TIER_4
accuracy_unwielded_mod = 0
accuracy_scoped_buff = HIT_ACCURACY_MULT_TIER_8 //to compensate initial debuff
- delay_scoped_nerf = FIRE_DELAY_TIER_9 //to compensate initial debuff. We want "high_fire_delay"
+ delay_scoped_nerf = FIRE_DELAY_TIER_11 //to compensate initial debuff. We want "high_fire_delay"
damage_falloff_scoped_buff = -0.4 //has to be negative
/obj/item/attachable/scope/proc/apply_scoped_buff(obj/item/weapon/gun/G, mob/living/carbon/user)
@@ -1007,7 +1008,7 @@ Defined in conflicts.dm of the #defines folder.
accuracy_unwielded_mod = 0
accuracy_scoped_buff = HIT_ACCURACY_MULT_TIER_8
- delay_scoped_nerf = FIRE_DELAY_TIER_8
+ delay_scoped_nerf = FIRE_DELAY_TIER_9
/obj/item/attachable/scope/mini/hunting
name = "2x hunting mini-scope"
@@ -1530,7 +1531,7 @@ Defined in conflicts.dm of the #defines folder.
scatter_mod = -SCATTER_AMOUNT_TIER_7
burst_scatter_mod = -1
burst_mod = BURST_AMOUNT_TIER_2
- delay_mod = -FIRE_DELAY_TIER_9
+ delay_mod = -FIRE_DELAY_TIER_11
movement_onehanded_acc_penalty_mod = -MOVEMENT_ACCURACY_PENALTY_MULT_TIER_4
//1h
accuracy_unwielded_mod = HIT_ACCURACY_MULT_TIER_1
@@ -2522,10 +2523,9 @@ Defined in conflicts.dm of the #defines folder.
accuracy_unwielded_mod = -HIT_ACCURACY_MULT_TIER_3
scatter_unwielded_mod = SCATTER_AMOUNT_TIER_10
-
/obj/item/attachable/angledgrip
name = "angled grip"
- desc = "An angled foregrip that improves weapon ergonomics and offers less recoil, and faster wielding time. \nHowever, it also increases weapon size."
+ desc = "An angled foregrip that improves weapon ergonomics resulting in faster wielding time. \nHowever, it also increases weapon size."
icon = 'icons/obj/items/weapons/guns/attachments/under.dmi'
icon_state = "angledgrip"
attach_icon = "angledgrip_a"
@@ -2534,16 +2534,6 @@ Defined in conflicts.dm of the #defines folder.
slot = "under"
pixel_shift_x = 20
-/obj/item/attachable/angledgrip/New()
- ..()
- recoil_mod = -RECOIL_AMOUNT_TIER_4
- accuracy_mod = HIT_ACCURACY_MULT_TIER_1
- accuracy_unwielded_mod = -HIT_ACCURACY_MULT_TIER_1
- scatter_mod = -SCATTER_AMOUNT_TIER_10
- scatter_unwielded_mod = SCATTER_AMOUNT_TIER_10
-
-
-
/obj/item/attachable/gyro
name = "gyroscopic stabilizer"
desc = "A set of weights and balances to stabilize the weapon when fired with one hand. Slightly decreases firing speed."
@@ -2554,7 +2544,7 @@ Defined in conflicts.dm of the #defines folder.
/obj/item/attachable/gyro/New()
..()
- delay_mod = FIRE_DELAY_TIER_9
+ delay_mod = FIRE_DELAY_TIER_11
scatter_mod = -SCATTER_AMOUNT_TIER_10
burst_scatter_mod = -2
movement_onehanded_acc_penalty_mod = -MOVEMENT_ACCURACY_PENALTY_MULT_TIER_3
@@ -2606,7 +2596,7 @@ Defined in conflicts.dm of the #defines folder.
/obj/item/attachable/bipod/New()
..()
- delay_mod = FIRE_DELAY_TIER_9
+ delay_mod = FIRE_DELAY_TIER_11
wield_delay_mod = WIELD_DELAY_FAST
accuracy_mod = -HIT_ACCURACY_MULT_TIER_5
scatter_mod = SCATTER_AMOUNT_TIER_9
@@ -2654,7 +2644,7 @@ Defined in conflicts.dm of the #defines folder.
scatter_mod = SCATTER_AMOUNT_TIER_9
recoil_mod = RECOIL_AMOUNT_TIER_5
burst_scatter_mod = 0
- delay_mod = FIRE_DELAY_TIER_10
+ delay_mod = FIRE_DELAY_TIER_12
G.recalculate_attachment_bonuses()
var/mob/living/user
if(isliving(G.loc))
@@ -2691,7 +2681,7 @@ Defined in conflicts.dm of the #defines folder.
if(istype(G,/obj/item/weapon/gun/rifle/sniper/M42A))
delay_mod = -FIRE_DELAY_TIER_7
else
- delay_mod = -FIRE_DELAY_TIER_10
+ delay_mod = -FIRE_DELAY_TIER_12
G.recalculate_attachment_bonuses()
initial_mob_dir = user.dir
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 25efbd420ec6..61ea0442a427 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -133,7 +133,7 @@
/obj/item/weapon/gun/energy/rxfm5_eva/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_8)
+ set_fire_delay(FIRE_DELAY_TIER_9)
accuracy_mult = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_3
scatter = SCATTER_AMOUNT_TIER_7
damage_mult = BASE_BULLET_DAMAGE_MULT
diff --git a/code/modules/projectiles/guns/flamer/flamer.dm b/code/modules/projectiles/guns/flamer/flamer.dm
index f327a92ffc9c..a108b3a9948f 100644
--- a/code/modules/projectiles/guns/flamer/flamer.dm
+++ b/code/modules/projectiles/guns/flamer/flamer.dm
@@ -51,7 +51,7 @@
/obj/item/weapon/gun/flamer/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_4 * 5)
+ set_fire_delay(FIRE_DELAY_TIER_5 * 5)
/obj/item/weapon/gun/flamer/unique_action(mob/user)
toggle_gun_safety()
diff --git a/code/modules/projectiles/guns/lever_action.dm b/code/modules/projectiles/guns/lever_action.dm
index 986f42716e64..73d9330e2a53 100644
--- a/code/modules/projectiles/guns/lever_action.dm
+++ b/code/modules/projectiles/guns/lever_action.dm
@@ -45,7 +45,7 @@ their unique feature is that a direct hit will buff your damage and firerate
/obj/item/weapon/gun/lever_action/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_1 + FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_1 + FIRE_DELAY_TIER_12)
lever_delay = FIRE_DELAY_TIER_3
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_10
@@ -116,7 +116,7 @@ their unique feature is that a direct hit will buff your damage and firerate
lever_sound = lever_super_sound
lever_message = "You quickly work the [lever_name]!"
last_fired = world.time - buff_fire_reduc //to shoot the next round faster
- lever_delay = FIRE_DELAY_TIER_10
+ lever_delay = FIRE_DELAY_TIER_12
damage_mult = initial(damage_mult) + BULLET_DAMAGE_MULT_TIER_10
set_fire_delay(FIRE_DELAY_TIER_5)
for(var/slot in attachments)
@@ -392,7 +392,7 @@ their unique feature is that a direct hit will buff your damage and firerate
/obj/item/weapon/gun/lever_action/xm88/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_1)
+ set_fire_delay(FIRE_DELAY_TIER_2)
lever_delay = FIRE_DELAY_TIER_3
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_10
@@ -529,7 +529,7 @@ their unique feature is that a direct hit will buff your damage and firerate
P.ammo = GLOB.ammo_list[/datum/ammo/bullet/lever_action/xm88]
floating_penetration = FLOATING_PENETRATION_TIER_0
//these are init configs and so cannot be initial()
- set_fire_delay(FIRE_DELAY_TIER_1 + FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_1 + FIRE_DELAY_TIER_12)
lever_delay = FIRE_DELAY_TIER_3
damage_mult = BASE_BULLET_DAMAGE_MULT
recalculate_attachment_bonuses() //stock wield delay
diff --git a/code/modules/projectiles/guns/misc.dm b/code/modules/projectiles/guns/misc.dm
index 2aa6b2dfc4d3..373587ff881a 100644
--- a/code/modules/projectiles/guns/misc.dm
+++ b/code/modules/projectiles/guns/misc.dm
@@ -24,7 +24,7 @@
/obj/item/weapon/gun/minigun/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_3
@@ -100,9 +100,9 @@
/obj/item/weapon/gun/m60/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
set_burst_amount(BURST_AMOUNT_TIER_5)
- set_burst_delay(FIRE_DELAY_TIER_10)
+ set_burst_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_10
diff --git a/code/modules/projectiles/guns/pistols.dm b/code/modules/projectiles/guns/pistols.dm
index 47b80f7b9218..e2985df6a12a 100644
--- a/code/modules/projectiles/guns/pistols.dm
+++ b/code/modules/projectiles/guns/pistols.dm
@@ -72,7 +72,7 @@
/obj/item/weapon/gun/pistol/m4a3/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
@@ -93,7 +93,7 @@
/obj/item/weapon/gun/pistol/m4a3/custom/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
@@ -122,7 +122,7 @@
/obj/item/weapon/gun/pistol/m1911/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_8)
+ set_fire_delay(FIRE_DELAY_TIER_9)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
@@ -140,7 +140,7 @@
/obj/item/weapon/gun/pistol/m1911/socom/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_8)
+ set_fire_delay(FIRE_DELAY_TIER_9)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
accuracy_mult_unwielded = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_2
scatter = SCATTER_AMOUNT_TIER_8
@@ -178,7 +178,7 @@
/obj/item/weapon/gun/pistol/b92fs/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_7
@@ -218,9 +218,9 @@
/obj/item/weapon/gun/pistol/heavy/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_4)
+ set_fire_delay(FIRE_DELAY_TIER_5)
set_burst_amount(BURST_AMOUNT_TIER_2)
- set_burst_delay(FIRE_DELAY_TIER_7)
+ set_burst_delay(FIRE_DELAY_TIER_8)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_5
scatter = SCATTER_AMOUNT_TIER_6
@@ -285,7 +285,7 @@
/obj/item/weapon/gun/pistol/c99/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
accuracy_mult_unwielded = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
scatter = SCATTER_AMOUNT_TIER_6
@@ -337,7 +337,7 @@
/obj/item/weapon/gun/pistol/kt42/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_1
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_2
scatter = SCATTER_AMOUNT_TIER_6
@@ -373,7 +373,7 @@
/obj/item/weapon/gun/pistol/holdout/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
@@ -410,7 +410,7 @@
/obj/item/weapon/gun/pistol/clfpistol/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
@@ -552,9 +552,9 @@
/obj/item/weapon/gun/pistol/mod88/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
set_burst_amount(BURST_AMOUNT_TIER_3)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_7
@@ -603,7 +603,7 @@
/obj/item/weapon/gun/pistol/es4/set_gun_config_values()
..()
- fire_delay = FIRE_DELAY_TIER_9
+ fire_delay = FIRE_DELAY_TIER_11
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_7
@@ -653,7 +653,7 @@
..()
set_fire_delay(FIRE_DELAY_TIER_4)
set_burst_amount(BURST_AMOUNT_TIER_3)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
@@ -685,7 +685,7 @@ It is a modified Beretta 93R, and can fire three-round burst or single fire. Whe
..()
set_fire_delay(FIRE_DELAY_TIER_7)
set_burst_amount(BURST_AMOUNT_TIER_3)
- set_burst_delay(FIRE_DELAY_TIER_10)
+ set_burst_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
@@ -715,8 +715,8 @@ It is a modified Beretta 93R, and can fire three-round burst or single fire. Whe
/obj/item/weapon/gun/pistol/chimp/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_8)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
set_burst_amount(BURST_AMOUNT_TIER_2)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT
@@ -747,9 +747,9 @@ It is a modified Beretta 93R, and can fire three-round burst or single fire. Whe
/obj/item/weapon/gun/pistol/smart/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
set_burst_amount(BURST_AMOUNT_TIER_3)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
@@ -796,7 +796,7 @@ It is a modified Beretta 93R, and can fire three-round burst or single fire. Whe
/obj/item/weapon/gun/pistol/skorpion/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
fa_scatter_peak = 15 //shots
fa_max_scatter = SCATTER_AMOUNT_TIER_4
diff --git a/code/modules/projectiles/guns/revolvers.dm b/code/modules/projectiles/guns/revolvers.dm
index 022a8cabd349..7a8782f34d7d 100644
--- a/code/modules/projectiles/guns/revolvers.dm
+++ b/code/modules/projectiles/guns/revolvers.dm
@@ -375,7 +375,7 @@
..()
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_2
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
/obj/item/weapon/gun/revolver/m44/custom/pkd_special/k2049
name = "\improper M2049 Blaster"
@@ -414,9 +414,9 @@
..()
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_2
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
set_burst_amount(BURST_AMOUNT_TIER_2)
- set_burst_delay(FIRE_DELAY_TIER_10)
+ set_burst_delay(FIRE_DELAY_TIER_12)
/obj/item/weapon/gun/revolver/m44/custom/webley //Van Bandolier's Webley.
@@ -469,7 +469,7 @@
/obj/item/weapon/gun/revolver/nagant/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_8)
+ set_fire_delay(FIRE_DELAY_TIER_9)
accuracy_mult = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_6
damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_1
@@ -596,9 +596,9 @@
/obj/item/weapon/gun/revolver/mateba/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_2)
+ set_fire_delay(FIRE_DELAY_TIER_3)
set_burst_amount(BURST_AMOUNT_TIER_3)
- set_burst_delay(FIRE_DELAY_TIER_7)
+ set_burst_delay(FIRE_DELAY_TIER_8)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_2
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_5
scatter = SCATTER_AMOUNT_TIER_7
diff --git a/code/modules/projectiles/guns/rifles.dm b/code/modules/projectiles/guns/rifles.dm
index 09a0e2b683cf..18ffb082217c 100644
--- a/code/modules/projectiles/guns/rifles.dm
+++ b/code/modules/projectiles/guns/rifles.dm
@@ -20,7 +20,7 @@
..()
set_fire_delay(FIRE_DELAY_TIER_5)
set_burst_amount(BURST_AMOUNT_TIER_3)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_7
scatter = SCATTER_AMOUNT_TIER_6
@@ -82,9 +82,9 @@
/obj/item/weapon/gun/rifle/m41a/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
set_burst_amount(BURST_AMOUNT_TIER_3)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4 + 2*HIT_ACCURACY_MULT_TIER_1
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_7
scatter = SCATTER_AMOUNT_TIER_8
@@ -162,7 +162,7 @@
..()
set_fire_delay(FIRE_DELAY_TIER_7)
set_burst_amount(BURST_AMOUNT_TIER_3)
- set_burst_delay(FIRE_DELAY_TIER_8)
+ set_burst_delay(FIRE_DELAY_TIER_9)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_10
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_7
scatter = SCATTER_AMOUNT_TIER_9
@@ -232,9 +232,9 @@
/obj/item/weapon/gun/rifle/m41a/elite/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
set_burst_amount(BURST_AMOUNT_TIER_2)
- set_burst_delay(FIRE_DELAY_TIER_10)
+ set_burst_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_10
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_4
scatter = SCATTER_AMOUNT_TIER_10
@@ -346,9 +346,9 @@
/obj/item/weapon/gun/rifle/m41a/elite/xm40/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
set_burst_amount(BURST_AMOUNT_TIER_3)
- set_burst_delay(FIRE_DELAY_TIER_10)
+ set_burst_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_10
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_4
scatter = SCATTER_AMOUNT_TIER_10
@@ -390,9 +390,9 @@
/obj/item/weapon/gun/rifle/m41aMK1/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
set_burst_amount(BURST_AMOUNT_TIER_4)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_3
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_7
scatter = SCATTER_AMOUNT_TIER_9
@@ -518,9 +518,9 @@
/obj/item/weapon/gun/rifle/m46c/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_8)
+ set_fire_delay(FIRE_DELAY_TIER_9)
set_burst_amount(BURST_AMOUNT_TIER_4)
- set_burst_delay(FIRE_DELAY_TIER_10)
+ set_burst_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_8
scatter = SCATTER_AMOUNT_TIER_8
@@ -631,7 +631,7 @@
/obj/item/weapon/gun/rifle/m46c/recalculate_attachment_bonuses()
. = ..()
if(iff_enabled)
- modify_fire_delay(FIRE_DELAY_TIER_10)
+ modify_fire_delay(FIRE_DELAY_TIER_12)
remove_firemode(GUN_FIREMODE_BURSTFIRE)
else
@@ -730,7 +730,7 @@
..()
set_fire_delay(FIRE_DELAY_TIER_7)
set_burst_amount(BURST_AMOUNT_TIER_4)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_7
scatter = SCATTER_AMOUNT_TIER_6
@@ -801,7 +801,7 @@
/obj/item/weapon/gun/rifle/mar40/carbine/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_8)
+ set_fire_delay(FIRE_DELAY_TIER_9)
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_4
damage_mult = BASE_BULLET_DAMAGE_MULT - BULLET_DAMAGE_MULT_TIER_2
scatter_unwielded = SCATTER_AMOUNT_TIER_4
@@ -847,9 +847,9 @@
/obj/item/weapon/gun/rifle/mar40/lmg/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_8)
+ set_fire_delay(FIRE_DELAY_TIER_9)
set_burst_amount(BURST_AMOUNT_TIER_5)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_7
scatter = SCATTER_AMOUNT_TIER_6
@@ -940,9 +940,9 @@
/obj/item/weapon/gun/rifle/m16/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
set_burst_amount(BURST_AMOUNT_TIER_3)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_7
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_7
scatter = SCATTER_AMOUNT_TIER_10
@@ -1303,9 +1303,9 @@
/obj/item/weapon/gun/rifle/type71/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
set_burst_amount(BURST_AMOUNT_TIER_4)
- set_burst_delay(FIRE_DELAY_TIER_8)
+ set_burst_delay(FIRE_DELAY_TIER_9)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_7
scatter = SCATTER_AMOUNT_TIER_6
@@ -1418,7 +1418,7 @@
/obj/item/weapon/gun/rifle/type71/carbine/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
damage_mult = BASE_BULLET_DAMAGE_MULT - BULLET_DAMAGE_MULT_TIER_2
scatter_unwielded = SCATTER_AMOUNT_TIER_5
recoil_unwielded = RECOIL_AMOUNT_TIER_4
@@ -1483,8 +1483,8 @@
..()
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_7
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_4
- set_fire_delay(FIRE_DELAY_TIER_9)
- set_burst_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_11)
+ set_burst_delay(FIRE_DELAY_TIER_12)
scatter = SCATTER_AMOUNT_TIER_8
//-------------------------------------------------------
@@ -1530,7 +1530,7 @@
/obj/item/weapon/gun/rifle/m4ra/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_8)
+ set_fire_delay(FIRE_DELAY_TIER_9)
set_burst_amount(0)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_4
@@ -1594,7 +1594,7 @@
/obj/item/weapon/gun/rifle/l42a/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_8)
+ set_fire_delay(FIRE_DELAY_TIER_9)
set_burst_amount(0)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_4
diff --git a/code/modules/projectiles/guns/shotguns.dm b/code/modules/projectiles/guns/shotguns.dm
index 8903be95db95..a154062c9d10 100644
--- a/code/modules/projectiles/guns/shotguns.dm
+++ b/code/modules/projectiles/guns/shotguns.dm
@@ -201,7 +201,7 @@ can cause issues with ammo types getting mixed up during the burst.
..()
set_fire_delay(FIRE_DELAY_TIER_6*2)
set_burst_amount(BURST_AMOUNT_TIER_2)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_4
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_10
scatter = SCATTER_AMOUNT_TIER_6
@@ -522,7 +522,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/double/set_gun_config_values()
..()
set_burst_amount(BURST_AMOUNT_TIER_2)
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_3
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_10
scatter = SCATTER_AMOUNT_TIER_6
@@ -655,7 +655,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/double/sawn/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_3 - HIT_ACCURACY_MULT_TIER_5
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_10
scatter = SCATTER_AMOUNT_TIER_6
@@ -789,7 +789,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/double/mou53/set_gun_config_values()
..()
set_burst_amount(BURST_AMOUNT_TIER_1)
- set_fire_delay(FIRE_DELAY_TIER_8)
+ set_fire_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_10
scatter = SCATTER_AMOUNT_TIER_10
@@ -1101,7 +1101,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/pump/Initialize(mapload, spawn_empty)
. = ..()
- pump_delay = FIRE_DELAY_TIER_4*2
+ pump_delay = FIRE_DELAY_TIER_5*2
additional_fire_group_delay += pump_delay
@@ -1112,7 +1112,7 @@ can cause issues with ammo types getting mixed up during the burst.
/obj/item/weapon/gun/shotgun/pump/set_gun_config_values()
..()
set_burst_amount(BURST_AMOUNT_TIER_1)
- set_fire_delay(FIRE_DELAY_TIER_7 * 5)
+ set_fire_delay(FIRE_DELAY_TIER_7 * 4)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_3
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_10
scatter = SCATTER_AMOUNT_TIER_6
diff --git a/code/modules/projectiles/guns/smartgun.dm b/code/modules/projectiles/guns/smartgun.dm
index 859f99b17908..2a88c9766ed8 100644
--- a/code/modules/projectiles/guns/smartgun.dm
+++ b/code/modules/projectiles/guns/smartgun.dm
@@ -687,11 +687,11 @@
/obj/item/weapon/gun/smartgun/dirty/elite/set_gun_config_values()
..()
set_burst_amount(BURST_AMOUNT_TIER_5)
- set_burst_delay(FIRE_DELAY_TIER_10)
+ set_burst_delay(FIRE_DELAY_TIER_12)
if(!recoil_compensation)
scatter = SCATTER_AMOUNT_TIER_8
burst_scatter_mult = SCATTER_AMOUNT_TIER_10
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
fa_scatter_peak = FULL_AUTO_SCATTER_PEAK_TIER_10
fa_max_scatter = SCATTER_AMOUNT_NONE
diff --git a/code/modules/projectiles/guns/smgs.dm b/code/modules/projectiles/guns/smgs.dm
index 699f05ed318c..70b0acb3f2c8 100644
--- a/code/modules/projectiles/guns/smgs.dm
+++ b/code/modules/projectiles/guns/smgs.dm
@@ -176,7 +176,7 @@
/obj/item/weapon/gun/smg/mp5/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
set_burst_delay(FIRE_DELAY_TIER_SMG)
set_burst_amount(BURST_AMOUNT_TIER_3)
@@ -371,7 +371,7 @@
fa_scatter_peak = FULL_AUTO_SCATTER_PEAK_TIER_7
fa_max_scatter = SCATTER_AMOUNT_TIER_3
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_5
burst_scatter_mult = SCATTER_AMOUNT_TIER_8
@@ -421,7 +421,7 @@
fa_scatter_peak = FULL_AUTO_SCATTER_PEAK_TIER_5
fa_max_scatter = SCATTER_AMOUNT_TIER_5
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_2
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_2
scatter = SCATTER_AMOUNT_TIER_6
@@ -572,7 +572,7 @@
/obj/item/weapon/gun/smg/nailgun/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_9)
+ set_fire_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5
accuracy_mult_unwielded = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_4
diff --git a/code/modules/projectiles/guns/specialist.dm b/code/modules/projectiles/guns/specialist.dm
index 66456f4e21fc..184c0ed38266 100644
--- a/code/modules/projectiles/guns/specialist.dm
+++ b/code/modules/projectiles/guns/specialist.dm
@@ -321,7 +321,7 @@
/obj/item/weapon/gun/rifle/sniper/M42A/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_6*3)
+ set_fire_delay(FIRE_DELAY_TIER_7*3)
set_burst_amount(BURST_AMOUNT_TIER_1)
accuracy_mult = BASE_ACCURACY_MULT * 3 //you HAVE to be able to hit
scatter = SCATTER_AMOUNT_TIER_8
@@ -509,7 +509,7 @@
..()
set_fire_delay(FIRE_DELAY_TIER_6)
set_burst_amount(BURST_AMOUNT_TIER_2)
- set_burst_delay(FIRE_DELAY_TIER_9)
+ set_burst_delay(FIRE_DELAY_TIER_11)
accuracy_mult = BASE_ACCURACY_MULT
scatter = SCATTER_AMOUNT_TIER_8
burst_scatter_mult = SCATTER_AMOUNT_TIER_6
@@ -586,7 +586,7 @@
..()
set_fire_delay(FIRE_DELAY_TIER_6)
set_burst_amount(BURST_AMOUNT_TIER_2)
- set_burst_delay(FIRE_DELAY_TIER_10)
+ set_burst_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_2
scatter = SCATTER_AMOUNT_TIER_8
burst_scatter_mult = SCATTER_AMOUNT_TIER_8
@@ -1373,7 +1373,7 @@
/obj/item/weapon/gun/flare/set_gun_config_values()
..()
- set_fire_delay(FIRE_DELAY_TIER_10)
+ set_fire_delay(FIRE_DELAY_TIER_12)
accuracy_mult = BASE_ACCURACY_MULT
accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_10
scatter = 0
diff --git a/code/modules/shuttle/shuttles/escape_shuttle.dm b/code/modules/shuttle/shuttles/escape_shuttle.dm
index 859aa45aceb3..daf91034036f 100644
--- a/code/modules/shuttle/shuttles/escape_shuttle.dm
+++ b/code/modules/shuttle/shuttles/escape_shuttle.dm
@@ -8,9 +8,12 @@
rechargeTime = SHUTTLE_RECHARGE
ignitionTime = 8 SECONDS
ignition_sound = 'sound/effects/escape_pod_warmup.ogg'
- /// The % chance of the escape pod crashing into the groundmap
+ /// The % chance of the escape pod crashing into the groundmap before lifeboats leaving
var/early_crash_land_chance = 75
+ /// The % chance of the escape pod crashing into the groundmap
var/crash_land_chance = 25
+ /// How many people can be in the escape pod before it crashes
+ var/max_capacity = 3
var/datum/door_controller/single/door_handler = new()
var/launched = FALSE
@@ -71,7 +74,7 @@
occupant_count++
for(var/obj/structure/machinery/cryopod/evacuation/cryotube in interior_area)
cryos += list(cryotube)
- if (occupant_count > 3)
+ if (occupant_count > max_capacity)
playsound(src,'sound/effects/escape_pod_warmup.ogg', 50, 1)
sleep(31)
var/turf/sploded = return_center_turf()
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/colonialmarines.dme b/colonialmarines.dme
index 11c35963edf9..42e7880bd313 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -1400,6 +1400,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/html/changelogs/AutoChangeLog-pr-4046.yml b/html/changelogs/AutoChangeLog-pr-4046.yml
new file mode 100644
index 000000000000..107125c48f4c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4046.yml
@@ -0,0 +1,8 @@
+author: "realforest2001"
+delete-after: True
+changes:
+ - 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."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4053.yml b/html/changelogs/AutoChangeLog-pr-4053.yml
new file mode 100644
index 000000000000..2c2e7a49db90
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4053.yml
@@ -0,0 +1,6 @@
+author: "ihatethisengine"
+delete-after: True
+changes:
+ - 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"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4073.yml b/html/changelogs/AutoChangeLog-pr-4073.yml
new file mode 100644
index 000000000000..aca9a327dd6c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4073.yml
@@ -0,0 +1,4 @@
+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-4081.yml b/html/changelogs/AutoChangeLog-pr-4081.yml
deleted file mode 100644
index dc975f1d7581..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4081.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Morrow, Thwomper"
-delete-after: True
-changes:
- - rscadd: "Added Auxiliary Support Officer"
- - rscadd: "Auxiliary Support Officer oversees the hangar, the intel team, the engineering department, and the requisitions department"
- - rscadd: "Chief Engineer has been demoted to O1."
- - rscadd: "Requisitions Officer is now \"Quartermaster\" and a Gunnery Sergeant."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4107.yml b/html/changelogs/AutoChangeLog-pr-4107.yml
new file mode 100644
index 000000000000..0fc0fe05b335
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4107.yml
@@ -0,0 +1,4 @@
+author: "mothblocks, harry"
+delete-after: True
+changes:
+ - rscadd: "added the backend functionality for autowiki, alongside automating much of the work of maintaining guns on the wiki"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4115.yml b/html/changelogs/AutoChangeLog-pr-4115.yml
deleted file mode 100644
index 8ef7e87aa024..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4115.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Segrain"
-delete-after: True
-changes:
- - bugfix: "Non-UPP synthetics no longer default to speaking Russian."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4118.yml b/html/changelogs/AutoChangeLog-pr-4118.yml
deleted file mode 100644
index 39204c7f29c3..000000000000
--- a/html/changelogs/AutoChangeLog-pr-4118.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "HeresKozmos"
-delete-after: True
-changes:
- - maptweak: "Added non-alcoholic drinks dispenser, space cleaner bottle and a regular medkit to the storage closet. Deleted old toxin medkit in the storage closet"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4162.yml b/html/changelogs/AutoChangeLog-pr-4162.yml
new file mode 100644
index 000000000000..11cc4dbed96e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4162.yml
@@ -0,0 +1,4 @@
+author: "realforest2001"
+delete-after: True
+changes:
+ - bugfix: "Squad Specialists can no longer bypass restrictions by not selecting a kit to use."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-4166.yml b/html/changelogs/AutoChangeLog-pr-4166.yml
new file mode 100644
index 000000000000..b62ce734be1f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-4166.yml
@@ -0,0 +1,4 @@
+author: "Morrow"
+delete-after: True
+changes:
+ - rscadd: "At end of round it now shows a Queen's prefix/postfix rather than their ckey"
\ No newline at end of file
diff --git a/html/changelogs/archive/2023-08.yml b/html/changelogs/archive/2023-08.yml
index 87ac33e88c1f..7908913b8d9d 100644
--- a/html/changelogs/archive/2023-08.yml
+++ b/html/changelogs/archive/2023-08.yml
@@ -96,3 +96,100 @@
2023-08-07:
Huffie56:
- maptweak: changing an area so it stop snowing inside walls.
+2023-08-08:
+ HeresKozmos:
+ - maptweak: Added non-alcoholic drinks dispenser, space cleaner bottle and a regular
+ medkit to the storage closet. Deleted old toxin medkit in the storage closet
+ Morrow, Thwomper:
+ - rscadd: Added Auxiliary Support Officer
+ - rscadd: Auxiliary Support Officer oversees the hangar, the intel team, the engineering
+ department, and the requisitions department
+ - rscadd: Chief Engineer has been demoted to O1.
+ - rscadd: Requisitions Officer is now "Quartermaster" and a Gunnery Sergeant.
+ Segrain:
+ - bugfix: Non-UPP synthetics no longer default to speaking Russian.
+2023-08-09:
+ BeagleGaming1:
+ - code_imp: occupant limit of evacuation pods changed to a variable
+ Drathek:
+ - bugfix: Fix new map dropship areas not getting changes to dropship ceilings that
+ prevents OBs
+ Megastar1234:
+ - rscadd: Adds reagent scanner goggles to CMO vendor
+ - rscadd: Gives CMO headset intel radio
+ Morrow:
+ - rscadd: Scan health now only works when non-revivable
+ - rscadd: Xenos with less than 10 hours on xeno now have the "Young" prefix
+ - rscadd: Young Queen has been renamed to Growing Queen
+ - balance: Removed the barrel charger from vendors
+ - balance: Removed all benefits other than wield delay mod from the angled grip
+ - balance: Added wield delay to extended barrel
+ Morrow, Sleepynecrons (beautiful sprites):
+ - rscadd: Xenos can now capture comms relays for bonuses after 90 minutes into the
+ round.
+ Steelpoint:
+ - balance: Yautja's Plasma Rifle has been rebalanced to make it a more effective
+ assault weapon against xenomorphs. It has lost its mini-high explosive fire
+ mode but its default fire mode now mostly ignores xenomorph armor.
+ blackdragonTOW:
+ - ui: Hardcore deaths are now marked with a unique red skull
+ - imageadd: Red skull added for hardcore deaths
+ morrowwolf:
+ - rscadd: Added basic IB surgery instructions to surgical case
+ realforest2001:
+ - rscadd: Changed 'Growing Queen' to 'Immature Queen'
+ - bugfix: Updated playerpanel transform Queen button title.
+ thwomper, Steelpoint:
+ - rscadd: Toolkits have been added to the game. Holds engineering supplies akin
+ to a medkit. Issued freely to ComTechs and Engineers, can be bought by the USCM
+ Synthetic for cheap.
+2023-08-10:
+ Drathek:
+ - bugfix: Fixed unnested mobs sometimes having incorrect density allowing xenos
+ to push them
+ Huffie56:
+ - rscadd: Add a skill check to operate IV.
+ - bugfix: Fix remove iv needing power to operate.
+ - rscadd: Update the MP and Warden vendor to fallow more the standard of the rifleman
+ vendor.
+ - rscadd: change the selection of the handgun from a full belt to a handgun case(3magazin,one
+ railgunlight and the gun.).
+ Morrow:
+ - balance: 'Across the board firerate nerfs with the exceptions of: M37 shotgun,
+ M240 Flamer, M42A Scope Rifle, XM88, Mateba, Desert Eagle'
+ - balance: Folded etools are now small items
+ Steelpoint:
+ - rscadd: The SMG belt has been changed. It now holds a SMG plus two extra magazines,
+ plus it can fit in either the belt or armour slot.
+ Tallfission:
+ - rscadd: Vehicles skill for Commanding Officer, Executive Officer, and Auxiliary
+ Support Officer jobs
+ Zonespace27:
+ - rscadd: Combisticks now use a proper chain instead of an invisible magic one.
+2023-08-11:
+ Drathek:
+ - bugfix: Fixed runtimes with hijack not calculating roles correctly for hijack
+ larva surge
+ - bugfix: Fix IV Drip machines not displaying the IV line correctly when adding/removing
+ a bag when already attached
+ - code_imp: Fixes a lingering reference to the mob when a IV drip machine is destroyed.
+ Zonespace27:
+ - bugfix: A pile of guns no longer have burst fire (who weren't meant to)
+ - bugfix: The combichain can now be yanked back if droppeed.
+2023-08-12:
+ BeagleGaming1:
+ - balance: Defibrillators are guaranteed to deal heart damage on successful revives
+ - balance: Blood volume now scales with heart damage rather than being a hardcoded
+ multiplier
+ - balance: Blood volume oxyloss now scales rather than being a hardcoded loss amount
+ Huffie56:
+ - code_imp: added welding google to the com tech tool vendor.
+ - code_imp: added scaling based on round population to the ColMarTech Surplus Uniform
+ like the other vendors.
+ - code_imp: Move every clothing items from ColMarTech Automated Armaments Squad
+ Vendor to ColMarTech Surplus Uniform Vendor.
+ - code_imp: rename ColMarTech Automated Armaments Squad Vendor to ColMarTech Automated
+ Utilities Squad Vendor and add in tools food and other utilities.
+ Steelpoint:
+ - bugfix: Synthetic Breaching Hammer will now properly appear on the user's back
+ when holstered.
diff --git a/icons/mob/hud/hud.dmi b/icons/mob/hud/hud.dmi
index f8ea98d01e53..c9e4c0c6c23d 100644
Binary files a/icons/mob/hud/hud.dmi and b/icons/mob/hud/hud.dmi differ
diff --git a/icons/mob/humans/onmob/back.dmi b/icons/mob/humans/onmob/back.dmi
index 4689fd35ab50..969016a4a4e5 100644
Binary files a/icons/mob/humans/onmob/back.dmi and b/icons/mob/humans/onmob/back.dmi differ
diff --git a/icons/mob/humans/onmob/hunter/items_lefthand.dmi b/icons/mob/humans/onmob/hunter/items_lefthand.dmi
index f3379c469113..91aa364340cb 100644
Binary files a/icons/mob/humans/onmob/hunter/items_lefthand.dmi and b/icons/mob/humans/onmob/hunter/items_lefthand.dmi differ
diff --git a/icons/mob/humans/onmob/hunter/items_righthand.dmi b/icons/mob/humans/onmob/hunter/items_righthand.dmi
index fbca4cfed5bb..8ec0871464c5 100644
Binary files a/icons/mob/humans/onmob/hunter/items_righthand.dmi and b/icons/mob/humans/onmob/hunter/items_righthand.dmi differ
diff --git a/icons/obj/items/clothing/belts.dmi b/icons/obj/items/clothing/belts.dmi
index 381dcbe9687a..e561b5f84548 100644
Binary files a/icons/obj/items/clothing/belts.dmi and b/icons/obj/items/clothing/belts.dmi differ
diff --git a/icons/obj/items/storage.dmi b/icons/obj/items/storage.dmi
index 2d0c1f5928df..310bee26b9e9 100644
Binary files a/icons/obj/items/storage.dmi and b/icons/obj/items/storage.dmi differ
diff --git a/icons/obj/structures/machinery/comm_tower3.dmi b/icons/obj/structures/machinery/comm_tower3.dmi
index 931d6f77514a..8a5aa1f68fe3 100644
Binary files a/icons/obj/structures/machinery/comm_tower3.dmi and b/icons/obj/structures/machinery/comm_tower3.dmi differ
diff --git a/maps/map_files/New_Varadero/New_Varadero.dmm b/maps/map_files/New_Varadero/New_Varadero.dmm
index 20558b48ac32..4488d13b9bc7 100644
--- a/maps/map_files/New_Varadero/New_Varadero.dmm
+++ b/maps/map_files/New_Varadero/New_Varadero.dmm
@@ -2832,7 +2832,6 @@
/obj/structure/surface/table/reinforced/prison{
color = "#6b675e"
},
-/obj/item/attachable/heavy_barrel,
/obj/structure/window/reinforced,
/turf/open/floor/strata{
color = "#5e5d5d";
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"
+ }
+}