Merge pull request #8816 from atlantiscze/nanocrusade-two

Nano Crusade 2
This commit is contained in:
Zuhayr
2015-05-23 20:44:28 +09:30
5 changed files with 335 additions and 206 deletions

View File

@@ -1,5 +1,3 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
/obj/machinery/computer/robotics
name = "robotics control console"
desc = "Used to remotely lockdown or detonate linked cyborgs."
@@ -9,218 +7,205 @@
req_access = list(access_robotics)
circuit = "/obj/item/weapon/circuitboard/robotics"
var/id = 0.0
var/temp = null
var/status = 0
var/timeleft = 60
var/stop = 0.0
var/screen = 0 // 0 - Main Menu, 1 - Cyborg Status, 2 - Kill 'em All! -- In text
var/safety = 1
/obj/machinery/computer/robotics/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
ui_interact(user)
/obj/machinery/computer/robotics/attack_hand(var/mob/user as mob)
if(..())
return
if (src.z > 6)
user << "\red <b>Unable to establish a connection</b>: \black You're too far away from the station!"
return
user.set_machine(src)
var/dat
if (src.temp)
dat = "<TT>[src.temp]</TT><BR><BR><A href='?src=\ref[src];temp=1'>Clear Screen</A>"
else
if(screen == 0)
dat += "<h3>Cyborg Control Console</h3><BR>"
dat += "<A href='?src=\ref[src];screen=1'>1. Cyborg Status</A><BR>"
dat += "<A href='?src=\ref[src];screen=2'>2. Emergency Full Destruct</A><BR>"
if(screen == 1)
for(var/mob/living/silicon/robot/R in mob_list)
if(istype(R, /mob/living/silicon/robot/drone))
continue //There's a specific console for drones.
if(istype(user, /mob/living/silicon/ai))
if (R.connected_ai != user)
continue
if(istype(user, /mob/living/silicon/robot))
if (R != user)
continue
if(R.scrambledcodes)
continue
ui_interact(user)
dat += "[R.name] |"
if(R.stat)
dat += " Not Responding |"
else if (!R.canmove)
dat += " Locked Down |"
else
dat += " Operating Normally |"
if (!R.canmove)
else if(R.cell)
dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |"
else
dat += " No Cell Installed |"
if(R.module)
dat += " Module Installed ([R.module.name]) |"
else
dat += " No Module Installed |"
if(R.connected_ai)
dat += " Slaved to [R.connected_ai.name] |"
else
dat += " Independent from AI |"
if (istype(user, /mob/living/silicon))
if((user.mind.special_role && user.mind.original == user) && !R.emagged)
dat += "<A href='?src=\ref[src];magbot=\ref[R]'>(<font color=blue><i>Hack</i></font>)</A> "
dat += "<A href='?src=\ref[src];stopbot=\ref[R]'>(<font color=green><i>[R.canmove ? "Lockdown" : "Release"]</i></font>)</A> "
dat += "<A href='?src=\ref[src];killbot=\ref[R]'>(<font color=red><i>Destroy</i></font>)</A>"
dat += "<BR>"
dat += "<A href='?src=\ref[src];screen=0'>(Return to Main Menu)</A><BR>"
if(screen == 2)
if(!src.status)
dat += {"<BR><B>Emergency Robot Self-Destruct</B><HR>\nStatus: Off<BR>
\n<BR>
\nCountdown: [src.timeleft]/60 <A href='?src=\ref[src];reset=1'>\[Reset\]</A><BR>
\n<BR>
\n<A href='?src=\ref[src];eject=1'>Start Sequence</A><BR>
\n<BR>
\n<A href='?src=\ref[user];mach_close=computer'>Close</A>"}
else
dat = {"<B>Emergency Robot Self-Destruct</B><HR>\nStatus: Activated<BR>
\n<BR>
\nCountdown: [src.timeleft]/60 \[Reset\]<BR>
\n<BR>\n<A href='?src=\ref[src];stop=1'>Stop Sequence</A><BR>
\n<BR>
\n<A href='?src=\ref[user];mach_close=computer'>Close</A>"}
dat += "<A href='?src=\ref[src];screen=0'>(Return to Main Menu)</A><BR>"
/obj/machinery/computer/robotics/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
data["robots"] = get_cyborgs(user)
data["safety"] = safety
// Also applies for cyborgs. Hides the manual self-destruct button.
data["is_ai"] = user.isSilicon()
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
return
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "robot_control.tmpl", "Robotic Control Console", 400, 500)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/robotics/Topic(href, href_list)
if(..())
return 1
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
return
var/mob/user = usr
if(!src.allowed(user))
user << "Access Denied"
return
if (href_list["eject"])
src.temp = {"Destroy Robots?<BR>
<BR><B><A href='?src=\ref[src];eject2=1'>\[Swipe ID to initiate destruction sequence\]</A></B><BR>
<A href='?src=\ref[src];temp=1'>Cancel</A>"}
else if (href_list["eject2"])
var/obj/item/weapon/card/id/I = usr.get_active_hand()
if (istype(I, /obj/item/device/pda))
var/obj/item/device/pda/pda = I
I = pda.id
if (istype(I))
if(src.check_access(I))
if (!status)
message_admins("\blue [key_name_admin(usr)] has initiated the global cyborg killswitch!")
log_game("\blue [key_name(usr)] has initiated the global cyborg killswitch!")
src.status = 1
src.start_sequence()
src.temp = null
else
usr << "\red Access Denied."
else if (href_list["stop"])
src.temp = {"
Stop Robot Destruction Sequence?<BR>
<BR><A href='?src=\ref[src];stop2=1'>Yes</A><BR>
<A href='?src=\ref[src];temp=1'>No</A>"}
else if (href_list["stop2"])
src.stop = 1
src.temp = null
src.status = 0
else if (href_list["reset"])
src.timeleft = 60
else if (href_list["temp"])
src.temp = null
else if (href_list["screen"])
switch(href_list["screen"])
if("0")
screen = 0
if("1")
screen = 1
if("2")
screen = 2
else if (href_list["killbot"])
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["killbot"])
if(R)
var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm")
if(R && istype(R))
if(R.mind && R.mind.special_role && R.emagged)
R << "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered."
R.ResetSecurityCodes()
else
message_admins("\blue [key_name_admin(usr)] detonated [R.name]!")
log_game("\blue [key_name_admin(usr)] detonated [R.name]!")
R.self_destruct()
else
usr << "\red Access Denied."
else if (href_list["stopbot"])
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["stopbot"])
if(R && istype(R)) // Extra sancheck because of input var references
var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm")
if(R && istype(R))
message_admins("\blue [key_name_admin(usr)] [R.canmove ? "locked down" : "released"] [R.name]!")
log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [R.name]!")
R.canmove = !R.canmove
if (R.lockcharge)
// R.cell.charge = R.lockcharge
R.lockcharge = !R.lockcharge
R << "Your lockdown has been lifted!"
else
R.lockcharge = !R.lockcharge
// R.cell.charge = 0
R << "You have been locked down!"
else
usr << "\red Access Denied."
else if (href_list["magbot"])
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["magbot"])
// whatever weirdness this is supposed to be, but that is how the href gets added, so here it is again
if(istype(R) && istype(usr, /mob/living/silicon) && usr.mind.special_role && (usr.mind.original == usr) && !R.emagged)
var/choice = input("Are you certain you wish to hack [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm")
if(R && istype(R))
// message_admins("\blue [key_name_admin(usr)] emagged [R.name] using robotic console!")
log_game("[key_name(usr)] emagged [R.name] using robotic console!")
R.emagged = 1
if(R.mind.special_role)
R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes
src.add_fingerprint(usr)
src.updateUsrDialog()
return
/obj/machinery/computer/robotics/proc/start_sequence()
do
if(src.stop)
src.stop = 0
// Destroys the cyborg
if(href_list["detonate"])
var/mob/living/silicon/robot/target = get_cyborg_by_name(href_list["detonate"])
if(!target || !istype(target))
return
src.timeleft--
sleep(10)
while(src.timeleft)
if(user.isMobAI() && (target.connected_ai != user))
user << "Access Denied. This robot is not linked to you."
return
// Cyborgs may blow up themselves via the console
if(isrobot(user) && user != target)
user << "Access Denied."
return
var/choice = input("Really detonate [target.name]?") in list ("Yes", "No")
if(choice != "Yes")
return
if(!target || !istype(target))
return
// Antagonistic cyborgs? Left here for downstream
if(target.mind && target.mind.special_role && target.emagged)
target << "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered."
target.ResetSecurityCodes()
else
message_admins("\blue [key_name_admin(usr)] detonated [target.name]!")
log_game("\blue [key_name_admin(usr)] detonated [target.name]!")
target << "<span class='danger'>Self-destruct command received.</span>"
spawn(10)
target.self_destruct()
// Locks or unlocks the cyborg
else if (href_list["lockdown"])
var/mob/living/silicon/robot/target = get_cyborg_by_name(href_list["lockdown"])
if(!target || !istype(target))
return
if(user.isMobAI() && (target.connected_ai != user))
user << "Access Denied. This robot is not linked to you."
return
if(isrobot(user))
user << "Access Denied."
return
var/choice = input("Really [target.lockcharge ? "unlock" : "lockdown"] [target.name] ?") in list ("Yes", "No")
if(choice != "Yes")
return
if(!target || !istype(target))
return
message_admins("\blue [key_name_admin(usr)] [target.canmove ? "locked down" : "released"] [target.name]!")
log_game("[key_name(usr)] [target.canmove ? "locked down" : "released"] [target.name]!")
target.canmove = !target.canmove
if (target.lockcharge)
target.lockcharge = !target.lockcharge
target << "Your lockdown has been lifted!"
else
target.lockcharge = !target.lockcharge
target << "You have been locked down!"
// Remotely hacks the cyborg. Only antag AIs can do this and only to linked cyborgs.
else if (href_list["hack"])
var/mob/living/silicon/robot/target = get_cyborg_by_name(href_list["hack"])
if(!target || !istype(target))
return
// Antag AI checks
if(!istype(user, /mob/living/silicon/ai) || !(user.mind.special_role && user.mind.original == user))
user << "Access Denied"
return
if(target.emagged)
user << "Robot is already hacked."
return
var/choice = input("Really hack [target.name]? This cannot be undone.") in list("Yes", "No")
if(choice != "Yes")
return
if(!target || !istype(target))
return
message_admins("\blue [key_name_admin(usr)] emagged [target.name] using robotic console!")
log_game("[key_name(usr)] emagged [target.name] using robotic console!")
target.emagged = 1
target << "<span class='notice'>Failsafe protocols overriden. New tools available.</span>"
// Arms the emergency self-destruct system
else if(href_list["arm"])
if(istype(user, /mob/living/silicon))
user << "Access Denied"
return
safety = !safety
user << "You [safety ? "disarm" : "arm"] the emergency self destruct"
// Destroys all accessible cyborgs if safety is disabled
else if(href_list["nuke"])
if(istype(user, /mob/living/silicon))
user << "Access Denied"
return
if(safety)
user << "Self-destruct aborted - safety active"
return
message_admins("\blue [key_name_admin(usr)] detonated all cyborgs!")
log_game("[key_name(usr)] detonated all cyborgs!")
for(var/mob/living/silicon/robot/R in mob_list)
if(istype(R, /mob/living/silicon/robot/drone))
continue
// Ignore antagonistic cyborgs
if(R.scrambledcodes)
continue
R << "<span class='danger'>Self-destruct command received.</span>"
spawn(10)
R.self_destruct()
// Proc: get_cyborgs()
// Parameters: 1 (operator - mob which is operating the console.)
// Description: Returns NanoUI-friendly list of accessible cyborgs.
/obj/machinery/computer/robotics/proc/get_cyborgs(var/mob/operator)
var/list/robots = list()
for(var/mob/living/silicon/robot/R in mob_list)
if(!R.scrambledcodes && !istype(R, /mob/living/silicon/robot/drone))
R.self_destruct()
// Ignore drones
if(istype(R, /mob/living/silicon/robot/drone))
continue
// Ignore antagonistic cyborgs
if(R.scrambledcodes)
continue
return
var/list/robot = list()
robot["name"] = R.name
if(R.stat)
robot["status"] = "Not Responding"
else if (!R.canmove)
robot["status"] = "Lockdown"
else
robot["status"] = "Operational"
if(R.cell)
robot["cell"] = 1
robot["cell_capacity"] = R.cell.maxcharge
robot["cell_current"] = R.cell.charge
robot["cell_percentage"] = round(R.cell.percent())
else
robot["cell"] = 0
robot["module"] = R.module ? R.module.name : "None"
robot["master_ai"] = R.connected_ai ? R.connected_ai.name : "None"
robot["hackable"] = 0
// Antag AIs know whether linked cyborgs are hacked or not.
if(operator && istype(operator, /mob/living/silicon/ai) && (R.connected_ai == operator) && (operator.mind.special_role && operator.mind.original == operator))
robot["hacked"] = R.emagged ? 1 : 0
robot["hackable"] = R.emagged? 0 : 1
robots.Add(list(robot))
return robots
// Proc: get_cyborg_by_name()
// Parameters: 1 (name - Cyborg we are trying to find)
// Description: Helper proc for finding cyborg by name
/obj/machinery/computer/robotics/proc/get_cyborg_by_name(var/name)
if (!name)
return
for(var/mob/living/silicon/robot/R in mob_list)
if(R.name == name)
return R

View File

@@ -120,10 +120,15 @@
if(lum != light_range || clr != light_color)
set_light(lum, l_color = clr)
/obj/machinery/power/supermatter/proc/announce_warning()
/obj/machinery/power/supermatter/proc/get_integrity()
var/integrity = damage / explosion_point
integrity = round(100 - integrity * 100)
integrity = integrity < 0 ? 0 : integrity
return integrity
/obj/machinery/power/supermatter/proc/announce_warning()
var/integrity = get_integrity()
var/alert_msg = " Integrity at [integrity]%"
if(damage > emergency_point)
@@ -267,11 +272,11 @@
if(Adjacent(user))
return attack_hand(user)
else
user << "<span class = \"warning\">You attempt to interface with the control circuits but find they are not connected to your network. Maybe in a future firmware update.</span>"
ui_interact(user)
return
/obj/machinery/power/supermatter/attack_ai(mob/user as mob)
user << "<span class = \"warning\">You attempt to interface with the control circuits but find they are not connected to your network. Maybe in a future firmware update.</span>"
ui_interact(user)
/obj/machinery/power/supermatter/attack_hand(mob/user as mob)
user.visible_message("<span class=\"warning\">\The [user] reaches out and touches \the [src], inducing a resonance... \his body starts to glow and bursts into flames before flashing into ash.</span>",\
@@ -280,6 +285,31 @@
Consume(user)
// This is purely informational UI that may be accessed by AIs or robots
/obj/machinery/power/supermatter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
data["integrity_percentage"] = round(get_integrity())
var/datum/gas_mixture/env = null
if(!istype(src.loc, /turf/space))
env = src.loc.return_air()
if(!env)
data["ambient_temp"] = 0
data["ambient_pressure"] = 0
else
data["ambient_temp"] = round(env.temperature)
data["ambient_pressure"] = round(env.return_pressure())
data["detonating"] = grav_pulling
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "supermatter_crystal.tmpl", "Supermatter Crystal", 500, 300)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/*
/obj/machinery/power/supermatter/proc/transfer_energy()
for(var/obj/machinery/power/rad_collector/R in rad_collectors)

View File

@@ -0,0 +1,6 @@
author: Atlantis
delete-after: True
changes:
- rscadd: "NanoUI for Robotics Control Console"
- rscdel: "NanoUI for Supermatter Crystal - AI/Robot only, purely informational"

View File

@@ -0,0 +1,83 @@
{{if !data.is_ai}}
<div class='notice'>
<div class="itemContentSmall" style="width: 180px">
Emergency Self-Destruct:
</div>
<div class="itemContentFull">
{{if data.safety}}
{{:helper.link('ARM', 'unlocked', {'arm' : 1})}}
{{:helper.link('DETONATE', 'radiation', {'nuke' : 1}, 'disabled')}}
{{else}}
{{:helper.link('DISARM', 'locked', {'arm' : 1})}}
{{:helper.link('DETONATE', 'radiation', {'nuke' : 1}, null, 'redButton')}}
{{/if}}
</div>
<div class="clearBoth"></div>
</div>
{{/if}}
{{for data.robots}}
<hr>
<div class='item'>
<h2>{{:value.name}}</h2>
<h3>Information</h3>
<span class="itemLabel">
Status:
</span>
<span class="itemContent">
{{:value.status}}
</span>
<span class="itemLabel">
Master AI:
</span>
<span class="itemContent">
{{:value.master_ai}}
</span>
<span class="itemLabel">
Module:
</span>
<span class="itemContent">
{{:value.module}}
</span>
{{if value.hackable}}
<span class="itemLabel">
Safeties:
</span>
<span class="itemContent">
ENABLED
</span>
{{else value.hacked}}
<span class="itemLabel">
Safeties:
</span>
<span class="itemContent">
DISABLED
</span>
{{/if}}
<h3>Power Cell</h3>
{{if value.cell}}
<span class="itemLabel">
Rating :
</span>
<span class="itemContent">
{{:value.cell_capacity}}
</span>
{{:helper.displayBar(value.cell_percentage, 0, 100, (value.cell_percentage >= 50) ? 'good' : (value.cell_percentage >= 25) ? 'average' : 'bad')}}
<b> {{:value.cell_percentage}} %</b>
{{else}}
<b><i>Not Installed</i></b>
{{:helper.displayBar(100, 0, 100, 'bad')}}
<b> N/A %</b>
{{/if}}
<h3>Actions</h3>
{{if value.status == "Operational"}}
{{:helper.link('Lockdown', 'locked', {'lockdown' : value.name})}}
{{else}}
{{:helper.link('Unlock', 'unlocked', {'lockdown' : value.name})}}
{{/if}}
{{:helper.link('Self-Destruct', 'radiation', {'detonate' : value.name}, null, 'redButton')}}
{{if value.hackable}}
{{:helper.link('Hack', 'calculator', {'hack' : value.name}, null, 'redButton')}}
{{/if}}
</div>
{{/for}}

View File

@@ -0,0 +1,25 @@
{{if data.detonating}}
<div class="notice" style="color: #000000;">
<h2 style="color: #000000;">CRYSTAL DELAMINATING</h2>
<h3 style="color: #000000;">Evacuate area immediately</h3>
<div class="clearBoth"></div>
</div>
{{else}}
<h3>Crystal Integrity</h3>
{{:helper.displayBar(data.integrity_percentage, 0, 100, (data.integrity_percentage >= 90) ? 'good' : (data.integrity_percentage >= 25) ? 'average' : 'bad')}}
<b>{{:data.integrity_percentage}} %</b>
<h3>Environment</h3>
<span class="itemLabel">
Temperature:
</span>
<span class="itemContent">
{{:helper.displayBar(data.ambient_temp, 0, 10000, (data.ambient_temp >= 5000) ? 'bad' : (data.ambient_temp >= 4000) ? 'average' : 'good')}}
{{:data.ambient_temp}} K
</span>
<span class="itemLabel">
Pressure:
</span>
<span class="itemContent">
{{:data.ambient_pressure}} kPa
</span>
{{/if}}