mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-18 19:44:58 +01:00
Merge pull request #12603 from JJRcop/chronosuit_phase_better
New chronosuit teleport mechanics
This commit is contained in:
@@ -12,13 +12,13 @@
|
||||
var/obj/item/weapon/tank/jetpack/J = H.back
|
||||
J.toggle()
|
||||
J.Topic(null, list("stat" = 1))
|
||||
|
||||
|
||||
|
||||
/datum/outfit/tournament
|
||||
|
||||
/datum/outfit/tournament/
|
||||
name = "tournament standard red"
|
||||
|
||||
|
||||
uniform = /obj/item/clothing/under/color/red
|
||||
shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
suit = /obj/item/clothing/suit/armor/vest
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
/datum/outfit/tournament/red
|
||||
name = "tournament standard green"
|
||||
|
||||
|
||||
uniform = /obj/item/clothing/under/color/green
|
||||
|
||||
/datum/outfit/tournament/gangster
|
||||
@@ -156,7 +156,7 @@
|
||||
/datum/outfit/assassin/post_equip(mob/living/carbon/human/H)
|
||||
var/obj/item/clothing/under/U = H.w_uniform
|
||||
U.attachTie(new /obj/item/clothing/tie/waistcoat(H))
|
||||
|
||||
|
||||
//Could use a type
|
||||
var/obj/item/weapon/storage/secure/briefcase/sec_briefcase = H.l_hand
|
||||
for(var/obj/item/briefcase_item in sec_briefcase)
|
||||
@@ -172,7 +172,7 @@
|
||||
pda.owner = H.real_name
|
||||
pda.ownjob = "Reaper"
|
||||
pda.update_label()
|
||||
|
||||
|
||||
var/obj/item/weapon/card/id/syndicate/W = H.wear_id
|
||||
W.access = get_all_accesses()
|
||||
W.assignment = "Reaper"
|
||||
@@ -340,7 +340,7 @@
|
||||
var/obj/item/device/radio/R = H.ears
|
||||
R.set_frequency(CENTCOM_FREQ)
|
||||
R.freqlock = 1
|
||||
|
||||
|
||||
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)//Here you go Deuryn
|
||||
L.imp_in = H
|
||||
L.implanted = 1
|
||||
@@ -359,7 +359,15 @@
|
||||
name = "Death Commando Officer"
|
||||
head = /obj/item/clothing/head/helmet/space/beret
|
||||
|
||||
/datum/outfit/chrono_agent
|
||||
name = "Timeline Eradication Agent"
|
||||
uniform = /obj/item/clothing/under/color/white
|
||||
suit = /obj/item/clothing/suit/space/chronos
|
||||
back = /obj/item/weapon/chrono_eraser
|
||||
head = /obj/item/clothing/head/helmet/space/chronos
|
||||
mask = /obj/item/clothing/mask/breath
|
||||
suit_store = /obj/item/weapon/tank/internals/oxygen
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -25,19 +25,27 @@
|
||||
action_button_name = "Toggle Chronosuit"
|
||||
armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 30, bio = 90, rad = 90)
|
||||
var/list/chronosafe_items = list(/obj/item/weapon/chrono_eraser, /obj/item/weapon/gun/energy/chrono_gun)
|
||||
var/hands_nodrop_states
|
||||
var/obj/item/clothing/head/helmet/space/chronos/helmet = null
|
||||
var/obj/effect/chronos_cam/camera = null
|
||||
var/atom/movable/overlay/phase_underlay = null
|
||||
var/datum/action/innate/chrono_teleport/teleport_now = new
|
||||
var/activating = 0
|
||||
var/activated = 0
|
||||
var/cooldowntime = 50 //deciseconds
|
||||
var/teleporting = 0
|
||||
|
||||
/obj/item/clothing/suit/space/chronos/New()
|
||||
..()
|
||||
teleport_now.chronosuit = src
|
||||
teleport_now.target = src
|
||||
|
||||
/obj/item/clothing/suit/space/chronos/proc/new_camera(mob/user)
|
||||
if(camera)
|
||||
qdel(camera)
|
||||
camera = new /obj/effect/chronos_cam(get_turf(user))
|
||||
camera = new /obj/effect/chronos_cam(user)
|
||||
camera.holder = user
|
||||
camera.chronosuit = src
|
||||
user.remote_control = camera
|
||||
|
||||
/obj/item/clothing/suit/space/chronos/ui_action_click()
|
||||
@@ -60,20 +68,48 @@
|
||||
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()
|
||||
if(activated && user && ishuman(user) && (user.wear_suit == src))
|
||||
user << "<span class='userdanger'>E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD</span>"
|
||||
deactivate(1, 1)
|
||||
|
||||
/obj/item/clothing/suit/space/chronos/proc/chronowalk(mob/living/carbon/human/user)
|
||||
if(!teleporting && user && (user.stat == CONSCIOUS))
|
||||
/obj/item/clothing/suit/space/chronos/proc/finish_chronowalk()
|
||||
var/mob/living/carbon/human/user = src.loc
|
||||
if(istype(user))
|
||||
user.SetStunned(0)
|
||||
user.next_move = 1
|
||||
user.alpha = 255
|
||||
user.color = "#ffffff"
|
||||
user.animate_movement = FORWARD_STEPS
|
||||
user.notransform = 0
|
||||
user.anchored = 0
|
||||
teleporting = 0
|
||||
if(user.l_hand && !(hands_nodrop_states & 1))
|
||||
user.l_hand.flags &= ~NODROP
|
||||
if(user.r_hand && !(hands_nodrop_states & 2))
|
||||
user.r_hand.flags &= ~NODROP
|
||||
if(phase_underlay && !qdeleted(phase_underlay))
|
||||
qdel(phase_underlay)
|
||||
phase_underlay = null
|
||||
if(camera)
|
||||
camera.remove_target_ui()
|
||||
camera.loc = user
|
||||
if(teleport_now.button)
|
||||
teleport_now.button.UpdateIcon()
|
||||
|
||||
/obj/item/clothing/suit/space/chronos/proc/chronowalk(atom/location)
|
||||
var/mob/living/carbon/human/user = src.loc
|
||||
if(activated && !teleporting && user && istype(user) && location && user.loc && location.loc && user.wear_suit == src && 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)
|
||||
var/turf/to_turf = get_turf(location)
|
||||
var/distance = cheap_hypotenuse(from_turf.x, from_turf.y, to_turf.x, to_turf.y)
|
||||
var/phase_in_ds = distance*2
|
||||
|
||||
if(camera)
|
||||
camera.remove_target_ui()
|
||||
|
||||
if(teleport_now.button)
|
||||
teleport_now.button.UpdateIcon()
|
||||
|
||||
var/list/nonsafe_slots = list(slot_belt, slot_back, slot_l_hand, slot_r_hand)
|
||||
for(var/slot in nonsafe_slots)
|
||||
@@ -81,52 +117,73 @@
|
||||
if(slot_item && !(slot_item.type in chronosafe_items) && user.unEquip(slot_item))
|
||||
user << "<span class='notice'>Your [slot_item.name] got left behind.</span>"
|
||||
|
||||
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_mob()
|
||||
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)
|
||||
|
||||
phase_underlay = create_phase_underlay(user)
|
||||
|
||||
hands_nodrop_states = 0
|
||||
if(user.l_hand)
|
||||
hands_nodrop_states |= (user.l_hand.flags & NODROP) ? 1 : 0
|
||||
user.l_hand.flags |= NODROP
|
||||
if(user.r_hand)
|
||||
hands_nodrop_states |= (user.r_hand.flags & NODROP) ? 2 : 0
|
||||
user.r_hand.flags |= NODROP
|
||||
|
||||
user.animate_movement = NO_STEPS
|
||||
user.changeNext_move(8 + phase_in_ds)
|
||||
user.notransform = 1
|
||||
user.anchored = 1
|
||||
user.Stun(INFINITY)
|
||||
|
||||
animate(user, color = "#00ccee", time = 3)
|
||||
spawn(3)
|
||||
if(teleporting && activated && user && phase_underlay && !qdeleted(phase_underlay))
|
||||
animate(user, alpha = 0, time = 2)
|
||||
animate(phase_underlay, alpha = 255, time = 2)
|
||||
sleep(2)
|
||||
if(teleporting && activated && user && phase_underlay && !qdeleted(phase_underlay))
|
||||
phase_underlay.loc = to_turf
|
||||
user.loc = to_turf
|
||||
if(user.client)
|
||||
if(camera)
|
||||
user.client.eye = camera
|
||||
else
|
||||
user.client.eye = user
|
||||
qdel(holder)
|
||||
else if(user)
|
||||
user.loc = from_turf
|
||||
if(phaseanim)
|
||||
qdel(phaseanim)
|
||||
teleporting = 0
|
||||
if(user && !user.loc) //ubersanity
|
||||
user.loc = locate(0,0,1)
|
||||
user.gib()
|
||||
animate(user, alpha = 255, time = phase_in_ds)
|
||||
animate(phase_underlay, alpha = 0, time = phase_in_ds)
|
||||
sleep(phase_in_ds)
|
||||
if(teleporting && activated && phase_underlay && !qdeleted(phase_underlay))
|
||||
animate(user, color = "#ffffff", time = 3)
|
||||
sleep(3)
|
||||
if(teleporting && user && !qdeleted(user))
|
||||
user.loc = to_turf //this will cover if bad things happen before the teleport, yes it is redundant
|
||||
finish_chronowalk()
|
||||
|
||||
/obj/item/clothing/suit/space/chronos/proc/create_phase_underlay(var/mob/user)
|
||||
var/icon/user_icon = getFlatIcon(user)
|
||||
user_icon.Blend("#ffffff")
|
||||
var/atom/movable/overlay/phase = new(user.loc)
|
||||
phase.icon = user_icon
|
||||
phase.density = 1
|
||||
phase.anchored = 1
|
||||
phase.master = user
|
||||
phase.animate_movement = NO_STEPS
|
||||
phase.alpha = 0
|
||||
phase.mouse_opacity = 0
|
||||
phase.name = user.name
|
||||
phase.transform = user.transform
|
||||
phase.pixel_x = user.pixel_x
|
||||
phase.pixel_y = user.pixel_y
|
||||
return phase
|
||||
|
||||
/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)
|
||||
if(!teleporting)
|
||||
if(camera.loc != user && ((camera.x != user.x) || (camera.y != user.y) || (camera.z != user.z)))
|
||||
if(camera.phase_time <= world.time)
|
||||
chronowalk(camera)
|
||||
else
|
||||
camera.remove_target_ui()
|
||||
else
|
||||
new_camera(user)
|
||||
else
|
||||
@@ -156,33 +213,41 @@
|
||||
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>"
|
||||
teleport_now.Grant(user)
|
||||
cooldown = world.time + cooldowntime
|
||||
activating = 0
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/suit/space/chronos/proc/deactivate()
|
||||
if(activated)
|
||||
/obj/item/clothing/suit/space/chronos/proc/deactivate(force = 0, silent = 0)
|
||||
if(activated && (!teleporting || force))
|
||||
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(!silent)
|
||||
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
|
||||
if(!silent)
|
||||
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
|
||||
qdel(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"
|
||||
if(!silent)
|
||||
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.flags &= ~NODROP
|
||||
helmet.suit = null
|
||||
helmet = null
|
||||
user << "logout"
|
||||
if(!silent)
|
||||
user << "logout"
|
||||
teleport_now.Remove(user)
|
||||
src.flags &= ~NODROP
|
||||
cooldown = world.time + cooldowntime * 1.5
|
||||
activated = 0
|
||||
activating = 0
|
||||
|
||||
finish_chronowalk()
|
||||
if(teleporting && force)
|
||||
user.electrocute_act(35, src, safety = 1)
|
||||
|
||||
/obj/effect/chronos_cam
|
||||
name = "Chronosuit View"
|
||||
@@ -192,28 +257,90 @@
|
||||
opacity = 0
|
||||
mouse_opacity = 0
|
||||
var/mob/holder = null
|
||||
var/phase_time = 0
|
||||
var/phase_time_length = 3
|
||||
var/obj/screen/chronos_target/target_ui = null
|
||||
var/obj/item/clothing/suit/space/chronos/chronosuit
|
||||
|
||||
/obj/effect/chronos_cam/proc/create_target_ui()
|
||||
if(holder && holder.client && chronosuit)
|
||||
if(target_ui)
|
||||
remove_target_ui()
|
||||
target_ui = new(null, holder)
|
||||
holder.client.screen += target_ui
|
||||
|
||||
/obj/effect/chronos_cam/proc/remove_target_ui()
|
||||
if(target_ui)
|
||||
qdel(target_ui)
|
||||
target_ui = null
|
||||
|
||||
/obj/effect/chronos_cam/relaymove(var/mob/user, direction)
|
||||
if(holder)
|
||||
if(user == holder)
|
||||
if(loc == user)
|
||||
loc = get_turf(user)
|
||||
if(user.client && user.client.eye != src)
|
||||
src.loc = get_turf(user)
|
||||
user.client.eye = src
|
||||
var/step = get_step(src, direction)
|
||||
user.reset_view(src)
|
||||
user.set_machine(src)
|
||||
var/atom/step = get_step(src, direction)
|
||||
if(step)
|
||||
if(istype(step, /turf/space))
|
||||
if((step.x <= TRANSITIONEDGE) || (step.x >= (world.maxx - TRANSITIONEDGE - 1)) || (step.y <= TRANSITIONEDGE) || (step.y >= (world.maxy - TRANSITIONEDGE - 1)))
|
||||
if(!src.Move(step))
|
||||
src.loc = step
|
||||
else
|
||||
src.loc = step
|
||||
if((x == holder.x) && (y == holder.y) && (z == holder.z))
|
||||
remove_target_ui()
|
||||
loc = user
|
||||
else if(!target_ui)
|
||||
create_target_ui()
|
||||
phase_time = world.time + phase_time_length
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/chronos_cam/check_eye(mob/user)
|
||||
if(user == holder)
|
||||
return 1
|
||||
user.unset_machine()
|
||||
user.reset_view(null)
|
||||
|
||||
/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
|
||||
holder.unset_machine()
|
||||
holder.reset_view(null)
|
||||
return ..()
|
||||
|
||||
/obj/screen/chronos_target
|
||||
name = "target display"
|
||||
screen_loc = "CENTER,CENTER"
|
||||
color = "#ff3311"
|
||||
blend_mode = BLEND_SUBTRACT
|
||||
|
||||
/obj/screen/chronos_target/New(loc, var/mob/living/carbon/human/user)
|
||||
if(user)
|
||||
var/icon/user_icon = getFlatIcon(user)
|
||||
icon = user_icon
|
||||
transform = user.transform
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/datum/action/innate/chrono_teleport
|
||||
name = "Teleport Now"
|
||||
button_icon_state = "chrono_phase"
|
||||
check_flags = AB_CHECK_ALIVE|AB_CHECK_INSIDE
|
||||
var/obj/item/clothing/suit/space/chronos/chronosuit = null
|
||||
|
||||
/datum/action/innate/chrono_teleport/IsAvailable()
|
||||
return (!CheckRemoval(owner) && !chronosuit.teleporting)
|
||||
|
||||
/datum/action/innate/chrono_teleport/Activate()
|
||||
if(IsAvailable())
|
||||
if(chronosuit.camera)
|
||||
chronosuit.chronowalk(chronosuit.camera)
|
||||
|
||||
/datum/action/innate/chrono_teleport/CheckRemoval()
|
||||
return (..() && !(chronosuit && chronosuit.activated && chronosuit.camera))
|
||||
@@ -0,0 +1,6 @@
|
||||
author: JJRcop
|
||||
delete-after: True
|
||||
changes:
|
||||
- tweak: "Chronosuits have had their movement revised, they now take time to teleport depending on how far you've traveled, and don't teleport automatically anymore unless you stop moving for a short moment, or press the new '
|
||||
Teleport Now' button."
|
||||
- rscadd: "Added new outfit that allows admins to dress people up in the chrono equipment easier."
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 55 KiB |
Reference in New Issue
Block a user