Merge remote-tracking branch 'citadel/master' into storage_rework

This commit is contained in:
kevinz000
2020-04-06 18:40:58 -07:00
2864 changed files with 782707 additions and 267358 deletions
+3 -4
View File
@@ -36,8 +36,7 @@
//procs that handle the actual buckling and unbuckling
/atom/movable/proc/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
if(!buckled_mobs)
buckled_mobs = list()
LAZYINITLIST(buckled_mobs)
if(!istype(M))
return FALSE
@@ -66,7 +65,7 @@
M.buckled = src
M.setDir(dir)
buckled_mobs |= M
M.update_canmove()
M.update_mobility()
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled)
post_buckle_mob(M)
@@ -85,7 +84,7 @@
. = buckled_mob
buckled_mob.buckled = null
buckled_mob.anchored = initial(buckled_mob.anchored)
buckled_mob.update_canmove()
buckled_mob.update_mobility()
buckled_mob.clear_alert("buckled")
buckled_mobs -= buckled_mob
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force)
+5 -15
View File
@@ -113,7 +113,7 @@
/obj/effect/anomaly/grav/proc/gravShock(mob/living/A)
if(boing && isliving(A) && !A.stat)
A.Knockdown(40)
A.DefaultCombatKnockdown(40)
var/atom/target = get_edge_target_turf(A, get_dir(src, get_step_away(A, src)))
A.throw_at(target, 5, 1)
boing = 0
@@ -138,13 +138,13 @@
name = "flux wave anomaly"
icon_state = "electricity2"
density = TRUE
var/canshock = 0
var/canshock = FALSE
var/shockdamage = 20
var/explosive = TRUE
/obj/effect/anomaly/flux/anomalyEffect()
..()
canshock = 1
canshock = TRUE
for(var/mob/living/M in range(0, src))
mobShock(M)
@@ -159,18 +159,8 @@
/obj/effect/anomaly/flux/proc/mobShock(mob/living/M)
if(canshock && istype(M))
canshock = 0 //Just so you don't instakill yourself if you slam into the anomaly five times in a second.
if(iscarbon(M))
if(ishuman(M))
M.electrocute_act(shockdamage, "[name]", safety=1)
return
M.electrocute_act(shockdamage, "[name]")
return
else
M.adjustFireLoss(shockdamage)
M.visible_message("<span class='danger'>[M] was shocked by \the [name]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>")
canshock = FALSE //Just so you don't instakill yourself if you slam into the anomaly five times in a second.
M.electrocute_act(shockdamage, "[name]", flags = SHOCK_NOGLOVES)
/obj/effect/anomaly/flux/detonate()
if(explosive)
+65 -4
View File
@@ -57,6 +57,7 @@
var/poster_item_name = "hypothetical poster"
var/poster_item_desc = "This hypothetical poster item should not exist, let's be honest here."
var/poster_item_icon_state = "rolled_poster"
var/poster_item_type = /obj/item/poster
/obj/structure/sign/poster/Initialize()
. = ..()
@@ -114,7 +115,7 @@
/obj/structure/sign/poster/proc/roll_and_drop(loc)
pixel_x = 0
pixel_y = 0
var/obj/item/poster/P = new(loc, src)
var/obj/item/poster/P = new poster_item_type(loc, src)
forceMove(P)
return P
@@ -128,7 +129,7 @@
if (smooth & SMOOTH_DIAGONAL)
for (var/O in overlays)
var/image/I = O
if (copytext(I.icon_state, 1, 3) == "d-")
if(copytext(I.icon_state, 1, 3) == "d-") //3 == length("d-") + 1
return
var/stuff_on_wall = 0
@@ -383,8 +384,8 @@
desc = "The POWER that gamers CRAVE! In partnership with Vlad's Salad."
icon_state = "poster39"
/obj/structure/sign/poster/contraband/sun_kist
name = "Sun-kist"
/obj/structure/sign/poster/contraband/starkist
name = "Star-kist"
desc = "Drink the stars!"
icon_state = "poster40"
@@ -408,6 +409,21 @@
desc = "A poster advertising a movie about some masked men."
icon_state = "poster44"
/obj/structure/sign/poster/contraband/buzzfuzz
name = "Buzz Fuzz"
desc = "A poster advertising the newest drink \"Buzz Fuzz\" with its iconic slogan of ~A Hive of Flavour~."
icon_state = "poster45"
/obj/structure/sign/poster/contraband/scum
name = "Security are Scum"
desc = "Anti-security propaganda. Features a human NanoTrasen security officer being shot in the head, with the words 'Scum' and a short inciteful manifesto. Used to anger security."
icon_state = "poster46"
/obj/structure/sign/poster/contraband/syndicate_logo
name = "Syndicate"
desc = "A poster decipting a snake shaped into an ominous 'S'!"
icon_state = "poster47"
/obj/structure/sign/poster/official
poster_item_name = "motivational poster"
poster_item_desc = "An official Nanotrasen-issued poster to foster a compliant and obedient workforce. It comes with state-of-the-art adhesive backing, for easy pinning to any vertical surface."
@@ -594,4 +610,49 @@
desc = "This informational poster teaches the viewer what carbon dioxide is."
icon_state = "poster35_legit"
/obj/structure/sign/poster/official/spiderlings
name = "Spiderlings"
desc = "This poster informs the crew of the dangers of spiderlings."
icon_state = "poster36_legit"
/obj/structure/sign/poster/official/duelshotgun
name = "Cycler Shotgun Ad"
desc = "A poster advertising an advanced dual magazine tubes shotgun, boasting about how easy it is to swap between the two tubes."
icon_state = "poster37_legit"
/obj/structure/sign/poster/official/fashion
name = "Fashion!"
desc = "An advertisement for 'Fashion!', a popular fashion magazine, depicting a woman with a black dress with a golden trim, she also has a red poppy in her hair."
icon_state = "poster38_legit"
/obj/structure/sign/poster/official/pda_ad600
name = "NT PDA600 Ad"
desc = "A poster advertising an old discounted Nanotrasen PDA. This is the old 600 model, it has a small screen and suffered from security and networking issues."
icon_state = "poster39_legit"
/obj/structure/sign/poster/official/pda_ad800
name = "NT PDA800 Ad"
desc = "An advertisement on an old Nanotrasen PDA model. The 800 fixed a lot of security flaws that the 600 had; it also had large touchscreen and hot-swappable cartridges."
icon_state = "poster40_legit"
/obj/structure/sign/poster/official/hydro_ad
name = "Hydroponics Tray"
desc = "An advertisement for hydroponics trays. Space Station 13's botanical department uses a slightly newer model, but the principles are the same. From left to right: Green means the plant is done, red means the plant is unhealthy, flashing red means pests or weeds, yellow means the plant needs nutriment and blue means the plant needs water."
icon_state = "poster41_legit"
/obj/structure/sign/poster/official/medical_green_cross
name = "Medical"
desc = "A green cross, one of the interplanetary symbol of health and aid. It has a bunch of common languages at the top with translations." // Didn't the American Heart Foundation trademark red crosses? I'm playing it safe with green, not that they'll notice spacegame13 poster.
icon_state = "poster42_legit"
/obj/structure/sign/poster/official/nt_storm_officer
name = "NT Storm Ad"
desc = "An advertisement for NanoTrasen Storm. A premium infantry helmet, This is the officer variant. I comes with a better radio, better HUD software and better targeting sensors."
icon_state = "poster43_legit"
/obj/structure/sign/poster/official/nt_storm
name = "NT Storm Ad"
desc = "An advertisement for NanoTrasen Storm. A premium infantry helmet, It contains a rebreather and full head coverage for use on harsh environments where the air isn't always safe to breathe."
icon_state = "poster44_legit"
#undef PLACE_SPEED
@@ -11,7 +11,7 @@
LAZYINITLIST(blood_DNA) //Kinda needed
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
create_reagents(300)
create_reagents(300, NONE, NO_REAGENTS_VALUE)
if(loc && isturf(loc))
for(var/obj/effect/decal/cleanable/C in loc)
if(C != src && C.type == type && !QDELETED(C))
@@ -29,13 +29,19 @@
var/list/diseases = list()
SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
var/direction = pick(directions)
for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
sleep(2)
if(i > 0)
var/dist = 0
if(prob(50)) //yes this and the one below are different for a reason.
if(prob(25))
dist = 2
else
dist = 1
if(dist)
for(var/i in 1 to dist)
sleep(2)
var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases)
splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/xeno/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
@@ -5,6 +5,7 @@
layer = LOW_OBJ_LAYER
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = FALSE
bloodiness = 0 //This isn't supposed to be bloody.
var/body_colors = "#e3ba84" //a default color just in case.
var/gibs_reagent_id = /datum/reagent/liquidgibs
var/gibs_bloodtype = "A+"
@@ -16,10 +17,9 @@
if(gibs_reagent_id)
reagents.add_reagent(gibs_reagent_id, 5)
if(gibs_bloodtype)
add_blood_DNA(list("Non-human DNA" = gibs_bloodtype, diseases))
add_blood_DNA(list("Non-human DNA" = gibs_bloodtype), diseases)
update_icon()
/obj/effect/decal/cleanable/blood/gibs/update_icon()
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
cut_overlays()
@@ -44,13 +44,18 @@
var/list/diseases = list()
SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
var/direction = pick(directions)
for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
sleep(2)
if(i > 0)
var/dist = 0
if(prob(50)) //yes this and the one below are different for a reason.
if(prob(25))
dist = 2
else
dist = 1
if(dist)
for(var/i in 1 to dist)
var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
@@ -5,12 +5,12 @@
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
blood_state = BLOOD_STATE_BLOOD
bloodiness = MAX_SHOE_BLOODINESS
bloodiness = BLOOD_AMOUNT_PER_DECAL
color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
if (C.blood_DNA)
blood_DNA |= C.blood_DNA.Copy()
blood_DNA |= C.blood_DNA
update_icon()
..()
@@ -48,6 +48,8 @@ would spawn and follow the beaker, even if it is carried or thrown.
holder = atom
/datum/effect_system/proc/start()
if(QDELETED(src))
return
for(var/i in 1 to number)
if(total_effects > 20)
return
@@ -69,7 +71,8 @@ would spawn and follow the beaker, even if it is carried or thrown.
for(var/j in 1 to steps_amt)
sleep(5)
step(E,direction)
addtimer(CALLBACK(src, .proc/decrement_total_effect), 20)
if(!QDELETED(src))
addtimer(CALLBACK(src, .proc/decrement_total_effect), 20)
/datum/effect_system/proc/decrement_total_effect()
total_effects--
@@ -94,7 +94,7 @@
/obj/effect/particle_effect/foam/Initialize()
. = ..()
MakeSlippery()
create_reagents(1000) //limited by the size of the reagent holder anyway.
create_reagents(1000, NONE, NO_REAGENTS_VALUE) //limited by the size of the reagent holder anyway.
START_PROCESSING(SSfastprocess, src)
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
@@ -126,7 +126,7 @@
T.PlaceOnTop(/turf/open/floor/plating/foam, flags = CHANGETURF_INHERIT_AIR)
for(var/direction in GLOB.cardinals)
var/turf/cardinal_turf = get_step(T, direction)
if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
if(get_base_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf!
new/obj/structure/foamedmetal(T)
break
flick("[icon_state]-disolve", src)
@@ -104,4 +104,5 @@
if(explosion_message)
location.visible_message("<span class='danger'>The solution violently explodes!</span>", \
"<span class='italics'>You hear an explosion!</span>")
dyn_explosion(location, amount, flashing_factor)
dyn_explosion(location, amount, flashing_factor)
@@ -32,7 +32,7 @@
/obj/effect/particle_effect/smoke/Initialize()
. = ..()
create_reagents(500)
create_reagents(500, NONE, NO_REAGENTS_VALUE)
START_PROCESSING(SSobj, src)
+3
View File
@@ -4,8 +4,11 @@
/obj/effect
icon = 'icons/effects/effects.dmi'
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF
move_resist = INFINITY
obj_flags = 0
vis_flags = NONE
/obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
return
+31 -1
View File
@@ -151,6 +151,10 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark)
name = "Medical Doctor"
icon_state = "Medical Doctor"
/obj/effect/landmark/start/paramedic
name = "Paramedic"
icon_state = "Paramedic"
/obj/effect/landmark/start/scientist
name = "Scientist"
icon_state = "Scientist"
@@ -273,6 +277,27 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
GLOB.newplayer_start += loc
return INITIALIZE_HINT_QDEL
/obj/effect/landmark/start/nuclear_equipment
name = "bomb or clown beacon spawner"
var/nukie_path = /obj/item/sbeacondrop/bomb
var/clown_path = /obj/item/sbeacondrop/clownbomb
/obj/effect/landmark/start/nuclear_equipment/after_round_start()
var/npath = nukie_path
if(istype(SSticker.mode, /datum/game_mode/nuclear/clown_ops))
npath = clown_path
else if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/D = SSticker.mode
if(locate(/datum/dynamic_ruleset/roundstart/nuclear/clown_ops) in D.current_rules)
npath = clown_path
new npath(loc)
return ..()
/obj/effect/landmark/start/nuclear_equipment/minibomb
name = "minibomb or bombanana spawner"
nukie_path = /obj/item/storage/box/minibombs
clown_path = /obj/item/storage/box/bombananas
/obj/effect/landmark/latejoin
name = "JoinLate"
@@ -456,7 +481,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
if(!SSmapping.station_room_templates[t])
log_world("Station room spawner placed at ([T.x], [T.y], [T.z]) has invalid ruin name of \"[t]\" in its list")
templates -= t
template_name = pickweight(templates)
template_name = pickweightAllowZero(templates)
if(!template_name)
GLOB.stationroom_landmarks -= src
qdel(src)
@@ -481,3 +506,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
/obj/effect/landmark/stationroom/box/engine/New()
. = ..()
templates = CONFIG_GET(keyed_list/box_random_engine)
// Landmark for the mining station
/obj/effect/landmark/stationroom/lavaland/station
templates = list("Public Mining Base" = 3)
icon = 'icons/rooms/Lavaland/Mining.dmi'
+1 -1
View File
@@ -48,7 +48,7 @@
/obj/effect/mine/stun/mineEffect(mob/living/victim)
if(isliving(victim))
victim.Knockdown(stun_time)
victim.DefaultCombatKnockdown(stun_time)
/obj/effect/mine/kickmine
name = "kick mine"
+1 -1
View File
@@ -109,4 +109,4 @@
/obj/effect/abstract/proximity_checker/Crossed(atom/movable/AM)
set waitfor = FALSE
monitor.hasprox_receiver.HasProximity(AM)
monitor?.hasprox_receiver.HasProximity(AM)
+16 -16
View File
@@ -24,20 +24,20 @@
/obj/effect/spawner/bundle/costume/gladiator
name = "gladiator costume spawner"
items = list(
/obj/item/clothing/under/gladiator,
/obj/item/clothing/under/costume/gladiator,
/obj/item/clothing/head/helmet/gladiator)
/obj/effect/spawner/bundle/costume/madscientist
name = "mad scientist costume spawner"
items = list(
/obj/item/clothing/under/gimmick/rank/captain/suit,
/obj/item/clothing/under/rank/captain/suit,
/obj/item/clothing/head/flatcap,
/obj/item/clothing/suit/toggle/labcoat/mad)
/obj/effect/spawner/bundle/costume/elpresidente
name = "el presidente costume spawner"
items = list(
/obj/item/clothing/under/gimmick/rank/captain/suit,
/obj/item/clothing/under/rank/captain/suit,
/obj/item/clothing/head/flatcap,
/obj/item/clothing/mask/cigarette/cigar/havana,
/obj/item/clothing/shoes/jackboots)
@@ -45,14 +45,14 @@
/obj/effect/spawner/bundle/costume/nyangirl
name = "nyangirl costume spawner"
items = list(
/obj/item/clothing/under/schoolgirl,
/obj/item/clothing/under/costume/schoolgirl,
/obj/item/clothing/head/kitty,
/obj/item/clothing/glasses/sunglasses/blindfold)
/obj/effect/spawner/bundle/costume/maid
name = "maid costume spawner"
items = list(
/obj/item/clothing/under/skirt/black,
/obj/item/clothing/under/dress/skirt,
/obj/effect/spawner/lootdrop/minor/beret_or_rabbitears,
/obj/item/clothing/glasses/sunglasses/blindfold)
@@ -61,13 +61,13 @@
name = "butler costume spawner"
items = list(
/obj/item/clothing/accessory/waistcoat,
/obj/item/clothing/under/suit_jacket,
/obj/item/clothing/under/suit/black,
/obj/item/clothing/head/that)
/obj/effect/spawner/bundle/costume/highlander
name = "highlander costume spawner"
items = list(
/obj/item/clothing/under/kilt,
/obj/item/clothing/under/costume/kilt,
/obj/item/clothing/head/beret)
/obj/effect/spawner/bundle/costume/prig
@@ -78,7 +78,7 @@
/obj/effect/spawner/lootdrop/minor/bowler_or_that,
/obj/item/clothing/shoes/sneakers/black,
/obj/item/cane,
/obj/item/clothing/under/sl_suit,
/obj/item/clothing/under/suit/sl,
/obj/item/clothing/mask/fakemoustache)
/obj/effect/spawner/bundle/costume/plaguedoctor
@@ -92,7 +92,7 @@
name = "night owl costume spawner"
items = list(
/obj/item/clothing/suit/toggle/owlwings,
/obj/item/clothing/under/owl,
/obj/item/clothing/under/costume/owl,
/obj/item/clothing/mask/gas/owl_mask)
/obj/effect/spawner/bundle/costume/griffin
@@ -100,20 +100,20 @@
items = list(
/obj/item/clothing/suit/toggle/owlwings/griffinwings,
/obj/item/clothing/shoes/griffin,
/obj/item/clothing/under/griffin,
/obj/item/clothing/under/costume/griffin,
/obj/item/clothing/head/griffin)
/obj/effect/spawner/bundle/costume/waiter
name = "waiter costume spawner"
items = list(
/obj/item/clothing/under/waiter,
/obj/item/clothing/under/suit/waiter,
/obj/effect/spawner/lootdrop/minor/kittyears_or_rabbitears,
/obj/item/clothing/suit/apron)
/obj/effect/spawner/bundle/costume/pirate
name = "pirate costume spawner"
items = list(
/obj/item/clothing/under/pirate,
/obj/item/clothing/under/costume/pirate,
/obj/item/clothing/suit/pirate,
/obj/effect/spawner/lootdrop/minor/pirate_or_bandana,
/obj/item/clothing/glasses/eyepatch)
@@ -121,7 +121,7 @@
/obj/effect/spawner/bundle/costume/commie
name = "commie costume spawner"
items = list(
/obj/item/clothing/under/soviet,
/obj/item/clothing/under/costume/soviet,
/obj/item/clothing/head/ushanka)
/obj/effect/spawner/bundle/costume/imperium_monk
@@ -145,7 +145,7 @@
/obj/effect/spawner/bundle/costume/cutewitch
name = "cute witch costume spawner"
items = list(
/obj/item/clothing/under/sundress,
/obj/item/clothing/under/dress/sundress,
/obj/item/clothing/head/witchwig,
/obj/item/staff/broom)
@@ -161,10 +161,10 @@
name = "sexy clown costume spawner"
items = list(
/obj/item/clothing/mask/gas/sexyclown,
/obj/item/clothing/under/rank/clown/sexy)
/obj/item/clothing/under/rank/civilian/clown/sexy)
/obj/effect/spawner/bundle/costume/sexymime
name = "sexy mime costume spawner"
items = list(
/obj/item/clothing/mask/gas/sexymime,
/obj/item/clothing/under/sexymime)
/obj/item/clothing/under/rank/civilian/mime/sexy)
@@ -10,7 +10,7 @@
var/list/gibamounts = list() //amount to spawn for each gib decal type we'll spawn.
var/list/gibdirections = list() //of lists of possible directions to spread each gib decal type towards.
/obj/effect/gibspawner/Initialize(mapload, mob/living/source_mob, list/datum/disease/diseases)
/obj/effect/gibspawner/Initialize(mapload, mob/living/source_mob, list/datum/disease/diseases, list/blood_dna)
. = ..()
if(gibtypes.len != gibamounts.len)
stack_trace("Gib list amount length mismatch!")
@@ -33,7 +33,7 @@
var/body_coloring = ""
if(source_mob)
if(!issilicon(source_mob))
dna_to_add = source_mob.get_blood_dna_list() //ez pz
dna_to_add = blood_dna || source_mob.get_blood_dna_list() //ez pz
if(ishuman(source_mob))
var/mob/living/carbon/human/H = source_mob
if(H.dna.species.use_skintones)
+138 -3
View File
@@ -45,7 +45,6 @@
/obj/effect/spawner/lootdrop/armory_contraband
name = "armory contraband gun spawner"
lootdoubles = FALSE
loot = list(
/obj/item/gun/ballistic/automatic/pistol = 8,
/obj/item/gun/ballistic/shotgun/automatic/combat = 5,
@@ -129,7 +128,6 @@
loot = typesof(/obj/item/flashlight/glowstick)
. = ..()
/obj/effect/spawner/lootdrop/gloves
name = "random gloves"
desc = "These gloves are supposed to be a random color..."
@@ -150,7 +148,6 @@
/obj/effect/spawner/lootdrop/crate_spawner
name = "lootcrate spawner" //USE PROMO CODE "SELLOUT" FOR 20% OFF!
lootdoubles = FALSE
loot = list(
/obj/structure/closet/crate/secure/loot = 20,
"" = 80
@@ -386,3 +383,141 @@
/obj/structure/reagent_dispensers/keg/aphro = 2,
/obj/structure/reagent_dispensers/keg/aphro/strong = 2,
/obj/structure/reagent_dispensers/keg/gargle = 1)
/obj/effect/spawner/lootdrop/coin
lootcount = 1
loot = list(
/obj/item/coin/silver = 30,
/obj/item/coin/iron = 30,
/obj/item/coin/gold = 10,
/obj/item/coin/diamond = 10,
/obj/item/coin/plasma = 10,
/obj/item/coin/uranium = 10,
)
/obj/effect/spawner/lootdrop/cig_packs
lootcount = 1
loot = list(
/obj/item/storage/fancy/cigarettes = 20,
/obj/item/storage/fancy/cigarettes/dromedaryco = 10,
/obj/item/storage/fancy/cigarettes/cigpack_robust = 5,
/obj/item/storage/fancy/cigarettes/cigpack_robustgold = 5,
/obj/item/storage/fancy/cigarettes/cigpack_carp = 15,
/obj/item/storage/fancy/cigarettes/cigpack_syndicate = 2,
/obj/item/storage/fancy/cigarettes/cigpack_midori = 10,
/obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 5,
/obj/item/storage/fancy/cigarettes/cigpack_xeno = 3,
/obj/item/storage/fancy/cigarettes/cigpack_cannabis = 10,
/obj/item/storage/fancy/cigarettes/cigpack_mindbreaker = 10,
/obj/item/storage/fancy/rollingpapers = 10
)
/obj/effect/spawner/lootdrop/cigars_cases
lootcount = 1
loot = list(
/obj/item/storage/fancy/cigarettes/cigars = 50,
/obj/item/storage/fancy/cigarettes/cigars/cohiba = 25,
/obj/item/storage/fancy/cigarettes/cigars/havana = 25,
)
/obj/effect/spawner/lootdrop/space_cash
lootcount = 1
loot = list(
/obj/item/stack/spacecash/c1 = 1,
/obj/item/stack/spacecash/c10 = 9,
/obj/item/stack/spacecash/c20 = 10,
/obj/item/stack/spacecash/c50 = 15,
/obj/item/stack/spacecash/c100 = 25,
/obj/item/stack/spacecash/c200 = 20,
/obj/item/stack/spacecash/c500 = 19,
/obj/item/stack/spacecash/c1000 = 1,
)
/obj/effect/spawner/lootdrop/druggie_pill
lootcount = 1
loot = list(
/obj/item/reagent_containers/pill/stimulant = 1,
/obj/item/reagent_containers/pill/zoom = 9,
/obj/item/reagent_containers/pill/happy = 10,
/obj/item/reagent_containers/pill/lsd = 15,
/obj/item/reagent_containers/pill/aranesp = 25,
/obj/item/reagent_containers/pill/psicodine = 20,
/obj/item/reagent_containers/pill/mannitol = 19,
/obj/item/reagent_containers/pill/happiness = 1,
)
/obj/effect/spawner/lootdrop/low_loot_toilet
name = "random low toilet spawner"
lootcount = 1
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
//This is ment for "low" loot that anyone could fine in a toilet, for better gear use high loot toilet
loot = list("" = 30,
/obj/item/lighter = 2,
/obj/item/tape/random = 1,
/obj/item/poster/random_contraband = 1,
/obj/item/clothing/glasses/sunglasses/blindfold = 4,
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/toy/plush/random = 5,
/obj/effect/spawner/lootdrop/gloves = 5,
/obj/effect/spawner/lootdrop/glowstick = 5,
/obj/effect/spawner/lootdrop/coin = 3,
/obj/effect/spawner/lootdrop/cig_packs = 10,
/obj/effect/spawner/lootdrop/cigars_cases = 2,
/obj/effect/spawner/lootdrop/space_cash = 5,
/obj/item/reagent_containers/food/snacks/grown/cannabis = 5,
/obj/item/storage/pill_bottle/dice = 5,
/obj/item/toy/cards/deck = 5,
/obj/effect/spawner/lootdrop/druggie_pill = 5
)
/obj/effect/spawner/lootdrop/prison_loot_toilet
name = "random prison toilet spawner"
lootcount = 1
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
//This is ment for "prison" loot that is rather rare and ment for "prisoners if they get a crowbar to fine, or sec.
loot = list("" = 10,
/obj/item/lighter = 5,
/obj/item/poster/random_contraband = 5,
/obj/item/clothing/glasses/sunglasses = 5,
/obj/effect/spawner/lootdrop/coin = 5,
/obj/effect/spawner/lootdrop/cig_packs = 10,
/obj/effect/spawner/lootdrop/cigars_cases = 5,
/obj/item/reagent_containers/food/snacks/grown/cannabis = 5,
/obj/item/storage/pill_bottle/dice = 5,
/obj/item/toy/cards/deck = 5,
/obj/effect/spawner/lootdrop/druggie_pill = 5,
/obj/item/kitchen/knife = 5,
/obj/item/screwdriver = 5,
/obj/item/crowbar/red = 0.5, //Dont you need a crowbar to open this?
/obj/item/stack/medical/bruise_pack = 3,
/obj/item/reagent_containers/food/drinks/bottle/vodka = 2,
/obj/item/radio = 5,
/obj/item/flashlight = 4.5,
/obj/item/clothing/mask/breath = 2,
/obj/item/tank/internals/emergency_oxygen = 3,
/obj/item/storage/box/mre/menu4/safe = 3,
/obj/item/grenade/smokebomb = 2
)
/obj/effect/spawner/lootdrop/high_loot_toilet
name = "random high toilet spawner"
lootcount = 1
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
//The items inside are always going to be something usefull, illegal and likely traitorous.
loot = list(
/obj/item/clothing/glasses/sunglasses = 5,
/obj/effect/spawner/lootdrop/coin = 5,
/obj/effect/spawner/lootdrop/space_cash = 5,
/obj/effect/spawner/lootdrop/druggie_pill = 5,
/obj/item/storage/fancy/cigarettes/cigpack_syndicate = 5,
/obj/item/suppressor = 5,
/obj/item/toy/cards/deck/syndicate = 5,
/obj/item/clothing/under/syndicate = 5,
/obj/item/clothing/mask/gas/syndicate = 5,
/obj/item/grenade/smokebomb = 10,
/obj/item/gun/ballistic/automatic/toy/pistol = 5,
/obj/item/firing_pin = 5,
/obj/item/grenade/empgrenade = 15,
/obj/item/clothing/gloves/combat = 10,
/obj/item/clothing/shoes/sneakers/noslip = 10
)
@@ -163,6 +163,10 @@ again.
icon_state = "plastitaniumwindow_spawner"
spawn_list = list(/obj/structure/grille, /obj/structure/window/plastitanium)
//plastitanium pirate window
/obj/effect/spawner/structure/window/plastitanium/pirate
spawn_list = list(/obj/structure/grille, /obj/structure/window/plastitanium/pirate)
//ice window
+34
View File
@@ -28,6 +28,7 @@
take_damage(5, BURN, 0, 0)
/obj/structure/spider/stickyweb
var/genetic = FALSE
icon_state = "stickyweb1"
/obj/structure/spider/stickyweb/Initialize()
@@ -36,6 +37,8 @@
. = ..()
/obj/structure/spider/stickyweb/CanPass(atom/movable/mover, turf/target)
if (genetic)
return
if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider))
return TRUE
else if(isliving(mover))
@@ -48,6 +51,27 @@
return prob(30)
return TRUE
/obj/structure/spider/stickyweb/genetic //for the spider genes in genetics
genetic = TRUE
var/mob/living/allowed_mob
/obj/structure/spider/stickyweb/genetic/Initialize(mapload, allowedmob)
allowed_mob = allowedmob
. = ..()
/obj/structure/spider/stickyweb/genetic/CanPass(atom/movable/mover, turf/target)
. = ..() //this is the normal spider web return aka a spider would make this TRUE
if(mover == allowed_mob)
return TRUE
else if(isliving(mover)) //we change the spider to not be able to go through here
if(mover.pulledby == allowed_mob)
return TRUE
if(prob(50))
to_chat(mover, "<span class='danger'>You get stuck in \the [src] for a moment.</span>")
return FALSE
else if(istype(mover, /obj/item/projectile))
return prob(30)
/obj/structure/spider/eggcluster
name = "egg cluster"
desc = "They seem to pulse slightly with an inner life."
@@ -128,6 +152,16 @@
else
..()
/obj/structure/spider/spiderling/attack_hand(mob/user)
. = ..()
if(user.a_intent != INTENT_HELP)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
user.visible_message("<span class='warning'>[user] splats [src].</span>", "<span class='warning'>You splat [src].</span>", "<span class='italics'>You hear a splat...</span>")
playsound(loc, 'sound/effects/snap.ogg', 25)
qdel(src)
return TRUE
/obj/structure/spider/spiderling/process()
if(travelling_in_vent)
if(isturf(loc))
+8 -6
View File
@@ -61,10 +61,11 @@
if(AM in T.affecting)
return
if(ismob(AM))
var/mob/M = AM
if(isliving(AM))
var/mob/living/M = AM
if(immobilize)
M.canmove = 0
ADD_TRAIT(M, TRAIT_MOBILITY_NOMOVE, src)
M.update_mobility()
affecting.Add(AM)
while(AM && !stopthrow)
@@ -98,10 +99,11 @@
affecting.Remove(AM)
if(ismob(AM))
var/mob/M = AM
if(isliving(AM))
var/mob/living/M = AM
if(immobilize)
M.canmove = 1
REMOVE_TRAIT(M, TRAIT_MOBILITY_NOMOVE, src)
M.update_mobility()
/* Stops things thrown by a thrower, doesn't do anything */
@@ -139,13 +139,6 @@
/obj/effect/temp_visual/dir_setting/curse/hand
icon_state = "cursehand"
/obj/effect/temp_visual/dir_setting/curse/hand/Initialize(mapload, set_dir, handedness)
. = ..()
update_icon()
/obj/item/projectile/curse_hand/update_icon()
icon_state = "[icon_state][handedness]"
/obj/effect/temp_visual/wizard
name = "water"
icon = 'icons/mob/mob.dmi'
@@ -474,7 +467,7 @@
else
update_icon()
/obj/effect/constructing_effect/update_icon()
/obj/effect/constructing_effect/update_icon_state()
icon_state = "rcd"
if (delay < 10)
icon_state += "_shortest"
@@ -39,4 +39,8 @@
/obj/effect/projectile/impact/laser/wavemotion
name = "particle impact"
icon_state = "impact_wavemotion"
icon_state = "impact_wavemotion"
/obj/effect/projectile/impact/laser/emitter
name = "emitter impact"
icon_state = "impact_emitter"
@@ -31,4 +31,8 @@
/obj/effect/projectile/muzzle/laser/wavemotion
name = "particle backblast"
icon_state = "muzzle_wavemotion"
icon_state = "muzzle_wavemotion"
/obj/effect/projectile/muzzle/laser/emitter
name = "emitter flash"
icon_state = "muzzle_emitter"
@@ -52,9 +52,7 @@
pixel_y += round((cos(angle_override)+16*cos(angle_override)*2), 1)
/obj/effect/projectile_lighting
var/owner
/obj/effect/projectile_lighting/Initialize(mapload, color, range, intensity, owner_key)
/obj/effect/projectile_lighting/Initialize(mapload, color, range, intensity)
. = ..()
set_light(range, intensity, color)
owner = owner_key
@@ -1,4 +1,4 @@
/proc/generate_tracer_between_points(datum/point/starting, datum/point/ending, beam_type, color, qdel_in = 5, light_range = 2, light_color_override, light_intensity = 1, instance_key) //Do not pass z-crossing points as that will not be properly (and likely will never be properly until it's absolutely needed) supported!
/proc/generate_tracer_between_points(datum/point/starting, datum/point/ending, beam_type, color, qdel_in = 5, light_range = 2, light_color_override, light_intensity = 1, list/turfs) //Do not pass z-crossing points as that will not be properly (and likely will never be properly until it's absolutely needed) supported!
if(!istype(starting) || !istype(ending) || !ispath(beam_type))
return
var/datum/point/midpoint = point_midpoint_points(starting, ending)
@@ -9,17 +9,15 @@
. = PB
if(light_range > 0 && light_intensity > 0)
var/list/turf/line = getline(starting.return_turf(), ending.return_turf())
tracing_line:
for(var/i in line)
var/turf/T = i
for(var/obj/effect/projectile_lighting/PL in T)
if(PL.owner == instance_key)
continue tracing_line
QDEL_IN(new /obj/effect/projectile_lighting(T, light_color_override, light_range, light_intensity, instance_key), qdel_in > 0? qdel_in : 5)
for(var/i in line)
if(turfs[i])
continue
turfs[i] = TRUE
QDEL_IN(new /obj/effect/projectile_lighting(i, light_color_override, light_range, light_intensity), qdel_in > 0? qdel_in : 5)
line = null
if(qdel_in)
QDEL_IN(PB, qdel_in)
d
/obj/effect/projectile/tracer
name = "beam"
icon = 'icons/obj/projectiles_tracer.dmi'
@@ -70,3 +68,7 @@
/obj/effect/projectile/tracer/laser/wavemotion
name = "particle trail"
icon_state = "tracer_wavemotion"
/obj/effect/projectile/tracer/laser/emitter
name = "emitter beam"
icon_state = "emitter"
@@ -8,6 +8,7 @@
/obj/structure/sign/poster/wanted
var/wanted_name
poster_item_type = /obj/item/poster/wanted
/obj/structure/sign/poster/wanted/Initialize(mapload, icon/person_icon, person_name, description)
. = ..()
+54 -28
View File
@@ -7,6 +7,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item
name = "item"
icon = 'icons/obj/items_and_weapons.dmi'
blocks_emissive = EMISSIVE_BLOCK_GENERIC
var/item_state = null
var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
var/righthand_file = 'icons/mob/inhands/items_righthand.dmi'
@@ -39,7 +40,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/// Volume override for the item, otherwise automatically calculated from w_class.
var/volume
/// The amount of stamina it takes to swing an item in a normal melee attack do not lie to me and say it's for realism because it ain't. If null it will autocalculate from w_class.
var/total_mass //Total mass in arbitrary pound-like values. If there's no balance reasons for an item to have otherwise, this var should be the item's weight in pounds.
/// How long, in deciseconds, this staggers for, if null it will autocalculate from w_class and force. Unlike total mass this supports 0 and negatives.
var/stagger_force
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
pass_flags = PASSTABLE
pressure_resistance = 4
@@ -73,7 +78,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/equip_delay_other = 20 //In deciseconds, how long an item takes to put on another person
var/strip_delay = 40 //In deciseconds, how long an item takes to remove from another person
var/breakouttime = 0
var/list/materials
var/reskinned = FALSE
var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
@@ -117,8 +121,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/Initialize()
materials = typelist("materials", materials)
if (attack_verb)
attack_verb = typelist("attack_verb", attack_verb)
@@ -183,14 +185,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
set category = "Object"
set src in oview(1)
if(!isturf(loc) || usr.stat || usr.restrained() || !usr.canmove)
var/mob/living/L = usr
if(!istype(L) || !isturf(loc) || !CHECK_MOBILITY(L, MOBILITY_USE))
return
var/turf/T = src.loc
src.loc = null
src.loc = T
var/turf/T = loc
loc = null
loc = T
/obj/item/examine(mob/user) //This might be spammy. Remove?
. = ..()
@@ -238,9 +239,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
// Extractable materials. Only shows the names, not the amounts.
research_msg += ".<br><font color='purple'>Extractable materials:</font> "
if (materials.len)
if (length(custom_materials))
sep = ""
for(var/mat in materials)
for(var/mat in custom_materials)
research_msg += sep
research_msg += CallMaterialName(mat)
sep = ", "
@@ -386,6 +387,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
qdel(src)
item_flags &= ~IN_INVENTORY
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user)
user.update_equipment_speed_mods()
// called just as an item is picked up (loc is not yet changed)
/obj/item/proc/pickup(mob/user)
@@ -405,12 +407,14 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
return usr.client.Click(src, src_location, src_control, params)
var/list/directaccess = usr.DirectAccess() //This, specifically, is what requires the copypaste. If this were after the adjacency check, then it'd be impossible to use items in your inventory, among other things.
//If this were before the above checks, then trying to click on items would act a little funky and signal overrides wouldn't work.
if((usr.CanReach(src) || (src in directaccess)) && (usr.CanReach(over) || (over in directaccess)))
if(!usr.get_active_held_item())
usr.UnarmedAttack(src, TRUE)
if(usr.get_active_held_item() == src)
melee_attack_chain(usr, over)
return TRUE //returning TRUE as a "is this overridden?" flag
if(iscarbon(usr))
var/mob/living/carbon/C = usr
if((C.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && ((C.CanReach(src) || (src in directaccess)) && (C.CanReach(over) || (over in directaccess))))
if(!C.get_active_held_item())
C.UnarmedAttack(src, TRUE)
if(C.get_active_held_item() == src)
melee_attack_chain(C, over)
return TRUE //returning TRUE as a "is this overridden?" flag
if(!Adjacent(usr) || !over.Adjacent(usr))
return // should stop you from dragging through windows
@@ -429,6 +433,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if(item_action_slot_check(slot, user, A)) //some items only give their actions buttons when in a specific slot.
A.Grant(user)
item_flags |= IN_INVENTORY
user.update_equipment_speed_mods()
//sometimes we only want to grant the item's action if it's equipped in a specific slot.
/obj/item/proc/item_action_slot_check(slot, mob/user, datum/action/A)
@@ -501,7 +506,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
to_chat(user, "<span class='danger'>You cannot locate any organic eyes on this brain!</span>")
return
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)//CIT CHANGE - makes eyestabbing impossible if you're in stamina softcrit
if(IS_STAMCRIT(user))//CIT CHANGE - makes eyestabbing impossible if you're in stamina softcrit
to_chat(user, "<span class='danger'>You're too exhausted for that.</span>")//CIT CHANGE - ditto
return //CIT CHANGE - ditto
@@ -550,7 +555,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
to_chat(M, "<span class='danger'>You drop what you're holding and clutch at your eyes!</span>")
M.adjust_blurriness(10)
M.Unconscious(20)
M.Knockdown(40)
M.DefaultCombatKnockdown(40)
if (prob(eyes.damage - 10 + 1))
M.become_blind(EYE_DAMAGE)
to_chat(M, "<span class='danger'>You go blind!</span>")
@@ -573,21 +578,21 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
else
return
/obj/item/throw_impact(atom/A, datum/thrownthing/throwingdatum)
if(A && !QDELETED(A))
SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, A, throwingdatum)
if(get_temperature() && isliving(A))
var/mob/living/L = A
/obj/item/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(hit_atom && !QDELETED(hit_atom))
SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
if(get_temperature() && isliving(hit_atom))
var/mob/living/L = hit_atom
L.IgniteMob()
var/itempush = 1
if(w_class < 4)
itempush = 0 //too light to push anything
return A.hitby(src, 0, itempush)
return hit_atom.hitby(src, 0, itempush, throwingdatum=throwingdatum)
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, messy_throw = TRUE)
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE)
thrownby = thrower
callback = CALLBACK(src, .proc/after_throw, callback, (spin && messy_throw)) //replace their callback with our own
. = ..(target, range, speed, thrower, spin, diagonals_first, callback)
. = ..(target, range, speed, thrower, spin, diagonals_first, callback, force)
/obj/item/proc/after_throw(datum/callback/callback, messy_throw)
if (callback) //call the original callback
@@ -679,7 +684,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
else
. = ""
/obj/item/hitby(atom/movable/AM)
/obj/item/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
return
/obj/item/attack_hulk(mob/living/carbon/human/user)
@@ -859,3 +864,24 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/// Get an item's volume that it uses when being stored.
/obj/item/proc/get_volume()
return isnull(volume)? AUTOSCALE_VOLUME(w_class) : volume
/obj/item/proc/embedded(mob/living/carbon/human/embedded_mob)
return
/obj/item/proc/unembedded()
return
/**
* Sets our slowdown and updates equipment slowdown of any mob we're equipped on.
*/
/obj/item/proc/set_slowdown(new_slowdown)
slowdown = new_slowdown
if(CHECK_BITFIELD(item_flags, IN_INVENTORY))
var/mob/living/L = loc
if(istype(L))
L.update_equipment_speed_mods()
/obj/item/vv_edit_var(var_name, var_value)
. = ..()
if(var_name == NAMEOF(src, slowdown))
set_slowdown(var_value) //don't care if it's a duplicate edit as slowdown'll be set, do it anyways to force normal behavior.
+2 -2
View File
@@ -22,7 +22,7 @@ AI MODULES
throw_range = 7
var/list/laws = list()
var/bypass_law_amt_check = 0
materials = list(MAT_GOLD=50)
custom_materials = list(/datum/material/gold=50)
/obj/item/aiModule/examine(var/mob/user as mob)
. = ..()
@@ -369,7 +369,7 @@ AI MODULES
if(!targName)
return
subject = targName
laws = list("You may not injure a [subject] or, through inaction, allow a [subject] to come to harm.",\
laws = list("You may not injure a [subject] or cause one to come to harm.",\
"You must obey orders given to you by [subject]s, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.")
..()
+17 -18
View File
@@ -22,7 +22,7 @@ RLD
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=100000)
custom_materials = list(/datum/material/iron=100000)
req_access_txt = "11"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
resistance_flags = FIRE_PROOF
@@ -196,7 +196,7 @@ RLD
/obj/item/construction/rcd/verb/change_airlock_access(mob/user)
if (!ishuman(user) && !user.has_unlimited_silicon_privilege)
if (!ishuman(user) && !user.silicon_privileges)
return
var/t1 = ""
@@ -552,8 +552,8 @@ RLD
explosion(src, 0, 0, 3, 1, flame_range = 1)
qdel(src)
/obj/item/construction/rcd/update_icon()
..()
/obj/item/construction/rcd/update_overlays()
. = ..()
if(has_ammobar)
var/ratio = CEILING((matter / max_matter) * ammo_sections, 1)
cut_overlays() //To prevent infinite stacking of overlays
@@ -603,7 +603,7 @@ RLD
energyfactor = 66
/obj/item/construction/rcd/loaded
materials = list(MAT_METAL=48000, MAT_GLASS=32000)
custom_materials = list(/datum/material/iron = 48000, /datum/material/glass = 32000)
matter = 160
/obj/item/construction/rcd/loaded/upgraded
@@ -635,13 +635,13 @@ RLD
item_state = "rcdammo"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
materials = list(MAT_METAL=12000, MAT_GLASS=8000)
custom_materials = list(/datum/material/iron=12000, /datum/material/glass=8000)
var/ammoamt = 40
/obj/item/rcd_ammo/large
name = "large compressed matter cartridge"
desc = "Highly compressed matter for the RCD. Has four times the matter packed into the same space as a normal cartridge."
materials = list(MAT_METAL=48000, MAT_GLASS=32000)
custom_materials = list(/datum/material/iron=48000, /datum/material/glass=32000)
ammoamt = 160
@@ -677,18 +677,18 @@ RLD
icon_state = "rld"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
matter = 500
max_matter = 500
sheetmultiplier = 16
matter = 200
max_matter = 200
sheetmultiplier = 5
var/mode = LIGHT_MODE
actions_types = list(/datum/action/item_action/pick_color)
ammo_sections = 5
has_ammobar = TRUE
var/wallcost = 10
var/floorcost = 15
var/launchcost = 5
var/deconcost = 10
var/wallcost = 20
var/floorcost = 25
var/launchcost = 10
var/deconcost = 20
var/walldelay = 10
var/floordelay = 10
@@ -707,11 +707,10 @@ RLD
else
..()
/obj/item/construction/rld/update_icon()
..()
/obj/item/construction/rld/update_overlays()
. = ..()
var/ratio = CEILING((matter / max_matter) * ammo_sections, 1)
cut_overlays() //To prevent infinite stacking of overlays
add_overlay("rld_light[ratio]")
. += "rld_light[ratio]"
/obj/item/construction/rld/attack_self(mob/user)
..()
+36 -68
View File
@@ -2,8 +2,8 @@
name = "rapid cable layer"
desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables. Do not use without insulation!"
icon = 'icons/obj/tools.dmi'
icon_state = "rcl-empty"
item_state = "rcl-0"
icon_state = "rcl"
item_state = "rcl"
var/obj/structure/cable/last
var/obj/item/stack/cable_coil/loaded
opacity = FALSE
@@ -23,6 +23,14 @@
var/datum/radial_menu/persistent/wiring_gui_menu
var/mob/listeningTo
/obj/item/twohanded/rcl/Initialize()
. = ..()
update_icon()
/obj/item/twohanded/rcl/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/twohanded/rcl/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = W
@@ -90,34 +98,28 @@
QDEL_NULL(wiring_gui_menu)
return ..()
/obj/item/twohanded/rcl/update_icon()
if(!loaded)
icon_state = "rcl-empty"
item_state = "rcl-empty"
/obj/item/twohanded/rcl/update_icon_state()
icon_state = initial(icon_state)
item_state = initial(item_state)
if(!loaded || !loaded.amount)
icon_state += "-empty"
item_state += "-0"
/obj/item/twohanded/rcl/update_overlays()
. = ..()
if(!loaded || !loaded.amount)
return
cut_overlays()
var/cable_amount = 0
switch(loaded.amount)
if(61 to INFINITY)
cable_amount = 3
if(31 to 60)
cable_amount = 2
if(1 to 30)
cable_amount = 1
else
cable_amount = 0
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[cable_amount]")
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "[initial(icon_state)]-[CEILING(loaded.amount/(max_amount/3), 1)]")
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
if(cable_amount >= 1)
icon_state = "rcl"
item_state = "rcl"
add_overlay(cable_overlay)
else
icon_state = "rcl-empty"
item_state = "rcl-0"
add_overlay(cable_overlay)
. += cable_overlay
/obj/item/twohanded/rcl/worn_overlays(isinhands, icon_file, style_flags = NONE)
. = ..()
if(!isinhands || !(loaded?.amount))
return
var/mutable_appearance/cable_overlay = mutable_appearance(icon_file, "rcl-[CEILING(loaded.amount/(max_amount/3), 1)]")
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
. += cable_overlay
/obj/item/twohanded/rcl/proc/is_empty(mob/user, loud = 1)
update_icon()
@@ -289,18 +291,6 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
wiringGuiUpdate(user)
/obj/item/twohanded/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff
. = ..()
loaded = new()
loaded.max_amount = max_amount
loaded.amount = max_amount
update_icon()
/obj/item/twohanded/rcl/Initialize()
. = ..()
update_icon()
/obj/item/twohanded/rcl/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/rcl_col))
current_color_index++;
@@ -319,37 +309,15 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
else //open the menu
showWiringGui(user)
/obj/item/twohanded/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff
loaded = new()
loaded.max_amount = max_amount
loaded.amount = max_amount
return ..()
/obj/item/twohanded/rcl/ghetto
actions_types = list()
max_amount = 30
name = "makeshift rapid cable layer"
icon_state = "rclg"
ghetto = TRUE
/obj/item/twohanded/rcl/ghetto/update_icon()
if(!loaded)
icon_state = "rclg-empty"
item_state = "rclg-0"
return
cut_overlays()
var/cable_amount = 0
switch(loaded.amount)
if(20 to INFINITY)
cable_amount = 3
if(10 to 19)
cable_amount = 2
if(1 to 9)
cable_amount = 1
else
cable_amount = 0
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[cable_amount]")
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
if(cable_amount >= 1)
icon_state = "rclg"
item_state = "rclg"
add_overlay(cable_overlay)
else
icon_state = "rclg-empty"
item_state = "rclg-0"
add_overlay(cable_overlay)
+50 -41
View File
@@ -7,32 +7,35 @@ RPD
#define DISPOSALS_CATEGORY 1
#define TRANSIT_CATEGORY 2
#define BUILD_MODE 1
#define WRENCH_MODE 2
#define DESTROY_MODE 4
#define PAINT_MODE 8
#define BUILD_MODE (1<<0)
#define WRENCH_MODE (1<<1)
#define DESTROY_MODE (1<<2)
#define PAINT_MODE (1<<3)
GLOBAL_LIST_INIT(atmos_pipe_recipes, list(
"Pipes" = list(
new /datum/pipe_info/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple),
new /datum/pipe_info/pipe("Manifold", /obj/machinery/atmospherics/pipe/manifold),
new /datum/pipe_info/pipe("Manual Valve", /obj/machinery/atmospherics/components/binary/valve),
new /datum/pipe_info/pipe("Digital Valve", /obj/machinery/atmospherics/components/binary/valve/digital),
new /datum/pipe_info/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/manifold4w),
new /datum/pipe_info/pipe("Layer Manifold", /obj/machinery/atmospherics/pipe/layer_manifold),
),
"Devices" = list(
new /datum/pipe_info/pipe("Connector", /obj/machinery/atmospherics/components/unary/portables_connector),
new /datum/pipe_info/pipe("Unary Vent", /obj/machinery/atmospherics/components/unary/vent_pump),
new /datum/pipe_info/pipe("Gas Pump", /obj/machinery/atmospherics/components/binary/pump),
new /datum/pipe_info/pipe("Passive Gate", /obj/machinery/atmospherics/components/binary/passive_gate),
new /datum/pipe_info/pipe("Volume Pump", /obj/machinery/atmospherics/components/binary/volume_pump),
new /datum/pipe_info/pipe("Scrubber", /obj/machinery/atmospherics/components/unary/vent_scrubber),
new /datum/pipe_info/pipe("Injector", /obj/machinery/atmospherics/components/unary/outlet_injector),
new /datum/pipe_info/meter("Meter"),
new /datum/pipe_info/pipe("Gas Filter", /obj/machinery/atmospherics/components/trinary/filter),
new /datum/pipe_info/pipe("Gas Mixer", /obj/machinery/atmospherics/components/trinary/mixer),
new /datum/pipe_info/pipe("Passive Gate", /obj/machinery/atmospherics/components/binary/passive_gate),
new /datum/pipe_info/pipe("Injector", /obj/machinery/atmospherics/components/unary/outlet_injector),
new /datum/pipe_info/pipe("Scrubber", /obj/machinery/atmospherics/components/unary/vent_scrubber),
new /datum/pipe_info/pipe("Unary Vent", /obj/machinery/atmospherics/components/unary/vent_pump),
new /datum/pipe_info/pipe("Passive Vent", /obj/machinery/atmospherics/components/unary/passive_vent),
new /datum/pipe_info/pipe("Manual Valve", /obj/machinery/atmospherics/components/binary/valve),
new /datum/pipe_info/pipe("Digital Valve", /obj/machinery/atmospherics/components/binary/valve/digital),
new /datum/pipe_info/pipe("Relief Valve (Binary)", /obj/machinery/atmospherics/components/binary/relief_valve),
new /datum/pipe_info/pipe("Relief Valve (Unary)", /obj/machinery/atmospherics/components/unary/relief_valve),
new /datum/pipe_info/meter("Meter"),
),
"Heat Exchange" = list(
new /datum/pipe_info/pipe("Pipe", /obj/machinery/atmospherics/pipe/heat_exchanging/simple),
@@ -99,22 +102,22 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
dirs = list("[NORTH]" = "Vertical", "[EAST]" = "Horizontal")
if(dirtype == PIPE_BENDABLE)
dirs += list("[NORTHWEST]" = "West to North", "[NORTHEAST]" = "North to East",
"[SOUTHWEST]" = "South to West", "[SOUTHEAST]" = "East to South")
"[SOUTHWEST]" = "South to West", "[SOUTHEAST]" = "East to South")
if(PIPE_TRINARY)
dirs = list("[NORTH]" = "West South East", "[EAST]" = "North West South",
"[SOUTH]" = "East North West", "[WEST]" = "South East North")
dirs = list("[NORTH]" = "West South East", "[SOUTH]" = "East North West",
"[EAST]" = "North West South", "[WEST]" = "South East North")
if(PIPE_TRIN_M)
dirs = list("[NORTH]" = "North East South", "[EAST]" = "East South West",
"[SOUTH]" = "South West North", "[WEST]" = "West North East",
"[SOUTHEAST]" = "West South East", "[NORTHEAST]" = "South East North",
"[NORTHWEST]" = "East North West", "[SOUTHWEST]" = "North West South")
dirs = list("[NORTH]" = "North East South", "[SOUTHWEST]" = "North West South",
"[NORTHEAST]" = "South East North", "[SOUTH]" = "South West North",
"[WEST]" = "West North East", "[SOUTHEAST]" = "West South East",
"[NORTHWEST]" = "East North West", "[EAST]" = "East South West",)
if(PIPE_UNARY)
dirs = list("[NORTH]" = "North", "[EAST]" = "East", "[SOUTH]" = "South", "[WEST]" = "West")
dirs = list("[NORTH]" = "North", "[SOUTH]" = "South", "[WEST]" = "West", "[EAST]" = "East")
if(PIPE_ONEDIR)
dirs = list("[SOUTH]" = name)
if(PIPE_UNARY_FLIPPABLE)
dirs = list("[NORTH]" = "North", "[NORTHEAST]" = "North Flipped", "[EAST]" = "East", "[SOUTHEAST]" = "East Flipped",
"[SOUTH]" = "South", "[SOUTHWEST]" = "South Flipped", "[WEST]" = "West", "[NORTHWEST]" = "West Flipped")
dirs = list("[NORTH]" = "North", "[EAST]" = "East", "[SOUTH]" = "South", "[WEST]" = "West",
"[NORTHEAST]" = "North Flipped", "[SOUTHEAST]" = "East Flipped", "[SOUTHWEST]" = "South Flipped", "[NORTHWEST]" = "West Flipped")
var/list/rows = list()
@@ -185,7 +188,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
throw_speed = 1
throw_range = 5
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=75000, MAT_GLASS=37500)
custom_materials = list(/datum/material/iron=75000, /datum/material/glass=37500)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
resistance_flags = FIRE_PROOF
var/datum/effect_system/spark_spread/spark_system
@@ -205,7 +208,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
var/static/datum/pipe_info/first_atmos
var/static/datum/pipe_info/first_disposal
var/static/datum/pipe_info/first_transit
var/mode = BUILD_MODE | PAINT_MODE | DESTROY_MODE | WRENCH_MODE
var/mode = BUILD_MODE | DESTROY_MODE | WRENCH_MODE
/obj/item/pipe_dispenser/New()
. = ..()
@@ -246,7 +249,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/pipes)
assets.send(user)
ui = new(user, src, ui_key, "rpd", name, 300, 550, master_ui, state)
ui = new(user, src, ui_key, "rpd", name, 425, 472, master_ui, state)
ui.open()
/obj/item/pipe_dispenser/ui_data(mob/user)
@@ -313,9 +316,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
playeffect = FALSE
if("mode")
var/n = text2num(params["mode"])
if(n == 2 && !(mode&1) && !(mode&2))
mode |= 3
else if(mode&n)
if(mode & n)
mode &= ~n
else
mode |= n
@@ -324,9 +325,11 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
spark_system.start()
effectcooldown = world.time + 100
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
return TRUE
/obj/item/pipe_dispenser/pre_attack(atom/A, mob/user)
if(!user.IsAdvancedToolUser() || istype(A, /turf/open/space/transit))
var/turf/T = get_turf(A)
if(!user.IsAdvancedToolUser() || !T || istype(T, /turf/open/space/transit) || isindestructiblewall(T))
return ..()
//So that changing the menu settings doesn't affect the pipes already being built.
@@ -338,11 +341,13 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
var/static/list/make_pipe_whitelist
if(!make_pipe_whitelist)
make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe, /obj/structure/window, /obj/structure/grille))
if(istype(A, /obj/machinery/atmospherics) && (mode & BUILD_MODE && !(mode & PAINT_MODE))) //Reduces pixelhunt when coloring is off.
A = get_turf(A)
var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist))
. = FALSE
. = TRUE
if((mode&DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter))
if((mode & DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter))
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, destroy_speed, target = A))
@@ -350,7 +355,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
qdel(A)
return
if((mode&PAINT_MODE))
if((mode & PAINT_MODE))
if(istype(A, /obj/machinery/atmospherics/pipe) && !istype(A, /obj/machinery/atmospherics/pipe/layer_manifold))
var/obj/machinery/atmospherics/pipe/P = A
to_chat(user, "<span class='notice'>You start painting \the [P] [paint_color]...</span>")
@@ -368,19 +373,23 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
user.visible_message("<span class='notice'>[user] paints \the [A] [paint_color].</span>","<span class='notice'>You paint \the [A] [paint_color].</span>")
return
if(mode&BUILD_MODE)
if(mode & BUILD_MODE)
switch(category) //if we've gotten this var, the target is valid
if(ATMOS_CATEGORY) //Making pipes
if(!can_make_pipe)
return ..()
A = T
if(is_type_in_typecache(recipe, GLOB.ventcrawl_machinery) && isclosedturf(A)) //wall escapism sanity check.
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
return
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if (recipe.type == /datum/pipe_info/meter)
to_chat(user, "<span class='notice'>You start building a meter...</span>")
if(do_after(user, atmos_build_speed, target = A))
activate()
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A))
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(A)
PM.setAttachLayer(piping_layer)
if(mode&WRENCH_MODE)
if(mode & WRENCH_MODE)
PM.wrench_act(user, src)
else
to_chat(user, "<span class='notice'>You start building a pipe...</span>")
@@ -388,7 +397,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
activate()
var/obj/machinery/atmospherics/path = queued_p_type
var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe
var/obj/item/pipe/P = new pipe_item_type(get_turf(A), queued_p_type, queued_p_dir)
var/obj/item/pipe/P = new pipe_item_type(A, queued_p_type, queued_p_dir)
if(queued_p_flipped && istype(P, /obj/item/pipe/trinary/flippable))
var/obj/item/pipe/trinary/flippable/F = P
@@ -399,13 +408,13 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
P.setPipingLayer(piping_layer)
if(findtext("[queued_p_type]", "/obj/machinery/atmospherics/pipe") && !findtext("[queued_p_type]", "layer_manifold"))
P.add_atom_colour(GLOB.pipe_paint_colors[paint_color], FIXED_COLOUR_PRIORITY)
if(mode&WRENCH_MODE)
if(mode & WRENCH_MODE)
P.wrench_act(user, src)
if(DISPOSALS_CATEGORY) //Making disposals pipes
if(!can_make_pipe)
return ..()
A = get_turf(A)
A = T
if(isclosedturf(A))
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
return
@@ -423,14 +432,14 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
C.add_fingerprint(usr)
C.update_icon()
if(mode&WRENCH_MODE)
if(mode & WRENCH_MODE)
C.wrench_act(user, src)
return
if(TRANSIT_CATEGORY) //Making transit tubes
if(!can_make_pipe)
return ..()
A = get_turf(A)
A = T
if(isclosedturf(A))
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
return
@@ -445,7 +454,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
if(queued_p_type == /obj/structure/c_transit_tube_pod)
var/obj/structure/c_transit_tube_pod/pod = new /obj/structure/c_transit_tube_pod(A)
pod.add_fingerprint(usr)
if(mode&WRENCH_MODE)
if(mode & WRENCH_MODE)
pod.wrench_act(user, src)
else
@@ -457,7 +466,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
tube.simple_rotate_flip()
tube.add_fingerprint(usr)
if(mode&WRENCH_MODE)
if(mode & WRENCH_MODE)
tube.wrench_act(user, src)
return
+3 -3
View File
@@ -7,7 +7,7 @@
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=50, MAT_GLASS=50)
custom_materials = list(/datum/material/iron=50, /datum/material/glass=50)
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
@@ -64,10 +64,10 @@
if(!L)
return OXYLOSS
L.Remove(user)
L.Remove()
// make some colorful reagent, and apply it to the lungs
L.create_reagents(10)
L.create_reagents(10, NONE, NO_REAGENTS_VALUE)
L.reagents.add_reagent(/datum/reagent/colorful_reagent, 10)
L.reagents.reaction(L, TOUCH, 1)
+4 -4
View File
@@ -1,6 +1,6 @@
/obj/item/wallframe
icon = 'icons/obj/wallframe.dmi'
materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT*2)
custom_materials = list(/datum/material/iron=MINERAL_MATERIAL_AMOUNT*2)
flags_1 = CONDUCT_1
item_state = "syringe_kit"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
@@ -66,8 +66,8 @@
if(iswallturf(T))
T.attackby(src, user, params)
var/metal_amt = round(materials[MAT_METAL]/MINERAL_MATERIAL_AMOUNT)
var/glass_amt = round(materials[MAT_GLASS]/MINERAL_MATERIAL_AMOUNT)
var/metal_amt = round(custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)]/MINERAL_MATERIAL_AMOUNT)
var/glass_amt = round(custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)]/MINERAL_MATERIAL_AMOUNT)
if(istype(W, /obj/item/wrench) && (metal_amt || glass_amt))
to_chat(user, "<span class='notice'>You dismantle [src].</span>")
@@ -119,5 +119,5 @@
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=50, MAT_GLASS=50)
custom_materials = list(/datum/material/iron=50, /datum/material/glass=50)
grind_results = list(/datum/reagent/iron = 10, /datum/reagent/silicon = 10)
+1 -1
View File
@@ -20,7 +20,7 @@
throw_range = 14
w_class = WEIGHT_CLASS_SMALL
/obj/item/toy/tennis/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
/obj/item/toy/tennis/alt_pre_attack(atom/A, mob/living/user, params) //checks if it can do right click memes
altafterattack(A, user, TRUE, params)
return TRUE
+2 -1
View File
@@ -13,7 +13,8 @@
/obj/item/areaeditor/attack_self(mob/user)
add_fingerprint(user)
. = "<BODY><HTML><head><title>[src]</title></head> \
. = "<BODY><HTML><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>\
<title>[src]</title></head> \
<h2>[station_name()] [src.name]</h2> \
<small>[fluffnotice]</small><hr>"
switch(get_area_type())
+3 -3
View File
@@ -20,12 +20,12 @@
owner.med_hud_set_status()
INVOKE_ASYNC(src, .proc/AddInfectionImages, owner)
/obj/item/organ/body_egg/Remove(var/mob/living/carbon/M, special = 0)
if(owner)
/obj/item/organ/body_egg/Remove(special = FALSE)
if(!QDELETED(owner))
REMOVE_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC)
owner.med_hud_set_status()
INVOKE_ASYNC(src, .proc/RemoveInfectionImages, owner)
..()
return ..()
/obj/item/organ/body_egg/on_death()
. = ..()
+6 -4
View File
@@ -23,7 +23,7 @@
if(!boomingandboxing)
var/list/tracklist = list()
for(var/datum/track/S in SSjukeboxes.songs)
if(istype(S) && S.song_associated_id in availabletrackids)
if(istype(S) && (S.song_associated_id in availabletrackids))
tracklist[S.song_name] = S
var/selected = input(user, "Play song", "Track:") as null|anything in tracklist
if(QDELETED(src) || !selected || !istype(tracklist[selected], /datum/track))
@@ -37,7 +37,7 @@
SSjukeboxes.removejukebox(SSjukeboxes.findjukeboxindex(src))
. = ..()
/obj/item/boombox/update_icon()
/obj/item/boombox/update_icon_state()
icon_state = "[baseiconstate]_[boomingandboxing ? "on" : "off"]"
return
@@ -48,8 +48,11 @@
baseiconstate = "raiqbawks"
availabletrackids = list("hotline.ogg","chiptune.ogg","genesis.ogg")
/obj/item/boombox/raiq/update_icon()
/obj/item/boombox/raiq/Initialize()
. = ..()
RegisterSignal(src, COMSIG_ATOM_UPDATED_ICON, .proc/start_party)
/obj/item/boombox/raiq/proc/start_party()
if(boomingandboxing)
START_PROCESSING(SSobj, src)
else
@@ -58,4 +61,3 @@
/obj/item/boombox/raiq/process()
set_light(5,0.95,pick("#d87aff","#7a7aff","#89ecff","#b88eff","#ff59ad"))
return
+8 -3
View File
@@ -13,13 +13,14 @@
var/lit = FALSE
var/infinite = FALSE
var/start_lit = FALSE
var/heats_space = TRUE
/obj/item/candle/Initialize()
. = ..()
if(start_lit)
light()
/obj/item/candle/update_icon()
/obj/item/candle/update_icon_state()
icon_state = "candle[(wax > 400) ? ((wax > 750) ? 1 : 2) : 3][lit ? "_lit" : ""]"
/obj/item/candle/attackby(obj/item/W, mob/user, params)
@@ -35,7 +36,7 @@
return ..()
/obj/item/candle/get_temperature()
return lit * heat
return lit * heat * heats_space
/obj/item/candle/proc/light(show_message)
if(!lit)
@@ -67,7 +68,8 @@
new /obj/item/trash/candle(loc)
qdel(src)
update_icon()
open_flame()
if(heats_space)
open_flame()
/obj/item/candle/attack_self(mob/user)
if(put_out_candle())
@@ -77,4 +79,7 @@
infinite = TRUE
start_lit = TRUE
/obj/item/candle/infinite/hugbox
heats_space = FALSE
#undef CANDLE_LUMINOSITY
@@ -74,6 +74,7 @@
playsound(src, 'sound/weapons/slice.ogg', 50, 1)
if(prob(P.damage))
push_over()
return BULLET_ACT_HIT
/obj/item/cardboard_cutout/proc/change_appearance(obj/item/toy/crayon/crayon, mob/living/user)
if(!crayon || !user)
+70 -34
View File
@@ -40,13 +40,13 @@
.=..()
update_icon()
/obj/item/card/data/update_icon()
cut_overlays()
/obj/item/card/data/update_overlays()
. = ..()
if(detail_color == COLOR_FLOORTILE_GRAY)
return
var/mutable_appearance/detail_overlay = mutable_appearance('icons/obj/card.dmi', "[icon_state]-color")
detail_overlay.color = detail_color
add_overlay(detail_overlay)
. += detail_overlay
/obj/item/card/data/attackby(obj/item/I, mob/living/user)
if(istype(I, /obj/item/integrated_electronics/detailer))
@@ -128,6 +128,9 @@
return
. = ..()
/obj/item/card/emag/empty
uses = 0
/obj/item/emagrecharge
name = "electromagnet charging device"
desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for charging the small batteries found in electromagnetic devices, sadly this can't be recharged like a normal cell."
@@ -247,6 +250,7 @@ update_label("John Doe", "Clowny")
name = "agent card"
access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE)
var/anyone = FALSE //Can anyone forge the ID or just syndicate?
var/forged = FALSE //have we set a custom name and job assignment, or will we use what we're given when we chameleon change?
/obj/item/card/id/syndicate/Initialize()
. = ..()
@@ -262,29 +266,52 @@ update_label("John Doe", "Clowny")
var/obj/item/card/id/I = O
src.access |= I.access
if(isliving(user) && user.mind)
if(user.mind.special_role)
if(user.mind.special_role || anyone)
to_chat(usr, "<span class='notice'>The card's microscanners activate as you pass it over the ID, copying its access.</span>")
/obj/item/card/id/syndicate/attack_self(mob/user)
if(isliving(user) && user.mind)
if(user.mind.special_role || anyone)
if(alert(user, "Action", "Agent ID", "Show", "Forge") == "Forge")
var/t = copytext(sanitize(input(user, "What name would you like to put on this card?", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name))as text | null),1,26)
if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall") //Same as mob/dead/new_player/prefrences.dm
if (t)
alert("Invalid name.")
return
registered_name = t
var/first_use = registered_name ? FALSE : TRUE
if(!(user.mind.special_role || anyone)) //Unless anyone is allowed, only syndies can use the card, to stop metagaming.
if(first_use) //If a non-syndie is the first to forge an unassigned agent ID, then anyone can forge it.
anyone = TRUE
else
return ..()
var/u = copytext(sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant")as text | null),1,MAX_MESSAGE_LEN)
if(!u)
registered_name = ""
return
assignment = u
update_label()
to_chat(user, "<span class='notice'>You successfully forge the ID card.</span>")
var/popup_input = alert(user, "Choose Action", "Agent ID", "Show", "Forge/Reset")
if(user.incapacitated())
return
if(popup_input == "Forge/Reset" && !forged)
var/input_name = stripped_input(user, "What name would you like to put on this card? Leave blank to randomise.", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name), MAX_NAME_LEN)
input_name = reject_bad_name(input_name)
if(!input_name)
// Invalid/blank names give a randomly generated one.
if(user.gender == MALE)
input_name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]"
else if(user.gender == FEMALE)
input_name = "[pick(GLOB.first_names_female)] [pick(GLOB.last_names)]"
else
input_name = "[pick(GLOB.first_names)] [pick(GLOB.last_names)]"
var/target_occupation = stripped_input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", assignment ? assignment : "Assistant", MAX_MESSAGE_LEN)
if(!target_occupation)
return
..()
registered_name = input_name
assignment = target_occupation
update_label()
forged = TRUE
to_chat(user, "<span class='notice'>You successfully forge the ID card.</span>")
log_game("[key_name(user)] has forged \the [initial(name)] with name \"[registered_name]\" and occupation \"[assignment]\".")
return
else if (popup_input == "Forge/Reset" && forged)
registered_name = initial(registered_name)
assignment = initial(assignment)
log_game("[key_name(user)] has reset \the [initial(name)] named \"[src]\" to default.")
update_label()
forged = FALSE
to_chat(user, "<span class='notice'>You successfully reset the ID card.</span>")
return
return ..()
/obj/item/card/id/syndicate/anyone
anyone = TRUE
@@ -490,10 +517,16 @@ update_label("John Doe", "Clowny")
//Polychromatic Knight Badge
/obj/item/card/id/knight
var/id_color = "#00FF00" //defaults to green
name = "knight badge"
icon_state = "knight"
desc = "A badge denoting the owner as a knight! It has a strip for swiping like an ID"
var/id_color = "#00FF00" //defaults to green
var/mutable_appearance/id_overlay
/obj/item/card/id/knight/Initialize()
. = ..()
id_overlay = mutable_appearance(icon, "knight_overlay")
update_icon()
/obj/item/card/id/knight/update_label(newname, newjob)
if(newname || newjob)
@@ -502,14 +535,10 @@ update_label("John Doe", "Clowny")
name = "[(!registered_name) ? "knight badge" : "[registered_name]'s Knight Badge"][(!assignment) ? "" : " ([assignment])"]"
/obj/item/card/id/knight/update_icon()
var/mutable_appearance/id_overlay = mutable_appearance(icon, "knight_overlay")
if(id_color)
id_overlay.color = id_color
cut_overlays()
add_overlay(id_overlay)
/obj/item/card/id/knight/update_overlays()
. = ..()
id_overlay.color = id_color
. += id_overlay
/obj/item/card/id/knight/AltClick(mob/living/user)
. = ..()
@@ -529,10 +558,6 @@ update_label("John Doe", "Clowny")
update_icon()
return TRUE
/obj/item/card/id/knight/Initialize()
. = ..()
update_icon()
/obj/item/card/id/knight/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click to recolor it.</span>"
@@ -541,4 +566,15 @@ update_label("John Doe", "Clowny")
id_color = "#0000FF"
/obj/item/card/id/knight/captain
id_color = "#FFD700"
id_color = "#FFD700"
/obj/item/card/id/debug
name = "\improper Debug ID"
desc = "A debug ID card. Has ALL the all access, you really shouldn't have this."
icon_state = "ert_janitor"
assignment = "Jannie"
/obj/item/card/id/debug/Initialize()
access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
. = ..()
+92
View File
@@ -0,0 +1,92 @@
/obj/item/chromosome
name = "blank chromosome"
icon = 'icons/obj/chromosomes.dmi'
icon_state = ""
desc = "A tube holding chromosomic data."
force = 0
w_class = WEIGHT_CLASS_SMALL
var/stabilizer_coeff = 1 //lower is better, affects genetic stability
var/synchronizer_coeff = 1 //lower is better, affects chance to backfire
var/power_coeff = 1 //higher is better, affects "strength"
var/energy_coeff = 1 //lower is better. affects recharge time
var/weight = 5
/obj/item/chromosome/proc/can_apply(datum/mutation/human/HM)
if(!HM || !(HM.can_chromosome == CHROMOSOME_NONE))
return FALSE
if((stabilizer_coeff != 1) && (HM.stabilizer_coeff != -1)) //if the chromosome is 1, we dont change anything. If the mutation is -1, we cant change it. sorry
return TRUE
if((synchronizer_coeff != 1) && (HM.synchronizer_coeff != -1))
return TRUE
if((power_coeff != 1) && (HM.power_coeff != -1))
return TRUE
if((energy_coeff != 1) && (HM.energy_coeff != -1))
return TRUE
/obj/item/chromosome/proc/apply(datum/mutation/human/HM)
if(HM.stabilizer_coeff != -1)
HM.stabilizer_coeff = stabilizer_coeff
if(HM.synchronizer_coeff != -1)
HM.synchronizer_coeff = synchronizer_coeff
if(HM.power_coeff != -1)
HM.power_coeff = power_coeff
if(HM.energy_coeff != -1)
HM.energy_coeff = energy_coeff
HM.can_chromosome = 2
HM.chromosome_name = name
HM.modify()
qdel(src)
/proc/generate_chromosome()
var/static/list/chromosomes
if(!chromosomes)
chromosomes = list()
for(var/A in subtypesof(/obj/item/chromosome))
var/obj/item/chromosome/CM = A
if(!initial(CM.weight))
break
chromosomes[A] = initial(CM.weight)
return pickweight(chromosomes)
/obj/item/chromosome/stabilizer
name = "stabilizer chromosome"
desc = "A chromosome that adjusts to the body to reduce genetic damage by 20%."
icon_state = "stabilizer"
stabilizer_coeff = 0.8
weight = 1
/obj/item/chromosome/synchronizer
name = "synchronizer chromosome"
desc = "A chromosome that gives the mind more controle over the mutation, reducing knockback and downsides by 50%."
icon_state = "synchronizer"
synchronizer_coeff = 0.5
/obj/item/chromosome/power
name = "power chromosome"
desc = "A power chromosome for boosting certain mutation's power by 50%."
icon_state = "power"
power_coeff = 1.5
/obj/item/chromosome/energy
name = "energetic chromosome"
desc = "A chromosome that reduces cooldown on action based mutations by 50%."
icon_state = "energy"
energy_coeff = 0.5
/obj/item/chromosome/reinforcer
name = "reinforcement chromosome"
desc = "Renders the mutation immune to mutadone."
icon_state = "reinforcer"
weight = 3
/obj/item/chromosome/reinforcer/can_apply(datum/mutation/human/HM)
if(!HM || !(HM.can_chromosome == CHROMOSOME_NONE))
return FALSE
return !HM.mutadone_proof
/obj/item/chromosome/reinforcer/apply(datum/mutation/human/HM)
HM.mutadone_proof = TRUE
..()
+5 -8
View File
@@ -18,15 +18,11 @@
/obj/item/chrono_eraser/proc/pass_mind(datum/mind/M)
erased_minds += M
/obj/item/chrono_eraser/dropped()
/obj/item/chrono_eraser/dropped(mob/user)
..()
if(PA)
qdel(PA)
/obj/item/chrono_eraser/Destroy()
dropped()
return ..()
/obj/item/chrono_eraser/ui_action_click(mob/user)
if(iscarbon(user))
var/mob/living/carbon/C = user
@@ -65,8 +61,9 @@
TED = new(src.loc)
return INITIALIZE_HINT_QDEL
/obj/item/gun/energy/chrono_gun/update_icon()
return
/obj/item/gun/energy/chrono_gun/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_blocker)
/obj/item/gun/energy/chrono_gun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
if(field)
@@ -242,7 +239,7 @@
if(Pgun && istype(Pgun))
Pgun.field_connect(src)
else
return 0
return BULLET_ACT_HIT
/obj/effect/chrono_field/assume_air()
return 0
+19 -16
View File
@@ -122,7 +122,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/cigarette/Initialize()
. = ..()
create_reagents(chem_volume, INJECTABLE | NO_REACT) // so it doesn't react until you light it
create_reagents(chem_volume, INJECTABLE | NO_REACT, NO_REAGENTS_VALUE) // so it doesn't react until you light it
if(list_reagents)
reagents.add_reagent_list(list_reagents)
if(starts_lit)
@@ -146,7 +146,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(!proximity || lit) //can't dip if cigarette is lit (it will heat the reagents in the glass instead)
return
if(istype(glass)) //you can dip cigarettes into beakers
if(glass.reagents.trans_to(src, chem_volume)) //if reagents were transfered, show the message
if(glass.reagents.trans_to(src, chem_volume, log = "cigar fill: dip cigarette")) //if reagents were transfered, show the message
to_chat(user, "<span class='notice'>You dip \the [src] into \the [glass].</span>")
else //if not, either the beaker was empty, or the cigarette was full
if(!glass.reagents.total_volume)
@@ -154,7 +154,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM
else
to_chat(user, "<span class='notice'>[src] is full.</span>")
/obj/item/clothing/mask/cigarette/proc/light(flavor_text = null)
if(lit)
return
@@ -438,7 +437,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
packeditem = 1
name = "[O.name]-packed [initial(name)]"
if(O.reagents)
O.reagents.trans_to(src, O.reagents.total_volume)
O.reagents.trans_to(src, O.reagents.total_volume, log = "cigar fill: pipe pack")
qdel(O)
else
to_chat(user, "<span class='warning'>It has to be dried first!</span>")
@@ -523,11 +522,13 @@ CIGARETTE PACKETS ARE IN FANCY.DM
user.visible_message("<span class='suicide'>[user] begins whacking [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/lighter/update_icon()
cut_overlays()
var/mutable_appearance/lighter_overlay = mutable_appearance(icon,"lighter_overlay_[overlay_state][lit ? "-on" : ""]")
/obj/item/lighter/update_icon_state()
icon_state = "[initial(icon_state)][lit ? "-on" : ""]"
add_overlay(lighter_overlay)
/obj/item/lighter/update_overlays()
. = ..()
var/mutable_appearance/lighter_overlay = mutable_appearance(icon,"lighter_overlay_[overlay_state][lit ? "-on" : ""]")
. += lighter_overlay
/obj/item/lighter/ignition_effect(atom/A, mob/user)
if(get_temperature())
@@ -646,12 +647,14 @@ CIGARETTE PACKETS ARE IN FANCY.DM
lighter_color = pick(color_list)
update_icon()
/obj/item/lighter/greyscale/update_icon()
cut_overlays()
var/mutable_appearance/lighter_overlay = mutable_appearance(icon,"lighter_overlay_[overlay_state][lit ? "-on" : ""]")
/obj/item/lighter/greyscale/update_icon_state()
icon_state = "[initial(icon_state)][lit ? "-on" : ""]"
/obj/item/lighter/greyscale/update_overlays()
. = ..()
var/mutable_appearance/lighter_overlay = mutable_appearance(icon,"lighter_overlay_[overlay_state][lit ? "-on" : ""]")
lighter_overlay.color = lighter_color
add_overlay(lighter_overlay)
. += lighter_overlay
/obj/item/lighter/greyscale/ignition_effect(atom/A, mob/user)
if(get_temperature())
@@ -687,7 +690,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(O.dry)
var/obj/item/clothing/mask/cigarette/rollie/R = new /obj/item/clothing/mask/cigarette/rollie(user.loc)
R.chem_volume = target.reagents.total_volume
target.reagents.trans_to(R, R.chem_volume)
target.reagents.trans_to(R, R.chem_volume, log = "cigar fill: rolling paper afterattack")
qdel(target)
qdel(src)
user.put_in_active_hand(R)
@@ -718,7 +721,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/vape/Initialize(mapload, param_color)
. = ..()
create_reagents(chem_volume, NO_REACT) // so it doesn't react until you light it
create_reagents(chem_volume, NO_REACT, NO_REAGENTS_VALUE) // so it doesn't react until you light it
reagents.add_reagent(/datum/reagent/drug/nicotine, 50)
if(!icon_state)
if(!param_color)
@@ -853,7 +856,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(prob(5))//small chance for the vape to break and deal damage if it's emagged
playsound(get_turf(src), 'sound/effects/pop_expl.ogg', 50, 0)
M.apply_damage(20, BURN, BODY_ZONE_HEAD)
M.Knockdown(300, 1, 0)
M.DefaultCombatKnockdown(300, 1, 0)
var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread
sp.set_up(5, 1, src)
sp.start()
@@ -903,7 +906,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
//Transfer reagents and remove the plant
user.show_message("<span class='notice'>You stuff the [DP] into the [src]'s bowl.</span>", MSG_VISUAL)
DP.reagents.trans_to(src, 100)
DP.reagents.trans_to(src, 100, log = "cigar fill: bong")
qdel(DP)
return
else
@@ -10,7 +10,7 @@
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
materials = list(MAT_GLASS=1000)
custom_materials = list(/datum/material/glass=1000)
w_class = WEIGHT_CLASS_SMALL
grind_results = list(/datum/reagent/silicon = 20)
var/build_path = null
@@ -35,6 +35,10 @@
/obj/item/stock_parts/manipulator = 1,
/obj/item/stack/sheet/glass = 1)
/obj/item/circuitboard/machine/autolathe/secure
name = "Secure Autolathe (Machine Board)"
build_path = /obj/machinery/autolathe/secure
/obj/item/circuitboard/machine/bloodbankgen
name = "Blood Bank Generator (Machine Board)"
build_path = /obj/machinery/bloodbankgen
@@ -70,7 +74,7 @@
build_path = /obj/machinery/dna_scannernew
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
/obj/item/stock_parts/manipulator = 1,
/obj/item/stock_parts/matter_bin = 1,
/obj/item/stock_parts/micro_laser = 1,
/obj/item/stack/sheet/glass = 1,
/obj/item/stack/cable_coil = 2)
@@ -238,6 +242,14 @@
/obj/machinery/vending/cigarette = "ShadyCigs Deluxe",
/obj/machinery/vending/games = "\improper Good Clean Fun",
/obj/machinery/vending/autodrobe = "AutoDrobe",
/obj/machinery/vending/assist = "\improper Vendomat",
/obj/machinery/vending/engivend = "\improper Engi-Vend",
/obj/machinery/vending/engivend = "\improper YouTool",
/obj/machinery/vending/sustenance = "\improper Sustenance Vendor",
/obj/machinery/vending/dinnerware = "\improper Plasteel Chef's Dinnerware Vendor",
/obj/machinery/vending/cart = "\improper PTech",
/obj/machinery/vending/hydronutrients = "\improper NutriMax",
/obj/machinery/vending/hydroseeds = "\improper MegaSeed Servitor",
/obj/machinery/vending/wardrobe/sec_wardrobe = "SecDrobe",
/obj/machinery/vending/wardrobe/medi_wardrobe = "MediDrobe",
/obj/machinery/vending/wardrobe/engi_wardrobe = "EngiDrobe",
@@ -308,6 +320,7 @@
/obj/item/circuitboard/machine/thermomachine
name = "Thermomachine (Machine Board)"
desc = "You can use a screwdriver to switch between heater and freezer."
var/pipe_layer = PIPING_LAYER_DEFAULT
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
/obj/item/stock_parts/micro_laser = 2,
@@ -342,8 +355,18 @@
build_path = initial(new_type.build_path)
I.play_tool_sound(src)
to_chat(user, "<span class='notice'>You change the circuitboard setting to \"[new_setting]\".</span>")
else
return ..()
return
if(I.tool_behaviour == TOOL_MULTITOOL)
pipe_layer = (pipe_layer >= PIPING_LAYER_MAX) ? PIPING_LAYER_MIN : (pipe_layer + 1)
to_chat(user, "<span class='notice'>You change the circuitboard to layer [pipe_layer].</span>")
return
. = ..()
/obj/item/circuitboard/machine/thermomachine/examine()
. = ..()
. += "<span class='notice'>It is set to layer [pipe_layer].</span>"
/obj/item/circuitboard/machine/thermomachine/heater
name = "Heater (Machine Board)"
+14 -15
View File
@@ -96,7 +96,7 @@
charges_left = charges
if(!reagents)
create_reagents(charges_left * volume_multiplier)
create_reagents(charges_left * volume_multiplier, NONE, NO_REAGENTS_VALUE)
reagents.clear_reagents()
var/total_weight = 0
@@ -407,7 +407,7 @@
to_chat(user, "<span class='notice'>You spray a [temp] on \the [target.name]</span>")
if(length(text_buffer) > 1)
text_buffer = copytext(text_buffer,2)
text_buffer = copytext(text_buffer, length(text_buffer[1]) + 1)
SStgui.update_uis(src)
if(post_noise)
@@ -427,7 +427,7 @@
/obj/item/toy/crayon/proc/can_claim_for_gang(mob/user, atom/target)
// Check area validity.
// Reject space, player-created areas, and non-station z-levels.
var/area/A = get_area(target)
var/area/A = get_base_area(target)
if(!A || (!is_station_level(A.z)) || !A.valid_territory)
to_chat(user, "<span class='warning'>[A] is unsuitable for tagging.</span>")
return FALSE
@@ -461,7 +461,7 @@
qdel(old_marking)
var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang)
var/area/territory = get_area(target)
var/area/territory = get_base_area(target)
new /obj/effect/decal/cleanable/crayon/gang(target,G.gang,"graffiti",0,user) // Heres the gang tag.
to_chat(user, "<span class='notice'>You tagged [territory] for your gang!</span>")
@@ -577,8 +577,8 @@
new /obj/item/toy/crayon/black(src)
update_icon()
/obj/item/storage/crayons/update_icon()
cut_overlays()
/obj/item/storage/crayons/update_overlays()
. = ..()
for(var/obj/item/toy/crayon/crayon in contents)
add_overlay(mutable_appearance('icons/obj/crayons.dmi', crayon.item_color))
@@ -619,7 +619,6 @@
is_capped = TRUE
self_contained = FALSE // Don't disappear when they're empty
can_change_colour = TRUE
gang = TRUE //Gang check is true for all things upon the honored hierarchy of spraycans, except those that are FALSE.
reagent_contents = list(/datum/reagent/fuel = 1, /datum/reagent/consumable/ethanol = 1)
@@ -695,7 +694,7 @@
C.blind_eyes(1)
if(C.get_eye_protection() <= 0) // no eye protection? ARGH IT BURNS.
C.confused = max(C.confused, 3)
C.Knockdown(60)
C.DefaultCombatKnockdown(60)
if(ishuman(C) && actually_paints)
var/mob/living/carbon/human/H = C
H.lip_style = "spray_face"
@@ -711,7 +710,8 @@
if(isobj(target))
if(actually_paints)
if(color_hex2num(paint_color) < 350 && !istype(target, /obj/structure/window) && !istype(target, /obj/effect/decal/cleanable/crayon)) //Colors too dark are rejected
var/list/hsl = rgb2hsl(hex2num(copytext(paint_color,2,4)),hex2num(copytext(paint_color,4,6)),hex2num(copytext(paint_color,6,8)))
if(hsl[3] < 0.25 && !istype(target, /obj/structure/window) && !istype(target, /obj/effect/decal/cleanable/crayon)) //Colors too dark are rejected
to_chat(usr, "<span class='warning'>A color that dark on an object like this? Surely not...</span>")
return FALSE
@@ -735,13 +735,15 @@
. = ..()
/obj/item/toy/crayon/spraycan/update_icon()
/obj/item/toy/crayon/spraycan/update_icon_state()
icon_state = is_capped ? icon_capped : icon_uncapped
/obj/item/toy/crayon/spraycan/update_overlays()
. = ..()
if(use_overlays)
cut_overlays()
var/mutable_appearance/spray_overlay = mutable_appearance('icons/obj/crayons.dmi', "[is_capped ? "spraycan_cap_colors" : "spraycan_colors"]")
spray_overlay.color = paint_color
add_overlay(spray_overlay)
. += spray_overlay
/obj/item/toy/crayon/spraycan/borg
name = "cyborg spraycan"
@@ -774,7 +776,6 @@
icon_capped = "deathcan2_cap"
icon_uncapped = "deathcan2"
use_overlays = FALSE
gang = FALSE
volume_multiplier = 25
charges = 100
@@ -789,7 +790,6 @@
icon_capped = "clowncan2_cap"
icon_uncapped = "clowncan2"
use_overlays = FALSE
gang = FALSE
reagent_contents = list(/datum/reagent/lube = 1, /datum/reagent/consumable/banana = 1)
volume_multiplier = 5
@@ -804,7 +804,6 @@
icon_capped = "mimecan_cap"
icon_uncapped = "mimecan"
use_overlays = FALSE
gang = FALSE
can_change_colour = FALSE
paint_color = "#FFFFFF" //RGB
+102
View File
@@ -0,0 +1,102 @@
/* This file contains standalone items for debug purposes. */
/obj/item/debug/human_spawner
name = "human spawner"
desc = "Spawn a human by aiming at a turf and clicking. Use in hand to change type."
icon = 'icons/obj/guns/magic.dmi'
icon_state = "nothingwand"
item_state = "wand"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
var/datum/species/selected_species
var/valid_species = list()
/obj/item/debug/human_spawner/afterattack(atom/target, mob/user, proximity)
..()
if(isturf(target))
var/mob/living/carbon/human/H = new /mob/living/carbon/human(target)
if(selected_species)
H.set_species(selected_species)
/obj/item/debug/human_spawner/attack_self(mob/user)
..()
var/choice = input("Select a species", "Human Spawner", null) in GLOB.species_list
selected_species = GLOB.species_list[choice]
/* Revive this once we purge all the istype checks for tools for tool_behaviour
/obj/item/debug/omnitool
name = "omnitool"
desc = "The original hypertool, born before them all. Use it in hand to unleash it's true power."
icon = 'icons/obj/device.dmi'
icon_state = "hypertool"
item_state = "hypertool"
toolspeed = 0.1
tool_behaviour = null
/obj/item/debug/omnitool/examine()
. = ..()
. += " The mode is: [tool_behaviour]"
/obj/item/debug/omnitool/proc/check_menu(mob/user)
if(!istype(user))
return FALSE
if(user.incapacitated() || !user.Adjacent(src))
return FALSE
return TRUE
/obj/item/debug/omnitool/attack_self(mob/user)
if(!user)
return
var/list/tool_list = list(
"Crowbar" = image(icon = 'icons/obj/tools.dmi', icon_state = "crowbar"),
"Multitool" = image(icon = 'icons/obj/device.dmi', icon_state = "multitool"),
"Screwdriver" = image(icon = 'icons/obj/tools.dmi', icon_state = "screwdriver_map"),
"Wirecutters" = image(icon = 'icons/obj/tools.dmi', icon_state = "cutters_map"),
"Wrench" = image(icon = 'icons/obj/tools.dmi', icon_state = "wrench"),
"Welding Tool" = image(icon = 'icons/obj/tools.dmi', icon_state = "miniwelder"),
"Analyzer" = image(icon = 'icons/obj/device.dmi', icon_state = "analyzer"),
"Mining Tool" = image(icon = 'icons/obj/mining.dmi', icon_state = "minipick"),
"Shovel" = image(icon = 'icons/obj/mining.dmi', icon_state = "spade"),
"Retractor" = image(icon = 'icons/obj/surgery.dmi', icon_state = "retractor"),
"Hemostat" = image(icon = 'icons/obj/surgery.dmi', icon_state = "hemostat"),
"Cautery" = image(icon = 'icons/obj/surgery.dmi', icon_state = "cautery"),
"Drill" = image(icon = 'icons/obj/surgery.dmi', icon_state = "drill"),
"Scalpel" = image(icon = 'icons/obj/surgery.dmi', icon_state = "scalpel"),
"Saw" = image(icon = 'icons/obj/surgery.dmi', icon_state = "saw")
)
var/tool_result = show_radial_menu(user, src, tool_list, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
if(!check_menu(user))
return
switch(tool_result)
if("Crowbar")
tool_behaviour = TOOL_CROWBAR
if("Multitool")
tool_behaviour = TOOL_MULTITOOL
if("Screwdriver")
tool_behaviour = TOOL_SCREWDRIVER
if("Wirecutters")
tool_behaviour = TOOL_WIRECUTTER
if("Wrench")
tool_behaviour = TOOL_WRENCH
if("Welding Tool")
tool_behaviour = TOOL_WELDER
if("Analyzer")
tool_behaviour = TOOL_ANALYZER
if("Mining Tool")
tool_behaviour = TOOL_MINING
if("Shovel")
tool_behaviour = TOOL_SHOVEL
if("Retractor")
tool_behaviour = TOOL_RETRACTOR
if("Hemostat")
tool_behaviour = TOOL_HEMOSTAT
if("Cautery")
tool_behaviour = TOOL_CAUTERY
if("Drill")
tool_behaviour = TOOL_DRILL
if("Scalpel")
tool_behaviour = TOOL_SCALPEL
if("Saw")
tool_behaviour = TOOL_SAW
*/
+44 -68
View File
@@ -20,7 +20,7 @@
var/safety = TRUE //if you can zap people with the defibs on harm mode
var/powered = FALSE //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise
var/obj/item/twohanded/shockpaddles/paddles
var/obj/item/stock_parts/cell/high/cell
var/obj/item/stock_parts/cell/cell
var/combat = FALSE //can we revive through space suits?
var/grab_ghost = FALSE // Do we pull the ghost back into their body?
var/healdisk = FALSE // Will we shock people dragging the body?
@@ -35,19 +35,14 @@
/obj/item/defibrillator/Initialize() //starts without a cell for rnd
. = ..()
if(cell)
cell = new cell(src)
paddles = make_paddles()
update_icon()
return
/obj/item/defibrillator/loaded/Initialize() //starts with hicap
. = ..()
cell = new(src)
update_icon()
return
/obj/item/defibrillator/update_icon()
update_power()
return ..()
return
/obj/item/defibrillator/loaded
cell = /obj/item/stock_parts/cell/high
/obj/item/defibrillator/proc/update_power()
if(!QDELETED(cell))
@@ -57,6 +52,7 @@
powered = TRUE
else
powered = FALSE
update_icon()
/obj/item/defibrillator/update_overlays()
. = ..()
@@ -76,7 +72,7 @@
/obj/item/defibrillator/CheckParts(list/parts_list)
..()
cell = locate(/obj/item/stock_parts/cell) in contents
update_icon()
update_power()
/obj/item/defibrillator/ui_action_click()
toggle_paddles()
@@ -124,7 +120,7 @@
return
cell = W
to_chat(user, "<span class='notice'>You install a cell in [src].</span>")
update_icon()
update_power()
else if(istype(W, /obj/item/screwdriver))
if(cell)
@@ -132,7 +128,7 @@
cell.forceMove(get_turf(src))
cell = null
to_chat(user, "<span class='notice'>You remove the cell from [src].</span>")
update_icon()
update_power()
else
return ..()
@@ -157,7 +153,7 @@
safety = TRUE
visible_message("<span class='notice'>[src] beeps: Safety protocols enabled!</span>")
playsound(src, 'sound/machines/defib_saftyOn.ogg', 50, 0)
update_icon()
update_power()
/obj/item/defibrillator/proc/toggle_paddles()
set name = "Toggle Paddles"
@@ -170,14 +166,14 @@
if(!usr.put_in_hands(paddles))
on = FALSE
to_chat(user, "<span class='warning'>You need a free hand to hold the paddles!</span>")
update_icon()
update_power()
return
else
//Remove from their hands and back onto the defib unit
paddles.unwield()
remove_paddles(user)
update_icon()
update_power()
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
@@ -189,7 +185,7 @@
..()
if((slot_flags == ITEM_SLOT_BACK && slot != SLOT_BACK) || (slot_flags == ITEM_SLOT_BELT && slot != SLOT_BELT))
remove_paddles(user)
update_icon()
update_power()
/obj/item/defibrillator/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == user.getBackSlot())
@@ -213,12 +209,12 @@
if(cell)
if(cell.charge < (paddles.revivecost+chrgdeductamt))
powered = FALSE
update_icon()
update_power()
if(cell.use(chrgdeductamt))
update_icon()
update_power()
return TRUE
else
update_icon()
update_power()
return FALSE
/obj/item/defibrillator/proc/cooldowncheck(mob/user)
@@ -232,7 +228,7 @@
playsound(src, 'sound/machines/defib_failed.ogg', 50, 0)
paddles.cooldown = FALSE
paddles.update_icon()
update_icon()
update_power()
/obj/item/defibrillator/compact
name = "compact defibrillator"
@@ -246,10 +242,8 @@
if(slot == user.getBeltSlot())
return TRUE
/obj/item/defibrillator/compact/loaded/Initialize()
. = ..()
cell = new(src)
update_icon()
/obj/item/defibrillator/compact/loaded
cell = /obj/item/stock_parts/cell/high
/obj/item/defibrillator/compact/combat
name = "combat defibrillator"
@@ -258,17 +252,12 @@
safety = FALSE
always_emagged = TRUE
disarm_shock_time = 0
/obj/item/defibrillator/compact/combat/loaded/Initialize()
. = ..()
cell = new /obj/item/stock_parts/cell/infinite(src)
update_icon()
cell = /obj/item/stock_parts/cell/infinite
/obj/item/defibrillator/compact/combat/loaded/attackby(obj/item/W, mob/user, params)
if(W == paddles)
paddles.unwield()
toggle_paddles()
update_icon()
return
//paddles
@@ -298,6 +287,10 @@
var/mob/listeningTo
/obj/item/twohanded/shockpaddles/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/twohanded/shockpaddles/equipped(mob/user, slot)
. = ..()
if(!req_defib)
@@ -339,14 +332,11 @@
busy = FALSE
update_icon()
/obj/item/twohanded/shockpaddles/update_icon()
/obj/item/twohanded/shockpaddles/update_icon_state()
icon_state = "defibpaddles[wielded]"
item_state = "defibpaddles[wielded]"
if(cooldown)
icon_state = "defibpaddles[wielded]_cooldown"
if(iscarbon(loc))
var/mob/living/carbon/C = loc
C.update_inv_hands()
/obj/item/twohanded/shockpaddles/suicide_act(mob/user)
user.visible_message("<span class='danger'>[user] is putting the live paddles on [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -373,7 +363,7 @@
return
defib.on = FALSE
forceMove(defib)
defib.update_icon()
defib.update_power()
/obj/item/twohanded/shockpaddles/proc/check_defib_exists(mainunit, mob/living/carbon/M, obj/O)
if(!req_defib)
@@ -431,35 +421,21 @@
if((!req_defib && grab_ghost) || (req_defib && defib.grab_ghost))
H.notify_ghost_cloning("Your heart is being defibrillated!")
H.grab_ghost() // Shove them back in their body.
else if(can_defib(H))
else if(H.can_defib())
H.notify_ghost_cloning("Your heart is being defibrillated. Re-enter your corpse if you want to be revived!", source = src)
do_help(H, user)
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H) //Our code here is different than tg, if it breaks in testing; BUG_PROBABLE_CAUSE
var/obj/item/organ/heart = H.getorgan(/obj/item/organ/heart)
if(H.suiciding || H.hellbound || HAS_TRAIT(H, TRAIT_HUSK))
return
if((world.time - H.timeofdeath) > tlimit)
return
if((H.getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (H.getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE))
return
if(!heart || (heart.organ_flags & ORGAN_FAILING))
return
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || H.suiciding)
return
return TRUE
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
if(req_defib)
if(defib.pullshocksafely && isliving(H.pulledby))
H.visible_message("<span class='danger'>The defibrillator safely discharges the excessive charge into the floor!</span>")
else
var/mob/living/M = H.pulledby
if(M.electrocute_act(30, src))
M.visible_message("<span class='danger'>[M] is electrocuted by [M.p_their()] contact with [H]!</span>")
M.emote("scream")
if(!H.pulledby || !isliving(H.pulledby))
return
if(req_defib && defib.pullshocksafely)
H.visible_message("<span class='danger'>The defibrillator safely discharges the excessive charge into the floor!</span>")
return
var/mob/living/M = H.pulledby
if(M.electrocute_act(30, src))
M.visible_message("<span class='danger'>[M] is electrocuted by [M.p_their()] contact with [H]!</span>")
M.emote("scream")
/obj/item/twohanded/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
if(req_defib && defib.safety)
@@ -473,7 +449,7 @@
M.visible_message("<span class='danger'>[user] zaps [M] with [src]!</span>", \
"<span class='userdanger'>[user] zaps [M] with [src]!</span>")
M.adjustStaminaLoss(50)
M.Knockdown(100)
M.DefaultCombatKnockdown(100)
M.updatehealth() //forces health update before next life tick
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
M.emote("gasp")
@@ -530,7 +506,7 @@
H.set_heartattack(TRUE)
H.apply_damage(50, BURN, BODY_ZONE_CHEST)
log_combat(user, H, "overloaded the heart of", defib)
H.Knockdown(100)
H.DefaultCombatKnockdown(100)
H.Jitter(100)
if(req_defib)
defib.deductcharge(revivecost)
@@ -744,22 +720,22 @@
name = "Defibrillator Healing Disk"
desc = "An upgrade which increases the healing power of the defibrillator"
icon_state = "heal_disk"
materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 6000, MAT_SILVER = 6000)
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 18000, /datum/material/gold = 6000, /datum/material/silver = 6000)
/obj/item/disk/medical/defib_shock
name = "Defibrillator Anti-Shock Disk"
desc = "A safety upgrade that guarantees only the patient will get shocked"
icon_state = "zap_disk"
materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 6000, MAT_SILVER = 6000)
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 18000, /datum/material/gold = 6000, /datum/material/silver = 6000)
/obj/item/disk/medical/defib_decay
name = "Defibrillator Body-Decay Extender Disk"
desc = "An upgrade allowing the defibrillator to work on more decayed bodies"
icon_state = "body_disk"
materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 16000, MAT_SILVER = 6000, MAT_TITANIUM = 2000)
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 18000, /datum/material/gold = 16000, /datum/material/silver = 6000, /datum/material/titanium = 2000)
/obj/item/disk/medical/defib_speed
name = "Defibrillator Fast Charge Disk"
desc = "An upgrade to the defibrillator capacitors, which let it charge faster"
icon_state = "fast_disk"
materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_GOLD = 26000, MAT_SILVER = 26000)
custom_materials = list(/datum/material/iron=16000, /datum/material/glass = 8000, /datum/material/gold = 26000, /datum/material/silver = 26000)
+1
View File
@@ -8,6 +8,7 @@
var/mob/owner = null //Carp doesn't attack owner, set when using in hand
var/owned = 0 //Boolean, no owner to begin with
var/mobtype = /mob/living/simple_animal/hostile/carp //So admins can change what mob spawns via var fuckery
can_random_spawn = FALSE
//Attack self
/obj/item/toy/plush/carpplushie/dehy_carp/attack_self(mob/user)
+99 -41
View File
@@ -1,4 +1,3 @@
//The advanced pea-green monochrome lcd of tomorrow.
GLOBAL_LIST_EMPTY(PDAs)
@@ -10,7 +9,6 @@ GLOBAL_LIST_EMPTY(PDAs)
#define PDA_SCANNER_HALOGEN 4
#define PDA_SCANNER_GAS 5
#define PDA_SPAM_DELAY 2 MINUTES
#define PDA_STANDARD_OVERLAYS list("pda-r", "blank", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay")
//pda icon overlays list defines
#define PDA_OVERLAY_ALERT 1
@@ -34,14 +32,19 @@ GLOBAL_LIST_EMPTY(PDAs)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
//Main variables
var/owner = null // String name of owner
var/default_cartridge = 0 // Access level defined by cartridge
var/obj/item/cartridge/cartridge = null //current cartridge
var/mode = 0 //Controls what menu the PDA will display. 0 is hub; the rest are either built in or based on cartridge.
var/list/overlays_icons = list('icons/obj/pda_alt.dmi' = list("pda-r", "screen_default", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay"))
var/current_overlays = PDA_STANDARD_OVERLAYS
var/static/list/standard_overlays_icons = list("pda-r", "blank", "id_overlay", "insert_overlay", "light_overlay", "pai_overlay")
var/list/current_overlays //set on Initialize.
//variables exclusively used on 'update_overlays' (which should never be called directly, and 'update_icon' doesn't use args anyway)
var/new_overlays = FALSE
var/new_alert = FALSE
var/font_index = 0 //This int tells DM which font is currently selected and lets DM know when the last font has been selected so that it can cycle back to the first font when "toggle font" is pressed again.
var/font_mode = "font-family:monospace;" //The currently selected font.
var/background_color = "#808000" //The currently selected background color.
@@ -77,6 +80,7 @@ GLOBAL_LIST_EMPTY(PDAs)
var/hidden = FALSE // Is the PDA hidden from the PDA list?
var/emped = FALSE
var/equipped = FALSE //used here to determine if this is the first time its been picked up
var/allow_emojis = TRUE //if the pda can send emojis and actually have them parsed as such
var/obj/item/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both.
var/ownjob = null //related to above
@@ -93,6 +97,8 @@ GLOBAL_LIST_EMPTY(PDAs)
var/underline_flag = TRUE //flag for underline
var/list/blocked_pdas
/obj/item/pda/suicide_act(mob/living/carbon/user)
var/deathMessage = msg_input(user)
if (!deathMessage)
@@ -121,7 +127,8 @@ GLOBAL_LIST_EMPTY(PDAs)
inserted_item = new inserted_item(src)
else
inserted_item = new /obj/item/pen(src)
update_icon(FALSE, TRUE)
new_overlays = TRUE
update_icon()
/obj/item/pda/CtrlShiftClick(mob/living/user)
. = ..()
@@ -142,7 +149,8 @@ GLOBAL_LIST_EMPTY(PDAs)
if(QDELETED(src) || isnull(new_icon) || new_icon == icon || !M.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
icon = new_icon
update_icon(FALSE, TRUE)
new_overlays = TRUE
update_icon()
to_chat(M, "[src] is now skinned as '[choice]'.")
/obj/item/pda/proc/set_new_overlays()
@@ -155,7 +163,7 @@ GLOBAL_LIST_EMPTY(PDAs)
overlays_x_offset = new_offsets[1]
overlays_y_offset = new_offsets[2]
if(!(icon in overlays_icons))
current_overlays = PDA_STANDARD_OVERLAYS
current_overlays = standard_overlays_icons
return
current_overlays = overlays_icons[icon]
@@ -186,7 +194,8 @@ GLOBAL_LIST_EMPTY(PDAs)
var/pref_skin = GLOB.pda_reskins[C.prefs.pda_skin]
if(icon != pref_skin)
icon = pref_skin
update_icon(FALSE, TRUE)
new_overlays = TRUE
update_icon()
equipped = TRUE
/obj/item/pda/proc/update_label()
@@ -213,25 +222,29 @@ GLOBAL_LIST_EMPTY(PDAs)
return TRUE
return FALSE
/obj/item/pda/update_icon(alert = FALSE, new_overlays = FALSE)
/obj/item/pda/update_overlays()
. = ..()
if(new_overlays)
set_new_overlays()
cut_overlays()
add_overlay(alert ? current_overlays[PDA_OVERLAY_ALERT] : current_overlays[PDA_OVERLAY_SCREEN])
var/mutable_appearance/overlay = new()
var/screen_state = new_alert ? current_overlays[PDA_OVERLAY_ALERT] : current_overlays[PDA_OVERLAY_SCREEN]
var/mutable_appearance/overlay = mutable_appearance(icon, screen_state)
overlay.pixel_x = overlays_x_offset
overlay.pixel_y = overlays_y_offset
. += new /mutable_appearance(overlay)
if(id)
overlay.icon_state = current_overlays[PDA_OVERLAY_ID]
add_overlay(new /mutable_appearance(overlay))
. += new /mutable_appearance(overlay)
if(inserted_item)
overlay.icon_state = current_overlays[PDA_OVERLAY_ITEM]
add_overlay(new /mutable_appearance(overlay))
. += new /mutable_appearance(overlay)
if(fon)
overlay.icon_state = current_overlays[PDA_OVERLAY_LIGHT]
add_overlay(new /mutable_appearance(overlay))
. += new /mutable_appearance(overlay)
if(pai)
overlay.icon_state = "[current_overlays[PDA_OVERLAY_PAI]][pai.pai ? "" : "_off"]"
add_overlay(new /mutable_appearance(overlay))
. += overlay
new_overlays = FALSE
new_alert = FALSE
/obj/item/pda/MouseDrop(mob/over, src_location, over_location)
var/mob/M = usr
@@ -253,10 +266,14 @@ GLOBAL_LIST_EMPTY(PDAs)
var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/simple/pda)
assets.send(user)
var/datum/asset/spritesheet/emoji_s = get_asset_datum(/datum/asset/spritesheet/goonchat)
emoji_s.send(user) //Already sent by chat but no harm doing this
user.set_machine(src)
var/dat = "<!DOCTYPE html><html><head><title>Personal Data Assistant</title><link href=\"https://fonts.googleapis.com/css?family=Orbitron|Share+Tech+Mono|VT323\" rel=\"stylesheet\"></head><body bgcolor=\"" + background_color + "\"><style>body{" + font_mode + "}ul,ol{list-style-type: none;}a, a:link, a:visited, a:active, a:hover { color: #000000;text-decoration:none; }img {border-style:none;}a img{padding-right: 9px;}</style>"
var/dat = "<!DOCTYPE html><html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Personal Data Assistant</title><link href=\"https://fonts.googleapis.com/css?family=Orbitron|Share+Tech+Mono|VT323\" rel=\"stylesheet\"></head><body bgcolor=\"" + background_color + "\"><style>body{" + font_mode + "}ul,ol{list-style-type: none;}a, a:link, a:visited, a:active, a:hover { color: #000000;text-decoration:none; }img {border-style:none;}a img{padding-right: 9px;}</style>"
dat += assets.css_tag()
dat += emoji_s.css_tag()
dat += "<a href='byond://?src=[REF(src)];choice=Refresh'>[PDAIMG(refresh)]Refresh</a>"
@@ -286,7 +303,7 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += text("ID: <a href='?src=[REF(src)];choice=Authenticate'>[id ? "[id.registered_name], [id.assignment]" : "----------"]")
dat += text("<br><a href='?src=[REF(src)];choice=UpdateInfo'>[id ? "Update PDA Info" : ""]</A><br><br>")
dat += "[STATION_TIME_TIMESTAMP("hh:mm:ss")]<br>" //:[world.time / 100 % 6][world.time / 100 % 10]"
dat += "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]<br>" //:[world.time / 100 % 6][world.time / 100 % 10]"
dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer]"
dat += "<br><br>"
@@ -336,6 +353,8 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "<li><a href='byond://?src=[REF(src)];choice=54'>[PDAIMG(medbot)]Bots Access</a></li>"
if (cartridge.access & CART_JANITOR)
dat += "<li><a href='byond://?src=[REF(src)];choice=49'>[PDAIMG(bucket)]Custodial Locator</a></li>"
if(cartridge.access & CART_MIME)
dat += "<li><a href='byond://?src=[REF(src)];choice=55'>[PDAIMG(emoji)]Emoji Guidebook</a></li>"
if (istype(cartridge.radio))
dat += "<li><a href='byond://?src=[REF(src)];choice=40'>[PDAIMG(signaler)]Signaler System</a></li>"
if (cartridge.access & CART_NEWSCASTER)
@@ -387,7 +406,10 @@ GLOBAL_LIST_EMPTY(PDAs)
for (var/obj/item/pda/P in sortNames(get_viewable_pdas()))
if (P == src)
continue
dat += "<li><a href='byond://?src=[REF(src)];choice=Message;target=[REF(P)]'>[P]</a>"
if(P.owner in blocked_pdas)
dat += "<li><a href='byond://?src=[REF(src)];choice=unblock_pda;target=[P.owner]'>(BLOCKED - CLICK TO UNBLOCK) [P]</a>"
else
dat += "<li><a href='byond://?src=[REF(src)];choice=Message;target=[REF(P)]'>[P]</a>"
if(cartridge)
dat += cartridge.message_special(P)
dat += "</li>"
@@ -448,7 +470,7 @@ GLOBAL_LIST_EMPTY(PDAs)
var/mob/living/U = usr
//Looking for master was kind of pointless since PDAs don't appear to have one.
if(usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && !href_list["close"])
if(usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK, FALSE) && !href_list["close"])
add_fingerprint(U)
U.set_machine(src)
@@ -630,13 +652,13 @@ GLOBAL_LIST_EMPTY(PDAs)
if("Clear")//Clears messages
tnote = null
if("Ringtone")
var/t = input(U, "Please enter new ringtone", name, ttone) as text
var/t = stripped_input(U, "Please enter new ringtone", name, ttone, 20)
if(in_range(src, U) && loc == U && t)
if(SEND_SIGNAL(src, COMSIG_PDA_CHANGE_RINGTONE, U, t) & COMPONENT_STOP_RINGTONE_CHANGE)
U << browse(null, "window=pda")
return
else
ttone = copytext(sanitize(t), 1, 20)
ttone = t
else
U << browse(null, "window=pda")
return
@@ -646,6 +668,15 @@ GLOBAL_LIST_EMPTY(PDAs)
if("MessageAll")
send_to_all(U)
if("toggle_block")
toggle_blocking(usr, href_list["target"])
if("block_pda")
block_pda(usr, href_list["target"])
if("unblock_pda")
unblock_pda(usr, href_list["target"])
if("cart")
if(cartridge)
cartridge.special(U, href_list)
@@ -701,7 +732,7 @@ GLOBAL_LIST_EMPTY(PDAs)
return
/obj/item/pda/proc/remove_id(mob/user)
if(issilicon(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
if(hasSiliconAccessInArea(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
do_remove_id(user)
@@ -727,7 +758,7 @@ GLOBAL_LIST_EMPTY(PDAs)
var/t = stripped_input(U, "Please enter message", name)
if (!t || toff)
return
if(!U.canUseTopic(src, BE_CLOSE))
if(!U.canUseTopic(src, BE_CLOSE, FALSE, NO_TK, FALSE))
return
if(emped)
t = Gibberish(t, 100)
@@ -739,14 +770,20 @@ GLOBAL_LIST_EMPTY(PDAs)
return
if((last_text && world.time < last_text + 10) || (everyone && last_everyone && world.time < last_everyone + PDA_SPAM_DELAY))
return
var/emoji_message = emoji_parse(message)
if(prob(1))
message += "\nSent from my PDA"
// Send the signal
var/list/string_targets = list()
for (var/obj/item/pda/P in targets)
if (P.owner && P.ownjob) // != src is checked by the UI
var/list/string_blocked
for(var/obj/item/pda/P in targets)
if(owner in P.blocked_pdas)
LAZYADD(string_blocked, P.owner)
continue
if(P.owner && P.ownjob) // != src is checked by the UI
string_targets += "[P.owner] ([P.ownjob])"
if(string_blocked)
string_blocked = english_list(string_blocked)
to_chat(user, "<span class='warning'>[icon2html(src, user)] The following recipients have blocked your message: [string_blocked].</span>")
for (var/obj/machinery/computer/message_monitor/M in targets)
// In case of "Reply" to a message from a console, this will make the
// message be logged successfully. If the console is impersonating
@@ -761,7 +798,7 @@ GLOBAL_LIST_EMPTY(PDAs)
"job" = "[ownjob]",
"message" = message,
"targets" = string_targets,
"emoji_message" = emoji_message
"emojis" = allow_emojis
))
if (picture)
signal.data["photo"] = picture
@@ -775,16 +812,20 @@ GLOBAL_LIST_EMPTY(PDAs)
playsound(src, 'sound/machines/terminal_error.ogg', 15, 1)
var/target_text = signal.format_target()
if(allow_emojis)
message = emoji_parse(message)//already sent- this just shows the sent emoji as one to the sender in the to_chat
signal.data["message"] = emoji_parse(signal.data["message"])
// Log it in our logs
tnote += "<i><b>&rarr; To [target_text]:</b></i><br>[signal.format_message()]<br>"
// Show it to ghosts
var/ghost_message = "<span class='name'>[owner] </span><span class='game say'>PDA Message</span> --> <span class='name'>[target_text]</span>: <span class='message'>[signal.format_message(TRUE)]</span>"
for(var/mob/M in GLOB.player_list)
if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTPDA))
var/ghost_message = "<span class='name'>[owner] </span><span class='game say'>PDA Message</span> --> <span class='name'>[target_text]</span>: <span class='message'>[signal.format_message()]</span>"
for(var/i in GLOB.dead_mob_list)
var/mob/M = i
if(M?.client && M.client.prefs.chat_toggles & CHAT_GHOSTPDA)
to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]")
to_chat(user, "<span class='info'>Message sent to [target_text]: \"[message]\"</span>")
// Log in the talk log
user.log_talk(message, LOG_PDA, tag="PDA: [initial(name)] to [target_text]")
to_chat(user, "<span class='info'>Message sent to [target_text]: \"[emoji_message]\"</span>")
user.log_talk(message, LOG_PDA, tag="PDA: [initial(name)] to [target_text] (BLOCKED:[string_blocked])")
if (!silent)
playsound(src, 'sound/machines/terminal_success.ogg', 15, 1)
// Reset the photo
@@ -794,8 +835,7 @@ GLOBAL_LIST_EMPTY(PDAs)
last_everyone = world.time
/obj/item/pda/proc/receive_message(datum/signal/subspace/pda/signal)
tnote += "<i><b>&larr; From <a href='byond://?src=[REF(src)];choice=Message;target=[REF(signal.source)]'>[signal.data["name"]]</a> ([signal.data["job"]]):</b></i><br>[signal.format_message()]<br>"
tnote += "<i><b>&larr; From <a href='byond://?src=[REF(src)];choice=Message;target=[REF(signal.source)]'>[signal.data["name"]]</a> ([signal.data["job"]]):</b></i> <a href='byond://?src=[REF(src)];choice=toggle_block;target=[signal.data["name"]]'>(BLOCK/UNBLOCK)</a><br>[signal.format_message()]<br>"
if (!silent)
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
audible_message("[icon2html(src, hearers(src))] *[ttone]*", null, 3)
@@ -814,8 +854,13 @@ GLOBAL_LIST_EMPTY(PDAs)
hrefstart = "<a href='?src=[REF(L)];track=[html_encode(signal.data["name"])]'>"
hrefend = "</a>"
to_chat(L, "[icon2html(src)] <b>Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[signal.format_message(TRUE)] (<a href='byond://?src=[REF(src)];choice=Message;skiprefresh=1;target=[REF(signal.source)]'>Reply</a>)")
var/inbound_message = signal.format_message()
if(signal.data["emojis"] == TRUE)//so will not parse emojis as such from pdas that don't send emojis
inbound_message = emoji_parse(inbound_message)
to_chat(L, "[icon2html(src)] <b>Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[inbound_message] (<a href='byond://?src=[REF(src)];choice=Message;skiprefresh=1;target=[REF(signal.source)]'>Reply</a>) (<a href='byond://?src=[REF(src)];choice=toggle_block;target=[signal.data["name"]]'>BLOCK/UNBLOCK</a>)")
new_alert = TRUE
update_icon(TRUE)
/obj/item/pda/proc/send_to_all(mob/living/U)
@@ -827,6 +872,20 @@ GLOBAL_LIST_EMPTY(PDAs)
/obj/item/pda/proc/create_message(mob/living/U, obj/item/pda/P)
send_message(U,list(P))
/obj/item/pda/proc/toggle_blocking(mob/user, target)
if(target in blocked_pdas)
unblock_pda(user, target)
else
block_pda(user, target)
/obj/item/pda/proc/block_pda(mob/user, target)
to_chat(user, "<span class='notice'>[icon2html(src, user)] [target] blocked from messages. Use the messenger PDA list to unblock.</span>")
LAZYOR(blocked_pdas, target)
/obj/item/pda/proc/unblock_pda(mob/user, target)
to_chat(user, "<span class='notice'>[icon2html(src, user)] [target] unblocked from messages.</span>")
LAZYREMOVE(blocked_pdas, target)
/obj/item/pda/AltClick(mob/user)
. = ..()
if(id)
@@ -869,7 +928,7 @@ GLOBAL_LIST_EMPTY(PDAs)
remove_pen()
/obj/item/pda/proc/toggle_light()
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE))
if(hasSiliconAccessInArea(usr) || !usr.canUseTopic(src, BE_CLOSE))
return
if(fon)
fon = FALSE
@@ -881,7 +940,7 @@ GLOBAL_LIST_EMPTY(PDAs)
/obj/item/pda/proc/remove_pen()
if(issilicon(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
if(hasSiliconAccessInArea(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if(inserted_item)
@@ -1133,7 +1192,7 @@ GLOBAL_LIST_EMPTY(PDAs)
if(incapacitated())
return
if(!isnull(aiPDA))
var/HTML = "<html><head><title>AI PDA Message Log</title></head><body>[aiPDA.tnote]</body></html>"
var/HTML = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>AI PDA Message Log</title></head><body>[aiPDA.tnote]</body></html>"
user << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
else
to_chat(user, "You do not have a PDA. You should make an issue report about this.")
@@ -1165,11 +1224,10 @@ GLOBAL_LIST_EMPTY(PDAs)
#undef PDA_SCANNER_HALOGEN
#undef PDA_SCANNER_GAS
#undef PDA_SPAM_DELAY
#undef PDA_STANDARD_OVERLAYS
#undef PDA_OVERLAY_ALERT
#undef PDA_OVERLAY_SCREEN
#undef PDA_OVERLAY_ID
#undef PDA_OVERLAY_ITEM
#undef PDA_OVERLAY_LIGHT
#undef PDA_OVERLAY_PAI
#undef PDA_OVERLAY_PAI
@@ -19,6 +19,26 @@
if(istype(cart) && cart.charges < 5)
cart.charges++
//Mime PDA sends "silent" messages.
/obj/item/pda/mime
name = "mime PDA"
default_cartridge = /obj/item/cartridge/virus/mime
inserted_item = /obj/item/toy/crayon/mime
icon_state = "pda-mime"
desc = "A portable microcomputer by Thinktronic Systems, LTD. The hardware has been modified for compliance with the vows of silence."
silent = TRUE
ttone = "silence"
/obj/item/pda/mime/msg_input(mob/living/U = usr)
if(emped || toff)
return
var/emojis = emoji_sanitize(stripped_input(U, "Please enter emojis", name))
if(!emojis)
return
if(!U.canUseTopic(src, BE_CLOSE))
return
return emojis
// Special AI/pAI PDAs that cannot explode.
/obj/item/pda/ai
icon = null
@@ -79,14 +99,6 @@
icon_state = "pda-science"
ttone = "boom"
/obj/item/pda/mime
name = "mime PDA"
default_cartridge = /obj/item/cartridge/virus/mime
inserted_item = /obj/item/toy/crayon/mime
icon_state = "pda-mime"
silent = TRUE
ttone = "silence"
/obj/item/pda/heads
default_cartridge = /obj/item/cartridge/head
icon_state = "pda-hop"
@@ -181,8 +193,6 @@
/obj/item/pda/curator
name = "curator PDA"
icon_state = "pda-library"
overlays_icons = list('icons/obj/pda.dmi' = list("pda-r-library","blank","id_overlay","insert_overlay", "light_overlay", "pai_overlay"),
'icons/obj/pda_alt.dmi' = list("pda-r","screen_default","id_overlay","insert_overlay", "light_overlay", "pai_overlay"))
current_overlays = list("pda-r-library","blank","id_overlay","insert_overlay", "light_overlay", "pai_overlay")
default_cartridge = /obj/item/cartridge/curator
inserted_item = /obj/item/pen/fountain
+39 -12
View File
@@ -100,7 +100,8 @@
bot_access_flags = CLEAN_BOT
/obj/item/cartridge/lawyer
name = "\improper P.R.O.V.E. cartridge"
name = "\improper S.P.A.M. cartridge"
desc = "Introducing the Station Public Announcement Messenger cartridge, featuring the unique ability to broadcast-mark messages, designed for lawyers across Nanotrasen to advertise their useful and important services."
icon_state = "cart-law"
access = CART_SECURITY
spam_enabled = 1
@@ -309,9 +310,14 @@ Code:
var/list/S = list(" Off","AOff"," On", " AOn")
var/list/chg = list("N","C","F")
//Neither copytext nor copytext_char is appropriate here; neither 30 UTF-8 code units nor 30 code points equates to 30 columns of output.
//Some glyphs are very tall or very wide while others are small or even take up no space at all.
//Emojis can take modifiers which are many characters but render as only one glyph.
//A proper solution here (as far as Unicode goes, maybe not ideal as far as markup goes, a table would be better)
//would be to use <span style="width: NNNpx; overflow: none;">[A.area.name]</span>
for(var/obj/machinery/power/apc/A in L)
menu += copytext(add_tspace(A.area.name, 30), 1, 30)
menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_lspace(DisplayPower(A.lastused_total), 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]<BR>"
menu += copytext_char(add_trailing(A.area.name, 30, " "), 1, 30)
menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_leading(DisplayPower(A.lastused_total), 6, " ")] [A.cell ? "[add_leading(round(A.cell.percent()), 3, " ")]% [chg[A.charging+1]]" : " N/C"]<BR>"
menu += "</FONT></PRE>"
@@ -326,7 +332,7 @@ Code:
if(active1 in GLOB.data_core.general)
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
menu += "Sex: [active1.fields["sex"]]<br>"
menu += "Sex: [active1.fields["gender"]]<br>"
menu += "Age: [active1.fields["age"]]<br>"
menu += "Rank: [active1.fields["rank"]]<br>"
menu += "Fingerprint: [active1.fields["fingerprint"]]<br>"
@@ -370,7 +376,7 @@ Code:
if(active1 in GLOB.data_core.general)
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
menu += "Sex: [active1.fields["sex"]]<br>"
menu += "Sex: [active1.fields["gender"]]<br>"
menu += "Age: [active1.fields["age"]]<br>"
menu += "Rank: [active1.fields["rank"]]<br>"
menu += "Fingerprint: [active1.fields["fingerprint"]]<br>"
@@ -557,28 +563,44 @@ Code:
if (53) // Newscaster
menu = "<h4>[PDAIMG(notes)] Newscaster Access</h4>"
menu += "<br> Current Newsfeed: <A href='byond://?src=[REF(src)];choice=Newscaster Switch Channel'>[current_channel ? current_channel : "None"]</a> <br>"
var/datum/newscaster/feed_channel/current
for(var/datum/newscaster/feed_channel/chan in GLOB.news_network.network_channels)
var/datum/news/feed_channel/current
for(var/datum/news/feed_channel/chan in GLOB.news_network.network_channels)
if (chan.channel_name == current_channel)
current = chan
if(!current)
menu += "<h5> ERROR : NO CHANNEL FOUND </h5>"
return
var/i = 1
for(var/datum/newscaster/feed_message/msg in current.messages)
for(var/datum/news/feed_message/msg in current.messages)
menu +="-[msg.returnBody(-1)] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[msg.returnAuthor(-1)]</FONT>\]</FONT><BR>"
menu +="<b><font size=1>[msg.comments.len] comment[msg.comments.len > 1 ? "s" : ""]</font></b><br>"
if(msg.img)
user << browse_rsc(msg.img, "tmp_photo[i].png")
menu +="<img src='tmp_photo[i].png' width = '180'><BR>"
i++
for(var/datum/newscaster/feed_comment/comment in msg.comments)
for(var/datum/news/feed_comment/comment in msg.comments)
menu +="<font size=1><small>[comment.body]</font><br><font size=1><small><small><small>[comment.author] [comment.time_stamp]</small></small></small></small></font><br>"
menu += "<br> <A href='byond://?src=[REF(src)];choice=Newscaster Message'>Post Message</a>"
if (54) // Beepsky, Medibot, Floorbot, and Cleanbot access
menu = "<h4>[PDAIMG(medbot)] Bots Interlink</h4>"
bot_control()
if (55) // Emoji Guidebook for mimes
menu = "<h4>[PDAIMG(emoji)] Emoji Guidebook</h4>"
var/static/list/emoji_icon_states
var/static/emoji_table
if(!emoji_table)
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat)
var/list/collate = list("<br><table>")
for(var/emoji in sortList(icon_states(icon('icons/emoji.dmi'))))
var/tag = sheet.icon_tag("emoji-[emoji]")
collate += "<tr><td>[emoji]</td><td>[tag]</td></tr>"
collate += "</table><br>"
emoji_table = collate.Join()
menu += "<br> To use an emoji in a pda message, refer to the guide and add \":\" around the emoji. Your PDA supports the following emoji:<br>"
menu += emoji_table
if (99) //Newscaster message permission error
menu = "<h5> ERROR : NOT AUTHORIZED [host_pda.id ? "" : "- ID SLOT EMPTY"] </h5>"
@@ -587,7 +609,7 @@ Code:
/obj/item/cartridge/Topic(href, href_list)
..()
if(!usr.canUseTopic(src, !issilicon(usr)))
if(!usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
usr.unset_machine()
usr << browse(null, "window=pda")
return
@@ -660,8 +682,8 @@ Code:
if("Newscaster Message")
var/host_pda_owner_name = host_pda.id ? "[host_pda.id.registered_name] ([host_pda.id.assignment])" : "Unknown"
var/message = host_pda.msg_input()
var/datum/newscaster/feed_channel/current
for(var/datum/newscaster/feed_channel/chan in GLOB.news_network.network_channels)
var/datum/news/feed_channel/current
for(var/datum/news/feed_channel/chan in GLOB.news_network.network_channels)
if (chan.channel_name == current_channel)
current = chan
if(current.locked && current.author != host_pda_owner_name)
@@ -679,6 +701,11 @@ Code:
return
playsound(src, 'sound/machines/terminal_select.ogg', 50, 1)
//emoji previews
if(href_list["emoji"])
var/parse = emoji_parse(":[href_list["emoji"]]:")
to_chat(usr, parse)
//Bot control section! Viciously ripped from radios for being laggy and terrible.
if(href_list["op"])
switch(href_list["op"])
@@ -21,7 +21,7 @@
var/obj/item/cigbutt/butt = /obj/item/cigbutt
saved_appearance = initial(butt.appearance)
/obj/item/chameleon/dropped()
/obj/item/chameleon/dropped(mob/user)
..()
disrupt()
@@ -49,6 +49,10 @@
return
if(istype(target, /obj/structure/falsewall))
return
if(target.alpha != 255)
return
if(target.invisibility != 0)
return
if(iseffect(target))
if(!(istype(target, /obj/effect/decal))) //be a footprint
return
@@ -146,7 +150,7 @@
master.disrupt()
/obj/effect/dummy/chameleon/bullet_act()
..()
. = ..()
master.disrupt()
/obj/effect/dummy/chameleon/relaymove(mob/user, direction)
@@ -46,7 +46,7 @@
var/list/organs = M.getorganszone("head") + M.getorganszone("eyes") + M.getorganszone("mouth")
for(var/internal_organ in organs)
var/obj/item/organ/I = internal_organ
I.Remove(M)
I.Remove()
I.forceMove(T)
head.drop_limb()
qdel(head)
@@ -89,25 +89,6 @@
else
to_chat(user, "<span class='notice'>Anomalous error. Summon a coder.</span>")
else if(ishuman(target) && user.zone_selected == BODY_ZONE_PRECISE_GROIN)
var/mob/living/carbon/human/H = target
var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
if(!P)
return
playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1)
H.visible_message("<span class='warning'>[user] is preparing to shrink [H]\'s [P.name] with their bluespace compression kit!</span>")
if(do_mob(user, H, 40) && charges > 0 && P.length > 0)
H.visible_message("<span class='warning'>[user] has shrunk [H]\'s [P.name]!</span>")
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1)
sparks()
flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN)
charges -= 1
var/p_name = P.name
P.modify_size(-5)
if(QDELETED(P))
H.visible_message("<span class='warning'>[H]\'s [p_name] vanishes!</span>")
/obj/item/compressionkit/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/ore/bluespace_crystal))
@@ -117,4 +98,4 @@
if(B.amount > 1)
B.amount -= 1
else
qdel(I)
qdel(I)
@@ -8,12 +8,13 @@
item_flags = NOBLUDGEON
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
materials = list(MAT_METAL = 250, MAT_GLASS = 500)
custom_materials = list(/datum/material/iron = 250, /datum/material/glass = 500)
var/max_duration = 3000
var/duration = 300
var/last_use = 0
var/next_use = 0
var/obj/effect/abstract/sync_holder/sync_holder
var/resync_timer
/obj/item/desynchronizer/attack_self(mob/living/user)
if(world.time < next_use)
@@ -56,16 +57,20 @@
SEND_SIGNAL(AM, COMSIG_MOVABLE_SECLUDED_LOCATION)
last_use = world.time
icon_state = "desynchronizer-on"
addtimer(CALLBACK(src, .proc/resync), duration)
resync_timer = addtimer(CALLBACK(src, .proc/resync), duration , TIMER_STOPPABLE)
/obj/item/desynchronizer/proc/resync()
new /obj/effect/temp_visual/desynchronizer(sync_holder.drop_location())
QDEL_NULL(sync_holder)
if(resync_timer)
deltimer(resync_timer)
resync_timer = null
icon_state = initial(icon_state)
next_use = world.time + (world.time - last_use) // Could be 2*world.time-last_use but that would just be confusing
/obj/item/desynchronizer/Destroy()
resync()
if(sync_holder)
resync()
return ..()
/obj/effect/abstract/sync_holder
@@ -12,7 +12,7 @@
item_flags = NOBLUDGEON
force = 3
attack_verb = list("blown up", "exploded", "detonated")
materials = list(MAT_METAL=50, MAT_GLASS=30)
custom_materials = list(/datum/material/iron=50, /datum/material/glass=30)
/obj/item/doorCharge/ex_act(severity, target)
switch(severity)
@@ -5,7 +5,7 @@
icon = 'icons/obj/module.dmi'
icon_state = "boris"
w_class = WEIGHT_CLASS_TINY
materials = list(MAT_METAL = 50, MAT_GLASS = 300)
custom_materials = list(/datum/material/iron = 50, /datum/material/glass = 300)
var/recharging = FALSE
var/circuits = 5 //How many circuits the pseudocircuit has left
var/static/recycleable_circuits = typecacheof(list(/obj/item/electronics/firelock, /obj/item/electronics/airalarm, /obj/item/electronics/firealarm, \
+16 -19
View File
@@ -9,7 +9,7 @@
w_class = WEIGHT_CLASS_SMALL
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
materials = list(MAT_METAL=50, MAT_GLASS=20)
custom_materials = list(/datum/material/iron=50, /datum/material/glass=20)
actions_types = list(/datum/action/item_action/toggle_light)
var/on = FALSE
var/brightness_on = 4 //range of light when on
@@ -51,7 +51,7 @@
/obj/item/flashlight/attack(mob/living/carbon/M, mob/living/carbon/human/user)
add_fingerprint(user)
if(istype(M) && on && user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH))
if(istype(M) && on && (user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH)))
if((HAS_TRAIT(user, TRAIT_CLUMSY) || HAS_TRAIT(user, TRAIT_DUMB)) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
@@ -170,7 +170,7 @@
flags_1 = CONDUCT_1
brightness_on = 2
light_color = "#FFDDCC"
flashlight_power = 0.3
flashlight_power = 0.5
var/holo_cooldown = 0
/obj/item/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag)
@@ -224,18 +224,15 @@
light_color = "#FFDDBB"
w_class = WEIGHT_CLASS_BULKY
flags_1 = CONDUCT_1
materials = list()
custom_materials = null
on = TRUE
// green-shaded desk lamp
/obj/item/flashlight/lamp/green
desc = "A classic green-shaded desk lamp."
icon_state = "lampgreen"
item_state = "lampgreen"
/obj/item/flashlight/lamp/verb/toggle_light()
set name = "Toggle light"
set category = "Object"
@@ -258,12 +255,13 @@
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
w_class = WEIGHT_CLASS_SMALL
brightness_on = 7 // Pretty bright.
total_mass = 0.8
light_color = "#FA421A"
icon_state = "flare"
item_state = "flare"
actions_types = list()
var/fuel = 0
var/on_damage = 7
var/on_damage = 9
var/produce_heat = 1500
heat = 1000
light_color = LIGHT_COLOR_FLARE
@@ -331,14 +329,15 @@
name = "torch"
desc = "A torch fashioned from some leaves and a log."
w_class = WEIGHT_CLASS_BULKY
brightness_on = 4
brightness_on = 6 //When on were like a lantern
light_color = "#FAA44B"
icon_state = "torch"
item_state = "torch"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
light_color = LIGHT_COLOR_ORANGE
on_damage = 10
total_mass = TOTAL_MASS_NORMAL_ITEM
on_damage = 12 //Its a log thats on fire
slot_flags = null
/obj/item/flashlight/lantern
@@ -348,10 +347,9 @@
lefthand_file = 'icons/mob/inhands/equipment/mining_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi'
desc = "A mining lantern."
brightness_on = 6 // luminosity when on
brightness_on = 6 // luminosity when on
light_color = "#FFAA44"
flashlight_power = 0.75
flashlight_power = 0.8
/obj/item/flashlight/slime
gender = PLURAL
@@ -362,7 +360,7 @@
item_state = "slime"
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
materials = list()
custom_materials = null
brightness_on = 6 //luminosity when on
light_color = "#FFEEAA"
flashlight_power = 0.6
@@ -372,7 +370,6 @@
var/emp_cur_charges = 4
var/charge_tick = 0
/obj/item/flashlight/emp/New()
..()
START_PROCESSING(SSobj, src)
@@ -390,7 +387,7 @@
return TRUE
/obj/item/flashlight/emp/attack(mob/living/M, mob/living/user)
if(on && user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH)) // call original attack when examining organs
if(on && (user.zone_selected in list(BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH))) // call original attack when examining organs
..()
return
@@ -435,7 +432,7 @@
var/fuel = 0
/obj/item/flashlight/glowstick/Initialize()
fuel = rand(1600, 2000)
fuel = rand(1000, 1500)
light_color = color
. = ..()
@@ -454,7 +451,7 @@
on = FALSE
update_icon()
/obj/item/flashlight/glowstick/update_icon()
/obj/item/flashlight/glowstick/update_icon_state()
item_state = "glowstick"
cut_overlays()
if(!fuel)
@@ -540,7 +537,7 @@
/obj/item/flashlight/eyelight
name = "eyelight"
desc = "This shouldn't exist outside of someone's head, how are you seeing this?"
brightness_on = 15
brightness_on = 10
flags_1 = CONDUCT_1
item_flags = DROPDEL
actions_types = list()
@@ -1,6 +1,6 @@
/obj/item/forcefield_projector
name = "forcefield projector"
desc = "An experimental device that can create several forcefields at a distance."
desc = "An experimental device that can create several forcefields at a short distance."
icon = 'icons/obj/device.dmi'
icon_state = "signmaker_forcefield"
slot_flags = ITEM_SLOT_BELT
@@ -9,12 +9,12 @@
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
materials = list(MAT_METAL=250, MAT_GLASS=500)
custom_materials = list(/datum/material/iron=250, /datum/material/glass=500)
var/max_shield_integrity = 100
var/shield_integrity = 250
var/max_fields = 3
var/list/current_fields
var/field_distance_limit = 7
var/field_distance_limit = 2
/obj/item/forcefield_projector/afterattack(atom/target, mob/user, proximity_flag)
. = ..()
@@ -18,7 +18,7 @@
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
materials = list(MAT_METAL = 150, MAT_GLASS = 150)
custom_materials = list(/datum/material/iron = 150, /datum/material/glass = 150)
var/grace = RAD_GRACE_PERIOD
var/datum/looping_sound/geiger/soundloop
@@ -38,6 +38,7 @@
/obj/item/geiger_counter/Destroy()
STOP_PROCESSING(SSobj, src)
QDEL_NULL(soundloop)
return ..()
/obj/item/geiger_counter/process()
@@ -86,27 +87,25 @@
. += "<span class='notice'>The last radiation amount detected was [last_tick_amount]</span>"
/obj/item/geiger_counter/update_icon()
/obj/item/geiger_counter/update_icon_state()
if(!scanning)
icon_state = "geiger_off"
return 1
if(obj_flags & EMAGGED)
else if(obj_flags & EMAGGED)
icon_state = "geiger_on_emag"
return 1
switch(radiation_count)
if(-INFINITY to RAD_LEVEL_NORMAL)
icon_state = "geiger_on_1"
if(RAD_LEVEL_NORMAL + 1 to RAD_LEVEL_MODERATE)
icon_state = "geiger_on_2"
if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH)
icon_state = "geiger_on_3"
if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH)
icon_state = "geiger_on_4"
if(RAD_LEVEL_VERY_HIGH + 1 to RAD_LEVEL_CRITICAL)
icon_state = "geiger_on_4"
if(RAD_LEVEL_CRITICAL + 1 to INFINITY)
icon_state = "geiger_on_5"
..()
else
switch(radiation_count)
if(-INFINITY to RAD_LEVEL_NORMAL)
icon_state = "geiger_on_1"
if(RAD_LEVEL_NORMAL + 1 to RAD_LEVEL_MODERATE)
icon_state = "geiger_on_2"
if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH)
icon_state = "geiger_on_3"
if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH)
icon_state = "geiger_on_4"
if(RAD_LEVEL_VERY_HIGH + 1 to RAD_LEVEL_CRITICAL)
icon_state = "geiger_on_4"
if(RAD_LEVEL_CRITICAL + 1 to INFINITY)
icon_state = "geiger_on_5"
/obj/item/geiger_counter/proc/update_sound()
var/datum/looping_sound/geiger/loop = soundloop
@@ -219,7 +218,7 @@
/obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount)
rad_act(amount)
/obj/item/geiger_counter/cyborg/dropped()
/obj/item/geiger_counter/cyborg/dropped(mob/user)
. = ..()
if(listeningTo)
UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT)
+7 -9
View File
@@ -73,8 +73,10 @@ GLOBAL_LIST_EMPTY(GPS_list)
return
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show
ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height
// Variable window height, depending on how many GPS units there are
// to show, clamped to relatively safe range.
var/gps_window_height = CLAMP(325 + GLOB.GPS_list.len * 14, 325, 700)
ui = new(user, src, ui_key, "gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height
ui.open()
ui.set_autoupdate(state = updating)
@@ -91,6 +93,8 @@ GLOBAL_LIST_EMPTY(GPS_list)
var/turf/curr = get_turf(src)
data["current"] = "[get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
data["currentArea"] = "[get_area_name(curr, TRUE)]"
data["currentCoords"] = "[curr.x], [curr.y], [curr.z]"
var/list/signals = list()
data["signals"] = list()
@@ -104,16 +108,10 @@ GLOBAL_LIST_EMPTY(GPS_list)
continue
var/list/signal = list()
signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
signal["area"] = get_area_name(G, TRUE)
signal["coord"] = "[pos.x], [pos.y], [pos.z]"
signal["coords"] = "[pos.x], [pos.y], [pos.z]"
if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful.
if(!direction)
direction = "CENTER"
signal["degrees"] = "N/A"
signal["direction"] = direction
signals += list(signal) //Add this signal to the list of signals
data["signals"] = signals
@@ -108,6 +108,12 @@
song.instrumentDir = name
song.instrumentExt = insTypes[name]
/obj/item/instrument/piano_synth/proc/selectInstrument() // Moved here so it can be used by the action and PAI software panel without copypasta
var/chosen = input("Choose the type of instrument you want to use", "Instrument Selection", song.instrumentDir) as null|anything in insTypes
if(!insTypes[chosen])
return
return changeInstrument(chosen)
/obj/item/instrument/banjo
name = "banjo"
desc = "A 'Mura' brand banjo. It's pretty much just a drum with a neck and strings."
@@ -283,3 +289,29 @@
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
/obj/item/choice_beacon/music
name = "instrument delivery beacon"
desc = "Summon your tool of art."
icon_state = "gangtool-red"
/obj/item/choice_beacon/music/generate_display_names()
var/static/list/instruments
if(!instruments)
instruments = list()
var/list/templist = list(/obj/item/instrument/violin,
/obj/item/instrument/piano_synth,
/obj/item/instrument/guitar,
/obj/item/instrument/eguitar,
/obj/item/instrument/glockenspiel,
/obj/item/instrument/accordion,
/obj/item/instrument/trumpet,
/obj/item/instrument/saxophone,
/obj/item/instrument/trombone,
/obj/item/instrument/recorder,
/obj/item/instrument/harmonica
)
for(var/V in templist)
var/atom/A = V
instruments[initial(A.name)] = A
return instruments
@@ -8,7 +8,7 @@
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
materials = list(MAT_METAL=500, MAT_GLASS=500)
custom_materials = list(/datum/material/iron=500, /datum/material/glass=500)
w_class = WEIGHT_CLASS_SMALL
var/turf/pointer_loc
var/energy = 5
@@ -56,6 +56,14 @@
else
return ..()
/obj/item/laser_pointer/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
if(!diode)
. += "<span class='notice'>The diode is missing.<span>"
else
. += "<span class='notice'>A class <b>[diode.rating]</b> laser diode is installed. It is <i>screwed</i> in place.<span>"
/obj/item/laser_pointer/afterattack(atom/target, mob/living/user, flag, params)
. = ..()
laser_act(target, user, params)
@@ -108,7 +116,7 @@
//chance to actually hit the eyes depends on internal component
if(prob(effectchance * diode.rating))
S.flash_act(affect_silicon = 1)
S.Knockdown(rand(100,200))
S.DefaultCombatKnockdown(rand(100,200))
to_chat(S, "<span class='danger'>Your sensors were overloaded by a laser!</span>")
outmsg = "<span class='notice'>You overload [S] by shining [src] at [S.p_their()] sensors.</span>"
else
@@ -144,8 +152,7 @@
if(prob(50))
C.visible_message("<span class='notice'>[C] pounces on the light!</span>","<span class='warning'>LIGHT!</span>")
C.Move(targloc)
C.resting = TRUE
C.update_canmove()
C.set_resting(TRUE)
else
C.visible_message("<span class='notice'>[C] looks uninterested in your games.</span>","<span class='warning'>You spot [user] shining [src] at you. How insulting!</span>")
@@ -158,7 +158,7 @@
/obj/item/lightreplacer/attack_self(mob/user)
to_chat(user, status_string())
/obj/item/lightreplacer/update_icon()
/obj/item/lightreplacer/update_icon_state()
icon_state = "lightreplacer[(obj_flags & EMAGGED ? 1 : 0)]"
/obj/item/lightreplacer/proc/status_string()
+3 -3
View File
@@ -24,7 +24,7 @@
throwforce = 0
throw_range = 7
throw_speed = 3
materials = list(MAT_METAL=50, MAT_GLASS=20)
custom_materials = list(/datum/material/iron=50, /datum/material/glass=20)
var/obj/machinery/buffer // simple machine buffer for device linkage
toolspeed = 1
tool_behaviour = TOOL_MULTITOOL
@@ -67,7 +67,7 @@
to_chat(user, "<span class='notice'>You clear the wired connection from the multitool.</span>")
update_icon()
/obj/item/multitool/update_icon()
/obj/item/multitool/update_icon_state()
if(selected_io)
icon_state = "multitool_red"
else
@@ -149,7 +149,7 @@
/obj/item/multitool/ai_detect/ui_action_click()
return
/obj/item/multitool/ai_detect/update_icon()
/obj/item/multitool/ai_detect/update_icon_state()
if(selected_io)
icon_state = "multitool_red"
else
+3 -5
View File
@@ -94,14 +94,12 @@
to_chat(pai, "<span class='userdanger'>Your mental faculties leave you.</span>")
to_chat(pai, "<span class='rose'>oblivion... </span>")
qdel(pai)
if(href_list["wires"])
var/wire = text2num(href_list["wires"])
if(pai.radio)
pai.radio.wires.cut(wire)
if(href_list["wires"] && pai.radio)
pai.radio.wires.cut(href_list["wires"])
if(href_list["reset_radio_short"])
pai.unshort_radio()
if(href_list["setlaws"])
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1]) as message),1,MAX_MESSAGE_LEN)
var/newlaws = stripped_multiline_input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", MAX_MESSAGE_LEN)
if(newlaws && pai)
pai.add_supplied_law(0,newlaws)
if(href_list["toggle_holo"])
@@ -6,7 +6,7 @@
item_flags = NOBLUDGEON
var/paint_color = "grey"
materials = list(MAT_METAL=5000, MAT_GLASS=2000)
custom_materials = list(/datum/material/iron=5000, /datum/material/glass=2000)
/obj/item/pipe_painter/afterattack(atom/A, mob/user, proximity_flag)
. = ..()
+12 -2
View File
@@ -1,5 +1,7 @@
// Powersink - used to drain station power
GLOBAL_LIST_EMPTY(power_sinks)
/obj/item/powersink
desc = "A nulling power sink which drains energy from electrical systems."
name = "power sink"
@@ -13,7 +15,7 @@
throwforce = 5
throw_speed = 1
throw_range = 2
materials = list(MAT_METAL=750)
custom_materials = list(/datum/material/iron=750)
var/drain_rate = 1600000 // amount of power to drain per tick
var/power_drained = 0 // has drained this much power
var/max_power = 1e10 // maximum power that can be drained before exploding
@@ -26,7 +28,15 @@
var/obj/structure/cable/attached // the attached cable
/obj/item/powersink/update_icon()
/obj/item/powersink/Initialize()
. = ..()
GLOB.power_sinks += src
/obj/item/powersink/Destroy()
GLOB.power_sinks -= src
. = ..()
/obj/item/powersink/update_icon_state()
icon_state = "powersink[mode == OPERATING]"
/obj/item/powersink/proc/set_mode(value)
@@ -27,7 +27,7 @@
qpad = null
return TRUE
/obj/item/quantum_keycard/update_icon()
/obj/item/quantum_keycard/update_icon_state()
if(qpad)
icon_state = "quantum_keycard_on"
else
@@ -9,7 +9,7 @@
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
w_class = WEIGHT_CLASS_HUGE
materials = list(MAT_METAL=10000, MAT_GLASS=2500)
custom_materials = list(/datum/material/iron=10000, /datum/material/glass=2500)
var/code = 2
var/frequency = FREQ_ELECTROPACK
@@ -61,7 +61,7 @@
var/mob/living/carbon/C = usr
if(usr.stat || usr.restrained() || C.back == src)
return
if(!usr.canUseTopic(src, BE_CLOSE))
usr << browse(null, "window=radio")
onclose(usr, "radio")
@@ -118,7 +118,7 @@
s.set_up(3, 1, L)
s.start()
L.Knockdown(100)
L.DefaultCombatKnockdown(100)
if(master)
master.receive_signal()
@@ -127,7 +127,7 @@
/obj/item/electropack/ui_interact(mob/user)
if(!ishuman(user))
return
user.set_machine(src)
var/dat = {"
<TT>
@@ -157,7 +157,7 @@ Code:
w_class = WEIGHT_CLASS_SMALL
strip_delay = 60
equip_delay_other = 60
materials = list(MAT_METAL=5000, MAT_GLASS=2000)
custom_materials = list(/datum/material/iron = 5000, /datum/material/glass = 2000)
var/tagname = null
@@ -166,7 +166,7 @@ Code:
id = "shockcollar"
build_type = AUTOLATHE
build_path = /obj/item/electropack/shockcollar
materials = list(MAT_METAL=5000, MAT_GLASS=2000)
materials = list(/datum/material/iron = 5000, /datum/material/glass =2000)
category = list("hacked", "Misc")
/obj/item/electropack/shockcollar/attack_hand(mob/user)
@@ -192,7 +192,7 @@ Code:
s.set_up(3, 1, L)
s.start()
L.Knockdown(100)
L.DefaultCombatKnockdown(100)
if(master)
master.receive_signal()
@@ -200,14 +200,14 @@ Code:
/obj/item/electropack/shockcollar/attackby(obj/item/W, mob/user, params) //moves it here because on_click is being bad
if(istype(W, /obj/item/pen))
var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text
var/t = stripped_input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot", MAX_NAME_LEN)
if(t)
tagname = copytext(sanitize(t), 1, MAX_NAME_LEN)
name = "[initial(name)] - [tagname]"
tagname = t
name = "[initial(name)] - [t]"
else
return ..()
/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this
/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this
var/dat = {"
<TT>
<B>Frequency/Code</B> for shock collar:<BR>
@@ -19,13 +19,14 @@ GLOBAL_LIST_INIT(channel_tokens, list(
desc = "An updated, modular intercom that fits over the head. Takes encryption keys."
icon_state = "headset"
item_state = "headset"
materials = list(MAT_METAL=75)
custom_materials = list(/datum/material/iron=75)
subspace_transmission = TRUE
canhear_range = 0 // can't hear headsets from very far away
slot_flags = ITEM_SLOT_EARS
var/obj/item/encryptionkey/keyslot2 = null
dog_fashion = null
var/bowman = FALSE
/obj/item/radio/headset/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins putting \the [src]'s antenna up [user.p_their()] nose! It looks like [user.p_theyre()] trying to give [user.p_them()]self cancer!</span>")
@@ -52,6 +53,11 @@ GLOBAL_LIST_INIT(channel_tokens, list(
else
. += "<span class='notice'>A small screen on the headset flashes, it's too small to read without holding or wearing the headset.</span>"
/obj/item/radio/headset/ComponentInitialize()
. = ..()
if (bowman)
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
/obj/item/radio/headset/Initialize()
. = ..()
recalculateChannels()
@@ -81,10 +87,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs."
icon_state = "syndie_headset"
item_state = "syndie_headset"
/obj/item/radio/headset/syndicate/alt/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
bowman = TRUE
/obj/item/radio/headset/syndicate/alt/leader
name = "team leader headset"
@@ -112,10 +115,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
desc = "This is used by your elite security force. Protects ears from flashbangs."
icon_state = "sec_headset_alt"
item_state = "sec_headset_alt"
/obj/item/radio/headset/headset_sec/alt/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
bowman = TRUE
/obj/item/radio/headset/headset_eng
name = "engineering radio headset"
@@ -161,10 +161,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
desc = "The headset of the boss. Protects ears from flashbangs."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
/obj/item/radio/headset/heads/captain/alt/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
bowman = TRUE
/obj/item/radio/headset/heads/rd
name = "\proper the research director's headset"
@@ -183,10 +180,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
/obj/item/radio/headset/heads/hos/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
bowman = TRUE
/obj/item/radio/headset/heads/ce
name = "\proper the chief engineer's headset"
@@ -258,22 +252,28 @@ GLOBAL_LIST_INIT(channel_tokens, list(
icon_state = "cent_headset_alt"
item_state = "cent_headset_alt"
keyslot = null
bowman = TRUE
/obj/item/radio/headset/headset_cent/alt/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
/obj/item/radio/headset/silicon/pai
name = "\proper mini Integrated Subspace Transceiver "
subspace_transmission = FALSE
/obj/item/radio/headset/ai
/obj/item/radio/headset/silicon/ai
name = "\proper Integrated Subspace Transceiver "
keyslot2 = new /obj/item/encryptionkey/ai
command = TRUE
/obj/item/radio/headset/ai/can_receive(freq, level)
/obj/item/radio/headset/silicon/can_receive(freq, level)
return ..(freq, level, TRUE)
/obj/item/radio/headset/attackby(obj/item/W, mob/user, params)
user.set_machine(src)
if (istype(W,/obj/item/headsetupgrader))
if (!bowman)
to_chat(user,"<span class='notice'>You upgrade [src].</span>")
bowmanize()
qdel(W)
if(istype(W, /obj/item/screwdriver))
if(keyslot || keyslot2)
for(var/ch_name in channels)
@@ -341,3 +341,24 @@ GLOBAL_LIST_INIT(channel_tokens, list(
use_command = !use_command
to_chat(user, "<span class='notice'>You toggle high-volume mode [use_command ? "on" : "off"].</span>")
return TRUE
/obj/item/radio/headset/proc/bowmanize()
cut_overlays()
var/icon/yeas = icon(icon,icon_state)
icon_state = "antenna_alt"
var/mutable_appearance/center = mutable_appearance(icon,"center_alt")
center.color = yeas.GetPixel(15,18)
var/mutable_appearance/centeralt = mutable_appearance(icon,"centeralt_alt")
centeralt.color = yeas.GetPixel(14,22)
var/mutable_appearance/centercenter = mutable_appearance(icon,"centercenter_alt")
centercenter.color = yeas.GetPixel(13,19)
var/mutable_appearance/centerpixel = mutable_appearance(icon,"centerpixel_alt")
centerpixel.color = yeas.GetPixel(13,21)
add_overlay(center)
add_overlay(centeralt)
add_overlay(centercenter)
add_overlay(centerpixel)
name = replacetext(name,"headset", "bowman headset")
desc = "[desc] Protects ears from flashbangs."
bowman = TRUE
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
@@ -147,4 +147,4 @@
result_path = /obj/item/radio/intercom/unscrewed
pixel_shift = 29
inverse = TRUE
materials = list(MAT_METAL = 75, MAT_GLASS = 25)
custom_materials = list(/datum/material/iron = 75, /datum/material/glass = 25)
@@ -11,7 +11,7 @@
throw_speed = 3
throw_range = 7
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=75, MAT_GLASS=25)
custom_materials = list(/datum/material/iron=75, /datum/material/glass=25)
obj_flags = USES_TGUI
var/on = TRUE
@@ -112,7 +112,14 @@
. = ..()
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "radio", name, 370, 220 + channels.len * 22, master_ui, state)
var/ui_width = 360
var/ui_height = 106
if(subspace_transmission)
if(channels.len > 0)
ui_height += 6 + channels.len * 21
else
ui_height += 24
ui = new(user, src, ui_key, "radio", name, ui_width, ui_height, master_ui, state)
ui.open()
/obj/item/radio/ui_data(mob/user)
+122 -19
View File
@@ -19,7 +19,7 @@ SLIME SCANNER
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
materials = list(MAT_METAL=150)
custom_materials = list(/datum/material/iron=150)
/obj/item/t_scanner/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins to emit terahertz-rays into [user.p_their()] brain with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -28,7 +28,7 @@ SLIME SCANNER
/obj/item/t_scanner/attack_self(mob/user)
on = !on
icon_state = copytext(icon_state, 1, length(icon_state))+"[on]"
icon_state = copytext_char(icon_state, 1, -1) + "[on]"
if(on)
START_PROCESSING(SSobj, src)
@@ -75,7 +75,7 @@ SLIME SCANNER
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=200)
custom_materials = list(/datum/material/iron=200)
var/mode = 1
var/scanmode = 0
var/advanced = FALSE
@@ -150,7 +150,10 @@ SLIME SCANNER
msg += "\n\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage.</span>"
if(advanced)
msg += "\n\t<span class='info'>Cellular Damage Level: [M.getCloneLoss()].</span>"
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(advanced && H.has_dna())
msg += "\n\t<span class='info'>Genetic Stability: [H.dna.stability]%.</span>"
to_chat(user, msg)
msg = ""
@@ -307,11 +310,11 @@ SLIME SCANNER
//GENERAL HANDLER
if(!damage_message)
if(O.organ_flags & ORGAN_FAILING)
damage_message += " <span class='alert'><b>End Stage [O.name] failure detected.</b></span>"
damage_message += " <span class='alert'><b>Chronic [O.name] failure detected.</b></span>"
else if(O.damage > O.high_threshold)
damage_message += " <span class='alert'>Chronic [O.name] failure detected.</span>"
damage_message += " <span class='alert'>Acute [O.name] failure detected.</span>"
else if(O.damage > O.low_threshold && advanced)
damage_message += " <font color='red'>Acute [O.name] failure detected.</span>"
damage_message += " <font color='red'>Minor [O.name] failure detected.</span>"
if(temp_message || damage_message)
msg += "\t<b><span class='info'>[uppertext(O.name)]:</b></span> [damage_message] [temp_message]\n"
@@ -326,8 +329,8 @@ SLIME SCANNER
breathes = FALSE
if(NOBLOOD in C.dna.species.species_traits)
blooded = FALSE
var/has_liver = (!(NOLIVER in C.dna.species.species_traits))
var/has_stomach = (!(NOSTOMACH in C.dna.species.species_traits))
var/has_liver = C.dna && !(NOLIVER in C.dna.species.species_traits)
var/has_stomach = C.dna && !(NOSTOMACH in C.dna.species.species_traits)
if(!M.getorganslot(ORGAN_SLOT_EYES))
msg += "\t<span class='alert'><b>Subject does not have eyes.</b></span>\n"
if(!M.getorganslot(ORGAN_SLOT_EARS))
@@ -407,19 +410,17 @@ SLIME SCANNER
// Blood Level
if(M.has_dna())
var/mob/living/carbon/C = M
var/blood_id = C.get_blood_id()
if(blood_id)
var/blood_typepath = C.get_blood_id()
if(blood_typepath)
if(ishuman(C))
if(H.bleed_rate)
msg += "<span class='danger'>Subject is bleeding!</span>\n"
var/blood_percent = round((C.scan_blood_volume() / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100)
var/blood_type = C.dna.blood_type
if(blood_id != ("blood" || "jellyblood"))//special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(!(blood_typepath in GLOB.blood_reagent_types))
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_typepath]
if(R)
blood_type = R.name
else
blood_type = blood_id
if(C.scan_blood_volume() <= (BLOOD_VOLUME_SAFE*C.blood_ratio) && C.scan_blood_volume() > (BLOOD_VOLUME_OKAY*C.blood_ratio))
msg += "<span class='danger'>LOW blood level [blood_percent] %, [C.scan_blood_volume()] cl,</span> <span class='info'>type: [blood_type]</span>\n"
else if(C.scan_blood_volume() <= (BLOOD_VOLUME_OKAY*C.blood_ratio))
@@ -486,7 +487,8 @@ SLIME SCANNER
set name = "Switch Verbosity"
set category = "Object"
if(usr.stat || !usr.canmove || usr.restrained())
var/mob/living/L = usr
if(!istype(L) || !CHECK_MOBILITY(L, MOBILITY_USE))
return
mode = !mode
@@ -518,7 +520,7 @@ SLIME SCANNER
throw_speed = 3
throw_range = 7
tool_behaviour = TOOL_ANALYZER
materials = list(MAT_METAL=30, MAT_GLASS=20)
custom_materials = list(/datum/material/iron=30, /datum/material/glass=20)
grind_results = list(/datum/reagent/mercury = 5, /datum/reagent/iron = 5, /datum/reagent/silicon = 5)
var/cooldown = FALSE
var/cooldown_time = 250
@@ -708,7 +710,7 @@ SLIME SCANNER
throwforce = 0
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=30, MAT_GLASS=20)
custom_materials = list(/datum/material/iron=30, /datum/material/glass=20)
/obj/item/slime_scanner/attack(mob/living/M, mob/living/user)
if(user.stat || user.eye_blind)
@@ -767,7 +769,7 @@ SLIME SCANNER
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=200)
custom_materials = list(/datum/material/iron=200)
/obj/item/nanite_scanner/attack(mob/living/M, mob/living/carbon/human/user)
user.visible_message("<span class='notice'>[user] has analyzed [M]'s nanites.</span>")
@@ -777,3 +779,104 @@ SLIME SCANNER
var/response = SEND_SIGNAL(M, COMSIG_NANITE_SCAN, user, TRUE)
if(!response)
to_chat(user, "<span class='info'>No nanites detected in the subject.</span>")
/obj/item/sequence_scanner
name = "genetic sequence scanner"
icon = 'icons/obj/device.dmi'
icon_state = "gene"
item_state = "healthanalyzer"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
desc = "A hand-held scanner for analyzing someones gene sequence on the fly. Hold near a DNA console to update the internal database."
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
throwforce = 3
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
custom_materials = list(/datum/material/iron=200)
var/list/discovered = list() //hit a dna console to update the scanners database
var/list/buffer
var/ready = TRUE
var/cooldown = 200
/obj/item/sequence_scanner/attack(mob/living/M, mob/living/carbon/human/user)
add_fingerprint(user)
if (!HAS_TRAIT_NOT_FROM(M, TRAIT_RADIMMUNE,BLOODSUCKER_TRAIT)) //no scanning if its a husk or DNA-less Species
user.visible_message("<span class='notice'>[user] analyzes [M]'s genetic sequence.</span>", \
"<span class='notice'>You analyze [M]'s genetic sequence.</span>")
gene_scan(M, user)
else
user.visible_message("<span class='notice'>[user] failed to analyse [M]'s genetic sequence.</span>", "<span class='warning'>[M] has no readable genetic sequence!</span>")
/obj/item/sequence_scanner/attack_self(mob/user)
display_sequence(user)
/obj/item/sequence_scanner/attack_self_tk(mob/user)
return
/obj/item/sequence_scanner/afterattack(obj/O, mob/user, proximity)
. = ..()
if(!istype(O) || !proximity)
return
if(istype(O, /obj/machinery/computer/scan_consolenew))
var/obj/machinery/computer/scan_consolenew/C = O
if(C.stored_research)
to_chat(user, "<span class='notice'>[name] linked to central research database.</span>")
discovered = C.stored_research.discovered_mutations
else
to_chat(user,"<span class='warning'>No database to update from.</span>")
/obj/item/sequence_scanner/proc/gene_scan(mob/living/carbon/C, mob/living/user)
if(!iscarbon(C) || !C.has_dna())
return
buffer = C.dna.mutation_index
to_chat(user, "<span class='notice'>Subject [C.name]'s DNA sequence has been saved to buffer.</span>")
if(LAZYLEN(buffer))
for(var/A in buffer)
to_chat(user, "<span class='notice'>[get_display_name(A)]</span>")
/obj/item/sequence_scanner/proc/display_sequence(mob/living/user)
if(!LAZYLEN(buffer) || !ready)
return
var/list/options = list()
for(var/A in buffer)
options += get_display_name(A)
var/answer = input(user, "Analyze Potential", "Sequence Analyzer") as null|anything in sortList(options)
if(answer && ready && user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
var/sequence
for(var/A in buffer) //this physically hurts but i dont know what anything else short of an assoc list
if(get_display_name(A) == answer)
sequence = buffer[A]
break
if(sequence)
var/display
for(var/i in 0 to length_char(sequence) / DNA_MUTATION_BLOCKS-1)
if(i)
display += "-"
display += copytext_char(sequence, 1 + i*DNA_MUTATION_BLOCKS, DNA_MUTATION_BLOCKS*(1+i) + 1)
to_chat(user, "<span class='boldnotice'>[display]</span><br>")
ready = FALSE
icon_state = "[icon_state]_recharging"
addtimer(CALLBACK(src, .proc/recharge), cooldown, TIMER_UNIQUE)
/obj/item/sequence_scanner/proc/recharge()
icon_state = initial(icon_state)
ready = TRUE
/obj/item/sequence_scanner/proc/get_display_name(mutation)
var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(mutation)
if(!HM)
return "ERROR"
if(mutation in discovered)
return "[HM.name] ([HM.alias])"
else
return HM.alias
@@ -9,7 +9,7 @@
w_class = WEIGHT_CLASS_SMALL
flags_1 = HEAR_1
slot_flags = ITEM_SLOT_BELT
materials = list(MAT_METAL=60, MAT_GLASS=30)
custom_materials = list(/datum/material/iron=60, /datum/material/glass=30)
force = 2
throwforce = 0
var/recording = 0
@@ -83,7 +83,7 @@
eject(usr)
/obj/item/taperecorder/update_icon()
/obj/item/taperecorder/update_icon_state()
if(!mytape)
icon_state = "taperecorder_empty"
else if(recording)
@@ -243,7 +243,7 @@
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
materials = list(MAT_METAL=20, MAT_GLASS=5)
custom_materials = list(/datum/material/iron=20, /datum/material/glass=5)
force = 1
throwforce = 0
var/max_capacity = 600
@@ -44,7 +44,7 @@ effective or pretty fucking useless.
for(var/mob/living/carbon/human/M in urange(10, user, 1))
if(prob(50))
M.Knockdown(rand(200,400))
M.DefaultCombatKnockdown(rand(200,400))
to_chat(M, "<span class='userdanger'>You feel a tremendous, paralyzing wave flood your mind.</span>")
else
@@ -69,7 +69,7 @@ effective or pretty fucking useless.
*/
/obj/item/healthanalyzer/rad_laser
materials = list(MAT_METAL=400)
custom_materials = list(/datum/material/iron=400)
var/irradiate = 1
var/intensity = 10 // how much damage the radiation does
var/wavelength = 10 // time it takes for the radiation to kick in, in seconds
@@ -251,3 +251,9 @@ effective or pretty fucking useless.
else
GLOB.active_jammers -= src
update_icon()
/obj/item/headsetupgrader
name = "headset upgrader"
desc = "A tool that can be used to upgrade a normal headset to be able to protect from flashbangs."
icon = 'icons/obj/device.dmi'
icon_state = "headset_upgrade"
@@ -63,10 +63,10 @@
if(attached_device)
attached_device.holder_movement()
/obj/item/transfer_valve/dropped()
/obj/item/transfer_valve/dropped(mob/user)
. = ..()
if(attached_device)
attached_device.dropped()
attached_device.dropped(user)
/obj/item/transfer_valve/on_found(mob/finder)
if(attached_device)
+13 -10
View File
@@ -134,8 +134,9 @@
w_class = WEIGHT_CLASS_SMALL
sides = 100
/obj/item/dice/d100/update_icon()
return
/obj/item/dice/d100/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_blocker)
/obj/item/dice/eightbd20
name = "strange d20"
@@ -144,8 +145,9 @@
sides = 20
special_faces = list("It is certain","It is decidedly so","Without a doubt","Yes, definitely","You may rely on it","As I see it, yes","Most likely","Outlook good","Yes","Signs point to yes","Reply hazy try again","Ask again later","Better not tell you now","Cannot predict now","Concentrate and ask again","Don't count on it","My reply is no","My sources say no","Outlook not so good","Very doubtful")
/obj/item/dice/eightbd20/update_icon()
return
/obj/item/dice/eightbd20/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_blocker)
/obj/item/dice/fourdd6
name = "4d d6"
@@ -154,13 +156,14 @@
sides = 48
special_faces = list("Cube-Side: 1-1","Cube-Side: 1-2","Cube-Side: 1-3","Cube-Side: 1-4","Cube-Side: 1-5","Cube-Side: 1-6","Cube-Side: 2-1","Cube-Side: 2-2","Cube-Side: 2-3","Cube-Side: 2-4","Cube-Side: 2-5","Cube-Side: 2-6","Cube-Side: 3-1","Cube-Side: 3-2","Cube-Side: 3-3","Cube-Side: 3-4","Cube-Side: 3-5","Cube-Side: 3-6","Cube-Side: 4-1","Cube-Side: 4-2","Cube-Side: 4-3","Cube-Side: 4-4","Cube-Side: 4-5","Cube-Side: 4-6","Cube-Side: 5-1","Cube-Side: 5-2","Cube-Side: 5-3","Cube-Side: 5-4","Cube-Side: 5-5","Cube-Side: 5-6","Cube-Side: 6-1","Cube-Side: 6-2","Cube-Side: 6-3","Cube-Side: 6-4","Cube-Side: 6-5","Cube-Side: 6-6","Cube-Side: 7-1","Cube-Side: 7-2","Cube-Side: 7-3","Cube-Side: 7-4","Cube-Side: 7-5","Cube-Side: 7-6","Cube-Side: 8-1","Cube-Side: 8-2","Cube-Side: 8-3","Cube-Side: 8-4","Cube-Side: 8-5","Cube-Side: 8-6")
/obj/item/dice/fourdd6/update_icon()
return
/obj/item/dice/fourdd6/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_blocker)
/obj/item/dice/attack_self(mob/user)
diceroll(user)
/obj/item/dice/throw_impact(atom/target)
/obj/item/dice/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
diceroll(thrownby)
. = ..()
@@ -187,9 +190,9 @@
else if(!src.throwing) //Dice was thrown and is coming to rest
visible_message("<span class='notice'>[src] rolls to a stop, landing on [result]. [comment]</span>")
/obj/item/dice/update_icon()
cut_overlays()
add_overlay("[src.icon_state]-[src.result]")
/obj/item/dice/update_overlays()
. = ..()
. += "[icon_state]-[result]"
/obj/item/dice/microwave_act(obj/machinery/microwave/M)
if(can_be_rigged)
+257 -76
View File
@@ -14,33 +14,25 @@
var/list/add_mutations = list()
var/list/remove_mutations = list()
var/list/add_mutations_static = list()
var/list/remove_mutations_static = list()
var/used = 0
/obj/item/dnainjector/attack_paw(mob/user)
return attack_hand(user)
/obj/item/dnainjector/proc/prepare()
for(var/mut_key in add_mutations_static)
add_mutations.Add(GLOB.mutations_list[mut_key])
for(var/mut_key in remove_mutations_static)
remove_mutations.Add(GLOB.mutations_list[mut_key])
/obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
prepare()
if(M.has_dna() && !HAS_TRAIT(M, TRAIT_RADIMMUNE) && !HAS_TRAIT(M, TRAIT_NOCLONE))
if(M.has_dna() && !HAS_TRAIT_NOT_FROM(M, TRAIT_RADIMMUNE,BLOODSUCKER_TRAIT) && !HAS_TRAIT(M, TRAIT_NOCLONE))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/datum/mutation/human/HM in remove_mutations)
HM.force_lose(M)
for(var/datum/mutation/human/HM in add_mutations)
if(HM.name == RACEMUT)
for(var/HM in remove_mutations)
M.dna.remove_mutation(HM)
for(var/HM in add_mutations)
if(HM == RACEMUT)
message_admins("[ADMIN_LOOKUPFLW(user)] injected [key_name_admin(M)] with the [name] <span class='danger'>(MONKEY)</span>")
log_msg += " (MONKEY)"
HM.force_give(M)
if(M.dna.mutation_in_sequence(HM))
M.dna.activate_mutation(HM)
else
M.dna.add_mutation(HM, MUT_EXTRA)
if(fields)
if(fields["name"] && fields["UE"] && fields["blood_type"])
M.real_name = fields["name"]
@@ -90,123 +82,123 @@
/obj/item/dnainjector/antihulk
name = "\improper DNA injector (Anti-Hulk)"
desc = "Cures green skin."
remove_mutations_static = list(HULK)
remove_mutations = list(HULK)
/obj/item/dnainjector/hulkmut
name = "\improper DNA injector (Hulk)"
desc = "This will make you big and strong, but give you a bad skin condition."
add_mutations_static = list(HULK)
add_mutations = list(HULK)
/obj/item/dnainjector/xraymut
name = "\improper DNA injector (X-ray)"
desc = "Finally you can see what the Captain does."
add_mutations_static = list(XRAY)
add_mutations = list(XRAY)
/obj/item/dnainjector/antixray
name = "\improper DNA injector (Anti-X-ray)"
desc = "It will make you see harder."
remove_mutations_static = list(XRAY)
remove_mutations = list(XRAY)
/////////////////////////////////////
/obj/item/dnainjector/antiglasses
name = "\improper DNA injector (Anti-Glasses)"
desc = "Toss away those glasses!"
remove_mutations_static = list(BADSIGHT)
remove_mutations = list(BADSIGHT)
/obj/item/dnainjector/glassesmut
name = "\improper DNA injector (Glasses)"
desc = "Will make you need dorkish glasses."
add_mutations_static = list(BADSIGHT)
add_mutations = list(BADSIGHT)
/obj/item/dnainjector/epimut
name = "\improper DNA injector (Epi.)"
desc = "Shake shake shake the room!"
add_mutations_static = list(EPILEPSY)
add_mutations = list(EPILEPSY)
/obj/item/dnainjector/antiepi
name = "\improper DNA injector (Anti-Epi.)"
desc = "Will fix you up from shaking the room."
remove_mutations_static = list(EPILEPSY)
remove_mutations = list(EPILEPSY)
////////////////////////////////////
/obj/item/dnainjector/anticough
name = "\improper DNA injector (Anti-Cough)"
desc = "Will stop that awful noise."
remove_mutations_static = list(COUGH)
remove_mutations = list(COUGH)
/obj/item/dnainjector/coughmut
name = "\improper DNA injector (Cough)"
desc = "Will bring forth a sound of horror from your throat."
add_mutations_static = list(COUGH)
add_mutations = list(COUGH)
/obj/item/dnainjector/antidwarf
name = "\improper DNA injector (Anti-Dwarfism)"
desc = "Helps you grow big and strong."
remove_mutations_static = list(DWARFISM)
remove_mutations = list(DWARFISM)
/obj/item/dnainjector/dwarf
name = "\improper DNA injector (Dwarfism)"
desc = "It's a small world after all."
add_mutations_static = list(DWARFISM)
add_mutations = list(DWARFISM)
/obj/item/dnainjector/clumsymut
name = "\improper DNA injector (Clumsy)"
desc = "Makes clown minions."
add_mutations_static = list(CLOWNMUT)
add_mutations = list(CLOWNMUT)
/obj/item/dnainjector/anticlumsy
name = "\improper DNA injector (Anti-Clumsy)"
desc = "Apply this for Security Clown."
remove_mutations_static = list(CLOWNMUT)
remove_mutations = list(CLOWNMUT)
/obj/item/dnainjector/antitour
name = "\improper DNA injector (Anti-Tour.)"
desc = "Will cure Tourette's."
remove_mutations_static = list(TOURETTES)
remove_mutations = list(TOURETTES)
/obj/item/dnainjector/tourmut
name = "\improper DNA injector (Tour.)"
desc = "Gives you a nasty case of Tourette's."
add_mutations_static = list(TOURETTES)
add_mutations = list(TOURETTES)
/obj/item/dnainjector/stuttmut
name = "\improper DNA injector (Stutt.)"
desc = "Makes you s-s-stuttterrr."
add_mutations_static = list(NERVOUS)
add_mutations = list(NERVOUS)
/obj/item/dnainjector/antistutt
name = "\improper DNA injector (Anti-Stutt.)"
desc = "Fixes that speaking impairment."
remove_mutations_static = list(NERVOUS)
remove_mutations = list(NERVOUS)
/obj/item/dnainjector/antifire
name = "\improper DNA injector (Anti-Fire)"
desc = "Cures fire."
remove_mutations_static = list(COLDRES)
remove_mutations = list(SPACEMUT)
/obj/item/dnainjector/firemut
name = "\improper DNA injector (Fire)"
desc = "Gives you fire."
add_mutations_static = list(COLDRES)
add_mutations = list(SPACEMUT)
/obj/item/dnainjector/blindmut
name = "\improper DNA injector (Blind)"
desc = "Makes you not see anything."
add_mutations_static = list(BLINDMUT)
add_mutations = list(BLINDMUT)
/obj/item/dnainjector/antiblind
name = "\improper DNA injector (Anti-Blind)"
desc = "IT'S A MIRACLE!!!"
remove_mutations_static = list(BLINDMUT)
remove_mutations = list(BLINDMUT)
/obj/item/dnainjector/antitele
name = "\improper DNA injector (Anti-Tele.)"
desc = "Will make you not able to control your mind."
remove_mutations_static = list(TK)
remove_mutations = list(TK)
/obj/item/dnainjector/telemut
name = "\improper DNA injector (Tele.)"
desc = "Super brain man!"
add_mutations_static = list(TK)
add_mutations = list(TK)
/obj/item/dnainjector/telemut/darkbundle
name = "\improper DNA injector"
@@ -215,100 +207,258 @@
/obj/item/dnainjector/deafmut
name = "\improper DNA injector (Deaf)"
desc = "Sorry, what did you say?"
add_mutations_static = list(DEAFMUT)
add_mutations = list(DEAFMUT)
/obj/item/dnainjector/antideaf
name = "\improper DNA injector (Anti-Deaf)"
desc = "Will make you hear once more."
remove_mutations_static = list(DEAFMUT)
remove_mutations = list(DEAFMUT)
/obj/item/dnainjector/h2m
name = "\improper DNA injector (Human > Monkey)"
desc = "Will make you a flea bag."
add_mutations_static = list(RACEMUT)
add_mutations = list(RACEMUT)
/obj/item/dnainjector/m2h
name = "\improper DNA injector (Monkey > Human)"
desc = "Will make you...less hairy."
remove_mutations_static = list(RACEMUT)
remove_mutations = list(RACEMUT)
/obj/item/dnainjector/antichameleon
name = "\improper DNA injector (Anti-Chameleon)"
remove_mutations_static = list(CHAMELEON)
remove_mutations = list(CHAMELEON)
/obj/item/dnainjector/chameleonmut
name = "\improper DNA injector (Chameleon)"
add_mutations_static = list(CHAMELEON)
add_mutations = list(CHAMELEON)
/obj/item/dnainjector/antiwacky
name = "\improper DNA injector (Anti-Wacky)"
remove_mutations_static = list(WACKY)
remove_mutations = list(WACKY)
/obj/item/dnainjector/wackymut
name = "\improper DNA injector (Wacky)"
add_mutations_static = list(WACKY)
add_mutations = list(WACKY)
/obj/item/dnainjector/antimute
name = "\improper DNA injector (Anti-Mute)"
remove_mutations_static = list(MUT_MUTE)
remove_mutations = list(MUT_MUTE)
/obj/item/dnainjector/mutemut
name = "\improper DNA injector (Mute)"
add_mutations_static = list(MUT_MUTE)
add_mutations = list(MUT_MUTE)
/obj/item/dnainjector/antismile
name = "\improper DNA injector (Anti-Smile)"
remove_mutations_static = list(SMILE)
remove_mutations = list(SMILE)
/obj/item/dnainjector/smilemut
name = "\improper DNA injector (Smile)"
add_mutations_static = list(SMILE)
add_mutations = list(SMILE)
/obj/item/dnainjector/unintelligiblemut
name = "\improper DNA injector (Unintelligible)"
add_mutations_static = list(UNINTELLIGIBLE)
add_mutations = list(UNINTELLIGIBLE)
/obj/item/dnainjector/antiunintelligible
name = "\improper DNA injector (Anti-Unintelligible)"
remove_mutations_static = list(UNINTELLIGIBLE)
remove_mutations = list(UNINTELLIGIBLE)
/obj/item/dnainjector/swedishmut
name = "\improper DNA injector (Swedish)"
add_mutations_static = list(SWEDISH)
add_mutations = list(SWEDISH)
/obj/item/dnainjector/antiswedish
name = "\improper DNA injector (Anti-Swedish)"
remove_mutations_static = list(SWEDISH)
remove_mutations = list(SWEDISH)
/obj/item/dnainjector/chavmut
name = "\improper DNA injector (Chav)"
add_mutations_static = list(CHAV)
add_mutations = list(CHAV)
/obj/item/dnainjector/antichav
name = "\improper DNA injector (Anti-Chav)"
remove_mutations_static = list(CHAV)
remove_mutations = list(CHAV)
/obj/item/dnainjector/elvismut
name = "\improper DNA injector (Elvis)"
add_mutations_static = list(ELVIS)
add_mutations = list(ELVIS)
/obj/item/dnainjector/antielvis
name = "\improper DNA injector (Anti-Elvis)"
remove_mutations_static = list(ELVIS)
remove_mutations = list(ELVIS)
/obj/item/dnainjector/lasereyesmut
name = "\improper DNA injector (Laser Eyes)"
add_mutations_static = list(LASEREYES)
add_mutations = list(LASEREYES)
/obj/item/dnainjector/antilasereyes
name = "\improper DNA injector (Anti-Laser Eyes)"
remove_mutations_static = list(LASEREYES)
remove_mutations = list(LASEREYES)
/obj/item/dnainjector/void
name = "\improper DNA injector (Void)"
add_mutations = list(VOID)
/obj/item/dnainjector/antivoid
name = "\improper DNA injector (Anti-Void)"
remove_mutations = list(VOID)
/obj/item/dnainjector/antenna
name = "\improper DNA injector (Antenna)"
add_mutations = list(ANTENNA)
/obj/item/dnainjector/antiantenna
name = "\improper DNA injector (Anti-Antenna)"
remove_mutations = list(ANTENNA)
/obj/item/dnainjector/paranoia
name = "\improper DNA injector (Paranoia)"
add_mutations = list(PARANOIA)
/obj/item/dnainjector/antiparanoia
name = "\improper DNA injector (Anti-Paranoia)"
remove_mutations = list(PARANOIA)
/obj/item/dnainjector/mindread
name = "\improper DNA injector (Mindread)"
add_mutations = list(MINDREAD)
/obj/item/dnainjector/antimindread
name = "\improper DNA injector (Anti-Mindread)"
remove_mutations = list(MINDREAD)
/obj/item/dnainjector/radioactive
name = "\improper DNA injector (Radioactive)"
add_mutations = list(RADIOACTIVE)
/obj/item/dnainjector/antiradioactive
name = "\improper DNA injector (Anti-Radioactive)"
remove_mutations = list(RADIOACTIVE)
/obj/item/dnainjector/olfaction
name = "\improper DNA injector (Olfaction)"
add_mutations = list(OLFACTION)
/obj/item/dnainjector/antiolfaction
name = "\improper DNA injector (Anti-Olfaction)"
remove_mutations = list(OLFACTION)
/obj/item/dnainjector/insulated
name = "\improper DNA injector (Insulated)"
add_mutations = list(INSULATED)
/obj/item/dnainjector/antiinsulated
name = "\improper DNA injector (Anti-Insulated)"
remove_mutations = list(INSULATED)
/obj/item/dnainjector/shock
name = "\improper DNA injector (Shock Touch)"
add_mutations = list(SHOCKTOUCH)
/obj/item/dnainjector/antishock
name = "\improper DNA injector (Anti-Shock Touch)"
remove_mutations = list(SHOCKTOUCH)
/obj/item/dnainjector/spacialinstability
name = "\improper DNA injector (Spacial Instability)"
add_mutations = list(BADBLINK)
/obj/item/dnainjector/antispacialinstability
name = "\improper DNA injector (Anti-Spacial Instability)"
remove_mutations = list(BADBLINK)
/obj/item/dnainjector/acidflesh
name = "\improper DNA injector (Acid Flesh)"
add_mutations = list(ACIDFLESH)
/obj/item/dnainjector/antiacidflesh
name = "\improper DNA injector (Acid Flesh)"
remove_mutations = list(ACIDFLESH)
/obj/item/dnainjector/gigantism
name = "\improper DNA injector (Gigantism)"
add_mutations = list(GIGANTISM)
/obj/item/dnainjector/antigigantism
name = "\improper DNA injector (Anti-Gigantism)"
remove_mutations = list(GIGANTISM)
/obj/item/dnainjector/spastic
name = "\improper DNA injector (Spastic)"
add_mutations = list(SPASTIC)
/obj/item/dnainjector/antispastic
name = "\improper DNA injector (Anti-Spastic)"
remove_mutations = list(SPASTIC)
/obj/item/dnainjector/geladikinesis
name = "\improper DNA injector (Geladikinesis)"
add_mutations = list(GELADIKINESIS)
/obj/item/dnainjector/antigeladikinesis
name = "\improper DNA injector (Anti-Geladikinesis)"
remove_mutations = list(GELADIKINESIS)
/obj/item/dnainjector/cryokinesis
name = "\improper DNA injector (Cryokinesis)"
add_mutations = list(CRYOKINESIS)
/obj/item/dnainjector/anticryokinesis
name = "\improper DNA injector (Anti-Cryokinesis)"
remove_mutations = list(CRYOKINESIS)
/obj/item/dnainjector/thermal
name = "\improper DNA injector (Thermal Vision)"
add_mutations = list(THERMAL)
/obj/item/dnainjector/antithermal
name = "\improper DNA injector (Anti-Thermal Vision)"
remove_mutations = list(THERMAL)
/obj/item/dnainjector/glow
name = "\improper DNA injector (Glowy)"
add_mutations = list(GLOWY)
/obj/item/dnainjector/removeglow
name = "\improper DNA injector (Anti-Glowy)"
remove_mutations = list(GLOWY)
/obj/item/dnainjector/antiglow
name = "\improper DNA injector (Antiglowy)"
add_mutations = list(ANTIGLOWY)
/obj/item/dnainjector/removeantiglow
name = "\improper DNA injector (Anti-Antiglowy)"
remove_mutations = list(ANTIGLOWY)
/obj/item/dnainjector/firebreath
name = "\improper DNA injector (Firebreath)"
add_mutations = list(FIREBREATH)
/obj/item/dnainjector/antifirebreath
name = "\improper DNA injector (Anti-Firebreath)"
remove_mutations = list(FIREBREATH)
/obj/item/dnainjector/tonguespike
name = "\improper DNA injector (Tongue Spike)"
add_mutations = list(TONGUESPIKE)
/obj/item/dnainjector/antitonguespike
name = "\improper DNA injector (Anti-Tongue Spike)"
remove_mutations = list(TONGUESPIKE)
/obj/item/dnainjector/spiderweb
name = "\improper DNA injector (Spider Web)"
add_mutations = list(SPIDER_WEB)
/obj/item/dnainjector/antispiderweb
name = "\improper DNA injector (Anti-Spider Web)"
remove_mutations = list(SPIDER_WEB)
/obj/item/dnainjector/timed
var/duration = 600
/obj/item/dnainjector/timed/inject(mob/living/carbon/M, mob/user)
prepare()
if(M.stat == DEAD) //prevents dead people from having their DNA changed
to_chat(user, "<span class='notice'>You can't modify [M]'s DNA while [M.p_theyre()] dead.</span>")
return FALSE
@@ -317,23 +467,22 @@
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
var/endtime = world.time+duration
for(var/datum/mutation/human/HM in remove_mutations)
if(HM.name == RACEMUT)
for(var/mutation in remove_mutations)
if(mutation == RACEMUT)
if(ishuman(M))
continue
M = HM.force_lose(M)
M = M.dna.remove_mutation(mutation)
else
HM.force_lose(M)
for(var/datum/mutation/human/HM in add_mutations)
if((HM in M.dna.mutations) && !(M.dna.temporary_mutations[HM.name]))
M.dna.remove_mutation(mutation)
for(var/mutation in add_mutations)
if(M.dna.get_mutation(mutation))
continue //Skip permanent mutations we already have.
if(HM.name == RACEMUT && ishuman(M))
if(mutation == RACEMUT && ishuman(M))
message_admins("[ADMIN_LOOKUPFLW(user)] injected [key_name_admin(M)] with the [name] <span class='danger'>(MONKEY)</span>")
log_msg += " (MONKEY)"
M = HM.force_give(M)
M = M.dna.add_mutation(mutation, MUT_OTHER, endtime)
else
HM.force_give(M)
M.dna.temporary_mutations[HM.name] = endtime
M.dna.add_mutation(mutation, MUT_OTHER, endtime)
if(fields)
if(fields["name"] && fields["UE"] && fields["blood_type"])
if(!M.dna.previous["name"])
@@ -361,9 +510,41 @@
/obj/item/dnainjector/timed/hulk
name = "\improper DNA injector (Hulk)"
desc = "This will make you big and strong, but give you a bad skin condition."
add_mutations_static = list(HULK)
add_mutations = list(HULK)
/obj/item/dnainjector/timed/h2m
name = "\improper DNA injector (Human > Monkey)"
desc = "Will make you a flea bag."
add_mutations_static = list(RACEMUT)
add_mutations = list(RACEMUT)
/obj/item/dnainjector/activator
name = "\improper DNA activator"
desc = "Activates the current mutation on injection, if the subject has it."
var/doitanyway = FALSE
var/research = FALSE //Set to true to get expended and filled injectors for chromosomes
var/filled = FALSE
/obj/item/dnainjector/activator/inject(mob/living/carbon/M, mob/user)
if(M.has_dna() && !HAS_TRAIT_NOT_FROM(M, TRAIT_RADIMMUNE,BLOODSUCKER_TRAIT) && !HAS_TRAIT(M,TRAIT_NOCLONE))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/mutation in add_mutations)
var/datum/mutation/human/HM = mutation
if(istype(HM, /datum/mutation/human))
mutation = HM.type
if(!M.dna.activate_mutation(HM))
if(!doitanyway)
log_msg += "(FAILED)"
else
M.dna.add_mutation(HM, MUT_EXTRA)
name = "expended [name]"
else if(research && M.client)
filled = TRUE
name = "filled [name]"
else
name = "expended [name]"
log_msg += "([mutation])"
log_attack("[log_msg] [loc_name(user)]")
return TRUE
return FALSE
+66 -47
View File
@@ -54,7 +54,7 @@
to_chat(user, "<span class='warning'>[src] was shaken recently, it needs time to settle.</span>")
return
user.visible_message("<span class='notice'>[user] starts shaking [src].</span>", "<span class='notice'>You start shaking [src].</span>", "<span class='italics'>You hear shaking and sloshing.</span>")
user.visible_message("<span class='notice'>[user] starts shaking [src].</span>", "<span class='notice'>You start shaking [src].</span>", "<span class='hear'>You hear shaking and sloshing.</span>")
shaking = TRUE
@@ -95,16 +95,47 @@
// except it actually ASKS THE DEAD (wooooo)
/obj/item/toy/eightball/haunted
shake_time = 150
cooldown_time = 1800
shake_time = 30 SECONDS
cooldown_time = 3 MINUTES
flags_1 = HEAR_1
var/last_message
var/selected_message
var/list/votes
//these kind of store the same thing but one is easier to work with.
var/list/votes = list()
var/list/voted = list()
var/static/list/haunted_answers = list(
"yes" = list(
"It is certain",
"It is decidedly so",
"Without a doubt",
"Yes definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes"
),
"maybe" = list(
"Reply hazy try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again"
),
"no" = list(
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful"
)
)
/obj/item/toy/eightball/haunted/Initialize(mapload)
. = ..()
votes = list()
for (var/answer in haunted_answers)
votes[answer] = 0
GLOB.poi_list |= src
/obj/item/toy/eightball/haunted/Destroy()
@@ -122,7 +153,7 @@
interact(user)
return ..()
/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode, atom/movable/source)
/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
. = ..()
last_message = raw_message
@@ -137,38 +168,31 @@
if(isobserver(usr))
interact(usr)
/obj/item/toy/eightball/haunted/proc/get_vote_tallies()
var/list/answers = list()
for(var/ckey in votes)
var/selected = votes[ckey]
if(selected in answers)
answers[selected]++
else
answers[selected] = 1
return answers
/obj/item/toy/eightball/haunted/get_answer()
if(!votes.len)
return pick(possible_answers)
var/top_amount = 0
var/top_vote
var/list/tallied_votes = get_vote_tallies()
for(var/vote in votes)
var/amount_of_votes = length(votes[vote])
if(amount_of_votes > top_amount)
top_vote = vote
top_amount = amount_of_votes
//If one option actually has votes and there's a tie, pick between them 50/50
else if(top_amount && amount_of_votes == top_amount && prob(50))
top_vote = vote
top_amount = amount_of_votes
// I miss python sorting, then I wouldn't have to muck about with
// all this
var/most_popular_answer
var/most_amount = 0
// yes, if there is a tie, there is an arbitary decision
// but we never said the spirit world was fair
for(var/A in tallied_votes)
var/amount = tallied_votes[A]
if(amount > most_amount)
most_popular_answer = A
if(isnull(top_vote))
top_vote = pick(votes)
return most_popular_answer
for(var/vote in votes)
votes[vote] = 0
/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.observer_state)
voted.Cut()
return top_vote
/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.always_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
@@ -179,21 +203,13 @@
var/list/data = list()
data["shaking"] = shaking
data["question"] = selected_message
var/list/tallied_votes = get_vote_tallies()
data["answers"] = list()
for(var/pa in possible_answers)
for(var/pa in haunted_answers)
var/list/L = list()
L["answer"] = pa
var/amount = 0
if(pa in tallied_votes)
amount = tallied_votes[pa]
L["amount"] = amount
var/selected = FALSE
if(votes[user.ckey] == pa)
selected = TRUE
L["selected"] = selected
L["amount"] = votes[pa]
L["selected"] = voted[user.ckey]
data["answers"] += list(L)
return data
@@ -206,8 +222,11 @@
switch(action)
if("vote")
var/selected_answer = params["answer"]
if(!(selected_answer in possible_answers))
if(!(selected_answer in haunted_answers))
return
if(user.ckey in voted)
return
else
votes[user.ckey] = selected_answer
. = TRUE
votes[selected_answer] += 1
voted[user.ckey] = selected_answer
. = TRUE
+2 -2
View File
@@ -11,7 +11,7 @@
throw_speed = 2
throw_range = 7
force = 10
materials = list(MAT_METAL = 90)
custom_materials = list(/datum/material/iron = 90)
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
dog_fashion = /datum/dog_fashion/back
resistance_flags = FIRE_PROOF
@@ -36,7 +36,7 @@
throwforce = 2
w_class = WEIGHT_CLASS_SMALL
force = 3
materials = list(MAT_METAL = 50, MAT_GLASS = 40)
custom_materials = list(/datum/material/iron = 50, /datum/material/glass = 40)
max_water = 30
sprite_name = "miniFE"
dog_fashion = null
+12 -13
View File
@@ -12,7 +12,7 @@
throw_speed = 1
throw_range = 5
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=500)
custom_materials = list(/datum/material/iron=500)
resistance_flags = FIRE_PROOF
var/status = FALSE
var/lit = FALSE //on or off
@@ -27,6 +27,10 @@
var/igniter_type = /obj/item/assembly/igniter
trigger_guard = TRIGGER_GUARD_NORMAL
/obj/item/flamethrower/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/flamethrower/Destroy()
if(weldtool)
qdel(weldtool)
@@ -48,22 +52,17 @@
if(isturf(location)) //start a fire if possible
igniter.flamethrower_process(location)
/obj/item/flamethrower/update_icon_state()
item_state = "flamethrower_[lit]"
/obj/item/flamethrower/update_icon()
cut_overlays()
/obj/item/flamethrower/update_overlays()
. = ..()
if(igniter)
add_overlay("+igniter[status]")
. += "+igniter[status]"
if(ptank)
add_overlay("+ptank")
. += "+ptank"
if(lit)
add_overlay("+lit")
item_state = "flamethrower_1"
else
item_state = "flamethrower_0"
if(ismob(loc))
var/mob/M = loc
M.update_inv_hands()
return
. += "+lit"
/obj/item/flamethrower/afterattack(atom/target, mob/user, flag)
. = ..()
+13 -6
View File
@@ -11,7 +11,7 @@
/obj/item/book/granter/proc/turn_page(mob/user)
playsound(user, pick('sound/effects/pageturn1.ogg','sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg'), 30, 1)
if(do_after(user,50, user))
if(do_after(user,50, TRUE, user))
if(remarks.len)
to_chat(user, "<span class='notice'>[pick(remarks)]</span>")
else
@@ -53,7 +53,7 @@
on_reading_stopped()
reading = FALSE
return
if(do_after(user,50, user))
if(do_after(user,50, TRUE, user))
on_reading_finished(user)
reading = FALSE
return TRUE
@@ -294,7 +294,7 @@
/obj/item/book/granter/spell/knock/recoil(mob/living/user)
..()
to_chat(user,"<span class='warning'>You're knocked down!</span>")
user.Knockdown(40)
user.DefaultCombatKnockdown(40)
/obj/item/book/granter/spell/barnyard
spell = /obj/effect/proc_holder/spell/targeted/barnyardcurse
@@ -402,10 +402,11 @@
martialname = "sleeping carp"
desc = "A scroll filled with strange markings. It seems to be drawings of some sort of martial art."
greet = "<span class='sciradio'>You have learned the ancient martial art of the Sleeping Carp! Your hand-to-hand combat has become much more effective, and you are now able to deflect any projectiles \
directed toward you. However, you are also unable to use any ranged weaponry. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab.</span>"
directed toward you while in Throw Mode. Your body is also honed to protect you from damage and punctures, and even briefly survive space. \
However, you are also unable to use any ranged weaponry, and some medical supplies will prove useless to you. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab.</span>"
icon = 'icons/obj/wizard.dmi'
icon_state = "scroll2"
remarks = list("I must prove myself worthy to the masters of the sleeping carp...", "Stance means everything...", "Focus... And you'll be able to incapacitate any foe in seconds...", "I must pierce armor for maximum damage...", "I don't think this would combine with other martial arts...", "Grab them first so they don't retaliate...", "I must prove myself worthy of this power...")
remarks = list("Wait, a high protein diet is really all it takes to become bulletproof...?", "Overwhelming force, immovable object...", "Focus... And you'll be able to incapacitate any foe in seconds...", "I must pierce armor for maximum damage...", "I don't think this would combine with other martial arts...", "Become one with the carp...", "Glub...")
/obj/item/book/granter/martial/carp/onlearned(mob/living/carbon/user)
..()
@@ -490,7 +491,13 @@
oneuse = FALSE
remarks = list("Looks like these would sell much better in a plasma fire...", "Using glass bowls rather then cones?", "Mixing soda and ice-cream?", "Tall glasses with of liquids and solids...", "Just add a bit of icecream and cherry on top?")
//Later content when I have free time - Trilby Date:24-Aug-2019
/obj/item/book/granter/crafting_recipe/bone_bow //Bow crafting for non-ashwalkers
name = "bowyery sandstone slab" // this is an actual word
desc = "A sandstone slab with inscriptions describing the Ash Walkers of Lavaland's bowyery."
crafting_recipe_types = list(/datum/crafting_recipe/bone_arrow, /datum/crafting_recipe/bone_bow, /datum/crafting_recipe/ashen_arrow, /datum/crafting_recipe/quiver, /datum/crafting_recipe/bow_tablet)
icon_state = "stone_tablet"
oneuse = FALSE
remarks = list("Sticking burning arrows into the sand makes them stronger...", "Breaking the bone apart to get shards, not sharpening the bone...", "Sinew is just like rope...")
/obj/item/book/granter/crafting_recipe/under_the_oven //Illegal cook book
name = "Under The Oven"
@@ -117,7 +117,7 @@
if(!O.reagents)
continue
var/reagent_list = pretty_string_from_reagent_list(O.reagents)
user.log_message("removed [O] ([reagent_list]) from [src]")
user.log_message("removed [O] ([reagent_list]) from [src]", LOG_GAME)
beakers = list()
to_chat(user, "<span class='notice'>You open the [initial(name)] assembly and remove the payload.</span>")
return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism.
@@ -177,7 +177,7 @@
/obj/item/grenade/chem_grenade/prime()
if(stage != READY)
return
return FALSE
var/list/datum/reagents/reactants = list()
for(var/obj/item/reagent_containers/glass/G in beakers)
@@ -192,7 +192,7 @@
O.forceMove(drop_location())
beakers = list()
stage_change(EMPTY)
return
return FALSE
if(nadeassembly)
var/mob/M = get_mob_by_ckey(assemblyattacher)
@@ -205,6 +205,7 @@
update_mob()
qdel(src)
return TRUE
//Large chem grenades accept slime cores and use the appropriately.
/obj/item/grenade/chem_grenade/large
@@ -219,7 +220,7 @@
/obj/item/grenade/chem_grenade/large/prime()
if(stage != READY)
return
return FALSE
for(var/obj/item/slime_extract/S in beakers)
if(S.Uses)
@@ -237,7 +238,7 @@
else
S.forceMove(get_turf(src))
no_splash = TRUE
..()
return ..()
//I tried to just put it in the allowed_containers list but
//if you do that it must have reagents. If you're going to
@@ -288,7 +289,7 @@
/obj/item/grenade/chem_grenade/adv_release/prime()
if(stage != READY)
return
return FALSE
var/total_volume = 0
for(var/obj/item/reagent_containers/RC in beakers)
@@ -296,7 +297,7 @@
if(!total_volume)
qdel(src)
qdel(nadeassembly)
return
return FALSE
var/fraction = unit_spread/total_volume
var/datum/reagents/reactants = new(unit_spread)
reactants.my_atom = src
@@ -313,6 +314,7 @@
else
addtimer(CALLBACK(src, .proc/prime), det_time)
log_game("A grenade detonated at [AREACOORD(DT)]")
return TRUE
@@ -31,7 +31,7 @@
M.show_message("<span class='warning'>BANG</span>", MSG_AUDIBLE)
var/distance = get_dist(get_turf(M), source)
if(!distance || loc == M || loc == M.loc) //Stop allahu akbarring rooms with this.
M.Knockdown(200)
M.DefaultCombatKnockdown(200)
M.soundbang_act(1, 200, 10, 15)
else
M.soundbang_act(1, max(200/max(1,distance), 60), rand(0, 5))
@@ -41,4 +41,4 @@
return
var/distance = get_dist(get_turf(M), source)
if(M.flash_act(affect_silicon = 1))
M.Knockdown(max(200/max(1,distance), 60))
M.DefaultCombatKnockdown(max(200/max(1,distance), 60))
+5 -6
View File
@@ -34,12 +34,12 @@
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY)
if(clumsy && (clumsy_check == GRENADE_CLUMSY_FUMBLE))
if(prob(50))
if(clumsy)
if(clumsy_check == GRENADE_CLUMSY_FUMBLE && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
preprime(user, 5, FALSE)
return FALSE
else if(!clumsy && (clumsy_check == GRENADE_NONCLUMSY_FUMBLE))
else if(clumsy_check == GRENADE_NONCLUMSY_FUMBLE && !(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY)))
to_chat(user, "<span class='warning'>You pull the pin on [src]. Attached to it is a pink ribbon that says, \"<span class='clown'>HONK</span>\"</span>")
preprime(user, 5, FALSE)
return FALSE
@@ -93,9 +93,8 @@
var/obj/item/I = loc
I.grenade_prime_react(src)
/obj/item/grenade/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/screwdriver))
/obj/item/grenade/tool_act(mob/living/user, obj/item/I, tool_behaviour)
if(tool_behaviour == TOOL_SCREWDRIVER)
switch(det_time)
if ("1")
det_time = 10
+1 -1
View File
@@ -158,7 +158,7 @@
user.gib(1, 1)
qdel(src)
/obj/item/grenade/plastic/update_icon()
/obj/item/grenade/plastic/update_icon_state()
if(nadeassembly)
icon_state = "[item_state]1"
else
+38 -22
View File
@@ -36,7 +36,7 @@
w_class = WEIGHT_CLASS_SMALL
throw_speed = 3
throw_range = 5
materials = list(MAT_METAL=500)
custom_materials = list(/datum/material/iron=500)
breakouttime = 600 //Deciseconds = 60s = 1 minute
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
var/cuffsound = 'sound/weapons/handcuffs.ogg'
@@ -113,27 +113,24 @@
desc = "Looks like some cables tied together. Could be used to tie something up."
icon_state = "cuff"
item_state = "coil"
item_color = "red"
color = "#ff0000"
color = "red"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
materials = list(MAT_METAL=150, MAT_GLASS=75)
custom_materials = list(/datum/material/iron=150, /datum/material/glass=75)
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable/Initialize(mapload, param_color)
. = ..()
var/list/cable_colors = GLOB.cable_colors
item_color = param_color || item_color || pick(cable_colors)
if(cable_colors[item_color])
item_color = cable_colors[item_color]
update_icon()
/obj/item/restraints/handcuffs/cable/update_icon()
color = null
add_atom_colour(item_color, FIXED_COLOUR_PRIORITY)
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable/attack_self(mob/user)
to_chat(user, "<span class='notice'>You start unwinding the cable restraints back into coil</span>")
if(!do_after(user, 25, TRUE, user))
return
qdel(src)
var/obj/item/stack/cable_coil/coil = new(get_turf(user))
coil.amount = 15
user.put_in_hands(coil)
coil.color = color
to_chat(user, "<span class='notice'>You unwind the cable restraints back into coil</span>")
/obj/item/restraints/handcuffs/cable/red
item_color = "red"
color = "#ff0000"
@@ -165,6 +162,13 @@
/obj/item/restraints/handcuffs/cable/white
item_color = "white"
/obj/item/restraints/handcuffs/cable/random
/obj/item/restraints/handcuffs/cable/random/Initialize(mapload)
. = ..()
var/list/cable_colors = GLOB.cable_colors
color = pick(cable_colors)
/obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/rods))
@@ -202,7 +206,7 @@
item_state = "zipties"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
materials = list()
custom_materials = null
breakouttime = 450 //Deciseconds = 45s
trashtype = /obj/item/restraints/handcuffs/cable/zipties/used
item_color = "white"
@@ -286,6 +290,7 @@
if(!C.legcuffed && C.get_num_legs(FALSE) >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs.
C.legcuffed = src
forceMove(C)
C.update_equipment_speed_mods()
C.update_inv_legcuffed()
SSblackbox.record_feedback("tally", "handcuffs", 1, type)
else if(isanimal(L))
@@ -310,6 +315,7 @@
trap_damage = 0
item_flags = DROPDEL
flags_1 = NONE
breakouttime = 50
/obj/item/restraints/legcuffs/beartrap/energy/New()
..()
@@ -340,18 +346,28 @@
return
playsound(src.loc,'sound/weapons/bolathrow.ogg', 75, 1)
/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom)
/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed,
return//abort
var/mob/living/carbon/C = hit_atom
ensnare(hit_atom)
/**
* Attempts to legcuff someone with the bola
*
* Arguments:
* * C - the carbon that we will try to ensnare
*/
/obj/item/restraints/legcuffs/bola/proc/ensnare(mob/living/carbon/C)
if(!C.legcuffed && C.get_num_legs(FALSE) >= 2)
visible_message("<span class='danger'>\The [src] ensnares [C]!</span>")
C.legcuffed = src
forceMove(C)
C.update_equipment_speed_mods()
C.update_inv_legcuffed()
SSblackbox.record_feedback("tally", "handcuffs", 1, type)
to_chat(C, "<span class='userdanger'>\The [src] ensnares you!</span>")
C.Knockdown(knockdown)
playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
/obj/item/restraints/legcuffs/bola/tactical//traitor variant
name = "reinforced bola"
@@ -368,7 +384,7 @@
w_class = WEIGHT_CLASS_SMALL
breakouttime = 60
/obj/item/restraints/legcuffs/bola/energy/throw_impact(atom/hit_atom)
/obj/item/restraints/legcuffs/bola/energy/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(iscarbon(hit_atom))
var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(hit_atom))
B.Crossed(hit_atom)
+1 -1
View File
@@ -92,7 +92,7 @@
master.emote("scream")
master.remove_status_effect(STATUS_EFFECT_HISGRACE)
REMOVE_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT)
master.Knockdown(60)
master.DefaultCombatKnockdown(60)
master.adjustBruteLoss(master.maxHealth)
playsound(master, 'sound/effects/splat.ogg', 100, 0)
else
@@ -92,6 +92,14 @@
creation_time = 0
max_signs = 3
/obj/item/holosign_creator/combifan
name = "ATMOS holo-combifan projector"
desc = "A holographic projector that creates holographic combi-fans that prevent changes in atmosphere and temperature conditions. Somehow."
icon_state = "signmaker_atmos"
holosign_type = /obj/structure/holosign/barrier/combifan
creation_time = 0
max_signs = 3
/obj/item/holosign_creator/medical
name = "\improper PENLITE barrier projector"
desc = "A holographic projector that creates PENLITE holobarriers. Useful during quarantines since they halt those with malicious diseases."
+39 -32
View File
@@ -51,42 +51,37 @@
item_state = "knight_hospitaller"
// CITADEL CHANGES ENDS HERE
/obj/item/holybeacon
/obj/item/choice_beacon/holy
name = "armaments beacon"
desc = "Contains a set of armaments for the chaplain."
icon = 'icons/obj/device.dmi'
icon_state = "gangtool-red"
item_state = "radio"
/obj/item/holybeacon/attack_self(mob/user)
if(user.mind && (user.mind.isholy) && !GLOB.holy_armor_type)
beacon_armor(user)
/obj/item/choice_beacon/holy/canUseBeacon(mob/living/user)
if(user.mind && user.mind.isholy)
return ..()
else
playsound(src, 'sound/machines/buzz-sigh.ogg', 40, 1)
return FALSE
/obj/item/holybeacon/proc/beacon_armor(mob/M)
var/list/holy_armor_list = typesof(/obj/item/storage/box/holy)
var/list/display_names = list()
for(var/V in holy_armor_list)
var/atom/A = V
display_names += list(initial(A.name) = A)
/obj/item/choice_beacon/holy/generate_display_names()
var/static/list/holy_item_list
if(!holy_item_list)
holy_item_list = list()
var/list/templist = typesof(/obj/item/storage/box/holy)
for(var/V in templist)
var/atom/A = V
holy_item_list[initial(A.name)] = A
return holy_item_list
var/choice = input(M,"What holy armor kit would you like to order?","Holy Armor Theme") as null|anything in display_names
if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type)
/obj/item/choice_beacon/holy/spawn_option(obj/choice,mob/living/M)
if(!GLOB.holy_armor_type)
..()
playsound(src, 'sound/effects/pray_chaplain.ogg', 40, 1)
SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]")
GLOB.holy_armor_type = choice
else
to_chat(M, "<span class='warning'>A selection has already been made. Self-Destructing...</span>")
return
var/index = display_names.Find(choice)
var/A = holy_armor_list[index]
GLOB.holy_armor_type = A
var/holy_armor_box = new A
SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]")
if(holy_armor_box)
qdel(src)
M.put_in_active_hand(holy_armor_box)///YOU COMPILED
/obj/item/storage/box/holy
name = "Templar Kit"
@@ -243,7 +238,7 @@
if(user.mind && (user.mind.isholy) && !reskinned)
reskin_holy_weapon(user)
/obj/item/nullrod/proc/reskin_holy_weapon(mob/M)
/obj/item/nullrod/proc/reskin_holy_weapon(mob/living/L)
if(GLOB.holy_weapon_type)
return
var/obj/item/holy_weapon
@@ -254,8 +249,8 @@
if (initial(rodtype.chaplain_spawnable))
display_names[initial(rodtype.name)] = rodtype
var/choice = input(M,"What theme would you like for your holy weapon?","Holy Weapon Theme") as null|anything in display_names
if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || reskinned)
var/choice = input(L, "What theme would you like for your holy weapon?","Holy Weapon Theme") as null|anything in display_names
if(QDELETED(src) || !choice || !in_range(L, src) || !CHECK_MOBILITY(L, MOBILITY_USE) || reskinned)
return
var/A = display_names[choice] // This needs to be on a separate var as list member access is not allowed for new
@@ -268,7 +263,7 @@
if(holy_weapon)
holy_weapon.reskinned = TRUE
qdel(src)
M.put_in_active_hand(holy_weapon)
L.put_in_active_hand(holy_weapon)
/obj/item/nullrod/proc/jedi_spin(mob/living/user)
for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH))
@@ -468,6 +463,16 @@
hitsound = 'sound/weapons/rapierhit.ogg'
var/possessed = FALSE
/obj/item/nullrod/scythe/talking/process()
for(var/mob/living/simple_animal/shade/S in contents)
if(S.mind)
return
else
qdel(S)
possessed = FALSE
visible_message("<span class='warning'>The blade makes a short sigh. The spirit within seems to have passed on...</span>")
return PROCESS_KILL
/obj/item/nullrod/scythe/talking/relaymove(mob/user)
return //stops buckled message spam for the ghost.
@@ -489,6 +494,8 @@
S.ckey = C.ckey
S.status_flags |= GODMODE
S.language_holder = user.language_holder.copy(S)
S.AddElement(/datum/element/ghost_role_eligibility,penalize_on_ghost = TRUE)
START_PROCESSING(SSprocessing,src)
var/input = stripped_input(S,"What are you named?", ,"", MAX_NAME_LEN)
if(src && input)
@@ -673,7 +680,7 @@
add_fingerprint(user)
if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
to_chat(user, "<span class ='warning'>You club yourself over the head with [src].</span>")
user.Knockdown(60)
user.DefaultCombatKnockdown(60)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.apply_damage(2*force, BRUTE, BODY_ZONE_HEAD)
+2 -3
View File
@@ -71,8 +71,7 @@
if(stimulant)
if(isliving(loc))
var/mob/living/L = loc
L.SetStun(0)
L.SetKnockdown(0)
L.SetAllImmobility(0)
L.SetSleeping(0)
L.SetUnconscious(0)
L.reagents.add_reagent(/datum/reagent/medicine/muscle_stimulant, CLAMP(5 - L.reagents.get_reagent_amount(/datum/reagent/medicine/muscle_stimulant), 0, 5)) //If you don't have legs or get bola'd, tough luck!
@@ -154,7 +153,7 @@
colorize(null)
active = FALSE
/obj/item/hot_potato/update_icon()
/obj/item/hot_potato/update_icon_state()
icon_state = active? icon_on : icon_off
/obj/item/hot_potato/syndicate
@@ -78,12 +78,13 @@
return
if(message && imp_in.stat == CONSCIOUS)
imp_in.visible_message("<span class='warning'>[imp_in] doubles over in pain!</span>")
imp_in.Knockdown(140)
imp_in.DefaultCombatKnockdown(140)
/obj/item/implant/explosive/proc/boom_goes_the_weasel()
explosion(get_turf(imp_in ? imp_in : src), heavy, medium, weak, weak, flame_range = weak)
imp_in?.gib(TRUE)
qdel(src)
if(!QDELETED(imp_in))
imp_in.gib(TRUE)
qdel(src)
/obj/item/implant/explosive/macro
name = "macrobomb implant"
@@ -0,0 +1,121 @@
#define HIJACK_APC_MAX_AMOUNT 5
/obj/item/implant/hijack
name = "hijack implant"
desc = "Allows you to control the machinery in a room by hacking into the APC."
actions_types = list(/datum/action/item_action/hands_free/activate, /datum/action/item_action/removeAPCs, /datum/action/item_action/accessAPCs, /datum/action/item_action/stealthmodetoggle)
activated = 1
var/toggled = FALSE
icon_state = "hijack"
var/eye_color
var/stealthmode = FALSE
var/stealthcooldown = 0
var/hijacking = FALSE
/obj/item/implant/hijack/activate()
. = ..()
toggled = !toggled
imp_in.click_intercept = toggled ? src : null
imp_in.siliconaccesstoggle = toggled ? TRUE : FALSE
to_chat(imp_in,"<span class='notice'>You turn [toggled ? "on" : "off"] [src]'s silicon interactions.</span>")
toggle_eyes()
/obj/item/implant/hijack/proc/toggle_eyes()
if (!ishuman(imp_in))
return
var/on = toggled && !stealthmode
var/mob/living/carbon/human/H = imp_in
H.eye_color = on ? "ff0" : eye_color
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.update_body()
/obj/item/implant/hijack/implant(mob/living/target, mob/user, silent = FALSE)
if(..())
ADD_TRAIT(target, TRAIT_HIJACKER, "implant")
if (ishuman(target))
var/mob/living/carbon/human/H = target
eye_color = H.eye_color
return TRUE
/obj/item/implant/hijack/removed(mob/living/source, silent = FALSE, special = 0)
if(..())
REMOVE_TRAIT(source, TRAIT_HIJACKER, "implant")
for (var/area/area in source.siliconaccessareas)
source.toggleSiliconAccessArea(area)
var/obj/machinery/power/apc/apc = area.get_apc()
if (apc)
apc.hijacker = null
apc.set_hijacked_lighting()
apc.update_icon()
if (ishuman(source))
var/mob/living/carbon/human/H = source
H.eye_color = eye_color
return TRUE
/obj/item/implant/hijack/proc/InterceptClickOn(mob/living/user,params,atom/object)
if (isitem(object) || !toggled || user.incapacitated())
return
if (stealthmode == FALSE && istype(object,/obj/machinery/power/apc) && !user.CanReach(object))
if (hijack_remotely(object))
return
if (stealthmode && !user.CanReach(object))
return
if (!object.hasSiliconAccessInArea(imp_in))
return
var/list/modifiers = params2list(params)
imp_in.face_atom(object)
if (modifiers["shift"] && modifiers["ctrl"])
object.AICtrlShiftClick(imp_in)
return TRUE
if (modifiers["shift"])
object.AIShiftClick(imp_in)
return TRUE
if (modifiers["ctrl"])
object.AICtrlClick(imp_in)
return TRUE
if (modifiers["alt"])
object.AIAltClick(imp_in)
return TRUE
if (user.get_active_held_item())
return
if (user.CanReach(object))
object.attack_robot(imp_in)
else
object.attack_ai(imp_in)
return TRUE
/obj/item/implant/hijack/proc/hijack_remotely(obj/machinery/power/apc/apc)
if (apc.hijacker || hijacking)
return FALSE //can't remotely hijack an already hijacked APC
hijacking = TRUE
to_chat(imp_in, "<span class='notice'>Establishing remote connection with APC.</span>")
if (!do_after(imp_in, 4 SECONDS,target=apc))
to_chat(imp_in, "<span class='warning'>Aborting.</span>")
hijacking = FALSE
return TRUE
if (LAZYLEN(imp_in.siliconaccessareas) >= HIJACK_APC_MAX_AMOUNT)
to_chat(src,"<span class='warning'>You are connected to too many APCs! Too many more will fry your brain.</span>")
hijacking = FALSE
return TRUE
imp_in.light_power = 2
imp_in.light_range = 2
imp_in.light_color = COLOR_YELLOW
imp_in.update_light()
imp_in.visible_message("<span class='warning'>[imp_in] starts glowing a with a hollow yellow light!</span>")
to_chat(imp_in, "<span class='notice'>Beginning hijack of APC.</span>")
if (do_after(imp_in, 21 SECONDS,target=apc))
apc.hijacker = imp_in
stealthmode = FALSE
apc.set_hijacked_lighting()
imp_in.toggleSiliconAccessArea(apc.area)
apc.update_icon()
stealthcooldown = world.time + 1 MINUTES + 30 SECONDS
toggle_eyes()
else
to_chat(imp_in, "<span class='warning'>Aborting.</span>")
hijacking = FALSE
imp_in.light_power = 0
imp_in.light_range = 0
imp_in.light_color = COLOR_YELLOW
imp_in.update_light()
return TRUE
@@ -21,7 +21,7 @@
if (!spell)
return FALSE
if (autorobeless && spell.clothes_req)
spell.clothes_req = FALSE
spell.clothes_req = NONE
target.AddSpell(spell)
return TRUE
@@ -9,19 +9,15 @@
throw_speed = 2
throw_range = 5
w_class = WEIGHT_CLASS_TINY
materials = list(MAT_GLASS=500)
var/obj/item/implant/imp = null
custom_materials = list(/datum/material/glass=500)
var/obj/item/implant/imp
var/imp_type
/obj/item/implantcase/update_icon()
/obj/item/implantcase/update_icon_state()
if(imp)
icon_state = "implantcase-[imp.item_color]"
reagents = imp.reagents
else
icon_state = "implantcase-0"
reagents = null
/obj/item/implantcase/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pen))
@@ -46,6 +42,7 @@
imp = I.imp
I.imp = null
update_icon()
reagents = imp.reagents
I.update_icon()
else
if(imp)
@@ -54,6 +51,7 @@
imp.forceMove(I)
I.imp = imp
imp = null
reagents = null
update_icon()
I.update_icon()
@@ -96,16 +96,17 @@
visible_message("<span class='warning'>[M] has been implanted by [src].</span>")
return TRUE
/obj/machinery/implantchair/update_icon()
/obj/machinery/implantchair/update_icon_state()
icon_state = initial(icon_state)
if(state_open)
icon_state += "_open"
if(occupant)
icon_state += "_occupied"
/obj/machinery/implantchair/update_overlays()
. = ..()
if(ready)
add_overlay("ready")
else
cut_overlays()
. += "ready"
/obj/machinery/implantchair/proc/replenish()
if(ready_implants < max_implants)
@@ -9,18 +9,17 @@
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=600, MAT_GLASS=200)
custom_materials = list(/datum/material/iron=600, /datum/material/glass=200)
var/obj/item/implant/imp = null
var/imp_type = null
/obj/item/implanter/update_icon()
/obj/item/implanter/update_icon_state()
if(imp)
icon_state = "implanter1"
else
icon_state = "implanter0"
/obj/item/implanter/attack(mob/living/M, mob/user)
if(!istype(M))
return
@@ -74,4 +73,8 @@
/obj/item/implanter/stealth
name = "implanter (stealth)"
imp_type = /obj/item/implant/stealth
imp_type = /obj/item/implant/stealth
/obj/item/implanter/hijack
name = "implanter (hijack)"
imp_type = /obj/item/implant/hijack
@@ -18,7 +18,7 @@
if(case)
. += "<span class='notice'>Alt-click [src] to remove the inserted implant case.</span>"
/obj/item/implantpad/update_icon()
/obj/item/implantpad/update_icon_state()
icon_state = "implantpad-[case ? TRUE : FALSE]"
/obj/item/implantpad/AltClick(mob/user)

Some files were not shown because too many files have changed in this diff Show More