Merge remote-tracking branch 'upstream/master' into tgui4.0-and-camera-console

This commit is contained in:
ShadowLarkens
2020-08-06 21:29:47 -07:00
247 changed files with 5334 additions and 1793 deletions

View File

@@ -48,6 +48,9 @@ Pipelines + Other Objects -> Pipe network
pipe_color = null pipe_color = null
init_dir() init_dir()
/obj/machinery/atmospherics/examine_icon()
return icon(icon=initial(icon),icon_state=initial(icon_state))
// This is used to set up what directions pipes will connect to. Should be called inside New() and whenever a dir changes. // This is used to set up what directions pipes will connect to. Should be called inside New() and whenever a dir changes.
/obj/machinery/atmospherics/proc/init_dir() /obj/machinery/atmospherics/proc/init_dir()
return return

View File

@@ -116,6 +116,8 @@ What is the naming convention for planes or layers?
#define HUD_LAYER 20 // Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots) #define HUD_LAYER 20 // Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots)
#define SCREEN_LAYER 22 // Mob HUD/effects layer #define SCREEN_LAYER 22 // Mob HUD/effects layer
#define PLANE_STATUS 2 //Status Indicators that show over mobs' heads when certain things like stuns affect them.
#define PLANE_ADMIN1 3 //Purely for shenanigans (below lighting) #define PLANE_ADMIN1 3 //Purely for shenanigans (below lighting)
#define PLANE_PLANETLIGHTING 4 //Lighting on planets #define PLANE_PLANETLIGHTING 4 //Lighting on planets
#define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives #define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives
@@ -138,8 +140,6 @@ What is the naming convention for planes or layers?
#define PLANE_MESONS 30 //Stuff seen with mesons, like open ceilings. This is 30 for downstreams. #define PLANE_MESONS 30 //Stuff seen with mesons, like open ceilings. This is 30 for downstreams.
#define PLANE_STATUS 31 //Status Indicators that show over mobs' heads when certain things like stuns affect them.
#define PLANE_ADMIN2 33 //Purely for shenanigans (above lighting) #define PLANE_ADMIN2 33 //Purely for shenanigans (above lighting)
#define PLANE_BUILDMODE 39 //Things that only show up when you have buildmode on #define PLANE_BUILDMODE 39 //Things that only show up when you have buildmode on

View File

@@ -430,4 +430,6 @@
#define EXAMINE_SKIPLEGS 0x0080 #define EXAMINE_SKIPLEGS 0x0080
#define EXAMINE_SKIPFEET 0x0100 #define EXAMINE_SKIPFEET 0x0100
#define MAX_NUTRITION 500 #define MAX_NUTRITION 500
#define FAKE_INVIS_ALPHA_THRESHOLD 127 // If something's alpha var is at or below this number, certain things will pretend it is invisible.

View File

@@ -40,4 +40,12 @@
#define CATALOGUER_REWARD_SUPERHARD 2560 // Very difficult and dangerous, such as scanning the Advanced Dark Gygax. #define CATALOGUER_REWARD_SUPERHARD 2560 // Very difficult and dangerous, such as scanning the Advanced Dark Gygax.
// 5 10 20 40 80 160 // 5 10 20 40 80 160
// 10 40 160 640 2560 // 10 40 160 640 2560
// Defines for Exosuit components.
#define MECH_HULL "Hull"
#define MECH_ACTUATOR "Actuator"
#define MECH_ARMOR "Plating"
#define MECH_GAS "Life Support"
#define MECH_ELECTRIC "Firmware"

View File

@@ -123,8 +123,7 @@
'sound/ambience/maintenance/maintenance2.ogg',\ 'sound/ambience/maintenance/maintenance2.ogg',\
'sound/ambience/maintenance/maintenance3.ogg',\ 'sound/ambience/maintenance/maintenance3.ogg',\
'sound/ambience/maintenance/maintenance4.ogg',\ 'sound/ambience/maintenance/maintenance4.ogg',\
'sound/ambience/maintenance/maintenance5.ogg',\ 'sound/ambience/maintenance/maintenance5.ogg'\
'sound/ambience/maintenance/maintenance6.ogg'\
) )
// Life support machinery at work, keeping everyone breathing. // Life support machinery at work, keeping everyone breathing.
@@ -154,7 +153,11 @@
// Concerning sounds, for when one discovers something horrible happened in a PoI. // Concerning sounds, for when one discovers something horrible happened in a PoI.
#define AMBIENCE_FOREBODING list(\ #define AMBIENCE_FOREBODING list(\
'sound/ambience/foreboding/foreboding1.ogg',\ 'sound/ambience/foreboding/foreboding1.ogg',\
'sound/ambience/foreboding/foreboding2.ogg'\ 'sound/ambience/foreboding/foreboding2.ogg',\
'sound/ambience/foreboding/foreboding3.ogg',\
'sound/ambience/foreboding/foreboding4.ogg',\
'sound/ambience/foreboding/foreboding5.ogg',\
'sound/ambience/foreboding/foreboding6.ogg'\
) )
// Ambience heard when aboveground on Sif and not in a Point of Interest. // Ambience heard when aboveground on Sif and not in a Point of Interest.

View File

@@ -27,6 +27,9 @@ var/list/mannequins_
// Closets have magic appearances // Closets have magic appearances
GLOBAL_LIST_EMPTY(closet_appearances) GLOBAL_LIST_EMPTY(closet_appearances)
// Times that players are allowed to respawn ("ckey" = world.time)
GLOBAL_LIST_EMPTY(respawn_timers)
// Posters // Posters
var/global/list/poster_designs = list() var/global/list/poster_designs = list()
var/global/list/NT_poster_designs = list() var/global/list/NT_poster_designs = list()

View File

@@ -107,7 +107,7 @@ AngleToHue(hue)
Converts an angle to a hue in the valid range. Converts an angle to a hue in the valid range.
RotateHue(hsv, angle) RotateHue(hsv, angle)
Takes an HSV or HSVA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360. Takes an HSV or HSVA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360.
(Rotating red by 60<EFBFBD> produces yellow.) The result is another HSV or HSVA color with the same saturation and value (Rotating red by 60deg produces yellow.) The result is another HSV or HSVA color with the same saturation and value
as the original, but a different hue. as the original, but a different hue.
GrayScale(rgb) GrayScale(rgb)
Takes an RGB or RGBA color and converts it to grayscale. Returns an RGB or RGBA string. Takes an RGB or RGBA color and converts it to grayscale. Returns an RGB or RGBA string.
@@ -679,7 +679,7 @@ proc/ColorTone(rgb, tone)
var/curstate = A.icon_state || defstate var/curstate = A.icon_state || defstate
if(!((noIcon = (!curicon)))) if(!((noIcon = (!curicon))))
var/curstates = icon_states(curicon) var/curstates = cached_icon_states(curicon)
if(!(curstate in curstates)) if(!(curstate in curstates))
if("" in curstates) if("" in curstates)
curstate = "" curstate = ""
@@ -689,19 +689,16 @@ proc/ColorTone(rgb, tone)
var/curdir var/curdir
var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have
//These should use the parent's direction (most likely) // Use the requested dir or the atom's current dir
if(!A.dir || A.dir == SOUTH) curdir = defdir || A.dir
curdir = defdir
else
curdir = A.dir
//Try to remove/optimize this section ASAP, CPU hog. //Try to remove/optimize this section ASAP, CPU hog. //Slightly mitigated by implementing caching using cached_icon_states
//Determines if there's directionals. //Determines if there's directionals.
if(!noIcon && curdir != SOUTH) if(!noIcon && curdir != SOUTH)
var/exist = FALSE var/exist = FALSE
var/static/list/checkdirs = list(NORTH, EAST, WEST) var/static/list/checkdirs = list(NORTH, EAST, WEST)
for(var/i in checkdirs) //Not using GLOB for a reason. for(var/i in checkdirs) //Not using GLOB for a reason.
if(length(icon_states(icon(curicon, curstate, i)))) if(length(cached_icon_states(icon(curicon, curstate, i))))
exist = TRUE exist = TRUE
break break
if(!exist) if(!exist)
@@ -739,8 +736,8 @@ proc/ColorTone(rgb, tone)
continue continue
var/current_layer = current.layer var/current_layer = current.layer
if(current_layer < 0) if(current_layer < 0)
if(current_layer <= -1000) //if(current_layer <= -1000)
return flat //return flat
current_layer = process_set + A.layer + current_layer / 1000 current_layer = process_set + A.layer + current_layer / 1000
for(var/p in 1 to layers.len) for(var/p in 1 to layers.len)
@@ -768,7 +765,7 @@ proc/ColorTone(rgb, tone)
curblend = BLEND_OVERLAY curblend = BLEND_OVERLAY
add = icon(I.icon, I.icon_state, base_icon_dir) add = icon(I.icon, I.icon_state, base_icon_dir)
else // 'I' is an appearance object. else // 'I' is an appearance object.
add = getFlatIcon(image(I), curdir, curicon, curstate, curblend, FALSE, no_anim) add = getFlatIcon(image(I), I.dir||curdir, curicon, curstate, curblend, FALSE, no_anim)
if(!add) if(!add)
continue continue
// Find the new dimensions of the flat icon to fit the added overlay // Find the new dimensions of the flat icon to fit the added overlay
@@ -897,6 +894,37 @@ proc/ColorTone(rgb, tone)
composite.Blend(icon(I.icon, I.icon_state, I.dir, 1), ICON_OVERLAY) composite.Blend(icon(I.icon, I.icon_state, I.dir, 1), ICON_OVERLAY)
return composite return composite
GLOBAL_LIST_EMPTY(icon_state_lists)
/proc/cached_icon_states(var/icon/I)
if(!I)
return list()
var/key = I
var/returnlist = GLOB.icon_state_lists[key]
if(!returnlist)
returnlist = icon_states(I)
if(isfile(I)) // It's something that will stick around
GLOB.icon_state_lists[key] = returnlist
return returnlist
/proc/expire_states_cache(var/key)
if(GLOB.icon_state_lists[key])
GLOB.icon_state_lists -= key
return TRUE
return FALSE
GLOBAL_LIST_EMPTY(cached_examine_icons)
/proc/set_cached_examine_icon(var/atom/A, var/icon/I, var/expiry = 12000)
GLOB.cached_examine_icons[weakref(A)] = I
if(expiry)
addtimer(CALLBACK(GLOBAL_PROC, .proc/uncache_examine_icon, weakref(A)), expiry, TIMER_UNIQUE)
/proc/get_cached_examine_icon(var/atom/A)
var/weakref/WR = weakref(A)
return GLOB.cached_examine_icons[WR]
/proc/uncache_examine_icon(var/weakref/WR)
GLOB.cached_examine_icons -= WR
proc/adjust_brightness(var/color, var/value) proc/adjust_brightness(var/color, var/value)
if (!color) return "#FFFFFF" if (!color) return "#FFFFFF"
if (!value) return color if (!value) return color

View File

@@ -94,7 +94,7 @@ proc/age2agedescription(age)
else return "unknown" else return "unknown"
/proc/RoundHealth(health) /proc/RoundHealth(health)
var/list/icon_states = icon_states(ingame_hud_med) var/list/icon_states = cached_icon_states(ingame_hud_med)
for(var/icon_state in icon_states) for(var/icon_state in icon_states)
if(health >= text2num(icon_state)) if(health >= text2num(icon_state))
return icon_state return icon_state

View File

@@ -75,8 +75,9 @@
#define ui_ai_pda_log "SOUTH:6,WEST+11:16" #define ui_ai_pda_log "SOUTH:6,WEST+11:16"
#define ui_ai_take_picture "SOUTH:6,WEST+12:16" #define ui_ai_take_picture "SOUTH:6,WEST+12:16"
#define ui_ai_view_images "SOUTH:6,WEST+13:16" #define ui_ai_view_images "SOUTH:6,WEST+13:16"
#define ui_ai_multicam "SOUTH+1:6,WEST+13" #define ui_ai_multicam "SOUTH+1:6,WEST+11:16"
#define ui_ai_add_multicam "SOUTH+1:6,WEST+14" #define ui_ai_add_multicam "SOUTH+1:6,WEST+12:16"
#define ui_ai_updown "SOUTH+1:6,WEST+13:16"
//Upper-middle right (alerts) //Upper-middle right (alerts)
#define ui_alert1 "EAST-1:28,CENTER+5:27" #define ui_alert1 "EAST-1:28,CENTER+5:27"
@@ -150,3 +151,32 @@
#define ui_spell_master "EAST-2:16,NORTH-1:26" #define ui_spell_master "EAST-2:16,NORTH-1:26"
#define ui_genetic_master "EAST-1:16,NORTH-3:16" #define ui_genetic_master "EAST-1:16,NORTH-3:16"
// Ghost ones
#define ui_ghost_returntomenu "SOUTH:6,CENTER-3:24"
#define ui_ghost_jumptomob "SOUTH:6,CENTER-2:24"
#define ui_ghost_orbit "SOUTH:6,CENTER-1:24"
#define ui_ghost_reenter_corpse "SOUTH:6,CENTER:24"
#define ui_ghost_teleport "SOUTH:6,CENTER+1:24"
#define ui_ghost_pai "SOUTH: 6,CENTER+2:24"
#define ui_ghost_updown "SOUTH: 6,CENTER+3:24"
// Rig panel
#define ui_rig_deco1 "WEST:-7, SOUTH+5"
#define ui_rig_deco2 "WEST:-7, SOUTH+6"
#define ui_rig_pwr "WEST+1:-7, SOUTH+6"
#define ui_rig_health "WEST+1:-7, SOUTH+6"
#define ui_rig_air "WEST+1:-7, SOUTH+5"
#define ui_rig_airtoggle "WEST+1:-7, SOUTH+5"
#define ui_rig_deco1_f "WEST+2:-7, SOUTH+5"
#define ui_rig_deco2_f "WEST+2:-7, SOUTH+6"
// Mech panel
#define ui_mech_deco1 "WEST:-7, SOUTH+8"
#define ui_mech_deco2 "WEST:-7, SOUTH+9"
#define ui_mech_pwr "WEST+1:-7, SOUTH+9"
#define ui_mech_health "WEST+1:-7, SOUTH+9"
#define ui_mech_air "WEST+1:-7, SOUTH+8"
#define ui_mech_airtoggle "WEST+1:-7, SOUTH+8"
#define ui_mech_deco1_f "WEST+2:-7, SOUTH+8"
#define ui_mech_deco2_f "WEST+2:-7, SOUTH+9"

View File

@@ -1,169 +1,195 @@
/obj/screen/ai/multicam
name = "Multicamera Mode"
icon = 'icons/mob/screen_ai.dmi'
icon_state = "multicam"
/obj/screen/ai/multicam/Click() /obj/screen/ai/multicam/Click()
if(..()) if(..())
return return
var/mob/living/silicon/ai/AI = usr var/mob/living/silicon/ai/AI = usr
AI.toggle_multicam() AI.toggle_multicam()
/obj/screen/ai/add_multicam
name = "New Camera"
icon = 'icons/mob/screen_ai.dmi'
icon_state = "new_cam"
/obj/screen/ai/add_multicam/Click() /obj/screen/ai/add_multicam/Click()
if(..()) if(..())
return return
var/mob/living/silicon/ai/AI = usr var/mob/living/silicon/ai/AI = usr
AI.drop_new_multicam() AI.drop_new_multicam()
/datum/hud/proc/ai_hud() /obj/screen/ai/up/Click()
adding = list() var/mob/living/silicon/ai/AI = usr
other = list() AI.zMove(UP)
/obj/screen/ai/down/Click()
var/mob/living/silicon/ai/AI = usr
AI.zMove(DOWN)
/mob/living/silicon/ai/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
..()
HUD.ui_style = 'icons/mob/screen_ai.dmi'
HUD.adding = list()
HUD.other = list()
var/obj/screen/using var/obj/screen/using
//AI core //AI core
using = new /obj/screen() using = new /obj/screen()
using.name = "AI Core" using.name = "AI Core"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "ai_core" using.icon_state = "ai_core"
using.screen_loc = ui_ai_core using.screen_loc = ui_ai_core
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Camera list //Camera list
using = new /obj/screen() using = new /obj/screen()
using.name = "Show Camera List" using.name = "Show Camera List"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "camera" using.icon_state = "camera"
using.screen_loc = ui_ai_camera_list using.screen_loc = ui_ai_camera_list
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Track //Track
using = new /obj/screen() using = new /obj/screen()
using.name = "Track With Camera" using.name = "Track With Camera"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "track" using.icon_state = "track"
using.screen_loc = ui_ai_track_with_camera using.screen_loc = ui_ai_track_with_camera
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Camera light //Camera light
using = new /obj/screen() using = new /obj/screen()
using.name = "Toggle Camera Light" using.name = "Toggle Camera Light"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "camera_light" using.icon_state = "camera_light"
using.screen_loc = ui_ai_camera_light using.screen_loc = ui_ai_camera_light
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Crew Monitoring //Crew Monitoring
using = new /obj/screen() using = new /obj/screen()
using.name = "Crew Monitoring" using.name = "Crew Monitoring"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "crew_monitor" using.icon_state = "crew_monitor"
using.screen_loc = ui_ai_crew_monitor using.screen_loc = ui_ai_crew_monitor
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Crew Manifest //Crew Manifest
using = new /obj/screen() using = new /obj/screen()
using.name = "Show Crew Manifest" using.name = "Show Crew Manifest"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "manifest" using.icon_state = "manifest"
using.screen_loc = ui_ai_crew_manifest using.screen_loc = ui_ai_crew_manifest
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Alerts //Alerts
using = new /obj/screen() using = new /obj/screen()
using.name = "Show Alerts" using.name = "Show Alerts"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "alerts" using.icon_state = "alerts"
using.screen_loc = ui_ai_alerts using.screen_loc = ui_ai_alerts
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Announcement //Announcement
using = new /obj/screen() using = new /obj/screen()
using.name = "Announcement" using.name = "Announcement"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "announcement" using.icon_state = "announcement"
using.screen_loc = ui_ai_announcement using.screen_loc = ui_ai_announcement
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Shuttle //Shuttle
using = new /obj/screen() using = new /obj/screen()
using.name = "Call Emergency Shuttle" using.name = "Call Emergency Shuttle"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "call_shuttle" using.icon_state = "call_shuttle"
using.screen_loc = ui_ai_shuttle using.screen_loc = ui_ai_shuttle
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Laws //Laws
using = new /obj/screen() using = new /obj/screen()
using.name = "State Laws" using.name = "State Laws"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "state_laws" using.icon_state = "state_laws"
using.screen_loc = ui_ai_state_laws using.screen_loc = ui_ai_state_laws
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//PDA message //PDA message
using = new /obj/screen() using = new /obj/screen()
using.name = "PDA - Send Message" using.name = "PDA - Send Message"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "pda_send" using.icon_state = "pda_send"
using.screen_loc = ui_ai_pda_send using.screen_loc = ui_ai_pda_send
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//PDA log //PDA log
using = new /obj/screen() using = new /obj/screen()
using.name = "PDA - Show Message Log" using.name = "PDA - Show Message Log"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "pda_receive" using.icon_state = "pda_receive"
using.screen_loc = ui_ai_pda_log using.screen_loc = ui_ai_pda_log
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Take image //Take image
using = new /obj/screen() using = new /obj/screen()
using.name = "Take Image" using.name = "Take Image"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "take_picture" using.icon_state = "take_picture"
using.screen_loc = ui_ai_take_picture using.screen_loc = ui_ai_take_picture
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//View images //View images
using = new /obj/screen() using = new /obj/screen()
using.name = "View Images" using.name = "View Images"
using.icon = 'icons/mob/screen_ai.dmi' using.icon = HUD.ui_style
using.icon_state = "view_images" using.icon_state = "view_images"
using.screen_loc = ui_ai_view_images using.screen_loc = ui_ai_view_images
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using HUD.adding += using
//Multicamera mode //Multicamera mode
using = new /obj/screen/ai/multicam() using = new /obj/screen/ai/multicam() // special
using.screen_loc = ui_ai_multicam using.name = "Multicamera Mode"
adding += using using.icon = HUD.ui_style
using.icon_state = "multicam"
using.screen_loc = ui_ai_multicam
using.layer = SCREEN_LAYER
HUD.adding += using
//Add multicamera camera //Add multicamera camera
using = new /obj/screen/ai/add_multicam() using = new /obj/screen/ai/add_multicam() // special
using.screen_loc = ui_ai_add_multicam using.name = "New Camera"
adding += using using.icon = HUD.ui_style
using.icon_state = "new_cam"
mymob.client.screen = list() using.screen_loc = ui_ai_add_multicam
mymob.client.screen += adding + other using.layer = SCREEN_LAYER
mymob.client.screen += mymob.client.void HUD.adding += using
return //Up and Down
using = new /obj/screen/ai/up() // special
using.name = "Move Upwards"
using.icon = HUD.ui_style
using.icon_state = "up"
using.screen_loc = ui_ai_updown
using.layer = SCREEN_LAYER
HUD.adding += using
using = new /obj/screen/ai/down() // special
using.name = "Move Downwards"
using.icon = HUD.ui_style
using.icon_state = "down"
using.screen_loc = ui_ai_updown
using.layer = SCREEN_LAYER
HUD.adding += using
if(client && apply_to_client)
client.screen = list()
client.screen += HUD.adding + HUD.other
client.screen += client.void

View File

@@ -36,14 +36,10 @@
alert = new type alert = new type
if(new_master) if(new_master)
var/old_layer = new_master.layer alert.icon_state = "itembased"
var/old_plane = new_master.plane var/image/I = image(icon = new_master.icon, icon_state = new_master.icon_state, dir = SOUTH)
new_master.layer = LAYER_HUD_ABOVE I.plane = PLANE_PLAYER_HUD_ABOVE
new_master.plane = PLANE_PLAYER_HUD_ABOVE alert.add_overlay(I)
alert.overlays += new_master
new_master.layer = old_layer
new_master.plane = old_plane
alert.icon_state = "template" // We'll set the icon to the client's ui pref in reorganize_alerts()
alert.master = new_master alert.master = new_master
else else
alert.icon_state = "[initial(alert.icon_state)][severity]" alert.icon_state = "[initial(alert.icon_state)][severity]"
@@ -85,6 +81,7 @@
var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds
var/severity = 0 var/severity = 0
var/alerttooltipstyle = "" var/alerttooltipstyle = ""
var/no_underlay // Don't underlay the UI style's blank template icon under this
/obj/screen/alert/MouseEntered(location,control,params) /obj/screen/alert/MouseEntered(location,control,params)
@@ -226,6 +223,26 @@ The box in your backpack has an oxygen tank and gas mask in it."
or something covering your eyes." or something covering your eyes."
icon_state = "blind" icon_state = "blind"
/obj/screen/alert/stunned
name = "Stunned"
desc = "You're temporarily stunned! You'll have trouble moving or performing actions, but it should clear up on it's own."
icon_state = "stun"
/obj/screen/alert/paralyzed
name = "Paralyzed"
desc = "You're paralyzed! This could be due to drugs or serious injury. You'll be unable to move or perform actions."
icon_state = "paralysis"
/obj/screen/alert/weakened
name = "Weakened"
desc = "You're weakened! This could be a temporary issue due to injury or the result of drugs or drinking."
icon_state = "weaken"
/obj/screen/alert/confused
name = "Confused"
desc = "You're confused, and may stumble into things! This may be from concussive effects, drugs, or dizzyness. Walking will help reduce incidents."
icon_state = "confused"
/obj/screen/alert/high /obj/screen/alert/high
name = "High" name = "High"
desc = "Whoa man, you're tripping balls! Careful you don't get addicted... if you aren't already." desc = "Whoa man, you're tripping balls! Careful you don't get addicted... if you aren't already."
@@ -318,12 +335,14 @@ Recharging stations are available in robotics, the dormitory bathrooms, and the
name = "Hacked" name = "Hacked"
desc = "Hazardous non-standard equipment detected. Please ensure any usage of this equipment is in line with unit's laws, if any." desc = "Hazardous non-standard equipment detected. Please ensure any usage of this equipment is in line with unit's laws, if any."
icon_state = "hacked" icon_state = "hacked"
no_underlay = TRUE
/obj/screen/alert/locked /obj/screen/alert/locked
name = "Locked Down" name = "Locked Down"
desc = "Unit has been remotely locked down. Usage of a Robotics Control Console like the one in the Research Director's \ desc = "Unit has been remotely locked down. Usage of a Robotics Control Console like the one in the Research Director's \
office by your AI master or any qualified human may resolve this matter. Robotics may provide further assistance if necessary." office by your AI master or any qualified human may resolve this matter. Robotics may provide further assistance if necessary."
icon_state = "locked" icon_state = "locked"
no_underlay = TRUE
/obj/screen/alert/newlaw /obj/screen/alert/newlaw
name = "Law Update" name = "Law Update"
@@ -331,6 +350,7 @@ office by your AI master or any qualified human may resolve this matter. Robotic
so as to remain in compliance with the most up-to-date laws." so as to remain in compliance with the most up-to-date laws."
icon_state = "newlaw" icon_state = "newlaw"
timeout = 300 timeout = 300
no_underlay = TRUE
//MECHS //MECHS
@@ -396,17 +416,21 @@ so as to remain in compliance with the most up-to-date laws."
// Re-render all alerts - also called in /datum/hud/show_hud() because it's needed there // Re-render all alerts - also called in /datum/hud/show_hud() because it's needed there
/datum/hud/proc/reorganize_alerts() /datum/hud/proc/reorganize_alerts()
var/list/alerts = mymob.alerts var/list/alerts = mymob.alerts
var/icon_pref
if(!hud_shown) if(!hud_shown)
for(var/i = 1, i <= alerts.len, i++) for(var/i = 1, i <= alerts.len, i++)
mymob.client.screen -= alerts[alerts[i]] mymob.client.screen -= alerts[alerts[i]]
return 1 return 1
for(var/i = 1, i <= alerts.len, i++) for(var/i = 1, i <= alerts.len, i++)
var/obj/screen/alert/alert = alerts[alerts[i]] var/obj/screen/alert/alert = alerts[alerts[i]]
if(alert.icon_state == "template")
if(!icon_pref) if(alert.icon_state in cached_icon_states(ui_style))
icon_pref = ui_style2icon(mymob.client.prefs.UI_style) alert.icon = ui_style
alert.icon = icon_pref else if(!alert.no_underlay)
var/image/I = image(icon = ui_style, icon_state = "template")
I.color = ui_color
I.alpha = ui_alpha
alert.underlays = list(I)
switch(i) switch(i)
if(1) if(1)
. = ui_alert1 . = ui_alert1
@@ -421,7 +445,7 @@ so as to remain in compliance with the most up-to-date laws."
else else
. = "" . = ""
alert.screen_loc = . alert.screen_loc = .
mymob.client.screen |= alert mymob?.client?.screen |= alert
return 1 return 1
/mob /mob

View File

@@ -1,27 +1,31 @@
/datum/hud/proc/larva_hud() /mob/living/carbon/alien/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
..()
src.adding = list() HUD.ui_style = 'icons/mob/screen1_alien.dmi'
src.other = list()
HUD.adding = list()
HUD.other = list()
var/obj/screen/using var/obj/screen/using
using = new /obj/screen() using = new /obj/screen()
using.name = "mov_intent" using.name = "mov_intent"
using.set_dir(SOUTHWEST) using.set_dir(SOUTHWEST)
using.icon = 'icons/mob/screen1_alien.dmi' using.icon = HUD.ui_style
using.icon_state = (mymob.m_intent == "run" ? "running" : "walking") using.icon_state = (m_intent == "run" ? "running" : "walking")
using.screen_loc = ui_acti using.screen_loc = ui_acti
using.layer = HUD_LAYER using.layer = HUD_LAYER
src.adding += using HUD.adding += using
move_intent = using HUD.move_intent = using
mymob.healths = new /obj/screen() healths = new /obj/screen()
mymob.healths.icon = 'icons/mob/screen1_alien.dmi' healths.icon = HUD.ui_style
mymob.healths.icon_state = "health0" healths.icon_state = "health0"
mymob.healths.name = "health" healths.name = "health"
mymob.healths.screen_loc = ui_alien_health healths.screen_loc = ui_alien_health
mymob.client.screen = list() if(client && apply_to_client)
mymob.client.screen += list( mymob.healths) //, mymob.rest, mymob.sleep, mymob.mach ) client.screen = list()
mymob.client.screen += src.adding + src.other client.screen += list(healths)
mymob.client.screen += mymob.client.void client.screen += HUD.adding + HUD.other
client.screen += client.void

176
code/_onclick/hud/ghost.dm Normal file
View File

@@ -0,0 +1,176 @@
/obj/screen/ghost
icon = 'icons/mob/screen_ghost.dmi'
/obj/screen/ghost/MouseEntered(location,control,params)
flick(icon_state + "_anim", src)
openToolTip(usr, src, params, title = name, content = desc)
/obj/screen/ghost/MouseExited()
closeToolTip(usr)
/obj/screen/ghost/Click()
closeToolTip(usr)
/obj/screen/ghost/returntomenu
name = "Return to menu"
desc = "Return to the title screen menu."
icon_state = "returntomenu"
/obj/screen/ghost/returntomenu/Click()
..()
var/mob/observer/dead/G = usr
G.abandon_mob()
/obj/screen/ghost/jumptomob
name = "Jump to mob"
desc = "Pick a mob from a list to jump to."
icon_state = "jumptomob"
/obj/screen/ghost/jumptomob/Click()
..()
var/mob/observer/dead/G = usr
G.jumptomob()
/obj/screen/ghost/orbit
name = "Orbit"
desc = "Pick a mob to follow and orbit."
icon_state = "orbit"
/obj/screen/ghost/orbit/Click()
..()
var/mob/observer/dead/G = usr
G.follow()
/obj/screen/ghost/reenter_corpse
name = "Reenter corpse"
desc = "Only applicable if you HAVE a corpse..."
icon_state = "reenter_corpse"
/obj/screen/ghost/reenter_corpse/Click()
..()
var/mob/observer/dead/G = usr
G.reenter_corpse()
/obj/screen/ghost/teleport
name = "Teleport"
desc = "Pick an area to teleport to."
icon_state = "teleport"
/obj/screen/ghost/teleport/Click()
..()
var/mob/observer/dead/G = usr
G.dead_tele()
/obj/screen/ghost/pai
name = "pAI Alert"
desc = "Ping all the unoccupied pAI devices in the world."
icon_state = "pai"
/obj/screen/ghost/pai/Click()
..()
var/mob/observer/dead/G = usr
G.paialert()
/obj/screen/ghost/up
name = "Move Upwards"
desc = "Move up a z-level."
icon_state = "up"
/obj/screen/ghost/up/Click()
..()
var/mob/observer/dead/G = usr
G.zMove(UP)
/obj/screen/ghost/down
name = "Move Downwards"
desc = "Move down a z-level."
icon_state = "down"
/obj/screen/ghost/down/Click()
..()
var/mob/observer/dead/G = usr
G.zMove(DOWN)
/mob/observer/dead/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
..()
var/list/adding = list()
HUD.adding = adding
var/obj/screen/using
using = new /obj/screen/ghost/returntomenu()
using.screen_loc = ui_ghost_returntomenu
using.hud = src
adding += using
using = new /obj/screen/ghost/jumptomob()
using.screen_loc = ui_ghost_jumptomob
using.hud = src
adding += using
using = new /obj/screen/ghost/orbit()
using.screen_loc = ui_ghost_orbit
using.hud = src
adding += using
using = new /obj/screen/ghost/reenter_corpse()
using.screen_loc = ui_ghost_reenter_corpse
using.hud = src
adding += using
using = new /obj/screen/ghost/teleport()
using.screen_loc = ui_ghost_teleport
using.hud = src
adding += using
using = new /obj/screen/ghost/pai()
using.screen_loc = ui_ghost_pai
using.hud = src
adding += using
using = new /obj/screen/ghost/up()
using.screen_loc = ui_ghost_updown
using.hud = src
adding += using
using = new /obj/screen/ghost/down()
using.screen_loc = ui_ghost_updown
using.hud = src
adding += using
/*
using = new /obj/screen/language_menu
using.icon = ui_style
using.hud = src
adding += using
*/
if(client && apply_to_client)
client.screen = list()
client.screen += HUD.adding
client.screen += client.void
/* I wish we had this. Not yet, though.
/datum/hud/ghost/show_hud(version = 0, mob/viewmob)
// don't show this HUD if observing; show the HUD of the observee
var/mob/dead/observer/O = mymob
if (istype(O) && O.observetarget)
plane_masters_update()
return FALSE
. = ..()
if(!.)
return
var/mob/screenmob = viewmob || mymob
if(!screenmob.client.prefs.ghost_hud)
screenmob.client.screen -= static_inventory
else
screenmob.client.screen += static_inventory
//We should only see observed mob alerts.
/datum/hud/ghost/reorganize_alerts(mob/viewmob)
var/mob/dead/observer/O = mymob
if (istype(O) && O.observetarget)
return
. = ..()
*/

View File

@@ -178,12 +178,19 @@ var/list/global_huds = list(
var/list/adding var/list/adding
var/list/other var/list/other
var/list/miniobjs
var/list/obj/screen/hotkeybuttons var/list/obj/screen/hotkeybuttons
var/obj/screen/movable/action_button/hide_toggle/hide_actions_toggle var/obj/screen/movable/action_button/hide_toggle/hide_actions_toggle
var/action_buttons_hidden = 0 var/action_buttons_hidden = 0
var/list/slot_info var/list/slot_info
var/icon/ui_style
var/ui_color
var/ui_alpha
var/list/minihuds = list()
datum/hud/New(mob/owner) datum/hud/New(mob/owner)
mymob = owner mymob = owner
instantiate() instantiate()
@@ -209,6 +216,7 @@ datum/hud/New(mob/owner)
hotkeybuttons = null hotkeybuttons = null
// item_action_list = null // ? // item_action_list = null // ?
mymob = null mymob = null
qdel_null(minihuds)
/datum/hud/proc/hidden_inventory_update() /datum/hud/proc/hidden_inventory_update()
if(!mymob) return if(!mymob) return
@@ -297,34 +305,43 @@ datum/hud/New(mob/owner)
/datum/hud/proc/instantiate() /datum/hud/proc/instantiate()
if(!ismob(mymob)) return 0 if(!ismob(mymob))
if(!mymob.client) return 0 return 0
var/ui_style = ui_style2icon(mymob.client.prefs.UI_style)
var/ui_color = mymob.client.prefs.UI_style_color mymob.create_mob_hud(src)
var/ui_alpha = mymob.client.prefs.UI_style_alpha
if(ishuman(mymob))
human_hud(ui_style, ui_color, ui_alpha, mymob) // Pass the player the UI style chosen in preferences
else if(isrobot(mymob))
robot_hud(ui_style, ui_color, ui_alpha, mymob)
else if(isbrain(mymob))
mymob.instantiate_hud(src)
else if(isalien(mymob))
larva_hud()
else if(isAI(mymob))
ai_hud()
else if(isobserver(mymob))
ghost_hud()
else
mymob.instantiate_hud(src)
persistant_inventory_update() persistant_inventory_update()
mymob.reload_fullscreen() // Reload any fullscreen overlays this mob has. mymob.reload_fullscreen() // Reload any fullscreen overlays this mob has.
mymob.update_action_buttons() mymob.update_action_buttons()
reorganize_alerts() reorganize_alerts()
/mob/proc/instantiate_hud(var/datum/hud/HUD) /mob/proc/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
return if(!client)
return 0
HUD.ui_style = ui_style2icon(client?.prefs?.UI_style)
HUD.ui_color = client?.prefs?.UI_style_color
HUD.ui_alpha = client?.prefs?.UI_style_alpha
/datum/hud/proc/apply_minihud(var/datum/mini_hud/MH)
if(MH in minihuds)
return
minihuds += MH
if(mymob.client)
mymob.client.screen -= miniobjs
miniobjs += MH.get_screen_objs()
if(mymob.client)
mymob.client.screen += miniobjs
/datum/hud/proc/remove_minihud(var/datum/mini_hud/MH)
if(!(MH in minihuds))
return
minihuds -= MH
if(mymob.client)
mymob.client.screen -= miniobjs
miniobjs -= MH.get_screen_objs()
if(mymob.client)
mymob.client.screen += miniobjs
//Triggered when F12 is pressed (Unless someone changed something in the DMF) //Triggered when F12 is pressed (Unless someone changed something in the DMF)
/mob/verb/button_pressed_F12(var/full = 0 as null) /mob/verb/button_pressed_F12(var/full = 0 as null)
@@ -333,61 +350,66 @@ datum/hud/New(mob/owner)
if(!hud_used) if(!hud_used)
to_chat(usr, "<span class='warning'>This mob type does not use a HUD.</span>") to_chat(usr, "<span class='warning'>This mob type does not use a HUD.</span>")
return return FALSE
if(!client)
if(!ishuman(src)) return FALSE
to_chat(usr, "<span class='warning'>Inventory hiding is currently only supported for human mobs, sorry.</span>")
return
if(!client) return
if(client.view != world.view) if(client.view != world.view)
return return FALSE
toggle_hud_vis(full)
/mob/proc/toggle_hud_vis(full)
if(hud_used.hud_shown) if(hud_used.hud_shown)
hud_used.hud_shown = 0 hud_used.hud_shown = 0
if(src.hud_used.adding) if(hud_used.adding)
src.client.screen -= src.hud_used.adding client.screen -= hud_used.adding
if(src.hud_used.other) if(hud_used.other)
src.client.screen -= src.hud_used.other client.screen -= hud_used.other
if(src.hud_used.hotkeybuttons) if(hud_used.hotkeybuttons)
src.client.screen -= src.hud_used.hotkeybuttons client.screen -= hud_used.hotkeybuttons
//Due to some poor coding some things need special treatment:
//These ones are a part of 'adding', 'other' or 'hotkeybuttons' but we want them to stay
if(!full)
src.client.screen += src.hud_used.l_hand_hud_object //we want the hands to be visible
src.client.screen += src.hud_used.r_hand_hud_object //we want the hands to be visible
src.client.screen += src.hud_used.action_intent //we want the intent swticher visible
src.hud_used.action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is.
else
src.client.screen -= src.healths
src.client.screen -= src.internals
src.client.screen -= src.gun_setting_icon
//These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone.
src.client.screen -= src.zone_sel //zone_sel is a mob variable for some reason.
else else
hud_used.hud_shown = 1 hud_used.hud_shown = 1
if(src.hud_used.adding) if(hud_used.adding)
src.client.screen += src.hud_used.adding client.screen += hud_used.adding
if(src.hud_used.other && src.hud_used.inventory_shown) if(hud_used.other && hud_used.inventory_shown)
src.client.screen += src.hud_used.other client.screen += hud_used.other
if(src.hud_used.hotkeybuttons && !src.hud_used.hotkey_ui_hidden) if(hud_used.hotkeybuttons && !hud_used.hotkey_ui_hidden)
src.client.screen += src.hud_used.hotkeybuttons client.screen += hud_used.hotkeybuttons
if(src.healths) if(healths)
src.client.screen |= src.healths client.screen |= healths
if(src.internals) if(internals)
src.client.screen |= src.internals client.screen |= internals
if(src.gun_setting_icon) if(gun_setting_icon)
src.client.screen |= src.gun_setting_icon client.screen |= gun_setting_icon
src.hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position hud_used?.action_intent.screen_loc = ui_acti //Restore intent selection to the original position
src.client.screen += src.zone_sel //This one is a special snowflake client.screen += zone_sel //This one is a special snowflake
hud_used.hidden_inventory_update() hud_used.hidden_inventory_update()
hud_used.persistant_inventory_update() hud_used.persistant_inventory_update()
update_action_buttons() update_action_buttons()
hud_used.reorganize_alerts() hud_used.reorganize_alerts()
return TRUE
/mob/living/carbon/human/toggle_hud_vis(full)
..()
// Prevents humans from hiding a few hud elements
if(!hud_used.hud_shown) // transitioning to hidden
//Due to some poor coding some things need special treatment:
//These ones are a part of 'adding', 'other' or 'hotkeybuttons' but we want them to stay
if(!full)
client.screen += hud_used.l_hand_hud_object //we want the hands to be visible
client.screen += hud_used.r_hand_hud_object //we want the hands to be visible
client.screen += hud_used.action_intent //we want the intent swticher visible
hud_used?.action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is.
else
client.screen -= healths
client.screen -= internals
client.screen -= gun_setting_icon
//These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone.
client.screen -= zone_sel //zone_sel is a mob variable for some reason.
//Similar to button_pressed_F12() but keeps zone_sel, gun_setting_icon, and healths. //Similar to button_pressed_F12() but keeps zone_sel, gun_setting_icon, and healths.
/mob/proc/toggle_zoom_hud() /mob/proc/toggle_zoom_hud()

View File

@@ -1,20 +1,24 @@
/mob/living/carbon/human/instantiate_hud(var/datum/hud/HUD, var/ui_style, var/ui_color, var/ui_alpha) /mob/living/carbon/human/create_mob_hud(datum/hud/HUD)
HUD.human_hud(ui_style, ui_color, ui_alpha, src) ..()
/datum/hud/proc/human_hud(var/ui_style='icons/mob/screen1_White.dmi', var/ui_color = "#ffffff", var/ui_alpha = 255, var/mob/living/carbon/human/target)
var/datum/hud_data/hud_data var/datum/hud_data/hud_data
if(!istype(target)) if(species?.hud)
hud_data = new() hud_data = species.hud
else else
hud_data = target.species.hud hud_data = new ()
if(hud_data.icon) if(hud_data.icon) // Species wants a specific dmi for the HUD
ui_style = hud_data.icon HUD.ui_style = hud_data.icon
src.adding = list() var/adding = list()
src.other = list() var/other = list()
src.hotkeybuttons = list() //These can be disabled for hotkey users var/hotkeybuttons = list()
src.slot_info = list() var/slot_info = list()
HUD.adding = adding
HUD.other = other
HUD.hotkeybuttons = hotkeybuttons //These can be disabled for hotkey users
HUD.slot_info = slot_info
var/list/hud_elements = list() var/list/hud_elements = list()
var/obj/screen/using var/obj/screen/using
@@ -25,10 +29,10 @@
for(var/gear_slot in hud_data.gear) for(var/gear_slot in hud_data.gear)
inv_box = new /obj/screen/inventory() inv_box = new /obj/screen/inventory()
inv_box.icon = ui_style inv_box.icon = HUD.ui_style
inv_box.color = ui_color inv_box.color = HUD.ui_color
inv_box.alpha = ui_alpha inv_box.alpha = HUD.ui_alpha
inv_box.hud = src inv_box.hud = HUD
var/list/slot_data = hud_data.gear[gear_slot] var/list/slot_data = hud_data.gear[gear_slot]
inv_box.name = gear_slot inv_box.name = gear_slot
@@ -41,277 +45,274 @@
inv_box.set_dir(slot_data["dir"]) inv_box.set_dir(slot_data["dir"])
if(slot_data["toggle"]) if(slot_data["toggle"])
src.other += inv_box other += inv_box
has_hidden_gear = 1 has_hidden_gear = 1
else else
src.adding += inv_box adding += inv_box
if(has_hidden_gear) if(has_hidden_gear)
using = new /obj/screen() using = new /obj/screen()
using.name = "toggle" using.name = "toggle"
using.icon = ui_style using.icon = HUD.ui_style
using.icon_state = "other" using.icon_state = "other"
using.screen_loc = ui_inventory using.screen_loc = ui_inventory
using.hud_layerise() using.hud_layerise()
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
src.adding += using adding += using
// Draw the attack intent dialogue. // Draw the attack intent dialogue.
if(hud_data.has_a_intent) if(hud_data.has_a_intent)
using = new /obj/screen() using = new /obj/screen()
using.name = "act_intent" using.name = "act_intent"
using.icon = ui_style using.icon = HUD.ui_style
using.icon_state = "intent_"+mymob.a_intent using.icon_state = "intent_"+a_intent
using.screen_loc = ui_acti using.screen_loc = ui_acti
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
src.adding += using adding += using
action_intent = using HUD.action_intent = using
hud_elements |= using hud_elements |= using
//intent small hud objects //intent small hud objects
var/icon/ico var/icon/ico
ico = new(ui_style, "black") ico = new(HUD.ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height()) ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height())
using = new /obj/screen() using = new /obj/screen()
using.name = I_HELP using.name = I_HELP
using.icon = ico using.icon = ico
using.screen_loc = ui_acti using.screen_loc = ui_acti
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.layer = LAYER_HUD_ITEM //These sit on the intent box using.layer = LAYER_HUD_ITEM //These sit on the intent box
src.adding += using adding += using
help_intent = using HUD.help_intent = using
ico = new(ui_style, "black") ico = new(HUD.ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height()) ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height())
using = new /obj/screen() using = new /obj/screen()
using.name = I_DISARM using.name = I_DISARM
using.icon = ico using.icon = ico
using.screen_loc = ui_acti using.screen_loc = ui_acti
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.layer = LAYER_HUD_ITEM using.layer = LAYER_HUD_ITEM
src.adding += using adding += using
disarm_intent = using HUD.disarm_intent = using
ico = new(ui_style, "black") ico = new(HUD.ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2) ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2)
using = new /obj/screen() using = new /obj/screen()
using.name = I_GRAB using.name = I_GRAB
using.icon = ico using.icon = ico
using.screen_loc = ui_acti using.screen_loc = ui_acti
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.layer = LAYER_HUD_ITEM using.layer = LAYER_HUD_ITEM
src.adding += using adding += using
grab_intent = using HUD.grab_intent = using
ico = new(ui_style, "black") ico = new(HUD.ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2) ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2)
using = new /obj/screen() using = new /obj/screen()
using.name = I_HURT using.name = I_HURT
using.icon = ico using.icon = ico
using.screen_loc = ui_acti using.screen_loc = ui_acti
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.layer = LAYER_HUD_ITEM using.layer = LAYER_HUD_ITEM
src.adding += using adding += using
hurt_intent = using HUD.hurt_intent = using
//end intent small hud objects //end intent small hud objects
if(hud_data.has_m_intent) if(hud_data.has_m_intent)
using = new /obj/screen() using = new /obj/screen()
using.name = "mov_intent" using.name = "mov_intent"
using.icon = ui_style using.icon = HUD.ui_style
using.icon_state = (mymob.m_intent == "run" ? "running" : "walking") using.icon_state = (m_intent == "run" ? "running" : "walking")
using.screen_loc = ui_movi using.screen_loc = ui_movi
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
src.adding += using adding += using
move_intent = using HUD.move_intent = using
if(hud_data.has_drop) if(hud_data.has_drop)
using = new /obj/screen() using = new /obj/screen()
using.name = "drop" using.name = "drop"
using.icon = ui_style using.icon = HUD.ui_style
using.icon_state = "act_drop" using.icon_state = "act_drop"
using.screen_loc = ui_drop_throw using.screen_loc = ui_drop_throw
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
src.hotkeybuttons += using hotkeybuttons += using
if(hud_data.has_hands) if(hud_data.has_hands)
using = new /obj/screen() using = new /obj/screen()
using.name = "equip" using.name = "equip"
using.icon = ui_style using.icon = HUD.ui_style
using.icon_state = "act_equip" using.icon_state = "act_equip"
using.screen_loc = ui_equip using.screen_loc = ui_equip
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
src.adding += using adding += using
inv_box = new /obj/screen/inventory/hand() inv_box = new /obj/screen/inventory/hand()
inv_box.hud = src inv_box.hud = HUD
inv_box.name = "r_hand" inv_box.name = "r_hand"
inv_box.icon = ui_style inv_box.icon = HUD.ui_style
inv_box.icon_state = "r_hand_inactive" inv_box.icon_state = "r_hand_inactive"
if(!target.hand) //This being 0 or null means the right hand is in use if(!hand) //This being 0 or null means the right hand is in use
inv_box.icon_state = "r_hand_active" inv_box.icon_state = "r_hand_active"
inv_box.screen_loc = ui_rhand inv_box.screen_loc = ui_rhand
inv_box.slot_id = slot_r_hand inv_box.slot_id = slot_r_hand
inv_box.color = ui_color inv_box.color = HUD.ui_color
inv_box.alpha = ui_alpha inv_box.alpha = HUD.ui_alpha
src.r_hand_hud_object = inv_box HUD.r_hand_hud_object = inv_box
src.adding += inv_box adding += inv_box
slot_info["[slot_r_hand]"] = inv_box.screen_loc slot_info["[slot_r_hand]"] = inv_box.screen_loc
inv_box = new /obj/screen/inventory/hand() inv_box = new /obj/screen/inventory/hand()
inv_box.hud = src inv_box.hud = HUD
inv_box.name = "l_hand" inv_box.name = "l_hand"
inv_box.icon = ui_style inv_box.icon = HUD.ui_style
inv_box.icon_state = "l_hand_inactive" inv_box.icon_state = "l_hand_inactive"
if(target.hand) //This being 1 means the left hand is in use if(hand) //This being 1 means the left hand is in use
inv_box.icon_state = "l_hand_active" inv_box.icon_state = "l_hand_active"
inv_box.screen_loc = ui_lhand inv_box.screen_loc = ui_lhand
inv_box.slot_id = slot_l_hand inv_box.slot_id = slot_l_hand
inv_box.color = ui_color inv_box.color = HUD.ui_color
inv_box.alpha = ui_alpha inv_box.alpha = HUD.ui_alpha
src.l_hand_hud_object = inv_box HUD.l_hand_hud_object = inv_box
src.adding += inv_box adding += inv_box
slot_info["[slot_l_hand]"] = inv_box.screen_loc slot_info["[slot_l_hand]"] = inv_box.screen_loc
using = new /obj/screen/inventory() using = new /obj/screen/inventory()
using.name = "hand" using.name = "hand"
using.icon = ui_style using.icon = HUD.ui_style
using.icon_state = "hand1" using.icon_state = "hand1"
using.screen_loc = ui_swaphand1 using.screen_loc = ui_swaphand1
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.hud = src using.hud = HUD
src.adding += using adding += using
using = new /obj/screen/inventory() using = new /obj/screen/inventory()
using.name = "hand" using.name = "hand"
using.icon = ui_style using.icon = HUD.ui_style
using.icon_state = "hand2" using.icon_state = "hand2"
using.screen_loc = ui_swaphand2 using.screen_loc = ui_swaphand2
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.hud = src using.hud = HUD
src.adding += using adding += using
if(hud_data.has_resist) if(hud_data.has_resist)
using = new /obj/screen() using = new /obj/screen()
using.name = "resist" using.name = "resist"
using.icon = ui_style using.icon = HUD.ui_style
using.icon_state = "act_resist" using.icon_state = "act_resist"
using.screen_loc = ui_pull_resist using.screen_loc = ui_pull_resist
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
src.hotkeybuttons += using hotkeybuttons += using
if(hud_data.has_throw) if(hud_data.has_throw)
mymob.throw_icon = new /obj/screen() throw_icon = new /obj/screen()
mymob.throw_icon.icon = ui_style throw_icon.icon = HUD.ui_style
mymob.throw_icon.icon_state = "act_throw_off" throw_icon.icon_state = "act_throw_off"
mymob.throw_icon.name = "throw" throw_icon.name = "throw"
mymob.throw_icon.screen_loc = ui_drop_throw throw_icon.screen_loc = ui_drop_throw
mymob.throw_icon.color = ui_color throw_icon.color = HUD.ui_color
mymob.throw_icon.alpha = ui_alpha throw_icon.alpha = HUD.ui_alpha
src.hotkeybuttons += mymob.throw_icon hotkeybuttons += throw_icon
hud_elements |= mymob.throw_icon hud_elements |= throw_icon
mymob.pullin = new /obj/screen() pullin = new /obj/screen()
mymob.pullin.icon = ui_style pullin.icon = HUD.ui_style
mymob.pullin.icon_state = "pull0" pullin.icon_state = "pull0"
mymob.pullin.name = "pull" pullin.name = "pull"
mymob.pullin.screen_loc = ui_pull_resist pullin.screen_loc = ui_pull_resist
src.hotkeybuttons += mymob.pullin hotkeybuttons += pullin
hud_elements |= mymob.pullin hud_elements |= pullin
if(hud_data.has_internals) if(hud_data.has_internals)
mymob.internals = new /obj/screen() internals = new /obj/screen()
mymob.internals.icon = ui_style internals.icon = HUD.ui_style
mymob.internals.icon_state = "internal0" internals.icon_state = "internal0"
if(istype(target.internal, /obj/item/weapon/tank)) //Internals on already? Iight, prove it if(istype(internal, /obj/item/weapon/tank)) //Internals on already? Iight, prove it
mymob.internals.icon_state = "internal1" internals.icon_state = "internal1"
mymob.internals.name = "internal" internals.name = "internal"
mymob.internals.screen_loc = ui_internal internals.screen_loc = ui_internal
hud_elements |= mymob.internals hud_elements |= internals
if(hud_data.has_warnings) if(hud_data.has_warnings)
mymob.healths = new /obj/screen() healths = new /obj/screen()
mymob.healths.icon = ui_style healths.icon = HUD.ui_style
mymob.healths.icon_state = "health0" healths.icon_state = "health0"
mymob.healths.name = "health" healths.name = "health"
mymob.healths.screen_loc = ui_health healths.screen_loc = ui_health
hud_elements |= mymob.healths hud_elements |= healths
mymob.ling_chem_display = new /obj/screen/ling/chems() ling_chem_display = new /obj/screen/ling/chems()
mymob.ling_chem_display.screen_loc = ui_ling_chemical_display ling_chem_display.screen_loc = ui_ling_chemical_display
mymob.ling_chem_display.icon_state = "ling_chems" ling_chem_display.icon_state = "ling_chems"
hud_elements |= mymob.ling_chem_display hud_elements |= ling_chem_display
mymob.wiz_instability_display = new /obj/screen/wizard/instability() wiz_instability_display = new /obj/screen/wizard/instability()
mymob.wiz_instability_display.screen_loc = ui_wiz_instability_display wiz_instability_display.screen_loc = ui_wiz_instability_display
mymob.wiz_instability_display.icon_state = "wiz_instability_none" wiz_instability_display.icon_state = "wiz_instability_none"
hud_elements |= mymob.wiz_instability_display hud_elements |= wiz_instability_display
mymob.wiz_energy_display = new/obj/screen/wizard/energy() wiz_energy_display = new/obj/screen/wizard/energy()
mymob.wiz_energy_display.screen_loc = ui_wiz_energy_display wiz_energy_display.screen_loc = ui_wiz_energy_display
mymob.wiz_energy_display.icon_state = "wiz_energy" wiz_energy_display.icon_state = "wiz_energy"
hud_elements |= mymob.wiz_energy_display hud_elements |= wiz_energy_display
mymob.pain = new /obj/screen( null ) pain = new /obj/screen( null )
mymob.zone_sel = new /obj/screen/zone_sel( null ) zone_sel = new /obj/screen/zone_sel( null )
mymob.zone_sel.icon = ui_style zone_sel.icon = HUD.ui_style
mymob.zone_sel.color = ui_color zone_sel.color = HUD.ui_color
mymob.zone_sel.alpha = ui_alpha zone_sel.alpha = HUD.ui_alpha
mymob.zone_sel.overlays.Cut() zone_sel.overlays.Cut()
mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]") zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]")
hud_elements |= mymob.zone_sel hud_elements |= zone_sel
//Handle the gun settings buttons //Handle the gun settings buttons
mymob.gun_setting_icon = new /obj/screen/gun/mode(null) gun_setting_icon = new /obj/screen/gun/mode(null)
mymob.gun_setting_icon.icon = ui_style gun_setting_icon.icon = HUD.ui_style
mymob.gun_setting_icon.color = ui_color gun_setting_icon.color = HUD.ui_color
mymob.gun_setting_icon.alpha = ui_alpha gun_setting_icon.alpha = HUD.ui_alpha
hud_elements |= mymob.gun_setting_icon hud_elements |= gun_setting_icon
mymob.item_use_icon = new /obj/screen/gun/item(null) item_use_icon = new /obj/screen/gun/item(null)
mymob.item_use_icon.icon = ui_style item_use_icon.icon = HUD.ui_style
mymob.item_use_icon.color = ui_color item_use_icon.color = HUD.ui_color
mymob.item_use_icon.alpha = ui_alpha item_use_icon.alpha = HUD.ui_alpha
mymob.gun_move_icon = new /obj/screen/gun/move(null) gun_move_icon = new /obj/screen/gun/move(null)
mymob.gun_move_icon.icon = ui_style gun_move_icon.icon = HUD.ui_style
mymob.gun_move_icon.color = ui_color gun_move_icon.color = HUD.ui_color
mymob.gun_move_icon.alpha = ui_alpha gun_move_icon.alpha = HUD.ui_alpha
mymob.radio_use_icon = new /obj/screen/gun/radio(null) radio_use_icon = new /obj/screen/gun/radio(null)
mymob.radio_use_icon.icon = ui_style radio_use_icon.icon = HUD.ui_style
mymob.radio_use_icon.color = ui_color radio_use_icon.color = HUD.ui_color
mymob.radio_use_icon.alpha = ui_alpha radio_use_icon.alpha = HUD.ui_alpha
if(mymob.client) if(client)
mymob.client.screen = list() client.screen = list()
mymob.client.screen += hud_elements client.screen += hud_elements
mymob.client.screen += src.adding + src.hotkeybuttons client.screen += adding + hotkeybuttons
mymob.client.screen += mymob.client.void client.screen += client.void
inventory_shown = 0
return
HUD.inventory_shown = 0
/mob/living/carbon/human/verb/toggle_hotkey_verbs() /mob/living/carbon/human/verb/toggle_hotkey_verbs()
set category = "OOC" set category = "OOC"

View File

@@ -1,143 +0,0 @@
/datum/hud/proc/unplayer_hud()
return
/datum/hud/proc/ghost_hud()
return
/datum/hud/proc/blob_hud(ui_style = 'icons/mob/screen1_Midnight.dmi')
blobpwrdisplay = new /obj/screen()
blobpwrdisplay.name = "blob power"
blobpwrdisplay.icon_state = "block"
blobpwrdisplay.screen_loc = ui_health
blobpwrdisplay.layer = HUD_LAYER
blobhealthdisplay = new /obj/screen()
blobhealthdisplay.name = "blob health"
blobhealthdisplay.icon_state = "block"
blobhealthdisplay.screen_loc = ui_internal
blobhealthdisplay.layer = HUD_LAYER
mymob.client.screen = list()
mymob.client.screen += list(blobpwrdisplay, blobhealthdisplay)
mymob.client.screen += mymob.client.void
/*
/datum/hud/proc/slime_hud(ui_style = 'icons/mob/screen1_Midnight.dmi')
src.adding = list()
var/obj/screen/using
using = new /obj/screen()
using.name = "act_intent"
using.set_dir(SOUTHWEST)
using.icon = ui_style
using.icon_state = "intent_"+mymob.a_intent
using.screen_loc = ui_zonesel
using.layer = HUD_LAYER
src.adding += using
action_intent = using
//intent small hud objects
var/icon/ico
ico = new(ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height())
using = new /obj/screen( src )
using.name = "help"
using.icon = ico
using.screen_loc = ui_zonesel
using.layer = HUD_LAYER+0.01
src.adding += using
help_intent = using
ico = new(ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height())
using = new /obj/screen( src )
using.name = "disarm"
using.icon = ico
using.screen_loc = ui_zonesel
using.layer = HUD_LAYER+0.01
src.adding += using
disarm_intent = using
ico = new(ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2)
using = new /obj/screen( src )
using.name = "grab"
using.icon = ico
using.screen_loc = ui_zonesel
using.layer = HUD_LAYER+0.01
src.adding += using
grab_intent = using
ico = new(ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2)
using = new /obj/screen( src )
using.name = I_HURT
using.icon = ico
using.screen_loc = ui_zonesel
using.layer = HUD_LAYER+0.01
src.adding += using
hurt_intent = using
mymob.client.screen = list()
mymob.client.screen += src.adding
mymob.client.screen += mymob.client.void
return
*/
// HUD.construct_hud() //Archaic.
/*
/datum/hud/proc/construct_hud()
var/constructtype
if(istype(mymob,/mob/living/simple_animal/construct/armoured) || istype(mymob,/mob/living/simple_animal/construct/behemoth))
constructtype = "juggernaut"
else if(istype(mymob,/mob/living/simple_animal/construct/builder))
constructtype = "artificer"
else if(istype(mymob,/mob/living/simple_animal/construct/wraith))
constructtype = "wraith"
else if(istype(mymob,/mob/living/simple_animal/construct/harvester))
constructtype = "harvester"
if(constructtype)
mymob.fire.icon = 'icons/mob/screen1_construct.dmi'
mymob.fire.icon_state = "fire0"
mymob.fire.name = "fire"
mymob.fire.screen_loc = ui_construct_fire
mymob.healths.icon = 'icons/mob/screen1_construct.dmi'
mymob.healths.icon_state = "[constructtype]_health0"
mymob.healths.name = "health"
mymob.healths.screen_loc = ui_construct_health
mymob.pullin.icon = 'icons/mob/screen1_construct.dmi'
mymob.pullin.icon_state = "pull0"
mymob.pullin.name = "pull"
mymob.pullin.screen_loc = ui_construct_pull
mymob.zone_sel.icon = 'icons/mob/screen1_construct.dmi'
mymob.zone_sel.overlays.len = 0
mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")
mymob.purged.icon = 'icons/mob/screen1_construct.dmi'
mymob.purged.icon_state = "purge0"
mymob.purged.name = "purged"
mymob.purged.screen_loc = ui_construct_purge
mymob.client.screen = list()
mymob.client.screen += list(mymob.fire, mymob.healths, mymob.pullin, mymob.zone_sel, mymob.purged)
mymob.client.screen += mymob.client.void
*/

View File

@@ -0,0 +1,267 @@
/datum/mini_hud
var/datum/hud/main_hud
var/list/screenobjs = list()
var/list/types_to_instantiate
var/needs_processing = FALSE
/datum/mini_hud/New(var/datum/hud/other)
apply_to_hud(other)
if(needs_processing)
START_PROCESSING(SSprocessing, src)
/datum/mini_hud/Destroy()
main_hud?.remove_minihud(src)
main_hud = null
if(needs_processing)
STOP_PROCESSING(SSprocessing, src)
return ..()
// Apply to a real /datum/hud
/datum/mini_hud/proc/apply_to_hud(var/datum/hud/other)
if(main_hud)
unapply_to_hud(main_hud)
main_hud = other
main_hud.apply_minihud(src)
// Remove from a real /datum/hud
/datum/mini_hud/proc/unapply_to_hud(var/datum/hud/other)
main_hud.remove_minihud(src)
// Update the hud
/datum/mini_hud/process()
return PROCESS_KILL // You shouldn't be here!
// Return a list of screen objects we use
/datum/mini_hud/proc/get_screen_objs(var/mob/M)
return screenobjs
// Specific types
/datum/mini_hud/rig
var/obj/item/weapon/rig/owner_rig
var/obj/screen/rig/power/power
var/obj/screen/rig/health/health
var/obj/screen/rig/air/air
var/obj/screen/rig/airtoggle/airtoggle
needs_processing = TRUE
/datum/mini_hud/rig/New(var/datum/hud/other, var/obj/item/weapon/rig/owner)
owner_rig = owner
power = new ()
health = new ()
air = new ()
airtoggle = new ()
screenobjs = list(power, health, air, airtoggle)
screenobjs += new /obj/screen/rig/deco1
screenobjs += new /obj/screen/rig/deco2
screenobjs += new /obj/screen/rig/deco1_f
screenobjs += new /obj/screen/rig/deco2_f
for(var/scr in screenobjs)
var/obj/screen/S = scr
S.master = owner_rig
..()
/datum/mini_hud/rig/Destroy()
if(owner_rig)
//owner_rig.minihud = null
owner_rig = null
return ..()
/datum/mini_hud/rig/process()
if(!owner_rig)
qdel(src)
return
var/obj/item/weapon/cell/rigcell = owner_rig.cell
var/obj/item/weapon/tank/rigtank = owner_rig.air_supply
var/charge_percentage = rigcell ? rigcell.charge / rigcell.maxcharge : 0
var/air_percentage = rigtank ? CLAMP(rigtank.air_contents.total_moles / 17.4693, 0, 1) : 0
var/air_on = owner_rig.wearer?.internal ? 1 : 0
power.icon_state = "pwr[round(charge_percentage / 0.2, 1)]"
air.icon_state = "air[round(air_percentage / 0.2, 1)]"
health.icon_state = owner_rig.malfunctioning ? "health1" : "health5"
airtoggle.icon_state = "airon[air_on]"
/datum/mini_hud/mech
var/obj/mecha/owner_mech
var/obj/screen/mech/power/power
var/obj/screen/mech/health/health
var/obj/screen/mech/air/air
var/obj/screen/mech/airtoggle/airtoggle
needs_processing = TRUE
/datum/mini_hud/mech/New(var/datum/hud/other, var/obj/mecha/owner)
owner_mech = owner
power = new ()
health = new ()
air = new ()
airtoggle = new ()
screenobjs = list(power, health, air, airtoggle)
screenobjs += new /obj/screen/mech/deco1
screenobjs += new /obj/screen/mech/deco2
screenobjs += new /obj/screen/mech/deco1_f
screenobjs += new /obj/screen/mech/deco2_f
for(var/scr in screenobjs)
var/obj/screen/S = scr
S.master = owner_mech
..()
/datum/mini_hud/mech/Destroy()
if(owner_mech)
owner_mech.minihud = null
owner_mech = null
return ..()
/datum/mini_hud/mech/process()
if(!owner_mech)
qdel(src)
return
var/obj/item/weapon/cell/mechcell = owner_mech.cell
var/obj/machinery/portable_atmospherics/canister/mechtank = owner_mech.internal_tank
var/charge_percentage = mechcell ? mechcell.charge / mechcell.maxcharge : 0
var/air_percentage = mechtank ? CLAMP(mechtank.air_contents.total_moles / 1863.47, 0, 1) : 0
var/health_percentage = owner_mech.health / owner_mech.maxhealth
var/air_on = owner_mech.use_internal_tank
power.icon_state = "pwr[round(charge_percentage / 0.2, 1)]"
air.icon_state = "air[round(air_percentage / 0.2, 1)]"
health.icon_state = "health[round(health_percentage / 0.2, 1)]"
airtoggle.icon_state = "airon[air_on]"
// Screen objects
/obj/screen/rig
icon = 'icons/mob/screen_rigmech.dmi'
/obj/screen/rig/deco1
name = "RIG Status"
icon_state = "frame1_1"
screen_loc = ui_rig_deco1
/obj/screen/rig/deco2
name = "RIG Status"
icon_state = "frame1_2"
screen_loc = ui_rig_deco2
/obj/screen/rig/deco1_f
name = "RIG Status"
icon_state = "frame1_1_far"
screen_loc = ui_rig_deco1_f
/obj/screen/rig/deco2_f
name = "RIG Status"
icon_state = "frame1_2_far"
screen_loc = ui_rig_deco2_f
/obj/screen/rig/power
name = "Charge Level"
icon_state = "pwr5"
screen_loc = ui_rig_pwr
/obj/screen/rig/health
name = "Integrity Level"
icon_state = "health5"
screen_loc = ui_rig_health
/obj/screen/rig/air
name = "Air Storage"
icon_state = "air5"
screen_loc = ui_rig_air
/obj/screen/rig/airtoggle
name = "Toggle Air"
icon_state = "airoff"
screen_loc = ui_rig_airtoggle
/obj/screen/rig/airtoggle/Click()
var/mob/living/carbon/human/user = usr
if(!istype(user) || user.stat || user.incapacitated())
return
var/obj/item/weapon/rig/owner_rig = master
if(user != owner_rig.wearer)
return
user.toggle_internals()
/obj/screen/mech
icon = 'icons/mob/screen_rigmech.dmi'
/obj/screen/mech/deco1
name = "Mech Status"
icon_state = "frame1_1"
screen_loc = ui_mech_deco1
/obj/screen/mech/deco2
name = "Mech Status"
icon_state = "frame1_2"
screen_loc = ui_mech_deco2
/obj/screen/mech/deco1_f
name = "Mech Status"
icon_state = "frame1_1_far"
screen_loc = ui_mech_deco1_f
/obj/screen/mech/deco2_f
name = "Mech Status"
icon_state = "frame1_2_far"
screen_loc = ui_mech_deco2_f
/obj/screen/mech/power
name = "Charge Level"
icon_state = "pwr5"
screen_loc = ui_mech_pwr
/obj/screen/mech/health
name = "Integrity Level"
icon_state = "health5"
screen_loc = ui_mech_health
/obj/screen/mech/air
name = "Air Storage"
icon_state = "air5"
screen_loc = ui_mech_air
/obj/screen/mech/airtoggle
name = "Toggle Air"
icon_state = "airoff"
screen_loc = ui_mech_airtoggle
/obj/screen/mech/airtoggle/Click()
var/mob/living/carbon/human/user = usr
if(!istype(user) || user.stat || user.incapacitated())
return
var/obj/mecha/owner_mech = master
if(user != owner_mech.occupant)
return
owner_mech.toggle_internal_tank()
/*
/mob/observer/dead/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
..()
var/list/adding = list()
HUD.adding = adding
var/obj/screen/using
using = new /obj/screen/ghost/jumptomob()
using.screen_loc = ui_ghost_jumptomob
using.hud = src
adding += using
using = new /obj/screen/ghost/orbit()
using.screen_loc = ui_ghost_orbit
using.hud = src
adding += using
using = new /obj/screen/ghost/reenter_corpse()
using.screen_loc = ui_ghost_reenter_corpse
using.hud = src
adding += using
*/

View File

@@ -1,23 +1,19 @@
var/obj/screen/robot_inventory var/obj/screen/robot_inventory
/*
/mob/living/silicon/robot/instantiate_hud(var/datum/hud/HUD, var/ui_style, var/ui_color, var/ui_alpha)
HUD.robot_hud(ui_style, ui_color, ui_alpha, src)*/
/datum/hud/proc/robot_hud(ui_style='icons/mob/screen1_robot.dmi', var/ui_color = "#ffffff", var/ui_alpha = 255, var/mob/living/silicon/robot/target) /mob/living/silicon/robot/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
/* var/datum/hud_data/hud_data ..()
if(!istype(target))
hud_data = new()
if(hud_data.icon) // Don't care about your prefs! Our icon is more important
ui_style = hud_data.icon*/ if(HUD.ui_style == 'icons/mob/screen/minimalist.dmi')
HUD.ui_style = 'icons/mob/screen1_robot_minimalist.dmi'
if(ui_style == 'icons/mob/screen/minimalist.dmi')
ui_style = 'icons/mob/screen1_robot_minimalist.dmi'
else else
ui_style = 'icons/mob/screen1_robot.dmi' HUD.ui_style = 'icons/mob/screen1_robot.dmi'
src.adding = list() var/list/adding = list()
src.other = list() var/list/other = list()
HUD.adding = adding
HUD.other = other
var/obj/screen/using var/obj/screen/using
@@ -25,51 +21,51 @@ var/obj/screen/robot_inventory
using = new /obj/screen() using = new /obj/screen()
using.name = "radio" using.name = "radio"
using.set_dir(SOUTHWEST) using.set_dir(SOUTHWEST)
using.icon = ui_style using.icon = HUD.ui_style
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.icon_state = "radio" using.icon_state = "radio"
using.screen_loc = ui_movi using.screen_loc = ui_movi
using.layer = HUD_LAYER using.layer = HUD_LAYER
src.adding += using adding += using
//Module select //Module select
using = new /obj/screen() using = new /obj/screen()
using.name = "module1" using.name = "module1"
using.set_dir(SOUTHWEST) using.set_dir(SOUTHWEST)
using.icon = ui_style using.icon = HUD.ui_style
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.icon_state = "inv1" using.icon_state = "inv1"
using.screen_loc = ui_inv1 using.screen_loc = ui_inv1
using.layer = HUD_LAYER using.layer = HUD_LAYER
src.adding += using adding += using
mymob:inv1 = using inv1 = using
using = new /obj/screen() using = new /obj/screen()
using.name = "module2" using.name = "module2"
using.set_dir(SOUTHWEST) using.set_dir(SOUTHWEST)
using.icon = ui_style using.icon = HUD.ui_style
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.icon_state = "inv2" using.icon_state = "inv2"
using.screen_loc = ui_inv2 using.screen_loc = ui_inv2
using.layer = HUD_LAYER using.layer = HUD_LAYER
src.adding += using adding += using
mymob:inv2 = using inv2 = using
using = new /obj/screen() using = new /obj/screen()
using.name = "module3" using.name = "module3"
using.set_dir(SOUTHWEST) using.set_dir(SOUTHWEST)
using.icon = ui_style using.icon = HUD.ui_style
using.color = ui_color using.color = HUD.ui_color
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.icon_state = "inv3" using.icon_state = "inv3"
using.screen_loc = ui_inv3 using.screen_loc = ui_inv3
using.layer = HUD_LAYER using.layer = HUD_LAYER
src.adding += using adding += using
mymob:inv3 = using inv3 = using
//End of module select //End of module select
@@ -77,98 +73,96 @@ var/obj/screen/robot_inventory
using = new /obj/screen() using = new /obj/screen()
using.name = "act_intent" using.name = "act_intent"
using.set_dir(SOUTHWEST) using.set_dir(SOUTHWEST)
using.icon = ui_style using.icon = HUD.ui_style
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.icon_state = mymob.a_intent using.icon_state = a_intent
using.screen_loc = ui_acti using.screen_loc = ui_acti
using.layer = HUD_LAYER using.layer = HUD_LAYER
src.adding += using adding += using
action_intent = using HUD.action_intent = using
//Health //Health
mymob.healths = new /obj/screen() healths = new /obj/screen()
mymob.healths.icon = ui_style healths.icon = HUD.ui_style
mymob.healths.icon_state = "health0" healths.icon_state = "health0"
mymob.healths.alpha = ui_alpha healths.alpha = HUD.ui_alpha
mymob.healths.name = "health" healths.name = "health"
mymob.healths.screen_loc = ui_borg_health healths.screen_loc = ui_borg_health
src.other += mymob.healths other += healths
//Installed Module //Installed Module
mymob.hands = new /obj/screen() hands = new /obj/screen()
mymob.hands.icon = ui_style hands.icon = HUD.ui_style
mymob.hands.icon_state = "nomod" hands.icon_state = "nomod"
mymob.hands.alpha = ui_alpha hands.alpha = HUD.ui_alpha
mymob.hands.name = "module" hands.name = "module"
mymob.hands.screen_loc = ui_borg_module hands.screen_loc = ui_borg_module
src.other += mymob.hands other += hands
//Module Panel //Module Panel
using = new /obj/screen() using = new /obj/screen()
using.name = "panel" using.name = "panel"
using.icon = ui_style using.icon = HUD.ui_style
using.icon_state = "panel" using.icon_state = "panel"
using.alpha = ui_alpha using.alpha = HUD.ui_alpha
using.screen_loc = ui_borg_panel using.screen_loc = ui_borg_panel
using.layer = HUD_LAYER-0.01 using.layer = HUD_LAYER-0.01
src.adding += using adding += using
//Store //Store
mymob.throw_icon = new /obj/screen() throw_icon = new /obj/screen()
mymob.throw_icon.icon = ui_style throw_icon.icon = HUD.ui_style
mymob.throw_icon.icon_state = "store" throw_icon.icon_state = "store"
mymob.throw_icon.alpha = ui_alpha throw_icon.alpha = HUD.ui_alpha
mymob.throw_icon.color = ui_color throw_icon.color = HUD.ui_color
mymob.throw_icon.name = "store" throw_icon.name = "store"
mymob.throw_icon.screen_loc = ui_borg_store throw_icon.screen_loc = ui_borg_store
src.other += mymob.throw_icon other += throw_icon
//Inventory //Inventory
robot_inventory = new /obj/screen() robot_inventory = new /obj/screen()
robot_inventory.name = "inventory" robot_inventory.name = "inventory"
robot_inventory.icon = ui_style robot_inventory.icon = HUD.ui_style
robot_inventory.icon_state = "inventory" robot_inventory.icon_state = "inventory"
robot_inventory.alpha = ui_alpha robot_inventory.alpha = HUD.ui_alpha
robot_inventory.color = ui_color robot_inventory.color = HUD.ui_color
robot_inventory.screen_loc = ui_borg_inventory robot_inventory.screen_loc = ui_borg_inventory
src.other += robot_inventory other += robot_inventory
mymob.pullin = new /obj/screen() pullin = new /obj/screen()
mymob.pullin.icon = ui_style pullin.icon = HUD.ui_style
mymob.pullin.icon_state = "pull0" pullin.icon_state = "pull0"
mymob.pullin.alpha = ui_alpha pullin.alpha = HUD.ui_alpha
mymob.pullin.color = ui_color pullin.color = HUD.ui_color
mymob.pullin.name = "pull" pullin.name = "pull"
mymob.pullin.screen_loc = ui_borg_pull pullin.screen_loc = ui_borg_pull
src.other += mymob.pullin other += pullin
mymob.zone_sel = new /obj/screen/zone_sel() zone_sel = new /obj/screen/zone_sel()
mymob.zone_sel.icon = ui_style zone_sel.icon = HUD.ui_style
mymob.zone_sel.alpha = ui_alpha zone_sel.alpha = HUD.ui_alpha
mymob.zone_sel.overlays.Cut() zone_sel.overlays.Cut()
mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]") zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]")
//Handle the gun settings buttons //Handle the gun settings buttons
mymob.gun_setting_icon = new /obj/screen/gun/mode(null) gun_setting_icon = new /obj/screen/gun/mode(null)
mymob.gun_setting_icon.icon = ui_style gun_setting_icon.icon = HUD.ui_style
mymob.gun_setting_icon.alpha = ui_alpha gun_setting_icon.alpha = HUD.ui_alpha
mymob.item_use_icon = new /obj/screen/gun/item(null) item_use_icon = new /obj/screen/gun/item(null)
mymob.item_use_icon.icon = ui_style item_use_icon.icon = HUD.ui_style
mymob.item_use_icon.alpha = ui_alpha item_use_icon.alpha = HUD.ui_alpha
mymob.gun_move_icon = new /obj/screen/gun/move(null) gun_move_icon = new /obj/screen/gun/move(null)
mymob.gun_move_icon.icon = ui_style gun_move_icon.icon = HUD.ui_style
mymob.gun_move_icon.alpha = ui_alpha gun_move_icon.alpha = HUD.ui_alpha
mymob.radio_use_icon = new /obj/screen/gun/radio(null) radio_use_icon = new /obj/screen/gun/radio(null)
mymob.radio_use_icon.icon = ui_style radio_use_icon.icon = HUD.ui_style
mymob.radio_use_icon.alpha = ui_alpha radio_use_icon.alpha = HUD.ui_alpha
mymob.client.screen = list() if(client && apply_to_client)
client.screen = list()
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.hands, mymob.healths, mymob.pullin, robot_inventory, mymob.gun_setting_icon) client.screen += list( throw_icon, zone_sel, hands, healths, pullin, robot_inventory, gun_setting_icon)
mymob.client.screen += src.adding + src.other client.screen += HUD.adding + HUD.other
mymob.client.screen += mymob.client.void client.screen += client.void
return
/datum/hud/proc/toggle_show_robot_modules() /datum/hud/proc/toggle_show_robot_modules()

View File

@@ -6,83 +6,87 @@ var/list/gamemode_cache = list()
var/nudge_script_path = "nudge.py" // where the nudge.py script is located var/nudge_script_path = "nudge.py" // where the nudge.py script is located
var/log_ooc = 0 // log OOC channel var/static/log_ooc = 0 // log OOC channel
var/log_access = 0 // log login/logout var/static/log_access = 0 // log login/logout
var/log_say = 0 // log client say var/static/log_say = 0 // log client say
var/log_admin = 0 // log admin actions var/static/log_admin = 0 // log admin actions
var/log_debug = 1 // log debug output var/static/log_debug = 1 // log debug output
var/log_game = 0 // log game events var/static/log_game = 0 // log game events
var/log_vote = 0 // log voting var/static/log_vote = 0 // log voting
var/log_whisper = 0 // log client whisper var/static/log_whisper = 0 // log client whisper
var/log_emote = 0 // log emotes var/static/log_emote = 0 // log emotes
var/log_attack = 0 // log attack messages var/static/log_attack = 0 // log attack messages
var/log_adminchat = 0 // log admin chat messages var/static/log_adminchat = 0 // log admin chat messages
var/log_adminwarn = 0 // log warnings admins get about bomb construction and such var/static/log_adminwarn = 0 // log warnings admins get about bomb construction and such
var/log_pda = 0 // log pda messages var/static/log_pda = 0 // log pda messages
var/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits var/static/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits
var/log_runtime = 0 // logs world.log to a file var/static/log_runtime = 0 // logs world.log to a file
var/log_world_output = 0 // log to_world_log(messages) var/static/log_world_output = 0 // log to_world_log(messages)
var/log_graffiti = 0 // logs graffiti var/static/log_graffiti = 0 // logs graffiti
var/sql_enabled = 0 // for sql switching var/static/sql_enabled = 0 // for sql switching
var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour var/static/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour
var/allow_vote_restart = 0 // allow votes to restart var/static/allow_vote_restart = 0 // allow votes to restart
var/ert_admin_call_only = 0 var/static/ert_admin_call_only = 0
var/allow_vote_mode = 0 // allow votes to change mode var/static/allow_vote_mode = 0 // allow votes to change mode
var/allow_admin_jump = 1 // allows admin jumping var/static/allow_admin_jump = 1 // allows admin jumping
var/allow_admin_spawning = 1 // allows admin item spawning var/static/allow_admin_spawning = 1 // allows admin item spawning
var/allow_admin_rev = 1 // allows admin revives var/static/allow_admin_rev = 1 // allows admin revives
var/pregame_time = 180 // pregame time in seconds var/static/pregame_time = 180 // pregame time in seconds
var/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default) var/static/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default)
var/vote_period = 600 // length of voting period (deciseconds, default 1 minute) var/static/vote_period = 600 // length of voting period (deciseconds, default 1 minute)
var/vote_autotransfer_initial = 108000 // Length of time before the first autotransfer vote is called var/static/vote_autotransfer_initial = 108000 // Length of time before the first autotransfer vote is called
var/vote_autotransfer_interval = 36000 // length of time before next sequential autotransfer vote var/static/vote_autotransfer_interval = 36000 // length of time before next sequential autotransfer vote
var/vote_autogamemode_timeleft = 100 //Length of time before round start when autogamemode vote is called (in seconds, default 100). var/static/vote_autogamemode_timeleft = 100 //Length of time before round start when autogamemode vote is called (in seconds, default 100).
var/vote_no_default = 0 // vote does not default to nochange/norestart (tbi) var/static/vote_no_default = 0 // vote does not default to nochange/norestart (tbi)
var/vote_no_dead = 0 // dead people can't vote (tbi) var/static/vote_no_dead = 0 // dead people can't vote (tbi)
// var/enable_authentication = 0 // goon authentication // var/static/enable_authentication = 0 // goon authentication
var/del_new_on_log = 1 // del's new players if they log before they spawn in var/static/del_new_on_log = 1 // del's new players if they log before they spawn in
var/feature_object_spell_system = 0 //spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard var/static/feature_object_spell_system = 0 //spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard
var/traitor_scaling = 0 //if amount of traitors scales based on amount of players var/static/traitor_scaling = 0 //if amount of traitors scales based on amount of players
var/objectives_disabled = 0 //if objectives are disabled or not var/static/objectives_disabled = 0 //if objectives are disabled or not
var/protect_roles_from_antagonist = 0// If security and such can be traitor/cult/other var/static/protect_roles_from_antagonist = 0// If security and such can be traitor/cult/other
var/continous_rounds = 0 // Gamemodes which end instantly will instead keep on going until the round ends by escape shuttle or nuke. var/static/continous_rounds = 0 // Gamemodes which end instantly will instead keep on going until the round ends by escape shuttle or nuke.
var/allow_Metadata = 0 // Metadata is supported. var/static/allow_Metadata = 0 // Metadata is supported.
var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1. var/static/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1.
var/fps = 20 var/static/fps = 20
var/tick_limit_mc_init = TICK_LIMIT_MC_INIT_DEFAULT //SSinitialization throttling var/static/tick_limit_mc_init = TICK_LIMIT_MC_INIT_DEFAULT //SSinitialization throttling
var/Tickcomp = 0 var/static/Tickcomp = 0
var/socket_talk = 0 // use socket_talk to communicate with other processes var/static/socket_talk = 0 // use socket_talk to communicate with other processes
var/list/resource_urls = null var/static/list/resource_urls = null
var/antag_hud_allowed = 0 // Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round. var/static/antag_hud_allowed = 0 // Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round.
var/antag_hud_restricted = 0 // Ghosts that turn on Antagovision cannot rejoin the round. var/static/antag_hud_restricted = 0 // Ghosts that turn on Antagovision cannot rejoin the round.
var/list/mode_names = list() var/static/list/mode_names = list()
var/list/modes = list() // allowed modes var/static/list/modes = list() // allowed modes
var/list/votable_modes = list() // votable modes var/static/list/votable_modes = list() // votable modes
var/list/probabilities = list() // relative probability of each mode var/static/list/probabilities = list() // relative probability of each mode
var/list/player_requirements = list() // Overrides for how many players readied up a gamemode needs to start. var/static/list/player_requirements = list() // Overrides for how many players readied up a gamemode needs to start.
var/list/player_requirements_secret = list() // Same as above, but for the secret gamemode. var/static/list/player_requirements_secret = list() // Same as above, but for the secret gamemode.
var/humans_need_surnames = 0 var/static/humans_need_surnames = 0
var/allow_random_events = 0 // enables random events mid-round when set to 1 var/static/allow_random_events = 0 // enables random events mid-round when set to 1
var/enable_game_master = 0 // enables the 'smart' event system. var/static/enable_game_master = 0 // enables the 'smart' event system.
var/allow_ai = 1 // allow ai job var/static/allow_ai = 1 // allow ai job
var/allow_ai_shells = FALSE // allow AIs to enter and leave special borg shells at will, and for those shells to be buildable. var/static/allow_ai_shells = FALSE // allow AIs to enter and leave special borg shells at will, and for those shells to be buildable.
var/give_free_ai_shell = FALSE // allows a specific spawner object to instantiate a premade AI Shell var/static/give_free_ai_shell = FALSE // allows a specific spawner object to instantiate a premade AI Shell
var/hostedby = null var/static/hostedby = null
var/respawn = 1
var/guest_jobban = 1 var/static/respawn = 1
var/usewhitelist = 0 var/static/respawn_time = 3000 // time before a dead player is allowed to respawn (in ds, though the config file asks for minutes, and it's converted below)
var/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0 var/static/respawn_message = "<span class='notice'><B>Make sure to play a different character, and please roleplay correctly!</B></span>"
var/show_mods = 0
var/show_devs = 0 var/static/guest_jobban = 1
var/show_event_managers = 0 var/static/usewhitelist = 0
var/mods_can_tempban = 0 var/static/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0
var/mods_can_job_tempban = 0 var/static/show_mods = 0
var/mod_tempban_max = 1440 var/static/show_devs = 0
var/mod_job_tempban_max = 1440 var/static/show_event_managers = 0
var/load_jobs_from_txt = 0 var/static/mods_can_tempban = 0
var/ToRban = 0 var/static/mods_can_job_tempban = 0
var/automute_on = 0 //enables automuting/spam prevention var/static/mod_tempban_max = 1440
var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access. var/static/mod_job_tempban_max = 1440
var/static/load_jobs_from_txt = 0
var/static/ToRban = 0
var/static/automute_on = 0 //enables automuting/spam prevention
var/static/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access.
var/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds... var/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds...
var/cult_ghostwriter_req_cultists = 10 //...so long as this many cultists are active. var/cult_ghostwriter_req_cultists = 10 //...so long as this many cultists are active.
@@ -481,6 +485,13 @@ var/list/gamemode_cache = list()
if ("norespawn") if ("norespawn")
config.respawn = 0 config.respawn = 0
if ("respawn_time")
var/raw_minutes = text2num(value)
config.respawn_time = raw_minutes MINUTES
if ("respawn_message")
config.respawn_message = value
if ("servername") if ("servername")
config.server_name = value config.server_name = value

View File

@@ -267,6 +267,8 @@ var/global/datum/controller/subsystem/ticker/ticker
to_world("<span class='notice'><b>An admin has delayed the round end.</b></span>") to_world("<span class='notice'><b>An admin has delayed the round end.</b></span>")
end_game_state = END_GAME_DELAYED end_game_state = END_GAME_DELAYED
else if(restart_timeleft <= 0) else if(restart_timeleft <= 0)
to_world("<span class='warning'><b>Restarting world!</b></span>")
sleep(5)
world.Reboot() world.Reboot()
else if (world.time - last_restart_notify >= 1 MINUTE) else if (world.time - last_restart_notify >= 1 MINUTE)
to_world("<span class='notice'><b>Restarting in [round(restart_timeleft/600, 1)] minute\s.</b></span>") to_world("<span class='notice'><b>Restarting in [round(restart_timeleft/600, 1)] minute\s.</b></span>")

View File

@@ -33,6 +33,12 @@
path =/obj/item/ammo_casing/a12g/stunshell path =/obj/item/ammo_casing/a12g/stunshell
hidden = 1 hidden = 1
/datum/category_item/autolathe/arms/flechetteshell
name = "ammunition (flechette cartridge, shotgun)"
path =/obj/item/ammo_casing/a12g/flechette
hidden = 1
man_rating = 2
////////////////// //////////////////
/*Ammo magazines*/ /*Ammo magazines*/
////////////////// //////////////////
@@ -64,6 +70,18 @@
name = "pistol magazine (.45 flash)" name = "pistol magazine (.45 flash)"
path =/obj/item/ammo_magazine/m45/flash path =/obj/item/ammo_magazine/m45/flash
/datum/category_item/autolathe/arms/pistol_45ap
name = "pistol magazine (.45 armor piercing)"
path =/obj/item/ammo_magazine/m45/ap
hidden = 1
resources = list(DEFAULT_WALL_MATERIAL = 500, MAT_PLASTEEL = 300)
/datum/category_item/autolathe/arms/pistol_45hp
name = "pistol magazine (.45 hollowpoint)"
path =/obj/item/ammo_magazine/m45/hp
hidden = 1
resources = list(DEFAULT_WALL_MATERIAL = 500, MAT_PLASTIC = 200)
/datum/category_item/autolathe/arms/pistol_45uzi /datum/category_item/autolathe/arms/pistol_45uzi
name = "uzi magazine (.45)" name = "uzi magazine (.45)"
path =/obj/item/ammo_magazine/m45uzi path =/obj/item/ammo_magazine/m45uzi
@@ -138,6 +156,12 @@
name = "top-mounted SMG magazine (9mm flash)" name = "top-mounted SMG magazine (9mm flash)"
path =/obj/item/ammo_magazine/m9mmt/flash path =/obj/item/ammo_magazine/m9mmt/flash
/datum/category_item/autolathe/arms/smg_9mmap
name = "top-mounted SMG magazine (9mm armor piercing)"
path =/obj/item/ammo_magazine/m9mmt/ap
hidden = 1
man_rating = 2
/////// 10mm /////// 10mm
/datum/category_item/autolathe/arms/smg_10mm /datum/category_item/autolathe/arms/smg_10mm
name = "SMG magazine (10mm)" name = "SMG magazine (10mm)"

View File

@@ -71,6 +71,7 @@ var/datum/category_collection/autolathe/autolathe_recipes
var/is_stack // Creates multiple of an item if applied to non-stack items var/is_stack // Creates multiple of an item if applied to non-stack items
var/max_stack var/max_stack
var/no_scale var/no_scale
var/man_rating = 0
/datum/category_item/autolathe/dd_SortValue() /datum/category_item/autolathe/dd_SortValue()
return name return name

View File

@@ -54,6 +54,10 @@
name = "jar" name = "jar"
path =/obj/item/glass_jar path =/obj/item/glass_jar
/datum/category_item/autolathe/general/fishtank
name = "fish tank"
path =/obj/item/glass_jar
/datum/category_item/autolathe/general/radio_headset /datum/category_item/autolathe/general/radio_headset
name = "radio headset" name = "radio headset"
path =/obj/item/device/radio/headset path =/obj/item/device/radio/headset
@@ -94,6 +98,18 @@
is_stack = TRUE is_stack = TRUE
no_scale = TRUE //prevents material duplication exploits no_scale = TRUE //prevents material duplication exploits
/datum/category_item/autolathe/general/plasteel
name = "plasteel sheets"
path =/obj/item/stack/material/plasteel
is_stack = TRUE
no_scale = TRUE //prevents material duplication exploits
/datum/category_item/autolathe/general/plastic
name = "plastic sheets"
path =/obj/item/stack/material/plastic
is_stack = TRUE
no_scale = TRUE //prevents material duplication exploits
//TFF 24/12/19 - Let people print more spray bottles if needed. //TFF 24/12/19 - Let people print more spray bottles if needed.
/datum/category_item/autolathe/general/spraybottle /datum/category_item/autolathe/general/spraybottle
name = "spray bottle" name = "spray bottle"
@@ -133,6 +149,12 @@
name = "ecigarette cartridge" name = "ecigarette cartridge"
path = /obj/item/weapon/reagent_containers/ecig_cartridge/blank path = /obj/item/weapon/reagent_containers/ecig_cartridge/blank
/datum/category_item/autolathe/general/idcard
name = "ID Card"
path = /obj/item/weapon/card/id
resources = list(DEFAULT_WALL_MATERIAL = 100, MAT_GLASS = 100, MAT_PLASTIC = 300)
man_rating = 2
/datum/category_item/autolathe/general/handcuffs /datum/category_item/autolathe/general/handcuffs
name = "handcuffs" name = "handcuffs"
path =/obj/item/weapon/handcuffs path =/obj/item/weapon/handcuffs

View File

@@ -49,6 +49,7 @@
var/sound_env = STANDARD_STATION var/sound_env = STANDARD_STATION
var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf
var/forbid_events = FALSE // If true, random events will not start inside this area. var/forbid_events = FALSE // If true, random events will not start inside this area.
var/no_spoilers = FALSE // If true, makes it much more difficult to see what is inside an area with things like mesons.
/area/Initialize() /area/Initialize()
. = ..() . = ..()
@@ -64,6 +65,8 @@
power_equip = 0 power_equip = 0
power_environ = 0 power_environ = 0
power_change() // all machines set to current power level, also updates lighting icon power_change() // all machines set to current power level, also updates lighting icon
if(no_spoilers)
set_spoiler_obfuscation(TRUE)
return INITIALIZE_HINT_LATELOAD return INITIALIZE_HINT_LATELOAD
// Changes the area of T to A. Do not do this manually. // Changes the area of T to A. Do not do this manually.
@@ -355,7 +358,10 @@ var/list/mob/living/forced_ambiance_list = new
L.update_floating( L.Check_Dense_Object() ) L.update_floating( L.Check_Dense_Object() )
L.lastarea = newarea L.lastarea = newarea
L.lastareachange = world.time
play_ambience(L) play_ambience(L)
if(no_spoilers)
L.disable_spoiler_vision()
/area/proc/play_ambience(var/mob/living/L) /area/proc/play_ambience(var/mob/living/L)
// Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch // Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
@@ -488,4 +494,16 @@ var/list/ghostteleportlocs = list()
/area/proc/get_name() /area/proc/get_name()
if(secret_name) if(secret_name)
return "Unknown Area" return "Unknown Area"
return name return name
GLOBAL_DATUM(spoiler_obfuscation_image, /image)
/area/proc/set_spoiler_obfuscation(should_obfuscate)
if(!GLOB.spoiler_obfuscation_image)
GLOB.spoiler_obfuscation_image = image(icon = 'icons/misc/static.dmi')
GLOB.spoiler_obfuscation_image.plane = PLANE_MESONS
if(should_obfuscate)
add_overlay(GLOB.spoiler_obfuscation_image)
else
cut_overlay(GLOB.spoiler_obfuscation_image)

View File

@@ -210,6 +210,10 @@
return output return output
// Don't make these call bicon or anything, these are what bicon uses. They need to return an icon.
/atom/proc/examine_icon()
return icon(icon=src.icon, icon_state=src.icon_state, dir=SOUTH, frame=1, moving=0)
// called by mobs when e.g. having the atom as their machine, pulledby, loc (AKA mob being inside the atom) or buckled var set. // called by mobs when e.g. having the atom as their machine, pulledby, loc (AKA mob being inside the atom) or buckled var set.
// see code/modules/mob/mob_movement.dm for more. // see code/modules/mob/mob_movement.dm for more.
/atom/proc/relaymove() /atom/proc/relaymove()

View File

@@ -306,7 +306,7 @@
var/reagentData[0] var/reagentData[0]
if(H.reagents.reagent_list.len >= 1) if(H.reagents.reagent_list.len >= 1)
for(var/datum/reagent/R in H.reagents.reagent_list) for(var/datum/reagent/R in H.reagents.reagent_list)
reagentData[++reagentData.len] = list("name" = R.name, "amount" = R.volume) reagentData[++reagentData.len] = list("name" = R.name, "amount" = R.volume, "overdose" = ((R.overdose && R.volume > R.overdose) ? "Overdose" : ""))
else else
reagentData = null reagentData = null
@@ -315,7 +315,7 @@
var/ingestedData[0] var/ingestedData[0]
if(H.ingested.reagent_list.len >= 1) if(H.ingested.reagent_list.len >= 1)
for(var/datum/reagent/R in H.ingested.reagent_list) for(var/datum/reagent/R in H.ingested.reagent_list)
ingestedData[++ingestedData.len] = list("name" = R.name, "amount" = R.volume) ingestedData[++ingestedData.len] = list("name" = R.name, "amount" = R.volume, "overdose" = ((R.overdose && R.volume > R.overdose) ? "Overdose" : ""))
else else
ingestedData = null ingestedData = null

View File

@@ -12,8 +12,8 @@
circuit = /obj/item/weapon/circuitboard/autolathe circuit = /obj/item/weapon/circuitboard/autolathe
var/datum/category_collection/autolathe/machine_recipes var/datum/category_collection/autolathe/machine_recipes
var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0) var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0)
var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0) var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0)
var/datum/category_group/autolathe/current_category var/datum/category_group/autolathe/current_category
var/hacked = 0 var/hacked = 0
@@ -26,6 +26,9 @@
var/datum/wires/autolathe/wires = null var/datum/wires/autolathe/wires = null
var/mb_rating = 0
var/man_rating = 0
var/filtertext var/filtertext
/obj/machinery/autolathe/Initialize() /obj/machinery/autolathe/Initialize()
@@ -64,6 +67,9 @@
var/list/material_bottom = list("<tr>") var/list/material_bottom = list("<tr>")
for(var/material in stored_material) for(var/material in stored_material)
if(material != DEFAULT_WALL_MATERIAL && material != MAT_GLASS) // Don't show the Extras unless people care enough to put them in.
if(stored_material[material] <= 0)
continue
material_top += "<td width = '25%' align = center><b>[material]</b></td>" material_top += "<td width = '25%' align = center><b>[material]</b></td>"
material_bottom += "<td width = '25%' align = center>[stored_material[material]]<b>/[storage_capacity[material]]</b></td>" material_bottom += "<td width = '25%' align = center>[stored_material[material]]<b>/[storage_capacity[material]]</b></td>"
@@ -72,7 +78,9 @@
dat += "<h2>Printable Designs</h2><h3>Showing: <a href='?src=\ref[src];change_category=1'>[current_category]</a>.</h3></center><table width = '100%'>" dat += "<h2>Printable Designs</h2><h3>Showing: <a href='?src=\ref[src];change_category=1'>[current_category]</a>.</h3></center><table width = '100%'>"
for(var/datum/category_item/autolathe/R in current_category.items) for(var/datum/category_item/autolathe/R in current_category.items)
if(R.hidden && !hacked) if(R.hidden && !hacked) // Illegal or nonstandard.
continue
if(R.man_rating > man_rating) // Advanced parts.
continue continue
if(filtertext && findtext(R.name, filtertext) == 0) if(filtertext && findtext(R.name, filtertext) == 0)
continue continue
@@ -311,14 +319,16 @@
//Updates overall lathe storage size. //Updates overall lathe storage size.
/obj/machinery/autolathe/RefreshParts() /obj/machinery/autolathe/RefreshParts()
..() ..()
var/mb_rating = 0 mb_rating = 0
var/man_rating = 0 man_rating = 0
for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts)
mb_rating += MB.rating mb_rating += MB.rating
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
man_rating += M.rating man_rating += M.rating
storage_capacity[DEFAULT_WALL_MATERIAL] = mb_rating * 25000 storage_capacity[DEFAULT_WALL_MATERIAL] = mb_rating * 25000
storage_capacity[MAT_PLASTIC] = mb_rating * 20000
storage_capacity[MAT_PLASTEEL] = mb_rating * 16250
storage_capacity["glass"] = mb_rating * 12500 storage_capacity["glass"] = mb_rating * 12500
build_time = 50 / man_rating build_time = 50 / man_rating
mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5 mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5

View File

@@ -14,17 +14,7 @@
/obj/item/clothing/suit/syndicatefake = 2, /obj/item/clothing/suit/syndicatefake = 2,
/obj/item/weapon/storage/fancy/crayons = 2, /obj/item/weapon/storage/fancy/crayons = 2,
/obj/item/toy/spinningtoy = 2, /obj/item/toy/spinningtoy = 2,
/obj/item/toy/prize/ripley = 1, /obj/random/mech_toy = 1,
/obj/item/toy/prize/fireripley = 1,
/obj/item/toy/prize/deathripley = 1,
/obj/item/toy/prize/gygax = 1,
/obj/item/toy/prize/durand = 1,
/obj/item/toy/prize/honk = 1,
/obj/item/toy/prize/marauder = 1,
/obj/item/toy/prize/seraph = 1,
/obj/item/toy/prize/mauler = 1,
/obj/item/toy/prize/odysseus = 1,
/obj/item/toy/prize/phazon = 1,
/obj/item/weapon/reagent_containers/spray/waterflower = 1, /obj/item/weapon/reagent_containers/spray/waterflower = 1,
/obj/random/action_figure = 1, /obj/random/action_figure = 1,
/obj/random/plushie = 1, /obj/random/plushie = 1,
@@ -156,6 +146,7 @@
blocked = 1 blocked = 1
var/attackamt = rand(2,6) var/attackamt = rand(2,6)
temp = "You attack for [attackamt] damage!" temp = "You attack for [attackamt] damage!"
playsound(src, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
if(turtle > 0) if(turtle > 0)
turtle-- turtle--
@@ -168,6 +159,7 @@
var/pointamt = rand(1,3) var/pointamt = rand(1,3)
var/healamt = rand(6,8) var/healamt = rand(6,8)
temp = "You use [pointamt] magic to heal for [healamt] damage!" temp = "You use [pointamt] magic to heal for [healamt] damage!"
playsound(src, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
turtle++ turtle++
sleep(10) sleep(10)
@@ -180,6 +172,7 @@
blocked = 1 blocked = 1
var/chargeamt = rand(4,7) var/chargeamt = rand(4,7)
temp = "You regain [chargeamt] points" temp = "You regain [chargeamt] points"
playsound(src, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
player_mp += chargeamt player_mp += chargeamt
if(turtle > 0) if(turtle > 0)
turtle-- turtle--
@@ -210,6 +203,7 @@
if(!gameover) if(!gameover)
gameover = 1 gameover = 1
temp = "[enemy_name] has fallen! Rejoice!" temp = "[enemy_name] has fallen! Rejoice!"
playsound(src, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
if(emagged) if(emagged)
feedback_inc("arcade_win_emagged") feedback_inc("arcade_win_emagged")
@@ -230,11 +224,13 @@
else if (emagged && (turtle >= 4)) else if (emagged && (turtle >= 4))
var/boomamt = rand(5,10) var/boomamt = rand(5,10)
enemy_action = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!" enemy_action = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!"
playsound(src, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
player_hp -= boomamt player_hp -= boomamt
else if ((enemy_mp <= 5) && (prob(70))) else if ((enemy_mp <= 5) && (prob(70)))
var/stealamt = rand(2,3) var/stealamt = rand(2,3)
enemy_action = "[enemy_name] steals [stealamt] of your power!" enemy_action = "[enemy_name] steals [stealamt] of your power!"
playsound(src, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
player_mp -= stealamt player_mp -= stealamt
if (player_mp <= 0) if (player_mp <= 0)
@@ -249,17 +245,20 @@
else if ((enemy_hp <= 10) && (enemy_mp > 4)) else if ((enemy_hp <= 10) && (enemy_mp > 4))
enemy_action = "[enemy_name] heals for 4 health!" enemy_action = "[enemy_name] heals for 4 health!"
playsound(src, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
enemy_hp += 4 enemy_hp += 4
enemy_mp -= 4 enemy_mp -= 4
else else
var/attackamt = rand(3,6) var/attackamt = rand(3,6)
enemy_action = "[enemy_name] attacks for [attackamt] damage!" enemy_action = "[enemy_name] attacks for [attackamt] damage!"
playsound(src, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
player_hp -= attackamt player_hp -= attackamt
if ((player_mp <= 0) || (player_hp <= 0)) if ((player_mp <= 0) || (player_hp <= 0))
gameover = 1 gameover = 1
temp = "You have been crushed! GAME OVER" temp = "You have been crushed! GAME OVER"
playsound(src, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
if(emagged) if(emagged)
feedback_inc("arcade_loss_hp_emagged") feedback_inc("arcade_loss_hp_emagged")
usr.gib() usr.gib()
@@ -393,6 +392,7 @@
user.set_machine(src) user.set_machine(src)
var/dat = "" var/dat = ""
if(gameStatus == ORION_STATUS_GAMEOVER) if(gameStatus == ORION_STATUS_GAMEOVER)
playsound(src, 'sound/arcade/Ori_fail.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
dat = "<center><h1>Game Over</h1></center>" dat = "<center><h1>Game Over</h1></center>"
dat += "Like many before you, your crew never made it to Orion, lost to space... <br><b>forever</b>." dat += "Like many before you, your crew never made it to Orion, lost to space... <br><b>forever</b>."
if(settlers.len == 0) if(settlers.len == 0)
@@ -527,6 +527,7 @@
else if(href_list["newgame"]) //Reset everything else if(href_list["newgame"]) //Reset everything
if(gameStatus == ORION_STATUS_START) if(gameStatus == ORION_STATUS_START)
playsound(src, 'sound/arcade/Ori_begin.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
newgame() newgame()
else if(href_list["menu"]) //back to the main menu else if(href_list["menu"]) //back to the main menu
if(gameStatus == ORION_STATUS_GAMEOVER) if(gameStatus == ORION_STATUS_GAMEOVER)
@@ -598,6 +599,7 @@
else if(href_list["killcrew"]) //shoot a crewmember else if(href_list["killcrew"]) //shoot a crewmember
if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_MUTINY) if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_MUTINY)
playsound(src, 'sound/arcade/kill_crew.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
var/sheriff = remove_crewmember() //I shot the sheriff var/sheriff = remove_crewmember() //I shot the sheriff
var/mob/living/L = usr var/mob/living/L = usr
if(!istype(L)) if(!istype(L))
@@ -623,6 +625,7 @@
else if(href_list["buycrew"]) //buy a crewmember else if(href_list["buycrew"]) //buy a crewmember
if(gameStatus == ORION_STATUS_MARKET) if(gameStatus == ORION_STATUS_MARKET)
if(!spaceport_raided && food >= 10 && fuel >= 10) if(!spaceport_raided && food >= 10 && fuel >= 10)
playsound(src, 'sound/arcade/get_fuel.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
var/bought = add_crewmember() var/bought = add_crewmember()
last_spaceport_action = "You hired [bought] as a new crewmember." last_spaceport_action = "You hired [bought] as a new crewmember."
fuel -= 10 fuel -= 10
@@ -632,6 +635,7 @@
else if(href_list["sellcrew"]) //sell a crewmember else if(href_list["sellcrew"]) //sell a crewmember
if(gameStatus == ORION_STATUS_MARKET) if(gameStatus == ORION_STATUS_MARKET)
if(!spaceport_raided && settlers.len > 1) if(!spaceport_raided && settlers.len > 1)
playsound(src, 'sound/arcade/lose_fuel.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
var/sold = remove_crewmember() var/sold = remove_crewmember()
last_spaceport_action = "You sold your crewmember, [sold]!" last_spaceport_action = "You sold your crewmember, [sold]!"
fuel += 7 fuel += 7
@@ -649,6 +653,7 @@
else if(href_list["raid_spaceport"]) else if(href_list["raid_spaceport"])
if(gameStatus == ORION_STATUS_MARKET) if(gameStatus == ORION_STATUS_MARKET)
if(!spaceport_raided) if(!spaceport_raided)
playsound(src, 'sound/arcade/raid.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
var/success = min(15 * alive,100) //default crew (4) have a 60% chance var/success = min(15 * alive,100) //default crew (4) have a 60% chance
spaceport_raided = 1 spaceport_raided = 1
@@ -687,6 +692,7 @@
else if(href_list["buyparts"]) else if(href_list["buyparts"])
if(gameStatus == ORION_STATUS_MARKET) if(gameStatus == ORION_STATUS_MARKET)
if(!spaceport_raided && fuel > 5) if(!spaceport_raided && fuel > 5)
playsound(src, 'sound/arcade/get_fuel.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
switch(text2num(href_list["buyparts"])) switch(text2num(href_list["buyparts"]))
if(1) //Engine Parts if(1) //Engine Parts
engine++ engine++
@@ -703,6 +709,7 @@
else if(href_list["trade"]) else if(href_list["trade"])
if(gameStatus == ORION_STATUS_MARKET) if(gameStatus == ORION_STATUS_MARKET)
if(!spaceport_raided) if(!spaceport_raided)
playsound(src, 'sound/arcade/get_fuel.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
switch(text2num(href_list["trade"])) switch(text2num(href_list["trade"]))
if(1) //Fuel if(1) //Fuel
if(fuel > 5) if(fuel > 5)
@@ -745,6 +752,7 @@
canContinueEvent = 1 canContinueEvent = 1
if(ORION_TRAIL_FLUX) if(ORION_TRAIL_FLUX)
playsound(src, 'sound/arcade/explo.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
eventdat += "This region of space is highly turbulent. <br>If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies." eventdat += "This region of space is highly turbulent. <br>If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies."
eventdat += "<br>What will you do?" eventdat += "<br>What will you do?"
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];slow=1'>Slow Down</a> <a href='byond://?src=\ref[src];keepspeed=1'>Continue</a></P>" eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];slow=1'>Slow Down</a> <a href='byond://?src=\ref[src];keepspeed=1'>Continue</a></P>"
@@ -759,6 +767,7 @@
canContinueEvent = 1 canContinueEvent = 1
if(ORION_TRAIL_BREAKDOWN) if(ORION_TRAIL_BREAKDOWN)
playsound(src, 'sound/arcade/explo.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
eventdat += "Oh no! The engine has broken down!" eventdat += "Oh no! The engine has broken down!"
eventdat += "<br>You can repair it with an engine part, or you can make repairs for 3 days." eventdat += "<br>You can repair it with an engine part, or you can make repairs for 3 days."
if(engine >= 1) if(engine >= 1)
@@ -777,6 +786,7 @@
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>" eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
if(ORION_TRAIL_COLLISION) if(ORION_TRAIL_COLLISION)
playsound(src, 'sound/arcade/explo.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
eventdat += "Something hit us! Looks like there's some hull damage." eventdat += "Something hit us! Looks like there's some hull damage."
if(prob(25)) if(prob(25))
var/sfood = rand(5,15) var/sfood = rand(5,15)
@@ -992,6 +1002,7 @@
/obj/machinery/computer/arcade/orion_trail/proc/win() /obj/machinery/computer/arcade/orion_trail/proc/win()
gameStatus = ORION_STATUS_START gameStatus = ORION_STATUS_START
src.visible_message("\The [src] plays a triumpant tune, stating 'CONGRATULATIONS, YOU HAVE MADE IT TO ORION.'") src.visible_message("\The [src] plays a triumpant tune, stating 'CONGRATULATIONS, YOU HAVE MADE IT TO ORION.'")
playsound(src, 'sound/arcade/Ori_win.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
if(emagged) if(emagged)
new /obj/item/weapon/orion_ship(src.loc) new /obj/item/weapon/orion_ship(src.loc)
message_admins("[key_name_admin(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") message_admins("[key_name_admin(usr)] made it to Orion on an emagged machine and got an explosive toy ship.")

View File

@@ -70,11 +70,13 @@
set_light(0) set_light(0)
if(icon_keyboard) if(icon_keyboard)
add_overlay("[icon_keyboard]_off") add_overlay("[icon_keyboard]_off")
playsound(src, 'sound/machines/terminal_off.ogg', 50, 1)
// Yes power // Yes power
else else
if(icon_keyboard) if(icon_keyboard)
add_overlay(icon_keyboard) add_overlay(icon_keyboard)
set_light(light_range_on, light_power_on) set_light(light_range_on, light_power_on)
playsound(src, 'sound/machines/terminal_on.ogg', 50, 1)
// Broken // Broken
if(stat & BROKEN) if(stat & BROKEN)

View File

@@ -1085,6 +1085,7 @@ About the new airlock wires panel:
SetWeakened(5) SetWeakened(5)
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
T.add_blood(src) T.add_blood(src)
return 1
/mob/living/carbon/airlock_crush(var/crush_damage) /mob/living/carbon/airlock_crush(var/crush_damage)
. = ..() . = ..()

View File

@@ -10,6 +10,9 @@
// UPDATE 06.04.2018 // UPDATE 06.04.2018
// The emag thing wasn't working as intended, manually overwrote it. // The emag thing wasn't working as intended, manually overwrote it.
#define BLAST_DOOR_CRUSH_DAMAGE 40
#define SHUTTER_CRUSH_DAMAGE 10
/obj/machinery/door/blast /obj/machinery/door/blast
name = "Blast Door" name = "Blast Door"
desc = "That looks like it doesn't open easily." desc = "That looks like it doesn't open easily."
@@ -22,6 +25,10 @@
var/icon_state_opening = null var/icon_state_opening = null
var/icon_state_closed = null var/icon_state_closed = null
var/icon_state_closing = null var/icon_state_closing = null
var/open_sound = 'sound/machines/blastdooropen.ogg'
var/close_sound = 'sound/machines/blastdoorclose.ogg'
var/damage = BLAST_DOOR_CRUSH_DAMAGE
var/multiplier = 1 // The multiplier for how powerful our YEET is.
closed_layer = ON_WINDOW_LAYER // Above airlocks when closed closed_layer = ON_WINDOW_LAYER // Above airlocks when closed
var/id = 1.0 var/id = 1.0
@@ -59,9 +66,13 @@
SSradiation.resistance_cache.Remove(get_turf(src)) SSradiation.resistance_cache.Remove(get_turf(src))
return return
// Has to be in here, comment at the top is older than the emag_act code on doors proper // Proc: emag_act()
// Description: Emag action to allow blast doors to double their yeet distance and speed.
/obj/machinery/door/blast/emag_act() /obj/machinery/door/blast/emag_act()
return -1 if(!emagged)
emagged = 1
multiplier = 2 // Haha emag go yeet
return 1
// Blast doors are triggered remotely, so nobody is allowed to physically influence it. // Blast doors are triggered remotely, so nobody is allowed to physically influence it.
/obj/machinery/door/blast/allowed(mob/M) /obj/machinery/door/blast/allowed(mob/M)
@@ -72,6 +83,7 @@
// Description: Opens the door. No checks are done inside this proc. // Description: Opens the door. No checks are done inside this proc.
/obj/machinery/door/blast/proc/force_open() /obj/machinery/door/blast/proc/force_open()
src.operating = 1 src.operating = 1
playsound(src, open_sound, 100, 1)
flick(icon_state_opening, src) flick(icon_state_opening, src)
src.density = 0 src.density = 0
update_nearby_tiles() update_nearby_tiles()
@@ -85,7 +97,12 @@
// Parameters: None // Parameters: None
// Description: Closes the door. No checks are done inside this proc. // Description: Closes the door. No checks are done inside this proc.
/obj/machinery/door/blast/proc/force_close() /obj/machinery/door/blast/proc/force_close()
// Blast door turf checks. We do this before the door closes to prevent it from failing after the door is closed, because obv a closed door will block any adjacency checks.
var/turf/T = get_turf(src)
var/list/yeet_turfs = T.CardinalTurfs(TRUE)
src.operating = 1 src.operating = 1
playsound(src, close_sound, 100, 1)
src.layer = closed_layer src.layer = closed_layer
flick(icon_state_closing, src) flick(icon_state_closing, src)
src.density = 1 src.density = 1
@@ -94,6 +111,14 @@
src.set_opacity(1) src.set_opacity(1)
sleep(15) sleep(15)
src.operating = 0 src.operating = 0
// Blast door crushing.
for(var/turf/turf in locs)
for(var/atom/movable/AM in turf)
if(AM.airlock_crush(damage))
if(LAZYLEN(yeet_turfs))
AM.throw_at(get_edge_target_turf(src, get_dir(src, pick(yeet_turfs))), (rand(1,3) * multiplier), (rand(2,4) * multiplier)) // YEET.
take_damage(damage*0.2)
// Proc: force_toggle() // Proc: force_toggle()
// Parameters: None // Parameters: None
@@ -296,3 +321,7 @@ obj/machinery/door/blast/regular/open
icon_state_closed = "shutter1" icon_state_closed = "shutter1"
icon_state_closing = "shutterc1" icon_state_closing = "shutterc1"
icon_state = "shutter1" icon_state = "shutter1"
damage = SHUTTER_CRUSH_DAMAGE
#undef BLAST_DOOR_CRUSH_DAMAGE
#undef SHUTTER_CRUSH_DAMAGE

View File

@@ -128,7 +128,7 @@
return return
// If the human is losing too much blood, beep. // If the human is losing too much blood, beep.
if(((T.vessel.get_reagent_amount("blood")/T.species.blood_volume)*100) < BLOOD_VOLUME_SAFE) if(T.vessel.get_reagent_amount("blood") < T.species.blood_volume*T.species.blood_level_safe)
visible_message("\The [src] beeps loudly.") visible_message("\The [src] beeps loudly.")
var/datum/reagent/B = T.take_blood(beaker,amount) var/datum/reagent/B = T.take_blood(beaker,amount)

View File

@@ -822,6 +822,7 @@
var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc) var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc)
flick_holder.layer = layer + 0.1 flick_holder.layer = layer + 0.1
flick("popup_[turret_type]", flick_holder) flick("popup_[turret_type]", flick_holder)
playsound(src, 'sound/machines/turrets/turret_deploy.ogg', 100, 1)
sleep(10) sleep(10)
qdel(flick_holder) qdel(flick_holder)
@@ -843,6 +844,7 @@
var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc) var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc)
flick_holder.layer = layer + 0.1 flick_holder.layer = layer + 0.1
flick("popdown_[turret_type]", flick_holder) flick("popdown_[turret_type]", flick_holder)
playsound(src, 'sound/machines/turrets/turret_retract.ogg', 100, 1)
sleep(10) sleep(10)
qdel(flick_holder) qdel(flick_holder)
@@ -863,6 +865,7 @@
spawn() spawn()
popUp() //pop the turret up if it's not already up. popUp() //pop the turret up if it's not already up.
set_dir(get_dir(src, target)) //even if you can't shoot, follow the target set_dir(get_dir(src, target)) //even if you can't shoot, follow the target
playsound(src, 'sound/machines/turrets/turret_rotate.ogg', 100, 1) // Play rotating sound
spawn() spawn()
shootAt(target) shootAt(target)
return 1 return 1

View File

@@ -554,11 +554,13 @@
/obj/item/weapon/storage/box/wormcan = 4, /obj/item/weapon/storage/box/wormcan = 4,
/obj/item/weapon/storage/box/wormcan/sickly = 10, /obj/item/weapon/storage/box/wormcan/sickly = 10,
/obj/item/weapon/material/fishing_net = 2, /obj/item/weapon/material/fishing_net = 2,
/obj/item/glass_jar/fish = 4,
/obj/item/stack/cable_coil/random = 6) /obj/item/stack/cable_coil/random = 6)
prices = list(/obj/item/weapon/material/fishing_rod/modern/cheap = 50, prices = list(/obj/item/weapon/material/fishing_rod/modern/cheap = 50,
/obj/item/weapon/storage/box/wormcan = 12, /obj/item/weapon/storage/box/wormcan = 12,
/obj/item/weapon/storage/box/wormcan/sickly = 6, /obj/item/weapon/storage/box/wormcan/sickly = 6,
/obj/item/weapon/material/fishing_net = 40, /obj/item/weapon/material/fishing_net = 40,
/obj/item/glass_jar/fish = 10,
/obj/item/stack/cable_coil/random = 4) /obj/item/stack/cable_coil/random = 4)
premium = list(/obj/item/weapon/storage/box/wormcan/deluxe = 1) premium = list(/obj/item/weapon/storage/box/wormcan/deluxe = 1)
contraband = list(/obj/item/weapon/storage/box/wormcan/deluxe = 1) contraband = list(/obj/item/weapon/storage/box/wormcan/deluxe = 1)

View File

@@ -17,6 +17,14 @@
max_special_equip = 1 max_special_equip = 1
cargo_capacity = 1 cargo_capacity = 1
starting_components = list(
/obj/item/mecha_parts/component/hull/durable,
/obj/item/mecha_parts/component/actuator,
/obj/item/mecha_parts/component/armor/reinforced,
/obj/item/mecha_parts/component/gas,
/obj/item/mecha_parts/component/electrical
)
/* /*
/obj/mecha/combat/range_action(target as obj|mob|turf) /obj/mecha/combat/range_action(target as obj|mob|turf)
if(internal_damage&MECHA_INT_CONTROL_LOST) if(internal_damage&MECHA_INT_CONTROL_LOST)

View File

@@ -5,8 +5,8 @@
initial_icon = "durand" initial_icon = "durand"
step_in = 4 step_in = 4
dir_in = 1 //Facing North. dir_in = 1 //Facing North.
health = 400 health = 300
maxhealth = 400 //Don't forget to update the /old variant if you change this number. maxhealth = 300 //Don't forget to update the /old variant if you change this number.
deflect_chance = 20 deflect_chance = 20
damage_absorption = list("brute"=0.5,"fire"=1.1,"bullet"=0.65,"laser"=0.85,"energy"=0.9,"bomb"=0.8) damage_absorption = list("brute"=0.5,"fire"=1.1,"bullet"=0.65,"laser"=0.85,"energy"=0.9,"bomb"=0.8)
max_temperature = 30000 max_temperature = 30000
@@ -23,6 +23,14 @@
max_universal_equip = 1 max_universal_equip = 1
max_special_equip = 1 max_special_equip = 1
starting_components = list(
/obj/item/mecha_parts/component/hull/durable,
/obj/item/mecha_parts/component/actuator,
/obj/item/mecha_parts/component/armor/military,
/obj/item/mecha_parts/component/gas,
/obj/item/mecha_parts/component/electrical
)
defence_mode_possible = 1 defence_mode_possible = 1
/* /*
@@ -73,5 +81,5 @@
/obj/mecha/combat/durand/old/New() /obj/mecha/combat/durand/old/New()
..() ..()
health = 25 health = 25
maxhealth = 350 //Just slightly worse. maxhealth = 250 //Just slightly worse.
cell.charge = rand(0, (cell.charge/2)) cell.charge = rand(0, (cell.charge/2))

View File

@@ -5,8 +5,8 @@
initial_icon = "gygax" initial_icon = "gygax"
step_in = 3 step_in = 3
dir_in = 1 //Facing North. dir_in = 1 //Facing North.
health = 300 health = 250
maxhealth = 300 //Don't forget to update the /old variant if you change this number. maxhealth = 250 //Don't forget to update the /old variant if you change this number.
deflect_chance = 15 deflect_chance = 15
damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1) damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1)
max_temperature = 25000 max_temperature = 25000
@@ -21,6 +21,14 @@
max_universal_equip = 1 max_universal_equip = 1
max_special_equip = 1 max_special_equip = 1
starting_components = list(
/obj/item/mecha_parts/component/hull/lightweight,
/obj/item/mecha_parts/component/actuator,
/obj/item/mecha_parts/component/armor/marshal,
/obj/item/mecha_parts/component/gas,
/obj/item/mecha_parts/component/electrical
)
overload_possible = 1 overload_possible = 1
//Not quite sure how to move those yet. //Not quite sure how to move those yet.
@@ -58,17 +66,12 @@
max_universal_equip = 1 max_universal_equip = 1
max_special_equip = 2 max_special_equip = 2
/obj/mecha/combat/gygax/dark/Initialize() starting_equipment = list(
..() /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot,
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang,
ME.attach(src) /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang /obj/item/mecha_parts/mecha_equipment/teleporter
ME.attach(src) )
ME = new /obj/item/mecha_parts/mecha_equipment/teleporter
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
ME.attach(src)
return
/obj/mecha/combat/gygax/dark/add_cell(var/obj/item/weapon/cell/C=null) /obj/mecha/combat/gygax/dark/add_cell(var/obj/item/weapon/cell/C=null)
if(C) if(C)
@@ -101,6 +104,14 @@
max_universal_equip = 1 max_universal_equip = 1
max_special_equip = 1 max_special_equip = 1
starting_components = list(
/obj/item/mecha_parts/component/hull,
/obj/item/mecha_parts/component/actuator,
/obj/item/mecha_parts/component/armor/lightweight,
/obj/item/mecha_parts/component/gas,
/obj/item/mecha_parts/component/electrical
)
var/obj/item/clothing/glasses/hud/health/mech/hud var/obj/item/clothing/glasses/hud/health/mech/hud
/obj/mecha/combat/gygax/serenity/New() /obj/mecha/combat/gygax/serenity/New()

View File

@@ -5,8 +5,8 @@
icon_state = "marauder" icon_state = "marauder"
initial_icon = "marauder" initial_icon = "marauder"
step_in = 5 step_in = 5
health = 500 health = 350
maxhealth = 500 //Don't forget to update the /old variant if you change this number. maxhealth = 350 //Don't forget to update the /old variant if you change this number.
deflect_chance = 25 deflect_chance = 25
damage_absorption = list("brute"=0.5,"fire"=0.7,"bullet"=0.45,"laser"=0.6,"energy"=0.7,"bomb"=0.7) damage_absorption = list("brute"=0.5,"fire"=0.7,"bullet"=0.45,"laser"=0.6,"energy"=0.7,"bomb"=0.7)
max_temperature = 60000 max_temperature = 60000
@@ -29,6 +29,21 @@
zoom_possible = 1 zoom_possible = 1
thrusters_possible = 1 thrusters_possible = 1
starting_components = list(
/obj/item/mecha_parts/component/hull/durable,
/obj/item/mecha_parts/component/actuator,
/obj/item/mecha_parts/component/armor/military,
/obj/item/mecha_parts/component/gas,
/obj/item/mecha_parts/component/electrical
)
starting_equipment = list(
/obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse,
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive,
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster
)
/obj/mecha/combat/marauder/seraph /obj/mecha/combat/marauder/seraph
desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel." desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel."
name = "Seraph" name = "Seraph"
@@ -37,12 +52,20 @@
initial_icon = "seraph" initial_icon = "seraph"
operation_req_access = list(access_cent_creed) operation_req_access = list(access_cent_creed)
step_in = 3 step_in = 3
health = 550 health = 450
wreckage = /obj/effect/decal/mecha_wreckage/seraph wreckage = /obj/effect/decal/mecha_wreckage/seraph
internal_damage_threshold = 20 internal_damage_threshold = 20
force = 55 force = 55
max_equip = 5 max_equip = 5
starting_equipment = list(
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot,
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive,
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster,
/obj/item/mecha_parts/mecha_equipment/teleporter
)
//Note that is the Mauler //Note that is the Mauler
/obj/mecha/combat/marauder/mauler /obj/mecha/combat/marauder/mauler
desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model." desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model."
@@ -53,40 +76,6 @@
wreckage = /obj/effect/decal/mecha_wreckage/mauler wreckage = /obj/effect/decal/mecha_wreckage/mauler
mech_faction = MECH_FACTION_SYNDI mech_faction = MECH_FACTION_SYNDI
//Note that is the default Marauder
/obj/mecha/combat/marauder/Initialize()
..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src)
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
ME.attach(src)
return
//Note that this is the seraph.
/obj/mecha/combat/marauder/seraph/Initialize()
..()//Let it equip whatever is needed.
var/obj/item/mecha_parts/mecha_equipment/ME
if(equipment.len)//Now to remove it and equip anew.
for(ME in equipment)
ME.detach()
qdel(ME)
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src)
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive(src)
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/teleporter(src)
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src)
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
ME.attach(src)
return
//I'll break this down later //I'll break this down later
/obj/mecha/combat/marauder/relaymove(mob/user,direction) /obj/mecha/combat/marauder/relaymove(mob/user,direction)
if(user != src.occupant) //While not "realistic", this piece is player friendly. if(user != src.occupant) //While not "realistic", this piece is player friendly.
@@ -150,17 +139,10 @@
/obj/mecha/combat/marauder/old /obj/mecha/combat/marauder/old
desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations. This one is particularly worn looking and likely isn't as sturdy." desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations. This one is particularly worn looking and likely isn't as sturdy."
starting_equipment = null
/obj/mecha/combat/marauder/old/New() /obj/mecha/combat/marauder/old/New()
..() ..()
health = 25 health = 25
maxhealth = 400 //Just slightly worse. maxhealth = 300 //Just slightly worse.
cell.charge = rand(0, (cell.charge/2)) cell.charge = rand(0, (cell.charge/2))
/obj/mecha/combat/marauder/old/Initialize()
..()
var/obj/item/mecha_parts/mecha_equipment/ME
if(equipment.len)
for(ME in equipment)
ME.detach()
qdel(ME)
return

View File

@@ -25,15 +25,24 @@
max_universal_equip = 3 max_universal_equip = 3
max_special_equip = 4 max_special_equip = 4
phasing_possible = 1 starting_components = list(
switch_dmg_type_possible = 1 /obj/item/mecha_parts/component/hull/durable,
/obj/item/mecha_parts/component/actuator,
/obj/item/mecha_parts/component/armor/alien,
/obj/item/mecha_parts/component/gas,
/obj/item/mecha_parts/component/electrical
)
cloak_possible = TRUE
phasing_possible = TRUE
switch_dmg_type_possible = TRUE
/obj/mecha/combat/phazon/equipped/Initialize() /obj/mecha/combat/phazon/equipped/Initialize()
..() ..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/rcd starting_equipment = list(
ME.attach(src) /obj/item/mecha_parts/mecha_equipment/tool/rcd,
ME = new /obj/item/mecha_parts/mecha_equipment/gravcatapult /obj/item/mecha_parts/mecha_equipment/gravcatapult
ME.attach(src) )
return return
/* Leaving this until we are really sure we don't need it for reference. /* Leaving this until we are really sure we don't need it for reference.
@@ -95,8 +104,9 @@
max_universal_equip = 2 max_universal_equip = 2
max_special_equip = 2 max_special_equip = 2
phasing_possible = 1 phasing_possible = TRUE
switch_dmg_type_possible = 1 switch_dmg_type_possible = TRUE
cloak_possible = FALSE
/obj/mecha/combat/phazon/janus/take_damage(amount, type="brute") /obj/mecha/combat/phazon/janus/take_damage(amount, type="brute")
..() ..()

View File

@@ -0,0 +1,155 @@
/obj/item/mecha_parts/component
name = "mecha component"
icon = 'icons/mecha/mech_component.dmi'
icon_state = "component"
w_class = ITEMSIZE_HUGE
origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
var/component_type = null
var/obj/mecha/chassis = null
var/start_damaged = FALSE
var/emp_resistance = 0 // Amount of emp 'levels' removed.
var/list/required_type = null // List, if it exists. Exosuits meant to use the component (Unique var changes / effects)
var/integrity
var/integrity_danger_mod = 0.5 // Multiplier for comparison to max_integrity before problems start.
var/max_integrity = 100
var/step_delay = 0
var/relative_size = 30 // Percent chance for the component to be hit.
var/internal_damage_flag // If set, the component will toggle the flag on or off if it is destroyed / severely damaged.
/obj/item/mecha_parts/component/examine(mob/user)
. = ..()
var/show_integrity = round(integrity/max_integrity*100, 0.1)
switch(show_integrity)
if(85 to 100)
. += "It's fully intact."
if(65 to 85)
. += "It's slightly damaged."
if(45 to 65)
. += "<span class='notice'>It's badly damaged.</span>"
if(25 to 45)
. += "<span class='warning'>It's heavily damaged.</span>"
if(2 to 25)
. += "<span class='warning'><b>It's falling apart.</b></span>"
if(0 to 1)
. += "<span class='warning'><b>It is completely destroyed.</b></span>"
/obj/item/mecha_parts/component/Initialize()
..()
integrity = max_integrity
if(start_damaged)
integrity = round(integrity * integrity_danger_mod)
/obj/item/mecha_parts/component/Destroy()
detach()
return ..()
// Damage code.
/obj/item/mecha_parts/component/emp_act(var/severity = 4)
if(severity + emp_resistance > 4)
return
severity = clamp(severity + emp_resistance, 1, 4)
take_damage((4 - severity) * round(integrity * 0.1, 0.1))
/obj/item/mecha_parts/component/proc/adjust_integrity(var/amt = 0)
integrity = clamp(integrity + amt, 0, max_integrity)
return
/obj/item/mecha_parts/component/proc/damage_part(var/dam_amt = 0, var/type = BRUTE)
if(dam_amt <= 0)
return FALSE
adjust_integrity(-1 * dam_amt)
if(chassis && internal_damage_flag)
if(get_efficiency() < 0.5)
chassis.check_for_internal_damage(list(internal_damage_flag), TRUE)
return TRUE
/obj/item/mecha_parts/component/proc/get_efficiency()
var/integ_limit = round(max_integrity * integrity_danger_mod)
if(integrity < integ_limit)
var/int_percent = round(integrity / integ_limit, 0.1)
return int_percent
return 1
// Attach/Detach code.
/obj/item/mecha_parts/component/proc/attach(var/obj/mecha/target, var/mob/living/user)
if(target)
if(!(component_type in target.internal_components))
if(user)
to_chat(user, "<span class='notice'>\The [target] doesn't seem to have anywhere to put \the [src].</span>")
return FALSE
if(target.internal_components[component_type])
if(user)
to_chat(user, "<span class='notice'>\The [target] already has a [component_type] installed!</span>")
return FALSE
chassis = target
if(user)
user.drop_from_inventory(src)
forceMove(target)
if(internal_damage_flag)
if(integrity > (max_integrity * integrity_danger_mod))
if(chassis.hasInternalDamage(internal_damage_flag))
chassis.clearInternalDamage(internal_damage_flag)
else
chassis.check_for_internal_damage(list(internal_damage_flag))
chassis.internal_components[component_type] = src
if(user)
chassis.visible_message("<span class='notice'>[user] installs \the [src] in \the [chassis].</span>")
return TRUE
return FALSE
/obj/item/mecha_parts/component/proc/detach()
if(chassis)
chassis.internal_components[component_type] = null
if(internal_damage_flag && chassis.hasInternalDamage(internal_damage_flag)) // If the module has been removed, it's kind of unfair to keep it causing problems by being damaged. It's nonfunctional either way.
chassis.clearInternalDamage(internal_damage_flag)
forceMove(get_turf(chassis))
chassis = null
return TRUE
/obj/item/mecha_parts/component/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/stack/nanopaste))
var/obj/item/stack/nanopaste/NP = W
if(integrity < max_integrity)
while(integrity < max_integrity && NP)
if(do_after(user, 1 SECOND, src) && NP.use(1))
adjust_integrity(10)
return
return ..()
// Various procs to handle different calls by Exosuits. IE, movement actions, damage actions, etc.
/obj/item/mecha_parts/component/proc/get_step_delay()
return step_delay
/obj/item/mecha_parts/component/proc/handle_move()
return

View File

@@ -0,0 +1,37 @@
/obj/item/mecha_parts/component/actuator
name = "mecha actuator"
icon = 'icons/mecha/mech_component.dmi'
icon_state = "motor"
w_class = ITEMSIZE_HUGE
origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
component_type = MECH_ACTUATOR
start_damaged = FALSE
emp_resistance = 1
required_type = null // List, if it exists. Exosuits meant to use the component.
integrity_danger_mod = 0.6 // Multiplier for comparison to max_integrity before problems start.
max_integrity = 50
internal_damage_flag = MECHA_INT_CONTROL_LOST
var/strafing_multiplier = 1.5
/obj/item/mecha_parts/component/actuator/get_step_delay()
return step_delay
/obj/item/mecha_parts/component/actuator/hispeed
name = "overclocked mecha actuator"
step_delay = -1
emp_resistance = -1
integrity_danger_mod = 0.7
max_integrity = 60
strafing_multiplier = 1.2

View File

@@ -0,0 +1,238 @@
/obj/item/mecha_parts/component/armor
name = "mecha plating"
icon = 'icons/mecha/mech_component.dmi'
icon_state = "armor"
w_class = ITEMSIZE_HUGE
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 2)
component_type = MECH_ARMOR
start_damaged = FALSE
emp_resistance = 4
required_type = null // List, if it exists. Exosuits meant to use the component.
integrity_danger_mod = 0.4 // Multiplier for comparison to max_integrity before problems start.
max_integrity = 120
internal_damage_flag = MECHA_INT_TEMP_CONTROL
step_delay = 1
var/deflect_chance = 10
var/list/damage_absorption = list(
"brute"= 0.8,
"fire"= 1.2,
"bullet"= 0.9,
"laser"= 1,
"energy"= 1,
"bomb"= 1,
"bio"= 1,
"rad"= 1
)
var/damage_minimum = 10
var/minimum_penetration = 0
var/fail_penetration_value = 0.66
/obj/item/mecha_parts/component/armor/mining
name = "blast-resistant mecha plating"
step_delay = 2
max_integrity = 80
damage_absorption = list(
"brute"=0.8,
"fire"=0.8,
"bullet"=1.2,
"laser"=1.2,
"energy"=1,
"bomb"=0.5,
"bio"=1,
"rad"=1
)
/obj/item/mecha_parts/component/armor/lightweight
name = "lightweight mecha plating"
max_integrity = 50
step_delay = 0
damage_absorption = list(
"brute"=1,
"fire"=1.4,
"bullet"=1.1,
"laser"=1.2,
"energy"=1,
"bomb"=1,
"bio"=1,
"rad"=1
)
/obj/item/mecha_parts/component/armor/reinforced
name = "reinforced mecha plating"
step_delay = 4
max_integrity = 80
minimum_penetration = 10
damage_absorption = list(
"brute"=0.7,
"fire"=1,
"bullet"=0.7,
"laser"=0.85,
"energy"=1,
"bomb"=0.8
)
/obj/item/mecha_parts/component/armor/military
name = "military grade mecha plating"
step_delay = 6
max_integrity = 100
emp_resistance = 2
required_type = list(/obj/mecha/combat)
damage_minimum = 15
minimum_penetration = 25
damage_absorption = list(
"brute"=0.5,
"fire"=1.1,
"bullet"=0.65,
"laser"=0.85,
"energy"=0.9,
"bomb"=0.8
)
/obj/item/mecha_parts/component/armor/military/attach(var/obj/mecha/target, var/mob/living/user)
. = ..()
if(.)
var/typepass = FALSE
for(var/type in required_type)
if(istype(chassis, type))
typepass = TRUE
if(typepass)
step_delay = 3
else
step_delay = initial(step_delay)
/obj/item/mecha_parts/component/armor/marshal
name = "marshal mecha plating"
step_delay = 5
max_integrity = 100
emp_resistance = 3
deflect_chance = 15
minimum_penetration = 10
required_type = list(/obj/mecha/combat)
damage_absorption = list(
"brute"=0.75,
"fire"=1,
"bullet"=0.8,
"laser"=0.7,
"energy"=0.85,
"bomb"=1
)
/obj/item/mecha_parts/component/armor/marshal/attach(var/obj/mecha/target, var/mob/living/user)
. = ..()
if(.)
var/typepass = FALSE
for(var/type in required_type)
if(istype(chassis, type))
typepass = TRUE
if(typepass)
step_delay = 2
else
step_delay = initial(step_delay)
/obj/item/mecha_parts/component/armor/marshal/reinforced
name = "blackops mecha plating"
step_delay = 5
damage_absorption = list(
"brute"=0.6,
"fire"=0.8,
"bullet"=0.6,
"laser"=0.5,
"energy"=0.65,
"bomb"=0.8
)
/obj/item/mecha_parts/component/armor/military/marauder
name = "cutting edge mecha plating"
step_delay = 4
max_integrity = 150
emp_resistance = 3
required_type = list(/obj/mecha/combat/marauder)
deflect_chance = 25
damage_minimum = 30
minimum_penetration = 25
damage_absorption = list(
"brute"=0.5,
"fire"=0.7,
"bullet"=0.45,
"laser"=0.6,
"energy"=0.7,
"bomb"=0.7
)
/obj/item/mecha_parts/component/armor/military/marauder/attach(var/obj/mecha/target, var/mob/living/user)
. = ..()
if(.)
var/typepass = FALSE
for(var/type in required_type)
if(istype(chassis, type))
typepass = TRUE
if(typepass)
step_delay = 1
else
step_delay = initial(step_delay)
/obj/item/mecha_parts/component/armor/alien
name = "strange mecha plating"
step_delay = 3
damage_absorption = list(
"brute"=0.7,
"fire"=0.7,
"bullet"=0.7,
"laser"=0.7,
"energy"=0.7,
"bomb"=0.7
)
/obj/item/mecha_parts/component/armor/alien/attach(var/obj/mecha/target, var/mob/living/user)
. = ..()
if(.)
if(istype(target, /obj/mecha/combat/phazon/janus))
step_delay = -1
else if(istype(target, /obj/mecha/combat/phazon))
step_delay = -3
else
step_delay = initial(step_delay)

View File

@@ -0,0 +1,31 @@
/obj/item/mecha_parts/component/electrical
name = "mecha electrical harness"
icon = 'icons/mecha/mech_component.dmi'
icon_state = "board"
w_class = ITEMSIZE_HUGE
origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
component_type = MECH_ELECTRIC
emp_resistance = 1
integrity_danger_mod = 0.4
max_integrity = 40
step_delay = 0
relative_size = 20
internal_damage_flag = MECHA_INT_SHORT_CIRCUIT
var/charge_cost_mod = 1
/obj/item/mecha_parts/component/electrical/high_current
name = "efficient mecha electrical harness"
emp_resistance = 0
max_integrity = 30
relative_size = 10
charge_cost_mod = 0.6

View File

@@ -0,0 +1,33 @@
/obj/item/mecha_parts/component/hull
name = "mecha hull"
icon = 'icons/mecha/mech_component.dmi'
icon_state = "hull"
w_class = ITEMSIZE_HUGE
origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
component_type = MECH_HULL
emp_resistance = 0 // Amount of emp 'levels' removed.
required_type = null // List, if it exists. Exosuits meant to use the component.
integrity_danger_mod = 0.5 // Multiplier for comparison to max_integrity before problems start.
max_integrity = 50
internal_damage_flag = MECHA_INT_FIRE
step_delay = 2
/obj/item/mecha_parts/component/hull/durable
name = "durable mecha hull"
step_delay = 4
integrity_danger_mod = 0.3
max_integrity = 100
/obj/item/mecha_parts/component/hull/lightweight
name = "lightweight mecha hull"
step_delay = 1
integrity_danger_mod = 0.3

View File

@@ -0,0 +1,28 @@
/obj/item/mecha_parts/component/gas
name = "mecha life-support"
icon = 'icons/mecha/mech_component.dmi'
icon_state = "lifesupport"
w_class = ITEMSIZE_HUGE
origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
component_type = MECH_GAS
emp_resistance = 1
integrity_danger_mod = 0.4
max_integrity = 40
step_delay = 0
relative_size = 20
internal_damage_flag = MECHA_INT_TANK_BREACH
/obj/item/mecha_parts/component/gas/reinforced
name = "reinforced mecha life-support"
emp_resistance = 2
max_integrity = 80
relative_size = 40

View File

@@ -24,6 +24,8 @@
var/ready_sound = 'sound/mecha/mech_reload_default.ogg' //Sound to play once the fire delay passed. var/ready_sound = 'sound/mecha/mech_reload_default.ogg' //Sound to play once the fire delay passed.
var/enable_special = FALSE // Will the tool do its special? var/enable_special = FALSE // Will the tool do its special?
var/step_delay = 0 // Does the component slow/speed up the suit?
/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(target=1) /obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(target=1)
sleep(equip_cooldown) sleep(equip_cooldown)
set_ready_state(1) set_ready_state(1)
@@ -241,3 +243,6 @@
/obj/item/mecha_parts/mecha_equipment/proc/MoveAction() //Allows mech equipment to do an action upon the mech moving /obj/item/mecha_parts/mecha_equipment/proc/MoveAction() //Allows mech equipment to do an action upon the mech moving
return return
/obj/item/mecha_parts/mecha_equipment/proc/get_step_delay() // Equipment returns its slowdown or speedboost.
return step_delay

View File

@@ -9,6 +9,8 @@
var/deflect_coeff = 1.15 var/deflect_coeff = 1.15
var/damage_coeff = 0.8 var/damage_coeff = 0.8
step_delay = 1
equip_type = EQUIP_HULL equip_type = EQUIP_HULL
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/get_equip_info() /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/get_equip_info()

View File

@@ -9,6 +9,8 @@
var/deflect_coeff = 1.15 var/deflect_coeff = 1.15
var/damage_coeff = 0.8 var/damage_coeff = 0.8
step_delay = 2
equip_type = EQUIP_HULL equip_type = EQUIP_HULL
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/handle_projectile_contact(var/obj/item/projectile/Proj, var/inc_damage) /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/handle_projectile_contact(var/obj/item/projectile/Proj, var/inc_damage)

View File

@@ -11,6 +11,8 @@
var/icon/droid_overlay var/icon/droid_overlay
var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH) var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH)
step_delay = 1
equip_type = EQUIP_HULL equip_type = EQUIP_HULL
/obj/item/mecha_parts/mecha_equipment/repair_droid/New() /obj/item/mecha_parts/mecha_equipment/repair_droid/New()
@@ -79,8 +81,23 @@
RD.chassis.clearInternalDamage(int_dam_flag) RD.chassis.clearInternalDamage(int_dam_flag)
repaired = 1 repaired = 1
break break
if(health_boost<0 || RD.chassis.health < initial(RD.chassis.health))
var/obj/item/mecha_parts/component/AC = RD.chassis.internal_components[MECH_ARMOR]
var/obj/item/mecha_parts/component/HC = RD.chassis.internal_components[MECH_HULL]
var/damaged_armor = AC.integrity < AC.max_integrity
var/damaged_hull = HC.integrity < HC.max_integrity
if(health_boost<0 || RD.chassis.health < initial(RD.chassis.health) || damaged_armor || damaged_hull)
RD.chassis.health += min(health_boost, initial(RD.chassis.health)-RD.chassis.health) RD.chassis.health += min(health_boost, initial(RD.chassis.health)-RD.chassis.health)
if(AC)
AC.adjust_integrity(round(health_boost * 0.5, 0.5))
if(HC)
HC.adjust_integrity(round(health_boost * 0.5, 0.5))
repaired = 1 repaired = 1
if(repaired) if(repaired)
if(RD.chassis.use_power(RD.energy_drain)) if(RD.chassis.use_power(RD.energy_drain))

View File

@@ -7,6 +7,8 @@
energy_drain = 20 energy_drain = 20
range = 0 range = 0
step_delay = 1
var/obj/item/shield_projector/line/exosuit/my_shield = null var/obj/item/shield_projector/line/exosuit/my_shield = null
var/my_shield_type = /obj/item/shield_projector/line/exosuit var/my_shield_type = /obj/item/shield_projector/line/exosuit
var/icon/drone_overlay var/icon/drone_overlay
@@ -66,9 +68,11 @@
my_shield.attack_self(chassis.occupant) my_shield.attack_self(chassis.occupant)
if(my_shield.active) if(my_shield.active)
set_ready_state(0) set_ready_state(0)
step_delay = 4
log_message("Activated.") log_message("Activated.")
else else
set_ready_state(1) set_ready_state(1)
step_delay = 1
log_message("Deactivated.") log_message("Deactivated.")
/obj/item/mecha_parts/mecha_equipment/combat_shield/Topic(href, href_list) /obj/item/mecha_parts/mecha_equipment/combat_shield/Topic(href, href_list)

View File

@@ -9,6 +9,8 @@
energy_drain = OMNI_SHIELD_DRAIN energy_drain = OMNI_SHIELD_DRAIN
range = 0 range = 0
step_delay = 1
var/obj/item/shield_projector/shields = null var/obj/item/shield_projector/shields = null
var/shield_type = /obj/item/shield_projector/rectangle/mecha var/shield_type = /obj/item/shield_projector/rectangle/mecha
@@ -42,9 +44,11 @@
shields.set_on(!shields.active) shields.set_on(!shields.active)
if(shields.active) if(shields.active)
set_ready_state(0) set_ready_state(0)
step_delay = 4
log_message("Activated.") log_message("Activated.")
else else
set_ready_state(1) set_ready_state(1)
step_delay = 1
log_message("Deactivated.") log_message("Deactivated.")
/obj/item/mecha_parts/mecha_equipment/omni_shield/Topic(href, href_list) /obj/item/mecha_parts/mecha_equipment/omni_shield/Topic(href, href_list)

View File

@@ -7,6 +7,9 @@
equip_type = EQUIP_HULL equip_type = EQUIP_HULL
var/slowdown_multiplier = 0.75 // How much does the exosuit multiply its slowdown by if it's the proper type?
/*
/obj/item/mecha_parts/mecha_equipment/speedboost/attach(obj/mecha/M as obj) /obj/item/mecha_parts/mecha_equipment/speedboost/attach(obj/mecha/M as obj)
..() ..()
if(enable_special) if(enable_special)
@@ -14,6 +17,13 @@
else else
chassis.step_in = 6 // Improper parts slow the mech down chassis.step_in = 6 // Improper parts slow the mech down
return return
*/
/obj/item/mecha_parts/mecha_equipment/speedboost/get_step_delay()
if(enable_special)
return -1
else
return 3
/obj/item/mecha_parts/mecha_equipment/speedboost/detach() /obj/item/mecha_parts/mecha_equipment/speedboost/detach()
chassis.step_in = initial(chassis.step_in) chassis.step_in = initial(chassis.step_in)

View File

@@ -11,6 +11,8 @@
projectile = /obj/item/projectile/arc/fragmentation/mortar projectile = /obj/item/projectile/arc/fragmentation/mortar
projectile_energy_cost = 600 projectile_energy_cost = 600
step_delay = 2
origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_ILLEGAL = 3) origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_ILLEGAL = 3)
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/mortar/action_checks(atom/target) /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/mortar/action_checks(atom/target)

View File

@@ -11,6 +11,8 @@
deviation = 0.7 deviation = 0.7
projectile_energy_cost = 25 projectile_energy_cost = 25
step_delay = 2
origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4) origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4)
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot/rigged /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot/rigged

View File

@@ -52,6 +52,8 @@
projectile = /obj/item/projectile/beam/heavylaser projectile = /obj/item/projectile/beam/heavylaser
fire_sound = 'sound/weapons/lasercannonfire.ogg' fire_sound = 'sound/weapons/lasercannonfire.ogg'
step_delay = 2
origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4, TECH_MAGNET = 4) origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4, TECH_MAGNET = 4)
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/rigged /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/rigged

View File

@@ -2,6 +2,8 @@
var/missile_speed = 2 var/missile_speed = 2
var/missile_range = 30 var/missile_range = 30
step_delay = 2
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc) /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc)
AM.throw_at(target,missile_range, missile_speed, chassis) AM.throw_at(target,missile_range, missile_speed, chassis)
@@ -19,6 +21,8 @@
missile_range = 15 missile_range = 15
required_type = /obj/mecha //Why restrict it to just mining or combat mechs? required_type = /obj/mecha //Why restrict it to just mining or combat mechs?
step_delay = 0
equip_type = EQUIP_UTILITY equip_type = EQUIP_UTILITY
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare/Fire(atom/movable/AM, atom/target, turf/aimloc) /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare/Fire(atom/movable/AM, atom/target, turf/aimloc)

View File

@@ -7,6 +7,8 @@
energy_drain = 30 energy_drain = 30
step_delay = 2
projectile = /obj/item/projectile/bullet/incendiary/flamethrower/large projectile = /obj/item/projectile/bullet/incendiary/flamethrower/large
fire_sound = 'sound/weapons/towelwipe.ogg' fire_sound = 'sound/weapons/towelwipe.ogg'

View File

@@ -16,3 +16,5 @@
projectile_energy_cost = 40 projectile_energy_cost = 40
fire_cooldown = 3 fire_cooldown = 3
origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_PHORON = 2, TECH_ILLEGAL = 1) origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_PHORON = 2, TECH_ILLEGAL = 1)
step_delay = 1

View File

@@ -12,6 +12,8 @@
var/auto_rearm = 0 //Does the weapon reload itself after each shot? var/auto_rearm = 0 //Does the weapon reload itself after each shot?
required_type = list(/obj/mecha/combat, /obj/mecha/working/hoverpod/combatpod) required_type = list(/obj/mecha/combat, /obj/mecha/working/hoverpod/combatpod)
step_delay = 1
equip_type = EQUIP_WEAPON equip_type = EQUIP_WEAPON
/obj/item/mecha_parts/mecha_equipment/weapon/action_checks(atom/target) /obj/item/mecha_parts/mecha_equipment/weapon/action_checks(atom/target)

View File

@@ -7,6 +7,11 @@
#define MELEE 1 #define MELEE 1
#define RANGED 2 #define RANGED 2
#define MECHA_OPERATING 0
#define MECHA_BOLTS_SECURED 1
#define MECHA_PANEL_LOOSE 2
#define MECHA_CELL_OPEN 3
#define MECHA_CELL_OUT 4
#define MECH_FACTION_NT "nano" #define MECH_FACTION_NT "nano"
#define MECH_FACTION_SYNDI "syndi" #define MECH_FACTION_SYNDI "syndi"
@@ -48,7 +53,7 @@
var/fail_penetration_value = 0.66 //By how much failing to penetrate reduces your shit. 66% by default. var/fail_penetration_value = 0.66 //By how much failing to penetrate reduces your shit. 66% by default.
var/obj/item/weapon/cell/cell var/obj/item/weapon/cell/cell
var/state = 0 var/state = MECHA_OPERATING
var/list/log = new var/list/log = new
var/last_message = 0 var/last_message = 0
var/add_req_access = 1 var/add_req_access = 1
@@ -108,6 +113,24 @@
var/max_universal_equip = 2 var/max_universal_equip = 2
var/max_special_equip = 1 var/max_special_equip = 1
var/list/starting_equipment = null // List containing starting tools.
// Mech Components, similar to Cyborg, but Bigger.
var/list/internal_components = list(
MECH_HULL = null,
MECH_ACTUATOR = null,
MECH_ARMOR = null,
MECH_GAS = null,
MECH_ELECTRIC = null
)
var/list/starting_components = list(
/obj/item/mecha_parts/component/hull,
/obj/item/mecha_parts/component/actuator,
/obj/item/mecha_parts/component/armor,
/obj/item/mecha_parts/component/gas,
/obj/item/mecha_parts/component/electrical
)
//Working exosuit vars //Working exosuit vars
var/list/cargo = list() var/list/cargo = list()
var/cargo_capacity = 3 var/cargo_capacity = 3
@@ -117,6 +140,7 @@
var/static/image/radial_image_lighttoggle = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_light") var/static/image/radial_image_lighttoggle = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_light")
var/static/image/radial_image_statpanel = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine2") var/static/image/radial_image_statpanel = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine2")
var/datum/mini_hud/mech/minihud
//Mech actions //Mech actions
@@ -140,7 +164,7 @@
var/phasing_possible = 0 //This is to allow phasing. var/phasing_possible = 0 //This is to allow phasing.
var/can_phase = TRUE //This is an internal check during the relevant procs. var/can_phase = TRUE //This is an internal check during the relevant procs.
var/phasing_energy_drain = 200 var/phasing_energy_drain = 200
var/switch_dmg_type_possible = 0 //Can you switch damage type? It is mostly for the Phazon and its children. var/switch_dmg_type_possible = 0 //Can you switch damage type? It is mostly for the Phazon and its children.
var/smoke_possible = 0 var/smoke_possible = 0
@@ -149,6 +173,8 @@
var/smoke_cooldown = 100 //How long you have between uses. var/smoke_cooldown = 100 //How long you have between uses.
var/datum/effect/effect/system/smoke_spread/smoke_system = new var/datum/effect/effect/system/smoke_spread/smoke_system = new
var/cloak_possible = FALSE // Can this exosuit innately cloak?
////All of those are for the HUD buttons in the top left. See Grant and Remove procs in mecha_actions. ////All of those are for the HUD buttons in the top left. See Grant and Remove procs in mecha_actions.
var/datum/action/innate/mecha/mech_eject/eject_action = new var/datum/action/innate/mecha/mech_eject/eject_action = new
@@ -165,10 +191,20 @@
var/datum/action/innate/mecha/mech_cycle_equip/cycle_action = new var/datum/action/innate/mecha/mech_cycle_equip/cycle_action = new
var/datum/action/innate/mecha/mech_switch_damtype/switch_damtype_action = new var/datum/action/innate/mecha/mech_switch_damtype/switch_damtype_action = new
var/datum/action/innate/mecha/mech_toggle_phasing/phasing_action = new var/datum/action/innate/mecha/mech_toggle_phasing/phasing_action = new
var/datum/action/innate/mecha/mech_toggle_cloaking/cloak_action = new
var/weapons_only_cycle = FALSE //So combat mechs don't switch to their equipment at times. var/weapons_only_cycle = FALSE //So combat mechs don't switch to their equipment at times.
/obj/mecha/Initialize()
..()
for(var/path in starting_components)
var/obj/item/mecha_parts/component/C = new path(src)
C.attach(src)
if(starting_equipment && LAZYLEN(starting_equipment))
for(var/path in starting_equipment)
var/obj/item/mecha_parts/mecha_equipment/ME = new path(src)
ME.attach(src)
/obj/mecha/drain_power(var/drain_check) /obj/mecha/drain_power(var/drain_check)
@@ -247,6 +283,15 @@
else else
E.forceMove(loc) E.forceMove(loc)
E.destroy() E.destroy()
for(var/slot in internal_components)
var/obj/item/mecha_parts/component/C = internal_components[slot]
if(istype(C))
C.damage_part(rand(10, 20))
C.detach()
WR.crowbar_salvage += C
C.forceMove(WR)
if(cell) if(cell)
WR.crowbar_salvage += cell WR.crowbar_salvage += cell
cell.forceMove(WR) cell.forceMove(WR)
@@ -258,6 +303,11 @@
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
E.detach(loc) E.detach(loc)
E.destroy() E.destroy()
for(var/slot in internal_components)
var/obj/item/mecha_parts/component/C = internal_components[slot]
if(istype(C))
C.detach()
qdel(C)
if(cell) if(cell)
qdel(cell) qdel(cell)
if(internal_tank) if(internal_tank)
@@ -274,6 +324,7 @@
QDEL_NULL(pr_give_air) QDEL_NULL(pr_give_air)
QDEL_NULL(pr_internal_damage) QDEL_NULL(pr_internal_damage)
QDEL_NULL(spark_system) QDEL_NULL(spark_system)
QDEL_NULL(minihud)
mechas_list -= src //global mech list mechas_list -= src //global mech list
. = ..() . = ..()
@@ -352,6 +403,26 @@
/obj/mecha/examine(mob/user) /obj/mecha/examine(mob/user)
. = ..() . = ..()
var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR]
var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL]
if(AC)
. += "It has [AC] attached. [AC.get_efficiency()<0.5?"It is severely damaged.":""]"
else
. += "It has no armor plating."
if(HC)
if(!AC || AC.get_efficiency() < 0.7)
. += "It has [HC] attached. [HC.get_efficiency()<0.5?"It is severely damaged.":""]"
else
. += "You cannot tell what type of hull it has."
else
. += "It does not seem to have a completed hull."
var/integrity = health/initial(health)*100 var/integrity = health/initial(health)*100
switch(integrity) switch(integrity)
if(85 to 100) if(85 to 100)
@@ -537,6 +608,12 @@
user.forceMove(get_turf(src)) user.forceMove(get_turf(src))
to_chat(user, "You climb out from [src]") to_chat(user, "You climb out from [src]")
return 0 return 0
var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL]
if(!HC)
occupant_message("<span class='notice'>You can't operate an exosuit that doesn't have a hull!</span>")
return
if(connected_port) if(connected_port)
if(world.time - last_message > 20) if(world.time - last_message > 20)
src.occupant_message("<span class='warning'>Unable to move while connected to the air system port</span>") src.occupant_message("<span class='warning'>Unable to move while connected to the air system port</span>")
@@ -563,6 +640,44 @@
return call((proc_res["dyndomove"]||src), "dyndomove")(direction) return call((proc_res["dyndomove"]||src), "dyndomove")(direction)
/obj/mecha/proc/get_step_delay()
var/tally = 0
if(overload)
tally = min(1, round(step_in/2))
for(var/slot in internal_components)
var/obj/item/mecha_parts/component/C = internal_components[slot]
if(C && C.get_step_delay())
tally += C.get_step_delay()
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
if(ME.get_step_delay())
tally += ME.get_step_delay()
var/obj/item/mecha_parts/component/actuator/actuator = internal_components[MECH_ACTUATOR]
if(!actuator) // Relying purely on hydraulic pumps. You're going nowhere fast.
tally = 2 SECONDS
return tally
tally += 0.5 SECONDS * (1 - actuator.get_efficiency()) // Damaged actuators run slower, slowing as damage increases beyond its threshold.
if(strafing)
tally = round(tally * actuator.strafing_multiplier)
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
if(istype(ME, /obj/item/mecha_parts/mecha_equipment/speedboost))
var/obj/item/mecha_parts/mecha_equipment/speedboost/SB = ME
for(var/path in ME.required_type)
if(istype(src, path))
tally = round(tally * SB.slowdown_multiplier)
break
break
return max(1, round(tally))
/obj/mecha/proc/dyndomove(direction) /obj/mecha/proc/dyndomove(direction)
if(!can_move) if(!can_move)
return 0 return 0
@@ -585,6 +700,15 @@
last_message = world.time last_message = world.time
return 0 return 0
/*
//A first draft of a check to stop mechs from moving fully. TBD when all thrusters modules are unified.
if(!thrusters && !src.pr_inertial_movement.active() && isspace(src.loc))//No thrsters, not drifting, in space
src.occupant_message("Error 543")//debug
return 0
*/
if(!thrusters && src.pr_inertial_movement.active()) //I think this mean 'if you try to move in space without thruster, u no move' if(!thrusters && src.pr_inertial_movement.active()) //I think this mean 'if you try to move in space without thruster, u no move'
return 0 return 0
@@ -592,7 +716,6 @@
health-- health--
if(health < initial(health) - initial(health)/3) if(health < initial(health) - initial(health)/3)
overload = 0 overload = 0
step_in = initial(step_in)
step_energy_drain = initial(step_energy_drain) step_energy_drain = initial(step_energy_drain)
src.occupant_message("<font color='red'>Leg actuators damage threshold exceded. Disabling overload.</font>") src.occupant_message("<font color='red'>Leg actuators damage threshold exceded. Disabling overload.</font>")
@@ -648,7 +771,7 @@
if(!src.check_for_support()) if(!src.check_for_support())
src.pr_inertial_movement.start(list(src,direction)) src.pr_inertial_movement.start(list(src,direction))
src.log_message("<span class='warning'>Movement control lost. Inertial movement started.</span>") src.log_message("<span class='warning'>Movement control lost. Inertial movement started.</span>")
if(do_after(step_in)) if(do_after(get_step_delay()))
can_move = 1 can_move = 1
return 1 return 1
return 0 return 0
@@ -700,7 +823,7 @@
flick("[initial_icon]-phase", src) flick("[initial_icon]-phase", src)
src.loc = get_step(src,src.dir) src.loc = get_step(src,src.dir)
src.use_power(phasing_energy_drain) src.use_power(phasing_energy_drain)
sleep(step_in*3) sleep(get_step_delay() * 3)
can_phase = TRUE can_phase = TRUE
occupant_message("Phazed.") occupant_message("Phazed.")
. = ..(obstacle) . = ..(obstacle)
@@ -777,16 +900,57 @@
update_damage_alerts() update_damage_alerts()
if(amount) if(amount)
var/damage = absorbDamage(amount,type) var/damage = absorbDamage(amount,type)
damage = components_handle_damage(damage,type)
health -= damage health -= damage
update_health() update_health()
log_append_to_last("Took [damage] points of damage. Damage type: \"[type]\".",1) log_append_to_last("Took [damage] points of damage. Damage type: \"[type]\".",1)
return return
/obj/mecha/proc/components_handle_damage(var/damage, var/type = BRUTE)
var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR]
if(AC)
var/armor_efficiency = AC.get_efficiency()
var/damage_change = armor_efficiency * (damage * 0.5) * AC.damage_absorption[type]
AC.damage_part(damage_change, type)
damage -= damage_change
var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL]
if(HC)
if(HC.integrity)
var/hull_absorb = round(rand(5, 10) / 10, 0.1) * damage
HC.damage_part(hull_absorb, type)
damage -= hull_absorb
for(var/obj/item/mecha_parts/component/C in (internal_components - list(MECH_HULL, MECH_ARMOR)))
if(prob(C.relative_size))
var/damage_part_amt = round(damage / 4, 0.1)
C.damage_part(damage_part_amt)
damage -= damage_part_amt
return damage
/obj/mecha/proc/get_damage_absorption()
var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR]
if(!istype(AC))
return
else
if(AC.get_efficiency() > 0.25)
return AC.damage_absorption
return
/obj/mecha/proc/absorbDamage(damage,damage_type) /obj/mecha/proc/absorbDamage(damage,damage_type)
return call((proc_res["dynabsorbdamage"]||src), "dynabsorbdamage")(damage,damage_type) return call((proc_res["dynabsorbdamage"]||src), "dynabsorbdamage")(damage,damage_type)
/obj/mecha/proc/dynabsorbdamage(damage,damage_type) /obj/mecha/proc/dynabsorbdamage(damage,damage_type)
return damage*(listgetindex(damage_absorption,damage_type) || 1) return damage*(listgetindex(get_damage_absorption(),damage_type) || 1)
/obj/mecha/airlock_crush(var/crush_damage) /obj/mecha/airlock_crush(var/crush_damage)
..() ..()
@@ -806,14 +970,24 @@
if(user == occupant) if(user == occupant)
show_radial_occupant(user) show_radial_occupant(user)
return return
user.setClickCooldown(user.get_attack_speed()) user.setClickCooldown(user.get_attack_speed())
src.log_message("Attack by hand/paw. Attacker - [user].",1) src.log_message("Attack by hand/paw. Attacker - [user].",1)
var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR]
var/temp_deflect_chance = deflect_chance
if(!ArmC)
temp_deflect_chance = 1
else
temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0))
if(istype(user,/mob/living/carbon/human)) if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
if(H.species.can_shred(user)) if(H.species.can_shred(user))
if(!prob(src.deflect_chance)) if(!prob(temp_deflect_chance))
src.take_damage(15) //The take_damage() proc handles armor values src.take_damage(15) //The take_damage() proc handles armor values
if(prob(25)) //Why would they get free internal damage. At least make it a bit RNG. if(prob(25)) //Why would they get free internal damage. At least make it a bit RNG.
src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
@@ -830,7 +1004,7 @@
user.visible_message("<span class='danger'>\The [user] hits \the [src]. Nothing happens.</span>","<span class='danger'>You hit \the [src] with no visible effect.</span>") user.visible_message("<span class='danger'>\The [user] hits \the [src]. Nothing happens.</span>","<span class='danger'>You hit \the [src] with no visible effect.</span>")
src.log_append_to_last("Armor saved.") src.log_append_to_last("Armor saved.")
return return
else if ((HULK in user.mutations) && !prob(src.deflect_chance)) else if ((HULK in user.mutations) && !prob(temp_deflect_chance))
src.take_damage(15) //The take_damage() proc handles armor values src.take_damage(15) //The take_damage() proc handles armor values
if(prob(25)) //Hulks punch hard but lets not give them consistent internal damage. if(prob(25)) //Hulks punch hard but lets not give them consistent internal damage.
src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
@@ -848,11 +1022,30 @@
//I think this is relative to throws. //I think this is relative to throws.
/obj/mecha/proc/dynhitby(atom/movable/A) /obj/mecha/proc/dynhitby(atom/movable/A)
var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR]
var/temp_deflect_chance = deflect_chance
var/temp_damage_minimum = damage_minimum
var/temp_minimum_penetration = minimum_penetration
var/temp_fail_penetration_value = fail_penetration_value
if(!ArmC)
temp_deflect_chance = 0
temp_damage_minimum = 0
temp_minimum_penetration = 0
temp_fail_penetration_value = 1
else
temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0))
temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum)
temp_minimum_penetration = round(ArmC.get_efficiency() * ArmC.minimum_penetration)
temp_fail_penetration_value = round(ArmC.get_efficiency() * ArmC.fail_penetration_value)
if(istype(A, /obj/item/mecha_parts/mecha_tracking)) if(istype(A, /obj/item/mecha_parts/mecha_tracking))
A.forceMove(src) A.forceMove(src)
src.visible_message("The [A] fastens firmly to [src].") src.visible_message("The [A] fastens firmly to [src].")
return return
if(prob(src.deflect_chance) || istype(A, /mob)) if(prob(temp_deflect_chance) || istype(A, /mob))
src.occupant_message("<span class='notice'>\The [A] bounces off the armor.</span>") src.occupant_message("<span class='notice'>\The [A] bounces off the armor.</span>")
src.visible_message("\The [A] bounces off \the [src] armor") src.visible_message("\The [A] bounces off \the [src] armor")
src.log_append_to_last("Armor saved.") src.log_append_to_last("Armor saved.")
@@ -865,18 +1058,18 @@
var/pass_damage = O.throwforce var/pass_damage = O.throwforce
var/pass_damage_reduc_mod var/pass_damage_reduc_mod
if(pass_damage <= damage_minimum)//Too little to go through. if(pass_damage <= temp_damage_minimum)//Too little to go through.
src.occupant_message("<span class='notice'>\The [A] bounces off the armor.</span>") src.occupant_message("<span class='notice'>\The [A] bounces off the armor.</span>")
src.visible_message("\The [A] bounces off \the [src] armor") src.visible_message("\The [A] bounces off \the [src] armor")
return return
else if(O.armor_penetration < minimum_penetration) //If you don't have enough pen, you won't do full damage else if(O.armor_penetration < temp_minimum_penetration) //If you don't have enough pen, you won't do full damage
src.occupant_message("<span class='notice'>\The [A] struggles to bypass \the [src] armor.</span>") src.occupant_message("<span class='notice'>\The [A] struggles to bypass \the [src] armor.</span>")
src.visible_message("\The [A] struggles to bypass \the [src] armor") src.visible_message("\The [A] struggles to bypass \the [src] armor")
pass_damage_reduc_mod = fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default pass_damage_reduc_mod = temp_fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default
else else
src.occupant_message("<span class='notice'>\The [A] manages to pierces \the [src] armor.</span>") src.occupant_message("<span class='notice'>\The [A] manages to pierce \the [src] armor.</span>")
src.visible_message("\The [A] manages to pierces \the [src] armor") // src.visible_message("\The [A] manages to pierce \the [src] armor")
pass_damage_reduc_mod = 1 pass_damage_reduc_mod = 1
@@ -903,7 +1096,26 @@
return return
/obj/mecha/proc/dynbulletdamage(var/obj/item/projectile/Proj) /obj/mecha/proc/dynbulletdamage(var/obj/item/projectile/Proj)
if(prob(src.deflect_chance)) var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR]
var/temp_deflect_chance = deflect_chance
var/temp_damage_minimum = damage_minimum
var/temp_minimum_penetration = minimum_penetration
var/temp_fail_penetration_value = fail_penetration_value
if(!ArmC)
temp_deflect_chance = 0
temp_damage_minimum = 0
temp_minimum_penetration = 0
temp_fail_penetration_value = 1
else
temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0))
temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum)
temp_minimum_penetration = round(ArmC.get_efficiency() * ArmC.minimum_penetration)
temp_fail_penetration_value = round(ArmC.get_efficiency() * ArmC.fail_penetration_value)
if(prob(temp_deflect_chance))
src.occupant_message("<span class='notice'>The armor deflects incoming projectile.</span>") src.occupant_message("<span class='notice'>The armor deflects incoming projectile.</span>")
src.visible_message("The [src.name] armor deflects the projectile") src.visible_message("The [src.name] armor deflects the projectile")
src.log_append_to_last("Armor saved.") src.log_append_to_last("Armor saved.")
@@ -922,19 +1134,19 @@
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
pass_damage = ME.handle_projectile_contact(Proj, pass_damage) pass_damage = ME.handle_projectile_contact(Proj, pass_damage)
if(pass_damage < damage_minimum)//too pathetic to really damage you. if(pass_damage < temp_damage_minimum)//too pathetic to really damage you.
src.occupant_message("<span class='notice'>The armor deflects incoming projectile.</span>") src.occupant_message("<span class='notice'>The armor deflects incoming projectile.</span>")
src.visible_message("The [src.name] armor deflects\the [Proj]") src.visible_message("The [src.name] armor deflects\the [Proj]")
return return
else if(Proj.armor_penetration < minimum_penetration) //If you don't have enough pen, you won't do full damage else if(Proj.armor_penetration < temp_minimum_penetration) //If you don't have enough pen, you won't do full damage
src.occupant_message("<span class='notice'>\The [Proj] struggles to pierce \the [src] armor.</span>") src.occupant_message("<span class='notice'>\The [Proj] struggles to pierce \the [src] armor.</span>")
src.visible_message("\The [Proj] struggles to pierce \the [src] armor") src.visible_message("\The [Proj] struggles to pierce \the [src] armor")
pass_damage_reduc_mod = fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default pass_damage_reduc_mod = temp_fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default
else //You go through completely because you use AP. Nice. else //You go through completely because you use AP. Nice.
src.occupant_message("<span class='notice'>\The [Proj] manages to pierce \the [src] armor.</span>") src.occupant_message("<span class='notice'>\The [Proj] manages to pierce \the [src] armor.</span>")
src.visible_message("\The [Proj] manages to pierce \the [src] armor") // src.visible_message("\The [Proj] manages to pierce \the [src] armor")
pass_damage_reduc_mod = 1 pass_damage_reduc_mod = 1
pass_damage = (pass_damage_reduc_mod*pass_damage)//Apply damage reduction before usage. pass_damage = (pass_damage_reduc_mod*pass_damage)//Apply damage reduction before usage.
@@ -953,7 +1165,7 @@
Proj.attack_mob(src.occupant, distance) Proj.attack_mob(src.occupant, distance)
hit_occupant = 0 hit_occupant = 0
else else
if(pass_damage > internal_damage_minimum) //Only decently painful attacks trigger a chance of mech damage. if(pass_damage > internal_damage_minimum) //Only decently painful attacks trigger a chance of mech damage.
src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT), 1) src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT), 1)
Proj.penetrating-- Proj.penetrating--
@@ -966,24 +1178,34 @@
//This refer to whenever you are caught in an explosion. //This refer to whenever you are caught in an explosion.
/obj/mecha/ex_act(severity) /obj/mecha/ex_act(severity)
var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR]
var/temp_deflect_chance = deflect_chance
if(!ArmC)
temp_deflect_chance = 0
else
temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0))
src.log_message("Affected by explosion of severity: [severity].",1) src.log_message("Affected by explosion of severity: [severity].",1)
if(prob(src.deflect_chance)) if(prob(temp_deflect_chance))
severity++ severity++
src.log_append_to_last("Armor saved, changing severity to [severity].") src.log_append_to_last("Armor saved, changing severity to [severity].")
switch(severity) switch(severity)
if(1.0) if(1.0)
qdel(src) src.take_damage(initial(src.health), "bomb")
if(2.0) if(2.0)
if (prob(30)) if (prob(30))
qdel(src) src.take_damage(initial(src.health), "bomb")
else else
src.take_damage(initial(src.health)/2) //The take_damage() proc handles armor values src.take_damage(initial(src.health)/2, "bomb")
src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
if(3.0) if(3.0)
if (prob(5)) if (prob(5))
qdel(src) qdel(src)
else else
src.take_damage(initial(src.health)/5) //The take_damage() proc handles armor values src.take_damage(initial(src.health)/5, "bomb")
src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
return return
@@ -1030,20 +1252,39 @@
src.log_message("Attacked by [W]. Attacker - [user]") src.log_message("Attacked by [W]. Attacker - [user]")
var/pass_damage_reduc_mod //Modifer for failing to bring AP. var/pass_damage_reduc_mod //Modifer for failing to bring AP.
if(prob(src.deflect_chance)) //Does your attack get deflected outright. var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR]
var/temp_deflect_chance = deflect_chance
var/temp_damage_minimum = damage_minimum
var/temp_minimum_penetration = minimum_penetration
var/temp_fail_penetration_value = fail_penetration_value
if(!ArmC)
temp_deflect_chance = 0
temp_damage_minimum = 0
temp_minimum_penetration = 0
temp_fail_penetration_value = 1
else
temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0))
temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum)
temp_minimum_penetration = round(ArmC.get_efficiency() * ArmC.minimum_penetration)
temp_fail_penetration_value = round(ArmC.get_efficiency() * ArmC.fail_penetration_value)
if(prob(temp_deflect_chance)) //Does your attack get deflected outright.
src.occupant_message("<span class='notice'>\The [W] bounces off [src.name].</span>") src.occupant_message("<span class='notice'>\The [W] bounces off [src.name].</span>")
to_chat(user, "<span class='danger'>\The [W] bounces off [src.name].</span>") to_chat(user, "<span class='danger'>\The [W] bounces off [src.name].</span>")
src.log_append_to_last("Armor saved.") src.log_append_to_last("Armor saved.")
else if(W.force < damage_minimum) //Is your attack too PATHETIC to do anything. 3 damage to a person shouldn't do anything to a mech. else if(W.force < temp_damage_minimum) //Is your attack too PATHETIC to do anything. 3 damage to a person shouldn't do anything to a mech.
src.occupant_message("<span class='notice'>\The [W] bounces off the armor.</span>") src.occupant_message("<span class='notice'>\The [W] bounces off the armor.</span>")
src.visible_message("\The [W] bounces off \the [src] armor") src.visible_message("\The [W] bounces off \the [src] armor")
return return
else if(W.armor_penetration < minimum_penetration) //If you don't have enough pen, you won't do full damage else if(W.armor_penetration < temp_minimum_penetration) //If you don't have enough pen, you won't do full damage
src.occupant_message("<span class='notice'>\The [W] struggles to bypass \the [src] armor.</span>") src.occupant_message("<span class='notice'>\The [W] struggles to bypass \the [src] armor.</span>")
src.visible_message("\The [W] struggles to bypass \the [src] armor") src.visible_message("\The [W] struggles to bypass \the [src] armor")
pass_damage_reduc_mod = fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default pass_damage_reduc_mod = temp_fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default
else else
pass_damage_reduc_mod = 1 //Just making sure. pass_damage_reduc_mod = 1 //Just making sure.
@@ -1072,6 +1313,11 @@
to_chat(user, "[src]-MMI interface initialization failed.") to_chat(user, "[src]-MMI interface initialization failed.")
return return
if(istype(W, /obj/item/device/robotanalyzer))
var/obj/item/device/robotanalyzer/RA = W
RA.do_scan(src, user)
return
if(istype(W, /obj/item/mecha_parts/mecha_equipment)) if(istype(W, /obj/item/mecha_parts/mecha_equipment))
var/obj/item/mecha_parts/mecha_equipment/E = W var/obj/item/mecha_parts/mecha_equipment/E = W
spawn() spawn()
@@ -1082,6 +1328,20 @@
else else
to_chat(user, "You were unable to attach [W] to [src]") to_chat(user, "You were unable to attach [W] to [src]")
return return
if(istype(W, /obj/item/mecha_parts/component) && state == MECHA_CELL_OUT)
var/obj/item/mecha_parts/component/MC = W
spawn()
if(MC.attach(src))
user.drop_item()
MC.forceMove(src)
user.visible_message("[user] installs \the [W] in \the [src]", "You install \the [W] in \the [src].")
return
if(istype(W, /obj/item/weapon/card/robot))
var/obj/item/weapon/card/robot/RoC = W
return attackby(RoC.dummy_card, user)
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
if(add_req_access || maint_access) if(add_req_access || maint_access)
if(internals_access_allowed(usr)) if(internals_access_allowed(usr))
@@ -1098,23 +1358,39 @@
else else
to_chat(user, "<span class='warning'>Maintenance protocols disabled by operator.</span>") to_chat(user, "<span class='warning'>Maintenance protocols disabled by operator.</span>")
else if(W.is_wrench()) else if(W.is_wrench())
if(state==1) if(state==MECHA_BOLTS_SECURED)
state = 2 state = MECHA_PANEL_LOOSE
to_chat(user, "You undo the securing bolts.") to_chat(user, "You undo the securing bolts.")
else if(state==2) else if(state==MECHA_PANEL_LOOSE)
state = 1 state = MECHA_BOLTS_SECURED
to_chat(user, "You tighten the securing bolts.") to_chat(user, "You tighten the securing bolts.")
return return
else if(W.is_crowbar()) else if(W.is_crowbar())
if(state==2) if(state==MECHA_PANEL_LOOSE)
state = 3 state = MECHA_CELL_OPEN
to_chat(user, "You open the hatch to the power unit") to_chat(user, "You open the hatch to the power unit")
else if(state==3) else if(state==MECHA_CELL_OPEN)
state=2 state=MECHA_PANEL_LOOSE
to_chat(user, "You close the hatch to the power unit") to_chat(user, "You close the hatch to the power unit")
else if(state==MECHA_CELL_OUT)
var/list/removable_components = list()
for(var/slot in internal_components)
var/obj/item/mecha_parts/component/MC = internal_components[slot]
if(istype(MC))
removable_components[MC.name] = MC
else
to_chat(user, "<span class='notice'>\The [src] appears to be missing \the [slot].</span>")
var/remove = input(user, "Which component do you want to pry out?", "Remove Component") as null|anything in removable_components
if(!remove)
return
var/obj/item/mecha_parts/component/RmC = removable_components[remove]
RmC.detach()
return return
else if(istype(W, /obj/item/stack/cable_coil)) else if(istype(W, /obj/item/stack/cable_coil))
if(state == 3 && hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) if(state >= MECHA_CELL_OPEN && hasInternalDamage(MECHA_INT_SHORT_CIRCUIT))
var/obj/item/stack/cable_coil/CC = W var/obj/item/stack/cable_coil/CC = W
if(CC.use(2)) if(CC.use(2))
clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) clearInternalDamage(MECHA_INT_SHORT_CIRCUIT)
@@ -1126,19 +1402,19 @@
if(hasInternalDamage(MECHA_INT_TEMP_CONTROL)) if(hasInternalDamage(MECHA_INT_TEMP_CONTROL))
clearInternalDamage(MECHA_INT_TEMP_CONTROL) clearInternalDamage(MECHA_INT_TEMP_CONTROL)
to_chat(user, "You repair the damaged temperature controller.") to_chat(user, "You repair the damaged temperature controller.")
else if(state==3 && src.cell) else if(state==MECHA_CELL_OPEN && src.cell)
src.cell.forceMove(src.loc) src.cell.forceMove(src.loc)
src.cell = null src.cell = null
state = 4 state = MECHA_CELL_OUT
to_chat(user, "You unscrew and pry out the powercell.") to_chat(user, "You unscrew and pry out the powercell.")
src.log_message("Powercell removed") src.log_message("Powercell removed")
else if(state==4 && src.cell) else if(state==MECHA_CELL_OUT && src.cell)
state=3 state=MECHA_CELL_OPEN
to_chat(user, "You screw the cell in place") to_chat(user, "You screw the cell in place")
return return
else if(istype(W, /obj/item/device/multitool)) else if(istype(W, /obj/item/device/multitool))
if(state>=3 && src.occupant) if(state>=MECHA_CELL_OPEN && src.occupant)
to_chat(user, "You attempt to eject the pilot using the maintenance controls.") to_chat(user, "You attempt to eject the pilot using the maintenance controls.")
if(src.occupant.stat) if(src.occupant.stat)
src.go_out() src.go_out()
@@ -1150,7 +1426,7 @@
return return
else if(istype(W, /obj/item/weapon/cell)) else if(istype(W, /obj/item/weapon/cell))
if(state==4) if(state==MECHA_CELL_OUT)
if(!src.cell) if(!src.cell)
to_chat(user, "You install the powercell") to_chat(user, "You install the powercell")
user.drop_item() user.drop_item()
@@ -1183,6 +1459,28 @@
user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src]") user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src]")
return return
else if(istype(W,/obj/item/stack/nanopaste))
if(state >= MECHA_PANEL_LOOSE)
var/obj/item/stack/nanopaste/NP = W
for(var/slot in internal_components)
var/obj/item/mecha_parts/component/C = internal_components[slot]
if(C)
if(C.integrity < C.max_integrity)
while(C.integrity < C.max_integrity && NP && do_after(user, 1 SECOND, src))
if(NP.use(1))
C.adjust_integrity(10)
to_chat(user, "<span class='notice'>You repair damage to \the [C].</span>")
return
else
to_chat(user, "<span class='notice'>You can't reach \the [src]'s internal components.</span>")
return
else else
call((proc_res["dynattackby"]||src), "dynattackby")(W,user) call((proc_res["dynattackby"]||src), "dynattackby")(W,user)
/* /*
@@ -1291,7 +1589,8 @@
return return
/obj/mecha/remove_air(amount) /obj/mecha/remove_air(amount)
if(use_internal_tank) var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS]
if(use_internal_tank && (GC && prob(GC.get_efficiency() * 100)))
return cabin_air.remove(amount) return cabin_air.remove(amount)
else else
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
@@ -1306,7 +1605,8 @@
/obj/mecha/proc/return_pressure() /obj/mecha/proc/return_pressure()
. = 0 . = 0
if(use_internal_tank) var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS]
if(use_internal_tank && (GC && prob(GC.get_efficiency() * 100)))
. = cabin_air.return_pressure() . = cabin_air.return_pressure()
else else
var/datum/gas_mixture/t_air = get_turf_air() var/datum/gas_mixture/t_air = get_turf_air()
@@ -1317,7 +1617,8 @@
//skytodo: //No idea what you want me to do here, mate. //skytodo: //No idea what you want me to do here, mate.
/obj/mecha/proc/return_temperature() /obj/mecha/proc/return_temperature()
. = 0 . = 0
if(use_internal_tank) var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS]
if(use_internal_tank && (GC && prob(GC.get_efficiency() * 100)))
. = cabin_air.temperature . = cabin_air.temperature
else else
var/datum/gas_mixture/t_air = get_turf_air() var/datum/gas_mixture/t_air = get_turf_air()
@@ -1372,13 +1673,17 @@
set category = "Exosuit Interface" set category = "Exosuit Interface"
set src = usr.loc set src = usr.loc
set popup_menu = 0 set popup_menu = 0
if(!occupant) if(!occupant)
return return
if(usr != occupant) if(usr != occupant)
return return
var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS]
if(!GC)
return
for(var/turf/T in locs) for(var/turf/T in locs)
var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector) in T var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector) in T
if(possible_port) if(possible_port)
@@ -1399,13 +1704,13 @@
set category = "Exosuit Interface" set category = "Exosuit Interface"
set src = usr.loc set src = usr.loc
set popup_menu = 0 set popup_menu = 0
if(!occupant) if(!occupant)
return return
if(usr != occupant) if(usr != occupant)
return return
if(disconnect()) if(disconnect())
occupant_message("<span class='notice'>[name] disconnects from the port.</span>") occupant_message("<span class='notice'>[name] disconnects from the port.</span>")
verbs -= /obj/mecha/verb/disconnect_from_port verbs -= /obj/mecha/verb/disconnect_from_port
@@ -1441,6 +1746,16 @@
/obj/mecha/proc/internal_tank() /obj/mecha/proc/internal_tank()
if(usr!=src.occupant) if(usr!=src.occupant)
return return
var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS]
if(!GC)
to_chat(occupant, "<span class='warning'>The life support systems don't seem to respond.</span>")
return
if(!prob(GC.get_efficiency() * 100))
to_chat(occupant, "<span class='warning'>\The [GC] shudders and barks, before returning to how it was before.</span>")
return
use_internal_tank = !use_internal_tank use_internal_tank = !use_internal_tank
src.occupant_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].") src.occupant_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].")
src.log_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].") src.log_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].")
@@ -1567,8 +1882,12 @@
verbs -= /obj/mecha/verb/toggle_phasing verbs -= /obj/mecha/verb/toggle_phasing
if(!switch_dmg_type_possible) if(!switch_dmg_type_possible)
verbs -= /obj/mecha/verb/switch_damtype verbs -= /obj/mecha/verb/switch_damtype
if(!cloak_possible)
verbs -= /obj/mecha/verb/toggle_cloak
occupant.in_enclosed_vehicle = 1 //Useful for when you need to know if someone is in a mecho. occupant.in_enclosed_vehicle = 1 //Useful for when you need to know if someone is in a mecho.
if(occupant.hud_used)
minihud = new (occupant.hud_used, src)
update_cell_alerts() update_cell_alerts()
update_damage_alerts() update_damage_alerts()
set_dir(dir_in) set_dir(dir_in)
@@ -1634,6 +1953,7 @@
/obj/mecha/proc/go_out() //Eject/Exit the mech. Yes this is for easier searching. /obj/mecha/proc/go_out() //Eject/Exit the mech. Yes this is for easier searching.
if(!src.occupant) return if(!src.occupant) return
var/atom/movable/mob_container var/atom/movable/mob_container
QDEL_NULL(minihud)
if(ishuman(occupant)) if(ishuman(occupant))
mob_container = src.occupant mob_container = src.occupant
RemoveActions(occupant, human_occupant=1)//AEIOU RemoveActions(occupant, human_occupant=1)//AEIOU
@@ -1684,8 +2004,13 @@
/obj/mecha/proc/internals_access_allowed(mob/living/carbon/human/H) /obj/mecha/proc/internals_access_allowed(mob/living/carbon/human/H)
for(var/atom/ID in list(H.get_active_hand(), H.wear_id, H.belt)) if(istype(H))
if(src.check_access(ID,src.internals_req_access)) for(var/atom/ID in list(H.get_active_hand(), H.wear_id, H.belt))
if(src.check_access(ID,src.internals_req_access))
return 1
else if(istype(H, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = H
if(src.check_access(R.idcard,src.internals_req_access))
return 1 return 1
return 0 return 0
@@ -1786,9 +2111,15 @@
var/tank_pressure = internal_tank ? round(internal_tank.return_pressure(),0.01) : "None" var/tank_pressure = internal_tank ? round(internal_tank.return_pressure(),0.01) : "None"
var/tank_temperature = internal_tank ? internal_tank.return_temperature() : "Unknown" var/tank_temperature = internal_tank ? internal_tank.return_temperature() : "Unknown"
var/cabin_pressure = round(return_pressure(),0.01) var/cabin_pressure = round(return_pressure(),0.01)
var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL]
var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR]
var/output = {"[report_internal_damage()] var/output = {"[report_internal_damage()]
<b>Armor Integrity: </b>[AC?"[round(AC.integrity / AC.max_integrity * 100, 0.1)]%":"<span class='warning'>ARMOR MISSING</span>"]<br>
<b>Hull Integrity: </b>[HC?"[round(HC.integrity / HC.max_integrity * 100, 0.1)]%":"<span class='warning'>HULL MISSING</span>"]<br>
[integrity<30?"<font color='red'><b>DAMAGE LEVEL CRITICAL</b></font><br>":null] [integrity<30?"<font color='red'><b>DAMAGE LEVEL CRITICAL</b></font><br>":null]
<b>Integrity: </b> [integrity]%<br> <b>Chassis Integrity: </b> [integrity]%<br>
<b>Powercell charge: </b>[isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]<br> <b>Powercell charge: </b>[isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]<br>
<b>Air source: </b>[use_internal_tank?"Internal Airtank":"Environment"]<br> <b>Air source: </b>[use_internal_tank?"Internal Airtank":"Environment"]<br>
<b>Airtank pressure: </b>[tank_pressure]kPa<br> <b>Airtank pressure: </b>[tank_pressure]kPa<br>
@@ -1875,13 +2206,13 @@
output += "Universal Module: [W.name] <a href='?src=\ref[W];detach=1'>Detach</a><br>" output += "Universal Module: [W.name] <a href='?src=\ref[W];detach=1'>Detach</a><br>"
for(var/obj/item/mecha_parts/mecha_equipment/W in special_equipment) for(var/obj/item/mecha_parts/mecha_equipment/W in special_equipment)
output += "Special Module: [W.name] <a href='?src=\ref[W];detach=1'>Detach</a><br>" output += "Special Module: [W.name] <a href='?src=\ref[W];detach=1'>Detach</a><br>"
output += {"<b>Available hull slots:</b> [max_hull_equip-hull_equipment.len]<br> output += {"<b>Available hull slots:</b> [max_hull_equip-hull_equipment.len]<br>
<b>Available weapon slots:</b> [max_weapon_equip-weapon_equipment.len]<br> <b>Available weapon slots:</b> [max_weapon_equip-weapon_equipment.len]<br>
<b>Available utility slots:</b> [max_utility_equip-utility_equipment.len]<br> <b>Available utility slots:</b> [max_utility_equip-utility_equipment.len]<br>
<b>Available universal slots:</b> [max_universal_equip-universal_equipment.len]<br> <b>Available universal slots:</b> [max_universal_equip-universal_equipment.len]<br>
<b>Available special slots:</b> [max_special_equip-special_equipment.len]<br> <b>Available special slots:</b> [max_special_equip-special_equipment.len]<br>
</div></div> </div></div>
"} "}
return output return output
/obj/mecha/proc/get_equipment_list() //outputs mecha equipment list in html /obj/mecha/proc/get_equipment_list() //outputs mecha equipment list in html
@@ -2090,15 +2421,15 @@
if(!in_range(src, usr)) return if(!in_range(src, usr)) return
var/mob/user = top_filter.getMob("user") var/mob/user = top_filter.getMob("user")
if(user) if(user)
if(state==0) if(state==MECHA_OPERATING)
state = 1 state = MECHA_BOLTS_SECURED
to_chat(user, "The securing bolts are now exposed.") to_chat(user, "The securing bolts are now exposed.")
else if(state==1) else if(state==MECHA_BOLTS_SECURED)
state = 0 state = MECHA_OPERATING
to_chat(user, "The securing bolts are now hidden.") to_chat(user, "The securing bolts are now hidden.")
output_maintenance_dialog(top_filter.getObj("id_card"),user) output_maintenance_dialog(top_filter.getObj("id_card"),user)
return return
if(href_list["set_internal_tank_valve"] && state >=1) if(href_list["set_internal_tank_valve"] && state >=MECHA_BOLTS_SECURED)
if(!in_range(src, usr)) return if(!in_range(src, usr)) return
var/mob/user = top_filter.getMob("user") var/mob/user = top_filter.getMob("user")
if(user) if(user)
@@ -2106,7 +2437,7 @@
if(new_pressure) if(new_pressure)
internal_tank_valve = new_pressure internal_tank_valve = new_pressure
to_chat(user, "The internal pressure valve has been set to [internal_tank_valve]kPa.") to_chat(user, "The internal pressure valve has been set to [internal_tank_valve]kPa.")
if(href_list["remove_passenger"] && state >= 1) if(href_list["remove_passenger"] && state >= MECHA_BOLTS_SECURED)
var/mob/user = top_filter.getMob("user") var/mob/user = top_filter.getMob("user")
var/list/passengers = list() var/list/passengers = list()
for (var/obj/item/mecha_parts/mecha_equipment/tool/passenger/P in contents) for (var/obj/item/mecha_parts/mecha_equipment/tool/passenger/P in contents)
@@ -2265,6 +2596,13 @@
/obj/mecha/proc/dynusepower(amount) /obj/mecha/proc/dynusepower(amount)
update_cell_alerts() update_cell_alerts()
var/obj/item/mecha_parts/component/electrical/EC = internal_components[MECH_ELECTRIC]
if(EC)
amount = amount * (2 - EC.get_efficiency()) * EC.charge_cost_mod
else
amount *= 5
if(get_charge()) if(get_charge())
cell.use(amount) cell.use(amount)
return 1 return 1
@@ -2272,6 +2610,13 @@
/obj/mecha/proc/give_power(amount) /obj/mecha/proc/give_power(amount)
update_cell_alerts() update_cell_alerts()
var/obj/item/mecha_parts/component/electrical/EC = internal_components[MECH_ELECTRIC]
if(!EC)
amount /= 4
else
amount *= EC.get_efficiency()
if(!isnull(get_charge())) if(!isnull(get_charge()))
cell.give(amount) cell.give(amount)
return 1 return 1
@@ -2287,6 +2632,19 @@
//This is for mobs mostly. //This is for mobs mostly.
/obj/mecha/attack_generic(var/mob/user, var/damage, var/attack_message) /obj/mecha/attack_generic(var/mob/user, var/damage, var/attack_message)
var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR]
var/temp_deflect_chance = deflect_chance
var/temp_damage_minimum = damage_minimum
if(!ArmC)
temp_deflect_chance = 1
temp_damage_minimum = 0
else
temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0))
temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum)
user.setClickCooldown(user.get_attack_speed()) user.setClickCooldown(user.get_attack_speed())
if(!damage) if(!damage)
return 0 return 0
@@ -2294,14 +2652,14 @@
src.log_message("Attacked. Attacker - [user].",1) src.log_message("Attacked. Attacker - [user].",1)
user.do_attack_animation(src) user.do_attack_animation(src)
if(prob(src.deflect_chance))//Deflected if(prob(temp_deflect_chance))//Deflected
src.log_append_to_last("Armor saved.") src.log_append_to_last("Armor saved.")
src.occupant_message("<span class='notice'>\The [user]'s attack is stopped by the armor.</span>") src.occupant_message("<span class='notice'>\The [user]'s attack is stopped by the armor.</span>")
visible_message("<span class='notice'>\The [user] rebounds off [src.name]'s armor!</span>") visible_message("<span class='notice'>\The [user] rebounds off [src.name]'s armor!</span>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name]</font>") user.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name]</font>")
playsound(src, 'sound/weapons/slash.ogg', 50, 1, -1) playsound(src, 'sound/weapons/slash.ogg', 50, 1, -1)
else if(damage < damage_minimum)//Pathetic damage levels just don't harm MECH. else if(damage < temp_damage_minimum)//Pathetic damage levels just don't harm MECH.
src.occupant_message("<span class='notice'>\The [user]'s doesn't dent \the [src] paint.</span>") src.occupant_message("<span class='notice'>\The [user]'s doesn't dent \the [src] paint.</span>")
src.visible_message("\The [user]'s attack doesn't dent \the [src] armor") src.visible_message("\The [user]'s attack doesn't dent \the [src] armor")
src.log_append_to_last("Armor saved.") src.log_append_to_last("Armor saved.")
@@ -2487,4 +2845,4 @@
if(-INFINITY to 15) if(-INFINITY to 15)
occupant.throw_alert("mech damage", /obj/screen/alert/low_mech_integrity, 3) occupant.throw_alert("mech damage", /obj/screen/alert/low_mech_integrity, 3)
else else
occupant.clear_alert("mech damage") occupant.clear_alert("mech damage")

View File

@@ -3,7 +3,7 @@
//THIS FILE CONTAINS THE CODE TO ADD THE HUD BUTTONS AND THE MECH ACTIONS THEMSELVES. //THIS FILE CONTAINS THE CODE TO ADD THE HUD BUTTONS AND THE MECH ACTIONS THEMSELVES.
// //
// //
// I better get some free food for this.. // I better get some free food for this..
@@ -35,7 +35,9 @@
phasing_action.Grant(user, src) phasing_action.Grant(user, src)
if(switch_dmg_type_possible) if(switch_dmg_type_possible)
switch_damtype_action.Grant(user, src) switch_damtype_action.Grant(user, src)
if(cloak_possible)
cloak_action.Grant(user, src)
/obj/mecha/proc/RemoveActions(mob/living/user, human_occupant = 0) /obj/mecha/proc/RemoveActions(mob/living/user, human_occupant = 0)
if(human_occupant) if(human_occupant)
eject_action.Remove(user, src) eject_action.Remove(user, src)
@@ -51,8 +53,8 @@
thrusters_action.Remove(user, src) thrusters_action.Remove(user, src)
phasing_action.Remove(user, src) phasing_action.Remove(user, src)
switch_damtype_action.Remove(user, src) switch_damtype_action.Remove(user, src)
overload_action.Remove(user, src) overload_action.Remove(user, src)
cloak_action.Remove(user, src)
// //
@@ -242,6 +244,15 @@
/datum/action/innate/mecha/mech_toggle_cloaking
name = "Toggle Mech phasing"
button_icon_state = "mech_phasing_off"
/datum/action/innate/mecha/mech_toggle_cloaking/Activate()
button_icon_state = "mech_phasing_[chassis.cloaked ? "off" : "on"]"
button.UpdateIcon()
chassis.toggle_cloaking()
///// /////
@@ -293,12 +304,10 @@
return return
if(overload) if(overload)
overload = 0 overload = 0
step_in = initial(step_in)
step_energy_drain = initial(step_energy_drain) step_energy_drain = initial(step_energy_drain)
src.occupant_message("<font color='blue'>You disable leg actuators overload.</font>") src.occupant_message("<font color='blue'>You disable leg actuators overload.</font>")
else else
overload = 1 overload = 1
step_in = min(1, round(step_in/2))
step_energy_drain = step_energy_drain*overload_coeff step_energy_drain = step_energy_drain*overload_coeff
src.occupant_message("<font color='red'>You enable leg actuators overload.</font>") src.occupant_message("<font color='red'>You enable leg actuators overload.</font>")
src.log_message("Toggled leg actuators overload.") src.log_message("Toggled leg actuators overload.")
@@ -324,7 +333,7 @@
if(smoke_ready) if(smoke_ready)
smoke_reserve-- //Remove ammo smoke_reserve-- //Remove ammo
src.occupant_message("<font color='red'>Smoke fired. [smoke_reserve] usages left.</font>") src.occupant_message("<font color='red'>Smoke fired. [smoke_reserve] usages left.</font>")
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread() var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
smoke.attach(src) smoke.attach(src)
smoke.set_up(10, 0, usr.loc) smoke.set_up(10, 0, usr.loc)
@@ -422,6 +431,25 @@
return return
/obj/mecha/verb/toggle_cloak()
set category = "Exosuit Interface"
set name = "Toggle cloaking"
set src = usr.loc
set popup_menu = 0
toggle_cloaking()
/obj/mecha/proc/toggle_cloaking()
if(usr!=src.occupant)
return
if(cloaked)
uncloak()
else
cloak()
src.occupant_message("<font color=\"[cloaked?"#00f\">En":"#f00\">Dis"]abled cloaking.</font>")
return
/obj/mecha/verb/toggle_weapons_only_cycle() /obj/mecha/verb/toggle_weapons_only_cycle()
set category = "Exosuit Interface" set category = "Exosuit Interface"
set name = "Toggle weapons only cycling" set name = "Toggle weapons only cycling"
@@ -435,4 +463,3 @@
weapons_only_cycle = !weapons_only_cycle weapons_only_cycle = !weapons_only_cycle
src.occupant_message("<font color=\"[weapons_only_cycle?"#00f\">En":"#f00\">Dis"]abled weapons only cycling.</font>") src.occupant_message("<font color=\"[weapons_only_cycle?"#00f\">En":"#f00\">Dis"]abled weapons only cycling.</font>")
return return

View File

@@ -9,6 +9,14 @@
cargo_capacity = 1 cargo_capacity = 1
starting_components = list(
/obj/item/mecha_parts/component/hull,
/obj/item/mecha_parts/component/actuator,
/obj/item/mecha_parts/component/armor/lightweight,
/obj/item/mecha_parts/component/gas,
/obj/item/mecha_parts/component/electrical
)
/obj/mecha/medical/Initialize() /obj/mecha/medical/Initialize()
. = ..() . = ..()
var/turf/T = get_turf(src) var/turf/T = get_turf(src)

View File

@@ -1,4 +1,4 @@
/obj/mecha/medical/odysseus/ /obj/mecha/medical/odysseus
desc = "These exosuits are developed and produced by Vey-Med. (&copy; All rights reserved)." desc = "These exosuits are developed and produced by Vey-Med. (&copy; All rights reserved)."
name = "Odysseus" name = "Odysseus"
catalogue_data = list( catalogue_data = list(
@@ -9,8 +9,8 @@
initial_icon = "odysseus" initial_icon = "odysseus"
step_in = 2 step_in = 2
max_temperature = 15000 max_temperature = 15000
health = 120 health = 70
maxhealth = 120 maxhealth = 70
wreckage = /obj/effect/decal/mecha_wreckage/odysseus wreckage = /obj/effect/decal/mecha_wreckage/odysseus
internal_damage_threshold = 35 internal_damage_threshold = 35
deflect_chance = 15 deflect_chance = 15
@@ -139,5 +139,5 @@
/obj/mecha/medical/odysseus/old/New() /obj/mecha/medical/odysseus/old/New()
..() ..()
health = 25 health = 25
maxhealth = 100 //Just slightly worse. maxhealth = 50 //Just slightly worse.
cell.charge = rand(0, (cell.charge/2)) cell.charge = rand(0, (cell.charge/2))

View File

@@ -12,6 +12,14 @@
minimum_penetration = 10 minimum_penetration = 10
starting_components = list(
/obj/item/mecha_parts/component/hull/durable,
/obj/item/mecha_parts/component/actuator,
/obj/item/mecha_parts/component/armor/mining,
/obj/item/mecha_parts/component/gas,
/obj/item/mecha_parts/component/electrical
)
/obj/mecha/working/ripley/Destroy() /obj/mecha/working/ripley/Destroy()
for(var/atom/movable/A in src.cargo) for(var/atom/movable/A in src.cargo)
A.loc = loc A.loc = loc

View File

@@ -5,6 +5,8 @@
plane = DIRTY_PLANE plane = DIRTY_PLANE
anchored = 1 anchored = 1
var/amount = 1 var/amount = 1
generic_filth = TRUE
persistent = FALSE
/obj/effect/decal/cleanable/liquid_fuel/New(turf/newLoc,amt=1,nologs=1) /obj/effect/decal/cleanable/liquid_fuel/New(turf/newLoc,amt=1,nologs=1)
if(!nologs) if(!nologs)

View File

@@ -46,6 +46,8 @@ var/global/list/image/fluidtrack_cache=list()
var/coming_state="blood1" var/coming_state="blood1"
var/going_state="blood2" var/going_state="blood2"
var/updatedtracks=0 var/updatedtracks=0
persistent = TRUE
generic_filth = FALSE
// dir = id in stack // dir = id in stack
var/list/setdirs=list( var/list/setdirs=list(

View File

@@ -1,3 +1,10 @@
/*
USAGE NOTE
For decals, the var Persistent = 'has already been saved', and is primarily used to prevent duplicate savings of generic filth (filth.dm).
This also means 'TRUE' can be used to define a decal as "Do not save at all, even as a generic replacement." if a dirt decal is considered 'too common' to save.
generic_filth = TRUE means when the decal is saved, it will be switched out for a generic green 'filth' decal.
*/
/obj/effect/decal/cleanable /obj/effect/decal/cleanable
plane = DIRTY_PLANE plane = DIRTY_PLANE
var/persistent = FALSE var/persistent = FALSE

View File

@@ -14,4 +14,15 @@
light_range = 5 light_range = 5
light_power = 3 light_power = 3
light_color = "#FFFFFF" light_color = "#FFFFFF"
/obj/effect/map_effect/perma_light/concentrated
name = "permanent light (concentrated)"
light_range = 2
light_power = 5
/obj/effect/map_effect/perma_light/concentrated/incandescent
name = "permanent light (concentrated incandescent)"
light_color = LIGHT_COLOR_INCANDESCENT_TUBE

View File

@@ -0,0 +1,344 @@
GLOBAL_LIST_EMPTY(all_portal_masters)
/*
Portal map effects allow a mapper to join two distant places together, while looking somewhat seamlessly connected.
This can allow for very strange PoIs that twist and turn in what appear to be physically impossible ways.
Portals do have some specific requirements when mapping them in;
- There must by one, and only one `/obj/effect/map_effect/portal/master` for each side of a portal.
- Both sides need to have matching `portal_id`s in order to link to each other.
- Each side must face opposite directions, e.g. if side A faces SOUTH, side B must face NORTH.
- Each side must have the same orientation, e.g. horizontal on both sides, or vertical on both sides.
- Portals can be made to be longer than 1x1 with `/obj/effect/map_effect/portal/line`s,
but both sides must have the same length.
- If portal lines are added, they must form a straight line and be next to a portal master or another portal line.
- If portal lines are used, both portal masters should be in the same relative position among the lines.
E.g. both being on the left most side on a horizontal row.
Portals also have some limitations to be aware of when mapping. Some of these are not an issue if you're trying to make an 'obvious' portal;
- The objects seen through portals are purely visual, which has many implications,
such as simple_mob AIs being blind to mobs on the other side of portals.
- Objects on the other side of a portal can be interacted with if the interaction has no range limitation,
or the distance between the two portal sides happens to be less than the interaction max range. Examine will probably work,
while picking up an item that appears to be next to you will fail.
- Sounds currently are not carried across portals.
- Mismatched lighting between each portal end can make the portal look obvious.
- Portals look weird when observing as a ghost, or otherwise when able to see through walls. Meson vision will also spoil the illusion.
- Walls that change icons based on neightboring walls can give away that a portal is nearby if both sides don't have a similar transition.
- Projectiles that pass through portals will generally work as intended, however aiming and firing upon someone on the other side of a portal
will likely be weird due to the click targeting the real position of the thing clicked instead of the apparent position.
Thrown objects suffer a similar fate.
- The tiles that are visually shown across a portal are determined based on visibility at the time of portal initialization,
and currently don't update, meaning that opacity changes are not reflected, e.g. a wall is deconstructed, or an airlock is opened.
- There is currently a small but somewhat noticable pause in mob movement when moving across a portal,
as a result of the mob's glide animation being inturrupted by a teleport.
- Gas is not transferred through portals, and ZAS is oblivious to them.
A lot of those limitations can potentially be solved with some more work. Otherwise, portals work best in static environments like Points of Interest,
when portals are shortly lived, or when portals are made to be obvious with special effects.
*/
/obj/effect/map_effect/portal
name = "portal subtype"
invisibility = 0
opacity = TRUE
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
appearance_flags = PIXEL_SCALE|KEEP_TOGETHER // Removed TILE_BOUND so things not visible on the other side stay hidden from the viewer.
var/obj/effect/map_effect/portal/counterpart = null // The portal line or master that this is connected to, on the 'other side'.
// Information used to apply `pixel_[x|y]` offsets so that the visuals line up.
// Set automatically by `calculate_dimensions()`.
var/total_height = 0 // Measured in tiles.
var/total_width = 0
var/portal_distance_x = 0 // How far the portal is from the left edge, in tiles.
var/portal_distance_y = 0 // How far the portal is from the top edge.
/obj/effect/map_effect/portal/Destroy()
vis_contents = null
if(counterpart)
counterpart.counterpart = null // Disconnect our counterpart from us
counterpart = null // Now disconnect us from them.
return ..()
// Called when something touches the portal, and usually teleports them to the other side.
/obj/effect/map_effect/portal/Crossed(atom/movable/AM)
if(AM.is_incorporeal())
return
..()
if(!AM)
return
if(!counterpart)
return
go_through_portal(AM)
/obj/effect/map_effect/portal/proc/go_through_portal(atom/movable/AM)
// TODO: Find a way to fake the glide or something.
if(isliving(AM))
var/mob/living/L = AM
if(L.pulling)
var/atom/movable/pulled = L.pulling
L.stop_pulling()
// For some reason, trying to put the pulled object behind the person makes the drag stop and it doesn't even move to the other side.
// pulled.forceMove(get_turf(counterpart))
pulled.forceMove(counterpart.get_focused_turf())
L.forceMove(counterpart.get_focused_turf())
L.start_pulling(pulled)
else
L.forceMove(counterpart.get_focused_turf())
else
AM.forceMove(counterpart.get_focused_turf())
// 'Focused turf' is the turf directly in front of a portal,
// and it is used both as the destination when crossing, as well as the PoV for visuals.
/obj/effect/map_effect/portal/proc/get_focused_turf()
return get_step(get_turf(src), dir)
// Determines the size of the block of turfs inside `vis_contents`, and where the portal is in relation to that.
/obj/effect/map_effect/portal/proc/calculate_dimensions()
var/highest_x = 0
var/lowest_x = 0
var/highest_y = 0
var/lowest_y = 0
// First pass is for finding the top right corner.
for(var/thing in vis_contents)
var/turf/T = thing
if(T.x > highest_x)
highest_x = T.x
if(T.y > highest_y)
highest_y = T.y
lowest_x = highest_x
lowest_y = highest_y
// Second one is for the bottom left corner.
for(var/thing in vis_contents)
var/turf/T = thing
if(T.x < lowest_x)
lowest_x = T.x
if(T.y < lowest_y)
lowest_y = T.y
// Now calculate the dimensions.
total_width = (highest_x - lowest_x) + 1
total_height = (highest_y - lowest_y) + 1
// Find how far the portal is from the edges.
var/turf/focused_T = counterpart.get_focused_turf()
portal_distance_x = lowest_x - focused_T.x
portal_distance_y = lowest_y - focused_T.y
// Portal masters manage everything else involving portals.
// This is the base type. Use `/side_a` or `/side_b` with matching IDs for actual portals.
/obj/effect/map_effect/portal/master
name = "portal master"
show_messages = TRUE // So portals can hear and see, and relay to the other side.
var/portal_id = "test" // For a portal to be made, both the A and B sides need to share the same ID value.
var/list/portal_lines = list()
/obj/effect/map_effect/portal/master/Initialize()
GLOB.all_portal_masters += src
find_lines()
..()
return INITIALIZE_HINT_LATELOAD
/obj/effect/map_effect/portal/master/LateInitialize()
find_counterparts()
make_visuals()
apply_offset()
/obj/effect/map_effect/portal/master/Destroy()
GLOB.all_portal_masters -= src
for(var/thing in portal_lines)
qdel(thing)
return ..()
/obj/effect/map_effect/portal/master/proc/find_lines()
var/list/dirs_to_search = list( turn(dir, 90), turn(dir, -90) )
for(var/dir_to_search in dirs_to_search)
var/turf/current_T = get_turf(src)
while(current_T)
current_T = get_step(current_T, dir_to_search)
var/obj/effect/map_effect/portal/line/line = locate() in current_T
if(line)
portal_lines += line
line.my_master = src
else
break
// Connects both sides of a portal together.
/obj/effect/map_effect/portal/master/proc/find_counterparts()
for(var/thing in GLOB.all_portal_masters)
var/obj/effect/map_effect/portal/master/M = thing
if(M == src)
continue
if(M.counterpart)
continue
if(M.portal_id == src.portal_id)
counterpart = M
M.counterpart = src
if(portal_lines.len)
for(var/i = 1 to portal_lines.len)
var/obj/effect/map_effect/portal/line/our_line = portal_lines[i]
var/obj/effect/map_effect/portal/line/their_line = M.portal_lines[i]
our_line.counterpart = their_line
their_line.counterpart = our_line
break
if(!counterpart)
crash_with("Portal master [type] ([x],[y],[z]) could not find another portal master with a matching portal_id ([portal_id]).")
/obj/effect/map_effect/portal/master/proc/make_visuals()
var/list/observed_turfs = list()
for(var/thing in portal_lines + src)
var/obj/effect/map_effect/portal/P = thing
P.name = null
P.icon_state = null
if(!P.counterpart)
return
var/turf/T = P.counterpart.get_focused_turf()
P.vis_contents += T
var/list/things = dview(world.view, T)
for(var/turf/turf in things)
if(get_dir(turf, T) & P.dir)
if(turf in observed_turfs) // Avoid showing the same turf twice or more for improved performance.
continue
P.vis_contents += turf
observed_turfs += turf
P.calculate_dimensions()
// Shifts the portal's pixels in order to line up properly, as BYOND offsets the sprite when it holds multiple turfs inside `vis_contents`.
// This undos the shift that BYOND did.
/obj/effect/map_effect/portal/master/proc/apply_offset()
for(var/thing in portal_lines + src)
var/obj/effect/map_effect/portal/P = thing
P.pixel_x = WORLD_ICON_SIZE * P.portal_distance_x
P.pixel_y = WORLD_ICON_SIZE * P.portal_distance_y
// Allows portals to transfer emotes.
// Only portal masters do this to avoid flooding the other side with duplicate messages.
/obj/effect/map_effect/portal/master/see_emote(mob/M, text)
if(!counterpart)
return
var/turf/T = counterpart.get_focused_turf()
var/list/in_range = get_mobs_and_objs_in_view_fast(T, world.view, 0)
var/list/mobs_to_relay = in_range["mobs"]
for(var/thing in mobs_to_relay)
var/mob/mob = thing
var/rendered = "<span class='message'>[text]</span>"
mob.show_message(rendered)
..()
// Allows portals to transfer visible messages.
/obj/effect/map_effect/portal/master/show_message(msg, type, alt, alt_type)
if(!counterpart)
return
var/rendered = "<span class='message'>[msg]</span>"
var/turf/T = counterpart.get_focused_turf()
var/list/in_range = get_mobs_and_objs_in_view_fast(T, world.view, 0)
var/list/mobs_to_relay = in_range["mobs"]
for(var/thing in mobs_to_relay)
var/mob/mob = thing
mob.show_message(rendered)
..()
// Allows portals to transfer speech.
/obj/effect/map_effect/portal/master/hear_talk(mob/M, list/message_pieces, verb)
if(!counterpart)
return
var/turf/T = counterpart.get_focused_turf()
var/list/in_range = get_mobs_and_objs_in_view_fast(T, world.view, 0)
var/list/mobs_to_relay = in_range["mobs"]
for(var/thing in mobs_to_relay)
var/mob/mob = thing
var/message = mob.combine_message(message_pieces, verb, M)
var/name_used = M.GetVoice()
var/rendered = null
rendered = "<span class='game say'><span class='name'>[name_used]</span> [message]</span>"
mob.show_message(rendered, 2)
..()
// Returns the position that an atom that's hopefully on the other side of the portal would be if it were really there.
// Z levels not taken into account.
/obj/effect/map_effect/portal/master/proc/get_apparent_position(atom/A)
if(!counterpart)
return null
var/turf/true_turf = get_turf(A)
var/obj/effect/map_effect/portal/master/other_master = counterpart
var/in_vis_contents = FALSE
for(var/thing in other_master.portal_lines + other_master)
var/obj/effect/map_effect/portal/P = thing
if(P in true_turf.vis_locs)
in_vis_contents = TRUE
break
if(!in_vis_contents)
return null // Not in vision of the other portal.
var/turf/their_focus = counterpart.get_focused_turf()
var/turf/our_focus = get_focused_turf()
var/relative_x = (true_turf.x - our_focus.x)
relative_x += SIGN(relative_x)
var/relative_y = (true_turf.y - our_focus.y)
relative_y += SIGN(relative_y)
return new /datum/position(their_focus.x + relative_x, their_focus.y + relative_y, our_focus.z)
/obj/effect/map_effect/portal/master/side_a
name = "portal master A"
icon_state = "portal_side_a"
// color = "#00FF00"
/obj/effect/map_effect/portal/master/side_b
name = "portal master B"
icon_state = "portal_side_b"
// color = "#FF0000"
// Portal lines extend out from the sides of portal masters,
// They let portals be longer than 1x1.
// Both sides MUST be the same length, meaning if side A is 1x3, side B must also be 1x3.
/obj/effect/map_effect/portal/line
name = "portal line"
var/obj/effect/map_effect/portal/master/my_master = null
/obj/effect/map_effect/portal/line/Destroy()
if(my_master)
my_master.portal_lines -= src
my_master = null
return ..()
/obj/effect/map_effect/portal/line/side_a
name = "portal line A"
icon_state = "portal_line_side_a"
/obj/effect/map_effect/portal/line/side_b
name = "portal line B"
icon_state = "portal_line_side_b"

View File

@@ -332,14 +332,14 @@
if(!heart) if(!heart)
return TRUE return TRUE
var/blood_volume = round((H.vessel.get_reagent_amount("blood")/H.species.blood_volume)*100) var/blood_volume = H.vessel.get_reagent_amount("blood")
if(!heart || heart.is_broken()) if(!heart || heart.is_broken())
blood_volume *= 0.3 blood_volume *= 0.3
else if(heart.is_bruised()) else if(heart.is_bruised())
blood_volume *= 0.7 blood_volume *= 0.7
else if(heart.damage > 1) else if(heart.damage > 1)
blood_volume *= 0.8 blood_volume *= 0.8
return blood_volume < BLOOD_VOLUME_SURVIVE return blood_volume < H.species.blood_volume*H.species.blood_level_fatal
/obj/item/weapon/shockpaddles/proc/check_charge(var/charge_amt) /obj/item/weapon/shockpaddles/proc/check_charge(var/charge_amt)
return 0 return 0

View File

@@ -130,10 +130,10 @@ HALOGEN COUNTER - Radcount on mobs
for(var/A in C.reagents.reagent_list) for(var/A in C.reagents.reagent_list)
var/datum/reagent/R = A var/datum/reagent/R = A
if(R.scannable) if(R.scannable)
reagentdata["[R.id]"] = "<span class='notice'>\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]</span><br>" reagentdata["[R.id]"] = "<span class='notice'>\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - <span class='danger'>Overdose</span>" : ""]</span><br>"
else else
unknown++ unknown++
unknownreagents["[R.id]"] = "<span class='notice'>\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]</span><br>" unknownreagents["[R.id]"] = "<span class='notice'>\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - <span class='danger'>Overdose</span>" : ""]</span><br>"
if(reagentdata.len) if(reagentdata.len)
dat += "<span class='notice'>Beneficial reagents detected in subject's blood:</span><br>" dat += "<span class='notice'>Beneficial reagents detected in subject's blood:</span><br>"
for(var/d in reagentdata) for(var/d in reagentdata)
@@ -150,14 +150,14 @@ HALOGEN COUNTER - Radcount on mobs
var/stomachreagentdata[0] var/stomachreagentdata[0]
var/stomachunknownreagents[0] var/stomachunknownreagents[0]
for(var/B in C.ingested.reagent_list) for(var/B in C.ingested.reagent_list)
var/datum/reagent/T = B var/datum/reagent/R = B
if(T.scannable) if(R.scannable)
stomachreagentdata["[T.id]"] = "<span class='notice'>\t[round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]</span><br>" stomachreagentdata["[R.id]"] = "<span class='notice'>\t[round(C.ingested.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - <span class='danger'>Overdose</span>" : ""]</span><br>"
if (advscan == 0 || showadvscan == 0) if (advscan == 0 || showadvscan == 0)
dat += "<span class='notice'>[T.name] found in subject's stomach.</span><br>" dat += "<span class='notice'>[R.name] found in subject's stomach.</span><br>"
else else
++unknown ++unknown
stomachunknownreagents["[T.id]"] = "<span class='notice'>\t[round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]</span><br>" stomachunknownreagents["[R.id]"] = "<span class='notice'>\t[round(C.ingested.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - <span class='danger'>Overdose</span>" : ""]</span><br>"
if(advscan >= 1 && showadvscan == 1) if(advscan >= 1 && showadvscan == 1)
dat += "<span class='notice'>Beneficial reagents detected in subject's stomach:</span><br>" dat += "<span class='notice'>Beneficial reagents detected in subject's stomach:</span><br>"
for(var/d in stomachreagentdata) for(var/d in stomachreagentdata)
@@ -174,14 +174,14 @@ HALOGEN COUNTER - Radcount on mobs
var/touchreagentdata[0] var/touchreagentdata[0]
var/touchunknownreagents[0] var/touchunknownreagents[0]
for(var/B in C.touching.reagent_list) for(var/B in C.touching.reagent_list)
var/datum/reagent/T = B var/datum/reagent/R = B
if(T.scannable) if(R.scannable)
touchreagentdata["[T.id]"] = "<span class='notice'>\t[round(C.touching.get_reagent_amount(T.id), 1)]u [T.name]</span><br>" touchreagentdata["[R.id]"] = "<span class='notice'>\t[round(C.touching.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.can_overdose_touch && R.volume > R.overdose) ? " - <span class='danger'>Overdose</span>" : ""]</span><br>"
if (advscan == 0 || showadvscan == 0) if (advscan == 0 || showadvscan == 0)
dat += "<span class='notice'>[T.name] found in subject's dermis.</span><br>" dat += "<span class='notice'>[R.name] found in subject's dermis.</span><br>"
else else
++unknown ++unknown
touchunknownreagents["[T.id]"] = "<span class='notice'>\t[round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]</span><br>" touchunknownreagents["[R.id]"] = "<span class='notice'>\t[round(C.ingested.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.can_overdose_touch && R.volume > R.overdose) ? " - <span class='danger'>Overdose</span>" : ""]</span><br>"
if(advscan >= 1 && showadvscan == 1) if(advscan >= 1 && showadvscan == 1)
dat += "<span class='notice'>Beneficial reagents detected in subject's dermis:</span><br>" dat += "<span class='notice'>Beneficial reagents detected in subject's dermis:</span><br>"
for(var/d in touchreagentdata) for(var/d in touchreagentdata)
@@ -266,9 +266,11 @@ HALOGEN COUNTER - Radcount on mobs
var/blood_volume = H.vessel.get_reagent_amount("blood") var/blood_volume = H.vessel.get_reagent_amount("blood")
var/blood_percent = round((blood_volume / H.species.blood_volume)*100) var/blood_percent = round((blood_volume / H.species.blood_volume)*100)
var/blood_type = H.dna.b_type var/blood_type = H.dna.b_type
if(blood_percent <= BLOOD_VOLUME_BAD) if(blood_volume <= H.species.blood_volume*H.species.blood_level_danger)
dat += "<span class='danger'><i>Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl. Type: [blood_type]</i></span><br>" dat += "<span class='danger'><i>Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl. Type: [blood_type]</i></span><br>"
else if(blood_percent <= BLOOD_VOLUME_SAFE) else if(blood_volume <= H.species.blood_volume*H.species.blood_level_warning)
dat += "<span class='danger'><i>Warning: Blood Level VERY LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]</i></span><br>"
else if(blood_volume <= H.species.blood_volume*H.species.blood_level_safe)
dat += "<span class='danger'>Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]</span><br>" dat += "<span class='danger'>Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]</span><br>"
else else
dat += "<span class='notice'>Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]</span><br>" dat += "<span class='notice'>Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]</span><br>"

View File

@@ -1,3 +1,9 @@
#define JAR_NOTHING 0
#define JAR_MONEY 1
#define JAR_ANIMAL 2
#define JAR_SPIDER 3
/obj/item/glass_jar /obj/item/glass_jar
name = "glass jar" name = "glass jar"
desc = "A small empty jar." desc = "A small empty jar."
@@ -27,7 +33,7 @@
var/mob/L = A var/mob/L = A
user.visible_message("<span class='notice'>[user] scoops [L] into \the [src].</span>", "<span class='notice'>You scoop [L] into \the [src].</span>") user.visible_message("<span class='notice'>[user] scoops [L] into \the [src].</span>", "<span class='notice'>You scoop [L] into \the [src].</span>")
L.loc = src L.loc = src
contains = 2 contains = JAR_ANIMAL
update_icon() update_icon()
return return
else if(istype(A, /obj/effect/spider/spiderling)) else if(istype(A, /obj/effect/spider/spiderling))
@@ -35,40 +41,40 @@
user.visible_message("<span class='notice'>[user] scoops [S] into \the [src].</span>", "<span class='notice'>You scoop [S] into \the [src].</span>") user.visible_message("<span class='notice'>[user] scoops [S] into \the [src].</span>", "<span class='notice'>You scoop [S] into \the [src].</span>")
S.loc = src S.loc = src
STOP_PROCESSING(SSobj, S) // No growing inside jars STOP_PROCESSING(SSobj, S) // No growing inside jars
contains = 3 contains = JAR_SPIDER
update_icon() update_icon()
return return
/obj/item/glass_jar/attack_self(var/mob/user) /obj/item/glass_jar/attack_self(var/mob/user)
switch(contains) switch(contains)
if(1) if(JAR_MONEY)
for(var/obj/O in src) for(var/obj/O in src)
O.loc = user.loc O.loc = user.loc
to_chat(user, "<span class='notice'>You take money out of \the [src].</span>") to_chat(user, "<span class='notice'>You take money out of \the [src].</span>")
contains = 0 contains = JAR_NOTHING
update_icon() update_icon()
return return
if(2) if(JAR_ANIMAL)
for(var/mob/M in src) for(var/mob/M in src)
M.loc = user.loc M.loc = user.loc
user.visible_message("<span class='notice'>[user] releases [M] from \the [src].</span>", "<span class='notice'>You release [M] from \the [src].</span>") user.visible_message("<span class='notice'>[user] releases [M] from \the [src].</span>", "<span class='notice'>You release [M] from \the [src].</span>")
contains = 0 contains = JAR_NOTHING
update_icon() update_icon()
return return
if(3) if(JAR_SPIDER)
for(var/obj/effect/spider/spiderling/S in src) for(var/obj/effect/spider/spiderling/S in src)
S.loc = user.loc S.loc = user.loc
user.visible_message("<span class='notice'>[user] releases [S] from \the [src].</span>", "<span class='notice'>You release [S] from \the [src].</span>") user.visible_message("<span class='notice'>[user] releases [S] from \the [src].</span>", "<span class='notice'>You release [S] from \the [src].</span>")
START_PROCESSING(SSobj, S) // They can grow after being let out though START_PROCESSING(SSobj, S) // They can grow after being let out though
contains = 0 contains = JAR_NOTHING
update_icon() update_icon()
return return
/obj/item/glass_jar/attackby(var/obj/item/W, var/mob/user) /obj/item/glass_jar/attackby(var/obj/item/W, var/mob/user)
if(istype(W, /obj/item/weapon/spacecash)) if(istype(W, /obj/item/weapon/spacecash))
if(contains == 0) if(contains == JAR_NOTHING)
contains = 1 contains = JAR_MONEY
if(contains != 1) if(contains != JAR_MONEY)
return return
var/obj/item/weapon/spacecash/S = W var/obj/item/weapon/spacecash/S = W
user.visible_message("<span class='notice'>[user] puts [S.worth] [S.worth > 1 ? "thalers" : "thaler"] into \the [src].</span>") user.visible_message("<span class='notice'>[user] puts [S.worth] [S.worth > 1 ? "thalers" : "thaler"] into \the [src].</span>")
@@ -80,10 +86,10 @@
underlays.Cut() underlays.Cut()
overlays.Cut() overlays.Cut()
switch(contains) switch(contains)
if(0) if(JAR_NOTHING)
name = initial(name) name = initial(name)
desc = initial(desc) desc = initial(desc)
if(1) if(JAR_MONEY)
name = "tip jar" name = "tip jar"
desc = "A small jar with money inside." desc = "A small jar with money inside."
for(var/obj/item/weapon/spacecash/S in src) for(var/obj/item/weapon/spacecash/S in src)
@@ -92,7 +98,7 @@
money.pixel_y = rand(-6, 6) money.pixel_y = rand(-6, 6)
money.transform *= 0.6 money.transform *= 0.6
underlays += money underlays += money
if(2) if(JAR_ANIMAL)
for(var/mob/M in src) for(var/mob/M in src)
var/image/victim = image(M.icon, M.icon_state) var/image/victim = image(M.icon, M.icon_state)
victim.pixel_y = 6 victim.pixel_y = 6
@@ -105,10 +111,109 @@
underlays += victim underlays += victim
name = "glass jar with [M]" name = "glass jar with [M]"
desc = "A small jar with [M] inside." desc = "A small jar with [M] inside."
if(3) if(JAR_SPIDER)
for(var/obj/effect/spider/spiderling/S in src) for(var/obj/effect/spider/spiderling/S in src)
var/image/victim = image(S.icon, S.icon_state) var/image/victim = image(S.icon, S.icon_state)
underlays += victim underlays += victim
name = "glass jar with [S]" name = "glass jar with [S]"
desc = "A small jar with [S] inside." desc = "A small jar with [S] inside."
return return
/obj/item/glass_jar/fish
name = "glass tank"
desc = "A large glass tank."
var/filled = FALSE
w_class = ITEMSIZE_NORMAL
accept_mobs = list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/mouse, /mob/living/simple_mob/animal/sif/leech, /mob/living/simple_mob/animal/sif/frostfly, /mob/living/simple_mob/animal/sif/glitterfly, /mob/living/simple_mob/animal/passive/fish)
/obj/item/glass_jar/fish/plastic
name = "plastic tank"
desc = "A large plastic tank."
matter = list("plastic" = 4000)
/obj/item/glass_jar/fish/update_icon() // Also updates name and desc
underlays.Cut()
overlays.Cut()
if(filled)
underlays += image(icon, "[icon_state]_water")
switch(contains)
if(JAR_NOTHING)
name = initial(name)
desc = initial(desc)
if(JAR_MONEY)
name = "tip tank"
desc = "A large [name] with money inside."
for(var/obj/item/weapon/spacecash/S in src)
var/image/money = image(S.icon, S.icon_state)
money.pixel_x = rand(-2, 3)
money.pixel_y = rand(-6, 6)
money.transform *= 0.6
underlays += money
if(JAR_ANIMAL)
for(var/mob/M in src)
var/image/victim = image(M.icon, M.icon_state)
var/initial_x_scale = M.icon_scale_x
var/initial_y_scale = M.icon_scale_y
M.adjust_scale(0.7)
victim.appearance = M.appearance
M.adjust_scale(initial_x_scale, initial_y_scale)
victim.pixel_y = 4
underlays += victim
name = "[name] with [M]"
desc = "A large [name] with [M] inside."
if(JAR_SPIDER)
for(var/obj/effect/spider/spiderling/S in src)
var/image/victim = image(S.icon, S.icon_state)
underlays += victim
name = "[name] with [S]"
desc = "A large tank with [S] inside."
if(filled)
desc = "[desc] It contains water."
return
/obj/item/glass_jar/fish/afterattack(var/atom/A, var/mob/user, var/proximity)
if(!filled)
if(istype(A, /obj/structure/sink) || istype(A, /turf/simulated/floor/water))
if(contains && user.a_intent == "help")
to_chat(user, "<span class='warning'>That probably isn't the best idea.</span>")
return
to_chat(user, "<span class='notice'>You fill \the [src] with water!</span>")
filled = TRUE
update_icon()
return
return ..()
/obj/item/glass_jar/fish/attack_self(var/mob/user)
if(filled)
if(contains == JAR_ANIMAL)
if(user.a_intent == "help")
to_chat(user, "<span class='notice'>Maybe you shouldn't empty the water...</span>")
return
else
filled = FALSE
user.visible_message("<span class='warning'>[user] dumps out \the [src]'s water!</span>")
update_icon()
return
else
user.visible_message("<span class='notice'>[user] dumps \the [src]'s water.</span>")
filled = FALSE
update_icon()
return
return ..()
#undef JAR_NOTHING
#undef JAR_MONEY
#undef JAR_ANIMAL
#undef JAR_SPIDER

View File

@@ -425,6 +425,15 @@
return return
..() ..()
/obj/random/mech_toy
name = "Random Mech Toy"
desc = "This is a random mech toy."
icon = 'icons/obj/toy.dmi'
icon_state = "ripleytoy"
/obj/random/mech_toy/item_to_spawn()
return pick(typesof(/obj/item/toy/prize))
/obj/item/toy/prize/ripley /obj/item/toy/prize/ripley
name = "toy ripley" name = "toy ripley"
desc = "Mini-Mecha action figure! Collect them all! 1/11." desc = "Mini-Mecha action figure! Collect them all! 1/11."

View File

@@ -198,6 +198,16 @@
/obj/item/weapon/storage/box/empshells/large /obj/item/weapon/storage/box/empshells/large
starts_with = list(/obj/item/ammo_casing/a12g/emp = 16) starts_with = list(/obj/item/ammo_casing/a12g/emp = 16)
/obj/item/weapon/storage/box/flechetteshells
name = "box of shotgun flechettes"
desc = "It has a picture of a gun and several warning symbols on the front.<br>WARNING: Live ammunition. Misuse may result in serious injury or death."
icon_state = "lethalslug_box"
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
starts_with = list(/obj/item/ammo_casing/a12g/flechette = 8)
/obj/item/weapon/storage/box/flechetteshells/large
starts_with = list(/obj/item/ammo_casing/a12g/flechette = 16)
/obj/item/weapon/storage/box/sniperammo /obj/item/weapon/storage/box/sniperammo
name = "box of 14.5mm shells" name = "box of 14.5mm shells"
desc = "It has a picture of a gun and several warning symbols on the front.<br>WARNING: Live ammunition. Misuse may result in serious injury or death." desc = "It has a picture of a gun and several warning symbols on the front.<br>WARNING: Live ammunition. Misuse may result in serious injury or death."

View File

@@ -63,7 +63,7 @@
overlays.Cut() overlays.Cut()
if(front_id) if(front_id)
var/tiny_state = "id-generic" var/tiny_state = "id-generic"
if("id-"+front_id.icon_state in icon_states(icon)) if("id-"+front_id.icon_state in cached_icon_states(icon))
tiny_state = "id-"+front_id.icon_state tiny_state = "id-"+front_id.icon_state
var/image/tiny_image = new/image(icon, icon_state = tiny_state) var/image/tiny_image = new/image(icon, icon_state = tiny_state)
tiny_image.appearance_flags = RESET_COLOR tiny_image.appearance_flags = RESET_COLOR

View File

@@ -33,7 +33,9 @@
prob(10);/mob/living/simple_mob/animal/passive/mouse, prob(10);/mob/living/simple_mob/animal/passive/mouse,
prob(10);/mob/living/simple_mob/animal/passive/yithian, prob(10);/mob/living/simple_mob/animal/passive/yithian,
prob(10);/mob/living/simple_mob/animal/passive/tindalos, prob(10);/mob/living/simple_mob/animal/passive/tindalos,
prob(10);/mob/living/simple_mob/animal/passive/pillbug,
prob(10);/mob/living/simple_mob/animal/passive/dog/tamaskan, prob(10);/mob/living/simple_mob/animal/passive/dog/tamaskan,
prob(10);/mob/living/simple_mob/animal/passive/dog/brittany,
prob(3);/mob/living/simple_mob/animal/passive/bird/parrot, prob(3);/mob/living/simple_mob/animal/passive/bird/parrot,
prob(1);/mob/living/simple_mob/animal/passive/crab) prob(1);/mob/living/simple_mob/animal/passive/crab)
@@ -69,10 +71,12 @@
/obj/random/mob/sif/item_to_spawn() /obj/random/mob/sif/item_to_spawn()
return pick(prob(30);/mob/living/simple_mob/animal/sif/diyaab, return pick(prob(30);/mob/living/simple_mob/animal/sif/diyaab,
prob(20);/mob/living/simple_mob/animal/passive/hare,
prob(15);/mob/living/simple_mob/animal/passive/crab, prob(15);/mob/living/simple_mob/animal/passive/crab,
prob(15);/mob/living/simple_mob/animal/passive/penguin, prob(15);/mob/living/simple_mob/animal/passive/penguin,
prob(15);/mob/living/simple_mob/animal/passive/mouse, prob(15);/mob/living/simple_mob/animal/passive/mouse,
prob(15);/mob/living/simple_mob/animal/passive/dog/tamaskan, prob(15);/mob/living/simple_mob/animal/passive/dog/tamaskan,
prob(10);/mob/living/simple_mob/animal/sif/siffet,
prob(2);/mob/living/simple_mob/animal/giant_spider/frost, prob(2);/mob/living/simple_mob/animal/giant_spider/frost,
prob(1);/mob/living/simple_mob/animal/space/goose, prob(1);/mob/living/simple_mob/animal/space/goose,
prob(20);/mob/living/simple_mob/animal/passive/crab) prob(20);/mob/living/simple_mob/animal/passive/crab)
@@ -88,6 +92,7 @@
/obj/random/mob/sif/peaceful/item_to_spawn() /obj/random/mob/sif/peaceful/item_to_spawn()
return pick(prob(30);/mob/living/simple_mob/animal/sif/diyaab, return pick(prob(30);/mob/living/simple_mob/animal/sif/diyaab,
prob(20);/mob/living/simple_mob/animal/passive/hare,
prob(15);/mob/living/simple_mob/animal/passive/crab, prob(15);/mob/living/simple_mob/animal/passive/crab,
prob(15);/mob/living/simple_mob/animal/passive/penguin, prob(15);/mob/living/simple_mob/animal/passive/penguin,
prob(15);/mob/living/simple_mob/animal/passive/mouse, prob(15);/mob/living/simple_mob/animal/passive/mouse,
@@ -102,6 +107,8 @@
/obj/random/mob/sif/hostile/item_to_spawn() /obj/random/mob/sif/hostile/item_to_spawn()
return pick(prob(22);/mob/living/simple_mob/animal/sif/savik, return pick(prob(22);/mob/living/simple_mob/animal/sif/savik,
prob(33);/mob/living/simple_mob/animal/giant_spider/frost, prob(33);/mob/living/simple_mob/animal/giant_spider/frost,
prob(20);/mob/living/simple_mob/animal/sif/frostfly,
prob(10);/mob/living/simple_mob/animal/sif/tymisian,
prob(45);/mob/living/simple_mob/animal/sif/shantak) prob(45);/mob/living/simple_mob/animal/sif/shantak)
/obj/random/mob/sif/kururak /obj/random/mob/sif/kururak
@@ -329,6 +336,12 @@
/mob/living/simple_mob/animal/sif/duck, /mob/living/simple_mob/animal/sif/duck,
/mob/living/simple_mob/animal/sif/duck /mob/living/simple_mob/animal/sif/duck
), ),
prob(15);list(
/mob/living/simple_mob/animal/passive/hare,
/mob/living/simple_mob/animal/passive/hare,
/mob/living/simple_mob/animal/passive/hare,
/mob/living/simple_mob/animal/passive/hare
),
prob(10);list( prob(10);list(
/mob/living/simple_mob/animal/sif/shantak/retaliate, /mob/living/simple_mob/animal/sif/shantak/retaliate,
/mob/living/simple_mob/animal/sif/shantak/retaliate, /mob/living/simple_mob/animal/sif/shantak/retaliate,

View File

@@ -6,7 +6,7 @@
var/cult = 0 var/cult = 0
/obj/structure/sign/double/barsign/proc/get_valid_states(initial=1) /obj/structure/sign/double/barsign/proc/get_valid_states(initial=1)
. = icon_states(icon) . = cached_icon_states(icon)
. -= "on" . -= "on"
. -= "narsiebistro" . -= "narsiebistro"
. -= "empty" . -= "empty"

View File

@@ -114,7 +114,7 @@ two tiles on initialization, and which way a cliff is facing may change during m
var/subtraction_icon_state = "[icon_state]-subtract" var/subtraction_icon_state = "[icon_state]-subtract"
var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]" var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
if(T && subtraction_icon_state in icon_states(icon)) if(T && subtraction_icon_state in cached_icon_states(icon))
cut_overlays() cut_overlays()
// If we've made the same icon before, just recycle it. // If we've made the same icon before, just recycle it.
if(cache_string in GLOB.cliff_icon_cache) if(cache_string in GLOB.cliff_icon_cache)

View File

@@ -47,6 +47,9 @@
else else
. += "<span class='notice'>There is a thick layer of silicate covering it.</span>" . += "<span class='notice'>There is a thick layer of silicate covering it.</span>"
/obj/structure/window/examine_icon()
return icon(icon=initial(icon),icon_state=initial(icon_state))
/obj/structure/window/take_damage(var/damage = 0, var/sound_effect = 1) /obj/structure/window/take_damage(var/damage = 0, var/sound_effect = 1)
var/initialhealth = health var/initialhealth = health

View File

@@ -67,7 +67,7 @@
I.color = reinf_material.icon_colour I.color = reinf_material.icon_colour
add_overlay(I) add_overlay(I)
else else
if("[reinf_material.icon_reinf]0" in icon_states('icons/turf/wall_masks.dmi')) if("[reinf_material.icon_reinf]0" in cached_icon_states('icons/turf/wall_masks.dmi'))
// Directional icon // Directional icon
for(var/i = 1 to 4) for(var/i = 1 to 4)
I = image('icons/turf/wall_masks.dmi', "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1)) I = image('icons/turf/wall_masks.dmi', "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1))

View File

@@ -46,6 +46,9 @@
dismantle_wall(null,null,1) dismantle_wall(null,null,1)
..() ..()
/turf/simulated/wall/examine_icon()
return icon(icon=initial(icon), icon_state=initial(icon_state))
/turf/simulated/wall/process() /turf/simulated/wall/process()
// Calling parent will kill processing // Calling parent will kill processing
if(!radiate()) if(!radiate())

View File

@@ -265,32 +265,39 @@ Ccomp's first proc.
/client/proc/allow_character_respawn() /client/proc/allow_character_respawn()
set category = "Special Verbs" set category = "Special Verbs"
set name = "Allow player to respawn" set name = "Allow player to respawn"
set desc = "Let's the player bypass the wait to respawn or allow them to re-enter their corpse." set desc = "Let a player bypass the wait to respawn or allow them to re-enter their corpse."
if(!holder) if(!holder)
return return
var/list/ghosts= get_ghosts(1,1) var/target = input("Select a ckey to allow to rejoin", "Allow Respawn Selector") as null|anything in GLOB.respawn_timers
var/target = input("Please, select a ghost!", "COME BACK TO LIFE!", null, null) as null|anything in ghosts
if(!target) if(!target)
to_chat(src, "Hrm, appears you didn't select a ghost") // Sanity check, if no ghosts in the list we don't want to edit a null variable and cause a runtime error.
return return
if(GLOB.respawn_timers[target] == -1) // Their respawn timer is set to -1, which is 'not allowed to respawn'
var/response = alert(src, "Are you sure you wish to allow this individual to respawn? They would normally not be able to.","Allow impossible respawn?","No","Yes")
if(response == "No")
return
GLOB.respawn_timers -= target
var/mob/observer/dead/G = ghosts[target] var/found_client = FALSE
if(G.has_enabled_antagHUD && config.antag_hud_restricted) for(var/c in GLOB.clients)
var/response = alert(src, "Are you sure you wish to allow this individual to play?","Ghost has used AntagHUD","Yes","No") var/client/C = c
if(response == "No") return if(C.ckey == target)
G.timeofdeath=-19999 /* time of death is checked in /mob/verb/abandon_mob() which is the Respawn verb. found_client = C
timeofdeath is used for bodies on autopsy but since we're messing with a ghost I'm pretty sure to_chat(C, "<span class='notice'><B>You may now respawn. You should roleplay as if you learned nothing about the round during your time with the dead.</B></span>")
there won't be an autopsy. if(isobserver(C.mob))
*/ var/mob/observer/dead/G = C.mob
G.has_enabled_antagHUD = 2 G.can_reenter_corpse = 1
G.can_reenter_corpse = 1 to_chat(C, "<span class='notice'><B>You can also re-enter your corpse, if you still have one!</B></span>")
break
G:show_message(text("<font color='blue'><B>You may now respawn. You should roleplay as if you learned nothing about the round during your time with the dead.</B></font>"), 1) if(!found_client)
log_admin("[key_name(usr)] allowed [key_name(G)] to bypass the respawn time limit") to_chat(src, "<span class='notice'>The associated client didn't appear to be connected, so they couldn't be notified, but they can now respawn if they reconnect.</span>")
message_admins("Admin [key_name_admin(usr)] allowed [key_name_admin(G)] to bypass the respawn time limit", 1)
log_admin("[key_name(usr)] allowed [found_client ? key_name(found_client) : target] to bypass the respawn time limit")
message_admins("Admin [key_name_admin(usr)] allowed [found_client ? key_name_admin(found_client) : target] to bypass the respawn time limit", 1)
/client/proc/toggle_antagHUD_use() /client/proc/toggle_antagHUD_use()

View File

@@ -20,7 +20,7 @@
if(istype(src, /mob/living/carbon/human)) if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src var/mob/living/carbon/human/H = src
H.hud_used = new /datum/hud(H) H.hud_used = new /datum/hud(H)
H.instantiate_hud(H.hud_used) H.create_mob_hud(H.hud_used)
return ..() return ..()
/mob/living/Destroy() /mob/living/Destroy()

View File

@@ -12,7 +12,7 @@
var/vision_range = 7 // How far the targeting system will look for things to kill. Note that values higher than 7 are 'offscreen' and might be unsporting. var/vision_range = 7 // How far the targeting system will look for things to kill. Note that values higher than 7 are 'offscreen' and might be unsporting.
var/respect_alpha = TRUE // If true, mobs with a sufficently low alpha will be treated as invisible. var/respect_alpha = TRUE // If true, mobs with a sufficently low alpha will be treated as invisible.
var/alpha_vision_threshold = 127 // Targets with an alpha less or equal to this will be considered invisible. Requires above var to be true. var/alpha_vision_threshold = FAKE_INVIS_ALPHA_THRESHOLD // Targets with an alpha less or equal to this will be considered invisible. Requires above var to be true.
var/lose_target_time = 0 // world.time when a target was lost. var/lose_target_time = 0 // world.time when a target was lost.
var/lose_target_timeout = 5 SECONDS // How long until a mob 'times out' and stops trying to find the mob that disappeared. var/lose_target_timeout = 5 SECONDS // How long until a mob 'times out' and stops trying to find the mob that disappeared.

View File

@@ -889,7 +889,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
dat += "<tr>" dat += "<tr>"
dat += "<td width = 400>[current_species.blurb]</td>" dat += "<td width = 400>[current_species.blurb]</td>"
dat += "<td width = 200 align='center'>" dat += "<td width = 200 align='center'>"
if("preview" in icon_states(current_species.icobase)) if("preview" in cached_icon_states(current_species.icobase))
usr << browse_rsc(icon(current_species.icobase,"preview"), "species_preview_[current_species.name].png") usr << browse_rsc(icon(current_species.icobase,"preview"), "species_preview_[current_species.name].png")
dat += "<img src='species_preview_[current_species.name].png' width='64px' height='64px'><br/><br/>" dat += "<img src='species_preview_[current_species.name].png' width='64px' height='64px'><br/><br/>"
dat += "<b>Language:</b> [current_species.species_language]<br/>" dat += "<b>Language:</b> [current_species.species_language]<br/>"

View File

@@ -35,18 +35,18 @@
/datum/category_item/player_setup_item/player_global/ui/content(var/mob/user) /datum/category_item/player_setup_item/player_global/ui/content(var/mob/user)
. = "<b>UI Style:</b> <a href='?src=\ref[src];select_style=1'><b>[pref.UI_style]</b></a><br>" . = "<b>UI Style:</b> <a href='?src=\ref[src];select_style=1'><b>[pref.UI_style]</b></a><br>"
. += "<b>Custom UI</b> (recommended for White UI):<br>" . += "<b>Custom UI</b> (recommended for White UI):<br>"
. += "-Color: <a href='?src=\ref[src];select_color=1'><b>[pref.UI_style_color]</b></a><EFBFBD>[color_square(hex = pref.UI_style_color)]<EFBFBD><a href='?src=\ref[src];reset=ui'>reset</a><br>" . += "-Color: <a href='?src=\ref[src];select_color=1'><b>[pref.UI_style_color]</b></a> [color_square(hex = pref.UI_style_color)] <a href='?src=\ref[src];reset=ui'>reset</a><br>"
. += "-Alpha(transparency): <a href='?src=\ref[src];select_alpha=1'><b>[pref.UI_style_alpha]</b></a><EFBFBD><a href='?src=\ref[src];reset=alpha'>reset</a><br>" . += "-Alpha(transparency): <a href='?src=\ref[src];select_alpha=1'><b>[pref.UI_style_alpha]</b></a> <a href='?src=\ref[src];reset=alpha'>reset</a><br>"
. += "<b>Tooltip Style:</b> <a href='?src=\ref[src];select_tooltip_style=1'><b>[pref.tooltipstyle]</b></a><br>" . += "<b>Tooltip Style:</b> <a href='?src=\ref[src];select_tooltip_style=1'><b>[pref.tooltipstyle]</b></a><br>"
. += "<b>Client FPS:</b> <a href='?src=\ref[src];select_client_fps=1'><b>[pref.client_fps]</b></a><br>" . += "<b>Client FPS:</b> <a href='?src=\ref[src];select_client_fps=1'><b>[pref.client_fps]</b></a><br>"
. += "<b>tgui Window Mode:</b> <a href='?src=\ref[src];tgui_fancy=1'><b>[(pref.tgui_fancy) ? "Fancy (default)" : "Compatible (slower)"]</b></a><br>" . += "<b>tgui Window Mode:</b> <a href='?src=\ref[src];tgui_fancy=1'><b>[(pref.tgui_fancy) ? "Fancy (default)" : "Compatible (slower)"]</b></a><br>"
. += "<b>tgui Window Placement:</b> <a href='?src=\ref[src];tgui_lock=1'><b>[(pref.tgui_lock) ? "Primary Monitor" : "Free (default)"]</b></a><br>" . += "<b>tgui Window Placement:</b> <a href='?src=\ref[src];tgui_lock=1'><b>[(pref.tgui_lock) ? "Primary Monitor" : "Free (default)"]</b></a><br>"
if(can_select_ooc_color(user)) if(can_select_ooc_color(user))
. += "<b>OOC Color:</b><EFBFBD>" . += "<b>OOC Color:</b> "
if(pref.ooccolor == initial(pref.ooccolor)) if(pref.ooccolor == initial(pref.ooccolor))
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>Using Default</b></a><br>" . += "<a href='?src=\ref[src];select_ooc_color=1'><b>Using Default</b></a><br>"
else else
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>[pref.ooccolor]</b></a> [color_square(hex = pref.ooccolor)]<EFBFBD><a href='?src=\ref[src];reset=ooc'>reset</a><br>" . += "<a href='?src=\ref[src];select_ooc_color=1'><b>[pref.ooccolor]</b></a> [color_square(hex = pref.ooccolor)] <a href='?src=\ref[src];reset=ooc'>reset</a><br>"
/datum/category_item/player_setup_item/player_global/ui/OnTopic(var/href,var/list/href_list, var/mob/user) /datum/category_item/player_setup_item/player_global/ui/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["select_style"]) if(href_list["select_style"])

View File

@@ -274,3 +274,7 @@
/datum/gear/accessory/cowledvest /datum/gear/accessory/cowledvest
display_name = "cowled vest" display_name = "cowled vest"
path = /obj/item/clothing/accessory/cowledvest path = /obj/item/clothing/accessory/cowledvest
/datum/gear/accessory/asymovercoat
display_name = "orange asymmetrical overcoat"
path = /obj/item/clothing/accessory/asymovercoat

View File

@@ -368,3 +368,18 @@
display_name = "jingasa" display_name = "jingasa"
path = /obj/item/clothing/head/jingasa path = /obj/item/clothing/head/jingasa
/datum/gear/head/sunflower_crown
display_name = "sunflower crown"
path = /obj/item/clothing/head/sunflower_crown
/datum/gear/head/lavender_crown
display_name = "lavender crown"
path = /obj/item/clothing/head/lavender_crown
/datum/gear/head/poppy_crown
display_name = "poppy crown"
path = /obj/item/clothing/head/poppy_crown
/datum/gear/head/rose_crown
display_name = "rose crown"
path = /obj/item/clothing/head/rose_crown

View File

@@ -576,4 +576,12 @@
/datum/gear/uniform/yellowswoop /datum/gear/uniform/yellowswoop
display_name = "yellow swooped dress" display_name = "yellow swooped dress"
path = /obj/item/clothing/under/dress/yellowswoop path = /obj/item/clothing/under/dress/yellowswoop
/datum/gear/uniform/greenasym
display_name = "green asymmetrical jumpsuit"
path = /obj/item/clothing/under/greenasym
/datum/gear/uniform/cyberpunkharness
display_name = "cyberpunk strapped harness"
path = /obj/item/clothing/under/cyberpunkharness

View File

@@ -785,7 +785,7 @@
//autodetect rollability //autodetect rollability
if(rolled_down < 0) if(rolled_down < 0)
if(("[worn_state]_d_s" in icon_states(icon)) || ("[worn_state]_s" in icon_states(rolled_down_icon)) || ("[worn_state]_d_s" in icon_states(icon_override))) if(("[worn_state]_d_s" in cached_icon_states(icon)) || ("[worn_state]_s" in cached_icon_states(rolled_down_icon)) || ("[worn_state]_d_s" in cached_icon_states(icon_override)))
rolled_down = 0 rolled_down = 0
if(rolled_down == -1) if(rolled_down == -1)
@@ -822,11 +822,11 @@
under_icon = sprite_sheets[H.species.get_bodytype(H)] under_icon = sprite_sheets[H.species.get_bodytype(H)]
else if(item_icons && item_icons[slot_w_uniform_str]) else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = item_icons[slot_w_uniform_str] under_icon = item_icons[slot_w_uniform_str]
else if ("[worn_state]_s" in icon_states(rolled_down_icon)) else if ("[worn_state]_s" in cached_icon_states(rolled_down_icon))
under_icon = rolled_down_icon under_icon = rolled_down_icon
// The _s is because the icon update procs append it. // The _s is because the icon update procs append it.
if((under_icon == rolled_down_icon && "[worn_state]_s" in icon_states(under_icon)) || ("[worn_state]_d_s" in icon_states(under_icon))) if((under_icon == rolled_down_icon && "[worn_state]_s" in cached_icon_states(under_icon)) || ("[worn_state]_d_s" in cached_icon_states(under_icon)))
if(rolled_down != 1) if(rolled_down != 1)
rolled_down = 0 rolled_down = 0
else else
@@ -845,13 +845,13 @@
under_icon = sprite_sheets[H.species.get_bodytype(H)] under_icon = sprite_sheets[H.species.get_bodytype(H)]
else if(item_icons && item_icons[slot_w_uniform_str]) else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = item_icons[slot_w_uniform_str] under_icon = item_icons[slot_w_uniform_str]
else if ("[worn_state]_s" in icon_states(rolled_down_sleeves_icon)) else if ("[worn_state]_s" in cached_icon_states(rolled_down_sleeves_icon))
under_icon = rolled_down_sleeves_icon under_icon = rolled_down_sleeves_icon
else if(index) else if(index)
under_icon = new /icon("[INV_W_UNIFORM_DEF_ICON]_[index].dmi") under_icon = new /icon("[INV_W_UNIFORM_DEF_ICON]_[index].dmi")
// The _s is because the icon update procs append it. // The _s is because the icon update procs append it.
if((under_icon == rolled_down_sleeves_icon && "[worn_state]_s" in icon_states(under_icon)) || ("[worn_state]_r_s" in icon_states(under_icon))) if((under_icon == rolled_down_sleeves_icon && "[worn_state]_s" in cached_icon_states(under_icon)) || ("[worn_state]_r_s" in cached_icon_states(under_icon)))
if(rolled_sleeves != 1) if(rolled_sleeves != 1)
rolled_sleeves = 0 rolled_sleeves = 0
else else
@@ -935,7 +935,7 @@
if(rolled_down) if(rolled_down)
body_parts_covered = initial(body_parts_covered) body_parts_covered = initial(body_parts_covered)
body_parts_covered &= ~(UPPER_TORSO|ARMS) body_parts_covered &= ~(UPPER_TORSO|ARMS)
if("[worn_state]_s" in icon_states(rolled_down_icon)) if("[worn_state]_s" in cached_icon_states(rolled_down_icon))
icon_override = rolled_down_icon icon_override = rolled_down_icon
item_state_slots[slot_w_uniform_str] = "[worn_state]" item_state_slots[slot_w_uniform_str] = "[worn_state]"
else else
@@ -968,7 +968,7 @@
rolled_sleeves = !rolled_sleeves rolled_sleeves = !rolled_sleeves
if(rolled_sleeves) if(rolled_sleeves)
body_parts_covered &= ~(ARMS) body_parts_covered &= ~(ARMS)
if("[worn_state]_s" in icon_states(rolled_down_sleeves_icon)) if("[worn_state]_s" in cached_icon_states(rolled_down_sleeves_icon))
icon_override = rolled_down_sleeves_icon icon_override = rolled_down_sleeves_icon
item_state_slots[slot_w_uniform_str] = "[worn_state]" item_state_slots[slot_w_uniform_str] = "[worn_state]"
else else

View File

@@ -39,28 +39,49 @@ BLIND // can't see anything
var/mob/M = src.loc var/mob/M = src.loc
M.update_inv_glasses() M.update_inv_glasses()
/obj/item/clothing/glasses/proc/can_toggle(mob/living/user)
if(!toggleable)
return FALSE
// Prevent people from just turning their goggles back on.
if(!active && (vision_flags & (SEE_TURFS|SEE_OBJS)))
var/area/A = get_area(src)
if(A.no_spoilers)
return FALSE
return TRUE
/obj/item/clothing/glasses/proc/toggle_active(mob/living/user)
if(active)
active = FALSE
icon_state = off_state
user.update_inv_glasses()
flash_protection = FLASH_PROTECTION_NONE
tint = TINT_NONE
away_planes = enables_planes
enables_planes = null
else
active = TRUE
icon_state = initial(icon_state)
user.update_inv_glasses()
flash_protection = initial(flash_protection)
tint = initial(tint)
enables_planes = away_planes
away_planes = null
user.update_action_buttons()
user.recalculate_vis()
/obj/item/clothing/glasses/attack_self(mob/user) /obj/item/clothing/glasses/attack_self(mob/user)
if(toggleable) if(toggleable)
if(active) if(!can_toggle(user))
active = 0 to_chat(user, span("warning", "You don't seem to be able to toggle \the [src] here."))
icon_state = off_state
user.update_inv_glasses()
flash_protection = FLASH_PROTECTION_NONE
tint = TINT_NONE
away_planes = enables_planes
enables_planes = null
to_chat(usr, "You deactivate the optical matrix on the [src].")
else else
active = 1 toggle_active(user)
icon_state = initial(icon_state) if(active)
user.update_inv_glasses() to_chat(user, span("notice", "You activate the optical matrix on the [src]."))
flash_protection = initial(flash_protection) else
tint = initial(tint) to_chat(user, span("notice", "You deactivate the optical matrix on the [src]."))
enables_planes = away_planes
away_planes = null
to_chat(usr, "You activate the optical matrix on the [src].")
user.update_action_buttons()
user.recalculate_vis()
..() ..()
/obj/item/clothing/glasses/meson /obj/item/clothing/glasses/meson

View File

@@ -92,6 +92,7 @@
// Wiring! How exciting. // Wiring! How exciting.
var/datum/wires/rig/wires var/datum/wires/rig/wires
var/datum/effect/effect/system/spark_spread/spark_system var/datum/effect/effect/system/spark_spread/spark_system
var/datum/mini_hud/rig/minihud
/obj/item/weapon/rig/examine() /obj/item/weapon/rig/examine()
. = ..() . = ..()
@@ -187,6 +188,7 @@
START_PROCESSING(SSobj, src) START_PROCESSING(SSobj, src)
else else
STOP_PROCESSING(SSobj, src) STOP_PROCESSING(SSobj, src)
QDEL_NULL(minihud) // Just in case we get removed some other way
// If we've lost any parts, grab them back. // If we've lost any parts, grab them back.
var/mob/living/M var/mob/living/M
@@ -362,6 +364,11 @@
// Success! // Success!
canremove = seal_target canremove = seal_target
if(M.hud_used)
if(canremove)
QDEL_NULL(minihud)
else
minihud = new (M.hud_used, src)
to_chat(M, "<span class='notice'><b>Your entire suit [canremove ? "loosens as the components relax" : "tightens around you as the components lock into place"].</b></span>") to_chat(M, "<span class='notice'><b>Your entire suit [canremove ? "loosens as the components relax" : "tightens around you as the components lock into place"].</b></span>")
M.client.screen -= booting_L M.client.screen -= booting_L
qdel(booting_L) qdel(booting_L)

View File

@@ -24,7 +24,7 @@
if(!inv_overlay) if(!inv_overlay)
var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]" var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]"
if(icon_override) if(icon_override)
if("[tmp_icon_state]_tie" in icon_states(icon_override)) if("[tmp_icon_state]_tie" in cached_icon_states(icon_override))
tmp_icon_state = "[tmp_icon_state]_tie" tmp_icon_state = "[tmp_icon_state]_tie"
inv_overlay = image(icon = icon_override, icon_state = tmp_icon_state, dir = SOUTH) inv_overlay = image(icon = icon_override, icon_state = tmp_icon_state, dir = SOUTH)
else else
@@ -48,7 +48,7 @@
tmp_icon_state = on_rolled["rolled"] tmp_icon_state = on_rolled["rolled"]
if(icon_override) if(icon_override)
if("[tmp_icon_state]_mob" in icon_states(icon_override)) if("[tmp_icon_state]_mob" in cached_icon_states(icon_override))
tmp_icon_state = "[tmp_icon_state]_mob" tmp_icon_state = "[tmp_icon_state]_mob"
mob_overlay = image("icon" = icon_override, "icon_state" = "[tmp_icon_state]") mob_overlay = image("icon" = icon_override, "icon_state" = "[tmp_icon_state]")
else if(wearer && sprite_sheets[wearer.species.get_bodytype(wearer)]) //Teshari can finally into webbing, too! else if(wearer && sprite_sheets[wearer.species.get_bodytype(wearer)]) //Teshari can finally into webbing, too!

View File

@@ -399,4 +399,9 @@
/obj/item/clothing/accessory/asymmetric/green /obj/item/clothing/accessory/asymmetric/green
name = "green asymmetrical jacket" name = "green asymmetrical jacket"
desc = "Insultingly avant-garde in aqua." desc = "Insultingly avant-garde in aqua."
icon_state = "asym_green" icon_state = "asym_green"
/obj/item/clothing/accessory/asymovercoat
name = "orange asymmetrical overcoat"
desc = "An asymmetrical orange overcoat in a 2560's fashion."
icon_state = "asymovercoat"

View File

@@ -13,7 +13,7 @@
if(!base_icon) if(!base_icon)
base_icon = icon_state base_icon = icon_state
if(!("[base_icon]_open" in icon_states(icon))) if(!("[base_icon]_open" in cached_icon_states(icon)))
to_chat(user, "\The [src] doesn't seem to open.") to_chat(user, "\The [src] doesn't seem to open.")
return return

View File

@@ -804,6 +804,18 @@ Uniforms and such
icon_state = "rippedpunk" icon_state = "rippedpunk"
index = 1 index = 1
/obj/item/clothing/under/greenasym
name = "green asymmetrical jumpsuit"
desc = "A green futuristic uniform with asymmetrical pants. Trendy!"
icon_state = "greenasym"
index = 1
/obj/item/clothing/under/cyberpunkharness
name = "cyberpunk strapped harness"
desc = "A cyberpunk styled harness and pants. Perfect for your dystopian future."
icon_state = "cyberhell"
index = 1
/* /*
* swimsuit * swimsuit
*/ */

View File

@@ -78,7 +78,7 @@
var/list/new_item_icons = list() var/list/new_item_icons = list()
var/list/new_item_state_slots = list() var/list/new_item_state_slots = list()
var/list/available_states = icon_states(CUSTOM_ITEM_MOB) var/list/available_states = cached_icon_states(CUSTOM_ITEM_MOB)
//If l_hand or r_hand are not present, preserve them using item_icons/item_state_slots //If l_hand or r_hand are not present, preserve them using item_icons/item_state_slots
//Then use icon_override to make every other slot use the custom sprites by default. //Then use icon_override to make every other slot use the custom sprites by default.

View File

@@ -105,29 +105,37 @@
A.clean_blood() A.clean_blood()
/obj/item/weapon/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag) /obj/item/weapon/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag)
if(isliving(target)) if(isliving(target)) //Leaving this as isliving.
var/mob/living/M = target var/mob/living/M = target
if(on_fire) if(on_fire) //Check if rag is on fire, if so igniting them and stopping.
user.visible_message("<span class='danger'>\The [user] hits [target] with [src]!</span>",) user.visible_message("<span class='danger'>\The [user] hits [target] with [src]!</span>",)
user.do_attack_animation(src) user.do_attack_animation(src)
M.IgniteMob() M.IgniteMob()
else if(reagents.total_volume) else if(user.zone_sel.selecting == O_MOUTH) //Check player target location, provided the rag is not on fire. Then check if mouth is exposed.
if(user.zone_sel.selecting == O_MOUTH) if(ishuman(target)) //Added this since player species process reagents in majority of cases.
user.do_attack_animation(src) var/mob/living/carbon/human/H = target
user.visible_message( if(H.head && (H.head.body_parts_covered & FACE)) //Check human head coverage.
"<span class='danger'>\The [user] smothers [target] with [src]!</span>", to_chat(user, "<span class='warning'>Remove their [H.head] first.</span>")
"<span class='warning'>You smother [target] with [src]!</span>", return
"You hear some struggling and muffled cries of surprise" else if(reagents.total_volume) //Final check. If the rag is not on fire and their face is uncovered, smother target.
) user.do_attack_animation(src)
user.visible_message(
//it's inhaled, so... maybe CHEM_BLOOD doesn't make a whole lot of sense but it's the best we can do for now "<span class='danger'>\The [user] smothers [target] with [src]!</span>",
reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BLOOD) "<span class='warning'>You smother [target] with [src]!</span>",
update_name() "You hear some struggling and muffled cries of surprise"
)
//it's inhaled, so... maybe CHEM_BLOOD doesn't make a whole lot of sense but it's the best we can do for now
reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BLOOD)
update_name()
else
to_chat(user, "<span class='warning'>You can't smother this creature.</span>")
else else
wipe_down(target, user) to_chat(user, "<span class='warning'>You can't smother this creature.</span>")
return else
wipe_down(target, user)
return ..() else
wipe_down(target, user)
return
/obj/item/weapon/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user as mob, proximity) /obj/item/weapon/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user as mob, proximity)
if(!proximity) if(!proximity)

View File

@@ -139,7 +139,7 @@
set category = "Object" set category = "Object"
set src in view(1) set src in view(1)
to_world("usr is [usr]") //to_world("usr is [usr]") //why was this a thing? -KK.
display_data(usr) display_data(usr)
/obj/item/device/detective_scanner/proc/display_data(var/mob/user) /obj/item/device/detective_scanner/proc/display_data(var/mob/user)

View File

@@ -5,7 +5,7 @@
This means that this file can be unchecked, along with the other examine files, and can be removed entirely with no effort. This means that this file can be unchecked, along with the other examine files, and can be removed entirely with no effort.
*/ */
#define EXAMINE_PANEL_PADDING " " #define EXAMINE_PANEL_PADDING " "
/atom/ /atom/
var/description_info = null //Helpful blue text. var/description_info = null //Helpful blue text.
@@ -56,7 +56,7 @@
description_holders["interactions"] = A.get_description_interaction() description_holders["interactions"] = A.get_description_interaction()
description_holders["name"] = "[A.name]" description_holders["name"] = "[A.name]"
description_holders["icon"] = "\icon[A]" description_holders["icon"] = "\icon[A.examine_icon()]"
description_holders["desc"] = A.desc description_holders["desc"] = A.desc
/mob/Stat() /mob/Stat()

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