"
@@ -624,6 +626,9 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
if(job.admin_only)
continue
+ if(job.hidden_from_job_prefs)
+ continue
+
index += 1
if((index >= limit) || (job.title in splitJobs))
if((index < limit) && (lastJob != null))
@@ -2001,6 +2006,11 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
windowflashing = !windowflashing
if("afk_watch")
+ if(!afk_watch)
+ to_chat(user, "You will now get put into cryo dorms after [config.auto_cryo_afk] minutes. \
+ Then after [config.auto_despawn_afk] minutes you will be fully despawned. You will receive a visual and auditory warning before you will be put into cryodorms.")
+ else
+ to_chat(user, "Automatic cryoing turned off.")
afk_watch = !afk_watch
if("UIcolor")
@@ -2071,6 +2081,11 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
load_preferences(user)
load_character(user)
+ if("clear")
+ if(!saved || real_name != input("This will clear the current slot permanently. Please enter the character's full name to confirm."))
+ return FALSE
+ clear_character_slot(user)
+
if("open_load_dialog")
if(!IsGuestKey(user.key))
open_load_dialog(user)
diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm
index 811d163c955..e889ec5a181 100644
--- a/code/modules/client/preference/preferences_mysql.dm
+++ b/code/modules/client/preference/preferences_mysql.dm
@@ -96,7 +96,7 @@
UI_style_alpha='[UI_style_alpha]',
be_role='[sanitizeSQL(list2params(be_special))]',
default_slot='[default_slot]',
- toggles='[num2text(toggles, Ceiling(log(10, (TOGGLES_TOTAL))))]',
+ toggles='[num2text(toggles, CEILING(log(10, (TOGGLES_TOTAL)), 1))]',
atklog='[atklog]',
sound='[sound]',
randomslot='[randomslot]',
@@ -121,6 +121,7 @@
return 1
/datum/preferences/proc/load_character(client/C,slot)
+ saved = FALSE
if(!slot) slot = default_slot
slot = sanitize_integer(slot, 1, max_save_slots, initial(default_slot))
@@ -262,6 +263,8 @@
loadout_gear = params2list(query.item[51])
autohiss_mode = text2num(query.item[52])
+ saved = TRUE
+
//Sanitize
var/datum/species/SP = GLOB.all_species[species]
metadata = sanitize_text(metadata, initial(metadata))
@@ -320,6 +323,10 @@
if(!rlimb_data) src.rlimb_data = list()
if(!loadout_gear) loadout_gear = list()
+ // Check if the current body accessory exists
+ if(!GLOB.body_accessory_by_name[body_accessory])
+ body_accessory = null
+
return 1
/datum/preferences/proc/save_character(client/C)
@@ -470,6 +477,8 @@
log_game("SQL ERROR during character slot saving. Error : \[[err]\]\n")
message_admins("SQL ERROR during character slot saving. Error : \[[err]\]\n")
return
+
+ saved = TRUE
return 1
/datum/preferences/proc/load_random_character_slot(client/C)
@@ -491,3 +500,20 @@
load_character(C,pick(saves))
return 1
+/datum/preferences/proc/clear_character_slot(client/C)
+ . = FALSE
+ // Is there a character in that slot?
+ var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' AND slot='[default_slot]'")
+ query.Execute()
+ if(!query.RowCount())
+ return
+
+ var/DBQuery/query2 = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' AND slot='[default_slot]'")
+ if(!query2.Execute())
+ var/err = query2.ErrorMsg()
+ log_game("SQL ERROR during character slot clearing. Error : \[[err]\]\n")
+ message_admins("SQL ERROR during character slot clearing. Error : \[[err]\]\n")
+ return
+
+ saved = FALSE
+ return TRUE
diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm
index da0873f162f..38b49314667 100644
--- a/code/modules/clothing/chameleon.dm
+++ b/code/modules/clothing/chameleon.dm
@@ -9,6 +9,10 @@
..()
initialize_outfits()
+/datum/action/chameleon_outfit/Destroy()
+ STOP_PROCESSING(SSprocessing, src)
+ return ..()
+
/datum/action/chameleon_outfit/proc/initialize_outfits()
var/static/list/standard_outfit_options
if(!standard_outfit_options)
@@ -140,29 +144,29 @@
UpdateButtonIcon()
/datum/action/item_action/chameleon/change/proc/update_item(obj/item/picked_item)
- // Species-related variables are lists, which can not be retrieved using initial(). As such, we need to instantiate the picked item.
- var/obj/item/P = new picked_item(null)
-
- target.name = P.name
- target.desc = P.desc
- target.icon_state = P.icon_state
+ target.name = initial(picked_item.name)
+ target.desc = initial(picked_item.desc)
+ target.icon_state = initial(picked_item.icon_state)
if(isitem(target))
var/obj/item/I = target
- I.item_state = P.item_state
- I.item_color = P.item_color
+ I.item_state = initial(picked_item.item_state)
+ I.item_color = initial(picked_item.item_color)
- I.icon_override = P.icon_override
- I.sprite_sheets = P.sprite_sheets
+ I.icon_override = initial(picked_item.icon_override)
+ if(initial(picked_item.sprite_sheets))
+ // Species-related variables are lists, which can not be retrieved using initial(). As such, we need to instantiate the picked item.
+ var/obj/item/P = new picked_item(null)
+ I.sprite_sheets = P.sprite_sheets
+ qdel(P)
- if(istype(I, /obj/item/clothing) && istype(P, /obj/item/clothing))
+ if(istype(I, /obj/item/clothing) && istype(initial(picked_item), /obj/item/clothing))
var/obj/item/clothing/CL = I
- var/obj/item/clothing/PCL = P
- CL.flags_cover = PCL.flags_cover
+ var/obj/item/clothing/PCL = picked_item
+ CL.flags_cover = initial(PCL.flags_cover)
- target.icon = P.icon
- qdel(P)
+ target.icon = initial(picked_item.icon)
/datum/action/item_action/chameleon/change/Trigger()
if(!IsAvailable())
@@ -198,7 +202,7 @@
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/clothing/under/chameleon/Initialize()
+/obj/item/clothing/under/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/under
@@ -206,11 +210,15 @@
chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/clothing/under, /obj/item/clothing/under/color, /obj/item/clothing/under/rank), only_root_path = TRUE)
chameleon_action.initialize_disguises()
+/obj/item/clothing/under/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/clothing/under/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/clothing/under/chameleon/broken/Initialize()
+/obj/item/clothing/under/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -229,7 +237,7 @@
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/clothing/suit/chameleon/Initialize()
+/obj/item/clothing/suit/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/suit
@@ -237,11 +245,15 @@
chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/clothing/suit/armor/abductor), only_root_path = TRUE)
chameleon_action.initialize_disguises()
+/obj/item/clothing/suit/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/clothing/suit/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/clothing/suit/chameleon/broken/Initialize()
+/obj/item/clothing/suit/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -261,7 +273,7 @@
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/clothing/glasses/chameleon/Initialize()
+/obj/item/clothing/glasses/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/glasses
@@ -269,11 +281,15 @@
chameleon_action.chameleon_blacklist = list()
chameleon_action.initialize_disguises()
+/obj/item/clothing/glasses/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/clothing/glasses/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/clothing/glasses/chameleon/broken/Initialize()
+/obj/item/clothing/glasses/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -289,7 +305,7 @@
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/clothing/glasses/hud/security/chameleon/Initialize()
+/obj/item/clothing/glasses/hud/security/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/glasses
@@ -297,11 +313,15 @@
chameleon_action.chameleon_blacklist = list()
chameleon_action.initialize_disguises()
+/obj/item/clothing/glasses/hud/security/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/clothing/glasses/hud/security/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/clothing/glasses/hud/security/chameleon/broken/Initialize()
+/obj/item/clothing/glasses/hud/security/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -316,7 +336,7 @@
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/clothing/gloves/chameleon/Initialize()
+/obj/item/clothing/gloves/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/gloves
@@ -324,11 +344,15 @@
chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/clothing/gloves, /obj/item/clothing/gloves/color), only_root_path = TRUE)
chameleon_action.initialize_disguises()
+/obj/item/clothing/gloves/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/clothing/gloves/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/clothing/gloves/chameleon/broken/Initialize()
+/obj/item/clothing/gloves/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -347,7 +371,7 @@
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/clothing/head/chameleon/Initialize()
+/obj/item/clothing/head/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/head
@@ -355,11 +379,15 @@
chameleon_action.chameleon_blacklist = list()
chameleon_action.initialize_disguises()
+/obj/item/clothing/head/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/clothing/head/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/clothing/head/chameleon/broken/Initialize()
+/obj/item/clothing/head/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -389,7 +417,7 @@
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/clothing/mask/chameleon/Initialize()
+/obj/item/clothing/mask/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
@@ -402,13 +430,14 @@
/obj/item/clothing/mask/chameleon/Destroy()
QDEL_NULL(voice_changer)
+ QDEL_NULL(chameleon_action)
return ..()
/obj/item/clothing/mask/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/clothing/mask/chameleon/broken/Initialize()
+/obj/item/clothing/mask/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -423,7 +452,7 @@
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/clothing/shoes/chameleon/Initialize()
+/obj/item/clothing/shoes/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/clothing/shoes
@@ -431,6 +460,10 @@
chameleon_action.chameleon_blacklist = list()
chameleon_action.initialize_disguises()
+/obj/item/clothing/shoes/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/clothing/shoes/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
@@ -442,7 +475,7 @@
desc = "A pair of black shoes."
flags = NOSLIP
-/obj/item/clothing/shoes/chameleon/noslip/broken/Initialize()
+/obj/item/clothing/shoes/chameleon/noslip/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -455,18 +488,22 @@
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/storage/backpack/chameleon/Initialize()
+/obj/item/storage/backpack/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/storage/backpack
chameleon_action.chameleon_name = "Backpack"
chameleon_action.initialize_disguises()
+/obj/item/storage/backpack/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/storage/backpack/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/storage/backpack/chameleon/broken/Initialize()
+/obj/item/storage/backpack/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -475,7 +512,7 @@
desc = "Holds tools."
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/storage/belt/chameleon/Initialize()
+/obj/item/storage/belt/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
@@ -483,11 +520,15 @@
chameleon_action.chameleon_name = "Belt"
chameleon_action.initialize_disguises()
+/obj/item/storage/belt/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/storage/belt/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/storage/belt/chameleon/broken/Initialize()
+/obj/item/storage/belt/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -495,18 +536,22 @@
name = "radio headset"
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/radio/headset/chameleon/Initialize()
+/obj/item/radio/headset/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/radio/headset
chameleon_action.chameleon_name = "Headset"
chameleon_action.initialize_disguises()
+/obj/item/radio/headset/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/radio/headset/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/radio/headset/chameleon/broken/Initialize()
+/obj/item/radio/headset/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
@@ -514,7 +559,7 @@
name = "PDA"
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/pda/chameleon/Initialize()
+/obj/item/pda/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/pda
@@ -522,24 +567,32 @@
chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/pda/heads), only_root_path = TRUE)
chameleon_action.initialize_disguises()
+/obj/item/pda/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
/obj/item/pda/chameleon/emp_act(severity)
. = ..()
chameleon_action.emp_randomise()
-/obj/item/pda/chameleon/broken/Initialize()
+/obj/item/pda/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
/obj/item/stamp/chameleon
var/datum/action/item_action/chameleon/change/chameleon_action
-/obj/item/stamp/chameleon/Initialize()
+/obj/item/stamp/chameleon/Initialize(mapload)
. = ..()
chameleon_action = new(src)
chameleon_action.chameleon_type = /obj/item/stamp
chameleon_action.chameleon_name = "Stamp"
chameleon_action.initialize_disguises()
-/obj/item/stamp/chameleon/broken/Initialize()
+/obj/item/stamp/chameleon/Destroy()
+ QDEL_NULL(chameleon_action)
+ return ..()
+
+/obj/item/stamp/chameleon/broken/Initialize(mapload)
. = ..()
chameleon_action.emp_randomise(INFINITY)
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 1b9c87f56e5..011bc60cdc4 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -376,7 +376,6 @@
desc = "Covers the eyes, preventing sight."
icon_state = "blindfold"
item_state = "blindfold"
- //vision_flags = BLIND
flash_protect = 2
tint = 3 //to make them blind
prescription_upgradable = 0
@@ -412,7 +411,7 @@
if(M.glasses == src)
M.EyeBlind(3)
M.EyeBlurry(5)
- if(!(M.disabilities & NEARSIGHTED))
+ if(!(NEARSIGHTED in M.mutations))
M.BecomeNearsighted()
spawn(100)
M.CureNearsighted()
diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm
index d34584ff425..7ac87e5d5bc 100644
--- a/code/modules/clothing/head/soft_caps.dm
+++ b/code/modules/clothing/head/soft_caps.dm
@@ -113,7 +113,7 @@
/obj/item/clothing/head/soft/sec/corp
name = "corporate security cap"
- desc = "It's baseball hat in corpotate colours."
+ desc = "It's a baseball hat in corporate colours."
icon_state = "corpsoft"
item_color = "corp"
diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm
index 0bf54e8692f..5bf6b90c98e 100644
--- a/code/modules/clothing/shoes/colour.dm
+++ b/code/modules/clothing/shoes/colour.dm
@@ -86,21 +86,25 @@
name = "orange shoes"
icon_state = "orange"
item_color = "orange"
+ var/obj/item/restraints/handcuffs/shackles
-/obj/item/clothing/shoes/orange/attack_self(mob/user as mob)
- if(src.chained)
- src.chained = null
- src.slowdown = SHOES_SLOWDOWN
- new /obj/item/restraints/handcuffs( user.loc )
- src.icon_state = "orange"
- return
+/obj/item/clothing/shoes/orange/Destroy()
+ QDEL_NULL(shackles)
+ return ..()
-/obj/item/clothing/shoes/orange/attackby(obj/H, loc, params)
- ..()
- if(istype(H, /obj/item/restraints/handcuffs) && !chained && !(H.flags & NODROP))
- if(src.icon_state != "orange") return
- qdel(H)
- src.chained = 1
- src.slowdown = 15
- src.icon_state = "orange1"
- return
+/obj/item/clothing/shoes/orange/attack_self(mob/user)
+ if(shackles)
+ user.put_in_hands(shackles)
+ shackles = null
+ slowdown = SHOES_SLOWDOWN
+ icon_state = "orange"
+
+/obj/item/clothing/shoes/orange/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/restraints/handcuffs) && !shackles)
+ if(user.drop_item())
+ I.forceMove(src)
+ shackles = I
+ slowdown = 15
+ icon_state = "orange1"
+ return
+ return ..()
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index 916cb8e89d4..129b07af36e 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -73,16 +73,15 @@ obj/item/clothing/shoes/magboots/syndie/advance //For the Syndicate Strike Team
shoe_sound = "clownstep"
origin_tech = "magnets=4;syndicate=2"
var/enabled_waddle = TRUE
- var/datum/component/waddle
/obj/item/clothing/shoes/magboots/clown/equipped(mob/user, slot)
. = ..()
if(slot == slot_shoes && enabled_waddle)
- waddle = user.AddComponent(/datum/component/waddling)
+ user.AddElement(/datum/element/waddling)
/obj/item/clothing/shoes/magboots/clown/dropped(mob/user)
. = ..()
- QDEL_NULL(waddle)
+ user.RemoveElement(/datum/element/waddling)
/obj/item/clothing/shoes/magboots/clown/CtrlClick(mob/living/user)
if(!isliving(user))
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 6858355f876..962cfed80c5 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -71,16 +71,15 @@
var/footstep = 1 //used for squeeks whilst walking
shoe_sound = "clownstep"
var/enabled_waddle = TRUE
- var/datum/component/waddle
/obj/item/clothing/shoes/clown_shoes/equipped(mob/user, slot)
. = ..()
if(slot == slot_shoes && enabled_waddle)
- waddle = user.AddComponent(/datum/component/waddling)
+ user.AddElement(/datum/element/waddling)
/obj/item/clothing/shoes/clown_shoes/dropped(mob/user)
. = ..()
- QDEL_NULL(waddle)
+ user.RemoveElement(/datum/element/waddling)
/obj/item/clothing/shoes/clown_shoes/CtrlClick(mob/living/user)
if(!isliving(user))
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 5a01c9f6f55..1198792c980 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -531,7 +531,7 @@
/obj/item/clothing/suit/space/hardsuit/shielded/process()
if(world.time > recharge_cooldown && current_charges < max_charges)
- current_charges = Clamp((current_charges + recharge_rate), 0, max_charges)
+ current_charges = clamp((current_charges + recharge_rate), 0, max_charges)
playsound(loc, 'sound/magic/charge.ogg', 50, TRUE)
if(current_charges == max_charges)
playsound(loc, 'sound/machines/ding.ogg', 50, TRUE)
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index 3608ee85164..0d106a874a7 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -155,9 +155,8 @@
if(piece.siemens_coefficient > siemens_coefficient) //So that insulated gloves keep their insulation.
piece.siemens_coefficient = siemens_coefficient
piece.permeability_coefficient = permeability_coefficient
- if(islist(armor))
- var/list/L = armor
- piece.armor = L.Copy()
+ if(armor)
+ piece.armor = armor
update_icon(1)
@@ -286,7 +285,7 @@
if(helmet)
helmet.update_light(wearer)
- correct_piece.armor["bio"] = 100
+ correct_piece.armor = correct_piece.armor.setRating(bio_value = 100)
sealing = FALSE
@@ -389,7 +388,7 @@
if(helmet)
helmet.update_light(wearer)
- correct_piece.armor["bio"] = armor["bio"]
+ correct_piece.armor = correct_piece.armor.setRating(bio_value = armor.getRating("bio"))
sealing = FALSE
@@ -553,7 +552,7 @@
data["charge"] = cell ? round(cell.charge,1) : 0
data["maxcharge"] = cell ? cell.maxcharge : 0
- data["chargestatus"] = cell ? Floor((cell.charge/cell.maxcharge)*50) : 0
+ data["chargestatus"] = cell ? FLOOR((cell.charge/cell.maxcharge)*50, 1) : 0
data["emagged"] = subverted
data["coverlock"] = locked
@@ -798,7 +797,7 @@
to_chat(wearer, "You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.")
return
use_obj.forceMove(wearer)
- if(!wearer.equip_to_slot_if_possible(use_obj, equip_to, 0, 1))
+ if(!wearer.equip_to_slot_if_possible(use_obj, equip_to, FALSE, TRUE))
use_obj.forceMove(src)
else
if(wearer)
diff --git a/code/modules/clothing/spacesuits/rig/rig_armormod.dm b/code/modules/clothing/spacesuits/rig/rig_armormod.dm
index 68daec45b5a..c04270aa97b 100644
--- a/code/modules/clothing/spacesuits/rig/rig_armormod.dm
+++ b/code/modules/clothing/spacesuits/rig/rig_armormod.dm
@@ -9,13 +9,22 @@
multi *= (100 - chest.damage) / 100 //If we have some breaches, lower the armor value.
//TODO check for other armor mods, likely modules, which need to be coded.
+ if(!armor) //Did we even give them some armor, if this is the case, the list should be initialized from New()
+ return
+ var/datum/armor/A = armor
for(var/obj/item/piece in list(gloves, helmet, boots, chest))
if(!istype(piece)) //Do we have the piece
continue
- if(islist(armor)) //Did we even give them some armor, if this is the case, the list should be initialized from New()
- var/list/L = armor
- for(var/armortype in L)
- piece.armor[armortype] = L[armortype]*multi
+
+ piece.armor = piece.armor.setRating(melee_value = A.getRating("melee") * multi,
+ bullet_value = A.getRating("bullet") * multi,
+ laser_value = A.getRating("laser") * multi,
+ energy_value = A.getRating("energy") * multi,
+ bomb_value = A.getRating("bomb") * multi,
+ bio_value = A.getRating("bio") * multi,
+ rad_value = A.getRating("rad") * multi,
+ fire_value = A.getRating("fire") * multi,
+ acid_value = A.getRating("acidd") * multi)
//Perfect place to also add something like shield modules, or any other hit_reaction modules check.
diff --git a/code/modules/clothing/suits/hood.dm b/code/modules/clothing/suits/hood.dm
index 83f0fcfc211..be05ced4fd8 100644
--- a/code/modules/clothing/suits/hood.dm
+++ b/code/modules/clothing/suits/hood.dm
@@ -59,7 +59,7 @@
if(H.head)
to_chat(H,"You're already wearing something on your head!")
return
- else if(H.equip_to_slot_if_possible(hood, slot_head, 0, 0, 1))
+ else if(H.equip_to_slot_if_possible(hood, slot_head, FALSE, FALSE))
suit_adjusted = 1
icon_state = "[initial(icon_state)]_hood"
H.update_inv_wear_suit()
diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm
index c329d8a0033..7e1a993fca4 100644
--- a/code/modules/clothing/suits/toggles.dm
+++ b/code/modules/clothing/suits/toggles.dm
@@ -68,7 +68,7 @@
if(H.head)
to_chat(H, "You're already wearing something on your head!")
return
- else if(H.equip_to_slot_if_possible(helmet, slot_head, 0 ,0, 1))
+ else if(H.equip_to_slot_if_possible(helmet, slot_head, FALSE, FALSE))
to_chat(H, "You engage the helmet on the hardsuit.")
suittoggled = TRUE
H.update_inv_wear_suit()
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index b417df89426..76bcd87921d 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -37,8 +37,13 @@
var/mob/M = has_suit.loc
A.Grant(M)
- for(var/armor_type in armor)
- has_suit.armor[armor_type] += armor[armor_type]
+ if (islist(has_suit.armor) || isnull(has_suit.armor)) // This proc can run before /obj/Initialize has run for U and src,
+ has_suit.armor = getArmor(arglist(has_suit.armor)) // we have to check that the armor list has been transformed into a datum before we try to call a proc on it
+ // This is safe to do as /obj/Initialize only handles setting up the datum if actually needed.
+ if (islist(armor) || isnull(armor))
+ armor = getArmor(arglist(armor))
+
+ has_suit.armor = has_suit.armor.attachArmor(armor)
if(user)
to_chat(user, "You attach [src] to [has_suit].")
@@ -56,8 +61,7 @@
var/mob/M = has_suit.loc
A.Remove(M)
- for(var/armor_type in armor)
- has_suit.armor[armor_type] -= armor[armor_type]
+ has_suit.armor = has_suit.armor.detachArmor(armor)
has_suit = null
if(user)
@@ -314,6 +318,36 @@
if(isliving(user))
user.visible_message("[user] invades [M]'s personal space, thrusting [src] into [M.p_their()] face insistently.","You invade [M]'s personal space, thrusting [src] into [M.p_their()] face insistently. You are the law.")
+//////////////
+//OBJECTION!//
+//////////////
+
+/obj/item/clothing/accessory/lawyers_badge
+ name = "attorney's badge"
+ desc = "Fills you with the conviction of JUSTICE. Lawyers tend to want to show it to everyone they meet."
+ icon_state = "lawyerbadge"
+ item_state = "lawyerbadge"
+ item_color = "lawyerbadge"
+ var/cached_bubble_icon = null
+
+/obj/item/clothing/accessory/lawyers_badge/attack_self(mob/user)
+ if(prob(1))
+ user.say("The testimony contradicts the evidence!")
+ user.visible_message("[user] shows [user.p_their()] attorney's badge.", "You show your attorney's badge.")
+
+/obj/item/clothing/accessory/lawyers_badge/on_attached(obj/item/clothing/under/S, mob/user)
+ ..()
+ if(has_suit && ismob(has_suit.loc))
+ var/mob/M = has_suit.loc
+ cached_bubble_icon = M.bubble_icon
+ M.bubble_icon = "lawyer"
+
+/obj/item/clothing/accessory/lawyers_badge/on_removed(mob/user)
+ if(has_suit && ismob(has_suit.loc))
+ var/mob/M = has_suit.loc
+ M.bubble_icon = cached_bubble_icon
+ ..()
+
///////////
//SCARVES//
///////////
diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm
index a9c47e760e7..a0d6823fe80 100644
--- a/code/modules/crafting/craft.dm
+++ b/code/modules/crafting/craft.dm
@@ -128,7 +128,7 @@
continue main_loop
return FALSE
for(var/obj/item/T in tools_used)
- if(!T.tool_start_check(user, 0)) //Check if all our tools are valid for their use
+ if(!T.tool_start_check(null, user, 0)) //Check if all our tools are valid for their use
return FALSE
return TRUE
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index f8d2029651d..530b9095f75 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -48,7 +48,7 @@
var/mob/living/carbon/human/target = M
- if(ismachine(target))
+ if(ismachineperson(target))
to_chat(user, "[target] has no skin, how do you expect to tattoo [target.p_them()]?")
return
@@ -349,7 +349,7 @@
to_chat(user, "You modify the appearance of [target].")
var/obj/item/clothing/mask/gas/M = target
M.name = "Prescription Gas Mask"
- M.desc = "It looks heavily modified, but otherwise functions as a gas mask. The words “Property of Yon-Dale” can be seen on the inner band."
+ M.desc = "It looks heavily modified, but otherwise functions as a gas mask. The words \"Property of Yon-Dale\" can be seen on the inner band."
M.icon = 'icons/obj/custom_items.dmi'
M.icon_state = "gas_tariq"
M.sprite_sheets = list(
diff --git a/code/modules/detective_work/footprints_and_rag.dm b/code/modules/detective_work/footprints_and_rag.dm
index 2646d03fb0f..bfc9d0aa824 100644
--- a/code/modules/detective_work/footprints_and_rag.dm
+++ b/code/modules/detective_work/footprints_and_rag.dm
@@ -18,7 +18,6 @@
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(5)
volume = 5
- can_be_placed_into = null
flags = NOBLUDGEON
container_type = OPENCONTAINER
has_lid = FALSE
diff --git a/code/modules/economy/Accounts_DB.dm b/code/modules/economy/Accounts_DB.dm
index 6995e260500..aafc91cb849 100644
--- a/code/modules/economy/Accounts_DB.dm
+++ b/code/modules/economy/Accounts_DB.dm
@@ -159,7 +159,7 @@ GLOBAL_VAR(current_date_string)
var/account_name = href_list["holder_name"]
var/starting_funds = max(text2num(href_list["starting_funds"]), 0)
- starting_funds = Clamp(starting_funds, 0, GLOB.station_account.money) // Not authorized to put the station in debt.
+ starting_funds = clamp(starting_funds, 0, GLOB.station_account.money) // Not authorized to put the station in debt.
starting_funds = min(starting_funds, fund_cap) // Not authorized to give more than the fund cap.
var/datum/money_account/M = create_account(account_name, starting_funds, src)
diff --git a/code/modules/economy/utils.dm b/code/modules/economy/utils.dm
index f7d6992e31f..4d7273cd719 100644
--- a/code/modules/economy/utils.dm
+++ b/code/modules/economy/utils.dm
@@ -5,7 +5,7 @@
////////////////////////
/proc/get_money_account(var/account_number, var/from_z=-1)
- for(var/obj/machinery/computer/account_database/DB in world)
+ for(var/obj/machinery/computer/account_database/DB in GLOB.machines)
if(from_z > -1 && DB.z != from_z) continue
if((DB.stat & NOPOWER) || !DB.activated ) continue
var/datum/money_account/acct = DB.get_account(account_number)
diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm
index 5e39295113c..8c01d5c7cc2 100644
--- a/code/modules/events/alien_infestation.dm
+++ b/code/modules/events/alien_infestation.dm
@@ -17,7 +17,7 @@
playercount = length(GLOB.clients)//grab playercount when event starts not when game starts
if(playercount >= highpop_trigger) //spawn with 4 if highpop
spawncount = 4
- for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
+ for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in SSair.atmos_machinery)
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
if(temp_vent.parent.other_atmosmch.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology
vents += temp_vent
diff --git a/code/modules/events/anomaly_bluespace.dm b/code/modules/events/anomaly_bluespace.dm
index 2924effa0de..929612cf6f9 100644
--- a/code/modules/events/anomaly_bluespace.dm
+++ b/code/modules/events/anomaly_bluespace.dm
@@ -18,7 +18,7 @@
// Calculate new position (searches through beacons in world)
var/obj/item/radio/beacon/chosen
var/list/possible = list()
- for(var/obj/item/radio/beacon/W in world)
+ for(var/obj/item/radio/beacon/W in GLOB.global_radios)
if(!is_station_level(W.z))
continue
possible += W
diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm
index 79e7c7b8434..0a5dc14bc3a 100644
--- a/code/modules/events/anomaly_pyro.dm
+++ b/code/modules/events/anomaly_pyro.dm
@@ -15,7 +15,7 @@
if(!newAnomaly)
kill()
return
- if(IsMultiple(activeFor, 5))
+ if(ISMULTIPLE(activeFor, 5))
newAnomaly.anomalyEffect()
/datum/event/anomaly/anomaly_pyro/end()
diff --git a/code/modules/events/apc_overload.dm b/code/modules/events/apc_overload.dm
new file mode 100644
index 00000000000..13cabe81b3c
--- /dev/null
+++ b/code/modules/events/apc_overload.dm
@@ -0,0 +1,64 @@
+#define APC_BREAK_PROBABILITY 25 // the probability that a given APC will be broken
+
+/datum/event/apc_overload
+ var/const/announce_after_mc_ticks = 5
+ var/const/delayed = FALSE
+ var/const/event_max_duration_mc_ticks = announce_after_mc_ticks * 2
+ var/const/event_min_duration_mc_ticks = announce_after_mc_ticks
+
+ announceWhen = announce_after_mc_ticks
+
+/datum/event/apc_overload/setup()
+ endWhen = rand(event_min_duration_mc_ticks, event_max_duration_mc_ticks)
+
+/datum/event/apc_overload/start()
+ apc_overload_failure(announce=delayed)
+ var/sound/S = sound('sound/effects/powerloss.ogg')
+ for(var/mob/living/M in GLOB.player_list)
+ var/turf/T = get_turf(M)
+ if(!M.client || !is_station_level(T.z))
+ continue
+ SEND_SOUND(M, S)
+
+/datum/event/apc_overload/announce()
+ GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/apc_overload.ogg')
+
+/datum/event/apc_overload/end()
+ return TRUE
+
+/proc/apc_overload_failure(announce=TRUE)
+ var/list/skipped_areas_apc = list(
+ /area/engine/engineering,
+ /area/turret_protected/ai)
+
+ if(announce)
+ GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/apc_overload.ogg')
+
+ // break APC_BREAK_PROBABILITY% of all of the APCs on the station
+ var/affected_apc_count = 0
+ for(var/thing in GLOB.apcs)
+ var/obj/machinery/power/apc/C = thing
+ // skip any APCs that are too critical to break
+ var/area/current_area = get_area(C)
+ if((current_area.type in skipped_areas_apc) || !is_station_level(C.z))
+ continue
+ // if we are going to break this one
+ if(prob(APC_BREAK_PROBABILITY))
+ // if it has a cell, drain all the charge from the cell
+ if(C.cell)
+ C.cell.charge = 0
+ // if it has a terminal, disconnect and delete the terminal
+ if(C.terminal)
+ var/obj/machinery/power/terminal/T = C.terminal
+ C.terminal.master = null
+ C.terminal = null
+ qdel(T)
+ // if it was operating, toggle off the breaker
+ if(C.operating)
+ C.toggle_breaker()
+ // no matter what, ensure the area knows something happened to the power
+ current_area.power_change()
+ affected_apc_count++
+ log_and_message_admins("APC Overload event deleted [affected_apc_count] underfloor APC terminals.")
+
+#undef APC_BREAK_PROBABILITY
diff --git a/code/modules/events/apc_short.dm b/code/modules/events/apc_short.dm
new file mode 100644
index 00000000000..c19b6cbe8b7
--- /dev/null
+++ b/code/modules/events/apc_short.dm
@@ -0,0 +1,89 @@
+#define APC_BREAK_PROBABILITY 25 // the probability that a given APC will be disabled
+
+/datum/event/apc_short
+ var/const/announce_after_mc_ticks = 5
+ var/const/delayed = FALSE
+ var/const/event_max_duration_mc_ticks = announce_after_mc_ticks * 2
+ var/const/event_min_duration_mc_ticks = announce_after_mc_ticks
+
+ announceWhen = announce_after_mc_ticks
+
+/datum/event/apc_short/setup()
+ endWhen = rand(event_min_duration_mc_ticks, event_max_duration_mc_ticks)
+
+/datum/event/apc_short/start()
+ power_failure(announce=delayed)
+ var/sound/S = sound('sound/effects/powerloss.ogg')
+ for(var/mob/living/M in GLOB.player_list)
+ var/turf/T = get_turf(M)
+ if(!M.client || !is_station_level(T.z))
+ continue
+ SEND_SOUND(M, S)
+
+/datum/event/apc_short/announce()
+ GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/apc_short.ogg')
+
+/datum/event/apc_short/end()
+ return TRUE
+
+/proc/power_failure(announce=TRUE)
+ var/list/skipped_areas_apc = list(
+ /area/engine/engineering,
+ /area/turret_protected/ai)
+
+ if(announce)
+ GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/apc_short.ogg')
+
+ // break APC_BREAK_PROBABILITY% of all of the APCs on the station
+ var/affected_apc_count = 0
+ for(var/thing in GLOB.apcs)
+ var/obj/machinery/power/apc/C = thing
+ // skip any APCs that are too critical to disable
+ var/area/current_area = get_area(C)
+ if((current_area.type in skipped_areas_apc) || !is_station_level(C.z))
+ continue
+ // if we are going to break this one
+ if(prob(APC_BREAK_PROBABILITY))
+ // if it has internal wires, cut the power wires
+ if(C.wires)
+ if(!C.wires.IsIndexCut(APC_WIRE_MAIN_POWER1))
+ C.wires.CutWireIndex(APC_WIRE_MAIN_POWER1)
+ if(!C.wires.IsIndexCut(APC_WIRE_MAIN_POWER2))
+ C.wires.CutWireIndex(APC_WIRE_MAIN_POWER2)
+ // if it was operating, toggle off the breaker
+ if(C.operating)
+ C.toggle_breaker()
+ // no matter what, ensure the area knows something happened to the power
+ current_area.power_change()
+ affected_apc_count++
+ log_and_message_admins("APC Short event shorted out [affected_apc_count] APCs.")
+
+/proc/power_restore(announce=TRUE)
+ if(announce)
+ GLOB.event_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
+
+ // recharge the APCs
+ for(var/thing in GLOB.apcs)
+ var/obj/machinery/power/apc/A = thing
+ if(!is_station_level(A.z))
+ continue
+ var/obj/item/stock_parts/cell/C = A.get_cell()
+ if(C)
+ C.give(C.maxcharge)
+
+/proc/power_restore_quick(announce=TRUE)
+ if(announce)
+ GLOB.event_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
+
+ // fix all of the SMESs
+ for(var/obj/machinery/power/smes/S in GLOB.machines)
+ if(!is_station_level(S.z))
+ continue
+ S.charge = S.capacity
+ S.output_level = S.output_level_max
+ S.output_attempt = 1
+ S.input_attempt = 1
+ S.update_icon()
+ S.power_change()
+
+#undef APC_BREAK_PROBABILITY
diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm
index d3b7cf012b8..8d91635c458 100644
--- a/code/modules/events/brand_intelligence.dm
+++ b/code/modules/events/brand_intelligence.dm
@@ -55,12 +55,12 @@
kill()
return
- if(IsMultiple(activeFor, 4))
+ if(ISMULTIPLE(activeFor, 4))
var/obj/machinery/vending/rebel = pick(vendingMachines)
vendingMachines.Remove(rebel)
infectedMachines.Add(rebel)
rebel.shut_up = 0
rebel.shoot_inventory = 1
- if(IsMultiple(activeFor, 8))
+ if(ISMULTIPLE(activeFor, 8))
originMachine.speak(pick(rampant_speeches))
diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm
index fb12a258c2d..fb02033b802 100644
--- a/code/modules/events/carp_migration.dm
+++ b/code/modules/events/carp_migration.dm
@@ -30,7 +30,8 @@
/datum/event/carp_migration/proc/spawn_fish(num_groups, group_size_min = 3, group_size_max = 5)
var/list/spawn_locations = list()
- for(var/obj/effect/landmark/C in GLOB.landmarks_list)
+ for(var/thing in GLOB.landmarks_list)
+ var/obj/effect/landmark/C = thing
if(C.name == "carpspawn")
spawn_locations.Add(C.loc)
spawn_locations = shuffle(spawn_locations)
diff --git a/code/modules/events/communications_blackout.dm b/code/modules/events/communications_blackout.dm
index 2d83372d625..52baf0fe05c 100644
--- a/code/modules/events/communications_blackout.dm
+++ b/code/modules/events/communications_blackout.dm
@@ -17,7 +17,7 @@
/datum/event/communications_blackout/start()
// This only affects the cores, relays should be unaffected imo
for(var/obj/machinery/tcomms/core/T in GLOB.tcomms_machines)
- T.disable_machine()
+ T.start_ion()
// Bring it back sometime between 3-5 minutes. This uses deciseconds, so 1800 and 3000 respecticely.
- // Note that because this is a strict enable not a toggle, the crew or AI can re-enable the machine themselves
- addtimer(CALLBACK(T, /obj/machinery/tcomms.proc/enable_machine), rand(1800, 3000))
+ // The AI cannot disable this, it must be waited for
+ addtimer(CALLBACK(T, /obj/machinery/tcomms.proc/end_ion), rand(1800, 3000))
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index 291ae55c743..1bc00c93025 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -1,43 +1,36 @@
/datum/event/disease_outbreak
announceWhen = 15
-
- var/datum/disease/advance/virus_type
+ var/datum/disease/D
/datum/event/disease_outbreak/setup()
announceWhen = rand(15, 30)
+ if(prob(25))
+ var/virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis, /datum/disease/beesease, /datum/disease/anxiety, /datum/disease/fake_gbs, /datum/disease/fluspanish, /datum/disease/pierrot_throat, /datum/disease/lycan)
+ D = new virus_type()
+ else
+ var/datum/disease/advance/A = new /datum/disease/advance
+ A.name = capitalize(pick(GLOB.adjectives)) + " " + capitalize(pick(GLOB.nouns + GLOB.verbs)) // random silly name
+ A.GenerateSymptoms(1,9,6)
+ A.AssignProperties(list("resistance" = rand(0,11), "stealth" = rand(0,2), "stage_rate" = rand(0,5), "transmittable" = rand(0,5), "severity" = rand(0,10)))
+ D = A
+
+ D.carrier = TRUE
/datum/event/disease_outbreak/announce()
GLOB.event_announcement.Announce("Confirmed outbreak of level 7 major viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
/datum/event/disease_outbreak/start()
- if(prob(25))
- virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis, /datum/disease/beesease, /datum/disease/anxiety, /datum/disease/fake_gbs, /datum/disease/fluspanish, /datum/disease/pierrot_throat, /datum/disease/lycan)
- else
- virus_type = new /datum/disease/advance
- virus_type.name = capitalize(pick(GLOB.adjectives)) + " " + capitalize(pick(GLOB.nouns,GLOB.verbs)) // random silly name
- virus_type.GenerateSymptoms(1,9,6)
- virus_type.AssignProperties(list("resistance" = rand(0,11), "stealth" = rand(0,2), "stage_rate" = rand(0,5), "transmittable" = rand(0,5), "severity" = rand(0,10)))
- for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
- if(issmall(H)) //don't infect monkies; that's a waste
- continue
+ for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
if(!H.client)
continue
- if(VIRUSIMMUNE in H.dna.species.species_traits) //don't let virus immune things get diseases they're not supposed to get.
+ if(issmall(H)) //don't infect monkies; that's a waste
continue
var/turf/T = get_turf(H)
if(!T)
continue
if(!is_station_level(T.z))
continue
- var/foundAlready = FALSE // don't infect someone that already has the virus
- for(var/thing in H.viruses)
- foundAlready = TRUE
- break
- if(H.stat == DEAD || foundAlready)
- continue
- var/datum/disease/advance/D
- D = virus_type
- D.carrier = TRUE
- H.AddDisease(D)
+ if(!H.ForceContractDisease(D))
+ continue
break
diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm
index 563ef98697d..a11ef107a8f 100644
--- a/code/modules/events/dust.dm
+++ b/code/modules/events/dust.dm
@@ -16,7 +16,7 @@
density = 1
anchored = 1
var/strength = 2 //ex_act severity number
- var/life = 2 //how many things we hit before del(src)
+ var/life = 2 //how many things we hit before qdel(src)
var/atom/goal = null
/obj/effect/space_dust/weak
diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm
index 755e2e2d47a..7304469f408 100644
--- a/code/modules/events/electrical_storm.dm
+++ b/code/modules/events/electrical_storm.dm
@@ -10,7 +10,8 @@
for(var/i=1, i <= lightsoutAmount, i++)
var/list/possibleEpicentres = list()
- for(var/obj/effect/landmark/newEpicentre in GLOB.landmarks_list)
+ for(var/thing in GLOB.landmarks_list)
+ var/obj/effect/landmark/newEpicentre = thing
if(newEpicentre.name == "lightsout" && !(newEpicentre in epicentreList))
possibleEpicentres += newEpicentre
if(possibleEpicentres.len)
@@ -21,7 +22,8 @@
if(!epicentreList.len)
return
- for(var/obj/effect/landmark/epicentre in epicentreList)
- for(var/obj/machinery/power/apc/apc in range(epicentre,lightsoutRange))
+ for(var/thing in epicentreList)
+ var/obj/effect/landmark/epicentre = thing
+ for(var/obj/machinery/power/apc/apc in range(epicentre, lightsoutRange))
apc.overload_lighting()
diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm
index 9c744b8060a..908bc762315 100644
--- a/code/modules/events/event_container.dm
+++ b/code/modules/events/event_container.dm
@@ -128,7 +128,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
/datum/event_container/mundane
severity = EVENT_LEVEL_MUNDANE
available_events = list(
- // Severity level, event name, even type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero
+ // Severity level, event name, event type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 1100),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15),
@@ -157,7 +157,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)),
//new /datum/event_meta(EVENT_LEVEL_MODERATE, "Virology Breach", /datum/event/prison_break/virology, 0, list(ASSIGNMENT_MEDICAL = 100)),
//new /datum/event_meta(EVENT_LEVEL_MODERATE, "Xenobiology Breach", /datum/event/prison_break/xenobiology, 0, list(ASSIGNMENT_SCIENCE = 100)),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_ENGINEER = 60)),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "APC Short", /datum/event/apc_short, 200, list(ASSIGNMENT_ENGINEER = 60)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 250, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_JANITOR = 150)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 25, list(ASSIGNMENT_MEDICAL = 50), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
@@ -191,6 +191,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
//new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
+ new /datum/event_meta(EVENT_LEVEL_MAJOR, "APC Overload", /datum/event/apc_overload, 0),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 5), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1),
diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm
deleted file mode 100644
index 8da2a6d707e..00000000000
--- a/code/modules/events/grid_check.dm
+++ /dev/null
@@ -1,82 +0,0 @@
-/datum/event/grid_check //NOTE: Times are measured in master controller ticks!
- announceWhen = 5
-
-/datum/event/grid_check/setup()
- endWhen = rand(30,120)
-
-/datum/event/grid_check/start()
- power_failure(0)
- var/sound/S = sound('sound/effects/powerloss.ogg')
- for(var/mob/living/M in GLOB.player_list)
- var/turf/T = get_turf(M)
- if(!M.client || !is_station_level(T.z))
- continue
- SEND_SOUND(M, S)
-
-/datum/event/grid_check/announce()
- GLOB.event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg')
-
-/datum/event/grid_check/end()
- power_restore()
-
-/proc/power_failure(var/announce = 1)
- if(announce)
- GLOB.event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", new_sound = 'sound/AI/poweroff.ogg')
-
- var/list/skipped_areas = list(/area/turret_protected/ai)
- var/list/skipped_areas_apc = list(/area/engine/engineering)
-
- for(var/obj/machinery/power/smes/S in GLOB.machines)
- var/area/current_area = get_area(S)
- if((current_area.type in skipped_areas) || !is_station_level(S.z))
- continue
- S.last_charge = S.charge
- S.last_output_attempt = S.output_attempt
- S.last_input_attempt = S.input_attempt
- S.charge = 0
- S.inputting(0)
- S.outputting(0)
- S.update_icon()
- S.power_change()
-
- for(var/obj/machinery/power/apc/C in GLOB.apcs)
- var/area/current_area = get_area(C)
- if((current_area.type in skipped_areas_apc) || !is_station_level(C.z))
- continue
- if(C.cell)
- C.cell.charge = 0
-
-/proc/power_restore(var/announce = 1)
- var/list/skipped_areas = list(/area/turret_protected/ai)
- var/list/skipped_areas_apc = list(/area/engine/engineering)
-
- if(announce)
- GLOB.event_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
- for(var/obj/machinery/power/apc/C in GLOB.apcs)
- var/area/current_area = get_area(C)
- if((current_area.type in skipped_areas_apc) || !is_station_level(C.z))
- continue
- if(C.cell)
- C.cell.charge = C.cell.maxcharge
- for(var/obj/machinery/power/smes/S in GLOB.machines)
- var/area/current_area = get_area(S)
- if((current_area.type in skipped_areas) || !is_station_level(S.z))
- continue
- S.charge = S.last_charge
- S.output_attempt = S.last_output_attempt
- S.input_attempt = S.last_input_attempt
- S.update_icon()
- S.power_change()
-
-/proc/power_restore_quick(var/announce = 1)
- if(announce)
- GLOB.event_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
- for(var/obj/machinery/power/smes/S in GLOB.machines)
- if(!is_station_level(S.z))
- continue
- S.charge = S.capacity
- S.output_level = S.output_level_max
- S.output_attempt = 1
- S.input_attempt = 1
- S.update_icon()
- S.power_change()
diff --git a/code/modules/events/holidays/AprilFools.dm b/code/modules/events/holidays/AprilFools.dm
deleted file mode 100644
index 562e6b98e0d..00000000000
--- a/code/modules/events/holidays/AprilFools.dm
+++ /dev/null
@@ -1 +0,0 @@
-//placeholder for holiday stuff
diff --git a/code/modules/events/holidays/Christmas.dm b/code/modules/events/holidays/Christmas.dm
deleted file mode 100644
index e04471482a5..00000000000
--- a/code/modules/events/holidays/Christmas.dm
+++ /dev/null
@@ -1,61 +0,0 @@
-/proc/Christmas_Game_Start()
- for(var/obj/structure/flora/tree/pine/xmas in world)
- if(!is_station_level(xmas.z)) continue
- for(var/turf/simulated/floor/T in orange(1,xmas))
- for(var/i=1,i<=rand(1,5),i++)
- new /obj/item/a_gift(T)
- for(var/mob/living/simple_animal/corgi/Ian/Ian in GLOB.mob_list)
- Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
-
-/proc/ChristmasEvent()
- for(var/obj/structure/flora/tree/pine/xmas in world)
- var/mob/living/simple_animal/hostile/tree/evil_tree = new /mob/living/simple_animal/hostile/tree(xmas.loc)
- evil_tree.icon_state = xmas.icon_state
- evil_tree.icon_living = evil_tree.icon_state
- evil_tree.icon_dead = evil_tree.icon_state
- evil_tree.icon_gib = evil_tree.icon_state
- qdel(xmas)
-
-/obj/item/toy/xmas_cracker
- name = "xmas cracker"
- icon = 'icons/obj/christmas.dmi'
- icon_state = "cracker"
- desc = "Directions for use: Requires two people, one to pull each end."
- var/cracked = 0
-
-/obj/item/toy/xmas_cracker/New()
- ..()
-
-/obj/item/toy/xmas_cracker/attack(mob/target, mob/user)
- if( !cracked && istype(target,/mob/living/carbon/human) && (target.stat == CONSCIOUS) && !target.get_active_hand() )
- target.visible_message("[user] and [target] pop \an [src]! *pop*", "You pull \an [src] with [target]! *pop*", "You hear a *pop*.")
- var/obj/item/paper/Joke = new /obj/item/paper(user.loc)
- Joke.name = "[pick("awful","terrible","unfunny")] joke"
- Joke.info = pick("What did one snowman say to the other?\n\n'Is it me or can you smell carrots?'",
- "Why couldn't the snowman get laid?\n\nHe was frigid!",
- "Where are santa's helpers educated?\n\nNowhere, they're ELF-taught.",
- "What happened to the man who stole advent calanders?\n\nHe got 25 days.",
- "What does Santa get when he gets stuck in a chimney?\n\nClaus-trophobia.",
- "Where do you find chili beans?\n\nThe north pole.",
- "What do you get from eating tree decorations?\n\nTinsilitis!",
- "What do snowmen wear on their heads?\n\nIce caps!",
- "Why is Christmas just like life on ss13?\n\nYou do all the work and the fat guy gets all the credit.",
- "Why doesn�t Santa have any children?\n\nBecause he only comes down the chimney.")
- new /obj/item/clothing/head/festive(target.loc)
- user.update_icons()
- cracked = 1
- icon_state = "cracker1"
- var/obj/item/toy/xmas_cracker/other_half = new /obj/item/toy/xmas_cracker(target)
- other_half.cracked = 1
- other_half.icon_state = "cracker2"
- target.put_in_active_hand(other_half)
- playsound(user, 'sound/effects/snap.ogg', 50, 1)
- return 1
- return ..()
-
-/obj/item/clothing/head/festive
- name = "festive paper hat"
- icon_state = "xmashat"
- desc = "A crappy paper hat that you are REQUIRED to wear."
- flags_inv = 0
- armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
diff --git a/code/modules/events/holidays/Easter.dm b/code/modules/events/holidays/Easter.dm
deleted file mode 100644
index 562e6b98e0d..00000000000
--- a/code/modules/events/holidays/Easter.dm
+++ /dev/null
@@ -1 +0,0 @@
-//placeholder for holiday stuff
diff --git a/code/modules/events/holidays/Holidays.dm b/code/modules/events/holidays/Holidays.dm
deleted file mode 100644
index 5bc49001e3a..00000000000
--- a/code/modules/events/holidays/Holidays.dm
+++ /dev/null
@@ -1,183 +0,0 @@
-//Uncommenting ALLOW_HOLIDAYS in config.txt will enable Holidays
-GLOBAL_VAR_INIT(Holiday) // I didnt update the rest of this code because this file hasnt been ticked in years, and holiday code got overhauled
- // If it really needs fixing, yell at me, -aa
-
-//Just thinking ahead! Here's the foundations to a more robust Holiday event system.
-//It's easy as hell to add stuff. Just set Holiday to something using the switch(or something else)
-//then use if(Holiday == "MyHoliday") to make stuff happen on that specific day only
-//Please, Don't spam stuff up with easter eggs, I'd rather somebody just delete this than people cause
-//the game to lag even more in the name of one-day content.
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-//ALSO, MOST IMPORTANTLY: Don't add stupid stuff! Discuss bonus content with Project-Heads first please!//
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-// ~Carn
-
-/hook/startup/proc/updateHoliday()
- Get_Holiday()
- return 1
-
-//sets up the Holiday global variable. Shouldbe called on game configuration or something.
-/proc/Get_Holiday()
- if(!Holiday) return // Holiday stuff was not enabled in the config!
-
- Holiday = null // reset our switch now so we can recycle it as our Holiday name
-
- var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
- var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
- var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
-
- //Main switch. If any of these are too dumb/inappropriate, or you have better ones, feel free to change whatever
- switch(MM)
- if(1) //Jan
- switch(DD)
- if(1) Holiday = "New Year's Day"
-
- if(2) //Feb
- switch(DD)
- if(2) Holiday = "Groundhog Day"
- if(14) Holiday = "Valentine's Day"
- if(17) Holiday = "Random Acts of Kindness Day"
-
- if(3) //Mar
- switch(DD)
- if(14) Holiday = "Pi Day"
- if(17) Holiday = "St. Patrick's Day"
- if(27)
- if(YY == 16)
- Holiday = "Easter"
- if(31)
- if(YY == 13)
- Holiday = "Easter"
-
- if(4) //Apr
- switch(DD)
- if(1)
- Holiday = "April Fool's Day"
- if(YY == 18 && prob(50)) Holiday = "Easter"
- if(5)
- if(YY == 15) Holiday = "Easter"
- if(16)
- if(YY == 17) Holiday = "Easter"
- if(20)
- Holiday = "Four-Twenty"
- if(YY == 14 && prob(50)) Holiday = "Easter"
- if(22) Holiday = "Earth Day"
-
- if(5) //May
- switch(DD)
- if(1) Holiday = "Labour Day"
- if(4) Holiday = "FireFighter's Day"
- if(12) Holiday = "Owl and Pussycat Day" //what a dumb day of observence...but we -do- have costumes already :3
-
- if(6) //Jun
-
- if(7) //Jul
- switch(DD)
- if(1) Holiday = "Doctor's Day"
- if(2) Holiday = "UFO Day"
- if(8) Holiday = "Writer's Day"
- if(30) Holiday = "Friendship Day"
-
- if(8) //Aug
- switch(DD)
- if(5) Holiday = "Beer Day"
-
- if(9) //Sep
- switch(DD)
- if(19) Holiday = "Talk-Like-a-Pirate Day"
- if(28) Holiday = "Stupid-Questions Day"
-
- if(10) //Oct
- switch(DD)
- if(4) Holiday = "Animal's Day"
- if(7) Holiday = "Smiling Day"
- if(16) Holiday = "Boss' Day"
- if(31) Holiday = "Halloween"
-
- if(11) //Nov
- switch(DD)
- if(1) Holiday = "Vegan Day"
- if(13) Holiday = "Kindness Day"
- if(19) Holiday = "Flowers Day"
- if(21) Holiday = "Saying-'Hello' Day"
-
- if(12) //Dec
- switch(DD)
- if(10) Holiday = "Human-Rights Day"
- if(14) Holiday = "Monkey Day"
- if(21) if(YY==12) Holiday = "End of the World"
- if(22) Holiday = "Orgasming Day" //lol. These all actually exist
- if(24) Holiday = "Christmas Eve"
- if(25) Holiday = "Christmas"
- if(26) Holiday = "Boxing Day"
- if(31) Holiday = "New Year's Eve"
-
- if(!Holiday)
- //Friday the 13th
- if(DD == 13)
- if(time2text(world.timeofday, "DDD") == "Fri")
- Holiday = "Friday the 13th"
-
-//Allows GA and GM to set the Holiday variable
-/client/proc/Set_Holiday(T as text|null)
- set name = ".Set Holiday"
- set category = "Event"
- set desc = "Force-set the Holiday variable to make the game think it's a certain day."
- if(!check_rights(R_SERVER)) return
-
- Holiday = T
- //get a new station name
- station_name = null
- station_name()
- //update our hub status
- world.update_status()
- Holiday_Game_Start()
-
- message_admins("ADMIN: Event: [key_name_admin(src)] force-set Holiday to \"[Holiday]\"")
- log_admin("[key_name(src)] force-set Holiday to \"[Holiday]\"")
-
-
-//Run at the start of a round
-/proc/Holiday_Game_Start()
- if(Holiday)
- to_chat(world, "and...")
- to_chat(world, "Happy [Holiday] Everybody!")
- switch(Holiday) //special holidays
- if("Easter")
- //do easter stuff
- if("Christmas Eve","Christmas")
- Christmas_Game_Start()
-
- return
-
-//Nested in the random events loop. Will be triggered every 2 minutes
-/proc/Holiday_Random_Event()
- switch(Holiday) //special holidays
-
- if("",null) //no Holiday today! Back to work!
- return
-
- if("Easter") //I'll make this into some helper procs at some point
-/* var/list/turf/simulated/floor/Floorlist = list()
- for(var/turf/simulated/floor/T)
- if(T.contents)
- Floorlist += T
- var/turf/simulated/floor/F = Floorlist[rand(1,Floorlist.len)]
- Floorlist = null
- var/obj/structure/closet/C = locate(/obj/structure/closet) in F
- var/obj/item/reagent_containers/food/snacks/chocolateegg/wrapped/Egg
- if( C ) Egg = new(C)
- else Egg = new(F)
-*/
-/* var/list/obj/containers = list()
- for(var/obj/item/storage/S in world)
- if(!is_station_level(S.z)) continue
- containers += S
-
- message_admins("DEBUG: Event: Egg spawned at [Egg.loc] ([Egg.x],[Egg.y],[Egg.z])")*/
- if("End of the World")
- if(prob(eventchance)) GameOver()
-
- if("Christmas","Christmas Eve")
- if(prob(eventchance)) ChristmasEvent()
diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm
index 021004c6ee9..2c718580d2c 100644
--- a/code/modules/events/ion_storm.dm
+++ b/code/modules/events/ion_storm.dm
@@ -22,7 +22,7 @@
/datum/event/ion_storm/start()
//AI laws
- for(var/mob/living/silicon/ai/M in GLOB.living_mob_list)
+ for(var/mob/living/silicon/ai/M in GLOB.alive_mob_list)
if(M.stat != DEAD && M.see_in_dark != FALSE)
var/message = generate_ion_law(ionMessage)
if(message)
@@ -493,7 +493,7 @@
/proc/generate_static_ion_law()
var/list/players = list()
for(var/mob/living/carbon/human/player in GLOB.player_list)
- if( !player.mind || player.mind.assigned_role == player.mind.special_role || player.client.inactivity > MinutesToTicks(10))
+ if( !player.mind || player.mind.assigned_role == player.mind.special_role || player.client.inactivity > 10 MINUTES)
continue
players += player.real_name
var/random_player = "The Captain"
diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm
index 6aceefcd41a..b8bde0a1a67 100644
--- a/code/modules/events/mass_hallucination.dm
+++ b/code/modules/events/mass_hallucination.dm
@@ -2,7 +2,10 @@
announceWhen = rand(0, 20)
/datum/event/mass_hallucination/start()
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
+ for(var/thing in GLOB.human_list)
+ var/mob/living/carbon/human/H = thing
+ if(H.stat == DEAD)
+ continue
var/armor = H.getarmor(type = "rad")
if((RADIMMUNE in H.dna.species.species_traits) || armor >= 75) // Leave radiation-immune species/rad armored players completely unaffected
continue
diff --git a/code/modules/events/money_hacker.dm b/code/modules/events/money_hacker.dm
index 928b35e84ea..ba50cbbfd8f 100644
--- a/code/modules/events/money_hacker.dm
+++ b/code/modules/events/money_hacker.dm
@@ -23,7 +23,7 @@ GLOBAL_VAR_INIT(account_hack_attempted, 0)
Notifications will be sent as updates occur. "
var/my_department = "[station_name()] firewall subroutines"
- for(var/obj/machinery/message_server/MS in world)
+ for(var/obj/machinery/message_server/MS in GLOB.machines)
if(!MS.active) continue
MS.send_rc_message("Head of Personnel's Desk", my_department, message, "", "", 2)
@@ -38,7 +38,7 @@ GLOBAL_VAR_INIT(account_hack_attempted, 0)
if(!isnull(affected_account) && !affected_account.suspended)
message = "The hack attempt has succeeded."
- var/lost = affected_account.money * (MINIMUM_PERCENTAGE_LOSS + rand(0,VARIABLE_LOSS) / 10);
+ var/lost = affected_account.money * (MINIMUM_PERCENTAGE_LOSS + rand(0,VARIABLE_LOSS) / 10)
affected_account.phantom_charge(lost)
@@ -64,7 +64,7 @@ GLOBAL_VAR_INIT(account_hack_attempted, 0)
var/my_department = "[station_name()] firewall subroutines"
- for(var/obj/machinery/message_server/MS in world)
+ for(var/obj/machinery/message_server/MS in GLOB.machines)
if(!MS.active) continue
MS.send_rc_message("Head of Personnel's Desk", my_department, message, "", "", 2)
diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm
index 35c976fa2f9..748d39f2080 100644
--- a/code/modules/events/prison_break.dm
+++ b/code/modules/events/prison_break.dm
@@ -47,7 +47,7 @@
if(areas && areas.len > 0)
var/my_department = "[station_name()] firewall subroutines"
var/rc_message = "An unknown malicious program has been detected in the [english_list(areaName)] lighting and airlock control systems at [station_time_timestamp()]. Systems will be fully compromised within approximately three minutes. Direct intervention is required immediately. "
- for(var/obj/machinery/message_server/MS in world)
+ for(var/obj/machinery/message_server/MS in GLOB.machines)
MS.send_rc_message("Engineering", my_department, rc_message, "", "", 2)
for(var/mob/living/silicon/ai/A in GLOB.player_list)
to_chat(A, "Malicious program detected in the [english_list(areaName)] lighting and airlock control systems by [my_department].")
diff --git a/code/modules/events/rogue_drones.dm b/code/modules/events/rogue_drones.dm
index e2a7dc739c3..02fa69b7c3e 100644
--- a/code/modules/events/rogue_drones.dm
+++ b/code/modules/events/rogue_drones.dm
@@ -6,7 +6,8 @@
/datum/event/rogue_drone/start()
//spawn them at the same place as carp
var/list/possible_spawns = list()
- for(var/obj/effect/landmark/C in GLOB.landmarks_list)
+ for(var/thing in GLOB.landmarks_list)
+ var/obj/effect/landmark/C = thing
if(C.name == "carpspawn")
possible_spawns.Add(C)
diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm
index 4dfe181bdb5..ab8a405785f 100644
--- a/code/modules/events/sentience.dm
+++ b/code/modules/events/sentience.dm
@@ -8,9 +8,9 @@
var/list/potential = list()
var/sentience_type = SENTIENCE_ORGANIC
- for(var/mob/living/simple_animal/L in GLOB.living_mob_list)
+ for(var/mob/living/simple_animal/L in GLOB.alive_mob_list)
var/turf/T = get_turf(L)
- if (T.z != 1)
+ if (!is_station_level(T.z))
continue
if(!(L in GLOB.player_list) && !L.mind && (L.sentience_type == sentience_type))
potential += L
diff --git a/code/modules/events/slaughterevent.dm b/code/modules/events/slaughterevent.dm
index 999303bf069..91918894cfd 100644
--- a/code/modules/events/slaughterevent.dm
+++ b/code/modules/events/slaughterevent.dm
@@ -16,13 +16,15 @@
var/datum/mind/player_mind = new /datum/mind(key_of_slaughter)
player_mind.active = 1
var/list/spawn_locs = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ for(var/thing in GLOB.landmarks_list)
+ var/obj/effect/landmark/L = thing
if(isturf(L.loc))
switch(L.name)
if("revenantspawn")
spawn_locs += L.loc
if(!spawn_locs) //If we can't find any revenant spawns, try the carp spawns
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ for(var/thing in GLOB.landmarks_list)
+ var/obj/effect/landmark/L = thing
if(isturf(L.loc))
switch(L.name)
if("carpspawn")
@@ -31,7 +33,7 @@
spawn_locs += get_turf(player_mind.current)
if(!spawn_locs) //If we can't find THAT, then just retry
return kill()
- var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(pick(spawn_locs))
+ var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(pick(spawn_locs))
var/mob/living/simple_animal/slaughter/S = new /mob/living/simple_animal/slaughter/(holder)
S.holder = holder
player_mind.transfer_to(S)
diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm
index e09e1efb705..694f8e98c89 100644
--- a/code/modules/events/spider_infestation.dm
+++ b/code/modules/events/spider_infestation.dm
@@ -15,7 +15,7 @@ GLOBAL_VAR_INIT(sent_spiders_to_station, 0)
/datum/event/spider_infestation/start()
var/list/vents = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
+ for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in SSair.atmos_machinery)
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
if(temp_vent.parent.other_atmosmch.len > 50)
vents += temp_vent
diff --git a/code/modules/events/spider_terror.dm b/code/modules/events/spider_terror.dm
index 75b86d20cb0..79acc49fe73 100644
--- a/code/modules/events/spider_terror.dm
+++ b/code/modules/events/spider_terror.dm
@@ -1,3 +1,4 @@
+#define TS_HIGHPOP_TRIGGER 80
/datum/event/spider_terror
announceWhen = 240
@@ -22,23 +23,32 @@
if(temp_vent.parent.other_atmosmch.len > 50)
vents += temp_vent
var/spider_type
- var/infestation_type = pick(1, 2, 3, 4, 5)
+ var/infestation_type
+ if((length(GLOB.clients)) < TS_HIGHPOP_TRIGGER)
+ infestation_type = pick(1, 2, 3, 4)
+ else
+ infestation_type = pick(2, 3, 4, 5)
switch(infestation_type)
if(1)
+ // Weakest, only used during lowpop.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/green
spawncount = 5
if(2)
- spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/white
- spawncount = 2
- if(3)
+ // Fairly weak. Dangerous in single combat but has little staying power. Always gets whittled down.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/prince
spawncount = 1
+ if(3)
+ // Variable. Depends how many they infect.
+ spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/white
+ spawncount = 2
if(4)
- spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen
- spawncount = 1
- if(5)
+ // Pretty strong.
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/princess
spawncount = 2
+ if(5)
+ // Strongest, only used during highpop.
+ spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen
+ spawncount = 1
while(spawncount >= 1 && vents.len)
var/obj/machinery/atmospherics/unary/vent_pump/vent = pick(vents)
@@ -60,3 +70,6 @@
new spider_type(vent.loc)
spawncount--
+
+#undef TS_HIGHPOP_TRIGGER
+
diff --git a/code/modules/events/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm
index fb9c146d7cd..53923f4d124 100644
--- a/code/modules/events/spontaneous_appendicitis.dm
+++ b/code/modules/events/spontaneous_appendicitis.dm
@@ -1,5 +1,5 @@
/datum/event/spontaneous_appendicitis/start()
- for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
+ for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
if(issmall(H)) //don't infect monkies; that's a waste.
continue
if(!H.client)
diff --git a/code/modules/events/traders.dm b/code/modules/events/traders.dm
index 4159885e993..0beeb3691e2 100644
--- a/code/modules/events/traders.dm
+++ b/code/modules/events/traders.dm
@@ -24,7 +24,8 @@ GLOBAL_LIST_INIT(unused_trade_stations, list("sol"))
return
var/list/spawnlocs = list()
- for(var/obj/effect/landmark/landmark in GLOB.landmarks_list)
+ for(var/thing in GLOB.landmarks_list)
+ var/obj/effect/landmark/landmark = thing
if(landmark.name == "traderstart_[station]")
spawnlocs += get_turf(landmark)
if(!spawnlocs.len)
diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm
index d4c06fdc3a3..a24b73ae56c 100644
--- a/code/modules/flufftext/Dreaming.dm
+++ b/code/modules/flufftext/Dreaming.dm
@@ -19,7 +19,7 @@
var/list/newlist = dreamlist.Copy()
for(var/i in 1 to newlist.len)
newlist[i] = replacetext(newlist[i], "\[DREAMER\]", "[user.name]")
- return dreamlist
+ return newlist
//NIGHTMARES
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 32e209f98f6..905b629a0b9 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -460,8 +460,9 @@ Gunshots/explosions/opening doors/less rare audio (done)
target = T
var/image/A = null
var/kind = force_kind ? force_kind : pick("clown", "corgi", "carp", "skeleton", "demon","zombie")
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- if(H == target)
+ for(var/thing in GLOB.human_list)
+ var/mob/living/carbon/human/H = thing
+ if(H.stat == DEAD || H == target)
continue
if(skip_nearby && (H in view(target)))
continue
@@ -539,7 +540,8 @@ Gunshots/explosions/opening doors/less rare audio (done)
var/mob/living/carbon/human/clone = null
var/clone_weapon = null
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
+ for(var/thing in GLOB.human_list)
+ var/mob/living/carbon/human/H = thing
if(H.stat || H.lying)
continue
clone = H
@@ -751,8 +753,10 @@ GLOBAL_LIST_INIT(non_fakeattack_weapons, list(/obj/item/gun/projectile, /obj/ite
target.client.images.Remove(speech_overlay)
else // Radio talk
var/list/humans = list()
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- humans += H
+ for(var/thing in GLOB.human_list)
+ var/mob/living/carbon/human/H = thing
+ if(H.stat != DEAD)
+ humans += H
person = pick(humans)
target.hear_radio(message_to_multilingual(pick(radio_messages), pick(person.languages)), speaker = person, part_a = "\[[get_frequency_name(PUB_FREQ)]\] ", part_b = " ")
qdel(src)
diff --git a/code/modules/food_and_drinks/drinks/bottler/bottler.dm b/code/modules/food_and_drinks/drinks/bottler/bottler.dm
index b1667fc6a00..d7f1736bb4a 100644
--- a/code/modules/food_and_drinks/drinks/bottler/bottler.dm
+++ b/code/modules/food_and_drinks/drinks/bottler/bottler.dm
@@ -82,7 +82,6 @@
else //If it doesn't qualify in the above checks, we don't want it. Inform the person so they (ideally) stop trying to put the nuke disc in.
to_chat(user, "You aren't sure this is able to be processed by the machine.")
return 0
- return ..()
/obj/machinery/bottler/wrench_act(mob/user, obj/item/I)
. = TRUE
diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
index 90929175eba..f77d4b60ab4 100644
--- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
@@ -72,8 +72,8 @@
if(istype(H.head, /obj/item/clothing/head) && affecting == "head")
// If their head has an armor value, assign headarmor to it, else give it 0.
- if(H.head.armor["melee"])
- headarmor = H.head.armor["melee"]
+ if(H.head.armor.getRating("melee"))
+ headarmor = H.head.armor.getRating("melee")
else
headarmor = 0
else
@@ -115,7 +115,7 @@
//The reagents in the bottle splash all over the target, thanks for the idea Nodrak
SplashReagents(target)
- //Finally, smash the bottle. This kills (del) the bottle.
+ //Finally, smash the bottle. This kills (qdel) the bottle.
smash(target, user)
/obj/item/reagent_containers/food/drinks/bottle/proc/SplashReagents(mob/M)
@@ -124,6 +124,13 @@
reagents.reaction(M, REAGENT_TOUCH)
reagents.clear_reagents()
+/obj/item/reagent_containers/food/drinks/bottle/decompile_act(obj/item/matter_decompiler/C, mob/user)
+ if(!reagents.total_volume)
+ C.stored_comms["glass"] += 3
+ qdel(src)
+ return TRUE
+ return ..()
+
//Keeping this here for now, I'll ask if I should keep it here.
/obj/item/broken_bottle
name = "Broken Bottle"
@@ -141,6 +148,11 @@
var/icon/broken_outline = icon('icons/obj/drinks.dmi', "broken")
sharp = 1
+/obj/item/broken_bottle/decompile_act(obj/item/matter_decompiler/C, mob/user)
+ C.stored_comms["glass"] += 3
+ qdel(src)
+ return TRUE
+
/obj/item/reagent_containers/food/drinks/bottle/gin
name = "Griffeater Gin"
desc = "A bottle of high quality gin, produced in the New London Space Station."
diff --git a/code/modules/food_and_drinks/food/foods/bread.dm b/code/modules/food_and_drinks/food/foods/bread.dm
index d888a532c01..55255658233 100644
--- a/code/modules/food_and_drinks/food/foods/bread.dm
+++ b/code/modules/food_and_drinks/food/foods/bread.dm
@@ -166,6 +166,15 @@
list_reagents = list("nutriment" = 2, "vitamin" = 2)
tastes = list("bread" = 2)
+/obj/item/reagent_containers/food/snacks/toast
+ name = "Toast"
+ desc = "Yeah! Toast!"
+ icon_state = "toast"
+ filling_color = "#B2580E"
+ bitesize = 3
+ list_reagents = list("nutriment" = 3)
+ tastes = list("toast" = 2)
+
/obj/item/reagent_containers/food/snacks/jelliedtoast
name = "Jellied Toast"
desc = "A slice of bread covered with delicious jam."
@@ -198,3 +207,5 @@
trash = /obj/item/trash/waffles
filling_color = "#E6DEB5"
list_reagents = list("nutriment" = 8, "vitamin" = 1)
+
+
diff --git a/code/modules/food_and_drinks/food/foods/desserts.dm b/code/modules/food_and_drinks/food/foods/desserts.dm
index 9e8ded0bd1b..67034e164ce 100644
--- a/code/modules/food_and_drinks/food/foods/desserts.dm
+++ b/code/modules/food_and_drinks/food/foods/desserts.dm
@@ -17,10 +17,10 @@
update_icon()
/obj/item/reagent_containers/food/snacks/icecream/update_icon()
- overlays.Cut()
- var/image/filling = image('icons/obj/kitchen.dmi', src, "icecream_color")
- filling.icon += mix_color_from_reagents(reagents.reagent_list)
- overlays += filling
+ cut_overlays()
+ var/mutable_appearance/filling = mutable_appearance('icons/obj/kitchen.dmi', "icecream_color")
+ filling.color = mix_color_from_reagents(reagents.reagent_list)
+ add_overlay(filling)
/obj/item/reagent_containers/food/snacks/icecream/icecreamcone
name = "ice cream cone"
diff --git a/code/modules/food_and_drinks/food/foods/seafood.dm b/code/modules/food_and_drinks/food/foods/seafood.dm
index b74ab0c3149..d4134ebe516 100644
--- a/code/modules/food_and_drinks/food/foods/seafood.dm
+++ b/code/modules/food_and_drinks/food/foods/seafood.dm
@@ -129,7 +129,7 @@
tastes = list("shrimp" = 1, "batter" = 1)
/obj/item/reagent_containers/food/snacks/sliceable/Ebi_maki
- name = "ebi makiroll"
+ name = "ebi maki roll"
desc = "A large unsliced roll of Ebi Sushi."
icon = 'icons/obj/food/seafood.dmi'
icon_state = "Ebi_maki"
@@ -149,7 +149,7 @@
tastes = list("shrimp" = 1, "rice" = 1, "seaweed" = 1)
/obj/item/reagent_containers/food/snacks/sliceable/Ikura_maki
- name = "ikura makiroll"
+ name = "ikura maki roll"
desc = "A large unsliced roll of Ikura Sushi."
icon = 'icons/obj/food/seafood.dmi'
icon_state = "Ikura_maki"
@@ -169,7 +169,7 @@
tastes = list("salmon roe" = 1, "rice" = 1, "seaweed" = 1)
/obj/item/reagent_containers/food/snacks/sliceable/Sake_maki
- name = "sake makiroll"
+ name = "sake maki roll"
desc = "A large unsliced roll of Sake Sushi."
icon = 'icons/obj/food/seafood.dmi'
icon_state = "Sake_maki"
@@ -189,7 +189,7 @@
tastes = list("raw salmon" = 1, "rice" = 1, "seaweed" = 1)
/obj/item/reagent_containers/food/snacks/sliceable/SmokedSalmon_maki
- name = "smoked salmon makiroll"
+ name = "smoked salmon maki roll"
desc = "A large unsliced roll of Smoked Salmon Sushi."
icon = 'icons/obj/food/seafood.dmi'
icon_state = "SmokedSalmon_maki"
@@ -209,7 +209,7 @@
tastes = list("smoked salmon" = 1, "rice" = 1, "seaweed" = 1)
/obj/item/reagent_containers/food/snacks/sliceable/Tamago_maki
- name = "tamago makiroll"
+ name = "tamago maki roll"
desc = "A large unsliced roll of Tamago Sushi."
icon = 'icons/obj/food/seafood.dmi'
icon_state = "Tamago_maki"
@@ -229,7 +229,7 @@
tastes = list("egg" = 1, "rice" = 1, "seaweed" = 1)
/obj/item/reagent_containers/food/snacks/sliceable/Inari_maki
- name = "inari makiroll"
+ name = "inari maki roll"
desc = "A large unsliced roll of Inari Sushi."
icon = 'icons/obj/food/seafood.dmi'
icon_state = "Inari_maki"
@@ -249,7 +249,7 @@
tastes = list("fried tofu" = 1, "rice" = 1, "seaweed" = 1)
/obj/item/reagent_containers/food/snacks/sliceable/Masago_maki
- name = "masago makiroll"
+ name = "masago maki roll"
desc = "A large unsliced roll of Masago Sushi."
icon = 'icons/obj/food/seafood.dmi'
icon_state = "Masago_maki"
@@ -269,7 +269,7 @@
tastes = list("goldfish roe" = 1, "rice" = 1, "seaweed" = 1)
/obj/item/reagent_containers/food/snacks/sliceable/Tobiko_maki
- name = "tobiko makiroll"
+ name = "tobiko maki roll"
desc = "A large unsliced roll of Tobkio Sushi."
icon = 'icons/obj/food/seafood.dmi'
icon_state = "Tobiko_maki"
@@ -289,7 +289,7 @@
tastes = list("shark roe" = 1, "rice" = 1, "seaweed" = 1)
/obj/item/reagent_containers/food/snacks/sliceable/TobikoEgg_maki
- name = "tobiko and egg makiroll"
+ name = "tobiko and egg maki roll"
desc = "A large unsliced roll of Tobkio and Egg Sushi."
icon = 'icons/obj/food/seafood.dmi'
icon_state = "TobikoEgg_maki"
@@ -309,7 +309,7 @@
tastes = list("shark roe" = 1, "rice" = 1, "egg" = 1, "seaweed" = 1)
/obj/item/reagent_containers/food/snacks/sliceable/Tai_maki
- name = "tai makiroll"
+ name = "tai maki roll"
desc = "A large unsliced roll of Tai Sushi."
icon = 'icons/obj/food/seafood.dmi'
icon_state = "Tai_maki"
diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
index 7d17ac07720..db078675db1 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
@@ -278,11 +278,6 @@
if(!UserOverride)
add_attack_logs(user, occupant, "Gibbed in [src]", !!occupant.ckey ? ATKLOG_FEW : ATKLOG_ALL)
- if(!iscarbon(user))
- occupant.LAssailant = null
- else
- occupant.LAssailant = user
-
else //this looks ugly but it's better than a copy-pasted startgibbing proc override
occupant.create_attack_log("Was gibbed by an autogibber (\the [src])")
add_attack_logs(src, occupant, "gibbed")
diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
index 69eda1e4269..0e9ecbaa7e4 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
@@ -43,10 +43,9 @@
return
if(istype(I, /obj/item/reagent_containers/food/snacks/icecream))
if(!I.reagents.has_reagent("sprinkles"))
- if(I.reagents.total_volume > 29) I.reagents.remove_any(1)
- I.reagents.add_reagent("sprinkles",1)
- var/image/sprinkles = image('icons/obj/kitchen.dmi', src, "sprinkles")
- I.overlays += sprinkles
+ if(I.reagents.total_volume > 29)
+ I.reagents.remove_any(1)
+ I.reagents.add_reagent("sprinkles", 1)
I.name += " with sprinkles"
I.desc += ". This also has sprinkles."
else
diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat_2.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat_2.dm
deleted file mode 100644
index c1602a14251..00000000000
--- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat_2.dm
+++ /dev/null
@@ -1,256 +0,0 @@
-#define ICECREAM_VANILLA 1
-#define FLAVOUR_CHOCOLATE 2
-#define FLAVOUR_STRAWBERRY 3
-#define FLAVOUR_BLUE 4
-#define CONE_WAFFLE 5
-#define CONE_CHOC 6
-#define INGR_MILK 7
-#define INGR_FLOUR 8
-#define INGR_SUGAR 9
-#define INGR_ICE 10
-#define MUCK 11
-
-GLOBAL_LIST_INIT(ingredients_source, list(
-"berryjuice" = FLAVOUR_STRAWBERRY,\
-"cocoa" = FLAVOUR_CHOCOLATE,\
-"singulo" = FLAVOUR_BLUE,\
-"milk" = INGR_MILK,\
-"soymilk" = INGR_MILK,\
-"ice" = INGR_ICE,\
-"flour" = INGR_FLOUR,\
-"sugar" = INGR_SUGAR,\
-))
-
-/proc/get_icecream_flavour_string(var/flavour_type)
- switch(flavour_type)
- if(FLAVOUR_CHOCOLATE)
- return "chocolate"
- if(FLAVOUR_STRAWBERRY)
- return "strawberry"
- if(FLAVOUR_BLUE)
- return "blue"
- if(CONE_WAFFLE)
- return "waffle"
- if(CONE_CHOC)
- return "chocolate"
- if(INGR_MILK)
- return "milk"
- if(INGR_FLOUR)
- return "flour"
- if(INGR_SUGAR)
- return "sugar"
- if(INGR_ICE)
- return "ice"
- if(MUCK)
- return "muck"
- else
- return "vanilla"
-
-/obj/machinery/icecream_vat
- name = "icecream vat"
- desc = "Ding-aling ding dong. Get your Nanotrasen-approved ice cream!"
- icon = 'icons/obj/kitchen.dmi'
- icon_state = "icecream_vat"
- density = 1
- anchored = 0
- max_integrity = 300
- var/list/ingredients = list()
- var/dispense_flavour = 1
- var/obj/item/reagent_containers/glass/held_container
-
-/obj/machinery/icecream_vat/New()
- ..()
- create_reagents(50)
- while(ingredients.len < 11)
- ingredients.Add(5)
-
-/obj/machinery/icecream_vat/attack_hand(mob/user)
- user.set_machine(src)
- interact(user)
-
-/obj/machinery/icecream_vat/interact(mob/user)
- var/dat
- dat += "Dispense vanilla icecream There is [ingredients[ICECREAM_VANILLA]] scoops of vanilla icecream left (made from milk and ice). "
- dat += "Dispense strawberry icecream There is [ingredients[FLAVOUR_STRAWBERRY]] dollops of strawberry flavouring left (obtained from berry juice. "
- dat += "Dispense chocolate icecream There is [ingredients[FLAVOUR_CHOCOLATE]] dollops of chocolate flavouring left (obtained from cocoa powder). "
- dat += "Dispense blue icecream There is [ingredients[FLAVOUR_BLUE]] dollops of blue flavouring left (obtained from bluespace tomato singulo). "
- dat += " "
- dat += "Dispense waffle cones There are [ingredients[CONE_WAFFLE]] waffle cones left. "
- dat += "Dispense chocolate cones There are [ingredients[CONE_CHOC]] chocolate cones left. "
- dat += " "
- dat += "Make waffle cones There is [ingredients[INGR_FLOUR]]/[ingredients[INGR_SUGAR]] of flour and sugar left. "
- dat += "Make chocolate cones There is [ingredients[FLAVOUR_CHOCOLATE]]/[ingredients[CONE_WAFFLE]] of chocolate flavouring and waffle cones left. "
- dat += "Make vanilla icecream There is [ingredients[INGR_MILK]]/[ingredients[INGR_ICE]] of milk and ice left. "
- dat += " "
- if(held_container)
- dat += "Eject [held_container] "
- else
- dat += "No beaker inserted. "
- dat += "Refresh Close"
-
- var/datum/browser/popup = new(user, "icecreamvat", name, 600, 400)
- popup.set_content(dat)
- popup.open(0)
-
-/obj/machinery/icecream_vat/attackby(obj/item/O, mob/user, params)
- if(istype(O, /obj/item/reagent_containers))
- if(istype(O, /obj/item/reagent_containers/food/snacks/icecream))
- var/obj/item/reagent_containers/food/snacks/icecream/I = O
- if(!I.ice_creamed)
- if(ingredients[ICECREAM_VANILLA] > 0)
- var/flavour_name = get_icecream_flavour_string(dispense_flavour)
- if(dispense_flavour < 11 && ingredients[dispense_flavour] > 0)
- visible_message("[bicon(src)] [user] scoops delicious [flavour_name] flavoured icecream into [I].")
- ingredients[dispense_flavour] -= 1
- ingredients[ICECREAM_VANILLA] -= 1
-
- I.add_ice_cream(dispense_flavour)
- if(held_container)
- held_container.reagents.trans_to(I, 10)
- if(I.reagents.total_volume < 10)
- I.reagents.add_reagent("sugar", 10 - I.reagents.total_volume)
- else
- to_chat(user, "There is not enough [flavour_name] flavouring left! Insert more of the required ingredients.")
- else
- to_chat(user, "There is not enough icecream left! Insert more milk and ice.")
- else
- to_chat(user, "[O] already has icecream in it.")
- else if(istype(O, /obj/item/reagent_containers/glass))
- if(held_container)
- to_chat(user, "You must remove [held_container] from [src] first.")
- else
- if(!user.drop_item())
- to_chat(user, "\The [O] is stuck to your hand!")
- return
- O.forceMove(src)
- to_chat(user, "You insert [O] into [src].")
- held_container = O
- else
- var/obj/item/reagent_containers/R = O
- if(R.reagents)
- visible_message("[user] has emptied all of [R] into [src].")
- for(var/datum/reagent/current_reagent in R.reagents.reagent_list)
- if(GLOB.ingredients_source[current_reagent.id])
- add(GLOB.ingredients_source[current_reagent.id], current_reagent.volume / 2)
- else
- add(MUCK, current_reagent.volume / 5)
- R.reagents.clear_reagents()
- return 1
- else
- return ..()
-
-/obj/machinery/icecream_vat/proc/add(var/add_type, var/amount)
- if(add_type <= ingredients.len)
- ingredients[add_type] += amount
- updateDialog()
-
-/obj/machinery/icecream_vat/proc/make(var/mob/user, var/make_type)
- switch(make_type)
- if(CONE_WAFFLE)
- if(ingredients[INGR_FLOUR] > 0 && ingredients[INGR_SUGAR] > 0)
- var/amount = max( min(ingredients[INGR_FLOUR], ingredients[INGR_SUGAR]), 5)
- ingredients[INGR_FLOUR] -= amount
- ingredients[INGR_SUGAR] -= amount
- ingredients[CONE_WAFFLE] += amount
- visible_message("[user] cooks up some waffle cones.")
- else
- to_chat(user, "You require sugar and flour to make waffle cones.")
- if(CONE_CHOC)
- if(ingredients[FLAVOUR_CHOCOLATE] > 0 && ingredients[CONE_WAFFLE] > 0)
- var/amount = min(ingredients[CONE_WAFFLE], ingredients[FLAVOUR_CHOCOLATE])
- ingredients[CONE_WAFFLE] -= amount
- ingredients[FLAVOUR_CHOCOLATE] -= amount
- ingredients[CONE_CHOC] += amount
- visible_message("[user] cooks up some chocolate cones.")
- else
- to_chat(user, "You require waffle cones and chocolate flavouring to make chocolate cones.")
- if(ICECREAM_VANILLA)
- if(ingredients[INGR_ICE] > 0 && ingredients[INGR_MILK] > 0)
- var/amount = min(ingredients[INGR_ICE], ingredients[INGR_MILK])
- ingredients[INGR_ICE] -= amount
- ingredients[INGR_MILK] -= amount
- ingredients[ICECREAM_VANILLA] += amount
- visible_message("[user] whips up some vanilla icecream.")
- else
- to_chat(user, "You require milk and ice to make vanilla icecream.")
- updateDialog()
-
-/obj/machinery/icecream_vat/Topic(href, href_list)
- if(..())
- return
- if(href_list["dispense"])
- dispense_flavour = text2num(href_list["dispense"])
- visible_message("[usr] sets [src] to dispense [get_icecream_flavour_string(dispense_flavour)] flavoured icecream.")
-
- if(href_list["cone"])
- var/dispense_cone = text2num(href_list["cone"])
- if(ingredients[dispense_cone] <= ingredients.len)
- var/cone_name = get_icecream_flavour_string(dispense_cone)
- if(ingredients[dispense_cone] >= 1)
- ingredients[dispense_cone] -= 1
- var/obj/item/reagent_containers/food/snacks/icecream/I = new(loc)
- I.cone_type = cone_name
- I.icon_state = "icecream_cone_[cone_name]"
- I.desc = "Delicious [cone_name] cone, but no ice cream."
- visible_message("[usr] dispenses a crunchy [cone_name] cone from [src].")
- else
- to_chat(usr, "There are no [cone_name] cones left!")
- updateDialog()
-
- if(href_list["make"])
- make( usr, text2num(href_list["make"]) )
- updateDialog()
-
- if(href_list["eject"])
- if(held_container)
- held_container.forceMove(loc)
- held_container = null
- updateDialog()
-
- if(href_list["refresh"])
- updateDialog()
-
- if(href_list["close"])
- usr.unset_machine()
- usr << browse(null,"window=icecreamvat")
- return
-
-/obj/machinery/icecream_vat/deconstruct(disassembled = TRUE)
- if(!(flags & NODECONSTRUCT))
- new /obj/item/stack/sheet/metal(loc, 4)
- qdel(src)
-
-
-/obj/item/reagent_containers/food/snacks/icecream
- name = "ice cream cone"
- desc = "Delicious waffle cone, but no ice cream."
- icon = 'icons/obj/kitchen.dmi'
- icon_state = "icecream_cone"
- layer = 3.1
- var/ice_creamed = 0
- var/cone_type
- bitesize = 3
-
-/obj/item/reagent_containers/food/snacks/icecream/New()
- ..()
- create_reagents(20)
- reagents.add_reagent("nutriment", 5)
-
-/obj/item/reagent_containers/food/snacks/icecream/proc/add_ice_cream(var/flavour)
- var/flavour_name = get_icecream_flavour_string(flavour)
- name = "[flavour_name] icecream"
- overlays += "icecream_[flavour_name]"
- desc = "Delicious [cone_type] cone with a dollop of [flavour_name] ice cream."
- ice_creamed = 1
-
-#undef ICECREAM_VANILLA
-#undef FLAVOUR_CHOCOLATE
-#undef FLAVOUR_STRAWBERRY
-#undef FLAVOUR_BLUE
-#undef CONE_WAFFLE
-#undef CONE_CHOC
-#undef INGR_MILK
-#undef INGR_FLOUR
-#undef INGR_SUGAR
-#undef INGR_ICE
-#undef MUCK
diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
index 61f887e44bc..6891ab578bc 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
@@ -175,7 +175,7 @@
if(default_unfasten_wrench(user, O))
return
- default_deconstruction_crowbar(user, O)
+ default_deconstruction_crowbar(user, O)
var/obj/item/what = O
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index 756d2cf77ef..346b78e5b26 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -602,7 +602,7 @@
if(stat & (NOPOWER|BROKEN))
return 0
if(usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf)))
- if(!allowed(usr) && !emagged && locked != -1 && href_list["vend"])
+ if(!allowed(usr) && !emagged && locked != -1 && scan_id && href_list["vend"])
to_chat(usr, "Access denied.")
SSnanoui.update_uis(src)
return 0
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm
index db7774fa41f..1aa33cab232 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm
@@ -90,7 +90,7 @@
subcategory = CAT_SUSHI
/datum/crafting_recipe/Ebi_maki
- name = "Ebi Makiroll"
+ name = "Ebi Maki Roll"
reqs = list(
/obj/item/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/reagent_containers/food/snacks/boiled_shrimp = 4,
@@ -111,7 +111,7 @@
subcategory = CAT_SUSHI
/datum/crafting_recipe/Ikura_maki
- name = "Ikura Makiroll"
+ name = "Ikura Maki Roll"
reqs = list(
/obj/item/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/fish_eggs/salmon = 4,
@@ -132,7 +132,7 @@
subcategory = CAT_SUSHI
/datum/crafting_recipe/Inari_maki
- name = "Inari Makiroll"
+ name = "Inari Maki Roll"
reqs = list(
/obj/item/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/reagent_containers/food/snacks/fried_tofu = 4,
@@ -153,7 +153,7 @@
subcategory = CAT_SUSHI
/datum/crafting_recipe/Sake_maki
- name = "Sake Makiroll"
+ name = "Sake Maki Roll"
reqs = list(
/obj/item/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/reagent_containers/food/snacks/salmonmeat = 4,
@@ -174,7 +174,7 @@
subcategory = CAT_SUSHI
/datum/crafting_recipe/SmokedSalmon_maki
- name = "Smoked Salmon Makiroll"
+ name = "Smoked Salmon Maki Roll"
reqs = list(
/obj/item/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/reagent_containers/food/snacks/salmonsteak = 4,
@@ -195,7 +195,7 @@
subcategory = CAT_SUSHI
/datum/crafting_recipe/Masago_maki
- name = "Masago Makiroll"
+ name = "Masago Maki Roll"
reqs = list(
/obj/item/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/fish_eggs/goldfish = 4,
@@ -216,7 +216,7 @@
subcategory = CAT_SUSHI
/datum/crafting_recipe/Tobiko_maki
- name = "Tobiko Makiroll"
+ name = "Tobiko Maki Roll"
reqs = list(
/obj/item/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/fish_eggs/shark = 4,
@@ -237,18 +237,7 @@
subcategory = CAT_SUSHI
/datum/crafting_recipe/TobikoEgg_maki
- name = "Tobiko Makiroll"
- reqs = list(
- /obj/item/reagent_containers/food/snacks/sushi_Tobiko = 4,
- /obj/item/reagent_containers/food/snacks/egg = 4,
- )
- pathtools = list(/obj/item/kitchen/sushimat)
- result = /obj/item/reagent_containers/food/snacks/sliceable/TobikoEgg_maki
- category = CAT_FOOD
- subcategory = CAT_SUSHI
-
-/datum/crafting_recipe/Sake_maki
- name = "Sake Makiroll"
+ name = "Tobiko and Egg Maki Roll"
reqs = list(
/obj/item/reagent_containers/food/snacks/sushi_Tobiko = 4,
/obj/item/reagent_containers/food/snacks/egg = 4,
@@ -269,7 +258,7 @@
subcategory = CAT_SUSHI
/datum/crafting_recipe/Tai_maki
- name = "Tai Makiroll"
+ name = "Tai Maki Roll"
reqs = list(
/obj/item/reagent_containers/food/snacks/boiledrice = 1,
/obj/item/reagent_containers/food/snacks/catfishmeat = 4,
diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm
index 7be44052729..9a7c8cca075 100644
--- a/code/modules/games/cards.dm
+++ b/code/modules/games/cards.dm
@@ -438,7 +438,7 @@
overlays += I
return
- var/offset = Floor(20/cards.len + 1)
+ var/offset = FLOOR(20/cards.len + 1, 1)
var/matrix/M = matrix()
if(direction)
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index c1b5e471315..bb25025cb7f 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -327,7 +327,7 @@
else if(href_list["create"])
var/amount = (text2num(href_list["amount"]))
//Can't be outside these (if you change this keep a sane limit)
- amount = Clamp(amount, 1, 10)
+ amount = clamp(amount, 1, 10)
var/datum/design/D = locate(href_list["create"])
create_product(D, amount)
updateUsrDialog()
diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm
index d39a0168f14..7ce64f40b20 100644
--- a/code/modules/hydroponics/gene_modder.dm
+++ b/code/modules/hydroponics/gene_modder.dm
@@ -71,7 +71,7 @@
for(var/obj/item/stock_parts/micro_laser/ML in component_parts)
var/wratemod = ML.rating * 2.5
- min_wrate = Floor(10-wratemod) // 7,5,2,0 Clamps at 0 and 10 You want this low
+ min_wrate = FLOOR(10-wratemod, 1) // 7,5,2,0 Clamps at 0 and 10 You want this low
min_wchance = 67-(ML.rating*16) // 48,35,19,3 Clamps at 0 and 67 You want this low
for(var/obj/item/circuitboard/plantgenes/vaultcheck in component_parts)
if(istype(vaultcheck, /obj/item/circuitboard/plantgenes/vault)) // TRAIT_DUMB BOTANY TUTS
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index d86f6f8f4c5..5ad8a5f32f4 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -40,7 +40,7 @@
for(var/datum/plant_gene/trait/T in seed.genes)
T.on_new(src, newloc)
seed.prepare_result(src)
- transform *= TransformUsingVariable(seed.potency, 100, 0.5) //Makes the resulting produce's sprite larger or smaller based on potency!
+ transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 //Makes the resulting produce's sprite larger or smaller based on potency!
add_juice()
/obj/item/reagent_containers/food/snacks/grown/Destroy()
@@ -154,17 +154,11 @@
T.on_consume(src, usr)
..()
-/obj/item/reagent_containers/food/snacks/grown/Crossed(atom/movable/AM, oldloc)
- if(seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_cross(src, AM)
- ..()
-
-/obj/item/reagent_containers/food/snacks/grown/on_trip(mob/living/carbon/human/H)
- . = ..()
- if(. && seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_slip(src, H)
+/obj/item/reagent_containers/food/snacks/grown/after_slip(mob/living/carbon/human/H)
+ if(!seed)
+ return
+ for(var/datum/plant_gene/trait/T in seed.genes)
+ T.on_slip(src, H)
// Glow gene procs
/obj/item/reagent_containers/food/snacks/grown/generate_trash(atom/location)
@@ -174,6 +168,11 @@
return
return ..()
+/obj/item/reagent_containers/food/snacks/grown/decompile_act(obj/item/matter_decompiler/C, mob/user)
+ C.stored_comms["wood"] += 4
+ qdel(src)
+ return TRUE
+
// For item-containing growns such as eggy or gatfruit
/obj/item/reagent_containers/food/snacks/grown/shell/attack_self(mob/user)
user.unEquip(src)
@@ -190,3 +189,4 @@
D.consume(src)
else
return ..()
+
diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm
index dc78ff71335..0552f78ee92 100644
--- a/code/modules/hydroponics/grown/banana.dm
+++ b/code/modules/hydroponics/grown/banana.dm
@@ -118,12 +118,10 @@
/obj/item/grown/bananapeel/specialpeel //used by /obj/item/clothing/shoes/clown_shoes/banana_shoes
name = "synthesized banana peel"
desc = "A synthetic banana peel."
- trip_stun = 2
- trip_weaken = 2
- trip_chance = 100
- trip_walksafe = FALSE
- trip_verb = TV_SLIP
-/obj/item/grown/bananapeel/specialpeel/on_trip(mob/living/carbon/human/H)
- if(..())
- qdel(src)
+/obj/item/grown/bananapeel/specialpeel/ComponentInitialize()
+ AddComponent(/datum/component/slippery, src, 2, 2, 100, 0, FALSE)
+
+/obj/item/grown/bananapeel/specialpeel/after_slip(mob/living/carbon/human/H)
+ . = ..()
+ qdel(src)
diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm
index 14a4b42ca5f..f10b286469a 100644
--- a/code/modules/hydroponics/growninedible.dm
+++ b/code/modules/hydroponics/growninedible.dm
@@ -28,7 +28,7 @@
if(istype(src, seed.product)) // no adding reagents if it is just a trash item
seed.prepare_result(src)
- transform *= TransformUsingVariable(seed.potency, 100, 0.5)
+ transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5
add_juice()
/obj/item/grown/Destroy()
@@ -50,18 +50,11 @@
return 1
return 0
-
-/obj/item/grown/Crossed(atom/movable/AM, oldloc)
- if(seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_cross(src, AM)
- ..()
-
-/obj/item/grown/on_trip(mob/living/carbon/human/H)
- . = ..()
- if(. && seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_slip(src, H)
+/obj/item/grown/after_slip(mob/living/carbon/human/H)
+ if(!seed)
+ return
+ for(var/datum/plant_gene/trait/T in seed.genes)
+ T.on_slip(src, H)
/obj/item/grown/throw_impact(atom/hit_atom)
if(!..()) //was it caught by a mob?
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index 0f41ba4b602..1be8f11527d 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -888,7 +888,7 @@
/obj/machinery/hydroponics/wrench_act(mob/user, obj/item/I)
. = TRUE
- if(!I.tool_start_check(user, 0))
+ if(!I.tool_start_check(src, user, 0))
return
if(wrenchable)
if(using_irrigation)
@@ -949,36 +949,36 @@
/// Tray Setters - The following procs adjust the tray or plants variables, and make sure that the stat doesn't go out of bounds.///
/obj/machinery/hydroponics/proc/adjustNutri(adjustamt)
- nutrilevel = Clamp(nutrilevel + adjustamt, 0, maxnutri)
+ nutrilevel = clamp(nutrilevel + adjustamt, 0, maxnutri)
plant_hud_set_nutrient()
/obj/machinery/hydroponics/proc/adjustWater(adjustamt)
- waterlevel = Clamp(waterlevel + adjustamt, 0, maxwater)
+ waterlevel = clamp(waterlevel + adjustamt, 0, maxwater)
plant_hud_set_water()
if(adjustamt>0)
adjustToxic(-round(adjustamt/4))//Toxicity dilutation code. The more water you put in, the lesser the toxin concentration.
/obj/machinery/hydroponics/proc/adjustHealth(adjustamt)
if(myseed && !dead)
- plant_health = Clamp(plant_health + adjustamt, 0, myseed.endurance)
+ plant_health = clamp(plant_health + adjustamt, 0, myseed.endurance)
plant_hud_set_health()
/obj/machinery/hydroponics/proc/adjustToxic(adjustamt)
- toxic = Clamp(toxic + adjustamt, 0, 100)
+ toxic = clamp(toxic + adjustamt, 0, 100)
plant_hud_set_toxin()
/obj/machinery/hydroponics/proc/adjustPests(adjustamt)
- pestlevel = Clamp(pestlevel + adjustamt, 0, 10)
+ pestlevel = clamp(pestlevel + adjustamt, 0, 10)
plant_hud_set_pest()
/obj/machinery/hydroponics/proc/adjustWeeds(adjustamt)
- weedlevel = Clamp(weedlevel + adjustamt, 0, 10)
+ weedlevel = clamp(weedlevel + adjustamt, 0, 10)
plant_hud_set_weed()
/obj/machinery/hydroponics/proc/spawnplant() // why would you put strange reagent in a hydro tray you monster I bet you also feed them blood
var/list/livingplants = list(/mob/living/simple_animal/hostile/tree, /mob/living/simple_animal/hostile/killertomato)
var/chosen = pick(livingplants)
- var/mob/living/simple_animal/hostile/C = new chosen
+ var/mob/living/simple_animal/hostile/C = new chosen(get_turf(src))
C.faction = list("plants")
/obj/machinery/hydroponics/proc/become_self_sufficient() // Ambrosia Gaia effect
diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm
index d20413d6331..a4c6fe7280d 100644
--- a/code/modules/hydroponics/plant_genes.dm
+++ b/code/modules/hydroponics/plant_genes.dm
@@ -175,9 +175,6 @@
/datum/plant_gene/trait/proc/on_consume(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/target)
return
-/datum/plant_gene/trait/proc/on_cross(obj/item/reagent_containers/food/snacks/grown/G, atom/target)
- return
-
/datum/plant_gene/trait/proc/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/target)
return
@@ -217,11 +214,7 @@
stun_len = min(stun_len, 7) // No fun allowed
- G.trip_stun = stun_len
- G.trip_weaken = stun_len
- G.trip_chance = 100
- G.trip_verb = TV_SLIP
- G.trip_walksafe = FALSE
+ G.AddComponent(/datum/component/slippery, G, stun_len, stun_len, 100, 0, FALSE)
/datum/plant_gene/trait/cell_charge
// Cell recharging trait. Charges all mob's power cells to (potency*rate)% mark when eaten.
diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm
index 8cfc9b7d5f0..08ccac07062 100644
--- a/code/modules/hydroponics/seeds.dm
+++ b/code/modules/hydroponics/seeds.dm
@@ -182,7 +182,7 @@
/// Setters procs ///
/obj/item/seeds/proc/adjust_yield(adjustamt)
if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable
- yield = Clamp(yield + adjustamt, 0, 10)
+ yield = clamp(yield + adjustamt, 0, 10)
if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism))
yield = 1 // Mushrooms always have a minimum yield of 1.
@@ -191,39 +191,39 @@
C.value = yield
/obj/item/seeds/proc/adjust_lifespan(adjustamt)
- lifespan = Clamp(lifespan + adjustamt, 10, 100)
+ lifespan = clamp(lifespan + adjustamt, 10, 100)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan)
if(C)
C.value = lifespan
/obj/item/seeds/proc/adjust_endurance(adjustamt)
- endurance = Clamp(endurance + adjustamt, 10, 100)
+ endurance = clamp(endurance + adjustamt, 10, 100)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance)
if(C)
C.value = endurance
/obj/item/seeds/proc/adjust_production(adjustamt)
if(yield != -1)
- production = Clamp(production + adjustamt, 1, 10)
+ production = clamp(production + adjustamt, 1, 10)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production)
if(C)
C.value = production
/obj/item/seeds/proc/adjust_potency(adjustamt)
if(potency != -1)
- potency = Clamp(potency + adjustamt, 0, 100)
+ potency = clamp(potency + adjustamt, 0, 100)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency)
if(C)
C.value = potency
/obj/item/seeds/proc/adjust_weed_rate(adjustamt)
- weed_rate = Clamp(weed_rate + adjustamt, 0, 10)
+ weed_rate = clamp(weed_rate + adjustamt, 0, 10)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate)
if(C)
C.value = weed_rate
/obj/item/seeds/proc/adjust_weed_chance(adjustamt)
- weed_chance = Clamp(weed_chance + adjustamt, 0, 67)
+ weed_chance = clamp(weed_chance + adjustamt, 0, 67)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance)
if(C)
C.value = weed_chance
@@ -232,7 +232,7 @@
/obj/item/seeds/proc/set_yield(adjustamt)
if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable
- yield = Clamp(adjustamt, 0, 10)
+ yield = clamp(adjustamt, 0, 10)
if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism))
yield = 1 // Mushrooms always have a minimum yield of 1.
@@ -241,39 +241,39 @@
C.value = yield
/obj/item/seeds/proc/set_lifespan(adjustamt)
- lifespan = Clamp(adjustamt, 10, 100)
+ lifespan = clamp(adjustamt, 10, 100)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan)
if(C)
C.value = lifespan
/obj/item/seeds/proc/set_endurance(adjustamt)
- endurance = Clamp(adjustamt, 10, 100)
+ endurance = clamp(adjustamt, 10, 100)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance)
if(C)
C.value = endurance
/obj/item/seeds/proc/set_production(adjustamt)
if(yield != -1)
- production = Clamp(adjustamt, 1, 10)
+ production = clamp(adjustamt, 1, 10)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production)
if(C)
C.value = production
/obj/item/seeds/proc/set_potency(adjustamt)
if(potency != -1)
- potency = Clamp(adjustamt, 0, 100)
+ potency = clamp(adjustamt, 0, 100)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency)
if(C)
C.value = potency
/obj/item/seeds/proc/set_weed_rate(adjustamt)
- weed_rate = Clamp(adjustamt, 0, 10)
+ weed_rate = clamp(adjustamt, 0, 10)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate)
if(C)
C.value = weed_rate
/obj/item/seeds/proc/set_weed_chance(adjustamt)
- weed_chance = Clamp(adjustamt, 0, 67)
+ weed_chance = clamp(adjustamt, 0, 67)
var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance)
if(C)
C.value = weed_chance
diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm
index cccf9977ad6..837e3a21104 100644
--- a/code/modules/karma/karma.dm
+++ b/code/modules/karma/karma.dm
@@ -4,9 +4,9 @@
proc/sql_report_karma(var/mob/spender, var/mob/receiver)
var/sqlspendername = sanitizeSQL(spender.name)
- var/sqlspenderkey = spender.ckey
+ var/sqlspenderkey = sanitizeSQL(spender.ckey)
var/sqlreceivername = sanitizeSQL(receiver.name)
- var/sqlreceiverkey = receiver.ckey
+ var/sqlreceiverkey = sanitizeSQL(receiver.ckey)
var/sqlreceiverrole = "None"
var/sqlreceiverspecial = "None"
@@ -28,7 +28,7 @@ proc/sql_report_karma(var/mob/spender, var/mob/receiver)
log_game("SQL ERROR during karma logging. Error : \[[err]\]\n")
- query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[receiver.ckey]'")
+ query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[sqlreceiverkey]'")
query.Execute()
var/karma
@@ -38,7 +38,7 @@ proc/sql_report_karma(var/mob/spender, var/mob/receiver)
karma = text2num(query.item[3])
if(karma == null)
karma = 1
- query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("karmatotals")] (byondkey, karma) VALUES ('[receiver.ckey]', [karma])")
+ query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("karmatotals")] (byondkey, karma) VALUES ('[sqlreceiverkey]', [karma])")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during karmatotal logging (adding new key). Error : \[[err]\]\n")
@@ -168,11 +168,12 @@ GLOBAL_LIST_EMPTY(karma_spenders)
/client/proc/verify_karma()
var/currentkarma = 0
+ var/sanitzedkey = sanitizeSQL(src.ckey)
if(!GLOB.dbcon.IsConnected())
to_chat(usr, "Unable to connect to karma database. Please try again later. ")
return
else
- var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey='[src.ckey]'")
+ var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey='[sanitzedkey]'")
query.Execute()
var/totalkarma
@@ -195,6 +196,24 @@ GLOBAL_LIST_EMPTY(karma_spenders)
karmashopmenu()
/client/proc/karmashopmenu()
+ var/sanitzedkey = sanitizeSQL(usr.ckey)
+ var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'")
+ query.Execute()
+
+ var/list/joblist
+ var/list/specieslist
+ var/dbjob
+ var/dbspecies
+ var/dbckey
+ while(query.NextRow())
+ dbckey = query.item[2]
+ dbjob = query.item[3]
+ dbspecies = query.item[4]
+
+ if(dbckey)
+ joblist = splittext(dbjob,",")
+ specieslist = splittext(dbspecies,",")
+
var/dat = ""
dat += "Job Unlocks"
dat += "Species Unlocks"
@@ -202,28 +221,69 @@ GLOBAL_LIST_EMPTY(karma_spenders)
dat += ""
dat += " "
+ var/currentkarma = verify_karma()
+ dat += "You have [currentkarma] available.
"
+
switch(karma_tab)
if(0) // Job Unlocks
- dat += {"
- Unlock Barber -- 5KP
- Unlock Brig Physician -- 5KP
- Unlock Nanotrasen Representative -- 30KP
- Unlock Blueshield -- 30KP
- Unlock Security Pod Pilot -- 30KP
- Unlock Mechanic -- 30KP
- Unlock Magistrate -- 45KP
- "}
+ if(!("Barber" in joblist))
+ dat += "Unlock Barber -- 5KP "
+ else
+ dat += "Barber - Unlocked "
+ if(!("Brig Physician" in joblist))
+ dat += "Unlock Brig Physician -- 5KP "
+ else
+ dat += "Brig Physician - Unlocked "
+ if(!("Nanotrasen Representative" in joblist))
+ dat += "Unlock Nanotrasen Representative -- 30KP "
+ else
+ dat += "Nanotrasen Representative - Unlocked "
+ if(!("Blueshield" in joblist))
+ dat += "Unlock Blueshield -- 30KP "
+ else
+ dat += "Blueshield - Unlocked "
+ if(!("Security Pod Pilot" in joblist))
+ dat += "Unlock Security Pod Pilot -- 30KP "
+ else
+ dat += "Security Pod Pilot - Unlocked "
+ if(!("Mechanic" in joblist))
+ dat += "Unlock Mechanic -- 30KP "
+ else
+ dat += "Mechanic - Unlocked "
+ if(!("Magistrate" in joblist))
+ dat += "Unlock Magistrate -- 45KP "
+ else
+ dat+= "Magistrate - Unlocked "
if(1) // Species Unlocks
- dat += {"
- Unlock Machine People -- 15KP
- Unlock Kidan -- 30KP
- Unlock Grey -- 30KP
- Unlock Drask -- 30KP
- Unlock Vox -- 45KP
- Unlock Slime People -- 45KP
- Unlock Plasmaman -- 45KP
- "}
+ if(!("Machine" in specieslist))
+ dat += "Unlock Machine People -- 15KP "
+ else
+ dat += "Machine People - Unlocked "
+ if(!("Kidan" in specieslist))
+ dat += "Unlock Kidan -- 30KP "
+ else
+ dat += "Kidan - Unlocked "
+ if(!("Grey" in specieslist))
+ dat += "Unlock Grey -- 30KP "
+ else
+ dat += "Grey - Unlocked "
+ if(!("Drask" in specieslist))
+ dat += "Unlock Drask -- 30KP "
+ else
+ dat += "Drask - Unlocked "
+ if(!("Vox" in specieslist))
+ dat += "Unlock Vox -- 45KP "
+ else
+ dat += "Vox - Unlocked "
+ if(!("Slime People" in specieslist))
+ dat += "Unlock Slime People -- 45KP "
+ else
+ dat += "Slime People - Unlocked "
+ if(!("Plasmaman" in specieslist))
+ dat += "Unlock Plasmaman -- 45KP "
+ else
+ dat += "Plasmaman - Unlocked "
if(2) // Karma Refunds
var/list/refundable = list()
@@ -283,11 +343,14 @@ GLOBAL_LIST_EMPTY(karma_spenders)
name = DBname
if(category == "job")
DB_job_unlock(name,price)
+ karmashopmenu()
else if(category == "species")
DB_species_unlock(name,price)
+ karmashopmenu()
/client/proc/DB_job_unlock(var/job,var/cost)
- var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'")
+ var/sanitzedkey = sanitizeSQL(usr.ckey)
+ var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'")
query.Execute()
var/dbjob
@@ -296,7 +359,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
dbckey = query.item[2]
dbjob = query.item[3]
if(!dbckey)
- query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, job) VALUES ('[usr.ckey]','[job]')")
+ query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, job) VALUES ('[sanitzedkey]','[job]')")
if(!query.Execute())
queryErrorLog(query.ErrorMsg(),"adding new key")
return
@@ -323,7 +386,8 @@ GLOBAL_LIST_EMPTY(karma_spenders)
return
/client/proc/DB_species_unlock(var/species,var/cost)
- var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'")
+ var/sanitzedkey = sanitizeSQL(usr.ckey)
+ var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'")
query.Execute()
var/dbspecies
@@ -332,7 +396,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
dbckey = query.item[2]
dbspecies = query.item[4]
if(!dbckey)
- query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, species) VALUES ('[usr.ckey]','[species]')")
+ query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, species) VALUES ('[sanitzedkey]','[species]')")
if(!query.Execute())
queryErrorLog(query.ErrorMsg(),"adding new key")
return
@@ -359,7 +423,8 @@ GLOBAL_LIST_EMPTY(karma_spenders)
return
/client/proc/karmacharge(var/cost,var/refund = FALSE)
- var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[usr.ckey]'")
+ var/sanitzedkey = sanitizeSQL(usr.ckey)
+ var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("karmatotals")] WHERE byondkey='[sanitzedkey]'")
query.Execute()
while(query.NextRow())
@@ -368,7 +433,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
spent -= cost
else
spent += cost
- query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=[spent] WHERE byondkey='[usr.ckey]'")
+ query = GLOB.dbcon.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=[spent] WHERE byondkey='[sanitzedkey]'")
if(!query.Execute())
queryErrorLog(query.ErrorMsg(),"updating existing entry")
return
@@ -378,6 +443,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
return
/client/proc/karmarefund(var/type,var/name,var/cost)
+ var/sanitzedkey = sanitizeSQL(usr.ckey)
switch(name)
if("Tajaran Ambassador","Unathi Ambassador","Skrell Ambassador","Diona Ambassador","Kidan Ambassador",
"Slime People Ambassador","Grey Ambassador","Vox Ambassador","Customs Officer")
@@ -388,7 +454,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
to_chat(usr, "That job is not refundable.")
return
- var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'")
+ var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'")
query.Execute()
var/dbjob
@@ -431,7 +497,8 @@ GLOBAL_LIST_EMPTY(karma_spenders)
message_admins("SQL ERROR during whitelist logging ([errType]]). Error : \[[err]\]\n")
/client/proc/checkpurchased(var/name = null) // If the first parameter is null, return a full list of purchases
- var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'")
+ var/sanitzedkey = sanitizeSQL(usr.ckey)
+ var/DBQuery/query = GLOB.dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[sanitzedkey]'")
query.Execute()
var/dbjob
diff --git a/code/modules/library/computers/checkout.dm b/code/modules/library/computers/checkout.dm
index 99f7e2cb8fe..934234f645e 100644
--- a/code/modules/library/computers/checkout.dm
+++ b/code/modules/library/computers/checkout.dm
@@ -95,7 +95,7 @@
dat += "ERROR: Unable to contact External Archive. Please contact your system administrator for assistance."
else
num_results = src.get_num_results()
- num_pages = Ceiling(num_results/LIBRARY_BOOKS_PER_PAGE)
+ num_pages = CEILING(num_results/LIBRARY_BOOKS_PER_PAGE, 1)
dat += {""}
@@ -165,7 +165,7 @@
dat += ""
var/list/forbidden = list(
- /obj/item/book/manual
+ /obj/item/book/manual/random
)
if(!emagged)
@@ -174,11 +174,12 @@
var/manualcount = 1
var/obj/item/book/manual/M = null
- for(var/manual_type in (typesof(/obj/item/book/manual) - forbidden))
- M = new manual_type()
- dat += "| [M.title] | "
+ for(var/manual_type in subtypesof(/obj/item/book/manual))
+ if(!(manual_type in forbidden))
+ M = new manual_type()
+ dat += "| [M.title] | "
+ QDEL_NULL(M)
manualcount++
- QDEL_NULL(M)
dat += " "
dat += " (Return to main menu) "
@@ -206,7 +207,7 @@
var/obj/item/barcodescanner/scanner = W
scanner.computer = src
to_chat(user, "[scanner]'s associated machine has been set to [src].")
- audible_message("[src] lets out a low, short blip.", 2)
+ audible_message("[src] lets out a low, short blip.", hearing_distance = 2)
return 1
else
return ..()
@@ -223,13 +224,13 @@
else
var/pn = text2num(href_list["pagenum"])
if(!isnull(pn))
- page_num = Clamp(pn, 1, num_pages)
+ page_num = clamp(pn, 1, num_pages)
if(href_list["page"])
if(num_pages == 0)
page_num = 1
else
- page_num = Clamp(text2num(href_list["page"]), 1, num_pages)
+ page_num = clamp(text2num(href_list["page"]), 1, num_pages)
if(href_list["settitle"])
var/newtitle = input("Enter a title to search for:") as text|null
if(newtitle)
@@ -251,7 +252,7 @@
if(href_list["search"])
num_results = src.get_num_results()
- num_pages = Ceiling(num_results/LIBRARY_BOOKS_PER_PAGE)
+ num_pages = CEILING(num_results/LIBRARY_BOOKS_PER_PAGE, 1)
page_num = 1
screenstate = 4
@@ -412,7 +413,7 @@
return
if(bibledelay)
- audible_message("[src]'s monitor flashes, \"Printer unavailable. Please allow a short time before attempting to print.\"")
+ visible_message("[src]'s monitor flashes, \"Printer unavailable. Please allow a short time before attempting to print.\"")
else
bibledelay = 1
spawn(60)
@@ -462,4 +463,5 @@
B.author = newbook.author
B.dat = newbook.content
B.icon_state = "book[rand(1,16)]"
+ B.has_drm = TRUE
visible_message("[src]'s printer hums as it produces a completely bound book. How did it do that?")
diff --git a/code/modules/library/computers/public.dm b/code/modules/library/computers/public.dm
index f94369b11b7..3c5116bc074 100644
--- a/code/modules/library/computers/public.dm
+++ b/code/modules/library/computers/public.dm
@@ -75,7 +75,7 @@
else
var/pn = text2num(href_list["pagenum"])
if(!isnull(pn))
- page_num = Clamp(pn, 1, num_pages)
+ page_num = clamp(pn, 1, num_pages)
if(href_list["settitle"])
var/newtitle = input("Enter a title to search for:") as text|null
@@ -100,11 +100,11 @@
if(num_pages == 0)
page_num = 1
else
- page_num = Clamp(text2num(href_list["page"]), 1, num_pages)
+ page_num = clamp(text2num(href_list["page"]), 1, num_pages)
if(href_list["search"])
num_results = src.get_num_results()
- num_pages = Ceiling(num_results/LIBRARY_BOOKS_PER_PAGE)
+ num_pages = CEILING(num_results/LIBRARY_BOOKS_PER_PAGE, 1)
page_num = 1
screenstate = 1
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index a7dd148b51a..e74625c8715 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -151,6 +151,8 @@
var/carved = 0 // Has the book been hollowed out for use as a secret storage item?
var/forbidden = 0 // Prevent ordering of this book. (0=no, 1=yes, 2=emag only)
var/obj/item/store // What's in the book?
+ /// Book DRM. If this var is TRUE, it cannot be scanned and re-uploaded
+ var/has_drm = FALSE
/obj/item/book/attack_self(var/mob/user as mob)
if(carved)
diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm
index 65fadaa9b45..0c23a0c5800 100644
--- a/code/modules/library/lib_machines.dm
+++ b/code/modules/library/lib_machines.dm
@@ -3,11 +3,6 @@
GLOBAL_DATUM_INIT(library_catalog, /datum/library_catalog, new())
GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "Adult", "Reference", "Religion"))
-
-/hook/startup/proc/load_manuals()
- GLOB.library_catalog.initialize()
- return 1
-
/*
* Borrowbook datum
*/
@@ -65,7 +60,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
/datum/library_catalog
var/list/cached_books = list()
-/datum/library_catalog/proc/initialize()
+/datum/library_catalog/New()
var/newid=1
for(var/typepath in subtypesof(/obj/item/book/manual))
var/obj/item/book/B = new typepath(null)
@@ -155,6 +150,11 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
power_change()
return
if(istype(I, /obj/item/book))
+ // NT with those pesky DRM schemes
+ var/obj/item/book/B = I
+ if(B.has_drm)
+ atom_say("Copyrighted material detected. Scanner is unable to copy book to memory.")
+ return FALSE
user.drop_item()
I.forceMove(src)
return 1
diff --git a/code/modules/lighting/lighting_atom.dm b/code/modules/lighting/lighting_atom.dm
index ff4bc517979..fa848700557 100644
--- a/code/modules/lighting/lighting_atom.dm
+++ b/code/modules/lighting/lighting_atom.dm
@@ -38,7 +38,7 @@
if(!light_power || !light_range) // We won't emit light anyways, destroy the light source.
QDEL_NULL(light)
else
- if(!ismovableatom(loc)) // We choose what atom should be the top atom of the light here.
+ if(!ismovable(loc)) // We choose what atom should be the top atom of the light here.
. = src
else
. = loc
diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm
index bc521114d56..57302b5b168 100644
--- a/code/modules/lighting/lighting_corner.dm
+++ b/code/modules/lighting/lighting_corner.dm
@@ -25,7 +25,7 @@ GLOBAL_LIST_INIT(LIGHTING_CORNER_DIAGONAL, list(NORTHEAST, SOUTHEAST, SOUTHWEST,
var/cache_b = LIGHTING_SOFT_THRESHOLD
var/cache_mx = 0
-/datum/lighting_corner/New(var/turf/new_turf, var/diagonal)
+/datum/lighting_corner/New(turf/new_turf, diagonal)
. = ..()
masters = list()
masters[new_turf] = turn(diagonal, 180)
@@ -79,15 +79,16 @@ GLOBAL_LIST_INIT(LIGHTING_CORNER_DIAGONAL, list(NORTHEAST, SOUTHEAST, SOUTHWEST,
active = FALSE
var/turf/T
var/thing
- for (thing in masters)
+ for(thing in masters)
T = thing
if(T.lighting_object)
active = TRUE
+ return
// God that was a mess, now to do the rest of the corner code! Hooray!
-/datum/lighting_corner/proc/update_lumcount(var/delta_r, var/delta_g, var/delta_b)
+/datum/lighting_corner/proc/update_lumcount(delta_r, delta_g, delta_b)
- if((abs(delta_r)+abs(delta_g)+abs(delta_b)) == 0)
+ if(!(delta_r || delta_g || delta_b)) // 0 is falsey ok
return
lum_r += delta_r
@@ -96,10 +97,10 @@ GLOBAL_LIST_INIT(LIGHTING_CORNER_DIAGONAL, list(NORTHEAST, SOUTHEAST, SOUTHWEST,
if(!needs_update)
needs_update = TRUE
- GLOB.lighting_update_corners += src
+ SSlighting.corners_queue += src
/datum/lighting_corner/proc/update_objects()
- // Cache these values a head of time so 4 individual lighting objects don't all calculate them individually.
+ // Cache these values ahead of time so 4 individual lighting objects don't all calculate them individually.
var/lum_r = src.lum_r
var/lum_g = src.lum_g
var/lum_b = src.lum_b
@@ -122,19 +123,18 @@ GLOBAL_LIST_INIT(LIGHTING_CORNER_DIAGONAL, list(NORTHEAST, SOUTHEAST, SOUTHWEST,
#endif
cache_mx = round(mx, LIGHTING_ROUND_VALUE)
- for (var/TT in masters)
+ for(var/TT in masters)
var/turf/T = TT
- if(T.lighting_object)
- if(!T.lighting_object.needs_update)
- T.lighting_object.needs_update = TRUE
- GLOB.lighting_update_objects += T.lighting_object
+ if(T.lighting_object && !T.lighting_object.needs_update)
+ T.lighting_object.needs_update = TRUE
+ SSlighting.objects_queue += T.lighting_object
/datum/lighting_corner/dummy/New()
return
-/datum/lighting_corner/Destroy(var/force)
+/datum/lighting_corner/Destroy(force)
if(!force)
return QDEL_HINT_LETMELIVE
diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm
index ea3e954fa6e..168a95c07f2 100644
--- a/code/modules/lighting/lighting_object.dm
+++ b/code/modules/lighting/lighting_object.dm
@@ -5,7 +5,7 @@
icon = LIGHTING_ICON
icon_state = "transparent"
- color = LIGHTING_BASE_MATRIX
+ color = null //we manually set color in init instead
plane = LIGHTING_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = LIGHTING_LAYER
@@ -18,6 +18,9 @@
/atom/movable/lighting_object/Initialize(mapload)
. = ..()
verbs.Cut()
+ //We avoid setting this in the base as if we do then the parent atom handling will add_atom_color it and that
+ //is totally unsuitable for this object, as we are always changing it's colour manually
+ color = LIGHTING_BASE_MATRIX
myturf = loc
if(myturf.lighting_object)
@@ -29,11 +32,11 @@
S.update_starlight()
needs_update = TRUE
- GLOB.lighting_update_objects += src
+ SSlighting.objects_queue += src
-/atom/movable/lighting_object/Destroy(var/force)
+/atom/movable/lighting_object/Destroy(force)
if(force)
- GLOB.lighting_update_objects -= src
+ SSlighting.objects_queue -= src
if(loc != myturf)
var/turf/oldturf = get_turf(myturf)
var/turf/newturf = get_turf(loc)
@@ -143,6 +146,6 @@
return
// Override here to prevent things accidentally moving around overlays.
-/atom/movable/lighting_object/forceMove(atom/destination, var/no_tp=FALSE, var/harderforce = FALSE)
+/atom/movable/lighting_object/forceMove(atom/destination, no_tp = FALSE, harderforce = FALSE)
if(harderforce)
. = ..()
diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm
index fc87a855dc4..9398bd9683c 100644
--- a/code/modules/lighting/lighting_source.dm
+++ b/code/modules/lighting/lighting_source.dm
@@ -29,7 +29,7 @@
var/needs_update = LIGHTING_NO_UPDATE // Whether we are queued for an update.
-/datum/light_source/New(var/atom/owner, var/atom/top)
+/datum/light_source/New(atom/owner, atom/top)
source_atom = owner // Set our new owner.
LAZYADD(source_atom.light_sources, src)
top_atom = top
@@ -56,7 +56,7 @@
LAZYREMOVE(top_atom.light_sources, src)
if(needs_update)
- GLOB.lighting_update_lights -= src
+ SSlighting.sources_queue -= src
. = ..()
@@ -65,13 +65,13 @@
// Actually that'd be great if you could!
#define EFFECT_UPDATE(level) \
if(needs_update == LIGHTING_NO_UPDATE) \
- GLOB.lighting_update_lights += src; \
+ SSlighting.sources_queue += src; \
if(needs_update < level) \
needs_update = level; \
// This proc will cause the light source to update the top atom, and add itself to the update queue.
-/datum/light_source/proc/update(var/atom/new_top_atom)
+/datum/light_source/proc/update(atom/new_top_atom)
// This top atom is different.
if(new_top_atom && new_top_atom != top_atom)
if(top_atom != source_atom && top_atom.light_sources) // Remove ourselves from the light sources of that top atom.
@@ -141,7 +141,7 @@
effect_str = null
-/datum/light_source/proc/recalc_corner(var/datum/lighting_corner/C)
+/datum/light_source/proc/recalc_corner(datum/lighting_corner/C)
LAZYINITLIST(effect_str)
if(effect_str[C]) // Already have one.
REMOVE_CORNER(C)
@@ -220,13 +220,14 @@
var/oldlum = source_turf.luminosity
source_turf.luminosity = CEILING(light_range, 1)
for(T in view(CEILING(light_range, 1), source_turf))
- if((!IS_DYNAMIC_LIGHTING(T) && !T.light_sources) || T.has_opaque_atom)
+ if((!IS_DYNAMIC_LIGHTING(T) && !T.light_sources))
continue
- if(!T.lighting_corners_initialised)
- T.generate_missing_corners()
- for(thing in T.corners)
- C = thing
- corners[C] = 0
+ if(!T.has_opaque_atom)
+ if(!T.lighting_corners_initialised)
+ T.generate_missing_corners()
+ for(thing in T.corners)
+ C = thing
+ corners[C] = 0
turfs += T
source_turf.luminosity = oldlum
diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm
index f368ff5ac4b..5483eebf4e1 100644
--- a/code/modules/lighting/lighting_turf.dm
+++ b/code/modules/lighting/lighting_turf.dm
@@ -57,7 +57,7 @@
C.active = TRUE
// Used to get a scaled lumcount.
-/turf/proc/get_lumcount(var/minlum = 0, var/maxlum = 1)
+/turf/proc/get_lumcount(minlum = 0, maxlum = 1)
if(!lighting_object)
return 1
@@ -102,7 +102,7 @@
recalc_atom_opacity() // Make sure to do this before reconsider_lights(), incase we're on instant updates.
reconsider_lights()
-/turf/proc/change_area(var/area/old_area, var/area/new_area)
+/turf/proc/change_area(area/old_area, area/new_area)
if(SSlighting.initialized)
if(new_area.dynamic_lighting != old_area.dynamic_lighting)
if(new_area.dynamic_lighting)
diff --git a/code/modules/logic/converter.dm b/code/modules/logic/converter.dm
deleted file mode 100644
index c54e3fe4882..00000000000
--- a/code/modules/logic/converter.dm
+++ /dev/null
@@ -1,143 +0,0 @@
-
-//////////////////////////////////
-// Converter Gate //
-//////////////////////////////////
-
-/*
- This gate is special enough to warrant its own file, as it overrides a lot of the logic_gate procs as well as adds a new one.
- - CONVERT Gates convert signaler and logic signals, to allow logic gates to actually be used in tandem with assemblies and station equipment like doors.
- - While technically a mono-input device, the input and output are actually completely different types of signals, and thus incompatible without this gate.
- - A signaler must be attached manually before the gate is fully functional, and will retain any frequency and code settings it had when attached.
- - You can adjust these settings through a link in the multitool menu, but the receiving mode is automatically controlled by the converter.
- - While attached, the ability to manually send the signal on the signaler through its menu is also disabled, to avoid messing up the logic system.
-*/
-
-//CONVERT Gate
-/obj/machinery/logic_gate/convert
- name = "CONVERT Gate"
- desc = "Converts signals between radio and logic types, allowing for signaller input/output from logic systems."
- icon_state = "logic_convert"
- mono_input = 1
-
- var/logic_output = 0 //When set to 1, the logic signal is the output. When set to 0, the logic signal is the input.
- var/obj/item/assembly/signaler/attached_signaler = null
-
-/obj/machinery/logic_gate/convert/handle_logic()
- output_state = input1_state
- return
-
-/obj/machinery/logic_gate/convert/attackby(obj/item/O, mob/user, params)
- if(tamperproof) //Extra precaution to avoid people attaching/removing signalers from tamperproofed converters
- return
- if(istype(O, /obj/item/assembly/signaler))
- var/obj/item/assembly/signaler/S = O
- if(S.secured)
- to_chat(user, "The [S] is already secured.")
- return
- if(attached_signaler)
- to_chat(user, "There is already a device attached, remove it first.")
- return
- user.unEquip(S)
- S.forceMove(src)
- S.holder = src
- S.toggle_secure()
- if(logic_output) //Make sure we are set to receive if the converter is set to output logic, and send if the converter is set to accept logic input
- S.receiving = 1
- else
- S.receiving = 0
- attached_signaler = S
- to_chat(user, "You attach \the [S] to the I/O connection port and secure it.")
- return
- if(attached_signaler && istype(O, /obj/item/screwdriver)) //Makes sure we remove the attached signaler before we can open up and deconstruct the machine
- var/obj/item/assembly/signaler/S = attached_signaler
- attached_signaler = null
- S.forceMove(get_turf(src))
- S.holder = null
- S.toggle_secure()
- to_chat(user, "You unsecure and detach \the [S] from the I/O connection port.")
- return
- return ..()
-
-/obj/machinery/logic_gate/convert/multitool_menu(var/mob/user, var/obj/item/multitool/P)
- var/logic_state_string
- var/menu_contents = {"
-
- "}
- if(logic_output)
- switch(output_state)
- if(LOGIC_OFF)
- logic_state_string = "OFF"
- if(LOGIC_ON)
- logic_state_string = "ON"
- if(LOGIC_FLICKER)
- logic_state_string = "FLICKER"
- else
- logic_state_string = "ERROR: UNKNOWN STATE"
- menu_contents += {"
- - Output: [format_tag("ID Tag","output_id_tag")]
- - Output State: [logic_state_string]
- "}
- else
- switch(input1_state)
- if(LOGIC_OFF)
- logic_state_string = "OFF"
- if(LOGIC_ON)
- logic_state_string = "ON"
- if(LOGIC_FLICKER)
- logic_state_string = "FLICKER"
- else
- logic_state_string = "ERROR: UNKNOWN STATE"
- menu_contents += {"
- - Input: [format_tag("ID Tag","input1_id_tag")]
- - Input State: [logic_state_string]
- "}
- menu_contents += {"
- - Logic Signal Designation: [logic_output ? "Output" : "Input"]
- "}
- if(attached_signaler)
- menu_contents += "- Adjust Signaler Settings
"
- else
- menu_contents += "- NO SIGNALER ATTACHED!
"
- menu_contents += {"
-
- "}
- return menu_contents
-
-/obj/machinery/logic_gate/convert/multitool_topic(var/mob/user,var/list/href_list,var/obj/O)
- ..()
- if("toggle_logic" in href_list)
- logic_output = !logic_output
- if(attached_signaler) //If we have a signaler attached, make sure we update it to send/receive when we change the logic signal desgination
- if(logic_output)
- attached_signaler.receiving = 1
- else
- attached_signaler.receiving = 0
- if(("adjust_signaler" in href_list) && attached_signaler) //Make sure that we have a signaler attached to handle this one, otherwise ignore this command
- attached_signaler.interact(user, 1)
- update_multitool_menu(user)
-
-/obj/machinery/logic_gate/convert/receive_signal(datum/signal/signal, receive_method, receive_param)
- if(logic_output)
- if(attached_signaler)
- attached_signaler.receive_signal(signal)
- return
- else
- ..()
-
-/obj/machinery/logic_gate/convert/handle_output()
- if(logic_output)
- ..()
- else
- if(attached_signaler && (output_state == LOGIC_ON || output_state == LOGIC_FLICKER))
- attached_signaler.signal()
- return
-
-/obj/machinery/logic_gate/convert/proc/process_activation(var/obj/item/D)
- if(!logic_output) //Don't bother if our input is a logic signal
- return
- if(D == attached_signaler) //Ignore if we somehow got called by a device that isn't what we have attached
- input1_state = LOGIC_FLICKER
- spawn(LOGIC_FLICKER_TIME)
- if(input1_state == LOGIC_FLICKER)
- input1_state = LOGIC_OFF
- return
diff --git a/code/modules/logic/dual_input.dm b/code/modules/logic/dual_input.dm
deleted file mode 100644
index b8f915ff46d..00000000000
--- a/code/modules/logic/dual_input.dm
+++ /dev/null
@@ -1,100 +0,0 @@
-
-//////////////////////////////////
-// Dual-Input Gates //
-//////////////////////////////////
-
-
-// OR Gate
-/obj/machinery/logic_gate/or
- name = "OR Gate"
- desc = "Outputs ON when at least one input is ON."
- icon_state = "logic_or"
-
-/obj/machinery/logic_gate/or/handle_logic()
- if(input1_state == LOGIC_ON || input1_state == LOGIC_FLICKER || input2_state == LOGIC_ON || input2_state == LOGIC_FLICKER)
- if(input1_state == LOGIC_ON || input2_state == LOGIC_ON) //continuous signal takes priority in determining what to output
- output_state = LOGIC_ON
- else
- output_state = LOGIC_FLICKER
- else //Both inputs were off, so input is off
- output_state = LOGIC_OFF
- return
-
-// AND Gate
-/obj/machinery/logic_gate/and
- name = "AND Gate"
- desc = "Outputs ON only when both inputs are ON."
- icon_state = "logic_and"
-
-/obj/machinery/logic_gate/and/handle_logic()
- if((input1_state == LOGIC_ON || input1_state == LOGIC_FLICKER) && (input2_state == LOGIC_ON || input2_state == LOGIC_FLICKER))
- if(input1_state == LOGIC_ON && input2_state == LOGIC_ON) //only output a continuous signal when both inputs are continuous signals
- output_state = LOGIC_ON
- else
- output_state = LOGIC_FLICKER
- else //At least one input was off, so output is off
- output_state = LOGIC_OFF
- return
-
-// NAND Gate
-/obj/machinery/logic_gate/nand
- name = "NAND Gate"
- desc = "Outputs OFF only when both inputs are ON."
- output_state = LOGIC_ON
- icon_state = "logic_nand"
-
-/obj/machinery/logic_gate/nand/handle_logic()
- if((input1_state == LOGIC_ON || input1_state == LOGIC_FLICKER) && (input2_state == LOGIC_ON || input2_state == LOGIC_FLICKER))
- output_state = LOGIC_OFF //Both inputs are ON/FLICKER, so output is off
- else
- output_state = LOGIC_ON //This can only output continuous signals
- return
-
-// NOR Gate
-/obj/machinery/logic_gate/nor
- name = "NOR Gate"
- desc = "Outputs OFF when at least one input is ON."
- icon_state = "logic_nor"
- output_state = LOGIC_ON
-
-/obj/machinery/logic_gate/nor/handle_logic()
- if(input1_state == LOGIC_OFF && input2_state == LOGIC_OFF) //Both inputs are OFF, so output is ON
- output_state = LOGIC_ON //This can only output continuous signals
- else
- output_state = LOGIC_OFF
- return
-
-// XOR Gate
-/obj/machinery/logic_gate/xor
- name = "XOR Gate"
- desc = "Outputs ON when only one input is ON."
- icon_state = "logic_xor"
-
-/obj/machinery/logic_gate/xor/handle_logic()
- if((input1_state == LOGIC_ON || input1_state == LOGIC_FLICKER) && (input2_state == LOGIC_OFF)) //Only input1 is ON/FLICKER, so output matches input1
- output_state = input1_state
- else if((input2_state == LOGIC_ON || input2_state == LOGIC_FLICKER) && (input1_state == LOGIC_OFF)) //Only input2 is ON/FLICKER, so output matches input2
- output_state = input2_state
- else //Both inputs are ON or OFF, so output is OFF
- output_state = LOGIC_OFF
- return
-
-
-// XNOR Gate
-/obj/machinery/logic_gate/xnor
- name = "XNOR Gate"
- desc = "Outputs ON when both inputs are ON or OFF."
- icon_state = "logic_xnor"
- output_state = LOGIC_ON
-
-/obj/machinery/logic_gate/xnor/handle_logic()
- if((input1_state == LOGIC_ON || input1_state == LOGIC_FLICKER) && (input2_state == LOGIC_ON || input2_state == LOGIC_FLICKER)) //Both inputs are ON/FLICKER
- if(input1_state == LOGIC_ON && input2_state == LOGIC_ON) //Only continuous signal when both inputs are ON
- output_state = LOGIC_ON
- else //If at least one input is FLICKER, output FLICKER
- output_state = LOGIC_FLICKER
- else if(input1_state == LOGIC_OFF && input2_state == LOGIC_OFF) //Both inputs are OFF
- output_state = LOGIC_ON //Always continuous in this case
- else //Only one input is ON/FLICKER
- output_state = LOGIC_OFF
- return
diff --git a/code/modules/logic/logic_base.dm b/code/modules/logic/logic_base.dm
deleted file mode 100644
index 542cb09bc7f..00000000000
--- a/code/modules/logic/logic_base.dm
+++ /dev/null
@@ -1,284 +0,0 @@
-
-/obj/machinery/logic_gate
- name = "Logic Base"
- desc = "This does nothing except connect to things. Highly illogical, report to a coder at once if you see this in-game."
- icon = 'icons/obj/computer3.dmi'
- icon_state = "serverframe"
- density = 1
- anchored = 1
-
- settagwhitelist = list("input1_id_tag", "input2_id_tag", "output_id_tag")
-
- var/tamperproof = 0 //if set, will make the machine unable to be destroyed, adjusted, etc. via in-game interaction (USE ONLY FOR MAPPING STUFF)
- var/mono_input = 0 //if set, will ignore input2
-
- var/datum/radio_frequency/radio_connection
- var/frequency = 0
-
- /*
- Some notes on Input/Output:
- - Multiple things can be linked to the same input or output tag, just like how wires can connect multiple sources and receivers.
- - For inputs, only the last signal received BEFORE a process() call will be used in the logic handling.
- - Input states are updated immediately whenever an input signal is received, so it is possible to update multiple times within a single process cycle.
- - This means if you have multiple connected inputs, but the last signal received before the process() call is OFF, it won't matter if the others are both ON.
- - For this reason, please set up your logic properly. You can theoretically chain these infinitely, so there's no need to link multiple things to a single input.
- - For outputs, the signal will attempt to be sent out every process() call, to ensure newly connected things are updated within one process cycle
- - Connecting an output to multiple inputs should not cause issues, as long as you don't have multiple connections to a given input (see previous notes on inputs).
- - The output state is determined immediately preceeding the signal broadcast, using the input states at the time of the process() call, not when a signal is received.
- - Because of how the process cycle works, it is possible that it may take multiple cycles for a signal to fully propogate through a logic chain.
- - This is because machines attempt to process in the order they were added to the scheduler.
- - Building the logic gates at the end of the chain first may cause delays in signal propogation.
- If you take all this into consideration when linking and using logic machinery, you should have no unexpected issues with input/output. Your design flaws are on you though.
- */
-
- var/input1_id_tag = null
- var/input1_state = LOGIC_OFF
- var/input2_id_tag = null
- var/input2_state = LOGIC_OFF
- var/output_id_tag = null
- var/output_state = LOGIC_OFF
-
-/obj/machinery/logic_gate/New()
- if(tamperproof) //doing this during New so we don't have to worry about forgetting to set these vars during editting / defining
- resistance_flags |= ACID_PROOF
- ..()
- if(SSradio)
- set_frequency(frequency)
- component_parts = list()
- var/obj/item/circuitboard/logic_gate/LG = new(null)
- LG.set_type(type)
- component_parts += LG
- component_parts += new /obj/item/stack/cable_coil(null, 1)
-
-/obj/machinery/logic_gate/Initialize()
- ..()
- set_frequency(frequency)
-
-/obj/machinery/logic_gate/proc/set_frequency(new_frequency)
- SSradio.remove_object(src, frequency)
- frequency = new_frequency
- radio_connection = SSradio.add_object(src, frequency, RADIO_LOGIC)
- return
-
-/obj/machinery/logic_gate/Destroy()
- if(SSradio)
- SSradio.remove_object(src, frequency)
- radio_connection = null
- return ..()
-
-/obj/machinery/logic_gate/process()
- handle_logic()
- handle_output() //All output will send for at least one cycle, and will attempt to send every cycle. Hopefully this won't be too taxing.
- return
-
-/obj/machinery/logic_gate/proc/handle_logic()
- return
-
-/obj/machinery/logic_gate/proc/handle_output()
- if(!radio_connection) //can't output without this
- return
-
- if(output_id_tag == null) //Don't output to an undefined id_tag
- return
-
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.source = src
-
- signal.data = list(
- "tag" = output_id_tag,
- "sigtype" = "logic",
- "state" = output_state,
- )
-
- radio_connection.post_signal(src, signal, filter = RADIO_LOGIC)
-
-/obj/machinery/logic_gate/receive_signal(datum/signal/signal, receive_method, receive_param)
- if(!signal.data["tag"] || ((signal.data["tag"] != input1_id_tag) && (signal.data["tag"] != input2_id_tag)) || (signal.data["sigtype"] != "logic"))
- //If the signal lacks tag data, the signal's tag data doesn't match either input id tag, or is not a "logic" signal, ignore it since it's not for us
- return
-
- if(signal.data["tag"] == input1_id_tag) //If the signal is for input1
- if(signal.data["state"] == input1_state) //If we already match, ignore the new signal since nothing changes
- return
- if(signal.data["state"] == LOGIC_OFF) //Shut it down and keep it off
- input1_state = LOGIC_OFF
- return
- if(signal.data["state"] == LOGIC_ON) //Turn it on and keep it on
- input1_state = LOGIC_ON
- return
- if(signal.data["state"] == LOGIC_FLICKER) //Turn it on then turn it off
- if(input1_state == LOGIC_ON) //An existing continuous ON state overrides new flicker signals
- return
- input1_state = LOGIC_FLICKER
- spawn(LOGIC_FLICKER_TIME)
- if(input1_state == LOGIC_FLICKER) //Make sure we didn't get a new continuous signal set while we waited (those take priority)
- input1_state = LOGIC_OFF
- return
-
- //Now, you may be wondering why I included those returns.
- //The answer is "If you link both inputs to the same source, you're an idiot and deserve to have it break", so yeah. Deal with it.
-
- if(mono_input)
- //We only care about input1, so if we didn't receive a signal for that, we're done.
- return
-
- if(signal.data["tag"] == input2_id_tag) //If the signal is for input2 (reaching this point assumes mono_input is not set)
- if(signal.data["state"] == input2_state) //If we already match, ignore the new signal since nothing changes
- return
- if(signal.data["state"] == LOGIC_OFF) //Shut it down and keep it off
- input2_state = LOGIC_OFF
- return
- if(signal.data["state"] == LOGIC_ON) //Turn it on and keep it on
- input2_state = LOGIC_ON
- return
- if(signal.data["state"] == LOGIC_FLICKER) //Turn it on then turn it off
- if(input2_state == LOGIC_ON) //An existing continuous ON state overrides new flicker signals
- return
- input2_state = LOGIC_FLICKER
- spawn(LOGIC_FLICKER_TIME)
- if(input2_state == LOGIC_FLICKER) //Make sure we didn't get a new continuous signal set while we waited (those take priority)
- input2_state = LOGIC_OFF
- return
-
-/obj/machinery/logic_gate/multitool_menu(var/mob/user, var/obj/item/multitool/P)
- var/input1_state_string
- var/input2_state_string
- var/output_state_string
-
- switch(input1_state)
- if(LOGIC_OFF)
- input1_state_string = "OFF"
- if(LOGIC_ON)
- input1_state_string = "ON"
- if(LOGIC_FLICKER)
- input1_state_string = "FLICKER"
- else
- input1_state_string = "ERROR: UNKNOWN STATE"
-
- switch(input2_state)
- if(LOGIC_OFF)
- input2_state_string = "OFF"
- if(LOGIC_ON)
- input2_state_string = "ON"
- if(LOGIC_FLICKER)
- input2_state_string = "FLICKER"
- else
- input2_state_string = "ERROR: UNKNOWN STATE"
-
- switch(output_state)
- if(LOGIC_OFF)
- output_state_string = "OFF"
- if(LOGIC_ON)
- output_state_string = "ON"
- if(LOGIC_FLICKER)
- output_state_string = "FLICKER"
- else
- output_state_string = "ERROR: UNKNOWN STATE"
- var/menu_contents = {"
-
- - Input: [format_tag("ID Tag","input1_id_tag")]
- - Input State: [input1_state_string]
- "}
- if(!mono_input)
- menu_contents = {"
- - Input 1: [format_tag("ID Tag","input1_id_tag")]
- - Input 1 State: [input1_state_string]
- - Input 2: [format_tag("ID Tag","input2_id_tag")]
- - Input 2 State: [input2_state_string]
- "}
- menu_contents += {"
- - Output: [format_tag("ID Tag","output_id_tag")]
- - Output State: [output_state_string]
-
- "}
- return menu_contents
-
-/obj/machinery/logic_gate/convert/multitool_topic(var/mob/user,var/list/href_list,var/obj/O)
- ..()
- update_multitool_menu(user)
-
-/obj/machinery/logic_gate/attackby(obj/item/O, mob/user, params)
- if(tamperproof)
- to_chat(user, "The [src] appears to be tamperproofed! You can't interact with it!")
- return 0
- if(istype(O, /obj/item/multitool))
- update_multitool_menu(user)
- return 1
- if(istype(O, /obj/item/screwdriver))
- panel_open = !panel_open
- to_chat(user, "You [panel_open ? "open" : "close"] the access panel.")
- return 1
- if(panel_open && istype(O, /obj/item/crowbar))
- default_deconstruction_crowbar(user, O)
- return 1
- return ..()
-
-//////////////////////////////////////
-// Attack procs //
-//////////////////////////////////////
-
-/obj/machinery/logic_gate/attack_ai(mob/user)
- if(tamperproof)
- to_chat(user, "The [src] appears to be tamperproofed! You can't interface with it!")
- return 0
- add_hiddenprint(user)
- return ui_interact(user)
-
-/obj/machinery/logic_gate/attack_ghost(mob/user)
- if(tamperproof)
- to_chat(user, "The [src] appears to be tamperproofed! You can't haunt it!")
- return 0
- return ui_interact(user)
-
-/obj/machinery/logic_gate/attack_hand(mob/user)
- if(tamperproof)
- to_chat(user, "The [src] appears to be tamperproofed! You can't interact with it!")
- return 0
- . = ..()
- if(.)
- return 0
- return interact(user)
-
-/obj/machinery/logic_gate/attack_alien(mob/user) //No xeno logic, that's too silly.
- to_chat(user, "The [src] appears to be too complex! You can't comprehend it and back off in fear!")
- return 0
-
-/obj/machinery/logic_gate/attack_animal(mob/user) //No animal logic either.
- to_chat(user, "The [src] appears to be beyond your comprehension! You can't fathom it!")
- return 0
-
-/obj/machinery/logic_gate/attack_slime(mob/user) //No slime logic. Seriously.
- to_chat(user, "The [src] appears to be beyond your gelatinous understanding! You ignore it!")
- return 0
-
-/obj/machinery/logic_gate/emp_act(severity)
- if(tamperproof)
- return 0
- ..()
-
-/obj/machinery/logic_gate/ex_act(severity)
- if(tamperproof)
- return 0
- ..()
-
-/obj/machinery/logic_gate/blob_act(obj/structure/blob/B)
- if(!tamperproof)
- return ..()
-
-/obj/machinery/logic_gate/singularity_act()
- if(tamperproof)
- //This is some top-level tamperproofing right here, that's for sure. It can even defy a singularity!
- return 0
- ..()
-
-/obj/machinery/logic_gate/bullet_act()
- if(tamperproof)
- return 0
- ..()
-
-/obj/machinery/logic_gate/tesla_act(var/power)
- if(tamperproof)
- tesla_zap(src, 3, power) //If we're tamperproof, we'll just bounce the full shock of the tesla zap we got hit by, so it continues on normally without diminishing
- return 0
- ..()
diff --git a/code/modules/logic/mono_input.dm b/code/modules/logic/mono_input.dm
deleted file mode 100644
index 58b76232fa0..00000000000
--- a/code/modules/logic/mono_input.dm
+++ /dev/null
@@ -1,62 +0,0 @@
-
-//////////////////////////////////
-// Mono-Input Gates //
-//////////////////////////////////
-
-//NOT Gate
-/obj/machinery/logic_gate/not
- name = "NOT Gate"
- desc = "Accepts one input and outputs the reverse state."
- icon_state = "logic_not"
- mono_input = 1 //NOT Gates are the simplest logic gate because they only utilize one input.
- output_state = LOGIC_ON //Starts with an active output, since the input will be OFF at start
-/*
- A quick note regarding NOT Gates:
- - Connecting multiple things to the input of a NOT Gate can cause weird behaviour due to updating both when it receives a signal and when it calls process().
- - This means it will attempt to output once for every logic machine connected to its input's own process() call.
- - It will then attempt to output an additional time based on the current state when it comes to its own process() call.
- - For this reason, it is HIGHLY RECOMMENDED that you only connect a single signal source to the input of a NOT Gate to avoid signal spasms.
- - Connecting multiple things to the output of a NOT Gate should not cause this unusual behavior.
-*/
-/obj/machinery/logic_gate/not/handle_logic() //Our output will always be a continuous signal, even with a FLICKER, it just will update the output when the FLICKER ends
- if(input1_state == LOGIC_ON) //Output is OFF while input is ON
- output_state = LOGIC_OFF
- else if(input1_state == LOGIC_FLICKER) //Output is OFF while input is FLICKER, then output returns to ON when input returns to OFF
- output_state = LOGIC_OFF
- spawn(LOGIC_FLICKER_TIME + 1) //Call handle_logic again after this delay (the input should update from the spawn(LOGIC_FLICKER_TIME) in receive_signal() by then)
- handle_logic()
- else //Output is ON while input is OFF
- output_state = LOGIC_ON
- handle_output()
- return
-
-//STATUS Gate
-/obj/machinery/logic_gate/status
- name = "Status Gate"
- desc = "Accepts one input and outputs the same state, showing a colored light based on current state."
- icon_state = "logic_status"
- mono_input = 1 //STATUS Gate doesn't actually perform logic operations, but instead acts as a testing conduit.
-
-/*
- STATUS Gates are largely a diagnostics tool, but I'm sure someone will still make a logic gate rave with them anyways.
- - There is no need to actually connect an output for these to work, they just need an input to sample from.
- - STATUS Gates attempt to update their lights whenever they receive a signal.
-*/
-
-/obj/machinery/logic_gate/status/receive_signal(datum/signal/signal, receive_method, receive_params)
- ..()
- handle_logic() //STATUS Gate calls handle_logic() when it receives a signal to update its light and output_state
-
-/obj/machinery/logic_gate/status/handle_logic()
- output_state = input1_state //Output is equal to input, since it is simply a connection with an attached light
- if(output_state == LOGIC_OFF) //Red light when OFF
- set_light(2,2,"#ff0000")
- return
- if(output_state == LOGIC_ON) //Green light when ON
- set_light(2,2,"#009933")
- return
- if(output_state == LOGIC_FLICKER) //Orange light when FLICKER, then update after LOGIC_FLICKER_TIME + 1 to reflect the changed state
- set_light(2,2,"#ff9900")
- spawn(LOGIC_FLICKER_TIME + 1)
- handle_logic()
- return
diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm
index 64e7cba86cd..8969463be1d 100644
--- a/code/modules/martial_arts/martial.dm
+++ b/code/modules/martial_arts/martial.dm
@@ -195,6 +195,9 @@
icon = 'icons/obj/library.dmi'
icon_state = "cqcmanual"
+/obj/item/CQC_manual/chef
+ desc = "A small, black manual. Written on the back it says: Bringing the home advantage with you."
+
/obj/item/CQC_manual/attack_self(mob/living/carbon/human/user)
if(!istype(user) || !user)
return
@@ -227,7 +230,7 @@
/obj/item/twohanded/bostaff/attack(mob/target, mob/living/user)
add_fingerprint(user)
- if((CLUMSY in user.disabilities) && prob(50))
+ if((CLUMSY in user.mutations) && prob(50))
to_chat(user, "You club yourself over the head with [src].")
user.Weaken(3)
if(ishuman(user))
@@ -275,7 +278,6 @@
return
else
return ..()
- return ..()
/obj/item/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(wielded)
diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm
index 9b74c922a6b..044b78a04bc 100644
--- a/code/modules/mining/abandonedcrates.dm
+++ b/code/modules/mining/abandonedcrates.dm
@@ -82,7 +82,7 @@
new /obj/item/clothing/head/corgi(src)
if(67 to 68)
for(var/i in 1 to rand(4, 7))
- var /newitem = pick(subtypesof(/obj/item/stock_parts))
+ var/newitem = pick(subtypesof(/obj/item/stock_parts))
new newitem(src)
if(69 to 70)
new /obj/item/stack/ore/bluespace_crystal(src, 5)
diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm
index f21978db625..4af48e7050a 100644
--- a/code/modules/mining/equipment/kinetic_crusher.dm
+++ b/code/modules/mining/equipment/kinetic_crusher.dm
@@ -65,6 +65,8 @@
user.drop_l_hand()
return
var/datum/status_effect/crusher_damage/C = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
+ if(!C)
+ C = target.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
var/target_health = target.health
..()
for(var/t in trophies)
@@ -101,6 +103,8 @@
if(!CM || CM.hammer_synced != src || !L.remove_status_effect(STATUS_EFFECT_CRUSHERMARK))
return
var/datum/status_effect/crusher_damage/C = L.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
+ if(!C)
+ C = L.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
var/target_health = L.health
for(var/t in trophies)
var/obj/item/crusher_trophy/T = t
diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm
index 44462dedfda..43cce5904e3 100644
--- a/code/modules/mining/equipment/wormhole_jaunter.dm
+++ b/code/modules/mining/equipment/wormhole_jaunter.dm
@@ -26,7 +26,7 @@
/obj/item/wormhole_jaunter/proc/get_destinations(mob/user)
var/list/destinations = list()
- for(var/obj/item/radio/beacon/B in world)
+ for(var/obj/item/radio/beacon/B in GLOB.global_radios)
var/turf/T = get_turf(B)
if(is_station_level(T.z))
destinations += B
diff --git a/code/modules/mining/lavaland/loot/ashdragon_loot.dm b/code/modules/mining/lavaland/loot/ashdragon_loot.dm
index e9728bc7901..a0ea3eb7639 100644
--- a/code/modules/mining/lavaland/loot/ashdragon_loot.dm
+++ b/code/modules/mining/lavaland/loot/ashdragon_loot.dm
@@ -81,7 +81,7 @@
var/mob/dead/observer/current_spirits = list()
for(var/mob/dead/observer/O in GLOB.player_list)
- if((O.following in contents))
+ if((O.orbiting in contents))
ghost_counter++
O.invisibility = 0
current_spirits |= O
@@ -97,13 +97,13 @@
force = 0
var/ghost_counter = ghost_check()
- force = Clamp((ghost_counter * 4), 0, 75)
+ force = clamp((ghost_counter * 4), 0, 75)
user.visible_message("[user] strikes with the force of [ghost_counter] vengeful spirits!")
..()
/obj/item/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
var/ghost_counter = ghost_check()
- final_block_chance += Clamp((ghost_counter * 5), 0, 75)
+ final_block_chance += clamp((ghost_counter * 5), 0, 75)
owner.visible_message("[owner] is protected by a ring of [ghost_counter] ghosts!")
return ..()
diff --git a/code/modules/mining/lavaland/loot/bubblegum_loot.dm b/code/modules/mining/lavaland/loot/bubblegum_loot.dm
index fa7791edb9e..4ee2c76a419 100644
--- a/code/modules/mining/lavaland/loot/bubblegum_loot.dm
+++ b/code/modules/mining/lavaland/loot/bubblegum_loot.dm
@@ -82,7 +82,7 @@
B.mineEffect(L)
for(var/mob/living/carbon/human/H in GLOB.player_list)
- if(H == L)
+ if(H.stat == DEAD || H == L)
continue
to_chat(H, "You have an overwhelming desire to kill [L]. [L.p_they(TRUE)] [L.p_have()] been marked red! Go kill [L.p_them()]!")
H.put_in_hands(new /obj/item/kitchen/knife/butcher(H))
diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm
index ac4d6a1e551..0bde4d95464 100644
--- a/code/modules/mining/lavaland/loot/colossus_loot.dm
+++ b/code/modules/mining/lavaland/loot/colossus_loot.dm
@@ -306,7 +306,7 @@
if(H.stat == DEAD)
H.set_species(/datum/species/shadow)
H.revive()
- H.disabilities |= NOCLONE //Free revives, but significantly limits your options for reviving except via the crystal
+ H.mutations |= NOCLONE //Free revives, but significantly limits your options for reviving except via the crystal
H.grab_ghost(force = TRUE)
/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
@@ -458,7 +458,7 @@
if(isliving(A) && holder_animal)
var/mob/living/L = A
L.notransform = 1
- L.disabilities |= MUTE
+ L.mutations |= MUTE
L.status_flags |= GODMODE
L.mind.transfer_to(holder_animal)
var/obj/effect/proc_holder/spell/targeted/exit_possession/P = new /obj/effect/proc_holder/spell/targeted/exit_possession
@@ -468,7 +468,7 @@
/obj/structure/closet/stasis/dump_contents(var/kill = 1)
STOP_PROCESSING(SSobj, src)
for(var/mob/living/L in src)
- L.disabilities &= ~MUTE
+ L.mutations -=MUTE
L.status_flags &= ~GODMODE
L.notransform = 0
if(holder_animal && !QDELETED(holder_animal))
diff --git a/code/modules/mining/lavaland/loot/hierophant_loot.dm b/code/modules/mining/lavaland/loot/hierophant_loot.dm
index a3f6e738380..fc81e6399ae 100644
--- a/code/modules/mining/lavaland/loot/hierophant_loot.dm
+++ b/code/modules/mining/lavaland/loot/hierophant_loot.dm
@@ -93,7 +93,7 @@
blast_range = initial(blast_range)
if(isliving(user))
var/mob/living/L = user
- var/health_percent = L.health / L.maxHealth
+ var/health_percent = max(L.health / L.maxHealth, 0) // Don't go negative
chaser_cooldown += round(health_percent * 20) //two tenths of a second for each missing 10% of health
cooldown_time += round(health_percent * 10) //one tenth of a second for each missing 10% of health
chaser_speed = max(chaser_speed + health_percent, 0.5) //one tenth of a second faster for each missing 10% of health
diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm
index f54bc974f7e..0af08e40c74 100644
--- a/code/modules/mining/lavaland/loot/tendril_loot.dm
+++ b/code/modules/mining/lavaland/loot/tendril_loot.dm
@@ -383,7 +383,10 @@
var/mob/living/L = target
if(!L.anchored)
L.visible_message("[L] is snagged by [firer]'s hook!")
+ var/old_density = L.density
+ L.density = FALSE // Ensures the hook does not hit the target multiple times
L.forceMove(get_turf(firer))
+ L.density = old_density
/obj/item/projectile/hook/Destroy()
QDEL_NULL(chain)
diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm
index 50cb7d09801..579df861c19 100644
--- a/code/modules/mining/machine_processing.dm
+++ b/code/modules/mining/machine_processing.dm
@@ -98,7 +98,7 @@
/obj/machinery/mineral/processing_unit/Destroy()
CONSOLE = null
QDEL_NULL(files)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
return ..()
@@ -120,7 +120,7 @@
CONSOLE.updateUsrDialog()
/obj/machinery/mineral/processing_unit/proc/process_ore(obj/item/stack/ore/O)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/material_amount = materials.get_item_material_amount(O)
if(!materials.has_space(material_amount))
unload_mineral(O)
@@ -132,7 +132,7 @@
/obj/machinery/mineral/processing_unit/proc/get_machine_data()
var/dat = "Smelter control console
"
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
dat += "[M.name]: [M.amount] cm³"
@@ -165,7 +165,7 @@
return dat
/obj/machinery/mineral/processing_unit/proc/smelt_ore()
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/datum/material/mat = materials.materials[selected_material]
if(mat)
var/sheets_to_remove = (mat.amount >= (MINERAL_MATERIAL_AMOUNT * SMELT_AMOUNT) ) ? SMELT_AMOUNT : round(mat.amount / MINERAL_MATERIAL_AMOUNT)
@@ -187,7 +187,7 @@
on = FALSE
return
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.use_amount(alloy.materials, amount)
generate_mineral(alloy.build_path)
@@ -198,7 +198,7 @@
var/build_amount = SMELT_AMOUNT
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in D.materials)
var/M = D.materials[mat_id]
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index ed955efda2c..9630395e0cd 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -67,7 +67,7 @@
/obj/machinery/mineral/ore_redemption/Destroy()
QDEL_NULL(files)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
return ..()
@@ -92,7 +92,7 @@
if(O && O.refined_type)
points += O.points * point_upgrade * O.amount
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/material_amount = materials.get_item_material_amount(O)
if(!material_amount)
@@ -111,7 +111,7 @@
var/build_amount = 0
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in D.materials)
var/M = D.materials[mat_id]
var/datum/material/redemption_mat = materials.materials[mat_id]
@@ -147,7 +147,7 @@
var/has_minerals = FALSE
var/mineral_name = null
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
var/mineral_amount = M.amount / MINERAL_MATERIAL_AMOUNT
@@ -221,7 +221,7 @@
. = TRUE
if(!powered())
return
- if(!I.tool_start_check(user, 0))
+ if(!I.tool_start_check(src, user, 0))
return
input_dir = turn(input_dir, -90)
output_dir = turn(output_dir, -90)
@@ -251,7 +251,7 @@
else
dat += "No ID inserted. Insert ID.
"
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
if(M.amount)
@@ -302,7 +302,7 @@
/obj/machinery/mineral/ore_redemption/Topic(href, href_list)
if(..())
return
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(href_list["eject_id"])
usr.put_in_hands(inserted_id)
inserted_id = null
diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm
index 1198e2fb9d3..dbaa24fef34 100644
--- a/code/modules/mining/minebot.dm
+++ b/code/modules/mining/minebot.dm
@@ -101,7 +101,7 @@
if(user.a_intent != INTENT_HELP)
return
. = TRUE
- if(!I.tool_start_check(user, 0))
+ if(!I.tool_start_check(src, user, 0))
return
I.melee_attack_chain(user, stored_gun)
diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm
index 9fb73229ba7..9cabe4ac486 100644
--- a/code/modules/mining/mint.dm
+++ b/code/modules/mining/mint.dm
@@ -23,7 +23,7 @@
if(!T)
return
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/obj/item/stack/sheet/O in T)
materials.insert_stack(O, O.amount)
@@ -32,7 +32,7 @@
return
var/dat = "Coin Press "
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
if(!M.amount && chosen != mat_id)
@@ -65,12 +65,12 @@
if(processing == 1)
to_chat(usr, "The machine is processing.")
return
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(href_list["choose"])
if(materials.materials[href_list["choose"]])
chosen = href_list["choose"]
if(href_list["chooseAmt"])
- coinsToProduce = Clamp(coinsToProduce + text2num(href_list["chooseAmt"]), 0, 1000)
+ coinsToProduce = clamp(coinsToProduce + text2num(href_list["chooseAmt"]), 0, 1000)
if(href_list["makeCoins"])
var/temp_coins = coinsToProduce
processing = TRUE
diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm
index 8737fdf21b3..c01d04beba8 100644
--- a/code/modules/mining/ores_coins.dm
+++ b/code/modules/mining/ores_coins.dm
@@ -273,7 +273,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
icon_state = "Gibtonite active"
var/turf/bombturf = get_turf(src)
var/notify_admins = 0
- if(z != 5)//Only annoy the admins ingame if we're triggered off the mining zlevel
+ if(!is_mining_level(z))//Only annoy the admins ingame if we're triggered off the mining zlevel
notify_admins = 1
if(notify_admins)
diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm
index 39931a60fb2..090e5ddac1e 100644
--- a/code/modules/mob/camera/camera.dm
+++ b/code/modules/mob/camera/camera.dm
@@ -14,3 +14,8 @@
/mob/camera/experience_pressure_difference()
return
+
+/mob/camera/forceMove(atom/destination)
+ var/oldloc = loc
+ loc = destination
+ Moved(oldloc, NONE)
diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm
index 24f129ee387..f60777a97ff 100644
--- a/code/modules/mob/dead/dead.dm
+++ b/code/modules/mob/dead/dead.dm
@@ -15,7 +15,7 @@
onTransitZ(old_turf?.z, new_turf?.z)
var/oldloc = loc
loc = destination
- Moved(oldloc, NONE, TRUE)
+ Moved(oldloc, NONE)
/mob/dead/onTransitZ(old_z,new_z)
..()
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 91a57e1ccbe..336ebdb8b67 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -23,7 +23,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
//If you died in the game and are a ghsot - this will remain as null.
//Note that this is not a reliable way to determine if admins started as observers, since they change mobs a lot.
universal_speak = TRUE
- var/atom/movable/following = null
var/image/ghostimage = null //this mobs ghost image, for deleting and stuff
var/ghostvision = TRUE //is the ghost able to see things humans can't?
var/seedarkness = TRUE
@@ -91,10 +90,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
..()
/mob/dead/observer/Destroy()
- if(ismob(following))
- var/mob/M = following
- M.following_mobs -= src
- following = null
if(ghostimage)
GLOB.ghost_images -= ghostimage
QDEL_NULL(ghostimage)
@@ -142,13 +137,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
Transfer_mind is there to check if mob is being deleted/not going to have a body.
Works together with spawning an observer, noted above.
*/
-/mob/dead/observer/Life(seconds, times_fired)
- ..()
- if(!loc) return
- if(!client) return 0
-
-
-
/mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U)
var/client/C = U.client
for(var/mob/living/carbon/human/target in target_list)
@@ -241,7 +229,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/Move(NewLoc, direct)
update_parallax_contents()
- following = null
setDir(direct)
ghostimage.setDir(dir)
@@ -423,7 +410,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
forceMove(pick(L))
update_parallax_contents()
- following = null
/mob/dead/observer/verb/follow()
set category = "Ghost"
@@ -435,7 +421,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
A.on_close(CALLBACK(src, .proc/ManualFollow))
// This is the ghost's follow verb with an argument
-/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
+/mob/dead/observer/proc/ManualFollow(atom/movable/target)
if(!target || !isobserver(usr))
return
@@ -443,7 +429,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
if(target != src)
- if(following && following == target)
+ if(orbiting && orbiting == target)
return
var/icon/I = icon(target.icon,target.icon_state,target.dir)
@@ -469,7 +455,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
else //Circular
rot_seg = 36 //360/10 bby, smooth enough aproximation of a circle
- following = target
to_chat(src, "Now following [target]")
orbit(target,orbitsize, FALSE, 20, rot_seg)
@@ -477,28 +462,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
setDir(2)//reset dir so the right directional sprites show up
return ..()
-/mob/proc/update_following()
- . = get_turf(src)
- for(var/mob/dead/observer/M in following_mobs)
- if(M.following != src)
- following_mobs -= M
- else
- if(M.loc != .)
- M.forceMove(.)
-
-/mob
- var/list/following_mobs = list()
-
-/mob/Move()
- . = ..()
- if(.)
- update_following()
-
-/mob/Life(seconds, times_fired)
- // to catch teleports etc which directly set loc
- update_following()
- return ..()
-
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
set category = "Ghost"
set name = "Jump to Mob"
@@ -518,7 +481,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
A.forceMove(T)
M.update_parallax_contents()
- following = null
return
to_chat(A, "This mob is not located in the game world.")
@@ -649,7 +611,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/Topic(href, href_list)
if(usr != src)
return
- ..()
if(href_list["track"])
var/atom/target = locate(href_list["track"])
@@ -663,7 +624,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(href_list["jump"])
var/mob/target = locate(href_list["jump"])
- var/mob/A = usr;
+ var/mob/A = usr
to_chat(A, "Teleporting to [target]...")
//var/mob/living/silicon/ai/A = locate(href_list["track2"]) in GLOB.mob_list
if(target && target != usr)
@@ -676,7 +637,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(!client)
return
forceMove(T)
- following = null
if(href_list["reenter"])
reenter_corpse()
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index 5f18a27adc9..99e0af0ca6a 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -135,7 +135,7 @@
if(message)
for(var/mob/M in GLOB.player_list)
- if(istype(M, /mob/new_player))
+ if(isnewplayer(M))
continue
if(check_rights(R_ADMIN|R_MOD, 0, M) && M.get_preference(CHAT_DEAD)) // Show the emote to admins/mods
diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm
index ee9a3c3cca2..f89d19afaac 100644
--- a/code/modules/mob/holder.dm
+++ b/code/modules/mob/holder.dm
@@ -22,7 +22,6 @@
var/atom/movable/mob_container
mob_container = M
mob_container.forceMove(get_turf(src))
- M.reset_perspective()
qdel(src)
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 6d96d77c321..8f4f4dbb2da 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -214,9 +214,9 @@
if(M.equip_to_appropriate_slot(src))
if(M.hand)
- M.update_inv_l_hand(0)
+ M.update_inv_l_hand()
else
- M.update_inv_r_hand(0)
+ M.update_inv_r_hand()
return 1
if(M.s_active && M.s_active.can_be_inserted(src, 1)) //if storage active insert there
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index 8445dec51ee..a46268daf50 100644
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -33,7 +33,7 @@
for(var/i = 0;i0;x--)
+ for(var/x = rand(FLOOR(syllable_count/2, 1),syllable_count);x>0;x--)
new_name += pick(syllables)
full_name += " [capitalize(lowertext(new_name))]"
@@ -619,7 +619,7 @@
var/message_start_dead = "[name], [speaker.name] ([ghost_follow_link(speaker, ghost=M)])"
M.show_message("[message_start_dead] [message_body]", 2)
- for(var/mob/living/S in GLOB.living_mob_list)
+ for(var/mob/living/S in GLOB.alive_mob_list)
if(drone_only && !istype(S,/mob/living/silicon/robot/drone))
continue
else if(isAI(S))
@@ -767,17 +767,6 @@
desc = "Bark bark bark."
key = "vu"
-/datum/language/zombie
- name = "Zombie"
- desc = "BRAAAAAAINS!"
- speech_verb = "moans"
- whisper_verb = "mutters"
- exclaim_verb = "wails"
- colour = "zombie"
- key = "zom"
- flags = RESTRICTED
- syllables = list("BRAAAAAAAAAAAAAAAAINS", "BRAAINS", "BRAINS")
-
/mob/proc/grant_all_babel_languages()
for(var/la in GLOB.all_languages)
var/datum/language/new_language = GLOB.all_languages[la]
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index 1b85c3e5386..f6354b61940 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -2,6 +2,7 @@
name = "alien"
voice_name = "alien"
speak_emote = list("hisses")
+ bubble_icon = "alien"
icon = 'icons/mob/alien.dmi'
gender = NEUTER
dna = null
@@ -26,6 +27,8 @@
var/death_sound = 'sound/voice/hiss6.ogg'
/mob/living/carbon/alien/New()
+ ..()
+ create_reagents(1000)
verbs += /mob/living/verb/mob_sleep
verbs += /mob/living/verb/lay_down
alien_organs += new /obj/item/organ/internal/brain/xeno
@@ -33,7 +36,6 @@
alien_organs += new /obj/item/organ/internal/ears
for(var/obj/item/organ/internal/I in alien_organs)
I.insert(src)
- ..()
/mob/living/carbon/alien/get_default_language()
if(default_language)
@@ -67,18 +69,6 @@
/mob/living/carbon/alien/check_eye_prot()
return 2
-/mob/living/carbon/alien/updatehealth(reason = "none given")
- if(status_flags & GODMODE)
- health = maxHealth
- stat = CONSCIOUS
- return
- health = maxHealth - getOxyLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
-
- update_stat("updatehealth([reason])")
- med_hud_set_health()
- med_hud_set_status()
- handle_hud_icons_health()
-
/mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment)
if(!environment)
@@ -118,12 +108,6 @@
else
clear_alert("alien_fire")
-/mob/living/carbon/alien/handle_fire()//Aliens on fire code
- if(..())
- return
- bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up!
- return
-
/mob/living/carbon/alien/IsAdvancedToolUser()
return has_fine_manipulation
@@ -243,7 +227,7 @@ Des: Removes all infected images from the alien.
/mob/living/carbon/alien/handle_footstep(turf/T)
if(..())
- if(T.footstep_sounds["xeno"])
+ if(T.footstep_sounds && T.footstep_sounds["xeno"])
var/S = pick(T.footstep_sounds["xeno"])
if(S)
if(m_intent == MOVE_INTENT_RUN)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index 1ea256357e9..58bdb3a9ecc 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -136,14 +136,11 @@ Doesn't work on other aliens/AI.*/
set category = "Alien"
if(powerc())
- if(stomach_contents.len)
+ if(LAZYLEN(stomach_contents))
for(var/mob/M in src)
- if(M in stomach_contents)
- stomach_contents.Remove(M)
- M.forceMove(loc)
- //Paralyse(10)
- src.visible_message("[src] hurls out the contents of [p_their()] stomach!")
- return
+ LAZYREMOVE(stomach_contents, M)
+ M.forceMove(drop_location())
+ visible_message("[src] hurls out the contents of [p_their()] stomach!")
/mob/living/carbon/proc/getPlasma()
var/obj/item/organ/internal/xenos/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/xenos/plasmavessel)
@@ -167,4 +164,4 @@ Doesn't work on other aliens/AI.*/
adjustPlasma(-amount)
return 1
- return 0
+ return 0
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
index 2d894ee357e..99900183185 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
@@ -6,7 +6,6 @@
icon_state = "aliend_s"
/mob/living/carbon/alien/humanoid/drone/New()
- create_reagents(100)
if(src.name == "alien drone")
src.name = text("alien drone ([rand(1, 1000)])")
src.real_name = src.name
@@ -26,7 +25,7 @@
if(powerc(500))
// Queen check
var/no_queen = 1
- for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.living_mob_list)
+ for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.alive_mob_list)
if(!Q.key && Q.get_int_organ(/obj/item/organ/internal/brain/))
continue
no_queen = 0
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
index 73931aa7be9..f23f9b7aa42 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
@@ -6,7 +6,6 @@
icon_state = "alienh_s"
/mob/living/carbon/alien/humanoid/hunter/New()
- create_reagents(100)
if(name == "alien hunter")
name = text("alien hunter ([rand(1, 1000)])")
real_name = name
@@ -17,28 +16,6 @@
. = -1 //hunters are sanic
. += ..() //but they still need to slow down on stun
-/mob/living/carbon/alien/humanoid/hunter/handle_hud_icons_health()
- ..() //-Yvarov
-
- if(healths)
- if(stat != 2)
- switch(health)
- if(125 to INFINITY)
- healths.icon_state = "health0"
- if(100 to 125)
- healths.icon_state = "health1"
- if(50 to 100)
- healths.icon_state = "health2"
- if(25 to 50)
- healths.icon_state = "health3"
- if(0 to 25)
- healths.icon_state = "health4"
- else
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
-
-
/mob/living/carbon/alien/humanoid/hunter/handle_environment()
if(m_intent == MOVE_INTENT_RUN || resting)
..()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
index c436a43e4ff..4dd2d1b8569 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
@@ -33,7 +33,6 @@
overlays += I
/mob/living/carbon/alien/humanoid/sentinel/New()
- create_reagents(100)
if(name == "alien sentinel")
name = text("alien sentinel ([rand(1, 1000)])")
real_name = name
@@ -42,27 +41,6 @@
alien_organs += new /obj/item/organ/internal/xenos/neurotoxin
..()
-/mob/living/carbon/alien/humanoid/sentinel/handle_hud_icons_health()
- ..() //-Yvarov
-
- if(healths)
- if(stat != 2)
- switch(health)
- if(150 to INFINITY)
- healths.icon_state = "health0"
- if(100 to 150)
- healths.icon_state = "health1"
- if(75 to 100)
- healths.icon_state = "health2"
- if(25 to 75)
- healths.icon_state = "health3"
- if(0 to 25)
- healths.icon_state = "health4"
- else
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
-
/*
/mob/living/carbon/alien/humanoid/sentinel/verb/evolve() // -- TLE
set name = "Evolve (250)"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/empress.dm b/code/modules/mob/living/carbon/alien/humanoid/empress.dm
index a64602d030c..a28b3f33a53 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/empress.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/empress.dm
@@ -6,6 +6,7 @@
icon_state = "alienq_s"
status_flags = CANPARALYSE
mob_size = MOB_SIZE_LARGE
+ bubble_icon = "alienroyal"
large = 1
ventcrawler = 0
@@ -30,17 +31,17 @@
overlays += I
/mob/living/carbon/alien/humanoid/empress/New()
- create_reagents(100)
-
//there should only be one queen
- for(var/mob/living/carbon/alien/humanoid/empress/E in GLOB.living_mob_list)
- if(E == src) continue
- if(E.stat == DEAD) continue
+ for(var/mob/living/carbon/alien/humanoid/empress/E in GLOB.alive_mob_list)
+ if(E == src)
+ continue
+ if(E.stat == DEAD)
+ continue
if(E.client)
name = "alien grand princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it.
break
- real_name = src.name
+ real_name = name
alien_organs += new /obj/item/organ/internal/xenos/plasmavessel/queen
alien_organs += new /obj/item/organ/internal/xenos/acidgland
alien_organs += new /obj/item/organ/internal/xenos/eggsac
@@ -48,27 +49,6 @@
alien_organs += new /obj/item/organ/internal/xenos/neurotoxin
..()
-/mob/living/carbon/alien/humanoid/empress/handle_hud_icons_health()
- ..() //-Yvarov
-
- if(healths)
- if(stat != 2)
- switch(health)
- if(250 to INFINITY)
- healths.icon_state = "health0"
- if(175 to 250)
- healths.icon_state = "health1"
- if(100 to 175)
- healths.icon_state = "health2"
- if(50 to 100)
- healths.icon_state = "health3"
- if(0 to 50)
- healths.icon_state = "health4"
- else
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
-
/mob/living/carbon/alien/humanoid/empress/verb/lay_egg()
set name = "Lay Egg (250)"
set desc = "Lay an egg to produce huggers to impregnate prey with."
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index 63f6d3dcea9..e82488ee064 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -17,7 +17,6 @@
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/humanoid/New()
- create_reagents(1000)
if(name == "alien")
name = text("alien ([rand(1, 1000)])")
real_name = name
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
index e7f783acd72..3174879caac 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
@@ -55,7 +55,7 @@
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("[M] has attempted to disarm [src]!")
-/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
+/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
if(!no_effect && !visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_CLAW
..()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm
index 646f069970b..071987f808e 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/life.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm
@@ -2,27 +2,6 @@
. = ..()
update_icons()
-
-
-/mob/living/carbon/alien/humanoid/handle_disabilities()
- if(disabilities & EPILEPSY)
- if((prob(1) && paralysis < 10))
- to_chat(src, "You have a seizure!")
- Paralyse(10)
- if(disabilities & COUGHING)
- if((prob(5) && paralysis <= 1))
- drop_item()
- emote("cough")
- return
- if(disabilities & TOURETTES)
- if((prob(10) && paralysis <= 1))
- Stun(10)
- emote("twitch")
- return
- if(disabilities & NERVOUS)
- if(prob(10))
- stuttering = max(10, stuttering)
-
/mob/living/carbon/alien/humanoid/proc/adjust_body_temperature(current, loc_temp, boost)
var/temperature = current
var/difference = abs(current-loc_temp) //get difference
@@ -39,51 +18,3 @@
temperature = max(loc_temp, temperature-change)
temp_change = (temperature - current)
return temp_change
-
-/mob/living/carbon/alien/humanoid/handle_regular_status_updates()
- updatehealth()
-
- if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
- SetSilence(0)
- else //ALIVE. LIGHTS ARE ON
- if(health < HEALTH_THRESHOLD_DEAD && check_death_method() || !get_int_organ(/obj/item/organ/internal/brain))
- death()
- SetSilence(0)
- return 1
-
- //UNCONSCIOUS. NO-ONE IS HOME
- if((getOxyLoss() > 50) || (HEALTH_THRESHOLD_CRIT >= health && check_death_method()))
- if(health <= 20 && prob(1))
- emote("gasp")
- if(!reagents.has_reagent("epinephrine"))
- adjustOxyLoss(1)
- Paralyse(3)
-
- if(paralysis)
- stat = UNCONSCIOUS
- else if(sleeping)
- stat = UNCONSCIOUS
- if(prob(10) && health)
- emote("hiss")
- //CONSCIOUS
- else
- stat = CONSCIOUS
-
- /* What in the living hell is this?*/
- if(move_delay_add > 0)
- move_delay_add = max(0, move_delay_add - rand(1, 2))
-
- if(eye_blind) //blindness, heals slowly over time
- AdjustEyeBlind(-1)
- else if(eye_blurry) //blurry eyes heal slowly
- AdjustEyeBlurry(-1)
-
- if(stuttering)
- AdjustStuttering(-1)
-
- if(silent)
- AdjustSilence(-1)
-
- if(druggy)
- AdjustDruggy(-1)
- return 1
diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
index 9390885c558..3adb87ad505 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
@@ -11,12 +11,12 @@
pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
/mob/living/carbon/alien/humanoid/queen/New()
- create_reagents(100)
-
//there should only be one queen
- for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.living_mob_list)
- if(Q == src) continue
- if(Q.stat == DEAD) continue
+ for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.alive_mob_list)
+ if(Q == src)
+ continue
+ if(Q.stat == DEAD)
+ continue
if(Q.client)
name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it.
break
@@ -33,27 +33,6 @@
. = ..()
. += 3
-/mob/living/carbon/alien/humanoid/queen/handle_hud_icons_health()
- ..() //-Yvarov
-
- if(healths)
- if(stat != DEAD)
- switch(health)
- if(250 to INFINITY)
- healths.icon_state = "health0"
- if(175 to 250)
- healths.icon_state = "health1"
- if(100 to 175)
- healths.icon_state = "health2"
- if(50 to 100)
- healths.icon_state = "health3"
- if(0 to 50)
- healths.icon_state = "health4"
- else
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
-
/mob/living/carbon/alien/humanoid/queen/can_inject(mob/user, error_msg, target_zone, penetrate_thick)
return FALSE
diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
index 4776f32596a..94c65095f01 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
@@ -56,13 +56,14 @@
/mob/living/carbon/alien/humanoid/regenerate_icons()
..()
- if(notransform) return
+ if(notransform)
+ return
- update_inv_head(0,0)
- update_inv_wear_suit(0,0)
- update_inv_r_hand(0)
- update_inv_l_hand(0)
- update_inv_pockets(0)
+ update_inv_head()
+ update_inv_wear_suit()
+ update_inv_r_hand()
+ update_inv_l_hand()
+ update_inv_pockets()
update_icons()
update_fire()
update_transform()
@@ -82,7 +83,7 @@
else
overlays_standing[X_FIRE_LAYER] = null
-/mob/living/carbon/alien/humanoid/update_inv_wear_suit(var/update_icons=1)
+/mob/living/carbon/alien/humanoid/update_inv_wear_suit()
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_suit]
inv.update_icon()
@@ -110,10 +111,10 @@
overlays_standing[X_SUIT_LAYER] = standing
else
overlays_standing[X_SUIT_LAYER] = null
- if(update_icons) update_icons()
+ update_icons()
-/mob/living/carbon/alien/humanoid/update_inv_head(var/update_icons=1)
+/mob/living/carbon/alien/humanoid/update_inv_head()
if(head)
var/t_state = head.item_state
if(!t_state) t_state = head.icon_state
@@ -124,17 +125,19 @@
overlays_standing[X_HEAD_LAYER] = standing
else
overlays_standing[X_HEAD_LAYER] = null
- if(update_icons) update_icons()
+ update_icons()
-/mob/living/carbon/alien/humanoid/update_inv_pockets(var/update_icons=1)
- if(l_store) l_store.screen_loc = ui_storage1
- if(r_store) r_store.screen_loc = ui_storage2
- if(update_icons) update_icons()
+/mob/living/carbon/alien/humanoid/update_inv_pockets()
+ if(l_store)
+ l_store.screen_loc = ui_storage1
+ if(r_store)
+ r_store.screen_loc = ui_storage2
+ update_icons()
-/mob/living/carbon/alien/humanoid/update_inv_r_hand(var/update_icons=1)
- ..(1)
+/mob/living/carbon/alien/humanoid/update_inv_r_hand()
+ ..()
if(r_hand)
var/t_state = r_hand.item_state
if(!t_state) t_state = r_hand.icon_state
@@ -142,10 +145,10 @@
overlays_standing[X_R_HAND_LAYER] = image("icon" = r_hand.righthand_file, "icon_state" = t_state)
else
overlays_standing[X_R_HAND_LAYER] = null
- if(update_icons) update_icons()
+ update_icons()
-/mob/living/carbon/alien/humanoid/update_inv_l_hand(var/update_icons=1)
- ..(1)
+/mob/living/carbon/alien/humanoid/update_inv_l_hand()
+ ..()
if(l_hand)
var/t_state = l_hand.item_state
if(!t_state) t_state = l_hand.icon_state
@@ -153,7 +156,7 @@
overlays_standing[X_L_HAND_LAYER] = image("icon" = l_hand.lefthand_file, "icon_state" = t_state)
else
overlays_standing[X_L_HAND_LAYER] = null
- if(update_icons) update_icons()
+ update_icons()
//Xeno Overlays Indexes//////////
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index a55126ec045..aeee677b905 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -5,8 +5,8 @@
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
- maxHealth = 30
- health = 30
+ maxHealth = 25
+ health = 25
density = 0
var/amount_grown = 0
@@ -17,7 +17,6 @@
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/larva/New()
- create_reagents(100)
if(name == "alien larva")
name = "alien larva ([rand(1, 1000)])"
real_name = name
@@ -25,7 +24,6 @@
add_language("Xenomorph")
add_language("Hivemind")
alien_organs += new /obj/item/organ/internal/xenos/plasmavessel/larva
-
..()
//This needs to be fixed
diff --git a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm
index 69e12b6ae19..d13dab884b2 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm
@@ -31,7 +31,7 @@
step_away(src, user, 15)
return TRUE
-/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
+/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
if(!no_effect && !visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_BITE
..()
diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm
index fd1543673e6..7acf07f4471 100644
--- a/code/modules/mob/living/carbon/alien/larva/life.dm
+++ b/code/modules/mob/living/carbon/alien/larva/life.dm
@@ -1,57 +1,28 @@
/mob/living/carbon/alien/larva/Life(seconds, times_fired)
- if(..()) //still breathing
+ set invisibility = 0
+ if(notransform)
+ return
+ if(..()) //not dead and not in stasis
// GROW!
if(amount_grown < max_grown)
amount_grown++
+ update_icons()
- //some kind of bug in canmove() isn't properly calling update_icons, so this is here as a placeholder
- update_icons()
-
-/mob/living/carbon/alien/larva/handle_regular_status_updates()
- updatehealth()
-
- if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
- SetSilence(0)
- else //ALIVE. LIGHTS ARE ON
- if(health < -25 || !get_int_organ(/obj/item/organ/internal/brain))
+/mob/living/carbon/alien/larva/update_stat(reason = "None given")
+ if(status_flags & GODMODE)
+ return
+ if(stat != DEAD)
+ if(health <= -maxHealth || !get_int_organ(/obj/item/organ/internal/brain))
death()
- SetSilence(0)
- return 1
+ return
- //UNCONSCIOUS. NO-ONE IS HOME
- if((getOxyLoss() > 25) || (HEALTH_THRESHOLD_CRIT >= health && check_death_method()))
- //if( health <= 20 && prob(1) )
- // spawn(0)
- // emote("gasp")
- if(!reagents.has_reagent("epinephrine"))
- adjustOxyLoss(1)
- Paralyse(3)
-
- if(paralysis)
- stat = UNCONSCIOUS
- else if(sleeping)
- stat = UNCONSCIOUS
- if(prob(10) && health)
- emote("hiss_")
- //CONSCIOUS
+ if(paralysis || sleeping || getOxyLoss() > 50 || (health <= HEALTH_THRESHOLD_CRIT && check_death_method()))
+ if(stat == CONSCIOUS)
+ KnockOut()
+ create_debug_log("fell unconscious, trigger reason: [reason]")
else
- stat = CONSCIOUS
-
- /* What in the living hell is this?*/
- if(move_delay_add > 0)
- move_delay_add = max(0, move_delay_add - rand(1, 2))
-
- if(eye_blind) //blindness, heals slowly over time
- AdjustEyeBlind(-1)
- else if(eye_blurry) //blurry eyes heal slowly
- AdjustEyeBlurry(-1)
-
- if(stuttering)
- AdjustStuttering(-1)
-
- if(silent)
- AdjustSilence(-1)
-
- if(druggy)
- AdjustDruggy(-1)
- return 1
+ if(stat == UNCONSCIOUS)
+ WakeUp()
+ create_debug_log("woke up, trigger reason: [reason]")
+ update_damage_hud()
+ update_health_hud()
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index a584f66dc97..5a1d08a010a 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -28,3 +28,15 @@
//BREATH TEMPERATURE
handle_breath_temperature(breath)
+
+/mob/living/carbon/alien/handle_status_effects()
+ ..()
+ //natural reduction of movement delay due to stun.
+ if(move_delay_add > 0)
+ move_delay_add = max(0, move_delay_add - rand(1, 2))
+
+/mob/living/carbon/alien/handle_fire()//Aliens on fire code
+ . = ..()
+ if(.) //if the mob isn't on fire anymore
+ return
+ adjust_bodytemperature(BODYTEMP_HEATING_MAX) //If you're on fire, you heat up!
diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm
index 5b80f6d032f..1dcd76c0358 100644
--- a/code/modules/mob/living/carbon/alien/special/facehugger.dm
+++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm
@@ -146,7 +146,7 @@
"[src] tears [W] off of [target]'s face!")
src.loc = target
- target.equip_to_slot(src, slot_wear_mask,,0)
+ target.equip_to_slot_if_possible(src, slot_wear_mask, FALSE, TRUE)
if(!sterile)
M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index 130a2e3a574..16014e7c353 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -49,7 +49,7 @@
brainmob.stat = CONSCIOUS
GLOB.respawnable_list -= brainmob
GLOB.dead_mob_list -= brainmob//Update dem lists
- GLOB.living_mob_list += brainmob
+ GLOB.alive_mob_list += brainmob
held_brain = B
if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff
@@ -157,7 +157,7 @@
brainmob.container = null//Reset brainmob mmi var.
brainmob.forceMove(held_brain) //Throw mob into brain.
GLOB.respawnable_list += brainmob
- GLOB.living_mob_list -= brainmob//Get outta here
+ GLOB.alive_mob_list -= brainmob//Get outta here
held_brain.brainmob = brainmob//Set the brain to use the brainmob
held_brain.brainmob.cancel_camera()
brainmob = null//Set mmi brainmob var to null
diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm
index ec80d6a44b4..386d5ae138f 100644
--- a/code/modules/mob/living/carbon/brain/brain.dm
+++ b/code/modules/mob/living/carbon/brain/brain.dm
@@ -7,9 +7,8 @@
icon_state = "brain1"
/mob/living/carbon/brain/New()
- create_reagents(330)
- add_language("Galactic Common")
..()
+ add_language("Galactic Common")
/mob/living/carbon/brain/Destroy()
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index 0b6bcededaf..93f31d0128c 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -26,11 +26,9 @@
mmi_icon = 'icons/mob/alien.dmi'
mmi_icon_state = "AlienMMI"
-/obj/item/organ/internal/brain/New()
- ..()
- spawn(5)
- if(brainmob && brainmob.client)
- brainmob.client.screen.len = null //clear the hud
+/obj/item/organ/internal/brain/Destroy()
+ QDEL_NULL(brainmob)
+ return ..()
/obj/item/organ/internal/brain/proc/transfer_identity(var/mob/living/carbon/H)
brainmob = new(src)
@@ -72,7 +70,7 @@
if(istype(owner,/mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
- H.update_hair(1)
+ H.update_hair()
. = ..()
/obj/item/organ/internal/brain/insert(var/mob/living/target,special = 0)
@@ -84,7 +82,7 @@
brain_already_exists = 1
var/mob/living/carbon/human/H = target
- H.update_hair(1)
+ H.update_hair()
if(!brain_already_exists)
if(brainmob)
diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm
index 6bd88e5e111..0faa238190e 100644
--- a/code/modules/mob/living/carbon/brain/life.dm
+++ b/code/modules/mob/living/carbon/brain/life.dm
@@ -28,13 +28,11 @@
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
adjustFireLoss(5.0*discomfort)
-/mob/living/carbon/brain/handle_regular_status_updates()
+/mob/living/carbon/brain/Life()
. = ..()
-
if(.)
- if(!container && (health < HEALTH_THRESHOLD_DEAD && check_death_method() || ((world.time - timeofhostdeath) > config.revival_brain_life)))
+ if(!container && (world.time - timeofhostdeath) > config.revival_brain_life)
death()
- return 0
/mob/living/carbon/brain/breathe()
return
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 3efcc7a9ce9..98585262518 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -2,6 +2,10 @@
var/canEnterVentWith = "/obj/item/implant=0&/obj/item/clothing/mask/facehugger=0&/obj/item/radio/borg=0&/obj/machinery/camera=0"
var/datum/middleClickOverride/middleClickOverride = null
+/mob/living/carbon/Initialize(mapload)
+ . = ..()
+ GLOB.carbon_list += src
+
/mob/living/carbon/Destroy()
// This clause is here due to items falling off from limb deletion
for(var/obj/item in get_all_slots())
@@ -14,11 +18,11 @@
if(B)
B.leave_host()
qdel(B)
+ GLOB.carbon_list -= src
return ..()
/mob/living/carbon/handle_atom_del(atom/A)
- if(A in processing_patches)
- processing_patches -= A
+ LAZYREMOVE(processing_patches, A)
return ..()
/mob/living/carbon/blob_act(obj/structure/blob/B)
@@ -46,41 +50,40 @@
/mob/living/carbon/var/last_stomach_attack //defining this here because no one would look in carbon_defines for it
-/mob/living/carbon/relaymove(var/mob/user, direction)
- if(user in src.stomach_contents)
- if(last_stomach_attack + STOMACH_ATTACK_DELAY > world.time) return
+/mob/living/carbon/relaymove(mob/user, direction)
+ if(LAZYLEN(stomach_contents))
+ if(user in stomach_contents)
+ if(last_stomach_attack + STOMACH_ATTACK_DELAY > world.time)
+ return
- last_stomach_attack = world.time
- for(var/mob/M in hearers(4, src))
- if(M.client)
- M.show_message(text("You hear something rumbling inside [src]'s stomach..."), 2)
-
- var/obj/item/I = user.get_active_hand()
- if(I && I.force)
- var/d = rand(round(I.force / 4), I.force)
-
- if(istype(src, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = src
- var/obj/item/organ/external/organ = H.get_organ("chest")
- if(istype(organ))
- if(organ.receive_damage(d, 0))
- H.UpdateDamageIcon()
-
- H.updatehealth("stomach attack")
-
- else
- src.take_organ_damage(d)
-
- for(var/mob/M in viewers(user, null))
+ last_stomach_attack = world.time
+ for(var/mob/M in hearers(4, src))
if(M.client)
- M.show_message(text("[user] attacks [src]'s stomach wall with the [I.name]!"), 2)
- playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
+ M.show_message(text("You hear something rumbling inside [src]'s stomach..."), 2)
- if(prob(src.getBruteLoss() - 50))
- for(var/atom/movable/A in stomach_contents)
- A.forceMove(drop_location())
- stomach_contents.Remove(A)
- src.gib()
+ var/obj/item/I = user.get_active_hand()
+ if(I && I.force)
+ var/d = rand(round(I.force / 4), I.force)
+
+ if(istype(src, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = src
+ var/obj/item/organ/external/organ = H.get_organ("chest")
+ if(istype(organ))
+ if(organ.receive_damage(d, 0))
+ H.UpdateDamageIcon()
+
+ H.updatehealth("stomach attack")
+
+ else
+ take_organ_damage(d)
+
+ for(var/mob/M in viewers(user, null))
+ if(M.client)
+ M.show_message(text("[user] attacks [src]'s stomach wall with the [I.name]!"), 2)
+ playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
+
+ if(prob(getBruteLoss() - 50))
+ gib()
#undef STOMACH_ATTACK_DELAY
@@ -135,9 +138,8 @@
I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
for(var/mob/M in src)
- if(M in src.stomach_contents)
- src.stomach_contents.Remove(M)
- M.forceMove(get_turf(src))
+ LAZYREMOVE(stomach_contents, M)
+ M.forceMove(drop_location())
visible_message("[M] bursts out of [src]!")
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
@@ -486,7 +488,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/starting_machine)
- if(!istype(starting_machine) || !starting_machine.returnPipenet())
+ if(!istype(starting_machine) || !starting_machine.returnPipenet() || !starting_machine.can_see_pipes())
return
var/datum/pipeline/pipeline = starting_machine.returnPipenet()
var/list/totalMembers = list()
@@ -870,7 +872,6 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
unEquip(I)
I.dropped()
return
- return 1
else
to_chat(src, "You fail to remove [I]!")
@@ -977,25 +978,30 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/carbon/proc/slip(description, stun, weaken, tilesSlipped, walkSafely, slipAny, slipVerb = "slip")
if(flying || buckled || (walkSafely && m_intent == MOVE_INTENT_WALK))
- return 0
+ return FALSE
+
if((lying) && (!(tilesSlipped)))
- return 0
+ return FALSE
+
if(!(slipAny))
if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
if(isobj(H.shoes) && H.shoes.flags & NOSLIP)
- return 0
+ return FALSE
+
if(tilesSlipped)
- for(var/t = 0, t<=tilesSlipped, t++)
- spawn (t) step(src, src.dir)
+ for(var/i in 1 to tilesSlipped)
+ spawn(i)
+ step(src, dir)
+
stop_pulling()
to_chat(src, "You [slipVerb]ped on [description]!")
- playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
+ playsound(loc, 'sound/misc/slip.ogg', 50, 1, -3)
// Something something don't run with scissors
moving_diagonally = 0 //If this was part of diagonal move slipping will stop it.
Stun(stun)
Weaken(weaken)
- return 1
+ return TRUE
/mob/living/carbon/proc/can_eat(flags = 255)
return 1
@@ -1060,10 +1066,6 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/carbon/proc/forceFedAttackLog(var/obj/item/reagent_containers/food/toEat, mob/user)
add_attack_logs(user, src, "Fed [toEat]. Reagents: [toEat.reagents.log_list(toEat)]", toEat.reagents.harmless_helper() ? ATKLOG_ALMOSTALL : null)
- if(!iscarbon(user))
- LAssailant = null
- else
- LAssailant = user
/*TO DO - If/when stomach organs are introduced, override this at the human level sending the item to the stomach
@@ -1196,3 +1198,18 @@ so that different stomachs can handle things in different ways VB*/
I.acid_level = 0 //washes off the acid on our clothes
I.extinguish() //extinguishes our clothes
..()
+
+/mob/living/carbon/clean_blood(clean_hands = TRUE, clean_mask = TRUE, clean_feet = TRUE)
+ if(head)
+ if(head.clean_blood())
+ update_inv_head()
+ if(head.flags_inv & HIDEMASK)
+ clean_mask = FALSE
+ if(wear_suit)
+ if(wear_suit.clean_blood())
+ update_inv_wear_suit()
+ if(wear_suit.flags_inv & HIDESHOES)
+ clean_feet = FALSE
+ if(wear_suit.flags_inv & HIDEGLOVES)
+ clean_hands = FALSE
+ ..(clean_hands, clean_mask, clean_feet)
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 75bd6d2664a..e0cba0b0281 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -12,7 +12,7 @@
visible_message("[src] catches [AM]!")
throw_mode_off()
return TRUE
- ..()
+ return ..()
/mob/living/carbon/water_act(volume, temperature, source, method = REAGENT_TOUCH)
. = ..()
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index 97ecf4dd08b..667fd86204e 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -1,11 +1,10 @@
/mob/living/carbon
gender = MALE
pressure_resistance = 15
- var/list/stomach_contents = list()
- var/list/processing_patches = list()
+ var/list/stomach_contents
+ var/list/processing_patches
var/list/internal_organs = list()
var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access.
- var/antibodies = 0
var/life_tick = 0 // The amount of life ticks that have processed on this mob.
diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm
index bc4b5b43b1c..58c6a39e6c1 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -131,7 +131,7 @@
m_styles["head"] = "None"
update_markings()
- update_body(1, 1) //Update the body and force limb icon regeneration to update the head with the new icon.
+ update_body(TRUE) //Update the body and force limb icon regeneration to update the head with the new icon.
if(wear_mask)
update_inv_wear_mask()
return 1
@@ -469,7 +469,7 @@
scramble(1, src, 100)
real_name = random_name(gender, dna.species.name) //Give them a name that makes sense for their species.
sync_organ_dna(assimilate = 1)
- update_body(0)
+ update_body()
reset_hair() //No more winding up with hairstyles you're not supposed to have, and blowing your cover.
reset_markings() //...Or markings.
dna.ResetUIFrom(src)
diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm
index e214f6068bb..1583bc62c70 100644
--- a/code/modules/mob/living/carbon/human/body_accessories.dm
+++ b/code/modules/mob/living/carbon/human/body_accessories.dm
@@ -1,17 +1,5 @@
GLOBAL_LIST_INIT(body_accessory_by_name, list("None" = null))
-
-/hook/startup/proc/initalize_body_accessories()
-
- __init_body_accessory(/datum/body_accessory/body)
- __init_body_accessory(/datum/body_accessory/tail)
-
- if(GLOB.body_accessory_by_name.len)
- if(initialize_body_accessory_by_species())
- return TRUE
-
- return FALSE //fail if no bodies are found
-
GLOBAL_LIST_INIT(body_accessory_by_species, list("None" = null))
/proc/initialize_body_accessory_by_species()
@@ -77,15 +65,6 @@ GLOBAL_LIST_INIT(body_accessory_by_species, list("None" = null))
/datum/body_accessory/body
blend_mode = ICON_MULTIPLY
-/datum/body_accessory/body/snake
- name = "Snake"
-
- icon = 'icons/mob/body_accessory_64.dmi'
- icon_state = "snake"
-
- pixel_x_offset = -16
-
-
//Tails
/datum/body_accessory/tail
icon = 'icons/mob/body_accessory.dmi'
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index aa8643173f4..d213ee7206f 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -6,7 +6,7 @@
canmove = 0
icon = null
invisibility = 101
- if(!isSynthetic())
+ if(!ismachineperson(src))
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
@@ -32,12 +32,11 @@
E.droplimb(DROPLIMB_SHARP)
for(var/mob/M in src)
- if(M in stomach_contents)
- stomach_contents.Remove(M)
- M.forceMove(get_turf(src))
+ LAZYREMOVE(stomach_contents, M)
+ M.forceMove(drop_location())
visible_message("[M] bursts out of [src]!")
- if(!isSynthetic())
+ if(!ismachineperson(src))
flick("gibbed-h", animation)
hgibs(loc, dna)
else
@@ -103,15 +102,9 @@
set_heartattack(FALSE)
SSmobs.cubemonkeys -= src
if(dna.species)
- dna.species.handle_hud_icons(src)
//Handle species-specific deaths.
dna.species.handle_death(gibbed, src)
- if(ishuman(LAssailant))
- var/mob/living/carbon/human/H=LAssailant
- if(H.mind)
- H.mind.kills += "[key_name(src)]"
-
if(SSticker && SSticker.mode)
// log_world("k")
sql_report_death(src)
@@ -124,10 +117,10 @@
if(. && healthdoll)
// We're alive again, so re-build the entire healthdoll
healthdoll.cached_healthdoll_overlays.Cut()
+ update_health_hud()
// Update healthdoll
if(dna.species)
dna.species.update_sight(src)
- dna.species.handle_hud_icons(src)
/mob/living/carbon/human/proc/makeSkeleton()
var/obj/item/organ/external/head/H = get_organ("head")
@@ -146,14 +139,14 @@
H.alt_head = initial(H.alt_head)
H.handle_alt_icon()
m_styles = DEFAULT_MARKING_STYLES
- update_fhair(0)
- update_hair(0)
- update_head_accessory(0)
- update_markings(0)
+ update_fhair()
+ update_hair()
+ update_head_accessory()
+ update_markings()
mutations.Add(SKELETON)
mutations.Add(NOCLONE)
- update_body(0)
+ update_body()
update_mutantrace()
return
@@ -172,11 +165,11 @@
H.f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE
if(H.h_style)
H.h_style = "Bald"
- update_fhair(0)
- update_hair(0)
+ update_fhair()
+ update_hair()
mutations.Add(HUSK)
- update_body(0)
+ update_body()
update_mutantrace()
return
@@ -190,6 +183,6 @@
var/obj/item/organ/external/head/H = bodyparts_by_name["head"]
if(istype(H))
H.disfigured = FALSE
- update_body(0)
- update_mutantrace(0)
+ update_body()
+ update_mutantrace()
UpdateAppearance() // reset hair from DNA
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index c1f6acdefe5..10c2ac8f119 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -34,7 +34,7 @@
//Cooldown-inducing emotes
if("ping", "pings", "buzz", "buzzes", "beep", "beeps", "yes", "no", "buzz2")
var/found_machine_head = FALSE
- if(ismachine(src)) //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise.
+ if(ismachineperson(src)) //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise.
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
found_machine_head = TRUE
else
@@ -139,10 +139,18 @@
//WHO THE FUCK THOUGHT THAT WAS A GOOD FUCKING IDEA!?!?
if("howl", "howls")
- var/M = handle_emote_param(param) //Check to see if the param is valid (mob with the param name is in view).
- message = "[src] howls[M ? " at [M]" : ""]!"
- playsound(loc, 'sound/goonstation/voice/howl.ogg', 100, 1, 10, frequency = get_age_pitch())
- m_type = 2
+ var/M = handle_emote_param(param)
+ if(miming)
+ message = "[src] acts out a howl[M ? " at [M]" : ""]!"
+ m_type = 1
+ else
+ if(!muzzled)
+ message = "[src] howls[M ? " at [M]" : ""]!"
+ playsound(loc, 'sound/goonstation/voice/howl.ogg', 100, 1, 10, frequency = get_age_pitch())
+ m_type = 2
+ else
+ message = "[src] makes a very loud noise[M ? " at [M]" : ""]."
+ m_type = 2
if("growl", "growls")
var/M = handle_emote_param(param)
@@ -256,12 +264,12 @@
if(body_accessory)
if(body_accessory.try_restrictions(src))
message = "[src] starts wagging [p_their()] tail."
- start_tail_wagging(1)
+ start_tail_wagging()
else if(dna.species.bodyflags & TAIL_WAGGING)
if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL))
message = "[src] starts wagging [p_their()] tail."
- start_tail_wagging(1)
+ start_tail_wagging()
else
return
else
@@ -271,7 +279,7 @@
if("swag", "swags")
if(dna.species.bodyflags & TAIL_WAGGING || body_accessory)
message = "[src] stops wagging [p_their()] tail."
- stop_tail_wagging(1)
+ stop_tail_wagging()
else
return
m_type = 1
@@ -939,7 +947,7 @@
if("Skrell")
emotelist += "\nSkrell specific emotes :- warble(s)"
- if(ismachine(src))
+ if(ismachineperson(src))
emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob"
else
var/obj/item/organ/external/head/H = get_organ("head") // If you have a robotic head, you can make beep-boop noises
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index b67e01924c8..60891563ad2 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -208,7 +208,7 @@
if(!E)
wound_flavor_text["[organ_tag]"] = "[p_they(TRUE)] [p_are()] missing [p_their()] [organ_descriptor].\n"
else
- if(!isSynthetic())
+ if(!ismachineperson(src))
if(E.is_robotic())
wound_flavor_text["[E.limb_name]"] = "[p_they(TRUE)] [p_have()] a robotic [E.name]!\n"
@@ -252,7 +252,7 @@
var/temp = getBruteLoss() //no need to calculate each of these twice
if(temp)
- var/brute_message = !isSynthetic() ? "bruising" : "denting"
+ var/brute_message = !ismachineperson(src) ? "bruising" : "denting"
if(temp < 30)
msg += "[p_they(TRUE)] [p_have()] minor [brute_message ].\n"
else
@@ -301,13 +301,13 @@
else if(nutrition >= NUTRITION_LEVEL_FAT)
msg += "[p_they(TRUE)] [p_are()] quite chubby.\n"
- if(!isSynthetic() && blood_volume < BLOOD_VOLUME_SAFE)
+ if(!ismachineperson(src) && blood_volume < BLOOD_VOLUME_SAFE)
msg += "[p_they(TRUE)] [p_have()] pale skin.\n"
if(bleedsuppress)
msg += "[p_they(TRUE)] [p_are()] bandaged with something.\n"
else if(bleed_rate)
- var/bleed_message = !isSynthetic() ? "bleeding" : "leaking"
+ var/bleed_message = !ismachineperson(src) ? "bleeding" : "leaking"
msg += "[p_they(TRUE)] [p_are()] [bleed_message]!\n"
if(reagents.has_reagent("teslium"))
@@ -341,7 +341,7 @@
if(decaylevel == 3)
msg += "[p_they(TRUE)] [p_are()] rotting and blackened, the skin sloughing off. The smell is indescribably foul.\n"
if(decaylevel == 4)
- msg += "[p_they(TRUE)] [p_are()] mostly dessicated now, with only bones remaining of what used to be a person.\n"
+ msg += "[p_they(TRUE)] [p_are()] mostly desiccated now, with only bones remaining of what used to be a person.\n"
if(hasHUD(user,"security"))
var/perpname = get_visible_name(TRUE)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 7d1073fbdb2..16f1738d2f6 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -18,9 +18,9 @@
dna = new /datum/dna(null)
// Species name is handled by set_species()
- set_species(new_species, 1, delay_icon_update = 1, skip_same_check = TRUE)
+ . = ..()
- ..()
+ set_species(new_species, 1, delay_icon_update = 1, skip_same_check = TRUE)
if(dna.species)
real_name = dna.species.get_random_name(gender)
@@ -41,6 +41,7 @@
sync_organ_dna(1)
UpdateAppearance()
+ GLOB.human_list += src
/mob/living/carbon/human/OpenCraftingMenu()
handcrafting.ui_interact(src)
@@ -60,61 +61,62 @@
SSmobs.cubemonkeys -= src
QDEL_LIST(bodyparts)
splinted_limbs.Cut()
+ GLOB.human_list -= src
/mob/living/carbon/human/dummy
real_name = "Test Dummy"
status_flags = GODMODE|CANPUSH
/mob/living/carbon/human/skrell/Initialize(mapload)
- ..(mapload, /datum/species/skrell)
+ . = ..(mapload, /datum/species/skrell)
/mob/living/carbon/human/tajaran/Initialize(mapload)
- ..(mapload, /datum/species/tajaran)
+ . = ..(mapload, /datum/species/tajaran)
/mob/living/carbon/human/vulpkanin/Initialize(mapload)
- ..(mapload, /datum/species/vulpkanin)
+ . = ..(mapload, /datum/species/vulpkanin)
/mob/living/carbon/human/unathi/Initialize(mapload)
- ..(mapload, /datum/species/unathi)
+ . = ..(mapload, /datum/species/unathi)
/mob/living/carbon/human/vox/Initialize(mapload)
- ..(mapload, /datum/species/vox)
+ . = ..(mapload, /datum/species/vox)
/mob/living/carbon/human/voxarmalis/Initialize(mapload)
- ..(mapload, /datum/species/vox/armalis)
+ . = ..(mapload, /datum/species/vox/armalis)
/mob/living/carbon/human/skeleton/Initialize(mapload)
- ..(mapload, /datum/species/skeleton)
+ . = ..(mapload, /datum/species/skeleton)
/mob/living/carbon/human/kidan/Initialize(mapload)
- ..(mapload, /datum/species/kidan)
+ . = ..(mapload, /datum/species/kidan)
/mob/living/carbon/human/plasma/Initialize(mapload)
- ..(mapload, /datum/species/plasmaman)
+ . = ..(mapload, /datum/species/plasmaman)
/mob/living/carbon/human/slime/Initialize(mapload)
- ..(mapload, /datum/species/slime)
+ . = ..(mapload, /datum/species/slime)
/mob/living/carbon/human/grey/Initialize(mapload)
- ..(mapload, /datum/species/grey)
+ . = ..(mapload, /datum/species/grey)
/mob/living/carbon/human/abductor/Initialize(mapload)
- ..(mapload, /datum/species/abductor)
+ . = ..(mapload, /datum/species/abductor)
/mob/living/carbon/human/diona/Initialize(mapload)
- ..(mapload, /datum/species/diona)
+ . = ..(mapload, /datum/species/diona)
/mob/living/carbon/human/pod_diona/Initialize(mapload)
- ..(mapload, /datum/species/diona/pod)
+ . = ..(mapload, /datum/species/diona/pod)
/mob/living/carbon/human/machine/Initialize(mapload)
- ..(mapload, /datum/species/machine)
+ . = ..(mapload, /datum/species/machine)
/mob/living/carbon/human/machine/created
name = "Integrated Robotic Chassis"
/mob/living/carbon/human/machine/created/Initialize(mapload)
- ..()
+ . = ..()
rename_character(null, "Integrated Robotic Chassis ([rand(1, 9999)])")
update_dna()
for(var/obj/item/organ/external/E in bodyparts)
@@ -127,34 +129,34 @@
death()
/mob/living/carbon/human/shadow/Initialize(mapload)
- ..(mapload, /datum/species/shadow)
+ . = ..(mapload, /datum/species/shadow)
/mob/living/carbon/human/golem/Initialize(mapload)
- ..(mapload, /datum/species/golem)
+ . = ..(mapload, /datum/species/golem)
/mob/living/carbon/human/wryn/Initialize(mapload)
- ..(mapload, /datum/species/wryn)
+ . = ..(mapload, /datum/species/wryn)
/mob/living/carbon/human/nucleation/Initialize(mapload)
- ..(mapload, /datum/species/nucleation)
+ . = ..(mapload, /datum/species/nucleation)
/mob/living/carbon/human/drask/Initialize(mapload)
- ..(mapload, /datum/species/drask)
+ . = ..(mapload, /datum/species/drask)
/mob/living/carbon/human/monkey/Initialize(mapload)
- ..(mapload, /datum/species/monkey)
+ . = ..(mapload, /datum/species/monkey)
/mob/living/carbon/human/farwa/Initialize(mapload)
- ..(mapload, /datum/species/monkey/tajaran)
+ . = ..(mapload, /datum/species/monkey/tajaran)
/mob/living/carbon/human/wolpin/Initialize(mapload)
- ..(mapload, /datum/species/monkey/vulpkanin)
+ . = ..(mapload, /datum/species/monkey/vulpkanin)
/mob/living/carbon/human/neara/Initialize(mapload)
- ..(mapload, /datum/species/monkey/skrell)
+ . = ..(mapload, /datum/species/monkey/skrell)
/mob/living/carbon/human/stok/Initialize(mapload)
- ..(mapload, /datum/species/monkey/unathi)
+ . = ..(mapload, /datum/species/monkey/unathi)
/mob/living/carbon/human/Stat()
..()
@@ -658,7 +660,7 @@
else
if(place_item)
usr.unEquip(place_item)
- equip_to_slot_if_possible(place_item, pocket_id, 0, 1)
+ equip_to_slot_if_possible(place_item, pocket_id, FALSE, TRUE)
add_attack_logs(usr, src, "Equipped with [place_item]", isLivingSSD(src) ? null : ATKLOG_ALL)
// Update strip window
@@ -1160,18 +1162,6 @@
custom_pain("You feel a stabbing pain in your chest!")
L.damage = L.min_bruised_damage
-//returns 1 if made bloody, returns 0 otherwise
-
-/mob/living/carbon/human/clean_blood(var/clean_feet)
- .=..()
- if(clean_feet && !shoes && istype(feet_blood_DNA, /list) && feet_blood_DNA.len)
- feet_blood_color = null
- qdel(feet_blood_DNA)
- bloody_feet = list(BLOOD_STATE_HUMAN = 0, BLOOD_STATE_XENO = 0, BLOOD_STATE_NOT_BLOODY = 0)
- blood_state = BLOOD_STATE_NOT_BLOODY
- update_inv_shoes(1)
- return 1
-
/mob/living/carbon/human/cuff_resist(obj/item/I)
if(HULK in mutations)
say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
@@ -1349,7 +1339,7 @@
dna.species.create_organs(src)
for(var/obj/item/thing in kept_items)
- equip_to_slot_if_possible(thing, kept_items[thing], redraw_mob = 0)
+ equip_to_slot_if_possible(thing, kept_items[thing])
thing.flags = item_flags[thing] // Reset the flags to the origional ones
//Handle default hair/head accessories for created mobs.
@@ -1399,7 +1389,7 @@
UpdateAppearance()
overlays.Cut()
- update_mutantrace(1)
+ update_mutantrace()
regenerate_icons()
if(dna.species)
@@ -1699,14 +1689,14 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
/mob/living/carbon/human/forceFed(var/obj/item/reagent_containers/food/toEat, mob/user, fullness)
if(!check_has_mouth())
- if(!((istype(toEat, /obj/item/reagent_containers/food/drinks) && (ismachine(src)))))
+ if(!((istype(toEat, /obj/item/reagent_containers/food/drinks) && (ismachineperson(src)))))
to_chat(user, "Where do you intend to put \the [toEat]? \The [src] doesn't have a mouth!")
return 0
return ..()
/mob/living/carbon/human/selfDrink(var/obj/item/reagent_containers/food/drinks/toDrink)
if(!check_has_mouth())
- if(!ismachine(src))
+ if(!ismachineperson(src))
to_chat(src, "Where do you intend to put \the [src]? You don't have a mouth!")
return 0
else
@@ -1962,3 +1952,6 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
if(O && O.glowing)
O.toggle_biolum(TRUE)
visible_message("[src] is engulfed in shadows and fades into the darkness.", "A sense of dread washes over you as you suddenly dim dark.")
+
+/mob/living/carbon/human/proc/get_perceived_trauma()
+ return min(health, maxHealth - getStaminaLoss())
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index f2a976e46d2..f9058065fb0 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -19,8 +19,6 @@
ChangeToHusk()
update_stat("updatehealth([reason])")
med_hud_set_health()
- med_hud_set_status()
- handle_hud_icons_health()
/mob/living/carbon/human/adjustBrainLoss(amount, updating = TRUE, use_brain_mod = TRUE)
if(status_flags & GODMODE)
@@ -32,7 +30,7 @@
if(dna.species && amount > 0)
if(use_brain_mod)
amount = amount * dna.species.brain_mod
- sponge.damage = Clamp(sponge.damage + amount, 0, 120)
+ sponge.damage = clamp(sponge.damage + amount, 0, 120)
if(sponge.damage >= 120)
visible_message("[src] goes limp, [p_their()] facial expression utterly blank.")
death()
@@ -50,7 +48,7 @@
if(dna.species && amount > 0)
if(use_brain_mod)
amount = amount * dna.species.brain_mod
- sponge.damage = Clamp(amount, 0, 120)
+ sponge.damage = clamp(amount, 0, 120)
if(sponge.damage >= 120)
visible_message("[src] goes limp, [p_their()] facial expression utterly blank.")
death()
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index d698a68c6d5..21a3e8bf274 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -84,7 +84,7 @@ emp_act
E.heal_damage(rembrute,0,0,1)
rembrute = nrembrute
user.visible_message("[user] patches some dents on [src]'s [E.name] with [I].")
- if(bleed_rate && isSynthetic())
+ if(bleed_rate && ismachineperson(src))
bleed_rate = 0
user.visible_message("[user] patches some leaks on [src] with [I].")
if(IgniteMob())
@@ -134,7 +134,7 @@ emp_act
if(bp && istype(bp ,/obj/item/clothing))
var/obj/item/clothing/C = bp
if(C.body_parts_covered & def_zone.body_part)
- protection += C.armor[type]
+ protection += C.armor.getRating(type)
return protection
@@ -185,19 +185,19 @@ emp_act
var/block_chance_modifier = round(damage / -3)
if(l_hand && !istype(l_hand, /obj/item/clothing))
- var/final_block_chance = l_hand.block_chance - (Clamp((armour_penetration-l_hand.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
+ var/final_block_chance = l_hand.block_chance - (clamp((armour_penetration-l_hand.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
if(l_hand.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
if(r_hand && !istype(r_hand, /obj/item/clothing))
- var/final_block_chance = r_hand.block_chance - (Clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)) + block_chance_modifier //Need to reset the var so it doesn't carry over modifications between attempts
+ var/final_block_chance = r_hand.block_chance - (clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)) + block_chance_modifier //Need to reset the var so it doesn't carry over modifications between attempts
if(r_hand.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
if(wear_suit)
- var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
+ var/final_block_chance = wear_suit.block_chance - (clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
if(wear_suit.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
if(w_uniform)
- var/final_block_chance = w_uniform.block_chance - (Clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier
+ var/final_block_chance = w_uniform.block_chance - (clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier
if(w_uniform.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
return 0
@@ -387,11 +387,6 @@ emp_act
to_chat(user, "You hack off a chunk of meat from [name]")
if(!meatleft)
add_attack_logs(user, src, "Chopped up into meat")
- if(!iscarbon(user))
- LAssailant = null
- else
- LAssailant = user
-
qdel(src)
var/obj/item/organ/external/affecting = get_organ(ran_zone(user.zone_selected))
@@ -457,13 +452,13 @@ emp_act
if(bloody)//Apply blood
if(wear_mask)
wear_mask.add_mob_blood(src)
- update_inv_wear_mask(0)
+ update_inv_wear_mask()
if(head)
head.add_mob_blood(src)
- update_inv_head(0,0)
+ update_inv_head()
if(glasses && prob(33))
glasses.add_mob_blood(src)
- update_inv_glasses(0)
+ update_inv_glasses()
if("chest")//Easier to score a stun but lasts less time
@@ -475,10 +470,10 @@ emp_act
if(bloody)
if(wear_suit)
wear_suit.add_mob_blood(src)
- update_inv_wear_suit(1)
+ update_inv_wear_suit()
if(w_uniform)
w_uniform.add_mob_blood(src)
- update_inv_w_uniform(1)
+ update_inv_w_uniform()
@@ -525,16 +520,16 @@ emp_act
else
add_mob_blood(source)
bloody_hands = amount
- update_inv_gloves(1) //updates on-mob overlays for bloody hands and/or bloody gloves
+ update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves
/mob/living/carbon/human/proc/bloody_body(var/mob/living/source)
if(wear_suit)
wear_suit.add_mob_blood(source)
- update_inv_wear_suit(0)
+ update_inv_wear_suit()
return
if(w_uniform)
w_uniform.add_mob_blood(source)
- update_inv_w_uniform(1)
+ update_inv_w_uniform()
/mob/living/carbon/human/proc/handle_suit_punctures(var/damtype, var/damage)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 60b6da987dd..3d365afa940 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -37,7 +37,6 @@ GLOBAL_DATUM_INIT(default_martial_art, /datum/martial_art, new())
var/obj/item/s_store = null
var/icon/stand_icon = null
- var/icon/lying_icon = null
var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life()
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 85bf001a206..5e1b5163a24 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -81,7 +81,7 @@
/mob/living/carbon/human/handle_footstep(turf/T)
if(..())
- if(T.footstep_sounds["human"])
+ if(T.footstep_sounds && T.footstep_sounds["human"])
var/S = pick(T.footstep_sounds["human"])
if(S)
if(m_intent == MOVE_INTENT_RUN)
diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm
index ea62f2fb5f9..b4a65b110a9 100644
--- a/code/modules/mob/living/carbon/human/human_organs.dm
+++ b/code/modules/mob/living/carbon/human/human_organs.dm
@@ -8,12 +8,15 @@
/mob/living/carbon/human/var/list/bodyparts_by_name = list() // map organ names to organs
// Takes care of organ related updates, such as broken and missing limbs
-/mob/living/carbon/human/proc/handle_organs()
+/mob/living/carbon/human/handle_organs()
+ ..()
//processing internal organs is pretty cheap, do that first.
- for(var/obj/item/organ/internal/I in internal_organs)
+ for(var/X in internal_organs)
+ var/obj/item/organ/internal/I = X
I.process()
- for(var/obj/item/organ/external/E in bodyparts)
+ for(var/Y in bodyparts)
+ var/obj/item/organ/external/E = Y
E.process()
if(!lying && world.time - l_move_time < 15)
@@ -109,6 +112,11 @@
do_sparks(5, 0, src)
+/mob/living/carbon/human/handle_germs()
+ ..()
+ if(gloves && germ_level > gloves.germ_level && prob(10))
+ gloves.germ_level += 1
+
/mob/living/carbon/human/proc/becomeSlim()
to_chat(src, "You feel fit again!")
mutations.Remove(FAT)
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index ea48884df9b..954d4e8fa55 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -178,8 +178,7 @@
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
-//set redraw_mob to 0 if you don't wish the hud to be updated - if you're doing it manually in your own proc.
-/mob/living/carbon/human/equip_to_slot(obj/item/I, slot, redraw_mob = 1)
+/mob/living/carbon/human/equip_to_slot(obj/item/I, slot)
if(!slot)
return
if(!istype(I))
@@ -203,40 +202,40 @@
switch(slot)
if(slot_back)
back = I
- update_inv_back(redraw_mob)
+ update_inv_back()
if(slot_wear_mask)
wear_mask = I
if((wear_mask.flags & BLOCKHAIR) || (wear_mask.flags & BLOCKHEADHAIR))
- update_hair(redraw_mob) //rebuild hair
- update_fhair(redraw_mob)
- update_head_accessory(redraw_mob)
+ update_hair() //rebuild hair
+ update_fhair()
+ update_head_accessory()
if(hud_list.len)
sec_hud_set_ID()
wear_mask_update(I, toggle_off = TRUE)
- update_inv_wear_mask(redraw_mob)
+ update_inv_wear_mask()
if(slot_handcuffed)
handcuffed = I
- update_inv_handcuffed(redraw_mob)
+ update_inv_handcuffed()
if(slot_legcuffed)
legcuffed = I
- update_inv_legcuffed(redraw_mob)
+ update_inv_legcuffed()
if(slot_l_hand)
l_hand = I
- update_inv_l_hand(redraw_mob)
+ update_inv_l_hand()
if(slot_r_hand)
r_hand = I
- update_inv_r_hand(redraw_mob)
+ update_inv_r_hand()
if(slot_belt)
belt = I
- update_inv_belt(redraw_mob)
+ update_inv_belt()
if(slot_wear_id)
wear_id = I
if(hud_list.len)
sec_hud_set_ID()
- update_inv_wear_id(redraw_mob)
+ update_inv_wear_id()
if(slot_wear_pda)
wear_pda = I
- update_inv_wear_pda(redraw_mob)
+ update_inv_wear_pda()
if(slot_l_ear)
l_ear = I
if(l_ear.slot_flags & SLOT_TWOEARS)
@@ -245,7 +244,7 @@
r_ear = O
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
- update_inv_ears(redraw_mob)
+ update_inv_ears()
if(slot_r_ear)
r_ear = I
if(r_ear.slot_flags & SLOT_TWOEARS)
@@ -254,7 +253,7 @@
l_ear = O
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
- update_inv_ears(redraw_mob)
+ update_inv_ears()
if(slot_glasses)
glasses = I
var/obj/item/clothing/glasses/G = I
@@ -264,42 +263,42 @@
update_nearsighted_effects()
if(G.vision_flags || G.see_in_dark || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
update_sight()
- update_inv_glasses(redraw_mob)
+ update_inv_glasses()
update_client_colour()
if(slot_gloves)
gloves = I
- update_inv_gloves(redraw_mob)
+ update_inv_gloves()
if(slot_head)
head = I
if((head.flags & BLOCKHAIR) || (head.flags & BLOCKHEADHAIR))
- update_hair(redraw_mob) //rebuild hair
- update_fhair(redraw_mob)
- update_head_accessory(redraw_mob)
+ update_hair() //rebuild hair
+ update_fhair()
+ update_head_accessory()
// paper + bandanas
if(istype(I, /obj/item/clothing/head))
var/obj/item/clothing/head/hat = I
if(hat.vision_flags || hat.see_in_dark || !isnull(hat.lighting_alpha))
update_sight()
head_update(I)
- update_inv_head(redraw_mob)
+ update_inv_head()
if(slot_shoes)
shoes = I
- update_inv_shoes(redraw_mob)
+ update_inv_shoes()
if(slot_wear_suit)
wear_suit = I
- update_inv_wear_suit(redraw_mob)
+ update_inv_wear_suit()
if(slot_w_uniform)
w_uniform = I
- update_inv_w_uniform(redraw_mob)
+ update_inv_w_uniform()
if(slot_l_store)
l_store = I
- update_inv_pockets(redraw_mob)
+ update_inv_pockets()
if(slot_r_store)
r_store = I
- update_inv_pockets(redraw_mob)
+ update_inv_pockets()
if(slot_s_store)
s_store = I
- update_inv_s_store(redraw_mob)
+ update_inv_s_store()
if(slot_in_backpack)
if(get_active_hand() == I)
unEquip(I)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 8f548100650..90653a6750b 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -1,18 +1,26 @@
/mob/living/carbon/human/Life(seconds, times_fired)
+ set invisibility = 0
+ if(notransform)
+ return
+
+ . = ..()
+
+ if(QDELETED(src))
+ return FALSE
+
life_tick++
voice = GetVoice()
- if(..())
+ if(.) //not dead
if(check_mutations)
domutcheck(src,null)
update_mutations()
- check_mutations=0
+ check_mutations = FALSE
handle_pain()
handle_heartbeat()
- handle_drunk()
dna.species.handle_life(src)
if(!client)
dna.species.handle_npc(src)
@@ -24,45 +32,45 @@
if(stat == DEAD)
handle_decay()
- if(life_tick > 5 && timeofdeath && (timeofdeath < 5 || world.time - timeofdeath > 6000)) //We are long dead, or we're junk mobs spawned like the clowns on the clown shuttle
- return //We go ahead and process them 5 times for HUD images and other stuff though.
-
//Update our name based on whether our face is obscured/disfigured
name = get_visible_name()
pulse = handle_pulse(times_fired)
- if(mind && mind.vampire)
+ if(mind?.vampire)
mind.vampire.handle_vampire()
if(life_tick == 1)
regenerate_icons() // Make sure the inventory updates
- handle_ghosted()
- handle_ssd()
+ if(player_ghosted > 0 && stat == CONSCIOUS && job && !restrained())
+ handle_ghosted()
+ if(player_logged > 0 && stat != DEAD && job)
+ handle_ssd()
+
+ if(stat != DEAD)
+ return TRUE
/mob/living/carbon/human/proc/handle_ghosted()
- if(player_ghosted > 0 && stat == CONSCIOUS && job && !restrained())
- if(key)
- player_ghosted = 0
- else
- player_ghosted++
- if(player_ghosted % 150 == 0)
- force_cryo_human(src)
+ if(key)
+ player_ghosted = 0
+ else
+ player_ghosted++
+ if(player_ghosted % 150 == 0)
+ force_cryo_human(src)
/mob/living/carbon/human/proc/handle_ssd()
- if(player_logged > 0 && stat != DEAD && job)
- player_logged++
- if(istype(loc, /obj/machinery/cryopod))
+ player_logged++
+ if(istype(loc, /obj/machinery/cryopod))
+ return
+ if(config.auto_cryo_ssd_mins && (player_logged >= (config.auto_cryo_ssd_mins * 30)) && player_logged % 30 == 0)
+ var/turf/T = get_turf(src)
+ if(!is_station_level(T.z))
return
- if(config.auto_cryo_ssd_mins && (player_logged >= (config.auto_cryo_ssd_mins * 30)) && player_logged % 30 == 0)
- var/turf/T = get_turf(src)
- if(!is_station_level(T.z))
- return
- var/area/A = get_area(src)
- if(cryo_ssd(src))
- var/obj/effect/portal/P = new /obj/effect/portal(T, null, null, 40)
- P.name = "NT SSD Teleportation Portal"
- if(A.fast_despawn)
- force_cryo_human(src)
+ var/area/A = get_area(src)
+ if(cryo_ssd(src))
+ var/obj/effect/portal/P = new /obj/effect/portal(T, null, null, 40)
+ P.name = "NT SSD Teleportation Portal"
+ if(A.fast_despawn)
+ force_cryo_human(src)
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
..()
@@ -80,38 +88,35 @@
/mob/living/carbon/human/handle_disabilities()
- if(disabilities & EPILEPSY)
- if((prob(1) && paralysis < 1))
- visible_message("[src] starts having a seizure!","You have a seizure!")
- Paralyse(10)
- Jitter(1000)
+ //Vision //god knows why this is here
+ var/obj/item/organ/vision
+ if(dna.species.vision_organ)
+ vision = get_int_organ(dna.species.vision_organ)
- // If we have the gene for being crazy, have random events.
- if(dna.GetSEState(GLOB.hallucinationblock))
- if(prob(1))
- Hallucinate(20)
+ if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means.
+ SetEyeBlind(0)
+ SetEyeBlurry(0)
- if(disabilities & COUGHING)
- if((prob(5) && paralysis <= 1))
- drop_item()
- emote("cough")
- if(disabilities & TOURETTES)
- if((prob(10) && paralysis <= 1))
- Stun(10)
- switch(rand(1, 3))
- if(1)
- emote("twitch")
- if(2 to 3)
- var/tourettes = pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")
- say("[prob(50) ? ";" : ""][tourettes]")
- var/x_offset = pixel_x + rand(-2,2) //Should probably be moved into the twitch emote at some point.
- var/y_offset = pixel_y + rand(-1,1)
- animate(src, pixel_x = pixel_x + x_offset, pixel_y = pixel_y + y_offset, time = 1)
- animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y), time = 1)
+ else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind.
+ EyeBlind(2)
+ EyeBlurry(2)
- if(disabilities & NERVOUS)
- if(prob(10))
- Stuttering(10)
+ else
+ //blindness
+ if(BLINDNESS in mutations) // Disabled-blind, doesn't get better on its own
+
+ else if(eye_blind) // Blindness, heals slowly over time
+ AdjustEyeBlind(-1)
+
+ else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold) && eye_blurry) //resting your eyes with a blindfold heals blurry eyes faster
+ AdjustEyeBlurry(-3)
+
+ //blurry sight
+ if(vision.is_bruised()) // Vision organs impaired? Permablurry.
+ EyeBlurry(2)
+
+ if(eye_blurry) // Blurry eyes heal slowly
+ AdjustEyeBlurry(-1)
if(getBrainLoss() >= 60 && stat != DEAD)
if(prob(3))
@@ -192,7 +197,7 @@
if(!(RADIMMUNE in dna.species.species_traits))
if(radiation)
- radiation = Clamp(radiation, 0, 200)
+ radiation = clamp(radiation, 0, 200)
var/autopsy_damage = 0
switch(radiation)
@@ -607,6 +612,7 @@
// nutrition decrease
if(nutrition > 0 && stat != DEAD)
+ handle_nutrition_alerts()
// THEY HUNGER
var/hunger_rate = hunger_drain
if(satiety > 0)
@@ -629,7 +635,7 @@
else
overeatduration -= 2
- if(!ismachine(src) && nutrition < NUTRITION_LEVEL_HYPOGLYCEMIA) //Gosh damn snowflakey IPCs
+ if(!ismachineperson(src) && nutrition < NUTRITION_LEVEL_HYPOGLYCEMIA) //Gosh damn snowflakey IPCs
var/datum/disease/D = new /datum/disease/critical/hypoglycemia
ForceContractDisease(D)
@@ -656,22 +662,25 @@
AdjustSleeping(1)
Paralyse(5)
- AdjustConfused(-1)
+ if(confused)
+ AdjustConfused(-1)
// decrement dizziness counter, clamped to 0
if(resting)
- AdjustDizzy(-15)
- AdjustJitter(-15)
+ if(dizziness)
+ AdjustDizzy(-15)
+ if(jitteriness)
+ AdjustJitter(-15)
else
- AdjustDizzy(-3)
- AdjustJitter(-3)
+ if(dizziness)
+ AdjustDizzy(-3)
+ if(jitteriness)
+ AdjustJitter(-3)
if(NO_INTORGANS in dna.species.species_traits)
return
handle_trace_chems()
- return //TODO: DEFERRED
-
/mob/living/carbon/human/handle_drunk()
var/slur_start = 30 //12u ethanol, 30u whiskey FOR HUMANS
var/confused_start = 40
@@ -683,55 +692,54 @@
var/collapse_start = 75
var/braindamage_start = 120
var/alcohol_strength = drunk
- var/sober_str=!(SOBER in mutations)?1:2
+ var/sober_str =! (SOBER in mutations) ? 1 : 2
- if(drunk)
- alcohol_strength/=sober_str
+ alcohol_strength /= sober_str
- var/obj/item/organ/internal/liver/L
- if(!isSynthetic())
- L = get_int_organ(/obj/item/organ/internal/liver)
+ var/obj/item/organ/internal/liver/L
+ if(!ismachineperson(src))
+ L = get_int_organ(/obj/item/organ/internal/liver)
+ if(L)
+ alcohol_strength *= L.alcohol_intensity
+ else
+ alcohol_strength *= 5
+
+ if(alcohol_strength >= slur_start) //slurring
+ Slur(drunk)
+ if(alcohol_strength >= brawl_start) //the drunken martial art
+ if(!istype(martial_art, /datum/martial_art/drunk_brawling))
+ var/datum/martial_art/drunk_brawling/F = new
+ F.teach(src, 1)
+ if(alcohol_strength < brawl_start) //removing the art
+ if(istype(martial_art, /datum/martial_art/drunk_brawling))
+ martial_art.remove(src)
+ if(alcohol_strength >= confused_start && prob(33)) //confused walking
+ if(!confused)
+ Confused(1)
+ AdjustConfused(3 / sober_str)
+ if(alcohol_strength >= blur_start) //blurry eyes
+ EyeBlurry(10 / sober_str)
+ if(!ismachineperson(src)) //stuff only for non-synthetics
+ if(alcohol_strength >= vomit_start) //vomiting
+ if(prob(8))
+ fakevomit()
+ if(alcohol_strength >= pass_out)
+ Paralyse(5 / sober_str)
+ Drowsy(30 / sober_str)
if(L)
- alcohol_strength *= L.alcohol_intensity
- else
- alcohol_strength *= 5
-
- if(alcohol_strength >= slur_start) //slurring
- Slur(drunk)
- if(alcohol_strength >= brawl_start) //the drunken martial art
- if(!istype(martial_art, /datum/martial_art/drunk_brawling))
- var/datum/martial_art/drunk_brawling/F = new
- F.teach(src,1)
- if(alcohol_strength < brawl_start) //removing the art
- if(istype(martial_art, /datum/martial_art/drunk_brawling))
- martial_art.remove(src)
- if(alcohol_strength >= confused_start && prob(33)) //confused walking
- if(!confused) Confused(1)
- AdjustConfused(3/sober_str)
- if(alcohol_strength >= blur_start) //blurry eyes
- EyeBlurry(10/sober_str)
- if(!isSynthetic()) //stuff only for non-synthetics
- if(alcohol_strength >= vomit_start) //vomiting
- if(prob(8))
- fakevomit()
- if(alcohol_strength >= pass_out)
- Paralyse(5/sober_str)
- Drowsy(30/sober_str)
- if(L)
- L.receive_damage(0.1, 1)
- adjustToxLoss(0.1)
- else //stuff only for synthetics
- if(alcohol_strength >= spark_start && prob(25))
- do_sparks(3, 1, src)
- if(alcohol_strength >= collapse_start && prob(10))
- emote("collapse")
- do_sparks(3, 1, src)
- if(alcohol_strength >= braindamage_start && prob(10))
- adjustBrainLoss(1)
+ L.receive_damage(0.1, 1)
+ adjustToxLoss(0.1)
+ else //stuff only for synthetics
+ if(alcohol_strength >= spark_start && prob(25))
+ do_sparks(3, 1, src)
+ if(alcohol_strength >= collapse_start && prob(10))
+ emote("collapse")
+ do_sparks(3, 1, src)
+ if(alcohol_strength >= braindamage_start && prob(10))
+ adjustBrainLoss(1)
if(!has_booze())
AdjustDrunk(-0.5)
- return
/mob/living/carbon/human/proc/has_booze() //checks if the human has ethanol or its subtypes inside
for(var/A in reagents.reagent_list)
@@ -740,180 +748,154 @@
return 1
return 0
-/mob/living/carbon/human/handle_regular_status_updates()
+/mob/living/carbon/human/handle_critical_condition()
if(status_flags & GODMODE)
return 0
- . = ..()
+ var/guaranteed_death_threshold = health + (getOxyLoss() * 0.5) - (getFireLoss() * 0.67) - (getBruteLoss() * 0.67)
- if(.) //alive
- if(REGEN in mutations)
- heal_overall_damage(0.1, 0.1)
+ if(getBrainLoss() >= 120 || (guaranteed_death_threshold) <= -500)
+ death()
+ return
- if(paralysis)
- stat = UNCONSCIOUS
+ if(getBrainLoss() >= 100) // braindeath
+ AdjustLoseBreath(10, bound_lower = 0, bound_upper = 25)
+ Weaken(30)
- else if(sleeping)
+ if(!check_death_method())
+ if(health <= HEALTH_THRESHOLD_DEAD)
+ var/deathchance = min(99, ((getBrainLoss() * -5) + (health + (getOxyLoss() / 2))) * -0.01)
+ if(prob(deathchance))
+ death()
+ return
- stat = UNCONSCIOUS
+ if(health <= HEALTH_THRESHOLD_CRIT)
+ if(prob(5))
+ emote(pick("faint", "collapse", "cry", "moan", "gasp", "shudder", "shiver"))
+ AdjustStuttering(5, bound_lower = 0, bound_upper = 5)
+ EyeBlurry(5)
+ if(prob(7))
+ AdjustConfused(2)
+ if(prob(5))
+ Paralyse(2)
+ switch(health)
+ if(-INFINITY to -100)
+ adjustOxyLoss(1)
+ if(prob(health * -0.1))
+ if(ishuman(src))
+ var/mob/living/carbon/human/H = src
+ H.set_heartattack(TRUE)
+ if(prob(health * -0.2))
+ var/datum/disease/D = new /datum/disease/critical/heart_failure
+ ForceContractDisease(D)
+ Paralyse(5)
+ if(-99 to -80)
+ adjustOxyLoss(1)
+ if(prob(4))
+ to_chat(src, "Your chest hurts...")
+ Paralyse(2)
+ var/datum/disease/D = new /datum/disease/critical/heart_failure
+ ForceContractDisease(D)
+ if(-79 to -50)
+ adjustOxyLoss(1)
+ if(prob(10))
+ var/datum/disease/D = new /datum/disease/critical/shock
+ ForceContractDisease(D)
+ if(prob(health * -0.08))
+ var/datum/disease/D = new /datum/disease/critical/heart_failure
+ ForceContractDisease(D)
+ if(prob(6))
+ to_chat(src, "You feel [pick("horrible pain", "awful", "like shit", "absolutely awful", "like death", "like you are dying", "nothing", "warm", "sweaty", "tingly", "really, really bad", "horrible")]!")
+ Weaken(3)
+ if(prob(3))
+ Paralyse(2)
+ if(-49 to 0)
+ adjustOxyLoss(1)
+ if(prob(3))
+ var/datum/disease/D = new /datum/disease/critical/shock
+ ForceContractDisease(D)
+ if(prob(5))
+ to_chat(src, "You feel [pick("terrible", "awful", "like shit", "sick", "numb", "cold", "sweaty", "tingly", "horrible")]!")
+ Weaken(3)
- if(mind)
- if(mind.vampire)
- if(istype(loc, /obj/structure/closet/coffin))
- adjustBruteLoss(-1)
- adjustFireLoss(-1)
- adjustToxLoss(-1)
-
- else if(status_flags & FAKEDEATH)
- stat = UNCONSCIOUS
-
- //Vision //god knows why this is here
- var/obj/item/organ/vision
- if(dna.species.vision_organ)
- vision = get_int_organ(dna.species.vision_organ)
-
- if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means.
- SetEyeBlind(0)
- SetEyeBlurry(0)
-
- else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind.
- EyeBlind(2)
- EyeBlurry(2)
-
- else
- //blindness
- if(disabilities & BLIND) // Disabled-blind, doesn't get better on its own
-
- else if(eye_blind) // Blindness, heals slowly over time
- AdjustEyeBlind(-1)
-
- else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster
- AdjustEyeBlurry(-3)
-
- //blurry sight
- if(vision.is_bruised()) // Vision organs impaired? Permablurry.
- EyeBlurry(2)
-
- if(eye_blurry) // Blurry eyes heal slowly
- AdjustEyeBlurry(-1)
-
-
- if(flying)
- animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING)
- animate(pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING)
-
- // If you're dirty, your gloves will become dirty, too.
- if(gloves && germ_level > gloves.germ_level && prob(10))
- gloves.germ_level += 1
-
- handle_organs()
-
- var/guaranteed_death_threshold = health + (getOxyLoss() * 0.5) - (getFireLoss() * 0.67) - (getBruteLoss() * 0.67)
-
- if(getBrainLoss() >= 120 || (guaranteed_death_threshold) <= -500)
- death()
- return
-
- if(getBrainLoss() >= 100) // braindeath
- AdjustLoseBreath(10, bound_lower = 0, bound_upper = 25)
- Weaken(30)
-
- if(!check_death_method())
- if(health <= HEALTH_THRESHOLD_DEAD)
- var/deathchance = min(99, ((getBrainLoss() * -5) + (health + (getOxyLoss() / 2))) * -0.01)
- if(prob(deathchance))
- death()
- return
-
- if(health <= HEALTH_THRESHOLD_CRIT)
- if(prob(5))
- emote(pick("faint", "collapse", "cry", "moan", "gasp", "shudder", "shiver"))
- AdjustStuttering(5, bound_lower = 0, bound_upper = 5)
- EyeBlurry(5)
- if(prob(7))
- AdjustConfused(2)
- if(prob(5))
- Paralyse(2)
- switch(health)
- if(-INFINITY to -100)
- adjustOxyLoss(1)
- if(prob(health * -0.1))
- if(ishuman(src))
- var/mob/living/carbon/human/H = src
- H.set_heartattack(TRUE)
- if(prob(health * -0.2))
- var/datum/disease/D = new /datum/disease/critical/heart_failure
- ForceContractDisease(D)
- Paralyse(5)
- if(-99 to -80)
- adjustOxyLoss(1)
- if(prob(4))
- to_chat(src, "Your chest hurts...")
- Paralyse(2)
- var/datum/disease/D = new /datum/disease/critical/heart_failure
- ForceContractDisease(D)
- if(-79 to -50)
- adjustOxyLoss(1)
- if(prob(10))
- var/datum/disease/D = new /datum/disease/critical/shock
- ForceContractDisease(D)
- if(prob(health * -0.08))
- var/datum/disease/D = new /datum/disease/critical/heart_failure
- ForceContractDisease(D)
- if(prob(6))
- to_chat(src, "You feel [pick("horrible pain", "awful", "like shit", "absolutely awful", "like death", "like you are dying", "nothing", "warm", "sweaty", "tingly", "really, really bad", "horrible")]!")
- Weaken(3)
- if(prob(3))
- Paralyse(2)
- if(-49 to 0)
- adjustOxyLoss(1)
- if(prob(3))
- var/datum/disease/D = new /datum/disease/critical/shock
- ForceContractDisease(D)
- if(prob(5))
- to_chat(src, "You feel [pick("terrible", "awful", "like shit", "sick", "numb", "cold", "sweaty", "tingly", "horrible")]!")
- Weaken(3)
-
- else //dead
- SetSilence(0)
-
-
-/mob/living/carbon/human/handle_vision()
- if(machine)
- if(!machine.check_eye(src))
- reset_perspective(null)
+/mob/living/carbon/human/update_health_hud()
+ if(!client)
+ return
+ if(dna.species.update_health_hud())
+ return
else
- var/isRemoteObserve = 0
- if((REMOTE_VIEW in mutations) && remoteview_target)
- isRemoteObserve = 1
+ if(healths)
+ var/health_amount = get_perceived_trauma()
+ if(..(health_amount)) //not dead
+ switch(hal_screwyhud)
+ if(SCREWYHUD_CRIT)
+ healths.icon_state = "health6"
+ if(SCREWYHUD_DEAD)
+ healths.icon_state = "health7"
+ if(SCREWYHUD_HEALTHY)
+ healths.icon_state = "health0"
- if(remoteview_target.stat != CONSCIOUS)
- to_chat(src, "Your psy-connection grows too faint to maintain!")
- isRemoteObserve = 0
+ if(healthdoll)
+ if(stat == DEAD)
+ healthdoll.icon_state = "healthdoll_DEAD"
+ if(healthdoll.overlays.len)
+ healthdoll.overlays.Cut()
+ else
+ var/list/new_overlays = list()
+ var/list/cached_overlays = healthdoll.cached_healthdoll_overlays
+ // Use the dead health doll as the base, since we have proper "healthy" overlays now
+ healthdoll.icon_state = "healthdoll_DEAD"
+ for(var/obj/item/organ/external/O in bodyparts)
+ var/damage = O.burn_dam + O.brute_dam
+ var/comparison = (O.max_damage/5)
+ var/icon_num = 0
+ if(damage)
+ icon_num = 1
+ if(damage > (comparison))
+ icon_num = 2
+ if(damage > (comparison*2))
+ icon_num = 3
+ if(damage > (comparison*3))
+ icon_num = 4
+ if(damage > (comparison*4))
+ icon_num = 5
+ new_overlays += "[O.limb_name][icon_num]"
+ healthdoll.overlays += (new_overlays - cached_overlays)
+ healthdoll.overlays -= (cached_overlays - new_overlays)
+ healthdoll.cached_healthdoll_overlays = new_overlays
- if(PSY_RESIST in remoteview_target.mutations)
- to_chat(src, "Your mind is shut out!")
- isRemoteObserve = 0
+/mob/living/carbon/human/proc/handle_nutrition_alerts() //This is a terrible abuse of the alert system; something like this should be a HUD element
+ if(NO_HUNGER in dna.species.species_traits)
+ return
+ if(mind?.vampire && (mind in SSticker.mode.vampires)) //Vampires
+ switch(nutrition)
+ if(NUTRITION_LEVEL_FULL to INFINITY)
+ throw_alert("nutrition", /obj/screen/alert/fat/vampire)
+ if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
+ throw_alert("nutrition", /obj/screen/alert/full/vampire)
+ if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
+ throw_alert("nutrition", /obj/screen/alert/well_fed/vampire)
+ if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
+ throw_alert("nutrition", /obj/screen/alert/fed/vampire)
+ if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
+ throw_alert("nutrition", /obj/screen/alert/hungry/vampire)
+ else
+ throw_alert("nutrition", /obj/screen/alert/starving/vampire)
- // Not on the station or mining?
- var/turf/temp_turf = get_turf(remoteview_target)
- if(!(temp_turf in config.contact_levels))
- to_chat(src, "Your psy-connection grows too faint to maintain!")
- isRemoteObserve = 0
-
- if(remote_view)
- isRemoteObserve = 1
-
- if(!isRemoteObserve && client && !client.adminobs)
- remoteview_target = null
- reset_perspective(null)
-
-/mob/living/carbon/human/handle_hud_icons()
- dna.species.handle_hud_icons(src)
-
-/mob/living/carbon/human/handle_hud_icons_health()
- dna.species.handle_hud_icons_health(src)
- handle_hud_icons_health_overlay()
+ else //Any other non-vampires
+ switch(nutrition)
+ if(NUTRITION_LEVEL_FULL to INFINITY)
+ throw_alert("nutrition", /obj/screen/alert/fat)
+ if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
+ throw_alert("nutrition", /obj/screen/alert/full)
+ if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
+ throw_alert("nutrition", /obj/screen/alert/well_fed)
+ if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
+ throw_alert("nutrition", /obj/screen/alert/fed)
+ if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
+ throw_alert("nutrition", /obj/screen/alert/hungry)
+ else
+ throw_alert("nutrition", /obj/screen/alert/starving)
/mob/living/carbon/human/handle_random_events()
// Puke if toxloss is too high
@@ -942,15 +924,14 @@
clear_alert("embeddedobject")
/mob/living/carbon/human/handle_changeling()
- if(mind)
- if(mind.changeling)
- mind.changeling.regenerate(src)
- if(hud_used)
- hud_used.lingchemdisplay.invisibility = 0
- hud_used.lingchemdisplay.maptext = "[round(mind.changeling.chem_charges)] "
- else
- if(hud_used)
- hud_used.lingchemdisplay.invisibility = 101
+ if(mind.changeling)
+ mind.changeling.regenerate(src)
+ if(hud_used)
+ hud_used.lingchemdisplay.invisibility = 0
+ hud_used.lingchemdisplay.maptext = "[round(mind.changeling.chem_charges)] "
+ else
+ if(hud_used)
+ hud_used.lingchemdisplay.invisibility = 101
/mob/living/carbon/human/proc/handle_pulse(times_fired)
diff --git a/code/modules/mob/living/carbon/human/npcs.dm b/code/modules/mob/living/carbon/human/npcs.dm
index 41c108dadb9..9dcf83f2e9a 100644
--- a/code/modules/mob/living/carbon/human/npcs.dm
+++ b/code/modules/mob/living/carbon/human/npcs.dm
@@ -7,7 +7,7 @@
species_exception = list(/datum/species/monkey)
/mob/living/carbon/human/monkey/punpun/Initialize(mapload)
- ..()
+ . = ..()
name = "Pun Pun"
real_name = name
equip_to_slot(new /obj/item/clothing/under/punpun(src), slot_w_uniform)
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index b53fa03cebf..01a9990ebd8 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -134,11 +134,9 @@
S.message = "[S.message]"
verb = translator.speech_verb
return list("verb" = verb)
- if(mind)
- span = mind.speech_span
if((COMIC in mutations) \
|| (locate(/obj/item/organ/internal/cyberimp/brain/clown_voice) in internal_organs) \
- || GetComponent(/datum/component/jestosterone))
+ || HAS_TRAIT(src, TRAIT_JESTER))
span = "sans"
if(WINGDINGS in mutations)
@@ -151,7 +149,7 @@
if(S.speaking && S.speaking.flags & NO_STUTTER)
continue
- if(silent || (disabilities & MUTE))
+ if(silent || (MUTE in mutations))
S.message = ""
if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index 06b42202b45..0914852b131 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -53,7 +53,6 @@
var/stun_mod = 1 // If a species is more/less impacated by stuns/weakens/paralysis
var/speed_mod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster
var/blood_damage_type = OXY //What type of damage does this species take if it's low on blood?
- var/obj/item/mutanthands
var/total_health = 100
var/punchdamagelow = 0 //lowest possible punch damage
var/punchdamagehigh = 9 //highest possible punch damage
@@ -346,30 +345,17 @@
switch(damagetype)
if(BRUTE)
- H.damageoverlaytemp = 20
damage = damage * brute_mod
+ if(damage)
+ H.damageoverlaytemp = 20
if(organ.receive_damage(damage, 0, sharp, used_weapon))
H.UpdateDamageIcon()
- if(H.LAssailant && ishuman(H.LAssailant)) //superheros still get the comical hit markers
- var/mob/living/carbon/human/A = H.LAssailant
- if(A.mind && (A.mind in (SSticker.mode.superheroes) || SSticker.mode.supervillains || SSticker.mode.greyshirts))
- var/list/attack_bubble_recipients = list()
- var/mob/living/user
- for(var/mob/O in viewers(user, src))
- if(O.client && O.has_vision(information_only=TRUE))
- attack_bubble_recipients.Add(O.client)
- spawn(0)
- var/image/dmgIcon = image('icons/effects/hit_blips.dmi', src, "dmg[rand(1,2)]",MOB_LAYER+1)
- dmgIcon.pixel_x = (!H.lying) ? rand(-3,3) : rand(-11,12)
- dmgIcon.pixel_y = (!H.lying) ? rand(-11,9) : rand(-10,1)
- flick_overlay(dmgIcon, attack_bubble_recipients, 9)
-
-
if(BURN)
- H.damageoverlaytemp = 20
damage = damage * burn_mod
+ if(damage)
+ H.damageoverlaytemp = 20
if(organ.receive_damage(0, damage, sharp, used_weapon))
H.UpdateDamageIcon()
@@ -443,6 +429,9 @@
else
target.LAssailant = user
+ target.lastattacker = user.real_name
+ target.lastattackerckey = user.ckey
+
var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh)
damage += attack.damage
if(!damage)
@@ -754,105 +743,8 @@
return FALSE //Unsupported slot
-/datum/species/proc/get_perceived_trauma(mob/living/carbon/human/H)
- return min(H.health, H.maxHealth - H.getStaminaLoss())
-
-/datum/species/proc/handle_hud_icons(mob/living/carbon/human/H)
- if(!H.client)
- return
- handle_hud_icons_health(H)
- H.handle_hud_icons_health_overlay()
- handle_hud_icons_nutrition(H)
-
-/datum/species/proc/handle_hud_icons_health(mob/living/carbon/H)
- if(!H.client)
- return
- handle_hud_icons_health_side(H)
- handle_hud_icons_health_doll(H)
-
-/datum/species/proc/handle_hud_icons_health_side(mob/living/carbon/human/H)
- if(H.healths)
- if(H.stat == DEAD || (H.status_flags & FAKEDEATH))
- H.healths.icon_state = "health7"
- else
- switch(H.hal_screwyhud)
- if(SCREWYHUD_CRIT) H.healths.icon_state = "health6"
- if(SCREWYHUD_DEAD) H.healths.icon_state = "health7"
- if(SCREWYHUD_HEALTHY) H.healths.icon_state = "health0"
- else
- switch(get_perceived_trauma(H))
- if(100 to INFINITY) H.healths.icon_state = "health0"
- if(80 to 100) H.healths.icon_state = "health1"
- if(60 to 80) H.healths.icon_state = "health2"
- if(40 to 60) H.healths.icon_state = "health3"
- if(20 to 40) H.healths.icon_state = "health4"
- if(0 to 20) H.healths.icon_state = "health5"
- else H.healths.icon_state = "health6"
-
-/datum/species/proc/handle_hud_icons_health_doll(mob/living/carbon/human/H)
- if(H.healthdoll)
- if(H.stat == DEAD || (H.status_flags & FAKEDEATH))
- H.healthdoll.icon_state = "healthdoll_DEAD"
- if(H.healthdoll.overlays.len)
- H.healthdoll.overlays.Cut()
- else
- var/list/new_overlays = list()
- var/list/cached_overlays = H.healthdoll.cached_healthdoll_overlays
- // Use the dead health doll as the base, since we have proper "healthy" overlays now
- H.healthdoll.icon_state = "healthdoll_DEAD"
- for(var/obj/item/organ/external/O in H.bodyparts)
- var/damage = O.burn_dam + O.brute_dam
- var/comparison = (O.max_damage/5)
- var/icon_num = 0
- if(damage)
- icon_num = 1
- if(damage > (comparison))
- icon_num = 2
- if(damage > (comparison*2))
- icon_num = 3
- if(damage > (comparison*3))
- icon_num = 4
- if(damage > (comparison*4))
- icon_num = 5
- new_overlays += "[O.limb_name][icon_num]"
- H.healthdoll.overlays += (new_overlays - cached_overlays)
- H.healthdoll.overlays -= (cached_overlays - new_overlays)
- H.healthdoll.cached_healthdoll_overlays = new_overlays
-
-/datum/species/proc/handle_hud_icons_nutrition(mob/living/carbon/human/H)
- if(NO_HUNGER in species_traits)
- return FALSE
- if(H.mind && H.mind.vampire && (H.mind in SSticker.mode.vampires)) //Vampires
- switch(H.nutrition)
- if(NUTRITION_LEVEL_FULL to INFINITY)
- H.throw_alert("nutrition", /obj/screen/alert/fat/vampire)
- if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
- H.throw_alert("nutrition", /obj/screen/alert/full/vampire)
- if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
- H.throw_alert("nutrition", /obj/screen/alert/well_fed/vampire)
- if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
- H.throw_alert("nutrition", /obj/screen/alert/fed/vampire)
- if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
- H.throw_alert("nutrition", /obj/screen/alert/hungry/vampire)
- else
- H.throw_alert("nutrition", /obj/screen/alert/starving/vampire)
- return 1
-
- else ///Any other non-vampires
- switch(H.nutrition)
- if(NUTRITION_LEVEL_FULL to INFINITY)
- H.throw_alert("nutrition", /obj/screen/alert/fat)
- if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
- H.throw_alert("nutrition", /obj/screen/alert/full)
- if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
- H.throw_alert("nutrition", /obj/screen/alert/well_fed)
- if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
- H.throw_alert("nutrition", /obj/screen/alert/fed)
- if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
- H.throw_alert("nutrition", /obj/screen/alert/hungry)
- else
- H.throw_alert("nutrition", /obj/screen/alert/starving)
- return 1
+/datum/species/proc/update_health_hud(mob/living/carbon/human/H)
+ return FALSE
/*
Returns the path corresponding to the corresponding organ
diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm
index 9f4a27a3c41..7ff32e38644 100644
--- a/code/modules/mob/living/carbon/human/species/golem.dm
+++ b/code/modules/mob/living/carbon/human/species/golem.dm
@@ -636,12 +636,11 @@
H.mutations.Add(COMIC)
H.equip_to_slot_or_del(new /obj/item/reagent_containers/food/drinks/bottle/bottleofbanana(H), slot_r_store)
H.equip_to_slot_or_del(new /obj/item/bikehorn(H), slot_l_store)
- H.AddComponent(/datum/component/waddling)
+ H.AddElement(/datum/element/waddling)
/datum/species/golem/bananium/on_species_loss(mob/living/carbon/C)
. = ..()
- GET_COMPONENT_FROM(waddling, /datum/component/waddling, C)
- waddling.Destroy()
+ C.RemoveElement(/datum/element/waddling)
/datum/species/golem/bananium/get_random_name()
var/clown_name = pick(GLOB.clown_names)
diff --git a/code/modules/mob/living/carbon/human/species/shadow.dm b/code/modules/mob/living/carbon/human/species/shadow.dm
index 63f062b8bc8..be2a7f44229 100644
--- a/code/modules/mob/living/carbon/human/species/shadow.dm
+++ b/code/modules/mob/living/carbon/human/species/shadow.dm
@@ -39,10 +39,10 @@
/datum/action/innate/shadow/darkvision/Activate()
var/mob/living/carbon/human/H = owner
if(!H.vision_type)
- H.vision_type = new /datum/vision_override/nightvision
+ H.set_sight(/datum/vision_override/nightvision)
to_chat(H, "You adjust your vision to pierce the darkness.")
else
- H.vision_type = null
+ H.set_sight(null)
to_chat(H, "You adjust your vision to recognize the shadows.")
/datum/species/shadow/on_species_gain(mob/living/carbon/human/H)
diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm
index 0a708db223f..60f972b69a4 100644
--- a/code/modules/mob/living/carbon/human/species/slime.dm
+++ b/code/modules/mob/living/carbon/human/species/slime.dm
@@ -95,7 +95,7 @@
var/obj/item/organ/external/E = H.bodyparts_by_name[organname]
if(istype(E) && E.dna && istype(E.dna.species, /datum/species/slime))
E.sync_colour_to_human(H)
- H.update_hair(0)
+ H.update_hair()
H.update_body()
..()
diff --git a/code/modules/mob/living/carbon/human/species/tajaran.dm b/code/modules/mob/living/carbon/human/species/tajaran.dm
index 1b1589cb6fd..903e4a32332 100644
--- a/code/modules/mob/living/carbon/human/species/tajaran.dm
+++ b/code/modules/mob/living/carbon/human/species/tajaran.dm
@@ -56,4 +56,4 @@
"is holding their breath!")
/datum/species/tajaran/handle_death(gibbed, mob/living/carbon/human/H)
- H.stop_tail_wagging(1)
+ H.stop_tail_wagging()
diff --git a/code/modules/mob/living/carbon/human/species/unathi.dm b/code/modules/mob/living/carbon/human/species/unathi.dm
index 61c34ab41d9..d4e9b02cd9b 100644
--- a/code/modules/mob/living/carbon/human/species/unathi.dm
+++ b/code/modules/mob/living/carbon/human/species/unathi.dm
@@ -104,7 +104,7 @@
return
/datum/species/unathi/handle_death(gibbed, mob/living/carbon/human/H)
- H.stop_tail_wagging(1)
+ H.stop_tail_wagging()
/datum/species/unathi/ashwalker
name = "Ash Walker"
diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm
index e803a33f3ec..6ac20e77b9b 100644
--- a/code/modules/mob/living/carbon/human/species/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/vox.dm
@@ -76,7 +76,7 @@
speciesbox = /obj/item/storage/box/survival_vox
/datum/species/vox/handle_death(gibbed, mob/living/carbon/human/H)
- H.stop_tail_wagging(1)
+ H.stop_tail_wagging()
/datum/species/vox/after_equip_job(datum/job/J, mob/living/carbon/human/H)
if(!H.mind || !H.mind.assigned_role || H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime")
diff --git a/code/modules/mob/living/carbon/human/species/vulpkanin.dm b/code/modules/mob/living/carbon/human/species/vulpkanin.dm
index 9a313042d2d..920cd86659d 100644
--- a/code/modules/mob/living/carbon/human/species/vulpkanin.dm
+++ b/code/modules/mob/living/carbon/human/species/vulpkanin.dm
@@ -50,4 +50,4 @@
"is holding their breath!")
/datum/species/vulpkanin/handle_death(gibbed, mob/living/carbon/human/H)
- H.stop_tail_wagging(1)
+ H.stop_tail_wagging()
diff --git a/code/modules/mob/living/carbon/human/species/wryn.dm b/code/modules/mob/living/carbon/human/species/wryn.dm
index 9e02e2e28be..080a67a032b 100644
--- a/code/modules/mob/living/carbon/human/species/wryn.dm
+++ b/code/modules/mob/living/carbon/human/species/wryn.dm
@@ -50,7 +50,7 @@
/datum/species/wryn/handle_death(gibbed, mob/living/carbon/human/H)
- for(var/mob/living/carbon/C in GLOB.living_mob_list)
+ for(var/mob/living/carbon/C in GLOB.alive_mob_list)
if(C.get_int_organ(/obj/item/organ/internal/wryn/hivenode))
to_chat(C, "Your antennae tingle as you are overcome with pain...")
to_chat(C, "It feels like part of you has died.") // This is bullshit
diff --git a/code/modules/mob/living/carbon/human/species/zombies.dm b/code/modules/mob/living/carbon/human/species/zombies.dm
deleted file mode 100644
index 1f1c4d979b7..00000000000
--- a/code/modules/mob/living/carbon/human/species/zombies.dm
+++ /dev/null
@@ -1,102 +0,0 @@
-#define REGENERATION_DELAY 60 // After taking damage, how long it takes for automatic regeneration to begin
-
-/datum/species/zombie
- // 1spooky
- name = "High-Functioning Zombie"
- name_plural = "High-Functioning Zombies"
- icobase = 'icons/mob/human_races/r_zombie.dmi'
- deform = 'icons/mob/human_races/r_def_zombie.dmi'
- dies_at_threshold = TRUE
- language = "Zombie"
- species_traits = list(NO_BLOOD, NOZOMBIE, NOTRANSSTING, NO_BREATHE, RADIMMUNE, NO_SCAN)
- var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
- warning_low_pressure = -1
- hazard_low_pressure = -1
- hazard_high_pressure = 999999999
- warning_high_pressure = 999999999
- cold_level_1 = -1
- cold_level_2 = -1
- cold_level_3 = -1
- tox_mod = 0
- flesh_color = "#00FF00" // for green examine text
- bodyflags = HAS_SKIN_COLOR
- dietflags = DIET_CARN
- has_organ = list(
- "heart" = /obj/item/organ/internal/heart,
- "lungs" = /obj/item/organ/internal/lungs,
- "liver" = /obj/item/organ/internal/liver,
- "kidneys" = /obj/item/organ/internal/kidneys,
- "brain" = /obj/item/organ/internal/brain,
- "appendix" = /obj/item/organ/internal/appendix,
- "eyes" = /obj/item/organ/internal/eyes,
- "ears" = /obj/item/organ/internal/ears)
-
-
-/datum/species/zombie/infectious
- name = "Infectious Zombie"
- mutanthands = /obj/item/zombie_hand
- icobase = 'icons/mob/human_races/r_zombie.dmi'
- deform = 'icons/mob/human_races/r_def_zombie.dmi'
- brute_mod = 0.8 // 120 damage to KO a zombie, which kills it
- burn_mod = 0.8
- clone_mod = 0.8
- brain_mod = 0.8
- stamina_mod = 0.8
- speed_mod = 1.6
- default_language = "Zombie"
- var/heal_rate = 1
- var/regen_cooldown = 0
-
-/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H, amount)
- . = min(20, amount)
-
-/datum/species/zombie/infectious/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, sharp = 0, obj/used_weapon = null)
- . = ..()
- if(damage)
- regen_cooldown = world.time + REGENERATION_DELAY
-
-/datum/species/zombie/infectious/handle_life(mob/living/carbon/human/H)
- . = ..()
- H.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
-
- //Zombies never actually die, they just fall down until they regenerate enough to rise back up.
- //They must be restrained, beheaded or gibbed to stop being a threat.
- if(regen_cooldown < world.time)
- var/heal_amt = heal_rate
- if(H.InCritical())
- heal_amt *= 2
- H.heal_overall_damage(heal_amt,heal_amt)
- H.adjustToxLoss(-heal_amt)
- if(!H.InCritical() && prob(4))
- playsound(H, pick(spooks), 50, TRUE, 10)
-
-//Congrats you somehow died so hard you stopped being a zombie
-/datum/species/zombie/infectious/handle_death(gibbed, mob/living/carbon/C)
- . = ..()
- var/obj/item/organ/internal/zombie_infection/infection
- infection = C.get_organ_slot("zombie_infection")
- if(infection)
- qdel(infection)
-
-/datum/species/zombie/infectious/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
- . = ..()
- // Deal with the source of this zombie corruption
- // Infection organ needs to be handled separately from mutant_organs
- // because it persists through species transitions
- if(mutanthands)
- H.drop_l_hand()
- H.drop_r_hand()
- H.put_in_hands(new mutanthands())
- H.put_in_hands(new mutanthands())
- var/obj/item/organ/internal/zombie_infection/infection
- infection = H.get_organ_slot("zombie_infection")
- if(!infection)
- infection = new()
- infection.insert(H)
-
-/datum/species/zombie/infectious/on_species_loss(mob/living/carbon/human/C, datum/species/old_species)
- QDEL_NULL(C.r_hand)
- QDEL_NULL(C.l_hand)
- return ..()
-
-#undef REGENERATION_DELAY
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index cbc768cdd02..1f38e564928 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -77,14 +77,14 @@ There are several things that need to be remembered:
If you wish to update several overlays at once, you can set the argument to 0 to disable the update and call
it manually:
e.g.
- update_inv_head(0)
- update_inv_l_hand(0)
+ update_inv_head()
+ update_inv_l_hand()
update_inv_r_hand() //<---calls update_icons()
or equivillantly:
- update_inv_head(0)
- update_inv_l_hand(0)
- update_inv_r_hand(0)
+ update_inv_head()
+ update_inv_l_hand()
+ update_inv_r_hand()
update_icons()
> If you need to update all overlays you can use regenerate_icons(). it works exactly like update_clothing used to.
@@ -124,7 +124,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//DAMAGE OVERLAYS
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists
-/mob/living/carbon/human/UpdateDamageIcon(var/update_icons=1)
+/mob/living/carbon/human/UpdateDamageIcon()
// first check whether something actually changed about damage appearance
var/damage_appearance = ""
@@ -164,7 +164,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//BASE MOB SPRITE
-/mob/living/carbon/human/proc/update_body(var/update_icons=1, var/rebuild_base=0)
+/mob/living/carbon/human/proc/update_body(rebuild_base = FALSE)
remove_overlay(BODY_LAYER)
remove_overlay(LIMBS_LAYER) // So we don't get the old species' sprite splatted on top of the new one's
remove_overlay(UNDERWEAR_LAYER)
@@ -273,27 +273,27 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[UNDERWEAR_LAYER] = mutable_appearance(underwear_standing, layer = -UNDERWEAR_LAYER)
apply_overlay(UNDERWEAR_LAYER)
- if(lip_style && (LIPS in dna.species.species_traits))
- var/icon/lips = icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "lips_[lip_style]_s")
- lips.Blend(lip_color, ICON_ADD)
- standing += mutable_appearance(lips, layer = -BODY_LAYER)
+ if(lip_style && (LIPS in dna.species.species_traits))
+ var/mutable_appearance/lips = mutable_appearance('icons/mob/human_face.dmi', "lips_[lip_style]_s")
+ lips.color = lip_color
+ standing += lips
overlays_standing[BODY_LAYER] = standing
apply_overlay(BODY_LAYER)
//tail
- update_tail_layer(0)
+ update_tail_layer()
update_int_organs()
//head accessory
- update_head_accessory(0)
+ update_head_accessory()
//markings
- update_markings(0)
+ update_markings()
//hair
- update_hair(0)
- update_fhair(0)
+ update_hair()
+ update_fhair()
//MARKINGS OVERLAY
-/mob/living/carbon/human/proc/update_markings(var/update_icons=1)
+/mob/living/carbon/human/proc/update_markings()
//Reset our markings.
remove_overlay(MARKINGS_LAYER)
@@ -325,7 +325,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(MARKINGS_LAYER)
//HEAD ACCESSORY OVERLAY
-/mob/living/carbon/human/proc/update_head_accessory(var/update_icons=1)
+/mob/living/carbon/human/proc/update_head_accessory()
//Reset our head accessory
remove_overlay(HEAD_ACCESSORY_LAYER)
remove_overlay(HEAD_ACC_OVER_LAYER)
@@ -362,7 +362,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//HAIR OVERLAY
-/mob/living/carbon/human/proc/update_hair(var/update_icons=1)
+/mob/living/carbon/human/proc/update_hair()
//Reset our hair
remove_overlay(HAIR_LAYER)
@@ -376,7 +376,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//base icons
var/icon/hair_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
- if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic())))
+ if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(ismachineperson(src))))
var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style]
if(hair_style && hair_style.species_allowed)
if((head_organ.dna.species.name in hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics...
@@ -403,7 +403,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//FACIAL HAIR OVERLAY
-/mob/living/carbon/human/proc/update_fhair(var/update_icons=1)
+/mob/living/carbon/human/proc/update_fhair()
//Reset our facial hair
remove_overlay(FHAIR_LAYER)
remove_overlay(FHAIR_OVER_LAYER)
@@ -447,7 +447,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
-/mob/living/carbon/human/update_mutations(var/update_icons=1)
+/mob/living/carbon/human/update_mutations()
remove_overlay(MUTATIONS_LAYER)
var/mutable_appearance/standing = mutable_appearance('icons/effects/genetics.dmi', layer = -MUTATIONS_LAYER)
var/add_image = 0
@@ -478,7 +478,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(MUTATIONS_LAYER)
-/mob/living/carbon/human/proc/update_mutantrace(var/update_icons=1)
+/mob/living/carbon/human/proc/update_mutantrace()
//BS12 EDIT
var/skel = (SKELETON in mutations)
if(skel)
@@ -486,8 +486,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
else
skeleton = null
- update_hair(0)
- update_fhair(0)
+ update_hair()
+ update_fhair()
/mob/living/carbon/human/update_fire()
@@ -501,41 +501,42 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//For legacy support.
/mob/living/carbon/human/regenerate_icons()
..()
- if(notransform) return
- update_mutations(0)
- update_body(0, 1) //Update the body and force limb icon regeneration.
- update_hair(0)
- update_head_accessory(0)
- update_fhair(0)
- update_mutantrace(0)
- update_inv_w_uniform(0,0)
- update_inv_wear_id(0)
- update_inv_gloves(0,0)
- update_inv_glasses(0)
- update_inv_ears(0)
- update_inv_shoes(0,0)
- update_inv_s_store(0)
- update_inv_wear_mask(0)
- update_inv_head(0,0)
- update_inv_belt(0)
- update_inv_back(0)
- update_inv_wear_suit(0)
- update_inv_r_hand(0)
- update_inv_l_hand(0)
- update_inv_handcuffed(0)
- update_inv_legcuffed(0)
- update_inv_pockets(0)
- update_inv_wear_pda(0)
- UpdateDamageIcon(0)
+ if(notransform)
+ return
+ update_mutations()
+ update_body(TRUE) //Update the body and force limb icon regeneration.
+ update_hair()
+ update_head_accessory()
+ update_fhair()
+ update_mutantrace()
+ update_inv_w_uniform()
+ update_inv_wear_id()
+ update_inv_gloves()
+ update_inv_glasses()
+ update_inv_ears()
+ update_inv_shoes()
+ update_inv_s_store()
+ update_inv_wear_mask()
+ update_inv_head()
+ update_inv_belt()
+ update_inv_back()
+ update_inv_wear_suit()
+ update_inv_r_hand()
+ update_inv_l_hand()
+ update_inv_handcuffed()
+ update_inv_legcuffed()
+ update_inv_pockets()
+ update_inv_wear_pda()
+ UpdateDamageIcon()
force_update_limbs()
- update_tail_layer(0)
+ update_tail_layer()
overlays.Cut() // Force all overlays to regenerate
update_fire()
update_icons()
/* --------------------------------------- */
//vvvvvv UPDATE_INV PROCS vvvvvv
-/mob/living/carbon/human/update_inv_w_uniform(var/update_icons=1)
+/mob/living/carbon/human/update_inv_w_uniform()
remove_overlay(UNIFORM_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_w_uniform]
@@ -593,7 +594,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
thing.plane = initial(thing.plane)
apply_overlay(UNIFORM_LAYER)
-/mob/living/carbon/human/update_inv_wear_id(var/update_icons=1)
+/mob/living/carbon/human/update_inv_wear_id()
remove_overlay(ID_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_id]
@@ -609,7 +610,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[ID_LAYER] = mutable_appearance('icons/mob/mob.dmi', "id", layer = -ID_LAYER)
apply_overlay(ID_LAYER)
-/mob/living/carbon/human/update_inv_gloves(var/update_icons=1)
+/mob/living/carbon/human/update_inv_gloves()
remove_overlay(GLOVES_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves]
@@ -646,7 +647,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(GLOVES_LAYER)
-/mob/living/carbon/human/update_inv_glasses(var/update_icons=1)
+/mob/living/carbon/human/update_inv_glasses()
remove_overlay(GLASSES_LAYER)
remove_overlay(GLASSES_OVER_LAYER)
remove_overlay(OVER_MASK_LAYER)
@@ -687,7 +688,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
update_misc_effects()
-/mob/living/carbon/human/update_inv_ears(var/update_icons=1)
+/mob/living/carbon/human/update_inv_ears()
remove_overlay(EARS_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_l_ear]
@@ -735,7 +736,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[EARS_LAYER] = mutable_appearance('icons/mob/ears.dmi', "[t_type]", layer = -EARS_LAYER)
apply_overlay(EARS_LAYER)
-/mob/living/carbon/human/update_inv_shoes(var/update_icons=1)
+/mob/living/carbon/human/update_inv_shoes()
remove_overlay(SHOES_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_shoes]
@@ -771,7 +772,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[SHOES_LAYER] = bloodsies
apply_overlay(SHOES_LAYER)
-/mob/living/carbon/human/update_inv_s_store(var/update_icons=1)
+/mob/living/carbon/human/update_inv_s_store()
remove_overlay(SUIT_STORE_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_s_store]
@@ -792,7 +793,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(SUIT_STORE_LAYER)
-/mob/living/carbon/human/update_inv_head(var/update_icons=1)
+/mob/living/carbon/human/update_inv_head()
..()
remove_overlay(HEAD_LAYER)
if(client && hud_used)
@@ -818,7 +819,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[HEAD_LAYER] = standing
apply_overlay(HEAD_LAYER)
-/mob/living/carbon/human/update_inv_belt(var/update_icons=1)
+/mob/living/carbon/human/update_inv_belt()
remove_overlay(BELT_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_belt]
@@ -844,7 +845,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(BELT_LAYER)
-/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1)
+/mob/living/carbon/human/update_inv_wear_suit()
remove_overlay(SUIT_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_suit]
@@ -885,8 +886,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[SUIT_LAYER] = standing
apply_overlay(SUIT_LAYER)
- update_tail_layer(0)
- update_collar(0)
+ update_tail_layer()
+ update_collar()
/mob/living/carbon/human/update_inv_pockets()
if(client && hud_used)
@@ -919,7 +920,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
client.screen += wear_pda
wear_pda.screen_loc = ui_pda
-/mob/living/carbon/human/update_inv_wear_mask(var/update_icons = 1)
+/mob/living/carbon/human/update_inv_wear_mask()
..()
remove_overlay(FACEMASK_LAYER)
if(client && hud_used)
@@ -955,7 +956,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(FACEMASK_LAYER)
-/mob/living/carbon/human/update_inv_back(var/update_icons=1)
+/mob/living/carbon/human/update_inv_back()
..()
remove_overlay(BACK_LAYER)
if(back)
@@ -978,7 +979,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[BACK_LAYER] = standing
apply_overlay(BACK_LAYER)
-/mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1)
+/mob/living/carbon/human/update_inv_handcuffed()
remove_overlay(HANDCUFF_LAYER)
if(handcuffed)
if(istype(handcuffed, /obj/item/restraints/handcuffs/pinkcuffs))
@@ -987,7 +988,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[HANDCUFF_LAYER] = mutable_appearance('icons/mob/mob.dmi', "handcuff1", layer = -HANDCUFF_LAYER)
apply_overlay(HANDCUFF_LAYER)
-/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
+/mob/living/carbon/human/update_inv_legcuffed()
remove_overlay(LEGCUFF_LAYER)
clear_alert("legcuffed")
if(legcuffed)
@@ -1000,7 +1001,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(LEGCUFF_LAYER)
-/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1)
+/mob/living/carbon/human/update_inv_r_hand()
..()
remove_overlay(R_HAND_LAYER)
if(r_hand)
@@ -1019,7 +1020,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(R_HAND_LAYER)
-/mob/living/carbon/human/update_inv_l_hand(var/update_icons=1)
+/mob/living/carbon/human/update_inv_l_hand()
..()
remove_overlay(L_HAND_LAYER)
if(l_hand)
@@ -1060,7 +1061,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
client.screen += I
-/mob/living/carbon/human/proc/update_tail_layer(var/update_icons=1)
+/mob/living/carbon/human/proc/update_tail_layer()
remove_overlay(TAIL_UNDERLIMBS_LAYER) // SEW direction icons, overlayed by LIMBS_LAYER.
remove_overlay(TAIL_LAYER) /* This will be one of two things:
If the species' tail is overlapped by limbs, this will be only the N direction icon so tails
@@ -1135,7 +1136,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(TAIL_LAYER)
apply_overlay(TAIL_UNDERLIMBS_LAYER)
-/mob/living/carbon/human/proc/start_tail_wagging(var/update_icons=1)
+/mob/living/carbon/human/proc/start_tail_wagging()
remove_overlay(TAIL_UNDERLIMBS_LAYER) // SEW direction icons, overlayed by LIMBS_LAYER.
remove_overlay(TAIL_LAYER) /* This will be one of two things:
If the species' tail is overlapped by limbs, this will be only the N direction icon so tails
@@ -1211,10 +1212,10 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(TAIL_LAYER)
apply_overlay(TAIL_UNDERLIMBS_LAYER)
-/mob/living/carbon/human/proc/stop_tail_wagging(var/update_icons=1)
+/mob/living/carbon/human/proc/stop_tail_wagging()
remove_overlay(TAIL_UNDERLIMBS_LAYER)
remove_overlay(TAIL_LAYER)
- update_tail_layer(update_icons) //just trigger a full update for normal stationary sprites
+ update_tail_layer() //just trigger a full update for normal stationary sprites
/mob/living/carbon/human/proc/update_int_organs()
remove_overlay(INTORGAN_LAYER)
@@ -1236,7 +1237,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//Adds a collar overlay above the helmet layer if the suit has one
// Suit needs an identically named sprite in icons/mob/collar.dmi
// For suits with sprite_sheets, an identically named sprite needs to exist in a file like this icons/mob/species/[species_name_here]/collar.dmi.
-/mob/living/carbon/human/proc/update_collar(var/update_icons=1)
+/mob/living/carbon/human/proc/update_collar()
remove_overlay(COLLAR_LAYER)
var/icon/C = new('icons/mob/collar.dmi')
var/mutable_appearance/standing = null
@@ -1282,7 +1283,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
/mob/living/carbon/human/proc/force_update_limbs()
for(var/obj/item/organ/external/O in bodyparts)
O.sync_colour_to_human(src)
- update_body(0)
+ update_body()
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
var/list/out = new
diff --git a/code/modules/mob/living/carbon/human/update_stat.dm b/code/modules/mob/living/carbon/human/update_stat.dm
index 14c87e13722..d5d1801e1a7 100644
--- a/code/modules/mob/living/carbon/human/update_stat.dm
+++ b/code/modules/mob/living/carbon/human/update_stat.dm
@@ -12,7 +12,7 @@
/mob/living/carbon/human/update_nearsighted_effects()
var/obj/item/clothing/glasses/G = glasses
- if((disabilities & NEARSIGHTED) && (!istype(G) || !G.prescription))
+ if((NEARSIGHTED in mutations) && (!istype(G) || !G.prescription))
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
else
clear_fullscreen("nearsighted")
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 87832154876..c11eaca5293 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -1,25 +1,39 @@
/mob/living/carbon/Life(seconds, times_fired)
set invisibility = 0
- set background = BACKGROUND_ENABLED
if(notransform)
return
- if(!loc)
+
+ if(damageoverlaytemp)
+ damageoverlaytemp = 0
+ update_damage_hud()
+
+ if(stat != DEAD)
+ handle_organs()
+
+ //stuff in the stomach
+ if(LAZYLEN(stomach_contents))
+ handle_stomach(times_fired)
+
+ . = ..()
+
+ if(QDELETED(src))
return
- if(..())
- . = 1
+ if(.) //not dead
handle_blood()
- for(var/obj/item/organ/internal/O in internal_organs)
- O.on_life()
- handle_patches()
- handle_changeling()
+ if(LAZYLEN(processing_patches))
+ handle_patches()
+ if(mind)
+ handle_changeling()
handle_wetness(times_fired)
// Increase germ_level regularly
- if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
- germ_level++
+ handle_germs()
+
+ if(stat != DEAD)
+ return TRUE
///////////////
@@ -112,7 +126,7 @@
var/O2_partialpressure = (breath.oxygen/breath.total_moles())*breath_pressure
var/Toxins_partialpressure = (breath.toxins/breath.total_moles())*breath_pressure
var/CO2_partialpressure = (breath.carbon_dioxide/breath.total_moles())*breath_pressure
-
+ var/SA_partialpressure = (breath.sleeping_agent/breath.total_moles())*breath_pressure
//OXYGEN
if(O2_partialpressure < safe_oxy_min) //Not enough oxygen
@@ -152,22 +166,20 @@
//TOXINS/PLASMA
if(Toxins_partialpressure > safe_tox_max)
var/ratio = (breath.toxins/safe_tox_max) * 10
- adjustToxLoss(Clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
+ adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
clear_alert("too_much_tox")
//TRACE GASES
- if(breath.trace_gases.len)
- for(var/datum/gas/sleeping_agent/SA in breath.trace_gases)
- var/SA_partialpressure = (SA.moles/breath.total_moles())*breath_pressure
- if(SA_partialpressure > SA_para_min)
- Paralyse(3)
- if(SA_partialpressure > SA_sleep_min)
- AdjustSleeping(2, bound_lower = 0, bound_upper = 10)
- else if(SA_partialpressure > 0.01)
- if(prob(20))
- emote(pick("giggle","laugh"))
+ if(breath.sleeping_agent)
+ if(SA_partialpressure > SA_para_min)
+ Paralyse(3)
+ if(SA_partialpressure > SA_sleep_min)
+ AdjustSleeping(2, bound_lower = 0, bound_upper = 10)
+ else if(SA_partialpressure > 0.01)
+ if(prob(20))
+ emote(pick("giggle","laugh"))
//BREATH TEMPERATURE
handle_breath_temperature(breath)
@@ -192,6 +204,11 @@
else
update_action_buttons_icon()
+/mob/living/carbon/proc/handle_organs()
+ for(var/thing in internal_organs)
+ var/obj/item/organ/internal/O = thing
+ O.on_life()
+
/mob/living/carbon/handle_diseases()
for(var/thing in viruses)
var/datum/disease/D = thing
@@ -230,26 +247,26 @@
adjustToxLoss(3)
updatehealth("handle mutations and radiation(75-100)")
- radiation = Clamp(radiation, 0, 100)
+ radiation = clamp(radiation, 0, 100)
/mob/living/carbon/handle_chemicals_in_body()
- if(reagents)
- reagents.metabolize(src)
+ reagents.metabolize(src)
/mob/living/carbon/proc/handle_wetness(times_fired)
if(times_fired % 20==2) //dry off a bit once every 20 ticks or so
wetlevel = max(wetlevel - 1,0)
-/mob/living/carbon/handle_stomach(times_fired)
- for(var/mob/living/M in stomach_contents)
+/mob/living/carbon/proc/handle_stomach(times_fired)
+ for(var/thing in stomach_contents)
+ var/mob/living/M = thing
if(M.loc != src)
- stomach_contents.Remove(M)
+ LAZYREMOVE(stomach_contents, M)
continue
if(stat != DEAD)
if(M.stat == DEAD)
- stomach_contents.Remove(M)
+ LAZYREMOVE(stomach_contents, M)
qdel(M)
continue
if(times_fired % 3 == 1)
@@ -262,7 +279,9 @@
if(stam_regen_start_time <= world.time)
if(stam_paralyzed)
update_stamina()
- setStaminaLoss(0, FALSE)
+ if(staminaloss)
+ setStaminaLoss(0, FALSE)
+ update_health_hud()
var/restingpwr = 1 + 4 * resting
@@ -320,8 +339,17 @@
AdjustHallucinate(-2)
+ // Keep SSD people asleep
+ if(player_logged)
+ Sleeping(2)
+
/mob/living/carbon/handle_sleeping()
if(..())
+ if(mind?.vampire)
+ if(istype(loc, /obj/structure/closet/coffin))
+ adjustBruteLoss(-1, FALSE)
+ adjustFireLoss(-1, FALSE)
+ adjustToxLoss(-1)
handle_dreams()
adjustStaminaLoss(-10)
var/comfort = 1
@@ -337,44 +365,42 @@
comfort += 1 //Aren't naps SO much better when drunk?
AdjustDrunk(-0.2*comfort) //reduce drunkenness while sleeping.
if(comfort > 1 && prob(3))//You don't heal if you're just sleeping on the floor without a blanket.
- adjustBruteLoss(-1*comfort)
- adjustFireLoss(-1*comfort)
+ adjustBruteLoss(-1 * comfort, FALSE)
+ adjustFireLoss(-1 * comfort)
if(prob(10) && health && hal_screwyhud != SCREWYHUD_CRIT)
emote("snore")
- // Keep SSD people asleep
- if(player_logged)
- Sleeping(2)
+
return sleeping
-/mob/living/carbon/handle_hud_icons()
- return
-
-/mob/living/carbon/handle_hud_icons_health()
+/mob/living/carbon/update_health_hud(shown_health_amount)
if(!client)
return
if(healths)
if(stat != DEAD)
- switch(health)
- if(100 to INFINITY)
- healths.icon_state = "health0"
- if(80 to 100)
- healths.icon_state = "health1"
- if(60 to 80)
- healths.icon_state = "health2"
- if(40 to 60)
- healths.icon_state = "health3"
- if(20 to 40)
- healths.icon_state = "health4"
- if(0 to 20)
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
+ . = TRUE
+ if(shown_health_amount == null)
+ shown_health_amount = health
+ if(shown_health_amount >= maxHealth)
+ healths.icon_state = "health0"
+ else if(shown_health_amount > maxHealth * 0.8)
+ healths.icon_state = "health1"
+ else if(shown_health_amount > maxHealth * 0.6)
+ healths.icon_state = "health2"
+ else if(shown_health_amount > maxHealth * 0.4)
+ healths.icon_state = "health3"
+ else if(shown_health_amount > maxHealth * 0.2)
+ healths.icon_state = "health4"
+ else if(shown_health_amount > 0)
+ healths.icon_state = "health5"
+ else
+ healths.icon_state = "health6"
else
healths.icon_state = "health7"
- handle_hud_icons_health_overlay()
-/mob/living/carbon/proc/handle_hud_icons_health_overlay()
+/mob/living/carbon/update_damage_hud()
+ if(!client)
+ return
if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT)
if(check_death_method())
var/severity = 0
@@ -441,20 +467,23 @@
clear_fullscreen("brute")
/mob/living/carbon/proc/handle_patches()
- if(LAZYLEN(processing_patches))
- var/multiple_patch_multiplier = processing_patches.len > 1 ? (processing_patches.len * 1.5) : 1
- var/applied_amount = 0.35 * multiple_patch_multiplier
+ var/multiple_patch_multiplier = processing_patches.len > 1 ? (processing_patches.len * 1.5) : 1
+ var/applied_amount = 0.35 * multiple_patch_multiplier
- for(var/patch in processing_patches)
- var/obj/item/reagent_containers/food/pill/patch/P = patch
+ for(var/patch in processing_patches)
+ var/obj/item/reagent_containers/food/pill/patch/P = patch
- if(P.reagents && P.reagents.total_volume)
- var/fractional_applied_amount = applied_amount / P.reagents.total_volume
- P.reagents.reaction(src, REAGENT_TOUCH, fractional_applied_amount, P.needs_to_apply_reagents)
- P.needs_to_apply_reagents = FALSE
- P.reagents.trans_to(src, applied_amount * 0.5)
- P.reagents.remove_any(applied_amount * 0.5)
- else
- if(!P.reagents || P.reagents.total_volume <= 0)
- processing_patches -= P
- qdel(P)
+ if(P.reagents && P.reagents.total_volume)
+ var/fractional_applied_amount = applied_amount / P.reagents.total_volume
+ P.reagents.reaction(src, REAGENT_TOUCH, fractional_applied_amount, P.needs_to_apply_reagents)
+ P.needs_to_apply_reagents = FALSE
+ P.reagents.trans_to(src, applied_amount * 0.5)
+ P.reagents.remove_any(applied_amount * 0.5)
+ else
+ if(!P.reagents || P.reagents.total_volume <= 0)
+ LAZYREMOVE(processing_patches, P)
+ qdel(P)
+
+/mob/living/carbon/proc/handle_germs()
+ if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
+ germ_level++
diff --git a/code/modules/mob/living/carbon/update_status.dm b/code/modules/mob/living/carbon/update_status.dm
index b67953c7e69..918968800ce 100644
--- a/code/modules/mob/living/carbon/update_status.dm
+++ b/code/modules/mob/living/carbon/update_status.dm
@@ -2,12 +2,10 @@
if(status_flags & GODMODE)
return
if(stat != DEAD)
-// if(health <= min_health)
if(health <= HEALTH_THRESHOLD_DEAD && check_death_method())
death()
create_debug_log("died of damage, trigger reason: [reason]")
return
-// if(paralysis || sleeping || getOxyLoss() > low_oxy_ko || (status_flags & FAKEDEATH) || health <= crit_health)
if(paralysis || sleeping || (check_death_method() && getOxyLoss() > 50) || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT && check_death_method())
if(stat == CONSCIOUS)
KnockOut()
@@ -16,6 +14,9 @@
if(stat == UNCONSCIOUS)
WakeUp()
create_debug_log("woke up, trigger reason: [reason]")
+ update_damage_hud()
+ update_health_hud()
+ med_hud_set_status()
/mob/living/carbon/update_stamina()
var/stam = getStaminaLoss()
@@ -24,7 +25,6 @@
else if(stam_paralyzed)
stam_paralyzed = FALSE
update_canmove()
- handle_hud_icons_health()
/mob/living/carbon/can_hear()
. = FALSE
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index fa1c392334d..60f186631b7 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -269,6 +269,7 @@
if(amount > 0)
stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME
if(updating)
+ update_health_hud()
update_stamina()
/mob/living/proc/setStaminaLoss(amount, updating = TRUE)
@@ -284,6 +285,7 @@
if(amount > 0)
stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME
if(updating)
+ update_health_hud()
update_stamina()
/mob/living/proc/getMaxHealth()
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index 0984c56decb..6af90792355 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -61,10 +61,13 @@
if(mind && suiciding)
mind.suicided = TRUE
+ reset_perspective(null)
clear_fullscreens()
update_sight()
update_action_buttons_icon()
+ update_damage_hud()
+ update_health_hud()
med_hud_set_health()
med_hud_set_status()
if(!gibbed && !QDELETED(src))
@@ -83,7 +86,7 @@
timeofdeath = world.time
create_log(ATTACK_LOG, "died[gibbed ? " (Gibbed)": ""]")
- GLOB.living_mob_list -= src
+ GLOB.alive_mob_list -= src
GLOB.dead_mob_list += src
if(mind)
mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 5ab604e5b3e..3062ef461f9 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -1,12 +1,10 @@
-/mob/living/Life(seconds, times_fired)
+/mob/living/proc/Life(seconds, times_fired)
+ set waitfor = FALSE
set invisibility = 0
- set background = BACKGROUND_ENABLED
- if(notransform)
- return FALSE
- if(!loc)
- return FALSE
- var/datum/gas_mixture/environment = loc.return_air()
+ if(flying) //TODO: Better floating
+ animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING)
+ animate(pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING)
if(client || registered_z) // This is a temporary error tracker to make sure we've caught everything
var/turf/T = get_turf(src)
@@ -17,51 +15,83 @@
else if (!client && registered_z)
log_game("Z-TRACKING: [src] of type [src.type] has a Z-registration despite not having a client.")
update_z(null)
+
+ if(notransform)
+ return FALSE
+ if(!loc)
+ return FALSE
+
if(stat != DEAD)
//Chemicals in the body
- handle_chemicals_in_body()
+ if(reagents)
+ handle_chemicals_in_body()
+ if(QDELETED(src)) // some chems can gib mobs
+ return
+
+ if(stat != DEAD)
//Mutations and radiation
handle_mutations_and_radiation()
+ if(stat != DEAD)
//Breathing, if applicable
handle_breathing(times_fired)
+ if(stat != DEAD)
//Random events (vomiting etc)
handle_random_events()
- . = 1
+ if(LAZYLEN(viruses))
+ handle_diseases()
- handle_diseases()
+ if(QDELETED(src)) // diseases can qdel the mob via transformations
+ return
//Heart Attack, if applicable
if(stat != DEAD)
handle_heartattack()
//Handle temperature/pressure differences between body and environment
+ var/datum/gas_mixture/environment = loc.return_air()
if(environment)
handle_environment(environment)
handle_fire()
- //stuff in the stomach
- handle_stomach(times_fired)
-
update_gravity(mob_has_gravity())
- update_pulling()
+ if(pulling)
+ update_pulling()
for(var/obj/item/grab/G in src)
G.process()
- if(handle_regular_status_updates()) // Status & health update, are we dead or alive etc.
+ if(stat != DEAD)
+ handle_critical_condition()
+
+ if(stat != DEAD) // Status & health update, are we dead or alive etc.
handle_disabilities() // eye, ear, brain damages
+
+ if(stat != DEAD)
handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
- if(client)
- handle_regular_hud_updates()
+ if(stat != DEAD)
+ if(forced_look)
+ if(!isnum(forced_look))
+ var/atom/A = locateUID(forced_look)
+ if(istype(A))
+ var/view = client ? client.view : world.view
+ if(get_dist(src, A) > view || !(src in viewers(view, A)))
+ forced_look = null
+ to_chat(src, "Your direction target has left your view, you are no longer facing anything.")
+ return
+ setDir()
- ..()
+ if(machine)
+ machine.check_eye(src)
+
+ if(stat != DEAD)
+ return TRUE
/mob/living/proc/handle_breathing(times_fired)
return
@@ -71,7 +101,6 @@
/mob/living/proc/handle_mutations_and_radiation()
radiation = 0 //so radiation don't accumulate in simple animals
- return
/mob/living/proc/handle_chemicals_in_body()
return
@@ -85,126 +114,55 @@
/mob/living/proc/handle_environment(datum/gas_mixture/environment)
return
-/mob/living/proc/handle_stomach(times_fired)
- return
-
/mob/living/proc/update_pulling()
- if(pulling)
- if(incapacitated())
- stop_pulling()
-
-//This updates the health and status of the mob (conscious, unconscious, dead)
-/mob/living/proc/handle_regular_status_updates()
- return stat != DEAD
+ if(incapacitated())
+ stop_pulling()
//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
-/mob/living/proc/handle_status_effects()
- handle_stunned()
- handle_weakened()
- handle_stuttering()
- handle_silent()
- handle_drugged()
- handle_slurring()
- handle_paralysed()
- handle_sleeping()
- handle_slowed()
- handle_drunk()
- handle_cultslurring()
-
-
-/mob/living/proc/handle_stunned()
+/mob/living/proc/handle_status_effects() // We check for the status effect in this proc as opposed to the procs below to avoid excessive proc call overhead
if(stunned)
AdjustStunned(-1, updating = 1, force = 1)
- if(!stunned)
- update_icons()
- return stunned
-
-/mob/living/proc/handle_weakened()
if(weakened)
AdjustWeakened(-1, updating = 1, force = 1)
- if(!weakened)
- update_icons()
- return weakened
-
-/mob/living/proc/handle_stuttering()
if(stuttering)
- stuttering = max(stuttering-1, 0)
- return stuttering
-
-/mob/living/proc/handle_silent()
+ stuttering = max(stuttering - 1, 0)
if(silent)
AdjustSilence(-1)
- return silent
-
-/mob/living/proc/handle_drugged()
if(druggy)
AdjustDruggy(-1)
- return druggy
-
-/mob/living/proc/handle_slurring()
if(slurring)
AdjustSlur(-1)
- return slurring
-
-/mob/living/proc/handle_cultslurring()
- if(cultslurring)
- AdjustCultSlur(-1)
- return cultslurring
-
-/mob/living/proc/handle_paralysed()
if(paralysis)
AdjustParalysis(-1, updating = 1, force = 1)
- return paralysis
-
-/mob/living/proc/handle_sleeping()
if(sleeping)
- AdjustSleeping(-1)
- throw_alert("asleep", /obj/screen/alert/asleep)
- else
- clear_alert("asleep")
- return sleeping
-
-/mob/living/proc/handle_slowed()
+ handle_sleeping()
if(slowed)
AdjustSlowed(-1)
- return slowed
+ if(drunk)
+ handle_drunk()
+ if(cultslurring)
+ AdjustCultSlur(-1)
+
+/mob/living/proc/update_damage_hud()
+ return
+
+/mob/living/proc/handle_sleeping()
+ AdjustSleeping(-1)
+ return sleeping
/mob/living/proc/handle_drunk()
- if(drunk)
- AdjustDrunk(-1)
+ AdjustDrunk(-1)
return drunk
/mob/living/proc/handle_disabilities()
//Eyes
- if(disabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own
+ if((BLINDNESS in mutations) || stat) //blindness from disability or unconsciousness doesn't get better on its own
EyeBlind(1)
else if(eye_blind) //blindness, heals slowly over time
AdjustEyeBlind(-1)
else if(eye_blurry) //blurry eyes heal slowly
AdjustEyeBlurry(-1)
-//this handles hud updates. Calls update_vision() and handle_hud_icons()
-/mob/living/proc/handle_regular_hud_updates()
- if(!client) return 0
-
- handle_vision()
- handle_hud_icons()
-
- return 1
-
-/mob/living/proc/handle_vision()
- update_sight()
-
- if(stat == DEAD)
- return
-
- if(machine)
- if(!machine.check_eye(src))
- reset_perspective(null)
- else
- if(!remote_view && !client.adminobs)
- reset_perspective(null)
-
// Gives a mob the vision of being dead
/mob/living/proc/grant_death_vision()
sight |= SEE_TURFS
@@ -215,9 +173,37 @@
see_invisible = SEE_INVISIBLE_OBSERVER
sync_lighting_plane_alpha()
-/mob/living/proc/handle_hud_icons()
- handle_hud_icons_health()
+/mob/living/proc/handle_critical_condition()
return
-/mob/living/proc/handle_hud_icons_health()
- return
+/mob/living/update_health_hud()
+ if(!client)
+ return
+ if(healths)
+ var/severity = 0
+ var/healthpercent = (health / maxHealth) * 100
+ switch(healthpercent)
+ if(100 to INFINITY)
+ healths.icon_state = "health0"
+ if(80 to 100)
+ healths.icon_state = "health1"
+ severity = 1
+ if(60 to 80)
+ healths.icon_state = "health2"
+ severity = 2
+ if(40 to 60)
+ healths.icon_state = "health3"
+ severity = 3
+ if(20 to 40)
+ healths.icon_state = "health4"
+ severity = 4
+ if(1 to 20)
+ healths.icon_state = "health5"
+ severity = 5
+ else
+ healths.icon_state = "health7"
+ severity = 6
+ if(severity > 0)
+ overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
+ else
+ clear_fullscreen("brute")
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 8371cacaebe..f3d23ca3f51 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -3,6 +3,7 @@
var/datum/atom_hud/data/human/medical/advanced/medhud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
medhud.add_to_hud(src)
faction += "\ref[src]"
+ GLOB.mob_living_list += src
/mob/living/prepare_huds()
..()
@@ -17,7 +18,7 @@
if(ranged_ability)
ranged_ability.remove_ranged_ability(src)
remove_from_all_data_huds()
-
+ GLOB.mob_living_list -= src
if(LAZYLEN(status_effects))
for(var/s in status_effects)
var/datum/status_effect/S = s
@@ -285,8 +286,9 @@
health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
update_stat("updatehealth([reason])")
- handle_hud_icons_health()
med_hud_set_health()
+ med_hud_set_status()
+ update_health_hud()
//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
@@ -680,9 +682,6 @@
*/////////////////////
/mob/living/proc/resist_grab()
var/resisting = 0
- for(var/obj/O in requests)
- qdel(O)
- resisting++
for(var/X in grabbed_by)
var/obj/item/grab/G = X
resisting++
@@ -738,7 +737,8 @@
clear_alert("weightless")
else
throw_alert("weightless", /obj/screen/alert/weightless)
- float(!has_gravity)
+ if(!flying)
+ float(!has_gravity)
/mob/living/proc/float(on)
if(throwing)
@@ -759,7 +759,7 @@
//called when the mob receives a bright flash
/mob/living/proc/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
- if(check_eye_prot() < intensity && (override_blindness_check || !(disabilities & BLIND)))
+ if(check_eye_prot() < intensity && (override_blindness_check || !(BLINDNESS in mutations)))
overlay_fullscreen("flash", type)
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
return 1
@@ -802,7 +802,7 @@
if(do_mob(src, who, what.put_on_delay))
if(what && Adjacent(who) && !(what.flags & NODROP))
unEquip(what)
- who.equip_to_slot_if_possible(what, where, 0, 1)
+ who.equip_to_slot_if_possible(what, where, FALSE, TRUE)
add_attack_logs(src, who, "Equipped [what]")
/mob/living/singularity_act()
@@ -823,8 +823,7 @@
spawn_dust()
gib()
-/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
- end_pixel_y = get_standard_pixel_y_offset(lying)
+/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
if(!used_item)
used_item = get_active_hand()
..()
@@ -1025,9 +1024,9 @@
if("stat")
if((stat == DEAD) && (var_value < DEAD))//Bringing the dead back to life
GLOB.dead_mob_list -= src
- GLOB.living_mob_list += src
+ GLOB.alive_mob_list += src
if((stat < DEAD) && (var_value == DEAD))//Kill he
- GLOB.living_mob_list -= src
+ GLOB.alive_mob_list -= src
GLOB.dead_mob_list += src
. = ..()
switch(var_name)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 604fd47de16..b38f1819524 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -79,9 +79,9 @@
/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
if(throwforce && w_class)
- return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
+ return clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
else if(w_class)
- return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
+ return clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
else
return 0
@@ -175,7 +175,7 @@
return
/mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person
- fire_stacks = Clamp(fire_stacks + add_fire_stacks, -20, 20)
+ fire_stacks = clamp(fire_stacks + add_fire_stacks, -20, 20)
if(on_fire && fire_stacks <= 0)
ExtinguishMob()
@@ -260,8 +260,6 @@
add_attack_logs(user, src, "Grabbed passively", ATKLOG_ALL)
var/obj/item/grab/G = new /obj/item/grab(user, src)
- if(buckled)
- to_chat(user, "You cannot grab [src]; [p_they()] [p_are()] buckled in!")
if(!G) //the grab will delete itself in New if src is anchored
return 0
user.put_in_active_hand(G)
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index edb62d0e013..630b2223321 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -61,7 +61,7 @@ proc/get_radio_key_from_channel(var/channel)
return default_language
/mob/living/proc/handle_speech_problems(list/message_pieces, var/verb)
- var/robot = isSynthetic()
+ var/robot = ismachineperson(src)
for(var/datum/multilingual_say_piece/S in message_pieces)
if(S.speaking && S.speaking.flags & NO_STUTTER)
continue
@@ -172,6 +172,9 @@ proc/get_radio_key_from_channel(var/channel)
var/list/hsp = handle_speech_problems(message_pieces, verb)
verb = hsp["verb"]
+ // Do this so it gets logged for all types of communication
+ var/log_message = "[message_mode ? "([message_mode])" : ""] '[message]'"
+ create_log(SAY_LOG, log_message)
var/list/used_radios = list()
if(handle_message_mode(message_mode, message_pieces, verb, used_radios))
@@ -179,9 +182,7 @@ proc/get_radio_key_from_channel(var/channel)
// Log of what we've said, plain message, no spans or junk
// handle_message_mode should have logged this already if it handled it
- var/log_message = "[message_mode ? "([message_mode])" : ""] '[message]'"
say_log += log_message
- create_log(SAY_LOG, log_message) // TODO after #13047: Include the channel
log_say(log_message, src)
var/list/handle_v = handle_speech_sound()
@@ -268,12 +269,12 @@ proc/get_radio_key_from_channel(var/channel)
M.hear_say(message_pieces, verb, italics, src, speech_sound, sound_vol, sound_frequency)
if(M.client)
speech_bubble_recipients.Add(M.client)
- spawn(0)
- if(loc && !isturf(loc))
- var/atom/A = loc //Non-turf, let it handle the speech bubble
- A.speech_bubble("hR[speech_bubble_test]", A, speech_bubble_recipients)
- else //Turf, leave speech bubbles to the mob
- speech_bubble("h[speech_bubble_test]", src, speech_bubble_recipients)
+
+ if(loc && !isturf(loc))
+ var/atom/A = loc //Non-turf, let it handle the speech bubble
+ A.speech_bubble("[A.bubble_icon][speech_bubble_test]", A, speech_bubble_recipients)
+ else //Turf, leave speech bubbles to the mob
+ speech_bubble("[bubble_icon][speech_bubble_test]", src, speech_bubble_recipients)
for(var/obj/O in listening_obj)
spawn(0)
@@ -335,7 +336,8 @@ proc/get_radio_key_from_channel(var/channel)
var/datum/multilingual_say_piece/S = message_pieces // Yay BYOND's hilarious typecasting
S.speaking.broadcast(src, S.message)
return 1
-
+ // Log it here since it skips the default way say handles it
+ create_log(SAY_LOG, "(whisper) '[message]'")
whisper_say(message_pieces)
// for weird circumstances where you're inside an atom that is also you, like pai's
@@ -364,7 +366,6 @@ proc/get_radio_key_from_channel(var/channel)
say_log += "whisper: [message]"
log_whisper(message, src)
- create_log(SAY_LOG, "WHISPER: [message]")
var/message_range = 1
var/eavesdropping_range = 2
var/watching_range = 5
@@ -461,10 +462,7 @@ proc/get_radio_key_from_channel(var/channel)
if(M.client)
speech_bubble_recipients.Add(M.client)
- spawn(0)
- var/image/I = image('icons/mob/talk.dmi', src, "h[speech_bubble_test]", MOB_LAYER + 1)
- I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
- flick_overlay(I, speech_bubble_recipients, 30)
+ speech_bubble("[bubble_icon][speech_bubble_test]", src, speech_bubble_recipients)
if(watching.len)
var/rendered = "[name] [not_heard]."
@@ -473,7 +471,7 @@ proc/get_radio_key_from_channel(var/channel)
return 1
-/mob/living/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list())
- var/image/I = image('icons/mob/talk.dmi', bubble_loc, bubble_state, MOB_LAYER + 1)
+/mob/living/speech_bubble(bubble_state = "", bubble_loc = src, list/bubble_recipients = list())
+ var/image/I = image('icons/mob/talk.dmi', bubble_loc, bubble_state, FLY_LAYER)
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
- flick_overlay(I, bubble_recipients, 30)
+ INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, bubble_recipients, 30)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 85c4ceac427..737298e2815 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -63,6 +63,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
//MALFUNCTION
var/datum/module_picker/malf_picker
+ var/datum/action/innate/ai/choose_modules/modules_action
var/list/datum/AI_Module/current_modules = list()
var/can_dominate_mechs = 0
var/shunted = 0 //1 if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead
@@ -243,7 +244,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
/mob/living/silicon/ai/proc/show_borg_info()
stat(null, text("Connected cyborgs: [connected_robots.len]"))
- for(var/mob/living/silicon/robot/R in connected_robots)
+ for(var/thing in connected_robots)
+ var/mob/living/silicon/robot/R = thing
var/robot_status = "Nominal"
if(R.stat || !R.client)
robot_status = "OFFLINE"
@@ -251,8 +253,9 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
robot_status = "DEPOWERED"
// Name, Health, Battery, Module, Area, and Status! Everything an AI wants to know about its borgies!
var/area/A = get_area(R)
+ var/area_name = A ? sanitize(A.name) : "Unknown"
stat(null, text("[R.name] | S.Integrity: [R.health]% | Cell: [R.cell ? "[R.cell.charge] / [R.cell.maxcharge]" : "Empty"] | \
- Module: [R.designation] | Loc: [sanitize(A.name)] | Status: [robot_status]"))
+ Module: [R.designation] | Loc: [area_name] | Status: [robot_status]"))
/mob/living/silicon/ai/rename_character(oldname, newname)
if(!..(oldname, newname))
@@ -849,13 +852,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
to_chat(src, "Switched to [network] camera network.")
//End of code by Mord_Sith
-
-/mob/living/silicon/ai/proc/choose_modules()
- set category = "Malfunction"
- set name = "Choose Module"
-
- malf_picker.use(src)
-
/mob/living/silicon/ai/proc/ai_statuschange()
set category = "AI Commands"
set name = "AI Status"
@@ -1026,15 +1022,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
return
-/mob/living/silicon/ai/proc/corereturn()
- set category = "Malfunction"
- set name = "Return to Main Core"
-
- var/obj/machinery/power/apc/apc = loc
- if(!istype(apc))
- to_chat(src, "You are already in your Main Core.")
- return
- apc.malfvacate()
//Toggles the luminosity and applies it by re-entereing the camera.
/mob/living/silicon/ai/proc/toggle_camera_light()
@@ -1242,8 +1229,17 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
to_chat(src, "In the top right corner of the screen you will find the Malfunctions tab, where you can purchase various abilities, from upgraded surveillance to station ending doomsday devices.")
to_chat(src, "You are also capable of hacking APCs, which grants you more points to spend on your Malfunction powers. The drawback is that a hacked APC will give you away if spotted by the crew. Hacking an APC takes 60 seconds.")
view_core() //A BYOND bug requires you to be viewing your core before your verbs update
- verbs += /mob/living/silicon/ai/proc/choose_modules
malf_picker = new /datum/module_picker
+ modules_action = new(malf_picker)
+ modules_action.Grant(src)
+
+///Removes all malfunction-related /datum/action's from the target AI.
+/mob/living/silicon/ai/proc/remove_malf_abilities()
+ QDEL_NULL(modules_action)
+ for(var/datum/AI_Module/AM in current_modules)
+ for(var/datum/action/A in actions)
+ if(istype(A, initial(AM.power_type)))
+ qdel(A)
/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target)
if(!istype(target))
diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm
index 641b1a2af0f..717f9700316 100644
--- a/code/modules/mob/living/silicon/ai/death.dm
+++ b/code/modules/mob/living/silicon/ai/death.dm
@@ -34,7 +34,7 @@
spawn(10)
explosion(src.loc, 3, 6, 12, 15)
- for(var/obj/machinery/ai_status_display/O in world) //change status
+ for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
O.mode = 2
if(istype(loc, /obj/item/aicard))
diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm
index 4b124c364c2..03e56a5e26e 100644
--- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm
@@ -67,9 +67,6 @@
// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
/datum/camerachunk/proc/update()
-
- set background = BACKGROUND_ENABLED
-
var/list/newVisibleTurfs = list()
for(var/camera in cameras)
diff --git a/code/modules/mob/living/silicon/ai/latejoin.dm b/code/modules/mob/living/silicon/ai/latejoin.dm
index 75e8854b45c..e1be5450811 100644
--- a/code/modules/mob/living/silicon/ai/latejoin.dm
+++ b/code/modules/mob/living/silicon/ai/latejoin.dm
@@ -1,15 +1,5 @@
GLOBAL_LIST_EMPTY(empty_playable_ai_cores)
-/hook/roundstart/proc/spawn_empty_ai()
- for(var/obj/effect/landmark/start/S in GLOB.landmarks_list)
- if(S.name != "AI")
- continue
- if(locate(/mob/living) in S.loc)
- continue
- GLOB.empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(get_turf(S))
-
- return 1
-
/mob/living/silicon/ai/verb/wipe_core()
set name = "Wipe Core"
set category = "OOC"
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 8d1555182a2..61151e35c92 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -37,7 +37,8 @@
else
adjustOxyLoss(-1)
- handle_stunned()
+ if(stunned)
+ AdjustStunned(-1, updating = 1, force = 1)
var/area/my_area = get_area(src)
@@ -140,7 +141,6 @@
else
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
update_stat("updatehealth([reason])")
- diag_hud_set_status()
diag_hud_set_health()
diff --git a/code/modules/mob/living/silicon/ai/logout.dm b/code/modules/mob/living/silicon/ai/logout.dm
index a8060abd15c..d9dac308870 100644
--- a/code/modules/mob/living/silicon/ai/logout.dm
+++ b/code/modules/mob/living/silicon/ai/logout.dm
@@ -1,6 +1,6 @@
/mob/living/silicon/ai/Logout()
..()
- for(var/obj/machinery/ai_status_display/O in world) //change status
+ for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
O.mode = 0
src.view_core()
return
diff --git a/code/modules/mob/living/silicon/ai/update_status.dm b/code/modules/mob/living/silicon/ai/update_status.dm
index fd001956c67..8ee4a825631 100644
--- a/code/modules/mob/living/silicon/ai/update_status.dm
+++ b/code/modules/mob/living/silicon/ai/update_status.dm
@@ -9,7 +9,7 @@
else if(stat == UNCONSCIOUS)
WakeUp()
create_debug_log("woke up, trigger reason: [reason]")
- //diag_hud_set_status()
+ diag_hud_set_status()
/mob/living/silicon/ai/has_vision(information_only = FALSE)
return ..() && !lacks_power()
diff --git a/code/modules/mob/living/silicon/decoy/death.dm b/code/modules/mob/living/silicon/decoy/death.dm
index 9e58001f47b..74db72978e0 100644
--- a/code/modules/mob/living/silicon/decoy/death.dm
+++ b/code/modules/mob/living/silicon/decoy/death.dm
@@ -4,7 +4,7 @@
if(!.)
return FALSE
icon_state = "ai-crash"
- for(var/obj/machinery/ai_status_display/O in world) //change status
+ for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
if(atoms_share_level(O, src))
O.mode = 2
gib()
diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm
index d91b724370b..321362217a1 100644
--- a/code/modules/mob/living/silicon/pai/life.dm
+++ b/code/modules/mob/living/silicon/pai/life.dm
@@ -1,22 +1,18 @@
/mob/living/silicon/pai/Life(seconds, times_fired)
. = ..()
- if(.)
- //if(secHUD == 1)
- // process_sec_hud(src, 1)
- ////if(medHUD == 1)
- // process_med_hud(src, 1)
- if(silence_time)
- if(world.timeofday >= silence_time)
- silence_time = null
- to_chat(src, "Communication circuit reinitialized. Speech and messaging functionality restored.")
+ if(QDELETED(src) || stat == DEAD)
+ return
+ if(silence_time)
+ if(world.timeofday >= silence_time)
+ silence_time = null
+ to_chat(src, "Communication circuit reinitialized. Speech and messaging functionality restored.")
- if(cable)
- if(get_dist(src, cable) > 1)
- var/turf/T = get_turf_or_move(loc)
- for(var/mob/M in viewers(T))
- M.show_message("The data cable rapidly retracts back into its spool.", 3, "You hear a click and the sound of wire spooling rapidly.", 2)
- qdel(src.cable)
- cable = null
+ if(cable)
+ if(get_dist(src, cable) > 1)
+ var/turf/T = get_turf_or_move(loc)
+ for(var/mob/M in viewers(T))
+ M.show_message("The data cable rapidly retracts back into its spool.", 3, "You hear a click and the sound of wire spooling rapidly.", 2)
+ QDEL_NULL(cable)
/mob/living/silicon/pai/updatehealth(reason = "none given")
if(status_flags & GODMODE)
diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm
index f52da9942e4..920dff8a8c2 100644
--- a/code/modules/mob/living/silicon/pai/recruit.dm
+++ b/code/modules/mob/living/silicon/pai/recruit.dm
@@ -1,6 +1,6 @@
// Recruiting observers to play as pAIs
-GLOBAL_DATUM(paiController, /datum/paiController) // Global handler for pAI candidates
+GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler for pAI candidates
/datum/paiCandidate
var/name
@@ -10,12 +10,6 @@ GLOBAL_DATUM(paiController, /datum/paiController) // Global handler for pAI cand
var/comments
var/ready = 0
-
-/hook/startup/proc/paiControllerSetup()
- GLOB.paiController = new /datum/paiController()
- return 1
-
-
/datum/paiController
var/list/pai_candidates = list()
var/list/asked = list()
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index 3b51048452e..574dcda3230 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -13,19 +13,6 @@ GLOBAL_LIST_INIT(pai_emotions, list(
GLOBAL_LIST_EMPTY(pai_software_by_key)
GLOBAL_LIST_EMPTY(default_pai_software)
-/hook/startup/proc/populate_pai_software_list()
- var/r = 1 // I would use ., but it'd sacrifice runtime detection
- for(var/type in subtypesof(/datum/pai_software))
- var/datum/pai_software/P = new type()
- if(GLOB.pai_software_by_key[P.id])
- var/datum/pai_software/O = GLOB.pai_software_by_key[P.id]
- to_chat(world, "pAI software module [P.name] has the same key as [O.name]!")
- r = 0
- continue
- GLOB.pai_software_by_key[P.id] = P
- if(P.default)
- GLOB.default_pai_software[P.id] = P
- return r
/mob/living/silicon/pai/New()
..()
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index 26b5683d1a3..2a1662b064d 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -227,7 +227,7 @@
throw_speed = 5
throw_range = 10
origin_tech = "magnets=1;biotech=1"
- var/mode = 1;
+ var/mode = 1
/obj/item/robotanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
if(( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
@@ -253,7 +253,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
to_chat(user, "You can't analyze non-robotic things!")
return
-
+
switch(scan_type)
if("robot")
var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss()
@@ -269,7 +269,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
to_chat(user, "Localized Damage:")
if(!LAZYLEN(damaged) && !LAZYLEN(missing))
to_chat(user, "\t Components are OK.")
- else
+ else
if(LAZYLEN(damaged))
for(var/datum/robot_component/org in damaged)
user.show_message(text("\t []: [][] - [] - [] - []", \
@@ -282,7 +282,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
if(LAZYLEN(missing))
for(var/datum/robot_component/org in missing)
user.show_message("\t [capitalize(org.name)]: MISSING")
-
+
if(H.emagged && prob(5))
to_chat(user, "\t ERROR: INTERNAL SYSTEMS COMPROMISED")
@@ -313,7 +313,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
if(!organ_found)
to_chat(user, "No prosthetics located.")
- if(H.isSynthetic())
+ if(ismachineperson(H))
to_chat(user, "Internal Fluid Level:[H.blood_volume]/[H.max_blood]")
if(H.bleed_rate)
to_chat(user, "Warning:External component leak detected!")
diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm
index 224c706f324..72d9b210712 100644
--- a/code/modules/mob/living/silicon/robot/death.dm
+++ b/code/modules/mob/living/silicon/robot/death.dm
@@ -18,7 +18,7 @@
flick("gibbed-r", animation)
robogibs(loc)
- GLOB.living_mob_list -= src
+ GLOB.alive_mob_list -= src
GLOB.dead_mob_list -= src
QDEL_IN(animation, 15)
QDEL_IN(src, 15)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index dc32deaf5a7..91970d030a6 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -6,6 +6,7 @@
icon_state = "repairbot"
maxHealth = 35
health = 35
+ bubble_icon = "machine"
universal_speak = 0
universal_understand = 1
gender = NEUTER
@@ -13,11 +14,14 @@
braintype = "Robot"
lawupdate = 0
density = 0
+ has_camera = FALSE
req_one_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS)
ventcrawler = 2
magpulse = 1
mob_size = MOB_SIZE_SMALL
+ modules_break = FALSE
+
// We need to keep track of a few module items so we don't need to do list operations
// every time we need them. These get set in New() after the module is chosen.
var/obj/item/stack/sheet/metal/cyborg/stack_metal = null
@@ -79,7 +83,7 @@
scanner.Grant(src)
update_icons()
-/mob/living/silicon/robot/drone/init()
+/mob/living/silicon/robot/drone/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
laws = new /datum/ai_laws/drone()
connected_ai = null
@@ -142,7 +146,7 @@
user.visible_message("\the [user] swipes [user.p_their()] ID card through [src], attempting to reboot it.", "You swipe your ID card through [src], attempting to reboot it.")
last_reboot = world.time / 10
var/drones = 0
- for(var/mob/living/silicon/robot/drone/D in world)
+ for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
if(D.key && D.client)
drones++
if(drones < config.max_maint_drones)
@@ -350,3 +354,20 @@
/mob/living/simple_animal/drone/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
if(affect_silicon)
return ..()
+
+/mob/living/silicon/robot/drone/decompile_act(obj/item/matter_decompiler/C, mob/user)
+ if(!client && istype(user, /mob/living/silicon/robot/drone))
+ to_chat(user, "You begin decompiling the other drone.")
+ if(!do_after(user, 5 SECONDS, target = loc))
+ to_chat(user, "You need to remain still while decompiling such a large object.")
+ return
+ if(QDELETED(src) || QDELETED(user))
+ return ..()
+ to_chat(user, "You carefully and thoroughly decompile your downed fellow, storing as much of its resources as you can within yourself.")
+ new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
+ C.stored_comms["metal"] += 15
+ C.stored_comms["glass"] += 15
+ C.stored_comms["wood"] += 5
+ qdel(src)
+ return TRUE
+ return ..()
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm
index 80d9f4d1ba3..d961d8e1c62 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm
@@ -34,7 +34,7 @@
var/dat
dat += "Maintenance Units "
- for(var/mob/living/silicon/robot/drone/D in world)
+ for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
dat += " [D.real_name] ([D.stat == 2 ? "INACTIVE" : "ACTIVE"])"
dat += " Cell charge: [D.cell.charge]/[D.cell.maxcharge]."
dat += " Currently located in: [get_area(D)]."
@@ -74,7 +74,7 @@
else if(href_list["ping"])
to_chat(usr, "You issue a maintenance request for all active drones, highlighting [drone_call_area].")
- for(var/mob/living/silicon/robot/drone/D in world)
+ for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
if(D.client && D.stat == 0)
to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].")
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
index 7958f983805..a0582c135e4 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
@@ -64,7 +64,7 @@
..()
can_hold = typecacheof(can_hold)
-/obj/item/gripper/verb/drop_item()
+/obj/item/gripper/verb/drop_item_gripped()
set name = "Drop Gripped Item"
set desc = "Release an item from your magnetic gripper."
set category = "Drone"
@@ -151,15 +151,13 @@
var/list/stored_comms = list(
"metal" = 0,
"glass" = 0,
- "wood" = 0,
- "plastic" = 0
+ "wood" = 0
)
/obj/item/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
return
-/obj/item/matter_decompiler/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
-
+/obj/item/matter_decompiler/afterattack(atom/target, mob/living/user, proximity, params)
if(!proximity) return //Not adjacent.
//We only want to deal with using this on turfs. Specific items aren't important.
@@ -168,101 +166,11 @@
return
//Used to give the right message.
- var/grabbed_something = 0
+ var/grabbed_something = FALSE
- for(var/mob/M in T)
- if(istype(M,/mob/living/simple_animal/lizard) || istype(M,/mob/living/simple_animal/mouse))
- src.loc.visible_message("[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.","It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.")
- new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
- qdel(M)
- stored_comms["wood"]++
- stored_comms["wood"]++
- stored_comms["plastic"]++
- stored_comms["plastic"]++
- return
-
- else if(istype(M,/mob/living/silicon/robot/drone) && !M.client)
-
- var/mob/living/silicon/robot/drone/D = src.loc
-
- if(!istype(D))
- return
-
- to_chat(D, "You begin decompiling the other drone.")
-
- if(!do_after(D, 50, target = target))
- to_chat(D, "You need to remain still while decompiling such a large object.")
- return
-
- if(!M || !D) return
-
- to_chat(D, "You carefully and thoroughly decompile your downed fellow, storing as much of its resources as you can within yourself.")
-
- qdel(M)
- new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
-
- stored_comms["metal"] += 15
- stored_comms["glass"] += 15
- stored_comms["wood"] += 5
- stored_comms["plastic"] += 5
-
- return
- else
- continue
-
- for(var/obj/W in T)
- //Different classes of items give different commodities.
- if(istype(W,/obj/item/cigbutt))
- stored_comms["plastic"]++
- else if(istype(W,/obj/structure/spider/spiderling))
- stored_comms["wood"]++
- stored_comms["wood"]++
- stored_comms["plastic"]++
- stored_comms["plastic"]++
- else if(istype(W,/obj/item/light))
- var/obj/item/light/L = W
- if(L.status >= 2) //In before someone changes the inexplicably local defines. ~ Z
- stored_comms["metal"]++
- stored_comms["glass"]++
- else
- continue
- else if(istype(W,/obj/effect/decal/remains/robot))
- stored_comms["metal"]++
- stored_comms["metal"]++
- stored_comms["plastic"]++
- stored_comms["plastic"]++
- stored_comms["glass"]++
- else if(istype(W,/obj/item/trash))
- stored_comms["metal"]++
- stored_comms["plastic"]++
- stored_comms["plastic"]++
- else if(istype(W,/obj/effect/decal/cleanable/blood/gibs/robot))
- stored_comms["metal"]++
- stored_comms["metal"]++
- stored_comms["glass"]++
- stored_comms["glass"]++
- else if(istype(W,/obj/item/ammo_casing))
- stored_comms["metal"]++
- else if(istype(W,/obj/item/shard))
- stored_comms["glass"]++
- stored_comms["glass"]++
- stored_comms["glass"]++
- else if(istype(W,/obj/item/reagent_containers/food/snacks/grown))
- stored_comms["wood"]++
- stored_comms["wood"]++
- stored_comms["wood"]++
- stored_comms["wood"]++
- else if(istype(W,/obj/item/broken_bottle))
- stored_comms["glass"]++
- stored_comms["glass"]++
- stored_comms["glass"]++
- else if(istype(W,/obj/item/light/tube) || istype(W,/obj/item/light/bulb))
- stored_comms["glass"]++
- else
- continue
-
- qdel(W)
- grabbed_something = 1
+ for(var/atom/movable/A in T)
+ if(A.decompile_act(src, user)) // Each decompileable mob or obj needs to have this defined
+ grabbed_something = TRUE
if(grabbed_something)
to_chat(user, "You deploy your decompiler and clear out the contents of \the [T].")
@@ -353,11 +261,5 @@
stack_wood = new /obj/item/stack/sheet/wood(src.module)
stack_wood.amount = 1
stack = stack_wood
- if("plastic")
- if(!stack_plastic)
- stack_plastic = new /obj/item/stack/sheet/plastic(src.module)
- stack_plastic.amount = 1
- stack = stack_plastic
-
stack.amount++
decompiler.stored_comms[type]--
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
index 50463b17bec..023cced9cdb 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
@@ -52,7 +52,7 @@
/obj/machinery/drone_fabricator/proc/count_drones()
var/drones = 0
- for(var/mob/living/silicon/robot/drone/D in world)
+ for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
if(D.key && D.client)
drones++
return drones
@@ -142,7 +142,7 @@
if(alert("Are you sure you want to respawn as a drone?", "Are you sure?", "Yes", "No") != "Yes")
return
- for(var/obj/machinery/drone_fabricator/DF in world)
+ for(var/obj/machinery/drone_fabricator/DF in GLOB.machines)
if(DF.stat & NOPOWER || !DF.produce_drones)
continue
diff --git a/code/modules/mob/living/silicon/robot/drone/update_status.dm b/code/modules/mob/living/silicon/robot/drone/update_status.dm
index 80eac952966..d64824b1876 100644
--- a/code/modules/mob/living/silicon/robot/drone/update_status.dm
+++ b/code/modules/mob/living/silicon/robot/drone/update_status.dm
@@ -4,7 +4,7 @@
/mob/living/silicon/robot/drone/update_stat(reason = "none given")
if(status_flags & GODMODE)
return
- if(health <= -35 && stat != DEAD)
+ if(health <= -maxHealth && stat != DEAD)
gib()
create_debug_log("died of damage, trigger reason: [reason]")
return
diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm
index a68da651ee9..f5b7048c3a8 100644
--- a/code/modules/mob/living/silicon/robot/inventory.dm
+++ b/code/modules/mob/living/silicon/robot/inventory.dm
@@ -78,6 +78,7 @@
set_actions(O)
else
to_chat(src, "You need to disable a module first!")
+ check_module_damage(FALSE)
update_icons()
/mob/living/silicon/robot/proc/set_actions(obj/item/I)
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index d40e801ba5f..07080e694bf 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -1,23 +1,20 @@
/mob/living/silicon/robot/Life(seconds, times_fired)
set invisibility = 0
- set background = BACKGROUND_ENABLED
-
- if(src.notransform)
+ if(notransform)
return
- //Status updates, death etc.
- clamp_values()
+ . = ..()
- if(..())
+ handle_equipment()
+
+ // if Alive
+ if(.)
+ handle_robot_hud_updates()
handle_robot_cell()
process_locks()
+ update_items()
process_queued_alarms()
-/mob/living/silicon/robot/proc/clamp_values()
- SetStunned(min(stunned, 30))
- SetParalysis(min(paralysis, 30))
- SetWeakened(min(weakened, 20))
- SetSleeping(0)
/mob/living/silicon/robot/proc/handle_robot_cell()
if(stat != DEAD)
@@ -39,7 +36,7 @@
if(is_component_functioning("power cell") && cell.charge)
if(cell.charge <= 100)
uneq_all()
- var/amt = Clamp((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell.
+ var/amt = clamp((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell.
cell.use(amt) //Usage table: 1/tick if off/lowest setting, 4 = 4/tick, 6 = 8/tick, 8 = 12/tick, 10 = 16/tick
else
uneq_all()
@@ -47,36 +44,13 @@
update_headlamp()
diag_hud_set_borgcell()
-/mob/living/silicon/robot/handle_regular_status_updates()
-
- . = ..()
-
+/mob/living/silicon/robot/proc/handle_equipment()
if(camera && !scrambledcodes)
if(stat == DEAD || wires.IsCameraCut())
camera.status = 0
else
camera.status = 1
- if(sleeping)
- AdjustSleeping(-1)
-
- if(.) //alive
- if(!istype(src, /mob/living/silicon/robot/drone))
- if(health < 50) //Gradual break down of modules as more damage is sustained
- if(uneq_module(module_state_3))
- to_chat(src, "SYSTEM ERROR: Module 3 OFFLINE.")
-
- if(health < 0)
- if(uneq_module(module_state_2))
- to_chat(src, "SYSTEM ERROR: Module 2 OFFLINE.")
-
- if(health < -50)
- if(uneq_module(module_state_1))
- to_chat(src, "CRITICAL ERROR: All modules OFFLINE.")
-
- diag_hud_set_health()
- diag_hud_set_status()
-
//update the state of modules and components here
if(stat != CONSCIOUS)
uneq_all()
@@ -86,18 +60,21 @@
else
radio.on = 1
- return 1
-
-/mob/living/silicon/robot/handle_hud_icons()
- update_items()
- update_cell()
+/mob/living/silicon/robot/proc/SetEmagged(new_state)
+ emagged = new_state
+ update_icons()
if(emagged)
throw_alert("hacked", /obj/screen/alert/hacked)
else
clear_alert("hacked")
- ..()
-/mob/living/silicon/robot/handle_hud_icons_health()
+/mob/living/silicon/robot/proc/handle_robot_hud_updates()
+ if(!client)
+ return
+
+ update_cell_hud_icon()
+
+/mob/living/silicon/robot/update_health_hud()
if(healths)
if(stat != DEAD)
if(health >= maxHealth)
@@ -115,19 +92,7 @@
else
healths.icon_state = "health7"
- switch(bodytemperature) //310.055 optimal body temp
- if(335 to INFINITY)
- throw_alert("temp", /obj/screen/alert/hot/robot, 2)
- if(320 to 335)
- throw_alert("temp", /obj/screen/alert/hot/robot, 1)
- if(300 to 320)
- clear_alert("temp")
- if(260 to 300)
- throw_alert("temp", /obj/screen/alert/cold/robot, 1)
- else
- throw_alert("temp", /obj/screen/alert/cold/robot, 2)
-
-/mob/living/silicon/robot/proc/update_cell()
+/mob/living/silicon/robot/proc/update_cell_hud_icon()
if(cell)
var/cellcharge = cell.charge/cell.maxcharge
switch(cellcharge)
@@ -146,7 +111,7 @@
-/mob/living/silicon/robot/proc/update_items()
+/mob/living/silicon/robot/proc/update_items() // What in the Sam hell is this?
if(client)
for(var/obj/I in get_all_slots())
client.screen |= I
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index cf3067b934f..faa51a58ec0 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -9,6 +9,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
icon_state = "robot"
maxHealth = 100
health = 100
+ bubble_icon = "robot"
universal_understand = 1
deathgasp_on_death = TRUE
@@ -16,8 +17,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/custom_name = ""
var/custom_sprite = 0 //Due to all the sprites involved, a var for our custom borgs may be best
-//Hud stuff
-
+ //Hud stuff
var/obj/screen/inv1 = null
var/obj/screen/inv2 = null
var/obj/screen/inv3 = null
@@ -27,7 +27,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
var/obj/screen/robot_modules_background
-//3 Modules can be activated at any one time.
+ //3 Modules can be activated at any one time.
var/obj/item/robot_module/module = null
var/module_active = null
var/module_state_1 = null
@@ -57,6 +57,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/is_emaggable = TRUE
var/eye_protection = 0
var/ear_protection = 0
+ var/damage_protection = 0
+ var/emp_protection = FALSE
+ var/xeno_disarm_chance = 85
var/list/force_modules = list()
var/allow_rename = TRUE
@@ -82,11 +85,12 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/lockcharge //Used when locking down a borg to preserve cell charge
var/speed = 0 //Cause sec borgs gotta go fast //No they dont!
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
+ var/has_camera = TRUE
var/pdahide = 0 //Used to hide the borg from the messenger list
var/tracking_entities = 0 //The number of known entities currently accessing the internal camera
var/braintype = "Cyborg"
var/base_icon = ""
- var/crisis = 0
+ var/modules_break = TRUE
var/lamp_max = 10 //Maximum brightness of a borg lamp. Set as a var for easy adjusting.
var/lamp_intensity = 0 //Luminosity of the headlamp. 0 is off. Higher settings than the minimum require power.
@@ -96,6 +100,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD)
+ var/default_cell_type = /obj/item/stock_parts/cell/high
var/magpulse = 0
var/ionpulse = 0 // Jetpack-like effect.
var/ionpulse_on = 0 // Jetpack-like effect.
@@ -107,7 +112,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
/mob/living/silicon/robot/get_cell()
return cell
-/mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0, var/alien = 0)
+/mob/living/silicon/robot/New(loc, syndie = FALSE, unfinished = FALSE, alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
@@ -129,9 +134,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
radio = new /obj/item/radio/borg(src)
common_radio = radio
- init()
+ init(ai_to_sync_to = ai_to_sync_to)
- if(!scrambledcodes && !camera)
+ if(has_camera && !camera)
camera = new /obj/machinery/camera(src)
camera.c_tag = real_name
camera.network = list("SS13","Robots")
@@ -143,7 +148,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
mmi.icon_state = "boris"
if(!cell) // Make sure a new cell gets created *before* executing initialize_components(). The cell component needs an existing cell for it to get set up properly
- cell = new /obj/item/stock_parts/cell/high(src)
+ cell = new default_cell_type(src)
initialize_components()
//if(!unfinished)
@@ -167,14 +172,16 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
scanner = new(src)
scanner.Grant(src)
-/mob/living/silicon/robot/proc/init(var/alien=0)
+/mob/living/silicon/robot/proc/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
make_laws()
additional_law_channels["Binary"] = ":b "
- var/new_ai = select_active_ai_with_fewest_borgs()
- if(new_ai)
+ var/found_ai = ai_to_sync_to
+ if(!found_ai)
+ found_ai = select_active_ai_with_fewest_borgs()
+ if(found_ai)
lawupdate = 1
- connect_to_ai(new_ai)
+ connect_to_ai(found_ai)
else
lawupdate = 0
@@ -234,7 +241,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(custom_name)
return 0
if(!allow_rename)
- to_chat(src, "Rename functionality is not enabled on this unit.");
+ to_chat(src, "Rename functionality is not enabled on this unit.")
return 0
rename_self(braintype, 1)
@@ -287,12 +294,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
/mob/living/silicon/robot/proc/pick_module()
if(module)
return
- var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
+ var/list/modules = list("Generalist", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
if(islist(force_modules) && force_modules.len)
modules = force_modules.Copy()
- if(GLOB.security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis)
- to_chat(src, "Crisis mode active. The combat module is now available.")
- modules += "Combat"
if(mmi != null && mmi.alien)
modules = list("Hunter")
modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules
@@ -305,9 +309,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
return
switch(modtype)
- if("Standard")
+ if("Generalist")
module = new /obj/item/robot_module/standard(src)
- module.channels = list("Service" = 1)
+ module.channels = list("Engineering" = 1, "Medical" = 1, "Security" = 1, "Service" = 1)
module_sprites["Basic"] = "robot_old"
module_sprites["Android"] = "droid"
module_sprites["Default"] = "Standard"
@@ -336,6 +340,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
module_sprites["Standard"] = "Standard-Mine"
module_sprites["Noble-DIG"] = "Noble-DIG"
module_sprites["Cricket"] = "Cricket-MINE"
+ module_sprites["Lavaland"] = "lavaland"
if("Medical")
module = new /obj/item/robot_module/medical(src)
@@ -352,6 +357,17 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
status_flags &= ~CANPUSH
if("Security")
+ if(!weapons_unlock)
+ var/count_secborgs = 0
+ for(var/mob/living/silicon/robot/R in GLOB.alive_mob_list)
+ if(R && R.stat != DEAD && R.module && istype(R.module, /obj/item/robot_module/security))
+ count_secborgs++
+ var/max_secborgs = 2
+ if(GLOB.security_level == SEC_LEVEL_GREEN)
+ max_secborgs = 1
+ if(count_secborgs >= max_secborgs)
+ to_chat(src, "There are too many Security cyborgs active. Please choose another module.")
+ return
module = new /obj/item/robot_module/security(src)
module.channels = list("Security" = 1)
module_sprites["Basic"] = "secborg"
@@ -386,10 +402,16 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
module_sprites["Noble-CLN"] = "Noble-CLN"
module_sprites["Cricket"] = "Cricket-JANI"
- if("Combat")
- module = new /obj/item/robot_module/combat(src)
+ if("Destroyer") // Rolling Borg
+ module = new /obj/item/robot_module/destroyer(src)
module.channels = list("Security" = 1)
icon_state = "droidcombat"
+ status_flags &= ~CANPUSH
+
+ if("Combat") // Gamma ERT
+ module = new /obj/item/robot_module/combat(src)
+ icon_state = "ertgamma"
+ status_flags &= ~CANPUSH
if("Hunter")
module = new /obj/item/robot_module/alien/hunter(src)
@@ -441,6 +463,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
ionpulse = FALSE
magpulse = FALSE
add_language("Robot Talk", 1)
+ if("lava" in weather_immunities) // Remove the lava-immunity effect given by a printable upgrade
+ weather_immunities -= "lava"
status_flags |= CANPUSH
@@ -840,7 +864,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
return
else
sleep(6)
- emagged = 1
+ SetEmagged(TRUE)
SetLockdown(1) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
if(src.hud_used)
src.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open.
@@ -915,7 +939,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
return 0
/mob/living/silicon/robot/update_icons()
-
overlays.Cut()
if(stat != DEAD && !(paralysis || stunned || IsWeakened() || low_power_mode)) //Not dead, not stunned.
if(custom_panel in custom_eye_names)
@@ -924,36 +947,24 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
overlays += "eyes-[icon_state]"
else
overlays -= "eyes"
-
if(opened)
var/panelprefix = "ov"
if(custom_sprite) //Custom borgs also have custom panels, heh
panelprefix = "[ckey]"
-
if(custom_panel in custom_panel_names) //For default borgs with different panels
panelprefix = custom_panel
-
if(wiresexposed)
overlays += "[panelprefix]-openpanel +w"
else if(cell)
overlays += "[panelprefix]-openpanel +c"
else
overlays += "[panelprefix]-openpanel -c"
-
- var/combat = list("Combat")
- if(modtype in combat)
- if(base_icon == "")
- base_icon = icon_state
- if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
- icon_state = "[base_icon]-roll"
- else
- icon_state = base_icon
- if(module)
- for(var/obj/item/borg/combat/shield/S in module.modules)
- if(activated(S))
- overlays += "[base_icon]-shield"
+ borg_icons()
update_fire()
+/mob/living/silicon/robot/proc/borg_icons() // Exists so that robot/destroyer can override it
+ return
+
/mob/living/silicon/robot/proc/installed_modules()
if(weapon_lock)
to_chat(src, "Weapon lock active, unable to use modules! Count:[weaponlock_time]")
@@ -1139,7 +1150,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(module)
if(module.type == /obj/item/robot_module/janitor)
var/turf/tile = loc
- if(isturf(tile))
+ if(stat != DEAD && isturf(tile))
var/floor_only = TRUE
for(var/A in tile)
if(istype(A, /obj/effect))
@@ -1157,16 +1168,16 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(cleaned_human.lying)
if(cleaned_human.head)
cleaned_human.head.clean_blood()
- cleaned_human.update_inv_head(0,0)
+ cleaned_human.update_inv_head()
if(cleaned_human.wear_suit)
cleaned_human.wear_suit.clean_blood()
- cleaned_human.update_inv_wear_suit(0,0)
+ cleaned_human.update_inv_wear_suit()
else if(cleaned_human.w_uniform)
cleaned_human.w_uniform.clean_blood()
- cleaned_human.update_inv_w_uniform(0,0)
+ cleaned_human.update_inv_w_uniform()
if(cleaned_human.shoes)
cleaned_human.shoes.clean_blood()
- cleaned_human.update_inv_shoes(0,0)
+ cleaned_human.update_inv_shoes()
cleaned_human.clean_blood()
to_chat(cleaned_human, "[src] cleans your face!")
if(floor_only)
@@ -1308,56 +1319,52 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
..()
update_module_icon()
+/mob/living/silicon/robot/emp_act(severity)
+ if(emp_protection)
+ return
+ ..()
+ switch(severity)
+ if(1)
+ disable_component("comms", 160)
+ if(2)
+ disable_component("comms", 60)
+
/mob/living/silicon/robot/deathsquad
base_icon = "nano_bloodhound"
icon_state = "nano_bloodhound"
designation = "SpecOps"
lawupdate = 0
scrambledcodes = 1
+ has_camera = FALSE
req_one_access = list(ACCESS_CENT_SPECOPS)
ionpulse = 1
magpulse = 1
pdahide = 1
eye_protection = 2 // Immunity to flashes and the visual part of flashbangs
ear_protection = 1 // Immunity to the audio part of flashbangs
+ damage_protection = 10 // Reduce all incoming damage by this number
+ xeno_disarm_chance = 20
allow_rename = FALSE
modtype = "Commando"
faction = list("nanotrasen")
is_emaggable = FALSE
+ default_cell_type = /obj/item/stock_parts/cell/bluespace
-/mob/living/silicon/robot/deathsquad/New(loc)
- ..()
- cell = new /obj/item/stock_parts/cell/hyper(src)
-
-/mob/living/silicon/robot/deathsquad/init()
+/mob/living/silicon/robot/deathsquad/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
laws = new /datum/ai_laws/deathsquad
module = new /obj/item/robot_module/deathsquad(src)
-
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
radio = new /obj/item/radio/borg/deathsquad(src)
radio.recalculateChannels()
-
playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
-/mob/living/silicon/robot/combat
- base_icon = "droidcombat"
- icon_state = "droidcombat"
- modtype = "Combat"
- designation = "Combat"
+/mob/living/silicon/robot/deathsquad/bullet_act(var/obj/item/projectile/P)
+ if(istype(P) && P.is_reflectable && P.starting)
+ visible_message("The [P.name] gets reflected by [src]!", "The [P.name] gets reflected by [src]!")
+ P.reflect_back(src)
+ return -1
+ return ..(P)
-/mob/living/silicon/robot/combat/init()
- ..()
- module = new /obj/item/robot_module/combat(src)
- module.channels = list("Security" = 1)
- //languages
- module.add_languages(src)
- //subsystems
- module.add_subsystems_and_actions(src)
-
- status_flags &= ~CANPUSH
-
- radio.config(module.channels)
- notify_ai(2)
/mob/living/silicon/robot/ert
designation = "ERT"
@@ -1365,24 +1372,24 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
scrambledcodes = 1
req_one_access = list(ACCESS_CENT_SPECOPS)
ionpulse = 1
-
force_modules = list("Engineering", "Medical", "Security")
static_radio_channels = 1
allow_rename = FALSE
weapons_unlock = TRUE
+ default_cell_type = /obj/item/stock_parts/cell/super
+ var/eprefix = "Amber"
-/mob/living/silicon/robot/ert/init()
+/mob/living/silicon/robot/ert/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
laws = new /datum/ai_laws/ert_override
radio = new /obj/item/radio/borg/ert(src)
radio.recalculateChannels()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
-/mob/living/silicon/robot/ert/New(loc, cyborg_unlock)
+/mob/living/silicon/robot/ert/New(loc)
..(loc)
- cell = new /obj/item/stock_parts/cell/hyper(src)
var/rnum = rand(1,1000)
- var/borgname = "ERT [rnum]"
+ var/borgname = "[eprefix] ERT [rnum]"
name = borgname
custom_name = borgname
real_name = name
@@ -1391,22 +1398,64 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
mind.original = src
mind.assigned_role = SPECIAL_ROLE_ERT
mind.special_role = SPECIAL_ROLE_ERT
- if(cyborg_unlock)
- crisis = 1
if(!(mind in SSticker.minds))
SSticker.minds += mind
SSticker.mode.ert += mind
-/mob/living/silicon/robot/ert/gamma
- crisis = 1
-/mob/living/silicon/robot/emp_act(severity)
+/mob/living/silicon/robot/ert/red
+ eprefix = "Red"
+ default_cell_type = /obj/item/stock_parts/cell/hyper
+
+/mob/living/silicon/robot/ert/gamma
+ default_cell_type = /obj/item/stock_parts/cell/bluespace
+ force_modules = list("Combat", "Engineering", "Medical")
+ damage_protection = 5 // Reduce all incoming damage by this number
+ eprefix = "Gamma"
+ magpulse = 1
+ xeno_disarm_chance = 40
+
+
+/mob/living/silicon/robot/destroyer
+ // admin-only borg, the seraph / special ops officer of borgs
+ base_icon = "droidcombat"
+ icon_state = "droidcombat"
+ modtype = "Destroyer"
+ designation = "Destroyer"
+ lawupdate = 0
+ scrambledcodes = 1
+ has_camera = FALSE
+ req_one_access = list(ACCESS_CENT_SPECOPS)
+ ionpulse = 1
+ magpulse = 1
+ pdahide = 1
+ eye_protection = 2 // Immunity to flashes and the visual part of flashbangs
+ ear_protection = 1 // Immunity to the audio part of flashbangs
+ emp_protection = TRUE // Immunity to EMP, due to heavy shielding
+ damage_protection = 20 // Reduce all incoming damage by this number. Very high in the case of /destroyer borgs, since it is an admin-only borg.
+ xeno_disarm_chance = 10
+ default_cell_type = /obj/item/stock_parts/cell/bluespace
+
+/mob/living/silicon/robot/destroyer/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
..()
- switch(severity)
- if(1)
- disable_component("comms", 160)
- if(2)
- disable_component("comms", 60)
+ module = new /obj/item/robot_module/destroyer(src)
+ module.add_languages(src)
+ module.add_subsystems_and_actions(src)
+ status_flags &= ~CANPUSH
+ if(radio)
+ qdel(radio)
+ radio = new /obj/item/radio/borg/ert/specops(src)
+ radio.recalculateChannels()
+
+/mob/living/silicon/robot/destroyer/borg_icons()
+ if(base_icon == "")
+ base_icon = icon_state
+ if(module_active && istype(module_active,/obj/item/borg/destroyer/mobility))
+ icon_state = "[base_icon]-roll"
+ else
+ icon_state = base_icon
+ overlays += "[base_icon]-shield"
+
/mob/living/silicon/robot/extinguish_light()
update_headlamp(1, 150)
@@ -1481,3 +1530,26 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
else
uneq_active() // else unequip the module and put it back into the robot's inventory.
return
+
+/mob/living/silicon/robot/proc/check_module_damage(makes_sound = TRUE)
+ if(modules_break)
+ if(health < 50) //Gradual break down of modules as more damage is sustained
+ if(uneq_module(module_state_3))
+ if(makes_sound)
+ audible_message("[src] sounds an alarm! \"SYSTEM ERROR: Module 3 OFFLINE.\"")
+ playsound(loc, 'sound/machines/warning-buzzer.ogg', 50, TRUE)
+ to_chat(src, "SYSTEM ERROR: Module 3 OFFLINE.")
+
+ if(health < 0)
+ if(uneq_module(module_state_2))
+ if(makes_sound)
+ audible_message("[src] sounds an alarm! \"SYSTEM ERROR: Module 2 OFFLINE.\"")
+ playsound(loc, 'sound/machines/warning-buzzer.ogg', 60, TRUE)
+ to_chat(src, "SYSTEM ERROR: Module 2 OFFLINE.")
+
+ if(health < -50)
+ if(uneq_module(module_state_1))
+ if(makes_sound)
+ audible_message("[src] sounds an alarm! \"CRITICAL ERROR: All modules OFFLINE.\"")
+ playsound(loc, 'sound/machines/warning-buzzer.ogg', 75, TRUE)
+ to_chat(src, "CRITICAL ERROR: All modules OFFLINE.")
diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm
index c73d566b729..b7b81ed40b7 100644
--- a/code/modules/mob/living/silicon/robot/robot_damage.dm
+++ b/code/modules/mob/living/silicon/robot/robot_damage.dm
@@ -1,12 +1,6 @@
/mob/living/silicon/robot/updatehealth(reason = "none given")
- if(status_flags & GODMODE)
- health = maxHealth
- stat = CONSCIOUS
- return
- health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss())
- update_stat("updatehealth([reason])")
- handle_hud_icons_health()
- diag_hud_set_health()
+ ..(reason)
+ check_module_damage()
/mob/living/silicon/robot/getBruteLoss(repairable_only = FALSE)
var/amount = 0
@@ -72,7 +66,7 @@
/mob/living/silicon/robot/heal_organ_damage(brute, burn, updating_health = TRUE)
var/list/datum/robot_component/parts = get_damaged_components(brute, burn)
- if(!LAZYLEN(parts))
+ if(!LAZYLEN(parts))
return
var/datum/robot_component/picked = pick(parts)
picked.heal_damage(brute, burn, updating_health)
@@ -82,29 +76,6 @@
if(!LAZYLEN(components))
return
- //Combat shielding absorbs a percentage of damage directly into the cell.
- var/obj/item/borg/combat/shield/shield
- if(module_state_1 && istype(module_state_1, /obj/item/borg/combat/shield))
- shield = module_state_1
- else if(module_state_2 && istype(module_state_2, /obj/item/borg/combat/shield))
- shield = module_state_2
- else if(module_state_3 && istype(module_state_3, /obj/item/borg/combat/shield))
- shield = module_state_3
- if(shield)
- //Shields absorb a certain percentage of damage based on their power setting.
- var/absorb_brute = brute * shield.shield_level
- var/absorb_burn = burn * shield.shield_level
- var/cost = (absorb_brute+absorb_burn) * 100
-
- cell.charge -= cost
- if(cell.charge <= 0)
- cell.charge = 0
- to_chat(src, "Your shield has overloaded!")
- else
- brute -= absorb_brute
- burn -= absorb_burn
- to_chat(src, "Your shield absorbs some of the impact!")
-
var/datum/robot_component/armour/A = get_armour()
if(A)
A.take_damage(brute, burn, sharp, updating_health)
@@ -133,32 +104,15 @@
updatehealth("heal overall damage")
/mob/living/silicon/robot/take_overall_damage(brute = 0, burn = 0, updating_health = TRUE, used_weapon = null, sharp = 0)
- if(status_flags & GODMODE) return //godmode
+ if(status_flags & GODMODE)
+ return
+
+ if(damage_protection)
+ brute = clamp(brute - damage_protection, 0, brute)
+ burn = clamp(burn - damage_protection, 0, burn)
+
var/list/datum/robot_component/parts = get_damageable_components()
- //Combat shielding absorbs a percentage of damage directly into the cell.
- var/obj/item/borg/combat/shield/shield
- if(module_state_1 && istype(module_state_1, /obj/item/borg/combat/shield))
- shield = module_state_1
- else if(module_state_2 && istype(module_state_2, /obj/item/borg/combat/shield))
- shield = module_state_2
- else if(module_state_3 && istype(module_state_3, /obj/item/borg/combat/shield))
- shield = module_state_3
- if(shield)
- //Shields absorb a certain percentage of damage based on their power setting.
- var/absorb_brute = brute * shield.shield_level
- var/absorb_burn = burn * shield.shield_level
- var/cost = (absorb_brute+absorb_burn) * 100
-
- cell.charge -= cost
- if(cell.charge <= 0)
- cell.charge = 0
- to_chat(src, "Your shield has overloaded!")
- else
- brute -= absorb_brute
- burn -= absorb_burn
- to_chat(src, "Your shield absorbs some of the impact!")
-
var/datum/robot_component/armour/A = get_armour()
if(A)
A.take_damage(brute, burn, sharp)
diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm
index 9b4f1089f46..8445a399582 100644
--- a/code/modules/mob/living/silicon/robot/robot_defense.dm
+++ b/code/modules/mob/living/silicon/robot/robot_defense.dm
@@ -2,7 +2,7 @@
if(M.a_intent == INTENT_DISARM)
if(!lying)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
- if(prob(85))
+ if(prob(xeno_disarm_chance))
Stun(7)
step(src, get_dir(M,src))
spawn(5)
diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm
index 92115986b2e..b1abb49d2ef 100644
--- a/code/modules/mob/living/silicon/robot/robot_items.dm
+++ b/code/modules/mob/living/silicon/robot/robot_items.dm
@@ -73,24 +73,7 @@
/obj/item/borg
var/powerneeded // Percentage of power remaining required to run item
-/obj/item/borg/combat/shield
- name = "personal shielding"
- desc = "A powerful experimental module that turns aside or absorbs incoming attacks at the cost of charge."
- icon = 'icons/obj/decals.dmi'
- icon_state = "shock"
- powerneeded = 25
- var/shield_level = 0.5 //Percentage of damage absorbed by the shield.
-
-/obj/item/borg/combat/shield/verb/set_shield_level()
- set name = "Set shield level"
- set category = "Object"
- set src in range(0)
-
- var/N = input("How much damage should the shield absorb?") in list("5","10","25","50","75","100")
- if(N)
- shield_level = text2num(N)/100
-
-/obj/item/borg/combat/mobility
+/obj/item/borg/destroyer/mobility
name = "mobility module"
desc = "By retracting limbs and tucking in its head, a combat android can roll at high speeds."
icon = 'icons/obj/decals.dmi'
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 3260775c674..8e8c67693c5 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -118,20 +118,48 @@
return
/obj/item/robot_module/standard
- name = "standard robot module"
+ // if station is fine, assist with constructing station goal room, cleaning, and repairing cables chewed by rats
+ // if medical crisis, assist by providing basic healthcare, retrieving corpses, and monitoring crew lifesigns
+ // if eng crisis, assist by helping repair hull breaches
+ // if sec crisis, assist by opening doors for sec and providing backup zipties on patrols
+ name = "generalist robot module"
module_type = "Standard"
+ subsystems = list(/mob/living/silicon/proc/subsystem_power_monitor, /mob/living/silicon/proc/subsystem_crew_monitor)
+ stacktypes = list(
+ /obj/item/stack/sheet/metal/cyborg = 50,
+ /obj/item/stack/cable_coil/cyborg = 50,
+ /obj/item/stack/rods/cyborg = 60,
+ /obj/item/stack/tile/plasteel = 20
+ )
/obj/item/robot_module/standard/New()
..()
- modules += new /obj/item/melee/baton/loaded(src)
- modules += new /obj/item/extinguisher(src)
- modules += new /obj/item/wrench/cyborg(src)
+ // sec
+ modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src)
+ // janitorial
+ modules += new /obj/item/soap/nanotrasen(src)
+ modules += new /obj/item/lightreplacer/cyborg(src)
+ // eng
modules += new /obj/item/crowbar/cyborg(src)
+ modules += new /obj/item/wrench/cyborg(src)
+ modules += new /obj/item/extinguisher(src) // for firefighting, and propulsion in space
+ modules += new /obj/item/weldingtool/largetank/cyborg(src)
+ // mining
+ modules += new /obj/item/pickaxe(src)
+ modules += new /obj/item/t_scanner/adv_mining_scanner(src)
+ modules += new /obj/item/storage/bag/ore/cyborg(src)
+ // med
modules += new /obj/item/healthanalyzer(src)
+ modules += new /obj/item/reagent_containers/borghypo/basic(src)
+ modules += new /obj/item/roller_holder(src) // for taking the injured to medbay without worsening their injuries or leaving a blood trail the whole way
emag = new /obj/item/melee/energy/sword/cyborg(src)
-
+ for(var/G in stacktypes)
+ var/obj/item/stack/sheet/M = new G(src)
+ M.amount = stacktypes[G]
+ modules += M
fix_modules()
+
/obj/item/robot_module/medical
name = "medical robot module"
module_type = "Medical"
@@ -259,6 +287,7 @@
modules += new /obj/item/mop/advanced/cyborg(src)
modules += new /obj/item/lightreplacer/cyborg(src)
modules += new /obj/item/holosign_creator(src)
+ modules += new /obj/item/extinguisher/mini(src)
emag = new /obj/item/reagent_containers/spray(src)
emag.reagents.add_reagent("lube", 250)
@@ -483,25 +512,44 @@
fix_modules()
-/obj/item/robot_module/combat
- name = "combat robot module"
+/obj/item/robot_module/destroyer
+ name = "destroyer robot module"
module_type = "Malf"
module_actions = list(
/datum/action/innate/robot_sight/thermal,
)
+/obj/item/robot_module/destroyer/New()
+ ..()
+
+ modules += new /obj/item/gun/energy/immolator/multi/cyborg(src) // See comments on /robot_module/combat below
+ modules += new /obj/item/melee/baton/loaded(src) // secondary weapon, for things immune to burn, immune to ranged weapons, or for arresting low-grade threats
+ modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src)
+ modules += new /obj/item/pickaxe/drill/jackhammer(src) // for breaking walls to execute flanking moves
+ modules += new /obj/item/borg/destroyer/mobility(src)
+ emag = null
+ fix_modules()
+
+
+/obj/item/robot_module/combat
+ name = "combat robot module"
+ module_type = "Malf"
+ module_actions = list()
+
/obj/item/robot_module/combat/New()
..()
+ modules += new /obj/item/gun/energy/immolator/multi/cyborg(src) // primary weapon, strong at close range (ie: against blob/terror/xeno), but consumes a lot of energy per shot.
+ // Borg gets 40 shots of this weapon. Gamma Sec ERT gets 10.
+ // So, borg has way more burst damage, but also takes way longer to recharge / get back in the fight once depleted. Has to find a borg recharger and sit in it for ages.
+ // Organic gamma sec ERT carries alternate weapons, including a box of flashbangs, and can load up on a huge number of guns from science. Borg cannot do either.
+ // Overall, gamma borg has higher skill floor but lower skill ceiling.
+ modules += new /obj/item/melee/baton/loaded(src) // secondary weapon, for things immune to burn, immune to ranged weapons, or for arresting low-grade threats
modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src)
- modules += new /obj/item/gun/energy/gun/cyborg(src)
- modules += new /obj/item/pickaxe/drill/jackhammer(src)
- modules += new /obj/item/borg/combat/shield(src)
- modules += new /obj/item/borg/combat/mobility(src)
- modules += new /obj/item/wrench/cyborg(src)
- emag = new /obj/item/gun/energy/lasercannon/cyborg(src)
-
+ modules += new /obj/item/pickaxe/drill/jackhammer(src) // for breaking walls to execute flanking moves
+ emag = null
fix_modules()
+
/obj/item/robot_module/alien/hunter
name = "alien hunter module"
module_type = "Standard"
diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm
index 4b645b02849..1d3e1cade6d 100644
--- a/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -9,7 +9,7 @@
/mob/living/silicon/robot/movement_delay()
. = ..()
. += speed
- if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
+ if(module_active && istype(module_active,/obj/item/borg/destroyer/mobility))
. -= 3
. += config.robot_delay
diff --git a/code/modules/mob/living/silicon/robot/syndicate.dm b/code/modules/mob/living/silicon/robot/syndicate.dm
index f5ac3e5532b..f5b58696059 100644
--- a/code/modules/mob/living/silicon/robot/syndicate.dm
+++ b/code/modules/mob/living/silicon/robot/syndicate.dm
@@ -3,8 +3,10 @@
icon_state = "syndie_bloodhound"
lawupdate = 0
scrambledcodes = 1
+ has_camera = FALSE
pdahide = 1
faction = list("syndicate")
+ bubble_icon = "syndibot"
designation = "Syndicate Assault"
modtype = "Syndicate"
req_access = list(ACCESS_SYNDICATE)
@@ -19,7 +21,7 @@
..()
cell = new /obj/item/stock_parts/cell/hyper(src)
-/mob/living/silicon/robot/syndicate/init()
+/mob/living/silicon/robot/syndicate/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
laws = new /datum/ai_laws/syndicate_override
module = new /obj/item/robot_module/syndicate(src)
@@ -45,7 +47,7 @@
Your energy saw functions as a circular saw, but can be activated to deal more damage, and your operative pinpointer will find and locate fellow nuclear operatives. \
Help the operatives secure the disk at all costs!"
-/mob/living/silicon/robot/syndicate/medical/init()
+/mob/living/silicon/robot/syndicate/medical/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
..()
module = new /obj/item/robot_module/syndicate_medical(src)
@@ -65,7 +67,7 @@
Be aware that physical contact or taking damage will break your disguise. \
Help the operatives secure the disk at all costs!"
-/mob/living/silicon/robot/syndicate/saboteur/init()
+/mob/living/silicon/robot/syndicate/saboteur/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
..()
module = new /obj/item/robot_module/syndicate_saboteur(src)
diff --git a/code/modules/mob/living/silicon/robot/update_status.dm b/code/modules/mob/living/silicon/robot/update_status.dm
index 5f1519395c7..91f9952c075 100644
--- a/code/modules/mob/living/silicon/robot/update_status.dm
+++ b/code/modules/mob/living/silicon/robot/update_status.dm
@@ -17,10 +17,12 @@
if(!is_component_functioning("actuator") || !is_component_functioning("power cell") || paralysis || sleeping || resting || stunned || IsWeakened() || getOxyLoss() > maxHealth * 0.5)
if(stat == CONSCIOUS)
KnockOut()
+ update_headlamp()
create_debug_log("fell unconscious, trigger reason: [reason]")
else
if(stat == UNCONSCIOUS)
WakeUp()
+ update_headlamp()
create_debug_log("woke up, trigger reason: [reason]")
else
if(health > 0)
@@ -31,9 +33,10 @@
ghost << sound('sound/effects/genetics.ogg')
create_attack_log("revived, trigger reason: [reason]")
create_log(MISC_LOG, "revived, trigger reason: [reason]")
- // diag_hud_set_status()
- // diag_hud_set_health()
- // update_health_hud()
+
+ diag_hud_set_status()
+ diag_hud_set_health()
+ update_health_hud()
/mob/living/silicon/robot/SetStunned(amount, updating = 1, force = 0) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned"
. = STATUS_UPDATE_CANMOVE
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 6457afc87d4..c923e0912b7 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -2,7 +2,9 @@
gender = NEUTER
robot_talk_understand = 1
voice_name = "synthesized voice"
+ bubble_icon = "machine"
has_unlimited_silicon_privilege = 1
+ weather_immunities = list("ash")
var/syndicate = 0
var/const/MAIN_CHANNEL = "Main Frequency"
var/lawchannel = MAIN_CHANNEL // Default channel on which to state laws
@@ -283,7 +285,7 @@
/mob/living/silicon/proc/receive_alarm(var/datum/alarm_handler/alarm_handler, var/datum/alarm/alarm, was_raised)
if(!next_alarm_notice)
- next_alarm_notice = world.time + SecondsToTicks(10)
+ next_alarm_notice = world.time + 10 SECONDS
var/list/alarms = queued_alarms[alarm_handler]
if(was_raised)
diff --git a/code/modules/mob/living/silicon/subsystems.dm b/code/modules/mob/living/silicon/subsystems.dm
index 5f00beff1e4..d18d41a40cf 100644
--- a/code/modules/mob/living/silicon/subsystems.dm
+++ b/code/modules/mob/living/silicon/subsystems.dm
@@ -2,7 +2,7 @@
var/register_alarms = 1
var/datum/nano_module/alarm_monitor/all/alarm_monitor
var/datum/nano_module/atmos_control/atmos_control
- var/datum/nano_module/crew_monitor/crew_monitor
+ var/datum/tgui_module/crew_monitor/crew_monitor
var/datum/nano_module/law_manager/law_manager
var/datum/nano_module/power_monitor/silicon/power_monitor
@@ -71,8 +71,7 @@
/mob/living/silicon/proc/subsystem_crew_monitor()
set category = "Subsystems"
set name = "Crew Monitor"
-
- crew_monitor.ui_interact(usr, state = GLOB.self_state)
+ crew_monitor.tgui_interact(usr, state = GLOB.tgui_self_state)
/****************
* Law Manager *
diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm
index 2cfc5e746dc..b42f3275997 100644
--- a/code/modules/mob/living/simple_animal/animal_defense.dm
+++ b/code/modules/mob/living/simple_animal/animal_defense.dm
@@ -118,7 +118,7 @@
/mob/living/simple_animal/blob_act(obj/structure/blob/B)
adjustBruteLoss(20)
-/mob/living/simple_animal/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y)
+/mob/living/simple_animal/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect)
if(!no_effect && !visual_effect_icon && melee_damage_upper)
if(melee_damage_upper < 10)
visual_effect_icon = ATTACK_EFFECT_PUNCH
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 88d130ddc82..e51dc527832 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -18,7 +18,7 @@
speak_emote = list("states")
friendly = "boops"
-
+ bubble_icon = "machine"
faction = list("neutral", "silicon")
var/obj/machinery/bot_core/bot_core = null
@@ -63,6 +63,7 @@
var/new_destination // pending new destination (waiting for beacon response)
var/destination // destination description tag
var/next_destination // the next destination in the patrol route
+ var/ignorelistcleanuptimer = 1 // This ticks up every automated action, at 300 we clean the ignore list
var/robot_arm = /obj/item/robot_parts/r_arm
var/blockcount = 0 //number of times retried a blocked path
@@ -254,6 +255,15 @@
/mob/living/simple_animal/bot/handle_automated_action()
diag_hud_set_botmode()
+ if(ignorelistcleanuptimer % 300 == 0) // Every 300 actions, clean up the ignore list from old junk
+ for(var/uid in ignore_list)
+ var/atom/referredatom = locateUID(uid)
+ if(!referredatom || QDELETED(referredatom))
+ ignore_list -= uid
+ ignorelistcleanuptimer = 1
+ else
+ ignorelistcleanuptimer++
+
if(!on)
return
@@ -439,14 +449,15 @@ Example usage: patient = scan(/mob/living/carbon/human, oldpatient, 1)
The proc would return a human next to the bot to be set to the patient var.
Pass the desired type path itself, declaring a temporary var beforehand is not required.
*/
-/mob/living/simple_animal/bot/proc/scan(scan_type, old_target, scan_range = DEFAULT_SCAN_RANGE)
+/mob/living/simple_animal/bot/proc/scan(atom/scan_type, atom/old_target, scan_range = DEFAULT_SCAN_RANGE)
var/final_result
for(var/scan in shuffle(view(scan_range, src))) //Search for something in range!
- if(!istype(scan, scan_type)) //Check that the thing we found is the type we want!
+ var/atom/A = scan
+ if(!istype(A, scan_type)) //Check that the thing we found is the type we want!
continue //If not, keep searching!
- if( (scan in ignore_list) || (scan == old_target) ) //Filter for blacklisted elements, usually unreachable or previously processed oness
+ if((A.UID() in ignore_list) || (A == old_target) ) //Filter for blacklisted elements, usually unreachable or previously processed oness
continue
- var/scan_result = process_scan(scan) //Some bots may require additional processing when a result is selected.
+ var/scan_result = process_scan(A) //Some bots may require additional processing when a result is selected.
if(scan_result)
final_result = scan_result
else
@@ -454,17 +465,16 @@ Pass the desired type path itself, declaring a temporary var beforehand is not r
return final_result
//When the scan finds a target, run bot specific processing to select it for the next step. Empty by default.
-/mob/living/simple_animal/bot/proc/process_scan(scan_target)
+/mob/living/simple_animal/bot/proc/process_scan(atom/scan_target)
return scan_target
-/mob/living/simple_animal/bot/proc/add_to_ignore(subject)
+/mob/living/simple_animal/bot/proc/add_to_ignore(atom/A)
if(ignore_list.len < 50) //This will help keep track of them, so the bot is always trying to reach a blocked spot.
- ignore_list |= subject
- else if(ignore_list.len >= subject) //If the list is full, insert newest, delete oldest.
- ignore_list -= ignore_list[1]
- ignore_list |= subject
-
+ ignore_list |= A.UID()
+ else //If the list is full, insert newest, delete oldest.
+ ignore_list.Cut(1, 2)
+ ignore_list |= A.UID()
/*
Movement proc for stepping a bot through a path generated through A-star.
Pass a positive integer as an argument to override a bot's default speed.
@@ -746,7 +756,7 @@ Pass a positive integer as an argument to override a bot's default speed.
// send a radio signal with multiple data key/values
/mob/living/simple_animal/bot/proc/post_signal_multiple(var/freq, var/list/keyval)
- if(z != 1) //Bot control will only work on station.
+ if(!is_station_level(z)) //Bot control will only work on station.
return
var/datum/radio_frequency/frequency = SSradio.return_frequency(freq)
if(!frequency)
@@ -1031,20 +1041,6 @@ Pass a positive integer as an argument to override a bot's default speed.
Radio.talk_into(src, message, message_mode, verb, speaking)
used_radios += Radio
-/mob/living/simple_animal/bot/handle_hud_icons_health()
- ..()
- switch(bodytemperature) //310.055 optimal body temp
- if(335 to INFINITY)
- throw_alert("temp", /obj/screen/alert/hot/robot, 2)
- if(320 to 335)
- throw_alert("temp", /obj/screen/alert/hot/robot, 1)
- if(300 to 320)
- clear_alert("temp")
- if(260 to 300)
- throw_alert("temp", /obj/screen/alert/cold/robot, 1)
- else
- throw_alert("temp", /obj/screen/alert/cold/robot, 2)
-
/mob/living/simple_animal/bot/is_mechanical()
return 1
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index f9747238138..4cb4a532d6b 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -50,7 +50,7 @@
/mob/living/simple_animal/bot/cleanbot/bot_reset()
..()
- ignore_list = list() //Allows the bot to clean targets it previously ignored due to being unreachable.
+ ignore_list.Cut() //Allows the bot to clean targets it previously ignored due to being unreachable.
target = null
oldloc = null
@@ -106,7 +106,7 @@
audible_message("[src] makes an excited beeping booping sound!")
if(!target) //Search for cleanables it can see.
- target = scan(/obj/effect/decal/cleanable/)
+ target = scan(/obj/effect/decal/cleanable)
if(!target && auto_patrol) //Search for cleanables it can see.
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index 024e2b5f304..e18672ffa20 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -474,8 +474,7 @@
return
build_step++
to_chat(user, "You complete the Securitron! Beep boop.")
- var/mob/living/simple_animal/bot/secbot/S = new /mob/living/simple_animal/bot/secbot
- S.forceMove(get_turf(src))
+ var/mob/living/simple_animal/bot/secbot/S = new /mob/living/simple_animal/bot/secbot(get_turf(src))
S.name = created_name
S.robot_arm = robot_arm
qdel(I)
@@ -512,7 +511,7 @@
//General Griefsky
else if((istype(I, /obj/item/wrench)) && (build_step == 3))
- var/obj/item/griefsky_assembly/A = new /obj/item/griefsky_assembly
+ var/obj/item/griefsky_assembly/A = new /obj/item/griefsky_assembly(get_turf(src))
user.put_in_hands(A)
to_chat(user, "You adjust the arm slots for extra weapons!.")
user.unEquip(src, 1)
@@ -540,8 +539,7 @@
if(!user.unEquip(I))
return
to_chat(user, "You complete General Griefsky!.")
- var/mob/living/simple_animal/bot/secbot/griefsky/S = new /mob/living/simple_animal/bot/secbot/griefsky
- S.forceMove(get_turf(src))
+ new /mob/living/simple_animal/bot/secbot/griefsky(get_turf(src))
qdel(I)
qdel(src)
@@ -556,8 +554,7 @@
if(!user.unEquip(I))
return
to_chat(user, "You complete Genewul Giftskee!.")
- var/mob/living/simple_animal/bot/secbot/griefsky/toy/S = new /mob/living/simple_animal/bot/secbot/griefsky/toy
- S.forceMove(get_turf(src))
+ new /mob/living/simple_animal/bot/secbot/griefsky/toy(get_turf(src))
qdel(I)
qdel(src)
diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm
index 5b0ea28a72a..df96cae3b6b 100644
--- a/code/modules/mob/living/simple_animal/bot/floorbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm
@@ -56,7 +56,7 @@
..()
target = null
oldloc = null
- ignore_list = list()
+ ignore_list.Cut()
nagged = 0
anchored = FALSE
update_icon()
@@ -270,7 +270,7 @@
return 1
//Floorbots, having several functions, need sort out special conditions here.
-/mob/living/simple_animal/bot/floorbot/process_scan(scan_target)
+/mob/living/simple_animal/bot/floorbot/process_scan(atom/scan_target)
var/result
var/turf/simulated/floor/F
switch(process_type)
diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm
index d9097a82d2e..62c133fffd7 100644
--- a/code/modules/mob/living/simple_animal/bot/honkbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm
@@ -33,7 +33,7 @@
/obj/machinery/bot_core/honkbot
req_one_access = list(ACCESS_CLOWN, ACCESS_ROBOTICS, ACCESS_MIME)
-/mob/living/simple_animal/bot/honkbot/Initialize()
+/mob/living/simple_animal/bot/honkbot/Initialize(mapload)
. = ..()
update_icon()
auto_patrol = TRUE
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index c89b160bf0e..f1278918898 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -323,13 +323,13 @@
/mob/living/simple_animal/bot/mulebot/proc/buzz(type)
switch(type)
if(SIGH)
- audible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
+ audible_message("[src] makes a sighing buzz.")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
if(ANNOYED)
- audible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.")
+ audible_message("[src] makes an annoyed buzzing sound.")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
if(DELIGHT)
- audible_message("[src] makes a delighted ping!", "You hear a ping.")
+ audible_message("[src] makes a delighted ping!")
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
@@ -391,8 +391,6 @@
passenger = M
load = M
can_buckle = FALSE
- // Not sure why this is done
- reset_perspective(src)
return TRUE
return FALSE
@@ -417,9 +415,6 @@
overlays.Cut()
- if(ismob(load))
- var/mob/M = load
- M.reset_perspective(null)
unbuckle_all_mobs()
if(load)
@@ -446,9 +441,6 @@
AM.layer = initial(AM.layer)
AM.pixel_y = initial(AM.pixel_y)
AM.plane = initial(AM.plane)
- if(ismob(AM))
- var/mob/M = AM
- M.reset_perspective(null)
/mob/living/simple_animal/bot/mulebot/call_bot()
..()
@@ -609,7 +601,7 @@
/mob/living/simple_animal/bot/mulebot/proc/at_target()
if(!reached_target)
radio_channel = "Supply" //Supply channel
- audible_message("[src] makes a chiming sound!", "You hear a chime.")
+ audible_message("[src] makes a chiming sound!")
playsound(loc, 'sound/machines/chime.ogg', 50, 0)
reached_target = 1
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index ee03c204d48..f150005116e 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -333,73 +333,116 @@
///ui stuff
-/mob/living/simple_animal/hostile/construct/armoured/handle_hud_icons_health()
- ..()
+/mob/living/simple_animal/hostile/construct/armoured/update_health_hud()
+ if(!client)
+ return
if(healths)
switch(health)
- if(250 to INFINITY) healths.icon_state = "juggernaut_health0"
- if(208 to 249) healths.icon_state = "juggernaut_health1"
- if(167 to 207) healths.icon_state = "juggernaut_health2"
- if(125 to 166) healths.icon_state = "juggernaut_health3"
- if(84 to 124) healths.icon_state = "juggernaut_health4"
- if(42 to 83) healths.icon_state = "juggernaut_health5"
- if(1 to 41) healths.icon_state = "juggernaut_health6"
- else healths.icon_state = "juggernaut_health7"
+ if(250 to INFINITY)
+ healths.icon_state = "juggernaut_health0"
+ if(208 to 249)
+ healths.icon_state = "juggernaut_health1"
+ if(167 to 207)
+ healths.icon_state = "juggernaut_health2"
+ if(125 to 166)
+ healths.icon_state = "juggernaut_health3"
+ if(84 to 124)
+ healths.icon_state = "juggernaut_health4"
+ if(42 to 83)
+ healths.icon_state = "juggernaut_health5"
+ if(1 to 41)
+ healths.icon_state = "juggernaut_health6"
+ else
+ healths.icon_state = "juggernaut_health7"
-/mob/living/simple_animal/hostile/construct/behemoth/handle_hud_icons_health()
- ..()
+/mob/living/simple_animal/hostile/construct/behemoth/update_health_hud()
+ if(!client)
+ return
if(healths)
switch(health)
- if(750 to INFINITY) healths.icon_state = "juggernaut_health0"
- if(625 to 749) healths.icon_state = "juggernaut_health1"
- if(500 to 624) healths.icon_state = "juggernaut_health2"
- if(375 to 499) healths.icon_state = "juggernaut_health3"
- if(250 to 374) healths.icon_state = "juggernaut_health4"
- if(125 to 249) healths.icon_state = "juggernaut_health5"
- if(1 to 124) healths.icon_state = "juggernaut_health6"
- else healths.icon_state = "juggernaut_health7"
+ if(750 to INFINITY)
+ healths.icon_state = "juggernaut_health0"
+ if(625 to 749)
+ healths.icon_state = "juggernaut_health1"
+ if(500 to 624)
+ healths.icon_state = "juggernaut_health2"
+ if(375 to 499)
+ healths.icon_state = "juggernaut_health3"
+ if(250 to 374)
+ healths.icon_state = "juggernaut_health4"
+ if(125 to 249)
+ healths.icon_state = "juggernaut_health5"
+ if(1 to 124)
+ healths.icon_state = "juggernaut_health6"
+ else
+ healths.icon_state = "juggernaut_health7"
-/mob/living/simple_animal/hostile/construct/builder/handle_hud_icons_health()
- ..()
+/mob/living/simple_animal/hostile/construct/builder/update_health_hud()
+ if(!client)
+ return
if(healths)
switch(health)
- if(50 to INFINITY) healths.icon_state = "artificer_health0"
- if(42 to 49) healths.icon_state = "artificer_health1"
- if(34 to 41) healths.icon_state = "artificer_health2"
- if(26 to 33) healths.icon_state = "artificer_health3"
- if(18 to 25) healths.icon_state = "artificer_health4"
- if(10 to 17) healths.icon_state = "artificer_health5"
- if(1 to 9) healths.icon_state = "artificer_health6"
- else healths.icon_state = "artificer_health7"
+ if(50 to INFINITY)
+ healths.icon_state = "artificer_health0"
+ if(42 to 49)
+ healths.icon_state = "artificer_health1"
+ if(34 to 41)
+ healths.icon_state = "artificer_health2"
+ if(26 to 33)
+ healths.icon_state = "artificer_health3"
+ if(18 to 25)
+ healths.icon_state = "artificer_health4"
+ if(10 to 17)
+ healths.icon_state = "artificer_health5"
+ if(1 to 9)
+ healths.icon_state = "artificer_health6"
+ else
+ healths.icon_state = "artificer_health7"
-/mob/living/simple_animal/hostile/construct/wraith/handle_hud_icons_health()
-
- ..()
+/mob/living/simple_animal/hostile/construct/wraith/update_health_hud()
+ if(!client)
+ return
if(healths)
switch(health)
- if(75 to INFINITY) healths.icon_state = "wraith_health0"
- if(62 to 74) healths.icon_state = "wraith_health1"
- if(50 to 61) healths.icon_state = "wraith_health2"
- if(37 to 49) healths.icon_state = "wraith_health3"
- if(25 to 36) healths.icon_state = "wraith_health4"
- if(12 to 24) healths.icon_state = "wraith_health5"
- if(1 to 11) healths.icon_state = "wraith_health6"
- else healths.icon_state = "wraith_health7"
+ if(75 to INFINITY)
+ healths.icon_state = "wraith_health0"
+ if(62 to 74)
+ healths.icon_state = "wraith_health1"
+ if(50 to 61)
+ healths.icon_state = "wraith_health2"
+ if(37 to 49)
+ healths.icon_state = "wraith_health3"
+ if(25 to 36)
+ healths.icon_state = "wraith_health4"
+ if(12 to 24)
+ healths.icon_state = "wraith_health5"
+ if(1 to 11)
+ healths.icon_state = "wraith_health6"
+ else
+ healths.icon_state = "wraith_health7"
-/mob/living/simple_animal/hostile/construct/harvester/handle_hud_icons_health()
-
- ..()
+/mob/living/simple_animal/hostile/construct/harvester/update_health_hud()
+ if(!client)
+ return
if(healths)
switch(health)
- if(150 to INFINITY) healths.icon_state = "harvester_health0"
- if(125 to 149) healths.icon_state = "harvester_health1"
- if(100 to 124) healths.icon_state = "harvester_health2"
- if(75 to 99) healths.icon_state = "harvester_health3"
- if(50 to 74) healths.icon_state = "harvester_health4"
- if(25 to 49) healths.icon_state = "harvester_health5"
- if(1 to 24) healths.icon_state = "harvester_health6"
- else healths.icon_state = "harvester_health7"
+ if(150 to INFINITY)
+ healths.icon_state = "harvester_health0"
+ if(125 to 149)
+ healths.icon_state = "harvester_health1"
+ if(100 to 124)
+ healths.icon_state = "harvester_health2"
+ if(75 to 99)
+ healths.icon_state = "harvester_health3"
+ if(50 to 74)
+ healths.icon_state = "harvester_health4"
+ if(25 to 49)
+ healths.icon_state = "harvester_health5"
+ if(1 to 24)
+ healths.icon_state = "harvester_health6"
+ else
+ healths.icon_state = "harvester_health7"
diff --git a/code/modules/mob/living/simple_animal/corpse.dm b/code/modules/mob/living/simple_animal/corpse.dm
index 10460d11e65..8d0ad5d0e2b 100644
--- a/code/modules/mob/living/simple_animal/corpse.dm
+++ b/code/modules/mob/living/simple_animal/corpse.dm
@@ -103,9 +103,9 @@
name = "Space Wizard Corpse"
outfit = /datum/outfit/wizardcorpse
-/obj/effect/mob_spawn/human/corpse/clownoff/Initialize()
+/obj/effect/mob_spawn/human/corpse/clownoff/Initialize(mapload)
mob_name = "[pick(GLOB.wizard_first)], [pick(GLOB.wizard_second)]"
- ..()
+ . = ..()
/datum/outfit/wizardcorpse
name = "Space Wizard Corpse"
diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm
index 6ba69de6a61..fdcbf95216b 100644
--- a/code/modules/mob/living/simple_animal/damage_procs.dm
+++ b/code/modules/mob/living/simple_animal/damage_procs.dm
@@ -3,7 +3,7 @@
if(status_flags & GODMODE)
return FALSE
var/oldbruteloss = bruteloss
- bruteloss = Clamp(bruteloss + amount, 0, maxHealth)
+ bruteloss = clamp(bruteloss + amount, 0, maxHealth)
if(oldbruteloss == bruteloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index 4b29e703116..07a21af8a0b 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -153,16 +153,16 @@
if(def_zone)
if(def_zone == "head")
if(inventory_head)
- armorval = inventory_head.armor[type]
+ armorval = inventory_head.armor.getRating(type)
else
if(inventory_back)
- armorval = inventory_back.armor[type]
+ armorval = inventory_back.armor.getRating(type)
return armorval
else
if(inventory_head)
- armorval += inventory_head.armor[type]
+ armorval += inventory_head.armor.getRating(type)
if(inventory_back)
- armorval += inventory_back.armor[type]
+ armorval += inventory_back.armor.getRating(type)
return armorval * 0.5
/mob/living/simple_animal/pet/dog/corgi/attackby(obj/item/O, mob/user, params)
diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm
index 96688963b73..566791786f6 100644
--- a/code/modules/mob/living/simple_animal/friendly/lizard.dm
+++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm
@@ -23,3 +23,14 @@
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat = 1)
can_collar = 1
gold_core_spawnable = FRIENDLY_SPAWN
+
+/mob/living/simple_animal/lizard/decompile_act(obj/item/matter_decompiler/C, mob/user)
+ if(!istype(user, /mob/living/silicon/robot/drone))
+ user.visible_message("[user] sucks [src] into its decompiler. There's a horrible crunching noise.", \
+ "It's a bit of a struggle, but you manage to suck [src] into your decompiler. It makes a series of visceral crunching noises.")
+ new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
+ C.stored_comms["wood"] += 2
+ C.stored_comms["glass"] += 2
+ qdel(src)
+ return TRUE
+ return ..()
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index a48b36cb0c7..152e2494132 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -234,3 +234,14 @@
gold_core_spawnable = NO_SPAWN
can_collar = 0
butcher_results = list(/obj/item/stack/sheet/metal = 1)
+
+/mob/living/simple_animal/mouse/decompile_act(obj/item/matter_decompiler/C, mob/user)
+ if(!(istype(user, /mob/living/silicon/robot/drone)))
+ user.visible_message("[user] sucks [src] into its decompiler. There's a horrible crunching noise.", \
+ "It's a bit of a struggle, but you manage to suck [src] into your decompiler. It makes a series of visceral crunching noises.")
+ new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
+ C.stored_comms["wood"] += 2
+ C.stored_comms["glass"] += 2
+ qdel(src)
+ return TRUE
+ return ..()
diff --git a/code/modules/mob/living/simple_animal/friendly/penguin.dm b/code/modules/mob/living/simple_animal/friendly/penguin.dm
index dc00e252661..08321b1bb5a 100644
--- a/code/modules/mob/living/simple_animal/friendly/penguin.dm
+++ b/code/modules/mob/living/simple_animal/friendly/penguin.dm
@@ -18,7 +18,7 @@
/mob/living/simple_animal/pet/penguin/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/waddling)
+ AddElement(/datum/element/waddling)
/mob/living/simple_animal/pet/penguin/emperor
name = "Emperor penguin"
diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
index 7a1227960f4..877d542fa2b 100644
--- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
@@ -123,8 +123,6 @@
if(health >= maxHealth)
to_chat(user, "[src] does not need repairing!")
return
- to_chat(user, "Unable to repair with the maintenance panel closed!")
- return
. = TRUE
if(!I.use_tool(src, user, volume = I.tool_volume))
return
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index 038b3b3d221..7c7b4dd6a2f 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -20,6 +20,7 @@
melee_damage_upper = 25
attacktext = "slashes"
speak_emote = list("hisses")
+ bubble_icon = "alien"
a_intent = INTENT_HARM
attack_sound = 'sound/weapons/bladeslice.ogg'
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)
@@ -127,6 +128,7 @@
icon_state = "queen_s"
icon_living = "queen_s"
icon_dead = "queen_dead"
+ bubble_icon = "alienroyal"
move_to_delay = 4
maxHealth = 400
health = 400
@@ -153,7 +155,7 @@
icon_dead = "maid_dead"
/mob/living/simple_animal/hostile/alien/maid/AttackingTarget()
- if(ismovableatom(target))
+ if(ismovable(target))
if(istype(target, /obj/effect/decal/cleanable))
visible_message("\The [src] cleans up \the [target].")
qdel(target)
diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm
index c1e7548d9a3..3276416fe7f 100644
--- a/code/modules/mob/living/simple_animal/hostile/bees.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bees.dm
@@ -60,6 +60,7 @@
/mob/living/simple_animal/hostile/poison/bees/New()
..()
generate_bee_visuals()
+ AddComponent(/datum/component/swarming)
/mob/living/simple_animal/hostile/poison/bees/Destroy()
beegent = null
diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm
index 8d2ba52709f..c093c8e3d36 100644
--- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm
+++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm
@@ -25,23 +25,20 @@
var/list/human_overlays = list()
/mob/living/simple_animal/hostile/headcrab/Life(seconds, times_fired)
- if(..())
+ if(..() && !stat)
if(!is_zombie && isturf(src.loc))
for(var/mob/living/carbon/human/H in oview(src, 1)) //Only for corpse right next to/on same tile
if(H.stat == DEAD || (!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD))
Zombify(H)
break
- var/cycles = 4
- if(cycles >= 4)
+ if(times_fired % 4 == 0)
for(var/mob/living/simple_animal/K in oview(src, 1)) //Only for corpse right next to/on same tile
if(K.stat == DEAD || (!K.check_death_method() && K.health <= HEALTH_THRESHOLD_DEAD))
- visible_message("[src] consumes [target] whole!")
+ visible_message("[src] consumes [K] whole!")
if(health < maxHealth)
health += 10
qdel(K)
break
- cycles = 0
- cycles++
/mob/living/simple_animal/hostile/headcrab/OpenFire(atom/A)
if(check_friendly_fire)
@@ -62,8 +59,8 @@
is_zombie = TRUE
if(H.wear_suit)
var/obj/item/clothing/suit/armor/A = H.wear_suit
- if(A.armor && A.armor["melee"])
- maxHealth += A.armor["melee"] //That zombie's got armor, I want armor!
+ if(A.armor && A.armor.getRating("melee"))
+ maxHealth += A.armor.getRating("melee") //That zombie's got armor, I want armor!
maxHealth += 200
health = maxHealth
name = "zombie"
@@ -93,7 +90,6 @@
if(is_zombie)
qdel(src)
-
/mob/living/simple_animal/hostile/headcrab/handle_automated_speech() // This way they have different screams when attacking, sometimes. Might be seen as sphagetthi code though.
if(speak_chance)
if(rand(0,200) < speak_chance)
@@ -106,7 +102,6 @@
M.loc = get_turf(src)
return ..()
-
/mob/living/simple_animal/hostile/headcrab/update_icons()
. = ..()
if(is_zombie)
diff --git a/code/modules/mob/living/simple_animal/hostile/headslug.dm b/code/modules/mob/living/simple_animal/hostile/headslug.dm
index 801514a3256..6800598fc7f 100644
--- a/code/modules/mob/living/simple_animal/hostile/headslug.dm
+++ b/code/modules/mob/living/simple_animal/hostile/headslug.dm
@@ -72,7 +72,7 @@
/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop()
var/mob/living/carbon/human/monkey/M = new(owner)
- owner.stomach_contents += M
+ LAZYADD(owner.stomach_contents, M)
for(var/obj/item/organ/internal/I in src)
I.insert(M, 1)
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
index d2a97949c8e..c6f3ac845e3 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
@@ -25,6 +25,7 @@
gold_core_spawnable = HOSTILE_SPAWN
loot = list(/obj/effect/decal/cleanable/blood/gibs/robot)
deathmessage = "blows apart!"
+ bubble_icon = "machine"
del_on_death = 1
/mob/living/simple_animal/hostile/hivebot/range
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 6cde07d0b8d..469ff0cc7e1 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -79,7 +79,7 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize(mapload)
. = ..()
if(true_spawn)
- for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in GLOB.living_mob_list)
+ for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in GLOB.alive_mob_list)
if(B != src)
qdel(src) //There can be only one
return
@@ -116,8 +116,8 @@ Difficulty: Hard
if(charging)
return
- anger_modifier = Clamp(((maxHealth - health)/60),0,20)
- enrage_time = initial(enrage_time) * Clamp(anger_modifier / 20, 0.5, 1)
+ anger_modifier = clamp(((maxHealth - health)/60),0,20)
+ enrage_time = initial(enrage_time) * clamp(anger_modifier / 20, 0.5, 1)
ranged_cooldown = world.time + 50
if(client)
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 7f1b3942d94..b8c72d7cf84 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -83,7 +83,7 @@ Difficulty: Very Hard
chosen_attack_num = 4
/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(client)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
index e97b7671b67..50531f976e9 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
@@ -103,7 +103,7 @@ Difficulty: Medium
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(client)
@@ -254,7 +254,7 @@ Difficulty: Medium
/mob/living/simple_animal/hostile/megafauna/dragon/proc/line_target(var/offset, var/range, var/atom/at = target)
if(!at)
return
- var/angle = Atan2(at.x - src.x, at.y - src.y) + offset
+ var/angle = ATAN2(at.x - src.x, at.y - src.y) + offset
var/turf/T = get_turf(src)
for(var/i in 1 to range)
var/turf/check = locate(src.x + cos(angle) * i, src.y + sin(angle) * i, src.z)
@@ -344,10 +344,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)
@@ -534,7 +534,7 @@ obj/effect/temp_visual/fireball
duration = 9
pixel_z = 270
-/obj/effect/temp_visual/fireball/Initialize()
+/obj/effect/temp_visual/fireball/Initialize(mapload)
. = ..()
animate(src, pixel_z = 0, time = duration)
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 716f5436223..65d056188a8 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -452,6 +452,7 @@ Difficulty: Hard
else
burst_range = 3
INVOKE_ASYNC(src, .proc/burst, get_turf(src), 0.25) //melee attacks on living mobs cause it to release a fast burst if on cooldown
+ OpenFire()
else
devour(L)
else
@@ -481,7 +482,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/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index 4ce66ccd1d5..eed05d55e91 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -43,7 +43,6 @@
. = ..()
if(internal_type && true_spawn)
internal = new internal_type(src)
- apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
for(var/action_type in attack_action_types)
var/datum/action/innate/megafauna_attack/attack_action = new action_type()
attack_action.Grant(src)
diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm
index 848a285abf4..fbf65ccfa9b 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimic.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm
@@ -48,8 +48,8 @@
var/attempt_open = 0
// Pickup loot
-/mob/living/simple_animal/hostile/mimic/crate/Initialize()
- ..()
+/mob/living/simple_animal/hostile/mimic/crate/Initialize(mapload)
+ . = ..()
for(var/obj/item/I in loc)
I.loc = src
diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
index ca9b632e06a..a5248e98bb6 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
@@ -90,6 +90,7 @@
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Initialize(mapload)
. = ..()
addtimer(CALLBACK(src, .proc/death), 100)
+ AddComponent(/datum/component/swarming)
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood
diff --git a/code/modules/mob/living/simple_animal/hostile/mining/mining.dm b/code/modules/mob/living/simple_animal/hostile/mining/mining.dm
index 7c7200e8588..a888fa7ee9a 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining/mining.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining/mining.dm
@@ -23,10 +23,6 @@
var/icon_aggro = null
var/crusher_drop_mod = 25
-/mob/living/simple_animal/hostile/asteroid/Initialize(mapload)
- . = ..()
- apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
-
/mob/living/simple_animal/hostile/asteroid/Aggro()
..()
if(vision_range != aggro_vision_range)
diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
index e8ce4027b4e..89164167005 100644
--- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -31,7 +31,7 @@
deathmessage = "wails as its form turns into a pulpy mush."
death_sound = 'sound/voice/hiss6.ogg'
-/mob/living/simple_animal/hostile/netherworld/migo/Initialize()
+/mob/living/simple_animal/hostile/netherworld/migo/Initialize(mapload)
. = ..()
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/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.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/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/weapons/sear.ogg', 'sound/ambience/antag/tatoralert.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/clownstep2.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heartbeat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/goonstation/effects/screech.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.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/goonstation/misc/airraid_loop.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/chainsaw.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/gunshots/gunshot_silenced.ogg', 'sound/weapons/gunshots/gunshot.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlock_close.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlock_open.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/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/ambience/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.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', 'sound/ambience/ambigen1.ogg', 'sound/ambience/ambigen3.ogg', 'sound/ambience/ambigen4.ogg', 'sound/ambience/ambigen5.ogg', 'sound/ambience/ambigen6.ogg', 'sound/ambience/ambigen10.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg') //hahahaha fuck you code divers
@@ -82,14 +82,14 @@
/obj/structure/spawner/nether/examine(mob/user)
. = ..()
- if(isskeleton(user) || iszombie(user))
+ if(isskeleton(user))
. += "A direct link to another dimension full of creatures very happy to see you. You can see your house from here!"
else
. += "A direct link to another dimension full of creatures not very happy to see you. Entering the link would be a very bad idea."
/obj/structure/spawner/nether/attack_hand(mob/user)
. = ..()
- if(isskeleton(user) || iszombie(user))
+ if(isskeleton(user))
to_chat(user, "You don't feel like going home yet...")
else
user.visible_message("[user] is violently pulled into the link!", \
diff --git a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm
index fd569984920..07f26031ed5 100644
--- a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm
+++ b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm
@@ -335,7 +335,7 @@
//Jiggle the whole worm forwards towards the next segment
-/mob/living/simple_animal/hostile/spaceWorm/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y)
+/mob/living/simple_animal/hostile/spaceWorm/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect)
..()
if(previousWorm)
previousWorm.do_attack_animation(src)
diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm
index 95ce5491395..105b9a02819 100644
--- a/code/modules/mob/living/simple_animal/hostile/statue.dm
+++ b/code/modules/mob/living/simple_animal/hostile/statue.dm
@@ -180,7 +180,7 @@
range = 10
/obj/effect/proc_holder/spell/aoe_turf/blindness/cast(list/targets, mob/user = usr)
- for(var/mob/living/L in GLOB.living_mob_list)
+ for(var/mob/living/L in GLOB.alive_mob_list)
if(L == user)
continue
var/turf/T = get_turf(L.loc)
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
index f3389108498..decfc7146cf 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
@@ -260,7 +260,7 @@
alert_on_shield_breach = TRUE
/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory/Initialize(mapload)
- ..()
+ . = ..()
if(prob(50))
// 50% chance of switching to extremely dangerous ranged variant
melee_damage_lower = 10
@@ -281,7 +281,7 @@
/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory/LateInitialize()
if(istype(depotarea))
var/list/key_candidates = list()
- for(var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/O in GLOB.living_mob_list)
+ for(var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/O in GLOB.alive_mob_list)
key_candidates += O
if(key_candidates.len)
var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/O = pick(key_candidates)
@@ -349,7 +349,8 @@
icon = 'icons/mob/critter.dmi'
icon_state = "viscerator_attack"
icon_living = "viscerator_attack"
- pass_flags = PASSTABLE
+ pass_flags = PASSTABLE | PASSMOB
+ a_intent = INTENT_HARM
health = 15
maxHealth = 15
obj_damage = 0
@@ -362,6 +363,11 @@
minbodytemp = 0
mob_size = MOB_SIZE_TINY
flying = 1
+ bubble_icon = "syndibot"
gold_core_spawnable = HOSTILE_SPAWN
del_on_death = 1
deathmessage = "is smashed into pieces!"
+
+/mob/living/simple_animal/hostile/viscerator/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/swarming)
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm
index 828e0e5f8f6..047219a151b 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm
@@ -38,9 +38,12 @@
evolvequeen_action.Grant(src)
/mob/living/simple_animal/hostile/poison/terror_spider/princess/proc/evolve_to_queen()
- var/mob/living/simple_animal/hostile/poison/terror_spider/queen/Q = new /mob/living/simple_animal/hostile/poison/terror_spider/queen(loc)
+ var/mob/living/simple_animal/hostile/poison/terror_spider/queen/Q = new(loc)
if(mind)
mind.transfer_to(Q)
+ // Calling `transfer_to()` removes our new body (the Queen's) ability to see the med hud, so we have to re-add the queen here.
+ var/datum/atom_hud/U = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
+ U.add_hud_to(Q)
qdel(src)
/mob/living/simple_animal/hostile/poison/terror_spider/princess/DoWrap()
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
index 241cceb3d2c..bf3c98bb86a 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
@@ -168,7 +168,7 @@
neststep = 4
else
spider_lastspawn = world.time
- var/spiders_left_to_spawn = Clamp( (spider_max_per_nest - CountSpiders()), 1, 10)
+ var/spiders_left_to_spawn = clamp( (spider_max_per_nest - CountSpiders()), 1, 10)
DoLayTerrorEggs(pick(spider_types_standard), spiders_left_to_spawn)
if(4)
// Nest should be full. Otherwise, start replenishing nest (stage 5).
diff --git a/code/modules/mob/living/simple_animal/posessed_object.dm b/code/modules/mob/living/simple_animal/posessed_object.dm
index bde995d8edb..c3cb61d5970 100644
--- a/code/modules/mob/living/simple_animal/posessed_object.dm
+++ b/code/modules/mob/living/simple_animal/posessed_object.dm
@@ -27,7 +27,7 @@
. += "[src] appears to be having trouble staying afloat!"
-/mob/living/simple_animal/possessed_object/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y)
+/mob/living/simple_animal/possessed_object/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect)
..()
animate_ghostly_presence(src, -1, 20, 1) // Restart the floating animation after the attack animation, as it will be cancelled.
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 2479f3c0674..d4f8e7c4c3d 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -144,8 +144,8 @@
/mob/living/simple_animal/updatehealth(reason = "none given")
..(reason)
- health = Clamp(health, 0, maxHealth)
- med_hud_set_status()
+ health = clamp(health, 0, maxHealth)
+ med_hud_set_health()
/mob/living/simple_animal/StartResting(updating = 1)
..()
@@ -166,12 +166,14 @@
/mob/living/simple_animal/update_stat(reason = "none given")
if(status_flags & GODMODE)
return
-
- ..(reason)
if(stat != DEAD)
- if(health < 1)
+ if(health <= 0)
death()
create_debug_log("died of damage, trigger reason: [reason]")
+ else
+ WakeUp()
+ create_debug_log("woke up, trigger reason: [reason]")
+ med_hud_set_status()
/mob/living/simple_animal/proc/handle_automated_action()
set waitfor = FALSE
@@ -613,3 +615,8 @@
if(pcollar && collar_type)
add_overlay("[collar_type]collar")
add_overlay("[collar_type]tag")
+
+/mob/living/simple_animal/Login()
+ ..()
+ walk(src, 0) // if mob is moving under ai control, then stop AI movement
+
diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm
index bd9d001f12f..3f978abbfbb 100644
--- a/code/modules/mob/living/simple_animal/slime/powers.dm
+++ b/code/modules/mob/living/simple_animal/slime/powers.dm
@@ -190,7 +190,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)
feedback_add_details("slime_babies_born", "slimebirth_[replacetext(M.colour," ","_")]")
var/mob/living/simple_animal/slime/new_slime = pick(babies)
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 91e6c502869..15f483bef76 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -17,6 +17,7 @@
response_harm = "stomps on"
emote_see = list("jiggles", "bounces in place")
speak_emote = list("blorbles")
+ bubble_icon = "slime"
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)
@@ -156,7 +157,7 @@
. += config.slime_delay
-/mob/living/simple_animal/slime/handle_hud_icons_health()
+/mob/living/simple_animal/slime/update_health_hud()
if(hud_used)
if(!client)
return
diff --git a/code/modules/mob/living/stat_states.dm b/code/modules/mob/living/stat_states.dm
index 926bdc5970d..eab88b5ec4d 100644
--- a/code/modules/mob/living/stat_states.dm
+++ b/code/modules/mob/living/stat_states.dm
@@ -51,7 +51,7 @@
log_game("[key_name(src)] came back to life at [atom_loc_line(get_turf(src))]")
stat = CONSCIOUS
GLOB.dead_mob_list -= src
- GLOB.living_mob_list += src
+ GLOB.alive_mob_list += src
if(mind)
GLOB.respawnable_list -= src
timeofdeath = null
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index b2871038155..7cd2b4414f7 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -125,10 +125,6 @@
var/stuttering = 0
var/weakened = 0
-/mob/living
- // Bitfields
- var/disabilities = 0
-
// RESTING
/mob/living/proc/StartResting(updating = 1)
@@ -467,16 +463,16 @@
// Blind
/mob/living/proc/BecomeBlind(updating = TRUE)
- var/val_change = !(disabilities & BLIND)
+ var/val_change = !(BLINDNESS in mutations)
. = val_change ? STATUS_UPDATE_BLIND : STATUS_UPDATE_NONE
- disabilities |= BLIND
+ mutations |= BLINDNESS
if(val_change && updating)
update_blind_effects()
/mob/living/proc/CureBlind(updating = TRUE)
- var/val_change = !!(disabilities & BLIND)
+ var/val_change = !!(BLINDNESS in mutations)
. = val_change ? STATUS_UPDATE_BLIND : STATUS_UPDATE_NONE
- disabilities &= ~BLIND
+ mutations -= BLINDNESS
if(val_change && updating)
CureIfHasDisability(GLOB.blindblock)
update_blind_effects()
@@ -484,52 +480,52 @@
// Coughing
/mob/living/proc/BecomeCoughing()
- disabilities |= COUGHING
+ mutations |= COUGHING
/mob/living/proc/CureCoughing()
- disabilities &= ~COUGHING
+ mutations -= COUGHING
CureIfHasDisability(GLOB.coughblock)
// Deaf
/mob/living/proc/BecomeDeaf()
- disabilities |= DEAF
+ mutations |= DEAF
/mob/living/proc/CureDeaf()
- disabilities &= ~DEAF
+ mutations -= DEAF
CureIfHasDisability(GLOB.deafblock)
// Epilepsy
/mob/living/proc/BecomeEpilepsy()
- disabilities |= EPILEPSY
+ mutations |= EPILEPSY
/mob/living/proc/CureEpilepsy()
- disabilities &= ~EPILEPSY
+ mutations -= EPILEPSY
CureIfHasDisability(GLOB.epilepsyblock)
// Mute
/mob/living/proc/BecomeMute()
- disabilities |= MUTE
+ mutations |= MUTE
/mob/living/proc/CureMute()
- disabilities &= ~MUTE
+ mutations -= MUTE
CureIfHasDisability(GLOB.muteblock)
// Nearsighted
/mob/living/proc/BecomeNearsighted(updating = TRUE)
- var/val_change = !(disabilities & NEARSIGHTED)
+ var/val_change = !(NEARSIGHTED in mutations)
. = val_change ? STATUS_UPDATE_NEARSIGHTED : STATUS_UPDATE_NONE
- disabilities |= NEARSIGHTED
+ mutations |= NEARSIGHTED
if(val_change && updating)
update_nearsighted_effects()
/mob/living/proc/CureNearsighted(updating = TRUE)
- var/val_change = !!(disabilities & NEARSIGHTED)
+ var/val_change = !!(NEARSIGHTED in mutations)
. = val_change ? STATUS_UPDATE_NEARSIGHTED : STATUS_UPDATE_NONE
- disabilities &= ~NEARSIGHTED
+ mutations -= NEARSIGHTED
if(val_change && updating)
CureIfHasDisability(GLOB.glassesblock)
update_nearsighted_effects()
@@ -537,19 +533,19 @@
// Nervous
/mob/living/proc/BecomeNervous()
- disabilities |= NERVOUS
+ mutations |= NERVOUS
/mob/living/proc/CureNervous()
- disabilities &= ~NERVOUS
+ mutations -= NERVOUS
CureIfHasDisability(GLOB.nervousblock)
// Tourettes
/mob/living/proc/BecomeTourettes()
- disabilities |= TOURETTES
+ mutations |= TOURETTES
/mob/living/proc/CureTourettes()
- disabilities &= ~TOURETTES
+ mutations -= TOURETTES
CureIfHasDisability(GLOB.twitchblock)
/mob/living/proc/CureIfHasDisability(block)
diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm
index d24301b0dd0..8ef178918b4 100644
--- a/code/modules/mob/living/update_status.dm
+++ b/code/modules/mob/living/update_status.dm
@@ -25,7 +25,7 @@
clear_alert("high")
/mob/living/update_nearsighted_effects()
- if(disabilities & NEARSIGHTED)
+ if(NEARSIGHTED in mutations)
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
else
clear_fullscreen("nearsighted")
@@ -41,17 +41,17 @@
// Whether the mob can hear things
/mob/living/can_hear()
- . = !(disabilities & DEAF)
+ . = !(DEAF in mutations)
// Whether the mob is able to see
// `information_only` is for stuff that's purely informational - like blindness overlays
// This flag exists because certain things like angel statues expect this to be false for dead people
/mob/living/has_vision(information_only = FALSE)
- return (information_only && stat == DEAD) || !(eye_blind || (disabilities & BLIND) || stat)
+ return (information_only && stat == DEAD) || !(eye_blind || (BLINDNESS in mutations) || stat)
// Whether the mob is capable of talking
/mob/living/can_speak()
- if(!(silent || (disabilities & MUTE)))
+ if(!(silent || (MUTE in mutations)))
if(is_muzzled())
var/obj/item/clothing/mask/muzzle/M = wear_mask
if(M.mute >= MUZZLE_MUTE_MUFFLE)
@@ -112,22 +112,6 @@
/mob/living/proc/update_stamina()
return
-/mob/living/update_stat(reason = "None given")
- if(status_flags & GODMODE)
- return
- if(stat != DEAD)
- if(health <= HEALTH_THRESHOLD_DEAD && check_death_method())
- death()
- create_debug_log("died of damage, trigger reason: [reason]")
- else if(paralysis || status_flags & FAKEDEATH)
- if(stat == CONSCIOUS)
- KnockOut()
- create_debug_log("fell unconscious, trigger reason: [reason]")
- else
- if(stat == UNCONSCIOUS)
- WakeUp()
- create_debug_log("woke up, trigger reason: [reason]")
-
/mob/living/vv_edit_var(var_name, var_value)
. = ..()
switch(var_name)
diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm
index 8bdb0d89332..91bf5f0ab9c 100644
--- a/code/modules/mob/logout.dm
+++ b/code/modules/mob/logout.dm
@@ -1,5 +1,6 @@
/mob/Logout()
SSnanoui.user_logout(src) // this is used to clean up (remove) this user's Nano UIs
+ SStgui.on_logout(src) // Cleanup any TGUIs the user has open
unset_machine()
GLOB.player_list -= src
log_access_out(src)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 6123c8429c5..3b86faeb7e6 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1,7 +1,7 @@
/mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game.
GLOB.mob_list -= src
GLOB.dead_mob_list -= src
- GLOB.living_mob_list -= src
+ GLOB.alive_mob_list -= src
focus = null
QDEL_NULL(hud_used)
if(mind && mind.current == src)
@@ -9,9 +9,6 @@
mobspellremove(src)
QDEL_LIST(viruses)
ghostize()
- for(var/mob/dead/observer/M in following_mobs)
- M.following = null
- following_mobs = null
QDEL_LIST_ASSOC_VAL(tkgrabbed_objects)
for(var/I in tkgrabbed_objects)
qdel(tkgrabbed_objects[I])
@@ -23,18 +20,18 @@
AA.viewers -= src
viewing_alternate_appearances = null
logs.Cut()
- ..()
- return QDEL_HINT_HARDDEL
+ LAssailant = null
+ return ..()
-/mob/Initialize()
+/mob/Initialize(mapload)
GLOB.mob_list += src
if(stat == DEAD)
GLOB.dead_mob_list += src
else
- GLOB.living_mob_list += src
+ GLOB.alive_mob_list += src
set_focus(src)
prepare_huds()
- ..()
+ . = ..()
/atom/proc/prepare_huds()
hud_list = list()
@@ -45,6 +42,7 @@
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/generate_name()
@@ -67,8 +65,8 @@
t+= "Oxygen: [environment.oxygen] \n"
t+= "Plasma : [environment.toxins] \n"
t+= "Carbon Dioxide: [environment.carbon_dioxide] \n"
- for(var/datum/gas/trace_gas in environment.trace_gases)
- to_chat(usr, "[trace_gas.type]: [trace_gas.moles] \n")
+ t+= "N2O: [environment.sleeping_agent] \n"
+ t+= "Agent B: [environment.agent_b] \n"
usr.show_message(t, 1)
@@ -129,14 +127,12 @@
// self_message (optional) is what the src mob hears.
// deaf_message (optional) is what deaf people will see.
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
-/mob/audible_message(var/message, var/deaf_message, var/hearing_distance, var/self_message)
+/mob/audible_message(message, deaf_message, hearing_distance)
var/range = 7
if(hearing_distance)
range = hearing_distance
var/msg = message
for(var/mob/M in get_mobs_in_view(range, src))
- if(self_message && M == src)
- msg = self_message
M.show_message(msg, 2, deaf_message, 1)
// based on say code
@@ -158,12 +154,12 @@
// message is the message output to anyone who can hear.
// deaf_message (optional) is what deaf people will see.
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
-/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance)
+/atom/proc/audible_message(message, deaf_message, hearing_distance)
var/range = 7
if(hearing_distance)
range = hearing_distance
for(var/mob/M in get_mobs_in_view(range, src))
- M.show_message( message, 2, deaf_message, 1)
+ M.show_message(message, 2, deaf_message, 1)
/mob/proc/findname(msg)
for(var/mob/M in GLOB.mob_list)
@@ -174,21 +170,6 @@
/mob/proc/movement_delay()
return 0
-/mob/proc/Life(seconds, times_fired)
- set waitfor = FALSE
- if(forced_look)
- if(!isnum(forced_look))
- var/atom/A = locateUID(forced_look)
- if(istype(A))
- var/view = client ? client.view : world.view
- if(get_dist(src, A) > view || !(src in viewers(view, A)))
- forced_look = null
- to_chat(src, "Your direction target has left your view, you are no longer facing anything.")
- return
- setDir()
-// handle_typing_indicator()
- return
-
//This proc is called whenever someone clicks an inventory ui slot.
/mob/proc/attack_ui(slot)
var/obj/item/W = get_active_hand()
@@ -204,10 +185,10 @@
src:update_hair()
src:update_fhair()
-/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1)
- if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob))
+/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1)
+ if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning))
return 1
- else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning, redraw_mob))
+ else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning))
return 1
return 0
@@ -216,8 +197,7 @@
//This is a SAFE proc. Use this instead of equip_to_slot()!
//set del_on_fail to have it delete W if it fails to equip
//set disable_warning to disable the 'you are unable to equip that' warning.
-//unset redraw_mob to prevent the mob from being redrawn at the end.
-/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1)
+/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, del_on_fail = 0, disable_warning = 0)
if(!istype(W)) return 0
if(!W.mob_can_equip(src, slot, disable_warning))
@@ -229,17 +209,17 @@
return 0
- equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail.
+ equip_to_slot(W, slot) //This proc should not ever fail.
return 1
//This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task.
//In most cases you will want to use equip_to_slot_if_possible()
-/mob/proc/equip_to_slot(obj/item/W as obj, slot)
+/mob/proc/equip_to_slot(obj/item/W, slot)
return
//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such.
/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot)
- return equip_to_slot_if_possible(W, slot, 1, 1, 0)
+ return equip_to_slot_if_possible(W, slot, TRUE, TRUE)
// Convinience proc. Collects crap that fails to equip either onto the mob's back, or drops it.
// Used in job equipping so shit doesn't pile up at the start loc.
@@ -290,7 +270,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
for(var/slot in GLOB.slot_equipment_priority)
if(istype(W,/obj/item/storage/) && slot == slot_head) // Storage items should be put on the belt before the head
continue
- if(equip_to_slot_if_possible(W, slot, 0, 1, 1)) //del_on_fail = 0; disable_warning = 0; redraw_mob = 1
+ if(equip_to_slot_if_possible(W, slot, FALSE, TRUE)) //del_on_fail = 0; disable_warning = 0
return 1
return 0
@@ -527,12 +507,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
update_pipe_vision()
/mob/dead/reset_perspective(atom/A)
- if(client)
- if(ismob(client.eye) && (client.eye != src))
- // Note to self: Use `client.eye` for ghost following in place
- // of periodic ghost updates
- var/mob/target = client.eye
- target.following_mobs -= src
. = ..()
if(.)
// Allows sharing HUDs with ghosts
@@ -778,7 +752,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
if(client.holder && (client.holder.rights & R_ADMIN))
is_admin = 1
- else if(stat != DEAD || istype(src, /mob/new_player))
+ else if(stat != DEAD || isnewplayer(src))
to_chat(usr, "You must be observing to use this!")
return
@@ -789,7 +763,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
var/list/namecounts = list()
var/list/creatures = list()
- for(var/obj/O in world) //EWWWWWWWWWWWWWWWWWWWWWWWW ~needs to be optimised
+ for(var/obj/O in GLOB.poi_list)
if(!O.loc)
continue
if(istype(O, /obj/item/disk/nuclear))
@@ -839,10 +813,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
if(client && mob_eye)
client.eye = mob_eye
- if(is_admin)
- client.adminobs = 1
- if(mob_eye == client.mob || client.eye == client.mob)
- client.adminobs = 0
/mob/verb/cancel_camera()
set name = "Cancel Camera View"
@@ -1092,7 +1062,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
if((usr in GLOB.respawnable_list) && (stat==2 || istype(usr,/mob/dead/observer)))
var/list/creatures = list("Mouse")
- for(var/mob/living/L in GLOB.living_mob_list)
+ for(var/mob/living/L in GLOB.alive_mob_list)
if(safe_respawn(L.type) && L.stat!=2)
if(!L.key)
creatures += L
@@ -1127,7 +1097,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
var/mob/living/simple_animal/mouse/host
var/obj/machinery/atmospherics/unary/vent_pump/vent_found
var/list/found_vents = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/v in world)
+ for(var/obj/machinery/atmospherics/unary/vent_pump/v in SSair.atmos_machinery)
if(!v.welded && v.z == src.z)
found_vents.Add(v)
if(found_vents.len)
@@ -1327,8 +1297,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
.["Add Organ"] = "?_src_=vars;addorgan=[UID()]"
.["Remove Organ"] = "?_src_=vars;remorgan=[UID()]"
- .["Fix NanoUI"] = "?_src_=vars;fix_nano=[UID()]"
-
.["Add Verb"] = "?_src_=vars;addverb=[UID()]"
.["Remove Verb"] = "?_src_=vars;remverb=[UID()]"
@@ -1385,6 +1353,12 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
+/mob/proc/set_sight(datum/vision_override/O)
+ QDEL_NULL(vision_type)
+ if(O) //in case of null
+ vision_type = new O
+ update_sight()
+
/mob/proc/sync_lighting_plane_alpha()
if(hud_used)
var/obj/screen/plane_master/lighting/L = hud_used.plane_masters["[LIGHTING_PLANE]"]
@@ -1412,3 +1386,29 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
///Force set the mob nutrition
/mob/proc/set_nutrition(change)
nutrition = max(0, change)
+
+/mob/clean_blood(clean_hands = TRUE, clean_mask = TRUE, clean_feet = TRUE)
+ . = ..()
+ if(bloody_hands && clean_hands)
+ bloody_hands = 0
+ update_inv_gloves()
+ if(l_hand)
+ if(l_hand.clean_blood())
+ update_inv_l_hand()
+ if(r_hand)
+ if(r_hand.clean_blood())
+ update_inv_r_hand()
+ if(back)
+ if(back.clean_blood())
+ update_inv_back()
+ if(wear_mask && clean_mask)
+ if(wear_mask.clean_blood())
+ update_inv_wear_mask()
+ if(clean_feet)
+ feet_blood_color = null
+ qdel(feet_blood_DNA)
+ bloody_feet = list(BLOOD_STATE_HUMAN = 0, BLOOD_STATE_XENO = 0, BLOOD_STATE_NOT_BLOODY = 0)
+ blood_state = BLOOD_STATE_NOT_BLOODY
+ update_inv_shoes()
+ update_icons() //apply the now updated overlays to the mob
+
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index ee514930c95..1477be47d89 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -31,8 +31,8 @@
var/use_me = 1 //Allows all mobs to use the me verb by default, will have to manually specify they cannot
var/damageoverlaytemp = 0
var/computer_id = null
- var/lastattacker = null
- var/lastattacked = null
+ var/lastattacker = null // real name of the person doing the attacking
+ var/lastattackerckey = null // their ckey
var/list/attack_log_old = list( )
var/list/debug_log = null
@@ -50,7 +50,6 @@
var/med_record = ""
var/sec_record = ""
var/gen_record = ""
- var/bhunger = 0 //Carbon
var/lying = 0
var/lying_prev = 0
var/lastpuke = 0
@@ -61,8 +60,7 @@
var/emote_type = 1 // Define emote default type, 1 for seen emotes, 2 for heard emotes
var/name_archive //For admin things like possession
- var/timeofdeath = 0.0//Living
-
+ var/timeofdeath = 0 //Living
var/bodytemperature = 310.055 //98.7 F
var/flying = 0
@@ -71,22 +69,22 @@
var/hunger_drain = HUNGER_FACTOR // how quickly the mob gets hungry; largely utilized by species.
var/overeatduration = 0 // How long this guy is overeating //Carbon
- var/intent = null//Living
+ var/intent = null //Living
var/shakecamera = 0
- var/a_intent = INTENT_HELP//Living
- var/m_intent = MOVE_INTENT_RUN//Living
+ var/a_intent = INTENT_HELP //Living
+ var/m_intent = MOVE_INTENT_RUN //Living
var/lastKnownIP = null
/// movable atoms buckled to this mob
- var/atom/movable/buckled = null//Living
+ var/atom/movable/buckled = null //Living
/// movable atom we are buckled to
var/atom/movable/buckling
- var/obj/item/l_hand = null//Living
- var/obj/item/r_hand = null//Living
- var/obj/item/back = null//Human/Monkey
- var/obj/item/tank/internal = null//Human/Monkey
- var/obj/item/storage/s_active = null//Carbon
- var/obj/item/clothing/mask/wear_mask = null//Carbon
+ var/obj/item/l_hand = null //Living
+ var/obj/item/r_hand = null //Living
+ var/obj/item/back = null //Human
+ var/obj/item/tank/internal = null //Human
+ var/obj/item/storage/s_active = null //Carbon
+ var/obj/item/clothing/mask/wear_mask = null //Carbon
var/datum/hud/hud_used = null
@@ -95,7 +93,6 @@
var/research_scanner = 0 //For research scanner equipped mobs. Enable to show research data when examining.
var/list/grabbed_by = list()
- var/list/requests = list()
var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
var/list/mapobjs = list()
@@ -103,9 +100,9 @@
var/emote_cd = 0 // Used to supress emote spamming. 1 if on CD, 2 if disabled by admin (manually set), else 0
- var/job = null//Living
+ var/job = null //Living
- var/datum/dna/dna = null//Carbon
+ var/datum/dna/dna = null //Carbon
var/radiation = 0 //Carbon
var/list/mutations = list() //Carbon -- Doohl
@@ -160,8 +157,6 @@
var/atom/movable/remote_control //Calls relaymove() to whatever it is
- var/remote_view = 0 // Set to 1 to prevent view resets on Life
-
var/obj/control_object //Used by admins to possess objects. All mobs should have this var
//Whether or not mobs can understand other mobtypes. These stay in /mob so that ghosts can hear everything.
@@ -181,8 +176,6 @@
var/turf/listed_turf = null //the current turf being examined in the stat panel
var/list/shouldnt_see = list() //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
- var/kills = 0
-
var/stance_damage = 0 //Whether this mob's ability to stand has been affected
var/list/active_genes = list()
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index f595f6b4839..37e116b4376 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -53,12 +53,11 @@
hud.master = src
//check if assailant is grabbed by victim as well
- if(assailant.grabbed_by)
- for(var/obj/item/grab/G in assailant.grabbed_by)
- if(G.assailant == affecting && G.affecting == assailant)
- G.dancing = 1
- G.adjust_position()
- dancing = 1
+ for(var/obj/item/grab/G in assailant.grabbed_by)
+ if(G.assailant == affecting && G.affecting == assailant)
+ G.dancing = 1
+ G.adjust_position()
+ dancing = 1
clean_grabbed_by(assailant, affecting)
adjust_position()
@@ -276,7 +275,7 @@
assailant.visible_message("[assailant] has reinforced [assailant.p_their()] grip on [affecting] (now neck)!")
state = GRAB_NECK
icon_state = "grabbed+1"
- assailant.setDir(get_dir(assailant, affecting))
+
add_attack_logs(assailant, affecting, "Neck grabbed", ATKLOG_ALL)
if(!iscarbon(assailant))
affecting.LAssailant = null
@@ -296,7 +295,7 @@
assailant.next_move = world.time + 10
if(!affecting.get_organ_slot("breathing_tube"))
affecting.AdjustLoseBreath(1)
- affecting.setDir(WEST)
+
adjust_position()
//This is used to make sure the victim hasn't managed to yackety sax away before using the grab.
@@ -409,7 +408,7 @@
add_attack_logs(attacker, affecting, "Devoured")
affecting.forceMove(user)
- attacker.stomach_contents.Add(affecting)
+ LAZYADD(attacker.stomach_contents, affecting)
qdel(src)
/obj/item/grab/proc/checkvalid(var/mob/attacker, var/mob/prey) //does all the checking for the attack proc to see if a mob can eat another with the grab
@@ -433,9 +432,10 @@
/obj/item/grab/Destroy()
if(affecting)
- affecting.pixel_x = 0
- affecting.pixel_y = 0 //used to be an animate, not quick enough for del'ing
- affecting.layer = initial(affecting.layer)
+ if(!affecting.buckled)
+ affecting.pixel_x = 0
+ affecting.pixel_y = 0 //used to be an animate, not quick enough for qdel'ing
+ affecting.layer = initial(affecting.layer)
affecting.grabbed_by -= src
affecting = null
if(assailant)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 1e0f31ac6fe..5fb5bcb06c8 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -12,14 +12,6 @@
return 1
return 0
-/mob/proc/isSynthetic()
- return 0
-
-/mob/living/carbon/human/isSynthetic()
- if(ismachine(src))
- return TRUE
- return FALSE
-
/mob/proc/get_screen_colour()
/mob/proc/update_client_colour(var/time = 10) //Update the mob's client.color with an animation the specified time in length.
@@ -467,7 +459,7 @@ GLOBAL_LIST_INIT(intents, list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM
name = realname
for(var/mob/M in GLOB.player_list)
- if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || check_rights(R_ADMIN|R_MOD,0,M)) && M.get_preference(CHAT_DEAD))
+ if(M.client && ((!isnewplayer(M) && M.stat == DEAD) || check_rights(R_ADMIN|R_MOD,0,M)) && M.get_preference(CHAT_DEAD))
var/follow
var/lname
if(subject)
@@ -521,11 +513,11 @@ GLOBAL_LIST_INIT(intents, list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM
alert_overlay.plane = FLOAT_PLANE
A.overlays += alert_overlay
-/mob/proc/switch_to_camera(var/obj/machinery/camera/C)
- if(!C.can_use() || stat || (get_dist(C, src) > 1 || machine != src || !has_vision() || !canmove))
- return 0
+/mob/proc/switch_to_camera(obj/machinery/camera/C)
+ if(!C.can_use() || incapacitated() || (get_dist(C, src) > 1 || machine != src || !has_vision()))
+ return FALSE
check_eye(src)
- return 1
+ return TRUE
/mob/proc/rename_character(oldname, newname)
if(!newname)
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 471ddc42557..4797c685fe1 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -26,25 +26,6 @@
else
to_chat(usr, "This mob type cannot throw items.")
-
-/client/verb/drop_item()
- set hidden = 1
- if(!isrobot(mob))
- mob.drop_item_v()
- return
-
-
-/* /client/Center()
- /* No 3D movement in 2D spessman game. dir 16 is Z Up
- if(isobj(mob.loc))
- var/obj/O = mob.loc
- if(mob.canmove)
- return O.relaymove(mob, 16)
- */
- return
- */
-
-
/client/proc/Move_object(direct)
if(mob && mob.control_object)
if(mob.control_object.density)
@@ -186,7 +167,7 @@
if(newdir)
direct = newdir
n = get_step(mob, direct)
-
+
. = mob.SelfMove(n, direct, delay)
mob.setDir(direct)
diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm
index c3ec68c9793..1e704ea3449 100644
--- a/code/modules/mob/mob_transformation_simple.dm
+++ b/code/modules/mob/mob_transformation_simple.dm
@@ -4,7 +4,7 @@
//Note that this proc does NOT do MMI related stuff!
/mob/proc/change_mob_type(var/new_type = null, var/turf/location = null, var/new_name = null as text, var/delete_old_mob = 0 as num, var/forcekey = 0)
- if(istype(src,/mob/new_player))
+ if(isnewplayer(src))
to_chat(usr, "cannot convert players who have not entered yet.")
return
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 69e27595a07..f53daba6626 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -12,8 +12,13 @@
stat = 2
canmove = 0
-/mob/new_player/New()
+/mob/new_player/Initialize(mapload)
+ SHOULD_CALL_PARENT(FALSE)
+ if(initialized)
+ stack_trace("Warning: [src]([type]) initialized multiple times!")
+ initialized = TRUE
GLOB.mob_list += src
+ return INITIALIZE_HINT_NORMAL
/mob/new_player/verb/new_player_panel()
set src = usr
@@ -205,6 +210,7 @@
if(!client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
observer.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
observer.key = key
+ QDEL_NULL(mind)
GLOB.respawnable_list += observer
qdel(src)
return 1
@@ -392,7 +398,7 @@
/mob/new_player/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message)
if(SSticker.current_state == GAME_STATE_PLAYING)
var/ailist[] = list()
- for(var/mob/living/silicon/ai/A in GLOB.living_mob_list)
+ for(var/mob/living/silicon/ai/A in GLOB.alive_mob_list)
ailist += A
if(ailist.len)
var/mob/living/silicon/ai/announcer = pick(ailist)
@@ -424,7 +430,7 @@
/mob/new_player/proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message)
if(SSticker.current_state == GAME_STATE_PLAYING)
var/ailist[] = list()
- for(var/mob/living/silicon/ai/A in GLOB.living_mob_list)
+ for(var/mob/living/silicon/ai/A in GLOB.alive_mob_list)
ailist += A
if(ailist.len)
var/mob/living/silicon/ai/announcer = pick(ailist)
diff --git a/code/modules/mob/new_player/poll.dm b/code/modules/mob/new_player/poll.dm
index f67c53c9941..2e109d36d34 100644
--- a/code/modules/mob/new_player/poll.dm
+++ b/code/modules/mob/new_player/poll.dm
@@ -90,9 +90,9 @@
if(adminonly)
question = "(Admin only poll) " + question
- var output = ""
+ var/output = ""
if(polltype == POLLTYPE_MULTI || polltype == POLLTYPE_OPTION)
- select_query = GLOB.dbcon.NewQuery("SELECT text, percentagecalc, (SELECT COUNT(optionid) FROM [format_table_name("poll_vote")] WHERE optionid = poll_option.id GROUP BY optionid) AS votecount FROM [format_table_name("poll_option")] WHERE pollid = [pollid]");
+ select_query = GLOB.dbcon.NewQuery("SELECT text, percentagecalc, (SELECT COUNT(optionid) FROM [format_table_name("poll_vote")] WHERE optionid = poll_option.id GROUP BY optionid) AS votecount FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
select_query.Execute()
var/list/options = list()
var/total_votes = 1
@@ -177,7 +177,7 @@
output += " |