Merge branch 'master' into assu

...and its still coming together...
This commit is contained in:
Anonymous
2019-10-25 10:29:47 +03:00
214 changed files with 4126 additions and 809 deletions
+2 -2
View File
@@ -17,7 +17,7 @@
/datum/ntnet_service/proc/connect(datum/ntnet/net)
if(!istype(net))
return FALSE
GET_COMPONENT(interface, /datum/component/ntnet_interface)
var/datum/component/ntnet_interface/interface = GetComponent(/datum/component/ntnet_interface)
if(!interface.register_connection(net))
return FALSE
if(!net.register_service(src))
@@ -29,7 +29,7 @@
/datum/ntnet_service/proc/disconnect(datum/ntnet/net, force = FALSE)
if(!istype(net) || (!net.unregister_service(src) && !force))
return FALSE
GET_COMPONENT(interface, /datum/component/ntnet_interface)
var/datum/component/ntnet_interface/interface = GetComponent(/datum/component/ntnet_interface)
interface.unregister_connection(net)
networks_by_id -= net.network_id
return TRUE
@@ -55,7 +55,7 @@
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user)
/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_WEAR_SUIT) //we only give the mob the ability to activate the vest if he's actually wearing it.
return 1
@@ -27,7 +27,7 @@
qdel(blaster)
return ..()
/obj/item/clothing/glasses/judicial_visor/item_action_slot_check(slot, mob/user)
/obj/item/clothing/glasses/judicial_visor/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot != SLOT_GLASSES)
return 0
return ..()
@@ -31,7 +31,6 @@ the new instance inside the host to be updated to the template's stats.
var/browser_open = FALSE
var/mob/living/following_host
var/datum/component/redirect/move_listener
var/list/disease_instances
var/list/hosts //this list is associative, affected_mob -> disease_instance
var/datum/disease/advance/sentient_disease/disease_template
@@ -261,16 +260,10 @@ the new instance inside the host to be updated to the template's stats.
refresh_adaptation_menu()
/mob/camera/disease/proc/set_following(mob/living/L)
if(following_host)
UnregisterSignal(following_host, COMSIG_MOVABLE_MOVED)
RegisterSignal(L, COMSIG_MOVABLE_MOVED, .proc/follow_mob)
following_host = L
if(!move_listener)
move_listener = L.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/follow_mob)))
else
if(L)
L.TakeComponent(move_listener)
if(QDELING(move_listener))
move_listener = null
else
QDEL_NULL(move_listener)
follow_mob()
/mob/camera/disease/proc/follow_next(reverse = FALSE)
@@ -12,8 +12,8 @@
disease_flags = CURABLE
permeability_mod = 1
severity = DISEASE_SEVERITY_DANGEROUS
var/finalstage = 0 //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
var/datum/mood_event/revenant_blight/depression
var/finalstage = FALSE //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
var/depression = FALSE
/datum/disease/revblight/cure()
if(affected_mob)
@@ -44,7 +44,8 @@
affected_mob.emote("pale")
if(3)
if(!depression)
depression = SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight)
SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight)
depression = TRUE
SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.12, SANITY_CRAZY)
if(prob(10))
affected_mob.emote(pick("pale","shiver"))
@@ -113,7 +113,7 @@
/obj/singularity/wizard/attack_tk(mob/user)
if(iscarbon(user))
var/mob/living/carbon/C = user
GET_COMPONENT_FROM(insaneinthemembrane, /datum/component/mood, C)
var/datum/component/mood/insaneinthemembrane = C.GetComponent(/datum/component/mood)
if(insaneinthemembrane.sanity < 15)
return //they've already seen it and are about to die, or are just too insane to care
to_chat(C, "<span class='userdanger'>OH GOD! NONE OF IT IS REAL! NONE OF IT IS REEEEEEEEEEEEEEEEEEEEEEEEAL!</span>")
+8 -4
View File
@@ -10,7 +10,7 @@
var/maxlength = 8
var/list/obj/effect/beam/i_beam/beams
var/olddir = 0
var/datum/component/redirect/listener
var/turf/listeningTo
var/hearing_range = 3
/obj/item/assembly/infra/Initialize()
@@ -33,7 +33,7 @@
/obj/item/assembly/infra/Destroy()
STOP_PROCESSING(SSobj, src)
QDEL_NULL(listener)
listeningTo = null
QDEL_LIST(beams)
. = ..()
@@ -163,8 +163,12 @@
next_activate = world.time + 30
/obj/item/assembly/infra/proc/switchListener(turf/newloc)
QDEL_NULL(listener)
listener = newloc.AddComponent(/datum/component/redirect, list(COMSIG_ATOM_EXITED = CALLBACK(src, .proc/check_exit)))
if(listeningTo == newloc)
return
if(listeningTo)
UnregisterSignal(listeningTo, COMSIG_ATOM_EXITED)
RegisterSignal(newloc, COMSIG_ATOM_EXITED, .proc/check_exit)
listeningTo = newloc
/obj/item/assembly/infra/proc/check_exit(datum/source, atom/movable/offender)
if(QDELETED(src))
+1 -1
View File
@@ -80,7 +80,7 @@
// Paper work done correctly
/datum/export/paperwork_correct
cost = 150
cost = 120 // finicky number 20 x 120 = 2400 per crate
k_elasticity = 0
unit_name = "correct paperwork"
export_types = list(/obj/item/folder/paperwork_correct)
+7 -7
View File
@@ -87,7 +87,7 @@
/datum/supply_pack/security/armory/mindshield
name = "Mindshield Implants Crate"
desc = "Prevent against radical thoughts with three Mindshield implants. Requires Armory access to open."
cost = 4000
cost = 3000 //Lowered untill cargo rework MK II is done
contains = list(/obj/item/storage/lockbox/loyalty)
crate_name = "mindshield implant crate"
@@ -175,7 +175,7 @@
/datum/supply_pack/security/armory/swat
name = "SWAT Crate"
desc = "Contains two fullbody sets of tough, fireproof, pressurized suits designed in a joint effort by IS-ERI and Nanotrasen. Each set contains a suit, helmet, mask, combat belt, and combat gloves. Requires Armory access to open."
cost = 6750
cost = 6000
contains = list(/obj/item/clothing/head/helmet/swat/nanotrasen,
/obj/item/clothing/head/helmet/swat/nanotrasen,
/obj/item/clothing/suit/space/swat,
@@ -199,7 +199,7 @@
/datum/supply_pack/security/armory/woodstock
name = "Classic WoodStock Shotguns Crate"
desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open."
cost = 3500
cost = 3000
contains = list(/obj/item/gun/ballistic/shotgun,
/obj/item/gun/ballistic/shotgun,
/obj/item/gun/ballistic/shotgun)
@@ -208,7 +208,7 @@
/datum/supply_pack/security/armory/wt550
name = "WT-550 Semi-Auto Rifle Crate"
desc = "Contains two high-powered, semiautomatic rifles chambered in 4.6x30mm. Requires Armory access to open."
cost = 3250
cost = 2550
contains = list(/obj/item/gun/ballistic/automatic/wt550,
/obj/item/gun/ballistic/automatic/wt550)
crate_name = "auto rifle crate"
@@ -216,7 +216,7 @@
/datum/supply_pack/security/armory/wt550ammo
name = "WT-550 Semi-Auto SMG Ammo Crate"
desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
cost = 2750
cost = 1750
contains = list(/obj/item/ammo_box/magazine/wt550m9,
/obj/item/ammo_box/magazine/wt550m9,
/obj/item/ammo_box/magazine/wt550m9,
@@ -226,7 +226,7 @@
/datum/supply_pack/security/armory/wt550ammo_nonlethal // Takes around 12 shots to stun crit someone
name = "WT-550 Semi-Auto SMG Non-Lethal Ammo Crate"
desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
cost = 1200
cost = 1000
contains = list(/obj/item/ammo_box/magazine/wt550m9/wtrubber,
/obj/item/ammo_box/magazine/wt550m9/wtrubber,
/obj/item/ammo_box/magazine/wt550m9/wtrubber,
@@ -236,7 +236,7 @@
/datum/supply_pack/security/armory/wt550ammo_special
name = "WT-550 Semi-Auto SMG Special Ammo Crate"
desc = "Contains 2 20-round Armour Piercing and Incendiary magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
cost = 3500
cost = 3000
contains = list(/obj/item/ammo_box/magazine/wt550m9/wtap,
/obj/item/ammo_box/magazine/wt550m9/wtap,
/obj/item/ammo_box/magazine/wt550m9/wtic,
+3 -3
View File
@@ -12,7 +12,7 @@
/datum/supply_pack/emergency/vehicle
name = "Biker Gang Kit" //TUNNEL SNAKES OWN THIS TOWN
desc = "TUNNEL SNAKES OWN THIS TOWN. Contains an unbranded All Terrain Vehicle, and a complete gang outfit -- consists of black gloves, a menacing skull bandanna, and a SWEET leather overcoat!"
cost = 2800
cost = 2500
contraband = TRUE
contains = list(/obj/vehicle/ridden/atv,
/obj/item/key,
@@ -26,7 +26,7 @@
/datum/supply_pack/emergency/equipment
name = "Emergency Bot/Internals Crate"
desc = "Explosions got you down? These supplies are guaranteed to patch up holes, in stations and people alike! Comes with two floorbots, two medbots, five oxygen masks and five small oxygen tanks."
cost = 3750
cost = 2750
contains = list(/mob/living/simple_animal/bot/floorbot,
/mob/living/simple_animal/bot/floorbot,
/mob/living/simple_animal/bot/medbot,
@@ -132,7 +132,7 @@
/datum/supply_pack/emergency/metalfoam
name = "Metal Foam Grenade Crate"
desc = "Seal up those pesky hull breaches with 14 Metal Foam Grenades."
cost = 2000
cost = 1500
contains = list(/obj/item/storage/box/metalfoam,
/obj/item/storage/box/metalfoam)
crate_name = "metal foam grenade crate"
+30 -4
View File
@@ -55,7 +55,7 @@
/datum/supply_pack/engineering/engihardsuit
name = "Engineering Hardsuit"
desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!"
cost = 2750
cost = 2250
contains = list(/obj/item/tank/internals/air,
/obj/item/clothing/mask/gas,
/obj/item/clothing/suit/space/hardsuit/engine)
@@ -84,7 +84,7 @@
/datum/supply_pack/engineering/powergamermitts
name = "Insulated Gloves Crate"
desc = "The backbone of modern society. Barely ever ordered for actual engineering. Contains three insulated gloves."
cost = 2750 //Made of pure-grade bullshittinium
cost = 2300 //Made of pure-grade bullshittinium
contains = list(/obj/item/clothing/gloves/color/yellow,
/obj/item/clothing/gloves/color/yellow,
/obj/item/clothing/gloves/color/yellow)
@@ -121,6 +121,18 @@
crate_name = "power cell crate"
crate_type = /obj/structure/closet/crate/engineering/electrical
/datum/supply_pack/engineering/siezedpower
name = "Siezed Power Cell Crate"
desc = "We took the means of power! Contains three high-voltage plus power cells."
cost = 1300
contraband = TRUE
contains = list(/obj/item/stock_parts/cell/high/plus,
/obj/item/stock_parts/cell/high/plus,
/obj/item/stock_parts/cell/high/plus)
crate_name = "siezed crate"
crate_type = /obj/structure/closet/crate/engineering/electrical
/datum/supply_pack/engineering/shuttle_engine
name = "Shuttle Engine Crate"
desc = "Through advanced bluespace-shenanigans, our engineers have managed to fit an entire shuttle engine into one tiny little crate. Requires CE access to open."
@@ -129,7 +141,22 @@
contains = list(/obj/structure/shuttle/engine/propulsion/burst/cargo)
crate_name = "shuttle engine crate"
crate_type = /obj/structure/closet/crate/secure/engineering
special = TRUE
/datum/supply_pack/engineering/siezedproduction
name = "The Means of Production"
desc = "We will win for we have took over the production! S five metal sheets, five wire, three matter bins, one manipulater and one sheet of glass."
cost = 1500
contraband = TRUE
contains = list(/obj/item/stock_parts/cell/high/plus,
/obj/item/circuitboard/machine/autolathe,
/obj/item/stack/cable_coil/random/five,
/obj/item/stack/sheet/metal/five,
/obj/item/stock_parts/matter_bin,
/obj/item/stock_parts/matter_bin,
/obj/item/stock_parts/matter_bin,
/obj/item/stock_parts/manipulator,
/obj/item/stack/sheet/glass,)
crate_name = "siezed crate"
/datum/supply_pack/engineering/tools
name = "Toolbox Crate"
@@ -183,7 +210,6 @@
)
crate_name= "dna samplers crate"
/datum/supply_pack/engineering/shield_sat
name = "Shield Generator Satellite"
desc = "Protect the very existence of this station with these Anti-Meteor defenses. Contains three Shield Generator Satellites."
+15 -8
View File
@@ -117,8 +117,8 @@
/datum/supply_pack/misc/paper_work
name = "Freelance Paper work"
desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (10) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up.
cost = 700 // Net of 0 credits
desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (20) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up.
cost = 700 // Net of 0 credits but makes (120 x 20 = 2400)
contains = list(/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
@@ -129,11 +129,18 @@
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/pen/fountain,
/obj/item/pen/fountain,
/obj/item/pen/fountain,
/obj/item/pen/fountain,
/obj/item/pen/fountain)
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/pen/fountain
)
crate_name = "Paperwork"
/datum/supply_pack/misc/funeral
@@ -149,7 +156,7 @@
/datum/supply_pack/misc/jukebox
name = "Jukebox"
cost = 15000
cost = 10000
contains = list(/obj/machinery/jukebox)
crate_name = "Jukebox"
+1 -1
View File
@@ -36,7 +36,7 @@
/datum/supply_pack/service/carpet_exotic
name = "Exotic Carpet Crate"
desc = "Exotic carpets straight from Space Russia, for all your decorating needs. Contains 100 tiles each of 10 different flooring patterns."
cost = 10000
cost = 7000
contains = list(/obj/item/stack/tile/carpet/blue/fifty,
/obj/item/stack/tile/carpet/blue/fifty,
/obj/item/stack/tile/carpet/cyan/fifty,
+1 -1
View File
@@ -561,7 +561,7 @@
/obj/item/storage/belt/chameleon/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.silent = TRUE
/obj/item/storage/belt/chameleon/emp_act(severity)
+1 -1
View File
@@ -123,7 +123,7 @@
..()
if(damaged_clothes)
to_chat(user, "<span class='warning'>It looks damaged!</span>")
GET_COMPONENT(pockets, /datum/component/storage)
var/datum/component/storage/pockets = GetComponent(/datum/component/storage)
if(pockets)
var/list/how_cool_are_your_threads = list("<span class='notice'>")
if(pockets.attack_hand_interact)
+2 -2
View File
@@ -104,7 +104,7 @@
resistance_flags = ACID_PROOF
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
/obj/item/clothing/glasses/science/item_action_slot_check(slot)
/obj/item/clothing/glasses/science/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_GLASSES)
return 1
@@ -307,7 +307,7 @@
M.appearance_flags |= RESET_COLOR
M.color = "#[H.eye_color]"
. += M
/obj/item/clothing/glasses/sunglasses/big
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks flashes."
icon_state = "bigsunglasses"
+1 -1
View File
@@ -14,7 +14,7 @@
/obj/item/clothing/gloves/ComponentInitialize()
. = ..()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, /obj/item/clothing/gloves/clean_blood)))
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /obj/item/clothing/gloves/clean_blood)
/obj/item/clothing/gloves/clean_blood(datum/source, strength)
. = ..()
+1 -1
View File
@@ -23,7 +23,7 @@
/obj/item/clothing/shoes/ComponentInitialize()
. = ..()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, /obj/item/clothing/shoes/clean_blood)))
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /obj/item/clothing/shoes/clean_blood)
/obj/item/clothing/shoes/suicide_act(mob/living/carbon/user)
if(rand(2)>1)
+3 -3
View File
@@ -17,7 +17,7 @@
/obj/item/clothing/shoes/clown_shoes/banana_shoes/step_action()
. = ..()
GET_COMPONENT(bananium, /datum/component/material_container)
var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
if(on)
if(bananium.amount(MAT_BANANIUM) < 100)
on = !on
@@ -30,7 +30,7 @@
bananium.use_amount_type(100, MAT_BANANIUM)
/obj/item/clothing/shoes/clown_shoes/banana_shoes/attack_self(mob/user)
GET_COMPONENT(bananium, /datum/component/material_container)
var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
var/sheet_amount = bananium.retrieve_all()
if(sheet_amount)
to_chat(user, "<span class='notice'>You retrieve [sheet_amount] sheets of bananium from the prototype shoes.</span>")
@@ -42,7 +42,7 @@
to_chat(user, "<span class='notice'>The shoes are [on ? "enabled" : "disabled"].</span>")
/obj/item/clothing/shoes/clown_shoes/banana_shoes/ui_action_click(mob/user)
GET_COMPONENT(bananium, /datum/component/material_container)
var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
if(bananium.amount(MAT_BANANIUM))
on = !on
update_icon()
@@ -547,7 +547,7 @@
changeWearer()
..()
/obj/item/flightpack/item_action_slot_check(slot)
/obj/item/flightpack/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == ITEM_SLOT_BACK)
return TRUE
@@ -574,7 +574,7 @@
momentum_speed_y = 0
momentum_speed = max(momentum_speed_x, momentum_speed_y)
/obj/item/flightpack/item_action_slot_check(slot)
/obj/item/flightpack/item_action_slot_check(slot, mob/user, datum/action/A)
return slot == SLOT_BACK
/obj/item/flightpack/proc/enable_stabilizers()
@@ -730,7 +730,7 @@
if(!active)
clothing_flags &= ~NOSLIP
/obj/item/clothing/shoes/flightshoes/item_action_slot_check(slot)
/obj/item/clothing/shoes/flightshoes/item_action_slot_check(slot, mob/user, datum/action/A)
return slot == SLOT_SHOES
/obj/item/clothing/shoes/flightshoes/proc/delink_suit()
+16 -13
View File
@@ -47,7 +47,7 @@
suit.RemoveHelmet()
soundloop.stop(user)
/obj/item/clothing/head/helmet/space/hardsuit/item_action_slot_check(slot)
/obj/item/clothing/head/helmet/space/hardsuit/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_HEAD)
return 1
@@ -158,7 +158,7 @@
var/datum/action/A = X
A.Remove(user)
/obj/item/clothing/suit/space/hardsuit/item_action_slot_check(slot)
/obj/item/clothing/suit/space/hardsuit/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_WEAR_SUIT) //we only give the mob the ability to toggle the helmet if he's wearing the hardsuit.
return 1
@@ -605,7 +605,6 @@
armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75)
item_color = "ancient"
resistance_flags = FIRE_PROOF
var/datum/component/mobhook
/obj/item/clothing/suit/space/hardsuit/ancient
name = "prototype RIG hardsuit"
@@ -617,7 +616,7 @@
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient
resistance_flags = FIRE_PROOF
var/footstep = 1
var/datum/component/mobhook
var/mob/listeningTo
/obj/item/clothing/suit/space/hardsuit/ancient/mason
name = "M.A.S.O.N RIG"
@@ -674,20 +673,24 @@
/obj/item/clothing/suit/space/hardsuit/ancient/equipped(mob/user, slot)
. = ..()
if (slot == SLOT_WEAR_SUIT)
if (mobhook && mobhook.parent != user)
QDEL_NULL(mobhook)
if (!mobhook)
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_mob_move)))
else
QDEL_NULL(mobhook)
if(slot != SLOT_WEAR_SUIT)
if(listeningTo)
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
return
if(listeningTo == user)
return
if(listeningTo)
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move)
listeningTo = user
/obj/item/clothing/suit/space/hardsuit/ancient/dropped()
. = ..()
QDEL_NULL(mobhook)
if(listeningTo)
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
/obj/item/clothing/suit/space/hardsuit/ancient/Destroy()
QDEL_NULL(mobhook) // mobhook is not our component
listeningTo = null
return ..()
/////////////SHIELDED//////////////////////////////////
+74 -74
View File
@@ -1,74 +1,74 @@
/obj/item/clothing/suit
icon = 'icons/obj/clothing/suits.dmi'
name = "suit"
var/fire_resist = T0C+100
allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
slot_flags = ITEM_SLOT_OCLOTHING
body_parts_covered = CHEST
var/blood_overlay_type = "suit"
var/togglename = null
var/suittoggled = FALSE
var/adjusted = NORMAL_STYLE
mutantrace_variation = MUTANTRACE_VARIATION
var/tauric = FALSE //Citadel Add for tauric hardsuits
var/taurmode = NOT_TAURIC
var/dimension_x = 32
var/dimension_y = 32
var/center = FALSE //Should we center the sprite?
/obj/item/clothing/suit/equipped(mob/user, slot)
..()
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(mutantrace_variation)
if(DIGITIGRADE in H.dna.species.species_traits)
adjusted = ALT_STYLE
H.update_inv_wear_suit()
else if(adjusted == ALT_STYLE)
adjusted = NORMAL_STYLE
if(("taur" in H.dna.species.mutant_bodyparts) && (H.dna.features["taur"] != "None"))
if(H.dna.features["taur"] in GLOB.noodle_taurs)
taurmode = SNEK_TAURIC
if(tauric == TRUE)
center = TRUE
dimension_x = 64
else if(H.dna.features["taur"] in GLOB.paw_taurs)
taurmode = PAW_TAURIC
if(tauric == TRUE)
center = TRUE
dimension_x = 64
else
taurmode = NOT_TAURIC
if(tauric == TRUE)
center = FALSE
dimension_x = 32
H.update_inv_wear_suit()
/obj/item/clothing/suit/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
if(blood_DNA)
if(tauric)
. += mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "[blood_overlay_type]blood", color = blood_DNA_to_color())
else
. += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood", color = blood_DNA_to_color())
var/mob/living/carbon/human/M = loc
if(ishuman(M) && M.w_uniform)
var/obj/item/clothing/under/U = M.w_uniform
if(istype(U) && U.attached_accessory)
var/obj/item/clothing/accessory/A = U.attached_accessory
if(A.above_suit)
. += U.accessory_overlay
/obj/item/clothing/suit/update_clothes_damaged_state(damaging = TRUE)
..()
if(ismob(loc))
var/mob/M = loc
M.update_inv_wear_suit()
/obj/item/clothing/suit
icon = 'icons/obj/clothing/suits.dmi'
name = "suit"
var/fire_resist = T0C+100
allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
slot_flags = ITEM_SLOT_OCLOTHING
body_parts_covered = CHEST
var/blood_overlay_type = "suit"
var/togglename = null
var/suittoggled = FALSE
var/adjusted = NORMAL_STYLE
mutantrace_variation = MUTANTRACE_VARIATION
var/tauric = FALSE //Citadel Add for tauric hardsuits
var/taurmode = NOT_TAURIC
var/dimension_x = 32
var/dimension_y = 32
var/center = FALSE //Should we center the sprite?
/obj/item/clothing/suit/equipped(mob/user, slot)
..()
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(mutantrace_variation)
if(DIGITIGRADE in H.dna.species.species_traits)
adjusted = ALT_STYLE
H.update_inv_wear_suit()
else if(adjusted == ALT_STYLE)
adjusted = NORMAL_STYLE
if(("taur" in H.dna.species.mutant_bodyparts) && (H.dna.features["taur"] != "None"))
if(H.dna.features["taur"] in GLOB.noodle_taurs)
taurmode = SNEK_TAURIC
if(tauric == TRUE)
center = TRUE
dimension_x = 64
else if(H.dna.features["taur"] in GLOB.paw_taurs)
taurmode = PAW_TAURIC
if(tauric == TRUE)
center = TRUE
dimension_x = 64
else
taurmode = NOT_TAURIC
if(tauric == TRUE)
center = FALSE
dimension_x = 32
H.update_inv_wear_suit()
/obj/item/clothing/suit/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
if(blood_DNA)
if(tauric)
. += mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "[blood_overlay_type]blood", color = blood_DNA_to_color())
else
. += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood", color = blood_DNA_to_color())
var/mob/living/carbon/human/M = loc
if(ishuman(M) && M.w_uniform)
var/obj/item/clothing/under/U = M.w_uniform
if(istype(U) && U.attached_accessory)
var/obj/item/clothing/accessory/A = U.attached_accessory
if(A.above_suit)
. += U.accessory_overlay
/obj/item/clothing/suit/update_clothes_damaged_state(damaging = TRUE)
..()
if(ismob(loc))
var/mob/M = loc
M.update_inv_wear_suit()
+1 -1
View File
@@ -23,7 +23,7 @@
/obj/item/clothing/suit/hooded/ui_action_click()
ToggleHood()
/obj/item/clothing/suit/hooded/item_action_slot_check(slot, mob/user)
/obj/item/clothing/suit/hooded/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_WEAR_SUIT || slot == SLOT_NECK)
return 1
+1 -1
View File
@@ -12,7 +12,7 @@
var/datum/component/storage/detached_pockets
/obj/item/clothing/accessory/proc/attach(obj/item/clothing/under/U, user)
GET_COMPONENT(storage, /datum/component/storage)
var/datum/component/storage/storage = GetComponent(/datum/component/storage)
if(storage)
if(SEND_SIGNAL(U, COMSIG_CONTAINS_STORAGE))
return FALSE
+1 -1
View File
@@ -13,7 +13,7 @@
if(istype(I, /obj/item/storage))
var/obj/item/storage/S = I
GET_COMPONENT_FROM(STR, /datum/component/storage, S)
var/datum/component/storage/STR = S.GetComponent(/datum/component/storage)
if(prob(upgrade_scroll_chance) && S.contents.len < STR.max_items && !S.invisibility)
var/obj/item/upgradescroll/scroll = new
SEND_SIGNAL(S, COMSIG_TRY_STORAGE_INSERT, scroll, null, TRUE, TRUE)
+9 -5
View File
@@ -283,7 +283,7 @@
var/field_type = /datum/proximity_monitor/advanced/debug
var/operating = FALSE
var/datum/proximity_monitor/advanced/current = null
var/datum/component/mobhook
var/mob/listeningTo
/obj/item/multitool/field_debug/Initialize()
. = ..()
@@ -292,7 +292,7 @@
/obj/item/multitool/field_debug/Destroy()
STOP_PROCESSING(SSobj, src)
QDEL_NULL(current)
QDEL_NULL(mobhook)
listeningTo = null
return ..()
/obj/item/multitool/field_debug/proc/setup_debug_field()
@@ -303,16 +303,20 @@
/obj/item/multitool/field_debug/attack_self(mob/user)
operating = !operating
to_chat(user, "You turn [src] [operating? "on":"off"].")
QDEL_NULL(mobhook)
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
listeningTo = null
if(!istype(current) && operating)
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_mob_move)))
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move)
listeningTo = user
setup_debug_field()
else if(!operating)
QDEL_NULL(current)
/obj/item/multitool/field_debug/dropped()
. = ..()
QDEL_NULL(mobhook)
if(listeningTo)
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
listeningTo = null
/obj/item/multitool/field_debug/proc/on_mob_move()
check_turf(get_turf(src))
@@ -38,9 +38,7 @@
if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM) && !HAS_TRAIT(H, TRAIT_AGEUSIA))
to_chat(H,"<span class='notice'>I love this taste!</span>")
H.adjust_disgust(-5 + -2.5 * fraction)
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
if(mood)
mood.add_event(null, "fav_food", /datum/mood_event/favorite_food)
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "fav_food", /datum/mood_event/favorite_food)
last_check_time = world.time
return
..()
+1 -1
View File
@@ -68,7 +68,7 @@
/obj/item/storage/bag/easterbasket/Initialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/egg, /obj/item/reagent_containers/food/snacks/chocolateegg, /obj/item/reagent_containers/food/snacks/boiledegg))
/obj/item/storage/bag/easterbasket/proc/countEggs()
+1 -1
View File
@@ -174,7 +174,7 @@
to_chat(usr, "<span class='notice'>\The [src] is full.</span>")
return FALSE
GET_COMPONENT_FROM(STR, /datum/component/storage, O.loc)
var/datum/component/storage/STR = O.loc.GetComponent(/datum/component/storage)
if(STR)
if(!STR.remove_from_storage(O,src))
return FALSE
@@ -893,7 +893,7 @@
return FALSE
var/ignore_bags = get_pin_data(IC_INPUT, 1)
if(ignore_bags)
GET_COMPONENT_FROM(STR, /datum/component/storage, A)
var/datum/component/storage/STR = A.GetComponent(/datum/component/storage)
if(STR)
return FALSE
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
@@ -1104,7 +1104,7 @@
/obj/item/integrated_circuit/input/matscan/do_work()
var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
var/turf/T = get_turf(src)
GET_COMPONENT_FROM(mt, /datum/component/material_container, H)
var/datum/component/material_container/mt = H.GetComponent(/datum/component/material_container)
if(!mt) //Invalid input
return
if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see.
@@ -411,7 +411,7 @@
.=..()
/obj/item/integrated_circuit/manipulation/matman/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted)
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
set_pin_data(IC_OUTPUT, 2, materials.total_amount)
for(var/I in 1 to mtypes.len)
var/datum/material/M = materials.materials[mtypes[I]]
@@ -423,7 +423,7 @@
return TRUE
/obj/item/integrated_circuit/manipulation/matman/do_work(ord)
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
if(!check_target(H))
activate_pin(4)
@@ -441,7 +441,7 @@
else
activate_pin(4)
if(2)
GET_COMPONENT_FROM(mt, /datum/component/material_container, H)
var/datum/component/material_container/mt = H.GetComponent(/datum/component/material_container)
var/suc
for(var/I in 1 to mtypes.len)
var/datum/material/M = materials.materials[mtypes[I]]
@@ -467,7 +467,7 @@
activate_pin(6)
/obj/item/integrated_circuit/manipulation/matman/Destroy()
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
.=..()
@@ -509,14 +509,14 @@
if(!container || !istype(container,/obj/item/storage) || !Adjacent(container))
return
GET_COMPONENT_FROM(STR, /datum/component/storage, container)
var/datum/component/storage/STR = container.GetComponent(/datum/component/storage)
if(!STR)
return
STR.attackby(src, target_obj)
else
GET_COMPONENT_FROM(STR, /datum/component/storage, target_obj.loc)
var/datum/component/storage/STR = target_obj.loc.GetComponent(/datum/component/storage)
if(!STR)
return
+1 -1
View File
@@ -78,7 +78,7 @@
state = 0
if(2)
GET_COMPONENT_FROM(STR, /datum/component/storage, I)
var/datum/component/storage/STR = I.GetComponent(/datum/component/storage)
if(is_type_in_list(I, allowed_books))
if(!user.transferItemToLoc(I, src))
return
+4 -1
View File
@@ -5,7 +5,7 @@
icon = LIGHTING_ICON
icon_state = "transparent"
color = LIGHTING_BASE_MATRIX
color = null //we manually set color in init instead
plane = LIGHTING_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = LIGHTING_LAYER
@@ -17,6 +17,9 @@
/atom/movable/lighting_object/Initialize(mapload)
. = ..()
verbs.Cut()
//We avoid setting this in the base as if we do then the parent atom handling will add_atom_color it and that
//is totally unsuitable for this object, as we are always changing its colour manually
color = LIGHTING_BASE_MATRIX
myturf = loc
if (myturf.lighting_object)
@@ -205,7 +205,7 @@
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/mob/living/carbon/human/active_owner
/obj/item/clothing/neck/necklace/memento_mori/item_action_slot_check(slot)
/obj/item/clothing/neck/necklace/memento_mori/item_action_slot_check(slot, mob/user, datum/action/A)
return slot == SLOT_NECK
/obj/item/clothing/neck/necklace/memento_mori/dropped(mob/user)
@@ -796,21 +796,21 @@
/obj/item/melee/ghost_sword/proc/ghost_check()
var/list/mob/dead/observer/current_spirits = list()
recursive_orbit_collect(src, current_spirits)
recursive_orbit_collect(loc, current_spirits) //anything holding us
for(var/i in spirits - current_spirits)
var/mob/dead/observer/G = i
G.invisibility = GLOB.observer_default_invisibility
for(var/i in current_spirits)
var/mob/dead/observer/G = i
G.invisibility = 0
spirits = current_spirits
return length(spirits)
/obj/item/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user)
force = 0
var/ghost_counter = ghost_check()
+6 -6
View File
@@ -95,7 +95,7 @@
process_ore(AM)
/obj/machinery/mineral/processing_unit/proc/process_ore(obj/item/stack/ore/O)
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/material_amount = materials.get_item_material_amount(O)
if(!materials.has_space(material_amount))
unload_mineral(O)
@@ -107,7 +107,7 @@
/obj/machinery/mineral/processing_unit/proc/get_machine_data()
var/dat = "<b>Smelter control console</b><br><br>"
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
dat += "<span class=\"res_name\">[M.name]: </span>[M.amount] cm&sup3;"
@@ -152,7 +152,7 @@
CONSOLE.updateUsrDialog()
/obj/machinery/mineral/processing_unit/proc/smelt_ore()
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/datum/material/mat = materials.materials[selected_material]
if(mat)
var/sheets_to_remove = (mat.amount >= (MINERAL_MATERIAL_AMOUNT * SMELT_AMOUNT) ) ? SMELT_AMOUNT : round(mat.amount / MINERAL_MATERIAL_AMOUNT)
@@ -175,7 +175,7 @@
on = FALSE
return
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.use_amount(alloy.materials, amount)
generate_mineral(alloy.build_path)
@@ -186,7 +186,7 @@
var/build_amount = SMELT_AMOUNT
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in D.materials)
var/M = D.materials[mat_id]
@@ -204,7 +204,7 @@
unload_mineral(O)
/obj/machinery/mineral/processing_unit/on_deconstruction()
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
..()
+4 -4
View File
@@ -34,13 +34,13 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
var/datum/component/remote_materials/mats = C
mats.disconnect_from(src)
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
return ..()
/obj/machinery/ore_silo/proc/remote_attackby(obj/machinery/M, mob/user, obj/item/stack/I)
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
// stolen from /datum/component/material_container/proc/OnAttackBy
if(user.a_intent != INTENT_HELP)
return
@@ -71,7 +71,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
popup.open()
/obj/machinery/ore_silo/proc/generate_ui()
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/list/ui = list("<head><title>Ore Silo</title></head><body><div class='statusDisplay'><h2>Stored Material:</h2>")
var/any = FALSE
for(var/M in materials.materials)
@@ -149,7 +149,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
return TRUE
else if(href_list["ejectsheet"])
var/eject_sheet = href_list["ejectsheet"]
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/count = materials.retrieve_sheets(text2num(href_list["eject_amt"]), eject_sheet, drop_location())
var/list/matlist = list()
matlist[eject_sheet] = MINERAL_MATERIAL_AMOUNT
+3 -3
View File
@@ -22,7 +22,7 @@
if(!T)
return
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/obj/item/stack/sheet/O in T)
materials.insert_stack(O, O.amount)
@@ -32,7 +32,7 @@
return
var/dat = "<b>Coin Press</b><br>"
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
if(!M.amount && chosen != mat_id)
@@ -65,7 +65,7 @@
if(processing==1)
to_chat(usr, "<span class='notice'>The machine is processing.</span>")
return
GET_COMPONENT(materials, /datum/component/material_container)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(href_list["choose"])
if(materials.materials[href_list["choose"]])
chosen = href_list["choose"]
+1 -1
View File
@@ -11,7 +11,7 @@
/obj/item/storage/bag/money/Initialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_items = 40
STR.max_combined_w_class = 40
@@ -151,7 +151,7 @@
message_admins(msg)
to_chat(usr, "<span class='danger'>The round is either not ready, or has already finished...</span>")
return
if(!GLOB.enter_allowed)
to_chat(usr, "<span class='notice'>There is an administrative lock on entering the game!</span>")
return
+1 -1
View File
@@ -40,7 +40,7 @@
if(iscyborg(user) && user.has_buckled_mobs())
var/mob/living/silicon/robot/R = user
GET_COMPONENT_FROM(riding_datum, /datum/component/riding, R)
var/datum/component/riding/riding_datum = R.GetComponent(/datum/component/riding)
if(riding_datum)
for(var/mob/M in R.buckled_mobs)
riding_datum.force_dismount(M)
@@ -92,6 +92,17 @@ GLOBAL_VAR(posibrain_notify_cooldown)
if(posi_ask == "No" || QDELETED(src))
return
transfer_personality(user)
latejoin_remove()
/obj/item/mmi/posibrain/Destroy()
latejoin_remove()
return ..()
/obj/item/mmi/posibrain/proc/latejoin_remove()
GLOB.poi_list -= src
LAZYREMOVE(GLOB.mob_spawners[name], src)
if(!LAZYLEN(GLOB.mob_spawners[name]))
GLOB.mob_spawners -= name
/obj/item/mmi/posibrain/transfer_identity(mob/living/carbon/C)
name = "[initial(name)] ([C])"
@@ -163,6 +174,8 @@ GLOBAL_VAR(posibrain_notify_cooldown)
brainmob.container = src
if(autoping)
ping_ghosts("created", TRUE)
GLOB.poi_list |= src
LAZYADD(GLOB.mob_spawners[name], src)
/obj/item/mmi/posibrain/attackby(obj/item/O, mob/user)
return
+2 -2
View File
@@ -905,7 +905,7 @@
/mob/living/carbon/do_after_coefficent()
. = ..()
GET_COMPONENT_FROM(mood, /datum/component/mood, src) //Currently, only carbons or higher use mood, move this once that changes.
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood) //Currently, only carbons or higher use mood, move this once that changes.
if(mood)
switch(mood.sanity) //Alters do_after delay based on how sane you are
if(SANITY_INSANE to SANITY_DISTURBED)
@@ -947,7 +947,7 @@
return TRUE
if(HAS_TRAIT(src, TRAIT_DUMB))
return TRUE
GET_COMPONENT_FROM(mood, /datum/component/mood, src)
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
if(mood)
if(mood.sanity < SANITY_UNSTABLE)
return TRUE
@@ -287,7 +287,7 @@
"<span class='notice'>You give [H] a pat on the head to make [p_them()] feel better!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat)
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
if (mood.sanity >= SANITY_GREAT)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
else if (mood.sanity >= SANITY_DISTURBED)
@@ -322,7 +322,7 @@
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug)
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
if (mood.sanity >= SANITY_GREAT)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
else if (mood.sanity >= SANITY_DISTURBED)
+13 -12
View File
@@ -1,8 +1,8 @@
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE)
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
var/hit_percent = (100-blocked)/100
if(hit_percent <= 0)
if(!forced && hit_percent <= 0)
return 0
var/obj/item/bodypart/BP = null
@@ -15,34 +15,35 @@
if(!BP)
BP = bodyparts[1]
var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
if(BP)
if(damage > 0 ? BP.receive_damage(damage * hit_percent, 0) : BP.heal_damage(abs(damage * hit_percent), 0))
if(damage > 0 ? BP.receive_damage(damage_amount) : BP.heal_damage(abs(damage_amount), 0))
update_damage_overlays()
else //no bodypart, we deal damage with a more general method.
adjustBruteLoss(damage * hit_percent)
adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
if(BP)
if(damage > 0 ? BP.receive_damage(0, damage * hit_percent) : BP.heal_damage(0, abs(damage * hit_percent)))
if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount)))
update_damage_overlays()
else
adjustFireLoss(damage * hit_percent)
adjustFireLoss(damage_amount, forced = forced)
if(TOX)
adjustToxLoss(damage * hit_percent)
adjustToxLoss(damage_amount, forced = forced)
if(OXY)
adjustOxyLoss(damage * hit_percent)
adjustOxyLoss(damage_amount, forced = forced)
if(CLONE)
adjustCloneLoss(damage * hit_percent)
adjustCloneLoss(damage_amount, forced = forced)
if(STAMINA)
if(BP)
if(damage > 0 ? BP.receive_damage(0, 0, damage * hit_percent) : BP.heal_damage(0, 0, abs(damage * hit_percent)))
if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage_amount)))
update_damage_overlays()
else
adjustStaminaLoss(damage * hit_percent)
adjustStaminaLoss(damage_amount, forced = forced)
//citadel code
if(AROUSAL)
adjustArousalLoss(damage * hit_percent)
adjustArousalLoss(damage_amount, forced = forced)
return TRUE
+1 -1
View File
@@ -93,7 +93,7 @@
msg += "[t_He] [t_is] visibly tense[resting ? "." : ", and [t_is] standing in combative stance."]\n"
msg += common_trait_examine()
GET_COMPONENT_FROM(mood, /datum/component/mood, src)
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
if(mood)
switch(mood.shown_mood)
if(-INFINITY to MOOD_LEVEL_SAD4)
@@ -1,5 +1,5 @@
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
// depending on the species, it will run the corresponding apply_damage code there
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced)
@@ -296,7 +296,7 @@
msg += "[t_He] seem[p_s()] winded.\n"
if (getToxLoss() >= 10)
msg += "[t_He] seem[p_s()] sickly.\n"
GET_COMPONENT_FROM(mood, /datum/component/mood, src)
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
if(mood.sanity <= SANITY_DISTURBED)
msg += "[t_He] seem[p_s()] distressed.\n"
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empath", /datum/mood_event/sad_empath, src)
@@ -32,7 +32,7 @@
if(CONFIG_GET(flag/disable_stambuffer))
togglesprint()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, /mob/living/carbon/human/clean_blood)))
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /mob/living/carbon/human/clean_blood)
/mob/living/carbon/human/ComponentInitialize()
+9 -9
View File
@@ -1,14 +1,14 @@
/mob/living/carbon/human/say_mod(input, message_mode)
verb_say = dna.species.say_mod
switch(slurring)
if(10 to 25)
return "jumbles"
if(25 to 50)
return "slurs"
if(50 to INFINITY)
return "garbles"
else
. = ..()
. = ..()
if(message_mode != MODE_CUSTOM_SAY && message_mode != MODE_WHISPER_CRIT)
switch(slurring)
if(10 to 25)
return "jumbles"
if(25 to 50)
return "slurs"
if(50 to INFINITY)
return "garbles"
/mob/living/carbon/human/GetVoice()
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
+22 -15
View File
@@ -1290,7 +1290,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if (H.nutrition > 0 && H.stat != DEAD && !HAS_TRAIT(H, TRAIT_NOHUNGER))
// THEY HUNGER
var/hunger_rate = HUNGER_FACTOR
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
var/datum/component/mood/mood = H.GetComponent(/datum/component/mood)
if(mood && mood.sanity > SANITY_DISTURBED)
hunger_rate *= max(0.5, 1 - 0.002 * mood.sanity) //0.85 to 0.75
@@ -1448,7 +1448,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/grav_force = min(gravity - STANDARD_GRAVITY,3)
. += 1 + grav_force
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
var/datum/component/mood/mood = H.GetComponent(/datum/component/mood)
if(mood && !flight) //How can depression slow you down if you can just fly away from your problems?
switch(mood.sanity)
if(SANITY_INSANE to SANITY_CRAZY)
@@ -1959,10 +1959,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
append_message = "loosening their grip on [target_held_item]"
log_combat(user, target, "shoved", append_message)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
var/hit_percent = (100-(blocked+armor))/100
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
if(hit_percent <= 0)
if(!forced && hit_percent <= 0)
return 0
var/obj/item/bodypart/BP = null
@@ -1984,37 +1984,44 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
switch(damagetype)
if(BRUTE)
H.damageoverlaytemp = 20
var/damage_amount = forced ? damage : damage * hit_percent * brutemod * H.physiology.brute_mod
if(BP)
if(damage > 0 ? BP.receive_damage(damage * hit_percent * brutemod * H.physiology.brute_mod, 0) : BP.heal_damage(abs(damage * hit_percent * brutemod * H.physiology.brute_mod), 0))
if(damage > 0 ? BP.receive_damage(damage_amount, 0) : BP.heal_damage(abs(damage_amount), 0))
H.update_damage_overlays()
if(HAS_TRAIT(H, TRAIT_MASO))
H.adjustArousalLoss(damage * brutemod * H.physiology.brute_mod)
H.adjustArousalLoss(damage_amount, 0)
if (H.getArousalLoss() >= 100 && ishuman(H) && H.has_dna())
H.mob_climax(forced_climax=TRUE)
else//no bodypart, we deal damage with a more general method.
H.adjustBruteLoss(damage * hit_percent * brutemod * H.physiology.brute_mod)
H.adjustBruteLoss(damage_amount)
if(BURN)
H.damageoverlaytemp = 20
var/damage_amount = forced ? damage : damage * hit_percent * burnmod * H.physiology.burn_mod
if(BP)
if(damage > 0 ? BP.receive_damage(0, damage * hit_percent * burnmod * H.physiology.burn_mod) : BP.heal_damage(0, abs(damage * hit_percent * burnmod * H.physiology.burn_mod)))
if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount)))
H.update_damage_overlays()
else
H.adjustFireLoss(damage * hit_percent * burnmod * H.physiology.burn_mod)
H.adjustFireLoss(damage_amount)
if(TOX)
H.adjustToxLoss(damage * hit_percent * H.physiology.tox_mod)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.tox_mod
H.adjustToxLoss(damage_amount)
if(OXY)
H.adjustOxyLoss(damage * hit_percent * H.physiology.oxy_mod)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.oxy_mod
H.adjustOxyLoss(damage_amount)
if(CLONE)
H.adjustCloneLoss(damage * hit_percent * H.physiology.clone_mod)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.clone_mod
H.adjustCloneLoss(damage_amount)
if(STAMINA)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.stamina_mod
if(BP)
if(damage > 0 ? BP.receive_damage(0, 0, damage * hit_percent * H.physiology.stamina_mod) : BP.heal_damage(0, 0, abs(damage * hit_percent * H.physiology.stamina_mod), only_robotic = FALSE, only_organic = FALSE))
if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage * hit_percent * H.physiology.stamina_mod), only_robotic = FALSE, only_organic = FALSE))
H.update_stamina()
else
H.adjustStaminaLoss(damage * hit_percent * H.physiology.stamina_mod)
H.adjustStaminaLoss(damage_amount)
if(BRAIN)
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage * hit_percent * H.physiology.brain_mod)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.brain_mod
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage_amount)
if(AROUSAL) //Citadel edit - arousal
H.adjustArousalLoss(damage * hit_percent)
return 1
@@ -634,9 +634,10 @@
id = "clockwork golem"
say_mod = "clicks"
limbs_id = "clockgolem"
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem</span><span class='bold alloy'>, you are faster than other types of golems. On death, you will break down into scrap.</span>"
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem</span><span class='bold alloy'>, you are faster than other types of golems, and are capable of using guns. On death, you will break down into scrap.</span>"
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL)
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
armor = 20 //Reinforced, but much less so to allow for fast movement
attack_verb = "smash"
attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg'
@@ -682,7 +683,7 @@
blacklisted = TRUE
dangerous_existence = TRUE
random_eligible = FALSE
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem Servant</span><span class='bold alloy'>, you are faster than other types of golems.</span>" //warcult golems leave a corpse
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem Servant</span><span class='bold alloy'>, you are faster than other types of golems, and are capable of using guns.</span>" //warcult golems leave a corpse
/datum/species/golem/cloth
name = "Cloth Golem"
@@ -45,7 +45,7 @@
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
. = min(20, amount)
/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
. = ..()
if(.)
regen_cooldown = world.time + REGENERATION_DELAY
+8 -7
View File
@@ -8,23 +8,24 @@
Returns
standard 0 if fail
*/
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
var/hit_percent = (100-blocked)/100
if(!damage || (hit_percent <= 0))
return 0
var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage * hit_percent)
adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
adjustFireLoss(damage * hit_percent)
adjustFireLoss(damage_amount, forced = forced)
if(TOX)
adjustToxLoss(damage * hit_percent)
adjustToxLoss(damage_amount, forced = forced)
if(OXY)
adjustOxyLoss(damage * hit_percent)
adjustOxyLoss(damage_amount, forced = forced)
if(CLONE)
adjustCloneLoss(damage * hit_percent)
adjustCloneLoss(damage_amount, forced = forced)
if(STAMINA)
adjustStaminaLoss(damage * hit_percent)
adjustStaminaLoss(damage_amount, forced = forced)
return 1
/mob/living/proc/apply_damage_type(damage = 0, damagetype = BRUTE) //like apply damage except it always uses the damage procs
+1 -1
View File
@@ -502,7 +502,7 @@
fire_stacks = 0
confused = 0
update_canmove()
GET_COMPONENT(mood, /datum/component/mood)
var/datum/component/mood/mood = GetComponent(/datum/component/mood)
if (mood)
QDEL_LIST_ASSOC_VAL(mood.mood_events)
mood.sanity = SANITY_GREAT
+9 -9
View File
@@ -391,16 +391,16 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return 0
/mob/living/say_mod(input, message_mode)
if(message_mode == MODE_WHISPER)
. = verb_whisper
else if(message_mode == MODE_WHISPER_CRIT)
. = ..()
if(message_mode == MODE_WHISPER_CRIT)
. = "[verb_whisper] in [p_their()] last breath"
else if(stuttering)
. = "stammers"
else if(derpspeech)
. = "gibbers"
else
. = ..()
else if(message_mode != MODE_CUSTOM_SAY)
if(message_mode == MODE_WHISPER)
. = verb_whisper
else if(stuttering)
. = "stammers"
else if(derpspeech)
. = "gibbers"
/mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced)
@@ -1,16 +1,17 @@
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
var/hit_percent = (100-blocked)/100
if(!damage || (hit_percent <= 0))
if(!damage || (!forced && hit_percent <= 0))
return 0
var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage * hit_percent)
adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
adjustFireLoss(damage * hit_percent)
adjustFireLoss(damage_amount, forced = forced)
if(OXY)
if(damage < 0) //we shouldn't be taking oxygen damage through this proc, but we'll let it heal.
adjustOxyLoss(damage * hit_percent)
if(damage < 0 || forced) //we shouldn't be taking oxygen damage through this proc, but we'll let it heal.
adjustOxyLoss(damage_amount, forced = forced)
return 1
@@ -29,7 +30,7 @@
/mob/living/silicon/setCloneLoss(amount, updating_health = TRUE, forced = FALSE)
return FALSE
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1)//immune to stamina damage.
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1, forced = FALSE)//immune to stamina damage.
return FALSE
/mob/living/silicon/setStaminaLoss(amount, updating_stamina = 1)
@@ -81,8 +81,11 @@
/mob/living/silicon/pai/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
return FALSE
/mob/living/silicon/pai/adjustStaminaLoss(amount)
take_holo_damage(amount & 0.25)
/mob/living/silicon/pai/adjustStaminaLoss(amount, updating_health, forced = FALSE)
if(forced)
take_holo_damage(amount)
else
take_holo_damage(amount * 0.25)
/mob/living/silicon/pai/adjustOrganLoss(slot, amount, maximum = 500) //I kept this in, unlike tg
Knockdown(amount * 0.2)
@@ -1233,7 +1233,7 @@
/mob/living/silicon/robot/unbuckle_mob(mob/user, force=FALSE)
if(iscarbon(user))
GET_COMPONENT(riding_datum, /datum/component/riding)
var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
if(istype(riding_datum))
riding_datum.unequip_buckle_inhands(user)
riding_datum.restore_position(user)
@@ -37,5 +37,5 @@
else if(damage_coeff[CLONE])
. = adjustHealth(amount * damage_coeff[CLONE] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
/mob/living/simple_animal/adjustStaminaLoss(amount)
/mob/living/simple_animal/adjustStaminaLoss(amount, forced = FALSE)
return
@@ -33,7 +33,7 @@
/mob/living/simple_animal/drone/syndrone/Initialize()
. = ..()
GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage)
var/datum/component/uplink/hidden_uplink = internal_storage.GetComponent(/datum/component/uplink)
hidden_uplink.telecrystals = 10
/mob/living/simple_animal/drone/syndrone/Login()
@@ -47,7 +47,7 @@
/mob/living/simple_animal/drone/syndrone/badass/Initialize()
. = ..()
GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage)
var/datum/component/uplink/hidden_uplink = internal_storage.GetComponent(/datum/component/uplink)
hidden_uplink.telecrystals = 30
var/obj/item/implant/weapons_auth/W = new
W.implant(src)
@@ -536,7 +536,7 @@
//ANIMAL RIDING
/mob/living/simple_animal/user_buckle_mob(mob/living/M, mob/user)
GET_COMPONENT(riding_datum, /datum/component/riding)
var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
if(riding_datum)
if(user.incapacitated())
return
@@ -547,7 +547,7 @@
return ..()
/mob/living/simple_animal/relaymove(mob/user, direction)
GET_COMPONENT(riding_datum, /datum/component/riding)
var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
if(tame && riding_datum)
riding_datum.handle_ride(user, direction)
+1 -1
View File
@@ -88,7 +88,7 @@
if(newletter==" ")
newletter="...huuuhhh..."
if(newletter==".")
newletter=" *BURP*."
newletter=" BURP!"
if(rand(1,100) <= strength*0.5)
if(rand(1,5) == 1)
newletter+="'"
+1 -1
View File
@@ -201,7 +201,7 @@
throwforce = 35
playsound(user, 'sound/weapons/saberon.ogg', 5, 1)
to_chat(user, "<span class='warning'>[src] is now active.</span>")
GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.butchering_enabled = on
update_icon()
+1 -1
View File
@@ -13,7 +13,7 @@
/obj/item/storage/photo_album/Initialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.can_hold = typecacheof(list(/obj/item/photo))
STR.max_combined_w_class = 42
STR.max_items = 21
+1
View File
@@ -20,6 +20,7 @@
var/self_recharge = 0 //does it self recharge, over time, or not?
var/ratingdesc = TRUE
var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it.
rad_flags = RAD_NO_CONTAMINATE // Prevent the same cheese as with the stock parts
/obj/item/stock_parts/cell/get_cell()
return src
@@ -29,7 +29,7 @@
#define MOLE_HEAT_PENALTY 350 //Heat damage scales around this. Too hot setups with this amount of moles do regular damage, anything above and below is scaled
#define POWER_PENALTY_THRESHOLD 5000 //Higher == Engine can generate more power before triggering the high power penalties.
#define SEVERE_POWER_PENALTY_THRESHOLD 7000 //Same as above, but causes more dangerous effects
#define CRITICAL_POWER_PENALTY_THRESHOLD 9000 //Even more dangerous effects, threshold for tesla delamination
#define CRITICAL_POWER_PENALTY_THRESHOLD 12000 //Even more dangerous effects, threshold for tesla delamination
#define HEAT_PENALTY_THRESHOLD 40 //Higher == Crystal safe operational temperature is higher.
#define DAMAGE_HARDCAP 0.002
#define DAMAGE_INCREASE_MULTIPLIER 0.25
+29 -53
View File
@@ -62,16 +62,16 @@
var/zoomed = FALSE //Zoom toggle
var/zoom_amt = 3 //Distance in TURFs to move the user's screen forward (the "zoom" effect)
var/zoom_out_amt = 0
var/datum/action/toggle_scope_zoom/azoom
var/datum/action/item_action/toggle_scope_zoom/azoom
/obj/item/gun/Initialize()
. = ..()
if(pin)
pin = new pin(src)
if(gun_light)
alight = new /datum/action/item_action/toggle_gunlight(src)
build_zooming()
alight = new (src)
if(zoomable)
azoom = new (src)
/obj/item/gun/CheckParts(list/parts_list)
..()
@@ -372,6 +372,12 @@
else
return ..()
/obj/item/gun/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_scope_zoom))
zoom(user)
else if(istype(action, alight))
toggle_gunlight()
/obj/item/gun/proc/toggle_gunlight()
if(!gun_light)
return
@@ -407,21 +413,10 @@
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/gun/pickup(mob/user)
..()
if(azoom)
azoom.Grant(user)
if(alight)
alight.Grant(user)
/obj/item/gun/dropped(mob/user)
..()
if(zoomed)
zoom(user,FALSE)
if(azoom)
azoom.Remove(user)
if(alight)
alight.Remove(user)
/obj/item/gun/item_action_slot_check(slot, mob/user, datum/action/A)
if(istype(A, /datum/action/item_action/toggle_scope_zoom) && slot != SLOT_HANDS)
return FALSE
return ..()
/obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer)
if(!ishuman(user) || !ishuman(target))
@@ -468,41 +463,32 @@
// ZOOMING //
/////////////
/datum/action/toggle_scope_zoom
/datum/action/item_action/toggle_scope_zoom
name = "Toggle Scope"
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "sniper_zoom"
var/obj/item/gun/gun = null
/datum/action/toggle_scope_zoom/Trigger()
gun.zoom(owner)
/datum/action/toggle_scope_zoom/IsAvailable()
/datum/action/item_action/toggle_scope_zoom/IsAvailable()
. = ..()
if(!gun)
return FALSE
if(!.)
gun.zoom(owner, FALSE)
if(!owner.get_held_index_of_item(gun))
return FALSE
/datum/action/toggle_scope_zoom/Remove(mob/living/L)
gun.zoom(L, FALSE)
..()
var/obj/item/gun/G = target
G.zoom(owner, FALSE)
/datum/action/item_action/toggle_scope_zoom/Remove(mob/living/L)
var/obj/item/gun/G = target
G.zoom(L, FALSE)
return ..()
/obj/item/gun/proc/zoom(mob/living/user, forced_zoom)
if(!user || !user.client)
if(!(user?.client))
return
switch(forced_zoom)
if(FALSE)
zoomed = FALSE
if(TRUE)
zoomed = TRUE
else
zoomed = !zoomed
if(!isnull(forced_zoom))
if(zoomed == forced_zoom)
return
zoomed = forced_zoom
else
zoomed = !zoomed
if(zoomed)
var/_x = 0
@@ -524,16 +510,6 @@
user.client.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
user.client.pixel_y = 0
return zoomed
//Proc, so that gun accessories/scopes/etc. can easily add zooming.
/obj/item/gun/proc/build_zooming()
if(azoom)
return
if(zoomable)
azoom = new()
azoom.gun = src
/obj/item/gun/handle_atom_del(atom/A)
if(A == chambered)
@@ -51,8 +51,11 @@
else
to_chat(user, "<span class='warning'>You cannot seem to get \the [src] out of your hands!</span>")
/obj/item/gun/ballistic/automatic/ui_action_click()
burst_select()
/obj/item/gun/ballistic/automatic/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_firemode))
burst_select()
else
return ..()
/obj/item/gun/ballistic/automatic/proc/burst_select()
var/mob/living/carbon/human/user = usr
-3
View File
@@ -174,9 +174,6 @@
itemState += "[ratio]"
item_state = itemState
/obj/item/gun/energy/ui_action_click()
toggle_gunlight()
/obj/item/gun/energy/suicide_act(mob/living/user)
if (istype(user) && can_shoot() && can_trigger_gun(user) && user.get_bodypart(BODY_ZONE_HEAD))
user.visible_message("<span class='suicide'>[user] is putting the barrel of [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -45,7 +45,7 @@
var/aiming_lastangle = 0
var/mob/current_user = null
var/list/obj/effect/projectile/tracer/current_tracers
var/structure_piercing = 1
var/structure_bleed_coeff = 0.7
var/wall_pierce_amount = 0
@@ -76,7 +76,7 @@
var/static/image/drained_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_empty")
var/datum/action/item_action/zoom_lock_action/zoom_lock_action
var/datum/component/mobhook
var/mob/listeningTo
/obj/item/gun/energy/beam_rifle/debug
delay = 0
@@ -111,7 +111,9 @@
to_chat(owner, "<span class='boldnotice'>You switch [src]'s zooming processor to center mode.</span>")
if(ZOOM_LOCK_OFF)
to_chat(owner, "<span class='boldnotice'>You disable [src]'s zooming system.</span>")
reset_zooming()
reset_zooming()
else
return ..()
/obj/item/gun/energy/beam_rifle/proc/set_autozoom_pixel_offsets_immediate(current_angle)
if(zoom_lock == ZOOM_LOCK_CENTER_VIEW || zoom_lock == ZOOM_LOCK_OFF)
@@ -172,7 +174,7 @@
STOP_PROCESSING(SSfastprocess, src)
set_user(null)
QDEL_LIST(current_tracers)
QDEL_NULL(mobhook)
listeningTo = null
return ..()
/obj/item/gun/energy/beam_rifle/emp_act(severity)
@@ -259,14 +261,17 @@
if(user == current_user)
return
stop_aiming(current_user)
QDEL_NULL(mobhook)
if(listeningTo)
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
listeningTo = null
if(istype(current_user))
LAZYREMOVE(current_user.mousemove_intercept_objects, src)
current_user = null
if(istype(user))
current_user = user
LAZYOR(current_user.mousemove_intercept_objects, src)
mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_mob_move)))
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move)
listeningTo = user
/obj/item/gun/energy/beam_rifle/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
if(aiming)
@@ -175,7 +175,7 @@
data["chosenPillStyle"] = chosenPillStyle
data["isPillBottleLoaded"] = bottle ? 1 : 0
if(bottle)
GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle)
var/datum/component/storage/STRB = bottle.GetComponent(/datum/component/storage)
data["pillBotContent"] = bottle.contents.len
data["pillBotMaxContent"] = STRB.max_items
@@ -263,7 +263,7 @@
var/target_loc = bottle ? bottle : drop_location()
var/drop_threshold = INFINITY
if(bottle)
GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle)
var/datum/component/storage/STRB = bottle.GetComponent(/datum/component/storage)
if(STRB)
drop_threshold = STRB.max_items - bottle.contents.len
@@ -423,7 +423,7 @@
. = 1
/datum/reagent/drug/happiness/addiction_act_stage1(mob/living/M)// all work and no play makes jack a dull boy
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(min(mood.sanity, SANITY_DISTURBED))
M.Jitter(5)
if(prob(20))
@@ -431,7 +431,7 @@
..()
/datum/reagent/drug/happiness/addiction_act_stage2(mob/living/M)
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(min(mood.sanity, SANITY_UNSTABLE))
M.Jitter(10)
if(prob(30))
@@ -439,7 +439,7 @@
..()
/datum/reagent/drug/happiness/addiction_act_stage3(mob/living/M)
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(min(mood.sanity, SANITY_CRAZY))
M.Jitter(15)
if(prob(40))
@@ -447,7 +447,7 @@
..()
/datum/reagent/drug/happiness/addiction_act_stage4(mob/living/carbon/human/M)
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(SANITY_INSANE)
M.Jitter(20)
if(prob(50))
@@ -1443,7 +1443,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
M.dizziness = max(0, M.dizziness-6)
M.confused = max(0, M.confused-6)
M.disgust = max(0, M.disgust-6)
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
if(mood.sanity <= SANITY_NEUTRAL) // only take effect if in negative sanity and then...
mood.setSanity(min(mood.sanity+5, SANITY_NEUTRAL)) // set minimum to prevent unwanted spiking over neutral
..()
@@ -2295,26 +2295,22 @@
chemical_flags = REAGENT_INVISIBLE
/datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C)
if(C && C.dna && data["desired_dna"])
if(ishuman(C) && C.dna && data["desired_dna"])
original_dna = new C.dna.type
C.dna.copy_dna(original_dna)
var/datum/dna/new_dna = data["desired_dna"]
new_dna.copy_dna(C.dna)
new_dna.transfer_identity(C, TRUE)
C.real_name = new_dna.real_name
C.updateappearance(mutcolor_update=1)
C.update_body()
C.updateappearance(mutcolor_update = TRUE)
C.domutcheck()
C.regenerate_icons()
..()
/datum/reagent/changeling_string/on_mob_end_metabolize(mob/living/carbon/C)
if(original_dna)
original_dna.copy_dna(C.dna)
original_dna.transfer_identity(C, TRUE)
C.real_name = original_dna.real_name
C.updateappearance(mutcolor_update=1)
C.update_body()
C.updateappearance(mutcolor_update = TRUE)
C.domutcheck()
C.regenerate_icons()
..()
/datum/reagent/changeling_string/Destroy()
+1 -1
View File
@@ -283,7 +283,7 @@
/obj/machinery/disposal/bin/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/storage/bag/trash)) //Not doing component overrides because this is a specific type.
var/obj/item/storage/bag/trash/T = I
GET_COMPONENT_FROM(STR, /datum/component/storage, T)
var/datum/component/storage/STR = T.GetComponent(/datum/component/storage)
to_chat(user, "<span class='warning'>You empty the bag.</span>")
for(var/obj/item/O in T.contents)
STR.remove_from_storage(O,src)
@@ -29,7 +29,7 @@
pipename = initial(pipe_type.name)
if(flip)
GET_COMPONENT(rotcomp,/datum/component/simple_rotation)
var/datum/component/simple_rotation/rotcomp = GetComponent(/datum/component/simple_rotation)
rotcomp.BaseRot(null,ROTATION_FLIP)
update_icon()
+1 -1
View File
@@ -422,7 +422,7 @@
if(exp == SCANTYPE_OBLITERATE)
visible_message("<span class='warning'>[exp_on] activates the crushing mechanism, [exp_on] is destroyed!</span>")
if(linked_console.linked_lathe)
GET_COMPONENT_FROM(linked_materials, /datum/component/material_container, linked_console.linked_lathe)
var/datum/component/material_container/linked_materials = linked_console.linked_lathe.GetComponent(/datum/component/material_container)
for(var/material in exp_on.materials)
linked_materials.insert_amount( min((linked_materials.max_amount - linked_materials.total_amount), (exp_on.materials[material])), material)
if(prob(EFFECT_PROB_LOW) && criticalReaction)
+9
View File
@@ -29,3 +29,12 @@
/obj/item/disk/tech_disk/illegal/Initialize()
. = ..()
stored_research = new /datum/techweb/syndicate
/obj/item/disk/tech_disk/abductor
name = "Gray technology disk"
desc = "You feel like it's not Gray because of its color."
materials = list()
/obj/item/disk/tech_disk/abductor/Initialize()
. = ..()
stored_research = new /datum/techweb/abductor
@@ -49,6 +49,14 @@
var/datum/techweb_node/syndicate_basic/Node = new()
research_node(Node, TRUE)
/datum/techweb/abductor
id = "ABDUCTOR"
organization = "Aliens"
/datum/techweb/abductor/New()
var/datum/techweb_node/alientech/Node = new()
research_node(Node, TRUE)
/datum/techweb/science //Global science techweb for RND consoles.
id = "SCIENCE"
organization = "Nanotrasen"
+7 -14
View File
@@ -1027,26 +1027,19 @@
id = "alien_bio"
display_name = "Alien Biological Tools"
description = "Advanced biological tools."
prereq_ids = list("alientech", "adv_biotech")
prereq_ids = list("alientech", "advance_surgerytools")
design_ids = list("alien_scalpel", "alien_hemostat", "alien_retractor", "alien_saw", "alien_drill", "alien_cautery")
boost_item_paths = list(/obj/item/gun/energy/alien, /obj/item/scalpel/alien, /obj/item/hemostat/alien, /obj/item/retractor/alien, /obj/item/circular_saw/alien,
/obj/item/cautery/alien, /obj/item/surgicaldrill/alien, /obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor, /obj/item/stock_parts/cell/infinite/abductor,
/obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 20000
hidden = TRUE
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 10000
/datum/techweb_node/alien_engi
id = "alien_engi"
display_name = "Alien Engineering"
description = "Alien engineering tools"
prereq_ids = list("alientech", "adv_engi")
prereq_ids = list("alientech", "exp_tools")
design_ids = list("alien_wrench", "alien_wirecutters", "alien_screwdriver", "alien_crowbar", "alien_welder", "alien_multitool")
boost_item_paths = list(/obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor, /obj/item/stock_parts/cell/infinite/abductor,
/obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 20000
hidden = TRUE
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 10000
/datum/techweb_node/syndicate_basic
id = "syndicate_basic"
@@ -1106,4 +1099,4 @@
for(var/i in processing)
var/datum/techweb_node/TN = i
TW.add_point_list(TN.research_costs)
return TW.printout_points()
return TW.printout_points()
@@ -58,9 +58,7 @@
var/mob/living/carbon/human/H = M
if(H.mind && !HAS_TRAIT(H, TRAIT_AGEUSIA))
to_chat(H,"<span class='notice'>That didn't taste very good...</span>") //No disgust, though. It's just not good tasting.
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
if(mood)
mood.add_event(null,"gross_food", /datum/mood_event/gross_food)
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "gross_food", /datum/mood_event/gross_food)
last_check_time = world.time
return
..()
@@ -64,10 +64,9 @@
var/interrupted = FALSE
var/mob/target
var/icon/bluespace
var/datum/weakref/redirect_component
/datum/status_effect/slimerecall/on_apply()
redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/resistField))))
RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/resistField)
to_chat(owner, "<span class='danger'>You feel a sudden tug from an unknown force, and feel a pull to bluespace!</span>")
to_chat(owner, "<span class='notice'>Resist if you wish avoid the force!</span>")
bluespace = icon('icons/effects/effects.dmi',"chronofield")
@@ -77,9 +76,9 @@
/datum/status_effect/slimerecall/proc/resistField()
interrupted = TRUE
owner.remove_status_effect(src)
/datum/status_effect/slimerecall/on_remove()
qdel(redirect_component.resolve())
redirect_component = null
UnregisterSignal(owner, COMSIG_LIVING_RESIST)
owner.cut_overlay(bluespace)
if(interrupted || !ismob(target))
to_chat(owner, "<span class='warning'>The bluespace tug fades away, and you feel that the force has passed you by.</span>")
@@ -98,10 +97,9 @@
duration = -1 //Will remove self when block breaks.
alert_type = /obj/screen/alert/status_effect/freon/stasis
var/obj/structure/ice_stasis/cube
var/datum/weakref/redirect_component
/datum/status_effect/frozenstasis/on_apply()
redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/breakCube))))
RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/breakCube)
cube = new /obj/structure/ice_stasis(get_turf(owner))
owner.forceMove(cube)
owner.status_flags |= GODMODE
@@ -118,8 +116,7 @@
if(cube)
qdel(cube)
owner.status_flags &= ~GODMODE
qdel(redirect_component.resolve())
redirect_component = null
UnregisterSignal(owner, COMSIG_LIVING_RESIST)
/datum/status_effect/slime_clone
id = "slime_cloned"
@@ -29,8 +29,6 @@
var/datum/action/innate/slime_scan/scan_action
var/datum/action/innate/feed_potion/potion_action
var/datum/component/redirect/listener
var/list/stored_slimes
var/obj/item/slimepotion/slime/current_potion
var/max_slimes = 5
@@ -50,7 +48,7 @@
scan_action = new
potion_action = new
stored_slimes = list()
listener = AddComponent(/datum/component/redirect, list(COMSIG_ATOM_CONTENTS_DEL = CALLBACK(src, .proc/on_contents_del)))
RegisterSignal(src, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del)
/obj/machinery/computer/camera_advanced/xenobio/Destroy()
stored_slimes = null
@@ -0,0 +1,530 @@
GLOBAL_VAR_INIT(hhStorageTurf, null)
GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
/obj/item/hilbertshotel
name = "Hilbert's Hotel"
desc = "A sphere of what appears to be an intricate network of bluespace. Observing it in detail seems to give you a headache as you try to comprehend the infinite amount of infinitesimally distinct points on its surface."
icon_state = "hilbertshotel"
w_class = WEIGHT_CLASS_SMALL
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/datum/map_template/hilbertshotel/hotelRoomTemp
var/datum/map_template/hilbertshotel/empty/hotelRoomTempEmpty
var/datum/map_template/hilbertshotel/lore/hotelRoomTempLore
var/list/activeRooms = list()
var/list/storedRooms = list()
var/storageTurf
//Lore Stuff
var/ruinSpawned = FALSE
var/mysteryRoom
/obj/item/hilbertshotel/Initialize()
. = ..()
//Load templates
hotelRoomTemp = new()
hotelRoomTempEmpty = new()
hotelRoomTempLore = new()
var/area/currentArea = get_area(src)
if(currentArea.type == /area/ruin/space/has_grav/hilbertresearchfacility)
ruinSpawned = TRUE
/obj/item/hilbertshotel/Destroy()
ejectRooms()
return ..()
/obj/item/hilbertshotel/attack(mob/living/M, mob/living/user)
if(M.mind)
to_chat(user, "<span class='notice'>You invite [M] to the hotel.</span>")
promptAndCheckIn(M)
else
to_chat(user, "<span class='warning'>[M] is not intelligent enough to understand how to use this device!</span>")
/obj/item/hilbertshotel/attack_self(mob/user)
. = ..()
promptAndCheckIn(user)
/obj/item/hilbertshotel/proc/promptAndCheckIn(mob/user)
var/chosenRoomNumber = input(user, "What number room will you be checking into?", "Room Number") as null|num
if(!chosenRoomNumber)
return
if(chosenRoomNumber > SHORT_REAL_LIMIT)
to_chat(user, "<span class='warning'>You have to check out the first [SHORT_REAL_LIMIT] rooms before you can go to a higher numbered one!</span>")
return
if((chosenRoomNumber < 1) || (chosenRoomNumber != round(chosenRoomNumber)))
to_chat(user, "<span class='warning'>That is not a valid room number!</span>")
return
if(ismob(loc))
if(user == loc) //Not always the same as user
forceMove(get_turf(user))
if(!storageTurf) //Blame subsystems for not allowing this to be in Initialize
if(!GLOB.hhStorageTurf)
var/datum/map_template/hilbertshotelstorage/storageTemp = new()
var/datum/turf_reservation/storageReservation = SSmapping.RequestBlockReservation(3, 3)
storageTemp.load(locate(storageReservation.bottom_left_coords[1], storageReservation.bottom_left_coords[2], storageReservation.bottom_left_coords[3]))
GLOB.hhStorageTurf = locate(storageReservation.bottom_left_coords[1]+1, storageReservation.bottom_left_coords[2]+1, storageReservation.bottom_left_coords[3])
else
storageTurf = GLOB.hhStorageTurf
if(tryActiveRoom(chosenRoomNumber, user))
return
if(tryStoredRoom(chosenRoomNumber, user))
return
sendToNewRoom(chosenRoomNumber, user)
/obj/item/hilbertshotel/proc/tryActiveRoom(var/roomNumber, var/mob/user)
if(activeRooms["[roomNumber]"])
var/datum/turf_reservation/roomReservation = activeRooms["[roomNumber]"]
do_sparks(3, FALSE, get_turf(user))
user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
return TRUE
else
return FALSE
/obj/item/hilbertshotel/proc/tryStoredRoom(var/roomNumber, var/mob/user)
if(storedRooms["[roomNumber]"])
var/datum/turf_reservation/roomReservation = SSmapping.RequestBlockReservation(hotelRoomTemp.width, hotelRoomTemp.height)
hotelRoomTempEmpty.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
var/turfNumber = 1
for(var/i=0, i<hotelRoomTemp.width, i++)
for(var/j=0, j<hotelRoomTemp.height, j++)
for(var/atom/movable/A in storedRooms["[roomNumber]"][turfNumber])
if(istype(A.loc, /obj/item/abstracthotelstorage))//Don't want to recall something thats been moved
A.forceMove(locate(roomReservation.bottom_left_coords[1] + i, roomReservation.bottom_left_coords[2] + j, roomReservation.bottom_left_coords[3]))
turfNumber++
for(var/obj/item/abstracthotelstorage/S in storageTurf)
if((S.roomNumber == roomNumber) && (S.parentSphere == src))
qdel(S)
storedRooms -= "[roomNumber]"
activeRooms["[roomNumber]"] = roomReservation
linkTurfs(roomReservation, roomNumber)
do_sparks(3, FALSE, get_turf(user))
user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
return TRUE
else
return FALSE
/obj/item/hilbertshotel/proc/sendToNewRoom(var/roomNumber, var/mob/user)
var/datum/turf_reservation/roomReservation = SSmapping.RequestBlockReservation(hotelRoomTemp.width, hotelRoomTemp.height)
if(ruinSpawned)
mysteryRoom = GLOB.hhmysteryRoomNumber
if(roomNumber == mysteryRoom)
hotelRoomTempLore.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
else
hotelRoomTemp.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
else
hotelRoomTemp.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
activeRooms["[roomNumber]"] = roomReservation
linkTurfs(roomReservation, roomNumber)
do_sparks(3, FALSE, get_turf(user))
user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
/obj/item/hilbertshotel/proc/linkTurfs(var/datum/turf_reservation/currentReservation, var/currentRoomnumber)
var/area/hilbertshotel/currentArea = get_area(locate(currentReservation.bottom_left_coords[1], currentReservation.bottom_left_coords[2], currentReservation.bottom_left_coords[3]))
currentArea.name = "Hilbert's Hotel Room [currentRoomnumber]"
currentArea.parentSphere = src
currentArea.storageTurf = storageTurf
currentArea.roomnumber = currentRoomnumber
currentArea.reservation = currentReservation
for(var/turf/closed/indestructible/hoteldoor/door in currentArea)
door.parentSphere = src
door.desc = "The door to this hotel room. The placard reads 'Room [currentRoomnumber]'. Strange, this door doesnt even seem openable. The doorknob, however, seems to buzz with unusual energy...<br /><span class='info'>Alt-Click to look through the peephole.</span>"
for(var/turf/open/space/bluespace/BSturf in currentArea)
BSturf.parentSphere = src
/obj/item/hilbertshotel/proc/ejectRooms()
if(activeRooms.len)
for(var/x in activeRooms)
var/datum/turf_reservation/room = activeRooms[x]
for(var/i=0, i<hotelRoomTemp.width, i++)
for(var/j=0, j<hotelRoomTemp.height, j++)
for(var/atom/movable/A in locate(room.bottom_left_coords[1] + i, room.bottom_left_coords[2] + j, room.bottom_left_coords[3]))
if(ismob(A))
var/mob/M = A
if(M.mind)
to_chat(M, "<span class='warning'>As the sphere breaks apart, you're suddenly ejected into the depths of space!</span>")
var/max = world.maxx-TRANSITIONEDGE
var/min = 1+TRANSITIONEDGE
var/list/possible_transtitons = list()
for(var/AZ in SSmapping.z_list)
var/datum/space_level/D = AZ
if (D.linkage == CROSSLINKED)
possible_transtitons += D.z_value
var/_z = pick(possible_transtitons)
var/_x = rand(min,max)
var/_y = rand(min,max)
var/turf/T = locate(_x, _y, _z)
A.forceMove(T)
qdel(room)
if(storedRooms.len)
for(var/x in storedRooms)
var/list/atomList = storedRooms[x]
for(var/atom/movable/A in atomList)
var/max = world.maxx-TRANSITIONEDGE
var/min = 1+TRANSITIONEDGE
var/list/possible_transtitons = list()
for(var/AZ in SSmapping.z_list)
var/datum/space_level/D = AZ
if (D.linkage == CROSSLINKED)
possible_transtitons += D.z_value
var/_z = pick(possible_transtitons)
var/_x = rand(min,max)
var/_y = rand(min,max)
var/turf/T = locate(_x, _y, _z)
A.forceMove(T)
//Template Stuff
/datum/map_template/hilbertshotel
name = "Hilbert's Hotel Room"
mappath = '_maps/templates/hilbertshotel.dmm'
var/landingZoneRelativeX = 2
var/landingZoneRelativeY = 8
/datum/map_template/hilbertshotel/empty
name = "Empty Hilbert's Hotel Room"
mappath = '_maps/templates/hilbertshotelempty.dmm'
/datum/map_template/hilbertshotel/lore
name = "Doctor Hilbert's Deathbed"
mappath = '_maps/templates/hilbertshotellore.dmm'
/datum/map_template/hilbertshotelstorage
name = "Hilbert's Hotel Storage"
mappath = '_maps/templates/hilbertshotelstorage.dmm'
//Turfs and Areas
/turf/closed/indestructible/hotelwall
name = "hotel wall"
desc = "A wall designed to protect the security of the hotel's guests."
icon_state = "hotelwall"
canSmoothWith = list(/turf/closed/indestructible/hotelwall)
explosion_block = INFINITY
/turf/open/indestructible/hotelwood
desc = "Stylish dark wood with extra reinforcement. Secured firmly to the floor to prevent tampering."
icon_state = "wood"
footstep = FOOTSTEP_WOOD
tiled_dirt = FALSE
/turf/open/indestructible/hoteltile
desc = "Smooth tile with extra reinforcement. Secured firmly to the floor to prevent tampering."
icon_state = "showroomfloor"
footstep = FOOTSTEP_FLOOR
tiled_dirt = FALSE
/turf/open/space/bluespace
name = "\proper bluespace hyperzone"
icon_state = "bluespace"
baseturfs = /turf/open/space/bluespace
flags_1 = NOJAUNT_1
explosion_block = INFINITY
var/obj/item/hilbertshotel/parentSphere
/turf/open/space/bluespace/Entered(atom/movable/A)
. = ..()
A.forceMove(get_turf(parentSphere))
do_sparks(3, FALSE, get_turf(A))
/turf/closed/indestructible/hoteldoor
name = "Hotel Door"
icon_state = "hoteldoor"
explosion_block = INFINITY
var/obj/item/hilbertshotel/parentSphere
/turf/closed/indestructible/hoteldoor/proc/promptExit(mob/living/user)
if(!isliving(user))
return
if(!user.mind)
return
if(!parentSphere)
to_chat(user, "<span class='warning'>The door seems to be malfunctioning and refuses to operate!</span>")
return
if(alert(user, "Hilbert's Hotel would like to remind you that while we will do everything we can to protect the belongings you leave behind, we make no guarantees of their safety while you're gone, especially that of the health of any living creatures. With that in mind, are you ready to leave?", "Exit", "Leave", "Stay") == "Leave")
if(!user.canmove || (get_dist(get_turf(src), get_turf(user)) > 1)) //no teleporting around if they're dead or moved away during the prompt.
return
user.forceMove(get_turf(parentSphere))
do_sparks(3, FALSE, get_turf(user))
/turf/closed/indestructible/hoteldoor/attack_ghost(mob/dead/observer/user)
if(!isobserver(user) || !parentSphere)
return ..()
user.forceMove(get_turf(parentSphere))
//If only this could be simplified...
/turf/closed/indestructible/hoteldoor/attack_tk(mob/user)
return //need to be close.
/turf/closed/indestructible/hoteldoor/attack_hand(mob/user)
promptExit(user)
/turf/closed/indestructible/hoteldoor/attack_animal(mob/user)
promptExit(user)
/turf/closed/indestructible/hoteldoor/attack_paw(mob/user)
promptExit(user)
/turf/closed/indestructible/hoteldoor/attack_hulk(mob/living/carbon/human/user, does_attack_animation)
promptExit(user)
/turf/closed/indestructible/hoteldoor/attack_larva(mob/user)
promptExit(user)
/turf/closed/indestructible/hoteldoor/attack_slime(mob/user)
promptExit(user)
/turf/closed/indestructible/hoteldoor/attack_robot(mob/user)
if(get_dist(get_turf(src), get_turf(user)) <= 1)
promptExit(user)
/turf/closed/indestructible/hoteldoor/AltClick(mob/user)
. = ..()
if(get_dist(get_turf(src), get_turf(user)) <= 1)
to_chat(user, "<span class='notice'>You peak through the door's bluespace peephole...</span>")
user.reset_perspective(parentSphere)
user.set_machine(src)
var/datum/action/peepholeCancel/PHC = new
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
PHC.Grant(user)
/turf/closed/indestructible/hoteldoor/check_eye(mob/user)
if(get_dist(get_turf(src), get_turf(user)) >= 2)
user.unset_machine()
for(var/datum/action/peepholeCancel/PHC in user.actions)
PHC.Trigger()
/datum/action/peepholeCancel
name = "Cancel View"
desc = "Stop looking through the bluespace peephole."
button_icon_state = "cancel_peephole"
/datum/action/peepholeCancel/Trigger()
. = ..()
to_chat(owner, "<span class='warning'>You move away from the peephole.</span>")
owner.reset_perspective()
owner.clear_fullscreen("remote_view", 0)
qdel(src)
/area/hilbertshotel
name = "Hilbert's Hotel Room"
icon_state = "hilbertshotel"
requires_power = FALSE
has_gravity = TRUE
noteleport = TRUE
hidden = TRUE
unique = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
ambientsounds = list('sound/ambience/servicebell.ogg')
var/roomnumber = 0
var/obj/item/hilbertshotel/parentSphere
var/datum/turf_reservation/reservation
var/turf/storageTurf
/area/hilbertshotel/Entered(atom/movable/AM)
. = ..()
if(istype(AM, /obj/item/hilbertshotel))
relocate(AM)
var/list/obj/item/hilbertshotel/hotels = AM.GetAllContents(/obj/item/hilbertshotel)
for(var/obj/item/hilbertshotel/H in hotels)
if(parentSphere == H)
relocate(H)
/area/hilbertshotel/proc/relocate(obj/item/hilbertshotel/H)
if(prob(0.135685)) //Because screw you
qdel(H)
return
var/turf/targetturf = find_safe_turf()
if(!targetturf)
if(GLOB.blobstart.len > 0)
targetturf = get_turf(pick(GLOB.blobstart))
else
CRASH("Unable to find a blobstart landmark")
var/turf/T = get_turf(H)
var/area/A = T.loc
log_game("[H] entered itself. Moving it to [loc_name(targetturf)].")
message_admins("[H] entered itself. Moving it to [ADMIN_VERBOSEJMP(targetturf)].")
for(var/mob/M in A)
to_chat(M, "<span class='danger'>[H] almost implodes in upon itself, but quickly rebounds, shooting off into a random point in space!</span>")
H.forceMove(targetturf)
/area/hilbertshotel/Exited(atom/movable/AM)
. = ..()
if(ismob(AM))
var/mob/M = AM
if(M.mind)
var/stillPopulated = FALSE
var/list/currentLivingMobs = GetAllContents(/mob/living) //Got to catch anyone hiding in anything
for(var/mob/living/L in currentLivingMobs) //Check to see if theres any sentient mobs left.
if(L.mind)
stillPopulated = TRUE
break
if(!stillPopulated)
storeRoom()
/area/hilbertshotel/proc/storeRoom()
var/roomSize = (reservation.top_right_coords[1]-reservation.bottom_left_coords[1]+1)*(reservation.top_right_coords[2]-reservation.bottom_left_coords[2]+1)
var/storage[roomSize]
var/turfNumber = 1
var/obj/item/abstracthotelstorage/storageObj = new(storageTurf)
storageObj.roomNumber = roomnumber
storageObj.parentSphere = parentSphere
storageObj.name = "Room [roomnumber] Storage"
for(var/i=0, i<parentSphere.hotelRoomTemp.width, i++)
for(var/j=0, j<parentSphere.hotelRoomTemp.height, j++)
var/list/turfContents = list()
for(var/atom/movable/A in locate(reservation.bottom_left_coords[1] + i, reservation.bottom_left_coords[2] + j, reservation.bottom_left_coords[3]))
if(ismob(A) && !isliving(A))
continue //Don't want to store ghosts
turfContents += A
A.forceMove(storageObj)
storage[turfNumber] = turfContents
turfNumber++
parentSphere.storedRooms["[roomnumber]"] = storage
parentSphere.activeRooms -= "[roomnumber]"
qdel(reservation)
/area/hilbertshotelstorage
name = "Hilbert's Hotel Storage Room"
icon_state = "hilbertshotel"
requires_power = FALSE
has_gravity = TRUE
noteleport = TRUE
hidden = TRUE
/obj/item/abstracthotelstorage
anchored = TRUE
invisibility = INVISIBILITY_ABSTRACT
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
item_flags = ABSTRACT
var/roomNumber
var/obj/item/hilbertshotel/parentSphere
/obj/item/abstracthotelstorage/Entered(atom/movable/AM, atom/oldLoc)
. = ..()
if(ismob(AM))
var/mob/M = AM
M.notransform = TRUE
/obj/item/abstracthotelstorage/Exited(atom/movable/AM, atom/newLoc)
. = ..()
if(ismob(AM))
var/mob/M = AM
M.notransform = FALSE
//Space Ruin stuff
/area/ruin/space/has_grav/hilbertresearchfacility
name = "Hilbert Research Facility"
/obj/item/analyzer/hilbertsanalyzer
name = "custom rigged analyzer"
desc = "A hand-held environmental scanner which reports current gas levels. This one seems custom rigged to additionally be able to analyze some sort of bluespace device."
icon_state = "hilbertsanalyzer"
/obj/item/analyzer/hilbertsanalyzer/afterattack(atom/target, mob/user, proximity)
. = ..()
if(istype(target, /obj/item/hilbertshotel))
if(!proximity)
to_chat(user, "<span class='warning'>It's to far away to scan!</span>")
return
var/obj/item/hilbertshotel/sphere = target
if(sphere.activeRooms.len)
to_chat(user, "Currently Occupied Rooms:")
for(var/roomnumber in sphere.activeRooms)
to_chat(user, roomnumber)
else
to_chat(user, "No currenty occupied rooms.")
if(sphere.storedRooms.len)
to_chat(user, "Vacated Rooms:")
for(var/roomnumber in sphere.storedRooms)
to_chat(user, roomnumber)
else
to_chat(user, "No vacated rooms.")
/obj/effect/mob_spawn/human/doctorhilbert
name = "Doctor Hilbert"
mob_name = "Doctor Hilbert"
mob_gender = "male"
assignedrole = null
ghost_usable = FALSE
oxy_damage = 500
mob_species = /datum/species/skeleton
id_job = "Head Researcher"
id_access = ACCESS_RESEARCH
id_access_list = list(ACCESS_AWAY_GENERIC3, ACCESS_RESEARCH)
instant = TRUE
id = /obj/item/card/id/silver
uniform = /obj/item/clothing/under/rank/research_director
shoes = /obj/item/clothing/shoes/sneakers/brown
back = /obj/item/storage/backpack/satchel/leather
suit = /obj/item/clothing/suit/toggle/labcoat
/obj/item/paper/crumpled/docslogs
name = "Research Logs"
/obj/item/paper/crumpled/docslogs/Initialize()
. = ..()
GLOB.hhmysteryRoomNumber = rand(1, SHORT_REAL_LIMIT)
info = {"<h4><center>Research Logs</center></h4>
I might just be onto something here!<br>
The strange space-warping properties of bluespace have been known about for awhile now, but I might be on the verge of discovering a new way of harnessing it.<br>
It's too soon to say for sure, but this might be the start of something quite important!<br>
I'll be sure to log any major future breakthroughs. This might be a lot more than I can manage on my own, perhaps I should hire that secretary after all...<br>
<h4>Breakthrough!</h4>
I can't believe it, but I did it! Just when I was certain it couldn't be done, I made the final necessary breakthrough.<br>
Exploiting the effects of space dilation caused by specific bluespace structures combined with a precise use of geometric calculus, I've discovered a way to correlate an infinite amount of space within a finite area!<br>
While the potential applications are endless, I utilized it in quite a nifty way so far by designing a system that recursively constructs subspace rooms and spatially links them to any of the infinite infinitesimally distinct points on the spheres surface.<br>
I call it: Hilbert's Hotel!<br>
<h4>Goodbye</h4>
I can't take this anymore. I know what happens next, and the fear of what is coming leaves me unable to continue working.<br>
Any fool in my field has heard the stories. It's not that I didn't believe them, it's just... I guess I underestimated the importance of my own research...<br>
Robert has reported a further increase in frequency of the strange, prying visitors who ask questions they have no business asking. I've requested him to keep everything on strict lockdown and have permanently dismissed all other assistants.<br>
I've also instructed him to use the encryption method we discussed for any important quantitative data. The poor lad... I don't think he truly understands what he's gotten himself into...<br>
It's clear what happens now. One day they'll show up uninvited, and claim my research as their own, leaving me as nothing more than a bullet ridden corpse floating in space.<br>
I can't stick around to the let that happen.<br>
I'm escaping into the very thing that brought all this trouble to my doorstep in the first place - my hotel.<br>
I'll be in <u>[uppertext(num2hex(GLOB.hhmysteryRoomNumber, 0))]</u> (That will make sense to anyone who should know)<br>
I'm sorry that I must go like this. Maybe one day things will be different and it will be safe to return... maybe...<br>
Goodbye<br>
<br>
<i>Doctor Hilbert</i>"}
/obj/item/paper/crumpled/robertsworkjournal
name = "Work Journal"
info = {"<h4>First Week!</h4>
First week on the new job. It's a secretarial position, but hey, whatever pays the bills. Plus it seems like some interesting stuff goes on here.<br>
Doc says its best that I don't openly talk about his research with others, I guess he doesn't want it getting out or something. I've caught myself slipping a few times when talking to others, it's hard not to brag about something this cool!<br>
I'm not really sure why I'm choosing to journal this. Doc seems to log everything. He says it's incase he discovers anything important.<br>
I guess that's why I'm doing it too, I've always wanted to be a part of something important.<br>
Here's to a new job and to becoming a part of something important!<br>
<h4>Weird times...</h4>
Things are starting to get a little strange around here. Just weeks after Doc's amazing breakthrough, weird visitors have began showing up unannounced, asking strange things about Doc's work.<br>
I knew Doc wasn't a big fan of company, but even he seemed strangely unnerved when I told him about the visitors.<br>
He said it's important that from here on out we keep tight security on everything, even other staff members.<br>
He also said something about securing data, something about hexes. What's that mean? Some sort of curse? Doc never struck me as the magic type...<br>
He often uses a lot of big sciencey words that I don't really understand, but I kinda dig it, it makes me feel like I'm witnessing something big.<br>
I hope things go back to normal soon, but I guess that's the price you pay for being a part of something important.<br>
<h4>Last day I guess?</h4>
Things are officially starting to get too strange for me.<br>
The visitors have been coming a lot more often, and they all seem increasingly aggressive and nosey. I'm starting to see why they made Doc so nervous, they're certainly starting to creep me out too.<br>
Awhile ago Doc started having me keep the place on strict lockdown and requested I refuse entry to anyone else, including previous staff.<br>
But the weirdest part?<br>
I haven't seen Doc in days. It's not unusual for him to work continuously for long periods of time in the lab, but when I took a peak in their yesterday - he was nowhere to be seen! I didn't risk prying much further, Doc had a habit of leaving the defense systems on these last few weeks.<br>
I'm thinking it might be time to call it quits. Can't work much without a boss, plus things are starting to get kind of shady. I wanted to be a part of something important, but you gotta know when to play it safe.<br>
As my dad always said, "The smart get famous, but the wise survive..."<br>
<br>
<i>Robert P.</i>"}
/obj/item/paper/crumpled/bloody/docsdeathnote
name = "note"
info = {"This is it isn't it?<br>
No one's coming to help, that much has become clear.<br>
Sure, it's lonely, but do I have much choice? At least I brought the analyzer with me, they shouldn't be able to find me without it.<br>
Who knows who's waiting for me out there. Its either die out there in their hands, or die a slower, slightly more comfortable death in here.<br>
Everyday I can feel myself slipping away more and more, both physically and mentally. Who knows what happens now...<br>
Heh, so it's true then, this must be the inescapable path of all great minds... so be it then.<br>
<br>
<br>
<br>
<i>Choose a room, and enter the sphere<br>
Lay your head to rest, it soon becomes clear<br>
There's always more room around every bend<br>
Not all that's countable has an end...<i>"}
+1 -1
View File
@@ -290,7 +290,7 @@ All ShuttleMove procs go here
// ignores the movement of the shuttle from the staging area on CentCom to
// the station as it is loaded in.
if (oldT && !is_centcom_level(oldT.z))
GET_COMPONENT(STR, /datum/component/storage/concrete/emergency)
var/datum/component/storage/concrete/emergency/STR = GetComponent(/datum/component/storage/concrete/emergency)
STR?.unlock_me()
/************************************Mob move procs************************************/
+2 -1
View File
@@ -24,7 +24,8 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
/obj/effect/portal,
/obj/item/shared_storage,
/obj/structure/extraction_point,
/obj/machinery/syndicatebomb
/obj/machinery/syndicatebomb,
/obj/item/hilbertshotel
)))
/obj/docking_port/mobile/supply
@@ -146,7 +146,7 @@
clothes_req = 0
invocation = "none"
invocation_type = "none"
proj_type = /obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile/lesser
proj_type = "/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile/lesser"
proj_lifespan = 10
max_targets = 6
action_icon_state = "magicm"
@@ -13,7 +13,7 @@
var/revert_on_death = TRUE
var/die_with_shapeshifted_form = TRUE
var/convert_damage = FALSE //If you want to convert the caster's health to the shift, and vice versa.
var/convert_damage = TRUE //If you want to convert the caster's health to the shift, and vice versa.
var/convert_damage_type = BRUTE //Since simplemobs don't have advanced damagetypes, what to convert damage back into.
var/shapeshift_type
var/list/possible_shapes = list(/mob/living/simple_animal/mouse,\
@@ -101,8 +101,10 @@
stored.forceMove(src)
stored.notransform = TRUE
if(source.convert_damage)
var/damapply = (stored.maxHealth - (stored.health + stored.maxHealth)/2) //Carbons go from -100 to 100 naturally, while simplemobs only go from 0 to 100. Can't do a direct conversion.
shape.apply_damage(damapply, source.convert_damage_type)
var/damage_percent = (stored.maxHealth - stored.health)/stored.maxHealth;
var/damapply = damage_percent * shape.maxHealth;
shape.apply_damage(damapply, source.convert_damage_type, forced = TRUE);
slink = soullink(/datum/soullink/shapeshift, stored , shape)
slink.source = src
@@ -152,8 +154,10 @@
stored.death()
else if(source.convert_damage)
stored.revive(full_heal = TRUE)
var/damapply = (shape.maxHealth - 2*shape.health) //Since we halved incoming damage, double outgoing.
stored.apply_damage(damapply, source.convert_damage_type)
var/damage_percent = (shape.maxHealth - shape.health)/shape.maxHealth;
var/damapply = stored.maxHealth * damage_percent
stored.apply_damage(damapply, source.convert_damage_type, forced = TRUE)
qdel(shape)
qdel(src)
@@ -61,6 +61,10 @@
organ.Remove(organ.owner)
else
while(!isturf(item_to_retrieve.loc) && infinite_recursion < 10) //if it's in something you get the whole thing.
if(isitem(item_to_retrieve.loc))
var/obj/item/I = item_to_retrieve.loc
if(I.item_flags & ABSTRACT) //Being able to summon abstract things because your item happened to get placed there is a no-no
break
if(ismob(item_to_retrieve.loc)) //If its on someone, properly drop it
var/mob/M = item_to_retrieve.loc
+1 -1
View File
@@ -917,7 +917,7 @@
speaktrigger += "[(H.client?.prefs.lewdchem?"You are my whole world and all of my being belongs to you, ":"I cannot think of anything else but aiding your cause, ")] "//Redflags!!
//mood
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
var/datum/component/mood/mood = H.GetComponent(/datum/component/mood)
switch(mood.sanity)
if(SANITY_GREAT to INFINITY)
speaktrigger += "I'm beyond elated!! " //did you mean byond elated? hohoho
+1
View File
@@ -2,6 +2,7 @@
//Keep this sorted alphabetically
#ifdef UNIT_TESTS
#include "component_tests.dm"
#include "reagent_id_typos.dm"
#include "reagent_recipe_collisions.dm"
#include "spawn_humans.dm"
@@ -0,0 +1,12 @@
/datum/unit_test/component_duping/Run()
var/list/bad_dms = list()
var/list/bad_dts = list()
for(var/t in typesof(/datum/component))
var/datum/component/comp = t
if(!isnum(initial(comp.dupe_mode)))
bad_dms += t
var/dupe_type = initial(comp.dupe_type)
if(dupe_type && !ispath(dupe_type))
bad_dts += t
if(length(bad_dms) || length(bad_dts))
Fail("Components with invalid dupe modes: ([bad_dms.Join(",")]) ||| Components with invalid dupe types: ([bad_dts.Join(",")])")
+4 -4
View File
@@ -25,18 +25,18 @@
/obj/item/uplink/nuclear/Initialize()
. = ..()
GET_COMPONENT(hidden_uplink, /datum/component/uplink)
var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.set_gamemode(/datum/game_mode/nuclear)
/obj/item/uplink/nuclear_restricted/Initialize()
. = ..()
GET_COMPONENT(hidden_uplink, /datum/component/uplink)
var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.allow_restricted = FALSE
hidden_uplink.set_gamemode(/datum/game_mode/nuclear)
/obj/item/uplink/clownop/Initialize()
. = ..()
GET_COMPONENT(hidden_uplink, /datum/component/uplink)
var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.set_gamemode(/datum/game_mode/nuclear/clown_ops)
/obj/item/uplink/old
@@ -45,7 +45,7 @@
/obj/item/uplink/old/Initialize(mapload, owner, tc_amount = 10)
. = ..()
GET_COMPONENT(hidden_uplink, /datum/component/uplink)
var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.name = "dusty radio"
// Multitool uplink
+9 -1
View File
@@ -1711,12 +1711,20 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist.
restricted_roles = list("Research Director", "Scientist")
/datum/uplink_item/role_restricted/alientech
name = "Alien Research Disk"
desc = "A technology disk holding a terabyte of highly confidential abductor technology. \
Simply insert into research console of choice and import the files from the disk. You might research some useful gear from this."
item = /obj/item/disk/tech_disk/abductor
cost = 12
restricted_roles = list("Research Director", "Scientist", "Roboticist")
/datum/uplink_item/role_restricted/brainwash_disk
name = "Brainwashing Surgery Program"
desc = "A disk containing the procedure to perform a brainwashing surgery, allowing you to implant an objective onto a target. \
Insert into an Operating Console to enable the procedure."
item = /obj/item/disk/surgery/brainwashing
restricted_roles = list("Medical Doctor")
restricted_roles = list("Medical Doctor", "Roboticist")
cost = 3
/datum/uplink_item/role_restricted/clown_bomb