diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index dc8e9e1859..e9f759fd42 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -484,6 +484,8 @@
/datum/config_entry/flag/modetier_voting
+/datum/config_entry/flag/must_be_readied_to_vote_gamemode
+
/datum/config_entry/number/dropped_modes
config_entry_value = 3
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index fb8299d108..2474a6f272 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -68,6 +68,10 @@ SUBSYSTEM_DEF(vote)
//get the highest number of votes
var/greatest_votes = 0
var/total_votes = 0
+ if(mode == "gamemode" && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
+ for(var/mob/dead/new_player/P in GLOB.player_list)
+ if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
+ choices[choices[voted[P.ckey]]]--
for(var/option in choices)
var/votes = choices[option]
total_votes += votes
@@ -101,6 +105,10 @@ SUBSYSTEM_DEF(vote)
/datum/controller/subsystem/vote/proc/calculate_condorcet_votes(var/blackbox_text)
// https://en.wikipedia.org/wiki/Schulze_method#Implementation
+ if((mode == "gamemode" || mode == "dynamic") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
+ for(var/mob/dead/new_player/P in GLOB.player_list)
+ if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
+ voted -= P.ckey
var/list/d[][] = new/list(choices.len,choices.len) // the basic vote matrix, how many times a beats b
for(var/ckey in voted)
var/list/this_vote = voted[ckey]
@@ -147,6 +155,10 @@ SUBSYSTEM_DEF(vote)
for(var/choice in choices)
scores_by_choice += "[choice]"
scores_by_choice["[choice]"] = list()
+ if((mode == "gamemode" || mode == "dynamic") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode))
+ for(var/mob/dead/new_player/P in GLOB.player_list)
+ if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey])
+ voted -= P.ckey
for(var/ckey in voted)
var/list/this_vote = voted[ckey]
var/list/pretty_vote = list()
diff --git a/code/game/gamemodes/objective_sabotage.dm b/code/game/gamemodes/objective_sabotage.dm
index c8f1ef4713..1fbebfdac4 100644
--- a/code/game/gamemodes/objective_sabotage.dm
+++ b/code/game/gamemodes/objective_sabotage.dm
@@ -33,6 +33,7 @@
/datum/sabotage_objective/processing/check_conditions()
return won
+/*
/datum/sabotage_objective/processing/power_sink
name = "Drain at least 100 megajoules of power using a power sink."
sabotage_type = "powersink"
@@ -44,6 +45,7 @@
for(var/s in GLOB.power_sinks)
var/obj/item/powersink/sink = s
won = max(won,sink.power_drained/1e8)
+*/
/obj/item/paper/guides/antag/supermatter_sabotage
info = "Ways to sabotage a supermatter:
\
diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm
index c14837b8e3..804025961b 100644
--- a/code/game/machinery/computer/apc_control.dm
+++ b/code/game/machinery/computer/apc_control.dm
@@ -151,7 +151,14 @@
var/obj/machinery/power/apc/target = locate(ref) in GLOB.apcs_list
if(!target)
return
- target.vars[type] = target.setsubsystem(text2num(value))
+ value = target.setsubsystem(text2num(value))
+ switch(type) // Sanity check
+ if("equipment", "lighting", "environ")
+ target.vars[type] = value
+ else
+ message_admins("Warning: possible href exploit by [key_name(usr)] - attempted to set [type] on [target] to [value]")
+ log_game("Warning: possible href exploit by [key_name(usr)] - attempted to set [type] on [target] to [value]")
+ return
target.update_icon()
target.update()
var/setTo = ""
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index f2bced4aa8..30bf06b475 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -97,7 +97,7 @@
icon_state = "mecha_ion"
energy_drain = 120
projectile = /obj/item/projectile/ion
- fire_sound = 'sound/weapons/laser.ogg'
+ fire_sound = 'sound/weapons/IonRifle.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla
equip_cooldown = 35
@@ -195,7 +195,7 @@
//Base ballistic weapon type
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic
name = "general ballistic weapon"
- fire_sound = 'sound/weapons/gunshot.ogg'
+ fire_sound = 'sound/weapons/lmgshot.ogg'
var/projectiles
var/projectiles_cache //ammo to be loaded in, if possible.
var/projectiles_cache_max
@@ -285,6 +285,7 @@
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
name = "\improper LBX AC 10 \"Scattershot\""
desc = "A weapon for combat exosuits. Shoots a spread of pellets."
+ fire_sound = 'sound/weapons/gunshotshotgunshot.ogg'
icon_state = "mecha_scatter"
equip_cooldown = 20
projectile = /obj/item/projectile/bullet/scattershot
@@ -299,6 +300,7 @@
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/seedscatter
name = "\improper Melon Seed \"Scattershot\""
desc = "A weapon for combat exosuits. Shoots a spread of pellets, shaped as seed."
+ fire_sound = 'sound/weapons/gunshotshotgunshot.ogg'
icon_state = "mecha_scatter"
equip_cooldown = 20
projectile = /obj/item/projectile/bullet/seed
@@ -331,7 +333,7 @@
desc = "A weapon for combat exosuits. Launches light explosive missiles."
icon_state = "mecha_missilerack"
projectile = /obj/item/projectile/bullet/a84mm_he
- fire_sound = 'sound/weapons/grenadelaunch.ogg'
+ fire_sound = 'sound/weapons/rocketlaunch.ogg'
projectiles = 8
projectiles_cache = 0
projectiles_cache_max = 0
@@ -345,7 +347,7 @@
desc = "A weapon for combat exosuits. Launches low-explosive breaching missiles designed to explode only when striking a sturdy target."
icon_state = "mecha_missilerack_six"
projectile = /obj/item/projectile/bullet/a84mm_br
- fire_sound = 'sound/weapons/grenadelaunch.ogg'
+ fire_sound = 'sound/weapons/rocketlaunch.ogg'
projectiles = 6
projectiles_cache = 0
projectiles_cache_max = 0
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index 6d051b6c8c..bd32ddadf3 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -81,6 +81,7 @@
/obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose
name = "blood"
+ icon = 'icons/effects/blood.dmi'
icon_state = "ltrails_1"
desc = "Your instincts say you shouldn't be following these."
random_icon_states = null
diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm
index 83e9b21e0b..0a86abdec9 100644
--- a/code/game/objects/items/implants/implant_misc.dm
+++ b/code/game/objects/items/implants/implant_misc.dm
@@ -44,7 +44,7 @@
icon_state = "warp"
uses = -1
var/total_delay = 10 SECONDS
- var/cooldown = 10 SECONDS
+ var/cooldown = 30 SECONDS
var/last_use = 0
var/list/positions = list()
var/next_prune = 0
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index 07900d6bbf..554ea81974 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -302,7 +302,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
damtype = STAMINA
attack_verb = list("whacked", "smacked", "struck")
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
- hitsound = 'sound/weapons/grenadelaunch.ogg' // no good wood thunk sounds
+ hitsound = 'sound/weapons/woodbonk.ogg'
var/harm = FALSE // TRUE = brute, FALSE = stam
var/reinforced = FALSE
var/burnt = FALSE
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index fc4185f207..fe08cbd63e 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -36,7 +36,7 @@
/obj/item/clothing/mask/surgical/aesthetic
name = "aesthetic sterile mask"
desc = "A sterile mask designed to help prevent the spread of diseases. This one doesn't seem like it does a whole lot, somehow."
- flags_inv = HIDEFACE
+ flags_inv = null
flags_cover = null
visor_flags_inv = null
visor_flags_cover = null
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index a47d55bfcb..0b705f7797 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -487,6 +487,13 @@
item_state = "militaryjacket"
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/radio)
+/obj/item/clothing/suit/jacket/urbanjacket
+ name = "urban jacket"
+ desc = "A canvas jacket styled with a fur neck piece, stylish."
+ icon_state = "urbanjacket"
+ item_state = "urbanjacket"
+ allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/radio)
+
/obj/item/clothing/suit/jacket/letterman
name = "letterman jacket"
desc = "A classic brown letterman jacket. Looks pretty hot and heavy."
diff --git a/code/modules/clothing/under/suits.dm b/code/modules/clothing/under/suits.dm
index 87e6e94b6b..b9f55e695a 100644
--- a/code/modules/clothing/under/suits.dm
+++ b/code/modules/clothing/under/suits.dm
@@ -91,6 +91,12 @@
icon_state = "tan_suit"
item_state = "tan_suit"
+/obj/item/clothing/under/suit/charismatic_suit
+ name = "charismatic suit"
+ desc = "Luck is for losers, baby."
+ icon_state = "charismatic_suit"
+ item_state = "charismatic_suit"
+
/obj/item/clothing/under/suit/white
name = "white suit"
desc = "A white suit and jacket with a blue shirt. You wanna play rough? OKAY!"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index f653c96cbc..8660e115a6 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -281,11 +281,13 @@
dropItemToGround(pocket_item)
if(!usr.can_hold_items() || !usr.put_in_hands(pocket_item))
pocket_item.forceMove(drop_location())
+ log_combat(usr, src, "pickpocketed of item: [pocket_item]")
else
if(place_item)
if(place_item.mob_can_equip(src, usr, pocket_id, FALSE, TRUE))
usr.temporarilyRemoveItemFromInventory(place_item, TRUE)
equip_to_slot(place_item, pocket_id, TRUE)
+ log_combat(usr, src, "placed item [place_item] onto")
//do nothing otherwise
// Update strip window
@@ -293,8 +295,9 @@
show_inv(usr)
else
// Display a warning if the user mocks up
- if (!strip_silence)
+ if(!strip_silence)
to_chat(src, "You feel your [pocket_side] pocket being fumbled with!")
+ log_combat(usr, src, "failed to [pocket_item ? "pickpocket item [pocket_item] from" : "place item [place_item] onto "]")
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY, null, FALSE))
// separate from first canusetopic
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index fcc1d734a3..6aaa2cca87 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -866,7 +866,7 @@
if(istype(G))
strip_mod = G.strip_mod
strip_silence = G.strip_silence
- if (!strip_silence)
+ if(!strip_silence)
who.visible_message("[src] tries to remove [who]'s [what.name].", \
"[src] tries to remove your [what.name].", target = src,
target_message = "You try to remove [who]'s [what.name].")
diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm
index 9e03207888..c53366c4f5 100644
--- a/code/modules/projectiles/guns/ballistic/launchers.dm
+++ b/code/modules/projectiles/guns/ballistic/launchers.dm
@@ -35,7 +35,7 @@
name = "gyrojet pistol"
desc = "A prototype pistol designed to fire self propelled rockets."
icon_state = "gyropistol"
- fire_sound = 'sound/weapons/grenadelaunch.ogg'
+ fire_sound = 'sound/weapons/rocketlaunch.ogg'
mag_type = /obj/item/ammo_box/magazine/m75
burst_size = 1
fire_delay = 0
diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm
index 8d19d46530..09881da469 100644
--- a/code/modules/vending/clothesmate.dm
+++ b/code/modules/vending/clothesmate.dm
@@ -31,7 +31,10 @@
/obj/item/clothing/under/suit/burgundy = 3,
/obj/item/clothing/under/suit/charcoal = 3,
/obj/item/clothing/under/suit/white = 3,
+ /obj/item/clothing/under/suit/tan = 3,
+ /obj/item/clothing/under/suit/charismatic_suit = 3,
/obj/item/clothing/under/costume/kilt = 3,
+ /obj/item/clothing/suit/suspenders = 3,
/obj/item/clothing/under/misc/overalls = 3,
/obj/item/clothing/under/suit/sl = 3,
/obj/item/clothing/accessory/sweater = 3,
@@ -70,6 +73,7 @@
/obj/item/clothing/accessory/suitjacket/burgundy = 2,
/obj/item/clothing/accessory/suitjacket/checkered = 2,
/obj/item/clothing/suit/jacket/miljacket = 5,
+ /obj/item/clothing/suit/jacket/urbanjacket = 5,
/obj/item/clothing/under/suit/white_on_white/skirt = 2,
/obj/item/clothing/under/rank/captain/suit/skirt = 2,
/obj/item/clothing/under/rank/civilian/head_of_personnel/suit/skirt = 2,
diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm
index e88cfe33a3..eebb07938b 100644
--- a/code/modules/vending/wardrobes.dm
+++ b/code/modules/vending/wardrobes.dm
@@ -207,6 +207,7 @@
product_ads = "You turn me TRUE, use defines!;0110001101101100011011110111010001101000011001010111001101101000011001010111001001100101"
vend_reply = "Thank you for using the RoboDrobe!"
products = list(/obj/item/clothing/glasses/hud/diagnostic = 3,
+ /obj/item/stack/medical/nanogel = 5,
/obj/item/clothing/head/beret/robo = 3,
/obj/item/clothing/under/rank/rnd/roboticist = 3,
/obj/item/clothing/under/rank/rnd/roboticist/sleek = 3,
diff --git a/html/changelog.html b/html/changelog.html
index 9b0c11ba24..51b1c9ed4d 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -68,6 +68,61 @@