Merge branch 'master' into crewobjectivesandmiscreants
This commit is contained in:
@@ -62,7 +62,7 @@
|
||||
M.setDir(dir)
|
||||
buckled_mobs |= M
|
||||
M.update_canmove()
|
||||
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src)
|
||||
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled)
|
||||
post_buckle_mob(M)
|
||||
|
||||
return TRUE
|
||||
@@ -131,5 +131,3 @@
|
||||
"<span class='italics'>You hear metal clanking.</span>")
|
||||
add_fingerprint(user)
|
||||
return M
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
var/obj/effect/countdown/anomaly/countdown
|
||||
|
||||
/obj/effect/anomaly/Initialize(mapload, new_lifespan)
|
||||
..()
|
||||
. = ..()
|
||||
GLOB.poi_list |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
impact_area = get_area(src)
|
||||
|
||||
@@ -97,21 +97,6 @@
|
||||
var/completion = round(C.get_completion())
|
||||
return completion
|
||||
|
||||
/obj/effect/countdown/dominator
|
||||
name = "dominator countdown"
|
||||
text_size = 1
|
||||
color = "#ff00ff" // Overwritten when the dominator starts
|
||||
|
||||
/obj/effect/countdown/dominator/get_value()
|
||||
var/obj/machinery/dominator/D = attached_to
|
||||
if(!istype(D))
|
||||
return
|
||||
else if(D.gang && D.gang.is_dominating)
|
||||
var/timer = D.gang.domination_time_remaining()
|
||||
return timer
|
||||
else
|
||||
return "OFFLINE"
|
||||
|
||||
/obj/effect/countdown/clockworkgate
|
||||
name = "gateway countdown"
|
||||
text_size = 1
|
||||
|
||||
@@ -1,91 +1,91 @@
|
||||
/obj/effect/decal/cleanable
|
||||
gender = PLURAL
|
||||
layer = ABOVE_NORMAL_TURF_LAYER
|
||||
var/list/random_icon_states = list()
|
||||
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
|
||||
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
|
||||
var/mergeable_decal = 1 //when two of these are on a same tile or do we need to merge them into just one?
|
||||
|
||||
/obj/effect/decal/cleanable/Initialize(mapload)
|
||||
if (random_icon_states && length(src.random_icon_states) > 0)
|
||||
src.icon_state = pick(src.random_icon_states)
|
||||
create_reagents(300)
|
||||
if(src.loc && isturf(src.loc))
|
||||
for(var/obj/effect/decal/cleanable/C in src.loc)
|
||||
if(C != src && C.type == src.type)
|
||||
replace_decal(C)
|
||||
..()
|
||||
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C)
|
||||
if(mergeable_decal)
|
||||
qdel(C)
|
||||
|
||||
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks))
|
||||
if(src.reagents && W.reagents)
|
||||
. = 1 //so the containers don't splash their content on the src while scooping.
|
||||
if(!src.reagents.total_volume)
|
||||
to_chat(user, "<span class='notice'>[src] isn't thick enough to scoop up!</span>")
|
||||
return
|
||||
if(W.reagents.total_volume >= W.reagents.maximum_volume)
|
||||
to_chat(user, "<span class='notice'>[W] is full!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You scoop up [src] into [W]!</span>")
|
||||
reagents.trans_to(W, reagents.total_volume)
|
||||
if(!reagents.total_volume) //scooped up all of it
|
||||
qdel(src)
|
||||
return
|
||||
if(W.is_hot()) //todo: make heating a reagent holder proc
|
||||
if(istype(W, /obj/item/clothing/mask/cigarette))
|
||||
return
|
||||
else
|
||||
var/hotness = W.is_hot()
|
||||
var/added_heat = (hotness / 100)
|
||||
src.reagents.chem_temp = min(src.reagents.chem_temp + added_heat, hotness)
|
||||
src.reagents.handle_reactions()
|
||||
to_chat(user, "<span class='notice'>You heat [src] with [W]!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/effect/decal/cleanable/ex_act()
|
||||
if(reagents)
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
R.on_ex_act()
|
||||
..()
|
||||
|
||||
/obj/effect/decal/cleanable/fire_act(exposed_temperature, exposed_volume)
|
||||
if(reagents)
|
||||
reagents.chem_temp += 30
|
||||
reagents.handle_reactions()
|
||||
..()
|
||||
|
||||
|
||||
//Add "bloodiness" of this blood's type, to the human's shoes
|
||||
//This is on /cleanable because fuck this ancient mess
|
||||
/obj/effect/decal/cleanable/Crossed(atom/movable/O)
|
||||
if(ishuman(O))
|
||||
var/mob/living/carbon/human/H = O
|
||||
if(H.shoes && blood_state && bloodiness)
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
var/add_blood = 0
|
||||
if(bloodiness >= BLOOD_GAIN_PER_STEP)
|
||||
add_blood = BLOOD_GAIN_PER_STEP
|
||||
else
|
||||
add_blood = bloodiness
|
||||
bloodiness -= add_blood
|
||||
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS,S.bloody_shoes[blood_state]+add_blood)
|
||||
if(blood_DNA && blood_DNA.len)
|
||||
S.add_blood(blood_DNA)
|
||||
S.blood_state = blood_state
|
||||
update_icon()
|
||||
H.update_inv_shoes()
|
||||
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
|
||||
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
|
||||
return bloodiness
|
||||
else
|
||||
return 0
|
||||
/obj/effect/decal/cleanable
|
||||
gender = PLURAL
|
||||
layer = ABOVE_NORMAL_TURF_LAYER
|
||||
var/list/random_icon_states = list()
|
||||
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
|
||||
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
|
||||
var/mergeable_decal = 1 //when two of these are on a same tile or do we need to merge them into just one?
|
||||
|
||||
/obj/effect/decal/cleanable/Initialize(mapload)
|
||||
if (random_icon_states && length(src.random_icon_states) > 0)
|
||||
src.icon_state = pick(src.random_icon_states)
|
||||
create_reagents(300)
|
||||
if(src.loc && isturf(src.loc))
|
||||
for(var/obj/effect/decal/cleanable/C in src.loc)
|
||||
if(C != src && C.type == src.type)
|
||||
replace_decal(C)
|
||||
. = ..()
|
||||
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C)
|
||||
if(mergeable_decal)
|
||||
qdel(C)
|
||||
|
||||
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks))
|
||||
if(src.reagents && W.reagents)
|
||||
. = 1 //so the containers don't splash their content on the src while scooping.
|
||||
if(!src.reagents.total_volume)
|
||||
to_chat(user, "<span class='notice'>[src] isn't thick enough to scoop up!</span>")
|
||||
return
|
||||
if(W.reagents.total_volume >= W.reagents.maximum_volume)
|
||||
to_chat(user, "<span class='notice'>[W] is full!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You scoop up [src] into [W]!</span>")
|
||||
reagents.trans_to(W, reagents.total_volume)
|
||||
if(!reagents.total_volume) //scooped up all of it
|
||||
qdel(src)
|
||||
return
|
||||
if(W.is_hot()) //todo: make heating a reagent holder proc
|
||||
if(istype(W, /obj/item/clothing/mask/cigarette))
|
||||
return
|
||||
else
|
||||
var/hotness = W.is_hot()
|
||||
var/added_heat = (hotness / 100)
|
||||
src.reagents.chem_temp = min(src.reagents.chem_temp + added_heat, hotness)
|
||||
src.reagents.handle_reactions()
|
||||
to_chat(user, "<span class='notice'>You heat [src] with [W]!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/effect/decal/cleanable/ex_act()
|
||||
if(reagents)
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
R.on_ex_act()
|
||||
..()
|
||||
|
||||
/obj/effect/decal/cleanable/fire_act(exposed_temperature, exposed_volume)
|
||||
if(reagents)
|
||||
reagents.chem_temp += 30
|
||||
reagents.handle_reactions()
|
||||
..()
|
||||
|
||||
|
||||
//Add "bloodiness" of this blood's type, to the human's shoes
|
||||
//This is on /cleanable because fuck this ancient mess
|
||||
/obj/effect/decal/cleanable/Crossed(atom/movable/O)
|
||||
if(ishuman(O))
|
||||
var/mob/living/carbon/human/H = O
|
||||
if(H.shoes && blood_state && bloodiness)
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
var/add_blood = 0
|
||||
if(bloodiness >= BLOOD_GAIN_PER_STEP)
|
||||
add_blood = BLOOD_GAIN_PER_STEP
|
||||
else
|
||||
add_blood = bloodiness
|
||||
bloodiness -= add_blood
|
||||
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS,S.bloody_shoes[blood_state]+add_blood)
|
||||
if(blood_DNA && blood_DNA.len)
|
||||
S.add_blood(blood_DNA)
|
||||
S.blood_state = blood_state
|
||||
update_icon()
|
||||
H.update_inv_shoes()
|
||||
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
|
||||
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
|
||||
return bloodiness
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
bloodiness = 0
|
||||
|
||||
/obj/effect/decal/cleanable/blood/old/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
icon_state += "-old" //This IS necessary because the parent /blood type uses icon randomization.
|
||||
blood_DNA["Non-human DNA"] = "A+"
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
mergeable_decal = 0
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
reagents.add_reagent("liquidgibs", 5)
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
|
||||
@@ -94,7 +94,7 @@
|
||||
bloodiness = 0
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/old/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
setDir(pick(1,2,4,8))
|
||||
icon_state += "-old"
|
||||
blood_DNA["Non-human DNA"] = "A+"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
mergeable_decal = 0
|
||||
|
||||
/obj/effect/decal/cleanable/ash/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
reagents.add_reagent("ash", 30)
|
||||
pixel_x = rand(-5, 5)
|
||||
pixel_y = rand(-5, 5)
|
||||
@@ -22,7 +22,7 @@
|
||||
icon_state = "big_ash"
|
||||
|
||||
/obj/effect/decal/cleanable/ash/large/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
reagents.add_reagent("ash", 30) //double the amount of ash.
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
icon_state = "greenglow"
|
||||
|
||||
/obj/effect/decal/cleanable/greenglow/Initialize(mapload)
|
||||
..()
|
||||
. = ..()
|
||||
set_light(1)
|
||||
|
||||
/obj/effect/decal/cleanable/greenglow/ex_act()
|
||||
@@ -102,7 +102,7 @@
|
||||
desc = "You try not to look at the chunks, and fail."
|
||||
|
||||
/obj/effect/decal/cleanable/vomit/old/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
icon_state += "-old"
|
||||
|
||||
/obj/effect/decal/cleanable/tomato_smudge
|
||||
@@ -153,7 +153,7 @@
|
||||
/obj/effect/decal/cleanable/shreds/Initialize()
|
||||
pixel_x = rand(-10, 10)
|
||||
pixel_y = rand(-10, 10)
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/obj/effect/decal/cleanable/salt
|
||||
name = "salt pile"
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
bloodiness = MAX_SHOE_BLOODINESS
|
||||
|
||||
/obj/effect/decal/cleanable/oil/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
reagents.add_reagent("oil", 30)
|
||||
|
||||
/obj/effect/decal/cleanable/oil/streak
|
||||
|
||||
@@ -7,12 +7,10 @@
|
||||
var/do_icon_rotate = TRUE
|
||||
|
||||
/obj/effect/decal/cleanable/crayon/Initialize(mapload, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune", var/rotation = 0, var/alt_icon = null)
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
name = e_name
|
||||
desc = "A [name] vandalizing the station."
|
||||
if(type == "poseur tag")
|
||||
type = pick(GLOB.gang_name_pool)
|
||||
|
||||
if(alt_icon)
|
||||
icon = alt_icon
|
||||
@@ -24,41 +22,3 @@
|
||||
src.transform = M
|
||||
|
||||
add_atom_colour(main, FIXED_COLOUR_PRIORITY)
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/crayon/gang
|
||||
layer = HIGH_OBJ_LAYER //Harder to hide
|
||||
do_icon_rotate = FALSE //These are designed to always face south, so no rotation please.
|
||||
var/datum/gang/gang
|
||||
var/datum/mind/user_mind
|
||||
var/area/territory
|
||||
|
||||
/obj/effect/decal/cleanable/crayon/gang/Initialize(mapload, var/datum/gang/G, var/e_name = "gang tag", var/rotation = 0, var/mob/user)
|
||||
if(!type || !G)
|
||||
qdel(src)
|
||||
user_mind = user.mind
|
||||
territory = get_area(src)
|
||||
gang = G
|
||||
var/newcolor = G.color_hex
|
||||
icon_state = G.name
|
||||
G.territory_new |= list(territory.type = territory.name)
|
||||
//If this isn't tagged by a specific gangster there's no bonus income.
|
||||
set_mind_owner(user_mind)
|
||||
..(mapload, newcolor, icon_state, e_name, rotation)
|
||||
|
||||
/obj/effect/decal/cleanable/crayon/gang/proc/set_mind_owner(datum/mind/mind)
|
||||
if(istype(user_mind) && istype(gang) && islist(gang.tags_by_mind[user_mind])) //Clear us out of old ownership
|
||||
gang.tags_by_mind[user_mind] -= src
|
||||
if(istype(mind))
|
||||
if(!islist(gang.tags_by_mind[mind]))
|
||||
gang.tags_by_mind[mind] = list()
|
||||
gang.tags_by_mind[mind] += src
|
||||
user_mind = mind
|
||||
|
||||
/obj/effect/decal/cleanable/crayon/gang/Destroy()
|
||||
if(gang)
|
||||
gang.territory -= territory.type
|
||||
set_mind_owner(null)
|
||||
gang.territory_new -= territory.type
|
||||
gang.territory_lost |= list(territory.type = territory.name)
|
||||
return ..()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
duration = 25
|
||||
|
||||
/obj/effect/temp_visual/point/Initialize(mapload, set_invis = 0)
|
||||
..()
|
||||
. = ..()
|
||||
var/atom/old_loc = loc
|
||||
loc = get_turf(src)
|
||||
pixel_x = old_loc.pixel_x
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
sleep(10)
|
||||
animate(victim.client,color = old_color, time = duration)//, easing = SINE_EASING|EASE_OUT)
|
||||
sleep(duration)
|
||||
to_chat(victim, "<span class='notice'>Your bloodlust seeps back into the bog of your subconscious and you regain self control.<span>")
|
||||
to_chat(victim, "<span class='notice'>Your bloodlust seeps back into the bog of your subconscious and you regain self control.</span>")
|
||||
qdel(chainsaw)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
pressure_resistance = 4
|
||||
var/obj/item/master = null
|
||||
|
||||
var/heat_protection = 0 //flags_1 which determine which body parts are protected from heat. Use the HEAD, CHEST, GROIN, etc. flags_1. See setup.dm
|
||||
var/cold_protection = 0 //flags_1 which determine which body parts are protected from cold. Use the HEAD, CHEST, GROIN, etc. flags_1. See setup.dm
|
||||
var/max_heat_protection_temperature //Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags_1
|
||||
var/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags_1
|
||||
var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm
|
||||
var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm
|
||||
var/max_heat_protection_temperature //Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags
|
||||
var/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags
|
||||
|
||||
var/list/actions //list of /datum/action's that this item has.
|
||||
var/list/actions_types //list of paths of action datums to give to the item on New().
|
||||
@@ -48,7 +48,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
|
||||
var/item_color = null //this needs deprecating, soonish
|
||||
|
||||
var/body_parts_covered = 0 //see setup.dm for appropriate bit flags_1
|
||||
var/body_parts_covered = 0 //see setup.dm for appropriate bit flags
|
||||
//var/heat_transfer_coefficient = 1 //0 prevents all transfers, 1 is invisible
|
||||
var/gas_transfer_coefficient = 1 // for leaking gas from turf to mask and vice-versa (for masks right now, but at some point, i'd like to include space helmets)
|
||||
var/permeability_coefficient = 1 // for chemicals/diseases
|
||||
@@ -64,6 +64,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
var/list/materials
|
||||
var/origin_tech = null //Used by R&D to determine what research bonuses it grants.
|
||||
var/needs_permit = 0 //Used by security bots to determine if this item is safe for public use.
|
||||
var/emagged = FALSE
|
||||
|
||||
var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
|
||||
var/list/species_exception = null // list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item
|
||||
@@ -86,7 +87,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
var/embedded_unsafe_removal_pain_multiplier = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage removing this without surgery causes (this*w_class)
|
||||
var/embedded_unsafe_removal_time = EMBEDDED_UNSAFE_REMOVAL_TIME //A time in ticks, multiplied by the w_class.
|
||||
|
||||
var/flags_cover = 0 //for flags_1 such as GLASSESCOVERSEYES
|
||||
var/flags_cover = 0 //for flags such as GLASSESCOVERSEYES
|
||||
var/heat = 0
|
||||
var/sharpness = IS_BLUNT
|
||||
var/toolspeed = 1
|
||||
@@ -114,6 +115,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
|
||||
var/trigger_guard = TRIGGER_GUARD_NONE
|
||||
|
||||
var/icon_override = null
|
||||
|
||||
/obj/item/Initialize()
|
||||
if (!materials)
|
||||
materials = list()
|
||||
@@ -128,6 +131,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
if(force_string)
|
||||
force_string_override = TRUE
|
||||
|
||||
if(!hitsound)
|
||||
if(damtype == "fire")
|
||||
hitsound = 'sound/items/welder.ogg'
|
||||
if(damtype == "brute")
|
||||
hitsound = "swing_hit"
|
||||
|
||||
/obj/item/Destroy()
|
||||
flags_1 &= ~DROPDEL_1 //prevent reqdels
|
||||
if(ismob(loc))
|
||||
@@ -542,9 +551,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
transfer_blood = 0
|
||||
|
||||
/obj/item/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FOUR)
|
||||
throw_at(S,14,3, spin=0)
|
||||
else ..()
|
||||
else return
|
||||
|
||||
/obj/item/throw_impact(atom/A)
|
||||
if(A && !QDELETED(A))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -74,7 +74,7 @@ obj/item/construction
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
to_chat(user, "<span class='notice'>You insert [amount_to_use] [S.name] sheets into the [src]. </span>")
|
||||
return 1
|
||||
to_chat(user, "<span class='warning'>You can't insert any more [S.name] sheets into the [src]!")
|
||||
to_chat(user, "<span class='warning'>You can't insert any more [S.name] sheets into the [src]!</span>")
|
||||
return 0
|
||||
|
||||
/obj/item/construction/proc/activate()
|
||||
|
||||
@@ -123,7 +123,6 @@ RSF
|
||||
var/toxin = 0
|
||||
var/cooldown = 0
|
||||
var/cooldowndelay = 10
|
||||
var/emagged = FALSE
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/cookiesynth/examine(mob/user)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
icon = 'icons/obj/chronos.dmi'
|
||||
icon_state = "chronobackpack"
|
||||
item_state = "backpack"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/backpack_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = SLOT_BACK
|
||||
slowdown = 1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -212,7 +212,6 @@
|
||||
build_path = /obj/machinery/computer/cargo
|
||||
origin_tech = "programming=3"
|
||||
var/contraband = FALSE
|
||||
var/emagged = FALSE
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/device/multitool))
|
||||
@@ -258,22 +257,6 @@
|
||||
build_path = /obj/machinery/computer/telecomms/server
|
||||
origin_tech = "programming=3;magnets=3;bluespace=2"
|
||||
|
||||
/obj/item/circuitboard/computer/shuttle
|
||||
name = "Shuttle (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle
|
||||
var/shuttleId
|
||||
var/possible_destinations = ""
|
||||
|
||||
/obj/item/circuitboard/computer/shuttle/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/device/multitool))
|
||||
var/chosen_id = round(input(usr, "Choose an ID number (-1 for reset):", "Input an Integer", null) as num|null)
|
||||
if(chosen_id >= 0)
|
||||
shuttleId = chosen_id
|
||||
else
|
||||
shuttleId = initial(shuttleId)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/circuitboard/computer/labor_shuttle
|
||||
name = "Labor Shuttle (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/labor
|
||||
@@ -340,7 +323,7 @@
|
||||
build_path = /obj/machinery/computer/apc_control
|
||||
origin_tech = "programming=3;engineering=3;powerstorage=2"
|
||||
|
||||
/obj/item/circuitboard/computer/shuttle/monastery_shuttle
|
||||
/obj/item/circuitboard/computer/monastery_shuttle
|
||||
name = "Monastery Shuttle (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/monastery_shuttle
|
||||
|
||||
|
||||
@@ -720,4 +720,12 @@
|
||||
/obj/item/stock_parts/matter_bin = 1,
|
||||
/obj/item/stack/cable_coil = 2,
|
||||
/obj/item/stock_parts/console_screen = 1,
|
||||
/obj/item/stack/sheet/glass = 1)
|
||||
/obj/item/stack/sheet/glass = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/vending/donksofttoyvendor
|
||||
name = "Donksoft Toy Vendor (Machine Board)"
|
||||
build_path = /obj/machinery/vending/donksofttoyvendor
|
||||
origin_tech = "programming=1;syndicate=2"
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/console_screen = 1,
|
||||
/obj/item/vending_refill/donksoft = 3)
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
/obj/item/soap/suicide_act(mob/user)
|
||||
user.say(";FFFFFFFFFFFFFFFFUUUUUUUDGE!!")
|
||||
user.visible_message("<span class='suicide'>[user] lifts [src] to their mouth and gnaws on it furiously, producing a thick froth! [user.p_they(TRUE)]'ll never get that BB gun now!")
|
||||
user.visible_message("<span class='suicide'>[user] lifts [src] to their mouth and gnaws on it furiously, producing a thick froth! [user.p_they(TRUE)]'ll never get that BB gun now!</span>")
|
||||
new /obj/effect/particle_effect/foam(loc)
|
||||
return (TOXLOSS)
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
var/self_contained = TRUE // If it deletes itself when it is empty
|
||||
|
||||
var/list/validSurfaces = list(/turf/open/floor)
|
||||
var/gang = FALSE //For marking territory
|
||||
|
||||
var/edible = TRUE // That doesn't mean eating it is a good idea
|
||||
|
||||
@@ -278,15 +277,6 @@
|
||||
else if(drawing in numerals)
|
||||
temp = "number"
|
||||
|
||||
// If a gang member is using a gang spraycan, it'll behave differently
|
||||
var/gang_mode = FALSE
|
||||
if(gang && user.mind && user.mind.gang_datum)
|
||||
gang_mode = TRUE
|
||||
|
||||
// discontinue if the area isn't valid for tagging because gang "honour"
|
||||
if(gang_mode && (!can_claim_for_gang(user, target)))
|
||||
return
|
||||
|
||||
var/graf_rot
|
||||
if(drawing in oriented)
|
||||
switch(user.dir)
|
||||
@@ -307,8 +297,6 @@
|
||||
playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5)
|
||||
|
||||
var/takes_time = !instant
|
||||
if(gang_mode)
|
||||
takes_time = TRUE
|
||||
|
||||
var/wait_time = 50
|
||||
if(PAINT_LARGE_HORIZONTAL)
|
||||
@@ -325,28 +313,21 @@
|
||||
var/list/turf/affected_turfs = list()
|
||||
|
||||
if(actually_paints)
|
||||
if(gang_mode)
|
||||
// Double check it wasn't tagged in the meanwhile
|
||||
if(!can_claim_for_gang(user, target))
|
||||
return
|
||||
tag_for_gang(user, target)
|
||||
affected_turfs += target
|
||||
else
|
||||
switch(paint_mode)
|
||||
if(PAINT_NORMAL)
|
||||
new /obj/effect/decal/cleanable/crayon(target, paint_color, drawing, temp, graf_rot)
|
||||
switch(paint_mode)
|
||||
if(PAINT_NORMAL)
|
||||
new /obj/effect/decal/cleanable/crayon(target, paint_color, drawing, temp, graf_rot)
|
||||
affected_turfs += target
|
||||
if(PAINT_LARGE_HORIZONTAL)
|
||||
var/turf/left = locate(target.x-1,target.y,target.z)
|
||||
var/turf/right = locate(target.x+1,target.y,target.z)
|
||||
if(is_type_in_list(left, validSurfaces) && is_type_in_list(right, validSurfaces))
|
||||
new /obj/effect/decal/cleanable/crayon(left, paint_color, drawing, temp, graf_rot, PAINT_LARGE_HORIZONTAL_ICON)
|
||||
affected_turfs += left
|
||||
affected_turfs += right
|
||||
affected_turfs += target
|
||||
if(PAINT_LARGE_HORIZONTAL)
|
||||
var/turf/left = locate(target.x-1,target.y,target.z)
|
||||
var/turf/right = locate(target.x+1,target.y,target.z)
|
||||
if(is_type_in_list(left, validSurfaces) && is_type_in_list(right, validSurfaces))
|
||||
new /obj/effect/decal/cleanable/crayon(left, paint_color, drawing, temp, graf_rot, PAINT_LARGE_HORIZONTAL_ICON)
|
||||
affected_turfs += left
|
||||
affected_turfs += right
|
||||
affected_turfs += target
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There isn't enough space to paint!</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There isn't enough space to paint!</span>")
|
||||
return
|
||||
|
||||
if(!instant)
|
||||
to_chat(user, "<span class='notice'>You finish drawing \the [temp].</span>")
|
||||
@@ -385,47 +366,6 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/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)
|
||||
if(!A || (A.z != ZLEVEL_STATION) || !A.valid_territory)
|
||||
to_chat(user, "<span class='warning'>[A] is unsuitable for tagging.</span>")
|
||||
return FALSE
|
||||
|
||||
var/spraying_over = FALSE
|
||||
for(var/obj/effect/decal/cleanable/crayon/gang/G in target)
|
||||
spraying_over = TRUE
|
||||
|
||||
for(var/obj/machinery/power/apc in target)
|
||||
to_chat(user, "<span class='warning'>You can't tag an APC.</span>")
|
||||
return FALSE
|
||||
|
||||
var/occupying_gang = territory_claimed(A, user)
|
||||
if(occupying_gang && !spraying_over)
|
||||
to_chat(user, "<span class='danger'>[A] has already been tagged by the [occupying_gang] gang! You must get rid of or spray over the old tag first!</span>")
|
||||
return FALSE
|
||||
|
||||
// If you pass the gaunlet of checks, you're good to proceed
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/crayon/proc/territory_claimed(area/territory, mob/user)
|
||||
for(var/datum/gang/G in SSticker.mode.gangs)
|
||||
if(territory.type in (G.territory|G.territory_new))
|
||||
. = G.name
|
||||
break
|
||||
|
||||
/obj/item/toy/crayon/proc/tag_for_gang(mob/user, atom/target)
|
||||
//Delete any old markings on this tile, including other gang tags
|
||||
for(var/obj/effect/decal/cleanable/crayon/old_marking in target)
|
||||
qdel(old_marking)
|
||||
|
||||
var/gangID = user.mind.gang_datum
|
||||
var/area/territory = get_area(target)
|
||||
|
||||
new /obj/effect/decal/cleanable/crayon/gang(target,gangID,"graffiti",0,user)
|
||||
to_chat(user, "<span class='notice'>You tagged [territory] for your gang!</span>")
|
||||
|
||||
/obj/item/toy/crayon/red
|
||||
icon_state = "crayonred"
|
||||
paint_color = "#DA0000"
|
||||
@@ -676,25 +616,9 @@
|
||||
spray_overlay.color = paint_color
|
||||
add_overlay(spray_overlay)
|
||||
|
||||
/obj/item/toy/crayon/spraycan/gang
|
||||
//desc = "A modified container containing suspicious paint."
|
||||
charges = 20
|
||||
gang = TRUE
|
||||
|
||||
pre_noise = FALSE
|
||||
post_noise = TRUE
|
||||
|
||||
/obj/item/toy/crayon/spraycan/gang/New(loc, datum/gang/G)
|
||||
..()
|
||||
if(G)
|
||||
paint_color = G.color_hex
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/crayon/spraycan/gang/examine(mob/user)
|
||||
. = ..()
|
||||
if((user.mind && user.mind.gang_datum) || isobserver(user))
|
||||
to_chat(user, "This spraycan has been specially modified for tagging territory.")
|
||||
|
||||
/obj/item/toy/crayon/spraycan/borg
|
||||
name = "cyborg spraycan"
|
||||
desc = "A metallic container containing shiny synthesised paint."
|
||||
|
||||
@@ -135,10 +135,10 @@
|
||||
/obj/item/defibrillator/emag_act(mob/user)
|
||||
if(safety)
|
||||
safety = 0
|
||||
to_chat(user, "<span class='warning'>You silently disable [src]'s safety protocols with the cryptographic sequencer.")
|
||||
to_chat(user, "<span class='warning'>You silently disable [src]'s safety protocols with the cryptographic sequencer.</span>")
|
||||
else
|
||||
safety = 1
|
||||
to_chat(user, "<span class='notice'>You silently enable [src]'s safety protocols with the cryptographic sequencer.")
|
||||
to_chat(user, "<span class='notice'>You silently enable [src]'s safety protocols with the cryptographic sequencer.</span>")
|
||||
|
||||
/obj/item/defibrillator/emp_act(severity)
|
||||
if(cell)
|
||||
@@ -497,7 +497,7 @@
|
||||
update_icon()
|
||||
return
|
||||
if(H.stat == DEAD)
|
||||
H.visible_message("<span class='warning'>[H]'s body convulses a bit.")
|
||||
H.visible_message("<span class='warning'>[H]'s body convulses a bit.</span>")
|
||||
playsound(get_turf(src), "bodyfall", 50, 1)
|
||||
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
total_brute = H.getBruteLoss()
|
||||
|
||||
@@ -30,7 +30,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
//Secondary variables
|
||||
var/scanmode = 0 //1 is medical scanner, 2 is forensics, 3 is reagent scanner.
|
||||
var/fon = 0 //Is the flashlight function on?
|
||||
var/f_lum = 3 //Luminosity for the flashlight function
|
||||
var/f_lum = 2.3 //Luminosity for the flashlight function
|
||||
var/silent = 0 //To beep or not to beep, that is the question
|
||||
var/toff = 0 //If 1, messenger disabled
|
||||
var/tnote = null //Current Texts
|
||||
@@ -352,9 +352,9 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
if(fon)
|
||||
fon = 0
|
||||
set_light(0)
|
||||
else
|
||||
else if(f_lum)
|
||||
fon = 1
|
||||
set_light(2.3)
|
||||
set_light(f_lum)
|
||||
update_icon()
|
||||
if("Medical Scan")
|
||||
if(scanmode == 1)
|
||||
@@ -856,7 +856,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
var/list/plist = list()
|
||||
var/list/namecounts = list()
|
||||
|
||||
if(user.stat == 2)
|
||||
if(user.stat == DEAD)
|
||||
return //won't work if dead
|
||||
|
||||
if(src.aiPDA.toff)
|
||||
@@ -889,7 +889,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
/mob/living/silicon/ai/verb/cmd_toggle_pda_receiver()
|
||||
set category = "AI Commands"
|
||||
set name = "PDA - Toggle Sender/Receiver"
|
||||
if(usr.stat == 2)
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
if(!isnull(aiPDA))
|
||||
aiPDA.toff = !aiPDA.toff
|
||||
@@ -900,7 +900,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
/mob/living/silicon/ai/verb/cmd_toggle_pda_silent()
|
||||
set category = "AI Commands"
|
||||
set name = "PDA - Toggle Ringer"
|
||||
if(usr.stat == 2)
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
if(!isnull(aiPDA))
|
||||
//0
|
||||
@@ -910,7 +910,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
to_chat(usr, "You do not have a PDA. You should make an issue report about this.")
|
||||
|
||||
/mob/living/silicon/ai/proc/cmd_show_message_log(mob/user)
|
||||
if(user.stat == 2)
|
||||
if(user.stat == DEAD)
|
||||
return //won't work if dead
|
||||
if(!isnull(aiPDA))
|
||||
var/HTML = "<html><head><title>AI PDA Message Log</title></head><body>[aiPDA.tnote]</body></html>"
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
access = CART_REAGENT_SCANNER | CART_ATMOS
|
||||
|
||||
/obj/item/cartridge/signal/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
radio = new /obj/item/radio/integrated/signal(src)
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
bot_access_flags = FLOOR_BOT | CLEAN_BOT | MED_BOT
|
||||
|
||||
/obj/item/cartridge/rd/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
radio = new /obj/item/radio/integrated/signal(src)
|
||||
|
||||
/obj/item/cartridge/captain
|
||||
@@ -302,7 +302,7 @@ Code:
|
||||
var/obj/machinery/power/apc/A = term.master
|
||||
L += A
|
||||
|
||||
menu += "<PRE>Total power: [powmonitor.attached.powernet.viewavail] W<BR>Total load: [num2text(powmonitor.attached.powernet.viewload,10)] W<BR>"
|
||||
menu += "<PRE>Total power: [DisplayPower(powmonitor.attached.powernet.viewavail)]<BR>Total load: [DisplayPower(powmonitor.attached.powernet.viewload)]<BR>"
|
||||
|
||||
menu += "<FONT SIZE=-1>"
|
||||
|
||||
@@ -314,7 +314,7 @@ Code:
|
||||
|
||||
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(A.lastused_total, 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]<BR>"
|
||||
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 += "</FONT></PRE>"
|
||||
|
||||
@@ -437,14 +437,14 @@ Code:
|
||||
switch(SSshuttle.supply.mode)
|
||||
if(SHUTTLE_CALL)
|
||||
menu += "Moving to "
|
||||
if(SSshuttle.supply.z != ZLEVEL_STATION)
|
||||
if(!(SSshuttle.supply.z in GLOB.station_z_levels))
|
||||
menu += "station"
|
||||
else
|
||||
menu += "centcom"
|
||||
menu += " ([SSshuttle.supply.timeLeft(600)] Mins)"
|
||||
else
|
||||
menu += "At "
|
||||
if(SSshuttle.supply.z != ZLEVEL_STATION)
|
||||
if(!(SSshuttle.supply.z in GLOB.station_z_levels))
|
||||
menu += "centcom"
|
||||
else
|
||||
menu += "station"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/integrated/signal/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
if (src.frequency < 1200 || src.frequency > 1600)
|
||||
src.frequency = sanitize_frequency(src.frequency)
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
return
|
||||
if(!isnull(target) && !target.toff)
|
||||
charges--
|
||||
var/lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
|
||||
var/lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
|
||||
to_chat(U, "<span class='notice'>Virus Sent! The unlock code to the target is: [lock_code]</span>")
|
||||
if(!target.hidden_uplink)
|
||||
var/obj/item/device/uplink/uplink = new(target)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
var/flashlight_power = 1 //strength of the light when on
|
||||
|
||||
/obj/item/device/flashlight/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
update_brightness()
|
||||
|
||||
/obj/item/device/flashlight/proc/update_brightness(mob/user = null)
|
||||
@@ -152,7 +152,7 @@
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[M] doesn't have any organs in [their] mouth.</span>")
|
||||
if(pill_count)
|
||||
to_chat(user, "<span class='notice'>[M] has [pill_count] pill[pill_count > 1 ? "s" : ""] implanted in [their] teeth.")
|
||||
to_chat(user, "<span class='notice'>[M] has [pill_count] pill[pill_count > 1 ? "s" : ""] implanted in [their] teeth.</span>")
|
||||
|
||||
else
|
||||
return ..()
|
||||
@@ -208,6 +208,8 @@
|
||||
desc = "A desk lamp with an adjustable mount."
|
||||
icon_state = "lamp"
|
||||
item_state = "lamp"
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
brightness_on = 5
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags_1 = CONDUCT_1
|
||||
@@ -407,7 +409,7 @@
|
||||
/obj/item/device/flashlight/glowstick/Initialize()
|
||||
fuel = rand(1600, 2000)
|
||||
light_color = color
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/obj/item/device/flashlight/glowstick/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
@@ -426,7 +428,7 @@
|
||||
|
||||
/obj/item/device/flashlight/glowstick/update_icon()
|
||||
item_state = "glowstick"
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(!fuel)
|
||||
icon_state = "glowstick-empty"
|
||||
cut_overlays()
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
materials = list(MAT_METAL = 150, MAT_GLASS = 150)
|
||||
var/scanning = 0
|
||||
var/radiation_count = 0
|
||||
var/emagged = FALSE
|
||||
|
||||
/obj/item/device/geiger_counter/New()
|
||||
..()
|
||||
|
||||
@@ -17,7 +17,7 @@ GLOBAL_LIST_EMPTY(GPS_list)
|
||||
|
||||
|
||||
/obj/item/device/gps/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
GLOB.GPS_list += src
|
||||
name = "global positioning system ([gpstag])"
|
||||
add_overlay("working")
|
||||
|
||||
@@ -1,65 +1,65 @@
|
||||
//copy pasta of the space piano, don't hurt me -Pete
|
||||
/obj/item/device/instrument
|
||||
name = "generic instrument"
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 100
|
||||
//copy pasta of the space piano, don't hurt me -Pete
|
||||
/obj/item/device/instrument
|
||||
name = "generic instrument"
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 100
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
lefthand_file = 'icons/mob/inhands/equipment/instruments_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/instruments_righthand.dmi'
|
||||
var/datum/song/handheld/song
|
||||
var/instrumentId = "generic"
|
||||
var/datum/song/handheld/song
|
||||
var/instrumentId = "generic"
|
||||
var/instrumentExt = "mid"
|
||||
|
||||
|
||||
/obj/item/device/instrument/Initialize()
|
||||
. = ..()
|
||||
song = new(instrumentId, src, instrumentExt)
|
||||
|
||||
/obj/item/device/instrument/Destroy()
|
||||
qdel(song)
|
||||
song = null
|
||||
return ..()
|
||||
|
||||
/obj/item/device/instrument/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] begins to play 'Gloomy Sunday'! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/device/instrument/Initialize(mapload)
|
||||
..()
|
||||
if(mapload)
|
||||
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
|
||||
|
||||
/obj/item/device/instrument/attack_self(mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return 1
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/instrument/interact(mob/user)
|
||||
if(!user)
|
||||
return
|
||||
|
||||
if(!isliving(user) || user.stat || user.restrained() || user.lying)
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
song.interact(user)
|
||||
|
||||
/obj/item/device/instrument/violin
|
||||
name = "space violin"
|
||||
desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
|
||||
icon_state = "violin"
|
||||
item_state = "violin"
|
||||
force = 10
|
||||
hitsound = "swing_hit"
|
||||
instrumentId = "violin"
|
||||
|
||||
/obj/item/device/instrument/violin/golden
|
||||
name = "golden violin"
|
||||
desc = "A golden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
|
||||
icon_state = "golden_violin"
|
||||
item_state = "golden_violin"
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
|
||||
/obj/item/device/instrument/Destroy()
|
||||
qdel(song)
|
||||
song = null
|
||||
return ..()
|
||||
|
||||
/obj/item/device/instrument/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] begins to play 'Gloomy Sunday'! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/device/instrument/Initialize(mapload)
|
||||
. = ..()
|
||||
if(mapload)
|
||||
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
|
||||
|
||||
/obj/item/device/instrument/attack_self(mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return 1
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/instrument/interact(mob/user)
|
||||
if(!user)
|
||||
return
|
||||
|
||||
if(!isliving(user) || user.stat || user.restrained() || user.lying)
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
song.interact(user)
|
||||
|
||||
/obj/item/device/instrument/violin
|
||||
name = "space violin"
|
||||
desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
|
||||
icon_state = "violin"
|
||||
item_state = "violin"
|
||||
force = 10
|
||||
hitsound = "swing_hit"
|
||||
instrumentId = "violin"
|
||||
|
||||
/obj/item/device/instrument/violin/golden
|
||||
name = "golden violin"
|
||||
desc = "A golden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
|
||||
icon_state = "golden_violin"
|
||||
item_state = "golden_violin"
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/device/instrument/piano_synth
|
||||
name = "synthesizer"
|
||||
desc = "An advanced electronic synthesizer that can be used as various instruments."
|
||||
@@ -74,26 +74,26 @@
|
||||
song.instrumentDir = name
|
||||
song.instrumentExt = insTypes[name]
|
||||
|
||||
/obj/item/device/instrument/guitar
|
||||
name = "guitar"
|
||||
desc = "It's made of wood and has bronze strings."
|
||||
icon_state = "guitar"
|
||||
item_state = "guitar"
|
||||
/obj/item/device/instrument/guitar
|
||||
name = "guitar"
|
||||
desc = "It's made of wood and has bronze strings."
|
||||
icon_state = "guitar"
|
||||
item_state = "guitar"
|
||||
instrumentExt = "ogg"
|
||||
force = 10
|
||||
attack_verb = list("played metal on", "serenaded", "crashed", "smashed")
|
||||
hitsound = 'sound/weapons/stringsmash.ogg'
|
||||
instrumentId = "guitar"
|
||||
|
||||
/obj/item/device/instrument/eguitar
|
||||
name = "electric guitar"
|
||||
desc = "Makes all your shredding needs possible."
|
||||
icon_state = "eguitar"
|
||||
item_state = "eguitar"
|
||||
force = 12
|
||||
attack_verb = list("played metal on", "shredded", "crashed", "smashed")
|
||||
hitsound = 'sound/weapons/stringsmash.ogg'
|
||||
instrumentId = "eguitar"
|
||||
force = 10
|
||||
attack_verb = list("played metal on", "serenaded", "crashed", "smashed")
|
||||
hitsound = 'sound/weapons/stringsmash.ogg'
|
||||
instrumentId = "guitar"
|
||||
|
||||
/obj/item/device/instrument/eguitar
|
||||
name = "electric guitar"
|
||||
desc = "Makes all your shredding needs possible."
|
||||
icon_state = "eguitar"
|
||||
item_state = "eguitar"
|
||||
force = 12
|
||||
attack_verb = list("played metal on", "shredded", "crashed", "smashed")
|
||||
hitsound = 'sound/weapons/stringsmash.ogg'
|
||||
instrumentId = "eguitar"
|
||||
instrumentExt = "ogg"
|
||||
|
||||
/obj/item/device/instrument/glockenspiel
|
||||
|
||||
@@ -1,269 +1,268 @@
|
||||
|
||||
// Light Replacer (LR)
|
||||
//
|
||||
// ABOUT THE DEVICE
|
||||
//
|
||||
// This is a device supposedly to be used by Janitors and Janitor Cyborgs which will
|
||||
// allow them to easily replace lights. This was mostly designed for Janitor Cyborgs since
|
||||
// they don't have hands or a way to replace lightbulbs.
|
||||
//
|
||||
// HOW IT WORKS
|
||||
//
|
||||
// You attack a light fixture with it, if the light fixture is broken it will replace the
|
||||
// light fixture with a working light; the broken light is then placed on the floor for the
|
||||
// user to then pickup with a trash bag. If it's empty then it will just place a light in the fixture.
|
||||
//
|
||||
// HOW TO REFILL THE DEVICE
|
||||
//
|
||||
// It will need to be manually refilled with lights.
|
||||
// If it's part of a robot module, it will charge when the Robot is inside a Recharge Station.
|
||||
//
|
||||
// EMAGGED FEATURES
|
||||
//
|
||||
// NOTICE: The Cyborg cannot use the emagged Light Replacer and the light's explosion was nerfed. It cannot create holes in the station anymore.
|
||||
//
|
||||
// I'm not sure everyone will react the emag's features so please say what your opinions are of it.
|
||||
//
|
||||
// When emagged it will rig every light it replaces, which will explode when the light is on.
|
||||
// This is VERY noticable, even the device's name changes when you emag it so if anyone
|
||||
// examines you when you're holding it in your hand, you will be discovered.
|
||||
// It will also be very obvious who is setting all these lights off, since only Janitor Borgs and Janitors have easy
|
||||
// access to them, and only one of them can emag their device.
|
||||
//
|
||||
// The explosion cannot insta-kill anyone with 30% or more health.
|
||||
|
||||
#define LIGHT_OK 0
|
||||
#define LIGHT_EMPTY 1
|
||||
#define LIGHT_BROKEN 2
|
||||
#define LIGHT_BURNED 3
|
||||
|
||||
|
||||
/obj/item/device/lightreplacer
|
||||
|
||||
name = "light replacer"
|
||||
desc = "A device to automatically replace lights. Refill with broken or working lightbulbs, or sheets of glass."
|
||||
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "lightreplacer0"
|
||||
item_state = "electronic"
|
||||
|
||||
// Light Replacer (LR)
|
||||
//
|
||||
// ABOUT THE DEVICE
|
||||
//
|
||||
// This is a device supposedly to be used by Janitors and Janitor Cyborgs which will
|
||||
// allow them to easily replace lights. This was mostly designed for Janitor Cyborgs since
|
||||
// they don't have hands or a way to replace lightbulbs.
|
||||
//
|
||||
// HOW IT WORKS
|
||||
//
|
||||
// You attack a light fixture with it, if the light fixture is broken it will replace the
|
||||
// light fixture with a working light; the broken light is then placed on the floor for the
|
||||
// user to then pickup with a trash bag. If it's empty then it will just place a light in the fixture.
|
||||
//
|
||||
// HOW TO REFILL THE DEVICE
|
||||
//
|
||||
// It will need to be manually refilled with lights.
|
||||
// If it's part of a robot module, it will charge when the Robot is inside a Recharge Station.
|
||||
//
|
||||
// EMAGGED FEATURES
|
||||
//
|
||||
// NOTICE: The Cyborg cannot use the emagged Light Replacer and the light's explosion was nerfed. It cannot create holes in the station anymore.
|
||||
//
|
||||
// I'm not sure everyone will react the emag's features so please say what your opinions are of it.
|
||||
//
|
||||
// When emagged it will rig every light it replaces, which will explode when the light is on.
|
||||
// This is VERY noticable, even the device's name changes when you emag it so if anyone
|
||||
// examines you when you're holding it in your hand, you will be discovered.
|
||||
// It will also be very obvious who is setting all these lights off, since only Janitor Borgs and Janitors have easy
|
||||
// access to them, and only one of them can emag their device.
|
||||
//
|
||||
// The explosion cannot insta-kill anyone with 30% or more health.
|
||||
|
||||
#define LIGHT_OK 0
|
||||
#define LIGHT_EMPTY 1
|
||||
#define LIGHT_BROKEN 2
|
||||
#define LIGHT_BURNED 3
|
||||
|
||||
|
||||
/obj/item/device/lightreplacer
|
||||
|
||||
name = "light replacer"
|
||||
desc = "A device to automatically replace lights. Refill with broken or working lightbulbs, or sheets of glass."
|
||||
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "lightreplacer0"
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
|
||||
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "magnets=3;engineering=4"
|
||||
|
||||
var/max_uses = 20
|
||||
var/uses = 0
|
||||
var/emagged = FALSE
|
||||
var/failmsg = ""
|
||||
// How much to increase per each glass?
|
||||
var/increment = 5
|
||||
// How much to take from the glass?
|
||||
var/decrement = 1
|
||||
var/charge = 1
|
||||
|
||||
// Eating used bulbs gives us bulb shards
|
||||
var/bulb_shards = 0
|
||||
// when we get this many shards, we get a free bulb.
|
||||
var/shards_required = 4
|
||||
|
||||
/obj/item/device/lightreplacer/New()
|
||||
uses = max_uses / 2
|
||||
failmsg = "The [name]'s refill light blinks red."
|
||||
..()
|
||||
|
||||
/obj/item/device/lightreplacer/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, status_string())
|
||||
|
||||
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user, params)
|
||||
|
||||
if(istype(W, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = W
|
||||
if(uses >= max_uses)
|
||||
to_chat(user, "<span class='warning'>[src.name] is full.</span>")
|
||||
return
|
||||
else if(G.use(decrement))
|
||||
AddUses(increment)
|
||||
to_chat(user, "<span class='notice'>You insert a piece of glass into the [src.name]. You have [uses] light\s remaining.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one sheet of glass to replace lights!</span>")
|
||||
|
||||
if(istype(W, /obj/item/shard))
|
||||
if(uses >= max_uses)
|
||||
to_chat(user, "<span class='warning'>[src.name] is full.</span>")
|
||||
return
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
return
|
||||
AddUses(round(increment*0.75))
|
||||
to_chat(user, "<span class='notice'>You insert a shard of glass into the [src.name]. You have [uses] light\s remaining.</span>")
|
||||
qdel(W)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/light))
|
||||
var/obj/item/light/L = W
|
||||
if(L.status == 0) // LIGHT OKAY
|
||||
if(uses < max_uses)
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
return
|
||||
AddUses(1)
|
||||
qdel(L)
|
||||
else
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You insert the [L.name] into the [src.name]</span>")
|
||||
AddShards(1, user)
|
||||
qdel(L)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/storage))
|
||||
var/obj/item/storage/S = W
|
||||
var/found_lightbulbs = FALSE
|
||||
var/replaced_something = TRUE
|
||||
|
||||
for(var/obj/item/I in S.contents)
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "magnets=3;engineering=4"
|
||||
|
||||
var/max_uses = 20
|
||||
var/uses = 0
|
||||
var/failmsg = ""
|
||||
// How much to increase per each glass?
|
||||
var/increment = 5
|
||||
// How much to take from the glass?
|
||||
var/decrement = 1
|
||||
var/charge = 1
|
||||
|
||||
// Eating used bulbs gives us bulb shards
|
||||
var/bulb_shards = 0
|
||||
// when we get this many shards, we get a free bulb.
|
||||
var/shards_required = 4
|
||||
|
||||
/obj/item/device/lightreplacer/New()
|
||||
uses = max_uses / 2
|
||||
failmsg = "The [name]'s refill light blinks red."
|
||||
..()
|
||||
|
||||
/obj/item/device/lightreplacer/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, status_string())
|
||||
|
||||
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user, params)
|
||||
|
||||
if(istype(W, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = W
|
||||
if(uses >= max_uses)
|
||||
to_chat(user, "<span class='warning'>[src.name] is full.</span>")
|
||||
return
|
||||
else if(G.use(decrement))
|
||||
AddUses(increment)
|
||||
to_chat(user, "<span class='notice'>You insert a piece of glass into the [src.name]. You have [uses] light\s remaining.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one sheet of glass to replace lights!</span>")
|
||||
|
||||
if(istype(W, /obj/item/shard))
|
||||
if(uses >= max_uses)
|
||||
to_chat(user, "<span class='warning'>[src.name] is full.</span>")
|
||||
return
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
return
|
||||
AddUses(round(increment*0.75))
|
||||
to_chat(user, "<span class='notice'>You insert a shard of glass into the [src.name]. You have [uses] light\s remaining.</span>")
|
||||
qdel(W)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/light))
|
||||
var/obj/item/light/L = W
|
||||
if(L.status == 0) // LIGHT OKAY
|
||||
if(uses < max_uses)
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
return
|
||||
AddUses(1)
|
||||
qdel(L)
|
||||
else
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You insert the [L.name] into the [src.name]</span>")
|
||||
AddShards(1, user)
|
||||
qdel(L)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/storage))
|
||||
var/obj/item/storage/S = W
|
||||
var/found_lightbulbs = FALSE
|
||||
var/replaced_something = TRUE
|
||||
|
||||
for(var/obj/item/I in S.contents)
|
||||
if(istype(I, /obj/item/light))
|
||||
var/obj/item/light/L = I
|
||||
found_lightbulbs = TRUE
|
||||
if(src.uses >= max_uses)
|
||||
break
|
||||
if(L.status == LIGHT_OK)
|
||||
replaced_something = TRUE
|
||||
AddUses(1)
|
||||
qdel(L)
|
||||
|
||||
else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED)
|
||||
replaced_something = TRUE
|
||||
AddShards(1, user)
|
||||
qdel(L)
|
||||
|
||||
if(!found_lightbulbs)
|
||||
to_chat(user, "<span class='warning'>\The [S] contains no bulbs.</span>")
|
||||
return
|
||||
|
||||
if(!replaced_something && src.uses == max_uses)
|
||||
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You fill \the [src] with lights from \the [S]. " + status_string() + "</span>")
|
||||
|
||||
/obj/item/device/lightreplacer/emag_act()
|
||||
var/obj/item/light/L = I
|
||||
found_lightbulbs = TRUE
|
||||
if(src.uses >= max_uses)
|
||||
break
|
||||
if(L.status == LIGHT_OK)
|
||||
replaced_something = TRUE
|
||||
AddUses(1)
|
||||
qdel(L)
|
||||
|
||||
else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED)
|
||||
replaced_something = TRUE
|
||||
AddShards(1, user)
|
||||
qdel(L)
|
||||
|
||||
if(!found_lightbulbs)
|
||||
to_chat(user, "<span class='warning'>\The [S] contains no bulbs.</span>")
|
||||
return
|
||||
|
||||
if(!replaced_something && src.uses == max_uses)
|
||||
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You fill \the [src] with lights from \the [S]. " + status_string() + "</span>")
|
||||
|
||||
/obj/item/device/lightreplacer/emag_act()
|
||||
if(emagged)
|
||||
return
|
||||
Emag()
|
||||
|
||||
/obj/item/device/lightreplacer/attack_self(mob/user)
|
||||
to_chat(user, status_string())
|
||||
|
||||
/obj/item/device/lightreplacer/update_icon()
|
||||
icon_state = "lightreplacer[emagged]"
|
||||
|
||||
/obj/item/device/lightreplacer/proc/status_string()
|
||||
return "It has [uses] light\s remaining (plus [bulb_shards] fragment\s)."
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Use(mob/user)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
AddUses(-1)
|
||||
return 1
|
||||
|
||||
// Negative numbers will subtract
|
||||
/obj/item/device/lightreplacer/proc/AddUses(amount = 1)
|
||||
uses = Clamp(uses + amount, 0, max_uses)
|
||||
|
||||
/obj/item/device/lightreplacer/proc/AddShards(amount = 1, user)
|
||||
bulb_shards += amount
|
||||
var/new_bulbs = round(bulb_shards / shards_required)
|
||||
if(new_bulbs > 0)
|
||||
AddUses(new_bulbs)
|
||||
bulb_shards = bulb_shards % shards_required
|
||||
if(new_bulbs != 0)
|
||||
to_chat(user, "<span class='notice'>\The [src] has fabricated a new bulb from the broken glass it has stored. It now has [uses] uses.</span>")
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
return new_bulbs
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Charge(var/mob/user)
|
||||
charge += 1
|
||||
if(charge > 3)
|
||||
AddUses(1)
|
||||
charge = 1
|
||||
|
||||
/obj/item/device/lightreplacer/proc/ReplaceLight(obj/machinery/light/target, mob/living/U)
|
||||
|
||||
if(target.status != LIGHT_OK)
|
||||
if(CanUse(U))
|
||||
if(!Use(U)) return
|
||||
to_chat(U, "<span class='notice'>You replace the [target.fitting] with \the [src].</span>")
|
||||
|
||||
if(target.status != LIGHT_EMPTY)
|
||||
AddShards(1, U)
|
||||
target.status = LIGHT_EMPTY
|
||||
target.update()
|
||||
|
||||
var/obj/item/light/L2 = new target.light_type()
|
||||
|
||||
target.status = L2.status
|
||||
target.switchcount = L2.switchcount
|
||||
target.rigged = emagged
|
||||
target.brightness = L2.brightness
|
||||
target.on = target.has_power()
|
||||
target.update()
|
||||
qdel(L2)
|
||||
|
||||
if(target.on && target.rigged)
|
||||
target.explode()
|
||||
return
|
||||
|
||||
else
|
||||
to_chat(U, failmsg)
|
||||
return
|
||||
else
|
||||
to_chat(U, "<span class='warning'>There is a working [target.fitting] already inserted!</span>")
|
||||
return
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Emag()
|
||||
emagged = !emagged
|
||||
playsound(src.loc, "sparks", 100, 1)
|
||||
if(emagged)
|
||||
name = "shortcircuited [initial(name)]"
|
||||
else
|
||||
name = initial(name)
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/lightreplacer/proc/CanUse(mob/living/user)
|
||||
src.add_fingerprint(user)
|
||||
if(uses > 0)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/device/lightreplacer/afterattack(atom/T, mob/U, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(!isturf(T))
|
||||
return
|
||||
|
||||
var/used = FALSE
|
||||
for(var/atom/A in T)
|
||||
if(!CanUse(U))
|
||||
break
|
||||
used = TRUE
|
||||
if(istype(A, /obj/machinery/light))
|
||||
ReplaceLight(A, U)
|
||||
|
||||
if(!used)
|
||||
to_chat(U, failmsg)
|
||||
|
||||
/obj/item/device/lightreplacer/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J)
|
||||
J.put_in_cart(src, user)
|
||||
J.myreplacer = src
|
||||
J.update_icon()
|
||||
|
||||
/obj/item/device/lightreplacer/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J)
|
||||
return
|
||||
|
||||
#undef LIGHT_OK
|
||||
#undef LIGHT_EMPTY
|
||||
#undef LIGHT_BROKEN
|
||||
#undef LIGHT_BURNED
|
||||
|
||||
/obj/item/device/lightreplacer/attack_self(mob/user)
|
||||
to_chat(user, status_string())
|
||||
|
||||
/obj/item/device/lightreplacer/update_icon()
|
||||
icon_state = "lightreplacer[emagged]"
|
||||
|
||||
/obj/item/device/lightreplacer/proc/status_string()
|
||||
return "It has [uses] light\s remaining (plus [bulb_shards] fragment\s)."
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Use(mob/user)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
AddUses(-1)
|
||||
return 1
|
||||
|
||||
// Negative numbers will subtract
|
||||
/obj/item/device/lightreplacer/proc/AddUses(amount = 1)
|
||||
uses = Clamp(uses + amount, 0, max_uses)
|
||||
|
||||
/obj/item/device/lightreplacer/proc/AddShards(amount = 1, user)
|
||||
bulb_shards += amount
|
||||
var/new_bulbs = round(bulb_shards / shards_required)
|
||||
if(new_bulbs > 0)
|
||||
AddUses(new_bulbs)
|
||||
bulb_shards = bulb_shards % shards_required
|
||||
if(new_bulbs != 0)
|
||||
to_chat(user, "<span class='notice'>\The [src] has fabricated a new bulb from the broken glass it has stored. It now has [uses] uses.</span>")
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
return new_bulbs
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Charge(var/mob/user)
|
||||
charge += 1
|
||||
if(charge > 3)
|
||||
AddUses(1)
|
||||
charge = 1
|
||||
|
||||
/obj/item/device/lightreplacer/proc/ReplaceLight(obj/machinery/light/target, mob/living/U)
|
||||
|
||||
if(target.status != LIGHT_OK)
|
||||
if(CanUse(U))
|
||||
if(!Use(U)) return
|
||||
to_chat(U, "<span class='notice'>You replace the [target.fitting] with \the [src].</span>")
|
||||
|
||||
if(target.status != LIGHT_EMPTY)
|
||||
AddShards(1, U)
|
||||
target.status = LIGHT_EMPTY
|
||||
target.update()
|
||||
|
||||
var/obj/item/light/L2 = new target.light_type()
|
||||
|
||||
target.status = L2.status
|
||||
target.switchcount = L2.switchcount
|
||||
target.rigged = emagged
|
||||
target.brightness = L2.brightness
|
||||
target.on = target.has_power()
|
||||
target.update()
|
||||
qdel(L2)
|
||||
|
||||
if(target.on && target.rigged)
|
||||
target.explode()
|
||||
return
|
||||
|
||||
else
|
||||
to_chat(U, failmsg)
|
||||
return
|
||||
else
|
||||
to_chat(U, "<span class='warning'>There is a working [target.fitting] already inserted!</span>")
|
||||
return
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Emag()
|
||||
emagged = !emagged
|
||||
playsound(src.loc, "sparks", 100, 1)
|
||||
if(emagged)
|
||||
name = "shortcircuited [initial(name)]"
|
||||
else
|
||||
name = initial(name)
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/lightreplacer/proc/CanUse(mob/living/user)
|
||||
src.add_fingerprint(user)
|
||||
if(uses > 0)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/device/lightreplacer/afterattack(atom/T, mob/U, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(!isturf(T))
|
||||
return
|
||||
|
||||
var/used = FALSE
|
||||
for(var/atom/A in T)
|
||||
if(!CanUse(U))
|
||||
break
|
||||
used = TRUE
|
||||
if(istype(A, /obj/machinery/light))
|
||||
ReplaceLight(A, U)
|
||||
|
||||
if(!used)
|
||||
to_chat(U, failmsg)
|
||||
|
||||
/obj/item/device/lightreplacer/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J)
|
||||
J.put_in_cart(src, user)
|
||||
J.myreplacer = src
|
||||
J.update_icon()
|
||||
|
||||
/obj/item/device/lightreplacer/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J)
|
||||
return
|
||||
|
||||
#undef LIGHT_OK
|
||||
#undef LIGHT_EMPTY
|
||||
#undef LIGHT_BROKEN
|
||||
#undef LIGHT_BURNED
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
siemens_coefficient = 1
|
||||
var/spamcheck = 0
|
||||
var/emagged = FALSE
|
||||
var/list/voicespan = list(SPAN_COMMAND)
|
||||
|
||||
/obj/item/device/megaphone/get_held_item_speechspans(mob/living/carbon/user)
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
|
||||
/obj/item/weapon/pinpointer
|
||||
name = "pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinpointer"
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/active = FALSE
|
||||
var/atom/movable/target = null //The thing we're searching for
|
||||
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
|
||||
var/alert = FALSE // TRUE to display things more seriously
|
||||
|
||||
/obj/item/weapon/pinpointer/New()
|
||||
..()
|
||||
GLOB.pinpointer_list += src
|
||||
|
||||
/obj/item/weapon/pinpointer/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.pinpointer_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/pinpointer/attack_self(mob/living/user)
|
||||
active = !active
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
if(active)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
target = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_pointer_overlay()
|
||||
|
||||
/obj/item/weapon/pinpointer/process()
|
||||
if(!active)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return
|
||||
scan_for_target()
|
||||
update_pointer_overlay()
|
||||
|
||||
/obj/item/weapon/pinpointer/proc/scan_for_target()
|
||||
return
|
||||
|
||||
/obj/item/weapon/pinpointer/proc/update_pointer_overlay()
|
||||
cut_overlays()
|
||||
if(!active)
|
||||
return
|
||||
if(!target)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
var/turf/here = get_turf(src)
|
||||
var/turf/there = get_turf(target)
|
||||
if(here.z != there.z)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
return
|
||||
if(get_dist_euclidian(here,there) <= minimum_range)
|
||||
add_overlay("pinon[alert ? "alert" : ""]direct")
|
||||
else
|
||||
setDir(get_dir(here, there))
|
||||
switch(get_dist(here, there))
|
||||
if(1 to 8)
|
||||
add_overlay("pinon[alert ? "alert" : "close"]")
|
||||
if(9 to 16)
|
||||
add_overlay("pinon[alert ? "alert" : "medium"]")
|
||||
if(16 to INFINITY)
|
||||
add_overlay("pinon[alert ? "alert" : "far"]")
|
||||
|
||||
/obj/item/weapon/pinpointer/crew // A replacement for the old crew monitoring consoles
|
||||
name = "crew pinpointer"
|
||||
desc = "A handheld tracking device that points to crew suit sensors."
|
||||
icon_state = "pinpointer_crew"
|
||||
|
||||
/obj/item/weapon/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
|
||||
var/turf/here = get_turf(src)
|
||||
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = H.w_uniform
|
||||
|
||||
// Suit sensors must be on maximum.
|
||||
if(!U.has_sensor || U.sensor_mode < SENSOR_COORDS)
|
||||
return FALSE
|
||||
|
||||
var/turf/there = get_turf(H)
|
||||
return (H.z != 0 || (there && there.z == H.z))
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/pinpointer/crew/attack_self(mob/living/user)
|
||||
if(active)
|
||||
active = FALSE
|
||||
user.visible_message("<span class='notice'>[user] deactivates their pinpointer.</span>", "<span class='notice'>You deactivate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
target = null //Restarting the pinpointer forces a target reset
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_pointer_overlay()
|
||||
return
|
||||
|
||||
var/list/name_counts = list()
|
||||
var/list/names = list()
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
if(!trackable(H))
|
||||
continue
|
||||
|
||||
var/name = "Unknown"
|
||||
if(H.wear_id)
|
||||
var/obj/item/weapon/card/id/I = H.wear_id.GetID()
|
||||
name = I.registered_name
|
||||
|
||||
while(name in name_counts)
|
||||
name_counts[name]++
|
||||
name = text("[] ([])", name, name_counts[name])
|
||||
names[name] = H
|
||||
name_counts[name] = 1
|
||||
|
||||
if(!names.len)
|
||||
user.visible_message("<span class='notice'>[user]'s pinpointer fails to detect a signal.</span>", "<span class='notice'>Your pinpointer fails to detect a signal.</span>")
|
||||
return
|
||||
|
||||
var/A = input(user, "Person to track", "Pinpoint") in names
|
||||
if(!src || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !A)
|
||||
return
|
||||
|
||||
target = names[A]
|
||||
active = TRUE
|
||||
user.visible_message("<span class='notice'>[user] activates their pinpointer.</span>", "<span class='notice'>You activate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
update_pointer_overlay()
|
||||
|
||||
/obj/item/weapon/pinpointer/crew/scan_for_target()
|
||||
if(target)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!trackable(H))
|
||||
target = null
|
||||
if(!target)
|
||||
active = FALSE
|
||||
|
||||
/obj/item/weapon/pinpointer/process()
|
||||
if(!active)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return
|
||||
scan_for_target()
|
||||
update_pointer_overlay()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
/obj/item/device/pressure_plate
|
||||
name = "pressure plate"
|
||||
desc = "Useful for autismforts"
|
||||
desc = "An electronic device that triggers when stepped on."
|
||||
item_state = "flash"
|
||||
icon_state = "pressureplate"
|
||||
level = 1
|
||||
@@ -17,11 +17,11 @@
|
||||
var/removable_signaller = TRUE
|
||||
var/active = FALSE
|
||||
var/image/tile_overlay = null
|
||||
var/crossed = FALSE
|
||||
var/can_trigger = TRUE
|
||||
var/trigger_delay = 10
|
||||
|
||||
/obj/item/device/pressure_plate/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
tile_overlay = image(icon = 'icons/turf/floors.dmi', icon_state = "pp_overlay")
|
||||
if(roundstart_signaller)
|
||||
sigdev = new
|
||||
@@ -31,45 +31,27 @@
|
||||
hide(TRUE)
|
||||
|
||||
/obj/item/device/pressure_plate/Crossed(atom/movable/AM)
|
||||
if(!active)
|
||||
. = ..()
|
||||
if(!can_trigger || !active)
|
||||
return
|
||||
if(isliving(AM) && trigger_mob)
|
||||
if(trigger_mob && isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
step_living(L)
|
||||
crossed = TRUE
|
||||
else if(trigger_item)
|
||||
step_item(AM)
|
||||
crossed = TRUE
|
||||
if(!trigger_silent)
|
||||
if(isturf(loc))
|
||||
loc.visible_message("<span class='danger'>Click!</span>")
|
||||
playsound(loc, trigger_sound, 50, 1)
|
||||
. = ..()
|
||||
|
||||
/obj/item/device/pressure_plate/Uncrossed(atom/movable/AM)
|
||||
if(crossed)
|
||||
playsound(loc, trigger_sound, 50, 1)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
to_chat(L, "<span class='warning'>You feel something click back into place as you step off [loc]!</span>")
|
||||
addtimer(CALLBACK(src, .proc/trigger), trigger_delay)
|
||||
. = ..()
|
||||
to_chat(L, "<span class='warning'>You feel something click beneath you!</span>")
|
||||
else if(!trigger_item)
|
||||
return
|
||||
can_trigger = FALSE
|
||||
addtimer(CALLBACK(src, .proc/trigger), trigger_delay)
|
||||
|
||||
/obj/item/device/pressure_plate/proc/trigger()
|
||||
can_trigger = TRUE
|
||||
if(istype(sigdev))
|
||||
sigdev.signal()
|
||||
|
||||
/obj/item/device/pressure_plate/proc/step_living(mob/living/L)
|
||||
to_chat(L, "<span class='warning'>You feel a click under your feet!</span>")
|
||||
|
||||
/obj/item/device/pressure_plate/proc/step_item(atom/movable/AM)
|
||||
return
|
||||
|
||||
/obj/item/device/pressure_plate/attackby(obj/item/I, mob/living/L)
|
||||
if(istype(I, /obj/item/device/assembly/signaler) && !istype(sigdev) && removable_signaller && L.transferItemToLoc(I, src))
|
||||
sigdev = I
|
||||
to_chat(L, "<span class='notice'>You attach [I] to [src]!</span>")
|
||||
. = ..()
|
||||
return ..()
|
||||
|
||||
/obj/item/device/pressure_plate/attack_self(mob/living/L)
|
||||
if(removable_signaller && istype(sigdev))
|
||||
@@ -77,7 +59,7 @@
|
||||
if(!L.put_in_hands(sigdev))
|
||||
sigdev.forceMove(get_turf(src))
|
||||
sigdev = null
|
||||
. = ..()
|
||||
return ..()
|
||||
|
||||
/obj/item/device/pressure_plate/hide(yes)
|
||||
if(yes)
|
||||
@@ -85,11 +67,10 @@
|
||||
anchored = TRUE
|
||||
icon_state = null
|
||||
active = TRUE
|
||||
can_trigger = TRUE
|
||||
if(tile_overlay)
|
||||
loc.overlays += tile_overlay
|
||||
loc.add_overlay(tile_overlay)
|
||||
else
|
||||
if(crossed)
|
||||
trigger() //no cheesing.
|
||||
invisibility = initial(invisibility)
|
||||
anchored = FALSE
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
@@ -426,7 +426,7 @@
|
||||
signal.frequency = freqnum // Quick frequency set
|
||||
for(var/obj/machinery/telecomms/receiver/R in GLOB.telecomms_list)
|
||||
R.receive_signal(signal)
|
||||
|
||||
|
||||
// Allinone can act as receivers. (Unless of course whoever coded this last time forgot to put it in somewhere!)
|
||||
for(var/obj/machinery/telecomms/allinone/R in GLOB.telecomms_list)
|
||||
R.receive_signal(signal)
|
||||
@@ -449,6 +449,8 @@
|
||||
return
|
||||
if(broadcasting)
|
||||
if(get_dist(src, speaker) <= canhear_range)
|
||||
if(message_mode == MODE_WHISPER || message_mode == MODE_WHISPER_CRIT)
|
||||
raw_message = stars(raw_message)
|
||||
talk_into(speaker, raw_message, , spans, language=message_language)
|
||||
/*
|
||||
/obj/item/device/radio/proc/accept_rad(obj/item/device/radio/R as obj, message)
|
||||
@@ -553,7 +555,7 @@
|
||||
flags_2 = NO_EMP_WIRES_2
|
||||
|
||||
/obj/item/device/radio/borg/Initialize(mapload)
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/obj/item/device/radio/borg/syndicate
|
||||
syndie = 1
|
||||
|
||||
@@ -113,7 +113,7 @@ MASS SPECTROMETER
|
||||
var/tox_loss = M.getToxLoss()
|
||||
var/fire_loss = M.getFireLoss()
|
||||
var/brute_loss = M.getBruteLoss()
|
||||
var/mob_status = (M.stat > 1 ? "<span class='alert'><b>Deceased</b></span>" : "<b>[round(M.health/M.maxHealth,0.01)*100] % healthy</b>")
|
||||
var/mob_status = (M.stat == DEAD ? "<span class='alert'><b>Deceased</b></span>" : "<b>[round(M.health/M.maxHealth,0.01)*100] % healthy</b>")
|
||||
|
||||
if(M.status_flags & FAKEDEATH)
|
||||
mob_status = "<span class='alert'>Deceased</span>"
|
||||
|
||||
@@ -1,294 +1,294 @@
|
||||
/obj/item/device/taperecorder
|
||||
name = "universal recorder"
|
||||
desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback."
|
||||
icon_state = "taperecorder_empty"
|
||||
item_state = "analyzer"
|
||||
/obj/item/device/taperecorder
|
||||
name = "universal recorder"
|
||||
desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback."
|
||||
icon_state = "taperecorder_empty"
|
||||
item_state = "analyzer"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
flags_1 = HEAR_1
|
||||
slot_flags = SLOT_BELT
|
||||
materials = list(MAT_METAL=60, MAT_GLASS=30)
|
||||
force = 2
|
||||
throwforce = 0
|
||||
var/recording = 0
|
||||
var/playing = 0
|
||||
var/playsleepseconds = 0
|
||||
var/obj/item/device/tape/mytape
|
||||
var/starting_tape_type = /obj/item/device/tape/random
|
||||
var/open_panel = 0
|
||||
var/canprint = 1
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/Initialize(mapload)
|
||||
..()
|
||||
if(starting_tape_type)
|
||||
mytape = new starting_tape_type(src)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "The wire panel is [open_panel ? "opened" : "closed"].")
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/attackby(obj/item/I, mob/user, params)
|
||||
if(!mytape && istype(I, /obj/item/device/tape))
|
||||
if(!user.transferItemToLoc(I,src))
|
||||
return
|
||||
mytape = I
|
||||
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/proc/eject(mob/user)
|
||||
if(mytape)
|
||||
to_chat(user, "<span class='notice'>You remove [mytape] from [src].</span>")
|
||||
stop()
|
||||
user.put_in_hands(mytape)
|
||||
mytape = null
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/taperecorder/fire_act(exposed_temperature, exposed_volume)
|
||||
mytape.ruin() //Fires destroy the tape
|
||||
..()
|
||||
|
||||
/obj/item/device/taperecorder/attack_hand(mob/user)
|
||||
if(loc == user)
|
||||
if(mytape)
|
||||
if(!user.is_holding(src))
|
||||
..()
|
||||
return
|
||||
eject(user)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/proc/can_use(mob/user)
|
||||
if(user && ismob(user))
|
||||
if(!user.incapacitated())
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/ejectverb()
|
||||
set name = "Eject Tape"
|
||||
set category = "Object"
|
||||
|
||||
if(!can_use(usr))
|
||||
return
|
||||
if(!mytape)
|
||||
return
|
||||
|
||||
eject(usr)
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/update_icon()
|
||||
if(!mytape)
|
||||
icon_state = "taperecorder_empty"
|
||||
else if(recording)
|
||||
icon_state = "taperecorder_recording"
|
||||
else if(playing)
|
||||
icon_state = "taperecorder_playing"
|
||||
else
|
||||
icon_state = "taperecorder_idle"
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
|
||||
if(mytape && recording)
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [message]"
|
||||
|
||||
/obj/item/device/taperecorder/verb/record()
|
||||
set name = "Start Recording"
|
||||
set category = "Object"
|
||||
|
||||
if(!can_use(usr))
|
||||
return
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
return
|
||||
if(playing)
|
||||
return
|
||||
|
||||
if(mytape.used_capacity < mytape.max_capacity)
|
||||
to_chat(usr, "<span class='notice'>Recording started.</span>")
|
||||
recording = 1
|
||||
update_icon()
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording started."
|
||||
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
|
||||
var/max = mytape.max_capacity
|
||||
for(used, used < max)
|
||||
if(recording == 0)
|
||||
break
|
||||
mytape.used_capacity++
|
||||
used++
|
||||
sleep(10)
|
||||
recording = 0
|
||||
update_icon()
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>The tape is full.</span>")
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/stop()
|
||||
set name = "Stop"
|
||||
set category = "Object"
|
||||
|
||||
if(!can_use(usr))
|
||||
return
|
||||
|
||||
if(recording)
|
||||
recording = 0
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording stopped."
|
||||
to_chat(usr, "<span class='notice'>Recording stopped.</span>")
|
||||
return
|
||||
else if(playing)
|
||||
playing = 0
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: Playback stopped.</font>")
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/play()
|
||||
set name = "Play Tape"
|
||||
set category = "Object"
|
||||
|
||||
if(!can_use(usr))
|
||||
return
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
return
|
||||
if(playing)
|
||||
return
|
||||
|
||||
playing = 1
|
||||
update_icon()
|
||||
to_chat(usr, "<span class='notice'>Playing started.</span>")
|
||||
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
|
||||
var/max = mytape.max_capacity
|
||||
for(var/i = 1, used < max, sleep(10 * playsleepseconds))
|
||||
if(!mytape)
|
||||
break
|
||||
if(playing == 0)
|
||||
break
|
||||
if(mytape.storedinfo.len < i)
|
||||
break
|
||||
say(mytape.storedinfo[i])
|
||||
if(mytape.storedinfo.len < i + 1)
|
||||
playsleepseconds = 1
|
||||
sleep(10)
|
||||
say("End of recording.")
|
||||
else
|
||||
playsleepseconds = mytape.timestamp[i + 1] - mytape.timestamp[i]
|
||||
if(playsleepseconds > 14)
|
||||
sleep(10)
|
||||
say("Skipping [playsleepseconds] seconds of silence")
|
||||
playsleepseconds = 1
|
||||
i++
|
||||
|
||||
playing = 0
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/attack_self(mob/user)
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
stop()
|
||||
else
|
||||
record()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/print_transcript()
|
||||
set name = "Print Transcript"
|
||||
set category = "Object"
|
||||
|
||||
if(!can_use(usr))
|
||||
return
|
||||
if(!mytape)
|
||||
return
|
||||
if(!canprint)
|
||||
to_chat(usr, "<span class='notice'>The recorder can't print that fast!</span>")
|
||||
return
|
||||
if(recording || playing)
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='notice'>Transcript printed.</span>")
|
||||
var/obj/item/paper/P = new /obj/item/paper(get_turf(src))
|
||||
var/t1 = "<B>Transcript:</B><BR><BR>"
|
||||
for(var/i = 1, mytape.storedinfo.len >= i, i++)
|
||||
t1 += "[mytape.storedinfo[i]]<BR>"
|
||||
P.info = t1
|
||||
P.name = "paper- 'Transcript'"
|
||||
usr.put_in_hands(P)
|
||||
canprint = 0
|
||||
sleep(300)
|
||||
canprint = 1
|
||||
|
||||
|
||||
//empty tape recorders
|
||||
/obj/item/device/taperecorder/empty
|
||||
starting_tape_type = null
|
||||
|
||||
|
||||
/obj/item/device/tape
|
||||
name = "tape"
|
||||
desc = "A magnetic tape that can hold up to ten minutes of content."
|
||||
icon_state = "tape_white"
|
||||
item_state = "analyzer"
|
||||
slot_flags = SLOT_BELT
|
||||
materials = list(MAT_METAL=60, MAT_GLASS=30)
|
||||
force = 2
|
||||
throwforce = 0
|
||||
var/recording = 0
|
||||
var/playing = 0
|
||||
var/playsleepseconds = 0
|
||||
var/obj/item/device/tape/mytape
|
||||
var/starting_tape_type = /obj/item/device/tape/random
|
||||
var/open_panel = 0
|
||||
var/canprint = 1
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/Initialize(mapload)
|
||||
. = ..()
|
||||
if(starting_tape_type)
|
||||
mytape = new starting_tape_type(src)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "The wire panel is [open_panel ? "opened" : "closed"].")
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/attackby(obj/item/I, mob/user, params)
|
||||
if(!mytape && istype(I, /obj/item/device/tape))
|
||||
if(!user.transferItemToLoc(I,src))
|
||||
return
|
||||
mytape = I
|
||||
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/proc/eject(mob/user)
|
||||
if(mytape)
|
||||
to_chat(user, "<span class='notice'>You remove [mytape] from [src].</span>")
|
||||
stop()
|
||||
user.put_in_hands(mytape)
|
||||
mytape = null
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/taperecorder/fire_act(exposed_temperature, exposed_volume)
|
||||
mytape.ruin() //Fires destroy the tape
|
||||
..()
|
||||
|
||||
/obj/item/device/taperecorder/attack_hand(mob/user)
|
||||
if(loc == user)
|
||||
if(mytape)
|
||||
if(!user.is_holding(src))
|
||||
..()
|
||||
return
|
||||
eject(user)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/proc/can_use(mob/user)
|
||||
if(user && ismob(user))
|
||||
if(!user.incapacitated())
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/ejectverb()
|
||||
set name = "Eject Tape"
|
||||
set category = "Object"
|
||||
|
||||
if(!can_use(usr))
|
||||
return
|
||||
if(!mytape)
|
||||
return
|
||||
|
||||
eject(usr)
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/update_icon()
|
||||
if(!mytape)
|
||||
icon_state = "taperecorder_empty"
|
||||
else if(recording)
|
||||
icon_state = "taperecorder_recording"
|
||||
else if(playing)
|
||||
icon_state = "taperecorder_playing"
|
||||
else
|
||||
icon_state = "taperecorder_idle"
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
|
||||
if(mytape && recording)
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [message]"
|
||||
|
||||
/obj/item/device/taperecorder/verb/record()
|
||||
set name = "Start Recording"
|
||||
set category = "Object"
|
||||
|
||||
if(!can_use(usr))
|
||||
return
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
return
|
||||
if(playing)
|
||||
return
|
||||
|
||||
if(mytape.used_capacity < mytape.max_capacity)
|
||||
to_chat(usr, "<span class='notice'>Recording started.</span>")
|
||||
recording = 1
|
||||
update_icon()
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording started."
|
||||
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
|
||||
var/max = mytape.max_capacity
|
||||
for(used, used < max)
|
||||
if(recording == 0)
|
||||
break
|
||||
mytape.used_capacity++
|
||||
used++
|
||||
sleep(10)
|
||||
recording = 0
|
||||
update_icon()
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>The tape is full.</span>")
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/stop()
|
||||
set name = "Stop"
|
||||
set category = "Object"
|
||||
|
||||
if(!can_use(usr))
|
||||
return
|
||||
|
||||
if(recording)
|
||||
recording = 0
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording stopped."
|
||||
to_chat(usr, "<span class='notice'>Recording stopped.</span>")
|
||||
return
|
||||
else if(playing)
|
||||
playing = 0
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: Playback stopped.</font>")
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/play()
|
||||
set name = "Play Tape"
|
||||
set category = "Object"
|
||||
|
||||
if(!can_use(usr))
|
||||
return
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
return
|
||||
if(playing)
|
||||
return
|
||||
|
||||
playing = 1
|
||||
update_icon()
|
||||
to_chat(usr, "<span class='notice'>Playing started.</span>")
|
||||
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
|
||||
var/max = mytape.max_capacity
|
||||
for(var/i = 1, used < max, sleep(10 * playsleepseconds))
|
||||
if(!mytape)
|
||||
break
|
||||
if(playing == 0)
|
||||
break
|
||||
if(mytape.storedinfo.len < i)
|
||||
break
|
||||
say(mytape.storedinfo[i])
|
||||
if(mytape.storedinfo.len < i + 1)
|
||||
playsleepseconds = 1
|
||||
sleep(10)
|
||||
say("End of recording.")
|
||||
else
|
||||
playsleepseconds = mytape.timestamp[i + 1] - mytape.timestamp[i]
|
||||
if(playsleepseconds > 14)
|
||||
sleep(10)
|
||||
say("Skipping [playsleepseconds] seconds of silence")
|
||||
playsleepseconds = 1
|
||||
i++
|
||||
|
||||
playing = 0
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/attack_self(mob/user)
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
stop()
|
||||
else
|
||||
record()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/print_transcript()
|
||||
set name = "Print Transcript"
|
||||
set category = "Object"
|
||||
|
||||
if(!can_use(usr))
|
||||
return
|
||||
if(!mytape)
|
||||
return
|
||||
if(!canprint)
|
||||
to_chat(usr, "<span class='notice'>The recorder can't print that fast!</span>")
|
||||
return
|
||||
if(recording || playing)
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='notice'>Transcript printed.</span>")
|
||||
var/obj/item/paper/P = new /obj/item/paper(get_turf(src))
|
||||
var/t1 = "<B>Transcript:</B><BR><BR>"
|
||||
for(var/i = 1, mytape.storedinfo.len >= i, i++)
|
||||
t1 += "[mytape.storedinfo[i]]<BR>"
|
||||
P.info = t1
|
||||
P.name = "paper- 'Transcript'"
|
||||
usr.put_in_hands(P)
|
||||
canprint = 0
|
||||
sleep(300)
|
||||
canprint = 1
|
||||
|
||||
|
||||
//empty tape recorders
|
||||
/obj/item/device/taperecorder/empty
|
||||
starting_tape_type = null
|
||||
|
||||
|
||||
/obj/item/device/tape
|
||||
name = "tape"
|
||||
desc = "A magnetic tape that can hold up to ten minutes of content."
|
||||
icon_state = "tape_white"
|
||||
item_state = "analyzer"
|
||||
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)
|
||||
force = 1
|
||||
throwforce = 0
|
||||
var/max_capacity = 600
|
||||
var/used_capacity = 0
|
||||
var/list/storedinfo = list()
|
||||
var/list/timestamp = list()
|
||||
var/ruined = 0
|
||||
|
||||
/obj/item/device/tape/fire_act(exposed_temperature, exposed_volume)
|
||||
ruin()
|
||||
..()
|
||||
|
||||
/obj/item/device/tape/attack_self(mob/user)
|
||||
if(!ruined)
|
||||
to_chat(user, "<span class='notice'>You pull out all the tape!</span>")
|
||||
ruin()
|
||||
|
||||
|
||||
/obj/item/device/tape/proc/ruin()
|
||||
//Lets not add infinite amounts of overlays when our fireact is called
|
||||
//repeatedly
|
||||
if(!ruined)
|
||||
add_overlay("ribbonoverlay")
|
||||
ruined = 1
|
||||
|
||||
|
||||
/obj/item/device/tape/proc/fix()
|
||||
cut_overlay("ribbonoverlay")
|
||||
ruined = 0
|
||||
|
||||
|
||||
/obj/item/device/tape/attackby(obj/item/I, mob/user, params)
|
||||
if(ruined)
|
||||
var/delay = -1
|
||||
if (istype(I, /obj/item/screwdriver))
|
||||
delay = 120*I.toolspeed
|
||||
else if(istype(I, /obj/item/pen))
|
||||
delay = 120*1.5
|
||||
if (delay != -1)
|
||||
to_chat(user, "<span class='notice'>You start winding the tape back in...</span>")
|
||||
if(do_after(user, delay, target = src))
|
||||
to_chat(user, "<span class='notice'>You wound the tape back in.</span>")
|
||||
fix()
|
||||
|
||||
//Random colour tapes
|
||||
/obj/item/device/tape/random/New()
|
||||
icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"
|
||||
..()
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
materials = list(MAT_METAL=20, MAT_GLASS=5)
|
||||
force = 1
|
||||
throwforce = 0
|
||||
var/max_capacity = 600
|
||||
var/used_capacity = 0
|
||||
var/list/storedinfo = list()
|
||||
var/list/timestamp = list()
|
||||
var/ruined = 0
|
||||
|
||||
/obj/item/device/tape/fire_act(exposed_temperature, exposed_volume)
|
||||
ruin()
|
||||
..()
|
||||
|
||||
/obj/item/device/tape/attack_self(mob/user)
|
||||
if(!ruined)
|
||||
to_chat(user, "<span class='notice'>You pull out all the tape!</span>")
|
||||
ruin()
|
||||
|
||||
|
||||
/obj/item/device/tape/proc/ruin()
|
||||
//Lets not add infinite amounts of overlays when our fireact is called
|
||||
//repeatedly
|
||||
if(!ruined)
|
||||
add_overlay("ribbonoverlay")
|
||||
ruined = 1
|
||||
|
||||
|
||||
/obj/item/device/tape/proc/fix()
|
||||
cut_overlay("ribbonoverlay")
|
||||
ruined = 0
|
||||
|
||||
|
||||
/obj/item/device/tape/attackby(obj/item/I, mob/user, params)
|
||||
if(ruined)
|
||||
var/delay = -1
|
||||
if (istype(I, /obj/item/screwdriver))
|
||||
delay = 120*I.toolspeed
|
||||
else if(istype(I, /obj/item/pen))
|
||||
delay = 120*1.5
|
||||
if (delay != -1)
|
||||
to_chat(user, "<span class='notice'>You start winding the tape back in...</span>")
|
||||
if(do_after(user, delay, target = src))
|
||||
to_chat(user, "<span class='notice'>You wound the tape back in.</span>")
|
||||
fix()
|
||||
|
||||
//Random colour tapes
|
||||
/obj/item/device/tape/random/New()
|
||||
icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"
|
||||
..()
|
||||
|
||||
@@ -147,7 +147,7 @@ effective or pretty fucking useless.
|
||||
usr.set_machine(src)
|
||||
if(href_list["rad"])
|
||||
irradiate = !irradiate
|
||||
|
||||
|
||||
else if(href_list["stealthy"])
|
||||
stealth = !stealth
|
||||
|
||||
@@ -242,11 +242,10 @@ effective or pretty fucking useless.
|
||||
var/range = 12
|
||||
|
||||
/obj/item/device/jammer/attack_self(mob/user)
|
||||
to_chat(user,"<span class='notice'>You [active ? "deactivate" : "activate"] the [src]<span>")
|
||||
to_chat(user,"<span class='notice'>You [active ? "deactivate" : "activate"] the [src].</span>")
|
||||
active = !active
|
||||
if(active)
|
||||
GLOB.active_jammers |= src
|
||||
else
|
||||
GLOB.active_jammers -= src
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -1,370 +1,370 @@
|
||||
/obj/item/dnainjector
|
||||
name = "\improper DNA injector"
|
||||
desc = "This injects the person with DNA."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "dnainjector"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
origin_tech = "biotech=1"
|
||||
|
||||
var/damage_coeff = 1
|
||||
var/list/fields
|
||||
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() && !(RADIMMUNE in M.dna.species.species_traits) && !(M.disabilities & 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)
|
||||
message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] <span class='danger'>(MONKEY)</span>")
|
||||
log_msg += " (MONKEY)"
|
||||
HM.force_give(M)
|
||||
if(fields)
|
||||
if(fields["name"] && fields["UE"] && fields["blood_type"])
|
||||
M.real_name = fields["name"]
|
||||
M.dna.unique_enzymes = fields["UE"]
|
||||
M.name = M.real_name
|
||||
M.dna.blood_type = fields["blood_type"]
|
||||
if(fields["UI"]) //UI+UE
|
||||
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
log_attack(log_msg)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/dnainjector/attack(mob/target, mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return
|
||||
if(used)
|
||||
to_chat(user, "<span class='warning'>This injector is used up!</span>")
|
||||
return
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/humantarget = target
|
||||
if (!humantarget.can_inject(user, 1))
|
||||
return
|
||||
add_logs(user, target, "attempted to inject", src)
|
||||
|
||||
if(target != user)
|
||||
target.visible_message("<span class='danger'>[user] is trying to inject [target] with [src]!</span>", "<span class='userdanger'>[user] is trying to inject [target] with [src]!</span>")
|
||||
if(!do_mob(user, target) || used)
|
||||
return
|
||||
target.visible_message("<span class='danger'>[user] injects [target] with the syringe with [src]!", \
|
||||
"<span class='userdanger'>[user] injects [target] with the syringe with [src]!")
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You inject yourself with [src].</span>")
|
||||
|
||||
add_logs(user, target, "injected", src)
|
||||
|
||||
if(!inject(target, user)) //Now we actually do the heavy lifting.
|
||||
to_chat(user, "<span class='notice'>It appears that [target] does not have compatible DNA.</span>")
|
||||
|
||||
used = 1
|
||||
icon_state = "dnainjector0"
|
||||
desc += " This one is used up."
|
||||
|
||||
|
||||
/obj/item/dnainjector/antihulk
|
||||
name = "\improper DNA injector (Anti-Hulk)"
|
||||
desc = "Cures green skin."
|
||||
remove_mutations_static = 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)
|
||||
|
||||
/obj/item/dnainjector/xraymut
|
||||
name = "\improper DNA injector (Xray)"
|
||||
desc = "Finally you can see what the Captain does."
|
||||
add_mutations_static = list(XRAY)
|
||||
|
||||
/obj/item/dnainjector/antixray
|
||||
name = "\improper DNA injector (Anti-Xray)"
|
||||
desc = "It will make you see harder."
|
||||
remove_mutations_static = list(XRAY)
|
||||
|
||||
/////////////////////////////////////
|
||||
/obj/item/dnainjector/antiglasses
|
||||
name = "\improper DNA injector (Anti-Glasses)"
|
||||
desc = "Toss away those glasses!"
|
||||
remove_mutations_static = list(BADSIGHT)
|
||||
|
||||
/obj/item/dnainjector/glassesmut
|
||||
name = "\improper DNA injector (Glasses)"
|
||||
desc = "Will make you need dorkish glasses."
|
||||
add_mutations_static = list(BADSIGHT)
|
||||
|
||||
/obj/item/dnainjector/epimut
|
||||
name = "\improper DNA injector (Epi.)"
|
||||
desc = "Shake shake shake the room!"
|
||||
add_mutations_static = 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)
|
||||
////////////////////////////////////
|
||||
/obj/item/dnainjector/anticough
|
||||
name = "\improper DNA injector (Anti-Cough)"
|
||||
desc = "Will stop that aweful noise."
|
||||
remove_mutations_static = 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)
|
||||
|
||||
/obj/item/dnainjector/antidwarf
|
||||
name = "\improper DNA injector (Anti-Dwarfism)"
|
||||
desc = "Helps you grow big and strong."
|
||||
remove_mutations_static = list(DWARFISM)
|
||||
|
||||
/obj/item/dnainjector/dwarf
|
||||
name = "\improper DNA injector (Dwarfism)"
|
||||
desc = "It's a small world after all."
|
||||
add_mutations_static = list(DWARFISM)
|
||||
|
||||
/obj/item/dnainjector/clumsymut
|
||||
name = "\improper DNA injector (Clumsy)"
|
||||
desc = "Makes clown minions."
|
||||
add_mutations_static = list(CLOWNMUT)
|
||||
|
||||
/obj/item/dnainjector/anticlumsy
|
||||
name = "\improper DNA injector (Anti-Clumsy)"
|
||||
desc = "Apply this for Security Clown."
|
||||
remove_mutations_static = list(CLOWNMUT)
|
||||
|
||||
/obj/item/dnainjector/antitour
|
||||
name = "\improper DNA injector (Anti-Tour.)"
|
||||
desc = "Will cure tourrets."
|
||||
remove_mutations_static = 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)
|
||||
|
||||
/obj/item/dnainjector/stuttmut
|
||||
name = "\improper DNA injector (Stutt.)"
|
||||
desc = "Makes you s-s-stuttterrr"
|
||||
add_mutations_static = list(NERVOUS)
|
||||
|
||||
/obj/item/dnainjector/antistutt
|
||||
name = "\improper DNA injector (Anti-Stutt.)"
|
||||
desc = "Fixes that speaking impairment."
|
||||
remove_mutations_static = list(NERVOUS)
|
||||
|
||||
/obj/item/dnainjector/antifire
|
||||
name = "\improper DNA injector (Anti-Fire)"
|
||||
desc = "Cures fire."
|
||||
remove_mutations_static = list(COLDRES)
|
||||
|
||||
/obj/item/dnainjector/firemut
|
||||
name = "\improper DNA injector (Fire)"
|
||||
desc = "Gives you fire."
|
||||
add_mutations_static = list(COLDRES)
|
||||
|
||||
/obj/item/dnainjector/blindmut
|
||||
name = "\improper DNA injector (Blind)"
|
||||
desc = "Makes you not see anything."
|
||||
add_mutations_static = list(BLINDMUT)
|
||||
|
||||
/obj/item/dnainjector/antiblind
|
||||
name = "\improper DNA injector (Anti-Blind)"
|
||||
desc = "IT'S A MIRACLE!!!"
|
||||
remove_mutations_static = 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)
|
||||
|
||||
/obj/item/dnainjector/telemut
|
||||
name = "\improper DNA injector (Tele.)"
|
||||
desc = "Super brain man!"
|
||||
add_mutations_static = list(TK)
|
||||
|
||||
/obj/item/dnainjector/telemut/darkbundle
|
||||
name = "\improper DNA injector"
|
||||
desc = "Good. Let the hate flow through you."
|
||||
|
||||
/obj/item/dnainjector/deafmut
|
||||
name = "\improper DNA injector (Deaf)"
|
||||
desc = "Sorry, what did you say?"
|
||||
add_mutations_static = list(DEAFMUT)
|
||||
|
||||
/obj/item/dnainjector/antideaf
|
||||
name = "\improper DNA injector (Anti-Deaf)"
|
||||
desc = "Will make you hear once more."
|
||||
remove_mutations_static = list(DEAFMUT)
|
||||
|
||||
/obj/item/dnainjector/h2m
|
||||
name = "\improper DNA injector (Human > Monkey)"
|
||||
desc = "Will make you a flea bag."
|
||||
add_mutations_static = list(RACEMUT)
|
||||
|
||||
/obj/item/dnainjector/m2h
|
||||
name = "\improper DNA injector (Monkey > Human)"
|
||||
desc = "Will make you...less hairy."
|
||||
remove_mutations_static = list(RACEMUT)
|
||||
|
||||
/obj/item/dnainjector/antichameleon
|
||||
name = "\improper DNA injector (Anti-Chameleon)"
|
||||
remove_mutations_static = list(CHAMELEON)
|
||||
|
||||
/obj/item/dnainjector/chameleonmut
|
||||
name = "\improper DNA injector (Chameleon)"
|
||||
add_mutations_static = list(CHAMELEON)
|
||||
|
||||
/obj/item/dnainjector/antiwacky
|
||||
name = "\improper DNA injector (Anti-Wacky)"
|
||||
remove_mutations_static = list(WACKY)
|
||||
|
||||
/obj/item/dnainjector/wackymut
|
||||
name = "\improper DNA injector (Wacky)"
|
||||
add_mutations_static = list(WACKY)
|
||||
|
||||
/obj/item/dnainjector/antimute
|
||||
name = "\improper DNA injector (Anti-Mute)"
|
||||
remove_mutations_static = list(MUT_MUTE)
|
||||
|
||||
/obj/item/dnainjector/mutemut
|
||||
name = "\improper DNA injector (Mute)"
|
||||
add_mutations_static = list(MUT_MUTE)
|
||||
|
||||
/obj/item/dnainjector/antismile
|
||||
name = "\improper DNA injector (Anti-Smile)"
|
||||
remove_mutations_static = list(SMILE)
|
||||
|
||||
/obj/item/dnainjector/smilemut
|
||||
name = "\improper DNA injector (Smile)"
|
||||
add_mutations_static = list(SMILE)
|
||||
|
||||
/obj/item/dnainjector/unintelligablemut
|
||||
name = "\improper DNA injector (Unintelligable)"
|
||||
add_mutations_static = list(UNINTELLIGABLE)
|
||||
|
||||
/obj/item/dnainjector/antiunintelligable
|
||||
name = "\improper DNA injector (Anti-Unintelligable)"
|
||||
remove_mutations_static = list(UNINTELLIGABLE)
|
||||
|
||||
/obj/item/dnainjector/swedishmut
|
||||
name = "\improper DNA injector (Swedish)"
|
||||
add_mutations_static = list(SWEDISH)
|
||||
|
||||
/obj/item/dnainjector/antiswedish
|
||||
name = "\improper DNA injector (Anti-Swedish)"
|
||||
remove_mutations_static = list(SWEDISH)
|
||||
|
||||
/obj/item/dnainjector/chavmut
|
||||
name = "\improper DNA injector (Chav)"
|
||||
add_mutations_static = list(CHAV)
|
||||
|
||||
/obj/item/dnainjector/antichav
|
||||
name = "\improper DNA injector (Anti-Chav)"
|
||||
remove_mutations_static = list(CHAV)
|
||||
|
||||
/obj/item/dnainjector/elvismut
|
||||
name = "\improper DNA injector (Elvis)"
|
||||
add_mutations_static = list(ELVIS)
|
||||
|
||||
/obj/item/dnainjector/antielvis
|
||||
name = "\improper DNA injector (Anti-Elvis)"
|
||||
remove_mutations_static = list(ELVIS)
|
||||
|
||||
/obj/item/dnainjector/lasereyesmut
|
||||
name = "\improper DNA injector (Laser Eyes)"
|
||||
add_mutations_static = list(LASEREYES)
|
||||
|
||||
/obj/item/dnainjector/antilasereyes
|
||||
name = "\improper DNA injector (Anti-Laser Eyes)"
|
||||
remove_mutations_static = list(LASEREYES)
|
||||
|
||||
/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
|
||||
|
||||
if(M.has_dna() && !(M.disabilities & 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]"
|
||||
var/endtime = world.time+duration
|
||||
for(var/datum/mutation/human/HM in remove_mutations)
|
||||
if(HM.name == RACEMUT)
|
||||
if(ishuman(M))
|
||||
continue
|
||||
M = HM.force_lose(M)
|
||||
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]))
|
||||
continue //Skip permanent mutations we already have.
|
||||
if(HM.name == RACEMUT && ishuman(M))
|
||||
message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] <span class='danger'>(MONKEY)</span>")
|
||||
log_msg += " (MONKEY)"
|
||||
M = HM.force_give(M)
|
||||
else
|
||||
HM.force_give(M)
|
||||
M.dna.temporary_mutations[HM.name] = endtime
|
||||
if(fields)
|
||||
if(fields["name"] && fields["UE"] && fields["blood_type"])
|
||||
if(!M.dna.previous["name"])
|
||||
M.dna.previous["name"] = M.real_name
|
||||
if(!M.dna.previous["UE"])
|
||||
M.dna.previous["UE"] = M.dna.unique_enzymes
|
||||
if(!M.dna.previous["blood_type"])
|
||||
M.dna.previous["blood_type"] = M.dna.blood_type
|
||||
M.real_name = fields["name"]
|
||||
M.dna.unique_enzymes = fields["UE"]
|
||||
M.name = M.real_name
|
||||
M.dna.blood_type = fields["blood_type"]
|
||||
M.dna.temporary_mutations[UE_CHANGED] = endtime
|
||||
if(fields["UI"]) //UI+UE
|
||||
if(!M.dna.previous["UI"])
|
||||
M.dna.previous["UI"] = M.dna.uni_identity
|
||||
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
M.dna.temporary_mutations[UI_CHANGED] = endtime
|
||||
log_attack(log_msg)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/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)
|
||||
|
||||
/obj/item/dnainjector/timed/h2m
|
||||
name = "\improper DNA injector (Human > Monkey)"
|
||||
desc = "Will make you a flea bag."
|
||||
add_mutations_static = list(RACEMUT)
|
||||
/obj/item/dnainjector
|
||||
name = "\improper DNA injector"
|
||||
desc = "This injects the person with DNA."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "dnainjector"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
origin_tech = "biotech=1"
|
||||
|
||||
var/damage_coeff = 1
|
||||
var/list/fields
|
||||
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() && !(RADIMMUNE in M.dna.species.species_traits) && !(M.disabilities & 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)
|
||||
message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] <span class='danger'>(MONKEY)</span>")
|
||||
log_msg += " (MONKEY)"
|
||||
HM.force_give(M)
|
||||
if(fields)
|
||||
if(fields["name"] && fields["UE"] && fields["blood_type"])
|
||||
M.real_name = fields["name"]
|
||||
M.dna.unique_enzymes = fields["UE"]
|
||||
M.name = M.real_name
|
||||
M.dna.blood_type = fields["blood_type"]
|
||||
if(fields["UI"]) //UI+UE
|
||||
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
log_attack(log_msg)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/dnainjector/attack(mob/target, mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return
|
||||
if(used)
|
||||
to_chat(user, "<span class='warning'>This injector is used up!</span>")
|
||||
return
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/humantarget = target
|
||||
if (!humantarget.can_inject(user, 1))
|
||||
return
|
||||
add_logs(user, target, "attempted to inject", src)
|
||||
|
||||
if(target != user)
|
||||
target.visible_message("<span class='danger'>[user] is trying to inject [target] with [src]!</span>", "<span class='userdanger'>[user] is trying to inject [target] with [src]!</span>")
|
||||
if(!do_mob(user, target) || used)
|
||||
return
|
||||
target.visible_message("<span class='danger'>[user] injects [target] with the syringe with [src]!", \
|
||||
"<span class='userdanger'>[user] injects [target] with the syringe with [src]!</span>")
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You inject yourself with [src].</span>")
|
||||
|
||||
add_logs(user, target, "injected", src)
|
||||
|
||||
if(!inject(target, user)) //Now we actually do the heavy lifting.
|
||||
to_chat(user, "<span class='notice'>It appears that [target] does not have compatible DNA.</span>")
|
||||
|
||||
used = 1
|
||||
icon_state = "dnainjector0"
|
||||
desc += " This one is used up."
|
||||
|
||||
|
||||
/obj/item/dnainjector/antihulk
|
||||
name = "\improper DNA injector (Anti-Hulk)"
|
||||
desc = "Cures green skin."
|
||||
remove_mutations_static = 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)
|
||||
|
||||
/obj/item/dnainjector/xraymut
|
||||
name = "\improper DNA injector (Xray)"
|
||||
desc = "Finally you can see what the Captain does."
|
||||
add_mutations_static = list(XRAY)
|
||||
|
||||
/obj/item/dnainjector/antixray
|
||||
name = "\improper DNA injector (Anti-Xray)"
|
||||
desc = "It will make you see harder."
|
||||
remove_mutations_static = list(XRAY)
|
||||
|
||||
/////////////////////////////////////
|
||||
/obj/item/dnainjector/antiglasses
|
||||
name = "\improper DNA injector (Anti-Glasses)"
|
||||
desc = "Toss away those glasses!"
|
||||
remove_mutations_static = list(BADSIGHT)
|
||||
|
||||
/obj/item/dnainjector/glassesmut
|
||||
name = "\improper DNA injector (Glasses)"
|
||||
desc = "Will make you need dorkish glasses."
|
||||
add_mutations_static = list(BADSIGHT)
|
||||
|
||||
/obj/item/dnainjector/epimut
|
||||
name = "\improper DNA injector (Epi.)"
|
||||
desc = "Shake shake shake the room!"
|
||||
add_mutations_static = 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)
|
||||
////////////////////////////////////
|
||||
/obj/item/dnainjector/anticough
|
||||
name = "\improper DNA injector (Anti-Cough)"
|
||||
desc = "Will stop that aweful noise."
|
||||
remove_mutations_static = 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)
|
||||
|
||||
/obj/item/dnainjector/antidwarf
|
||||
name = "\improper DNA injector (Anti-Dwarfism)"
|
||||
desc = "Helps you grow big and strong."
|
||||
remove_mutations_static = list(DWARFISM)
|
||||
|
||||
/obj/item/dnainjector/dwarf
|
||||
name = "\improper DNA injector (Dwarfism)"
|
||||
desc = "It's a small world after all."
|
||||
add_mutations_static = list(DWARFISM)
|
||||
|
||||
/obj/item/dnainjector/clumsymut
|
||||
name = "\improper DNA injector (Clumsy)"
|
||||
desc = "Makes clown minions."
|
||||
add_mutations_static = list(CLOWNMUT)
|
||||
|
||||
/obj/item/dnainjector/anticlumsy
|
||||
name = "\improper DNA injector (Anti-Clumsy)"
|
||||
desc = "Apply this for Security Clown."
|
||||
remove_mutations_static = list(CLOWNMUT)
|
||||
|
||||
/obj/item/dnainjector/antitour
|
||||
name = "\improper DNA injector (Anti-Tour.)"
|
||||
desc = "Will cure tourrets."
|
||||
remove_mutations_static = 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)
|
||||
|
||||
/obj/item/dnainjector/stuttmut
|
||||
name = "\improper DNA injector (Stutt.)"
|
||||
desc = "Makes you s-s-stuttterrr"
|
||||
add_mutations_static = list(NERVOUS)
|
||||
|
||||
/obj/item/dnainjector/antistutt
|
||||
name = "\improper DNA injector (Anti-Stutt.)"
|
||||
desc = "Fixes that speaking impairment."
|
||||
remove_mutations_static = list(NERVOUS)
|
||||
|
||||
/obj/item/dnainjector/antifire
|
||||
name = "\improper DNA injector (Anti-Fire)"
|
||||
desc = "Cures fire."
|
||||
remove_mutations_static = list(COLDRES)
|
||||
|
||||
/obj/item/dnainjector/firemut
|
||||
name = "\improper DNA injector (Fire)"
|
||||
desc = "Gives you fire."
|
||||
add_mutations_static = list(COLDRES)
|
||||
|
||||
/obj/item/dnainjector/blindmut
|
||||
name = "\improper DNA injector (Blind)"
|
||||
desc = "Makes you not see anything."
|
||||
add_mutations_static = list(BLINDMUT)
|
||||
|
||||
/obj/item/dnainjector/antiblind
|
||||
name = "\improper DNA injector (Anti-Blind)"
|
||||
desc = "IT'S A MIRACLE!!!"
|
||||
remove_mutations_static = 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)
|
||||
|
||||
/obj/item/dnainjector/telemut
|
||||
name = "\improper DNA injector (Tele.)"
|
||||
desc = "Super brain man!"
|
||||
add_mutations_static = list(TK)
|
||||
|
||||
/obj/item/dnainjector/telemut/darkbundle
|
||||
name = "\improper DNA injector"
|
||||
desc = "Good. Let the hate flow through you."
|
||||
|
||||
/obj/item/dnainjector/deafmut
|
||||
name = "\improper DNA injector (Deaf)"
|
||||
desc = "Sorry, what did you say?"
|
||||
add_mutations_static = list(DEAFMUT)
|
||||
|
||||
/obj/item/dnainjector/antideaf
|
||||
name = "\improper DNA injector (Anti-Deaf)"
|
||||
desc = "Will make you hear once more."
|
||||
remove_mutations_static = list(DEAFMUT)
|
||||
|
||||
/obj/item/dnainjector/h2m
|
||||
name = "\improper DNA injector (Human > Monkey)"
|
||||
desc = "Will make you a flea bag."
|
||||
add_mutations_static = list(RACEMUT)
|
||||
|
||||
/obj/item/dnainjector/m2h
|
||||
name = "\improper DNA injector (Monkey > Human)"
|
||||
desc = "Will make you...less hairy."
|
||||
remove_mutations_static = list(RACEMUT)
|
||||
|
||||
/obj/item/dnainjector/antichameleon
|
||||
name = "\improper DNA injector (Anti-Chameleon)"
|
||||
remove_mutations_static = list(CHAMELEON)
|
||||
|
||||
/obj/item/dnainjector/chameleonmut
|
||||
name = "\improper DNA injector (Chameleon)"
|
||||
add_mutations_static = list(CHAMELEON)
|
||||
|
||||
/obj/item/dnainjector/antiwacky
|
||||
name = "\improper DNA injector (Anti-Wacky)"
|
||||
remove_mutations_static = list(WACKY)
|
||||
|
||||
/obj/item/dnainjector/wackymut
|
||||
name = "\improper DNA injector (Wacky)"
|
||||
add_mutations_static = list(WACKY)
|
||||
|
||||
/obj/item/dnainjector/antimute
|
||||
name = "\improper DNA injector (Anti-Mute)"
|
||||
remove_mutations_static = list(MUT_MUTE)
|
||||
|
||||
/obj/item/dnainjector/mutemut
|
||||
name = "\improper DNA injector (Mute)"
|
||||
add_mutations_static = list(MUT_MUTE)
|
||||
|
||||
/obj/item/dnainjector/antismile
|
||||
name = "\improper DNA injector (Anti-Smile)"
|
||||
remove_mutations_static = list(SMILE)
|
||||
|
||||
/obj/item/dnainjector/smilemut
|
||||
name = "\improper DNA injector (Smile)"
|
||||
add_mutations_static = list(SMILE)
|
||||
|
||||
/obj/item/dnainjector/unintelligablemut
|
||||
name = "\improper DNA injector (Unintelligable)"
|
||||
add_mutations_static = list(UNINTELLIGABLE)
|
||||
|
||||
/obj/item/dnainjector/antiunintelligable
|
||||
name = "\improper DNA injector (Anti-Unintelligable)"
|
||||
remove_mutations_static = list(UNINTELLIGABLE)
|
||||
|
||||
/obj/item/dnainjector/swedishmut
|
||||
name = "\improper DNA injector (Swedish)"
|
||||
add_mutations_static = list(SWEDISH)
|
||||
|
||||
/obj/item/dnainjector/antiswedish
|
||||
name = "\improper DNA injector (Anti-Swedish)"
|
||||
remove_mutations_static = list(SWEDISH)
|
||||
|
||||
/obj/item/dnainjector/chavmut
|
||||
name = "\improper DNA injector (Chav)"
|
||||
add_mutations_static = list(CHAV)
|
||||
|
||||
/obj/item/dnainjector/antichav
|
||||
name = "\improper DNA injector (Anti-Chav)"
|
||||
remove_mutations_static = list(CHAV)
|
||||
|
||||
/obj/item/dnainjector/elvismut
|
||||
name = "\improper DNA injector (Elvis)"
|
||||
add_mutations_static = list(ELVIS)
|
||||
|
||||
/obj/item/dnainjector/antielvis
|
||||
name = "\improper DNA injector (Anti-Elvis)"
|
||||
remove_mutations_static = list(ELVIS)
|
||||
|
||||
/obj/item/dnainjector/lasereyesmut
|
||||
name = "\improper DNA injector (Laser Eyes)"
|
||||
add_mutations_static = list(LASEREYES)
|
||||
|
||||
/obj/item/dnainjector/antilasereyes
|
||||
name = "\improper DNA injector (Anti-Laser Eyes)"
|
||||
remove_mutations_static = list(LASEREYES)
|
||||
|
||||
/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
|
||||
|
||||
if(M.has_dna() && !(M.disabilities & 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]"
|
||||
var/endtime = world.time+duration
|
||||
for(var/datum/mutation/human/HM in remove_mutations)
|
||||
if(HM.name == RACEMUT)
|
||||
if(ishuman(M))
|
||||
continue
|
||||
M = HM.force_lose(M)
|
||||
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]))
|
||||
continue //Skip permanent mutations we already have.
|
||||
if(HM.name == RACEMUT && ishuman(M))
|
||||
message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with the [name] <span class='danger'>(MONKEY)</span>")
|
||||
log_msg += " (MONKEY)"
|
||||
M = HM.force_give(M)
|
||||
else
|
||||
HM.force_give(M)
|
||||
M.dna.temporary_mutations[HM.name] = endtime
|
||||
if(fields)
|
||||
if(fields["name"] && fields["UE"] && fields["blood_type"])
|
||||
if(!M.dna.previous["name"])
|
||||
M.dna.previous["name"] = M.real_name
|
||||
if(!M.dna.previous["UE"])
|
||||
M.dna.previous["UE"] = M.dna.unique_enzymes
|
||||
if(!M.dna.previous["blood_type"])
|
||||
M.dna.previous["blood_type"] = M.dna.blood_type
|
||||
M.real_name = fields["name"]
|
||||
M.dna.unique_enzymes = fields["UE"]
|
||||
M.name = M.real_name
|
||||
M.dna.blood_type = fields["blood_type"]
|
||||
M.dna.temporary_mutations[UE_CHANGED] = endtime
|
||||
if(fields["UI"]) //UI+UE
|
||||
if(!M.dna.previous["UI"])
|
||||
M.dna.previous["UI"] = M.dna.uni_identity
|
||||
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
M.dna.temporary_mutations[UI_CHANGED] = endtime
|
||||
log_attack(log_msg)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/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)
|
||||
|
||||
/obj/item/dnainjector/timed/h2m
|
||||
name = "\improper DNA injector (Human > Monkey)"
|
||||
desc = "Will make you a flea bag."
|
||||
add_mutations_static = list(RACEMUT)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
desc = "PRESENTS!!!! eek!"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "giftdeliverypackage3"
|
||||
item_state = "gift1"
|
||||
item_state = "gift"
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/a_gift/New()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "plastic explosive"
|
||||
desc = "Used to put holes in specific areas without too much extra hole."
|
||||
icon_state = "plastic-explosive0"
|
||||
item_state = "plastic-explosive"
|
||||
item_state = "plasticx"
|
||||
flags_1 = NOBLUDGEON_1
|
||||
flags_2 = NO_EMP_WIRES_2
|
||||
det_time = 10
|
||||
@@ -135,8 +135,6 @@
|
||||
message_say = "FOR NAR-SIE!"
|
||||
else if(role == "revolutionary" || role == "head revolutionary")
|
||||
message_say = "VIVA LA REVOLUTION!"
|
||||
else if(user.mind.gang_datum)
|
||||
message_say = "[uppertext(user.mind.gang_datum.name)] RULES!"
|
||||
user.say(message_say)
|
||||
explosion(user,0,2,0) //Cheap explosion imitation because putting prime() here causes runtimes
|
||||
user.gib(1, 1)
|
||||
@@ -192,8 +190,6 @@
|
||||
message_say = "FOR NAR-SIE!"
|
||||
else if(role == "revolutionary" || role == "head revolutionary")
|
||||
message_say = "VIVA LA REVOLUTION!"
|
||||
else if(user.mind.gang_datum)
|
||||
message_say = "[uppertext(user.mind.gang_datum.name)] RULES!"
|
||||
user.say(message_say)
|
||||
target = user
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [name] at [ADMIN_COORDJMP(src)]",0,1)
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
desc = "A toolbox painted bright green. Looking at it makes you feel uneasy."
|
||||
icon_state = "his_grace"
|
||||
item_state = "artistic_toolbox"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi'
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
w_class = WEIGHT_CLASS_GIGANTIC
|
||||
origin_tech = "combat=4;engineering=4;syndicate=2"
|
||||
|
||||
@@ -336,6 +336,8 @@
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "carpplushie"
|
||||
item_state = "carp_plushie"
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
force = 15
|
||||
attack_verb = list("bitten", "eaten", "fin slapped")
|
||||
hitsound = 'sound/weapons/bite.ogg'
|
||||
@@ -403,3 +405,14 @@
|
||||
attack_verb = list("poked", "impaled", "pierced", "jabbed")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
|
||||
/obj/item/nullrod/egyptian
|
||||
name = "egyptian staff"
|
||||
desc = "A tutorial in mummification is carved into the staff. You could probably follow the steps yourself if you had some bandages."
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
icon_state = "pharoah_sceptre"
|
||||
item_state = "pharoah_sceptre"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("bashes", "smacks", "whacks")
|
||||
|
||||
@@ -19,19 +19,12 @@
|
||||
|
||||
/obj/item/implant/mindshield/implant(mob/living/target, mob/user, silent = 0)
|
||||
if(..())
|
||||
if((target.mind in (SSticker.mode.head_revolutionaries | SSticker.mode.get_gang_bosses())))
|
||||
if((target.mind in (SSticker.mode.head_revolutionaries)))
|
||||
if(!silent)
|
||||
target.visible_message("<span class='warning'>[target] seems to resist the implant!</span>", "<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
|
||||
removed(target, 1)
|
||||
qdel(src)
|
||||
return 0
|
||||
if(target.mind in SSticker.mode.get_gangsters())
|
||||
SSticker.mode.remove_gangster(target.mind)
|
||||
if(!silent)
|
||||
target.visible_message("<span class='warning'>[src] was destroyed in the process!</span>", "<span class='notice'>You feel a sense of peace and security. You are now protected from brainwashing.</span>")
|
||||
removed(target, 1)
|
||||
qdel(src)
|
||||
return 0
|
||||
if(target.mind in SSticker.mode.revolutionaries)
|
||||
SSticker.mode.remove_revolutionary(target.mind)
|
||||
if(!silent)
|
||||
|
||||
@@ -1,187 +1,188 @@
|
||||
/obj/machinery/implantchair
|
||||
name = "mindshield implanter"
|
||||
desc = "Used to implant occupants with mindshield implants."
|
||||
icon = 'icons/obj/machines/implantchair.dmi'
|
||||
icon_state = "implantchair"
|
||||
density = TRUE
|
||||
opacity = 0
|
||||
anchored = TRUE
|
||||
|
||||
var/ready = TRUE
|
||||
var/replenishing = FALSE
|
||||
|
||||
var/ready_implants = 5
|
||||
var/max_implants = 5
|
||||
var/injection_cooldown = 600
|
||||
var/replenish_cooldown = 6000
|
||||
var/implant_type = /obj/item/implant/mindshield
|
||||
var/auto_inject = FALSE
|
||||
var/auto_replenish = TRUE
|
||||
var/special = FALSE
|
||||
var/special_name = "special function"
|
||||
|
||||
/obj/machinery/implantchair/Initialize()
|
||||
. = ..()
|
||||
open_machine()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = occupant ? 1 : 0
|
||||
data["open"] = state_open
|
||||
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
data["occupant"]["stat"] = mob_occupant.stat
|
||||
|
||||
data["special_name"] = special ? special_name : null
|
||||
data["ready_implants"] = ready_implants
|
||||
data["ready"] = ready
|
||||
data["replenishing"] = replenishing
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/implantchair/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine()
|
||||
. = TRUE
|
||||
if("implant")
|
||||
implant(occupant,usr)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user)
|
||||
if (!istype(M))
|
||||
return
|
||||
if(!ready_implants || !ready)
|
||||
return
|
||||
if(implant_action(M,user))
|
||||
ready_implants--
|
||||
if(!replenishing && auto_replenish)
|
||||
replenishing = TRUE
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
if(injection_cooldown > 0)
|
||||
ready = FALSE
|
||||
addtimer(CALLBACK(src,"set_ready"),injection_cooldown)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/proc/implant_action(mob/living/M)
|
||||
var/obj/item/implant/I = new implant_type
|
||||
if(I.implant(M))
|
||||
visible_message("<span class='warning'>[M] has been implanted by the [name].</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/implantchair/update_icon()
|
||||
icon_state = initial(icon_state)
|
||||
if(state_open)
|
||||
icon_state += "_open"
|
||||
if(occupant)
|
||||
icon_state += "_occupied"
|
||||
if(ready)
|
||||
add_overlay("ready")
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
/obj/machinery/implantchair/proc/replenish()
|
||||
if(ready_implants < max_implants)
|
||||
ready_implants++
|
||||
if(ready_implants < max_implants)
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
else
|
||||
replenishing = FALSE
|
||||
|
||||
/obj/machinery/implantchair/proc/set_ready()
|
||||
ready = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/container_resist(mob/living/user)
|
||||
if(state_open)
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about about a minute.)</span>")
|
||||
audible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>",hearing_distance = 2)
|
||||
|
||||
if(do_after(user, 600, target = src))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/implantchair/relaymove(mob/user)
|
||||
container_resist(user)
|
||||
|
||||
/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser())
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
/obj/machinery/implantchair/close_machine(mob/living/user)
|
||||
if((isnull(user) || istype(user)) && state_open)
|
||||
..(user)
|
||||
if(auto_inject && ready && ready_implants > 0)
|
||||
implant(user,null)
|
||||
|
||||
/obj/machinery/implantchair/genepurge
|
||||
name = "Genetic purifier"
|
||||
desc = "Used to purge human genome of foreign influences"
|
||||
special = TRUE
|
||||
special_name = "Purge genome"
|
||||
injection_cooldown = 0
|
||||
replenish_cooldown = 300
|
||||
|
||||
/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user)
|
||||
if(!istype(H))
|
||||
return 0
|
||||
H.set_species(/datum/species/human, 1)//lizards go home
|
||||
purrbation_remove(H)//remove cats
|
||||
H.dna.remove_all_mutations()//hulks out
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/implantchair/brainwash
|
||||
name = "Neural Imprinter"
|
||||
desc = "Used to <s>indoctrinate</s> rehabilitate hardened recidivists."
|
||||
special_name = "Imprint"
|
||||
injection_cooldown = 3000
|
||||
auto_inject = FALSE
|
||||
auto_replenish = FALSE
|
||||
special = TRUE
|
||||
var/objective = "Obey the law. Praise Nanotrasen."
|
||||
var/custom = FALSE
|
||||
|
||||
/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user)
|
||||
if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway.
|
||||
return 0
|
||||
if(custom)
|
||||
if(!user || !user.Adjacent(src))
|
||||
return 0
|
||||
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
|
||||
message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
var/datum/objective/custom_objective = new/datum/objective(objective)
|
||||
custom_objective.owner = C.mind
|
||||
C.mind.objectives += custom_objective
|
||||
C.mind.announce_objectives()
|
||||
message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
return 1
|
||||
|
||||
/obj/machinery/implantchair
|
||||
name = "mindshield implanter"
|
||||
desc = "Used to implant occupants with mindshield implants."
|
||||
icon = 'icons/obj/machines/implantchair.dmi'
|
||||
icon_state = "implantchair"
|
||||
density = TRUE
|
||||
opacity = 0
|
||||
anchored = TRUE
|
||||
|
||||
var/ready = TRUE
|
||||
var/replenishing = FALSE
|
||||
|
||||
var/ready_implants = 5
|
||||
var/max_implants = 5
|
||||
var/injection_cooldown = 600
|
||||
var/replenish_cooldown = 6000
|
||||
var/implant_type = /obj/item/implant/mindshield
|
||||
var/auto_inject = FALSE
|
||||
var/auto_replenish = TRUE
|
||||
var/special = FALSE
|
||||
var/special_name = "special function"
|
||||
var/message_cooldown
|
||||
var/breakout_time = 1
|
||||
|
||||
/obj/machinery/implantchair/Initialize()
|
||||
. = ..()
|
||||
open_machine()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = occupant ? 1 : 0
|
||||
data["open"] = state_open
|
||||
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
data["occupant"]["stat"] = mob_occupant.stat
|
||||
|
||||
data["special_name"] = special ? special_name : null
|
||||
data["ready_implants"] = ready_implants
|
||||
data["ready"] = ready
|
||||
data["replenishing"] = replenishing
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/implantchair/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine()
|
||||
. = TRUE
|
||||
if("implant")
|
||||
implant(occupant,usr)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user)
|
||||
if (!istype(M))
|
||||
return
|
||||
if(!ready_implants || !ready)
|
||||
return
|
||||
if(implant_action(M,user))
|
||||
ready_implants--
|
||||
if(!replenishing && auto_replenish)
|
||||
replenishing = TRUE
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
if(injection_cooldown > 0)
|
||||
ready = FALSE
|
||||
addtimer(CALLBACK(src,"set_ready"),injection_cooldown)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/proc/implant_action(mob/living/M)
|
||||
var/obj/item/implant/I = new implant_type
|
||||
if(I.implant(M))
|
||||
visible_message("<span class='warning'>[M] has been implanted by the [name].</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/implantchair/update_icon()
|
||||
icon_state = initial(icon_state)
|
||||
if(state_open)
|
||||
icon_state += "_open"
|
||||
if(occupant)
|
||||
icon_state += "_occupied"
|
||||
if(ready)
|
||||
add_overlay("ready")
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
/obj/machinery/implantchair/proc/replenish()
|
||||
if(ready_implants < max_implants)
|
||||
ready_implants++
|
||||
if(ready_implants < max_implants)
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
else
|
||||
replenishing = FALSE
|
||||
|
||||
/obj/machinery/implantchair/proc/set_ready()
|
||||
ready = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/container_resist(mob/living/user)
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/implantchair/relaymove(mob/user)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
|
||||
/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser())
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
/obj/machinery/implantchair/close_machine(mob/living/user)
|
||||
if((isnull(user) || istype(user)) && state_open)
|
||||
..(user)
|
||||
if(auto_inject && ready && ready_implants > 0)
|
||||
implant(user,null)
|
||||
|
||||
/obj/machinery/implantchair/genepurge
|
||||
name = "Genetic purifier"
|
||||
desc = "Used to purge human genome of foreign influences"
|
||||
special = TRUE
|
||||
special_name = "Purge genome"
|
||||
injection_cooldown = 0
|
||||
replenish_cooldown = 300
|
||||
|
||||
/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user)
|
||||
if(!istype(H))
|
||||
return 0
|
||||
H.set_species(/datum/species/human, 1)//lizards go home
|
||||
purrbation_remove(H)//remove cats
|
||||
H.dna.remove_all_mutations()//hulks out
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/implantchair/brainwash
|
||||
name = "Neural Imprinter"
|
||||
desc = "Used to <s>indoctrinate</s> rehabilitate hardened recidivists."
|
||||
special_name = "Imprint"
|
||||
injection_cooldown = 3000
|
||||
auto_inject = FALSE
|
||||
auto_replenish = FALSE
|
||||
special = TRUE
|
||||
var/objective = "Obey the law. Praise Nanotrasen."
|
||||
var/custom = FALSE
|
||||
|
||||
/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user)
|
||||
if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway.
|
||||
return 0
|
||||
if(custom)
|
||||
if(!user || !user.Adjacent(src))
|
||||
return 0
|
||||
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
|
||||
message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
var/datum/objective/custom_objective = new/datum/objective(objective)
|
||||
custom_objective.owner = C.mind
|
||||
C.mind.objectives += custom_objective
|
||||
C.mind.announce_objectives()
|
||||
message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
return 1
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
/obj/item/inducer/examine(mob/living/M)
|
||||
..()
|
||||
if(cell)
|
||||
to_chat(M, "<span class='notice'>It's display shows: [cell.charge]W</span>")
|
||||
to_chat(M, "<span class='notice'>It's display shows: [DisplayPower(cell.charge)]</span>")
|
||||
else
|
||||
to_chat(M,"<span class='notice'>It's display is dark.</span>")
|
||||
if(opened)
|
||||
|
||||
+170
-168
@@ -1,168 +1,170 @@
|
||||
/* Kitchen tools
|
||||
* Contains:
|
||||
* Fork
|
||||
* Kitchen knives
|
||||
* Ritual Knife
|
||||
* Butcher's cleaver
|
||||
* Combat Knife
|
||||
* Rolling Pins
|
||||
*/
|
||||
|
||||
/obj/item/kitchen
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
origin_tech = "materials=1"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
|
||||
|
||||
/obj/item/kitchen/fork
|
||||
name = "fork"
|
||||
desc = "Pointy."
|
||||
icon_state = "fork"
|
||||
force = 5
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throwforce = 0
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
materials = list(MAT_METAL=80)
|
||||
flags_1 = CONDUCT_1
|
||||
attack_verb = list("attacked", "stabbed", "poked")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
|
||||
var/datum/reagent/forkload //used to eat omelette
|
||||
|
||||
/obj/item/kitchen/fork/attack(mob/living/carbon/M, mob/living/carbon/user)
|
||||
if(!istype(M))
|
||||
return ..()
|
||||
|
||||
if(forkload)
|
||||
if(M == user)
|
||||
M.visible_message("<span class='notice'>[user] eats a delicious forkful of omelette!</span>")
|
||||
M.reagents.add_reagent(forkload.id, 1)
|
||||
else
|
||||
M.visible_message("<span class='notice'>[user] feeds [M] a delicious forkful of omelette!</span>")
|
||||
M.reagents.add_reagent(forkload.id, 1)
|
||||
icon_state = "fork"
|
||||
forkload = null
|
||||
|
||||
else if(user.zone_selected == "eyes")
|
||||
if(user.disabilities & CLUMSY && prob(50))
|
||||
M = user
|
||||
return eyestab(M,user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/kitchen/knife
|
||||
name = "kitchen knife"
|
||||
icon_state = "knife"
|
||||
desc = "A general purpose Chef's Knife made by SpaceCook Incorporated. Guaranteed to stay sharp for years to come."
|
||||
flags_1 = CONDUCT_1
|
||||
force = 10
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throwforce = 10
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
throw_speed = 3
|
||||
throw_range = 6
|
||||
materials = list(MAT_METAL=12000)
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
sharpness = IS_SHARP_ACCURATE
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50)
|
||||
var/bayonet = FALSE //Can this be attached to a gun?
|
||||
|
||||
/obj/item/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user)
|
||||
if(user.zone_selected == "eyes")
|
||||
if(user.disabilities & CLUMSY && prob(50))
|
||||
M = user
|
||||
return eyestab(M,user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/kitchen/knife/suicide_act(mob/user)
|
||||
user.visible_message(pick("<span class='suicide'>[user] is slitting [user.p_their()] wrists with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.</span>", \
|
||||
"<span class='suicide'>[user] is slitting [user.p_their()] throat with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.</span>", \
|
||||
"<span class='suicide'>[user] is slitting [user.p_their()] stomach open with the [src.name]! It looks like [user.p_theyre()] trying to commit seppuku.</span>"))
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/kitchen/knife/ritual
|
||||
name = "ritual knife"
|
||||
desc = "The unearthly energies that once powered this blade are now dormant."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "render"
|
||||
item_state = "knife"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/kitchen/knife/butcher
|
||||
name = "butcher's cleaver"
|
||||
icon_state = "butch"
|
||||
desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown by-products."
|
||||
flags_1 = CONDUCT_1
|
||||
force = 15
|
||||
throwforce = 10
|
||||
materials = list(MAT_METAL=18000)
|
||||
attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/kitchen/knife/combat
|
||||
name = "combat knife"
|
||||
icon_state = "buckknife"
|
||||
item_state = "knife"
|
||||
desc = "A military combat utility survival knife."
|
||||
force = 20
|
||||
throwforce = 20
|
||||
origin_tech = "materials=3;combat=4"
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
|
||||
bayonet = TRUE
|
||||
|
||||
/obj/item/kitchen/knife/combat/survival
|
||||
name = "survival knife"
|
||||
icon_state = "survivalknife"
|
||||
item_state = "knife"
|
||||
desc = "A hunting grade survival knife."
|
||||
force = 15
|
||||
throwforce = 15
|
||||
bayonet = TRUE
|
||||
|
||||
/obj/item/kitchen/knife/combat/bone
|
||||
name = "bone dagger"
|
||||
item_state = "bone_dagger"
|
||||
icon_state = "bone_dagger"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
desc = "A sharpened bone. The bare mimimum in survival."
|
||||
force = 15
|
||||
throwforce = 15
|
||||
materials = list()
|
||||
|
||||
/obj/item/kitchen/knife/combat/cyborg
|
||||
name = "cyborg knife"
|
||||
icon = 'icons/obj/items_cyborg.dmi'
|
||||
icon_state = "knife"
|
||||
desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable."
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/kitchen/knife/carrotshiv
|
||||
name = "carrot shiv"
|
||||
icon_state = "carrotshiv"
|
||||
item_state = "carrotshiv"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
desc = "Unlike other carrots, you should probably keep this far away from your eyes."
|
||||
force = 8
|
||||
throwforce = 12//fuck git
|
||||
materials = list()
|
||||
origin_tech = "biotech=3;combat=2"
|
||||
attack_verb = list("shanked", "shivved")
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
|
||||
|
||||
/obj/item/kitchen/rollingpin
|
||||
name = "rolling pin"
|
||||
desc = "Used to knock out the Bartender."
|
||||
icon_state = "rolling_pin"
|
||||
force = 8
|
||||
throwforce = 5
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked")
|
||||
|
||||
/* Trays moved to /obj/item/storage/bag */
|
||||
/* Kitchen tools
|
||||
* Contains:
|
||||
* Fork
|
||||
* Kitchen knives
|
||||
* Ritual Knife
|
||||
* Butcher's cleaver
|
||||
* Combat Knife
|
||||
* Rolling Pins
|
||||
*/
|
||||
|
||||
/obj/item/kitchen
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
origin_tech = "materials=1"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
|
||||
|
||||
/obj/item/kitchen/fork
|
||||
name = "fork"
|
||||
desc = "Pointy."
|
||||
icon_state = "fork"
|
||||
force = 5
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throwforce = 0
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
materials = list(MAT_METAL=80)
|
||||
flags_1 = CONDUCT_1
|
||||
attack_verb = list("attacked", "stabbed", "poked")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
|
||||
var/datum/reagent/forkload //used to eat omelette
|
||||
|
||||
/obj/item/kitchen/fork/attack(mob/living/carbon/M, mob/living/carbon/user)
|
||||
if(!istype(M))
|
||||
return ..()
|
||||
|
||||
if(forkload)
|
||||
if(M == user)
|
||||
M.visible_message("<span class='notice'>[user] eats a delicious forkful of omelette!</span>")
|
||||
M.reagents.add_reagent(forkload.id, 1)
|
||||
else
|
||||
M.visible_message("<span class='notice'>[user] feeds [M] a delicious forkful of omelette!</span>")
|
||||
M.reagents.add_reagent(forkload.id, 1)
|
||||
icon_state = "fork"
|
||||
forkload = null
|
||||
|
||||
else if(user.zone_selected == "eyes")
|
||||
if(user.disabilities & CLUMSY && prob(50))
|
||||
M = user
|
||||
return eyestab(M,user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/kitchen/knife
|
||||
name = "kitchen knife"
|
||||
icon_state = "knife"
|
||||
desc = "A general purpose Chef's Knife made by SpaceCook Incorporated. Guaranteed to stay sharp for years to come."
|
||||
flags_1 = CONDUCT_1
|
||||
force = 10
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throwforce = 10
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
throw_speed = 3
|
||||
throw_range = 6
|
||||
materials = list(MAT_METAL=12000)
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
sharpness = IS_SHARP_ACCURATE
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50)
|
||||
var/bayonet = FALSE //Can this be attached to a gun?
|
||||
|
||||
/obj/item/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user)
|
||||
if(user.zone_selected == "eyes")
|
||||
if(user.disabilities & CLUMSY && prob(50))
|
||||
M = user
|
||||
return eyestab(M,user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/kitchen/knife/suicide_act(mob/user)
|
||||
user.visible_message(pick("<span class='suicide'>[user] is slitting [user.p_their()] wrists with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.</span>", \
|
||||
"<span class='suicide'>[user] is slitting [user.p_their()] throat with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.</span>", \
|
||||
"<span class='suicide'>[user] is slitting [user.p_their()] stomach open with the [src.name]! It looks like [user.p_theyre()] trying to commit seppuku.</span>"))
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/kitchen/knife/ritual
|
||||
name = "ritual knife"
|
||||
desc = "The unearthly energies that once powered this blade are now dormant."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "render"
|
||||
item_state = "knife"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/kitchen/knife/butcher
|
||||
name = "butcher's cleaver"
|
||||
icon_state = "butch"
|
||||
desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown by-products."
|
||||
flags_1 = CONDUCT_1
|
||||
force = 15
|
||||
throwforce = 10
|
||||
materials = list(MAT_METAL=18000)
|
||||
attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/kitchen/knife/combat
|
||||
name = "combat knife"
|
||||
icon_state = "buckknife"
|
||||
item_state = "knife"
|
||||
desc = "A military combat utility survival knife."
|
||||
force = 20
|
||||
throwforce = 20
|
||||
origin_tech = "materials=3;combat=4"
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
|
||||
bayonet = TRUE
|
||||
|
||||
/obj/item/kitchen/knife/combat/survival
|
||||
name = "survival knife"
|
||||
icon_state = "survivalknife"
|
||||
item_state = "knife"
|
||||
desc = "A hunting grade survival knife."
|
||||
force = 15
|
||||
throwforce = 15
|
||||
bayonet = TRUE
|
||||
|
||||
/obj/item/kitchen/knife/combat/bone
|
||||
name = "bone dagger"
|
||||
item_state = "bone_dagger"
|
||||
icon_state = "bone_dagger"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
desc = "A sharpened bone. The bare mimimum in survival."
|
||||
force = 15
|
||||
throwforce = 15
|
||||
materials = list()
|
||||
|
||||
/obj/item/kitchen/knife/combat/cyborg
|
||||
name = "cyborg knife"
|
||||
icon = 'icons/obj/items_cyborg.dmi'
|
||||
icon_state = "knife"
|
||||
desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable."
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/kitchen/knife/carrotshiv
|
||||
name = "carrot shiv"
|
||||
icon_state = "carrotshiv"
|
||||
item_state = "carrotshiv"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
desc = "Unlike other carrots, you should probably keep this far away from your eyes."
|
||||
force = 8
|
||||
throwforce = 12//fuck git
|
||||
materials = list()
|
||||
origin_tech = "biotech=3;combat=2"
|
||||
attack_verb = list("shanked", "shivved")
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
|
||||
|
||||
/obj/item/kitchen/rollingpin
|
||||
name = "rolling pin"
|
||||
desc = "Used to knock out the Bartender."
|
||||
icon_state = "rolling_pin"
|
||||
force = 8
|
||||
throwforce = 5
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked")
|
||||
|
||||
/* Trays moved to /obj/item/storage/bag */
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "arm_blade"
|
||||
item_state = "arm_blade"
|
||||
lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
|
||||
origin_tech = "combat=5;biotech=5"
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
force = 20
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
|
||||
/obj/item/pinpointer
|
||||
name = "pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinpointer"
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/active = FALSE
|
||||
var/atom/movable/target //The thing we're searching for
|
||||
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
|
||||
var/alert = FALSE // TRUE to display things more seriously
|
||||
|
||||
/obj/item/pinpointer/Initialize()
|
||||
. = ..()
|
||||
GLOB.pinpointer_list += src
|
||||
|
||||
/obj/item/pinpointer/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.pinpointer_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/pinpointer/attack_self(mob/living/user)
|
||||
active = !active
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
if(active)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
target = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/pinpointer/process()
|
||||
if(!active)
|
||||
return PROCESS_KILL
|
||||
scan_for_target()
|
||||
update_icon()
|
||||
|
||||
/obj/item/pinpointer/proc/scan_for_target()
|
||||
return
|
||||
|
||||
/obj/item/pinpointer/update_icon()
|
||||
cut_overlays()
|
||||
if(!active)
|
||||
return
|
||||
if(!target)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
var/turf/here = get_turf(src)
|
||||
var/turf/there = get_turf(target)
|
||||
if(here.z != there.z)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
return
|
||||
if(get_dist_euclidian(here,there) <= minimum_range)
|
||||
add_overlay("pinon[alert ? "alert" : ""]direct")
|
||||
else
|
||||
setDir(get_dir(here, there))
|
||||
switch(get_dist(here, there))
|
||||
if(1 to 8)
|
||||
add_overlay("pinon[alert ? "alert" : "close"]")
|
||||
if(9 to 16)
|
||||
add_overlay("pinon[alert ? "alert" : "medium"]")
|
||||
if(16 to INFINITY)
|
||||
add_overlay("pinon[alert ? "alert" : "far"]")
|
||||
|
||||
/obj/item/pinpointer/crew // A replacement for the old crew monitoring consoles
|
||||
name = "crew pinpointer"
|
||||
desc = "A handheld tracking device that points to crew suit sensors."
|
||||
icon_state = "pinpointer_crew"
|
||||
|
||||
/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
|
||||
var/turf/here = get_turf(src)
|
||||
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = H.w_uniform
|
||||
|
||||
// Suit sensors must be on maximum.
|
||||
if(!U.has_sensor || U.sensor_mode < SENSOR_COORDS)
|
||||
return FALSE
|
||||
|
||||
var/turf/there = get_turf(H)
|
||||
return (H.z != 0 || (there && there.z == H.z))
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/item/pinpointer/crew/attack_self(mob/living/user)
|
||||
if(active)
|
||||
active = FALSE
|
||||
user.visible_message("<span class='notice'>[user] deactivates their pinpointer.</span>", "<span class='notice'>You deactivate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
target = null //Restarting the pinpointer forces a target reset
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
var/list/name_counts = list()
|
||||
var/list/names = list()
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
if(!trackable(H))
|
||||
continue
|
||||
|
||||
var/crewmember_name = "Unknown"
|
||||
if(H.wear_id)
|
||||
var/obj/item/card/id/I = H.wear_id.GetID()
|
||||
crewmember_name = I.registered_name
|
||||
|
||||
while(crewmember_name in name_counts)
|
||||
name_counts[crewmember_name]++
|
||||
crewmember_name = text("[] ([])", crewmember_name, name_counts[crewmember_name])
|
||||
names[crewmember_name] = H
|
||||
name_counts[crewmember_name] = 1
|
||||
|
||||
if(!names.len)
|
||||
user.visible_message("<span class='notice'>[user]'s pinpointer fails to detect a signal.</span>", "<span class='notice'>Your pinpointer fails to detect a signal.</span>")
|
||||
return
|
||||
|
||||
var/A = input(user, "Person to track", "Pinpoint") in names
|
||||
if(!A || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated())
|
||||
return
|
||||
|
||||
target = names[A]
|
||||
active = TRUE
|
||||
user.visible_message("<span class='notice'>[user] activates their pinpointer.</span>", "<span class='notice'>You activate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/pinpointer/crew/scan_for_target()
|
||||
if(target)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!trackable(H))
|
||||
target = null
|
||||
if(!target) //target can be set to null from above code, or elsewhere
|
||||
active = FALSE
|
||||
|
||||
/obj/item/pinpointer/process()
|
||||
if(!active)
|
||||
return PROCESS_KILL
|
||||
scan_for_target()
|
||||
update_icon()
|
||||
|
||||
@@ -1,27 +1,201 @@
|
||||
/obj/item/banner
|
||||
name = "banner"
|
||||
desc = "A banner with Nanotrasen's logo on it."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "banner"
|
||||
item_state = "banner"
|
||||
force = 8
|
||||
attack_verb = list("forcefully inspired", "violently encouraged", "relentlessly galvanized")
|
||||
lefthand_file = 'icons/mob/inhands/equipment/banners_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/banners_righthand.dmi'
|
||||
desc = "A banner with Nanotrasen's logo on it."
|
||||
var/moralecooldown = 0
|
||||
var/moralewait = 600
|
||||
var/inspiration_available = TRUE //If this banner can be used to inspire crew
|
||||
var/morale_time = 0
|
||||
var/morale_cooldown = 600 //How many deciseconds between uses
|
||||
var/list/job_loyalties //Mobs with any of these assigned roles will be inspired
|
||||
var/list/role_loyalties //Mobs with any of these special roles will be inspired
|
||||
var/warcry
|
||||
|
||||
/obj/item/banner/examine(mob/user)
|
||||
..()
|
||||
if(inspiration_available)
|
||||
to_chat(user, "<span class='notice'>Activate it in your hand to inspire nearby allies of this banner's allegiance!</span>")
|
||||
|
||||
/obj/item/banner/attack_self(mob/living/carbon/human/user)
|
||||
if(moralecooldown + moralewait > world.time)
|
||||
if(!inspiration_available)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You increase the morale of your fellows!</span>")
|
||||
moralecooldown = world.time
|
||||
if(morale_time > world.time)
|
||||
to_chat(user, "<span class='warning'>You aren't feeling inspired enough to flourish [src] again yet.</span>")
|
||||
return
|
||||
user.visible_message("<span class='big notice'>[user] flourishes [src]!</span>", \
|
||||
"<span class='notice'>You raise [src] skywards, inspiring your allies!</span>")
|
||||
playsound(src, "rustle", 100, FALSE)
|
||||
if(warcry)
|
||||
user.say("[warcry]")
|
||||
var/old_transform = user.transform
|
||||
user.transform *= 1.2
|
||||
animate(user, transform = old_transform, time = 10)
|
||||
morale_time = world.time + morale_cooldown
|
||||
|
||||
for(var/mob/living/carbon/human/H in range(4,get_turf(src)))
|
||||
to_chat(H, "<span class='notice'>Your morale is increased by [user]'s banner!</span>")
|
||||
H.adjustBruteLoss(-15)
|
||||
H.adjustFireLoss(-15)
|
||||
H.AdjustStun(-40)
|
||||
H.AdjustKnockdown(-40)
|
||||
H.AdjustUnconscious(-40)
|
||||
var/list/inspired = list()
|
||||
var/has_job_loyalties = LAZYLEN(job_loyalties)
|
||||
var/has_role_loyalties = LAZYLEN(role_loyalties)
|
||||
inspired += user //The user is always inspired, regardless of loyalties
|
||||
for(var/mob/living/carbon/human/H in range(4, get_turf(src)))
|
||||
if(H.stat == DEAD || H == user)
|
||||
continue
|
||||
if(H.mind && (has_job_loyalties || has_role_loyalties))
|
||||
if(has_job_loyalties && H.mind.assigned_role in job_loyalties)
|
||||
inspired += H
|
||||
else if(has_role_loyalties && H.mind.special_role in role_loyalties)
|
||||
inspired += H
|
||||
else if(check_inspiration(H))
|
||||
inspired += H
|
||||
|
||||
for(var/V in inspired)
|
||||
var/mob/living/carbon/human/H = V
|
||||
if(H != user)
|
||||
to_chat(H, "<span class='notice'>Your confidence surges as [user] flourishes [user.p_their()] [name]!</span>")
|
||||
inspiration(H)
|
||||
special_inspiration(H)
|
||||
|
||||
/obj/item/banner/proc/check_inspiration(mob/living/carbon/human/H) //Banner-specific conditions for being eligible
|
||||
return
|
||||
|
||||
/obj/item/banner/proc/inspiration(mob/living/carbon/human/H)
|
||||
H.adjustBruteLoss(-15)
|
||||
H.adjustFireLoss(-15)
|
||||
H.AdjustStun(-40)
|
||||
H.AdjustKnockdown(-40)
|
||||
H.AdjustUnconscious(-40)
|
||||
playsound(H, 'sound/magic/staff_healing.ogg', 25, FALSE)
|
||||
|
||||
/obj/item/banner/proc/special_inspiration(mob/living/carbon/human/H) //Any banner-specific inspiration effects go here
|
||||
return
|
||||
|
||||
/obj/item/banner/security
|
||||
name = "securistan banner"
|
||||
desc = "The banner of Securistan, ruling the station with an iron fist."
|
||||
icon_state = "banner_security"
|
||||
job_loyalties = list("Security Officer", "Warden", "Detective", "Head of Security")
|
||||
warcry = "EVERYONE DOWN ON THE GROUND!!"
|
||||
|
||||
/obj/item/banner/security/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/datum/crafting_recipe/security_banner
|
||||
name = "Securistan Banner"
|
||||
result = /obj/item/banner/security/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/security = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/medical
|
||||
name = "meditopia banner"
|
||||
desc = "The banner of Meditopia, generous benefactors that cure wounds and shelter the weak."
|
||||
icon_state = "banner_medical"
|
||||
job_loyalties = list("Medical Doctor", "Chemist", "Geneticist", "Virologist", "Chief Medical Officer")
|
||||
warcry = "No wounds cannot be healed!"
|
||||
|
||||
/obj/item/banner/medical/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/medical/check_inspiration(mob/living/carbon/human/H)
|
||||
return H.stat //Meditopia is moved to help those in need
|
||||
|
||||
/datum/crafting_recipe/medical_banner
|
||||
name = "Meditopia Banner"
|
||||
result = /obj/item/banner/medical/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/medical = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H)
|
||||
H.adjustToxLoss(-15)
|
||||
H.setOxyLoss(0)
|
||||
H.reagents.add_reagent("inaprovaline", 5)
|
||||
|
||||
/obj/item/banner/science
|
||||
name = "sciencia banner"
|
||||
desc = "The banner of Sciencia, bold and daring thaumaturges and researchers that take the path less traveled."
|
||||
icon_state = "banner_science"
|
||||
job_loyalties = list("Scientist", "Roboticist", "Research Director")
|
||||
warcry = "For Cuban Pete!"
|
||||
|
||||
/obj/item/banner/science/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/science/check_inspiration(mob/living/carbon/human/H)
|
||||
return H.on_fire //Sciencia is pleased by dedication to the art of Toxins
|
||||
|
||||
/datum/crafting_recipe/science_banner
|
||||
name = "Sciencia Banner"
|
||||
result = /obj/item/banner/science/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/scientist = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/cargo
|
||||
name = "cargonia banner"
|
||||
desc = "The banner of the eternal Cargonia, with the mystical power of conjuring any object into existence."
|
||||
icon_state = "banner_cargo"
|
||||
job_loyalties = list("Cargo Technician", "Shaft Miner", "Quartermaster")
|
||||
warcry = "Hail Cargonia!"
|
||||
|
||||
/obj/item/banner/cargo/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/datum/crafting_recipe/cargo_banner
|
||||
name = "Cargonia Banner"
|
||||
result = /obj/item/banner/cargo/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/cargotech = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/engineering
|
||||
name = "engitopia banner"
|
||||
desc = "The banner of Engitopia, wielders of limitless power."
|
||||
icon_state = "banner_engineering"
|
||||
job_loyalties = list("Station Engineer", "Atmospheric Technician", "Chief Engineer")
|
||||
warcry = "All hail lord Singuloth!!"
|
||||
|
||||
/obj/item/banner/engineering/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/engineering/special_inspiration(mob/living/carbon/human/H)
|
||||
H.radiation = 0
|
||||
|
||||
/datum/crafting_recipe/engineering_banner
|
||||
name = "Engitopia Banner"
|
||||
result = /obj/item/banner/engineering/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/engineer = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/command
|
||||
name = "command banner"
|
||||
desc = "The banner of Command, a staunch and ancient line of bueraucratic kings and queens."
|
||||
//No icon state here since the default one is the NT banner
|
||||
job_loyalties = list("Captain", "Head of Personnel", "Chief Engineer", "Head of Security", "Research Director", "Chief Medical Officer")
|
||||
warcry = "Hail Nanotrasen!"
|
||||
|
||||
/obj/item/banner/command/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/command/check_inspiration(mob/living/carbon/human/H)
|
||||
return H.isloyal() //Command is stalwart but rewards their allies.
|
||||
|
||||
/datum/crafting_recipe/command_banner
|
||||
name = "Command Banner"
|
||||
result = /obj/item/banner/command/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/captainparade = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/red
|
||||
name = "red banner"
|
||||
|
||||
@@ -278,7 +278,6 @@
|
||||
desc = "Releases a harmless blast that confuses most organics. For when the harm is JUST TOO MUCH"
|
||||
icon_state = "megaphone"
|
||||
var/cooldown = 0
|
||||
var/emagged = FALSE
|
||||
|
||||
/obj/item/device/harmalarm/emag_act(mob/user)
|
||||
emagged = !emagged
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
/obj/item/stack/medical/attack(mob/living/M, mob/user)
|
||||
|
||||
if(M.stat == 2)
|
||||
if(M.stat == DEAD)
|
||||
var/t_him = "it"
|
||||
if(M.gender == MALE)
|
||||
t_him = "him"
|
||||
|
||||
@@ -23,7 +23,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
|
||||
novariants = TRUE
|
||||
|
||||
/obj/item/stack/rods/Initialize(mapload, new_amount, merge = TRUE)
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
recipes = GLOB.rod_recipes
|
||||
update_icon()
|
||||
|
||||
@@ -32,6 +32,13 @@ GLOBAL_LIST_INIT(human_recipes, list( \
|
||||
singular_name = "corgi hide piece"
|
||||
icon_state = "sheet-corgi"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/gondola
|
||||
name = "gondola hide"
|
||||
desc = "The extremely valuable by-product of gondola hunting."
|
||||
singular_name = "gondola hide piece"
|
||||
icon_state = "sheet-gondola"
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(corgi_recipes, list ( \
|
||||
new/datum/stack_recipe("corgi costume", /obj/item/clothing/suit/hooded/ian_costume, 3), \
|
||||
))
|
||||
|
||||
@@ -21,6 +21,10 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
|
||||
new/datum/stack_recipe("swivel chair", /obj/structure/chair/office/dark, 5, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("comfy chair", /obj/structure/chair/comfy/beige, 2, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new /datum/stack_recipe("sofa (left)", /obj/structure/chair/sofa/left, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new /datum/stack_recipe("sofa (right)", /obj/structure/chair/sofa/right, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new /datum/stack_recipe("sofa (corner)", /obj/structure/chair/sofa/corner, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
null, \
|
||||
new/datum/stack_recipe("rack parts", /obj/item/rack_parts), \
|
||||
new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
@@ -421,4 +425,4 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
|
||||
/obj/item/stack/sheet/paperframes/twenty
|
||||
amount = 20
|
||||
/obj/item/stack/sheet/paperframes/fifty
|
||||
amount = 50
|
||||
amount = 50
|
||||
|
||||
@@ -62,20 +62,20 @@
|
||||
/obj/item/stack/examine(mob/user)
|
||||
..()
|
||||
if (is_cyborg)
|
||||
if(src.singular_name)
|
||||
to_chat(user, "There is enough energy for [src.get_amount()] [src.singular_name]\s.")
|
||||
if(singular_name)
|
||||
to_chat(user, "There is enough energy for [get_amount()] [singular_name]\s.")
|
||||
else
|
||||
to_chat(user, "There is enough energy for [src.get_amount()].")
|
||||
to_chat(user, "There is enough energy for [get_amount()].")
|
||||
return
|
||||
if(src.singular_name)
|
||||
if(src.get_amount()>1)
|
||||
to_chat(user, "There are [src.get_amount()] [src.singular_name]\s in the stack.")
|
||||
if(singular_name)
|
||||
if(get_amount()>1)
|
||||
to_chat(user, "There are [get_amount()] [singular_name]\s in the stack.")
|
||||
else
|
||||
to_chat(user, "There is [src.get_amount()] [src.singular_name] in the stack.")
|
||||
else if(src.get_amount()>1)
|
||||
to_chat(user, "There are [src.get_amount()] in the stack.")
|
||||
to_chat(user, "There is [get_amount()] [singular_name] in the stack.")
|
||||
else if(get_amount()>1)
|
||||
to_chat(user, "There are [get_amount()] in the stack.")
|
||||
else
|
||||
to_chat(user, "There is [src.get_amount()] in the stack.")
|
||||
to_chat(user, "There is [get_amount()] in the stack.")
|
||||
|
||||
/obj/item/stack/proc/get_amount()
|
||||
if(is_cyborg)
|
||||
@@ -93,7 +93,7 @@
|
||||
user << browse(null, "window=stack")
|
||||
return
|
||||
user.set_machine(src) //for correct work of onclose
|
||||
var/t1 = text("<HTML><HEAD><title>Constructions from []</title></HEAD><body><TT>Amount Left: []<br>", src, src.get_amount())
|
||||
var/t1 = text("<HTML><HEAD><title>Constructions from []</title></HEAD><body><TT>Amount Left: []<br>", src, get_amount())
|
||||
for(var/i=1;i<=recipes.len,i++)
|
||||
var/datum/stack_recipe/R = recipes[i]
|
||||
if (isnull(R))
|
||||
@@ -101,7 +101,7 @@
|
||||
continue
|
||||
if (i>1 && !isnull(recipes[i-1]))
|
||||
t1+="<br>"
|
||||
var/max_multiplier = round(src.get_amount() / R.req_amount)
|
||||
var/max_multiplier = round(get_amount() / R.req_amount)
|
||||
var/title as text
|
||||
var/can_build = 1
|
||||
can_build = can_build && (max_multiplier>0)
|
||||
@@ -109,7 +109,7 @@
|
||||
title+= "[R.res_amount]x [R.title]\s"
|
||||
else
|
||||
title+= "[R.title]"
|
||||
title+= " ([R.req_amount] [src.singular_name]\s)"
|
||||
title+= " ([R.req_amount] [singular_name]\s)"
|
||||
if (can_build)
|
||||
t1 += text("<A href='?src=\ref[];make=[];multiplier=1'>[]</A> ", src, i, title)
|
||||
else
|
||||
@@ -134,7 +134,7 @@
|
||||
if (usr.restrained() || usr.stat || usr.get_active_held_item() != src)
|
||||
return
|
||||
if (href_list["make"])
|
||||
if (src.get_amount() < 1) qdel(src) //Never should happen
|
||||
if (get_amount() < 1) qdel(src) //Never should happen
|
||||
|
||||
var/datum/stack_recipe/R = recipes[text2num(href_list["make"])]
|
||||
var/multiplier = text2num(href_list["multiplier"])
|
||||
@@ -185,7 +185,7 @@
|
||||
addtimer(CALLBACK(src, /atom/.proc/interact, usr), 0)
|
||||
|
||||
/obj/item/stack/proc/building_checks(datum/stack_recipe/R, multiplier)
|
||||
if (src.get_amount() < R.req_amount*multiplier)
|
||||
if (get_amount() < R.req_amount*multiplier)
|
||||
if (R.req_amount*multiplier>1)
|
||||
to_chat(usr, "<span class='warning'>You haven't got enough [src] to build \the [R.req_amount*multiplier] [R.title]\s!</span>")
|
||||
else
|
||||
@@ -276,9 +276,9 @@
|
||||
return
|
||||
//get amount from user
|
||||
var/min = 0
|
||||
var/max = src.get_amount()
|
||||
var/max = get_amount()
|
||||
var/stackmaterial = round(input(user,"How many sheets do you wish to take out of this stack? (Maximum [max])") as num)
|
||||
if(stackmaterial == null || stackmaterial <= min || stackmaterial >= src.get_amount())
|
||||
if(stackmaterial == null || stackmaterial <= min || stackmaterial >= get_amount() || !user.canUseTopic(src))
|
||||
return
|
||||
else
|
||||
change_stack(user,stackmaterial)
|
||||
@@ -304,10 +304,10 @@
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/proc/copy_evidences(obj/item/stack/from as obj)
|
||||
src.blood_DNA = from.blood_DNA
|
||||
src.fingerprints = from.fingerprints
|
||||
src.fingerprintshidden = from.fingerprintshidden
|
||||
src.fingerprintslast = from.fingerprintslast
|
||||
blood_DNA = from.blood_DNA
|
||||
fingerprints = from.fingerprints
|
||||
fingerprintshidden = from.fingerprintshidden
|
||||
fingerprintslast = from.fingerprintslast
|
||||
//TODO bloody overlay
|
||||
|
||||
/obj/item/stack/microwave_act(obj/machinery/microwave/M)
|
||||
|
||||
@@ -1,215 +1,217 @@
|
||||
/* First aid storage
|
||||
* Contains:
|
||||
* First Aid Kits
|
||||
* Pill Bottles
|
||||
* Dice Pack (in a pill bottle)
|
||||
*/
|
||||
|
||||
/*
|
||||
* First Aid Kits
|
||||
*/
|
||||
/obj/item/storage/firstaid
|
||||
name = "first-aid kit"
|
||||
desc = "It's an emergency medical kit for those serious boo-boos."
|
||||
icon_state = "firstaid"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
var/empty = 0
|
||||
|
||||
/obj/item/storage/firstaid/regular
|
||||
icon_state = "firstaid"
|
||||
desc = "A first aid kit with the ability to heal common types of injuries."
|
||||
|
||||
/obj/item/storage/firstaid/regular/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
new /obj/item/device/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/ancient
|
||||
icon_state = "firstaid"
|
||||
desc = "A first aid kit with the ability to heal common types of injuries."
|
||||
|
||||
|
||||
/obj/item/storage/firstaid/ancient/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
|
||||
/obj/item/storage/firstaid/fire
|
||||
name = "burn treatment kit"
|
||||
desc = "A specialized medical kit for when the toxins lab <i>-spontaneously-</i> burns down."
|
||||
icon_state = "ointment"
|
||||
item_state = "firstaid-ointment"
|
||||
|
||||
/obj/item/storage/firstaid/fire/Initialize(mapload)
|
||||
..()
|
||||
icon_state = pick("ointment","firefirstaid")
|
||||
|
||||
/obj/item/storage/firstaid/fire/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
|
||||
new /obj/item/reagent_containers/pill/oxandrolone(src)
|
||||
new /obj/item/reagent_containers/pill/oxandrolone(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
new /obj/item/device/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/toxin
|
||||
name = "toxin treatment kit"
|
||||
desc = "Used to treat toxic blood content and radiation poisoning."
|
||||
icon_state = "antitoxin"
|
||||
item_state = "firstaid-toxin"
|
||||
|
||||
/obj/item/storage/firstaid/toxin/Initialize(mapload)
|
||||
. = ..()
|
||||
icon_state = pick("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3")
|
||||
|
||||
/obj/item/storage/firstaid/toxin/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
for(var/i in 1 to 4)
|
||||
new /obj/item/reagent_containers/syringe/charcoal(src)
|
||||
for(var/i in 1 to 2)
|
||||
new /obj/item/storage/pill_bottle/charcoal(src)
|
||||
new /obj/item/device/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/o2
|
||||
name = "oxygen deprivation treatment kit"
|
||||
desc = "A box full of oxygen goodies."
|
||||
icon_state = "o2"
|
||||
item_state = "firstaid-o2"
|
||||
|
||||
/obj/item/storage/firstaid/o2/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
for(var/i in 1 to 4)
|
||||
new /obj/item/reagent_containers/pill/salbutamol(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
new /obj/item/device/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/brute
|
||||
name = "brute trauma treatment kit"
|
||||
desc = "A first aid kit for when you get toolboxed."
|
||||
icon_state = "brute"
|
||||
item_state = "firstaid-brute"
|
||||
|
||||
/obj/item/storage/firstaid/brute/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
for(var/i in 1 to 4)
|
||||
new /obj/item/reagent_containers/pill/patch/styptic(src)
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/device/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/tactical
|
||||
name = "combat medical kit"
|
||||
desc = "I hope you've got insurance."
|
||||
icon_state = "bezerk"
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/storage/firstaid/tactical/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/defibrillator/compact/combat/loaded(src)
|
||||
new /obj/item/reagent_containers/hypospray/combat(src)
|
||||
new /obj/item/reagent_containers/pill/patch/styptic(src)
|
||||
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
|
||||
new /obj/item/reagent_containers/syringe/lethal/choral(src)
|
||||
new /obj/item/clothing/glasses/hud/health/night(src)
|
||||
|
||||
|
||||
/*
|
||||
* Pill Bottles
|
||||
*/
|
||||
/obj/item/storage/pill_bottle
|
||||
name = "pill bottle"
|
||||
desc = "It's an airtight container for storing medication."
|
||||
icon_state = "pill_canister"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
item_state = "contsolid"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
can_hold = list(/obj/item/reagent_containers/pill, /obj/item/dice)
|
||||
allow_quick_gather = 1
|
||||
use_to_pickup = 1
|
||||
|
||||
/obj/item/storage/pill_bottle/MouseDrop(obj/over_object) //Quick pillbottle fix. -Agouri
|
||||
|
||||
if(ishuman(usr) || ismonkey(usr)) //Can monkeys even place items in the pocket slots? Leaving this in just in case~
|
||||
var/mob/M = usr
|
||||
if(!istype(over_object, /obj/screen) || !Adjacent(M))
|
||||
return ..()
|
||||
if(!M.incapacitated() && istype(over_object, /obj/screen/inventory/hand))
|
||||
var/obj/screen/inventory/hand/H = over_object
|
||||
if(M.putItemFromInventoryInHandIfPossible(src, H.held_index))
|
||||
add_fingerprint(usr)
|
||||
if(over_object == usr && in_range(src, usr) || usr.contents.Find(src))
|
||||
if(usr.s_active)
|
||||
usr.s_active.close(usr)
|
||||
src.show_to(usr)
|
||||
|
||||
/obj/item/storage/pill_bottle/charcoal
|
||||
name = "bottle of charcoal pills"
|
||||
desc = "Contains pills used to counter toxins."
|
||||
|
||||
/obj/item/storage/pill_bottle/charcoal/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/charcoal(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/epinephrine
|
||||
name = "bottle of epinephrine pills"
|
||||
desc = "Contains pills used to stabilize patients."
|
||||
|
||||
/obj/item/storage/pill_bottle/epinephrine/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/epinephrine(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/mutadone
|
||||
name = "bottle of mutadone pills"
|
||||
desc = "Contains pills used to treat genetic abnormalities."
|
||||
|
||||
/obj/item/storage/pill_bottle/mutadone/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/mutadone(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/mannitol
|
||||
name = "bottle of mannitol pills"
|
||||
desc = "Contains pills used to treat brain damage."
|
||||
|
||||
/obj/item/storage/pill_bottle/mannitol/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/mannitol(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/stimulant
|
||||
name = "bottle of stimulant pills"
|
||||
desc = "Guaranteed to give you that extra burst of energy during a long shift!"
|
||||
|
||||
/obj/item/storage/pill_bottle/stimulant/PopulateContents()
|
||||
for(var/i in 1 to 5)
|
||||
new /obj/item/reagent_containers/pill/stimulant(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/mining
|
||||
name = "bottle of patches"
|
||||
desc = "Contains patches used to treat brute and burn damage."
|
||||
|
||||
/obj/item/storage/pill_bottle/mining/PopulateContents()
|
||||
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/reagent_containers/pill/patch/styptic(src)
|
||||
/* First aid storage
|
||||
* Contains:
|
||||
* First Aid Kits
|
||||
* Pill Bottles
|
||||
* Dice Pack (in a pill bottle)
|
||||
*/
|
||||
|
||||
/*
|
||||
* First Aid Kits
|
||||
*/
|
||||
/obj/item/storage/firstaid
|
||||
name = "first-aid kit"
|
||||
desc = "It's an emergency medical kit for those serious boo-boos."
|
||||
icon_state = "firstaid"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
var/empty = 0
|
||||
|
||||
/obj/item/storage/firstaid/regular
|
||||
icon_state = "firstaid"
|
||||
desc = "A first aid kit with the ability to heal common types of injuries."
|
||||
|
||||
/obj/item/storage/firstaid/regular/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
new /obj/item/device/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/ancient
|
||||
icon_state = "firstaid"
|
||||
desc = "A first aid kit with the ability to heal common types of injuries."
|
||||
|
||||
|
||||
/obj/item/storage/firstaid/ancient/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/bruise_pack(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
new /obj/item/stack/medical/ointment(src)
|
||||
|
||||
/obj/item/storage/firstaid/fire
|
||||
name = "burn treatment kit"
|
||||
desc = "A specialized medical kit for when the toxins lab <i>-spontaneously-</i> burns down."
|
||||
icon_state = "ointment"
|
||||
item_state = "firstaid-ointment"
|
||||
|
||||
/obj/item/storage/firstaid/fire/Initialize(mapload)
|
||||
..()
|
||||
icon_state = pick("ointment","firefirstaid")
|
||||
|
||||
/obj/item/storage/firstaid/fire/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
|
||||
new /obj/item/reagent_containers/pill/oxandrolone(src)
|
||||
new /obj/item/reagent_containers/pill/oxandrolone(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
new /obj/item/device/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/toxin
|
||||
name = "toxin treatment kit"
|
||||
desc = "Used to treat toxic blood content and radiation poisoning."
|
||||
icon_state = "antitoxin"
|
||||
item_state = "firstaid-toxin"
|
||||
|
||||
/obj/item/storage/firstaid/toxin/Initialize(mapload)
|
||||
. = ..()
|
||||
icon_state = pick("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3")
|
||||
|
||||
/obj/item/storage/firstaid/toxin/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
for(var/i in 1 to 4)
|
||||
new /obj/item/reagent_containers/syringe/charcoal(src)
|
||||
for(var/i in 1 to 2)
|
||||
new /obj/item/storage/pill_bottle/charcoal(src)
|
||||
new /obj/item/device/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/o2
|
||||
name = "oxygen deprivation treatment kit"
|
||||
desc = "A box full of oxygen goodies."
|
||||
icon_state = "o2"
|
||||
item_state = "firstaid-o2"
|
||||
|
||||
/obj/item/storage/firstaid/o2/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
for(var/i in 1 to 4)
|
||||
new /obj/item/reagent_containers/pill/salbutamol(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
new /obj/item/device/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/brute
|
||||
name = "brute trauma treatment kit"
|
||||
desc = "A first aid kit for when you get toolboxed."
|
||||
icon_state = "brute"
|
||||
item_state = "firstaid-brute"
|
||||
|
||||
/obj/item/storage/firstaid/brute/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
for(var/i in 1 to 4)
|
||||
new /obj/item/reagent_containers/pill/patch/styptic(src)
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/device/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/tactical
|
||||
name = "combat medical kit"
|
||||
desc = "I hope you've got insurance."
|
||||
icon_state = "bezerk"
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/storage/firstaid/tactical/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
new /obj/item/stack/medical/gauze(src)
|
||||
new /obj/item/defibrillator/compact/combat/loaded(src)
|
||||
new /obj/item/reagent_containers/hypospray/combat(src)
|
||||
new /obj/item/reagent_containers/pill/patch/styptic(src)
|
||||
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
|
||||
new /obj/item/reagent_containers/syringe/lethal/choral(src)
|
||||
new /obj/item/clothing/glasses/hud/health/night(src)
|
||||
|
||||
|
||||
/*
|
||||
* Pill Bottles
|
||||
*/
|
||||
/obj/item/storage/pill_bottle
|
||||
name = "pill bottle"
|
||||
desc = "It's an airtight container for storing medication."
|
||||
icon_state = "pill_canister"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
item_state = "contsolid"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
can_hold = list(/obj/item/reagent_containers/pill, /obj/item/dice)
|
||||
allow_quick_gather = 1
|
||||
use_to_pickup = 1
|
||||
|
||||
/obj/item/storage/pill_bottle/MouseDrop(obj/over_object) //Quick pillbottle fix. -Agouri
|
||||
|
||||
if(ishuman(usr) || ismonkey(usr)) //Can monkeys even place items in the pocket slots? Leaving this in just in case~
|
||||
var/mob/M = usr
|
||||
if(!istype(over_object, /obj/screen) || !Adjacent(M))
|
||||
return ..()
|
||||
if(!M.incapacitated() && istype(over_object, /obj/screen/inventory/hand))
|
||||
var/obj/screen/inventory/hand/H = over_object
|
||||
if(M.putItemFromInventoryInHandIfPossible(src, H.held_index))
|
||||
add_fingerprint(usr)
|
||||
if(over_object == usr && in_range(src, usr) || usr.contents.Find(src))
|
||||
if(usr.s_active)
|
||||
usr.s_active.close(usr)
|
||||
src.show_to(usr)
|
||||
|
||||
/obj/item/storage/pill_bottle/charcoal
|
||||
name = "bottle of charcoal pills"
|
||||
desc = "Contains pills used to counter toxins."
|
||||
|
||||
/obj/item/storage/pill_bottle/charcoal/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/charcoal(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/epinephrine
|
||||
name = "bottle of epinephrine pills"
|
||||
desc = "Contains pills used to stabilize patients."
|
||||
|
||||
/obj/item/storage/pill_bottle/epinephrine/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/epinephrine(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/mutadone
|
||||
name = "bottle of mutadone pills"
|
||||
desc = "Contains pills used to treat genetic abnormalities."
|
||||
|
||||
/obj/item/storage/pill_bottle/mutadone/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/mutadone(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/mannitol
|
||||
name = "bottle of mannitol pills"
|
||||
desc = "Contains pills used to treat brain damage."
|
||||
|
||||
/obj/item/storage/pill_bottle/mannitol/PopulateContents()
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/mannitol(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/stimulant
|
||||
name = "bottle of stimulant pills"
|
||||
desc = "Guaranteed to give you that extra burst of energy during a long shift!"
|
||||
|
||||
/obj/item/storage/pill_bottle/stimulant/PopulateContents()
|
||||
for(var/i in 1 to 5)
|
||||
new /obj/item/reagent_containers/pill/stimulant(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/mining
|
||||
name = "bottle of patches"
|
||||
desc = "Contains patches used to treat brute and burn damage."
|
||||
|
||||
/obj/item/storage/pill_bottle/mining/PopulateContents()
|
||||
new /obj/item/reagent_containers/pill/patch/silver_sulf(src)
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/reagent_containers/pill/patch/styptic(src)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
if(quickdraw)
|
||||
to_chat(user, "<span class='notice'>You discreetly slip [W] into [src]. Alt-click [src] to remove it.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You discreetly slip [W] into [src].")
|
||||
to_chat(user, "<span class='notice'>You discreetly slip [W] into [src].</span>")
|
||||
|
||||
/obj/item/storage/internal/pocket/big
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
@@ -89,7 +89,7 @@ Frequency:
|
||||
continue
|
||||
else
|
||||
var/mob/M = W.loc
|
||||
if (M.stat == 2)
|
||||
if (M.stat == DEAD)
|
||||
if (M.timeofdeath + 6000 < world.time)
|
||||
continue
|
||||
|
||||
|
||||
+790
-790
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,7 @@
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "waterballoon-e"
|
||||
item_state = "balloon-empty"
|
||||
|
||||
|
||||
/obj/item/toy/balloon/New()
|
||||
create_reagents(10)
|
||||
@@ -278,6 +279,8 @@
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "foamblade"
|
||||
item_state = "arm_blade"
|
||||
lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
|
||||
attack_verb = list("pricked", "absorbed", "gored")
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
resistance_flags = FLAMMABLE
|
||||
@@ -288,6 +291,8 @@
|
||||
desc = "A replica toolbox that rumbles when you turn the key"
|
||||
icon_state = "his_grace"
|
||||
item_state = "artistic_toolbox"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi'
|
||||
var/active = FALSE
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
attack_verb = list("robusted")
|
||||
@@ -547,6 +552,8 @@
|
||||
desc = "A tool to help you write fictional devils!"
|
||||
icon = 'icons/obj/library.dmi'
|
||||
icon_state = "demonomicon"
|
||||
lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
recharge_time = 60
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@
|
||||
righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 13
|
||||
var/force_on = 21
|
||||
var/force_on = 24
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
throwforce = 13
|
||||
throw_speed = 2
|
||||
@@ -500,6 +500,18 @@
|
||||
actions_types = list(/datum/action/item_action/startchainsaw)
|
||||
var/on = FALSE
|
||||
|
||||
/obj/item/twohanded/required/chainsaw/suicide_act(mob/living/carbon/user)
|
||||
if(on)
|
||||
user.visible_message("<span class='suicide'>[user] begins to tear [user.p_their()] head off with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(src, 'sound/weapons/chainsawhit.ogg', 100, 1)
|
||||
var/obj/item/bodypart/head/myhead = user.get_bodypart("head")
|
||||
if(myhead)
|
||||
myhead.dismember()
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] smashes [src] into [user.p_their()] neck, destroying [user.p_their()] esophagus! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(src, 'sound/weapons/genhit1.ogg', 100, 1)
|
||||
return(BRUTELOSS)
|
||||
|
||||
/obj/item/twohanded/required/chainsaw/attack_self(mob/user)
|
||||
on = !on
|
||||
to_chat(user, "As you pull the starting cord dangling from [src], [on ? "it begins to whirr." : "the chain stops moving."]")
|
||||
|
||||
@@ -1,81 +1,87 @@
|
||||
/obj/item/vending_refill
|
||||
name = "resupply canister"
|
||||
var/machine_name = "Generic"
|
||||
|
||||
icon = 'icons/obj/vending_restock.dmi'
|
||||
icon_state = "refill_snack"
|
||||
item_state = "restock_unit"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 7
|
||||
throwforce = 10
|
||||
throw_speed = 1
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 70, acid = 30)
|
||||
var/charges = list(0, 0, 0) //how many restocking "charges" the refill has for standard/contraband/coin products
|
||||
var/init_charges = list(0, 0, 0)
|
||||
|
||||
|
||||
/obj/item/vending_refill/New(amt = -1)
|
||||
..()
|
||||
name = "\improper [machine_name] restocking unit"
|
||||
if(isnum(amt) && amt > -1)
|
||||
charges[1] = amt
|
||||
|
||||
/obj/item/vending_refill/examine(mob/user)
|
||||
..()
|
||||
if(charges[1] > 0)
|
||||
to_chat(user, "It can restock [charges[1]+charges[2]+charges[3]] item(s).")
|
||||
else
|
||||
to_chat(user, "It's empty!")
|
||||
|
||||
//NOTE I decided to go for about 1/3 of a machine's capacity
|
||||
|
||||
/obj/item/vending_refill/boozeomat
|
||||
machine_name = "Booze-O-Mat"
|
||||
icon_state = "refill_booze"
|
||||
charges = list(54, 4, 0)//of 159 standard, 12 contraband
|
||||
init_charges = list(54, 4, 0)
|
||||
|
||||
/obj/item/vending_refill/coffee
|
||||
machine_name = "Solar's Best Hot Drinks"
|
||||
icon_state = "refill_joe"
|
||||
charges = list(25, 4, 0)//of 75 standard, 12 contraband
|
||||
init_charges = list(25, 4, 0)
|
||||
|
||||
/obj/item/vending_refill/snack
|
||||
machine_name = "Getmore Chocolate Corp"
|
||||
charges = list(12, 2, 0)//of 36 standard, 6 contraband
|
||||
init_charges = list(12, 2, 0)
|
||||
|
||||
/obj/item/vending_refill/cola
|
||||
machine_name = "Robust Softdrinks"
|
||||
icon_state = "refill_cola"
|
||||
charges = list(30, 4, 1)//of 90 standard, 12 contraband, 1 premium
|
||||
init_charges = list(30, 4, 1)
|
||||
|
||||
/obj/item/vending_refill/cigarette
|
||||
machine_name = "ShadyCigs Deluxe"
|
||||
icon_state = "refill_smoke"
|
||||
charges = list(12, 3, 2)// of 36 standard, 9 contraband, 6 premium
|
||||
init_charges = list(12, 3, 2)
|
||||
|
||||
/obj/item/vending_refill/autodrobe
|
||||
machine_name = "AutoDrobe"
|
||||
icon_state = "refill_costume"
|
||||
charges = list(32, 2, 3)// of 96 standard, 6 contraband, 9 premium
|
||||
init_charges = list(32, 2, 3)
|
||||
|
||||
/obj/item/vending_refill/clothing
|
||||
machine_name = "ClothesMate"
|
||||
icon_state = "refill_clothes"
|
||||
charges = list(37, 4, 4)// of 111 standard, 12 contraband, 10 premium(?)
|
||||
init_charges = list(37, 4, 4)
|
||||
|
||||
/obj/item/vending_refill/medical
|
||||
machine_name = "NanoMed"
|
||||
icon_state = "refill_medical"
|
||||
charges = list(26, 5, 3)// of 76 standard, 13 contraband, 8 premium
|
||||
init_charges = list(26, 5, 3)
|
||||
/obj/item/vending_refill
|
||||
name = "resupply canister"
|
||||
var/machine_name = "Generic"
|
||||
|
||||
icon = 'icons/obj/vending_restock.dmi'
|
||||
icon_state = "refill_snack"
|
||||
item_state = "restock_unit"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 7
|
||||
throwforce = 10
|
||||
throw_speed = 1
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 70, acid = 30)
|
||||
var/charges = list(0, 0, 0) //how many restocking "charges" the refill has for standard/contraband/coin products
|
||||
var/init_charges = list(0, 0, 0)
|
||||
|
||||
|
||||
/obj/item/vending_refill/New(amt = -1)
|
||||
..()
|
||||
name = "\improper [machine_name] restocking unit"
|
||||
if(isnum(amt) && amt > -1)
|
||||
charges[1] = amt
|
||||
|
||||
/obj/item/vending_refill/examine(mob/user)
|
||||
..()
|
||||
if(charges[1] > 0)
|
||||
to_chat(user, "It can restock [charges[1]+charges[2]+charges[3]] item(s).")
|
||||
else
|
||||
to_chat(user, "It's empty!")
|
||||
|
||||
//NOTE I decided to go for about 1/3 of a machine's capacity
|
||||
|
||||
/obj/item/vending_refill/boozeomat
|
||||
machine_name = "Booze-O-Mat"
|
||||
icon_state = "refill_booze"
|
||||
charges = list(54, 4, 0)//of 159 standard, 12 contraband
|
||||
init_charges = list(54, 4, 0)
|
||||
|
||||
/obj/item/vending_refill/coffee
|
||||
machine_name = "Solar's Best Hot Drinks"
|
||||
icon_state = "refill_joe"
|
||||
charges = list(25, 4, 0)//of 75 standard, 12 contraband
|
||||
init_charges = list(25, 4, 0)
|
||||
|
||||
/obj/item/vending_refill/snack
|
||||
machine_name = "Getmore Chocolate Corp"
|
||||
charges = list(12, 2, 0)//of 36 standard, 6 contraband
|
||||
init_charges = list(12, 2, 0)
|
||||
|
||||
/obj/item/vending_refill/cola
|
||||
machine_name = "Robust Softdrinks"
|
||||
icon_state = "refill_cola"
|
||||
charges = list(30, 4, 1)//of 90 standard, 12 contraband, 1 premium
|
||||
init_charges = list(30, 4, 1)
|
||||
|
||||
/obj/item/vending_refill/cigarette
|
||||
machine_name = "ShadyCigs Deluxe"
|
||||
icon_state = "refill_smoke"
|
||||
charges = list(12, 3, 2)// of 36 standard, 9 contraband, 6 premium
|
||||
init_charges = list(12, 3, 2)
|
||||
|
||||
/obj/item/vending_refill/autodrobe
|
||||
machine_name = "AutoDrobe"
|
||||
icon_state = "refill_costume"
|
||||
charges = list(32, 2, 3)// of 96 standard, 6 contraband, 9 premium
|
||||
init_charges = list(32, 2, 3)
|
||||
|
||||
/obj/item/vending_refill/clothing
|
||||
machine_name = "ClothesMate"
|
||||
icon_state = "refill_clothes"
|
||||
charges = list(37, 4, 4)// of 111 standard, 12 contraband, 10 premium(?)
|
||||
init_charges = list(37, 4, 4)
|
||||
|
||||
/obj/item/vending_refill/medical
|
||||
machine_name = "NanoMed"
|
||||
icon_state = "refill_medical"
|
||||
charges = list(26, 5, 3)// of 76 standard, 13 contraband, 8 premium
|
||||
init_charges = list(26, 5, 3)
|
||||
|
||||
/obj/item/vending_refill/donksoft
|
||||
machine_name = "Donksoft Toy Vendor"
|
||||
icon_state = "refill_donksoft"
|
||||
charges = list(32,28,0)// of 90 standard, 75 contraband, 0 premium
|
||||
init_charges = list(32,28,0)
|
||||
|
||||
+586
-586
File diff suppressed because it is too large
Load Diff
@@ -169,6 +169,7 @@
|
||||
return
|
||||
|
||||
/obj/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(!anchored || current_size >= STAGE_FIVE)
|
||||
step_towards(src,S)
|
||||
|
||||
@@ -198,7 +199,7 @@
|
||||
|
||||
/obj/vv_get_dropdown()
|
||||
. = ..()
|
||||
.["Delete all of type"] = "?_src_=vars;delall=\ref[src]"
|
||||
.["Delete all of type"] = "?_src_=vars;[HrefToken()];delall=\ref[src]"
|
||||
|
||||
/obj/examine(mob/user)
|
||||
..()
|
||||
@@ -225,6 +226,3 @@
|
||||
current_skin = choice
|
||||
icon_state = unique_reskin[choice]
|
||||
to_chat(M, "[src] is now skinned as '[choice].'")
|
||||
|
||||
/obj/proc/gang_contraband_value()
|
||||
return 0
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
/obj/structure/alien/weeds/Initialize()
|
||||
pixel_x = -4
|
||||
pixel_y = -4 //so the sprites line up right in the map editor
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
if(!blacklisted_turfs)
|
||||
blacklisted_turfs = typecacheof(list(
|
||||
@@ -178,7 +178,7 @@
|
||||
|
||||
/obj/structure/alien/weeds/node/Initialize()
|
||||
icon = 'icons/obj/smooth_structures/alien/weednode.dmi'
|
||||
..()
|
||||
. = ..()
|
||||
set_light(lon_range)
|
||||
var/obj/structure/alien/weeds/W = locate(/obj/structure/alien/weeds) in loc
|
||||
if(W && W != src)
|
||||
@@ -223,7 +223,7 @@
|
||||
var/obj/item/clothing/mask/facehugger/child
|
||||
|
||||
/obj/structure/alien/egg/Initialize(mapload)
|
||||
..()
|
||||
. = ..()
|
||||
update_icon()
|
||||
if(status == GROWING || status == GROWN)
|
||||
child = new(src)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
layer = OBJ_LAYER
|
||||
|
||||
/obj/structure/chair/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
if(!anchored) //why would you put these on the shuttle?
|
||||
addtimer(CALLBACK(src, .proc/RemoveFromLatejoin), 0)
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/obj/structure/chair/sofa
|
||||
name = "old ratty sofa"
|
||||
icon_state = "sofamiddle"
|
||||
icon = 'icons/obj/sofa.dmi'
|
||||
buildstackamount = 1
|
||||
|
||||
/obj/structure/chair/sofa/left
|
||||
icon_state = "sofaend_left"
|
||||
/obj/structure/chair/sofa/right
|
||||
icon_state = "sofaend_right"
|
||||
/obj/structure/chair/sofa/corner
|
||||
icon_state = "sofacorner"
|
||||
@@ -16,7 +16,7 @@
|
||||
integrity_failure = 50
|
||||
armor = list(melee = 20, bullet = 10, laser = 10, energy = 0, bomb = 10, bio = 0, rad = 0, fire = 70, acid = 60)
|
||||
var/breakout_time = 2
|
||||
var/lastbang
|
||||
var/message_cooldown
|
||||
var/can_weld_shut = TRUE
|
||||
var/horizontal = FALSE
|
||||
var/allow_objects = FALSE
|
||||
@@ -300,14 +300,12 @@
|
||||
/obj/structure/closet/relaymove(mob/user)
|
||||
if(user.stat || !isturf(loc) || !isliving(user))
|
||||
return
|
||||
var/mob/living/L = user
|
||||
if(!open())
|
||||
if(L.last_special <= world.time)
|
||||
container_resist(L)
|
||||
if(world.time > lastbang+5)
|
||||
lastbang = world.time
|
||||
for(var/mob/M in get_hearers_in_view(src, null))
|
||||
M.show_message("<FONT size=[max(0, 5 - get_dist(src, M))]>BANG, bang!</FONT>", 2)
|
||||
if(locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
container_resist()
|
||||
|
||||
/obj/structure/closet/attack_hand(mob/user)
|
||||
..()
|
||||
@@ -367,9 +365,10 @@
|
||||
//okay, so the closet is either welded or locked... resist!!!
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open.</span>")
|
||||
visible_message("<span class='warning'>[src] begins to shake violently!</span>")
|
||||
if(do_after(user,(breakout_time * 60 * 10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
user.visible_message("<span class='warning'>[src] begins to shake violently!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear banging from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) )
|
||||
return
|
||||
//we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting
|
||||
@@ -388,7 +387,7 @@
|
||||
|
||||
/obj/structure/closet/AltClick(mob/user)
|
||||
..()
|
||||
if(!user.canUseTopic(src, be_close=TRUE))
|
||||
if(!user.canUseTopic(src, be_close=TRUE) || !isturf(loc))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
if(opened || !secure)
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
new /obj/item/storage/belt/security/full(src)
|
||||
new /obj/item/gun/energy/e_gun/hos(src)
|
||||
new /obj/item/device/flashlight/seclite(src)
|
||||
new /obj/item/pinpointer(src)
|
||||
new /obj/item/pinpointer/nuke(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/warden
|
||||
name = "\proper warden's locker"
|
||||
@@ -108,6 +108,7 @@
|
||||
new /obj/item/clothing/gloves/krav_maga/sec(src)
|
||||
new /obj/item/door_remote/head_of_security(src)
|
||||
new /obj/item/gun/ballistic/shotgun/automatic/combat/compact(src)
|
||||
new /obj/item/pinpointer/crew(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/security
|
||||
name = "security officer's locker"
|
||||
@@ -183,6 +184,8 @@
|
||||
new /obj/item/reagent_containers/spray/pepper(src)
|
||||
new /obj/item/clothing/suit/armor/vest/det_suit(src)
|
||||
new /obj/item/storage/belt/holster/full(src)
|
||||
new /obj/item/pinpointer/crew(src)
|
||||
new /obj/item/device/mass_spectrometer(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/injection
|
||||
name = "lethal injections"
|
||||
|
||||
@@ -267,6 +267,7 @@
|
||||
var/image/I = image(icon = 'icons/obj/flora/plants.dmi' , icon_state = src.icon_state, loc = user)
|
||||
I.override = 1
|
||||
add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "sneaking_mission", I)
|
||||
I.layer = ABOVE_MOB_LAYER
|
||||
..()
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/dropped(mob/living/user)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
var/height = 0 //the 'height' of the ladder. higher numbers are considered physically higher
|
||||
var/obj/structure/ladder/down = null //the ladder below this one
|
||||
var/obj/structure/ladder/up = null //the ladder above this one
|
||||
var/auto_connect = FALSE
|
||||
|
||||
/obj/structure/ladder/unbreakable //mostly useful for awaymissions to prevent halting progress in a mission
|
||||
name = "sturdy ladder"
|
||||
@@ -19,12 +20,18 @@
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/structure/ladder/Destroy()
|
||||
if(up && up.down == src)
|
||||
up.down = null
|
||||
up.update_icon()
|
||||
if(down && down.up == src)
|
||||
down.up = null
|
||||
down.update_icon()
|
||||
GLOB.ladders -= src
|
||||
. = ..()
|
||||
|
||||
/obj/structure/ladder/LateInitialize()
|
||||
for(var/obj/structure/ladder/L in GLOB.ladders)
|
||||
if(L.id == id)
|
||||
if(L.id == id || (auto_connect && L.auto_connect && L.x == x && L.y == y))
|
||||
if(L.height == (height - 1))
|
||||
down = L
|
||||
continue
|
||||
@@ -50,31 +57,33 @@
|
||||
else //wtf make your ladders properly assholes
|
||||
icon_state = "ladder00"
|
||||
|
||||
/obj/structure/ladder/proc/go_up(mob/user,is_ghost)
|
||||
/obj/structure/ladder/proc/travel(going_up, mob/user, is_ghost, obj/structure/ladder/ladder)
|
||||
if(!is_ghost)
|
||||
show_fluff_message(1,user)
|
||||
up.add_fingerprint(user)
|
||||
user.loc = get_turf(up)
|
||||
show_fluff_message(going_up,user)
|
||||
ladder.add_fingerprint(user)
|
||||
|
||||
var/atom/movable/AM
|
||||
if(user.pulling)
|
||||
AM = user.pulling
|
||||
user.pulling.forceMove(get_turf(ladder))
|
||||
user.forceMove(get_turf(ladder))
|
||||
if(AM)
|
||||
user.start_pulling(AM)
|
||||
|
||||
/obj/structure/ladder/proc/go_down(mob/user,is_ghost)
|
||||
if(!is_ghost)
|
||||
show_fluff_message(0,user)
|
||||
down.add_fingerprint(user)
|
||||
user.loc = get_turf(down)
|
||||
|
||||
/obj/structure/ladder/proc/use(mob/user,is_ghost=0)
|
||||
if(up && down)
|
||||
switch( alert("Go up or down the ladder?", "Ladder", "Up", "Down", "Cancel") )
|
||||
if("Up")
|
||||
go_up(user,is_ghost)
|
||||
travel(TRUE, user, is_ghost, up)
|
||||
if("Down")
|
||||
go_down(user,is_ghost)
|
||||
travel(FALSE, user, is_ghost, down)
|
||||
if("Cancel")
|
||||
return
|
||||
else if(up)
|
||||
go_up(user,is_ghost)
|
||||
travel(TRUE, user, is_ghost, up)
|
||||
else if(down)
|
||||
go_down(user,is_ghost)
|
||||
travel(FALSE, user,is_ghost, down)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] doesn't seem to lead anywhere!</span>")
|
||||
|
||||
@@ -108,3 +117,14 @@
|
||||
. = ..()
|
||||
else
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
/obj/structure/ladder/unbreakable/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/structure/ladder/auto_connect //They will connect to ladders with the same X and Y without needing to share an ID
|
||||
auto_connect = TRUE
|
||||
|
||||
|
||||
/obj/structure/ladder/singularity_pull()
|
||||
visible_message("<span class='danger'>[src] is torn to pieces by the gravitational pull!</span>")
|
||||
qdel(src)
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/lattice/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FOUR)
|
||||
deconstruct()
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
var/obj/structure/tray/connected = null
|
||||
var/locked = FALSE
|
||||
var/opendir = SOUTH
|
||||
var/message_cooldown
|
||||
var/breakout_time = 1
|
||||
|
||||
/obj/structure/bodycontainer/Destroy()
|
||||
open()
|
||||
@@ -41,6 +43,11 @@
|
||||
/obj/structure/bodycontainer/relaymove(mob/user)
|
||||
if(user.stat || !isturf(loc))
|
||||
return
|
||||
if(locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
open()
|
||||
|
||||
/obj/structure/bodycontainer/attack_paw(mob/user)
|
||||
@@ -84,11 +91,20 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/bodycontainer/container_resist(mob/living/user)
|
||||
open()
|
||||
|
||||
/obj/structure/bodycontainer/relay_container_resist(mob/living/user, obj/O)
|
||||
to_chat(user, "<span class='notice'>You slam yourself into the side of [O].</span>")
|
||||
container_resist(user)
|
||||
if(!locked)
|
||||
open()
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message(null, \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the tray open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src )
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open()
|
||||
|
||||
/obj/structure/bodycontainer/proc/open()
|
||||
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
|
||||
|
||||
#define MUSICIAN_HEARCHECK_MINDELAY 4
|
||||
#define MUSIC_MAXLINES 300
|
||||
#define MUSIC_MAXLINECHARS 50
|
||||
|
||||
/datum/song
|
||||
var/name = "Untitled"
|
||||
var/list/lines = new()
|
||||
var/tempo = 5 // delay between notes
|
||||
|
||||
var/playing = 0 // if we're playing
|
||||
var/help = 0 // if help is open
|
||||
var/edit = 1 // if we're in editing mode
|
||||
var/repeat = 0 // number of times remaining to repeat
|
||||
var/max_repeats = 10 // maximum times we can repeat
|
||||
|
||||
var/instrumentDir = "piano" // the folder with the sounds
|
||||
var/instrumentExt = "ogg" // the file extension
|
||||
var/obj/instrumentObj = null // the associated obj playing the sound
|
||||
|
||||
/datum/song
|
||||
var/name = "Untitled"
|
||||
var/list/lines = new()
|
||||
var/tempo = 5 // delay between notes
|
||||
|
||||
var/playing = 0 // if we're playing
|
||||
var/help = 0 // if help is open
|
||||
var/edit = 1 // if we're in editing mode
|
||||
var/repeat = 0 // number of times remaining to repeat
|
||||
var/max_repeats = 10 // maximum times we can repeat
|
||||
|
||||
var/instrumentDir = "piano" // the folder with the sounds
|
||||
var/instrumentExt = "ogg" // the file extension
|
||||
var/obj/instrumentObj = null // the associated obj playing the sound
|
||||
var/last_hearcheck = 0
|
||||
var/list/hearing_mobs
|
||||
|
||||
|
||||
/datum/song/New(dir, obj, ext = "ogg")
|
||||
tempo = sanitize_tempo(tempo)
|
||||
instrumentDir = dir
|
||||
instrumentObj = obj
|
||||
tempo = sanitize_tempo(tempo)
|
||||
instrumentDir = dir
|
||||
instrumentObj = obj
|
||||
instrumentExt = ext
|
||||
|
||||
/datum/song/Destroy()
|
||||
instrumentObj = null
|
||||
return ..()
|
||||
|
||||
// note is a number from 1-7 for A-G
|
||||
// acc is either "b", "n", or "#"
|
||||
// oct is 1-8 (or 9 for C)
|
||||
/datum/song/proc/playnote(note, acc as text, oct)
|
||||
// handle accidental -> B<>C of E<>F
|
||||
if(acc == "b" && (note == 3 || note == 6)) // C or F
|
||||
if(note == 3)
|
||||
oct--
|
||||
note--
|
||||
acc = "n"
|
||||
else if(acc == "#" && (note == 2 || note == 5)) // B or E
|
||||
if(note == 2)
|
||||
oct++
|
||||
note++
|
||||
acc = "n"
|
||||
else if(acc == "#" && (note == 7)) //G#
|
||||
note = 1
|
||||
acc = "b"
|
||||
else if(acc == "#") // mass convert all sharps to flats, octave jump already handled
|
||||
acc = "b"
|
||||
note++
|
||||
|
||||
// check octave, C is allowed to go to 9
|
||||
if(oct < 1 || (note == 3 ? oct > 9 : oct > 8))
|
||||
return
|
||||
|
||||
// now generate name
|
||||
|
||||
/datum/song/Destroy()
|
||||
instrumentObj = null
|
||||
return ..()
|
||||
|
||||
// note is a number from 1-7 for A-G
|
||||
// acc is either "b", "n", or "#"
|
||||
// oct is 1-8 (or 9 for C)
|
||||
/datum/song/proc/playnote(note, acc as text, oct)
|
||||
// handle accidental -> B<>C of E<>F
|
||||
if(acc == "b" && (note == 3 || note == 6)) // C or F
|
||||
if(note == 3)
|
||||
oct--
|
||||
note--
|
||||
acc = "n"
|
||||
else if(acc == "#" && (note == 2 || note == 5)) // B or E
|
||||
if(note == 2)
|
||||
oct++
|
||||
note++
|
||||
acc = "n"
|
||||
else if(acc == "#" && (note == 7)) //G#
|
||||
note = 1
|
||||
acc = "b"
|
||||
else if(acc == "#") // mass convert all sharps to flats, octave jump already handled
|
||||
acc = "b"
|
||||
note++
|
||||
|
||||
// check octave, C is allowed to go to 9
|
||||
if(oct < 1 || (note == 3 ? oct > 9 : oct > 8))
|
||||
return
|
||||
|
||||
// now generate name
|
||||
var/soundfile = "sound/instruments/[instrumentDir]/[ascii2text(note+64)][acc][oct].[instrumentExt]"
|
||||
soundfile = file(soundfile)
|
||||
// make sure the note exists
|
||||
if(!fexists(soundfile))
|
||||
return
|
||||
// and play
|
||||
var/turf/source = get_turf(instrumentObj)
|
||||
soundfile = file(soundfile)
|
||||
// make sure the note exists
|
||||
if(!fexists(soundfile))
|
||||
return
|
||||
// and play
|
||||
var/turf/source = get_turf(instrumentObj)
|
||||
if((world.time - MUSICIAN_HEARCHECK_MINDELAY) > last_hearcheck)
|
||||
LAZYCLEARLIST(hearing_mobs)
|
||||
for(var/mob/M in get_hearers_in_view(15, source))
|
||||
@@ -76,321 +76,321 @@
|
||||
for(var/i in hearing_mobs)
|
||||
var/mob/M = i
|
||||
M.playsound_local(source, null, 100, falloff = 5, S = music_played)
|
||||
|
||||
/datum/song/proc/updateDialog(mob/user)
|
||||
instrumentObj.updateDialog() // assumes it's an object in world, override if otherwise
|
||||
|
||||
/datum/song/proc/shouldStopPlaying(mob/user)
|
||||
if(instrumentObj)
|
||||
if(!user.canUseTopic(instrumentObj))
|
||||
|
||||
/datum/song/proc/updateDialog(mob/user)
|
||||
instrumentObj.updateDialog() // assumes it's an object in world, override if otherwise
|
||||
|
||||
/datum/song/proc/shouldStopPlaying(mob/user)
|
||||
if(instrumentObj)
|
||||
if(!user.canUseTopic(instrumentObj))
|
||||
return TRUE
|
||||
return !instrumentObj.anchored // add special cases to stop in subclasses
|
||||
else
|
||||
return !instrumentObj.anchored // add special cases to stop in subclasses
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/datum/song/proc/playsong(mob/user)
|
||||
while(repeat >= 0)
|
||||
var/cur_oct[7]
|
||||
var/cur_acc[7]
|
||||
for(var/i = 1 to 7)
|
||||
cur_oct[i] = 3
|
||||
cur_acc[i] = "n"
|
||||
|
||||
for(var/line in lines)
|
||||
//to_chat(world, line)
|
||||
for(var/beat in splittext(lowertext(line), ","))
|
||||
//to_chat(world, "beat: [beat]")
|
||||
var/list/notes = splittext(beat, "/")
|
||||
for(var/note in splittext(notes[1], "-"))
|
||||
//to_chat(world, "note: [note]")
|
||||
if(!playing || shouldStopPlaying(user))//If the instrument is playing, or special case
|
||||
|
||||
/datum/song/proc/playsong(mob/user)
|
||||
while(repeat >= 0)
|
||||
var/cur_oct[7]
|
||||
var/cur_acc[7]
|
||||
for(var/i = 1 to 7)
|
||||
cur_oct[i] = 3
|
||||
cur_acc[i] = "n"
|
||||
|
||||
for(var/line in lines)
|
||||
//to_chat(world, line)
|
||||
for(var/beat in splittext(lowertext(line), ","))
|
||||
//to_chat(world, "beat: [beat]")
|
||||
var/list/notes = splittext(beat, "/")
|
||||
for(var/note in splittext(notes[1], "-"))
|
||||
//to_chat(world, "note: [note]")
|
||||
if(!playing || shouldStopPlaying(user))//If the instrument is playing, or special case
|
||||
playing = FALSE
|
||||
hearing_mobs = null
|
||||
return
|
||||
return
|
||||
if(!lentext(note))
|
||||
continue
|
||||
//to_chat(world, "Parse: [copytext(note,1,2)]")
|
||||
var/cur_note = text2ascii(note) - 96
|
||||
if(cur_note < 1 || cur_note > 7)
|
||||
continue
|
||||
for(var/i=2 to lentext(note))
|
||||
var/ni = copytext(note,i,i+1)
|
||||
if(!text2num(ni))
|
||||
if(ni == "#" || ni == "b" || ni == "n")
|
||||
cur_acc[cur_note] = ni
|
||||
else if(ni == "s")
|
||||
cur_acc[cur_note] = "#" // so shift is never required
|
||||
else
|
||||
cur_oct[cur_note] = text2num(ni)
|
||||
if(user.dizziness > 0 && prob(user.dizziness / 2))
|
||||
cur_note = Clamp(cur_note + rand(round(-user.dizziness / 10), round(user.dizziness / 10)), 1, 7)
|
||||
if(user.dizziness > 0 && prob(user.dizziness / 5))
|
||||
if(prob(30))
|
||||
cur_acc[cur_note] = "#"
|
||||
else if(prob(42))
|
||||
cur_acc[cur_note] = "b"
|
||||
else if(prob(75))
|
||||
cur_acc[cur_note] = "n"
|
||||
playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note])
|
||||
if(notes.len >= 2 && text2num(notes[2]))
|
||||
sleep(sanitize_tempo(tempo / text2num(notes[2])))
|
||||
else
|
||||
sleep(tempo)
|
||||
repeat--
|
||||
continue
|
||||
//to_chat(world, "Parse: [copytext(note,1,2)]")
|
||||
var/cur_note = text2ascii(note) - 96
|
||||
if(cur_note < 1 || cur_note > 7)
|
||||
continue
|
||||
for(var/i=2 to lentext(note))
|
||||
var/ni = copytext(note,i,i+1)
|
||||
if(!text2num(ni))
|
||||
if(ni == "#" || ni == "b" || ni == "n")
|
||||
cur_acc[cur_note] = ni
|
||||
else if(ni == "s")
|
||||
cur_acc[cur_note] = "#" // so shift is never required
|
||||
else
|
||||
cur_oct[cur_note] = text2num(ni)
|
||||
if(user.dizziness > 0 && prob(user.dizziness / 2))
|
||||
cur_note = Clamp(cur_note + rand(round(-user.dizziness / 10), round(user.dizziness / 10)), 1, 7)
|
||||
if(user.dizziness > 0 && prob(user.dizziness / 5))
|
||||
if(prob(30))
|
||||
cur_acc[cur_note] = "#"
|
||||
else if(prob(42))
|
||||
cur_acc[cur_note] = "b"
|
||||
else if(prob(75))
|
||||
cur_acc[cur_note] = "n"
|
||||
playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note])
|
||||
if(notes.len >= 2 && text2num(notes[2]))
|
||||
sleep(sanitize_tempo(tempo / text2num(notes[2])))
|
||||
else
|
||||
sleep(tempo)
|
||||
repeat--
|
||||
hearing_mobs = null
|
||||
playing = FALSE
|
||||
repeat = 0
|
||||
updateDialog(user)
|
||||
|
||||
/datum/song/proc/interact(mob/user)
|
||||
var/dat = ""
|
||||
|
||||
if(lines.len > 0)
|
||||
dat += "<H3>Playback</H3>"
|
||||
if(!playing)
|
||||
dat += "<A href='?src=\ref[src];play=1'>Play</A> <SPAN CLASS='linkOn'>Stop</SPAN><BR><BR>"
|
||||
dat += "Repeat Song: "
|
||||
dat += repeat > 0 ? "<A href='?src=\ref[src];repeat=-10'>-</A><A href='?src=\ref[src];repeat=-1'>-</A>" : "<SPAN CLASS='linkOff'>-</SPAN><SPAN CLASS='linkOff'>-</SPAN>"
|
||||
dat += " [repeat] times "
|
||||
dat += repeat < max_repeats ? "<A href='?src=\ref[src];repeat=1'>+</A><A href='?src=\ref[src];repeat=10'>+</A>" : "<SPAN CLASS='linkOff'>+</SPAN><SPAN CLASS='linkOff'>+</SPAN>"
|
||||
dat += "<BR>"
|
||||
else
|
||||
dat += "<SPAN CLASS='linkOn'>Play</SPAN> <A href='?src=\ref[src];stop=1'>Stop</A><BR>"
|
||||
dat += "Repeats left: <B>[repeat]</B><BR>"
|
||||
if(!edit)
|
||||
dat += "<BR><B><A href='?src=\ref[src];edit=2'>Show Editor</A></B><BR>"
|
||||
else
|
||||
dat += "<H3>Editing</H3>"
|
||||
dat += "<B><A href='?src=\ref[src];edit=1'>Hide Editor</A></B>"
|
||||
dat += " <A href='?src=\ref[src];newsong=1'>Start a New Song</A>"
|
||||
dat += " <A href='?src=\ref[src];import=1'>Import a Song</A><BR><BR>"
|
||||
var/bpm = round(600 / tempo)
|
||||
dat += "Tempo: <A href='?src=\ref[src];tempo=[world.tick_lag]'>-</A> [bpm] BPM <A href='?src=\ref[src];tempo=-[world.tick_lag]'>+</A><BR><BR>"
|
||||
var/linecount = 0
|
||||
for(var/line in lines)
|
||||
linecount += 1
|
||||
dat += "Line [linecount]: <A href='?src=\ref[src];modifyline=[linecount]'>Edit</A> <A href='?src=\ref[src];deleteline=[linecount]'>X</A> [line]<BR>"
|
||||
dat += "<A href='?src=\ref[src];newline=1'>Add Line</A><BR><BR>"
|
||||
if(help)
|
||||
dat += "<B><A href='?src=\ref[src];help=1'>Hide Help</A></B><BR>"
|
||||
dat += {"
|
||||
repeat = 0
|
||||
updateDialog(user)
|
||||
|
||||
/datum/song/proc/interact(mob/user)
|
||||
var/dat = ""
|
||||
|
||||
if(lines.len > 0)
|
||||
dat += "<H3>Playback</H3>"
|
||||
if(!playing)
|
||||
dat += "<A href='?src=\ref[src];play=1'>Play</A> <SPAN CLASS='linkOn'>Stop</SPAN><BR><BR>"
|
||||
dat += "Repeat Song: "
|
||||
dat += repeat > 0 ? "<A href='?src=\ref[src];repeat=-10'>-</A><A href='?src=\ref[src];repeat=-1'>-</A>" : "<SPAN CLASS='linkOff'>-</SPAN><SPAN CLASS='linkOff'>-</SPAN>"
|
||||
dat += " [repeat] times "
|
||||
dat += repeat < max_repeats ? "<A href='?src=\ref[src];repeat=1'>+</A><A href='?src=\ref[src];repeat=10'>+</A>" : "<SPAN CLASS='linkOff'>+</SPAN><SPAN CLASS='linkOff'>+</SPAN>"
|
||||
dat += "<BR>"
|
||||
else
|
||||
dat += "<SPAN CLASS='linkOn'>Play</SPAN> <A href='?src=\ref[src];stop=1'>Stop</A><BR>"
|
||||
dat += "Repeats left: <B>[repeat]</B><BR>"
|
||||
if(!edit)
|
||||
dat += "<BR><B><A href='?src=\ref[src];edit=2'>Show Editor</A></B><BR>"
|
||||
else
|
||||
dat += "<H3>Editing</H3>"
|
||||
dat += "<B><A href='?src=\ref[src];edit=1'>Hide Editor</A></B>"
|
||||
dat += " <A href='?src=\ref[src];newsong=1'>Start a New Song</A>"
|
||||
dat += " <A href='?src=\ref[src];import=1'>Import a Song</A><BR><BR>"
|
||||
var/bpm = round(600 / tempo)
|
||||
dat += "Tempo: <A href='?src=\ref[src];tempo=[world.tick_lag]'>-</A> [bpm] BPM <A href='?src=\ref[src];tempo=-[world.tick_lag]'>+</A><BR><BR>"
|
||||
var/linecount = 0
|
||||
for(var/line in lines)
|
||||
linecount += 1
|
||||
dat += "Line [linecount]: <A href='?src=\ref[src];modifyline=[linecount]'>Edit</A> <A href='?src=\ref[src];deleteline=[linecount]'>X</A> [line]<BR>"
|
||||
dat += "<A href='?src=\ref[src];newline=1'>Add Line</A><BR><BR>"
|
||||
if(help)
|
||||
dat += "<B><A href='?src=\ref[src];help=1'>Hide Help</A></B><BR>"
|
||||
dat += {"
|
||||
Lines are a series of chords, separated by commas (,), each with notes separated by hyphens (-).<br>
|
||||
Every note in a chord will play together, with chord timed by the tempo.<br>
|
||||
<br>
|
||||
Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.<br>
|
||||
By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.<br>
|
||||
Example: <i>C,D,E,F,G,A,B</i> will play a C major scale.<br>
|
||||
After a note has an accidental placed, it will be remembered: <i>C,C4,C,C3</i> is C3,C4,C4,C3</i><br>
|
||||
Chords can be played simply by seperating each note with a hyphon: <i>A-C#,Cn-E,E-G#,Gn-B</i><br>
|
||||
A pause may be denoted by an empty chord: <i>C,E,,C,G</i><br>
|
||||
To make a chord be a different time, end it with /x, where the chord length will be length<br>
|
||||
defined by tempo / x: <i>C,G/2,E/4</i><br>
|
||||
Combined, an example is: <i>E-E4/4,F#/2,G#/8,B/8,E3-E4/4</i>
|
||||
<br>
|
||||
Every note in a chord will play together, with chord timed by the tempo.<br>
|
||||
<br>
|
||||
Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.<br>
|
||||
By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.<br>
|
||||
Example: <i>C,D,E,F,G,A,B</i> will play a C major scale.<br>
|
||||
After a note has an accidental placed, it will be remembered: <i>C,C4,C,C3</i> is C3,C4,C4,C3</i><br>
|
||||
Chords can be played simply by seperating each note with a hyphon: <i>A-C#,Cn-E,E-G#,Gn-B</i><br>
|
||||
A pause may be denoted by an empty chord: <i>C,E,,C,G</i><br>
|
||||
To make a chord be a different time, end it with /x, where the chord length will be length<br>
|
||||
defined by tempo / x: <i>C,G/2,E/4</i><br>
|
||||
Combined, an example is: <i>E-E4/4,F#/2,G#/8,B/8,E3-E4/4</i>
|
||||
<br>
|
||||
Lines may be up to [MUSIC_MAXLINECHARS] characters.<br>
|
||||
A song may only contain up to [MUSIC_MAXLINES] lines.<br>
|
||||
"}
|
||||
else
|
||||
dat += "<B><A href='?src=\ref[src];help=2'>Show Help</A></B><BR>"
|
||||
|
||||
var/datum/browser/popup = new(user, "instrument", instrumentObj.name, 700, 500)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(instrumentObj.icon, instrumentObj.icon_state))
|
||||
popup.open()
|
||||
|
||||
/datum/song/proc/ParseSong(text)
|
||||
set waitfor = FALSE
|
||||
//split into lines
|
||||
lines = splittext(text, "\n")
|
||||
if(lines.len)
|
||||
if(copytext(lines[1],1,6) == "BPM: ")
|
||||
tempo = sanitize_tempo(600 / text2num(copytext(lines[1],6)))
|
||||
lines.Cut(1,2)
|
||||
else
|
||||
tempo = sanitize_tempo(5) // default 120 BPM
|
||||
"}
|
||||
else
|
||||
dat += "<B><A href='?src=\ref[src];help=2'>Show Help</A></B><BR>"
|
||||
|
||||
var/datum/browser/popup = new(user, "instrument", instrumentObj.name, 700, 500)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(instrumentObj.icon, instrumentObj.icon_state))
|
||||
popup.open()
|
||||
|
||||
/datum/song/proc/ParseSong(text)
|
||||
set waitfor = FALSE
|
||||
//split into lines
|
||||
lines = splittext(text, "\n")
|
||||
if(lines.len)
|
||||
if(copytext(lines[1],1,6) == "BPM: ")
|
||||
tempo = sanitize_tempo(600 / text2num(copytext(lines[1],6)))
|
||||
lines.Cut(1,2)
|
||||
else
|
||||
tempo = sanitize_tempo(5) // default 120 BPM
|
||||
if(lines.len > MUSIC_MAXLINES)
|
||||
to_chat(usr, "Too many lines!")
|
||||
to_chat(usr, "Too many lines!")
|
||||
lines.Cut(MUSIC_MAXLINES + 1)
|
||||
var/linenum = 1
|
||||
for(var/l in lines)
|
||||
var/linenum = 1
|
||||
for(var/l in lines)
|
||||
if(lentext(l) > MUSIC_MAXLINECHARS)
|
||||
to_chat(usr, "Line [linenum] too long!")
|
||||
lines.Remove(l)
|
||||
else
|
||||
linenum++
|
||||
updateDialog(usr) // make sure updates when complete
|
||||
|
||||
/datum/song/Topic(href, href_list)
|
||||
if(!usr.canUseTopic(instrumentObj))
|
||||
usr << browse(null, "window=instrument")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
instrumentObj.add_fingerprint(usr)
|
||||
|
||||
if(href_list["newsong"])
|
||||
lines = new()
|
||||
tempo = sanitize_tempo(5) // default 120 BPM
|
||||
name = ""
|
||||
|
||||
else if(href_list["import"])
|
||||
var/t = ""
|
||||
do
|
||||
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
|
||||
if(!in_range(instrumentObj, usr))
|
||||
return
|
||||
|
||||
to_chat(usr, "Line [linenum] too long!")
|
||||
lines.Remove(l)
|
||||
else
|
||||
linenum++
|
||||
updateDialog(usr) // make sure updates when complete
|
||||
|
||||
/datum/song/Topic(href, href_list)
|
||||
if(!usr.canUseTopic(instrumentObj))
|
||||
usr << browse(null, "window=instrument")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
instrumentObj.add_fingerprint(usr)
|
||||
|
||||
if(href_list["newsong"])
|
||||
lines = new()
|
||||
tempo = sanitize_tempo(5) // default 120 BPM
|
||||
name = ""
|
||||
|
||||
else if(href_list["import"])
|
||||
var/t = ""
|
||||
do
|
||||
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
|
||||
if(!in_range(instrumentObj, usr))
|
||||
return
|
||||
|
||||
if(lentext(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
|
||||
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
|
||||
if(cont == "no")
|
||||
break
|
||||
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
|
||||
if(cont == "no")
|
||||
break
|
||||
while(lentext(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
|
||||
ParseSong(t)
|
||||
|
||||
else if(href_list["help"])
|
||||
help = text2num(href_list["help"]) - 1
|
||||
|
||||
else if(href_list["edit"])
|
||||
edit = text2num(href_list["edit"]) - 1
|
||||
|
||||
if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops.
|
||||
if(playing)
|
||||
return //So that people cant keep adding to repeat. If the do it intentionally, it could result in the server crashing.
|
||||
repeat += round(text2num(href_list["repeat"]))
|
||||
if(repeat < 0)
|
||||
repeat = 0
|
||||
if(repeat > max_repeats)
|
||||
repeat = max_repeats
|
||||
|
||||
else if(href_list["tempo"])
|
||||
tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]))
|
||||
|
||||
else if(href_list["play"])
|
||||
ParseSong(t)
|
||||
|
||||
else if(href_list["help"])
|
||||
help = text2num(href_list["help"]) - 1
|
||||
|
||||
else if(href_list["edit"])
|
||||
edit = text2num(href_list["edit"]) - 1
|
||||
|
||||
if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops.
|
||||
if(playing)
|
||||
return //So that people cant keep adding to repeat. If the do it intentionally, it could result in the server crashing.
|
||||
repeat += round(text2num(href_list["repeat"]))
|
||||
if(repeat < 0)
|
||||
repeat = 0
|
||||
if(repeat > max_repeats)
|
||||
repeat = max_repeats
|
||||
|
||||
else if(href_list["tempo"])
|
||||
tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]))
|
||||
|
||||
else if(href_list["play"])
|
||||
playing = TRUE
|
||||
spawn()
|
||||
playsong(usr)
|
||||
|
||||
else if(href_list["newline"])
|
||||
var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null)
|
||||
if(!newline || !in_range(instrumentObj, usr))
|
||||
return
|
||||
spawn()
|
||||
playsong(usr)
|
||||
|
||||
else if(href_list["newline"])
|
||||
var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null)
|
||||
if(!newline || !in_range(instrumentObj, usr))
|
||||
return
|
||||
if(lines.len > MUSIC_MAXLINES)
|
||||
return
|
||||
return
|
||||
if(lentext(newline) > MUSIC_MAXLINECHARS)
|
||||
newline = copytext(newline, 1, MUSIC_MAXLINECHARS)
|
||||
lines.Add(newline)
|
||||
|
||||
else if(href_list["deleteline"])
|
||||
var/num = round(text2num(href_list["deleteline"]))
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines.Cut(num, num+1)
|
||||
|
||||
else if(href_list["modifyline"])
|
||||
var/num = round(text2num(href_list["modifyline"]),1)
|
||||
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
|
||||
if(!content || !in_range(instrumentObj, usr))
|
||||
return
|
||||
lines.Add(newline)
|
||||
|
||||
else if(href_list["deleteline"])
|
||||
var/num = round(text2num(href_list["deleteline"]))
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines.Cut(num, num+1)
|
||||
|
||||
else if(href_list["modifyline"])
|
||||
var/num = round(text2num(href_list["modifyline"]),1)
|
||||
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
|
||||
if(!content || !in_range(instrumentObj, usr))
|
||||
return
|
||||
if(lentext(content) > MUSIC_MAXLINECHARS)
|
||||
content = copytext(content, 1, MUSIC_MAXLINECHARS)
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines[num] = content
|
||||
|
||||
else if(href_list["stop"])
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines[num] = content
|
||||
|
||||
else if(href_list["stop"])
|
||||
playing = FALSE
|
||||
hearing_mobs = null
|
||||
|
||||
updateDialog(usr)
|
||||
return
|
||||
|
||||
/datum/song/proc/sanitize_tempo(new_tempo)
|
||||
new_tempo = abs(new_tempo)
|
||||
return max(round(new_tempo, world.tick_lag), world.tick_lag)
|
||||
|
||||
// subclass for handheld instruments, like violin
|
||||
/datum/song/handheld
|
||||
|
||||
/datum/song/handheld/updateDialog(mob/user)
|
||||
instrumentObj.interact(user)
|
||||
|
||||
/datum/song/handheld/shouldStopPlaying()
|
||||
if(instrumentObj)
|
||||
return !isliving(instrumentObj.loc)
|
||||
else
|
||||
|
||||
updateDialog(usr)
|
||||
return
|
||||
|
||||
/datum/song/proc/sanitize_tempo(new_tempo)
|
||||
new_tempo = abs(new_tempo)
|
||||
return max(round(new_tempo, world.tick_lag), world.tick_lag)
|
||||
|
||||
// subclass for handheld instruments, like violin
|
||||
/datum/song/handheld
|
||||
|
||||
/datum/song/handheld/updateDialog(mob/user)
|
||||
instrumentObj.interact(user)
|
||||
|
||||
/datum/song/handheld/shouldStopPlaying()
|
||||
if(instrumentObj)
|
||||
return !isliving(instrumentObj.loc)
|
||||
else
|
||||
return TRUE
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/structure/piano
|
||||
name = "space minimoog"
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "minimoog"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/structure/piano
|
||||
name = "space minimoog"
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "minimoog"
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
var/datum/song/song
|
||||
|
||||
|
||||
/obj/structure/piano/New()
|
||||
..()
|
||||
song = new("piano", src)
|
||||
|
||||
if(prob(50))
|
||||
name = "space minimoog"
|
||||
desc = "This is a minimoog, like a space piano, but more spacey!"
|
||||
icon_state = "minimoog"
|
||||
else
|
||||
name = "space piano"
|
||||
desc = "This is a space piano, like a regular piano, but always in tune! Even if the musician isn't."
|
||||
icon_state = "piano"
|
||||
|
||||
/obj/structure/piano/Destroy()
|
||||
qdel(song)
|
||||
song = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/piano/Initialize(mapload)
|
||||
..()
|
||||
if(mapload)
|
||||
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
|
||||
|
||||
/obj/structure/piano/attack_hand(mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return 1
|
||||
interact(user)
|
||||
|
||||
/obj/structure/piano/attack_paw(mob/user)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/structure/piano/interact(mob/user)
|
||||
if(!user || !anchored)
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
song.interact(user)
|
||||
|
||||
/obj/structure/piano/attackby(obj/item/O, mob/user, params)
|
||||
if (istype(O, /obj/item/wrench))
|
||||
if (!anchored && !isinspace())
|
||||
var/datum/song/song
|
||||
|
||||
|
||||
/obj/structure/piano/New()
|
||||
..()
|
||||
song = new("piano", src)
|
||||
|
||||
if(prob(50))
|
||||
name = "space minimoog"
|
||||
desc = "This is a minimoog, like a space piano, but more spacey!"
|
||||
icon_state = "minimoog"
|
||||
else
|
||||
name = "space piano"
|
||||
desc = "This is a space piano, like a regular piano, but always in tune! Even if the musician isn't."
|
||||
icon_state = "piano"
|
||||
|
||||
/obj/structure/piano/Destroy()
|
||||
qdel(song)
|
||||
song = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/piano/Initialize(mapload)
|
||||
. = ..()
|
||||
if(mapload)
|
||||
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
|
||||
|
||||
/obj/structure/piano/attack_hand(mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return 1
|
||||
interact(user)
|
||||
|
||||
/obj/structure/piano/attack_paw(mob/user)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/structure/piano/interact(mob/user)
|
||||
if(!user || !anchored)
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
song.interact(user)
|
||||
|
||||
/obj/structure/piano/attackby(obj/item/O, mob/user, params)
|
||||
if (istype(O, /obj/item/wrench))
|
||||
if (!anchored && !isinspace())
|
||||
playsound(src, O.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'> You begin to tighten \the [src] to the floor...</span>")
|
||||
if (do_after(user, 20*O.toolspeed, target = src))
|
||||
user.visible_message( \
|
||||
"[user] tightens \the [src]'s casters.", \
|
||||
"<span class='notice'>You tighten \the [src]'s casters. Now it can be played again.</span>", \
|
||||
"<span class='italics'>You hear ratchet.</span>")
|
||||
to_chat(user, "<span class='notice'> You begin to tighten \the [src] to the floor...</span>")
|
||||
if (do_after(user, 20*O.toolspeed, target = src))
|
||||
user.visible_message( \
|
||||
"[user] tightens \the [src]'s casters.", \
|
||||
"<span class='notice'>You tighten \the [src]'s casters. Now it can be played again.</span>", \
|
||||
"<span class='italics'>You hear ratchet.</span>")
|
||||
anchored = TRUE
|
||||
else if(anchored)
|
||||
else if(anchored)
|
||||
playsound(src, O.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'> You begin to loosen \the [src]'s casters...</span>")
|
||||
if (do_after(user, 40*O.toolspeed, target = src))
|
||||
user.visible_message( \
|
||||
"[user] loosens \the [src]'s casters.", \
|
||||
"<span class='notice'>You loosen \the [src]. Now it can be pulled somewhere else.</span>", \
|
||||
"<span class='italics'>You hear ratchet.</span>")
|
||||
to_chat(user, "<span class='notice'> You begin to loosen \the [src]'s casters...</span>")
|
||||
if (do_after(user, 40*O.toolspeed, target = src))
|
||||
user.visible_message( \
|
||||
"[user] loosens \the [src]'s casters.", \
|
||||
"<span class='notice'>You loosen \the [src]. Now it can be pulled somewhere else.</span>", \
|
||||
"<span class='italics'>You hear ratchet.</span>")
|
||||
anchored = FALSE
|
||||
else
|
||||
return ..()
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -1,127 +1,127 @@
|
||||
/obj/structure/noticeboard
|
||||
name = "notice board"
|
||||
desc = "A board for pinning important notices upon."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "nboard00"
|
||||
/obj/structure/noticeboard
|
||||
name = "notice board"
|
||||
desc = "A board for pinning important notices upon."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "nboard00"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
max_integrity = 150
|
||||
var/notices = 0
|
||||
|
||||
/obj/structure/noticeboard/Initialize(mapload)
|
||||
..()
|
||||
|
||||
if(!mapload)
|
||||
return
|
||||
|
||||
for(var/obj/item/I in loc)
|
||||
if(notices > 4) break
|
||||
if(istype(I, /obj/item/paper))
|
||||
I.loc = src
|
||||
notices++
|
||||
icon_state = "nboard0[notices]"
|
||||
|
||||
//attaching papers!!
|
||||
/obj/structure/noticeboard/attackby(obj/item/O, mob/user, params)
|
||||
if(istype(O, /obj/item/paper) || istype(O, /obj/item/photo))
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='info'>You are not authorized to add notices</span>")
|
||||
return
|
||||
if(notices < 5)
|
||||
if(!user.transferItemToLoc(O, src))
|
||||
return
|
||||
notices++
|
||||
icon_state = "nboard0[notices]"
|
||||
to_chat(user, "<span class='notice'>You pin the [O] to the noticeboard.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The notice board is full</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/noticeboard/attack_hand(mob/user)
|
||||
var/auth = allowed(user)
|
||||
var/dat = "<B>[name]</B><BR>"
|
||||
for(var/obj/item/P in src)
|
||||
if(istype(P, /obj/item/paper))
|
||||
dat += "<A href='?src=\ref[src];read=\ref[P]'>[P.name]</A> [auth ? "<A href='?src=\ref[src];write=\ref[P]'>Write</A> <A href='?src=\ref[src];remove=\ref[P]'>Remove</A>" : ""]<BR>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];read=\ref[P]'>[P.name]</A> [auth ? "<A href='?src=\ref[src];remove=\ref[P]'>Remove</A>" : ""]<BR>"
|
||||
user << browse("<HEAD><TITLE>Notices</TITLE></HEAD>[dat]","window=noticeboard")
|
||||
onclose(user, "noticeboard")
|
||||
|
||||
/obj/structure/noticeboard/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
if(href_list["remove"])
|
||||
if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
|
||||
return
|
||||
var/obj/item/I = locate(href_list["remove"]) in contents
|
||||
if(istype(I) && I.loc == src)
|
||||
I.loc = usr.loc
|
||||
usr.put_in_hands(I)
|
||||
notices--
|
||||
icon_state = "nboard0[notices]"
|
||||
|
||||
if(href_list["write"])
|
||||
if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
|
||||
return
|
||||
var/obj/item/P = locate(href_list["write"]) in contents
|
||||
if(istype(P) && P.loc == src)
|
||||
var/obj/item/I = usr.is_holding_item_of_type(/obj/item/pen)
|
||||
if(I)
|
||||
add_fingerprint(usr)
|
||||
P.attackby(I, usr)
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You'll need something to write with!</span>")
|
||||
|
||||
if(href_list["read"])
|
||||
var/obj/item/I = locate(href_list["read"]) in contents
|
||||
if(istype(I) && I.loc == src)
|
||||
usr.examinate(I)
|
||||
|
||||
/obj/structure/noticeboard/deconstruct(disassembled = TRUE)
|
||||
max_integrity = 150
|
||||
var/notices = 0
|
||||
|
||||
/obj/structure/noticeboard/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
if(!mapload)
|
||||
return
|
||||
|
||||
for(var/obj/item/I in loc)
|
||||
if(notices > 4) break
|
||||
if(istype(I, /obj/item/paper))
|
||||
I.loc = src
|
||||
notices++
|
||||
icon_state = "nboard0[notices]"
|
||||
|
||||
//attaching papers!!
|
||||
/obj/structure/noticeboard/attackby(obj/item/O, mob/user, params)
|
||||
if(istype(O, /obj/item/paper) || istype(O, /obj/item/photo))
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='info'>You are not authorized to add notices</span>")
|
||||
return
|
||||
if(notices < 5)
|
||||
if(!user.transferItemToLoc(O, src))
|
||||
return
|
||||
notices++
|
||||
icon_state = "nboard0[notices]"
|
||||
to_chat(user, "<span class='notice'>You pin the [O] to the noticeboard.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The notice board is full</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/noticeboard/attack_hand(mob/user)
|
||||
var/auth = allowed(user)
|
||||
var/dat = "<B>[name]</B><BR>"
|
||||
for(var/obj/item/P in src)
|
||||
if(istype(P, /obj/item/paper))
|
||||
dat += "<A href='?src=\ref[src];read=\ref[P]'>[P.name]</A> [auth ? "<A href='?src=\ref[src];write=\ref[P]'>Write</A> <A href='?src=\ref[src];remove=\ref[P]'>Remove</A>" : ""]<BR>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];read=\ref[P]'>[P.name]</A> [auth ? "<A href='?src=\ref[src];remove=\ref[P]'>Remove</A>" : ""]<BR>"
|
||||
user << browse("<HEAD><TITLE>Notices</TITLE></HEAD>[dat]","window=noticeboard")
|
||||
onclose(user, "noticeboard")
|
||||
|
||||
/obj/structure/noticeboard/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
if(href_list["remove"])
|
||||
if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
|
||||
return
|
||||
var/obj/item/I = locate(href_list["remove"]) in contents
|
||||
if(istype(I) && I.loc == src)
|
||||
I.loc = usr.loc
|
||||
usr.put_in_hands(I)
|
||||
notices--
|
||||
icon_state = "nboard0[notices]"
|
||||
|
||||
if(href_list["write"])
|
||||
if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
|
||||
return
|
||||
var/obj/item/P = locate(href_list["write"]) in contents
|
||||
if(istype(P) && P.loc == src)
|
||||
var/obj/item/I = usr.is_holding_item_of_type(/obj/item/pen)
|
||||
if(I)
|
||||
add_fingerprint(usr)
|
||||
P.attackby(I, usr)
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You'll need something to write with!</span>")
|
||||
|
||||
if(href_list["read"])
|
||||
var/obj/item/I = locate(href_list["read"]) in contents
|
||||
if(istype(I) && I.loc == src)
|
||||
usr.examinate(I)
|
||||
|
||||
/obj/structure/noticeboard/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
new /obj/item/stack/sheet/metal (loc, 1)
|
||||
qdel(src)
|
||||
|
||||
// Notice boards for the heads of staff (plus the qm)
|
||||
|
||||
/obj/structure/noticeboard/captain
|
||||
name = "Captain's Notice Board"
|
||||
desc = "Important notices from the Captain."
|
||||
new /obj/item/stack/sheet/metal (loc, 1)
|
||||
qdel(src)
|
||||
|
||||
// Notice boards for the heads of staff (plus the qm)
|
||||
|
||||
/obj/structure/noticeboard/captain
|
||||
name = "Captain's Notice Board"
|
||||
desc = "Important notices from the Captain."
|
||||
req_access = list(ACCESS_CAPTAIN)
|
||||
|
||||
/obj/structure/noticeboard/hop
|
||||
name = "Head of Personnel's Notice Board"
|
||||
desc = "Important notices from the Head of Personnel."
|
||||
|
||||
/obj/structure/noticeboard/hop
|
||||
name = "Head of Personnel's Notice Board"
|
||||
desc = "Important notices from the Head of Personnel."
|
||||
req_access = list(ACCESS_HOP)
|
||||
|
||||
/obj/structure/noticeboard/ce
|
||||
name = "Chief Engineer's Notice Board"
|
||||
desc = "Important notices from the Chief Engineer."
|
||||
|
||||
/obj/structure/noticeboard/ce
|
||||
name = "Chief Engineer's Notice Board"
|
||||
desc = "Important notices from the Chief Engineer."
|
||||
req_access = list(ACCESS_CE)
|
||||
|
||||
/obj/structure/noticeboard/hos
|
||||
name = "Head of Security's Notice Board"
|
||||
desc = "Important notices from the Head of Security."
|
||||
|
||||
/obj/structure/noticeboard/hos
|
||||
name = "Head of Security's Notice Board"
|
||||
desc = "Important notices from the Head of Security."
|
||||
req_access = list(ACCESS_HOS)
|
||||
|
||||
/obj/structure/noticeboard/cmo
|
||||
name = "Chief Medical Officer's Notice Board"
|
||||
desc = "Important notices from the Chief Medical Officer."
|
||||
|
||||
/obj/structure/noticeboard/cmo
|
||||
name = "Chief Medical Officer's Notice Board"
|
||||
desc = "Important notices from the Chief Medical Officer."
|
||||
req_access = list(ACCESS_CMO)
|
||||
|
||||
/obj/structure/noticeboard/rd
|
||||
name = "Research Director's Notice Board"
|
||||
desc = "Important notices from the Research Director."
|
||||
|
||||
/obj/structure/noticeboard/rd
|
||||
name = "Research Director's Notice Board"
|
||||
desc = "Important notices from the Research Director."
|
||||
req_access = list(ACCESS_RD)
|
||||
|
||||
/obj/structure/noticeboard/qm
|
||||
name = "Quartermaster's Notice Board"
|
||||
desc = "Important notices from the Quartermaster."
|
||||
|
||||
/obj/structure/noticeboard/qm
|
||||
name = "Quartermaster's Notice Board"
|
||||
desc = "Important notices from the Quartermaster."
|
||||
req_access = list(ACCESS_QM)
|
||||
|
||||
/obj/structure/noticeboard/staff
|
||||
name = "Staff Notice Board"
|
||||
desc = "Important notices from the heads of staff."
|
||||
|
||||
/obj/structure/noticeboard/staff
|
||||
name = "Staff Notice Board"
|
||||
desc = "Important notices from the heads of staff."
|
||||
req_access = list(ACCESS_HEADS)
|
||||
|
||||
@@ -1,202 +1,202 @@
|
||||
/*
|
||||
CONTAINS:
|
||||
SAFES
|
||||
FLOOR SAFES
|
||||
*/
|
||||
|
||||
//SAFES
|
||||
/obj/structure/safe
|
||||
name = "safe"
|
||||
desc = "A huge chunk of metal with a dial embedded in it. Fine print on the dial reads \"Scarborough Arms - 2 tumbler safe, guaranteed thermite resistant, explosion resistant, and assistant resistant.\""
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "safe"
|
||||
/*
|
||||
CONTAINS:
|
||||
SAFES
|
||||
FLOOR SAFES
|
||||
*/
|
||||
|
||||
//SAFES
|
||||
/obj/structure/safe
|
||||
name = "safe"
|
||||
desc = "A huge chunk of metal with a dial embedded in it. Fine print on the dial reads \"Scarborough Arms - 2 tumbler safe, guaranteed thermite resistant, explosion resistant, and assistant resistant.\""
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "safe"
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/open = FALSE //is the safe open?
|
||||
var/tumbler_1_pos //the tumbler position- from 0 to 72
|
||||
var/tumbler_1_open //the tumbler position to open at- 0 to 72
|
||||
var/tumbler_2_pos
|
||||
var/tumbler_2_open
|
||||
var/dial = 0 //where is the dial pointing?
|
||||
var/space = 0 //the combined w_class of everything in the safe
|
||||
var/maxspace = 24 //the maximum combined w_class of stuff in the safe
|
||||
|
||||
|
||||
/obj/structure/safe/New()
|
||||
..()
|
||||
tumbler_1_pos = rand(0, 71)
|
||||
tumbler_1_open = rand(0, 71)
|
||||
|
||||
tumbler_2_pos = rand(0, 71)
|
||||
tumbler_2_open = rand(0, 71)
|
||||
|
||||
|
||||
/obj/structure/safe/Initialize(mapload)
|
||||
..()
|
||||
|
||||
if(!mapload)
|
||||
return
|
||||
|
||||
for(var/obj/item/I in loc)
|
||||
if(space >= maxspace)
|
||||
return
|
||||
if(I.w_class + space <= maxspace)
|
||||
space += I.w_class
|
||||
I.loc = src
|
||||
|
||||
|
||||
/obj/structure/safe/proc/check_unlocked(mob/user, canhear)
|
||||
if(user && canhear)
|
||||
if(tumbler_1_pos == tumbler_1_open)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("tonk", "krunk", "plunk")] from [src].</span>")
|
||||
if(tumbler_2_pos == tumbler_2_open)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("tink", "krink", "plink")] from [src].</span>")
|
||||
if(tumbler_1_pos == tumbler_1_open && tumbler_2_pos == tumbler_2_open)
|
||||
if(user) visible_message("<i><b>[pick("Spring", "Sprang", "Sproing", "Clunk", "Krunk")]!</b></i>")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/structure/safe/proc/decrement(num)
|
||||
num -= 1
|
||||
if(num < 0)
|
||||
num = 71
|
||||
return num
|
||||
|
||||
|
||||
/obj/structure/safe/proc/increment(num)
|
||||
num += 1
|
||||
if(num > 71)
|
||||
num = 0
|
||||
return num
|
||||
|
||||
|
||||
/obj/structure/safe/update_icon()
|
||||
if(open)
|
||||
icon_state = "[initial(icon_state)]-open"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
|
||||
/obj/structure/safe/attack_hand(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = "<center>"
|
||||
dat += "<a href='?src=\ref[src];open=1'>[open ? "Close" : "Open"] [src]</a> | <a href='?src=\ref[src];decrement=1'>-</a> [dial * 5] <a href='?src=\ref[src];increment=1'>+</a>"
|
||||
if(open)
|
||||
dat += "<table>"
|
||||
for(var/i = contents.len, i>=1, i--)
|
||||
var/obj/item/P = contents[i]
|
||||
dat += "<tr><td><a href='?src=\ref[src];retrieve=\ref[P]'>[P.name]</a></td></tr>"
|
||||
dat += "</table></center>"
|
||||
user << browse("<html><head><title>[name]</title></head><body>[dat]</body></html>", "window=safe;size=350x300")
|
||||
|
||||
|
||||
/obj/structure/safe/Topic(href, href_list)
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
var/mob/living/carbon/human/user = usr
|
||||
|
||||
var/canhear = 0
|
||||
if(user.is_holding_item_of_type(/obj/item/clothing/neck/stethoscope))
|
||||
canhear = 1
|
||||
|
||||
if(href_list["open"])
|
||||
if(check_unlocked())
|
||||
to_chat(user, "<span class='notice'>You [open ? "close" : "open"] [src].</span>")
|
||||
open = !open
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't [open ? "close" : "open"] [src], the lock is engaged!</span>")
|
||||
return
|
||||
|
||||
if(href_list["decrement"])
|
||||
dial = decrement(dial)
|
||||
if(dial == tumbler_1_pos + 1 || dial == tumbler_1_pos - 71)
|
||||
tumbler_1_pos = decrement(tumbler_1_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("clack", "scrape", "clank")] from [src].</span>")
|
||||
if(tumbler_1_pos == tumbler_2_pos + 37 || tumbler_1_pos == tumbler_2_pos - 35)
|
||||
tumbler_2_pos = decrement(tumbler_2_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("click", "chink", "clink")] from [src].</span>")
|
||||
check_unlocked(user, canhear)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["increment"])
|
||||
dial = increment(dial)
|
||||
if(dial == tumbler_1_pos - 1 || dial == tumbler_1_pos + 71)
|
||||
tumbler_1_pos = increment(tumbler_1_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("clack", "scrape", "clank")] from [src].</span>")
|
||||
if(tumbler_1_pos == tumbler_2_pos - 37 || tumbler_1_pos == tumbler_2_pos + 35)
|
||||
tumbler_2_pos = increment(tumbler_2_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("click", "chink", "clink")] from [src].</span>")
|
||||
check_unlocked(user, canhear)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["retrieve"])
|
||||
user << browse("", "window=safe") // Close the menu
|
||||
|
||||
var/obj/item/P = locate(href_list["retrieve"]) in src
|
||||
if(open)
|
||||
if(P && in_range(src, user))
|
||||
user.put_in_hands(P)
|
||||
space -= P.w_class
|
||||
updateUsrDialog()
|
||||
|
||||
|
||||
/obj/structure/safe/attackby(obj/item/I, mob/user, params)
|
||||
if(open)
|
||||
. = 1 //no afterattack
|
||||
if(I.w_class + space <= maxspace)
|
||||
space += I.w_class
|
||||
if(!user.drop_item())
|
||||
to_chat(user, "<span class='warning'>\The [I] is stuck to your hand, you cannot put it in the safe!</span>")
|
||||
return
|
||||
I.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
|
||||
updateUsrDialog()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[I] won't fit in [src].</span>")
|
||||
return
|
||||
else if(istype(I, /obj/item/clothing/neck/stethoscope))
|
||||
to_chat(user, "<span class='warning'>Hold [I] in one of your hands while you manipulate the dial!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/safe/handle_atom_del(atom/A)
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/structure/safe/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
/obj/structure/safe/ex_act(severity, target)
|
||||
return
|
||||
|
||||
|
||||
//FLOOR SAFES
|
||||
/obj/structure/safe/floor
|
||||
name = "floor safe"
|
||||
icon_state = "floorsafe"
|
||||
var/tumbler_1_pos //the tumbler position- from 0 to 72
|
||||
var/tumbler_1_open //the tumbler position to open at- 0 to 72
|
||||
var/tumbler_2_pos
|
||||
var/tumbler_2_open
|
||||
var/dial = 0 //where is the dial pointing?
|
||||
var/space = 0 //the combined w_class of everything in the safe
|
||||
var/maxspace = 24 //the maximum combined w_class of stuff in the safe
|
||||
|
||||
|
||||
/obj/structure/safe/New()
|
||||
..()
|
||||
tumbler_1_pos = rand(0, 71)
|
||||
tumbler_1_open = rand(0, 71)
|
||||
|
||||
tumbler_2_pos = rand(0, 71)
|
||||
tumbler_2_open = rand(0, 71)
|
||||
|
||||
|
||||
/obj/structure/safe/Initialize(mapload)
|
||||
..()
|
||||
|
||||
if(!mapload)
|
||||
return
|
||||
|
||||
for(var/obj/item/I in loc)
|
||||
if(space >= maxspace)
|
||||
return
|
||||
if(I.w_class + space <= maxspace)
|
||||
space += I.w_class
|
||||
I.loc = src
|
||||
|
||||
|
||||
/obj/structure/safe/proc/check_unlocked(mob/user, canhear)
|
||||
if(user && canhear)
|
||||
if(tumbler_1_pos == tumbler_1_open)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("tonk", "krunk", "plunk")] from [src].</span>")
|
||||
if(tumbler_2_pos == tumbler_2_open)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("tink", "krink", "plink")] from [src].</span>")
|
||||
if(tumbler_1_pos == tumbler_1_open && tumbler_2_pos == tumbler_2_open)
|
||||
if(user) visible_message("<i><b>[pick("Spring", "Sprang", "Sproing", "Clunk", "Krunk")]!</b></i>")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/structure/safe/proc/decrement(num)
|
||||
num -= 1
|
||||
if(num < 0)
|
||||
num = 71
|
||||
return num
|
||||
|
||||
|
||||
/obj/structure/safe/proc/increment(num)
|
||||
num += 1
|
||||
if(num > 71)
|
||||
num = 0
|
||||
return num
|
||||
|
||||
|
||||
/obj/structure/safe/update_icon()
|
||||
if(open)
|
||||
icon_state = "[initial(icon_state)]-open"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
|
||||
/obj/structure/safe/attack_hand(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = "<center>"
|
||||
dat += "<a href='?src=\ref[src];open=1'>[open ? "Close" : "Open"] [src]</a> | <a href='?src=\ref[src];decrement=1'>-</a> [dial * 5] <a href='?src=\ref[src];increment=1'>+</a>"
|
||||
if(open)
|
||||
dat += "<table>"
|
||||
for(var/i = contents.len, i>=1, i--)
|
||||
var/obj/item/P = contents[i]
|
||||
dat += "<tr><td><a href='?src=\ref[src];retrieve=\ref[P]'>[P.name]</a></td></tr>"
|
||||
dat += "</table></center>"
|
||||
user << browse("<html><head><title>[name]</title></head><body>[dat]</body></html>", "window=safe;size=350x300")
|
||||
|
||||
|
||||
/obj/structure/safe/Topic(href, href_list)
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
var/mob/living/carbon/human/user = usr
|
||||
|
||||
var/canhear = 0
|
||||
if(user.is_holding_item_of_type(/obj/item/clothing/neck/stethoscope))
|
||||
canhear = 1
|
||||
|
||||
if(href_list["open"])
|
||||
if(check_unlocked())
|
||||
to_chat(user, "<span class='notice'>You [open ? "close" : "open"] [src].</span>")
|
||||
open = !open
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't [open ? "close" : "open"] [src], the lock is engaged!</span>")
|
||||
return
|
||||
|
||||
if(href_list["decrement"])
|
||||
dial = decrement(dial)
|
||||
if(dial == tumbler_1_pos + 1 || dial == tumbler_1_pos - 71)
|
||||
tumbler_1_pos = decrement(tumbler_1_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("clack", "scrape", "clank")] from [src].</span>")
|
||||
if(tumbler_1_pos == tumbler_2_pos + 37 || tumbler_1_pos == tumbler_2_pos - 35)
|
||||
tumbler_2_pos = decrement(tumbler_2_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("click", "chink", "clink")] from [src].</span>")
|
||||
check_unlocked(user, canhear)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["increment"])
|
||||
dial = increment(dial)
|
||||
if(dial == tumbler_1_pos - 1 || dial == tumbler_1_pos + 71)
|
||||
tumbler_1_pos = increment(tumbler_1_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("clack", "scrape", "clank")] from [src].</span>")
|
||||
if(tumbler_1_pos == tumbler_2_pos - 37 || tumbler_1_pos == tumbler_2_pos + 35)
|
||||
tumbler_2_pos = increment(tumbler_2_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("click", "chink", "clink")] from [src].</span>")
|
||||
check_unlocked(user, canhear)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["retrieve"])
|
||||
user << browse("", "window=safe") // Close the menu
|
||||
|
||||
var/obj/item/P = locate(href_list["retrieve"]) in src
|
||||
if(open)
|
||||
if(P && in_range(src, user))
|
||||
user.put_in_hands(P)
|
||||
space -= P.w_class
|
||||
updateUsrDialog()
|
||||
|
||||
|
||||
/obj/structure/safe/attackby(obj/item/I, mob/user, params)
|
||||
if(open)
|
||||
. = 1 //no afterattack
|
||||
if(I.w_class + space <= maxspace)
|
||||
space += I.w_class
|
||||
if(!user.drop_item())
|
||||
to_chat(user, "<span class='warning'>\The [I] is stuck to your hand, you cannot put it in the safe!</span>")
|
||||
return
|
||||
I.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
|
||||
updateUsrDialog()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[I] won't fit in [src].</span>")
|
||||
return
|
||||
else if(istype(I, /obj/item/clothing/neck/stethoscope))
|
||||
to_chat(user, "<span class='warning'>Hold [I] in one of your hands while you manipulate the dial!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/safe/handle_atom_del(atom/A)
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/structure/safe/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
/obj/structure/safe/ex_act(severity, target)
|
||||
return
|
||||
|
||||
|
||||
//FLOOR SAFES
|
||||
/obj/structure/safe/floor
|
||||
name = "floor safe"
|
||||
icon_state = "floorsafe"
|
||||
density = FALSE
|
||||
level = 1 //underfloor
|
||||
layer = LOW_OBJ_LAYER
|
||||
|
||||
|
||||
/obj/structure/safe/floor/Initialize(mapload)
|
||||
..()
|
||||
if(mapload)
|
||||
var/turf/T = loc
|
||||
hide(T.intact)
|
||||
|
||||
|
||||
/obj/structure/safe/floor/hide(var/intact)
|
||||
invisibility = intact ? INVISIBILITY_MAXIMUM : 0
|
||||
level = 1 //underfloor
|
||||
layer = LOW_OBJ_LAYER
|
||||
|
||||
|
||||
/obj/structure/safe/floor/Initialize(mapload)
|
||||
. = ..()
|
||||
if(mapload)
|
||||
var/turf/T = loc
|
||||
hide(T.intact)
|
||||
|
||||
|
||||
/obj/structure/safe/floor/hide(var/intact)
|
||||
invisibility = intact ? INVISIBILITY_MAXIMUM : 0
|
||||
|
||||
@@ -155,12 +155,9 @@
|
||||
|
||||
/obj/structure/statue/plasma/bullet_act(obj/item/projectile/Proj)
|
||||
var/burn = FALSE
|
||||
if(istype(Proj, /obj/item/projectile/beam))
|
||||
if(!(Proj.nodamage) && Proj.damage_type == BURN)
|
||||
PlasmaBurn(2500)
|
||||
burn = TRUE
|
||||
else if(istype(Proj, /obj/item/projectile/ion))
|
||||
PlasmaBurn(500)
|
||||
burn = TRUE
|
||||
if(burn)
|
||||
var/turf/T = get_turf(src)
|
||||
if(Proj.firer)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -147,8 +147,11 @@
|
||||
sleep(OPEN_DURATION + 2)
|
||||
pod_moving = 0
|
||||
if(!QDELETED(pod))
|
||||
var/datum/gas_mixture/floor_mixture = loc.return_air()
|
||||
floor_mixture.archive()
|
||||
pod.air_contents.archive()
|
||||
pod.air_contents.share(loc.return_air(), 1) //mix the pod's gas mixture with the tile it's on
|
||||
pod.air_contents.share(floor_mixture, 1) //mix the pod's gas mixture with the tile it's on
|
||||
air_update_turf()
|
||||
|
||||
/obj/structure/transit_tube/station/init_tube_dirs()
|
||||
switch(dir)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/transit_tube/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
var/datum/gas_mixture/air_contents = new()
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod/New(loc)
|
||||
..()
|
||||
air_contents.assert_gases("o2", "n2")
|
||||
/obj/structure/transit_tube_pod/Initialize()
|
||||
. = ..()
|
||||
air_contents.add_gases("o2", "n2")
|
||||
air_contents.gases["o2"][MOLES] = MOLES_O2STANDARD
|
||||
air_contents.gases["n2"][MOLES] = MOLES_N2STANDARD
|
||||
air_contents.temperature = T20C
|
||||
@@ -62,10 +62,14 @@
|
||||
AM.ex_act(severity, target)
|
||||
|
||||
/obj/structure/transit_tube_pod/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
/obj/structure/transit_tube_pod/container_resist(mob/living/user)
|
||||
if(!user.incapacitated())
|
||||
empty_pod()
|
||||
return
|
||||
if(!moving)
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
|
||||
@@ -274,16 +274,16 @@
|
||||
ismist = 0
|
||||
|
||||
|
||||
/obj/machinery/shower/Crossed(atom/movable/O)
|
||||
/obj/machinery/shower/Crossed(atom/movable/AM)
|
||||
..()
|
||||
if(on)
|
||||
if(isliving(O))
|
||||
var/mob/living/L = O
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(wash_mob(L)) //it's a carbon mob.
|
||||
var/mob/living/carbon/C = L
|
||||
C.slip(80,null,NO_SLIP_WHEN_WALKING)
|
||||
else
|
||||
wash_obj(O)
|
||||
else if(isobj(AM))
|
||||
wash_obj(AM)
|
||||
|
||||
|
||||
/obj/machinery/shower/proc/wash_obj(obj/O)
|
||||
@@ -374,12 +374,11 @@
|
||||
/obj/machinery/shower/process()
|
||||
if(on)
|
||||
wash_turf()
|
||||
for(var/atom/movable/G in loc)
|
||||
if(isliving(G))
|
||||
var/mob/living/L = G
|
||||
wash_mob(L)
|
||||
else
|
||||
wash_obj(G)
|
||||
for(var/atom/movable/AM in loc)
|
||||
if(isliving(AM))
|
||||
wash_mob(AM)
|
||||
else if(isobj(AM))
|
||||
wash_obj(AM)
|
||||
|
||||
/obj/machinery/shower/deconstruct(disassembled = TRUE)
|
||||
new /obj/item/stack/sheet/metal (loc, 3)
|
||||
@@ -535,6 +534,7 @@
|
||||
name = "puddle"
|
||||
desc = "A puddle used for washing one's hands and face."
|
||||
icon_state = "puddle"
|
||||
resistance_flags = UNACIDABLE
|
||||
|
||||
/obj/structure/sink/puddle/attack_hand(mob/M)
|
||||
icon_state = "puddle-splash"
|
||||
@@ -546,6 +546,10 @@
|
||||
. = ..()
|
||||
icon_state = "puddle"
|
||||
|
||||
/obj/structure/sink/puddle/deconstruct(disassembled = TRUE)
|
||||
qdel(src)
|
||||
|
||||
|
||||
|
||||
//Shower Curtains//
|
||||
//Defines used are pre-existing in layers.dm//
|
||||
|
||||
@@ -105,6 +105,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/window/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user