Out of Time

This commit is contained in:
Fox-McCloud
2015-02-03 01:12:00 -05:00
parent 0dab97ab6d
commit fd23cc9861
17 changed files with 477 additions and 0 deletions
@@ -0,0 +1,258 @@
#define CHRONO_BEAM_RANGE 3
#define CHRONO_FRAME_COUNT 22
/obj/item/weapon/chrono_eraser
name = "Timestream Eradication Device"
desc = "The result of outlawed time-bluespace research, this device is capable of wiping a being from the timestream. They never are, they never were, they never will be."
icon = 'icons/obj/chronos.dmi'
icon_state = "chronobackpack"
item_state = "backpack"
w_class = 4.0
slot_flags = SLOT_BACK
slowdown = 1
action_button_name = "Equip/Unequip TED Gun"
icon_action_button = "action_chronobackpack"
var/obj/item/weapon/gun/energy/chrono_gun/PA = null
var/list/erased_minds = list() //a collection of minds from the dead
/obj/item/weapon/chrono_eraser/proc/pass_mind(var/datum/mind/M)
erased_minds += M
/obj/item/weapon/chrono_eraser/dropped()
if(PA)
del(PA)
/obj/item/weapon/chrono_eraser/Destroy()
dropped()
..()
/obj/item/weapon/chrono_eraser/ui_action_click()
var/mob/living/carbon/user = src.loc
if(iscarbon(user) && (user.back == src))
if(PA)
del(PA)
else
PA = new(src)
user.put_in_hands(PA)
/obj/item/weapon/gun/energy/chrono_gun
name = "T.E.D. Projection Apparatus"
desc = "It's as if they never existed in the first place."
icon = 'icons/obj/chronos.dmi'
icon_state = "chronogun"
item_state = "chronogun"
icon_override = 'icons/mob/in-hand/guns.dmi'
w_class = 3.0
canremove = 0
projectile_type = "/obj/item/projectile/energy/chrono_beam"
fire_sound = 'sound/weapons/Laser.ogg'
charge_cost = 0
fire_delay = 50
var/obj/item/weapon/chrono_eraser/TED = null
var/obj/effect/chrono_field/field = null
var/turf/startpos = null
/obj/item/weapon/gun/energy/chrono_gun/New(var/obj/item/weapon/chrono_eraser/T)
. = ..()
if(istype(T))
TED = T
else //admin must have spawned it
TED = new(src.loc)
del(src)
/obj/item/weapon/gun/energy/chrono_gun/dropped()
del(src)
/obj/item/weapon/gun/energy/chrono_gun/update_icon()
return
/obj/item/weapon/gun/energy/chrono_gun/Fire()
if(field)
field_disconnect(field)
..()
/obj/item/weapon/gun/energy/chrono_gun/Destroy()
if(TED)
TED.PA = null
TED = null
if(field)
field_disconnect(field)
..()
/obj/item/weapon/gun/energy/chrono_gun/proc/field_connect(var/obj/effect/chrono_field/F)
var/mob/living/user = src.loc
if(F.gun)
if(isliving(user) && F.captured)
user << "<span class='alert'><b>FAIL: <i>[F.captured]</i> already has an existing connection.</b></span>"
src.field_disconnect(F)
else
startpos = get_turf(src)
field = F
F.gun = src
if(isliving(user) && F.captured)
user << "<span class='notice'>Connection established with target: <b>[F.captured]</b></span>"
/obj/item/weapon/gun/energy/chrono_gun/proc/field_disconnect(var/obj/effect/chrono_field/F)
if(F && field == F)
var/mob/living/user = src.loc
if(F.gun == src)
F.gun = null
if(isliving(user) && F.captured)
user << "<span class='alert'>Disconnected from target: <b>[F.captured]</b></span>"
field = null
startpos = null
/obj/item/weapon/gun/energy/chrono_gun/proc/field_check(var/obj/effect/chrono_field/F)
if(F)
if(field == F)
var/turf/currentpos = get_turf(src)
var/mob/living/user = src.loc
if((currentpos == startpos) && (field in view(CHRONO_BEAM_RANGE, currentpos)) && !user.lying && (user.stat == CONSCIOUS))
return 1
field_disconnect(F)
return 0
/obj/item/weapon/gun/energy/chrono_gun/proc/pass_mind(var/datum/mind/M)
if(TED)
TED.pass_mind(M)
/obj/item/projectile/energy/chrono_beam
name = "eradication beam"
icon_state = "chronobolt"
range = CHRONO_BEAM_RANGE
color = null
nodamage = 1
var/obj/item/weapon/gun/energy/chrono_gun/gun = null
/obj/item/projectile/energy/chrono_beam/process()
gun = firer.get_active_hand()
if(istype(gun))
return ..()
else
return 0
/obj/item/projectile/energy/chrono_beam/on_hit(var/atom/target)
if(target && gun && isliving(target))
var/obj/effect/chrono_field/F = new(target.loc, target, gun)
gun.field_connect(F)
/obj/effect/chrono_field
name = "eradication field"
desc = "An aura of time-bluespace energy."
icon = 'icons/effects/effects.dmi'
icon_state = "chronofield"
density = 1
anchored = 1
unacidable = 1
blend_mode = BLEND_MULTIPLY
var/mob/living/captured = null
var/obj/item/weapon/gun/energy/chrono_gun/gun = null
var/tickstokill = 30
var/image/mob_underlay = null
var/preloaded = 0
var/RPpos = null
/obj/effect/chrono_field/New(loc, var/mob/living/target, var/obj/item/weapon/gun/energy/chrono_gun/G)
if(target && isliving(target) && G)
target.loc = src
src.captured = target
var/icon/mob_snapshot = getFlatIcon(target)
var/icon/cached_icon = new()
for(var/i=1, i<=CHRONO_FRAME_COUNT, i++)
var/icon/removing_frame = icon('icons/obj/chronos.dmi', "erasing", SOUTH, i)
var/icon/mob_icon = icon(mob_snapshot)
mob_icon.Blend(removing_frame, ICON_MULTIPLY)
cached_icon.Insert(mob_icon, "frame[i]")
mob_underlay = new(cached_icon, "frame1")
update_icon()
desc = initial(desc) + "<br><span class='info'>It appears to contain [target.name].</span>"
processing_objects.Add(src)
/obj/effect/chrono_field/Destroy()
if(gun && gun.field_check(src))
gun.field_disconnect(src)
..()
/obj/effect/chrono_field/update_icon()
var/ttk_frame = 1 - (tickstokill / initial(tickstokill))
ttk_frame = Clamp(Ceiling(ttk_frame * CHRONO_FRAME_COUNT), 1, CHRONO_FRAME_COUNT)
if(ttk_frame != RPpos)
RPpos = ttk_frame
mob_underlay.icon_state = "frame[RPpos]"
underlays = list() //hack: BYOND refuses to update the underlay to match the icon_state otherwise
underlays += mob_underlay
/obj/effect/chrono_field/process()
if(captured)
if(tickstokill > initial(tickstokill))
for(var/atom/movable/AM in contents)
AM.loc = loc
del(src)
else if(tickstokill <= 0)
captured << "<span class='boldnotice'>As the last essence of your being is erased from time, you begin to re-experience your most enjoyable memory. You feel happy...</span>"
var/mob/dead/observer/ghost = captured.ghostize(1)
if(captured.mind)
if(ghost)
ghost.mind = null
if(gun)
gun.pass_mind(captured.mind)
del(captured)
del(src)
else
captured.Paralyse(4)
if(captured.reagents)
captured.reagents.del_reagent("synaptizine") //you pesky thing you
if(captured.loc != src) //If they manage to escape, immediately kill them, this is so that even if there IS a way to get out, they won't use it
captured.loc = src
tickstokill = 0
return .()
update_icon()
if(gun)
if(gun.field_check(src))
tickstokill--
else
gun = null
return .()
else
tickstokill++
else
del(src)
/obj/effect/chrono_field/bullet_act(var/obj/item/projectile/P)
if(istype(P, /obj/item/projectile/energy/chrono_beam))
var/obj/item/projectile/energy/chrono_beam/beam = P
var/obj/item/weapon/gun/energy/chrono_gun/Pgun = beam.gun
if(Pgun && istype(Pgun))
Pgun.field_connect(src)
else
return 0
/obj/effect/chrono_field/assume_air()
return 0
/obj/effect/chrono_field/return_air() //we always have nominal air and temperature
var/datum/gas_mixture/GM = new
GM.oxygen = MOLES_O2STANDARD
GM.nitrogen = MOLES_N2STANDARD
GM.temperature = T20C
return GM
/obj/effect/chrono_field/Move()
return
/obj/effect/chrono_field/ex_act()
return
/obj/effect/chrono_field/blob_act()
return
#undef CHRONO_BEAM_RANGE
#undef CHRONO_FRAME_COUNT
@@ -0,0 +1,213 @@
/obj/item/clothing/head/helmet/space/chronos
name = "Chronosuit Helmet"
desc = "A white helmet with an opaque blue visor."
icon_state = "chronohelmet"
item_state = "chronohelmet"
slowdown = 1
armor = list(melee = 60, bullet = 30/*bullet through the visor*/, laser = 60, energy = 60, bomb = 30, bio = 90, rad = 90)
var/obj/item/clothing/suit/space/chronos/suit = null
/obj/item/clothing/head/helmet/space/chronos/dropped()
if(suit)
suit.deactivate()
..()
/obj/item/clothing/head/helmet/space/chronos/Destroy()
dropped()
..()
/obj/item/clothing/suit/space/chronos
name = "Chronosuit"
desc = "An advanced spacesuit equipped with teleportation and anti-compression technology"
icon_state = "chronosuit"
item_state = "chronosuit"
action_button_name = "Toggle Chronosuit"
icon_action_button = "action_chronosuit"
slowdown = 2
armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 30, bio = 90, rad = 90)
var/obj/item/clothing/head/helmet/space/chronos/helmet = null
var/obj/effect/chronos_cam/camera = null
var/activating = 0
var/activated = 0
var/cooldowntime = 50 //deciseconds
var/cooldown = 0
var/teleporting = 0
/obj/item/clothing/suit/space/chronos/proc/new_camera(var/mob/user)
if(camera)
del(camera)
camera = new /obj/effect/chronos_cam(get_turf(user))
camera.holder = user
user.remote_control = camera
/obj/item/clothing/suit/space/chronos/ui_action_click()
if((cooldown <= world.time) && !teleporting && !activating)
if(!activated)
activate()
else
deactivate()
/obj/item/clothing/suit/space/chronos/dropped()
if(activated)
deactivate()
..()
/obj/item/clothing/suit/space/chronos/Destroy()
dropped()
..()
/obj/item/clothing/suit/space/chronos/emp_act(severity)
var/mob/living/carbon/human/user = src.loc
switch(severity)
if(1)
if(user && ishuman(user) && (user.wear_suit == src))
user << "<span class='userdanger'>Elecrtromagnetic pulse detected, shutting down systems to preserve integrity...</span>"
deactivate()
/obj/item/clothing/suit/space/chronos/proc/chronowalk(var/mob/living/carbon/human/user)
if(!teleporting && user && (user.stat == CONSCIOUS))
teleporting = 1
var/turf/from_turf = get_turf(user)
if(!from_turf) //sanity, things happen
teleporting = 0
return
var/turf/to_turf = from_turf
var/atom/movable/overlay/phaseanim = new(from_turf)
var/obj/holder = new(camera)
phaseanim.name = "phasing [user.name]"
phaseanim.icon = 'icons/mob/mob.dmi'
phaseanim.icon_state = "chronostuck"
phaseanim.density = 1
phaseanim.layer = FLY_LAYER
phaseanim.master = user
user.ExtinguishMob()
if(user.buckled)
user.buckled.unbuckle()
user.loc = holder
flick("chronophase", phaseanim)
spawn(7)
if(user)
if(phaseanim)
if(camera && camera.loc)
to_turf = camera.loc
flick("chronounphase", phaseanim)
else
flick("chronostuck", phaseanim)
phaseanim.loc = to_turf
sleep(7)
if(holder)
if(user && user in holder.contents)
user.loc = to_turf
if(user.client)
if(camera)
user.client.eye = camera
else
user.client.eye = user
del(holder)
else if(user)
user.loc = from_turf
if(phaseanim)
del(phaseanim)
teleporting = 0
if(user && !user.loc) //ubersanity
user.loc = locate(0,0,1)
user.gib()
/obj/item/clothing/suit/space/chronos/process()
if(activated)
var/mob/living/carbon/human/user = src.loc
if(user && ishuman(user) && (user.wear_suit == src))
if(camera && (user.remote_control == camera))
if(!teleporting && !((camera.x == user.x) && (camera.y == user.y) && (camera.z == user.z))) //cheaper than a couple get_turf calls???
chronowalk(user)
else
new_camera(user)
else
processing_objects.Remove(src)
/obj/item/clothing/suit/space/chronos/proc/activate()
if(!activating && !activated && !teleporting)
activating = 1
var/mob/living/carbon/human/user = src.loc
if(user && ishuman(user))
if(user.wear_suit == src)
user << "\nChronosuitMK4 login: root"
user << "Password:\n"
user << "root@ChronosuitMK4# chronowalk4 --start\n"
if(user.head && istype(user.head, /obj/item/clothing/head/helmet/space/chronos))
user << "\[ <span style='color: #00ff00;'>ok</span> \] Mounting /dev/helmet"
helmet = user.head
helmet.canremove = 0
helmet.suit = src
src.canremove = 0
user << "\[ <span style='color: #00ff00;'>ok</span> \] Starting brainwave scanner"
user << "\[ <span style='color: #00ff00;'>ok</span> \] Starting ui display driver"
user << "\[ <span style='color: #00ff00;'>ok</span> \] Initializing chronowalk4-view"
new_camera(user)
processing_objects.Add(src)
activated = 1
else
user << "\[ <span style='color: #ff0000;'>fail</span> \] Mounting /dev/helmet"
user << "<span style='color: #ff0000;'><b>FATAL: </b>Unable to locate /dev/helmet. <b>Aborting...</b>"
cooldown = world.time + cooldowntime
activating = 0
return 0
/obj/item/clothing/suit/space/chronos/proc/deactivate()
if(activated)
activating = 1
var/mob/living/carbon/human/user = src.loc
if(user && ishuman(user))
if(user.wear_suit == src)
user << "\nroot@ChronosuitMK4# chronowalk4 --stop\n"
if(camera)
user << "\[ <span style='color: #ff5500;'>ok</span> \] Sending TERM signal to chronowalk4-view" //yes I know they aren't a different color when shutting down, but they were too similar at a glance
del(camera)
if(helmet)
user << "\[ <span style='color: #ff5500;'>ok</span> \] Stopping ui display driver"
user << "\[ <span style='color: #ff5500;'>ok</span> \] Stopping brainwave scanner"
user << "\[ <span style='color: #ff5500;'>ok</span> \] Unmounting /dev/helmet"
helmet.canremove = 1
helmet.suit = null
helmet = null
user << "logout"
src.canremove = 1
cooldown = world.time + cooldowntime * 1.5
activated = 0
activating = 0
/obj/effect/chronos_cam
name = "Chronosuit View"
density = 0
anchored = 1
invisibility = 101
opacity = 0
mouse_opacity = 0
var/mob/holder = null
/obj/effect/chronos_cam/relaymove(var/mob/user, direction)
if(holder)
if(user == holder)
if(user.client && user.client.eye != src)
src.loc = get_turf(user)
user.client.eye = src
var/step = get_step(src, direction)
if(step)
if(istype(step, /turf/space))
if(!src.Move(step))
src.loc = step
else
src.loc = step
else
del(src)
/obj/effect/chronos_cam/Destroy()
if(holder)
if(holder.remote_control == src)
holder.remote_control = null
if(holder.client && (holder.client.eye == src))
holder.client.eye = holder
..()
+1
View File
@@ -203,6 +203,7 @@
var/list/radar_blips = list() // list of screen objects, radar blips
var/radar_open = 0 // nonzero is radar is open
var/atom/movable/remote_control //Calls relaymove() to whatever it is
var/obj/control_object //Used by admins to possess objects. All mobs should have this var
var/datum/visibility_interface/visibility_interface = null // used by the visibility system to provide an interface for the visibility networks
+3
View File
@@ -207,6 +207,9 @@
if(Process_Grab()) return
if(mob.remote_control) //we're controlling something, our movement is relayed to it
return mob.remote_control.relaymove(mob, direct)
if(!mob.canmove)
return