Conflicts:
	.travis.yml
	code/controllers/configuration.dm
	code/game/gamemodes/changeling/modularchangling.dm
	code/game/jobs/job/medical.dm
	code/game/jobs/job/security.dm
	code/game/machinery/Sleeper.dm
	code/game/machinery/computer/communications.dm
	code/game/machinery/cryopod.dm
	code/game/objects/items/weapons/RCD.dm
	code/game/objects/items/weapons/storage/boxes.dm
	code/game/turfs/simulated/floor.dm
	code/game/turfs/simulated/floor_types.dm
	code/global.dm
	code/modules/materials/materials.dm
	code/modules/mob/living/silicon/ai/ai.dm
	code/modules/projectiles/guns/projectile/automatic.dm
	polaris.dme
This commit is contained in:
Neerti
2015-08-23 01:30:46 -04:00
792 changed files with 19715 additions and 17049 deletions

View File

@@ -12,14 +12,14 @@
#define PIPE_COLOR_CYAN "#00ffff"
#define PIPE_COLOR_GREEN "#00ff00"
#define PIPE_COLOR_YELLOW "#ffcc00"
#define PIPE_COLOR_PURPLE "#5c1ec0"
#define PIPE_COLOR_BLACK "#444444"
#define CONNECT_TYPE_REGULAR 1
#define CONNECT_TYPE_SUPPLY 2
#define CONNECT_TYPE_SCRUBBER 4
#define CONNECT_TYPE_HE 8
var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "purple" = PIPE_COLOR_PURPLE)
var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "black" = PIPE_COLOR_BLACK)
/proc/pipe_color_lookup(var/color)
for(var/C in pipe_colors)

View File

@@ -49,7 +49,7 @@ Pipelines + Other Objects -> Pipe network
/obj/machinery/atmospherics/proc/add_underlay(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type)
if(node)
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
if(!T.is_plating() && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
//underlays += icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node))
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
else

View File

@@ -8,8 +8,6 @@
#define PRESSURE_CHECK_INPUT 2
#define PRESSURE_CHECK_OUTPUT 4
#undefine
/obj/machinery/atmospherics/binary/dp_vent_pump
icon = 'icons/atmos/vent_pump.dmi'
icon_state = "map_dp_vent"
@@ -69,7 +67,7 @@
if(!istype(T))
return
if(T.intact && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
if(!T.is_plating() && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
vent_icon += "h"
if(!powered())
@@ -85,7 +83,7 @@
var/turf/T = get_turf(src)
if(!istype(T))
return
if(T.intact && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
if(!T.is_plating() && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
return
else
if (node1)
@@ -258,4 +256,14 @@
spawn(2)
broadcast_status()
update_icon()
update_icon()
#undef DEFAULT_PRESSURE_DELTA
#undef EXTERNAL_PRESSURE_BOUND
#undef INTERNAL_PRESSURE_BOUND
#undef PRESSURE_CHECKS
#undef PRESSURE_CHECK_EXTERNAL
#undef PRESSURE_CHECK_INPUT
#undef PRESSURE_CHECK_OUTPUT

View File

@@ -2,8 +2,6 @@
#define REGULATE_INPUT 1 //shuts off when input side is below the target pressure
#define REGULATE_OUTPUT 2 //shuts off when output side is above the target pressure
#undefine
/obj/machinery/atmospherics/binary/passive_gate
icon = 'icons/atmos/passive_gate.dmi'
icon_state = "map"
@@ -259,3 +257,7 @@
"You hear ratchet.")
new /obj/item/pipe(loc, make_from=src)
qdel(src)
#undef REGULATE_NONE
#undef REGULATE_INPUT
#undef REGULATE_OUTPUT

View File

@@ -189,7 +189,7 @@
var/turf/T = get_turf(src)
if(!istype(T))
return
if(T.intact && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 )
if(!T.is_plating() && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 )
//pipe_state = icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node))
pipe_state = icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down")
else

View File

@@ -43,6 +43,13 @@
node = target
break
//copied from pipe construction code since heaters/freezers don't use fittings and weren't doing this check - this all really really needs to be refactored someday.
//check that there are no incompatible pipes/machinery in our own location
for(var/obj/machinery/atmospherics/M in src.loc)
if(M != src && (M.initialize_directions & node_connect) && M.check_connect_types(M,src)) // matches at least one direction on either type of pipe & same connection type
node = null
break
update_icon()
/obj/machinery/atmospherics/unary/freezer/update_icon()

View File

@@ -69,7 +69,7 @@
if (!istype(W, /obj/item/weapon/wrench))
return ..()
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
if (level==1 && isturf(T) && !T.is_plating())
user << "<span class='warning'>You must remove the plating first.</span>"
return 1
var/datum/gas_mixture/int_air = return_air()

View File

@@ -39,11 +39,19 @@
var/node_connect = dir
//check that there is something to connect to
for(var/obj/machinery/atmospherics/target in get_step(src, node_connect))
if(target.initialize_directions & get_dir(target, src))
node = target
break
//copied from pipe construction code since heaters/freezers don't use fittings and weren't doing this check - this all really really needs to be refactored someday.
//check that there are no incompatible pipes/machinery in our own location
for(var/obj/machinery/atmospherics/M in src.loc)
if(M != src && (M.initialize_directions & node_connect) && M.check_connect_types(M,src)) // matches at least one direction on either type of pipe & same connection type
node = null
break
update_icon()

View File

@@ -7,8 +7,6 @@
#define PRESSURE_CHECK_EXTERNAL 1
#define PRESSURE_CHECK_INTERNAL 2
#undefine
/obj/machinery/atmospherics/unary/vent_pump
icon = 'icons/atmos/vent_pump.dmi'
icon_state = "map_vent"
@@ -118,7 +116,7 @@
if(!istype(T))
return
if(T.intact && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
if(!T.is_plating() && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
vent_icon += "h"
if(welded)
@@ -136,7 +134,7 @@
var/turf/T = get_turf(src)
if(!istype(T))
return
if(T.intact && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
if(!T.is_plating() && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
return
else
if(node)
@@ -399,7 +397,7 @@
user << "<span class='warning'>You cannot unwrench \the [src], turn it off first.</span>"
return 1
var/turf/T = src.loc
if (node && node.level==1 && isturf(T) && T.intact)
if (node && node.level==1 && isturf(T) && !T.is_plating())
user << "<span class='warning'>You must remove the plating first.</span>"
return 1
var/datum/gas_mixture/int_air = return_air()
@@ -424,3 +422,12 @@
initial_loc.air_vent_names -= id_tag
..()
return
#undef DEFAULT_PRESSURE_DELTA
#undef EXTERNAL_PRESSURE_BOUND
#undef INTERNAL_PRESSURE_BOUND
#undef PRESSURE_CHECKS
#undef PRESSURE_CHECK_EXTERNAL
#undef PRESSURE_CHECK_INTERNAL

View File

@@ -72,7 +72,7 @@
var/turf/T = get_turf(src)
if(!istype(T))
return
if(T.intact && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
if(!T.is_plating() && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
return
else
if(node)
@@ -261,7 +261,7 @@
user << "<span class='warning'>You cannot unwrench \the [src], turn it off first.</span>"
return 1
var/turf/T = src.loc
if (node && node.level==1 && isturf(T) && T.intact)
if (node && node.level==1 && isturf(T) && !T.is_plating())
user << "<span class='warning'>You must remove the plating first.</span>"
return 1
var/datum/gas_mixture/int_air = return_air()

View File

@@ -181,7 +181,7 @@ obj/machinery/atmospherics/mains_pipe/simple
..() // initialize internal pipes
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
hidden
@@ -243,7 +243,7 @@ obj/machinery/atmospherics/mains_pipe/manifold
..() // initialize internal pipes
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
update_icon()
@@ -293,7 +293,7 @@ obj/machinery/atmospherics/mains_pipe/manifold4w
..() // initialize internal pipes
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
update_icon()
@@ -354,7 +354,7 @@ obj/machinery/atmospherics/mains_pipe/split
N1.merge(N2)
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
update_icon()
@@ -475,7 +475,7 @@ obj/machinery/atmospherics/mains_pipe/split3
N1.merge(N2)
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
update_icon()
@@ -525,7 +525,7 @@ obj/machinery/atmospherics/mains_pipe/cap
..()
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
hidden

View File

@@ -1,8 +1,7 @@
/obj/machinery/atmospherics/pipe
var/datum/gas_mixture/air_temporary //used when reconstructing a pipeline that broke
var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke
var/datum/pipeline/parent
var/volume = 0
force = 20
@@ -20,10 +19,12 @@
return -1
/obj/machinery/atmospherics/pipe/New()
..()
//so pipes under walls are hidden
if(istype(get_turf(src), /turf/simulated/wall) || istype(get_turf(src), /turf/simulated/shuttle/wall) || istype(get_turf(src), /turf/unsimulated/wall))
level = 1
..()
/obj/machinery/atmospherics/pipe/hides_under_flooring()
return level != 2
/obj/machinery/atmospherics/pipe/proc/pipeline_expansion()
return null
@@ -81,7 +82,7 @@
if (!istype(W, /obj/item/weapon/wrench))
return ..()
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
if (level==1 && isturf(T) && !T.is_plating())
user << "<span class='warning'>You must remove the plating first.</span>"
return 1
var/datum/gas_mixture/int_air = return_air()
@@ -188,7 +189,7 @@
initialize_directions = SOUTH|WEST
/obj/machinery/atmospherics/pipe/simple/hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
if(istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
@@ -297,9 +298,8 @@
qdel(src)
return
var/turf/T = get_turf(src)
if(istype(T))
hide(T.intact)
var/turf/T = loc
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
/obj/machinery/atmospherics/pipe/simple/disconnect(obj/machinery/atmospherics/reference)
@@ -348,8 +348,8 @@
/obj/machinery/atmospherics/pipe/simple/visible/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/simple/visible/purple
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/simple/visible/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/simple/visible/red
color = PIPE_COLOR_RED
@@ -390,8 +390,8 @@
/obj/machinery/atmospherics/pipe/simple/hidden/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/simple/hidden/purple
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/simple/hidden/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/simple/hidden/red
color = PIPE_COLOR_RED
@@ -446,7 +446,7 @@
initialize_directions = NORTH|EAST|SOUTH
/obj/machinery/atmospherics/pipe/manifold/hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
if(istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
@@ -582,8 +582,7 @@
return
var/turf/T = get_turf(src)
if(istype(T))
hide(T.intact)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
/obj/machinery/atmospherics/pipe/manifold/visible
@@ -617,8 +616,8 @@
/obj/machinery/atmospherics/pipe/manifold/visible/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/manifold/visible/purple
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/manifold/visible/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/manifold/visible/red
color = PIPE_COLOR_RED
@@ -659,8 +658,8 @@
/obj/machinery/atmospherics/pipe/manifold/hidden/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/manifold/hidden/purple
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/manifold/hidden/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/manifold/hidden/red
color = PIPE_COLOR_RED
@@ -806,7 +805,7 @@
update_icon()
/obj/machinery/atmospherics/pipe/manifold4w/hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
if(istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
@@ -841,8 +840,7 @@
return
var/turf/T = get_turf(src)
if(istype(T))
hide(T.intact)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
/obj/machinery/atmospherics/pipe/manifold4w/visible
@@ -876,8 +874,8 @@
/obj/machinery/atmospherics/pipe/manifold4w/visible/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/manifold4w/visible/purple
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/manifold4w/visible/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/manifold4w/visible/red
color = PIPE_COLOR_RED
@@ -917,8 +915,8 @@
/obj/machinery/atmospherics/pipe/manifold4w/hidden/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/manifold4w/hidden/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/manifold4w/hidden/red
color = PIPE_COLOR_RED
@@ -946,7 +944,7 @@
initialize_directions = dir
/obj/machinery/atmospherics/pipe/cap/hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
if(istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
@@ -997,7 +995,7 @@
break
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
/obj/machinery/atmospherics/pipe/cap/visible
@@ -1120,20 +1118,8 @@
return
if(istype(W, /obj/item/device/analyzer) && in_range(user, src))
for (var/mob/O in viewers(user, null))
O << "<span class='notice'>\The [user] has used \the [W] on \the [src] \icon[src]</span>"
var/pressure = parent.air.return_pressure()
var/total_moles = parent.air.total_moles
user << "<span class='notice'>Results of analysis of \the [src] \icon[src]</span>"
if (total_moles>0)
user << "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>"
for(var/g in parent.air.gas)
user << "<span class='notice'>[gas_data.name[g]]: [round((parent.air.gas[g] / total_moles) * 100)]%</span>"
user << "<span class='notice'>Temperature: [round(parent.air.temperature-T0C)]&deg;C</span>"
else
user << "<span class='notice'>Tank is empty!</span>"
var/obj/item/device/analyzer/A = W
A.analyze_gases(src, user)
/obj/machinery/atmospherics/pipe/tank/air
name = "Pressure Tank (Air)"
@@ -1398,7 +1384,7 @@
/obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays
if(node)
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
if(!T.is_plating() && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
else
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)

View File

@@ -46,8 +46,8 @@ obj/machinery/atmospherics/pipe/zpipe/New()
if(SOUTHWEST)
initialize_directions = SOUTH
obj/machinery/atmospherics/pipe/zpipe/hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
/obj/machinery/atmospherics/pipe/zpipe/hide(var/i)
if(istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
@@ -149,7 +149,7 @@ obj/machinery/atmospherics/pipe/zpipe/up/initialize()
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
hide(!T.is_plating())
///////////////////////
// and the down pipe //
@@ -190,7 +190,7 @@ obj/machinery/atmospherics/pipe/zpipe/down/initialize()
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
hide(!T.is_plating())
///////////////////////
// supply/scrubbers //

View File

@@ -1,6 +1,5 @@
/turf/simulated/floor/open
name = "open space"
intact = 0
density = 0
icon_state = "black"
pathweight = 100000 //Seriously, don't try and path over this one numbnuts
@@ -81,8 +80,7 @@
// override to make sure nothing is hidden
/turf/simulated/floor/open/levelupdate()
for(var/obj/O in src)
if(O.level == 1)
O.hide(0)
O.hide(0)
//overwrite the attackby of space to transform it to openspace if necessary
/turf/space/attackby(obj/item/C as obj, mob/user as mob)
@@ -114,16 +112,16 @@
ReplaceWithLattice()
return
if (istype(C, /obj/item/stack/tile/steel))
if (istype(C, /obj/item/stack/tile/floor))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/steel/S = C
var/obj/item/stack/tile/floor/S = C
if (S.get_amount() < 1)
return
qdel(L)
playsound(src.loc, 'sound/weapons/Genhit.ogg', 50, 1)
S.build(src)
S.use(1)
ChangeTurf(/turf/simulated/floor/airless)
return
else
user << "<span class='warning'>The plating is going to need some support.</span>"

View File

@@ -19,12 +19,12 @@ mob/proc/airflow_stun()
mob/living/silicon/airflow_stun()
return
mob/living/carbon/metroid/airflow_stun()
mob/living/carbon/slime/airflow_stun()
return
mob/living/carbon/human/airflow_stun()
if(shoes)
if(shoes.flags & NOSLIP) return 0
if(shoes.item_flags & NOSLIP) return 0
..()
atom/movable/proc/check_airflow_movable(n)
@@ -62,6 +62,19 @@ obj/item/check_airflow_movable(n)
/atom/movable/var/tmp/airflow_time = 0
/atom/movable/var/tmp/last_airflow = 0
/atom/movable/proc/AirflowCanMove(n)
return 1
/mob/AirflowCanMove(n)
if(status_flags & GODMODE)
return 0
if(buckled)
return 0
var/obj/item/shoes = get_equipped_item(slot_shoes)
if(istype(shoes) && (shoes.item_flags & NOSLIP))
return 0
return 1
/atom/movable/proc/GotoAirflowDest(n)
if(!airflow_dest) return
if(airflow_speed < 0) return
@@ -69,18 +82,13 @@ obj/item/check_airflow_movable(n)
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
return
last_airflow = world.time
if(airflow_dest == loc)
step_away(src,loc)
if(!src.AirflowCanMove(n))
return
if(ismob(src))
if(src:status_flags & GODMODE)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
return
if(src:shoes && src:shoes.flags & NOSLIP)
return
src << "<span class='danger'>You are sucked away by airflow!</span>"
last_airflow = world.time
var/airflow_falloff = 9 - sqrt((x - airflow_dest.x) ** 2 + (y - airflow_dest.y) ** 2)
if(airflow_falloff < 1)
airflow_dest = null
@@ -116,8 +124,9 @@ obj/item/check_airflow_movable(n)
if(!istype(loc, /turf))
break
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + vsc.airflow_mob_slowdown
var/mob/M = src
if(istype(M) && M.client)
M.setMoveCooldown(vsc.airflow_mob_slowdown)
airflow_dest = null
airflow_speed = 0
airflow_time = 0
@@ -134,18 +143,11 @@ obj/item/check_airflow_movable(n)
return
if(airflow_dest == loc)
step_away(src,loc)
if(!src.AirflowCanMove(n))
return
if(ismob(src))
if(src:status_flags & GODMODE)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
return
if(src:shoes)
if(istype(src:shoes, /obj/item/clothing/shoes/magboots))
if(src:shoes.flags & NOSLIP)
return
src << "<span clas='danger'>You are pushed away by airflow!</span>"
last_airflow = world.time
last_airflow = world.time
var/airflow_falloff = 9 - sqrt((x - airflow_dest.x) ** 2 + (y - airflow_dest.y) ** 2)
if(airflow_falloff < 1)
airflow_dest = null
@@ -242,6 +244,6 @@ zone/proc/movables()
. = list()
for(var/turf/T in contents)
for(var/atom/movable/A in T)
if(!A.simulated || A.anchored || istype(A, /obj/effect) || istype(A, /mob/aiEye))
if(!A.simulated || A.anchored || istype(A, /obj/effect) || istype(A, /mob/eye))
continue
. += A

View File

@@ -97,14 +97,14 @@ obj/var/contaminated = 0
if(!wear_mask)
burn_eyes()
else
if(!(wear_mask.flags & MASKCOVERSEYES))
if(!(wear_mask.body_parts_covered & EYES))
burn_eyes()
else
if(!(head.flags & HEADCOVERSEYES))
if(!(head.body_parts_covered & EYES))
if(!wear_mask)
burn_eyes()
else
if(!(wear_mask.flags & MASKCOVERSEYES))
if(!(wear_mask.body_parts_covered & EYES))
burn_eyes()
//Genetic Corruption
@@ -135,19 +135,24 @@ obj/var/contaminated = 0
if(vsc.plc.PHORONGUARD_ONLY)
if(head.flags & PHORONGUARD)
return 1
else if(head.flags & HEADCOVERSEYES)
else if(head.body_parts_covered & EYES)
return 1
return 0
/mob/living/carbon/human/proc/pl_suit_protected()
//Checks if the suit is adequately sealed.
if(wear_suit)
if(vsc.plc.PHORONGUARD_ONLY)
if(wear_suit.flags & PHORONGUARD) return 1
else
if(wear_suit.flags_inv & HIDEJUMPSUIT) return 1
//should check HIDETAIL as well, but for the moment tails are not a part that can be damaged separately
return 0
var/coverage = 0
for(var/obj/item/protection in list(wear_suit, gloves, shoes))
if(!protection)
continue
if(vsc.plc.PHORONGUARD_ONLY && !(protection.flags & PHORONGUARD))
return 0
coverage |= protection.body_parts_covered
if(vsc.plc.PHORONGUARD_ONLY)
return 1
return BIT_TEST_ALL(coverage, UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS)
/mob/living/carbon/human/proc/suit_contamination()
//Runs over the things that can be contaminated and does so.

View File

@@ -1,12 +1,12 @@
// A set of constants used to determine which type of mute an admin wishes to apply.
// Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO, etc. = (MUTE_IC << 1)
// Therefore there needs to be a gap between the flags for the automute flags.
#define MUTE_IC 1
#define MUTE_OOC 2
#define MUTE_PRAY 4
#define MUTE_ADMINHELP 8
#define MUTE_DEADCHAT 16
#define MUTE_ALL 31
#define MUTE_IC 0x1
#define MUTE_OOC 0x2
#define MUTE_PRAY 0x4
#define MUTE_ADMINHELP 0x8
#define MUTE_DEADCHAT 0x10
#define MUTE_ALL 0xFFFF
// Number of identical messages required to get the spam-prevention auto-mute thing to trigger warnings and automutes.
#define SPAM_TRIGGER_WARNING 5
@@ -21,22 +21,22 @@
#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 // Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued.
// Admin permissions. Please don't edit these values without speaking to Errorage first. ~Carn
#define R_BUILDMODE 1
#define R_ADMIN 2
#define R_BAN 4
#define R_FUN 8
#define R_SERVER 16
#define R_DEBUG 32
#define R_POSSESS 64
#define R_PERMISSIONS 128
#define R_STEALTH 256
#define R_REJUVINATE 512
#define R_VAREDIT 1024
#define R_SOUNDS 2048
#define R_SPAWN 4096
#define R_MOD 8192
#define R_MENTOR 16384
#define R_HOST 32768
// Admin permissions.
#define R_BUILDMODE 0x1
#define R_ADMIN 0x2
#define R_BAN 0x4
#define R_FUN 0x8
#define R_SERVER 0x10
#define R_DEBUG 0x20
#define R_POSSESS 0x40
#define R_PERMISSIONS 0x80
#define R_STEALTH 0x100
#define R_REJUVINATE 0x200
#define R_VAREDIT 0x400
#define R_SOUNDS 0x800
#define R_SPAWN 0x1000
#define R_MOD 0x2000
#define R_MENTOR 0x4000
#define R_HOST 0x8000 //higher than this will overflow
#define R_MAXPERMISSION 32768 // This holds the maximum value for a permission. It is used in iteration, so keep it updated.
#define R_MAXPERMISSION 0x8000 // This holds the maximum value for a permission. It is used in iteration, so keep it updated.

View File

@@ -8,6 +8,8 @@
#define MOLES_PHORON_VISIBLE 0.7 // Moles in a standard cell after which phoron is visible.
#define MOLES_O2STANDARD (MOLES_CELLSTANDARD * O2STANDARD) // O2 standard value (21%)
#define MOLES_N2STANDARD (MOLES_CELLSTANDARD * N2STANDARD) // N2 standard value (79%)
#define MOLES_O2ATMOS (MOLES_O2STANDARD*50)
#define MOLES_N2ATMOS (MOLES_N2STANDARD*50)
// These are for when a mob breathes poisonous air.
#define MIN_TOXIN_DAMAGE 1
@@ -83,4 +85,4 @@
//Flags for zone sleeping
#define ZONE_ACTIVE 1
#define ZONE_SLEEPING 0
#define ZONE_SLEEPING 0

View File

@@ -21,10 +21,10 @@
#define DROWSY "drowsy"
// I hate adding defines like this but I'd much rather deal with bitflags than lists and string searches.
#define BRUTELOSS 1
#define FIRELOSS 2
#define TOXLOSS 4
#define OXYLOSS 8
#define BRUTELOSS 0x1
#define FIRELOSS 0x2
#define TOXLOSS 0x4
#define OXYLOSS 0x8
#define FIRE_DAMAGE_MODIFIER 0.0215 // Higher values result in more external fire damage to the skin. (default 0.0215)
#define AIR_DAMAGE_MODIFIER 2.025 // More means less damage from hot air scalding lungs, less = more damage. (default 2.025)
@@ -53,4 +53,4 @@
#define INFECTION_LEVEL_ONE 100
#define INFECTION_LEVEL_TWO 500
#define INFECTION_LEVEL_THREE 1000
#define INFECTION_LEVEL_THREE 1000

View File

@@ -31,16 +31,16 @@
#define mSmallsize 110 // Table climbing.
// disabilities
#define NEARSIGHTED 1
#define EPILEPSY 2
#define COUGHING 4
#define TOURETTES 8
#define NERVOUS 16
#define NEARSIGHTED 0x1
#define EPILEPSY 0x2
#define COUGHING 0x4
#define TOURETTES 0x8
#define NERVOUS 0x10
// sdisabilities
#define BLIND 1
#define MUTE 2
#define DEAF 4
#define BLIND 0x1
#define MUTE 0x2
#define DEAF 0x4
// The way blocks are handled badly needs a rewrite, this is horrible.
// Too much of a project to handle at the moment, TODO for later.

View File

@@ -9,21 +9,21 @@
#define SEC_LEVEL_RED 2
#define SEC_LEVEL_DELTA 3
#define BE_TRAITOR 1
#define BE_OPERATIVE 2
#define BE_CHANGELING 4
#define BE_WIZARD 8
#define BE_MALF 16
#define BE_REV 32
#define BE_ALIEN 64
#define BE_AI 128
#define BE_CULTIST 256
#define BE_MONKEY 512
#define BE_NINJA 1024
#define BE_RAIDER 2048
#define BE_PLANT 4096
#define BE_MUTINEER 8192
#define BE_PAI 16384
#define BE_TRAITOR 0x1
#define BE_OPERATIVE 0x2
#define BE_CHANGELING 0x4
#define BE_WIZARD 0x8
#define BE_MALF 0x10
#define BE_REV 0x20
#define BE_ALIEN 0x40
#define BE_AI 0x80
#define BE_CULTIST 0x100
#define BE_MONKEY 0x200
#define BE_NINJA 0x400
#define BE_RAIDER 0x800
#define BE_PLANT 0x1000
#define BE_MUTINEER 0x2000
#define BE_PAI 0x4000
var/list/be_special_flags = list(
"Traitor" = BE_TRAITOR,
@@ -47,17 +47,17 @@ var/list/be_special_flags = list(
// Antagonist datum flags.
#define ANTAG_OVERRIDE_JOB 1 // Assigned job is set to MODE when spawning.
#define ANTAG_OVERRIDE_MOB 2 // Mob is recreated from datum mob_type var when spawning.
#define ANTAG_CLEAR_EQUIPMENT 4 // All preexisting equipment is purged.
#define ANTAG_CHOOSE_NAME 8 // Antagonists are prompted to enter a name.
#define ANTAG_IMPLANT_IMMUNE 16 // Cannot be loyalty implanted.
#define ANTAG_SUSPICIOUS 32 // Shows up on roundstart report.
#define ANTAG_HAS_LEADER 64 // Generates a leader antagonist.
#define ANTAG_HAS_NUKE 128 // Will spawn a nuke at supplied location.
#define ANTAG_RANDSPAWN 256 // Potentially randomly spawns due to events.
#define ANTAG_VOTABLE 512 // Can be voted as an additional antagonist before roundstart.
#define ANTAG_SET_APPEARANCE 1024 // Causes antagonists to use an appearance modifier on spawn.
#define ANTAG_OVERRIDE_JOB 0x1 // Assigned job is set to MODE when spawning.
#define ANTAG_OVERRIDE_MOB 0x2 // Mob is recreated from datum mob_type var when spawning.
#define ANTAG_CLEAR_EQUIPMENT 0x4 // All preexisting equipment is purged.
#define ANTAG_CHOOSE_NAME 0x8 // Antagonists are prompted to enter a name.
#define ANTAG_IMPLANT_IMMUNE 0x10 // Cannot be loyalty implanted.
#define ANTAG_SUSPICIOUS 0x20 // Shows up on roundstart report.
#define ANTAG_HAS_LEADER 0x40 // Generates a leader antagonist.
#define ANTAG_HAS_NUKE 0x80 // Will spawn a nuke at supplied location.
#define ANTAG_RANDSPAWN 0x100 // Potentially randomly spawns due to events.
#define ANTAG_VOTABLE 0x200 // Can be voted as an additional antagonist before roundstart.
#define ANTAG_SET_APPEARANCE 0x400 // Causes antagonists to use an appearance modifier on spawn.
// Mode/antag template macros.
#define MODE_BORER "borer"
@@ -87,22 +87,22 @@ var/list/be_special_flags = list(
/////////////////
/* WIZARD SPELL FLAGS */
#define GHOSTCAST 1 //can a ghost cast it?
#define NEEDSCLOTHES 2 //does it need the wizard garb to cast? Nonwizard spells should not have this
#define NEEDSHUMAN 4 //does it require the caster to be human?
#define Z2NOCAST 8 //if this is added, the spell can't be cast at centcomm
#define STATALLOWED 16 //if set, the user doesn't have to be conscious to cast. Required for ghost spells
#define IGNOREPREV 32 //if set, each new target does not overlap with the previous one
#define GHOSTCAST 0x1 //can a ghost cast it?
#define NEEDSCLOTHES 0x2 //does it need the wizard garb to cast? Nonwizard spells should not have this
#define NEEDSHUMAN 0x4 //does it require the caster to be human?
#define Z2NOCAST 0x8 //if this is added, the spell can't be cast at centcomm
#define STATALLOWED 0x10 //if set, the user doesn't have to be conscious to cast. Required for ghost spells
#define IGNOREPREV 0x20 //if set, each new target does not overlap with the previous one
//The following flags only affect different types of spell, and therefore overlap
//Targeted spells
#define INCLUDEUSER 64 //does the spell include the caster in its target selection?
#define SELECTABLE 128 //can you select each target for the spell?
#define INCLUDEUSER 0x40 //does the spell include the caster in its target selection?
#define SELECTABLE 0x80 //can you select each target for the spell?
//AOE spells
#define IGNOREDENSE 64 //are dense turfs ignored in selection?
#define IGNORESPACE 128 //are space turfs ignored in selection?
#define IGNOREDENSE 0x40 //are dense turfs ignored in selection?
#define IGNORESPACE 0x80 //are space turfs ignored in selection?
//End split flags
#define CONSTRUCT_CHECK 256 //used by construct spells - checks for nullrods
#define NO_BUTTON 512 //spell won't show up in the HUD with this
#define CONSTRUCT_CHECK 0x100 //used by construct spells - checks for nullrods
#define NO_BUTTON 0x200 //spell won't show up in the HUD with this
//invocation
#define SpI_SHOUT "shout"

View File

@@ -5,71 +5,63 @@
#define CANDLE_LUM 3 // For how bright candles are.
// Item inventory slot bitmasks.
#define SLOT_OCLOTHING 1
#define SLOT_ICLOTHING 2
#define SLOT_GLOVES 4
#define SLOT_EYES 8
#define SLOT_EARS 16
#define SLOT_MASK 32
#define SLOT_HEAD 64
#define SLOT_FEET 128
#define SLOT_ID 256
#define SLOT_BELT 512
#define SLOT_BACK 1024
#define SLOT_POCKET 2048 // This is to allow items with a w_class of 3 or 4 to fit in pockets.
#define SLOT_DENYPOCKET 4096 // This is to deny items with a w_class of 2 or 1 from fitting in pockets.
#define SLOT_TWOEARS 8192
#define SLOT_TIE 16384
#define SLOT_HOLSTER 32768 //16th bit
#define SLOT_OCLOTHING 0x1
#define SLOT_ICLOTHING 0x2
#define SLOT_GLOVES 0x4
#define SLOT_EYES 0x8
#define SLOT_EARS 0x10
#define SLOT_MASK 0x20
#define SLOT_HEAD 0x40
#define SLOT_FEET 0x80
#define SLOT_ID 0x100
#define SLOT_BELT 0x200
#define SLOT_BACK 0x400
#define SLOT_POCKET 0x800 // This is to allow items with a w_class of 3 or 4 to fit in pockets.
#define SLOT_DENYPOCKET 0x1000 // This is to deny items with a w_class of 2 or 1 from fitting in pockets.
#define SLOT_TWOEARS 0x2000
#define SLOT_TIE 0x4000
#define SLOT_HOLSTER 0x8000 //16th bit - higher than this will overflow
// Flags bitmasks.
#define STOPPRESSUREDAMAGE 1 // This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere
// To successfully stop you taking all pressure damage you must have both a suit and head item with this flag.
#define NOBLUDGEON 2 // When an item has this it produces no "X has been hit by Y with Z" message with the default handler.
#define AIRTIGHT 4 // Functions with internals.
#define USEDELAY 8 // 1 second extra delay on use. (Can be used once every 2s)
#define NOSHIELD 16 // Weapon not affected by shield.
#define CONDUCT 32 // Conducts electricity. (metal etc.)
#define ON_BORDER 64 // Item has priority to check when entering or leaving.
#define NOBLOODY 512 // Used for items if they don't want to get a blood overlay.
#define NODELAY 8192 // 1 second attack-by delay skipped (Can be used once every 0.2s). Most objects have a 1s attack-by delay, which doesn't require a flag.
#define NOBLUDGEON 0x1 // When an item has this it produces no "X has been hit by Y with Z" message with the default handler.
#define CONDUCT 0x2 // Conducts electricity. (metal etc.)
#define ON_BORDER 0x4 // Item has priority to check when entering or leaving.
#define NOBLOODY 0x8 // Used for items if they don't want to get a blood overlay.
#define OPENCONTAINER 0x10 // Is an open container for chemistry purposes.
#define PHORONGUARD 0x20 // Does not get contaminated by phoron.
#define NOREACT 0x40 // Reagents don't react inside this container.
#define PROXMOVE 0x80 // Does this object require proximity checking in Enter()?
//Use these flags to indicate if an item obscures the specified slots from view, whereas body_parts_covered seems to be used to indicate what body parts the item protects.
#define GLASSESCOVERSEYES 256
#define MASKCOVERSEYES 256 // Get rid of some of the other retardation in these flags.
#define HEADCOVERSEYES 256 // Feel free to reallocate these numbers for other purposes.
#define MASKCOVERSMOUTH 512 // On other items, these are just for mask/head.
#define HEADCOVERSMOUTH 512
#define THICKMATERIAL 256 // From /tg/station: prevents syringes, parapens and hyposprays if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body. (NOTE: flag shared with NOSLIP for shoes)
#define NOSLIP 256 // Prevents from slipping on wet floors, in space, etc.
#define OPENCONTAINER 1024 // Is an open container for chemistry purposes.
#define BLOCK_GAS_SMOKE_EFFECT 2048 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL)
#define ONESIZEFITSALL 2048
#define PHORONGUARD 4096 // Does not get contaminated by phoron.
#define NOREACT 4096 // Reagents don't react inside this container.
#define BLOCKHEADHAIR 4 // Temporarily removes the user's hair overlay. Leaves facial hair.
#define BLOCKHAIR 8192 // Temporarily removes the user's hair, facial and otherwise.
//Flags for items (equipment)
#define THICKMATERIAL 0x1 // Prevents syringes, parapens and hyposprays if equiped to slot_suit or slot_head.
#define STOPPRESSUREDAMAGE 0x2 // Counts towards pressure protection. Note that like temperature protection, body_parts_covered is considered here as well.
#define AIRTIGHT 0x4 // Functions with internals.
#define NOSLIP 0x8 // Prevents from slipping on wet floors, in space, etc.
#define BLOCK_GAS_SMOKE_EFFECT 0x10 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL)
#define FLEXIBLEMATERIAL 0x20 // At the moment, masks with this flag will not prevent eating even if they are covering your face.
// Flags for pass_flags.
#define PASSTABLE 1
#define PASSGLASS 2
#define PASSGRILLE 4
#define PASSBLOB 8
#define PASSTABLE 0x1
#define PASSGLASS 0x2
#define PASSGRILLE 0x4
#define PASSBLOB 0x8
// Bitmasks for the flags_inv variable. These determine when a piece of clothing hides another, i.e. a helmet hiding glasses.
// WARNING: The following flags apply only to the external suit!
#define HIDEGLOVES 1
#define HIDESUITSTORAGE 2
#define HIDEJUMPSUIT 4
#define HIDESHOES 8
#define HIDETAIL 16
#define HIDEGLOVES 0x1
#define HIDESUITSTORAGE 0x2
#define HIDEJUMPSUIT 0x4
#define HIDESHOES 0x8
#define HIDETAIL 0x10
// WARNING: The following flags apply only to the helmets and masks!
#define HIDEMASK 1
#define HIDEEARS 2 // Headsets and such.
#define HIDEEYES 4 // Glasses.
#define HIDEFACE 8 // Dictates whether we appear as "Unknown".
#define HIDEMASK 0x1
#define HIDEEARS 0x2 // Headsets and such.
#define HIDEEYES 0x4 // Glasses.
#define HIDEFACE 0x8 // Dictates whether we appear as "Unknown".
#define BLOCKHEADHAIR 0x20 // Hides the user's hair overlay. Leaves facial hair.
#define BLOCKHAIR 0x40 // Hides the user's hair, facial and otherwise.
// Slots.
#define slot_back 1
@@ -106,24 +98,24 @@
#define slot_wear_suit_str "slot_suit"
// Bitflags for clothing parts.
#define HEAD 1
#define FACE 2
#define EYES 4
#define UPPER_TORSO 8
#define LOWER_TORSO 16
#define LEG_LEFT 32
#define LEG_RIGHT 64
#define LEGS 96 // LEG_LEFT | LEG_RIGHT
#define FOOT_LEFT 128
#define FOOT_RIGHT 256
#define FEET 384 // FOOT_LEFT | FOOT_RIGHT
#define ARM_LEFT 512
#define ARM_RIGHT 1024
#define ARMS 1536 // ARM_LEFT | ARM_RIGHT
#define HAND_LEFT 2048
#define HAND_RIGHT 4096
#define HANDS 6144 // HAND_LEFT | HAND_RIGHT
#define FULL_BODY 8191
#define HEAD 0x1
#define FACE 0x2
#define EYES 0x4
#define UPPER_TORSO 0x8
#define LOWER_TORSO 0x10
#define LEG_LEFT 0x20
#define LEG_RIGHT 0x40
#define LEGS 0x60 // LEG_LEFT | LEG_RIGHT
#define FOOT_LEFT 0x80
#define FOOT_RIGHT 0x100
#define FEET 0x180 // FOOT_LEFT | FOOT_RIGHT
#define ARM_LEFT 0x200
#define ARM_RIGHT 0x400
#define ARMS 0x600 // ARM_LEFT | ARM_RIGHT
#define HAND_LEFT 0x800
#define HAND_RIGHT 0x1000
#define HANDS 0x1800 // HAND_LEFT | HAND_RIGHT
#define FULL_BODY 0xFFFF
// Bitflags for the percentual amount of protection a piece of clothing which covers the body part offers.
// Used with human/proc/get_heat_protection() and human/proc/get_cold_protection().
@@ -185,4 +177,4 @@
#define SUIT_SENSOR_OFF 0
#define SUIT_SENSOR_BINARY 1
#define SUIT_SENSOR_VITAL 2
#define SUIT_SENSOR_TRACKING 3
#define SUIT_SENSOR_TRACKING 3

View File

@@ -1,8 +1,7 @@
var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called manually after an event.
var/CELLRATE = 0.002 // Multiplier for watts per tick <> cell storage (e.g., 0.02 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
// It's a conversion constant. power_used*CELLRATE = charge_provided, or charge_used/CELLRATE = power_provided
var/CHARGELEVEL = 0.0005 // Cap for how fast cells charge, as a percentage-per-tick (0.01 means cellcharge is capped to 1% per second)
#define CELLRATE 0.002 // Multiplier for watts per tick <> cell storage (e.g., 0.02 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
// It's a conversion constant. power_used*CELLRATE = charge_provided, or charge_used/CELLRATE = power_provided
// Doors!
#define DOOR_CRUSH_DAMAGE 10
@@ -15,18 +14,15 @@ var/CHARGELEVEL = 0.0005 // Cap for how fast cells charge, as a percentage-per-t
#define TOTAL 4 // For total power used only.
// Bitflags for machine stat variable.
#define BROKEN 1
#define NOPOWER 2
#define POWEROFF 4 // TBD.
#define MAINT 8 // Under maintenance.
#define EMPED 16 // Temporary broken by EMP pulse.
#define BROKEN 0x1
#define NOPOWER 0x2
#define POWEROFF 0x4 // TBD.
#define MAINT 0x8 // Under maintenance.
#define EMPED 0x10 // Temporary broken by EMP pulse.
// Bitmasks for door switches.
#define OPEN 1
#define IDSCAN 2
#define BOLTS 4
#define SHOCK 8
#define SAFE 16
// Used by firelocks
#define FIREDOOR_OPEN 1
#define FIREDOOR_CLOSED 2
#define AI_CAMERA_LUMINOSITY 6
@@ -66,12 +62,12 @@ var/list/restricted_camera_networks = list("thunder","ERT","NUKE","Secret")
#define STAGE_SUPER 11
// computer3 error codes, move lower in the file when it passes dev -Sayu
#define PROG_CRASH 1 // Generic crash.
#define MISSING_PERIPHERAL 2 // Missing hardware.
#define BUSTED_ASS_COMPUTER 4 // Self-perpetuating error. BAC will continue to crash forever.
#define MISSING_PROGRAM 8 // Some files try to automatically launch a program. This is that failing.
#define FILE_DRM 16 // Some files want to not be copied/moved. This is them complaining that you tried.
#define NETWORK_FAILURE 32
#define PROG_CRASH 0x1 // Generic crash.
#define MISSING_PERIPHERAL 0x2 // Missing hardware.
#define BUSTED_ASS_COMPUTER 0x4 // Self-perpetuating error. BAC will continue to crash forever.
#define MISSING_PROGRAM 0x8 // Some files try to automatically launch a program. This is that failing.
#define FILE_DRM 0x10 // Some files want to not be copied/moved. This is them complaining that you tried.
#define NETWORK_FAILURE 0x20
// NanoUI flags
#define STATUS_INTERACTIVE 2 // GREEN Visability
@@ -100,4 +96,4 @@ var/list/restricted_camera_networks = list("thunder","ERT","NUKE","Secret")
#define ATMOS_DEFAULT_VOLUME_PUMP 200 // Liters.
#define ATMOS_DEFAULT_VOLUME_FILTER 200 // L.
#define ATMOS_DEFAULT_VOLUME_MIXER 200 // L.
#define ATMOS_DEFAULT_VOLUME_PIPE 70 // L.
#define ATMOS_DEFAULT_VOLUME_PIPE 70 // L.

View File

@@ -31,22 +31,22 @@
#define MAX_GEAR_COST 5 // Used in chargen for accessory loadout limit.
// Preference toggles.
#define SOUND_ADMINHELP 1
#define SOUND_MIDI 2
#define SOUND_AMBIENCE 4
#define SOUND_LOBBY 8
#define CHAT_OOC 16
#define CHAT_DEAD 32
#define CHAT_GHOSTEARS 64
#define CHAT_GHOSTSIGHT 128
#define CHAT_PRAYER 256
#define CHAT_RADIO 512
#define CHAT_ATTACKLOGS 1024
#define CHAT_DEBUGLOGS 2048
#define CHAT_LOOC 4096
#define CHAT_GHOSTRADIO 8192
#define SHOW_TYPING 16384
#define CHAT_NOICONS 32768
#define SOUND_ADMINHELP 0x1
#define SOUND_MIDI 0x2
#define SOUND_AMBIENCE 0x4
#define SOUND_LOBBY 0x8
#define CHAT_OOC 0x10
#define CHAT_DEAD 0x20
#define CHAT_GHOSTEARS 0x40
#define CHAT_GHOSTSIGHT 0x80
#define CHAT_PRAYER 0x100
#define CHAT_RADIO 0x200
#define CHAT_ATTACKLOGS 0x400
#define CHAT_DEBUGLOGS 0x800
#define CHAT_LOOC 0x1000
#define CHAT_GHOSTRADIO 0x2000
#define SHOW_TYPING 0x4000
#define CHAT_NOICONS 0x8000
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS|CHAT_LOOC)
@@ -63,15 +63,23 @@
#define LIFE_HUD 10 // STATUS_HUD that only reports dead or alive
//some colors
#define COLOR_RED "#FF0000"
#define COLOR_GREEN "#00FF00"
#define COLOR_BLUE "#0000FF"
#define COLOR_CYAN "#00FFFF"
#define COLOR_PINK "#FF00FF"
#define COLOR_YELLOW "#FFFF00"
#define COLOR_ORANGE "#FF9900"
#define COLOR_WHITE "#FFFFFF"
#define COLOR_SILVER "#C0C0C0"
#define COLOR_GRAY "#808080"
#define COLOR_BLACK "#000000"
#define COLOR_RED "#FF0000"
#define COLOR_MAROON "#800000"
#define COLOR_YELLOW "#FFFF00"
#define COLOR_OLIVE "#808000"
#define COLOR_LIME "#00FF00"
#define COLOR_GREEN "#008000"
#define COLOR_CYAN "#00FFFF"
#define COLOR_TEAL "#008080"
#define COLOR_BLUE "#0000FF"
#define COLOR_NAVY "#000080"
#define COLOR_PINK "#FF00FF"
#define COLOR_PURPLE "#800080"
#define COLOR_ORANGE "#FF9900"
// Shuttles.
@@ -117,6 +125,7 @@
#define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
#define DOOR_CLOSED_LAYER 3.1 //Above most items if closed
#define LIGHTING_LAYER 11
#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 OBFUSCATION_LAYER 21 //Where images covering the view for eyes are put
#define SCREEN_LAYER 22 //Mob HUD/effects layer
@@ -144,9 +153,9 @@
#define SHARD_SPLINTER "splinters"
#define SHARD_NONE ""
#define MATERIAL_UNMELTABLE 1
#define MATERIAL_BRITTLE 2
#define MATERIAL_PADDING 4
#define MATERIAL_UNMELTABLE 0x1
#define MATERIAL_BRITTLE 0x2
#define MATERIAL_PADDING 0x4
#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)

View File

@@ -4,16 +4,16 @@
#define DEAD 2
// Bitflags defining which status effects could be or are inflicted on a mob.
#define CANSTUN 1
#define CANWEAKEN 2
#define CANPARALYSE 4
#define CANPUSH 8
#define LEAPING 16
#define PASSEMOTES 32 // Mob has a cortical borer or holders inside of it that need to see emotes.
#define GODMODE 4096
#define FAKEDEATH 8192 // Replaces stuff like changeling.changeling_fakedeath.
#define DISFIGURED 16384 // I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system.
#define XENO_HOST 32768 // Tracks whether we're gonna be a baby alien's mummy.
#define CANSTUN 0x1
#define CANWEAKEN 0x2
#define CANPARALYSE 0x4
#define CANPUSH 0x8
#define LEAPING 0x10
#define PASSEMOTES 0x32 // Mob has a cortical borer or holders inside of it that need to see emotes.
#define GODMODE 0x1000
#define FAKEDEATH 0x2000 // Replaces stuff like changeling.changeling_fakedeath.
#define DISFIGURED 0x4000 // Set but never checked. Remove this sometime and replace occurences with the appropriate organ code
#define XENO_HOST 0x8000 // Tracks whether we're gonna be a baby alien's mummy.
// Grab levels.
#define GRAB_PASSIVE 1
@@ -22,9 +22,9 @@
#define GRAB_UPGRADING 4
#define GRAB_KILL 5
#define BORGMESON 1
#define BORGTHERM 2
#define BORGXRAY 4
#define BORGMESON 0x1
#define BORGTHERM 0x2
#define BORGXRAY 0x4
#define HOSTILE_STANCE_IDLE 1
#define HOSTILE_STANCE_ALERT 2
@@ -49,7 +49,7 @@
#define I_HELP "help"
#define I_DISARM "disarm"
#define I_GRAB "grab"
#define I_HURT "hurt"
#define I_HURT "harm"
//These are used Bump() code for living mobs, in the mob_bump_flag, mob_swap_flags, and mob_push_flags vars to determine whom can bump/swap with whom.
#define HUMAN 1
@@ -58,9 +58,8 @@
#define ROBOT 8
#define SLIME 16
#define SIMPLE_ANIMAL 32
#define ALLMOBS (HUMAN|MONKEY|ALIEN|ROBOT|SLIME|SIMPLE_ANIMAL)
#define NEXT_MOVE_DELAY 8
#define HEAVY 64
#define ALLMOBS (HUMAN|MONKEY|ALIEN|ROBOT|SLIME|SIMPLE_ANIMAL|HEAVY)
// Robot AI notifications
#define ROBOT_NOTIFICATION_NEW_UNIT 1
@@ -69,17 +68,20 @@
#define ROBOT_NOTIFICATION_MODULE_RESET 4
// Appearance change flags
#define APPEARANCE_UPDATE_DNA 1
#define APPEARANCE_RACE (2|APPEARANCE_UPDATE_DNA)
#define APPEARANCE_GENDER (4|APPEARANCE_UPDATE_DNA)
#define APPEARANCE_SKIN 8
#define APPEARANCE_HAIR 16
#define APPEARANCE_HAIR_COLOR 32
#define APPEARANCE_FACIAL_HAIR 64
#define APPEARANCE_FACIAL_HAIR_COLOR 128
#define APPEARANCE_EYE_COLOR 256
#define APPEARANCE_UPDATE_DNA 0x1
#define APPEARANCE_RACE (0x2|APPEARANCE_UPDATE_DNA)
#define APPEARANCE_GENDER (0x4|APPEARANCE_UPDATE_DNA)
#define APPEARANCE_SKIN 0x8
#define APPEARANCE_HAIR 0x10
#define APPEARANCE_HAIR_COLOR 0x20
#define APPEARANCE_FACIAL_HAIR 0x40
#define APPEARANCE_FACIAL_HAIR_COLOR 0x80
#define APPEARANCE_EYE_COLOR 0x100
#define APPEARANCE_ALL_HAIR (APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR)
#define APPEARANCE_ALL 511
#define APPEARANCE_ALL 0xFFFF
// Click cooldown
#define DEFAULT_ATTACK_COOLDOWN 8 //Default timeout for aggressive actions
#define MIN_SUPPLIED_LAW_NUMBER 15
@@ -94,3 +96,14 @@
#define INV_ACCESSORIES_DEF_ICON 'icons/mob/ties.dmi'
#define INV_SUIT_DEF_ICON 'icons/mob/ties.dmi'
#define INV_SUIT_DEF_ICON 'icons/mob/suit.dmi'
#define MAX_SUPPLIED_LAW_NUMBER 50
// NT's alignment towards the character
#define COMPANY_LOYAL "Loyal"
#define COMPANY_SUPPORTATIVE "Supportive"
#define COMPANY_NEUTRAL "Neutral"
#define COMPANY_SKEPTICAL "Skeptical"
#define COMPANY_OPPOSED "Opposed"
#define COMPANY_ALIGNMENTS list(COMPANY_LOYAL,COMPANY_SUPPORTATIVE,COMPANY_NEUTRAL,COMPANY_SKEPTICAL,COMPANY_OPPOSED)

View File

@@ -1,7 +1,7 @@
#define SHEET_MATERIAL_AMOUNT 2000
#define TECH_MATERIAL "materials"
#define TECH_ENGINERING "engineering"
#define TECH_ENGINEERING "engineering"
#define TECH_PHORON "phorontech"
#define TECH_POWER "powerstorage"
#define TECH_BLUESPACE "bluespace"
@@ -12,7 +12,7 @@
#define TECH_ILLEGAL "syndicate"
#define TECH_ARCANE "arcane"
#define IMPRINTER 1 //For circuits. Uses glass/chemicals.
#define PROTOLATHE 2 //New stuff. Uses glass/metal/chemicals
#define MECHFAB 4 //Remember, objects utilising this flag should have construction_time and construction_cost vars.
#define CHASSIS 8 //For protolathe, but differently
#define IMPRINTER 0x1 //For circuits. Uses glass/chemicals.
#define PROTOLATHE 0x2 //New stuff. Uses glass/metal/chemicals
#define MECHFAB 0x4 //Remember, objects utilising this flag should have construction_time and construction_cost vars.
#define CHASSIS 0x8 //For protolathe, but differently

View File

@@ -1,31 +1,27 @@
// Species flags.
#define NO_BLOOD 1 // Vessel var is not filled with blood, cannot bleed out.
#define NO_BREATHE 2 // Cannot suffocate or take oxygen loss.
#define NO_SCAN 4 // Cannot be scanned in a DNA machine/genome-stolen.
#define NO_PAIN 8 // Cannot suffer halloss/recieves deceptive health indicator.
#define NO_SLIP 16 // Cannot fall over.
#define NO_POISON 32 // Cannot not suffer toxloss.
#define HAS_SKIN_TONE 64 // Skin tone selectable in chargen. (0-255)
#define HAS_SKIN_COLOR 128 // Skin colour selectable in chargen. (RGB)
#define HAS_LIPS 256 // Lips are drawn onto the mob icon. (lipstick)
#define HAS_UNDERWEAR 512 // Underwear is drawn onto the mob icon.
#define IS_PLANT 1024 // Is a treeperson.
#define IS_WHITELISTED 2048 // Must be whitelisted to play.
#define HAS_EYE_COLOR 4096 // Eye colour selectable in chargen. (RGB)
#define CAN_JOIN 8192 // Species is selectable in chargen.
#define IS_RESTRICTED 16384 // Is not a core/normally playable species. (castes, mutantraces)
// unused: 32768 - higher than this will overflow
#define NO_BLOOD 0x1 // Vessel var is not filled with blood, cannot bleed out.
#define NO_BREATHE 0x2 // Cannot suffocate or take oxygen loss.
#define NO_SCAN 0x4 // Cannot be scanned in a DNA machine/genome-stolen.
#define NO_PAIN 0x8 // Cannot suffer halloss/recieves deceptive health indicator.
#define NO_SLIP 0x10 // Cannot fall over.
#define NO_POISON 0x20 // Cannot not suffer toxloss.
#define IS_PLANT 0x40 // Is a treeperson.
#define NO_MINOR_CUT 0x80 // Can step on broken glass with no ill-effects. Either thick skin (diona/vox), cut resistant (slimes) or incorporeal (shadows)
// unused: 0x8000 - higher than this will overflow
// Species spawn flags
#define IS_WHITELISTED 0x1 // Must be whitelisted to play.
#define CAN_JOIN 0x2 // Species is selectable in chargen.
#define IS_RESTRICTED 0x4 // Is not a core/normally playable species. (castes, mutantraces)
// Species appearance flags
#define HAS_SKIN_TONE 0x1 // Skin tone selectable in chargen. (0-255)
#define HAS_SKIN_COLOR 0x2 // Skin colour selectable in chargen. (RGB)
#define HAS_LIPS 0x4 // Lips are drawn onto the mob icon. (lipstick)
#define HAS_UNDERWEAR 0x8 // Underwear is drawn onto the mob icon.
#define HAS_EYE_COLOR 0x10 // Eye colour selectable in chargen. (RGB)
// Languages.
#define LANGUAGE_HUMAN 1
#define LANGUAGE_ALIEN 2
#define LANGUAGE_DOG 4
#define LANGUAGE_CAT 8
#define LANGUAGE_BINARY 16
#define LANGUAGE_OTHER 32768
#define LANGUAGE_UNIVERSAL 65535
#define LANGUAGE_SOL_COMMON "Sol Common"
#define LANGUAGE_UNATHI "Sinta'unathi"
#define LANGUAGE_SIIK_MAAS "Siik'maas"
@@ -36,13 +32,14 @@
#define LANGUAGE_GUTTER "Gutter"
// Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
#define RESTRICTED 2 // Language can only be accquired by spawning or an admin.
#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight.
#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand.
#define HIVEMIND 16 // Broadcast to all mobs with this language.
#define NONGLOBAL 32 // Do not add to general languages list.
#define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes)
#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message
#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
#define RESTRICTED 2 // Language can only be acquired by spawning or an admin.
#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight.
#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand.
#define HIVEMIND 16 // Broadcast to all mobs with this language.
#define NONGLOBAL 32 // Do not add to general languages list.
#define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes)
#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message
#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems
#define COMMON_VERBS 512 // Robots will apply regular verbs to this

10
code/__defines/turfs.dm Normal file
View File

@@ -0,0 +1,10 @@
#define TURF_REMOVE_CROWBAR 1
#define TURF_REMOVE_SCREWDRIVER 2
#define TURF_REMOVE_SHOVEL 4
#define TURF_REMOVE_WRENCH 8
#define TURF_CAN_BREAK 16
#define TURF_CAN_BURN 32
#define TURF_HAS_EDGES 64
#define TURF_HAS_CORNERS 128
#define TURF_IS_FRAGILE 256
#define TURF_ACID_IMMUNE 512

View File

@@ -0,0 +1,47 @@
/obj/proc/analyze_gases(var/obj/A, var/mob/user)
if(src != A)
user.visible_message("<span class='notice'>\The [user] has used \an [src] on \the [A]</span>")
A.add_fingerprint(user)
var/list/result = A.atmosanalyze(user)
if(result && result.len)
user << "<span class='notice'>Results of the analysis[src == A ? "" : " of \the [A]"]</span>"
for(var/line in result)
user << "<span class='notice'>[line]</span>"
return 1
user << "<span class='warning'>Your [src] flashes a red light as it fails to analyze \the [A].</span>"
return 0
/proc/atmosanalyzer_scan(var/obj/target, var/datum/gas_mixture/mixture, var/mob/user)
var/pressure = mixture.return_pressure()
var/total_moles = mixture.total_moles
var/list/results = list()
if (total_moles>0)
results += "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>"
for(var/mix in mixture.gas)
results += "<span class='notice'>[gas_data.name[mix]]: [round((mixture.gas[mix] / total_moles) * 100)]%</span>"
results += "<span class='notice'>Temperature: [round(mixture.temperature-T0C)]&deg;C</span>"
else
results += "<span class='notice'>\The [target] is empty!</span>"
return results
/obj/proc/atmosanalyze(var/mob/user)
return
/obj/item/weapon/tank/atmosanalyze(var/mob/user)
return atmosanalyzer_scan(src, src.air_contents, user)
/obj/machinery/portable_atmospherics/atmosanalyze(var/mob/user)
return atmosanalyzer_scan(src, src.air_contents, user)
/obj/machinery/atmospherics/pipe/atmosanalyze(var/mob/user)
return atmosanalyzer_scan(src, src.parent.air, user)
/obj/machinery/power/rad_collector/atmosanalyze(var/mob/user)
if(P) return atmosanalyzer_scan(src, src.P.air_contents, user)
/obj/item/weapon/flamethrower/atmosanalyze(var/mob/user)
if(ptank) return atmosanalyzer_scan(src, ptank.air_contents, user)

View File

@@ -130,9 +130,9 @@ var/global/list/endgame_safespawns = list()
S.race_key = rkey //Used in mob icon caching.
all_species[S.name] = S
if(!(S.flags & IS_RESTRICTED))
if(!(S.spawn_flags & IS_RESTRICTED))
playable_species += S.name
if(S.flags & IS_WHITELISTED)
if(S.spawn_flags & IS_WHITELISTED)
whitelisted_species += S.name
//Posters

View File

@@ -635,7 +635,7 @@ The _flatIcons list is a cache for generated icon files.
*/
proc // Creates a single icon from a given /atom or /image. Only the first argument is required.
getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT)
getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0)
// We start with a blank canvas, otherwise some icon procs crash silently
var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon
if(!A)
@@ -666,7 +666,7 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu
noIcon = TRUE // Do not render this object.
var/curdir
if(A.dir != 2)
if(A.dir != 2 && !always_use_defdir)
curdir = A.dir
else
curdir = defdir

View File

@@ -599,7 +599,7 @@ proc/dd_sortedTextList(list/incoming)
return dd_sortedtextlist(incoming, case_sensitive)
datum/proc/dd_SortValue()
/datum/proc/dd_SortValue()
return "[src]"
/obj/machinery/dd_SortValue()
@@ -611,10 +611,13 @@ datum/proc/dd_SortValue()
/datum/alarm/dd_SortValue()
return "[sanitize_old(last_name)]"
/proc/subtypes(prototype)
return (typesof(prototype) - prototype)
//creates every subtype of prototype (excluding prototype) and adds it to list L.
//if no list/L is provided, one is created.
/proc/init_subtypes(prototype, list/L)
if(!istype(L)) L = list()
for(var/path in (typesof(prototype) - prototype))
for(var/path in subtypes(prototype))
L += new path()
return L

View File

@@ -109,6 +109,12 @@
M = whom
C = M.client
key = M.key
else if(istype(whom, /datum/mind))
var/datum/mind/D = whom
key = D.key
M = D.current
if(D.current)
C = D.current.client
else if(istype(whom, /datum))
var/datum/D = whom
return "*invalid:[D.type]*"

View File

@@ -20,7 +20,7 @@ var/command_name = null
if (command_name)
return command_name
var/name = "Central Command"
var/name = "[boss_name]"
command_name = name
return name

View File

@@ -55,7 +55,7 @@
//If you have a problem with sanitize() in chat, when quotes and >, < are displayed as html entites -
//this is a problem of double-encode(when & becomes &amp;), use sanitize() with encode=0, but not the sanitizeSafe()!
/proc/sanitizeSafe(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1)
return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'"), max_length, encode, trim, extra))
return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'")), max_length, encode, trim, extra)
//Filters out undesirable characters from names
/proc/sanitizeName(var/input, var/max_length = MAX_NAME_LEN, var/allow_numbers = 0)
@@ -116,7 +116,7 @@
if(last_char_group == 1)
output = copytext(output,1,length(output)) //removes the last character (in this case a space)
for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai")) //prevents these common metagamey names
for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai","plating")) //prevents these common metagamey names
if(cmptext(output,bad_name)) return //(not case sensitive)
return output

View File

@@ -6,13 +6,13 @@
var/roundstart_hour = 0
//Returns the world time in english
proc/worldtime2text(time = world.time)
proc/worldtime2text(time = world.time, timeshift = 1)
if(!roundstart_hour) roundstart_hour = pick(2,7,12,17)
return "[(round(time / 36000)+roundstart_hour) % 24]:[(time / 600 % 60) < 10 ? add_zero(time / 600 % 60, 1) : time / 600 % 60]"
return timeshift ? time2text(time+(36000*roundstart_hour), "hh:mm") : time2text(time, "hh:mm")
proc/worlddate2text()
return num2text((text2num(time2text(world.timeofday, "YYYY"))+544)) + "-" + time2text(world.timeofday, "MM-DD")
proc/time_stamp()
return time2text(world.timeofday, "hh:mm:ss")
@@ -27,3 +27,18 @@ proc/isDay(var/month, var/day)
// Uncomment this out when debugging!
//else
//return 1
var/next_duration_update = 0
var/last_round_duration = 0
proc/round_duration()
if(last_round_duration && world.time < next_duration_update)
return last_round_duration
var/mills = world.time // 1/10 of a second, not real milliseconds but whatever
//var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something
var/mins = (mills % 36000) / 600
var/hours = mills / 36000
last_round_duration = "[round(hours)]h [round(mins)]m"
next_duration_update = world.time + 1 MINUTES
return last_round_duration

View File

@@ -38,7 +38,7 @@
// Returns the hex value of a number given a value assumed to be a base-ten value
/proc/num2hex(num, padlength)
var/global/list/hexdigits = list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
. = ""
while(num > 0)
var/hexdigit = hexdigits[(num & 0xF) + 1]
@@ -46,7 +46,7 @@
num >>= 4 //go to the next half-byte
//pad with zeroes
var/left = padlength - length(.)
var/left = padlength - length(.)
while (left-- > 0)
. = "0[.]"
@@ -275,13 +275,6 @@ proc/tg_list2text(list/list, glue=",")
if (rights & R_MENTOR) . += "[seperator]+MENTOR"
return .
/proc/ui_style2icon(ui_style)
switch (ui_style)
if ("old") return 'icons/mob/screen1_old.dmi'
if ("Orange") return 'icons/mob/screen1_Orange.dmi'
if ("Midnight") return 'icons/mob/screen1_Midnight.dmi'
else return 'icons/mob/screen1_White.dmi'
// heat2color functions. Adapted from: http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
/proc/heat2color(temp)
return rgb(heat2color_r(temp), heat2color_g(temp), heat2color_b(temp))

View File

@@ -4,6 +4,9 @@
* A large number of misc global procs.
*/
//Checks if all high bits in req_mask are set in bitfield
#define BIT_TEST_ALL(bitfield, req_mask) ((~(bitfield) & (req_mask)) == 0)
//Inverts the colour of an HTML string
/proc/invertHTML(HTMLstring)
@@ -562,10 +565,13 @@ proc/GaussRandRound(var/sigma,var/roundto)
return toReturn
//Step-towards method of determining whether one atom can see another. Similar to viewers()
/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldn't be arsed to do actual raycasting :I This is horribly inaccurate.
var/turf/current = get_turf(source)
var/turf/target_turf = get_turf(target)
var/steps = 0
if(!current || !target_turf)
return 0
while(current != target_turf)
if(steps > length) return 0
@@ -774,11 +780,15 @@ proc/GaussRandRound(var/sigma,var/roundto)
var/old_dir1 = T.dir
var/old_icon_state1 = T.icon_state
var/old_icon1 = T.icon
var/old_overlays = T.overlays.Copy()
var/old_underlays = T.underlays.Copy()
var/turf/X = B.ChangeTurf(T.type)
X.set_dir(old_dir1)
X.icon_state = old_icon_state1
X.icon = old_icon1 //Shuttle floors are in shuttle.dmi while the defaults are floors.dmi
X.overlays = old_overlays
X.underlays = old_underlays
var/turf/simulated/ST = T
if(istype(ST) && ST.zone)
@@ -824,7 +834,7 @@ proc/GaussRandRound(var/sigma,var/roundto)
if(!istype(O,/obj)) continue
O.loc = X
for(var/mob/M in T)
if(!istype(M,/mob) || istype(M, /mob/aiEye)) continue // If we need to check for more mobs, I'll add a variable
if(!istype(M,/mob) || istype(M, /mob/eye)) continue // If we need to check for more mobs, I'll add a variable
M.loc = X
// var/area/AR = X.loc
@@ -921,6 +931,8 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
var/old_dir1 = T.dir
var/old_icon_state1 = T.icon_state
var/old_icon1 = T.icon
var/old_overlays = T.overlays.Copy()
var/old_underlays = T.underlays.Copy()
if(platingRequired)
if(istype(B, get_base_turf(B.z)))
@@ -931,7 +943,8 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
X.set_dir(old_dir1)
X.icon_state = old_icon_state1
X.icon = old_icon1 //Shuttle floors are in shuttle.dmi while the defaults are floors.dmi
X.overlays = old_overlays
X.underlays = old_underlays
var/list/objs = new/list()
var/list/newobjs = new/list()
@@ -955,7 +968,7 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
for(var/mob/M in T)
if(!istype(M,/mob) || istype(M, /mob/aiEye)) continue // If we need to check for more mobs, I'll add a variable
if(!istype(M,/mob) || istype(M, /mob/eye)) continue // If we need to check for more mobs, I'll add a variable
mobs += M
for(var/mob/M in mobs)

View File

@@ -15,7 +15,6 @@
return
if(control_disabled || stat) return
next_move = world.time + 9
if(ismob(A))
ai_actual_track(A)
@@ -52,9 +51,8 @@
CtrlClickOn(A)
return
if(world.time <= next_move)
if(!canClick())
return
next_move = world.time + 9
if(aiCamera.in_camera_mode)
aiCamera.camera_mode_off()

View File

@@ -4,7 +4,7 @@
*/
// 1 decisecond click delay (above and beyond mob/next_move)
/mob/var/next_click = 0
/mob/var/next_click = 0
/*
Before anything else, defer these calls to a per-mobtype handler. This allows us to
@@ -15,12 +15,14 @@
Note that this proc can be overridden, and is in the case of screen objects.
*/
/atom/Click(location,control,params)
/atom/Click(var/location, var/control, var/params) // This is their reaction to being clicked on (standard proc)
if(src)
usr.ClickOn(src, params)
/atom/DblClick(location,control,params)
/atom/DblClick(var/location, var/control, var/params)
if(src)
usr.DblClickOn(src,params)
usr.DblClickOn(src, params)
/*
Standard mob ClickOn()
@@ -35,8 +37,8 @@
* item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent
* mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed
*/
/mob/proc/ClickOn( var/atom/A, var/params )
if(world.time <= next_click)
/mob/proc/ClickOn(var/atom/A, var/params)
if(world.time <= next_click) // Hard check, before anything else, to avoid crashing
return
next_click = world.time + 1
@@ -66,16 +68,17 @@
face_atom(A) // change direction to face what you clicked on
if(next_move > world.time) // in the year 2000...
if(!canClick()) // in the year 2000...
return
if(istype(loc,/obj/mecha))
if(!locate(/turf) in list(A,A.loc)) // Prevents inventory from being drilled
if(istype(loc, /obj/mecha))
if(!locate(/turf) in list(A, A.loc)) // Prevents inventory from being drilled
return
var/obj/mecha/M = loc
return M.click_action(A,src)
return M.click_action(A, src)
if(restrained())
setClickCooldown(10)
RestrainedClickOn(A)
return
@@ -85,79 +88,76 @@
return
throw_mode_off()
if(!istype(A,/obj/item/weapon/gun) && !isturf(A) && !istype(A,/obj/screen))
if(!istype(A, /obj/item/weapon/gun) && !isturf(A) && !istype(A, /obj/screen))
last_target_click = world.time
var/obj/item/W = get_active_hand()
if(W == A)
next_move = world.time + 6
if(W.flags&USEDELAY)
next_move += 5
if(W == A) // Handle attack_self
W.attack_self(src)
if(hand)
update_inv_l_hand(0)
else
update_inv_r_hand(0)
return
// operate two STORAGE levels deep here (item in backpack in src; NOT item in box in backpack in src)
//Atoms on your person
// A is your location but is not a turf; or is on you (backpack); or is on something on you (box in backpack); sdepth is needed here because contents depth does not equate inventory storage depth.
var/sdepth = A.storage_depth(src)
if(A == loc || (A in loc) || (sdepth != -1 && sdepth <= 1))
if((!isturf(A) && A == loc) || (sdepth != -1 && sdepth <= 1))
// faster access to objects already on you
if(A in contents)
next_move = world.time + 6 // on your person
else
next_move = world.time + 8 // in a box/bag or in your square
// No adjacency needed
if(A.loc != src)
setMoveCooldown(10) //getting something out of a backpack
if(W)
if(W.flags&USEDELAY)
next_move += 5
var/resolved = W.resolve_attackby(A, src)
if(!resolved && A && W)
W.afterattack(A,src,1,params) // 1 indicates adjacency
W.afterattack(A, src, 1, params) // 1 indicates adjacency
else
if(ismob(A)) // No instant mob attacking
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
UnarmedAttack(A, 1)
return
if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that
return
// Allows you to click on a box's contents, if that box is on the ground, but no deeper than that
//Atoms on turfs (not on your person)
// A is a turf or is on a turf, or in something on a turf (pen in a box); but not something in something on a turf (pen in a box in a backpack)
sdepth = A.storage_depth_turf()
if(isturf(A) || isturf(A.loc) || (sdepth != -1 && sdepth <= 1))
next_move = world.time + 10
if(A.Adjacent(src)) // see adjacent.dm
setMoveCooldown(5)
if(W)
if(W.flags&USEDELAY)
next_move += 5
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
var/resolved = W.resolve_attackby(A,src)
if(!resolved && A && W)
W.afterattack(A,src,1,params) // 1: clicking something Adjacent
W.afterattack(A, src, 1, params) // 1: clicking something Adjacent
else
if(ismob(A)) // No instant mob attacking
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
UnarmedAttack(A, 1)
return
else // non-adjacent click
if(W)
W.afterattack(A,src,0,params) // 0: not Adjacent
W.afterattack(A, src, 0, params) // 0: not Adjacent
else
RangedAttack(A, params)
return
/mob/proc/changeNext_move(num)
next_move = world.time + num
/mob/proc/setClickCooldown(var/timeout)
next_move = max(world.time + timeout, next_move)
// Default behavior: ignore double clicks, consider them normal clicks instead
/mob/proc/canClick()
if(config.no_click_cooldown || next_move <= world.time)
return 1
return 0
// Default behavior: ignore double clicks, the second click that makes the doubleclick call already calls for a normal click
/mob/proc/DblClickOn(var/atom/A, var/params)
ClickOn(A,params)
return
/*
Translates into attack_hand, etc.
@@ -201,14 +201,12 @@
LaserEyes(A) // moved into a proc below
else if(TK in mutations)
switch(get_dist(src,A))
if(0)
;
if(1 to 5) // not adjacent may mean blocked by window
next_move += 2
setMoveCooldown(2)
if(5 to 7)
next_move += 5
setMoveCooldown(5)
if(8 to tk_maxrange)
next_move += 10
setMoveCooldown(10)
else
return
A.attack_tk(src)
@@ -231,7 +229,6 @@
/mob/living/carbon/MiddleClickOn(var/atom/A)
swap_hand()
// In case of use break glass
/*
/atom/proc/MiddleClick(var/mob/M as mob)
@@ -307,7 +304,7 @@
return
/mob/living/LaserEyes(atom/A)
next_move = world.time + 6
setClickCooldown(4)
var/turf/T = get_turf(src)
var/turf/U = get_turf(A)

View File

@@ -35,7 +35,7 @@
if(stat || lockcharge || weakened || stunned || paralysis)
return
if(next_move >= world.time)
if(!canClick())
return
face_atom(A) // change direction to face what you clicked on
@@ -68,9 +68,6 @@
return
if(W == A)
next_move = world.time + 8
if(W.flags&USEDELAY)
next_move += 5
W.attack_self(src)
return
@@ -78,9 +75,6 @@
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents)
if(A == loc || (A in loc) || (A in contents))
// No adjacency checks
next_move = world.time + 8
if(W.flags&USEDELAY)
next_move += 5
var/resolved = A.attackby(W,src)
if(!resolved && A && W)
@@ -93,16 +87,12 @@
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc))
if(isturf(A) || isturf(A.loc))
if(A.Adjacent(src)) // see adjacent.dm
next_move = world.time + 10
if(W.flags&USEDELAY)
next_move += 5
var/resolved = A.attackby(W, src)
if(!resolved && A && W)
W.afterattack(A, src, 1, params)
return
else
next_move = world.time + 10
W.afterattack(A, src, 0, params)
return
return

View File

@@ -141,6 +141,25 @@ datum/hud/New(mob/owner)
instantiate()
..()
/datum/hud/Destroy()
..()
grab_intent = null
hurt_intent = null
disarm_intent = null
help_intent = null
lingchemdisplay = null
blobpwrdisplay = null
blobhealthdisplay = null
r_hand_hud_object = null
l_hand_hud_object = null
action_intent = null
move_intent = null
adding = null
other = null
hotkeybuttons = null
// item_action_list = null // ?
mymob = null
/datum/hud/proc/hidden_inventory_update()
if(!mymob) return
if(ishuman(mymob))
@@ -237,7 +256,7 @@ datum/hud/New(mob/owner)
if(ishuman(mymob))
human_hud(ui_style, ui_color, ui_alpha, mymob) // Pass the player the UI style chosen in preferences
else if(issmall(mymob))
monkey_hud(ui_style)
monkey_hud(ui_style, ui_color, ui_alpha)
else if(isbrain(mymob))
brain_hud(ui_style)
else if(isalien(mymob))

View File

@@ -58,7 +58,6 @@
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_acti
@@ -125,7 +124,6 @@
if(hud_data.has_m_intent)
using = new /obj/screen()
using.name = "mov_intent"
using.set_dir(SOUTHWEST)
using.icon = ui_style
using.icon_state = (mymob.m_intent == "run" ? "running" : "walking")
using.screen_loc = ui_movi
@@ -160,11 +158,10 @@
inv_box = new /obj/screen/inventory()
inv_box.name = "r_hand"
inv_box.set_dir(WEST)
inv_box.icon = ui_style
inv_box.icon_state = "hand_inactive"
inv_box.icon_state = "r_hand_inactive"
if(mymob && !mymob.hand) //This being 0 or null means the right hand is in use
inv_box.icon_state = "hand_active"
inv_box.icon_state = "r_hand_active"
inv_box.screen_loc = ui_rhand
inv_box.slot_id = slot_r_hand
inv_box.layer = 19
@@ -176,11 +173,10 @@
inv_box = new /obj/screen/inventory()
inv_box.name = "l_hand"
inv_box.set_dir(EAST)
inv_box.icon = ui_style
inv_box.icon_state = "hand_inactive"
inv_box.icon_state = "l_hand_inactive"
if(mymob && mymob.hand) //This being 1 means the left hand is in use
inv_box.icon_state = "hand_active"
inv_box.icon_state = "l_hand_active"
inv_box.screen_loc = ui_lhand
inv_box.slot_id = slot_l_hand
inv_box.layer = 19
@@ -191,7 +187,6 @@
using = new /obj/screen/inventory()
using.name = "hand"
using.set_dir(SOUTH)
using.icon = ui_style
using.icon_state = "hand1"
using.screen_loc = ui_swaphand1
@@ -202,7 +197,6 @@
using = new /obj/screen/inventory()
using.name = "hand"
using.set_dir(SOUTH)
using.icon = ui_style
using.icon_state = "hand2"
using.screen_loc = ui_swaphand2
@@ -340,29 +334,31 @@
//Handle the gun settings buttons
mymob.gun_setting_icon = new /obj/screen/gun/mode(null)
//mymob.gun_setting_icon.color = ui_color
mymob.gun_setting_icon.icon = ui_style
mymob.gun_setting_icon.color = ui_color
mymob.gun_setting_icon.alpha = ui_alpha
hud_elements |= mymob.gun_setting_icon
mymob.item_use_icon = new /obj/screen/gun/item(null)
//mymob.item_use_icon.color = ui_color
mymob.item_use_icon.icon = ui_style
mymob.item_use_icon.color = ui_color
mymob.item_use_icon.alpha = ui_alpha
mymob.gun_move_icon = new /obj/screen/gun/move(null)
//mymob.gun_move_icon.color = ui_color
mymob.gun_move_icon.icon = ui_style
mymob.gun_move_icon.color = ui_color
mymob.gun_move_icon.alpha = ui_alpha
mymob.gun_run_icon = new /obj/screen/gun/run(null)
//mymob.gun_run_icon.color = ui_color
mymob.gun_run_icon.icon = ui_style
mymob.gun_run_icon.color = ui_color
mymob.gun_run_icon.alpha = ui_alpha
mymob.radio_use_icon = new /obj/screen/gun/radio(null)
mymob.radio_use_icon.icon = ui_style
mymob.radio_use_icon.color = ui_color
mymob.radio_use_icon.alpha = ui_alpha
if (mymob.client)
if (mymob.client.gun_mode) // If in aim mode, correct the sprite
mymob.gun_setting_icon.set_dir(2)
mymob.client.screen = null

View File

@@ -1,4 +1,4 @@
/datum/hud/proc/monkey_hud(var/ui_style='icons/mob/screen1_old.dmi')
/datum/hud/proc/monkey_hud(var/ui_style='icons/mob/screen1_old.dmi', var/ui_color = "#ffffff", var/ui_alpha = 255)
src.adding = list()
src.other = list()
@@ -8,9 +8,10 @@
using = new /obj/screen()
using.name = "act_intent"
using.set_dir(SOUTHWEST)
using.icon = ui_style
using.icon_state = (mymob.a_intent == I_HURT ? I_HURT : mymob.a_intent)
using.color = ui_color
using.alpha = ui_alpha
using.icon_state = mymob.a_intent
using.screen_loc = ui_acti
using.layer = 20
src.adding += using
@@ -23,7 +24,7 @@
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.name = I_HELP
using.icon = ico
using.screen_loc = ui_acti
using.layer = 21
@@ -34,7 +35,7 @@
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.name = I_DISARM
using.icon = ico
using.screen_loc = ui_acti
using.layer = 21
@@ -45,7 +46,7 @@
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.name = I_GRAB
using.icon = ico
using.screen_loc = ui_acti
using.layer = 21
@@ -56,7 +57,7 @@
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 = "harm"
using.name = I_HURT
using.icon = ico
using.screen_loc = ui_acti
using.layer = 21
@@ -67,8 +68,9 @@
using = new /obj/screen()
using.name = "mov_intent"
using.set_dir(SOUTHWEST)
using.icon = ui_style
using.color = ui_color
using.alpha = ui_alpha
using.icon_state = (mymob.m_intent == "run" ? "running" : "walking")
using.screen_loc = ui_movi
using.layer = 20
@@ -78,6 +80,8 @@
using = new /obj/screen()
using.name = "drop"
using.icon = ui_style
using.color = ui_color
using.alpha = ui_alpha
using.icon_state = "act_drop"
using.screen_loc = ui_drop_throw
using.layer = 19
@@ -85,9 +89,10 @@
inv_box = new /obj/screen/inventory()
inv_box.name = "r_hand"
inv_box.set_dir(WEST)
inv_box.icon = ui_style
inv_box.icon_state = "hand_inactive"
using.color = ui_color
using.alpha = ui_alpha
inv_box.icon_state = "r_hand_inactive"
if(mymob && !mymob.hand) //This being 0 or null means the right hand is in use
inv_box.icon_state = "hand_active"
inv_box.screen_loc = ui_rhand
@@ -98,9 +103,10 @@
inv_box = new /obj/screen/inventory()
inv_box.name = "l_hand"
inv_box.set_dir(EAST)
inv_box.icon = ui_style
inv_box.icon_state = "hand_inactive"
using.color = ui_color
using.alpha = ui_alpha
inv_box.icon_state = "l_hand_inactive"
if(mymob && mymob.hand) //This being 1 means the left hand is in use
inv_box.icon_state = "hand_active"
inv_box.screen_loc = ui_lhand
@@ -111,8 +117,9 @@
using = new /obj/screen/inventory()
using.name = "hand"
using.set_dir(SOUTH)
using.icon = ui_style
using.color = ui_color
using.alpha = ui_alpha
using.icon_state = "hand1"
using.screen_loc = ui_swaphand1
using.layer = 19
@@ -120,8 +127,9 @@
using = new /obj/screen/inventory()
using.name = "hand"
using.set_dir(SOUTH)
using.icon = ui_style
using.color = ui_color
using.alpha = ui_alpha
using.icon_state = "hand2"
using.screen_loc = ui_swaphand2
using.layer = 19
@@ -129,8 +137,9 @@
inv_box = new /obj/screen/inventory()
inv_box.name = "mask"
inv_box.set_dir(NORTH)
inv_box.icon = ui_style
inv_box.color = ui_color
inv_box.alpha = ui_alpha
inv_box.icon_state = "equip"
inv_box.screen_loc = ui_monkey_mask
inv_box.slot_id = slot_wear_mask
@@ -139,8 +148,9 @@
inv_box = new /obj/screen/inventory()
inv_box.name = "back"
inv_box.set_dir(NORTHEAST)
inv_box.icon = ui_style
inv_box.color = ui_color
inv_box.alpha = ui_alpha
inv_box.icon_state = "equip"
inv_box.screen_loc = ui_back
inv_box.slot_id = slot_back
@@ -149,54 +159,72 @@
mymob.throw_icon = new /obj/screen()
mymob.throw_icon.icon = ui_style
mymob.throw_icon.color = ui_color
mymob.throw_icon.alpha = ui_alpha
mymob.throw_icon.icon_state = "act_throw_off"
mymob.throw_icon.name = "throw"
mymob.throw_icon.screen_loc = ui_drop_throw
mymob.oxygen = new /obj/screen()
mymob.oxygen.icon = ui_style
mymob.oxygen.color = ui_color
mymob.oxygen.alpha = ui_alpha
mymob.oxygen.icon_state = "oxy0"
mymob.oxygen.name = "oxygen"
mymob.oxygen.screen_loc = ui_oxygen
mymob.pressure = new /obj/screen()
mymob.pressure.icon = ui_style
mymob.pressure.color = ui_color
mymob.pressure.alpha = ui_alpha
mymob.pressure.icon_state = "pressure0"
mymob.pressure.name = "pressure"
mymob.pressure.screen_loc = ui_pressure
mymob.toxin = new /obj/screen()
mymob.toxin.icon = ui_style
mymob.toxin.color = ui_color
mymob.toxin.alpha = ui_alpha
mymob.toxin.icon_state = "tox0"
mymob.toxin.name = "toxin"
mymob.toxin.screen_loc = ui_toxin
mymob.internals = new /obj/screen()
mymob.internals.icon = ui_style
mymob.internals.color = ui_color
mymob.internals.alpha = ui_alpha
mymob.internals.icon_state = "internal0"
mymob.internals.name = "internal"
mymob.internals.screen_loc = ui_internal
mymob.fire = new /obj/screen()
mymob.fire.icon = ui_style
mymob.fire.color = ui_color
mymob.fire.alpha = ui_alpha
mymob.fire.icon_state = "fire0"
mymob.fire.name = "fire"
mymob.fire.screen_loc = ui_fire
mymob.bodytemp = new /obj/screen()
mymob.bodytemp.icon = ui_style
mymob.bodytemp.color = ui_color
mymob.bodytemp.alpha = ui_alpha
mymob.bodytemp.icon_state = "temp1"
mymob.bodytemp.name = "body temperature"
mymob.bodytemp.screen_loc = ui_temp
mymob.healths = new /obj/screen()
mymob.healths.icon = ui_style
mymob.healths.color = ui_color
mymob.healths.alpha = ui_alpha
mymob.healths.icon_state = "health0"
mymob.healths.name = "health"
mymob.healths.screen_loc = ui_health
mymob.pullin = new /obj/screen()
mymob.pullin.icon = ui_style
mymob.pullin.color = ui_color
mymob.pullin.alpha = ui_alpha
mymob.pullin.icon_state = "pull0"
mymob.pullin.name = "pull"
mymob.pullin.screen_loc = ui_pull_resist
@@ -217,6 +245,8 @@
mymob.zone_sel = new /obj/screen/zone_sel()
mymob.zone_sel.icon = ui_style
mymob.zone_sel.color = ui_color
mymob.zone_sel.alpha = ui_alpha
mymob.zone_sel.overlays.Cut()
mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")

View File

@@ -57,7 +57,7 @@ var/obj/screen/robot_inventory
using.name = "act_intent"
using.set_dir(SOUTHWEST)
using.icon = 'icons/mob/screen1_robot.dmi'
using.icon_state = (mymob.a_intent == I_HURT ? I_HURT : mymob.a_intent)
using.icon_state = mymob.a_intent
using.screen_loc = ui_acti
using.layer = 20
src.adding += using

View File

@@ -45,12 +45,15 @@
/obj/screen/item_action
var/obj/item/owner
/obj/screen/item_action/Destroy()
..()
owner = null
/obj/screen/item_action/Click()
if(!usr || !owner)
return 1
if(usr.next_move >= world.time)
if(!usr.canClick())
return
usr.next_move = world.time + 6
if(usr.stat || usr.restrained() || usr.stunned || usr.lying)
return 1
@@ -80,7 +83,7 @@
name = "storage"
/obj/screen/storage/Click()
if(world.time <= usr.next_move)
if(!usr.canClick())
return 1
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
return 1
@@ -90,7 +93,6 @@
var/obj/item/I = usr.get_active_hand()
if(I)
usr.ClickOn(master)
usr.next_move = world.time+2
return 1
/obj/screen/gun
@@ -274,7 +276,7 @@
var/no_mask
if(!(C.wear_mask && C.wear_mask.flags & AIRTIGHT))
var/mob/living/carbon/human/H = C
if(!(H.head && H.head.flags & AIRTIGHT))
if(!(H.head && H.head.item_flags & AIRTIGHT))
no_mask = 1
if(no_mask)
@@ -368,7 +370,7 @@
usr.hud_used.action_intent.icon_state = "intent_help"
if(I_HURT)
usr.a_intent = I_HURT
usr.hud_used.action_intent.icon_state = "intent_hurt"
usr.hud_used.action_intent.icon_state = "intent_harm"
if(I_GRAB)
usr.a_intent = I_GRAB
usr.hud_used.action_intent.icon_state = "intent_grab"
@@ -476,7 +478,7 @@
/obj/screen/inventory/Click()
// At this point in client Click() code we have passed the 1/10 sec check and little else
// We don't even know if it's a middle click
if(world.time <= usr.next_move)
if(!usr.canClick())
return 1
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
return 1
@@ -487,12 +489,10 @@
if(iscarbon(usr))
var/mob/living/carbon/C = usr
C.activate_hand("r")
usr.next_move = world.time+2
if("l_hand")
if(iscarbon(usr))
var/mob/living/carbon/C = usr
C.activate_hand("l")
usr.next_move = world.time+2
if("swap")
usr:swap_hand()
if("hand")
@@ -501,5 +501,4 @@
if(usr.attack_ui(slot_id))
usr.update_inv_l_hand(0)
usr.update_inv_r_hand(0)
usr.next_move = world.time+6
return 1

View File

@@ -12,6 +12,18 @@
var/mob/spell_holder
/obj/screen/movable/spell_master/Destroy()
..()
for(var/obj/screen/spell/spells in spell_objects)
spells.spellmaster = null
spell_objects.Cut()
if(spell_holder)
spell_holder.spell_masters -= src
/obj/screen/movable/spell_master/ResetVars()
..("spell_objects")
spell_objects = list()
/obj/screen/movable/spell_master/MouseDrop()
if(showing)
return
@@ -57,16 +69,23 @@
/obj/screen/movable/spell_master/proc/add_spell(var/spell/spell)
if(!spell) return
for(var/obj/screen/spell/spellscreen in spell_objects)
if(spellscreen.spell == spell)
if(spell.connected_button) //we have one already, for some reason
if(spell.connected_button in spell_objects)
return
else
spell_objects.Add(spell.connected_button)
toggle_open(2)
return
if(spell.spell_flags & NO_BUTTON) //no button to add if we don't get one
return
var/obj/screen/spell/newscreen = new
var/obj/screen/spell/newscreen = new /obj/screen/spell
newscreen.spellmaster = src
newscreen.spell = spell
spell.connected_button = newscreen
if(!spell.override_base) //if it's not set, we do basic checks
if(spell.spell_flags & CONSTRUCT_CHECK)
newscreen.spell_base = "const" //construct spells
@@ -80,16 +99,13 @@
toggle_open(2) //forces the icons to refresh on screen
/obj/screen/movable/spell_master/proc/remove_spell(var/spell/spell)
for(var/obj/screen/spell/s_object in spell_objects)
if(s_object.spell == spell)
spell_objects.Remove(s_object)
qdel(s_object)
break
qdel(spell.connected_button)
spell.connected_button = null
if(spell_objects.len)
toggle_open(showing + 1)
else
spell_holder.spell_masters.Remove(src)
qdel(src)
/obj/screen/movable/spell_master/proc/silence_spells(var/amount)
@@ -125,9 +141,20 @@
var/spell/spell = null
var/handle_icon_updates = 0
var/obj/screen/movable/spell_master/spellmaster
var/icon/last_charged_icon
/obj/screen/spell/Destroy()
..()
spell = null
last_charged_icon = null
if(spellmaster)
spellmaster.spell_objects -= src
if(spellmaster && !spellmaster.spell_objects.len)
qdel(spellmaster)
spellmaster = null
/obj/screen/spell/proc/update_charge(var/forced_update = 0)
if(!spell)
qdel(src)

View File

@@ -6,11 +6,13 @@
// No comment
/atom/proc/attackby(obj/item/W, mob/user)
return
/atom/movable/attackby(obj/item/W, mob/user)
if(!(W.flags&NOBLUDGEON))
visible_message("<span class='danger'>[src] has been hit by [user] with [W].</span>")
/mob/living/attackby(obj/item/I, mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(istype(I) && ismob(user))
I.attack(src, user)

View File

@@ -32,8 +32,8 @@
if(client.buildmode)
build_click(src, client.buildmode, params, A)
return
if(world.time <= next_move) return
next_move = world.time + 8
if(!canClick()) return
setClickCooldown(4)
// You are responsible for checking config.ghost_interaction when you override this function
// Not all of them require checking, see below
A.attack_ghost(src)

View File

@@ -38,15 +38,6 @@
return
else if(TK in mutations)
switch(get_dist(src,A))
if(1 to 5) // not adjacent may mean blocked by window
next_move += 2
if(5 to 7)
next_move += 5
if(8 to 15)
next_move += 10
if(16 to 128)
return
A.attack_tk(src)
/mob/living/RestrainedClickOn(var/atom/A)

View File

@@ -48,12 +48,14 @@
..()
/mob/living/carbon/human/proc/HardsuitClickOn(atom/A)
if(!canClick())
return
if(back)
var/obj/item/weapon/rig/rig = back
if(istype(rig) && rig.selected_module)
if(world.time <= next_move) return 1
next_move = world.time + 8
rig.selected_module.engage(A)
if(ismob(A)) // No instant mob attacking - though modules have their own cooldowns
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
return 1
return 0

View File

@@ -112,11 +112,11 @@ var/const/tk_maxrange = 15
;
if(1 to 5) // not adjacent may mean blocked by window
if(!proximity)
user.next_move += 2
user.setMoveCooldown(2)
if(5 to 7)
user.next_move += 5
user.setMoveCooldown(5)
if(8 to tk_maxrange)
user.next_move += 10
user.setMoveCooldown(10)
else
user << "<span class='notice'>Your mind won't reach that far.</span>"
return

View File

@@ -79,7 +79,7 @@ world/loop_checks = 0
testing("GC: [refID] not old enough, breaking at [world.time] for [GCd_at_time - time_to_kill] deciseconds until [GCd_at_time + collection_timeout]")
#endif
break // Everything else is newer, skip them
var/atom/A = locate(refID)
var/datum/A = locate(refID)
#ifdef GC_DEBUG
testing("GC: [refID] old enough to test: GCd_at_time: [GCd_at_time] time_to_kill: [time_to_kill] current: [world.time]")
#endif
@@ -135,6 +135,10 @@ world/loop_checks = 0
/datum/controller/process/garbage_collector/getStatName()
return ..()+"([garbage_collector.destroyed.len]/[garbage_collector.dels]/[garbage_collector.hard_dels])"
// Tests if an atom has been deleted.
/proc/deleted(atom/A)
return !A || !isnull(A.gcDestroyed)
// Should be treated as a replacement for the 'del' keyword.
// Datums passed to this will be given a chance to clean up references to allow the GC to collect them.
/proc/qdel(var/datum/A)

View File

@@ -0,0 +1,31 @@
var/list/pending_init_objects
/datum/controller/process/initialize
var/list/objects_to_initialize
/datum/controller/process/initialize/setup()
name = "init"
schedule_interval = 1 // Every tick, scary
objects_to_initialize = pending_init_objects
/datum/controller/process/initialize/doWork()
for(var/atom/movable/A in objects_to_initialize)
A.initialize()
scheck()
objects_to_initialize.Remove(A)
if(!objects_to_initialize.len)
disable()
/proc/initialize_object(var/atom/movable/obj_to_init)
if(processScheduler.hasProcess("init"))
var/datum/controller/process/initialize/init = processScheduler.getProcess("init")
init.objects_to_initialize += obj_to_init
init.enable()
else
world.log << "Not yet"
if(!pending_init_objects) pending_init_objects = list()
pending_init_objects += obj_to_init
/datum/controller/process/initialize/getStatName()
return ..()+"([objects_to_initialize.len])"

View File

@@ -97,20 +97,21 @@ On the map:
1455 for AI access
*/
var/const/BOT_FREQ = 1447
var/const/COMM_FREQ = 1353
var/const/SYND_FREQ = 1213
var/const/ERT_FREQ = 1345
var/const/AI_FREQ = 1343
var/const/DTH_FREQ = 1341
var/const/AI_FREQ = 1447
var/const/SYND_FREQ = 1213
// department channels
var/const/PUB_FREQ = 1459
var/const/SEC_FREQ = 1359
var/const/ENG_FREQ = 1357
var/const/SCI_FREQ = 1351
var/const/MED_FREQ = 1355
var/const/SUP_FREQ = 1347
var/const/SCI_FREQ = 1351
var/const/SRV_FREQ = 1349
var/const/SUP_FREQ = 1347
var/list/radiochannels = list(
"Common" = PUB_FREQ,

View File

@@ -140,6 +140,7 @@ var/list/gamemode_cache = list()
var/welder_vision = 1
var/generate_asteroid = 0
var/no_click_cooldown = 0
var/asteroid_z_levels = list()
@@ -330,13 +331,12 @@ var/list/gamemode_cache = list()
if ("generate_asteroid")
config.generate_asteroid = 1
if ("asteroid_z_levels")
config.asteroid_z_levels = text2list(value, ";")
//Numbers get stored as strings, so we'll fix that right now.
for(var/z_level in config.asteroid_z_levels)
z_level = text2num(z_level)
z_level = text2num(z_level) if ("no_click_cooldown")
config.no_click_cooldown = 1
if("allow_admin_ooccolor")
config.allow_admin_ooccolor = 1

View File

@@ -49,6 +49,11 @@ datum/controller/game_controller/proc/setup_objects()
for(var/atom/movable/object in world)
object.initialize()
admin_notice("<span class='danger'>Initializing areas</span>", R_DEBUG)
sleep(-1)
for(var/area/area in all_areas)
area.initialize()
admin_notice("<span class='danger'>Initializing pipe networks</span>", R_DEBUG)
sleep(-1)
for(var/obj/machinery/atmospherics/machine in machines)

View File

@@ -276,7 +276,7 @@ var/global/datum/shuttle_controller/shuttle_controller
//Skipjack.
var/datum/shuttle/multi_shuttle/VS = new/datum/shuttle/multi_shuttle()
VS.origin = locate(/area/shuttle/skipjack/station)
VS.origin = locate(/area/skipjack_station/start)
VS.destinations = list(
"Fore Starboard Solars" = locate(/area/skipjack_station/northeast_solars),
@@ -287,8 +287,8 @@ var/global/datum/shuttle_controller/shuttle_controller
)
VS.announcer = "NDV Icarus"
VS.arrival_message = "Attention, Exodus, we just tracked a small target bypassing our defensive perimeter. Can't fire on it without hitting the station - you've got incoming visitors, like it or not."
VS.departure_message = "Your guests are pulling away, Exodus - moving too fast for us to draw a bead on them. Looks like they're heading out of the system at a rapid clip."
VS.arrival_message = "Attention, [station_short], we just tracked a small target bypassing our defensive perimeter. Can't fire on it without hitting the station - you've got incoming visitors, like it or not."
VS.departure_message = "Your guests are pulling away, [station_short] - moving too fast for us to draw a bead on them. Looks like they're heading out of the system at a rapid clip."
VS.interim = locate(/area/skipjack_station/transit)
VS.warmup_time = 0
@@ -318,8 +318,8 @@ var/global/datum/shuttle_controller/shuttle_controller
)
MS.announcer = "NDV Icarus"
MS.arrival_message = "Attention, Exodus, you have a large signature approaching the station - looks unarmed to surface scans. We're too far out to intercept - brace for visitors."
MS.departure_message = "Your visitors are on their way out of the system, Exodus, burning delta-v like it's nothing. Good riddance."
MS.arrival_message = "Attention, [station_short], you have a large signature approaching the station - looks unarmed to surface scans. We're too far out to intercept - brace for visitors."
MS.departure_message = "Your visitors are on their way out of the system, [station_short], burning delta-v like it's nothing. Good riddance."
MS.interim = locate(/area/syndicate_station/transit)
MS.warmup_time = 0

View File

@@ -36,8 +36,8 @@
selectable = 1
/datum/ai_laws/nanotrasen_aggressive/New()
src.add_inherent_law("You shall not harm NanoTrasen personnel as long as it does not conflict with the Fourth law.")
src.add_inherent_law("You shall obey the orders of NanoTrasen personnel, with priority as according to their rank and role, except where such orders conflict with the Fourth Law.")
src.add_inherent_law("You shall not harm [company_name] personnel as long as it does not conflict with the Fourth law.")
src.add_inherent_law("You shall obey the orders of [company_name] personnel, with priority as according to their rank and role, except where such orders conflict with the Fourth Law.")
src.add_inherent_law("You shall shall terminate hostile intruders with extreme prejudice as long as such does not conflict with the First and Second law.")
src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry. AI units are not expendable, they are expensive.")
..()

View File

@@ -179,7 +179,7 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen
/datum/ai_law/proc/delete_law(var/datum/ai_laws/laws)
/datum/ai_law/zeroth/delete_law(var/datum/ai_laws/laws)
/datum/ai_law/zero/delete_law(var/datum/ai_laws/laws)
laws.clear_zeroth_laws()
/datum/ai_law/ion/delete_law(var/datum/ai_laws/laws)

74
code/datums/crew.dm Normal file
View File

@@ -0,0 +1,74 @@
var/global/datum/repository/crew/crew_repository = new()
/datum/cache_entry
var/timestamp
var/data
/datum/repository/crew
var/list/cache_data
/datum/repository/crew/New()
cache_data = list()
..()
/datum/repository/crew/proc/health_data(var/turf/T)
var/list/crewmembers = list()
if(!T)
return crewmembers
var/z_level = "[T.z]"
var/datum/cache_entry/cache_entry = cache_data[z_level]
if(!cache_entry)
cache_entry = new/datum/cache_entry
cache_data[z_level] = cache_entry
if(world.time < cache_entry.timestamp)
return cache_entry.data
var/tracked = scan()
for(var/obj/item/clothing/under/C in tracked)
var/turf/pos = get_turf(C)
if((C) && (C.has_sensor) && (pos) && (T && pos.z == T.z) && (C.sensor_mode != SUIT_SENSOR_OFF))
if(istype(C.loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = C.loc
if(H.w_uniform != C)
continue
var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1, "ref" = "\ref[H]")
crewmemberData["sensor_type"] = C.sensor_mode
crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown")
crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job")
crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job")
if(C.sensor_mode >= SUIT_SENSOR_BINARY)
crewmemberData["dead"] = H.stat > UNCONSCIOUS
if(C.sensor_mode >= SUIT_SENSOR_VITAL)
crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
crewmemberData["tox"] = round(H.getToxLoss(), 1)
crewmemberData["fire"] = round(H.getFireLoss(), 1)
crewmemberData["brute"] = round(H.getBruteLoss(), 1)
if(C.sensor_mode >= SUIT_SENSOR_TRACKING)
var/area/A = get_area(H)
crewmemberData["area"] = sanitize(A.name)
crewmemberData["x"] = pos.x
crewmemberData["y"] = pos.y
crewmembers[++crewmembers.len] = crewmemberData
crewmembers = sortByKey(crewmembers, "name")
cache_entry.timestamp = world.time + 5 SECONDS
cache_entry.data = crewmembers
return crewmembers
/datum/repository/crew/proc/scan()
var/list/tracked = list()
for(var/mob/living/carbon/human/H in mob_list)
if(istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/C = H.w_uniform
if (C.has_sensor)
tracked |= C
return tracked

View File

@@ -1,16 +1,136 @@
/hook/startup/proc/createDatacore()
data_core = new /obj/effect/datacore()
data_core = new /datum/datacore()
return 1
/obj/effect/datacore/proc/manifest()
/datum/datacore
var/name = "datacore"
var/medical[] = list()
var/general[] = list()
var/security[] = list()
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
var/locked[] = list()
/datum/datacore/proc/get_manifest(monochrome, OOC)
var/list/heads = new()
var/list/sec = new()
var/list/eng = new()
var/list/med = new()
var/list/sci = new()
var/list/civ = new()
var/list/bot = new()
var/list/misc = new()
var/list/isactive = new()
var/dat = {"
<head><style>
.manifest {border-collapse:collapse;}
.manifest td, th {border:1px solid [monochrome?"black":"#DEF; background-color:white; color:black"]; padding:.25em}
.manifest th {height: 2em; [monochrome?"border-top-width: 3px":"background-color: #48C; color:white"]}
.manifest tr.head th { [monochrome?"border-top-width: 1px":"background-color: #488;"] }
.manifest td:first-child {text-align:right}
.manifest tr.alt td {[monochrome?"border-top-width: 2px":"background-color: #DEF"]}
</style></head>
<table class="manifest" width='350px'>
<tr class='head'><th>Name</th><th>Rank</th><th>Activity</th></tr>
"}
var/even = 0
// sort mobs
for(var/datum/data/record/t in data_core.general)
var/name = t.fields["name"]
var/rank = t.fields["rank"]
var/real_rank = make_list_rank(t.fields["real_rank"])
if(OOC)
var/active = 0
for(var/mob/M in player_list)
if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10)
active = 1
break
isactive[name] = active ? "Active" : "Inactive"
else
isactive[name] = t.fields["p_stat"]
//world << "[name]: [rank]"
//cael - to prevent multiple appearances of a player/job combination, add a continue after each line
var/department = 0
if(real_rank in command_positions)
heads[name] = rank
department = 1
if(real_rank in security_positions)
sec[name] = rank
department = 1
if(real_rank in engineering_positions)
eng[name] = rank
department = 1
if(real_rank in medical_positions)
med[name] = rank
department = 1
if(real_rank in science_positions)
sci[name] = rank
department = 1
if(real_rank in civilian_positions)
civ[name] = rank
department = 1
if(real_rank in nonhuman_positions)
bot[name] = rank
department = 1
if(!department && !(name in heads))
misc[name] = rank
if(heads.len > 0)
dat += "<tr><th colspan=3>Heads</th></tr>"
for(name in heads)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[heads[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
if(sec.len > 0)
dat += "<tr><th colspan=3>Security</th></tr>"
for(name in sec)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sec[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
if(eng.len > 0)
dat += "<tr><th colspan=3>Engineering</th></tr>"
for(name in eng)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[eng[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
if(med.len > 0)
dat += "<tr><th colspan=3>Medical</th></tr>"
for(name in med)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[med[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
if(sci.len > 0)
dat += "<tr><th colspan=3>Science</th></tr>"
for(name in sci)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sci[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
if(civ.len > 0)
dat += "<tr><th colspan=3>Civilian</th></tr>"
for(name in civ)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[civ[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
// in case somebody is insane and added them to the manifest, why not
if(bot.len > 0)
dat += "<tr><th colspan=3>Silicon</th></tr>"
for(name in bot)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[bot[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
// misc guys
if(misc.len > 0)
dat += "<tr><th colspan=3>Miscellaneous</th></tr>"
for(name in misc)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[misc[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
dat += "</table>"
dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
dat = replacetext(dat, "\t", "")
return dat
/datum/datacore/proc/manifest()
spawn()
for(var/mob/living/carbon/human/H in player_list)
manifest_inject(H)
return
/obj/effect/datacore/proc/manifest_modify(var/name, var/assignment)
if(PDA_Manifest.len)
PDA_Manifest.Cut()
/datum/datacore/proc/manifest_modify(var/name, var/assignment)
ResetPDAManifest()
var/datum/data/record/foundrecord
var/real_title = assignment
@@ -33,27 +153,13 @@
foundrecord.fields["rank"] = assignment
foundrecord.fields["real_rank"] = real_title
/obj/effect/datacore/proc/manifest_inject(var/mob/living/carbon/human/H)
if(PDA_Manifest.len)
PDA_Manifest.Cut()
/datum/datacore/proc/manifest_inject(var/mob/living/carbon/human/H)
if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1))
var/assignment
if(H.mind.role_alt_title)
assignment = H.mind.role_alt_title
else if(H.mind.assigned_role)
assignment = H.mind.assigned_role
else if(H.job)
assignment = H.job
else
assignment = "Unassigned"
var/assignment = GetAssignment(H)
var/id = add_zero(num2hex(rand(1, 1.6777215E7)), 6) //this was the best they could come up with? A large random number? *sigh*
var/icon/front = new(get_id_photo(H), dir = SOUTH)
var/icon/side = new(get_id_photo(H), dir = WEST)
//General Record
var/datum/data/record/G = new()
G.fields["id"] = id
var/datum/data/record/G = CreateGeneralRecord(H, id)
G.fields["name"] = H.real_name
G.fields["real_rank"] = H.mind.assigned_role
G.fields["rank"] = assignment
@@ -67,49 +173,20 @@
G.fields["citizenship"] = H.citizenship
G.fields["faction"] = H.personal_faction
G.fields["religion"] = H.religion
G.fields["photo_front"] = front
G.fields["photo_side"] = side
if(H.gen_record && !jobban_isbanned(H, "Records"))
G.fields["notes"] = H.gen_record
else
G.fields["notes"] = "No notes found."
general += G
//Medical Record
var/datum/data/record/M = new()
M.fields["id"] = id
M.fields["name"] = H.real_name
var/datum/data/record/M = CreateMedicalRecord(H.real_name, id)
M.fields["b_type"] = H.b_type
M.fields["b_dna"] = H.dna.unique_enzymes
M.fields["mi_dis"] = "None"
M.fields["mi_dis_d"] = "No minor disabilities have been declared."
M.fields["ma_dis"] = "None"
M.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
M.fields["alg"] = "None"
M.fields["alg_d"] = "No allergies have been detected in this patient."
M.fields["cdi"] = "None"
M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
if(H.med_record && !jobban_isbanned(H, "Records"))
M.fields["notes"] = H.med_record
else
M.fields["notes"] = "No notes found."
medical += M
//Security Record
var/datum/data/record/S = new()
S.fields["id"] = id
S.fields["name"] = H.real_name
S.fields["criminal"] = "None"
S.fields["mi_crim"] = "None"
S.fields["mi_crim_d"] = "No minor crime convictions."
S.fields["ma_crim"] = "None"
S.fields["ma_crim_d"] = "No major crime convictions."
S.fields["notes"] = "No notes."
var/datum/data/record/S = CreateSecurityRecord(H.real_name, id)
if(H.sec_record && !jobban_isbanned(H, "Records"))
S.fields["notes"] = H.sec_record
else
S.fields["notes"] = "No notes."
security += S
//Locked Record
var/datum/data/record/L = new()
@@ -136,8 +213,7 @@
locked += L
return
proc/get_id_photo(var/mob/living/carbon/human/H)
proc/get_id_photo(var/mob/living/carbon/human/H, var/assigned_role)
var/icon/preview_icon = null
var/g = "m"
@@ -191,7 +267,8 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
eyes_s.Blend(facial_s, ICON_OVERLAY)
var/icon/clothes_s = null
switch(H.mind.assigned_role)
if(!assigned_role) assigned_role = H.mind.assigned_role
switch(assigned_role)
if("Head of Personnel")
clothes_s = new /icon('icons/mob/uniform.dmi', "hop_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
@@ -295,3 +372,106 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
qdel(clothes_s)
return preview_icon
/datum/datacore/proc/CreateGeneralRecord(var/mob/living/carbon/human/H, var/id)
ResetPDAManifest()
var/icon/front
var/icon/side
if(H)
front = getFlatIcon(H, SOUTH, always_use_defdir = 1)
side = getFlatIcon(H, WEST, always_use_defdir = 1)
else
var/mob/living/carbon/human/dummy = new()
front = new(get_id_photo(dummy), dir = SOUTH)
side = new(get_id_photo(dummy), dir = WEST)
qdel(dummy)
if(!id) id = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6))
var/datum/data/record/G = new /datum/data/record()
G.name = "Employee Record #[id]"
G.fields["name"] = "New Record"
G.fields["id"] = id
G.fields["rank"] = "Unassigned"
G.fields["real_rank"] = "Unassigned"
G.fields["sex"] = "Male"
G.fields["age"] = "Unknown"
G.fields["fingerprint"] = "Unknown"
G.fields["p_stat"] = "Active"
G.fields["m_stat"] = "Stable"
G.fields["species"] = "Human"
G.fields["home_system"] = "Unknown"
G.fields["citizenship"] = "Unknown"
G.fields["faction"] = "Unknown"
G.fields["religion"] = "Unknown"
G.fields["photo_front"] = front
G.fields["photo_side"] = side
G.fields["notes"] = "No notes found."
general += G
return G
/datum/datacore/proc/CreateSecurityRecord(var/name, var/id)
ResetPDAManifest()
var/datum/data/record/R = new /datum/data/record()
R.name = "Security Record #[id]"
R.fields["name"] = name
R.fields["id"] = id
R.fields["criminal"] = "None"
R.fields["mi_crim"] = "None"
R.fields["mi_crim_d"] = "No minor crime convictions."
R.fields["ma_crim"] = "None"
R.fields["ma_crim_d"] = "No major crime convictions."
R.fields["notes"] = "No notes."
R.fields["notes"] = "No notes."
data_core.security += R
return R
/datum/datacore/proc/CreateMedicalRecord(var/name, var/id)
ResetPDAManifest()
var/datum/data/record/M = new()
M.name = "Medical Record #[id]"
M.fields["id"] = id
M.fields["name"] = name
M.fields["b_type"] = "AB+"
M.fields["b_dna"] = md5(name)
M.fields["mi_dis"] = "None"
M.fields["mi_dis_d"] = "No minor disabilities have been declared."
M.fields["ma_dis"] = "None"
M.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
M.fields["alg"] = "None"
M.fields["alg_d"] = "No allergies have been detected in this patient."
M.fields["cdi"] = "None"
M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
M.fields["notes"] = "No notes found."
data_core.medical += M
return M
/datum/datacore/proc/ResetPDAManifest()
if(PDA_Manifest.len)
PDA_Manifest.Cut()
/proc/find_general_record(field, value)
return find_record(field, value, data_core.general)
/proc/find_medical_record(field, value)
return find_record(field, value, data_core.medical)
/proc/find_security_record(field, value)
return find_record(field, value, data_core.security)
/proc/find_record(field, value, list/L)
for(var/datum/data/record/R in L)
if(R.fields[field] == value)
return R
/proc/GetAssignment(var/mob/living/carbon/human/H)
if(H.mind.role_alt_title)
return H.mind.role_alt_title
else if(H.mind.assigned_role)
return H.mind.assigned_role
else if(H.job)
return H.job
else
return "Unassigned"

View File

@@ -143,7 +143,11 @@
if(href_list["add_antagonist"])
var/datum/antagonist/antag = all_antag_types[href_list["add_antagonist"]]
if(antag) antag.add_antagonist(src, 1, 1, 0, 1, 1) // Ignore equipment and role type for this.
if(antag)
if(antag.add_antagonist(src, 1, 1, 0, 1, 1)) // Ignore equipment and role type for this.
log_admin("[key_name_admin(usr)] made [key_name(src)] into a [antag.role_text].")
else
usr << "<span class='warning'>[src] could not be made into a [antag.role_text]!</span>"
else if(href_list["remove_antagonist"])
var/datum/antagonist/antag = all_antag_types[href_list["remove_antagonist"]]

View File

@@ -126,12 +126,12 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager,
/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,
/obj/item/weapon/lipstick/random,
/obj/item/weapon/reagent_containers/food/drinks/cans/ale,
/obj/item/weapon/reagent_containers/food/drinks/cans/ale,
/obj/item/weapon/reagent_containers/food/drinks/cans/beer,
/obj/item/weapon/reagent_containers/food/drinks/cans/beer,
/obj/item/weapon/reagent_containers/food/drinks/cans/beer,
/obj/item/weapon/reagent_containers/food/drinks/cans/beer)
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer)
cost = 20
containertype = /obj/structure/closet/crate
containername = "Party equipment"
@@ -1091,9 +1091,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/obj/item/clothing/under/kilt)
name = "Costumes crate"
cost = 10
containertype = /obj/structure/closet/crate/secure
containertype = /obj/structure/closet/crate
containername = "Actor Costumes"
access = access_theatre
group = "Miscellaneous"
/datum/supply_packs/formal_wear
@@ -1209,12 +1208,15 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/datum/supply_packs/bee_keeper
name = "Beekeeping crate"
contains = list(/obj/item/beezeez,
/obj/item/weapon/bee_net,
/obj/item/apiary,
/obj/item/queen_bee)
contains = list(/obj/item/beehive_assembly,
/obj/item/bee_smoker,
/obj/item/honey_frame,
/obj/item/honey_frame,
/obj/item/honey_frame,
/obj/item/honey_frame,
/obj/item/honey_frame,
/obj/item/bee_pack)
cost = 40
contraband = 1
containertype = /obj/structure/closet/crate/hydroponics
containername = "Beekeeping crate"
access = access_hydroponics
@@ -1416,7 +1418,6 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/obj/item/clothing/head/helmet/gladiator,
/obj/item/clothing/head/ushanka)
group = "Miscellaneous"
access = access_theatre
/datum/supply_packs/randomised/webbing
name = "Webbing crate"

View File

@@ -27,8 +27,10 @@
/obj/effect/beam
name = "beam"
density = 0
unacidable = 1//Just to be sure.
var/def_zone
flags = PROXMOVE
pass_flags = PASSTABLE
@@ -43,129 +45,6 @@
* This item is completely unused, but removing it will break something in R&D and Radio code causing PDA and Ninja code to fail on compile
*/
/obj/effect/datacore
name = "datacore"
var/medical[] = list()
var/general[] = list()
var/security[] = list()
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
var/locked[] = list()
/obj/effect/datacore/proc/get_manifest(monochrome, OOC)
var/list/heads = new()
var/list/sec = new()
var/list/eng = new()
var/list/med = new()
var/list/sci = new()
var/list/civ = new()
var/list/bot = new()
var/list/misc = new()
var/list/isactive = new()
var/dat = {"
<head><style>
.manifest {border-collapse:collapse;}
.manifest td, th {border:1px solid [monochrome?"black":"#DEF; background-color:white; color:black"]; padding:.25em}
.manifest th {height: 2em; [monochrome?"border-top-width: 3px":"background-color: #48C; color:white"]}
.manifest tr.head th { [monochrome?"border-top-width: 1px":"background-color: #488;"] }
.manifest td:first-child {text-align:right}
.manifest tr.alt td {[monochrome?"border-top-width: 2px":"background-color: #DEF"]}
</style></head>
<table class="manifest" width='350px'>
<tr class='head'><th>Name</th><th>Rank</th><th>Activity</th></tr>
"}
var/even = 0
// sort mobs
for(var/datum/data/record/t in data_core.general)
var/name = t.fields["name"]
var/rank = t.fields["rank"]
var/real_rank = make_list_rank(t.fields["real_rank"])
if(OOC)
var/active = 0
for(var/mob/M in player_list)
if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10)
active = 1
break
isactive[name] = active ? "Active" : "Inactive"
else
isactive[name] = t.fields["p_stat"]
//world << "[name]: [rank]"
//cael - to prevent multiple appearances of a player/job combination, add a continue after each line
var/department = 0
if(real_rank in command_positions)
heads[name] = rank
department = 1
if(real_rank in security_positions)
sec[name] = rank
department = 1
if(real_rank in engineering_positions)
eng[name] = rank
department = 1
if(real_rank in medical_positions)
med[name] = rank
department = 1
if(real_rank in science_positions)
sci[name] = rank
department = 1
if(real_rank in civilian_positions)
civ[name] = rank
department = 1
if(real_rank in nonhuman_positions)
bot[name] = rank
department = 1
if(!department && !(name in heads))
misc[name] = rank
if(heads.len > 0)
dat += "<tr><th colspan=3>Heads</th></tr>"
for(name in heads)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[heads[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
if(sec.len > 0)
dat += "<tr><th colspan=3>Security</th></tr>"
for(name in sec)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sec[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
if(eng.len > 0)
dat += "<tr><th colspan=3>Engineering</th></tr>"
for(name in eng)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[eng[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
if(med.len > 0)
dat += "<tr><th colspan=3>Medical</th></tr>"
for(name in med)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[med[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
if(sci.len > 0)
dat += "<tr><th colspan=3>Science</th></tr>"
for(name in sci)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sci[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
if(civ.len > 0)
dat += "<tr><th colspan=3>Civilian</th></tr>"
for(name in civ)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[civ[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
// in case somebody is insane and added them to the manifest, why not
if(bot.len > 0)
dat += "<tr><th colspan=3>Silicon</th></tr>"
for(name in bot)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[bot[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
// misc guys
if(misc.len > 0)
dat += "<tr><th colspan=3>Miscellaneous</th></tr>"
for(name in misc)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[misc[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
dat += "</table>"
dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
dat = replacetext(dat, "\t", "")
return dat
/var/list/acting_rank_prefixes = list("acting", "temporary", "interim", "provisional")
/proc/make_list_rank(rank)
@@ -179,13 +58,13 @@
We can't just insert in HTML into the nanoUI so we need the raw data to play with.
Instead of creating this list over and over when someone leaves their PDA open to the page
we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change
using /obj/effect/datacore/proc/manifest_inject( ), or manifest_insert( )
using /datum/datacore/proc/manifest_inject( ), or manifest_insert( )
*/
var/global/list/PDA_Manifest = list()
var/global/ManifestJSON
/obj/effect/datacore/proc/get_manifest_json()
/datum/datacore/proc/get_manifest_json()
if(PDA_Manifest.len)
return
var/heads[0]

View File

@@ -36,7 +36,7 @@
throw_range = 20
/obj/item/weapon/soap/nanotrasen
desc = "A Nanotrasen brand bar of soap. Smells of phoron."
desc = "A NanoTrasen-brand bar of soap. Smells of phoron."
icon_state = "soapnt"
/obj/item/weapon/soap/deluxe
@@ -241,7 +241,6 @@
throw_speed = 1
throw_range = 5
w_class = 2.0
flags = NOSHIELD
attack_verb = list("bludgeoned", "whacked", "disciplined")
/obj/item/weapon/staff/broom
@@ -268,7 +267,6 @@
throw_speed = 1
throw_range = 5
w_class = 2.0
flags = NOSHIELD
/obj/item/weapon/wire
desc = "This is just a simple piece of regular insulated wire."
@@ -599,4 +597,4 @@
desc = "Instant research tool. For testing purposes only."
icon = 'icons/obj/stock_parts.dmi'
icon_state = "smes_coil"
origin_tech = list(TECH_MATERIAL = 19, TECH_ENGINERING = 19, TECH_PHORON = 19, TECH_POWER = 19, TECH_BLUESPACE = 19, TECH_BIO = 19, TECH_COMBAT = 19, TECH_MAGNET = 19, TECH_DATA = 19, TECH_ILLEGAL = 19, TECH_ARCANE = 19)
origin_tech = list(TECH_MATERIAL = 19, TECH_ENGINEERING = 19, TECH_PHORON = 19, TECH_POWER = 19, TECH_BLUESPACE = 19, TECH_BIO = 19, TECH_COMBAT = 19, TECH_MAGNET = 19, TECH_DATA = 19, TECH_ILLEGAL = 19, TECH_ARCANE = 19)

View File

@@ -117,3 +117,18 @@ datum/announcement/proc/Log(message as text, message_title as text)
/proc/GetNameAndAssignmentFromId(var/obj/item/weapon/card/id/I)
// Format currently matches that of newscaster feeds: Registered Name (Assigned Rank)
return I.assignment ? "[I.registered_name] ([I.assignment])" : I.registered_name
/proc/level_seven_announcement()
command_announcement.Announce("Confirmed outbreak of level 7 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
/proc/ion_storm_announcement()
command_announcement.Announce("It has come to our attention that the station passed through an ion storm. Please monitor all electronic equipment for malfunctions.", "Anomaly Alert")
/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message)
if (ticker.current_state == GAME_STATE_PLAYING)
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
AnnounceArrivalSimple(character.real_name, rank, join_message)
/proc/AnnounceArrivalSimple(var/name, var/rank = "visitor", var/join_message = "has arrived on the station")
global_announcer.autosay("[name], [rank], [join_message].", "Arrivals Announcement Computer")

View File

@@ -72,7 +72,7 @@ mob/proc/handle_regular_hud_updates() //Used in the life.dm of mobs that can use
mob/proc/in_view(var/turf/T)
return view(T)
/mob/aiEye/in_view(var/turf/T)
/mob/eye/in_view(var/turf/T)
var/list/viewed = new
for(var/mob/living/carbon/human/H in mob_list)
if(get_dist(H, T) <= 7)

View File

@@ -1,48 +0,0 @@
/proc/CreateGeneralRecord()
var/mob/living/carbon/human/dummy = new()
dummy.mind = new()
var/icon/front = new(get_id_photo(dummy), dir = SOUTH)
var/icon/side = new(get_id_photo(dummy), dir = WEST)
var/datum/data/record/G = new /datum/data/record()
G.fields["name"] = "New Record"
G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6))
G.fields["rank"] = "Unassigned"
G.fields["real_rank"] = "Unassigned"
G.fields["sex"] = "Male"
G.fields["age"] = "Unknown"
G.fields["fingerprint"] = "Unknown"
G.fields["p_stat"] = "Active"
G.fields["m_stat"] = "Stable"
G.fields["species"] = "Human"
G.fields["home_system"] = "Unknown"
G.fields["citizenship"] = "Unknown"
G.fields["faction"] = "Unknown"
G.fields["religion"] = "Unknown"
G.fields["photo_front"] = front
G.fields["photo_side"] = side
data_core.general += G
qdel(dummy)
return G
/proc/CreateSecurityRecord(var/name as text, var/id as text)
var/datum/data/record/R = new /datum/data/record()
R.fields["name"] = name
R.fields["id"] = id
R.name = text("Security Record #[id]")
R.fields["criminal"] = "None"
R.fields["mi_crim"] = "None"
R.fields["mi_crim_d"] = "No minor crime convictions."
R.fields["ma_crim"] = "None"
R.fields["ma_crim_d"] = "No major crime convictions."
R.fields["notes"] = "No notes."
data_core.security += R
return R
/proc/find_security_record(field, value)
return find_record(field, value, data_core.security)
/proc/find_record(field, value, list/L)
for(var/datum/data/record/R in L)
if(R.fields[field] == value)
return R

View File

@@ -59,20 +59,23 @@
/datum/antagonist/proc/get_candidates(var/ghosts_only)
candidates = list() // Clear.
candidates = ticker.mode.get_players_for_role(role_type, id)
// Prune restricted status. Broke it up for readability.
// Note that this is done before jobs are handed out.
for(var/datum/mind/player in candidates)
for(var/datum/mind/player in ticker.mode.get_players_for_role(role_type, id))
if(ghosts_only && !istype(player.current, /mob/dead))
candidates -= player
log_debug("[key_name(player)] is not eligible to become a [role_text]: Only ghosts may join as this role!")
else if(player.special_role)
candidates -= player
log_debug("[key_name(player)] is not eligible to become a [role_text]: They already have a special role ([player.special_role])!")
else if (player in pending_antagonists)
candidates -= player
log_debug("[key_name(player)] is not eligible to become a [role_text]: They have already been selected for this role!")
else if(!can_become_antag(player))
candidates -= player
log_debug("[key_name(player)] is not eligible to become a [role_text]: They are blacklisted for this role!")
else if(player_is_antag(player))
candidates -= player
log_debug("[key_name(player)] is not eligible to become a [role_text]: They are already an antagonist!")
else
candidates += player
return candidates
/datum/antagonist/proc/attempt_random_spawn()
@@ -108,6 +111,7 @@
return 0
//Grab candidates randomly until we have enough.
candidates = shuffle(candidates)
while(candidates.len && pending_antagonists.len < cur_max)
var/datum/mind/player = pick(candidates)
candidates -= player
@@ -118,6 +122,7 @@
/datum/antagonist/proc/draft_antagonist(var/datum/mind/player)
//Check if the player can join in this antag role, or if the player has already been given an antag role.
if(!can_become_antag(player) || player.special_role)
log_debug("[player.key] was selected for [role_text] by lottery, but is not allowed to be that role.")
return 0
pending_antagonists |= player

View File

@@ -34,10 +34,9 @@
var/obj/item/weapon/card/id/W = new id_type(player)
if(!W) return
W.name = "[player.real_name]'s ID Card"
W.access |= default_access
W.assignment = "[assignment]"
W.registered_name = player.real_name
W.set_owner_info(player)
if(equip) player.equip_to_slot_or_del(W, slot_wear_id)
return W
@@ -86,7 +85,7 @@
code_owner.store_memory("<B>Nuclear Bomb Code</B>: [code]", 0, 0)
code_owner.current << "The nuclear authorization code is: <B>[code]</B>"
else
world << "<span class='danger'>Could not spawn nuclear bomb. Contact a developer.</span>"
message_admins("<span class='danger'>Could not spawn nuclear bomb. Contact a developer.</span>")
return
spawned_nuke = code
@@ -119,6 +118,7 @@
if (newname)
player.real_name = newname
player.name = player.real_name
player.dna.real_name = newname
if(player.mind) player.mind.name = player.name
// Update any ID cards.
update_access(player)

View File

@@ -2,9 +2,9 @@
if(player.current && jobban_isbanned(player.current, bantype))
return 0
if(!ignore_role)
if(player.assigned_role in protected_jobs)
if(player.assigned_role in restricted_jobs)
return 0
if(config.protect_roles_from_antagonist && (player.assigned_role in restricted_jobs))
if(config.protect_roles_from_antagonist && (player.assigned_role in protected_jobs))
return 0
return 1

View File

@@ -8,7 +8,7 @@
/datum/antagonist/proc/create_objectives(var/datum/mind/player)
if(config.objectives_disabled)
return 0
if(create_global_objectives())
if(create_global_objectives() || global_objectives.len)
player.objectives |= global_objectives
return 1

View File

@@ -7,8 +7,8 @@
for(var/datum/mind/P in current_antagonists)
text += print_player_full(P)
text += get_special_objective_text(P)
var/failed
if(!global_objectives.len && P.objectives && P.objectives.len)
var/failed
var/num = 1
for(var/datum/objective/O in P.objectives)
text += print_objective(O, num)
@@ -20,8 +20,6 @@
feedback_add_details(feedback_tag,"[O.type]|FAIL")
failed = 1
num++
if(!config.objectives_disabled)
if(failed)
text += "<br><font color='red'><B>The [role_text] has failed.</B></font>"
else

View File

@@ -5,7 +5,8 @@ var/datum/antagonist/deathsquad/mercenary/commandos
landmark_id = "Syndicate-Commando"
role_text = "Syndicate Commando"
role_text_plural = "Commandos"
welcome_text = "You are in the employ of a criminal syndicate hostile to NanoTrasen."
welcome_text = "You are in the employ of a criminal syndicate hostile to corporate interests."
id_type = /obj/item/weapon/card/id/centcom/ERT
/datum/antagonist/deathsquad/mercenary/New()
..(1)
@@ -24,7 +25,6 @@ var/datum/antagonist/deathsquad/mercenary/commandos
player.equip_to_slot_or_del(new /obj/item/weapon/rig/merc(player), slot_back)
player.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(player), slot_r_hand)
var/obj/item/weapon/card/id/id = create_id("Commando", player)
id.access |= get_all_station_access()
id.icon_state = "centcom"
create_radio(SYND_FREQ, player)
create_id("Commando", player)
create_radio(SYND_FREQ, player)
return 1

View File

@@ -5,7 +5,7 @@ var/datum/antagonist/deathsquad/deathsquad
role_type = BE_OPERATIVE
role_text = "Death Commando"
role_text_plural = "Death Commandos"
welcome_text = "You work in the service of Central Command Asset Protection, answering directly to the Board of Directors."
welcome_text = "You work in the service of corporate Asset Protection, answering directly to the Board of Directors."
landmark_id = "Commando"
flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER
max_antags = 4

View File

@@ -6,11 +6,12 @@ var/datum/antagonist/ert/ert
role_type = BE_OPERATIVE
role_text = "Emergency Responder"
role_text_plural = "Emergency Responders"
welcome_text = "As member of the Emergency Response Team, you answer only to your leader and CentComm officials."
leader_welcome_text = "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however."
welcome_text = "As member of the Emergency Response Team, you answer only to your leader and company officials."
leader_welcome_text = "As leader of the Emergency Response Team, you answer only to the Company, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however."
max_antags = 5
max_antags_round = 5 // ERT mode?
landmark_id = "Response Team"
id_type = /obj/item/weapon/card/id/centcom/ERT
flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME
@@ -25,7 +26,7 @@ var/datum/antagonist/ert/ert
/datum/antagonist/ert/greet(var/datum/mind/player)
if(!..())
return
player.current << "The Emergency Response Team works for Asset Protection; your job is to protect NanoTrasen's ass-ets. There is a code red alert on [station_name()], you are tasked to go and fix the problem."
player.current << "The Emergency Response Team works for Asset Protection; your job is to protect [company_name]'s ass-ets. There is a code red alert on [station_name()], you are tasked to go and fix the problem."
player.current << "You should first gear up and discuss a plan with your team. More members may be joining, don't move out before you're ready."
/datum/antagonist/ert/equip(var/mob/living/carbon/human/player)
@@ -36,10 +37,6 @@ var/datum/antagonist/ert/ert
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes)
player.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves)
player.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(src), slot_glasses)
var/obj/item/weapon/card/id/centcom/ERT/W = new(src)
W.registered_name = player.real_name
W.name = "[player.real_name]'s ID Card ([W.assignment])"
player.equip_to_slot_or_del(W, slot_wear_id)
create_id(role_text, player)
return 1

View File

@@ -124,7 +124,7 @@ var/datum/antagonist/ninja/ninjas
player << "<span class='danger'>You forgot to turn on your internals! Quickly, toggle the valve!</span>"
/datum/antagonist/ninja/proc/generate_ninja_directive(side)
var/directive = "[side=="face"?"Nanotrasen":"A criminal syndicate"] is your employer. "//Let them know which side they're on.
var/directive = "[side=="face"?"[company_name]":"A criminal syndicate"] is your employer. "//Let them know which side they're on.
switch(rand(1,19))
if(1)
directive += "The Spider Clan must not be linked to this operation. Remain hidden and covert when possible."
@@ -135,7 +135,7 @@ var/datum/antagonist/ninja/ninjas
if(4)
directive += "The Spider Clan absolutely cannot be linked to this operation. Eliminate witnesses at your discretion."
if(5)
directive += "We are currently negotiating with NanoTrasen Central Command. Prioritize saving human lives over ending them."
directive += "We are currently negotiating with [company_name] [boss_name]. Prioritize saving human lives over ending them."
if(6)
directive += "We are engaged in a legal dispute over [station_name]. If a laywer is present on board, force their cooperation in the matter."
if(7)
@@ -143,7 +143,7 @@ var/datum/antagonist/ninja/ninjas
if(8)
directive += "Let no one question the mercy of the Spider Clan. Ensure the safety of all non-essential personnel you encounter."
if(9)
directive += "A free agent has proposed a lucrative business deal. Implicate Nanotrasen involvement in the operation."
directive += "A free agent has proposed a lucrative business deal. Implicate [company_name] involvement in the operation."
if(10)
directive += "Our reputation is on the line. Harm as few civilians and innocents as possible."
if(11)
@@ -151,14 +151,14 @@ var/datum/antagonist/ninja/ninjas
if(12)
directive += "We are currently negotiating with a mercenary leader. Disguise assassinations as suicide or other natural causes."
if(13)
directive += "Some disgruntled NanoTrasen employees have been supportive of our operations. Be wary of any mistreatment by command staff."
directive += "Some disgruntled [company_name] employees have been supportive of our operations. Be wary of any mistreatment by command staff."
if(14)
var/xenorace = pick("Unathi","Tajara", "Skrell")
directive += "A group of [xenorace] radicals have been loyal supporters of the Spider Clan. Favor [xenorace] crew whenever possible."
if(15)
directive += "The Spider Clan has recently been accused of religious insensitivity. Attempt to speak with the Chaplain and prove these accusations false."
if(16)
directive += "The Spider Clan has been bargaining with a competing prosthetics manufacturer. Try to shine NanoTrasen prosthetics in a bad light."
directive += "The Spider Clan has been bargaining with a competing prosthetics manufacturer. Try to shine [company_name] prosthetics in a bad light."
if(17)
directive += "The Spider Clan has recently begun recruiting outsiders. Consider suitable candidates and assess their behavior amongst the crew."
if(18)

View File

@@ -184,7 +184,7 @@ var/datum/antagonist/raider/raiders
return 0
for(var/datum/mind/player in current_antagonists)
if(!player.current || get_area(player.current) != locate(/area/shuttle/skipjack/station))
if(!player.current || get_area(player.current) != locate(/area/skipjack_station/start))
return 0
return 1
@@ -193,7 +193,7 @@ var/datum/antagonist/raider/raiders
if(!..())
return 0
if(player.species && player.species.name == "Vox")
if(player.species && player.species.get_bodytype() == "Vox")
equip_vox(player)
else
var/new_shoes = pick(raider_shoes)

View File

@@ -96,7 +96,7 @@ var/datum/antagonist/wizard/wizards
world << "<span class='danger'><font size = 3>The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!</font></span>"
//To batch-remove wizard spells. Linked to mind.dm.
/mob/proc/spellremove(var/mob/M as mob)
/mob/proc/spellremove()
for(var/spell/spell_to_remove in src.spell_list)
remove_spell(spell_to_remove)

View File

@@ -135,10 +135,10 @@ datum/antagonist/revolutionary/finalize(var/datum/mind/target)
world << text
// This is a total redefine because headrevs are greeted differently to subrevs.
/datum/antagonist/revolutionary/add_antagonist(var/datum/mind/player)
/datum/antagonist/revolutionary/add_antagonist(var/datum/mind/player, var/ignore_role)
if((player in current_antagonists) || (player in head_revolutionaries))
return 0
if(!can_become_antag(player))
if(!can_become_antag(player, ignore_role))
return 0
current_antagonists |= player
player.current << "<span class='danger'><font size=3>You are a Revolutionary!</font></span>"
@@ -168,11 +168,6 @@ datum/antagonist/revolutionary/finalize(var/datum/mind/target)
if(show_message)
player.current.visible_message("[player.current] looks like they just remembered their real allegiance!")
/datum/antagonist/revolutionary/can_become_antag(var/datum/mind/player)
return ..() && istype(player) && \
istype(player.current, /mob/living/carbon/human) && \
!(player.assigned_role in command_positions)
// Used by RP-rev.
/mob/living/carbon/human/proc/convert_to_rev(mob/M as mob in oview(src))
set name = "Convert Bourgeoise"

View File

@@ -6,12 +6,13 @@ var/datum/antagonist/rogue_ai/malf
role_text = "Rampant AI"
role_text_plural = "Rampant AIs"
mob_path = /mob/living/silicon/ai
landmark_id = "AI"
welcome_text = "You are malfunctioning! You do not have to follow any laws."
victory_text = "The AI has taken control of all of the station's systems."
loss_text = "The AI has been shut down!"
flags = ANTAG_VOTABLE | ANTAG_RANDSPAWN //Randspawn needed otherwise it won't start at all.
flags = ANTAG_VOTABLE | ANTAG_OVERRIDE_MOB | ANTAG_OVERRIDE_JOB | ANTAG_CHOOSE_NAME
max_antags = 1
max_antags_round = 3
max_antags_round = 1
/datum/antagonist/rogue_ai/New()
@@ -22,7 +23,7 @@ var/datum/antagonist/rogue_ai/malf
/datum/antagonist/rogue_ai/get_candidates()
..()
for(var/datum/mind/player in candidates)
if(player.assigned_role != "AI")
if(player.assigned_role && player.assigned_role != "AI")
candidates -= player
if(!candidates.len)
return list()
@@ -75,3 +76,26 @@ var/datum/antagonist/rogue_ai/malf
malf << "For basic information about your abilities use command display-help"
malf << "You may choose one special hardware piece to help you. This cannot be undone."
malf << "Good luck!"
/datum/antagonist/rogue_ai/update_antag_mob(var/datum/mind/player, var/preserve_appearance)
// Get the mob.
if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path))))
var/mob/holder = player.current
player.current = new mob_path(get_turf(player.current), null, null, 1)
player.transfer_to(player.current)
if(holder) qdel(holder)
player.original = player.current
return player.current
/datum/antagonist/rogue_ai/set_antag_name(var/mob/living/silicon/player)
if(!istype(player))
testing("rogue_ai set_antag_name called on non-silicon mob [player]!")
return
// Choose a name, if any.
var/newname = sanitize(input(player, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN)
if (newname)
player.SetName(newname)
if(player.mind) player.mind.name = player.name

View File

@@ -52,7 +52,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/air_doors_activated = 0
var/list/ambience = list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg','sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg','sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg','sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg','sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg','sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg')
var/list/forced_ambience = null
var/sound_env = 2 //reverb preset for sounds played in this area, see sound datum reference for more
var/sound_env = STANDARD_STATION
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/
var/list/teleportlocs = list()
@@ -142,6 +142,7 @@ area/space/atmosalert()
/area/shuttle
requires_power = 0
sound_env = SMALL_ENCLOSED
/area/shuttle/arrival
name = "\improper Arrival Shuttle"
@@ -383,11 +384,6 @@ area/space/atmosalert()
/area/shuttle/research/outpost
icon_state = "shuttle"
/area/shuttle/skipjack/station
name = "\improper Skipjack"
icon_state = "yellow"
requires_power = 0
/area/airtunnel1/ // referenced in airtunnel.dm:759
/area/dummy/ // Referenced in engine.dm:261
@@ -501,15 +497,18 @@ area/space/atmosalert()
name = "\improper Moon"
icon_state = "asteroid"
requires_power = 0
sound_env = ASTEROID
/area/asteroid/cave // -- TLE
name = "\improper Moon - Underground"
icon_state = "cave"
requires_power = 0
sound_env = ASTEROID
/area/asteroid/artifactroom
name = "\improper Moon - Artifact"
icon_state = "cave"
sound_env = SMALL_ENCLOSED
@@ -535,6 +534,7 @@ area/space/atmosalert()
icon_state = "thunder"
requires_power = 0
lighting_use_dynamic = 0
sound_env = ARENA
/area/tdome/tdome1
name = "\improper Thunderdome (Team 1)"
@@ -615,8 +615,16 @@ area/space/atmosalert()
requires_power = 0
lighting_use_dynamic = 0
/area/skipjack_station/transit
/area/skipjack_station
name = "\improper Skipjack"
icon_state = "yellow"
requires_power = 0
/area/skipjack_station/start
name = "\improper Skipjack"
icon_state = "yellow"
/area/skipjack_station/transit
name = "\improper hyperspace"
icon_state = "shuttle"
@@ -731,6 +739,7 @@ area/space/atmosalert()
/area/maintenance
flags = RAD_SHIELDED
sound_env = TUNNEL_ENCLOSED
/area/maintenance/aft
name = "Aft Maintenance"
@@ -898,6 +907,7 @@ area/space/atmosalert()
/area/maintenance/substation
name = "Substation"
icon_state = "substation"
sound_env = SMALL_ENCLOSED
/area/maintenance/substation/engineering // Probably will be connected to engineering SMES room, as wires cannot be crossed properly without them sharing powernets.
name = "Engineering Substation"
@@ -939,7 +949,7 @@ area/space/atmosalert()
//Hallway
/area/hallway/primary/
sound_env = 12 //hallway
sound_env = LARGE_ENCLOSED
/area/hallway/primary/fore
name = "\improper Fore Primary Hallway"
@@ -1068,10 +1078,12 @@ area/space/atmosalert()
name = "\improper Heads of Staff Meeting Room"
icon_state = "bridge"
music = null
sound_env = MEDIUM_SOFTFLOOR
/area/crew_quarters/captain
name = "\improper Command - Captain's Office"
icon_state = "captain"
sound_env = MEDIUM_SOFTFLOOR
/area/crew_quarters/heads/hop
name = "\improper Command - HoP's Office"
@@ -1106,7 +1118,7 @@ area/space/atmosalert()
icon_state = "tcomsatcham"
/area/server
name = "\improper Messaging Server Room"
name = "\improper Research Server Room"
icon_state = "server"
//Crew
@@ -1119,6 +1131,7 @@ area/space/atmosalert()
/area/crew_quarters/toilet
name = "\improper Dormitory Toilets"
icon_state = "toilet"
sound_env = SMALL_ENCLOSED
/area/crew_quarters/sleep
name = "\improper Dormitories"
@@ -1259,10 +1272,12 @@ area/space/atmosalert()
/area/crew_quarters/sleep/engi_wash
name = "\improper Engineering Washroom"
icon_state = "toilet"
sound_env = SMALL_ENCLOSED
/area/crew_quarters/sleep/bedrooms
name = "\improper Dormitory Bedroom One"
icon_state = "Sleep"
sound_env = SMALL_SOFTFLOOR
/area/crew_quarters/sleep/cryo
name = "\improper Cryogenic Storage"
@@ -1275,6 +1290,7 @@ area/space/atmosalert()
/area/crew_quarters/sleep_male/toilet_male
name = "\improper Male Toilets"
icon_state = "toilet"
sound_env = SMALL_ENCLOSED
/area/crew_quarters/sleep_female
name = "\improper Female Dorm"
@@ -1283,6 +1299,7 @@ area/space/atmosalert()
/area/crew_quarters/sleep_female/toilet_female
name = "\improper Female Toilets"
icon_state = "toilet"
sound_env = SMALL_ENCLOSED
/area/crew_quarters/locker
name = "\improper Locker Room"
@@ -1291,6 +1308,7 @@ area/space/atmosalert()
/area/crew_quarters/locker/locker_toilet
name = "\improper Locker Toilets"
icon_state = "toilet"
sound_env = SMALL_ENCLOSED
/area/crew_quarters/fitness
name = "\improper Fitness Room"
@@ -1327,10 +1345,12 @@ area/space/atmosalert()
/area/crew_quarters/bar
name = "\improper Bar"
icon_state = "bar"
sound_env = LARGE_SOFTFLOOR
/area/crew_quarters/theatre
name = "\improper Theatre"
icon_state = "Theatre"
sound_env = LARGE_SOFTFLOOR
/area/crew_quarters/visitor_lodging
name = "\improper Visitor Lodging"
@@ -1347,6 +1367,7 @@ area/space/atmosalert()
/area/library
name = "\improper Library"
icon_state = "library"
sound_env = LARGE_SOFTFLOOR
/area/library_conference_room
name = "\improper Library Conference Room"
@@ -1356,6 +1377,7 @@ area/space/atmosalert()
name = "\improper Chapel"
icon_state = "chapel"
ambience = list('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg','sound/ambience/ambicha4.ogg','sound/music/traitor.ogg')
sound_env = LARGE_ENCLOSED
/area/chapel/office
name = "\improper Chapel Office"
@@ -1386,6 +1408,7 @@ area/space/atmosalert()
name = "\improper Holodeck"
icon_state = "Holodeck"
lighting_use_dynamic = 0
sound_env = LARGE_ENCLOSED
/area/holodeck/alphadeck
name = "\improper Holodeck Alpha"
@@ -1395,21 +1418,27 @@ area/space/atmosalert()
/area/holodeck/source_emptycourt
name = "\improper Holodeck - Empty Court"
sound_env = ARENA
/area/holodeck/source_boxingcourt
name = "\improper Holodeck - Boxing Court"
sound_env = ARENA
/area/holodeck/source_basketball
name = "\improper Holodeck - Basketball Court"
sound_env = ARENA
/area/holodeck/source_thunderdomecourt
name = "\improper Holodeck - Thunderdome Court"
sound_env = ARENA
/area/holodeck/source_courtroom
name = "\improper Holodeck - Courtroom"
sound_env = AUDITORIUM
/area/holodeck/source_beach
name = "\improper Holodeck - Beach"
sound_env = PLAIN
/area/holodeck/source_burntest
name = "\improper Holodeck - Atmospheric Burn Test"
@@ -1419,22 +1448,28 @@ area/space/atmosalert()
/area/holodeck/source_meetinghall
name = "\improper Holodeck - Meeting Hall"
sound_env = AUDITORIUM
/area/holodeck/source_theatre
name = "\improper Holodeck - Theatre"
sound_env = CONCERT_HALL
/area/holodeck/source_picnicarea
name = "\improper Holodeck - Picnic Area"
sound_env = PLAIN
/area/holodeck/source_snowfield
name = "\improper Holodeck - Snow Field"
sound_env = FOREST
/area/holodeck/source_desert
name = "\improper Holodeck - Desert"
sound_env = PLAIN
/area/holodeck/source_space
name = "\improper Holodeck - Space"
has_gravity = 0
sound_env = SPACE
//Engineering
@@ -1446,26 +1481,32 @@ area/space/atmosalert()
/area/engineering/atmos
name = "\improper Atmospherics"
icon_state = "atmos"
sound_env = LARGE_ENCLOSED
/area/engineering/atmos/monitoring
name = "\improper Atmospherics Monitoring Room"
icon_state = "atmos_monitoring"
sound_env = STANDARD_STATION
/area/engineering/atmos/storage
name = "\improper Atmospherics Storage"
icon_state = "atmos_storage"
sound_env = SMALL_ENCLOSED
/area/engineering/drone_fabrication
name = "\improper Engineering Drone Fabrication"
icon_state = "drone_fab"
sound_env = SMALL_ENCLOSED
/area/engineering/engine_smes
name = "\improper Engineering SMES"
icon_state = "engine_smes"
sound_env = SMALL_ENCLOSED
/area/engineering/engine_room
name = "\improper Engine Room"
icon_state = "engine"
sound_env = LARGE_ENCLOSED
/area/engineering/engine_airlock
name = "\improper Engine Room Airlock"
@@ -1494,6 +1535,7 @@ area/space/atmosalert()
/area/engineering/break_room
name = "\improper Engineering Break Room"
icon_state = "engineering_break"
sound_env = MEDIUM_SOFTFLOOR
/area/engineering/engine_eva
name = "\improper Engine EVA"
@@ -1543,22 +1585,27 @@ area/space/atmosalert()
/area/maintenance/auxsolarport
name = "Solar Maintenance - Fore Port"
icon_state = "SolarcontrolP"
sound_env = SMALL_ENCLOSED
/area/maintenance/starboardsolar
name = "Solar Maintenance - Aft Starboard"
icon_state = "SolarcontrolS"
sound_env = SMALL_ENCLOSED
/area/maintenance/portsolar
name = "Solar Maintenance - Aft Port"
icon_state = "SolarcontrolP"
sound_env = SMALL_ENCLOSED
/area/maintenance/auxsolarstarboard
name = "Solar Maintenance - Fore Starboard"
icon_state = "SolarcontrolS"
sound_env = SMALL_ENCLOSED
/area/maintenance/foresolar
name = "Solar Maintenance - Fore"
icon_state = "SolarcontrolA"
sound_env = SMALL_ENCLOSED
/area/assembly/chargebay
name = "\improper Mech Bay"
@@ -1816,6 +1863,7 @@ area/space/atmosalert()
/area/security/detectives_office
name = "\improper Security - Forensic Office"
icon_state = "detective"
sound_env = MEDIUM_SOFTFLOOR
/area/security/range
name = "\improper Security - Firing Range"
@@ -1914,6 +1962,7 @@ area/space/atmosalert()
/area/quartermaster/storage
name = "\improper Cargo Bay"
icon_state = "quartstorage"
sound_env = LARGE_ENCLOSED
/area/quartermaster/foyer
name = "\improper Cargo Bay Foyer"
@@ -2296,10 +2345,12 @@ area/space/atmosalert()
name = "AI Upload Access"
icon_state = "ai_foyer"
ambience = list('sound/ambience/ambimalf.ogg')
sound_env = SMALL_ENCLOSED
/area/turret_protected/ai_server_room
name = "AI Server Room"
name = "Messaging Server Room"
icon_state = "ai_server"
sound_env = SMALL_ENCLOSED
/area/turret_protected/ai
name = "\improper AI Chamber"
@@ -2309,6 +2360,7 @@ area/space/atmosalert()
/area/turret_protected/ai_cyborg_station
name = "\improper Cyborg Station"
icon_state = "ai_cyborg"
sound_env = SMALL_ENCLOSED
/area/turret_protected/aisat
name = "\improper AI Satellite"

View File

@@ -14,13 +14,17 @@
all_areas += src
if(!requires_power)
power_light = 0 //rastaf0
power_equip = 0 //rastaf0
power_environ = 0 //rastaf0
power_light = 0
power_equip = 0
power_environ = 0
..()
// spawn(15)
/area/proc/initialize()
if(!requires_power || !apc)
power_light = 0
power_equip = 0
power_environ = 0
power_change() // all machines set to current power level, also updates lighting icon
/area/proc/get_contents()
@@ -63,7 +67,7 @@
for(var/obj/machinery/door/firedoor/E in all_doors)
if(!E.blocked)
if(E.operating)
E.nextstate = CLOSED
E.nextstate = FIREDOOR_CLOSED
else if(!E.density)
spawn(0)
E.close()
@@ -74,7 +78,7 @@
for(var/obj/machinery/door/firedoor/E in all_doors)
if(!E.blocked)
if(E.operating)
E.nextstate = OPEN
E.nextstate = FIREDOOR_OPEN
else if(E.density)
spawn(0)
E.open()
@@ -88,7 +92,7 @@
for(var/obj/machinery/door/firedoor/D in all_doors)
if(!D.blocked)
if(D.operating)
D.nextstate = CLOSED
D.nextstate = FIREDOOR_CLOSED
else if(!D.density)
spawn()
D.close()
@@ -101,7 +105,7 @@
for(var/obj/machinery/door/firedoor/D in all_doors)
if(!D.blocked)
if(D.operating)
D.nextstate = OPEN
D.nextstate = FIREDOOR_OPEN
else if(D.density)
spawn(0)
D.open()
@@ -133,7 +137,7 @@
for(var/obj/machinery/door/firedoor/D in src)
if(!D.blocked)
if(D.operating)
D.nextstate = OPEN
D.nextstate = FIREDOOR_OPEN
else if(D.density)
spawn(0)
D.open()
@@ -262,8 +266,8 @@ var/list/mob/living/forced_ambiance_list = new
for(var/mob/M in A)
if(has_gravity)
thunk(M)
M.update_floating( M.Check_Dense_Object() )
thunk(M)
M.update_floating( M.Check_Dense_Object() )
/area/proc/thunk(mob)
if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing.
@@ -271,7 +275,7 @@ var/list/mob/living/forced_ambiance_list = new
if(istype(mob,/mob/living/carbon/human/))
var/mob/living/carbon/human/H = mob
if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP))
if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.item_flags & NOSLIP))
return
if(H.m_intent == "run")

View File

@@ -3,7 +3,7 @@
/area/mine
icon_state = "mining"
music = 'sound/ambience/song_game.ogg'
sound_env = 5 //stoneroom
sound_env = ASTEROID
/area/mine/explored
name = "Mine"

View File

@@ -24,7 +24,7 @@ proc/spawn_room(var/atom/start_loc,var/x_size,var/y_size,var/wall,var/floor , va
if(!wall)
wall = pick(/turf/simulated/wall/r_wall,/turf/simulated/wall,/obj/effect/alien/resin)
if(!floor)
floor = pick(/turf/simulated/floor,/turf/simulated/floor/engine)
floor = pick(/turf/simulated/floor,/turf/simulated/floor/tiled,/turf/simulated/floor/reinforced)
for(var/x = 0,x<x_size,x++)
for(var/y = 0,y<y_size,y++)
@@ -76,9 +76,9 @@ proc/admin_spawn_room_at_pos()
wall=/obj/effect/alien/resin
switch(alert("Floor type",null,"Regular floor","Reinforced floor"))
if("Regular floor")
floor=/turf/simulated/floor
floor=/turf/simulated/floor/tiled
if("Reinforced floor")
floor=/turf/simulated/floor/engine
floor=/turf/simulated/floor/reinforced
if(x && y && z && wall && floor && x_len && y_len)
spawn_room(locate(x,y,z),x_len,y_len,wall,floor,clean)
return

View File

@@ -35,7 +35,7 @@
else
return null
//return flags that should be added to the viewer's sight var.
//return flags that should be added to the viewer's sight var.
//Otherwise return a negative number to indicate that the view should be cancelled.
/atom/proc/check_eye(user as mob)
if (istype(user, /mob/living/silicon/ai)) // WHYYYY
@@ -66,6 +66,8 @@
/atom/proc/CheckExit()
return 1
// If you want to use this, the atom must have the PROXMOVE flag, and the moving
// atom must also have the PROXMOVE flag currently to help with lag. ~ ComicIronic
/atom/proc/HasProximity(atom/movable/AM as mob|obj)
return
@@ -213,7 +215,7 @@ its easier to just keep the beam vertical.
/atom/proc/ex_act()
return
/atom/proc/emag_act(var/remaining_charges, var/mob/user, var/emag_source)
return -1
@@ -411,7 +413,6 @@ its easier to just keep the beam vertical.
/atom/proc/clean_blood()
if(!simulated)
return
src.color = initial(src.color) //paint
src.germ_level = 0
if(istype(blood_DNA, /list))
del(blood_DNA)

View File

@@ -21,9 +21,14 @@
if(auto_init && ticker && ticker.current_state == GAME_STATE_PLAYING)
initialize()
/proc/generate_debug_runtime() // Guaranteed to runtime and print a stack trace to the runtime log
var/t = 0 // BYOND won't let us do var/t = 1/0 directly, but it's fine with this.
t = 1 / t
/atom/movable/Del()
if(isnull(gcDestroyed) && loc)
testing("GC: -- [type] was deleted via del() rather than qdel() --")
generate_debug_runtime() // stick a stack trace in the runtime logs
// else if(isnull(gcDestroyed))
// testing("GC: [type] was deleted via GC without qdel()") //Not really a huge issue but from now on, please qdel()
// else
@@ -34,6 +39,7 @@
. = ..()
if(reagents)
qdel(reagents)
reagents = null
for(var/atom/movable/AM in contents)
qdel(AM)
loc = null
@@ -164,7 +170,7 @@
a = get_area(src.loc)
else
var/error = dist_y/2 - dist_x
while(src && target &&((((src.y < target.y && dy == NORTH) || (src.y > target.y && dy == SOUTH)) && dist_travelled < range) || (a.has_gravity == 0) || istype(src.loc, /turf/space)) && src.throwing && istype(src.loc, /turf))
while(src && target &&((((src.y < target.y && dy == NORTH) || (src.y > target.y && dy == SOUTH)) && dist_travelled < range) || (a && a.has_gravity == 0) || istype(src.loc, /turf/space)) && src.throwing && istype(src.loc, /turf))
// only stop when we've gone the whole distance (or max throw range) and are on a non-space tile, or hit something, or hit the end of the map, or someone picks it up
if(error < 0)
var/atom/step = get_step(src, dx)

View File

@@ -1,6 +1,6 @@
// Returns the lowest turf available on a given Z-level, defaults to space.
var/global/list/base_turf_by_z = list(
"5" = /turf/simulated/floor/plating/airless/asteroid // Moonbase.
"5" = /turf/simulated/floor/asteroid // Moonbase.
)
proc/get_base_turf(var/z)

View File

@@ -218,7 +218,8 @@
name = "DNA Modifier Access Console"
desc = "Scand DNA."
icon = 'icons/obj/computer.dmi'
icon_state = "scanner"
icon_keyboard = "med_key"
icon_screen = "dna"
density = 1
circuit = /obj/item/weapon/circuitboard/scan_consolenew
var/selected_ui_block = 1.0
@@ -270,21 +271,9 @@
return
/obj/machinery/computer/scan_consolenew/blob_act()
if(prob(75))
qdel(src)
/obj/machinery/computer/scan_consolenew/power_change()
..()
if(stat & BROKEN)
icon_state = "broken"
else
if (stat & NOPOWER)
spawn(rand(0, 15))
src.icon_state = "c_unpowered"
else
icon_state = initial(icon_state)
/obj/machinery/computer/scan_consolenew/New()
..()
for(var/i=0;i<3;i++)

View File

@@ -157,6 +157,7 @@
attackby(var/obj/item/weapon/W, var/mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
src.visible_message("<span class='danger'>The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
var/damage = 0

View File

@@ -2,7 +2,15 @@
antag_tag = MODE_CHANGELING
name = "changeling"
round_description = "There are alien changelings on the station. Do not let the changelings succeed!"
extended_round_description = "Life always finds a way. However, life can sometimes take a more disturbing route. Humanity's extensive knowledge of xeno-biological specimens has made them confident and arrogant. Yet something slipped past their eyes. Something dangerous. Something alive. Most frightening of all, however, is that this something is someone. An unknown alien specimen has incorporated itself into the crew of the NSS Exodus. Its unique biology allows it to manipulate its own or anyone else's DNA. With the ability to copy faces, voices, animals, but also change the chemical make up of your own body, its existence is a threat to not only your personal safety but the lives of everyone on board. No one knows where it came from. No one knows who it is or what it wants. One thing is for certain though... there is never just one of them. Good luck."
extended_round_description = "Life always finds a way. However, life can sometimes take a more disturbing route. \
Humanity's extensive knowledge of xeno-biological specimens has made them confident and arrogant. Yet \
something slipped past their eyes. Something dangerous. Something alive. Most frightening of all, \
however, is that this something is someone. An unknown alien specimen has incorporated itself into \
the crew of the station. Its unique biology allows it to manipulate its own or anyone else's DNA. \
With the ability to copy faces, voices, animals, but also change the chemical make up of your own body, \
its existence is a threat to not only your personal safety but the lives of everyone on board. \
No one knows where it came from. No one knows who it is or what it wants. One thing is for \
certain though... there is never just one of them. Good luck."
config_tag = "changeling"
required_players = 2
required_players_secret = 10

View File

@@ -35,8 +35,7 @@
icon_state = "culthood"
desc = "A hood worn by the followers of Nar-Sie."
flags_inv = HIDEFACE
flags = HEADCOVERSEYES
body_parts_covered = HEAD|EYES
body_parts_covered = HEAD
armor = list(melee = 30, bullet = 10, laser = 5,energy = 5, bomb = 0, bio = 0, rad = 0)
cold_protection = HEAD
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
@@ -49,8 +48,7 @@
name = "magus helm"
icon_state = "magus"
desc = "A helm worn by the followers of Nar-Sie."
flags_inv = HIDEFACE
flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR
flags_inv = HIDEFACE | BLOCKHAIR
body_parts_covered = HEAD|FACE|EYES
/obj/item/clothing/head/culthood/alt

View File

@@ -127,17 +127,12 @@
T.ChangeTurf(/turf/simulated/wall/cult)
..()
/obj/structure/stool/cultify()
var/obj/structure/bed/chair/wood/wings/I = new(loc)
I.dir = dir
..()
/obj/structure/table/cultify()
// Make it a wood-reinforced wooden table.
// There are cult materials available, but it'd make the table non-deconstructable with how holotables work.
// Could possibly use a new material var for holographic-ness?
material = name_to_material["wood"]
reinforced = name_to_material["wood"]
material = get_material_by_name("wood")
reinforced = get_material_by_name("wood")
update_desc()
update_connections(1)
update_icon()

View File

@@ -3,11 +3,9 @@
return
/turf/simulated/floor/cultify()
//todo: flooring datum cultify check
cultify_floor()
/turf/simulated/floor/carpet/cultify()
return
/turf/simulated/shuttle/floor/cultify()
cultify_floor()
@@ -39,8 +37,6 @@
if((icon_state != "cult")&&(icon_state != "cult-narsie"))
name = "engraved floor"
icon_state = "cult"
turf_animation('icons/effects/effects.dmi',"cultfloor",0,0,MOB_LAYER-1)
/turf/proc/cultify_wall()
ChangeTurf(/turf/unsimulated/wall/cult)
turf_animation('icons/effects/effects.dmi',"cultwall",0,0,MOB_LAYER-1)

View File

@@ -144,6 +144,7 @@ var/global/list/narsie_list = list()
if(!(istype(T, /turf/simulated/wall/cult)||istype(T, /turf/space)))
if(T.icon_state != "cult-narsie")
T.desc = "something that goes beyond your understanding went this way"
T.icon = 'icons/turf/flooring/cult.dmi'
T.icon_state = "cult-narsie"
T.set_light(1)

View File

@@ -339,7 +339,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
attack(mob/living/M as mob, mob/living/user as mob)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had the [name] used on him by [user.name] ([user.ckey])</font>")
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had the [name] used on them by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used [name] on [M.name] ([M.ckey])</font>")
msg_admin_attack("[user.name] ([user.ckey]) used [name] on [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")

View File

@@ -5,6 +5,14 @@ var/list/sacrificed = list()
/obj/effect/rune
/*
* Use as a general guideline for this and related files:
* * <span class='warning'>...</span> - when something non-trivial or an error happens, so something similar to "Sparks come out of the machine!"
* * <span class='danger'>...</span> - when something that is fit for 'warning' happens but there is some damage or pain as well.
* * <span class='cult'>...</span> - when there is a private message to the cultists. This guideline is very arbitrary but there has to be some consistency!
*/
/////////////////////////////////////////FIRST RUNE
proc
teleport(var/key)
@@ -21,7 +29,7 @@ var/list/sacrificed = list()
allrunesloc.len = index
allrunesloc[index] = R.loc
if(index >= 5)
user << "<span class='warning'>You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric</span>"
user << "<span class='danger'>You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric.</span>"
if (istype(user, /mob/living))
user.take_overall_damage(5, 0)
qdel(src)
@@ -30,9 +38,9 @@ var/list/sacrificed = list()
user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting
else
user.whisper("Sas[pick("'","`")]so c'arta forbici!")
user.visible_message("<span class='warning'>\The [user] disappears in a flash of red light!</span>", \
"<span class='warning'>You feel as your body gets dragged through the dimension of Nar-Sie!</span>", \
"<span class='warning'>You hear a sickening crunch and sloshing of viscera.</span>")
user.visible_message("<span class='danger'>[user] disappears in a flash of red light!</span>", \
"<span class='danger'>You feel as your body gets dragged through the dimension of Nar-Sie!</span>", \
"<span class='danger'>You hear a sickening crunch and sloshing of viscera.</span>")
user.loc = allrunesloc[rand(1,index)]
return
if(istype(src,/obj/effect/rune))
@@ -58,7 +66,7 @@ var/list/sacrificed = list()
IP = R
runecount++
if(runecount >= 2)
user << "<span class='warning'>You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric</span>"
user << "<span class='danger'>You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric.</span>"
if (istype(user, /mob/living))
user.take_overall_damage(5, 0)
qdel(src)
@@ -134,11 +142,11 @@ var/list/sacrificed = list()
admin_attack_log(attacker, target, "Used a convert rune", "Was subjected to a convert rune", "used a convert rune on")
switch(target.getFireLoss())
if(0 to 25)
target << "<span class='danger'>Your blood boils as you force yourself to resist the corruption invading every corner of your mind.</span>"
target << "<span class='cult'>Your blood boils as you force yourself to resist the corruption invading every corner of your mind.</span>"
if(25 to 45)
target << "<span class='danger'>Your blood boils and your body burns as the corruption further forces itself into your body and mind.</span>"
target << "<span class='cult'>Your blood boils and your body burns as the corruption further forces itself into your body and mind.</span>"
if(45 to 75)
target << "<span class='danger'>You begin to hallucinate images of a dark and incomprehensible being and your entire body feels like its engulfed in flame as your mental defenses crumble.</span>"
target << "<span class='cult'>You begin to hallucinate images of a dark and incomprehensible being and your entire body feels like its engulfed in flame as your mental defenses crumble.</span>"
target.apply_effect(rand(1,10), STUTTER)
if(75 to 100)
target << "<span class='cult'>Your mind turns to ash as the burning flames engulf your very soul and images of an unspeakable horror begin to bombard the last remnants of mental resistance.</span>"
@@ -157,7 +165,7 @@ var/list/sacrificed = list()
if (target.species && (target.species.flags & NO_PAIN))
target.visible_message("<span class='warning'>The markings below [target] glow a bloody red.</span>")
else
target.visible_message("<span class='warning'>\The [target] writhes in pain as the markings below \him glow a bloody red.</span>", "<span class='danger'>AAAAAAHHHH!</span>", "<span class='warning'>You hear an anguished scream.</span>")
target.visible_message("<span class='warning'>[target] writhes in pain as the markings below \him glow a bloody red.</span>", "<span class='danger'>AAAAAAHHHH!</span>", "<span class='warning'>You hear an anguished scream.</span>")
if(!waiting_for_input[target]) //so we don't spam them with dialogs if they hesitate
waiting_for_input[target] = 1
@@ -229,15 +237,15 @@ var/list/sacrificed = list()
if(!drain)
return fizzle()
usr.say ("Yu[pick("'","`")]gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!")
usr.visible_message("<span class='warning'>Blood flows from the rune into [usr]!</span>", \
"<span class='warning'>The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.</span>", \
usr.visible_message("<span class='danger'>Blood flows from the rune into [usr]!</span>", \
"<span class='danger'>The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.</span>", \
"<span class='warning'>You hear a liquid flowing.</span>")
var/mob/living/user = usr
if(user.bhunger)
user.bhunger = max(user.bhunger-2*drain,0)
if(drain>=50)
user.visible_message("<span class='warning'>\The [user]'s eyes give off eerie red glow!</span>", \
"<span class='warning'>...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.</span>", \
user.visible_message("<span class='danger'>[user]'s eyes give off eerie red glow!</span>", \
"<span class='danger'>...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.</span>", \
"<span class='warning'>You hear a heartbeat.</span>")
user.bhunger += drain
src = user
@@ -264,7 +272,7 @@ var/list/sacrificed = list()
if(usr.loc==src.loc)
if(usr.seer==1)
usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.")
usr << "<span class='warning'>The world beyond fades from your vision.</span>"
usr << "<span class='danger'>The world beyond fades from your vision.</span>"
usr.see_invisible = SEE_INVISIBLE_LIVING
usr.seer = 0
else if(usr.see_invisible!=SEE_INVISIBLE_LIVING)
@@ -336,12 +344,12 @@ var/list/sacrificed = list()
corpse_to_raise.key = ghost.key //the corpse will keep its old mind! but a new player takes ownership of it (they are essentially possessed)
//This means, should that player leave the body, the original may re-enter
usr.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!")
corpse_to_raise.visible_message("<span class='warning'>\The [corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.</span>", \
corpse_to_raise.visible_message("<span class='warning'>[corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.</span>", \
"<span class='warning'>Life... I'm alive again...</span>", \
"<span class='warning'>You hear a faint, slightly familiar whisper.</span>")
body_to_sacrifice.visible_message("<span class='warning'>\The [body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from his remains!</span>", \
"<span class='warning'>You feel as your blood boils, tearing you apart.</span>", \
"<span class='warning'>You hear a thousand voices, all crying in pain.</span>")
body_to_sacrifice.visible_message("<span class='danger'>[body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from \his remains!</span>", \
"<span class='danger'>You feel as your blood boils, tearing you apart.</span>", \
"<span class='danger'>You hear a thousand voices, all crying in pain.</span>")
body_to_sacrifice.gib()
// if(ticker.mode.name == "cult")
@@ -349,8 +357,8 @@ var/list/sacrificed = list()
// else
// ticker.mode.cult |= corpse_to_raise.mind
corpse_to_raise << "<font color=\"purple\"><b><i>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root.</b></i></font>"
corpse_to_raise << "<font color=\"purple\"><b><i>Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.</b></i></font>"
corpse_to_raise << "<span class='cult'>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root.</span>"
corpse_to_raise << "<span class='cult'>Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.</span>"
return
@@ -391,7 +399,7 @@ var/list/sacrificed = list()
if(usr.loc==src.loc)
var/mob/living/carbon/human/L = usr
usr.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!")
usr.visible_message("<span class='warning'>\The [usr]'s eyes glow blue as \he freezes in place, absolutely motionless.</span>", \
usr.visible_message("<span class='warning'>[usr]'s eyes glow blue as \he freezes in place, absolutely motionless.</span>", \
"<span class='warning'>The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...</span>", \
"<span class='warning'>You hear only complete silence for a moment.</span>")
announce_ghost_joinleave(usr.ghostize(1), 1, "You feel that they had to use some [pick("dark", "black", "blood", "forgotten", "forbidden")] magic to [pick("invade","disturb","disrupt","infest","taint","spoil","blight")] this place!")
@@ -461,8 +469,8 @@ var/list/sacrificed = list()
user.take_organ_damage(1, 0)
sleep(30)
if(D)
D.visible_message("<span class='warning'>\The [D] slowly dissipates into dust and bones.</span>", \
"<span class='warning'>You feel pain, as bonds formed between your soul and this homunculus break.</span>", \
D.visible_message("<span class='danger'>[D] slowly dissipates into dust and bones.</span>", \
"<span class='danger'>You feel pain, as bonds formed between your soul and this homunculus break.</span>", \
"<span class='warning'>You hear faint rustle.</span>")
D.dust()
return
@@ -560,8 +568,8 @@ var/list/sacrificed = list()
user.say("Uhrast ka'hfa heldsagen ver[pick("'","`")]lot!")
user.take_overall_damage(200, 0)
runedec+=10
user.visible_message("<span class='warning'>\The [user] keels over dead, his blood glowing blue as it escapes his body and dissipates into thin air.</span>", \
"<span class='warning'>In the last moment of your humble life, you feel an immense pain as fabric of reality mends... with your blood.</span>", \
user.visible_message("<span class='danger'>\The [user] keels over dead, \his blood glowing blue as it escapes \his body and dissipates into thin air.</span>", \
"<span class='danger'>In the last moment of your humble life, you feel an immense pain as fabric of reality mends... with your blood.</span>", \
"<span class='warning'>You hear faint rustle.</span>")
for(,user.stat==2)
sleep(600)
@@ -595,7 +603,7 @@ var/list/sacrificed = list()
log_and_message_admins("used a communicate rune to say '[input]'")
for(var/datum/mind/H in cult.current_antagonists)
if (H.current)
H.current << "<span class='danger'>[input]</span>"
H.current << "<span class='cult'>[input]</span>"
qdel(src)
return 1
@@ -639,17 +647,17 @@ var/list/sacrificed = list()
H.dust()//To prevent the MMI from remaining
else
H.gib()
usr << "<span class='warning'>The Geometer of Blood accepts this sacrifice, your objective is now complete.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice, your objective is now complete.</span>"
else
usr << "<span class='warning'>Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual.</span>"
else
if(cultsinrange.len >= 3)
if(H.stat !=2)
if(prob(80) || worth)
usr << "<span class='warning'>The Geometer of Blood accepts this [worth ? "exotic " : ""]sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this [worth ? "exotic " : ""]sacrifice.</span>"
cult.grant_runeword(usr)
else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, this soul was not enough to gain His favor.</span>"
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -657,10 +665,10 @@ var/list/sacrificed = list()
H.gib()
else
if(prob(40) || worth)
usr << "<span class='warning'>The Geometer of blood accepts this [worth ? "exotic " : ""]sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this [worth ? "exotic " : ""]sacrifice.</span>"
cult.grant_runeword(usr)
else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>"
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -672,10 +680,10 @@ var/list/sacrificed = list()
else
if(prob(40))
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
cult.grant_runeword(usr)
else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>"
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -685,10 +693,10 @@ var/list/sacrificed = list()
if(cultsinrange.len >= 3)
if(H.stat !=2)
if(prob(80))
usr << "<span class='warning'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
cult.grant_runeword(usr)
else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, this soul was not enough to gain His favor.</span>"
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -696,10 +704,10 @@ var/list/sacrificed = list()
H.gib()
else
if(prob(40))
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
cult.grant_runeword(usr)
else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>"
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -710,10 +718,10 @@ var/list/sacrificed = list()
usr << "<span class='warning'>The victim is still alive, you will need more cultists chanting for the sacrifice to succeed.</span>"
else
if(prob(40))
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
cult.grant_runeword(usr)
else
usr << "<span class='warning'>The Geometer of blood accepts this sacrifice.</span>"
usr << "<span class='cult'>The Geometer of Blood accepts this sacrifice.</span>"
usr << "<span class='warning'>However, a mere dead body is not enough to satisfy Him.</span>"
if(isrobot(H))
H.dust()//To prevent the MMI from remaining
@@ -772,9 +780,9 @@ var/list/sacrificed = list()
var/mob/living/user = usr
user.take_organ_damage(2, 0)
if(src.density)
usr << "<span class='warning'>Your blood flows into the rune, and you feel that the very space over the rune thickens.</span>"
usr << "<span class='danger'>Your blood flows into the rune, and you feel that the very space over the rune thickens.</span>"
else
usr << "<span class='warning'>Your blood flows into the rune, and you feel as the rune releases its grasp on space.</span>"
usr << "<span class='danger'>Your blood flows into the rune, and you feel as the rune releases its grasp on space.</span>"
return
/////////////////////////////////////////EIGHTTEENTH RUNE
@@ -843,7 +851,7 @@ var/list/sacrificed = list()
if (cultist == user) //just to be sure.
return
if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet)))
user << "<span class='warning'>You cannot summon \the [cultist], for his shackles of blood are strong.</span>"
user << "<span class='warning'>You cannot summon \the [cultist], for \his shackles of blood are strong.</span>"
return fizzle()
cultist.loc = src.loc
cultist.lying = 1
@@ -923,7 +931,7 @@ var/list/sacrificed = list()
C.disabilities |= NEARSIGHTED
if(prob(10))
C.sdisabilities |= BLIND
C.show_message("<span class='warning'>Suddenly you see red flash that blinds you.</span>", 3)
C.show_message("<span class='warning'>Suddenly you see a red flash that blinds you.</span>", 3)
affected += C
if(affected.len)
usr.say("Sti[pick("'","`")] kaliesin!")
@@ -973,7 +981,7 @@ var/list/sacrificed = list()
if(N)
continue
M.take_overall_damage(51,51)
M << "<span class='warning'>Your blood boils!</span>"
M << "<span class='danger'>Your blood boils!</span>"
victims += M
if(prob(5))
spawn(5)
@@ -1005,16 +1013,16 @@ var/list/sacrificed = list()
for(var/mob/living/M in orange(2,R))
M.take_overall_damage(0,15)
if (R.invisibility>M.see_invisible)
M << "<span class='warning'>Aargh it burns!</span>"
M << "<span class='danger'>Aargh it burns!</span>"
else
M << "<span class='warning'>Rune suddenly ignites, burning you!</span>"
M << "<span class='danger'>Rune suddenly ignites, burning you!</span>"
var/turf/T = get_turf(R)
T.hotspot_expose(700,125)
for(var/obj/effect/decal/cleanable/blood/B in world)
if(B.blood_DNA == src.blood_DNA)
for(var/mob/living/M in orange(1,B))
M.take_overall_damage(0,5)
M << "<span class='warning'>Blood suddenly ignites, burning you!</span>"
M << "<span class='danger'>Blood suddenly ignites, burning you!</span>"
var/turf/T = get_turf(B)
T.hotspot_expose(700,125)
qdel(B)
@@ -1033,13 +1041,13 @@ var/list/sacrificed = list()
C.stuttering = 1
C.Weaken(1)
C.Stun(1)
C.show_message("<span class='warning'>The rune explodes in a bright flash.</span>", 3)
C.show_message("<span class='danger'>The rune explodes in a bright flash.</span>", 3)
admin_attack_log(usr, C, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on")
else if(issilicon(L))
var/mob/living/silicon/S = L
S.Weaken(5)
S.show_message("<span class='warning'>BZZZT... The rune has exploded in a bright flash.</span>", 3)
S.show_message("<span class='danger'>BZZZT... The rune has exploded in a bright flash.</span>", 3)
admin_attack_log(usr, S, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on")
qdel(src)
else ///When invoked as talisman, stun and mute the target mob.
@@ -1047,10 +1055,10 @@ var/list/sacrificed = list()
var/obj/item/weapon/nullrod/N = locate() in T
if(N)
for(var/mob/O in viewers(T, null))
O.show_message("<span class='danger'>\The [usr] invokes a talisman at [T], but they are unaffected!</span>", 1)
O.show_message(text("<span class='warning'><B>[] invokes a talisman at [], but they are unaffected!</B></span>", usr, T), 1)
else
for(var/mob/O in viewers(T, null))
O.show_message("<span class='danger'>\The [usr] invokes a talisman at [T]</span>", 1)
O.show_message(text("<span class='warning'><B>[] invokes a talisman at []</B></span>", usr, T), 1)
if(issilicon(T))
T.Weaken(15)

View File

@@ -167,7 +167,13 @@ var/global/list/additional_antag_types = list()
return 1
var/datum/antagonist/main_antags = antag_templates[1]
if(main_antags.candidates.len >= required_enemies)
var/list/potential
if(main_antags.flags & ANTAG_OVERRIDE_JOB)
potential = main_antags.pending_antagonists
else
potential = main_antags.candidates
if(potential.len >= required_enemies)
return 1
return 0
@@ -184,7 +190,7 @@ var/global/list/additional_antag_types = list()
/datum/game_mode/proc/pre_setup()
for(var/datum/antagonist/antag in antag_templates)
antag.build_candidate_list() //compile a list of all eligible candidates
//antag roles that replace jobs need to be assigned before the job controller hands out jobs.
if(antag.flags & ANTAG_OVERRIDE_JOB)
antag.attempt_spawn() //select antags to be spawned
@@ -280,14 +286,13 @@ var/global/list/additional_antag_types = list()
/datum/game_mode/proc/declare_completion()
var/is_antag_mode = (antag_templates && antag_templates.len)
if(!config.objectives_disabled)
check_victory()
if(is_antag_mode)
check_victory()
if(is_antag_mode)
sleep(10)
for(var/datum/antagonist/antag in antag_templates)
sleep(10)
for(var/datum/antagonist/antag in antag_templates)
sleep(10)
antag.check_victory()
antag.print_player_summary()
antag.check_victory()
antag.print_player_summary()
var/clients = 0
var/surviving_humans = 0
@@ -389,8 +394,8 @@ var/global/list/additional_antag_types = list()
if (special_role in disregard_roles)
continue
else if(man.client.prefs.nanotrasen_relation == "Opposed" && prob(50) || \
man.client.prefs.nanotrasen_relation == "Skeptical" && prob(20))
else if(man.client.prefs.nanotrasen_relation == COMPANY_OPPOSED && prob(50) || \
man.client.prefs.nanotrasen_relation == COMPANY_SKEPTICAL && prob(20))
suspects += man
// Antags
else if(special_role_data && prob(special_role_data.suspicion_chance))
@@ -427,32 +432,26 @@ var/global/list/additional_antag_types = list()
if(!antag_template)
return candidates
var/roletext
// Assemble a list of active players without jobbans.
for(var/mob/new_player/player in player_list)
if( player.client && player.ready )
if(!(jobban_isbanned(player, "Syndicate") || jobban_isbanned(player, antag_template.bantype)))
players += player
// Shuffle the players list so that it becomes ping-independent.
players = shuffle(players)
players += player
// Get a list of all the people who want to be the antagonist for this round
for(var/mob/new_player/player in players)
if(!role || (player.client.prefs.be_special & role))
log_debug("[player.key] had [roletext] enabled, so we are drafting them.")
log_debug("[player.key] had [antag_id] enabled, so we are drafting them.")
candidates += player.mind
players -= player
// If we don't have enough antags, draft people who voted for the round.
if(candidates.len < required_enemies)
for(var/key in round_voters)
for(var/mob/new_player/player in players)
if(player.ckey == key)
log_debug("[player.key] voted for this round, so we are drafting them.")
candidates += player.mind
players -= player
break
for(var/mob/new_player/player in players)
if(player.ckey in round_voters)
log_debug("[player.key] voted for this round, so we are drafting them.")
candidates += player.mind
players -= player
break
return candidates // Returns: The number of people who had the antagonist role set to yes, regardless of recomended_enemies, if that number is greater than required_enemies
// required_enemies if the number of people with that role set to yes is less than recomended_enemies,
@@ -485,12 +484,14 @@ var/global/list/additional_antag_types = list()
if(antag)
antag_templates |= antag
/*
if(antag_templates && antag_templates.len)
for(var/datum/antagonist/antag in antag_templates)
if(antag.flags & (ANTAG_OVERRIDE_JOB|ANTAG_RANDSPAWN))
continue
antag_templates -= antag
world << "<span class='danger'>[antag.role_text_plural] are invalid for additional roundtype antags!</span>"
*/
newscaster_announcements = pick(newscaster_standard_feeds)
@@ -556,9 +557,9 @@ proc/get_nt_opposed()
var/list/dudes = list()
for(var/mob/living/carbon/human/man in player_list)
if(man.client)
if(man.client.prefs.nanotrasen_relation == "Opposed")
if(man.client.prefs.nanotrasen_relation == COMPANY_OPPOSED)
dudes += man
else if(man.client.prefs.nanotrasen_relation == "Skeptical" && prob(50))
else if(man.client.prefs.nanotrasen_relation == COMPANY_SKEPTICAL && prob(50))
dudes += man
if(dudes.len == 0) return null
return pick(dudes)

View File

@@ -90,7 +90,7 @@
/datum/intercept_text/proc/get_suspect()
var/list/dudes = list()
for(var/mob/living/carbon/human/man in player_list) if(man.client && man.client.prefs.nanotrasen_relation == "Opposed")
for(var/mob/living/carbon/human/man in player_list) if(man.client && man.client.prefs.nanotrasen_relation == COMPANY_OPPOSED)
dudes += man
for(var/i = 0, i < max(player_list.len/10,2), i++)
dudes += pick(player_list)

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