mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-27 05:57:24 +01:00
resolving conflicts
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
@@ -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")
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -306,5 +306,5 @@ var/global/datum/prizes/global_prizes = new
|
||||
/datum/prize_item/bike
|
||||
name = "Awesome Bike!"
|
||||
desc = "WOAH."
|
||||
typepath = /obj/structure/stool/bed/chair/wheelchair/bike
|
||||
typepath = /obj/structure/chair/wheelchair/bike
|
||||
cost = 10000 //max stack + 1 tickets.
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
return
|
||||
|
||||
/obj/item/assembly/shock_kit/receive_signal()
|
||||
if(istype(loc, /obj/structure/stool/bed/chair/e_chair))
|
||||
var/obj/structure/stool/bed/chair/e_chair/C = loc
|
||||
if(istype(loc, /obj/structure/chair/e_chair))
|
||||
var/obj/structure/chair/e_chair/C = loc
|
||||
C.shock()
|
||||
return
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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." : ""]")
|
||||
@@ -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])")
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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]")
|
||||
@@ -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>")
|
||||
|
||||
@@ -2159,7 +2159,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
var/obj/item/organ/external/l_foot = character.get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = character.get_organ("r_foot")
|
||||
if(!l_foot && !r_foot)
|
||||
var/obj/structure/stool/bed/chair/wheelchair/W = new /obj/structure/stool/bed/chair/wheelchair (character.loc)
|
||||
var/obj/structure/chair/wheelchair/W = new /obj/structure/chair/wheelchair (character.loc)
|
||||
character.buckled = W
|
||||
character.update_canmove()
|
||||
W.dir = character.dir
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'"
|
||||
@@ -168,9 +189,9 @@
|
||||
if(!proximity || !ishuman(user) || user.incapacitated())
|
||||
return
|
||||
|
||||
if(istype(target, /obj/structure/stool/bed/chair/wheelchair) && !istype(target, /obj/structure/stool/bed/chair/wheelchair/bike))
|
||||
if(istype(target, /obj/structure/chair/wheelchair) && !istype(target, /obj/structure/chair/wheelchair/bike))
|
||||
to_chat(user, "<span class='notice'>You modify the appearance of [target].</span>")
|
||||
var/obj/structure/stool/bed/chair/wheelchair/chair = target
|
||||
var/obj/structure/chair/wheelchair/chair = target
|
||||
chair.icon = 'icons/obj/custom_items.dmi'
|
||||
chair.icon_state = "vox_wheelchair"
|
||||
chair.name = "vox wheelchair"
|
||||
@@ -1484,3 +1505,4 @@
|
||||
item_state = "Xann_necklace"
|
||||
item_color = "Xann_necklace"
|
||||
slot_flags = SLOT_TIE
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -196,13 +196,13 @@
|
||||
if("winter") //Snow terrain is slow to move in and cold! Get the assistants to shovel your driveway.
|
||||
NewTerrainFloors = /turf/simulated/floor/snow // Needs to be updated after turf update
|
||||
NewTerrainWalls = /turf/simulated/wall/mineral/wood
|
||||
NewTerrainChairs = /obj/structure/stool/bed/chair/wood/normal
|
||||
NewTerrainChairs = /obj/structure/chair/wood/normal
|
||||
NewTerrainTables = /obj/structure/table/glass
|
||||
NewFlora = list(/obj/structure/flora/grass/green, /obj/structure/flora/grass/brown, /obj/structure/flora/grass/both)
|
||||
if("jungle") //Beneficial due to actually having breathable air. Plus, monkeys and bows and arrows.
|
||||
NewTerrainFloors = /turf/simulated/floor/grass
|
||||
NewTerrainWalls = /turf/simulated/wall/mineral/sandstone
|
||||
NewTerrainChairs = /obj/structure/stool/bed/chair/wood/normal
|
||||
NewTerrainChairs = /obj/structure/chair/wood/normal
|
||||
NewTerrainTables = /obj/structure/table/wood
|
||||
NewFlora = list(/obj/structure/flora/ausbushes/sparsegrass, /obj/structure/flora/ausbushes/fernybush, /obj/structure/flora/ausbushes/leafybush,
|
||||
/obj/structure/flora/ausbushes/grassybush, /obj/structure/flora/ausbushes/sunnybush, /obj/structure/flora/tree/palm, /mob/living/carbon/human/monkey,
|
||||
@@ -211,7 +211,7 @@
|
||||
if("alien") //Beneficial, turns stuff into alien alloy which is useful to cargo and research. Also repairs atmos.
|
||||
NewTerrainFloors = /turf/simulated/floor/mineral/abductor
|
||||
NewTerrainWalls = /turf/simulated/wall/mineral/abductor
|
||||
NewTerrainChairs = /obj/structure/stool/bed/abductor //ayys apparently don't have chairs. An entire species of people who only recline.
|
||||
NewTerrainChairs = /obj/structure/bed/abductor //ayys apparently don't have chairs. An entire species of people who only recline.
|
||||
NewTerrainTables = /obj/structure/table/abductor
|
||||
|
||||
/obj/machinery/anomalous_crystal/theme_warp/ActivationReaction(mob/user, method)
|
||||
@@ -233,9 +233,9 @@
|
||||
if(iswallturf(T) && NewTerrainWalls)
|
||||
T.ChangeTurf(NewTerrainWalls)
|
||||
continue
|
||||
if(istype(Stuff, /obj/structure/stool/bed/chair) && NewTerrainChairs)
|
||||
var/obj/structure/stool/bed/chair/Original = Stuff
|
||||
var/obj/structure/stool/bed/chair/C = new NewTerrainChairs(Original.loc)
|
||||
if(istype(Stuff, /obj/structure/chair) && NewTerrainChairs)
|
||||
var/obj/structure/chair/Original = Stuff
|
||||
var/obj/structure/chair/C = new NewTerrainChairs(Original.loc)
|
||||
C.dir = Original.dir
|
||||
qdel(Stuff)
|
||||
continue
|
||||
|
||||
@@ -442,7 +442,7 @@
|
||||
attack_self(user)
|
||||
|
||||
//Bed
|
||||
/obj/structure/stool/bed/pod
|
||||
/obj/structure/bed/pod
|
||||
icon = 'icons/obj/lavaland/survival_pod.dmi'
|
||||
icon_state = "bed"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -146,7 +146,7 @@ Doesn't work on other aliens/AI.*/
|
||||
if("resin membrane")
|
||||
new /obj/structure/alien/resin/membrane(loc)
|
||||
if("resin nest")
|
||||
new /obj/structure/stool/bed/nest(loc)
|
||||
new /obj/structure/bed/nest(loc)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/humanoid/verb/regurgitate()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -578,14 +578,14 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
|
||||
|
||||
/mob/living/carbon/can_use_hands()
|
||||
if(handcuffed)
|
||||
return 0
|
||||
if(buckled && ! istype(buckled, /obj/structure/stool/bed/chair)) // buckling does not restrict hands
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
if(buckled && ! istype(buckled, /obj/structure/chair)) // buckling does not restrict hands
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/restrained()
|
||||
if(handcuffed)
|
||||
return 1
|
||||
return TRUE
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
@@ -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
|
||||
|
||||
@@ -354,8 +326,8 @@
|
||||
handle_dreams()
|
||||
adjustStaminaLoss(-10)
|
||||
var/comfort = 1
|
||||
if(istype(buckled, /obj/structure/stool/bed))
|
||||
var/obj/structure/stool/bed/bed = buckled
|
||||
if(istype(buckled, /obj/structure/bed))
|
||||
var/obj/structure/bed/bed = buckled
|
||||
comfort+= bed.comfort
|
||||
for(var/obj/item/bedsheet/bedsheet in range(loc,0))
|
||||
if(bedsheet.loc != loc) //bedsheets in your backpack/neck don't give you comfort
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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]")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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])")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -46,11 +46,20 @@
|
||||
|
||||
|
||||
/mob/living/silicon/robot/death(gibbed)
|
||||
if(stat == DEAD) return
|
||||
if(!gibbed)
|
||||
emote("deathgasp")
|
||||
stat = DEAD
|
||||
update_canmove()
|
||||
if(can_die())
|
||||
if(!gibbed)
|
||||
emote("deathgasp")
|
||||
|
||||
if(module)
|
||||
module.handle_death(gibbed)
|
||||
|
||||
// Only execute the below if we successfully died
|
||||
. = ..(gibbed)
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
diag_hud_set_status()
|
||||
diag_hud_set_health()
|
||||
if(camera)
|
||||
camera.status = 0
|
||||
update_headlamp(1) //So borg lights are disabled when killed.
|
||||
@@ -59,13 +68,6 @@
|
||||
var/obj/machinery/recharge_station/RC = loc
|
||||
RC.go_out()
|
||||
|
||||
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
update_icons()
|
||||
timeofdeath = world.time
|
||||
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
|
||||
|
||||
sql_report_cyborg_death(src)
|
||||
|
||||
return ..(gibbed)
|
||||
|
||||
@@ -215,33 +215,13 @@
|
||||
//DRONE LIFE/DEATH
|
||||
|
||||
//For some goddamn reason robots have this hardcoded. Redefining it for our fragile friends here.
|
||||
/mob/living/silicon/robot/drone/updatehealth()
|
||||
/mob/living/silicon/robot/drone/updatehealth(reason = "none given")
|
||||
if(status_flags & GODMODE)
|
||||
health = 35
|
||||
stat = CONSCIOUS
|
||||
return
|
||||
health = 35 - (getBruteLoss() + getFireLoss())
|
||||
return
|
||||
|
||||
//Easiest to check this here, then check again in the robot proc.
|
||||
//Standard robots use config for crit, which is somewhat excessive for these guys.
|
||||
//Drones killed by damage will gib.
|
||||
/mob/living/silicon/robot/drone/handle_regular_status_updates()
|
||||
|
||||
if(health <= -35 && src.stat != DEAD)
|
||||
timeofdeath = world.time
|
||||
death() //Possibly redundant, having trouble making death() cooperate.
|
||||
gib()
|
||||
return
|
||||
return ..() // If you don't return anything here, you won't update status effects, like weakening
|
||||
|
||||
/mob/living/silicon/robot/drone/death(gibbed)
|
||||
|
||||
if(module)
|
||||
var/obj/item/gripper/G = locate(/obj/item/gripper) in module
|
||||
if(G) G.drop_item()
|
||||
|
||||
..(gibbed)
|
||||
update_stat("updatehealth([reason])")
|
||||
|
||||
|
||||
//CONSOLE PROCS
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
//Redefining some robot procs, since drones can't be repaired and really shouldn't take component damage.
|
||||
/mob/living/silicon/robot/drone/take_overall_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/used_weapon = null)
|
||||
/mob/living/silicon/robot/drone/take_overall_damage(brute, burn, updating_health = TRUE, used_weapon = null, sharp = 0)
|
||||
bruteloss += brute
|
||||
fireloss += burn
|
||||
if(updating_health)
|
||||
updatehealth("take overall damage")
|
||||
|
||||
/mob/living/silicon/robot/drone/heal_overall_damage(var/brute, var/burn)
|
||||
/mob/living/silicon/robot/drone/heal_overall_damage(brute, burn, updating_health = TRUE)
|
||||
|
||||
bruteloss -= brute
|
||||
fireloss -= burn
|
||||
|
||||
if(bruteloss<0) bruteloss = 0
|
||||
if(fireloss<0) fireloss = 0
|
||||
if(updating_health)
|
||||
updatehealth("heal overall damage")
|
||||
|
||||
/mob/living/silicon/robot/drone/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0)
|
||||
take_overall_damage(brute,burn)
|
||||
/mob/living/silicon/robot/drone/take_organ_damage(brute, burn, updating_health = TRUE, sharp = 0)
|
||||
take_overall_damage(brute,burn, updating_health, null, sharp)
|
||||
|
||||
/mob/living/silicon/robot/drone/heal_organ_damage(var/brute, var/burn)
|
||||
heal_overall_damage(brute,burn)
|
||||
/mob/living/silicon/robot/drone/heal_organ_damage(brute, burn, updating_health = TRUE)
|
||||
heal_overall_damage(brute,burn, updating_health)
|
||||
|
||||
/mob/living/silicon/robot/drone/getFireLoss()
|
||||
return fireloss
|
||||
|
||||
/mob/living/silicon/robot/drone/getBruteLoss()
|
||||
return bruteloss
|
||||
return bruteloss
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//Easiest to check this here, then check again in the robot proc.
|
||||
//Standard robots use config for crit, which is somewhat excessive for these guys.
|
||||
//Drones killed by damage will gib.
|
||||
/mob/living/silicon/robot/drone/update_stat()
|
||||
/mob/living/silicon/robot/drone/update_stat(reason = "none given")
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
if(health <= -35 && stat != DEAD)
|
||||
gib()
|
||||
create_debug_log("died of damage, trigger reason: [reason]")
|
||||
return
|
||||
return ..()
|
||||
return ..(reason)
|
||||
|
||||
@@ -21,22 +21,22 @@
|
||||
|
||||
/mob/living/silicon/robot/proc/handle_robot_cell()
|
||||
if(stat != DEAD)
|
||||
if(!is_component_functioning("power cell") || !cell)
|
||||
Paralyse(2)
|
||||
if(!is_component_functioning("power cell"))
|
||||
uneq_all()
|
||||
low_power_mode = 1
|
||||
update_headlamp()
|
||||
diag_hud_set_borgcell()
|
||||
return
|
||||
if(low_power_mode)
|
||||
if(is_component_functioning("power cell") && cell && cell.charge)
|
||||
if(is_component_functioning("power cell") && cell.charge)
|
||||
low_power_mode = 0
|
||||
update_headlamp()
|
||||
else if(stat == CONSCIOUS)
|
||||
use_power()
|
||||
|
||||
/mob/living/silicon/robot/proc/use_power()
|
||||
if(is_component_functioning("power cell") && cell && cell.charge)
|
||||
// this check is safe because `cell` is guaranteed to be set when the power cell is functioning
|
||||
if(is_component_functioning("power cell") && cell.charge)
|
||||
if(cell.charge <= 100)
|
||||
uneq_all()
|
||||
var/amt = Clamp((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell.
|
||||
@@ -57,22 +57,10 @@
|
||||
else
|
||||
camera.status = 1
|
||||
|
||||
if(getOxyLoss() > 50)
|
||||
Paralyse(3)
|
||||
|
||||
if(sleeping)
|
||||
Paralyse(3)
|
||||
AdjustSleeping(-1)
|
||||
|
||||
if(resting)
|
||||
Weaken(5)
|
||||
|
||||
if(.) //alive
|
||||
if(health <= config.health_threshold_dead)
|
||||
death()
|
||||
diag_hud_set_status()
|
||||
return
|
||||
|
||||
if(!istype(src, /mob/living/silicon/robot/drone))
|
||||
if(health < 50) //Gradual break down of modules as more damage is sustained
|
||||
if(uneq_module(module_state_3))
|
||||
@@ -86,19 +74,8 @@
|
||||
if(uneq_module(module_state_1))
|
||||
to_chat(src, "<span class='warning'>CRITICAL ERROR: All modules OFFLINE.</span>")
|
||||
|
||||
if(paralysis || stunned || weakened)
|
||||
stat = UNCONSCIOUS
|
||||
|
||||
if(!paralysis > 0)
|
||||
SetEyeBlind(0)
|
||||
|
||||
else
|
||||
stat = CONSCIOUS
|
||||
|
||||
diag_hud_set_health()
|
||||
diag_hud_set_status()
|
||||
else //dead
|
||||
SetEyeBlind(0)
|
||||
|
||||
//update the state of modules and components here
|
||||
if(stat != CONSCIOUS)
|
||||
@@ -109,14 +86,6 @@
|
||||
else
|
||||
radio.on = 1
|
||||
|
||||
if(is_component_functioning("camera") && stat == CONSCIOUS)
|
||||
blinded = 0
|
||||
else
|
||||
blinded = 1
|
||||
|
||||
if(!is_component_functioning("actuator"))
|
||||
Paralyse(3)
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/robot/update_sight()
|
||||
@@ -234,7 +203,7 @@
|
||||
weaponlock_time = 120
|
||||
|
||||
/mob/living/silicon/robot/update_canmove(delay_action_updates = 0)
|
||||
if(paralysis || stunned || weakened || buckled || lockcharge)
|
||||
if(paralysis || stunned || weakened || buckled || lockcharge || stat)
|
||||
canmove = 0
|
||||
else
|
||||
canmove = 1
|
||||
|
||||
@@ -477,12 +477,8 @@ var/list/robot_verbs_default = list(
|
||||
return
|
||||
|
||||
var/datum/robot_component/C = components[toggle]
|
||||
if(C.toggled)
|
||||
C.toggled = 0
|
||||
to_chat(src, "<span class='warning'>You disable [C.name].</span>")
|
||||
else
|
||||
C.toggled = 1
|
||||
to_chat(src, "<span class='warning'>You enable [C.name].</span>")
|
||||
C.toggle()
|
||||
to_chat(src, "<span class='warning'>You [C.toggled ? "enable" : "disable"] [C.name].</span>")
|
||||
|
||||
/mob/living/silicon/robot/proc/sensor_mode()
|
||||
set name = "Set Sensor Augmentation"
|
||||
@@ -528,9 +524,8 @@ var/list/robot_verbs_default = list(
|
||||
thruster_button.icon_state = "ionpulse[ionpulse_on]"
|
||||
|
||||
/mob/living/silicon/robot/blob_act()
|
||||
if(stat != 2)
|
||||
if(stat != DEAD)
|
||||
adjustBruteLoss(60)
|
||||
updatehealth()
|
||||
return 1
|
||||
else
|
||||
gib()
|
||||
@@ -573,7 +568,6 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/robot/bullet_act(var/obj/item/projectile/Proj)
|
||||
..(Proj)
|
||||
updatehealth()
|
||||
if(prob(75) && Proj.damage > 0) spark_system.start()
|
||||
return 2
|
||||
|
||||
@@ -609,7 +603,6 @@ var/list/robot_verbs_default = list(
|
||||
if(WT.remove_fuel(0))
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
adjustBruteLoss(-30)
|
||||
updatehealth()
|
||||
add_fingerprint(user)
|
||||
user.visible_message("<span class='alert'>\The [user] patches some dents on \the [src] with \the [WT].</span>")
|
||||
else
|
||||
@@ -1259,7 +1252,9 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/robot/adjustOxyLoss(var/amount)
|
||||
if(suiciding)
|
||||
..()
|
||||
return ..()
|
||||
else
|
||||
return STATUS_UPDATE_NONE
|
||||
|
||||
/mob/living/silicon/robot/regenerate_icons()
|
||||
..()
|
||||
@@ -1439,6 +1434,7 @@ var/list/robot_verbs_default = list(
|
||||
disable_component("comms", 160)
|
||||
if(2)
|
||||
disable_component("comms", 60)
|
||||
|
||||
/mob/living/silicon/robot/rejuvenate()
|
||||
..()
|
||||
var/brute = 1000
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
/mob/living/silicon/robot/updatehealth()
|
||||
/mob/living/silicon/robot/updatehealth(reason = "none given")
|
||||
if(status_flags & GODMODE)
|
||||
health = maxHealth
|
||||
stat = CONSCIOUS
|
||||
return
|
||||
health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss())
|
||||
if(stat == DEAD && health > 0)
|
||||
update_revive()
|
||||
var/mob/dead/observer/ghost = get_ghost()
|
||||
if(ghost)
|
||||
to_chat(ghost, "<span class='ghostalert'>Your cyborg shell has been repaired, re-enter if you want to continue!</span> (Verbs -> Ghost -> Re-enter corpse)")
|
||||
ghost << sound('sound/effects/genetics.ogg')
|
||||
return
|
||||
|
||||
update_stat("updatehealth([reason])")
|
||||
handle_hud_icons_health()
|
||||
diag_hud_set_health()
|
||||
|
||||
/mob/living/silicon/robot/getBruteLoss()
|
||||
var/amount = 0
|
||||
@@ -27,17 +22,19 @@
|
||||
if(C.installed != 0) amount += C.electronics_damage
|
||||
return amount
|
||||
|
||||
/mob/living/silicon/robot/adjustBruteLoss(var/amount)
|
||||
/mob/living/silicon/robot/adjustBruteLoss(amount, updating_health = TRUE)
|
||||
if(amount > 0)
|
||||
take_overall_damage(amount, 0)
|
||||
take_overall_damage(amount, 0, updating_health)
|
||||
else
|
||||
heal_overall_damage(-amount, 0)
|
||||
heal_overall_damage(-amount, 0, updating_health)
|
||||
return STATUS_UPDATE_HEALTH
|
||||
|
||||
/mob/living/silicon/robot/adjustFireLoss(var/amount)
|
||||
/mob/living/silicon/robot/adjustFireLoss(amount, updating_health = TRUE)
|
||||
if(amount > 0)
|
||||
take_overall_damage(0, amount)
|
||||
take_overall_damage(0, amount, updating_health)
|
||||
else
|
||||
heal_overall_damage(0, -amount)
|
||||
heal_overall_damage(0, -amount, updating_health)
|
||||
return STATUS_UPDATE_HEALTH
|
||||
|
||||
/mob/living/silicon/robot/proc/get_damaged_components(var/brute, var/burn, var/get_all)
|
||||
var/list/datum/robot_component/parts = list()
|
||||
@@ -62,13 +59,13 @@
|
||||
return C
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/heal_organ_damage(var/brute, var/burn)
|
||||
/mob/living/silicon/robot/heal_organ_damage(brute, burn, updating_health = TRUE)
|
||||
var/list/datum/robot_component/parts = get_damaged_components(brute,burn)
|
||||
if(!parts.len) return
|
||||
var/datum/robot_component/picked = pick(parts)
|
||||
picked.heal_damage(brute,burn)
|
||||
picked.heal_damage(brute,burn, updating_health)
|
||||
|
||||
/mob/living/silicon/robot/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/edge = 0)
|
||||
/mob/living/silicon/robot/take_organ_damage(brute = 0, burn = 0, updating_health = TRUE, sharp = 0, edge = 0)
|
||||
var/list/components = get_damageable_components()
|
||||
if(!components.len)
|
||||
return
|
||||
@@ -98,13 +95,13 @@
|
||||
|
||||
var/datum/robot_component/armour/A = get_armour()
|
||||
if(A)
|
||||
A.take_damage(brute, burn, sharp)
|
||||
A.take_damage(brute, burn, sharp, updating_health)
|
||||
return
|
||||
|
||||
var/datum/robot_component/C = pick(components)
|
||||
C.take_damage(brute, burn, sharp)
|
||||
C.take_damage(brute, burn, sharp, updating_health)
|
||||
|
||||
/mob/living/silicon/robot/heal_overall_damage(var/brute, var/burn)
|
||||
/mob/living/silicon/robot/heal_overall_damage(var/brute, var/burn, updating_health = TRUE)
|
||||
var/list/datum/robot_component/parts = get_damaged_components(brute,burn)
|
||||
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
@@ -113,14 +110,14 @@
|
||||
var/brute_was = picked.brute_damage
|
||||
var/burn_was = picked.electronics_damage
|
||||
|
||||
picked.heal_damage(brute,burn)
|
||||
picked.heal_damage(brute,burn, updating_health)
|
||||
|
||||
brute -= (brute_was-picked.brute_damage)
|
||||
burn -= (burn_was-picked.electronics_damage)
|
||||
|
||||
parts -= picked
|
||||
|
||||
/mob/living/silicon/robot/take_overall_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/used_weapon = null)
|
||||
/mob/living/silicon/robot/take_overall_damage(brute = 0, burn = 0, updating_health = TRUE, used_weapon = null, sharp = 0)
|
||||
if(status_flags & GODMODE) return //godmode
|
||||
var/list/datum/robot_component/parts = get_damageable_components()
|
||||
|
||||
@@ -158,9 +155,10 @@
|
||||
var/brute_was = picked.brute_damage
|
||||
var/burn_was = picked.electronics_damage
|
||||
|
||||
picked.take_damage(brute, burn)
|
||||
picked.take_damage(brute, burn, sharp, FALSE)
|
||||
|
||||
brute -= (picked.brute_damage - brute_was)
|
||||
burn -= (picked.electronics_damage - burn_was)
|
||||
|
||||
parts -= picked
|
||||
updatehealth()
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
damage = rand(5, 35)
|
||||
damage = round(damage / 2) // borgs recieve half damage
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/attack_hand(mob/living/carbon/human/user)
|
||||
@@ -47,7 +46,7 @@
|
||||
user.put_in_active_hand(cell)
|
||||
to_chat(user, "<span class='notice'>You remove \the [cell].</span>")
|
||||
cell = null
|
||||
update_icons()
|
||||
update_stat()
|
||||
diag_hud_set_borgcell()
|
||||
|
||||
if(!opened)
|
||||
|
||||
@@ -106,7 +106,10 @@
|
||||
|
||||
// Return true in an overridden subtype to prevent normal removal handling
|
||||
/obj/item/robot_module/proc/handle_custom_removal(component_id, mob/living/user, obj/item/W, params)
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/obj/item/robot_module/proc/handle_death(gibbed)
|
||||
return
|
||||
|
||||
/obj/item/robot_module/standard
|
||||
name = "standard robot module"
|
||||
@@ -217,6 +220,11 @@
|
||||
|
||||
fix_modules()
|
||||
|
||||
/obj/item/robot_module/engineering/handle_death()
|
||||
var/obj/item/gripper/G = locate(/obj/item/gripper) in modules
|
||||
if(G)
|
||||
G.drop_item()
|
||||
|
||||
/obj/item/robot_module/security
|
||||
name = "security robot module"
|
||||
module_type = "Security"
|
||||
@@ -530,6 +538,12 @@
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/robot_module/drone/handle_death()
|
||||
var/obj/item/gripper/G = locate(/obj/item/gripper) in modules
|
||||
if(G)
|
||||
G.drop_item()
|
||||
|
||||
//checks whether this item is a module of the robot it is located in.
|
||||
/obj/item/proc/is_robot_module()
|
||||
if(!istype(loc, /mob/living/silicon/robot))
|
||||
|
||||
@@ -3,19 +3,38 @@
|
||||
if(stat || lockcharge || weakened || stunned || paralysis || !is_component_functioning("actuator"))
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/robot/update_stat()
|
||||
/mob/living/silicon/robot/has_vision(information_only = FALSE)
|
||||
return ..(information_only) && ((stat == DEAD && information_only) || is_component_functioning("camera"))
|
||||
|
||||
/mob/living/silicon/robot/update_stat(reason = "none given")
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
if(stat != DEAD)
|
||||
if(health <= -maxHealth) //die only once
|
||||
death()
|
||||
create_debug_log("died of damage, trigger reason: [reason]")
|
||||
return
|
||||
if(!is_component_functioning("actuator") || paralysis || sleeping || stunned || weakened || getOxyLoss() > maxHealth * 0.5)
|
||||
if(!is_component_functioning("actuator") || !is_component_functioning("power cell") || paralysis || sleeping || resting || stunned || weakened || getOxyLoss() > maxHealth * 0.5)
|
||||
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]")
|
||||
else
|
||||
if(health > 0)
|
||||
update_revive()
|
||||
var/mob/dead/observer/ghost = get_ghost()
|
||||
if(ghost)
|
||||
to_chat(ghost, "<span class='ghostalert'>Your cyborg shell has been repaired, re-enter if you want to continue!</span> (Verbs -> Ghost -> Re-enter corpse)")
|
||||
ghost << sound('sound/effects/genetics.ogg')
|
||||
create_attack_log("revived, trigger reason: [reason]")
|
||||
// diag_hud_set_status()
|
||||
// diag_hud_set_health()
|
||||
// update_health_hud()
|
||||
|
||||
/mob/living/silicon/robot/update_revive(updating = TRUE)
|
||||
. = ..(updating)
|
||||
if(.)
|
||||
update_icons()
|
||||
|
||||
@@ -317,7 +317,7 @@
|
||||
to_chat(src, "[A.alarm_name()]! ([(cameratext)? cameratext : "No Camera"])")
|
||||
|
||||
/mob/living/silicon/adjustToxLoss(var/amount)
|
||||
return
|
||||
return STATUS_UPDATE_NONE
|
||||
|
||||
/mob/living/silicon/get_access()
|
||||
return IGNORE_ACCESS //silicons always have access
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user