mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Add UAV, UAV software
Design placed in mechfab
This commit is contained in:
@@ -272,17 +272,17 @@
|
|||||||
var/list/hearturfs = list()
|
var/list/hearturfs = list()
|
||||||
|
|
||||||
for(var/thing in hear)
|
for(var/thing in hear)
|
||||||
if(istype(thing,/obj))
|
if(istype(thing, /obj)) //Can't use isobj() because /atom/movable returns true in that, and so lighting overlays would be included
|
||||||
objs += thing
|
objs += thing
|
||||||
hearturfs |= get_turf(thing)
|
hearturfs |= get_turf(thing)
|
||||||
else if(istype(thing,/mob))
|
if(ismob(thing))
|
||||||
mobs += thing
|
mobs += thing
|
||||||
hearturfs |= get_turf(thing)
|
hearturfs |= get_turf(thing)
|
||||||
|
|
||||||
//A list of every mob with a client
|
//A list of every mob with a client
|
||||||
for(var/mob in player_list)
|
for(var/mob in player_list)
|
||||||
//VOREStation Edit - Trying to fix some vorestation bug.
|
//VOREStation Edit - Trying to fix some vorestation bug.
|
||||||
if(!istype(mob, /mob))
|
if(!ismob(mob))
|
||||||
player_list -= mob
|
player_list -= mob
|
||||||
crash_with("There is a null or non-mob reference inside player_list ([mob]).")
|
crash_with("There is a null or non-mob reference inside player_list ([mob]).")
|
||||||
continue
|
continue
|
||||||
|
|||||||
347
code/game/objects/items/uav.dm
Normal file
347
code/game/objects/items/uav.dm
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
#define UAV_OFF 0
|
||||||
|
#define UAV_ON 1
|
||||||
|
#define UAV_PAIRING 2
|
||||||
|
#define UAV_PACKED 3
|
||||||
|
|
||||||
|
/obj/item/device/uav
|
||||||
|
name = "recon skimmer"
|
||||||
|
desc = "A semi-portable reconisance drone that folds into a backpack-sized carrying case."
|
||||||
|
icon = 'icons/obj/uav.dmi'
|
||||||
|
icon_state = "uav"
|
||||||
|
|
||||||
|
var/obj/item/weapon/cell/cell
|
||||||
|
var/cell_type = null //Can put a starting cell here
|
||||||
|
|
||||||
|
density = 1 //Is dense, but not anchored, so you can swap with it
|
||||||
|
slowdown = 3 //Heevvee.
|
||||||
|
|
||||||
|
health = 100
|
||||||
|
var/power_per_process = 50 // About 6.5 minutes of use on a high-cell (10,000)
|
||||||
|
var/state = UAV_OFF
|
||||||
|
|
||||||
|
var/datum/effect/effect/system/ion_trail_follow/ion_trail
|
||||||
|
|
||||||
|
var/list/mob/living/masters
|
||||||
|
|
||||||
|
// So you know which is which
|
||||||
|
var/nickname = "Generic Droan"
|
||||||
|
|
||||||
|
// Radial menu
|
||||||
|
var/static/image/radial_pickup = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pickup")
|
||||||
|
var/static/image/radial_wrench = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_wrench")
|
||||||
|
var/static/image/radial_power = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_power")
|
||||||
|
var/static/image/radial_pair = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pair")
|
||||||
|
|
||||||
|
// Movement cooldown
|
||||||
|
var/next_move = 0
|
||||||
|
|
||||||
|
// Idle shutdown time
|
||||||
|
var/no_masters_time = 0
|
||||||
|
|
||||||
|
/obj/item/device/uav/loaded
|
||||||
|
cell_type = /obj/item/weapon/cell/high
|
||||||
|
|
||||||
|
/obj/item/device/uav/Initialize()
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
if(!cell && cell_type)
|
||||||
|
cell = new cell_type
|
||||||
|
|
||||||
|
ion_trail = new /datum/effect/effect/system/ion_trail_follow()
|
||||||
|
ion_trail.set_up(src)
|
||||||
|
ion_trail.stop()
|
||||||
|
|
||||||
|
/obj/item/device/uav/Destroy()
|
||||||
|
qdel_null(cell)
|
||||||
|
qdel_null(ion_trail)
|
||||||
|
LAZYCLEARLIST(masters)
|
||||||
|
STOP_PROCESSING(SSobj, src)
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/item/device/uav/attack_hand(var/mob/user)
|
||||||
|
//Has to be on the ground to work with it properly
|
||||||
|
if(!isturf(loc))
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
var/list/options = list(
|
||||||
|
"Pick Up" = radial_pickup,
|
||||||
|
"(Dis)Assemble" = radial_wrench,
|
||||||
|
"Toggle Power" = radial_power,
|
||||||
|
"Pairing Mode" = radial_pair)
|
||||||
|
var/choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
|
||||||
|
|
||||||
|
switch(choice)
|
||||||
|
// Can pick up when off or packed
|
||||||
|
if("Pick Up")
|
||||||
|
if(state == UAV_OFF || state == UAV_PACKED)
|
||||||
|
return ..()
|
||||||
|
else
|
||||||
|
to_chat(user,"<span class='warning'>Turn [nickname] off or pack it first!</span>")
|
||||||
|
return
|
||||||
|
// Can disasemble or reassemble from packed or off (and this one takes time)
|
||||||
|
if("(Dis)Assemble")
|
||||||
|
if(can_transition_to(state == UAV_PACKED ? UAV_OFF : UAV_PACKED, user) && do_after(user, 10 SECONDS, src))
|
||||||
|
return toggle_packed(user)
|
||||||
|
// Can toggle power from on and off
|
||||||
|
if("Toggle Power")
|
||||||
|
if(can_transition_to(state == UAV_ON ? UAV_OFF : UAV_ON, user))
|
||||||
|
return toggle_power(user)
|
||||||
|
// Can pair when off
|
||||||
|
if("Pairing Mode")
|
||||||
|
if(can_transition_to(state == UAV_PAIRING ? UAV_OFF : UAV_PAIRING, user))
|
||||||
|
return toggle_pairing(user)
|
||||||
|
|
||||||
|
/obj/item/device/uav/attackby(var/obj/item/I, var/mob/user)
|
||||||
|
if(istype(I, /obj/item/modular_computer) && state == UAV_PAIRING)
|
||||||
|
var/obj/item/modular_computer/MC = I
|
||||||
|
LAZYDISTINCTADD(MC.paired_uavs, weakref(src))
|
||||||
|
playsound(src, 'sound/machines/buttonbeep.ogg', 50, 1)
|
||||||
|
visible_message("<span class='notice'>[user] pairs [I] to [nickname]</span>")
|
||||||
|
toggle_pairing()
|
||||||
|
|
||||||
|
else if(I.is_screwdriver() && cell)
|
||||||
|
if(do_after(user, 3 SECONDS, src))
|
||||||
|
to_chat(user, "<span class='notice'>You remove [cell] into [nickname].</span>")
|
||||||
|
playsound(src, I.usesound, 50, 1)
|
||||||
|
power_down()
|
||||||
|
cell.forceMove(get_turf(src))
|
||||||
|
cell = null
|
||||||
|
|
||||||
|
else if(istype(I, /obj/item/weapon/cell) && !cell)
|
||||||
|
if(do_after(user, 3 SECONDS, src))
|
||||||
|
to_chat(user, "<span class='notice'>You insert [I] into [nickname].</span>")
|
||||||
|
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
|
||||||
|
power_down()
|
||||||
|
cell.forceMove(get_turf(src))
|
||||||
|
cell = null
|
||||||
|
|
||||||
|
else if(istype(I, /obj/item/weapon/pen) || istype(I, /obj/item/device/flashlight/pen))
|
||||||
|
var/tmp_label = sanitizeSafe(input(user, "Enter a nickname for [src]", "Nickname", nickname), MAX_NAME_LEN)
|
||||||
|
if(length(tmp_label) > 50 || length(tmp_label) < 3)
|
||||||
|
to_chat(user, "<span class='notice'>The nickname must be between 3 and 50 characters.</span>")
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='notice'>You scribble your new nickname on the side of [src].</span>")
|
||||||
|
nickname = tmp_label
|
||||||
|
desc = initial(desc) + " This one has <span class='notice'>'[nickname]'</span> scribbled on the side."
|
||||||
|
else
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/can_transition_to(var/new_state, var/mob/user)
|
||||||
|
switch(state) //Current one
|
||||||
|
if(UAV_ON)
|
||||||
|
if(new_state == UAV_OFF || new_state == UAV_PACKED)
|
||||||
|
. = TRUE
|
||||||
|
if(UAV_OFF)
|
||||||
|
if(new_state == UAV_ON || new_state == UAV_PACKED || new_state == UAV_PAIRING)
|
||||||
|
. = TRUE
|
||||||
|
if(UAV_PAIRING)
|
||||||
|
if(new_state == UAV_OFF)
|
||||||
|
. = TRUE
|
||||||
|
if(UAV_PACKED)
|
||||||
|
if(new_state == UAV_OFF)
|
||||||
|
. = TRUE
|
||||||
|
|
||||||
|
if(!.)
|
||||||
|
if(user)
|
||||||
|
to_chat(user, "<span class='warning'>You can't do that while [nickname] is in this state.</span>")
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/obj/item/device/uav/update_icon()
|
||||||
|
cut_overlays()
|
||||||
|
switch(state)
|
||||||
|
if(UAV_PAIRING)
|
||||||
|
add_overlay("[initial(icon_state)]_pairing")
|
||||||
|
icon_state = "[initial(icon_state)]"
|
||||||
|
if(UAV_ON)
|
||||||
|
icon_state = "[initial(icon_state)]_on"
|
||||||
|
if(UAV_OFF)
|
||||||
|
icon_state = "[initial(icon_state)]"
|
||||||
|
if(UAV_PACKED)
|
||||||
|
icon_state = "[initial(icon_state)]_packed"
|
||||||
|
|
||||||
|
/obj/item/device/uav/process()
|
||||||
|
if(cell?.use(power_per_process) != power_per_process)
|
||||||
|
visible_message("<span class='warning'>[src] sputters and thuds to the ground, inert.</span>")
|
||||||
|
playsound(src, 'sound/items/drop/metalboots.ogg', 75, 1)
|
||||||
|
power_down()
|
||||||
|
health -= initial(health)*0.25 //Lose 25% of your original health
|
||||||
|
|
||||||
|
if(LAZYLEN(masters))
|
||||||
|
no_masters_time = 0
|
||||||
|
else if(no_masters_time++ > 50)
|
||||||
|
power_down()
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/toggle_pairing()
|
||||||
|
switch(state)
|
||||||
|
if(UAV_PAIRING)
|
||||||
|
state = UAV_OFF
|
||||||
|
update_icon()
|
||||||
|
return TRUE
|
||||||
|
if(UAV_OFF)
|
||||||
|
state = UAV_PAIRING
|
||||||
|
update_icon()
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/toggle_power()
|
||||||
|
switch(state)
|
||||||
|
if(UAV_OFF)
|
||||||
|
power_up()
|
||||||
|
return TRUE
|
||||||
|
if(UAV_ON)
|
||||||
|
power_down()
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/toggle_packed()
|
||||||
|
if(UAV_ON)
|
||||||
|
power_down()
|
||||||
|
switch(state)
|
||||||
|
if(UAV_OFF) //Packing
|
||||||
|
state = UAV_PACKED
|
||||||
|
w_class = ITEMSIZE_LARGE
|
||||||
|
slowdown = 1
|
||||||
|
density = FALSE
|
||||||
|
update_icon()
|
||||||
|
return TRUE
|
||||||
|
if(UAV_PACKED) //Unpacking
|
||||||
|
state = UAV_OFF
|
||||||
|
w_class = ITEMSIZE_HUGE
|
||||||
|
slowdown = 3
|
||||||
|
density = TRUE
|
||||||
|
update_icon()
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/power_up()
|
||||||
|
if(state != UAV_OFF || !isturf(loc))
|
||||||
|
return
|
||||||
|
if(cell?.use(power_per_process) != power_per_process)
|
||||||
|
visible_message("<span class='warning'>[src] sputters and chugs as it tries, and fails, to power up.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
state = UAV_ON
|
||||||
|
update_icon()
|
||||||
|
start_hover()
|
||||||
|
set_light(4, 4, "#FFFFFF")
|
||||||
|
START_PROCESSING(SSobj, src)
|
||||||
|
no_masters_time = 0
|
||||||
|
visible_message("<span class='notice'>[nickname] buzzes and lifts into the air.</span>")
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/power_down()
|
||||||
|
if(state != UAV_ON)
|
||||||
|
return
|
||||||
|
|
||||||
|
state = UAV_OFF
|
||||||
|
update_icon()
|
||||||
|
stop_hover()
|
||||||
|
set_light(0)
|
||||||
|
LAZYCLEARLIST(masters)
|
||||||
|
STOP_PROCESSING(SSobj, src)
|
||||||
|
visible_message("<span class='notice'>[nickname] gracefully settles onto the ground.</span>")
|
||||||
|
|
||||||
|
//////////////// Helpers
|
||||||
|
/obj/item/device/uav/get_cell()
|
||||||
|
return cell
|
||||||
|
|
||||||
|
/obj/item/device/uav/relaymove(var/mob/user, direction, signal = 1)
|
||||||
|
if(signal && state == UAV_ON && (weakref(user) in masters))
|
||||||
|
if(next_move <= world.time)
|
||||||
|
next_move = world.time + (1 SECOND/signal)
|
||||||
|
step(src, direction)
|
||||||
|
return TRUE // Even if we couldn't step, we're taking credit for absorbing the move
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/get_status_string()
|
||||||
|
return "[nickname] - [get_x(src)],[get_y(src)],[get_z(src)] - I:[health]/[initial(health)] - C:[cell ? "[cell.charge]/[cell.maxcharge]" : "Not Installed"]"
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/add_master(var/mob/living/M)
|
||||||
|
LAZYDISTINCTADD(masters, weakref(M))
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/remove_master(var/mob/living/M)
|
||||||
|
LAZYREMOVE(masters, weakref(M))
|
||||||
|
|
||||||
|
/obj/item/device/uav/check_eye()
|
||||||
|
if(state == UAV_ON)
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return -1
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/start_hover()
|
||||||
|
if(!ion_trail.on) //We'll just use this to store if we're floating or not
|
||||||
|
ion_trail.start()
|
||||||
|
var/amplitude = 2 //maximum displacement from original position
|
||||||
|
var/period = 36 //time taken for the mob to go up >> down >> original position, in deciseconds. Should be multiple of 4
|
||||||
|
|
||||||
|
var/top = old_y + amplitude
|
||||||
|
var/bottom = old_y - amplitude
|
||||||
|
var/half_period = period / 2
|
||||||
|
var/quarter_period = period / 4
|
||||||
|
|
||||||
|
animate(src, pixel_y = top, time = quarter_period, easing = SINE_EASING | EASE_OUT, loop = -1) //up
|
||||||
|
animate(pixel_y = bottom, time = half_period, easing = SINE_EASING, loop = -1) //down
|
||||||
|
animate(pixel_y = old_y, time = quarter_period, easing = SINE_EASING | EASE_IN, loop = -1) //back
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/stop_hover()
|
||||||
|
if(ion_trail.on)
|
||||||
|
ion_trail.stop()
|
||||||
|
animate(src, pixel_y = old_y, time = 5, easing = SINE_EASING | EASE_IN) //halt animation
|
||||||
|
|
||||||
|
/obj/item/device/uav/hear_talk(var/mob/M, list/message_pieces, verb)
|
||||||
|
var/name_used = M.GetVoice()
|
||||||
|
for(var/wr_master in masters)
|
||||||
|
var/weakref/wr = wr_master
|
||||||
|
var/mob/master = wr.resolve()
|
||||||
|
var/message = master.combine_message(message_pieces, verb, M)
|
||||||
|
var/rendered = "<i><span class='game say'>UAV received: <span class='name'>[name_used]</span> [message]</span></i>"
|
||||||
|
master.show_message(rendered, 2)
|
||||||
|
|
||||||
|
/obj/item/device/uav/see_emote(var/mob/living/M, text)
|
||||||
|
for(var/wr_master in masters)
|
||||||
|
var/weakref/wr = wr_master
|
||||||
|
var/mob/master = wr.resolve()
|
||||||
|
var/rendered = "<i><span class='game say'>UAV received, <span class='message'>[text]</span></span></i>"
|
||||||
|
master.show_message(rendered, 2)
|
||||||
|
|
||||||
|
/obj/item/device/uav/show_message(msg, type, alt, alt_type)
|
||||||
|
for(var/wr_master in masters)
|
||||||
|
var/weakref/wr = wr_master
|
||||||
|
var/mob/master = wr.resolve()
|
||||||
|
var/rendered = "<i><span class='game say'>UAV received, <span class='message'>[msg]</span></span></i>"
|
||||||
|
master.show_message(rendered, type)
|
||||||
|
|
||||||
|
/obj/item/device/uav/take_damage(var/damage)
|
||||||
|
health -= damage
|
||||||
|
CheckHealth()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/item/device/uav/attack_generic(var/mob/user, var/damage, var/attack_verb)
|
||||||
|
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
|
||||||
|
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
|
||||||
|
user.do_attack_animation(src)
|
||||||
|
health -= damage
|
||||||
|
CheckHealth()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/item/device/uav/ex_act(severity)
|
||||||
|
switch(severity)
|
||||||
|
if(1.0)
|
||||||
|
die()
|
||||||
|
if(2.0)
|
||||||
|
health -= 25
|
||||||
|
CheckHealth()
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/CheckHealth()
|
||||||
|
if(health <= 0)
|
||||||
|
die()
|
||||||
|
|
||||||
|
/obj/item/device/uav/proc/die()
|
||||||
|
visible_message("<span class='danger'>[src] shorts out and explodes!</span>")
|
||||||
|
power_down()
|
||||||
|
var/turf/T = get_turf(src)
|
||||||
|
qdel(src)
|
||||||
|
explosion(T, -1, 0, 1, 2) //Not very large
|
||||||
|
|
||||||
|
#undef UAV_OFF
|
||||||
|
#undef UAV_ON
|
||||||
|
#undef UAV_PACKED
|
||||||
@@ -142,6 +142,7 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
/mob/proc/unset_machine()
|
/mob/proc/unset_machine()
|
||||||
|
machine?.remove_visual(src)
|
||||||
src.machine = null
|
src.machine = null
|
||||||
|
|
||||||
/mob/proc/set_machine(var/obj/O)
|
/mob/proc/set_machine(var/obj/O)
|
||||||
|
|||||||
@@ -418,7 +418,7 @@
|
|||||||
BITSET(hud_updateflag, WANTED_HUD)
|
BITSET(hud_updateflag, WANTED_HUD)
|
||||||
if(istype(usr,/mob/living/carbon/human))
|
if(istype(usr,/mob/living/carbon/human))
|
||||||
var/mob/living/carbon/human/U = usr
|
var/mob/living/carbon/human/U = usr
|
||||||
U.handle_regular_hud_updates()
|
U.handle_hud_list()
|
||||||
if(istype(usr,/mob/living/silicon/robot))
|
if(istype(usr,/mob/living/silicon/robot))
|
||||||
var/mob/living/silicon/robot/U = usr
|
var/mob/living/silicon/robot/U = usr
|
||||||
U.handle_regular_hud_updates()
|
U.handle_regular_hud_updates()
|
||||||
|
|||||||
@@ -58,8 +58,8 @@
|
|||||||
|
|
||||||
..()
|
..()
|
||||||
|
|
||||||
if(life_tick%30==15)
|
if(life_tick % 30)
|
||||||
hud_updateflag = 1022
|
hud_updateflag = (1 << TOTAL_HUDS) - 1
|
||||||
|
|
||||||
voice = GetVoice()
|
voice = GetVoice()
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
else if(stat == DEAD && !stasis)
|
else if(stat == DEAD && !stasis)
|
||||||
handle_defib_timer()
|
handle_defib_timer()
|
||||||
|
|
||||||
if(!handle_some_updates())
|
if(skip_some_updates())
|
||||||
return //We go ahead and process them 5 times for HUD images and other stuff though.
|
return //We go ahead and process them 5 times for HUD images and other stuff though.
|
||||||
|
|
||||||
//Update our name based on whether our face is obscured/disfigured
|
//Update our name based on whether our face is obscured/disfigured
|
||||||
@@ -99,10 +99,10 @@
|
|||||||
|
|
||||||
pulse = handle_pulse()
|
pulse = handle_pulse()
|
||||||
|
|
||||||
/mob/living/carbon/human/proc/handle_some_updates()
|
/mob/living/carbon/human/proc/skip_some_updates()
|
||||||
if(life_tick > 5 && timeofdeath && (timeofdeath < 5 || world.time - timeofdeath > 6000)) //We are long dead, or we're junk mobs spawned like the clowns on the clown shuttle
|
if(life_tick > 5 && timeofdeath && (timeofdeath < 5 || world.time - timeofdeath > 6000)) //We are long dead, or we're junk mobs spawned like the clowns on the clown shuttle
|
||||||
return 0
|
return 1
|
||||||
return 1
|
return 0
|
||||||
|
|
||||||
/mob/living/carbon/human/breathe()
|
/mob/living/carbon/human/breathe()
|
||||||
if(!inStasisNow())
|
if(!inStasisNow())
|
||||||
@@ -951,7 +951,7 @@
|
|||||||
|
|
||||||
//DO NOT CALL handle_statuses() from this proc, it's called from living/Life() as long as this returns a true value.
|
//DO NOT CALL handle_statuses() from this proc, it's called from living/Life() as long as this returns a true value.
|
||||||
/mob/living/carbon/human/handle_regular_status_updates()
|
/mob/living/carbon/human/handle_regular_status_updates()
|
||||||
if(!handle_some_updates())
|
if(skip_some_updates())
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if(status_flags & GODMODE) return 0
|
if(status_flags & GODMODE) return 0
|
||||||
@@ -1292,8 +1292,11 @@
|
|||||||
else
|
else
|
||||||
bodytemp.icon_state = "temp0"
|
bodytemp.icon_state = "temp0"
|
||||||
|
|
||||||
if(blinded) overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
if(blinded)
|
||||||
else clear_fullscreens()
|
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
||||||
|
|
||||||
|
else if(!machine)
|
||||||
|
clear_fullscreens()
|
||||||
|
|
||||||
if(disabilities & NEARSIGHTED) //this looks meh but saves a lot of memory by not requiring to add var/prescription
|
if(disabilities & NEARSIGHTED) //this looks meh but saves a lot of memory by not requiring to add var/prescription
|
||||||
if(glasses) //to every /obj/item
|
if(glasses) //to every /obj/item
|
||||||
@@ -1395,11 +1398,12 @@
|
|||||||
|
|
||||||
if(machine)
|
if(machine)
|
||||||
var/viewflags = machine.check_eye(src)
|
var/viewflags = machine.check_eye(src)
|
||||||
machine.apply_visual(src)
|
|
||||||
if(viewflags < 0)
|
if(viewflags < 0)
|
||||||
reset_view(null, 0)
|
reset_view(null, 0)
|
||||||
else if(viewflags && !looking_elsewhere)
|
else if(viewflags && !looking_elsewhere)
|
||||||
sight |= viewflags
|
sight |= viewflags
|
||||||
|
else
|
||||||
|
machine.apply_visual(src)
|
||||||
else if(eyeobj)
|
else if(eyeobj)
|
||||||
if(eyeobj.owner != src)
|
if(eyeobj.owner != src)
|
||||||
|
|
||||||
|
|||||||
@@ -173,13 +173,11 @@
|
|||||||
if(ear_damage < 100)
|
if(ear_damage < 100)
|
||||||
adjustEarDamage(-0.05,-1)
|
adjustEarDamage(-0.05,-1)
|
||||||
|
|
||||||
//this handles hud updates. Calls update_vision() and handle_hud_icons()
|
|
||||||
/mob/living/handle_regular_hud_updates()
|
/mob/living/handle_regular_hud_updates()
|
||||||
if(!client)
|
if(!client)
|
||||||
return 0
|
return 0
|
||||||
..()
|
..()
|
||||||
|
|
||||||
handle_vision()
|
|
||||||
handle_darksight()
|
handle_darksight()
|
||||||
handle_hud_icons()
|
handle_hud_icons()
|
||||||
|
|
||||||
|
|||||||
@@ -110,8 +110,8 @@
|
|||||||
|
|
||||||
|
|
||||||
/client/Move(n, direct)
|
/client/Move(n, direct)
|
||||||
if(!mob)
|
//if(!mob) // Clients cannot have a null mob, as enforced by byond
|
||||||
return // Moved here to avoid nullrefs below
|
// return // Moved here to avoid nullrefs below
|
||||||
|
|
||||||
if(mob.control_object) Move_object(direct)
|
if(mob.control_object) Move_object(direct)
|
||||||
|
|
||||||
@@ -166,8 +166,11 @@
|
|||||||
if(!mob.canmove)
|
if(!mob.canmove)
|
||||||
return
|
return
|
||||||
|
|
||||||
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
|
//Relaymove could handle it
|
||||||
// if(!mob.Process_Spacemove(0)) return 0
|
if(mob.machine)
|
||||||
|
var/result = mob.machine.relaymove(mob, direct)
|
||||||
|
if(result)
|
||||||
|
return result
|
||||||
|
|
||||||
if(!mob.lastarea)
|
if(!mob.lastarea)
|
||||||
mob.lastarea = get_area(mob.loc)
|
mob.lastarea = get_area(mob.loc)
|
||||||
@@ -218,10 +221,6 @@
|
|||||||
return
|
return
|
||||||
return mob.buckled.relaymove(mob,direct)
|
return mob.buckled.relaymove(mob,direct)
|
||||||
|
|
||||||
if(istype(mob.machine, /obj/machinery))
|
|
||||||
if(mob.machine.relaymove(mob,direct))
|
|
||||||
return
|
|
||||||
|
|
||||||
if(mob.pulledby || mob.buckled) // Wheelchair driving!
|
if(mob.pulledby || mob.buckled) // Wheelchair driving!
|
||||||
if(istype(mob.loc, /turf/space))
|
if(istype(mob.loc, /turf/space))
|
||||||
return // No wheelchair driving in space
|
return // No wheelchair driving in space
|
||||||
|
|||||||
@@ -255,6 +255,18 @@
|
|||||||
else
|
else
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
|
/obj/item/modular_computer/apply_visual(var/mob/user)
|
||||||
|
if(active_program)
|
||||||
|
return active_program.apply_visual(user)
|
||||||
|
|
||||||
|
/obj/item/modular_computer/remove_visual(var/mob/user)
|
||||||
|
if(active_program)
|
||||||
|
return active_program.remove_visual(user)
|
||||||
|
|
||||||
|
/obj/item/modular_computer/relaymove(var/mob/user, direction)
|
||||||
|
if(active_program)
|
||||||
|
return active_program.relaymove(user, direction)
|
||||||
|
|
||||||
/obj/item/modular_computer/proc/set_autorun(program)
|
/obj/item/modular_computer/proc/set_autorun(program)
|
||||||
if(!hard_drive)
|
if(!hard_drive)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -203,8 +203,12 @@
|
|||||||
|
|
||||||
/datum/computer_file/program/apply_visual(mob/M)
|
/datum/computer_file/program/apply_visual(mob/M)
|
||||||
if(NM)
|
if(NM)
|
||||||
NM.apply_visual(M)
|
return NM.apply_visual(M)
|
||||||
|
|
||||||
/datum/computer_file/program/remove_visual(mob/M)
|
/datum/computer_file/program/remove_visual(mob/M)
|
||||||
if(NM)
|
if(NM)
|
||||||
NM.remove_visual(M)
|
return NM.remove_visual(M)
|
||||||
|
|
||||||
|
/datum/computer_file/program/proc/relaymove(var/mob/M, direction)
|
||||||
|
if(NM)
|
||||||
|
return NM.relaymove(M, direction)
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
/obj/item/modular_computer
|
||||||
|
var/list/paired_uavs //Weakrefs, don't worry about it!
|
||||||
|
|
||||||
|
/datum/computer_file/program/uav
|
||||||
|
filename = "rigger"
|
||||||
|
filedesc = "UAV Control"
|
||||||
|
nanomodule_path = /datum/nano_module/uav
|
||||||
|
program_icon_state = "comm_monitor"
|
||||||
|
program_key_state = "generic_key"
|
||||||
|
program_menu_icon = "link"
|
||||||
|
extended_desc = "This program allows remote control of certain drones, but only when paired with this device."
|
||||||
|
size = 12
|
||||||
|
available_on_ntnet = 1
|
||||||
|
//requires_ntnet = 1
|
||||||
|
|
||||||
|
/datum/nano_module/uav
|
||||||
|
name = "UAV Control program"
|
||||||
|
var/obj/item/device/uav/current_uav = null //The UAV we're watching
|
||||||
|
var/signal_strength = 0 //Our last signal strength report (cached for a few seconds)
|
||||||
|
var/signal_test_counter = 0 //How long until next signal strength check
|
||||||
|
var/list/viewers //Who's viewing a UAV through us
|
||||||
|
var/adhoc_range = 30 //How far we can operate on a UAV without NTnet
|
||||||
|
|
||||||
|
/datum/nano_module/uav/Destroy()
|
||||||
|
if(LAZYLEN(viewers))
|
||||||
|
for(var/weakref/W in viewers)
|
||||||
|
var/M = W.resolve()
|
||||||
|
if(M)
|
||||||
|
unlook(M)
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/datum/nano_module/uav/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, state = default_state)
|
||||||
|
var/list/data = host.initial_data()
|
||||||
|
|
||||||
|
if(current_uav)
|
||||||
|
if(QDELETED(current_uav))
|
||||||
|
set_current(null)
|
||||||
|
else if(signal_test_counter-- <= 0)
|
||||||
|
signal_strength = get_signal_to(current_uav)
|
||||||
|
if(!signal_strength)
|
||||||
|
set_current(null)
|
||||||
|
else // Don't reset counter until we find a UAV that's actually in range we can stay connected to
|
||||||
|
signal_test_counter = 20
|
||||||
|
|
||||||
|
data["current_uav"] = null
|
||||||
|
if(current_uav)
|
||||||
|
data["current_uav"] = list("status" = current_uav.get_status_string(), "power" = current_uav.state == 1 ? 1 : null)
|
||||||
|
data["signal_strength"] = signal_strength ? signal_strength >= 2 ? "High" : "Low" : "None"
|
||||||
|
data["in_use"] = LAZYLEN(viewers)
|
||||||
|
|
||||||
|
var/list/paired_map = list()
|
||||||
|
var/obj/item/modular_computer/mc_host = nano_host()
|
||||||
|
if(istype(mc_host))
|
||||||
|
for(var/puav in mc_host.paired_uavs)
|
||||||
|
var/weakref/wr = puav
|
||||||
|
var/obj/item/device/uav/U = wr.resolve()
|
||||||
|
paired_map[++paired_map.len] = list("name" = "[U ? U.nickname : "!!Missing!!"]", "uavref" = "\ref[U]")
|
||||||
|
|
||||||
|
data["paired_uavs"] = paired_map
|
||||||
|
|
||||||
|
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||||
|
if (!ui)
|
||||||
|
ui = new(user, src, ui_key, "mod_uav.tmpl", "UAV Control", 600, 500, state = state)
|
||||||
|
ui.set_initial_data(data)
|
||||||
|
ui.open()
|
||||||
|
ui.set_auto_update(1)
|
||||||
|
|
||||||
|
/datum/nano_module/uav/Topic(var/href, var/href_list = list(), var/datum/topic_state/state)
|
||||||
|
if((. = ..()))
|
||||||
|
return
|
||||||
|
state = state || DefaultTopicState() || global.default_state
|
||||||
|
if(CanUseTopic(usr, state, href_list) == STATUS_INTERACTIVE)
|
||||||
|
CouldUseTopic(usr)
|
||||||
|
return OnTopic(usr, href_list, state)
|
||||||
|
CouldNotUseTopic(usr)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/datum/nano_module/uav/proc/OnTopic(var/mob/user, var/list/href_list)
|
||||||
|
if(href_list["switch_uav"])
|
||||||
|
var/obj/item/device/uav/U = locate(href_list["switch_uav"]) //This is a \ref to the UAV itself
|
||||||
|
if(!istype(U))
|
||||||
|
to_chat(usr,"<span class='warning'>Something is blocking the connection to that UAV. In-person investigation is required.</span>")
|
||||||
|
return TOPIC_NOACTION
|
||||||
|
|
||||||
|
if(!get_signal_to(U))
|
||||||
|
to_chat(usr,"<span class='warning'>The screen freezes for a moment, before returning to the UAV selection menu. It's not able to connect to that UAV.</span>")
|
||||||
|
return TOPIC_NOACTION
|
||||||
|
|
||||||
|
set_current(U)
|
||||||
|
return TOPIC_REFRESH
|
||||||
|
|
||||||
|
if(href_list["del_uav"])
|
||||||
|
var/refstring = href_list["del_uav"] //This is a \ref to the UAV itself
|
||||||
|
var/obj/item/modular_computer/mc_host = nano_host()
|
||||||
|
//This is so we can really scrape up any weakrefs that can't resolve
|
||||||
|
for(var/weakref/wr in mc_host.paired_uavs)
|
||||||
|
if(wr.ref == refstring)
|
||||||
|
if(current_uav?.weakref == wr)
|
||||||
|
set_current(null)
|
||||||
|
LAZYREMOVE(mc_host.paired_uavs, wr)
|
||||||
|
|
||||||
|
else if(href_list["view_uav"])
|
||||||
|
if(!current_uav)
|
||||||
|
return TOPIC_NOACTION
|
||||||
|
|
||||||
|
if(current_uav.check_eye(user) < 0)
|
||||||
|
to_chat(usr,"<span class='warning'>The screen freezes for a moment, before returning to the UAV selection menu. It's not able to connect to that UAV.</span>")
|
||||||
|
else
|
||||||
|
viewing_uav(user) ? unlook(user) : look(user)
|
||||||
|
return TOPIC_NOACTION
|
||||||
|
|
||||||
|
else if(href_list["power_uav"])
|
||||||
|
if(!current_uav)
|
||||||
|
return TOPIC_NOACTION
|
||||||
|
else if(current_uav.toggle_power())
|
||||||
|
//Clean up viewers faster
|
||||||
|
if(LAZYLEN(viewers))
|
||||||
|
for(var/weakref/W in viewers)
|
||||||
|
var/M = W.resolve()
|
||||||
|
if(M)
|
||||||
|
unlook(M)
|
||||||
|
return TOPIC_REFRESH
|
||||||
|
|
||||||
|
/datum/nano_module/uav/proc/DefaultTopicState()
|
||||||
|
return global.default_state
|
||||||
|
|
||||||
|
/datum/nano_module/uav/proc/CouldNotUseTopic(mob/user)
|
||||||
|
. = ..()
|
||||||
|
unlook(user)
|
||||||
|
|
||||||
|
/datum/nano_module/uav/proc/CouldUseTopic(mob/user)
|
||||||
|
. = ..()
|
||||||
|
if(viewing_uav(user))
|
||||||
|
look(user)
|
||||||
|
|
||||||
|
/datum/nano_module/uav/proc/set_current(var/obj/item/device/uav/U)
|
||||||
|
if(current_uav == U)
|
||||||
|
return
|
||||||
|
|
||||||
|
signal_strength = 0
|
||||||
|
current_uav = U
|
||||||
|
|
||||||
|
if(LAZYLEN(viewers))
|
||||||
|
for(var/weakref/W in viewers)
|
||||||
|
var/M = W.resolve()
|
||||||
|
if(M)
|
||||||
|
if(current_uav)
|
||||||
|
to_chat(M, "<span class='warning'>You're disconnected from the UAV's camera!</span>")
|
||||||
|
unlook(M)
|
||||||
|
else
|
||||||
|
look(M)
|
||||||
|
|
||||||
|
////
|
||||||
|
//// Finding signal strength between us and the UAV
|
||||||
|
////
|
||||||
|
/datum/nano_module/uav/proc/get_signal_to(var/atom/movable/AM)
|
||||||
|
// Following roughly the ntnet signal levels
|
||||||
|
// 0 is none
|
||||||
|
// 1 is weak
|
||||||
|
// 2 is strong
|
||||||
|
var/obj/item/modular_computer/host = nano_host() //Better not add this to anything other than modular computers.
|
||||||
|
if(!istype(host))
|
||||||
|
return
|
||||||
|
var/our_signal = host.get_ntnet_status() //1 low, 2 good, 3 wired, 0 none
|
||||||
|
var/their_z = get_z(AM)
|
||||||
|
|
||||||
|
//If we have no NTnet connection don't bother getting theirs
|
||||||
|
if(!our_signal)
|
||||||
|
if(get_z(host) == their_z && (get_dist(host, AM) < adhoc_range))
|
||||||
|
return 1 //We can connect (with weak signal) in same z without ntnet, within 30 turfs
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
|
||||||
|
var/list/zlevels_in_range = using_map.get_map_levels(their_z, FALSE)
|
||||||
|
var/list/zlevels_in_long_range = using_map.get_map_levels(their_z, TRUE) - zlevels_in_range
|
||||||
|
var/their_signal = 0
|
||||||
|
for(var/relay in ntnet_global.relays)
|
||||||
|
var/obj/machinery/ntnet_relay/R = relay
|
||||||
|
if(!R.operable())
|
||||||
|
continue
|
||||||
|
if(R.z == their_z)
|
||||||
|
their_signal = 2
|
||||||
|
break
|
||||||
|
if(R.z in zlevels_in_range)
|
||||||
|
their_signal = 2
|
||||||
|
break
|
||||||
|
if(R.z in zlevels_in_long_range)
|
||||||
|
their_signal = 1
|
||||||
|
break
|
||||||
|
|
||||||
|
if(!their_signal) //They have no NTnet at all
|
||||||
|
if(get_z(host) == their_z && (get_dist(host, AM) < adhoc_range))
|
||||||
|
return 1 //We can connect (with weak signal) in same z without ntnet, within 30 turfs
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return max(our_signal, their_signal)
|
||||||
|
|
||||||
|
////
|
||||||
|
//// UAV viewer handling
|
||||||
|
////
|
||||||
|
/datum/nano_module/uav/proc/viewing_uav(mob/user)
|
||||||
|
return (weakref(user) in viewers)
|
||||||
|
|
||||||
|
/datum/nano_module/uav/proc/look(var/mob/user)
|
||||||
|
if(issilicon(user)) //Too complicated for me to want to mess with at the moment
|
||||||
|
to_chat(user, "<span class='warning'>Regulations prevent you from controlling several corporeal forms at the same time!</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!current_uav)
|
||||||
|
return
|
||||||
|
|
||||||
|
user.set_machine(nano_host())
|
||||||
|
user.reset_view(current_uav)
|
||||||
|
current_uav.add_master(user)
|
||||||
|
LAZYDISTINCTADD(viewers, weakref(user))
|
||||||
|
|
||||||
|
/datum/nano_module/uav/proc/unlook(var/mob/user)
|
||||||
|
user.unset_machine()
|
||||||
|
user.reset_view()
|
||||||
|
if(current_uav)
|
||||||
|
current_uav.remove_master(user)
|
||||||
|
LAZYREMOVE(viewers, weakref(user))
|
||||||
|
|
||||||
|
/datum/nano_module/uav/check_eye(var/mob/user)
|
||||||
|
if(get_dist(user, nano_host()) > 1 || user.blinded || !current_uav)
|
||||||
|
unlook(user)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
var/viewflag = current_uav.check_eye(user)
|
||||||
|
if (viewflag < 0) //camera doesn't work
|
||||||
|
unlook(user)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
return viewflag
|
||||||
|
|
||||||
|
////
|
||||||
|
//// Relaying movements to the UAV
|
||||||
|
////
|
||||||
|
/datum/nano_module/uav/relaymove(var/mob/user, direction)
|
||||||
|
if(current_uav)
|
||||||
|
return current_uav.relaymove(user, direction, signal_strength)
|
||||||
|
|
||||||
|
////
|
||||||
|
//// The effects when looking through a UAV
|
||||||
|
////
|
||||||
|
/datum/nano_module/uav/apply_visual(var/mob/M)
|
||||||
|
if(!M.client)
|
||||||
|
return
|
||||||
|
if(weakref(M) in viewers)
|
||||||
|
M.overlay_fullscreen("fishbed",/obj/screen/fullscreen/fishbed)
|
||||||
|
M.overlay_fullscreen("scanlines",/obj/screen/fullscreen/scanline)
|
||||||
|
|
||||||
|
if(signal_strength <= 1)
|
||||||
|
M.overlay_fullscreen("whitenoise",/obj/screen/fullscreen/noise)
|
||||||
|
else
|
||||||
|
M.clear_fullscreen("whitenoise", 0)
|
||||||
|
else
|
||||||
|
remove_visual(M)
|
||||||
|
|
||||||
|
/datum/nano_module/uav/remove_visual(mob/M)
|
||||||
|
if(!M.client)
|
||||||
|
return
|
||||||
|
M.clear_fullscreen("fishbed",0)
|
||||||
|
M.clear_fullscreen("scanlines",0)
|
||||||
|
M.clear_fullscreen("whitenoise",0)
|
||||||
@@ -39,6 +39,27 @@ var/global/ntnet_card_uid = 1
|
|||||||
icon_state = "netcard_advanced"
|
icon_state = "netcard_advanced"
|
||||||
hardware_size = 1
|
hardware_size = 1
|
||||||
|
|
||||||
|
/obj/item/weapon/computer_hardware/network_card/quantum
|
||||||
|
name = "quantum NTNet network card"
|
||||||
|
desc = "A network card that can connect to NTnet from anywhere, using quantum entanglement."
|
||||||
|
long_range = 1
|
||||||
|
origin_tech = list(TECH_DATA = 6, TECH_ENGINEERING = 7)
|
||||||
|
power_usage = 200 // Infinite range but higher power usage.
|
||||||
|
icon_state = "netcard_advanced"
|
||||||
|
hardware_size = 1
|
||||||
|
|
||||||
|
/obj/item/weapon/computer_hardware/network_card/quantum/get_signal(var/specific_action = 0)
|
||||||
|
if(!holder2)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if(!enabled)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if(!check_functionality() || !ntnet_global || is_banned())
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return 2
|
||||||
|
|
||||||
/obj/item/weapon/computer_hardware/network_card/wired
|
/obj/item/weapon/computer_hardware/network_card/wired
|
||||||
name = "wired NTNet network card"
|
name = "wired NTNet network card"
|
||||||
desc = "An advanced network card for usage with standard NTNet frequencies. This one also supports wired connection."
|
desc = "An advanced network card for usage with standard NTNet frequencies. This one also supports wired connection."
|
||||||
@@ -82,7 +103,8 @@ var/global/ntnet_card_uid = 1
|
|||||||
var/holderz = get_z(holder2)
|
var/holderz = get_z(holder2)
|
||||||
if(!holderz) //no reception in nullspace
|
if(!holderz) //no reception in nullspace
|
||||||
return 0
|
return 0
|
||||||
var/list/zlevels_in_range = using_map.get_map_levels(holderz, long_range)
|
var/list/zlevels_in_range = using_map.get_map_levels(holderz, FALSE)
|
||||||
|
var/list/zlevels_in_long_range = using_map.get_map_levels(holderz, TRUE) - zlevels_in_range
|
||||||
var/best = 0
|
var/best = 0
|
||||||
for(var/relay in ntnet_global.relays)
|
for(var/relay in ntnet_global.relays)
|
||||||
var/obj/machinery/ntnet_relay/R = relay
|
var/obj/machinery/ntnet_relay/R = relay
|
||||||
@@ -91,11 +113,16 @@ var/global/ntnet_card_uid = 1
|
|||||||
continue
|
continue
|
||||||
//We're on the same z
|
//We're on the same z
|
||||||
if(R.z == holderz)
|
if(R.z == holderz)
|
||||||
best = 2
|
best = 2 //Every network card gets high signal on the same z as the relay
|
||||||
break // No point in going further
|
break // No point in going further
|
||||||
//Not on the same z but within range anyway
|
//Not on the same z but within range anyway
|
||||||
if(R.z in zlevels_in_range)
|
if(R.z in zlevels_in_range)
|
||||||
best = 1
|
best = long_range ? 2 : 1 //High-power network cards get good signal further away
|
||||||
|
break
|
||||||
|
//Only in long range
|
||||||
|
if(long_range && (R.z in zlevels_in_long_range))
|
||||||
|
best = 1 //High-power network cards can get low signal even at long range
|
||||||
|
break
|
||||||
return best
|
return best
|
||||||
return 0 // No computer!
|
return 0 // No computer!
|
||||||
|
|
||||||
|
|||||||
@@ -62,3 +62,6 @@
|
|||||||
|
|
||||||
/datum/proc/update_layout()
|
/datum/proc/update_layout()
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
|
/datum/nano_module/proc/relaymove(var/mob/user, direction)
|
||||||
|
return FALSE
|
||||||
|
|||||||
@@ -1030,3 +1030,12 @@
|
|||||||
req_tech = list(TECH_MATERIAL = 7, TECH_ENGINEERING = 5, TECH_MAGNET = 5, TECH_POWER = 6, TECH_ILLEGAL = 3, TECH_BLUESPACE = 4, TECH_ARCANE = 2, TECH_PRECURSOR = 3)
|
req_tech = list(TECH_MATERIAL = 7, TECH_ENGINEERING = 5, TECH_MAGNET = 5, TECH_POWER = 6, TECH_ILLEGAL = 3, TECH_BLUESPACE = 4, TECH_ARCANE = 2, TECH_PRECURSOR = 3)
|
||||||
materials = list(MAT_DURASTEEL = 5000, MAT_GRAPHITE = 3000, MAT_MORPHIUM = 1500, MAT_OSMIUM = 1500, MAT_PHORON = 1750, MAT_VERDANTIUM = 3000, MAT_SUPERMATTER = 2000)
|
materials = list(MAT_DURASTEEL = 5000, MAT_GRAPHITE = 3000, MAT_MORPHIUM = 1500, MAT_OSMIUM = 1500, MAT_PHORON = 1750, MAT_VERDANTIUM = 3000, MAT_SUPERMATTER = 2000)
|
||||||
build_path = /obj/item/rig_module/teleporter
|
build_path = /obj/item/rig_module/teleporter
|
||||||
|
|
||||||
|
/datum/design/item/mechfab/uav/basic
|
||||||
|
name = "UAV - Recon Skimmer"
|
||||||
|
id = "recon_skimmer"
|
||||||
|
build_path = /obj/item/device/uav
|
||||||
|
time = 20
|
||||||
|
req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 5, TECH_PHORON = 3, TECH_MAGNET = 4, TECH_POWER = 6)
|
||||||
|
materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 6000, "silver" = 4000)
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
BIN
icons/obj/uav.dmi
Normal file
BIN
icons/obj/uav.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
53
nano/templates/mod_uav.tmpl
Normal file
53
nano/templates/mod_uav.tmpl
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<div class='block'>
|
||||||
|
<div class='item'>
|
||||||
|
<div class='itemLabelNarrow'>UAV:</div>
|
||||||
|
<div>
|
||||||
|
{{if data.current_uav}}
|
||||||
|
{{:data.current_uav.status}}
|
||||||
|
{{else}}
|
||||||
|
[Not Connected]
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='item'>
|
||||||
|
<div class='itemLabelNarrow'>Signal:</div>
|
||||||
|
<div>
|
||||||
|
{{if data.current_uav}}
|
||||||
|
{{:data.signal_strength}}
|
||||||
|
{{else}}
|
||||||
|
[Not Connected]
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='item'>
|
||||||
|
<div class='itemLabelNarrow'>Power:</div>
|
||||||
|
<div>
|
||||||
|
{{if data.current_uav}}
|
||||||
|
{{:helper.link(data.current_uav.power ? 'Online' : 'Offline', data.current_uav.power ? 'check' : 'close', {'power_uav' : 1}, null, data.current_uav.power ? 'linkOn' : 'redButton')}}
|
||||||
|
{{else}}
|
||||||
|
[Not Connected]
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='item'>
|
||||||
|
<div class='itemLabelNarrow'>Camera:</div>
|
||||||
|
<div>
|
||||||
|
{{if data.current_uav}}
|
||||||
|
{{:helper.link(data.current_uav.power ? 'Available' : 'Unavailable', data.current_uav.power ? 'check' : 'close', {'view_uav' : 1}, null, data.in_use ? 'linkOn' : null)}}
|
||||||
|
{{else}}
|
||||||
|
[Not Connected]
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='item'>
|
||||||
|
<div class='itemLabel'>Paired UAVs:</div>
|
||||||
|
</div>
|
||||||
|
{{for data.paired_uavs}}
|
||||||
|
<div>
|
||||||
|
{{:helper.link(value.name, '', {'switch_uav' : value.uavref})}}{{:helper.link('', 'close', {'del_uav' : value.uavref}, null, 'redButton')}}
|
||||||
|
</div>
|
||||||
|
{{/for}}
|
||||||
@@ -1069,6 +1069,7 @@
|
|||||||
#include "code\game\objects\items\trash.dm"
|
#include "code\game\objects\items\trash.dm"
|
||||||
#include "code\game\objects\items\trash_material.dm"
|
#include "code\game\objects\items\trash_material.dm"
|
||||||
#include "code\game\objects\items\trash_vr.dm"
|
#include "code\game\objects\items\trash_vr.dm"
|
||||||
|
#include "code\game\objects\items\uav.dm"
|
||||||
#include "code\game\objects\items\devices\advnifrepair.dm"
|
#include "code\game\objects\items\devices\advnifrepair.dm"
|
||||||
#include "code\game\objects\items\devices\ai_detector.dm"
|
#include "code\game\objects\items\devices\ai_detector.dm"
|
||||||
#include "code\game\objects\items\devices\aicard.dm"
|
#include "code\game\objects\items\devices\aicard.dm"
|
||||||
@@ -2803,6 +2804,7 @@
|
|||||||
#include "code\modules\modular_computers\file_system\programs\generic\ntdownloader.dm"
|
#include "code\modules\modular_computers\file_system\programs\generic\ntdownloader.dm"
|
||||||
#include "code\modules\modular_computers\file_system\programs\generic\ntnrc_client.dm"
|
#include "code\modules\modular_computers\file_system\programs\generic\ntnrc_client.dm"
|
||||||
#include "code\modules\modular_computers\file_system\programs\generic\nttransfer.dm"
|
#include "code\modules\modular_computers\file_system\programs\generic\nttransfer.dm"
|
||||||
|
#include "code\modules\modular_computers\file_system\programs\generic\uav.dm"
|
||||||
#include "code\modules\modular_computers\file_system\programs\generic\wordprocessor.dm"
|
#include "code\modules\modular_computers\file_system\programs\generic\wordprocessor.dm"
|
||||||
#include "code\modules\modular_computers\file_system\programs\medical\suit_sensors.dm"
|
#include "code\modules\modular_computers\file_system\programs\medical\suit_sensors.dm"
|
||||||
#include "code\modules\modular_computers\file_system\programs\research\email_administration.dm"
|
#include "code\modules\modular_computers\file_system\programs\research\email_administration.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user