diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm
index 61a57a16fd..54ea62d02e 100644
--- a/code/controllers/subsystems/ticker.dm
+++ b/code/controllers/subsystems/ticker.dm
@@ -450,7 +450,7 @@ var/global/datum/controller/subsystem/ticker/ticker
if(captainless)
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
- to_chat(M, "Colony Directorship not forced on anyone.")
+ to_chat(M, "Site Management is not forced on anyone.")
/datum/controller/subsystem/ticker/proc/declare_completion()
diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm
index 1307b8f985..69f198bbd4 100644
--- a/code/datums/supplypacks/medical.dm
+++ b/code/datums/supplypacks/medical.dm
@@ -32,6 +32,13 @@
containertype = /obj/structure/closet/crate/nanomed
containername = "BloodPack crate"
+/datum/supply_pack/med/synthplas
+ name = "BloodPack (Synthplas) crate"
+ contains = list(/obj/item/weapon/reagent_containers/blood/synthplas = 6)
+ cost = 80
+ containertype = /obj/structure/closet/crate/nanomed
+ containername = "SynthPlas crate"
+
/datum/supply_pack/med/bodybag
name = "Body bag crate"
contains = list(/obj/item/weapon/storage/box/bodybags = 3)
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index d10d41c05a..256afb8ed8 100644
--- a/code/game/gamemodes/events.dm
+++ b/code/game/gamemodes/events.dm
@@ -297,9 +297,9 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
M.add_ion_law("HUMANS NEED TO EAT [what2pref] [what2] TO SURVIVE")
if(5)
to_chat(M, "
")
- to_chat(M, "THE COLONY DIRECTOR, HOP AND HOS ARE [who2]...LAWS UPDATED")
+ to_chat(M, "THE SITE MANAGER, HOP AND HOS ARE [who2]...LAWS UPDATED")
to_chat(M, "
")
- M.add_ion_law("THE COLONY DIRECTOR, HOP AND HOS ARE [who2]")
+ M.add_ion_law("THE SITE MANAGER, HOP AND HOS ARE [who2]")
if(6)
to_chat(M, "
")
to_chat(M, "THE STATION IS BUILT FOR [who2]...LAWS UPDATED")
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index 48223c67e2..1e804bbb26 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -438,11 +438,15 @@ steam.start() -- spawns the effect
if(src.processing)
src.processing = 0
spawn(0)
- var/turf/T = get_turf(src.holder)
+ var/turf/T
if(istype(holder, /atom/movable))
var/atom/movable/AM = holder
if(AM.locs && AM.locs.len)
- T = pick(AM.locs)
+ T = get_turf(pick(AM.locs))
+ else
+ T = get_turf(AM)
+ else //when would this ever be attached a non-atom/movable?
+ T = get_turf(src.holder)
if(T != src.oldposition)
if(isturf(T))
var/obj/effect/effect/ion_trails/I = new /obj/effect/effect/ion_trails(src.oldposition)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 65f6009807..376ee1e65a 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -63,7 +63,7 @@
/obj/structure/closet/secure_closet/hos
name = "head of security's locker"
req_access = list(access_hos)
- storage_capacity = 2.5 * MOB_MEDIUM
+ storage_capacity = 2.6 * MOB_MEDIUM
closet_appearance = /decl/closet_appearance/secure_closet/security/hos
starts_with = list(
@@ -99,7 +99,8 @@
/obj/item/clothing/suit/storage/hooded/wintercoat/security,
/obj/item/clothing/shoes/boots/winter/security,
/obj/item/device/flashlight/maglight,
- /obj/item/clothing/mask/gas/half)
+ /obj/item/clothing/mask/gas/half,
+ /obj/item/clothing/mask/gas/sechailer/swat/hos)
/obj/structure/closet/secure_closet/hos/Initialize()
if(prob(50))
@@ -113,6 +114,7 @@
/obj/structure/closet/secure_closet/warden
name = "warden's locker"
+ storage_capacity = 42
req_access = list(access_armory)
closet_appearance = /decl/closet_appearance/secure_closet/security/warden
@@ -143,7 +145,8 @@
/obj/item/clothing/shoes/boots/winter/security,
/obj/item/device/flashlight/maglight,
/obj/item/device/megaphone,
- /obj/item/clothing/mask/gas/half)
+ /obj/item/clothing/mask/gas/half,
+ /obj/item/clothing/mask/gas/sechailer/swat/warden)
/obj/structure/closet/secure_closet/warden/Initialize()
if(prob(50))
diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
index 200d4993b3..5eb36f6dc3 100644
--- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
+++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
@@ -406,7 +406,8 @@
/obj/item/clothing/gloves/swat,
/obj/item/clothing/mask/balaclava/tactical,
/obj/item/clothing/mask/balaclava,
- /obj/item/clothing/mask/bandana/skull = 2)
+ /obj/item/clothing/mask/bandana/skull = 2,
+ /obj/item/clothing/mask/gas/sechailer/swat)
/obj/structure/closet/wardrobe/suit
diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno.dm b/code/modules/client/preference_setup/loadout/loadout_xeno.dm
index eabf443bef..7124b55337 100644
--- a/code/modules/client/preference_setup/loadout/loadout_xeno.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_xeno.dm
@@ -397,6 +397,7 @@
/datum/gear/suit/teshcoat/New()
..()
+
gear_tweaks += gear_tweak_free_color_choice
/datum/gear/suit/teshcoatwhite
@@ -417,4 +418,17 @@
/datum/gear/accessory/teshneckscarf/New()
..()
- gear_tweaks += gear_tweak_free_color_choice
\ No newline at end of file
+ gear_tweaks += gear_tweak_free_color_choice
+
+/datum/gear/shoes/toelessjack
+ display_name = "toe-less jackboots"
+ path = /obj/item/clothing/shoes/boots/jackboots/toeless
+
+
+/datum/gear/shoes/toelessknee
+ display_name = "toe-less jackboots, knee-length"
+ path = /obj/item/clothing/shoes/boots/jackboots/toeless/knee
+
+/datum/gear/shoes/toelessthigh
+ display_name = "toe-less jackboots, thigh-length"
+ path = /obj/item/clothing/shoes/boots/jackboots/toeless/thigh
\ No newline at end of file
diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm
index 594600b601..116a54e494 100644
--- a/code/modules/clothing/masks/gasmask.dm
+++ b/code/modules/clothing/masks/gasmask.dm
@@ -42,6 +42,23 @@
w_class = ITEMSIZE_SMALL
armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 55, rad = 0)
+//Turn it into a hailer mask
+/obj/item/clothing/mask/gas/half/attackby(obj/item/I, mob/user)
+ if(istype(I, /obj/item/device/hailer))
+ playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
+ user.drop_item(src)
+ var/obj/item/clothing/mask/gas/sechailer/N = new /obj/item/clothing/mask/gas/sechailer(src.loc)
+ N.fingerprints = src.fingerprints
+ N.fingerprintshidden = src.fingerprintshidden
+ N.fingerprintslast = src.fingerprintslast
+ N.suit_fibers = src.suit_fibers
+ N.hailer = I
+ I.loc = N
+ if(!isturf(N.loc))
+ user.put_in_hands(N)
+ qdel(src)
+ ..()
+
//Plague Dr suit can be found in clothing/suits/bio.dm
/obj/item/clothing/mask/gas/plaguedoctor
name = "plague doctor mask"
diff --git a/code/modules/clothing/masks/hailer.dm b/code/modules/clothing/masks/hailer.dm
new file mode 100644
index 0000000000..a3a37772b3
--- /dev/null
+++ b/code/modules/clothing/masks/hailer.dm
@@ -0,0 +1,165 @@
+/obj/item/clothing/mask/gas/sechailer
+ name = "hailer face mask"
+ desc = "A compact, durable gas mask that can be connected to an air supply. This one possesses a security hailer."
+ description_info = "This mask has a hailer attached, you can activate it on the button or use the Halt! verb, for switching phrases you can alt+click it or change it using the change phrase verb."
+ icon_state = "halfgas"
+ armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 55, rad = 0)
+ action_button_name = "HALT!"
+ body_parts_covered = FACE
+ var/obj/item/device/hailer/hailer
+ var/cooldown = 0
+ var/phrase = 1
+ var/aggressiveness = 1
+ var/safety = 1
+ var/list/phrase_list = list(
+ "halt" = "HALT! HALT! HALT! HALT!",
+ "bobby" = "Stop in the name of the Law.",
+ "compliance" = "Compliance is in your best interest.",
+ "justice" = "Prepare for justice!",
+ "running" = "Running will only increase your sentence.",
+ "dontmove" = "Don't move, Creep!",
+ "floor" = "Down on the floor, Creep!",
+ "robocop" = "Dead or alive you're coming with me.",
+ "god" = "God made today for the crooks we could not catch yesterday.",
+ "freeze" = "Freeze, Scum Bag!",
+ "imperial" = "Stop right there, criminal scum!",
+ "bash" = "Stop or I'll bash you.",
+ "harry" = "Go ahead, make my day.",
+ "asshole" = "Stop breaking the law, asshole.",
+ "stfu" = "You have the right to shut the fuck up",
+ "shutup" = "Shut up crime!",
+ "super" = "Face the wrath of the golden bolt.",
+ "dredd" = "I am, the LAW!"
+ )
+
+/obj/item/clothing/mask/gas/sechailer/swat/hos
+ name = "\improper HOS SWAT mask"
+ desc = "A close-fitting tactical mask with an especially aggressive Compli-o-nator 3000. It has a tan stripe."
+ icon_state = "hosmask"
+
+
+/obj/item/clothing/mask/gas/sechailer/swat/warden
+ name = "\improper Warden SWAT mask"
+ desc = "A close-fitting tactical mask with an especially aggressive Compli-o-nator 3000. It has a blue stripe."
+ icon_state = "wardenmask"
+
+/obj/item/clothing/mask/gas/sechailer/swat
+ name = "\improper SWAT mask"
+ desc = "A close-fitting tactical mask with an especially aggressive Compli-o-nator 3000."
+ icon_state = "officermask"
+ body_parts_covered = HEAD|FACE|EYES
+ flags_inv = HIDEFACE|BLOCKHAIR
+ aggressiveness = 3
+ phrase = 12
+
+
+/obj/item/clothing/mask/gas/sechailer/ui_action_click()
+ halt()
+
+/obj/item/clothing/mask/gas/sechailer/AltClick(mob/user)
+ selectphrase()
+
+/obj/item/clothing/mask/gas/sechailer/verb/selectphrase()
+ set name = "Select gas mask phrase"
+ set category = "Object"
+ set desc = "Alter the message shouted by your complionator gas mask."
+
+ var/key = phrase_list[phrase]
+ var/message = phrase_list[key]
+
+ if (!safety)
+ to_chat(usr, "You set the restrictor to: FUCK YOUR CUNT YOU SHIT EATING COCKSUCKER MAN EAT A DONG FUCKING ASS RAMMING SHIT FUCK EAT PENISES IN YOUR FUCK FACE AND SHIT OUT ABORTIONS OF FUCK AND DO SHIT IN YOUR ASS YOU COCK FUCK SHIT MONKEY FUCK ASS WANKER FROM THE DEPTHS OF SHIT.")
+ return
+ switch(aggressiveness)
+ if(1)
+ phrase = (phrase < 6) ? (phrase + 1) : 1
+ key = phrase_list[phrase]
+ message = phrase_list[key]
+ to_chat(usr,"You set the restrictor to: [message]")
+ if(2)
+ phrase = (phrase < 11 && phrase >= 7) ? (phrase + 1) : 7
+ key = phrase_list[phrase]
+ message = phrase_list[key]
+ to_chat(usr,"You set the restrictor to: [message]")
+ if(3)
+ phrase = (phrase < 18 && phrase >= 12 ) ? (phrase + 1) : 12
+ key = phrase_list[phrase]
+ message = phrase_list[key]
+ to_chat(usr,"You set the restrictor to: [message]")
+ if(4)
+ phrase = (phrase < 18 && phrase >= 1 ) ? (phrase + 1) : 1
+ key = phrase_list[phrase]
+ message = phrase_list[key]
+ to_chat(usr,"You set the restrictor to: [message]")
+ else
+ to_chat(usr, "It's broken.")
+
+/obj/item/clothing/mask/gas/sechailer/emag_act(mob/user)
+ if(safety)
+ safety = 0
+ to_chat(user, "You silently fry [src]'s vocal circuit with the cryptographic sequencer.")
+ else
+ return
+
+/obj/item/clothing/mask/gas/sechailer/attackby(obj/item/I, mob/user)
+ if(I.is_screwdriver())
+ switch(aggressiveness)
+ if(1)
+ to_chat(user, "You set the aggressiveness restrictor to the second position.")
+ aggressiveness = 2
+ phrase = 7
+ if(2)
+ to_chat(user, "You set the aggressiveness restrictor to the third position.")
+ aggressiveness = 3
+ phrase = 13
+ if(3)
+ to_chat(user, "You set the aggressiveness restrictor to the fourth position.")
+ aggressiveness = 4
+ phrase = 1
+ if(4)
+ to_chat(user, "You set the aggressiveness restrictor to the first position.")
+ aggressiveness = 1
+ phrase = 1
+ if(5)
+ to_chat(user, "You adjust the restrictor but nothing happens, probably because its broken.")
+ if(I.is_wirecutter())
+ if(aggressiveness != 5)
+ to_chat(user, "You broke it!")
+ aggressiveness = 5
+ if(I.is_crowbar())
+ if(!hailer)
+ to_chat(user, "This mask has an integrated hailer, you can't remove it!")
+ else
+ var/obj/N = new /obj/item/clothing/mask/gas/half(src.loc)
+ playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
+ N.fingerprints = src.fingerprints
+ N.fingerprintshidden = src.fingerprintshidden
+ N.fingerprintslast = src.fingerprintslast
+ N.suit_fibers = src.suit_fibers
+ if(!isturf(N.loc))
+ user.put_in_hands(hailer)
+ user.put_in_hands(N)
+ else
+ hailer.loc = N.loc
+ qdel(src)
+ return
+ ..()
+
+/obj/item/clothing/mask/gas/sechailer/verb/halt()
+ set name = "HALT!"
+ set category = "Objects"
+ set desc = "Activate your face mask hailer."
+ var/key = phrase_list[phrase]
+ var/message = phrase_list[key]
+
+ if(cooldown < world.time - 35) // A cooldown, to stop people being jerks
+ if(!safety)
+ message = "FUCK YOUR CUNT YOU SHIT EATING COCKSUCKER MAN EAT A DONG FUCKING ASS RAMMING SHIT FUCK EAT PENISES IN YOUR FUCK FACE AND SHIT OUT ABORTIONS OF FUCK AND DO SHIT IN YOUR ASS YOU COCK FUCK SHIT MONKEY FUCK ASS WANKER FROM THE DEPTHS OF SHIT."
+ usr.visible_message("[usr]'s Compli-o-Nator: [message]")
+ playsound(src, 'sound/voice/binsult.ogg', 50, 0, 4) //Future sound channel = something like SFX
+ cooldown = world.time
+ return
+
+ usr.visible_message("[usr]'s Compli-o-Nator: [message]")
+ playsound(src, "sound/voice/complionator/[key].ogg", 50, 0, 4) //future sound channel = something like SFX
+ cooldown = world.time
\ No newline at end of file
diff --git a/code/modules/clothing/under/xenos/seromi.dm b/code/modules/clothing/under/xenos/seromi.dm
index 8da5e52755..71f00f293a 100644
--- a/code/modules/clothing/under/xenos/seromi.dm
+++ b/code/modules/clothing/under/xenos/seromi.dm
@@ -39,19 +39,19 @@
/obj/item/clothing/under/seromi/smock/dress/science
name = "small research dress"
- icon_state = "seromi_dress_science"
+ icon_state = "tesh_dress_science"
/obj/item/clothing/under/seromi/smock/dress/security
name = "small security dress"
- icon_state = "seromi_dress_security"
+ icon_state = "tesh_dress_security"
/obj/item/clothing/under/seromi/smock/dress/engine
name = "small engineering dress"
- icon_state = "seromi_dress_engine"
+ icon_state = "tesh_dress_engine"
/obj/item/clothing/under/seromi/smock/dress/medical
name = "small medical dress"
- icon_state = "seromi_dress_medical"
+ icon_state = "tesh_dress_medical"
/obj/item/clothing/under/seromi/smock/uniform
name = "small command uniform"
diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm
index 6354baa1f3..3600dd23aa 100644
--- a/code/modules/events/ion_storm.dm
+++ b/code/modules/events/ion_storm.dm
@@ -133,9 +133,9 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
M.add_ion_law("HUMANS NEED TO EAT [what2pref] [what2] TO SURVIVE")
if(5)
to_chat(M, "
")
- to_chat(M, "THE COLONY DIRECTOR, HOP AND HOS ARE [who2]...LAWS UPDATED")
+ to_chat(M, "THE SITE MANAGER, HOP AND HOS ARE [who2]...LAWS UPDATED")
to_chat(M, "
")
- M.add_ion_law("THE COLONY DIRECTOR, HOP AND HOS ARE [who2]")
+ M.add_ion_law("THE SITE MANAGER, HOP AND HOS ARE [who2]")
if(6)
to_chat(M, "
")
to_chat(M, "THE STATION IS BUILT FOR [who2]...LAWS UPDATED")
diff --git a/code/modules/mining/drilling/scanner.dm b/code/modules/mining/drilling/scanner.dm
index 31da4a9753..50bf8bdd35 100644
--- a/code/modules/mining/drilling/scanner.dm
+++ b/code/modules/mining/drilling/scanner.dm
@@ -6,7 +6,7 @@
item_state = "electronic"
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
matter = list(DEFAULT_WALL_MATERIAL = 150)
- var/scan_time = 5 SECONDS
+ var/scan_time = 2 SECONDS
/obj/item/weapon/mining_scanner/attack_self(mob/user as mob)
to_chat(user, "You begin sweeping \the [src] about, scanning for metal deposits.")
diff --git a/code/modules/mob/new_player/skill.dm b/code/modules/mob/new_player/skill.dm
index b2d061d5a6..a24da0e4ba 100644
--- a/code/modules/mob/new_player/skill.dm
+++ b/code/modules/mob/new_player/skill.dm
@@ -63,7 +63,7 @@ var/global/list/SKILL_PRE = list("Engineer" = SKILL_ENGINEER, "Roboticist" = SKI
/datum/skill/knowledge/law
ID = "law"
name = "Corporate Law"
- desc = "Your knowledge of corporate law and procedures. This includes Corporate Regulations, as well as general station rulings and procedures. A low level in this skill is typical for security officers, a high level in this skill is typical for Colony Directors."
+ desc = "Your knowledge of corporate law and procedures. This includes Corporate Regulations, as well as general station rulings and procedures. A low level in this skill is typical for security officers, a high level in this skill is typical for Site Managers."
field = "Security"
secondary = 1
diff --git a/code/modules/overmap/ships/computers/ship.dm b/code/modules/overmap/ships/computers/ship.dm
index f350aa11f6..9ce2029978 100644
--- a/code/modules/overmap/ships/computers/ship.dm
+++ b/code/modules/overmap/ships/computers/ship.dm
@@ -71,6 +71,10 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
if(linked)
apply_visual(user)
user.reset_view(linked)
+ if(isliving(user))
+ var/mob/living/L = user
+ L.looking_elsewhere = 1
+ L.handle_vision()
user.set_viewsize(world.view + extra_view)
GLOB.moved_event.register(user, src, /obj/machinery/computer/ship/proc/unlook)
// TODO GLOB.stat_set_event.register(user, src, /obj/machinery/computer/ship/proc/unlook)
@@ -78,6 +82,10 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
/obj/machinery/computer/ship/proc/unlook(var/mob/user)
user.reset_view()
+ if(isliving(user))
+ var/mob/living/L = user
+ L.looking_elsewhere = 0
+ L.handle_vision()
user.set_viewsize() // reset to default
GLOB.moved_event.unregister(user, src, /obj/machinery/computer/ship/proc/unlook)
// TODO GLOB.stat_set_event.unregister(user, src, /obj/machinery/computer/ship/proc/unlook)
@@ -109,4 +117,4 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
var/M = W.resolve()
if(M)
unlook(M)
- . = ..()
\ No newline at end of file
+ . = ..()
diff --git a/code/modules/overmap/spacetravel.dm b/code/modules/overmap/spacetravel.dm
index 94da01879f..9ce971f356 100644
--- a/code/modules/overmap/spacetravel.dm
+++ b/code/modules/overmap/spacetravel.dm
@@ -45,8 +45,29 @@ proc/get_deepspace(x,y)
for(var/atom/movable/AM in contents)
if(!AM.lost_in_space())
return FALSE
+ if(has_buckled_mobs())
+ for(var/mob/M in buckled_mobs)
+ if(!M.lost_in_space())
+ return FALSE
+
return TRUE
+/obj/item/device/uav/lost_in_space()
+ if(state == 1)
+ return FALSE
+ return ..()
+
+/obj/machinery/power/supermatter/lost_in_space()
+ return FALSE
+
+/obj/singularity/lost_in_space()
+ return FALSE
+
+/obj/vehicle/lost_in_space()
+ if(load && !load.lost_in_space())
+ return FALSE
+ return ..()
+
/mob/lost_in_space()
return isnull(client)
diff --git a/code/modules/projectiles/guns/energy/hooklauncher.dm b/code/modules/projectiles/guns/energy/hooklauncher.dm
index 2c170544a0..79ddf7443d 100644
--- a/code/modules/projectiles/guns/energy/hooklauncher.dm
+++ b/code/modules/projectiles/guns/energy/hooklauncher.dm
@@ -5,12 +5,14 @@
/obj/item/weapon/gun/energy/hooklauncher
name = "gravity whip"
desc = "A large, strange gauntlet."
+ icon = 'icons/obj/gun2.dmi'
icon_state = "gravwhip"
item_state = "gravwhip"
fire_sound_text = "laser blast"
fire_delay = 15
charge_cost = 300
+ charge_meter = FALSE
cell_type = /obj/item/weapon/cell/device/weapon
projectile_type = /obj/item/projectile/energy/hook
@@ -29,7 +31,6 @@
cell_type = /obj/item/weapon/cell/device/weapon/recharge/alien
battery_lock = TRUE
charge_cost = 400
- charge_meter = FALSE
projectile_type = /obj/item/projectile/energy/hook/ring
diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm
new file mode 100644
index 0000000000..0b0678894f
--- /dev/null
+++ b/code/modules/projectiles/guns/magic.dm
@@ -0,0 +1,60 @@
+/*
+ * "Magic" "Guns"
+ */
+
+/obj/item/weapon/gun/magic
+ name = "staff of nothing"
+ desc = "This staff is boring to watch because even though it came first you've seen everything it can do in other staves for years."
+ icon = 'icons/obj/wizard.dmi'
+ icon_state = "staffofnothing"
+ item_icons = list(
+ slot_l_hand_str = 'icons/mob/items/lefthand_magic.dmi',
+ slot_r_hand_str = 'icons/mob/items/righthand_magic.dmi',
+ )
+ fire_sound = 'sound/weapons/emitter.ogg'
+ w_class = ITEMSIZE_HUGE
+ projectile_type = null
+ var/checks_antimagic = TRUE
+ var/max_charges = 6
+ var/charges = 0
+ var/recharge_rate = 4
+ var/charge_tick = 0
+ var/can_charge = TRUE
+
+/obj/item/weapon/gun/magic/consume_next_projectile()
+ if(checks_antimagic && locate(/obj/item/weapon/nullrod) in usr) return null
+ if(!ispath(projectile_type)) return null
+ if(charges <= 0) return null
+
+ charges -= 1
+
+ return new projectile_type(src)
+
+/obj/item/weapon/gun/magic/Initialize()
+ . = ..()
+ charges = max_charges
+ if(can_charge)
+ START_PROCESSING(SSobj, src)
+
+/obj/item/weapon/gun/magic/Destroy()
+ if(can_charge)
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/item/weapon/gun/magic/process()
+ if (charges >= max_charges)
+ charge_tick = 0
+ return
+ charge_tick++
+ if(charge_tick < recharge_rate)
+ return 0
+ charge_tick = 0
+ charges++
+ return 1
+
+/obj/item/weapon/gun/magic/handle_click_empty(mob/user)
+ if (user)
+ user.visible_message("*wzhzhzh*", "The [name] whizzles quietly.")
+ else
+ src.visible_message("*wzhzh*")
+ playsound(src, 'sound/weapons/empty.ogg', 100, 1)
diff --git a/code/modules/projectiles/guns/magic/fireball.dm b/code/modules/projectiles/guns/magic/fireball.dm
new file mode 100644
index 0000000000..4abe3e286e
--- /dev/null
+++ b/code/modules/projectiles/guns/magic/fireball.dm
@@ -0,0 +1,17 @@
+
+/obj/item/weapon/gun/magic/firestaff
+ name = "flaming staff"
+ desc = "A long, everburning torch."
+ icon = 'icons/obj/wizard.dmi'
+ icon_state = "staffoffire"
+ item_state = "staff"
+ fire_sound = 'sound/weapons/emitter.ogg'
+ w_class = ITEMSIZE_HUGE
+ checks_antimagic = TRUE
+ max_charges = 6
+ charges = 0
+ recharge_rate = 4
+ charge_tick = 0
+ can_charge = TRUE
+
+ projectile_type = /obj/item/projectile/energy/fireball
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 8ef1bfe2a6..6cd885f0c1 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -739,6 +739,8 @@
shot_from = launcher.name
silenced = launcher.silenced
+ if(user)
+ firer = user
return launch_projectile(target, target_zone, user, params, angle_override, forced_spread)
diff --git a/code/modules/projectiles/projectile/hook.dm b/code/modules/projectiles/projectile/hook.dm
index ee5fd6c471..3e98319ebd 100644
--- a/code/modules/projectiles/projectile/hook.dm
+++ b/code/modules/projectiles/projectile/hook.dm
@@ -27,13 +27,15 @@
var/list/help_messages = list("slaps", "pokes", "nudges", "bumps", "pinches")
var/done_mob_unique = FALSE // Has the projectile already done something to a mob?
+ var/datum/beam/chain = null
+
/obj/item/projectile/energy/hook/launch_projectile(atom/target, target_zone, mob/user, params, angle_override, forced_spread = 0)
var/expected_distance = get_dist(target, loc)
range = expected_distance // So the hook hits the ground if no mob is hit.
target_distance = expected_distance
if(firer) // Needed to ensure later checks in impact and on hit function.
launcher_intent = firer.a_intent
- firer.Beam(src,icon_state=beam_state,icon='icons/effects/beam.dmi',time=60, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=1)
+ chain = firer.Beam(src,icon_state=beam_state,icon='icons/effects/beam.dmi',time=60, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=1)
if(launcher_intent)
switch(launcher_intent)
@@ -58,10 +60,22 @@
..() // Does the regular launching stuff.
+/obj/item/projectile/energy/hook/after_move()
+ if(chain)
+ var/origin_turf = get_turf(firer)
+ var/target_turf = get_turf(src)
+ if(!chain.static_beam && (origin_turf != chain.origin_oldloc || target_turf != chain.target_oldloc))
+ chain.origin_oldloc = origin_turf //so we don't keep checking against their initial positions, leading to endless Reset()+Draw() calls
+ chain.target_oldloc = target_turf
+ chain.Reset()
+ chain.Draw()
+ return
+
/obj/item/projectile/energy/hook/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null)
if(..())
perform_intent_unique(target)
+
/obj/item/projectile/energy/hook/on_impact(var/atom/A)
perform_intent_unique(get_turf(A))
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
new file mode 100644
index 0000000000..9fcc1c1979
--- /dev/null
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -0,0 +1,20 @@
+
+/obj/item/projectile/energy/fireball
+ name = "fireball"
+ icon_state = "fireball2"
+ damage = 15
+ damage_type = BURN
+ check_armour = "bomb"
+ armor_penetration = 25 // It's a great ball of fire.
+
+ combustion = TRUE
+
+/obj/item/projectile/energy/fireball/on_hit(var/atom/target, var/blocked = 0)
+ new /obj/effect/explosion(get_turf(target))
+ explosion(target, -1, 0, 2)
+ ..()
+
+/obj/item/projectile/energy/fireball/on_impact(var/atom/target)
+ new /obj/effect/explosion(get_turf(target))
+ explosion(target, -1, 0, 2)
+ ..()
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
index 9997ac0f1f..7776ff80f5 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
@@ -110,7 +110,7 @@
remove_self(volume)
/datum/reagent/blood/synthblood
- name = "Synthetic blood"
+ name = "synthetic blood"
id = "synthblood"
color = "#999966"
volume_mod = 2
@@ -119,8 +119,16 @@
..()
if(data && !data["blood_type"])
data["blood_type"] = "O-"
+ if(data && data["species"])
+ data["species"] = null
return
+/datum/reagent/blood/synthblood/dilute
+ name = "synthetic plasma"
+ id = "synthblood_dilute"
+ color = "#cacaaf"
+ volume_mod = 1.2
+
// pure concentrated antibodies
/datum/reagent/antibodies
data = list("antibodies"=list())
diff --git a/code/modules/reagents/distilling/Distilling-Recipes.dm b/code/modules/reagents/distilling/Distilling-Recipes.dm
index a8ac2ee975..0736ac7e61 100644
--- a/code/modules/reagents/distilling/Distilling-Recipes.dm
+++ b/code/modules/reagents/distilling/Distilling-Recipes.dm
@@ -128,6 +128,17 @@
temp_range = list(T0C + 100, T0C + 120)
+/datum/chemical_reaction/distilling/synthplas
+ name = "Distilling Synthplas"
+ id = "distill_synthplas"
+ result = "synthblood_dilute"
+ required_reagents = list("protein" = 2, "antibodies" = 1, "bicaridine" = 1)
+ result_amount = 3
+
+ reaction_rate = HALF_LIFE(15)
+
+ temp_range = list(T0C + 110, T0C + 130)
+
// Alcohol
/datum/chemical_reaction/distilling/beer
name = "Distilling Beer"
diff --git a/code/modules/reagents/distilling/distilling.dm b/code/modules/reagents/distilling/distilling.dm
index 645f13c76b..5d37f8510c 100644
--- a/code/modules/reagents/distilling/distilling.dm
+++ b/code/modules/reagents/distilling/distilling.dm
@@ -19,7 +19,7 @@
var/target_temp = T20C
- var/max_temp = T20C + 300
+ var/max_temp = T0C + 300
var/min_temp = T0C - 10
var/current_temp = T20C
@@ -86,6 +86,16 @@
update_icon()
+/obj/machinery/portable_atmospherics/powered/reagent_distillery/RefreshParts()
+ var/total_laser_rating = 0
+ for(var/obj/item/weapon/stock_parts/micro_laser/ML in component_parts)
+ total_laser_rating += ML.rating
+
+ max_temp = initial(max_temp) + (50 * (total_laser_rating - 1))
+ min_temp = max(1, initial(min_temp) - (30 * (total_laser_rating - 1)))
+
+ return
+
/obj/machinery/portable_atmospherics/powered/reagent_distillery/proc/setup_overlay_vars()
overlay_output_beaker = image(icon = src.icon, icon_state = "[base_state]-output")
overlay_input_beaker = image(icon = src.icon, icon_state = "[base_state]-input")
diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm
index 223583f7dc..693330fef7 100644
--- a/code/modules/reagents/reagent_containers/blood_pack.dm
+++ b/code/modules/reagents/reagent_containers/blood_pack.dm
@@ -27,6 +27,7 @@
var/label_text = ""
var/blood_type = null
+ var/reag_id = "blood"
/obj/item/weapon/reagent_containers/blood/Initialize()
. = ..()
@@ -35,7 +36,7 @@
if(blood_type != null)
label_text = "[blood_type]"
update_iv_label()
- reagents.add_reagent("blood", 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
+ reagents.add_reagent(reag_id, 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
update_icon()
/obj/item/weapon/reagent_containers/blood/on_reagent_change()
@@ -95,6 +96,14 @@
/obj/item/weapon/reagent_containers/blood/OMinus
blood_type = "O-"
+/obj/item/weapon/reagent_containers/blood/synthplas
+ blood_type = "O-"
+ reag_id = "synthblood_dilute"
+
+/obj/item/weapon/reagent_containers/blood/synthblood
+ blood_type = "O-"
+ reag_id = "synthblood"
+
/obj/item/weapon/reagent_containers/blood/empty
name = "Empty BloodPack"
desc = "Seems pretty useless... Maybe if there were a way to fill it?"
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghypo.dm
similarity index 97%
rename from code/modules/reagents/reagent_containers/borghydro.dm
rename to code/modules/reagents/reagent_containers/borghypo.dm
index a08ea1b19b..d8afdf4631 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghypo.dm
@@ -1,157 +1,159 @@
-/obj/item/weapon/reagent_containers/borghypo
- name = "cyborg hypospray"
- desc = "An advanced chemical synthesizer and injection system, designed for heavy-duty medical equipment."
- icon = 'icons/obj/syringe.dmi'
- item_state = "hypo"
- icon_state = "borghypo"
- amount_per_transfer_from_this = 5
- volume = 30
- possible_transfer_amounts = null
-
- var/mode = 1
- var/charge_cost = 50
- var/charge_tick = 0
- var/recharge_time = 5 //Time it takes for shots to recharge (in seconds)
- var/bypass_protection = FALSE // If true, can inject through things like spacesuits and armor.
-
- var/list/reagent_ids = list("tricordrazine", "inaprovaline", "anti_toxin", "tramadol", "dexalin" ,"spaceacillin")
- var/list/reagent_volumes = list()
- var/list/reagent_names = list()
-
-/obj/item/weapon/reagent_containers/borghypo/surgeon
- reagent_ids = list("tricordrazine", "inaprovaline", "oxycodone", "dexalin" ,"spaceacillin")
-
-/obj/item/weapon/reagent_containers/borghypo/crisis
- reagent_ids = list("tricordrazine", "inaprovaline", "anti_toxin", "tramadol", "dexalin" ,"spaceacillin")
-
-/obj/item/weapon/reagent_containers/borghypo/lost
- reagent_ids = list("tricordrazine", "bicaridine", "dexalin", "anti_toxin", "tramadol", "spaceacillin")
-
-/obj/item/weapon/reagent_containers/borghypo/merc
- name = "advanced cyborg hypospray"
- desc = "An advanced nanite and chemical synthesizer and injection system, designed for heavy-duty medical equipment. This type is capable of safely bypassing \
- thick materials that other hyposprays would struggle with."
- bypass_protection = TRUE // Because mercs tend to be in spacesuits.
- reagent_ids = list("healing_nanites", "hyperzine", "tramadol", "oxycodone", "spaceacillin", "peridaxon", "osteodaxon", "myelamine", "synthblood")
-
-/obj/item/weapon/reagent_containers/borghypo/Initialize()
- . = ..()
-
- for(var/T in reagent_ids)
- reagent_volumes[T] = volume
- var/datum/reagent/R = SSchemistry.chemical_reagents[T]
- reagent_names += R.name
-
- START_PROCESSING(SSobj, src)
-
-/obj/item/weapon/reagent_containers/borghypo/Destroy()
- STOP_PROCESSING(SSobj, src)
- return ..()
-
-/obj/item/weapon/reagent_containers/borghypo/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg+
- if(++charge_tick < recharge_time)
- return 0
- charge_tick = 0
-
- if(isrobot(loc))
- var/mob/living/silicon/robot/R = loc
- if(R && R.cell)
- for(var/T in reagent_ids)
- if(reagent_volumes[T] < volume)
- R.cell.use(charge_cost)
- reagent_volumes[T] = min(reagent_volumes[T] + 5, volume)
- return 1
-
-/obj/item/weapon/reagent_containers/borghypo/attack(var/mob/living/M, var/mob/user)
- if(!istype(M))
- return
-
- if(!reagent_volumes[reagent_ids[mode]])
- to_chat(user, "The injector is empty.")
- return
-
- var/mob/living/carbon/human/H = M
- if(istype(H))
- var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
- if(!affected)
- to_chat(user, "\The [H] is missing that limb!")
- return
- else if(affected.robotic >= ORGAN_ROBOT)
- to_chat(user, "You cannot inject a robotic limb.")
- return
-
- if(M.can_inject(user, 1, ignore_thickness = bypass_protection))
- to_chat(user, "You inject [M] with the injector.")
- to_chat(M, "You feel a tiny prick!")
-
- if(M.reagents)
- var/t = min(amount_per_transfer_from_this, reagent_volumes[reagent_ids[mode]])
- M.reagents.add_reagent(reagent_ids[mode], t)
- reagent_volumes[reagent_ids[mode]] -= t
- add_attack_logs(user, M, "Borg injected with [reagent_ids[mode]]")
- to_chat(user, "[t] units injected. [reagent_volumes[reagent_ids[mode]]] units remaining.")
- return
-
-/obj/item/weapon/reagent_containers/borghypo/attack_self(mob/user as mob) //Change the mode
- var/t = ""
- for(var/i = 1 to reagent_ids.len)
- if(t)
- t += ", "
- if(mode == i)
- t += "[reagent_names[i]]"
- else
- t += "[reagent_names[i]]"
- t = "Available reagents: [t]."
- to_chat(user,t)
-
- return
-
-/obj/item/weapon/reagent_containers/borghypo/Topic(var/href, var/list/href_list)
- if(href_list["reagent"])
- var/t = reagent_ids.Find(href_list["reagent"])
- if(t)
- playsound(src, 'sound/effects/pop.ogg', 50, 0)
- mode = t
- var/datum/reagent/R = SSchemistry.chemical_reagents[reagent_ids[mode]]
- to_chat(usr, "Synthesizer is now producing '[R.name]'.")
-
-/obj/item/weapon/reagent_containers/borghypo/examine(mob/user)
- . = ..()
- if(get_dist(user, src) <= 2)
- var/datum/reagent/R = SSchemistry.chemical_reagents[reagent_ids[mode]]
- . += "It is currently producing [R.name] and has [reagent_volumes[reagent_ids[mode]]] out of [volume] units left."
-
-/obj/item/weapon/reagent_containers/borghypo/service
- name = "cyborg drink synthesizer"
- desc = "A portable drink dispencer."
- icon = 'icons/obj/drinks.dmi'
- icon_state = "shaker"
- charge_cost = 20
- recharge_time = 3
- volume = 60
- possible_transfer_amounts = list(5, 10, 20, 30)
- reagent_ids = list("ale", "cider", "beer", "berryjuice", "bitters", "coffee", "cognac", "cola", "dr_gibb", "egg", "gin", "gingerale", "hot_coco", "ice", "icetea", "kahlua", "lemonjuice", "lemon_lime", "limejuice", "mead", "milk", "mint", "orangejuice", "rum", "sake", "sodawater", "soymilk", "space_up", "spacemountainwind", "specialwhiskey", "sugar", "tea", "tequilla", "tomatojuice", "tonic", "vermouth", "vodka", "water", "watermelonjuice", "whiskey", "wine")
-
-/obj/item/weapon/reagent_containers/borghypo/service/attack(var/mob/M, var/mob/user)
- return
-
-/obj/item/weapon/reagent_containers/borghypo/service/afterattack(var/obj/target, var/mob/user, var/proximity)
- if(!proximity)
- return
-
- if(!target.is_open_container() || !target.reagents)
- return
-
- if(!reagent_volumes[reagent_ids[mode]])
- to_chat(user, "[src] is out of this reagent, give it some time to refill.")
- return
-
- if(!target.reagents.get_free_space())
- to_chat(user, "[target] is full.")
- return
-
- var/t = min(amount_per_transfer_from_this, reagent_volumes[reagent_ids[mode]])
- target.reagents.add_reagent(reagent_ids[mode], t)
- reagent_volumes[reagent_ids[mode]] -= t
- to_chat(user, "You transfer [t] units of the solution to [target].")
- return
+/obj/item/weapon/reagent_containers/borghypo
+ name = "cyborg hypospray"
+ desc = "An advanced chemical synthesizer and injection system, designed for heavy-duty medical equipment."
+ icon = 'icons/obj/syringe.dmi'
+ item_state = "hypo"
+ icon_state = "borghypo"
+ amount_per_transfer_from_this = 5
+ volume = 30
+ possible_transfer_amounts = null
+
+ var/mode = 1
+ var/charge_cost = 50
+ var/charge_tick = 0
+ var/recharge_time = 5 //Time it takes for shots to recharge (in seconds)
+ var/bypass_protection = FALSE // If true, can inject through things like spacesuits and armor.
+
+ var/list/reagent_ids = list("tricordrazine", "inaprovaline", "anti_toxin", "tramadol", "dexalin" ,"spaceacillin")
+ var/list/reagent_volumes = list()
+ var/list/reagent_names = list()
+
+/obj/item/weapon/reagent_containers/borghypo/surgeon
+ reagent_ids = list("tricordrazine", "inaprovaline", "oxycodone", "dexalin" ,"spaceacillin")
+
+/obj/item/weapon/reagent_containers/borghypo/crisis
+ reagent_ids = list("tricordrazine", "inaprovaline", "anti_toxin", "tramadol", "dexalin" ,"spaceacillin")
+
+/obj/item/weapon/reagent_containers/borghypo/lost
+ reagent_ids = list("tricordrazine", "bicaridine", "dexalin", "anti_toxin", "tramadol", "spaceacillin")
+
+/obj/item/weapon/reagent_containers/borghypo/merc
+ name = "advanced cyborg hypospray"
+ desc = "An advanced nanite and chemical synthesizer and injection system, designed for heavy-duty medical equipment. This type is capable of safely bypassing \
+ thick materials that other hyposprays would struggle with."
+ bypass_protection = TRUE // Because mercs tend to be in spacesuits.
+ reagent_ids = list("healing_nanites", "hyperzine", "tramadol", "oxycodone", "spaceacillin", "peridaxon", "osteodaxon", "myelamine", "synthblood")
+
+/obj/item/weapon/reagent_containers/borghypo/Initialize()
+ . = ..()
+
+ for(var/T in reagent_ids)
+ reagent_volumes[T] = volume
+ var/datum/reagent/R = SSchemistry.chemical_reagents[T]
+ reagent_names += R.name
+
+ START_PROCESSING(SSobj, src)
+
+/obj/item/weapon/reagent_containers/borghypo/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/item/weapon/reagent_containers/borghypo/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg+
+ if(++charge_tick < recharge_time)
+ return 0
+ charge_tick = 0
+
+ if(isrobot(loc))
+ var/mob/living/silicon/robot/R = loc
+ if(R && R.cell)
+ for(var/T in reagent_ids)
+ if(reagent_volumes[T] < volume)
+ R.cell.use(charge_cost)
+ reagent_volumes[T] = min(reagent_volumes[T] + 5, volume)
+ return 1
+
+/obj/item/weapon/reagent_containers/borghypo/attack(var/mob/living/M, var/mob/user)
+ if(!istype(M))
+ return
+
+ if(!reagent_volumes[reagent_ids[mode]])
+ to_chat(user, "The injector is empty.")
+ return
+
+ var/mob/living/carbon/human/H = M
+ if(istype(H))
+ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
+ if(!affected)
+ to_chat(user, "\The [H] is missing that limb!")
+ return
+ /* since synths have oil/coolant streams now, it only makes sense that you should be able to inject stuff. preserved for posterity.
+ else if(affected.robotic >= ORGAN_ROBOT)
+ to_chat(user, "You cannot inject a robotic limb.")
+ return
+ */
+
+ if(M.can_inject(user, 1, ignore_thickness = bypass_protection))
+ to_chat(user, "You inject [M] with the injector.")
+ to_chat(M, "You feel a tiny prick!")
+
+ if(M.reagents)
+ var/t = min(amount_per_transfer_from_this, reagent_volumes[reagent_ids[mode]])
+ M.reagents.add_reagent(reagent_ids[mode], t)
+ reagent_volumes[reagent_ids[mode]] -= t
+ add_attack_logs(user, M, "Borg injected with [reagent_ids[mode]]")
+ to_chat(user, "[t] units injected. [reagent_volumes[reagent_ids[mode]]] units remaining.")
+ return
+
+/obj/item/weapon/reagent_containers/borghypo/attack_self(mob/user as mob) //Change the mode
+ var/t = ""
+ for(var/i = 1 to reagent_ids.len)
+ if(t)
+ t += ", "
+ if(mode == i)
+ t += "[reagent_names[i]]"
+ else
+ t += "[reagent_names[i]]"
+ t = "Available reagents: [t]."
+ to_chat(user,t)
+
+ return
+
+/obj/item/weapon/reagent_containers/borghypo/Topic(var/href, var/list/href_list)
+ if(href_list["reagent"])
+ var/t = reagent_ids.Find(href_list["reagent"])
+ if(t)
+ playsound(src, 'sound/effects/pop.ogg', 50, 0)
+ mode = t
+ var/datum/reagent/R = SSchemistry.chemical_reagents[reagent_ids[mode]]
+ to_chat(usr, "Synthesizer is now producing '[R.name]'.")
+
+/obj/item/weapon/reagent_containers/borghypo/examine(mob/user)
+ . = ..()
+ if(get_dist(user, src) <= 2)
+ var/datum/reagent/R = SSchemistry.chemical_reagents[reagent_ids[mode]]
+ . += "It is currently producing [R.name] and has [reagent_volumes[reagent_ids[mode]]] out of [volume] units left."
+
+/obj/item/weapon/reagent_containers/borghypo/service
+ name = "cyborg drink synthesizer"
+ desc = "A portable drink dispencer."
+ icon = 'icons/obj/drinks.dmi'
+ icon_state = "shaker"
+ charge_cost = 20
+ recharge_time = 3
+ volume = 60
+ possible_transfer_amounts = list(5, 10, 20, 30)
+ reagent_ids = list("ale", "cider", "beer", "berryjuice", "bitters", "coffee", "cognac", "cola", "dr_gibb", "egg", "gin", "gingerale", "hot_coco", "ice", "icetea", "kahlua", "lemonjuice", "lemon_lime", "limejuice", "mead", "milk", "mint", "orangejuice", "rum", "sake", "sodawater", "soymilk", "space_up", "spacemountainwind", "specialwhiskey", "sugar", "tea", "tequilla", "tomatojuice", "tonic", "vermouth", "vodka", "water", "watermelonjuice", "whiskey", "wine")
+
+/obj/item/weapon/reagent_containers/borghypo/service/attack(var/mob/M, var/mob/user)
+ return
+
+/obj/item/weapon/reagent_containers/borghypo/service/afterattack(var/obj/target, var/mob/user, var/proximity)
+ if(!proximity)
+ return
+
+ if(!target.is_open_container() || !target.reagents)
+ return
+
+ if(!reagent_volumes[reagent_ids[mode]])
+ to_chat(user, "[src] is out of this reagent, give it some time to refill.")
+ return
+
+ if(!target.reagents.get_free_space())
+ to_chat(user, "[target] is full.")
+ return
+
+ var/t = min(amount_per_transfer_from_this, reagent_volumes[reagent_ids[mode]])
+ target.reagents.add_reagent(reagent_ids[mode], t)
+ reagent_volumes[reagent_ids[mode]] -= t
+ to_chat(user, "You transfer [t] units of the solution to [target].")
+ return
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index e674d2493e..b32deb21a3 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -42,9 +42,11 @@
if(!affected)
to_chat(user, "\The [H] is missing that limb!")
return
+ /* since synths have oil/coolant streams now, it only makes sense that you should be able to inject stuff. preserved for posterity.
else if(affected.robotic >= ORGAN_ROBOT)
to_chat(user, "You cannot inject a robotic limb.")
return
+ */
if(!H.stat)
if(H != user)
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index f7c1ffc615..5875d7f407 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -169,9 +169,11 @@
if(!affected)
to_chat(user, "\The [H] is missing that limb!")
return
+ /* since synths have oil/coolant streams now, it only makes sense that you should be able to inject stuff. preserved for posterity.
else if(affected.robotic >= ORGAN_ROBOT)
to_chat(user, "You cannot inject a robotic limb.")
return
+ */
var/cycle_time = injtime*0.33 //33% of the time slept between 5u doses
var/warmup_time = 0 //0 for containers
diff --git a/config/example/config.txt b/config/example/config.txt
index 76adb8bd56..dca21e1d4c 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -536,3 +536,6 @@ ENABLE_NIGHT_SHIFTS
# ALLOW_BYOND_LINKS
# ALLOW_DISCORD_LINKS
ALLOW_URL_LINKS
+
+# Control which submaps are loaded for the Dynamic Engine system
+ENGINE_MAP Supermatter Engine,Edison's Bane
diff --git a/html/changelogs/Killian - synth injections.yml b/html/changelogs/Killian - synth injections.yml
new file mode 100644
index 0000000000..3f32aa9aac
--- /dev/null
+++ b/html/changelogs/Killian - synth injections.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Killian
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "You can now inject reagents directly into a synth's 'blood' stream using syringes and hypos (inc. borg hypos). Taking oil/coolant samples is still impossible."
diff --git a/html/changelogs/Mechoid - distil4chem.yml b/html/changelogs/Mechoid - distil4chem.yml
new file mode 100644
index 0000000000..13b193984e
--- /dev/null
+++ b/html/changelogs/Mechoid - distil4chem.yml
@@ -0,0 +1,38 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Mechoid
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Added Distillery to Chemistry, beside the Grinder."
+ - rscadd: "Added distilling recipe for Synthetic Plasma, which acts as a blood-restoration of 1.2 units per synthplas. Also orderable in cargo."
+ - tweak: "Moves wrapper, spacecleaner, and labeller from the grinder table to the Chem locker."
diff --git a/html/changelogs/splintergp - hailermasks.yml b/html/changelogs/splintergp - hailermasks.yml
new file mode 100644
index 0000000000..d69f84d5b1
--- /dev/null
+++ b/html/changelogs/splintergp - hailermasks.yml
@@ -0,0 +1,37 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: SplinterGP
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Adds new hailer masks with quotes with sound, allowing you to use a hailer on a face mask to attach a security hailer into one."
+ - soundadd: "Adds new sound effects for hailer face masks."
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index 5555d0e1ad..88f6dbf028 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/items/lefthand_magic.dmi b/icons/mob/items/lefthand_magic.dmi
new file mode 100644
index 0000000000..11552b79ff
Binary files /dev/null and b/icons/mob/items/lefthand_magic.dmi differ
diff --git a/icons/mob/items/lefthand_melee.dmi b/icons/mob/items/lefthand_melee.dmi
index fa92a768f3..6a128a9e57 100644
Binary files a/icons/mob/items/lefthand_melee.dmi and b/icons/mob/items/lefthand_melee.dmi differ
diff --git a/icons/mob/items/righthand_magic.dmi b/icons/mob/items/righthand_magic.dmi
new file mode 100644
index 0000000000..490deebcf4
Binary files /dev/null and b/icons/mob/items/righthand_magic.dmi differ
diff --git a/icons/mob/items/righthand_melee.dmi b/icons/mob/items/righthand_melee.dmi
index 916f610112..12f370d048 100644
Binary files a/icons/mob/items/righthand_melee.dmi and b/icons/mob/items/righthand_melee.dmi differ
diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi
index 0fe183dd90..5761446f43 100644
Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ
diff --git a/icons/mob/species/seromi/masks.dmi b/icons/mob/species/seromi/masks.dmi
index 83493f851a..afe787be11 100644
Binary files a/icons/mob/species/seromi/masks.dmi and b/icons/mob/species/seromi/masks.dmi differ
diff --git a/icons/mob/species/tajaran/mask.dmi b/icons/mob/species/tajaran/mask.dmi
index 0b68e98a67..15f0bf0fe9 100644
Binary files a/icons/mob/species/tajaran/mask.dmi and b/icons/mob/species/tajaran/mask.dmi differ
diff --git a/icons/mob/species/vox/masks.dmi b/icons/mob/species/vox/masks.dmi
index 6afaa10c22..29b7d76ef9 100644
Binary files a/icons/mob/species/vox/masks.dmi and b/icons/mob/species/vox/masks.dmi differ
diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi
index 195662d14b..88fa471cfd 100644
Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ
diff --git a/icons/obj/gun2.dmi b/icons/obj/gun2.dmi
index 38a4148c20..a5c13c95c4 100644
Binary files a/icons/obj/gun2.dmi and b/icons/obj/gun2.dmi differ
diff --git a/icons/obj/machines/drone_fab.dmi b/icons/obj/machines/drone_fab.dmi
index 066b51c258..2bbef003b8 100644
Binary files a/icons/obj/machines/drone_fab.dmi and b/icons/obj/machines/drone_fab.dmi differ
diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi
index 40cec418bc..cb79babe03 100644
Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ
diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi
index b7d095f87a..0878311519 100644
Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ
diff --git a/maps/southern_cross/southern_cross-1.dmm b/maps/southern_cross/southern_cross-1.dmm
index 9ead71a710..4eee56489e 100644
--- a/maps/southern_cross/southern_cross-1.dmm
+++ b/maps/southern_cross/southern_cross-1.dmm
@@ -6736,7 +6736,7 @@
"cDl" = (/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/paleblue/border{dir = 8},/obj/effect/floor_decal/borderfloorwhite/corner2{dir = 10},/obj/effect/floor_decal/corner/paleblue/bordercorner2{dir = 10},/turf/simulated/floor/tiled/white,/area/medical/foyer)
"cDm" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/tiled/white,/area/medical/foyer)
"cDn" = (/obj/structure/bed/chair{dir = 8},/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/paleblue/border{dir = 4},/obj/effect/floor_decal/borderfloorwhite/corner2{dir = 5},/obj/effect/floor_decal/corner/paleblue/bordercorner2{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/foyer)
-"cDo" = (/obj/structure/table/glass,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; name = "Chemistry Cleaner"},/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/beige/border{dir = 8},/turf/simulated/floor/tiled/white,/area/medical/chemistry)
+"cDo" = (/obj/structure/table/glass,/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/beige/border{dir = 8},/obj/machinery/portable_atmospherics/powered/reagent_distillery,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/simulated/floor/tiled/white,/area/medical/chemistry)
"cDp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/white,/area/medical/chemistry)
"cDq" = (/obj/structure/closet/secure_closet/chemical,/obj/item/weapon/storage/box/pillbottles,/obj/machinery/alarm{dir = 8; pixel_x = 22},/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/beige/border{dir = 4},/obj/item/weapon/storage/box/syringes,/obj/item/weapon/tool/screwdriver,/turf/simulated/floor/tiled/white,/area/medical/chemistry)
"cDr" = (/obj/structure/bed/chair/wheelchair,/obj/item/device/radio/intercom/department/medbay{dir = 4; pixel_x = -21},/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/paleblue/border{dir = 8},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage)
@@ -6824,7 +6824,7 @@
"cEV" = (/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/structure/table/glass,/obj/machinery/light,/obj/effect/floor_decal/borderfloorwhite/corner{dir = 8},/obj/effect/floor_decal/corner/beige/bordercorner{dir = 8},/turf/simulated/floor/tiled/white,/area/medical/chemistry)
"cEW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/segment,/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 8},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/chemistry)
"cEX" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/camera/network/medbay{c_tag = "MED - Chemistry"; dir = 1},/obj/effect/floor_decal/borderfloorwhite/corner,/obj/effect/floor_decal/corner/beige/bordercorner,/turf/simulated/floor/tiled/white,/area/medical/chemistry)
-"cEY" = (/obj/structure/closet/wardrobe/chemistry_white,/obj/item/device/radio/headset/headset_med,/obj/machinery/power/apc{name = "south bump"; pixel_y = -24},/obj/machinery/light_switch{pixel_x = 11; pixel_y = -24},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/item/weapon/storage/box/pillbottles,/obj/effect/floor_decal/borderfloorwhite{dir = 6},/obj/effect/floor_decal/corner/beige/border{dir = 6},/turf/simulated/floor/tiled/white,/area/medical/chemistry)
+"cEY" = (/obj/structure/closet/wardrobe/chemistry_white,/obj/item/device/radio/headset/headset_med,/obj/machinery/power/apc{name = "south bump"; pixel_y = -24},/obj/machinery/light_switch{pixel_x = 11; pixel_y = -24},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/item/weapon/storage/box/pillbottles,/obj/effect/floor_decal/borderfloorwhite{dir = 6},/obj/effect/floor_decal/corner/beige/border{dir = 6},/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; name = "Chemistry Cleaner"},/obj/item/weapon/hand_labeler,/obj/item/weapon/packageWrap,/turf/simulated/floor/tiled/white,/area/medical/chemistry)
"cEZ" = (/obj/machinery/alarm{dir = 4; pixel_x = -22},/turf/simulated/floor,/area/maintenance/cargo)
"cFa" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 8},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage)
"cFb" = (/obj/structure/table/standard,/obj/item/roller,/obj/item/roller{pixel_y = 8},/obj/item/roller{pixel_y = 16},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/light_switch{name = "light switch "; pixel_x = 36},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/disposalpipe/segment,/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/paleblue/border{dir = 4},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage)
diff --git a/polaris.dme b/polaris.dme
index e0272c5c80..946bd6db04 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -1593,6 +1593,7 @@
#include "code\modules\clothing\masks\boxing.dm"
#include "code\modules\clothing\masks\breath.dm"
#include "code\modules\clothing\masks\gasmask.dm"
+#include "code\modules\clothing\masks\hailer.dm"
#include "code\modules\clothing\masks\miscellaneous.dm"
#include "code\modules\clothing\masks\voice.dm"
#include "code\modules\clothing\rings\material.dm"
@@ -2629,6 +2630,7 @@
#include "code\modules\projectiles\brokenguns\projectile.dm"
#include "code\modules\projectiles\guns\energy.dm"
#include "code\modules\projectiles\guns\launcher.dm"
+#include "code\modules\projectiles\guns\magic.dm"
#include "code\modules\projectiles\guns\modular_guns.dm"
#include "code\modules\projectiles\guns\projectile.dm"
#include "code\modules\projectiles\guns\vox.dm"
@@ -2645,6 +2647,7 @@
#include "code\modules\projectiles\guns\launcher\pneumatic.dm"
#include "code\modules\projectiles\guns\launcher\rocket.dm"
#include "code\modules\projectiles\guns\launcher\syringe_gun.dm"
+#include "code\modules\projectiles\guns\magic\fireball.dm"
#include "code\modules\projectiles\guns\magnetic\bore.dm"
#include "code\modules\projectiles\guns\magnetic\gasthrower.dm"
#include "code\modules\projectiles\guns\magnetic\magnetic.dm"
@@ -2670,6 +2673,7 @@
#include "code\modules\projectiles\projectile\explosive.dm"
#include "code\modules\projectiles\projectile\force.dm"
#include "code\modules\projectiles\projectile\hook.dm"
+#include "code\modules\projectiles\projectile\magic.dm"
#include "code\modules\projectiles\projectile\magnetic.dm"
#include "code\modules\projectiles\projectile\pellets.dm"
#include "code\modules\projectiles\projectile\scatter.dm"
@@ -2729,7 +2733,7 @@
#include "code\modules\reagents\hoses\hose.dm"
#include "code\modules\reagents\hoses\hose_connector.dm"
#include "code\modules\reagents\reagent_containers\blood_pack.dm"
-#include "code\modules\reagents\reagent_containers\borghydro.dm"
+#include "code\modules\reagents\reagent_containers\borghypo.dm"
#include "code\modules\reagents\reagent_containers\dropper.dm"
#include "code\modules\reagents\reagent_containers\glass.dm"
#include "code\modules\reagents\reagent_containers\hypospray.dm"
diff --git a/sound/voice/complionator/asshole.ogg b/sound/voice/complionator/asshole.ogg
new file mode 100644
index 0000000000..9ee40942c4
Binary files /dev/null and b/sound/voice/complionator/asshole.ogg differ
diff --git a/sound/voice/complionator/bash.ogg b/sound/voice/complionator/bash.ogg
new file mode 100644
index 0000000000..e79a2cd1e1
Binary files /dev/null and b/sound/voice/complionator/bash.ogg differ
diff --git a/sound/voice/complionator/bobby.ogg b/sound/voice/complionator/bobby.ogg
new file mode 100644
index 0000000000..4bc8f8df94
Binary files /dev/null and b/sound/voice/complionator/bobby.ogg differ
diff --git a/sound/voice/complionator/compliance.ogg b/sound/voice/complionator/compliance.ogg
new file mode 100644
index 0000000000..fcfb608202
Binary files /dev/null and b/sound/voice/complionator/compliance.ogg differ
diff --git a/sound/voice/complionator/dontmove.ogg b/sound/voice/complionator/dontmove.ogg
new file mode 100644
index 0000000000..09cefea9d6
Binary files /dev/null and b/sound/voice/complionator/dontmove.ogg differ
diff --git a/sound/voice/complionator/dredd.ogg b/sound/voice/complionator/dredd.ogg
new file mode 100644
index 0000000000..ab434dbfde
Binary files /dev/null and b/sound/voice/complionator/dredd.ogg differ
diff --git a/sound/voice/complionator/floor.ogg b/sound/voice/complionator/floor.ogg
new file mode 100644
index 0000000000..996dd0f54a
Binary files /dev/null and b/sound/voice/complionator/floor.ogg differ
diff --git a/sound/voice/complionator/freeze.ogg b/sound/voice/complionator/freeze.ogg
new file mode 100644
index 0000000000..d4224be839
Binary files /dev/null and b/sound/voice/complionator/freeze.ogg differ
diff --git a/sound/voice/complionator/god.ogg b/sound/voice/complionator/god.ogg
new file mode 100644
index 0000000000..8e1a54d268
Binary files /dev/null and b/sound/voice/complionator/god.ogg differ
diff --git a/sound/voice/complionator/halt.ogg b/sound/voice/complionator/halt.ogg
new file mode 100644
index 0000000000..81563b928f
Binary files /dev/null and b/sound/voice/complionator/halt.ogg differ
diff --git a/sound/voice/complionator/harry.ogg b/sound/voice/complionator/harry.ogg
new file mode 100644
index 0000000000..eae132675e
Binary files /dev/null and b/sound/voice/complionator/harry.ogg differ
diff --git a/sound/voice/complionator/imperial.ogg b/sound/voice/complionator/imperial.ogg
new file mode 100644
index 0000000000..903cf1197c
Binary files /dev/null and b/sound/voice/complionator/imperial.ogg differ
diff --git a/sound/voice/complionator/justice.ogg b/sound/voice/complionator/justice.ogg
new file mode 100644
index 0000000000..2aef43b150
Binary files /dev/null and b/sound/voice/complionator/justice.ogg differ
diff --git a/sound/voice/complionator/robocop.ogg b/sound/voice/complionator/robocop.ogg
new file mode 100644
index 0000000000..4dec421ed0
Binary files /dev/null and b/sound/voice/complionator/robocop.ogg differ
diff --git a/sound/voice/complionator/running.ogg b/sound/voice/complionator/running.ogg
new file mode 100644
index 0000000000..3711ce6ccf
Binary files /dev/null and b/sound/voice/complionator/running.ogg differ
diff --git a/sound/voice/complionator/shutup.ogg b/sound/voice/complionator/shutup.ogg
new file mode 100644
index 0000000000..ecd2b02015
Binary files /dev/null and b/sound/voice/complionator/shutup.ogg differ
diff --git a/sound/voice/complionator/stfu.ogg b/sound/voice/complionator/stfu.ogg
new file mode 100644
index 0000000000..9c3fcf675b
Binary files /dev/null and b/sound/voice/complionator/stfu.ogg differ
diff --git a/sound/voice/complionator/super.ogg b/sound/voice/complionator/super.ogg
new file mode 100644
index 0000000000..8bae406dea
Binary files /dev/null and b/sound/voice/complionator/super.ogg differ
diff --git a/tgui/.eslintrc.yml b/tgui/.eslintrc.yml
index 9fd4db9fd2..fe11b8a34c 100644
--- a/tgui/.eslintrc.yml
+++ b/tgui/.eslintrc.yml
@@ -369,7 +369,7 @@ rules:
# max-depth: error
## Enforce a maximum line length
max-len: [error, {
- code: 80,
+ code: 120, # Bump to 140 if this is still too in the way
## Ignore imports
ignorePattern: '^(import\s.+\sfrom\s|.*require\()',
ignoreUrls: true,
diff --git a/tgui/docs/tutorial-and-examples.md b/tgui/docs/tutorial-and-examples.md
index 00d5546d91..c0e32ebf8e 100644
--- a/tgui/docs/tutorial-and-examples.md
+++ b/tgui/docs/tutorial-and-examples.md
@@ -77,7 +77,7 @@ input. The input's `action` and `params` are passed to the proc.
```dm
/obj/machinery/my_machine/tgui_act(action, params)
if(..())
- return
+ return TRUE
if(action == "change_color")
var/new_color = params["color"]
if(!(color in allowed_coors))
@@ -305,7 +305,7 @@ upon code review):
/obj/copypasta/tgui_act(action, params)
if(..())
- return
+ return TRUE
switch(action)
if("copypasta")
var/newvar = params["var"]
diff --git a/tgui/packages/common/string.js b/tgui/packages/common/string.js
index d05dbfb6fc..a3da0885a1 100644
--- a/tgui/packages/common/string.js
+++ b/tgui/packages/common/string.js
@@ -91,7 +91,7 @@ export const toTitleCase = str => {
return str;
}
// Handle string
- const WORDS_UPPER = ['Id', 'Tv'];
+ const WORDS_UPPER = ['Id', 'Tv', 'Rcd'];
const WORDS_LOWER = [
'A', 'An', 'And', 'As', 'At', 'But', 'By', 'For', 'For', 'From', 'In',
'Into', 'Near', 'Nor', 'Of', 'On', 'Onto', 'Or', 'The', 'To', 'With',
@@ -105,7 +105,7 @@ export const toTitleCase = str => {
}
for (let word of WORDS_UPPER) {
const regex = new RegExp('\\b' + word + '\\b', 'g');
- currentStr = currentStr.replace(regex, str => str.toLowerCase());
+ currentStr = currentStr.replace(regex, str => str.toUpperCase());
}
return currentStr;
};
@@ -120,7 +120,7 @@ export const decodeHtmlEntities = str => {
if (!str) {
return str;
}
- const translate_re = /&(nbsp|amp|quot|lt|gt|apos);/g;
+ const translate_re = /&(nbsp|amp|quot|lt|gt|apos|trade);/g;
const translate = {
nbsp: ' ',
amp: '&',
@@ -128,6 +128,7 @@ export const decodeHtmlEntities = str => {
lt: '<',
gt: '>',
apos: '\'',
+ trade: 'â„¢',
};
return str
// Newline tags
diff --git a/tgui/packages/tgui/components/Box.js b/tgui/packages/tgui/components/Box.js
index 7e8aca3c12..a53fa1e8fd 100644
--- a/tgui/packages/tgui/components/Box.js
+++ b/tgui/packages/tgui/components/Box.js
@@ -73,7 +73,10 @@ const mapColorPropTo = attrName => (style, value) => {
const styleMapperByPropName = {
// Direct mapping
+ display: mapRawPropTo('display'),
position: mapRawPropTo('position'),
+ float: mapRawPropTo('float'),
+ clear: mapRawPropTo('clear'),
overflow: mapRawPropTo('overflow'),
overflowX: mapRawPropTo('overflow-x'),
overflowY: mapRawPropTo('overflow-y'),
@@ -99,6 +102,8 @@ const styleMapperByPropName = {
opacity: mapRawPropTo('opacity'),
textAlign: mapRawPropTo('text-align'),
verticalAlign: mapRawPropTo('vertical-align'),
+ textTransform: mapRawPropTo('text-transform'),
+ wordWrap: mapRawPropTo('word-wrap'),
// Boolean props
inline: mapBooleanPropTo('display', 'inline-block'),
bold: mapBooleanPropTo('font-weight', 'bold'),
@@ -136,6 +141,18 @@ const styleMapperByPropName = {
color: mapColorPropTo('color'),
textColor: mapColorPropTo('color'),
backgroundColor: mapColorPropTo('background-color'),
+ // Flex props
+ order: mapRawPropTo('order'),
+ flexDirection: mapRawPropTo('flex-direction'),
+ flexGrow: mapRawPropTo('flex-grow'),
+ flexShrink: mapRawPropTo('flex-shrink'),
+ flexWrap: mapRawPropTo('flex-wrap'),
+ flexFlow: mapRawPropTo('flex-flow'),
+ flexBasis: mapRawPropTo('flex-basis'),
+ flex: mapRawPropTo('flex'),
+ alignItems: mapRawPropTo('align-items'),
+ justifyContent: mapRawPropTo('justify-content'),
+ alignSelf: mapRawPropTo('align-self'),
// Utility props
fillPositionedParent: (style, value) => {
if (value) {
@@ -151,6 +168,9 @@ const styleMapperByPropName = {
export const computeBoxProps = props => {
const computedProps = {};
const computedStyles = {};
+ if (props.double) {
+ computedStyles["transform"] = "scale(2);";
+ }
// Compute props
for (let propName of Object.keys(props)) {
if (propName === 'style') {
diff --git a/tgui/packages/tgui/components/Button.js b/tgui/packages/tgui/components/Button.js
index bb8b4bcbf0..ced7bd13bd 100644
--- a/tgui/packages/tgui/components/Button.js
+++ b/tgui/packages/tgui/components/Button.js
@@ -25,10 +25,13 @@ export const Button = props => {
selected,
tooltip,
tooltipPosition,
+ tooltipScale,
ellipsis,
content,
iconRotation,
iconSpin,
+ iconColor,
+ iconSize,
children,
onclick,
onClick,
@@ -89,14 +92,17 @@ export const Button = props => {
| + | min2 | +min1 | +max1 | +max2 | +
| + + {getGasLabel(threshold.name)} + + | + {threshold.settings.map(setting => ( +
+ |
+ ))}
+
| + {area.name} + | +
+ |
+ + {area.load} + | +
+ |
+
+ |
+
+ |
+