diff --git a/code/controllers/Processes/mob.dm b/code/controllers/Processes/mob.dm index c1dd47236f1..8de5b1d6774 100644 --- a/code/controllers/Processes/mob.dm +++ b/code/controllers/Processes/mob.dm @@ -1,12 +1,16 @@ +var/global/datum/controller/process/mob/mob_master + /datum/controller/process/mob + var/current_cycle /datum/controller/process/mob/setup() name = "mob" schedule_interval = 20 // every 2 seconds start_delay = 16 - if(!mob_master) - mob_master = new - mob_master.Setup() + log_startup_progress("Mob ticker starting up.") + if(mob_master) + qdel(mob_master) //only one mob master + mob_master = src /datum/controller/process/mob/started() ..() @@ -29,17 +33,4 @@ else catchBadType(M) mob_list -= M - mob_master.process() - -var/global/datum/controller/mob_system/mob_master - -/datum/controller/mob_system - var/current_cycle - var/starttime - -/datum/controller/mob_system/proc/Setup() - log_startup_progress("Mob ticker starting up.") - starttime = world.timeofday - -/datum/controller/mob_system/proc/process() current_cycle++ \ No newline at end of file diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 96acbacb0e8..fe6a5da9fe2 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -347,6 +347,36 @@ datum/objective/hijack return 0 return 1 +/datum/objective/hijackclone + explanation_text = "Hijack the emergency shuttle by ensuring only you (or your copies) escape." + + check_completion() + if(!owner.current) + return 0 + if(!emergency_shuttle.returned()) + return 0 + + var/area/A = locate(/area/shuttle/escape/centcom) + + for(var/mob/living/player in player_list) //Make sure nobody else is onboard + if(player.mind && player.mind != owner) + if(player.stat != DEAD) + if(istype(player, /mob/living/silicon)) + continue + if(get_area(player) == A) + if(player.real_name != owner.current.real_name && !istype(get_turf(player.mind.current), /turf/simulated/shuttle/floor4)) + return 0 + + for(var/mob/living/player in player_list) //Make sure at least one of you is onboard + if(player.mind && player.mind != owner) + if(player.stat != DEAD) + if(istype(player, /mob/living/silicon)) + continue + if(get_area(player) == A) + if(player.real_name == owner.current.real_name && !istype(get_turf(player.mind.current), /turf/simulated/shuttle/floor4)) + return 1 + return 0 + datum/objective/block explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive." diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index ef0dddac0fa..3008d2db0c7 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -213,3 +213,387 @@ user << " You can see...everything!" visible_message("[user] stares into [src], their eyes glazing over.") user.ghostize(1) + +/////////////////////Multiverse Blade//////////////////// +var/global/list/multiverse = list() + +/obj/item/weapon/multisword + name = "multiverse sword" + desc = "A weapon capable of conquering the universe and beyond. Activate it to summon copies of yourself from others dimensions to fight by your side." + icon = 'icons/obj/weapons.dmi' + icon_state = "energy_katana" + item_state = "energy_katana" + hitsound = 'sound/weapons/bladeslice.ogg' + flags = CONDUCT + slot_flags = SLOT_BELT + force = 20 + throwforce = 10 + sharp = 1 + edge = 1 + w_class = 2 + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + var/faction = list("unassigned") + var/cooldown = 0 + var/cooldown_between_uses = 400 //time in deciseconds between uses--default of 40 seconds. + var/assigned = "unassigned" + var/evil = TRUE + var/probability_evil = 30 //what's the probability this sword will be evil when activated? + var/duplicate_self = 0 //Do we want the species randomized along with equipment should the user be duplicated in their entirety? + var/sword_type = /obj/item/weapon/multisword //type of sword to equip. + +/obj/item/weapon/multisword/New() + ..() + multiverse |= src + + +/obj/item/weapon/multisword/Destroy() + multiverse.Remove(src) + return ..() + +/obj/item/weapon/multisword/attack(mob/living/M as mob, mob/living/user as mob) //to prevent accidental friendly fire or out and out grief. + if(M.real_name == user.real_name) + user << "The [src] detects benevolent energies in your target and redirects your attack!" + return + ..() + +/obj/item/weapon/multisword/attack_self(mob/user) + if(user.mind.special_role == "apprentice") + user << "You know better than to touch your teacher's stuff." + return + if(cooldown < world.time) + var/faction_check = 0 + for(var/F in faction) + if(F in user.faction) + faction_check = 1 + break + if(faction_check == 0) + faction = list("[user.real_name]") + assigned = "[user.real_name]" + user.faction = list("[user.real_name]") + user << "You bind the sword to yourself. You can now use it to summon help." + if(!usr.mind.special_role) + if(prob(probability_evil)) + user << "With your new found power you could easily conquer the station!" + var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone + hijack_objective.owner = usr.mind + usr.mind.objectives += hijack_objective + hijack_objective.explanation_text = "Ensure only [usr.real_name] and their copies are on the shuttle!" + usr << "Objective #[1]: [hijack_objective.explanation_text]" + ticker.mode.traitors += usr.mind + usr.mind.special_role = "[usr.real_name] Prime" + evil = TRUE + else + user << "With your new found power you could easily defend the station!" + var/datum/objective/survive/new_objective = new /datum/objective/survive + new_objective.owner = usr.mind + new_objective.explanation_text = "Survive, and help defend the innocent from the mobs of multiverse clones." + usr << "Objective #[1]: [new_objective.explanation_text]" + usr.mind.objectives += new_objective + ticker.mode.traitors += usr.mind + usr.mind.special_role = "[usr.real_name] Prime" + evil = FALSE + else + var/list/candidates = get_candidates(BE_WIZARD) + if(candidates.len) + var/client/C = pick(candidates) + spawn_copy(C, get_turf(user.loc), user) + user << "The sword flashes, and you find yourself face to face with...you!" + cooldown = world.time + cooldown_between_uses + for(var/obj/item/weapon/multisword/M in multiverse) + if(M.assigned == assigned) + M.cooldown = cooldown + + else + user << "You fail to summon any copies of yourself. Perhaps you should try again in a bit." + else + user << "[src] is recharging! Keep in mind it shares a cooldown with the swords wielded by your copies." + + +/obj/item/weapon/multisword/proc/spawn_copy(var/client/C, var/turf/T) + var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) + if(duplicate_self) + usr.client.prefs.copy_to(M) + else + C.prefs.copy_to(M) + M.key = C.key + M.mind.name = usr.real_name + M << "You are an alternate version of [usr.real_name] from another universe! Help them accomplish their goals at all costs." + M.faction = list("[usr.real_name]") + if(duplicate_self) + M.set_species(usr.get_species()) //duplicate the sword user's species. + else + if(prob(50)) + var/list/all_species = list("Human","Unathi","Skrell","Tajaran","Kidan","Golem","Diona","Machine","Slime People","Grey","Vulpkanin") + M.set_species(pick(all_species)) + M.real_name = usr.real_name //this is clear down here in case the user happens to become a golem; that way they have the proper name. + M.name = usr.real_name + if(duplicate_self) + M.dna = usr.dna.Clone() + M.UpdateAppearance() + domutcheck(M, null) + M.update_body() + M.update_hair() + + equip_copy(M) + + if(evil) + var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone + hijack_objective.owner = M.mind + M.mind.objectives += hijack_objective + hijack_objective.explanation_text = "Ensure only [usr.real_name] and their copies are on the shuttle!" + M << "Objective #[1]: [hijack_objective.explanation_text]" + M.mind.special_role = "multiverse traveller" + log_game("[M.key] was made a multiverse traveller with the objective to help [usr.real_name] hijack.") + else + var/datum/objective/protect/new_objective = new /datum/objective/protect + new_objective.owner = M.mind + new_objective.target = usr.mind + new_objective.explanation_text = "Protect [usr.real_name], your copy, and help them defend the innocent from the mobs of multiverse clones." + M.mind.objectives += new_objective + M << "Objective #[1]: [new_objective.explanation_text]" + M.mind.special_role = "multiverse traveller" + log_game("[M.key] was made a multiverse traveller with the objective to help [usr.real_name] protect the station.") + +/obj/item/weapon/multisword/proc/equip_copy(var/mob/living/carbon/human/M) + + var/obj/item/weapon/multisword/sword = new sword_type + sword.assigned = assigned + sword.faction = list("[assigned]") + sword.evil = evil + + if(duplicate_self) + //Duplicates the user's current equipent + var/mob/living/carbon/human/H = usr + + var/obj/head = H.get_item_by_slot(slot_head) + if(head) + M.equip_to_slot_or_del(new head.type(M), slot_head) + + var/obj/mask = H.get_item_by_slot(slot_wear_mask) + if(mask) + M.equip_to_slot_or_del(new mask.type(M), slot_wear_mask) + + var/obj/glasses = H.get_item_by_slot(slot_glasses) + if(glasses) + M.equip_to_slot_or_del(new glasses.type(M), slot_glasses) + + var/obj/left_ear = H.get_item_by_slot(slot_l_ear) + if(left_ear) + M.equip_to_slot_or_del(new left_ear.type(M), slot_l_ear) + + var/obj/right_ear = H.get_item_by_slot(slot_r_ear) + if(right_ear) + M.equip_to_slot_or_del(new right_ear.type(M), slot_r_ear) + + var/obj/uniform = H.get_item_by_slot(slot_w_uniform) + if(uniform) + M.equip_to_slot_or_del(new uniform.type(M), slot_w_uniform) + + var/obj/suit = H.get_item_by_slot(slot_wear_suit) + if(suit) + M.equip_to_slot_or_del(new suit.type(M), slot_wear_suit) + + var/obj/gloves = H.get_item_by_slot(slot_gloves) + if(gloves) + M.equip_to_slot_or_del(new gloves.type(M), slot_gloves) + + var/obj/shoes = H.get_item_by_slot(slot_shoes) + if(shoes) + M.equip_to_slot_or_del(new shoes.type(M), slot_shoes) + + var/obj/belt = H.get_item_by_slot(slot_belt) + if(belt) + M.equip_to_slot_or_del(new belt.type(M), slot_belt) + + var/obj/pda = H.get_item_by_slot(slot_wear_pda) + if(pda) + M.equip_to_slot_or_del(new pda.type(M), slot_wear_pda) + + var/obj/back = H.get_item_by_slot(slot_back) + if(back) + M.equip_to_slot_or_del(new back.type(M), slot_back) + + var/obj/suit_storage = H.get_item_by_slot(slot_s_store) + if(suit_storage) + M.equip_to_slot_or_del(new suit_storage.type(M), slot_s_store) + + var/obj/left_pocket = H.get_item_by_slot(slot_l_store) + if(left_pocket) + M.equip_to_slot_or_del(new left_pocket.type(M), slot_l_store) + + var/obj/right_pocket = H.get_item_by_slot(slot_r_store) + if(right_pocket) + M.equip_to_slot_or_del(new right_pocket.type(M), slot_r_store) + + M.equip_to_slot_or_del(sword, slot_r_hand) //Don't duplicate what's equipped to hands, or else duplicate swords could be generated...or weird cases of factionless swords. + else + if(M.get_species() == "Tajaran" || M.get_species() == "Unathi") + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes) //If they can't wear shoes, give them a pair of sandals. + + var/randomize = pick("mobster","roman","wizard","cyborg","syndicate","assistant", "animu", "cultist", "highlander", "clown", "killer", "pirate", "soviet", "officer", "gladiator") + + switch(randomize) + if("mobster") + M.equip_to_slot_or_del(new /obj/item/clothing/head/fedora(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses) + M.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket/really_black(M), slot_w_uniform) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("roman") + var/hat = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionaire) + M.equip_to_slot_or_del(new hat(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/under/roman(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/weapon/shield/riot/roman(M), slot_l_hand) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("wizard") + M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red(M), slot_head) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("cyborg") + if(M.get_species() != "Machine") + for(var/obj/item/organ/O in M.organs) + O.robotize() + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("syndicate") + M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/swat(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(M),slot_wear_mask) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("assistant") + M.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("animu") + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/head/kitty(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/under/schoolgirl(M), slot_w_uniform) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("cultist") + M.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("highlander") + M.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/head/beret(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("clown") + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/clown(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(M), slot_wear_mask) + M.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(M), slot_l_store) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("killer") + M.equip_to_slot_or_del(new /obj/item/clothing/under/overalls(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/latex(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(M), slot_wear_mask) + M.equip_to_slot_or_del(new /obj/item/clothing/head/welding(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/weapon/kitchen/utensil/knife(M), slot_l_store) + M.equip_to_slot_or_del(new /obj/item/weapon/scalpel(M), slot_r_store) + M.equip_to_slot_or_del(sword, slot_r_hand) + for(var/obj/item/carried_item in M.contents) + if(!istype(carried_item, /obj/item/weapon/implant)) + carried_item.add_blood(M) + + if("pirate") + M.equip_to_slot_or_del(new /obj/item/clothing/under/pirate(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/head/bandana(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), slot_glasses) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("soviet") + M.equip_to_slot_or_del(new /obj/item/clothing/head/hgpiratecap(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/hgpirate(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("officer") + M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/havana(M), slot_wear_mask) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/jacket/miljacket(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), slot_glasses) + M.equip_to_slot_or_del(sword, slot_r_hand) + + if("gladiator") + M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/gladiator(M), slot_head) + M.equip_to_slot_or_del(new /obj/item/clothing/under/gladiator(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes) + M.equip_to_slot_or_del(sword, slot_r_hand) + + + else + return + + var/obj/item/weapon/card/id/W = new /obj/item/weapon/card/id + if(duplicate_self) + var/duplicated_access = usr.get_item_by_slot(slot_wear_id) + if(duplicated_access && istype(duplicated_access, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/duplicated_id = duplicated_access + W.access = duplicated_id.access + W.icon_state = duplicated_id.icon_state + else + W.access += access_maint_tunnels + W.icon_state = "centcom" + else + W.access += access_maint_tunnels + W.icon_state = "centcom" + W.assignment = "Multiverse Traveller" + W.registered_name = M.real_name + W.update_label(M.real_name) + W.SetOwnerInfo(M) + M.equip_to_slot_or_del(W, slot_wear_id) + + M.update_icons() + +/obj/item/weapon/multisword/pure_evil + probability_evil = 100 + +/obj/item/weapon/multisword/pike //If We are to be used and spent, let it be for a noble purpose. + name = "phantom pike" + desc = "A fishing pike that appears to be imbued with a peculiar energy." + icon_state = "harpoon" + item_state = "harpoon" + cooldown_between_uses = 200 //Half the time + probability_evil = 100 + duplicate_self = 1 + sword_type = /obj/item/weapon/multisword/pike diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 2459e1cc121..0035170d4dd 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -7,6 +7,8 @@ icon = 'icons/obj/Cryogenic2.dmi' icon_state = "console" var/obj/machinery/sleeper/connected = null + var/ui_title = "Sleeper" + anchored = 1 //About time someone fixed this. density = 1 var/orient = "LEFT" @@ -39,10 +41,6 @@ /obj/machinery/sleep_console/RefreshParts() /obj/machinery/sleep_console/process() - if(stat & (NOPOWER|BROKEN)) - return - src.updateUsrDialog() - return /obj/machinery/sleep_console/ex_act(severity) switch(severity) @@ -116,88 +114,137 @@ findsleeper() if (src.connected) - var/mob/living/occupant = src.connected.occupant - var/dat = "Occupant Statistics:
" - if (occupant) - var/t1 - switch(occupant.stat) - if(0) - t1 = "Conscious" - if(1) - t1 = "Unconscious" - if(2) - t1 = "*dead*" - else - dat += text("[]\tHealth %: [] ([])
", (occupant.health > 50 ? "" : ""), occupant.health, t1) - if(iscarbon(occupant)) - var/mob/living/carbon/C = occupant - dat += text("[]\t-Pulse, bpm: []
", (C.pulse == PULSE_NONE || C.pulse == PULSE_THREADY ? "" : ""), C.get_pulse(GETPULSE_TOOL)) - dat += text("[]\t-Brute Damage %: []
", (occupant.getBruteLoss() < 60 ? "" : ""), occupant.getBruteLoss()) - dat += text("[]\t-Respiratory Damage %: []
", (occupant.getOxyLoss() < 60 ? "" : ""), occupant.getOxyLoss()) - dat += text("[]\t-Toxin Content %: []
", (occupant.getToxLoss() < 60 ? "" : ""), occupant.getToxLoss()) - dat += text("[]\t-Burn Severity %: []
", (occupant.getFireLoss() < 60 ? "" : ""), occupant.getFireLoss()) - dat += text("
Paralysis Summary %: [] ([] seconds left!)
", occupant.paralysis, round(occupant.paralysis / 4)) - if(occupant.reagents) - for(var/chemical in connected.injection_chems) - var/datum/reagent/C = chemical_reagents_list[chemical] - dat += "[C.name]: [occupant.reagents.get_reagent_amount(chemical)] units
" - dat += "Refresh Meter Readings
" - if(src.connected.beaker) - dat += "
Remove Beaker
" - if(src.connected.filtering) - dat += "Stop Dialysis
" - dat += text("Output Beaker has [] units of free space remaining

", src.connected.beaker.reagents.maximum_volume - src.connected.beaker.reagents.total_volume) - else - dat += "
Start Dialysis
" - dat += text("Output Beaker has [] units of free space remaining

", src.connected.beaker.reagents.maximum_volume - src.connected.beaker.reagents.total_volume) - else - dat += "
No Dialysis Output Beaker is present.

" - for(var/chemical in connected.injection_chems) - var/datum/reagent/C = chemical_reagents_list[chemical] - dat += "Inject [C.name]: " - for(var/amount in connected.amounts) - dat += "[amount] units
" - dat += "
Eject Patient" - else - dat += "The sleeper is empty." - dat += text("

Close", user) - user << browse(dat, "window=sleeper;size=400x500") - onclose(user, "sleeper") - return + ui_interact(user) + +/obj/machinery/sleep_console/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + var/mob/living/carbon/human/occupant = connected.occupant + data["hasOccupant"] = occupant ? 1 : 0 + var/occupantData[0] + var/crisis = 0 + if (occupant) + occupantData["name"] = occupant.name + occupantData["stat"] = occupant.stat + occupantData["health"] = occupant.health + occupantData["maxHealth"] = occupant.maxHealth + occupantData["minHealth"] = config.health_threshold_dead + occupantData["bruteLoss"] = occupant.getBruteLoss() + occupantData["oxyLoss"] = occupant.getOxyLoss() + occupantData["toxLoss"] = occupant.getToxLoss() + occupantData["fireLoss"] = occupant.getFireLoss() + occupantData["paralysis"] = occupant.paralysis + occupantData["hasBlood"] = 0 + occupantData["bodyTemperature"] = occupant.bodytemperature + occupantData["maxTemp"] = 1000 // If you get a burning vox armalis into the sleeper, congratulations + // Because we can put simple_animals in here, we need to do something tricky to get things working nice + occupantData["temperatureSuitability"] = 0 // 0 is the baseline + if (ishuman(occupant) && occupant.species) + // I wanna do something where the bar gets bluer as the temperature gets lower + // For now, I'll just use the standard format for the temperature status + var/datum/species/sp = occupant.species + if (occupant.bodytemperature < sp.cold_level_3) + occupantData["temperatureSuitability"] = -3 + else if (occupant.bodytemperature < sp.cold_level_2) + occupantData["temperatureSuitability"] = -2 + else if (occupant.bodytemperature < sp.cold_level_1) + occupantData["temperatureSuitability"] = -1 + else if (occupant.bodytemperature > sp.heat_level_3) + occupantData["temperatureSuitability"] = 3 + else if (occupant.bodytemperature > sp.heat_level_2) + occupantData["temperatureSuitability"] = 2 + else if (occupant.bodytemperature > sp.heat_level_1) + occupantData["temperatureSuitability"] = 1 + else if (istype(occupant, /mob/living/simple_animal)) + var/mob/living/simple_animal/silly = occupant + if (silly.bodytemperature < silly.minbodytemp) + occupantData["temperatureSuitability"] = -3 + else if (silly.bodytemperature > silly.maxbodytemp) + occupantData["temperatureSuitability"] = 3 + // Blast you, imperial measurement system + occupantData["btCelsius"] = occupant.bodytemperature - T0C + occupantData["btFaren"] = ((occupant.bodytemperature - T0C) * (9.0/5.0))+ 32 + + + crisis = (occupant.health < connected.min_health) + // I'm not sure WHY you'd want to put a simple_animal in a sleeper, but precedent is precedent + // Runtime is aptly named, isn't she? + if (ishuman(occupant) && occupant.vessel && !(occupant.species && occupant.species.flags & NO_BLOOD)) + occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL) + occupantData["hasBlood"] = 1 + occupantData["bloodLevel"] = round(occupant.vessel.get_reagent_amount("blood")) + occupantData["bloodMax"] = occupant.max_blood + occupantData["bloodPercent"] = round(100*(occupant.vessel.get_reagent_amount("blood")/occupant.max_blood), 0.01) + + data["occupant"] = occupantData + data["maxchem"] = connected.max_chem + data["minhealth"] = connected.min_health + data["dialysis"] = connected.filtering + if (connected.beaker) + data["isBeakerLoaded"] = 1 + data["beakerFreeSpace"] = round(connected.beaker.reagents.maximum_volume - connected.beaker.reagents.total_volume) + + var/chemicals[0] + for (var/re in connected.injection_chems) + var/datum/reagent/temp = chemical_reagents_list[re] + if(temp) + var/reagent_amount = 0 + var/pretty_amount + var/injectable = occupant ? 1 : 0 + var/overdosing = 0 + var/caution = 0 // To make things clear that you're coming close to an overdose + if (crisis && !(temp.id in connected.emergency_chems)) + injectable = 0 + + if (occupant && occupant.reagents) + reagent_amount = occupant.reagents.get_reagent_amount(temp.id) + // If they're mashing the highest concentration, they get one warning + if (temp.overdose_threshold && reagent_amount + 10 > temp.overdose_threshold) + caution = 1 + if (temp.id in occupant.reagents.overdose_list()) + overdosing = 1 + + // Because I don't know how to do this on the nano side + pretty_amount = round(reagent_amount, 0.05) + + chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("chemical" = temp.id), "occ_amount" = reagent_amount, "pretty_amount" = pretty_amount, "injectable" = injectable, "overdosing" = overdosing, "od_warning" = caution))) + data["chemicals"] = chemicals + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "sleeper.tmpl", ui_title, 550, 655) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) /obj/machinery/sleep_console/Topic(href, href_list) + if(!connected | usr == connected.occupant) + return 0 + if(..()) return 1 if(panel_open) usr << "Close the maintenance panel first." - return 1 + return 0 if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai))) - usr.set_machine(src) if (href_list["chemical"]) if (src.connected) if (src.connected.occupant) if (src.connected.occupant.stat == DEAD) - usr << "\red \b This person has no life for to preserve anymore. Take them to a department capable of reanimating them." - else if(src.connected.occupant.health > src.connected.min_health || href_list["chemical"] == "epinephrine") + usr << "This person has no life for to preserve anymore. Take them to a department capable of reanimating them." + else if(src.connected.occupant.health > src.connected.min_health || (href_list["chemical"] in connected.emergency_chems)) src.connected.inject_chemical(usr,href_list["chemical"],text2num(href_list["amount"])) else - usr << "\red \b This person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!" - src.updateUsrDialog() - if (href_list["refresh"]) - src.updateUsrDialog() + usr << "This person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!" if (href_list["removebeaker"]) src.connected.remove_beaker() - src.updateUsrDialog() if (href_list["togglefilter"]) src.connected.toggle_filter() - src.updateUsrDialog() if (href_list["ejectify"]) src.connected.eject() - src.updateUsrDialog() src.add_fingerprint(usr) - return + return 1 ///////////////////////////////////////// // THE SLEEPER ITSELF @@ -216,24 +263,25 @@ list("epinephrine", "ether", "salbutamol", "styptic_powder", "oculine"), list("epinephrine", "ether", "salbutamol", "styptic_powder", "oculine", "charcoal", "mutadone", "mannitol"), list("epinephrine", "ether", "salbutamol", "styptic_powder", "oculine", "charcoal", "mutadone", "mannitol", "pen_acid", "omnizine")) + var/emergency_chems = list("epinephrine") // Desnowflaking var/amounts = list(5, 10) var/obj/item/weapon/reagent_containers/glass/beaker = null var/filtering = 0 - var/efficiency + var/max_chem var/initial_bin_rating = 1 - var/min_health = 25 + var/min_health = -25 var/injection_chems = list() idle_power_usage = 1250 active_power_usage = 2500 light_color = LIGHT_COLOR_CYAN - power_change() - ..() - if(!(stat & (BROKEN|NOPOWER))) - set_light(2) - else - set_light(0) +/obj/machinery/sleeper/power_change() + ..() + if(!(stat & (BROKEN|NOPOWER))) + set_light(2) + else + set_light(0) /obj/machinery/sleeper/New() ..() @@ -271,16 +319,20 @@ I += M.rating injection_chems = possible_chems[I] - efficiency = E + max_chem = E * 20 min_health = -E * 25 /obj/machinery/sleeper/process() if(filtering > 0) if(beaker) + // To prevent runtimes from drawing blood from runtime, and to prevent getting IPC blood. + if(!istype(occupant) || !occupant.dna || (occupant.species && occupant.species.flags & NO_BLOOD)) + filtering = 0 + return + if(beaker.reagents.total_volume < beaker.reagents.maximum_volume) src.occupant.vessel.trans_to(beaker, 1) for(var/datum/reagent/x in src.occupant.reagents.reagent_list) - // world << "FILTERING CHEMS" src.occupant.reagents.trans_to(beaker, 3) src.occupant.vessel.trans_to(beaker, 1) src.updateDialog() @@ -306,11 +358,10 @@ beaker = G G.forceMove(src) user.visible_message("[user] adds \a [G] to \the [src]!", "You add \a [G] to \the [src]!") - src.updateUsrDialog() return else - user << "\red The sleeper has a beaker already." + user << "The sleeper has a beaker already." return if (istype(G, /obj/item/weapon/screwdriver)) @@ -342,12 +393,12 @@ if(istype(G, /obj/item/weapon/grab)) if(panel_open) - user << "\blue Close the maintenance panel first." + user << "Close the maintenance panel first." return if(!ismob(G:affecting)) return if(src.occupant) - user << "\blue The sleeper is already occupied!" + user << "The sleeper is already occupied!" return for(var/mob/living/carbon/slime/M in range(1,G:affecting)) if(M.Victim == G:affecting) @@ -358,7 +409,7 @@ if(do_after(user, 20, target = G:affecting)) if(src.occupant) - user << "\blue The sleeper is already occupied!" + user << "The sleeper is already occupied!" return if(!G || !G:affecting) return var/mob/M = G:affecting @@ -368,7 +419,7 @@ M.forceMove(src) src.occupant = M src.icon_state = "sleeper" - M << "\blue You feel cool air surround you. You go numb as your senses turn inward." + M << "You feel cool air surround you. You go numb as your senses turn inward." src.add_fingerprint(user) qdel(G) @@ -412,6 +463,8 @@ go_out() ..(severity) +// ??? +// This looks cool, although mildly broken, should it be included again? /obj/machinery/sleeper/alter_health(mob/living/M as mob) if (M.health > 0) if (M.getOxyLoss() >= 10) @@ -447,11 +500,14 @@ return /obj/machinery/sleeper/proc/inject_chemical(mob/living/user as mob, chemical, amount) + if (!(chemical in injection_chems)) + user << "The sleeper does not offer that chemical!" + return + if(src.occupant) if(src.occupant.reagents) - if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= 20 * efficiency) + if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= max_chem) src.occupant.reagents.add_reagent(chemical, amount) - user << "Occupant now has [src.occupant.reagents.get_reagent_amount(chemical)] units of [chemical] in his/her bloodstream." return else user << "You can not inject any more of this chemical." @@ -463,39 +519,9 @@ user << "There's no occupant in the sleeper!" return - -/obj/machinery/sleeper/proc/check(mob/living/user as mob) - if(src.occupant) - user << text("\blue Occupant ([]) Statistics:", src.occupant) - var/t1 - switch(src.occupant.stat) - if(0.0) - t1 = "Conscious" - if(1.0) - t1 = "Unconscious" - if(2.0) - t1 = "*dead*" - else - user << text("[]\t Health %: [] ([])", (src.occupant.health > 50 ? "\blue " : "\red "), src.occupant.health, t1) - user << text("[]\t -Core Temperature: []°C ([]°F)

", (src.occupant.bodytemperature > 50 ? "" : ""), src.occupant.bodytemperature-T0C, src.occupant.bodytemperature*1.8-459.67) - user << text("[]\t -Brute Damage %: []", (src.occupant.getBruteLoss() < 60 ? "\blue " : "\red "), src.occupant.getBruteLoss()) - user << text("[]\t -Respiratory Damage %: []", (src.occupant.getOxyLoss() < 60 ? "\blue " : "\red "), src.occupant.getOxyLoss()) - user << text("[]\t -Toxin Content %: []", (src.occupant.getToxLoss() < 60 ? "\blue " : "\red "), src.occupant.getToxLoss()) - user << text("[]\t -Burn Severity %: []", (src.occupant.getFireLoss() < 60 ? "\blue " : "\red "), src.occupant.getFireLoss()) - user << "\blue Expected time till occupant can safely awake: (note: If health is below 20% these times are inaccurate)" - user << text("\blue \t [] second\s (if around 1 or 2 the sleeper is keeping them asleep.)", src.occupant.paralysis / 5) - if(src.beaker) - user << text("\blue \t Dialysis Output Beaker has [] of free space remaining.", src.beaker.reagents.maximum_volume - src.beaker.reagents.total_volume) - else - user << "\blue No Dialysis Output Beaker loaded." - else - user << "\blue There is no one inside!" - return - - /obj/machinery/sleeper/verb/eject() set name = "Eject Sleeper" - set category = null + set category = "Object" set src in oview(1) if(usr.stat != 0) return @@ -506,7 +532,7 @@ /obj/machinery/sleeper/verb/remove_beaker() set name = "Remove Beaker" - set category = null + set category = "Object" set src in oview(1) if(usr.stat != 0) return @@ -520,7 +546,7 @@ /obj/machinery/sleeper/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) if(O.loc == user) //no you can't pull things out of your ass return - if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis || user.resting) //are you cuffed, dying, lying, stunned or other + if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other return if(get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source return @@ -535,10 +561,10 @@ if(!istype(user.loc, /turf) || !istype(O.loc, /turf)) // are you in a container/closet/pod/etc? return if(panel_open) - user << "\blue Close the maintenance panel first." + user << "Close the maintenance panel first." return if(occupant) - user << "\blue The sleeper is already occupied!" + user << "The sleeper is already occupied!" return /* if(isrobot(user)) if(!istype(user:module, /obj/item/weapon/robot_module/medical)) @@ -548,7 +574,7 @@ if(!istype(L) || L.buckled) return if(L.abiotic()) - user << "\blue Subject cannot have abiotic items on." + user << "Subject cannot have abiotic items on." return for(var/mob/living/carbon/slime/M in range(1,L)) if(M.Victim == L) @@ -561,7 +587,7 @@ if(do_after(user, 20, target = L)) if(src.occupant) - user << "\blue The sleeper is already occupied!" + user << ">The sleeper is already occupied!" return if(!L) return @@ -571,7 +597,7 @@ L.forceMove(src) src.occupant = L src.icon_state = "sleeper" - L << "\blue You feel cool air surround you. You go numb as your senses turn inward." + L << "You feel cool air surround you. You go numb as your senses turn inward." src.add_fingerprint(user) if(user.pulling == L) user.pulling = null @@ -583,15 +609,15 @@ /obj/machinery/sleeper/verb/move_inside() set name = "Enter Sleeper" - set category = null + set category = "Object" set src in oview(1) if(usr.stat != 0 || !(ishuman(usr))) return if(src.occupant) - usr << "\blue The sleeper is already occupied!" + usr << "The sleeper is already occupied!" return if (panel_open) - usr << "\blue Close the maintenance panel first." + usr << "Close the maintenance panel first." return if(usr.restrained() || usr.stat || usr.weakened || usr.stunned || usr.paralysis || usr.resting) //are you cuffed, dying, lying, stunned or other return @@ -602,7 +628,7 @@ visible_message("[usr] starts climbing into the sleeper.") if(do_after(usr, 20, target = usr)) if(src.occupant) - usr << "\blue The sleeper is already occupied!" + usr << "The sleeper is already occupied!" return usr.stop_pulling() usr.client.perspective = EYE_PERSPECTIVE diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 1d6e07b04c6..9662358a32f 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -12,12 +12,12 @@ light_color = "#00FF00" - power_change() - ..() - if(!(stat & (BROKEN|NOPOWER))) - set_light(2) - else - set_light(0) +/obj/machinery/bodyscanner/power_change() + ..() + if(!(stat & (BROKEN|NOPOWER))) + set_light(2) + else + set_light(0) /obj/machinery/bodyscanner/New() ..() @@ -66,130 +66,85 @@ default_deconstruction_crowbar(G) if(istype(G, /obj/item/weapon/grab)) + var/obj/item/weapon/grab/TYPECAST_YOUR_SHIT = G if(panel_open) - user << "\blue Close the maintenance panel first." + user << "Close the maintenance panel first." return - if(!ismob(G:affecting)) + if(!ismob(TYPECAST_YOUR_SHIT.affecting)) return - if (src.occupant) - user << "\blue The scanner is already occupied!" + if(occupant) + user << "The scanner is already occupied!" return - for(var/mob/living/carbon/slime/M in range(1,G:affecting)) - if(M.Victim == G:affecting) - usr << "[G:affecting.name] will not fit into the sleeper because they have a slime latched onto their head." + for(var/mob/living/carbon/slime/M in range(1, TYPECAST_YOUR_SHIT.affecting)) + if(M.Victim == TYPECAST_YOUR_SHIT.affecting) + user << "[TYPECAST_YOUR_SHIT.affecting.name] has a fucking slime attached to them, deal with that first." return - var/mob/M = G:affecting - if (M.abiotic()) - user << "\blue Subject cannot have abiotic items on." + var/mob/M = TYPECAST_YOUR_SHIT.affecting + if(M.abiotic()) + user << "Subject cannot have abiotic items on." return - if (M.client) + /*if(M.client) M.client.perspective = EYE_PERSPECTIVE - M.client.eye = src - M.loc = src - src.occupant = M - src.icon_state = "body_scanner_1" - src.add_fingerprint(user) - //G = null + M.client.eye = src*///THIS IS FUCKING POINTLESS BECAUSE OF ON-LIFE() FUCKING RESET_VIEW() AHHHHHHHHHHGGGGGGGGGG + M.forceMove(src) + occupant = M + icon_state = "body_scanner_1" + add_fingerprint(user) qdel(G) - return -/obj/machinery/bodyscanner/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) + +/obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/O, mob/user as mob) if(!istype(O)) - return - if(O.loc == user) //no you can't pull things out of your ass - return - if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis || user.resting) //are you cuffed, dying, lying, stunned or other - return - if(O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source - return - if(!ismob(O)) //humans only - return - if(istype(O, /mob/living/simple_animal) || istype(O, /mob/living/silicon)) //animals and robutts dont fit - return - if(!ishuman(user) && !isrobot(user)) //No ghosts or mice putting people into the sleeper - return - if(user.loc==null) // just in case someone manages to get a closet into the blue light dimension, as unlikely as that seems - return - if(!istype(user.loc, /turf) || !istype(O.loc, /turf)) // are you in a container/closet/pod/etc? - return + return 0 //not a mob + if(user.incapacitated()) + return 0 //user shouldn't be doing things + if(O.anchored) + return 0 //mob is anchored??? + if(get_dist(user, src) > 1 || get_dist(user, O) > 1) + return 0 //doesn't use adjacent() to allow for non-cardinal (fuck my life) + if(!ishuman(user) && !isrobot(user)) + return 0 //not a borg or human if(panel_open) - user << "\blue Close the maintenance panel first." - return + user << "Close the maintenance panel first." + return 0 //panel open if(occupant) - user << "\blue The body scanner is already occupied!" - return - var/mob/living/L = O - if(!istype(L) || L.buckled) - return - if(L.abiotic()) - user << "\blue Subject cannot have abiotic items on." - return - for(var/mob/living/carbon/slime/M in range(1,L)) - if(M.Victim == L) - usr << "[L.name] will not fit into the body scanner because they have a slime latched onto their head." - return - if(L == user) - visible_message("[user] climbs into the body scanner.") + user << "\The [src] is already occupied." + return 0 //occupied + + if(O.buckled) + return 0 + if(O.abiotic()) + user << "Subject cannot have abiotic items on." + return 0 + for(var/mob/living/carbon/slime/M in range(1, O)) + if(M.Victim == O) + user << "[O] has a fucking slime attached to them, deal with that first." + return 0 + + if(O == user) + visible_message("[user] climbs into \the [src].") else - visible_message("[user] puts [L.name] into the body scanner.") + visible_message("[user] puts [O] into the body scanner.") - if (L.client) - L.client.perspective = EYE_PERSPECTIVE - L.client.eye = src - L.loc = src - src.occupant = L - src.icon_state = "bodyscanner" - src.add_fingerprint(user) - return - -/*/obj/machinery/bodyscanner/allow_drop() - return 0*/ + O.forceMove(src) + occupant = O + icon_state = "bodyscanner" + add_fingerprint(user) /obj/machinery/bodyscanner/relaymove(mob/user as mob) - if (user.stat) - return - src.go_out() - return + if(user.incapacitated()) + return 0 //maybe they should be able to get out with cuffs, but whatever + go_out() /obj/machinery/bodyscanner/verb/eject() set src in oview(1) set category = "Object" set name = "Eject Body Scanner" - if (usr.stat != 0) + if(usr.incapacitated()) return - src.go_out() + go_out() add_fingerprint(usr) - return - -/obj/machinery/bodyscanner/verb/move_inside() - set src in oview(1) - set category = "Object" - set name = "Enter Body Scanner" - - if (usr.stat != 0) - return - if (src.occupant) - usr << "\blue The scanner is already occupied!" - return - if (panel_open) - usr << "\blue Close the maintenance panel first." - return - if (usr.abiotic()) - usr << "\blue Subject cannot have abiotic items on." - return - usr.pulling = null - usr.client.perspective = EYE_PERSPECTIVE - usr.client.eye = src - usr.loc = src - src.occupant = usr - src.icon_state = "bodyscanner" - for(var/obj/O in src) - //O = null - qdel(O) - //Foreach goto(124) - src.add_fingerprint(usr) - return /obj/machinery/bodyscanner/proc/go_out() if ((!( src.occupant ) || src.locked)) @@ -305,28 +260,6 @@ return return -/* - -/obj/machinery/body_scanconsole/process() //not really used right now - if(stat & (NOPOWER|BROKEN)) - return - //use_power(250) // power stuff - -// var/mob/M //occupant -// if (!( src.status )) //remove this -// return -// if ((src.connected && src.connected.occupant)) //connected & occupant ok -// M = src.connected.occupant -// else -// if (istype(M, /mob)) -// //do stuff -// else -/// src.temphtml = "Process terminated due to lack of occupant in scanning chamber." -// src.status = null -// src.updateDialog() -// return - -*/ /obj/machinery/body_scanconsole/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) if (istype(G, /obj/item/weapon/screwdriver)) @@ -365,181 +298,315 @@ if(!src.connected) findscanner() - if (src.connected) - if(!connected.occupant) - user << "The scanner is empty." - return - if(!ishuman(connected.occupant)) - user << "\red This device can only scan compatible lifeforms." - return - var/dat - if (src.delete && src.temphtml) //Window in buffer but its just simple message, so nothing - src.delete = src.delete - else if (!src.delete && src.temphtml) //Window in buffer - its a menu, dont add clear message - dat = text("[]

Main Menu", src.temphtml, src) - else - if (src.connected) //Is something connected? - var/mob/living/carbon/human/occupant = src.connected.occupant - dat = "Occupant Statistics:
" //Blah obvious - if (istype(occupant)) //is there REALLY someone in there? - var/t1 - switch(occupant.stat) // obvious, see what their status is - if(0) - t1 = "Conscious" - if(1) - t1 = "Unconscious" - else - t1 = "*dead*" - if (!istype(occupant,/mob/living/carbon/human)) - dat += "This device can only scan human occupants." - else - dat += text("[]\tHealth %: [] ([])

", (occupant.health > 50 ? "" : ""), occupant.health, t1) + ui_interact(user) - if(occupant.virus2.len) - dat += text("Viral pathogen detected in blood stream.
") - dat += text("[]\t-Brute Damage %: []

", (occupant.getBruteLoss() < 60 ? "" : ""), occupant.getBruteLoss()) - dat += text("[]\t-Respiratory Damage %: []
", (occupant.getOxyLoss() < 60 ? "" : ""), occupant.getOxyLoss()) - dat += text("[]\t-Toxin Content %: []
", (occupant.getToxLoss() < 60 ? "" : ""), occupant.getToxLoss()) - dat += text("[]\t-Burn Severity %: []

", (occupant.getFireLoss() < 60 ? "" : ""), occupant.getFireLoss()) +/obj/machinery/body_scanconsole/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] - dat += text("[]\tRadiation Level %: []
", (occupant.radiation < 10 ?"" : ""), occupant.radiation) - dat += text("[]\tGenetic Tissue Damage %: []
", (occupant.getCloneLoss() < 1 ?"" : ""), occupant.getCloneLoss()) - dat += text("[]\tApprox. Brain Damage %: []
", (occupant.getBrainLoss() < 1 ?"" : ""), occupant.getBrainLoss()) - dat += text("Paralysis Summary %: [] ([] seconds left!)
", occupant.paralysis, round(occupant.paralysis / 4)) - dat += text("Body Temperature: [occupant.bodytemperature-T0C]°C ([occupant.bodytemperature*1.8-459.67]°F)

") + data["connected"] = connected ? 1 : 0 - if(occupant.has_brain_worms()) - dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
" + if(connected) + data["occupied"] = connected.occupant ? 1 : 0 - if(occupant.vessel) - var/blood_volume = round(occupant.vessel.get_reagent_amount("blood")) - var/blood_percent = blood_volume / 560 - blood_percent *= 100 - dat += text("[]\tBlood Level %: [] ([] units)

", (blood_volume > 448 ?"" : ""), blood_percent, blood_volume) - if(occupant.reagents) - dat += text("Epinephrine units: [] units
", occupant.reagents.get_reagent_amount("Epinephrine")) - dat += text("Ether: [] units
", occupant.reagents.get_reagent_amount("ether")) - dat += text("[]\tSilver Sulfadiazine: [] units

", (occupant.reagents.get_reagent_amount("silver_sulfadiazine") < 30 ? "" : ""), occupant.reagents.get_reagent_amount("silver_sulfadiazine")) - dat += text("[]\tStyptic Powder: [] units
", (occupant.reagents.get_reagent_amount("styptic_powder") < 30 ? "" : ""), occupant.reagents.get_reagent_amount("styptic_powder")) - dat += text("[]\tsalbutamol: [] units
", (occupant.reagents.get_reagent_amount("salbutamol") < 30 ? "" : ""), occupant.reagents.get_reagent_amount("salbutamol")) + var/occupantData[0] + if(connected.occupant && ishuman(connected.occupant)) + var/mob/living/carbon/human/H = connected.occupant + occupantData["name"] = H.name + occupantData["stat"] = H.stat + occupantData["health"] = H.health - dat += "
" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" + occupantData["hasVirus"] = H.virus2.len - for(var/obj/item/organ/external/e in occupant.organs) + occupantData["bruteLoss"] = H.getBruteLoss() + occupantData["oxyLoss"] = H.getOxyLoss() + occupantData["toxLoss"] = H.getToxLoss() + occupantData["fireLoss"] = H.getFireLoss() - dat += "" - var/AN = "" - var/open = "" - var/infected = "" - var/robot = "" - var/imp = "" - var/bled = "" - var/splint = "" - var/internal_bleeding = "" - var/lung_ruptured = "" - for(var/datum/wound/W in e.wounds) if(W.internal) - internal_bleeding = "
Internal bleeding" - break - if(istype(e, /obj/item/organ/external/chest) && occupant.is_lung_ruptured()) - lung_ruptured = "Lung ruptured:" - if(e.status & ORGAN_SPLINTED) - splint = "Splinted:" - if(e.status & ORGAN_BLEEDING) - bled = "Bleeding:" - if(e.status & ORGAN_BROKEN) - AN = "[e.broken_description]:" - if(e.status & ORGAN_ROBOT) - robot = "Prosthetic:" - if(e.open) - open = "Open:" - switch (e.germ_level) - if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200) - infected = "Mild Infection:" - if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) - infected = "Mild Infection+:" - if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) - infected = "Mild Infection++:" - if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) - infected = "Acute Infection:" - if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) - infected = "Acute Infection+:" - if (INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_TWO + 400) - infected = "Acute Infection++:" - if (INFECTION_LEVEL_THREE to INFINITY) - infected = "Septic:" + occupantData["radLoss"] = H.radiation + occupantData["cloneLoss"] = H.getCloneLoss() + occupantData["brainLoss"] = H.getBrainLoss() + occupantData["paralysis"] = H.paralysis + occupantData["paralysisSeconds"] = round(H.paralysis / 4) + occupantData["bodyTempC"] = H.bodytemperature-T0C + occupantData["bodyTempF"] = (((H.bodytemperature-T0C) * 1.8) + 32) - var/unknown_body = 0 - for(var/I in e.implants) - if(is_type_in_list(I,known_implants)) - imp += "[I] implanted:" - else - unknown_body++ + occupantData["hasBorer"] = H.has_brain_worms() - if(unknown_body || e.hidden) - imp += "Unknown body present:" - if(!AN && !open && !infected & !imp) - AN = "None:" - if(!(e.status & ORGAN_DESTROYED)) - dat += "" - else - dat += "" - dat += "" - for(var/obj/item/organ/i in occupant.internal_organs) - var/mech = i.desc - var/infection = "None" - switch (i.germ_level) - if (1 to INFECTION_LEVEL_ONE + 200) - infection = "Mild Infection:" - if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) - infection = "Mild Infection+:" - if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) - infection = "Mild Infection++:" - if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) - infection = "Acute Infection:" - if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) - infection = "Acute Infection+:" - if (INFECTION_LEVEL_TWO + 300 to INFINITY) - infection = "Acute Infection++:" + var/bloodData[0] + if(H.vessel) + var/blood_volume = round(H.vessel.get_reagent_amount("blood")) + bloodData["volume"] = blood_volume + bloodData["percent"] = round(((blood_volume / 560)*100)) + + occupantData["blood"] = bloodData + + var/reagentData[0] + if(H.reagents) + reagentData["epinephrine"] = H.reagents.get_reagent_amount("Epinephrine") + reagentData["ether"] = H.reagents.get_reagent_amount("ether") + reagentData["silver_sulfadiazine"] = H.reagents.get_reagent_amount("silver_sulfadiazine") + reagentData["styptic_powder"] = H.reagents.get_reagent_amount("styptic_powder") + reagentData["salbutamol"] = H.reagents.get_reagent_amount("salbutamol") + + occupantData["reagents"] = reagentData + + var/extOrganData[0] + for(var/obj/item/organ/external/E in H.organs) + var/organData[0] + organData["name"] = E.name + organData["open"] = E.open + organData["germ_level"] = E.germ_level + organData["bruteLoss"] = E.brute_dam + organData["fireLoss"] = E.burn_dam + + var/implantData[0] + for(var/obj/I in E.implants) + var/implantSubData[0] + implantSubData["name"] = I.name + if(is_type_in_list(I, known_implants)) + implantSubData["known"] = 1 + + implantData.Add(list(implantSubData)) + + organData["implants"] = implantData + organData["implants_len"] = implantData.len + + var/organStatus[0] + if(E.status & ORGAN_DESTROYED) + organStatus["destroyed"] = 1 + if(E.status & ORGAN_BROKEN) + organStatus["broken"] = E.broken_description + if(E.status & ORGAN_ROBOT) + organStatus["robotic"] = 1 + if(E.status & ORGAN_SPLINTED) + organStatus["splinted"] = 1 + if(E.status & ORGAN_BLEEDING) + organStatus["bleeding"] = 1 + + organData["status"] = organStatus + + if(istype(E, /obj/item/organ/external/chest) && H.is_lung_ruptured()) + organData["lungRuptured"] = 1 + + for(var/datum/wound/W in E.wounds) + if(W.internal) + organData["internalBleeding"] = 1 + break + + extOrganData.Add(list(organData)) + + occupantData["extOrgan"] = extOrganData + + var/intOrganData[0] + for(var/obj/item/organ/I in H.internal_organs) + var/organData[0] + organData["name"] = I.name + organData["desc"] = I.desc + organData["germ_level"] = I.germ_level + organData["damage"] = I.damage + + intOrganData.Add(list(organData)) + + occupantData["intOrgan"] = intOrganData + + occupantData["blind"] = (H.sdisabilities & BLIND) + occupantData["nearsighted"] = (H.disabilities & NEARSIGHTED) + + data["occupant"] = occupantData + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "adv_med.tmpl", "Body Scanner", 690, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) - dat += "" - dat += "" - dat += "" - dat += "
OrganBurn DamageBrute DamageOther Wounds
[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured][e.name]--Not Found
[i.name]N/A[i.damage][infection]:[mech]
" - if(occupant.sdisabilities & BLIND) - dat += text("Cataracts detected.
") - if(occupant.sdisabilities & NEARSIGHTED) - dat += text("Retinal misalignment detected.
") - src.printing_text = dat - dat += "

Print medical condition
" - else - dat += "\The [src] is empty." - else - dat = " Error: No Body Scanner connected." - dat += text("Close", user) - user << browse(dat, "window=scanconsole;size=430x600") - return /obj/machinery/body_scanconsole/Topic(href, href_list) if(..()) return 1 if (href_list["print_p"]) - if (!(src.printing) && src.printing_text) - src.printing = 1 - for(var/mob/O in viewers(usr)) - O.show_message("\blue \the [src] rattles and prints out a sheet of paper.", 1) - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( src.loc ) + generate_printing_text() + + if (!(printing) && printing_text) + printing = 1 + visible_message("\The [src] rattles and prints out a sheet of paper.") + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc) P.info = "
Body Scan - [href_list["name"]]

" P.info += "Time of scan: [worldtime2text(world.time)]

" - P.info += "[src.printing_text]" + P.info += "[printing_text]" P.info += "

Notes:
" P.name = "Body Scan - [href_list["name"]]" - src.printing = null - src.printing_text = null \ No newline at end of file + printing = null + printing_text = null + +/obj/machinery/body_scanconsole/proc/generate_printing_text() + var/dat = "" + + if(connected) + var/mob/living/carbon/human/occupant = connected.occupant + dat = "Occupant Statistics:
" //Blah obvious + if(istype(occupant)) //is there REALLY someone in there? + var/t1 + switch(occupant.stat) // obvious, see what their status is + if(0) + t1 = "Conscious" + if(1) + t1 = "Unconscious" + else + t1 = "*dead*" + dat += "[occupant.health > 50 ? "" : ""]\tHealth %: [occupant.health], ([t1])
" + + if(occupant.virus2.len) + dat += "Viral pathogen detected in blood stream.
" + + var/extra_font = null + extra_font = (occupant.getBruteLoss() < 60 ? "" : "") + dat += "[extra_font]\t-Brute Damage %: [occupant.getBruteLoss()]
" + + extra_font = (occupant.getOxyLoss() < 60 ? "" : "") + dat += "[extra_font]\t-Respiratory Damage %: [occupant.getOxyLoss()]
" + + extra_font = (occupant.getToxLoss() < 60 ? "" : "") + dat += "[extra_font]\t-Toxin Content %: [occupant.getToxLoss()]
" + + extra_font = (occupant.getFireLoss() < 60 ? "" : "") + dat += "[extra_font]\t-Burn Severity %: [occupant.getFireLoss()]
" + + extra_font = (occupant.radiation < 10 ?"" : "") + dat += "[extra_font]\tRadiation Level %: [occupant.radiation]
" + + extra_font = (occupant.getCloneLoss() < 1 ?"" : "") + dat += "[extra_font]\tGenetic Tissue Damage %: [occupant.getCloneLoss()]
" + + extra_font = (occupant.getBrainLoss() < 1 ?"" : "") + dat += "[extra_font]\tApprox. Brain Damage %: [occupant.getBrainLoss()]
" + + dat += "Paralysis Summary %: [occupant.paralysis] ([round(occupant.paralysis / 4)] seconds left!)
" + dat += "Body Temperature: [occupant.bodytemperature-T0C]°C ([occupant.bodytemperature*1.8-459.67]°F)
" + + dat += "
" + + if(occupant.has_brain_worms()) + dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
" + + if(occupant.vessel) + var/blood_volume = round(occupant.vessel.get_reagent_amount("blood")) + var/blood_percent = blood_volume / 560 + blood_percent *= 100 + + extra_font = (blood_volume > 448 ? "" : "") + dat += "[extra_font]\tBlood Level %: [blood_percent] ([blood_volume] units)
" + + if(occupant.reagents) + dat += "Epinephrine units: [occupant.reagents.get_reagent_amount("Epinephrine")] units
" + dat += "Ether: [occupant.reagents.get_reagent_amount("ether")] units
" + + extra_font = (occupant.reagents.get_reagent_amount("silver_sulfadiazine") < 30 ? "" : "") + dat += "[extra_font]\tSilver Sulfadiazine: [occupant.reagents.get_reagent_amount("silver_sulfadiazine")]
" + + extra_font = (occupant.reagents.get_reagent_amount("styptic_powder") < 30 ? "" : "") + dat += "[extra_font]\tStyptic Powder: [occupant.reagents.get_reagent_amount("styptic_powder")] units
" + + extra_font = (occupant.reagents.get_reagent_amount("salbutamol") < 30 ? "" : "") + dat += "[extra_font]\tSalbutamol: [occupant.reagents.get_reagent_amount("salbutamol")] units
" + + dat += "
" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + + for(var/obj/item/organ/external/e in occupant.organs) + dat += "" + var/AN = "" + var/open = "" + var/infected = "" + var/robot = "" + var/imp = "" + var/bled = "" + var/splint = "" + var/internal_bleeding = "" + var/lung_ruptured = "" + for(var/datum/wound/W in e.wounds) if(W.internal) + internal_bleeding = "
Internal bleeding" + break + if(istype(e, /obj/item/organ/external/chest) && occupant.is_lung_ruptured()) + lung_ruptured = "Lung ruptured:" + if(e.status & ORGAN_SPLINTED) + splint = "Splinted:" + if(e.status & ORGAN_BLEEDING) + bled = "Bleeding:" + if(e.status & ORGAN_BROKEN) + AN = "[e.broken_description]:" + if(e.status & ORGAN_ROBOT) + robot = "Prosthetic:" + if(e.open) + open = "Open:" + switch (e.germ_level) + if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200) + infected = "Mild Infection:" + if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) + infected = "Mild Infection+:" + if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) + infected = "Mild Infection++:" + if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) + infected = "Acute Infection:" + if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) + infected = "Acute Infection+:" + if (INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_TWO + 400) + infected = "Acute Infection++:" + if (INFECTION_LEVEL_THREE to INFINITY) + infected = "Septic:" + + var/unknown_body = 0 + for(var/I in e.implants) + if(is_type_in_list(I,known_implants)) + imp += "[I] implanted:" + else + unknown_body++ + + if(unknown_body || e.hidden) + imp += "Unknown body present:" + if(!AN && !open && !infected & !imp) + AN = "None:" + if(!(e.status & ORGAN_DESTROYED)) + dat += "" + else + dat += "" + dat += "" + for(var/obj/item/organ/i in occupant.internal_organs) + var/mech = i.desc + var/infection = "None" + switch (i.germ_level) + if (1 to INFECTION_LEVEL_ONE + 200) + infection = "Mild Infection:" + if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) + infection = "Mild Infection+:" + if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) + infection = "Mild Infection++:" + if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) + infection = "Acute Infection:" + if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) + infection = "Acute Infection+:" + if (INFECTION_LEVEL_TWO + 300 to INFINITY) + infection = "Acute Infection++:" + + dat += "" + dat += "" + dat += "" + dat += "
OrganBurn DamageBrute DamageOther Wounds
[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured][e.name]--Not Found
[i.name]N/A[i.damage][infection]:[mech]
" + if(occupant.sdisabilities & BLIND) + dat += "Cataracts detected.
" + if(occupant.disabilities & NEARSIGHTED) + dat += "Retinal misalignment detected.
" + else + dat += "\The [src] is empty." + else + dat = " Error: No Body Scanner connected." + + printing_text = dat \ No newline at end of file diff --git a/code/game/machinery/kitchen/monkeyrecycler.dm b/code/game/machinery/kitchen/monkeyrecycler.dm index 22115ad0cdc..810143f6583 100644 --- a/code/game/machinery/kitchen/monkeyrecycler.dm +++ b/code/game/machinery/kitchen/monkeyrecycler.dm @@ -53,11 +53,11 @@ var/mob/living/carbon/human/target = grabbed if(issmall(target)) if(target.stat == 0) - user << "\red The monkey is struggling far too much to put it in the recycler." + user << "The monkey is struggling far too much to put it in the recycler." else user.drop_item() qdel(target) - user << "\blue You stuff the monkey in the machine." + user << "You stuff the monkey in the machine." playsound(src.loc, 'sound/machines/juicer.ogg', 50, 1) var/offset = prob(50) ? -2 : 2 animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking @@ -65,22 +65,23 @@ src.grinded++ sleep(50) pixel_x = initial(pixel_x) - user << "\blue The machine now has [grinded] monkeys worth of material stored." + user << "The machine now has [grinded] monkey\s worth of material stored." else - user << "\red The machine only accepts monkeys!" + user << "The machine only accepts monkeys!" else - user << "\red The machine only accepts monkeys!" + user << "The machine only accepts monkeys!" return /obj/machinery/monkey_recycler/attack_hand(var/mob/user as mob) if (src.stat != 0) //NOPOWER etc return if(grinded >= required_grind) - user << "\blue The machine hisses loudly as it condenses the grinded monkey meat. After a moment, it dispenses a brand new monkey cube." + user << "The machine hisses loudly as it condenses the grinded monkey meat. After a moment, it dispenses a brand new monkey cube." playsound(src.loc, 'sound/machines/hiss.ogg', 50, 1) grinded -= required_grind - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped(src.loc) - user << "\blue The machine's display flashes that it has [grinded] monkeys worth of material left." - else - user << "\red The machine needs at least [required_grind] monkey\s worth of material to produce a monkey cube. It only has [grinded]." - return + for(var/i = 0, i < cube_production, i++) // Forgot to fix this bit the first time through + new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped(src.loc) + user << "The machine's display flashes that it has [grinded] monkey\s worth of material left." + else // I'm not sure if the \s macro works with a word in between; I'll play it safe + user << "The machine needs at least [required_grind] monkey\s worth of material to compress [cube_production] monkey\s. It only has [grinded]." + return \ No newline at end of file diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index 68df2d59ed1..31b58bcac10 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -16,7 +16,7 @@ Bent Pipe
Manifold
Manual Valve
-Digital Valve
+Digital Valve
Pipe Cap
4-Way Manifold
Manual T-Valve
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 23dbb530fa9..c535f53a753 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -136,7 +136,7 @@ if(5.0) size = "huge" - ..(user, distance, "", "It is a [size] item.") + . = ..(user, distance, "", "It is a [size] item.") if(user.research_scanner) //Mob has a research scanner active. var/msg = "*--------*
" diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 84fad33f60c..ee203dad9b4 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -179,6 +179,13 @@ /obj/item/weapon/card/id/proc/is_untrackable() return untrackable +/obj/item/weapon/card/id/proc/update_label(newname, newjob) + if(newname || newjob) + name = "[(!newname) ? "identification card" : "[newname]'s ID Card"][(!newjob) ? "" : " ([newjob])"]" + return + + name = "[(!registered_name) ? "identification card" : "[registered_name]'s ID Card"][(!assignment) ? "" : " ([assignment])"]" + /obj/item/weapon/card/id/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() @@ -623,12 +630,12 @@ assignment = "Green Team Fighter" icon_state = "TDgreen" desc = "This ID card is given to those who fought inside the thunderdome for the Green Team. Not many have lived to see one of those, even fewer lived to keep it." - + /obj/item/weapon/card/id/lifetime name = "Lifetime ID Card" desc = "A modified ID card given only to those people who have devoted their lives to the better interests of Nanotrasen. It sparkles blue." icon_state = "lifetimeid" - + // Decals /obj/item/weapon/id_decal name = "identification card decal" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 85494318fa9..8cd2500b0e0 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -105,7 +105,7 @@ var/mob/O = M if(!O.lastarea) O.lastarea = get_area(O.loc) - O.update_gravity(O.mob_has_gravity(src)) +// O.update_gravity(O.mob_has_gravity(src)) var/loopsanity = 100 for(var/atom/A in range(1)) diff --git a/code/game/vehicles/spacepods/spacepod.dm b/code/game/vehicles/spacepods/spacepod.dm index d1525fde451..effd1bd64b9 100644 --- a/code/game/vehicles/spacepods/spacepod.dm +++ b/code/game/vehicles/spacepods/spacepod.dm @@ -85,6 +85,7 @@ pr_give_air = null qdel(ion_trail) ion_trail = null + occupant_sanity_check() if(occupant) occupant.forceMove(get_turf(src)) occupant = null @@ -148,6 +149,7 @@ var/oldhealth = health health = max(0, health - damage) var/percentage = (health / initial(health)) * 100 + occupant_sanity_check() if(occupant && oldhealth > health && percentage <= 25 && percentage > 0) var/sound/S = sound('sound/effects/engine_alert2.ogg') S.wait = 0 //No queue @@ -186,6 +188,7 @@ /obj/spacepod/ex_act(severity) + occupant_sanity_check() switch(severity) if(1) var/mob/living/carbon/human/H = occupant @@ -207,6 +210,7 @@ deal_damage(50) /obj/spacepod/emp_act(severity) + occupant_sanity_check() switch(severity) if(1) if(src.occupant) src.occupant << "The pod console flashes 'Heavy EMP WAVE DETECTED'." //warn the occupants @@ -464,129 +468,118 @@ . = t_air.return_temperature() return -/obj/spacepod/proc/moved_inside(var/mob/living/carbon/human/H as mob) - var/fukkendisk = usr.GetTypeInAllContents(/obj/item/weapon/disk/nuclear) - if(fukkendisk) - usr << "\red The nuke-disk locks the door as you try to get in. You evil person." - return - - if(H && H.client && H in range(1)) - if(src.occupant && src.occupant2) - H << "[src.name] is full." - return - - if(src.occupant && !src.occupant2) - if(src.occupant == H) - H.visible_message("You climb over the console and drop down into the secondary seat.") - H.reset_view(src) - H.stop_pulling() - H.forceMove(src) - if(src.occupant == H) occupant = null - src.occupant2 = H - src.add_fingerprint(H) - src.forceMove(src.loc) - playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) - return 1 - - else - if(!src.occupant) - H.reset_view(src) - H.stop_pulling() - H.forceMove(src) - src.occupant = H - src.add_fingerprint(H) - src.forceMove(src.loc) - playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) - return 1 - else - return - else - return 0 - /obj/spacepod/proc/moved_other_inside(var/mob/living/carbon/human/H as mob) - if(!src.occupant2) - H.reset_view(src) + occupant_sanity_check() + if(!occupant2) H.stop_pulling() H.forceMove(src) - src.occupant2 = H - src.forceMove(src.loc) + occupant2 = H + H.forceMove(src) playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) return 1 - else + +/obj/spacepod/MouseDrop_T(mob/M, mob/user) + if(!isliving(M)) return - - -/obj/spacepod/MouseDrop_T(mob/M as mob, mob/user as mob) - if(!isliving(M)) return + occupant_sanity_check() if(M != user && M.stat == DEAD && allow2enter) - if(src.occupant2 && !src.occupant) + if(occupant2 && !occupant) usr << "You can't put a corpse into the driver's seat!" - return - if(!src.occupant2) + return 0 + if(!occupant2) visible_message("[user.name] starts loading [M.name] into the pod!") sleep(10) moved_other_inside(M) if(M == user) - move_inside(user) + enter_pod(user) -/obj/spacepod/verb/move_inside(var/mob/user) +/obj/spacepod/verb/enter_pod(mob/user = usr) set category = "Object" set name = "Enter Pod" set src in oview(1) - var/fukkendisk = usr.GetTypeInAllContents(/obj/item/weapon/disk/nuclear) - if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis || user.resting) //are you cuffed, dying, lying, stunned or other - return - if (!ishuman(user)) return + if(!istype(user)) + return 0 + + var/fukkendisk = user.GetTypeInAllContents(/obj/item/weapon/disk/nuclear) + + if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other + return 0 + if(!ishuman(user)) + return 0 if(fukkendisk) - user << "The nuke-disk is locking the door every time you try to open it. You get the feeling that it doesn't want to go into the spacepod." - return + user << "The nuke-disk is locking the door every time you try to open it. You get the feeling that it doesn't want to go into the spacepod." + return 0 for(var/mob/living/carbon/slime/S in range(1,usr)) if(S.Victim == user) user << "You're too busy getting your life sucked out of you." - return + return 0 - try_user_enter(user) + move_inside(user) -/obj/spacepod/proc/try_user_enter(var/mob/user) - if(!src.occupant && !src.occupant2) - visible_message("[user] starts to climb into [src.name]") - if(enter_after(40,user)) - if(!src.occupant) - moved_inside(user) - else if(src.occupant != user) - user << "[src.occupant] was faster. Try better next time, loser." - else user << "You stop entering the spacepod." - return +/obj/spacepod/proc/move_inside(mob/user) + if(!istype(user)) + log_debug("SHIT'S GONE WRONG WITH THE SPACEPOD [src] AT [x], [y], [z], AREA [get_area(src)], TURF [get_turf(src)]") - if(!allow2enter) - user << "The door is locked!" - return + occupant_sanity_check() - if(occupant && occupant2) - user << "You can't fit in \the [src], it's full!" - return + if(!occupant) + visible_message("[user] starts to climb into \the [src].") + if(do_after(user, 40, target = src)) + if(!occupant) + user.stop_pulling() + occupant = user + user.forceMove(src) + add_fingerprint(user) + playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) + else + user << "[occupant] was faster. Try better next time, loser." + else + user << "You stop entering \the [src]." - if(occupant && !occupant2) - user << "You start climbing into the passenger bay." - user_enter(user) - - if(!occupant && occupant2) - user << "You start climbing into the pilot's seat." - user_enter(user) - -/obj/spacepod/proc/user_enter(var/mob/user) - visible_message("[user] starts to climb into \the [src.name].") - if(enter_after(40,user)) - moved_inside(user) + else if(!occupant2) + visible_message("[user] starts to climb into \the [src].") + if(do_after(user, 40, target = src)) + if(!occupant2) + user.stop_pulling() + occupant2 = user + user.forceMove(src) + add_fingerprint(user) + playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) + else + user << "[occupant] was faster. Try better next time, loser." + else + user << "You stop entering \the [src]." else - user << "You stop entering the spacepod." + user << "You can't fit in \the [src], it's full!" + +/obj/spacepod/proc/occupant_sanity_check() + if(occupant) + if(!ismob(occupant)) + occupant.forceMove(get_turf(src)) + log_debug("##SPACEPOD WARNING: NON-MOB OCCUPANT [occupant], TURF [get_turf(src)] | AREA [get_area(src)] | COORDS [x], [y], [z]") + occupant = null + else if(occupant.loc != src) + log_debug("##SPACEPOD WARNING: OCCUPANT [occupant] ESCAPED, TURF [get_turf(src)] | AREA [get_area(src)] | COORDS [x], [y], [z]") + occupant = null + if(occupant2) + if(!ismob(occupant2)) + occupant2.forceMove(get_turf(src)) + log_debug("##SPACEPOD WARNING: NON-MOB OCCUPANT [occupant2], TURF [get_turf(src)] | AREA [get_area(src)] | COORDS [x], [y], [z]") + occupant2 = null + else if(occupant2.loc != src) + log_debug("##SPACEPOD WARNING: OCCUPANT [occupant2] ESCAPED, TURF [get_turf(src)] | AREA [get_area(src)] | COORDS [x], [y], [z]") + occupant2 = null + + if(!occupant && !allow2enter) + allow2enter = 1 + log_debug("##SPACEPOD WARNING: DOORS WERE STILL LOCKED WITH NO OCCUPANT, TURF [get_turf(src)] | AREA [get_area(src)] | COORDS [x], [y], [z]") /obj/spacepod/verb/exit_pod() set name = "Exit pod" @@ -595,7 +588,10 @@ var/mob/user = usr var/spos = 0 - if(!ismob(user)) return + if(!istype(user)) + return + + occupant_sanity_check() if(occupant == user) spos = 1 if(occupant2 == user) spos = 2 @@ -618,6 +614,8 @@ set category = "Spacepod" set src = usr.loc + occupant_sanity_check() + if(!occupant2) usr << "There is no one in the second seat." return @@ -685,7 +683,7 @@ return equipment_system.weapon_system.fire_weapons() -obj/spacepod/verb/toggleLights() +/obj/spacepod/verb/toggleLights() set name = "Toggle Lights" set category = "Spacepod" set src = usr.loc diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index a064788ebba..7ae8cb1fe28 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -100,6 +100,7 @@ TDM
Everyone is the traitor   There can only be one!   + There can only be me!   Dodgeball (TDM)!
Round-enders
The floor is lava! (DANGEROUS: extremely lame)
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index c58d9edf765..12dbc638e57 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2668,6 +2668,10 @@ feedback_add_details("admin_secrets_fun_used","OO") usr.client.only_one() // message_admins("[key_name_admin(usr)] has triggered HIGHLANDER") + if("onlyme") + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","OM") + usr.client.only_me() if("onlyoneteam") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","OOT") diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm index ae1e053659b..97e7f716a3c 100644 --- a/code/modules/admin/verbs/onlyone.dm +++ b/code/modules/admin/verbs/onlyone.dm @@ -5,9 +5,9 @@ var/list/incompatible_species = list("Plasmaman") for(var/mob/living/carbon/human/H in player_list) - if(H.stat == DEAD || !(H.client)) + if(H.stat == DEAD || !(H.client)) continue - if(is_special_character(H)) + if(is_special_character(H)) continue if(H.species.name in incompatible_species) H.set_species("Human") @@ -55,3 +55,50 @@ message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ONE! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1) log_admin("[key_name(usr)] used there can be only one.") nologevent = 1 + world << sound('sound/music/THUNDERDOME.ogg') + +/client/proc/only_me() + if(!ticker) + alert("The game hasn't started yet!") + return + + for(var/mob/living/carbon/human/H in player_list) + if(H.stat == 2 || !(H.client)) continue + if(is_special_character(H)) continue + + ticker.mode.traitors += H.mind + H.mind.special_role = "[H.real_name] Prime" + + var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone + hijack_objective.owner = H.mind + H.mind.objectives += hijack_objective + + H << "You are the multiverse summoner. Activate your blade to summon copies of yourself from another universe to fight by your side." + var/obj_count = 1 + for(var/datum/objective/OBJ in H.mind.objectives) + H << "Objective #[obj_count]: [OBJ.explanation_text]" + obj_count++ + + var/obj/item/slot_item_ID = H.get_item_by_slot(slot_wear_id) + qdel(slot_item_ID) + var/obj/item/slot_item_hand = H.get_item_by_slot(slot_r_hand) + H.unEquip(slot_item_hand) + + var /obj/item/weapon/multisword/pure_evil/multi = new(H) + H.equip_to_slot_or_del(multi, slot_r_hand) + + var/obj/item/weapon/card/id/W = new(H) + W.icon_state = "centcom" + W.access = get_all_accesses() + W.access += get_all_centcom_access() + W.assignment = "Multiverse Summoner" + W.registered_name = H.real_name + W.update_label(H.real_name) + H.equip_to_slot_or_del(W, slot_wear_id) + + H.update_icons() + + message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ME! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1) + log_admin("[key_name(usr)] used there can be only me.") + nologevent = 1 + world << sound('sound/music/THUNDERDOME.ogg') \ No newline at end of file diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 210b1ddea65..23add6c8b59 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -905,7 +905,6 @@ datum/preferences proc/process_link(mob/user, list/href_list) if(!user) return - if(!istype(user, /mob/new_player)) return if(href_list["preference"] == "job") switch(href_list["task"]) if("close") diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 0eae2206ba0..ec3aa30a778 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -178,7 +178,7 @@ src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1) src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2) feedback_add_details("admin_verb","Thb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - + // This needs a toggle because you people are awful and spammed terrible music /client/verb/toggle_instruments() set name = "Hear/Silence Instruments" @@ -192,56 +192,6 @@ src << "You will no longer hear musical instruments." feedback_add_details("admin_verb","TInstru") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -//be special -/client/verb/toggle_be_special(role in be_special_flags) - set name = "Toggle Special Role Candidacy" - set category = "Preferences" - set desc = "Toggles which special roles you would like to be a candidate for, during events." - var/role_flag = be_special_flags[role] - if(!role_flag) return - if(!player_old_enough_antag(src,be_special_flags[role])) - var/available_in_days_antag = available_in_days_antag(src,be_special_flags[role]) - src << "This role is not yet available to you. You need to wait another [available_in_days_antag] days." - return - prefs.be_special ^= role_flag - prefs.save_preferences(src) - src << "You will [(prefs.be_special & role_flag) ? "now" : "no longer"] be considered for [role] events (where possible)." - feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/verb/change_ui() - set name = "Change UI" - set category = "Preferences" - set desc = "Configure your user interface" - - if(!ishuman(usr)) - usr << "This only for human" - return - - var/UI_style_new = input(usr, "Select a style, we recommend White for customization") in list("White", "Midnight", "Orange", "old") - if(!UI_style_new) return - - var/UI_style_alpha_new = input(usr, "Select a new alpha (transparency) parameter for UI, between 50 and 255") as num - if(!UI_style_alpha_new | !(UI_style_alpha_new <= 255 && UI_style_alpha_new >= 50)) return - - var/UI_style_color_new = input(usr, "Choose your UI color. Dark colors are not recommended!") as color|null - if(!UI_style_color_new) return - - //update UI - var/list/icons = usr.hud_used.adding + usr.hud_used.other +usr.hud_used.hotkeybuttons - icons.Add(usr.zone_sel) - - for(var/obj/screen/I in icons) - I.icon = ui_style2icon(UI_style_new) - I.color = UI_style_color_new - I.alpha = UI_style_alpha_new - - if(alert("Like it? Save changes?",,"Yes", "No") == "Yes") - prefs.UI_style = UI_style_new - prefs.UI_style_alpha = UI_style_alpha_new - prefs.UI_style_color = UI_style_color_new - prefs.save_preferences(src) - usr << "UI was saved" - /client/verb/toggle_media() set name = "Hear/Silence Streaming" set category = "Preferences" @@ -255,12 +205,10 @@ media.update_music() else media.stop_music() - -/client/verb/toggle_member_publicity() - set name = "Toggle Membership Publicity" + +/client/verb/setup_character() + set name = "Game Preferences" set category = "Preferences" - set desc = "Toggles whether other players can see that you are a BYOND member (OOC blag icon/colours)." - - prefs.toggles ^= MEMBER_PUBLIC - prefs.save_preferences(src) - src << "Others can[(prefs.toggles & MEMBER_PUBLIC) ? "" : " not"] see whether you are a BYOND member." + set desc = "Allows you to access the Setup Character screen. Changes to your character won't take effect until next round, but other changes will." + prefs.current_tab = 1 + prefs.ShowChoices(usr) \ No newline at end of file diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 874637995a0..5bc193892a0 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -514,8 +514,8 @@ health = 0 dead = 0 - nutrilevel = max(0,min(nutrilevel,10)) - waterlevel = max(0,min(waterlevel,100)) + nutrilevel = max(0,min(nutrilevel,maxnutri)) + waterlevel = max(0,min(waterlevel,maxwater)) pestlevel = max(0,min(pestlevel,10)) weedlevel = max(0,min(weedlevel,10)) toxins = max(0,min(toxins,10)) @@ -793,8 +793,8 @@ if(!Adjacent(user)) return - user << "Water: [round(waterlevel,0.1)]/100" - user << "Nutrient: [round(nutrilevel,0.1)]/10" + user << "Water: [round(waterlevel,0.1)]/[maxwater]" + user << "Nutrient: [round(nutrilevel,0.1)]/[maxnutri]" if(weedlevel >= 5) user << "\The [src] is infested with weeds!" @@ -864,4 +864,4 @@ if(istype(holding, /obj/item/weapon/tank)) usr << "\blue You eject [holding.name] from [src]." holding.loc = loc - holding = null + holding = null \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 0ec7e3c8ded..88000afe32f 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -85,7 +85,7 @@ return health = maxHealth - getOxyLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() -/mob/living/carbon/alien/proc/handle_environment(var/datum/gas_mixture/environment) +/mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment) //If there are alien weeds on the ground then heal if needed or give some toxins if(locate(/obj/structure/alien/weeds) in loc) @@ -136,7 +136,7 @@ fire_alert = max(fire_alert, 2) return -/mob/living/carbon/alien/proc/handle_mutations_and_radiation() +/mob/living/carbon/alien/handle_mutations_and_radiation() if(getFireLoss()) if((RESIST_HEAT in mutations) || prob(5)) adjustFireLoss(-1) @@ -171,11 +171,6 @@ bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up! return -/mob/living/carbon/alien/proc/handle_wetness() - if(mob_master.current_cycle%20==2) //dry off a bit once every 20 ticks or so - wetlevel = max(wetlevel - 1,0) - return - /mob/living/carbon/alien/IsAdvancedToolUser() return has_fine_manipulation diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm index 2b6407398d2..6e4fe3705f4 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/life.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm @@ -9,70 +9,12 @@ /mob/living/carbon/alien/humanoid/Life() - set invisibility = 0 - set background = BACKGROUND_ENABLED - - ..() - - var/datum/gas_mixture/environment = loc.return_air() - - if (stat != DEAD) //still breathing - - //First, resolve location and get a breath - - if(mob_master.current_cycle%4==2) - //Only try to take a breath every 4 seconds, unless suffocating - spawn(0) breathe() - - else //Still give containing object the chance to interact - if(istype(loc, /obj/)) - var/obj/location_as_object = loc - location_as_object.handle_internal_lifeform(src, 0) - - //Mutations and radiation - handle_mutations_and_radiation() - - //Chemicals in the body - handle_chemicals_in_body() - - //Disabilities - handle_disabilities() - - //Apparently, the person who wrote this code designed it so that - //blinded get reset each cycle and then get activated later in the - //code. Very ugly. I dont care. Moving this stuff here so its easy - //to find it. - blinded = null - - //Handle temperature/pressure differences between body and environment - handle_environment(environment) - - //stuff in the stomach - handle_stomach() - - //Handle being on fire - handle_fire() - - //Decrease wetness over time - handle_wetness() - - //Status updates, death etc. - handle_regular_status_updates() - - handle_actions() - - update_canmove() + . = ..() update_icons() - // Grabbing - for(var/obj/item/weapon/grab/G in src) - G.process() - - if(client) - handle_regular_hud_updates() -/mob/living/carbon/alien/humanoid/proc/handle_disabilities() +/mob/living/carbon/alien/humanoid/handle_disabilities() if (disabilities & EPILEPSY) if ((prob(1) && paralysis < 10)) src << "You have a seizure!" @@ -110,7 +52,7 @@ temp_change = (temperature - current) return temp_change -/mob/living/carbon/alien/humanoid/proc/handle_regular_status_updates() +/mob/living/carbon/alien/humanoid/handle_regular_status_updates() updatehealth() if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP @@ -191,7 +133,7 @@ return 1 -/mob/living/carbon/alien/humanoid/proc/handle_regular_hud_updates() +/mob/living/carbon/alien/humanoid/handle_regular_hud_updates() if (stat == 2 || (XRAY in mutations)) sight |= SEE_TURFS diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 01e36955196..d4e57324826 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -3,61 +3,16 @@ /mob/living/carbon/alien/larva var/temperature_alert = 0 - /mob/living/carbon/alien/larva/Life() - set invisibility = 0 - set background = BACKGROUND_ENABLED - - ..() - var/datum/gas_mixture/enviroment = loc.return_air() - if (stat != DEAD) //still breathing - + if(..()) //still breathing // GROW! if(amount_grown < max_grown) amount_grown++ - //First, resolve location and get a breath - if(mob_master.current_cycle%4==2) - //Only try to take a breath every 4 seconds, unless suffocating - spawn(0) breathe() - else //Still give containing object the chance to interact - if(istype(loc, /obj/)) - var/obj/location_as_object = loc - location_as_object.handle_internal_lifeform(src, 0) - //Mutations and radiation - handle_mutations_and_radiation() - - //Chemicals in the body - handle_chemicals_in_body() - - - //Apparently, the person who wrote this code designed it so that - //blinded get reset each cycle and then get activated later in the - //code. Very ugly. I dont care. Moving this stuff here so its easy - //to find it. - blinded = null - - //Handle temperature/pressure differences between body and environment - handle_environment(enviroment) - - //stuff in the stomach - //handle_stomach() - - //Status updates, death etc. - handle_regular_status_updates() - update_canmove() - - // Grabbing - for(var/obj/item/weapon/grab/G in src) - G.process() - //some kind of bug in canmove() isn't properly calling update_icons, so this is here as a placeholder update_icons() - if(client) - handle_regular_hud_updates() - -/mob/living/carbon/alien/larva/proc/handle_regular_status_updates() +/mob/living/carbon/alien/larva/handle_regular_status_updates() updatehealth() if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP @@ -133,7 +88,7 @@ return 1 -/mob/living/carbon/alien/larva/proc/handle_regular_hud_updates() +/mob/living/carbon/alien/larva/handle_regular_hud_updates() if (stat == 2 || (XRAY in mutations)) sight |= SEE_TURFS @@ -210,7 +165,4 @@ if(!client.adminobs) reset_view(null) - return 1 - -/mob/living/carbon/alien/larva/proc/handle_random_events() - return + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 58f43b525b3..ffd8c3bca5e 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -1,4 +1,17 @@ -/mob/living/carbon/alien/proc/handle_chemicals_in_body() +/mob/living/carbon/alien/Life() + if(..()) + //First, resolve location and get a breath + if(mob_master.current_cycle%4==2) + //Only try to take a breath every 4 seconds, unless suffocating + spawn(0) breathe() + + else //Still give containing object the chance to interact + if(istype(loc, /obj/)) + var/obj/location_as_object = loc + location_as_object.handle_internal_lifeform(src, 0) + return 1 + +/mob/living/carbon/alien/handle_chemicals_in_body() if(reagents) reagents.metabolize(src) @@ -102,21 +115,4 @@ //Temporary fixes to the alerts. - return 1 - -/mob/living/carbon/alien/proc/handle_stomach() - spawn(0) - for(var/mob/living/M in stomach_contents) - if(M.loc != src) - stomach_contents.Remove(M) - continue - if(istype(M, /mob/living/carbon) && stat != 2) - if(M.stat == 2) - M.death(1) - stomach_contents.Remove(M) - qdel(M) - continue - if(mob_master.current_cycle%3==1) - if(!(M.status_flags & GODMODE)) - M.adjustBruteLoss(5) - nutrition += 10 + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 606959d5de8..0cfa62d008f 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -1,39 +1,5 @@ -/mob/living/carbon/brain/Life() - set invisibility = 0 - //set background = 1 - ..() - - if(stat != DEAD) - //Mutations and radiation - handle_mutations_and_radiation() - - //Chemicals in the body - handle_chemicals_in_body() - - var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE - if(loc) - environment = loc.return_air() - - //Apparently, the person who wrote this code designed it so that - //blinded get reset each cycle and then get activated later in the - //code. Very ugly. I dont care. Moving this stuff here so its easy - //to find it. - blinded = null - - //Handle temperature/pressure differences between body and environment - if(environment) // More error checking -- TLE - handle_environment(environment) - - //Status updates, death etc. - handle_regular_status_updates() - update_canmove() - - if(client) - handle_regular_hud_updates() - - /mob/living/carbon/brain/ - proc/handle_mutations_and_radiation() + handle_mutations_and_radiation() if (radiation) if (radiation > 100) @@ -68,7 +34,7 @@ adjustToxLoss(3) updatehealth() - proc/handle_environment(datum/gas_mixture/environment) + handle_environment(datum/gas_mixture/environment) if(!environment) return var/environment_heat_capacity = environment.heat_capacity() @@ -104,7 +70,7 @@ - proc/handle_chemicals_in_body() + handle_chemicals_in_body() if(reagents) reagents.metabolize(src) @@ -120,7 +86,7 @@ return //TODO: DEFERRED - proc/handle_regular_status_updates() //TODO: comment out the unused bits >_> + handle_regular_status_updates() //TODO: comment out the unused bits >_> updatehealth() if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP @@ -191,7 +157,7 @@ return 1 - proc/handle_regular_hud_updates() + handle_regular_hud_updates() if (stat == 2 || (XRAY in src.mutations)) sight |= SEE_TURFS diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 39a946c6a7d..21cd55e47ba 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -84,6 +84,9 @@ if(stat == DEAD) return if(healths) healths.icon_state = "health5" + if(!gibbed) + emote("deathgasp") //let the world KNOW WE ARE DEAD + stat = DEAD dizziness = 0 jitteriness = 0 @@ -128,8 +131,6 @@ H.mind.kills += "[name] ([ckey])" if(!gibbed) - emote("deathgasp") //let the world KNOW WE ARE DEAD - update_canmove() if(client) blind.layer = 0 @@ -179,4 +180,4 @@ /mob/living/carbon/human/proc/Drain() ChangeToHusk() mutations |= NOCLONE - return + return diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 0bac4c222e9..16a9ca22837 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -1,4 +1,8 @@ /mob/living/carbon/human/emote(var/act,var/m_type=1,var/message = null,var/force) + + if (stat == DEAD) + return // No screaming bodies + var/param = null if (findtext(act, "-", 1, null)) var/t1 = findtext(act, "-", 1, null) @@ -814,4 +818,4 @@ set desc = "Sets an extended description of your character's features." set category = "IC" - flavor_text = TextPreview(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text) + flavor_text = TextPreview(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index eb53f62a774..c6513be0799 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -73,6 +73,7 @@ var/mob/remoteview_target = null var/meatleft = 3 //For chef item var/decaylevel = 0 // For rotting bodies + var/max_blood = 560 // For stuff in the vessel var/slime_color = "blue" //For slime people this defines their color, it's blue by default to pay tribute to the old icons var/check_mutations=0 // Check mutations on next life tick diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index dbb12594803..9173803926e 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -43,27 +43,9 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc var/tinttotal = 0 // Total level of visually impairing items /mob/living/carbon/human/Life() - set invisibility = 0 - //set background = 1 - - if (notransform) return - if(!loc) return // Fixing a null error that occurs when the mob isn't found in the world -- TLE - - ..() - - //Apparently, the person who wrote this code designed it so that - //blinded get reset each cycle and then get activated later in the - //code. Very ugly. I dont care. Moving this stuff here so its easy - //to find it. - blinded = null fire_alert = 0 //Reset this here, because both breathe() and handle_environment() have a chance to set it. tinttotal = tintcheck() //here as both hud updates and status updates call it - - //TODO: seperate this out - // update the current life tick, can be used to e.g. only do something every 4 ticks - life_tick++ - - var/datum/gas_mixture/environment = loc.return_air() + life_tick++ in_stasis = 0 if(istype(loc, /obj/structure/closet/body_bag/cryobag)) @@ -72,13 +54,12 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc loc_as_cryobag.used++ in_stasis = 1 - if(life_tick % 30 == 15) + if(mob_master.current_cycle % 30 == 15) hud_updateflag = 1022 voice = GetVoice() - //No need to update all of these procs if the guy is dead. - if(stat != DEAD && !in_stasis) + if(..() && !in_stasis) if(mob_master.current_cycle % 4 == 2 || failed_last_breath) //First, resolve location and get a breath breathe() //Only try to take a breath every 4 ticks, unless suffocating @@ -88,43 +69,15 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc location_as_object.handle_internal_lifeform(src, 0) if(check_mutations) -// testing("Updating [src.real_name]'s mutations: "+english_list(mutations)) domutcheck(src,null) update_mutations() check_mutations=0 - //Updates the number of stored chemicals for powers - handle_changeling() - - //Mutations and radiation - handle_mutations_and_radiation() - - //Chemicals in the body - handle_chemicals_in_body() - - //Disabilities - handle_disabilities() - - //Random events (vomiting etc) - handle_random_events() - handle_virus_updates() - //Check if we're on fire - handle_fire() - - //Decrease wetness over time - handle_wetness() - - //stuff in the stomach - handle_stomach() - handle_shock() - handle_pain() - handle_heartbeat() - handle_heartattack() if(!client) @@ -138,28 +91,10 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc 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. - - //Handle temperature/pressure differences between body and environment - handle_environment(environment) //Optimized a good bit. - - //Status updates, death etc. - handle_regular_status_updates() //Optimized a bit - - handle_actions() - - update_canmove() - //Update our name based on whether our face is obscured/disfigured name = get_visible_name() - - handle_regular_hud_updates() - pulse = handle_pulse() - // Grabbing - for(var/obj/item/weapon/grab/G in src) - G.process() - if(mind && mind.vampire) handle_vampire() if(life_tick == 1) @@ -181,7 +116,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc return ONE_ATMOSPHERE - pressure_difference -/mob/living/carbon/human/proc/handle_disabilities() +/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!") @@ -246,7 +181,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc // as cloneloss adjustCloneLoss(0.1) -/mob/living/carbon/human/proc/handle_mutations_and_radiation() +/mob/living/carbon/human/handle_mutations_and_radiation() if(getFireLoss()) if((RESIST_HEAT in mutations) || (prob(1))) heal_organ_damage(0,1) @@ -469,7 +404,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc return species.handle_breath(breath, src) -/mob/living/carbon/human/proc/handle_environment(datum/gas_mixture/environment) +/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment) if(!environment) return @@ -578,11 +513,6 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc return //END FIRE CODE -/mob/living/carbon/human/proc/handle_wetness() - if(mob_master.current_cycle%20==2) //dry off a bit once every 20 ticks or so - wetlevel = max(wetlevel - 1,0) - return - /* /mob/living/carbon/human/proc/adjust_body_temperature(current, loc_temp, boost) var/temperature = current @@ -755,7 +685,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc return covered -/mob/living/carbon/human/proc/handle_chemicals_in_body() +/mob/living/carbon/human/handle_chemicals_in_body() if(reagents) reagents.metabolize(src) @@ -869,7 +799,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc return //TODO: DEFERRED -/mob/living/carbon/human/proc/handle_regular_status_updates() +/mob/living/carbon/human/handle_regular_status_updates() if(status_flags & GODMODE) return 0 @@ -977,7 +907,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(halloss > 0) adjustHalLoss(-1) - if(embedded_flag && !(life_tick % 10)) + if(embedded_flag && !(mob_master.current_cycle % 10)) var/list/E E = get_visible_implants(0) if(!E.len) @@ -1081,7 +1011,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc return 1 -/mob/living/carbon/human/proc/handle_regular_hud_updates() +/mob/living/carbon/human/handle_regular_hud_updates() if(hud_updateflag) handle_hud_list() @@ -1433,7 +1363,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc reset_view(null) return 1 -/mob/living/carbon/human/proc/handle_random_events() +/mob/living/carbon/human/handle_random_events() // Puke if toxloss is too high if(!stat) if (getToxLoss() >= 45 && nutrition > 20) @@ -1478,7 +1408,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc for (var/ID in virus2) var/datum/disease2/disease/V = virus2[ID] V.cure(src) - if(life_tick % 3) //don't spam checks over all objects in view every tick. + if(mob_master.current_cycle % 3) //don't spam checks over all objects in view every tick. for(var/obj/effect/decal/cleanable/O in view(1,src)) if(istype(O,/obj/effect/decal/cleanable/blood)) var/obj/effect/decal/cleanable/blood/B = O @@ -1509,24 +1439,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc V.dead = 1 return -/mob/living/carbon/human/proc/handle_stomach() - spawn(0) - for(var/mob/living/M in stomach_contents) - if(M.loc != src) - stomach_contents.Remove(M) - continue - if(isliving(M) && stat != 2) - if(M.stat == 2) - M.death(1) - stomach_contents.Remove(M) - qdel(M) - continue - if(mob_master.current_cycle%3==1) - if(!(M.status_flags & GODMODE)) - M.adjustBruteLoss(5) - nutrition += 10 - -/mob/living/carbon/human/proc/handle_changeling() +/mob/living/carbon/human/handle_changeling() if(mind && mind.changeling) mind.changeling.regenerate() @@ -1582,7 +1495,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc /mob/living/carbon/human/proc/handle_pulse() - if(life_tick % 5) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load) + if(mob_master.current_cycle % 5) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load) if(species && species.flags & NO_BLOOD) return PULSE_NONE //No blood, no pulse. diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 8397ca9b043..11b99dc2782 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -11,4 +11,115 @@ else if (internals) internals.icon_state = "internal0" - return null \ No newline at end of file + return + +/mob/living/carbon/Life() + set invisibility = 0 + set background = BACKGROUND_ENABLED + + if(notransform) + return + if(!loc) + return + var/datum/gas_mixture/environment = loc.return_air() + + //Handle temperature/pressure differences between body and environment + handle_environment(environment) + + //Apparently, the person who wrote this code designed it so that + //blinded get reset each cycle and then get activated later in the + //code. Very ugly. I dont care. Moving this stuff here so its easy + //to find it. + blinded = null + + handle_regular_status_updates() // Status updates, death etc. + + if(stat != DEAD) + + //Updates the number of stored chemicals for powers + handle_changeling() + + //Mutations and radiation + handle_mutations_and_radiation() + + //Chemicals in the body + handle_chemicals_in_body() + + //Disabilities + handle_disabilities() + + //Random events (vomiting etc) + handle_random_events() + + . = 1 + + handle_fire() + + //Decrease wetness over time + handle_wetness() + + //stuff in the stomach + handle_stomach() + + update_canmove() + + update_gravity(mob_has_gravity()) + + for(var/obj/item/weapon/grab/G in src) + G.process() + + handle_actions() + + if(client) + handle_regular_hud_updates() + + return . + + + +//remember to remove the "proc" of the child procs of these. + +/mob/living/carbon/proc/handle_changeling() + return + +/mob/living/carbon/proc/handle_mutations_and_radiation() + return + +/mob/living/carbon/proc/handle_chemicals_in_body() + return + +/mob/living/carbon/proc/handle_disabilities() + return + +/mob/living/carbon/proc/handle_random_events() + return + +/mob/living/carbon/proc/handle_environment(var/datum/gas_mixture/environment) + return + +/mob/living/carbon/proc/handle_regular_status_updates() + return + +/mob/living/carbon/proc/handle_wetness() + if(mob_master.current_cycle%20==2) //dry off a bit once every 20 ticks or so + wetlevel = max(wetlevel - 1,0) + +/mob/living/carbon/proc/handle_stomach() + spawn(0) + for(var/mob/living/M in stomach_contents) + if(M.loc != src) + stomach_contents.Remove(M) + continue + if(istype(M, /mob/living/carbon) && stat != 2) + if(M.stat == 2) + M.death(1) + stomach_contents.Remove(M) + qdel(M) + continue + if(mob_master.current_cycle%3==1) + if(!(M.status_flags & GODMODE)) + M.adjustBruteLoss(5) + nutrition += 10 + +/mob/living/carbon/proc/handle_regular_hud_updates() + return diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index 05e078553a8..b70075a084b 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -6,46 +6,12 @@ var/SStun = 0 // stun variable /mob/living/carbon/slime/Life() - set invisibility = 0 - //set background = 1 - - if (src.notransform) - return - - ..() - - if(stat != DEAD) - //Chemicals in the body - handle_chemicals_in_body() - + if(..()) handle_nutrition() - handle_targets() - if (!ckey) handle_speech_and_mood() - var/datum/gas_mixture/environment - if(src.loc) - environment = loc.return_air() - - //Apparently, the person who wrote this code designed it so that - //blinded get reset each cycle and then get activated later in the - //code. Very ugly. I dont care. Moving this stuff here so its easy - //to find it. - src.blinded = null - - regular_hud_updates() // Basically just deletes any screen objects :< - - if(environment) - handle_environment(environment) // Handle temperature/pressure differences between body and environment - - handle_regular_status_updates() // Status updates, death etc. - - handle_actions() - - handle_wetness() - /mob/living/carbon/slime/proc/AIprocess() // the master AI process if(AIproc || stat == DEAD || client) return @@ -126,7 +92,7 @@ AIproc = 0 -/mob/living/carbon/slime/proc/handle_environment(datum/gas_mixture/environment) +/mob/living/carbon/slime/handle_environment(datum/gas_mixture/environment) if(!environment) adjustToxLoss(rand(10,20)) return @@ -141,7 +107,7 @@ loc_temp = loc:air_contents.temperature else loc_temp = environment.temperature - + //Account for massive pressure differences if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc if(bodytemperature <= (T0C - 40)) // stun temperature @@ -154,7 +120,7 @@ adjustToxLoss(round(sqrt(bodytemperature)) * 2) else Tempstun = 0 - + /*moved after the temperature damage code so freeze beams can instantly kill slimes -Deity Link*/ if(loc_temp < 310.15) // a cold place @@ -183,7 +149,7 @@ temp_change = (temperature - current) return temp_change -/mob/living/carbon/slime/proc/handle_chemicals_in_body() +/mob/living/carbon/slime/handle_chemicals_in_body() if(reagents) reagents.metabolize(src) if (reagents.get_reagent_amount("plasma")>=5) @@ -196,7 +162,7 @@ return //TODO: DEFERRED -/mob/living/carbon/slime/proc/handle_regular_status_updates() +/mob/living/carbon/slime/handle_regular_status_updates() if(is_adult) health = 200 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) @@ -289,10 +255,6 @@ else Evolve() -/mob/living/carbon/slime/proc/handle_wetness() - if(mob_master.current_cycle%20==2) //dry off a bit once every 20 ticks or so - wetlevel = max(wetlevel - 1,0) - return /mob/living/carbon/slime/proc/handle_targets() if(Tempstun) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3d7f30d87ff..9806145854b 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -890,11 +890,15 @@ /mob/living/proc/float(on) if(throwing) return - if(on && !floating) - animate(src, pixel_y = 2, time = 10, loop = -1) + var/fixed = 0 + if(anchored || (buckled && buckled.anchored)) + fixed = 1 + if(on && !floating && !fixed) + animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1) floating = 1 - else if(!on && floating) - animate(src, pixel_y = initial(pixel_y), time = 10) + else if(((!on || fixed) && floating)) + var/final_pixel_y = get_standard_pixel_y_offset(lying) + animate(src, pixel_y = final_pixel_y, time = 10) floating = 0 /mob/living/proc/can_use_vents() diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 40facde6f9c..06698318f44 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -12,6 +12,8 @@ src.updatehealth() + update_gravity(mob_has_gravity()) + if (src.malfhack) if (src.malfhack.aidisabled) src << "\red ERROR: APC access disabled, hack attempt canceled." @@ -174,7 +176,7 @@ sleep(50) theAPC = null - process_queued_alarms() + process_queued_alarms() regular_hud_updates() switch(src.sensor_mode) if (SEC_HUD) @@ -191,12 +193,12 @@ health = 100 - getOxyLoss() - getToxLoss() - getBruteLoss() else health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - + /mob/living/silicon/ai/proc/lacks_power() var/turf/T = get_turf(src) var/area/A = get_area(src) return ((!A.power_equip) && A.requires_power == 1 || istype(T, /turf/space)) && !istype(src.loc,/obj/item) - + /mob/living/silicon/ai/rejuvenate() ..() add_ai_verbs(src) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index c8c9c8c37c0..ae8f7da7d4c 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -88,10 +88,9 @@ return /mob/living/simple_animal/Life() - if(paralysis || stunned || weakened || buckled || resting) - canmove = 0 - else - canmove = 1 + + update_gravity(mob_has_gravity()) + update_canmove() //Health if(stat == DEAD) @@ -554,4 +553,28 @@ if(speak_emote.len) verb = pick(speak_emote) - return verb \ No newline at end of file + return verb + +/mob/living/simple_animal/update_canmove() + if(paralysis || stunned || weakened || stat || resting) + drop_r_hand() + drop_l_hand() + canmove = 0 + else if(buckled) + canmove = 0 + else + canmove = 1 + update_transform() + return canmove + +/mob/living/simple_animal/update_transform() + var/matrix/ntransform = matrix(transform) //aka transform.Copy() + var/changed = 0 + + if(resize != RESIZE_DEFAULT_SIZE) + changed++ + ntransform.Scale(resize) + resize = RESIZE_DEFAULT_SIZE + + if(changed) + animate(src, transform = ntransform, time = 2, easing = EASE_IN|EASE_OUT) \ No newline at end of file diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index febe62ba4e8..0fd9804bd46 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -781,6 +781,36 @@ icon_state = "vox_keetquills" species_allowed = list("Vox") + vox_quills_kingly + name = "Kingly Vox Quills" + icon_state = "vox_kingly" + species_allowed = list("Vox") + + vox_quills_fluff + name = "Fluffy Quills" + icon_state = "vox_afro" + species_allowed = list("Vox") + + vox_quills_mohawk + name = "Quill Mohawk" + icon_state = "vox_mohawk" + species_allowed = list("Vox") + + vox_quills_long + name = "Long Vox Quills" + icon_state = "vox_yasu" + species_allowed = list("Vox") + + vox_horns + name = "Vox Spikes" + icon_state = "vox_horns" + species_allowed = list("Vox") + + vox_nights + name = "Vox Pigtails" + icon_state = "vox_nights" + species_allowed = list("Vox") + // Apollo-specific //Wryn antennae @@ -855,10 +885,31 @@ species_allowed = list("Tajaran") taj_smallstache - name = "Tajara Smallsatche" + name = "Tajara Smallstache" icon_state = "facial_smallstache" species_allowed = list("Tajaran") + vox_colonel + name = "Vox Colonel Beard" + icon_state = "vox_colonel" + species_allowed = list("Vox") + + vox_long + name = "Long Mustache" + icon_state = "vox_fu" + species_allowed = list("Vox") + + vox_neck + name = "Neck Quills" + icon_state = "vox_neck" + species_allowed = list("Vox") + + vox_beard + name = "Vox Quill Beard" + icon_state = "vox_beard" + species_allowed = list("Vox") + + //Vulpkanin vulp_blaze diff --git a/code/modules/reagents/Chemistry-Readme.dm b/code/modules/reagents/Chemistry-Readme.dm index 77921d0ab07..61e2a0c82a0 100644 --- a/code/modules/reagents/Chemistry-Readme.dm +++ b/code/modules/reagents/Chemistry-Readme.dm @@ -98,6 +98,9 @@ About the Holder: Returns the amount of the matching reagent inside the holder. Returns 0 if the reagent is missing. + overdose_list() + Returns a list of all the chemical IDs in the reagent holder that are overdosing + Important variables: total_volume diff --git a/code/modules/reagents/newchem/newchem_procs.dm b/code/modules/reagents/newchem/newchem_procs.dm index b2d6edc0995..faf530f6b3e 100644 --- a/code/modules/reagents/newchem/newchem_procs.dm +++ b/code/modules/reagents/newchem/newchem_procs.dm @@ -82,6 +82,14 @@ datum/reagents/proc/metabolize(var/mob/M) addiction_tick++ update_total() +/datum/reagents/proc/overdose_list() + var/od_chems[0] + for(var/datum/reagent/R in reagent_list) + if(R.overdosed) + od_chems.Add(R.id) + return od_chems + + datum/reagents/proc/reagent_on_tick() for(var/datum/reagent/R in reagent_list) R.on_tick() diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index cc0fcbf3e09..fc720126d47 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 7d24d3ceadb..b7ebe8a9c6e 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/nano/css/shared.css b/nano/css/shared.css index 786b577e615..b9ceac02814 100644 --- a/nano/css/shared.css +++ b/nano/css/shared.css @@ -606,4 +606,29 @@ th.misc { .Pearl { color: #C6CACB; +} + +/* Status bar colors for sleeper temperatures */ +.cold1 { + color: #94B8FF; +} + +.cold2 { + color: #6699FF; +} + +.cold3 { + color: #293D66; +} + +.hot1 { + color: #FF9966; +} + +.hot2 { + color: #993D00; +} + +.hot3 { + color: #FF6600; } \ No newline at end of file diff --git a/nano/templates/adv_med.tmpl b/nano/templates/adv_med.tmpl new file mode 100644 index 00000000000..92049364561 --- /dev/null +++ b/nano/templates/adv_med.tmpl @@ -0,0 +1,308 @@ + +{{if !data.occupied}} +

No occupant detected.

+{{else}} +

Occupant Data:

+
+
+ Name: +
+
+ {{:data.occupant.name}} +
+
+
+
+ Health: +
+ {{:helper.displayBar(data.occupant.health, 0, 100, (data.occupant.health >= 50) ? 'good' : (data.occupant.health >= 25) ? 'average' : 'bad')}} +
+ {{:helper.round(data.occupant.health*10)/10}}% +
+
+
+ Status: +
+
+ {{if data.occupant.stat==0}} + Alive + {{else data.occupant.stat==1}} + Critical + {{else}} + Dead + {{/if}} +
+
+ {{:helper.link('Print', 'document', {'print_p' : 1, 'name' : data.occupant.name})}} +
+

Damage:

+
+ Brute: +
+
+ {{:data.occupant.bruteLoss}} +

+
+ Burn: +
+
+ {{:data.occupant.fireLoss}} +

+
+ Oxygen: +
+
+ {{:data.occupant.oxyLoss}} +

+
+ Toxins: +
+
+ {{:data.occupant.toxLoss}} +

+
+ Brain: +
+
+ {{:data.occupant.brainLoss}} +

+
+ Radiation Level: +
+
+ {{:data.occupant.radLoss}} +

+
+ Genetic: +
+
+ {{:data.occupant.cloneLoss}} +

+
+ Paralysis: +
+
+ {{:data.occupant.paralysis}}% ({{:data.occupant.paralysisSeconds}} seconds left!) +

+
+
+
+ Body Temperature: +
+
+ {{:data.occupant.bodyTempC}}°C, {{:data.occupant.bodyTempF}}°F +
+
+ {{if data.occupant.hasVirus}} +
+ Viral pathogen detected in blood stream. +
+ {{/if}} + {{if data.occupant.hasBorer}} +
+ Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended. +
+ {{/if}} + {{if data.occupant.blind}} + Pupils unresponsive.
+ {{/if}} + {{if data.occupant.nearsighted}} + Retinal Misalignment Detected + {{/if}} +
+
+ Blood +
+ Volume +
+
+ {{:data.occupant.blood.volume}} +
+
+ Percent +
+
+ {{:data.occupant.blood.percent}}% +
+
+
+
+ Reagents +
+ Epinephrine +
+
+ {{:data.occupant.reagents.epinephrine}} +
+
+ Ether +
+
+ {{:data.occupant.reagents.ether}} +
+
+ + Silver Sulfadiazine + +
+
+ + {{:data.occupant.reagents.silver_sulfadiazine}} + +
+
+ + Styptic Powder + +
+
+ + {{:data.occupant.reagents.styptic_powder}} + +
+
+ + Salbutamol + +
+
+ + {{:data.occupant.reagents.salbutamol}} + +
+
+
+ External Organs +
+ {{for data.occupant.extOrgan}} +
+ {{if value.status.destroyed}} +
+ {{:value.name}} - DESTROYED +
+ {{else}} +
+ {{:value.name}} +
+
+ {{if value.status.broken}} + {{:value.status.broken}} + {{else value.status.splinted}} + Splinted + {{else value.status.robotic}} + Robotic + {{/if}} +
+
+  Brute/Burn +
+
+ {{:value.bruteLoss}}/{{:value.fireLoss}} +
+
+  Injuries +
+
+ {{if !value.status.bleeding}} + {{if !value.status.internalBleeding}} + No Injuries Detected + {{else}} + Internal Bleeding Detected + {{/if}} + {{else}} + {{if value.status.internalBleeding}} +
Internal Bleeding Detected. External Bleeding Detected.
+ {{else}} + External Bleeding Detected + {{/if}} + {{/if}} +
+ {{if value.germ_level > 100}} +
+  Infection +
+
+ {{if value.germ_level < 300}} + Mild Infection + {{else value.germ_level < 400}} + Mild Infection+ + {{else value.germ_level < 500}} + Mild Infection++ + {{else value.germ_level < 700}} + Acute Infection + {{else value.germ_level < 800}} + Acute Infection+ + {{else value.germ_level < 900}} + Acute Infection++ + {{else value.germ_level >= 900}} + Septic + {{/if}} +
+ {{/if}} + {{if value.open}} +
+  Operation Status +
+
+ Open Incision +
+ {{/if}} + {{if value.implants_len}} +
+  Implants +

+ {{for value.implants :impValue:impindex}} +
+   {{:impValue.known ? impValue.name : "Unknown"}} +

+ {{/for}} + {{/if}} + {{/if}} +

+ {{/for}} +
+ Internal Organs +
+ {{for data.occupant.intOrgan}} +
+
+ {{:value.name}} +
+
+ {{:value.desc != null ? value.desc : ""}} +
+ {{if value.germ_level > 100}} +
+  Infection +
+
+ {{if value.germ_level < 300}} + Mild Infection + {{else value.germ_level < 400}} + Mild Infection+ + {{else value.germ_level < 500}} + Mild Infection++ + {{else value.germ_level < 700}} + Acute Infection + {{else value.germ_level < 800}} + Acute Infection+ + {{else value.germ_level < 900}} + Acute Infection++ + {{else value.germ_level >= 900}} + Septic + {{/if}} +
+ {{/if}} +
+  Damage +
+
+ {{:value.damage}} +
+
+ {{/for}} +
+{{/if}} \ No newline at end of file diff --git a/nano/templates/pda.tmpl b/nano/templates/pda.tmpl index 753e06f299e..4f74a358930 100644 --- a/nano/templates/pda.tmpl +++ b/nano/templates/pda.tmpl @@ -69,6 +69,14 @@ Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm margin: 0 2px 2px 0; } + .uiIcon16 { + background-image: none; + float: left; + width: auto; + height: auto; + margin: 0 0 0 0; + } + #uiTitleText { color: #000000; } @@ -307,7 +315,7 @@ Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm

Current Conversations

{{for data.convopdas}}
- {{:helper.link(value.Name, 'circle-arrow-s', {'choice' : "Select Conversation", 'convo' : value.Reference } , null, 'pdalink fixedLeftWider')}} + {{:helper.link(value.Name, 'circle-arrow-s', {'choice' : "Select Conversation", 'convo' : value.Reference } , null, 'pdalink')}} {{if data.cartridge}} {{if data.cartridge.access.access_detonate_pda && value.Detonate}} {{:helper.link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : value.Reference}, null, 'pdalink fixedLeft')}} @@ -324,7 +332,7 @@ Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm

Other PDAs

{{for data.pdas}}
- {{:helper.link(value.Name, 'circle-arrow-s', {'choice' : "Message", 'target' : value.Reference}, null, 'pdalink fixedLeftWider')}} + {{:helper.link(value.Name, 'circle-arrow-s', {'choice' : "Message", 'target' : value.Reference}, null, 'pdalink')}} {{if data.cartridge}} {{if data.cartridge.access.access_detonate_pda && value.Detonate}} {{:helper.link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : value.Reference}, null, 'pdalink fixedLeft')}} {{/if}} {{if data.cartridge.access.access_clown}} {{:helper.link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : value.Reference}, null, 'pdalink fixedLeft')}} {{/if}} diff --git a/nano/templates/sleeper.tmpl b/nano/templates/sleeper.tmpl new file mode 100644 index 00000000000..8cd59a4e4b9 --- /dev/null +++ b/nano/templates/sleeper.tmpl @@ -0,0 +1,201 @@ + +

Sleeper Status

+ +
+ {{if !data.hasOccupant}} +
Sleeper Unoccupied
+ {{else}} +
+ {{:data.occupant.name}} =>  + {{if data.occupant.stat == 0}} + Conscious + {{else data.occupant.stat == 1}} + Unconscious + {{else}} + DEAD + {{/if}} +
+ +
+
Health:
+ {{if data.occupant.health >= data.occupant.maxHealth}} + {{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, 'good')}} + {{else data.occupant.health > 0}} + {{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, 'average')}} + {{else data.occupant.health >= data.minhealth}} + {{:helper.displayBar(data.occupant.health, 0, data.occupant.minHealth, 'average alignRight')}} + {{else}} + {{:helper.displayBar(data.occupant.health, 0, data.occupant.minHealth, 'bad alignRight')}} + {{/if}} +
{{:helper.round(data.occupant.health)}}
+
+ +
+
=> Brute Damage:
+ {{:helper.displayBar(data.occupant.bruteLoss, 0, data.occupant.maxHealth, 'bad')}} +
{{:helper.round(data.occupant.bruteLoss)}}
+
+ +
+
=> Resp. Damage:
+ {{:helper.displayBar(data.occupant.oxyLoss, 0, data.occupant.maxHealth, 'bad')}} +
{{:helper.round(data.occupant.oxyLoss)}}
+
+ +
+
=> Toxin Damage:
+ {{:helper.displayBar(data.occupant.toxLoss, 0, data.occupant.maxHealth, 'bad')}} +
{{:helper.round(data.occupant.toxLoss)}}
+
+ +
+
=> Burn Severity:
+ {{:helper.displayBar(data.occupant.fireLoss, 0, data.occupant.maxHealth, 'bad')}} +
{{:helper.round(data.occupant.fireLoss)}}
+
+ +
+
+ +
Patient Temperature:
+ {{if data.occupant.temperatureSuitability == -3}} + {{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'bad')}} +
{{:helper.round(data.occupant.btCelsius)}}°C, {{:helper.round(data.occupant.btFaren)}}°F
+ {{else data.occupant.temperatureSuitability == -2}} + {{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}} +
{{:helper.round(data.occupant.btCelsius)}}°C, {{:helper.round(data.occupant.btFaren)}}°F
+ {{else data.occupant.temperatureSuitability == -1}} + {{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}} +
{{:helper.round(data.occupant.btCelsius)}}°C, {{:helper.round(data.occupant.btFaren)}}°F
+ {{else data.occupant.temperatureSuitability == 0}} + {{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'good')}} +
{{:helper.round(data.occupant.btCelsius)}}°C, {{:helper.round(data.occupant.btFaren)}}°F
+ {{else data.occupant.temperatureSuitability == 1}} + {{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}} +
{{:helper.round(data.occupant.btCelsius)}}°C, {{:helper.round(data.occupant.btFaren)}}°F
+ {{else data.occupant.temperatureSuitability == 2}} + {{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}} +
{{:helper.round(data.occupant.btCelsius)}}°C, {{:helper.round(data.occupant.btFaren)}}°F
+ {{else data.occupant.temperatureSuitability == 3}} + {{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'bad')}} +
{{:helper.round(data.occupant.btCelsius)}}°C, {{:helper.round(data.occupant.btFaren)}}°F
+ {{/if}} +
+ + + {{if data.occupant.hasBlood}} + +
+
+
Pulse:
{{:data.occupant.pulse}} bpm
+
+
+
Blood Level:
+ {{if data.occupant.bloodPercent <= 60}} + {{:helper.displayBar(data.occupant.bloodLevel, 0, data.occupant.bloodMax, 'bad')}} +
+ {{:data.occupant.bloodPercent}}%, {{:data.occupant.bloodLevel}}cl +
+ {{else data.occupant.bloodPercent <= 90}} + {{:helper.displayBar(data.occupant.bloodLevel, 0, data.occupant.bloodMax, 'average')}} +
+ {{:data.occupant.bloodPercent}}%, {{:data.occupant.bloodLevel}}cl +
+ {{else}} + {{:helper.displayBar(data.occupant.bloodLevel, 0, data.occupant.bloodMax, 'good')}} +
+ {{:data.occupant.bloodPercent}}%, {{:data.occupant.bloodLevel}}cl +
+ {{/if}} +
+ {{/if}} + {{/if}} +
+ +

Sleeper Operation

+
+
+ Sleeper Status: +
+
+ {{:helper.link('Eject Occupant', 'arrowreturnthick-1-s', {'ejectify' : 1}, data.hasOccupant ? null : 'disabled')}} +
+
+
 
+
+
+ Dialysis Beaker: +
+
+ {{if data.isBeakerLoaded}} + {{:helper.round(data.beakerFreeSpace)}} units of space remaining
+ {{else}} + No Dialysis Output Beaker Loaded + {{/if}} +
+
+ {{:helper.link('Eject Beaker', 'eject', {'removebeaker' : 1}, data.isBeakerLoaded ? null : 'disabled')}} + {{if data.isBeakerLoaded}} +
+
+ {{:helper.link('On', 'power', {'togglefilter' : 1}, data.occupant.hasBlood ? (data.dialysis ? 'selected' : null) : 'disabled')}}{{:helper.link('Off', 'close', {'togglefilter' : 1}, data.dialysis ? null : 'selected')}} +
+
+ {{/if}} +
+
+
+
+ Chemicals: +
+ + {{for data.chemicals}} +
+ {{:value.title}}: + {{if value.overdosing}} + {{:helper.displayBar(value.occ_amount, 0, data.maxchem, 'bad')}} + {{else value.od_warning}} + {{:helper.displayBar(value.occ_amount, 0, data.maxchem, 'average')}} + {{else}} + {{:helper.displayBar(value.occ_amount, 0, data.maxchem, 'good')}} + {{/if}} +
{{:value.pretty_amount}}/{{:data.maxchem}}
+
+
+
+ {{:helper.link('5', 'gear', {'chemical' : value.id, 'amount' : 5}, (!value.injectable || ((value.occ_amount + 5) > data.maxchem)) ? 'disabled' : null)}} + {{:helper.link('10', 'gear', {'chemical' : value.id, 'amount' : 10}, (!value.injectable || ((value.occ_amount + 10) > data.maxchem)) ? 'disabled' : null)}} +
+
+ {{/for}} +
+