mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-16 13:12:22 +00:00
Merge branch 'master' of https://github.com/PolarisSS13/Polaris into woodrat_map
This commit is contained in:
28
.github/workflows/ci.yml
vendored
28
.github/workflows/ci.yml
vendored
@@ -24,6 +24,34 @@ jobs:
|
||||
tools/ci/validate_files.sh
|
||||
tools/ci/build_tgui.sh
|
||||
|
||||
dreamchecker:
|
||||
name: DreamChecker
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Cache SpacemanDMM
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/SpacemanDMM
|
||||
key: ${{ runner.os }}-dreamchecker-${{ hashFiles('dependencies.sh')}}
|
||||
restore-keys: ${{ runner.os }}-dreamchecker
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
tools/ci/install_spaceman_dmm.sh dreamchecker
|
||||
|
||||
- name: Run Linter
|
||||
id: linter
|
||||
run: |
|
||||
~/dreamchecker > ${GITHUB_WORKSPACE}/output-annotations.txt 2>&1
|
||||
|
||||
- name: Annotate Linter
|
||||
uses: yogstation13/DreamAnnotate@v1
|
||||
if: always()
|
||||
with:
|
||||
outputFile: output-annotations.txt
|
||||
|
||||
unit_tests:
|
||||
name: Integration Tests
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
[diagnostics]
|
||||
macro_redefined = "off"
|
||||
macro_undefined_no_definition = "off"
|
||||
as_local_var = "off"
|
||||
tmp_no_effect = "off"
|
||||
|
||||
[langserver]
|
||||
dreamchecker = true
|
||||
|
||||
[code_standards]
|
||||
disallow_relative_type_definitions = true
|
||||
disallow_relative_proc_definitions = true
|
||||
@@ -1,6 +1,6 @@
|
||||
# This file has all the information on what versions of libraries are thrown into the code
|
||||
# For dreamchecker
|
||||
export SPACEMANDMM_TAG=suite-1.4
|
||||
export SPACEMAN_DMM_VERSION=suite-1.7
|
||||
# For NanoUI + TGUI
|
||||
export NODE_VERSION=12
|
||||
# Byond Major
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
//node1, air1, network1 correspond to input
|
||||
//node2, air2, network2 correspond to output
|
||||
|
||||
#define ADIABATIC_EXPONENT 0.667 //Actually adiabatic exponent - 1.
|
||||
|
||||
/obj/machinery/atmospherics/binary/circulator
|
||||
name = "circulator"
|
||||
desc = "A gas circulator turbine and heat exchanger."
|
||||
|
||||
@@ -1,288 +0,0 @@
|
||||
#define ADIABATIC_EXPONENT 0.667 //Actually adiabatic exponent - 1.
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine
|
||||
name = "turbine"
|
||||
desc = "A gas turbine. Converting pressure into energy since 1884."
|
||||
icon = 'icons/obj/pipeturbine.dmi'
|
||||
icon_state = "turbine"
|
||||
anchored = 0
|
||||
density = 1
|
||||
|
||||
var/efficiency = 0.4
|
||||
var/kin_energy = 0
|
||||
var/datum/gas_mixture/air_in = new
|
||||
var/datum/gas_mixture/air_out = new
|
||||
var/volume_ratio = 0.2
|
||||
var/kin_loss = 0.001
|
||||
|
||||
var/dP = 0
|
||||
|
||||
var/datum/pipe_network/network1
|
||||
var/datum/pipe_network/network2
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/New()
|
||||
..()
|
||||
air_in.volume = 200
|
||||
air_out.volume = 800
|
||||
volume_ratio = air_in.volume / (air_in.volume + air_out.volume)
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
initialize_directions = EAST|WEST
|
||||
if(SOUTH)
|
||||
initialize_directions = EAST|WEST
|
||||
if(EAST)
|
||||
initialize_directions = NORTH|SOUTH
|
||||
if(WEST)
|
||||
initialize_directions = NORTH|SOUTH
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/Destroy()
|
||||
. = ..()
|
||||
|
||||
if(node1)
|
||||
node1.disconnect(src)
|
||||
qdel(network1)
|
||||
if(node2)
|
||||
node2.disconnect(src)
|
||||
qdel(network2)
|
||||
|
||||
node1 = null
|
||||
node2 = null
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/process()
|
||||
..()
|
||||
if(anchored && !(stat&BROKEN))
|
||||
kin_energy *= 1 - kin_loss
|
||||
dP = max(air_in.return_pressure() - air_out.return_pressure(), 0)
|
||||
if(dP > 10)
|
||||
kin_energy += 1/ADIABATIC_EXPONENT * dP * air_in.volume * (1 - volume_ratio**ADIABATIC_EXPONENT) * efficiency
|
||||
air_in.temperature *= volume_ratio**ADIABATIC_EXPONENT
|
||||
|
||||
var/datum/gas_mixture/air_all = new
|
||||
air_all.volume = air_in.volume + air_out.volume
|
||||
air_all.merge(air_in.remove_ratio(1))
|
||||
air_all.merge(air_out.remove_ratio(1))
|
||||
|
||||
air_in.merge(air_all.remove(volume_ratio))
|
||||
air_out.merge(air_all)
|
||||
|
||||
update_icon()
|
||||
|
||||
if (network1)
|
||||
network1.update = 1
|
||||
if (network2)
|
||||
network2.update = 1
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/update_icon()
|
||||
overlays.Cut()
|
||||
if (dP > 10)
|
||||
overlays += image('icons/obj/pipeturbine.dmi', "moto-turb")
|
||||
if (kin_energy > 100000)
|
||||
overlays += image('icons/obj/pipeturbine.dmi', "low-turb")
|
||||
if (kin_energy > 500000)
|
||||
overlays += image('icons/obj/pipeturbine.dmi', "med-turb")
|
||||
if (kin_energy > 1000000)
|
||||
overlays += image('icons/obj/pipeturbine.dmi', "hi-turb")
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(W.is_wrench())
|
||||
anchored = !anchored
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "secure" : "unsecure"] the bolts holding \the [src] to the floor.</span>")
|
||||
|
||||
if(anchored)
|
||||
if(dir & (NORTH|SOUTH))
|
||||
initialize_directions = EAST|WEST
|
||||
else if(dir & (EAST|WEST))
|
||||
initialize_directions = NORTH|SOUTH
|
||||
|
||||
atmos_init()
|
||||
build_network()
|
||||
if (node1)
|
||||
node1.atmos_init()
|
||||
node1.build_network()
|
||||
if (node2)
|
||||
node2.atmos_init()
|
||||
node2.build_network()
|
||||
else
|
||||
if(node1)
|
||||
node1.disconnect(src)
|
||||
qdel(network1)
|
||||
if(node2)
|
||||
node2.disconnect(src)
|
||||
qdel(network2)
|
||||
|
||||
node1 = null
|
||||
node2 = null
|
||||
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/verb/rotate_clockwise()
|
||||
set name = "Rotate Turbine Clockwise"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if (usr.stat || usr.restrained() || anchored)
|
||||
return
|
||||
|
||||
src.set_dir(turn(src.dir, 270))
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/verb/rotate_counterclockwise()
|
||||
set name = "Rotate Turbine Counterclockwise"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if (usr.stat || usr.restrained() || anchored)
|
||||
return
|
||||
|
||||
src.set_dir(turn(src.dir, 90))
|
||||
|
||||
//Goddamn copypaste from binary base class because atmospherics machinery API is not damn flexible
|
||||
/obj/machinery/atmospherics/pipeturbine/get_neighbor_nodes_for_init()
|
||||
return list(node1, node2)
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
|
||||
if(reference == node1)
|
||||
network1 = new_network
|
||||
|
||||
else if(reference == node2)
|
||||
network2 = new_network
|
||||
|
||||
if(new_network.normal_members.Find(src))
|
||||
return 0
|
||||
|
||||
new_network.normal_members += src
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/atmos_init()
|
||||
if(node1 && node2)
|
||||
return
|
||||
|
||||
var/node2_connect = turn(dir, -90)
|
||||
var/node1_connect = turn(dir, 90)
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node1 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node2 = target
|
||||
break
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/build_network()
|
||||
if(!network1 && node1)
|
||||
network1 = new /datum/pipe_network()
|
||||
network1.normal_members += src
|
||||
network1.build_network(node1, src)
|
||||
|
||||
if(!network2 && node2)
|
||||
network2 = new /datum/pipe_network()
|
||||
network2.normal_members += src
|
||||
network2.build_network(node2, src)
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/return_network(obj/machinery/atmospherics/reference)
|
||||
build_network()
|
||||
|
||||
if(reference==node1)
|
||||
return network1
|
||||
|
||||
if(reference==node2)
|
||||
return network2
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
|
||||
if(network1 == old_network)
|
||||
network1 = new_network
|
||||
if(network2 == old_network)
|
||||
network2 = new_network
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/return_network_air(datum/pipe_network/reference)
|
||||
var/list/results = list()
|
||||
|
||||
if(network1 == reference)
|
||||
results += air_in
|
||||
if(network2 == reference)
|
||||
results += air_out
|
||||
|
||||
return results
|
||||
|
||||
/obj/machinery/atmospherics/pipeturbine/disconnect(obj/machinery/atmospherics/reference)
|
||||
if(reference==node1)
|
||||
qdel(network1)
|
||||
node1 = null
|
||||
|
||||
else if(reference==node2)
|
||||
qdel(network2)
|
||||
node2 = null
|
||||
|
||||
return null
|
||||
|
||||
|
||||
/obj/machinery/power/turbinemotor
|
||||
name = "motor"
|
||||
desc = "Electrogenerator. Converts rotation into power."
|
||||
icon = 'icons/obj/pipeturbine.dmi'
|
||||
icon_state = "motor"
|
||||
anchored = 0
|
||||
density = 1
|
||||
|
||||
var/kin_to_el_ratio = 0.1 //How much kinetic energy will be taken from turbine and converted into electricity
|
||||
var/obj/machinery/atmospherics/pipeturbine/turbine
|
||||
|
||||
/obj/machinery/power/turbinemotor/Initialize()
|
||||
. = ..()
|
||||
updateConnection()
|
||||
|
||||
/obj/machinery/power/turbinemotor/proc/updateConnection()
|
||||
turbine = null
|
||||
if(src.loc && anchored)
|
||||
turbine = locate(/obj/machinery/atmospherics/pipeturbine) in get_step(src,dir)
|
||||
if (turbine.stat & (BROKEN) || !turbine.anchored || turn(turbine.dir,180) != dir)
|
||||
turbine = null
|
||||
|
||||
/obj/machinery/power/turbinemotor/process()
|
||||
updateConnection()
|
||||
if(!turbine || !anchored || stat & (BROKEN))
|
||||
return
|
||||
|
||||
var/power_generated = kin_to_el_ratio * turbine.kin_energy
|
||||
turbine.kin_energy -= power_generated
|
||||
add_avail(power_generated)
|
||||
|
||||
/obj/machinery/power/turbinemotor/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(W.is_wrench())
|
||||
anchored = !anchored
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
turbine = null
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "secure" : "unsecure"] the bolts holding \the [src] to the floor.</span>")
|
||||
updateConnection()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/power/turbinemotor/verb/rotate_clockwise()
|
||||
set name = "Rotate Motor Clockwise"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if (usr.stat || usr.restrained() || anchored)
|
||||
return
|
||||
|
||||
src.set_dir(turn(src.dir, 270))
|
||||
|
||||
/obj/machinery/power/turbinemotor/verb/rotate_counterclockwise()
|
||||
set name = "Rotate Motor Counterclockwise"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if (usr.stat || usr.restrained() || anchored)
|
||||
return
|
||||
|
||||
src.set_dir(turn(src.dir, 90))
|
||||
@@ -163,7 +163,7 @@
|
||||
//
|
||||
// "T" Orientation - Inputs are on oposite sides instead of adjacent
|
||||
//
|
||||
obj/machinery/atmospherics/trinary/mixer/t_mixer
|
||||
/obj/machinery/atmospherics/trinary/mixer/t_mixer
|
||||
icon_state = "tmap"
|
||||
construction_type = /obj/item/pipe/trinary // Can't flip a "T", its symmetrical
|
||||
pipe_state = "t_mixer"
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
/obj/machinery/atmospherics/unary/generator_input
|
||||
icon = 'icons/obj/atmospherics/heat_exchanger.dmi'
|
||||
icon_state = "intact"
|
||||
density = 1
|
||||
|
||||
name = "Generator Input"
|
||||
desc = "Placeholder"
|
||||
|
||||
var/update_cycle
|
||||
|
||||
update_icon()
|
||||
if(node)
|
||||
icon_state = "intact"
|
||||
else
|
||||
icon_state = "exposed"
|
||||
|
||||
return
|
||||
|
||||
proc
|
||||
return_exchange_air()
|
||||
return air_contents
|
||||
@@ -11,7 +11,7 @@
|
||||
var/obj/machinery/atmospherics/unary/heat_exchanger/partner = null
|
||||
var/update_cycle
|
||||
|
||||
update_icon()
|
||||
/obj/machinery/atmospherics/unary/heat_exchanger/update_icon()
|
||||
if(node)
|
||||
icon_state = "intact"
|
||||
else
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
return
|
||||
|
||||
atmos_init()
|
||||
/obj/machinery/atmospherics/unary/heat_exchanger/atmos_init()
|
||||
if(!partner)
|
||||
var/partner_connect = turn(dir,180)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
..()
|
||||
|
||||
process()
|
||||
/obj/machinery/atmospherics/unary/heat_exchanger/process()
|
||||
..()
|
||||
if(!partner)
|
||||
return 0
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
return 1
|
||||
|
||||
attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
/obj/machinery/atmospherics/unary/heat_exchanger/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
if (!W.is_wrench())
|
||||
return ..()
|
||||
var/turf/T = src.loc
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
obj/machinery/atmospherics/unary/oxygen_generator
|
||||
icon = 'icons/obj/atmospherics/oxygen_generator.dmi'
|
||||
icon_state = "intact_off"
|
||||
density = 1
|
||||
|
||||
name = "Oxygen Generator"
|
||||
desc = ""
|
||||
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH
|
||||
|
||||
var/on = 0
|
||||
|
||||
var/oxygen_content = 10
|
||||
|
||||
update_icon()
|
||||
if(node)
|
||||
icon_state = "intact_[on?("on"):("off")]"
|
||||
else
|
||||
icon_state = "exposed_off"
|
||||
|
||||
on = 0
|
||||
|
||||
return
|
||||
|
||||
New()
|
||||
..()
|
||||
|
||||
air_contents.volume = 50
|
||||
|
||||
process()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
var/total_moles = air_contents.total_moles
|
||||
|
||||
if(total_moles < oxygen_content)
|
||||
var/current_heat_capacity = air_contents.heat_capacity()
|
||||
|
||||
var/added_oxygen = oxygen_content - total_moles
|
||||
|
||||
air_contents.temperature = (current_heat_capacity*air_contents.temperature + 20*added_oxygen*T0C)/(current_heat_capacity+20*added_oxygen)
|
||||
air_contents.adjust_gas("oxygen", added_oxygen)
|
||||
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
return 1
|
||||
@@ -1,708 +0,0 @@
|
||||
// internal pipe, don't actually place or use these
|
||||
obj/machinery/atmospherics/pipe/mains_component
|
||||
var/obj/machinery/atmospherics/mains_pipe/parent_pipe
|
||||
var/list/obj/machinery/atmospherics/pipe/mains_component/nodes = new()
|
||||
|
||||
New(loc)
|
||||
..(loc)
|
||||
parent_pipe = loc
|
||||
|
||||
check_pressure(pressure)
|
||||
var/datum/gas_mixture/environment = loc.loc.return_air()
|
||||
|
||||
var/pressure_difference = pressure - environment.return_pressure()
|
||||
|
||||
if(pressure_difference > parent_pipe.maximum_pressure)
|
||||
mains_burst()
|
||||
|
||||
else if(pressure_difference > parent_pipe.fatigue_pressure)
|
||||
//TODO: leak to turf, doing pfshhhhh
|
||||
if(prob(5))
|
||||
mains_burst()
|
||||
|
||||
else return 1
|
||||
|
||||
pipeline_expansion()
|
||||
return nodes
|
||||
|
||||
disconnect(obj/machinery/atmospherics/reference)
|
||||
if(nodes.Find(reference))
|
||||
nodes.Remove(reference)
|
||||
|
||||
proc/mains_burst()
|
||||
parent_pipe.burst()
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe
|
||||
icon = 'icons/obj/atmospherics/mainspipe.dmi'
|
||||
layer = PIPES_LAYER
|
||||
plane = PLATING_PLANE
|
||||
|
||||
var/volume = 0
|
||||
|
||||
var/alert_pressure = 80*ONE_ATMOSPHERE
|
||||
|
||||
var/initialize_mains_directions = 0
|
||||
|
||||
var/list/obj/machinery/atmospherics/mains_pipe/nodes = new()
|
||||
var/obj/machinery/atmospherics/pipe/mains_component/supply
|
||||
var/obj/machinery/atmospherics/pipe/mains_component/scrubbers
|
||||
var/obj/machinery/atmospherics/pipe/mains_component/aux
|
||||
|
||||
var/minimum_temperature_difference = 300
|
||||
var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No
|
||||
|
||||
var/maximum_pressure = 70*ONE_ATMOSPHERE
|
||||
var/fatigue_pressure = 55*ONE_ATMOSPHERE
|
||||
alert_pressure = 55*ONE_ATMOSPHERE
|
||||
|
||||
New()
|
||||
..()
|
||||
|
||||
supply = new(src)
|
||||
supply.volume = volume
|
||||
supply.nodes.len = nodes.len
|
||||
scrubbers = new(src)
|
||||
scrubbers.volume = volume
|
||||
scrubbers.nodes.len = nodes.len
|
||||
aux = new(src)
|
||||
aux.volume = volume
|
||||
aux.nodes.len = nodes.len
|
||||
|
||||
hide(var/i)
|
||||
if(level == 1 && istype(loc, /turf/simulated))
|
||||
invisibility = i ? 101 : 0
|
||||
update_icon()
|
||||
|
||||
proc/burst()
|
||||
for(var/obj/machinery/atmospherics/pipe/mains_component/pipe in contents)
|
||||
burst()
|
||||
|
||||
proc/check_pressure(pressure)
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
var/pressure_difference = pressure - environment.return_pressure()
|
||||
|
||||
if(pressure_difference > maximum_pressure)
|
||||
burst()
|
||||
|
||||
else if(pressure_difference > fatigue_pressure)
|
||||
//TODO: leak to turf, doing pfshhhhh
|
||||
if(prob(5))
|
||||
burst()
|
||||
|
||||
else return 1
|
||||
|
||||
get_neighbor_nodes_for_init()
|
||||
return nodes
|
||||
|
||||
disconnect()
|
||||
..()
|
||||
for(var/obj/machinery/atmospherics/pipe/mains_component/node in nodes)
|
||||
node.disconnect()
|
||||
|
||||
Destroy()
|
||||
disconnect()
|
||||
..()
|
||||
|
||||
atmos_init()
|
||||
for(var/i = 1 to nodes.len)
|
||||
var/obj/machinery/atmospherics/mains_pipe/node = nodes[i]
|
||||
if(node)
|
||||
supply.nodes[i] = node.supply
|
||||
scrubbers.nodes[i] = node.scrubbers
|
||||
aux.nodes[i] = node.aux
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/simple
|
||||
name = "mains pipe"
|
||||
desc = "A one meter section of 3-line mains pipe"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_mains_directions = SOUTH|NORTH
|
||||
|
||||
New()
|
||||
nodes.len = 2
|
||||
..()
|
||||
switch(dir)
|
||||
if(SOUTH || NORTH)
|
||||
initialize_mains_directions = SOUTH|NORTH
|
||||
if(EAST || WEST)
|
||||
initialize_mains_directions = EAST|WEST
|
||||
if(NORTHEAST)
|
||||
initialize_mains_directions = NORTH|EAST
|
||||
if(NORTHWEST)
|
||||
initialize_mains_directions = NORTH|WEST
|
||||
if(SOUTHEAST)
|
||||
initialize_mains_directions = SOUTH|EAST
|
||||
if(SOUTHWEST)
|
||||
initialize_mains_directions = SOUTH|WEST
|
||||
|
||||
proc/normalize_dir()
|
||||
if(dir==3)
|
||||
set_dir(1)
|
||||
else if(dir==12)
|
||||
set_dir(4)
|
||||
|
||||
update_icon()
|
||||
if(nodes[1] && nodes[2])
|
||||
icon_state = "intact[invisibility ? "-f" : "" ]"
|
||||
|
||||
//var/node1_direction = get_dir(src, node1)
|
||||
//var/node2_direction = get_dir(src, node2)
|
||||
|
||||
//set_dir(node1_direction|node2_direction)
|
||||
|
||||
else
|
||||
if(!nodes[1]&&!nodes[2])
|
||||
qdel(src) //TODO: silent deleting looks weird
|
||||
var/have_node1 = nodes[1]?1:0
|
||||
var/have_node2 = nodes[2]?1:0
|
||||
icon_state = "exposed[have_node1][have_node2][invisibility ? "-f" : "" ]"
|
||||
|
||||
atmos_init()
|
||||
normalize_dir()
|
||||
var/node1_dir
|
||||
var/node2_dir
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&initialize_mains_directions)
|
||||
if (!node1_dir)
|
||||
node1_dir = direction
|
||||
else if (!node2_dir)
|
||||
node2_dir = direction
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node1_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node2_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[2] = target
|
||||
break
|
||||
|
||||
..() // initialize internal pipes
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "intact-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "intact"
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/manifold
|
||||
name = "manifold pipe"
|
||||
desc = "A manifold composed of mains pipes"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_mains_directions = EAST|NORTH|WEST
|
||||
volume = 105
|
||||
|
||||
New()
|
||||
nodes.len = 3
|
||||
..()
|
||||
initialize_mains_directions = (NORTH|SOUTH|EAST|WEST) & ~dir
|
||||
|
||||
atmos_init()
|
||||
var/connect_directions = initialize_mains_directions
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&connect_directions)
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,direction))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
connect_directions &= ~direction
|
||||
break
|
||||
if (nodes[1])
|
||||
break
|
||||
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&connect_directions)
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,direction))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[2] = target
|
||||
connect_directions &= ~direction
|
||||
break
|
||||
if (nodes[2])
|
||||
break
|
||||
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&connect_directions)
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,direction))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[3] = target
|
||||
connect_directions &= ~direction
|
||||
break
|
||||
if (nodes[3])
|
||||
break
|
||||
|
||||
..() // initialize internal pipes
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
icon_state = "manifold[invisibility ? "-f" : "" ]"
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "manifold-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "manifold"
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/manifold4w
|
||||
name = "manifold pipe"
|
||||
desc = "A manifold composed of mains pipes"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_mains_directions = EAST|NORTH|WEST|SOUTH
|
||||
volume = 105
|
||||
|
||||
New()
|
||||
nodes.len = 4
|
||||
..()
|
||||
|
||||
atmos_init()
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,NORTH))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,SOUTH))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[2] = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,EAST))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[3] = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,WEST))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[3] = target
|
||||
break
|
||||
|
||||
..() // initialize internal pipes
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
icon_state = "manifold4w[invisibility ? "-f" : "" ]"
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "manifold4w-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "manifold4w"
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/split
|
||||
name = "mains splitter"
|
||||
desc = "A splitter for connecting to a single pipe off a mains."
|
||||
|
||||
var/obj/machinery/atmospherics/pipe/mains_component/split_node
|
||||
var/obj/machinery/atmospherics/node3
|
||||
var/icon_type
|
||||
|
||||
New()
|
||||
nodes.len = 2
|
||||
..()
|
||||
initialize_mains_directions = turn(dir, 90) | turn(dir, -90)
|
||||
initialize_directions = dir // actually have a normal connection too
|
||||
|
||||
atmos_init()
|
||||
var/node1_dir
|
||||
var/node2_dir
|
||||
var/node3_dir
|
||||
|
||||
node1_dir = turn(dir, 90)
|
||||
node2_dir = turn(dir, -90)
|
||||
node3_dir = dir
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node1_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node2_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[2] = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node3_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node3 = target
|
||||
break
|
||||
|
||||
..() // initialize internal pipes
|
||||
|
||||
// bind them
|
||||
spawn(5)
|
||||
if(node3 && split_node)
|
||||
var/datum/pipe_network/N1 = node3.return_network(src)
|
||||
var/datum/pipe_network/N2 = split_node.return_network(split_node)
|
||||
if(N1 && N2)
|
||||
N1.merge(N2)
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
icon_state = "split-[icon_type][invisibility ? "-f" : "" ]"
|
||||
|
||||
return_network(A)
|
||||
return split_node.return_network(A)
|
||||
|
||||
supply
|
||||
icon_type = "supply"
|
||||
|
||||
New()
|
||||
..()
|
||||
split_node = supply
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "split-supply-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "split-supply"
|
||||
|
||||
scrubbers
|
||||
icon_type = "scrubbers"
|
||||
|
||||
New()
|
||||
..()
|
||||
split_node = scrubbers
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "split-scrubbers-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "split-scrubbers"
|
||||
|
||||
aux
|
||||
icon_type = "aux"
|
||||
|
||||
New()
|
||||
..()
|
||||
split_node = aux
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "split-aux-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "split-aux"
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/split3
|
||||
name = "triple mains splitter"
|
||||
desc = "A splitter for connecting to the 3 pipes on a mainline."
|
||||
|
||||
var/obj/machinery/atmospherics/supply_node
|
||||
var/obj/machinery/atmospherics/scrubbers_node
|
||||
var/obj/machinery/atmospherics/aux_node
|
||||
|
||||
New()
|
||||
nodes.len = 1
|
||||
..()
|
||||
initialize_mains_directions = dir
|
||||
initialize_directions = cardinal & ~dir // actually have a normal connection too
|
||||
|
||||
atmos_init()
|
||||
var/node1_dir
|
||||
var/supply_node_dir
|
||||
var/scrubbers_node_dir
|
||||
var/aux_node_dir
|
||||
|
||||
node1_dir = dir
|
||||
aux_node_dir = turn(dir, 180)
|
||||
if(dir & (NORTH|SOUTH))
|
||||
supply_node_dir = EAST
|
||||
scrubbers_node_dir = WEST
|
||||
else
|
||||
supply_node_dir = SOUTH
|
||||
scrubbers_node_dir = NORTH
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src, node1_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,supply_node_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
supply_node = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,scrubbers_node_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
scrubbers_node = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,aux_node_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
aux_node = target
|
||||
break
|
||||
|
||||
..() // initialize internal pipes
|
||||
|
||||
// bind them
|
||||
spawn(5)
|
||||
if(supply_node)
|
||||
var/datum/pipe_network/N1 = supply_node.return_network(src)
|
||||
var/datum/pipe_network/N2 = supply.return_network(supply)
|
||||
if(N1 && N2)
|
||||
N1.merge(N2)
|
||||
if(scrubbers_node)
|
||||
var/datum/pipe_network/N1 = scrubbers_node.return_network(src)
|
||||
var/datum/pipe_network/N2 = scrubbers.return_network(scrubbers)
|
||||
if(N1 && N2)
|
||||
N1.merge(N2)
|
||||
if(aux_node)
|
||||
var/datum/pipe_network/N1 = aux_node.return_network(src)
|
||||
var/datum/pipe_network/N2 = aux.return_network(aux)
|
||||
if(N1 && N2)
|
||||
N1.merge(N2)
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
icon_state = "split-t[invisibility ? "-f" : "" ]"
|
||||
|
||||
return_network(obj/machinery/atmospherics/reference)
|
||||
var/obj/machinery/atmospherics/A
|
||||
|
||||
A = supply_node.return_network(reference)
|
||||
if(!A)
|
||||
A = scrubbers_node.return_network(reference)
|
||||
if(!A)
|
||||
A = aux_node.return_network(reference)
|
||||
|
||||
return A
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "split-t-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "split-t"
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/cap
|
||||
name = "pipe cap"
|
||||
desc = "A cap for the end of a mains pipe"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH
|
||||
volume = 35
|
||||
|
||||
New()
|
||||
nodes.len = 1
|
||||
..()
|
||||
initialize_mains_directions = dir
|
||||
|
||||
update_icon()
|
||||
icon_state = "cap[invisibility ? "-f" : ""]"
|
||||
|
||||
atmos_init()
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
|
||||
..()
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "cap-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "cap"
|
||||
|
||||
//TODO: Get Mains valves working!
|
||||
/*
|
||||
obj/machinery/atmospherics/mains_pipe/valve
|
||||
icon_state = "mvalve0"
|
||||
|
||||
name = "mains shutoff valve"
|
||||
desc = "A mains pipe valve"
|
||||
|
||||
var/open = 1
|
||||
|
||||
dir = SOUTH
|
||||
initialize_mains_directions = SOUTH|NORTH
|
||||
|
||||
New()
|
||||
nodes.len = 2
|
||||
..()
|
||||
initialize_mains_directions = dir | turn(dir, 180)
|
||||
|
||||
update_icon(animation)
|
||||
var/turf/simulated/floor = loc
|
||||
var/hide = istype(floor) ? floor.intact : 0
|
||||
level = 1
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/node in nodes)
|
||||
if(node.level == 2)
|
||||
hide = 0
|
||||
level = 2
|
||||
break
|
||||
|
||||
if(animation)
|
||||
flick("[hide?"h":""]mvalve[src.open][!src.open]",src)
|
||||
else
|
||||
icon_state = "[hide?"h":""]mvalve[open]"
|
||||
|
||||
initialize()
|
||||
normalize_dir()
|
||||
var/node1_dir
|
||||
var/node2_dir
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&initialize_mains_directions)
|
||||
if (!node1_dir)
|
||||
node1_dir = direction
|
||||
else if (!node2_dir)
|
||||
node2_dir = direction
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node1_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node2_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[2] = target
|
||||
break
|
||||
|
||||
if(open)
|
||||
..() // initialize internal pipes
|
||||
|
||||
update_icon()
|
||||
|
||||
proc/normalize_dir()
|
||||
if(dir==3)
|
||||
set_dir(1)
|
||||
else if(dir==12)
|
||||
set_dir(4)
|
||||
|
||||
proc/open()
|
||||
if(open) return 0
|
||||
|
||||
open = 1
|
||||
update_icon()
|
||||
|
||||
initialize()
|
||||
|
||||
return 1
|
||||
|
||||
proc/close()
|
||||
if(!open) return 0
|
||||
|
||||
open = 0
|
||||
update_icon()
|
||||
|
||||
for(var/obj/machinery/atmospherics/pipe/mains_component/node in src)
|
||||
for(var/obj/machinery/atmospherics/pipe/mains_component/o in node.nodes)
|
||||
o.disconnect(node)
|
||||
o.build_network()
|
||||
|
||||
return 1
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
return
|
||||
|
||||
attack_paw(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
src.add_fingerprint(usr)
|
||||
update_icon(1)
|
||||
sleep(10)
|
||||
if (open)
|
||||
close()
|
||||
else
|
||||
open()
|
||||
|
||||
digital // can be controlled by AI
|
||||
name = "digital mains valve"
|
||||
desc = "A digitally controlled valve."
|
||||
icon_state = "dvalve0"
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if(!src.allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
//Radio remote control
|
||||
|
||||
proc
|
||||
set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
initialize()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
update_icon(animation)
|
||||
var/turf/simulated/floor = loc
|
||||
var/hide = istype(floor) ? floor.intact : 0
|
||||
level = 1
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/node in nodes)
|
||||
if(node.level == 2)
|
||||
hide = 0
|
||||
level = 2
|
||||
break
|
||||
|
||||
if(animation)
|
||||
flick("[hide?"h":""]dvalve[src.open][!src.open]",src)
|
||||
else
|
||||
icon_state = "[hide?"h":""]dvalve[open]"
|
||||
|
||||
receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id))
|
||||
return 0
|
||||
|
||||
switch(signal.data["command"])
|
||||
if("valve_open")
|
||||
if(!open)
|
||||
open()
|
||||
|
||||
if("valve_close")
|
||||
if(open)
|
||||
close()
|
||||
|
||||
if("valve_toggle")
|
||||
if(open)
|
||||
close()
|
||||
else
|
||||
open()
|
||||
*/
|
||||
@@ -2,8 +2,8 @@
|
||||
Contains helper procs for airflow, handled in /connection_group.
|
||||
*/
|
||||
|
||||
mob/var/tmp/last_airflow_stun = 0
|
||||
mob/proc/airflow_stun()
|
||||
/mob/var/tmp/last_airflow_stun = 0
|
||||
/mob/proc/airflow_stun()
|
||||
if(stat == 2)
|
||||
return 0
|
||||
if(last_airflow_stun > world.time - vsc.airflow_stun_cooldown) return 0
|
||||
@@ -19,16 +19,16 @@ mob/proc/airflow_stun()
|
||||
Weaken(5)
|
||||
last_airflow_stun = world.time
|
||||
|
||||
mob/living/silicon/airflow_stun()
|
||||
/mob/living/silicon/airflow_stun()
|
||||
return
|
||||
|
||||
mob/living/carbon/human/airflow_stun()
|
||||
/mob/living/carbon/human/airflow_stun()
|
||||
if(shoes && (shoes.item_flags & NOSLIP))
|
||||
to_chat(src, "<span class='notice'>Air suddenly rushes past you!</span>")
|
||||
return 0
|
||||
..()
|
||||
|
||||
atom/movable/proc/check_airflow_movable(n)
|
||||
/atom/movable/proc/check_airflow_movable(n)
|
||||
if(!simulated) return 0
|
||||
|
||||
if(anchored && !ismob(src)) return 0
|
||||
@@ -37,19 +37,19 @@ atom/movable/proc/check_airflow_movable(n)
|
||||
|
||||
return 1
|
||||
|
||||
mob/check_airflow_movable(n)
|
||||
/mob/check_airflow_movable(n)
|
||||
if(n < vsc.airflow_heavy_pressure)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
mob/observer/check_airflow_movable()
|
||||
/mob/observer/check_airflow_movable()
|
||||
return 0
|
||||
|
||||
mob/living/silicon/check_airflow_movable()
|
||||
/mob/living/silicon/check_airflow_movable()
|
||||
return 0
|
||||
|
||||
|
||||
obj/check_airflow_movable(n)
|
||||
/obj/check_airflow_movable(n)
|
||||
if (!(. = ..()))
|
||||
return 0
|
||||
if(isnull(w_class))
|
||||
@@ -90,11 +90,11 @@ obj/check_airflow_movable(n)
|
||||
airflow_time = 0
|
||||
. = ..()
|
||||
|
||||
atom/movable/proc/airflow_hit(atom/A)
|
||||
/atom/movable/proc/airflow_hit(atom/A)
|
||||
airflow_speed = 0
|
||||
airflow_dest = null
|
||||
|
||||
mob/airflow_hit(atom/A)
|
||||
/mob/airflow_hit(atom/A)
|
||||
for(var/mob/M in hearers(src))
|
||||
M.show_message("<span class='danger'>\The [src] slams into \a [A]!</span>",1,"<span class='danger'>You hear a loud slam!</span>",2)
|
||||
playsound(src, "smash.ogg", 25, 1, -1)
|
||||
@@ -102,17 +102,17 @@ mob/airflow_hit(atom/A)
|
||||
Weaken(weak_amt)
|
||||
. = ..()
|
||||
|
||||
obj/airflow_hit(atom/A)
|
||||
/obj/airflow_hit(atom/A)
|
||||
for(var/mob/M in hearers(src))
|
||||
M.show_message("<span class='danger'>\The [src] slams into \a [A]!</span>",1,"<span class='danger'>You hear a loud slam!</span>",2)
|
||||
playsound(src, "smash.ogg", 25, 1, -1)
|
||||
. = ..()
|
||||
|
||||
obj/item/airflow_hit(atom/A)
|
||||
/obj/item/airflow_hit(atom/A)
|
||||
airflow_speed = 0
|
||||
airflow_dest = null
|
||||
|
||||
mob/living/carbon/human/airflow_hit(atom/A)
|
||||
/mob/living/carbon/human/airflow_hit(atom/A)
|
||||
// for(var/mob/M in hearers(src))
|
||||
// M.show_message("<span class='danger'>[src] slams into [A]!</span>",1,"<span class='danger'>You hear a loud slam!</span>",2)
|
||||
playsound(src, "punch", 25, 1, -1)
|
||||
@@ -140,7 +140,7 @@ mob/living/carbon/human/airflow_hit(atom/A)
|
||||
Stun(round(airflow_speed * vsc.airflow_stun/2))
|
||||
. = ..()
|
||||
|
||||
zone/proc/movables()
|
||||
/zone/proc/movables()
|
||||
. = list()
|
||||
for(var/turf/T in contents)
|
||||
for(var/atom/movable/A in T)
|
||||
|
||||
@@ -64,13 +64,13 @@
|
||||
// AIR_BLOCKED - Blocked
|
||||
// ZONE_BLOCKED - Not blocked, but zone boundaries will not cross.
|
||||
// BLOCKED - Blocked, zone boundaries will not cross even if opened.
|
||||
atom/proc/c_airblock(turf/other)
|
||||
/atom/proc/c_airblock(turf/other)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(isturf(other))
|
||||
#endif
|
||||
return (AIR_BLOCKED*!CanZASPass(other, FALSE))|(ZONE_BLOCKED*!CanZASPass(other, TRUE))
|
||||
|
||||
turf/c_airblock(turf/other)
|
||||
/turf/c_airblock(turf/other)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(isturf(other))
|
||||
#endif
|
||||
|
||||
@@ -242,7 +242,7 @@ Class Procs:
|
||||
if(!A.air.compare(air, vacuum_exception = 1))
|
||||
air_master.mark_edge_active(src)
|
||||
|
||||
proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
/proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
//This implements a simplistic version of the Stefan-Boltzmann law.
|
||||
var/energy_delta = ((A.temperature - B.temperature) ** 4) * STEFAN_BOLTZMANN_CONSTANT * connecting_tiles * 2.5
|
||||
var/maximum_energy_delta = max(0, min(A.temperature * A.heat_capacity() * A.group_multiplier, B.temperature * B.heat_capacity() * B.group_multiplier))
|
||||
|
||||
@@ -16,5 +16,5 @@ var/image/mark = image('icons/Testing/Zone.dmi', icon_state = "mark")
|
||||
overlays += img
|
||||
dbg_img = img
|
||||
|
||||
proc/soft_assert(thing,fail)
|
||||
/proc/soft_assert(thing,fail)
|
||||
if(!thing) message_admins(fail)
|
||||
@@ -1,4 +1,4 @@
|
||||
client/proc/ZoneTick()
|
||||
/client/proc/ZoneTick()
|
||||
set category = "Debug"
|
||||
set name = "Process Atmos"
|
||||
set desc = "Manually run a single tick of the air subsystem"
|
||||
@@ -16,7 +16,7 @@ client/proc/ZoneTick()
|
||||
to_chat(src, "Failed to process! ([air_master.tick_progress])")
|
||||
*/
|
||||
|
||||
client/proc/Zone_Info(turf/T as null|turf)
|
||||
/client/proc/Zone_Info(turf/T as null|turf)
|
||||
set category = "Debug"
|
||||
if(T)
|
||||
if(istype(T,/turf/simulated) && T:zone)
|
||||
@@ -33,9 +33,9 @@ client/proc/Zone_Info(turf/T as null|turf)
|
||||
images -= zone_debug_images[zone]
|
||||
zone_debug_images = null
|
||||
|
||||
client/var/list/zone_debug_images
|
||||
/client/var/list/zone_debug_images
|
||||
|
||||
client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
|
||||
/client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
|
||||
set category = "Debug"
|
||||
if(!istype(T))
|
||||
return
|
||||
@@ -94,7 +94,7 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
|
||||
else
|
||||
to_chat(mob, "both turfs can merge.")
|
||||
|
||||
client/proc/ZASSettings()
|
||||
/client/proc/ZASSettings()
|
||||
set category = "Debug"
|
||||
|
||||
vsc.SetDefault(mob)
|
||||
|
||||
@@ -11,11 +11,11 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin
|
||||
/turf/var/obj/fire/fire = null
|
||||
|
||||
//Some legacy definitions so fires can be started.
|
||||
atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
/atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return null
|
||||
|
||||
|
||||
turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
/turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
|
||||
|
||||
/turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
|
||||
@@ -320,7 +320,7 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
|
||||
return firelevel
|
||||
|
||||
datum/gas_mixture/proc/check_recombustability(list/fuel_objs)
|
||||
/datum/gas_mixture/proc/check_recombustability(list/fuel_objs)
|
||||
. = 0
|
||||
for(var/g in gas)
|
||||
if(gas_data.flags[g] & XGM_GAS_OXIDIZER && gas[g] >= 0.1)
|
||||
|
||||
@@ -38,7 +38,7 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi')
|
||||
var/N2O_HALLUCINATION_DESC = "Does being in sleeping gas cause you to hallucinate?"
|
||||
|
||||
|
||||
obj/var/contaminated = 0
|
||||
/obj/var/contaminated = 0
|
||||
|
||||
|
||||
/obj/item/proc/can_contaminate()
|
||||
@@ -173,7 +173,7 @@ obj/var/contaminated = 0
|
||||
gloves.contaminate()
|
||||
|
||||
|
||||
turf/Entered(obj/item/I)
|
||||
/turf/Entered(obj/item/I)
|
||||
. = ..()
|
||||
//Items that are in phoron, but not on a mob, can still be contaminated.
|
||||
if(istype(I) && vsc.plc.CLOTH_CONTAMINATION && I.can_contaminate())
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#define LAZYACCESSASSOC(L, I, K) L ? L[I] ? L[I][K] ? L[I][K] : null : null : null
|
||||
|
||||
// Null-safe L.Cut()
|
||||
#define LAZYCLEARLIST(L) if(L) L.Cut()
|
||||
#define LAZYCLEARLIST(L) if(L) { L.Cut(); L = null; }
|
||||
|
||||
// Reads L or an empty list if L is not a list. Note: Does NOT assign, L may be an expression.
|
||||
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
|
||||
|
||||
@@ -94,6 +94,8 @@ What is the naming convention for planes or layers?
|
||||
#define BELOW_MOB_LAYER 3.9 // Should be converted to plane swaps
|
||||
#define ABOVE_MOB_LAYER 4.1 // Should be converted to plane swaps
|
||||
|
||||
#define ABOVE_MOB_PLANE -24
|
||||
|
||||
// Invisible things plane
|
||||
#define CLOAKED_PLANE -15
|
||||
|
||||
@@ -123,6 +125,7 @@ What is the naming convention for planes or layers?
|
||||
#define PLANE_PLANETLIGHTING 4 //Lighting on planets
|
||||
#define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives
|
||||
#define PLANE_LIGHTING_ABOVE 6 //For glowy eyes etc. that shouldn't be affected by darkness
|
||||
#define PLANE_RUNECHAT 7
|
||||
|
||||
#define PLANE_GHOSTS 10 //Spooooooooky ghooooooosts
|
||||
#define PLANE_AI_EYE 11 //The AI eye lives here
|
||||
@@ -154,6 +157,9 @@ What is the naming convention for planes or layers?
|
||||
#define CRIT_LAYER 18.3
|
||||
|
||||
//Client UI HUD stuff
|
||||
#define PLANE_HOLOMAP_FRAME 92
|
||||
#define PLANE_HOLOMAP 93 // Holomap rendered here
|
||||
#define PLANE_HOLOMAP_ICONS 94 // Holomap markers and bobbins
|
||||
#define PLANE_PLAYER_HUD 95 //The character's UI is on this plane
|
||||
#define LAYER_HUD_UNDER 1 //Under the HUD items
|
||||
#define LAYER_HUD_BASE 2 //The HUD items themselves
|
||||
|
||||
@@ -94,3 +94,7 @@
|
||||
#define ATMOSTANK_CO2 25000 // CO2 and PH are not critically important for station, only for toxins and alternative coolants, no need to store a lot of those.
|
||||
#define ATMOSTANK_PHORON 25000
|
||||
#define ATMOSTANK_NITROUSOXIDE 10000 // N2O doesn't have a real useful use, i guess it's on station just to allow refilling of sec's riot control canisters?
|
||||
|
||||
// Used in various things like tanks and oxygen pumps.
|
||||
#define TANK_MAX_RELEASE_PRESSURE (3*ONE_ATMOSPHERE)
|
||||
#define TANK_DEFAULT_RELEASE_PRESSURE ONE_ATMOSPHERE
|
||||
@@ -163,9 +163,6 @@
|
||||
#define COLOR_ASSEMBLY_PURPLE "#6F6192"
|
||||
#define COLOR_ASSEMBLY_HOT_PINK "#FF69B4"
|
||||
|
||||
#define COLOR_ASTEROID_ROCK "#735555"
|
||||
#define COLOR_GOLD "#ffcc33"
|
||||
|
||||
// Discord requires colors to be in decimal instead of hexadecimal.
|
||||
#define COLOR_WEBHOOK_DEFAULT 0x8bbbd5 // "#8bbbd5"
|
||||
#define COLOR_WEBHOOK_GOOD 0x2ECC71 // "#2ECC71"
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
#define PIPING_LAYER_DEFAULT PIPING_LAYER_REGULAR
|
||||
|
||||
// We offset the layer values of the different pipe types to ensure they look nice
|
||||
#define PIPES_SCRUBBER_LAYER (PIPES_LAYER - 0.05)
|
||||
#define PIPES_AUX_LAYER (PIPES_LAYER - 0.04)
|
||||
#define PIPES_FUEL_LAYER (PIPES_LAYER - 0.03)
|
||||
#define PIPES_SCRUBBER_LAYER (PIPES_LAYER - 0.02)
|
||||
|
||||
@@ -91,7 +91,6 @@ var/list/be_special_flags = list(
|
||||
#define MODE_MONKEY "monkey"
|
||||
#define MODE_RENEGADE "renegade"
|
||||
#define MODE_REVOLUTIONARY "revolutionary"
|
||||
#define MODE_LOYALIST "loyalist"
|
||||
#define MODE_MALFUNCTION "malf"
|
||||
#define MODE_TRAITOR "traitor"
|
||||
#define MODE_AUTOTRAITOR "autotraitor"
|
||||
@@ -140,3 +139,27 @@ var/list/be_special_flags = list(
|
||||
#define Sp_HOLDVAR "holdervar"
|
||||
|
||||
#define CHANGELING_STASIS_COST 20
|
||||
|
||||
//Spell stuff, for Technomancer and Cult.
|
||||
//cast_method flags
|
||||
#define CAST_USE 1 // Clicking the spell in your hand.
|
||||
#define CAST_MELEE 2 // Clicking an atom in melee range.
|
||||
#define CAST_RANGED 4 // Clicking an atom beyond melee range.
|
||||
#define CAST_THROW 8 // Throwing the spell and hitting an atom.
|
||||
#define CAST_COMBINE 16 // Clicking another spell with this spell.
|
||||
#define CAST_INNATE 32 // Activates upon verb usage, used for mobs without hands.
|
||||
|
||||
//Aspects
|
||||
#define ASPECT_FIRE "fire" //Damage over time and raising body-temp. Firesuits protect from this.
|
||||
#define ASPECT_FROST "frost" //Slows down the affected, also involves imbedding with icicles. Winter coats protect from this.
|
||||
#define ASPECT_SHOCK "shock" //Energy-expensive, usually stuns. Insulated armor protects from this.
|
||||
#define ASPECT_AIR "air" //Mostly involves manipulation of atmos, useless in a vacuum. Magboots protect from this.
|
||||
#define ASPECT_FORCE "force" //Manipulates gravity to push things away or towards a location.
|
||||
#define ASPECT_TELE "tele" //Teleportation of self, other objects, or other people.
|
||||
#define ASPECT_DARK "dark" //Makes all those photons vanish using magic-- WITH SCIENCE. Used for sneaky stuff.
|
||||
#define ASPECT_LIGHT "light" //The opposite of dark, usually blinds, makes holo-illusions, or makes laser lightshows.
|
||||
#define ASPECT_BIOMED "biomed" //Mainly concerned with healing and restoration.
|
||||
#define ASPECT_EMP "emp" //Unused now.
|
||||
#define ASPECT_UNSTABLE "unstable" //Heavily RNG-based, causes instability to the victim.
|
||||
#define ASPECT_CHROMATIC "chromatic" //Used to combine with other spells.
|
||||
#define ASPECT_UNHOLY "unholy" //Involves the dead, blood, and most things against divine beings.
|
||||
@@ -2,12 +2,50 @@
|
||||
// Constants and standard colors for the holomap
|
||||
//
|
||||
|
||||
#define WORLD_ICON_SIZE 32 // Size of a standard tile in pixels (world.icon_size)
|
||||
#define PIXEL_MULTIPLIER WORLD_ICON_SIZE/32 // Convert from normal icon size of 32 to whatever insane thing this server is using.
|
||||
#define HOLOMAP_ICON 'icons/480x480.dmi' // Icon file to start with when drawing holomaps (to get a 480x480 canvas).
|
||||
#define HOLOMAP_ICON_SIZE 480 // Pixel width & height of the holomap icon. Used for auto-centering etc.
|
||||
#define ui_holomap "CENTER-7, CENTER-7" // Screen location of the holomap "hud"
|
||||
|
||||
//Holomap filters
|
||||
#define HOLOMAP_FILTER_DEATHSQUAD 1
|
||||
#define HOLOMAP_FILTER_ERT 2
|
||||
#define HOLOMAP_FILTER_NUKEOPS 4
|
||||
#define HOLOMAP_FILTER_ELITESYNDICATE 8
|
||||
#define HOLOMAP_FILTER_VOX 16
|
||||
#define HOLOMAP_FILTER_STATIONMAP 32
|
||||
#define HOLOMAP_FILTER_STATIONMAP_STRATEGIC 64//features markers over the captain's office, the armory, the SMES
|
||||
#define HOLOMAP_FILTER_CULT 128//bloodstone locators
|
||||
|
||||
#define HOLOMAP_EXTRA_STATIONMAP "stationmapformatted"
|
||||
#define HOLOMAP_EXTRA_STATIONMAP_STRATEGIC "stationmapstrategic"
|
||||
#define HOLOMAP_EXTRA_STATIONMAPAREAS "stationareas"
|
||||
#define HOLOMAP_EXTRA_STATIONMAPSMALL "stationmapsmall"
|
||||
#define HOLOMAP_EXTRA_STATIONMAPSMALL_NORTH "stationmapsmallnorth"
|
||||
#define HOLOMAP_EXTRA_STATIONMAPSMALL_SOUTH "stationmapsmallsouth"
|
||||
#define HOLOMAP_EXTRA_STATIONMAPSMALL_EAST "stationmapsmalleast"
|
||||
#define HOLOMAP_EXTRA_STATIONMAPSMALL_WEST "stationmapsmallwest"
|
||||
#define HOLOMAP_EXTRA_CULTMAP "cultmap"
|
||||
|
||||
#define HOLOMAP_MARKER_SMES "smes"
|
||||
#define HOLOMAP_MARKER_DISK "diskspawn"
|
||||
#define HOLOMAP_MARKER_SKIPJACK "skipjack"
|
||||
#define HOLOMAP_MARKER_SYNDISHUTTLE "syndishuttle"
|
||||
#define HOLOMAP_MARKER_BLOODSTONE "bloodstone"
|
||||
#define HOLOMAP_MARKER_BLOODSTONE_BROKEN "bloodstone-broken"
|
||||
#define HOLOMAP_MARKER_BLOODSTONE_ANCHOR "bloodstone-narsie"
|
||||
#define HOLOMAP_MARKER_CULT_ALTAR "altar"
|
||||
#define HOLOMAP_MARKER_CULT_FORGE "forge"
|
||||
#define HOLOMAP_MARKER_CULT_SPIRE "spire"
|
||||
#define HOLOMAP_MARKER_CULT_ENTRANCE "path_entrance"
|
||||
#define HOLOMAP_MARKER_CULT_EXIT "path_exit"
|
||||
#define HOLOMAP_MARKER_CULT_RUNE "rune"
|
||||
|
||||
#define HOLOMAP_DRAW_NORMAL 0
|
||||
#define HOLOMAP_DRAW_FULL 1
|
||||
#define HOLOMAP_DRAW_EMPTY 2
|
||||
#define HOLOMAP_DRAW_PATH 3
|
||||
#define HOLOMAP_DRAW_HALLWAY 4
|
||||
|
||||
// Holomap colors
|
||||
#define HOLOMAP_OBSTACLE "#FFFFFFDD" // Color of walls and barriers
|
||||
#define HOLOMAP_PATH "#66666699" // Color of floors
|
||||
@@ -46,7 +84,3 @@
|
||||
// #define HOLOMAP_MARKER_DISK "diskspawn"
|
||||
// #define HOLOMAP_MARKER_SKIPJACK "skipjack"
|
||||
// #define HOLOMAP_MARKER_SYNDISHUTTLE "syndishuttle"
|
||||
|
||||
#define HOLOMAP_EXTRA_STATIONMAP "stationmapformatted"
|
||||
#define HOLOMAP_EXTRA_STATIONMAPAREAS "stationareas"
|
||||
#define HOLOMAP_EXTRA_STATIONMAPSMALL "stationmapsmall"
|
||||
@@ -57,3 +57,5 @@
|
||||
//#define isturf(D) istype(D, /turf) //Built in
|
||||
#define isopenspace(A) istype(A, /turf/simulated/open)
|
||||
#define isspace(A) istype(A, /turf/space)
|
||||
|
||||
#define istaurtail(A) istype(A, /datum/sprite_accessory/tail/taur)
|
||||
|
||||
@@ -101,11 +101,9 @@
|
||||
#define slot_r_ear_str "slot_r_ear"
|
||||
#define slot_belt_str "slot_belt"
|
||||
#define slot_shoes_str "slot_shoes"
|
||||
#define slot_head_str "slot_head"
|
||||
#define slot_wear_mask_str "slot_wear_mask"
|
||||
#define slot_handcuffed_str "slot_handcuffed"
|
||||
#define slot_legcuffed_str "slot_legcuffed"
|
||||
#define slot_wear_mask_str "slot_wear_mask"
|
||||
#define slot_wear_id_str "slot_wear_id"
|
||||
#define slot_gloves_str "slot_gloves"
|
||||
#define slot_glasses_str "slot_glasses"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define MAP_LEVEL_CONSOLES 0x040 // Z-levels available to various consoles, such as the crew monitor (when that gets coded in). Defaults to station_levels if unset.
|
||||
#define MAP_LEVEL_XENOARCH_EXEMPT 0x080 // Z-levels exempt from xenoarch digsite generation.
|
||||
#define MAP_LEVEL_PERSIST 0x100 // Z-levels where SSpersistence should persist between rounds
|
||||
#define MAP_LEVEL_MAPPABLE 0x200 // Z-levels where mapping units will work fully
|
||||
|
||||
// Misc map defines.
|
||||
#define SUBMAP_MAP_EDGE_PAD 15 // Automatically created submaps are forbidden from being this close to the main map's edge.
|
||||
@@ -57,7 +57,4 @@
|
||||
#define MATERIAL_BRITTLE 0x2
|
||||
#define MATERIAL_PADDING 0x4
|
||||
|
||||
#define DEFAULT_TABLE_MATERIAL "plastic"
|
||||
#define DEFAULT_WALL_MATERIAL "steel"
|
||||
|
||||
#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define R_IDEAL_GAS_EQUATION 8.31 // kPa*L/(K*mol).
|
||||
#define ONE_ATMOSPHERE 101.325 // kPa.
|
||||
#define IDEAL_GAS_ENTROPY_CONSTANT 1164 // (mol^3 * s^3) / (kg^3 * L).
|
||||
#define ADIABATIC_EXPONENT 0.667 //Actually adiabatic exponent - 1.
|
||||
|
||||
#define T0C 273.15 // 0.0 degrees celcius
|
||||
#define T20C 293.15 // 20.0 degrees celcius
|
||||
|
||||
@@ -196,8 +196,6 @@
|
||||
|
||||
#define MIDNIGHT_ROLLOVER 864000 //number of deciseconds in a day
|
||||
|
||||
#define WORLD_ICON_SIZE 32 //Needed for the R-UST port
|
||||
#define PIXEL_MULTIPLIER WORLD_ICON_SIZE/32 //Needed for the R-UST port
|
||||
#define MAX_CLIENT_VIEW 34 // Maximum effective value of client.view (According to DM references)
|
||||
|
||||
// Maploader bounds indices
|
||||
@@ -453,3 +451,5 @@ GLOBAL_LIST_INIT(all_volume_channels, list(
|
||||
#ifndef HTTP_POST_DLL_LOCATION
|
||||
#define HTTP_POST_DLL_LOCATION (world.system_type == MS_WINDOWS ? WINDOWS_HTTP_POST_DLL_LOCATION : UNIX_HTTP_POST_DLL_LOCATION)
|
||||
#endif
|
||||
|
||||
#define DOCK_ATTEMPT_TIMEOUT 200 //how long in ticks we wait before assuming the docking controller is broken or blown up.
|
||||
@@ -25,19 +25,18 @@
|
||||
#define EMP_OXY_DMG 0x100 // EMPs inflict oxy damage
|
||||
|
||||
// Species allergens
|
||||
#define MEAT 0x1 // Skrell won't like this.
|
||||
#define FISH 0x2 // Seperate for completion's sake. Still bad for skrell.
|
||||
#define FRUIT 0x4 // An apple a day only keeps the doctor away if they're allergic.
|
||||
#define VEGETABLE 0x8 // Taters 'n' carrots. Potato allergy is a thing, apparently.
|
||||
#define GRAINS 0x10 // Wheat, oats, etc.
|
||||
#define BEANS 0x20 // The musical fruit! Includes soy.
|
||||
#define SEEDS 0x40 // Hope you don't have a nut allergy.
|
||||
#define DAIRY 0x80 // Lactose intolerance, ho! Also bad for skrell.
|
||||
#define FUNGI 0x100 // Delicious shrooms.
|
||||
#define COFFEE 0x200 // Mostly here for tajara.
|
||||
#define GENERIC 0x400 // Catchall for stuff that doesn't fall into the groups above. You shouldn't be allergic to this type, ever.
|
||||
#define SUGARS 0x800 // For unathi-like reactions
|
||||
#define EGGS 0x1000 // For Skrell eggs allergy
|
||||
#define ALLERGEN_MEAT 0x1 // Skrell won't like this.
|
||||
#define ALLERGEN_FISH 0x2 // Seperate for completion's sake. Still bad for skrell.
|
||||
#define ALLERGEN_FRUIT 0x4 // An apple a day only keeps the doctor away if they're allergic.
|
||||
#define ALLERGEN_VEGETABLE 0x8 // Taters 'n' carrots. Potato allergy is a thing, apparently.
|
||||
#define ALLERGEN_GRAINS 0x10 // Wheat, oats, etc.
|
||||
#define ALLERGEN_BEANS 0x20 // The musical fruit! Includes soy.
|
||||
#define ALLERGEN_SEEDS 0x40 // Hope you don't have a nut allergy.
|
||||
#define ALLERGEN_DAIRY 0x80 // Lactose intolerance, ho! Also bad for skrell.
|
||||
#define ALLERGEN_FUNGI 0x100 // Delicious shrooms.
|
||||
#define ALLERGEN_COFFEE 0x200 // Mostly here for tajara.
|
||||
#define ALLERGEN_SUGARS 0x400 // For unathi-like reactions
|
||||
#define ALLERGEN_EGGS 0x800 // For Skrell eggs allergy
|
||||
|
||||
// Allergen reactions
|
||||
#define AG_TOX_DMG 0x1 // the classic
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#define isCardinal(x) (x == NORTH || x == SOUTH || x == EAST || x == WEST)
|
||||
#define isDiagonal(x) (x == NORTHEAST || x == SOUTHEAST || x == NORTHWEST || x == SOUTHWEST)
|
||||
|
||||
#define FOOTSTEP_SPRITE_AMT 2
|
||||
|
||||
// Used to designate if a turf (or its area) should initialize as outdoors or not.
|
||||
#define OUTDOORS_YES 1 // This needs to be 1 for backwards compatibility.
|
||||
#define OUTDOORS_NO 0 // Ditto.
|
||||
|
||||
@@ -2,6 +2,38 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"datum_flags" = list(
|
||||
"DF_VAR_EDITED" = DF_VAR_EDITED,
|
||||
"DF_ISPROCESSING" = DF_ISPROCESSING
|
||||
)
|
||||
|
||||
),
|
||||
"appearance_flags" = list(
|
||||
"KEEP_APART" = KEEP_APART,
|
||||
"KEEP_TOGETHER" = KEEP_TOGETHER,
|
||||
"LONG_GLIDE" = LONG_GLIDE,
|
||||
"NO_CLIENT_COLOR" = NO_CLIENT_COLOR,
|
||||
"PIXEL_SCALE" = PIXEL_SCALE,
|
||||
"PLANE_MASTER" = PLANE_MASTER,
|
||||
"RESET_ALPHA" = RESET_ALPHA,
|
||||
"RESET_COLOR" = RESET_COLOR,
|
||||
"RESET_TRANSFORM" = RESET_TRANSFORM,
|
||||
"TILE_BOUND" = TILE_BOUND,
|
||||
),
|
||||
"vis_flags" = list(
|
||||
"VIS_HIDE" = VIS_HIDE,
|
||||
"VIS_INHERIT_DIR" = VIS_INHERIT_DIR,
|
||||
"VIS_INHERIT_ICON" = VIS_INHERIT_ICON,
|
||||
"VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE,
|
||||
"VIS_INHERIT_ID" = VIS_INHERIT_ID,
|
||||
"VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER,
|
||||
"VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE,
|
||||
"VIS_UNDERLAY" = VIS_UNDERLAY,
|
||||
),
|
||||
"sight" = list(
|
||||
"BLIND" = BLIND,
|
||||
"SEE_BLACKNESS" = SEE_BLACKNESS,
|
||||
"SEE_INFRA" = SEE_INFRA,
|
||||
"SEE_MOBS" = SEE_MOBS,
|
||||
"SEE_OBJS" = SEE_OBJS,
|
||||
"SEE_PIXELS" = SEE_PIXELS,
|
||||
"SEE_SELF" = SEE_SELF,
|
||||
"SEE_THRU" = SEE_THRU,
|
||||
"SEE_TURFS" = SEE_TURFS,
|
||||
),
|
||||
))
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
return counting_english_list(input, output_icons, determiners, nothing_text, and_text, comma_text, final_comma_text)
|
||||
|
||||
//Returns list element or null. Should prevent "index out of bounds" error.
|
||||
proc/listgetindex(var/list/list,index)
|
||||
/proc/listgetindex(var/list/list,index)
|
||||
if(istype(list) && list.len)
|
||||
if(isnum(index))
|
||||
if(InRange(index,1,list.len))
|
||||
@@ -89,13 +89,13 @@ proc/listgetindex(var/list/list,index)
|
||||
return
|
||||
|
||||
//Return either pick(list) or null if list is not of type /list or is empty
|
||||
proc/safepick(list/list)
|
||||
/proc/safepick(list/list)
|
||||
if(!islist(list) || !list.len)
|
||||
return
|
||||
return pick(list)
|
||||
|
||||
//Checks if the list is empty
|
||||
proc/isemptylist(list/list)
|
||||
/proc/isemptylist(list/list)
|
||||
if(!list.len)
|
||||
return 1
|
||||
return 0
|
||||
@@ -177,13 +177,13 @@ proc/isemptylist(list/list)
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
//Empties the list by setting the length to 0. Hopefully the elements get garbage collected
|
||||
proc/clearlist(list/list)
|
||||
/proc/clearlist(list/list)
|
||||
if(istype(list))
|
||||
list.len = 0
|
||||
return
|
||||
|
||||
//Removes any null entries from the list
|
||||
proc/listclearnulls(list/list)
|
||||
/proc/listclearnulls(list/list)
|
||||
if(istype(list))
|
||||
while(null in list)
|
||||
list -= null
|
||||
@@ -611,7 +611,7 @@ This actually tests if they have the same entries and values.
|
||||
min = mid+1
|
||||
|
||||
/*
|
||||
proc/dd_sortedObjectList(list/incoming)
|
||||
/proc/dd_sortedObjectList(list/incoming)
|
||||
/*
|
||||
Use binary search to order by dd_SortValue().
|
||||
This works by going to the half-point of the list, seeing if the node in
|
||||
@@ -669,7 +669,7 @@ proc/dd_sortedObjectList(list/incoming)
|
||||
return sorted_list
|
||||
*/
|
||||
|
||||
proc/dd_sortedtextlist(list/incoming, case_sensitive = 0)
|
||||
/proc/dd_sortedtextlist(list/incoming, case_sensitive = 0)
|
||||
// Returns a new list with the text values sorted.
|
||||
// Use binary search to order by sortValue.
|
||||
// This works by going to the half-point of the list, seeing if the node in question is higher or lower cost,
|
||||
@@ -728,7 +728,7 @@ proc/dd_sortedtextlist(list/incoming, case_sensitive = 0)
|
||||
return sorted_text
|
||||
|
||||
|
||||
proc/dd_sortedTextList(list/incoming)
|
||||
/proc/dd_sortedTextList(list/incoming)
|
||||
var/case_sensitive = 1
|
||||
return dd_sortedtextlist(incoming, case_sensitive)
|
||||
|
||||
|
||||
@@ -314,10 +314,7 @@
|
||||
|
||||
return list("mobs" = mobs, "objs" = objs)
|
||||
|
||||
#define SIGN(X) ((X<0)?-1:1)
|
||||
|
||||
proc
|
||||
inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5)
|
||||
/proc/inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5)
|
||||
var/turf/T
|
||||
if(X1==X2)
|
||||
if(Y1==Y2)
|
||||
@@ -346,7 +343,6 @@ proc
|
||||
if(T.opacity)
|
||||
return 0
|
||||
return 1
|
||||
#undef SIGN
|
||||
|
||||
/proc/flick_overlay(image/I, list/show_to, duration, gc_after)
|
||||
for(var/client/C in show_to)
|
||||
@@ -365,7 +361,7 @@ proc
|
||||
viewing += M.client
|
||||
flick_overlay(I, viewing, duration, gc_after)
|
||||
|
||||
proc/isInSight(var/atom/A, var/atom/B)
|
||||
/proc/isInSight(var/atom/A, var/atom/B)
|
||||
var/turf/Aturf = get_turf(A)
|
||||
var/turf/Bturf = get_turf(B)
|
||||
|
||||
@@ -446,7 +442,7 @@ proc/isInSight(var/atom/A, var/atom/B)
|
||||
for(var/client/C in group)
|
||||
C.screen -= O
|
||||
|
||||
datum/projectile_data
|
||||
/datum/projectile_data
|
||||
var/src_x
|
||||
var/src_y
|
||||
var/time
|
||||
|
||||
@@ -31,9 +31,10 @@ GLOBAL_LIST_EMPTY(closet_appearances)
|
||||
// Times that players are allowed to respawn ("ckey" = world.time)
|
||||
GLOBAL_LIST_EMPTY(respawn_timers)
|
||||
|
||||
// Posters
|
||||
var/global/list/poster_designs = list()
|
||||
var/global/list/NT_poster_designs = list()
|
||||
// Holomaps
|
||||
var/global/list/holomap_markers = list()
|
||||
var/global/list/mapping_units = list()
|
||||
var/global/list/mapping_beacons = list()
|
||||
|
||||
//Preferences stuff
|
||||
//Hairstyles
|
||||
@@ -207,18 +208,6 @@ var/global/list/string_slot_flags = list(
|
||||
if(S.spawn_flags & SPECIES_IS_WHITELISTED)
|
||||
GLOB.whitelisted_species += S.name
|
||||
|
||||
//Posters
|
||||
paths = typesof(/datum/poster) - /datum/poster
|
||||
paths -= typesof(/datum/poster/nanotrasen)
|
||||
for(var/T in paths)
|
||||
var/datum/poster/P = new T
|
||||
poster_designs += P
|
||||
|
||||
paths = typesof(/datum/poster/nanotrasen)
|
||||
for(var/T in paths)
|
||||
var/datum/poster/P = new T
|
||||
NT_poster_designs += P
|
||||
|
||||
//Ores
|
||||
paths = typesof(/ore)-/ore
|
||||
for(var/oretype in paths)
|
||||
@@ -230,10 +219,7 @@ var/global/list/string_slot_flags = list(
|
||||
GLOB.alloy_data += new alloytype()
|
||||
|
||||
//Closet appearances
|
||||
paths = typesof(/decl/closet_appearance)
|
||||
for(var/T in paths)
|
||||
var/decl/closet_appearance/app = new T()
|
||||
GLOB.closet_appearances[T] = app
|
||||
GLOB.closet_appearances = decls_repository.get_decls_of_type(/decl/closet_appearance)
|
||||
|
||||
paths = typesof(/datum/sprite_accessory/ears) - /datum/sprite_accessory/ears
|
||||
for(var/path in paths)
|
||||
|
||||
@@ -199,7 +199,7 @@ mob
|
||||
getFlatIcon(src)
|
||||
Browse_Icon()
|
||||
|
||||
obj/effect/overlayTest
|
||||
/obj/effect/overlayTest
|
||||
icon = 'old_or_unused.dmi'
|
||||
icon_state = "blue"
|
||||
pixel_x = -24
|
||||
@@ -215,26 +215,25 @@ world
|
||||
|
||||
#define TO_HEX_DIGIT(n) ascii2text((n&15) + ((n&15)<10 ? 48 : 87))
|
||||
|
||||
icon
|
||||
proc/MakeLying()
|
||||
/icon/proc/MakeLying()
|
||||
var/icon/I = new(src,dir=SOUTH)
|
||||
I.BecomeLying()
|
||||
return I
|
||||
|
||||
proc/BecomeLying()
|
||||
/icon/proc/BecomeLying()
|
||||
Turn(90)
|
||||
Shift(SOUTH,6)
|
||||
Shift(EAST,1)
|
||||
|
||||
// Multiply all alpha values by this float
|
||||
proc/ChangeOpacity(opacity = 1.0)
|
||||
/icon/proc/ChangeOpacity(opacity = 1.0)
|
||||
MapColors(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,opacity, 0,0,0,0)
|
||||
|
||||
// Convert to grayscale
|
||||
proc/GrayScale()
|
||||
/icon/proc/GrayScale()
|
||||
MapColors(0.3,0.3,0.3, 0.59,0.59,0.59, 0.11,0.11,0.11, 0,0,0)
|
||||
|
||||
proc/ColorTone(tone)
|
||||
/icon/proc/ColorTone(tone)
|
||||
GrayScale()
|
||||
|
||||
var/list/TONE = ReadRGB(tone)
|
||||
@@ -252,14 +251,14 @@ icon
|
||||
Blend(upper, ICON_ADD)
|
||||
|
||||
// Take the minimum color of two icons; combine transparency as if blending with ICON_ADD
|
||||
proc/MinColors(icon)
|
||||
/icon/proc/MinColors(icon)
|
||||
var/icon/I = new(src)
|
||||
I.Opaque()
|
||||
I.Blend(icon, ICON_SUBTRACT)
|
||||
Blend(I, ICON_SUBTRACT)
|
||||
|
||||
// Take the maximum color of two icons; combine opacity as if blending with ICON_OR
|
||||
proc/MaxColors(icon)
|
||||
/icon/proc/MaxColors(icon)
|
||||
var/icon/I
|
||||
if(isicon(icon))
|
||||
I = new(icon)
|
||||
@@ -275,21 +274,21 @@ icon
|
||||
Blend(I, ICON_OR)
|
||||
|
||||
// make this icon fully opaque--transparent pixels become black
|
||||
proc/Opaque(background = "#000000")
|
||||
/icon/proc/Opaque(background = "#000000")
|
||||
SwapColor(null, background)
|
||||
MapColors(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,0, 0,0,0,1)
|
||||
|
||||
// Change a grayscale icon into a white icon where the original color becomes the alpha
|
||||
// I.e., black -> transparent, gray -> translucent white, white -> solid white
|
||||
proc/BecomeAlphaMask()
|
||||
/icon/proc/BecomeAlphaMask()
|
||||
SwapColor(null, "#000000ff") // don't let transparent become gray
|
||||
MapColors(0,0,0,0.3, 0,0,0,0.59, 0,0,0,0.11, 0,0,0,0, 1,1,1,0)
|
||||
|
||||
proc/UseAlphaMask(mask)
|
||||
/icon/proc/UseAlphaMask(mask)
|
||||
Opaque()
|
||||
AddAlphaMask(mask)
|
||||
|
||||
proc/AddAlphaMask(mask)
|
||||
/icon/proc/AddAlphaMask(mask)
|
||||
var/icon/M = new(mask)
|
||||
M.Blend("#ffffff", ICON_SUBTRACT)
|
||||
// apply mask
|
||||
@@ -317,7 +316,7 @@ icon
|
||||
Higher value means brighter color
|
||||
*/
|
||||
|
||||
proc/ReadRGB(rgb)
|
||||
/proc/ReadRGB(rgb)
|
||||
if(!rgb) return
|
||||
|
||||
// interpret the HSV or HSVA value
|
||||
@@ -367,7 +366,7 @@ proc/ReadRGB(rgb)
|
||||
. = list(r, g, b)
|
||||
if(usealpha) . += alpha
|
||||
|
||||
proc/ReadHSV(hsv)
|
||||
/proc/ReadHSV(hsv)
|
||||
if(!hsv) return
|
||||
|
||||
// interpret the HSV or HSVA value
|
||||
@@ -406,7 +405,7 @@ proc/ReadHSV(hsv)
|
||||
. = list(hue, sat, val)
|
||||
if(usealpha) . += alpha
|
||||
|
||||
proc/HSVtoRGB(hsv)
|
||||
/proc/HSVtoRGB(hsv)
|
||||
if(!hsv) return "#000000"
|
||||
var/list/HSV = ReadHSV(hsv)
|
||||
if(!HSV) return "#000000"
|
||||
@@ -434,7 +433,7 @@ proc/HSVtoRGB(hsv)
|
||||
|
||||
return (HSV.len > 3) ? rgb(r,g,b,HSV[4]) : rgb(r,g,b)
|
||||
|
||||
proc/RGBtoHSV(rgb)
|
||||
/proc/RGBtoHSV(rgb)
|
||||
if(!rgb) return "#0000000"
|
||||
var/list/RGB = ReadRGB(rgb)
|
||||
if(!RGB) return "#0000000"
|
||||
@@ -465,7 +464,7 @@ proc/RGBtoHSV(rgb)
|
||||
|
||||
return hsv(hue, sat, val, (RGB.len>3 ? RGB[4] : null))
|
||||
|
||||
proc/hsv(hue, sat, val, alpha)
|
||||
/proc/hsv(hue, sat, val, alpha)
|
||||
if(hue < 0 || hue >= 1536) hue %= 1536
|
||||
if(hue < 0) hue += 1536
|
||||
if((hue & 0xFF) == 0xFF)
|
||||
@@ -498,7 +497,7 @@ proc/hsv(hue, sat, val, alpha)
|
||||
|
||||
amount<0 or amount>1 are allowed
|
||||
*/
|
||||
proc/BlendHSV(hsv1, hsv2, amount)
|
||||
/proc/BlendHSV(hsv1, hsv2, amount)
|
||||
var/list/HSV1 = ReadHSV(hsv1)
|
||||
var/list/HSV2 = ReadHSV(hsv2)
|
||||
|
||||
@@ -552,7 +551,7 @@ proc/BlendHSV(hsv1, hsv2, amount)
|
||||
|
||||
amount<0 or amount>1 are allowed
|
||||
*/
|
||||
proc/BlendRGB(rgb1, rgb2, amount)
|
||||
/proc/BlendRGB(rgb1, rgb2, amount)
|
||||
var/list/RGB1 = ReadRGB(rgb1)
|
||||
var/list/RGB2 = ReadRGB(rgb2)
|
||||
|
||||
@@ -568,10 +567,10 @@ proc/BlendRGB(rgb1, rgb2, amount)
|
||||
|
||||
return isnull(alpha) ? rgb(r, g, b) : rgb(r, g, b, alpha)
|
||||
|
||||
proc/BlendRGBasHSV(rgb1, rgb2, amount)
|
||||
/proc/BlendRGBasHSV(rgb1, rgb2, amount)
|
||||
return HSVtoRGB(RGBtoHSV(rgb1), RGBtoHSV(rgb2), amount)
|
||||
|
||||
proc/HueToAngle(hue)
|
||||
/proc/HueToAngle(hue)
|
||||
// normalize hsv in case anything is screwy
|
||||
if(hue < 0 || hue >= 1536) hue %= 1536
|
||||
if(hue < 0) hue += 1536
|
||||
@@ -579,7 +578,7 @@ proc/HueToAngle(hue)
|
||||
hue -= hue >> 8
|
||||
return hue / (1530/360)
|
||||
|
||||
proc/AngleToHue(angle)
|
||||
/proc/AngleToHue(angle)
|
||||
// normalize hsv in case anything is screwy
|
||||
if(angle < 0 || angle >= 360) angle -= 360 * round(angle / 360)
|
||||
var/hue = angle * (1530/360)
|
||||
@@ -589,7 +588,7 @@ proc/AngleToHue(angle)
|
||||
|
||||
|
||||
// positive angle rotates forward through red->green->blue
|
||||
proc/RotateHue(hsv, angle)
|
||||
/proc/RotateHue(hsv, angle)
|
||||
var/list/HSV = ReadHSV(hsv)
|
||||
|
||||
// normalize hsv in case anything is screwy
|
||||
@@ -611,13 +610,13 @@ proc/RotateHue(hsv, angle)
|
||||
return hsv(HSV[1], HSV[2], HSV[3], (HSV.len > 3 ? HSV[4] : null))
|
||||
|
||||
// Convert an rgb color to grayscale
|
||||
proc/GrayScale(rgb)
|
||||
/proc/GrayScale(rgb)
|
||||
var/list/RGB = ReadRGB(rgb)
|
||||
var/gray = RGB[1]*0.3 + RGB[2]*0.59 + RGB[3]*0.11
|
||||
return (RGB.len > 3) ? rgb(gray, gray, gray, RGB[4]) : rgb(gray, gray, gray)
|
||||
|
||||
// Change grayscale color to black->tone->white range
|
||||
proc/ColorTone(rgb, tone)
|
||||
/proc/ColorTone(rgb, tone)
|
||||
var/list/RGB = ReadRGB(rgb)
|
||||
var/list/TONE = ReadRGB(tone)
|
||||
|
||||
@@ -925,7 +924,7 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
|
||||
/proc/uncache_examine_icon(var/weakref/WR)
|
||||
GLOB.cached_examine_icons -= WR
|
||||
|
||||
proc/adjust_brightness(var/color, var/value)
|
||||
/proc/adjust_brightness(var/color, var/value)
|
||||
if (!color) return "#FFFFFF"
|
||||
if (!value) return color
|
||||
|
||||
@@ -935,7 +934,7 @@ proc/adjust_brightness(var/color, var/value)
|
||||
RGB[3] = CLAMP(RGB[3]+value,0,255)
|
||||
return rgb(RGB[1],RGB[2],RGB[3])
|
||||
|
||||
proc/sort_atoms_by_layer(var/list/atoms)
|
||||
/proc/sort_atoms_by_layer(var/list/atoms)
|
||||
// Comb sort icons based on levels
|
||||
var/list/result = atoms.Copy()
|
||||
var/gap = result.len
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
proc/random_hair_style(gender, species = SPECIES_HUMAN)
|
||||
/proc/random_hair_style(gender, species = SPECIES_HUMAN)
|
||||
var/h_style = "Bald"
|
||||
|
||||
var/list/valid_hairstyles = list()
|
||||
@@ -17,7 +17,7 @@ proc/random_hair_style(gender, species = SPECIES_HUMAN)
|
||||
|
||||
return h_style
|
||||
|
||||
proc/random_facial_hair_style(gender, species = SPECIES_HUMAN)
|
||||
/proc/random_facial_hair_style(gender, species = SPECIES_HUMAN)
|
||||
var/f_style = "Shaved"
|
||||
|
||||
var/list/valid_facialhairstyles = list()
|
||||
@@ -37,14 +37,14 @@ proc/random_facial_hair_style(gender, species = SPECIES_HUMAN)
|
||||
|
||||
return f_style
|
||||
|
||||
proc/sanitize_name(name, species = SPECIES_HUMAN, robot = 0)
|
||||
/proc/sanitize_name(name, species = SPECIES_HUMAN, robot = 0)
|
||||
var/datum/species/current_species
|
||||
if(species)
|
||||
current_species = GLOB.all_species[species]
|
||||
|
||||
return current_species ? current_species.sanitize_name(name, robot) : sanitizeName(name, MAX_NAME_LEN, robot)
|
||||
|
||||
proc/random_name(gender, species = SPECIES_HUMAN)
|
||||
/proc/random_name(gender, species = SPECIES_HUMAN)
|
||||
|
||||
var/datum/species/current_species
|
||||
if(species)
|
||||
@@ -58,7 +58,7 @@ proc/random_name(gender, species = SPECIES_HUMAN)
|
||||
else
|
||||
return current_species.get_random_name(gender)
|
||||
|
||||
proc/random_skin_tone()
|
||||
/proc/random_skin_tone()
|
||||
switch(pick(60;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino"))
|
||||
if("caucasian") . = -10
|
||||
if("afroamerican") . = -115
|
||||
@@ -68,7 +68,7 @@ proc/random_skin_tone()
|
||||
else . = rand(-185,34)
|
||||
return min(max( .+rand(-25, 25), -185),34)
|
||||
|
||||
proc/skintone2racedescription(tone)
|
||||
/proc/skintone2racedescription(tone)
|
||||
switch (tone)
|
||||
if(30 to INFINITY) return "albino"
|
||||
if(20 to 30) return "pale"
|
||||
@@ -80,7 +80,7 @@ proc/skintone2racedescription(tone)
|
||||
if(-INFINITY to -65) return "black"
|
||||
else return "unknown"
|
||||
|
||||
proc/age2agedescription(age)
|
||||
/proc/age2agedescription(age)
|
||||
switch(age)
|
||||
if(0 to 1) return "infant"
|
||||
if(1 to 3) return "toddler"
|
||||
|
||||
@@ -57,12 +57,6 @@
|
||||
if (!.)
|
||||
. = B[STAT_ENTRY_COUNT] - A[STAT_ENTRY_COUNT]
|
||||
|
||||
// Compares complexity of recipes for use in cooking, etc. This is for telling which recipe to make, not for showing things to the player.
|
||||
/proc/cmp_recipe_complexity_dsc(datum/recipe/A, datum/recipe/B)
|
||||
var/a_score = LAZYLEN(A.items) + LAZYLEN(A.reagents) + LAZYLEN(A.fruit)
|
||||
var/b_score = LAZYLEN(B.items) + LAZYLEN(B.reagents) + LAZYLEN(B.fruit)
|
||||
return b_score - a_score
|
||||
|
||||
/proc/cmp_typepaths_asc(A, B)
|
||||
return sorttext("[B]","[A]")
|
||||
|
||||
|
||||
@@ -319,7 +319,7 @@
|
||||
|
||||
//Used in preferences' SetFlavorText and human's set_flavor verb
|
||||
//Previews a string of len or less length
|
||||
proc/TextPreview(var/string,var/len=40)
|
||||
/proc/TextPreview(var/string,var/len=40)
|
||||
if(length(string) <= len)
|
||||
if(!length(string))
|
||||
return "\[...\]"
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#define TICKS2DS(T) ((T) TICKS) // Convert ticks to deciseconds
|
||||
#define DS2NEARESTTICK(DS) TICKS2DS(-round(-(DS2TICKS(DS))))
|
||||
|
||||
var/world_startup_time
|
||||
|
||||
/proc/get_game_time()
|
||||
var/global/time_offset = 0
|
||||
var/global/last_time = 0
|
||||
@@ -78,7 +80,7 @@ var/next_station_date_change = 1 DAY
|
||||
return time2text(wtime - GLOB.timezoneOffset, format)
|
||||
|
||||
/* Returns 1 if it is the selected month and day */
|
||||
proc/isDay(var/month, var/day)
|
||||
/proc/isDay(var/month, var/day)
|
||||
if(isnum(month) && isnum(day))
|
||||
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
|
||||
var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
|
||||
|
||||
@@ -595,7 +595,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return max(min(middle, high), low)
|
||||
|
||||
//returns random gauss number
|
||||
proc/GaussRand(var/sigma)
|
||||
/proc/GaussRand(var/sigma)
|
||||
var/x,y,rsq
|
||||
do
|
||||
x=2*rand()-1
|
||||
@@ -605,7 +605,7 @@ proc/GaussRand(var/sigma)
|
||||
return sigma*y*sqrt(-2*log(rsq)/rsq)
|
||||
|
||||
//returns random gauss number, rounded to 'roundto'
|
||||
proc/GaussRandRound(var/sigma,var/roundto)
|
||||
/proc/GaussRandRound(var/sigma,var/roundto)
|
||||
return round(GaussRand(sigma),roundto)
|
||||
|
||||
//Will return the contents of an atom recursivly to a depth of 'searchDepth'
|
||||
@@ -866,7 +866,7 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
refined_trg -= B
|
||||
continue moving
|
||||
|
||||
proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
/proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
if(!original)
|
||||
return null
|
||||
|
||||
@@ -1014,16 +1014,16 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0)
|
||||
|
||||
|
||||
|
||||
proc/get_cardinal_dir(atom/A, atom/B)
|
||||
/proc/get_cardinal_dir(atom/A, atom/B)
|
||||
var/dx = abs(B.x - A.x)
|
||||
var/dy = abs(B.y - A.y)
|
||||
return get_dir(A, B) & (rand() * (dx+dy) < dy ? 3 : 12)
|
||||
|
||||
//chances are 1:value. anyprob(1) will always return true
|
||||
proc/anyprob(value)
|
||||
/proc/anyprob(value)
|
||||
return (rand(1,value)==value)
|
||||
|
||||
proc/view_or_range(distance = world.view , center = usr , type)
|
||||
/proc/view_or_range(distance = world.view , center = usr , type)
|
||||
switch(type)
|
||||
if("view")
|
||||
. = view(distance,center)
|
||||
@@ -1031,7 +1031,7 @@ proc/view_or_range(distance = world.view , center = usr , type)
|
||||
. = range(distance,center)
|
||||
return
|
||||
|
||||
proc/oview_or_orange(distance = world.view , center = usr , type)
|
||||
/proc/oview_or_orange(distance = world.view , center = usr , type)
|
||||
switch(type)
|
||||
if("view")
|
||||
. = oview(distance,center)
|
||||
@@ -1039,7 +1039,7 @@ proc/oview_or_orange(distance = world.view , center = usr , type)
|
||||
. = orange(distance,center)
|
||||
return
|
||||
|
||||
proc/get_mob_with_client_list()
|
||||
/proc/get_mob_with_client_list()
|
||||
var/list/mobs = list()
|
||||
for(var/mob/M in mob_list)
|
||||
if (M.client)
|
||||
@@ -1096,7 +1096,7 @@ var/global/list/common_tools = list(
|
||||
return TRUE
|
||||
return
|
||||
|
||||
proc/is_hot(obj/item/W as obj)
|
||||
/proc/is_hot(obj/item/W as obj)
|
||||
switch(W.type)
|
||||
if(/obj/item/weapon/weldingtool)
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
@@ -1478,8 +1478,6 @@ var/mob/dview/dview_mob = new
|
||||
/proc/pass()
|
||||
return
|
||||
|
||||
#define NAMEOF(datum, X) (#X || ##datum.##X)
|
||||
|
||||
/proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
|
||||
if (value == FALSE) //nothing should be calling us with a number, so this is safe
|
||||
value = input("Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text
|
||||
|
||||
@@ -40,5 +40,6 @@
|
||||
|
||||
#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") }
|
||||
|
||||
#define isitem(A) istype(A, /obj/item)
|
||||
#define isTaurTail(A) istype(A, /datum/sprite_accessory/tail/taur)
|
||||
#define WORLD_ICON_SIZE 32 //Needed for the R-UST port
|
||||
|
||||
#define PIXEL_MULTIPLIER WORLD_ICON_SIZE/32 //Needed for the R-UST port
|
||||
@@ -87,12 +87,6 @@ var/list/global_huds = list(
|
||||
science = setup_overlay("science_hud")
|
||||
material = setup_overlay("material_hud")
|
||||
|
||||
// The holomap screen object is actually totally invisible.
|
||||
// Station maps work by setting it as an images location before sending to client, not
|
||||
// actually changing the icon or icon state of the screen object itself!
|
||||
// Why do they work this way? I don't know really, that is how /vg designed them, but since they DO
|
||||
// work this way, we can take advantage of their immutability by making them part of
|
||||
// the global_hud (something we have and /vg doesn't) instead of an instance per mob.
|
||||
holomap = new /obj/screen()
|
||||
holomap.name = "holomap"
|
||||
holomap.icon = null
|
||||
@@ -191,13 +185,14 @@ var/list/global_huds = list(
|
||||
|
||||
var/list/minihuds = list()
|
||||
|
||||
datum/hud/New(mob/owner)
|
||||
/datum/hud/New(mob/owner)
|
||||
mymob = owner
|
||||
instantiate()
|
||||
..()
|
||||
|
||||
/datum/hud/Destroy()
|
||||
. = ..()
|
||||
qdel_null(minihuds)
|
||||
grab_intent = null
|
||||
hurt_intent = null
|
||||
disarm_intent = null
|
||||
@@ -216,7 +211,6 @@ datum/hud/New(mob/owner)
|
||||
hotkeybuttons = null
|
||||
// item_action_list = null // ?
|
||||
mymob = null
|
||||
qdel_null(minihuds)
|
||||
|
||||
/datum/hud/proc/hidden_inventory_update()
|
||||
if(!mymob) return
|
||||
|
||||
36
code/_onclick/hud/minihud.dm
Normal file
36
code/_onclick/hud/minihud.dm
Normal file
@@ -0,0 +1,36 @@
|
||||
/datum/mini_hud
|
||||
var/datum/hud/main_hud
|
||||
var/list/screenobjs
|
||||
var/needs_processing = FALSE
|
||||
|
||||
/datum/mini_hud/New(var/datum/hud/other)
|
||||
apply_to_hud(other)
|
||||
if(needs_processing)
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/datum/mini_hud/Destroy()
|
||||
unapply_to_hud()
|
||||
if(needs_processing)
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
QDEL_LIST_NULL(screenobjs)
|
||||
return ..()
|
||||
|
||||
// Apply to a real /datum/hud
|
||||
/datum/mini_hud/proc/apply_to_hud(var/datum/hud/other)
|
||||
if(main_hud)
|
||||
unapply_to_hud(main_hud)
|
||||
main_hud = other
|
||||
main_hud.apply_minihud(src)
|
||||
|
||||
// Remove from a real /datum/hud
|
||||
/datum/mini_hud/proc/unapply_to_hud()
|
||||
main_hud?.remove_minihud(src)
|
||||
main_hud = null
|
||||
|
||||
// Update the hud
|
||||
/datum/mini_hud/process()
|
||||
return PROCESS_KILL // You shouldn't be here!
|
||||
|
||||
// Return a list of screen objects we use
|
||||
/datum/mini_hud/proc/get_screen_objs(var/mob/M)
|
||||
return screenobjs.Copy()
|
||||
13
code/_onclick/hud/minihud_mapper.dm
Normal file
13
code/_onclick/hud/minihud_mapper.dm
Normal file
@@ -0,0 +1,13 @@
|
||||
// Specific types
|
||||
/datum/mini_hud/mapper
|
||||
var/obj/item/device/mapping_unit/owner
|
||||
|
||||
/datum/mini_hud/mapper/New(var/datum/hud/other, owner)
|
||||
src.owner = owner
|
||||
screenobjs = list(new /obj/screen/movable/mapper_holder(null, owner))
|
||||
..()
|
||||
|
||||
/datum/mini_hud/mapper/Destroy()
|
||||
owner?.hud_item = null
|
||||
owner?.hud_datum = null
|
||||
return ..()
|
||||
@@ -1,40 +1,3 @@
|
||||
/datum/mini_hud
|
||||
var/datum/hud/main_hud
|
||||
var/list/screenobjs = list()
|
||||
var/list/types_to_instantiate
|
||||
var/needs_processing = FALSE
|
||||
|
||||
/datum/mini_hud/New(var/datum/hud/other)
|
||||
apply_to_hud(other)
|
||||
if(needs_processing)
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/datum/mini_hud/Destroy()
|
||||
main_hud?.remove_minihud(src)
|
||||
main_hud = null
|
||||
if(needs_processing)
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
return ..()
|
||||
|
||||
// Apply to a real /datum/hud
|
||||
/datum/mini_hud/proc/apply_to_hud(var/datum/hud/other)
|
||||
if(main_hud)
|
||||
unapply_to_hud(main_hud)
|
||||
main_hud = other
|
||||
main_hud.apply_minihud(src)
|
||||
|
||||
// Remove from a real /datum/hud
|
||||
/datum/mini_hud/proc/unapply_to_hud(var/datum/hud/other)
|
||||
main_hud.remove_minihud(src)
|
||||
|
||||
// Update the hud
|
||||
/datum/mini_hud/process()
|
||||
return PROCESS_KILL // You shouldn't be here!
|
||||
|
||||
// Return a list of screen objects we use
|
||||
/datum/mini_hud/proc/get_screen_objs(var/mob/M)
|
||||
return screenobjs
|
||||
|
||||
// Specific types
|
||||
/datum/mini_hud/rig
|
||||
var/obj/item/weapon/rig/owner_rig
|
||||
@@ -655,3 +655,218 @@
|
||||
holder.screen -= src
|
||||
holder = null
|
||||
return ..()
|
||||
|
||||
|
||||
/**
|
||||
* This object holds all the on-screen elements of the mapping unit.
|
||||
* It has a decorative frame and onscreen buttons. The map itself is drawn
|
||||
* using a white mask and multiplying the mask against it to crop it to the
|
||||
* size of the screen. This is not ideal, as filter() is faster, and has
|
||||
* alpha masks, but the alpha masks it has can't be animated, so the 'ping'
|
||||
* mode of this device isn't possible using that technique.
|
||||
*
|
||||
* The markers use that technique, though, so at least there's that.
|
||||
*/
|
||||
/obj/screen/movable/mapper_holder
|
||||
name = "gps unit"
|
||||
icon = null
|
||||
icon_state = ""
|
||||
screen_loc = "CENTER,CENTER"
|
||||
alpha = 255
|
||||
appearance_flags = KEEP_TOGETHER
|
||||
mouse_opacity = 1
|
||||
plane = PLANE_HOLOMAP
|
||||
|
||||
var/running = FALSE
|
||||
|
||||
var/obj/screen/mapper/mask_full/mask_full
|
||||
var/obj/screen/mapper/mask_ping/mask_ping
|
||||
var/obj/screen/mapper/bg/bg
|
||||
|
||||
var/obj/screen/mapper/frame/frame
|
||||
var/obj/screen/mapper/powbutton/powbutton
|
||||
var/obj/screen/mapper/mapbutton/mapbutton
|
||||
|
||||
var/obj/item/device/mapping_unit/owner
|
||||
var/obj/screen/mapper/extras_holder/extras_holder
|
||||
|
||||
/obj/screen/movable/mapper_holder/Initialize(mapload, newowner)
|
||||
owner = newowner
|
||||
|
||||
mask_full = new(src) // Full white square mask
|
||||
mask_ping = new(src) // Animated 'pinging' mask
|
||||
bg = new(src) // Background color, holds map in vis_contents, uses mult against masks
|
||||
|
||||
frame = new(src) // Decorative frame
|
||||
powbutton = new(src) // Clickable button
|
||||
mapbutton = new(src) // Clickable button
|
||||
|
||||
frame.icon_state = initial(frame.icon_state)+owner.hud_frame_hint
|
||||
|
||||
/**
|
||||
* The vis_contents layout is: this(frame,extras_holder,mask(bg(map)))
|
||||
* bg is set to BLEND_MULTIPLY against the mask to crop it.
|
||||
*/
|
||||
|
||||
mask_full.vis_contents.Add(bg)
|
||||
mask_ping.vis_contents.Add(bg)
|
||||
frame.vis_contents.Add(powbutton,mapbutton)
|
||||
vis_contents.Add(frame)
|
||||
|
||||
|
||||
/obj/screen/movable/mapper_holder/Destroy()
|
||||
qdel_null(mask_full)
|
||||
qdel_null(mask_ping)
|
||||
qdel_null(bg)
|
||||
|
||||
qdel_null(frame)
|
||||
qdel_null(powbutton)
|
||||
qdel_null(mapbutton)
|
||||
|
||||
extras_holder = null
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
/obj/screen/movable/mapper_holder/proc/update(var/obj/screen/mapper/map, var/obj/screen/mapper/extras_holder/extras, ping = FALSE)
|
||||
if(!running)
|
||||
running = TRUE
|
||||
if(ping)
|
||||
vis_contents.Add(mask_ping)
|
||||
else
|
||||
vis_contents.Add(mask_full)
|
||||
|
||||
bg.vis_contents.Cut()
|
||||
bg.vis_contents.Add(map)
|
||||
|
||||
if(extras && !extras_holder)
|
||||
extras_holder = extras
|
||||
vis_contents += extras_holder
|
||||
if(!extras && extras_holder)
|
||||
vis_contents -= extras_holder
|
||||
extras_holder = null
|
||||
|
||||
/obj/screen/movable/mapper_holder/proc/powerClick()
|
||||
if(running)
|
||||
off()
|
||||
else
|
||||
on()
|
||||
|
||||
/obj/screen/movable/mapper_holder/proc/mapClick()
|
||||
if(owner)
|
||||
if(running)
|
||||
off()
|
||||
owner.pinging = !owner.pinging
|
||||
on()
|
||||
|
||||
/obj/screen/movable/mapper_holder/proc/off(var/inform = TRUE)
|
||||
frame.cut_overlay("powlight")
|
||||
bg.vis_contents.Cut()
|
||||
vis_contents.Remove(mask_ping, mask_full, extras_holder)
|
||||
extras_holder = null
|
||||
running = FALSE
|
||||
if(inform)
|
||||
owner.stop_updates()
|
||||
|
||||
/obj/screen/movable/mapper_holder/proc/on(var/inform = TRUE)
|
||||
frame.add_overlay("powlight")
|
||||
if(inform)
|
||||
owner.start_updates()
|
||||
|
||||
// Prototype
|
||||
/obj/screen/mapper
|
||||
plane = PLANE_HOLOMAP
|
||||
mouse_opacity = 0
|
||||
var/obj/screen/movable/mapper_holder/parent
|
||||
|
||||
/obj/screen/mapper/New()
|
||||
..()
|
||||
parent = loc
|
||||
|
||||
/obj/screen/mapper/Destroy()
|
||||
parent = null
|
||||
return ..()
|
||||
|
||||
// Holds the actual map image
|
||||
/obj/screen/mapper/map
|
||||
var/offset_x = 32
|
||||
var/offset_y = 32
|
||||
|
||||
// I really wish I could use filters for this instead of this multiplication-masking technique
|
||||
// but alpha filters can't be animated, which means I can't use them for the 'sonar ping' mode.
|
||||
// If filters start supporting animated icons in the future (for the alpha mask filter),
|
||||
// you should definitely replace these with that technique instead.
|
||||
/obj/screen/mapper/mask_full
|
||||
icon = 'icons/effects/64x64.dmi'
|
||||
icon_state = "mapper_mask"
|
||||
|
||||
/obj/screen/mapper/mask_ping
|
||||
icon = 'icons/effects/64x64.dmi'
|
||||
icon_state = "mapper_ping"
|
||||
|
||||
/obj/screen/mapper/bg
|
||||
icon = 'icons/effects/64x64.dmi'
|
||||
icon_state = "mapper_bg"
|
||||
|
||||
blend_mode = BLEND_MULTIPLY
|
||||
appearance_flags = KEEP_TOGETHER
|
||||
|
||||
// Frame/deco components
|
||||
/obj/screen/mapper/frame
|
||||
icon = 'icons/effects/gpshud.dmi'
|
||||
icon_state = "frame"
|
||||
plane = PLANE_HOLOMAP_FRAME
|
||||
pixel_x = -18
|
||||
pixel_y = -29
|
||||
mouse_opacity = 1
|
||||
vis_flags = VIS_INHERIT_ID
|
||||
|
||||
/obj/screen/mapper/powbutton
|
||||
icon = 'icons/effects/gpshud.dmi'
|
||||
icon_state = "powbutton"
|
||||
plane = PLANE_HOLOMAP_FRAME
|
||||
mouse_opacity = 1
|
||||
|
||||
/obj/screen/mapper/powbutton/Click()
|
||||
if(!usr.checkClickCooldown())
|
||||
return TRUE
|
||||
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
|
||||
return TRUE
|
||||
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
return TRUE
|
||||
parent.powerClick()
|
||||
flick("powClick",src)
|
||||
usr << get_sfx("button")
|
||||
return TRUE
|
||||
|
||||
/obj/screen/mapper/mapbutton
|
||||
icon = 'icons/effects/gpshud.dmi'
|
||||
icon_state = "mapbutton"
|
||||
plane = PLANE_HOLOMAP_FRAME
|
||||
mouse_opacity = 1
|
||||
|
||||
/obj/screen/mapper/mapbutton/Click()
|
||||
if(!usr.checkClickCooldown())
|
||||
return TRUE
|
||||
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
|
||||
return TRUE
|
||||
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
return TRUE
|
||||
parent.mapClick()
|
||||
flick("mapClick",src)
|
||||
usr << get_sfx("button")
|
||||
return TRUE
|
||||
|
||||
// Markers are 16x16, people have apparently settled on centering them on the 8,8 pixel
|
||||
/obj/screen/mapper/marker
|
||||
icon = 'icons/holomap_markers.dmi'
|
||||
plane = PLANE_HOLOMAP_ICONS
|
||||
|
||||
var/offset_x = -8
|
||||
var/offset_y = -8
|
||||
|
||||
// Holds markers in its vis_contents. It uses an alpha filter to crop them to the HUD screen size
|
||||
/obj/screen/mapper/extras_holder
|
||||
icon = null
|
||||
icon_state = null
|
||||
plane = PLANE_HOLOMAP_ICONS
|
||||
appearance_flags = KEEP_TOGETHER
|
||||
|
||||
@@ -62,6 +62,5 @@
|
||||
client.update_skybox()
|
||||
client.skybox?.scale_to_view(client.view)
|
||||
|
||||
#undef SKYBOX_BORDER
|
||||
#undef SKYBOX_PIXELS
|
||||
#undef SKYBOX_TURFS
|
||||
|
||||
@@ -4,14 +4,14 @@ These are the default click code call sequences used when clicking on stuff with
|
||||
|
||||
Atoms:
|
||||
|
||||
mob/ClickOn() calls the item's resolve_attackby() proc.
|
||||
/mob/ClickOn() calls the item's resolve_attackby() proc.
|
||||
item/resolve_attackby() calls the target atom's attackby() proc.
|
||||
|
||||
Mobs:
|
||||
|
||||
mob/living/attackby() after checking for surgery, calls the item's attack() proc.
|
||||
/mob/living/attackby() after checking for surgery, calls the item's attack() proc.
|
||||
item/attack() generates attack logs, sets click cooldown and calls the mob's attacked_with_item() proc. If you override this, consider whether you need to set a click cooldown, play attack animations, and generate logs yourself.
|
||||
mob/attacked_with_item() should then do mob-type specific stuff (like determining hit/miss, handling shields, etc) and then possibly call the item's apply_hit_effect() proc to actually apply the effects of being hit.
|
||||
/mob/attacked_with_item() should then do mob-type specific stuff (like determining hit/miss, handling shields, etc) and then possibly call the item's apply_hit_effect() proc to actually apply the effects of being hit.
|
||||
|
||||
Item Hit Effects:
|
||||
|
||||
@@ -41,11 +41,6 @@ avoid code duplication. This includes items that may sometimes act as a standard
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/atom/movable/attackby(obj/item/W, mob/user, var/attack_modifier, var/click_parameters)
|
||||
. = ..()
|
||||
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, var/attack_modifier, var/click_parameters)
|
||||
if(!ismob(user))
|
||||
return 0
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
var/datum/controller/transfer_controller/transfer_controller
|
||||
|
||||
datum/controller/transfer_controller
|
||||
/datum/controller/transfer_controller
|
||||
var/timerbuffer = 0 //buffer for time check
|
||||
var/currenttick = 0
|
||||
datum/controller/transfer_controller/New()
|
||||
/datum/controller/transfer_controller/New()
|
||||
timerbuffer = config.vote_autotransfer_initial
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
datum/controller/transfer_controller/Destroy()
|
||||
/datum/controller/transfer_controller/Destroy()
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
|
||||
datum/controller/transfer_controller/process()
|
||||
/datum/controller/transfer_controller/process()
|
||||
currenttick = currenttick + 1
|
||||
if (round_duration_in_ds >= timerbuffer - 1 MINUTE)
|
||||
SSvote.autotransfer()
|
||||
|
||||
@@ -154,9 +154,6 @@ var/list/ANTAG_FREQS = list(SYND_FREQ, RAID_FREQ)
|
||||
//Department channels, arranged lexically
|
||||
var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, ENT_FREQ, MED_FREQ, SEC_FREQ, SCI_FREQ, SRV_FREQ, SUP_FREQ)
|
||||
|
||||
#define TRANSMISSION_WIRE 0
|
||||
#define TRANSMISSION_RADIO 1
|
||||
|
||||
/proc/frequency_span_class(var/frequency)
|
||||
// Antags!
|
||||
if (frequency in ANTAG_FREQS)
|
||||
|
||||
@@ -56,23 +56,23 @@ var/datum/controller/failsafe/Failsafe
|
||||
if(4,5)
|
||||
--defcon
|
||||
if(3)
|
||||
to_chat(admins, "<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.</span>")
|
||||
log_and_message_admins("<span class='adminnotice'>SSfailsafe Notice: DEFCON [defcon_pretty()]. The Master Controller (\ref[Master]) has not fired in the last [(5-defcon) * processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(2)
|
||||
to_chat(admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
|
||||
log_and_message_admins("<span class='boldannounce'>SSfailsafe Warning: DEFCON [defcon_pretty()]. The Master Controller (\ref[Master]) has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
|
||||
--defcon
|
||||
if(1)
|
||||
|
||||
to_chat(admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>")
|
||||
log_and_message_admins("<span class='boldannounce'>SSfailsafe Warning: DEFCON [defcon_pretty()]. The Master Controller (\ref[Master]) has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>")
|
||||
--defcon
|
||||
var/rtn = Recreate_MC()
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
log_and_message_admins("<span class='adminnotice'>SSfailsafe Notice: MC (New:\ref[Master]) restarted successfully</span>")
|
||||
else if(rtn < 0)
|
||||
log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0")
|
||||
to_chat(admins, "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>")
|
||||
log_game("SSfailsafe Notice: Could not restart MC (\ref[Master]), runtime encountered. Entering defcon 0")
|
||||
log_and_message_admins("<span class='boldannounce'>SSFAILSAFE ERROR: DEFCON [defcon_pretty()]. Could not restart MC (\ref[Master]), runtime encountered. I will silently keep retrying.</span>")
|
||||
//if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again
|
||||
//no need to handle that specially when defcon 0 can handle it
|
||||
if(0) //DEFCON 0! (mc failed to restart)
|
||||
@@ -80,7 +80,7 @@ var/datum/controller/failsafe/Failsafe
|
||||
if(rtn > 0)
|
||||
defcon = 4
|
||||
master_iteration = 0
|
||||
to_chat(admins, "<span class='adminnotice'>MC restarted successfully</span>")
|
||||
log_and_message_admins("<span class='adminnotice'>SSfailsafe Notice: MC (New:\ref[Master]) restarted successfully</span>")
|
||||
else
|
||||
defcon = min(defcon + 1,5)
|
||||
master_iteration = Master.iteration
|
||||
|
||||
@@ -132,10 +132,10 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
LAZYINITLIST(BadBoy.failure_strikes)
|
||||
switch(++BadBoy.failure_strikes[BadBoy.type])
|
||||
if(2)
|
||||
msg = "The [BadBoy.name] subsystem was the last to fire for 2 controller restarts. It will be recovered now and disabled if it happens again."
|
||||
msg = "MC Notice: The [BadBoy.name] subsystem was the last to fire for 2 controller restarts. It will be recovered now and disabled if it happens again."
|
||||
FireHim = TRUE
|
||||
if(3)
|
||||
msg = "The [BadBoy.name] subsystem seems to be destabilizing the MC and will be offlined."
|
||||
msg = "MC Notice: The [BadBoy.name] subsystem seems to be destabilizing the MC and will be offlined."
|
||||
BadBoy.flags |= SS_NO_FIRE
|
||||
if(msg)
|
||||
log_game(msg)
|
||||
@@ -150,7 +150,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
current_runlevel = Master.current_runlevel
|
||||
StartProcessing(10)
|
||||
else
|
||||
to_chat(world, "<span class='boldannounce'>The Master Controller is having some issues, we will need to re-initialize EVERYTHING</span>")
|
||||
to_world("<span class='boldannounce'>The Master Controller is having some issues, we will need to re-initialize EVERYTHING</span>")
|
||||
Initialize(20, TRUE)
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
if(init_sss)
|
||||
init_subtypes(/datum/controller/subsystem, subsystems)
|
||||
|
||||
to_chat(world, "<span class='boldannounce'>Initializing subsystems...</span>")
|
||||
to_chat(world, "<span class='boldannounce'>MC: Initializing subsystems...</span>")
|
||||
|
||||
// Sort subsystems by init_order, so they initialize in the correct order.
|
||||
sortTim(subsystems, /proc/cmp_subsystem_init)
|
||||
@@ -181,7 +181,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
var/time = (REALTIMEOFDAY - start_timeofday) / 10
|
||||
|
||||
var/msg = "Initializations complete within [time] second[time == 1 ? "" : "s"]!"
|
||||
var/msg = "MC: Initializations complete within [time] second[time == 1 ? "" : "s"]!"
|
||||
to_chat(world, "<span class='boldannounce'>[msg]</span>")
|
||||
log_world(msg)
|
||||
|
||||
@@ -219,13 +219,17 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
if (rtn > 0 || processing < 0)
|
||||
return //this was suppose to happen.
|
||||
//loop ended, restart the mc
|
||||
log_game("MC crashed or runtimed, restarting")
|
||||
message_admins("MC crashed or runtimed, restarting")
|
||||
log_and_message_admins("MC Notice: MC crashed or runtimed, self-restarting (\ref[src])")
|
||||
var/rtn2 = Recreate_MC()
|
||||
if (rtn2 <= 0)
|
||||
log_game("Failed to recreate MC (Error code: [rtn2]), it's up to the failsafe now")
|
||||
message_admins("Failed to recreate MC (Error code: [rtn2]), it's up to the failsafe now")
|
||||
switch(rtn2)
|
||||
if(-1)
|
||||
log_and_message_admins("MC Warning: Failed to self-recreate MC (Return code: [rtn2]), it's up to the failsafe now (\ref[src])")
|
||||
Failsafe.defcon = 2
|
||||
if(0)
|
||||
log_and_message_admins("MC Warning: Too soon for MC self-restart (Return code: [rtn2]), going to let failsafe handle it (\ref[src])")
|
||||
Failsafe.defcon = 2
|
||||
if(1)
|
||||
log_and_message_admins("MC Notice: MC self-recreated, old MC departing (Return code: [rtn2]) (\ref[src])")
|
||||
|
||||
// Main loop.
|
||||
/datum/controller/master/proc/Loop()
|
||||
|
||||
@@ -13,10 +13,10 @@ var/global/last_tick_duration = 0
|
||||
|
||||
var/global/pipe_processing_killed = 0
|
||||
|
||||
datum/controller/game_controller
|
||||
/datum/controller/game_controller
|
||||
var/list/shuttle_list // For debugging and VV
|
||||
|
||||
datum/controller/game_controller/New()
|
||||
/datum/controller/game_controller/New()
|
||||
//There can be only one master_controller. Out with the old and in with the new.
|
||||
if(master_controller != src)
|
||||
log_debug("Rebuilding Master Controller")
|
||||
@@ -33,7 +33,7 @@ datum/controller/game_controller/New()
|
||||
if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase()
|
||||
if(!syndicate_code_response) syndicate_code_response = generate_code_phrase()
|
||||
|
||||
datum/controller/game_controller/proc/setup()
|
||||
/datum/controller/game_controller/proc/setup()
|
||||
|
||||
setup_objects()
|
||||
// setupgenetics() Moved to SSatoms
|
||||
@@ -48,7 +48,7 @@ datum/controller/game_controller/proc/setup()
|
||||
// #define CHECK_SLEEP_MASTER if(++initialized_objects > 500) { initialized_objects=0;sleep(world.tick_lag); }
|
||||
// #endif
|
||||
|
||||
datum/controller/game_controller/proc/setup_objects()
|
||||
/datum/controller/game_controller/proc/setup_objects()
|
||||
// Set up antagonists.
|
||||
populate_antag_type_list()
|
||||
|
||||
|
||||
@@ -68,8 +68,12 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
/datum/controller/subsystem/air/fire(resumed = 0)
|
||||
var/timer
|
||||
if(!resumed)
|
||||
ASSERT(LAZYLEN(currentrun) == 0) // Santity checks to make sure we don't somehow have items left over from last cycle
|
||||
ASSERT(current_step == null) // Or somehow didn't finish all the steps from last cycle
|
||||
// Santity checks to make sure we don't somehow have items left over from last cycle
|
||||
// Or somehow didn't finish all the steps from last cycle
|
||||
if(LAZYLEN(currentrun) || current_step)
|
||||
log_and_message_admins("SSair: Was told to start a new run, but the previous run wasn't finished! currentrun.len=[currentrun.len], current_step=[current_step]")
|
||||
resumed = TRUE
|
||||
else
|
||||
current_cycle++ // Begin a new air_master cycle!
|
||||
current_step = SSAIR_TURFS // Start with Step 1 of course
|
||||
|
||||
@@ -80,8 +84,9 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
INTERNAL_PROCESS_STEP(SSAIR_ZONES, FALSE, process_zones_to_update, cost_zones, SSAIR_DONE)
|
||||
|
||||
// Okay, we're done! Woo! Got thru a whole air_master cycle!
|
||||
ASSERT(LAZYLEN(currentrun) == 0) // Sanity checks to make sure there are really none left
|
||||
ASSERT(current_step == SSAIR_DONE) // And that we didn't somehow skip past the last step
|
||||
if(LAZYLEN(currentrun) || current_step != SSAIR_DONE)
|
||||
log_and_message_admins("SSair: Was not able to complete a full air cycle despite reaching the end of fire(). This shouldn't happen.")
|
||||
else
|
||||
currentrun = null
|
||||
current_step = null
|
||||
|
||||
|
||||
@@ -45,8 +45,12 @@ SUBSYSTEM_DEF(lighting)
|
||||
/datum/controller/subsystem/lighting/fire(resumed = FALSE)
|
||||
var/timer
|
||||
if(!resumed)
|
||||
ASSERT(LAZYLEN(currentrun) == 0) // Santity checks to make sure we don't somehow have items left over from last cycle
|
||||
ASSERT(stage == null) // Or somehow didn't finish all the steps from last cycle
|
||||
// Santity checks to make sure we don't somehow have items left over from last cycle
|
||||
// Or somehow didn't finish all the steps from last cycle
|
||||
if(LAZYLEN(currentrun) || stage)
|
||||
log_and_message_admins("SSlighting: Was told to start a new run, but the previous run wasn't finished! currentrun.len=[currentrun.len], stage=[stage]")
|
||||
resumed = TRUE
|
||||
else
|
||||
stage = SSLIGHTING_STAGE_LIGHTS // Start with Step 1 of course
|
||||
|
||||
if(stage == SSLIGHTING_STAGE_LIGHTS)
|
||||
@@ -77,8 +81,9 @@ SUBSYSTEM_DEF(lighting)
|
||||
stage = SSLIGHTING_STAGE_DONE
|
||||
|
||||
// Okay, we're done! Woo! Got thru a whole air_master cycle!
|
||||
ASSERT(LAZYLEN(currentrun) == 0) // Sanity checks to make sure there are really none left
|
||||
ASSERT(stage == SSLIGHTING_STAGE_DONE) // And that we didn't somehow skip past the last step
|
||||
if(LAZYLEN(currentrun) || stage != SSLIGHTING_STAGE_DONE)
|
||||
log_and_message_admins("SSlighting: Was not able to complete a full lighting cycle despite reaching the end of fire(). This shouldn't happen.")
|
||||
else
|
||||
currentrun = null
|
||||
stage = null
|
||||
|
||||
@@ -163,4 +168,3 @@ SUBSYSTEM_DEF(lighting)
|
||||
#undef SSLIGHTING_STAGE_LIGHTS
|
||||
#undef SSLIGHTING_STAGE_CORNERS
|
||||
#undef SSLIGHTING_STAGE_OVERLAYS
|
||||
#undef SSLIGHTING_STAGE_STATS
|
||||
@@ -175,5 +175,4 @@ SUBSYSTEM_DEF(machines)
|
||||
|
||||
#undef SSMACHINES_PIPENETS
|
||||
#undef SSMACHINES_MACHINERY
|
||||
#undef SSMACHINES_POWER
|
||||
#undef SSMACHINES_POWER_OBJECTS
|
||||
|
||||
@@ -200,10 +200,11 @@ SUBSYSTEM_DEF(supply)
|
||||
else if(islist(SP.access) && SP.one_access)
|
||||
var/list/L = SP.access // access var is a plain var, we need a list
|
||||
A.req_one_access = L.Copy()
|
||||
A.req_access.Cut()
|
||||
LAZYCLEARLIST(A.req_access)
|
||||
else if(islist(SP.access) && !SP.one_access)
|
||||
var/list/L = SP.access
|
||||
A.req_access = L.Copy()
|
||||
LAZYCLEARLIST(A.req_one_access)
|
||||
else
|
||||
log_debug("<span class='danger'>Supply pack with invalid access restriction [SP.access] encountered!</span>")
|
||||
|
||||
|
||||
@@ -305,8 +305,7 @@
|
||||
div_slider = "locked"
|
||||
output += {"<li>
|
||||
<label class="switch">
|
||||
<input type="[inputtype]" value="1" name="[i["name"]]"[i["checked"] ? " checked" : ""][i["allowed_edit"] ? "" : " onclick='return false' onkeydown='return false'"]>
|
||||
<div class="slider [div_slider ? "[div_slider]" : ""]"></div>
|
||||
<input type="[inputtype]" value="1" name="[i["name"]]"[i["checked"] ? " checked" : ""][i["allowed_edit"] ? "" : " disabled onclick='return false' onkeydown='return false'"]>
|
||||
<span>[i["name"]]</span>
|
||||
</label>
|
||||
</li>"}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
collection = null
|
||||
return ..()
|
||||
|
||||
datum/category_group/dd_SortValue()
|
||||
/datum/category_group/dd_SortValue()
|
||||
return name
|
||||
|
||||
|
||||
@@ -77,5 +77,5 @@ datum/category_group/dd_SortValue()
|
||||
category = null
|
||||
return ..()
|
||||
|
||||
datum/category_item/dd_SortValue()
|
||||
/datum/category_item/dd_SortValue()
|
||||
return name
|
||||
|
||||
336
code/datums/chat_message.dm
Normal file
336
code/datums/chat_message.dm
Normal file
@@ -0,0 +1,336 @@
|
||||
#define CHAT_MESSAGE_SPAWN_TIME 0.2 SECONDS
|
||||
#define CHAT_MESSAGE_LIFESPAN 5 SECONDS
|
||||
#define CHAT_MESSAGE_EOL_FADE 0.7 SECONDS
|
||||
#define CHAT_MESSAGE_EXP_DECAY 0.8 // Messages decay at pow(factor, idx in stack)
|
||||
#define CHAT_MESSAGE_HEIGHT_DECAY 0.7 // Increase message decay based on the height of the message
|
||||
#define CHAT_MESSAGE_APPROX_LHEIGHT 11 // Approximate height in pixels of an 'average' line, used for height decay
|
||||
|
||||
#define CHAT_MESSAGE_WIDTH 96 // pixels
|
||||
#define CHAT_MESSAGE_EXT_WIDTH 128
|
||||
#define CHAT_MESSAGE_LENGTH 68 // characters
|
||||
#define CHAT_MESSAGE_EXT_LENGTH 150
|
||||
|
||||
#define CHAT_MESSAGE_MOB 1
|
||||
#define CHAT_MESSAGE_OBJ 2
|
||||
#define WXH_TO_HEIGHT(x) text2num(copytext((x), findtextEx((x), "x") + 1)) // thanks lummox
|
||||
|
||||
#define CHAT_RUNE_EMOTE 0x1
|
||||
#define CHAT_RUNE_RADIO 0x2
|
||||
|
||||
/**
|
||||
* # Chat Message Overlay
|
||||
*
|
||||
* Datum for generating a message overlay on the map
|
||||
* Ported from TGStation; https://github.com/tgstation/tgstation/pull/50608/, author: bobbahbrown
|
||||
*/
|
||||
|
||||
// Cached runechat icon
|
||||
var/list/runechat_image_cache = list()
|
||||
|
||||
|
||||
/hook/startup/proc/runechat_images()
|
||||
var/image/radio_image = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "radio")
|
||||
runechat_image_cache["radio"] = radio_image
|
||||
|
||||
var/image/emote_image = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "emote")
|
||||
runechat_image_cache["emote"] = emote_image
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/chatmessage
|
||||
/// The visual element of the chat messsage
|
||||
var/image/message
|
||||
/// The location in which the message is appearing
|
||||
var/atom/message_loc
|
||||
/// The client who heard this message
|
||||
var/client/owned_by
|
||||
/// Contains the scheduled destruction time
|
||||
var/scheduled_destruction
|
||||
/// Contains the approximate amount of lines for height decay
|
||||
var/approx_lines
|
||||
/// If we are currently processing animation and cleanup at EOL
|
||||
var/ending_life
|
||||
|
||||
/**
|
||||
* Constructs a chat message overlay
|
||||
*
|
||||
* Arguments:
|
||||
* * text - The text content of the overlay
|
||||
* * target - The target atom to display the overlay at
|
||||
* * owner - The mob that owns this overlay, only this mob will be able to view it
|
||||
* * extra_classes - Extra classes to apply to the span that holds the text
|
||||
* * lifespan - The lifespan of the message in deciseconds
|
||||
*/
|
||||
/datum/chatmessage/New(text, atom/target, mob/owner, list/extra_classes = null, lifespan = CHAT_MESSAGE_LIFESPAN)
|
||||
. = ..()
|
||||
if(!istype(target))
|
||||
CRASH("Invalid target given for chatmessage")
|
||||
if(!istype(owner) || QDELETED(owner) || !owner.client)
|
||||
stack_trace("/datum/chatmessage created with [isnull(owner) ? "null" : "invalid"] mob owner")
|
||||
qdel(src)
|
||||
return
|
||||
generate_image(text, target, owner, extra_classes, lifespan)
|
||||
|
||||
/datum/chatmessage/Destroy()
|
||||
if(owned_by)
|
||||
UnregisterSignal(owned_by, COMSIG_PARENT_QDELETING)
|
||||
LAZYREMOVEASSOC(owned_by.seen_messages, message_loc, src)
|
||||
owned_by.images.Remove(message)
|
||||
if(message_loc)
|
||||
UnregisterSignal(message_loc, COMSIG_PARENT_QDELETING)
|
||||
owned_by = null
|
||||
message_loc = null
|
||||
message = null
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Generates a chat message image representation
|
||||
*
|
||||
* Arguments:
|
||||
* * text - The text content of the overlay
|
||||
* * target - The target atom to display the overlay at
|
||||
* * owner - The mob that owns this overlay, only this mob will be able to view it
|
||||
* * extra_classes - Extra classes to apply to the span that holds the text
|
||||
* * lifespan - The lifespan of the message in deciseconds
|
||||
*/
|
||||
/datum/chatmessage/proc/generate_image(text, atom/target, mob/owner, list/extra_classes, lifespan)
|
||||
set waitfor = FALSE
|
||||
|
||||
if(!target || !owner)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
// Register client who owns this message
|
||||
owned_by = owner.client
|
||||
RegisterSignal(owned_by, COMSIG_PARENT_QDELETING, .proc/qdel_self)
|
||||
|
||||
var/extra_length = owned_by.is_preference_enabled(/datum/client_preference/runechat_long_messages)
|
||||
var/maxlen = extra_length ? CHAT_MESSAGE_EXT_LENGTH : CHAT_MESSAGE_LENGTH
|
||||
var/msgwidth = extra_length ? CHAT_MESSAGE_EXT_WIDTH : CHAT_MESSAGE_WIDTH
|
||||
|
||||
// Clip message
|
||||
if(length_char(text) > maxlen)
|
||||
text = copytext_char(text, 1, maxlen + 1) + "..." // BYOND index moment
|
||||
|
||||
// Calculate target color if not already present
|
||||
if(!target.chat_color || target.chat_color_name != target.name)
|
||||
target.chat_color = colorize_string(target.name)
|
||||
target.chat_color_darkened = colorize_string(target.name, 0.85, 0.85)
|
||||
target.chat_color_name = target.name
|
||||
|
||||
// Get rid of any URL schemes that might cause BYOND to automatically wrap something in an anchor tag
|
||||
var/static/regex/url_scheme = new(@"[A-Za-z][A-Za-z0-9+-\.]*:\/\/", "g")
|
||||
text = replacetext(text, url_scheme, "")
|
||||
|
||||
// Reject whitespace
|
||||
var/static/regex/whitespace = new(@"^\s*$")
|
||||
if(whitespace.Find(text))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
// Non mobs speakers can be small
|
||||
if(!ismob(target))
|
||||
extra_classes |= "small"
|
||||
|
||||
// If we heard our name, it's important
|
||||
// Differnt from our own system of name emphasis, maybe unify
|
||||
var/list/names = splittext(owner.name, " ")
|
||||
for (var/word in names)
|
||||
text = replacetext(text, word, "<b>[word]</b>")
|
||||
|
||||
var/list/prefixes
|
||||
|
||||
// Append prefixes
|
||||
if(extra_classes.Find("virtual-speaker"))
|
||||
LAZYADD(prefixes, "\icon[runechat_image_cache["radio"]]")
|
||||
if(extra_classes.Find("emote"))
|
||||
// Icon on both ends?
|
||||
//var/image/I = runechat_image_cache["emote"]
|
||||
//text = "\icon[I][text]\icon[I]"
|
||||
|
||||
// Icon on one end?
|
||||
//LAZYADD(prefixes, "\icon[runechat_image_cache["emote"]]")
|
||||
|
||||
// Asterisks instead?
|
||||
text = "* [text] *"
|
||||
|
||||
text = "[prefixes?.Join(" ")][text]"
|
||||
|
||||
text = encode_html_emphasis(text)
|
||||
|
||||
// We dim italicized text to make it more distinguishable from regular text
|
||||
var/tgt_color = extra_classes.Find("italics") ? target.chat_color_darkened : target.chat_color
|
||||
|
||||
// Approximate text height
|
||||
var/complete_text = "<span class='center maptext [extra_classes != null ? extra_classes.Join(" ") : ""]' style='color: [tgt_color];'>[text]</span>"
|
||||
var/mheight = WXH_TO_HEIGHT(owned_by.MeasureText(complete_text, null, msgwidth))
|
||||
approx_lines = max(1, mheight / CHAT_MESSAGE_APPROX_LHEIGHT)
|
||||
|
||||
// Translate any existing messages upwards, apply exponential decay factors to timers
|
||||
message_loc = target
|
||||
RegisterSignal(message_loc, COMSIG_PARENT_QDELETING, .proc/qdel_self)
|
||||
if(owned_by.seen_messages)
|
||||
var/idx = 1
|
||||
var/combined_height = approx_lines
|
||||
for(var/msg in owned_by.seen_messages[message_loc])
|
||||
var/datum/chatmessage/m = msg
|
||||
animate(m.message, pixel_y = m.message.pixel_y + mheight, time = CHAT_MESSAGE_SPAWN_TIME)
|
||||
combined_height += m.approx_lines
|
||||
|
||||
if(!m.ending_life) // Don't bother!
|
||||
var/sched_remaining = m.scheduled_destruction - world.time
|
||||
if(sched_remaining > CHAT_MESSAGE_SPAWN_TIME)
|
||||
var/remaining_time = (sched_remaining) * (CHAT_MESSAGE_EXP_DECAY ** idx++) * (CHAT_MESSAGE_HEIGHT_DECAY ** combined_height)
|
||||
m.scheduled_destruction = world.time + remaining_time
|
||||
spawn(remaining_time)
|
||||
m.end_of_life()
|
||||
|
||||
// Build message image
|
||||
message = image(loc = message_loc, layer = ABOVE_MOB_LAYER)
|
||||
message.plane = PLANE_RUNECHAT
|
||||
message.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA | KEEP_APART
|
||||
message.alpha = 0
|
||||
message.pixel_y = owner.bound_height * 0.95
|
||||
message.maptext_width = msgwidth
|
||||
message.maptext_height = mheight
|
||||
message.maptext_x = (CHAT_MESSAGE_WIDTH - owner.bound_width) * -0.5
|
||||
message.maptext = complete_text
|
||||
|
||||
if(owner.contains(target)) // Special case, holding an atom speaking (pAI, recorder...)
|
||||
message.plane = PLANE_PLAYER_HUD_ABOVE
|
||||
|
||||
// View the message
|
||||
LAZYADDASSOCLIST(owned_by.seen_messages, message_loc, src)
|
||||
owned_by.images += message
|
||||
animate(message, alpha = 255, time = CHAT_MESSAGE_SPAWN_TIME)
|
||||
|
||||
// Prepare for destruction
|
||||
scheduled_destruction = world.time + (lifespan - CHAT_MESSAGE_EOL_FADE)
|
||||
spawn(lifespan - CHAT_MESSAGE_EOL_FADE)
|
||||
end_of_life()
|
||||
|
||||
/**
|
||||
* Applies final animations to overlay CHAT_MESSAGE_EOL_FADE deciseconds prior to message deletion
|
||||
*/
|
||||
/datum/chatmessage/proc/end_of_life(fadetime = CHAT_MESSAGE_EOL_FADE)
|
||||
if(gc_destroyed || ending_life)
|
||||
return
|
||||
ending_life = TRUE
|
||||
animate(message, alpha = 0, time = fadetime, flags = ANIMATION_PARALLEL)
|
||||
spawn(fadetime)
|
||||
qdel(src)
|
||||
|
||||
/**
|
||||
* Creates a message overlay at a defined location for a given speaker
|
||||
*
|
||||
* Arguments:
|
||||
* * speaker - The atom who is saying this message
|
||||
* * message - The text content of the message
|
||||
* * italics - Decides if this should be small or not, as generally italics text are for whisper/radio overhear
|
||||
* * existing_extra_classes - Additional classes to add to the message
|
||||
*/
|
||||
/mob/proc/create_chat_message(atom/movable/speaker, message, italics, list/existing_extra_classes, audible = TRUE)
|
||||
if(!client)
|
||||
return
|
||||
|
||||
// Doesn't want to hear
|
||||
if(ismob(speaker) && !client.is_preference_enabled(/datum/client_preference/runechat_mob))
|
||||
return
|
||||
else if(isobj(speaker) && !client.is_preference_enabled(/datum/client_preference/runechat_obj))
|
||||
return
|
||||
|
||||
// Incapable of receiving
|
||||
if((audible && is_deaf()) || (!audible && is_blind()))
|
||||
return
|
||||
|
||||
// Check for virtual speakers (aka hearing a message through a radio)
|
||||
if(existing_extra_classes.Find("radio"))
|
||||
return
|
||||
|
||||
/* Not currently necessary
|
||||
message = strip_html_properly(message)
|
||||
if(!message)
|
||||
return
|
||||
*/
|
||||
|
||||
var/list/extra_classes = list()
|
||||
extra_classes += existing_extra_classes
|
||||
|
||||
if(italics)
|
||||
extra_classes |= "italics"
|
||||
|
||||
if(client.is_preference_enabled(/datum/client_preference/runechat_border))
|
||||
extra_classes |= "black_outline"
|
||||
|
||||
var/dist = get_dist(src, speaker)
|
||||
switch (dist)
|
||||
if(4 to 5)
|
||||
extra_classes |= "small"
|
||||
if(5 to 16)
|
||||
extra_classes |= "very_small"
|
||||
|
||||
// Display visual above source
|
||||
new /datum/chatmessage(message, speaker, src, extra_classes)
|
||||
|
||||
// Tweak these defines to change the available color ranges
|
||||
#define CM_COLOR_SAT_MIN 0.6
|
||||
#define CM_COLOR_SAT_MAX 0.95
|
||||
#define CM_COLOR_LUM_MIN 0.70
|
||||
#define CM_COLOR_LUM_MAX 0.90
|
||||
|
||||
/**
|
||||
* Gets a color for a name, will return the same color for a given string consistently within a round.atom
|
||||
*
|
||||
* Note that this proc aims to produce pastel-ish colors using the HSL colorspace. These seem to be favorable for displaying on the map.
|
||||
*
|
||||
* Arguments:
|
||||
* * name - The name to generate a color for
|
||||
* * sat_shift - A value between 0 and 1 that will be multiplied against the saturation
|
||||
* * lum_shift - A value between 0 and 1 that will be multiplied against the luminescence
|
||||
*/
|
||||
/datum/chatmessage/proc/colorize_string(name, sat_shift = 1, lum_shift = 1)
|
||||
// seed to help randomness
|
||||
var/static/rseed = rand(1,26)
|
||||
|
||||
// get hsl using the selected 6 characters of the md5 hash
|
||||
var/hash = copytext(md5(name + "[world_startup_time]"), rseed, rseed + 6)
|
||||
var/h = hex2num(copytext(hash, 1, 3)) * (360 / 255)
|
||||
var/s = (hex2num(copytext(hash, 3, 5)) >> 2) * ((CM_COLOR_SAT_MAX - CM_COLOR_SAT_MIN) / 63) + CM_COLOR_SAT_MIN
|
||||
var/l = (hex2num(copytext(hash, 5, 7)) >> 2) * ((CM_COLOR_LUM_MAX - CM_COLOR_LUM_MIN) / 63) + CM_COLOR_LUM_MIN
|
||||
|
||||
// adjust for shifts
|
||||
s *= clamp(sat_shift, 0, 1)
|
||||
l *= clamp(lum_shift, 0, 1)
|
||||
|
||||
// convert to rgba
|
||||
var/h_int = round(h/60) // mapping each section of H to 60 degree sections
|
||||
var/c = (1 - abs(2 * l - 1)) * s
|
||||
var/x = c * (1 - abs((h / 60) % 2 - 1))
|
||||
var/m = l - c * 0.5
|
||||
x = (x + m) * 255
|
||||
c = (c + m) * 255
|
||||
m *= 255
|
||||
switch(h_int)
|
||||
if(0)
|
||||
return rgb(c,x,m)
|
||||
if(1)
|
||||
return rgb(x,c,m)
|
||||
if(2)
|
||||
return rgb(m,c,x)
|
||||
if(3)
|
||||
return rgb(m,x,c)
|
||||
if(4)
|
||||
return rgb(x,m,c)
|
||||
if(5)
|
||||
return rgb(c,m,x)
|
||||
|
||||
/atom/proc/runechat_message(message, range = world.view, italics, list/classes = list(), audible = TRUE)
|
||||
var/list/hear = get_mobs_and_objs_in_view_fast(get_turf(src), range, remote_ghosts = FALSE)
|
||||
|
||||
var/list/hearing_mobs = hear["mobs"]
|
||||
|
||||
for(var/mob in hearing_mobs)
|
||||
var/mob/M = mob
|
||||
if(!M.client)
|
||||
continue
|
||||
M.create_chat_message(src, message, italics, classes, audible)
|
||||
@@ -213,10 +213,10 @@
|
||||
*
|
||||
* Arguments:
|
||||
* * datum/target Datum to stop listening to signals from
|
||||
* * sig_typeor_types Signal string key or list of signal keys to stop listening to specifically
|
||||
* * sig_type_or_types Signal string key or list of signal keys to stop listening to specifically
|
||||
*/
|
||||
/datum/proc/UnregisterSignal(datum/target, sig_type_or_types)
|
||||
var/list/lookup = target.comp_lookup
|
||||
var/list/lookup = target?.comp_lookup
|
||||
if(!signal_procs || !signal_procs[target] || !lookup)
|
||||
return
|
||||
if(!islist(sig_type_or_types))
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
datum
|
||||
computer
|
||||
var/name
|
||||
folder
|
||||
var/list/datum/computer/contents = list()
|
||||
|
||||
file
|
||||
@@ -6,11 +6,11 @@
|
||||
/datum/events
|
||||
var/list/events
|
||||
|
||||
New()
|
||||
/datum/events/New()
|
||||
..()
|
||||
events = new
|
||||
|
||||
proc/addEventType(event_type as text)
|
||||
/datum/events/proc/addEventType(event_type as text)
|
||||
if(!(event_type in events) || !islist(events[event_type]))
|
||||
events[event_type] = list()
|
||||
return 1
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
// Arguments: event_type as text, proc_holder as datum, proc_name as text
|
||||
// Returns: New event, null on error.
|
||||
proc/addEvent(event_type as text, proc_holder, proc_name as text)
|
||||
/datum/events/proc/addEvent(event_type as text, proc_holder, proc_name as text)
|
||||
if(!event_type || !proc_holder || !proc_name)
|
||||
return
|
||||
addEventType(event_type)
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
// Arguments: event_type as text, any number of additional arguments to pass to event handler
|
||||
// Returns: null
|
||||
proc/fireEvent()
|
||||
/datum/events/proc/fireEvent()
|
||||
//to_world("Events in [args[1]] called")
|
||||
var/list/event = listgetindex(events,args[1])
|
||||
if(istype(event))
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
// Arguments: event_type as text, E as /datum/event
|
||||
// Returns: 1 if event cleared, null on error
|
||||
proc/clearEvent(event_type as text, datum/event/E)
|
||||
/datum/events/proc/clearEvent(event_type as text, datum/event/E)
|
||||
if(!event_type || !E)
|
||||
return
|
||||
var/list/event = listgetindex(events,event_type)
|
||||
@@ -54,12 +54,12 @@
|
||||
var/listener
|
||||
var/proc_name
|
||||
|
||||
New(tlistener,tprocname)
|
||||
/datum/event/New(tlistener,tprocname)
|
||||
listener = tlistener
|
||||
proc_name = tprocname
|
||||
return ..()
|
||||
|
||||
proc/Fire()
|
||||
/datum/event/proc/Fire()
|
||||
//to_world("Event fired")
|
||||
if(listener)
|
||||
call(listener,proc_name)(arglist(args))
|
||||
|
||||
@@ -29,7 +29,7 @@ var/global/datum/getrev/revdata = new()
|
||||
to_world_log(date)
|
||||
to_world_log(revision)
|
||||
|
||||
client/verb/showrevinfo()
|
||||
/client/verb/showrevinfo()
|
||||
set category = "OOC"
|
||||
set name = "Show Server Revision"
|
||||
set desc = "Check the current server code revision"
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
DO NOT USE THIS. THIS IS BEING DEPRECATED BY PROCESSING SUBSYSTEMS (controllers/subsystems/processing) AND TIMERS.
|
||||
*/
|
||||
|
||||
/*
|
||||
README:
|
||||
|
||||
The global_iterator datum is supposed to provide a simple and robust way to
|
||||
create some constantly "looping" processes with ability to stop and restart them at will.
|
||||
Generally, the only thing you want to play with (meaning, redefine) is the process() proc.
|
||||
It must contain all the things you want done.
|
||||
|
||||
Control functions:
|
||||
new - used to create datum. First argument (optional) - var list(to use in process() proc) as list,
|
||||
second (optional) - autostart control.
|
||||
If autostart == TRUE, the loop will be started immediately after datum creation.
|
||||
|
||||
start(list/arguments) - starts the loop. Takes arguments(optional) as a list, which is then used
|
||||
by process() proc. Returns null if datum already active, 1 if loop started succesfully and 0 if there's
|
||||
an error in supplied arguments (not list or empty list).
|
||||
|
||||
stop() - stops the loop. Returns null if datum is already inactive and 1 on success.
|
||||
|
||||
set_delay(new_delay) - sets the delay between iterations. Pretty selfexplanatory.
|
||||
Returns 0 on error(new_delay is not numerical), 1 otherwise.
|
||||
|
||||
set_process_args(list/arguments) - passes the supplied arguments to the process() proc.
|
||||
|
||||
active() - Returns 1 if datum is active, 0 otherwise.
|
||||
|
||||
toggle() - toggles datum state. Returns new datum state (see active()).
|
||||
|
||||
Misc functions:
|
||||
|
||||
get_last_exec_time() - Returns the time of last iteration.
|
||||
|
||||
get_last_exec_time_as_text() - Returns the time of last iteration as text
|
||||
|
||||
|
||||
Control vars:
|
||||
|
||||
delay - delay between iterations
|
||||
|
||||
check_for_null - if equals TRUE, on each iteration the supplied arguments will be checked for nulls.
|
||||
If some varible equals null (and null only), the loop is stopped.
|
||||
Usefull, if some var unexpectedly becomes null - due to object deletion, for example.
|
||||
Of course, you can also check the variables inside process() proc to prevent runtime errors.
|
||||
|
||||
Data storage vars:
|
||||
|
||||
result - stores the value returned by process() proc
|
||||
*/
|
||||
|
||||
/datum/global_iterator
|
||||
var/control_switch = 0
|
||||
var/delay = 10
|
||||
var/list/arg_list = new
|
||||
var/last_exec = null
|
||||
var/check_for_null = 1
|
||||
var/forbid_garbage = 0
|
||||
var/result
|
||||
var/state = 0
|
||||
|
||||
New(list/arguments=null,autostart=1)
|
||||
delay = delay>0?(delay):1
|
||||
if(forbid_garbage) //prevents garbage collection with tag != null
|
||||
tag = "\ref[src]"
|
||||
set_process_args(arguments)
|
||||
if(autostart)
|
||||
start()
|
||||
return
|
||||
|
||||
proc/main()
|
||||
state = 1
|
||||
while(src && control_switch)
|
||||
last_exec = world.timeofday
|
||||
if(check_for_null && has_null_args())
|
||||
stop()
|
||||
return 0
|
||||
result = process(arglist(arg_list))
|
||||
for(var/sleep_time=delay;sleep_time>0;sleep_time--) //uhh, this is ugly. But I see no other way to terminate sleeping proc. Such disgrace.
|
||||
if(!control_switch)
|
||||
return 0
|
||||
sleep(1)
|
||||
return 0
|
||||
|
||||
proc/start(list/arguments=null)
|
||||
if(active())
|
||||
return
|
||||
if(arguments)
|
||||
if(!set_process_args(arguments))
|
||||
return 0
|
||||
if(!state_check()) //the main loop is sleeping, wait for it to terminate.
|
||||
return
|
||||
control_switch = 1
|
||||
spawn()
|
||||
state = main()
|
||||
return 1
|
||||
|
||||
proc/stop()
|
||||
if(!active())
|
||||
return
|
||||
control_switch = 0
|
||||
spawn(-1) //report termination error but don't wait for state_check().
|
||||
state_check()
|
||||
return 1
|
||||
|
||||
proc/state_check()
|
||||
var/lag = 0
|
||||
while(state)
|
||||
sleep(1)
|
||||
if(++lag>10)
|
||||
CRASH("The global_iterator loop \ref[src] failed to terminate in designated timeframe. This may be caused by server lagging.")
|
||||
return 1
|
||||
|
||||
proc/active()
|
||||
return control_switch
|
||||
|
||||
proc/has_null_args()
|
||||
if(null in arg_list)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
proc/set_delay(new_delay)
|
||||
if(isnum(new_delay))
|
||||
delay = max(1, round(new_delay))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
proc/get_last_exec_time()
|
||||
return (last_exec||0)
|
||||
|
||||
proc/get_last_exec_time_as_text()
|
||||
return (time2text(last_exec)||"Wasn't executed yet")
|
||||
|
||||
proc/set_process_args(list/arguments)
|
||||
if(arguments && istype(arguments, /list) && arguments.len)
|
||||
arg_list = arguments
|
||||
return 1
|
||||
else
|
||||
// to_world("<span class='danger'>Invalid arguments supplied for [src.type], ref = \ref[src]</span>")
|
||||
return 0
|
||||
|
||||
proc/toggle_null_checks()
|
||||
check_for_null = !check_for_null
|
||||
return check_for_null
|
||||
|
||||
proc/toggle()
|
||||
if(!stop())
|
||||
start()
|
||||
return active()
|
||||
|
||||
/datum/global_iterator/Destroy()
|
||||
tag = null
|
||||
arg_list.Cut()
|
||||
stop()
|
||||
return QDEL_HINT_LETMELIVE
|
||||
//Do not call ..()
|
||||
@@ -2,59 +2,59 @@
|
||||
var/href
|
||||
var/list/href_list
|
||||
|
||||
New(thref,list/thref_list)
|
||||
/datum/topic_input/New(thref,list/thref_list)
|
||||
href = thref
|
||||
href_list = thref_list.Copy()
|
||||
return
|
||||
|
||||
proc/get(i)
|
||||
/datum/topic_input/proc/get(i)
|
||||
return listgetindex(href_list,i)
|
||||
|
||||
proc/getAndLocate(i)
|
||||
/datum/topic_input/proc/getAndLocate(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = locate(t)
|
||||
return t || null
|
||||
|
||||
proc/getNum(i)
|
||||
/datum/topic_input/proc/getNum(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = text2num(t)
|
||||
return isnum(t) ? t : null
|
||||
|
||||
proc/getObj(i)
|
||||
/datum/topic_input/proc/getObj(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isobj(t) ? t : null
|
||||
|
||||
proc/getMob(i)
|
||||
/datum/topic_input/proc/getMob(i)
|
||||
var/t = getAndLocate(i)
|
||||
return ismob(t) ? t : null
|
||||
|
||||
proc/getTurf(i)
|
||||
/datum/topic_input/proc/getTurf(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isturf(t) ? t : null
|
||||
|
||||
proc/getAtom(i)
|
||||
/datum/topic_input/proc/getAtom(i)
|
||||
return getType(i,/atom)
|
||||
|
||||
proc/getArea(i)
|
||||
/datum/topic_input/proc/getArea(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isarea(t) ? t : null
|
||||
|
||||
proc/getStr(i)//params should always be text, but...
|
||||
/datum/topic_input/proc/getStr(i)//params should always be text, but...
|
||||
var/t = get(i)
|
||||
return istext(t) ? t : null
|
||||
|
||||
proc/getType(i,type)
|
||||
/datum/topic_input/proc/getType(i,type)
|
||||
var/t = getAndLocate(i)
|
||||
return istype(t,type) ? t : null
|
||||
|
||||
proc/getPath(i)
|
||||
/datum/topic_input/proc/getPath(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = text2path(t)
|
||||
return ispath(t) ? t : null
|
||||
|
||||
proc/getList(i)
|
||||
/datum/topic_input/proc/getList(i)
|
||||
var/t = getAndLocate(i)
|
||||
return islist(t) ? t : null
|
||||
@@ -4,7 +4,7 @@
|
||||
/client/can_vv_get(var_name)
|
||||
return var_name != NAMEOF(src, feedback_form) // No snooping.
|
||||
|
||||
GENERAL_PROTECT_DATUM(datum/managed_browser/feedback_form)
|
||||
GENERAL_PROTECT_DATUM(/datum/managed_browser/feedback_form)
|
||||
|
||||
// A fairly simple object to hold information about a player's feedback as it's being written.
|
||||
// Having this be it's own object instead of being baked into /mob/new_player allows for it to be used
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// III. Thou shalt not write a decl that relies on arguments supplied to New().
|
||||
// IV. Thou shalt not call Initialize() on a /decl.
|
||||
|
||||
var/repository/decls/decls_repository = new()
|
||||
var/repository/decls/decls_repository // Initialiozed in /datum/global_init/New()
|
||||
|
||||
/repository/decls
|
||||
var/list/fetched_decls
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
containertype = /obj/structure/closet/crate/gilthari
|
||||
containername = "Formal suit crate"
|
||||
|
||||
datum/supply_pack/costumes/witch
|
||||
/datum/supply_pack/costumes/witch
|
||||
name = "Witch costume"
|
||||
containername = "Witch costume"
|
||||
containertype = /obj/structure/closet/crate/nanothreads
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
/obj/item/weapon/reagent_containers/glass/paint/purple,
|
||||
/obj/item/weapon/reagent_containers/glass/paint/black,
|
||||
/obj/item/weapon/reagent_containers/glass/paint/white,
|
||||
/obj/item/weapon/contraband/poster/custom,
|
||||
/obj/item/poster/custom,
|
||||
/obj/item/weapon/wrapping_paper = 3
|
||||
)
|
||||
cost = 10
|
||||
|
||||
@@ -419,7 +419,8 @@
|
||||
/obj/item/clothing/accessory/holster,
|
||||
/obj/item/clothing/accessory/holster/armpit,
|
||||
/obj/item/clothing/accessory/holster/waist,
|
||||
/obj/item/clothing/accessory/holster/hip
|
||||
/obj/item/clothing/accessory/holster/hip,
|
||||
/obj/item/clothing/accessory/holster/leg
|
||||
)
|
||||
cost = 15
|
||||
containertype = /obj/structure/closet/crate/hedberg
|
||||
@@ -663,9 +664,9 @@
|
||||
/datum/supply_pack/security/posters
|
||||
name = "Gear - Morale Posters"
|
||||
contains = list(
|
||||
/obj/item/weapon/contraband/poster/nanotrasen = 6
|
||||
/obj/item/poster/nanotrasen = 6
|
||||
)
|
||||
cost = 20
|
||||
cost = 10
|
||||
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||
containername = "Morale Posters"
|
||||
access = access_maint_tunnels
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/display_name // For displaying in text
|
||||
var/gender = NEUTER
|
||||
|
||||
datum/category_group/underwear/dd_SortValue()
|
||||
/datum/category_group/underwear/dd_SortValue()
|
||||
return sort_order
|
||||
|
||||
/datum/category_group/underwear/top
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
..()
|
||||
items = list()
|
||||
|
||||
datum/uplink_category/ammunition
|
||||
/datum/uplink_category/ammunition
|
||||
name = "Ammunition"
|
||||
|
||||
/datum/uplink_category/services
|
||||
|
||||
@@ -95,7 +95,7 @@ var/datum/uplink/uplink = new()
|
||||
log_and_message_admins("\the [M] bought \a [src] through the uplink")
|
||||
M.mind.purchase_log[src] += 1
|
||||
|
||||
datum/uplink_item/dd_SortValue()
|
||||
/datum/uplink_item/dd_SortValue()
|
||||
return item_cost
|
||||
|
||||
/********************************
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
/obj/structure/signpost/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
/obj/structure/signpost/attack_hand(mob/user as mob)
|
||||
switch(alert("Travel back to ss13?",,"Yes","No"))
|
||||
if("Yes")
|
||||
if(user.z != src.z) return
|
||||
@@ -99,7 +99,7 @@
|
||||
drop_sound = 'sound/items/drop/rubber.ogg'
|
||||
pickup_sound = 'sound/items/pickup/rubber.ogg'
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
|
||||
/obj/item/weapon/beach_ball/afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
|
||||
user.drop_item()
|
||||
src.throw_at(target, throw_range, throw_speed, user)
|
||||
|
||||
|
||||
@@ -37,18 +37,18 @@ length to avoid portals or something i guess?? Not that they're counted right no
|
||||
// Also added 'exclude' turf to avoid travelling over; defaults to null
|
||||
|
||||
|
||||
PriorityQueue
|
||||
/PriorityQueue
|
||||
var/list/queue
|
||||
var/comparison_function
|
||||
|
||||
New(compare)
|
||||
/PriorityQueue/New(compare)
|
||||
queue = list()
|
||||
comparison_function = compare
|
||||
|
||||
proc/IsEmpty()
|
||||
/PriorityQueue/proc/IsEmpty()
|
||||
return !queue.len
|
||||
|
||||
proc/Enqueue(var/data)
|
||||
/PriorityQueue/proc/Enqueue(var/data)
|
||||
queue.Add(data)
|
||||
var/index = queue.len
|
||||
|
||||
@@ -57,12 +57,12 @@ PriorityQueue
|
||||
queue.Swap(index, index / 2)
|
||||
index /= 2
|
||||
|
||||
proc/Dequeue()
|
||||
/PriorityQueue/proc/Dequeue()
|
||||
if(!queue.len)
|
||||
return 0
|
||||
return Remove(1)
|
||||
|
||||
proc/Remove(var/index)
|
||||
/PriorityQueue/proc/Remove(var/index)
|
||||
if(index > queue.len)
|
||||
return 0
|
||||
|
||||
@@ -73,7 +73,7 @@ PriorityQueue
|
||||
FixQueue(index)
|
||||
return thing
|
||||
|
||||
proc/FixQueue(var/index)
|
||||
/PriorityQueue/proc/FixQueue(var/index)
|
||||
var/child = 2 * index
|
||||
var/item = queue[index]
|
||||
|
||||
@@ -88,18 +88,18 @@ PriorityQueue
|
||||
child = 2 * index
|
||||
queue[index] = item
|
||||
|
||||
proc/List()
|
||||
/PriorityQueue/proc/List()
|
||||
return queue.Copy()
|
||||
|
||||
proc/Length()
|
||||
/PriorityQueue/proc/Length()
|
||||
return queue.len
|
||||
|
||||
proc/RemoveItem(data)
|
||||
/PriorityQueue/proc/RemoveItem(data)
|
||||
var/index = queue.Find(data)
|
||||
if(index)
|
||||
return Remove(index)
|
||||
|
||||
PathNode
|
||||
/PathNode
|
||||
var/datum/position
|
||||
var/PathNode/previous_node
|
||||
|
||||
@@ -109,7 +109,7 @@ PathNode
|
||||
var/cost
|
||||
var/nodes_traversed
|
||||
|
||||
New(_position, _previous_node, _known_cost, _cost, _nodes_traversed)
|
||||
/PathNode/New(_position, _previous_node, _known_cost, _cost, _nodes_traversed)
|
||||
position = _position
|
||||
previous_node = _previous_node
|
||||
|
||||
@@ -120,10 +120,10 @@ PathNode
|
||||
best_estimated_cost = estimated_cost
|
||||
nodes_traversed = _nodes_traversed
|
||||
|
||||
proc/PathWeightCompare(PathNode/a, PathNode/b)
|
||||
/proc/PathWeightCompare(PathNode/a, PathNode/b)
|
||||
return a.estimated_cost - b.estimated_cost
|
||||
|
||||
proc/AStar(var/start, var/end, var/adjacent, var/dist, var/max_nodes, var/max_node_depth = 30, var/min_target_dist = 0, var/min_node_dist, var/id, var/datum/exclude)
|
||||
/proc/AStar(var/start, var/end, var/adjacent, var/dist, var/max_nodes, var/max_node_depth = 30, var/min_target_dist = 0, var/min_node_dist, var/id, var/datum/exclude)
|
||||
var/PriorityQueue/open = new /PriorityQueue(/proc/PathWeightCompare)
|
||||
var/list/closed = list()
|
||||
var/list/path
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
Sound(message_sound, zlevels)
|
||||
Log(message, message_title)
|
||||
|
||||
datum/announcement/proc/Message(message as text, message_title as text, var/list/zlevels)
|
||||
/datum/announcement/proc/Message(message as text, message_title as text, var/list/zlevels)
|
||||
for(var/mob/M in player_list)
|
||||
if(!istype(M,/mob/new_player) && !isdeaf(M))
|
||||
to_chat(M, "<h2 class='alert'>[title]</h2>")
|
||||
@@ -59,17 +59,17 @@ datum/announcement/proc/Message(message as text, message_title as text, var/list
|
||||
to_chat(M, "<span class='alert'> -[html_encode(announcer)]</span>")
|
||||
|
||||
// You'll need to update these to_world usages if you want to make these z-level specific ~Aro
|
||||
datum/announcement/minor/Message(message as text, message_title as text)
|
||||
/datum/announcement/minor/Message(message as text, message_title as text)
|
||||
to_world("<b>[message]</b>")
|
||||
|
||||
datum/announcement/priority/Message(message as text, message_title as text)
|
||||
/datum/announcement/priority/Message(message as text, message_title as text)
|
||||
to_world("<h1 class='alert'>[message_title]</h1>")
|
||||
to_world("<span class='alert'>[message]</span>")
|
||||
if(announcer)
|
||||
to_world("<span class='alert'> -[html_encode(announcer)]</span>")
|
||||
to_world("<br>")
|
||||
|
||||
datum/announcement/priority/command/Message(message as text, message_title as text, var/list/zlevels)
|
||||
/datum/announcement/priority/command/Message(message as text, message_title as text, var/list/zlevels)
|
||||
var/command
|
||||
command += "<h1 class='alert'>[command_name()] Update</h1>"
|
||||
if (message_title)
|
||||
@@ -83,11 +83,11 @@ datum/announcement/priority/command/Message(message as text, message_title as te
|
||||
if(!istype(M,/mob/new_player) && !isdeaf(M))
|
||||
to_chat(M, command)
|
||||
|
||||
datum/announcement/priority/security/Message(message as text, message_title as text)
|
||||
/datum/announcement/priority/security/Message(message as text, message_title as text)
|
||||
to_world("<font size=4 color='red'>[message_title]</font>")
|
||||
to_world("<font color='red'>[message]</font>")
|
||||
|
||||
datum/announcement/proc/NewsCast(message as text, message_title as text)
|
||||
/datum/announcement/proc/NewsCast(message as text, message_title as text)
|
||||
if(!newscast)
|
||||
return
|
||||
|
||||
@@ -99,7 +99,7 @@ datum/announcement/proc/NewsCast(message as text, message_title as text)
|
||||
news.can_be_redacted = 0
|
||||
announce_newscaster_news(news)
|
||||
|
||||
datum/announcement/proc/PlaySound(var/message_sound, var/list/zlevels)
|
||||
/datum/announcement/proc/PlaySound(var/message_sound, var/list/zlevels)
|
||||
if(!message_sound)
|
||||
return
|
||||
|
||||
@@ -109,17 +109,17 @@ datum/announcement/proc/PlaySound(var/message_sound, var/list/zlevels)
|
||||
if(!istype(M,/mob/new_player) && !isdeaf(M))
|
||||
M << message_sound
|
||||
|
||||
datum/announcement/proc/Sound(var/message_sound, var/list/zlevels)
|
||||
/datum/announcement/proc/Sound(var/message_sound, var/list/zlevels)
|
||||
PlaySound(message_sound, zlevels)
|
||||
|
||||
datum/announcement/priority/Sound(var/message_sound)
|
||||
/datum/announcement/priority/Sound(var/message_sound)
|
||||
if(message_sound)
|
||||
world << message_sound
|
||||
|
||||
datum/announcement/priority/command/Sound(var/message_sound)
|
||||
/datum/announcement/priority/command/Sound(var/message_sound)
|
||||
PlaySound(message_sound)
|
||||
|
||||
datum/announcement/proc/Log(message as text, message_title as text)
|
||||
/datum/announcement/proc/Log(message as text, message_title as text)
|
||||
if(log)
|
||||
log_game("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]")
|
||||
message_admins("[key_name_admin(usr)] has made \a [announcement_type].", 1)
|
||||
|
||||
@@ -38,7 +38,7 @@ var/DB_SERVER = "" // This is the location of your MySQL server (localhost is US
|
||||
var/DB_PORT = 3306 // This is the port your MySQL server is running on (3306 is the default)
|
||||
*/
|
||||
|
||||
DBConnection
|
||||
/DBConnection
|
||||
var/_db_con // This variable contains a reference to the actual database connection.
|
||||
var/dbi // This variable is a string containing the DBI MySQL requires.
|
||||
var/user // This variable contains the username data.
|
||||
@@ -48,14 +48,14 @@ DBConnection
|
||||
var/server = ""
|
||||
var/port = 3306
|
||||
|
||||
DBConnection/New(dbi_handler,username,password_handler,cursor_handler)
|
||||
/DBConnection/New(dbi_handler,username,password_handler,cursor_handler)
|
||||
src.dbi = dbi_handler
|
||||
src.user = username
|
||||
src.password = password_handler
|
||||
src.default_cursor = cursor_handler
|
||||
_db_con = _dm_db_new_con()
|
||||
|
||||
DBConnection/proc/Connect(dbi_handler=src.dbi,user_handler=src.user,password_handler=src.password,cursor_handler)
|
||||
/DBConnection/proc/Connect(dbi_handler=src.dbi,user_handler=src.user,password_handler=src.password,cursor_handler)
|
||||
if(!config.sql_enabled)
|
||||
return 0
|
||||
if(!src) return 0
|
||||
@@ -63,24 +63,24 @@ DBConnection/proc/Connect(dbi_handler=src.dbi,user_handler=src.user,password_han
|
||||
if(!cursor_handler) cursor_handler = Default_Cursor
|
||||
return _dm_db_connect(_db_con,dbi_handler,user_handler,password_handler,cursor_handler,null)
|
||||
|
||||
DBConnection/proc/Disconnect() return _dm_db_close(_db_con)
|
||||
/DBConnection/proc/Disconnect() return _dm_db_close(_db_con)
|
||||
|
||||
DBConnection/proc/IsConnected()
|
||||
/DBConnection/proc/IsConnected()
|
||||
if(!config.sql_enabled) return 0
|
||||
var/success = _dm_db_is_connected(_db_con)
|
||||
return success
|
||||
|
||||
DBConnection/proc/Quote(str) return _dm_db_quote(_db_con,str)
|
||||
/DBConnection/proc/Quote(str) return _dm_db_quote(_db_con,str)
|
||||
|
||||
DBConnection/proc/ErrorMsg() return _dm_db_error_msg(_db_con)
|
||||
DBConnection/proc/SelectDB(database_name,dbi)
|
||||
/DBConnection/proc/ErrorMsg() return _dm_db_error_msg(_db_con)
|
||||
/DBConnection/proc/SelectDB(database_name,dbi)
|
||||
if(IsConnected()) Disconnect()
|
||||
//return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[DB_SERVER]:[DB_PORT]"]",user,password)
|
||||
return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[sqladdress]:[sqlport]"]",user,password)
|
||||
DBConnection/proc/NewQuery(sql_query,cursor_handler=src.default_cursor) return new/DBQuery(sql_query,src,cursor_handler)
|
||||
/DBConnection/proc/NewQuery(sql_query,cursor_handler=src.default_cursor) return new/DBQuery(sql_query,src,cursor_handler)
|
||||
|
||||
|
||||
DBQuery/New(sql_query,DBConnection/connection_handler,cursor_handler)
|
||||
/DBQuery/New(sql_query,DBConnection/connection_handler,cursor_handler)
|
||||
if(sql_query) src.sql = sql_query
|
||||
if(connection_handler) src.db_connection = connection_handler
|
||||
if(cursor_handler) src.default_cursor = cursor_handler
|
||||
@@ -88,7 +88,7 @@ DBQuery/New(sql_query,DBConnection/connection_handler,cursor_handler)
|
||||
return ..()
|
||||
|
||||
|
||||
DBQuery
|
||||
/DBQuery
|
||||
var/sql // The sql query being executed.
|
||||
var/default_cursor
|
||||
var/list/columns //list of DB Columns populated by Columns()
|
||||
@@ -98,26 +98,26 @@ DBQuery
|
||||
var/DBConnection/db_connection
|
||||
var/_db_query
|
||||
|
||||
DBQuery/proc/Connect(DBConnection/connection_handler) src.db_connection = connection_handler
|
||||
/DBQuery/proc/Connect(DBConnection/connection_handler) src.db_connection = connection_handler
|
||||
|
||||
DBQuery/proc/Execute(sql_query=src.sql,cursor_handler=default_cursor)
|
||||
/DBQuery/proc/Execute(sql_query=src.sql,cursor_handler=default_cursor)
|
||||
Close()
|
||||
return _dm_db_execute(_db_query,sql_query,db_connection._db_con,cursor_handler,null)
|
||||
|
||||
DBQuery/proc/NextRow() return _dm_db_next_row(_db_query,item,conversions)
|
||||
/DBQuery/proc/NextRow() return _dm_db_next_row(_db_query,item,conversions)
|
||||
|
||||
DBQuery/proc/RowsAffected() return _dm_db_rows_affected(_db_query)
|
||||
/DBQuery/proc/RowsAffected() return _dm_db_rows_affected(_db_query)
|
||||
|
||||
DBQuery/proc/RowCount() return _dm_db_row_count(_db_query)
|
||||
/DBQuery/proc/RowCount() return _dm_db_row_count(_db_query)
|
||||
|
||||
DBQuery/proc/ErrorMsg() return _dm_db_error_msg(_db_query)
|
||||
/DBQuery/proc/ErrorMsg() return _dm_db_error_msg(_db_query)
|
||||
|
||||
DBQuery/proc/Columns()
|
||||
/DBQuery/proc/Columns()
|
||||
if(!columns)
|
||||
columns = _dm_db_columns(_db_query,/DBColumn)
|
||||
return columns
|
||||
|
||||
DBQuery/proc/GetRowData()
|
||||
/DBQuery/proc/GetRowData()
|
||||
var/list/columns = Columns()
|
||||
var/list/results
|
||||
if(columns.len)
|
||||
@@ -128,23 +128,23 @@ DBQuery/proc/GetRowData()
|
||||
results[C] = src.item[(cur_col.position+1)]
|
||||
return results
|
||||
|
||||
DBQuery/proc/Close()
|
||||
/DBQuery/proc/Close()
|
||||
item.len = 0
|
||||
columns = null
|
||||
conversions = null
|
||||
return _dm_db_close(_db_query)
|
||||
|
||||
DBQuery/proc/Quote(str)
|
||||
/DBQuery/proc/Quote(str)
|
||||
return db_connection.Quote(str)
|
||||
|
||||
DBQuery/proc/SetConversion(column,conversion)
|
||||
/DBQuery/proc/SetConversion(column,conversion)
|
||||
if(istext(column)) column = columns.Find(column)
|
||||
if(!conversions) conversions = new/list(column)
|
||||
else if(conversions.len < column) conversions.len = column
|
||||
conversions[column] = conversion
|
||||
|
||||
|
||||
DBColumn
|
||||
/DBColumn
|
||||
var/name
|
||||
var/table
|
||||
var/position //1-based index into item data
|
||||
@@ -153,7 +153,7 @@ DBColumn
|
||||
var/length
|
||||
var/max_length
|
||||
|
||||
DBColumn/New(name_handler,table_handler,position_handler,type_handler,flag_handler,length_handler,max_length_handler)
|
||||
/DBColumn/New(name_handler,table_handler,position_handler,type_handler,flag_handler,length_handler,max_length_handler)
|
||||
src.name = name_handler
|
||||
src.table = table_handler
|
||||
src.position = position_handler
|
||||
@@ -164,7 +164,7 @@ DBColumn/New(name_handler,table_handler,position_handler,type_handler,flag_handl
|
||||
return ..()
|
||||
|
||||
|
||||
DBColumn/proc/SqlTypeName(type_handler=src.sql_type)
|
||||
/DBColumn/proc/SqlTypeName(type_handler=src.sql_type)
|
||||
switch(type_handler)
|
||||
if(TINYINT) return "TINYINT"
|
||||
if(SMALLINT) return "SMALLINT"
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
/* sd_Alert library
|
||||
by Shadowdarke (shadowdarke@byond.com)
|
||||
|
||||
sd_Alert() is a powerful and flexible alternative to the built in BYOND
|
||||
alert() proc. sd_Alert offers timed popups, unlimited buttons, custom
|
||||
appearance, and even the option to popup without stealing keyboard focus
|
||||
from the map or command line.
|
||||
|
||||
Please see demo.dm for detailed examples.
|
||||
|
||||
FORMAT
|
||||
sd_Alert(who, message, title, buttons, default, duration, unfocus, \
|
||||
size, table, style, tag, select, flags)
|
||||
|
||||
ARGUMENTS
|
||||
who - the client or mob to display the alert to.
|
||||
message - text message to display
|
||||
title - title of the alert box
|
||||
buttons - list of buttons
|
||||
Default Value: list("Ok")
|
||||
default - default button selestion
|
||||
Default Value: the first button in the list
|
||||
duration - the number of ticks before this alert expires. If not
|
||||
set, the alert lasts until a button is clicked.
|
||||
Default Value: 0 (unlimited)
|
||||
unfocus - if this value is set, the popup will not steal keyboard
|
||||
focus from the map or command line.
|
||||
Default Value: 1 (do not take focus)
|
||||
size - size of the popup window in px
|
||||
Default Value: "300x200"
|
||||
table - optional parameters for the HTML table in the alert
|
||||
Default Value: "width=100% height=100%" (fill the window)
|
||||
style - optional style sheet information
|
||||
tag - lets you specify a certain tag for this sd_Alert so you may manipulate it
|
||||
externally. (i.e. force the alert to close, change options and redisplay,
|
||||
reuse the same window, etc.)
|
||||
select - if set, the buttons will be replaced with a selection box with a number of
|
||||
lines displayed equal to this value.
|
||||
Default value: 0 (use buttons)
|
||||
flags - optional flags effecting the alert display. These flags may be ORed (|)
|
||||
together for multiple effects.
|
||||
SD_ALERT_SCROLL = display a scrollbar
|
||||
SD_ALERT_SELECT_MULTI = forces selection box display (instead of
|
||||
buttons) allows the user to select multiple
|
||||
choices.
|
||||
SD_ALERT_LINKS = display each choice as a plain text link.
|
||||
Any selection box style overrides this flag.
|
||||
SD_ALERT_NOVALIDATE = don't validate responses
|
||||
Default value: SD_ALERT_SCROLL
|
||||
(button display with scroll bar, validate responses)
|
||||
RETURNS
|
||||
The text of the selected button, or null if the alert duration expired
|
||||
without a button click.
|
||||
|
||||
Version 1 changes (from version 0):
|
||||
* Added the tag, select, and flags arguments, thanks to several suggestions from Foomer.
|
||||
* Split the sd_Alert/Alert() proc into New(), Display(), and Response() to allow more
|
||||
customization by developers. Primarily developers would want to use Display() to change
|
||||
the display of active tagged windows
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#define SD_ALERT_SCROLL 1
|
||||
#define SD_ALERT_SELECT_MULTI 2
|
||||
#define SD_ALERT_LINKS 4
|
||||
#define SD_ALERT_NOVALIDATE 8
|
||||
|
||||
proc/sd_Alert(client/who, message, title, buttons = list("Ok"),\
|
||||
default, duration = 0, unfocus = 1, size = "300x200", \
|
||||
table = "width=100% height=100%", style, tag, select, flags = SD_ALERT_SCROLL)
|
||||
|
||||
if(ismob(who))
|
||||
var/mob/M = who
|
||||
who = M.client
|
||||
if(!istype(who)) CRASH("sd_Alert: Invalid target:[who] (\ref[who])")
|
||||
|
||||
var/sd_alert/T = locate(tag)
|
||||
if(T)
|
||||
if(istype(T)) qdel(T)
|
||||
else CRASH("sd_Alert: tag \"[tag]\" is already in use by datum '[T]' (type: [T.type])")
|
||||
T = new(who, tag)
|
||||
if(duration)
|
||||
spawn(duration)
|
||||
if(T) qdel(T)
|
||||
return
|
||||
T.Display(message,title,buttons,default,unfocus,size,table,style,select,flags)
|
||||
. = T.Response()
|
||||
|
||||
sd_alert
|
||||
var
|
||||
client/target
|
||||
response
|
||||
list/validation
|
||||
|
||||
Destroy()
|
||||
target << browse(null,"window=\ref[src]")
|
||||
..()
|
||||
|
||||
New(who, tag)
|
||||
..()
|
||||
target = who
|
||||
src.tag = tag
|
||||
|
||||
Topic(href,params[])
|
||||
if(usr.client != target) return
|
||||
response = params["clk"]
|
||||
|
||||
proc/Display(message,title,list/buttons,default,unfocus,size,table,style,select,flags)
|
||||
if(unfocus) spawn() target << browse(null,null)
|
||||
if(istext(buttons)) buttons = list(buttons)
|
||||
if(!default) default = buttons[1]
|
||||
if(!(flags & SD_ALERT_NOVALIDATE)) validation = buttons.Copy()
|
||||
|
||||
var/html = {"<head><title>[title]</title>[style]<script>\
|
||||
function c(x) {document.location.href='BYOND://?src=\ref[src];'+x;}\
|
||||
</script></head><body onLoad="fcs.focus();"\
|
||||
[(flags&SD_ALERT_SCROLL)?"":" scroll=no"]><table [table]><tr>\
|
||||
<td>[message]</td></tr><tr><th>"}
|
||||
|
||||
if(select || (flags & SD_ALERT_SELECT_MULTI)) // select style choices
|
||||
html += {"<FORM ID=fcs ACTION='BYOND://?' METHOD=GET>\
|
||||
<INPUT TYPE=HIDDEN NAME=src VALUE='\ref[src]'>
|
||||
<SELECT NAME=clk SIZE=[select]\
|
||||
[(flags & SD_ALERT_SELECT_MULTI)?" MULTIPLE":""]>"}
|
||||
for(var/b in buttons)
|
||||
html += "<OPTION[(b == default)?" SELECTED":""]>\
|
||||
[html_encode(b)]</OPTION>"
|
||||
html += "</SELECT><BR><INPUT TYPE=SUBMIT VALUE=Submit></FORM>"
|
||||
else if(flags & SD_ALERT_LINKS) // text link style
|
||||
for(var/b in buttons)
|
||||
var/list/L = list()
|
||||
L["clk"] = b
|
||||
var/html_string=list2params(L)
|
||||
var/focus
|
||||
if(b == default) focus = " ID=fcs"
|
||||
html += "<A[focus] href=# onClick=\"c('[html_string]')\">[html_encode(b)]</A>\
|
||||
<BR>"
|
||||
else // button style choices
|
||||
for(var/b in buttons)
|
||||
var/list/L = list()
|
||||
L["clk"] = b
|
||||
var/html_string=list2params(L)
|
||||
var/focus
|
||||
if(b == default) focus = " ID=fcs"
|
||||
html += "<INPUT[focus] TYPE=button VALUE='[html_encode(b)]' \
|
||||
onClick=\"c('[html_string]')\"> "
|
||||
|
||||
html += "</th></tr></table></body>"
|
||||
|
||||
target << browse(html,"window=\ref[src];size=[size];can_close=0")
|
||||
|
||||
proc/Response()
|
||||
var/validated
|
||||
while(!validated)
|
||||
while(target && !response) // wait for a response
|
||||
sleep(2)
|
||||
|
||||
if(response && validation)
|
||||
if(istype(response, /list))
|
||||
var/list/L = response - validation
|
||||
if(L.len) response = null
|
||||
else validated = 1
|
||||
else if(response in validation) validated = 1
|
||||
else response=null
|
||||
else validated = 1
|
||||
spawn(2) qdel(src)
|
||||
return response
|
||||
@@ -1,4 +1,4 @@
|
||||
proc/sql_poll_population()
|
||||
/proc/sql_poll_population()
|
||||
if(!sqllogging)
|
||||
return
|
||||
var/admincount = admins.len
|
||||
@@ -16,16 +16,16 @@ proc/sql_poll_population()
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during population polling. Error : \[[err]\]\n")
|
||||
|
||||
proc/sql_report_round_start()
|
||||
/proc/sql_report_round_start()
|
||||
// TODO
|
||||
if(!sqllogging)
|
||||
return
|
||||
proc/sql_report_round_end()
|
||||
/proc/sql_report_round_end()
|
||||
// TODO
|
||||
if(!sqllogging)
|
||||
return
|
||||
|
||||
proc/sql_report_death(var/mob/living/carbon/human/H)
|
||||
/proc/sql_report_death(var/mob/living/carbon/human/H)
|
||||
if(!sqllogging)
|
||||
return
|
||||
if(!H)
|
||||
@@ -59,7 +59,7 @@ proc/sql_report_death(var/mob/living/carbon/human/H)
|
||||
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
|
||||
|
||||
|
||||
proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
|
||||
/proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
|
||||
if(!sqllogging)
|
||||
return
|
||||
if(!H)
|
||||
@@ -93,7 +93,7 @@ proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
|
||||
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
|
||||
|
||||
|
||||
proc/statistic_cycle()
|
||||
/proc/statistic_cycle()
|
||||
set waitfor = 0
|
||||
if(!sqllogging)
|
||||
return
|
||||
@@ -102,7 +102,7 @@ proc/statistic_cycle()
|
||||
sleep(6000)
|
||||
|
||||
//This proc is used for feedback. It is executed at round end.
|
||||
proc/sql_commit_feedback()
|
||||
/proc/sql_commit_feedback()
|
||||
if(!blackbox)
|
||||
log_game("Round ended without a blackbox recorder. No feedback was sent to the database.")
|
||||
return
|
||||
|
||||
@@ -14,19 +14,6 @@
|
||||
- To skip equipping with appropriate gear, supply a positive third argument.
|
||||
*/
|
||||
|
||||
// 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.
|
||||
|
||||
// Globals.
|
||||
var/global/list/all_antag_types = list()
|
||||
var/global/list/all_antag_spawnpoints = list()
|
||||
|
||||
@@ -105,7 +105,7 @@ var/datum/antagonist/wizard/wizards
|
||||
for(var/spell/spell_to_remove in src.spell_list)
|
||||
remove_spell(spell_to_remove)
|
||||
|
||||
obj/item/clothing
|
||||
/obj/item/clothing
|
||||
var/wizard_garb = 0
|
||||
|
||||
// Does this clothing slot count as wizard garb? (Combines a few checks)
|
||||
|
||||
@@ -1473,27 +1473,27 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
dynamic_lighting = 0
|
||||
ambience = AMBIENCE_SPACE
|
||||
|
||||
auxport
|
||||
/area/solar/auxport
|
||||
name = "\improper Fore Port Solar Array"
|
||||
icon_state = "panelsA"
|
||||
|
||||
auxstarboard
|
||||
/area/solar/auxstarboard
|
||||
name = "\improper Fore Starboard Solar Array"
|
||||
icon_state = "panelsA"
|
||||
|
||||
fore
|
||||
/area/solar/fore
|
||||
name = "\improper Fore Solar Array"
|
||||
icon_state = "yellow"
|
||||
|
||||
aft
|
||||
/area/solar/aft
|
||||
name = "\improper Aft Solar Array"
|
||||
icon_state = "aft"
|
||||
|
||||
starboard
|
||||
/area/solar/starboard
|
||||
name = "\improper Aft Starboard Solar Array"
|
||||
icon_state = "panelsS"
|
||||
|
||||
port
|
||||
/area/solar/port
|
||||
name = "\improper Aft Port Solar Array"
|
||||
icon_state = "panelsP"
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
always_unpowered = 1
|
||||
dynamic_lighting = 0
|
||||
|
||||
aft
|
||||
/area/outpost/engineering/solarsoutside/aft
|
||||
name = "\improper Engineering Outpost Solar Array"
|
||||
icon_state = "yellow"
|
||||
|
||||
|
||||
@@ -34,6 +34,15 @@
|
||||
// Track if we are already had initialize() called to prevent double-initialization.
|
||||
var/initialized = FALSE
|
||||
|
||||
/// Last name used to calculate a color for the chatmessage overlays
|
||||
var/chat_color_name
|
||||
/// Last color calculated for the the chatmessage overlays
|
||||
var/chat_color
|
||||
/// A luminescence-shifted value of the last color calculated for chatmessage overlays
|
||||
var/chat_color_darkened
|
||||
/// The chat color var, without alpha.
|
||||
var/chat_color_hover
|
||||
|
||||
/atom/New(loc, ...)
|
||||
// Don't call ..() unless /datum/New() ever exists
|
||||
|
||||
@@ -476,7 +485,7 @@
|
||||
// Use for objects performing visible actions
|
||||
// message is output to anyone who can see, e.g. "The [src] does something!"
|
||||
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
|
||||
/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs, var/range = world.view)
|
||||
/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs, var/range = world.view, var/runemessage = "<span style='font-size: 1.5em'>👁</span>")
|
||||
|
||||
var/list/see = get_mobs_and_objs_in_view_fast(get_turf(src), range, remote_ghosts = FALSE)
|
||||
|
||||
@@ -492,6 +501,8 @@
|
||||
var/mob/M = mob
|
||||
if(M.see_invisible >= invisibility && MOB_CAN_SEE_PLANE(M, plane))
|
||||
M.show_message(message, VISIBLE_MESSAGE, blind_message, AUDIBLE_MESSAGE)
|
||||
if(runemessage != -1)
|
||||
M.create_chat_message(src, "[runemessage]", FALSE, list("emote"), audible = FALSE)
|
||||
else if(blind_message)
|
||||
M.show_message(blind_message, AUDIBLE_MESSAGE)
|
||||
|
||||
@@ -500,7 +511,7 @@
|
||||
// message is the message output to anyone who can hear.
|
||||
// deaf_message (optional) is what deaf people will see.
|
||||
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance, var/radio_message)
|
||||
/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance, var/radio_message, var/runemessage)
|
||||
|
||||
var/range = hearing_distance || world.view
|
||||
var/list/hear = get_mobs_and_objs_in_view_fast(get_turf(src),range,remote_ghosts = FALSE)
|
||||
@@ -521,6 +532,8 @@
|
||||
var/mob/M = mob
|
||||
var/msg = message
|
||||
M.show_message(msg, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE)
|
||||
if(runemessage != -1)
|
||||
M.create_chat_message(src, "[runemessage || message]", FALSE, list("emote"))
|
||||
|
||||
/atom/movable/proc/dropInto(var/atom/destination)
|
||||
while(istype(destination))
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// Returns the lowest turf available on a given Z-level, defaults to asteroid for Polaris.
|
||||
|
||||
proc/get_base_turf(var/z)
|
||||
/proc/get_base_turf(var/z)
|
||||
if(!using_map.base_turf_by_z["[z]"])
|
||||
using_map.base_turf_by_z["[z]"] = /turf/space
|
||||
return using_map.base_turf_by_z["[z]"]
|
||||
|
||||
//An area can override the z-level base turf, so our solar array areas etc. can be space-based.
|
||||
proc/get_base_turf_by_area(var/turf/T)
|
||||
/proc/get_base_turf_by_area(var/turf/T)
|
||||
var/area/A = T.loc
|
||||
if(A.base_turf)
|
||||
return A.base_turf
|
||||
|
||||
@@ -58,10 +58,6 @@ var/global/list/datum/dna/gene/dna_genes[0]
|
||||
// Used for genes that check for value rather than a binary on/off.
|
||||
#define GENE_ALWAYS_ACTIVATE 1
|
||||
|
||||
// Skip checking if it's already active.
|
||||
// Used for genes that check for value rather than a binary on/off.
|
||||
#define GENE_ALWAYS_ACTIVATE 1
|
||||
|
||||
/datum/dna
|
||||
// READ-ONLY, GETS OVERWRITTEN
|
||||
// DO NOT FUCK WITH THESE OR BYOND WILL EAT YOUR FACE
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
activation_message="Your mind says 'Hello'."
|
||||
mutation=mHallucination
|
||||
|
||||
New()
|
||||
/datum/dna/gene/disability/hallucinate/New()
|
||||
block=HALLUCINATIONBLOCK
|
||||
|
||||
/datum/dna/gene/disability/epilepsy
|
||||
@@ -65,7 +65,7 @@
|
||||
activation_message="You get a headache."
|
||||
disability=EPILEPSY
|
||||
|
||||
New()
|
||||
/datum/dna/gene/disability/epilepsy/New()
|
||||
block=HEADACHEBLOCK
|
||||
|
||||
/datum/dna/gene/disability/cough
|
||||
@@ -73,7 +73,7 @@
|
||||
activation_message="You start coughing."
|
||||
disability=COUGHING
|
||||
|
||||
New()
|
||||
/datum/dna/gene/disability/cough/New()
|
||||
block=COUGHBLOCK
|
||||
|
||||
/datum/dna/gene/disability/clumsy
|
||||
@@ -81,7 +81,7 @@
|
||||
activation_message="You feel lightheaded."
|
||||
mutation=CLUMSY
|
||||
|
||||
New()
|
||||
/datum/dna/gene/disability/clumsy/New()
|
||||
block=CLUMSYBLOCK
|
||||
|
||||
/datum/dna/gene/disability/tourettes
|
||||
@@ -89,7 +89,7 @@
|
||||
activation_message="You twitch."
|
||||
disability=TOURETTES
|
||||
|
||||
New()
|
||||
/datum/dna/gene/disability/tourettes/New()
|
||||
block=TWITCHBLOCK
|
||||
|
||||
/datum/dna/gene/disability/nervousness
|
||||
@@ -97,7 +97,7 @@
|
||||
activation_message="You feel nervous."
|
||||
disability=NERVOUS
|
||||
|
||||
New()
|
||||
/datum/dna/gene/disability/nervousness/New()
|
||||
block=NERVOUSBLOCK
|
||||
|
||||
/datum/dna/gene/disability/blindness
|
||||
@@ -105,7 +105,7 @@
|
||||
activation_message="You can't seem to see anything."
|
||||
sdisability=BLIND
|
||||
|
||||
New()
|
||||
/datum/dna/gene/disability/blindness/New()
|
||||
block=BLINDBLOCK
|
||||
|
||||
/datum/dna/gene/disability/deaf
|
||||
@@ -113,10 +113,10 @@
|
||||
activation_message="It's kinda quiet."
|
||||
sdisability=DEAF
|
||||
|
||||
New()
|
||||
/datum/dna/gene/disability/deaf/New()
|
||||
block=DEAFBLOCK
|
||||
|
||||
activate(var/mob/M, var/connected, var/flags)
|
||||
/datum/dna/gene/disability/deaf/activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.ear_deaf = 1
|
||||
|
||||
@@ -125,5 +125,5 @@
|
||||
activation_message="Your eyes feel weird..."
|
||||
disability=NEARSIGHTED
|
||||
|
||||
New()
|
||||
/datum/dna/gene/disability/nearsighted/New()
|
||||
block=GLASSESBLOCK
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
activation_messages=list("You feel no need to breathe.")
|
||||
mutation=mNobreath
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/nobreath/New()
|
||||
block=NOBREATHBLOCK
|
||||
|
||||
/datum/dna/gene/basic/remoteview
|
||||
@@ -15,10 +15,10 @@
|
||||
activation_messages=list("Your mind expands.")
|
||||
mutation=mRemote
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/remoteview/New()
|
||||
block=REMOTEVIEWBLOCK
|
||||
|
||||
activate(var/mob/M, var/connected, var/flags)
|
||||
/datum/dna/gene/basic/remoteview/activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.verbs += /mob/living/carbon/human/proc/remoteobserve
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
activation_messages=list("You feel better.")
|
||||
mutation=mRegen
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/regenerate/New()
|
||||
block=REGENERATEBLOCK
|
||||
|
||||
/datum/dna/gene/basic/increaserun
|
||||
@@ -35,7 +35,7 @@
|
||||
activation_messages=list("Your leg muscles pulsate.")
|
||||
mutation=mRun
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/increaserun/New()
|
||||
block=INCREASERUNBLOCK
|
||||
|
||||
/datum/dna/gene/basic/remotetalk
|
||||
@@ -43,10 +43,10 @@
|
||||
activation_messages=list("You expand your mind outwards.")
|
||||
mutation=mRemotetalk
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/remotetalk/New()
|
||||
block=REMOTETALKBLOCK
|
||||
|
||||
activate(var/mob/M, var/connected, var/flags)
|
||||
/datum/dna/gene/basic/remotetalk/activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.verbs += /mob/living/carbon/human/proc/remotesay
|
||||
|
||||
@@ -55,56 +55,29 @@
|
||||
activation_messages=list("Your skin feels strange.")
|
||||
mutation=mMorph
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/morph/New()
|
||||
block=MORPHBLOCK
|
||||
|
||||
activate(var/mob/M)
|
||||
/datum/dna/gene/basic/morph/activate(var/mob/M)
|
||||
..(M)
|
||||
M.verbs += /mob/living/carbon/human/proc/morph
|
||||
|
||||
/* Not used on bay
|
||||
/datum/dna/gene/basic/heat_resist
|
||||
name="Heat Resistance"
|
||||
activation_messages=list("Your skin is icy to the touch.")
|
||||
mutation=mHeatres
|
||||
|
||||
New()
|
||||
block=COLDBLOCK
|
||||
|
||||
can_activate(var/mob/M,var/flags)
|
||||
if(flags & MUTCHK_FORCED)
|
||||
return !(/datum/dna/gene/basic/cold_resist in M.active_genes)
|
||||
// Probability check
|
||||
var/_prob = 15
|
||||
if(COLD_RESISTANCE in M.mutations)
|
||||
_prob=5
|
||||
if(probinj(_prob,(flags&MUTCHK_FORCED)))
|
||||
return 1
|
||||
|
||||
OnDrawUnderlays(var/mob/M,var/g,var/fat)
|
||||
return "cold[fat]_s"
|
||||
*/
|
||||
|
||||
/datum/dna/gene/basic/cold_resist
|
||||
name="Cold Resistance"
|
||||
activation_messages=list("Your body is filled with warmth.")
|
||||
mutation=COLD_RESISTANCE
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/cold_resist/New()
|
||||
block=FIREBLOCK
|
||||
|
||||
can_activate(var/mob/M,var/flags)
|
||||
/datum/dna/gene/basic/cold_resist/can_activate(var/mob/M,var/flags)
|
||||
if(flags & MUTCHK_FORCED)
|
||||
return 1
|
||||
// return !(/datum/dna/gene/basic/heat_resist in M.active_genes)
|
||||
// Probability check
|
||||
var/_prob=30
|
||||
//if(mHeatres in M.mutations)
|
||||
// _prob=5
|
||||
if(probinj(_prob,(flags&MUTCHK_FORCED)))
|
||||
return 1
|
||||
|
||||
OnDrawUnderlays(var/mob/M,var/g,var/fat)
|
||||
/datum/dna/gene/basic/cold_resist/OnDrawUnderlays(var/mob/M,var/g,var/fat)
|
||||
return "fire[fat]_s"
|
||||
|
||||
/datum/dna/gene/basic/noprints
|
||||
@@ -112,7 +85,7 @@
|
||||
activation_messages=list("Your fingers feel numb.")
|
||||
mutation=mFingerprints
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/noprints/New()
|
||||
block=NOPRINTSBLOCK
|
||||
|
||||
/datum/dna/gene/basic/noshock
|
||||
@@ -120,7 +93,7 @@
|
||||
activation_messages=list("Your skin feels strange.")
|
||||
mutation=mShock
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/noshock/New()
|
||||
block=SHOCKIMMUNITYBLOCK
|
||||
|
||||
/datum/dna/gene/basic/midget
|
||||
@@ -128,20 +101,20 @@
|
||||
activation_messages=list("Your skin feels rubbery.")
|
||||
mutation=mSmallsize
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/midget/New()
|
||||
block=SMALLSIZEBLOCK
|
||||
|
||||
can_activate(var/mob/M,var/flags)
|
||||
/datum/dna/gene/basic/midget/can_activate(var/mob/M,var/flags)
|
||||
// Can't be big and small.
|
||||
if(HULK in M.mutations)
|
||||
return 0
|
||||
return ..(M,flags)
|
||||
|
||||
activate(var/mob/M, var/connected, var/flags)
|
||||
/datum/dna/gene/basic/midget/activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.pass_flags |= 1
|
||||
|
||||
deactivate(var/mob/M, var/connected, var/flags)
|
||||
/datum/dna/gene/basic/midget/deactivate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.pass_flags &= ~1 //This may cause issues down the track, but offhand I can't think of any other way for humans to get passtable short of varediting so it should be fine. ~Z
|
||||
|
||||
@@ -150,22 +123,22 @@
|
||||
activation_messages=list("Your muscles hurt.")
|
||||
mutation=HULK
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/hulk/New()
|
||||
block=HULKBLOCK
|
||||
|
||||
can_activate(var/mob/M,var/flags)
|
||||
/datum/dna/gene/basic/hulk/can_activate(var/mob/M,var/flags)
|
||||
// Can't be big and small.
|
||||
if(mSmallsize in M.mutations)
|
||||
return 0
|
||||
return ..(M,flags)
|
||||
|
||||
OnDrawUnderlays(var/mob/M,var/g,var/fat)
|
||||
/datum/dna/gene/basic/hulk/OnDrawUnderlays(var/mob/M,var/g,var/fat)
|
||||
if(fat)
|
||||
return "hulk_[fat]_s"
|
||||
else
|
||||
return "hulk_[g]_s"
|
||||
|
||||
OnMobLife(var/mob/living/carbon/human/M)
|
||||
/datum/dna/gene/basic/hulk/OnMobLife(var/mob/living/carbon/human/M)
|
||||
if(!istype(M)) return
|
||||
if(M.health <= 25)
|
||||
M.mutations.Remove(HULK)
|
||||
@@ -179,7 +152,7 @@
|
||||
activation_messages=list("The walls suddenly disappear.")
|
||||
mutation=XRAY
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/xray/New()
|
||||
block=XRAYBLOCK
|
||||
|
||||
/datum/dna/gene/basic/tk
|
||||
@@ -188,7 +161,7 @@
|
||||
mutation=TK
|
||||
activation_prob=15
|
||||
|
||||
New()
|
||||
/datum/dna/gene/basic/tk/New()
|
||||
block=TELEBLOCK
|
||||
OnDrawUnderlays(var/mob/M,var/g,var/fat)
|
||||
/datum/dna/gene/basic/tk/OnDrawUnderlays(var/mob/M,var/g,var/fat)
|
||||
return "telekinesishead[fat]_s"
|
||||
|
||||
@@ -160,7 +160,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
//STINGS// //They get a pretty header because there's just so fucking many of them ;_;
|
||||
//////////
|
||||
|
||||
turf/proc/AdjacentTurfsRangedSting()
|
||||
/turf/proc/AdjacentTurfsRangedSting()
|
||||
//Yes this is snowflakey, but I couldn't get it to work any other way.. -Luke
|
||||
var/list/allowed = list(
|
||||
/obj/structure/table,
|
||||
|
||||
@@ -1,29 +1,6 @@
|
||||
//cast_method flags, needs to be up to date with Technomancer's. They were, for some reason, not working outside it.
|
||||
#define CAST_USE 1 // Clicking the spell in your hand.
|
||||
#define CAST_MELEE 2 // Clicking an atom in melee range.
|
||||
#define CAST_RANGED 4 // Clicking an atom beyond melee range.
|
||||
#define CAST_THROW 8 // Throwing the spell and hitting an atom.
|
||||
#define CAST_COMBINE 16 // Clicking another spell with this spell.
|
||||
#define CAST_INNATE 32 // Activates upon verb usage, used for mobs without hands.
|
||||
|
||||
//Aspects
|
||||
#define ASPECT_FIRE "fire" //Damage over time and raising body-temp. Firesuits protect from this.
|
||||
#define ASPECT_FROST "frost" //Slows down the affected, also involves imbedding with icicles. Winter coats protect from this.
|
||||
#define ASPECT_SHOCK "shock" //Energy-expensive, usually stuns. Insulated armor protects from this.
|
||||
#define ASPECT_AIR "air" //Mostly involves manipulation of atmos, useless in a vacuum. Magboots protect from this.
|
||||
#define ASPECT_FORCE "force" //Manipulates gravity to push things away or towards a location.
|
||||
#define ASPECT_TELE "tele" //Teleportation of self, other objects, or other people.
|
||||
#define ASPECT_DARK "dark" //Makes all those photons vanish using magic-- WITH SCIENCE. Used for sneaky stuff.
|
||||
#define ASPECT_LIGHT "light" //The opposite of dark, usually blinds, makes holo-illusions, or makes laser lightshows.
|
||||
#define ASPECT_BIOMED "biomed" //Mainly concerned with healing and restoration.
|
||||
#define ASPECT_EMP "emp" //Unused now.
|
||||
#define ASPECT_UNSTABLE "unstable" //Heavily RNG-based, causes instability to the victim.
|
||||
#define ASPECT_CHROMATIC "chromatic" //Used to combine with other spells.
|
||||
#define ASPECT_UNHOLY "unholy" //Involves the dead, blood, and most things against divine beings.
|
||||
|
||||
//////////////////////////////Construct Spells/////////////////////////
|
||||
|
||||
proc/findNullRod(var/atom/target)
|
||||
/proc/findNullRod(var/atom/target)
|
||||
if(istype(target,/obj/item/weapon/nullrod))
|
||||
return 1
|
||||
else if(target.contents)
|
||||
|
||||
@@ -65,8 +65,8 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
|
||||
// self other technology - Communication rune //was other hear blood
|
||||
// join hide technology - stun rune. Rune color: bright pink.
|
||||
New()
|
||||
..()
|
||||
/obj/effect/rune/Initialize()
|
||||
. = ..()
|
||||
blood_image = image(loc = src)
|
||||
blood_image.override = 1
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
@@ -74,7 +74,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
AI.client.images += blood_image
|
||||
rune_list.Add(src)
|
||||
|
||||
Destroy()
|
||||
/obj/effect/rune/Destroy()
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
if(AI.client)
|
||||
AI.client.images -= blood_image
|
||||
@@ -83,13 +83,13 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
rune_list.Remove(src)
|
||||
..()
|
||||
|
||||
examine(mob/user)
|
||||
/obj/effect/rune/examine(mob/user)
|
||||
. = ..()
|
||||
if(iscultist(user))
|
||||
. += "This spell circle reads: <i>[word1] [word2] [word3]</i>."
|
||||
|
||||
|
||||
attackby(I as obj, user as mob)
|
||||
/obj/effect/rune/attackby(I as obj, user as mob)
|
||||
if(istype(I, /obj/item/weapon/book/tome) && iscultist(user))
|
||||
to_chat(user, "You retrace your steps, carefully undoing the lines of the rune.")
|
||||
qdel(src)
|
||||
@@ -101,7 +101,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
return
|
||||
|
||||
|
||||
attack_hand(mob/living/user as mob)
|
||||
/obj/effect/rune/attack_hand(mob/living/user as mob)
|
||||
if(!iscultist(user))
|
||||
to_chat(user, "You can't mouth the arcane scratchings without fumbling over them.")
|
||||
return
|
||||
@@ -164,8 +164,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
return fizzle()
|
||||
|
||||
|
||||
proc
|
||||
fizzle()
|
||||
/obj/effect/rune/proc/fizzle()
|
||||
if(istype(src,/obj/effect/rune))
|
||||
usr.say(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix."))
|
||||
else
|
||||
@@ -174,7 +173,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
V.show_message("<span class='warning'>The markings pulse with a small burst of light, then fall dark.</span>", 3, "<span class='warning'>You hear a faint fizzle.</span>", 2)
|
||||
return
|
||||
|
||||
check_icon()
|
||||
/obj/effect/rune/proc/check_icon()
|
||||
icon = get_uristrune_cult(word1, word2, word3)
|
||||
|
||||
/obj/item/weapon/book/tome
|
||||
@@ -289,14 +288,14 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
</html>
|
||||
"}
|
||||
|
||||
New()
|
||||
..()
|
||||
/obj/item/weapon/book/tome/Initialize()
|
||||
. = ..()
|
||||
if(!cultwords["travel"])
|
||||
runerandom()
|
||||
for(var/V in cultwords)
|
||||
words[cultwords[V]] = V
|
||||
|
||||
attack(mob/living/M as mob, mob/living/user as mob)
|
||||
/obj/item/weapon/book/tome/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
add_attack_logs(user,M,"Hit with [name]")
|
||||
|
||||
if(istype(M,/mob/observer/dead))
|
||||
@@ -315,7 +314,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
to_chat(M, "<span class='danger'>You feel searing heat inside!</span>")
|
||||
|
||||
|
||||
attack_self(mob/living/user as mob)
|
||||
/obj/item/weapon/book/tome/attack_self(mob/living/user as mob)
|
||||
usr = user
|
||||
if(!usr.canmove || usr.stat || usr.restrained())
|
||||
return
|
||||
@@ -426,7 +425,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
to_chat(user, "The book seems full of illegible scribbles. Is this a joke?")
|
||||
return
|
||||
|
||||
examine(mob/user)
|
||||
/obj/item/weapon/book/tome/examine(mob/user)
|
||||
. = ..()
|
||||
if(!iscultist(user))
|
||||
. += "An old, dusty tome with frayed edges and a sinister looking cover."
|
||||
@@ -439,7 +438,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
/obj/item/weapon/book/tome/imbued //admin tome, spawns working runes without waiting
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/cultistsonly = 1
|
||||
attack_self(mob/user as mob)
|
||||
/obj/item/weapon/book/tome/imbued/attack_self(mob/user as mob)
|
||||
if(src.cultistsonly && !iscultist(usr))
|
||||
return
|
||||
if(!cultwords["travel"])
|
||||
|
||||
@@ -3,8 +3,6 @@ var/list/sacrificed = list()
|
||||
/obj/effect/rune/cultify()
|
||||
return
|
||||
|
||||
/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!"
|
||||
@@ -14,13 +12,11 @@ var/list/sacrificed = list()
|
||||
|
||||
|
||||
/////////////////////////////////////////FIRST RUNE
|
||||
proc
|
||||
teleport(var/key)
|
||||
/obj/effect/rune/proc/teleport(var/key)
|
||||
var/mob/living/user = usr
|
||||
var/allrunesloc[]
|
||||
allrunesloc = new/list()
|
||||
var/index = 0
|
||||
// var/tempnum = 0
|
||||
for(var/obj/effect/rune/R in rune_list)
|
||||
if(R == src)
|
||||
continue
|
||||
@@ -50,11 +46,7 @@ var/list/sacrificed = list()
|
||||
return
|
||||
|
||||
|
||||
itemport(var/key)
|
||||
// var/allrunesloc[]
|
||||
// allrunesloc = new/list()
|
||||
// var/index = 0
|
||||
// var/tempnum = 0
|
||||
/obj/effect/rune/proc/itemport(var/key)
|
||||
var/culcount = 0
|
||||
var/runecount = 0
|
||||
var/obj/effect/rune/IP = null
|
||||
@@ -90,7 +82,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////SECOND RUNE
|
||||
|
||||
tomesummon()
|
||||
/obj/effect/rune/proc/tomesummon()
|
||||
if(istype(src,/obj/effect/rune))
|
||||
usr.say("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!")
|
||||
else
|
||||
@@ -109,7 +101,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////THIRD RUNE
|
||||
|
||||
convert()
|
||||
/obj/effect/rune/proc/convert()
|
||||
var/mob/attacker = usr
|
||||
var/mob/living/carbon/target = null
|
||||
for(var/mob/living/carbon/M in src.loc)
|
||||
@@ -192,7 +184,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////FOURTH RUNE
|
||||
|
||||
tearreality()
|
||||
/obj/effect/rune/proc/tearreality()
|
||||
if(!cult.allow_narsie)
|
||||
return fizzle()
|
||||
|
||||
@@ -217,14 +209,13 @@ var/list/sacrificed = list()
|
||||
emergency_shuttle.launch_time = 0 // Cannot recall
|
||||
|
||||
log_and_message_admins_many(cultists, "summoned the end of days.")
|
||||
// new /obj/singularity/narsie/large(src.loc)
|
||||
return
|
||||
else
|
||||
return fizzle()
|
||||
|
||||
/////////////////////////////////////////FIFTH RUNE
|
||||
|
||||
emp(var/U,var/range_red) //range_red - var which determines by which number to reduce the default emp range, U is the source loc, needed because of talisman emps which are held in hand at the moment of using and that apparently messes things up -- Urist
|
||||
/obj/effect/rune/proc/emp(var/U,var/range_red) //range_red - var which determines by which number to reduce the default emp range, U is the source loc, needed because of talisman emps which are held in hand at the moment of using and that apparently messes things up -- Urist
|
||||
log_and_message_admins("activated an EMP rune.")
|
||||
if(istype(src,/obj/effect/rune))
|
||||
usr.say("Ta'gh fara[pick("'","`")]qha fel d'amar det!")
|
||||
@@ -241,7 +232,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////SIXTH RUNE
|
||||
|
||||
drain()
|
||||
/obj/effect/rune/proc/drain()
|
||||
var/drain = 0
|
||||
for(var/obj/effect/rune/R in rune_list)
|
||||
if(R.word1==cultwords["travel"] && R.word2==cultwords["blood"] && R.word3==cultwords["self"])
|
||||
@@ -301,7 +292,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////SEVENTH RUNE
|
||||
|
||||
seer()
|
||||
/obj/effect/rune/proc/seer()
|
||||
if(usr.loc==src.loc)
|
||||
if(usr.seer==1)
|
||||
usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.")
|
||||
@@ -322,7 +313,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////EIGHTH RUNE
|
||||
|
||||
raise()
|
||||
/obj/effect/rune/proc/raise()
|
||||
var/mob/living/carbon/human/corpse_to_raise
|
||||
var/mob/living/carbon/human/body_to_sacrifice
|
||||
|
||||
@@ -390,11 +381,6 @@ var/list/sacrificed = list()
|
||||
"<span class='danger'>You hear a thousand voices, all crying in pain.</span>")
|
||||
body_to_sacrifice.gib()
|
||||
|
||||
// if(ticker.mode.name == "cult")
|
||||
// ticker.mode:add_cultist(corpse_to_raise.mind)
|
||||
// else
|
||||
// ticker.mode.cult |= corpse_to_raise.mind
|
||||
|
||||
to_chat(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>")
|
||||
to_chat(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>")
|
||||
|
||||
@@ -406,7 +392,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////NINETH RUNE
|
||||
|
||||
obscure(var/rad)
|
||||
/obj/effect/rune/proc/obscure(var/rad)
|
||||
var/S=0
|
||||
for(var/obj/effect/rune/R in orange(rad,src))
|
||||
if(R!=src)
|
||||
@@ -434,7 +420,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////TENTH RUNE
|
||||
|
||||
ajourney() //some bits copypastaed from admin tools - Urist
|
||||
/obj/effect/rune/proc/ajourney() //some bits copypastaed from admin tools - Urist
|
||||
if(usr.loc==src.loc)
|
||||
var/mob/living/carbon/human/L = usr
|
||||
var/datum/gender/TU = gender_datums[L.get_visible_gender()]
|
||||
@@ -458,7 +444,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////ELEVENTH RUNE
|
||||
|
||||
manifest()
|
||||
/obj/effect/rune/proc/manifest()
|
||||
var/obj/effect/rune/this_rune = src
|
||||
src = null
|
||||
if(usr.loc!=this_rune.loc)
|
||||
@@ -521,7 +507,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////TWELFTH RUNE
|
||||
|
||||
talisman()//only hide, emp, teleport, deafen, blind and tome runes can be imbued atm
|
||||
/obj/effect/rune/proc/talisman()//only hide, emp, teleport, deafen, blind and tome runes can be imbued atm
|
||||
var/obj/item/weapon/paper/newtalisman
|
||||
var/unsuitable_newtalisman = 0
|
||||
for(var/obj/item/weapon/paper/P in src.loc)
|
||||
@@ -602,7 +588,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////THIRTEENTH RUNE
|
||||
|
||||
mend()
|
||||
/obj/effect/rune/proc/mend()
|
||||
var/mob/living/user = usr
|
||||
var/datum/gender/TU = gender_datums[usr.get_visible_gender()]
|
||||
src = null
|
||||
@@ -623,7 +609,7 @@ var/list/sacrificed = list()
|
||||
/////////////////////////////////////////FOURTEETH RUNE
|
||||
|
||||
// returns 0 if the rune is not used. returns 1 if the rune is used.
|
||||
communicate()
|
||||
/obj/effect/rune/proc/communicate()
|
||||
. = 1 // Default output is 1. If the rune is deleted it will return 1
|
||||
var/input = input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "")//sanitize() below, say() and whisper() have their own
|
||||
if(!input)
|
||||
@@ -650,7 +636,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////FIFTEENTH RUNE
|
||||
|
||||
sacrifice()
|
||||
/obj/effect/rune/proc/sacrifice()
|
||||
var/list/mob/living/carbon/human/cultsinrange = list()
|
||||
var/list/mob/living/carbon/human/victims = list()
|
||||
for(var/mob/living/carbon/human/V in src.loc)//Checks for non-cultist humans to sacrifice
|
||||
@@ -771,7 +757,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////SIXTEENTH RUNE
|
||||
|
||||
revealrunes(var/obj/W as obj)
|
||||
/obj/effect/rune/proc/revealrunes(var/obj/W as obj)
|
||||
var/go=0
|
||||
var/rad
|
||||
var/S=0
|
||||
@@ -815,7 +801,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////SEVENTEENTH RUNE
|
||||
|
||||
wall()
|
||||
/obj/effect/rune/proc/wall()
|
||||
usr.say("Khari[pick("'","`")]d! Eske'te tannin!")
|
||||
src.density = !src.density
|
||||
var/mob/living/user = usr
|
||||
@@ -828,7 +814,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////EIGHTTEENTH RUNE
|
||||
|
||||
freedom()
|
||||
/obj/effect/rune/proc/freedom()
|
||||
var/mob/living/user = usr
|
||||
var/list/mob/living/carbon/cultists = new
|
||||
for(var/datum/mind/H in cult.current_antagonists)
|
||||
@@ -875,7 +861,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////NINETEENTH RUNE
|
||||
|
||||
cultsummon()
|
||||
/obj/effect/rune/proc/cultsummon()
|
||||
var/mob/living/user = usr
|
||||
var/list/mob/living/carbon/cultists = new
|
||||
for(var/datum/mind/H in cult.current_antagonists)
|
||||
@@ -916,7 +902,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////TWENTIETH RUNES
|
||||
|
||||
deafen()
|
||||
/obj/effect/rune/proc/deafen()
|
||||
if(istype(src,/obj/effect/rune))
|
||||
var/list/affected = new()
|
||||
for(var/mob/living/carbon/C in range(7,src))
|
||||
@@ -958,7 +944,7 @@ var/list/sacrificed = list()
|
||||
V.show_message("<span class='warning'>Dust flows from [usr]'s hands for a moment, and the world suddenly becomes quiet..</span>", 3)
|
||||
return
|
||||
|
||||
blind()
|
||||
/obj/effect/rune/proc/blind()
|
||||
if(istype(src,/obj/effect/rune))
|
||||
var/list/affected = new()
|
||||
for(var/mob/living/carbon/C in viewers(src))
|
||||
@@ -1002,7 +988,7 @@ var/list/sacrificed = list()
|
||||
return
|
||||
|
||||
|
||||
bloodboil() //cultists need at least one DANGEROUS rune. Even if they're all stealthy.
|
||||
/obj/effect/rune/proc/bloodboil() //cultists need at least one DANGEROUS rune. Even if they're all stealthy.
|
||||
/*
|
||||
var/list/mob/living/carbon/cultists = new
|
||||
for(var/datum/mind/H in ticker.mode.cult)
|
||||
@@ -1043,7 +1029,7 @@ var/list/sacrificed = list()
|
||||
|
||||
// WIP rune, I'll wait for Rastaf0 to add limited blood.
|
||||
|
||||
burningblood()
|
||||
/obj/effect/rune/proc/burningblood()
|
||||
var/culcount = 0
|
||||
for(var/mob/living/carbon/C in orange(1,src))
|
||||
if(iscultist(C) && !C.stat)
|
||||
@@ -1071,7 +1057,7 @@ var/list/sacrificed = list()
|
||||
|
||||
////////// Rune 24 (counting burningblood, which kinda doesnt work yet.)
|
||||
|
||||
runestun(var/mob/living/T as mob)
|
||||
/obj/effect/rune/proc/runestun(var/mob/living/T as mob)
|
||||
if(istype(src,/obj/effect/rune)) ///When invoked as rune, flash and stun everyone around.
|
||||
usr.say("Fuu ma[pick("'","`")]jin!")
|
||||
for(var/mob/living/L in viewers(src))
|
||||
@@ -1116,7 +1102,7 @@ var/list/sacrificed = list()
|
||||
|
||||
/////////////////////////////////////////TWENTY-FIFTH RUNE
|
||||
|
||||
armor()
|
||||
/obj/effect/rune/proc/armor()
|
||||
var/mob/living/carbon/human/user = usr
|
||||
if(istype(src,/obj/effect/rune))
|
||||
usr.say("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!")
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
var/uses = 0
|
||||
info = "<center><img src='talisman.png'></center><br/><br/>"
|
||||
|
||||
attack_self(mob/living/user as mob)
|
||||
/obj/item/weapon/paper/talisman/attack_self(mob/living/user as mob)
|
||||
if(iscultist(user))
|
||||
var/delete = 1
|
||||
// who the hell thought this was a good idea :(
|
||||
@@ -43,7 +43,7 @@
|
||||
return
|
||||
|
||||
|
||||
attack(mob/living/carbon/T as mob, mob/living/user as mob)
|
||||
/obj/item/weapon/paper/talisman/attack(mob/living/carbon/T as mob, mob/living/user as mob)
|
||||
if(iscultist(user))
|
||||
if(imbue == "runestun")
|
||||
user.take_organ_damage(5, 0)
|
||||
@@ -55,7 +55,7 @@
|
||||
..()
|
||||
|
||||
|
||||
proc/supply(var/key)
|
||||
/obj/item/weapon/paper/talisman/proc/supply(var/key)
|
||||
if (!src.uses)
|
||||
qdel(src)
|
||||
return
|
||||
@@ -76,7 +76,7 @@
|
||||
return
|
||||
|
||||
|
||||
Topic(href, href_list)
|
||||
/obj/item/weapon/paper/talisman/Topic(href, href_list)
|
||||
if(!src) return
|
||||
if (usr.stat || usr.restrained() || !in_range(src, usr)) return
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
Bump(atom/clong)
|
||||
/obj/effect/immovablerod/Bump(atom/clong)
|
||||
if(istype(clong, /turf/simulated/shuttle)) //Skip shuttles without actually deleting the rod
|
||||
return
|
||||
|
||||
@@ -41,7 +41,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
if(clong && prob(25))
|
||||
src.loc = clong.loc
|
||||
|
||||
Destroy()
|
||||
/obj/effect/immovablerod/Destroy()
|
||||
walk(src, 0) // Because we might have called walk_towards, we must stop the walk loop or BYOND keeps an internal reference to us forever.
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -469,7 +469,7 @@ var/global/list/additional_antag_types = list()
|
||||
//////////////////////////
|
||||
//Reports player logouts//
|
||||
//////////////////////////
|
||||
proc/display_roundstart_logout_report()
|
||||
/proc/display_roundstart_logout_report()
|
||||
var/msg = "<span class='notice'><b>Roundstart logout report</b>\n\n"
|
||||
for(var/mob/living/L in mob_list)
|
||||
|
||||
@@ -521,7 +521,7 @@ proc/display_roundstart_logout_report()
|
||||
if(M.client && M.client.holder)
|
||||
to_chat(M,msg)
|
||||
|
||||
proc/get_nt_opposed()
|
||||
/proc/get_nt_opposed()
|
||||
var/list/dudes = list()
|
||||
for(var/mob/living/carbon/human/man in player_list)
|
||||
if(man.client)
|
||||
|
||||
@@ -1453,7 +1453,7 @@ datum
|
||||
return 0
|
||||
return 1
|
||||
|
||||
datum/objective/silence
|
||||
/datum/objective/silence
|
||||
explanation_text = "Do not allow anyone to escape the station. Only allow the shuttle to be called when everyone is dead and your story is the only one left."
|
||||
|
||||
check_completion()
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
var/global/list/all_objectives = list()
|
||||
|
||||
datum/objective
|
||||
/datum/objective
|
||||
var/datum/mind/owner = null //Who owns the objective.
|
||||
var/explanation_text = "Nothing" //What that person is supposed to do.
|
||||
var/datum/mind/target = null //If they are focused on a particular person.
|
||||
var/target_amount = 0 //If they are focused on a particular number. Steal objectives have their own counter.
|
||||
var/completed = 0 //currently only used for custom objectives.
|
||||
|
||||
New(var/text)
|
||||
/datum/objective/New(var/text)
|
||||
all_objectives |= src
|
||||
if(text)
|
||||
explanation_text = text
|
||||
..()
|
||||
|
||||
Destroy()
|
||||
/datum/objective/Destroy()
|
||||
all_objectives -= src
|
||||
..()
|
||||
|
||||
proc/check_completion()
|
||||
/datum/objective/proc/check_completion()
|
||||
return completed
|
||||
|
||||
proc/find_target()
|
||||
/datum/objective/proc/find_target()
|
||||
var/list/possible_targets = list()
|
||||
for(var/datum/mind/possible_target in ticker.minds)
|
||||
if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2))
|
||||
@@ -30,7 +30,7 @@ datum/objective
|
||||
target = pick(possible_targets)
|
||||
|
||||
|
||||
proc/find_target_by_role(role, role_type=0)//Option sets either to check assigned role or special role. Default to assigned.
|
||||
/datum/objective/proc/find_target_by_role(role, role_type=0)//Option sets either to check assigned role or special role. Default to assigned.
|
||||
for(var/datum/mind/possible_target in ticker.minds)
|
||||
if((possible_target != owner) && ishuman(possible_target.current) && ((role_type ? possible_target.special_role : possible_target.assigned_role) == role) )
|
||||
target = possible_target
|
||||
@@ -38,8 +38,7 @@ datum/objective
|
||||
|
||||
|
||||
|
||||
datum/objective/assassinate
|
||||
find_target()
|
||||
/datum/objective/assassinate/find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Assassinate [target.current.real_name], the [target.assigned_role]."
|
||||
@@ -48,7 +47,7 @@ datum/objective/assassinate
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
/datum/objective/assassinate/find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Assassinate [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]."
|
||||
@@ -57,7 +56,7 @@ datum/objective/assassinate
|
||||
return target
|
||||
|
||||
|
||||
check_completion()
|
||||
/datum/objective/assassinate/check_completion()
|
||||
if(target && target.current)
|
||||
if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
|
||||
return 1
|
||||
@@ -65,8 +64,7 @@ datum/objective/assassinate
|
||||
return 1
|
||||
|
||||
|
||||
datum/objective/anti_revolution/execute
|
||||
find_target()
|
||||
/datum/objective/anti_revolution/execute/find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
var/datum/gender/T = gender_datums[target.current.get_visible_gender()]
|
||||
@@ -76,7 +74,7 @@ datum/objective/anti_revolution/execute
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
/datum/objective/anti_revolution/execute/find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
var/datum/gender/T = gender_datums[target.current.get_visible_gender()]
|
||||
@@ -85,17 +83,17 @@ datum/objective/anti_revolution/execute
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
/datum/objective/anti_revolution/execute/check_completion()
|
||||
if(target && target.current)
|
||||
if(target.current.stat == DEAD || !ishuman(target.current))
|
||||
return 1
|
||||
return 0
|
||||
return 1
|
||||
|
||||
datum/objective/anti_revolution/brig
|
||||
/datum/objective/anti_revolution/brig
|
||||
var/already_completed = 0
|
||||
|
||||
find_target()
|
||||
/datum/objective/anti_revolution/brig/find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Brig [target.current.real_name], the [target.assigned_role] for 20 minutes to set an example."
|
||||
@@ -104,7 +102,7 @@ datum/objective/anti_revolution/brig
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
/datum/objective/anti_revolution/brig/find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Brig [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] for 20 minutes to set an example."
|
||||
@@ -112,7 +110,7 @@ datum/objective/anti_revolution/brig
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
/datum/objective/anti_revolution/brig/check_completion()
|
||||
if(already_completed)
|
||||
return 1
|
||||
|
||||
@@ -125,8 +123,7 @@ datum/objective/anti_revolution/brig
|
||||
return 0
|
||||
return 0
|
||||
|
||||
datum/objective/anti_revolution/demote
|
||||
find_target()
|
||||
/datum/objective/anti_revolution/demote/find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
var/datum/gender/T = gender_datums[target.current.get_visible_gender()]
|
||||
@@ -135,7 +132,7 @@ datum/objective/anti_revolution/demote
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
/datum/objective/anti_revolution/demote/find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
var/datum/gender/T = gender_datums[target.current.get_visible_gender()]
|
||||
@@ -144,7 +141,7 @@ datum/objective/anti_revolution/demote
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
/datum/objective/anti_revolution/demote/check_completion()
|
||||
if(target && target.current && istype(target,/mob/living/carbon/human))
|
||||
var/obj/item/weapon/card/id/I = target.current:wear_id
|
||||
if(istype(I, /obj/item/device/pda))
|
||||
@@ -159,8 +156,8 @@ datum/objective/anti_revolution/demote
|
||||
return 0
|
||||
return 1
|
||||
|
||||
datum/objective/debrain//I want braaaainssss
|
||||
find_target()
|
||||
//I want braaaainssss
|
||||
/datum/objective/debrain/find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Steal the brain of [target.current.real_name]."
|
||||
@@ -169,7 +166,7 @@ datum/objective/debrain//I want braaaainssss
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
/datum/objective/debrain/find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Steal the brain of [target.current.real_name] the [!role_type ? target.assigned_role : target.special_role]."
|
||||
@@ -177,7 +174,7 @@ datum/objective/debrain//I want braaaainssss
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
/datum/objective/debrain/check_completion()
|
||||
if(!target)//If it's a free objective.
|
||||
return 1
|
||||
if( !owner.current || owner.current.stat==DEAD )//If you're otherwise dead.
|
||||
@@ -192,8 +189,8 @@ datum/objective/debrain//I want braaaainssss
|
||||
return 0
|
||||
|
||||
|
||||
datum/objective/protect//The opposite of killing a dude.
|
||||
find_target()
|
||||
//The opposite of killing a dude.
|
||||
/datum/objective/protect/find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Protect [target.current.real_name], the [target.assigned_role]."
|
||||
@@ -202,7 +199,7 @@ datum/objective/protect//The opposite of killing a dude.
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
/datum/objective/protect/find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Protect [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]."
|
||||
@@ -210,7 +207,7 @@ datum/objective/protect//The opposite of killing a dude.
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
/datum/objective/protect/check_completion()
|
||||
if(!target) //If it's a free objective.
|
||||
return 1
|
||||
if(target.current)
|
||||
@@ -220,10 +217,10 @@ datum/objective/protect//The opposite of killing a dude.
|
||||
return 0
|
||||
|
||||
|
||||
datum/objective/hijack
|
||||
/datum/objective/hijack
|
||||
explanation_text = "Hijack the emergency shuttle by escaping alone."
|
||||
|
||||
check_completion()
|
||||
/datum/objective/hijack/check_completion()
|
||||
if(!owner.current || owner.current.stat)
|
||||
return 0
|
||||
if(!emergency_shuttle.returned())
|
||||
@@ -241,11 +238,11 @@ datum/objective/hijack
|
||||
return 1
|
||||
|
||||
|
||||
datum/objective/block
|
||||
/datum/objective/block
|
||||
explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive."
|
||||
|
||||
|
||||
check_completion()
|
||||
/datum/objective/block/check_completion()
|
||||
if(!istype(owner.current, /mob/living/silicon))
|
||||
return 0
|
||||
if(!emergency_shuttle.returned())
|
||||
@@ -262,10 +259,10 @@ datum/objective/block
|
||||
return 0
|
||||
return 1
|
||||
|
||||
datum/objective/silence
|
||||
/datum/objective/silence
|
||||
explanation_text = "Do not allow anyone to escape the station. Only allow the shuttle to be called when everyone is dead and your story is the only one left."
|
||||
|
||||
check_completion()
|
||||
/datum/objective/silence/check_completion()
|
||||
if(!emergency_shuttle.returned())
|
||||
return 0
|
||||
|
||||
@@ -282,11 +279,11 @@ datum/objective/silence
|
||||
return 1
|
||||
|
||||
|
||||
datum/objective/escape
|
||||
/datum/objective/escape
|
||||
explanation_text = "Escape on the shuttle or an escape pod alive and free."
|
||||
|
||||
|
||||
check_completion()
|
||||
/datum/objective/escape/check_completion()
|
||||
if(issilicon(owner.current))
|
||||
return 0
|
||||
if(isbrain(owner.current))
|
||||
@@ -322,10 +319,10 @@ datum/objective/escape
|
||||
|
||||
|
||||
|
||||
datum/objective/survive
|
||||
/datum/objective/survive
|
||||
explanation_text = "Stay alive until the end."
|
||||
|
||||
check_completion()
|
||||
/datum/objective/survive/check_completion()
|
||||
if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current))
|
||||
return 0 //Brains no longer win survive objectives. --NEO
|
||||
if(issilicon(owner.current) && owner.current != owner.original)
|
||||
@@ -333,10 +330,10 @@ datum/objective/survive
|
||||
return 1
|
||||
|
||||
// Similar to the anti-rev objective, but for traitors
|
||||
datum/objective/brig
|
||||
/datum/objective/brig
|
||||
var/already_completed = 0
|
||||
|
||||
find_target()
|
||||
/datum/objective/brig/find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Have [target.current.real_name], the [target.assigned_role] brigged for 10 minutes."
|
||||
@@ -345,7 +342,7 @@ datum/objective/brig
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
/datum/objective/brig/find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Have [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] brigged for 10 minutes."
|
||||
@@ -353,7 +350,7 @@ datum/objective/brig
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
/datum/objective/brig/check_completion()
|
||||
if(already_completed)
|
||||
return 1
|
||||
|
||||
@@ -368,10 +365,10 @@ datum/objective/brig
|
||||
return 0
|
||||
|
||||
// Harm a crew member, making an example of them
|
||||
datum/objective/harm
|
||||
/datum/objective/harm
|
||||
var/already_completed = 0
|
||||
|
||||
find_target()
|
||||
/datum/objective/harm/find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Make an example of [target.current.real_name], the [target.assigned_role]. Break one of their bones, detach one of their limbs or disfigure their face. Make sure they're alive when you do it."
|
||||
@@ -380,7 +377,7 @@ datum/objective/harm
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
/datum/objective/harm/find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Make an example of [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]. Break one of their bones, detach one of their limbs or disfigure their face. Make sure they're alive when you do it."
|
||||
@@ -388,7 +385,7 @@ datum/objective/harm
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
/datum/objective/harm/check_completion()
|
||||
if(already_completed)
|
||||
return 1
|
||||
|
||||
@@ -417,12 +414,12 @@ datum/objective/harm
|
||||
return 0
|
||||
|
||||
|
||||
datum/objective/nuclear
|
||||
/datum/objective/nuclear
|
||||
explanation_text = "Destroy the station with a nuclear device."
|
||||
|
||||
|
||||
|
||||
datum/objective/steal
|
||||
/datum/objective/steal
|
||||
var/obj/item/steal_target
|
||||
var/target_name
|
||||
|
||||
@@ -461,7 +458,7 @@ datum/objective/steal
|
||||
)
|
||||
|
||||
|
||||
proc/set_target(item_name)
|
||||
/datum/objective/steal/proc/set_target(item_name)
|
||||
target_name = item_name
|
||||
steal_target = possible_items[target_name]
|
||||
if (!steal_target )
|
||||
@@ -470,11 +467,11 @@ datum/objective/steal
|
||||
return steal_target
|
||||
|
||||
|
||||
find_target()
|
||||
/datum/objective/steal/find_target()
|
||||
return set_target(pick(possible_items))
|
||||
|
||||
|
||||
proc/select_target()
|
||||
/datum/objective/steal/proc/select_target()
|
||||
var/list/possible_items_all = possible_items+possible_items_special+"custom"
|
||||
var/new_target = input("Select target:", "Objective target", steal_target) as null|anything in possible_items_all
|
||||
if (!new_target) return
|
||||
@@ -493,7 +490,7 @@ datum/objective/steal
|
||||
set_target(new_target)
|
||||
return steal_target
|
||||
|
||||
check_completion()
|
||||
/datum/objective/steal/check_completion()
|
||||
if(!steal_target || !owner.current) return 0
|
||||
if(!isliving(owner.current)) return 0
|
||||
var/list/all_items = owner.current.get_contents()
|
||||
@@ -547,14 +544,13 @@ datum/objective/steal
|
||||
|
||||
|
||||
|
||||
datum/objective/download
|
||||
proc/gen_amount_goal()
|
||||
/datum/objective/download/proc/gen_amount_goal()
|
||||
target_amount = rand(10,20)
|
||||
explanation_text = "Download [target_amount] research levels."
|
||||
return target_amount
|
||||
|
||||
|
||||
check_completion()
|
||||
/datum/objective/download/check_completion()
|
||||
if(!ishuman(owner.current))
|
||||
return 0
|
||||
if(!owner.current || owner.current.stat == 2)
|
||||
@@ -579,14 +575,13 @@ datum/objective/download
|
||||
|
||||
return (current_amount<target_amount) ? 0 : 1
|
||||
|
||||
datum/objective/capture
|
||||
proc/gen_amount_goal()
|
||||
/datum/objective/capture/proc/gen_amount_goal()
|
||||
target_amount = rand(5,10)
|
||||
explanation_text = "Accumulate [target_amount] capture points."
|
||||
return target_amount
|
||||
|
||||
|
||||
check_completion()//Basically runs through all the mobs in the area to determine how much they are worth.
|
||||
/datum/objective/capture/check_completion()//Basically runs through all the mobs in the area to determine how much they are worth.
|
||||
var/captured_amount = 0
|
||||
var/area/centcom/holding/A = locate()
|
||||
|
||||
@@ -609,8 +604,7 @@ datum/objective/capture
|
||||
return 1
|
||||
|
||||
|
||||
/datum/objective/absorb
|
||||
proc/gen_amount_goal(var/lowbound = 4, var/highbound = 6)
|
||||
/datum/objective/absorb/proc/gen_amount_goal(var/lowbound = 4, var/highbound = 6)
|
||||
target_amount = rand (lowbound,highbound)
|
||||
if (ticker)
|
||||
var/n_p = 1 //autowin
|
||||
@@ -627,19 +621,17 @@ datum/objective/capture
|
||||
explanation_text = "Absorb [target_amount] compatible genomes."
|
||||
return target_amount
|
||||
|
||||
check_completion()
|
||||
/datum/objective/absorb/check_completion()
|
||||
if(owner && owner.changeling && owner.changeling.absorbed_dna && (owner.changeling.absorbedcount >= target_amount))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
// Heist objectives.
|
||||
datum/objective/heist
|
||||
proc/choose_target()
|
||||
/datum/objective/heist/proc/choose_target()
|
||||
return
|
||||
|
||||
datum/objective/heist/kidnap
|
||||
choose_target()
|
||||
/datum/objective/heist/kidnap/choose_target()
|
||||
var/list/roles = list("Chief Engineer","Research Director","Roboticist","Chemist","Station Engineer")
|
||||
var/list/possible_targets = list()
|
||||
var/list/priority_targets = list()
|
||||
@@ -663,7 +655,7 @@ datum/objective/heist/kidnap
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
/datum/objective/heist/kidnap/check_completion()
|
||||
if(target && target.current)
|
||||
if (target.current.stat == 2)
|
||||
return 0 // They're dead. Fail.
|
||||
@@ -677,9 +669,7 @@ datum/objective/heist/kidnap
|
||||
else
|
||||
return 0
|
||||
|
||||
datum/objective/heist/loot
|
||||
|
||||
choose_target()
|
||||
/datum/objective/heist/loot/choose_target()
|
||||
var/loot = "an object"
|
||||
switch(rand(1,8))
|
||||
if(1)
|
||||
@@ -717,8 +707,8 @@ datum/objective/heist/loot
|
||||
|
||||
explanation_text = "It's a buyer's market out here. Steal [loot] for resale."
|
||||
|
||||
check_completion()
|
||||
|
||||
/datum/objective/heist/loot/check_completion()
|
||||
var/total_amount = 0
|
||||
|
||||
for(var/obj/O in locate(/area/skipjack_station/start))
|
||||
@@ -735,9 +725,7 @@ datum/objective/heist/loot
|
||||
|
||||
return 0
|
||||
|
||||
datum/objective/heist/salvage
|
||||
|
||||
choose_target()
|
||||
/datum/objective/heist/salvage/choose_target()
|
||||
switch(rand(1,8))
|
||||
if(1)
|
||||
target = DEFAULT_WALL_MATERIAL
|
||||
@@ -766,7 +754,7 @@ datum/objective/heist/salvage
|
||||
|
||||
explanation_text = "Ransack the station and escape with [target_amount] [target]."
|
||||
|
||||
check_completion()
|
||||
/datum/objective/heist/salvage/check_completion()
|
||||
|
||||
var/total_amount = 0
|
||||
|
||||
@@ -798,7 +786,7 @@ datum/objective/heist/salvage
|
||||
/datum/objective/heist/preserve_crew
|
||||
explanation_text = "Do not leave anyone behind, alive or dead."
|
||||
|
||||
check_completion()
|
||||
/datum/objective/heist/preserve_crew/check_completion()
|
||||
if(raiders && raiders.is_raider_crew_safe()) return 1
|
||||
return 0
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user