Merge branch 'master' of https://github.com/tgstation/-tg-station into AttackbyDestruction
Conflicts: code/game/objects/items/devices/lightreplacer.dm code/game/objects/structures/crates_lockers/closets.dm
@@ -6,7 +6,7 @@
|
||||
|
||||
##BIODOMES
|
||||
_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland__biodome_beach.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_surface_cube.dmm
|
||||
|
||||
@@ -15,6 +15,7 @@ _maps/RandomRuins/LavaRuins/lavaland_surface_prisoner_crash.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm
|
||||
|
||||
##SIN
|
||||
_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm
|
||||
@@ -29,4 +30,5 @@ _maps/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_surface_automated_trade_outpost.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_fountain_hall.dmm
|
||||
_maps/RandomRuins/LavaRuins/lavaland_gym.dmm
|
||||
@@ -2504,7 +2504,7 @@
|
||||
"aWj" = (/obj/item/weapon/circuitboard/security,/turf/open/floor/plating,/area/maintenance/asmaint2)
|
||||
"aWk" = (/obj/structure/window/reinforced,/obj/structure/flora/kirbyplants{icon_state = "plant-17"; layer = 4.1},/turf/open/floor/plasteel/whitebot,/area/maintenance/fore{name = "Security Maintenance"})
|
||||
"aWl" = (/obj/machinery/vending/assist,/turf/open/floor/plasteel/warning{icon_state = "warning"; dir = 10},/area/maintenance/fore{name = "Security Maintenance"})
|
||||
"aWm" = (/obj/structure/table,/obj/item/clothing/gloves/color/yellow/fake,/obj/item/clothing/gloves/color/yellow/fake,/obj/item/clothing/gloves/color/yellow/fake,/turf/open/floor/plasteel/warning,/area/maintenance/fore{name = "Security Maintenance"})
|
||||
"aWm" = (/obj/structure/table,/obj/item/clothing/gloves/color/fyellow,/obj/item/clothing/gloves/color/fyellow,/obj/item/clothing/gloves/color/fyellow,/turf/open/floor/plasteel/warning,/area/maintenance/fore{name = "Security Maintenance"})
|
||||
"aWn" = (/obj/machinery/power/apc{dir = 4; name = "Security Maintenance APC"; pixel_x = 24},/obj/structure/cable/cyan,/obj/machinery/atmospherics/pipe/simple/cyan/hidden,/turf/open/floor/plating,/area/maintenance/fore{name = "Security Maintenance"})
|
||||
"aWo" = (/obj/structure/table,/obj/item/weapon/cautery,/obj/item/weapon/surgicaldrill,/obj/item/weapon/circular_saw{pixel_y = 9},/turf/open/floor/plasteel/white,/area/security/warden)
|
||||
"aWp" = (/obj/structure/bodycontainer/morgue,/obj/effect/landmark{name = "revenantspawn"},/turf/open/floor/plasteel/white,/area/security/warden)
|
||||
|
||||
@@ -410,3 +410,11 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
#define PLANT_WEED 1
|
||||
#define PLANT_MUSHROOM 2
|
||||
#define PLANT_ALIEN 3
|
||||
|
||||
// Maploader bounds indices
|
||||
#define MAP_MINX 1
|
||||
#define MAP_MINY 2
|
||||
#define MAP_MINZ 3
|
||||
#define MAP_MAXX 4
|
||||
#define MAP_MAXY 5
|
||||
#define MAP_MAXZ 6
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define json_load(FILE) (json_decode(file2text(FILE)))
|
||||
|
||||
var/global/list/string_cache
|
||||
var/global/list/string_filename_current_key
|
||||
var/global/string_filename_current_key
|
||||
|
||||
|
||||
/proc/strings_replacement(filename, key)
|
||||
|
||||
@@ -344,3 +344,13 @@
|
||||
while(L.Remove(null))
|
||||
continue
|
||||
return L
|
||||
|
||||
//Copies a list, and all lists inside it recusively
|
||||
//Does not copy any other reference type
|
||||
/proc/deepCopyList(list/l)
|
||||
if(!islist(l))
|
||||
return l
|
||||
. = l.Copy()
|
||||
for(var/i = 1 to l.len)
|
||||
if(islist(.[i]))
|
||||
.[i] = .(.[i])
|
||||
|
||||
@@ -50,8 +50,8 @@
|
||||
|
||||
/obj/screen/blob/Blobbernaut
|
||||
icon_state = "ui_blobbernaut"
|
||||
name = "Produce Blobbernaut (30)"
|
||||
desc = "Produces a strong, smart blobbernaut from a factory blob for 30 points.<br>The factory blob used will become fragile and briefly unable to produce spores."
|
||||
name = "Produce Blobbernaut (40)"
|
||||
desc = "Produces a strong, smart blobbernaut from a factory blob for 40 points.<br>The factory blob used will become fragile and unable to produce spores."
|
||||
|
||||
/obj/screen/blob/Blobbernaut/Click()
|
||||
if(isovermind(usr))
|
||||
|
||||
@@ -270,6 +270,8 @@ var/datum/subsystem/air/SSair
|
||||
for(var/thing in turfs_to_init)
|
||||
var/turf/T = thing
|
||||
active_turfs -= T
|
||||
if (T.blocks_air)
|
||||
return
|
||||
T.Initalize_Atmos(times_fired)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/datum/dog_fashion
|
||||
var/name
|
||||
var/desc
|
||||
var/emote_see
|
||||
var/emote_hear
|
||||
var/speak
|
||||
var/speak_emote
|
||||
|
||||
// This isn't applied to the dog, but stores the icon_state of the
|
||||
// sprite that the associated item uses
|
||||
var/icon_file
|
||||
var/icon_state
|
||||
|
||||
/datum/dog_fashion/New(mob/M)
|
||||
name = replacetext(name, "REAL_NAME", M.real_name)
|
||||
desc = replacetext(desc, "NAME", name)
|
||||
|
||||
/datum/dog_fashion/proc/apply(mob/living/simple_animal/pet/dog/D)
|
||||
if(name)
|
||||
D.name = name
|
||||
if(desc)
|
||||
D.desc = desc
|
||||
if(emote_see)
|
||||
D.emote_see = emote_see
|
||||
if(emote_hear)
|
||||
D.emote_hear = emote_hear
|
||||
if(speak)
|
||||
D.speak = speak
|
||||
if(speak_emote)
|
||||
D.speak_emote = speak_emote
|
||||
|
||||
/datum/dog_fashion/proc/get_image(var/dir)
|
||||
if(icon_file && icon_state)
|
||||
return image(icon_file, icon_state = icon_state, dir = dir)
|
||||
|
||||
|
||||
/datum/dog_fashion/head
|
||||
icon_file = 'icons/mob/corgi_head.dmi'
|
||||
|
||||
/datum/dog_fashion/back
|
||||
icon_file = 'icons/mob/corgi_back.dmi'
|
||||
|
||||
/datum/dog_fashion/head
|
||||
|
||||
/datum/dog_fashion/head/helmet
|
||||
name = "Sergeant REAL_NAME"
|
||||
desc = "The ever-loyal, the ever-vigilant."
|
||||
|
||||
/datum/dog_fashion/head/chef
|
||||
name = "Sous chef REAL_NAME"
|
||||
desc = "Your food will be taste-tested. All of it."
|
||||
|
||||
|
||||
/datum/dog_fashion/head/captain
|
||||
name = "Captain REAL_NAME"
|
||||
desc = "Probably better than the last captain."
|
||||
|
||||
/datum/dog_fashion/head/kitty
|
||||
name = "Runtime"
|
||||
emote_see = list("coughs up a furball", "stretches")
|
||||
emote_hear = list("purrs")
|
||||
speak = list("Purrr", "Meow!", "MAOOOOOW!", "HISSSSS", "MEEEEEEW")
|
||||
desc = "It's a cute little kitty-cat! ... wait ... what the hell?"
|
||||
|
||||
/datum/dog_fashion/head/rabbit
|
||||
name = "Hoppy"
|
||||
emote_see = list("twitches its nose", "hops around a bit")
|
||||
desc = "This is Hoppy. It's a corgi-...urmm... bunny rabbit."
|
||||
|
||||
/datum/dog_fashion/head/beret
|
||||
name = "Yann"
|
||||
desc = "Mon dieu! C'est un chien!"
|
||||
speak = list("le woof!", "le bark!", "JAPPE!!")
|
||||
emote_see = list("cowers in fear.", "surrenders.", "plays dead.","looks as though there is a wall in front of him.")
|
||||
|
||||
|
||||
/datum/dog_fashion/head/detective
|
||||
name = "Detective REAL_NAME"
|
||||
desc = "NAME sees through your lies..."
|
||||
emote_see = list("investigates the area.","sniffs around for clues.","searches for scooby snacks.","takes a candycorn from the hat.")
|
||||
|
||||
|
||||
/datum/dog_fashion/head/nurse
|
||||
name = "Nurse REAL_NAME"
|
||||
desc = "NAME needs 100cc of beef jerky... STAT!"
|
||||
|
||||
/datum/dog_fashion/head/pirate
|
||||
name = "Pirate-title Pirate-name"
|
||||
desc = "Yaarghh!! Thar' be a scurvy dog!"
|
||||
emote_see = list("hunts for treasure.","stares coldly...","gnashes his tiny corgi teeth!")
|
||||
emote_hear = list("growls ferociously!", "snarls.")
|
||||
speak = list("Arrrrgh!!","Grrrrrr!")
|
||||
|
||||
/datum/dog_fashion/head/pirate/New(mob/M)
|
||||
..()
|
||||
name = "[pick("Ol'","Scurvy","Black","Rum","Gammy","Bloody","Gangrene","Death","Long-John")] [pick("kibble","leg","beard","tooth","poop-deck","Threepwood","Le Chuck","corsair","Silver","Crusoe")]"
|
||||
|
||||
/datum/dog_fashion/head/ushanka
|
||||
name = "Communist-title Realname"
|
||||
desc = "A follower of Karl Barx."
|
||||
emote_see = list("contemplates the failings of the capitalist economic model.", "ponders the pros and cons of vanguardism.")
|
||||
|
||||
/datum/dog_fashion/head/ushanka/New(mob/M)
|
||||
..()
|
||||
name = "[pick("Comrade","Commissar","Glorious Leader")] [M.real_name]"
|
||||
|
||||
/datum/dog_fashion/head/warden
|
||||
name = "Officer REAL_NAME"
|
||||
emote_see = list("drools.","looks for donuts.")
|
||||
desc = "Stop right there criminal scum!"
|
||||
|
||||
/datum/dog_fashion/head/blue_wizard
|
||||
name = "Grandwizard REAL_NAME"
|
||||
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "EI NATH!")
|
||||
|
||||
/datum/dog_fashion/head/red_wizard
|
||||
name = "Pyromancer REAL_NAME"
|
||||
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "ONI SOMA!")
|
||||
|
||||
/datum/dog_fashion/head/cardborg
|
||||
name = "Borgi"
|
||||
speak = list("Ping!","Beep!","Woof!")
|
||||
emote_see = list("goes rogue.", "sniffs out non-humans.")
|
||||
desc = "Result of robotics budget cuts."
|
||||
|
||||
/datum/dog_fashion/head/ghost
|
||||
name = "\improper Ghost"
|
||||
speak = list("WoooOOOooo~","AUUUUUUUUUUUUUUUUUU")
|
||||
emote_see = list("stumbles around.", "shivers.")
|
||||
emote_hear = list("howls!","groans.")
|
||||
desc = "Spooky!"
|
||||
icon_state = "sheet"
|
||||
|
||||
/datum/dog_fashion/head/santa
|
||||
name = "Santa's Corgi Helper"
|
||||
emote_hear = list("barks Christmas songs.", "yaps merrily!")
|
||||
emote_see = list("looks for presents.", "checks his list.")
|
||||
desc = "He's very fond of milk and cookies."
|
||||
|
||||
/datum/dog_fashion/head/cargo_tech
|
||||
name = "Corgi Tech REAL_NAME"
|
||||
desc = "The reason your yellow gloves have chew-marks."
|
||||
|
||||
/datum/dog_fashion/head/reindeer
|
||||
name = "REAL_NAME the red-nosed Corgi"
|
||||
emote_hear = list("lights the way!", "illuminates.", "yaps!")
|
||||
desc = "He has a very shiny nose."
|
||||
|
||||
/datum/dog_fashion/head/sombrero
|
||||
name = "Segnor REAL_NAME"
|
||||
desc = "You must respect Elder Dogname"
|
||||
|
||||
/datum/dog_fashion/head/sombrero/New(mob/M)
|
||||
..()
|
||||
desc = "You must respect Elder [M.real_name]."
|
||||
|
||||
/datum/dog_fashion/head/hop
|
||||
name = "Lieutenant REAL_NAME"
|
||||
desc = "Can actually be trusted to not run off on his own."
|
||||
|
||||
/datum/dog_fashion/head/deathsquad
|
||||
name = "Trooper REAL_NAME"
|
||||
desc = "That's not red paint. That's real corgi blood."
|
||||
|
||||
/datum/dog_fashion/head/clown
|
||||
name = "REAL_NAME the Clown"
|
||||
desc = "Honkman's best friend."
|
||||
speak = list("HONK!", "Honk!")
|
||||
emote_see = list("plays tricks.", "slips.")
|
||||
|
||||
/datum/dog_fashion/back/deathsquad
|
||||
name = "Trooper REAL_NAME"
|
||||
desc = "That's not red paint. That's real corgi blood."
|
||||
@@ -16,16 +16,11 @@
|
||||
name = rename
|
||||
|
||||
/datum/map_template/proc/preload_size(path)
|
||||
var/quote = ascii2text(34)
|
||||
var/map_file = file2text(path)
|
||||
var/key_len = length(copytext(map_file,2,findtext(map_file,quote,2,0)))
|
||||
//assuming one map per file since more makes no sense for templates anyway
|
||||
var/mapstart = findtext(map_file,"\n(1,1,") //todo replace with something saner
|
||||
var/content = copytext(map_file,findtext(map_file,quote+"\n",mapstart,0)+2,findtext(map_file,"\n"+quote,mapstart,0)+1)
|
||||
var/line_len = length(copytext(content,1,findtext(content,"\n",2,0)))
|
||||
|
||||
width = line_len/key_len
|
||||
height = length(content)/(line_len+1)
|
||||
var/bounds = maploader.load_map(file(path), 1, 1, 1, cropMap=FALSE, measureOnly=TRUE)
|
||||
if(bounds)
|
||||
width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1
|
||||
height = bounds[MAP_MAXY]
|
||||
return bounds
|
||||
|
||||
/datum/map_template/proc/load(turf/T, centered = FALSE)
|
||||
if(centered)
|
||||
@@ -37,14 +32,17 @@
|
||||
if(T.y+height > world.maxy)
|
||||
return
|
||||
|
||||
maploader.load_map(get_file(), T.x-1, T.y-1, T.z)
|
||||
var/list/bounds = maploader.load_map(get_file(), T.x, T.y, T.z, cropMap=TRUE)
|
||||
if(!bounds)
|
||||
return 0
|
||||
|
||||
//initialize things that are normally initialized after map load
|
||||
var/list/obj/machinery/atmospherics/atmos_machines = list()
|
||||
var/list/obj/structure/cable/cables = list()
|
||||
var/list/atom/atoms = list()
|
||||
|
||||
for(var/L in block(T,locate(T.x+width-1, T.y+height-1, T.z)))
|
||||
for(var/L in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]),
|
||||
locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
|
||||
var/turf/B = L
|
||||
for(var/A in B)
|
||||
atoms += A
|
||||
@@ -60,6 +58,7 @@
|
||||
SSair.setup_template_machinery(atmos_machines)
|
||||
|
||||
log_game("[name] loaded at at [T.x],[T.y],[T.z]")
|
||||
return 1
|
||||
|
||||
/datum/map_template/proc/get_file()
|
||||
if(mapfile)
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
H.color = overmind.blob_reagent_datum.complementary_color
|
||||
else
|
||||
H.color = "#000000"
|
||||
adjustHealth(-maxHealth*0.025)
|
||||
adjustHealth(-maxHealth*0.0125)
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
/obj/effect/blob/factory/Be_Pulsed()
|
||||
. = ..()
|
||||
if(naut)
|
||||
return
|
||||
if(spores.len >= max_spores)
|
||||
return
|
||||
if(spore_delay > world.time)
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
|
||||
/mob/camera/blob/verb/create_blobbernaut()
|
||||
set category = "Blob"
|
||||
set name = "Create Blobbernaut (30)"
|
||||
set name = "Create Blobbernaut (40)"
|
||||
set desc = "Create a powerful blobbernaut which is mildly smart and will attack enemies."
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/effect/blob/factory/B = locate(/obj/effect/blob/factory) in T
|
||||
@@ -150,7 +150,7 @@
|
||||
if(B.health < B.maxhealth * 0.5)
|
||||
src << "<span class='warning'>This factory blob is too damaged to sustain a blobbernaut.</span>"
|
||||
return
|
||||
if(!can_buy(30))
|
||||
if(!can_buy(40))
|
||||
return
|
||||
B.maxhealth = initial(B.maxhealth) * 0.25 //factories that produced a blobbernaut have much lower health
|
||||
B.check_health()
|
||||
@@ -163,7 +163,8 @@
|
||||
blobber.overmind = src
|
||||
blobber.update_icons()
|
||||
blobber.notransform = 1 //stop the naut from moving around
|
||||
blob_mobs.Add(blobber)
|
||||
blobber.adjustHealth(blobber.maxHealth * 0.5)
|
||||
blob_mobs += blobber
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
|
||||
var/client/C = null
|
||||
if(candidates.len) //if we got at least one candidate, they're a blobbernaut now.
|
||||
|
||||
@@ -9,15 +9,12 @@
|
||||
|
||||
var/power_type
|
||||
|
||||
|
||||
/datum/AI_Module/large/
|
||||
uses = 1
|
||||
|
||||
/datum/AI_Module/small/
|
||||
uses = 5
|
||||
|
||||
//////DOOMSDAY DEVICE
|
||||
|
||||
/datum/AI_Module/large/nuke_station
|
||||
module_name = "Doomsday Device"
|
||||
mod_pick_name = "nukestation"
|
||||
@@ -81,7 +78,6 @@
|
||||
var/message = "[timer] SECONDS UNTIL DOOMSDAY DEVICE ACTIVATION!"
|
||||
minor_announce(message, "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", 1)
|
||||
|
||||
|
||||
/obj/machinery/doomsday_device/proc/detonate(z_level = 1)
|
||||
for(var/mob/M in player_list)
|
||||
M << 'sound/machines/Alarm.ogg'
|
||||
@@ -106,11 +102,6 @@
|
||||
|
||||
power_type = /mob/living/silicon/ai/proc/fireproof_core
|
||||
|
||||
|
||||
|
||||
//////END DOOMSDAY DEVICE
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/fireproof_core()
|
||||
set category = "Malfunction"
|
||||
set name = "Fireproof Core"
|
||||
@@ -254,7 +245,6 @@
|
||||
src << "Virus package compiled. Select a target mech at any time. <b>You must remain on the station at all times. Loss of signal will result in total system lockout.</b>"
|
||||
verbs -= /mob/living/silicon/ai/proc/mech_takeover
|
||||
|
||||
|
||||
/datum/AI_Module/large/break_fire_alarms
|
||||
module_name = "Thermal Sensor Override"
|
||||
mod_pick_name = "burnpigs"
|
||||
@@ -303,8 +293,6 @@
|
||||
src << "<span class='notice'>All air alarm safeties on the station have been overriden. Air alarms may now use the Flood environmental mode."
|
||||
src.verbs -= /mob/living/silicon/ai/proc/break_air_alarms
|
||||
|
||||
|
||||
|
||||
/datum/AI_Module/small/overload_machine
|
||||
module_name = "Machine Overload"
|
||||
mod_pick_name = "overload"
|
||||
@@ -623,7 +611,6 @@
|
||||
src.use(usr)
|
||||
return
|
||||
|
||||
|
||||
/datum/AI_Module/large/eavesdrop
|
||||
module_name = "Enhanced Surveillance"
|
||||
mod_pick_name = "eavesdrop"
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
stop_automated_movement = 1
|
||||
status_flags = CANPUSH
|
||||
attack_sound = 'sound/magic/demon_attack1.ogg'
|
||||
var/feast_sound = 'sound/magic/Demon_consume.ogg'
|
||||
var/death_sound = 'sound/magic/demon_dies.ogg'
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
@@ -32,14 +34,20 @@
|
||||
var/boost = 0
|
||||
bloodcrawl = BLOODCRAWL_EAT
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
var/list/consumed_mobs = list()
|
||||
var/playstyle_string = "<B><font size=3 color='red'>You are a slaughter demon,</font> a terrible creature from another realm. You have a single desire: To kill. \
|
||||
You may use the \"Blood Crawl\" ability near blood pools to travel through them, appearing and dissaapearing from the station at will. \
|
||||
Pulling a dead or unconscious mob while you enter a pool will pull them in with you, allowing you to feast and regain your health. \
|
||||
You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. </B>"
|
||||
|
||||
loot = list(/obj/effect/decal/cleanable/blood, \
|
||||
/obj/effect/decal/cleanable/blood/innards, \
|
||||
/obj/item/organ/internal/heart/demon)
|
||||
del_on_death = 1
|
||||
deathmessage = "<span class='danger'>The generic slaughter demon screams in anger because this is the default death message!</span>"
|
||||
|
||||
/mob/living/simple_animal/slaughter/New()
|
||||
..()
|
||||
deathmessage = "<span class='danger'>[src] screams in anger as it collapses into a puddle of viscera.</span>"
|
||||
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
|
||||
AddSpell(bloodspell)
|
||||
if(istype(loc, /obj/effect/dummy/slaughter))
|
||||
@@ -53,22 +61,14 @@
|
||||
speed = 0
|
||||
|
||||
/mob/living/simple_animal/slaughter/death()
|
||||
..(1)
|
||||
new /obj/effect/decal/cleanable/blood (get_turf(src))
|
||||
var/obj/effect/decal/cleanable/blood/innards = new (get_turf(src))
|
||||
innards.icon = 'icons/obj/surgery.dmi'
|
||||
innards.icon_state = "innards"
|
||||
innards.name = "pile of viscera"
|
||||
innards.desc = "A repulsive pile of guts and gore."
|
||||
new /obj/item/organ/internal/heart/demon (src.loc)
|
||||
playsound(get_turf(src),'sound/magic/demon_dies.ogg', 200, 1)
|
||||
visible_message("<span class='danger'>[src] screams in anger as it collapses into a puddle of viscera, its most recent meals spilling out of it.</span>")
|
||||
for(var/mob/living/M in consumed_mobs)
|
||||
M.loc = get_turf(src)
|
||||
ghostize()
|
||||
qdel(src)
|
||||
return
|
||||
playsound(get_turf(src),death_sound, 200, 1)
|
||||
..()
|
||||
|
||||
/obj/effect/decal/cleanable/blood/innards
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
name = "pile of viscera"
|
||||
desc = "A repulsive pile of guts and gore."
|
||||
random_icon_states = list("innards")
|
||||
|
||||
/mob/living/simple_animal/slaughter/phasein()
|
||||
. = ..()
|
||||
@@ -115,3 +115,63 @@
|
||||
|
||||
/obj/item/organ/internal/heart/demon/Stop()
|
||||
return 0 // Always beating.
|
||||
|
||||
/mob/living/simple_animal/slaughter/laughter
|
||||
// The laughter demon! It's everyone's best friend! It just wants to hug
|
||||
// them so much, it wants to hug everyone at once!
|
||||
name = "laughter demon"
|
||||
real_name = "laughter demon"
|
||||
desc = "A large, adorable creature covered in armor with pink bows."
|
||||
speak_emote = list("giggles","titters","chuckles")
|
||||
emote_hear = list("gaffaws","laughs")
|
||||
response_help = "hugs"
|
||||
attacktext = "wildly tickles"
|
||||
|
||||
attack_sound = 'sound/items/bikehorn.ogg'
|
||||
feast_sound = 'sound/spookoween/scary_horn2.ogg'
|
||||
death_sound = 'sound/misc/sadtrombone.ogg'
|
||||
|
||||
icon_state = "bowmon"
|
||||
icon_living = "bowmon"
|
||||
|
||||
loot = list(/mob/living/simple_animal/pet/cat/kitten{name = "Laughter"})
|
||||
|
||||
// Keep the people we hug!
|
||||
var/list/consumed_mobs = list()
|
||||
|
||||
// HOT. PINK.
|
||||
//color = "#FF69B4"
|
||||
|
||||
|
||||
/mob/living/simple_animal/slaughter/laughter/New()
|
||||
..()
|
||||
|
||||
deathmessage = "<span class='warning'>[src] fades out, as all of its friends are released from its prison of hugs.</span>"
|
||||
|
||||
/mob/living/simple_animal/slaughter/laughter/death()
|
||||
if(!consumed_mobs)
|
||||
return ..()
|
||||
|
||||
for(var/mob/living/M in consumed_mobs)
|
||||
M.loc = get_turf(src)
|
||||
if(M.revive(full_heal = 1))
|
||||
// Feel there should be a better way of FORCING a mob's ghost
|
||||
// back into the body
|
||||
if(!M.ckey)
|
||||
for(var/mob/dead/observer/ghost in player_list)
|
||||
if(M.real_name == ghost.real_name)
|
||||
ghost.reenter_corpse()
|
||||
break
|
||||
M << "<span class='clown'>You leave the [src]'s warm embrace, and feel ready to take on the world.</span>"
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/slaughter/laughter/bloodcrawl_swallow(var/mob/living/victim)
|
||||
if(consumed_mobs)
|
||||
// Keep their corpse so rescue is possible
|
||||
consumed_mobs += victim
|
||||
else
|
||||
// Be safe and just eject the corpse
|
||||
victim.forceMove(get_turf(victim))
|
||||
victim.exit_blood_effect()
|
||||
victim.visible_message("[victim] falls out of the air, covered in blood, looking highly confused. And dead.")
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
/obj/mecha/working/ripley/Destroy()
|
||||
for(var/i=1, i <= hides, i++)
|
||||
new /obj/item/asteroid/goliath_hide(loc) //If a goliath-plated ripley gets killed, all the plates drop
|
||||
new /obj/item/stack/sheet/animalhide/goliath_hide(loc) //If a goliath-plated ripley gets killed, all the plates drop
|
||||
damage_absorption["brute"] = initial(damage_absorption["brute"])
|
||||
for(var/atom/movable/A in cargo)
|
||||
A.loc = loc
|
||||
|
||||
@@ -107,6 +107,11 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
|
||||
slot_drone_storage\
|
||||
)
|
||||
|
||||
// Needs to be in /obj/item because corgis can wear a lot of
|
||||
// non-clothing items
|
||||
var/datum/dog_fashion/dog_fashion = null
|
||||
|
||||
|
||||
/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)
|
||||
if(((src in target) && !target_self) || (!istype(target.loc, /turf) && !istype(target, /turf) && not_inside))
|
||||
return 0
|
||||
@@ -566,4 +571,4 @@ obj/item/proc/item_action_slot_check(slot, mob/user)
|
||||
return heat
|
||||
|
||||
/obj/item/proc/is_sharp()
|
||||
return sharpness
|
||||
return sharpness
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
/obj/item/device/lightreplacer
|
||||
|
||||
name = "light replacer"
|
||||
desc = "A device to automatically replace lights. Refill with working lightbulbs."
|
||||
desc = "A device to automatically replace lights. Refill with broken or working lightbulbs, or sheets of glass."
|
||||
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "lightreplacer0"
|
||||
@@ -61,6 +61,11 @@
|
||||
var/decrement = 1
|
||||
var/charge = 1
|
||||
|
||||
// Eating used bulbs gives us bulb shards
|
||||
var/bulb_shards = 0
|
||||
// when we get this many shards, we get a free bulb.
|
||||
var/shards_required = 4
|
||||
|
||||
/obj/item/device/lightreplacer/New()
|
||||
uses = max_uses / 2
|
||||
failmsg = "The [name]'s refill light blinks red."
|
||||
@@ -68,7 +73,7 @@
|
||||
|
||||
/obj/item/device/lightreplacer/examine(mob/user)
|
||||
..()
|
||||
user << "It has [uses] light\s remaining."
|
||||
user << status_string()
|
||||
|
||||
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user, params)
|
||||
|
||||
@@ -79,62 +84,74 @@
|
||||
return
|
||||
else if(G.use(decrement))
|
||||
AddUses(increment)
|
||||
user << "<span class='notice'>You insert a piece of glass into the [src.name]. You have [uses] lights remaining.</span>"
|
||||
user << "<span class='notice'>You insert a piece of glass into the [src.name]. You have [uses] light\s remaining.</span>"
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>You need one sheet of glass to replace lights!</span>"
|
||||
|
||||
if(istype(W, /obj/item/weapon/light))
|
||||
var/new_bulbs = 0
|
||||
var/obj/item/weapon/light/L = W
|
||||
if(L.status == 0) // LIGHT OKAY
|
||||
if(uses < max_uses)
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
AddUses(1)
|
||||
user << "<span class='notice'>You insert the [L.name] into the [src.name]. You have [uses] lights remaining.</span>"
|
||||
qdel(L)
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>You need a working light!</span>"
|
||||
return
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
new_bulbs += AddShards(1)
|
||||
qdel(L)
|
||||
if(new_bulbs != 0)
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
user << "<span class='notice'>You insert the [L.name] into the [src.name]. " + status_string() + "</span>"
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/S = W
|
||||
var/found_good_light = 0
|
||||
var/replaced_something = 0
|
||||
var/found_lightbulbs = FALSE
|
||||
var/replaced_something = TRUE
|
||||
|
||||
for(var/obj/item/I in S.contents)
|
||||
if(istype(I,/obj/item/weapon/light))
|
||||
var/obj/item/weapon/light/L = I
|
||||
found_lightbulbs = TRUE
|
||||
if(src.uses >= max_uses)
|
||||
break
|
||||
if(L.status == LIGHT_OK)
|
||||
found_good_light = 1
|
||||
if(src.uses < max_uses)
|
||||
qdel(L)
|
||||
AddUses(1)
|
||||
replaced_something = 1
|
||||
else
|
||||
break
|
||||
replaced_something = TRUE
|
||||
AddUses(1)
|
||||
qdel(L)
|
||||
|
||||
if(!found_good_light)
|
||||
user << "<span class='warning'>\The [S] contains no useable lights!</span>"
|
||||
else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED)
|
||||
replaced_something = TRUE
|
||||
AddShards(1)
|
||||
qdel(L)
|
||||
|
||||
if(!found_lightbulbs)
|
||||
user << "<span class='warning'>\The [S] contains no bulbs.</span>"
|
||||
return
|
||||
|
||||
if(!replaced_something && src.uses == max_uses)
|
||||
user << "<span class='warning'>\The [src] is full!</span>"
|
||||
return
|
||||
|
||||
user << "<span class='notice'>You fill \the [src] with lights from \the [S]. You have [uses] lights remaining.</span>"
|
||||
user << "<span class='notice'>You fill \the [src] with lights from \the [S]. " + status_string() + "</span>"
|
||||
|
||||
/obj/item/device/lightreplacer/emag_act()
|
||||
if(!emagged)
|
||||
Emag()
|
||||
|
||||
/obj/item/device/lightreplacer/attack_self(mob/user)
|
||||
user << "It has [uses] lights remaining."
|
||||
user << status_string()
|
||||
|
||||
|
||||
/obj/item/device/lightreplacer/update_icon()
|
||||
icon_state = "lightreplacer[emagged]"
|
||||
|
||||
/obj/item/device/lightreplacer/proc/status_string()
|
||||
return "It has [uses] light\s remaining (plus [bulb_shards] fragment\s)."
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Use(mob/user)
|
||||
|
||||
@@ -144,7 +161,15 @@
|
||||
|
||||
// Negative numbers will subtract
|
||||
/obj/item/device/lightreplacer/proc/AddUses(amount = 1)
|
||||
uses = min(max(uses + amount, 0), max_uses)
|
||||
uses = Clamp(uses + amount, 0, max_uses)
|
||||
|
||||
/obj/item/device/lightreplacer/proc/AddShards(amount = 1)
|
||||
bulb_shards += amount
|
||||
var/new_bulbs = round(bulb_shards / shards_required)
|
||||
if(new_bulbs > 0)
|
||||
AddUses(new_bulbs)
|
||||
bulb_shards = bulb_shards % shards_required
|
||||
return new_bulbs
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Charge(var/mob/user)
|
||||
charge += 1
|
||||
@@ -160,14 +185,10 @@
|
||||
U << "<span class='notice'>You replace the [target.fitting] with \the [src].</span>"
|
||||
|
||||
if(target.status != LIGHT_EMPTY)
|
||||
|
||||
var/obj/item/weapon/light/L1 = new target.light_type(target.loc)
|
||||
L1.status = target.status
|
||||
L1.rigged = target.rigged
|
||||
L1.brightness = target.brightness
|
||||
L1.switchcount = target.switchcount
|
||||
target.switchcount = 0
|
||||
L1.update()
|
||||
var/new_bulbs = AddShards(1)
|
||||
if(new_bulbs != 0)
|
||||
U << "<span class='notice'>\The [src] has fabricated a new bulb from the broken bulbs it has stored. It now has [uses] uses.</span>"
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
|
||||
target.status = LIGHT_EMPTY
|
||||
target.update()
|
||||
@@ -212,7 +233,22 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/device/lightreplacer/cyborg
|
||||
/obj/item/device/lightreplacer/afterattack(atom/T, mob/U, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(!isturf(T))
|
||||
return
|
||||
|
||||
var/used = FALSE
|
||||
for(var/atom/A in T)
|
||||
if(!CanUse(U))
|
||||
break
|
||||
used = TRUE
|
||||
if(istype(A, /obj/machinery/light))
|
||||
ReplaceLight(A, U)
|
||||
|
||||
if(!used)
|
||||
U << failmsg
|
||||
|
||||
/obj/item/device/lightreplacer/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J)
|
||||
J.put_in_cart(src, user)
|
||||
@@ -225,4 +261,4 @@
|
||||
#undef LIGHT_OK
|
||||
#undef LIGHT_EMPTY
|
||||
#undef LIGHT_BROKEN
|
||||
#undef LIGHT_BURNED
|
||||
#undef LIGHT_BURNED
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
var/track_cooldown = 0
|
||||
var/track_delay = 10 //How often it checks for proximity
|
||||
var/detect_state = PROXIMITY_NONE
|
||||
var/turf/our_turf
|
||||
var/rangealert = 8 //Glows red when inside
|
||||
var/rangewarning = 20 //Glows yellow when inside
|
||||
|
||||
@@ -47,12 +46,12 @@
|
||||
if(track_cooldown > world.time)
|
||||
return
|
||||
detect_state = PROXIMITY_NONE
|
||||
our_turf = get_turf(src)
|
||||
multitool_detect()
|
||||
icon_state = "[initial(icon_state)][detect_state]"
|
||||
track_cooldown = world.time + track_delay // 1 second
|
||||
track_cooldown = world.time + track_delay
|
||||
|
||||
/obj/item/device/multitool/ai_detect/proc/multitool_detect()
|
||||
var/turf/our_turf = get_turf(src)
|
||||
for(var/mob/living/silicon/ai/AI in ai_list)
|
||||
if(AI.cameraFollow == src)
|
||||
detect_state = PROXIMITY_ON_SCREEN
|
||||
@@ -76,7 +75,8 @@
|
||||
track_delay = 5
|
||||
|
||||
/obj/item/device/multitool/ai_detect/admin/multitool_detect()
|
||||
for(var/mob/J in range(rangewarning,src))
|
||||
var/turf/our_turf = get_turf(src)
|
||||
for(var/mob/J in urange(rangewarning,our_turf))
|
||||
if(admin_datums[J.ckey])
|
||||
detect_state = PROXIMITY_NEAR
|
||||
var/turf/detect_turf = get_turf(J)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
item_state = "beacon"
|
||||
var/code = "electronic"
|
||||
origin_tech = "bluespace=1"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/device/radio/beacon/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
return
|
||||
@@ -29,4 +30,4 @@
|
||||
//Probably a better way of doing this, I'm lazy.
|
||||
/obj/item/device/radio/beacon/bacon/proc/digest_delay()
|
||||
spawn(600)
|
||||
qdel(src)*/ //Bacon beacons are no more rip in peace
|
||||
qdel(src)*/ //Bacon beacons are no more rip in peace
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
slot_flags = SLOT_EARS
|
||||
var/obj/item/device/encryptionkey/keyslot2 = null
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/device/radio/headset/New()
|
||||
..()
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
var/anyai = 1
|
||||
var/mob/living/silicon/ai/ai = list()
|
||||
var/last_tick //used to delay the powercheck
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/device/radio/intercom/New()
|
||||
..()
|
||||
@@ -67,4 +68,4 @@
|
||||
icon_state = "intercom"
|
||||
|
||||
/obj/item/device/radio/intercom/rejects_blood()
|
||||
return 1
|
||||
return 1
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
suffix = "\[3\]"
|
||||
icon_state = "walkietalkie"
|
||||
item_state = "walkietalkie"
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
var/on = 1 // 0 for off
|
||||
var/last_transmission
|
||||
var/frequency = 1459 //common chat
|
||||
@@ -539,6 +540,7 @@
|
||||
/obj/item/device/radio/borg
|
||||
name = "cyborg radio"
|
||||
subspace_switchable = 1
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/device/radio/borg/syndicate
|
||||
syndie = 1
|
||||
@@ -585,3 +587,4 @@
|
||||
|
||||
/obj/item/device/radio/off // Station bounced radios, their only difference is spawning with the speakers off, this was made to help the lag.
|
||||
listening = 0 // And it's nice to have a subtype too for future features.
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
|
||||
@@ -133,7 +133,21 @@ var/global/list/datum/stack_recipe/xeno_recipes = list ( \
|
||||
desc = "Long stringy filaments which presumably came from a watcher's wings."
|
||||
singular_name = "watcher sinew"
|
||||
icon_state = "sinew"
|
||||
origin_tech = "bio=4"
|
||||
origin_tech = "biotech=4"
|
||||
|
||||
/*
|
||||
* Plates
|
||||
*/
|
||||
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide
|
||||
name = "goliath hide plates"
|
||||
desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "goliath_hide"
|
||||
singular_name = "hide plate"
|
||||
flags = NOBLUDGEON
|
||||
w_class = 3
|
||||
layer = 4
|
||||
|
||||
|
||||
//Step one - dehairing.
|
||||
|
||||
@@ -265,4 +265,6 @@ var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \
|
||||
w_class = 3
|
||||
throw_speed = 1
|
||||
throw_range = 3
|
||||
origin_tech = "materials=2;bio=2"
|
||||
origin_tech = "materials=2;bio=2"
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
force = 10
|
||||
materials = list(MAT_METAL=90)
|
||||
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
var/max_water = 50
|
||||
var/last_use = 1
|
||||
var/safety = 1
|
||||
@@ -34,6 +35,7 @@
|
||||
materials = list()
|
||||
max_water = 30
|
||||
sprite_name = "miniFE"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/weapon/extinguisher/New()
|
||||
..()
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
desc = "A backpack that opens into a localized pocket of Blue Space."
|
||||
origin_tech = "bluespace=4"
|
||||
icon_state = "holdingpack"
|
||||
max_w_class = 5
|
||||
max_w_class = 6
|
||||
max_combined_w_class = 35
|
||||
burn_state = FIRE_PROOF
|
||||
var/pshoom = 'sound/items/PSHOOM.ogg'
|
||||
|
||||
@@ -471,8 +471,8 @@
|
||||
|
||||
|
||||
/obj/item/weapon/storage/Destroy()
|
||||
var/turf = get_turf(src)
|
||||
empty_object_contents(0, turf)
|
||||
for(var/obj/O in contents)
|
||||
O.mouse_opacity = initial(O.mouse_opacity)
|
||||
|
||||
close_all()
|
||||
qdel(boxes)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
icon_state = "oxygen"
|
||||
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
|
||||
force = 10
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
|
||||
|
||||
/obj/item/weapon/tank/internals/oxygen/New()
|
||||
@@ -28,10 +29,12 @@
|
||||
/obj/item/weapon/tank/internals/oxygen/yellow
|
||||
desc = "A tank of oxygen, this one is yellow."
|
||||
icon_state = "oxygen_f"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/weapon/tank/internals/oxygen/red
|
||||
desc = "A tank of oxygen, this one is red."
|
||||
icon_state = "oxygen_fr"
|
||||
dog_fashion = null
|
||||
|
||||
|
||||
/*
|
||||
@@ -59,7 +62,7 @@
|
||||
desc = "Mixed anyone?"
|
||||
icon_state = "oxygen"
|
||||
force = 10
|
||||
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
|
||||
/obj/item/weapon/tank/internals/air/New()
|
||||
..()
|
||||
|
||||
@@ -71,6 +71,9 @@
|
||||
return 0
|
||||
if(buckled_mobs.len)
|
||||
return 0
|
||||
if(usr.incapacitated())
|
||||
usr << "<span class='warning'>You can't do that right now!</span>"
|
||||
return 0
|
||||
usr.visible_message("[usr] collapses \the [src.name].", "<span class='notice'>You collapse \the [src.name].</span>")
|
||||
new foldabletype(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
@@ -216,6 +216,9 @@
|
||||
if(over_object == usr && Adjacent(usr))
|
||||
if(!item_chair || !ishuman(usr) || buckled_mobs.len || src.flags & NODECONSTRUCT)
|
||||
return
|
||||
if(usr.incapacitated())
|
||||
usr << "<span class='warning'>You can't do that right now!</span>"
|
||||
return
|
||||
usr.visible_message("<span class='notice'>[usr] grabs \the [src.name].</span>", "<span class='notice'>You grab \the [src.name].</span>")
|
||||
var/C = new item_chair(loc)
|
||||
usr.put_in_hands(C)
|
||||
|
||||
@@ -19,6 +19,7 @@ LINEN BINS
|
||||
item_color = "white"
|
||||
burn_state = FLAMMABLE
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/ghost
|
||||
|
||||
/obj/item/weapon/bedsheet/attack(mob/living/M, mob/user)
|
||||
if(!attempt_initiate_surgery(src, M, user))
|
||||
|
||||
@@ -251,7 +251,8 @@
|
||||
"<span class='italics'>You hear welding.</span>")
|
||||
update_icon()
|
||||
else if(user.a_intent != "harm" && !(W.flags & NOBLUDGEON))
|
||||
togglelock(user)
|
||||
if(!toggle(user))
|
||||
togglelock(user)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
/turf/open/Initalize_Atmos(times_fired)
|
||||
excited = 0
|
||||
update_visuals()
|
||||
if (blocks_air)
|
||||
return
|
||||
|
||||
current_cycle = times_fired
|
||||
|
||||
//cache some vars
|
||||
|
||||
@@ -129,17 +129,18 @@
|
||||
qdel(L)
|
||||
|
||||
//Creates a new turf
|
||||
/turf/proc/ChangeTurf(path)
|
||||
/turf/proc/ChangeTurf(path, defer_change = FALSE)
|
||||
if(!path)
|
||||
return
|
||||
if(path == type)
|
||||
if(!use_preloader && path == type) // Don't no-op if the map loader requires it to be reconstructed
|
||||
return src
|
||||
var/old_blueprint_data = blueprint_data
|
||||
|
||||
SSair.remove_from_active(src)
|
||||
|
||||
var/turf/W = new path(src)
|
||||
W.AfterChange()
|
||||
if(!defer_change)
|
||||
W.AfterChange()
|
||||
W.blueprint_data = old_blueprint_data
|
||||
return W
|
||||
|
||||
@@ -153,10 +154,11 @@
|
||||
|
||||
queue_smooth_neighbors(src)
|
||||
|
||||
/turf/open/AfterChange()
|
||||
/turf/open/AfterChange(ignore_air)
|
||||
..()
|
||||
RemoveLattice()
|
||||
Assimilate_Air()
|
||||
if(!ignore_air)
|
||||
Assimilate_Air()
|
||||
|
||||
//////Assimilate Air//////
|
||||
/turf/open/proc/Assimilate_Air()
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
preview += image('icons/turf/overlays.dmi',S,"greenOverlay")
|
||||
usr.client.images += preview
|
||||
if(alert(usr,"Confirm location.","Template Confirm","Yes","No") == "Yes")
|
||||
template.load(T, centered = TRUE)
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has placed a map template ([template.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>(JMP)</a></span>")
|
||||
if(template.load(T, centered = TRUE))
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has placed a map template ([template.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>(JMP)</a></span>")
|
||||
else
|
||||
usr << "Failed to place map"
|
||||
usr.client.images -= preview
|
||||
|
||||
/client/proc/map_template_upload()
|
||||
@@ -34,6 +36,9 @@
|
||||
return
|
||||
|
||||
var/datum/map_template/M = new(map=map, rename="[map]")
|
||||
M.preload_size(map)
|
||||
map_templates[M.name] = M
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has uploaded a map template ([map])</span>")
|
||||
if(M.preload_size(map))
|
||||
usr << "Map template '[map]' ready to place ([M.width]x[M.height])"
|
||||
map_templates[M.name] = M
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has uploaded a map template ([map])</span>")
|
||||
else
|
||||
usr << "Map template '[map]' failed to load properly"
|
||||
|
||||
@@ -53,9 +53,11 @@ dmm_suite{
|
||||
|
||||
*/
|
||||
|
||||
verb/load_map(var/dmm_file as file, var/x_offset as num, var/y_offset as num, var/z_offset as num){
|
||||
verb/load_map(var/dmm_file as file, var/x_offset as num, var/y_offset as num, var/z_offset as num, var/cropMap as num, var/measureOnly as num){
|
||||
// dmm_file: A .dmm file to load (Required).
|
||||
// z_offset: A number representing the z-level on which to start loading the map (Optional).
|
||||
// cropMap: When true, the map will be cropped to fit the existing world dimensions (Optional).
|
||||
// measureOnly: When true, no changes will be made to the world (Optional).
|
||||
}
|
||||
verb/write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num){
|
||||
// t1: A turf representing one corner of a three dimensional grid (Required).
|
||||
|
||||
@@ -6,6 +6,14 @@
|
||||
var/global/use_preloader = FALSE
|
||||
var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
/dmm_suite
|
||||
// /"([a-zA-Z]+)" = \(((?:.|\n)*?)\)\n(?!\t)|\((\d+),(\d+),(\d+)\) = \{"([a-zA-Z\n]*)"\}/g
|
||||
var/static/regex/dmmRegex = new/regex({""(\[a-zA-Z]+)" = \\(((?:.|\n)*?)\\)\n(?!\t)|\\((\\d+),(\\d+),(\\d+)\\) = \\{"(\[a-zA-Z\n]*)"\\}"}, "g")
|
||||
// /^[\s\n]+"?|"?[\s\n]+$|^"|"$/g
|
||||
var/static/regex/trimQuotesRegex = new/regex({"^\[\\s\n]+"?|"?\[\\s\n]+$|^"|"$"}, "g")
|
||||
// /^[\s\n]+|[\s\n]+$/
|
||||
var/static/regex/trimRegex = new/regex("^\[\\s\n]+|\[\\s\n]+$", "g")
|
||||
var/static/list/modelCache = list()
|
||||
|
||||
/**
|
||||
* Construct the model map and control the loading process
|
||||
@@ -17,92 +25,120 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
* 2) Read the map line by line, parsing the result (using parse_grid)
|
||||
*
|
||||
*/
|
||||
/dmm_suite/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num)
|
||||
if(!z_offset)//what z_level we are creating the map on
|
||||
z_offset = world.maxz+1
|
||||
/dmm_suite/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num)
|
||||
var/tfile = dmm_file//the map file we're creating
|
||||
if(isfile(tfile))
|
||||
tfile = file2text(tfile)
|
||||
|
||||
if(!x_offset)
|
||||
x_offset = 0
|
||||
|
||||
x_offset = 1
|
||||
if(!y_offset)
|
||||
y_offset = 0
|
||||
var/quote = ascii2text(34)
|
||||
var/tfile = file2text(dmm_file)//the map file we're creating
|
||||
var/tfile_len = length(tfile)
|
||||
var/lpos = 1 // the models definition index
|
||||
y_offset = 1
|
||||
if(!z_offset)
|
||||
z_offset = world.maxz + 1
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//first let's map model keys (e.g "aa") to their contents (e.g /turf/open/space{variables})
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
|
||||
var/list/grid_models = list()
|
||||
var/key_len = length(copytext(tfile,2,findtext(tfile,quote,2,0)))//the length of the model key (e.g "aa" or "aba")
|
||||
var/key_len = 0
|
||||
|
||||
//proceed line by line
|
||||
for(lpos=1; lpos<tfile_len; lpos=findtext(tfile,"\n",lpos,0)+1)
|
||||
var/tline = copytext(tfile,lpos,findtext(tfile,"\n",lpos,0))
|
||||
if(copytext(tline,1,2) != quote)//we reached the map "layout"
|
||||
break
|
||||
var/model_key = copytext(tline,2,2+key_len)
|
||||
var/model_contents = copytext(tline,findtext(tfile,"=")+3,length(tline))
|
||||
grid_models[model_key] = model_contents
|
||||
sleep(-1)
|
||||
dmmRegex.next = 1
|
||||
while(dmmRegex.Find(tfile, dmmRegex.next))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//now let's fill the map with turf and objects using the constructed model map
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// "aa" = (/type{vars=blah})
|
||||
if(dmmRegex.group[1]) // Model
|
||||
var/key = dmmRegex.group[1]
|
||||
if(grid_models[key]) // Duplicate model keys are ignored in DMMs
|
||||
continue
|
||||
if(key_len != length(key))
|
||||
if(!key_len)
|
||||
key_len = length(key)
|
||||
else
|
||||
throw EXCEPTION("Inconsistant key length in DMM")
|
||||
if(!measureOnly)
|
||||
grid_models[key] = dmmRegex.group[2]
|
||||
|
||||
//position of the currently processed square
|
||||
var/zcrd=-1
|
||||
var/ycrd=y_offset
|
||||
var/xcrd=x_offset
|
||||
// (1,1,1) = {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
|
||||
else if(dmmRegex.group[3]) // Coords
|
||||
if(!key_len)
|
||||
throw EXCEPTION("Coords before model definition in DMM")
|
||||
|
||||
for(var/zpos=findtext(tfile,"\n(1,1,",lpos,0);zpos!=0;zpos=findtext(tfile,"\n(1,1,",zpos+1,0)) //in case there's several maps to load
|
||||
var/xcrdStart = text2num(dmmRegex.group[3]) + x_offset - 1
|
||||
//position of the currently processed square
|
||||
var/xcrd
|
||||
var/ycrd = text2num(dmmRegex.group[4]) + y_offset - 1
|
||||
var/zcrd = text2num(dmmRegex.group[5]) + z_offset - 1
|
||||
|
||||
zcrd++
|
||||
world.maxz = max(world.maxz, zcrd+z_offset)//create a new z_level if needed
|
||||
if(zcrd > world.maxz)
|
||||
if(cropMap)
|
||||
continue
|
||||
else
|
||||
world.maxz = zcrd //create a new z_level if needed
|
||||
|
||||
var/zgrid = copytext(tfile,findtext(tfile,quote+"\n",zpos,0)+2,findtext(tfile,"\n"+quote,zpos,0)+1) //copy the whole map grid
|
||||
var/z_depth = length(zgrid)
|
||||
bounds[MAP_MINX] = min(bounds[MAP_MINX], xcrdStart)
|
||||
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], zcrd)
|
||||
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], zcrd)
|
||||
|
||||
//if exceeding the world max x or y, increase it
|
||||
var/x_depth = length(copytext(zgrid,1,findtext(zgrid,"\n",2,0)))
|
||||
var/x_tilecount = x_depth/key_len
|
||||
if(world.maxx<x_tilecount)
|
||||
world.maxx=x_tilecount
|
||||
var/list/gridLines = splittext(dmmRegex.group[6], "\n")
|
||||
|
||||
var/y_depth = z_depth / (x_depth+1)//x_depth + 1 because we're counting the '\n' characters in z_depth
|
||||
if(world.maxy<y_depth)
|
||||
world.maxy=y_depth
|
||||
var/leadingBlanks = 0
|
||||
while(leadingBlanks < gridLines.len && gridLines[++leadingBlanks] == "")
|
||||
if(leadingBlanks > 1)
|
||||
gridLines.Cut(1, leadingBlanks) // Remove all leading blank lines.
|
||||
|
||||
//then proceed it line by line, starting from top
|
||||
ycrd = y_depth
|
||||
if(!gridLines.len) // Skip it if only blank lines exist.
|
||||
continue
|
||||
|
||||
for(var/gpos=1;gpos!=0;gpos=findtext(zgrid,"\n",gpos,0)+1)
|
||||
var/grid_line = copytext(zgrid,gpos,findtext(zgrid,"\n",gpos,0))
|
||||
if(gridLines.len && gridLines[gridLines.len] == "")
|
||||
gridLines.Cut(gridLines.len) // Remove only one blank line at the end.
|
||||
|
||||
//fill the current square using the model map
|
||||
xcrd=0
|
||||
bounds[MAP_MINY] = min(bounds[MAP_MINY], ycrd)
|
||||
ycrd += gridLines.len - 1 // Start at the top and work down
|
||||
|
||||
if(!cropMap && ycrd > world.maxy)
|
||||
if(!measureOnly)
|
||||
world.maxy = ycrd // Expand Y here. X is expanded in the loop below
|
||||
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], ycrd)
|
||||
else
|
||||
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], min(ycrd, world.maxy))
|
||||
|
||||
for(var/mpos in 1 to x_depth step key_len)
|
||||
xcrd++
|
||||
var/model_key = copytext(grid_line,mpos,mpos+key_len)
|
||||
parse_grid(grid_models[model_key],xcrd+x_offset,ycrd+y_offset,zcrd+z_offset)
|
||||
var/maxx = xcrdStart
|
||||
if(measureOnly)
|
||||
for(var/line in gridLines)
|
||||
maxx = max(maxx, xcrdStart + length(line) / key_len - 1)
|
||||
else
|
||||
for(var/line in gridLines)
|
||||
if(ycrd <= world.maxy && ycrd >= 1)
|
||||
xcrd = xcrdStart
|
||||
for(var/tpos = 1 to length(line) - key_len + 1 step key_len)
|
||||
if(xcrd > world.maxx)
|
||||
if(cropMap)
|
||||
break
|
||||
else
|
||||
world.maxx = xcrd
|
||||
|
||||
//reached end of current map
|
||||
if(gpos+x_depth+1>z_depth)
|
||||
break
|
||||
if(xcrd >= 1)
|
||||
var/model_key = copytext(line, tpos, tpos + key_len)
|
||||
if(!grid_models[model_key])
|
||||
throw EXCEPTION("Undefined model key in DMM.")
|
||||
parse_grid(grid_models[model_key], xcrd, ycrd, zcrd)
|
||||
CHECK_TICK
|
||||
|
||||
ycrd--
|
||||
CHECK_TICK
|
||||
maxx = max(maxx, xcrd)
|
||||
++xcrd
|
||||
--ycrd
|
||||
|
||||
|
||||
//reached End Of File
|
||||
if(findtext(tfile,quote+"}",zpos,0)+2==tfile_len)
|
||||
break
|
||||
bounds[MAP_MAXX] = max(bounds[MAP_MAXX], cropMap ? min(maxx, world.maxx) : maxx)
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
if(bounds[1] == 1.#INF) // Shouldn't need to check every item
|
||||
return null
|
||||
else
|
||||
for(var/t in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
|
||||
var/turf/T = t
|
||||
//we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs
|
||||
T.AfterChange(TRUE)
|
||||
return bounds
|
||||
|
||||
/**
|
||||
* Fill a given tile with its area/turf/objects/mobs
|
||||
@@ -127,41 +163,55 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
same construction as those contained in a .dmm file, and instantiates them.
|
||||
*/
|
||||
|
||||
var/list/members = list()//will contain all members (paths) in model (in our example : /turf/unsimulated/wall and /area/mine/explored)
|
||||
var/list/members_attributes = list()//will contain lists filled with corresponding variables, if any (in our example : list(icon_state = "rock") and list())
|
||||
var/list/members //will contain all members (paths) in model (in our example : /turf/unsimulated/wall and /area/mine/explored)
|
||||
var/list/members_attributes //will contain lists filled with corresponding variables, if any (in our example : list(icon_state = "rock") and list())
|
||||
var/list/cached = modelCache[model]
|
||||
var/index
|
||||
|
||||
if(cached)
|
||||
members = cached[1]
|
||||
members_attributes = cached[2]
|
||||
else
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//Constructing members and corresponding variables lists
|
||||
////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////
|
||||
//Constructing members and corresponding variables lists
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
var/index=1
|
||||
var/old_position = 1
|
||||
var/dpos
|
||||
members = list()
|
||||
members_attributes = list()
|
||||
index = 1
|
||||
|
||||
do
|
||||
//finding next member (e.g /turf/unsimulated/wall{icon_state = "rock"} or /area/mine/explored)
|
||||
dpos= find_next_delimiter_position(model,old_position,",","{","}")//find next delimiter (comma here) that's not within {...}
|
||||
var/old_position = 1
|
||||
var/dpos
|
||||
|
||||
var/full_def = copytext(model,old_position,dpos)//full definition, e.g : /obj/foo/bar{variables=derp}
|
||||
var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))//path definition, e.g /obj/foo/bar
|
||||
members.Add(atom_def)
|
||||
old_position = dpos + 1
|
||||
do
|
||||
//finding next member (e.g /turf/unsimulated/wall{icon_state = "rock"} or /area/mine/explored)
|
||||
dpos = find_next_delimiter_position(model, old_position, ",", "{", "}") //find next delimiter (comma here) that's not within {...}
|
||||
|
||||
//transform the variables in text format into a list (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
|
||||
var/list/fields = list()
|
||||
var/full_def = trim_text(copytext(model, old_position, dpos)) //full definition, e.g : /obj/foo/bar{variables=derp}
|
||||
var/variables_start = findtext(full_def, "{")
|
||||
var/atom_def = text2path(trim_text(copytext(full_def, 1, variables_start))) //path definition, e.g /obj/foo/bar
|
||||
old_position = dpos + 1
|
||||
|
||||
var/variables_start = findtext(full_def,"{")
|
||||
if(variables_start)//if there's any variable
|
||||
full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}'
|
||||
fields = readlist(full_def, ";")
|
||||
if(!atom_def) // Skip the item if the path does not exist. Fix your crap, mappers!
|
||||
continue
|
||||
members.Add(atom_def)
|
||||
|
||||
//then fill the members_attributes list with the corresponding variables
|
||||
members_attributes.len++
|
||||
members_attributes[index++] = fields
|
||||
CHECK_TICK
|
||||
//transform the variables in text format into a list (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
|
||||
var/list/fields = list()
|
||||
|
||||
while(dpos != 0)
|
||||
if(variables_start)//if there's any variable
|
||||
full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}'
|
||||
fields = readlist(full_def, ";")
|
||||
|
||||
//then fill the members_attributes list with the corresponding variables
|
||||
members_attributes.len++
|
||||
members_attributes[index++] = fields
|
||||
|
||||
CHECK_TICK
|
||||
while(dpos != 0)
|
||||
|
||||
modelCache[model] = list(members, members_attributes)
|
||||
|
||||
|
||||
////////////////
|
||||
@@ -170,10 +220,6 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
//The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile
|
||||
|
||||
//in case of multiples turfs on one tile,
|
||||
//will contains the images of all underlying turfs, to simulate the DMM multiple tiles piling
|
||||
var/list/turfs_underlays = list()
|
||||
|
||||
//first instance the /area and remove it from the members list
|
||||
index = members.len
|
||||
if(members[index] != /area/template_noop)
|
||||
@@ -187,7 +233,6 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
if(use_preloader && instance)
|
||||
_preloader.load(instance)
|
||||
members.Remove(members[index])
|
||||
|
||||
//then instance the /turf and, if multiple tiles are presents, simulates the DMM underlays piling effect
|
||||
|
||||
@@ -203,11 +248,10 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
if(T)
|
||||
//if others /turf are presents, simulates the underlays piling effect
|
||||
index = first_turf_index + 1
|
||||
while(index <= members.len)
|
||||
turfs_underlays.Insert(1,image(T.icon,null,T.icon_state,T.layer,T.dir))//add the current turf image to the underlays list
|
||||
var/turf/UT = instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)//instance new turf
|
||||
add_underlying_turf(UT,T,turfs_underlays)//simulates the DMM piling effect
|
||||
T = UT
|
||||
while(index <= members.len - 1) // Last item is an /area
|
||||
var/underlay = T.appearance
|
||||
T = instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)//instance new turf
|
||||
T.underlays += underlay
|
||||
index++
|
||||
|
||||
//finally instance all remainings objects/mobs
|
||||
@@ -226,7 +270,11 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
var/turf/T = locate(x,y,z)
|
||||
if(T)
|
||||
instance = new path (T)//first preloader pass
|
||||
if(ispath(path, /turf))
|
||||
T.ChangeTurf(path, TRUE)
|
||||
instance = T
|
||||
else
|
||||
instance = new path (T)//first preloader pass
|
||||
|
||||
if(use_preloader && instance)//second preloader pass, for those atoms that don't ..() in New()
|
||||
_preloader.load(instance)
|
||||
@@ -236,16 +284,11 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
//text trimming (both directions) helper proc
|
||||
//optionally removes quotes before and after the text (for variable name)
|
||||
/dmm_suite/proc/trim_text(what as text,trim_quotes=0)
|
||||
while(length(what) && (findtext(what," ",1,2)))
|
||||
what=copytext(what,2,0)
|
||||
while(length(what) && (findtext(what," ",length(what),0)))
|
||||
what=copytext(what,1,length(what))
|
||||
if(trim_quotes)
|
||||
while(length(what) && (findtext(what,quote,1,2)))
|
||||
what=copytext(what,2,0)
|
||||
while(length(what) && (findtext(what,quote,length(what),0)))
|
||||
what=copytext(what,1,length(what))
|
||||
return what
|
||||
return trimQuotesRegex.Replace(what, "")
|
||||
else
|
||||
return trimRegex.Replace(what, "")
|
||||
|
||||
|
||||
//find the position of the next delimiter,skipping whatever is comprised between opening_escape and closing_escape
|
||||
//returns 0 if reached the last delimiter
|
||||
@@ -317,14 +360,6 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
return to_return
|
||||
|
||||
//simulates the DM multiple turfs on one tile underlaying
|
||||
/dmm_suite/proc/add_underlying_turf(turf/placed,turf/underturf, list/turfs_underlays)
|
||||
if(underturf.density)
|
||||
placed.density = 1
|
||||
if(underturf.opacity)
|
||||
placed.opacity = 1
|
||||
placed.underlays += turfs_underlays
|
||||
|
||||
//atom creation method that preloads variables at creation
|
||||
/atom/New()
|
||||
if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
@@ -353,11 +388,14 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
/dmm_suite/preloader/proc/load(atom/what)
|
||||
for(var/attribute in attributes)
|
||||
what.vars[attribute] = attributes[attribute]
|
||||
var/value = attributes[attribute]
|
||||
if(islist(value))
|
||||
value = deepCopyList(value)
|
||||
what.vars[attribute] = value
|
||||
use_preloader = FALSE
|
||||
|
||||
/area/template_noop
|
||||
name = "Area Passthrough"
|
||||
|
||||
/turf/template_noop
|
||||
name = "Turf Passthrough"
|
||||
name = "Turf Passthrough"
|
||||
|
||||
@@ -32,10 +32,10 @@
|
||||
export_types = list(/obj/item/stack/sheet/animalhide/human)
|
||||
|
||||
// Goliath hide. Expensive.
|
||||
/datum/export/goliath_hide
|
||||
/datum/export/stack/skin/goliath_hide
|
||||
cost = 2500
|
||||
unit_name = "goliath hide"
|
||||
export_types = list(/obj/item/asteroid/goliath_hide)
|
||||
export_types = list(/obj/item/stack/sheet/animalhide/goliath_hide)
|
||||
|
||||
// Cat hide. Just in case Runtime is catsploding again.
|
||||
/datum/export/stack/skin/cat
|
||||
|
||||
@@ -133,6 +133,8 @@
|
||||
flash_protect = 1
|
||||
tint = 1
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/reagent
|
||||
name = "beer goggles"
|
||||
desc = "A pair of sunglasses outfitted with apparatus to scan reagents."
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
item_color="yellow"
|
||||
burn_state = FIRE_PROOF
|
||||
|
||||
/obj/item/clothing/gloves/color/yellow/fake
|
||||
desc = "These gloves will protect the wearer from electric shock. They don't feel like rubber..."
|
||||
siemens_coefficient = 1
|
||||
|
||||
/obj/item/clothing/gloves/color/fyellow //Cheap Chinese Crap
|
||||
desc = "These gloves are cheap knockoffs of the coveted ones - no way this can end badly."
|
||||
name = "budget insulated gloves"
|
||||
|
||||
@@ -35,4 +35,21 @@
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
heat_protection = HANDS
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
burn_state = FIRE_PROOF
|
||||
burn_state = FIRE_PROOF
|
||||
|
||||
/obj/item/clothing/gloves/bracer
|
||||
name = "bone bracers"
|
||||
desc = "For when you're expecting to get slapped on the wrist. Offers modest protection to your arms."
|
||||
icon_state = "bracers"
|
||||
item_state = "bracers"
|
||||
item_color = null //So they don't wash.
|
||||
transfer_prints = TRUE
|
||||
strip_delay = 40
|
||||
put_on_delay = 20
|
||||
body_parts_covered = ARMS
|
||||
cold_protection = ARMS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
burn_state = FIRE_PROOF
|
||||
armor = list(melee = 15, bullet = 35, laser = 35, energy = 20, bomb = 35, bio = 35, rad = 35) //Not like anything ever hits the arms anyways.
|
||||
|
||||
|
||||
@@ -26,11 +26,15 @@
|
||||
icon_state = "chef"
|
||||
item_state = "chef"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/chef
|
||||
|
||||
/obj/item/clothing/head/collectable/paper
|
||||
name = "collectable paper hat"
|
||||
desc = "What looks like an ordinary paper hat is actually a rare and valuable collector's edition paper hat. Keep away from water, fire, and Librarians."
|
||||
icon_state = "paper"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
|
||||
/obj/item/clothing/head/collectable/tophat
|
||||
name = "collectable top hat"
|
||||
desc = "A top hat worn by only the most prestigious hat collectors."
|
||||
@@ -43,16 +47,22 @@
|
||||
icon_state = "captain"
|
||||
item_state = "caphat"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/captain
|
||||
|
||||
/obj/item/clothing/head/collectable/police
|
||||
name = "collectable police officer's hat"
|
||||
desc = "A collectable police officer's Hat. This hat emphasizes that you are THE LAW."
|
||||
icon_state = "policehelm"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/warden
|
||||
|
||||
/obj/item/clothing/head/collectable/beret
|
||||
name = "collectable beret"
|
||||
desc = "A collectable red beret. It smells faintly of garlic."
|
||||
icon_state = "beret"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/beret
|
||||
|
||||
/obj/item/clothing/head/collectable/welding
|
||||
name = "collectable welding helmet"
|
||||
desc = "A collectable welding helmet. Now with 80% less lead! Not for actual welding. Any welding done while wearing this helmet is done so at the owner's own risk!"
|
||||
@@ -78,29 +88,39 @@
|
||||
icon_state = "pirate"
|
||||
item_state = "pirate"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/pirate
|
||||
|
||||
/obj/item/clothing/head/collectable/kitty
|
||||
name = "collectable kitty ears"
|
||||
desc = "The fur feels... a bit too realistic."
|
||||
icon_state = "kitty"
|
||||
item_state = "kitty"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/kitty
|
||||
|
||||
/obj/item/clothing/head/collectable/rabbitears
|
||||
name = "collectable rabbit ears"
|
||||
desc = "Not as lucky as the feet!"
|
||||
icon_state = "bunny"
|
||||
item_state = "bunny"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/rabbit
|
||||
|
||||
/obj/item/clothing/head/collectable/wizard
|
||||
name = "collectable wizard's hat"
|
||||
desc = "NOTE: Any magical powers gained from wearing this hat are purely coincidental."
|
||||
icon_state = "wizard"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/blue_wizard
|
||||
|
||||
/obj/item/clothing/head/collectable/hardhat
|
||||
name = "collectable hard hat"
|
||||
desc = "WARNING! Offers no real protection, or luminosity, but damn, is it fancy!"
|
||||
icon_state = "hardhat0_yellow"
|
||||
item_state = "hardhat0_yellow"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
|
||||
/obj/item/clothing/head/collectable/HoS
|
||||
name = "collectable HoS hat"
|
||||
desc = "Now you too can beat prisoners, set silly sentences, and arrest for no reason!"
|
||||
@@ -118,4 +138,4 @@
|
||||
desc = "That's not real blood. That's red paint." //Reference to the actual description
|
||||
icon_state = "swat"
|
||||
item_state = "swat"
|
||||
burn_state = FIRE_PROOF
|
||||
burn_state = FIRE_PROOF
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
actions_types = list(/datum/action/item_action/toggle_helmet_light)
|
||||
burn_state = FIRE_PROOF
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
|
||||
/obj/item/clothing/head/hardhat/attack_self(mob/user)
|
||||
if(!isturf(user.loc))
|
||||
user << "<span class='warning'>You cannot turn the light on while in this [user.loc]!</span>" //To prevent some lighting anomalities.
|
||||
@@ -50,11 +52,13 @@
|
||||
icon_state = "hardhat0_orange"
|
||||
item_state = "hardhat0_orange"
|
||||
item_color = "orange"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/hardhat/red
|
||||
icon_state = "hardhat0_red"
|
||||
item_state = "hardhat0_red"
|
||||
item_color = "red"
|
||||
dog_fashion = null
|
||||
name = "firefighter helmet"
|
||||
flags = STOPSPRESSUREDMAGE
|
||||
heat_protection = HEAD
|
||||
@@ -71,16 +75,19 @@
|
||||
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
|
||||
/obj/item/clothing/head/hardhat/dblue
|
||||
icon_state = "hardhat0_dblue"
|
||||
item_state = "hardhat0_dblue"
|
||||
item_color = "dblue"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/hardhat/atmos
|
||||
icon_state = "hardhat0_atmos"
|
||||
item_state = "hardhat0_atmos"
|
||||
item_color = "atmos"
|
||||
dog_fashion = null
|
||||
name = "atmospheric technician's firefighting helmet"
|
||||
desc = "A firefighter's helmet, able to keep the user cool in any situation."
|
||||
flags = STOPSPRESSUREDMAGE | THICKMATERIAL
|
||||
@@ -88,4 +95,4 @@
|
||||
heat_protection = HEAD
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
burn_state = FIRE_PROOF
|
||||
flags_cover = HEADCOVERSEYES
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/helmet
|
||||
|
||||
|
||||
/obj/item/clothing/head/helmet/New()
|
||||
..()
|
||||
@@ -31,6 +33,7 @@
|
||||
item_state = "helmetalt"
|
||||
armor = list(melee = 15, bullet = 40, laser = 10, energy = 10, bomb = 40, bio = 0, rad = 0)
|
||||
can_flashlight = 1
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/riot
|
||||
name = "riot helmet"
|
||||
@@ -48,6 +51,7 @@
|
||||
visor_flags_inv = HIDEMASK|HIDEFACE
|
||||
toggle_cooldown = 0
|
||||
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/attack_self(mob/user)
|
||||
if(can_toggle && !user.incapacitated())
|
||||
@@ -80,6 +84,7 @@
|
||||
can_toggle = 1
|
||||
toggle_cooldown = 20
|
||||
active_sound = 'sound/items/WEEOO1.ogg'
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/justice/escape
|
||||
name = "alarm helmet"
|
||||
@@ -100,6 +105,7 @@
|
||||
max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT
|
||||
flags = STOPSPRESSUREDMAGE
|
||||
strip_delay = 80
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/swat/nanotrasen
|
||||
name = "\improper SWAT helmet"
|
||||
@@ -119,6 +125,7 @@
|
||||
heat_protection = HEAD
|
||||
max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT
|
||||
strip_delay = 80
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/roman
|
||||
name = "roman helmet"
|
||||
@@ -129,6 +136,7 @@
|
||||
icon_state = "roman"
|
||||
item_state = "roman"
|
||||
strip_delay = 100
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/roman/legionaire
|
||||
name = "roman legionaire helmet"
|
||||
@@ -143,6 +151,7 @@
|
||||
item_state = "gladiator"
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEHAIR
|
||||
flags_cover = HEADCOVERSEYES
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/redtaghelm
|
||||
name = "red laser tag helmet"
|
||||
@@ -152,6 +161,7 @@
|
||||
item_state = "redtaghelm"
|
||||
armor = list(melee = 15, bullet = 10, laser = 20,energy = 10, bomb = 20, bio = 0, rad = 0)
|
||||
// Offer about the same protection as a hardhat.
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/bluetaghelm
|
||||
name = "blue laser tag helmet"
|
||||
@@ -161,6 +171,7 @@
|
||||
item_state = "bluetaghelm"
|
||||
armor = list(melee = 15, bullet = 10, laser = 20,energy = 10, bomb = 20, bio = 0, rad = 0)
|
||||
// Offer about the same protection as a hardhat.
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/knight
|
||||
name = "medieval helmet"
|
||||
@@ -172,6 +183,7 @@
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR
|
||||
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
|
||||
strip_delay = 80
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/knight/blue
|
||||
icon_state = "knight_blue"
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
strip_delay = 10
|
||||
put_on_delay = 10
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/chef
|
||||
|
||||
/obj/item/clothing/head/chefhat/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is donning [src]! It looks like they're trying to become a chef.</span>")
|
||||
user.say("Bork Bork Bork!")
|
||||
@@ -28,12 +30,16 @@
|
||||
armor = list(melee = 25, bullet = 15, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0)
|
||||
strip_delay = 60
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/captain
|
||||
|
||||
//Captain: This is no longer space-worthy
|
||||
/obj/item/clothing/head/caphat/parade
|
||||
name = "captain's parade cap"
|
||||
desc = "Worn only by Captains with an abundance of class."
|
||||
icon_state = "capcap"
|
||||
|
||||
dog_fashion = null
|
||||
|
||||
|
||||
//Head of Personnel
|
||||
/obj/item/clothing/head/hopcap
|
||||
@@ -42,6 +48,8 @@
|
||||
desc = "The symbol of true bureaucratic micromanagement."
|
||||
armor = list(melee = 25, bullet = 15, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0)
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/hop
|
||||
|
||||
//Chaplain
|
||||
/obj/item/clothing/head/nun_hood
|
||||
name = "nun hood"
|
||||
@@ -57,6 +65,8 @@
|
||||
armor = list(melee = 25, bullet = 5, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0)
|
||||
var/candy_cooldown = 0
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/detective
|
||||
|
||||
/obj/item/clothing/head/det_hat/AltClick()
|
||||
..()
|
||||
if(ismob(loc))
|
||||
@@ -76,6 +86,9 @@
|
||||
desc = "A beret, a mime's favorite headwear."
|
||||
icon_state = "beret"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/beret
|
||||
|
||||
|
||||
//Security
|
||||
|
||||
/obj/item/clothing/head/HoS
|
||||
@@ -97,12 +110,15 @@
|
||||
armor = list(melee = 30, bullet = 5, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0)
|
||||
strip_delay = 60
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/warden
|
||||
|
||||
/obj/item/clothing/head/beret/sec
|
||||
name = "security beret"
|
||||
desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficent protection."
|
||||
icon_state = "beret_badge"
|
||||
armor = list(melee = 30, bullet = 25, laser = 25,energy = 10, bomb = 25, bio = 0, rad = 0)
|
||||
strip_delay = 60
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/beret/sec/navyhos
|
||||
name = "head of security's beret"
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
desc = "It's an amish looking hat."
|
||||
icon_state = "tophat"
|
||||
item_state = "that"
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
|
||||
/obj/item/clothing/head/canada
|
||||
name = "striped red tophat"
|
||||
@@ -55,6 +56,8 @@
|
||||
desc = "It allows quick identification of trained medical personnel."
|
||||
icon_state = "nursehat"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/nurse
|
||||
|
||||
/obj/item/clothing/head/syndicatefake
|
||||
name = "black space-helmet replica"
|
||||
icon_state = "syndicate-helm-black-red"
|
||||
@@ -99,6 +102,9 @@
|
||||
desc = "Wearing these makes you look useless, and only good for your sex appeal."
|
||||
icon_state = "bunny"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/rabbit
|
||||
|
||||
|
||||
/obj/item/clothing/head/flatcap
|
||||
name = "flat cap"
|
||||
desc = "A working man's cap."
|
||||
@@ -111,6 +117,8 @@
|
||||
icon_state = "pirate"
|
||||
item_state = "pirate"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/pirate
|
||||
|
||||
/obj/item/clothing/head/hgpiratecap
|
||||
name = "pirate hat"
|
||||
desc = "Yarr."
|
||||
@@ -186,12 +194,15 @@
|
||||
desc = "You can practically taste the fiesta."
|
||||
flags_inv = HIDEHAIR
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/sombrero
|
||||
|
||||
/obj/item/clothing/head/sombrero/green
|
||||
name = "green sombrero"
|
||||
icon_state = "greensombrero"
|
||||
item_state = "greensombrero"
|
||||
desc = "As elegant as a dancing cactus."
|
||||
flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/sombrero/shamebrero
|
||||
name = "shamebrero"
|
||||
@@ -199,6 +210,7 @@
|
||||
item_state = "shamebrero"
|
||||
desc = "Once it's on, it never comes off."
|
||||
flags = NODROP
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/cone
|
||||
desc = "This cone is trying to warn you of something!"
|
||||
@@ -221,6 +233,7 @@
|
||||
item_state = "that"
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
dog_fashion = /datum/dog_fashion/head/santa
|
||||
|
||||
/obj/item/clothing/head/jester
|
||||
name = "jester hat"
|
||||
@@ -247,4 +260,4 @@
|
||||
name = "paper sack hat"
|
||||
desc = "A paper sack with crude holes cut out for eyes and a sketchy smile drawn on the front. Not creepy at all."
|
||||
icon_state = "papersack_smile"
|
||||
flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
|
||||
flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
|
||||
|
||||
@@ -93,6 +93,8 @@
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/ushanka
|
||||
|
||||
/obj/item/clothing/head/ushanka/attack_self(mob/user)
|
||||
if(earflaps)
|
||||
src.icon_state = "ushankaup"
|
||||
@@ -128,6 +130,8 @@
|
||||
icon_state = "kitty"
|
||||
color = "#999"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/kitty
|
||||
|
||||
/obj/item/clothing/head/kitty/equipped(mob/user, slot)
|
||||
if(user && slot == slot_head)
|
||||
update_icon(user)
|
||||
@@ -148,6 +152,7 @@
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
brightness_on = 1 //luminosity when on
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/reindeer
|
||||
|
||||
/obj/item/clothing/head/cardborg
|
||||
name = "cardborg helmet"
|
||||
@@ -157,6 +162,8 @@
|
||||
flags_cover = HEADCOVERSEYES
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/cardborg
|
||||
|
||||
/obj/item/clothing/head/cardborg/equipped(mob/living/user, slot)
|
||||
..()
|
||||
if(ishuman(user) && slot == slot_head)
|
||||
@@ -167,4 +174,4 @@
|
||||
|
||||
/obj/item/clothing/head/cardborg/dropped(mob/living/user)
|
||||
..()
|
||||
user.remove_alt_appearance("standard_borg_disguise")
|
||||
user.remove_alt_appearance("standard_borg_disguise")
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
icon_state = "cargosoft"
|
||||
item_state = "helmet"
|
||||
item_color = "cargo"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/cargo_tech
|
||||
|
||||
var/flipped = 0
|
||||
|
||||
/obj/item/clothing/head/soft/dropped()
|
||||
@@ -49,60 +52,70 @@
|
||||
desc = "It's a baseball hat in a tasteless red colour."
|
||||
icon_state = "redsoft"
|
||||
item_color = "red"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/blue
|
||||
name = "blue cap"
|
||||
desc = "It's a baseball hat in a tasteless blue colour."
|
||||
icon_state = "bluesoft"
|
||||
item_color = "blue"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/green
|
||||
name = "green cap"
|
||||
desc = "It's a baseball hat in a tasteless green colour."
|
||||
icon_state = "greensoft"
|
||||
item_color = "green"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/yellow
|
||||
name = "yellow cap"
|
||||
desc = "It's a baseball hat in a tasteless yellow colour."
|
||||
icon_state = "yellowsoft"
|
||||
item_color = "yellow"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/grey
|
||||
name = "grey cap"
|
||||
desc = "It's a baseball hat in a tasteful grey colour."
|
||||
icon_state = "greysoft"
|
||||
item_color = "grey"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/orange
|
||||
name = "orange cap"
|
||||
desc = "It's a baseball hat in a tasteless orange colour."
|
||||
icon_state = "orangesoft"
|
||||
item_color = "orange"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/mime
|
||||
name = "white cap"
|
||||
desc = "It's a baseball hat in a tasteless white colour."
|
||||
icon_state = "mimesoft"
|
||||
item_color = "mime"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/purple
|
||||
name = "purple cap"
|
||||
desc = "It's a baseball hat in a tasteless purple colour."
|
||||
icon_state = "purplesoft"
|
||||
item_color = "purple"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/black
|
||||
name = "black cap"
|
||||
desc = "It's a baseball hat in a tasteless black colour."
|
||||
icon_state = "blacksoft"
|
||||
item_color = "black"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/rainbow
|
||||
name = "rainbow cap"
|
||||
desc = "It's a baseball hat in a bright rainbow of colors."
|
||||
icon_state = "rainbowsoft"
|
||||
item_color = "rainbow"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/sec
|
||||
name = "security cap"
|
||||
@@ -111,9 +124,11 @@
|
||||
item_color = "sec"
|
||||
armor = list(melee = 30, bullet = 25, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0)
|
||||
strip_delay = 60
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/soft/emt
|
||||
name = "EMT cap"
|
||||
desc = "It's a baseball hat with a dark turquoise color and a reflective cross on the top."
|
||||
icon_state = "emtsoft"
|
||||
item_color = "emt"
|
||||
dog_fashion = null
|
||||
|
||||
@@ -61,11 +61,17 @@
|
||||
item_state = "clown_hat"
|
||||
flags_cover = MASKCOVERSEYES
|
||||
burn_state = FLAMMABLE
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/clown
|
||||
|
||||
/obj/item/clothing/mask/gas/clown_hat/attack_self(mob/user)
|
||||
AltClick(user)
|
||||
|
||||
/obj/item/clothing/mask/gas/clown_hat/AltClick(mob/living/user)
|
||||
if(!istype(user) || user.incapacitated())
|
||||
return
|
||||
|
||||
|
||||
var/list/options = list()
|
||||
options["True Form"] = "clown"
|
||||
options["The Feminist"] = "sexyclown"
|
||||
@@ -155,4 +161,4 @@
|
||||
/obj/item/clothing/mask/gas/carp
|
||||
name = "carp mask"
|
||||
desc = "Gnash gnash."
|
||||
icon_state = "carp_mask"
|
||||
icon_state = "carp_mask"
|
||||
|
||||
@@ -482,6 +482,10 @@
|
||||
var/shield_state = "shield-old"
|
||||
var/shield_on = "shield-old"
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/shielded/New()
|
||||
jetpack = new /obj/item/weapon/tank/jetpack/suit(src)
|
||||
..()
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/shielded/hit_reaction(mob/living/carbon/human/owner, attack_text)
|
||||
if(current_charges > 0)
|
||||
var/datum/effect_system/spark_spread/s = new
|
||||
|
||||
@@ -60,6 +60,7 @@ Contains:
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
|
||||
unacidable = 1
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/deathsquad
|
||||
dog_fashion = /datum/dog_fashion/back/deathsquad
|
||||
|
||||
//NEW SWAT suit
|
||||
/obj/item/clothing/suit/space/swat
|
||||
@@ -121,6 +122,8 @@ Contains:
|
||||
flags = STOPSPRESSUREDMAGE
|
||||
flags_cover = HEADCOVERSEYES
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/santa
|
||||
|
||||
/obj/item/clothing/suit/space/santa
|
||||
name = "Santa's suit"
|
||||
desc = "Festive!"
|
||||
@@ -308,4 +311,17 @@ Contains:
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor
|
||||
name = "inquisitor's helmet"
|
||||
icon_state = "hardsuit0-inq"
|
||||
item_state = "hardsuit0-inq"
|
||||
item_state = "hardsuit0-inq"
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker
|
||||
name = "champion's hardsuit"
|
||||
desc = "Voices echo from the hardsuit, driving the user insane."
|
||||
icon_state = "hardsuit-beserker"
|
||||
item_state = "hardsuit-beserker"
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker
|
||||
name = "champion's helmet"
|
||||
desc = "Peering into the eyes of the helmet is enough to seal damnation."
|
||||
icon_state = "hardsuit0-beserker"
|
||||
item_state = "hardsuit0-beserker"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
item_state = "armor"
|
||||
blood_overlay_type = "armor"
|
||||
armor = list(melee = 25, bullet = 15, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0)
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
|
||||
/obj/item/clothing/suit/armor/hos
|
||||
name = "armored greatcoat"
|
||||
@@ -47,6 +48,7 @@
|
||||
heat_protection = CHEST|GROIN|ARMS|HANDS
|
||||
strip_delay = 70
|
||||
burn_state = FLAMMABLE
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/warden/alt
|
||||
name = "warden's armored jacket"
|
||||
@@ -61,6 +63,7 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS|LEGS
|
||||
cold_protection = CHEST|GROIN|LEGS|ARMS
|
||||
heat_protection = CHEST|GROIN|LEGS|ARMS
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/capcarapace
|
||||
name = "captain's carapace"
|
||||
@@ -69,6 +72,7 @@
|
||||
item_state = "armor"
|
||||
body_parts_covered = CHEST|GROIN
|
||||
armor = list(melee = 50, bullet = 40, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/capcarapace/alt
|
||||
name = "captain's parade jacket"
|
||||
@@ -129,6 +133,7 @@
|
||||
icon_state = "detective-armor"
|
||||
allowed = list(/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/device/flashlight,/obj/item/weapon/gun/energy,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/detective_scanner,/obj/item/device/taperecorder,/obj/item/weapon/melee/classic_baton/telescopic)
|
||||
burn_state = FLAMMABLE
|
||||
dog_fashion = null
|
||||
|
||||
|
||||
//Reactive armor
|
||||
|
||||
@@ -162,6 +162,7 @@
|
||||
item_state = "cardborg"
|
||||
body_parts_covered = CHEST|GROIN
|
||||
flags_inv = HIDEJUMPSUIT
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
|
||||
/obj/item/clothing/suit/cardborg/equipped(mob/living/user, slot)
|
||||
..()
|
||||
@@ -257,6 +258,7 @@
|
||||
allowed = list(,)
|
||||
hooded = 1
|
||||
hoodtype = /obj/item/clothing/head/ian_hood
|
||||
dog_fashion = /datum/dog_fashion/back
|
||||
|
||||
/obj/item/clothing/head/ian_hood
|
||||
name = "corgi hood"
|
||||
@@ -487,4 +489,4 @@
|
||||
hoodtype = /obj/item/clothing/head/winterhood/miner
|
||||
|
||||
/obj/item/clothing/head/winterhood/miner
|
||||
icon_state = "winterhood_miner"
|
||||
icon_state = "winterhood_miner"
|
||||
|
||||
@@ -9,21 +9,25 @@
|
||||
put_on_delay = 50
|
||||
unacidable = 1
|
||||
burn_state = FIRE_PROOF
|
||||
dog_fashion = /datum/dog_fashion/head/blue_wizard
|
||||
|
||||
/obj/item/clothing/head/wizard/red
|
||||
name = "red wizard hat"
|
||||
desc = "Strange-looking red hat-wear that most certainly belongs to a real magic user."
|
||||
icon_state = "redwizard"
|
||||
dog_fashion = /datum/dog_fashion/head/red_wizard
|
||||
|
||||
/obj/item/clothing/head/wizard/yellow
|
||||
name = "yellow wizard hat"
|
||||
desc = "Strange-looking yellow hat-wear that most certainly belongs to a powerful magic user."
|
||||
icon_state = "yellowwizard"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/wizard/black
|
||||
name = "black wizard hat"
|
||||
desc = "Strange-looking black hat-wear that most certainly belongs to a real skeleton. Spooky."
|
||||
icon_state = "blackwizard"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/wizard/fake
|
||||
name = "wizard hat"
|
||||
@@ -32,23 +36,27 @@
|
||||
gas_transfer_coefficient = 1
|
||||
permeability_coefficient = 1
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
dog_fashion = /datum/dog_fashion/head/blue_wizard
|
||||
|
||||
/obj/item/clothing/head/wizard/marisa
|
||||
name = "witch hat"
|
||||
desc = "Strange-looking hat-wear. Makes you want to cast fireballs."
|
||||
icon_state = "marisa"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/wizard/magus
|
||||
name = "\improper Magus helm"
|
||||
desc = "A mysterious helmet that hums with an unearthly power."
|
||||
icon_state = "magus"
|
||||
item_state = "magus"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/wizard/santa
|
||||
name = "Santa's hat"
|
||||
desc = "Ho ho ho. Merrry X-mas!"
|
||||
icon_state = "santahat"
|
||||
flags_inv = HIDEHAIR|HIDEFACIALHAIR
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/suit/wizrobe
|
||||
name = "wizard robe"
|
||||
@@ -139,4 +147,4 @@
|
||||
permeability_coefficient = 1
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
unacidable = 0
|
||||
burn_state = FLAMMABLE
|
||||
burn_state = FLAMMABLE
|
||||
|
||||
@@ -210,6 +210,7 @@
|
||||
/obj/item/clothing/tie/scarf
|
||||
name = "scarf"
|
||||
desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks."
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
|
||||
/obj/item/clothing/tie/scarf/red
|
||||
name = "red scarf"
|
||||
@@ -319,4 +320,4 @@
|
||||
item_state = ""
|
||||
item_color = "talisman"
|
||||
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS|HEAD
|
||||
armor = list(melee = 5, bullet = 5, laser = 5, energy = 5, bomb = 50, bio = 65, rad = 5) //Faith is the best armor. //This won't actually work because of accessories kill me with a fucking knife jesus christ I hate code
|
||||
armor = list(melee = 5, bullet = 5, laser = 5, energy = 5, bomb = 50, bio = 65, rad = 5) //Faith is the best armor. //This won't actually work because of accessories kill me with a fucking knife jesus christ I hate code
|
||||
|
||||
@@ -363,6 +363,14 @@
|
||||
name = "Bone Talisman"
|
||||
result = /obj/item/clothing/tie/talisman
|
||||
time = 20
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/table_recipe/bracers
|
||||
name = "Bone Bracers"
|
||||
result = /obj/item/clothing/gloves/bracer
|
||||
time = 20
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_MISC
|
||||
@@ -14,10 +14,8 @@
|
||||
"Ionospheri:%£ MCayj^j<.3-BZZZZZZT", \
|
||||
"#4nd%;f4y6,>£%-BZZZZZZZT")
|
||||
|
||||
for(var/mob/living/silicon/ai/A in player_list) //AIs are always aware of communication blackouts.
|
||||
A << "<br>"
|
||||
A << "<span class='warning'><b>[alert]</b></span>"
|
||||
A << "<br>"
|
||||
for(var/mob/living/silicon/ai/A in ai_list) //AIs are always aware of communication blackouts.
|
||||
A << "<br><span class='warning'><b>[alert]</b></span><br>"
|
||||
|
||||
if(prob(30)) //most of the time, we don't want an announcement, so as to allow AIs to fake blackouts.
|
||||
priority_announce(alert)
|
||||
@@ -25,4 +23,4 @@
|
||||
|
||||
/datum/round_event/communications_blackout/start()
|
||||
for(var/obj/machinery/telecomms/T in telecomms_list)
|
||||
T.emp_act(1)
|
||||
T.emp_act(1)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/datum/round_event_control/processor_overload
|
||||
name = "Processor Overload"
|
||||
typepath = /datum/round_event/processor_overload
|
||||
weight = 15
|
||||
|
||||
/datum/round_event/processor_overload
|
||||
announceWhen = 1
|
||||
|
||||
/datum/round_event/processor_overload/announce()
|
||||
var/alert = pick( "Exospheric bubble inbound. Processor overload is likely. Please contact you*%xp25)`6cq-BZZT", \
|
||||
"Exospheric bubble inbound. Processor overload is likel*1eta;c5;'1v¬-BZZZT", \
|
||||
"Exospheric bubble inbound. Processor ov#MCi46:5.;@63-BZZZZT", \
|
||||
"Exospheric bubble inbo'Fz\\k55_@-BZZZZZT", \
|
||||
"Exospheri:%£ QCbyj^j</.3-BZZZZZZT", \
|
||||
"!!hy%;f3l7e,<$^-BZZZZZZZT")
|
||||
|
||||
for(var/mob/living/silicon/ai/A in ai_list)
|
||||
//AIs are always aware of processor overload
|
||||
A << "<br><span class='warning'><b>[alert]</b></span><br>"
|
||||
|
||||
// Announce most of the time, but leave a little gap so people don't know
|
||||
// whether it's, say, a tesla zapping tcomms, or some selective
|
||||
// modification of the tcomms bus
|
||||
if(prob(80))
|
||||
priority_announce(alert)
|
||||
|
||||
|
||||
/datum/round_event/processor_overload/start()
|
||||
for(var/obj/machinery/telecomms/T in telecomms_list)
|
||||
if(istype(T, /obj/machinery/telecomms/processor))
|
||||
var/obj/machinery/telecomms/processor/P = T
|
||||
if(prob(10))
|
||||
// Damage the surrounding area to indicate that it popped
|
||||
explosion(get_turf(P), 0, 0, 2)
|
||||
// Only a level 1 explosion actually damages the machine
|
||||
// at all
|
||||
P.ex_act(1)
|
||||
else
|
||||
P.emp_act(1)
|
||||
@@ -258,7 +258,7 @@
|
||||
var/list/affecting_lights //not initialised until used (even empty lists reserve a fair bit of memory)
|
||||
|
||||
/turf/ChangeTurf(path)
|
||||
if(!path || path == type) //Sucks this is here but it would cause problems otherwise.
|
||||
if(!path || (!use_preloader && path == type)) //Sucks this is here but it would cause problems otherwise.
|
||||
return ..()
|
||||
|
||||
for(var/obj/effect/decal/cleanable/decal in src.contents)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
if(11)
|
||||
new /obj/vehicle/lavaboat/dragon(src)
|
||||
if(12)
|
||||
new /obj/item/upgradescroll(src)
|
||||
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker(src)
|
||||
if(13)
|
||||
new /obj/item/weapon/sord(src)
|
||||
if(14)
|
||||
@@ -68,6 +68,7 @@
|
||||
new /obj/item/weapon/spellbook/oneuse/smoke(src)
|
||||
|
||||
|
||||
|
||||
//Spooky special loot
|
||||
|
||||
/obj/item/device/wisp_lantern
|
||||
@@ -373,7 +374,7 @@
|
||||
/datum/table_recipe/boat
|
||||
name = "goliath hide boat"
|
||||
result = /obj/vehicle/lavaboat
|
||||
reqs = list(/obj/item/asteroid/goliath_hide = 3)
|
||||
reqs = list(/obj/item/stack/sheet/animalhide/goliath_hide = 3)
|
||||
time = 50
|
||||
category = CAT_MISC
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
if(C.l_hand || C.r_hand)
|
||||
//TODO make it toggleable to either forcedrop the items, or deny
|
||||
//entry when holding them
|
||||
// literally only an option for carbons though
|
||||
C << "<span class='warning'>You may not hold items while blood crawling!</span>"
|
||||
return 0
|
||||
var/obj/item/weapon/bloodcrawl/B1 = new(C)
|
||||
@@ -37,64 +40,121 @@
|
||||
C.put_in_hands(B1)
|
||||
C.put_in_hands(B2)
|
||||
C.regenerate_icons()
|
||||
var/mob/living/kidnapped = null
|
||||
var/turf/mobloc = get_turf(src.loc)
|
||||
src.notransform = TRUE
|
||||
spawn(0)
|
||||
src.visible_message("<span class='warning'>[src] sinks into the pool of blood!</span>")
|
||||
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
|
||||
var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,mobloc)
|
||||
src.ExtinguishMob()
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob(src,force=1)
|
||||
if(buckled_mobs.len)
|
||||
unbuckle_all_mobs(force=1)
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
if(src.pulling && src.bloodcrawl == BLOODCRAWL_EAT)
|
||||
if(istype(src.pulling, /mob/living))
|
||||
var/mob/living/victim = src.pulling
|
||||
if(victim.stat == CONSCIOUS)
|
||||
src.visible_message("<span class='warning'>[victim] kicks free of the blood pool just before entering it!</span>")
|
||||
else if(victim.reagents && victim.reagents.has_reagent("demonsblood"))
|
||||
visible_message("<span class='warning'>Something prevents [victim] from entering the pool!</span>", "<span class='warning'>A strange force is blocking [victim] from entering!</span>")
|
||||
else
|
||||
victim.loc = holder
|
||||
victim.emote("scream")
|
||||
src.visible_message("<span class='warning'><b>[src] drags [victim] into the pool of blood!</b></span>")
|
||||
kidnapped = victim
|
||||
src.loc = holder
|
||||
src.holder = holder
|
||||
if(kidnapped)
|
||||
src << "<span class='danger'>You begin to feast on [kidnapped]. You can not move while you are doing this.</span>"
|
||||
for(var/i = 3; i > 0; i--)
|
||||
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
|
||||
sleep(30)
|
||||
if(kidnapped)
|
||||
if(kidnapped.reagents && kidnapped.reagents.has_reagent("devilskiss"))
|
||||
src << "<span class='warning'><b>AAH! THEIR FLESH! IT BURNS!</b></span>"
|
||||
adjustBruteLoss(25) //I can't use adjustHealth() here because bloodcrawl affects /mob/living and adjustHealth() only affects simple mobs
|
||||
kidnapped.loc = get_turf(B)
|
||||
kidnapped.visible_message("<span class='warning'>[B] violently expels [kidnapped]!</span>")
|
||||
else
|
||||
src << "<span class='danger'>You devour [kidnapped]. Your health is fully restored.</span>"
|
||||
src.adjustBruteLoss(-1000)
|
||||
src.adjustFireLoss(-1000)
|
||||
src.adjustOxyLoss(-1000)
|
||||
src.adjustToxLoss(-1000)
|
||||
kidnapped.ghostize()
|
||||
qdel(kidnapped)
|
||||
else
|
||||
src << "<span class='danger'>You happily devour... nothing? Your meal vanished at some point!</span>"
|
||||
src.notransform = 0
|
||||
bloodpool_sink(B)
|
||||
src.notransform = FALSE
|
||||
return 1
|
||||
|
||||
/mob/living/proc/bloodpool_sink(obj/effect/decal/cleanable/B)
|
||||
var/turf/mobloc = get_turf(src.loc)
|
||||
|
||||
src.visible_message("<span class='warning'>[src] sinks into the pool of blood!</span>")
|
||||
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
|
||||
// Extinguish, unbuckle, stop being pulled, set our location into the
|
||||
// dummy object
|
||||
var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,mobloc)
|
||||
src.ExtinguishMob()
|
||||
|
||||
// Keep a reference to whatever we're pulling, because forceMove()
|
||||
// makes us stop pulling
|
||||
var/pullee = src.pulling
|
||||
|
||||
src.holder = holder
|
||||
src.forceMove(holder)
|
||||
|
||||
// if we're not pulling anyone, or we can't eat anyone
|
||||
if(!pullee || src.bloodcrawl != BLOODCRAWL_EAT)
|
||||
return
|
||||
|
||||
// if the thing we're pulling isn't alive
|
||||
if (!(istype(pullee, /mob/living)))
|
||||
return
|
||||
|
||||
var/mob/living/victim = pullee
|
||||
var/kidnapped = FALSE
|
||||
|
||||
if(victim.stat == CONSCIOUS)
|
||||
src.visible_message("<span class='warning'>[victim] kicks free of the blood pool just before entering it!</span>", null, "<span class='notice'>You hear splashing and struggling.</span>")
|
||||
else if(victim.reagents && victim.reagents.has_reagent("demonsblood"))
|
||||
visible_message("<span class='warning'>Something prevents [victim] from entering the pool!</span>", "<span class='warning'>A strange force is blocking [victim] from entering!</span>", "<span class='notice'>You hear a splash and a thud.</span>")
|
||||
else
|
||||
victim.forceMove(src)
|
||||
victim.emote("scream")
|
||||
src.visible_message("<span class='warning'><b>[src] drags [victim] into the pool of blood!</b></span>", null, "<span class='notice'>You hear a splash.</span>")
|
||||
kidnapped = TRUE
|
||||
|
||||
if(kidnapped)
|
||||
var/success = bloodcrawl_consume(victim)
|
||||
if(!success)
|
||||
src << "<span class='danger'>You happily devour... nothing? Your meal vanished at some point!</span>"
|
||||
return 1
|
||||
|
||||
/mob/living/proc/bloodcrawl_consume(mob/living/victim)
|
||||
src << "<span class='danger'>You begin to feast on [victim]. You can not move while you are doing this.</span>"
|
||||
|
||||
var/sound
|
||||
if(istype(src, /mob/living/simple_animal/slaughter))
|
||||
var/mob/living/simple_animal/slaughter/SD = src
|
||||
sound = SD.feast_sound
|
||||
else
|
||||
sound = 'sound/magic/Demon_consume.ogg'
|
||||
|
||||
for(var/i in 1 to 3)
|
||||
playsound(get_turf(src),sound, 100, 1)
|
||||
sleep(30)
|
||||
|
||||
if(!victim)
|
||||
return FALSE
|
||||
|
||||
if(victim.reagents && victim.reagents.has_reagent("devilskiss"))
|
||||
src << "<span class='warning'><b>AAH! THEIR FLESH! IT BURNS!</b></span>"
|
||||
adjustBruteLoss(25) //I can't use adjustHealth() here because bloodcrawl affects /mob/living and adjustHealth() only affects simple mobs
|
||||
var/found_bloodpool = FALSE
|
||||
for(var/obj/effect/decal/cleanable/target in range(1,get_turf(victim)))
|
||||
if(target.can_bloodcrawl_in())
|
||||
victim.forceMove(get_turf(target))
|
||||
victim.visible_message("<span class='warning'>[target] violently expels [victim]!</span>")
|
||||
victim.exit_blood_effect(target)
|
||||
found_bloodpool = TRUE
|
||||
|
||||
if(!found_bloodpool)
|
||||
// Fuck it, just eject them, thanks to some split second cleaning
|
||||
victim.forceMove(get_turf(victim))
|
||||
victim.visible_message("<span class='warning'>[victim] appears from nowhere, covered in blood!</span>")
|
||||
victim.exit_blood_effect()
|
||||
return TRUE
|
||||
|
||||
src << "<span class='danger'>You devour [victim]. Your health is fully restored.</span>"
|
||||
src.revive(full_heal = 1)
|
||||
|
||||
// No defib possible after laughter
|
||||
victim.adjustBruteLoss(1000)
|
||||
victim.death()
|
||||
bloodcrawl_swallow(victim)
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/bloodcrawl_swallow(var/mob/living/victim)
|
||||
qdel(victim)
|
||||
|
||||
/obj/item/weapon/bloodcrawl
|
||||
name = "blood crawl"
|
||||
desc = "You are unable to hold anything while in this form."
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
flags = NODROP|ABSTRACT
|
||||
|
||||
/mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B)
|
||||
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
|
||||
var/oldcolor = src.color
|
||||
//Makes the mob have the color of the blood pool it came out of
|
||||
if(istype(B, /obj/effect/decal/cleanable/xenoblood))
|
||||
src.color = rgb(43, 186, 0)
|
||||
else
|
||||
src.color = rgb(149, 10, 10)
|
||||
// but only for a few seconds
|
||||
spawn(30)
|
||||
src.color = oldcolor
|
||||
|
||||
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
|
||||
if(src.notransform)
|
||||
src << "<span class='warning'>Finish eating first!</span>"
|
||||
@@ -107,20 +167,13 @@
|
||||
src.loc = B.loc
|
||||
src.client.eye = src
|
||||
src.visible_message("<span class='warning'><B>[src] rises out of the pool of blood!</B>")
|
||||
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
|
||||
exit_blood_effect(B)
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
for(var/obj/item/weapon/bloodcrawl/BC in C)
|
||||
BC.flags = null
|
||||
C.unEquip(BC)
|
||||
qdel(BC)
|
||||
var/oldcolor = src.color
|
||||
if(istype(B, /obj/effect/decal/cleanable/xenoblood)) //Makes the mob have the color of the blood pool it came out of for a few seconds
|
||||
src.color = rgb(43, 186, 0)
|
||||
else
|
||||
src.color = rgb(149, 10, 10)
|
||||
qdel(src.holder)
|
||||
src.holder = null
|
||||
spawn(30)
|
||||
src.color = oldcolor
|
||||
return 1
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
if(ismob(AM))
|
||||
if(isliving(AM))
|
||||
var/mob/living/A = AM
|
||||
if(A.mob_size > MOB_SIZE_TINY)
|
||||
if(A.mob_size > MOB_SIZE_SMALL)
|
||||
if(prob(squish_chance))
|
||||
A.visible_message("<span class='notice'>\The [A] squashed \the [name].</span>", "<span class='notice'>You squashed \the [name].</span>")
|
||||
death()
|
||||
@@ -53,4 +53,4 @@
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "xfloor1"
|
||||
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
|
||||
layer = 2
|
||||
layer = 2
|
||||
|
||||
@@ -159,28 +159,22 @@
|
||||
if(!item_to_add)
|
||||
usr.visible_message("[usr] pets [src].","<span class='notice'>You rest your hand on [src]'s back for a moment.</span>")
|
||||
return
|
||||
|
||||
if(!usr.drop_item())
|
||||
usr << "<span class='warning'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s back!</span>"
|
||||
return
|
||||
|
||||
if(istype(item_to_add,/obj/item/weapon/c4)) // last thing he ever wears, I guess
|
||||
item_to_add.afterattack(src,usr,1)
|
||||
return
|
||||
|
||||
//The objects that corgis can wear on their backs.
|
||||
var/list/allowed_types = list(
|
||||
/obj/item/clothing/suit/armor/vest,
|
||||
/obj/item/clothing/suit/space/hardsuit/deathsquad,
|
||||
/obj/item/device/radio,
|
||||
/obj/item/device/radio/off,
|
||||
/obj/item/clothing/suit/cardborg,
|
||||
/obj/item/weapon/tank/internals/oxygen,
|
||||
/obj/item/weapon/tank/internals/air,
|
||||
/obj/item/weapon/extinguisher,
|
||||
/obj/item/clothing/suit/hooded/ian_costume,
|
||||
)
|
||||
var/allowed = FALSE
|
||||
if(ispath(item_to_add.dog_fashion,/datum/dog_fashion/back))
|
||||
allowed = TRUE
|
||||
|
||||
if( ! ( item_to_add.type in allowed_types ) )
|
||||
if(!allowed)
|
||||
usr << "<span class='warning'>You set [item_to_add] on [src]'s back, but it falls off!</span>"
|
||||
if(!usr.drop_item())
|
||||
usr << "<span class='warning'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s back!</span>"
|
||||
return
|
||||
item_to_add.loc = loc
|
||||
if(prob(25))
|
||||
step_rand(item_to_add)
|
||||
@@ -202,6 +196,7 @@
|
||||
//Corgis are supposed to be simpler, so only a select few objects can actually be put
|
||||
//to be compatible with them. The objects are below.
|
||||
//Many hats added, Some will probably be removed, just want to see which ones are popular.
|
||||
// > some will probably be removed
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/user)
|
||||
|
||||
@@ -217,31 +212,17 @@
|
||||
user.visible_message("[user] pets [src].","<span class='notice'>You rest your hand on [src]'s head for a moment.</span>")
|
||||
return
|
||||
|
||||
var/valid = 0
|
||||
if(user && !user.drop_item())
|
||||
user << "<span class='warning'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s head!</span>"
|
||||
return 0
|
||||
|
||||
var/valid = FALSE
|
||||
if(ispath(item_to_add.dog_fashion, /datum/dog_fashion/head))
|
||||
valid = TRUE
|
||||
|
||||
//Various hats and items (worn on his head) change Ian's behaviour. His attributes are reset when a hat is removed.
|
||||
if(istype(item_to_add, /obj/item/clothing/tie/scarf))
|
||||
valid = 1
|
||||
else
|
||||
switch(item_to_add.type)
|
||||
if( /obj/item/clothing/glasses/sunglasses, /obj/item/clothing/head/that, /obj/item/clothing/head/collectable/paper,
|
||||
/obj/item/clothing/head/hardhat, /obj/item/clothing/head/collectable/hardhat, /obj/item/clothing/head/hardhat/white,
|
||||
/obj/item/weapon/paper, /obj/item/clothing/head/helmet, /obj/item/clothing/head/chefhat, /obj/item/clothing/head/collectable/chef,
|
||||
/obj/item/clothing/head/caphat, /obj/item/clothing/head/collectable/captain, /obj/item/clothing/head/kitty,
|
||||
/obj/item/clothing/head/collectable/kitty, /obj/item/clothing/head/rabbitears, /obj/item/clothing/head/collectable/rabbitears,
|
||||
/obj/item/clothing/head/beret, /obj/item/clothing/head/collectable/beret, /obj/item/clothing/head/det_hat,
|
||||
/obj/item/clothing/head/nursehat, /obj/item/clothing/head/pirate, /obj/item/clothing/head/collectable/pirate,
|
||||
/obj/item/clothing/head/ushanka, /obj/item/clothing/head/warden, /obj/item/clothing/head/collectable/police,
|
||||
/obj/item/clothing/head/wizard/fake, /obj/item/clothing/head/wizard, /obj/item/clothing/head/collectable/wizard,
|
||||
/obj/item/clothing/head/cardborg, /obj/item/weapon/bedsheet, /obj/item/clothing/head/helmet/space/santahat,
|
||||
/obj/item/clothing/head/soft, /obj/item/clothing/head/hardhat/reindeer, /obj/item/clothing/head/sombrero,
|
||||
/obj/item/clothing/head/hopcap, /obj/item/clothing/mask/gas/clown_hat, /obj/item/clothing/head/wizard/red)
|
||||
valid = 1
|
||||
|
||||
if(valid)
|
||||
if(user && !user.drop_item())
|
||||
user << "<span class='warning'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s head!</span>"
|
||||
return 0
|
||||
if(health <= 0)
|
||||
user << "<span class ='notice'>There is merely a dull, lifeless look in [real_name]'s eyes as you put the [item_to_add] on \him.</span>"
|
||||
else if(user)
|
||||
@@ -253,9 +234,6 @@
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
else
|
||||
if(user && !user.drop_item())
|
||||
user << "<span class='warning'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s head!</span>"
|
||||
return 0
|
||||
user << "<span class='warning'>You set [item_to_add] on [src]'s head, but it falls off!</span>"
|
||||
item_to_add.loc = loc
|
||||
if(prob(25))
|
||||
@@ -267,143 +245,24 @@
|
||||
return valid
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/update_corgi_fluff()
|
||||
var/special_hat = 0
|
||||
if(inventory_head)
|
||||
special_hat = 1
|
||||
switch(inventory_head.type)
|
||||
if(/obj/item/clothing/head/helmet)
|
||||
name = "Sergeant [real_name]"
|
||||
desc = "The ever-loyal, the ever-vigilant."
|
||||
// First, change back to defaults
|
||||
name = real_name
|
||||
desc = initial(desc)
|
||||
// BYOND/DM doesn't support the use of initial on lists.
|
||||
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
|
||||
speak_emote = list("barks", "woofs")
|
||||
emote_hear = list("barks!", "woofs!", "yaps.","pants.")
|
||||
emote_see = list("shakes its head.", "chases its tail.","shivers.")
|
||||
desc = initial(desc)
|
||||
SetLuminosity(0)
|
||||
|
||||
if(/obj/item/clothing/head/chefhat, /obj/item/clothing/head/collectable/chef)
|
||||
name = "Sous chef [real_name]"
|
||||
desc = "Your food will be taste-tested. All of it."
|
||||
if(inventory_head && inventory_head.dog_fashion)
|
||||
var/datum/dog_fashion/DF = new inventory_head.dog_fashion(src)
|
||||
DF.apply(src)
|
||||
|
||||
|
||||
if(/obj/item/clothing/head/caphat, /obj/item/clothing/head/collectable/captain)
|
||||
name = "Captain [real_name]"
|
||||
desc = "Probably better than the last captain."
|
||||
|
||||
if(/obj/item/clothing/head/kitty, /obj/item/clothing/head/collectable/kitty)
|
||||
name = "Runtime"
|
||||
emote_see = list("coughs up a furball", "stretches")
|
||||
emote_hear = list("purrs")
|
||||
speak = list("Purrr", "Meow!", "MAOOOOOW!", "HISSSSS", "MEEEEEEW")
|
||||
desc = "It's a cute little kitty-cat! ... wait ... what the hell?"
|
||||
|
||||
if(/obj/item/clothing/head/rabbitears, /obj/item/clothing/head/collectable/rabbitears)
|
||||
name = "Hoppy"
|
||||
emote_see = list("twitches its nose", "hops around a bit")
|
||||
desc = "This is Hoppy. It's a corgi-...urmm... bunny rabbit"
|
||||
|
||||
if(/obj/item/clothing/head/beret, /obj/item/clothing/head/collectable/beret)
|
||||
name = "Yann"
|
||||
desc = "Mon dieu! C'est un chien!"
|
||||
speak = list("le woof!", "le bark!", "JAPPE!!")
|
||||
emote_see = list("cowers in fear.", "surrenders.", "plays dead.","looks as though there is a wall in front of him.")
|
||||
|
||||
if(/obj/item/clothing/head/det_hat)
|
||||
name = "Detective [real_name]"
|
||||
desc = "[name] sees through your lies..."
|
||||
emote_see = list("investigates the area.","sniffs around for clues.","searches for scooby snacks.")
|
||||
|
||||
if(/obj/item/clothing/head/nursehat)
|
||||
name = "Nurse [real_name]"
|
||||
desc = "[name] needs 100cc of beef jerky... STAT!"
|
||||
|
||||
if(/obj/item/clothing/head/pirate, /obj/item/clothing/head/collectable/pirate)
|
||||
name = "[pick("Ol'","Scurvy","Black","Rum","Gammy","Bloody","Gangrene","Death","Long-John")] [pick("kibble","leg","beard","tooth","poop-deck","Threepwood","Le Chuck","corsair","Silver","Crusoe")]"
|
||||
desc = "Yaarghh!! Thar' be a scurvy dog!"
|
||||
emote_see = list("hunts for treasure.","stares coldly...","gnashes his tiny corgi teeth!")
|
||||
emote_hear = list("growls ferociously!", "snarls.")
|
||||
speak = list("Arrrrgh!!","Grrrrrr!")
|
||||
|
||||
if(/obj/item/clothing/head/ushanka)
|
||||
name = "[pick("Comrade","Commissar","Glorious Leader")] [real_name]"
|
||||
desc = "A follower of Karl Barx."
|
||||
emote_see = list("contemplates the failings of the capitalist economic model.", "ponders the pros and cons of vanguardism.")
|
||||
|
||||
if(/obj/item/clothing/head/warden, /obj/item/clothing/head/collectable/police)
|
||||
name = "Officer [real_name]"
|
||||
emote_see = list("drools.","looks for donuts.")
|
||||
desc = "Stop right there criminal scum!"
|
||||
|
||||
if(/obj/item/clothing/head/wizard/fake, /obj/item/clothing/head/wizard, /obj/item/clothing/head/collectable/wizard)
|
||||
name = "Grandwizard [real_name]"
|
||||
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "EI NATH!")
|
||||
|
||||
if(/obj/item/clothing/head/wizard/red)
|
||||
name = "Pyromancer [real_name]"
|
||||
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "ONI SOMA!")
|
||||
|
||||
if(/obj/item/clothing/head/cardborg)
|
||||
name = "Borgi"
|
||||
speak = list("Ping!","Beep!","Woof!")
|
||||
emote_see = list("goes rogue.", "sniffs out non-humans.")
|
||||
desc = "Result of robotics budget cuts."
|
||||
|
||||
if(/obj/item/weapon/bedsheet)
|
||||
name = "\improper Ghost"
|
||||
speak = list("WoooOOOooo~","AUUUUUUUUUUUUUUUUUU")
|
||||
emote_see = list("stumbles around.", "shivers.")
|
||||
emote_hear = list("howls!","groans.")
|
||||
desc = "Spooky!"
|
||||
|
||||
if(/obj/item/clothing/head/helmet/space/santahat)
|
||||
name = "Santa's Corgi Helper"
|
||||
emote_hear = list("barks Christmas songs.", "yaps merrily!")
|
||||
emote_see = list("looks for presents.", "checks his list.")
|
||||
desc = "He's very fond of milk and cookies."
|
||||
|
||||
if(/obj/item/clothing/head/soft)
|
||||
name = "Corgi Tech [real_name]"
|
||||
desc = "The reason your yellow gloves have chew-marks."
|
||||
|
||||
if(/obj/item/clothing/head/hardhat/reindeer)
|
||||
name = "[real_name] the red-nosed Corgi"
|
||||
emote_hear = list("lights the way!", "illuminates.", "yaps!")
|
||||
desc = "He has a very shiny nose."
|
||||
|
||||
if(/obj/item/clothing/head/sombrero)
|
||||
name = "Segnor [real_name]"
|
||||
desc = "You must respect elder [real_name]"
|
||||
|
||||
if(/obj/item/clothing/head/hopcap)
|
||||
name = "Lieutenant [real_name]"
|
||||
desc = "Can actually be trusted to not run off on his own."
|
||||
|
||||
if(/obj/item/clothing/head/helmet/space/hardsuit/deathsquad)
|
||||
name = "Trooper [real_name]"
|
||||
desc = "That's not red paint. That's real corgi blood."
|
||||
|
||||
if(/obj/item/clothing/mask/gas/clown_hat)
|
||||
name = "[real_name] the Clown"
|
||||
desc = "Honkman's best friend."
|
||||
speak = list("HONK!", "Honk!")
|
||||
emote_see = list("plays tricks.", "slips.")
|
||||
else
|
||||
special_hat = 0
|
||||
|
||||
var/special_back = 0
|
||||
if(inventory_back)
|
||||
special_back = 1
|
||||
switch(inventory_back.type)
|
||||
if(/obj/item/clothing/suit/space/hardsuit/deathsquad)
|
||||
name = "Trooper [real_name]"
|
||||
desc = "That's not red paint. That's real corgi blood."
|
||||
else
|
||||
special_back = 0
|
||||
|
||||
if(!special_hat && !special_back)
|
||||
name = real_name
|
||||
desc = initial(desc)
|
||||
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
|
||||
speak_emote = list("barks", "woofs")
|
||||
emote_hear = list("barks", "woofs", "yaps","pants")
|
||||
emote_see = list("shakes its head", "shivers")
|
||||
desc = "It's a corgi."
|
||||
SetLuminosity(0)
|
||||
return
|
||||
if(inventory_back && inventory_back.dog_fashion)
|
||||
var/datum/dog_fashion/DF = new inventory_back.dog_fashion(src)
|
||||
DF.apply(src)
|
||||
|
||||
//IAN! SQUEEEEEEEEE~
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian
|
||||
@@ -538,22 +397,35 @@
|
||||
overlays.Cut()
|
||||
if(inventory_head)
|
||||
var/image/head_icon
|
||||
var/datum/dog_fashion.DF = new inventory_head.dog_fashion(src)
|
||||
|
||||
if(!DF.icon_state)
|
||||
DF.icon_state = inventory_head.icon_state
|
||||
|
||||
if(health <= 0)
|
||||
head_icon = image('icons/mob/corgi_head.dmi', icon_state = inventory_head.icon_state, dir = EAST)
|
||||
head_icon = DF.get_image(dir = EAST)
|
||||
head_icon.pixel_y = -8
|
||||
head_icon.transform = turn(head_icon.transform, 180)
|
||||
else
|
||||
head_icon = image('icons/mob/corgi_head.dmi', icon_state = inventory_head.icon_state)
|
||||
head_icon = DF.get_image()
|
||||
|
||||
overlays += head_icon
|
||||
|
||||
if(inventory_back)
|
||||
var/image/back_icon
|
||||
var/datum/dog_fashion.DF = new inventory_back.dog_fashion(src)
|
||||
|
||||
if(!DF.icon_state)
|
||||
DF.icon_state = inventory_back.icon_state
|
||||
|
||||
if(health <= 0)
|
||||
back_icon = image('icons/mob/corgi_back.dmi', icon_state = inventory_back.icon_state, dir = EAST)
|
||||
back_icon = DF.get_image(dir = EAST)
|
||||
back_icon.pixel_y = -11
|
||||
back_icon.transform = turn(back_icon.transform, 180)
|
||||
else
|
||||
back_icon = image('icons/mob/corgi_back.dmi', icon_state = inventory_back.icon_state)
|
||||
back_icon = DF.get_image()
|
||||
overlays += back_icon
|
||||
|
||||
if(facehugger)
|
||||
if(istype(src, /mob/living/simple_animal/pet/dog/corgi/puppy))
|
||||
overlays += image('icons/mob/mask.dmi',"facehugger_corgipuppy")
|
||||
@@ -665,4 +537,4 @@
|
||||
emote("me", 1, "yaps happily!")
|
||||
else
|
||||
if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case)
|
||||
emote("me", 1, "growls!")
|
||||
emote("me", 1, "growls!")
|
||||
|
||||
@@ -350,7 +350,7 @@
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
var/pre_attack = 0
|
||||
var/pre_attack_icon = "Goliath_preattack"
|
||||
loot = list(/obj/item/asteroid/goliath_hide{layer = 4.1})
|
||||
loot = list(/obj/item/stack/sheet/animalhide/goliath_hide{layer = 4.1})
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/Life()
|
||||
..()
|
||||
@@ -438,7 +438,7 @@
|
||||
spawn(50)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/asteroid/goliath_hide
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide
|
||||
name = "goliath hide plates"
|
||||
desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
@@ -447,7 +447,7 @@
|
||||
w_class = 3
|
||||
layer = 4
|
||||
|
||||
/obj/item/asteroid/goliath_hide/afterattack(atom/target, mob/user, proximity_flag)
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide/afterattack(atom/target, mob/user, proximity_flag)
|
||||
if(proximity_flag)
|
||||
if(istype(target, /obj/item/clothing/suit/space/hardsuit/mining) || istype(target, /obj/item/clothing/head/helmet/space/hardsuit/mining) || istype(target, /obj/item/clothing/suit/hooded/explorer) || istype(target, /obj/item/clothing/head/explorer))
|
||||
var/obj/item/clothing/C = target
|
||||
@@ -455,7 +455,7 @@
|
||||
if(current_armor.["melee"] < 60)
|
||||
current_armor.["melee"] = min(current_armor.["melee"] + 10, 60)
|
||||
user << "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>"
|
||||
qdel(src)
|
||||
use(1)
|
||||
else
|
||||
user << "<span class='warning'>You can't improve [C] any further!</span>"
|
||||
return
|
||||
@@ -635,7 +635,7 @@
|
||||
stat_attack = 1
|
||||
robust_searching = 1
|
||||
loot = list()
|
||||
butcher_results = list(/obj/item/weapon/ore/diamond = 2, /obj/item/stack/sheet/sinew = 1)
|
||||
butcher_results = list(/obj/item/weapon/ore/diamond = 2, /obj/item/stack/sheet/sinew = 1, /obj/item/stack/sheet/bone = 1)
|
||||
|
||||
//Goliath
|
||||
|
||||
@@ -649,7 +649,7 @@
|
||||
icon_dead = "goliath_dead"
|
||||
throw_message = "does nothing to the tough hide of the"
|
||||
pre_attack_icon = "goliath2"
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/goliath = 2, /obj/item/asteroid/goliath_hide = 1, /obj/item/stack/sheet/bone = 2)
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/goliath = 2, /obj/item/stack/sheet/animalhide/goliath_hide = 1, /obj/item/stack/sheet/bone = 2)
|
||||
loot = list()
|
||||
stat_attack = 1
|
||||
robust_searching = 1
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
body_parts_covered = HEAD
|
||||
burn_state = FLAMMABLE
|
||||
burntime = 5
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
|
||||
var/info //What's actually written on the paper.
|
||||
var/info_links //A different version of the paper which includes html links at fields and EOF
|
||||
|
||||
@@ -190,5 +190,5 @@
|
||||
click_cooldown_override = 1
|
||||
|
||||
/obj/item/projectile/beam/weak
|
||||
damage = 7
|
||||
damage = 15
|
||||
armour_penetration = 50
|
||||
|
||||
@@ -694,4 +694,9 @@
|
||||
description = "Fluorosulfuric acid is a an extremely corrosive chemical substance."
|
||||
color = "#8E18A9" // rgb: 142, 24, 169
|
||||
toxpwr = 2
|
||||
acidpwr = 20
|
||||
acidpwr = 42.0
|
||||
|
||||
/datum/reagent/toxin/acid/fluacid/on_mob_life(mob/living/M)
|
||||
M.adjustFireLoss(current_cycle/10, 0) // I rode a tank, held a general's rank
|
||||
. = 1 // When the blitzkrieg raged and the bodies stank
|
||||
..() // Pleased to meet you, hope you guess my name
|
||||
|
||||
@@ -32,6 +32,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
var/human_req = 0 //spell can only be cast by humans
|
||||
var/nonabstract_req = 0 //spell can only be cast by mobs that are physical entities
|
||||
var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells
|
||||
var/phase_allowed = 0 // If true, the spell can be cast while phased, eg. blood crawling, ethereal jaunting
|
||||
var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell
|
||||
var/invocation_emote_self = null
|
||||
var/invocation_type = "none" //can be none, whisper, emote and shout
|
||||
@@ -91,6 +92,10 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
user << "<span class='notice'>Not when you're incapacitated.</span>"
|
||||
return 0
|
||||
|
||||
if(!phase_allowed && istype(user.loc, /obj/effect/dummy))
|
||||
user << "<span class='notice'>[name] cannot be cast unless you are completely manifested in the material plane.</span>"
|
||||
return 0
|
||||
|
||||
if(ishuman(user))
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
desc = "Use pools of blood to phase out of existence."
|
||||
charge_max = 0
|
||||
clothes_req = 0
|
||||
//If you couldn't cast this while phased, you'd have a problem
|
||||
phase_allowed = 1
|
||||
selection_type = "range"
|
||||
range = 1
|
||||
cooldown_min = 0
|
||||
|
||||
@@ -43,9 +43,7 @@
|
||||
target.notransform=0 //mob is safely inside holder now, no need for protection.
|
||||
jaunt_steam(mobloc)
|
||||
|
||||
mute(target)
|
||||
sleep(jaunt_duration)
|
||||
unmute(target)
|
||||
|
||||
if(target.loc != holder) //mob warped out of the warp
|
||||
qdel(holder)
|
||||
@@ -71,29 +69,6 @@
|
||||
break
|
||||
target.canmove = 1
|
||||
|
||||
//Silence wizard during jaunt so they cannot spell cast while invisible
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/mute(target)
|
||||
if(!istype(target, /mob/living/carbon))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/mob_to_mute = target
|
||||
if(!mob_to_mute.dna)
|
||||
return FALSE
|
||||
|
||||
mob_to_mute.dna.add_mutation(MUT_MUTE)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/unmute(target)
|
||||
if(!istype(target, /mob/living/carbon))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/mob_to_mute = target
|
||||
if(!mob_to_mute.dna)
|
||||
return FALSE
|
||||
|
||||
mob_to_mute.dna.remove_mutation(MUT_MUTE)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/jaunt_disappear(atom/movable/overlay/animation, mob/living/target)
|
||||
animation.icon_state = "liquify"
|
||||
flick("liquify",animation)
|
||||
|
||||
@@ -4600,3 +4600,46 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
|
||||
- rscadd: You can craft primitive gear from bone and sinew.
|
||||
coiax:
|
||||
- bugfix: Non-humans are now able to interact with bee boxes.
|
||||
2016-04-25:
|
||||
Joan:
|
||||
- bugfix: You can once again hit a closet or crate with an item to open it.
|
||||
Kor Razharas:
|
||||
- rscadd: Adds support for autoclicking.
|
||||
- rscadd: The Shock Revolver has been added to RnD.
|
||||
- rscadd: The Laser Gatling Gun has been added to RnD. The Gatling Gun uses autoclick
|
||||
to fire as you hold down the mouse.
|
||||
- rscadd: The Research Director now starts with a box of firing pins.
|
||||
- rscadd: The SABR and Stun Revolver recipes have been removed from RnD
|
||||
coiax:
|
||||
- rscadd: Laughter demons are like slaughter demons, but they tickle people to death
|
||||
- tweak: Slaughter demons are no longer able to cast spells while phased.
|
||||
- tweak: Wizards can now speak while ethereal, but still cannot cast spells while
|
||||
ethereal.
|
||||
- rscadd: 'Centcom''s "drone expert" reports that drones vision filters have been
|
||||
upgraded to include the option of making all beings appear as harmless animals.
|
||||
info: As always, all drone filters are togglable.'
|
||||
- rscadd: As a sign of friendship between the Free Golems and Centcom, they have
|
||||
modified Centcom's jaunter to be worn around a user's waist, which will save
|
||||
them from falling to their death in a chasm.
|
||||
- experiment: The Golems warn that these modifications have created a risk of accidental
|
||||
activation when exposed to heavy electromagnetic fields.
|
||||
- tweak: Renamed hivelord stabilizer to stabilizing serum.
|
||||
- rscadd: Centcom regret to inform you that new instabilities with nearby gas giants
|
||||
are causing exospheric bubbles to affect the telecommunications processors.
|
||||
Please contact your supervisor for further instructions.
|
||||
- rscadd: The Janitor's Union has mandated additional features to station light
|
||||
replacer devices.
|
||||
- rscadd: The light replacer now can be used on the floor to replace the bulbs of
|
||||
any lights on that tile.
|
||||
- rscadd: The light replacer now eats replaced bulbs, and after a certain number
|
||||
of bulb fragments (four) will recycle them into a new bulb.
|
||||
- tweak: The description of the light replacer is now more informative.
|
||||
- rscadd: Clown mask appearance toggle now has an action button.
|
||||
2016-04-26:
|
||||
Joan:
|
||||
- tweak: Blobbernauts now spawn at half health.
|
||||
- tweak: Blobbernauts regeneration on blob is now 2.5 health per tick, from 5.
|
||||
- tweak: Blobbernauts now cost 40 resources to produce, from 30.
|
||||
- rscdel: Factories supporting blobbernauts do not spawn spores.
|
||||
TechnoAlchemisto:
|
||||
- tweak: Goliath plates can now be stacked.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
author: Iamgoofball & Super Aggro Crag
|
||||
delete-after: True
|
||||
changes:
|
||||
- tweak: "Fluorosulfuric Acid now has doubled acid power."
|
||||
- experiment: "Fluorosulfuric Acid now does BONUS burn damage scaling on the time it's been inside the consumer."
|
||||
@@ -1,8 +0,0 @@
|
||||
author: Kor Razharas
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Adds support for autoclicking."
|
||||
- rscadd: "The Shock Revolver has been added to RnD."
|
||||
- rscadd: "The Laser Gatling Gun has been added to RnD. The Gatling Gun uses autoclick to fire as you hold down the mouse."
|
||||
- rscadd: "The Research Director now starts with a box of firing pins."
|
||||
- rscadd: "The SABR and Stun Revolver recipes have been removed from RnD"
|
||||
@@ -1,6 +0,0 @@
|
||||
author: coiax
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Centcom's \"drone expert\" reports that drones vision filters have
|
||||
been upgraded to include the option of making all beings appear as harmless animals.
|
||||
info: As always, all drone filters are togglable."
|
||||
@@ -1,10 +0,0 @@
|
||||
author: coiax
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "As a sign of friendship between the Free Golems and Centcom,
|
||||
they have modified Centcom's jaunter to be worn around a user's waist,
|
||||
which will save them from falling to their death in a chasm."
|
||||
- experiment: "The Golems warn that these modifications have created
|
||||
a risk of accidental activation when exposed to heavy electromagnetic
|
||||
fields."
|
||||
- tweak: "Renamed hivelord stabilizer to stabilizing serum."
|
||||
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 242 KiB |
|
Before Width: | Height: | Size: 285 KiB After Width: | Height: | Size: 287 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 94 KiB |
@@ -153,6 +153,7 @@
|
||||
#include "code\datums\browser.dm"
|
||||
#include "code\datums\datacore.dm"
|
||||
#include "code\datums\datumvars.dm"
|
||||
#include "code\datums\dog_fashion.dm"
|
||||
#include "code\datums\hud.dm"
|
||||
#include "code\datums\martial.dm"
|
||||
#include "code\datums\material_container.dm"
|
||||
@@ -1022,6 +1023,7 @@
|
||||
#include "code\modules\events\operative.dm"
|
||||
#include "code\modules\events\portal_storm.dm"
|
||||
#include "code\modules\events\prison_break.dm"
|
||||
#include "code\modules\events\processor_overload.dm"
|
||||
#include "code\modules\events\radiation_storm.dm"
|
||||
#include "code\modules\events\shuttle_loan.dm"
|
||||
#include "code\modules\events\spacevine.dm"
|
||||
|
||||
@@ -27,7 +27,7 @@ THE SOFTWARE.
|
||||
|
||||
from __future__ import print_function
|
||||
import yaml, os, glob, sys, re, time, argparse
|
||||
from datetime import datetime, date
|
||||
from datetime import datetime, date, timedelta
|
||||
from time import time
|
||||
|
||||
today = date.today()
|
||||
@@ -36,6 +36,7 @@ dateformat = "%d %B %Y"
|
||||
|
||||
opt = argparse.ArgumentParser()
|
||||
opt.add_argument('-d', '--dry-run', dest='dryRun', default=False, action='store_true', help='Only parse changelogs and, if needed, the targetFile. (A .dry_changelog.yml will be output for debugging purposes.)')
|
||||
opt.add_argument('-t', '--time-period', dest='timePeriod', default=4, type=int, help='Define how many weeks back the changelog should display')
|
||||
opt.add_argument('targetFile', help='The HTML changelog we wish to update.')
|
||||
opt.add_argument('ymlDir', help='The directory of YAML changelogs we will use.')
|
||||
|
||||
@@ -172,8 +173,11 @@ with open(args.targetFile.replace('.htm', '.dry.htm') if args.dryRun else args.t
|
||||
with open(os.path.join(targetDir, 'templates', 'header.html'), 'r') as h:
|
||||
for line in h:
|
||||
changelog.write(line)
|
||||
|
||||
|
||||
weekstoshow = timedelta(weeks=args.timePeriod)
|
||||
for _date in reversed(sorted(all_changelog_entries.keys())):
|
||||
if not (today - _date < weekstoshow):
|
||||
continue
|
||||
entry_htm = '\n'
|
||||
entry_htm += '\t\t\t<h2 class="date">{date}</h2>\n'.format(date=_date.strftime(dateformat))
|
||||
write_entry = False
|
||||
|
||||