Merge branch 'master' into upstream-merge-31222
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -70,6 +70,8 @@
|
||||
#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175)
|
||||
#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250)
|
||||
|
||||
#define LIGHT_RANGE_FIRE 3 //How many tiles standard fires glow.
|
||||
|
||||
#define LIGHTING_PLANE_ALPHA_VISIBLE 255
|
||||
#define LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE 192
|
||||
#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 128 //For lighting alpha, small amounts lead to big changes. even at 128 its hard to figure out what is dark and what is light, at 64 you almost can't even tell.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -15,6 +15,7 @@ GLOBAL_LIST_INIT(carp_names, world.file2list("strings/names/carp.txt"))
|
||||
GLOBAL_LIST_INIT(golem_names, world.file2list("strings/names/golem.txt"))
|
||||
GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt"))
|
||||
GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt"))
|
||||
GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt"))
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt"))
|
||||
|
||||
@@ -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]")
|
||||
|
||||
@@ -8,10 +8,8 @@ CONFIG_DEF(string/autoadmin_rank) // the rank for autoadmins
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(string/servername) // server name (the name of the game window)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(string/serversqlname) // short form server name used for the DB
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(string/stationname) // station name (the name of the station in-game)
|
||||
|
||||
@@ -24,52 +22,38 @@ CONFIG_DEF(number/round_end_countdown) // Post round murder death kill countdown
|
||||
min_val = 0
|
||||
|
||||
CONFIG_DEF(flag/hub) // if the game appears on the hub or not
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_ooc) // log OOC channel
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_access) // log login/logout
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_say) // log client say
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_admin) // log admin actions
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_prayer) // log prayers
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_law) // log lawchanges
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_game) // log game events
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_vote) // log voting
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_whisper) // log client whisper
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_attack) // log attack messages
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_emote) // log emotes
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_adminchat) // log admin chat messages
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_pda) // log pda messages
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
@@ -85,14 +69,12 @@ CONFIG_DEF(number/vote_delay) // minimum time between voting sessions (decisecon
|
||||
CONFIG_DEF(number/vote_period) // length of voting period (deciseconds, default 1 minute)
|
||||
value = 600
|
||||
min_val = 0
|
||||
|
||||
|
||||
CONFIG_DEF(flag/default_no_vote) // vote does not default to nochange/norestart
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/no_dead_vote) // dead people can't vote
|
||||
|
||||
CONFIG_DEF(flag/allow_metadata) // Metadata is supported.
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/popup_admin_pm) // adminPMs to non-admins show in a pop-up 'reply' window when set
|
||||
|
||||
@@ -140,14 +122,12 @@ CONFIG_DEF(flag/admin_legacy_system) //Defines whether the server uses the legac
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(string/hostedby)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/norespawn)
|
||||
|
||||
CONFIG_DEF(flag/guest_jobban)
|
||||
|
||||
CONFIG_DEF(flag/usewhitelist)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(flag/ban_legacy_system) //Defines whether the server uses the legacy banning system with the files in /data or the SQL system.
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
@@ -171,29 +151,22 @@ CONFIG_DEF(flag/use_exp_restrictions_other)
|
||||
CONFIG_DEF(flag/use_exp_restrictions_admin_bypass)
|
||||
|
||||
CONFIG_DEF(string/server)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(string/banappeals)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(string/wikiurl)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
value = "http://www.tgstation13.org/wiki"
|
||||
|
||||
CONFIG_DEF(string/forumurl)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
value = "http://tgstation13.org/phpBB/index.php"
|
||||
|
||||
CONFIG_DEF(string/rulesurl)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
value = "http://www.tgstation13.org/wiki/Rules"
|
||||
|
||||
CONFIG_DEF(string/githuburl)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
value = "https://www.github.com/tgstation/-tg-station"
|
||||
|
||||
CONFIG_DEF(number/githubrepoid)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
value = null
|
||||
min_val = 0
|
||||
|
||||
@@ -233,7 +206,6 @@ CONFIG_DEF(flag/useircbot) //tgs2 support
|
||||
CONFIG_DEF(flag/automute_on) //enables automuting/spam prevention
|
||||
|
||||
CONFIG_DEF(string/panic_server_name)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val)
|
||||
return str_val != "\[Put the name here\]" && ..()
|
||||
@@ -290,7 +262,6 @@ CONFIG_DEF(string/extreme_popcap_message)
|
||||
value = "The server is currently serving a high number of users, find alternative servers."
|
||||
|
||||
CONFIG_DEF(flag/panic_bunker) // prevents people the server hasn't seen before from connecting
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
CONFIG_DEF(number/notify_new_player_age) // how long do we notify admins of a new player
|
||||
min_val = -1
|
||||
@@ -303,7 +274,6 @@ CONFIG_DEF(flag/irc_first_connection_alert) // do we notify the irc channel when
|
||||
CONFIG_DEF(flag/check_randomizer)
|
||||
|
||||
CONFIG_DEF(string/ipintel_email)
|
||||
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
|
||||
|
||||
/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val)
|
||||
return str_val != "ch@nge.me" && ..()
|
||||
@@ -315,17 +285,14 @@ CONFIG_DEF(number/ipintel_rating_bad)
|
||||
max_val = 1
|
||||
|
||||
CONFIG_DEF(number/ipintel_save_good)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
value = 12
|
||||
min_val = 0
|
||||
|
||||
CONFIG_DEF(number/ipintel_save_bad)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
value = 1
|
||||
min_val = 0
|
||||
|
||||
CONFIG_DEF(string/ipintel_domain)
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
value = "check.getipintel.net"
|
||||
|
||||
CONFIG_DEF(flag/aggressive_changelog)
|
||||
|
||||
@@ -591,7 +591,4 @@
|
||||
var/mob/M = owner
|
||||
var/datum/language_holder/H = M.get_language_holder()
|
||||
H.open_language_menu(usr)
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
>>>>>>> 380413f... Ports dash weapons to the dash datum (#31222)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/show_on_examine
|
||||
var/list/allowed_typecache
|
||||
var/last_inserted_type
|
||||
var/last_inserted_id
|
||||
var/last_amount_inserted
|
||||
var/last_insert_success
|
||||
var/datum/callback/precondition
|
||||
@@ -116,7 +117,7 @@
|
||||
if(!amt)
|
||||
return 0
|
||||
|
||||
insert_materials(S,amt)
|
||||
last_inserted_id = insert_materials(S,amt)
|
||||
last_inserted_type = S.type
|
||||
S.use(amt)
|
||||
last_amount_inserted = amt
|
||||
@@ -133,17 +134,22 @@
|
||||
if(!material_amount || !has_space(material_amount))
|
||||
return 0
|
||||
|
||||
insert_materials(I, multiplier)
|
||||
last_inserted_id = insert_materials(I, multiplier)
|
||||
last_inserted_type = I.type
|
||||
last_amount_inserted = material_amount
|
||||
return material_amount
|
||||
|
||||
/datum/component/material_container/proc/insert_materials(obj/item/I, multiplier = 1) //for internal usage only
|
||||
var/datum/material/M
|
||||
var/primary_mat
|
||||
var/max_mat_value = 0
|
||||
for(var/MAT in materials)
|
||||
M = materials[MAT]
|
||||
M.amount += I.materials[MAT] * multiplier
|
||||
total_amount += I.materials[MAT] * multiplier
|
||||
if(I.materials[MAT] > max_mat_value)
|
||||
primary_mat = MAT
|
||||
return primary_mat
|
||||
|
||||
//For consuming material
|
||||
//mats is a list of types of material to use and the corresponding amounts, example: list(MAT_METAL=100, MAT_GLASS=200)
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
|
||||
var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems)
|
||||
var/datum/language_holder/language_holder
|
||||
var/unconvertable = FALSE
|
||||
|
||||
/datum/mind/New(var/key)
|
||||
src.key = key
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -151,7 +151,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/maintenance/department/medical
|
||||
name = "Medbay Maintenance"
|
||||
icon_state = "asmaint"
|
||||
icon_state = "medbay_maint"
|
||||
|
||||
/area/maintenance/department/medical/morgue
|
||||
name = "Morgue Maintenance"
|
||||
icon_state = "morgue_maint"
|
||||
|
||||
/area/maintenance/department/science
|
||||
name = "Science Maintenance"
|
||||
|
||||
@@ -53,6 +53,8 @@ Credit where due:
|
||||
return FALSE
|
||||
if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to))
|
||||
return FALSE
|
||||
if(M.mind.unconvertable)
|
||||
return FALSE
|
||||
else
|
||||
return FALSE
|
||||
if(iscultist(M) || isconstruct(M) || M.isloyal() || ispAI(M))
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
return FALSE
|
||||
if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to))
|
||||
return FALSE
|
||||
if(M.mind.unconvertable)
|
||||
return FALSE
|
||||
else
|
||||
return FALSE
|
||||
if(M.isloyal() || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M))
|
||||
|
||||
@@ -72,8 +72,6 @@
|
||||
if(is_servant_of_ratvar(C) && C.reagents)
|
||||
C.reagents.add_reagent("heparin", 1)
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
/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."
|
||||
@@ -100,7 +98,6 @@
|
||||
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()
|
||||
@@ -176,11 +173,12 @@
|
||||
if(H.stat != CONSCIOUS)
|
||||
var/obj/item/device/soulstone/SS = new /obj/item/device/soulstone(src)
|
||||
SS.attack(H, user)
|
||||
shards += SS
|
||||
return
|
||||
if(!LAZYLEN(SS.contents))
|
||||
qdel(SS)
|
||||
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))
|
||||
if(istype(SS))
|
||||
SS.transfer_soul("CONSTRUCT",target,user)
|
||||
qdel(SS)
|
||||
|
||||
/datum/action/innate/dash/cult
|
||||
@@ -238,7 +236,6 @@
|
||||
sword.slowdown -= 1.5
|
||||
sleep(sword.spin_cooldown)
|
||||
holder.update_action_buttons_icon()
|
||||
>>>>>>> 380413f... Ports dash weapons to the dash datum (#31222)
|
||||
|
||||
/obj/item/restraints/legcuffs/bola/cult
|
||||
name = "nar'sien bola"
|
||||
|
||||
@@ -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)].</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))
|
||||
|
||||
@@ -253,12 +253,14 @@
|
||||
|
||||
/datum/game_mode/proc/add_revolutionary(datum/mind/rev_mind)
|
||||
if(rev_mind.assigned_role in GLOB.command_positions)
|
||||
return 0
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/H = rev_mind.current//Check to see if the potential rev is implanted
|
||||
if(H.isloyal())
|
||||
return 0
|
||||
return FALSE
|
||||
if((rev_mind in revolutionaries) || (rev_mind in head_revolutionaries))
|
||||
return 0
|
||||
return FALSE
|
||||
if(rev_mind.unconvertable)
|
||||
return FALSE
|
||||
revolutionaries += rev_mind
|
||||
if(iscarbon(rev_mind.current))
|
||||
var/mob/living/carbon/carbon_mob = rev_mind.current
|
||||
@@ -271,7 +273,7 @@
|
||||
update_rev_icons_added(rev_mind)
|
||||
if(jobban_isbanned(rev_mind.current, ROLE_REV))
|
||||
INVOKE_ASYNC(src, .proc/replace_jobbaned_player, rev_mind.current, ROLE_REV, ROLE_REV)
|
||||
return 1
|
||||
return TRUE
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//Deals with players being converted from the revolution (Not a rev anymore)// // Modified to handle borged MMIs. Accepts another var if the target is being borged at the time -- Polymorph.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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!")
|
||||
|
||||
@@ -134,12 +134,11 @@
|
||||
if(ispath(lit, /obj/item/ore/bluespace_crystal))
|
||||
use_power(max(500,M.last_amount_inserted/10))
|
||||
else
|
||||
var/obj/item/stack/S = lit
|
||||
var/list/initmats = initial(S.materials)
|
||||
if (initmats[MAT_METAL])
|
||||
flick("autolathe_o",src)//plays metal insertion animation
|
||||
if (initmats[MAT_GLASS])
|
||||
flick("autolathe_r",src)//plays glass insertion animation
|
||||
switch(M.last_inserted_id)
|
||||
if (MAT_METAL)
|
||||
flick("autolathe_o",src)//plays metal insertion animation
|
||||
if (MAT_GLASS)
|
||||
flick("autolathe_r",src)//plays glass insertion animation
|
||||
use_power(M.last_amount_inserted*100)
|
||||
updateUsrDialog()
|
||||
|
||||
|
||||
@@ -420,13 +420,7 @@
|
||||
var/datum/component/material_container/M = C
|
||||
if(!M.last_insert_success)
|
||||
return
|
||||
var/lit = M.last_inserted_type
|
||||
var/stack_name
|
||||
if(ispath(lit, /obj/item/ore/bluespace_crystal))
|
||||
stack_name = "bluespace"
|
||||
else
|
||||
var/obj/item/stack/S = lit
|
||||
stack_name = material2name(initial(S.materials)[1])
|
||||
var/stack_name = material2name(M.last_inserted_id)
|
||||
add_overlay("fab-load-[stack_name]")
|
||||
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "fab-load-[stack_name]"), 10)
|
||||
updateUsrDialog()
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
/obj/effect/temp_visual/fire
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "3"
|
||||
light_range = 3
|
||||
light_range = LIGHT_RANGE_FIRE
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
duration = 10
|
||||
|
||||
|
||||
@@ -143,4 +143,82 @@ Code:
|
||||
</TT>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/device/electropack/shockcollar
|
||||
name = "shock collar"
|
||||
desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.."
|
||||
icon = 'icons/obj/clothing/neck.dmi'
|
||||
icon_state = "shockcollar"
|
||||
item_state = "shockcollar"
|
||||
body_parts_covered = NECK
|
||||
slot_flags = SLOT_NECK
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
strip_delay = 60
|
||||
equip_delay_other = 60
|
||||
materials = list(MAT_METAL=5000, MAT_GLASS=2000)
|
||||
var/tagname = null
|
||||
|
||||
/obj/item/device/electropack/shockcollar/attack_hand(mob/user)
|
||||
if(loc == user)
|
||||
if(slot_flags == SLOT_NECK)
|
||||
to_chat(user, "<span class='warning'>The collar is fastened tight! You'll need help taking this off!</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/electropack/shockcollar/receive_signal(datum/signal/signal)
|
||||
if(!signal || signal.encryption != code)
|
||||
return
|
||||
|
||||
if(isliving(loc) && on)
|
||||
if(shock_cooldown != 0)
|
||||
return
|
||||
shock_cooldown = 1
|
||||
spawn(100)
|
||||
shock_cooldown = 0
|
||||
var/mob/living/L = loc
|
||||
step(L, pick(GLOB.cardinals))
|
||||
|
||||
to_chat(L, "<span class='danger'>You feel a sharp shock from the collar!</span>")
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, L)
|
||||
s.start()
|
||||
|
||||
L.Knockdown(100)
|
||||
|
||||
if(master)
|
||||
master.receive_signal()
|
||||
return
|
||||
|
||||
/obj/item/device/electropack/shockcollar/attack_self(mob/user) //Turns out can't fully source this from the parent item, spritepath gets confused if power toggled. Will come back to this when I know how to code better and readd powertoggle..
|
||||
var/option = "Change Name"
|
||||
option = input(user, "What do you want to do?", "[src]", option) as null|anything in list("Change Name", "Change Frequency")
|
||||
switch(option)
|
||||
if("Change Name")
|
||||
var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text
|
||||
if(t)
|
||||
tagname = copytext(sanitize(t), 1, MAX_NAME_LEN)
|
||||
name = "[initial(name)] - [tagname]"
|
||||
if("Change Frequency")
|
||||
if(!ishuman(user))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = {"<SK><BR>
|
||||
<B>Frequency/Code</B> for shock collar:<BR>
|
||||
Frequency:
|
||||
<A href='byond://?src=\ref[src];freq=-10'>-</A>
|
||||
<A href='byond://?src=\ref[src];freq=-2'>-</A> [format_frequency(frequency)]
|
||||
<A href='byond://?src=\ref[src];freq=2'>+</A>
|
||||
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
|
||||
|
||||
Code:
|
||||
<A href='byond://?src=\ref[src];code=-5'>-</A>
|
||||
<A href='byond://?src=\ref[src];code=-1'>-</A> [code]
|
||||
<A href='byond://?src=\ref[src];code=1'>+</A>
|
||||
<A href='byond://?src=\ref[src];code=5'>+</A><BR>
|
||||
</SK>"}
|
||||
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
|
||||
|
||||
@@ -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)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °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."
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
|
||||
/obj/item/implant/mindshield/implant(mob/living/target, mob/user, silent = 0)
|
||||
if(..())
|
||||
if((target.mind in (SSticker.mode.head_revolutionaries)))
|
||||
if((target.mind in (SSticker.mode.head_revolutionaries)) || target.mind.unconvertable)
|
||||
if(!silent)
|
||||
target.visible_message("<span class='warning'>[target] seems to resist the implant!</span>", "<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
|
||||
removed(target, 1)
|
||||
qdel(src)
|
||||
return 0
|
||||
return FALSE
|
||||
if(target.mind in SSticker.mode.revolutionaries)
|
||||
SSticker.mode.remove_revolutionary(target.mind, FALSE, user)
|
||||
if(!silent)
|
||||
@@ -32,8 +32,8 @@
|
||||
to_chat(target, "<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
|
||||
else
|
||||
to_chat(target, "<span class='notice'>You feel a sense of peace and security. You are now protected from brainwashing.</span>")
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/implant/mindshield/removed(mob/target, silent = 0, special = 0)
|
||||
if(..())
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "1"
|
||||
layer = ABOVE_OPEN_TURF_LAYER
|
||||
light_range = 3
|
||||
light_range = LIGHT_RANGE_FIRE
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
|
||||
var/volume = 125
|
||||
@@ -175,3 +175,15 @@
|
||||
..()
|
||||
if(isliving(L))
|
||||
L.fire_act(temperature, volume)
|
||||
|
||||
/obj/effect/dummy/fire
|
||||
name = "fire"
|
||||
desc = "OWWWWWW. IT BURNS. Tell a coder if you're seeing this."
|
||||
icon_state = "nothing"
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
light_range = LIGHT_RANGE_FIRE
|
||||
|
||||
/obj/effect/dummy/fire/Initialize()
|
||||
. = ..()
|
||||
if(!isliving(loc))
|
||||
qdel(src)
|
||||
|
||||
@@ -185,7 +185,9 @@
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand()
|
||||
visible_message("<span class='notice'>[src] expands!</span>")
|
||||
new /mob/living/carbon/monkey(get_turf(src))
|
||||
var/mob/spammer = get_mob_by_key(src.fingerprintslast)
|
||||
var/mob/living/carbon/monkey/bananas = new(get_turf(src))
|
||||
bananas.log_message("Spawned via [src] at [COORD(src)], Last attached mob: [key_name(spammer)].", INDIVIDUAL_ATTACK_LOG)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/enchiladas
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
vital = FALSE
|
||||
decoy_override = TRUE
|
||||
|
||||
/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0)
|
||||
/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0,no_id_transfer = FALSE)
|
||||
..()
|
||||
|
||||
name = "brain"
|
||||
|
||||
if(C.mind && C.mind.changeling) //congrats, you're trapped in a body you don't control
|
||||
if(C.mind && C.mind.changeling && !no_id_transfer) //congrats, you're trapped in a body you don't control
|
||||
if(brainmob && !(C.stat == DEAD || (C.status_flags & FAKEDEATH)))
|
||||
to_chat(brainmob, "<span class = danger>You can't feel your body! You're still just a brain!</span>")
|
||||
loc = C
|
||||
@@ -44,13 +44,9 @@
|
||||
//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)
|
||||
/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0, no_id_transfer = FALSE)
|
||||
..()
|
||||
if(!special)
|
||||
if(C.has_brain_worms())
|
||||
var/mob/living/simple_animal/borer/B = C.has_brain_worms()
|
||||
B.leave_victim() //Should remove borer if the brain is removed - RR
|
||||
if(!gc_destroyed || (owner && !owner.gc_destroyed))
|
||||
if((!gc_destroyed || (owner && !owner.gc_destroyed)) && !no_id_transfer)
|
||||
transfer_identity(C)
|
||||
C.update_hair()
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -277,9 +277,11 @@
|
||||
if(!appears_dead)
|
||||
if(stat == UNCONSCIOUS)
|
||||
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
|
||||
else if(getBrainLoss() >= 60)
|
||||
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
|
||||
|
||||
else
|
||||
if(getBrainLoss() >= 60)
|
||||
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
|
||||
if(InCritical())
|
||||
msg += "[t_He] is barely concious.\n"
|
||||
if(getorgan(/obj/item/organ/brain))
|
||||
if(istype(src, /mob/living/carbon/human/interactive))
|
||||
var/mob/living/carbon/human/interactive/auto = src
|
||||
|
||||
@@ -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
|
||||
@@ -21,41 +22,12 @@
|
||||
set_species(dna.species.type)
|
||||
|
||||
//initialise organs
|
||||
create_internal_organs()
|
||||
create_internal_organs() //most of it is done in set_species now, this is only for parent call
|
||||
|
||||
handcrafting = new()
|
||||
|
||||
. = ..()
|
||||
|
||||
/mob/living/carbon/human/create_internal_organs()
|
||||
if(!(NOHUNGER in dna.species.species_traits))
|
||||
internal_organs += new /obj/item/organ/appendix
|
||||
if(!(NOBREATH in dna.species.species_traits))
|
||||
if(dna.species.mutantlungs)
|
||||
internal_organs += new dna.species.mutantlungs()
|
||||
else
|
||||
internal_organs += new /obj/item/organ/lungs()
|
||||
if(!(NOBLOOD in dna.species.species_traits))
|
||||
internal_organs += new /obj/item/organ/heart
|
||||
|
||||
if(!(NOLIVER in dna.species.species_traits))
|
||||
if(dna.species.mutantliver)
|
||||
internal_organs += new dna.species.mutantliver()
|
||||
else
|
||||
internal_organs += new /obj/item/organ/liver()
|
||||
|
||||
if(!(NOSTOMACH in dna.species.species_traits))
|
||||
if(dna.species.mutantstomach)
|
||||
internal_organs += new dna.species.mutantstomach()
|
||||
else
|
||||
internal_organs += new /obj/item/organ/stomach()
|
||||
|
||||
internal_organs += new dna.species.mutanteyes
|
||||
internal_organs += new dna.species.mutantears
|
||||
internal_organs += new dna.species.mutanttongue
|
||||
internal_organs += new /obj/item/organ/brain
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/OpenCraftingMenu()
|
||||
handcrafting.ui_interact(src)
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@
|
||||
|
||||
//Flight and floating
|
||||
var/override_float = 0
|
||||
|
||||
|
||||
var/obj/item/organ/brain/mutant_brain = /obj/item/organ/brain
|
||||
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
|
||||
var/obj/item/organ/ears/mutantears = /obj/item/organ/ears
|
||||
var/obj/item/mutanthands
|
||||
@@ -123,6 +124,113 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
//Will regenerate missing organs
|
||||
/datum/species/proc/regenerate_organs(mob/living/carbon/C,datum/species/old_species,replace_current=TRUE)
|
||||
var/obj/item/organ/brain/brain = C.getorganslot("brain")
|
||||
var/obj/item/organ/heart/heart = C.getorganslot("heart")
|
||||
var/obj/item/organ/lungs/lungs = C.getorganslot("lungs")
|
||||
var/obj/item/organ/appendix/appendix = C.getorganslot("appendix")
|
||||
var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
|
||||
var/obj/item/organ/ears/ears = C.getorganslot("ears")
|
||||
var/obj/item/organ/tongue/tongue = C.getorganslot("tongue")
|
||||
var/obj/item/organ/liver/liver = C.getorganslot("liver")
|
||||
var/obj/item/organ/stomach/stomach = C.getorganslot("stomach")
|
||||
|
||||
var/should_have_brain = TRUE
|
||||
var/should_have_heart = !(NOBLOOD in species_traits)
|
||||
var/should_have_lungs = !(NOBREATH in species_traits)
|
||||
var/should_have_appendix = !(NOHUNGER in species_traits)
|
||||
var/should_have_eyes = TRUE
|
||||
var/should_have_ears = TRUE
|
||||
var/should_have_tongue = TRUE
|
||||
var/should_have_liver = !(NOLIVER in species_traits)
|
||||
var/should_have_stomach = !(NOSTOMACH in species_traits)
|
||||
|
||||
if(brain && (replace_current || !should_have_brain))
|
||||
if(!brain.decoy_override)//Just keep it if it's fake
|
||||
brain.Remove(C,TRUE,TRUE)
|
||||
QDEL_NULL(brain)
|
||||
if(should_have_brain && !brain)
|
||||
brain = new mutant_brain()
|
||||
brain.Insert(C, TRUE, TRUE)
|
||||
|
||||
if(heart && (!should_have_heart || replace_current))
|
||||
heart.Remove(C,1)
|
||||
QDEL_NULL(heart)
|
||||
if(should_have_heart && !heart)
|
||||
heart = new()
|
||||
heart.Insert(C)
|
||||
|
||||
if(lungs && (replace_current || !should_have_lungs))
|
||||
lungs.Remove(C,1)
|
||||
QDEL_NULL(lungs)
|
||||
if(should_have_lungs && !lungs)
|
||||
if(mutantlungs)
|
||||
lungs = new mutantlungs()
|
||||
else
|
||||
lungs = new()
|
||||
lungs.Insert(C)
|
||||
|
||||
if(liver && (!should_have_liver || replace_current))
|
||||
liver.Remove(C,1)
|
||||
QDEL_NULL(liver)
|
||||
if(should_have_liver && !liver)
|
||||
if(mutantliver)
|
||||
liver = new mutantliver()
|
||||
else
|
||||
liver = new()
|
||||
liver.Insert(C)
|
||||
|
||||
if(stomach && (!should_have_stomach || replace_current))
|
||||
stomach.Remove(C,1)
|
||||
QDEL_NULL(stomach)
|
||||
if(should_have_stomach && !stomach)
|
||||
if(mutantstomach)
|
||||
stomach = new mutantstomach()
|
||||
else
|
||||
stomach = new()
|
||||
stomach.Insert(C)
|
||||
|
||||
if(appendix && (!should_have_appendix || replace_current))
|
||||
appendix.Remove(C,1)
|
||||
QDEL_NULL(appendix)
|
||||
if(should_have_appendix && !appendix)
|
||||
appendix = new()
|
||||
appendix.Insert(C)
|
||||
|
||||
if(C.get_bodypart("head"))
|
||||
if(eyes && (replace_current || !should_have_eyes))
|
||||
eyes.Remove(C,1)
|
||||
QDEL_NULL(eyes)
|
||||
if(should_have_eyes && !eyes)
|
||||
eyes = new mutanteyes
|
||||
eyes.Insert(C)
|
||||
|
||||
if(ears && (replace_current || !should_have_ears))
|
||||
ears.Remove(C,1)
|
||||
QDEL_NULL(ears)
|
||||
if(should_have_ears && !ears)
|
||||
ears = new mutantears
|
||||
ears.Insert(C)
|
||||
|
||||
if(tongue && (replace_current || !should_have_tongue))
|
||||
tongue.Remove(C,1)
|
||||
QDEL_NULL(tongue)
|
||||
if(should_have_tongue && !tongue)
|
||||
tongue = new mutanttongue
|
||||
tongue.Insert(C)
|
||||
|
||||
if(old_species)
|
||||
for(var/mutantorgan in old_species.mutant_organs)
|
||||
var/obj/item/organ/I = C.getorgan(mutantorgan)
|
||||
if(I)
|
||||
I.Remove(C)
|
||||
QDEL_NULL(I)
|
||||
|
||||
for(var/path in mutant_organs)
|
||||
var/obj/item/organ/I = new path()
|
||||
I.Insert(C)
|
||||
|
||||
/datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
// Drop the items the new species can't wear
|
||||
for(var/slot_id in no_equip)
|
||||
@@ -138,79 +246,7 @@
|
||||
if(DIGITIGRADE in species_traits)
|
||||
C.Digitigrade_Leg_Swap(FALSE)
|
||||
|
||||
var/obj/item/organ/heart/heart = C.getorganslot("heart")
|
||||
var/obj/item/organ/lungs/lungs = C.getorganslot("lungs")
|
||||
var/obj/item/organ/appendix/appendix = C.getorganslot("appendix")
|
||||
var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
|
||||
var/obj/item/organ/ears/ears = C.getorganslot("ears")
|
||||
var/obj/item/organ/tongue/tongue = C.getorganslot("tongue")
|
||||
|
||||
var/obj/item/organ/liver/liver = C.getorganslot("liver")
|
||||
var/obj/item/organ/stomach/stomach = C.getorganslot("stomach")
|
||||
|
||||
|
||||
|
||||
if((NOBLOOD in species_traits) && heart)
|
||||
heart.Remove(C)
|
||||
qdel(heart)
|
||||
else if((!(NOBLOOD in species_traits)) && (!heart))
|
||||
heart = new()
|
||||
heart.Insert(C)
|
||||
|
||||
if(lungs)
|
||||
qdel(lungs)
|
||||
lungs = null
|
||||
|
||||
QDEL_NULL(liver)
|
||||
|
||||
QDEL_NULL(stomach)
|
||||
|
||||
if(C.get_bodypart("head"))
|
||||
if(eyes)
|
||||
qdel(eyes)
|
||||
eyes = new mutanteyes
|
||||
eyes.Insert(C)
|
||||
|
||||
if(ears)
|
||||
qdel(ears)
|
||||
ears = new mutantears
|
||||
ears.Insert(C)
|
||||
|
||||
if(tongue)
|
||||
qdel(tongue)
|
||||
tongue = new mutanttongue
|
||||
tongue.Insert(C)
|
||||
|
||||
if((!(NOBREATH in species_traits)) && !lungs)
|
||||
if(mutantlungs)
|
||||
lungs = new mutantlungs()
|
||||
else
|
||||
lungs = new()
|
||||
lungs.Insert(C)
|
||||
|
||||
if((!(NOLIVER in species_traits)) && (!liver))
|
||||
if(mutantliver)
|
||||
liver = new mutantliver()
|
||||
else
|
||||
liver = new()
|
||||
liver.Insert(C)
|
||||
|
||||
if((!(NOSTOMACH in species_traits)) && (!stomach))
|
||||
if(mutantstomach)
|
||||
stomach = new mutantstomach()
|
||||
else
|
||||
stomach = new()
|
||||
stomach.Insert(C)
|
||||
|
||||
if((NOHUNGER in species_traits) && appendix)
|
||||
qdel(appendix)
|
||||
else if((!(NOHUNGER in species_traits)) && (!appendix))
|
||||
appendix = new()
|
||||
appendix.Insert(C)
|
||||
|
||||
for(var/path in mutant_organs)
|
||||
var/obj/item/organ/I = new path()
|
||||
I.Insert(C)
|
||||
regenerate_organs(C,old_species)
|
||||
|
||||
if(exotic_bloodtype && C.dna.blood_type != exotic_bloodtype)
|
||||
C.dna.blood_type = exotic_bloodtype
|
||||
|
||||
@@ -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,31 +34,21 @@
|
||||
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 = "Nightmare"
|
||||
C.name = "Nightmare"
|
||||
C.real_name = "[pick(GLOB.nightmare_names)]"
|
||||
C.name = C.real_name
|
||||
if(C.mind)
|
||||
C.mind.name = "Nightmare"
|
||||
C.dna.real_name = "Nightmare"
|
||||
|
||||
/datum/species/shadow/nightmare/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
if(shadowwalk)
|
||||
C.RemoveSpell(shadowwalk)
|
||||
C.mind.name = C.real_name
|
||||
C.dna.real_name = C.real_name
|
||||
|
||||
/datum/species/shadow/nightmare/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
var/turf/T = H.loc
|
||||
@@ -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
|
||||
@@ -1,13 +1,13 @@
|
||||
/datum/species/skeleton
|
||||
// 2spooky
|
||||
name = "Spooky Scary Skeleton"
|
||||
id = "skeleton"
|
||||
say_mod = "rattles"
|
||||
blacklisted = 1
|
||||
sexes = 0
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
|
||||
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
|
||||
mutant_organs = list(/obj/item/organ/tongue/bone)
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
disliked_food = NONE
|
||||
liked_food = NONE
|
||||
/datum/species/skeleton
|
||||
// 2spooky
|
||||
name = "Spooky Scary Skeleton"
|
||||
id = "skeleton"
|
||||
say_mod = "rattles"
|
||||
blacklisted = 1
|
||||
sexes = 0
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
|
||||
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
|
||||
mutanttongue = /obj/item/organ/tongue/bone
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
disliked_food = NONE
|
||||
liked_food = NONE
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
blacklisted = 1
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
|
||||
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT,NOTRANSSTING)
|
||||
mutant_organs = list(/obj/item/organ/tongue/zombie)
|
||||
mutanttongue = /obj/item/organ/tongue/zombie
|
||||
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
|
||||
disliked_food = NONE
|
||||
liked_food = NONE
|
||||
@@ -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())
|
||||
@@ -64,6 +65,6 @@
|
||||
limbs_id = "zombie" //They look like zombies
|
||||
sexes = 0
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
|
||||
mutant_organs = list(/obj/item/organ/tongue/zombie)
|
||||
mutanttongue = /obj/item/organ/tongue/zombie
|
||||
|
||||
#undef REGENERATION_DELAY
|
||||
|
||||
@@ -884,7 +884,7 @@
|
||||
on_fire = 1
|
||||
src.visible_message("<span class='warning'>[src] catches fire!</span>", \
|
||||
"<span class='userdanger'>You're set on fire!</span>")
|
||||
src.set_light(3)
|
||||
new/obj/effect/dummy/fire(src)
|
||||
throw_alert("fire", /obj/screen/alert/fire)
|
||||
update_fire()
|
||||
return TRUE
|
||||
@@ -894,7 +894,8 @@
|
||||
if(on_fire)
|
||||
on_fire = 0
|
||||
fire_stacks = 0
|
||||
src.set_light(0)
|
||||
for(var/obj/effect/dummy/fire/F in src)
|
||||
qdel(F)
|
||||
clear_alert("fire")
|
||||
update_fire()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -180,10 +180,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
new /obj/effect/temp_visual/guardian/phase(loc)
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/canSuicide()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/proc/is_deployed()
|
||||
return loc != summoner
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/AttackingTarget()
|
||||
if(loc == summoner)
|
||||
if(!is_deployed())
|
||||
to_chat(src, "<span class='danger'><B>You must be manifested to attack!</span></B>")
|
||||
return FALSE
|
||||
else
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget()
|
||||
. = ..()
|
||||
if(. && toggle && iscarbon(target))
|
||||
if(is_deployed() && toggle && iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
C.adjustBruteLoss(-5)
|
||||
C.adjustFireLoss(-5)
|
||||
|
||||
@@ -105,22 +105,22 @@
|
||||
/mob/living/simple_animal/hostile/poison/bees/CanAttack(atom/the_target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return 0
|
||||
return FALSE
|
||||
if(isliving(the_target))
|
||||
var/mob/living/H = the_target
|
||||
return !H.bee_friendly()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Found(atom/A)
|
||||
if(isliving(A))
|
||||
var/mob/living/H = A
|
||||
return !H.bee_friendly()
|
||||
if(istype(A, /obj/machinery/hydroponics))
|
||||
var/obj/machinery/hydroponics/Hydro = A
|
||||
if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit)
|
||||
wanted_objects |= typecacheof(/obj/machinery/hydroponics) //so we only hunt them while they're alive/seeded/not visisted
|
||||
return 1
|
||||
if(isliving(A))
|
||||
var/mob/living/H = A
|
||||
return !H.bee_friendly()
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/AttackingTarget()
|
||||
@@ -187,7 +187,7 @@
|
||||
if(loc == beehome)
|
||||
idle = min(100, ++idle)
|
||||
if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM))
|
||||
forceMove(get_turf(beehome))
|
||||
forceMove(beehome.drop_location())
|
||||
else
|
||||
idle = max(0, --idle)
|
||||
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
|
||||
@@ -200,6 +200,7 @@
|
||||
continue
|
||||
BB.bees |= src
|
||||
beehome = BB
|
||||
break // End loop after the first compatible find.
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/toxin/Initialize()
|
||||
. = ..()
|
||||
@@ -215,7 +216,7 @@
|
||||
|
||||
//the Queen doesn't leave the box on her own, and she CERTAINLY doesn't pollinate by herself
|
||||
/mob/living/simple_animal/hostile/poison/bees/queen/Found(atom/A)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
|
||||
//leave pollination for the peasent bees
|
||||
@@ -234,10 +235,10 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/proc/reagent_incompatible(mob/living/simple_animal/hostile/poison/bees/B)
|
||||
if(!B)
|
||||
return 0
|
||||
return FALSE
|
||||
if(B.beegent && beegent && B.beegent.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/item/queen_bee
|
||||
@@ -255,7 +256,7 @@
|
||||
if(S.reagents.has_reagent("royal_bee_jelly")) //checked twice, because I really don't want royal bee jelly to be duped
|
||||
if(S.reagents.has_reagent("royal_bee_jelly",5))
|
||||
S.reagents.remove_reagent("royal_bee_jelly", 5)
|
||||
var/obj/item/queen_bee/qb = new(get_turf(user))
|
||||
var/obj/item/queen_bee/qb = new(user.drop_location())
|
||||
qb.queen = new(qb)
|
||||
if(queen && queen.beegent)
|
||||
qb.queen.assign_reagent(queen.beegent) //Bees use the global singleton instances of reagents, so we don't need to worry about one bee being deleted and her copies losing their reagents.
|
||||
|
||||
@@ -115,7 +115,11 @@
|
||||
if(can_see(targets_from, HM, vision_range))
|
||||
. += HM
|
||||
else
|
||||
. = oview(vision_range, targets_from)
|
||||
. = list() // The following code is only very slightly slower than just returning oview(vision_range, targets_from), but it saves us much more work down the line, particularly when bees are involved
|
||||
for (var/obj/A in oview(vision_range, targets_from))
|
||||
. += A
|
||||
for (var/mob/A in oview(vision_range, targets_from))
|
||||
. += A
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about
|
||||
. = list()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -608,6 +608,14 @@
|
||||
build_path = /obj/item/device/electropack
|
||||
category = list("hacked", "Tools")
|
||||
|
||||
/datum/design/shock_collar
|
||||
name = "Shock Collar"
|
||||
id = "shock_collar"
|
||||
build_type = AUTOLATHE
|
||||
materials = list(MAT_METAL = 5000, MAT_GLASS = 2000)
|
||||
build_path = /obj/item/device/electropack/shockcollar
|
||||
category = list("hacked", "Security")
|
||||
|
||||
/datum/design/large_welding_tool
|
||||
name = "Industrial Welding Tool"
|
||||
id = "large_welding_tool"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
var/slot
|
||||
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
|
||||
var/vital = 0
|
||||
//Was this organ implanted/inserted/etc, if true will not be removed during species change.
|
||||
var/external = FALSE
|
||||
|
||||
|
||||
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
|
||||
|
||||
Reference in New Issue
Block a user