mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-29 19:42:42 +00:00
Merge branch 'master' of https://github.com/Baystation12/Baystation12
This commit is contained in:
@@ -62,6 +62,7 @@ max volume of plasma storeable by the field = the total volume of a number of ti
|
||||
active_power_usage = 500 //multiplied by field strength
|
||||
var/cached_power_avail = 0
|
||||
directwired = 1
|
||||
anchored = 0
|
||||
|
||||
var/state = 0
|
||||
var/locked = 1
|
||||
|
||||
@@ -3,17 +3,19 @@
|
||||
name = "Fuel Injector"
|
||||
icon = 'code/WorkInProgress/Cael_Aislinn/Rust/rust.dmi'
|
||||
icon_state = "injector0"
|
||||
|
||||
density = 1
|
||||
var/state = 2
|
||||
anchored = 0
|
||||
var/state = 0
|
||||
var/locked = 0
|
||||
req_access = list(access_engine)
|
||||
|
||||
var/obj/item/weapon/fuel_assembly/cur_assembly
|
||||
var/fuel_usage = 0.0001 //percentage of available fuel to use per cycle
|
||||
var/id_tag = "One"
|
||||
var/injecting = 0
|
||||
var/trying_to_swap_fuel = 0
|
||||
//
|
||||
req_access = list(access_engine)
|
||||
//
|
||||
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 500
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.0 KiB |
@@ -1,405 +0,0 @@
|
||||
|
||||
// Basic transit tubes. Straight pieces, curved sections,
|
||||
// and basic splits/joins (no routing logic).
|
||||
// Mappers: you can use "Generate Instances from Icon-states"
|
||||
// to get the different pieces.
|
||||
/obj/structure/transit_tube
|
||||
icon = 'transit_tube.dmi'
|
||||
icon_state = "E-W"
|
||||
density = 1
|
||||
layer = 3.1
|
||||
anchored = 1.0
|
||||
var/list/tube_dirs = null
|
||||
var/exit_delay = 2
|
||||
var/enter_delay = 1
|
||||
|
||||
|
||||
// A place where tube pods stop, and people can get in or out.
|
||||
// Mappers: use "Generate Instances from Directions" for this
|
||||
// one.
|
||||
/obj/structure/transit_tube/station
|
||||
icon = 'transit_tube_station.dmi'
|
||||
icon_state = "closed"
|
||||
exit_delay = 2
|
||||
enter_delay = 3
|
||||
var/pod_moving = 0
|
||||
var/automatic_launch_time = 100
|
||||
|
||||
var/const/OPEN_DURATION = 6
|
||||
var/const/CLOSE_DURATION = 6
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod
|
||||
icon = 'transit_tube_pod.dmi'
|
||||
icon_state = "pod"
|
||||
animate_movement = FORWARD_STEPS
|
||||
var/moving = 0
|
||||
var/datum/gas_mixture/air_contents
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/New(loc)
|
||||
..(loc)
|
||||
|
||||
spawn(automatic_launch_time)
|
||||
launch_pod()
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
|
||||
if(!pod_moving && icon_state == "open" && istype(AM, /mob))
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && pod.dir in directions())
|
||||
AM.loc = pod
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/attack_hand(mob/user as mob)
|
||||
if(!pod_moving)
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && pod.dir in directions())
|
||||
if(icon_state == "closed")
|
||||
open_animation()
|
||||
|
||||
else if(icon_state == "open")
|
||||
close_animation()
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/proc/open_animation()
|
||||
if(icon_state == "closed")
|
||||
icon_state = "opening"
|
||||
spawn(OPEN_DURATION)
|
||||
if(icon_state == "opening")
|
||||
icon_state = "open"
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/proc/close_animation()
|
||||
if(icon_state == "open")
|
||||
icon_state = "closing"
|
||||
spawn(CLOSE_DURATION)
|
||||
if(icon_state == "closing")
|
||||
icon_state = "closed"
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/proc/launch_pod()
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && pod.dir in directions())
|
||||
spawn(5)
|
||||
pod_moving = 1
|
||||
close_animation()
|
||||
sleep(CLOSE_DURATION + 2)
|
||||
if(icon_state == "closed" && pod)
|
||||
pod.follow_tube()
|
||||
|
||||
pod_moving = 0
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/should_stop_pod(pod, from_dir)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/pod_stopped(pod, from_dir)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
|
||||
pod_moving = 1
|
||||
spawn(5)
|
||||
open_animation()
|
||||
sleep(OPEN_DURATION + 2)
|
||||
pod_moving = 0
|
||||
pod.mix_air()
|
||||
|
||||
if(automatic_launch_time)
|
||||
var/const/wait_step = 5
|
||||
var/i = 0
|
||||
while(i < automatic_launch_time)
|
||||
sleep(wait_step)
|
||||
i += wait_step
|
||||
|
||||
if(pod_moving || icon_state != "open")
|
||||
return
|
||||
|
||||
launch_pod()
|
||||
|
||||
|
||||
|
||||
// Returns a /list of directions this tube section can
|
||||
// connect to.
|
||||
/obj/structure/transit_tube/proc/directions()
|
||||
return tube_dirs
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/has_entrance(from_dir)
|
||||
from_dir = turn(from_dir, 180)
|
||||
|
||||
for(var/direction in directions())
|
||||
if(direction == from_dir)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/has_exit(in_dir)
|
||||
for(var/direction in directions())
|
||||
if(direction == in_dir)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
// Searches for an exit direction within 45 degrees of the
|
||||
// specified dir. Returns that direction, or 0 if none match.
|
||||
/obj/structure/transit_tube/proc/get_exit(in_dir)
|
||||
var/near_dir = 0
|
||||
var/in_dir_cw = turn(in_dir, -45)
|
||||
var/in_dir_ccw = turn(in_dir, 45)
|
||||
|
||||
for(var/direction in directions())
|
||||
if(direction == in_dir)
|
||||
return direction
|
||||
|
||||
else if(direction == in_dir_cw)
|
||||
near_dir = direction
|
||||
|
||||
else if(direction == in_dir_ccw)
|
||||
near_dir = direction
|
||||
|
||||
return near_dir
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/exit_delay(pod, to_dir)
|
||||
return exit_delay
|
||||
|
||||
/obj/structure/transit_tube/proc/enter_delay(pod, to_dir)
|
||||
return enter_delay
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod/proc/follow_tube()
|
||||
if(moving)
|
||||
return
|
||||
|
||||
moving = 1
|
||||
|
||||
spawn()
|
||||
var/obj/structure/transit_tube/current_tube = null
|
||||
var/next_dir
|
||||
var/next_loc
|
||||
|
||||
for(var/obj/structure/transit_tube/tube in loc)
|
||||
if(tube.has_exit(dir))
|
||||
current_tube = tube
|
||||
break
|
||||
|
||||
while(current_tube)
|
||||
next_dir = current_tube.get_exit(dir)
|
||||
|
||||
if(!next_dir)
|
||||
break
|
||||
|
||||
sleep(current_tube.exit_delay(src, dir))
|
||||
next_loc = get_step(loc, next_dir)
|
||||
|
||||
current_tube = null
|
||||
for(var/obj/structure/transit_tube/tube in next_loc)
|
||||
if(tube.has_entrance(next_dir))
|
||||
current_tube = tube
|
||||
break
|
||||
|
||||
if(current_tube == null)
|
||||
dir = next_dir
|
||||
step(src, dir)
|
||||
break
|
||||
|
||||
sleep(current_tube.enter_delay(src, next_dir))
|
||||
dir = next_dir
|
||||
loc = next_loc
|
||||
|
||||
if(current_tube && current_tube.should_stop_pod(src, next_dir))
|
||||
current_tube.pod_stopped(src, dir)
|
||||
break
|
||||
|
||||
moving = 0
|
||||
|
||||
|
||||
|
||||
// HUGE HACK: Because the pod isn't a mecha, travelling through tubes over space
|
||||
// won't protect people from space.
|
||||
// This avoids editing an additional file, so that adding
|
||||
// tubes to a SS13 codebase is a simple as dropping this code file and the
|
||||
// required icon files somewhere where BYOND can find them.
|
||||
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
|
||||
if(!istype(loc, /obj/structure/transit_tube_pod))
|
||||
return ..(environment)
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod/return_air()
|
||||
var/datum/gas_mixture/GM = new()
|
||||
GM.oxygen = MOLES_O2STANDARD * 2
|
||||
GM.nitrogen = MOLES_N2STANDARD
|
||||
GM.temperature = T20C
|
||||
return GM
|
||||
|
||||
// For now, copying what I found in an unused FEA file (and almost identical in a
|
||||
// used ZAS file). Means that assume_air and remove_air don't actually alter the
|
||||
// air contents.
|
||||
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
|
||||
return 0
|
||||
|
||||
/obj/structure/transit_tube_pod/remove_air(amount)
|
||||
var/oxygen = MOLES_O2STANDARD
|
||||
var/carbon_dioxide = 0
|
||||
var/nitrogen = MOLES_N2STANDARD
|
||||
var/toxins = 0
|
||||
|
||||
var/datum/gas_mixture/GM = new()
|
||||
|
||||
var/sum = oxygen + carbon_dioxide + nitrogen + toxins
|
||||
if(sum>0)
|
||||
GM.oxygen = (oxygen/sum)*amount
|
||||
GM.carbon_dioxide = (carbon_dioxide/sum)*amount
|
||||
GM.nitrogen = (nitrogen/sum)*amount
|
||||
GM.toxins = (toxins/sum)*amount
|
||||
|
||||
GM.temperature = T20C
|
||||
GM.update_values() //Needed in ZAS to prevent suffocation. Not present in FEA. Comment/uncomment as nessecary.
|
||||
|
||||
return GM
|
||||
|
||||
|
||||
|
||||
// Called when a pod arrives at, and before a pod departs from a station,
|
||||
// giving it a chance to mix its internal air supply with the turf it is
|
||||
// currently on.
|
||||
/obj/structure/transit_tube_pod/proc/mix_air()
|
||||
//Needs to be implemented at some point
|
||||
|
||||
|
||||
|
||||
// When the player moves, check if the pos is currently stopped at a station.
|
||||
// if it is, check the direction. If the direction matches the direction of
|
||||
// the station, try to exit. If the direction matches one of the station's
|
||||
// tube directions, launch the pod in that direction.
|
||||
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
|
||||
if(!moving && istype(mob, /mob) && mob.client)
|
||||
for(var/obj/structure/transit_tube/station/station in loc)
|
||||
if(!station.pod_moving && (dir in station.directions()))
|
||||
if(direction == station.dir)
|
||||
if(station.icon_state == "open")
|
||||
mob.loc = loc
|
||||
mob.client.Move(get_step(loc, direction), direction)
|
||||
|
||||
else
|
||||
station.open_animation()
|
||||
|
||||
else if(direction in station.directions())
|
||||
dir = direction
|
||||
station.launch_pod()
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/New(loc)
|
||||
..(loc)
|
||||
|
||||
if(tube_dirs == null)
|
||||
init_dirs()
|
||||
|
||||
|
||||
|
||||
// Parse the icon_state into a list of directions.
|
||||
// This means that mappers can use Dream Maker's built in
|
||||
// "Generate Instances from Icon-states" option to get all
|
||||
// variations. Additionally, as a separate proc, sub-types
|
||||
// can handle it more intelligently.
|
||||
/obj/structure/transit_tube/proc/init_dirs()
|
||||
tube_dirs = parse_dirs(icon_state)
|
||||
|
||||
if(copytext(icon_state, 1, 3) == "D-")
|
||||
density = 0
|
||||
|
||||
|
||||
|
||||
// Tube station directions are simply 90 to either side of
|
||||
// the exit.
|
||||
/obj/structure/transit_tube/station/init_dirs()
|
||||
tube_dirs = list(turn(dir, 90), turn(dir, -90))
|
||||
|
||||
|
||||
|
||||
// Uses a list() to cache return values. Since they should
|
||||
// never be edited directly, all tubes with a certain
|
||||
// icon_state can just reference the same list. In theory,
|
||||
// reduces memory usage, and improves CPU cache usage.
|
||||
// In reality, I don't know if that is quite how BYOND works,
|
||||
// but it is probably safer to assume the existence of, and
|
||||
// rely on, a sufficiently smart compiler/optimizer.
|
||||
/obj/structure/transit_tube/proc/parse_dirs(text)
|
||||
var/global/list/direction_table = list()
|
||||
|
||||
if(text in direction_table)
|
||||
return direction_table[text]
|
||||
|
||||
var/list/split_text = stringsplit(text, "-")
|
||||
|
||||
// If the first token is D, the icon_state represents
|
||||
// a purely decorative tube, and doesn't actually
|
||||
// connect to anything.
|
||||
if(split_text[1] == "D")
|
||||
direction_table[text] = list()
|
||||
return null
|
||||
|
||||
var/list/directions = list()
|
||||
|
||||
for(var/text_part in split_text)
|
||||
var/direction = text2dir_extended(text_part)
|
||||
|
||||
if(direction > 0)
|
||||
directions += direction
|
||||
|
||||
direction_table[text] = directions
|
||||
return directions
|
||||
|
||||
|
||||
|
||||
// A copy of text2dir, extended to accept one and two letter
|
||||
// directions, and to clearly return 0 otherwise.
|
||||
/obj/structure/transit_tube/proc/text2dir_extended(direction)
|
||||
switch(uppertext(direction))
|
||||
if("NORTH", "N")
|
||||
return 1
|
||||
if("SOUTH", "S")
|
||||
return 2
|
||||
if("EAST", "E")
|
||||
return 4
|
||||
if("WEST", "W")
|
||||
return 8
|
||||
if("NORTHEAST", "NE")
|
||||
return 5
|
||||
if("NORTHWEST", "NW")
|
||||
return 9
|
||||
if("SOUTHEAST", "SE")
|
||||
return 6
|
||||
if("SOUTHWEST", "SW")
|
||||
return 10
|
||||
else
|
||||
return 0
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
/obj/effect/bee
|
||||
/mob/living/simple_animal/bee
|
||||
name = "bees"
|
||||
icon = 'icons/obj/apiary_bees_etc.dmi'
|
||||
icon_state = "bees1"
|
||||
@@ -11,162 +11,154 @@
|
||||
var/mob/target_mob
|
||||
var/obj/machinery/apiary/parent
|
||||
pass_flags = PASSGRILLE|PASSTABLE
|
||||
turns_per_move = 6
|
||||
var/obj/machinery/hydroponics/my_hydrotray
|
||||
|
||||
/obj/effect/bee/New(loc, var/obj/machinery/apiary/new_parent)
|
||||
/mob/living/simple_animal/bee/New(loc, var/obj/machinery/apiary/new_parent)
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
parent = new_parent
|
||||
verbs -= /atom/movable/verb/pull
|
||||
|
||||
/obj/effect/bee/Del()
|
||||
processing_objects.Remove(src)
|
||||
/mob/living/simple_animal/bee/Del()
|
||||
if(parent)
|
||||
parent.owned_bee_swarms.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/effect/bee/process()
|
||||
/mob/living/simple_animal/bee/Life()
|
||||
..()
|
||||
|
||||
//if we're strong enough, sting some people
|
||||
var/overrun = strength - 5 + feral / 2
|
||||
if(prob(max( overrun * 10 + feral * 10, 0)))
|
||||
var/mob/living/carbon/human/M = locate() in src.loc
|
||||
if(M)
|
||||
var/sting_prob = 100
|
||||
var/obj/item/clothing/worn_suit = M.wear_suit
|
||||
var/obj/item/clothing/worn_helmet = M.head
|
||||
if(worn_suit)
|
||||
sting_prob -= worn_suit.armor["bio"]
|
||||
if(worn_helmet)
|
||||
sting_prob -= worn_helmet.armor["bio"]
|
||||
if(stat == CONSCIOUS)
|
||||
//if we're strong enough, sting some people
|
||||
var/overrun = strength - 5 + feral / 2
|
||||
if(prob(max( overrun * 10 + feral * 10, 0)))
|
||||
var/mob/living/carbon/human/M = pick(range(1,src))
|
||||
if(M)
|
||||
var/sting_prob = 100
|
||||
var/obj/item/clothing/worn_suit = M.wear_suit
|
||||
var/obj/item/clothing/worn_helmet = M.head
|
||||
if(worn_suit)
|
||||
sting_prob -= worn_suit.armor["bio"]
|
||||
if(worn_helmet)
|
||||
sting_prob -= worn_helmet.armor["bio"]
|
||||
|
||||
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) )
|
||||
M.apply_damage(overrun / 2 + mut / 2, BRUTE)
|
||||
M.apply_damage(overrun / 2 + toxic / 2, TOX)
|
||||
M << "\red You have been stung!"
|
||||
M.flash_pain()
|
||||
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) )
|
||||
M.apply_damage(overrun / 2 + mut / 2, BRUTE)
|
||||
M.apply_damage(overrun / 2 + toxic / 2, TOX)
|
||||
M << "\red You have been stung!"
|
||||
M.flash_pain()
|
||||
|
||||
//if we're chasing someone, get a little bit angry
|
||||
if(target_mob && prob(10))
|
||||
feral++
|
||||
//if we're chasing someone, get a little bit angry
|
||||
if(target_mob && prob(10))
|
||||
feral++
|
||||
|
||||
//calm down a little bit
|
||||
var/move_prob = 40
|
||||
if(feral > 0)
|
||||
if(prob(feral * 10))
|
||||
feral -= 1
|
||||
else
|
||||
//if feral is less than 0, we're becalmed by smoke or steam
|
||||
if(feral < 0)
|
||||
feral += 1
|
||||
|
||||
if(target_mob)
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
if(strength > 5)
|
||||
//calm down and spread out a little
|
||||
var/obj/effect/bee/B = new(get_turf(pick(orange(src,1))))
|
||||
B.strength = rand(1,5)
|
||||
src.strength -= B.strength
|
||||
if(src.strength <= 5)
|
||||
src.icon_state = "bees[src.strength]"
|
||||
B.icon_state = "bees[B.strength]"
|
||||
if(src.parent)
|
||||
B.parent = src.parent
|
||||
src.parent.owned_bee_swarms.Add(B)
|
||||
|
||||
//make some noise
|
||||
if(prob(0.5))
|
||||
src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
|
||||
|
||||
//smoke, water and steam calms us down
|
||||
var/calming = 0
|
||||
var/list/calmers = list(/obj/effect/effect/chem_smoke, /obj/effect/effect/water, /obj/effect/effect/foam, /obj/effect/effect/steam, /obj/effect/mist)
|
||||
|
||||
for(var/this_type in calmers)
|
||||
var/obj/effect/check_effect = locate() in src.loc
|
||||
if(check_effect.type == this_type)
|
||||
calming = 1
|
||||
break
|
||||
|
||||
if(calming)
|
||||
//calm down a little bit
|
||||
if(feral > 0)
|
||||
src.visible_message("\blue The bees calm down!")
|
||||
feral = -10
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
|
||||
for(var/obj/effect/bee/B in src.loc)
|
||||
if(B == src)
|
||||
continue
|
||||
|
||||
if(feral > 0)
|
||||
src.strength += B.strength
|
||||
del(B)
|
||||
src.icon_state = "bees[src.strength]"
|
||||
if(strength > 5)
|
||||
icon_state = "bees_swarm"
|
||||
else if(prob(10))
|
||||
//make the other swarm of bees stronger, then move away
|
||||
var/total_bees = B.strength + src.strength
|
||||
if(total_bees < 10)
|
||||
B.strength = min(5, total_bees)
|
||||
src.strength = total_bees - B.strength
|
||||
|
||||
B.icon_state = "bees[B.strength]"
|
||||
if(src.strength <= 0)
|
||||
del(src)
|
||||
return
|
||||
src.icon_state = "bees[B.strength]"
|
||||
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
|
||||
density = 1
|
||||
if(T.Enter(src, get_turf(src)))
|
||||
src.loc = T
|
||||
density = 0
|
||||
break
|
||||
|
||||
if(target_mob)
|
||||
if(target_mob in view(src,7))
|
||||
target_turf = get_turf(target_mob)
|
||||
if(prob(feral * 10))
|
||||
feral -= 1
|
||||
else
|
||||
for(var/mob/living/carbon/M in view(src,7))
|
||||
target_mob = M
|
||||
//if feral is less than 0, we're becalmed by smoke or steam
|
||||
if(feral < 0)
|
||||
feral += 1
|
||||
|
||||
if(target_mob)
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
if(strength > 5)
|
||||
//calm down and spread out a little
|
||||
var/mob/living/simple_animal/bee/B = new(get_turf(pick(orange(src,1))))
|
||||
B.strength = rand(1,5)
|
||||
src.strength -= B.strength
|
||||
if(src.strength <= 5)
|
||||
src.icon_state = "bees[src.strength]"
|
||||
B.icon_state = "bees[B.strength]"
|
||||
if(src.parent)
|
||||
B.parent = src.parent
|
||||
src.parent.owned_bee_swarms.Add(B)
|
||||
|
||||
//make some noise
|
||||
if(prob(0.5))
|
||||
src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
|
||||
|
||||
//smoke, water and steam calms us down
|
||||
var/calming = 0
|
||||
var/list/calmers = list(/obj/effect/effect/chem_smoke, \
|
||||
/obj/effect/effect/water, \
|
||||
/obj/effect/effect/foam, \
|
||||
/obj/effect/effect/steam, \
|
||||
/obj/effect/mist)
|
||||
|
||||
for(var/this_type in calmers)
|
||||
var/mob/living/simple_animal/check_effect = locate() in src.loc
|
||||
if(check_effect.type == this_type)
|
||||
calming = 1
|
||||
break
|
||||
|
||||
if(target_turf)
|
||||
var/turf/next_turf = get_step(src.loc, get_dir(src,target_turf))
|
||||
if(calming)
|
||||
if(feral > 0)
|
||||
src.visible_message("\blue The bees calm down!")
|
||||
feral = -10
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
wander = 1
|
||||
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
if(B == src)
|
||||
continue
|
||||
|
||||
if(feral > 0)
|
||||
src.strength += B.strength
|
||||
del(B)
|
||||
src.icon_state = "bees[src.strength]"
|
||||
if(strength > 5)
|
||||
icon_state = "bees_swarm"
|
||||
else if(prob(10))
|
||||
//make the other swarm of bees stronger, then move away
|
||||
var/total_bees = B.strength + src.strength
|
||||
if(total_bees < 10)
|
||||
B.strength = min(5, total_bees)
|
||||
src.strength = total_bees - B.strength
|
||||
|
||||
B.icon_state = "bees[B.strength]"
|
||||
if(src.strength <= 0)
|
||||
del(src)
|
||||
return
|
||||
src.icon_state = "bees[B.strength]"
|
||||
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
|
||||
density = 1
|
||||
if(T.Enter(src, get_turf(src)))
|
||||
src.loc = T
|
||||
density = 0
|
||||
break
|
||||
|
||||
if(target_mob)
|
||||
if(target_mob in view(src,7))
|
||||
target_turf = get_turf(target_mob)
|
||||
wander = 0
|
||||
else
|
||||
for(var/mob/living/carbon/M in view(src,7))
|
||||
target_mob = M
|
||||
break
|
||||
|
||||
if(target_turf)
|
||||
Move(get_step(src, get_dir(src,target_turf)))
|
||||
|
||||
//hacky, but w/e
|
||||
var/old_density = -1
|
||||
if(target_mob && get_dist(src, target_mob) <= 1)
|
||||
old_density = target_mob.density
|
||||
target_mob.density = 0
|
||||
density = 1
|
||||
if(next_turf.Enter(src, get_turf(src)))
|
||||
src.loc = next_turf
|
||||
density = 0
|
||||
if(src.loc == target_turf)
|
||||
target_turf = null
|
||||
if(target_mob && old_density != -1)
|
||||
target_mob.density = old_density
|
||||
wander = 1
|
||||
else
|
||||
//find some flowers, harvest
|
||||
//angry bee swarms don't hang around
|
||||
if(feral > 0)
|
||||
move_prob = 60
|
||||
turns_per_move = rand(1,3)
|
||||
else if(feral < 0)
|
||||
move_prob = 0
|
||||
else
|
||||
var/obj/machinery/hydroponics/H = locate() in src.loc
|
||||
if(H)
|
||||
if(H.planted && !H.dead && H.myseed)
|
||||
move_prob = 1
|
||||
|
||||
//chance to wander around
|
||||
if(prob(move_prob))
|
||||
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
|
||||
density = 1
|
||||
if(T.Enter(src, get_turf(src)))
|
||||
src.loc = T
|
||||
density = 0
|
||||
turns_since_move = 0
|
||||
else if(!my_hydrotray || my_hydrotray.loc != src.loc || !my_hydrotray.planted || my_hydrotray.dead || !my_hydrotray.myseed)
|
||||
var/obj/machinery/hydroponics/my_hydrotray = locate() in src.loc
|
||||
if(my_hydrotray)
|
||||
if(my_hydrotray.planted && !my_hydrotray.dead && my_hydrotray.myseed)
|
||||
turns_per_move = rand(20,50)
|
||||
else
|
||||
my_hydrotray = null
|
||||
|
||||
pixel_x = rand(-12,12)
|
||||
pixel_y = rand(-12,12)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
var/bees_in_hive = 0
|
||||
var/list/owned_bee_swarms = list()
|
||||
var/hydrotray_type = /obj/machinery/hydroponics
|
||||
|
||||
//overwrite this after it's created if the apiary needs a custom machinery sprite
|
||||
/obj/machinery/apiary/New()
|
||||
@@ -69,7 +70,7 @@
|
||||
else
|
||||
user << "\blue You begin to dislodge the dead apiary from the tray."
|
||||
if(do_after(user, 50))
|
||||
new /obj/machinery/hydroponics(src.loc)
|
||||
new hydrotray_type(src.loc)
|
||||
new /obj/item/apiary(src.loc)
|
||||
user << "\red You dislodge the apiary from the tray."
|
||||
del(src)
|
||||
@@ -112,11 +113,11 @@
|
||||
if(swarming > 0)
|
||||
swarming -= 1
|
||||
if(swarming <= 0)
|
||||
for(var/obj/effect/bee/B in src.loc)
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
bees_in_hive += B.strength
|
||||
del(B)
|
||||
else if(bees_in_hive < 10)
|
||||
for(var/obj/effect/bee/B in src.loc)
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
bees_in_hive += B.strength
|
||||
del(B)
|
||||
|
||||
@@ -144,7 +145,7 @@
|
||||
health += max(nutrilevel - 1, round(-health / 2))
|
||||
bees_in_hive += max(nutrilevel - 1, round(-bees_in_hive / 2))
|
||||
if(owned_bee_swarms.len)
|
||||
var/obj/effect/bee/B = pick(owned_bee_swarms)
|
||||
var/mob/living/simple_animal/bee/B = pick(owned_bee_swarms)
|
||||
B.target_turf = get_turf(src)
|
||||
|
||||
//clear out some toxins
|
||||
@@ -161,7 +162,7 @@
|
||||
|
||||
//make some new bees
|
||||
if(bees_in_hive >= 10 && prob(bees_in_hive * 10))
|
||||
var/obj/effect/bee/B = new(get_turf(src), src)
|
||||
var/mob/living/simple_animal/bee/B = new(get_turf(src), src)
|
||||
owned_bee_swarms.Add(B)
|
||||
B.mut = mut
|
||||
B.toxic = toxic
|
||||
@@ -193,7 +194,7 @@
|
||||
|
||||
/obj/machinery/apiary/proc/die()
|
||||
if(owned_bee_swarms.len)
|
||||
var/obj/effect/bee/B = pick(owned_bee_swarms)
|
||||
var/mob/living/simple_animal/bee/B = pick(owned_bee_swarms)
|
||||
B.target_turf = get_turf(src)
|
||||
B.strength -= 1
|
||||
if(B.strength <= 0)
|
||||
@@ -204,7 +205,7 @@
|
||||
health = 0
|
||||
|
||||
/obj/machinery/apiary/proc/angry_swarm(var/mob/M)
|
||||
for(var/obj/effect/bee/B in owned_bee_swarms)
|
||||
for(var/mob/living/simple_animal/bee/B in owned_bee_swarms)
|
||||
B.feral = 50
|
||||
B.target_mob = M
|
||||
|
||||
@@ -215,7 +216,7 @@
|
||||
if(bees_in_hive >= 5)
|
||||
spawn_strength = 6
|
||||
|
||||
var/obj/effect/bee/B = new(get_turf(src), src)
|
||||
var/mob/living/simple_animal/bee/B = new(get_turf(src), src)
|
||||
B.target_mob = M
|
||||
B.strength = spawn_strength
|
||||
B.feral = 5
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
/obj/item/weapon/bee_net/attack_self(mob/user as mob)
|
||||
var/turf/T = get_step(get_turf(user), user.dir)
|
||||
for(var/obj/effect/bee/B in T)
|
||||
for(var/mob/living/simple_animal/bee/B in T)
|
||||
if(B.feral < 0)
|
||||
caught_bees += B.strength
|
||||
del(B)
|
||||
@@ -38,7 +38,7 @@
|
||||
while(caught_bees > 0)
|
||||
//release a few super massive swarms
|
||||
while(caught_bees > 5)
|
||||
var/obj/effect/bee/B = new(src.loc)
|
||||
var/mob/living/simple_animal/bee/B = new(src.loc)
|
||||
B.feral = 5
|
||||
B.target_mob = M
|
||||
B.strength = 6
|
||||
@@ -46,7 +46,7 @@
|
||||
caught_bees -= 6
|
||||
|
||||
//what's left over
|
||||
var/obj/effect/bee/B = new(src.loc)
|
||||
var/mob/living/simple_animal/bee/B = new(src.loc)
|
||||
B.strength = caught_bees
|
||||
B.icon_state = "bees[B.strength]"
|
||||
B.feral = 5
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
laws.add_inherent_law(M.newFreeFormLaw)
|
||||
usr << "Added a freeform law."
|
||||
|
||||
if(istype(P, /obj/item/device/mmi) || istype(P, /obj/item/device/posibrain))
|
||||
if(istype(P, /obj/item/device/mmi) || istype(P, /obj/item/device/mmi/posibrain))
|
||||
if(!P:brainmob)
|
||||
user << "\red Sticking an empty [P] into the frame would sort of defeat the purpose."
|
||||
return
|
||||
|
||||
@@ -779,6 +779,7 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
var/obj/machinery/apiary/A = new(src.loc)
|
||||
A.icon = src.icon
|
||||
A.icon_state = src.icon_state
|
||||
A.hydrotray_type = src.type
|
||||
del(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -651,7 +651,7 @@
|
||||
/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
|
||||
if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/posibrain))
|
||||
if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/mmi/posibrain))
|
||||
if(mmi_move_inside(W,user))
|
||||
user << "[src]-MMI interface initialized successfuly"
|
||||
else
|
||||
@@ -1136,7 +1136,7 @@
|
||||
src.occupant.client.perspective = MOB_PERSPECTIVE
|
||||
*/
|
||||
src.occupant << browse(null, "window=exosuit")
|
||||
if(istype(mob_container, /obj/item/device/mmi) || istype(mob_container, /obj/item/device/posibrain))
|
||||
if(istype(mob_container, /obj/item/device/mmi) || istype(mob_container, /obj/item/device/mmi/posibrain))
|
||||
var/obj/item/device/mmi/mmi = mob_container
|
||||
if(mmi.brainmob)
|
||||
occupant.loc = mmi
|
||||
|
||||
@@ -114,7 +114,8 @@
|
||||
|
||||
/obj/effect/spider/spiderling/proc/die()
|
||||
visible_message("<span class='alert'>[src] dies!</span>")
|
||||
icon_state = "greenshatter"
|
||||
new /obj/effect/decal/cleanable/spiderling_remains(src.loc)
|
||||
del(src)
|
||||
|
||||
/obj/effect/spider/spiderling/healthcheck()
|
||||
if(health <= 0)
|
||||
@@ -189,6 +190,12 @@
|
||||
new spawn_type(src.loc)
|
||||
del(src)
|
||||
|
||||
/obj/effect/decal/cleanable/spiderling_remains
|
||||
name = "spiderling remains"
|
||||
desc = "Green squishy mess."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "greenshatter"
|
||||
|
||||
/obj/effect/spider/cocoon
|
||||
name = "cocoon"
|
||||
desc = "Something wrapped in silky spider web"
|
||||
|
||||
@@ -210,10 +210,12 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
|
||||
if (!connection)
|
||||
return
|
||||
|
||||
Broadcast_Message(connection, new /mob/living/silicon/ai(src,null,null,1),
|
||||
var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(src, null, null, 1)
|
||||
Broadcast_Message(connection, A,
|
||||
0, "*garbled automated announcement*", src,
|
||||
message, from, "Automated Announcement", from, "synthesized voice",
|
||||
4, 0, 1)
|
||||
4, 0, list(1), 1459)
|
||||
del(A)
|
||||
return
|
||||
|
||||
/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel)
|
||||
|
||||
@@ -126,9 +126,11 @@ MASS SPECTROMETER
|
||||
if(M.status_flags & FAKEDEATH)
|
||||
OX = fake_oxy > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal"
|
||||
user.show_message("[OX] | [TX] | [BU] | [BR]")
|
||||
if (istype(M, /mob/living/carbon/human))
|
||||
if(M:virus2 || M:reagents.total_volume > 0)
|
||||
if (istype(M, /mob/living/carbon))
|
||||
if(M:reagents.total_volume > 0)
|
||||
user.show_message(text("\red Warning: Unknown substance detected in subject's blood."))
|
||||
if(M:virus2)
|
||||
user.show_message(text("\red Warning: Unknown pathogen detected in subject's blood."))
|
||||
if (M.getCloneLoss())
|
||||
user.show_message("\red Subject appears to have been imperfectly cloned.")
|
||||
for(var/datum/disease/D in M.viruses)
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
else
|
||||
user << "\blue You need to attach a flash to it first!"
|
||||
|
||||
if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/posibrain))
|
||||
if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/mmi/posibrain))
|
||||
var/obj/item/device/mmi/M = W
|
||||
if(check_completion())
|
||||
if(!istype(loc,/turf))
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
for(var/obj/effect/dummy/chameleon/AD in src)
|
||||
AD.loc = src.loc
|
||||
|
||||
for(var/obj/item/I in src)
|
||||
for(var/obj/I in src)
|
||||
I.loc = src.loc
|
||||
|
||||
for(var/mob/M in src)
|
||||
|
||||
@@ -175,15 +175,29 @@
|
||||
redlight = "largemetalr"
|
||||
greenlight = "largemetalg"
|
||||
|
||||
/obj/structure/closet/crate/secure/large_reinforced
|
||||
name = "large crate"
|
||||
/obj/structure/closet/crate/secure/large/close()
|
||||
//we can hold up to one large item
|
||||
var/found = 0
|
||||
for(var/obj/structure/S in src.loc)
|
||||
if(S == src)
|
||||
continue
|
||||
if(!S.anchored)
|
||||
found = 1
|
||||
S.loc = src
|
||||
break
|
||||
if(!found)
|
||||
for(var/obj/machinery/M in src.loc)
|
||||
if(!M.anchored)
|
||||
M.loc = src
|
||||
break
|
||||
..()
|
||||
|
||||
//fluff variant
|
||||
/obj/structure/closet/crate/secure/large/reinforced
|
||||
desc = "A hefty, reinforced metal crate with an electronic locking system."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "largermetal"
|
||||
icon_opened = "largermetalopen"
|
||||
icon_closed = "largermetal"
|
||||
redlight = "largemetalr"
|
||||
greenlight = "largemetalg"
|
||||
|
||||
/obj/structure/closet/crate/secure
|
||||
desc = "A secure crate."
|
||||
@@ -206,6 +220,23 @@
|
||||
icon_opened = "largemetalopen"
|
||||
icon_closed = "largemetal"
|
||||
|
||||
/obj/structure/closet/crate/large/close()
|
||||
//we can hold up to one large item
|
||||
var/found = 0
|
||||
for(var/obj/structure/S in src.loc)
|
||||
if(S == src)
|
||||
continue
|
||||
if(!S.anchored)
|
||||
found = 1
|
||||
S.loc = src
|
||||
break
|
||||
if(!found)
|
||||
for(var/obj/machinery/M in src.loc)
|
||||
if(!M.anchored)
|
||||
M.loc = src
|
||||
break
|
||||
..()
|
||||
|
||||
/obj/structure/closet/crate/hydroponics
|
||||
name = "Hydroponics crate"
|
||||
desc = "All you need to destroy those pesky weeds and pests."
|
||||
|
||||
621
code/game/objects/structures/transit_tubes.dm
Normal file
621
code/game/objects/structures/transit_tubes.dm
Normal file
@@ -0,0 +1,621 @@
|
||||
|
||||
// Basic transit tubes. Straight pieces, curved sections,
|
||||
// and basic splits/joins (no routing logic).
|
||||
// Mappers: you can use "Generate Instances from Icon-states"
|
||||
// to get the different pieces.
|
||||
/obj/structure/transit_tube
|
||||
icon = 'icons/obj/pipes/transit_tube.dmi'
|
||||
icon_state = "E-W"
|
||||
density = 1
|
||||
layer = 3.1
|
||||
anchored = 1.0
|
||||
var/list/tube_dirs = null
|
||||
var/exit_delay = 2
|
||||
var/enter_delay = 1
|
||||
|
||||
// alldirs in global.dm is the same list of directions, but since
|
||||
// the specific order matters to get a usable icon_state, it is
|
||||
// copied here so that, in the unlikely case that alldirs is changed,
|
||||
// this continues to work.
|
||||
var/global/list/tube_dir_list = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
|
||||
|
||||
|
||||
// A place where tube pods stop, and people can get in or out.
|
||||
// Mappers: use "Generate Instances from Directions" for this
|
||||
// one.
|
||||
/obj/structure/transit_tube/station
|
||||
icon = 'icons/obj/pipes/transit_tube_station.dmi'
|
||||
icon_state = "closed"
|
||||
exit_delay = 2
|
||||
enter_delay = 3
|
||||
var/pod_moving = 0
|
||||
var/automatic_launch_time = 100
|
||||
|
||||
var/const/OPEN_DURATION = 6
|
||||
var/const/CLOSE_DURATION = 6
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod
|
||||
icon = 'icons/obj/pipes/transit_tube_pod.dmi'
|
||||
icon_state = "pod"
|
||||
animate_movement = FORWARD_STEPS
|
||||
anchored = 1.0
|
||||
density = 1
|
||||
var/moving = 0
|
||||
var/datum/gas_mixture/air_contents = new()
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod/Del()
|
||||
for(var/atom/movable/AM in contents)
|
||||
AM.loc = loc
|
||||
|
||||
..()
|
||||
|
||||
|
||||
|
||||
// When destroyed by explosions, properly handle contents.
|
||||
obj/structure/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
for(var/atom/movable/AM in contents)
|
||||
AM.loc = loc
|
||||
AM.ex_act(severity++)
|
||||
|
||||
del(src)
|
||||
return
|
||||
if(2.0)
|
||||
if(prob(50))
|
||||
for(var/atom/movable/AM in contents)
|
||||
AM.loc = loc
|
||||
AM.ex_act(severity++)
|
||||
|
||||
del(src)
|
||||
return
|
||||
if(3.0)
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod/New(loc)
|
||||
..(loc)
|
||||
|
||||
air_contents.oxygen = MOLES_O2STANDARD * 2
|
||||
air_contents.nitrogen = MOLES_N2STANDARD
|
||||
air_contents.temperature = T20C
|
||||
|
||||
// Give auto tubes time to align before trying to start moving
|
||||
spawn(5)
|
||||
follow_tube()
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/New(loc)
|
||||
..(loc)
|
||||
|
||||
if(tube_dirs == null)
|
||||
init_dirs()
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/New(loc)
|
||||
..(loc)
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
|
||||
if(!pod_moving && icon_state == "open" && istype(AM, /mob))
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && pod.dir in directions())
|
||||
AM.loc = pod
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/attack_hand(mob/user as mob)
|
||||
if(!pod_moving)
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && pod.dir in directions())
|
||||
if(icon_state == "closed")
|
||||
open_animation()
|
||||
|
||||
else if(icon_state == "open")
|
||||
close_animation()
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/proc/open_animation()
|
||||
if(icon_state == "closed")
|
||||
icon_state = "opening"
|
||||
spawn(OPEN_DURATION)
|
||||
if(icon_state == "opening")
|
||||
icon_state = "open"
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/proc/close_animation()
|
||||
if(icon_state == "open")
|
||||
icon_state = "closing"
|
||||
spawn(CLOSE_DURATION)
|
||||
if(icon_state == "closing")
|
||||
icon_state = "closed"
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/proc/launch_pod()
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
if(!pod.moving && pod.dir in directions())
|
||||
spawn(5)
|
||||
pod_moving = 1
|
||||
close_animation()
|
||||
sleep(CLOSE_DURATION + 2)
|
||||
if(icon_state == "closed" && pod)
|
||||
pod.follow_tube()
|
||||
|
||||
pod_moving = 0
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
// Called to check if a pod should stop upon entering this tube.
|
||||
/obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/should_stop_pod(pod, from_dir)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
// Called when a pod stops in this tube section.
|
||||
/obj/structure/transit_tube/proc/pod_stopped(pod, from_dir)
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
|
||||
pod_moving = 1
|
||||
spawn(5)
|
||||
open_animation()
|
||||
sleep(OPEN_DURATION + 2)
|
||||
pod_moving = 0
|
||||
pod.mix_air()
|
||||
|
||||
if(automatic_launch_time)
|
||||
var/const/wait_step = 5
|
||||
var/i = 0
|
||||
while(i < automatic_launch_time)
|
||||
sleep(wait_step)
|
||||
i += wait_step
|
||||
|
||||
if(pod_moving || icon_state != "open")
|
||||
return
|
||||
|
||||
launch_pod()
|
||||
|
||||
|
||||
|
||||
// Returns a /list of directions this tube section can connect to.
|
||||
// Tubes that have some sort of logic or changing direction might
|
||||
// override it with additional logic.
|
||||
/obj/structure/transit_tube/proc/directions()
|
||||
return tube_dirs
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/has_entrance(from_dir)
|
||||
from_dir = turn(from_dir, 180)
|
||||
|
||||
for(var/direction in directions())
|
||||
if(direction == from_dir)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/has_exit(in_dir)
|
||||
for(var/direction in directions())
|
||||
if(direction == in_dir)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
// Searches for an exit direction within 45 degrees of the
|
||||
// specified dir. Returns that direction, or 0 if none match.
|
||||
/obj/structure/transit_tube/proc/get_exit(in_dir)
|
||||
var/near_dir = 0
|
||||
var/in_dir_cw = turn(in_dir, -45)
|
||||
var/in_dir_ccw = turn(in_dir, 45)
|
||||
|
||||
for(var/direction in directions())
|
||||
if(direction == in_dir)
|
||||
return direction
|
||||
|
||||
else if(direction == in_dir_cw)
|
||||
near_dir = direction
|
||||
|
||||
else if(direction == in_dir_ccw)
|
||||
near_dir = direction
|
||||
|
||||
return near_dir
|
||||
|
||||
|
||||
|
||||
// Return how many BYOND ticks to wait before entering/exiting
|
||||
// the tube section. Default action is to return the value of
|
||||
// a var, which wouldn't need a proc, but it makes it possible
|
||||
// for later tube types to interact in more interesting ways
|
||||
// such as being very fast in one direction, but slow in others
|
||||
/obj/structure/transit_tube/proc/exit_delay(pod, to_dir)
|
||||
return exit_delay
|
||||
|
||||
/obj/structure/transit_tube/proc/enter_delay(pod, to_dir)
|
||||
return enter_delay
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube_pod/proc/follow_tube()
|
||||
if(moving)
|
||||
return
|
||||
|
||||
moving = 1
|
||||
|
||||
spawn()
|
||||
var/obj/structure/transit_tube/current_tube = null
|
||||
var/next_dir
|
||||
var/next_loc
|
||||
var/last_delay = 0
|
||||
var/exit_delay
|
||||
|
||||
for(var/obj/structure/transit_tube/tube in loc)
|
||||
if(tube.has_exit(dir))
|
||||
current_tube = tube
|
||||
break
|
||||
|
||||
while(current_tube)
|
||||
next_dir = current_tube.get_exit(dir)
|
||||
|
||||
if(!next_dir)
|
||||
break
|
||||
|
||||
exit_delay = current_tube.exit_delay(src, dir)
|
||||
last_delay += exit_delay
|
||||
|
||||
sleep(exit_delay)
|
||||
|
||||
next_loc = get_step(loc, next_dir)
|
||||
|
||||
current_tube = null
|
||||
for(var/obj/structure/transit_tube/tube in next_loc)
|
||||
if(tube.has_entrance(next_dir))
|
||||
current_tube = tube
|
||||
break
|
||||
|
||||
if(current_tube == null)
|
||||
dir = next_dir
|
||||
Move(get_step(loc, dir)) // Allow collisions when leaving the tubes.
|
||||
break
|
||||
|
||||
last_delay = current_tube.enter_delay(src, next_dir)
|
||||
sleep(last_delay)
|
||||
dir = next_dir
|
||||
loc = next_loc // When moving from one tube to another, skip collision and such.
|
||||
density = current_tube.density
|
||||
|
||||
if(current_tube && current_tube.should_stop_pod(src, next_dir))
|
||||
current_tube.pod_stopped(src, dir)
|
||||
break
|
||||
|
||||
density = 1
|
||||
|
||||
// If the pod is no longer in a tube, move in a line until stopped or slowed to a halt.
|
||||
// /turf/inertial_drift appears to only work on mobs, and re-implementing some of the
|
||||
// logic allows a gradual slowdown and eventual stop when passing over non-space turfs.
|
||||
if(!current_tube && last_delay <= 10)
|
||||
do
|
||||
sleep(last_delay)
|
||||
|
||||
if(!istype(loc, /turf/space))
|
||||
last_delay++
|
||||
|
||||
if(last_delay > 10)
|
||||
break
|
||||
|
||||
while(isturf(loc) && Move(get_step(loc, dir)))
|
||||
|
||||
moving = 0
|
||||
|
||||
|
||||
// Should I return a copy here? If the caller edits or del()s the returned
|
||||
// datum, there might be problems if I don't...
|
||||
/obj/structure/transit_tube_pod/return_air()
|
||||
var/datum/gas_mixture/GM = new()
|
||||
GM.oxygen = air_contents.oxygen
|
||||
GM.carbon_dioxide = air_contents.carbon_dioxide
|
||||
GM.nitrogen = air_contents.nitrogen
|
||||
GM.toxins = air_contents.toxins
|
||||
GM.temperature = air_contents.temperature
|
||||
return GM
|
||||
|
||||
// For now, copying what I found in an unused FEA file (and almost identical in a
|
||||
// used ZAS file). Means that assume_air and remove_air don't actually alter the
|
||||
// air contents.
|
||||
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
|
||||
return air_contents.merge(giver)
|
||||
|
||||
/obj/structure/transit_tube_pod/remove_air(amount)
|
||||
return air_contents.remove(amount)
|
||||
|
||||
|
||||
|
||||
// Called when a pod arrives at, and before a pod departs from a station,
|
||||
// giving it a chance to mix its internal air supply with the turf it is
|
||||
// currently on.
|
||||
/obj/structure/transit_tube_pod/proc/mix_air()
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/env_pressure = environment.return_pressure()
|
||||
var/int_pressure = air_contents.return_pressure()
|
||||
var/total_pressure = env_pressure + int_pressure
|
||||
|
||||
if(total_pressure == 0)
|
||||
return
|
||||
|
||||
// Math here: Completely made up, not based on realistic equasions.
|
||||
// Goal is to balance towards equal pressure, but ensure some gas
|
||||
// transfer in both directions regardless.
|
||||
// Feel free to rip this out and replace it with something better,
|
||||
// I don't really know muhch about how gas transfer rates work in
|
||||
// SS13.
|
||||
var/transfer_in = max(0.1, 0.5 * (env_pressure - int_pressure) / total_pressure)
|
||||
var/transfer_out = max(0.1, 0.3 * (int_pressure - env_pressure) / total_pressure)
|
||||
|
||||
var/datum/gas_mixture/from_env = loc.remove_air(environment.total_moles() * transfer_in)
|
||||
var/datum/gas_mixture/from_int = air_contents.remove(air_contents.total_moles() * transfer_out)
|
||||
|
||||
loc.assume_air(from_int)
|
||||
air_contents.merge(from_env)
|
||||
|
||||
|
||||
|
||||
// When the player moves, check if the pos is currently stopped at a station.
|
||||
// if it is, check the direction. If the direction matches the direction of
|
||||
// the station, try to exit. If the direction matches one of the station's
|
||||
// tube directions, launch the pod in that direction.
|
||||
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
|
||||
if(istype(mob, /mob) && mob.client)
|
||||
// If the pod is not in a tube at all, you can get out at any time.
|
||||
if(!(locate(/obj/structure/transit_tube) in loc))
|
||||
mob.loc = loc
|
||||
mob.client.Move(get_step(loc, direction), direction)
|
||||
|
||||
//if(moving && istype(loc, /turf/space))
|
||||
// Todo: If you get out of a moving pod in space, you should move as well.
|
||||
// Same direction as pod? Direcion you moved? Halfway between?
|
||||
|
||||
if(!moving)
|
||||
for(var/obj/structure/transit_tube/station/station in loc)
|
||||
if(dir in station.directions())
|
||||
if(!station.pod_moving)
|
||||
if(direction == station.dir)
|
||||
if(station.icon_state == "open")
|
||||
mob.loc = loc
|
||||
mob.client.Move(get_step(loc, direction), direction)
|
||||
|
||||
else
|
||||
station.open_animation()
|
||||
|
||||
else if(direction in station.directions())
|
||||
dir = direction
|
||||
station.launch_pod()
|
||||
return
|
||||
|
||||
for(var/obj/structure/transit_tube/tube in loc)
|
||||
if(dir in tube.directions())
|
||||
if(tube.has_exit(direction))
|
||||
dir = direction
|
||||
return
|
||||
|
||||
|
||||
|
||||
// Parse the icon_state into a list of directions.
|
||||
// This means that mappers can use Dream Maker's built in
|
||||
// "Generate Instances from Icon-states" option to get all
|
||||
// variations. Additionally, as a separate proc, sub-types
|
||||
// can handle it more intelligently.
|
||||
/obj/structure/transit_tube/proc/init_dirs()
|
||||
if(icon_state == "auto")
|
||||
// Additional delay, for map loading.
|
||||
spawn(1)
|
||||
init_dirs_automatic()
|
||||
|
||||
else
|
||||
tube_dirs = parse_dirs(icon_state)
|
||||
|
||||
if(copytext(icon_state, 1, 3) == "D-" || findtextEx(icon_state, "Pass"))
|
||||
density = 0
|
||||
|
||||
|
||||
|
||||
// Tube station directions are simply 90 to either side of
|
||||
// the exit.
|
||||
/obj/structure/transit_tube/station/init_dirs()
|
||||
tube_dirs = list(turn(dir, 90), turn(dir, -90))
|
||||
|
||||
|
||||
|
||||
// Initialize dirs by searching for tubes that do/might connect
|
||||
// on nearby turfs. Create corner pieces if nessecary.
|
||||
// Pick two directions, preferring tubes that already connect
|
||||
// to loc, or other auto tubes if there aren't enough connections.
|
||||
/obj/structure/transit_tube/proc/init_dirs_automatic()
|
||||
var/list/connected = list()
|
||||
var/list/connected_auto = list()
|
||||
|
||||
for(var/direction in tube_dir_list)
|
||||
var/location = get_step(loc, direction)
|
||||
for(var/obj/structure/transit_tube/tube in location)
|
||||
if(tube.directions() == null && tube.icon_state == "auto")
|
||||
connected_auto += direction
|
||||
break
|
||||
|
||||
else if(turn(direction, 180) in tube.directions())
|
||||
connected += direction
|
||||
break
|
||||
|
||||
connected += connected_auto
|
||||
|
||||
tube_dirs = select_automatic_dirs(connected)
|
||||
|
||||
if(length(tube_dirs) == 2 && tube_dir_list.Find(tube_dirs[1]) > tube_dir_list.Find(tube_dirs[2]))
|
||||
tube_dirs.Swap(1, 2)
|
||||
|
||||
generate_automatic_corners(tube_dirs)
|
||||
select_automatic_icon_state(tube_dirs)
|
||||
|
||||
|
||||
|
||||
// Given a list of directions, look a pair that forms a 180 or
|
||||
// 135 degree angle, and return a list containing the pair.
|
||||
// If none exist, return list(connected[1], turn(connected[1], 180)
|
||||
/obj/structure/transit_tube/proc/select_automatic_dirs(connected)
|
||||
if(length(connected) < 1)
|
||||
return list()
|
||||
|
||||
for(var/i = 1, i <= length(connected), i++)
|
||||
for(var/j = i + 1, j <= length(connected), j++)
|
||||
var/d1 = connected[i]
|
||||
var/d2 = connected[j]
|
||||
|
||||
if(d1 == turn(d2, 135) || d1 == turn(d2, 180) || d1 == turn(d2, 225))
|
||||
return list(d1, d2)
|
||||
|
||||
return list(connected[1], turn(connected[1], 180))
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/proc/select_automatic_icon_state(directions)
|
||||
if(length(directions) == 2)
|
||||
icon_state = "[dir2text_short(directions[1])]-[dir2text_short(directions[2])]"
|
||||
|
||||
|
||||
|
||||
// Look for diagonal directions, generate the decorative corners in each.
|
||||
/obj/structure/transit_tube/proc/generate_automatic_corners(directions)
|
||||
for(var/direction in directions)
|
||||
if(direction == 5 || direction == 6 || direction == 9 || direction == 10)
|
||||
if(direction & NORTH)
|
||||
create_automatic_decorative_corner(get_step(loc, NORTH), direction ^ 3)
|
||||
|
||||
else
|
||||
create_automatic_decorative_corner(get_step(loc, SOUTH), direction ^ 3)
|
||||
|
||||
if(direction & EAST)
|
||||
create_automatic_decorative_corner(get_step(loc, EAST), direction ^ 12)
|
||||
|
||||
else
|
||||
create_automatic_decorative_corner(get_step(loc, WEST), direction ^ 12)
|
||||
|
||||
|
||||
|
||||
// Generate a corner, if one doesn't exist for the direction on the turf.
|
||||
/obj/structure/transit_tube/proc/create_automatic_decorative_corner(location, direction)
|
||||
var/state = "D-[dir2text_short(direction)]"
|
||||
|
||||
for(var/obj/structure/transit_tube/tube in location)
|
||||
if(tube.icon_state == state)
|
||||
return
|
||||
|
||||
var/obj/structure/transit_tube/tube = new(location)
|
||||
tube.icon_state = state
|
||||
tube.init_dirs()
|
||||
|
||||
|
||||
|
||||
// Uses a list() to cache return values. Since they should
|
||||
// never be edited directly, all tubes with a certain
|
||||
// icon_state can just reference the same list. In theory,
|
||||
// reduces memory usage, and improves CPU cache usage.
|
||||
// In reality, I don't know if that is quite how BYOND works,
|
||||
// but it is probably safer to assume the existence of, and
|
||||
// rely on, a sufficiently smart compiler/optimizer.
|
||||
/obj/structure/transit_tube/proc/parse_dirs(text)
|
||||
var/global/list/direction_table = list()
|
||||
|
||||
if(text in direction_table)
|
||||
return direction_table[text]
|
||||
|
||||
var/list/split_text = stringsplit(text, "-")
|
||||
|
||||
// If the first token is D, the icon_state represents
|
||||
// a purely decorative tube, and doesn't actually
|
||||
// connect to anything.
|
||||
if(split_text[1] == "D")
|
||||
direction_table[text] = list()
|
||||
return null
|
||||
|
||||
var/list/directions = list()
|
||||
|
||||
for(var/text_part in split_text)
|
||||
var/direction = text2dir_extended(text_part)
|
||||
|
||||
if(direction > 0)
|
||||
directions += direction
|
||||
|
||||
direction_table[text] = directions
|
||||
return directions
|
||||
|
||||
|
||||
|
||||
// A copy of text2dir, extended to accept one and two letter
|
||||
// directions, and to clearly return 0 otherwise.
|
||||
/obj/structure/transit_tube/proc/text2dir_extended(direction)
|
||||
switch(uppertext(direction))
|
||||
if("NORTH", "N")
|
||||
return 1
|
||||
if("SOUTH", "S")
|
||||
return 2
|
||||
if("EAST", "E")
|
||||
return 4
|
||||
if("WEST", "W")
|
||||
return 8
|
||||
if("NORTHEAST", "NE")
|
||||
return 5
|
||||
if("NORTHWEST", "NW")
|
||||
return 9
|
||||
if("SOUTHEAST", "SE")
|
||||
return 6
|
||||
if("SOUTHWEST", "SW")
|
||||
return 10
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
// A copy of dir2text, which returns the short one or two letter
|
||||
// directions used in tube icon states.
|
||||
/obj/structure/transit_tube/proc/dir2text_short(direction)
|
||||
switch(direction)
|
||||
if(1)
|
||||
return "N"
|
||||
if(2)
|
||||
return "S"
|
||||
if(4)
|
||||
return "E"
|
||||
if(8)
|
||||
return "W"
|
||||
if(5)
|
||||
return "NE"
|
||||
if(6)
|
||||
return "SE"
|
||||
if(9)
|
||||
return "NW"
|
||||
if(10)
|
||||
return "SW"
|
||||
else
|
||||
return
|
||||
@@ -350,6 +350,8 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
excavate_find(5, src.finds[1])
|
||||
else if(prob(50))
|
||||
src.finds.Remove(src.finds[1])
|
||||
if(prob(50))
|
||||
artifact_debris()
|
||||
|
||||
if(do_after(user,P.digspeed))
|
||||
user << "\blue You finish [P.drill_verb] the rock."
|
||||
@@ -387,9 +389,8 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
B = new(src)
|
||||
if(artifact_find)
|
||||
B.artifact_find = artifact_find
|
||||
else if(src.excavation_level + P.excavation_amount >= 100)
|
||||
spawn(0)
|
||||
artifact_debris()
|
||||
else if(artifact_find && src.excavation_level + P.excavation_amount >= 100)
|
||||
artifact_debris(1)
|
||||
|
||||
gets_drilled(B ? 0 : 1)
|
||||
return
|
||||
@@ -477,13 +478,8 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
for (var/i=0;i<mineralAmt;i++)
|
||||
drop_mineral()
|
||||
|
||||
/*if (prob(src.artifactChance))
|
||||
//spawn a rare artifact here
|
||||
new /obj/machinery/artifact(src)*/
|
||||
var/turf/simulated/floor/plating/airless/asteroid/N = ChangeTurf(/turf/simulated/floor/plating/airless/asteroid)
|
||||
N.fullUpdateMineralOverlays()
|
||||
|
||||
//destroyed artifacts have weird, unpleasant effects
|
||||
//make sure to destroy them before changing the turf though
|
||||
if(artifact_find && artifact_fail)
|
||||
var/pain = 0
|
||||
if(prob(50))
|
||||
@@ -500,6 +496,12 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
M.Stun(5)
|
||||
M.apply_effect(25, IRRADIATE)
|
||||
|
||||
/*if (prob(src.artifactChance))
|
||||
//spawn a rare artifact here
|
||||
new /obj/machinery/artifact(src)*/
|
||||
var/turf/simulated/floor/plating/airless/asteroid/N = ChangeTurf(/turf/simulated/floor/plating/airless/asteroid)
|
||||
N.fullUpdateMineralOverlays()
|
||||
|
||||
/*if(destroyed) //Display message about being a terrible miner
|
||||
usr << "\red You destroy some of the rocks!"*/
|
||||
return
|
||||
@@ -528,73 +530,60 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
var/obj/effect/suspension_field/S = locate() in src
|
||||
if(!S || S.field_type != get_responsive_reagent(F.find_type))
|
||||
if(X)
|
||||
src.visible_message("\red<b>[pick("[display_name] crumbles away into dust","[display_name] breaks apart","[display_name] collapses onto itself")].</b>")
|
||||
src.visible_message("\red<b>[pick("[display_name] crumbles away into dust","[display_name] breaks apart")].</b>")
|
||||
del(X)
|
||||
|
||||
src.finds.Remove(F)
|
||||
|
||||
/turf/simulated/mineral/proc/artifact_debris()
|
||||
/turf/simulated/mineral/proc/artifact_debris(var/severity = 0)
|
||||
//cael's patented random limited drop componentized loot system!
|
||||
severity = max(min(severity,1),0)
|
||||
var/materials = 0
|
||||
var/list/viable_materials = list(1,2,4,8,16,32,64,128,256)
|
||||
|
||||
var/num_materials = rand(1,5)
|
||||
var/num_materials = rand(1,3 + severity*2)
|
||||
for(var/i=0, i<num_materials, i++)
|
||||
var/chosen = pick(viable_materials)
|
||||
materials |= chosen
|
||||
viable_materials.Remove(chosen)
|
||||
|
||||
if(materials & 1)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/rods/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
var/obj/item/stack/rods/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
|
||||
if(materials & 2)
|
||||
var/quantity = pick(0, 0, 1)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/tile/R = new(src)
|
||||
R.amount = rand(1,5)
|
||||
var/obj/item/stack/tile/R = new(src)
|
||||
R.amount = rand(1,5)
|
||||
|
||||
if(materials & 4)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/sheet/metal/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
var/obj/item/stack/sheet/metal/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
|
||||
if(materials & 8)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/sheet/plasteel/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
var/obj/item/stack/sheet/plasteel/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
|
||||
if(materials & 16)
|
||||
var/quantity = rand(0,3)
|
||||
var/quantity = rand(1,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
new /obj/item/weapon/shard(src)
|
||||
|
||||
if(materials & 32)
|
||||
var/quantity = rand(0,3)
|
||||
var/quantity = rand(1,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
new /obj/item/weapon/shard/plasma(src)
|
||||
|
||||
if(materials & 64)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/sheet/mineral/uranium/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
var/obj/item/stack/sheet/mineral/uranium/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
|
||||
if(materials & 128)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/sheet/mineral/mythril/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
var/obj/item/stack/sheet/mineral/mythril/R = new(src)
|
||||
R.amount = rand(1,5)
|
||||
|
||||
if(materials & 256)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/sheet/mineral/adamantine/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
var/obj/item/stack/sheet/mineral/adamantine/R = new(src)
|
||||
R.amount = rand(1,5)
|
||||
|
||||
/*
|
||||
/turf/simulated/mineral/proc/setRandomMinerals()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/item/device/posibrain
|
||||
/obj/item/device/mmi/posibrain
|
||||
name = "positronic brain"
|
||||
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves."
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
@@ -6,14 +6,15 @@
|
||||
w_class = 3
|
||||
origin_tech = "engineering=4;materials=4;bluespace=2;programming=4"
|
||||
|
||||
var/list/construction_cost = list("metal"=500,"glass"=500,"silver"=200,"gold"=200,"plasma"=100,"diamond"=10)
|
||||
var/construction_time = 75
|
||||
construction_cost = list("metal"=500,"glass"=500,"silver"=200,"gold"=200,"plasma"=100,"diamond"=10)
|
||||
construction_time = 75
|
||||
var/searching = 0
|
||||
var/askDelay = 10 * 60 * 1
|
||||
var/mob/living/carbon/brain/brainmob = null
|
||||
mob/living/carbon/brain/brainmob = null
|
||||
req_access = list(access_robotics)
|
||||
var/locked = 0
|
||||
var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm.
|
||||
locked = 0
|
||||
mecha = null//This does not appear to be used outside of reference in mecha.dm.
|
||||
|
||||
|
||||
attack_self(mob/user as mob)
|
||||
if(!brainmob.key && searching == 0)
|
||||
@@ -73,7 +74,7 @@
|
||||
for (var/mob/M in viewers(T))
|
||||
M.show_message("\blue The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
|
||||
|
||||
/obj/item/device/posibrain/examine()
|
||||
/obj/item/device/mmi/posibrain/examine()
|
||||
|
||||
set src in oview()
|
||||
|
||||
@@ -97,20 +98,20 @@
|
||||
usr << msg
|
||||
return
|
||||
|
||||
/obj/item/device/posibrain/emp_act(severity)
|
||||
if(!brainmob)
|
||||
/obj/item/device/mmi/posibrain/emp_act(severity)
|
||||
if(!src.brainmob)
|
||||
return
|
||||
else
|
||||
switch(severity)
|
||||
if(1)
|
||||
brainmob.emp_damage += rand(20,30)
|
||||
src.brainmob.emp_damage += rand(20,30)
|
||||
if(2)
|
||||
brainmob.emp_damage += rand(10,20)
|
||||
src.brainmob.emp_damage += rand(10,20)
|
||||
if(3)
|
||||
brainmob.emp_damage += rand(0,10)
|
||||
src.brainmob.emp_damage += rand(0,10)
|
||||
..()
|
||||
|
||||
/obj/item/device/posibrain/New()
|
||||
/obj/item/device/mmi/posibrain/New()
|
||||
|
||||
src.brainmob = new(src)
|
||||
src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
if (silent)
|
||||
return
|
||||
|
||||
if(!(container && (istype(container, /obj/item/device/mmi) || istype(container, /obj/item/device/posibrain))))
|
||||
if(!(container && (istype(container, /obj/item/device/mmi) || istype(container, /obj/item/device/mmi/posibrain))))
|
||||
return //No MMI, can't speak, bucko./N
|
||||
else
|
||||
if ((copytext(message, 1, 3) == ":b") || (copytext(message, 1, 3) == ":B") && (container && istype(container, /obj/item/device/posibrain)))
|
||||
if ((copytext(message, 1, 3) == ":b") || (copytext(message, 1, 3) == ":B") && (container && istype(container, /obj/item/device/mmi/posibrain)))
|
||||
message = copytext(message, 3)
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
robot_talk(message)
|
||||
|
||||
@@ -684,7 +684,7 @@
|
||||
if(dna)
|
||||
switch(dna.mutantrace)
|
||||
if("lizard")
|
||||
return "Soghun"
|
||||
return "Unathi"
|
||||
if("tajaran")
|
||||
return "Tajaran"
|
||||
if("skrell")
|
||||
@@ -699,7 +699,7 @@
|
||||
/mob/living/carbon/get_species()
|
||||
if(src.dna)
|
||||
if(src.dna.mutantrace == "lizard")
|
||||
return "Soghun"
|
||||
return "Unathi"
|
||||
else if(src.dna.mutantrace == "skrell")
|
||||
return "Skrell"
|
||||
else if(src.dna.mutantrace == "tajaran")
|
||||
|
||||
@@ -84,6 +84,8 @@
|
||||
//Random events (vomiting etc)
|
||||
handle_random_events()
|
||||
|
||||
handle_virus_updates()
|
||||
|
||||
//Handle temperature/pressure differences between body and environment
|
||||
handle_environment(environment)
|
||||
|
||||
@@ -1262,6 +1264,7 @@
|
||||
if(bodytemperature > 406)
|
||||
for(var/datum/disease/D in viruses)
|
||||
D.cure()
|
||||
if(virus2) virus2.cure(src)
|
||||
if(!virus2)
|
||||
for(var/obj/effect/decal/cleanable/blood/B in view(1,src))
|
||||
if(B.virus2 && get_infection_chance())
|
||||
|
||||
@@ -126,7 +126,7 @@ Please contact me on #coderbus IRC. ~Carn x
|
||||
var/list/overlays_lying[TOTAL_LAYERS]
|
||||
var/list/overlays_standing[TOTAL_LAYERS]
|
||||
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
|
||||
|
||||
var/race_icon
|
||||
|
||||
//UPDATES OVERLAYS FROM OVERLAYS_LYING/OVERLAYS_STANDING
|
||||
//this proc is messy as I was forced to include some old laggy cloaking code to it so that I don't break cloakers
|
||||
@@ -234,24 +234,8 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
var/g = "m"
|
||||
if(gender == FEMALE) g = "f"
|
||||
|
||||
var/icon/icobase
|
||||
if(skeleton)
|
||||
icobase = 'icons/mob/human_races/r_skeleton.dmi'
|
||||
else if(dna)
|
||||
switch(dna.mutantrace)
|
||||
if("tajaran")
|
||||
icobase = 'icons/mob/human_races/r_tajaran.dmi'
|
||||
if("lizard")
|
||||
icobase = 'icons/mob/human_races/r_lizard.dmi'
|
||||
if("skrell")
|
||||
icobase = 'icons/mob/human_races/r_skrell.dmi'
|
||||
else
|
||||
icobase = 'icons/mob/human_races/r_human.dmi'
|
||||
else
|
||||
icobase = 'icons/mob/human_races/r_human.dmi'
|
||||
|
||||
if(!skeleton)
|
||||
stand_icon = new /icon(icobase, "torso_[g][fat?"_fat":""]")
|
||||
stand_icon = new /icon(race_icon, "torso_[g][fat?"_fat":""]")
|
||||
if(husk)
|
||||
stand_icon.ColorTone(husk_color_mod)
|
||||
else if(hulk)
|
||||
@@ -261,7 +245,7 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
else if(plant)
|
||||
stand_icon.ColorTone(plant_color_mod)
|
||||
else
|
||||
stand_icon = new /icon(icobase, "torso")
|
||||
stand_icon = new /icon(race_icon, "torso")
|
||||
|
||||
var/datum/organ/external/head = get_organ("head")
|
||||
var/has_head = 0
|
||||
@@ -273,16 +257,16 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
var/icon/temp
|
||||
if(istype(part, /datum/organ/external/groin))
|
||||
if(skeleton)
|
||||
temp = new /icon(icobase, "groin")
|
||||
temp = new /icon(race_icon, "groin")
|
||||
else
|
||||
temp = new /icon(icobase, "groin_[g]")
|
||||
temp = new /icon(race_icon, "groin_[g]")
|
||||
else if(istype(part, /datum/organ/external/head))
|
||||
if(skeleton)
|
||||
temp = new /icon(icobase, "head")
|
||||
temp = new /icon(race_icon, "head")
|
||||
else
|
||||
temp = new /icon(icobase, "head_[g]")
|
||||
temp = new /icon(race_icon, "head_[g]")
|
||||
else
|
||||
temp = new /icon(icobase, "[part.icon_name]")
|
||||
temp = new /icon(race_icon, "[part.icon_name]")
|
||||
if(part.status & ORGAN_ROBOT)
|
||||
temp.GrayScale()
|
||||
if(part.status & ORGAN_DEAD)
|
||||
@@ -327,7 +311,7 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
|
||||
if(husk)
|
||||
var/icon/mask = new(stand_icon)
|
||||
var/icon/husk_over = new(icobase,"overlay_husk")
|
||||
var/icon/husk_over = new(race_icon,"overlay_husk")
|
||||
mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0)
|
||||
husk_over.Blend(mask, ICON_ADD)
|
||||
stand_icon.Blend(husk_over, ICON_OVERLAY)
|
||||
@@ -451,14 +435,30 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
// var/g = "m"
|
||||
// if (gender == FEMALE) g = "f"
|
||||
//BS12 EDIT
|
||||
var/skeleton = (SKELETON in src.mutations)
|
||||
if(skeleton)
|
||||
race_icon = 'icons/mob/human_races/r_skeleton.dmi'
|
||||
else if(dna)
|
||||
switch(dna.mutantrace)
|
||||
if("tajaran")
|
||||
race_icon = 'icons/mob/human_races/r_tajaran.dmi'
|
||||
if("lizard")
|
||||
race_icon = 'icons/mob/human_races/r_lizard.dmi'
|
||||
if("skrell")
|
||||
race_icon = 'icons/mob/human_races/r_skrell.dmi'
|
||||
else
|
||||
race_icon = 'icons/mob/human_races/r_human.dmi'
|
||||
else
|
||||
icon = 'icons/mob/human_races/r_human.dmi'
|
||||
|
||||
if(dna)
|
||||
switch(dna.mutantrace)
|
||||
if("lizard","golem","slime","shadow","adamantine")
|
||||
if("golem","slime","shadow","adamantine")
|
||||
overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_l")
|
||||
overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_s")
|
||||
if("lizard","tajaran","skrell")
|
||||
overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.mutantrace]_[gender]_l")
|
||||
overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.mutantrace]_[gender]_s")
|
||||
// if("lizard","tajaran","skrell")
|
||||
// overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.mutantrace]_[gender]_l")
|
||||
// overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.mutantrace]_[gender]_s")
|
||||
if("plant")
|
||||
if(stat == DEAD) //TODO
|
||||
overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace]_d")
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
//Disabilities
|
||||
handle_disabilities()
|
||||
|
||||
//Virus updates, duh
|
||||
handle_virus_updates()
|
||||
|
||||
//Apparently, the person who wrote this code designed it so that
|
||||
//blinded get reset each cycle and then get activated later in the
|
||||
//code. Very ugly. I dont care. Moving this stuff here so its easy
|
||||
@@ -147,6 +150,28 @@
|
||||
emote("gasp")
|
||||
updatehealth()
|
||||
|
||||
proc/handle_virus_updates()//copypaste from mob/carbon/human/life.dm
|
||||
if(bodytemperature > 406)
|
||||
for(var/datum/disease/D in viruses)
|
||||
D.cure()
|
||||
if(!virus2)
|
||||
for(var/obj/effect/decal/cleanable/blood/B in view(1,src))
|
||||
if(B.virus2 && get_infection_chance())
|
||||
infect_virus2(src,B.virus2)
|
||||
for(var/obj/effect/decal/cleanable/mucus/M in view(1,src))
|
||||
if(M.virus2 && get_infection_chance())
|
||||
infect_virus2(src,M.virus2)
|
||||
else
|
||||
if(isnull(virus2)) // Trying to figure out a runtime error that keeps repeating
|
||||
CRASH("virus2 nulled before calling activate()")
|
||||
else
|
||||
virus2.activate(src)
|
||||
|
||||
// activate may have deleted the virus
|
||||
if(!virus2) return
|
||||
|
||||
// check if we're immune
|
||||
if(virus2.antigen & src.antibodies) virus2.dead = 1
|
||||
|
||||
proc/breathe()
|
||||
if(reagents)
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
|
||||
/mob/living/silicon/robot/proc/updatename(var/prefix as text)
|
||||
|
||||
if(istype(mmi, /obj/item/device/posibrain))
|
||||
if(istype(mmi, /obj/item/device/mmi/posibrain))
|
||||
braintype = "Android"
|
||||
else
|
||||
braintype = "Cyborg"
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
/mob/living/simple_animal/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
|
||||
if(istype(O, /obj/item/device/mmi) || istype(O, /obj/item/device/posibrain))
|
||||
if(istype(O, /obj/item/device/mmi) || istype(O, /obj/item/device/mmi/posibrain))
|
||||
var/obj/item/device/mmi/B = O
|
||||
if(src.mmi) //There's already a brain in it.
|
||||
user << "\red There's already a brain in [src]!"
|
||||
@@ -284,14 +284,14 @@
|
||||
return 0
|
||||
|
||||
if(istype(held_item, /obj/item/weapon/grenade))
|
||||
visible_message("\red [src] launches the [held_item]!", "\red You launch the [held_item]!", "You hear a skittering noise and a thump!")
|
||||
visible_message("\red [src] launches \the [held_item]!", "\red You launch \the [held_item]!", "You hear a skittering noise and a thump!")
|
||||
var/obj/item/weapon/grenade/G = held_item
|
||||
G.loc = src.loc
|
||||
G.prime()
|
||||
held_item = null
|
||||
return 1
|
||||
|
||||
visible_message("\blue [src] drops the [held_item]!", "\blue You drop the [held_item]!", "You hear a skittering noise and a soft thump.")
|
||||
visible_message("\blue [src] drops \the [held_item]!", "\blue You drop \the [held_item]!", "You hear a skittering noise and a soft thump.")
|
||||
|
||||
held_item.loc = src.loc
|
||||
held_item = null
|
||||
@@ -308,7 +308,7 @@
|
||||
return -1
|
||||
|
||||
if(held_item)
|
||||
src << "\red You are already holding the [held_item]"
|
||||
src << "\red You are already holding \the [held_item]"
|
||||
return 1
|
||||
|
||||
var/list/items = list()
|
||||
@@ -318,16 +318,14 @@
|
||||
|
||||
var/obj/selection = input("Select an item.", "Pickup") in items
|
||||
|
||||
items.Cut()
|
||||
if(selection)
|
||||
for(var/obj/item/I in view(1, src))
|
||||
if(selection == I)
|
||||
held_item = selection
|
||||
selection.loc = src
|
||||
visible_message("\blue [src] scoops up the [held_item]!", "\blue You grab the [held_item]!", "You hear a skittering noise and a clink.")
|
||||
visible_message("\blue [src] scoops up \the [held_item]!", "\blue You grab \the [held_item]!", "You hear a skittering noise and a clink.")
|
||||
return held_item
|
||||
else
|
||||
src << "\red \The [selection] is too far away."
|
||||
src << "\red \The [selection] is too far away."
|
||||
|
||||
src << "\red There is nothing of interest to take."
|
||||
return 0
|
||||
@@ -335,4 +333,4 @@
|
||||
/mob/living/simple_animal/spiderbot/examine()
|
||||
..()
|
||||
if(src.held_item)
|
||||
usr << "It is carrying \a [src.held_item] \icon[src.held_item]."
|
||||
usr << "It is carrying \a [src.held_item] \icon[src.held_item]."
|
||||
|
||||
@@ -224,9 +224,11 @@
|
||||
return "[emote], \"[text]\""
|
||||
return "says, \"[text]\"";
|
||||
|
||||
/mob/living/simple_animal/emote(var/act)
|
||||
/mob/living/simple_animal/emote(var/act, var/type, var/desc)
|
||||
if(act)
|
||||
if(act == "scream") act = "makes a loud and pained whimper" //ugly hack to stop animals screaming when crushed :P
|
||||
if(act == "me") //Allow me-emotes.
|
||||
act = desc
|
||||
if( findtext(act,".",lentext(act)) == 0 && findtext(act,"!",lentext(act)) == 0 && findtext(act,"?",lentext(act)) == 0 )
|
||||
act = addtext(act,".") //Makes sure all emotes end with a period.
|
||||
for (var/mob/O in viewers(src, null))
|
||||
|
||||
@@ -129,7 +129,10 @@
|
||||
return
|
||||
|
||||
if(client.prefs.species != "Human")
|
||||
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
|
||||
|
||||
var/S = client.prefs.species
|
||||
if(S == "Unathi") S = "Soghun"
|
||||
if(!is_alien_whitelisted(src, S) && config.usealienwhitelist)
|
||||
src << alert("You are currently not whitelisted to play [client.prefs.species].")
|
||||
return 0
|
||||
|
||||
@@ -144,7 +147,9 @@
|
||||
usr << "\blue There is an administrative lock on entering the game!"
|
||||
return
|
||||
|
||||
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
|
||||
var/S = client.prefs.species
|
||||
if(S == "Unathi") S = "Soghun"
|
||||
if(!is_alien_whitelisted(src, S) && config.usealienwhitelist)
|
||||
src << alert("You are currently not whitelisted to play [client.prefs.species].")
|
||||
return 0
|
||||
|
||||
@@ -286,13 +291,9 @@
|
||||
proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank)
|
||||
if (ticker.current_state == GAME_STATE_PLAYING)
|
||||
var/obj/item/device/radio/intercom/a = new /obj/item/device/radio/intercom(null)// BS12 EDIT Arrivals Announcement Computer, rather than the AI.
|
||||
|
||||
//unlikely for this to be an issue, but just in case
|
||||
if(istype(character.wear_id, /obj/item/weapon/card/id))
|
||||
var/obj/item/weapon/card/id/I = character.wear_id
|
||||
a.autosay("\"[character.real_name],[I.assignment ? " [I.assignment]," : "" ] has arrived on the station.\"", "Arrivals Announcement Computer")
|
||||
else
|
||||
a.autosay("\"[character.real_name], visitor, has arrived on the station.\"", "Arrivals Announcement Computer")
|
||||
if(character.mind.role_alt_title)
|
||||
rank = character.mind.role_alt_title
|
||||
a.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] has arrived on the station.", "Arrivals Announcement Computer")
|
||||
del(a)
|
||||
|
||||
proc/LateChoices()
|
||||
@@ -331,15 +332,15 @@
|
||||
new_character.lastarea = get_area(loc)
|
||||
|
||||
if(client.prefs.species == "Tajaran") //This is like the worst, but it works, so meh. - Erthilo
|
||||
if(is_alien_whitelisted(src, "Tajaran") || !config.usealienwhitelist)
|
||||
if(is_alien_whitelisted(src, "Tajaran"|| !config.usealienwhitelist))
|
||||
new_character.dna.mutantrace = "tajaran"
|
||||
new_character.tajaran_talk_understand = 1
|
||||
if(client.prefs.species == "Unathi")
|
||||
if(is_alien_whitelisted(src, "Soghun") || !config.usealienwhitelist)
|
||||
if(is_alien_whitelisted(src, "Soghun"|| !config.usealienwhitelist))
|
||||
new_character.dna.mutantrace = "lizard"
|
||||
new_character.soghun_talk_understand = 1
|
||||
if(client.prefs.species == "Skrell")
|
||||
if(is_alien_whitelisted(src, "Skrell") || !config.usealienwhitelist)
|
||||
if(is_alien_whitelisted(src, "Skrell"|| !config.usealienwhitelist))
|
||||
new_character.dna.mutantrace = "skrell"
|
||||
new_character.skrell_talk_understand = 1
|
||||
|
||||
|
||||
@@ -135,37 +135,34 @@ datum/preferences
|
||||
|
||||
var/g = "m"
|
||||
if(gender == FEMALE) g = "f"
|
||||
if(species == "Tajaran")
|
||||
preview_icon = new /icon('icons/effects/species.dmi', "tajaran_[g]_s")
|
||||
preview_icon.Blend(new /icon('icons/effects/species.dmi', "tajtail_s"), ICON_OVERLAY)
|
||||
else if(species == "Unathi")
|
||||
preview_icon = new /icon('icons/effects/species.dmi', "lizard_[g]_s")
|
||||
preview_icon.Blend(new /icon('icons/effects/species.dmi', "sogtail_s"), ICON_OVERLAY)
|
||||
else if(species == "Skrell")
|
||||
preview_icon = new /icon('icons/effects/species.dmi', "skrell_[g]_s")
|
||||
else
|
||||
preview_icon = new /icon('human.dmi', "torso_[g]_s")
|
||||
|
||||
preview_icon.Blend(new /icon('human.dmi', "chest_[g]_s"), ICON_OVERLAY)
|
||||
var/icon/icobase
|
||||
switch(species)
|
||||
if("Tajaran")
|
||||
icobase = 'icons/mob/human_races/r_tajaran.dmi'
|
||||
if("Unathi")
|
||||
icobase = 'icons/mob/human_races/r_lizard.dmi'
|
||||
if("Skrell")
|
||||
icobase = 'icons/mob/human_races/r_skrell.dmi'
|
||||
else
|
||||
icobase = 'icons/mob/human_races/r_human.dmi'
|
||||
preview_icon = new /icon(icobase, "torso_[g]")
|
||||
preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY)
|
||||
preview_icon.Blend(new /icon(icobase, "head_[g]"), ICON_OVERLAY)
|
||||
|
||||
if(organ_data["head"] != "amputated")
|
||||
preview_icon.Blend(new /icon('human.dmi', "head_[g]_s"), ICON_OVERLAY)
|
||||
for(var/name in list("l_arm","r_arm","l_leg","r_leg","l_foot","r_foot","l_hand","r_hand"))
|
||||
// make sure the organ is added to the list so it's drawn
|
||||
if(organ_data[name] == null)
|
||||
organ_data[name] = null
|
||||
|
||||
for(var/name in list("l_arm","r_arm","l_leg","r_leg","l_foot","r_foot","l_hand","r_hand"))
|
||||
// make sure the organ is added to the list so it's drawn
|
||||
if(organ_data[name] == null)
|
||||
organ_data[name] = null
|
||||
for(var/name in organ_data)
|
||||
if(organ_data[name] == "amputated") continue
|
||||
|
||||
for(var/name in organ_data)
|
||||
if(organ_data[name] == "amputated") continue
|
||||
var/icon/temp = new /icon(icobase, "[name]")
|
||||
if(organ_data[name] == "cyborg")
|
||||
temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
|
||||
|
||||
var/icon/temp = new /icon('human.dmi', "[name]_s")
|
||||
if(organ_data[name] == "cyborg")
|
||||
temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
|
||||
|
||||
preview_icon.Blend(temp, ICON_OVERLAY)
|
||||
|
||||
preview_icon.Blend(new /icon('human.dmi', "groin_[g]_s"), ICON_OVERLAY)
|
||||
preview_icon.Blend(temp, ICON_OVERLAY)
|
||||
|
||||
// Skin tone
|
||||
if(species == "Human")
|
||||
|
||||
@@ -25,7 +25,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
for(var/datum/reagent/blood/B in vessel.reagent_list)
|
||||
if(B.id == "blood")
|
||||
B.data = list( "donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.b_type, \
|
||||
"resistances"=null,"trace_chem"=null, "virus2" = null, "antobodies" = null)
|
||||
"resistances"=null,"trace_chem"=null, "virus2" = null, "antibodies" = null)
|
||||
|
||||
// Takes care blood loss and regeneration
|
||||
/mob/living/carbon/human/proc/handle_blood()
|
||||
@@ -165,7 +165,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
B.data["donor"] = src
|
||||
if(src.virus2)
|
||||
B.data["virus2"] = src.virus2.getcopy()
|
||||
B.data["antibodies"] |= src.antibodies
|
||||
B.data["antibodies"] = src.antibodies
|
||||
B.data["blood_DNA"] = copytext(src.dna.unique_enzymes,1,0)
|
||||
if(src.resistances && src.resistances.len)
|
||||
if(B.data["resistances"])
|
||||
@@ -176,8 +176,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
|
||||
var/list/temp_chem = list()
|
||||
for(var/datum/reagent/R in src.reagents.reagent_list)
|
||||
temp_chem += R.name
|
||||
temp_chem[R.name] = R.volume
|
||||
temp_chem += R.id
|
||||
temp_chem[R.id] = R.volume
|
||||
B.data["trace_chem"] = list2params(temp_chem)
|
||||
return B
|
||||
|
||||
@@ -197,9 +197,16 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
reagents.add_reagent("toxin",amount * 0.5)
|
||||
reagents.update_total()
|
||||
else
|
||||
vessel.add_reagent("blood", amount)
|
||||
vessel.add_reagent("blood", amount, injected.data)
|
||||
vessel.update_total()
|
||||
|
||||
var/list/chems = list()
|
||||
chems = params2list(injected.data["trace_chem"])
|
||||
for(var/C in chems)
|
||||
src.reagents.add_reagent(C, (text2num(chems[C]) / 560) * amount)//adds trace chemicals to owner's blood
|
||||
//world << "added [(text2num(chems[C])/560) * amount] = [text2num(chems[C])]/560*[amount] units of [C] to [src]" //DEBUG
|
||||
reagents.update_total()
|
||||
|
||||
container.reagents.remove_reagent("blood", amount)
|
||||
|
||||
//Gets human's own blood.
|
||||
|
||||
@@ -340,6 +340,9 @@
|
||||
P.pixel_y = rand(-7, 7)
|
||||
P.icon_state = "pill"+pillsprite
|
||||
reagents.trans_to(P,50)
|
||||
if(src.loaded_pill_bottle)
|
||||
P.loc = src.loaded_pill_bottle
|
||||
src.updateUsrDialog()
|
||||
else if (href_list["createbottle"])
|
||||
if(!condi)
|
||||
var/name = reject_bad_text(input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()))
|
||||
|
||||
@@ -103,7 +103,7 @@ datum
|
||||
|
||||
|
||||
blood
|
||||
data = new/list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null)
|
||||
data = new/list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null, "antibodies" = null)
|
||||
name = "Blood"
|
||||
id = "blood"
|
||||
reagent_state = LIQUID
|
||||
@@ -122,11 +122,14 @@ datum
|
||||
M.contract_disease(D)
|
||||
else //injected
|
||||
M.contract_disease(D, 1, 0)
|
||||
if(self.data && self.data["virus2"])
|
||||
if(self.data && self.data["virus2"] && istype(M, /mob/living/carbon))//infecting...
|
||||
if(method == TOUCH)
|
||||
infect_virus2(M,self.data["virus2"])
|
||||
else
|
||||
infect_virus2(M,self.data["virus2"],1)
|
||||
if(self.data && self.data["antibodies"] && istype(M, /mob/living/carbon))//... and curing
|
||||
var/mob/living/carbon/C = M
|
||||
C.antibodies |= self.data["antibodies"]
|
||||
|
||||
|
||||
|
||||
@@ -1693,6 +1696,13 @@ datum
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
holywater
|
||||
name = "Holy Water"
|
||||
id = "holywater"
|
||||
description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen."
|
||||
reagent_state = LIQUID
|
||||
color = "#535E66" // rgb: 83, 94, 102
|
||||
|
||||
nanites
|
||||
name = "Nanomachines"
|
||||
id = "nanites"
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
var/slices_num
|
||||
|
||||
//Placeholder for effect that trigger on eating that aren't tied to reagents.
|
||||
/obj/item/weapon/reagent_containers/food/snacks/proc/On_Consume()
|
||||
/obj/item/weapon/reagent_containers/food/snacks/proc/On_Consume(var/mob/M)
|
||||
if(!usr) return
|
||||
if(!reagents.total_volume)
|
||||
usr.visible_message("<span class='notice'>[usr] finishes eating [src].</span>","<span class='notice'>You finish eating [src].</span>")
|
||||
if(M == usr)
|
||||
usr << "<span class='notice'>You finish eating \the [src].</span>"
|
||||
usr.visible_message("<span class='notice'>[usr] finishes eating \the [src].</span>")
|
||||
usr.drop_from_inventory(src) //so icons update :[
|
||||
|
||||
if(trash)
|
||||
@@ -90,7 +92,7 @@
|
||||
else
|
||||
reagents.trans_to(M, reagents.total_volume)
|
||||
bitecount++
|
||||
On_Consume()
|
||||
On_Consume(M)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
@@ -207,15 +207,15 @@
|
||||
|
||||
if (target != user && target.getarmor(target_zone, "melee") > 5 && prob(50))
|
||||
for(var/mob/O in viewers(world.view, user))
|
||||
O.show_message(text("\red <B>[user] tries to stab [target] in the [hit_area] with [src.name], but the attack is deflected by armor!</B>"), 1)
|
||||
O.show_message(text("\red <B>[user] tries to stab [target] in \the [hit_area] with [src.name], but the attack is deflected by armor!</B>"), 1)
|
||||
user.u_equip(src)
|
||||
del(src)
|
||||
return
|
||||
|
||||
for(var/mob/O in viewers(world.view, user))
|
||||
O.show_message(text("\red <B>[user] stabs [target] in the [hit_area] with [src.name]!</B>"), 1)
|
||||
O.show_message(text("\red <B>[user] stabs [target] in \the [hit_area] with [src.name]!</B>"), 1)
|
||||
|
||||
if(affecting.take_damage(7))
|
||||
if(affecting.take_damage(3))
|
||||
target:UpdateDamageIcon()
|
||||
|
||||
else
|
||||
|
||||
@@ -22,16 +22,20 @@
|
||||
usr << "\blue [syringes.len] / [max_syringes] syringes."
|
||||
|
||||
attackby(obj/item/I as obj, mob/user as mob)
|
||||
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/syringe))
|
||||
if(syringes.len < max_syringes)
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
syringes += I
|
||||
user << "\blue You put the syringe in [src]."
|
||||
user << "\blue [syringes.len] / [max_syringes] syringes."
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = I
|
||||
if(S.mode != 2)//SYRINGE_BROKEN in syringes.dm
|
||||
if(syringes.len < max_syringes)
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
syringes += I
|
||||
user << "\blue You put the syringe in [src]."
|
||||
user << "\blue [syringes.len] / [max_syringes] syringes."
|
||||
else
|
||||
usr << "\red [src] cannot hold more syringes."
|
||||
else
|
||||
usr << "\red [src] cannot hold more syringes."
|
||||
usr << "\red This syringe is broken!"
|
||||
|
||||
|
||||
afterattack(obj/target, mob/user , flag)
|
||||
if(!isturf(target.loc) || target == user) return
|
||||
|
||||
@@ -33,19 +33,19 @@
|
||||
return 0
|
||||
|
||||
//these three procs overriden to play different sounds
|
||||
/obj/mecha/mechturn(direction)
|
||||
/obj/mecha/working/hoverpod/mechturn(direction)
|
||||
dir = direction
|
||||
//playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return 1
|
||||
|
||||
/obj/mecha/mechstep(direction)
|
||||
/obj/mecha/working/hoverpod/mechstep(direction)
|
||||
var/result = step(src,direction)
|
||||
if(result)
|
||||
playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return result
|
||||
|
||||
|
||||
/obj/mecha/mechsteprand()
|
||||
/obj/mecha/working/hoverpod/mechsteprand()
|
||||
var/result = step_rand(src)
|
||||
if(result)
|
||||
playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/target_scan_ticks = 60
|
||||
var/report_num = 0
|
||||
var/scan_process = 0
|
||||
var/heat_accumulation_rate = 1
|
||||
var/heat_accumulation_rate = 0.25
|
||||
var/temperature = 273 //measured in kelvin, if this exceeds 1200, the machine is damaged and requires repairs
|
||||
//if this exceeds 600 and safety is enabled it will shutdown
|
||||
//temp greater than 600 also requires a safety prompt to initiate scanning
|
||||
|
||||
@@ -312,7 +312,7 @@
|
||||
the the denser clumps of matter out of the refined sample. This is done by mixing 1 part lithium, 2 parts sodium, 1 part tungsten, 4 parts oxygen.</li>
|
||||
<li><b>Mix separator with sample</b> - The resulting mixture is very close to the final product, but make sure to extract any leftover reagents and
|
||||
the chemical waste byproduct.</li>
|
||||
<li><b>Bring sample to boil</b> - Using a standard bunsen burner, bring the mixture to a boil to vaporise the remaining unwanted matter. Remember
|
||||
<li><b>Bring sample to boil</b> - Using a standard bunsen burner, bring the mixture containing at least 5u of DST to a boil to vaporise the remaining unwanted matter. Remember
|
||||
to again clear out any waste byproducts.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
@@ -411,3 +411,65 @@
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/stasis
|
||||
name = "Cellular suspension, the new Cryogenics?"
|
||||
icon_state = "stasis"
|
||||
author = "Elvin Schmidt"
|
||||
title = "Cellular suspension, the new Cryogenics?"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Forward">Forward: A replacement for cryosleep?</a></li>
|
||||
<li><a href="#Development">The breakthrough</a></li>
|
||||
<li><a href="#Application">Applying this new principle</a></li>
|
||||
</ol>
|
||||
<br>
|
||||
<h1><a name="Forward">Forward: A replacement for cryosleep?</a></h1>
|
||||
The development of rudimentary cryofreezing in the 20th and 21st centuries was hailed as a crank science by some, but many early visionaries recognised the
|
||||
potential it had to change the way we approach so many fields, such as medicine, therapeutics and space travel. It was breakthroughs in the field in the 22nd and
|
||||
later centures that turned the procedure from science fiction to science fact, however. Since then, cryogenics has become a hallmark of modern science, and
|
||||
regarded as one of the great achievements of our era. As with all sciences however, they have their time and are superseded by newer technological miracles when
|
||||
it is over.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Development">The breakthrough</a></h1>
|
||||
It was in examining the effects of decellerated, blue-space high energy particles when transphased through bluespace that the effects where primarily noticed.
|
||||
Due to exigent properties of that dimension, transphasing those particles capable of existing in bluespace with high stability levels has the effect of bringing
|
||||
some of those effects into realspace. Examining the Hoffman emissions in particular, it was discovered that they exhibited a-entropic behaviour, and in what is
|
||||
now termed the 'Effete Hoffman Principle,' it was found that metastabilising the Hoffman radiation resulted in the effect being applied across other physical
|
||||
interactions, in particular forces and reactions.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Application">Applying this new principle</a></h1>
|
||||
When combined with an appropriate energy-effect replicate for cryogenics (slowing down biological activity, thus stabilising the organics), the effect is
|
||||
effectively identical to cryogenics, and while it consumes vastly more power and requires extremely complex equipment, it's (for all intents and purposes) superior
|
||||
to cryogenics, all that remains is to 'commercialise' the process by enabling cheaper development and mass production.<br>
|
||||
The Effete Hoffman Principle can be tweak-combined with other effects however, for different purposes. A division of PMC Research initially developed the application
|
||||
in prisons as a literal 'suspension field' where convincts are held immobile in the air, and the use quickly spread to numerous other areas.<br>
|
||||
<br>
|
||||
By examining the material resonance properties of certain strong waveforms when combined with Hoffman radiation, an effect was produced able to reverse energy
|
||||
transferral through matter, and to slow the effects of gravity. When combined with energy repulse technology, the triple effects compound themselves into a much
|
||||
stronger field, although all three componenets do slightly different things. High energy researchers assure me of the following key points:<br>
|
||||
<ol>
|
||||
<li>The energy repulsion factor provides a 'shell' capable of weak suspension.</li>
|
||||
<li>The Hoffman emissions nullify energy transferral and other kinetic activity, maintaining stability inside the field.</li>
|
||||
<li>The resonant waveform combines the effects of the above two points, and applies it magnified onto it's synched 'resonance' materials.</li>
|
||||
</ol>
|
||||
As an interesting aside, a carbon waveform was chosen for the field in prison suspension fields, due to it's resonance with organic matter.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
new /obj/item/weapon/book/manual/materials_chemistry_analysis(src)
|
||||
new /obj/item/weapon/book/manual/anomaly_testing(src)
|
||||
new /obj/item/weapon/book/manual/anomaly_spectroscopy(src)
|
||||
new /obj/item/weapon/book/manual/stasis(src)
|
||||
update_icon()
|
||||
|
||||
//---- Lockers and closets
|
||||
@@ -85,7 +86,6 @@
|
||||
icon_closed = "toolcloset"
|
||||
icon_opened = "toolclosetopen"
|
||||
|
||||
|
||||
New()
|
||||
..()
|
||||
sleep(2)
|
||||
@@ -99,10 +99,11 @@
|
||||
new /obj/item/device/radio/beacon(src)
|
||||
new /obj/item/clothing/glasses/meson(src)
|
||||
new /obj/item/weapon/pickaxe(src)
|
||||
new /obj/item/device/measuring_tape(src)
|
||||
return
|
||||
|
||||
//---- Isolation room air alarms
|
||||
|
||||
/obj/machinery/alarm/isolation
|
||||
name = "Isolation room air control"
|
||||
req_access = list(access_research)
|
||||
req_access = list(access_research)
|
||||
|
||||
@@ -82,13 +82,14 @@
|
||||
dat += "<hr>"
|
||||
if(!locked)
|
||||
dat += "<b>Select field mode</b><br>"
|
||||
dat += "[field_type=="carbon"?"<b>":"" ]<A href='?src=\ref[src];select_field=carbon'>Diffracted CO2 laser</A></b><br>"
|
||||
dat += "[field_type=="carbon"?"<b>":"" ]<A href='?src=\ref[src];select_field=carbon'>Diffracted carbon dioxide laser</A></b><br>"
|
||||
dat += "[field_type=="nitrogen"?"<b>":"" ]<A href='?src=\ref[src];select_field=nitrogen'>Nitrogen tracer field</A></b><br>"
|
||||
dat += "[field_type=="potassium"?"<b>":"" ]<A href='?src=\ref[src];select_field=potassium'>Potassium refrigerant cloud</A></b><br>"
|
||||
dat += "[field_type=="mercury"?"<b>":"" ]<A href='?src=\ref[src];select_field=mercury'>Mercury dispersion wave</A></b><br>"
|
||||
dat += "[field_type=="iron"?"<b>":"" ]<A href='?src=\ref[src];select_field=iron'>Iron wafer conduction field</A></b><br>"
|
||||
dat += "[field_type=="calcium"?"<b>":"" ]<A href='?src=\ref[src];select_field=calcium'>Calcium binary deoxidiser</A></b><br>"
|
||||
dat += "[field_type=="plasma"?"<b>":"" ]<A href='?src=\ref[src];select_field=chlorine'>Plasma saturated field</A></b><br>"
|
||||
dat += "[field_type=="plasma"?"<b>":"" ]<A href='?src=\ref[src];select_field=chlorine'>Chlorine diffusion emissions</A></b><br>"
|
||||
dat += "[field_type=="plasma"?"<b>":"" ]<A href='?src=\ref[src];select_field=plasma'>Plasma saturated field</A></b><br>"
|
||||
else
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
@@ -260,6 +261,9 @@
|
||||
if("plasma")
|
||||
success = 1
|
||||
//
|
||||
if("calcium")
|
||||
success = 1
|
||||
//
|
||||
if("iron")
|
||||
success = 1
|
||||
for(var/mob/living/silicon/R in T)
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
excavation_amount = 5
|
||||
drill_sound = 'sound/items/Screwdriver.ogg'
|
||||
drill_verb = "delicately picking"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/weapon/pickaxe/six_pick
|
||||
name = "1/1 pick"
|
||||
@@ -118,6 +119,7 @@
|
||||
"/obj/item/weapon/pickaxe/six_pick",\
|
||||
"/obj/item/weapon/pickaxe/hand")
|
||||
max_combined_w_class = 20
|
||||
max_w_class = 4
|
||||
use_to_pickup = 1 // for picking up broken bulbs, not that most people will try
|
||||
|
||||
/obj/item/weapon/storage/box/excavation/New()
|
||||
|
||||
Reference in New Issue
Block a user