Merge branch 'master' into thatdanguy23_fluff_t2

This commit is contained in:
Gwydion Brain
2018-10-10 10:52:04 -07:00
384 changed files with 10115 additions and 6575 deletions
-1
View File
@@ -212,7 +212,6 @@ var/list/admin_verbs_proccall = list(
)
var/list/admin_verbs_snpc = list(
/client/proc/resetSNPC,
/client/proc/toggleSNPC,
/client/proc/customiseSNPC,
/client/proc/hide_snpc_verbs
)
-656
View File
@@ -1,656 +0,0 @@
#define BASIC_BUILDMODE 1
#define ADV_BUILDMODE 2
#define VAR_BUILDMODE 3
#define THROW_BUILDMODE 4
#define AREA_BUILDMODE 5
#define COPY_BUILDMODE 6
#define AREAEDIT_BUILDMODE 7
#define FILL_BUILDMODE 8
#define LINK_BUILDMODE 9
#define BOOM_BUILDMODE 10
#define SAVE_BUILDMODE 11
#define NUM_BUILDMODES 11
/obj/screen/buildmode
icon = 'icons/misc/buildmode.dmi'
var/datum/click_intercept/buildmode/bd
layer = HUD_LAYER_BUILDMODE
/obj/screen/buildmode/New(bld)
..()
bd = bld
/obj/screen/buildmode/mode
name = "Toggle Mode"
icon_state = "buildmode1"
screen_loc = "NORTH,WEST"
/obj/screen/buildmode/mode/Click(location, control, params)
var/list/pa = params2list(params)
if(pa.Find("left"))
bd.toggle_modes()
else if(pa.Find("right"))
bd.change_settings(usr)
update_icon()
return 1
/obj/screen/buildmode/mode/update_icon()
icon_state = "buildmode[bd.mode]"
return
/obj/screen/buildmode/help
icon_state = "buildhelp"
screen_loc = "NORTH,WEST+1"
name = "Buildmode Help"
/obj/screen/buildmode/help/Click()
bd.show_help(usr)
return 1
/obj/screen/buildmode/bdir
icon_state = "build"
screen_loc = "NORTH,WEST+2"
name = "Change Dir"
/obj/screen/buildmode/bdir/update_icon()
dir = bd.build_dir
return
/obj/screen/buildmode/bdir/Click()
bd.change_dir()
update_icon()
return 1
/obj/screen/buildmode/quit
icon_state = "buildquit"
screen_loc = "NORTH,WEST+3"
name = "Quit Buildmode"
/obj/screen/buildmode/quit/Click()
bd.quit()
return 1
/obj/screen/buildmode/dir/Click()
bd.change_dir()
update_icon()
return 1
/obj/effect/buildmode_reticule
var/image/I
var/client/cl
anchored = TRUE
/obj/effect/buildmode_reticule/New(var/turf/t, var/client/c)
loc = t
I = image('icons/mob/blob.dmi', t, "marker",19.0,2) // Sprite reuse wooo
if(c)
cl = c
cl.images += I
else
log_runtime(EXCEPTION("Buildmode reticule created without a client!"), src)
/obj/effect/buildmode_reticule/proc/deselect()
qdel(src)
/obj/effect/buildmode_reticule/Destroy()
cl.images -= I
cl = null
qdel(I)
return ..()
/obj/effect/buildmode_line
var/image/I
var/client/cl
/obj/effect/buildmode_line/New(var/client/c, var/atom/atom_a, var/atom/atom_b, var/linename)
name = linename
loc = get_turf(atom_a)
I = image('icons/misc/mark.dmi', src, "line", 19.0)
var/x_offset = ((atom_b.x * 32) + atom_b.pixel_x) - ((atom_a.x * 32) + atom_a.pixel_x)
var/y_offset = ((atom_b.y * 32) + atom_b.pixel_y) - ((atom_a.y * 32) + atom_a.pixel_y)
var/matrix/M = matrix()
M.Translate(0, 16)
M.Scale(1, sqrt((x_offset * x_offset) + (y_offset * y_offset)) / 32)
M.Turn(90 - Atan2(x_offset, y_offset)) // So... You pass coords in order x,y to this version of atan2. It should be called acsc2.
M.Translate(atom_a.pixel_x, atom_a.pixel_y)
transform = M
cl = c
cl.images += I
/obj/effect/buildmode_line/Destroy()
if(I)
if(istype(cl))
cl.images -= I
cl = null
QDEL_NULL(I)
return ..()
/datum/click_intercept
var/client/holder = null
var/list/obj/screen/buttons = list()
/datum/click_intercept/New(client/c)
create_buttons()
holder = c
holder.click_intercept = src
holder.show_popup_menus = 0
holder.screen += buttons
/datum/click_intercept/Destroy()
QDEL_LIST(buttons)
return ..()
/datum/click_intercept/proc/create_buttons()
return
/datum/click_intercept/proc/InterceptClickOn(user,params,atom/object)
return
/datum/click_intercept/proc/quit()
holder.screen -= buttons
holder.click_intercept = null
holder.show_popup_menus = 1
qdel(src)
/datum/click_intercept/buildmode
var/mode = BASIC_BUILDMODE
var/build_dir = SOUTH
var/atom/movable/throw_atom = null
var/obj/effect/buildmode_reticule/cornerA = null
var/obj/effect/buildmode_reticule/cornerB = null
var/generator_path = null
var/varholder = "name"
var/valueholder = "derp"
var/objholder = /obj/structure/closet
var/area/storedarea = null
var/image/areaimage
var/atom/movable/stored = null
var/list/link_lines = list()
var/obj/link_obj
var/valid_links = 0
//Explosion mode
var/devastation = -1
var/heavy = -1
var/light = -1
var/flash = -1
var/flames = -1
// Saving mode
var/use_json = TRUE
/datum/click_intercept/buildmode/New(client/c)
..()
areaimage = image('icons/turf/areas.dmi',null,"yellow")
holder.images += areaimage
/datum/click_intercept/buildmode/Destroy()
stored = null
Reset()
areaimage.loc = null
qdel(areaimage)
return ..()
/datum/click_intercept/buildmode/create_buttons()
buttons += new /obj/screen/buildmode/mode(src)
buttons += new /obj/screen/buildmode/help(src)
buttons += new /obj/screen/buildmode/bdir(src)
buttons += new /obj/screen/buildmode/quit(src)
/datum/click_intercept/buildmode/proc/toggle_modes()
mode = (mode % NUM_BUILDMODES) +1
Reset()
return
/datum/click_intercept/buildmode/proc/show_help(mob/user)
switch(mode)
if(BASIC_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button = Construct / Upgrade</span>")
to_chat(user, "<span class='notice'>Right Mouse Button = Deconstruct / Delete / Downgrade</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + ctrl = R-Window</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + alt = Airlock</span>")
to_chat(user, "")
to_chat(user, "<span class='notice'>Use the button in the upper left corner to</span>")
to_chat(user, "<span class='notice'>change the direction of built objects.</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
if(ADV_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Set object type</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj = Place objects</span>")
to_chat(user, "<span class='notice'>Right Mouse Button = Delete objects</span>")
to_chat(user, "")
to_chat(user, "<span class='notice'>Use the button in the upper left corner to</span>")
to_chat(user, "<span class='notice'>change the direction of built objects.</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
if(VAR_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select var(type) & value</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Set var(type) & value</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on turf/obj/mob = Reset var's value</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
if(THROW_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on turf/obj/mob = Throw</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
if(AREA_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select generator</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
if(COPY_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on obj/turf/mob = Spawn a Copy of selected target</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on obj/mob = Select target to copy</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
if(AREAEDIT_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on obj/turf/mob = Paint area</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on obj/turf/mob = Select area to paint</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Create new area</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
if(FILL_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + Alt on turf/obj/mob = Delete region</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select object type</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
if(LINK_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on obj = Select button to link</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on obj = Link/unlink to selected button")
to_chat(user, "<span class='notice'>***********************************************************</span>")
if(BOOM_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Mouse Button on obj = Kaboom</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
if(SAVE_BUILDMODE)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/click_intercept/buildmode/proc/change_settings(mob/user)
switch(mode)
if(BASIC_BUILDMODE)
return 1
if(ADV_BUILDMODE)
var/target_path = input(user,"Enter typepath:" ,"Typepath","/obj/structure/closet")
objholder = text2path(target_path)
if(!ispath(objholder))
objholder = pick_closest_path(target_path)
if(!objholder || ispath(objholder, /area))
objholder = /obj/structure/closet
alert("That path is not allowed.")
else
if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0))
objholder = /obj/structure/closet
if(VAR_BUILDMODE)
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine")
varholder = input(user,"Enter variable name:" ,"Name", "name")
if(varholder in locked && !check_rights(R_DEBUG,0))
return 1
var/thetype = input(user,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference")
if(!thetype) return 1
switch(thetype)
if("text")
valueholder = input(user,"Enter variable value:" ,"Value", "value") as text
if("number")
valueholder = input(user,"Enter variable value:" ,"Value", 123) as num
if("mob-reference")
valueholder = input(user,"Enter variable value:" ,"Value") as mob in mob_list
if("obj-reference")
valueholder = input(user,"Enter variable value:" ,"Value") as obj in world
if("turf-reference")
valueholder = input(user,"Enter variable value:" ,"Value") as turf in world
if(AREA_BUILDMODE)
var/list/gen_paths = subtypesof(/datum/mapGenerator)
var/type = input(user,"Select Generator Type","Type") as null|anything in gen_paths
if(!type) return
generator_path = type
cornerA = null
cornerB = null
if(AREAEDIT_BUILDMODE)
var/target_path = input(user,"Enter typepath:", "Typepath", "/area")
var/areatype = text2path(target_path)
if(ispath(areatype,/area))
var/areaname = input(user,"Enter area name:", "Area name", "Area")
if(!areaname || !length(areaname))
return
storedarea = new areatype
storedarea.power_equip = 0
storedarea.power_light = 0
storedarea.power_environ = 0
storedarea.always_unpowered = 0
storedarea.name = areaname
areaimage.loc = storedarea
if(FILL_BUILDMODE)
var/target_path = input(user,"Enter typepath:" ,"Typepath","/obj/structure/closet")
objholder = text2path(target_path)
if(!ispath(objholder))
objholder = pick_closest_path(target_path)
if(!objholder || ispath(objholder, /area))
objholder = /obj/structure/closet
return
else
if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0))
objholder = /obj/structure/closet
deselect_region()
if(BOOM_BUILDMODE)
devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null
if(devastation == null) devastation = -1
heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null
if(heavy == null) heavy = -1
light = input("Range of light impact. -1 to none", text("Input")) as num|null
if(light == null) light = -1
flash = input("Range of flash. -1 to none", text("Input")) as num|null
if(flash == null) flash = -1
flames = input("Range of flames. -1 to none", text("Input")) as num|null
if(flames == null) flames = -1
if(SAVE_BUILDMODE)
use_json = (alert("Would you like to use json (Default is \"Yes\")?",,"Yes","No") == "Yes")
/datum/click_intercept/buildmode/proc/change_dir()
switch(build_dir)
if(NORTH)
build_dir = EAST
if(EAST)
build_dir = SOUTH
if(SOUTH)
build_dir = WEST
if(WEST)
build_dir = NORTHWEST
if(NORTHWEST)
build_dir = NORTH
return 1
/datum/click_intercept/buildmode/proc/deselect_region()
QDEL_NULL(cornerA)
QDEL_NULL(cornerB)
/datum/click_intercept/buildmode/proc/Reset()//Reset temporary variables
deselect_region()
if(mode == AREAEDIT_BUILDMODE)
areaimage.loc = storedarea
else
areaimage.loc = null
for(var/obj/effect/buildmode_line/L in link_lines)
qdel(L)
link_lines -= L
/datum/click_intercept/buildmode/proc/select_tile(var/turf/T)
return new /obj/effect/buildmode_reticule(T, holder)
/proc/togglebuildmode(mob/M as mob in player_list)
set name = "Toggle Build Mode"
set category = "Event"
if(M.client)
if(istype(M.client.click_intercept,/datum/click_intercept/buildmode))
var/datum/click_intercept/buildmode/B = M.client.click_intercept
B.quit()
log_admin("[key_name(usr)] has left build mode.")
else
new/datum/click_intercept/buildmode(M.client)
message_admins("[key_name_admin(usr)] has entered build mode.")
log_admin("[key_name(usr)] has entered build mode.")
/datum/click_intercept/buildmode/InterceptClickOn(user,params,atom/object) //Click Intercept
var/list/pa = params2list(params)
var/right_click = pa.Find("right")
var/left_click = pa.Find("left")
var/alt_click = pa.Find("alt")
var/ctrl_click = pa.Find("ctrl")
. = 1
switch(mode)
if(BASIC_BUILDMODE)
if(istype(object,/turf) && left_click && !alt_click && !ctrl_click)
var/turf/T = object
if(istype(object,/turf/space))
T.ChangeTurf(/turf/simulated/floor/plasteel)
else if(istype(object,/turf/simulated/floor))
T.ChangeTurf(/turf/simulated/wall)
else if(istype(object,/turf/simulated/wall))
T.ChangeTurf(/turf/simulated/wall/r_wall)
log_admin("Build Mode: [key_name(user)] built [T] at ([T.x],[T.y],[T.z])")
return
else if(right_click)
log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])")
if(istype(object,/turf/simulated/wall))
var/turf/T = object
T.ChangeTurf(/turf/simulated/floor/plasteel)
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
T.ChangeTurf(/turf/space)
else if(istype(object,/turf/simulated/wall/r_wall))
var/turf/T = object
T.ChangeTurf(/turf/simulated/wall)
else if(istype(object,/obj))
qdel(object)
return
else if(istype(object,/turf) && alt_click && left_click)
log_admin("Build Mode: [key_name(user)] built an airlock at ([object.x],[object.y],[object.z])")
new/obj/machinery/door/airlock(get_turf(object))
else if(istype(object,/turf) && ctrl_click && left_click)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.setDir(build_dir)
log_admin("Build Mode: [key_name(user)] built a window at ([object.x],[object.y],[object.z])")
if(ADV_BUILDMODE)
if(left_click)
if(ispath(objholder,/turf))
var/turf/T = get_turf(object)
log_admin("Build Mode: [key_name(user)] modified [T] ([T.x],[T.y],[T.z]) to [objholder]")
T.ChangeTurf(objholder)
else if(!isnull(objholder))
var/obj/A = new objholder (get_turf(object))
A.setDir(build_dir)
log_admin("Build Mode: [key_name(user)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [build_dir]")
else
to_chat(user, "<span class='warning'>Select object type first.</span>")
else if(right_click)
if(isobj(object))
log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])")
qdel(object)
if(VAR_BUILDMODE)
if(left_click) //I cant believe this shit actually compiles.
if(object.vars.Find(varholder))
log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]")
object.vars[varholder] = valueholder
else
to_chat(user, "<span class='warning'>[initial(object.name)] does not have a var called '[varholder]'</span>")
if(right_click)
if(object.vars.Find(varholder))
log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]")
object.vars[varholder] = initial(object.vars[varholder])
else
to_chat(user, "<span class='warning'>[initial(object.name)] does not have a var called '[varholder]'</span>")
if(THROW_BUILDMODE)
if(left_click)
if(isturf(object))
return
throw_atom = object
if(right_click)
if(throw_atom)
throw_atom.throw_at(object, 10, 1,user)
log_admin("Build Mode: [key_name(user)] threw [throw_atom] at [object] ([object.x],[object.y],[object.z])")
if(AREA_BUILDMODE)
if(!cornerA)
cornerA = select_tile(get_turf(object))
return
if(cornerA && !cornerB)
cornerB = select_tile(get_turf(object))
if(left_click) //rectangular
if(cornerA && cornerB)
if(!generator_path)
to_chat(user, "<span class='warning'>Select generator type first.</span>")
else
var/datum/mapGenerator/G = new generator_path
G.defineRegion(cornerA.loc,cornerB.loc,1)
G.generate()
deselect_region()
return
//Something wrong - Reset
deselect_region()
if(COPY_BUILDMODE)
if(left_click)
var/turf/T = get_turf(object)
if(stored)
DuplicateObject(stored, perfectcopy=1, sameloc=0,newloc=T)
else if(right_click)
if(ismovableatom(object)) // No copying turfs for now.
to_chat(user, "<span class='notice'>[object] set as template.</span>")
stored = object
if(AREAEDIT_BUILDMODE)
if(left_click)
if(!storedarea)
return
var/turf/T = get_turf(object)
if(get_area(T) != storedarea)
storedarea.contents.Add(T)
else if(right_click)
var/turf/T = get_turf(object)
storedarea = get_area(T)
areaimage.loc = storedarea
if(FILL_BUILDMODE)
if(!cornerA)
cornerA = select_tile(get_turf(object))
return
if(cornerA && !cornerB)
cornerB = select_tile(get_turf(object))
if(left_click) //rectangular
if(cornerA && cornerB)
if(alt_click)
empty_region(block(get_turf(cornerA),get_turf(cornerB)))
deselect_region()
else
if(!objholder)
to_chat(user, "<span class='warning'>Select object type first.</span>")
else
for(var/turf/T in block(get_turf(cornerA),get_turf(cornerB)))
if(ispath(objholder,/turf))
T.ChangeTurf(objholder)
else
var/obj/A = new objholder(T)
A.setDir(build_dir)
deselect_region()
return
//Something wrong - Reset
deselect_region()
if(LINK_BUILDMODE)
if(left_click && istype(object, /obj/machinery))
link_obj = object
if(right_click && istype(object, /obj/machinery))
if(istype(link_obj, /obj/machinery/door_control) && istype(object, /obj/machinery/door/airlock))
var/obj/machinery/door_control/M = link_obj
var/obj/machinery/door/airlock/P = object
if(!M.id || M.id == "")
M.id = input(holder, "Please select an ID for the button", "Buildmode", "")
if(!M.id || M.id == "")
goto(line_jump)
if(P.id_tag == M.id && (P in range(M.range, M)) && P.id_tag && P.id_tag != "")
P.id_tag = null
to_chat(holder, "[P] unlinked.")
goto(line_jump)
if(!M.normaldoorcontrol)
if(link_lines.len && alert(holder, "Warning: This will disable links to connected pod doors. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
M.normaldoorcontrol = 1
if(P.id_tag && alert(holder, "Warning: This will unlink something else from the door. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
P.id_tag = M.id
if(istype(link_obj, /obj/machinery/door_control) && istype(object, /obj/machinery/door/poddoor))
var/obj/machinery/door_control/M = link_obj
var/obj/machinery/door/poddoor/P = object
if(!M.id || M.id == "")
M.id = input(holder, "Please select an ID for the button", "Buildmode", "")
if(!M.id || M.id == "")
goto(line_jump)
if(P.id_tag == M.id && P.id_tag && P.id_tag != "")
P.id_tag = null
to_chat(holder, "[P] unlinked.")
goto(line_jump)
if(M.normaldoorcontrol)
if(link_lines.len && alert(holder, "Warning: This will disable links to connected airlocks. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
M.normaldoorcontrol = 0
if(!M.id || M.id == "")
M.id = input(holder, "Please select an ID for the button", "Buildmode", "")
if(!M.id || M.id == "")
goto(line_jump)
if(P.id_tag && P.id_tag != 1 && alert(holder, "Warning: This will unlink something else from the door. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
P.id_tag = M.id
line_jump // For the goto
valid_links = 0
for(var/obj/effect/buildmode_line/L in link_lines)
qdel(L)
link_lines -= L
if(istype(link_obj, /obj/machinery/door_control))
var/obj/machinery/door_control/M = link_obj
for(var/obj/machinery/door/airlock/P in range(M.range,M))
if(P.id_tag == M.id)
var/obj/effect/buildmode_line/L = new(holder, M, P, "[M.name] to [P.name]")
L.color = M.normaldoorcontrol ? "#339933" : "#993333"
if(M.normaldoorcontrol)
valid_links = 1
link_lines += L
var/obj/effect/buildmode_line/L2 = new(holder, P, M, "[M.name] to [P.name]") // Yes, reversed one so that you can see it from both sides.
L2.color = L.color
link_lines += L2
for(var/obj/machinery/door/poddoor/P in airlocks)
if(P.id_tag == M.id)
var/obj/effect/buildmode_line/L = new(holder, M, P, "[M.name] to [P.name]")
L.color = M.normaldoorcontrol ? "#993333" : "#339933"
if(M.normaldoorcontrol)
valid_links = 0
link_lines += L
var/obj/effect/buildmode_line/L2 = new(holder, P, M, "[M.name] to [P.name]") // Yes, reversed one so that you can see it from both sides.
L2.color = L.color
link_lines += L2
if(BOOM_BUILDMODE)
explosion(object, devastation, heavy, light, flash, null, TRUE, flames)
if(SAVE_BUILDMODE)
if(!cornerA)
cornerA = select_tile(get_turf(object))
return
if(!cornerB)
cornerB = select_tile(get_turf(object))
if(left_click)
if(cornerA && cornerB)
var/turf/A = get_turf(cornerA)
var/turf/B = get_turf(cornerB)
deselect_region() // So we don't read our own reticules
var/map_name = input(holder, "Please select a name for your map", "Buildmode", "")
if(map_name == "")
return
var/map_flags = 0
if(use_json)
map_flags = 32 // Magic number defined in `writer.dm` that I can't use directly
// because #defines are for some reason our coding standard
var/our_map = maploader.save_map(A,B,map_name,map_flags)
holder << ftp(our_map) // send the map they've made! Or are stealing, whatever
to_chat(holder, "Map saving complete! [our_map]")
return
deselect_region()
+2 -2
View File
@@ -1988,7 +1988,7 @@
P.name = "Central Command - paper"
var/stypes = list("Handle it yourselves!","Illegible fax","Fax not signed","Not Right Now","You are wasting our time", "Keep up the good work", "ERT Instructions")
var/stype = input(src.owner, "Which type of standard reply do you wish to send to [H]?","Choose your paperwork", "") as null|anything in stypes
var/tmsg = "<font face='Verdana' color='black'><center><img src = 'ntlogo.png'><BR><BR><BR><font size='4'><B>Nanotrasen Science Station Cyberiad</B></font><BR><BR><BR><font size='4'>NAS Trurl Communications Department Report</font></center><BR><BR>"
var/tmsg = "<font face='Verdana' color='black'><center><img src = 'ntlogo.png'><BR><BR><BR><font size='4'><B>Nanotrasen Science Station [using_map.station_short]</B></font><BR><BR><BR><font size='4'>NAS Trurl Communications Department Report</font></center><BR><BR>"
if(stype == "Handle it yourselves!")
tmsg += "Greetings, esteemed crewmember. Your fax has been <B><I>DECLINED</I></B> automatically by NAS Trurl Fax Registration.<BR><BR>Please proceed in accordance with Standard Operating Procedure and/or Space Law. You are fully trained to handle this situation without Central Command intervention.<BR><BR><i><small>This is an automatic message.</small>"
else if(stype == "Illegible fax")
@@ -2066,7 +2066,7 @@
var/input = input(src.owner, "Please enter a reason for denying [key_name(H)]'s ERT request.","Outgoing message from CentComm", "")
if(!input) return
ert_request_answered = 1
ert_request_answered = TRUE
to_chat(src.owner, "You sent [input] to [H] via a secure channel.")
log_admin("[src.owner] denied [key_name(H)]'s ERT request with the message [input].")
to_chat(H, "You hear something crackle in your headset for a moment before a voice speaks. \"Your ERT request has been denied for the following reasons: [input]. Message ends.\"")
+21 -17
View File
@@ -516,6 +516,24 @@ var/list/VVpixelmovement = list("step_x", "step_y", "step_size", "bound_height",
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: [original_var]=[new_var]")
message_admins("[key_name_admin(src)] modified [original_name]'s varlist [objectvar]: [original_var]=[new_var]")
/proc/vv_varname_lockcheck(param_var_name)
if(param_var_name in VVlocked)
if(!check_rights(R_DEBUG))
return FALSE
if(param_var_name in VVckey_edit)
if(!check_rights(R_EVENT | R_DEBUG))
return FALSE
if(param_var_name in VVicon_edit_lock)
if(!check_rights(R_EVENT | R_DEBUG))
return FALSE
if(param_var_name in VVpixelmovement)
if(!check_rights(R_DEBUG))
return FALSE
var/prompt = alert(usr, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT")
if(prompt != "Continue")
return FALSE
return TRUE
/client/proc/modify_variables(atom/O, param_var_name = null, autodetect_class = 0)
if(!check_rights(R_VAREDIT))
return
@@ -544,25 +562,11 @@ var/list/VVpixelmovement = list("step_x", "step_y", "step_size", "bound_height",
if(!O.can_vv_get(variable))
return
if(!vv_varname_lockcheck(variable))
return
var_value = O.vars[variable]
if(variable in VVlocked)
if(!check_rights(R_DEBUG))
return
if(variable in VVckey_edit)
if(!check_rights(R_EVENT | R_DEBUG))
return
if(variable in VVicon_edit_lock)
if(!check_rights(R_EVENT | R_DEBUG))
return
if(variable in VVpixelmovement)
if(!check_rights(R_DEBUG))
return
var/prompt = alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT")
if(prompt != "Continue")
return
var/default = vv_get_class(var_value)
if(isnull(default))
-1
View File
@@ -54,7 +54,6 @@
H.Stun(3)
if(affecting)
affecting.receive_damage(1, 0)
H.updatehealth()
else if(ismouse(target))
var/mob/living/simple_animal/mouse/M = target
visible_message("<span class='danger'>SPLAT!</span>")
@@ -3,7 +3,7 @@
icon = 'icons/effects/effects.dmi'
icon_state = "extinguish"
opacity = 0
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
density = 0
anchored = 1
invisibility = 101
@@ -262,8 +262,9 @@
return list()
/mob/living/simple_animal/hostile/syndicate/ranged/wildwest/death(gibbed)
if(!on_alert)
// putting this up here so we don't say anything after deathgasp
if(can_die() && !on_alert)
say("How could you betray the Syndicate?")
for(var/mob/living/simple_animal/hostile/syndicate/ranged/wildwest/W in living_mob_list)
W.on_alert = TRUE
..(gibbed)
return ..(gibbed)
+297
View File
@@ -0,0 +1,297 @@
# Buildmode
## Code layout
### Buildmode
Manager for buildmode modes. Contains logic to manage switching between each mode, and presenting a suitable user interface.
### Effects
Special graphics used by buildmode modes for user interface purposes.
### Buildmode Mode
Implementer of buildmode behaviors.
Existing varieties:
+ Basic
**Description**:
Allows creation of simple structures consisting of floors, walls, windows, and airlocks.
**Controls**:
+ *Left click a turf*:
"Upgrades" the turf based on the following rules below:
+ Space -> Tiled floor
+ Simulated floor -> Regular wall
+ Wall -> Reinforced wall
+ *Right click a turf*:
"Downgrades" the turf based on the following rules below:
+ Reinforced wall -> Regular wall
+ Wall -> Tiled floor
+ Simulated floor -> Space
+ *Right click an object*:
Deletes the clicked object.
+ *Alt+Left click a location*:
Places an airlock at the clicked location.
+ *Ctrl+Left click a location*:
Places a window at the clicked location.
+ Advanced
**Description**:
Creates an instance of a configurable atom path where you click.
**Controls**:
+ *Right click on the mode selector*:
Choose a path to spawn.
+ *Alt+Left click a turf, object, or mob*:
Select the type of the object clicked.
+ *Left click a location* (requires chosen path):
Place an instance of the chosen path at the location.
+ *Right click an object*:
Delete the object.
+ Fill
**Description**:
Creates an instance of an atom path on every tile in a chosen region.
With a special control input, instead deletes everything within the region.
**Controls**:
+ *Right click on the mode selector*:
Choose a path to spawn.
+ *Left click on a region* (requires chosen path):
Fill the region with the chosen path.
+ *Alt+Left click on a region*:
Deletes everything within the region.
+ *Right click during region selection*:
Cancel region selection.
+ Atmos
**Description**:
Fills a region with configurable atmos. By default, ignores unsimulated turfs, but is able to "overwrite" the atmos of unsimulated turfs with a special control input.
By default, fills a region with a breathable, standard atmosphere.
**Controls**:
+ *Right click on the mode selector icon*:
Set the following traits:
+ Total Pressure
+ Temperature
+ Partial Pressure Ratio (PPR) Oxygen
+ PPR Nitrogen
+ PPR Plasma
+ PPR CO2
+ PPR N2O
+ *Left click a region*:
Fill the region with the configured atmos.
+ *Control+Left click a region*:
As with the regular left click, but also "overwrites" the base atmos of any unsimulated turfs in the region - such as space turfs.
+ *Right click during region selection*:
Cancel region selection.
+ Copy
**Description**:
Take an existing object in the world, and place duplicates with identical attributes where you click.
May not always work nicely - "deep" variables such as lists or datums may malfunction.
**Controls**:
+ *Right click an existing object*:
Select the clicked object as a template.
+ *Left click a location* (Requires a selected object as template):
Place a duplicate of the template at the clicked location.
+ Link
**Description**:
Form links between door control buttons and either airlocks or pod bay doors.
The selected button will be highlighted, and visible lines will be drawn between the doors it is linked to and itself.
**Controls**:
+ *Left click a door control button*:
Makes the button active, and show what doors it is linked to.
+ *Right click an airlock* (requires active button):
Links the airlock to the active button. Will remove all links from the button first, if the button is linked to pod bay doors.
+ *Right click a pod bay door* (requires active button):
Links the pod bay door to the active button. Will remove all links from the button first, if the button is linked to regular airlocks.
+ Area Edit
**Description**:
Modifies and creates areas.
The active area will be highlighted in yellow.
**Controls**:
+ *Right click the mode selector*:
Create a new area, and make it active.
+ *Right click an existing area*:
Make the clicked area active.
+ *Left click a turf*:
When an area is active, adds the turf to the active area.
+ Var Edit
**Description**:
Allows for setting and resetting variables of objects with a click.
If the object does not have the var, will do nothing and print a warning message.
**Controls**:
+ *Right click the mode selector*:
Choose which variable to set, and what to set it to.
+ *Left click an atom*:
Change the clicked atom's variables as configured.
+ *Right click an atom*:
Reset the targeted variable to its original value in the code.
+ Map Generator
**Description**:
Fills rectangular regions with algorithmically generated content. Right click during region selection to cancel.
See the `procedural_mapping` module for the generators themselves.
**Controls**:
+ *Right-click on the mode selector*:
Select a map generator from all the generators present in the codebase.
+ *Left click two corners of an area*:
Use the generator to populate the region.
+ *Right click during region selection*:
Cancel region selection.
+ Save
**Description**:
Captures a rectangular region in a `.dmm` format, which can be loaded back later using the "Place Map Template" debug verb.
Keep in mind this feature is somewhat experimental, and may not always work.
**Controls**:
+ *Right click on the mode selector*:
Configure whether to save in either JSON mode or not.
+ *Left click two corners of an area*:
Save the region to a `.dmm` file. You will be prompted for where to save this - a copy will be saved in the `_maps/quicksave` folder.
+ *Right click during region selection*:
Cancel region selection.
+ Throwing
**Description**:
Select an object with left click, and right click to throw it towards where you clicked.
**Controls**:
+ *Left click on a movable atom*:
Select the atom for throwing.
+ *Right click on a location*:
Throw the selected atom towards that location.
+ Boom
**Description**:
Make explosions where you click.
**Controls**:
+ *Right click the mode selector*:
Configure the explosion size.
+ *Left click a location*:
Cause an explosion where you clicked.
+87
View File
@@ -0,0 +1,87 @@
/datum/buildmode_mode
var/key = "oops"
var/datum/click_intercept/buildmode/BM
var/use_corner_selection = FALSE
var/processing_selection = FALSE
var/list/preview
var/turf/cornerA
var/turf/cornerB
/datum/buildmode_mode/New(datum/click_intercept/buildmode/newBM)
BM = newBM
preview = list()
return ..()
/datum/buildmode_mode/Destroy()
Reset()
return ..()
/datum/buildmode_mode/proc/enter_mode(datum/click_intercept/buildmode/BM)
return
/datum/buildmode_mode/proc/exit_mode(datum/click_intercept/buildmode/BM)
return
/datum/buildmode_mode/proc/get_button_iconstate()
return "buildmode_[key]"
/datum/buildmode_mode/proc/show_help(mob/user)
CRASH("No help defined, yell at a coder")
to_chat(user, "<span class='warning'>There is no help defined for this mode, this is a bug.</span>")
/datum/buildmode_mode/proc/change_settings(mob/user)
to_chat(user, "<span class='warning'>There is no configuration available for this mode</span>")
/datum/buildmode_mode/proc/Reset()
deselect_region()
/datum/buildmode_mode/proc/select_tile(turf/T, corner_to_select)
var/overlaystate
BM.holder.images -= preview
switch(corner_to_select)
if(AREASELECT_CORNERA)
overlaystate = "greenOverlay"
if(AREASELECT_CORNERB)
overlaystate = "blueOverlay"
preview += image('icons/turf/overlays.dmi', T, overlaystate)
BM.holder.images += preview
return T
/datum/buildmode_mode/proc/highlight_region(region)
BM.holder.images -= preview
for(var/t in region)
preview += image('icons/turf/overlays.dmi', T, "redOverlay")
BM.holder.images += preview
/datum/buildmode_mode/proc/deselect_region()
BM.holder.images -= preview
QDEL_LIST(preview)
cornerA = null
cornerB = null
/datum/buildmode_mode/proc/handle_click(user, params, object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
if(use_corner_selection)
if(left_click)
if(!cornerA)
cornerA = select_tile(get_turf(object), AREASELECT_CORNERA)
return
else if(!cornerB)
cornerB = select_tile(get_turf(object), AREASELECT_CORNERB)
to_chat(user, "<span class='boldwarning'>Region selected, if you're happy with your selection left click again, otherwise right click.</span>")
return
if(processing_selection)
return
processing_selection = TRUE
handle_selected_region(user, params)
processing_selection = FALSE
deselect_region()
else if(cornerA || cornerB)
to_chat(user, "<span class='notice'>Region selection canceled!</span>")
deselect_region()
/datum/buildmode_mode/proc/handle_selected_region(mob/user, params)
return
+127
View File
@@ -0,0 +1,127 @@
#define BM_SWITCHSTATE_NONE 0
#define BM_SWITCHSTATE_MODE 1
#define BM_SWITCHSTATE_DIR 2
/datum/click_intercept/buildmode
var/build_dir = SOUTH
var/datum/buildmode_mode/mode
// SECTION UI
// Switching management
var/switch_state = BM_SWITCHSTATE_NONE
var/switch_width = 5
// modeswitch UI
var/obj/screen/buildmode/mode/modebutton
var/list/modeswitch_buttons = list()
// dirswitch UI
var/obj/screen/buildmode/bdir/dirbutton
var/list/dirswitch_buttons = list()
/datum/click_intercept/buildmode/New()
mode = new /datum/buildmode_mode/basic(src)
. = ..()
mode.enter_mode(src)
/datum/click_intercept/buildmode/Destroy()
close_switchstates()
QDEL_NULL(mode)
QDEL_LIST(modeswitch_buttons)
QDEL_LIST(dirswitch_buttons)
return ..()
/datum/click_intercept/buildmode/create_buttons()
// keep a reference so we can update it upon mode switch
modebutton = new /obj/screen/buildmode/mode(src)
buttons += modebutton
buttons += new /obj/screen/buildmode/help(src)
// keep a reference so we can update it upon dir switch
dirbutton = new /obj/screen/buildmode/bdir(src)
buttons += dirbutton
buttons += new /obj/screen/buildmode/quit(src)
// build the list of modeswitching buttons
build_options_grid(subtypesof(/datum/buildmode_mode), modeswitch_buttons, /obj/screen/buildmode/modeswitch)
build_options_grid(list(SOUTH,EAST,WEST,NORTH,NORTHWEST), dirswitch_buttons, /obj/screen/buildmode/dirswitch)
/datum/click_intercept/buildmode/proc/build_options_grid(list/elements, list/buttonslist, buttontype)
var/pos_idx = 0
for(var/thing in elements)
var/x = pos_idx % switch_width
var/y = FLOOR(pos_idx / switch_width, 1)
var/obj/screen/buildmode/B = new buttontype(src, thing)
// extra .5 for a nice offset look
B.screen_loc = "NORTH-[(1 + 0.5 + y*1.5)],WEST+[0.5 + x*1.5]"
buttonslist += B
pos_idx++
/datum/click_intercept/buildmode/proc/close_switchstates()
switch(switch_state)
if(BM_SWITCHSTATE_MODE)
close_modeswitch()
if(BM_SWITCHSTATE_DIR)
close_dirswitch()
/datum/click_intercept/buildmode/proc/toggle_modeswitch()
if(switch_state == BM_SWITCHSTATE_MODE)
close_modeswitch()
else
close_switchstates()
open_modeswitch()
/datum/click_intercept/buildmode/proc/open_modeswitch()
switch_state = BM_SWITCHSTATE_MODE
holder.screen += modeswitch_buttons
/datum/click_intercept/buildmode/proc/close_modeswitch()
switch_state = BM_SWITCHSTATE_NONE
holder.screen -= modeswitch_buttons
/datum/click_intercept/buildmode/proc/toggle_dirswitch()
if(switch_state == BM_SWITCHSTATE_DIR)
close_dirswitch()
else
close_switchstates()
open_dirswitch()
/datum/click_intercept/buildmode/proc/open_dirswitch()
switch_state = BM_SWITCHSTATE_DIR
holder.screen += dirswitch_buttons
/datum/click_intercept/buildmode/proc/close_dirswitch()
switch_state = BM_SWITCHSTATE_NONE
holder.screen -= dirswitch_buttons
/datum/click_intercept/buildmode/proc/change_mode(newmode)
mode.exit_mode(src)
QDEL_NULL(mode)
close_switchstates()
mode = new newmode(src)
mode.enter_mode(src)
modebutton.update_icon()
/datum/click_intercept/buildmode/proc/change_dir(newdir)
build_dir = newdir
close_dirswitch()
dirbutton.update_icon()
return TRUE
/datum/click_intercept/buildmode/InterceptClickOn(user, params, atom/object)
mode.handle_click(user, params, object)
/proc/togglebuildmode(mob/M in player_list)
set name = "Toggle Build Mode"
set category = "Event"
if(M.client)
if(istype(M.client.click_intercept, /datum/click_intercept/buildmode))
var/datum/click_intercept/buildmode/B = M.client.click_intercept
B.quit()
log_admin("[key_name(usr)] has left build mode.")
else
new/datum/click_intercept/buildmode(M.client)
message_admins("[key_name_admin(usr)] has entered build mode.")
log_admin("[key_name(usr)] has entered build mode.")
#undef BM_SWITCHSTATE_NONE
#undef BM_SWITCHSTATE_MODE
#undef BM_SWITCHSTATE_DIR
+88
View File
@@ -0,0 +1,88 @@
/obj/screen/buildmode
icon = 'icons/misc/buildmode.dmi'
var/datum/click_intercept/buildmode/bd
layer = HUD_LAYER_BUILDMODE
/obj/screen/buildmode/New(bld)
bd = bld
return ..()
/obj/screen/buildmode/Destroy()
bd = null
return ..()
/obj/screen/buildmode/mode
name = "Toggle Mode"
icon_state = "buildmode_basic"
screen_loc = "NORTH,WEST"
/obj/screen/buildmode/mode/Click(location, control, params)
var/list/pa = params2list(params)
if(pa.Find("left"))
bd.toggle_modeswitch()
else if(pa.Find("right"))
bd.mode.change_settings(usr)
update_icon()
return TRUE
/obj/screen/buildmode/mode/update_icon()
icon_state = bd.mode.get_button_iconstate()
/obj/screen/buildmode/help
icon_state = "buildhelp"
screen_loc = "NORTH,WEST+1"
name = "Buildmode Help"
/obj/screen/buildmode/help/Click()
bd.mode.show_help(usr)
return TRUE
/obj/screen/buildmode/bdir
icon_state = "build"
screen_loc = "NORTH,WEST+2"
name = "Change Dir"
/obj/screen/buildmode/bdir/update_icon()
dir = bd.build_dir
/obj/screen/buildmode/bdir/Click()
bd.toggle_dirswitch()
update_icon()
return TRUE
// used to switch between modes
/obj/screen/buildmode/modeswitch
var/datum/buildmode_mode/modetype
/obj/screen/buildmode/modeswitch/New(bld, mt)
modetype = mt
icon_state = "buildmode_[initial(modetype.key)]"
name = initial(modetype.key)
return ..(bld)
/obj/screen/buildmode/modeswitch/Click()
bd.change_mode(modetype)
return TRUE
// used to switch between dirs
/obj/screen/buildmode/dirswitch
icon_state = "build"
/obj/screen/buildmode/dirswitch/New(bld, newdir)
dir = newdir
name = dir2text(dir)
return ..(bld)
/obj/screen/buildmode/dirswitch/Click()
bd.change_dir(dir)
return TRUE
/obj/screen/buildmode/quit
icon_state = "buildquit"
screen_loc = "NORTH,WEST+3"
name = "Quit Buildmode"
/obj/screen/buildmode/quit/Click()
bd.quit()
return TRUE
+28
View File
@@ -0,0 +1,28 @@
/obj/effect/buildmode_line
var/image/I
var/client/cl
/obj/effect/buildmode_line/New(client/C, atom/atom_a, atom/atom_b, linename)
name = linename
loc = get_turf(atom_a)
I = image('icons/misc/mark.dmi', src, "line", 19.0)
var/x_offset = ((atom_b.x * 32) + atom_b.pixel_x) - ((atom_a.x * 32) + atom_a.pixel_x)
var/y_offset = ((atom_b.y * 32) + atom_b.pixel_y) - ((atom_a.y * 32) + atom_a.pixel_y)
var/matrix/mat = matrix()
mat.Translate(0, 16)
mat.Scale(1, sqrt((x_offset * x_offset) + (y_offset * y_offset)) / 32)
mat.Turn(90 - Atan2(x_offset, y_offset)) // So... You pass coords in order x,y to this version of atan2. It should be called acsc2.
mat.Translate(atom_a.pixel_x, atom_a.pixel_y)
transform = mat
cl = C
cl.images += I
/obj/effect/buildmode_line/Destroy()
if(I)
if(istype(cl))
cl.images -= I
cl = null
QDEL_NULL(I)
return ..()
@@ -0,0 +1,59 @@
/datum/buildmode_mode/advanced
key = "advanced"
var/objholder = null
// FIXME: add logic which adds a button displaying the icon
// of the currently selected path
/datum/buildmode_mode/advanced/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Set object type</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + alt on turf/obj = Copy object type")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj = Place objects</span>")
to_chat(user, "<span class='notice'>Right Mouse Button = Delete objects</span>")
to_chat(user, "")
to_chat(user, "<span class='notice'>Use the button in the upper left corner to</span>")
to_chat(user, "<span class='notice'>change the direction of built objects.</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/advanced/change_settings(mob/user)
var/target_path = input(user,"Enter typepath:" ,"Typepath","/obj/structure/closet")
objholder = text2path(target_path)
if(!ispath(objholder))
objholder = pick_closest_path(target_path)
if(!objholder)
alert("No path was selected")
return
else if(ispath(objholder, /area))
objholder = null
alert("That path is not allowed.")
return
/datum/buildmode_mode/advanced/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
var/alt_click = pa.Find("alt")
if(left_click && alt_click)
if (isturf(object) || isobj(object) || ismob(object))
objholder = object.type
to_chat(user, "<span class='notice'>[initial(object.name)] ([object.type]) selected.</span>")
else
to_chat(user, "<span class='notice'>[initial(object.name)] is not a turf, object, or mob! Please select again.</span>")
else if(left_click)
if(ispath(objholder,/turf))
var/turf/T = get_turf(object)
log_admin("Build Mode: [key_name(user)] modified [T] ([T.x],[T.y],[T.z]) to [objholder]")
T.ChangeTurf(objholder)
else if(!isnull(objholder))
var/obj/A = new objholder (get_turf(object))
A.setDir(BM.build_dir)
log_admin("Build Mode: [key_name(user)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [BM.build_dir]")
else
to_chat(user, "<span class='warning'>Select object type first.</span>")
else if(right_click)
if(isobj(object))
log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])")
qdel(object)
@@ -0,0 +1,59 @@
/datum/buildmode_mode/area_edit
key = "areaedit"
var/area/storedarea
var/image/areaimage
/datum/buildmode_mode/area_edit/New()
areaimage = image('icons/turf/areas.dmi', null, "yellow")
..()
/datum/buildmode_mode/area_edit/enter_mode(datum/click_intercept/buildmode/BM)
BM.holder.images += areaimage
/datum/buildmode_mode/area_edit/exit_mode(datum/click_intercept/buildmode/BM)
areaimage.loc = null // de-color the area
BM.holder.images -= areaimage
return ..()
/datum/buildmode_mode/area_edit/Destroy()
QDEL_NULL(areaimage)
return ..()
/datum/buildmode_mode/area_edit/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on obj/turf/mob = Paint area</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on obj/turf/mob = Select area to paint</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Create new area</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/area_edit/change_settings(mob/user)
var/target_path = input(user,"Enter typepath:", "Typepath", "/area")
var/areatype = text2path(target_path)
if(ispath(areatype,/area))
var/areaname = input(user,"Enter area name:", "Area name", "Area")
if(!areaname || !length(areaname))
return
storedarea = new areatype
storedarea.power_equip = 0
storedarea.power_light = 0
storedarea.power_environ = 0
storedarea.always_unpowered = 0
storedarea.name = areaname
areaimage.loc = storedarea // color our area
/datum/buildmode_mode/area_edit/handle_click(user, params, object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
if(left_click)
if(!storedarea)
to_chat(user, "<span class='warning'>Configure or select the area you want to paint first!</span>")
return
var/turf/T = get_turf(object)
if(get_area(T) != storedarea)
storedarea.contents.Add(T)
else if(right_click)
var/turf/T = get_turf(object)
storedarea = get_area(T)
areaimage.loc = storedarea // color our area
+72
View File
@@ -0,0 +1,72 @@
/datum/buildmode_mode/atmos
key = "atmos"
use_corner_selection = TRUE
var/pressure = ONE_ATMOSPHERE
var/temperature = T20C
var/oxygen = O2STANDARD
var/nitrogen = N2STANDARD
var/plasma = 0
var/cdiox = 0
var/nitrox = 0
/datum/buildmode_mode/atmos/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf = Select corner</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + Ctrl on turf = Set 'base atmos conditions' for unsimulated turfs in region</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Adjust target atmos</span>")
to_chat(user, "<span class='notice'><b>Notice:</b> Starts out with standard breathable/liveable defaults</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
// FIXME this is a little tedious, something where you don't have to fill in each field would be cooler
// maybe some kind of stat panel thing?
/datum/buildmode_mode/atmos/change_settings(mob/user)
pressure = input(user, "Atmospheric Pressure", "Input", ONE_ATMOSPHERE) as num|null
temperature = input(user, "Temperature", "Input", T20C) as num|null
oxygen = input(user, "Oxygen ratio", "Input", O2STANDARD) as num|null
nitrogen = input(user, "Nitrogen ratio", "Input", N2STANDARD) as num|null
plasma = input(user, "Plasma ratio", "Input", 0) as num|null
cdiox = input(user, "CO2 ratio", "Input", 0) as num|null
nitrox = input(user, "N2O ratio", "Input", 0) as num|null
/datum/buildmode_mode/atmos/proc/ppratio_to_moles(ppratio)
// ideal gas equation: Pressure * Volume = Moles * r * Temperature
// air datum fields are in moles, we have partial pressure ratios
// Moles = (Pressure * Volume) / (r * Temperature)
return ((ppratio * pressure) * CELL_VOLUME) / (temperature * R_IDEAL_GAS_EQUATION)
/datum/buildmode_mode/atmos/handle_selected_region(mob/user, params)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/ctrl_click = pa.Find("ctrl")
if(left_click) //rectangular
for(var/turf/T in block(cornerA,cornerB))
if(istype(T, /turf/simulated))
// fill the turf with the appropriate gasses
// this feels slightly icky
var/turf/simulated/S = T
if(S.air)
S.air.temperature = temperature
S.air.oxygen = ppratio_to_moles(oxygen)
S.air.nitrogen = ppratio_to_moles(nitrogen)
S.air.toxins = ppratio_to_moles(plasma)
S.air.carbon_dioxide = ppratio_to_moles(cdiox)
S.air.trace_gases.Cut()
if(nitrox)
var/datum/gas/TG = new /datum/gas/sleeping_agent
TG.moles = ppratio_to_moles(nitrox)
S.air.trace_gases += TG
S.update_visuals()
S.air_update_turf()
else if(ctrl_click) // overwrite "default" unsimulated air
T.temperature = temperature
T.oxygen = ppratio_to_moles(oxygen)
T.nitrogen = ppratio_to_moles(nitrogen)
T.toxins = ppratio_to_moles(plasma)
T.carbon_dioxide = ppratio_to_moles(cdiox)
// no interface for trace gases on unsim turfs
T.air_update_turf()
// admin log
log_admin("Build Mode: [key_name(user)] changed the atmos of region [COORD(cornerA)] to [COORD(cornerB)]. T: [temperature], P: [pressure], Ox: [oxygen]%, N2: [nitrogen]%, Plsma: [plasma]%, CO2: [cdiox]%, N2O: [nitrox]%. [ctrl_click ? "Overwrote base unsimulated turf gases." : ""]")
+50
View File
@@ -0,0 +1,50 @@
/datum/buildmode_mode/basic
key = "basic"
/datum/buildmode_mode/basic/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button = Construct / Upgrade</span>")
to_chat(user, "<span class='notice'>Right Mouse Button = Deconstruct / Delete / Downgrade</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + ctrl = R-Window</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + alt = Airlock</span>")
to_chat(user, "")
to_chat(user, "<span class='notice'>Use the button in the upper left corner to</span>")
to_chat(user, "<span class='notice'>change the direction of built objects.</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/basic/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
var/ctrl_click = pa.Find("ctrl")
var/alt_click = pa.Find("alt")
if(istype(object,/turf) && left_click && !alt_click && !ctrl_click)
var/turf/T = object
if(istype(object,/turf/space))
T.ChangeTurf(/turf/simulated/floor/plasteel)
else if(istype(object,/turf/simulated/floor))
T.ChangeTurf(/turf/simulated/wall)
else if(istype(object,/turf/simulated/wall))
T.ChangeTurf(/turf/simulated/wall/r_wall)
log_admin("Build Mode: [key_name(user)] built [T] at ([T.x],[T.y],[T.z])")
else if(right_click)
log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])")
if(istype(object,/turf/simulated/wall))
var/turf/T = object
T.ChangeTurf(/turf/simulated/floor/plasteel)
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
T.ChangeTurf(/turf/space)
else if(istype(object,/turf/simulated/wall/r_wall))
var/turf/T = object
T.ChangeTurf(/turf/simulated/wall)
else if(istype(object,/obj))
qdel(object)
else if(istype(object,/turf) && alt_click && left_click)
log_admin("Build Mode: [key_name(user)] built an airlock at ([object.x],[object.y],[object.z])")
new/obj/machinery/door/airlock(get_turf(object))
else if(istype(object,/turf) && ctrl_click && left_click)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.setDir(BM.build_dir)
log_admin("Build Mode: [key_name(user)] built a window at ([object.x],[object.y],[object.z])")
+32
View File
@@ -0,0 +1,32 @@
/datum/buildmode_mode/boom
key = "boom"
var/devastation = -1
var/heavy = -1
var/light = -1
var/flash = -1
var/flames = -1
/datum/buildmode_mode/boom/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Mouse Button on obj = Kaboom</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/boom/change_settings(mob/user)
devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null
if(devastation == null) devastation = -1
heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null
if(heavy == null) heavy = -1
light = input("Range of light impact. -1 to none", text("Input")) as num|null
if(light == null) light = -1
flash = input("Range of flash. -1 to none", text("Input")) as num|null
if(flash == null) flash = -1
flames = input("Range of flames. -1 to none", text("Input")) as num|null
if(flames == null) flames = -1
/datum/buildmode_mode/boom/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
if(left_click)
explosion(object, devastation, heavy, light, flash, null, TRUE, flames)
+27
View File
@@ -0,0 +1,27 @@
/datum/buildmode_mode/copy
key = "copy"
var/atom/movable/stored = null
/datum/buildmode_mode/copy/exit_mode()
stored = null
return ..()
/datum/buildmode_mode/copy/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on obj/turf/mob = Spawn a Copy of selected target</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on obj/mob = Select target to copy</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/copy/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
if(left_click)
var/turf/T = get_turf(object)
if(stored)
DuplicateObject(stored, perfectcopy=1, sameloc=0,newloc=T)
else if(right_click)
if(ismovableatom(object)) // No copying turfs for now.
to_chat(user, "<span class='notice'>[object] set as template.</span>")
stored = object
+49
View File
@@ -0,0 +1,49 @@
/datum/buildmode_mode/fill
key = "fill"
use_corner_selection = TRUE
var/objholder = null
/datum/buildmode_mode/fill/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
to_chat(user, "<span class='notice'>Left Mouse Button + Alt on turf/obj/mob = Delete region</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select object type</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/fill/change_settings(mob/user)
var/target_path = input(user,"Enter typepath:" ,"Typepath","/obj/structure/closet")
objholder = text2path(target_path)
if(!ispath(objholder))
objholder = pick_closest_path(target_path)
if(!objholder)
alert("No path has been selected.")
return
else if(ispath(objholder, /area))
objholder = null
alert("Area paths are not supported for this mode, use the area edit mode instead.")
return
deselect_region()
/datum/buildmode_mode/fill/handle_click(mob/user, params, obj/object)
if(isnull(objholder))
to_chat(user, "<span class='warning'>Select an object type first.</span>")
deselect_region()
return
..()
/datum/buildmode_mode/fill/handle_selected_region(mob/user, params)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/alt_click = pa.Find("alt")
if(left_click) //rectangular
if(alt_click)
empty_region(block(cornerA,cornerB))
else
for(var/turf/T in block(cornerA,cornerB))
if(ispath(objholder,/turf))
T.ChangeTurf(objholder)
else
var/obj/A = new objholder(T)
A.setDir(BM.build_dir)
+94
View File
@@ -0,0 +1,94 @@
/datum/buildmode_mode/link
key = "link"
var/list/link_lines = list()
var/obj/link_obj
/datum/buildmode_mode/link/proc/clear_lines()
QDEL_LIST(link_lines)
/datum/buildmode_mode/link/proc/form_connection(atom/source, atom/dest, valid)
var/obj/effect/buildmode_line/L = new(BM.holder, source, dest, "[source.name] to [dest.name]")
L.color = valid ? "#339933" : "#993333"
link_lines += L
var/obj/effect/buildmode_line/L2 = new(BM.holder, dest, source, "[dest.name] to [source.name]") // Yes, reversed one so that you can see it source both sides.
L2.color = L.color
link_lines += L2
/datum/buildmode_mode/link/Destroy()
clear_lines()
link_obj = null
return ..()
/datum/buildmode_mode/link/Reset()
clear_lines()
link_obj = null
..()
/datum/buildmode_mode/link/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on obj = Select button to link</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on obj = Link/unlink to selected button")
to_chat(user, "<span class='notice'>***********************************************************</span>")
// FIXME: this probably would work better with something component-based
/datum/buildmode_mode/link/handle_click(mob/user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
if(left_click && istype(object, /obj/machinery))
link_obj = object
if(right_click && istype(object, /obj/machinery))
if(istype(link_obj, /obj/machinery/door_control) && istype(object, /obj/machinery/door/airlock))
var/obj/machinery/door_control/M = link_obj
var/obj/machinery/door/airlock/P = object
if(!M.id || M.id == "")
M.id = input(user, "Please select an ID for the button", "Buildmode", "")
if(!M.id || M.id == "")
goto(line_jump)
if(P.id_tag == M.id && (P in range(M.range, M)) && P.id_tag && P.id_tag != "")
P.id_tag = null
to_chat(user, "[P] unlinked.")
goto(line_jump)
if(!M.normaldoorcontrol)
if(link_lines.len && alert(user, "Warning: This will disable links to connected pod doors. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
M.normaldoorcontrol = 1
if(P.id_tag && alert(user, "Warning: This will unlink something else from the door. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
P.id_tag = M.id
if(istype(link_obj, /obj/machinery/door_control) && istype(object, /obj/machinery/door/poddoor))
var/obj/machinery/door_control/M = link_obj
var/obj/machinery/door/poddoor/P = object
if(!M.id || M.id == "")
M.id = input(user, "Please select an ID for the button", "Buildmode", "")
if(!M.id || M.id == "")
goto(line_jump)
if(P.id_tag == M.id && P.id_tag && P.id_tag != "")
P.id_tag = null
to_chat(user, "[P] unlinked.")
goto(line_jump)
if(M.normaldoorcontrol)
if(link_lines.len && alert(user, "Warning: This will disable links to connected airlocks. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
M.normaldoorcontrol = 0
if(!M.id || M.id == "")
M.id = input(user, "Please select an ID for the button", "Buildmode", "")
if(!M.id || M.id == "")
goto(line_jump)
if(P.id_tag && P.id_tag != 1 && alert(user, "Warning: This will unlink something else from the door. Continue?", "Buildmode", "Yes", "No") == "No")
goto(line_jump)
P.id_tag = M.id
line_jump // For the goto
clear_lines()
if(istype(link_obj, /obj/machinery/door_control))
var/obj/machinery/door_control/M = link_obj
for(var/obj/machinery/door/airlock/P in range(M.range,M))
if(P.id_tag == M.id)
form_connection(M, P, M.normaldoorcontrol)
for(var/obj/machinery/door/poddoor/P in airlocks)
if(P.id_tag == M.id)
form_connection(M, P, !M.normaldoorcontrol)
+40
View File
@@ -0,0 +1,40 @@
/datum/buildmode_mode/mapgen
key = "mapgen"
use_corner_selection = TRUE
var/generator_path
/datum/buildmode_mode/mapgen/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select generator</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/mapgen/change_settings(mob/user)
var/list/gen_paths = subtypesof(/datum/mapGenerator)
var/type = input(user,"Select Generator Type","Type") as null|anything in gen_paths
if(!type) return
generator_path = type
deselect_region()
/datum/buildmode_mode/mapgen/handle_click(mob/user, params, obj/object)
if(isnull(generator_path))
to_chat(user, "<span class='warning'>Select generator type first.</span>")
deselect_region()
return
..()
/datum/buildmode_mode/mapgen/handle_selected_region(mob/user, params)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
if(left_click) //rectangular
if(cornerA && cornerB)
var/datum/mapGenerator/G = new generator_path
G.defineRegion(cornerA, cornerB, 1)
highlight_region(G.map)
var/confirm = alert("Are you sure you want run the map generator?", "Run generator", "Yes", "No")
if(confirm == "Yes")
G.generate()
+28
View File
@@ -0,0 +1,28 @@
/datum/buildmode_mode/save
key = "save"
use_corner_selection = TRUE
var/use_json = TRUE
/datum/buildmode_mode/save/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/save/change_settings(mob/user)
use_json = (alert("Would you like to use json (Default is \"Yes\")?",,"Yes","No") == "Yes")
/datum/buildmode_mode/save/handle_selected_region(mob/user, params)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
if(left_click)
var/map_name = input(user, "Please select a name for your map", "Buildmode", "")
if(map_name == "")
return
var/map_flags = 0
if(use_json)
map_flags = 32 // Magic number defined in `writer.dm` that I can't use directly
// because #defines are for some reason our coding standard
var/our_map = maploader.save_map(cornerA, cornerB, map_name, map_flags)
user << ftp(our_map) // send the map they've made! Or are stealing, whatever
to_chat(user, "Map saving complete! [our_map]")
+12
View File
@@ -0,0 +1,12 @@
// SKELETON CODE, not yet functional
/datum/buildmode_mode/sdql
key = "sdql"
var/sdql_command = "SELECT /turf IN"
/datum/buildmode_mode/sdql/show_help(mob/user)
/datum/buildmode_mode/sdql/change_settings(mob/user)
/datum/buildmode_mode/sdql/handle_click(mob/user, params, obj/object)
@@ -0,0 +1,25 @@
/datum/buildmode_mode/throwing
key = "throw"
var/atom/movable/throw_atom = null
/datum/buildmode_mode/throwing/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on turf/obj/mob = Throw</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
/datum/buildmode_mode/throwing/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
if(left_click)
if(isturf(object))
return
throw_atom = object
to_chat(user, "Selected object '[throw_atom]'")
if(right_click)
if(throw_atom)
throw_atom.throw_at(object, 10, 1, user)
log_admin("Build Mode: [key_name(user)] threw [throw_atom] at [object] ([object.x],[object.y],[object.z])")
@@ -0,0 +1,55 @@
/datum/buildmode_mode/varedit
key = "edit"
// Varedit mode
var/varholder = "name"
var/valueholder = "value"
/datum/buildmode_mode/varedit/show_help(mob/user)
to_chat(user, "<span class='notice'>***********************************************************</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select var(type) & value</span>")
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Set var(type) & value</span>")
to_chat(user, "<span class='notice'>Right Mouse Button on turf/obj/mob = Reset var's value</span>")
to_chat(user, "<span class='notice'>***********************************************************</span>")
// FIXME: This needs to use a standard var-editing interface instead of
// doing its own thing here
/datum/buildmode_mode/varedit/change_settings(mob/user)
var/temp_varname = input(user,"Enter variable name:", "Name", "name")
if(!vv_varname_lockcheck(temp_varname))
return
var/temp_value = user.client.vv_get_value()
if(isnull(temp_value["class"]))
Reset()
to_chat(user, "<span class='notice'>Variable unset.</span>")
return
// we assign this once all user input is done, since things could get wonky otherwise
varholder = temp_varname
valueholder = temp_value["value"]
/datum/buildmode_mode/varedit/handle_click(user, params, obj/object)
var/list/pa = params2list(params)
var/left_click = pa.Find("left")
var/right_click = pa.Find("right")
if(isnull(varholder))
to_chat(user, "<span class='warning'>Choose a variable to modify first.</span>")
return
if(left_click)
if(object.vars.Find(varholder))
if(!object.vv_edit_var(varholder, valueholder))
to_chat(user, "<span class='warning'>Your edit was rejected by [object].</span>")
return
log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]")
else
to_chat(user, "<span class='warning'>[initial(object.name)] does not have a var called '[varholder]'</span>")
if(right_click)
if(object.vars.Find(varholder))
var/reset_value = initial(object.vars[varholder])
if(!object.vv_edit_var(varholder, reset_value))
to_chat(user, "<span class='warning'>Your edit was rejected by [object].</span>")
return
log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [reset_value]")
else
to_chat(user, "<span class='warning'>[initial(object.name)] does not have a var called '[varholder]'</span>")
+3 -9
View File
@@ -385,18 +385,12 @@ BLIND // can't see anything
/obj/item/clothing/shoes/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/match) && src.loc == user)
var/obj/item/match/M = I
if(!M.lit) // Match isn't lit, but isn't burnt.
M.lit = 1
M.icon_state = "match_lit"
processing_objects.Add(M)
M.update_icon()
if(M.matchignite()) // Match isn't lit, but isn't burnt.
user.visible_message("<span class='warning'>[user] strikes a [M] on the bottom of [src], lighting it.</span>","<span class='warning'>You strike the [M] on the bottom of [src] to light it.</span>")
playsound(user.loc, 'sound/goonstation/misc/matchstick_light.ogg', 50, 1)
else if(M.lit == 1) // Match is lit, not extinguished.
M.dropped()
else
user.visible_message("<span class='warning'>[user] crushes the [M] into the bottom of [src], extinguishing it.</span>","<span class='warning'>You crush the [M] into the bottom of [src], extinguishing it.</span>")
else // Match has been previously lit and extinguished.
to_chat(user, "<span class='notice'>The [M] has already been extinguished.</span>")
M.dropped()
return
if(istype(I, /obj/item/wirecutters))
+6
View File
@@ -238,6 +238,12 @@ obj/item/clothing/head/blob
desc = "An in-atmosphere helmet worn by security members of the Nanotrasen Emergency Response Team. Has red highlights."
icon_state = "erthelmet_sec"
/obj/item/clothing/head/helmet/ert/security/paranormal
name = "paranormal emergency response team helmet"
desc = "An in-atmosphere helmet worn by paranormal members of the Nanotrasen Emergency Response Team. Has crusader sigils."
icon_state = "knight_templar"
item_state = "knight_templar"
//Engineer
/obj/item/clothing/head/helmet/ert/engineer
name = "emergency response team engineer helmet"
+12
View File
@@ -24,6 +24,12 @@
/obj/item/clothing/mask/breath/attack_self(var/mob/user)
adjustmask(user)
/obj/item/clothing/mask/breath/AltClick(mob/user)
..()
if( (!in_range(src, user)) || user.stat || user.restrained() )
return
adjustmask(user)
/obj/item/clothing/mask/breath/medical
desc = "A close-fitting sterile mask that can be connected to an air supply."
name = "medical mask"
@@ -41,3 +47,9 @@
permeability_coefficient = 0.01
species_restricted = list("Vox")
actions_types = list()
/obj/item/clothing/mask/breath/vox/attack_self(var/mob/user)
return
/obj/item/clothing/mask/breath/vox/AltClick(mob/user)
return
@@ -183,7 +183,7 @@
anchored = 1
invisibility = 101
opacity = 0
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/mob/holder = null
/obj/effect/chronos_cam/relaymove(var/mob/user, direction)
+67 -1
View File
@@ -40,7 +40,7 @@
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/t_scanner, /obj/item/rcd, /obj/item/crowbar, \
/obj/item/screwdriver, /obj/item/weldingtool, /obj/item/wirecutters, /obj/item/wrench, /obj/item/multitool, \
/obj/item/radio, /obj/item/analyzer, /obj/item/gun/energy/laser, /obj/item/gun/energy/pulse, \
/obj/item/gun/energy/gun/advtaser, /obj/item/melee/baton, /obj/item/gun/energy/gun, /obj/item/gun/projectile/automatic/lasercarbine, /obj/item/gun/energy/gun/blueshield)
/obj/item/gun/energy/gun/advtaser, /obj/item/melee/baton, /obj/item/gun/energy/gun, /obj/item/gun/projectile/automatic/lasercarbine, /obj/item/gun/energy/gun/blueshield, /obj/item/gun/energy/immolator/multi)
strip_delay = 130
species_fit = list("Drask", "Vox")
sprite_sheets = list(
@@ -56,12 +56,25 @@
item_state = "helm-command"
item_color = "ert_commander"
/obj/item/clothing/head/helmet/space/hardsuit/ert/commander/gamma
name = "elite emergency response team commander helmet"
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
icon_state = "hardsuit0-gammacommander"
item_color = "gammacommander"
species_fit = null
/obj/item/clothing/suit/space/hardsuit/ert/commander
name = "emergency response team commander suit"
desc = "A suit worn by the commander of a Nanotrasen Emergency Response Team. Has blue highlights. Armoured, space ready, and fire resistant."
icon_state = "ert_commander"
item_state = "suit-command"
/obj/item/clothing/suit/space/hardsuit/ert/commander/gamma
name = "elite emergency response team commander suit"
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
icon_state = "ert_gcommander"
species_fit = null
//Security
/obj/item/clothing/head/helmet/space/hardsuit/ert/security
name = "emergency response team security helmet"
@@ -70,12 +83,25 @@
item_state = "syndicate-helm-black-red"
item_color = "ert_security"
/obj/item/clothing/head/helmet/space/hardsuit/ert/security/gamma
name = "elite emergency response team security helmet"
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
icon_state = "hardsuit0-gammasecurity"
item_color = "gammasecurity"
species_fit = null
/obj/item/clothing/suit/space/hardsuit/ert/security
name = "emergency response team security suit"
desc = "A suit worn by security members of a Nanotrasen Emergency Response Team. Has red highlights. Armoured, space ready, and fire resistant."
icon_state = "ert_security"
item_state = "syndicate-black-red"
/obj/item/clothing/suit/space/hardsuit/ert/security/gamma
name = "elite emergency response team security suit"
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
icon_state = "ert_gsecurity"
species_fit = null
//Engineer
/obj/item/clothing/head/helmet/space/hardsuit/ert/engineer
name = "emergency response team engineer helmet"
@@ -84,12 +110,26 @@
item_state = "helm-orange"
item_color = "ert_engineer"
//Engineer
/obj/item/clothing/head/helmet/space/hardsuit/ert/engineer/gamma
name = "elite emergency response team engineer helmet"
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
icon_state = "hardsuit0-gammaengineer"
item_color = "gammaengineer"
species_fit = null
/obj/item/clothing/suit/space/hardsuit/ert/engineer
name = "emergency response team engineer suit"
desc = "A suit worn by the engineers of a Nanotrasen Emergency Response Team. Has yellow highlights. Armoured, space ready, and fire resistant."
icon_state = "ert_engineer"
item_state = "suit-orange"
/obj/item/clothing/suit/space/hardsuit/ert/engineer/gamma
name = "elite emergency response team engineer suit"
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
icon_state = "ert_gengineer"
species_fit = null
//Medical
/obj/item/clothing/head/helmet/space/hardsuit/ert/medical
name = "emergency response team medical helmet"
@@ -97,11 +137,24 @@
icon_state = "hardsuit0-ert_medical"
item_color = "ert_medical"
/obj/item/clothing/head/helmet/space/hardsuit/ert/medical/gamma
name = "elite emergency response team medical helmet"
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
icon_state = "hardsuit0-gammamedical"
item_color = "gammamedical"
species_fit = null
/obj/item/clothing/suit/space/hardsuit/ert/medical
name = "emergency response team medical suit"
desc = "A suit worn by medical members of a Nanotrasen Emergency Response Team. Has white highlights. Armoured and space ready."
icon_state = "ert_medical"
/obj/item/clothing/suit/space/hardsuit/ert/medical/gamma
name = "elite emergency response team medical suit"
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
icon_state = "ert_gmedical"
species_fit = null
//Janitor
/obj/item/clothing/head/helmet/space/hardsuit/ert/janitor
name = "emergency response team janitor helmet"
@@ -109,11 +162,24 @@
icon_state = "hardsuit0-ert_janitor"
item_color = "ert_janitor"
/obj/item/clothing/head/helmet/space/hardsuit/ert/janitor/gamma
name = "elite emergency response team janitor helmet"
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
icon_state = "hardsuit0-gammajanitor"
item_color = "gammajanitor"
species_fit = null
/obj/item/clothing/suit/space/hardsuit/ert/janitor
name = "emergency response team janitor suit"
desc = "A suit worn by the janitorial of a Nanotrasen Emergency Response Team. Has purple highlights. Armoured, space ready, and fire resistant."
icon_state = "ert_janitor"
/obj/item/clothing/suit/space/hardsuit/ert/janitor/gamma
name = "elite emergency response team janitor suit"
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
icon_state = "ert_gjanitor"
species_fit = null
//Paranormal
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal
name = "paranormal response unit helmet"
+8 -1
View File
@@ -295,7 +295,7 @@
return 0
if(prob(hit_reaction_chance))
var/mob/living/carbon/human/H = owner
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!</span>")
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text]!</span>")
var/list/turfs = new/list()
for(var/turf/T in orange(tele_range, H))
if(istype(T, /turf/space))
@@ -440,6 +440,13 @@
name = "emergency response team security armor"
desc = "A set of armor worn by security members of the Nanotrasen Emergency Response Team. Has red highlights."
icon_state = "ertarmor_sec"
/obj/item/clothing/suit/armor/vest/ert/security/paranormal
name = "emergency response team paranormal armor"
desc = "A set of armor worn by paranormal members of the Nanotrasen Emergency Response Team. Has crusader sigils."
icon_state = "knight_templar"
item_state = "knight_templar"
//Engineer
/obj/item/clothing/suit/armor/vest/ert/engineer
+22
View File
@@ -135,6 +135,27 @@
/obj/item/claymore/fluff/hit_reaction()
return 0
/obj/item/fluff/rsik_katana //Xydonus: Rsik Ugsharki
name = "ceremonial katana"
desc = "A shimmering ceremonial golden katana, for the most discerning class of ninja. Looks expensive, and fragile."
icon = 'icons/obj/custom_items.dmi'
icon_state = "rsik_katana"
item_state = "rsik_katana"
lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi'
righthand_file = 'icons/mob/inhands/fluff_righthand.dmi'
force = 5
sharp = 0
flags = CONDUCT
slot_flags = SLOT_BELT
throwforce = 5
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("attacked", "slashed", "stabbed", "sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
/obj/item/fluff/rsik_katana/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] tries to stab [src] into [user.p_their()] stomach! Except [src] shatters! [user.p_they(TRUE)] look[user.p_s()] as if [user.p_they()] might die from the shame.</span>")
return(BRUTELOSS)
/obj/item/crowbar/fluff/zelda_creedy_1 // Zomgponies: Griffin Rowley
name = "Zelda's Crowbar"
desc = "A pink crow bar that has an engraving that reads, 'To Zelda. Love always, Dawn'"
@@ -1495,3 +1516,4 @@
item_state = "Xann_necklace"
item_color = "Xann_necklace"
slot_flags = SLOT_TIE
+1 -1
View File
@@ -59,7 +59,7 @@
blueeffect.icon = 'icons/effects/effects.dmi'
blueeffect.icon_state = "shieldsparkles"
blueeffect.layer = 17
blueeffect.mouse_opacity = 0
blueeffect.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
M.client.screen += blueeffect
sleep(20)
M.client.screen -= blueeffect
+3 -3
View File
@@ -13,12 +13,12 @@
if(!(L in player_list) && !L.mind && (L.sentience_type == sentience_type))
potential += L
if(!candidates.len || !potential.len) //if there are no players or simple animals to choose from, then end
return FALSE
var/mob/living/simple_animal/SA = pick(potential)
var/mob/SG = pick(candidates)
if(!SA || !SG) //if you can't find either a simple animal or a player, end
return FALSE
var/sentience_report = "<font size=3><b>[command_name()] Medium-Priority Update</b></font>"
var/data = pick("scans from our long-range sensors", "our sophisticated probabilistic models", "our omnipotence", "the communications traffic on your station", "energy emissions we detected", "\[REDACTED\]", "Steve")
+1 -1
View File
@@ -411,7 +411,7 @@
anchored = TRUE
density = FALSE
layer = SPACEVINE_LAYER
mouse_opacity = 2 //Clicking anywhere on the turf is good enough
mouse_opacity = MOUSE_OPACITY_OPAQUE //Clicking anywhere on the turf is good enough
pass_flags = PASSTABLE | PASSGRILLE
max_integrity = 50
var/energy = 0
+1 -1
View File
@@ -65,7 +65,7 @@ var/global/list/unused_trade_stations = list("sol")
/datum/event/traders/proc/greet_trader(var/mob/living/carbon/human/M)
to_chat(M, "<span class='boldnotice'>You are a trader!</span>")
to_chat(M, "<span class='notice'>You are currently docked at [get_area(M)].</span>")
to_chat(M, "<span class='notice'>You are about to trade with NSS Cyberiad.</span>")
to_chat(M, "<span class='notice'>You are about to trade with [station_name()].</span>")
to_chat(M, "<span class='notice'>Negotiate an agreement, and request docking.</span>")
spawn(25)
show_objectives(M.mind)
+1 -1
View File
@@ -17,5 +17,5 @@
return
/hook/startup/proc/ircNotify()
send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]")
send2mainirc("Server starting up on [station_name()]. Connect to: [config.server? "[config.server]" : "[world.address]:[world.port]"]")
return 1
+3 -3
View File
@@ -301,7 +301,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
if(bubblegum.Adjacent(target) && !charged)
charged = TRUE
target.Weaken(4)
target.staminaloss += 40
target.adjustStaminaLoss(40)
step_away(target, bubblegum)
shake_camera(target, 4, 3)
target.visible_message("<span class='warning'>[target] jumps backwards, falling on the ground!</span>","<span class='userdanger'>[bubblegum] slams into you!</span>")
@@ -637,7 +637,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
if(weapon_name)
my_target.playsound_local(my_target, weap.hitsound, 1)
my_target.show_message("<span class='danger'>[src.name] has attacked [my_target] with [weapon_name]!</span>", 1)
my_target.staminaloss += 30
my_target.adjustStaminaLoss(30)
if(prob(20))
my_target.AdjustEyeBlurry(3)
if(prob(33))
@@ -646,7 +646,7 @@ Gunshots/explosions/opening doors/less rare audio (done)
else
my_target.playsound_local(my_target, pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg'), 25, 1, -1)
my_target.show_message("<span class='userdanger'>[src.name] has punched [my_target]!</span>", 1)
my_target.staminaloss += 30
my_target.adjustStaminaLoss(30)
if(prob(33))
if(!locate(/obj/effect/overlay) in my_target.loc)
fake_blood(my_target)
@@ -73,7 +73,7 @@
bitesize = 4
var/top = 1 //Do we have a top?
var/obj/item/toptype
var/add_overlays = 1 //Do we stack?
var/snack_overlays = 1 //Do we stack?
// var/offsetstuff = 1 //Do we offset the overlays?
var/sandwich_limit = 40
var/fullycustom = 0
@@ -87,7 +87,7 @@
icon_state = "personal_pizza"
baseicon = "personal_pizza"
basename = "personal pizza"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/pasta
@@ -96,7 +96,7 @@
icon_state = "pasta_bot"
baseicon = "pasta_bot"
basename = "pasta"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/cook/bread
@@ -105,7 +105,7 @@
icon_state = "breadcustom"
baseicon = "breadcustom"
basename = "bread"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/cook/pie
@@ -114,7 +114,7 @@
icon_state = "piecustom"
baseicon = "piecustom"
basename = "pie"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/cook/cake
@@ -123,7 +123,7 @@
icon_state = "cakecustom"
baseicon = "cakecustom"
basename = "cake"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/cook/jelly
@@ -132,7 +132,7 @@
icon_state = "jellycustom"
baseicon = "jellycustom"
basename = "jelly"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/cook/donkpocket
@@ -141,7 +141,7 @@
icon_state = "donkcustom"
baseicon = "donkcustom"
basename = "donk pocket"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/cook/kebab
@@ -150,7 +150,7 @@
icon_state = "kababcustom"
baseicon = "kababcustom"
basename = "kebab"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/cook/salad
@@ -159,7 +159,7 @@
icon_state = "saladcustom"
baseicon = "saladcustom"
basename = "salad"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/cook/waffles
@@ -168,7 +168,7 @@
icon_state = "wafflecustom"
baseicon = "wafflecustom"
basename = "waffles"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/cookie
@@ -177,7 +177,7 @@
icon_state = "cookiecustom"
baseicon = "cookiecustom"
basename = "cookie"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/cotton
@@ -186,7 +186,7 @@
icon_state = "cottoncandycustom"
baseicon = "cottoncandycustom"
basename = "flavored cotton candy"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/gummybear
@@ -195,7 +195,7 @@
icon_state = "gummybearcustom"
baseicon = "gummybearcustom"
basename = "flavored giant gummy bear"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/gummyworm
@@ -204,7 +204,7 @@
icon_state = "gummywormcustom"
baseicon = "gummywormcustom"
basename = "flavored giant gummy worm"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/jellybean
@@ -213,7 +213,7 @@
icon_state = "jellybeancustom"
baseicon = "jellybeancustom"
basename = "flavored giant jelly bean"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/jawbreaker
@@ -222,7 +222,7 @@
icon_state = "jawbreakercustom"
baseicon = "jawbreakercustom"
basename = "flavored jawbreaker"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/candycane
@@ -231,7 +231,7 @@
icon_state = "candycanecustom"
baseicon = "candycanecustom"
basename = "flavored candy cane"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/gum
@@ -240,7 +240,7 @@
icon_state = "gumcustom"
baseicon = "gumcustom"
basename = "flavored gum"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/donut
@@ -249,7 +249,7 @@
icon_state = "donutcustom"
baseicon = "donutcustom"
basename = "filled donut"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/bar
@@ -258,7 +258,7 @@
icon_state = "barcustom"
baseicon = "barcustom"
basename = "flavored chocolate bar"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/sucker
@@ -267,7 +267,7 @@
icon_state = "suckercustom"
baseicon = "suckercustom"
basename = "flavored sucker"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/cash
@@ -276,7 +276,7 @@
icon_state = "cashcustom"
baseicon = "cashcustom"
basename = "flavored cash"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/coin
@@ -285,7 +285,7 @@
icon_state = "coincustom"
baseicon = "coincustom"
basename = "flavored coin"
add_overlays = 0
snack_overlays = 0
top = 0
/obj/item/reagent_containers/food/snacks/customizable/fullycustom // In the event you fuckers find something I forgot to add a customizable food for.
@@ -294,7 +294,7 @@
icon_state = "fullycustom"
baseicon = "fullycustom"
basename = "on a plate"
add_overlays = 0
snack_overlays = 0
top = 0
sandwich_limit = 20
fullycustom = 1
@@ -305,7 +305,7 @@
icon_state = "soup"
baseicon = "soup"
basename = "soup"
add_overlays = 0
snack_overlays = 0
trash = /obj/item/trash/bowl
top = 0
@@ -355,7 +355,7 @@
I.color = pick("#FF0000","#0000FF","#008000","#FFFF00")
else
I.color = pick("#FF0000","#0000FF","#008000","#FFFF00")
if(add_overlays)
if(snack_overlays)
I.pixel_x = pick(list(-1,0,1))
I.pixel_y = (i*2)+1
overlays += I
+58 -68
View File
@@ -45,15 +45,15 @@
to_chat(user, "<span class='warning'>None of [src] left, oh no!</span>")
M.unEquip(src) //so icons update :[
qdel(src)
return 0
return FALSE
if(iscarbon(M))
var/mob/living/carbon/C = M
if(C.eat(src, user))
bitecount++
On_Consume(C, user)
return 1
return 0
return TRUE
return FALSE
/obj/item/reagent_containers/food/snacks/afterattack(obj/target, mob/user, proximity)
return
@@ -115,70 +115,7 @@
TrashItem = trash
TrashItem.forceMove(loc)
qdel(src)
return 1
if((slices_num <= 0 || !slices_num) || !slice_path)
return 0
var/inaccurate = 0
if( \
istype(W, /obj/item/kitchen/knife) || \
istype(W, /obj/item/scalpel) \
)
else if( \
istype(W, /obj/item/circular_saw) || \
istype(W, /obj/item/melee/energy/sword/saber) && W:active || \
istype(W, /obj/item/melee/energy/blade) || \
istype(W, /obj/item/shovel) || \
istype(W, /obj/item/hatchet) \
)
inaccurate = 1
else if(W.w_class <= WEIGHT_CLASS_SMALL && istype(src,/obj/item/reagent_containers/food/snacks/sliceable))
var/newweight = GetTotalContentsWeight() + W.GetTotalContentsWeight() + W.w_class
if(newweight > MAX_WEIGHT_CLASS)
// Nope, no bluespace slice food
to_chat(user, "<span class='warning'>You cannot fit [W] in [src]!</span>")
return 1
if(!iscarbon(user))
return 1
to_chat(user, "<span class='warning'>You slip [W] inside [src].</span>")
user.unEquip(W)
if((user.client && user.s_active != src))
user.client.screen -= W
W.dropped(user)
total_w_class += W.w_class
add_fingerprint(user)
contents += W
return
else
return 1
if( \
!isturf(loc) || \
!(locate(/obj/structure/table) in loc) && \
!(locate(/obj/machinery/optable) in loc) && \
!(locate(/obj/item/storage/bag/tray) in loc) \
)
to_chat(user, "<span class='warning'>You cannot slice [src] here! You need a table or at least a tray to do it.</span>")
return 1
var/slices_lost = 0
if(!inaccurate)
user.visible_message( \
"<span class='notice'>[user] slices [src]!</span>", \
"<span class='notice'>You slice [src]!</span>" \
)
else
user.visible_message( \
"<span class='notice'>[user] crudely slices [src] with [W]!</span>", \
"<span class='notice'>You crudely slice [src] with your [W]</span>!" \
)
slices_lost = rand(1,min(1,round(slices_num/2)))
var/reagents_per_slice = reagents.total_volume/slices_num
for(var/i=1 to (slices_num-slices_lost))
var/obj/slice = new slice_path (loc)
reagents.trans_to(slice,reagents_per_slice)
qdel(src)
return
return TRUE
/obj/item/reagent_containers/food/snacks/proc/generate_trash(atom/location)
if(trash)
@@ -228,7 +165,60 @@
N.adjustBruteLoss(-1)
N.adjustFireLoss(-1)
/obj/item/reagent_containers/food/snacks/sliceable/examine(mob/user)
. = ..()
to_chat(user, "<span class='notice'>Alt-click to put something small inside.</span>")
/obj/item/reagent_containers/food/snacks/sliceable/AltClick(mob/user)
var/obj/item/I = user.get_active_hand()
if(!I)
return
if(I.w_class > WEIGHT_CLASS_SMALL)
to_chat(user, "<span class='warning'>You cannot fit [I] in [src]!</span>")
return
var/newweight = GetTotalContentsWeight() + I.GetTotalContentsWeight() + I.w_class
if(newweight > MAX_WEIGHT_CLASS)
// Nope, no bluespace slice food
to_chat(user, "<span class='warning'>You cannot fit [I] in [src]!</span>")
return
if(!iscarbon(user))
return
if(!user.drop_item())
to_chat(user, "<span class='warning'>You cannot slip [I] inside [src]!</span>")
return
to_chat(user, "<span class='warning'>You slip [I] inside [src].</span>")
total_w_class += I.w_class
add_fingerprint(user)
I.forceMove(src)
/obj/item/reagent_containers/food/snacks/sliceable/attackby(obj/item/I, mob/user, params)
if((slices_num <= 0 || !slices_num) || !slice_path)
return FALSE
var/inaccurate = TRUE
if(I.sharp)
if(istype(I, /obj/item/kitchen/knife) || istype(I, /obj/item/scalpel))
inaccurate = FALSE
else
return TRUE
if(!isturf(loc) || !(locate(/obj/structure/table) in loc) && \
!(locate(/obj/machinery/optable) in loc) && !(locate(/obj/item/storage/bag/tray) in loc))
to_chat(user, "<span class='warning'>You cannot slice [src] here! You need a table or at least a tray to do it.</span>")
return TRUE
var/slices_lost = 0
if(!inaccurate)
user.visible_message("<span class='notice'>[user] slices [src]!</span>",
"<span class='notice'>You slice [src]!</span>")
else
user.visible_message("<span class='notice'>[user] crudely slices [src] with [I]!</span>",
"<span class='notice'>You crudely slice [src] with your [I]</span>!")
slices_lost = rand(1,min(1,round(slices_num/2)))
var/reagents_per_slice = reagents.total_volume/slices_num
for(var/i=1 to (slices_num-slices_lost))
var/obj/slice = new slice_path (loc)
reagents.trans_to(slice,reagents_per_slice)
qdel(src)
return ..()
////////////////////////////////////////////////////////////////////////////////
/// FOOD END
////////////////////////////////////////////////////////////////////////////////
@@ -301,4 +291,4 @@
list_reagents = list("nutriment" = 3)
#undef MAX_WEIGHT_CLASS
#undef MAX_WEIGHT_CLASS
+1 -1
View File
@@ -1,7 +1,7 @@
/var/total_lighting_overlays = 0
/atom/movable/lighting_overlay
name = ""
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
simulated = 0
anchored = 1
icon = LIGHTING_ICON
+2 -2
View File
@@ -722,7 +722,7 @@
icon = 'icons/effects/effects.dmi'
icon_state = "shield1"
layer = 4.1
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/resonance_damage = 20
/obj/effect/resonance/New(loc, var/creator = null, var/timetoburst)
@@ -975,7 +975,7 @@
layer = 18
icon = 'icons/turf/mining.dmi'
anchored = 1
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
duration = 30
pixel_x = -4
pixel_y = -4
+2 -3
View File
@@ -453,7 +453,6 @@ var/global/list/rockTurfEdgeCache = list(
/turf/simulated/floor/plating/airless/asteroid
name = "Asteroid"
icon = 'icons/turf/floors.dmi'
icon_state = "asteroid"
icon_plating = "asteroid"
var/dug = 0 //0 = has not yet been dug, 1 = has already been dug
@@ -463,10 +462,10 @@ var/global/list/rockTurfEdgeCache = list(
/turf/simulated/floor/plating/airless/asteroid/New()
var/proper_name = name
..()
name = proper_name
if(prob(20))
icon_state = "asteroid[rand(0,12)]"
..()
/turf/simulated/floor/plating/airless/asteroid/ex_act(severity, target)
switch(severity)
@@ -663,4 +662,4 @@ var/global/list/rockTurfEdgeCache = list(
#undef NORTH_EDGING
#undef SOUTH_EDGING
#undef EAST_EDGING
#undef WEST_EDGING
#undef WEST_EDGING
+6 -4
View File
@@ -9,7 +9,7 @@
icon_state = "mining_drone"
icon_living = "mining_drone"
status_flags = CANSTUN|CANWEAKEN|CANPUSH
mouse_opacity = 1
mouse_opacity = MOUSE_OPACITY_ICON
faction = list("neutral")
a_intent = INTENT_HARM
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)
@@ -92,12 +92,14 @@
..()
/mob/living/simple_animal/hostile/mining_drone/death()
..()
// Only execute the below if we successfully died
. = ..()
if(!.)
return FALSE
visible_message("<span class='danger'>[src] is destroyed!</span>")
new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc)
DropOre(0)
qdel(src)
return
/mob/living/simple_animal/hostile/mining_drone/attack_hand(mob/living/carbon/human/M)
if(M.a_intent == INTENT_HELP)
@@ -307,4 +309,4 @@
origin_tech = "programming=6"
#undef MINEDRONE_COLLECT
#undef MINEDRONE_ATTACK
#undef MINEDRONE_ATTACK
+1 -1
View File
@@ -5,7 +5,7 @@
density = 0
anchored = 1
status_flags = GODMODE // You can't damage it.
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
see_in_dark = 7
invisibility = 101 // No one can see us
sight = SEE_SELF
+1 -2
View File
@@ -12,7 +12,6 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
stat = DEAD
density = 0
canmove = 0
blinded = 0
anchored = 1 // don't get pushed around
invisibility = INVISIBILITY_OBSERVER
var/can_reenter_corpse
@@ -171,7 +170,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
response = alert(src, alertmsg,"Are you sure you want to ghost?","Stay in body","Ghost")
if(response != "Ghost")
return //didn't want to ghost after-all
resting = 1
StartResting()
var/mob/dead/observer/ghost = ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly.
var/obj/structure/morgue/Morgue = locate() in M.loc
+5 -87
View File
@@ -1,94 +1,12 @@
//This is the proc for gibbing a mob. Cannot gib ghosts.
//added different sort of gibs and animations. N
// can't die if you're not alive
/mob/proc/gib()
death(1)
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
icon = null
invisibility = 101
return FALSE
playsound(src.loc, 'sound/goonstation/effects/gib.ogg', 50, 1)
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
// flick("gibbed-m", animation)
gibs(loc, dna)
dead_mob_list -= src
if(client)
respawnable_list += src
spawn(15)
if(animation) qdel(animation)
if(src) qdel(src)
//This is the proc for turning a mob into ash. Mostly a copy of gib code (above).
//Originally created for wizard disintegrate. I've removed the virus code since it's irrelevant here.
//Dusting robots does not eject the MMI, so it's a bit more powerful than gib() /N
/mob/proc/dust()
death(1)
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
// flick("dust-m", animation)
new /obj/effect/decal/cleanable/ash(loc)
dead_mob_list -= src
if(client)
respawnable_list += src
spawn(15)
if(animation) qdel(animation)
if(src) qdel(src)
return FALSE
/mob/proc/melt()
death(1)
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
// flick("liquify", animation)
// new /obj/effect/decal/cleanable/ash(loc)
dead_mob_list -= src
if(client)
respawnable_list += src
spawn(15)
if(animation) qdel(animation)
if(src) qdel(src)
return FALSE
/mob/proc/death(gibbed)
//Makes it so gib/dust/melt all unbuckle their victims from anything they may be buckled to to avoid breaking beds/chairs/etc
if(gibbed && buckled)
buckled.unbuckle_mob()
//Quick fix for corpses kept propped up in chairs. ~Z
drop_r_hand()
drop_l_hand()
//End of fix.
timeofdeath = world.time
living_mob_list -= src
dead_mob_list += src
if(client)
respawnable_list += src
return ..(gibbed)
return FALSE
+2 -2
View File
@@ -28,7 +28,7 @@
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
if(language && (language.flags & NONVERBAL))
if(!has_vision()) //blind people can't see dumbass
if(!has_vision(information_only = TRUE)) //blind people can't see dumbass
message = stars(message)
if(!speaker || !(speaker in view(src)))
@@ -95,7 +95,7 @@
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
if(language && (language.flags & NONVERBAL))
if(!has_vision()) //blind people can't see dumbass
if(!has_vision(information_only=TRUE)) //blind people can't see dumbass
message = stars(message)
if(!speaker || !(speaker in view(src)))
@@ -19,6 +19,8 @@
var/leaping = 0
ventcrawler = 2
var/list/alien_organs = list()
var/death_message = "lets out a waning guttural screech, green blood bubbling from its maw..."
var/death_sound = 'sound/voice/hiss6.ogg'
/mob/living/carbon/alien/New()
verbs += /mob/living/verb/mob_sleep
@@ -49,25 +51,25 @@
/mob/living/carbon/alien/adjustToxLoss(amount)
return
return STATUS_UPDATE_NONE
/mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire
if(amount > 0)
..(amount * 2)
return ..(amount * 2)
else
..(amount)
return
return ..(amount)
/mob/living/carbon/alien/check_eye_prot()
return 2
/mob/living/carbon/alien/updatehealth()
/mob/living/carbon/alien/updatehealth(reason = "none given")
if(status_flags & GODMODE)
health = maxHealth
stat = CONSCIOUS
return
health = maxHealth - getOxyLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
update_stat("updatehealth([reason])")
/mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment)
@@ -256,4 +258,4 @@ Des: Removes all infected images from the alien.
if(getBruteLoss() < 200)
return pick("xltrails_1", "xltrails_2")
else
return pick("xttrails_1", "xttrails_2")
return pick("xttrails_1", "xttrails_2")
@@ -17,7 +17,7 @@ In all, this is a lot like the monkey code. /N
switch(M.a_intent)
if(INTENT_HELP)
AdjustSleeping(-5)
resting = 0
StopResting()
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)
@@ -36,7 +36,6 @@ In all, this is a lot like the monkey code. /N
"<span class='userdanger'>[M.name] bites [src]!</span>")
adjustBruteLoss(damage)
add_attack_logs(M, src, "Alien attack", ATKLOG_ALL)
updatehealth()
else
to_chat(M, "<span class='warning'>[name] is too injured for that.</span>")
@@ -75,4 +74,3 @@ In all, this is a lot like the monkey code. /N
adjustCloneLoss(damage)
if(STAMINA)
adjustStaminaLoss(damage)
updatehealth()
+9 -12
View File
@@ -43,18 +43,15 @@
if(src) qdel(src)
/mob/living/carbon/alien/death(gibbed)
if(stat == DEAD) return
if(healths) healths.icon_state = "health6"
stat = DEAD
// Only execute the below if we successfully died
. = ..(gibbed)
if(!.)
return FALSE
if(healths)
healths.icon_state = "health6"
if(!gibbed)
playsound(loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("<B>[src]</B> lets out a waning guttural screech, green blood bubbling from its maw...", 1)
update_canmove()
if(death_sound)
playsound(loc, death_sound, 80, 1, 1)
visible_message("<B>[src]</B> [death_message]")
update_icons()
timeofdeath = world.time
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
return ..(gibbed)
@@ -73,10 +73,7 @@
AdjustEarDamage(15)
AdjustEarDeaf(60)
adjustBruteLoss(b_loss)
adjustFireLoss(f_loss)
updatehealth()
take_overall_damage(b_loss, f_loss)
/mob/living/carbon/alien/humanoid/attack_slime(mob/living/carbon/slime/M)
..()
@@ -85,7 +82,6 @@
damage = rand(10, 40)
adjustBruteLoss(damage)
add_attack_logs(src, M, "Slime'd for [damage] damage")
updatehealth()
return
/mob/living/carbon/alien/humanoid/restrained()
@@ -30,7 +30,6 @@
"<span class='danger'>You hear someone fall.</span>")
adjustBruteLoss(damage)
add_attack_logs(M, src, "Melee attacked with fists")
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
@@ -56,4 +55,4 @@
/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
if(!no_effect && !visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_CLAW
..()
..()
@@ -44,12 +44,10 @@
updatehealth()
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
blinded = 1
SetSilence(0)
else //ALIVE. LIGHTS ARE ON
if(health < config.health_threshold_dead || !get_int_organ(/obj/item/organ/internal/brain))
death()
blinded = 1
SetSilence(0)
return 1
@@ -62,10 +60,8 @@
Paralyse(3)
if(paralysis)
blinded = 1
stat = UNCONSCIOUS
else if(sleeping)
blinded = 1
stat = UNCONSCIOUS
if(prob(10) && health)
emote("hiss")
@@ -77,12 +73,8 @@
if(move_delay_add > 0)
move_delay_add = max(0, move_delay_add - rand(1, 2))
//Eyes
if(disabilities & BLIND) //disabled-blind, doesn't get better on its own
blinded = 1
else if(eye_blind) //blindness, heals slowly over time
if(eye_blind) //blindness, heals slowly over time
AdjustEyeBlind(-1)
blinded = 1
else if(eye_blurry) //blurry eyes heal slowly
AdjustEyeBlurry(-1)
@@ -1,15 +0,0 @@
/mob/living/carbon/alien/larva/death(gibbed)
if(stat == DEAD) return
if(healths) healths.icon_state = "health6"
stat = DEAD
icon_state = "larva_dead"
if(!gibbed)
visible_message("<span class='name'>[src]</span> lets out a waning high-pitched cry.")
update_canmove()
timeofdeath = world.time
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
living_mob_list -= src
return ..(gibbed)
@@ -12,6 +12,8 @@
var/amount_grown = 0
var/max_grown = 200
var/time_of_birth
death_message = "lets out a waning high-pitched cry."
death_sound = null
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/larva/New()
@@ -11,12 +11,10 @@
updatehealth()
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
blinded = 1
SetSilence(0)
else //ALIVE. LIGHTS ARE ON
if(health < -25 || !get_int_organ(/obj/item/organ/internal/brain))
death()
blinded = 1
SetSilence(0)
return 1
@@ -30,10 +28,8 @@
Paralyse(3)
if(paralysis)
blinded = 1
stat = UNCONSCIOUS
else if(sleeping)
blinded = 1
stat = UNCONSCIOUS
if(prob(10) && health)
emote("hiss_")
@@ -45,12 +41,8 @@
if(move_delay_add > 0)
move_delay_add = max(0, move_delay_add - rand(1, 2))
//Eyes
if(disabilities & BLIND) //disabled-blind, doesn't get better on its own
blinded = 1
else if(eye_blind) //blindness, heals slowly over time
if(eye_blind) //blindness, heals slowly over time
AdjustEyeBlind(-1)
blinded = 1
else if(eye_blurry) //blurry eyes heal slowly
AdjustEyeBlurry(-1)
@@ -9,16 +9,10 @@
if(layer != TURF_LAYER+0.2)
layer = TURF_LAYER+0.2
to_chat(src, text("<span class='noticealien'>You are now hiding.</span>"))
for(var/mob/O in oviewers(src, null))
if((O.client && !( O.blinded )))
to_chat(O, text("<B>[] scurries to the ground!</B>", src))
visible_message("<B>[src] scurries to the ground!</B>", "<span class='noticealien'>You are now hiding.</span>")
else
layer = MOB_LAYER
to_chat(src, text("<span class=notice'>You have stopped hiding.</span>"))
for(var/mob/O in oviewers(src, null))
if((O.client && !( O.blinded )))
to_chat(O, text("[] slowly peaks up from the ground...", src))
visible_message("[src] slowly peeks up from the ground...", "<span class=notice'>You have stopped hiding.</span>")
/mob/living/carbon/alien/larva/verb/evolve()
set name = "Evolve"
+9 -25
View File
@@ -1,42 +1,26 @@
/mob/living/carbon/brain/death(gibbed)
if(stat == DEAD) return
// Only execute the below if we successfully died
. = ..()
if(!.)
return FALSE
if(!gibbed && container && istype(container, /obj/item/mmi))//If not gibbed but in a container.
for(var/mob/O in viewers(container, null))
O.show_message(text("<span class='danger'>[]'s MMI flatlines!</span>", src), 1, "<span class='warning'>You hear something flatline.</span>", 2)
visible_message("<span class='danger'>[src]'s MMI flatlines!</span>", "<span class='warning'>You hear something flatline.</span>")
container.icon_state = "mmi_dead"
stat = DEAD
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
timeofdeath = world.time
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0) //mind. ?
return ..(gibbed)
/mob/living/carbon/brain/gib()
death(1)
var/atom/movable/overlay/animation = null
// can we muster a parent call here?
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
// flick("gibbed-m", animation)
gibs(loc, dna)
dead_mob_list -= src
if(container && istype(container, /obj/item/mmi))
qdel(container)//Gets rid of the MMI if there is one
if(loc)
if(istype(loc,/obj/item/organ/internal/brain))
qdel(loc)//Gets rid of the brain item
spawn(15)
if(animation) qdel(animation)
if(src) qdel(src)
QDEL_IN(src, 0)
+3 -10
View File
@@ -29,19 +29,12 @@
adjustFireLoss(5.0*discomfort)
/mob/living/carbon/brain/handle_regular_status_updates()
updatehealth()
. = ..()
if(stat == DEAD)
blinded = 1
SetSilence(0)
else
if(.)
if(!container && (health < config.health_threshold_dead || ((world.time - timeofhostdeath) > config.revival_brain_life)))
death()
blinded = 1
SetSilence(0)
return 1
. = 1
return 0
/mob/living/carbon/brain/breathe()
return
@@ -1,8 +1,16 @@
/mob/living/carbon/brain/update_stat()
/mob/living/carbon/brain/update_stat(reason = "none given")
if(status_flags & GODMODE)
return
// if(health <= min_health)
if(health <= config.health_threshold_dead)
if(stat != DEAD)
if(stat == DEAD)
if(container && health > config.health_threshold_dead)
update_revive()
create_debug_log("revived, trigger reason: [reason]")
return
else
if(!container || health <= config.health_threshold_dead)
// Considered "dead" without any external apparatus
death()
create_debug_log("died, trigger reason: [reason]")
return
// Put brain(organ) damaging code here
+3 -3
View File
@@ -60,7 +60,7 @@
if(organ.receive_damage(d, 0))
H.UpdateDamageIcon()
H.updatehealth()
H.updatehealth("stomach attack")
else
src.take_organ_damage(d)
@@ -144,7 +144,7 @@
return 0
if(reagents.has_reagent("teslium"))
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
take_overall_damage(0,shock_damage, used_weapon = "Electrocution")
take_overall_damage(0,shock_damage, TRUE, used_weapon = "Electrocution")
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
@@ -269,7 +269,7 @@
H.w_uniform.add_fingerprint(M)
AdjustSleeping(-5)
if(sleeping == 0)
resting = 0
StopResting()
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)
@@ -55,9 +55,9 @@
var/stunprob = M.powerlevel * 7 + 10
if(prob(stunprob) && M.powerlevel >= 8)
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
updatehealth("slime attack")
return 1
/mob/living/carbon/is_mouth_covered(head_only = FALSE, mask_only = FALSE)
if((!mask_only && head && (head.flags_cover & HEADCOVERSMOUTH)) || (!head_only && wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH)))
return TRUE
return TRUE
+4 -5
View File
@@ -1,12 +1,11 @@
/mob/living/carbon/death(gibbed)
SetLoseBreath(0)
med_hud_set_health()
med_hud_set_status()
// Only execute the below if we successfully died
. = ..(gibbed)
if(!.)
return FALSE
if(reagents)
reagents.death_metabolize(src)
for(var/obj/item/organ/internal/I in internal_organs)
I.on_owner_death()
..(gibbed)
+27 -38
View File
@@ -1,5 +1,6 @@
/mob/living/carbon/human/gib()
death(1)
if(!death(TRUE) && stat != DEAD)
return FALSE
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
@@ -43,13 +44,13 @@
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
spawn(15)
if(animation) qdel(animation)
if(src) qdel(src)
QDEL_IN(animation, 15)
QDEL_IN(src, 0)
return TRUE
/mob/living/carbon/human/dust()
death(1)
if(!death(TRUE) && stat != DEAD)
return FALSE
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
@@ -63,13 +64,13 @@
flick("dust-h", animation)
new dna.species.remains_type(get_turf(src))
spawn(15)
if(animation) qdel(animation)
if(src) qdel(src)
QDEL_IN(src, 0)
QDEL_IN(animation, 15)
return TRUE
/mob/living/carbon/human/melt()
death(1)
if(!death(TRUE) && stat != DEAD)
return FALSE
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
@@ -82,60 +83,48 @@
animation.master = src
flick("liquify", animation)
QDEL_IN(src, 0)
QDEL_IN(animation, 15)
//new /obj/effect/decal/remains/human(loc)
spawn(15)
if(animation) qdel(animation)
if(src) qdel(src)
return TRUE
/mob/living/carbon/human/death(gibbed)
if(stat == DEAD)
return
if(healths)
healths.icon_state = "health5"
if(!gibbed)
if(can_die() && !gibbed)
emote("deathgasp") //let the world KNOW WE ARE DEAD
stat = DEAD
SetDizzy(0)
SetJitter(0)
// Only execute the below if we successfully died
. = ..(gibbed)
if(!.)
return FALSE
set_heartattack(FALSE)
//Handle species-specific deaths.
if(dna.species)
dna.species.handle_hud_icons(src)
//Handle species-specific deaths.
dna.species.handle_death(src)
callHook("death", list(src, gibbed))
if(ishuman(LAssailant))
var/mob/living/carbon/human/H=LAssailant
if(H.mind)
H.mind.kills += "[key_name(src)]"
if(!gibbed)
update_canmove()
timeofdeath = world.time
med_hud_set_health()
med_hud_set_status()
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
if(ticker && ticker.mode)
// log_world("k")
sql_report_death(src)
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
if(wearing_rig)
wearing_rig.notify_ai("<span class='danger'>Warning: user death event. Mobility control passed to integrated intelligence system.</span>")
return ..(gibbed)
/mob/living/carbon/human/update_revive()
. = ..()
// Update healthdoll
if(. && healthdoll)
// We're alive again, so re-build the entire healthdoll
healthdoll.cached_healthdoll_overlays.Cut()
// Update healthdoll
if(dna.species)
dna.species.update_sight(src)
dna.species.handle_hud_icons(src)
/mob/living/carbon/human/proc/makeSkeleton()
var/obj/item/organ/external/head/H = get_organ("head")
+67 -5
View File
@@ -294,7 +294,7 @@
if(prob(50) && !shielded)
Paralyse(10)
take_overall_damage(b_loss,f_loss, used_weapon = "Explosive Blast")
take_overall_damage(b_loss,f_loss, TRUE, used_weapon = "Explosive Blast")
..()
@@ -1272,7 +1272,7 @@
else
to_chat(usr, "<span class='notice'>[self ? "Your" : "[src]'s"] pulse is [src.get_pulse(GETPULSE_HAND)].</span>")
/mob/living/carbon/human/proc/set_species(datum/species/new_species, default_colour, delay_icon_update = FALSE, skip_same_check = FALSE)
/mob/living/carbon/human/proc/set_species(datum/species/new_species, default_colour, delay_icon_update = FALSE, skip_same_check = FALSE, retain_damage = FALSE)
if(!skip_same_check)
if(dna.species.name == initial(new_species.name))
return
@@ -1325,7 +1325,69 @@
if(I)
kept_items[I] = thing
dna.species.create_organs(src)
if(retain_damage)
//Create a list of body parts which are damaged by burn or brute and save them to apply after new organs are generated. First we just handle external organs.
var/bodypart_damages = list()
//Loop through all external organs and save the damage states for brute and burn
for(var/obj/item/organ/external/E in bodyparts)
if(E.brute_dam == 0 && E.burn_dam == 0 && E.internal_bleeding == FALSE) //If there's no damage we don't bother remembering it.
continue
var/brute = E.brute_dam
var/burn = E.burn_dam
var/IB = E.internal_bleeding
var/obj/item/organ/external/OE = new E.type()
var/stats = list(OE, brute, burn, IB)
bodypart_damages += list(stats)
//Now we do the same for internal organs via the same proceedure.
var/internal_damages = list()
for(var/obj/item/organ/internal/I in internal_organs)
if(I.damage == 0)
continue
var/obj/item/organ/internal/OI = new I.type()
var/damage = I.damage
var/broken = I.is_broken()
var/stats = list(OI, damage, broken)
internal_damages += list(stats)
//Create the new organs for the species change
dna.species.create_organs(src)
//Apply relevant damages and variables to the new organs.
for(var/B in bodyparts)
var/obj/item/organ/external/E = B
for(var/list/part in bodypart_damages)
var/obj/item/organ/external/OE = part[1]
if((E.type == OE.type)) // Type has to be explicit, as right limbs are a child of left ones etc.
var/brute = part[2]
var/burn = part[3]
var/IB = part[4]
//Deal the damage to the new organ and then delete the entry to prevent duplicate checks
E.receive_damage(brute, burn, ignore_resists = TRUE)
E.internal_bleeding = IB
qdel(part)
for(var/O in internal_organs)
var/obj/item/organ/internal/I = O
for(var/list/part in internal_damages)
var/obj/item/organ/internal/OI = part[1]
var/organ_type
if(OI.parent_type == /obj/item/organ/internal) //Dealing with species organs
organ_type = OI.type
else
organ_type = OI.parent_type
if(istype(I, organ_type))
var/damage = part[2]
var/broken = part[3]
I.receive_damage(damage, 1)
if(broken && !(I.status & ORGAN_BROKEN))
I.status |= ORGAN_BROKEN
qdel(part)
else
dna.species.create_organs(src)
for(var/thing in kept_items)
equip_to_slot_if_possible(thing, kept_items[thing], redraw_mob = 0)
@@ -1598,7 +1660,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
if(H.health > config.health_threshold_dead && H.health <= config.health_threshold_crit)
var/suff = min(H.getOxyLoss(), 7)
H.adjustOxyLoss(-suff)
H.updatehealth()
H.updatehealth("cpr")
visible_message("<span class='danger'>[src] performs CPR on [H.name]!</span>", \
"<span class='notice'>You perform CPR on [H.name].</span>")
@@ -1867,4 +1929,4 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
/mob/living/carbon/human/proc/special_post_clone_handling()
if(mind && mind.assigned_role == "Cluwne") //HUNKE your suffering never stops
makeCluwne()
makeCluwne()
@@ -1,5 +1,5 @@
//Updates the mob's health from organs and mob damage variables
/mob/living/carbon/human/updatehealth()
/mob/living/carbon/human/updatehealth(reason = "none given")
if(status_flags & GODMODE)
health = maxHealth
stat = CONSCIOUS
@@ -17,20 +17,14 @@
//TODO: fix husking
if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD)
ChangeToHusk()
if(dna.species.can_revive_by_healing)
var/obj/item/organ/internal/brain/B = get_int_organ(/obj/item/organ/internal/brain)
if(B)
if((health >= (config.health_threshold_dead + config.health_threshold_crit) * 0.5) && stat == DEAD && getBrainLoss()<120)
update_revive()
if(stat == CONSCIOUS && (src in dead_mob_list)) //Defib fix
update_revive()
update_stat("updatehealth([reason])")
med_hud_set_health()
med_hud_set_status()
handle_hud_icons()
handle_hud_icons_health()
/mob/living/carbon/human/adjustBrainLoss(amount)
/mob/living/carbon/human/adjustBrainLoss(amount, updating = TRUE)
if(status_flags & GODMODE)
return 0 //godmode
return STATUS_UPDATE_NONE //godmode
if(dna.species && dna.species.has_organ["brain"])
var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain)
@@ -38,15 +32,13 @@
if(dna.species)
amount = amount * dna.species.brain_mod
sponge.receive_damage(amount, 1)
brainloss = sponge.damage
else
brainloss = 200
else
brainloss = 0
if(updating)
update_stat("adjustBrainLoss")
return STATUS_UPDATE_STAT
/mob/living/carbon/human/setBrainLoss(amount)
/mob/living/carbon/human/setBrainLoss(amount, updating = TRUE)
if(status_flags & GODMODE)
return 0 //godmode
return STATUS_UPDATE_NONE //godmode
if(dna.species && dna.species.has_organ["brain"])
var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain)
@@ -54,11 +46,9 @@
if(dna.species)
amount = amount * dna.species.brain_mod
sponge.damage = min(max(amount, 0), (maxHealth*2))
brainloss = sponge.damage
else
brainloss = 200
else
brainloss = 0
if(updating)
update_stat("setBrainLoss")
return STATUS_UPDATE_STAT
/mob/living/carbon/human/getBrainLoss()
if(status_flags & GODMODE)
@@ -67,12 +57,11 @@
if(dna.species && dna.species.has_organ["brain"])
var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain)
if(sponge)
brainloss = min(sponge.damage,maxHealth*2)
return min(sponge.damage,maxHealth*2)
else
brainloss = 200
return 200
else
brainloss = 0
return brainloss
return 0
//These procs fetch a cumulative total damage from all organs
/mob/living/carbon/human/getBruteLoss()
@@ -88,23 +77,27 @@
return amount
/mob/living/carbon/human/adjustBruteLoss(amount, damage_source, robotic=0)
/mob/living/carbon/human/adjustBruteLoss(amount, updating_health = TRUE, damage_source = null, robotic = FALSE)
if(dna.species)
amount = amount * dna.species.brute_mod
if(amount > 0)
take_overall_damage(amount, 0, used_weapon = damage_source)
take_overall_damage(amount, 0, updating_health, used_weapon = damage_source)
else
heal_overall_damage(-amount, 0, 0, robotic)
heal_overall_damage(-amount, 0, updating_health, FALSE, robotic)
// brainless default for now
return STATUS_UPDATE_HEALTH
/mob/living/carbon/human/adjustFireLoss(amount, damage_source, robotic=0)
/mob/living/carbon/human/adjustFireLoss(amount, updating_health = TRUE, damage_source = null, robotic = FALSE)
if(dna.species)
amount = amount * dna.species.burn_mod
if(amount > 0)
take_overall_damage(0, amount, used_weapon = damage_source)
take_overall_damage(0, amount, updating_health, used_weapon = damage_source)
else
heal_overall_damage(0, -amount, 0, robotic)
heal_overall_damage(0, -amount, updating_health, FALSE, robotic)
// brainless default for now
return STATUS_UPDATE_HEALTH
/mob/living/carbon/human/proc/adjustBruteLossByPart(amount, organ_name, obj/damage_source = null)
/mob/living/carbon/human/proc/adjustBruteLossByPart(amount, organ_name, obj/damage_source = null, updating_health = TRUE)
if(dna.species)
amount = amount * dna.species.brute_mod
@@ -112,13 +105,14 @@
var/obj/item/organ/external/O = get_organ(organ_name)
if(amount > 0)
O.receive_damage(amount, 0, sharp=is_sharp(damage_source), used_weapon=damage_source)
O.receive_damage(amount, 0, sharp=is_sharp(damage_source), used_weapon=damage_source, list(), FALSE, updating_health)
else
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(-amount, 0, internal = 0, robo_repair = O.is_robotic())
O.heal_damage(-amount, 0, internal = 0, robo_repair = O.is_robotic(), updating_health = updating_health)
return STATUS_UPDATE_HEALTH
/mob/living/carbon/human/proc/adjustFireLossByPart(amount, organ_name, obj/damage_source = null)
/mob/living/carbon/human/proc/adjustFireLossByPart(amount, organ_name, obj/damage_source = null, updating_health = TRUE)
if(dna.species)
amount = amount * dna.species.burn_mod
@@ -126,22 +120,23 @@
var/obj/item/organ/external/O = get_organ(organ_name)
if(amount > 0)
O.receive_damage(0, amount, sharp=is_sharp(damage_source), used_weapon=damage_source)
O.receive_damage(0, amount, sharp=is_sharp(damage_source), used_weapon=damage_source, forbidden_limbs = list(), ignore_resists = FALSE, updating_health = updating_health)
else
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(0, -amount, internal = 0, robo_repair = O.is_robotic())
O.heal_damage(0, -amount, internal = 0, robo_repair = O.is_robotic(), updating_health = updating_health)
return STATUS_UPDATE_HEALTH
/mob/living/carbon/human/Paralyse(amount)
// Notify our AI if they can now control the suit.
if(wearing_rig && !stat && paralysis < amount) //We are passing out right this second.
wearing_rig.notify_ai("<span class='danger'>Warning: user consciousness failure. Mobility control passed to integrated intelligence system.</span>")
..()
return ..()
/mob/living/carbon/human/adjustCloneLoss(amount)
if(dna.species)
amount = amount * dna.species.clone_mod
..()
. = ..()
var/heal_prob = max(0, 80 - getCloneLoss())
var/mut_prob = min(80, getCloneLoss() + 10)
@@ -181,22 +176,22 @@
/mob/living/carbon/human/adjustOxyLoss(amount)
if(dna.species)
amount = amount * dna.species.oxy_mod
..()
. = ..()
/mob/living/carbon/human/setOxyLoss(amount)
if(dna.species)
amount = amount * dna.species.oxy_mod
..()
. = ..()
/mob/living/carbon/human/adjustToxLoss(amount)
if(dna.species)
amount = amount * dna.species.tox_mod
..()
. = ..()
/mob/living/carbon/human/setToxLoss(amount)
if(dna.species)
amount = amount * dna.species.tox_mod
..()
. = ..()
////////////////////////////////////////////
@@ -223,31 +218,29 @@
//Heals ONE external organ, organ gets randomly selected from damaged ones.
//It automatically updates damage overlays if necesary
//It automatically updates health status
/mob/living/carbon/human/heal_organ_damage(brute, burn)
/mob/living/carbon/human/heal_organ_damage(brute, burn, updating_health = TRUE)
var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn)
if(!parts.len)
return
var/obj/item/organ/external/picked = pick(parts)
if(picked.heal_damage(brute,burn))
if(picked.heal_damage(brute,burn, updating_health))
UpdateDamageIcon()
updatehealth()
//Damages ONE external organ, organ gets randomly selected from damagable ones.
//It automatically updates damage overlays if necesary
//It automatically updates health status
/mob/living/carbon/human/take_organ_damage(brute, burn, sharp = 0, edge = 0)
/mob/living/carbon/human/take_organ_damage(brute, burn, updating_health = TRUE, sharp = 0, edge = 0)
var/list/obj/item/organ/external/parts = get_damageable_organs()
if(!parts.len)
return
var/obj/item/organ/external/picked = pick(parts)
if(picked.receive_damage(brute, burn, sharp))
if(picked.receive_damage(brute, burn, sharp, updating_health))
UpdateDamageIcon()
updatehealth()
speech_problem_flag = 1
//Heal MANY external organs, in random order
/mob/living/carbon/human/heal_overall_damage(brute, burn, internal=0, robotic=0)
/mob/living/carbon/human/heal_overall_damage(brute, burn, updating_health = TRUE, internal=0, robotic=0)
var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn)
var/update = 0
@@ -257,20 +250,21 @@
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
update |= picked.heal_damage(brute,burn, internal, robotic)
update |= picked.heal_damage(brute,burn, internal, robotic, updating_health = FALSE)
brute -= (brute_was-picked.brute_dam)
burn -= (burn_was-picked.burn_dam)
parts -= picked
updatehealth()
if(updating_health)
updatehealth("heal overall damage")
speech_problem_flag = 1
if(update)
UpdateDamageIcon()
// damage MANY external organs, in random order
/mob/living/carbon/human/take_overall_damage(brute, burn, sharp = 0, edge = 0, used_weapon = null)
/mob/living/carbon/human/take_overall_damage(brute, burn, updating_health = TRUE, used_weapon = null, sharp = 0, edge = 0)
if(status_flags & GODMODE)
return //godmode
var/list/obj/item/organ/external/parts = get_damageable_organs()
@@ -285,14 +279,15 @@
var/burn_was = picked.burn_dam
update |= picked.receive_damage(brute_per_part, burn_per_part, sharp, used_weapon)
update |= picked.receive_damage(brute_per_part, burn_per_part, sharp, used_weapon, list(), FALSE, FALSE)
brute -= (picked.brute_dam - brute_was)
burn -= (picked.burn_dam - burn_was)
parts -= picked
updatehealth()
if(updating_health)
updatehealth("take overall damage")
if(update)
UpdateDamageIcon()
@@ -364,7 +359,7 @@ This function restores all organs.
var/list/attack_bubble_recipients = list()
var/mob/living/user
for(var/mob/O in viewers(user, src))
if(O.client && !(O.blinded))
if(O.client && O.has_vision(information_only=TRUE))
attack_bubble_recipients.Add(O.client)
spawn(0)
var/image/dmgIcon = image('icons/effects/hit_blips.dmi', src, "dmg[rand(1,2)]",MOB_LAYER+1)
@@ -383,5 +378,5 @@ This function restores all organs.
UpdateDamageIcon()
// Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life().
updatehealth()
updatehealth("apply damage")
return 1
@@ -375,7 +375,7 @@ emp_act
var/obj/item/organ/external/affecting = get_organ(ran_zone(L.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
updatehealth()
updatehealth("larva attack")
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
if(check_shields(0, M.name))
@@ -404,7 +404,7 @@ emp_act
"<span class='userdanger'>[M] has wounded [src]!</span>")
apply_effect(4, WEAKEN, armor_block)
add_attack_logs(M, src, "Alien attacked")
updatehealth()
updatehealth("alien attack")
if(M.a_intent == INTENT_DISARM)
if(prob(80))
@@ -434,7 +434,7 @@ emp_act
if(affected)
affected.add_autopsy_data(M.name, damage) // Add the mob's name to the autopsy data
apply_damage(damage, M.melee_damage_type, affecting, armor)
updatehealth()
updatehealth("animal attack")
/mob/living/carbon/human/attack_slime(mob/living/carbon/slime/M)
..()
@@ -473,7 +473,7 @@ emp_act
M.mech_toxin_damage(src)
else
return
updatehealth()
updatehealth("mech melee attack")
M.occupant_message("<span class='danger'>You hit [src].</span>")
visible_message("<span class='danger'>[src] has been hit by [M.name].</span>", \
@@ -502,4 +502,4 @@ emp_act
if(check_head && head && (head.flags_cover & HEADCOVERSEYES))
return TRUE
if(check_mask && wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH))
return TRUE
return TRUE
@@ -38,7 +38,7 @@
// Buckled to a bed/chair. Stance damage is forced to 0 since they're sitting on something solid
// Not standing, so no need to care about stance
if(istype(buckled, /obj/structure/stool/bed) || !isturf(loc))
if(istype(buckled, /obj/structure/chair) || !isturf(loc))
return
for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot"))
@@ -67,14 +67,13 @@
//modules
var/list/functions = list("nearbyscan","combat","shitcurity","chatter")
var/restrictedJob = 0
var/shouldUseDynamicProc = 0 // switch to make the AI control it's own proccessing
var/alternateProcessing = 0
var/forceProcess = 0
var/processTime = 10
var/speak_file = "npc_chatter.json"
var/debugexamine = FALSE //If we show debug info in our examine
var/showexaminetext = TRUE //If we show our telltale examine text
var/voice_saved = FALSE
var/list/knownStrings = list()
//snpc traitor variables
@@ -95,6 +94,8 @@
knownStrings = list()
/mob/living/carbon/human/interactive/proc/saveVoice()
if(voice_saved)
return
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
S["knownStrings"] << knownStrings
@@ -142,7 +143,7 @@
doing = 0
inactivity_period = 0
/client/proc/resetSNPC(mob/living/carbon/human/interactive/T in npc_master.botPool_l)
/client/proc/resetSNPC(mob/living/carbon/human/interactive/T in SSnpcpool.processing)
set name = "Reset SNPC"
set desc = "Reset the SNPC"
set category = "Debug"
@@ -153,20 +154,7 @@
if(istype(T))
T.reset()
/client/proc/toggleSNPC(mob/living/carbon/human/interactive/T in npc_master.botPool_l)
set name = "Toggle SNPC Proccessing Mode"
set desc = "Toggle SNPC Proccessing Mode"
set category = "Debug"
if(!holder)
return
if(istype(T))
T.alternateProcessing = !T.alternateProcessing
T.forceProcess = 1
to_chat(usr, "[T]'s processing has been switched to [T.alternateProcessing ? "High Profile" : "Low Profile"]")
/client/proc/customiseSNPC(mob/living/carbon/human/interactive/T in npc_master.botPool_l)
/client/proc/customiseSNPC(mob/living/carbon/human/interactive/T in SSnpcpool.processing)
set name = "Customize SNPC"
set desc = "Customize the SNPC"
set category = "Debug"
@@ -191,8 +179,12 @@
T.myjob = cjob
T.job = cjob.title
T.mind.assigned_role = cjob.title
for(var/obj/item/W in T)
qdel(W)
for(var/obj/item/I in T)
if(istype(I, /obj/item/implant))
continue
if(istype(I, /obj/item/organ))
continue
qdel(I)
T.myjob.equip(T)
T.doSetup(alt_title)
@@ -316,6 +308,12 @@
if(TRAITS & TRAIT_THIEVING)
slyness = 75
/mob/living/carbon/human/interactive/proc/InteractiveProcess()
if(ticker.current_state == GAME_STATE_FINISHED)
saveVoice()
voice_saved = TRUE
doProcess()
/mob/living/carbon/human/interactive/proc/setup_job(thejob)
switch(thejob)
if("Civilian")
@@ -419,7 +417,7 @@
sync_mind()
random()
doSetup()
npc_master.insertBot(src)
START_PROCESSING(SSnpcpool, src)
loadVoice()
hear_radio_list += src
@@ -432,9 +430,7 @@
doProcess()
/mob/living/carbon/human/interactive/Destroy()
hear_radio_list -= src
snpc_list -= src
npc_master.removeBot(src)
SSnpcpool.stop_processing(src)
return ..()
/mob/living/carbon/human/interactive/proc/retalTarget(mob/living/target)
@@ -578,8 +574,11 @@
return get_dist(get_turf(towhere), get_turf(src))
/mob/living/carbon/human/interactive/death()
// Only execute the below if we successfully died
. = ..()
if(!.)
return FALSE
saveVoice()
..()
/mob/living/carbon/human/interactive/hear_say(message, verb = "says", datum/language/language = null, italics = 0, mob/speaker = null, sound/speech_sound, sound_vol)
if(!istype(speaker, /mob/living/carbon/human/interactive))
@@ -592,17 +591,7 @@
..()
/mob/living/carbon/human/interactive/proc/doProcess()
forceProcess = 0
if(shouldUseDynamicProc)
var/isSeen = 0
for(var/mob/living/carbon/human/A in orange(12, src))
if(A.client)
isSeen = 1
alternateProcessing = isSeen
if(alternateProcessing)
forceProcess = 1
set waitfor = FALSE
if(IsDeadOrIncap())
reset()
return
@@ -630,10 +619,13 @@
if(istype(D,/obj/machinery/door/airlock))
var/obj/machinery/door/airlock/AL = D
if(!AL.CanAStarPass(RPID)) // only crack open doors we can't get through
inactivity_period = 20
AL.panel_open = 1
AL.update_icon()
AL.shock(src, mistake_chance)
sleep(5)
if(QDELETED(AL))
return
AL.unlock()
if(prob(mistake_chance))
if(!AL.wires.IsIndexCut(AIRLOCK_WIRE_DOOR_BOLTS))
@@ -650,6 +642,8 @@
if(prob(mistake_chance) && !AL.wires.IsIndexCut(AIRLOCK_WIRE_ELECTRIFY))
AL.wires.CutWireIndex(AIRLOCK_WIRE_ELECTRIFY)
sleep(5)
if(QDELETED(AL))
return
AL.panel_open = 0
AL.update_icon()
D.open()
@@ -683,7 +677,7 @@
//proc functions
for(var/Proc in functions)
if(!IsDeadOrIncap())
callfunction(Proc)
INVOKE_ASYNC(src, Proc)
//target interaction stays hardcoded
@@ -697,8 +691,8 @@
if(istype(TARGET, /obj/machinery/door))
var/obj/machinery/door/D = TARGET
if(D.check_access(MYID) && !istype(D,/obj/machinery/door/poddoor))
inactivity_period = 10
D.open()
sleep(15)
var/turf/T = get_step(get_step(D.loc, dir), dir) //recursion yo
tryWalk(T)
//THIEVING SKILLS
@@ -722,15 +716,8 @@
insert_into_backpack()
//---------FASHION
if(istype(TARGET, /obj/item/clothing))
var/obj/item/clothing/C = TARGET
drop_item()
spawn(5)
take_to_slot(C,1)
if(!equip_to_appropriate_slot(C))
var/obj/item/I = get_item_by_slot(C)
unEquip(I)
spawn(5)
equip_to_appropriate_slot(C)
dressup(TARGET)
update_hands = 1
if(MYPDA in loc)
equip_to_appropriate_slot(MYPDA)
@@ -787,9 +774,19 @@
TARGET = traitorTarget
tryWalk(TARGET)
LAST_TARGET = TARGET
if(alternateProcessing)
spawn(processTime)
doProcess()
/mob/living/carbon/human/interactive/proc/dressup(obj/item/clothing/C)
set waitfor = FALSE
inactivity_period = 12
sleep(5)
if(!QDELETED(C) && !QDELETED(src))
take_to_slot(C,1)
if(!equip_to_appropriate_slot(C))
var/obj/item/I = get_item_by_slot(C)
unEquip(I)
sleep(5)
if(!QDELETED(src) && !QDELETED(C))
equip_to_appropriate_slot(C)
/mob/living/carbon/human/interactive/proc/favouredObjIn(list/inList)
var/list/outList = list()
@@ -801,10 +798,6 @@
outList = inList
return outList
/mob/living/carbon/human/interactive/proc/callfunction(Proc)
spawn(0)
call(src, Proc)(src)
/mob/living/carbon/human/interactive/proc/tryWalk(turf/inTarget)
if(restrictedJob) // we're a job that has to stay in our home
if(!(get_turf(inTarget) in get_area_turfs(job2area(myjob))))
@@ -114,7 +114,7 @@
if(G.tint)
update_tint()
if(G.prescription)
clear_fullscreen("nearsighted")
update_nearsighted_effects()
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view)
update_sight()
update_inv_glasses()
@@ -266,8 +266,7 @@
if(G.tint)
update_tint()
if(G.prescription)
if(disabilities & NEARSIGHTED)
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
update_nearsighted_effects()
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view)
update_sight()
update_inv_glasses(redraw_mob)
+15 -24
View File
@@ -144,12 +144,12 @@
if(3)
emote("drool")
if(getBrainLoss() >= 100 && stat != 2) //you lapse into a coma and die without immediate aid; RIP. -Fox
if(getBrainLoss() >= 100 && stat != DEAD) //you lapse into a coma and die without immediate aid; RIP. -Fox
Weaken(20)
AdjustLoseBreath(10)
AdjustSilence(2)
if(getBrainLoss() >= 120 && stat != 2) //they died from stupidity--literally. -Fox
if(getBrainLoss() >= 120 && stat != DEAD) //they died from stupidity--literally. -Fox
visible_message("<span class='alert'><B>[src]</B> goes limp, [p_their()] facial expression utterly blank.</span>")
death()
@@ -339,16 +339,16 @@
if(bodytemperature >= dna.species.heat_level_1 && bodytemperature <= dna.species.heat_level_2)
throw_alert("temp", /obj/screen/alert/hot, 1)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_1, updating_health = TRUE, used_weapon = "High Body Temperature")
if(bodytemperature > dna.species.heat_level_2 && bodytemperature <= dna.species.heat_level_3)
throw_alert("temp", /obj/screen/alert/hot, 2)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, updating_health = TRUE, used_weapon = "High Body Temperature")
if(bodytemperature > dna.species.heat_level_3 && bodytemperature < INFINITY)
throw_alert("temp", /obj/screen/alert/hot, 3)
if(on_fire)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire")
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_3, updating_health = TRUE, used_weapon = "Fire")
else
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, updating_health = TRUE, used_weapon = "High Body Temperature")
else if(bodytemperature < dna.species.cold_level_1)
if(status_flags & GODMODE)
@@ -360,13 +360,13 @@
var/mult = dna.species.coldmod
if(bodytemperature >= dna.species.cold_level_2 && bodytemperature <= dna.species.cold_level_1)
throw_alert("temp", /obj/screen/alert/cold, 1)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_1, used_weapon = "Low Body Temperature")
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_1, updating_health = TRUE, used_weapon = "Low Body Temperature")
if(bodytemperature >= dna.species.cold_level_3 && bodytemperature < dna.species.cold_level_2)
throw_alert("temp", /obj/screen/alert/cold, 2)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_2, used_weapon = "Low Body Temperature")
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_2, updating_health = TRUE, used_weapon = "Low Body Temperature")
if(bodytemperature > -INFINITY && bodytemperature < dna.species.cold_level_3)
throw_alert("temp", /obj/screen/alert/cold, 3)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_3, used_weapon = "Low Body Temperature")
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_3, updating_health = TRUE, used_weapon = "Low Body Temperature")
else
clear_alert("temp")
else
@@ -382,7 +382,7 @@
if(adjusted_pressure >= dna.species.hazard_high_pressure)
if(!(HEATRES in mutations))
var/pressure_damage = min( ( (adjusted_pressure / dna.species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)
take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure")
take_overall_damage(brute=pressure_damage, updating_health = TRUE, used_weapon = "High Pressure")
throw_alert("pressure", /obj/screen/alert/highpressure, 2)
else
clear_alert("pressure")
@@ -396,7 +396,7 @@
if(COLDRES in mutations)
clear_alert("pressure")
else
take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure")
take_overall_damage(brute=LOW_PRESSURE_DAMAGE, updating_health = TRUE, used_weapon = "Low Pressure")
throw_alert("pressure", /obj/screen/alert/lowpressure, 2)
@@ -657,8 +657,6 @@
handle_trace_chems()
updatehealth()
return //TODO: DEFERRED
/mob/living/carbon/human/handle_drunk()
@@ -744,13 +742,11 @@
heal_overall_damage(0.1, 0.1)
if(paralysis)
blinded = 1
stat = UNCONSCIOUS
else if(sleeping)
speech_problem_flag = 1
blinded = 1
stat = UNCONSCIOUS
if(mind)
@@ -761,7 +757,6 @@
adjustToxLoss(-1)
else if(status_flags & FAKEDEATH)
blinded = 1
stat = UNCONSCIOUS
//Vision //god knows why this is here
@@ -771,26 +766,21 @@
if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means.
SetEyeBlind(0)
blinded = 0
SetEyeBlurry(0)
else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind.
EyeBlind(2)
blinded = 1
EyeBlurry(2)
else
//blindness
if(disabilities & BLIND) // Disabled-blind, doesn't get better on its own
blinded = 1
else if(eye_blind) // Blindness, heals slowly over time
AdjustEyeBlind(-1)
blinded = 1
else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster
AdjustEyeBlurry(-3)
blinded = 1
//blurry sight
if(vision.is_bruised()) // Vision organs impaired? Permablurry.
@@ -826,7 +816,6 @@
else //dead
blinded = 1
SetSilence(0)
@@ -860,11 +849,13 @@
remoteview_target = null
reset_perspective(null)
dna.species.handle_vision(src)
/mob/living/carbon/human/handle_hud_icons()
dna.species.handle_hud_icons(src)
/mob/living/carbon/human/handle_hud_icons_health()
dna.species.handle_hud_icons_health(src)
handle_hud_icons_health_overlay()
/mob/living/carbon/human/handle_random_events()
// Puke if toxloss is too high
if(!stat)
@@ -504,43 +504,23 @@
/datum/species/proc/handle_can_equip(obj/item/I, slot, disable_warning = 0, mob/living/carbon/human/user)
return FALSE
/datum/species/proc/handle_vision(mob/living/carbon/human/H)
// Right now this just handles blind, blurry, and similar states
if(H.blinded || H.eye_blind)
H.overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
H.throw_alert("blind", /obj/screen/alert/blind)
else
H.clear_fullscreen("blind")
H.clear_alert("blind")
if(H.disabilities & NEARSIGHTED) //this looks meh but saves a lot of memory by not requiring to add var/prescription
if(H.glasses) //to every /obj/item
var/obj/item/clothing/glasses/G = H.glasses
if(G.prescription)
H.clear_fullscreen("nearsighted")
else
H.overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
else
H.overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
else
H.clear_fullscreen("nearsighted")
if(H.eye_blurry)
H.overlay_fullscreen("blurry", /obj/screen/fullscreen/blurry)
else
H.clear_fullscreen("blurry")
if(H.druggy)
H.overlay_fullscreen("high", /obj/screen/fullscreen/high)
H.throw_alert("high", /obj/screen/alert/high)
else
H.clear_fullscreen("high")
H.clear_alert("high")
/datum/species/proc/get_perceived_trauma(mob/living/carbon/human/H)
return 100 - ((NO_PAIN in species_traits) ? 0 : H.traumatic_shock) - H.getStaminaLoss()
/datum/species/proc/handle_hud_icons(mob/living/carbon/human/H)
if(!H.client)
return
handle_hud_icons_health(H)
H.handle_hud_icons_health_overlay()
handle_hud_icons_nutrition(H)
/datum/species/proc/handle_hud_icons_health(mob/living/carbon/H)
if(!H.client)
return
handle_hud_icons_health_side(H)
handle_hud_icons_health_doll(H)
/datum/species/proc/handle_hud_icons_health_side(mob/living/carbon/human/H)
if(H.healths)
if(H.stat == DEAD)
H.healths.icon_state = "health7"
@@ -550,7 +530,7 @@
if(SCREWYHUD_DEAD) H.healths.icon_state = "health7"
if(SCREWYHUD_HEALTHY) H.healths.icon_state = "health0"
else
switch(100 - ((NO_PAIN in species_traits) ? 0 : H.traumatic_shock) - H.staminaloss)
switch(get_perceived_trauma(H))
if(100 to INFINITY) H.healths.icon_state = "health0"
if(80 to 100) H.healths.icon_state = "health1"
if(60 to 80) H.healths.icon_state = "health2"
@@ -559,6 +539,7 @@
if(0 to 20) H.healths.icon_state = "health5"
else H.healths.icon_state = "health6"
/datum/species/proc/handle_hud_icons_health_doll(mob/living/carbon/human/H)
if(H.healthdoll)
if(H.stat == DEAD)
H.healthdoll.icon_state = "healthdoll_DEAD"
@@ -588,6 +569,7 @@
H.healthdoll.overlays -= (cached_overlays - new_overlays)
H.healthdoll.cached_healthdoll_overlays = new_overlays
/datum/species/proc/handle_hud_icons_nutrition(mob/living/carbon/human/H)
switch(H.nutrition)
if(NUTRITION_LEVEL_FULL to INFINITY)
H.throw_alert("nutrition", /obj/screen/alert/fat)
@@ -717,4 +699,4 @@ It'll return null if the organ doesn't correspond, so include null checks when u
random_species += initial(S.name)
var/picked_species = pick(random_species)
var/datum/species/selected_species = GLOB.all_species[picked_species]
return species_name ? picked_species : selected_species.type
return species_name ? picked_species : selected_species.type
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,27 @@
/mob/living/carbon/human/update_stat(reason = "none given")
if(status_flags & GODMODE)
return
..(reason)
if(stat != DEAD)
switch(getBrainLoss())
if(100 to 120)
Weaken(20)
create_debug_log("collapsed from brain damage, trigger reason: [reason]")
if(120 to INFINITY)
visible_message("<span class='alert'><B>[src]</B> goes limp, [p_their()] facial expression utterly blank.</span>")
death()
create_debug_log("died of brain damage, trigger reason: [reason]")
else
if(dna.species && dna.species.can_revive_by_healing)
var/obj/item/organ/internal/brain/B = get_int_organ(/obj/item/organ/internal/brain)
if(B)
if((health >= (config.health_threshold_dead + config.health_threshold_crit) * 0.5) && getBrainLoss()<120)
update_revive()
create_debug_log("revived from healing, trigger reason: [reason]")
/mob/living/carbon/human/update_nearsighted_effects()
var/obj/item/clothing/glasses/G = glasses
if((disabilities & NEARSIGHTED) && (!istype(G) || !G.prescription))
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
else
clear_fullscreen("nearsighted")
+55 -87
View File
@@ -219,19 +219,19 @@
radiation--
if(prob(25))
adjustToxLoss(1)
updatehealth()
updatehealth("handle mutations and radiation(0-50)")
if(50 to 75)
radiation -= 2
adjustToxLoss(1)
if(prob(5))
radiation -= 5
updatehealth()
updatehealth("handle mutations and radiation(50-75)")
if(75 to 100)
radiation -= 3
adjustToxLoss(3)
updatehealth()
updatehealth("handle mutations and radiation(75-100)")
radiation = Clamp(radiation, 0, 100)
@@ -259,39 +259,11 @@
M.adjustBruteLoss(5)
nutrition += 10
//This updates the health and status of the mob (conscious, unconscious, dead)
/mob/living/carbon/handle_regular_status_updates()
if(..()) //alive
if(health <= config.health_threshold_dead)
death()
return
if(getOxyLoss() > 50 || health <= config.health_threshold_crit)
Paralyse(3)
stat = UNCONSCIOUS
if(sleeping)
stat = UNCONSCIOUS
return 1
/mob/living/carbon/proc/CheckStamina()
if(staminaloss)
var/total_health = (health - staminaloss)
if(total_health <= config.health_threshold_softcrit && !stat)
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
Weaken(5)
setStaminaLoss(health - 2)
return
setStaminaLoss(max((staminaloss - 3), 0))
//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
/mob/living/carbon/handle_status_effects()
..()
CheckStamina()
setStaminaLoss(max((staminaloss - 3), 0))
var/restingpwr = 1 + 4 * resting
@@ -375,61 +347,6 @@
Sleeping(2)
return sleeping
//this handles hud updates. Calls update_vision() and handle_hud_icons()
/mob/living/carbon/handle_regular_hud_updates()
if(!client)
return 0
if(stat == UNCONSCIOUS && health <= config.health_threshold_crit)
var/severity = 0
switch(health)
if(-20 to -10) severity = 1
if(-30 to -20) severity = 2
if(-40 to -30) severity = 3
if(-50 to -40) severity = 4
if(-60 to -50) severity = 5
if(-70 to -60) severity = 6
if(-80 to -70) severity = 7
if(-90 to -80) severity = 8
if(-95 to -90) severity = 9
if(-INFINITY to -95) severity = 10
overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity)
else
clear_fullscreen("crit")
if(oxyloss)
var/severity = 0
switch(oxyloss)
if(10 to 20) severity = 1
if(20 to 25) severity = 2
if(25 to 30) severity = 3
if(30 to 35) severity = 4
if(35 to 40) severity = 5
if(40 to 45) severity = 6
if(45 to INFINITY) severity = 7
overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
else
clear_fullscreen("oxy")
//Fire and Brute damage overlay (BSSR)
var/hurtdamage = getBruteLoss() + getFireLoss() + damageoverlaytemp
damageoverlaytemp = 0 // We do this so we can detect if someone hits us or not.
if(hurtdamage)
var/severity = 0
switch(hurtdamage)
if(5 to 15) severity = 1
if(15 to 30) severity = 2
if(30 to 45) severity = 3
if(45 to 70) severity = 4
if(70 to 85) severity = 5
if(85 to INFINITY) severity = 6
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
else
clear_fullscreen("brute")
..()
return 1
/mob/living/carbon/update_sight()
if(!client)
return
@@ -464,6 +381,9 @@
return
/mob/living/carbon/handle_hud_icons_health()
if(!client)
return
if(healths)
if(stat != DEAD)
switch(health)
@@ -483,3 +403,51 @@
healths.icon_state = "health6"
else
healths.icon_state = "health7"
handle_hud_icons_health_overlay()
/mob/living/carbon/proc/handle_hud_icons_health_overlay()
if(stat == UNCONSCIOUS && health <= config.health_threshold_crit)
var/severity = 0
switch(health)
if(-20 to -10) severity = 1
if(-30 to -20) severity = 2
if(-40 to -30) severity = 3
if(-50 to -40) severity = 4
if(-60 to -50) severity = 5
if(-70 to -60) severity = 6
if(-80 to -70) severity = 7
if(-90 to -80) severity = 8
if(-95 to -90) severity = 9
if(-INFINITY to -95) severity = 10
overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity)
else if(stat == CONSCIOUS)
clear_fullscreen("crit")
if(oxyloss)
var/severity = 0
switch(oxyloss)
if(10 to 20) severity = 1
if(20 to 25) severity = 2
if(25 to 30) severity = 3
if(30 to 35) severity = 4
if(35 to 40) severity = 5
if(40 to 45) severity = 6
if(45 to INFINITY) severity = 7
overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
else
clear_fullscreen("oxy")
//Fire and Brute damage overlay (BSSR)
var/hurtdamage = getBruteLoss() + getFireLoss() + damageoverlaytemp
damageoverlaytemp = 0 // We do this so we can detect if someone hits us or not.
if(hurtdamage)
var/severity = 0
switch(hurtdamage)
if(5 to 15) severity = 1
if(15 to 30) severity = 2
if(30 to 45) severity = 3
if(45 to 70) severity = 4
if(70 to 85) severity = 5
if(85 to INFINITY) severity = 6
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
else
clear_fullscreen("brute")
+5 -11
View File
@@ -1,6 +1,8 @@
/mob/living/carbon/slime/death(gibbed)
if(stat == DEAD)
return
// Only execute the below if we successfully died
. = ..()
if(!.)
return FALSE
if(!gibbed)
if(is_adult)
var/mob/living/carbon/slime/M = new /mob/living/carbon/slime(loc)
@@ -15,13 +17,5 @@
return
else
visible_message("<b>The [name]</b> seizes up and falls limp...")
stat = DEAD
icon_state = "[colour] baby slime dead"
overlays.len = 0
update_canmove()
if(ticker && ticker.mode)
ticker.mode.check_win()
return ..(gibbed)
overlays.Cut()
+2 -7
View File
@@ -131,7 +131,7 @@
else // a hot place
bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1)
updatehealth()
updatehealth("handle environment")
return //TODO: DEFERRED
@@ -163,7 +163,7 @@
if(reagents.get_reagent_amount("epinephrine")>=5)
mutation_chance = max(mutation_chance - 5,0) //Prevents mutation chance going <0%
reagents.remove_reagent("epinephrine", 5)
updatehealth()
updatehealth("handle chemicals in body")
return //TODO: DEFERRED
@@ -195,7 +195,6 @@
if(src.stat == DEAD)
src.lying = 1
src.blinded = 1
else
if(src.paralysis || src.stunned || src.weakened || (status_flags && FAKEDEATH)) //Stunned etc.
if(src.stunned > 0)
@@ -207,7 +206,6 @@
src.stat = 0
if(src.paralysis > 0)
AdjustParalysis(-1)
src.blinded = 0
src.lying = 0
src.stat = 0
@@ -219,7 +217,6 @@
if(src.eye_blind)
src.SetEyeBlind(0)
src.blinded = 1
if(src.ear_deaf > 0) SetEarDeaf(0)
if(src.ear_damage < 25)
@@ -227,8 +224,6 @@
src.density = !( src.lying )
if(src.disabilities & BLIND)
src.blinded = 1
if(src.disabilities & DEAF)
EarDeaf(1)
@@ -102,9 +102,9 @@
adjustFireLoss(-10)
adjustCloneLoss(-10)
updatehealth()
updatehealth("slime feeding")
if(Victim)
Victim.updatehealth()
Victim.updatehealth("slime feeding")
sleep(rand(15,45))
@@ -1,15 +1,29 @@
/mob/living/carbon/update_stat()
/mob/living/carbon/update_stat(reason = "none given")
if(status_flags & GODMODE)
return
if(stat != DEAD)
// if(health <= min_health)
if(health <= config.health_threshold_dead)
death()
create_debug_log("died of damage, trigger reason: [reason]")
return
// if(paralysis || sleeping || getOxyLoss() > low_oxy_ko || (status_flags & FAKEDEATH) || health <= crit_health)
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit)
if(stat == CONSCIOUS)
KnockOut()
create_debug_log("fell unconscious, trigger reason: [reason]")
else
if(stat == UNCONSCIOUS)
WakeUp()
create_debug_log("woke up, trigger reason: [reason]")
/mob/living/carbon/update_stamina()
..()
if(staminaloss)
var/total_health = (health - staminaloss)
if(total_health <= config.health_threshold_softcrit && !stat)
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
Weaken(5)
setStaminaLoss(health - 2)
handle_hud_icons_health()
return
+204 -2
View File
@@ -24,7 +24,7 @@
adjustCloneLoss(damage * blocked)
if(STAMINA)
adjustStaminaLoss(damage * blocked)
updatehealth()
updatehealth("apply damage")
return 1
/mob/living/proc/apply_damage_type(damage = 0, damagetype = BRUTE) //like apply damage except it always uses the damage procs
@@ -83,7 +83,7 @@
if(JITTER)
if(status_flags & CANSTUN)
Jitter(effect * blocked)
updatehealth()
updatehealth("apply effect")
return 1
/mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/irradiate = 0, var/slur = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/blocked = 0, var/stamina = 0, var/jitter = 0)
@@ -99,3 +99,205 @@
if(stamina) apply_damage(stamina, STAMINA, null, blocked)
if(jitter) apply_effect(jitter, JITTER, blocked)
return 1
/mob/living/proc/getBruteLoss()
return bruteloss
/mob/living/proc/adjustBruteLoss(var/amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_bruteloss = bruteloss
bruteloss = min(max(bruteloss + amount, 0),(maxHealth*2))
if(old_bruteloss == bruteloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
else
. = STATUS_UPDATE_HEALTH
if(updating_health)
updatehealth("adjustBruteLoss")
/mob/living/proc/getOxyLoss()
return oxyloss
/mob/living/proc/adjustOxyLoss(var/amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_oxyloss = oxyloss
oxyloss = min(max(oxyloss + amount, 0),(maxHealth*2))
if(old_oxyloss == oxyloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
else
. = STATUS_UPDATE_HEALTH
if(updating_health)
updatehealth("adjustOxyLoss")
/mob/living/proc/setOxyLoss(amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_oxyloss = oxyloss
oxyloss = amount
if(old_oxyloss == oxyloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
else
. = STATUS_UPDATE_HEALTH
if(updating_health)
updatehealth("setOxyLoss")
/mob/living/proc/getToxLoss()
return toxloss
/mob/living/proc/adjustToxLoss(var/amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_toxloss = toxloss
toxloss = min(max(toxloss + amount, 0),(maxHealth*2))
if(old_toxloss == toxloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
else
. = STATUS_UPDATE_HEALTH
if(updating_health)
updatehealth("adjustToxLoss")
/mob/living/proc/setToxLoss(var/amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_toxloss = toxloss
toxloss = amount
if(old_toxloss == toxloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
else
. = STATUS_UPDATE_HEALTH
if(updating_health)
updatehealth("setToxLoss")
/mob/living/proc/getFireLoss()
return fireloss
/mob/living/proc/adjustFireLoss(var/amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_fireloss = fireloss
fireloss = min(max(fireloss + amount, 0),(maxHealth*2))
if(old_fireloss == fireloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
else
. = STATUS_UPDATE_HEALTH
if(updating_health)
updatehealth("adjustFireLoss")
/mob/living/proc/getCloneLoss()
return cloneloss
/mob/living/proc/adjustCloneLoss(var/amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_cloneloss = cloneloss
cloneloss = min(max(cloneloss + amount, 0),(maxHealth*2))
if(old_cloneloss == cloneloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
else
. = STATUS_UPDATE_HEALTH
if(updating_health)
updatehealth("adjustCloneLoss")
/mob/living/proc/setCloneLoss(var/amount, updating_health = TRUE)
if(status_flags & GODMODE) return 0 //godmode
var/old_cloneloss = cloneloss
cloneloss = amount
if(old_cloneloss == cloneloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
else
. = STATUS_UPDATE_HEALTH
if(updating_health)
updatehealth("setCloneLoss")
/mob/living/proc/getBrainLoss()
return 0
/mob/living/proc/adjustBrainLoss(amount, updating = TRUE)
return STATUS_UPDATE_NONE
/mob/living/proc/setBrainLoss(amount, updating = TRUE)
return STATUS_UPDATE_NONE
/mob/living/proc/getStaminaLoss()
return staminaloss
/mob/living/proc/adjustStaminaLoss(amount, updating = TRUE)
if(status_flags & GODMODE)
return FALSE
var/old_stamloss = staminaloss
staminaloss = min(max(staminaloss + amount, 0),(maxHealth*2))
if(old_stamloss == staminaloss)
updating = FALSE
. = STATUS_UPDATE_NONE
else
. = STATUS_UPDATE_STAMINA
if(updating)
handle_hud_icons_health()
update_stamina()
/mob/living/proc/setStaminaLoss(amount, updating = TRUE)
if(status_flags & GODMODE)
return FALSE
var/old_stamloss = staminaloss
staminaloss = amount
if(old_stamloss == staminaloss)
updating = FALSE
. = STATUS_UPDATE_NONE
else
. = STATUS_UPDATE_STAMINA
if(updating)
handle_hud_icons_health()
update_stamina()
/mob/living/proc/getMaxHealth()
return maxHealth
/mob/living/proc/setMaxHealth(var/newMaxHealth)
maxHealth = newMaxHealth
// heal ONE external organ, organ gets randomly selected from damaged ones.
/mob/living/proc/heal_organ_damage(brute, burn, updating_health = TRUE)
adjustBruteLoss(-brute, FALSE)
adjustFireLoss(-burn, FALSE)
if(updating_health)
updatehealth("heal organ damage")
// damage ONE external organ, organ gets randomly selected from damaged ones.
/mob/living/proc/take_organ_damage(brute, burn, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
adjustBruteLoss(brute, FALSE)
adjustFireLoss(burn, FALSE)
if(updating_health)
updatehealth("take organ damage")
// heal MANY external organs, in random order
/mob/living/proc/heal_overall_damage(brute, burn, updating_health = TRUE)
adjustBruteLoss(-brute, FALSE)
adjustFireLoss(-burn, FALSE)
if(updating_health)
updatehealth("heal overall damage")
// damage MANY external organs, in random order
/mob/living/proc/take_overall_damage(brute, burn, updating_health = TRUE, used_weapon = null)
if(status_flags & GODMODE)
return FALSE //godmode
adjustBruteLoss(brute, FALSE)
adjustFireLoss(burn, FALSE)
if(updating_health)
updatehealth("take overall damage")
/mob/living/proc/has_organic_damage()
return (maxHealth - health)
+76 -5
View File
@@ -1,12 +1,71 @@
//This is the proc for gibbing a mob. Cannot gib ghosts.
//added different sort of gibs and animations. N
/mob/living/gib()
if(!death(TRUE) && stat != DEAD)
return FALSE
// hide and freeze for the GC
notransform = 1
canmove = 0
icon = null
invisibility = 101
playsound(src.loc, 'sound/goonstation/effects/gib.ogg', 50, 1)
gibs(loc, dna)
QDEL_IN(src, 0)
return TRUE
//This is the proc for turning a mob into ash. Mostly a copy of gib code (above).
//Originally created for wizard disintegrate. I've removed the virus code since it's irrelevant here.
//Dusting robots does not eject the MMI, so it's a bit more powerful than gib() /N
/mob/living/dust()
if(!death(TRUE) && stat != DEAD)
return FALSE
new /obj/effect/decal/cleanable/ash(loc)
// hide and freeze them while they get GC'd
notransform = 1
canmove = 0
icon = null
invisibility = 101
QDEL_IN(src, 0)
return TRUE
/mob/living/melt()
if(!death(TRUE) && stat != DEAD)
return FALSE
// hide and freeze them while they get GC'd
notransform = 1
canmove = 0
icon = null
invisibility = 101
QDEL_IN(src, 0)
return TRUE
/mob/living/proc/can_die()
return !(stat == DEAD || (status_flags & GODMODE))
// Returns true if mob transitioned from live to dead
// Do a check with `can_die` beforehand if you need to do any
// handling before `stat` is set
/mob/living/death(gibbed)
blinded = max(blinded, 1)
if(!can_die())
// Whew! Good thing I'm indestructible! (or already dead)
return FALSE
stat = DEAD
SetDizzy(0)
SetJitter(0)
SetLoseBreath(0)
if(suiciding)
mind.suicided = TRUE
clear_fullscreens()
update_sight()
update_action_buttons_icon()
med_hud_set_health()
med_hud_set_status()
callHook("death", list(src, gibbed))
for(var/s in ownedSoullinks)
var/datum/soullink/S = s
S.ownerDies(gibbed, src)
@@ -14,7 +73,19 @@
var/datum/soullink/S = s
S.sharerDies(gibbed, src)
med_hud_set_health()
med_hud_set_status()
if(!gibbed)
update_canmove()
..(gibbed)
timeofdeath = world.time
living_mob_list -= src
dead_mob_list += src
if(mind)
mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
respawnable_list += src
if(ticker && ticker.mode)
ticker.mode.check_win()
// u no we dead
return TRUE
+3 -46
View File
@@ -8,12 +8,6 @@
return
var/datum/gas_mixture/environment = loc.return_air()
//Apparently, the person who wrote this code designed it so that
//blinded get reset each cycle and then get activated later in the
//code. Very ugly. I dont care. Moving this stuff here so its easy
//to find it.
blinded = null
if(stat != DEAD)
//Chemicals in the body
handle_chemicals_in_body()
@@ -51,8 +45,6 @@
handle_disabilities() // eye, ear, brain damages
handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
update_canmove(1) // set to 1 to not update icon action buttons; rip this argument out if Life is ever refactored to be non-stupid. -Fox
if(client)
//regular_hud_updates() //THIS DOESN'T FUCKING UPDATE SHIT
handle_regular_hud_updates() //IT JUST REMOVES FUCKING HUD IMAGES
@@ -90,21 +82,7 @@
//This updates the health and status of the mob (conscious, unconscious, dead)
/mob/living/proc/handle_regular_status_updates()
updatehealth()
if(stat != DEAD)
if(paralysis)
stat = UNCONSCIOUS
else if(status_flags & FAKEDEATH)
stat = UNCONSCIOUS
else
stat = CONSCIOUS
return 1
return stat != DEAD
//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
/mob/living/proc/handle_status_effects()
@@ -215,29 +193,6 @@
if(stat == DEAD)
return
if(blinded || eye_blind)
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
throw_alert("blind", /obj/screen/alert/blind)
else
clear_fullscreen("blind")
clear_alert("blind")
if(disabilities & NEARSIGHTED)
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
else
clear_fullscreen("nearsighted")
if(eye_blurry)
overlay_fullscreen("blurry", /obj/screen/fullscreen/blurry)
else
clear_fullscreen("blurry")
if(druggy)
overlay_fullscreen("high", /obj/screen/fullscreen/high)
throw_alert("high", /obj/screen/alert/high)
else
clear_fullscreen("high")
clear_alert("high")
if(machine)
if(!machine.check_eye(src))
@@ -247,6 +202,8 @@
reset_perspective(null)
/mob/living/proc/update_sight()
if(stat == DEAD)
grant_death_vision()
return
// Gives a mob the vision of being dead
+10 -121
View File
@@ -214,16 +214,14 @@
/mob/living/verb/succumb()
set hidden = 1
if(InCritical())
attack_log += "[src] has ["succumbed to death"] with [round(health, 0.1)] points of health!"
create_attack_log("[src] has ["succumbed to death"] with [round(health, 0.1)] points of health!")
adjustOxyLoss(health - config.health_threshold_dead)
updatehealth()
// super check for weird mobs, including ones that adjust hp
// we don't want to go overboard and gib them, though
for(var/i = 1 to 5)
if(health < config.health_threshold_dead)
break
take_overall_damage(max(5, health - config.health_threshold_dead), 0)
updatehealth()
to_chat(src, "<span class='notice'>You have given up life and succumbed to death.</span>")
/mob/living/proc/InCritical()
@@ -233,12 +231,15 @@
..()
flash_eyes()
/mob/living/proc/updatehealth()
/mob/living/proc/updatehealth(reason = "none given")
if(status_flags & GODMODE)
health = maxHealth
stat = CONSCIOUS
return
health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
update_stat("updatehealth([reason])")
handle_hud_icons_health()
med_hud_set_health()
@@ -268,89 +269,6 @@
return temperature
// ++++ROCKDTBEN++++ MOB PROCS -- Ask me before touching.
// Stop! ... Hammertime! ~Carn
// I touched them without asking... I'm soooo edgy ~Erro (added nodamage checks)
// no ~Tigerkitty
/mob/living/proc/getBruteLoss()
return bruteloss
/mob/living/proc/adjustBruteLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
bruteloss = min(max(bruteloss + amount, 0),(maxHealth*2))
/mob/living/proc/getOxyLoss()
return oxyloss
/mob/living/proc/adjustOxyLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
oxyloss = min(max(oxyloss + amount, 0),(maxHealth*2))
/mob/living/proc/setOxyLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
oxyloss = amount
/mob/living/proc/getToxLoss()
return toxloss
/mob/living/proc/adjustToxLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
toxloss = min(max(toxloss + amount, 0),(maxHealth*2))
/mob/living/proc/setToxLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
toxloss = amount
/mob/living/proc/getFireLoss()
return fireloss
/mob/living/proc/adjustFireLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
fireloss = min(max(fireloss + amount, 0),(maxHealth*2))
/mob/living/proc/getCloneLoss()
return cloneloss
/mob/living/proc/adjustCloneLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
cloneloss = min(max(cloneloss + amount, 0),(maxHealth*2))
/mob/living/proc/setCloneLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
cloneloss = amount
/mob/living/proc/getBrainLoss()
return brainloss
/mob/living/proc/adjustBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
brainloss = min(max(brainloss + amount, 0),(maxHealth*2))
/mob/living/proc/setBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
brainloss = amount
/mob/living/proc/getStaminaLoss()
return staminaloss
/mob/living/proc/adjustStaminaLoss(var/amount)
if(status_flags & GODMODE) return 0
staminaloss = min(max(staminaloss + amount, 0),(maxHealth*2))
/mob/living/proc/setStaminaLoss(var/amount)
if(status_flags & GODMODE) return 0
staminaloss = amount
/mob/living/proc/getMaxHealth()
return maxHealth
/mob/living/proc/setMaxHealth(var/newMaxHealth)
maxHealth = newMaxHealth
// ++++ROCKDTBEN++++ MOB PROCS //END
/mob/proc/get_contents()
@@ -421,35 +339,6 @@
var/obj/item/organ/external/def_zone = ran_zone(t)
return def_zone
// heal ONE external organ, organ gets randomly selected from damaged ones.
/mob/living/proc/heal_organ_damage(var/brute, var/burn)
adjustBruteLoss(-brute)
adjustFireLoss(-burn)
updatehealth()
// damage ONE external organ, organ gets randomly selected from damaged ones.
/mob/living/proc/take_organ_damage(var/brute, var/burn)
if(status_flags & GODMODE) return 0 //godmode
adjustBruteLoss(brute)
adjustFireLoss(burn)
updatehealth()
// heal MANY external organs, in random order
/mob/living/proc/heal_overall_damage(var/brute, var/burn)
adjustBruteLoss(-brute)
adjustFireLoss(-burn)
updatehealth()
// damage MANY external organs, in random order
/mob/living/proc/take_overall_damage(var/brute, var/burn, var/used_weapon = null)
if(status_flags & GODMODE) return 0 //godmode
adjustBruteLoss(brute)
adjustFireLoss(burn)
updatehealth()
/mob/living/proc/has_organic_damage()
return (maxHealth - health)
/mob/living/proc/restore_all_organs()
return
@@ -474,6 +363,8 @@
C.reagents.clear_reagents()
C.reagents.addiction_list.Cut()
// rejuvenate: Called by `revive` to get the mob into a revivable state
// the admin "rejuvenate" command calls `revive`, not this proc.
/mob/living/proc/rejuvenate()
var/mob/living/carbon/human/human_mob = null //Get this declared for use later.
@@ -496,7 +387,6 @@
radiation = 0
SetDruggy(0)
SetHallucinate(0)
blinded = 0
nutrition = NUTRITION_LEVEL_FED + 50
bodytemperature = 310
CureBlind()
@@ -544,11 +434,10 @@
restore_all_organs()
surgeries.Cut() //End all surgeries.
if(stat == DEAD)
dead_mob_list -= src
living_mob_list += src
timeofdeath = 0
update_revive()
else if(stat == UNCONSCIOUS)
WakeUp()
stat = CONSCIOUS
update_fire()
regenerate_icons()
restore_blood()
+1 -1
View File
@@ -122,7 +122,7 @@
M.mech_toxin_damage(src)
else
return
updatehealth()
updatehealth("mech melee attack")
M.occupant_message("<span class='danger'>You hit [src].</span>")
visible_message("<span class='danger'>[src] has been hit by [M.name].</span>", \
"<span class='userdanger'>[src] has been hit by [M.name].</span>")
@@ -12,7 +12,6 @@
var/toxloss = 0 //Toxic damage caused by being poisoned or radiated
var/fireloss = 0 //Burn damage caused by being way too hot, too cold or burnt.
var/cloneloss = 0 //Damage caused by being cloned or ejected from the cloner early. slimes also deal cloneloss damage to victims
var/brainloss = 0 //'Retardation' damage caused by someone hitting you in the head with a bible or being infected with brainrot.
var/staminaloss = 0 //Stamina damage, or exhaustion. You recover it slowly naturally, and are stunned if it gets too high. Holodeck and hallucinations deal this.
@@ -67,4 +66,3 @@
hud_possible = list(HEALTH_HUD,STATUS_HUD,SPECIALROLE_HUD)
var/list/status_effects //a list of all status effects the mob has
+4 -2
View File
@@ -2,6 +2,8 @@
..()
//Mind updates
sync_mind()
update_stat("mob login")
update_sight()
//If they're SSD, remove it so they can wake back up.
player_logged = 0
@@ -11,8 +13,8 @@
to_chat(src, "<span class='notice'>You can ventcrawl! Use alt+click on vents to quickly travel about the station.</span>")
if(ranged_ability)
ranged_ability.add_ranged_ability(src, "<span class='notice'>You currently have <b>[ranged_ability]</b> active!</span>")
ranged_ability.add_ranged_ability(src, "<span class='notice'>You currently have <b>[ranged_ability]</b> active!</span>")
//Should update regardless of if we can ventcrawl, since we can end up in pipes in other ways.
update_pipe_vision()
-2
View File
@@ -549,7 +549,6 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/blob_act()
if(stat != 2)
adjustBruteLoss(60)
updatehealth()
return TRUE
return FALSE
@@ -685,7 +684,6 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/bullet_act(var/obj/item/projectile/Proj)
..(Proj)
updatehealth()
return 2
/mob/living/silicon/ai/reset_perspective(atom/A)
+6 -14
View File
@@ -1,19 +1,16 @@
/mob/living/silicon/ai/death(gibbed)
if(stat == DEAD)
return
stat = DEAD
// Only execute the below if we successfully died
. = ..(gibbed)
if(!.)
return FALSE
if(custom_sprite == 1)//check for custom AI sprite, defaulting to blue screen if no.
icon_state = "[ckey]-ai_dead"
else if("[icon_state]_dead" in icon_states(icon,1))
icon_state = "[icon_state]_dead"
else
icon_state = "ai_dead"
update_canmove()
if(eyeobj)
eyeobj.setLoc(get_turf(src))
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
shuttle_caller_list -= src
SSshuttle.autoEvac()
@@ -38,12 +35,7 @@
explosion(src.loc, 3, 6, 12, 15)
for(var/obj/machinery/ai_status_display/O in world) //change status
spawn( 0 )
O.mode = 2
if(istype(loc, /obj/item/aicard))
loc.icon_state = "aicard-404"
timeofdeath = world.time
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
return ..(gibbed)
if(istype(loc, /obj/item/aicard))
loc.icon_state = "aicard-404"
+11 -18
View File
@@ -14,13 +14,11 @@
reset_perspective(null)
unset_machine()
updatehealth()
updatehealth("life")
if(stat == DEAD)
return
update_gravity(mob_has_gravity())
if(health <= config.health_threshold_dead)
death()
return 0
if(!eyeobj || QDELETED(eyeobj) || !eyeobj.loc)
view_core()
@@ -44,21 +42,15 @@
var/area/my_area = get_area(src)
if(!lacks_power())
if(aiRestorePowerRoutine == 2)
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
if(aiRestorePowerRoutine > 1)
update_blind_effects()
aiRestorePowerRoutine = 0
clear_fullscreen("blind")
update_sight()
else if(aiRestorePowerRoutine == 3)
to_chat(src, "Alert cancelled. Power has been restored.")
aiRestorePowerRoutine = 0
clear_fullscreen("blind")
update_sight()
to_chat(src, "Alert cancelled. Power has been restored[aiRestorePowerRoutine == 2 ? "without our assistance" : ""].")
else
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
if(lacks_power())
if(!aiRestorePowerRoutine)
update_blind_effects()
aiRestorePowerRoutine = 1
update_sight()
to_chat(src, "<span class='danger'>You have lost power!</span>")
@@ -73,7 +65,7 @@
if(!lacks_power())
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
aiRestorePowerRoutine = 0
clear_fullscreen("blind")
update_blind_effects()
update_sight()
return
to_chat(src, "Fault confirmed: missing external power. Shutting down main control system to save power.")
@@ -112,7 +104,7 @@
if(!lacks_power())
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
aiRestorePowerRoutine = 0
clear_fullscreen("blind")
update_blind_effects()
update_sight()
return
@@ -143,12 +135,13 @@
if(get_nations_mode())
process_nations_ai()
/mob/living/silicon/ai/updatehealth()
/mob/living/silicon/ai/updatehealth(reason = "none given")
if(status_flags & GODMODE)
health = 100
stat = CONSCIOUS
else
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
update_stat("updatehealth([reason])")
diag_hud_set_status()
diag_hud_set_health()
@@ -1,10 +1,15 @@
/mob/living/silicon/ai/update_stat()
/mob/living/silicon/ai/update_stat(reason = "none given")
if(status_flags & GODMODE)
return
if(stat != DEAD)
if(health <= config.health_threshold_dead)
death()
create_debug_log("died of damage, trigger reason: [reason]")
return
else if(stat == UNCONSCIOUS)
WakeUp()
create_debug_log("woke up, trigger reason: [reason]")
//diag_hud_set_status()
/mob/living/silicon/ai/has_vision(information_only = FALSE)
return ..() && !lacks_power()
@@ -1,10 +1,10 @@
/mob/living/silicon/decoy/death(gibbed)
if(stat == DEAD)
return
stat = DEAD
// Only execute the below if we successfully died
. = ..()
if(!.)
return FALSE
icon_state = "ai-crash"
for(var/obj/machinery/ai_status_display/O in world) //change status
if(atoms_share_level(O, src))
O.mode = 2
..(0)
gib()
gib()
@@ -2,17 +2,18 @@
return
/mob/living/silicon/decoy/updatehealth()
/mob/living/silicon/decoy/updatehealth(reason = "none given")
if(status_flags & GODMODE)
health = 100
stat = CONSCIOUS
else
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
update_stat()
update_stat("updatehealth([reason])")
/mob/living/silicon/decoy/update_stat()
/mob/living/silicon/decoy/update_stat(reason = "none given")
if(stat == DEAD)
return
if(health <= 0)
death()
death()
create_debug_log("died of damage, trigger reason: [reason]")
+11 -22
View File
@@ -1,28 +1,17 @@
/mob/living/silicon/pai/death(gibbed, cleanWipe)
if(stat == DEAD)
return
if(can_die())
if(!cleanWipe)
force_fold_out()
if(!cleanWipe)
force_fold_out()
visible_message("<span class=warning>[src] emits a dull beep before it loses power and collapses.</span>", "<span class=warning>You hear a dull beep followed by the sound of glass crunching.</span>")
name = "pAI debris"
desc = "The unfortunate remains of some poor personal AI device."
icon_state = "[chassis]_dead"
var/turf/T = get_turf_or_move(loc)
for(var/mob/M in viewers(T))
M.show_message("<span class='warning'>[src] emits a dull beep before it loses power and collapses.</span>", 3, "<span class='warning'>You hear a dull beep followed by the sound of glass crunching.</span>", 2)
name = "pAI debris"
desc = "The unfortunate remains of some poor personal AI device."
icon_state = "[chassis]_dead"
stat = DEAD
canmove = 0
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
// Only execute the below if we successfully died
. = ..(gibbed)
if(!.)
return FALSE
//var/tod = time2text(world.realtime,"hh:mm:ss") //weasellos time of death patch
//mind.store_memory("Time of death: [tod]", 0)
//New pAI's get a brand new mind to prevent meta stuff from their previous life. This new mind causes problems down the line if it's not deleted here.
//Read as: I have no idea what I'm doing but asking for help got me nowhere so this is what you get. - Nodrak
if(mind) qdel(mind)
living_mob_list -= src
if(icon_state != "[chassis]_dead" || cleanWipe)
qdel(src)
+2 -3
View File
@@ -18,11 +18,10 @@
qdel(src.cable)
cable = null
/mob/living/silicon/pai/updatehealth()
/mob/living/silicon/pai/updatehealth(reason = "none given")
if(status_flags & GODMODE)
health = 100
stat = CONSCIOUS
else
health = 100 - getBruteLoss() - getFireLoss()
if(health <= 0)
death(0)
update_stat("updatehealth([reason])")
+2 -8
View File
@@ -160,9 +160,8 @@
return 1
/mob/living/silicon/pai/blob_act()
if(stat != 2)
if(stat != DEAD)
adjustBruteLoss(60)
updatehealth()
return 1
return 0
@@ -238,7 +237,6 @@
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
add_attack_logs(M, src, "Animal attacked for [damage] damage")
adjustBruteLoss(damage)
updatehealth()
/mob/living/silicon/pai/proc/switchCamera(var/obj/machinery/camera/C)
usr:cameraFollow = null
@@ -454,9 +452,7 @@
if(stat == DEAD)
to_chat(user, "<span class='danger'>\The [src] is beyond help, at this point.</span>")
else if(getBruteLoss() || getFireLoss())
adjustBruteLoss(-15)
adjustFireLoss(-15)
updatehealth()
heal_overall_damage(15, 15)
N.use(1)
user.visible_message("<span class='notice'>[user.name] applied some [W] at [src]'s damaged areas.</span>",\
"<span class='notice'>You apply some [W] at [name]'s damaged areas.</span>")
@@ -467,7 +463,6 @@
else if(W.force)
visible_message("<span class='danger'>[user.name] attacks [src] with [W]!</span>")
adjustBruteLoss(W.force)
updatehealth()
else
visible_message("<span class='warning'>[user.name] bonks [src] harmlessly with [W].</span>")
spawn(1)
@@ -557,7 +552,6 @@
/mob/living/silicon/pai/bullet_act(var/obj/item/projectile/Proj)
..(Proj)
updatehealth()
if(stat != 2)
spawn(1)
close_up()
@@ -226,7 +226,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
<td class="button"><a href='byond://?src=[UID()];option=submit;new=1;candidate=\ref[candidate]' class="button"><b><font size="4px">Submit Personality</font></b></a></td>
</table><br>
<body>
</body>
"}
M << browse(dat, "window=paiRecruit;size=580x580;")
@@ -1,3 +1,4 @@
/mob/living/silicon/pai/update_stat()
/mob/living/silicon/pai/update_stat(reason = "none given")
if(health <= 0)
death(gibbed = 0)
create_debug_log("died of damage, trigger reason: [reason]")
@@ -21,7 +21,9 @@
src.owner = R
/datum/robot_component/proc/install()
go_online()
/datum/robot_component/proc/uninstall()
go_offline()
/datum/robot_component/proc/destroy()
if(wrapped)
@@ -34,34 +36,62 @@
installed = -1
uninstall()
/datum/robot_component/proc/take_damage(brute, electronics, sharp)
/datum/robot_component/proc/take_damage(brute, electronics, sharp, updating_health = TRUE)
if(installed != 1)
return
if(owner && updating_health)
owner.updatehealth("component '[src]' take damage")
brute_damage += brute
electronics_damage += electronics
if(brute_damage + electronics_damage >= max_damage)
destroy()
/datum/robot_component/proc/heal_damage(brute, electronics)
/datum/robot_component/proc/heal_damage(brute, electronics, updating_health = TRUE)
if(installed != 1)
// If it's not installed, can't repair it.
return 0
if(owner && updating_health)
owner.updatehealth("component '[src]' heal damage")
brute_damage = max(0, brute_damage - brute)
electronics_damage = max(0, electronics_damage - electronics)
/datum/robot_component/proc/is_powered()
return (installed == 1) && (brute_damage + electronics_damage < max_damage) && (powered)
/datum/robot_component/proc/consume_power()
if(toggled == 0)
powered = 0
return
powered = 1
/datum/robot_component/proc/disable()
if(!component_disabled)
go_offline()
component_disabled++
/datum/robot_component/proc/enable()
component_disabled--
if(!component_disabled)
go_online()
/datum/robot_component/proc/toggle()
toggled = !toggled
if(toggled)
go_online()
else
go_offline()
/datum/robot_component/proc/go_online()
return
/datum/robot_component/proc/go_offline()
return
/datum/robot_component/armour
name = "armour plating"
external_type = /obj/item/robot_parts/robot_component/armour
@@ -72,10 +102,25 @@
external_type = /obj/item/robot_parts/robot_component/actuator
max_damage = 50
/datum/robot_component/actuator/go_online()
owner.update_stat()
/datum/robot_component/actuator/go_offline()
owner.update_stat()
/datum/robot_component/cell
name = "power cell"
max_damage = 50
/datum/robot_component/cell/is_powered()
return ..() && owner.cell
/datum/robot_component/cell/go_online()
owner.update_stat()
/datum/robot_component/cell/go_offline()
owner.update_stat()
/datum/robot_component/cell/destroy()
..()
owner.cell = null
@@ -95,6 +140,14 @@
external_type = /obj/item/robot_parts/robot_component/camera
max_damage = 40
/datum/robot_component/camera/go_online()
owner.update_blind_effects()
owner.update_sight()
/datum/robot_component/camera/go_offline()
owner.update_blind_effects()
owner.update_sight()
/datum/robot_component/diagnosis_unit
name = "self-diagnosis unit"
external_type = /obj/item/robot_parts/robot_component/diagnosis_unit
@@ -117,9 +170,9 @@
/mob/living/silicon/robot/proc/disable_component(module_name, duration)
var/datum/robot_component/D = get_component(module_name)
D.component_disabled++
D.disable()
spawn(duration)
D.component_disabled--
D.enable()
// Returns component by it's string name
/mob/living/silicon/robot/proc/get_component(var/component_name)
@@ -154,6 +207,8 @@
name = "camera"
icon_state = "camera"
/obj/item/robot_parts/robot_component/diagnosis_unit
name = "diagnosis unit"
icon_state = "diagnosis_unit"

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