Merge pull request #2 from Citadel-Station-13/master

Updating fork.
This commit is contained in:
Neri
2017-10-04 16:13:04 -07:00
committed by GitHub
64 changed files with 809 additions and 221 deletions
+2 -1
View File
@@ -6,7 +6,8 @@
#define PLANE_SPACE -95
#define PLANE_SPACE_PARALLAX -90
#define GAME_PLANE 0
#define GAME_PLANE -1
#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals
#define SPACE_LAYER 1.8
#define ABOVE_SPACE_LAYER 1.9
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
+6 -3
View File
@@ -1,4 +1,4 @@
// /tg/station 13 server tools API v3.1
// /tg/station 13 server tools API v3.1.0.1
//CONFIGURATION
//use this define if you want to do configuration outside of this file
@@ -21,6 +21,8 @@
#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]")
//Notify current in-game administrators of a string `event`
#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event)
//The current amount of connected clients
#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len
#endif
//Required hooks:
@@ -62,7 +64,7 @@
//IMPLEMENTATION
#define SERVICE_API_VERSION_STRING "3.1.0.0"
#define SERVICE_API_VERSION_STRING "3.1.0.1"
#define REBOOT_MODE_NORMAL 0
#define REBOOT_MODE_HARD 1
@@ -78,12 +80,13 @@
#define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown"
#define SERVICE_CMD_WORLD_ANNOUNCE "world_announce"
#define SERVICE_CMD_LIST_CUSTOM "list_custom_commands"
#define SERVICE_CMD_API_COMPATIBLE "api_compat"
#define SERVICE_CMD_PLAYER_COUNT "client_count"
#define SERVICE_CMD_PARAM_KEY "serviceCommsKey"
#define SERVICE_CMD_PARAM_COMMAND "command"
#define SERVICE_CMD_PARAM_SENDER "sender"
#define SERVICE_CMD_PARAM_CUSTOM "custom"
#define SERVICE_CMD_API_COMPATIBLE "api_compat"
#define SERVICE_JSON_PARAM_HELPTEXT "help_text"
#define SERVICE_JSON_PARAM_ADMINONLY "admin_only"
+4
View File
@@ -313,11 +313,15 @@
inv.hud = src
inv_slots[inv.slot_id] = inv
inv.update_icon()
update_locked_slots()
/datum/hud/human/update_locked_slots()
if(!mymob)
return
var/mob/living/carbon/human/H = mymob
if(!istype(H) || !H.dna.species)
return
var/datum/species/S = H.dna.species
for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory))
if(inv.slot_id)
@@ -74,6 +74,10 @@ GLOBAL_PROTECT(config_dir)
if(copytext(L, 1, 2) == "#")
continue
var/lockthis = copytext(L, 1, 2) == "@"
if(lockthis)
L = copytext(L, 2)
var/pos = findtext(L, " ")
var/entry = null
var/value = null
@@ -96,6 +100,9 @@ GLOBAL_PROTECT(config_dir)
log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.")
continue
if(lockthis)
E.protection |= CONFIG_ENTRY_LOCKED
var/validated = E.ValidateAndSet(value)
if(!validated)
log_config("Failed to validate setting \"[value]\" for [entry]")
+47
View File
@@ -591,3 +591,50 @@
var/mob/M = owner
var/datum/language_holder/H = M.get_language_holder()
H.open_language_menu(usr)
/datum/action/innate/dash
name = "Dash"
desc = "Teleport to the targeted location."
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "jetboot"
var/charged = TRUE
var/charge_rate = 250
var/mob/living/carbon/human/holder
var/obj/item/dashing_item
var/dash_sound = 'sound/magic/blink.ogg'
var/recharge_sound = 'sound/magic/charge.ogg'
var/beam_effect = "blur"
var/phasein = /obj/effect/temp_visual/dir_setting/ninja/phase
var/phaseout = /obj/effect/temp_visual/dir_setting/ninja/phase/out
/datum/action/innate/dash/Grant(mob/user, obj/dasher)
. = ..()
dashing_item = dasher
holder = user
/datum/action/innate/dash/IsAvailable()
if(charged)
return TRUE
else
return FALSE
/datum/action/innate/dash/Activate()
dashing_item.attack_self(holder) //Used to toggle dash behavior in the dashing item
/datum/action/innate/dash/proc/Teleport(mob/user, atom/target)
var/turf/T = get_turf(target)
if(target in view(user.client.view, get_turf(user)))
var/obj/spot1 = new phaseout(get_turf(user), user.dir)
user.forceMove(T)
playsound(T, dash_sound, 25, 1)
var/obj/spot2 = new phasein(get_turf(user), user.dir)
spot1.Beam(spot2,beam_effect,time=20)
charged = FALSE
holder.update_action_buttons_icon()
addtimer(CALLBACK(src, .proc/charge), charge_rate)
/datum/action/innate/dash/proc/charge()
charged = TRUE
holder.update_action_buttons_icon()
playsound(dashing_item, recharge_sound, 50, 1)
to_chat(holder, "<span class='warning'>[dashing_item] is ready for another jaunt.</span>")
+28
View File
@@ -384,3 +384,31 @@
if(islist(owner.stun_absorption) && owner.stun_absorption["blooddrunk"])
owner.stun_absorption -= "blooddrunk"
/datum/status_effect/sword_spin
id = "Bastard Sword Spin"
duration = 50
tick_interval = 8
alert_type = null
/datum/status_effect/sword_spin/on_apply()
owner.visible_message("<span class='danger'>[owner] begins swinging the sword with inhuman strength!</span>")
var/oldcolor = owner.color
owner.color = "#ff0000"
owner.add_stun_absorption("bloody bastard sword", duration, 2, "doesn't even flinch as the sword's power courses through them!", "You shrug off the stun!", " glowing with a blazing red aura!")
owner.spin(duration,1)
animate(owner, color = oldcolor, time = duration, easing = EASE_IN)
addtimer(CALLBACK(owner, /atom/proc/update_atom_colour), duration)
playsound(owner, 'sound/weapons/fwoosh.wav', 75, 0)
return ..()
/datum/status_effect/sword_spin/tick()
playsound(owner, 'sound/weapons/fwoosh.wav', 75, 0)
var/obj/item/slashy
slashy = owner.get_active_held_item()
for(var/mob/living/M in orange(1,owner))
slashy.attack(M, owner)
/datum/status_effect/sword_spin/on_remove()
owner.visible_message("<span class='warning'>[owner]'s inhuman strength dissipates and the sword's runes grow cold!</span>")
+164
View File
@@ -72,6 +72,170 @@
if(is_servant_of_ratvar(C) && C.reagents)
C.reagents.add_reagent("heparin", 1)
/obj/item/twohanded/required/cult_bastard
name = "bloody bastard sword"
desc = "An enormous sword used by Nar-Sien cultists to rapidly harvest the souls of non-believers."
w_class = WEIGHT_CLASS_HUGE
block_chance = 50
throwforce = 20
force = 35
armour_penetration = 45
throw_speed = 1
throw_range = 3
sharpness = IS_SHARP
light_color = "#ff0000"
attack_verb = list("cleaved", "slashed", "torn", "hacked", "ripped", "diced", "carved")
icon_state = "cultbastard"
item_state = "cultbastard"
hitsound = 'sound/weapons/bladeslice.ogg'
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
inhand_x_dimension = 64
inhand_y_dimension = 64
actions_types = list()
flags_2 = SLOWS_WHILE_IN_HAND_2
var/datum/action/innate/dash/cult/jaunt
var/datum/action/innate/cult/spin2win/linked_action
var/spinning = FALSE
var/spin_cooldown = 250
var/list/shards = list()
var/dash_toggled = TRUE
/obj/item/twohanded/required/cult_bastard/Initialize()
. = ..()
set_light(4)
jaunt = new(src)
linked_action = new(src)
/obj/item/twohanded/required/cult_bastard/can_be_pulled(user)
return FALSE
/obj/item/twohanded/required/cult_bastard/attack_self(mob/user)
dash_toggled = !dash_toggled
if(dash_toggled)
to_chat(loc, "<span class='notice'>You raise the [src] and prepare to jaunt with it.</span>")
else
to_chat(loc, "<span class='notice'>You lower the [src] and prepare to swing it normally.</span>")
/obj/item/twohanded/required/cult_bastard/pickup(mob/living/user)
. = ..()
if(!iscultist(user))
if(!is_servant_of_ratvar(user))
to_chat(user, "<span class='cultlarge'>\"I wouldn't advise that.\"</span>")
to_chat(user, "<span class='warning'>An overwhelming sense of nausea overpowers you!</span>")
user.Dizzy(80)
user.Knockdown(30)
return
else
to_chat(user, "<span class='cultlarge'>\"One of Ratvar's toys is trying to play with things [user.p_they()] shouldn't. Cute.\"</span>")
to_chat(user, "<span class='userdanger'>A horrible force yanks at your arm!</span>")
user.emote("scream")
user.apply_damage(30, BRUTE, pick("l_arm", "r_arm"))
user.Knockdown(50)
return
jaunt.Grant(user, src)
linked_action.Grant(user, src)
user.update_icons()
/obj/item/twohanded/required/cult_bastard/dropped(mob/user)
. = ..()
linked_action.Remove(user)
jaunt.Remove(user)
user.update_icons()
/obj/item/twohanded/required/cult_bastard/IsReflect()
if(spinning)
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return TRUE
else
..()
/obj/item/twohanded/required/cult_bastard/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(prob(final_block_chance))
if(attack_type == PROJECTILE_ATTACK)
owner.visible_message("<span class='danger'>[owner] deflects [attack_text] with [src]!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 100, 1)
return TRUE
else
playsound(src, 'sound/weapons/parry.ogg', 75, 1)
owner.visible_message("<span class='danger'>[owner] parries [attack_text] with [src]!</span>")
return TRUE
return FALSE
/obj/item/twohanded/required/cult_bastard/afterattack(atom/target, mob/user, proximity, click_parameters)
. = ..()
if(dash_toggled && jaunt.IsAvailable())
jaunt.Teleport(user, target)
return
if(!proximity)
return
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.stat != CONSCIOUS)
var/obj/item/device/soulstone/SS = new /obj/item/device/soulstone(src)
SS.attack(H, user)
shards += SS
return
if(istype(target, /obj/structure/constructshell) && contents.len)
var/obj/item/device/soulstone/SS = contents[1]
if(istype(SS) && SS.transfer_soul("CONSTRUCT",target,user))
qdel(SS)
/datum/action/innate/dash/cult
name = "Rend the Veil"
desc = "Use the sword to shear open the flimsy fabric of this reality and teleport to your target."
icon_icon = 'icons/mob/actions/actions_cult.dmi'
button_icon_state = "phaseshift"
dash_sound = 'sound/magic/enter_blood.ogg'
recharge_sound = 'sound/magic/exit_blood.ogg'
beam_effect = "sendbeam"
phasein = /obj/effect/temp_visual/dir_setting/cult/phase
phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out
/datum/action/innate/dash/cult/IsAvailable()
if(iscultist(holder) && charged)
return TRUE
else
return FALSE
/datum/action/innate/cult/spin2win
name = "Geometer's Fury"
desc = "You draw on the power of the sword's ancient runes, spinning it wildly around you as you become immune to most attacks."
background_icon_state = "bg_demon"
button_icon_state = "sintouch"
var/cooldown = 0
var/mob/living/carbon/human/holder
var/obj/item/twohanded/required/cult_bastard/sword
/datum/action/innate/cult/spin2win/Grant(mob/user, obj/bastard)
. = ..()
sword = bastard
holder = user
/datum/action/innate/cult/spin2win/IsAvailable()
if(iscultist(holder) && cooldown <= world.time)
return TRUE
else
return FALSE
/datum/action/innate/cult/spin2win/Activate()
cooldown = world.time + sword.spin_cooldown
holder.changeNext_move(50)
holder.apply_status_effect(/datum/status_effect/sword_spin)
sword.spinning = TRUE
sword.block_chance = 100
sword.slowdown += 1.5
addtimer(CALLBACK(src, .proc/stop_spinning), 50)
holder.update_action_buttons_icon()
/datum/action/innate/cult/spin2win/proc/stop_spinning()
sword.spinning = FALSE
sword.block_chance = 50
sword.slowdown -= 1.5
sleep(sword.spin_cooldown)
holder.update_action_buttons_icon()
/obj/item/restraints/legcuffs/bola/cult
name = "nar'sien bola"
+9 -3
View File
@@ -100,15 +100,21 @@
if(cooldowntime > world.time)
to_chat(user, "<span class='cultitalic'>The magic in [src] is weak, it will be ready to use again in [DisplayTimeText(cooldowntime - world.time)].</span>")
return
var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Nar-Sien Hardsuit")
var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Bastard Sword")
var/pickedtype
switch(choice)
if("Shielded Robe")
pickedtype = /obj/item/clothing/suit/hooded/cultrobes/cult_shield
if("Flagellant's Robe")
pickedtype = /obj/item/clothing/suit/hooded/cultrobes/berserker
if("Nar-Sien Hardsuit")
pickedtype = /obj/item/clothing/suit/space/hardsuit/cult
if("Bastard Sword")
if((world.time - SSticker.round_start_time) >= 12000)
pickedtype = /obj/item/twohanded/required/cult_bastard
else
cooldowntime = 12000 - (world.time - SSticker.round_start_time)
to_chat(user, "<span class='cultitalic'>The forge fires are not yet hot enough for this weapon, give it another [DisplayTimeText(cooldowntime - world.time)].</span>")
cooldowntime = 0
return
if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time)
cooldowntime = world.time + 2400
var/obj/item/N = new pickedtype(get_turf(src))
-1
View File
@@ -199,7 +199,6 @@
SSticker.mode.cult -= A.mind
SSticker.mode.update_cult_icons_removed(A.mind)
qdel(T)
user.drop_item()
qdel(src)
else
to_chat(user, "<span class='userdanger'>Creation failed!</span>: The soul stone is empty! Go kill someone!")
+73 -8
View File
@@ -73,6 +73,7 @@ MASS SPECTROMETER
origin_tech = "magnets=1;biotech=1"
var/mode = 1
var/scanmode = 0
var/advanced = FALSE
/obj/item/device/healthanalyzer/attack_self(mob/user)
if(!scanmode)
@@ -97,7 +98,7 @@ MASS SPECTROMETER
user.visible_message("<span class='notice'>[user] has analyzed [M]'s vitals.</span>")
if(scanmode == 0)
healthscan(user, M, mode)
healthscan(user, M, mode, advanced)
else if(scanmode == 1)
chemscan(user, M)
@@ -105,7 +106,7 @@ MASS SPECTROMETER
// Used by the PDA medical scanner too
/proc/healthscan(mob/living/user, mob/living/M, mode = 1)
/proc/healthscan(mob/living/user, mob/living/M, mode = 1, advanced = FALSE)
if(user.incapacitated() || user.eye_blind)
return
//Damage specifics
@@ -115,8 +116,8 @@ MASS SPECTROMETER
var/brute_loss = M.getBruteLoss()
var/mob_status = (M.stat == DEAD ? "<span class='alert'><b>Deceased</b></span>" : "<b>[round(M.health/M.maxHealth,0.01)*100] % healthy</b>")
if(M.status_flags & FAKEDEATH)
mob_status = "<span class='alert'>Deceased</span>"
if(M.status_flags & FAKEDEATH && !advanced)
mob_status = "<span class='alert'><b>Deceased</b></span>"
oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss
if(ishuman(M))
@@ -141,19 +142,77 @@ MASS SPECTROMETER
if(oxy_loss > 10)
to_chat(user, "\t<span class='info'><span class='alert'>[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected.</span>")
if(tox_loss > 10)
to_chat(user, "\t<span class='alert'>[tox_loss > 50 ? "Critical" : "Dangerous"] amount of toxins detected.</span>")
to_chat(user, "\t<span class='alert'>[tox_loss > 50 ? "Severe" : "Minor"] amount of toxin damage detected.</span>")
if(M.getStaminaLoss())
to_chat(user, "\t<span class='alert'>Subject appears to be suffering from fatigue.</span>")
if(advanced)
to_chat(user, "\t<span class='info'>Fatigue Level: [M.getStaminaLoss()]%.</span>")
if (M.getCloneLoss())
to_chat(user, "\t<span class='alert'>Subject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.</span>")
if (M.reagents && M.reagents.get_reagent_amount("epinephrine"))
to_chat(user, "\t<span class='info'>Bloodstream analysis located [M.reagents.get_reagent_amount("epinephrine")] units of rejuvenation chemicals.</span>")
if(advanced)
to_chat(user, "\t<span class='info'>Cellular Damage Level: [M.getCloneLoss()].</span>")
if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain))
to_chat(user, "\t<span class='alert'>Subject brain function is non-existent.</span>")
else if (M.getBrainLoss() >= 60)
to_chat(user, "\t<span class='alert'>Severe brain damage detected. Subject likely to have mental retardation.</span>")
else if (M.getBrainLoss() >= 10)
to_chat(user, "\t<span class='alert'>Brain damage detected. Subject may have had a concussion.</span>")
if(advanced)
to_chat(user, "\t<span class='info'>Brain Activity Level: [100 - M.getBrainLoss()]%.</span>")
if (M.radiation)
to_chat(user, "\t<span class='alert'>Subject is irradiated.</span>")
if(advanced)
to_chat(user, "\t<span class='info'>Radiation Level: [M.radiation]%.</span>")
if(advanced && M.hallucinating())
to_chat(user, "\t<span class='info'>Subject is hallucinating.</span>")
//Eyes and ears
if(advanced)
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/organ/ears/ears = C.getorganslot("ears")
to_chat(user, "\t<span class='info'><b>==EAR STATUS==</b></span>")
if(istype(ears))
var/healthy = TRUE
if(C.disabilities & DEAF)
healthy = FALSE
to_chat(user, "\t<span class='alert'>Subject is genetically deaf.</span>")
else
if(ears.ear_damage)
to_chat(user, "\t<span class='alert'>Subject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage.</span>")
healthy = FALSE
if(ears.deaf)
to_chat(user, "\t<span class='alert'>Subject is [ears.ear_damage > UNHEALING_EAR_DAMAGE ? "permanently ": "temporarily "] deaf.</span>")
healthy = FALSE
if(healthy)
to_chat(user, "\t<span class='info'>Healthy.</span>")
else
to_chat(user, "\t<span class='alert'>Subject does not have ears.</span>")
var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
to_chat(user, "\t<span class='info'><b>==EYE STATUS==</b></span>")
if(istype(eyes))
var/healthy = TRUE
if(C.disabilities & BLIND)
to_chat(user, "\t<span class='alert'>Subject is blind.</span>")
healthy = FALSE
if(C.disabilities & NEARSIGHT)
to_chat(user, "\t<span class='alert'>Subject is nearsighted.</span>")
healthy = FALSE
if(eyes.eye_damage > 30)
to_chat(user, "\t<span class='alert'>Subject has severe eye damage.</span>")
healthy = FALSE
else if(eyes.eye_damage > 20)
to_chat(user, "\t<span class='alert'>Subject has significant eye damage.</span>")
healthy = FALSE
else if(eyes.eye_damage)
to_chat(user, "\t<span class='alert'>Subject has minor eye damage.</span>")
healthy = FALSE
if(healthy)
to_chat(user, "\t<span class='info'>Healthy.</span>")
else
to_chat(user, "\t<span class='alert'>Subject does not have eyes.</span>")
if(ishuman(M))
var/mob/living/carbon/human/H = M
@@ -177,7 +236,7 @@ MASS SPECTROMETER
to_chat(user, "<span class='info'>Body temperature: [round(M.bodytemperature-T0C,0.1)] &deg;C ([round(M.bodytemperature*1.8-459.67,0.1)] &deg;F)</span>")
// Time of death
if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
if(M.tod && (M.stat == DEAD || ((M.status_flags & FAKEDEATH) && !advanced)))
to_chat(user, "<span class='info'>Time of Death:</span> [M.tod]")
var/tdelta = round(world.time - M.timeofdeath)
if(tdelta < (DEFIB_TIME_LIMIT * 10))
@@ -251,6 +310,12 @@ MASS SPECTROMETER
if(0)
to_chat(usr, "The scanner no longer shows limb damage.")
/obj/item/device/healthanalyzer/advanced
name = "advanced health analyzer"
icon_state = "health_adv"
desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy."
origin_tech = "magnets=3;biotech=3"
advanced = TRUE
/obj/item/device/analyzer
desc = "A hand-held environmental scanner which reports current gas levels."
+2 -2
View File
@@ -335,8 +335,8 @@
/obj/item/nullrod/carp
name = "carp-sie plushie"
desc = "An adorable stuffed toy that resembles the god of all carp. The teeth look pretty sharp. Activate it to receive the blessing of Carp-Sie."
icon = 'icons/obj/toy.dmi'
icon_state = "carpplushie"
icon = 'icons/obj/plushes.dmi'
icon_state = "carpplush"
item_state = "carp_plushie"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
+18
View File
@@ -156,6 +156,24 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
var/unholy2clean = A.reagents.get_reagent_amount("unholywater")
A.reagents.del_reagent("unholywater")
A.reagents.add_reagent("holywater",unholy2clean)
if(istype(A, /obj/item/twohanded/required/cult_bastard))
var/obj/item/twohanded/required/cult_bastard/sword = A
to_chat(user, "<span class='notice'>You begin to exorcise [sword].</span>")
playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1)
if(do_after(user, 40, target = sword))
playsound(src,'sound/effects/pray_chaplain.ogg',60,1)
for(var/obj/item/device/soulstone/SS in sword.shards)
SS.usability = TRUE
for(var/mob/living/simple_animal/shade/EX in SS)
SSticker.mode.remove_cultist(EX.mind, 1, 0)
EX.icon_state = "ghost1"
EX.name = "Purified [EX.name]"
SS.release_shades(user)
qdel(SS)
new /obj/item/nullrod/claymore(get_turf(sword))
user.visible_message("<span class='notice'>[user] has purified the [sword]!!</span>")
qdel(sword)
/obj/item/storage/book/bible/booze
desc = "To be applied to the head repeatedly."
@@ -21,6 +21,10 @@
var/buildstacktype = /obj/item/stack/sheet/metal
var/buildstackamount = 2
/obj/structure/bed/examine(mob/user)
..()
to_chat(user, "<span class='notice'>It's held together by a couple of <b>bolts</b>.</span>")
/obj/structure/bed/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(buildstacktype)
@@ -1,6 +1,6 @@
/obj/structure/chair
name = "chair"
desc = "You sit in this. Either by will or force.\n<span class='notice'>Drag your sprite to sit in the chair. Alt-click to rotate it clockwise.</span>"
desc = "You sit in this. Either by will or force."
icon = 'icons/obj/chairs.dmi'
icon_state = "chair"
anchored = TRUE
@@ -14,6 +14,14 @@
var/item_chair = /obj/item/chair // if null it can't be picked up
layer = OBJ_LAYER
/obj/structure/chair/examine(mob/user)
..()
to_chat(user, "<span class='notice'>It's held together by a couple of <b>bolts</b>.</span>")
if(!has_buckled_mobs())
to_chat(user, "<span class='notice'>Drag your sprite to sit in it. Alt-click to rotate.</span>")
else
to_chat(user, "<span class='notice'>Alt-click to rotate.</span>")
/obj/structure/chair/Initialize()
. = ..()
if(!anchored) //why would you put these on the shuttle?
@@ -140,7 +148,7 @@
/obj/structure/chair/comfy
name = "comfy chair"
desc = "It looks comfy.\n<span class='notice'>Alt-click to rotate it clockwise.</span>"
desc = "It looks comfy."
icon_state = "comfychair"
color = rgb(255,255,255)
resistance_flags = FLAMMABLE
@@ -76,8 +76,12 @@
/obj/structure/closet/examine(mob/user)
..()
if(welded)
to_chat(user, "<span class='notice'>It's welded shut.</span>")
if(anchored)
to_chat(user, "It is anchored to the ground.")
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)
to_chat(user, "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"].</span>")
@@ -453,4 +457,4 @@
/obj/structure/closet/return_temperature()
return
return
@@ -1,93 +1,94 @@
/obj/structure/closet/secure_closet/medical1
name = "medicine closet"
desc = "Filled to the brim with medical junk."
icon_state = "med"
/obj/structure/closet/secure_closet/medical1
name = "medicine closet"
desc = "Filled to the brim with medical junk."
icon_state = "med"
req_access = list(ACCESS_MEDICAL)
/obj/structure/closet/secure_closet/medical1/PopulateContents()
..()
new /obj/item/reagent_containers/glass/beaker(src)
new /obj/item/reagent_containers/glass/beaker(src)
new /obj/item/reagent_containers/dropper(src)
new /obj/item/reagent_containers/dropper(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/storage/box/syringes(src)
new /obj/item/reagent_containers/glass/bottle/toxin(src)
new /obj/item/reagent_containers/glass/bottle/morphine(src)
new /obj/item/reagent_containers/glass/bottle/morphine(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/glass/bottle/epinephrine(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/glass/bottle/charcoal(src)
new /obj/item/storage/box/rxglasses(src)
/obj/structure/closet/secure_closet/medical2
name = "anesthetic closet"
desc = "Used to knock people out."
/obj/structure/closet/secure_closet/medical1/PopulateContents()
..()
new /obj/item/reagent_containers/glass/beaker(src)
new /obj/item/reagent_containers/glass/beaker(src)
new /obj/item/reagent_containers/dropper(src)
new /obj/item/reagent_containers/dropper(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/storage/box/syringes(src)
new /obj/item/reagent_containers/glass/bottle/toxin(src)
new /obj/item/reagent_containers/glass/bottle/morphine(src)
new /obj/item/reagent_containers/glass/bottle/morphine(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/glass/bottle/epinephrine(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/glass/bottle/charcoal(src)
new /obj/item/storage/box/rxglasses(src)
/obj/structure/closet/secure_closet/medical2
name = "anesthetic closet"
desc = "Used to knock people out."
req_access = list(ACCESS_SURGERY)
/obj/structure/closet/secure_closet/medical2/PopulateContents()
..()
for(var/i in 1 to 3)
new /obj/item/tank/internals/anesthetic(src)
for(var/i in 1 to 3)
new /obj/item/clothing/mask/breath/medical(src)
/obj/structure/closet/secure_closet/medical3
name = "medical doctor's locker"
/obj/structure/closet/secure_closet/medical2/PopulateContents()
..()
for(var/i in 1 to 3)
new /obj/item/tank/internals/anesthetic(src)
for(var/i in 1 to 3)
new /obj/item/clothing/mask/breath/medical(src)
/obj/structure/closet/secure_closet/medical3
name = "medical doctor's locker"
req_access = list(ACCESS_SURGERY)
icon_state = "med_secure"
/obj/structure/closet/secure_closet/medical3/PopulateContents()
..()
new /obj/item/device/radio/headset/headset_med(src)
new /obj/item/defibrillator/loaded(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/clothing/glasses/hud/health(src)
return
/obj/structure/closet/secure_closet/CMO
name = "\proper chief medical officer's locker"
icon_state = "med_secure"
/obj/structure/closet/secure_closet/medical3/PopulateContents()
..()
new /obj/item/device/radio/headset/headset_med(src)
new /obj/item/defibrillator/loaded(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/clothing/glasses/hud/health(src)
return
/obj/structure/closet/secure_closet/CMO
name = "\proper chief medical officer's locker"
req_access = list(ACCESS_CMO)
icon_state = "cmo"
/obj/structure/closet/secure_closet/CMO/PopulateContents()
..()
new /obj/item/clothing/neck/cloak/cmo(src)
new /obj/item/storage/backpack/duffelbag/med(src)
new /obj/item/clothing/suit/bio_suit/cmo(src)
new /obj/item/clothing/head/bio_hood/cmo(src)
new /obj/item/clothing/suit/toggle/labcoat/cmo(src)
new /obj/item/clothing/under/rank/chief_medical_officer(src)
new /obj/item/clothing/shoes/sneakers/brown (src)
new /obj/item/cartridge/cmo(src)
new /obj/item/device/radio/headset/heads/cmo(src)
new /obj/item/device/megaphone/command(src)
new /obj/item/defibrillator/compact/loaded(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/device/assembly/flash/handheld(src)
new /obj/item/reagent_containers/hypospray/CMO(src)
new /obj/item/device/autosurgeon/cmo(src)
new /obj/item/door_remote/chief_medical_officer(src)
/obj/structure/closet/secure_closet/animal
name = "animal control"
icon_state = "cmo"
/obj/structure/closet/secure_closet/CMO/PopulateContents()
..()
new /obj/item/clothing/neck/cloak/cmo(src)
new /obj/item/storage/backpack/duffelbag/med(src)
new /obj/item/clothing/suit/bio_suit/cmo(src)
new /obj/item/clothing/head/bio_hood/cmo(src)
new /obj/item/clothing/suit/toggle/labcoat/cmo(src)
new /obj/item/clothing/under/rank/chief_medical_officer(src)
new /obj/item/clothing/shoes/sneakers/brown (src)
new /obj/item/cartridge/cmo(src)
new /obj/item/device/radio/headset/heads/cmo(src)
new /obj/item/device/megaphone/command(src)
new /obj/item/defibrillator/compact/loaded(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/device/healthanalyzer/advanced(src)
new /obj/item/device/assembly/flash/handheld(src)
new /obj/item/reagent_containers/hypospray/CMO(src)
new /obj/item/device/autosurgeon/cmo(src)
new /obj/item/door_remote/chief_medical_officer(src)
/obj/structure/closet/secure_closet/animal
name = "animal control"
req_access = list(ACCESS_SURGERY)
/obj/structure/closet/secure_closet/animal/PopulateContents()
..()
new /obj/item/device/assembly/signaler(src)
for(var/i in 1 to 3)
new /obj/item/device/electropack(src)
/obj/structure/closet/secure_closet/chemical
name = "chemical closet"
desc = "Store dangerous chemicals in here."
icon_door = "chemical"
/obj/structure/closet/secure_closet/chemical/PopulateContents()
..()
new /obj/item/storage/box/pillbottles(src)
new /obj/item/storage/box/pillbottles(src)
/obj/structure/closet/secure_closet/animal/PopulateContents()
..()
new /obj/item/device/assembly/signaler(src)
for(var/i in 1 to 3)
new /obj/item/device/electropack(src)
/obj/structure/closet/secure_closet/chemical
name = "chemical closet"
desc = "Store dangerous chemicals in here."
icon_door = "chemical"
/obj/structure/closet/secure_closet/chemical/PopulateContents()
..()
new /obj/item/storage/box/pillbottles(src)
new /obj/item/storage/box/pillbottles(src)
+8 -1
View File
@@ -1,5 +1,5 @@
/obj/structure/grille
desc = "A flimsy lattice of metal rods, with screws to secure it to the floor."
desc = "A flimsy framework of metal rods."
name = "grille"
icon = 'icons/obj/structures.dmi'
icon_state = "grille"
@@ -17,6 +17,13 @@
var/grille_type = null
var/broken_type = /obj/structure/grille/broken
/obj/structure/grille/examine(mob/user)
..()
if(anchored)
to_chat(user, "<span class='notice'>It's secured in place with <b>screws</b>. The rods look like they could be <b>cut</b> through.</span>")
if(!anchored)
to_chat(user, "<span class='notice'>The anchoring screws are <i>unscrewed</i>. The rods look like they could be <b>cut</b> through.</span>")
/obj/structure/grille/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
switch(the_rcd.mode)
if(RCD_DECONSTRUCT)
+10
View File
@@ -16,6 +16,13 @@
smooth = SMOOTH_MORE
// flags_1 = CONDUCT_1
/obj/structure/lattice/examine(mob/user)
..()
deconstruction_hints(user)
/obj/structure/lattice/proc/deconstruction_hints(mob/user)
to_chat(user, "<span class='notice'>The rods look like they could be <b>cut</b>. There's space for more <i>rods</i> or a <i>tile</i>.</span>")
/obj/structure/lattice/Initialize(mapload)
. = ..()
for(var/obj/structure/lattice/LAT in loc)
@@ -79,6 +86,9 @@
smooth = SMOOTH_TRUE
canSmoothWith = null
/obj/structure/lattice/catwalk/deconstruction_hints(mob/user)
to_chat(user, "<span class='notice'>The supporting rods look like they could be <b>cut</b>.</span>")
/obj/structure/lattice/catwalk/ratvar_act()
new /obj/structure/lattice/catwalk/clockwork(loc)
+18 -1
View File
@@ -34,6 +34,13 @@
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/table, /obj/structure/table/reinforced)
/obj/structure/table/examine(mob/user)
..()
deconstruction_hints(user)
/obj/structure/table/proc/deconstruction_hints(mob/user)
to_chat(user, "<span class='notice'>The top is <b>screwed</b> on, but the main <b>bolts</b> are also visible.</span>")
/obj/structure/table/Initialize()
. = ..()
for(var/obj/structure/table/T in src.loc)
@@ -285,7 +292,7 @@
*/
/obj/structure/table/reinforced
name = "reinforced table"
desc = "A reinforced version of the four legged table, much harder to simply deconstruct."
desc = "A reinforced version of the four legged table."
icon = 'icons/obj/smooth_structures/reinforced_table.dmi'
icon_state = "r_table"
deconstruction_ready = 0
@@ -295,6 +302,12 @@
integrity_failure = 50
armor = list(melee = 10, bullet = 30, laser = 30, energy = 100, bomb = 20, bio = 0, rad = 0, fire = 80, acid = 70)
/obj/structure/table/reinforced/deconstruction_hints(mob/user)
if(deconstruction_ready)
to_chat(user, "<span class='notice'>The top cover has been <i>welded</i> loose and the main frame's <b>bolts</b> are exposed.</span>")
else
to_chat(user, "<span class='notice'>The top cover is firmly <b>welded</b> on.</span>")
/obj/structure/table/reinforced/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
@@ -405,6 +418,10 @@
pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.
max_integrity = 20
/obj/structure/rack/examine(mob/user)
..()
to_chat(user, "<span class='notice'>It's held together by a couple of <b>bolts</b>.</span>")
/obj/structure/rack/CanPass(atom/movable/mover, turf/target)
if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!|
return 1
+2 -2
View File
@@ -161,10 +161,10 @@
broken = 0
burnt = 0
if(user && !silent)
to_chat(user, "<span class='danger'>You remove the broken plating.</span>")
to_chat(user, "<span class='notice'>You remove the broken plating.</span>")
else
if(user && !silent)
to_chat(user, "<span class='danger'>You remove the floor tile.</span>")
to_chat(user, "<span class='notice'>You remove the floor tile.</span>")
if(floor_tile && make_tile)
new floor_tile(src)
return make_plating()
+13 -4
View File
@@ -8,10 +8,15 @@
*/
/turf/open/floor/wood
desc = "Stylish dark wood."
icon_state = "wood"
floor_tile = /obj/item/stack/tile/wood
broken_states = list("wood-broken", "wood-broken2", "wood-broken3", "wood-broken4", "wood-broken5", "wood-broken6", "wood-broken7")
/turf/open/floor/wood/examine(mob/user)
..()
to_chat(user, "<span class='notice'>There's a few <b>screws</b> and a <b>small crack</b> visible.</span>")
/turf/open/floor/wood/attackby(obj/item/C, mob/user, params)
if(..())
return
@@ -42,16 +47,16 @@
broken = 0
burnt = 0
if(user && !silent)
to_chat(user, "<span class='danger'>You remove the broken planks.</span>")
to_chat(user, "<span class='notice'>You remove the broken planks.</span>")
else
if(make_tile)
if(user && !silent)
to_chat(user, "<span class='danger'>You unscrew the planks.</span>")
to_chat(user, "<span class='notice'>You unscrew the planks.</span>")
if(floor_tile)
new floor_tile(src)
else
if(user && !silent)
to_chat(user, "<span class='danger'>You forcefully pry off the planks, destroying them in the process.</span>")
to_chat(user, "<span class='notice'>You forcefully pry off the planks, destroying them in the process.</span>")
return make_plating()
/turf/open/floor/wood/cold
@@ -78,7 +83,7 @@
if(istype(C, /obj/item/shovel) && params)
new ore_type(src)
new ore_type(src) //Make some sand if you shovel grass
user.visible_message("<span class='notice'>[user] digs up [src].</span>", "<span class='notice'>You [src.turfverb] [src].</span>")
user.visible_message("[user] digs up [src].", "<span class='notice'>You [src.turfverb] [src].</span>")
playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1)
make_plating()
if(..())
@@ -143,6 +148,10 @@
canSmoothWith = list(/turf/open/floor/carpet)
flags_1 = NONE
/turf/open/floor/carpet/examine(mob/user)
..()
to_chat(user, "<span class='notice'>There's a <b>small crack</b> on the edge of it.</span>")
/turf/open/floor/carpet/Initialize()
. = ..()
update_icon()
@@ -12,6 +12,10 @@
var/can_modify_colour = TRUE
/turf/open/floor/light/examine(mob/user)
..()
to_chat(user, "<span class='notice'>There's a <b>small crack</b> on the edge of it.</span>")
/turf/open/floor/light/Initialize()
. = ..()
update_icon()
@@ -4,6 +4,10 @@
broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5")
burnt_states = list("floorscorched1", "floorscorched2")
/turf/open/floor/plasteel/examine(mob/user)
..()
to_chat(user, "<span class='notice'>There's a <b>small crack</b> on the edge of it.</span>")
/turf/open/floor/plasteel/update_icon()
if(!..())
return 0
@@ -12,6 +12,13 @@
icon_state = "plating"
intact = FALSE
/turf/open/floor/plating/examine(mob/user)
..()
if(broken || burnt)
to_chat(user, "<span class='notice'>It looks like the dents could be <i>welded</i> smooth.</span>")
return
to_chat(user, "<span class='notice'>There are few attachment holes for a new <i>tile</i> or reinforcement <i>rods</i>.</span>")
/turf/open/floor/plating/Initialize()
if (!broken_states)
broken_states = list("platingdmg1", "platingdmg2", "platingdmg3")
@@ -193,7 +193,7 @@
var/list/L = list(45)
if(IsOdd(dir2angle(dir))) // We're going at an angle and we want thick angled tunnels.
L += -45
L -= 45
// Expand the edges of our tunnel
for(var/edge_angle in L)
@@ -1,11 +1,16 @@
/turf/open/floor/engine
name = "reinforced floor"
desc = "Extremely sturdy."
icon_state = "engine"
thermal_conductivity = 0.025
heat_capacity = INFINITY
floor_tile = /obj/item/stack/rods
/turf/open/floor/engine/examine(mob/user)
..()
to_chat(user, "<span class='notice'>The reinforcement rods are <b>wrenched</b> firmly in place.</span>")
/turf/open/floor/engine/airless
initial_gas_mix = "TEMP=2.7"
+15
View File
@@ -25,6 +25,21 @@
var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/book) //Things allowed in the bookcase
/obj/structure/bookcase/examine(mob/user)
..()
if(!anchored)
to_chat(user, "<span class='notice'>The <i>bolts</i> on the bottom are unsecured.</span>")
if(anchored)
to_chat(user, "<span class='notice'>It's secured in place with <b>bolts</b>.</span>")
switch(state)
if(0)
to_chat(user, "<span class='notice'>There's a <b>small crack</b> visible on the back panel.</span>")
if(1)
to_chat(user, "<span class='notice'>There's space inside for a <i>wooden</i> shelf.</span>")
if(2)
to_chat(user, "<span class='notice'>There's a <b>small crack</b> visible on the shelf.</span>")
/obj/structure/bookcase/Initialize(mapload)
. = ..()
if(!mapload)
@@ -59,6 +59,7 @@
if(previewJob && !nude)
mannequin.job = previewJob.title
previewJob.equip(mannequin, TRUE)
mannequin.compile_overlays()
CHECK_TICK
preview_icon = icon('icons/effects/effects.dmi', "nothing")
preview_icon.Scale(48+32, 16+32)
+1 -1
View File
@@ -44,7 +44,7 @@
//Update the body's icon so it doesnt appear debrained anymore
C.update_hair()
/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0,no_id_transfer = FALSE)
/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0, no_id_transfer = FALSE)
..()
if((!gc_destroyed || (owner && !owner.gc_destroyed)) && !no_id_transfer)
transfer_identity(C)
@@ -250,6 +250,9 @@
if(health >= 0 && !(status_flags & FAKEDEATH))
if(lying)
if(buckled)
to_chat(M, "<span class='warning'>You need to unbuckle [src] first to do that!")
return
M.visible_message("<span class='notice'>[M] shakes [src] trying to get [p_them()] up!</span>", \
"<span class='notice'>You shake [src] trying to get [p_them()] up!</span>")
else if(check_zone(M.zone_selected) == "head")
@@ -4,6 +4,7 @@
voice_name = "Unknown"
icon = 'icons/mob/human.dmi'
icon_state = "caucasian_m"
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE
/mob/living/carbon/human/Initialize()
verbs += /mob/living/proc/mob_sleep
@@ -37,7 +37,7 @@
if(H.nutrition > NUTRITION_LEVEL_FULL)
H.nutrition = NUTRITION_LEVEL_FULL
if(light_amount > 0.2) //if there's enough light, heal
H.heal_overall_damage(0.05,0)
H.heal_overall_damage(0.75,0)
H.adjustOxyLoss(-0.5)
if(H.nutrition < NUTRITION_LEVEL_STARVING + 55)
@@ -1,3 +1,5 @@
#define HEART_RESPAWN_THRESHHOLD 40
/datum/species/shadow
// Humans cursed to stay in the darkness, lest their life forces drain. They regain health in shadow and die in light.
name = "???"
@@ -32,19 +34,14 @@
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store)
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOHUNGER,NO_DNA_COPY,NOTRANSSTING)
mutanteyes = /obj/item/organ/eyes/night_vision/nightmare
var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
mutant_organs = list(/obj/item/organ/heart/nightmare)
mutant_brain = /obj/item/organ/brain/nightmare
var/info_text = "You are a <span class='danger'>Nightmare</span>. The ability <span class='warning'>shadow walk</span> allows unlimited, unrestricted movement in the dark using. \
Your <span class='warning'>light eater</span> will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile."
var/info_text = "You are a <span class='danger'>Nightmare</span>. The ability <span class='warning'>shadow walk</span> allows unlimited, unrestricted movement in the dark while activated. \
Your <span class='warning'>light eater</span> will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile. If killed, you will eventually revive if left in darkness."
/datum/species/shadow/nightmare/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
var/obj/effect/proc_holder/spell/targeted/shadowwalk/SW = new
C.AddSpell(SW)
shadowwalk = SW
var/obj/item/light_eater/blade = new
C.put_in_hands(blade)
to_chat(C, "[info_text]")
C.real_name = "[pick(GLOB.nightmare_names)]"
@@ -53,11 +50,6 @@
C.mind.name = C.real_name
C.dna.real_name = C.real_name
/datum/species/shadow/nightmare/on_species_loss(mob/living/carbon/C)
. = ..()
if(shadowwalk)
C.RemoveSpell(shadowwalk)
/datum/species/shadow/nightmare/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
var/turf/T = H.loc
if(istype(T))
@@ -68,6 +60,93 @@
return -1
return 0
//Organs
/obj/item/organ/brain/nightmare
name = "tumorous mass"
desc = "A fleshy growth that was dug out of the skull of a Nightmare."
icon_state = "brain-x-d"
var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
/obj/item/organ/brain/nightmare/Insert(mob/living/carbon/M, special = 0)
..()
if(M.dna.species.id != "nightmare")
M.set_species(/datum/species/shadow/nightmare)
visible_message("<span class='warning'>[M] thrashes as [src] takes root in their body!</span>")
var/obj/effect/proc_holder/spell/targeted/shadowwalk/SW = new
M.AddSpell(SW)
shadowwalk = SW
/obj/item/organ/brain/nightmare/Remove(mob/living/carbon/M, special = 0)
if(shadowwalk)
M.RemoveSpell(shadowwalk)
..()
/obj/item/organ/heart/nightmare
name = "heart of darkness"
desc = "An alien organ that twists and writhes when exposed to light."
icon = 'icons/obj/surgery.dmi'
icon_state = "demon_heart-on"
color = "#1C1C1C"
var/respawn_progress = 0
var/obj/item/light_eater/blade
/obj/item/organ/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target)
if(M != user)
return ..()
user.visible_message("<span class='warning'>[user] raises [src] to their mouth and tears into it with their teeth!</span>", \
"<span class='danger'>[src] feels unnaturally cold in your hands. You raise [src] your mouth and devour it!</span>")
playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
user.visible_message("<span class='warning'>Blood erupts from [user]'s arm as it reforms into a weapon!</span>", \
"<span class='userdanger'>Icy blood pumps through your veins as your arm reforms itself!</span>")
user.temporarilyRemoveItemFromInventory(src, TRUE)
Insert(user)
/obj/item/organ/heart/nightmare/Insert(mob/living/carbon/M, special = 0)
..()
blade = new/obj/item/light_eater
M.put_in_hands(blade)
START_PROCESSING(SSobj, src)
/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
STOP_PROCESSING(SSobj, src)
respawn_progress = 0
if(blade)
QDEL_NULL(blade)
M.visible_message("<span class='warning'>\The [blade] disintegrates!</span>")
..()
/obj/item/organ/heart/nightmare/Stop()
return 0
/obj/item/organ/heart/nightmare/update_icon()
return //always beating visually
/obj/item/organ/heart/nightmare/process()
if(QDELETED(owner) || owner.stat != DEAD)
respawn_progress = 0
return
var/turf/T = get_turf(owner)
if(istype(T))
var/light_amount = T.get_lumcount()
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
respawn_progress++
playsound(owner,'sound/effects/singlebeat.ogg',40,1)
if(respawn_progress >= HEART_RESPAWN_THRESHHOLD)
owner.revive(full_heal = TRUE)
owner.visible_message("<span class='warning'>[owner] staggers to their feet!</span>")
playsound(owner, 'sound/hallucinations/far_noise.ogg', 50, 1)
respawn_progress = 0
//Weapon
/obj/item/light_eater
name = "light eater"
icon_state = "arm_blade"
@@ -113,3 +192,5 @@
visible_message("<span class='danger'>[O] is disintegrated by [src]!</span>")
O.burn()
playsound(src, 'sound/items/welder.ogg', 50, 1)
#undef HEART_RESPAWN_THRESHHOLD
@@ -37,6 +37,7 @@
C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
if(regen_cooldown < world.time)
C.heal_overall_damage(4,4)
C.adjustToxLoss(-4)
if(prob(4))
playsound(C, pick(spooks), 50, TRUE, 10)
if(C.InCritical())
@@ -86,7 +86,7 @@
if(istype(head, /obj/item/clothing/mask))
used_head_icon = 'icons/mob/mask.dmi'
var/mutable_appearance/head_overlay = head.build_worn_icon(state = head.icon_state, default_layer = DRONE_HEAD_LAYER, default_icon_file = used_head_icon)
head_overlay.pixel_y += -15
head_overlay.pixel_y -= 15
drone_overlays[DRONE_HEAD_LAYER] = head_overlay
@@ -62,6 +62,9 @@
return TRUE
if(isobj(the_target) && is_type_in_typecache(the_target, wanted_objects))
return TRUE
return FALSE
/mob/living/simple_animal/hostile/asteroid/gutlunch/Destroy()
+1 -1
View File
@@ -63,7 +63,7 @@
if(isnum(.)) //Numerical values of drained handle their feedback here, Alpha values handle it themselves (Research hacking)
if(.)
to_chat(H, "<span class='notice'>Gained <B>[.]</B> energy from \the [A].</span>")
to_chat(H, "<span class='notice'>Gained <B>[DisplayPower(.)]</B> of energy from [A].</span>")
else
to_chat(H, "<span class='danger'>\The [A] has run dry of power, you must find another source!</span>")
else
@@ -1,62 +1,65 @@
/obj/effect/accelerated_particle
name = "Accelerated Particles"
desc = "Small things moving very fast."
icon = 'icons/obj/machines/particle_accelerator.dmi'
icon_state = "particle"
/obj/effect/accelerated_particle
name = "Accelerated Particles"
desc = "Small things moving very fast."
icon = 'icons/obj/machines/particle_accelerator.dmi'
icon_state = "particle"
anchored = TRUE
density = FALSE
var/movement_range = 10
var/energy = 10
var/speed = 1
/obj/effect/accelerated_particle/weak
movement_range = 8
energy = 5
/obj/effect/accelerated_particle/strong
movement_range = 15
energy = 15
/obj/effect/accelerated_particle/powerful
movement_range = 20
energy = 50
/obj/effect/accelerated_particle/New(loc)
..()
addtimer(CALLBACK(src, .proc/move), 1)
var/movement_range = 10
var/energy = 10
var/speed = 1
/obj/effect/accelerated_particle/weak
movement_range = 8
energy = 5
/obj/effect/accelerated_particle/strong
movement_range = 15
energy = 15
/obj/effect/accelerated_particle/powerful
movement_range = 20
energy = 50
/obj/effect/accelerated_particle/New(loc)
..()
addtimer(CALLBACK(src, .proc/move), 1)
/obj/effect/accelerated_particle/Collide(atom/A)
if(A)
if(isliving(A))
toxmob(A)
else if(istype(A, /obj/machinery/the_singularitygen))
var/obj/machinery/the_singularitygen/S = A
S.energy += energy
else if(istype(A, /obj/singularity))
var/obj/singularity/S = A
S.energy += energy
/obj/effect/accelerated_particle/Crossed(atom/A)
if(isliving(A))
toxmob(A)
/obj/effect/accelerated_particle/ex_act(severity, target)
qdel(src)
/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
M.rad_act(energy*6)
/obj/effect/accelerated_particle/proc/move()
if(!step(src,dir))
forceMove(get_step(src,dir))
movement_range--
if(movement_range == 0)
qdel(src)
else
sleep(speed)
move()
if(A)
if(isliving(A))
toxmob(A)
else if(istype(A, /obj/machinery/the_singularitygen))
var/obj/machinery/the_singularitygen/S = A
S.energy += energy
else if(istype(A, /obj/singularity))
var/obj/singularity/S = A
S.energy += energy
else if(istype(A, /obj/structure/blob))
var/obj/structure/blob/B = A
B.take_damage(energy*0.6)
movement_range = 0
/obj/effect/accelerated_particle/Crossed(atom/A)
if(isliving(A))
toxmob(A)
/obj/effect/accelerated_particle/ex_act(severity, target)
qdel(src)
/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
M.rad_act(energy*6)
/obj/effect/accelerated_particle/proc/move()
if(!step(src,dir))
forceMove(get_step(src,dir))
movement_range--
if(movement_range == 0)
qdel(src)
else
sleep(speed)
move()
@@ -12,21 +12,17 @@
randomspread = FALSE
var/obj/item/device/transfer_valve/bomb
var/datum/gas_mixture/air1
var/datum/gas_mixture/air2
/obj/item/gun/blastcannon/New()
if(!pin)
pin = new
. = ..()
return ..()
/obj/item/gun/blastcannon/Destroy()
if(bomb)
qdel(bomb)
bomb = null
air1 = null
air2 = null
. = ..()
return ..()
/obj/item/gun/blastcannon/attack_self(mob/user)
if(bomb)
@@ -35,7 +31,7 @@
user.visible_message("<span class='warning'>[user] detaches the [bomb] from the [src]</span>")
bomb = null
update_icon()
. = ..(user)
return ..()
/obj/item/gun/blastcannon/update_icon()
if(bomb)
@@ -46,7 +42,6 @@
icon_state = initial(icon_state)
name = initial(name)
desc = initial(desc)
. = ..()
/obj/item/gun/blastcannon/attackby(obj/O, mob/user)
if(istype(O, /obj/item/device/transfer_valve))
@@ -59,20 +54,17 @@
return FALSE
user.visible_message("<span class='warning'>[user] attaches the [O] to the [src]!</span>")
bomb = O
O.loc = src
O.forceMove(src)
update_icon()
return TRUE
. = ..()
return ..()
/obj/item/gun/blastcannon/proc/calculate_bomb()
if(!istype(bomb)||!istype(bomb.tank_one)||!istype(bomb.tank_two))
return 0
air1 = bomb.tank_one.air_contents
air2 = bomb.tank_two.air_contents
var/datum/gas_mixture/temp
temp.volume = air1.volume + air2.volume
temp.merge(air1)
temp.merge(air2)
var/datum/gas_mixture/temp = new(60) //directional buff.
temp.merge(bomb.tank_one.air_contents.remove_ratio(1))
temp.merge(bomb.tank_two.air_contents.remove_ratio(2))
for(var/i in 1 to 6)
temp.react()
var/pressure = temp.return_pressure()
@@ -82,7 +74,7 @@
return (pressure/TANK_FRAGMENT_SCALE)
/obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params)
if((!bomb) || (target == user) || (target.loc == user) || (!target) || (target.loc == user.loc) || (target.loc in range(user, 2)) || (target in range(user, 2)))
if((!bomb) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2))
return ..()
var/power = calculate_bomb()
qdel(bomb)
@@ -90,13 +82,17 @@
var/heavy = power * 0.2
var/medium = power * 0.5
var/light = power
user.visible_message("<span class='danger'>[user] opens \the [bomb] on \his [src.name] and fires a blast wave at \the [target]!</span>","<span class='danger'>You open \the [bomb] on your [src.name] and fire a blast wave at \the [target]!</span>")
user.visible_message("<span class='danger'>[user] opens \the [bomb] on \his [name] and fires a blast wave at \the [target]!</span>","<span class='danger'>You open \the [bomb] on your [name] and fire a blast wave at \the [target]!</span>")
playsound(user, "explosion", 100, 1)
var/turf/starting = get_turf(user)
var/turf/targturf = get_turf(target)
var/area/A = get_area(user)
var/log_str = "Blast wave fired at [ADMIN_COORDJMP(starting)] ([A.name]) by [user.name]([user.ckey]) with power [heavy]/[medium]/[light]."
var/log_str = "Blast wave fired from [ADMIN_COORDJMP(starting)] ([A.name]) at [ADMIN_COORDJMP(targturf)] ([target.name]) by [user.name]([user.ckey]) with power [heavy]/[medium]/[light]."
message_admins(log_str)
log_game(log_str)
var/obj/item/projectile/blastwave/BW = new(loc, heavy, medium, light)
BW.preparePixelProjectile(target, get_turf(target), user, params, 0)
BW.fire()
/obj/item/projectile/blastwave
name = "blast wave"
@@ -109,6 +105,12 @@
var/lightr = 0
range = 150
/obj/item/projectile/blastwave/Initialize(mapload, _h, _m, _l)
heavyr = _h
mediumr = _m
lightr = _l
return ..()
/obj/item/projectile/blastwave/Range()
..()
if(heavyr)
+2 -2
View File
@@ -90,8 +90,6 @@
new impact_effect_type(target_loca, target, src)
return 0
var/mob/living/L = target
if(L.buckled && ismob(L.buckled))
L = L.buckled
if(blocked != 100) // not completely blocked
if(damage && L.blood_volume && damage_type == BRUTE)
var/splatter_dir = dir
@@ -178,6 +176,8 @@
var/mob/living/picked_mob = pick(mobs_list)
if(!prehit(picked_mob))
return FALSE
if(ismob(picked_mob.buckled))
picked_mob = picked_mob.buckled
picked_mob.bullet_act(src, def_zone)
qdel(src)
return TRUE
@@ -10,7 +10,7 @@
/obj/item/projectile/bullet/pellet/Range()
..()
damage += -0.75
damage -= 0.75
if(damage < 0)
qdel(src)
@@ -66,7 +66,7 @@
/obj/item/projectile/bullet/c38
name = ".38 bullet"
damage = 15
knockdown = 30
knockdown = 60
stamina = 50
// 10mm (Stechkin)
@@ -89,6 +89,8 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE)
return "No message set!"
SERVER_TOOLS_WORLD_ANNOUNCE(msg)
return "SUCCESS"
if(SERVICE_CMD_PLAYER_COUNT)
return "[SERVER_TOOLS_CLIENT_COUNT]"
if(SERVICE_CMD_LIST_CUSTOM)
return json_encode(ListServiceCustomCommands(FALSE))
else
@@ -25,8 +25,9 @@
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, 1, -1)
visible_message("<span class='boldwarning'>[user] melts into the shadows!</span>")
user.AdjustStun(-20, 0)
user.AdjustKnockdown(-20, 0)
user.SetStun(0, FALSE)
user.SetKnockdown(0, FALSE)
user.setStaminaLoss(0, 0)
var/obj/effect/dummy/shadow/S2 = new(get_turf(user.loc))
user.forceMove(S2)
S2.jaunter = user
+3
View File
@@ -44,9 +44,11 @@
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
actions_types = list(/datum/action/item_action/organ_action/use)
sight_flags = SEE_BLACKNESS
var/night_vision = TRUE
/obj/item/organ/eyes/night_vision/ui_action_click()
sight_flags = initial(sight_flags)
switch(lighting_alpha)
if (LIGHTING_PLANE_ALPHA_VISIBLE)
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
@@ -56,6 +58,7 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
else
lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
sight_flags &= ~SEE_BLACKNESS
owner.update_sight()
/obj/item/organ/eyes/night_vision/alien
+8
View File
@@ -1,3 +1,11 @@
# You can use the @ character at the beginning of a config option to lock it from being edited in-game
# Example usage:
# @SERVERNAME tgstation
# Which sets the SERVERNAME, and disallows admins from being able to change it using View Variables.
# @LOG_TWITTER 0
# Which explicitly disables LOG_TWITTER, as well as locking it.
# There are various options which are hard-locked for security reasons.
## Server name: This appears at the top of the screen in-game and in the BYOND hub. Uncomment and replace 'tgstation' with the name of your choice.
# SERVERNAME tgstation
@@ -0,0 +1,5 @@
author: "Robustin"
delete-after: True
changes:
- rscadd: "Blood cultists can now create a unique bastard sword at their forge"
- rscdel: "Blood cultists can no longer obtain a hardsuit from the forge"
@@ -0,0 +1,4 @@
author: "More Robust Than You"
delete-after: True
changes:
- balance: "Blobs now take damage from particle accelerators"
@@ -0,0 +1,4 @@
author: "CitadelStationBot"
delete-after: True
changes:
- balance: "The detectives gun has been restored from a system change that nerfed knockdown in general. We need to have a serious discussion about anti revolver hate in this community."
@@ -0,0 +1,4 @@
author: "XDTM"
delete-after: True
changes:
- rscadd: "The CMO now has an advanced health analyzer in his closet! It can give more precise readings on the non-standard damage types."
@@ -0,0 +1,4 @@
author: "Kor"
delete-after: True
changes:
- rscadd: "Nightmares now have mutant hearts and brains, with their own special properties when consumed or implanted in mobs. Experiment!"
@@ -0,0 +1,4 @@
author: "Daniel0Mclovin"
delete-after: True
changes:
- tweak: "Modify health regeneration from 0.05 to 0.75"
@@ -0,0 +1,4 @@
author: "Naksu"
delete-after: True
changes:
- bugfix: "Gutlunches will now once again look for gibs to eat."
@@ -0,0 +1,4 @@
author: "Raeschen"
delete-after: True
changes:
- rscadd: "FTL Milky Way added to music"
@@ -0,0 +1,4 @@
author: "CitadelStationBot"
delete-after: True
changes:
- spellcheck: "Beds, chairs, closets, grilles, lattices, catwalks, tables, racks, floors, plating and bookcases now show hints about constructing/deconstructing them."
@@ -0,0 +1,4 @@
author: "ShizCalev"
delete-after: True
changes:
- bugfix: "You now have to unbuckle a player PRIOR to shaking them up off a bed or resin nest."
Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
View File
@@ -20,3 +20,4 @@ sound/music/oceanman.ogg
sound/music/indeep.ogg
sound/music/goodbyemoonmen.ogg
sound/music/flytothemoon_otomatone.ogg
sound/music/milkyway.ogg