mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-08-24 14:36:14 +01:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
// the laser beam
|
||||
|
||||
|
||||
/obj/beam/laser
|
||||
name = "laser beam"
|
||||
icon = 'beam.dmi'
|
||||
icon_state = "full"
|
||||
density = 0
|
||||
mouse_opacity = 0
|
||||
|
||||
flags = TABLEPASS
|
||||
|
||||
var/wavelength // the (vaccuum) wavelength of the beam
|
||||
var/width = 1 // 1=thin, 2=medium, 3=wide
|
||||
|
||||
var/obj/beam/laser/next
|
||||
var/obj/beam/laser/prev
|
||||
var/obj/master
|
||||
|
||||
New(var/atom/newloc, var/dirn, var/lambda, var/omega=1, var/half=0)
|
||||
|
||||
if(!isturf(loc))
|
||||
return
|
||||
|
||||
//boutput(world, "creating beam at ([newloc.x],[newloc.y]) with [dirn] [lambda] [omega] [half]")
|
||||
|
||||
icon_state = "[omega]-[half ? "half" : "full"]"
|
||||
dir = dirn
|
||||
set_wavelength(lambda)
|
||||
..(newloc)
|
||||
spawn(0)
|
||||
src.propagate()
|
||||
src.verbs -= /atom/movable/verb/pull
|
||||
|
||||
|
||||
|
||||
proc/propagate()
|
||||
var/turf/T = get_step(src, dir)
|
||||
if(T)
|
||||
if(T.Enter(src))
|
||||
next = new(T, dir, wavelength, width, 0)
|
||||
next.prev = src
|
||||
next.master = src.master
|
||||
else
|
||||
spawn(5)
|
||||
propagate()
|
||||
|
||||
|
||||
proc/remove()
|
||||
if(next)
|
||||
next.remove()
|
||||
qdel(src)
|
||||
|
||||
|
||||
|
||||
proc/blocked(var/atom/A)
|
||||
return density || opacity
|
||||
/*
|
||||
/turf/Enter(atom/movable/mover as mob|obj)
|
||||
if (!mover || !isturf(mover.loc))
|
||||
return 1
|
||||
|
||||
|
||||
//First, check objects to block exit that are not on the border
|
||||
for(var/obj/obstacle in mover.loc)
|
||||
if((obstacle.flags & ~ON_BORDER) && (mover != obstacle) && (forget != obstacle))
|
||||
if(!obstacle.CheckExit(mover, src))
|
||||
mover.Bump(obstacle, 1)
|
||||
return 0
|
||||
|
||||
//Now, check objects to block exit that are on the border
|
||||
for(var/obj/border_obstacle in mover.loc)
|
||||
if((border_obstacle.flags & ON_BORDER) && (mover != border_obstacle) && (forget != border_obstacle))
|
||||
if(!border_obstacle.CheckExit(mover, src))
|
||||
mover.Bump(border_obstacle, 1)
|
||||
return 0
|
||||
|
||||
//Next, check objects to block entry that are on the border
|
||||
for(var/obj/border_obstacle in src)
|
||||
if(border_obstacle.flags & ON_BORDER)
|
||||
if(!border_obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != border_obstacle))
|
||||
mover.Bump(border_obstacle, 1)
|
||||
return 0
|
||||
|
||||
//Then, check the turf itself
|
||||
if (!src.CanPass(mover, src))
|
||||
mover.Bump(src, 1)
|
||||
return 0
|
||||
|
||||
//Finally, check objects/mobs to block entry that are not on the border
|
||||
for(var/atom/movable/obstacle in src)
|
||||
if(obstacle.flags & ~ON_BORDER)
|
||||
if(!obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != obstacle))
|
||||
mover.Bump(obstacle, 1)
|
||||
return 0
|
||||
return 1 //Nothing found to block so return success!
|
||||
*/
|
||||
|
||||
|
||||
HasEntered(var/atom/movable/AM)
|
||||
if(istype(AM, /obj/beam))
|
||||
return
|
||||
if(blocked(AM))
|
||||
remove(src)
|
||||
if(prev)
|
||||
prev.propagate()
|
||||
else if(master)
|
||||
master:turn_on()
|
||||
|
||||
proc/set_wavelength(var/lambda)
|
||||
|
||||
var/w = round(lambda,1) // integer wavelength
|
||||
wavelength = lambda
|
||||
// first look for cached version of the icon at this wavelength
|
||||
var/icon/cached = beam_icons["[w]"]
|
||||
if(cached)
|
||||
icon = cached
|
||||
|
||||
return
|
||||
|
||||
// no cached version, so generate a new one
|
||||
|
||||
// this maps a wavelength in the range 380-780 nm to an R,G,B,A value
|
||||
var/red = 0
|
||||
var/green = 0
|
||||
var/blue = 0
|
||||
var/alpha = 0
|
||||
|
||||
switch(w)
|
||||
if(380 to 439)
|
||||
red = (440-w) / 60
|
||||
green = 0
|
||||
blue = 1
|
||||
if(440 to 489)
|
||||
red = 0
|
||||
green = (w-440) / 50
|
||||
blue = 1
|
||||
if(490 to 509)
|
||||
red = 0
|
||||
green = 1
|
||||
blue = (510 - w) / 20
|
||||
if(510 to 579)
|
||||
red = (w-510) / 70
|
||||
green = 1
|
||||
blue = 0
|
||||
if(580 to 644)
|
||||
red = 1
|
||||
green = (645-w) / 65
|
||||
blue = 0
|
||||
if(645 to 780)
|
||||
red = 1
|
||||
green = 0
|
||||
blue = 0
|
||||
|
||||
// colour is done, now calculate intensity
|
||||
switch(w)
|
||||
if(380 to 419)
|
||||
alpha = 0.75*(w-380)/40
|
||||
if(420 to 700)
|
||||
alpha = 0.75
|
||||
if(701 to 780)
|
||||
alpha = 0.75*(780-w)/80
|
||||
|
||||
// remap alpha by intensity gamma
|
||||
if(alpha != 0)
|
||||
alpha = alpha**0.80
|
||||
|
||||
var/icon/I = icon('beam.dmi')
|
||||
I.MapColors(red,0,0,0, 0,green,0,0, 0,0,blue,0, 0,0,0,alpha, 0,0,0,0)
|
||||
icon = I
|
||||
|
||||
beam_icons["[w]"] = I
|
||||
|
||||
|
||||
|
||||
// global cache of beam icons
|
||||
// this is an assoc list mapping (integer) wavelength to icons
|
||||
|
||||
var/list/beam_icons = new()
|
||||
@@ -0,0 +1,113 @@
|
||||
/obj/beam/custom
|
||||
var/obj/item/lens/lens = null
|
||||
|
||||
|
||||
/obj/machinery/industrial_laser
|
||||
name = "industrial laser"
|
||||
desc = "An industrial laser beam emitter."
|
||||
icon = 'icons/obj/machines/fusion.dmi'
|
||||
icon_state = "laser-premade"
|
||||
var/obj/item/lens/lens = null
|
||||
var/obj/beam/custom/beam = null
|
||||
var/setup_beam_length = 48
|
||||
|
||||
New ()
|
||||
..()
|
||||
if (!src.lens)
|
||||
src.lens = new/obj/item/lens(src)
|
||||
|
||||
disposing()
|
||||
if (src.beam)
|
||||
src.beam.dispose()
|
||||
src.beam = null
|
||||
..()
|
||||
|
||||
process()
|
||||
if (stat & BROKEN)
|
||||
if (src.beam)
|
||||
src.beam.dispose()
|
||||
return
|
||||
power_usage = 1000
|
||||
..()
|
||||
if (stat & NOPOWER)
|
||||
if (src.beam)
|
||||
src.beam.dispose()
|
||||
return
|
||||
|
||||
use_power(power_usage)
|
||||
|
||||
if (!src.beam)
|
||||
var/turf/beamTurf = get_step(src, src.dir)
|
||||
if (!istype(beamTurf) || beamTurf.density)
|
||||
return
|
||||
src.beam = new /obj/beam/custom(beamTurf, setup_beam_length)
|
||||
src.beam.dir = src.dir
|
||||
src.beam.lens = src.lens
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
power_change()
|
||||
if(powered())
|
||||
stat &= ~NOPOWER
|
||||
src.update_icon()
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
stat |= NOPOWER
|
||||
src.update_icon()
|
||||
|
||||
ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
//dispose()
|
||||
src.dispose()
|
||||
return
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
src.stat |= BROKEN
|
||||
src.update_icon()
|
||||
if(3.0)
|
||||
if (prob(25))
|
||||
src.stat |= BROKEN
|
||||
src.update_icon()
|
||||
else
|
||||
return
|
||||
|
||||
proc
|
||||
update_icon()
|
||||
if (stat & (NOPOWER|BROKEN))
|
||||
//src.icon_state = "heptemitter-p"
|
||||
if (src.beam)
|
||||
//qdel(src.beam)
|
||||
src.beam.dispose()
|
||||
//else
|
||||
//src.icon_state = "heptemitter[src.beam ? "1" : "0"]"
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/machinery/beamline
|
||||
name = "beamline component"
|
||||
desc = "Some sort of heavy machinery for use with a heavy laser setup."
|
||||
icon = 'icons/obj/machines/beamline64x32.dmi'
|
||||
icon_state = "beamline"
|
||||
|
||||
|
||||
bullet_act()
|
||||
// todo: write in a system for these to react to laser shots
|
||||
return
|
||||
|
||||
/obj/machinery/beamline/amplifier
|
||||
name = "beamline amplifier"
|
||||
desc = "Supercharges lasers that pass through it."
|
||||
icon = 'icons/obj/machines/beamline64x32.dmi'
|
||||
icon_state = "amplifier-0"
|
||||
|
||||
/obj/machinery/beamline/spectrometer
|
||||
name = "spectrometer"
|
||||
desc = "A huge mass spectrometer that works with laser setups."
|
||||
icon = 'icons/obj/machines/beamline64x32.dmi'
|
||||
icon_state = "spectrometer-0"
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// A laser pointer. Emits a (tunable) low-power laser beam
|
||||
// Used for alignment and testing of the optics system
|
||||
|
||||
/obj/item/device/laser_pointer
|
||||
name = "laser pointer"
|
||||
desc = "A portable low-power laser used for optical system alignment. The label reads: 'Danger: Class IIIa laser device. Avoid direct eye exposure."
|
||||
icon = 'optics.dmi'
|
||||
icon_state = "pointer0"
|
||||
var/on = 0 // true if operating
|
||||
var/wavelength = 632 // operation wavelength (nm)
|
||||
|
||||
var/gain_peak = 632 // gain peak (nm)
|
||||
var/gain_width = 35 // gain bandwidth (nm)
|
||||
var/peak_output = 0.005 // max output 5 mW
|
||||
layer = OBJ_LAYER + 0.1
|
||||
|
||||
w_class = 4
|
||||
m_amt = 500
|
||||
g_amt = 100
|
||||
w_amt = 200
|
||||
|
||||
var/obj/beam/laser/beam // the created beam
|
||||
|
||||
flags = FPRINT | CONDUCT | TABLEPASS
|
||||
|
||||
attack_ai()
|
||||
return
|
||||
|
||||
attack_self(var/mob/user)
|
||||
on = !on
|
||||
if(on)
|
||||
turn_on()
|
||||
else
|
||||
turn_off()
|
||||
|
||||
updateicon()
|
||||
|
||||
verb/rotate()
|
||||
set src in view(1)
|
||||
turn_off()
|
||||
dir = turn(dir, -90)
|
||||
if(on) turn_on()
|
||||
|
||||
Move(var/atom/newloc,var/newdir)
|
||||
. = ..(newloc,newdir)
|
||||
if(on && . && isturf(newloc))
|
||||
turn_off()
|
||||
turn_on()
|
||||
return .
|
||||
|
||||
proc/turn_on()
|
||||
if(!isturf(loc))
|
||||
return
|
||||
|
||||
beam = new(loc, dir, wavelength, 1, 1)
|
||||
beam.master = src
|
||||
|
||||
proc/turn_off()
|
||||
if(beam)
|
||||
beam.remove()
|
||||
|
||||
dropped()
|
||||
turn_off()
|
||||
turn_on()
|
||||
|
||||
proc/updateicon()
|
||||
icon_state = "pointer[on]"
|
||||
@@ -0,0 +1,83 @@
|
||||
// Mirror object
|
||||
// Part of the optics system
|
||||
//
|
||||
// reflects laser beams
|
||||
// 16 directional states 0/22.5/45/67.5deg to allow for 0/45deg beam angles
|
||||
|
||||
|
||||
// ideas:
|
||||
// frame/stand icon w/ mirror directional overlay
|
||||
// two sets of overlay icons for 0/45 and 22.5/67.5 deg angles
|
||||
|
||||
// can rotate cw/acw - need screwdriver to loosen/tighten mirror
|
||||
// use wrench to anchor/unanchor frame
|
||||
// if touched, gets dirty - fingerprints, which reduce reflectivity
|
||||
// if dirty and hit with high-power beam, mirror may shatter
|
||||
// some kind of dust accumulation with HasProximity? Could check for mob w/o labcoat etc.
|
||||
// can clean with acetone+wipes
|
||||
|
||||
/obj/optical/mirror
|
||||
icon = 'optical.dmi'
|
||||
icon_state = "mirrorA"
|
||||
dir = 1
|
||||
desc = "A large, optical-grade mirror firmly mounted on a stand."
|
||||
flags = FPRINT
|
||||
anchored = 0
|
||||
var/rotatable = 0 // true if mirror can be rotated
|
||||
var/angle = 0 // normal of mirror, 0-15. 0=N, 1=NNE, 2=NE, 3=ENE, 4=E etc
|
||||
|
||||
|
||||
New()
|
||||
..()
|
||||
set_angle()
|
||||
|
||||
|
||||
|
||||
//set the angle from icon_state and dir
|
||||
proc/set_angle()
|
||||
switch(dir)
|
||||
if(1)
|
||||
angle = 0
|
||||
if(5)
|
||||
angle = 2
|
||||
if(4)
|
||||
angle = 4
|
||||
if(6)
|
||||
angle = 6
|
||||
if(2)
|
||||
angle = 8
|
||||
if(10)
|
||||
angle = 10
|
||||
if(8)
|
||||
angle = 12
|
||||
if(9)
|
||||
angle = 14
|
||||
|
||||
if(icon_state == "mirrorB") // 22.5deg turned states
|
||||
angle++
|
||||
return
|
||||
|
||||
// set the dir and icon_state from the angle
|
||||
proc/set_dir()
|
||||
if(angle%2 == 1)
|
||||
icon_state = "mirrorB"
|
||||
else
|
||||
icon_state = "mirrorA"
|
||||
switch(round(angle/2)*2)
|
||||
if(0)
|
||||
dir = 1
|
||||
if(2)
|
||||
dir = 5
|
||||
if(4)
|
||||
dir = 4
|
||||
if(6)
|
||||
dir = 6
|
||||
if(8)
|
||||
dir = 2
|
||||
if(10)
|
||||
dir = 10
|
||||
if(12)
|
||||
dir = 8
|
||||
if(14)
|
||||
dir = 9
|
||||
return
|
||||
Reference in New Issue
Block a user