mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-07-20 04:32:50 +01:00
Merge branch 'master' of https://github.com/PolarisSS13/Polaris into woodrat_map
This commit is contained in:
@@ -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
|
||||
|
||||
+4
-6
@@ -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,77 +11,77 @@
|
||||
var/obj/machinery/atmospherics/unary/heat_exchanger/partner = null
|
||||
var/update_cycle
|
||||
|
||||
update_icon()
|
||||
if(node)
|
||||
icon_state = "intact"
|
||||
else
|
||||
icon_state = "exposed"
|
||||
/obj/machinery/atmospherics/unary/heat_exchanger/update_icon()
|
||||
if(node)
|
||||
icon_state = "intact"
|
||||
else
|
||||
icon_state = "exposed"
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
atmos_init()
|
||||
if(!partner)
|
||||
var/partner_connect = turn(dir,180)
|
||||
/obj/machinery/atmospherics/unary/heat_exchanger/atmos_init()
|
||||
if(!partner)
|
||||
var/partner_connect = turn(dir,180)
|
||||
|
||||
for(var/obj/machinery/atmospherics/unary/heat_exchanger/target in get_step(src,partner_connect))
|
||||
if(target.dir & get_dir(src,target))
|
||||
partner = target
|
||||
partner.partner = src
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/unary/heat_exchanger/target in get_step(src,partner_connect))
|
||||
if(target.dir & get_dir(src,target))
|
||||
partner = target
|
||||
partner.partner = src
|
||||
break
|
||||
|
||||
..()
|
||||
..()
|
||||
|
||||
process()
|
||||
..()
|
||||
if(!partner)
|
||||
return 0
|
||||
/obj/machinery/atmospherics/unary/heat_exchanger/process()
|
||||
..()
|
||||
if(!partner)
|
||||
return 0
|
||||
|
||||
if(!air_master || air_master.current_cycle <= update_cycle)
|
||||
return 0
|
||||
if(!air_master || air_master.current_cycle <= update_cycle)
|
||||
return 0
|
||||
|
||||
update_cycle = air_master.current_cycle
|
||||
partner.update_cycle = air_master.current_cycle
|
||||
update_cycle = air_master.current_cycle
|
||||
partner.update_cycle = air_master.current_cycle
|
||||
|
||||
var/air_heat_capacity = air_contents.heat_capacity()
|
||||
var/other_air_heat_capacity = partner.air_contents.heat_capacity()
|
||||
var/combined_heat_capacity = other_air_heat_capacity + air_heat_capacity
|
||||
var/air_heat_capacity = air_contents.heat_capacity()
|
||||
var/other_air_heat_capacity = partner.air_contents.heat_capacity()
|
||||
var/combined_heat_capacity = other_air_heat_capacity + air_heat_capacity
|
||||
|
||||
var/old_temperature = air_contents.temperature
|
||||
var/other_old_temperature = partner.air_contents.temperature
|
||||
var/old_temperature = air_contents.temperature
|
||||
var/other_old_temperature = partner.air_contents.temperature
|
||||
|
||||
if(combined_heat_capacity > 0)
|
||||
var/combined_energy = partner.air_contents.temperature*other_air_heat_capacity + air_heat_capacity*air_contents.temperature
|
||||
if(combined_heat_capacity > 0)
|
||||
var/combined_energy = partner.air_contents.temperature*other_air_heat_capacity + air_heat_capacity*air_contents.temperature
|
||||
|
||||
var/new_temperature = combined_energy/combined_heat_capacity
|
||||
air_contents.temperature = new_temperature
|
||||
partner.air_contents.temperature = new_temperature
|
||||
var/new_temperature = combined_energy/combined_heat_capacity
|
||||
air_contents.temperature = new_temperature
|
||||
partner.air_contents.temperature = new_temperature
|
||||
|
||||
if(network)
|
||||
if(abs(old_temperature-air_contents.temperature) > 1)
|
||||
network.update = 1
|
||||
if(network)
|
||||
if(abs(old_temperature-air_contents.temperature) > 1)
|
||||
network.update = 1
|
||||
|
||||
if(partner.network)
|
||||
if(abs(other_old_temperature-partner.air_contents.temperature) > 1)
|
||||
partner.network.update = 1
|
||||
if(partner.network)
|
||||
if(abs(other_old_temperature-partner.air_contents.temperature) > 1)
|
||||
partner.network.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/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
|
||||
if (level==1 && isturf(T) && !T.is_plating())
|
||||
to_chat(user, "<span class='warning'>You must remove the plating first.</span>")
|
||||
return 1
|
||||
|
||||
attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
if (!W.is_wrench())
|
||||
return ..()
|
||||
var/turf/T = src.loc
|
||||
if (level==1 && isturf(T) && !T.is_plating())
|
||||
to_chat(user, "<span class='warning'>You must remove the plating first.</span>")
|
||||
return 1
|
||||
if (!can_unwrench())
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if (do_after(user, 40 * W.toolspeed))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
deconstruct()
|
||||
if (!can_unwrench())
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if (do_after(user, 40 * W.toolspeed))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
deconstruct()
|
||||
|
||||
@@ -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()
|
||||
*/
|
||||
+15
-15
@@ -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)
|
||||
|
||||
+2
-2
@@ -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))
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+3
-3
@@ -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)
|
||||
|
||||
+2
-2
@@ -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"
|
||||
@@ -139,4 +138,28 @@ var/list/be_special_flags = list(
|
||||
#define Sp_CHARGES "charges"
|
||||
#define Sp_HOLDVAR "holdervar"
|
||||
|
||||
#define CHANGELING_STASIS_COST 20
|
||||
#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
|
||||
@@ -452,4 +450,6 @@ 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
|
||||
#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,7 +19,9 @@
|
||||
#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.
|
||||
#define OUTDOORS_INHERIT -1 // If a turf has this, it will defer to the area's settings.
|
||||
#define OUTDOORS_INHERIT -1 // If a turf has this, it will defer to the area's settings.
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
+27
-31
@@ -314,39 +314,35 @@
|
||||
|
||||
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)
|
||||
var/turf/T
|
||||
if(X1==X2)
|
||||
if(Y1==Y2)
|
||||
return 1 //Light cannot be blocked on same tile
|
||||
else
|
||||
var/s = SIGN(Y2-Y1)
|
||||
Y1+=s
|
||||
while(Y1!=Y2)
|
||||
T=locate(X1,Y1,Z)
|
||||
if(T.opacity)
|
||||
return 0
|
||||
Y1+=s
|
||||
/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)
|
||||
return 1 //Light cannot be blocked on same tile
|
||||
else
|
||||
var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1))
|
||||
var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles
|
||||
var/signX = SIGN(X2-X1)
|
||||
var/signY = SIGN(Y2-Y1)
|
||||
if(X1<X2)
|
||||
b+=m
|
||||
while(X1!=X2 || Y1!=Y2)
|
||||
if(round(m*X1+b-Y1))
|
||||
Y1+=signY //Line exits tile vertically
|
||||
else
|
||||
X1+=signX //Line exits tile horizontally
|
||||
var/s = SIGN(Y2-Y1)
|
||||
Y1+=s
|
||||
while(Y1!=Y2)
|
||||
T=locate(X1,Y1,Z)
|
||||
if(T.opacity)
|
||||
return 0
|
||||
return 1
|
||||
#undef SIGN
|
||||
Y1+=s
|
||||
else
|
||||
var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1))
|
||||
var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles
|
||||
var/signX = SIGN(X2-X1)
|
||||
var/signY = SIGN(Y2-Y1)
|
||||
if(X1<X2)
|
||||
b+=m
|
||||
while(X1!=X2 || Y1!=Y2)
|
||||
if(round(m*X1+b-Y1))
|
||||
Y1+=signY //Line exits tile vertically
|
||||
else
|
||||
X1+=signX //Line exits tile horizontally
|
||||
T=locate(X1,Y1,Z)
|
||||
if(T.opacity)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/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)
|
||||
|
||||
+81
-82
@@ -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,85 +215,84 @@ world
|
||||
|
||||
#define TO_HEX_DIGIT(n) ascii2text((n&15) + ((n&15)<10 ? 48 : 87))
|
||||
|
||||
icon
|
||||
proc/MakeLying()
|
||||
var/icon/I = new(src,dir=SOUTH)
|
||||
I.BecomeLying()
|
||||
return I
|
||||
/icon/proc/MakeLying()
|
||||
var/icon/I = new(src,dir=SOUTH)
|
||||
I.BecomeLying()
|
||||
return I
|
||||
|
||||
proc/BecomeLying()
|
||||
Turn(90)
|
||||
Shift(SOUTH,6)
|
||||
Shift(EAST,1)
|
||||
/icon/proc/BecomeLying()
|
||||
Turn(90)
|
||||
Shift(SOUTH,6)
|
||||
Shift(EAST,1)
|
||||
|
||||
// Multiply all alpha values by this float
|
||||
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)
|
||||
// Multiply all alpha values by this float
|
||||
/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()
|
||||
MapColors(0.3,0.3,0.3, 0.59,0.59,0.59, 0.11,0.11,0.11, 0,0,0)
|
||||
// Convert to 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)
|
||||
GrayScale()
|
||||
/icon/proc/ColorTone(tone)
|
||||
GrayScale()
|
||||
|
||||
var/list/TONE = ReadRGB(tone)
|
||||
var/gray = round(TONE[1]*0.3 + TONE[2]*0.59 + TONE[3]*0.11, 1)
|
||||
var/list/TONE = ReadRGB(tone)
|
||||
var/gray = round(TONE[1]*0.3 + TONE[2]*0.59 + TONE[3]*0.11, 1)
|
||||
|
||||
var/icon/upper = (255-gray) ? new(src) : null
|
||||
var/icon/upper = (255-gray) ? new(src) : null
|
||||
|
||||
if(gray)
|
||||
MapColors(255/gray,0,0, 0,255/gray,0, 0,0,255/gray, 0,0,0)
|
||||
Blend(tone, ICON_MULTIPLY)
|
||||
else SetIntensity(0)
|
||||
if(255-gray)
|
||||
upper.Blend(rgb(gray,gray,gray), ICON_SUBTRACT)
|
||||
upper.MapColors((255-TONE[1])/(255-gray),0,0,0, 0,(255-TONE[2])/(255-gray),0,0, 0,0,(255-TONE[3])/(255-gray),0, 0,0,0,0, 0,0,0,1)
|
||||
Blend(upper, ICON_ADD)
|
||||
if(gray)
|
||||
MapColors(255/gray,0,0, 0,255/gray,0, 0,0,255/gray, 0,0,0)
|
||||
Blend(tone, ICON_MULTIPLY)
|
||||
else SetIntensity(0)
|
||||
if(255-gray)
|
||||
upper.Blend(rgb(gray,gray,gray), ICON_SUBTRACT)
|
||||
upper.MapColors((255-TONE[1])/(255-gray),0,0,0, 0,(255-TONE[2])/(255-gray),0,0, 0,0,(255-TONE[3])/(255-gray),0, 0,0,0,0, 0,0,0,1)
|
||||
Blend(upper, ICON_ADD)
|
||||
|
||||
// Take the minimum color of two icons; combine transparency as if blending with ICON_ADD
|
||||
proc/MinColors(icon)
|
||||
var/icon/I = new(src)
|
||||
I.Opaque()
|
||||
I.Blend(icon, ICON_SUBTRACT)
|
||||
Blend(I, ICON_SUBTRACT)
|
||||
// Take the minimum color of two icons; combine transparency as if blending with ICON_ADD
|
||||
/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)
|
||||
var/icon/I
|
||||
if(isicon(icon))
|
||||
I = new(icon)
|
||||
else
|
||||
// solid color
|
||||
I = new(src)
|
||||
I.Blend("#000000", ICON_OVERLAY)
|
||||
I.SwapColor("#000000", null)
|
||||
I.Blend(icon, ICON_OVERLAY)
|
||||
var/icon/J = new(src)
|
||||
J.Opaque()
|
||||
I.Blend(J, ICON_SUBTRACT)
|
||||
Blend(I, ICON_OR)
|
||||
// Take the maximum color of two icons; combine opacity as if blending with ICON_OR
|
||||
/icon/proc/MaxColors(icon)
|
||||
var/icon/I
|
||||
if(isicon(icon))
|
||||
I = new(icon)
|
||||
else
|
||||
// solid color
|
||||
I = new(src)
|
||||
I.Blend("#000000", ICON_OVERLAY)
|
||||
I.SwapColor("#000000", null)
|
||||
I.Blend(icon, ICON_OVERLAY)
|
||||
var/icon/J = new(src)
|
||||
J.Opaque()
|
||||
I.Blend(J, ICON_SUBTRACT)
|
||||
Blend(I, ICON_OR)
|
||||
|
||||
// make this icon fully opaque--transparent pixels become black
|
||||
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)
|
||||
// make this icon fully opaque--transparent pixels become black
|
||||
/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()
|
||||
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)
|
||||
// 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
|
||||
/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)
|
||||
Opaque()
|
||||
AddAlphaMask(mask)
|
||||
/icon/proc/UseAlphaMask(mask)
|
||||
Opaque()
|
||||
AddAlphaMask(mask)
|
||||
|
||||
proc/AddAlphaMask(mask)
|
||||
var/icon/M = new(mask)
|
||||
M.Blend("#ffffff", ICON_SUBTRACT)
|
||||
// apply mask
|
||||
Blend(M, ICON_ADD)
|
||||
/icon/proc/AddAlphaMask(mask)
|
||||
var/icon/M = new(mask)
|
||||
M.Blend("#ffffff", ICON_SUBTRACT)
|
||||
// apply mask
|
||||
Blend(M, ICON_ADD)
|
||||
|
||||
/*
|
||||
HSV format is represented as "#hhhssvv" or "#hhhssvvaa"
|
||||
@@ -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
|
||||
|
||||
+3
-2
@@ -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
|
||||
@@ -188,16 +182,17 @@ var/list/global_huds = list(
|
||||
var/icon/ui_style
|
||||
var/ui_color
|
||||
var/ui_alpha
|
||||
|
||||
|
||||
var/list/minihuds = list()
|
||||
|
||||
datum/hud/New(mob/owner)
|
||||
/datum/hud/New(mob/owner)
|
||||
mymob = owner
|
||||
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
|
||||
@@ -307,7 +301,7 @@ datum/hud/New(mob/owner)
|
||||
/datum/hud/proc/instantiate()
|
||||
if(!ismob(mymob))
|
||||
return 0
|
||||
|
||||
|
||||
mymob.create_mob_hud(src)
|
||||
|
||||
persistant_inventory_update()
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
+15
-11
@@ -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")
|
||||
Failsafe.defcon = 2
|
||||
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,10 +68,14 @@ 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
|
||||
current_cycle++ // Begin a new air_master cycle!
|
||||
current_step = SSAIR_TURFS // Start with Step 1 of course
|
||||
// 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
|
||||
|
||||
INTERNAL_PROCESS_STEP(SSAIR_TURFS, TRUE, process_tiles_to_update, cost_turfs, SSAIR_EDGES)
|
||||
INTERNAL_PROCESS_STEP(SSAIR_EDGES, FALSE, process_active_edges, cost_edges, SSAIR_FIREZONES)
|
||||
@@ -80,10 +84,11 @@ 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
|
||||
currentrun = null
|
||||
current_step = null
|
||||
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
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_tiles_to_update(resumed = 0)
|
||||
if (!resumed)
|
||||
|
||||
@@ -45,9 +45,13 @@ 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
|
||||
stage = SSLIGHTING_STAGE_LIGHTS // Start with Step 1 of course
|
||||
// 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)
|
||||
timer = TICK_USAGE
|
||||
@@ -77,10 +81,11 @@ 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
|
||||
currentrun = null
|
||||
stage = null
|
||||
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
|
||||
|
||||
/datum/controller/subsystem/lighting/proc/internal_process_lights(resumed = FALSE, init_tick_checks = FALSE)
|
||||
if (!resumed)
|
||||
@@ -162,5 +167,4 @@ SUBSYSTEM_DEF(lighting)
|
||||
#undef DUAL_TICK_CHECK
|
||||
#undef SSLIGHTING_STAGE_LIGHTS
|
||||
#undef SSLIGHTING_STAGE_CORNERS
|
||||
#undef SSLIGHTING_STAGE_OVERLAYS
|
||||
#undef SSLIGHTING_STAGE_STATS
|
||||
#undef SSLIGHTING_STAGE_OVERLAYS
|
||||
@@ -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
|
||||
|
||||
@@ -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,62 +6,62 @@
|
||||
/datum/events
|
||||
var/list/events
|
||||
|
||||
New()
|
||||
..()
|
||||
events = new
|
||||
/datum/events/New()
|
||||
..()
|
||||
events = new
|
||||
|
||||
proc/addEventType(event_type as text)
|
||||
if(!(event_type in events) || !islist(events[event_type]))
|
||||
events[event_type] = list()
|
||||
return 1
|
||||
return
|
||||
|
||||
|
||||
// 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)
|
||||
if(!event_type || !proc_holder || !proc_name)
|
||||
return
|
||||
addEventType(event_type)
|
||||
var/list/event = events[event_type]
|
||||
var/datum/event/E = new /datum/event(proc_holder,proc_name)
|
||||
event += E
|
||||
return E
|
||||
|
||||
// Arguments: event_type as text, any number of additional arguments to pass to event handler
|
||||
// Returns: null
|
||||
proc/fireEvent()
|
||||
//to_world("Events in [args[1]] called")
|
||||
var/list/event = listgetindex(events,args[1])
|
||||
if(istype(event))
|
||||
spawn(-1)
|
||||
for(var/datum/event/E in event)
|
||||
if(!E.Fire(arglist(args.Copy(2))))
|
||||
clearEvent(args[1],E)
|
||||
return
|
||||
|
||||
// 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)
|
||||
if(!event_type || !E)
|
||||
return
|
||||
var/list/event = listgetindex(events,event_type)
|
||||
event -= E
|
||||
/datum/events/proc/addEventType(event_type as text)
|
||||
if(!(event_type in events) || !islist(events[event_type]))
|
||||
events[event_type] = list()
|
||||
return 1
|
||||
return
|
||||
|
||||
|
||||
// Arguments: event_type as text, proc_holder as datum, proc_name as text
|
||||
// Returns: New event, null on error.
|
||||
/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)
|
||||
var/list/event = events[event_type]
|
||||
var/datum/event/E = new /datum/event(proc_holder,proc_name)
|
||||
event += E
|
||||
return E
|
||||
|
||||
// Arguments: event_type as text, any number of additional arguments to pass to event handler
|
||||
// Returns: null
|
||||
/datum/events/proc/fireEvent()
|
||||
//to_world("Events in [args[1]] called")
|
||||
var/list/event = listgetindex(events,args[1])
|
||||
if(istype(event))
|
||||
spawn(-1)
|
||||
for(var/datum/event/E in event)
|
||||
if(!E.Fire(arglist(args.Copy(2))))
|
||||
clearEvent(args[1],E)
|
||||
return
|
||||
|
||||
// Arguments: event_type as text, E as /datum/event
|
||||
// Returns: 1 if event cleared, null on error
|
||||
/datum/events/proc/clearEvent(event_type as text, datum/event/E)
|
||||
if(!event_type || !E)
|
||||
return
|
||||
var/list/event = listgetindex(events,event_type)
|
||||
event -= E
|
||||
return 1
|
||||
|
||||
|
||||
/datum/event
|
||||
var/listener
|
||||
var/proc_name
|
||||
|
||||
New(tlistener,tprocname)
|
||||
listener = tlistener
|
||||
proc_name = tprocname
|
||||
return ..()
|
||||
/datum/event/New(tlistener,tprocname)
|
||||
listener = tlistener
|
||||
proc_name = tprocname
|
||||
return ..()
|
||||
|
||||
proc/Fire()
|
||||
//to_world("Event fired")
|
||||
if(listener)
|
||||
call(listener,proc_name)(arglist(args))
|
||||
return 1
|
||||
return
|
||||
/datum/event/proc/Fire()
|
||||
//to_world("Event fired")
|
||||
if(listener)
|
||||
call(listener,proc_name)(arglist(args))
|
||||
return 1
|
||||
return
|
||||
@@ -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)
|
||||
href = thref
|
||||
href_list = thref_list.Copy()
|
||||
return
|
||||
/datum/topic_input/New(thref,list/thref_list)
|
||||
href = thref
|
||||
href_list = thref_list.Copy()
|
||||
return
|
||||
|
||||
proc/get(i)
|
||||
return listgetindex(href_list,i)
|
||||
/datum/topic_input/proc/get(i)
|
||||
return listgetindex(href_list,i)
|
||||
|
||||
proc/getAndLocate(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = locate(t)
|
||||
return t || null
|
||||
/datum/topic_input/proc/getAndLocate(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = locate(t)
|
||||
return t || null
|
||||
|
||||
proc/getNum(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = text2num(t)
|
||||
return isnum(t) ? t : null
|
||||
/datum/topic_input/proc/getNum(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = text2num(t)
|
||||
return isnum(t) ? t : null
|
||||
|
||||
proc/getObj(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isobj(t) ? t : null
|
||||
/datum/topic_input/proc/getObj(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isobj(t) ? t : null
|
||||
|
||||
proc/getMob(i)
|
||||
var/t = getAndLocate(i)
|
||||
return ismob(t) ? t : null
|
||||
/datum/topic_input/proc/getMob(i)
|
||||
var/t = getAndLocate(i)
|
||||
return ismob(t) ? t : null
|
||||
|
||||
proc/getTurf(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isturf(t) ? t : null
|
||||
/datum/topic_input/proc/getTurf(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isturf(t) ? t : null
|
||||
|
||||
proc/getAtom(i)
|
||||
return getType(i,/atom)
|
||||
/datum/topic_input/proc/getAtom(i)
|
||||
return getType(i,/atom)
|
||||
|
||||
proc/getArea(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isarea(t) ? t : null
|
||||
/datum/topic_input/proc/getArea(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isarea(t) ? t : null
|
||||
|
||||
proc/getStr(i)//params should always be text, but...
|
||||
var/t = get(i)
|
||||
return istext(t) ? t : null
|
||||
/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)
|
||||
var/t = getAndLocate(i)
|
||||
return istype(t,type) ? t : null
|
||||
/datum/topic_input/proc/getType(i,type)
|
||||
var/t = getAndLocate(i)
|
||||
return istype(t,type) ? t : null
|
||||
|
||||
proc/getPath(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = text2path(t)
|
||||
return ispath(t) ? t : null
|
||||
/datum/topic_input/proc/getPath(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = text2path(t)
|
||||
return ispath(t) ? t : null
|
||||
|
||||
proc/getList(i)
|
||||
var/t = getAndLocate(i)
|
||||
return islist(t) ? t : null
|
||||
/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
|
||||
|
||||
/********************************
|
||||
|
||||
+12
-12
@@ -4,16 +4,16 @@
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
return attack_hand(user)
|
||||
/obj/structure/signpost/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
switch(alert("Travel back to ss13?",,"Yes","No"))
|
||||
if("Yes")
|
||||
if(user.z != src.z) return
|
||||
user.forceMove(pick(latejoin))
|
||||
if("No")
|
||||
return
|
||||
/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
|
||||
user.forceMove(pick(latejoin))
|
||||
if("No")
|
||||
return
|
||||
|
||||
/obj/effect/mark
|
||||
var/mark = ""
|
||||
@@ -99,9 +99,9 @@
|
||||
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)
|
||||
user.drop_item()
|
||||
src.throw_at(target, throw_range, throw_speed, user)
|
||||
/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)
|
||||
|
||||
/obj/effect/spawner
|
||||
name = "object spawner"
|
||||
|
||||
+58
-58
@@ -37,69 +37,69 @@ 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)
|
||||
queue = list()
|
||||
comparison_function = compare
|
||||
/PriorityQueue/New(compare)
|
||||
queue = list()
|
||||
comparison_function = compare
|
||||
|
||||
proc/IsEmpty()
|
||||
return !queue.len
|
||||
/PriorityQueue/proc/IsEmpty()
|
||||
return !queue.len
|
||||
|
||||
proc/Enqueue(var/data)
|
||||
queue.Add(data)
|
||||
var/index = queue.len
|
||||
/PriorityQueue/proc/Enqueue(var/data)
|
||||
queue.Add(data)
|
||||
var/index = queue.len
|
||||
|
||||
//From what I can tell, this automagically sorts the added data into the correct location.
|
||||
while(index > 2 && call(comparison_function)(queue[index / 2], queue[index]) > 0)
|
||||
queue.Swap(index, index / 2)
|
||||
index /= 2
|
||||
//From what I can tell, this automagically sorts the added data into the correct location.
|
||||
while(index > 2 && call(comparison_function)(queue[index / 2], queue[index]) > 0)
|
||||
queue.Swap(index, index / 2)
|
||||
index /= 2
|
||||
|
||||
proc/Dequeue()
|
||||
if(!queue.len)
|
||||
return 0
|
||||
return Remove(1)
|
||||
/PriorityQueue/proc/Dequeue()
|
||||
if(!queue.len)
|
||||
return 0
|
||||
return Remove(1)
|
||||
|
||||
proc/Remove(var/index)
|
||||
if(index > queue.len)
|
||||
return 0
|
||||
/PriorityQueue/proc/Remove(var/index)
|
||||
if(index > queue.len)
|
||||
return 0
|
||||
|
||||
var/thing = queue[index]
|
||||
queue.Swap(index, queue.len)
|
||||
queue.Cut(queue.len)
|
||||
if(index < queue.len)
|
||||
FixQueue(index)
|
||||
return thing
|
||||
var/thing = queue[index]
|
||||
queue.Swap(index, queue.len)
|
||||
queue.Cut(queue.len)
|
||||
if(index < queue.len)
|
||||
FixQueue(index)
|
||||
return thing
|
||||
|
||||
proc/FixQueue(var/index)
|
||||
var/child = 2 * index
|
||||
var/item = queue[index]
|
||||
/PriorityQueue/proc/FixQueue(var/index)
|
||||
var/child = 2 * index
|
||||
var/item = queue[index]
|
||||
|
||||
while(child <= queue.len)
|
||||
if(child < queue.len && call(comparison_function)(queue[child], queue[child + 1]) > 0)
|
||||
child++
|
||||
if(call(comparison_function)(item, queue[child]) > 0)
|
||||
queue[index] = queue[child]
|
||||
index = child
|
||||
else
|
||||
break
|
||||
child = 2 * index
|
||||
queue[index] = item
|
||||
while(child <= queue.len)
|
||||
if(child < queue.len && call(comparison_function)(queue[child], queue[child + 1]) > 0)
|
||||
child++
|
||||
if(call(comparison_function)(item, queue[child]) > 0)
|
||||
queue[index] = queue[child]
|
||||
index = child
|
||||
else
|
||||
break
|
||||
child = 2 * index
|
||||
queue[index] = item
|
||||
|
||||
proc/List()
|
||||
return queue.Copy()
|
||||
/PriorityQueue/proc/List()
|
||||
return queue.Copy()
|
||||
|
||||
proc/Length()
|
||||
return queue.len
|
||||
/PriorityQueue/proc/Length()
|
||||
return queue.len
|
||||
|
||||
proc/RemoveItem(data)
|
||||
var/index = queue.Find(data)
|
||||
if(index)
|
||||
return Remove(index)
|
||||
/PriorityQueue/proc/RemoveItem(data)
|
||||
var/index = queue.Find(data)
|
||||
if(index)
|
||||
return Remove(index)
|
||||
|
||||
PathNode
|
||||
/PathNode
|
||||
var/datum/position
|
||||
var/PathNode/previous_node
|
||||
|
||||
@@ -109,21 +109,21 @@ PathNode
|
||||
var/cost
|
||||
var/nodes_traversed
|
||||
|
||||
New(_position, _previous_node, _known_cost, _cost, _nodes_traversed)
|
||||
position = _position
|
||||
previous_node = _previous_node
|
||||
/PathNode/New(_position, _previous_node, _known_cost, _cost, _nodes_traversed)
|
||||
position = _position
|
||||
previous_node = _previous_node
|
||||
|
||||
known_cost = _known_cost
|
||||
cost = _cost
|
||||
estimated_cost = cost + known_cost
|
||||
known_cost = _known_cost
|
||||
cost = _cost
|
||||
estimated_cost = cost + known_cost
|
||||
|
||||
best_estimated_cost = estimated_cost
|
||||
nodes_traversed = _nodes_traversed
|
||||
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,29 +1473,29 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
dynamic_lighting = 0
|
||||
ambience = AMBIENCE_SPACE
|
||||
|
||||
auxport
|
||||
name = "\improper Fore Port Solar Array"
|
||||
icon_state = "panelsA"
|
||||
/area/solar/auxport
|
||||
name = "\improper Fore Port Solar Array"
|
||||
icon_state = "panelsA"
|
||||
|
||||
auxstarboard
|
||||
name = "\improper Fore Starboard Solar Array"
|
||||
icon_state = "panelsA"
|
||||
/area/solar/auxstarboard
|
||||
name = "\improper Fore Starboard Solar Array"
|
||||
icon_state = "panelsA"
|
||||
|
||||
fore
|
||||
name = "\improper Fore Solar Array"
|
||||
icon_state = "yellow"
|
||||
/area/solar/fore
|
||||
name = "\improper Fore Solar Array"
|
||||
icon_state = "yellow"
|
||||
|
||||
aft
|
||||
name = "\improper Aft Solar Array"
|
||||
icon_state = "aft"
|
||||
/area/solar/aft
|
||||
name = "\improper Aft Solar Array"
|
||||
icon_state = "aft"
|
||||
|
||||
starboard
|
||||
name = "\improper Aft Starboard Solar Array"
|
||||
icon_state = "panelsS"
|
||||
/area/solar/starboard
|
||||
name = "\improper Aft Starboard Solar Array"
|
||||
icon_state = "panelsS"
|
||||
|
||||
port
|
||||
name = "\improper Aft Port Solar Array"
|
||||
icon_state = "panelsP"
|
||||
/area/solar/port
|
||||
name = "\improper Aft Port Solar Array"
|
||||
icon_state = "panelsP"
|
||||
|
||||
/area/maintenance/auxsolarport
|
||||
name = "Solar Maintenance - Fore Port"
|
||||
|
||||
@@ -129,9 +129,9 @@
|
||||
always_unpowered = 1
|
||||
dynamic_lighting = 0
|
||||
|
||||
aft
|
||||
name = "\improper Engineering Outpost Solar Array"
|
||||
icon_state = "yellow"
|
||||
/area/outpost/engineering/solarsoutside/aft
|
||||
name = "\improper Engineering Outpost Solar Array"
|
||||
icon_state = "yellow"
|
||||
|
||||
// Engineering Mining Outpost
|
||||
/area/outpost/engineering/mining
|
||||
|
||||
+15
-2
@@ -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,73 +57,73 @@
|
||||
activation_message="Your mind says 'Hello'."
|
||||
mutation=mHallucination
|
||||
|
||||
New()
|
||||
block=HALLUCINATIONBLOCK
|
||||
/datum/dna/gene/disability/hallucinate/New()
|
||||
block=HALLUCINATIONBLOCK
|
||||
|
||||
/datum/dna/gene/disability/epilepsy
|
||||
name="Epilepsy"
|
||||
activation_message="You get a headache."
|
||||
disability=EPILEPSY
|
||||
|
||||
New()
|
||||
block=HEADACHEBLOCK
|
||||
/datum/dna/gene/disability/epilepsy/New()
|
||||
block=HEADACHEBLOCK
|
||||
|
||||
/datum/dna/gene/disability/cough
|
||||
name="Coughing"
|
||||
activation_message="You start coughing."
|
||||
disability=COUGHING
|
||||
|
||||
New()
|
||||
block=COUGHBLOCK
|
||||
/datum/dna/gene/disability/cough/New()
|
||||
block=COUGHBLOCK
|
||||
|
||||
/datum/dna/gene/disability/clumsy
|
||||
name="Clumsiness"
|
||||
activation_message="You feel lightheaded."
|
||||
mutation=CLUMSY
|
||||
|
||||
New()
|
||||
block=CLUMSYBLOCK
|
||||
/datum/dna/gene/disability/clumsy/New()
|
||||
block=CLUMSYBLOCK
|
||||
|
||||
/datum/dna/gene/disability/tourettes
|
||||
name="Tourettes"
|
||||
activation_message="You twitch."
|
||||
disability=TOURETTES
|
||||
|
||||
New()
|
||||
block=TWITCHBLOCK
|
||||
/datum/dna/gene/disability/tourettes/New()
|
||||
block=TWITCHBLOCK
|
||||
|
||||
/datum/dna/gene/disability/nervousness
|
||||
name="Nervousness"
|
||||
activation_message="You feel nervous."
|
||||
disability=NERVOUS
|
||||
|
||||
New()
|
||||
block=NERVOUSBLOCK
|
||||
/datum/dna/gene/disability/nervousness/New()
|
||||
block=NERVOUSBLOCK
|
||||
|
||||
/datum/dna/gene/disability/blindness
|
||||
name="Blindness"
|
||||
activation_message="You can't seem to see anything."
|
||||
sdisability=BLIND
|
||||
|
||||
New()
|
||||
block=BLINDBLOCK
|
||||
/datum/dna/gene/disability/blindness/New()
|
||||
block=BLINDBLOCK
|
||||
|
||||
/datum/dna/gene/disability/deaf
|
||||
name="Deafness"
|
||||
activation_message="It's kinda quiet."
|
||||
sdisability=DEAF
|
||||
|
||||
New()
|
||||
block=DEAFBLOCK
|
||||
/datum/dna/gene/disability/deaf/New()
|
||||
block=DEAFBLOCK
|
||||
|
||||
activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.ear_deaf = 1
|
||||
/datum/dna/gene/disability/deaf/activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.ear_deaf = 1
|
||||
|
||||
/datum/dna/gene/disability/nearsighted
|
||||
name="Nearsightedness"
|
||||
activation_message="Your eyes feel weird..."
|
||||
disability=NEARSIGHTED
|
||||
|
||||
New()
|
||||
block=GLASSESBLOCK
|
||||
/datum/dna/gene/disability/nearsighted/New()
|
||||
block=GLASSESBLOCK
|
||||
|
||||
+74
-101
@@ -7,180 +7,153 @@
|
||||
activation_messages=list("You feel no need to breathe.")
|
||||
mutation=mNobreath
|
||||
|
||||
New()
|
||||
block=NOBREATHBLOCK
|
||||
/datum/dna/gene/basic/nobreath/New()
|
||||
block=NOBREATHBLOCK
|
||||
|
||||
/datum/dna/gene/basic/remoteview
|
||||
name="Remote Viewing"
|
||||
activation_messages=list("Your mind expands.")
|
||||
mutation=mRemote
|
||||
|
||||
New()
|
||||
block=REMOTEVIEWBLOCK
|
||||
/datum/dna/gene/basic/remoteview/New()
|
||||
block=REMOTEVIEWBLOCK
|
||||
|
||||
activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.verbs += /mob/living/carbon/human/proc/remoteobserve
|
||||
/datum/dna/gene/basic/remoteview/activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.verbs += /mob/living/carbon/human/proc/remoteobserve
|
||||
|
||||
/datum/dna/gene/basic/regenerate
|
||||
name="Regenerate"
|
||||
activation_messages=list("You feel better.")
|
||||
mutation=mRegen
|
||||
|
||||
New()
|
||||
block=REGENERATEBLOCK
|
||||
/datum/dna/gene/basic/regenerate/New()
|
||||
block=REGENERATEBLOCK
|
||||
|
||||
/datum/dna/gene/basic/increaserun
|
||||
name="Super Speed"
|
||||
activation_messages=list("Your leg muscles pulsate.")
|
||||
mutation=mRun
|
||||
|
||||
New()
|
||||
block=INCREASERUNBLOCK
|
||||
/datum/dna/gene/basic/increaserun/New()
|
||||
block=INCREASERUNBLOCK
|
||||
|
||||
/datum/dna/gene/basic/remotetalk
|
||||
name="Telepathy"
|
||||
activation_messages=list("You expand your mind outwards.")
|
||||
mutation=mRemotetalk
|
||||
|
||||
New()
|
||||
block=REMOTETALKBLOCK
|
||||
/datum/dna/gene/basic/remotetalk/New()
|
||||
block=REMOTETALKBLOCK
|
||||
|
||||
activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.verbs += /mob/living/carbon/human/proc/remotesay
|
||||
/datum/dna/gene/basic/remotetalk/activate(var/mob/M, var/connected, var/flags)
|
||||
..(M,connected,flags)
|
||||
M.verbs += /mob/living/carbon/human/proc/remotesay
|
||||
|
||||
/datum/dna/gene/basic/morph
|
||||
name="Morph"
|
||||
activation_messages=list("Your skin feels strange.")
|
||||
mutation=mMorph
|
||||
|
||||
New()
|
||||
block=MORPHBLOCK
|
||||
/datum/dna/gene/basic/morph/New()
|
||||
block=MORPHBLOCK
|
||||
|
||||
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/morph/activate(var/mob/M)
|
||||
..(M)
|
||||
M.verbs += /mob/living/carbon/human/proc/morph
|
||||
|
||||
/datum/dna/gene/basic/cold_resist
|
||||
name="Cold Resistance"
|
||||
activation_messages=list("Your body is filled with warmth.")
|
||||
mutation=COLD_RESISTANCE
|
||||
|
||||
New()
|
||||
block=FIREBLOCK
|
||||
/datum/dna/gene/basic/cold_resist/New()
|
||||
block=FIREBLOCK
|
||||
|
||||
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
|
||||
/datum/dna/gene/basic/cold_resist/can_activate(var/mob/M,var/flags)
|
||||
if(flags & MUTCHK_FORCED)
|
||||
return 1
|
||||
var/_prob=30
|
||||
if(probinj(_prob,(flags&MUTCHK_FORCED)))
|
||||
return 1
|
||||
|
||||
OnDrawUnderlays(var/mob/M,var/g,var/fat)
|
||||
return "fire[fat]_s"
|
||||
/datum/dna/gene/basic/cold_resist/OnDrawUnderlays(var/mob/M,var/g,var/fat)
|
||||
return "fire[fat]_s"
|
||||
|
||||
/datum/dna/gene/basic/noprints
|
||||
name="No Prints"
|
||||
activation_messages=list("Your fingers feel numb.")
|
||||
mutation=mFingerprints
|
||||
|
||||
New()
|
||||
block=NOPRINTSBLOCK
|
||||
/datum/dna/gene/basic/noprints/New()
|
||||
block=NOPRINTSBLOCK
|
||||
|
||||
/datum/dna/gene/basic/noshock
|
||||
name="Shock Immunity"
|
||||
activation_messages=list("Your skin feels strange.")
|
||||
mutation=mShock
|
||||
|
||||
New()
|
||||
block=SHOCKIMMUNITYBLOCK
|
||||
/datum/dna/gene/basic/noshock/New()
|
||||
block=SHOCKIMMUNITYBLOCK
|
||||
|
||||
/datum/dna/gene/basic/midget
|
||||
name="Midget"
|
||||
activation_messages=list("Your skin feels rubbery.")
|
||||
mutation=mSmallsize
|
||||
|
||||
New()
|
||||
block=SMALLSIZEBLOCK
|
||||
/datum/dna/gene/basic/midget/New()
|
||||
block=SMALLSIZEBLOCK
|
||||
|
||||
can_activate(var/mob/M,var/flags)
|
||||
// Can't be big and small.
|
||||
if(HULK in M.mutations)
|
||||
return 0
|
||||
return ..(M,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)
|
||||
..(M,connected,flags)
|
||||
M.pass_flags |= 1
|
||||
/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)
|
||||
..(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
|
||||
/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
|
||||
|
||||
/datum/dna/gene/basic/hulk
|
||||
name="Hulk"
|
||||
activation_messages=list("Your muscles hurt.")
|
||||
mutation=HULK
|
||||
|
||||
New()
|
||||
block=HULKBLOCK
|
||||
/datum/dna/gene/basic/hulk/New()
|
||||
block=HULKBLOCK
|
||||
|
||||
can_activate(var/mob/M,var/flags)
|
||||
// Can't be big and small.
|
||||
if(mSmallsize in M.mutations)
|
||||
return 0
|
||||
return ..(M,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)
|
||||
if(fat)
|
||||
return "hulk_[fat]_s"
|
||||
else
|
||||
return "hulk_[g]_s"
|
||||
/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)
|
||||
if(!istype(M)) return
|
||||
if(M.health <= 25)
|
||||
M.mutations.Remove(HULK)
|
||||
M.update_mutations() //update our mutation overlays
|
||||
to_chat(M, "<span class='warning'>You suddenly feel very weak.</span>")
|
||||
M.Weaken(3)
|
||||
M.emote("collapse")
|
||||
/datum/dna/gene/basic/hulk/OnMobLife(var/mob/living/carbon/human/M)
|
||||
if(!istype(M)) return
|
||||
if(M.health <= 25)
|
||||
M.mutations.Remove(HULK)
|
||||
M.update_mutations() //update our mutation overlays
|
||||
to_chat(M, "<span class='warning'>You suddenly feel very weak.</span>")
|
||||
M.Weaken(3)
|
||||
M.emote("collapse")
|
||||
|
||||
/datum/dna/gene/basic/xray
|
||||
name="X-Ray Vision"
|
||||
activation_messages=list("The walls suddenly disappear.")
|
||||
mutation=XRAY
|
||||
|
||||
New()
|
||||
block=XRAYBLOCK
|
||||
/datum/dna/gene/basic/xray/New()
|
||||
block=XRAYBLOCK
|
||||
|
||||
/datum/dna/gene/basic/tk
|
||||
name="Telekenesis"
|
||||
@@ -188,7 +161,7 @@
|
||||
mutation=TK
|
||||
activation_prob=15
|
||||
|
||||
New()
|
||||
block=TELEBLOCK
|
||||
OnDrawUnderlays(var/mob/M,var/g,var/fat)
|
||||
return "telekinesishead[fat]_s"
|
||||
/datum/dna/gene/basic/tk/New()
|
||||
block=TELEBLOCK
|
||||
/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)
|
||||
|
||||
+402
-403
@@ -65,117 +65,116 @@ 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()
|
||||
..()
|
||||
blood_image = image(loc = src)
|
||||
blood_image.override = 1
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
if(AI.client)
|
||||
AI.client.images += blood_image
|
||||
rune_list.Add(src)
|
||||
/obj/effect/rune/Initialize()
|
||||
. = ..()
|
||||
blood_image = image(loc = src)
|
||||
blood_image.override = 1
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
if(AI.client)
|
||||
AI.client.images += blood_image
|
||||
rune_list.Add(src)
|
||||
|
||||
Destroy()
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
if(AI.client)
|
||||
AI.client.images -= blood_image
|
||||
qdel(blood_image)
|
||||
blood_image = null
|
||||
rune_list.Remove(src)
|
||||
..()
|
||||
/obj/effect/rune/Destroy()
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
if(AI.client)
|
||||
AI.client.images -= blood_image
|
||||
qdel(blood_image)
|
||||
blood_image = null
|
||||
rune_list.Remove(src)
|
||||
..()
|
||||
|
||||
examine(mob/user)
|
||||
. = ..()
|
||||
if(iscultist(user))
|
||||
. += "This spell circle reads: <i>[word1] [word2] [word3]</i>."
|
||||
/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)
|
||||
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)
|
||||
return
|
||||
else if(istype(I, /obj/item/weapon/nullrod))
|
||||
to_chat(user, "<span class='notice'>You disrupt the vile magic with the deadening field of the null rod!</span>")
|
||||
qdel(src)
|
||||
return
|
||||
/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)
|
||||
return
|
||||
else if(istype(I, /obj/item/weapon/nullrod))
|
||||
to_chat(user, "<span class='notice'>You disrupt the vile magic with the deadening field of the null rod!</span>")
|
||||
qdel(src)
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
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
|
||||
if(user.is_muzzled())
|
||||
to_chat(user, "You are unable to speak the words of the rune.")
|
||||
return
|
||||
if(!word1 || !word2 || !word3 || prob(user.getBrainLoss()))
|
||||
return fizzle()
|
||||
/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
|
||||
if(user.is_muzzled())
|
||||
to_chat(user, "You are unable to speak the words of the rune.")
|
||||
return
|
||||
if(!word1 || !word2 || !word3 || prob(user.getBrainLoss()))
|
||||
return fizzle()
|
||||
// if(!src.visibility)
|
||||
// src.visibility=1
|
||||
if(word1 == cultwords["travel"] && word2 == cultwords["self"])
|
||||
return teleport(src.word3)
|
||||
if(word1 == cultwords["see"] && word2 == cultwords["blood"] && word3 == cultwords["hell"])
|
||||
return tomesummon()
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["destroy"] && word3 == cultwords["other"])
|
||||
return armor()
|
||||
if(word1 == cultwords["join"] && word2 == cultwords["blood"] && word3 == cultwords["self"])
|
||||
return convert()
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["join"] && word3 == cultwords["self"])
|
||||
return tearreality()
|
||||
if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["technology"])
|
||||
return emp(src.loc,5)
|
||||
if(word1 == cultwords["travel"] && word2 == cultwords["blood"] && word3 == cultwords["self"])
|
||||
return drain()
|
||||
if(word1 == cultwords["see"] && word2 == cultwords["hell"] && word3 == cultwords["join"])
|
||||
return seer()
|
||||
if(word1 == cultwords["blood"] && word2 == cultwords["join"] && word3 == cultwords["hell"])
|
||||
return raise()
|
||||
if(word1 == cultwords["hide"] && word2 == cultwords["see"] && word3 == cultwords["blood"])
|
||||
return obscure(4)
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["travel"] && word3 == cultwords["self"])
|
||||
return ajourney()
|
||||
if(word1 == cultwords["blood"] && word2 == cultwords["see"] && word3 == cultwords["travel"])
|
||||
return manifest()
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["technology"] && word3 == cultwords["join"])
|
||||
return talisman()
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["blood"] && word3 == cultwords["join"])
|
||||
return sacrifice()
|
||||
if(word1 == cultwords["blood"] && word2 == cultwords["see"] && word3 == cultwords["hide"])
|
||||
return revealrunes(src)
|
||||
if(word1 == cultwords["destroy"] && word2 == cultwords["travel"] && word3 == cultwords["self"])
|
||||
return wall()
|
||||
if(word1 == cultwords["travel"] && word2 == cultwords["technology"] && word3 == cultwords["other"])
|
||||
return freedom()
|
||||
if(word1 == cultwords["join"] && word2 == cultwords["other"] && word3 == cultwords["self"])
|
||||
return cultsummon()
|
||||
if(word1 == cultwords["hide"] && word2 == cultwords["other"] && word3 == cultwords["see"])
|
||||
return deafen()
|
||||
if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["other"])
|
||||
return blind()
|
||||
if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["blood"])
|
||||
return bloodboil()
|
||||
if(word1 == cultwords["self"] && word2 == cultwords["other"] && word3 == cultwords["technology"])
|
||||
return communicate()
|
||||
if(word1 == cultwords["travel"] && word2 == cultwords["other"])
|
||||
return itemport(src.word3)
|
||||
if(word1 == cultwords["join"] && word2 == cultwords["hide"] && word3 == cultwords["technology"])
|
||||
return runestun()
|
||||
else
|
||||
return fizzle()
|
||||
if(word1 == cultwords["travel"] && word2 == cultwords["self"])
|
||||
return teleport(src.word3)
|
||||
if(word1 == cultwords["see"] && word2 == cultwords["blood"] && word3 == cultwords["hell"])
|
||||
return tomesummon()
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["destroy"] && word3 == cultwords["other"])
|
||||
return armor()
|
||||
if(word1 == cultwords["join"] && word2 == cultwords["blood"] && word3 == cultwords["self"])
|
||||
return convert()
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["join"] && word3 == cultwords["self"])
|
||||
return tearreality()
|
||||
if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["technology"])
|
||||
return emp(src.loc,5)
|
||||
if(word1 == cultwords["travel"] && word2 == cultwords["blood"] && word3 == cultwords["self"])
|
||||
return drain()
|
||||
if(word1 == cultwords["see"] && word2 == cultwords["hell"] && word3 == cultwords["join"])
|
||||
return seer()
|
||||
if(word1 == cultwords["blood"] && word2 == cultwords["join"] && word3 == cultwords["hell"])
|
||||
return raise()
|
||||
if(word1 == cultwords["hide"] && word2 == cultwords["see"] && word3 == cultwords["blood"])
|
||||
return obscure(4)
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["travel"] && word3 == cultwords["self"])
|
||||
return ajourney()
|
||||
if(word1 == cultwords["blood"] && word2 == cultwords["see"] && word3 == cultwords["travel"])
|
||||
return manifest()
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["technology"] && word3 == cultwords["join"])
|
||||
return talisman()
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["blood"] && word3 == cultwords["join"])
|
||||
return sacrifice()
|
||||
if(word1 == cultwords["blood"] && word2 == cultwords["see"] && word3 == cultwords["hide"])
|
||||
return revealrunes(src)
|
||||
if(word1 == cultwords["destroy"] && word2 == cultwords["travel"] && word3 == cultwords["self"])
|
||||
return wall()
|
||||
if(word1 == cultwords["travel"] && word2 == cultwords["technology"] && word3 == cultwords["other"])
|
||||
return freedom()
|
||||
if(word1 == cultwords["join"] && word2 == cultwords["other"] && word3 == cultwords["self"])
|
||||
return cultsummon()
|
||||
if(word1 == cultwords["hide"] && word2 == cultwords["other"] && word3 == cultwords["see"])
|
||||
return deafen()
|
||||
if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["other"])
|
||||
return blind()
|
||||
if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["blood"])
|
||||
return bloodboil()
|
||||
if(word1 == cultwords["self"] && word2 == cultwords["other"] && word3 == cultwords["technology"])
|
||||
return communicate()
|
||||
if(word1 == cultwords["travel"] && word2 == cultwords["other"])
|
||||
return itemport(src.word3)
|
||||
if(word1 == cultwords["join"] && word2 == cultwords["hide"] && word3 == cultwords["technology"])
|
||||
return runestun()
|
||||
else
|
||||
return fizzle()
|
||||
|
||||
|
||||
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
|
||||
usr.whisper(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix."))
|
||||
for (var/mob/V in viewers(src))
|
||||
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
|
||||
/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
|
||||
usr.whisper(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix."))
|
||||
for (var/mob/V in viewers(src))
|
||||
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()
|
||||
icon = get_uristrune_cult(word1, word2, word3)
|
||||
/obj/effect/rune/proc/check_icon()
|
||||
icon = get_uristrune_cult(word1, word2, word3)
|
||||
|
||||
/obj/item/weapon/book/tome
|
||||
name = "arcane tome"
|
||||
@@ -289,149 +288,149 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
</html>
|
||||
"}
|
||||
|
||||
New()
|
||||
..()
|
||||
if(!cultwords["travel"])
|
||||
runerandom()
|
||||
for(var/V in cultwords)
|
||||
words[cultwords[V]] = V
|
||||
/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)
|
||||
add_attack_logs(user,M,"Hit with [name]")
|
||||
/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))
|
||||
var/mob/observer/dead/D = M
|
||||
D.manifest(user)
|
||||
return
|
||||
if(!istype(M))
|
||||
return
|
||||
if(!iscultist(user))
|
||||
return ..()
|
||||
if(iscultist(M))
|
||||
return
|
||||
M.take_organ_damage(0,rand(5,20)) //really lucky - 5 hits for a crit
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message("<span class='warning'>\The [user] beats \the [M] with \the [src]!</span>", 1)
|
||||
to_chat(M, "<span class='danger'>You feel searing heat inside!</span>")
|
||||
if(istype(M,/mob/observer/dead))
|
||||
var/mob/observer/dead/D = M
|
||||
D.manifest(user)
|
||||
return
|
||||
if(!istype(M))
|
||||
return
|
||||
if(!iscultist(user))
|
||||
return ..()
|
||||
if(iscultist(M))
|
||||
return
|
||||
M.take_organ_damage(0,rand(5,20)) //really lucky - 5 hits for a crit
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message("<span class='warning'>\The [user] beats \the [M] with \the [src]!</span>", 1)
|
||||
to_chat(M, "<span class='danger'>You feel searing heat inside!</span>")
|
||||
|
||||
|
||||
attack_self(mob/living/user as mob)
|
||||
usr = user
|
||||
if(!usr.canmove || usr.stat || usr.restrained())
|
||||
/obj/item/weapon/book/tome/attack_self(mob/living/user as mob)
|
||||
usr = user
|
||||
if(!usr.canmove || usr.stat || usr.restrained())
|
||||
return
|
||||
|
||||
if(!cultwords["travel"])
|
||||
runerandom()
|
||||
if(iscultist(user))
|
||||
var/C = 0
|
||||
for(var/obj/effect/rune/N in rune_list)
|
||||
C++
|
||||
if (!istype(user.loc,/turf))
|
||||
to_chat(user, "<span class='warning'>You do not have enough space to write a proper rune.</span>")
|
||||
return
|
||||
|
||||
if(!cultwords["travel"])
|
||||
runerandom()
|
||||
if(iscultist(user))
|
||||
var/C = 0
|
||||
for(var/obj/effect/rune/N in rune_list)
|
||||
C++
|
||||
if (!istype(user.loc,/turf))
|
||||
to_chat(user, "<span class='warning'>You do not have enough space to write a proper rune.</span>")
|
||||
return
|
||||
|
||||
if (C>=26 + runedec + cult.current_antagonists.len) //including the useless rune at the secret room, shouldn't count against the limit of 25 runes - Urist
|
||||
alert("The cloth of reality can't take that much of a strain. Remove some runes first!")
|
||||
return
|
||||
else
|
||||
switch(alert("You open the tome",,"Read it","Scribe a rune", "Cancel"))
|
||||
if("Cancel")
|
||||
return
|
||||
if("Read it")
|
||||
if(usr.get_active_hand() != src)
|
||||
return
|
||||
user << browse("[tomedat]", "window=Arcane Tome")
|
||||
return
|
||||
if(usr.get_active_hand() != src)
|
||||
return
|
||||
|
||||
var/list/dictionary = list (
|
||||
"convert" = list("join","blood","self"),
|
||||
"wall" = list("destroy","travel","self"),
|
||||
"blood boil" = list("destroy","see","blood"),
|
||||
"blood drain" = list("travel","blood","self"),
|
||||
"raise dead" = list("blood","join","hell"),
|
||||
"summon narsie" = list("hell","join","self"),
|
||||
"communicate" = list("self","other","technology"),
|
||||
"emp" = list("destroy","see","technology"),
|
||||
"manifest" = list("blood","see","travel"),
|
||||
"summon tome" = list("see","blood","hell"),
|
||||
"see invisible" = list("see","hell","join"),
|
||||
"hide" = list("hide","see","blood"),
|
||||
"reveal" = list("blood","see","hide"),
|
||||
"astral journey" = list("hell","travel","self"),
|
||||
"imbue" = list("hell","technology","join"),
|
||||
"sacrifice" = list("hell","blood","join"),
|
||||
"summon cultist" = list("join","other","self"),
|
||||
"free cultist" = list("travel","technology","other"),
|
||||
"deafen" = list("hide","other","see"),
|
||||
"blind" = list("destroy","see","other"),
|
||||
"stun" = list("join","hide","technology"),
|
||||
"armor" = list("hell","destroy","other"),
|
||||
"teleport" = list("travel","self"),
|
||||
"teleport other" = list("travel","other")
|
||||
)
|
||||
|
||||
var/list/english = list()
|
||||
|
||||
var/list/scribewords = list("none")
|
||||
|
||||
for (var/entry in words)
|
||||
if (words[entry] != entry)
|
||||
english += list(words[entry] = entry)
|
||||
|
||||
for (var/entry in dictionary)
|
||||
var/list/required = dictionary[entry]
|
||||
if (length(english&required) == required.len)
|
||||
scribewords += entry
|
||||
|
||||
var/chosen_rune = null
|
||||
|
||||
if(usr)
|
||||
chosen_rune = input ("Choose a rune to scribe.") in scribewords
|
||||
if (!chosen_rune)
|
||||
return
|
||||
if (chosen_rune == "none")
|
||||
to_chat(user, "<span class='notice'>You decide against scribing a rune, perhaps you should take this time to study your notes.</span>")
|
||||
return
|
||||
if (chosen_rune == "teleport")
|
||||
dictionary[chosen_rune] += input ("Choose a destination word") in english
|
||||
if (chosen_rune == "teleport other")
|
||||
dictionary[chosen_rune] += input ("Choose a destination word") in english
|
||||
|
||||
if(usr.get_active_hand() != src)
|
||||
return
|
||||
|
||||
for (var/mob/V in viewers(src))
|
||||
V.show_message("<span class='danger'>\The [user] slices open a finger and begins to chant and paint symbols on the floor.</span>", 3, "<span class='danger'>You hear chanting.</span>", 2)
|
||||
to_chat(user, "<span class='danger'>You slice open one of your fingers and begin drawing a rune on the floor whilst chanting the ritual that binds your life essence with the dark arcane energies flowing through the surrounding world.</span>")
|
||||
user.take_overall_damage((rand(9)+1)/10) // 0.1 to 1.0 damage
|
||||
if(do_after(user, 50))
|
||||
var/area/A = get_area(user)
|
||||
log_and_message_admins("created \an [chosen_rune] rune at \the [A.name] - [user.loc.x]-[user.loc.y]-[user.loc.z].")
|
||||
if(usr.get_active_hand() != src)
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/effect/rune/R = new /obj/effect/rune(user.loc)
|
||||
to_chat(user, "<span class='notice'>You finish drawing the arcane markings of the Geometer.</span>")
|
||||
var/list/required = dictionary[chosen_rune]
|
||||
R.word1 = english[required[1]]
|
||||
R.word2 = english[required[2]]
|
||||
R.word3 = english[required[3]]
|
||||
R.check_icon()
|
||||
R.blood_DNA = list()
|
||||
R.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
|
||||
if (C>=26 + runedec + cult.current_antagonists.len) //including the useless rune at the secret room, shouldn't count against the limit of 25 runes - Urist
|
||||
alert("The cloth of reality can't take that much of a strain. Remove some runes first!")
|
||||
return
|
||||
else
|
||||
to_chat(user, "The book seems full of illegible scribbles. Is this a joke?")
|
||||
switch(alert("You open the tome",,"Read it","Scribe a rune", "Cancel"))
|
||||
if("Cancel")
|
||||
return
|
||||
if("Read it")
|
||||
if(usr.get_active_hand() != src)
|
||||
return
|
||||
user << browse("[tomedat]", "window=Arcane Tome")
|
||||
return
|
||||
if(usr.get_active_hand() != src)
|
||||
return
|
||||
|
||||
examine(mob/user)
|
||||
. = ..()
|
||||
if(!iscultist(user))
|
||||
. += "An old, dusty tome with frayed edges and a sinister looking cover."
|
||||
else
|
||||
. += "The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood. Contains the details of every ritual his followers could think of. Most of these are useless, though."
|
||||
var/list/dictionary = list (
|
||||
"convert" = list("join","blood","self"),
|
||||
"wall" = list("destroy","travel","self"),
|
||||
"blood boil" = list("destroy","see","blood"),
|
||||
"blood drain" = list("travel","blood","self"),
|
||||
"raise dead" = list("blood","join","hell"),
|
||||
"summon narsie" = list("hell","join","self"),
|
||||
"communicate" = list("self","other","technology"),
|
||||
"emp" = list("destroy","see","technology"),
|
||||
"manifest" = list("blood","see","travel"),
|
||||
"summon tome" = list("see","blood","hell"),
|
||||
"see invisible" = list("see","hell","join"),
|
||||
"hide" = list("hide","see","blood"),
|
||||
"reveal" = list("blood","see","hide"),
|
||||
"astral journey" = list("hell","travel","self"),
|
||||
"imbue" = list("hell","technology","join"),
|
||||
"sacrifice" = list("hell","blood","join"),
|
||||
"summon cultist" = list("join","other","self"),
|
||||
"free cultist" = list("travel","technology","other"),
|
||||
"deafen" = list("hide","other","see"),
|
||||
"blind" = list("destroy","see","other"),
|
||||
"stun" = list("join","hide","technology"),
|
||||
"armor" = list("hell","destroy","other"),
|
||||
"teleport" = list("travel","self"),
|
||||
"teleport other" = list("travel","other")
|
||||
)
|
||||
|
||||
var/list/english = list()
|
||||
|
||||
var/list/scribewords = list("none")
|
||||
|
||||
for (var/entry in words)
|
||||
if (words[entry] != entry)
|
||||
english += list(words[entry] = entry)
|
||||
|
||||
for (var/entry in dictionary)
|
||||
var/list/required = dictionary[entry]
|
||||
if (length(english&required) == required.len)
|
||||
scribewords += entry
|
||||
|
||||
var/chosen_rune = null
|
||||
|
||||
if(usr)
|
||||
chosen_rune = input ("Choose a rune to scribe.") in scribewords
|
||||
if (!chosen_rune)
|
||||
return
|
||||
if (chosen_rune == "none")
|
||||
to_chat(user, "<span class='notice'>You decide against scribing a rune, perhaps you should take this time to study your notes.</span>")
|
||||
return
|
||||
if (chosen_rune == "teleport")
|
||||
dictionary[chosen_rune] += input ("Choose a destination word") in english
|
||||
if (chosen_rune == "teleport other")
|
||||
dictionary[chosen_rune] += input ("Choose a destination word") in english
|
||||
|
||||
if(usr.get_active_hand() != src)
|
||||
return
|
||||
|
||||
for (var/mob/V in viewers(src))
|
||||
V.show_message("<span class='danger'>\The [user] slices open a finger and begins to chant and paint symbols on the floor.</span>", 3, "<span class='danger'>You hear chanting.</span>", 2)
|
||||
to_chat(user, "<span class='danger'>You slice open one of your fingers and begin drawing a rune on the floor whilst chanting the ritual that binds your life essence with the dark arcane energies flowing through the surrounding world.</span>")
|
||||
user.take_overall_damage((rand(9)+1)/10) // 0.1 to 1.0 damage
|
||||
if(do_after(user, 50))
|
||||
var/area/A = get_area(user)
|
||||
log_and_message_admins("created \an [chosen_rune] rune at \the [A.name] - [user.loc.x]-[user.loc.y]-[user.loc.z].")
|
||||
if(usr.get_active_hand() != src)
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/effect/rune/R = new /obj/effect/rune(user.loc)
|
||||
to_chat(user, "<span class='notice'>You finish drawing the arcane markings of the Geometer.</span>")
|
||||
var/list/required = dictionary[chosen_rune]
|
||||
R.word1 = english[required[1]]
|
||||
R.word2 = english[required[2]]
|
||||
R.word3 = english[required[3]]
|
||||
R.check_icon()
|
||||
R.blood_DNA = list()
|
||||
R.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
|
||||
return
|
||||
else
|
||||
to_chat(user, "The book seems full of illegible scribbles. Is this a joke?")
|
||||
return
|
||||
|
||||
/obj/item/weapon/book/tome/examine(mob/user)
|
||||
. = ..()
|
||||
if(!iscultist(user))
|
||||
. += "An old, dusty tome with frayed edges and a sinister looking cover."
|
||||
else
|
||||
. += "The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood. Contains the details of every ritual his followers could think of. Most of these are useless, though."
|
||||
|
||||
/obj/item/weapon/book/tome/cultify()
|
||||
return
|
||||
@@ -439,174 +438,174 @@ 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)
|
||||
if(src.cultistsonly && !iscultist(usr))
|
||||
return
|
||||
if(!cultwords["travel"])
|
||||
runerandom()
|
||||
if(user)
|
||||
var/r
|
||||
if (!istype(user.loc,/turf))
|
||||
to_chat(user, "<span class='notice'>You do not have enough space to write a proper rune.</span>")
|
||||
var/list/runes = list("teleport", "itemport", "tome", "armor", "convert", "tear in reality", "emp", "drain", "seer", "raise", "obscure", "reveal", "astral journey", "manifest", "imbue talisman", "sacrifice", "wall", "freedom", "cultsummon", "deafen", "blind", "bloodboil", "communicate", "stun")
|
||||
r = input("Choose a rune to scribe", "Rune Scribing") in runes //not cancellable.
|
||||
var/obj/effect/rune/R = new /obj/effect/rune
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
R.blood_DNA = list()
|
||||
R.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
|
||||
var/area/A = get_area(user)
|
||||
log_and_message_admins("created \an [r] rune at \the [A.name] - [user.loc.x]-[user.loc.y]-[user.loc.z].")
|
||||
switch(r)
|
||||
if("teleport")
|
||||
var/list/words = list("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri")
|
||||
var/beacon
|
||||
if(usr)
|
||||
beacon = input("Select the last rune", "Rune Scribing") in words
|
||||
R.word1=cultwords["travel"]
|
||||
R.word2=cultwords["self"]
|
||||
R.word3=beacon
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("itemport")
|
||||
var/list/words = list("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri")
|
||||
var/beacon
|
||||
if(usr)
|
||||
beacon = input("Select the last rune", "Rune Scribing") in words
|
||||
R.word1=cultwords["travel"]
|
||||
R.word2=cultwords["other"]
|
||||
R.word3=beacon
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("tome")
|
||||
R.word1=cultwords["see"]
|
||||
R.word2=cultwords["blood"]
|
||||
R.word3=cultwords["hell"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("armor")
|
||||
R.word1=cultwords["hell"]
|
||||
R.word2=cultwords["destroy"]
|
||||
R.word3=cultwords["other"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("convert")
|
||||
R.word1=cultwords["join"]
|
||||
R.word2=cultwords["blood"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("tear in reality")
|
||||
R.word1=cultwords["hell"]
|
||||
R.word2=cultwords["join"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("emp")
|
||||
R.word1=cultwords["destroy"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["technology"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("drain")
|
||||
R.word1=cultwords["travel"]
|
||||
R.word2=cultwords["blood"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("seer")
|
||||
R.word1=cultwords["see"]
|
||||
R.word2=cultwords["hell"]
|
||||
R.word3=cultwords["join"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("raise")
|
||||
R.word1=cultwords["blood"]
|
||||
R.word2=cultwords["join"]
|
||||
R.word3=cultwords["hell"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("obscure")
|
||||
R.word1=cultwords["hide"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["blood"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("astral journey")
|
||||
R.word1=cultwords["hell"]
|
||||
R.word2=cultwords["travel"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("manifest")
|
||||
R.word1=cultwords["blood"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["travel"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("imbue talisman")
|
||||
R.word1=cultwords["hell"]
|
||||
R.word2=cultwords["technology"]
|
||||
R.word3=cultwords["join"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("sacrifice")
|
||||
R.word1=cultwords["hell"]
|
||||
R.word2=cultwords["blood"]
|
||||
R.word3=cultwords["join"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("reveal")
|
||||
R.word1=cultwords["blood"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["hide"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("wall")
|
||||
R.word1=cultwords["destroy"]
|
||||
R.word2=cultwords["travel"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("freedom")
|
||||
R.word1=cultwords["travel"]
|
||||
R.word2=cultwords["technology"]
|
||||
R.word3=cultwords["other"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("cultsummon")
|
||||
R.word1=cultwords["join"]
|
||||
R.word2=cultwords["other"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("deafen")
|
||||
R.word1=cultwords["hide"]
|
||||
R.word2=cultwords["other"]
|
||||
R.word3=cultwords["see"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("blind")
|
||||
R.word1=cultwords["destroy"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["other"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("bloodboil")
|
||||
R.word1=cultwords["destroy"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["blood"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("communicate")
|
||||
R.word1=cultwords["self"]
|
||||
R.word2=cultwords["other"]
|
||||
R.word3=cultwords["technology"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("stun")
|
||||
R.word1=cultwords["join"]
|
||||
R.word2=cultwords["hide"]
|
||||
R.word3=cultwords["technology"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
/obj/item/weapon/book/tome/imbued/attack_self(mob/user as mob)
|
||||
if(src.cultistsonly && !iscultist(usr))
|
||||
return
|
||||
if(!cultwords["travel"])
|
||||
runerandom()
|
||||
if(user)
|
||||
var/r
|
||||
if (!istype(user.loc,/turf))
|
||||
to_chat(user, "<span class='notice'>You do not have enough space to write a proper rune.</span>")
|
||||
var/list/runes = list("teleport", "itemport", "tome", "armor", "convert", "tear in reality", "emp", "drain", "seer", "raise", "obscure", "reveal", "astral journey", "manifest", "imbue talisman", "sacrifice", "wall", "freedom", "cultsummon", "deafen", "blind", "bloodboil", "communicate", "stun")
|
||||
r = input("Choose a rune to scribe", "Rune Scribing") in runes //not cancellable.
|
||||
var/obj/effect/rune/R = new /obj/effect/rune
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
R.blood_DNA = list()
|
||||
R.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
|
||||
var/area/A = get_area(user)
|
||||
log_and_message_admins("created \an [r] rune at \the [A.name] - [user.loc.x]-[user.loc.y]-[user.loc.z].")
|
||||
switch(r)
|
||||
if("teleport")
|
||||
var/list/words = list("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri")
|
||||
var/beacon
|
||||
if(usr)
|
||||
beacon = input("Select the last rune", "Rune Scribing") in words
|
||||
R.word1=cultwords["travel"]
|
||||
R.word2=cultwords["self"]
|
||||
R.word3=beacon
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("itemport")
|
||||
var/list/words = list("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri")
|
||||
var/beacon
|
||||
if(usr)
|
||||
beacon = input("Select the last rune", "Rune Scribing") in words
|
||||
R.word1=cultwords["travel"]
|
||||
R.word2=cultwords["other"]
|
||||
R.word3=beacon
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("tome")
|
||||
R.word1=cultwords["see"]
|
||||
R.word2=cultwords["blood"]
|
||||
R.word3=cultwords["hell"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("armor")
|
||||
R.word1=cultwords["hell"]
|
||||
R.word2=cultwords["destroy"]
|
||||
R.word3=cultwords["other"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("convert")
|
||||
R.word1=cultwords["join"]
|
||||
R.word2=cultwords["blood"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("tear in reality")
|
||||
R.word1=cultwords["hell"]
|
||||
R.word2=cultwords["join"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("emp")
|
||||
R.word1=cultwords["destroy"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["technology"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("drain")
|
||||
R.word1=cultwords["travel"]
|
||||
R.word2=cultwords["blood"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("seer")
|
||||
R.word1=cultwords["see"]
|
||||
R.word2=cultwords["hell"]
|
||||
R.word3=cultwords["join"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("raise")
|
||||
R.word1=cultwords["blood"]
|
||||
R.word2=cultwords["join"]
|
||||
R.word3=cultwords["hell"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("obscure")
|
||||
R.word1=cultwords["hide"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["blood"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("astral journey")
|
||||
R.word1=cultwords["hell"]
|
||||
R.word2=cultwords["travel"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("manifest")
|
||||
R.word1=cultwords["blood"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["travel"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("imbue talisman")
|
||||
R.word1=cultwords["hell"]
|
||||
R.word2=cultwords["technology"]
|
||||
R.word3=cultwords["join"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("sacrifice")
|
||||
R.word1=cultwords["hell"]
|
||||
R.word2=cultwords["blood"]
|
||||
R.word3=cultwords["join"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("reveal")
|
||||
R.word1=cultwords["blood"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["hide"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("wall")
|
||||
R.word1=cultwords["destroy"]
|
||||
R.word2=cultwords["travel"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("freedom")
|
||||
R.word1=cultwords["travel"]
|
||||
R.word2=cultwords["technology"]
|
||||
R.word3=cultwords["other"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("cultsummon")
|
||||
R.word1=cultwords["join"]
|
||||
R.word2=cultwords["other"]
|
||||
R.word3=cultwords["self"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("deafen")
|
||||
R.word1=cultwords["hide"]
|
||||
R.word2=cultwords["other"]
|
||||
R.word3=cultwords["see"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("blind")
|
||||
R.word1=cultwords["destroy"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["other"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("bloodboil")
|
||||
R.word1=cultwords["destroy"]
|
||||
R.word2=cultwords["see"]
|
||||
R.word3=cultwords["blood"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("communicate")
|
||||
R.word1=cultwords["self"]
|
||||
R.word2=cultwords["other"]
|
||||
R.word3=cultwords["technology"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
if("stun")
|
||||
R.word1=cultwords["join"]
|
||||
R.word2=cultwords["hide"]
|
||||
R.word3=cultwords["technology"]
|
||||
R.loc = user.loc
|
||||
R.check_icon()
|
||||
|
||||
+971
-985
File diff suppressed because it is too large
Load Diff
@@ -4,113 +4,113 @@
|
||||
var/uses = 0
|
||||
info = "<center><img src='talisman.png'></center><br/><br/>"
|
||||
|
||||
attack_self(mob/living/user as mob)
|
||||
if(iscultist(user))
|
||||
var/delete = 1
|
||||
// who the hell thought this was a good idea :(
|
||||
switch(imbue)
|
||||
if("newtome")
|
||||
call(/obj/effect/rune/proc/tomesummon)()
|
||||
if("armor")
|
||||
call(/obj/effect/rune/proc/armor)()
|
||||
if("emp")
|
||||
call(/obj/effect/rune/proc/emp)(usr.loc,3)
|
||||
if("conceal")
|
||||
call(/obj/effect/rune/proc/obscure)(2)
|
||||
if("revealrunes")
|
||||
call(/obj/effect/rune/proc/revealrunes)(src)
|
||||
if("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri")
|
||||
call(/obj/effect/rune/proc/teleport)(imbue)
|
||||
if("communicate")
|
||||
//If the user cancels the talisman this var will be set to 0
|
||||
delete = call(/obj/effect/rune/proc/communicate)()
|
||||
if("deafen")
|
||||
call(/obj/effect/rune/proc/deafen)()
|
||||
if("blind")
|
||||
call(/obj/effect/rune/proc/blind)()
|
||||
if("runestun")
|
||||
to_chat(user, "<span class='warning'>To use this talisman, attack your target directly.</span>")
|
||||
return
|
||||
if("supply")
|
||||
supply()
|
||||
user.take_organ_damage(5, 0)
|
||||
if(src && src.imbue!="supply" && src.imbue!="runestun")
|
||||
if(delete)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
to_chat(user, "You see strange symbols on the paper. Are they supposed to mean something?")
|
||||
return
|
||||
|
||||
|
||||
attack(mob/living/carbon/T as mob, mob/living/user as mob)
|
||||
if(iscultist(user))
|
||||
if(imbue == "runestun")
|
||||
user.take_organ_damage(5, 0)
|
||||
call(/obj/effect/rune/proc/runestun)(T)
|
||||
/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 :(
|
||||
switch(imbue)
|
||||
if("newtome")
|
||||
call(/obj/effect/rune/proc/tomesummon)()
|
||||
if("armor")
|
||||
call(/obj/effect/rune/proc/armor)()
|
||||
if("emp")
|
||||
call(/obj/effect/rune/proc/emp)(usr.loc,3)
|
||||
if("conceal")
|
||||
call(/obj/effect/rune/proc/obscure)(2)
|
||||
if("revealrunes")
|
||||
call(/obj/effect/rune/proc/revealrunes)(src)
|
||||
if("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri")
|
||||
call(/obj/effect/rune/proc/teleport)(imbue)
|
||||
if("communicate")
|
||||
//If the user cancels the talisman this var will be set to 0
|
||||
delete = call(/obj/effect/rune/proc/communicate)()
|
||||
if("deafen")
|
||||
call(/obj/effect/rune/proc/deafen)()
|
||||
if("blind")
|
||||
call(/obj/effect/rune/proc/blind)()
|
||||
if("runestun")
|
||||
to_chat(user, "<span class='warning'>To use this talisman, attack your target directly.</span>")
|
||||
return
|
||||
if("supply")
|
||||
supply()
|
||||
user.take_organ_damage(5, 0)
|
||||
if(src && src.imbue!="supply" && src.imbue!="runestun")
|
||||
if(delete)
|
||||
qdel(src)
|
||||
else
|
||||
..() ///If its some other talisman, use the generic attack code, is this supposed to work this way?
|
||||
else
|
||||
..()
|
||||
return
|
||||
else
|
||||
to_chat(user, "You see strange symbols on the paper. Are they supposed to mean something?")
|
||||
return
|
||||
|
||||
|
||||
proc/supply(var/key)
|
||||
if (!src.uses)
|
||||
/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)
|
||||
call(/obj/effect/rune/proc/runestun)(T)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
..() ///If its some other talisman, use the generic attack code, is this supposed to work this way?
|
||||
else
|
||||
..()
|
||||
|
||||
var/dat = "<B>There are [src.uses] bloody runes on the parchment.</B><BR>"
|
||||
dat += "Please choose the chant to be imbued into the fabric of reality.<BR>"
|
||||
dat += "<HR>"
|
||||
dat += "<A href='?src=\ref[src];rune=newtome'>N'ath reth sh'yro eth d'raggathnor!</A> - Allows you to summon a new arcane tome.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=teleport'>Sas'so c'arta forbici!</A> - Allows you to move to a rune with the same last word.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=emp'>Ta'gh fara'qha fel d'amar det!</A> - Allows you to destroy technology in a short range.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=conceal'>Kla'atu barada nikt'o!</A> - Allows you to conceal the runes you placed on the floor.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=communicate'>O bidai nabora se'sma!</A> - Allows you to coordinate with others of your cult.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=runestun'>Fuu ma'jin</A> - Allows you to stun a person by attacking them with the talisman.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=armor'>Sa tatha najin</A> - Allows you to summon armoured robes and an unholy blade<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=soulstone'>Kal om neth</A> - Summons a soul stone<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=construct'>Da A'ig Osk</A> - Summons a construct shell for use with captured souls. It is too large to carry on your person.<BR>"
|
||||
usr << browse(dat, "window=id_com;size=350x200")
|
||||
|
||||
/obj/item/weapon/paper/talisman/proc/supply(var/key)
|
||||
if (!src.uses)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
var/dat = "<B>There are [src.uses] bloody runes on the parchment.</B><BR>"
|
||||
dat += "Please choose the chant to be imbued into the fabric of reality.<BR>"
|
||||
dat += "<HR>"
|
||||
dat += "<A href='?src=\ref[src];rune=newtome'>N'ath reth sh'yro eth d'raggathnor!</A> - Allows you to summon a new arcane tome.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=teleport'>Sas'so c'arta forbici!</A> - Allows you to move to a rune with the same last word.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=emp'>Ta'gh fara'qha fel d'amar det!</A> - Allows you to destroy technology in a short range.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=conceal'>Kla'atu barada nikt'o!</A> - Allows you to conceal the runes you placed on the floor.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=communicate'>O bidai nabora se'sma!</A> - Allows you to coordinate with others of your cult.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=runestun'>Fuu ma'jin</A> - Allows you to stun a person by attacking them with the talisman.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=armor'>Sa tatha najin</A> - Allows you to summon armoured robes and an unholy blade<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=soulstone'>Kal om neth</A> - Summons a soul stone<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=construct'>Da A'ig Osk</A> - Summons a construct shell for use with captured souls. It is too large to carry on your person.<BR>"
|
||||
usr << browse(dat, "window=id_com;size=350x200")
|
||||
return
|
||||
|
||||
Topic(href, href_list)
|
||||
if(!src) return
|
||||
if (usr.stat || usr.restrained() || !in_range(src, usr)) return
|
||||
|
||||
if (href_list["rune"])
|
||||
switch(href_list["rune"])
|
||||
if("newtome")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "newtome"
|
||||
if("teleport")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "[pick("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri", "orkan", "allaq")]"
|
||||
T.info = "[T.imbue]"
|
||||
if("emp")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "emp"
|
||||
if("conceal")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "conceal"
|
||||
if("communicate")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "communicate"
|
||||
if("runestun")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "runestun"
|
||||
if("armor")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "armor"
|
||||
if("soulstone")
|
||||
new /obj/item/device/soulstone(get_turf(usr))
|
||||
if("construct")
|
||||
new /obj/structure/constructshell/cult(get_turf(usr))
|
||||
src.uses--
|
||||
supply()
|
||||
return
|
||||
/obj/item/weapon/paper/talisman/Topic(href, href_list)
|
||||
if(!src) return
|
||||
if (usr.stat || usr.restrained() || !in_range(src, usr)) return
|
||||
|
||||
if (href_list["rune"])
|
||||
switch(href_list["rune"])
|
||||
if("newtome")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "newtome"
|
||||
if("teleport")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "[pick("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri", "orkan", "allaq")]"
|
||||
T.info = "[T.imbue]"
|
||||
if("emp")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "emp"
|
||||
if("conceal")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "conceal"
|
||||
if("communicate")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "communicate"
|
||||
if("runestun")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "runestun"
|
||||
if("armor")
|
||||
var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(get_turf(usr))
|
||||
T.imbue = "armor"
|
||||
if("soulstone")
|
||||
new /obj/item/device/soulstone(get_turf(usr))
|
||||
if("construct")
|
||||
new /obj/structure/constructshell/cult(get_turf(usr))
|
||||
src.uses--
|
||||
supply()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/paper/talisman/supply
|
||||
|
||||
@@ -16,34 +16,34 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
Bump(atom/clong)
|
||||
if(istype(clong, /turf/simulated/shuttle)) //Skip shuttles without actually deleting the rod
|
||||
return
|
||||
/obj/effect/immovablerod/Bump(atom/clong)
|
||||
if(istype(clong, /turf/simulated/shuttle)) //Skip shuttles without actually deleting the rod
|
||||
return
|
||||
|
||||
else if (istype(clong, /turf) && !istype(clong, /turf/unsimulated))
|
||||
if(clong.density)
|
||||
clong.ex_act(2)
|
||||
for (var/mob/O in hearers(src, null))
|
||||
O.show_message("CLANG", 2)
|
||||
else if (istype(clong, /turf) && !istype(clong, /turf/unsimulated))
|
||||
if(clong.density)
|
||||
clong.ex_act(2)
|
||||
for (var/mob/O in hearers(src, null))
|
||||
O.show_message("CLANG", 2)
|
||||
|
||||
else if (istype(clong, /obj))
|
||||
if(clong.density)
|
||||
clong.ex_act(2)
|
||||
for (var/mob/O in hearers(src, null))
|
||||
O.show_message("CLANG", 2)
|
||||
else if (istype(clong, /obj))
|
||||
if(clong.density)
|
||||
clong.ex_act(2)
|
||||
for (var/mob/O in hearers(src, null))
|
||||
O.show_message("CLANG", 2)
|
||||
|
||||
else if (istype(clong, /mob))
|
||||
if(clong.density || prob(10))
|
||||
clong.ex_act(2)
|
||||
else
|
||||
qdel(src)
|
||||
else if (istype(clong, /mob))
|
||||
if(clong.density || prob(10))
|
||||
clong.ex_act(2)
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
if(clong && prob(25))
|
||||
src.loc = clong.loc
|
||||
if(clong && prob(25))
|
||||
src.loc = clong.loc
|
||||
|
||||
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 ..()
|
||||
/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 ..()
|
||||
|
||||
/proc/immovablerod()
|
||||
var/startx = 0
|
||||
|
||||
@@ -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()
|
||||
|
||||
+622
-634
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user