This commit is contained in:
Ghommie
2019-10-17 00:50:30 +02:00
539 changed files with 63595 additions and 58228 deletions
+1
View File
@@ -89,6 +89,7 @@
buckled_mob.clear_alert("buckled")
buckled_mobs -= buckled_mob
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force)
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, src, force)
post_unbuckle_mob(.)
@@ -288,7 +288,7 @@
contained = "\[[contained]\]"
var/where = "[AREACOORD(location)]"
if(carry.my_atom.fingerprintslast)
if(carry.my_atom && carry.my_atom.fingerprintslast)
var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast)
var/more = ""
if(M)
+6 -6
View File
@@ -421,10 +421,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
//the mob M is attempting to equip this item into the slot passed through as 'slot'. Return 1 if it can do this and 0 if it can't.
//if this is being done by a mob other than M, it will include the mob equipper, who is trying to equip the item to mob M. equipper will be null otherwise.
//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen.
//Set disable_warning to 1 if you wish it to not give you outputs.
//Set disable_warning to TRUE if you wish it to not give you outputs.
/obj/item/proc/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
if(!M)
return 0
return FALSE
return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self)
@@ -514,12 +514,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
log_combat(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])")
M.adjust_blurriness(3)
M.adjust_eye_damage(rand(2,4))
var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return
if(eyes.eye_damage >= 10)
M.adjust_blurriness(3)
eyes.applyOrganDamage(rand(2,4))
if(eyes.damage >= 10)
M.adjust_blurriness(15)
if(M.stat != DEAD)
to_chat(M, "<span class='danger'>Your eyes start to bleed profusely!</span>")
@@ -533,7 +533,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.adjust_blurriness(10)
M.Unconscious(20)
M.Knockdown(40)
if (prob(eyes.eye_damage - 10 + 1))
if (prob(eyes.damage - 10 + 1))
M.become_blind(EYE_DAMAGE)
to_chat(M, "<span class='danger'>You go blind!</span>")
+7 -6
View File
@@ -17,26 +17,27 @@
/obj/item/organ/body_egg/Insert(var/mob/living/carbon/M, special = 0)
..()
ADD_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC)
START_PROCESSING(SSobj, src)
owner.med_hud_set_status()
INVOKE_ASYNC(src, .proc/AddInfectionImages, owner)
/obj/item/organ/body_egg/Remove(var/mob/living/carbon/M, special = 0)
STOP_PROCESSING(SSobj, src)
if(owner)
REMOVE_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC)
owner.med_hud_set_status()
INVOKE_ASYNC(src, .proc/RemoveInfectionImages, owner)
..()
/obj/item/organ/body_egg/process()
/obj/item/organ/body_egg/on_death()
. = ..()
if(!owner)
return
if(!(src in owner.internal_organs))
Remove(owner)
return
egg_process()
/obj/item/organ/body_egg/on_life()
. = ..()
egg_process()
/obj/item/organ/body_egg/proc/egg_process()
return
@@ -59,7 +59,7 @@
name = "Department Management Console (Computer Board)"
build_path = /obj/machinery/computer/card/minor
var/target_dept = 1
var/list/dept_list = list("General","Security","Medical","Science","Engineering")
var/list/dept_list = list("Civilian","Security","Medical","Science","Engineering","Cargo")
/obj/item/circuitboard/computer/card/minor/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/screwdriver))
@@ -399,6 +399,7 @@
/obj/machinery/smartfridge/food = "food",
/obj/machinery/smartfridge/drinks = "drinks",
/obj/machinery/smartfridge/extract = "slimes",
/obj/machinery/smartfridge/organ = "organs",
/obj/machinery/smartfridge/chemistry = "chems",
/obj/machinery/smartfridge/chemistry/virology = "viruses",
/obj/machinery/smartfridge/disks = "disks")
+21 -4
View File
@@ -234,8 +234,13 @@
paint_mode = PAINT_NORMAL
if("select_colour")
if(can_change_colour)
paint_color = input(usr,"","Choose Color",paint_color) as color|null
. = TRUE
var/chosen_colour = input(usr,"","Choose Color",paint_color) as color|null
if (!isnull(chosen_colour))
paint_color = chosen_colour
. = TRUE
else
. = FALSE
if("enter_text")
var/txt = stripped_input(usr,"Choose what to write.",
"Scribbles",default = text_buffer)
@@ -298,9 +303,10 @@
drawing = pick(all_drawables)
var/temp = "rune"
if(is_alpha(drawing))
var/ascii = (length(drawing) == 1) ? TRUE : FALSE
if(ascii && is_alpha(drawing))
temp = "letter"
else if(is_digit(drawing))
else if(ascii && is_digit(drawing))
temp = "number"
else if(drawing in punctuation)
temp = "punctuation mark"
@@ -703,12 +709,18 @@
if(isobj(target))
if(actually_paints)
if(color_hex2num(paint_color) < 350 && !istype(target, /obj/structure/window) && !istype(target, /obj/effect/decal/cleanable/crayon)) //Colors too dark are rejected
to_chat(usr, "<span class='warning'>A color that dark on an object like this? Surely not...</span>")
return FALSE
target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
if(istype(target, /obj/structure/window))
if(color_hex2num(paint_color) < 255)
target.set_opacity(255)
else
target.set_opacity(initial(target.opacity))
. = use_charges(user, 2)
var/fraction = min(1, . / reagents.maximum_volume)
reagents.reaction(target, TOUCH, fraction * volume_multiplier)
@@ -819,6 +831,11 @@
if(user.mind && user.mind.has_antag_datum(/datum/antagonist/gang) || isobserver(user))
to_chat(user, "This spraycan has been specially modified with a stage 2 nozzle kit, making it faster.")
/obj/item/toy/crayon/spraycan/infinite
name = "infinite spraycan"
charges = -1
desc = "Now with 30% more bluespace technology."
#undef RANDOM_GRAFFITI
#undef RANDOM_LETTER
#undef RANDOM_PUNCTUATION
+35 -12
View File
@@ -440,9 +440,20 @@
do_help(H, user)
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H)
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H) //Our code here is different than tg, if it breaks in testing; BUG_PROBABLE_CAUSE
var/obj/item/organ/heart = H.getorgan(/obj/item/organ/heart)
if(H.suiciding || H.hellbound || HAS_TRAIT(H, TRAIT_HUSK))
return
if((world.time - H.timeofdeath) > tlimit)
return
if((H.getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (H.getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE))
return
if(!heart || (heart.organ_flags & ORGAN_FAILING))
return
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
return (!H.suiciding && !(HAS_TRAIT(H, TRAIT_NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || H.suiciding)
return
return TRUE
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
if(req_defib)
@@ -557,14 +568,12 @@
if(do_after(user, primetimer, target = H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
user.visible_message("<span class='notice'>[user] places [src] on [H]'s chest.</span>", "<span class='warning'>You place [src] on [H]'s chest.</span>")
playsound(src, 'sound/machines/defib_charge.ogg', 75, 0)
var/tplus = world.time - H.timeofdeath
// past this much time the patient is unrecoverable
// (in deciseconds)
// brain damage starts setting in on the patient after
// some time left rotting
// patients rot when they are killed, and die when they are dead
var/tplus = world.time - H.timeofdeath //length of time spent dead
var/tloss = deathtimer
var/total_burn = 0
var/total_brute = 0
var/obj/item/organ/heart = H.getorgan(/obj/item/organ/heart)
if(do_after(user, primetimer2, target = H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
for(var/obj/item/carried_item in H.contents)
if(istype(carried_item, /obj/item/clothing/suit/space))
@@ -589,16 +598,26 @@
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existence. Further attempts futile.</span>"
else if (tplus > tlimit)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile.</span>"
else if (!H.getorgan(/obj/item/organ/heart))
else if (!heart)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing.</span>"
else if (heart.organ_flags & ORGAN_FAILING)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart too damaged.</span>"
else if(total_burn >= 180 || total_brute >= 180)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile.</span>"
else if(H.get_ghost())
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful.</span>"
else
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
if(!BR || BR.damaged_brain)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing or damaged beyond point of no return. Further attempts futile.</span>"
if(BR) //BUG_PROBABLE_CAUSE - slight difference between us and tg
if(BR.organ_flags & ORGAN_FAILING)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain tissue is damaged making recovery of patient impossible via defibrillator. Further attempts futile.</span>"
if(BR.brain_death)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain damaged beyond point of no return. Further attempts futile.</span>"
if(H.suiciding || BR.brainmob?.suiciding)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No intelligence pattern can be detected in patient's brain. Further attempts futile.</span>"
else
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing. Further attempts futile.</span>"
if(failed)
user.visible_message(failed)
@@ -623,7 +642,7 @@
H.Jitter(100)
SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK)
if(tplus > tloss)
H.adjustBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))), 150)
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, max(0, min(99, ((tlimit - tplus) / tlimit * 100))), 150)
log_combat(user, H, "revived", defib)
if(req_defib)
if(defib.healdisk)
@@ -641,7 +660,11 @@
playsound(src, 'sound/machines/defib_failed.ogg', 50, 0)
else if(H.undergoing_cardiac_arrest())
H.set_heartattack(FALSE)
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.</span>")
if(!(heart.organ_flags & ORGAN_FAILING))
H.set_heartattack(FALSE)
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.</span>")
else
user.visible_message("<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed, heart damage detected.</span>")
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
@@ -211,7 +211,7 @@
data["occupant"]["toxLoss"] = mob_occupant.getToxLoss()
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
data["occupant"]["brainLoss"] = mob_occupant.getBrainLoss()
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
data["occupant"]["reagents"] = list()
if(mob_occupant.reagents.reagent_list.len)
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
@@ -544,4 +544,26 @@
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashman] slips inside.</span>")
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1)
return
else if(issilicon(target))
var/mob/living/silicon/trashbot = target
if (!trashbot.devourable)
to_chat(user, "<span class='warning'>[target] registers an error code to your [src]</span>")
return
if(patient)
to_chat(user,"<span class='warning'>Your [src] is already occupied.</span>")
return
if(trashbot.buckled)
to_chat(user,"<span class='warning'>[trashbot] is buckled and can not be put into your [src].</span>")
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [trashbot] into their [src].</span>", "<span class='notice'>You start ingesting [trashbot] into your [src.name]...</span>")
if(do_after(user, 30, target = trashbot) && !patient && !trashbot.buckled && length(contents) < max_item_count)
if(!in_range(src, trashbot)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them.
trashbot.forceMove(src)
trashbot.reset_perspective(src)
update_gut()
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashbot] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashbot] slips inside.</span>")
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1)
return
return
@@ -96,7 +96,7 @@
if(BODY_ZONE_PRECISE_MOUTH)
if((M.head && M.head.flags_cover & HEADCOVERSMOUTH) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
if(M.is_mouth_covered())
to_chat(user, "<span class='notice'>You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSMOUTH) ? "helmet" : "mask"] first.</span>")
return
+12 -1
View File
@@ -167,8 +167,19 @@ GLOBAL_LIST_EMPTY(GPS_list)
gpstag = "Eerie Signal"
desc = "Report to a coder immediately."
invisibility = INVISIBILITY_MAXIMUM
var/obj/item/implant/gps/implant
/obj/item/gps/mining/internal
/obj/item/gps/internal/Initialize(mapload, obj/item/implant/gps/_implant)
. = ..()
implant = _implant
/obj/item/gps/internal/Destroy()
if(implant?.imp_in)
qdel(implant)
else
return ..()
/obj/item/gps/internal/mining
icon_state = "gps-m"
gpstag = "MINER"
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
@@ -413,3 +413,16 @@
/obj/item/radio/off // Station bounced radios, their only difference is spawning with the speakers off, this was made to help the lag.
listening = 0 // And it's nice to have a subtype too for future features.
dog_fashion = /datum/dog_fashion/back
/obj/item/radio/internal
var/obj/item/implant/radio/implant
/obj/item/radio/internal/Initialize(mapload, obj/item/implant/radio/_implant)
. = ..()
implant = _implant
/obj/item/radio/internal/Destroy()
if(implant?.imp_in)
qdel(implant)
else
return ..()
+87 -15
View File
@@ -135,7 +135,7 @@ SLIME SCANNER
var/mob/living/carbon/human/H = M
if(H.undergoing_cardiac_arrest() && H.stat != DEAD)
to_chat(user, "<span class='danger'>Subject suffering from heart attack: Apply defibrillation or other electric shock immediately!</span>")
if(H.undergoing_liver_failure() && H.stat != DEAD)
if(H.undergoing_liver_failure() && H.stat != DEAD) //might be depreciated BUG_PROBABLE_CAUSE
to_chat(user, "<span class='danger'>Subject is suffering from liver failure: Apply Corazone and begin a liver transplant immediately!</span>")
var/msg = "<span class='info'>*---------*\nAnalyzing results for [M]:\n\tOverall status: [mob_status]\n"
@@ -157,12 +157,8 @@ SLIME SCANNER
msg += "\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage.</span>\n"
if(advanced)
msg += "\t<span class='info'>Cellular Damage Level: [M.getCloneLoss()].</span>\n"
if (M.getBrainLoss() >= 200 || !M.getorgan(/obj/item/organ/brain))
msg += "\t<span class='alert'>Subject's brain function is non-existent.</span>\n"
else if (M.getBrainLoss() >= 120)
msg += "\t<span class='alert'>Severe brain damage detected. Subject likely to have mental traumas.</span>\n"
else if (M.getBrainLoss() >= 45)
msg += "\t<span class='alert'>Brain damage detected.</span>\n"
if (!M.getorgan(/obj/item/organ/brain))
to_chat(user, "\t<span class='alert'>Subject lacks a brain.</span>") //Unsure how this won't proc for 50% of the cit playerbase (This is a joke everyone on cit a cute.)
if(ishuman(M) && advanced) // Should I make this not advanced?
var/mob/living/carbon/human/H = M
var/obj/item/organ/liver/L = H.getorganslot("liver")
@@ -194,6 +190,14 @@ SLIME SCANNER
if(Br.cached_size>5)
msg += "\t<span class='info'>Subject has a sizeable bosom with a [Br.size] cup.</span>\n"
if (M.getOrganLoss(ORGAN_SLOT_BRAIN) >= 200 || !M.getorgan(/obj/item/organ/brain))
msg += "\t<span class='alert'>Subject's brain function is non-existent.</span>\n"
else if (M.getOrganLoss(ORGAN_SLOT_BRAIN) >= 120)
msg += "\t<span class='alert'>Severe brain damage detected. Subject likely to have mental traumas.</span>\n"
else if (M.getOrganLoss(ORGAN_SLOT_BRAIN) >= 45)
msg += "\t<span class='alert'>Brain damage detected.</span>\n"
if(iscarbon(M))
var/mob/living/carbon/C = M
if(LAZYLEN(C.get_traumas()))
var/list/trauma_text = list()
@@ -212,7 +216,7 @@ SLIME SCANNER
if(C.roundstart_quirks.len)
msg += "\t<span class='info'>Subject has the following physiological traits: [C.get_trait_string()].</span>\n"
if(advanced)
msg += "\t<span class='info'>Brain Activity Level: [(200 - M.getBrainLoss())/2]%.</span>\n"
msg += "\t<span class='info'>Brain Activity Level: [(200 - M.getOrganLoss(ORGAN_SLOT_BRAIN))/2]%.</span>\n"
if(M.radiation)
msg += "\t<span class='alert'>Subject is irradiated.</span>\n"
msg += "\t<span class='info'>Radiation Level: [M.radiation] rad</span>\n"
@@ -246,11 +250,11 @@ SLIME SCANNER
healthy = FALSE
msg += "\t<span class='alert'>Subject is deaf.</span>\n"
else
if(ears.ear_damage)
msg += "\t<span class='alert'>Subject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage.</span>\n"
if(ears.damage)
to_chat(user, "\t<span class='alert'>Subject has [ears.damage > ears.maxHealth ? "permanent ": "temporary "]hearing damage.</span>")
healthy = FALSE
if(ears.deaf)
msg += "\t<span class='alert'>Subject is [ears.ear_damage > UNHEALING_EAR_DAMAGE ? "permanently ": "temporarily "] deaf.</span>\n"
to_chat(user, "\t<span class='alert'>Subject is [ears.damage > ears.maxHealth ? "permanently ": "temporarily "] deaf.</span>")
healthy = FALSE
if(healthy)
msg += "\t<span class='info'>Healthy.</span>\n"
@@ -266,13 +270,13 @@ SLIME SCANNER
if(HAS_TRAIT(C, TRAIT_NEARSIGHT))
msg += "\t<span class='alert'>Subject is nearsighted.</span>\n"
healthy = FALSE
if(eyes.eye_damage > 30)
if(eyes.damage > 30)
msg += "\t<span class='alert'>Subject has severe eye damage.</span>\n"
healthy = FALSE
else if(eyes.eye_damage > 20)
else if(eyes.damage > 20)
msg += "\t<span class='alert'>Subject has significant eye damage.</span>\n"
healthy = FALSE
else if(eyes.eye_damage)
else if(eyes.damage)
msg += "\t<span class='alert'>Subject has minor eye damage.</span>\n"
healthy = FALSE
if(healthy)
@@ -296,6 +300,59 @@ SLIME SCANNER
for(var/obj/item/bodypart/org in damaged)
msg += "\t\t<span class='info'>[capitalize(org.name)]: [(org.brute_dam > 0) ? "<font color='red'>[org.brute_dam]</font></span>" : "<font color='red'>0</font>"]-[(org.burn_dam > 0) ? "<font color='#FF8000'>[org.burn_dam]</font>" : "<font color='#FF8000'>0</font>"]\n"
//Organ damages report
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/minor_damage
var/major_damage
var/max_damage
var/report_organs = FALSE
//Piece together the lists to be reported
for(var/O in H.internal_organs)
var/obj/item/organ/organ = O
if(organ.organ_flags & ORGAN_FAILING)
report_organs = TRUE //if we report one organ, we report all organs, even if the lists are empty, just for consistency
if(max_damage)
max_damage += ", " //prelude the organ if we've already reported an organ
max_damage += organ.name //this just slaps the organ name into the string of text
else
max_damage = "\t<span class='alert'>Non-Functional Organs: " //our initial statement
max_damage += organ.name
else if(organ.damage > organ.high_threshold)
report_organs = TRUE
if(major_damage)
major_damage += ", "
major_damage += organ.name
else
major_damage = "\t<span class='info'>Severely Damaged Organs: "
major_damage += organ.name
else if(organ.damage > organ.low_threshold)
report_organs = TRUE
if(minor_damage)
minor_damage += ", "
minor_damage += organ.name
else
minor_damage = "\t<span class='info'>Mildly Damaged Organs: "
minor_damage += organ.name
if(report_organs) //we either finish the list, or set it to be empty if no organs were reported in that category
if(!max_damage)
max_damage = "\t<span class='alert'>Non-Functional Organs: </span>"
else
max_damage += "</span>"
if(!major_damage)
major_damage = "\t<span class='info'>Severely Damaged Organs: </span>"
else
major_damage += "</span>"
if(!minor_damage)
minor_damage = "\t<span class='info'>Mildly Damaged Organs: </span>"
else
minor_damage += "</span>"
msg += "[minor_damage]"
msg += "[major_damage]"
msg += "[max_damage]"
// Species and body temperature
if(ishuman(M))
@@ -384,7 +441,7 @@ SLIME SCANNER
if(M.reagents.reagent_list.len)
var/list/datum/reagent/reagents = list()
for(var/datum/reagent/R in M.reagents.reagent_list)
if(R.invisible)
if(R.chemical_flags & REAGENT_INVISIBLE)
continue
reagents += R
@@ -403,6 +460,21 @@ SLIME SCANNER
msg += "<span class='danger'>[R.name]</span>\n"
else
msg += "<span class='notice'>Subject is not addicted to any reagents.</span>\n"
if(M.reagents.has_reagent("fermiTox"))
var/datum/reagent/fermiTox = M.reagents.has_reagent("fermiTox")
switch(fermiTox.volume)
if(5 to 10)
msg += "<span class='notice'>Subject contains a low amount of toxic isomers.</span>\n"
if(10 to 25)
msg += "<span class='danger'>Subject contains toxic isomers.</span>\n"
if(25 to 50)
msg += "<span class='danger'>Subject contains a substantial amount of toxic isomers.</span>\n"
if(50 to 95)
msg += "<span class='danger'>Subject contains a high amount of toxic isomers.</span>\n"
if(95 to INFINITY)
msg += "<span class='danger'>Subject contains a extremely dangerous amount of toxic isomers.</span>\n"
msg += "*---------*</span>"
to_chat(user, msg)
+1 -1
View File
@@ -302,7 +302,7 @@
spellname = "charge"
icon_state ="bookcharge"
desc = "This book is made of 100% postconsumer wizard."
remarks = list("I feel ALIVE!", "I CAN TASTE THE MANA!", "What a RUSH!", "I'm FLYING through these pages!", "THIS GENIUS IS MAKING IT!", "This book is ACTION PAcKED!", "HE'S DONE IT", "LETS GOOOOOOOOOOOO")
remarks = list("I feel ALIVE!", "I CAN TASTE THE MANA!", "What a RUSH!", "I'm FLYING through these pages!", "THIS GENIUS IS MAKING IT!", "This book is ACTION PAcKED!", "HE'S DONE IT", "LETS GOOOOOOOOOOOO", "Just wait faster is all...")
/obj/item/book/granter/spell/charge/recoil(mob/user)
..()
+6 -1
View File
@@ -358,6 +358,8 @@
slot_flags = ITEM_SLOT_BELT
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
tool_behaviour = TOOL_SAW
toolspeed = 1.5 //slower than a real saw
/obj/item/nullrod/claymore/glowing
icon_state = "swordon"
@@ -513,7 +515,8 @@
slot_flags = ITEM_SLOT_BELT
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
tool_behaviour = TOOL_SAW
toolspeed = 0.5
/obj/item/nullrod/hammmer
icon_state = "hammeron"
@@ -539,6 +542,8 @@
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
total_mass = TOTAL_MASS_HAND_REPLACEMENT
tool_behaviour = TOOL_SAW
toolspeed = 2
/obj/item/nullrod/chainsaw/Initialize()
. = ..()
+1 -2
View File
@@ -72,7 +72,7 @@
else
return FALSE
forceMove(target)
moveToNullspace()
imp_in = target
target.implants += src
if(activated)
@@ -89,7 +89,6 @@
return TRUE
/obj/item/implant/proc/removed(mob/living/source, silent = FALSE, special = 0)
moveToNullspace()
imp_in = null
source.implants -= src
for(var/X in actions)
@@ -3,6 +3,7 @@
desc = "Injects things."
icon_state = "reagents"
activated = FALSE
var/obj/item/imp_chemholder/chemholder
/obj/item/implant/chem/get_data()
var/dat = {"<b>Implant Specifications:</b><BR>
@@ -29,6 +30,26 @@
GLOB.tracked_chem_implants -= src
return ..()
/obj/item/implant/chem/implant(mob/living/target, mob/user, silent = FALSE)
. = ..()
if(!.)
return
if(chemholder)
chemholder.forceMove(target)
return
chemholder = new(imp_in, src)
reagents.trans_to(chemholder, reagents.total_volume)
/obj/item/implant/chem/removed(mob/target, silent = FALSE, special = 0)
. = ..()
if(!.)
return
if(!special)
chemholder.reagents.trans_to(src, chemholder.reagents.total_volume)
QDEL_NULL(chemholder)
else
chemholder?.moveToNullspace()
/obj/item/implant/chem/trigger(emote, mob/living/source)
if(emote == "deathgasp")
if(istype(source) && !(source.stat == DEAD))
@@ -45,13 +66,12 @@
injectamount = reagents.total_volume
else
injectamount = cause
reagents.trans_to(R, injectamount)
chemholder.reagents.trans_to(R, injectamount)
to_chat(R, "<span class='italics'>You hear a faint beep.</span>")
if(!reagents.total_volume)
if(!chemholder.reagents.total_volume)
to_chat(R, "<span class='italics'>You hear a faint click from your chest.</span>")
qdel(src)
/obj/item/implantcase/chem
name = "implant case - 'Remote Chemical'"
desc = "A glass case containing a remote chemical implant."
@@ -63,3 +83,17 @@
return TRUE
else
return ..()
/obj/item/imp_chemholder
var/obj/item/implant/chem/implant
/obj/item/imp_chemholder/Initialize(mapload, obj/item/implant/chem/_implant)
. = ..()
create_reagents(50)
implant = _implant
/obj/item/imp_chemholder/Destroy()
if(implant?.imp_in)
qdel(implant)
else
return ..()
@@ -11,7 +11,7 @@
/obj/item/implant/sad_trombone/trigger(emote, mob/source)
if(emote == "deathgasp")
playsound(loc, 'sound/misc/sadtrombone.ogg', 50, 0)
playsound(source.loc, 'sound/misc/sadtrombone.ogg', 50, 0)
/obj/item/implanter/sad_trombone
name = "implanter (sad trombone)"
@@ -11,8 +11,9 @@
var/popup = FALSE // is the DOUWANNABLOWUP window open?
var/active = FALSE
/obj/item/implant/explosive/on_mob_death(mob/living/L, gibbed)
activate("death")
/obj/item/implant/explosive/trigger(emote, mob/source)
if(emote == "deathgasp")
activate("death")
/obj/item/implant/explosive/get_data()
var/dat = {"<b>Implant Specifications:</b><BR>
@@ -29,32 +30,18 @@
/obj/item/implant/explosive/activate(cause)
. = ..()
if(!cause || !imp_in || active)
return 0
return FALSE
if(cause == "action_button" && !popup)
popup = TRUE
var/response = alert(imp_in, "Are you sure you want to activate your [name]? This will cause you to explode!", "[name] Confirmation", "Yes", "No")
popup = FALSE
if(response == "No")
return 0
heavy = round(heavy)
medium = round(medium)
weak = round(weak)
to_chat(imp_in, "<span class='notice'>You activate your [name].</span>")
active = TRUE
var/turf/boomturf = get_turf(imp_in)
message_admins("[ADMIN_LOOKUPFLW(imp_in)] has activated their [name] at [ADMIN_VERBOSEJMP(boomturf)], with cause of [cause].")
//If the delay is short, just blow up already jeez
if(delay <= 7)
explosion(src,heavy,medium,weak,weak, flame_range = weak)
if(imp_in)
imp_in.gib(1)
qdel(src)
return
timed_explosion()
return FALSE
addtimer(CALLBACK(src, .proc/timed_explosion, cause), 1)
/obj/item/implant/explosive/implant(mob/living/target)
for(var/X in target.implants)
if(istype(X, type))
if(istype(X, /obj/item/implant/explosive))
var/obj/item/implant/explosive/imp_e = X
imp_e.heavy += heavy
imp_e.medium += medium
@@ -65,22 +52,37 @@
return ..()
/obj/item/implant/explosive/proc/timed_explosion()
imp_in.visible_message("<span class='warning'>[imp_in] starts beeping ominously!</span>")
playsound(loc, 'sound/items/timer.ogg', 30, 0)
sleep(delay*0.25)
if(imp_in && !imp_in.stat)
/obj/item/implant/explosive/proc/timed_explosion(cause)
if(cause == "death" && imp_in.stat != DEAD)
return FALSE
heavy = round(heavy)
medium = round(medium)
weak = round(weak)
to_chat(imp_in, "<span class='notice'>You activate your [name].</span>")
active = TRUE
var/turf/boomturf = get_turf(imp_in)
message_admins("[ADMIN_LOOKUPFLW(imp_in)] has activated their [name] at [ADMIN_VERBOSEJMP(boomturf)], with cause of [cause].")
if(delay > 7)
imp_in?.visible_message("<span class='warning'>[imp_in] starts beeping ominously!</span>")
playsound(get_turf(imp_in ? imp_in : src), 'sound/items/timer.ogg', 30, 0)
addtimer(CALLBACK(src, .proc/double_pain, TRUE), delay * 0.25)
addtimer(CALLBACK(src, .proc/double_pain), delay * 0.5)
addtimer(CALLBACK(src, .proc/double_pain), delay * 0.75)
addtimer(CALLBACK(src, .proc/boom_goes_the_weasel), delay)
else //If the delay is short, just blow up already jeez
boom_goes_the_weasel()
/obj/item/implant/explosive/proc/double_pain(message = FALSE)
playsound(get_turf(imp_in ? imp_in : src), 'sound/items/timer.ogg', 30, 0)
if(!imp_in)
return
if(message && imp_in.stat == CONSCIOUS)
imp_in.visible_message("<span class='warning'>[imp_in] doubles over in pain!</span>")
imp_in.Knockdown(140)
playsound(loc, 'sound/items/timer.ogg', 30, 0)
sleep(delay*0.25)
playsound(loc, 'sound/items/timer.ogg', 30, 0)
sleep(delay*0.25)
playsound(loc, 'sound/items/timer.ogg', 30, 0)
sleep(delay*0.25)
explosion(src,heavy,medium,weak,weak, flame_range = weak)
if(imp_in)
imp_in.gib(1)
imp_in.Knockdown(140)
/obj/item/implant/explosive/proc/boom_goes_the_weasel()
explosion(get_turf(imp_in ? imp_in : src), heavy, medium, weak, weak, flame_range = weak)
imp_in?.gib(TRUE)
qdel(src)
/obj/item/implant/explosive/macro
@@ -95,17 +97,7 @@
/obj/item/implant/explosive/macro/implant(mob/living/target)
for(var/X in target.implants)
if(istype(X, type))
return 0
for(var/Y in target.implants)
if(istype(Y, /obj/item/implant/explosive))
var/obj/item/implant/explosive/imp_e = Y
heavy += imp_e.heavy
medium += imp_e.medium
weak += imp_e.weak
delay += imp_e.delay
qdel(imp_e)
break
return FALSE
return ..()
@@ -1,7 +1,6 @@
/obj/item/implant/mindshield
name = "mindshield implant"
desc = "Protects against brainwashing."
resistance_flags = INDESTRUCTIBLE
activated = 0
/obj/item/implant/mindshield/get_data()
@@ -69,62 +69,4 @@
healthstring = "<small>Oxygen Deprivation Damage => [round(L.getOxyLoss())]<br />Fire Damage => [round(L.getFireLoss())]<br />Toxin Damage => [round(L.getToxLoss())]<br />Brute Force Damage => [round(L.getBruteLoss())]</small>"
if (!healthstring)
healthstring = "ERROR"
return healthstring
/obj/item/implant/radio
name = "internal radio implant"
activated = TRUE
var/obj/item/radio/radio
var/radio_key
var/subspace_transmission = FALSE
icon = 'icons/obj/radio.dmi'
icon_state = "walkietalkie"
/obj/item/implant/radio/activate()
. = ..()
// needs to be GLOB.deep_inventory_state otherwise it won't open
radio.ui_interact(usr, "main", null, FALSE, null, GLOB.deep_inventory_state)
/obj/item/implant/radio/Initialize(mapload)
. = ..()
radio = new(src)
// almost like an internal headset, but without the
// "must be in ears to hear" restriction.
radio.name = "internal radio"
radio.subspace_transmission = subspace_transmission
radio.canhear_range = 0
if(radio_key)
radio.keyslot = new radio_key
radio.recalculateChannels()
/obj/item/implant/radio/mining
radio_key = /obj/item/encryptionkey/headset_cargo
/obj/item/implant/radio/syndicate
desc = "Are you there God? It's me, Syndicate Comms Agent."
radio_key = /obj/item/encryptionkey/syndicate
subspace_transmission = TRUE
/obj/item/implant/radio/slime
name = "slime radio"
icon = 'icons/obj/surgery.dmi'
icon_state = "adamantine_resonator"
radio_key = /obj/item/encryptionkey/headset_sci
subspace_transmission = TRUE
/obj/item/implant/radio/get_data()
var/dat = {"<b>Implant Specifications:</b><BR>
<b>Name:</b> Internal Radio Implant<BR>
<b>Life:</b> 24 hours<BR>
<b>Implant Details:</b> Allows user to use an internal radio, useful if user expects equipment loss, or cannot equip conventional radios."}
return dat
/obj/item/implanter/radio
name = "implanter (internal radio)"
imp_type = /obj/item/implant/radio
/obj/item/implanter/radio/syndicate
name = "implanter (internal syndicate radio)"
imp_type = /obj/item/implant/radio/syndicate
return healthstring
@@ -0,0 +1,69 @@
/obj/item/implant/radio
name = "internal radio implant"
activated = TRUE
var/obj/item/radio/internal/radio
var/radio_key
var/subspace_transmission = FALSE
icon = 'icons/obj/radio.dmi'
icon_state = "walkietalkie"
/obj/item/implant/radio/activate()
. = ..()
// needs to be GLOB.deep_inventory_state otherwise it won't open
radio.ui_interact(usr, "main", null, FALSE, null, GLOB.deep_inventory_state)
/obj/item/implant/radio/implant(mob/living/target, mob/user, silent = FALSE)
. = ..()
if(!.)
return
if(radio)
radio.forceMove(target)
return
radio = new(target)
// almost like an internal headset, but without the
// "must be in ears to hear" restriction.
radio.name = "internal radio"
radio.subspace_transmission = subspace_transmission
radio.canhear_range = 0
if(radio_key)
radio.keyslot = new radio_key
radio.recalculateChannels()
/obj/item/implant/radio/removed(mob/target, silent = FALSE, special = 0)
. = ..()
if(!.)
return
if(!special)
qdel(radio)
else
radio?.moveToNullspace()
/obj/item/implant/radio/mining
radio_key = /obj/item/encryptionkey/headset_cargo
/obj/item/implant/radio/syndicate
desc = "Are you there God? It's me, Syndicate Comms Agent."
radio_key = /obj/item/encryptionkey/syndicate
subspace_transmission = TRUE
/obj/item/implant/radio/slime
name = "slime radio"
icon = 'icons/obj/surgery.dmi'
icon_state = "adamantine_resonator"
radio_key = /obj/item/encryptionkey/headset_sci
subspace_transmission = TRUE
/obj/item/implant/radio/get_data()
var/dat = {"<b>Implant Specifications:</b><BR>
<b>Name:</b> Internal Radio Implant<BR>
<b>Life:</b> 24 hours<BR>
<b>Implant Details:</b> Allows user to use an internal radio, useful if user expects equipment loss, or cannot equip conventional radios."}
return dat
/obj/item/implanter/radio
name = "implanter (internal radio)"
imp_type = /obj/item/implant/radio
/obj/item/implanter/radio/syndicate
name = "implanter (internal syndicate radio)"
imp_type = /obj/item/implant/radio/syndicate
@@ -4,30 +4,44 @@
icon_state = "storage"
item_color = "r"
var/max_slot_stacking = 4
var/obj/item/storage/bluespace_pocket/pocket
/obj/item/implant/storage/activate()
. = ..()
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SHOW, imp_in, TRUE)
SEND_SIGNAL(pocket, COMSIG_TRY_STORAGE_SHOW, imp_in, TRUE)
/obj/item/implant/storage/removed(source, silent = FALSE, special = 0)
. = ..()
if(.)
if(!special)
qdel(GetComponent(/datum/component/storage/concrete/implant))
if(!special)
qdel(pocket)
else
pocket?.moveToNullspace()
return ..()
/obj/item/implant/storage/implant(mob/living/target, mob/user, silent = FALSE)
for(var/X in target.implants)
if(istype(X, type))
var/obj/item/implant/storage/imp_e = X
GET_COMPONENT_FROM(STR, /datum/component/storage, imp_e)
GET_COMPONENT_FROM(STR, /datum/component/storage, imp_e.pocket)
if(!STR || (STR && STR.max_items < max_slot_stacking))
imp_e.AddComponent(/datum/component/storage/concrete/implant)
imp_e.pocket.AddComponent(/datum/component/storage/concrete/implant)
qdel(src)
return TRUE
return FALSE
AddComponent(/datum/component/storage/concrete/implant)
. = ..()
if(.)
if(pocket)
pocket.forceMove(target)
else
pocket = new(target)
return ..()
/obj/item/storage/bluespace_pocket
name = "internal bluespace pocket"
icon_state = "pillbox"
w_class = WEIGHT_CLASS_TINY
desc = "A tiny yet spacious pocket, usually found implanted inside sneaky syndicate agents and nowhere else."
component_type = /datum/component/storage/concrete/implant
resistance_flags = INDESTRUCTIBLE //A bomb!
item_flags = DROPDEL
/obj/item/implanter/storage
name = "implanter (storage)"
@@ -3,8 +3,8 @@
desc = "Track with this."
activated = 0
/obj/item/implant/tracking/New()
..()
/obj/item/implant/tracking/Initialize()
. = ..()
GLOB.tracked_implants += src
/obj/item/implant/tracking/Destroy()
@@ -15,7 +15,31 @@
imp_type = /obj/item/implant/tracking
/obj/item/implanter/tracking/gps
imp_type = /obj/item/gps/mining/internal
imp_type = /obj/item/implant/gps
/obj/item/implant/gps
name = "\improper GPS implant"
desc = "Track with this and a GPS."
activated = FALSE
var/obj/item/gps/internal/mining/real_gps
/obj/item/implant/gps/implant(mob/living/target, mob/user, silent = FALSE)
. = ..()
if(!.)
return
if(real_gps)
real_gps.forceMove(target)
else
real_gps = new(target)
/obj/item/implant/gps/removed(mob/living/source, silent = FALSE, special = 0)
. = ..()
if(!.)
return
if(!special)
qdel(real_gps)
else
real_gps?.moveToNullspace()
/obj/item/implant/tracking/get_data()
var/dat = {"<b>Implant Specifications:</b><BR>
@@ -1,23 +1,23 @@
/obj/item/implant/uplink
name = "uplink implant"
desc = "Sneeki breeki."
icon = 'icons/obj/radio.dmi'
icon_state = "radio"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
var/starting_tc = 0
/obj/item/implant/uplink/Initialize(mapload, _owner)
. = ..()
AddComponent(/datum/component/uplink, _owner, TRUE, FALSE, null, starting_tc)
/obj/item/implanter/uplink
name = "implanter (uplink)"
imp_type = /obj/item/implant/uplink
/obj/item/implanter/uplink/precharged
name = "implanter (precharged uplink)"
imp_type = /obj/item/implant/uplink/precharged
/obj/item/implant/uplink/precharged
starting_tc = 10
/obj/item/implant/uplink
name = "uplink implant"
desc = "Sneeki breeki."
icon = 'icons/obj/radio.dmi'
icon_state = "radio"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
var/starting_tc = 0
/obj/item/implant/uplink/Initialize(mapload, _owner)
. = ..()
AddComponent(/datum/component/uplink, _owner, TRUE, FALSE, null, starting_tc, GLOB.not_incapacitated_state)
/obj/item/implanter/uplink
name = "implanter (uplink)"
imp_type = /obj/item/implant/uplink
/obj/item/implanter/uplink/precharged
name = "implanter (precharged uplink)"
imp_type = /obj/item/implant/uplink/precharged
/obj/item/implant/uplink/precharged
starting_tc = 10
+2
View File
@@ -142,6 +142,8 @@
w_class = WEIGHT_CLASS_NORMAL
sharpness = IS_SHARP
light_color = "#40ceff"
tool_behaviour = TOOL_SAW
toolspeed = 0.7
/obj/item/melee/transforming/energy/sword/cyborg/saw/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
+1 -1
View File
@@ -254,7 +254,7 @@
to_chat(user, "<span class='warning'>The MMI indicates that their mind is currently inactive; it might change!</span>")
return
if(BM.stat == DEAD || (M.brain && M.brain.damaged_brain))
if(BM.stat == DEAD || (M.brain && M.brain.organ_flags & ORGAN_FAILING))
to_chat(user, "<span class='warning'>Sticking a dead brain into the frame would sort of defeat the purpose!</span>")
return
@@ -25,6 +25,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
merge_type = /obj/item/stack/sheet/glass
grind_results = list(/datum/reagent/silicon = 20)
point_value = 1
tableVariant = /obj/structure/table/glass
/obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins to slice [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -88,6 +89,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \
resistance_flags = ACID_PROOF
merge_type = /obj/item/stack/sheet/plasmaglass
grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10)
tableVariant = /obj/structure/table/plasmaglass
/obj/item/stack/sheet/plasmaglass/fifty
amount = 50
@@ -232,6 +232,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
grind_results = list("silver" = 20)
point_value = 20
merge_type = /obj/item/stack/sheet/mineral/silver
tableVariant = /obj/structure/table/optable
GLOBAL_LIST_INIT(silver_recipes, list ( \
new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
@@ -107,6 +107,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
merge_type = /obj/item/stack/sheet/metal
grind_results = list("iron" = 20)
point_value = 2
tableVariant = /obj/structure/table
/obj/item/stack/sheet/metal/ratvar_act()
new /obj/item/stack/tile/brass(loc, amount)
@@ -168,6 +169,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
merge_type = /obj/item/stack/sheet/plasteel
grind_results = list("iron" = 20, "plasma" = 20)
point_value = 23
tableVariant = /obj/structure/table/reinforced
/obj/item/stack/sheet/plasteel/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.plasteel_recipes
@@ -474,6 +476,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
novariants = FALSE
grind_results = list("iron" = 5, "teslium" = 15, "holyoil" = 1)
merge_type = /obj/item/stack/tile/brass
tableVariant = /obj/structure/table/reinforced/brass
/obj/item/stack/tile/brass/narsie_act()
new /obj/item/stack/sheet/runed_metal(loc, amount)
@@ -526,6 +529,7 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
novariants = FALSE
grind_results = list("iron" = 5, "copper" = 3) //we have no "tin" reagent so this is the closest thing
merge_type = /obj/item/stack/tile/bronze
tableVariant = /obj/structure/table/bronze
/obj/item/stack/tile/bronze/attack_self(mob/living/user)
if(is_servant_of_ratvar(user)) //still lets them build with it, just gives a message
+1
View File
@@ -22,6 +22,7 @@
var/full_w_class = WEIGHT_CLASS_NORMAL //The weight class the stack should have at amount > 2/3rds max_amount
var/novariants = TRUE //Determines whether the item should update it's sprites based on amount.
//NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind()
var/obj/structure/table/tableVariant // we tables now (stores table variant to be built from this stack)
/obj/item/stack/on_grind()
for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists
@@ -9,9 +9,10 @@
item_flags = NOBLUDGEON
/obj/item/stack/telecrystal/attack(mob/target, mob/user)
if(target == user) //You can't go around smacking people with crystals to find out if they have an uplink or not.
for(var/obj/item/implant/uplink/I in target)
if(I && I.imp_in)
if(target == user && isliving(user)) //You can't go around smacking people with crystals to find out if they have an uplink or not.
var/mob/living/L = user
for(var/obj/item/implant/uplink/I in L.implants)
if(I?.imp_in)
GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, I)
if(hidden_uplink)
hidden_uplink.telecrystals += amount
@@ -99,33 +99,117 @@
icon_state = "tile-carpet"
turf_type = /turf/open/floor/carpet
resistance_flags = FLAMMABLE
/obj/item/stack/tile/carpet/fifty
amount = 50
tableVariant = /obj/structure/table/wood/fancy
/obj/item/stack/tile/carpet/black
name = "black carpet"
icon_state = "tile-carpet-black"
turf_type = /turf/open/floor/carpet/black
tableVariant = /obj/structure/table/wood/fancy/black
/obj/item/stack/tile/carpet/blackred
name = "red carpet"
icon_state = "tile-carpet-blackred"
turf_type = /turf/open/floor/carpet/blackred
tableVariant = /obj/structure/table/wood/fancy/blackred
/obj/item/stack/tile/carpet/monochrome
name = "monochrome carpet"
icon_state = "tile-carpet-monochrome"
turf_type = /turf/open/floor/carpet/monochrome
tableVariant = /obj/structure/table/wood/fancy/monochrome
/obj/item/stack/tile/carpet/blue
name = "blue carpet"
icon_state = "tile-carpet-blue"
item_state = "tile-carpet-blue"
turf_type = /turf/open/floor/carpet/blue
tableVariant = /obj/structure/table/wood/fancy/blue
/obj/item/stack/tile/carpet/cyan
name = "cyan carpet"
icon_state = "tile-carpet-cyan"
item_state = "tile-carpet-cyan"
turf_type = /turf/open/floor/carpet/cyan
tableVariant = /obj/structure/table/wood/fancy/cyan
/obj/item/stack/tile/carpet/green
name = "green carpet"
icon_state = "tile-carpet-green"
item_state = "tile-carpet-green"
turf_type = /turf/open/floor/carpet/green
tableVariant = /obj/structure/table/wood/fancy/green
/obj/item/stack/tile/carpet/orange
name = "orange carpet"
icon_state = "tile-carpet-orange"
item_state = "tile-carpet-orange"
turf_type = /turf/open/floor/carpet/orange
tableVariant = /obj/structure/table/wood/fancy/orange
/obj/item/stack/tile/carpet/purple
name = "purple carpet"
icon_state = "tile-carpet-purple"
item_state = "tile-carpet-purple"
turf_type = /turf/open/floor/carpet/purple
tableVariant = /obj/structure/table/wood/fancy/purple
/obj/item/stack/tile/carpet/red
name = "red carpet"
icon_state = "tile-carpet-red"
item_state = "tile-carpet-red"
turf_type = /turf/open/floor/carpet/red
tableVariant = /obj/structure/table/wood/fancy/red
/obj/item/stack/tile/carpet/royalblack
name = "royal black carpet"
icon_state = "tile-carpet-royalblack"
item_state = "tile-carpet-royalblack"
turf_type = /turf/open/floor/carpet/royalblack
tableVariant = /obj/structure/table/wood/fancy/royalblack
/obj/item/stack/tile/carpet/royalblue
name = "royal blue carpet"
icon_state = "tile-carpet-royalblue"
item_state = "tile-carpet-royalblue"
turf_type = /turf/open/floor/carpet/royalblue
tableVariant = /obj/structure/table/wood/fancy/royalblue
/obj/item/stack/tile/carpet/fifty
amount = 50
/obj/item/stack/tile/carpet/black/fifty
amount = 50
/obj/item/stack/tile/carpet/blackred
name = "red carpet"
icon_state = "tile-carpet-blackred"
turf_type = /turf/open/floor/carpet/blackred
/obj/item/stack/tile/carpet/blackred/fifty
amount = 50
/obj/item/stack/tile/carpet/monochrome
name = "monochrome carpet"
icon_state = "tile-carpet-monochrome"
turf_type = /turf/open/floor/carpet/monochrome
amount = 50
/obj/item/stack/tile/carpet/monochrome/fifty
amount = 50
amount = 50
/obj/item/stack/tile/carpet/blue/fifty
amount = 50
/obj/item/stack/tile/carpet/cyan/fifty
amount = 50
/obj/item/stack/tile/carpet/green/fifty
amount = 50
/obj/item/stack/tile/carpet/orange/fifty
amount = 50
/obj/item/stack/tile/carpet/purple/fifty
amount = 50
/obj/item/stack/tile/carpet/red/fifty
amount = 50
/obj/item/stack/tile/carpet/royalblack/fifty
amount = 50
/obj/item/stack/tile/carpet/royalblue/fifty
amount = 50
/obj/item/stack/tile/fakespace
name = "astral carpet"
+3 -6
View File
@@ -493,12 +493,9 @@
desc = "A large duffel bag for holding surgical tools. Bears the logo of an advanced med-tech firm."
/obj/item/storage/backpack/duffelbag/syndie/surgery_adv/PopulateContents()
new /obj/item/hemostat/adv(src)
new /obj/item/circular_saw/adv(src)
new /obj/item/scalpel/adv(src)
new /obj/item/retractor/adv(src)
new /obj/item/cautery/adv(src)
new /obj/item/surgicaldrill/adv(src)
new /obj/item/scalpel/advanced(src)
new /obj/item/retractor/advanced(src)
new /obj/item/surgicaldrill/advanced(src)
new /obj/item/surgical_drapes(src)
new /obj/item/storage/firstaid/tactical(src)
new /obj/item/clothing/suit/straight_jacket(src)
+3 -6
View File
@@ -185,12 +185,9 @@
content_overlays = FALSE
/obj/item/storage/belt/medical/surgery_belt_adv/PopulateContents()
new /obj/item/hemostat/adv(src)
new /obj/item/circular_saw/adv(src)
new /obj/item/scalpel/adv(src)
new /obj/item/retractor/adv(src)
new /obj/item/cautery/adv(src)
new /obj/item/surgicaldrill/adv(src)
new /obj/item/scalpel/advanced(src)
new /obj/item/retractor/advanced(src)
new /obj/item/surgicaldrill/advanced(src)
new /obj/item/surgical_drapes(src)
/obj/item/storage/belt/security
+1 -1
View File
@@ -140,7 +140,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
else if(iscarbon(M))
var/mob/living/carbon/C = M
if(!istype(C.head, /obj/item/clothing/head))
C.adjustBrainLoss(10, 80)
C.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 80)
to_chat(C, "<span class='danger'>You feel dumber.</span>")
if(smack)
+6 -7
View File
@@ -75,15 +75,14 @@
temp += "<B>Implant Signals:</B><BR>"
for (var/obj/item/implant/tracking/W in GLOB.tracked_implants)
if (!W.imp_in || !isliving(W.loc))
if (!isliving(W.imp_in))
continue
else
var/mob/living/M = W.loc
if (M.stat == DEAD)
if (M.timeofdeath + 6000 < world.time)
continue
var/mob/living/M = W.imp_in
if (M.stat == DEAD)
if (M.timeofdeath + 6000 < world.time)
continue
var/turf/tr = get_turf(W)
var/turf/tr = get_turf(M)
if (tr.z == sr.z && tr)
var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
if (direct < 20)
+1 -1
View File
@@ -232,7 +232,7 @@
. = ..()
if(!sliver)
return
if(ismovableatom(O) && O != sliver)
if(proximity && ismovableatom(O) && O != sliver)
Consume(O, user)
/obj/item/hemostat/supermatter/throw_impact(atom/hit_atom) // no instakill supermatter javelins
+4 -2
View File
@@ -35,7 +35,7 @@
if(!wielded || !user)
return
wielded = 0
if(force_unwielded)
if(!isnull(force_unwielded))
force = force_unwielded
var/sf = findtext(name," (Wielded)")
if(sf)
@@ -304,7 +304,7 @@
var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD)//stole from chainsaw code
var/obj/item/organ/brain/B = user.getorganslot(ORGAN_SLOT_BRAIN)
B.vital = FALSE//this cant possibly be a good idea
B.organ_flags &= ~ORGAN_VITAL //this cant possibly be a good idea
var/randdir
for(var/i in 1 to 24)//like a headless chicken!
if(user.is_holding(src))
@@ -599,6 +599,8 @@
sharpness = IS_SHARP
actions_types = list(/datum/action/item_action/startchainsaw)
var/on = FALSE
tool_behaviour = TOOL_SAW
toolspeed = 0.5
/obj/item/twohanded/required/chainsaw/Initialize()
. = ..()
+2
View File
@@ -436,6 +436,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
total_mass = TOTAL_MASS_HAND_REPLACEMENT
tool_behaviour = TOOL_SAW
toolspeed = 1
/obj/item/mounted_chainsaw/Initialize()
. = ..()
+22 -11
View File
@@ -288,17 +288,19 @@ LINEN BINS
resistance_flags = FLAMMABLE
max_integrity = 70
var/amount = 10
var/list/sheet_types = list(/obj/item/bedsheet)
var/static/allowed_sheets = list(/obj/item/bedsheet, /obj/item/reagent_containers/rag/towel)
var/list/sheets = list()
var/obj/item/hidden = null
/obj/structure/bedsheetbin/examine(mob/user)
..()
if(amount < 1)
to_chat(user, "There are no bed sheets in the bin.")
to_chat(user, "There are no sheets in the bin.")
else if(amount == 1)
to_chat(user, "There is one bed sheet in the bin.")
to_chat(user, "There is one sheet in the bin.")
else
to_chat(user, "There are [amount] bed sheets in the bin.")
to_chat(user, "There are [amount] sheets in the bin.")
/obj/structure/bedsheetbin/update_icon()
@@ -317,8 +319,9 @@ LINEN BINS
..()
/obj/structure/bedsheetbin/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/bedsheet))
if(is_type_in_list(I, allowed_sheets))
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>\The [I] is stuck to your hand, you cannot place it into the bin!</span>")
return
sheets.Add(I)
amount++
@@ -339,18 +342,19 @@ LINEN BINS
. = ..()
if(.)
return
if(user.lying)
if(user.incapacitated())
return
if(amount >= 1)
amount--
var/obj/item/bedsheet/B
var/obj/item/B
if(sheets.len > 0)
B = sheets[sheets.len]
sheets.Remove(B)
else
B = new /obj/item/bedsheet(loc)
var/chosen = pick(sheet_types)
B = new chosen
B.forceMove(drop_location())
user.put_in_hands(B)
@@ -362,19 +366,20 @@ LINEN BINS
to_chat(user, "<span class='notice'>[hidden] falls out of [B]!</span>")
hidden = null
add_fingerprint(user)
/obj/structure/bedsheetbin/attack_tk(mob/user)
if(amount >= 1)
amount--
var/obj/item/bedsheet/B
var/obj/item/B
if(sheets.len > 0)
B = sheets[sheets.len]
sheets.Remove(B)
else
B = new /obj/item/bedsheet(loc)
var/chosen = pick(sheet_types)
B = new chosen
B.forceMove(drop_location())
to_chat(user, "<span class='notice'>You telekinetically remove [B] from [src].</span>")
@@ -384,5 +389,11 @@ LINEN BINS
hidden.forceMove(drop_location())
hidden = null
/obj/structure/bedsheetbin/towel
desc = "It looks rather cosy. This one is designed to hold towels."
sheet_types = list(/obj/item/reagent_containers/rag/towel)
add_fingerprint(user)
/obj/structure/bedsheetbin/color
sheet_types = list(/obj/item/bedsheet, /obj/item/bedsheet/blue, /obj/item/bedsheet/green, /obj/item/bedsheet/orange, \
/obj/item/bedsheet/purple, /obj/item/bedsheet/red, /obj/item/bedsheet/yellow, /obj/item/bedsheet/brown, \
/obj/item/bedsheet/black)
@@ -2,6 +2,24 @@
icon_state = "freezer"
var/jones = FALSE
/obj/structure/closet/secure_closet/freezer/Destroy()
recursive_organ_check(src)
..()
/obj/structure/closet/secure_closet/freezer/Initialize()
..()
recursive_organ_check(src)
/obj/structure/closet/secure_closet/freezer/open(mob/living/user)
if(opened || !can_open(user)) //dupe check just so we don't let the organs decay when someone fails to open the locker
return FALSE
recursive_organ_check(src)
return ..()
/obj/structure/closet/secure_closet/freezer/close(mob/living/user)
if(..()) //if we actually closed the locker
recursive_organ_check(src)
/obj/structure/closet/secure_closet/freezer/ex_act()
if(!jones)
jones = TRUE
@@ -99,6 +99,25 @@
name = "freezer"
icon_state = "freezer"
//Snowflake organ freezer code
//Order is important, since we check source, we need to do the check whenever we have all the organs in the crate
/obj/structure/closet/crate/freezer/open()
recursive_organ_check(src)
..()
/obj/structure/closet/crate/freezer/close()
..()
recursive_organ_check(src)
/obj/structure/closet/crate/freezer/Destroy()
recursive_organ_check(src)
..()
/obj/structure/closet/crate/freezer/Initialize()
. = ..()
recursive_organ_check(src)
/obj/structure/closet/crate/freezer/blood
name = "blood freezer"
desc = "A freezer containing packs of blood."
@@ -45,7 +45,7 @@
death = FALSE
anchored = FALSE
density = FALSE
flavour_text = "<span class='big bold'>You are an ash walker.</span><b> Your tribe worships <span class='danger'>the Necropolis</span>. The wastes are sacred ground, its monsters a blessed bounty. \
flavour_text = "<span class='big bold'>You are an ash walker.</span><b> Your tribe worships <span class='danger'>the Necropolis</span>. The wastes are sacred ground, its monsters a blessed bounty. You would never leave its beautiful expanse. \
You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest.</b>"
assignedrole = "Ash Walker"
@@ -561,7 +561,7 @@
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
mob_name = "a space pirate"
mob_species = /datum/species/skeleton/pirate
mob_species = /datum/species/skeleton/space
outfit = /datum/outfit/pirate/space
roundstart = FALSE
death = FALSE
+4
View File
@@ -31,6 +31,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
/obj/structure/bodycontainer/Initialize()
. = ..()
GLOB.bodycontainers += src
recursive_organ_check(src)
/obj/structure/bodycontainer/Destroy()
GLOB.bodycontainers -= src
@@ -101,6 +102,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
/obj/structure/bodycontainer/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 5)
recursive_organ_check(src)
qdel(src)
/obj/structure/bodycontainer/container_resist(mob/living/user)
@@ -120,6 +122,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
open()
/obj/structure/bodycontainer/proc/open()
recursive_organ_check(src)
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
playsound(src, 'sound/effects/roll.ogg', 5, 1)
var/turf/T = get_step(src, dir)
@@ -134,6 +137,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
for(var/atom/movable/AM in connected.loc)
if(!AM.anchored || AM == connected)
AM.forceMove(src)
recursive_organ_check(src)
update_icon()
/obj/structure/bodycontainer/get_remote_view_fullscreens(mob/user)
+26 -98
View File
@@ -22,92 +22,22 @@
var/framestackamount = 2
/obj/structure/table_frame/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/wrench))
if(I.tool_behaviour == TOOL_WRENCH)
to_chat(user, "<span class='notice'>You start disassembling [src]...</span>")
I.play_tool_sound(src)
if(I.use_tool(src, user, 30))
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, TRUE)
deconstruct(TRUE)
else if(istype(I, /obj/item/stack/sheet/plasteel))
var/obj/item/stack/sheet/plasteel/P = I
if(P.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one plasteel sheet to do this!</span>")
return
var/obj/item/stack/material = I
if (istype(I, /obj/item/stack) && material?.tableVariant)
if(material.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one [material.name] sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [P] to [src]...</span>")
if(do_after(user, 50, target = src) && P.use(1))
make_new_table(/obj/structure/table/reinforced)
else if(istype(I, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/metal/M = I
if(M.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one metal sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [M] to [src]...</span>")
if(do_after(user, 20, target = src) && M.use(1))
make_new_table(/obj/structure/table)
else if(istype(I, /obj/item/stack/sheet/glass))
var/obj/item/stack/sheet/glass/G = I
if(G.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one glass sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [G] to [src]...</span>")
if(do_after(user, 20, target = src) && G.use(1))
make_new_table(/obj/structure/table/glass)
else if(istype(I, /obj/item/stack/sheet/mineral/silver))
var/obj/item/stack/sheet/mineral/silver/S = I
if(S.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one silver sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [S] to [src]...</span>")
if(do_after(user, 20, target = src) && S.use(1))
make_new_table(/obj/structure/table/optable)
else if(istype(I, /obj/item/stack/tile/carpet/black))
var/obj/item/stack/tile/carpet/black/C = I
if(C.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one black carpet sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [C] to [src]...</span>")
if(do_after(user, 20, target = src) && C.use(1))
make_new_table(/obj/structure/table/wood/fancy/black)
else if(istype(I, /obj/item/stack/tile/carpet/blackred))
var/obj/item/stack/tile/carpet/blackred/C = I
if(C.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one red carpet sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [C] to [src]...</span>")
if(do_after(user, 20, target = src) && C.use(1))
make_new_table(/obj/structure/table/wood/fancy/blackred)
else if(istype(I, /obj/item/stack/tile/carpet/monochrome))
var/obj/item/stack/tile/carpet/monochrome/C = I
if(C.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one monochrome carpet sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [C] to [src]...</span>")
if(do_after(user, 20, target = src) && C.use(1))
make_new_table(/obj/structure/table/wood/fancy/monochrome)
else if(istype(I, /obj/item/stack/tile/carpet))
var/obj/item/stack/tile/carpet/C = I
if(C.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one carpet sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [C] to [src]...</span>")
if(do_after(user, 20, target = src) && C.use(1))
make_new_table(/obj/structure/table/wood/fancy)
else if(istype(I, /obj/item/stack/tile/bronze))
var/obj/item/stack/tile/bronze/B = I
if(B.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one bronze sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [B] to [src]...</span>")
if(do_after(user, 20, target = src) && B.use(1))
make_new_table(/obj/structure/table/bronze)
else if(istype(I, /obj/item/stack/sheet/plasmaglass))
var/obj/item/stack/sheet/plasmaglass/G = I
if(G.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one plasmaglass sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [G] to [src]...</span>")
if(do_after(user, 20, target = src) && G.use(1))
make_new_table(/obj/structure/table/plasmaglass)
to_chat(user, "<span class='notice'>You start adding [material] to [src]...</span>")
if(do_after(user, 20, target = src) && material.use(1))
make_new_table(material.tableVariant)
else
return ..()
@@ -143,23 +73,21 @@
resistance_flags = FLAMMABLE
/obj/structure/table_frame/wood/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/stack/sheet/mineral/wood))
var/obj/item/stack/sheet/mineral/wood/W = I
if(W.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one wood sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [W] to [src]...</span>")
if(do_after(user, 20, target = src) && W.use(1))
make_new_table(/obj/structure/table/wood)
return
else if(istype(I, /obj/item/stack/tile/carpet))
var/obj/item/stack/tile/carpet/C = I
if(C.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one carpet sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [C] to [src]...</span>")
if(do_after(user, 20, target = src) && C.use(1))
make_new_table(/obj/structure/table/wood/poker)
if (istype(I, /obj/item/stack))
var/obj/item/stack/material = I
var/toConstruct // stores the table variant
if(istype(I, /obj/item/stack/sheet/mineral/wood))
toConstruct = /obj/structure/table/wood
else if(istype(I, /obj/item/stack/tile/carpet))
toConstruct = /obj/structure/table/wood/poker
if (toConstruct)
if(material.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one [material.name] sheet to do this!</span>")
return
to_chat(user, "<span class='notice'>You start adding [material] to [src]...</span>")
if(do_after(user, 20, target = src) && material.use(1))
make_new_table(toConstruct)
else
return ..()
+71 -22
View File
@@ -21,6 +21,7 @@
anchored = TRUE
layer = TABLE_LAYER
climbable = TRUE
obj_flags = CAN_BE_HIT|SHOVABLE_ONTO
pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.")
var/frame = /obj/structure/table_frame
var/framestack = /obj/item/stack/rods
@@ -136,6 +137,15 @@
var/mob/living/carbon/human/H = pushed_mob
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table)
/obj/structure/table/shove_act(mob/living/target, mob/living/user)
if(!target.resting)
target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
user.visible_message("<span class='danger'>[user.name] shoves [target.name] onto \the [src]!</span>",
"<span class='danger'>You shove [target.name] onto \the [src]!</span>", null, COMBAT_MESSAGE_RANGE)
target.forceMove(src.loc)
log_combat(user, target, "shoved", "onto [src] (table)")
return TRUE
/obj/structure/table/attackby(obj/item/I, mob/user, params)
if(!(flags_1 & NODECONSTRUCT_1))
if(istype(I, /obj/item/screwdriver) && deconstruction_ready)
@@ -348,44 +358,83 @@
frame = /obj/structure/table_frame
framestack = /obj/item/stack/rods
buildstack = /obj/item/stack/tile/carpet
canSmoothWith = list(/obj/structure/table/wood/fancy, /obj/structure/table/wood/fancy/black, /obj/structure/table/wood/fancy/blackred, /obj/structure/table/wood/fancy/monochrome)
canSmoothWith = list(/obj/structure/table/wood/fancy,
/obj/structure/table/wood/fancy/black,
/obj/structure/table/wood/fancy/blackred,
/obj/structure/table/wood/fancy/monochrome,
/obj/structure/table/wood/fancy/blue,
/obj/structure/table/wood/fancy/cyan,
/obj/structure/table/wood/fancy/green,
/obj/structure/table/wood/fancy/orange,
/obj/structure/table/wood/fancy/purple,
/obj/structure/table/wood/fancy/red,
/obj/structure/table/wood/fancy/royalblack,
/obj/structure/table/wood/fancy/royalblue)
var/smooth_icon = 'icons/obj/smooth_structures/fancy_table.dmi' // see Initialize()
/obj/structure/table/wood/fancy/New()
// New() is used so that the /black subtype can override `icon` easily and
// the correct value will be used by the smoothing subsystem.
/obj/structure/table/wood/fancy/Initialize()
. = ..()
// Needs to be set dynamically because table smooth sprites are 32x34,
// which the editor treats as a two-tile-tall object. The sprites are that
// size so that the north/south corners look nice - examine the detail on
// the sprites in the editor to see why.
icon = 'icons/obj/smooth_structures/fancy_table.dmi'
icon = smooth_icon
/obj/structure/table/wood/fancy/black
icon_state = "fancy_table_black"
buildstack = /obj/item/stack/tile/carpet/black
smooth_icon = 'icons/obj/smooth_structures/fancy_table_black.dmi'
/obj/structure/table/wood/fancy/blackred
icon = 'icons/obj/structures.dmi'
icon_state = "fancy_table_blackred"
buildstack = /obj/item/stack/tile/carpet/blackred
/obj/structure/table/wood/fancy/blackred/New()
. = ..()
icon = 'icons/obj/smooth_structures/fancy_table_blackred.dmi'
icon_state = "fancy_table_blackred"
buildstack = /obj/item/stack/tile/carpet/blackred
smooth_icon = 'icons/obj/smooth_structures/fancy_table_blackred.dmi'
/obj/structure/table/wood/fancy/monochrome
icon = 'icons/obj/structures.dmi'
icon_state = "fancy_table_monochrome"
buildstack = /obj/item/stack/tile/carpet/monochrome
icon_state = "fancy_table_monochrome"
buildstack = /obj/item/stack/tile/carpet/monochrome
smooth_icon = 'icons/obj/smooth_structures/fancy_table_monochrome.dmi'
/obj/structure/table/wood/fancy/monochrome/New()
. = ..()
icon = 'icons/obj/smooth_structures/fancy_table_monochrome.dmi'
/obj/structure/table/wood/fancy/blue
icon_state = "fancy_table_blue"
buildstack = /obj/item/stack/tile/carpet/blue
smooth_icon = 'icons/obj/smooth_structures/fancy_table_blue.dmi'
/obj/structure/table/wood/fancy/cyan
icon_state = "fancy_table_cyan"
buildstack = /obj/item/stack/tile/carpet/cyan
smooth_icon = 'icons/obj/smooth_structures/fancy_table_cyan.dmi'
/obj/structure/table/wood/fancy/green
icon_state = "fancy_table_green"
buildstack = /obj/item/stack/tile/carpet/green
smooth_icon = 'icons/obj/smooth_structures/fancy_table_green.dmi'
/obj/structure/table/wood/fancy/orange
icon_state = "fancy_table_orange"
buildstack = /obj/item/stack/tile/carpet/orange
smooth_icon = 'icons/obj/smooth_structures/fancy_table_orange.dmi'
/obj/structure/table/wood/fancy/purple
icon_state = "fancy_table_purple"
buildstack = /obj/item/stack/tile/carpet/purple
smooth_icon = 'icons/obj/smooth_structures/fancy_table_purple.dmi'
/obj/structure/table/wood/fancy/red
icon_state = "fancy_table_red"
buildstack = /obj/item/stack/tile/carpet/red
smooth_icon = 'icons/obj/smooth_structures/fancy_table_red.dmi'
/obj/structure/table/wood/fancy/royalblack
icon_state = "fancy_table_royalblack"
buildstack = /obj/item/stack/tile/carpet/royalblack
smooth_icon = 'icons/obj/smooth_structures/fancy_table_royalblack.dmi'
/obj/structure/table/wood/fancy/royalblue
icon_state = "fancy_table_royalblue"
buildstack = /obj/item/stack/tile/carpet/royalblue
smooth_icon = 'icons/obj/smooth_structures/fancy_table_royalblue.dmi'
/obj/structure/table/wood/fancy/black/New()
. = ..()
// Ditto above.
icon = 'icons/obj/smooth_structures/fancy_table_black.dmi'
/*
* Reinforced tables
*/