This commit is contained in:
Ghommie
2019-08-08 04:46:54 +02:00
329 changed files with 6488 additions and 3837 deletions
+9 -9
View File
@@ -40,7 +40,7 @@
#define BALLS_SACK_SIZE_DEF 8
#define BALLS_SACK_SIZE_MAX 40
#define CUM_RATE 5
#define CUM_RATE 0.035
#define CUM_RATE_MULT 1
#define CUM_EFFICIENCY 1//amount of nutrition required per life()
@@ -115,22 +115,22 @@
//xenobio console upgrade stuff
#define XENOBIO_UPGRADE_MONKEYS 1
#define XENOBIO_UPGRADE_SLIMEBASIC 2
#define XENOBIO_UPGRADE_SLIMEBASIC 2
#define XENOBIO_UPGRADE_SLIMEADV 4
//stamina stuff
#define STAMINA_SOFTCRIT 100 //softcrit for stamina damage. prevents standing up, prevents performing actions that cost stamina, etc, but doesn't force a rest or stop movement
#define STAMINA_CRIT 140 //crit for stamina damage. forces a rest, and stops movement until stamina goes back to stamina softcrit
#define STAMINA_SOFTCRIT_TRADITIONAL 0 //same as STAMINA_SOFTCRIT except for the more traditional health calculations
#define STAMINA_SOFTCRIT 100 //softcrit for stamina damage. prevents standing up, prevents performing actions that cost stamina, etc, but doesn't force a rest or stop movement
#define STAMINA_CRIT 140 //crit for stamina damage. forces a rest, and stops movement until stamina goes back to stamina softcrit
#define STAMINA_SOFTCRIT_TRADITIONAL 0 //same as STAMINA_SOFTCRIT except for the more traditional health calculations
#define STAMINA_CRIT_TRADITIONAL -40 //ditto, but for STAMINA_CRIT
#define MIN_MELEE_STAMCOST 1.25 //Minimum cost for swinging items around. Will be extra useful when stats and skills are introduced.
#define MIN_MELEE_STAMCOST 1.25 //Minimum cost for swinging items around. Will be extra useful when stats and skills are introduced.
#define CRAWLUNDER_DELAY 30 //Delay for crawling under a standing mob
//Citadel toggles because bitflag memes
#define MEDIHOUND_SLEEPER 1
#define EATING_NOISES 2
#define DIGESTION_NOISES 4
#define MEDIHOUND_SLEEPER (1<<0)
#define EATING_NOISES (1<<1)
#define DIGESTION_NOISES (1<<2)
#define TOGGLES_CITADEL (EATING_NOISES|DIGESTION_NOISES)
+2
View File
@@ -73,6 +73,8 @@
#define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next)
#define COMPONENT_BLOCK_REACH 1
#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I)
#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin)
#define COMPONENT_BLOCK_TELEPORT 1
/////////////////
#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost)
#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user)
+1 -1
View File
@@ -7,7 +7,7 @@
//for convenience
#define ENABLE_BITFIELD(variable, flag) (variable |= (flag))
#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag))
#define CHECK_BITFIELD(variable, flag) (variable & flag)
#define CHECK_BITFIELD(variable, flag) (variable & (flag))
#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag))
GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768))
+4
View File
@@ -28,6 +28,7 @@
#define ITEM_SLOT_POCKET (1<<11) // this is to allow items with a w_class of WEIGHT_CLASS_NORMAL or WEIGHT_CLASS_BULKY to fit in pockets.
#define ITEM_SLOT_DENYPOCKET (1<<12) // this is to deny items with a w_class of WEIGHT_CLASS_SMALL or WEIGHT_CLASS_TINY to fit in pockets.
#define ITEM_SLOT_NECK (1<<13)
#define ITEM_SLOT_SUITSTORE (1<<14)
//SLOTS
#define SLOT_BACK 1
@@ -52,6 +53,7 @@
#define SLOT_LEGCUFFED 19
#define SLOT_GENERC_DEXTROUS_STORAGE 20
#define SLOTS_AMT 20 // Keep this up to date!
//I hate that this has to exist
@@ -84,6 +86,8 @@
. = ITEM_SLOT_ICLOTHING
if(SLOT_L_STORE, SLOT_R_STORE)
. = ITEM_SLOT_POCKET
if(SLOT_S_STORE)
. = ITEM_SLOT_SUITSTORE
//Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses.
+10
View File
@@ -0,0 +1,10 @@
//Martial arts defines
#define MARTIALART_BOXING "boxing"
#define MARTIALART_WRESTLING "wrestling"
#define MARTIALART_SLEEPINGCARP "sleeping carp"
#define MARTIALART_PSYCHOBRAWL "psychotic brawling"
#define MARTIALART_MUSHPUNCH "mushroom punch"
#define MARTIALART_KRAVMAGA "krav maga"
#define MARTIALART_CQC "CQC"
#define MARTIALART_PLASMAFIST "plasma fist"
+7
View File
@@ -455,6 +455,13 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define SUMMON_GUNS "guns"
#define SUMMON_MAGIC "magic"
#define TELEPORT_CHANNEL_BLUESPACE "bluespace" //Classic bluespace teleportation, requires a sender but no receiver
#define TELEPORT_CHANNEL_QUANTUM "quantum" //Quantum-based teleportation, requires both sender and receiver, but is free from normal disruption
#define TELEPORT_CHANNEL_WORMHOLE "wormhole" //Wormhole teleportation, is not disrupted by bluespace fluctuations but tends to be very random or unsafe
#define TELEPORT_CHANNEL_MAGIC "magic" //Magic teleportation, does whatever it wants (unless there's antimagic)
#define TELEPORT_CHANNEL_CULT "cult" //Cult teleportation, does whatever it wants (unless there's holiness)
#define TELEPORT_CHANNEL_FREE "free" //Anything else
//Run the world with this parameter to enable a single run though of the game setup and tear down process with unit tests in between
#define TEST_RUN_PARAMETER "test-run"
//Force the log directory to be something specific in the data/logs folder
+50
View File
@@ -1,5 +1,55 @@
// Radios use a large variety of predefined frequencies.
//say based modes like binary are in living/say.dm
#define RADIO_CHANNEL_COMMON "Common"
#define RADIO_KEY_COMMON ";"
#define RADIO_CHANNEL_SECURITY "Security"
#define RADIO_KEY_SECURITY "s"
#define RADIO_TOKEN_SECURITY ":s"
#define RADIO_CHANNEL_ENGINEERING "Engineering"
#define RADIO_KEY_ENGINEERING "e"
#define RADIO_TOKEN_ENGINEERING ":e"
#define RADIO_CHANNEL_COMMAND "Command"
#define RADIO_KEY_COMMAND "c"
#define RADIO_TOKEN_COMMAND ":c"
#define RADIO_CHANNEL_SCIENCE "Science"
#define RADIO_KEY_SCIENCE "n"
#define RADIO_TOKEN_SCIENCE ":n"
#define RADIO_CHANNEL_MEDICAL "Medical"
#define RADIO_KEY_MEDICAL "m"
#define RADIO_TOKEN_MEDICAL ":m"
#define RADIO_CHANNEL_SUPPLY "Supply"
#define RADIO_KEY_SUPPLY "u"
#define RADIO_TOKEN_SUPPLY ":u"
#define RADIO_CHANNEL_SERVICE "Service"
#define RADIO_KEY_SERVICE "v"
#define RADIO_TOKEN_SERVICE ":v"
#define RADIO_CHANNEL_AI_PRIVATE "AI Private"
#define RADIO_KEY_AI_PRIVATE "o"
#define RADIO_TOKEN_AI_PRIVATE ":o"
#define RADIO_CHANNEL_SYNDICATE "Syndicate"
#define RADIO_KEY_SYNDICATE "t"
#define RADIO_TOKEN_SYNDICATE ":t"
#define RADIO_CHANNEL_CENTCOM "CentCom"
#define RADIO_KEY_CENTCOM "y"
#define RADIO_TOKEN_CENTCOM ":y"
#define RADIO_CHANNEL_CTF_RED "Red Team"
#define RADIO_CHANNEL_CTF_BLUE "Blue Team"
#define MIN_FREE_FREQ 1201 // -------------------------------------------------
// Frequencies are always odd numbers and range from 1201 to 1599.
+26
View File
@@ -6,17 +6,43 @@
//Message modes. Each one defines a radio channel, more or less.
#define MODE_HEADSET "headset"
#define MODE_ROBOT "robot"
#define MODE_R_HAND "right hand"
#define MODE_KEY_R_HAND "r"
#define MODE_L_HAND "left hand"
#define MODE_KEY_L_HAND "l"
#define MODE_INTERCOM "intercom"
#define MODE_KEY_INTERCOM "i"
#define MODE_BINARY "binary"
#define MODE_KEY_BINARY "b"
#define MODE_TOKEN_BINARY ":b"
#define MODE_WHISPER "whisper"
#define MODE_WHISPER_CRIT "whispercrit"
#define MODE_DEPARTMENT "department"
#define MODE_KEY_DEPARTMENT "h"
#define MODE_TOKEN_DEPARTMENT ":h"
#define MODE_ADMIN "admin"
#define MODE_KEY_ADMIN "p"
#define MODE_DEADMIN "deadmin"
#define MODE_KEY_DEADMIN "d"
#define MODE_ALIEN "alientalk"
#define MODE_HOLOPAD "holopad"
#define MODE_CHANGELING "changeling"
#define MODE_KEY_CHANGELING "g"
#define MODE_TOKEN_CHANGELING ":g"
#define MODE_VOCALCORDS "cords"
#define MODE_KEY_VOCALCORDS "x"
#define MODE_MONKEY "monkeyhive"
//Spans. Robot speech, italics, etc. Applied in compose_message().
+1
View File
@@ -128,6 +128,7 @@
#define TRAIT_HEAVY_SLEEPER "heavy_sleeper"
#define TRAIT_NIGHT_VISION "night_vision"
#define TRAIT_LIGHT_STEP "light_step"
#define TRAIT_SILENT_STEP "silent_step"
#define TRAIT_SPEEDY_STEP "speedy_step"
#define TRAIT_SPIRITUAL "spiritual"
#define TRAIT_VORACIOUS "voracious"
+18 -11
View File
@@ -494,6 +494,7 @@
else
to_chat(owner, "<span class='cultitalic'>Your hands are full!</span>")
//MGS Box
/datum/action/item_action/agent_box
name = "Deploy Box"
desc = "Find inner peace, here, in the box."
@@ -502,21 +503,27 @@
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "deploy_box"
var/cooldown = 0
var/obj/structure/closet/cardboard/agent/box
var/boxtype = /obj/structure/closet/cardboard/agent
//Handles open and closing the box
/datum/action/item_action/agent_box/Trigger()
if(!..())
. = ..()
if(!.)
return FALSE
if(QDELETED(box))
if(cooldown < world.time - 100)
box = new(owner.drop_location())
owner.forceMove(box)
cooldown = world.time
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
else
owner.forceMove(box.drop_location())
if(istype(owner.loc, /obj/structure/closet/cardboard/agent))
var/obj/structure/closet/cardboard/agent/box = owner.loc
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
box.open()
return
//Box closing from here on out.
if(!isturf(owner.loc)) //Don't let the player use this to escape mechs/welded closets.
to_chat(owner, "<span class = 'notice'>You need more space to activate this implant.</span>")
return
if(cooldown < world.time - 100)
var/box = new boxtype(owner.drop_location())
owner.forceMove(box)
cooldown = world.time
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
QDEL_NULL(box)
//Preset for spells
/datum/action/spell_action
+20 -17
View File
@@ -14,15 +14,18 @@
var/turf/open/T = get_turf(parent)
if(!istype(T))
return
var/mob/living/LM = parent
var/v = volume
var/e = e_range
if(!T.footstep || LM.buckled || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING))
if (LM.lying && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying
if (LM.lying && !LM.buckled && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v)
return
if(HAS_TRAIT(LM, TRAIT_SILENT_STEP))
return
if(iscarbon(LM))
var/mob/living/carbon/C = LM
if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG))
@@ -31,18 +34,18 @@
v /= 2
e -= 5
steps++
if(steps >= 3)
steps = 0
else
return
if(prob(80) && !LM.has_gravity(T)) // don't need to step as often when you hop around
return
//begin playsound shenanigans//
//for barefooted non-clawed mobs like monkeys
if(isbarefoot(LM))
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
@@ -50,19 +53,19 @@
TRUE,
GLOB.barefootstep[T.barefootstep][3] + e)
return
//for xenomorphs, dogs, and other clawed mobs
if(isclawfoot(LM))
if(isalienadult(LM)) //xenos are stealthy and get quieter footsteps
v /= 3
e -= 5
playsound(T, pick(GLOB.clawfootstep[T.clawfootstep][1]),
GLOB.clawfootstep[T.clawfootstep][2] * v,
TRUE,
GLOB.clawfootstep[T.clawfootstep][3] + e)
return
//for megafauna and other large and imtimidating mobs such as the bloodminer
if(isheavyfoot(LM))
playsound(T, pick(GLOB.heavyfootstep[T.heavyfootstep][1]),
@@ -70,12 +73,12 @@
TRUE,
GLOB.heavyfootstep[T.heavyfootstep][3] + e)
return
//for slimes
if(isslime(LM))
if(isslime(LM))
playsound(T, 'sound/effects/footstep/slime1.ogg', 15 * v)
return
//for (simple) humanoid mobs (clowns, russians, pirates, etc.)
if(isshoefoot(LM))
if(!ishuman(LM))
@@ -87,17 +90,17 @@
if(ishuman(LM)) //for proper humans, they're special
var/mob/living/carbon/human/H = LM
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET))
if (H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle") //are we a naga or tentacle taur creature
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v)
return
if(H.shoes || feetCover) //are we wearing shoes
playsound(T, pick(GLOB.footstep[T.footstep][1]),
GLOB.footstep[T.footstep][2] * v,
TRUE,
GLOB.footstep[T.footstep][3] + e)
if((!H.shoes && !feetCover)) //are we NOT wearing shoes
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
GLOB.barefootstep[T.barefootstep][2] * v,
+46 -22
View File
@@ -5,11 +5,19 @@
// effectout: effect to show right after teleportation
// asoundin: soundfile to play before teleportation
// asoundout: soundfile to play after teleportation
// force_teleport: if false, teleport will use Move() proc (dense objects will prevent teleportation)
// no_effects: disable the default effectin/effectout of sparks
/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, force_teleport=TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE)
// forceMove: if false, teleport will use Move() proc (dense objects will prevent teleportation)
// forced: whether or not to ignore no_teleport
/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, forceMove = TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, forced = FALSE)
// teleporting most effects just deletes them
if(iseffect(teleatom) && !istype(teleatom, /obj/effect/dummy/chameleon))
var/static/list/delete_atoms = typecacheof(list(
/obj/effect,
)) - typecacheof(list(
/obj/effect/dummy/chameleon,
/obj/effect/wisp,
/obj/effect/mob_spawn
))
if(delete_atoms[teleatom.type])
qdel(teleatom)
return FALSE
@@ -17,25 +25,37 @@
// if the precision is not specified, default to 0, but apply BoH penalties
if (isnull(precision))
precision = 0
if(istype(teleatom, /obj/item/storage/backpack/holding))
precision = rand(1,100)
var/static/list/bag_cache = typecacheof(/obj/item/storage/backpack/holding)
var/list/bagholding = typecache_filter_list(teleatom.GetAllContents(), bag_cache)
if(bagholding.len)
precision = max(rand(1,100)*bagholding.len,100)
if(isliving(teleatom))
var/mob/living/MM = teleatom
to_chat(MM, "<span class='warning'>The bluespace interface on your bag of holding interferes with the teleport!</span>")
switch(channel)
if(TELEPORT_CHANNEL_BLUESPACE)
if(istype(teleatom, /obj/item/storage/backpack/holding))
precision = rand(1,100)
// if effects are not specified and not explicitly disabled, sparks
if ((!effectin || !effectout) && !no_effects)
var/datum/effect_system/spark_spread/sparks = new
sparks.set_up(5, 1, teleatom)
if (!effectin)
effectin = sparks
if (!effectout)
effectout = sparks
var/static/list/bag_cache = typecacheof(/obj/item/storage/backpack/holding)
var/list/bagholding = typecache_filter_list(teleatom.GetAllContents(), bag_cache)
if(bagholding.len)
precision = max(rand(1,100)*bagholding.len,100)
if(isliving(teleatom))
var/mob/living/MM = teleatom
to_chat(MM, "<span class='warning'>The bluespace interface on your bag of holding interferes with the teleport!</span>")
// if effects are not specified and not explicitly disabled, sparks
if ((!effectin || !effectout) && !no_effects)
var/datum/effect_system/spark_spread/sparks = new
sparks.set_up(5, 1, teleatom)
if (!effectin)
effectin = sparks
if (!effectout)
effectout = sparks
if(TELEPORT_CHANNEL_QUANTUM)
// if effects are not specified and not explicitly disabled, rainbow sparks
if ((!effectin || !effectout) && !no_effects)
var/datum/effect_system/spark_spread/quantum/sparks = new
sparks.set_up(5, 1, teleatom)
if (!effectin)
effectin = sparks
if (!effectout)
effectout = sparks
// perform the teleport
var/turf/curturf = get_turf(teleatom)
@@ -45,11 +65,15 @@
return FALSE
var/area/A = get_area(curturf)
if(A.noteleport)
var/area/B = get_area(destturf)
if(!forced && (A.noteleport || B.noteleport))
return FALSE
if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf))
return FALSE
tele_play_specials(teleatom, curturf, effectin, asoundin)
var/success = force_teleport ? teleatom.forceMove(destturf) : teleatom.Move(destturf)
var/success = forceMove ? teleatom.forceMove(destturf) : teleatom.Move(destturf)
if (success)
log_game("[key_name(teleatom)] has teleported from [loc_name(curturf)] to [loc_name(destturf)]")
tele_play_specials(teleatom, destturf, effectout, asoundout)
+1
View File
@@ -2,6 +2,7 @@
var/name = "Martial Art"
var/streak = ""
var/max_streak_length = 6
var/id = "" //ID, used by mind/has_martialartcode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proc
var/current_target
var/datum/martial_art/base // The permanent style. This will be null unless the martial art is temporary
var/deflection_chance = 0 //Chance to deflect projectiles
+1
View File
@@ -1,5 +1,6 @@
/datum/martial_art/boxing
name = "Boxing"
id = MARTIALART_BOXING
/datum/martial_art/boxing/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
to_chat(A, "<span class='warning'>Can't disarm while boxing!</span>")
+1
View File
@@ -6,6 +6,7 @@
/datum/martial_art/cqc
name = "CQC"
id = MARTIALART_CQC
help_verb = /mob/living/carbon/human/proc/CQC_help
block_chance = 75
var/just_a_cook = FALSE
+3 -2
View File
@@ -1,5 +1,6 @@
/datum/martial_art/krav_maga
name = "Krav Maga"
id = MARTIALART_KRAVMAGA
var/datum/action/neck_chop/neckchop = new/datum/action/neck_chop()
var/datum/action/leg_sweep/legsweep = new/datum/action/leg_sweep()
var/datum/action/lung_punch/lungpunch = new/datum/action/lung_punch()
@@ -92,7 +93,7 @@
"<span class='userdanger'>[A] leg sweeps you!</span>")
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
D.apply_damage(5, BRUTE)
D.Knockdown(40, override_hardstun = 0.01, 25)
D.Knockdown(40, override_hardstun = 0.01, override_stamdmg = 25)
log_combat(A, D, "leg sweeped")
return 1
@@ -196,7 +197,7 @@
name = "combat gloves plus"
desc = "These tactical gloves are fireproof and shock resistant, and using nanochip technology it teaches you the powers of krav maga."
icon_state = "combat"
item_state = "blackglovesplus"
item_state = "blackgloves"
siemens_coefficient = 0
permeability_coefficient = 0.05
strip_delay = 80
+1
View File
@@ -1,5 +1,6 @@
/datum/martial_art/mushpunch
name = "Mushroom Punch"
id = MARTIALART_MUSHPUNCH
/datum/martial_art/mushpunch/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
var/atk_verb
+1
View File
@@ -4,6 +4,7 @@
/datum/martial_art/plasma_fist
name = "Plasma Fist"
id = MARTIALART_PLASMAFIST
help_verb = /mob/living/carbon/human/proc/plasma_fist_help
+1
View File
@@ -1,5 +1,6 @@
/datum/martial_art/psychotic_brawling
name = "Psychotic Brawling"
id = MARTIALART_PSYCHOBRAWL
/datum/martial_art/psychotic_brawling/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
return psycho_attack(A,D)
+1
View File
@@ -6,6 +6,7 @@
/datum/martial_art/the_sleeping_carp
name = "The Sleeping Carp"
id = MARTIALART_SLEEPINGCARP
deflection_chance = 100
reroute_deflection = TRUE
no_guns = TRUE
+1
View File
@@ -10,6 +10,7 @@
/datum/martial_art/wrestling
name = "Wrestling"
id = MARTIALART_WRESTLING
var/datum/action/slam/slam = new/datum/action/slam()
var/datum/action/throw_wrassle/throw_wrassle = new/datum/action/throw_wrassle()
var/datum/action/kick/kick = new/datum/action/kick()
+9 -1
View File
@@ -64,6 +64,8 @@
var/force_escaped = FALSE // Set by Into The Sunset command of the shuttle manipulator
var/list/learned_recipes //List of learned recipe TYPES.
/datum/mind/New(var/key)
src.key = key
soulOwner = src
@@ -130,7 +132,8 @@
L.update_arousal_hud() //Removes the old icon
/datum/mind/proc/store_memory(new_text)
memory += "[new_text]<BR>"
if((length(memory) + length(new_text)) <= MAX_MESSAGE_LEN)
memory += "[new_text]<BR>"
/datum/mind/proc/wipe_memory()
memory = null
@@ -778,6 +781,11 @@
mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
mind.active = 1 //indicates that the mind is currently synced with a client
/datum/mind/proc/has_martialart(var/string)
if(martial_art && martial_art.id == string)
return martial_art
return FALSE
/mob/dead/new_player/sync_mind()
return
+2 -4
View File
@@ -63,16 +63,14 @@
/datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.resize = 0.8
owner.update_transform()
owner.transform = owner.transform.Scale(1, 0.8)
owner.pass_flags |= PASSTABLE
owner.visible_message("<span class='danger'>[owner] suddenly shrinks!</span>", "<span class='notice'>Everything around you seems to grow..</span>")
/datum/mutation/human/dwarfism/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.resize = 1.25
owner.update_transform()
owner.transform = owner.transform.Scale(1, 1.25)
owner.pass_flags &= ~PASSTABLE
owner.visible_message("<span class='danger'>[owner] suddenly grows!</span>", "<span class='notice'>Everything around you seems to shrink..</span>")
+6
View File
@@ -310,3 +310,9 @@
suffix = "spacehermit.dmm"
name = "Space Hermit"
description = "A late awakening cryo pod in a crashed escape pod wakes up to find what befell of his fellow survivors. Contains all the necessary resources to actually make it out alive. Good luck."
/datum/map_template/ruin/space/advancedlab
id = "advancedlab"
suffix = "advancedlab.dmm"
name = "Abductor Replication Lab"
description = "Some scientists tried and almost succeeded to recreate abductor tools. Somewhat slower and a bit less modern than their originals, these tools are the best you can get if you aren't an alien."
+3 -3
View File
@@ -11,7 +11,7 @@
/datum/saymode/changeling
key = "g"
key = MODE_KEY_CHANGELING
mode = MODE_CHANGELING
/datum/saymode/changeling/handle_message(mob/living/user, message, datum/language/language)
@@ -73,7 +73,7 @@
/datum/saymode/vocalcords
key = "x"
key = MODE_KEY_VOCALCORDS
mode = MODE_VOCALCORDS
/datum/saymode/vocalcords/handle_message(mob/living/user, message, datum/language/language)
@@ -87,7 +87,7 @@
/datum/saymode/binary //everything that uses .b (silicons, drones, blobbernauts/spores, swarmers)
key = "b"
key = MODE_KEY_BINARY
mode = MODE_BINARY
/datum/saymode/binary/handle_message(mob/living/user, message, datum/language/language)
+3
View File
@@ -231,6 +231,9 @@
// Same for anyone with an abductor multitool.
else if(user.is_holding_item_of_type(/obj/item/multitool/abductor))
reveal_wires = TRUE
// and advanced multitool
else if(user.is_holding_item_of_type(/obj/item/multitool/advanced))
reveal_wires = TRUE
// Station blueprints do that too, but only if the wires are not randomized.
else if(user.is_holding_item_of_type(/obj/item/areaeditor/blueprints) && !randomize)
+5
View File
@@ -467,3 +467,8 @@
/area/ruin/space/has_grav/powered/ancient_shuttle
name = "Ancient Shuttle"
icon_state = "yellow"
// Abductor Replication Lab
/area/ruin/space/has_grav/powered/advancedlab
name = "Abductor Replication Lab"
icon_state = "yellow"
+26 -26
View File
@@ -91,35 +91,35 @@ GLOBAL_LIST_EMPTY(all_radios)
// use in maps, such as in intercoms.
GLOBAL_LIST_INIT(radiochannels, list(
"Common" = FREQ_COMMON,
"Science" = FREQ_SCIENCE,
"Command" = FREQ_COMMAND,
"Medical" = FREQ_MEDICAL,
"Engineering" = FREQ_ENGINEERING,
"Security" = FREQ_SECURITY,
"CentCom" = FREQ_CENTCOM,
"Syndicate" = FREQ_SYNDICATE,
"Supply" = FREQ_SUPPLY,
"Service" = FREQ_SERVICE,
"AI Private" = FREQ_AI_PRIVATE,
"Red Team" = FREQ_CTF_RED,
"Blue Team" = FREQ_CTF_BLUE
RADIO_CHANNEL_COMMON = FREQ_COMMON,
RADIO_CHANNEL_SCIENCE = FREQ_SCIENCE,
RADIO_CHANNEL_COMMAND = FREQ_COMMAND,
RADIO_CHANNEL_MEDICAL = FREQ_MEDICAL,
RADIO_CHANNEL_ENGINEERING = FREQ_ENGINEERING,
RADIO_CHANNEL_SECURITY = FREQ_SECURITY,
RADIO_CHANNEL_CENTCOM = FREQ_CENTCOM,
RADIO_CHANNEL_SYNDICATE = FREQ_SYNDICATE,
RADIO_CHANNEL_SUPPLY = FREQ_SUPPLY,
RADIO_CHANNEL_SERVICE = FREQ_SERVICE,
RADIO_CHANNEL_AI_PRIVATE = FREQ_AI_PRIVATE,
RADIO_CHANNEL_CTF_RED = FREQ_CTF_RED,
RADIO_CHANNEL_CTF_BLUE = FREQ_CTF_BLUE
))
GLOBAL_LIST_INIT(reverseradiochannels, list(
"[FREQ_COMMON]" = "Common",
"[FREQ_SCIENCE]" = "Science",
"[FREQ_COMMAND]" = "Command",
"[FREQ_MEDICAL]" = "Medical",
"[FREQ_ENGINEERING]" = "Engineering",
"[FREQ_SECURITY]" = "Security",
"[FREQ_CENTCOM]" = "CentCom",
"[FREQ_SYNDICATE]" = "Syndicate",
"[FREQ_SUPPLY]" = "Supply",
"[FREQ_SERVICE]" = "Service",
"[FREQ_AI_PRIVATE]" = "AI Private",
"[FREQ_CTF_RED]" = "Red Team",
"[FREQ_CTF_BLUE]" = "Blue Team"
"[FREQ_COMMON]" = RADIO_CHANNEL_COMMON,
"[FREQ_SCIENCE]" = RADIO_CHANNEL_SCIENCE,
"[FREQ_COMMAND]" = RADIO_CHANNEL_COMMAND,
"[FREQ_MEDICAL]" = RADIO_CHANNEL_MEDICAL,
"[FREQ_ENGINEERING]" = RADIO_CHANNEL_ENGINEERING,
"[FREQ_SECURITY]" = RADIO_CHANNEL_SECURITY,
"[FREQ_CENTCOM]" = RADIO_CHANNEL_CENTCOM,
"[FREQ_SYNDICATE]" = RADIO_CHANNEL_SYNDICATE,
"[FREQ_SUPPLY]" = RADIO_CHANNEL_SUPPLY,
"[FREQ_SERVICE]" = RADIO_CHANNEL_SERVICE,
"[FREQ_AI_PRIVATE]" = RADIO_CHANNEL_AI_PRIVATE,
"[FREQ_CTF_RED]" = RADIO_CHANNEL_CTF_RED,
"[FREQ_CTF_BLUE]" = RADIO_CHANNEL_CTF_BLUE
))
/datum/radio_frequency
+2 -2
View File
@@ -52,7 +52,7 @@ Credit where due:
if(!istype(M))
return FALSE
if(M.mind)
if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain")))
if(M.mind.assigned_role in list("Captain", "Chaplain"))
return FALSE
if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to))
return FALSE
@@ -275,7 +275,7 @@ Credit where due:
gloves = /obj/item/clothing/gloves/color/yellow
belt = /obj/item/storage/belt/utility/servant
backpack_contents = list(/obj/item/storage/box/engineer = 1, \
/obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1, /obj/item/reagent_containers/food/drinks/holyoil = 1)
/obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1, /obj/item/reagent_containers/food/drinks/bottle/holyoil = 1)
id = /obj/item/pda
var/plasmaman //We use this to determine if we should activate internals in post_equip()
+1 -1
View File
@@ -16,7 +16,7 @@
if(!istype(M))
return FALSE
if(M.mind)
if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain")))
if(M.mind.assigned_role in list("Captain", "Chaplain"))
return FALSE
if(specific_cult && specific_cult.is_sacrifice_target(M.mind))
return FALSE
+7 -7
View File
@@ -53,7 +53,7 @@
name = "the chief engineer's advanced magnetic boots."
targetitem = /obj/item/clothing/shoes/magboots/advance
difficulty = 5
excludefromjob = list("Chief Engineer")
excludefromjob = list("Chief Engineer", "Station Engineer", "Atmospheric Technician")
/datum/objective_item/steal/capmedal
name = "the medal of captaincy."
@@ -62,10 +62,10 @@
excludefromjob = list("Captain")
/datum/objective_item/steal/hypo
name = "the hypospray."
name = "the Chief Medical Officer's MKII hypospray."
targetitem = /obj/item/hypospray/mkii/CMO //CITADEL EDIT, changing theft objective for the Hypo MK II
difficulty = 5
excludefromjob = list("Chief Medical Officer")
excludefromjob = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Virologist", "Geneticist")
/datum/objective_item/steal/nukedisc
name = "the nuclear authentication disk."
@@ -83,10 +83,10 @@
excludefromjob = list("Head of Security", "Warden")
/datum/objective_item/steal/reactive
name = "the reactive teleport armor."
name = "a reactive teleport armor."
targetitem = /obj/item/clothing/suit/armor/reactive
difficulty = 5
excludefromjob = list("Research Director")
excludefromjob = list("Research Director","Scientist", "Roboticist")
/datum/objective_item/steal/documents
name = "any set of secret documents of any organization."
@@ -143,7 +143,7 @@
name = "the station blueprints."
targetitem = /obj/item/areaeditor/blueprints
difficulty = 10
excludefromjob = list("Chief Engineer")
excludefromjob = list("Chief Engineer", "Station Engineer", "Atmospheric Technician")
altitems = list(/obj/item/photo)
/datum/objective_item/steal/blueprints/check_special_completion(obj/item/I)
@@ -159,7 +159,7 @@
name = "an unused sample of slime extract."
targetitem = /obj/item/slime_extract
difficulty = 3
excludefromjob = list("Research Director","Scientist")
excludefromjob = list("Research Director","Scientist", "Roboticist")
/datum/objective_item/steal/slime/check_special_completion(obj/item/slime_extract/E)
if(E.Uses > 0)
+1 -1
View File
@@ -6,7 +6,7 @@
var/siphoning = FALSE
var/next_warning = 0
var/obj/item/radio/radio
var/radio_channel = "Common"
var/radio_channel = RADIO_CHANNEL_COMMON
var/minimum_time_between_warnings = 400
/obj/machinery/computer/bank_machine/Initialize()
+1 -1
View File
@@ -31,7 +31,7 @@
var/internal_radio = TRUE
var/obj/item/radio/radio
var/radio_key = /obj/item/encryptionkey/headset_med
var/radio_channel = "Medical"
var/radio_channel = RADIO_CHANNEL_MEDICAL
var/obj/effect/countdown/clonepod/countdown
@@ -361,14 +361,16 @@
return
button_icon_state = "warp_down"
owner.update_action_buttons()
QDEL_NULL(warping)
if(!do_teleport(user, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE))
to_chat(user, "<span class='bold sevtug_small'>Warp Failed. Something deflected our attempt to warp to [AR].</span>")
return
T.visible_message("<span class='warning'>[user] warps in!</span>")
playsound(user, 'sound/magic/magic_missile.ogg', 50, TRUE)
playsound(T, 'sound/magic/magic_missile.ogg', 50, TRUE)
user.forceMove(get_turf(T))
user.setDir(SOUTH)
flash_color(user, flash_color = "#AF0AAF", flash_time = 5)
R.remove_eye_control(user)
QDEL_NULL(warping)
/datum/action/innate/servant_warp/proc/is_canceled()
return !cancel
+2 -2
View File
@@ -30,7 +30,7 @@
obj_flags |= EMAGGED
/obj/machinery/gulag_item_reclaimer/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/card/id/prisoner))
if(istype(I, /obj/item/card/id))
if(!inserted_id)
if(!user.transferItemToLoc(I, src))
return
@@ -83,7 +83,7 @@
usr.put_in_hands(inserted_id)
inserted_id = null
else
var/obj/item/I = usr.is_holding_item_of_type(/obj/item/card/id/prisoner)
var/obj/item/I = usr.is_holding_item_of_type(/obj/item/card/id)
if(I)
if(!usr.transferItemToLoc(I, src))
return
+1 -1
View File
@@ -63,7 +63,7 @@
if(91 to INFINITY)
filling_overlay.icon_state = "reagent100"
filling_overlay.color = list("#0000", "#0000", "#0000", "#000f", mix_color_from_reagents(beaker.reagents.reagent_list))
filling_overlay.color = mix_color_from_reagents(beaker.reagents.reagent_list)
add_overlay(filling_overlay)
/obj/machinery/iv_drip/MouseDrop(mob/living/target)
+3 -3
View File
@@ -127,7 +127,7 @@
if(first_inner)
log_msg += "empty"
log_msg += ")"
do_teleport(ROI, dest, no_effects = !first)
do_teleport(ROI, dest, no_effects = !first, channel = TELEPORT_CHANNEL_BLUESPACE)
first = FALSE
if (first)
@@ -206,7 +206,7 @@
/obj/item/storage/briefcase/launchpad/PopulateContents()
new /obj/item/pen(src)
new /obj/item/launchpad_remote(src, pad)
new /obj/item/launchpad_remote(src, pad)
/obj/item/storage/briefcase/launchpad/attack_self(mob/user)
if(!isturf(user.loc)) //no setting up in a locker
@@ -227,7 +227,7 @@
L.pad = src.pad
to_chat(user, "<span class='notice'>You link [pad] to [L].</span>")
else
return ..()
return ..()
/obj/item/launchpad_remote
name = "folder"
+36 -21
View File
@@ -36,7 +36,7 @@
to_chat(user, "<span class='notice'>The panel is <i>screwed</i> in, obstructing the linking device.</span>")
else
to_chat(user, "<span class='notice'>The <i>linking</i> device is now able to be <i>scanned<i> with a multitool.</span>")
/obj/machinery/quantumpad/RefreshParts()
var/E = 0
for(var/obj/item/stock_parts/capacitor/C in component_parts)
@@ -74,15 +74,26 @@
to_chat(user, "<span class='warning'>There is no quantum pad data saved in [I]'s buffer!</span>")
return TRUE
else if(istype(I, /obj/item/quantum_keycard))
var/obj/item/quantum_keycard/K = I
if(K.qpad)
to_chat(user, "<span class='notice'>You insert [K] into [src]'s card slot, activating it.</span>")
interact(user, K.qpad)
else
to_chat(user, "<span class='notice'>You insert [K] into [src]'s card slot, initiating the link procedure.</span>")
if(do_after(user, 40, target = src))
to_chat(user, "<span class='notice'>You complete the link between [K] and [src].</span>")
K.qpad = src
if(default_deconstruction_crowbar(I))
return
return ..()
/obj/machinery/quantumpad/interact(mob/user)
if(!linked_pad || QDELETED(linked_pad))
/obj/machinery/quantumpad/interact(mob/user, obj/machinery/quantumpad/target_pad = linked_pad)
if(!target_pad || QDELETED(target_pad))
if(!map_pad_link_id || !initMappedLink())
to_chat(user, "<span class='warning'>There is no linked pad!</span>")
to_chat(user, "<span class='warning'>Target pad not found!</span>")
return
if(world.time < last_teleport + teleport_cooldown)
@@ -93,18 +104,18 @@
to_chat(user, "<span class='warning'>[src] is charging up. Please wait.</span>")
return
if(linked_pad.teleporting)
to_chat(user, "<span class='warning'>Linked pad is busy. Please wait.</span>")
if(target_pad.teleporting)
to_chat(user, "<span class='warning'>Target pad is busy. Please wait.</span>")
return
if(linked_pad.stat & NOPOWER)
to_chat(user, "<span class='warning'>Linked pad is not responding to ping.</span>")
if(target_pad.stat & NOPOWER)
to_chat(user, "<span class='warning'>Target pad is not responding to ping.</span>")
return
add_fingerprint(user)
doteleport(user)
doteleport(user, target_pad)
/obj/machinery/quantumpad/proc/sparks()
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
var/datum/effect_system/spark_spread/quantum/s = new
s.set_up(5, 1, get_turf(src))
s.start()
@@ -117,8 +128,8 @@
if(linked_pad)
ghost.forceMove(get_turf(linked_pad))
/obj/machinery/quantumpad/proc/doteleport(mob/user)
if(linked_pad)
/obj/machinery/quantumpad/proc/doteleport(mob/user, obj/machinery/quantumpad/target_pad = linked_pad)
if(target_pad)
playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, 1)
teleporting = TRUE
@@ -130,7 +141,7 @@
to_chat(user, "<span class='warning'>[src] is unpowered!</span>")
teleporting = FALSE
return
if(!linked_pad || QDELETED(linked_pad) || linked_pad.stat & NOPOWER)
if(!target_pad || QDELETED(target_pad) || target_pad.stat & NOPOWER)
to_chat(user, "<span class='warning'>Linked pad is not responding to ping. Teleport aborted.</span>")
teleporting = FALSE
return
@@ -141,26 +152,30 @@
// use a lot of power
use_power(10000 / power_efficiency)
sparks()
linked_pad.sparks()
target_pad.sparks()
flick("qpad-beam", src)
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
flick("qpad-beam", linked_pad)
playsound(get_turf(linked_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
flick("qpad-beam", target_pad)
playsound(get_turf(target_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
for(var/atom/movable/ROI in get_turf(src))
if(QDELETED(ROI))
continue //sleeps in CHECK_TICK
// if is anchored, don't let through
if(ROI.anchored)
if(isliving(ROI))
var/mob/living/L = ROI
if(L.buckled)
// TP people on office chairs
if(L.buckled.anchored)
continue
//only TP living mobs buckled to non anchored items
if(!L.buckled || L.buckled.anchored)
continue
else
continue
//Don't TP camera mobs
else if(!isobserver(ROI))
continue
do_teleport(ROI, get_turf(linked_pad))
do_teleport(ROI, get_turf(target_pad),null,TRUE,null,null,null,null,TRUE, channel = TELEPORT_CHANNEL_QUANTUM)
CHECK_TICK
/obj/machinery/quantumpad/proc/initMappedLink()
. = FALSE
+1 -1
View File
@@ -66,7 +66,7 @@
visible_message("<span class='alert'>Cannot authenticate locked on coordinates. Please reinstate coordinate matrix.</span>")
return
if (ismovableatom(M))
if(do_teleport(M, com.target))
if(do_teleport(M, com.target, channel = TELEPORT_CHANNEL_BLUESPACE))
use_power(5000)
if(!calibrated && prob(30 - ((accurate) * 10))) //oh dear a problem
log_game("[M] ([key_name(M)]) was turned into a fly person")
@@ -76,6 +76,9 @@
return 0
if(energy_drain && !chassis.has_charge(energy_drain))
return 0
if(chassis.equipment_disabled)
to_chat(chassis.occupant, "<span=warn>Error -- Equipment control unit is unresponsive.</span>")
return 0
return 1
/obj/item/mecha_parts/mecha_equipment/proc/action(atom/target)
@@ -17,7 +17,7 @@
return
var/turf/T = get_turf(target)
if(T)
do_teleport(chassis, T, 4)
do_teleport(chassis, T, 4, channel = TELEPORT_CHANNEL_BLUESPACE)
return 1
+10 -3
View File
@@ -42,6 +42,7 @@
var/last_message = 0
var/add_req_access = 1
var/maint_access = 0
var/equipment_disabled = 0 //disabled due to EMP
var/dna_lock //dna-locking the mech
var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference
var/datum/effect_system/spark_spread/spark_system = new
@@ -143,7 +144,6 @@
diag_hud_set_mechhealth()
diag_hud_set_mechcell()
diag_hud_set_mechstat()
diag_hud_set_mechtracking()
/obj/mecha/get_cell()
return cell
@@ -205,6 +205,15 @@
GLOB.mechas_list -= src //global mech list
return ..()
/obj/mecha/proc/restore_equipment()
equipment_disabled = 0
if(istype(src, /obj/mecha/combat))
mouse_pointer = 'icons/mecha/mecha_mouse.dmi'
if(occupant)
SEND_SOUND(occupant, sound('sound/items/timer.ogg', volume=50))
to_chat(occupant, "<span=notice>Equipment control unit has been rebooted successfuly.</span>")
occupant.update_mouse_pointer()
/obj/mecha/CheckParts(list/parts_list)
..()
cell = locate(/obj/item/stock_parts/cell) in contents
@@ -394,8 +403,6 @@
diag_hud_set_mechhealth()
diag_hud_set_mechcell()
diag_hud_set_mechstat()
diag_hud_set_mechtracking()
/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits.
return
+2 -2
View File
@@ -11,8 +11,8 @@
var/obj/mecha/M = new result(drop_location())
QDEL_NULL(M.cell)
var/atom/parent_atom = parent
M.CheckParts(parent_atom.contents)
var/obj/item/mecha_parts/chassis/parent_chassis = parent
M.CheckParts(parent_chassis.contents)
SSblackbox.record_feedback("tally", "mechas_created", 1, M.name)
QDEL_NULL(parent)
+12 -4
View File
@@ -21,8 +21,9 @@
var/answer = TR.get_mecha_info()
if(answer)
dat += {"<hr>[answer]<br/>
<a href='?src=[REF(src)];send_message=[REF(TR)]'>Send message</a><br/>
<a href='?src=[REF(src)];get_log=[REF(TR)]'>Show exosuit log</a> | <a style='color: #f00;' href='?src=[REF(src)];shock=[REF(TR)]'>(EMP pulse)</a><br>"}
<a href='?src=[REF(src)];send_message=[REF(TR)]'>Send message</a><br/>
<a href='?src=[REF(src)];get_log=[REF(TR)]'>Show exosuit log</a><br/>
[TR.recharging?"Recharging EMP Pulse...<br>":"<a style='color: #f00;' href='?src=[REF(src)];shock=[REF(TR)]'>(EMP Pulse)</a><br>"]"}
if(screen==1)
dat += "<h3>Log contents</h3>"
@@ -65,6 +66,7 @@
icon_state = "motion2"
w_class = WEIGHT_CLASS_SMALL
var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking.
var/recharging = 0
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
if(!in_mecha())
@@ -102,10 +104,16 @@
return 0
/obj/item/mecha_parts/mecha_tracking/proc/shock()
if(recharging)
return
var/obj/mecha/M = in_mecha()
if(M)
M.emp_act(EMP_LIGHT)
qdel(src)
M.emp_act(EMP_HEAVY)
addtimer(CALLBACK(src, /obj/item/mecha_parts/mecha_tracking/proc/recharge), 5 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
recharging = 1
/obj/item/mecha_parts/mecha_tracking/proc/recharge()
recharging = 0
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
if(!ismecha(loc))
+8 -1
View File
@@ -149,7 +149,14 @@
use_power((cell.charge/3)/(severity*2))
take_damage(30 / severity, BURN, "energy", 1)
log_message("EMP detected", color="red")
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
if(istype(src, /obj/mecha/combat))
mouse_pointer = 'icons/mecha/mecha_mouse-disable.dmi'
occupant?.update_mouse_pointer()
if(!equipment_disabled && occupant) //prevent spamming this message with back-to-back EMPs
to_chat(occupant, "<span=danger>Error -- Connection to equipment control unit has been lost.</span>")
addtimer(CALLBACK(src, /obj/mecha/proc/restore_equipment), 3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
equipment_disabled = 1
/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature>max_temperature)
+1 -6
View File
@@ -1,8 +1,3 @@
/obj/mecha/medical/Initialize()
. = ..()
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
/obj/mecha/medical/mechturn(direction)
setDir(direction)
playsound(src,'sound/mecha/mechmove01.ogg',40,1)
@@ -18,4 +13,4 @@
var/result = step_rand(src)
if(result)
playsound(src,'sound/mecha/mechstep.ogg',25,1)
return result
return result
-3
View File
@@ -1,6 +1,3 @@
/obj/mecha/working
internal_damage_threshold = 60
/obj/mecha/working/Initialize()
. = ..()
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
+2 -2
View File
@@ -190,11 +190,11 @@
/obj/effect/anomaly/bluespace/anomalyEffect()
..()
for(var/mob/living/M in range(1,src))
do_teleport(M, locate(M.x, M.y, M.z), 4)
do_teleport(M, locate(M.x, M.y, M.z), 4, channel = TELEPORT_CHANNEL_BLUESPACE)
/obj/effect/anomaly/bluespace/Bumped(atom/movable/AM)
if(isliving(AM))
do_teleport(AM, locate(AM.x, AM.y, AM.z), 8)
do_teleport(AM, locate(AM.x, AM.y, AM.z), 8, channel = TELEPORT_CHANNEL_BLUESPACE)
/obj/effect/anomaly/bluespace/detonate()
var/turf/T = safepick(get_area_turfs(impact_area))
+9
View File
@@ -16,3 +16,12 @@
I.alpha = 64
I.appearance_flags = RESET_ALPHA
add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/blessedAware, "blessing", I)
RegisterSignal(loc, COMSIG_ATOM_INTERCEPT_TELEPORT, .proc/block_cult_teleport)
/obj/effect/blessing/Destroy()
UnregisterSignal(loc, COMSIG_ATOM_INTERCEPT_TELEPORT)
return ..()
/obj/effect/blessing/proc/block_cult_teleport(datum/source, channel, turf/origin, turf/destination)
if(channel == TELEPORT_CHANNEL_CULT)
return COMPONENT_BLOCK_TELEPORT
@@ -26,7 +26,7 @@
/obj/effect/particle_effect/sparks/Initialize()
. = ..()
flick("sparks", src) // replay the animation
flick(icon_state, src) // replay the animation
playsound(src, "sparks", 100, TRUE)
var/turf/T = loc
if(isturf(T))
@@ -48,6 +48,8 @@
/datum/effect_system/spark_spread
effect_type = /obj/effect/particle_effect/sparks
/datum/effect_system/spark_spread/quantum
effect_type = /obj/effect/particle_effect/sparks/quantum
//electricity
@@ -55,5 +57,9 @@
name = "lightning"
icon_state = "electricity"
/obj/effect/particle_effect/sparks/quantum
name = "quantum sparks"
icon_state = "quantum_sparks"
/datum/effect_system/lightning_spread
effect_type = /obj/effect/particle_effect/sparks/electricity
+3 -1
View File
@@ -20,6 +20,7 @@
var/mech_sized = FALSE
var/obj/effect/portal/linked
var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted.
var/teleport_channel = TELEPORT_CHANNEL_BLUESPACE
var/creator
var/turf/hard_target //For when a portal needs a hard target and isn't to be linked.
var/atmos_link = FALSE //Link source/destination atmos.
@@ -34,6 +35,7 @@
icon = 'icons/obj/objects.dmi'
icon_state = "anom"
mech_sized = TRUE
teleport_channel = TELEPORT_CHANNEL_WORMHOLE
/obj/effect/portal/Move(newloc)
for(var/T in newloc)
@@ -160,7 +162,7 @@
no_effect = TRUE
else
last_effect = world.time
if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect))
if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect, channel = teleport_channel))
if(istype(M, /obj/item/projectile))
var/obj/item/projectile/P = M
P.ignore_source_check = TRUE
+3
View File
@@ -579,6 +579,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/proc/get_belt_overlay() //Returns the icon used for overlaying the object on a belt
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state)
/obj/item/proc/get_worn_belt_overlay(icon_file)
return
/obj/item/proc/update_slot_icon()
if(!ismob(loc))
return
+9 -3
View File
@@ -616,7 +616,7 @@ RLD
name = "rapid-light-device (RLD)"
desc = "A device used to rapidly provide lighting sources to an area. Reload with metal, plasteel, glass or compressed matter cartridges."
icon = 'icons/obj/tools.dmi'
icon_state = "rld-5"
icon_state = "rld"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
matter = 500
@@ -625,6 +625,7 @@ RLD
var/mode = LIGHT_MODE
actions_types = list(/datum/action/item_action/pick_color)
ammo_sections = 5
has_ammobar = TRUE
var/wallcost = 10
var/floorcost = 15
@@ -638,6 +639,10 @@ RLD
var/color_choice = null
/obj/item/construction/rld/Initialize()
. = ..()
update_icon()
/obj/item/construction/rld/ui_action_click(mob/user, var/datum/action/A)
if(istype(A, /datum/action/item_action/pick_color))
color_choice = input(user,"","Choose Color",color_choice) as color
@@ -645,9 +650,10 @@ RLD
..()
/obj/item/construction/rld/update_icon()
icon_state = "rld-[round((matter/max_matter) * 5, 1)]"
..()
var/ratio = CEILING((matter / max_matter) * ammo_sections, 1)
cut_overlays() //To prevent infinite stacking of overlays
add_overlay("rld_light[ratio]")
/obj/item/construction/rld/attack_self(mob/user)
..()
+44 -17
View File
@@ -2,7 +2,7 @@
name = "rapid cable layer"
desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables. Do not use without insulation!"
icon = 'icons/obj/tools.dmi'
icon_state = "rcl-0"
icon_state = "rcl-empty"
item_state = "rcl-0"
var/obj/structure/cable/last
var/obj/item/stack/cable_coil/loaded
@@ -92,22 +92,32 @@
/obj/item/twohanded/rcl/update_icon()
if(!loaded)
icon_state = "rcl-0"
item_state = "rcl-0"
icon_state = "rcl-empty"
item_state = "rcl-empty"
return
cut_overlays()
var/cable_amount = 0
switch(loaded.amount)
if(61 to INFINITY)
icon_state = "rcl-30"
item_state = "rcl"
cable_amount = 3
if(31 to 60)
icon_state = "rcl-20"
item_state = "rcl"
cable_amount = 2
if(1 to 30)
icon_state = "rcl-10"
item_state = "rcl"
cable_amount = 1
else
icon_state = "rcl-0"
item_state = "rcl-0"
cable_amount = 0
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[cable_amount]")
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
if(cable_amount >= 1)
icon_state = "rcl"
item_state = "rcl"
add_overlay(cable_overlay)
else
icon_state = "rcl-empty"
item_state = "rcl-0"
add_overlay(cable_overlay)
/obj/item/twohanded/rcl/proc/is_empty(mob/user, loud = 1)
update_icon()
@@ -302,6 +312,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
to_chat(user, "Color changed to [cwname]!")
if(loaded)
loaded.item_color= colors[current_color_index]
update_icon()
if(wiring_gui_menu)
wiringGuiUpdate(user)
else if(istype(action, /datum/action/item_action/rcl_gui))
@@ -318,13 +329,29 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
/obj/item/twohanded/rcl/ghetto/update_icon()
if(!loaded)
icon_state = "rclg-0"
icon_state = "rclg-empty"
item_state = "rclg-0"
return
cut_overlays()
var/cable_amount = 0
switch(loaded.amount)
if(1 to INFINITY)
icon_state = "rclg-1"
item_state = "rcl"
if(20 to INFINITY)
cable_amount = 3
if(10 to 19)
cable_amount = 2
if(1 to 9)
cable_amount = 1
else
icon_state = "rclg-1"
item_state = "rclg-1"
cable_amount = 0
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[cable_amount]")
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
if(cable_amount >= 1)
icon_state = "rclg"
item_state = "rclg"
add_overlay(cable_overlay)
else
icon_state = "rclg-empty"
item_state = "rclg-0"
add_overlay(cable_overlay)
+2
View File
@@ -177,6 +177,8 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
desc = "A device used to rapidly pipe things."
icon = 'icons/obj/tools.dmi'
icon_state = "rpd"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
flags_1 = CONDUCT_1
force = 10
throwforce = 10
@@ -237,3 +237,10 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "multitool"
toolspeed = 0.1
/obj/item/multitool/advanced
name = "advanced multitool"
desc = "The reproduction of an abductor's multitool, this multitool is a classy silver."
icon = 'icons/obj/advancedtools.dmi'
icon_state = "multitool"
toolspeed = 0.2
@@ -0,0 +1,32 @@
/obj/item/quantum_keycard
name = "quantum keycard"
desc = "A keycard able to link to a quantum pad's particle signature, allowing other quantum pads to travel there instead of their linked pad."
icon = 'icons/obj/device.dmi'
icon_state = "quantum_keycard"
item_state = "card-id"
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
var/obj/machinery/quantumpad/qpad
/obj/item/quantum_keycard/examine(mob/user)
..()
if(qpad)
to_chat(user, "It's currently linked to a quantum pad.")
to_chat(user, "<span class='notice'>Alt-click to unlink the keycard.</span>")
else
to_chat(user, "<span class='notice'>Insert [src] into an active quantum pad to link it.</span>")
/obj/item/quantum_keycard/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
to_chat(user, "<span class='notice'>You start pressing [src]'s unlink button...</span>")
if(do_after(user, 40, target = src))
to_chat(user, "<span class='notice'>The keycard beeps twice and disconnects the quantum link.</span>")
qpad = null
/obj/item/quantum_keycard/update_icon()
if(qpad)
icon_state = "quantum_keycard_on"
else
icon_state = initial(icon_state)
@@ -1,6 +1,6 @@
/obj/item/encryptionkey
name = "standard encryption key"
desc = "An encryption key for a radio headset. Has no special codes in it. WHY DOES IT EXIST? ASK NANOTRASEN."
desc = "An encryption key for a radio headset."
icon = 'icons/obj/radio.dmi'
icon_state = "cypherkey"
w_class = WEIGHT_CLASS_TINY
@@ -9,124 +9,119 @@
var/independent = FALSE
var/list/channels = list()
/obj/item/encryptionkey/Initialize()
. = ..()
if(!channels.len)
desc = "An encryption key for a radio headset. Has no special codes in it. You should probably tell a coder!"
/obj/item/encryptionkey/examine(mob/user)
. = ..()
if(LAZYLEN(channels))
var/list/examine_text_list = list()
for(var/i in channels)
examine_text_list += "[GLOB.channel_tokens[i]] - [lowertext(i)]"
to_chat(user, "<span class='notice'>It can access the following channels; [jointext(examine_text_list, ", ")].</span>")
/obj/item/encryptionkey/syndicate
name = "syndicate encryption key"
desc = "An encryption key for a radio headset. To access the syndicate channel, use :t."
icon_state = "syn_cypherkey"
channels = list("Syndicate" = 1)
syndie = 1//Signifies that it de-crypts Syndicate transmissions
channels = list(RADIO_CHANNEL_SYNDICATE = 1)
syndie = TRUE //Signifies that it de-crypts Syndicate transmissions
/obj/item/encryptionkey/binary
name = "binary translator key"
desc = "An encryption key for a radio headset. To access the binary channel, use :b."
icon_state = "bin_cypherkey"
translate_binary = TRUE
/obj/item/encryptionkey/headset_sec
name = "security radio encryption key"
desc = "An encryption key for a radio headset. To access the security channel, use :s."
icon_state = "sec_cypherkey"
channels = list("Security" = 1)
channels = list(RADIO_CHANNEL_SECURITY = 1)
/obj/item/encryptionkey/headset_eng
name = "engineering radio encryption key"
desc = "An encryption key for a radio headset. To access the engineering channel, use :e."
icon_state = "eng_cypherkey"
channels = list("Engineering" = 1)
channels = list(RADIO_CHANNEL_ENGINEERING = 1)
/obj/item/encryptionkey/headset_rob
name = "robotics radio encryption key"
desc = "An encryption key for a radio headset. To access the engineering channel, use :e. For research, use :n."
icon_state = "rob_cypherkey"
channels = list("Science" = 1, "Engineering" = 1)
channels = list(RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_ENGINEERING = 1)
/obj/item/encryptionkey/headset_med
name = "medical radio encryption key"
desc = "An encryption key for a radio headset. To access the medical channel, use :m."
icon_state = "med_cypherkey"
channels = list("Medical" = 1)
channels = list(RADIO_CHANNEL_MEDICAL = 1)
/obj/item/encryptionkey/headset_sci
name = "science radio encryption key"
desc = "An encryption key for a radio headset. To access the science channel, use :n."
icon_state = "sci_cypherkey"
channels = list("Science" = 1)
channels = list(RADIO_CHANNEL_SCIENCE = 1)
/obj/item/encryptionkey/headset_medsci
name = "medical research radio encryption key"
desc = "An encryption key for a radio headset. To access the medical channel, use :m. For science, use :n."
icon_state = "medsci_cypherkey"
channels = list("Science" = 1, "Medical" = 1)
channels = list(RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_MEDICAL = 1)
/obj/item/encryptionkey/headset_com
name = "command radio encryption key"
desc = "An encryption key for a radio headset. To access the command channel, use :c."
icon_state = "com_cypherkey"
channels = list("Command" = 1)
channels = list(RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/heads/captain
name = "\proper the captain's encryption key"
desc = "An encryption key for a radio headset. Channels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
icon_state = "cap_cypherkey"
channels = list("Command" = 1, "Security" = 1, "Engineering" = 0, "Science" = 0, "Medical" = 0, "Supply" = 0, "Service" = 0)
channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_SECURITY = 1, RADIO_CHANNEL_ENGINEERING = 0, RADIO_CHANNEL_SCIENCE = 0, RADIO_CHANNEL_MEDICAL = 0, RADIO_CHANNEL_SUPPLY = 0, RADIO_CHANNEL_SERVICE = 0)
/obj/item/encryptionkey/heads/rd
name = "\proper the research director's encryption key"
desc = "An encryption key for a radio headset. To access the science channel, use :n. For command, use :c."
icon_state = "rd_cypherkey"
channels = list("Science" = 1, "Command" = 1)
channels = list(RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/heads/hos
name = "\proper the head of security's encryption key"
desc = "An encryption key for a radio headset. To access the security channel, use :s. For command, use :c."
icon_state = "hos_cypherkey"
channels = list("Security" = 1, "Command" = 1)
channels = list(RADIO_CHANNEL_SECURITY = 1, RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/heads/ce
name = "\proper the chief engineer's encryption key"
desc = "An encryption key for a radio headset. To access the engineering channel, use :e. For command, use :c."
icon_state = "ce_cypherkey"
channels = list("Engineering" = 1, "Command" = 1)
channels = list(RADIO_CHANNEL_ENGINEERING = 1, RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/heads/cmo
name = "\proper the chief medical officer's encryption key"
desc = "An encryption key for a radio headset. To access the medical channel, use :m. For command, use :c."
icon_state = "cmo_cypherkey"
channels = list("Medical" = 1, "Command" = 1)
channels = list(RADIO_CHANNEL_MEDICAL = 1, RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/heads/hop
name = "\proper the head of personnel's encryption key"
desc = "An encryption key for a radio headset. Channels are as follows: :u - supply, :v - service, :c - command."
icon_state = "hop_cypherkey"
channels = list("Supply" = 1, "Service" = 1, "Command" = 1)
channels = list(RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SERVICE = 1, RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/headset_cargo
name = "supply radio encryption key"
desc = "An encryption key for a radio headset. To access the supply channel, use :u."
icon_state = "cargo_cypherkey"
channels = list("Supply" = 1)
channels = list(RADIO_CHANNEL_SUPPLY = 1)
/obj/item/encryptionkey/headset_mining
name = "mining radio encryption key"
desc = "An encryption key for a radio headset. To access the supply channel, use :u. For science, use :n."
icon_state = "cargo_cypherkey"
channels = list("Supply" = 1, "Science" = 1)
channels = list(RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SCIENCE = 1)
/obj/item/encryptionkey/headset_service
name = "service radio encryption key"
desc = "An encryption key for a radio headset. To access the service channel, use :v."
icon_state = "srv_cypherkey"
channels = list("Service" = 1)
channels = list(RADIO_CHANNEL_SERVICE = 1)
/obj/item/encryptionkey/headset_cent
name = "\improper CentCom radio encryption key"
desc = "An encryption key for a radio headset. To access the CentCom channel, use :y."
icon_state = "cent_cypherkey"
independent = TRUE
channels = list("CentCom" = 1)
channels = list(RADIO_CHANNEL_CENTCOM = 1)
/obj/item/encryptionkey/ai //ported from NT, this goes 'inside' the AI.
channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1, "AI Private" = 1)
channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_SECURITY = 1, RADIO_CHANNEL_ENGINEERING = 1, RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_MEDICAL = 1, RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SERVICE = 1, RADIO_CHANNEL_AI_PRIVATE = 1)
/obj/item/encryptionkey/secbot
channels = list("AI Private"=1,"Security"=1)
channels = list(RADIO_CHANNEL_AI_PRIVATE = 1, RADIO_CHANNEL_SECURITY = 1)
@@ -1,3 +1,19 @@
// Used for translating channels to tokens on examination
GLOBAL_LIST_INIT(channel_tokens, list(
RADIO_CHANNEL_COMMON = RADIO_KEY_COMMON,
RADIO_CHANNEL_SCIENCE = RADIO_TOKEN_SCIENCE,
RADIO_CHANNEL_COMMAND = RADIO_TOKEN_COMMAND,
RADIO_CHANNEL_MEDICAL = RADIO_TOKEN_MEDICAL,
RADIO_CHANNEL_ENGINEERING = RADIO_TOKEN_ENGINEERING,
RADIO_CHANNEL_SECURITY = RADIO_TOKEN_SECURITY,
RADIO_CHANNEL_CENTCOM = RADIO_TOKEN_CENTCOM,
RADIO_CHANNEL_SYNDICATE = RADIO_TOKEN_SYNDICATE,
RADIO_CHANNEL_SUPPLY = RADIO_TOKEN_SUPPLY,
RADIO_CHANNEL_SERVICE = RADIO_TOKEN_SERVICE,
MODE_BINARY = MODE_TOKEN_BINARY,
RADIO_CHANNEL_AI_PRIVATE = RADIO_TOKEN_AI_PRIVATE
))
/obj/item/radio/headset
name = "radio headset"
desc = "An updated, modular intercom that fits over the head. Takes encryption keys."
@@ -17,9 +33,24 @@
/obj/item/radio/headset/examine(mob/user)
..()
to_chat(user, "<span class='notice'>To speak on the general radio frequency, use ; before speaking.</span>")
if (command)
to_chat(user, "<span class='notice'>Alt-click to toggle the high-volume mode.</span>")
if(item_flags & IN_INVENTORY && loc == user)
// construction of frequency description
var/list/avail_chans = list("Use [RADIO_KEY_COMMON] for the currently tuned frequency")
if(translate_binary)
avail_chans += "use [MODE_TOKEN_BINARY] for [MODE_BINARY]"
if(length(channels))
for(var/i in 1 to length(channels))
if(i == 1)
avail_chans += "use [MODE_TOKEN_DEPARTMENT] or [GLOB.channel_tokens[channels[i]]] for [lowertext(channels[i])]"
else
avail_chans += "use [GLOB.channel_tokens[channels[i]]] for [lowertext(channels[i])]"
to_chat(user, "<span class='notice'>A small screen on the headset displays the following available frequencies:\n[english_list(avail_chans)].")
if(command)
to_chat(user, "<span class='info'>Alt-click to toggle the high-volume mode.</span>")
else
to_chat(user, "<span class='notice'>A small screen on the headset flashes, it's too small to read without holding or wearing the headset.</span>")
/obj/item/radio/headset/Initialize()
. = ..()
@@ -47,7 +78,7 @@
/obj/item/radio/headset/syndicate/alt //undisguised bowman with flash protection
name = "syndicate headset"
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs. \nTo access the syndicate channel, use ; before speaking."
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs."
icon_state = "syndie_headset"
item_state = "syndie_headset"
@@ -72,13 +103,13 @@
/obj/item/radio/headset/headset_sec
name = "security radio headset"
desc = "This is used by your elite security force.\nTo access the security channel, use :s."
desc = "This is used by your elite security force."
icon_state = "sec_headset"
keyslot = new /obj/item/encryptionkey/headset_sec
/obj/item/radio/headset/headset_sec/alt
name = "security bowman headset"
desc = "This is used by your elite security force. Protects ears from flashbangs.\nTo access the security channel, use :s."
desc = "This is used by your elite security force. Protects ears from flashbangs."
icon_state = "sec_headset_alt"
item_state = "sec_headset_alt"
@@ -88,31 +119,31 @@
/obj/item/radio/headset/headset_eng
name = "engineering radio headset"
desc = "When the engineers wish to chat like girls.\nTo access the engineering channel, use :e."
desc = "When the engineers wish to chat like girls."
icon_state = "eng_headset"
keyslot = new /obj/item/encryptionkey/headset_eng
/obj/item/radio/headset/headset_rob
name = "robotics radio headset"
desc = "Made specifically for the roboticists, who cannot decide between departments.\nTo access the engineering channel, use :e. For research, use :n."
desc = "Made specifically for the roboticists, who cannot decide between departments."
icon_state = "rob_headset"
keyslot = new /obj/item/encryptionkey/headset_rob
/obj/item/radio/headset/headset_med
name = "medical radio headset"
desc = "A headset for the trained staff of the medbay.\nTo access the medical channel, use :m."
desc = "A headset for the trained staff of the medbay."
icon_state = "med_headset"
keyslot = new /obj/item/encryptionkey/headset_med
/obj/item/radio/headset/headset_sci
name = "science radio headset"
desc = "A sciency headset. Like usual.\nTo access the science channel, use :n."
desc = "A sciency headset. Like usual."
icon_state = "sci_headset"
keyslot = new /obj/item/encryptionkey/headset_sci
/obj/item/radio/headset/headset_medsci
name = "medical research radio headset"
desc = "A headset that is a result of the mating between medical and science.\nTo access the medical channel, use :m. For science, use :n."
desc = "A headset that is a result of the mating between medical and science."
icon_state = "medsci_headset"
keyslot = new /obj/item/encryptionkey/headset_medsci
@@ -127,13 +158,13 @@
/obj/item/radio/headset/heads/captain
name = "\proper the captain's headset"
desc = "The headset of the king.\nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
desc = "The headset of the king."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/captain
/obj/item/radio/headset/heads/captain/alt
name = "\proper the captain's bowman headset"
desc = "The headset of the boss. Protects ears from flashbangs.\nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
desc = "The headset of the boss. Protects ears from flashbangs."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
@@ -143,19 +174,19 @@
/obj/item/radio/headset/heads/rd
name = "\proper the research director's headset"
desc = "Headset of the fellow who keeps society marching towards technological singularity.\nTo access the science channel, use :n. For command, use :c."
desc = "Headset of the fellow who keeps society marching towards technological singularity."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/rd
/obj/item/radio/headset/heads/hos
name = "\proper the head of security's headset"
desc = "The headset of the man in charge of keeping order and protecting the station.\nTo access the security channel, use :s. For command, use :c."
desc = "The headset of the man in charge of keeping order and protecting the station."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/hos
/obj/item/radio/headset/heads/hos/alt
name = "\proper the head of security's bowman headset"
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs.\nTo access the security channel, use :s. For command, use :c."
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
@@ -165,43 +196,43 @@
/obj/item/radio/headset/heads/ce
name = "\proper the chief engineer's headset"
desc = "The headset of the guy in charge of keeping the station powered and undamaged.\nTo access the engineering channel, use :e. For command, use :c."
desc = "The headset of the guy in charge of keeping the station powered and undamaged."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/ce
/obj/item/radio/headset/heads/cmo
name = "\proper the chief medical officer's headset"
desc = "The headset of the highly trained medical chief.\nTo access the medical channel, use :m. For command, use :c."
desc = "The headset of the highly trained medical chief."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/cmo
/obj/item/radio/headset/heads/hop
name = "\proper the head of personnel's headset"
desc = "The headset of the guy who will one day be captain.\nChannels are as follows: :u - supply, :v - service, :c - command."
desc = "The headset of the guy who will one day be captain."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/hop
/obj/item/radio/headset/headset_cargo
name = "supply radio headset"
desc = "A headset used by the QM and his slaves.\nTo access the supply channel, use :u."
desc = "A headset used by the QM and his slaves."
icon_state = "cargo_headset"
keyslot = new /obj/item/encryptionkey/headset_cargo
/obj/item/radio/headset/headset_cargo/mining
name = "mining radio headset"
desc = "Headset used by shaft miners.\nTo access the supply channel, use :u. For science, use :n."
desc = "Headset used by shaft miners."
icon_state = "mine_headset"
keyslot = new /obj/item/encryptionkey/headset_mining
/obj/item/radio/headset/headset_srv
name = "service radio headset"
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean.\nTo access the service channel, use :v."
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean."
icon_state = "srv_headset"
keyslot = new /obj/item/encryptionkey/headset_service
/obj/item/radio/headset/headset_cent
name = "\improper CentCom headset"
desc = "A headset used by the upper echelons of Nanotrasen.\nTo access the CentCom channel, use :y."
desc = "A headset used by the upper echelons of Nanotrasen."
icon_state = "cent_headset"
keyslot = new /obj/item/encryptionkey/headset_com
keyslot2 = new /obj/item/encryptionkey/headset_cent
@@ -215,7 +246,7 @@
/obj/item/radio/headset/headset_cent/alt
name = "\improper CentCom bowman headset"
desc = "A headset especially for emergency response personnel. Protects ears from flashbangs.\nTo access the CentCom channel, use :y."
desc = "A headset especially for emergency response personnel. Protects ears from flashbangs."
icon_state = "cent_headset_alt"
item_state = "cent_headset_alt"
keyslot = null
@@ -221,7 +221,7 @@
// From the channel, determine the frequency and get a reference to it.
var/freq
if(channel && channels && channels.len > 0)
if(channel == "department")
if(channel == MODE_DEPARTMENT)
channel = channels[1]
freq = secure_radio_connections[channel]
if (!channels[channel]) // if the channel is turned off, don't broadcast
+122 -81
View File
@@ -1,4 +1,3 @@
///books that teach things (intrinsic actions like bar flinging, spells like fireball or smoke, or martial arts)///
/obj/item/book/granter
@@ -13,19 +12,50 @@
/obj/item/book/granter/proc/turn_page(mob/user)
playsound(user, pick('sound/effects/pageturn1.ogg','sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg'), 30, 1)
if(do_after(user,50, user))
to_chat(user, "<span class='notice'>[pick(remarks)]</span>")
if(remarks.len)
to_chat(user, "<span class='notice'>[pick(remarks)]</span>")
else
to_chat(user, "<span class='notice'>You keep reading...</span>")
return TRUE
return FALSE
/obj/item/book/granter/proc/recoil(mob/user) //nothing so some books can just return
/obj/item/book/granter/proc/already_known(mob/user)
return FALSE
/obj/item/book/granter/proc/on_reading_start(mob/user)
to_chat(user, "<span class='notice'>You start reading [name]...</span>")
/obj/item/book/granter/proc/on_reading_stopped(mob/user)
to_chat(user, "<span class='notice'>You stop reading...</span>")
/obj/item/book/granter/proc/on_reading_finished(mob/user)
to_chat(user, "<span class='notice'>You finish reading [name]!</span>")
/obj/item/book/granter/proc/onlearned(mob/user)
used = TRUE
/obj/item/book/granter/attack_self(mob/user)
if(reading == TRUE)
if(reading)
to_chat(user, "<span class='warning'>You're already reading this!</span>")
return FALSE
if(already_known(user))
return FALSE
if(used && oneuse)
recoil(user)
else
on_reading_start(user)
reading = TRUE
for(var/i=1, i<=pages_to_mastery, i++)
if(!turn_page(user))
on_reading_stopped()
reading = FALSE
return
if(do_after(user,50, user))
on_reading_finished(user)
reading = FALSE
return TRUE
///ACTION BUTTONS///
@@ -34,33 +64,23 @@
var/granted_action
var/actionname = "catching bugs" //might not seem needed but this makes it so you can safely name action buttons toggle this or that without it fucking up the granter, also caps
/obj/item/book/granter/action/attack_self(mob/user)
. = ..()
if(!.)
return
/obj/item/book/granter/action/already_known(mob/user)
if(!granted_action)
return
var/datum/action/G = new granted_action
return TRUE
for(var/datum/action/A in user.actions)
if(A.type == G.type)
if(A.type == granted_action)
to_chat(user, "<span class='notice'>You already know all about [actionname].</span>")
qdel(G)
return
if(used == TRUE && oneuse == TRUE)
recoil(user)
else
to_chat(user, "<span class='notice'>You start reading about [actionname]...</span>")
reading = TRUE
for(var/i=1, i<=pages_to_mastery, i++)
if(!turn_page(user))
to_chat(user, "<span class='notice'>You stop reading...</span>")
reading = FALSE
qdel(G)
return
if(do_after(user,50, user))
to_chat(user, "<span class='notice'>You feel like you've got a good handle on [actionname]!</span>")
G.Grant(user)
reading = FALSE
return TRUE
return FALSE
/obj/item/book/granter/action/on_reading_start(mob/user)
to_chat(user, "<span class='notice'>You start reading about [actionname]...</span>")
/obj/item/book/granter/action/on_reading_finished(mob/user)
to_chat(user, "<span class='notice'>You feel like you've got a good handle on [actionname]!</span>")
var/datum/action/G = new granted_action
G.Grant(user)
onlearned(user)
/obj/item/book/granter/action/drink_fling
granted_action = /datum/action/innate/drink_fling
@@ -120,38 +140,28 @@
var/spell
var/spellname = "conjure bugs"
/obj/item/book/granter/spell/attack_self(mob/user)
. = ..()
if(!.)
return
/obj/item/book/granter/spell/already_known(mob/user)
if(!spell)
return
var/obj/effect/proc_holder/spell/S = new spell
return TRUE
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
if(knownspell.type == S.type)
if(knownspell.type == spell)
if(user.mind)
if(iswizard(user))
to_chat(user,"<span class='notice'>You're already far more versed in this spell than this flimsy howto book can provide.</span>")
to_chat(user,"<span class='notice'>You're already far more versed in this spell than this flimsy how-to book can provide.</span>")
else
to_chat(user,"<span class='notice'>You've already read this one.</span>")
return
if(used == TRUE && oneuse == TRUE)
recoil(user)
else
to_chat(user, "<span class='notice'>You start reading about casting [spellname]...</span>")
reading = TRUE
for(var/i=1, i<=pages_to_mastery, i++)
if(!turn_page(user))
to_chat(user, "<span class='notice'>You stop reading...</span>")
reading = FALSE
qdel(S)
return
if(do_after(user,50, user))
to_chat(user, "<span class='notice'>You feel like you've experienced enough to cast [spellname]!</span>")
user.mind.AddSpell(S)
user.log_message("learned the spell [spellname] ([S])", LOG_ATTACK, color="orange")
onlearned(user)
reading = FALSE
return TRUE
return FALSE
/obj/item/book/granter/spell/on_reading_start(mob/user)
to_chat(user, "<span class='notice'>You start reading about casting [spellname]...</span>")
/obj/item/book/granter/spell/on_reading_finished(mob/user)
to_chat(user, "<span class='notice'>You feel like you've experienced enough to cast [spellname]!</span>")
var/obj/effect/proc_holder/spell/S = new spell
user.mind.AddSpell(S)
user.log_message("learned the spell [spellname] ([S])", LOG_ATTACK, color="orange")
onlearned(user)
/obj/item/book/granter/spell/recoil(mob/user)
user.visible_message("<span class='warning'>[src] glows in a black light!</span>")
@@ -280,7 +290,8 @@
if(ishuman(user))
to_chat(user,"<font size='15' color='red'><b>HORSIE HAS RISEN</b></font>")
var/obj/item/clothing/magichead = new /obj/item/clothing/mask/horsehead/cursed(user.drop_location())
user.dropItemToGround(user.wear_mask, TRUE)
if(!user.dropItemToGround(user.wear_mask))
qdel(user.wear_mask)
user.equip_to_slot_if_possible(magichead, SLOT_WEAR_MASK, TRUE, TRUE)
qdel(src)
else
@@ -327,35 +338,24 @@
var/martialname = "bug jitsu"
var/greet = "You feel like you have mastered the art in breaking code. Nice work, jackass."
/obj/item/book/granter/martial/attack_self(mob/user)
. = ..()
if(!.)
return
/obj/item/book/granter/martial/already_known(mob/user)
if(!martial)
return
return TRUE
var/datum/martial_art/MA = martial
if(user.mind.has_martialart(initial(MA.id)))
to_chat(user,"<span class='warning'>You already know [martialname]!</span>")
return TRUE
return FALSE
/obj/item/book/granter/martial/on_reading_start(mob/user)
to_chat(user, "<span class='notice'>You start reading about [martialname]...</span>")
/obj/item/book/granter/martial/on_reading_finished(mob/user)
to_chat(user, "[greet]")
var/datum/martial_art/MA = new martial
if(user.mind.martial_art)
for(var/datum/martial_art/knownmartial in user.mind.martial_art)
if(knownmartial.type == MA.type)
to_chat(user,"<span class='warning'>You already know [martialname]!</span>")
return
if(used == TRUE && oneuse == TRUE)
recoil(user)
else
to_chat(user, "<span class='notice'>You start reading about [martialname]...</span>")
reading = TRUE
for(var/i=1, i<=pages_to_mastery, i++)
if(!turn_page(user))
to_chat(user, "<span class='notice'>You stop reading...</span>")
reading = FALSE
qdel(MA)
return
if(do_after(user,50, user))
to_chat(user, "[greet]")
MA.teach(user)
user.log_message("learned the martial art [martialname] ([MA])", LOG_ATTACK, color="orange")
onlearned(user)
reading = FALSE
MA.teach(user)
user.log_message("learned the martial art [martialname] ([MA])", LOG_ATTACK, color="orange")
onlearned(user)
/obj/item/book/granter/martial/cqc
martial = /datum/martial_art/cqc
@@ -416,3 +416,44 @@
icon_state = "blankscroll"
// I did not include mushpunch's grant, it is not a book and the item does it just fine.
//Crafting Recipe books
/obj/item/book/granter/crafting_recipe
var/list/crafting_recipe_types = list() //Use full /datum/crafting_recipe/what_you_craft
/obj/item/book/granter/crafting_recipe/on_reading_finished(mob/user)
. = ..()
if(!user.mind)
return
for(var/crafting_recipe_type in crafting_recipe_types)
var/datum/crafting_recipe/R = crafting_recipe_type
user.mind.teach_crafting_recipe(crafting_recipe_type)
to_chat(user,"<span class='notice'>You learned how to make [initial(R.name)].</span>")
/obj/item/book/granter/crafting_recipe/cooking_sweets_101 //We start at 101 for 103 and 105
name = "Cooking Desserts 101"
desc = "A cook book that teaches you some more of the newest desserts. AI approved, and a best seller on Honkplanet."
crafting_recipe_types = list(/datum/crafting_recipe/food/mimetart, /datum/crafting_recipe/food/berrytart, /datum/crafting_recipe/food/cocolavatart, /datum/crafting_recipe/food/clowncake, /datum/crafting_recipe/food/vanillacake)
icon_state = "cooking_learing_sweets"
oneuse = FALSE
remarks = list("So that is how icing is made!", "Placing fruit on top? How simple...", "Huh layering cake seems harder then this...", "This book smells like candy", "A clown must have made this page, or they forgot to spell check it before printing...", "Wait, a way to cook slime to be safe?")
//Later content when I have free time - Trilby Date:02-Aug-2019
/obj/item/book/granter/crafting_recipe/under_the_oven //Illegal cook book
name = "Under The Oven"
desc = "A cook book that teaches you many illegal and fun candys. MALF AI approved, and a best seller on the blackmarket."
crafting_recipe_types = list()
icon_state = "cooking_learing_illegal"
oneuse = FALSE
remarks = list()
/obj/item/book/granter/crafting_recipe/coldcooking //IceCream
name = "Cooking with Ice"
desc = "A cook book that teaches you many old icecream treats."
crafting_recipe_types = list()
icon_state = "cooking_learing_ice"
oneuse = FALSE
remarks = list()
+11 -3
View File
@@ -26,6 +26,7 @@
gender = PLURAL
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "handcuff"
item_state = "handcuff"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
flags_1 = CONDUCT_1
@@ -103,7 +104,6 @@
desc = "A pair of restraints fashioned from long strands of flesh."
icon = 'icons/obj/mining.dmi'
icon_state = "sinewcuff"
item_state = "sinewcuff"
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
@@ -172,6 +172,13 @@
desc = "Fake handcuffs meant for gag purposes."
breakouttime = 10 //Deciseconds = 1s
/obj/item/restraints/handcuffs/fake/kinky
name = "kinky handcuffs"
desc = "Fake handcuffs meant for erotic roleplay."
icon = 'modular_citadel/icons/obj/items_and_weapons.dmi'
icon_state = "handcuffgag"
item_state = "kinkycuff"
/obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/rods))
@@ -206,7 +213,8 @@
/obj/item/restraints/handcuffs/cable/zipties
name = "zipties"
desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use."
icon_state = "cuff"
icon_state = "zipties"
item_state = "zipties"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
materials = list()
@@ -217,7 +225,6 @@
/obj/item/restraints/handcuffs/cable/zipties/used
desc = "A pair of broken zipties."
icon_state = "cuff_used"
item_state = "cuff"
/obj/item/restraints/handcuffs/cable/zipties/used/attack()
return
@@ -230,6 +237,7 @@
gender = PLURAL
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "handcuff"
item_state = "legcuff"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
flags_1 = CONDUCT_1
+5 -1
View File
@@ -174,6 +174,7 @@
/obj/item/his_grace/proc/consume(mob/living/meal) //Here's your dinner, Mr. Grace.
if(!meal)
return
var/victims = 0
meal.visible_message("<span class='warning'>[src] swings open and devours [meal]!</span>", "<span class='his_grace big bold'>[src] consumes you!</span>")
meal.adjustBruteLoss(200)
playsound(meal, 'sound/misc/desceration-02.ogg', 75, 1)
@@ -185,7 +186,10 @@
bloodthirst = max(LAZYLEN(contents), 1) //Never fully sated, and His hunger will only grow.
else
bloodthirst = HIS_GRACE_CONSUME_OWNER
if(LAZYLEN(contents) >= victims_needed)
for(var/mob/living/C in contents)
if(C.mind)
victims++
if(victims >= victims_needed)
ascend()
update_stats()
@@ -21,7 +21,7 @@
return
if(!H.mind)
return
if(istype(H.mind.martial_art, /datum/martial_art/krav_maga))
if(H.mind.has_martialart(MARTIALART_KRAVMAGA))
style.remove(H)
else
style.teach(H,1)
@@ -9,6 +9,7 @@
name = "inconspicious box"
desc = "It's so normal that you didn't notice it before."
icon_state = "agentbox"
max_integrity = 1
use_mob_movespeed = TRUE
/obj/structure/closet/cardboard/agent/proc/go_invisible()
+13 -1
View File
@@ -89,6 +89,12 @@
if(istype(B))
playsound(B, 'sound/items/sheath.ogg', 25, 1)
/obj/item/melee/sabre/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "sabre")
/obj/item/melee/sabre/get_worn_belt_overlay(icon_file)
return mutable_appearance(icon_file, "-sabre")
/obj/item/melee/sabre/suicide_act(mob/living/user)
user.visible_message("<span class='suicide'>[user] is trying to cut off all [user.p_their()] limbs with [src]! it looks like [user.p_theyre()] trying to commit suicide!</span>")
var/i = 0
@@ -147,13 +153,19 @@
flags_1 = CONDUCT_1
obj_flags = UNIQUE_RENAME
w_class = WEIGHT_CLASS_BULKY
sharpness = IS_SHARP_ACCURATE //It cant be sharpend cook -_-
sharpness = IS_SHARP_ACCURATE //It cant be sharpend cook -_-
attack_verb = list("slashed", "cut", "pierces", "pokes")
/obj/item/melee/rapier/Initialize()
. = ..()
AddComponent(/datum/component/butchering, 20, 65, 0)
/obj/item/melee/rapier/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "rapier")
/obj/item/melee/rapier/get_worn_belt_overlay(icon_file)
return mutable_appearance(icon_file, "-rapier")
/obj/item/melee/classic_baton
name = "police baton"
desc = "A wooden truncheon for beating criminal scum."
+5 -4
View File
@@ -66,7 +66,8 @@
to_chat(user, "The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry.")
return
user.forceMove(pick(L))
smoke.start()
uses--
if(do_teleport(user, pick(L), forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC, forced = TRUE))
smoke.start()
uses--
else
to_chat(user, "The spell matrix was disrupted by something near the destination.")
+1 -1
View File
@@ -33,7 +33,7 @@
use(1)
/obj/item/stack/ore/bluespace_crystal/proc/blink_mob(mob/living/L)
do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg')
do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
/obj/item/stack/ore/bluespace_crystal/throw_impact(atom/hit_atom)
if(!..()) // not caught in mid-air
+1 -1
View File
@@ -18,7 +18,7 @@
/obj/item/stack/medical/attack(mob/living/M, mob/user)
if(M.stat == DEAD)
if(M.stat == DEAD && !stop_bleeding)
var/t_him = "it"
if(M.gender == MALE)
t_him = "him"
@@ -415,6 +415,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
new/datum/stack_recipe("brass window - directional", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass window - fulltile", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass bar stool", /obj/structure/chair/stool/bar/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass stool", /obj/structure/chair/stool/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \
null,
new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
@@ -426,7 +428,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
new/datum/stack_recipe("receiver - power nullifier", /obj/structure/destructible/clockwork/trap/power_nullifier, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
null,
new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/holyoil/null), \
new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/bottle/holyoil/empty), \
))
@@ -478,6 +480,8 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
new/datum/stack_recipe("bronze boots", /obj/item/clothing/shoes/bronze), \
null,
new/datum/stack_recipe("bronze chair", /obj/structure/chair/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("bronze bar stool", /obj/structure/chair/stool/bar/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("bronze stool", /obj/structure/chair/stool/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
))
/obj/item/stack/tile/bronze
+32 -41
View File
@@ -10,6 +10,7 @@
attack_verb = list("whipped", "lashed", "disciplined")
max_integrity = 300
var/content_overlays = FALSE //If this is true, the belt will gain overlays based on what it's holding
var/worn_overlays = FALSE //worn counterpart of the above.
/obj/item/storage/belt/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins belting [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -23,6 +24,12 @@
add_overlay(M)
..()
/obj/item/storage/belt/worn_overlays(isinhands, icon_file)
. = ..()
if(!isinhands && worn_overlays)
for(var/obj/item/I in contents)
. += I.get_worn_belt_overlay(icon_file)
/obj/item/storage/belt/Initialize()
. = ..()
update_icon()
@@ -653,6 +660,10 @@
icon_state = "sheath"
item_state = "sheath"
w_class = WEIGHT_CLASS_BULKY
content_overlays = TRUE
worn_overlays = TRUE
var/list/fitting_swords = list(/obj/item/melee/sabre, /obj/item/melee/baton/stunsword)
var/starting_sword = /obj/item/melee/sabre
/obj/item/storage/belt/sabre/ComponentInitialize()
. = ..()
@@ -660,35 +671,7 @@
STR.max_items = 1
STR.rustle_sound = FALSE
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.can_hold = typecacheof(list(
/obj/item/melee/sabre
))
/obj/item/storage/belt/sabre/rapier
name = "rapier sheath"
desc = "A black, thin sheath that looks to house only a long thin blade. Feels like its made of metal."
icon_state = "rsheath"
item_state = "rsheath"
force = 5
throwforce = 15
block_chance = 30
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("bashed", "slashes", "prods", "pokes")
/obj/item/storage/belt/sabre/rapier/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_items = 1
STR.rustle_sound = FALSE
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.can_hold = typecacheof(list(
/obj/item/melee/rapier
))
/obj/item/storage/belt/sabre/rapier/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0 //To thin to block bullets
return ..()
STR.can_hold = typecacheof(fitting_swords)
/obj/item/storage/belt/sabre/examine(mob/user)
..()
@@ -707,20 +690,28 @@
to_chat(user, "[src] is empty.")
/obj/item/storage/belt/sabre/update_icon()
icon_state = initial(icon_state)
item_state = initial(item_state)
if(contents.len)
icon_state += "-sabre"
item_state += "-sabre"
if(loc && isliving(loc))
. = ..()
if(isliving(loc))
var/mob/living/L = loc
L.regenerate_icons()
..()
/obj/item/storage/belt/sabre/PopulateContents()
new /obj/item/melee/sabre(src)
update_icon()
new starting_sword(src)
/obj/item/storage/belt/sabre/rapier/PopulateContents()
new /obj/item/melee/rapier(src)
update_icon()
/obj/item/storage/belt/sabre/rapier
name = "rapier sheath"
desc = "A black, thin sheath that looks to house only a long thin blade. Feels like its made of metal."
icon_state = "rsheath"
item_state = "rsheath"
force = 5
throwforce = 15
block_chance = 30
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("bashed", "slashes", "prods", "pokes")
fitting_swords = list(/obj/item/melee/rapier)
starting_sword = /obj/item/melee/rapier
/obj/item/storage/belt/sabre/rapier/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0 //To thin to block bullets
return ..()
+21 -2
View File
@@ -1131,6 +1131,7 @@
name = "Nanotrasen MRE Ration Kit Menu 0"
desc = "A package containing food suspended in an outdated bluespace pocket which lasts for centuries. If you're lucky you may even be able to enjoy the meal without getting food poisoning."
icon_state = "mre"
illustration = null
var/can_expire = TRUE
var/spawner_chance = 2
var/expiration_date
@@ -1184,7 +1185,7 @@
/obj/item/storage/box/mre/menu3
name = "\improper Nanotrasen MRE Ration Kit Menu 3"
desc = "The holy grail of MREs. This item contains the fabled MRE pizza and a sample of coffee instant type 2. Any NT employee lucky enough to get their hands on one of these is truly blessed."
desc = "The holy grail of MREs. This item contains the fabled MRE pizza, spicy nachos and a sample of coffee instant type 2. Any NT employee lucky enough to get their hands on one of these is truly blessed."
icon_state = "menu3"
can_expire = FALSE //always fresh, never expired.
spawner_chance = 1
@@ -1192,11 +1193,29 @@
/obj/item/storage/box/mre/menu3/PopulateContents()
new /obj/item/reagent_containers/food/snacks/pizzaslice/pepperoni(src)
new /obj/item/reagent_containers/food/snacks/breadslice/plain(src)
new /obj/item/reagent_containers/food/snacks/cheesewedge(src)
new /obj/item/reagent_containers/food/snacks/cubannachos(src)
new /obj/item/reagent_containers/food/snacks/grown/chili(src)
new /obj/item/reagent_containers/food/drinks/coffee/type2(src)
new /obj/item/tank/internals/emergency_oxygen(src)
/obj/item/storage/box/mre/menu4
name = "\improper Nanotrasen MRE Ration Kit Menu 4"
/obj/item/storage/box/mre/menu4/safe
spawner_chance = 0
desc = "A package containing food suspended in a bluespace pocket capable of lasting till the end of time."
can_expire = FALSE
/obj/item/storage/box/mre/menu4/PopulateContents()
if(prob(66))
new /obj/item/reagent_containers/food/snacks/salad/boiledrice(src)
else
new /obj/item/reagent_containers/food/snacks/salad/ricebowl(src)
new /obj/item/reagent_containers/food/snacks/burger/tofu(src)
new /obj/item/reagent_containers/food/snacks/salad/fruit(src)
new /obj/item/reagent_containers/food/snacks/cracker(src)
new /obj/item/tank/internals/emergency_oxygen(src)
//Where do I put this?
/obj/item/secbat
name = "Secbat box"
+1 -1
View File
@@ -16,7 +16,7 @@
AddComponent(component_type)
/obj/item/storage/AllowDrop()
return TRUE
return FALSE
/obj/item/storage/contents_explosion(severity, target)
for(var/atom/A in contents)
+2 -2
View File
@@ -10,7 +10,7 @@
. = ..()
if(!. || !istype(M) || M.anchored)
return
do_teleport(M, get_turf(M), 15)
do_teleport(M, get_turf(M), 15, channel = TELEPORT_CHANNEL_BLUESPACE)
/obj/item/melee/baton/cattleprod/teleprod/clowning_around(mob/living/user)
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
@@ -18,7 +18,7 @@
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
user.Knockdown(stunforce*3)
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
if(do_teleport(user, get_turf(user), 50))
if(do_teleport(user, get_turf(user), 50, channel = TELEPORT_CHANNEL_BLUESPACE))
deductcharge(hitcost)
else
deductcharge(hitcost * 0.25)
+9 -1
View File
@@ -90,4 +90,12 @@
var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power(drop_location())
to_chat(user, "<span class='notice'>You attach the cutting jaws to [src].</span>")
qdel(src)
user.put_in_active_hand(cutjaws)
user.put_in_active_hand(cutjaws)
/obj/item/crowbar/advanced
name = "advanced crowbar"
desc = "A scientist's almost successful reproduction of an abductor's crowbar, it uses the same technology combined with a handle that can't quite hold it."
icon = 'icons/obj/advancedtools.dmi'
usesound = 'sound/weapons/sonic_jackhammer.ogg'
icon_state = "crowbar"
toolspeed = 0.2
+11 -1
View File
@@ -141,4 +141,14 @@
name = "powered screwdriver"
desc = "An electrical screwdriver, designed to be both precise and quick."
usesound = 'sound/items/drill_use.ogg'
toolspeed = 0.5
toolspeed = 0.5
/obj/item/screwdriver/advanced
name = "advanced screwdriver"
desc = "A classy silver screwdriver with an alien alloy tip, it works almost as well as the real thing."
icon = 'icons/obj/advancedtools.dmi'
icon_state = "screwdriver_a"
item_state = "screwdriver_nuke"
usesound = 'sound/items/pshoom.ogg'
toolspeed = 0.2
random_color = FALSE
@@ -377,4 +377,18 @@
nextrefueltick = world.time + 10
reagents.add_reagent("welding_fuel", 1)
/obj/item/weldingtool/advanced
name = "advanced welding tool"
desc = "A modern welding tool combined with an alien welding tool, it never runs out of fuel and works almost as fast."
icon = 'icons/obj/advancedtools.dmi'
icon_state = "welder"
toolspeed = 0.2
light_intensity = 0
change_icons = 0
/obj/item/weldingtool/advanced/process()
if(get_fuel() <= max_fuel)
reagents.add_reagent("welding_fuel", 1)
..()
#undef WELDER_FUEL_BURN_INTERVAL
+8 -1
View File
@@ -82,7 +82,6 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "cutters"
toolspeed = 0.1
random_color = FALSE
/obj/item/wirecutters/cyborg
@@ -126,3 +125,11 @@
return
else
..()
/obj/item/wirecutters/advanced
name = "advanced wirecutters"
desc = "A set of reproduction alien wirecutters, they have a silver handle with an exceedingly sharp blade."
icon = 'icons/obj/advancedtools.dmi'
icon_state = "cutters"
toolspeed = 0.2
random_color = FALSE
+9 -1
View File
@@ -112,4 +112,12 @@
user.dust()
return OXYLOSS
return OXYLOSS
/obj/item/wrench/advanced
name = "advanced wrench"
desc = "A wrench that uses the same magnetic technology that abductor tools use, but slightly more ineffeciently."
icon = 'icons/obj/advancedtools.dmi'
icon_state = "wrench"
usesound = 'sound/effects/empulse.ogg'
toolspeed = 0.2
@@ -317,9 +317,6 @@
new stack_type(get_turf(loc))
qdel(src)
/obj/item/chair/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == UNARMED_ATTACK && prob(hit_reaction_chance))
owner.visible_message("<span class='danger'>[owner] fends off [attack_text] with [src]!</span>")
@@ -338,7 +335,6 @@
C.Knockdown(20)
smash(user)
/obj/item/chair/stool
name = "stool"
icon_state = "stool_toppled"
@@ -352,6 +348,70 @@
item_state = "stool_bar"
origin_type = /obj/structure/chair/stool/bar
//////////////////////////
//Brass & Bronze stools!//
//////////////////////////
/obj/structure/chair/stool/bar/brass
name = "brass bar stool"
desc = "A brass bar stool with red silk for a pillow."
icon_state = "barbrass"
item_chair = /obj/item/chair/stool/bar/brass
buildstacktype = /obj/item/stack/tile/brass
buildstackamount = 1
/obj/structure/chair/stool/bar/bronze
name = "bronze bar stool"
desc = "A bronze bar stool with red silk for a pillow."
icon_state = "barbrass"
item_chair = /obj/item/chair/stool/bar/bronze
buildstacktype = /obj/item/stack/tile/bronze
buildstackamount = 1
/obj/structure/chair/stool/brass
name = "brass stool"
desc = "A brass stool with a silk top for comfort."
icon_state = "stoolbrass"
item_chair = /obj/item/chair/stool/brass
buildstacktype = /obj/item/stack/tile/brass
buildstackamount = 1
/obj/structure/chair/stool/bronze
name = "bronze stool"
desc = "A bronze stool with a silk top for comfort."
icon_state = "stoolbrass"
item_chair = /obj/item/chair/stool/bronze
buildstacktype = /obj/item/stack/tile/bronze
buildstackamount = 1
/obj/item/chair/stool/brass
name = "brass stool"
icon_state = "stoolbrass_toppled"
item_state = "stoolbrass"
origin_type = /obj/structure/chair/stool/brass
/obj/item/chair/stool/bar/brass
name = "brass bar stool"
icon_state = "barbrass_toppled"
item_state = "stoolbrass_bar"
origin_type = /obj/structure/chair/stool/bar/brass
/obj/item/chair/stool/bronze
name = "bronze stool"
icon_state = "stoolbrass_toppled"
item_state = "stoolbrass"
origin_type = /obj/structure/chair/stool/bronze
/obj/item/chair/stool/bar/bronze
name = "bronze bar stool"
icon_state = "barbrass_toppled"
item_state = "stoolbrass_bar"
origin_type = /obj/structure/chair/stool/bar/bronze
/////////////////////////////////
//End of Brass & Bronze stools!//
/////////////////////////////////
/obj/item/chair/stool/narsie_act()
return //sturdy enough to ignore a god
@@ -34,7 +34,8 @@
var/delivery_icon = "deliverycloset" //which icon to use when packagewrapped. null to be unwrappable.
var/anchorable = TRUE
var/icon_welded = "welded"
var/obj/item/electronics/airlock/lockerelectronics //Installed electronics
var/lock_in_use = FALSE //Someone is doing some stuff with the lock here, better not proceed further
/obj/structure/closet/Initialize(mapload)
. = ..()
@@ -42,47 +43,56 @@
PopulateContents()
if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents
take_contents()
if(secure)
lockerelectronics = new(src)
lockerelectronics.accesses = req_access
//USE THIS TO FILL IT, NOT INITIALIZE OR NEW
/obj/structure/closet/proc/PopulateContents()
return
/obj/structure/closet/Destroy()
dump_contents()
dump_contents(override = FALSE)
return ..()
/obj/structure/closet/update_icon()
cut_overlays()
if(!opened)
if(opened & icon_door_override)
add_overlay("[icon_door]_open")
layer = OBJ_LAYER
if(icon_door)
add_overlay("[icon_door]_door")
else
add_overlay("[icon_state]_door")
if(welded)
add_overlay(icon_welded)
if(secure && !broken)
if(locked)
add_overlay("locked")
else
add_overlay("unlocked")
return
else if(opened)
add_overlay("[icon_state]_open")
return
if(icon_door)
add_overlay("[icon_door]_door")
else
layer = BELOW_OBJ_LAYER
if(icon_door_override)
add_overlay("[icon_door]_open")
else
add_overlay("[icon_state]_open")
add_overlay("[icon_state]_door")
if(welded)
add_overlay("welded")
if(!secure)
return
if(broken)
add_overlay("off")
add_overlay("sparking")
else if(locked)
add_overlay("locked")
else
add_overlay("unlocked")
/obj/structure/closet/examine(mob/user)
..()
if(welded)
to_chat(user, "<span class='notice'>It's welded shut.</span>")
to_chat(user, "<span class='notice'>It's <b>welded</b> shut.</span>")
if(anchored)
to_chat(user, "<span class='notice'>It is <b>bolted</b> to the ground.</span>")
if(opened)
to_chat(user, "<span class='notice'>The parts are <b>welded</b> together.</span>")
else if(secure && !opened)
else if(broken)
to_chat(user, "<span class='notice'>The lock is <b>screwed</b> in.</span>")
else if(secure)
to_chat(user, "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"].</span>")
if(isliving(user))
var/mob/living/L = user
@@ -117,9 +127,37 @@
return FALSE
return TRUE
/obj/structure/closet/proc/dump_contents()
/obj/structure/closet/proc/can_lock(mob/living/user, var/check_access = TRUE) //set check_access to FALSE if you only need to check if a locker has a functional lock rather than access
if(!secure)
return FALSE
if(broken)
to_chat(user, "<span class='notice'>[src] is broken!</span>")
return FALSE
if(QDELETED(lockerelectronics) && !locked) //We want to be able to unlock it regardless of electronics, but only lockable with electronics
to_chat(user, "<span class='notice'>[src] is missing locker electronics!</span>")
return FALSE
if(!check_access)
return TRUE
if(allowed(user))
return TRUE
to_chat(user, "<span class='notice'>Access denied.</span>")
/obj/structure/closet/proc/togglelock(mob/living/user)
add_fingerprint(user)
if(opened)
return
if(!can_lock(user))
return
locked = !locked
user.visible_message("<span class='notice'>[user] [locked ? null : "un"]locks [src].</span>",
"<span class='notice'>You [locked ? null : "un"]lock [src].</span>")
update_icon()
/obj/structure/closet/proc/dump_contents(var/override = TRUE) //Override is for not revealing the locker electronics when you open the locker, for example
var/atom/L = drop_location()
for(var/atom/movable/AM in src)
if(AM == lockerelectronics && override)
continue
AM.forceMove(L)
if(throwing) // you keep some momentum when getting out of a thrown closet
step(AM, dir)
@@ -207,6 +245,73 @@
else
return open(user)
/obj/structure/closet/proc/bust_open()
welded = FALSE //applies to all lockers
locked = FALSE //applies to critter crates and secure lockers only
broken = TRUE //applies to secure lockers only
open()
/obj/structure/closet/proc/handle_lock_addition(mob/user, obj/item/electronics/airlock/E)
add_fingerprint(user)
if(lock_in_use)
to_chat(user, "<span class='notice'>Wait for work on [src] to be done first!</span>")
return
if(secure)
to_chat(user, "<span class='notice'>This locker already has a lock!</span>")
return
if(broken)
to_chat(user, "<span class='notice'><b>Unscrew</b> the broken lock first!</span>")
return
if(!istype(E))
return
user.visible_message("<span class='notice'>[user] begins installing a lock on [src]...</span>","<span class='notice'>You begin installing a lock on [src]...</span>")
lock_in_use = TRUE
playsound(loc, 'sound/items/screwdriver.ogg', 50, 1)
if(!do_after(user, 60, target = src))
lock_in_use = FALSE
return
lock_in_use = FALSE
to_chat(user, "<span class='notice'>You finish the lock on [src]!</span>")
E.forceMove(src)
lockerelectronics = E
req_access = E.accesses
secure = TRUE
update_icon()
return TRUE
/obj/structure/closet/proc/handle_lock_removal(mob/user, obj/item/screwdriver/S)
if(lock_in_use)
to_chat(user, "<span class='notice'>Wait for work on [src] to be done first!</span>")
return
if(locked)
to_chat(user, "<span class='notice'>Unlock it first!</span>")
return
if(!secure)
to_chat(user, "<span class='notice'>[src] doesn't have a lock that you can remove!</span>")
return
if(!istype(S))
return
var/brokenword = broken ? "broken " : null
user.visible_message("<span class='notice'>[user] begins removing the [brokenword]lock on [src]...</span>","<span class='notice'>You begin removing the [brokenword]lock on [src]...</span>")
playsound(loc, S.usesound, 50, 1)
lock_in_use = TRUE
if(!do_after(user, 100 * S.toolspeed, target = src))
lock_in_use = FALSE
return
to_chat(user, "<span class='notice'>You remove the [brokenword]lock from [src]!</span>")
if(!QDELETED(lockerelectronics))
lockerelectronics.add_fingerprint(user)
lockerelectronics.forceMove(user.loc)
lockerelectronics = null
req_access = null
secure = FALSE
broken = FALSE
locked = FALSE
lock_in_use = FALSE
update_icon()
return TRUE
/obj/structure/closet/deconstruct(disassembled = TRUE)
if(ispath(material_drop) && material_drop_amount && !(flags_1 & NODECONSTRUCT_1))
new material_drop(loc, material_drop_amount)
@@ -247,7 +352,11 @@
deconstruct(TRUE)
return
if(user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too
return
return TRUE
else if(istype(W, /obj/item/electronics/airlock))
handle_lock_addition(user, W)
else if(istype(W, /obj/item/screwdriver))
handle_lock_removal(user, W)
else if(istype(W, /obj/item/weldingtool) && can_weld_shut)
if(!W.tool_start_check(user, amount=0))
return
@@ -258,7 +367,7 @@
return
welded = !welded
after_weld(welded)
user.visible_message("<span class='notice'>[user] [welded ? "welds shut" : "unwelded"] \the [src].</span>",
user.visible_message("<span class='notice'>[user] [welded ? "welds shut" : "unwelds"] \the [src].</span>",
"<span class='notice'>You [welded ? "weld" : "unwelded"] \the [src] with \the [W].</span>",
"<span class='italics'>You hear welding.</span>")
update_icon()
@@ -401,20 +510,12 @@
if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
to_chat(user, "<span class='warning'>You fail to break out of [src]!</span>")
/obj/structure/closet/proc/bust_open()
welded = FALSE //applies to all lockers
locked = FALSE //applies to critter crates and secure lockers only
broken = TRUE //applies to secure lockers only
open()
/obj/structure/closet/AltClick(mob/user)
..()
if(!user.canUseTopic(src, BE_CLOSE) || !isturf(loc))
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)
return
else
togglelock(user)
togglelock(user)
/obj/structure/closet/CtrlShiftClick(mob/living/user)
if(!HAS_TRAIT(user, TRAIT_SKITTISH))
@@ -423,20 +524,6 @@
return
dive_into(user)
/obj/structure/closet/proc/togglelock(mob/living/user, silent)
if(secure && !broken)
if(allowed(user))
if(iscarbon(user))
add_fingerprint(user)
locked = !locked
user.visible_message("<span class='notice'>[user] [locked ? null : "un"]locks [src].</span>",
"<span class='notice'>You [locked ? null : "un"]lock [src].</span>")
update_icon()
else if(!silent)
to_chat(user, "<span class='notice'>Access Denied</span>")
else if(secure && broken)
to_chat(user, "<span class='warning'>\The [src] is broken!</span>")
/obj/structure/closet/emag_act(mob/user)
if(secure && !broken)
user.visible_message("<span class='warning'>Sparks fly from [src]!</span>",
@@ -445,6 +532,9 @@
playsound(src, "sparks", 50, 1)
broken = TRUE
locked = FALSE
if(!QDELETED(lockerelectronics))
qdel(lockerelectronics)
lockerelectronics = null
update_icon()
/obj/structure/closet/get_remote_view_fullscreens(mob/user)
@@ -458,16 +548,19 @@
if (!(. & EMP_PROTECT_CONTENTS))
for(var/obj/O in src)
O.emp_act(severity)
if(secure && !broken && !(. & EMP_PROTECT_SELF))
if(prob(50 / severity))
locked = !locked
update_icon()
if(prob(20 / severity) && !opened)
if(!locked)
open()
else
req_access = list()
req_access += pick(get_all_accesses())
if(!secure || broken)
return ..()
if(prob(50 / severity))
locked = !locked
update_icon()
if(prob(20 / severity) && !opened)
if(!locked)
open()
else
req_access = list()
req_access += pick(get_all_accesses())
if(!QDELETED(lockerelectronics))
lockerelectronics.accesses = req_access
/obj/structure/closet/contents_explosion(severity, target)
for(var/atom/A in contents)
@@ -49,6 +49,12 @@
return 1
return 0
/obj/structure/closet/body_bag/handle_lock_addition()
return
/obj/structure/closet/body_bag/handle_lock_removal()
return
/obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location)
. = ..()
if(over_object == usr && Adjacent(usr) && (in_range(src, usr) || usr.contents.Find(src)))
@@ -57,6 +57,11 @@
I.alpha = 0
animate(I, pixel_z = 32, alpha = 255, time = 5, easing = ELASTIC_EASING)
/obj/structure/closet/cardboard/handle_lock_addition() //Whoever heard of a lockable cardboard box anyway
return
/obj/structure/closet/cardboard/handle_lock_removal()
return
/obj/structure/closet/cardboard/metal
name = "large metal box"
@@ -358,3 +358,8 @@
new /obj/item/clothing/shoes/workboots/mining(src)
new /obj/item/storage/backpack/satchel/explorer(src)
/obj/structure/closet/coffin/handle_lock_addition()
return
/obj/structure/closet/coffin/handle_lock_removal()
return
@@ -4,6 +4,18 @@
req_access = list(ACCESS_ALL_PERSONAL_LOCKERS)
var/registered_name = null
/obj/structure/closet/secure_closet/personal/examine(mob/user)
..()
if(registered_name)
to_chat(user, "<span class='notice'>The display reads, \"Owned by [registered_name]\".</span>")
/obj/structure/closet/secure_closet/personal/check_access(obj/item/card/id/I)
. = ..()
if(!I || !istype(I))
return
if(registered_name == I.registered_name)
return TRUE
/obj/structure/closet/secure_closet/personal/PopulateContents()
..()
if(prob(50))
@@ -33,21 +45,21 @@
/obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params)
var/obj/item/card/id/I = W.GetID()
if(istype(I))
if(broken)
to_chat(user, "<span class='danger'>It appears to be broken.</span>")
return
if(!I || !I.registered_name)
return
if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name)))
//they can open all lockers, or nobody owns this, or they own this locker
locked = !locked
update_icon()
if(!registered_name)
registered_name = I.registered_name
desc = "Owned by [I.registered_name]."
else
to_chat(user, "<span class='danger'>Access Denied.</span>")
else
if(!I || !istype(I))
return ..()
if(!can_lock(user, FALSE)) //Can't do anything if there isn't a lock!
return
if(I.registered_name && !registered_name)
to_chat(user, "<span class='notice'>You claim [src].</span>")
registered_name = I.registered_name
else
..()
/obj/structure/closet/secure_closet/personal/handle_lock_addition() //If lock construction is successful we don't care what access the electronics had, so we override it
if(..())
req_access = list(ACCESS_ALL_PERSONAL_LOCKERS)
lockerelectronics.accesses = req_access
/obj/structure/closet/secure_closet/personal/handle_lock_removal()
if(..())
registered_name = null
@@ -54,6 +54,12 @@
manifest = null
update_icon()
/obj/structure/closet/crate/handle_lock_addition()
return
/obj/structure/closet/crate/handle_lock_removal()
return
/obj/structure/closet/crate/proc/tear_manifest(mob/user)
to_chat(user, "<span class='notice'>You tear the manifest off of [src].</span>")
playsound(src, 'sound/items/poster_ripped.ogg', 75, 1)
+1 -1
View File
@@ -79,4 +79,4 @@
var/n_color = input(H, "Choose your [garment_type]'\s color.", "Character Preference", default_color) as color|null
if(!n_color || !H.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return default_color
return n_color
return sanitize_hexcolor(n_color, include_crunch= TRUE)
@@ -0,0 +1,174 @@
#define BREAKER_ANIMATION_LENGTH 32
#define BREAKER_SLAT_RAISED 1
#define BREAKER_SLAT_MOVING 2
#define BREAKER_SLAT_DROPPED 3
#define BREAKER_ACTIVATE_DELAY 30
#define BREAKER_WRENCH_DELAY 10
#define BREAKER_ACTION_INUSE 5
#define BREAKER_ACTION_WRENCH 6
/obj/structure/femur_breaker
name = "femur breaker"
desc = "A large structure used to break the femurs of traitors and treasonists."
icon = 'icons/obj/femur_breaker.dmi'
icon_state = "breaker_raised"
can_buckle = TRUE
anchored = TRUE
density = TRUE
max_buckled_mobs = 1
buckle_lying = TRUE
buckle_prevents_pull = TRUE
layer = ABOVE_MOB_LAYER
var/slat_status = BREAKER_SLAT_RAISED
var/current_action = 0 // What's currently happening to the femur breaker
/obj/structure/femur_breaker/examine(mob/user)
..()
var/msg = ""
msg += "It is [anchored ? "secured to the floor." : "unsecured."]<br/>"
if (slat_status == BREAKER_SLAT_RAISED)
msg += "The breaker slat is in a neutral position."
else
msg += "The breaker slat is lowered, and must be raised."
if (LAZYLEN(buckled_mobs))
msg += "<br/>"
msg += "Someone appears to be strapped in. You can help them unbuckle, or activate the femur breaker."
to_chat(user, msg)
return msg
/obj/structure/femur_breaker/attack_hand(mob/user)
add_fingerprint(user)
// Currently being used
if (current_action)
return
switch (slat_status)
if (BREAKER_SLAT_MOVING)
return
if (BREAKER_SLAT_DROPPED)
slat_status = BREAKER_SLAT_MOVING
icon_state = "breaker_raise"
addtimer(CALLBACK(src, .proc/raise_slat), BREAKER_ANIMATION_LENGTH)
return
if (BREAKER_SLAT_RAISED)
if (LAZYLEN(buckled_mobs))
if (user.a_intent == INTENT_HARM)
user.visible_message("<span class='warning'>[user] begins to pull the lever!</span>",
"<span class='warning'>You begin to the pull the lever.</span>")
current_action = BREAKER_ACTION_INUSE
if (do_after(user, BREAKER_ACTIVATE_DELAY, target = src) && slat_status == BREAKER_SLAT_RAISED)
current_action = 0
slat_status = BREAKER_SLAT_MOVING
icon_state = "breaker_drop"
drop_slat(user)
else
current_action = 0
else
var/mob/living/carbon/human/H = buckled_mobs[1]
if (H)
H.regenerate_icons()
unbuckle_all_mobs()
else //HERE
slat_status = BREAKER_SLAT_DROPPED
icon_state = "breaker_drop"
/obj/structure/femur_breaker/proc/damage_leg(mob/living/carbon/human/H)
H.say("AAAAAAAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHHH!!", forced = "femur broken")
H.apply_damage(150, BRUTE, pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
/obj/structure/femur_breaker/proc/raise_slat()
slat_status = BREAKER_SLAT_RAISED
icon_state = "breaker_raised"
/obj/structure/femur_breaker/proc/drop_slat(mob/user)
if (buckled_mobs.len)
var/mob/living/carbon/human/H = buckled_mobs[1]
if (!H)
return
playsound(src, 'sound/effects/femur_breaker.ogg', 100, FALSE)
H.Stun(BREAKER_ANIMATION_LENGTH)
addtimer(CALLBACK(src, .proc/damage_leg, H), BREAKER_ANIMATION_LENGTH, TIMER_UNIQUE)
log_combat(user, H, "femur broke", src)
slat_status = BREAKER_SLAT_DROPPED
icon_state = "breaker"
/obj/structure/femur_breaker/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
if (!anchored)
to_chat(usr, "<span class='warning'>The [src] needs to be wrenched to the floor!</span>")
return FALSE
if (!istype(M, /mob/living/carbon/human))
to_chat(usr, "<span class='warning'>It doesn't look like [M.p_they()] can fit into this properly!</span>")
return FALSE
if (slat_status != BREAKER_SLAT_RAISED)
to_chat(usr, "<span class='warning'>The femur breaker must be in its neutral position before buckling someone in!</span>")
return FALSE
return ..(M, force, FALSE)
/obj/structure/femur_breaker/post_buckle_mob(mob/living/M)
if (!istype(M, /mob/living/carbon/human))
return
var/mob/living/carbon/human/H = M
if (H.dna)
if (H.dna.species)
var/datum/species/S = H.dna.species
if (!istype(S))
unbuckle_all_mobs()
else
unbuckle_all_mobs()
else
unbuckle_all_mobs()
..()
/obj/structure/femur_breaker/can_be_unfasten_wrench(mob/user, silent)
if (LAZYLEN(buckled_mobs))
if (!silent)
to_chat(user, "<span class='warning'>Can't unfasten, someone's strapped in!</span>")
return FAILED_UNFASTEN
if (current_action)
return FAILED_UNFASTEN
return ..()
/obj/structure/femur_breaker/wrench_act(mob/living/user, obj/item/I)
if (current_action)
return
current_action = BREAKER_ACTION_WRENCH
if (do_after(user, BREAKER_WRENCH_DELAY, target = src))
current_action = 0
default_unfasten_wrench(user, I, 0)
setDir(SOUTH)
return TRUE
else
current_action = 0
#undef BREAKER_ANIMATION_LENGTH
#undef BREAKER_SLAT_RAISED
#undef BREAKER_SLAT_MOVING
#undef BREAKER_SLAT_DROPPED
#undef BREAKER_ACTIVATE_DELAY
#undef BREAKER_WRENCH_DELAY
#undef BREAKER_ACTION_INUSE
#undef BREAKER_ACTION_WRENCH
+1 -1
View File
@@ -272,7 +272,7 @@
return 0
if(ishuman(C) && (lube&NO_SLIP_WHEN_WALKING))
var/mob/living/carbon/human/H = C
if(!H.sprinting && H.getStaminaLoss() >= 20)
if(!H.sprinting && H.getStaminaLoss() <= 20)
return 0
if(!(lube&SLIDE_ICE))
to_chat(C, "<span class='notice'>You slipped[ O ? " on the [O.name]" : ""]!</span>")
+2 -2
View File
@@ -15,9 +15,9 @@
H.real_name = random_unique_name(H.gender)
H.name = H.real_name
H.underwear = random_underwear(H.gender)
H.undie_color = random_color()
H.undie_color = random_short_color()
H.undershirt = random_undershirt(H.gender)
H.shirt_color = random_color()
H.shirt_color = random_short_color()
H.skin_tone = random_skin_tone()
H.hair_style = random_hair_style(H.gender)
H.facial_hair_style = random_facial_hair_style(H.gender)
+2 -2
View File
@@ -1882,14 +1882,14 @@
return
var/mob/M = locate(href_list["CentComReply"])
usr.client.admin_headset_message(M, "CentCom")
usr.client.admin_headset_message(M, RADIO_CHANNEL_CENTCOM)
else if(href_list["SyndicateReply"])
if(!check_rights(R_ADMIN))
return
var/mob/M = locate(href_list["SyndicateReply"])
usr.client.admin_headset_message(M, "Syndicate")
usr.client.admin_headset_message(M, RADIO_CHANNEL_SYNDICATE)
else if(href_list["HeadsetMessage"])
if(!check_rights(R_ADMIN))
+7 -7
View File
@@ -62,7 +62,7 @@
.["laws"] = borg.laws ? borg.laws.get_law_list(include_zeroth = TRUE) : list()
.["channels"] = list()
for (var/k in GLOB.radiochannels)
if (k == "Common")
if (k == RADIO_CHANNEL_COMMON)
continue
.["channels"] += list(list("name" = k, "installed" = (k in borg.radio.channels)))
.["cell"] = borg.cell ? list("missing" = FALSE, "maxcharge" = borg.cell.maxcharge, "charge" = borg.cell.charge) : list("missing" = TRUE, "maxcharge" = 1, "charge" = 0)
@@ -164,15 +164,15 @@
if (channel in borg.radio.channels) // We're removing a channel
if (!borg.radio.keyslot) // There's no encryption key. This shouldn't happen but we can cope
borg.radio.channels -= channel
if (channel == "Syndicate")
if (channel == RADIO_CHANNEL_SYNDICATE)
borg.radio.syndie = FALSE
else if (channel == "CentCom")
else if (channel == RADIO_CHANNEL_CENTCOM)
borg.radio.independent = FALSE
else
borg.radio.keyslot.channels -= channel
if (channel == "Syndicate")
if (channel == RADIO_CHANNEL_SYNDICATE)
borg.radio.keyslot.syndie = FALSE
else if (channel == "CentCom")
else if (channel == RADIO_CHANNEL_CENTCOM)
borg.radio.keyslot.independent = FALSE
message_admins("[key_name_admin(user)] removed the [channel] radio channel from [ADMIN_LOOKUPFLW(borg)].")
log_admin("[key_name(user)] removed the [channel] radio channel from [key_name(borg)].")
@@ -180,9 +180,9 @@
if (!borg.radio.keyslot) // Assert that an encryption key exists
borg.radio.keyslot = new (borg.radio)
borg.radio.keyslot.channels[channel] = 1
if (channel == "Syndicate")
if (channel == RADIO_CHANNEL_SYNDICATE)
borg.radio.keyslot.syndie = TRUE
else if (channel == "CentCom")
else if (channel == RADIO_CHANNEL_CENTCOM)
borg.radio.keyslot.independent = TRUE
message_admins("[key_name_admin(user)] added the [channel] radio channel to [ADMIN_LOOKUPFLW(borg)].")
log_admin("[key_name(user)] added the [channel] radio channel to [key_name(borg)].")
+1 -1
View File
@@ -65,7 +65,7 @@
return
if (!sender)
sender = input("Who is the message from?", "Sender") as null|anything in list("CentCom","Syndicate")
sender = input("Who is the message from?", "Sender") as null|anything in list(RADIO_CHANNEL_CENTCOM,RADIO_CHANNEL_SYNDICATE)
if(!sender)
return
@@ -353,7 +353,7 @@
/datum/antagonist/changeling/greet()
if (you_are_greet)
to_chat(owner.current, "<span class='boldannounce'>You are [changelingID], a changeling! You have absorbed and taken the form of a human.</span>")
to_chat(owner.current, "<span class='boldannounce'>Use say \":g message\" to communicate with your fellow changelings.</span>")
to_chat(owner.current, "<span class='boldannounce'>Use say \"[MODE_TOKEN_CHANGELING] message\" to communicate with your fellow changelings.</span>")
to_chat(owner.current, "<b>You must complete the following tasks:</b>")
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE)
@@ -1,8 +1,8 @@
//HIVEMIND COMMUNICATION (:g)
//HIVEMIND COMMUNICATION //MODE_TOKEN_CHANGELING / :g
/obj/effect/proc_holder/changeling/hivemind_comms
name = "Hivemind Communication"
desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings."
helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives."
helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives." //MODE_TOKEN_CHANGELING needs to be manually updated here.
dna_cost = 1
chemical_cost = -1
action_icon = 'icons/mob/actions/actions_xeno.dmi'
@@ -20,7 +20,7 @@
..()
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
changeling.changeling_speak = 1
to_chat(user, "<i><font color=#800080>Use say \":g message\" to communicate with the other changelings.</font></i>")
to_chat(user, "<i><font color=#800080>Use say \"[MODE_TOKEN_CHANGELING] message\" to communicate with the other changelings.</font></i>")
var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new
if(!changeling.has_sting(S1))
changeling.purchasedpowers+=S1
@@ -56,8 +56,8 @@
if(M.lingcheck() == LINGHIVE_LING)
to_chat(M, "<i><font color=#800080>We can sense a foreign presence in the hivemind...</font></i>")
target.mind.linglink = 1
target.say(":g AAAAARRRRGGGGGHHHHH!!")
to_chat(target, "<font color=#800040><span class='boldannounce'>You can now communicate in the changeling hivemind, say \":g message\" to communicate!</span>")
target.say("[MODE_TOKEN_CHANGELING] AAAAARRRRGGGGGHHHHH!!")
to_chat(target, "<font color=#800040><span class='boldannounce'>You can now communicate in the changeling hivemind, say \"[MODE_TOKEN_CHANGELING] message\" to communicate!</span>")
target.reagents.add_reagent("salbutamol", 40) // So they don't choke to death while you interrogate them
sleep(1800)
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]", "[i]"))
@@ -244,6 +244,7 @@
lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL | NOBLUDGEON
slot_flags = NONE
flags_1 = NONE
w_class = WEIGHT_CLASS_HUGE
ammo_type = /obj/item/ammo_casing/magic/tentacle
@@ -230,24 +230,23 @@
/obj/effect/proc_holder/changeling/sting/LSD
name = "Hallucination Sting"
desc = "Causes terror in the target."
helptext = "We evolve the ability to sting a target with a powerful hallucinogenic chemical. The target does not notice they have been stung, and the effect begins after a few seconds."
desc = "Causes terror in the target and deals a minor amount of toxin damage."
helptext = "We evolve the ability to sting a target with a powerful toxic hallucinogenic chemical. The target does not notice they have been stung, and the effect begins instantaneously. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat."
sting_icon = "sting_lsd"
chemical_cost = 10
dna_cost = 1
loudness = 1
action_icon = 'icons/mob/actions/actions_changeling.dmi'
action_icon_state = "ling_sting_lsd"
action_background_icon_state = "bg_ling"
/obj/effect/proc_holder/changeling/sting/LSD/sting_action(mob/user, mob/living/carbon/target)
/obj/effect/proc_holder/changeling/sting/LSD/sting_action(mob/user, mob/target)
log_combat(user, target, "stung", "LSD sting")
addtimer(CALLBACK(src, .proc/hallucination_time, target), rand(100,200))
if(target.reagents)
target.reagents.add_reagent("regenerative_materia", 5)
target.reagents.add_reagent("mindbreaker", 5)
return TRUE
/obj/effect/proc_holder/changeling/sting/LSD/proc/hallucination_time(mob/living/carbon/target)
if(target)
target.hallucination = max(90, target.hallucination)
/obj/effect/proc_holder/changeling/sting/cryo
name = "Cryogenic Sting"
desc = "We silently sting a human with a cocktail of chemicals that freeze them."
@@ -133,6 +133,9 @@
return FALSE
if(!uses)
return FALSE
if(!do_teleport(A, get_turf(linked_gateway), channel = TELEPORT_CHANNEL_CULT, forced = TRUE))
visible_message("<span class='warning'>[A] bounces off [src]!</span>")
return FALSE
if(isliving(A))
var/mob/living/user = A
to_chat(user, "<span class='warning'><b>You pass through [src] and appear elsewhere!</b></span>")
@@ -141,7 +144,6 @@
playsound(linked_gateway, 'sound/effects/empulse.ogg', 50, 1)
transform = matrix() * 1.5
linked_gateway.transform = matrix() * 1.5
A.forceMove(get_turf(linked_gateway))
if(!no_cost)
uses = max(0, uses - 1)
linked_gateway.uses = max(0, linked_gateway.uses - 1)
@@ -67,6 +67,7 @@
name = "replicant manacles"
desc = "Heavy manacles made out of freezing-cold metal. It looks like brass, but feels much more solid."
icon_state = "brass_manacles"
item_state = "brass_manacles"
item_flags = DROPDEL
/obj/item/restraints/handcuffs/clockwork/dropped(mob/user)

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