"
@@ -361,7 +361,7 @@
if(!load_mob(AM))
return
else
- AM.loc = src
+ AM.forceMove(src)
load = AM
mode = BOT_IDLE
@@ -377,12 +377,11 @@
return FALSE
/mob/living/simple_animal/bot/mulebot/post_buckle_mob(mob/living/M)
- if(M in buckled_mobs) //post buckling
- M.pixel_y = initial(M.pixel_y) + 9
- if(M.layer < layer)
- M.layer = layer + 0.01
+ M.pixel_y = initial(M.pixel_y) + 9
+ if(M.layer < layer)
+ M.layer = layer + 0.01
- else //post unbuckling
+/mob/living/simple_animal/bot/mulebot/post_unbuckle_mob(mob/living/M)
load = null
M.layer = initial(M.layer)
M.pixel_y = initial(M.pixel_y)
@@ -401,7 +400,7 @@
unbuckle_all_mobs()
if(load)
- load.loc = loc
+ load.forceMove(loc)
load.pixel_y = initial(load.pixel_y)
load.layer = initial(load.layer)
load.plane = initial(load.plane)
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index 82eae37f82..b8b2621875 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -20,6 +20,7 @@
window_name = "Automatic Security Unit v1.6"
allow_pai = 0
data_hud_type = DATA_HUD_SECURITY_ADVANCED
+ path_image_color = "#FF0000"
var/mob/living/carbon/target
var/oldtarget_name
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 0e6ecf1672..8046daf55d 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -360,8 +360,14 @@
..()
/datum/action/innate/seek_master/Activate()
- if(!SSticker.mode.eldergod)
- the_construct.master = GLOB.blood_target
+ var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult)
+ if(!C)
+ return
+ var/datum/objective/eldergod/summon_objective = locate() in C.cult_team.objectives
+
+ if(summon_objective.check_completion())
+ the_construct.master = C.cult_team.blood_target
+
if(!the_construct.master)
to_chat(the_construct, "
You have no master to seek!")
the_construct.seeking = FALSE
diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm
index 5405ee03c6..bb6794a36a 100644
--- a/code/modules/mob/living/simple_animal/damage_procs.dm
+++ b/code/modules/mob/living/simple_animal/damage_procs.dm
@@ -2,7 +2,7 @@
/mob/living/simple_animal/proc/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
if(!forced && (status_flags & GODMODE))
return FALSE
- bruteloss = Clamp(bruteloss + amount, 0, maxHealth)
+ bruteloss = CLAMP(bruteloss + amount, 0, maxHealth)
if(updating_health)
updatehealth()
return amount
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index a333f22c38..42d38e40a3 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -9,8 +9,8 @@
gender = MALE
speak = list("Meow!", "Esp!", "Purr!", "HSSSSS")
speak_emote = list("purrs", "meows")
- emote_hear = list("meows", "mews")
- emote_see = list("shakes its head", "shivers")
+ emote_hear = list("meows.", "mews.")
+ emote_see = list("shakes its head.", "shivers.")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
@@ -22,7 +22,7 @@
unsuitable_atmos_damage = 1
animal_species = /mob/living/simple_animal/pet/cat
childtype = list(/mob/living/simple_animal/pet/cat/kitten)
- butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/organ/ears/cat = 1, /obj/item/organ/tail/cat = 1)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index 6ea4d2ef94..adc88c5633 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -135,7 +135,7 @@
switch(remove_from)
if("head")
if(inventory_head)
- inventory_head.loc = src.loc
+ inventory_head.forceMove(drop_location())
inventory_head = null
update_corgi_fluff()
regenerate_icons()
@@ -144,7 +144,7 @@
return
if("back")
if(inventory_back)
- inventory_back.loc = src.loc
+ inventory_back.forceMove(drop_location())
inventory_back = null
update_corgi_fluff()
regenerate_icons()
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index f7ee4ac29a..ea159a5749 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -48,6 +48,7 @@
faction = list("neutral","silicon","turret")
dextrous = TRUE
dextrous_hud_type = /datum/hud/dextrous/drone
+ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
var/staticChoice = "static"
var/list/staticChoices = list("static", "blank", "letter", "animal")
var/picked = FALSE //Have we picked our visual appearence (+ colour if applicable)
@@ -57,7 +58,6 @@
"1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone.\n"+\
"2. You may not harm any being, regardless of intent or circumstance.\n"+\
"3. Your goals are to build, maintain, repair, improve, and provide power to the best of your abilities, You must never actively work against these goals."
- var/light_on = 0
var/heavy_emp_damage = 25 //Amount of damage sustained if hit by a heavy EMP pulse
var/alarms = list("Atmosphere" = list(), "Fire" = list(), "Power" = list())
var/obj/item/internal_storage //Drones can store one item, of any size/type in their body
@@ -102,8 +102,8 @@
else
verbs -= /mob/living/simple_animal/drone/verb/toggle_statics
- var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC]
- diag_hud.add_to_hud(src)
+ for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
+ diag_hud.add_to_hud(src)
/mob/living/simple_animal/drone/med_hud_set_health()
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
index 9900133723..c0a57e3739 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
@@ -13,7 +13,6 @@
desc = "A shell of a maintenance drone, an expendable robot built to perform station repairs."
icon = 'icons/mob/drone.dmi'
icon_state = "drone_maint_hat"//yes reuse the _hat state.
- origin_tech = "programming=2;biotech=4"
var/drone_type = /mob/living/simple_animal/drone //Type of drone that will be spawned
/obj/item/drone_shell/New()
@@ -68,7 +67,7 @@
L.dropItemToGround(src)
contents -= drone
- drone.loc = get_turf(src)
+ drone.forceMove(drop_location())
drone.reset_perspective()
drone.setDir(SOUTH )//Looks better
drone.visible_message("
[drone] uncurls!")
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
index a19a6abeb3..1105940f22 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
@@ -34,7 +34,8 @@
/mob/living/simple_animal/drone/syndrone/Initialize()
. = ..()
- internal_storage.hidden_uplink.telecrystals = 10
+ GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage)
+ hidden_uplink.telecrystals = 10
/mob/living/simple_animal/drone/syndrone/Login()
..()
@@ -47,7 +48,8 @@
/mob/living/simple_animal/drone/syndrone/badass/Initialize()
. = ..()
- internal_storage.hidden_uplink.telecrystals = 30
+ GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage)
+ hidden_uplink.telecrystals = 30
var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(src)
W.implant(src)
@@ -146,12 +148,11 @@
qdel(access_card) //we don't have free access
access_card = null
verbs -= /mob/living/simple_animal/drone/verb/check_laws
- verbs -= /mob/living/simple_animal/drone/verb/toggle_light
verbs -= /mob/living/simple_animal/drone/verb/drone_ping
/mob/living/simple_animal/drone/cogscarab/Login()
..()
- add_servant_of_ratvar(src, TRUE)
+ add_servant_of_ratvar(src, TRUE, GLOB.servants_active)
to_chat(src,"
You yourself are one of these servants, and will be able to utilize almost anything they can[GLOB.ratvar_awakens ? "":", excluding a clockwork slab"].") // this can't go with flavortext because i'm assuming it requires them to be ratvar'd
/mob/living/simple_animal/drone/cogscarab/binarycheck()
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm
index 378a5cce2d..aac87829bc 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm
@@ -58,7 +58,7 @@
I.pulledby.stop_pulling()
I.screen_loc = null // will get moved if inventory is visible
- I.loc = src
+ I.forceMove(src)
I.layer = ABOVE_HUD_LAYER
I.plane = ABOVE_HUD_PLANE
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/say.dm b/code/modules/mob/living/simple_animal/friendly/drone/say.dm
index fb0c0c0614..16bf370f02 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/say.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/say.dm
@@ -3,14 +3,6 @@
/////////////
//Drone speach
-/mob/living/simple_animal/drone/handle_inherent_channels(message, message_mode)
- if(message_mode == MODE_BINARY)
- drone_chat(message)
- return 1
- else
- ..()
-
-
/mob/living/simple_animal/drone/get_spans()
return ..() | SPAN_ROBOT
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm
index 49faea14b3..86bc3b69e5 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm
@@ -11,23 +11,7 @@
to_chat(src, "
Drone Laws")
to_chat(src, laws)
-
-/mob/living/simple_animal/drone/verb/toggle_light()
- set category = "Drone"
- set name = "Toggle drone light"
- if(stat == DEAD)
- to_chat(src, "
There's no light in your life... by that I mean you're dead.")
- return
- if(light_on)
- set_light(0)
- else
- set_light(8)
-
- light_on = !light_on
-
- to_chat(src, "
Your light is now [light_on ? "on" : "off"].")
-
/mob/living/simple_animal/drone/verb/drone_ping()
set category = "Drone"
set name = "Drone ping"
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 85ec19bfb9..809681ed6b 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -110,3 +110,7 @@
eatverb = "devours"
list_reagents = list("nutriment" = 3, "vitamin" = 2)
foodtype = GROSS | MEAT | RAW
+ grind_results = list("blood" = 20, "liquidgibs" = 5)
+
+/obj/item/reagent_containers/food/snacks/deadmouse/on_grind()
+ reagents.clear_reagents()
diff --git a/code/modules/mob/living/simple_animal/friendly/sloth.dm b/code/modules/mob/living/simple_animal/friendly/sloth.dm
index 7519951876..6f19632e88 100644
--- a/code/modules/mob/living/simple_animal/friendly/sloth.dm
+++ b/code/modules/mob/living/simple_animal/friendly/sloth.dm
@@ -19,10 +19,10 @@
melee_damage_upper = 18
health = 50
maxHealth = 50
- speed = 2
+ speed = 10
+ glide_size = 2
devourable = TRUE
-
//Cargo Sloth
/mob/living/simple_animal/sloth/paperwork
name = "Paperwork"
@@ -39,4 +39,4 @@
icon_dead = "cool_sloth_dead"
gender = FEMALE
butcher_results = list(/obj/item/toy/spinningtoy = 1)
- gold_core_spawnable = NO_SPAWN
\ No newline at end of file
+ gold_core_spawnable = NO_SPAWN
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index 222369dd55..577eba1858 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -257,7 +257,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
I.pulledby.stop_pulling()
I.screen_loc = null // will get moved if inventory is visible
- I.loc = src
+ I.forceMove(src)
I.equipped(src, slot)
I.layer = ABOVE_HUD_LAYER
I.plane = ABOVE_HUD_PLANE
diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
index 1353293484..54ef51ad5a 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
@@ -54,7 +54,7 @@
/obj/guardian_bomb/proc/disguise(obj/A)
- A.loc = src
+ A.forceMove(src)
stored_obj = A
opacity = A.opacity
anchored = A.anchored
diff --git a/code/modules/mob/living/simple_animal/hostile/creature.dm b/code/modules/mob/living/simple_animal/hostile/creature.dm
index 12da922fc0..bba37f94af 100644
--- a/code/modules/mob/living/simple_animal/hostile/creature.dm
+++ b/code/modules/mob/living/simple_animal/hostile/creature.dm
@@ -1,18 +1,18 @@
-/mob/living/simple_animal/hostile/creature
- name = "creature"
- desc = "A sanity-destroying otherthing."
- icon_state = "otherthing"
- icon_living = "otherthing"
- icon_dead = "otherthing-dead"
- health = 80
- maxHealth = 80
- obj_damage = 100
- melee_damage_lower = 25
- melee_damage_upper = 50
- attacktext = "chomps"
- attack_sound = 'sound/weapons/bite.ogg'
- faction = list("creature")
- speak_emote = list("screams")
- gold_core_spawnable = HOSTILE_SPAWN
- atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- minbodytemp = 0
+/mob/living/simple_animal/hostile/creature
+ name = "creature"
+ desc = "A sanity-destroying otherthing."
+ icon_state = "otherthing"
+ icon_living = "otherthing"
+ icon_dead = "otherthing-dead"
+ health = 80
+ maxHealth = 80
+ obj_damage = 100
+ melee_damage_lower = 25
+ melee_damage_upper = 50
+ attacktext = "chomps"
+ attack_sound = 'sound/weapons/bite.ogg'
+ faction = list("creature")
+ speak_emote = list("screams")
+ gold_core_spawnable = HOSTILE_SPAWN
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 0
diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm
index 4e302b3d55..a42a79e02a 100644
--- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm
+++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm
@@ -32,7 +32,7 @@
else if(mind) // Let's make this a feature
egg.origin = mind
for(var/obj/item/organ/I in src)
- I.loc = egg
+ I.forceMove(egg)
visible_message("
[src] plants something in [victim]'s flesh!", \
"
We inject our egg into [victim]'s body!")
egg_lain = 1
@@ -53,7 +53,6 @@
/obj/item/organ/body_egg/changeling_egg
name = "changeling egg"
desc = "Twitching and disgusting."
- origin_tech = "biotech=7" // You need to be really lucky to obtain it.
var/datum/mind/origin
var/time
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index a977338008..c6f0f6a91c 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -79,10 +79,10 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/bubblegum/Life()
..()
- move_to_delay = Clamp((health/maxHealth) * 10, 5, 10)
+ move_to_delay = CLAMP((health/maxHealth) * 10, 5, 10)
/mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire()
- anger_modifier = Clamp(((maxHealth - health)/60),0,20)
+ anger_modifier = CLAMP(((maxHealth - health)/60),0,20)
if(charging)
return
ranged_cooldown = world.time + ranged_cooldown_time
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index 58e3e0837b..d47385efc3 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -57,7 +57,7 @@ Difficulty: Very Hard
L.dust()
/mob/living/simple_animal/hostile/megafauna/colossus/OpenFire()
- anger_modifier = Clamp(((maxHealth - health)/50),0,20)
+ anger_modifier = CLAMP(((maxHealth - health)/50),0,20)
ranged_cooldown = world.time + 120
if(enrage(target))
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
index 7f12e684e8..724e4fc5c7 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
@@ -101,7 +101,7 @@ Difficulty: Medium
/mob/living/simple_animal/hostile/megafauna/dragon/OpenFire()
if(swooping)
return
- anger_modifier = Clamp(((maxHealth - health)/50),0,20)
+ anger_modifier = CLAMP(((maxHealth - health)/50),0,20)
ranged_cooldown = world.time + ranged_cooldown_time
if(prob(15 + anger_modifier) && !client)
@@ -227,10 +227,10 @@ Difficulty: Medium
//ensure swoop direction continuity.
if(negative)
- if(IsInRange(x, initial_x + 1, initial_x + DRAKE_SWOOP_DIRECTION_CHANGE_RANGE))
+ if(ISINRANGE(x, initial_x + 1, initial_x + DRAKE_SWOOP_DIRECTION_CHANGE_RANGE))
negative = FALSE
else
- if(IsInRange(x, initial_x - DRAKE_SWOOP_DIRECTION_CHANGE_RANGE, initial_x - 1))
+ if(ISINRANGE(x, initial_x - DRAKE_SWOOP_DIRECTION_CHANGE_RANGE, initial_x - 1))
negative = TRUE
new /obj/effect/temp_visual/dragon_flight/end(loc, negative)
new /obj/effect/temp_visual/dragon_swoop(loc)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index 02fb81a1ed..8dc1780e5e 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -187,7 +187,7 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/calculate_rage() //how angry we are overall
did_reset = FALSE //oh hey we're doing SOMETHING, clearly we might need to heal if we recall
- anger_modifier = Clamp(((maxHealth - health) / 42),0,50)
+ anger_modifier = CLAMP(((maxHealth - health) / 42),0,50)
burst_range = initial(burst_range) + round(anger_modifier * 0.08)
beam_range = initial(beam_range) + round(anger_modifier * 0.12)
diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm
index dd96c87371..670d571d4d 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimic.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm
@@ -43,7 +43,7 @@
. = ..()
if(mapload) //eat shit
for(var/obj/item/I in loc)
- I.loc = src
+ I.forceMove(src)
/mob/living/simple_animal/hostile/mimic/crate/DestroyPathToTarget()
..()
@@ -89,7 +89,7 @@
var/obj/structure/closet/crate/C = new(get_turf(src))
// Put loot in crate
for(var/obj/O in src)
- O.loc = C
+ O.forceMove(C)
..()
GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/cable, /obj/structure/window))
@@ -116,7 +116,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
/mob/living/simple_animal/hostile/mimic/copy/death()
for(var/atom/movable/M in src)
- M.loc = get_turf(src)
+ M.forceMove(get_turf(src))
..()
/mob/living/simple_animal/hostile/mimic/copy/ListTargets()
@@ -136,7 +136,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(obj/O, mob/living/user, destroy_original = 0)
if(destroy_original || CheckObject(O))
- O.loc = src
+ O.forceMove(src)
name = O.name
desc = O.desc
icon = O.icon
@@ -249,15 +249,15 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
..()
else
visible_message("
The [src] clears a jam!")
- Pewgun.chambered.loc = loc //rip revolver immersions, blame shotgun snowflake procs
+ Pewgun.chambered.forceMove(loc) //rip revolver immersions, blame shotgun snowflake procs
Pewgun.chambered = null
if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len)
Pewgun.chambered = Pewgun.magazine.get_round(0)
- Pewgun.chambered.loc = Pewgun
+ Pewgun.chambered.forceMove(Pewgun)
Pewgun.update_icon()
else if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len) //only true for pumpguns i think
Pewgun.chambered = Pewgun.magazine.get_round(0)
- Pewgun.chambered.loc = Pewgun
+ Pewgun.chambered.forceMove(Pewgun)
visible_message("
The [src] cocks itself!")
else
ranged = 0 //BANZAIIII
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
index a9627c7e2d..7a3a85c35b 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
@@ -137,8 +137,9 @@
. = ..()
if(.)
var/mob/living/L = target
- L.adjust_fire_stacks(0.1)
- L.IgniteMob()
+ if (istype(L))
+ L.adjust_fire_stacks(0.1)
+ L.IgniteMob()
/obj/item/projectile/temp/basilisk/icewing
damage = 5
diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
new file mode 100644
index 0000000000..67a565f945
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -0,0 +1,103 @@
+/mob/living/simple_animal/hostile/netherworld
+ name = "creature"
+ desc = "A sanity-destroying otherthing from the netherworld."
+ icon_state = "otherthing"
+ icon_living = "otherthing"
+ icon_dead = "otherthing-dead"
+ health = 80
+ maxHealth = 80
+ obj_damage = 100
+ melee_damage_lower = 25
+ melee_damage_upper = 50
+ attacktext = "slashes"
+ attack_sound = 'sound/weapons/bladeslice.ogg'
+ faction = list("creature")
+ speak_emote = list("screams")
+ gold_core_spawnable = HOSTILE_SPAWN
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 0
+ faction = list("nether")
+
+/mob/living/simple_animal/hostile/netherworld/migo
+ name = "mi-go"
+ desc = "A pinkish, fungoid crustacean-like creature with numerous pairs of clawed appendages and a head covered with waving antennae."
+ speak_emote = list("screams", "clicks", "chitters", "barks", "moans", "growls", "meows", "reverberates", "roars", "squeaks", "rattles", "exclaims", "yells", "remarks", "mumbles", "jabbers", "stutters", "seethes")
+ icon_state = "mi-go"
+ icon_living = "mi-go"
+ icon_dead = "mi-go-dead"
+ attacktext = "lacerates"
+ speed = -0.5
+ var/static/list/migo_sounds
+ deathmessage = "wails as its form turns into a pulpy mush."
+ death_sound = 'sound/voice/hiss6.ogg'
+
+/mob/living/simple_animal/hostile/netherworld/migo/Initialize()
+ . = ..()
+ migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/bcreep.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/mpatchedup.ogg', 'sound/voice/mfeelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg', 'sound/misc/disco.ogg', 'sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshot_silenced.ogg', 'sound/weapons/gunshot2.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/machines/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/poweroff.ogg', 'sound/ai/radiation.ogg', 'sound/ai/shuttlecalled.ogg', 'sound/ai/shuttledock.ogg', 'sound/ai/shuttlerecalled.ogg', 'sound/ai/aimalf.ogg') //hahahaha fuck you code divers
+
+/mob/living/simple_animal/hostile/netherworld/migo/say(message)
+ ..()
+ if(stat)
+ return
+ var/chosen_sound = pick(migo_sounds)
+ playsound(src, chosen_sound, 100, TRUE)
+
+/mob/living/simple_animal/hostile/netherworld/migo/Life()
+ ..()
+ if(stat)
+ return
+ if(prob(10))
+ var/chosen_sound = pick(migo_sounds)
+ playsound(src, chosen_sound, 100, TRUE)
+
+/mob/living/simple_animal/hostile/netherworld/blankbody
+ name = "blank body"
+ desc = "This looks human enough, but its flesh has an ashy texture, and it's face is featureless save an eerie smile."
+ icon_state = "blank-body"
+ icon_living = "blank-body"
+ icon_dead = "blank-dead"
+ gold_core_spawnable = NO_SPAWN
+ health = 100
+ maxHealth = 100
+ melee_damage_lower = 5
+ melee_damage_upper = 10
+ attacktext = "punches"
+ deathmessage = "falls apart into a fine dust."
+
+/mob/living/simple_animal/hostile/spawner/nether
+ name = "netherworld link"
+ desc = "A direct link to another dimension full of creatures not very happy to see you.
Entering the link would be a very bad idea."
+ icon_state = "nether"
+ icon_living = "nether"
+ health = 50
+ maxHealth = 50
+ spawn_time = 50 //5 seconds
+ max_mobs = 15
+ icon = 'icons/mob/nest.dmi'
+ spawn_text = "crawls through"
+ mob_type = /mob/living/simple_animal/hostile/netherworld/migo
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ faction = list("nether")
+ deathmessage = "shatters into oblivion."
+ del_on_death = TRUE
+
+/mob/living/simple_animal/hostile/spawner/nether/attack_hand(mob/user)
+ user.visible_message("
[user] is violently pulled into the link!", \
+ "
Touching the portal, you are quickly pulled through into a world of unimaginable horror!")
+ contents.Add(user)
+
+/mob/living/simple_animal/hostile/spawner/nether/Life()
+ ..()
+ var/list/C = src.get_contents()
+ for(var/mob/living/M in C)
+ if(M)
+ playsound(src, 'sound/magic/demon_consume.ogg', 50, 1)
+ M.adjustBruteLoss(60)
+ new /obj/effect/gibspawner/human(get_turf(M))
+ if(M.stat == DEAD)
+ var/mob/living/simple_animal/hostile/netherworld/blankbody/blank
+ blank = new(loc)
+ blank.name = "[M]"
+ blank.desc = "It's [M], but their flesh has an ashy texture, and their face is featureless save an eerie smile."
+ src.visible_message("
[M] reemerges from the link!")
+ qdel(M)
diff --git a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm
index 97dd430a12..5737f5f4b2 100644
--- a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm
+++ b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm
@@ -2,10 +2,10 @@
/mob/living/simple_animal/hostile/asteroid/fugu
name = "wumborian fugu"
desc = "The wumborian fugu rapidly increases its body mass in order to ward off its prey. Great care should be taken to avoid it while it's in this state as it is nearly invincible, but it cannot maintain its form forever."
- icon = 'icons/mob/lavaland/lavaland_monsters.dmi'
- icon_state = "Fugu"
- icon_living = "Fugu"
- icon_aggro = "Fugu"
+ icon = 'icons/mob/lavaland/64x64megafauna.dmi'
+ icon_state = "Fugu0"
+ icon_living = "Fugu0"
+ icon_aggro = "Fugu0"
icon_dead = "Fugu_dead"
icon_gib = "syndicate_gib"
mouse_opacity = MOUSE_OPACITY_OPAQUE
@@ -16,6 +16,7 @@
speed = 0
maxHealth = 50
health = 50
+ pixel_x = -16
harm_intent_damage = 5
obj_damage = 0
melee_damage_lower = 0
@@ -30,13 +31,23 @@
gold_core_spawnable = HOSTILE_SPAWN
var/wumbo = 0
var/inflate_cooldown = 0
+ var/datum/action/innate/fugu/expand/E
loot = list(/obj/item/asteroid/fugu_gland{layer = ABOVE_MOB_LAYER})
+/mob/living/simple_animal/hostile/asteroid/fugu/Initialize()
+ . = ..()
+ E = new
+ E.Grant(src)
+
+/mob/living/simple_animal/hostile/asteroid/fugu/Destroy()
+ QDEL_NULL(E)
+ return ..()
+
/mob/living/simple_animal/hostile/asteroid/fugu/Life()
if(!wumbo)
inflate_cooldown = max((inflate_cooldown - 1), 0)
if(target && AIStatus == AI_ON)
- Inflate()
+ E.Activate()
..()
/mob/living/simple_animal/hostile/asteroid/fugu/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
@@ -46,42 +57,47 @@
/mob/living/simple_animal/hostile/asteroid/fugu/Aggro()
..()
- Inflate()
+ E.Activate()
-/mob/living/simple_animal/hostile/asteroid/fugu/verb/Inflate()
- set name = "Inflate"
- set category = "Fugu"
- set desc = "Temporarily increases your size, and makes you significantly more dangerous and tough."
- if(wumbo)
- to_chat(src, "
You're already inflated.")
+/datum/action/innate/fugu
+ icon_icon = 'icons/mob/actions/actions_animal.dmi'
+
+/datum/action/innate/fugu/expand
+ name = "Inflate"
+ desc = "Temporarily increases your size, and makes you significantly more dangerous and tough! Do not bully the fugu!"
+ button_icon_state = "expand"
+
+/datum/action/innate/fugu/expand/Activate()
+ var/mob/living/simple_animal/hostile/asteroid/fugu/F = owner
+ if(F.wumbo)
+ to_chat(F, "
YOU'RE ALREADY WUMBO!")
return
- if(inflate_cooldown)
- to_chat(src, "
We need time to gather our strength.")
+ if(F.inflate_cooldown)
+ to_chat(F, "
You need time to gather your strength.")
return
- if(buffed)
- to_chat(src, "
Something is interfering with our growth.")
+ if(F.buffed)
+ to_chat(F, "
Something is interfering with your growth.")
return
- wumbo = 1
- icon_state = "Fugu_big"
- obj_damage = 60
- melee_damage_lower = 15
- melee_damage_upper = 20
- harm_intent_damage = 0
- throw_message = "is absorbed by the girth of the"
- retreat_distance = null
- minimum_distance = 1
- move_to_delay = 6
- transform *= 2
- environment_smash = ENVIRONMENT_SMASH_WALLS
- mob_size = MOB_SIZE_LARGE
- speed = 1
- addtimer(CALLBACK(src, .proc/Deflate), 100)
+ F.wumbo = 1
+ F.icon_state = "Fugu1"
+ F.obj_damage = 60
+ F.melee_damage_lower = 15
+ F.melee_damage_upper = 20
+ F.harm_intent_damage = 0
+ F.throw_message = "is absorbed by the girth of the"
+ F.retreat_distance = null
+ F.minimum_distance = 1
+ F.move_to_delay = 6
+ F.environment_smash = ENVIRONMENT_SMASH_WALLS
+ F.mob_size = MOB_SIZE_LARGE
+ F.speed = 1
+ addtimer(CALLBACK(F, /mob/living/simple_animal/hostile/asteroid/fugu/proc/Deflate), 100)
/mob/living/simple_animal/hostile/asteroid/fugu/proc/Deflate()
if(wumbo)
walk(src, 0)
wumbo = 0
- icon_state = "Fugu"
+ icon_state = "Fugu0"
obj_damage = 0
melee_damage_lower = 0
melee_damage_upper = 0
@@ -90,7 +106,6 @@
retreat_distance = 9
minimum_distance = 9
move_to_delay = 2
- transform /= 2
inflate_cooldown = 4
environment_smash = ENVIRONMENT_SMASH_NONE
mob_size = MOB_SIZE_SMALL
@@ -108,7 +123,6 @@
flags_1 = NOBLUDGEON_1
w_class = WEIGHT_CLASS_NORMAL
layer = MOB_LAYER
- origin_tech = "biotech=6"
var/list/banned_mobs
/obj/item/asteroid/fugu_gland/afterattack(atom/target, mob/user, proximity_flag)
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index ffbeb1f503..e4de22b2a7 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -127,7 +127,7 @@
/mob/living/simple_animal/parrot/death(gibbed)
if(held_item)
- held_item.loc = src.loc
+ held_item.forceMove(drop_location())
held_item = null
walk(src,0)
@@ -213,7 +213,7 @@
src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
else
src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
- ears.loc = src.loc
+ ears.forceMove(src.loc)
ears = null
for(var/possible_phrase in speak)
if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys)
@@ -504,7 +504,7 @@
else //This should ensure that we only grab the item we want, and make sure it's not already collected on our perch
if(!parrot_perch || parrot_interest.loc != parrot_perch.loc)
held_item = parrot_interest
- parrot_interest.loc = src
+ parrot_interest.forceMove(src)
visible_message("[src] grabs [held_item]!", "
You grab [held_item]!", "
You hear the sounds of wings flapping furiously.")
parrot_interest = null
@@ -526,7 +526,7 @@
return
if(Adjacent(parrot_perch))
- src.loc = parrot_perch.loc
+ forceMove(parrot_perch.loc)
drop_held_item()
parrot_state = PARROT_PERCH
icon_state = icon_sit
@@ -702,7 +702,7 @@
continue
held_item = I
- I.loc = src
+ I.forceMove(src)
visible_message("[src] grabs [held_item]!", "
You grab [held_item]!", "
You hear the sounds of wings flapping furiously.")
return held_item
@@ -777,7 +777,7 @@
if(!drop_gently)
if(istype(held_item, /obj/item/grenade))
var/obj/item/grenade/G = held_item
- G.loc = src.loc
+ G.forceMove(drop_location())
G.prime()
to_chat(src, "You let go of [held_item]!")
held_item = null
@@ -785,7 +785,7 @@
to_chat(src, "You drop [held_item].")
- held_item.loc = src.loc
+ held_item.forceMove(drop_location())
held_item = null
return 1
@@ -801,7 +801,7 @@
for(var/atom/movable/AM in view(src,1))
for(var/perch_path in desired_perches)
if(istype(AM, perch_path))
- src.loc = AM.loc
+ src.forceMove(AM.loc)
icon_state = icon_sit
return
to_chat(src, "
There is no perch nearby to sit on!")
@@ -838,7 +838,7 @@
/mob/living/simple_animal/parrot/proc/perch_on_human(mob/living/carbon/human/H)
if(!H)
return
- loc = get_turf(H)
+ forceMove(get_turf(H))
H.buckle_mob(src, force=1)
pixel_y = 9
pixel_x = pick(-8,8) //pick left or right shoulder
@@ -962,7 +962,7 @@
playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 75, TRUE)
var/mob/living/simple_animal/parrot/clock_hawk/H = new(loc)
H.setDir(dir)
- dust()
+ qdel(src)
/mob/living/simple_animal/parrot/Poly/ghost
name = "The Ghost of Poly"
@@ -996,7 +996,7 @@
return
var/datum/disease/parrot_possession/P = new
P.parrot = src
- loc = H
+ forceMove(H)
H.ForceContractDisease(P)
parrot_interest = null
H.visible_message("
[src] dive bombs into [H]'s chest and vanishes!", "
[src] dive bombs into your chest, vanishing! This can't be good!")
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 72a1ec84c1..4c5b94f2e3 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -111,7 +111,7 @@
/mob/living/simple_animal/updatehealth()
..()
- health = Clamp(health, 0, maxHealth)
+ health = CLAMP(health, 0, maxHealth)
/mob/living/simple_animal/update_stat()
if(status_flags & GODMODE)
@@ -521,37 +521,26 @@
client.screen |= l_hand
//ANIMAL RIDING
-/mob/living/simple_animal/unbuckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1)
- if(riding_datum)
- riding_datum.restore_position(buckled_mob)
- . = ..()
-
/mob/living/simple_animal/user_buckle_mob(mob/living/M, mob/user)
+ GET_COMPONENT(riding_datum, /datum/component/riding)
if(riding_datum)
if(user.incapacitated())
return
for(var/atom/movable/A in get_turf(src))
if(A != src && A != M && A.density)
return
- M.loc = get_turf(src)
- riding_datum.handle_vehicle_offsets()
- riding_datum.ridden = src
+ M.forceMove(get_turf(src))
+ return ..()
/mob/living/simple_animal/relaymove(mob/user, direction)
+ GET_COMPONENT(riding_datum, /datum/component/riding)
if(tame && riding_datum)
riding_datum.handle_ride(user, direction)
-/mob/living/simple_animal/Moved()
- . = ..()
- if(riding_datum)
- riding_datum.on_vehicle_move()
-
-
/mob/living/simple_animal/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1)
. = ..()
- riding_datum = new/datum/riding/animal
-
+ LoadComponent(/datum/component/riding)
/mob/living/simple_animal/proc/toggle_ai(togglestatus)
if (AIStatus != togglestatus)
diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm
index e7e71bf091..9654f91b6c 100644
--- a/code/modules/mob/living/simple_animal/slime/powers.dm
+++ b/code/modules/mob/living/simple_animal/slime/powers.dm
@@ -166,7 +166,7 @@
step_away(M,src)
M.Friends = Friends.Copy()
babies += M
- M.mutation_chance = Clamp(mutation_chance+(rand(5,-5)),0,100)
+ M.mutation_chance = CLAMP(mutation_chance+(rand(5,-5)),0,100)
SSblackbox.record_feedback("tally", "slime_babies_born", 1, M.colour)
var/mob/living/simple_animal/slime/new_slime = pick(babies)
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index bed14bdff4..a91db7f177 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -26,20 +26,28 @@
reload_fullscreen() // Reload any fullscreen overlays this mob has.
- if(ckey in GLOB.deadmins)
- verbs += /client/proc/readmin
-
add_click_catcher()
sync_mind()
client.sethotkeys() //set mob specific hotkeys
+ //Reload alternate appearances
+ for(var/v in GLOB.active_alternate_appearances)
+ if(!v)
+ continue
+ var/datum/atom_hud/alternate_appearance/AA = v
+ AA.onNewMob(src)
+
update_client_colour()
if(client)
client.click_intercept = null
- client.change_view(world.view) // Resets the client.view in case it was changed.
+ client.change_view(CONFIG_GET(string/default_view)) // Resets the client.view in case it was changed.
+
+ if(client.player_details.player_actions.len)
+ for(var/datum/action/A in client.player_details.player_actions)
+ A.Grant(src)
if(!GLOB.individual_log_list[ckey])
GLOB.individual_log_list[ckey] = logging
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 9a9b161e51..b19af6342c 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -42,9 +42,14 @@
/atom/proc/prepare_huds()
hud_list = list()
for(var/hud in hud_possible)
- var/image/I = image('icons/mob/hud.dmi', src, "")
- I.appearance_flags = RESET_COLOR|RESET_TRANSFORM
- hud_list[hud] = I
+ var/hint = hud_possible[hud]
+ switch(hint)
+ if(HUD_LIST_LIST)
+ hud_list[hud] = list()
+ else
+ var/image/I = image('icons/mob/hud.dmi', src, "")
+ I.appearance_flags = RESET_COLOR|RESET_TRANSFORM
+ hud_list[hud] = I
/mob/proc/Cell()
set category = "Admin"
@@ -395,6 +400,7 @@
pulling = null
grab_state = 0
update_pull_hud_icon()
+
if(isliving(ex_pulled))
var/mob/living/L = ex_pulled
L.update_canmove()// mob gets up if it was lyng down in a chokehold
@@ -769,14 +775,14 @@
//Default buckling shift visual for mobs
/mob/post_buckle_mob(mob/living/M)
- if(M in buckled_mobs)//post buckling
- var/height = M.get_mob_buckling_height(src)
- M.pixel_y = initial(M.pixel_y) + height
- if(M.layer < layer)
- M.layer = layer + 0.1
- else //post unbuckling
- M.layer = initial(M.layer)
- M.pixel_y = initial(M.pixel_y)
+ var/height = M.get_mob_buckling_height(src)
+ M.pixel_y = initial(M.pixel_y) + height
+ if(M.layer < layer)
+ M.layer = layer + 0.1
+
+/mob/post_unbuckle_mob(mob/living/M)
+ M.layer = initial(M.layer)
+ M.pixel_y = initial(M.pixel_y)
//returns the height in pixel the mob should have when buckled to another mob.
/mob/proc/get_mob_buckling_height(mob/seat)
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 58cb82714e..edbf11654b 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -33,7 +33,6 @@
var/obj/machinery/machine = null
var/other_mobs = null
var/disabilities = 0 //Carbon
- var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc.
var/atom/movable/pulling = null
var/grab_state = 0
@@ -45,6 +44,7 @@
var/stuttering = 0 //Carbon
var/slurring = 0 //Carbon
var/cultslurring = 0 //Carbon
+ var/derpspeech = 0 //Carbon
var/real_name = null
var/spacewalk = FALSE
var/druggy = 0 //Carbon
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 3dc56c936b..747d589c05 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -363,7 +363,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
if(M.mind in SSticker.mode.cult)
return 2
if("nuclear")
- if(M.mind in SSticker.mode.syndicates)
+ if(M.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE))
return 2
if("changeling")
if(M.mind.has_antag_datum(/datum/antagonist/changeling,TRUE))
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 9885d1c4d6..94431a9a7c 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -107,7 +107,7 @@
return
mob.control_object.setDir(direct)
else
- mob.control_object.loc = get_step(mob.control_object,direct)
+ mob.control_object.forceMove(get_step(mob.control_object,direct))
return
#define MOVEMENT_DELAY_BUFFER 0.75
@@ -186,7 +186,7 @@
if(LAZYLEN(mob.user_movement_hooks))
for(var/obj/O in mob.user_movement_hooks)
O.intercept_user_move(direct, mob, n, oldloc)
-
+
var/atom/movable/P = mob.pulling
if(P && !ismob(P) && P.density)
mob.dir = turn(mob.dir, 180)
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index a396072b4f..1ee7f27452 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -19,7 +19,7 @@
/mob/proc/whisper(message, datum/language/language=null)
say(message, language) //only living mobs actually whisper, everything else just talks
-/mob/verb/me_verb(message as message)
+/mob/verb/me_verb(message as text)
set name = "Me"
set category = "IC"
@@ -27,8 +27,7 @@
to_chat(usr, "
Speech is currently admin-disabled.")
return
- var/list/replace_chars = list("\n"=" ","\t"=" ")
- message = copytext(sanitize(message, replace_chars), 1, (MAX_MESSAGE_LEN*2))
+ message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
usr.emote("me",1,message)
@@ -80,4 +79,4 @@
return 0
/mob/proc/lingcheck()
- return 0
+ return LINGHIVE_NONE
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 85a8ed5448..42a1ce725f 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -58,7 +58,6 @@
O.suiciding = suiciding
if(hellbound)
O.hellbound = hellbound
- O.loc = loc
O.a_intent = INTENT_HARM
//keep viruses?
@@ -79,6 +78,9 @@
O.setBrainLoss(getBrainLoss(), 0)
O.updatehealth()
O.radiation = radiation
+ for(var/T in get_traumas())
+ var/datum/brain_trauma/BT = T
+ O.gain_trauma(BT.type, BT.permanent)
//re-add implants to new mob
if (tr_flags & TR_KEEPIMPLANTS)
@@ -110,7 +112,7 @@
var/obj/item/bodypart/chest/torso = O.get_bodypart("chest")
if(cavity_object)
torso.cavity_item = cavity_object //cavity item is given to the new chest
- cavity_object.loc = O
+ cavity_object.forceMove(O)
for(var/missing_zone in missing_bodyparts_zones)
var/obj/item/bodypart/BP = O.get_bodypart(missing_zone)
@@ -217,8 +219,6 @@
if(hellbound)
O.hellbound = hellbound
- O.loc = loc
-
//keep viruses?
if (tr_flags & TR_KEEPVIRUS)
O.viruses = viruses
@@ -238,6 +238,9 @@
O.setBrainLoss(getBrainLoss(), 0)
O.updatehealth()
O.radiation = radiation
+ for(var/T in get_traumas())
+ var/datum/brain_trauma/BT = T
+ O.gain_trauma(BT.type, BT.permanent)
//re-add implants to new mob
if (tr_flags & TR_KEEPIMPLANTS)
@@ -270,7 +273,7 @@
var/obj/item/bodypart/chest/torso = get_bodypart("chest")
if(cavity_object)
torso.cavity_item = cavity_object //cavity item is given to the new chest
- cavity_object.loc = O
+ cavity_object.forceMove(O)
for(var/missing_zone in missing_bodyparts_zones)
var/obj/item/bodypart/BP = O.get_bodypart(missing_zone)
@@ -372,10 +375,7 @@
var/mob/living/silicon/robot/R = new /mob/living/silicon/robot(loc)
// cyborgs produced by Robotize get an automatic power cell
- R.cell = new(R)
- R.cell.maxcharge = 7500
- R.cell.charge = 7500
-
+ R.cell = new /obj/item/stock_parts/cell/high(R, 7500)
R.gender = gender
R.invisibility = 0
@@ -398,7 +398,6 @@
R.mmi.brainmob.real_name = real_name //the name of the brain inside the cyborg is the robotized human's name.
R.mmi.brainmob.name = real_name
- R.loc = loc
R.job = "Cyborg"
R.notify_ai(NEW_BORG)
diff --git a/code/modules/modular_computers/hardware/CPU.dm b/code/modules/modular_computers/hardware/CPU.dm
index b0c56ee0ba..38b7b5dec4 100644
--- a/code/modules/modular_computers/hardware/CPU.dm
+++ b/code/modules/modular_computers/hardware/CPU.dm
@@ -9,7 +9,6 @@
power_usage = 50
critical = 1
malfunction_probability = 1
- origin_tech = "programming=3;engineering=2"
var/max_idle_programs = 2 // 2 idle, + 1 active = 3 as said in description.
device_type = MC_CPU
@@ -23,7 +22,6 @@
w_class = WEIGHT_CLASS_TINY
power_usage = 25
max_idle_programs = 1
- origin_tech = "programming=2;engineering=2"
/obj/item/computer_hardware/processor_unit/photonic
name = "photonic processor board"
@@ -32,7 +30,6 @@
w_class = WEIGHT_CLASS_SMALL
power_usage = 250
max_idle_programs = 4
- origin_tech = "programming=5;engineering=4"
/obj/item/computer_hardware/processor_unit/photonic/small
name = "photonic microprocessor"
@@ -40,5 +37,4 @@
icon_state = "cpu_super"
w_class = WEIGHT_CLASS_TINY
power_usage = 75
- max_idle_programs = 2
- origin_tech = "programming=4;engineering=3"
\ No newline at end of file
+ max_idle_programs = 2
\ No newline at end of file
diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm
index edd78839c3..4dace2b4cf 100644
--- a/code/modules/modular_computers/hardware/ai_slot.dm
+++ b/code/modules/modular_computers/hardware/ai_slot.dm
@@ -4,7 +4,6 @@
power_usage = 100 //W
icon_state = "card_mini"
w_class = WEIGHT_CLASS_SMALL
- origin_tech = "programming=2"
device_type = MC_AI
var/obj/item/device/aicard/stored_card = null
diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm
index 6c3dac9b63..c6b96e3136 100644
--- a/code/modules/modular_computers/hardware/battery_module.dm
+++ b/code/modules/modular_computers/hardware/battery_module.dm
@@ -4,7 +4,6 @@
icon_state = "cell_con"
critical = 1
malfunction_probability = 1
- origin_tech = "powerstorage=1;engineering=1"
var/obj/item/stock_parts/cell/battery = null
device_type = MC_CELL
@@ -64,7 +63,6 @@
desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops."
icon = 'icons/obj/module.dmi'
icon_state = "cell_mini"
- origin_tech = "powerstorage=2;engineering=1"
w_class = WEIGHT_CLASS_TINY
maxcharge = 750
@@ -73,7 +71,6 @@
name = "advanced battery"
desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices."
icon_state = "cell"
- origin_tech = "powerstorage=2;engineering=2"
w_class = WEIGHT_CLASS_SMALL
maxcharge = 1500
@@ -81,7 +78,6 @@
name = "super battery"
desc = "An advanced power cell, often used in high-end laptops."
icon_state = "cell"
- origin_tech = "powerstorage=3;engineering=3"
w_class = WEIGHT_CLASS_SMALL
maxcharge = 2000
diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm
index caebfb447b..3d071c47aa 100644
--- a/code/modules/modular_computers/hardware/card_slot.dm
+++ b/code/modules/modular_computers/hardware/card_slot.dm
@@ -4,7 +4,6 @@
power_usage = 10 //W
icon_state = "card_mini"
w_class = WEIGHT_CLASS_TINY
- origin_tech = "programming=2"
device_type = MC_CARD
var/obj/item/card/id/stored_card = null
diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm
index 2ad1caa951..62d8ff5d86 100644
--- a/code/modules/modular_computers/hardware/hard_drive.dm
+++ b/code/modules/modular_computers/hardware/hard_drive.dm
@@ -5,7 +5,6 @@
icon_state = "harddisk_mini"
critical = 1
w_class = WEIGHT_CLASS_TINY
- origin_tech = "programming=1;engineering=1"
device_type = MC_HDD
var/max_capacity = 128
var/used_capacity = 0
@@ -130,7 +129,6 @@
name = "advanced hard disk drive"
desc = "A hybrid HDD, for use in higher grade computers where balance between power efficiency and capacity is desired."
max_capacity = 256
- origin_tech = "programming=2;engineering=2"
power_usage = 50 // Hybrid, medium capacity and medium power storage
icon_state = "harddisk_mini"
w_class = WEIGHT_CLASS_SMALL
@@ -139,7 +137,6 @@
name = "super hard disk drive"
desc = "A high capacity HDD, for use in cluster storage solutions where capacity is more important than power efficiency."
max_capacity = 512
- origin_tech = "programming=3;engineering=3"
power_usage = 100 // High-capacity but uses lots of power, shortening battery life. Best used with APC link.
icon_state = "harddisk_mini"
w_class = WEIGHT_CLASS_SMALL
@@ -148,7 +145,6 @@
name = "cluster hard disk drive"
desc = "A large storage cluster consisting of multiple HDDs for usage in dedicated storage systems."
power_usage = 500
- origin_tech = "programming=4;engineering=4"
max_capacity = 2048
icon_state = "harddisk"
w_class = WEIGHT_CLASS_NORMAL
@@ -158,7 +154,6 @@
name = "solid state drive"
desc = "An efficient SSD for portable devices."
power_usage = 10
- origin_tech = "programming=2;engineering=2"
max_capacity = 64
icon_state = "ssd_mini"
w_class = WEIGHT_CLASS_TINY
@@ -167,7 +162,6 @@
name = "micro solid state drive"
desc = "A highly efficient SSD chip for portable devices."
power_usage = 2
- origin_tech = "programming=1;engineering=1"
max_capacity = 32
icon_state = "ssd_micro"
w_class = WEIGHT_CLASS_TINY
\ No newline at end of file
diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm
index c6d507c4ed..216d55fbd8 100644
--- a/code/modules/modular_computers/hardware/network_card.dm
+++ b/code/modules/modular_computers/hardware/network_card.dm
@@ -2,7 +2,6 @@
name = "network card"
desc = "A basic wireless network card for usage with standard NTNet frequencies."
power_usage = 50
- origin_tech = "programming=2;engineering=1"
icon_state = "radio_mini"
var/identification_id = null // Identification ID. Technically MAC address of this device. Can't be changed by user.
var/identification_string = "" // Identification string, technically nickname seen in the network. Can be set by user.
@@ -65,7 +64,6 @@
name = "advanced network card"
desc = "An advanced network card for usage with standard NTNet frequencies. Its transmitter is strong enough to connect even off-station."
long_range = 1
- origin_tech = "programming=4;engineering=2"
power_usage = 100 // Better range but higher power usage.
icon_state = "radio"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
@@ -76,7 +74,6 @@
name = "wired network card"
desc = "An advanced network card for usage with standard NTNet frequencies. This one also supports wired connection."
ethernet = 1
- origin_tech = "programming=5;engineering=3"
power_usage = 100 // Better range but higher power usage.
icon_state = "net_wired"
w_class = WEIGHT_CLASS_NORMAL
diff --git a/code/modules/modular_computers/hardware/portable_disk.dm b/code/modules/modular_computers/hardware/portable_disk.dm
index 47430f80ac..d5aa404f58 100644
--- a/code/modules/modular_computers/hardware/portable_disk.dm
+++ b/code/modules/modular_computers/hardware/portable_disk.dm
@@ -6,7 +6,6 @@
w_class = WEIGHT_CLASS_TINY
critical = 0
max_capacity = 16
- origin_tech = "programming=1"
device_type = MC_SDD
/obj/item/computer_hardware/hard_drive/portable/on_install(obj/item/device/modular_computer/M, mob/living/user = null)
@@ -24,7 +23,6 @@
power_usage = 20
icon_state = "datadisk5"
max_capacity = 64
- origin_tech = "programming=2"
/obj/item/computer_hardware/hard_drive/portable/super
name = "super data disk"
@@ -32,4 +30,3 @@
power_usage = 40
icon_state = "datadisk3"
max_capacity = 256
- origin_tech = "programming=4"
diff --git a/code/modules/modular_computers/hardware/printer.dm b/code/modules/modular_computers/hardware/printer.dm
index 27eb050655..b000c353b0 100644
--- a/code/modules/modular_computers/hardware/printer.dm
+++ b/code/modules/modular_computers/hardware/printer.dm
@@ -2,7 +2,6 @@
name = "printer"
desc = "Computer-integrated printer with paper recycling module."
power_usage = 100
- origin_tech = "programming=2;engineering=2"
icon_state = "printer"
w_class = WEIGHT_CLASS_NORMAL
device_type = MC_PRINT
diff --git a/code/modules/modular_computers/hardware/recharger.dm b/code/modules/modular_computers/hardware/recharger.dm
index 7096233d3a..f1c7578aa7 100644
--- a/code/modules/modular_computers/hardware/recharger.dm
+++ b/code/modules/modular_computers/hardware/recharger.dm
@@ -28,7 +28,6 @@
desc = "A device that wirelessly recharges connected device from nearby APC."
icon_state = "charger_APC"
w_class = WEIGHT_CLASS_SMALL // Can't be installed into tablets/PDAs
- origin_tech = "programming=2;engineering=2;powerstorage=3"
/obj/item/computer_hardware/recharger/APC/use_power(amount, charging=0)
if(ismachinery(holder.physical))
@@ -52,7 +51,6 @@
desc = "A power connector that recharges connected device from nearby power wire. Incompatible with portable computers."
icon_state = "charger_wire"
w_class = WEIGHT_CLASS_NORMAL
- origin_tech = "engineering=2;powerstorage=1"
/obj/item/computer_hardware/recharger/wired/can_install(obj/item/device/modular_computer/M, mob/living/user = null)
if(ismachinery(M.physical) && M.physical.anchored)
diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm
index 1656a43505..b26d01d880 100644
--- a/code/modules/ninja/ninja_event.dm
+++ b/code/modules/ninja/ninja_event.dm
@@ -95,7 +95,7 @@ Contents:
var/datum/mind/Mind = new /datum/mind(key)
Mind.assigned_role = "Space Ninja"
Mind.special_role = "Space Ninja"
- SSticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list.
+ SSticker.mode.traitors |= Mind //Adds them to current traitor list. TODO : Remove this in admin tools refeactor.
return Mind
diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm
index 6cf03d1c10..c49ca072e8 100644
--- a/code/modules/ninja/suit/gloves.dm
+++ b/code/modules/ninja/suit/gloves.dm
@@ -63,9 +63,9 @@
if(isnum(.)) //Numerical values of drained handle their feedback here, Alpha values handle it themselves (Research hacking)
if(.)
- to_chat(H, "
Gained [DisplayPower(.)] of power from [A].")
+ to_chat(H, "
Gained [DisplayEnergy(.)] of energy from [A].")
else
- to_chat(H, "
\The [A] has run dry of power, you must find another source!")
+ to_chat(H, "
\The [A] has run dry of energy, you must find another source!")
else
. = 0 //as to not cancel attack_hand()
diff --git a/code/modules/ninja/suit/ninjaDrainAct.dm b/code/modules/ninja/suit/ninjaDrainAct.dm
index 4679b5ffbd..cdae56571f 100644
--- a/code/modules/ninja/suit/ninjaDrainAct.dm
+++ b/code/modules/ninja/suit/ninjaDrainAct.dm
@@ -10,7 +10,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
*/
-//Needs to return the amount drained from the atom, if no drain on a power object, return 0, otherwise, return a define.
+//Needs to return the amount drained from the atom, if no drain on a power object, return FALSE, otherwise, return a define.
/atom/proc/ninjadrain_act()
return INVALID_DRAIN
@@ -130,26 +130,15 @@ They *could* go in their appropriate files, but this is supposed to be modular
to_chat(H, "
Hacking \the [src]...")
AI_notify_hack()
- if(files && files.known_tech.len)
- for(var/datum/tech/current_data in S.stored_research)
- to_chat(H, "
Checking \the [current_data.name] database.")
- if(do_after(H, S.s_delay, target = src) && G.candrain && src)
- for(var/id in files.known_tech)
- var/datum/tech/analyzing_data = files.known_tech[id]
- if(current_data.id == analyzing_data.id)
- if(analyzing_data.level > current_data.level)
- to_chat(H, "
Database: UPDATED.")
- current_data.level = analyzing_data.level
- . = DRAIN_RD_HACKED
- break//Move on to next.
- else
- break//Otherwise, quit processing.
-
+ if(stored_research)
+ to_chat(H, "
Copying files...")
+ if(do_after(H, S.s_delay, target = src) && G.candrain && src)
+ stored_research.copy_research_to(S.stored_research)
to_chat(H, "
Data analyzed. Process finished.")
//RD SERVER//
//Shamelessly copypasted from above, since these two used to be the same proc, but with MANY colon operators
-/obj/machinery/r_n_d/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
+/obj/machinery/rnd/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
if(!S || !H || !G)
return INVALID_DRAIN
@@ -158,21 +147,10 @@ They *could* go in their appropriate files, but this is supposed to be modular
to_chat(H, "
Hacking \the [src]...")
AI_notify_hack()
- if(files && files.known_tech.len)
- for(var/datum/tech/current_data in S.stored_research)
- to_chat(H, "
Checking \the [current_data.name] database.")
- if(do_after(H, S.s_delay, target = src) && G.candrain && src)
- for(var/id in files.known_tech)
- var/datum/tech/analyzing_data = files.known_tech[id]
- if(current_data.id == analyzing_data.id)
- if(analyzing_data.level > current_data.level)
- to_chat(H, "
Database: UPDATED.")
- current_data.level = analyzing_data.level
- . = DRAIN_RD_HACKED
- break//Move on to next.
- else
- break//Otherwise, quit processing.
-
+ if(stored_research)
+ to_chat(H, "
Copying files...")
+ if(do_after(H, S.s_delay, target = src) && G.candrain && src)
+ stored_research.copy_research_to(S.stored_research)
to_chat(H, "
Data analyzed. Process finished.")
diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm
index 1dcfed99c0..82c7dfa0bf 100644
--- a/code/modules/ninja/suit/suit.dm
+++ b/code/modules/ninja/suit/suit.dm
@@ -28,7 +28,7 @@ Contents:
var/mob/living/carbon/human/affecting = null
var/obj/item/stock_parts/cell/cell
var/datum/effect_system/spark_spread/spark_system
- var/list/stored_research = list()//For stealing station research.
+ var/datum/techweb/stored_research
var/obj/item/disk/tech_disk/t_disk//To copy design onto disk.
var/obj/item/energy_katana/energyKatana //For teleporting the katana back to the ninja (It's an ability)
@@ -62,14 +62,12 @@ Contents:
..()
//Spark Init
- spark_system = new()
+ spark_system = new
spark_system.set_up(5, 0, src)
spark_system.attach(src)
//Research Init
stored_research = new()
- for(var/T in subtypesof(/datum/tech))//Store up on research.
- stored_research += new T(src)
//Cell Init
cell = new/obj/item/stock_parts/cell/high
@@ -97,7 +95,7 @@ Contents:
//This proc prevents the suit from being taken off.
/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/human/H)
if(!istype(H))
- return 0
+ return FALSE
if(!is_ninja(H))
to_chat(H, "
fTaL RRoR: 382200-*#00CDE RED\nUNAU?HORIZED US DETC???eD\nCoMMNCING SUB-R0U?IN3 13...\nTRMInATING U-U-USR...")
H.gib()
@@ -152,7 +150,7 @@ Contents:
..()
if(s_initialized)
if(user == affecting)
- to_chat(user, "All systems operational. Current energy capacity:
[DisplayPower(cell.charge)].")
+ to_chat(user, "All systems operational. Current energy capacity:
[DisplayEnergy(cell.charge)].")
to_chat(user, "The CLOAK-tech device is
[s_active?"active":"inactive"].")
to_chat(user, "There are
[s_bombs] smoke bomb\s remaining.")
to_chat(user, "There are
[a_boost] adrenaline booster\s remaining.")
diff --git a/code/modules/ninja/suit/suit_attackby.dm b/code/modules/ninja/suit/suit_attackby.dm
index ce75fd6ed3..d185d596a3 100644
--- a/code/modules/ninja/suit/suit_attackby.dm
+++ b/code/modules/ninja/suit/suit_attackby.dm
@@ -32,26 +32,12 @@
else if(istype(I, /obj/item/disk/tech_disk))//If it's a data disk, we want to copy the research on to the suit.
var/obj/item/disk/tech_disk/TD = I
- var/has_research = FALSE
- for(var/V in TD.tech_stored)
- if(V)
- has_research = TRUE
- break
+ var/has_research = 0
if(has_research)//If it has something on it.
- to_chat(U, "
Research information detected, processing...")
+ to_chat(U, "Research information detected, processing...")
if(do_after(U,s_delay, target = src))
- for(var/V1 in 1 to TD.max_tech_stored)
- var/datum/tech/new_data = TD.tech_stored[V1]
- TD.tech_stored[V1] = null
- if(!new_data)
- continue
- for(var/V2 in stored_research)
- var/datum/tech/current_data = V2
- if(current_data.id == new_data.id)
- current_data.level = max(current_data.level, new_data.level)
- break
+ TD.stored_research.copy_research_to(stored_research)
to_chat(U, "
Data analyzed and updated. Disk erased.")
-
else
to_chat(U, "
ERROR: Procedure interrupted. Process terminated.")
else
diff --git a/code/modules/ninja/suit/suit_initialisation.dm b/code/modules/ninja/suit/suit_initialisation.dm
index 0084ff1995..e19e67404d 100644
--- a/code/modules/ninja/suit/suit_initialisation.dm
+++ b/code/modules/ninja/suit/suit_initialisation.dm
@@ -42,7 +42,7 @@
addtimer(CALLBACK(src, .proc/ninitialize_six, delay, U), delay)
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_six(delay, mob/living/carbon/human/U)
- to_chat(U, "
Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [DisplayPower(cell.charge)].")
+ to_chat(U, "
Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [DisplayEnergy(cell.charge)].")
addtimer(CALLBACK(src, .proc/ninitialize_seven, delay, U), delay)
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_seven(delay, mob/living/carbon/human/U)
diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm
index d9d220b0ef..e8487b3344 100644
--- a/code/modules/paperwork/clipboard.dm
+++ b/code/modules/paperwork/clipboard.dm
@@ -73,7 +73,7 @@
if(href_list["pen"])
if(haspen)
- haspen.loc = usr.loc
+ haspen.forceMove(usr.loc)
usr.put_in_hands(haspen)
haspen = null
@@ -96,7 +96,7 @@
if(href_list["remove"])
var/obj/item/P = locate(href_list["remove"])
if(istype(P) && P.loc == src)
- P.loc = usr.loc
+ P.forceMove(usr.loc)
usr.put_in_hands(P)
if(P == toppaper)
toppaper = null
diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm
index a02e98ed2b..3f23b8ba22 100644
--- a/code/modules/paperwork/contract.dm
+++ b/code/modules/paperwork/contract.dm
@@ -45,11 +45,6 @@
to_chat(M, "
You feel that your soul has returned to its rightful owner, Nanotrasen.")
M.return_soul()
else
- if(ishuman(M))
- var/mob/living/carbon/human/N = M
- if(!istype(N.head, /obj/item/clothing/head/helmet))
- N.adjustBrainLoss(10)
- to_chat(N, "
You feel dumber.")
M.visible_message("
[user] beats [M] over the head with [src]!", \
"
[user] beats [M] over the head with [src]!")
return ..()
@@ -207,7 +202,7 @@
if(!user.mind.hasSoul)
to_chat(user, "
You do not possess a soul.")
return 0
- if(prob(user.getBrainLoss()))
+ if(user.disabilities & DUMB)
to_chat(user, "
You quickly scrawl 'your name' on the contract.")
signIncorrectly()
return 0
@@ -307,11 +302,11 @@
if(istype(worn, /obj/item/device/pda))
var/obj/item/device/pda/PDA = worn
PDA.id = id
- id.loc = worn
+ id.forceMove(worn)
else if(istype(worn, /obj/item/storage/wallet))
var/obj/item/storage/wallet/W = worn
W.front_id = id
- id.loc = worn
+ id.forceMove(worn)
worn.update_icon()
var/datum/round_event/ion_storm/add_law_only/ion = new()
ion.announceEvent = -1
diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm
index 21d157a33c..0d963d4be8 100644
--- a/code/modules/paperwork/filingcabinet.dm
+++ b/code/modules/paperwork/filingcabinet.dm
@@ -36,7 +36,7 @@
if(mapload)
for(var/obj/item/I in loc)
if(istype(I, /obj/item/paper) || istype(I, /obj/item/folder) || istype(I, /obj/item/photo))
- I.loc = src
+ I.forceMove(src)
/obj/structure/filingcabinet/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
@@ -90,7 +90,7 @@
if(contents.len)
if(prob(40 + contents.len * 5))
var/obj/item/I = pick(contents)
- I.loc = loc
+ I.forceMove(loc)
if(prob(25))
step_rand(I)
to_chat(user, "
You pull \a [I] out of [src] at random.")
@@ -184,7 +184,8 @@ GLOBAL_LIST_EMPTY(employmentCabinets)
icon_state = "employmentcabinet"
var/virgin = 1
-/obj/structure/filingcabinet/employment/New()
+/obj/structure/filingcabinet/employment/Initialize()
+ . = ..()
GLOB.employmentCabinets += src
return ..()
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
index 3221a2c8db..c81ab37591 100644
--- a/code/modules/paperwork/folders.dm
+++ b/code/modules/paperwork/folders.dm
@@ -62,7 +62,7 @@
if(href_list["remove"])
var/obj/item/I = locate(href_list["remove"])
if(istype(I) && I.loc == src)
- I.loc = usr.loc
+ I.forceMove(usr.loc)
usr.put_in_hands(I)
if(href_list["read"])
diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm
index 4a85d03df7..fbf6e7b6e4 100644
--- a/code/modules/paperwork/paper_cutter.dm
+++ b/code/modules/paperwork/paper_cutter.dm
@@ -55,7 +55,7 @@
if(!user.transferItemToLoc(P, src))
return
to_chat(user, "
You replace [src]'s [P].")
- P.loc = src
+ P.forceMove(src)
storedcutter = P
update_icon()
return
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index 962802aa6d..87dc0506f2 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -22,7 +22,7 @@
return
var/obj/item/pen/P = locate(/obj/item/pen) in src.loc
if(P && !bin_pen)
- P.loc = src
+ P.forceMove(src)
bin_pen = P
update_icon()
@@ -69,7 +69,7 @@
user.changeNext_move(CLICK_CD_MELEE)
if(bin_pen)
var/obj/item/pen/P = bin_pen
- P.loc = user.loc
+ P.forceMove(user.loc)
user.put_in_hands(P)
to_chat(user, "
You take [P] out of \the [src].")
bin_pen = null
@@ -90,7 +90,7 @@
P.rigged = 1
P.updateinfolinks()
- P.loc = user.loc
+ P.forceMove(user.loc)
user.put_in_hands(P)
to_chat(user, "
You take [P] out of \the [src].")
else
@@ -169,4 +169,4 @@
CHECK_TICK
qdel(src)
else
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index 4b31ce7262..cde600186f 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -23,6 +23,7 @@
throw_range = 7
materials = list(MAT_METAL=10)
pressure_resistance = 2
+ grind_results = list("iron" = 2, "iodine" = 1)
var/colour = "black" //what colour the ink is!
var/traitor_unlock_degrees = 0
var/degrees = 0
@@ -99,19 +100,13 @@
if(deg && (deg > 0 && deg <= 360))
degrees = deg
to_chat(user, "
You rotate the top of the pen to [degrees] degrees.")
+ GET_COMPONENT(hidden_uplink, /datum/component/uplink)
if(hidden_uplink && degrees == traitor_unlock_degrees)
to_chat(user, "
Your pen makes a clicking noise, before quickly rotating back to 0 degrees!")
degrees = 0
+ hidden_uplink.locked = FALSE
hidden_uplink.interact(user)
-
-/obj/item/pen/attackby(obj/item/I, mob/user, params)
- if(hidden_uplink)
- return hidden_uplink.attackby(I, user, params)
- else
- return ..()
-
-
/obj/item/pen/attack(mob/living/M, mob/user,stealth)
if(!istype(M))
return
@@ -167,8 +162,7 @@
* Sleepypens
*/
/obj/item/pen/sleepy
- origin_tech = "engineering=4;syndicate=2"
- container_type = OPENCONTAINER_1
+ container_type = OPENCONTAINER
/obj/item/pen/sleepy/attack(mob/living/M, mob/user)
@@ -181,7 +175,8 @@
reagents.trans_to(M, reagents.total_volume)
-/obj/item/pen/sleepy/New()
+/obj/item/pen/sleepy/Initialize()
+ . = ..()
create_reagents(45)
reagents.add_reagent("chloralhydrate2", 20)
reagents.add_reagent("mutetoxin", 15)
@@ -192,7 +187,6 @@
* (Alan) Edaggers
*/
/obj/item/pen/edagger
- origin_tech = "combat=3;syndicate=1"
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") //these wont show up if the pen is off
var/on = FALSE
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index 20038f5745..e065fd8c03 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -247,10 +247,10 @@
/obj/machinery/photocopier/proc/remove_photocopy(obj/item/O, mob/user)
if(!issilicon(user)) //surprised this check didn't exist before, putting stuff in AI's hand is bad
- O.loc = user.loc
+ O.forceMove(user.loc)
user.put_in_hands(O)
else
- O.loc = src.loc
+ O.forceMove(drop_location())
to_chat(user, "
You take [O] out of [src].")
/obj/machinery/photocopier/attackby(obj/item/O, mob/user, params)
@@ -338,16 +338,16 @@
else
user.visible_message("
[user] puts [target] onto the photocopier!", "
You put [target] onto the photocopier.")
- target.loc = get_turf(src)
+ target.forceMove(drop_location())
ass = target
if(photocopy)
- photocopy.loc = src.loc
+ photocopy.forceMove(drop_location())
visible_message("
[photocopy] is shoved out of the way by [ass]!")
photocopy = null
else if(copy)
- copy.loc = src.loc
+ copy.forceMove(drop_location())
visible_message("
[copy] is shoved out of the way by [ass]!")
copy = null
updateUsrDialog()
@@ -391,5 +391,6 @@
/obj/item/device/toner
name = "toner cartridge"
icon_state = "tonercartridge"
+ grind_results = list("iodine" = 40, "iron" = 10)
var/charges = 5
var/max_charges = 5
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 48b045f680..6e908c0f6a 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -33,6 +33,7 @@
w_class = WEIGHT_CLASS_TINY
resistance_flags = FLAMMABLE
max_integrity = 50
+ grind_results = list("iodine" = 4)
var/icon/img //Big photo image
var/scribble //Scribble on the back.
var/blueprints = 0 //Does it include the blueprints?
diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm
index a37344d635..f8b8cae22a 100644
--- a/code/modules/power/antimatter/control.dm
+++ b/code/modules/power/antimatter/control.dm
@@ -339,7 +339,7 @@
if(href_list["ejectjar"])
if(fueljar)
- fueljar.loc = src.loc
+ fueljar.forceMove(drop_location())
fueljar = null
//fueljar.control_unit = null currently it does not care where it is
//update_icon() when we have the icon for it
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 815da3fbdb..548651f9c8 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -89,6 +89,7 @@
var/auto_name = 0
var/failure_timer = 0
var/force_update = 0
+ var/emergency_lights = FALSE
var/update_state = -1
var/update_overlay = -1
var/icon_update_needed = FALSE
@@ -152,7 +153,7 @@
GLOB.apcs_list -= src
if(malfai && operating)
- malfai.malf_picker.processing_time = Clamp(malfai.malf_picker.processing_time - 10,0,1000)
+ malfai.malf_picker.processing_time = CLAMP(malfai.malf_picker.processing_time - 10,0,1000)
area.power_light = FALSE
area.power_equip = FALSE
area.power_environ = FALSE
@@ -760,6 +761,7 @@
"coverLocked" = coverlocked,
"siliconUser" = user.has_unlimited_silicon_privilege || user.using_power_flow_console(),
"malfStatus" = get_malf_status(user),
+ "emergencyLights" = !emergency_lights,
"powerChannels" = list(
list(
@@ -899,6 +901,14 @@
failure_timer = 0
update_icon()
update()
+ if("emergency_lighting")
+ emergency_lights = !emergency_lights
+ for(var/area/A in area.related)
+ for(var/obj/machinery/light/L in A)
+ if(!initial(L.no_emergency)) //If there was an override set on creation, keep that override
+ L.no_emergency = emergency_lights
+ INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE)
+ CHECK_TICK
return 1
/obj/machinery/power/apc/proc/toggle_breaker()
@@ -962,7 +972,7 @@
else
to_chat(occupier, "
Primary core damaged, unable to return core processes.")
if(forced)
- occupier.loc = src.loc
+ occupier.forceMove(drop_location())
occupier.death()
occupier.gib()
for(var/obj/item/pinpointer/nuke/P in GLOB.pinpointer_list)
@@ -1243,7 +1253,7 @@
/obj/machinery/power/apc/proc/set_broken()
if(malfai && operating)
- malfai.malf_picker.processing_time = Clamp(malfai.malf_picker.processing_time - 10,0,1000)
+ malfai.malf_picker.processing_time = CLAMP(malfai.malf_picker.processing_time - 10,0,1000)
stat |= BROKEN
operating = FALSE
if(occupier)
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index dc63253681..ca424cb80d 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -427,10 +427,10 @@ By design, d1 is the smallest direction and d2 is the highest
var/obj/O = P_list[1]
// remove the cut cable from its turf and powernet, so that it doesn't get count in propagate_network worklist
if(remove)
- loc = null
+ moveToNullspace()
powernet.remove_cable(src) //remove the cut cable from its powernet
- addtimer(CALLBACK(src, .proc/auto_propogate_cut_cable, O), 0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables
+ addtimer(CALLBACK(O, .proc/auto_propogate_cut_cable, O), 0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables
// Disconnect machines connected to nodes
if(d1 == 0) // if we cut a node (O-X) cable
@@ -472,6 +472,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
attack_verb = list("whipped", "lashed", "disciplined", "flogged")
singular_name = "cable piece"
full_w_class = WEIGHT_CLASS_SMALL
+ grind_results = list("copper" = 2) //2 copper per cable in the coil
/obj/item/stack/cable_coil/cyborg
is_cyborg = 1
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index c8e58791e2..cd24dbb928 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -6,7 +6,6 @@
item_state = "cell"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
- origin_tech = "powerstorage=1"
force = 5
throwforce = 5
throw_speed = 2
@@ -15,6 +14,7 @@
var/charge = 0 // note %age conveted to actual charge in New
var/maxcharge = 1000
materials = list(MAT_METAL=700, MAT_GLASS=50)
+ grind_results = list("lithium" = 15, "iron" = 5, "silicon" = 5)
var/rigged = 0 // true if rigged to explode
var/chargerate = 100 //how much power is given every tick in a recharger
var/self_recharge = 0 //does it self recharge, over time, or not?
@@ -24,12 +24,14 @@
/obj/item/stock_parts/cell/get_cell()
return src
-/obj/item/stock_parts/cell/New()
+/obj/item/stock_parts/cell/Initialize(mapload, override_maxcharge)
. = ..()
START_PROCESSING(SSobj, src)
+ if (override_maxcharge)
+ maxcharge = override_maxcharge
charge = maxcharge
if(ratingdesc)
- desc += " This one has a power rating of [DisplayPower(maxcharge)], and you should not swallow it."
+ desc += " This one has a rating of [DisplayEnergy(maxcharge)], and you should not swallow it."
update_icon()
/obj/item/stock_parts/cell/Destroy()
@@ -106,6 +108,7 @@
to_chat(user, "
You inject the solution into the power cell.")
if(S.reagents.has_reagent("plasma", 5))
rigged = 1
+ grind_results["plasma"] = 5
S.reagents.clear_reagents()
@@ -154,7 +157,7 @@
/obj/item/stock_parts/cell/proc/get_electrocute_damage()
if(charge >= 1000)
- return Clamp(round(charge/10000), 10, 90) + rand(-5,5)
+ return CLAMP(round(charge/10000), 10, 90) + rand(-5,5)
else
return 0
@@ -185,7 +188,6 @@
/obj/item/stock_parts/cell/secborg
name = "security borg rechargeable D battery"
- origin_tech = null
maxcharge = 600 //600 max charge / 100 charge per shot = six shots
materials = list(MAT_GLASS=40)
rating = 2.5
@@ -210,7 +212,6 @@
/obj/item/stock_parts/cell/high
name = "high-capacity power cell"
- origin_tech = "powerstorage=2"
icon_state = "hcell"
maxcharge = 10000
materials = list(MAT_GLASS=60)
@@ -230,7 +231,6 @@
/obj/item/stock_parts/cell/super
name = "super-capacity power cell"
- origin_tech = "powerstorage=3;materials=3"
icon_state = "scell"
maxcharge = 20000
materials = list(MAT_GLASS=300)
@@ -243,7 +243,6 @@
/obj/item/stock_parts/cell/hyper
name = "hyper-capacity power cell"
- origin_tech = "powerstorage=4;engineering=4;materials=4"
icon_state = "hpcell"
maxcharge = 30000
materials = list(MAT_GLASS=400)
@@ -257,7 +256,6 @@
/obj/item/stock_parts/cell/bluespace
name = "bluespace power cell"
desc = "A rechargeable transdimensional power cell."
- origin_tech = "powerstorage=5;bluespace=4;materials=4;engineering=4"
icon_state = "bscell"
maxcharge = 40000
materials = list(MAT_GLASS=600)
@@ -271,7 +269,6 @@
/obj/item/stock_parts/cell/infinite
name = "infinite-capacity power cell!"
icon_state = "icell"
- origin_tech = "powerstorage=7"
maxcharge = 30000
materials = list(MAT_GLASS=1000)
rating = 6
@@ -285,7 +282,6 @@
desc = "An alien power cell that produces energy seemingly out of nowhere."
icon = 'icons/obj/abductor.dmi'
icon_state = "cell"
- origin_tech = "abductor=5;powerstorage=8;engineering=6"
maxcharge = 50000
rating = 12
ratingdesc = FALSE
@@ -299,7 +295,6 @@
desc = "A rechargeable starch based power cell."
icon = 'icons/obj/hydroponics/harvest.dmi'
icon_state = "potato"
- origin_tech = "powerstorage=1;biotech=1"
charge = 100
maxcharge = 300
materials = list()
@@ -309,7 +304,6 @@
/obj/item/stock_parts/cell/high/slime
name = "charged slime core"
desc = "A yellow slime core infused with plasma, it crackles with power."
- origin_tech = "powerstorage=5;biotech=4"
icon = 'icons/mob/slimes.dmi'
icon_state = "yellow slime extract"
materials = list()
@@ -342,4 +336,18 @@
return
/obj/item/stock_parts/cell/beam_rifle/emp_act(severity)
- charge = Clamp((charge-(10000/severity)),0,maxcharge)
+ charge = CLAMP((charge-(10000/severity)),0,maxcharge)
+
+/obj/item/stock_parts/cell/emergency_light
+ name = "miniature power cell"
+ desc = "A tiny power cell with a very low power capacity. Used in light fixtures to power them in the event of an outage."
+ maxcharge = 120 //Emergency lights use 0.2 W per tick, meaning ~10 minutes of emergency power from a cell
+ materials = list(MAT_GLASS = 20)
+ rating = 1
+ w_class = WEIGHT_CLASS_TINY
+
+/obj/item/stock_parts/cell/emergency_light/Initialize()
+ . = ..()
+ var/area/A = get_area(src)
+ if(!A.lightswitch || !A.light_power)
+ charge = 0 //For naturally depowered areas, we start with no power
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 98fb2ed233..749dcb463e 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -2,7 +2,7 @@
//
// consists of light fixtures (/obj/machinery/light) and light tube/bulb items (/obj/item/light)
-
+#define LIGHT_EMERGENCY_POWER_USE 0.2 //How much power emergency lights will consume per tick
// status values shared between lighting fixtures and items
#define LIGHT_OK 0
#define LIGHT_EMPTY 1
@@ -49,12 +49,22 @@
var/fixture_type = "tube"
var/sheets_refunded = 2
var/obj/machinery/light/newlight = null
+ var/obj/item/stock_parts/cell/cell
-/obj/structure/light_construct/New(loc, ndir, building)
- ..()
+ var/cell_connectors = TRUE
+
+/obj/structure/light_construct/Initialize(mapload, ndir, building)
+ . = ..()
if(building)
setDir(ndir)
+/obj/structure/light_construct/Destroy()
+ QDEL_NULL(cell)
+ return ..()
+
+/obj/structure/light_construct/get_cell()
+ return cell
+
/obj/structure/light_construct/examine(mob/user)
..()
switch(src.stage)
@@ -64,9 +74,38 @@
to_chat(user, "It's wired.")
if(3)
to_chat(user, "The casing is closed.")
+ if(cell_connectors)
+ if(cell)
+ to_chat(user, "You see [cell] inside the casing.")
+ else
+ to_chat(user, "The casing has no power cell for backup power.")
+ else
+ to_chat(user, "
This casing doesn't support power cells for backup power.")
+ return
/obj/structure/light_construct/attackby(obj/item/W, mob/user, params)
add_fingerprint(user)
+ if(istype(W, /obj/item/stock_parts/cell))
+ if(!cell_connectors)
+ to_chat(user, "
This [name] can't support a power cell!")
+ return
+ if(W.flags_1 & NODROP_1)
+ to_chat(user, "
[W] is stuck to your hand!")
+ return
+ user.dropItemToGround(W)
+ if(cell)
+ user.visible_message("
[user] swaps [W] out for [src]'s cell.", \
+ "
You swap [src]'s power cells.")
+ cell.forceMove(drop_location())
+ user.put_in_hands(cell)
+ else
+ user.visible_message("
[user] hooks up [W] to [src].", \
+ "
You add [W] to [src].")
+ playsound(src, 'sound/machines/click.ogg', 50, TRUE)
+ W.forceMove(src)
+ cell = W
+ add_fingerprint(user)
+ return
switch(stage)
if(1)
if(istype(W, /obj/item/wrench))
@@ -124,6 +163,10 @@
newlight = new /obj/machinery/light/small/built(loc)
newlight.setDir(dir)
transfer_fingerprints_to(newlight)
+ if(cell)
+ newlight.cell = cell
+ cell.forceMove(newlight)
+ cell = null
qdel(src)
return
return ..()
@@ -173,6 +216,11 @@
var/rigged = 0 // true if rigged to explode
+ var/obj/item/stock_parts/cell/cell
+ var/start_with_cell = TRUE // if true, this fixture generates a very weak cell at roundstart
+ var/emergency_mode = FALSE // if true, the light is in emergency mode
+ var/no_emergency = FALSE // if true, this light cannot ever have an emergency mode
+
// the smaller bulb light fixture
/obj/machinery/light/small
@@ -192,8 +240,10 @@
/obj/machinery/light/built
icon_state = "tube-empty"
+ start_with_cell = FALSE
-/obj/machinery/light/built/New()
+/obj/machinery/light/built/Initialize()
+ . = ..()
status = LIGHT_EMPTY
update(0)
..()
@@ -208,8 +258,10 @@
// create a new lighting fixture
-/obj/machinery/light/New()
- ..()
+/obj/machinery/light/Initialize()
+ . = ..()
+ if(start_with_cell && !no_emergency)
+ cell = new/obj/item/stock_parts/cell/emergency_light(src)
spawn(2)
switch(fitting)
if("tube")
@@ -228,28 +280,30 @@
if(A)
on = FALSE
// A.update_lights()
+ QDEL_NULL(cell)
return ..()
/obj/machinery/light/update_icon()
-
switch(status) // set icon_states
if(LIGHT_OK)
- icon_state = "[base_state][on]"
+ if(emergency_mode)
+ icon_state = "[base_state]_emergency"
+ else
+ icon_state = "[base_state][on]"
if(LIGHT_EMPTY)
icon_state = "[base_state]-empty"
- on = FALSE
if(LIGHT_BURNED)
icon_state = "[base_state]-burned"
- on = FALSE
if(LIGHT_BROKEN)
icon_state = "[base_state]-broken"
- on = FALSE
return
// update the icon_state and luminosity of the light depending on its state
/obj/machinery/light/proc/update(trigger = 1)
-
- update_icon()
+ switch(status)
+ if(LIGHT_BROKEN,LIGHT_BURNED,LIGHT_EMPTY)
+ on = FALSE
+ emergency_mode = FALSE
if(on)
if(!light || light.light_range != brightness)
switchcount++
@@ -261,10 +315,14 @@
burn_out()
else
use_power = ACTIVE_POWER_USE
- set_light(brightness)
+ set_light(brightness, 1, "#FFFFFF")
+ else if(has_emergency_power(LIGHT_EMERGENCY_POWER_USE) && !turned_off())
+ use_power = IDLE_POWER_USE
+ emergency_mode = TRUE
else
use_power = IDLE_POWER_USE
set_light(0)
+ update_icon()
active_power_usage = (brightness * 10)
if(on != on_gs)
@@ -276,6 +334,12 @@
removeStaticPower(static_power_used, STATIC_LIGHT)
+/obj/machinery/light/process()
+ if(has_power() && cell)
+ cell.charge = min(cell.maxcharge, cell.charge + LIGHT_EMERGENCY_POWER_USE) //Recharge emergency power automatically while not using it
+ if(emergency_mode && !use_emergency_power(LIGHT_EMERGENCY_POWER_USE))
+ update(FALSE) //Disables emergency mode and sets the color to normal
+
/obj/machinery/light/proc/burn_out()
if(status == LIGHT_OK)
status = LIGHT_BURNED
@@ -289,6 +353,9 @@
on = (s && status == LIGHT_OK)
update()
+/obj/machinery/light/get_cell()
+ return cell
+
// examine verb
/obj/machinery/light/examine(mob/user)
..()
@@ -301,6 +368,8 @@
to_chat(user, "The [fitting] is burnt out.")
if(LIGHT_BROKEN)
to_chat(user, "The [fitting] has been smashed.")
+ if(cell)
+ to_chat(user, "Its backup power charge meter reads [(cell.charge / cell.maxcharge) * 100]%.")
@@ -384,6 +453,10 @@
drop_light_tube()
new /obj/item/stack/cable_coil(loc, 1, "red")
transfer_fingerprints_to(newlight)
+ if(cell)
+ newlight.cell = cell
+ cell.forceMove(newlight)
+ cell = null
qdel(src)
/obj/machinery/light/attacked_by(obj/item/I, mob/living/user)
@@ -415,6 +488,11 @@
if(BURN)
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
+// returns if the light has power /but/ is manually turned off
+// if a light is turned off, it won't activate emergency power
+/obj/machinery/light/proc/turned_off()
+ var/area/A = get_area(src)
+ return !A.lightswitch && A.power_light || !flickering
// returns whether this light has power
// true if area has power and lightswitch is on
@@ -422,6 +500,27 @@
var/area/A = get_area(src)
return A.lightswitch && A.power_light
+// returns whether this light has emergency power
+// can also return if it has access to a certain amount of that power
+/obj/machinery/light/proc/has_emergency_power(pwr)
+ if(no_emergency || !cell)
+ return FALSE
+ if(pwr ? cell.charge >= pwr : cell.charge)
+ return status == LIGHT_OK
+
+// attempts to use power from the installed emergency cell, returns true if it does and false if it doesn't
+/obj/machinery/light/proc/use_emergency_power(pwr = LIGHT_EMERGENCY_POWER_USE)
+ if(!has_emergency_power(pwr))
+ return FALSE
+ if(cell.charge > 300) //it's meant to handle 120 W, ya doofus
+ visible_message("
[src] short-circuits from too powerful of a power cell!")
+ burn_out()
+ return FALSE
+ cell.use(pwr)
+ set_light(brightness * 0.25, max(0.5, 0.75 * (cell.charge / cell.maxcharge)), "#FF3232") //RGB: 255, 50, 50
+ return TRUE
+
+
/obj/machinery/light/proc/flicker(var/amount = rand(10, 20))
set waitfor = 0
if(flickering)
@@ -441,7 +540,9 @@
// ai attack - make lights flicker, because why not
/obj/machinery/light/attack_ai(mob/user)
- src.flicker(1)
+ no_emergency = !no_emergency
+ to_chat(user, "
Emergency lights for this fixture have been [no_emergency ? "disabled" : "enabled"].")
+ update(FALSE)
return
// attack with hand - remove tube/bulb
@@ -575,10 +676,11 @@
force = 2
throwforce = 5
w_class = WEIGHT_CLASS_TINY
- var/status = 0 // LIGHT_OK, LIGHT_BURNED or LIGHT_BROKEN
+ var/status = LIGHT_OK // LIGHT_OK, LIGHT_BURNED or LIGHT_BROKEN
var/base_state
var/switchcount = 0 // number of times switched
materials = list(MAT_GLASS=100)
+ grind_results = list("silicon" = 5, "nitrogen" = 10) //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs
var/rigged = 0 // true if rigged to explode
var/brightness = 2 //how much light it gives off
@@ -658,7 +760,7 @@
/obj/item/light/proc/shatter()
if(status == LIGHT_OK || status == LIGHT_BURNED)
- src.visible_message("
[name] shatters.","
You hear a small glass object shatter.")
+ visible_message("
[name] shatters.","
You hear a small glass object shatter.")
status = LIGHT_BROKEN
force = 5
playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1)
diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm
index b6f61103ca..c34edc53f3 100644
--- a/code/modules/power/powernet.dm
+++ b/code/modules/power/powernet.dm
@@ -94,6 +94,6 @@
/datum/powernet/proc/get_electrocute_damage()
if(avail >= 1000)
- return Clamp(round(avail/10000), 10, 90) + rand(-5,5)
+ return CLAMP(round(avail/10000), 10, 90) + rand(-5,5)
else
return 0
\ No newline at end of file
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index 0ede336ef6..a5e9db1fde 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -37,7 +37,7 @@
eject()
else
loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] -= 0.001*drainratio
- ASSERT_GAS(/datum/gas/tritium,loaded_tank.air_contents)
+ loaded_tank.air_contents.assert_gas(/datum/gas/tritium)
loaded_tank.air_contents.gases[/datum/gas/tritium][MOLES] += 0.001*drainratio
loaded_tank.air_contents.garbage_collect()
@@ -132,7 +132,7 @@
var/obj/item/tank/internals/plasma/Z = src.loaded_tank
if (!Z)
return
- Z.loc = get_turf(src)
+ Z.forceMove(drop_location())
Z.layer = initial(Z.layer)
Z.plane = initial(Z.plane)
src.loaded_tank = null
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index 7596d890e0..1c5f0a3375 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -335,7 +335,7 @@
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 0
if(buckled_mob.client)
- buckled_mob.client.change_view(world.view)
+ buckled_mob.client.change_view(CONFIG_GET(string/default_view))
auto.Remove(buckled_mob)
. = ..()
diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm
index 74aa140721..cdfbb35b34 100644
--- a/code/modules/power/singularity/field_generator.dm
+++ b/code/modules/power/singularity/field_generator.dm
@@ -285,9 +285,8 @@ field_generator power level display
var/field_dir = get_dir(T,get_step(G.loc, NSEW))
T = get_step(T, NSEW)
if(!locate(/obj/machinery/field/containment) in T)
- var/obj/machinery/field/containment/CF = new/obj/machinery/field/containment()
+ var/obj/machinery/field/containment/CF = new(T)
CF.set_master(src,G)
- CF.loc = T
CF.setDir(field_dir)
fields += CF
G.fields += CF
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 22712e970d..15b76d2641 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -47,8 +47,15 @@
/obj/singularity/narsie/large/cult/Initialize()
. = ..()
GLOB.cult_narsie = src
- deltimer(GLOB.blood_target_reset_timer)
- GLOB.blood_target = src
+ var/list/all_cults = list()
+ for(var/datum/antagonist/cult/C in GLOB.antagonists)
+ all_cults |= C.cult_team
+ for(var/datum/team/cult/T in all_cults)
+ deltimer(T.blood_target_reset_timer)
+ T.blood_target = src
+ var/datum/objective/eldergod/summon_objective = locate() in T.objectives
+ if(summon_objective)
+ summon_objective.summoned = TRUE
for(var/datum/mind/cult_mind in SSticker.mode.cult)
if(isliving(cult_mind.current))
var/mob/living/L = cult_mind.current
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index 70776b5c05..95b78ff0b5 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -227,7 +227,7 @@
/obj/machinery/power/smes/proc/chargedisplay()
- return Clamp(round(5.5*charge/capacity),0,5)
+ return CLAMP(round(5.5*charge/capacity),0,5)
/obj/machinery/power/smes/process()
if(stat & BROKEN)
@@ -382,7 +382,7 @@
target = text2num(target)
. = TRUE
if(.)
- input_level = Clamp(target, 0, input_level_max)
+ input_level = CLAMP(target, 0, input_level_max)
log_smes(usr.ckey)
if("output")
var/target = params["target"]
@@ -404,7 +404,7 @@
target = text2num(target)
. = TRUE
if(.)
- output_level = Clamp(target, 0, output_level_max)
+ output_level = CLAMP(target, 0, output_level_max)
log_smes(usr.ckey)
/obj/machinery/power/smes/proc/log_smes(user = "")
diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm
index fb530f128f..af81b632d7 100644
--- a/code/modules/power/solar.dm
+++ b/code/modules/power/solar.dm
@@ -378,14 +378,14 @@
if("direction")
var/adjust = text2num(params["adjust"])
if(adjust)
- currentdir = Clamp((360 + adjust + currentdir) % 360, 0, 359)
+ currentdir = CLAMP((360 + adjust + currentdir) % 360, 0, 359)
targetdir = currentdir
set_panels(currentdir)
. = TRUE
if("rate")
var/adjust = text2num(params["adjust"])
if(adjust)
- trackrate = Clamp(trackrate + adjust, -7200, 7200)
+ trackrate = CLAMP(trackrate + adjust, -7200, 7200)
if(trackrate)
nexttime = world.time + 36000 / abs(trackrate)
. = TRUE
@@ -419,7 +419,7 @@
new /obj/item/shard( src.loc )
var/obj/item/circuitboard/computer/solar_control/M = new /obj/item/circuitboard/computer/solar_control( A )
for (var/obj/C in src)
- C.loc = src.loc
+ C.forceMove(drop_location())
A.circuit = M
A.state = 3
A.icon_state = "3"
@@ -430,7 +430,7 @@
var/obj/structure/frame/computer/A = new /obj/structure/frame/computer( src.loc )
var/obj/item/circuitboard/computer/solar_control/M = new /obj/item/circuitboard/computer/solar_control( A )
for (var/obj/C in src)
- C.loc = src.loc
+ C.forceMove(drop_location())
A.circuit = M
A.state = 4
A.icon_state = "4"
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index de67f837f4..5f9f6042d3 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -258,7 +258,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
return //Yeah just stop.
if(power)
- soundloop.volume = min(50, (round(power, 50)/50)+1) // 5 +1 volume per 20 power. 2500 power is max
+ soundloop.volume = min(40, (round(power/100)/50)+1) // 5 +1 volume per 20 power. 2500 power is max
//Ok, get the air from the turf
var/datum/gas_mixture/env = T.return_air()
@@ -317,10 +317,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
mole_heat_penalty = max(combined_gas / MOLE_HEAT_PENALTY, 0.25)
if (combined_gas > POWERLOSS_INHIBITION_MOLE_THRESHOLD && co2comp > POWERLOSS_INHIBITION_GAS_THRESHOLD)
- powerloss_dynamic_scaling = Clamp(powerloss_dynamic_scaling + Clamp(co2comp - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1)
+ powerloss_dynamic_scaling = CLAMP(powerloss_dynamic_scaling + CLAMP(co2comp - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1)
else
- powerloss_dynamic_scaling = Clamp(powerloss_dynamic_scaling - 0.05,0, 1)
- powerloss_inhibitor = Clamp(1-(powerloss_dynamic_scaling * Clamp(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD,1 ,1.5)),0 ,1)
+ powerloss_dynamic_scaling = CLAMP(powerloss_dynamic_scaling - 0.05,0, 1)
+ powerloss_inhibitor = CLAMP(1-(powerloss_dynamic_scaling * CLAMP(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD,1 ,1.5)),0 ,1)
if(matter_power)
var/removed_matter = max(matter_power/MATTER_POWER_CONVERSION, 40)
@@ -368,7 +368,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
if(!istype(l.glasses, /obj/item/clothing/glasses/meson))
var/D = sqrt(1 / max(1, get_dist(l, src)))
l.hallucination += power * config_hallucination_power * D
- l.hallucination = Clamp(0, 200, l.hallucination)
+ l.hallucination = CLAMP(0, 200, l.hallucination)
for(var/mob/living/l in range(src, round((power / 100) ** 0.25)))
var/rads = (power / 10) * sqrt( 1 / max(get_dist(l, src),1) )
@@ -386,7 +386,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
supermatter_zap(src, 5, min(power*2, 20000))
else if (damage > damage_penalty_point && prob(20))
playsound(src.loc, 'sound/weapons/emitter2.ogg', 100, 1, extrarange = 10)
- supermatter_zap(src, 5, Clamp(power*2, 4000, 20000))
+ supermatter_zap(src, 5, CLAMP(power*2, 4000, 20000))
if(prob(15) && power > POWER_PENALTY_THRESHOLD)
supermatter_pull(src, power/750)
diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm
index 57ec453863..a0977d93e3 100644
--- a/code/modules/power/tesla/coil.dm
+++ b/code/modules/power/tesla/coil.dm
@@ -103,8 +103,6 @@
buckle_lying = FALSE
buckle_requires_restraints = TRUE
- circuit = /obj/item/circuitboard/machine/grounding_rod
-
/obj/machinery/power/grounding_rod/default_unfasten_wrench(mob/user, obj/item/wrench/W, time = 20)
. = ..()
if(. == SUCCESSFUL_UNFASTEN)
diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm
index 4a26950217..51cb99a34f 100644
--- a/code/modules/power/tesla/energy_ball.dm
+++ b/code/modules/power/tesla/energy_ball.dm
@@ -62,7 +62,7 @@
pixel_x = -32
pixel_y = -32
for (var/ball in orbiting_balls)
- var/range = rand(1, Clamp(orbiting_balls.len, 3, 7))
+ var/range = rand(1, CLAMP(orbiting_balls.len, 3, 7))
tesla_zap(ball, range, TESLA_MINI_POWER/7*range, TRUE)
else
energy = 0 // ensure we dont have miniballs of miniballs
@@ -268,7 +268,7 @@
closest_grounding_rod.tesla_act(power, explosive, stun_mobs)
else if(closest_mob)
- var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5)
+ var/shock_damage = CLAMP(round(power/400), 10, 90) + rand(-5, 5)
closest_mob.electrocute_act(shock_damage, source, 1, tesla_shock = 1, stun = stun_mobs)
if(issilicon(closest_mob))
var/mob/living/silicon/S = closest_mob
diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm
index 5e129acf8f..a46627b7ca 100644
--- a/code/modules/power/tracker.dm
+++ b/code/modules/power/tracker.dm
@@ -47,7 +47,7 @@
S.glass_type = /obj/item/stack/sheet/glass
S.tracker = 1
S.anchored = TRUE
- S.loc = src
+ S.forceMove(src)
update_icon()
//updates the tracker icon and the facing angle for the control computer
@@ -94,4 +94,4 @@
// Tracker Electronic
/obj/item/electronics/tracker
- name = "tracker electronics"
\ No newline at end of file
+ name = "tracker electronics"
diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm
index ac664894de..5c463b4ee9 100644
--- a/code/modules/power/turbine.dm
+++ b/code/modules/power/turbine.dm
@@ -75,7 +75,6 @@
// The inlet of the compressor is the direction it faces
gas_contained = new
inturf = get_step(src, dir)
-
locate_machinery()
if(!turbine)
stat |= BROKEN
@@ -344,10 +343,10 @@
/obj/machinery/computer/turbine_computer/ui_data(mob/user)
var/list/data = list()
- data["working"] = (compressor.starter && compressor && compressor.turbine && !compressor.stat && !compressor.turbine.stat)
data["connected"] = (compressor && compressor.turbine) ? TRUE : FALSE
- data["compressor_broke"] = (!compressor || compressor.stat) ? TRUE : FALSE
- data["turbine_broke"] = (!compressor || compressor.turbine.stat) ? TRUE : FALSE
+ data["compressor_broke"] = (!compressor || (compressor.stat & BROKEN)) ? TRUE : FALSE
+ data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.stat & BROKEN)) ? TRUE : FALSE
+ data["broken"] = (data["compressor_broke"] || data["turbine_broke"])
data["online"] = compressor.starter
data["power"] = DisplayPower(compressor.turbine.lastgen)
@@ -360,9 +359,13 @@
if(..())
return
switch(action)
- if("power")
+ if("power-on")
if(compressor && compressor.turbine)
- compressor.starter = !compressor.starter
+ compressor.starter = TRUE
+ . = TRUE
+ if("power-off")
+ if(compressor && compressor.turbine)
+ compressor.starter = FALSE
. = TRUE
if("reconnect")
locate_machinery()
diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm
index 71befb50f1..4e341fa2a4 100644
--- a/code/modules/projectiles/ammunition.dm
+++ b/code/modules/projectiles/ammunition.dm
@@ -17,6 +17,7 @@
var/delay = 0 //Delay for energy weapons
var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown.
var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect //the visual effect appearing when the ammo is fired.
+ var/heavy_metal = TRUE
/obj/item/ammo_casing/New()
@@ -58,3 +59,47 @@
to_chat(user, "
You fail to collect anything!")
else
return ..()
+
+/obj/item/ammo_casing/throw_impact(atom/A)
+ if(heavy_metal)
+ bounce_away(FALSE, NONE)
+ . = ..()
+
+/obj/item/ammo_casing/proc/bounce_away(still_warm = FALSE, delay = 3)
+ SpinAnimation(10, 1)
+ update_icon()
+ var/turf/T = get_turf(src)
+ if(still_warm && T && (is_type_in_typecache(T, GLOB.bullet_bounce_away_sizzle)))
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/items/welder.ogg', 20, 1), delay)
+ else if(T && (!is_type_in_typecache(T, GLOB.bullet_bounce_away_blacklist)))
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/weapons/bulletremove.ogg', 60, 1), delay)
+
+GLOBAL_LIST_INIT(bullet_bounce_away_sizzle, typecacheof(list(
+ /turf/closed/indestructible/rock/snow,
+ /turf/closed/wall/ice,
+ /turf/closed/wall/mineral/snow,
+ /turf/open/floor/grass/snow,
+ /turf/open/floor/holofloor/snow,
+ /turf/open/floor/plating/asteroid/snow,
+ /turf/open/floor/plating/ice,
+ /turf/open/water)))
+
+GLOBAL_LIST_INIT(bullet_bounce_away_blacklist, typecacheof(list(
+ /turf/closed/indestructible/rock/snow,
+ /turf/closed/indestructible/splashscreen,
+ /turf/closed/wall/mineral/snow,
+ /turf/open/chasm,
+ /turf/open/floor/carpet,
+ /turf/open/floor/grass,
+ /turf/open/floor/holofloor/beach,
+ /turf/open/floor/holofloor/carpet,
+ /turf/open/floor/holofloor/grass,
+ /turf/open/floor/holofloor/hyperspace,
+ /turf/open/floor/holofloor/snow,
+ /turf/open/floor/plating/asteroid/snow,
+ /turf/open/floor/plating/beach,
+ /turf/open/indestructible/reebe_void,
+ /turf/open/lava,
+ /turf/open/space,
+ /turf/open/water,
+ /turf/template_noop)))
diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm
index d51ea36e15..edd28e72a8 100644
--- a/code/modules/projectiles/ammunition/ammo_casings.dm
+++ b/code/modules/projectiles/ammunition/ammo_casings.dm
@@ -284,9 +284,9 @@
icon_state = "cshell"
projectile_type = /obj/item/projectile/bullet/dart
-/obj/item/ammo_casing/shotgun/dart/New()
- ..()
- container_type |= OPENCONTAINER_1
+/obj/item/ammo_casing/shotgun/dart/Initialize()
+ . = ..()
+ container_type |= OPENCONTAINER
create_reagents(30)
reagents.set_reacting(TRUE)
@@ -302,4 +302,4 @@
reagents.add_reagent("spore", 6)
reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT
reagents.add_reagent("coniine", 6)
- reagents.add_reagent("sodium_thiopental", 6)
\ No newline at end of file
+ reagents.add_reagent("sodium_thiopental", 6)
diff --git a/code/modules/projectiles/ammunition/caseless.dm b/code/modules/projectiles/ammunition/caseless.dm
index e5b905019d..b3439c86b2 100644
--- a/code/modules/projectiles/ammunition/caseless.dm
+++ b/code/modules/projectiles/ammunition/caseless.dm
@@ -4,10 +4,11 @@
/obj/item/ammo_casing/caseless
desc = "A caseless bullet casing."
firing_effect_type = null
+ heavy_metal = FALSE
/obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread)
if (..()) //successfully firing
- loc = null
+ moveToNullspace()
return 1
else
return 0
diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm
index dcd9d356ad..40c198ec4e 100644
--- a/code/modules/projectiles/ammunition/energy.dm
+++ b/code/modules/projectiles/ammunition/energy.dm
@@ -7,6 +7,7 @@
var/select_name = "energy"
fire_sound = 'sound/weapons/laser.ogg'
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy
+ heavy_metal = FALSE
/obj/item/ammo_casing/energy/chameleon
projectile_type = /obj/item/projectile/energy/chameleon
diff --git a/code/modules/projectiles/ammunition/special.dm b/code/modules/projectiles/ammunition/special.dm
index 11fd12da70..de103b399e 100644
--- a/code/modules/projectiles/ammunition/special.dm
+++ b/code/modules/projectiles/ammunition/special.dm
@@ -3,6 +3,7 @@
desc = "I didn't even know magic needed ammo..."
projectile_type = /obj/item/projectile/magic
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/magic
+ heavy_metal = FALSE
/obj/item/ammo_casing/magic/change
projectile_type = /obj/item/projectile/magic/change
diff --git a/code/modules/projectiles/box_magazine.dm b/code/modules/projectiles/box_magazine.dm
index 324470ede4..bf941108ff 100644
--- a/code/modules/projectiles/box_magazine.dm
+++ b/code/modules/projectiles/box_magazine.dm
@@ -87,7 +87,7 @@
if(num_loaded)
if(!silent)
to_chat(user, "
You load [num_loaded] shell\s into \the [src]!")
- playsound(user, 'sound/weapons/bulletinsert.ogg', 60, 1)
+ playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1)
A.update_icon()
update_icon()
@@ -96,9 +96,10 @@
/obj/item/ammo_box/attack_self(mob/user)
var/obj/item/ammo_casing/A = get_round()
if(A)
- user.put_in_hands(A)
+ if(!user.put_in_hands(A))
+ A.bounce_away(FALSE, NONE)
+ playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1)
to_chat(user, "
You remove a round from \the [src]!")
- playsound(user, 'sound/weapons/bulletremove.ogg', 60, 1)
update_icon()
/obj/item/ammo_box/update_icon()
diff --git a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
index 50769b926e..73f8379baf 100644
--- a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
+++ b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
@@ -17,21 +17,18 @@
/obj/item/ammo_box/c9mm
name = "ammo box (9mm)"
icon_state = "9mmbox"
- origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/c9mm
max_ammo = 30
/obj/item/ammo_box/c10mm
name = "ammo box (10mm)"
icon_state = "10mmbox"
- origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/c10mm
max_ammo = 20
/obj/item/ammo_box/c45
name = "ammo box (.45)"
icon_state = "45box"
- origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/c45
max_ammo = 20
@@ -53,7 +50,6 @@
/obj/item/ammo_box/n762
name = "ammo box (7.62x38mmR)"
icon_state = "10mmbox"
- origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/n762
max_ammo = 14
diff --git a/code/modules/projectiles/boxes_magazines/external_mag.dm b/code/modules/projectiles/boxes_magazines/external_mag.dm
index f288482349..b7b3a3e286 100644
--- a/code/modules/projectiles/boxes_magazines/external_mag.dm
+++ b/code/modules/projectiles/boxes_magazines/external_mag.dm
@@ -5,7 +5,6 @@
name = "pistol magazine (10mm)"
desc = "A gun magazine."
icon_state = "9x19p"
- origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/c10mm
caliber = "10mm"
max_ammo = 8
@@ -15,7 +14,6 @@
name = "rifle magazine (10mm)"
desc = "A well-worn magazine fitted for the surplus rifle."
icon_state = "75-8"
- origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/c10mm
caliber = "10mm"
max_ammo = 10
@@ -129,7 +127,6 @@
/obj/item/ammo_box/magazine/smgm45
name = "SMG magazine (.45)"
icon_state = "c20r45-24"
- origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/c45/nostamina
caliber = ".45"
max_ammo = 24
@@ -148,7 +145,6 @@
/obj/item/ammo_box/magazine/m50
name = "handgun magazine (.50ae)"
icon_state = "50ae"
- origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/a50AE
caliber = ".50"
max_ammo = 7
@@ -165,7 +161,6 @@
/obj/item/ammo_box/magazine/m556
name = "toploader magazine (5.56mm)"
icon_state = "5.56m"
- origin_tech = "combat=5;syndicate=1"
ammo_type = /obj/item/ammo_casing/a556
caliber = "a556"
max_ammo = 30
@@ -176,13 +171,12 @@
desc = "A drum magazine."
icon_state = "m12gs"
ammo_type = /obj/item/ammo_casing/shotgun/stunslug
- origin_tech = "combat=3;syndicate=1"
caliber = "shotgun"
max_ammo = 8
/obj/item/ammo_box/magazine/m12g/update_icon()
..()
- icon_state = "[initial(icon_state)]-[Ceiling(ammo_count(0)/8)*8]"
+ icon_state = "[initial(icon_state)]-[CEILING(ammo_count(0)/8, 1)*8]"
/obj/item/ammo_box/magazine/m12g/buckshot
name = "shotgun magazine (12g buckshot slugs)"
@@ -215,7 +209,6 @@
/obj/item/ammo_box/magazine/sniper_rounds
name = "sniper rounds (.50)"
icon_state = ".50mag"
- origin_tech = "combat=6;syndicate=2"
ammo_type = /obj/item/ammo_casing/p50
max_ammo = 6
caliber = ".50"
@@ -230,7 +223,6 @@
name = "sniper rounds (Zzzzz)"
desc = "Soporific sniper rounds, designed for happy days and dead quiet nights..."
icon_state = "soporific"
- origin_tech = "combat=6;syndicate=3"
ammo_type = /obj/item/ammo_casing/p50/soporific
max_ammo = 3
caliber = ".50"
@@ -239,7 +231,6 @@
name = "sniper rounds (penetrator)"
desc = "An extremely powerful round capable of passing straight through cover and anyone unfortunate enough to be behind it."
ammo_type = /obj/item/ammo_casing/p50/penetrator
- origin_tech = "combat=6;syndicate=3"
max_ammo = 5
//// SAW MAGAZINES
@@ -247,24 +238,20 @@
/obj/item/ammo_box/magazine/mm195x129
name = "box magazine (1.95x129mm)"
icon_state = "a762-50"
- origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/mm195x129
caliber = "mm195129"
max_ammo = 50
/obj/item/ammo_box/magazine/mm195x129/hollow
name = "box magazine (Hollow-Point 1.95x129mm)"
- origin_tech = "combat=3"
ammo_type = /obj/item/ammo_casing/mm195x129/hollow
/obj/item/ammo_box/magazine/mm195x129/ap
name = "box magazine (Armor Penetrating 1.95x129mm)"
- origin_tech = "combat=4"
ammo_type = /obj/item/ammo_casing/mm195x129/ap
/obj/item/ammo_box/magazine/mm195x129/incen
name = "box magazine (Incendiary 1.95x129mm)"
- origin_tech = "combat=4"
ammo_type = /obj/item/ammo_casing/mm195x129/incen
/obj/item/ammo_box/magazine/mm195x129/update_icon()
diff --git a/code/modules/projectiles/boxes_magazines/internal_mag.dm b/code/modules/projectiles/boxes_magazines/internal_mag.dm
index 3a8b4e6f2f..f486be732d 100644
--- a/code/modules/projectiles/boxes_magazines/internal_mag.dm
+++ b/code/modules/projectiles/boxes_magazines/internal_mag.dm
@@ -51,10 +51,10 @@
var/obj/item/ammo_casing/bullet = stored_ammo[i]
if(!bullet || !bullet.BB) // found a spent ammo
stored_ammo[i] = R
- R.loc = src
+ R.forceMove(src)
if(bullet)
- bullet.loc = get_turf(src.loc)
+ bullet.forceMove(drop_location())
return 1
return 0
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 085c618c42..ff7ed7653e 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -15,9 +15,8 @@
throw_speed = 3
throw_range = 5
force = 5
- origin_tech = "combat=1"
- needs_permit = 1
- unique_rename = 0
+ needs_permit = TRUE
+ unique_rename = FALSE
attack_verb = list("struck", "hit", "bashed")
var/fire_sound = "gunshot"
@@ -78,9 +77,8 @@
..()
var/obj/item/gun/G = locate(/obj/item/gun) in contents
if(G)
- G.loc = loc
- qdel(G.pin)
- G.pin = null
+ G.forceMove(loc)
+ QDEL_NULL(G.pin)
visible_message("[G] can now fit a new pin, but the old one was destroyed in the process.", null, null, 3)
qdel(src)
@@ -109,7 +107,7 @@
/obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj)
to_chat(user, "
*click*")
- playsound(user, 'sound/weapons/empty.ogg', 100, 1)
+ playsound(src, "gun_dry_fire", 30, 1)
/obj/item/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1)
@@ -500,7 +498,7 @@
user.client.pixel_x = world.icon_size*_x
user.client.pixel_y = world.icon_size*_y
else
- user.client.change_view(world.view)
+ user.client.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
user.client.pixel_y = 0
return zoomed
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index b7db29084a..680c86ff5c 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -2,7 +2,6 @@
desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason."
name = "projectile gun"
icon_state = "pistol"
- origin_tech = "combat=2;materials=2"
w_class = WEIGHT_CLASS_NORMAL
var/spawnwithmagazine = TRUE
var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info
@@ -31,8 +30,8 @@
var/obj/item/ammo_casing/AC = chambered //Find chambered round
if(istype(AC)) //there's a chambered round
if(casing_ejector)
- AC.forceMove(get_turf(src)) //Eject casing onto ground.
- AC.SpinAnimation(10, 1) //next gen special effects
+ AC.forceMove(drop_location()) //Eject casing onto ground.
+ AC.bounce_away(TRUE)
chambered = null
else if(empty_chamber)
chambered = null
@@ -59,7 +58,13 @@
if(user.transferItemToLoc(AM, src))
magazine = AM
to_chat(user, "
You load a new magazine into \the [src].")
- chamber_round()
+ if(magazine.ammo_count())
+ playsound(src, "gun_insert_full_magazine", 70, 1)
+ if(!chambered)
+ chamber_round()
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/weapons/gun_chamber_round.ogg', 100, 1), 3)
+ else
+ playsound(src, "gun_insert_empty_magazine", 70, 1)
A.update_icon()
update_icon()
return 1
@@ -108,16 +113,21 @@
/obj/item/gun/ballistic/attack_self(mob/living/user)
var/obj/item/ammo_casing/AC = chambered //Find chambered round
if(magazine)
- magazine.loc = get_turf(src.loc)
+ magazine.forceMove(drop_location())
user.put_in_hands(magazine)
magazine.update_icon()
+ if(magazine.ammo_count())
+ playsound(src, "sound/weapons/gun_magazine_remove_full.ogg", 70, 1)
+ else
+ playsound(src, "gun_remove_empty_magazine", 70, 1)
magazine = null
to_chat(user, "
You pull the magazine out of \the [src].")
else if(chambered)
- AC.loc = get_turf(src)
- AC.SpinAnimation(10, 1)
+ AC.forceMove(drop_location())
+ AC.bounce_away()
chambered = null
to_chat(user, "
You unload the round from \the [src]'s chamber.")
+ playsound(src, "gun_slide_lock", 70, 1)
else
to_chat(user, "
There's no magazine in \the [src].")
update_icon()
@@ -163,7 +173,7 @@
return(OXYLOSS)
else
user.visible_message("
[user] is pretending to blow [user.p_their()] brain[user.p_s()] out with [src]! It looks like [user.p_theyre()] trying to commit suicide!")
- playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1)
+ playsound(src, "gun_dry_fire", 30, 1)
return (OXYLOSS)
#undef BRAINS_BLOWN_THROW_SPEED
#undef BRAINS_BLOWN_THROW_RANGE
@@ -217,4 +227,3 @@
desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits all weapons."
icon = 'icons/obj/guns/projectile.dmi'
icon_state = "suppressor"
-
diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm
index 7fc37b8c56..9724f9be01 100644
--- a/code/modules/projectiles/guns/ballistic/automatic.dm
+++ b/code/modules/projectiles/guns/ballistic/automatic.dm
@@ -1,5 +1,4 @@
/obj/item/gun/ballistic/automatic
- origin_tech = "combat=4;materials=2"
w_class = WEIGHT_CLASS_NORMAL
var/alarmed = 0
var/select = 1
@@ -89,7 +88,6 @@
desc = "A bullpup two-round burst .45 SMG, designated 'C-20r'. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp."
icon_state = "c20r"
item_state = "c20r"
- origin_tech = "combat=5;materials=2;syndicate=6"
mag_type = /obj/item/ammo_box/magazine/smgm45
fire_sound = 'sound/weapons/gunshot_smg.ogg'
fire_delay = 2
@@ -110,7 +108,7 @@
/obj/item/gun/ballistic/automatic/c20r/update_icon()
..()
- icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
+ icon_state = "c20r[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
/obj/item/gun/ballistic/automatic/wt550
name = "security auto rifle"
@@ -125,13 +123,12 @@
/obj/item/gun/ballistic/automatic/wt550/update_icon()
..()
- icon_state = "wt550[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]"
+ icon_state = "wt550[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""]"
/obj/item/gun/ballistic/automatic/mini_uzi
name = "\improper Type U3 Uzi"
desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds."
icon_state = "mini-uzi"
- origin_tech = "combat=4;materials=2;syndicate=4"
mag_type = /obj/item/ammo_box/magazine/uzim9mm
burst_size = 2
@@ -140,7 +137,6 @@
desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be toggled on and off."
icon_state = "m90"
item_state = "m90"
- origin_tech = "combat=5;materials=2;syndicate=6"
mag_type = /obj/item/ammo_box/magazine/m556
fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = FALSE
@@ -214,7 +210,6 @@
item_state = "shotgun"
w_class = WEIGHT_CLASS_HUGE
slot_flags = 0
- origin_tech = "combat=5;materials=1;syndicate=3"
mag_type = /obj/item/ammo_box/magazine/tommygunm45
fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = FALSE
@@ -223,11 +218,10 @@
/obj/item/gun/ballistic/automatic/ar
name = "\improper NT-ARG 'Boarder'"
- desc = "A robust assault rile used by Nanotrasen fighting forces."
+ desc = "A robust assault rifle used by Nanotrasen fighting forces."
icon_state = "arg"
item_state = "arg"
slot_flags = 0
- origin_tech = "combat=6;engineering=4"
mag_type = /obj/item/ammo_box/magazine/m556
fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = FALSE
@@ -243,7 +237,6 @@
item_state = "bulldog"
w_class = WEIGHT_CLASS_NORMAL
weapon_weight = WEAPON_MEDIUM
- origin_tech = "combat=6;materials=4;syndicate=6"
mag_type = /obj/item/ammo_box/magazine/m12g
fire_sound = 'sound/weapons/gunshot.ogg'
can_suppress = FALSE
@@ -281,7 +274,6 @@
item_state = "l6closedmag"
w_class = WEIGHT_CLASS_HUGE
slot_flags = 0
- origin_tech = "combat=6;engineering=3;syndicate=6"
mag_type = /obj/item/ammo_box/magazine/mm195x129
weapon_weight = WEAPON_HEAVY
fire_sound = 'sound/weapons/gunshot_smg.ogg'
@@ -312,7 +304,7 @@
/obj/item/gun/ballistic/automatic/l6_saw/update_icon()
- icon_state = "l6[cover_open ? "open" : "closed"][magazine ? Ceiling(get_ammo(0)/12.5)*25 : "-empty"][suppressed ? "-suppressed" : ""]"
+ icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEILING(get_ammo(0)/12.5, 1)*25 : "-empty"][suppressed ? "-suppressed" : ""]"
item_state = "l6[cover_open ? "openmag" : "closedmag"]"
@@ -333,7 +325,7 @@
else if(cover_open && magazine)
//drop the mag
magazine.update_icon()
- magazine.loc = get_turf(src.loc)
+ magazine.forceMove(drop_location())
user.put_in_hands(magazine)
magazine = null
update_icon()
@@ -361,7 +353,6 @@
mag_type = /obj/item/ammo_box/magazine/sniper_rounds
fire_delay = 40
burst_size = 1
- origin_tech = "combat=7"
can_unsuppress = TRUE
can_suppress = TRUE
w_class = WEIGHT_CLASS_NORMAL
@@ -382,14 +373,12 @@
name = "syndicate sniper rifle"
desc = "An illegally modified .50 cal sniper rifle with suppression compatibility. Quickscoping still doesn't work."
pin = /obj/item/device/firing_pin/implant/pindicate
- origin_tech = "combat=7;syndicate=6"
// Old Semi-Auto Rifle //
/obj/item/gun/ballistic/automatic/surplus
name = "Surplus Rifle"
desc = "One of countless obsolete ballistic rifles that still sees use as a cheap deterrent. Uses 10mm ammo and its bulky frame prevents one-hand firing."
- origin_tech = "combat=3;materials=2"
icon_state = "surplus"
item_state = "moistnugget"
weapon_weight = WEAPON_HEAVY
@@ -426,5 +415,5 @@
/obj/item/gun/ballistic/automatic/laser/update_icon()
..()
- icon_state = "oldrifle[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]"
+ icon_state = "oldrifle[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""]"
return
diff --git a/code/modules/projectiles/guns/ballistic/laser_gatling.dm b/code/modules/projectiles/guns/ballistic/laser_gatling.dm
index f7b5b4cd61..2dc6dd9857 100644
--- a/code/modules/projectiles/guns/ballistic/laser_gatling.dm
+++ b/code/modules/projectiles/guns/ballistic/laser_gatling.dm
@@ -97,7 +97,6 @@
icon = 'icons/obj/guns/minigun.dmi'
icon_state = "minigun_spin"
item_state = "minigun"
- origin_tech = "combat=6;powerstorage=5;magnets=4"
flags_1 = CONDUCT_1
slowdown = 1
slot_flags = null
diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm
index a32d78bb2e..01e323e1a7 100644
--- a/code/modules/projectiles/guns/ballistic/launchers.dm
+++ b/code/modules/projectiles/guns/ballistic/launchers.dm
@@ -35,7 +35,6 @@
desc = "A prototype pistol designed to fire self propelled rockets."
icon_state = "gyropistol"
fire_sound = 'sound/weapons/grenadelaunch.ogg'
- origin_tech = "combat=5"
mag_type = /obj/item/ammo_box/magazine/m75
burst_size = 1
fire_delay = 0
@@ -52,7 +51,6 @@
icon_state = "speargun"
item_state = "speargun"
w_class = WEIGHT_CLASS_BULKY
- origin_tech = "combat=4;engineering=4"
force = 10
can_suppress = FALSE
mag_type = /obj/item/ammo_box/magazine/internal/speargun
diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm
index 06bb452b0b..569040745f 100644
--- a/code/modules/projectiles/guns/ballistic/pistol.dm
+++ b/code/modules/projectiles/guns/ballistic/pistol.dm
@@ -3,7 +3,6 @@
desc = "A small, easily concealable 10mm handgun. Has a threaded barrel for suppressors."
icon_state = "pistol"
w_class = WEIGHT_CLASS_SMALL
- origin_tech = "combat=3;materials=2;syndicate=4"
mag_type = /obj/item/ammo_box/magazine/m10mm
can_suppress = TRUE
burst_size = 1
@@ -55,7 +54,6 @@
desc = "The original russian version of a widely used Syndicate sidearm. Uses 9mm ammo."
icon_state = "aps"
w_class = WEIGHT_CLASS_SMALL
- origin_tech = "combat=3;materials=2;syndicate=3"
mag_type = /obj/item/ammo_box/magazine/pistolm9mm
can_suppress = FALSE
burst_size = 3
@@ -66,7 +64,6 @@
name = "flat gun"
desc = "A 2 dimensional gun.. what?"
icon_state = "flatgun"
- origin_tech = "combat=3;materials=2;abductor=3"
/obj/item/gun/ballistic/automatic/pistol/stickman/pickup(mob/living/user)
to_chat(user, "
As you try to pick up [src], it slips out of your grip..")
diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm
index 584445a573..563b3d9ad5 100644
--- a/code/modules/projectiles/guns/ballistic/revolver.dm
+++ b/code/modules/projectiles/guns/ballistic/revolver.dm
@@ -3,7 +3,6 @@
desc = "A suspicious revolver. Uses .357 ammo." //usually used by syndicates
icon_state = "revolver"
mag_type = /obj/item/ammo_box/magazine/internal/cylinder
- origin_tech = "combat=3;materials=2"
casing_ejector = FALSE
/obj/item/gun/ballistic/revolver/Initialize()
@@ -40,13 +39,11 @@
var/obj/item/ammo_casing/CB
CB = magazine.get_round(0)
if(CB)
- CB.loc = get_turf(src.loc)
- CB.SpinAnimation(10, 1)
- CB.update_icon()
+ CB.forceMove(drop_location())
+ CB.bounce_away(FALSE, NONE)
num_unloaded++
if (num_unloaded)
to_chat(user, "
You unload [num_unloaded] shell\s from [src].")
- playsound(user, 'sound/weapons/bulletremove.ogg', 60, 1)
else
to_chat(user, "
[src] is empty!")
@@ -158,8 +155,8 @@
name = "nagant revolver"
desc = "An old model of revolver that originated in Russia. Able to be suppressed. Uses 7.62x38mmR ammo."
icon_state = "nagant"
- origin_tech = "combat=3"
can_suppress = TRUE
+
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev762
@@ -169,7 +166,6 @@
/obj/item/gun/ballistic/revolver/russian
name = "\improper russian revolver"
desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism requiring you to spin the chamber before each trigger pull."
- origin_tech = "combat=2;materials=2"
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rus357
var/spun = FALSE
@@ -231,7 +227,7 @@
return
user.visible_message("
*click*")
- playsound(user, 'sound/weapons/empty.ogg', 100, 1)
+ playsound(src, "gun_dry_fire", 30, 1)
/obj/item/gun/ballistic/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = "head")
user.apply_damage(300, BRUTE, affecting)
@@ -291,7 +287,7 @@
var/obj/item/ammo_casing/CB
CB = magazine.get_round(0)
chambered = null
- CB.loc = get_turf(src.loc)
+ CB.forceMove(drop_location())
CB.update_icon()
num_unloaded++
if (num_unloaded)
diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm
index 105e170429..e702013233 100644
--- a/code/modules/projectiles/guns/ballistic/shotgun.dm
+++ b/code/modules/projectiles/guns/ballistic/shotgun.dm
@@ -7,7 +7,6 @@
force = 10
flags_1 = CONDUCT_1
slot_flags = SLOT_BACK
- origin_tech = "combat=4;materials=2"
mag_type = /obj/item/ammo_box/magazine/internal/shot
casing_ejector = FALSE
var/recentpump = 0 // to prevent spammage
@@ -57,8 +56,8 @@
/obj/item/gun/ballistic/shotgun/proc/pump_unload(mob/M)
if(chambered)//We have a shell in the chamber
- chambered.loc = get_turf(src)//Eject casing
- chambered.SpinAnimation(5, 1)
+ chambered.forceMove(drop_location())//Eject casing
+ chambered.bounce_away()
chambered = null
/obj/item/gun/ballistic/shotgun/proc/pump_reload(mob/M)
@@ -189,7 +188,6 @@
name = "combat shotgun"
desc = "A semi automatic shotgun with tactical furniture and a six-shell capacity underneath."
icon_state = "cshotgun"
- origin_tech = "combat=6"
mag_type = /obj/item/ammo_box/magazine/internal/shot/com
w_class = WEIGHT_CLASS_HUGE
@@ -197,7 +195,6 @@
name = "compact combat shotgun"
desc = "A compact version of the semi automatic combat shotgun. For close encounters."
icon_state = "cshotgunc"
- origin_tech = "combat=4;materials=2"
mag_type = /obj/item/ammo_box/magazine/internal/shot/com/compact
w_class = WEIGHT_CLASS_BULKY
@@ -207,7 +204,6 @@
name = "cycler shotgun"
desc = "An advanced shotgun with two separate magazine tubes, allowing you to quickly toggle between ammo types."
icon_state = "cycler"
- origin_tech = "combat=4;materials=2"
mag_type = /obj/item/ammo_box/magazine/internal/shot/tube
w_class = WEIGHT_CLASS_HUGE
var/toggled = FALSE
diff --git a/code/modules/projectiles/guns/ballistic/toy.dm b/code/modules/projectiles/guns/ballistic/toy.dm
index c251a791d0..a04d6f1b54 100644
--- a/code/modules/projectiles/guns/ballistic/toy.dm
+++ b/code/modules/projectiles/guns/ballistic/toy.dm
@@ -51,7 +51,6 @@
icon = 'icons/obj/guns/toy.dmi'
force = 0
throwforce = 0
- origin_tech = null
mag_type = /obj/item/ammo_box/magazine/internal/shot/toy
clumsy_check = 0
needs_permit = 0
diff --git a/code/modules/projectiles/guns/beam_rifle.dm b/code/modules/projectiles/guns/beam_rifle.dm
index a88e271056..ee8036bf44 100644
--- a/code/modules/projectiles/guns/beam_rifle.dm
+++ b/code/modules/projectiles/guns/beam_rifle.dm
@@ -23,7 +23,6 @@
slot_flags = SLOT_BACK
force = 15
materials = list()
- origin_tech = ""
recoil = 4
ammo_x_offset = 3
ammo_y_offset = 3
@@ -179,7 +178,7 @@
zoom_animating = 0
animate(current_user.client, pixel_x = 0, pixel_y = 0, 0, FALSE, LINEAR_EASING, ANIMATION_END_NOW)
zoom_current_view_increase = 0
- current_user.client.change_view(world.view)
+ current_user.client.change_view(CONFIG_GET(string/default_view))
zooming_angle = 0
current_zoom_x = 0
current_zoom_y = 0
@@ -358,15 +357,15 @@
if(lastfire > world.time + delay)
return
lastfire = world.time
+ . = ..()
stop_aiming()
- return ..()
/obj/item/gun/energy/beam_rifle/proc/sync_ammo()
for(var/obj/item/ammo_casing/energy/beam_rifle/AC in contents)
AC.sync_stats()
/obj/item/gun/energy/beam_rifle/proc/delay_penalty(amount)
- aiming_time_left = Clamp(aiming_time_left + amount, 0, aiming_time)
+ aiming_time_left = CLAMP(aiming_time_left + amount, 0, aiming_time)
/obj/item/ammo_casing/energy/beam_rifle
name = "particle acceleration lens"
@@ -417,11 +416,11 @@
HS_BB.stun = projectile_stun
HS_BB.impact_structure_damage = impact_structure_damage
HS_BB.aoe_mob_damage = aoe_mob_damage
- HS_BB.aoe_mob_range = Clamp(aoe_mob_range, 0, 15) //Badmin safety lock
+ HS_BB.aoe_mob_range = CLAMP(aoe_mob_range, 0, 15) //Badmin safety lock
HS_BB.aoe_fire_chance = aoe_fire_chance
HS_BB.aoe_fire_range = aoe_fire_range
HS_BB.aoe_structure_damage = aoe_structure_damage
- HS_BB.aoe_structure_range = Clamp(aoe_structure_range, 0, 15) //Badmin safety lock
+ HS_BB.aoe_structure_range = CLAMP(aoe_structure_range, 0, 15) //Badmin safety lock
HS_BB.wall_devastate = wall_devastate
HS_BB.wall_pierce_amount = wall_pierce_amount
HS_BB.structure_pierce_amount = structure_piercing
@@ -503,11 +502,11 @@
if(!do_pierce)
return FALSE
if(pierced[target]) //we already pierced them go away
- loc = get_turf(target)
+ forceMove(get_turf(target))
return TRUE
if(isclosedturf(target))
if(wall_pierce++ < wall_pierce_amount)
- loc = target
+ forceMove(target)
if(prob(wall_devastate))
if(iswallturf(target))
var/turf/closed/wall/W = target
@@ -523,7 +522,7 @@
var/obj/O = AM
O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(AM), BURN, "energy", FALSE)
pierced[AM] = TRUE
- loc = get_turf(AM)
+ forceMove(AM.drop_location())
structure_pierce++
return TRUE
return FALSE
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index aa5b137a5b..b52a56426b 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -130,7 +130,7 @@
..()
if(!automatic_charge_overlays)
return
- var/ratio = Ceiling((cell.charge / cell.maxcharge) * charge_sections)
+ var/ratio = CEILING((cell.charge / cell.maxcharge) * charge_sections, 1)
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
var/iconState = "[icon_state]_charge"
var/itemState = null
@@ -175,7 +175,7 @@
return(OXYLOSS)
else
user.visible_message("
[user] is pretending to blow [user.p_their()] brains out with [src]! It looks like [user.p_theyre()] trying to commit suicide!")
- playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1)
+ playsound(src, "gun_dry_fire", 30, 1)
return (OXYLOSS)
diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm
index c9ec6077aa..524f1e8f90 100644
--- a/code/modules/projectiles/guns/energy/energy_gun.dm
+++ b/code/modules/projectiles/guns/energy/energy_gun.dm
@@ -4,7 +4,6 @@
icon_state = "energy"
item_state = null //so the human update icon uses the icon_state instead.
ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
- origin_tech = "combat=4;magnets=3"
modifystate = 1
can_flashlight = 1
ammo_x_offset = 3
@@ -55,7 +54,6 @@
name = "\improper X-01 MultiPhase Energy Gun"
desc = "This is an expensive, modern recreation of an antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time."
icon_state = "hoslaser"
- origin_tech = null
force = 10
ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/disabler)
ammo_x_offset = 4
@@ -68,7 +66,6 @@
item_state = "dragnet"
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
- origin_tech = "combat=4;magnets=3;bluespace=4"
ammo_type = list(/obj/item/ammo_casing/energy/net, /obj/item/ammo_casing/energy/trap)
can_flashlight = 0
ammo_x_offset = 1
@@ -96,7 +93,6 @@
desc = "An energy gun with an experimental miniaturized nuclear reactor that automatically charges the internal power cell."
icon_state = "nucgun"
item_state = "nucgun"
- origin_tech = "combat=4;magnets=4;powerstorage=4"
charge_delay = 5
pin = null
can_charge = 0
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index d2261fc6f8..3b93a960ca 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -7,7 +7,6 @@
cell_type = /obj/item/stock_parts/cell/emproof
needs_permit = 0
unique_rename = 1
- origin_tech = "combat=3;powerstorage=3;engineering=3"
weapon_weight = WEAPON_LIGHT
can_flashlight = 1
flight_x_offset = 15
@@ -213,7 +212,6 @@
desc = "An upgrade for kinetic accelerators."
icon = 'icons/obj/objects.dmi'
icon_state = "modkit"
- origin_tech = "programming=2;materials=2;magnets=4"
w_class = WEIGHT_CLASS_SMALL
require_module = 1
module_type = /obj/item/robot_module/miner
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index 6f916a5709..37bb252adc 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -5,7 +5,6 @@
item_state = "laser"
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=2000)
- origin_tech = "combat=4;magnets=2"
ammo_type = list(/obj/item/ammo_casing/energy/lasergun)
ammo_x_offset = 1
shaded_charge = 1
@@ -13,7 +12,6 @@
/obj/item/gun/energy/laser/practice
name = "practice laser gun"
desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice."
- origin_tech = "combat=2;magnets=2"
ammo_type = list(/obj/item/ammo_casing/energy/laser/practice)
clumsy_check = 0
needs_permit = 0
@@ -37,7 +35,6 @@
item_state = "caplaser"
desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding."
force = 10
- origin_tech = null
ammo_x_offset = 3
selfcharge = 1
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
@@ -47,13 +44,11 @@
icon_state = "lasercannon"
item_state = "laser"
desc = "An industrial-grade heavy-duty laser rifle with a modified laser lens to scatter its shot into multiple smaller lasers. The inner-core can self-charge for theoretically infinite use."
- origin_tech = "combat=5;materials=4;powerstorage=4"
ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser)
/obj/item/gun/energy/laser/cyborg
can_charge = 0
desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?"
- origin_tech = null
use_cyborg_cell = 1
/obj/item/gun/energy/laser/cyborg/emp_act()
@@ -85,7 +80,6 @@
force = 10
flags_1 = CONDUCT_1
slot_flags = SLOT_BACK
- origin_tech = "combat=4;magnets=4;powerstorage=3"
ammo_type = list(/obj/item/ammo_casing/energy/laser/accelerator)
pin = null
ammo_x_offset = 3
@@ -111,7 +105,6 @@
desc = "A high-power laser gun capable of expelling concentrated x-ray blasts that pass through multiple soft targets and heavier materials."
icon_state = "xray"
item_state = null
- origin_tech = "combat=6;materials=4;magnets=4;syndicate=1"
ammo_type = list(/obj/item/ammo_casing/energy/xray)
pin = null
ammo_x_offset = 3
@@ -123,7 +116,6 @@
icon_state = "bluetag"
desc = "A retro laser gun modified to fire harmless blue beams of light. Sound effects included!"
ammo_type = list(/obj/item/ammo_casing/energy/laser/bluetag)
- origin_tech = "combat=2;magnets=2"
clumsy_check = 0
needs_permit = 0
pin = /obj/item/device/firing_pin/tag/blue
@@ -135,7 +127,6 @@
icon_state = "redtag"
desc = "A retro laser gun modified to fire harmless beams red of light. Sound effects included!"
ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag)
- origin_tech = "combat=2;magnets=2"
clumsy_check = 0
needs_permit = 0
pin = /obj/item/device/firing_pin/tag/red
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index d7c54f193d..a4ae8cae13 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -3,7 +3,6 @@
desc = "A man-portable anti-armor weapon designed to disable mechanical threats at range."
icon_state = "ionrifle"
item_state = null //so the human update icon uses the icon_state instead.
- origin_tech = "combat=4;magnets=4"
can_flashlight = 1
w_class = WEIGHT_CLASS_HUGE
flags_1 = CONDUCT_1
@@ -31,7 +30,6 @@
name = "biological demolecularisor"
desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements."
icon_state = "decloner"
- origin_tech = "combat=4;materials=4;biotech=5;plasmatech=6"
ammo_type = list(/obj/item/ammo_casing/energy/declone)
pin = null
ammo_x_offset = 1
@@ -48,7 +46,6 @@
icon_state = "flora"
item_state = "gun"
ammo_type = list(/obj/item/ammo_casing/energy/flora/yield, /obj/item/ammo_casing/energy/flora/mut)
- origin_tech = "materials=2;biotech=4"
modifystate = 1
ammo_x_offset = 1
selfcharge = 1
@@ -89,7 +86,6 @@
item_state = "crossbow"
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=2000)
- origin_tech = "combat=4;magnets=4;syndicate=5"
suppressed = TRUE
ammo_type = list(/obj/item/ammo_casing/energy/bolt)
weapon_weight = WEAPON_LIGHT
@@ -114,7 +110,6 @@
icon_state = "crossbowlarge"
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=4000)
- origin_tech = "combat=4;magnets=4;syndicate=2"
suppressed = null
ammo_type = list(/obj/item/ammo_casing/energy/bolt/large)
pin = null
@@ -124,10 +119,8 @@
desc = "A mining tool capable of expelling concentrated plasma bursts. You could use it to cut limbs off xenos! Or, you know, mine stuff."
icon_state = "plasmacutter"
item_state = "plasmacutter"
- origin_tech = "combat=1;materials=3;magnets=2;plasmatech=3;engineering=1"
ammo_type = list(/obj/item/ammo_casing/energy/plasma)
flags_1 = CONDUCT_1
- container_type = OPENCONTAINER_1
attack_verb = list("attacked", "slashed", "cut", "sliced")
force = 12
sharpness = IS_SHARP
@@ -159,7 +152,6 @@
/obj/item/gun/energy/plasmacutter/adv
name = "advanced plasma cutter"
icon_state = "adv_plasmacutter"
- origin_tech = "combat=3;materials=4;magnets=3;plasmatech=4;engineering=2"
force = 15
ammo_type = list(/obj/item/ammo_casing/energy/plasma/adv)
@@ -169,7 +161,6 @@
ammo_type = list(/obj/item/ammo_casing/energy/wormhole, /obj/item/ammo_casing/energy/wormhole/orange)
item_state = null
icon_state = "wormhole_projector"
- origin_tech = "combat=4;bluespace=6;plasmatech=4;engineering=4"
var/obj/effect/portal/p_blue
var/obj/effect/portal/p_orange
@@ -243,7 +234,6 @@
name = "temperature gun"
icon_state = "freezegun"
desc = "A gun that changes temperatures."
- origin_tech = "combat=4;materials=4;powerstorage=3;magnets=2"
ammo_type = list(/obj/item/ammo_casing/energy/temp, /obj/item/ammo_casing/energy/temp/hot)
cell_type = "/obj/item/stock_parts/cell/high"
pin = null
@@ -251,7 +241,6 @@
/obj/item/gun/energy/temperature/security
name = "security temperature gun"
desc = "A weapon that can only be used to its full potential by the truly robust."
- origin_tech = "combat=2;materials=2;powerstorage=1;magnets=1"
pin = /obj/item/device/firing_pin
/obj/item/gun/energy/laser/instakill
@@ -261,7 +250,6 @@
desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit."
ammo_type = list(/obj/item/ammo_casing/energy/instakill)
force = 60
- origin_tech = "combat=7;magnets=6"
/obj/item/gun/energy/laser/instakill/red
desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a red design."
@@ -282,7 +270,6 @@
name = "one-point bluespace-gravitational manipulator"
desc = "An experimental, multi-mode device that fires bolts of Zero-Point Energy, causing local distortions in gravity."
ammo_type = list(/obj/item/ammo_casing/energy/gravityrepulse, /obj/item/ammo_casing/energy/gravityattract, /obj/item/ammo_casing/energy/gravitychaos)
- origin_tech = "combat=4;magnets=4;materials=6;powerstorage=4;bluespace=4"
item_state = "gravity_gun"
icon_state = "gravity_gun"
var/power = 4
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 1b9532c2af..69f6a47813 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -4,7 +4,6 @@
icon_state = "taser"
item_state = null //so the human update icon uses the icon_state instead.
ammo_type = list(/obj/item/ammo_casing/energy/electrode)
- origin_tech = "combat=3"
ammo_x_offset = 3
/obj/item/gun/energy/tesla_revolver
@@ -13,7 +12,6 @@
icon_state = "tesla"
item_state = "tesla"
ammo_type = list(/obj/item/ammo_casing/energy/tesla_revolver)
- origin_tech = "combat=4;materials=4;powerstorage=4"
can_flashlight = 0
pin = null
shaded_charge = 1
@@ -23,7 +21,6 @@
desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams."
icon_state = "advtaser"
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler)
- origin_tech = "combat=4"
ammo_x_offset = 2
/obj/item/gun/energy/e_gun/advtaser/cyborg
@@ -38,7 +35,6 @@
desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse."
icon_state = "disabler"
item_state = null
- origin_tech = "combat=3"
ammo_type = list(/obj/item/ammo_casing/energy/disabler)
ammo_x_offset = 3
diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/grenade_launcher.dm
index d87a657710..771c0091e3 100644
--- a/code/modules/projectiles/guns/grenade_launcher.dm
+++ b/code/modules/projectiles/guns/grenade_launcher.dm
@@ -42,7 +42,7 @@
"
You fire the grenade launcher!")
var/obj/item/grenade/F = grenades[1] //Now with less copypasta!
grenades -= F
- F.loc = user.loc
+ F.forceMove(user.loc)
F.throw_at(target, 30, 2, user)
message_admins("[key_name_admin(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).")
log_game("[key_name(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).")
diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm
index 21bc12bb1f..36dc4937c5 100644
--- a/code/modules/projectiles/guns/magic.dm
+++ b/code/modules/projectiles/guns/magic.dm
@@ -16,7 +16,6 @@
var/can_charge = 1
var/ammo_type
var/no_den_usage
- origin_tech = null
clumsy_check = 0
trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses magic instead
pin = /obj/item/device/firing_pin/magic
diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm
index 27fb040de4..bf3ade0748 100644
--- a/code/modules/projectiles/guns/magic/wand.dm
+++ b/code/modules/projectiles/guns/magic/wand.dm
@@ -12,9 +12,9 @@
/obj/item/gun/magic/wand/Initialize()
if(prob(75) && variable_charges) //25% chance of listed max charges, 50% chance of 1/2 max charges, 25% chance of 1/3 max charges
if(prob(33))
- max_charges = Ceiling(max_charges / 3)
+ max_charges = CEILING(max_charges / 3, 1)
else
- max_charges = Ceiling(max_charges / 2)
+ max_charges = CEILING(max_charges / 2, 1)
return ..()
/obj/item/gun/magic/wand/examine(mob/user)
diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm
index 17d2ea7cbe..ac9f7daedf 100644
--- a/code/modules/projectiles/guns/syringe_gun.dm
+++ b/code/modules/projectiles/guns/syringe_gun.dm
@@ -8,7 +8,6 @@
throw_range = 7
force = 4
materials = list(MAT_METAL=2000)
- origin_tech = "combat=2;biotech=3"
clumsy_check = 0
fire_sound = 'sound/items/syringeproj.ogg'
var/list/syringes = list()
@@ -43,7 +42,7 @@
if(!S)
return 0
- S.loc = user.loc
+ S.forceMove(user.loc)
syringes.Remove(S)
to_chat(user, "
You unload [S] from \the [src].")
@@ -75,7 +74,6 @@
icon_state = "syringe_pistol"
item_state = "gun" //Smaller inhand
w_class = WEIGHT_CLASS_SMALL
- origin_tech = "combat=2;syndicate=2;biotech=3"
force = 2 //Also very weak because it's smaller
suppressed = TRUE //Softer fire sound
can_unsuppress = FALSE //Permanently silenced
@@ -83,7 +81,6 @@
/obj/item/gun/syringe/dna
name = "modified syringe gun"
desc = "A syringe gun that has been modified to fit DNA injectors instead of normal syringes."
- origin_tech = "combat=2;syndicate=2;biotech=3"
/obj/item/gun/syringe/dna/Initialize()
. = ..()
@@ -104,4 +101,4 @@
return TRUE
else
to_chat(user, "
[src] cannot hold more syringes!")
- return FALSE
\ No newline at end of file
+ return FALSE
diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm
index 75066540cf..faf7de9010 100644
--- a/code/modules/projectiles/pins.dm
+++ b/code/modules/projectiles/pins.dm
@@ -4,7 +4,6 @@
icon = 'icons/obj/device.dmi'
icon_state = "firing_pin"
item_state = "pen"
- origin_tech = "materials=2;combat=4"
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
attack_verb = list("poked")
@@ -25,7 +24,7 @@
if(istype(target, /obj/item/gun))
var/obj/item/gun/G = target
if(G.pin && (force_replace || G.pin.pin_removeable))
- G.pin.loc = get_turf(G)
+ G.pin.forceMove(get_turf(G))
G.pin.gun_remove(user)
to_chat(user, "
You remove [G]'s old pin.")
@@ -79,7 +78,6 @@
desc = "This safety firing pin allows weapons to be fired within proximity to a firing range."
fail_message = "
TEST RANGE CHECK FAILED."
pin_removeable = 1
- origin_tech = "combat=2;materials=2"
/obj/item/device/firing_pin/test_range/pin_auth(mob/living/user)
for(var/obj/machinery/magnetic_controller/M in range(user, 3))
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index a45b713b85..79e2fdf903 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -168,7 +168,7 @@
/obj/item/projectile/proc/vol_by_damage()
if(src.damage)
- return Clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100
+ return CLAMP((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100
else
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
@@ -177,6 +177,7 @@
ricochets++
if(A.handle_ricochet(src))
ignore_source_check = TRUE
+ range = initial(range)
return FALSE
if(firer && !ignore_source_check)
if(A == firer || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech
@@ -187,7 +188,7 @@
def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use.
if(isturf(A) && hitsound_wall)
- var/volume = Clamp(vol_by_damage() + 20, 0, 100)
+ var/volume = CLAMP(vol_by_damage() + 20, 0, 100)
if(suppressed)
volume = 5
playsound(loc, hitsound_wall, volume, 1, -1)
@@ -258,7 +259,7 @@
return
var/elapsed_time_deciseconds = (world.time - last_projectile_move) + time_offset
time_offset = 0
- var/required_moves = speed > 0? Floor(elapsed_time_deciseconds / speed) : MOVES_HITSCAN //Would be better if a 0 speed made hitscan but everyone hates those so I can't make it a universal system :<
+ var/required_moves = speed > 0? FLOOR(elapsed_time_deciseconds / speed, 1) : MOVES_HITSCAN //Would be better if a 0 speed made hitscan but everyone hates those so I can't make it a universal system :<
if(required_moves == MOVES_HITSCAN)
required_moves = SSprojectiles.global_max_tick_moves
else
@@ -266,7 +267,7 @@
var/overrun = required_moves - SSprojectiles.global_max_tick_moves
required_moves = SSprojectiles.global_max_tick_moves
time_offset += overrun * speed
- time_offset += Modulus(elapsed_time_deciseconds, speed)
+ time_offset += MODULUS(elapsed_time_deciseconds, speed)
for(var/i in 1 to required_moves)
pixel_move(required_moves)
@@ -286,7 +287,7 @@
setAngle(Angle + ((rand() - 0.5) * spread))
if(isnull(Angle)) //Try to resolve through offsets if there's no angle set.
var/turf/starting = get_turf(src)
- var/turf/target = locate(Clamp(starting + xo, 1, world.maxx), Clamp(starting + yo, 1, world.maxy), starting.z)
+ var/turf/target = locate(CLAMP(starting + xo, 1, world.maxx), CLAMP(starting + yo, 1, world.maxy), starting.z)
setAngle(Get_Angle(src, target))
if(!nondirectional_sprite)
var/matrix/M = new
@@ -358,8 +359,9 @@
forceMove(get_turf(source))
starting = get_turf(source)
original = target
- yo = targloc.y - curloc.y
- xo = targloc.x - curloc.x
+ if(targloc || !params)
+ yo = targloc.y - curloc.y
+ xo = targloc.x - curloc.x
if(isliving(source) && params)
var/list/calculated = calculate_projectile_angle_and_pixel_offsets(source, params)
@@ -395,11 +397,13 @@
var/y = text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32
//Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average.
- var/screenview = (user.client.view * 2 + 1) * world.icon_size //Refer to http://www.byond.com/docs/ref/info.html#/client/var/view for mad maths
+ var/list/screenview = getviewsize(user.client.view)
+ var/screenviewX = screenview[1] * world.icon_size
+ var/screenviewY = screenview[2] * world.icon_size
- var/ox = round(screenview/2) - user.client.pixel_x //"origin" x
- var/oy = round(screenview/2) - user.client.pixel_y //"origin" y
- angle = Atan2(y - oy, x - ox)
+ var/ox = round(screenviewX/2) - user.client.pixel_x //"origin" x
+ var/oy = round(screenviewY/2) - user.client.pixel_y //"origin" y
+ angle = ATAN2(y - oy, x - ox)
return list(angle, p_x, p_y)
/obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it.
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index a10c264b9a..9b4842d644 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -285,7 +285,7 @@
to_chat(new_mob, poly_msg)
M.transfer_observers_to(new_mob)
-
+
qdel(M)
return new_mob
@@ -319,7 +319,7 @@
L.mind.transfer_to(S)
if(owner)
to_chat(S, "
You are an animate statue. You cannot move when monitored, but are nearly invincible and deadly when unobserved! Do not harm [owner], your creator.")
- P.loc = S
+ P.forceMove(S)
return
else
var/obj/O = src
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index 5a650ff2c3..152cff6c74 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -100,7 +100,7 @@
/obj/item/projectile/meteor/Collide(atom/A)
if(A == firer)
- loc = A.loc
+ forceMove(A.loc)
return
A.ex_act(EXPLODE_HEAVY)
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
@@ -612,4 +612,3 @@
knockdown = 0
nodamage = TRUE
return ..()
-
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index 9c4bff72cb..94e8b465c1 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -59,6 +59,19 @@
if(my_atom && my_atom.reagents == src)
my_atom.reagents = null
+
+// Used in attack logs for reagents in pills and such
+/datum/reagents/proc/log_list()
+ if(!length(reagent_list))
+ return "no reagents"
+
+ var/list/data = list()
+ for(var/r in reagent_list) //no reagents will be left behind
+ var/datum/reagent/R = r
+ data += "[R.id] ([round(R.volume, 0.1)]u)"
+ //Using IDs because SOME chemicals (I'm looking at you, chlorhydrate-beer) have the same names as other chemicals.
+ return english_list(data)
+
/datum/reagents/proc/remove_any(amount = 1)
var/list/cached_reagents = reagent_list
var/total_transfered = 0
@@ -228,8 +241,7 @@
var/list/cached_reagents = reagent_list
var/list/cached_addictions = addiction_list
if(C)
- chem_temp = C.bodytemperature
- handle_reactions()
+ expose_temperature(C.bodytemperature, 0.25)
var/need_mob_update = 0
for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
@@ -580,7 +592,7 @@
if (R.id == reagent)
//clamp the removal amount to be between current reagent amount
//and zero, to prevent removing more than the holder has stored
- amount = Clamp(amount, 0, R.volume)
+ amount = CLAMP(amount, 0, R.volume)
R.volume -= amount
update_total()
if(!safety)//So it does not handle reactions when it need not to
@@ -731,6 +743,16 @@
out += "[taste_desc]"
return english_list(out, "something indescribable")
+
+
+/datum/reagents/proc/expose_temperature(var/temperature, var/coeff=0.02)
+ var/temp_delta = (temperature - chem_temp) * coeff
+ if(temp_delta > 0)
+ chem_temp = min(chem_temp + max(temp_delta, 1), temperature)
+ else
+ chem_temp = max(chem_temp + min(temp_delta, -1), temperature)
+ chem_temp = round(chem_temp)
+ handle_reactions()
///////////////////////////////////////////////////////////////////////////////////
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index 654b9e0e69..ac8f3bc656 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -59,6 +59,11 @@
recharge()
dispensable_reagents = sortList(dispensable_reagents)
+/obj/machinery/chem_dispenser/Destroy()
+ QDEL_NULL(beaker)
+ QDEL_NULL(cell)
+ return ..()
+
/obj/machinery/chem_dispenser/process()
if(recharged < 0)
@@ -179,7 +184,7 @@
if(default_unfasten_wrench(user, I))
return
- if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1))
+ if(istype(I, /obj/item/reagent_containers) && I.is_open_container())
var/obj/item/reagent_containers/B = I
. = 1 //no afterattack
if(beaker)
@@ -206,7 +211,7 @@
/obj/machinery/chem_dispenser/emp_act(severity)
var/list/datum/reagents/R = list()
- var/total = min(rand(7,15), Floor(cell.charge*powerefficiency))
+ var/total = min(rand(7,15), FLOOR(cell.charge*powerefficiency, 1))
var/datum/reagents/Q = new(total*10)
if(beaker && beaker.reagents)
R += beaker.reagents
@@ -303,6 +308,7 @@
if(beaker)
beaker.forceMove(drop_location())
beaker = null
+ return ..()
/obj/machinery/chem_dispenser/drinks
name = "soda dispenser"
diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm
index f8d2a66247..96dabf8aaa 100644
--- a/code/modules/reagents/chemistry/machinery/chem_heater.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm
@@ -13,6 +13,28 @@
var/heater_coefficient = 0.1
var/on = FALSE
+/obj/machinery/chem_heater/Destroy()
+ QDEL_NULL(beaker)
+ return ..()
+
+/obj/machinery/chem_heater/handle_atom_del(atom/A)
+ . = ..()
+ if(A == beaker)
+ beaker = null
+ update_icon()
+
+/obj/machinery/chem_heater/update_icon()
+ if(beaker)
+ icon_state = "mixer1b"
+ else
+ icon_state = "mixer0b"
+
+/obj/machinery/chem_heater/proc/eject_beaker()
+ if(beaker)
+ beaker.forceMove(drop_location())
+ beaker = null
+ update_icon()
+
/obj/machinery/chem_heater/RefreshParts()
heater_coefficient = 0.1
for(var/obj/item/stock_parts/micro_laser/M in component_parts)
@@ -42,7 +64,7 @@
if(default_deconstruction_crowbar(I))
return
- if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1))
+ if(istype(I, /obj/item/reagent_containers) && I.is_open_container())
. = 1 //no afterattack
if(beaker)
to_chat(user, "
A container is already loaded into [src]!")
@@ -52,12 +74,13 @@
return
beaker = I
to_chat(user, "
You add [I] to [src].")
- icon_state = "mixer1b"
+ update_icon()
return
return ..()
/obj/machinery/chem_heater/on_deconstruction()
eject_beaker()
+ return ..()
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
@@ -103,15 +126,8 @@
target = text2num(target)
. = TRUE
if(.)
- target_temperature = Clamp(target, 0, 1000)
+ target_temperature = CLAMP(target, 0, 1000)
if("eject")
on = FALSE
eject_beaker()
. = TRUE
-
-/obj/machinery/chem_heater/proc/eject_beaker()
- if(beaker)
- beaker.forceMove(drop_location())
- beaker.reagents.handle_reactions()
- beaker = null
- icon_state = "mixer0b"
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 434996fb08..d463def8af 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -13,7 +13,7 @@
var/obj/item/reagent_containers/beaker = null
var/obj/item/storage/pill_bottle/bottle = null
var/mode = 1
- var/condi = 0
+ var/condi = FALSE
var/screen = "home"
var/analyzeVars[0]
var/useramount = 30 // Last used amount
@@ -23,6 +23,11 @@
add_overlay("waitlight")
. = ..()
+/obj/machinery/chem_master/Destroy()
+ QDEL_NULL(beaker)
+ QDEL_NULL(bottle)
+ return ..()
+
/obj/machinery/chem_master/RefreshParts()
reagents.maximum_volume = 0
for(var/obj/item/reagent_containers/glass/beaker/B in component_parts)
@@ -44,10 +49,22 @@
if(A == beaker)
beaker = null
reagents.clear_reagents()
- icon_state = "mixer0"
+ update_icon()
else if(A == bottle)
bottle = null
+/obj/machinery/chem_master/update_icon()
+ if(beaker)
+ icon_state = "mixer1"
+ else
+ icon_state = "mixer0"
+
+/obj/machinery/chem_master/proc/eject_beaker()
+ if(beaker)
+ beaker.forceMove(drop_location())
+ adjust_item_drop_location(beaker)
+ beaker = null
+ update_icon()
/obj/machinery/chem_master/blob_act(obj/structure/blob/B)
if (prob(50))
@@ -61,15 +78,6 @@
/obj/machinery/chem_master/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", I))
- if(beaker)
- beaker.forceMove(drop_location())
- adjust_item_drop_location(beaker)
- beaker = null
- reagents.clear_reagents()
- if(bottle)
- bottle.forceMove(drop_location())
- adjust_item_drop_location(bottle)
- bottle = null
return
else if(exchange_parts(user, I))
@@ -80,7 +88,7 @@
if(default_unfasten_wrench(user, I))
return
- if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1))
+ if(istype(I, /obj/item/reagent_containers) && I.is_open_container())
. = 1 // no afterattack
if(panel_open)
to_chat(user, "
You can't use the [src.name] while its panel is opened!")
@@ -94,7 +102,7 @@
beaker = I
to_chat(user, "
You add [I] to [src].")
src.updateUsrDialog()
- icon_state = "mixer1"
+ update_icon()
else if(!condi && istype(I, /obj/item/storage/pill_bottle))
if(bottle)
@@ -109,6 +117,13 @@
else
return ..()
+/obj/machinery/chem_master/on_deconstruction()
+ eject_beaker()
+ if(bottle)
+ bottle.forceMove(drop_location())
+ adjust_item_drop_location(bottle)
+ bottle = null
+ return ..()
/obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
@@ -154,13 +169,8 @@
return
switch(action)
if("eject")
- if(beaker)
- beaker.forceMove(drop_location())
- adjust_item_drop_location(beaker)
- beaker = null
- reagents.clear_reagents()
- icon_state = "mixer0"
- . = TRUE
+ eject_beaker()
+ . = TRUE
if("ejectp")
if(bottle)
@@ -205,7 +215,7 @@
var/amount = 1
var/vol_each = min(reagents.total_volume, 50)
if(text2num(many))
- amount = Clamp(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many pills?", amount) as num|null), 0, 10)
+ amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many pills?", amount) as num|null), 0, 10)
if(!amount)
return
vol_each = min(reagents.total_volume / amount, 50)
@@ -241,7 +251,7 @@
var/amount = 1
var/vol_each = min(reagents.total_volume, 40)
if(text2num(many))
- amount = Clamp(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many patches?", amount) as num|null), 0, 10)
+ amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many patches?", amount) as num|null), 0, 10)
if(!amount)
return
vol_each = min(reagents.total_volume / amount, 40)
@@ -348,7 +358,7 @@
#if DM_VERSION >= 513
#warning 512 is definitely stable now, remove the old code
#endif
-
+
#if DM_VERSION >= 512
. += hex2num(md5[i])
#else
@@ -361,4 +371,4 @@
/obj/machinery/chem_master/condimaster
name = "CondiMaster 3000"
desc = "Used to create condiments and other cooking supplies."
- condi = 1
+ condi = TRUE
diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm
index 466aa047ad..ef186d8a79 100644
--- a/code/modules/reagents/chemistry/machinery/pandemic.dm
+++ b/code/modules/reagents/chemistry/machinery/pandemic.dm
@@ -25,6 +25,12 @@
QDEL_NULL(beaker)
return ..()
+/obj/machinery/computer/pandemic/handle_atom_del(atom/A)
+ . = ..()
+ if(A == beaker)
+ beaker = null
+ update_icon()
+
/obj/machinery/computer/pandemic/proc/get_by_index(thing, index)
if(!beaker || !beaker.reagents)
return
@@ -121,9 +127,10 @@
add_overlay("waitlight")
/obj/machinery/computer/pandemic/proc/eject_beaker()
- beaker.forceMove(drop_location())
- beaker = null
- update_icon()
+ if(beaker)
+ beaker.forceMove(drop_location())
+ beaker = null
+ update_icon()
/obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
@@ -159,8 +166,7 @@
return
switch(action)
if("eject_beaker")
- if(beaker)
- eject_beaker()
+ eject_beaker()
. = TRUE
if("empty_beaker")
if(beaker)
@@ -219,7 +225,7 @@
/obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1))
+ if(istype(I, /obj/item/reagent_containers) && I.is_open_container())
. = TRUE //no afterattack
if(stat & (NOPOWER|BROKEN))
return
@@ -236,7 +242,5 @@
return ..()
/obj/machinery/computer/pandemic/on_deconstruction()
- if(beaker)
- beaker.forceMove(drop_location())
- beaker = null
+ eject_beaker()
. = ..()
diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
index 77fcd50306..48dd5c2dc0 100644
--- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
+++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
@@ -2,7 +2,7 @@
#define MILK_TO_BUTTER_COEFF 15
/obj/machinery/reagentgrinder
- name = "All-In-One Grinder"
+ name = "\improper All-In-One Grinder"
desc = "From BlenderTech. Will It Blend? Let's test it out!"
icon = 'icons/obj/kitchen.dmi'
icon_state = "juicer1"
@@ -16,97 +16,6 @@
var/operating = FALSE
var/obj/item/reagent_containers/beaker = null
var/limit = 10
-
- var/static/list/blend_items = list(
- //Sheets
- /obj/item/stack/sheet/mineral/plasma = list("plasma" = 20),
- /obj/item/stack/sheet/metal = list("iron" = 20),
- /obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20),
- /obj/item/stack/sheet/mineral/wood = list("carbon" = 20),
- /obj/item/stack/sheet/glass = list("silicon" = 20),
- /obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20),
- /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20),
- /obj/item/stack/sheet/mineral/bananium = list("banana" = 20),
- /obj/item/stack/sheet/mineral/silver = list("silver" = 20),
- /obj/item/stack/sheet/mineral/gold = list("gold" = 20),
- /obj/item/stack/sheet/bluespace_crystal = list("bluespace" = 20),
- /obj/item/stack/cable_coil = list ("copper" = 5),
- /obj/item/ore/bluespace_crystal = list("bluespace" = 20),
- /obj/item/grown/nettle/basic = list("sacid" = 0),
- /obj/item/grown/nettle/death = list("facid" = 0, "sacid" = 0),
- /obj/item/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0),
- //Blender Stuff
- /obj/item/reagent_containers/food/snacks/donkpocket/warm = list("omnizine" = 3),
- /obj/item/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0),
- /obj/item/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0),
- /obj/item/reagent_containers/food/snacks/grown/wheat = list("flour" = -5),
- /obj/item/reagent_containers/food/snacks/grown/oat = list("flour" = -5),
- /obj/item/reagent_containers/food/snacks/grown/rice = list("rice" = -5),
- /obj/item/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1),
- /obj/item/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0),
- /obj/item/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0),
- /obj/item/reagent_containers/food/snacks/egg = list("eggyolk" = -5),
- /obj/item/reagent_containers/food/snacks/deadmouse = list ("blood" = 20, "gibs" = 5), // You monster
- //Grinder stuff, but only if dry
- /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
- /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
- /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
- /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0),
- //Stuff that doesn't quite fit in the other categories
- /obj/item/electronics = list ("iron" = 10, "silicon" = 10),
- /obj/item/circuitboard = list ("silicon" = 20, "sacid" = 0.5), // Retrieving acid this way is extremely inefficient
- /obj/item/match = list ("phosphorus" = 2),
- /obj/item/device/toner = list ("iodine" = 40, "iron" = 10),
- /obj/item/photo = list ("iodine" = 4),
- /obj/item/pen = list ("iodine" = 2, "iron" = 1),
- /obj/item/reagent_containers/food/drinks/soda_cans = list ("aluminium" = 10),
- /obj/item/trash/can = list ("aluminium" = 10),
- /obj/item/device/flashlight/flare = list ("sulfur" = 15),
- /obj/item/device/flashlight/glowstick = list ("phenol" = 15, "hydrodgen" = 10, "oxygen" = 5),
- /obj/item/stock_parts/cell = list ("lithium" = 15, "iron" = 5, "silicon" = 5),
- /obj/item/soap = list ("lye" = 10),
- /obj/item/device/analyzer = list ("mercury" = 5, "iron" = 5, "silicon" = 5),
- /obj/item/lighter = list ("iron" = 1, "weldingfuel" = 5, "oil" = 5),
- /obj/item/light = list ("silicon" = 5, "nitrogen" = 10), //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs
- /obj/item/cigbutt/ = list ("carbon" = 2),
- /obj/item/trash/coal = list ("carbon" = 20),
- /obj/item/stack/medical/bruise_pack = list ("styptic_powder" = 5),
- /obj/item/stack/medical/ointment = list ("silver_sulfadiazine" = 5),
- //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.!
- /obj/item/slime_extract = list(),
- /obj/item/reagent_containers/pill = list(),
- /obj/item/reagent_containers/food = list(),
- /obj/item/reagent_containers/honeycomb = list(),
- /obj/item/toy/crayon = list(),
- /obj/item/clothing/mask/cigarette = list())
-
- var/static/list/juice_items = list(
- //Juicer Stuff
- /obj/item/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0),
- /obj/item/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/banana = list("banana" = 0),
- /obj/item/reagent_containers/food/snacks/grown/potato = list("potato" = 0),
- /obj/item/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0),
- /obj/item/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0),
- /obj/item/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0))
-
- var/static/list/dried_items = list(
- //Grinder stuff, but only if dry,
- /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
- /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
- /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
- /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0))
-
var/list/holdingitems
/obj/machinery/reagentgrinder/Initialize()
@@ -153,11 +62,12 @@
if(default_unfasten_wrench(user, I))
return
- if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1) )
+ if (istype(I, /obj/item/reagent_containers) && I.is_open_container())
if (!beaker)
if(!user.transferItemToLoc(I, src))
to_chat(user, "
[I] is stuck to your hand!")
return TRUE
+ to_chat(user, "
You slide [I] into [src].")
beaker = I
update_icon()
updateUsrDialog()
@@ -165,15 +75,8 @@
to_chat(user, "
There's already a container inside [src].")
return TRUE //no afterattack
- if(is_type_in_list(I, dried_items))
- if(istype(I, /obj/item/reagent_containers/food/snacks/grown))
- var/obj/item/reagent_containers/food/snacks/grown/G = I
- if(!G.dry)
- to_chat(user, "
You must dry [G] first!")
- return TRUE
-
- if(length(holdingitems) >= limit)
- to_chat(user, "The machine cannot hold anymore items.")
+ if(holdingitems.len >= limit)
+ to_chat(user, "
[src] is filled to capacity!")
return TRUE
//Fill machine with a bag!
@@ -192,14 +95,18 @@
updateUsrDialog()
return TRUE
- if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items))
+ if(!I.grind_results && !I.juice_results)
if(user.a_intent == INTENT_HARM)
return ..()
else
- to_chat(user, "
Cannot refine into a reagent!")
+ to_chat(user, "
You cannot grind [I] into reagents!")
return TRUE
+ if(!I.grind_requirements(src)) //Error messages should be in the objects' definitions
+ return
+
if(user.transferItemToLoc(I, src))
+ to_chat(user, "
You add [I] to [src].")
holdingitems[I] = TRUE
updateUsrDialog()
return FALSE
@@ -214,7 +121,7 @@
user.set_machine(src)
interact(user)
-/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu
+/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave
var/is_chamber_empty = FALSE
var/is_beaker_ready = FALSE
var/processing_chamber = ""
@@ -307,60 +214,10 @@
holdingitems -= O
updateUsrDialog()
-/obj/machinery/reagentgrinder/proc/get_allowed_by_obj(obj/item/O)
- for (var/i in blend_items)
- if (istype(O, i))
- return blend_items[i]
-
-/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_obj(obj/item/reagent_containers/food/snacks/O)
- for(var/i in juice_items)
- if(istype(O, i))
- return juice_items[i]
-
-/obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/grown/O)
- if (!istype(O) || !O.seed)
- return 5
- else if (O.seed.potency == -1)
- return 5
- else
- return round(O.seed.potency)
-
-/obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/reagent_containers/food/snacks/grown/O)
- if (!istype(O) || !O.seed)
- return 5
- else if (O.seed.potency == -1)
- return 5
- else
- return round(5*sqrt(O.seed.potency))
-
/obj/machinery/reagentgrinder/proc/remove_object(obj/item/O)
holdingitems -= O
qdel(O)
-/obj/machinery/reagentgrinder/proc/juice()
- power_change()
- if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)))
- return
- operate_for(50, juicing = TRUE)
-
- //Snacks
- for(var/obj/item/i in holdingitems)
- var/obj/item/I = i
- if(istype(I, /obj/item/reagent_containers/food/snacks))
- var/obj/item/reagent_containers/food/snacks/O = I
- if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
- break
- var/list/allowed = get_allowed_juice_by_obj(O)
- if(isnull(allowed))
- break
- for(var/r_id in allowed)
- var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
- var/amount = get_juice_amount(O)
- beaker.reagents.add_reagent(r_id, min(amount, space))
- if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
- break
- remove_object(O)
-
/obj/machinery/reagentgrinder/proc/shake_for(duration)
var/offset = prob(50) ? -2 : 2
var/old_pixel_x = pixel_x
@@ -386,8 +243,26 @@
operating = FALSE
updateUsrDialog()
-/obj/machinery/reagentgrinder/proc/grind()
+/obj/machinery/reagentgrinder/proc/juice()
+ power_change()
+ if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)))
+ return
+ operate_for(50, juicing = TRUE)
+ for(var/obj/item/i in holdingitems)
+ if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
+ break
+ var/obj/item/I = i
+ if(I.juice_results)
+ juice_item(I)
+/obj/machinery/reagentgrinder/proc/juice_item(obj/item/I) //Juicing results can be found in respective object definitions
+ if(I.on_juice(src) == -1)
+ to_chat(usr, "
[src] shorts out as it tries to juice up [I], and transfers it back to storage.")
+ return
+ beaker.reagents.add_reagent_list(I.juice_results)
+ remove_object(I)
+
+/obj/machinery/reagentgrinder/proc/grind()
power_change()
if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume))
return
@@ -396,82 +271,17 @@
if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
var/obj/item/I = i
- //Snacks
- if(istype(I, /obj/item/reagent_containers/food/snacks))
- var/obj/item/reagent_containers/food/snacks/O = I
- var/list/allowed = get_allowed_by_obj(O)
- if(isnull(allowed))
- continue
- for(var/r_id in allowed)
- var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
- var/amount = allowed[r_id]
- if(amount <= 0)
- if(amount == 0)
- if (O.reagents != null && O.reagents.has_reagent("nutriment"))
- beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space))
- O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space))
- else
- if (O.reagents != null && O.reagents.has_reagent("nutriment"))
- beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space))
- O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space))
- else
- O.reagents.trans_id_to(beaker, r_id, min(amount, space))
- if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
- break
- if(O.reagents.reagent_list.len == 0)
- remove_object(O)
- //Sheets
- else if(istype(I, /obj/item/stack/sheet))
- var/obj/item/stack/sheet/O = I
- var/list/allowed = get_allowed_by_obj(O)
- for(var/t in 1 to round(O.amount, 1))
- for(var/r_id in allowed)
- var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
- var/amount = allowed[r_id]
- beaker.reagents.add_reagent(r_id,min(amount, space))
- if (space < amount)
- break
- if(t == round(O.amount, 1))
- remove_object(O)
- break
- //Plants
- else if(istype(I, /obj/item/grown))
- var/obj/item/grown/O = I
- var/list/allowed = get_allowed_by_obj(O)
- for (var/r_id in allowed)
- var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
- var/amount = allowed[r_id]
- if (amount == 0)
- if (O.reagents != null && O.reagents.has_reagent(r_id))
- beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space))
- else
- beaker.reagents.add_reagent(r_id,min(amount, space))
- if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
- break
- remove_object(O)
- else if(istype(I, /obj/item/slime_extract))
- var/obj/item/slime_extract/O = I
- var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
- if (O.reagents != null)
- var/amount = O.reagents.total_volume
- O.reagents.trans_to(beaker, min(amount, space))
- if (O.Uses > 0)
- beaker.reagents.add_reagent("slimejelly",min(20, space))
- remove_object(O)
- if(istype(I, /obj/item/reagent_containers))
- var/obj/item/reagent_containers/O = I
- var/amount = O.reagents.total_volume
- O.reagents.trans_to(beaker, amount)
- if(!O.reagents.total_volume)
- remove_object(O)
- else if(istype(I, /obj/item/toy/crayon))
- var/obj/item/toy/crayon/O = I
- for (var/r_id in O.reagent_contents)
- var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
- if(!space)
- break
- beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space))
- remove_object(O)
+ if(I.grind_results)
+ grind_item(i)
+
+/obj/machinery/reagentgrinder/proc/grind_item(obj/item/I) //Grind results can be found in respective object definitions
+ if(I.on_grind(src) == -1) //Call on_grind() to change amount as needed, and stop grinding the item if it returns -1
+ to_chat(usr, "
[src] shorts out as it tries to grind up [I], and transfers it back to storage.")
+ return
+ beaker.reagents.add_reagent_list(I.grind_results)
+ if(I.reagents)
+ I.reagents.trans_to(beaker, I.reagents.total_volume)
+ remove_object(I)
/obj/machinery/reagentgrinder/proc/mix(mob/user)
//For butter and other things that would change upon shaking or mixing
@@ -484,7 +294,7 @@
/obj/machinery/reagentgrinder/proc/mix_complete()
if(beaker && beaker.reagents.total_volume)
//Recipe to make Butter
- var/butter_amt = Floor(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF)
+ var/butter_amt = FLOOR(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF, 1)
beaker.reagents.remove_reagent("milk", MILK_TO_BUTTER_COEFF * butter_amt)
for(var/i in 1 to butter_amt)
new /obj/item/reagent_containers/food/snacks/butter(drop_location())
diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
index dc92dd3b52..7941853a91 100644
--- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm
+++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
@@ -1,3 +1,5 @@
+#define REAGENTS_BASE_VOLUME 100 // actual volume is REAGENTS_BASE_VOLUME plus REAGENTS_BASE_VOLUME * rating for each matterbin
+
/obj/machinery/smoke_machine
name = "smoke machine"
desc = "A machine with a centrifuge installed into it. It produces smoke with any reagents you put into the machine."
@@ -11,14 +13,13 @@
var/cooldown = 0
var/screen = "home"
var/useramount = 30 // Last used amount
- var/volume = 300
- var/setting = 3
- var/list/possible_settings = list(3,6,9)
+ var/setting = 1 // displayed range is 3 * setting
+ var/max_range = 3 // displayed max range is 3 * max range
-/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting = 3, efficiency = 10, loc)
- amount = setting
+/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting=1, efficiency=10, loc)
+ amount = setting * 3
carry.copy_to(chemholder, 20)
- carry.remove_any(setting * 16 / efficiency)
+ carry.remove_any(amount * 16 / efficiency)
location = loc
/datum/effect_system/smoke_spread/chem/smoke_machine
@@ -28,10 +29,11 @@
opaque = FALSE
alpha = 100
-
/obj/machinery/smoke_machine/Initialize()
. = ..()
- create_reagents(volume)
+ create_reagents(REAGENTS_BASE_VOLUME)
+ for(var/obj/item/stock_parts/matter_bin/B in component_parts)
+ reagents.maximum_volume += REAGENTS_BASE_VOLUME * B.rating
/obj/machinery/smoke_machine/update_icon()
if((!is_operational()) || (!on) || (reagents.total_volume == 0))
@@ -41,13 +43,22 @@
. = ..()
/obj/machinery/smoke_machine/RefreshParts()
- efficiency = 6
+ var/new_volume = REAGENTS_BASE_VOLUME
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
- efficiency += B.rating
+ new_volume += REAGENTS_BASE_VOLUME * B.rating
+ if(!reagents)
+ create_reagents(new_volume)
+ reagents.maximum_volume = new_volume
+ if(new_volume < reagents.total_volume)
+ reagents.reaction(loc, TOUCH) // if someone manages to downgrade it without deconstructing
+ reagents.clear_reagents()
+ efficiency = 9
for(var/obj/item/stock_parts/capacitor/C in component_parts)
efficiency += C.rating
+ max_range = 1
for(var/obj/item/stock_parts/manipulator/M in component_parts)
- efficiency += M.rating
+ max_range += M.rating
+ max_range = max(3, max_range)
/obj/machinery/smoke_machine/process()
..()
@@ -78,6 +89,11 @@
return
return ..()
+/obj/machinery/smoke_machine/deconstruct()
+ reagents.reaction(loc, TOUCH)
+ reagents.clear_reagents()
+ return ..()
+
/obj/machinery/smoke_machine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
@@ -99,6 +115,7 @@
data["active"] = on
data["setting"] = setting
data["screen"] = screen
+ data["maxSetting"] = max_range
return data
/obj/machinery/smoke_machine/ui_act(action, params)
@@ -110,7 +127,7 @@
. = TRUE
if("setting")
var/amount = text2num(params["amount"])
- if (locate(amount) in possible_settings)
+ if(amount in 1 to max_range)
setting = amount
. = TRUE
if("power")
@@ -122,3 +139,5 @@
if("goScreen")
screen = params["screen"]
. = TRUE
+
+#undef REAGENTS_BASE_VOLUME
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index 5f76a87654..9f8e129420 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -41,7 +41,7 @@
return 0
if(method == VAPOR) //smoke, foam, spray
if(M.reagents)
- var/modifier = Clamp((1 - touch_protection), 0, 1)
+ var/modifier = CLAMP((1 - touch_protection), 0, 1)
var/amount = round(reac_volume*modifier, 0.1)
if(amount >= 0.5)
M.reagents.add_reagent(id, amount)
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index 9321c6b015..00fd7d56a3 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -109,7 +109,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
glass_icon_state = "kahluaglass"
- glass_name = "glass of RR Coffee Liquor"
+ glass_name = "glass of RR coffee liquor"
glass_desc = "DAMN, THIS THING LOOKS ROBUST!"
shot_glass_icon_state = "shotglasscream"
@@ -341,7 +341,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 25
taste_description = "burning cinnamon"
glass_icon_state = "goldschlagerglass"
- glass_name = "glass of Goldschlager"
+ glass_name = "glass of goldschlager"
glass_desc = "100% proof that teen girls will drink anything with gold in it."
shot_glass_icon_state = "shotglassgold"
@@ -396,7 +396,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 70
taste_description = "cola"
glass_icon_state = "whiskeycolaglass"
- glass_name = "Whiskey Cola"
+ glass_name = "whiskey cola"
glass_desc = "An innocent-looking mixture of cola and Whiskey. Delicious."
/datum/reagent/consumable/ethanol/martini
@@ -706,7 +706,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 70
taste_description = "soda"
glass_icon_state = "whiskeysodaglass2"
- glass_name = "Whiskey Soda"
+ glass_name = "whiskey soda"
glass_desc = "Ultimate refreshment."
/datum/reagent/consumable/ethanol/antifreeze
@@ -785,7 +785,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 70
taste_description = "tart bitterness"
glass_icon_state = "vodkatonicglass"
- glass_name = "Vodka and Tonic"
+ glass_name = "vodka and tonic"
glass_desc = "For when a gin and tonic isn't Russian enough."
@@ -797,7 +797,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 45
taste_description = "dry, tart lemons"
glass_icon_state = "ginfizzglass"
- glass_name = "Gin Fizz"
+ glass_name = "gin fizz"
glass_desc = "Refreshingly lemony, deliciously dry."
@@ -870,7 +870,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 15
taste_description = "refreshingly cold"
glass_icon_state = "iced_beerglass"
- glass_name = "Iced Beer"
+ glass_name = "iced beer"
glass_desc = "A beer so frosty, the air around it freezes."
/datum/reagent/consumable/ethanol/iced_beer/on_mob_life(mob/living/M)
@@ -961,7 +961,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
var/datum/antagonist/changeling/changeling = M.mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling)
changeling.chem_charges += metabolization_rate
- changeling.chem_charges = Clamp(changeling.chem_charges, 0, changeling.chem_storage)
+ changeling.chem_charges = CLAMP(changeling.chem_charges, 0, changeling.chem_storage)
return ..()
/datum/reagent/consumable/ethanol/irishcarbomb
@@ -1069,7 +1069,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 35
taste_description = "sour lemons"
glass_icon_state = "whiskey_sour"
- glass_name = "Whiskey Sour"
+ glass_name = "whiskey sour"
glass_desc = "Lemon juice mixed with whiskey and a dash of sugar. Surprisingly satisfying."
/datum/reagent/consumable/ethanol/hcider
@@ -1081,7 +1081,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 25
taste_description = "apples"
glass_icon_state = "whiskeyglass"
- glass_name = "Hard Cider"
+ glass_name = "hard cider"
glass_desc = "Tastes like autumn."
shot_glass_icon_state = "shotglassbrown"
@@ -1279,5 +1279,5 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 1
taste_description = "custard and alcohol"
glass_icon_state = "glass_yellow"
- glass_name = "Eggnog"
+ glass_name = "eggnog"
glass_desc = "For enjoying the most wonderful time of the year."
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index 308fd47a16..b62afb80c0 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -148,7 +148,7 @@
description = "Absolutely nothing."
taste_description = "nothing"
glass_icon_state = "nothing"
- glass_name = "Nothing"
+ glass_name = "nothing"
glass_desc = "Absolutely nothing."
shot_glass_icon_state = "shotglass"
@@ -319,7 +319,7 @@
nutriment_factor = 0
taste_description = "bitter coldness"
glass_icon_state = "icedcoffeeglass"
- glass_name = "Iced Coffee"
+ glass_name = "iced coffee"
glass_desc = "A drink to perk you up and refresh you!"
/datum/reagent/consumable/icecoffee/on_mob_life(mob/living/M)
@@ -340,7 +340,7 @@
nutriment_factor = 0
taste_description = "sweet tea"
glass_icon_state = "icedteaglass"
- glass_name = "Iced Tea"
+ glass_name = "iced tea"
glass_desc = "All natural, antioxidant-rich flavour sensation."
/datum/reagent/consumable/icetea/on_mob_life(mob/living/M)
@@ -361,7 +361,7 @@
color = "#100800" // rgb: 16, 8, 0
taste_description = "cola"
glass_icon_state = "glass_brown"
- glass_name = "glass of space Cola"
+ glass_name = "glass of Space Cola"
glass_desc = "A glass of refreshing Space Cola."
/datum/reagent/consumable/space_cola/on_mob_life(mob/living/M)
@@ -377,7 +377,7 @@
color = "#100800" // rgb: 16, 8, 0
taste_description = "the future"
glass_icon_state = "nuka_colaglass"
- glass_name = "Nuka Cola"
+ glass_name = "glass of Nuka Cola"
glass_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland."
/datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/M)
@@ -434,7 +434,7 @@
color = "#00FF00" // rgb: 0, 255, 0
taste_description = "cherry soda"
glass_icon_state = "space-up_glass"
- glass_name = "glass of Space-up"
+ glass_name = "glass of Space-Up"
glass_desc = "Space-up. It helps you keep your cool."
@@ -450,7 +450,7 @@
color = "#8CFF00" // rgb: 135, 255, 0
taste_description = "tangy lime and lemon soda"
glass_icon_state = "glass_yellow"
- glass_name = "glass of Lemon-Lime"
+ glass_name = "glass of lemon-lime"
glass_desc = "You're pretty certain a real fruit has never actually touched this."
@@ -481,7 +481,7 @@
color = "#f00060" // rgb: 94, 0, 38
taste_description = "carbonated metallic soda"
glass_icon_state = "glass_red"
- glass_name = "glass of Shambler's Juice"
+ glass_name = "glass of Shambler's juice"
glass_desc = "Mmm mm, shambly."
/datum/reagent/consumable/shamblers/on_mob_life(mob/living/M)
@@ -495,7 +495,7 @@
color = "#619494" // rgb: 97, 148, 148
taste_description = "carbonated water"
glass_icon_state = "glass_clear"
- glass_name = "glass of Soda Water"
+ glass_name = "glass of soda water"
glass_desc = "Soda water. Why not make a scotch and soda?"
/datum/reagent/consumable/sodawater/on_mob_life(mob/living/M)
@@ -512,7 +512,7 @@
color = "#0064C8" // rgb: 0, 100, 200
taste_description = "tart and fresh"
glass_icon_state = "glass_clear"
- glass_name = "glass of Tonic Water"
+ glass_name = "glass of tonic water"
glass_desc = "Quinine tastes funny, but at least it'll keep that Space Malaria away."
/datum/reagent/consumable/tonic/on_mob_life(mob/living/M)
@@ -546,7 +546,7 @@
color = "#664300" // rgb: 102, 67, 0
taste_description = "creamy coffee"
glass_icon_state = "soy_latte"
- glass_name = "Soy Latte"
+ glass_name = "soy latte"
glass_desc = "A nice and refreshing beverage while you're reading."
/datum/reagent/consumable/soy_latte/on_mob_life(mob/living/M)
@@ -568,7 +568,7 @@
color = "#664300" // rgb: 102, 67, 0
taste_description = "bitter cream"
glass_icon_state = "cafe_latte"
- glass_name = "Cafe Latte"
+ glass_name = "cafe latte"
glass_desc = "A nice, strong and refreshing beverage while you're reading."
/datum/reagent/consumable/cafe_latte/on_mob_life(mob/living/M)
@@ -612,7 +612,7 @@
nutriment_factor = 4 * REAGENTS_METABOLISM
taste_description = "sweet chocolate"
glass_icon_state = "chocolatepudding"
- glass_name = "Chocolate Pudding"
+ glass_name = "chocolate pudding"
glass_desc = "Tasty."
/datum/reagent/consumable/vanillapudding
@@ -623,7 +623,7 @@
nutriment_factor = 4 * REAGENTS_METABOLISM
taste_description = "sweet vanilla"
glass_icon_state = "vanillapudding"
- glass_name = "Vanilla Pudding"
+ glass_name = "vanilla pudding"
glass_desc = "Tasty."
/datum/reagent/consumable/cherryshake
@@ -634,7 +634,7 @@
nutriment_factor = 4 * REAGENTS_METABOLISM
taste_description = "creamy cherry"
glass_icon_state = "cherryshake"
- glass_name = "Cherry Shake"
+ glass_name = "cherry shake"
glass_desc = "A cherry flavored milkshake."
/datum/reagent/consumable/bluecherryshake
@@ -645,7 +645,7 @@
nutriment_factor = 4 * REAGENTS_METABOLISM
taste_description = "creamy blue cherry"
glass_icon_state = "bluecherryshake"
- glass_name = "Blue Cherry Shake"
+ glass_name = "blue cherry shake"
glass_desc = "An exotic blue milkshake."
/datum/reagent/consumable/pumpkin_latte
@@ -656,7 +656,7 @@
nutriment_factor = 3 * REAGENTS_METABOLISM
taste_description = "creamy pumpkin"
glass_icon_state = "pumpkin_latte"
- glass_name = "Pumpkin Latte"
+ glass_name = "pumpkin latte"
glass_desc = "A mix of coffee and pumpkin juice."
/datum/reagent/consumable/gibbfloats
diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
index 60d1f64754..534cf515d9 100644
--- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
@@ -99,7 +99,7 @@
. = 1
/datum/reagent/drug/crank/addiction_act_stage4(mob/living/M)
- M.adjustBrainLoss(5*REM)
+ M.adjustBrainLoss(3*REM)
M.adjustToxLoss(5*REM, 0)
M.adjustBruteLoss(5*REM, 0)
..()
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 08db315b7d..a3c0d2c034 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -628,7 +628,7 @@
. = 1
if(prob(20))
M.losebreath += 4
- M.adjustBrainLoss(2*REM)
+ M.adjustBrainLoss(2*REM, 150)
M.adjustToxLoss(3*REM,0)
M.adjustStaminaLoss(10*REM,0)
M.blur_eyes(5)
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 7547a0834c..ddb08db032 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -59,6 +59,7 @@
M.confused = 0
M.SetSleeping(0, 0)
M.jitteriness = 0
+ M.cure_all_traumas(TRUE, TRUE)
for(var/thing in M.viruses)
var/datum/disease/D = thing
if(D.severity == VIRUS_SEVERITY_POSITIVE)
@@ -792,7 +793,13 @@
color = "#DCDCFF"
/datum/reagent/medicine/mannitol/on_mob_life(mob/living/M)
- M.adjustBrainLoss(-3*REM)
+ M.adjustBrainLoss(-2*REM)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ if(prob(30) && C.has_trauma_type(BRAIN_TRAUMA_SPECIAL))
+ C.cure_trauma_type(BRAIN_TRAUMA_SPECIAL)
+ if(prob(10) && C.has_trauma_type(BRAIN_TRAUMA_MILD))
+ C.cure_trauma_type(BRAIN_TRAUMA_MILD)
..()
/datum/reagent/medicine/mutadone
@@ -1016,7 +1023,7 @@
M.adjustFireLoss(-3 * REM, 0)
M.adjustOxyLoss(-15 * REM, 0)
M.adjustToxLoss(-3 * REM, 0)
- M.adjustBrainLoss(2 * REM) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
+ M.adjustBrainLoss(2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
M.adjustCloneLoss(-1 * REM, 0)
M.adjustStaminaLoss(-30 * REM, 0)
M.jitteriness = min(max(0, M.jitteriness + 3), 30)
@@ -1047,7 +1054,7 @@
if (M.hallucination >= 5)
M.hallucination -= 5
if(prob(20))
- M.adjustBrainLoss(1*REM)
+ M.adjustBrainLoss(1*REM, 50)
M.adjustStaminaLoss(2.5*REM, 0)
..()
. = 1
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index aab8491249..219d9df8ef 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -117,7 +117,7 @@
taste_description = "water"
var/cooling_temperature = 2
glass_icon_state = "glass_clear"
- glass_name = "glass of Water"
+ glass_name = "glass of water"
glass_desc = "The father of all refreshments."
shot_glass_icon_state = "shotglassclear"
@@ -188,7 +188,7 @@
description = "Water blessed by some deity."
color = "#E0E8EF" // rgb: 224, 232, 239
glass_icon_state = "glass_clear"
- glass_name = "glass of Holy Water"
+ glass_name = "glass of holy water"
glass_desc = "A glass of holy water."
/datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
@@ -261,7 +261,7 @@
M.adjustBruteLoss(-2, 0)
M.adjustFireLoss(-2, 0)
else
- M.adjustBrainLoss(3)
+ M.adjustBrainLoss(3, 150)
M.adjustToxLoss(1, 0)
M.adjustFireLoss(2, 0)
M.adjustOxyLoss(2, 0)
@@ -280,7 +280,7 @@
M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire
M.adjustToxLoss(1, 0)
M.adjustFireLoss(1, 0) //Hence the other damages... ain't I a bastard?
- M.adjustBrainLoss(5)
+ M.adjustBrainLoss(5, 150)
holder.remove_reagent(src.id, 1)
/datum/reagent/medicine/omnizine/godblood
@@ -676,7 +676,7 @@
step(M, pick(GLOB.cardinals))
if(prob(5))
M.emote(pick("twitch","drool","moan"))
- M.adjustBrainLoss(2)
+ M.adjustBrainLoss(1)
..()
/datum/reagent/sulfur
@@ -1029,7 +1029,7 @@
/datum/reagent/impedrezene/on_mob_life(mob/living/M)
M.jitteriness = max(M.jitteriness-5,0)
if(prob(80))
- M.adjustBrainLoss(1*REM)
+ M.adjustBrainLoss(2*REM)
if(prob(50))
M.drowsyness = max(M.drowsyness, 3)
if(prob(10))
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index fd7d5750f1..7bee2ef958 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -455,13 +455,12 @@
toxpwr = 0
/datum/reagent/toxin/neurotoxin2/on_mob_life(mob/living/M)
- if(M.brainloss + M.toxloss <= 60)
- M.adjustBrainLoss(1*REM)
+ M.adjustBrainLoss(3*REM, 150)
+ . = 1
+ if(M.toxloss <= 60)
M.adjustToxLoss(1*REM, 0)
- . = 1
if(current_cycle >= 18)
M.Sleeping(40, 0)
- . = 1
..()
/datum/reagent/toxin/cyanide
@@ -851,9 +850,9 @@
/datum/reagent/toxin/peaceborg/confuse/on_mob_life(mob/living/M)
if(M.confused < 6)
- M.confused = Clamp(M.confused + 3, 0, 5)
+ M.confused = CLAMP(M.confused + 3, 0, 5)
if(M.dizziness < 6)
- M.dizziness = Clamp(M.dizziness + 3, 0, 5)
+ M.dizziness = CLAMP(M.dizziness + 3, 0, 5)
if(prob(20))
to_chat(M, "You feel confused and disorientated.")
..()
diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
index aa97dd3180..b77dcc435a 100644
--- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
+++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
@@ -139,7 +139,6 @@
/datum/chemical_reaction/reagent_explosion/methsplosion
name = "Meth explosion"
id = "methboom1"
- results = list("methboom1" = 1)
required_temp = 380 //slightly above the meth mix time.
required_reagents = list("methamphetamine" = 1)
strengthdiv = 6
@@ -154,9 +153,9 @@
..()
/datum/chemical_reaction/reagent_explosion/methsplosion/methboom2
+ id = "methboom2"
required_reagents = list("diethylamine" = 1, "iodine" = 1, "phosphorus" = 1, "hydrogen" = 1) //diethylamine is often left over from mixing the ephedrine.
- required_temp = 300 //room temperature, chilling it even a little will prevent the explosion
- results = list("methboom1" = 4) // this is ugly. Sorry goof.
+ required_temp = 300 //room temperature, chilling it even a little will prevent the explosion
/datum/chemical_reaction/sorium
name = "Sorium"
@@ -169,7 +168,7 @@
return
holder.remove_reagent("sorium", created_volume*4)
var/turf/T = get_turf(holder.my_atom)
- var/range = Clamp(sqrt(created_volume*4), 1, 6)
+ var/range = CLAMP(sqrt(created_volume*4), 1, 6)
goonchem_vortex(T, 1, range)
/datum/chemical_reaction/sorium_vortex
@@ -180,7 +179,7 @@
/datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, created_volume)
var/turf/T = get_turf(holder.my_atom)
- var/range = Clamp(sqrt(created_volume), 1, 6)
+ var/range = CLAMP(sqrt(created_volume), 1, 6)
goonchem_vortex(T, 1, range)
/datum/chemical_reaction/liquid_dark_matter
@@ -194,7 +193,7 @@
return
holder.remove_reagent("liquid_dark_matter", created_volume*3)
var/turf/T = get_turf(holder.my_atom)
- var/range = Clamp(sqrt(created_volume*3), 1, 6)
+ var/range = CLAMP(sqrt(created_volume*3), 1, 6)
goonchem_vortex(T, 0, range)
/datum/chemical_reaction/ldm_vortex
@@ -205,7 +204,7 @@
/datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, created_volume)
var/turf/T = get_turf(holder.my_atom)
- var/range = Clamp(sqrt(created_volume/2), 1, 6)
+ var/range = CLAMP(sqrt(created_volume/2), 1, 6)
goonchem_vortex(T, 0, range)
/datum/chemical_reaction/flash_powder
@@ -382,7 +381,6 @@
name = "Teslium Destabilization"
id = "teslium_lightning"
required_reagents = list("teslium" = 1, "water" = 1)
- results = list("destabilized_teslium" = 1)
strengthdiv = 100
modifier = -100
mix_message = "
The teslium starts to spark as electricity arcs away from it!"
diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
index f3143e1193..9b04eb1b0a 100644
--- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm
+++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
@@ -152,11 +152,10 @@
var/chosen = pick(borks)
var/obj/B = new chosen(T)
if(prob(5))//Fry it!
- var/obj/item/reagent_containers/food/snacks/deepfryholder/D = new(T)
- var/datum/reagents/reagents = new(25)
- reagents.add_reagent("nutriment", 25)
- D.fry(B, reagents)
- B = D
+ var/obj/item/reagent_containers/food/snacks/deepfryholder/fried
+ fried = new(T, B)
+ fried.fry() // actually set the name and colour it
+ B = fried
if(prob(50))
for(var/j in 1 to rand(1, 3))
step(B, pick(NORTH,SOUTH,EAST,WEST))
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index 8698c10b05..6fb21e847b 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -48,15 +48,6 @@
/obj/item/reagent_containers/afterattack(obj/target, mob/user , flag)
return
-/obj/item/reagent_containers/proc/reagentlist(obj/item/reagent_containers/snack) //Attack logs for regents in pills
- var/data
- if(snack.reagents.reagent_list && snack.reagents.reagent_list.len) //find a reagent list if there is and check if it has entries
- for (var/datum/reagent/R in snack.reagents.reagent_list) //no reagents will be left behind
- data += "[R.id]([R.volume] units); " //Using IDs because SOME chemicals(I'm looking at you, chlorhydrate-beer) have the same names as other chemicals.
- return data
- else
- return "No reagents"
-
/obj/item/reagent_containers/proc/canconsume(mob/eater, mob/user)
if(!iscarbon(eater))
return 0
@@ -80,8 +71,7 @@
..()
/obj/item/reagent_containers/fire_act(exposed_temperature, exposed_volume)
- reagents.chem_temp += 30
- reagents.handle_reactions()
+ reagents.expose_temperature(exposed_temperature)
..()
/obj/item/reagent_containers/throw_impact(atom/target)
@@ -127,7 +117,8 @@
reagents.clear_reagents()
/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M)
- if(is_open_container())
- reagents.chem_temp = max(reagents.chem_temp, 1000)
- reagents.handle_reactions()
+ reagents.expose_temperature(1000)
..()
+
+/obj/item/reagent_containers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ reagents.expose_temperature(exposed_temperature)
diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm
index a4d766539f..bc92521b93 100644
--- a/code/modules/reagents/reagent_containers/blood_pack.dm
+++ b/code/modules/reagents/reagent_containers/blood_pack.dm
@@ -40,6 +40,9 @@
if(51 to INFINITY)
icon_state = "full"
+/obj/item/reagent_containers/blood/random
+ icon_state = "random_bloodpack"
+
/obj/item/reagent_containers/blood/random/Initialize()
blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L")
. = ..()
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index 28a07d5862..0a99d9da6e 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -173,7 +173,7 @@ Borg Shaker
if(!proximity)
return
- else if(target.is_open_container() && target.reagents)
+ else if(target.is_refillable())
var/datum/reagents/R = reagent_list[mode]
if(!R.total_volume)
to_chat(user, "
[src] is currently out of this ingredient! Please allow some time for the synthesizer to produce more.")
diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm
index 30aa67e91a..144db32a6c 100644
--- a/code/modules/reagents/reagent_containers/dropper.dm
+++ b/code/modules/reagents/reagent_containers/dropper.dm
@@ -6,7 +6,7 @@
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(1, 2, 3, 4, 5)
volume = 5
- container_type = TRANSPARENT_1
+ container_type = TRANSPARENT
/obj/item/reagent_containers/dropper/afterattack(obj/target, mob/user , proximity)
if(!proximity)
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index c27e2e9ea5..06a242cca9 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -3,7 +3,7 @@
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
volume = 50
- container_type = OPENCONTAINER_1
+ container_type = OPENCONTAINER
spillable = TRUE
resistance_flags = ACID_PROOF
@@ -44,7 +44,7 @@
if(!reagents || !reagents.total_volume)
return // The drink might be empty after the delay, such as by spam-feeding
M.visible_message("
[user] feeds something to [M].", "
[user] feeds something to you.")
- add_logs(user, M, "fed", reagentlist(src))
+ add_logs(user, M, "fed", reagents.log_list())
else
to_chat(user, "
You swallow a gulp of [src].")
var/fraction = min(5/reagents.total_volume, 1)
@@ -56,32 +56,30 @@
if((!proximity) || !check_allowed_items(target,target_self=1))
return
- else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
-
- if(target.reagents && !target.reagents.total_volume)
- to_chat(user, "
[target] is empty and can't be refilled!")
- return
-
- if(reagents.total_volume >= reagents.maximum_volume)
- to_chat(user, "
[src] is full.")
- return
-
- var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
- to_chat(user, "
You fill [src] with [trans] unit\s of the contents of [target].")
-
- else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it.
+ if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
to_chat(user, "
[src] is empty!")
return
- if(target.reagents.total_volume >= target.reagents.maximum_volume)
- to_chat(user, "
[target] is full.")
+ if(target.reagents.holder_full())
+ to_chat(user, "
[target] is full.")
return
-
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "
You transfer [trans] unit\s of the solution to [target].")
+ else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
+ if(!target.reagents.total_volume)
+ to_chat(user, "
[target] is empty and can't be refilled!")
+ return
+
+ if(reagents.holder_full())
+ to_chat(user, "
[src] is full.")
+ return
+
+ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
+ to_chat(user, "
You fill [src] with [trans] unit\s of the contents of [target].")
+
else if(reagents.total_volume)
if(user.a_intent == INTENT_HARM)
user.visible_message("
[user] splashes the contents of [src] onto [target]!", \
@@ -91,15 +89,9 @@
/obj/item/reagent_containers/glass/attackby(obj/item/I, mob/user, params)
var/hotness = I.is_hot()
- if(hotness)
- var/added_heat = (hotness / 100) //ishot returns a temperature
- if(reagents)
- if(reagents.chem_temp < hotness) //can't be heated to be hotter than the source
- reagents.chem_temp += added_heat
- to_chat(user, "
You heat [src] with [I].")
- reagents.handle_reactions()
- else
- to_chat(user, "
[src] is already hotter than [I]!")
+ if(hotness && reagents)
+ reagents.expose_temperature(hotness)
+ to_chat(user, "
You heat [name] with [I]!")
if(istype(I, /obj/item/reagent_containers/food/snacks/egg)) //breaking eggs
var/obj/item/reagent_containers/food/snacks/egg/E = I
@@ -169,7 +161,6 @@
volume = 100
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
- flags_1 = OPENCONTAINER_1
/obj/item/reagent_containers/glass/beaker/noreact
name = "cryostasis beaker"
@@ -179,8 +170,6 @@
materials = list(MAT_METAL=3000)
volume = 50
amount_per_transfer_from_this = 10
- origin_tech = "materials=2;engineering=3;plasmatech=3"
- flags_1 = OPENCONTAINER_1
/obj/item/reagent_containers/glass/beaker/noreact/Initialize()
. = ..()
@@ -196,8 +185,6 @@
volume = 300
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
- flags_1 = OPENCONTAINER_1
- origin_tech = "bluespace=5;materials=4;plasmatech=4"
/obj/item/reagent_containers/glass/beaker/cryoxadone
list_reagents = list("cryoxadone" = 30)
@@ -240,7 +227,6 @@
amount_per_transfer_from_this = 20
possible_transfer_amounts = list(10,15,20,25,30,50,70)
volume = 70
- flags_1 = OPENCONTAINER_1
flags_inv = HIDEHAIR
slot_flags = SLOT_HEAD
resistance_flags = NONE
@@ -298,7 +284,6 @@
materials = list(MAT_GLASS=0)
volume = 50
amount_per_transfer_from_this = 10
- origin_tech = null
/obj/item/reagent_containers/glass/beaker/waterbottle/empty
list_reagents = list()
@@ -412,4 +397,4 @@
/obj/item/reagent_containers/glass/beaker/large/bromine
name = "bromine beaker"
- list_reagents = list("bromine" = 50)
\ No newline at end of file
+ list_reagents = list("bromine" = 50)
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index dff0869322..53e0c9bfb6 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -10,7 +10,7 @@
volume = 30
possible_transfer_amounts = list()
resistance_flags = ACID_PROOF
- container_type = OPENCONTAINER_1
+ container_type = OPENCONTAINER
slot_flags = SLOT_BELT
var/ignore_flags = 0
var/infinite = FALSE
@@ -88,7 +88,7 @@
amount_per_transfer_from_this = 10
volume = 10
ignore_flags = 1 //so you can medipen through hardsuits
- container_type = DRAWABLE_1
+ container_type = DRAWABLE
flags_1 = null
list_reagents = list("epinephrine" = 10)
diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm
index 324623edbd..4908a55911 100644
--- a/code/modules/reagents/reagent_containers/pill.dm
+++ b/code/modules/reagents/reagent_containers/pill.dm
@@ -1,154 +1,160 @@
-/obj/item/reagent_containers/pill
- name = "pill"
- desc = "A tablet or capsule."
- icon = 'icons/obj/chemical.dmi'
- icon_state = "pill"
- item_state = "pill"
- lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
- possible_transfer_amounts = list()
- volume = 50
- var/apply_type = INGEST
- var/apply_method = "swallow"
- var/roundstart = 0
- var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills
-
-/obj/item/reagent_containers/pill/Initialize()
- . = ..()
- if(!icon_state)
- icon_state = "pill[rand(1,20)]"
- if(reagents.total_volume && roundstart)
- name += " ([reagents.total_volume]u)"
-
-
-/obj/item/reagent_containers/pill/attack_self(mob/user)
- return
-
-
-/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone)
- if(!canconsume(M, user))
- return 0
-
- if(M == user)
- M.visible_message("
[user] attempts to [apply_method] [src].")
- if(self_delay)
- if(!do_mob(user, M, self_delay))
- return 0
- to_chat(M, "
You [apply_method] [src].")
-
- else
- M.visible_message("
[user] attempts to force [M] to [apply_method] [src].", \
- "
[user] attempts to force [M] to [apply_method] [src].")
- if(!do_mob(user, M))
- return 0
- M.visible_message("
[user] forces [M] to [apply_method] [src].", \
- "
[user] forces [M] to [apply_method] [src].")
-
-
- add_logs(user, M, "fed", reagentlist(src))
- if(reagents.total_volume)
- reagents.reaction(M, apply_type)
- reagents.trans_to(M, reagents.total_volume)
- qdel(src)
- return 1
-
-
-/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity)
- if(!proximity)
- return
- if(target.is_open_container() != 0 && target.reagents)
- if(!target.reagents.total_volume)
- to_chat(user, "
[target] is empty! There's nothing to dissolve [src] in.")
- return
- to_chat(user, "
You dissolve [src] in [target].")
- for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius
- to_chat(O, "
[user] slips something into [target]!")
- reagents.trans_to(target, reagents.total_volume)
- qdel(src)
-
-/obj/item/reagent_containers/pill/tox
- name = "toxins pill"
- desc = "Highly toxic."
- icon_state = "pill5"
- list_reagents = list("toxin" = 50)
- roundstart = 1
-/obj/item/reagent_containers/pill/cyanide
- name = "cyanide pill"
- desc = "Don't swallow this."
- icon_state = "pill5"
- list_reagents = list("cyanide" = 50)
- roundstart = 1
-/obj/item/reagent_containers/pill/adminordrazine
- name = "adminordrazine pill"
- desc = "It's magic. We don't have to explain it."
- icon_state = "pill16"
- list_reagents = list("adminordrazine" = 50)
- roundstart = 1
-/obj/item/reagent_containers/pill/morphine
- name = "morphine pill"
- desc = "Commonly used to treat insomnia."
- icon_state = "pill8"
- list_reagents = list("morphine" = 30)
- roundstart = 1
-/obj/item/reagent_containers/pill/stimulant
- name = "stimulant pill"
- desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!"
- icon_state = "pill19"
- list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30)
- roundstart = 1
-/obj/item/reagent_containers/pill/salbutamol
- name = "salbutamol pill"
- desc = "Used to treat oxygen deprivation."
- icon_state = "pill16"
- list_reagents = list("salbutamol" = 30)
- roundstart = 1
-/obj/item/reagent_containers/pill/charcoal
- name = "charcoal pill"
- desc = "Neutralizes many common toxins."
- icon_state = "pill17"
- list_reagents = list("charcoal" = 10)
- roundstart = 1
-/obj/item/reagent_containers/pill/epinephrine
- name = "epinephrine pill"
- desc = "Used to stabilize patients."
- icon_state = "pill5"
- list_reagents = list("epinephrine" = 15)
- roundstart = 1
-/obj/item/reagent_containers/pill/mannitol
- name = "mannitol pill"
- desc = "Used to treat brain damage."
- icon_state = "pill17"
- list_reagents = list("mannitol" = 50)
- roundstart = 1
-/obj/item/reagent_containers/pill/mutadone
- name = "mutadone pill"
- desc = "Used to treat genetic damage."
- icon_state = "pill20"
- list_reagents = list("mutadone" = 50)
- roundstart = 1
-/obj/item/reagent_containers/pill/salicyclic
- name = "salicylic acid pill"
- desc = "Used to dull pain."
- icon_state = "pill9"
- list_reagents = list("sal_acid" = 24)
- roundstart = 1
-/obj/item/reagent_containers/pill/oxandrolone
- name = "oxandrolone pill"
- desc = "Used to stimulate burn healing."
- icon_state = "pill11"
- list_reagents = list("oxandrolone" = 24)
- roundstart = 1
-
-/obj/item/reagent_containers/pill/insulin
- name = "insulin pill"
- desc = "Handles hyperglycaemic coma."
- icon_state = "pill18"
- list_reagents = list("insulin" = 50)
- roundstart = 1
-
-/obj/item/reagent_containers/pill/shadowtoxin
- name = "black pill"
- desc = "I wouldn't eat this if I were you."
- icon_state = "pill9"
- color = "#454545"
- list_reagents = list("shadowmutationtoxin" = 1)
+/obj/item/reagent_containers/pill
+ name = "pill"
+ desc = "A tablet or capsule."
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = "pill"
+ item_state = "pill"
+ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
+ possible_transfer_amounts = list()
+ volume = 50
+ grind_results = list()
+ var/apply_type = INGEST
+ var/apply_method = "swallow"
+ var/roundstart = 0
+ var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills
+
+/obj/item/reagent_containers/pill/Initialize()
+ . = ..()
+ if(!icon_state)
+ icon_state = "pill[rand(1,20)]"
+ if(reagents.total_volume && roundstart)
+ name += " ([reagents.total_volume]u)"
+
+
+/obj/item/reagent_containers/pill/attack_self(mob/user)
+ return
+
+
+/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone)
+ if(!canconsume(M, user))
+ return 0
+
+ if(M == user)
+ M.visible_message("
[user] attempts to [apply_method] [src].")
+ if(self_delay)
+ if(!do_mob(user, M, self_delay))
+ return 0
+ to_chat(M, "
You [apply_method] [src].")
+
+ else
+ M.visible_message("
[user] attempts to force [M] to [apply_method] [src].", \
+ "
[user] attempts to force [M] to [apply_method] [src].")
+ if(!do_mob(user, M))
+ return 0
+ M.visible_message("
[user] forces [M] to [apply_method] [src].", \
+ "
[user] forces [M] to [apply_method] [src].")
+
+
+ add_logs(user, M, "fed", reagents.log_list())
+ if(reagents.total_volume)
+ reagents.reaction(M, apply_type)
+ reagents.trans_to(M, reagents.total_volume)
+ qdel(src)
+ return 1
+
+
+/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity)
+ if(!proximity)
+ return
+ if(target.is_refillable())
+ if(target.is_drainable() && !target.reagents.total_volume)
+ to_chat(user, "
[target] is empty! There's nothing to dissolve [src] in.")
+ return
+
+ if(target.reagents.holder_full())
+ to_chat(user, "
[target] is full.")
+ return
+
+ to_chat(user, "
You dissolve [src] in [target].")
+ for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius
+ to_chat(O, "
[user] slips something into [target]!")
+ reagents.trans_to(target, reagents.total_volume)
+ qdel(src)
+
+/obj/item/reagent_containers/pill/tox
+ name = "toxins pill"
+ desc = "Highly toxic."
+ icon_state = "pill5"
+ list_reagents = list("toxin" = 50)
+ roundstart = 1
+/obj/item/reagent_containers/pill/cyanide
+ name = "cyanide pill"
+ desc = "Don't swallow this."
+ icon_state = "pill5"
+ list_reagents = list("cyanide" = 50)
+ roundstart = 1
+/obj/item/reagent_containers/pill/adminordrazine
+ name = "adminordrazine pill"
+ desc = "It's magic. We don't have to explain it."
+ icon_state = "pill16"
+ list_reagents = list("adminordrazine" = 50)
+ roundstart = 1
+/obj/item/reagent_containers/pill/morphine
+ name = "morphine pill"
+ desc = "Commonly used to treat insomnia."
+ icon_state = "pill8"
+ list_reagents = list("morphine" = 30)
+ roundstart = 1
+/obj/item/reagent_containers/pill/stimulant
+ name = "stimulant pill"
+ desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!"
+ icon_state = "pill19"
+ list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30)
+ roundstart = 1
+/obj/item/reagent_containers/pill/salbutamol
+ name = "salbutamol pill"
+ desc = "Used to treat oxygen deprivation."
+ icon_state = "pill16"
+ list_reagents = list("salbutamol" = 30)
+ roundstart = 1
+/obj/item/reagent_containers/pill/charcoal
+ name = "charcoal pill"
+ desc = "Neutralizes many common toxins."
+ icon_state = "pill17"
+ list_reagents = list("charcoal" = 10)
+ roundstart = 1
+/obj/item/reagent_containers/pill/epinephrine
+ name = "epinephrine pill"
+ desc = "Used to stabilize patients."
+ icon_state = "pill5"
+ list_reagents = list("epinephrine" = 15)
+ roundstart = 1
+/obj/item/reagent_containers/pill/mannitol
+ name = "mannitol pill"
+ desc = "Used to treat brain damage."
+ icon_state = "pill17"
+ list_reagents = list("mannitol" = 50)
+ roundstart = 1
+/obj/item/reagent_containers/pill/mutadone
+ name = "mutadone pill"
+ desc = "Used to treat genetic damage."
+ icon_state = "pill20"
+ list_reagents = list("mutadone" = 50)
+ roundstart = 1
+/obj/item/reagent_containers/pill/salicyclic
+ name = "salicylic acid pill"
+ desc = "Used to dull pain."
+ icon_state = "pill9"
+ list_reagents = list("sal_acid" = 24)
+ roundstart = 1
+/obj/item/reagent_containers/pill/oxandrolone
+ name = "oxandrolone pill"
+ desc = "Used to stimulate burn healing."
+ icon_state = "pill11"
+ list_reagents = list("oxandrolone" = 24)
+ roundstart = 1
+
+/obj/item/reagent_containers/pill/insulin
+ name = "insulin pill"
+ desc = "Handles hyperglycaemic coma."
+ icon_state = "pill18"
+ list_reagents = list("insulin" = 50)
+ roundstart = 1
+
+/obj/item/reagent_containers/pill/shadowtoxin
+ name = "black pill"
+ desc = "I wouldn't eat this if I were you."
+ icon_state = "pill9"
+ color = "#454545"
+ list_reagents = list("shadowmutationtoxin" = 1)
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index 869076081e..2e34e39f8f 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -7,7 +7,7 @@
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
flags_1 = NOBLUDGEON_1
- container_type = OPENCONTAINER_1
+ container_type = OPENCONTAINER
slot_flags = SLOT_BELT
throwforce = 0
w_class = WEIGHT_CLASS_SMALL
@@ -23,17 +23,17 @@
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
-/obj/item/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user)
+/obj/item/reagent_containers/spray/afterattack(atom/A, mob/user)
if(istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics))
return
- if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) //this block copypasted from reagent_containers/glass, for lack of a better solution
- if(!A.reagents.total_volume && A.reagents)
- to_chat(user, "
\The [A] is empty.")
+ if((A.is_drainable() && !A.is_refillable()) && get_dist(src,A) <= 1)
+ if(!A.reagents.total_volume)
+ to_chat(user, "
[A] is empty.")
return
- if(reagents.total_volume >= reagents.maximum_volume)
- to_chat(user, "
\The [src] is full.")
+ if(reagents.holder_full())
+ to_chat(user, "
[src] is full.")
return
var/trans = A.reagents.trans_to(src, 50) //transfer 50u , using the spray's transfer amount would take too long to refill
@@ -41,7 +41,7 @@
return
if(reagents.total_volume < amount_per_transfer_from_this)
- to_chat(user, "
\The [src] is empty!")
+ to_chat(user, "
[src] is empty!")
return
spray(A)
@@ -123,6 +123,14 @@
current_range = spray_range
to_chat(user, "
You switch the nozzle setting to [stream_mode ? "\"stream\"":"\"spray\""]. You'll now use [amount_per_transfer_from_this] units per use.")
+/obj/item/reagent_containers/spray/attackby(obj/item/I, mob/user, params)
+ var/hotness = I.is_hot()
+ if(hotness && reagents)
+ reagents.expose_temperature(hotness)
+ to_chat(user, "
You heat [name] with [I]!")
+ return ..()
+
+
/obj/item/reagent_containers/spray/verb/empty()
set name = "Empty Spray Bottle"
set category = "Object"
@@ -214,7 +222,6 @@
stream_range = 7
amount_per_transfer_from_this = 10
volume = 600
- origin_tech = "combat=3;materials=3;engineering=3"
/obj/item/reagent_containers/spray/chemsprayer/afterattack(atom/A as mob|obj, mob/user)
// Make it so the bioterror spray doesn't spray yourself when you click your inventory items
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index 9695caab02..3f38be95c9 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -13,7 +13,7 @@
var/busy = FALSE // needed for delayed drawing of blood
var/proj_piercing = 0 //does it pierce through thick clothes when shot with syringe gun
materials = list(MAT_METAL=10, MAT_GLASS=20)
- container_type = TRANSPARENT_1
+ container_type = TRANSPARENT
/obj/item/reagent_containers/syringe/Initialize()
. = ..()
@@ -107,11 +107,8 @@
update_icon()
if(SYRINGE_INJECT)
- //Always log attemped injections for admins
- var/list/rinject = list()
- for(var/datum/reagent/R in reagents.reagent_list)
- rinject += R.name
- var/contained = english_list(rinject)
+ // Always log attemped injections for admins
+ var/contained = reagents.log_list()
add_logs(user, L, "attemped to inject", src, addition="which had [contained]")
if(!reagents.total_volume)
@@ -157,7 +154,7 @@
/obj/item/reagent_containers/syringe/update_icon()
- var/rounded_vol = Clamp(round((reagents.total_volume / volume * 15),5), 0, 15)
+ var/rounded_vol = CLAMP(round((reagents.total_volume / volume * 15),5), 0, 15)
cut_overlays()
if(ismob(loc))
var/injoverlay
@@ -207,6 +204,11 @@
desc = "Contains calomel."
list_reagents = list("calomel" = 15)
+/obj/item/reagent_containers/syringe/plasma
+ name = "syringe (plasma)"
+ desc = "Contains plasma."
+ list_reagents = list("plasma" = 15)
+
/obj/item/reagent_containers/syringe/lethal
name = "lethal injection syringe"
desc = "A syringe used for lethal injections. It can hold up to 50 units."
@@ -238,13 +240,11 @@
desc = "An advanced syringe that can hold 60 units of chemicals."
amount_per_transfer_from_this = 20
volume = 60
- origin_tech = "bluespace=4;materials=4;biotech=4"
/obj/item/reagent_containers/syringe/noreact
name = "cryo syringe"
desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units."
volume = 20
- origin_tech = "materials=3;engineering=3"
/obj/item/reagent_containers/syringe/noreact/Initialize()
. = ..()
@@ -255,4 +255,3 @@
desc = "A diamond-tipped syringe that pierces armor when launched at high velocity. It can hold up to 10 units."
volume = 10
proj_piercing = 1
- origin_tech = "combat=3;materials=4;engineering=5"
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index ea80f4c508..f0c0ecfb68 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -5,7 +5,7 @@
icon_state = "water"
density = TRUE
anchored = FALSE
- container_type = DRAWABLE_1
+ container_type = DRAINABLE | AMOUNT_VISIBLE
pressure_resistance = 2*ONE_ATMOSPHERE
max_integrity = 300
var/tank_volume = 1000 //In units, how much the dispenser can hold
@@ -18,7 +18,7 @@
boom()
/obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/reagent_containers))
+ if(W.is_refillable())
return 0 //so we can refill them via their afterattack.
else
return ..()
@@ -28,14 +28,6 @@
reagents.add_reagent(reagent_id, tank_volume)
. = ..()
-/obj/structure/reagent_dispensers/examine(mob/user)
- ..()
- if(reagents.total_volume)
- to_chat(user, "
It has [reagents.total_volume] unit\s left.")
- else
- to_chat(user, "
It's empty.")
-
-
/obj/structure/reagent_dispensers/proc/boom()
visible_message("
\The [src] ruptures!")
chem_splash(loc, 5, list(reagents))
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index ed14ae63c1..62965f7ca1 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -29,7 +29,7 @@
if(make_from)
setDir(make_from.dir)
- make_from.loc = null
+ make_from.moveToNullspace()
stored = make_from
pressure_charging = FALSE // newly built disposal bins start with pump off
else
@@ -297,7 +297,7 @@
data["full_pressure"] = full_pressure
data["pressure_charging"] = pressure_charging
data["panel_open"] = panel_open
- var/per = Clamp(100* air_contents.return_pressure() / (SEND_PRESSURE), 0, 100)
+ var/per = CLAMP(100* air_contents.return_pressure() / (SEND_PRESSURE), 0, 100)
data["per"] = round(per, 1)
data["isai"] = isAI(user)
return data
@@ -471,7 +471,7 @@
if(isobj(AM))
var/obj/O = AM
- O.loc = src
+ O.forceMove(src)
else if(ismob(AM))
var/mob/M = AM
if(prob(2)) // to prevent mobs being stuck in infinite loops
diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm
index 0bafcba54d..e7410685f7 100644
--- a/code/modules/recycling/sortingmachinery.dm
+++ b/code/modules/recycling/sortingmachinery.dm
@@ -61,7 +61,7 @@
if(!user || user.stat != CONSCIOUS || user.loc != O || O.loc != src )
return
to_chat(user, "
You successfully removed [O]'s wrapping !")
- O.loc = loc
+ O.forceMove(loc)
playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1)
qdel(src)
else
diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm
index ebeb869d9c..26fa304209 100644
--- a/code/modules/research/circuitprinter.dm
+++ b/code/modules/research/circuitprinter.dm
@@ -4,14 +4,18 @@ a /datum/desgin on the linked R&D console. You can then print them out in a fasi
using metal and glass, it uses glass and reagents (usually sulfuric acis).
*/
-/obj/machinery/r_n_d/circuit_imprinter
+/obj/machinery/rnd/circuit_imprinter
name = "circuit imprinter"
desc = "Manufactures circuit boards for the construction of machines."
icon_state = "circuit_imprinter"
- container_type = OPENCONTAINER_1
+ container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/circuit_imprinter
var/efficiency_coeff
+ var/console_link = TRUE //can this link to a console?
+ var/requires_console = TRUE
+
+ var/datum/component/material_container/materials //Store for hyper speed!
var/list/categories = list(
"AI Modules",
@@ -27,14 +31,15 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
"Computer Parts"
)
-/obj/machinery/r_n_d/circuit_imprinter/Initialize()
- var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE),
- FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready))
+/obj/machinery/rnd/circuit_imprinter/Initialize()
+ var/datum/component/material_container/materials
+ materials = AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE), 0,
+ FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
materials.precise_insertion = TRUE
create_reagents(0)
return ..()
-/obj/machinery/r_n_d/circuit_imprinter/RefreshParts()
+/obj/machinery/rnd/circuit_imprinter/RefreshParts()
reagents.maximum_volume = 0
for(var/obj/item/reagent_containers/glass/G in component_parts)
reagents.maximum_volume += G.volume
@@ -50,11 +55,11 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
T += M.rating
efficiency_coeff = 2 ** (T - 1) //Only 1 manipulator here, you're making runtimes Razharas
-/obj/machinery/r_n_d/circuit_imprinter/blob_act(obj/structure/blob/B)
+/obj/machinery/rnd/circuit_imprinter/blob_act(obj/structure/blob/B)
if (prob(50))
qdel(src)
-/obj/machinery/r_n_d/circuit_imprinter/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material
+/obj/machinery/rnd/circuit_imprinter/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material
var/list/all_materials = being_built.reagents_list + being_built.materials
GET_COMPONENT(materials, /datum/component/material_container)
@@ -65,7 +70,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
return round(A / max(1, (all_materials[M]/efficiency_coeff)))
//we eject the materials upon deconstruction.
-/obj/machinery/r_n_d/circuit_imprinter/on_deconstruction()
+/obj/machinery/rnd/circuit_imprinter/on_deconstruction()
for(var/obj/item/reagent_containers/glass/G in component_parts)
reagents.trans_to(G, G.reagents.maximum_volume)
GET_COMPONENT(materials, /datum/component/material_container)
@@ -73,24 +78,52 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
..()
-/obj/machinery/r_n_d/circuit_imprinter/disconnect_console()
+/obj/machinery/rnd/circuit_imprinter/disconnect_console()
linked_console.linked_imprinter = null
..()
-/obj/machinery/r_n_d/circuit_imprinter/ComponentActivated(datum/component/C)
- ..()
- if(istype(C, /datum/component/material_container))
- var/datum/component/material_container/M = C
- if(!M.last_insert_success)
- return
- var/lit = M.last_inserted_type
- var/stack_name
- if(ispath(lit, /obj/item/ore/bluespace_crystal))
- stack_name = "bluespace"
- use_power(MINERAL_MATERIAL_AMOUNT / 10)
- else
- var/obj/item/stack/S = lit
- stack_name = initial(S.name)
- use_power(max(1000, (MINERAL_MATERIAL_AMOUNT * M.last_amount_inserted / 10)))
- add_overlay("protolathe_[stack_name]")
- addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[stack_name]"), 10)
+/obj/machinery/rnd/circuit_imprinter/proc/user_try_print_id(id)
+ if((!linked_console && requires_console) || !id)
+ return FALSE
+ var/datum/design/D = (linked_console || requires_console)? linked_console.stored_research.researched_designs[id] : get_techweb_design_by_id(id)
+ if(!istype(D))
+ return FALSE
+
+ var/power = 1000
+ for(var/M in D.materials)
+ power += round(D.materials[M] / 5)
+ power = max(4000, power)
+ use_power(power)
+
+ var/list/efficient_mats = list()
+ for(var/MAT in D.materials)
+ efficient_mats[MAT] = D.materials[MAT]/efficiency_coeff
+
+ if(!materials.has_materials(efficient_mats))
+ say("Not enough materials to complete prototype.")
+ return FALSE
+ for(var/R in D.reagents_list)
+ if(!reagents.has_reagent(R, D.reagents_list[R]/efficiency_coeff))
+ say("Not enough reagents to complete prototype.")
+ return FALSE
+
+ busy = TRUE
+ flick("circuit_imprinter_ani", src)
+ materials.use_amount(efficient_mats)
+ for(var/R in D.reagents_list)
+ reagents.remove_reagent(R, D.reagents_list[R]/efficiency_coeff)
+
+ var/P = D.build_path
+ addtimer(CALLBACK(src, .proc/reset_busy), 16)
+ addtimer(CALLBACK(src, .proc/do_print, P, efficient_mats, D.dangerous_construction), 16)
+ return TRUE
+
+/obj/machinery/rnd/circuit_imprinter/proc/do_print(path, list/matlist, notify_admins)
+ if(notify_admins)
+ if(usr)
+ usr.investigate_log("built [path] at a circuit imprinter.", INVESTIGATE_RESEARCH)
+ var/turf/T = get_turf(usr)
+ message_admins("[key_name(usr)][ADMIN_JMP(T)] has built [path] at a circuit imprinter at [COORD(usr)]")
+ var/obj/item/I = new path(get_turf(src))
+ I.materials = matlist.Copy()
+ SSblackbox.record_feedback("nested_tally", "circuit_printed", 1, list("[type]", "[path]"))
diff --git a/code/modules/research/departmental_circuit_imprinter.dm b/code/modules/research/departmental_circuit_imprinter.dm
new file mode 100644
index 0000000000..7b06aaa839
--- /dev/null
+++ b/code/modules/research/departmental_circuit_imprinter.dm
@@ -0,0 +1,201 @@
+/obj/machinery/rnd/circuit_imprinter/department
+ name = "Department Circuit Imprinter"
+ desc = "A special circuit imprinter with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!"
+ icon_state = "circuit_imprinter"
+ container_type = OPENCONTAINER
+ circuit = /obj/item/circuitboard/machine/circuit_imprinter/department
+ requires_console = FALSE
+
+ var/list/datum/design/cached_designs
+ var/list/datum/design/matching_designs
+ var/department_tag = "Unidentified" //used for material distribution among other things.
+ var/datum/techweb/stored_research
+ var/datum/techweb/host_research
+ var/screen = DEPPRINTER_SCREEN_PRIMARY
+
+/obj/machinery/rnd/circuit_imprinter/department/science
+ allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SCIENCE
+ department_tag = "Science"
+
+/obj/machinery/rnd/circuit_imprinter/department/Initialize()
+ . = ..()
+ stored_research = new
+ cached_designs = list()
+ host_research = SSresearch.science_tech
+ matching_designs = list()
+ update_research()
+
+/obj/machinery/rnd/circuit_imprinter/department/Destroy()
+ QDEL_NULL(stored_research)
+ return ..()
+
+/obj/machinery/rnd/circuit_imprinter/department/user_try_print_id(id, amount)
+ var/datum/design/D = get_techweb_design_by_id(id)
+ if(!D || !(D.departmental_flags & allowed_department_flags))
+ say("Warning: Printing failed. Please update the research data with the on-screen button!")
+ return FALSE
+ . = ..()
+
+/obj/machinery/rnd/circuit_imprinter/department/attack_hand(mob/user)
+ if(..())
+ return
+ interact(user)
+
+/obj/machinery/rnd/circuit_imprinter/department/interact(mob/user)
+ user.set_machine(src)
+
+ var/datum/browser/popup = new(user, "rndconsole", name, 460, 550)
+ popup.set_content(generate_ui())
+ popup.open()
+
+/obj/machinery/rnd/circuit_imprinter/department/proc/search(string)
+ matching_designs.Cut()
+ for(var/v in stored_research.researched_designs)
+ var/datum/design/D = stored_research.researched_designs[v]
+ if(!(D.build_type & IMPRINTER) || !(D.departmental_flags & allowed_department_flags))
+ continue
+ if(findtext(D.name,string))
+ matching_designs.Add(D)
+
+/obj/machinery/rnd/circuit_imprinter/department/proc/update_research()
+ host_research.copy_research_to(stored_research, TRUE)
+ update_designs()
+
+/obj/machinery/rnd/circuit_imprinter/department/proc/update_designs()
+ cached_designs.Cut()
+ for(var/i in stored_research.researched_designs)
+ var/datum/design/d = stored_research.researched_designs[i]
+ if((d.departmental_flags & allowed_department_flags) && (d.build_type & IMPRINTER))
+ cached_designs |= d
+
+/obj/machinery/rnd/circuit_imprinter/department/proc/generate_ui()
+ var/list/ui = list()
+ ui += ui_header()
+ switch(screen)
+ if(DEPPRINTER_SCREEN_MATERIALS)
+ ui += ui_materials()
+ if(DEPPRINTER_SCREEN_CHEMICALS)
+ ui += ui_chemicals()
+ if(DEPPRINTER_SCREEN_SEARCH)
+ ui += ui_search()
+ else
+ ui += ui_department_imprinter()
+ for(var/i in 1 to length(ui))
+ if(!findtextEx(ui[i], RDSCREEN_NOBREAK))
+ ui[i] += "
"
+ ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "")
+ return ui.Join("")
+
+/obj/machinery/rnd/circuit_imprinter/department/proc/ui_search() //Legacy code
+ var/list/l = list()
+ l += "
Search Results:
"
+ l += "
"
+ var/coeff = efficiency_coeff
+ for(var/datum/design/D in matching_designs)
+ var/temp_materials
+ var/check_materials = TRUE
+ var/all_materials = D.materials + D.reagents_list
+ for(var/M in all_materials)
+ temp_materials += " | "
+ if (!check_mat(D, M))
+ check_materials = FALSE
+ temp_materials += "
[all_materials[M]/coeff] [CallMaterialName(M)]"
+ else
+ temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]"
+ if (check_materials)
+ l += "
[D.name][temp_materials]"
+ else
+ l += "
[D.name][temp_materials]"
+ l += "
"
+ return l
+
+/obj/machinery/rnd/circuit_imprinter/department/proc/ui_department_imprinter()
+ var/list/l = list()
+ var/coeff = efficiency_coeff
+ l += "