From c9914063555c5c85abeeb14714df60b90173f45a Mon Sep 17 00:00:00 2001 From: Markolie Date: Mon, 17 Aug 2015 20:30:19 +0200 Subject: [PATCH 01/30] Hostile lockdown nerf --- code/defines/procs/announce.dm | 11 ++++- .../gamemodes/malfunction/Malf_Modules.dm | 46 +++++++------------ code/modules/mob/living/silicon/ai/ai.dm | 1 - .../security levels/keycard authentication.dm | 6 +-- 4 files changed, 27 insertions(+), 37 deletions(-) diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index 1211f9e14f8..34822d2d509 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -1,3 +1,4 @@ +/var/datum/announcement/minor/minor_announcement = new() /var/datum/announcement/priority/priority_announcement = new(do_log = 0) /var/datum/announcement/priority/command/command_announcement = new(do_log = 0, do_newscast = 1) @@ -15,6 +16,11 @@ sound = new_sound log = do_log newscast = do_newscast + +/datum/announcement/minor/New(var/do_log = 0, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) + ..(do_log, new_sound, do_newscast) + title = "Attention" + announcement_type = "Minor Announcement" /datum/announcement/priority/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) ..(do_log, new_sound, do_newscast) @@ -55,8 +61,9 @@ datum/announcement/proc/Message(message as text, message_title as text) if (announcer) M << " -[html_encode(announcer)]" -datum/announcement/minor/Message(message as text, message_title as text) - world << "[message]" +/datum/announcement/minor/Message(message as text, message_title as text) + world << "[message_title]" + world << "[message]" datum/announcement/priority/Message(message as text, message_title as text) world << "

[message_title]

" diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index f32407a62af..d1bc36e3625 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -79,8 +79,8 @@ rcd light flash thingy on matter drain /datum/AI_Module/large/lockdown module_name = "Hostile Station Lockdown" mod_pick_name = "lockdown" - description = "Take control of the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks." - cost = 20 + description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 90 seconds." + cost = 30 one_time = 1 power_type = /mob/living/silicon/ai/proc/lockdown @@ -89,15 +89,12 @@ rcd light flash thingy on matter drain set category = "Malfunction" set name = "Initiate Hostile Lockdown" - if(src.stat == 2) - src <<"You cannot begin a lockdown because you are dead!" - return - - if(malf_cooldown) + if(src.stat == DEAD) + src << "You cannot begin a lockdown because you are dead!" return var/obj/machinery/door/airlock/AL - for(var/obj/machinery/door/D in airlocks) + for(var/obj/machinery/door/airlock/D in airlocks) if(!(D.z in config.contact_levels)) continue spawn() @@ -107,8 +104,7 @@ rcd light flash thingy on matter drain AL.locked = 0 //For airlocks that were bolted open. AL.safe = 0 //DOOR CRUSH AL.close() - AL.locked = 1 //Bolt it! - AL.lights = 0 //Stealth bolt for a classic AI door trap. + AL.lock() AL.electrified_until = -1 //Shock it! else if(!D.stat) //So that only powered doors are closed. D.close() //Close ALL the doors! @@ -117,40 +113,30 @@ rcd light flash thingy on matter drain if(C) C.post_status("alert", "lockdown") - src.verbs += /mob/living/silicon/ai/proc/disablelockdown - src << "Lockdown Initiated." - malf_cooldown = 1 - spawn(30) - malf_cooldown = 0 + verbs -= /mob/living/silicon/ai/proc/lockdown + minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.","Network Alert") + src << "Lockdown initiated. Network reset in 90 seconds." + spawn(900) //90 Seconds. + disablelockdown() //Reset the lockdown after 90 seconds. /mob/living/silicon/ai/proc/disablelockdown() set category = "Malfunction" set name = "Disable Lockdown" - if(src.stat == 2) - src <<"You cannot disable lockdown because you are dead!" - return - if(malf_cooldown) - return - var/obj/machinery/door/airlock/AL - for(var/obj/machinery/door/D in airlocks) + for(var/obj/machinery/door/airlock/D in airlocks) spawn() if(istype(D, /obj/machinery/door/airlock)) AL = D if(AL.canAIControl() && !AL.stat) //Must be powered and have working AI wire. - AL.locked = 0 + AL.unlock() AL.electrified_until = 0 AL.open() AL.safe = 1 - AL.lights = 1 //Essentially reset the airlock to normal. else if(!D.stat) //Opens only powered doors. - D.open() //Open everything! - - src << "Lockdown Lifted." - malf_cooldown = 1 - spawn(30) - malf_cooldown = 0 + D.open() //Open everything! + + minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network Reset") /datum/AI_Module/large/disable_rcd module_name = "RCD disable" diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index c89552719bb..8fe44113b27 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -69,7 +69,6 @@ var/list/ai_verbs_default = list( var/control_disabled = 0 // Set to 1 to stop AI from interacting via Click() -- TLE var/malfhacking = 0 // More or less a copy of the above var, so that malf AIs can hack and still get new cyborgs -- NeoFite - var/malf_cooldown = 0 //Cooldown var for malf modules var/obj/machinery/power/apc/malfhack = null var/explosive = 0 //does the AI explode when it dies? diff --git a/code/modules/security levels/keycard authentication.dm b/code/modules/security levels/keycard authentication.dm index 0950f5d1594..b0909f87af6 100644 --- a/code/modules/security levels/keycard authentication.dm +++ b/code/modules/security levels/keycard authentication.dm @@ -174,8 +174,7 @@ var/global/maint_all_access = 0 for(var/obj/machinery/door/airlock/D in A) D.emergency = 1 D.update_icon(0) - world << "Attention!" - world << "The maintenance access requirement has been revoked on all airlocks." + minor_announcement.Announce("The maintenance access requirement has been revoked on all airlocks.") maint_all_access = 1 /proc/revoke_maint_all_access() @@ -183,6 +182,5 @@ var/global/maint_all_access = 0 for(var/obj/machinery/door/airlock/D in A) D.emergency = 0 D.update_icon(0) - world << "Attention!" - world << "The maintenance access requirement has been readded on all maintenance airlocks." + minor_announcement.Announce("The maintenance access requirement has been readded on all maintenance airlocks.") maint_all_access = 0 \ No newline at end of file From 13acca11a35d3c91f07e8b66e79fad15f82ff37f Mon Sep 17 00:00:00 2001 From: Markolie Date: Mon, 17 Aug 2015 20:33:00 +0200 Subject: [PATCH 02/30] Z check for lockdown lift --- code/game/gamemodes/malfunction/Malf_Modules.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index d1bc36e3625..363053d4984 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -125,6 +125,8 @@ rcd light flash thingy on matter drain var/obj/machinery/door/airlock/AL for(var/obj/machinery/door/airlock/D in airlocks) + if(!(D.z in config.contact_levels)) + continue spawn() if(istype(D, /obj/machinery/door/airlock)) AL = D From 80360fd8a97f52b73beebd730d39d84c8ad8df69 Mon Sep 17 00:00:00 2001 From: Markolie Date: Tue, 18 Aug 2015 20:22:38 +0200 Subject: [PATCH 03/30] Malf AI update --- code/__DEFINES/misc.dm | 5 + code/_globalvars/lists/objects.dm | 4 +- code/_onclick/ai.dm | 2 + .../gamemodes/malfunction/Malf_Modules.dm | 234 ++++++++++------ .../game/gamemodes/malfunction/malfunction.dm | 11 +- code/game/machinery/computer/ai_core.dm | 215 ++------------ code/game/machinery/computer/aifixer.dm | 84 +++--- code/game/mecha/equipment/tools/tools.dm | 14 +- code/game/mecha/mecha.dm | 264 ++++++++++-------- code/game/objects/items/devices/aicard.dm | 211 +++++++------- code/game/objects/items/weapons/RCD.dm | 8 +- code/modules/mob/living/silicon/ai/ai.dm | 30 +- code/modules/mob/living/silicon/ai/life.dm | 4 +- code/modules/mob/mob_movement.dm | 9 +- 14 files changed, 546 insertions(+), 549 deletions(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 4a5b588a629..4efd869751f 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -134,6 +134,11 @@ #define RESIZE_DEFAULT_SIZE 1 +//transfer_ai() defines. Main proc in ai_core.dm +#define AI_TRANS_TO_CARD 1 //Downloading AI to InteliCard. +#define AI_TRANS_FROM_CARD 2 //Uploading AI from InteliCard +#define AI_MECH_HACK 3 //Malfunctioning AI hijacking mecha + //singularity defines #define STAGE_ONE 1 #define STAGE_TWO 3 diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 8c419cc35fb..690ac0e5c5b 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -17,6 +17,6 @@ var/global/list/table_recipes = list() //list of all table craft recipes var/global/list/all_areas = list() var/global/list/machines = list() -var/global/list/processing_power_items = list() - //items that ask to be called every cycle +var/global/list/processing_power_items = list() //items that ask to be called every cycle +var/global/list/rcd_list = list() //list of Rapid Construction Devices. diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index ca02a66a463..ed0e976c5da 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -43,6 +43,8 @@ return if(modifiers["middle"]) MiddleClickOn(A) + if(controlled_mech) //Are we piloting a mech? Placed here so the modifiers are not overridden. + controlled_mech.click_action(A, src) //Override AI normal click behavior. return if(modifiers["shift"]) ShiftClickOn(A) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 363053d4984..a464bfc29cd 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -34,7 +34,7 @@ rcd light flash thingy on matter drain /datum/AI_Module/large/fireproof_core - module_name = "Core upgrade" + module_name = "Core Upgrade" mod_pick_name = "coreup" description = "An upgrade to improve core resistance, making it immune to fire and heat. This effect is permanent." cost = 50 @@ -51,9 +51,9 @@ rcd light flash thingy on matter drain src << "Core fireproofed." /datum/AI_Module/large/upgrade_turrets - module_name = "AI Turret upgrade" + module_name = "AI Turret Upgrade" mod_pick_name = "turret" - description = "Improves the firing speed and health of all AI turrets. This effect is permanent." + description = "Improves the firing power and health of all AI turrets. This effect is permanent." cost = 50 one_time = 1 @@ -62,26 +62,25 @@ rcd light flash thingy on matter drain /mob/living/silicon/ai/proc/upgrade_turrets() set category = "Malfunction" set name = "Upgrade Turrets" + + if(stat) + return + src.verbs -= /mob/living/silicon/ai/proc/upgrade_turrets - for(var/obj/machinery/turret/turret in machines) - var/turf/T = get_turf(turret) - if(T.z in config.station_levels) - turret.health += 30 - turret.shot_delay = 20 for(var/obj/machinery/porta_turret/turret in machines) var/turf/T = get_turf(turret) if(T.z in config.station_levels) // Increase health by 37.5% of original max, decrease delays between shots to 66% turret.health += initial(turret.health) * 3 / 8 - turret.shot_delay = initial(turret.shot_delay) * 2 / 3 + turret.eprojectile = /obj/item/projectile/beam/heavylaser //Once you see it, you will know what it means to FEAR. + turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg' src << "Turrets upgraded." /datum/AI_Module/large/lockdown module_name = "Hostile Station Lockdown" mod_pick_name = "lockdown" - description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 90 seconds." - cost = 30 - one_time = 1 + description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 120 seconds." + cost = 20 power_type = /mob/living/silicon/ai/proc/lockdown @@ -89,12 +88,11 @@ rcd light flash thingy on matter drain set category = "Malfunction" set name = "Initiate Hostile Lockdown" - if(src.stat == DEAD) - src << "You cannot begin a lockdown because you are dead!" + if(stat) return - + var/obj/machinery/door/airlock/AL - for(var/obj/machinery/door/airlock/D in airlocks) + for(var/obj/machinery/door/D in airlocks) if(!(D.z in config.contact_levels)) continue spawn() @@ -115,16 +113,16 @@ rcd light flash thingy on matter drain verbs -= /mob/living/silicon/ai/proc/lockdown minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.","Network Alert") - src << "Lockdown initiated. Network reset in 90 seconds." - spawn(900) //90 Seconds. - disablelockdown() //Reset the lockdown after 90 seconds. + src << "Lockdown initiated. Network reset in two minutes." + spawn(1200) //120 Seconds. + disablelockdown() //Reset the lockdown after 120 seconds. /mob/living/silicon/ai/proc/disablelockdown() set category = "Malfunction" set name = "Disable Lockdown" var/obj/machinery/door/airlock/AL - for(var/obj/machinery/door/airlock/D in airlocks) + for(var/obj/machinery/door/D in airlocks) if(!(D.z in config.contact_levels)) continue spawn() @@ -141,28 +139,54 @@ rcd light flash thingy on matter drain minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network Reset") /datum/AI_Module/large/disable_rcd - module_name = "RCD disable" + module_name = "RCD Disable" mod_pick_name = "rcd" - description = "Send a specialised pulse to break all RCD devices on the station." - cost = 50 + description = "Send a specialised pulse to break all hand-held and exosuit Rapid Cconstruction Devices on the station." + cost = 25 + one_time = 1 power_type = /mob/living/silicon/ai/proc/disable_rcd /mob/living/silicon/ai/proc/disable_rcd() set category = "Malfunction" set name = "Disable RCDs" - for(var/datum/AI_Module/large/disable_rcd/rcdmod in current_modules) - if(rcdmod.uses > 0) - rcdmod.uses -- - for(var/obj/item/weapon/rcd/rcd in world) - rcd.disabled = 1 - for(var/obj/item/mecha_parts/mecha_equipment/tool/rcd/rcd in world) - rcd.disabled = 1 - src << "Out of uses." + set desc = "Disable all RCD devices on the station, while sparing onboard cyborg RCDs." + + if(stat) + return + + for(var/obj/item/weapon/rcd/RCD in rcd_list) + if(!istype(/obj/item/weapon/rcd/borg, RCD)) //Ensures that cyborg RCDs are spared. + RCD.disabled = 1 + for(var/obj/item/mecha_parts/mecha_equipment/tool/rcd/MRCD in rcd_list) + MRCD.disabled = 1 + src << "RCD-disabling pulse emitted." + +/datum/AI_Module/large/mecha_domination + module_name = "Viral Mech Domination" + mod_pick_name = "mechjack" + description = "Hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. Once uploaded to the mech, it is impossible to leave.\ + Do not allow the mech to leave the station's vicinity or allow it to be destroyed." + cost = 30 + one_time = 1 + + power_type = /mob/living/silicon/ai/proc/mech_takeover + +/mob/living/silicon/ai/proc/mech_takeover() + set name = "Compile Mecha Virus" + set category = "Malfunction" + set desc = "Target a mech by clicking it. Click the appropriate command when ready." + + if(stat) + return + + can_dominate_mechs = 1 //Yep. This is all it does. Honk! + src << "Virus package compiled. Select a target mech at any time. You must remain on the station at all times. Loss of signal will result in total system lockout." + verbs -= /mob/living/silicon/ai/proc/mech_takeover + /datum/AI_Module/small/overload_machine - module_name = "Machine overload" + module_name = "Machine Overload" mod_pick_name = "overload" description = "Overloads an electrical machine, causing a small explosion. 2 uses." uses = 2 @@ -173,6 +197,10 @@ rcd light flash thingy on matter drain /mob/living/silicon/ai/proc/overload_machine(obj/machinery/M as obj in world) set name = "Overload Machine" set category = "Malfunction" + + if(stat) + return + if (istype(M, /obj/machinery)) if(istype(M,/obj/machinery/field_generator)) src << "This machine can not be overloaded due to a firewall." @@ -189,7 +217,7 @@ rcd light flash thingy on matter drain else src << "That's not a machine." /datum/AI_Module/small/override_machine - module_name = "Machine override" + module_name = "Machine Override" mod_pick_name = "override" description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. 4 uses." uses = 4 @@ -201,6 +229,10 @@ rcd light flash thingy on matter drain /mob/living/silicon/ai/proc/override_machine(obj/machinery/M as obj in world) set name = "Override Machine" set category = "Malfunction" + + if(stat) + return + if (istype(M, /obj/machinery)) if(istype(M,/obj/machinery/field_generator)) src << "This machine can not be overloaded due to a firewall." @@ -234,8 +266,10 @@ rcd light flash thingy on matter drain /mob/living/silicon/ai/proc/place_transformer() set name = "Place Robotic Factory" set category = "Malfunction" + if(!canPlaceTransformer()) return + var/sure = alert(src, "Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No") if(sure == "Yes") if(!canPlaceTransformer()) @@ -300,6 +334,10 @@ rcd light flash thingy on matter drain /mob/living/silicon/ai/proc/blackout() set category = "Malfunction" set name = "Blackout" + + if(stat) + return + for(var/datum/AI_Module/small/blackout/blackout in current_modules) if(blackout.uses > 0) blackout.uses -- @@ -310,70 +348,86 @@ rcd light flash thingy on matter drain src << "Overcurrent applied to the powernet." else src << "Out of uses." -/datum/AI_Module/small/reactivate_camera - module_name = "Reactivate camera" +/datum/AI_Module/small/reactivate_cameras + module_name = "Reactivate Camera Network" mod_pick_name = "recam" - description = "Reactivates a currently disabled camera. 5 uses." - uses = 5 - cost = 5 + description = "Runs a network-wide diagnostic on the camera network, resetting focus and re-routing power to failed cameras. Can be used to repair up to 30 cameras." + uses = 30 + cost = 10 + one_time = 1 - power_type = /client/proc/reactivate_camera + power_type = /mob/living/silicon/ai/proc/reactivate_cameras -/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras) - set name = "Reactivate Camera" +/mob/living/silicon/ai/proc/reactivate_cameras() + set name = "Reactivate Cameranet" set category = "Malfunction" - if (istype (C, /obj/machinery/camera)) - for(var/datum/AI_Module/small/reactivate_camera/camera in usr:current_modules) + + if(!CanUseTopic() || malf_cooldown) + return + var/fixedcams = 0 //Tells the AI how many cams it fixed. Stats are fun. + + for(var/datum/AI_Module/small/reactivate_cameras/camera in current_modules) + for(var/obj/machinery/camera/C in cameranet.cameras) + var/initial_range = initial(C.view_range) //To prevent calling the proc twice if(camera.uses > 0) if(!C.status) - C.deactivate(src) - camera.uses -- - src << "Camera reactivated." - else - src << "This camera is either active, or not repairable." - else src << "Out of uses." - else src << "That's not a camera." - -/datum/AI_Module/small/upgrade_camera - module_name = "Upgrade Camera" - mod_pick_name = "upgradecam" - description = "Upgrades a camera to have X-Ray vision, Motion and be EMP-Proof. 5 uses." - uses = 5 - cost = 5 - - power_type = /client/proc/upgrade_camera - -/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras) - set name = "Upgrade Camera" - set category = "Malfunction" - if(istype(C)) - var/datum/AI_Module/small/upgrade_camera/UC = locate(/datum/AI_Module/small/upgrade_camera) in usr:current_modules - if(UC) - if(UC.uses > 0) - if(C.assembly) - var/upgraded = 0 - - if(!C.isXRay()) - C.upgradeXRay() - upgraded = 1 - - if(!C.isEmpProof()) - C.upgradeEmpProof() - upgraded = 1 - - if(!C.isMotion()) - C.upgradeMotion() - upgraded = 1 - - if(upgraded) - UC.uses -- - C.visible_message("\icon[C] *beep*") - src << "Camera successully upgraded!" - else - src << "This camera is already upgraded!" + C.deactivate(src, 0) //Reactivates the camera based on status. Badly named proc. + fixedcams++ + camera.uses-- + if(C.view_range != initial_range) + C.view_range = initial_range //Fixes cameras with bad focus. + camera.uses-- + fixedcams++ + //If a camera is both deactivated and has bad focus, it will cost two uses to fully fix! else - src << "Out of uses." + src << "Out of uses." + verbs -= /mob/living/silicon/ai/proc/reactivate_cameras //It is useless now, clean it up. + break + src << "Diagnostic complete! Operations completed: [fixedcams]." + malf_cooldown = 1 + spawn(30) //Lag protection + malf_cooldown = 0 + +/datum/AI_Module/small/upgrade_cameras + module_name = "Upgrade Camera Network" + mod_pick_name = "upgradecam" + description = "Install broad-spectrum scanning and electrical redundancy firmware to the camera network, enabling EMP-Proofing and light-amplified X-ray vision." //I <3 pointless technobabble + //This used to have motion sensing as well, but testing quickly revealed that giving it to the whole cameranet is PURE HORROR. + one_time = 1 + cost = 35 //Decent price for omniscience! + + power_type = /mob/living/silicon/ai/proc/upgrade_cameras + +/mob/living/silicon/ai/proc/upgrade_cameras() + set name = "Upgrade Cameranet" + set category = "Malfunction" + + if(stat) + return + + var/upgradedcams = 0 + see_override = SEE_INVISIBLE_MINIMUM //Night-vision, without which X-ray would be very limited in power. + + for(var/obj/machinery/camera/C in cameranet.cameras) + if(C.assembly) + var/upgraded = 0 + + if(!C.isXRay()) + C.upgradeXRay() + //Update what it can see. + cameranet.updateVisibility(C, 0) + upgraded = 1 + + if(!C.isEmpProof()) + C.upgradeEmpProof() + upgraded = 1 + + if(upgraded) + upgradedcams++ + + src << "OTA firmware distribution complete! Cameras upgraded: [upgradedcams]. Light amplification system online." + verbs -= /mob/living/silicon/ai/proc/upgrade_cameras /datum/module_picker var/temp = null diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm index fdca56bd5cc..e3fb3809c39 100644 --- a/code/game/gamemodes/malfunction/malfunction.dm +++ b/code/game/gamemodes/malfunction/malfunction.dm @@ -127,7 +127,7 @@ /datum/game_mode/malfunction/proc/capture_the_station() - world << "The AI has won!" + world << "The AI has accessed the station's core files!" world << "It has fully taken control of all of [station_name()]'s systems." to_nuke_or_not_to_nuke = 1 @@ -328,7 +328,8 @@ /datum/game_mode/proc/auto_declare_completion_malfunction() if( malf_ai.len || istype(ticker.mode,/datum/game_mode/malfunction) ) var/text = "The malfunctioning AI were:" - + var/module_text_temp = "
Purchased modules:
" //Added at the end + for(var/datum/mind/malf in malf_ai) text += "
[malf.key] was [malf.name] (" @@ -339,9 +340,13 @@ text += "operational" if(malf.current.real_name != malf.name) text += " as [malf.current.real_name]" + var/mob/living/silicon/ai/AI = malf.current + for(var/datum/AI_Module/mod in AI.current_modules) + module_text_temp += mod.module_name + "
" else text += "hardware destroyed" text += ")" - + text += module_text_temp + world << text return 1 \ No newline at end of file diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 8aa64e18b6b..76fd8cf7ea5 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -233,201 +233,28 @@ This is a good place for AI-related object verbs so I'm sticking it here. If adding stuff to this, don't forget that an AI need to cancel_camera() whenever it physically moves to a different location. That prevents a few funky behaviors. */ -//What operation to perform based on target, what ineraction to perform based on object used, target itself, user. The object used is src and calls this proc. -/obj/item/proc/transfer_ai(var/choice as text, var/interaction as text, var/target, var/mob/U as mob) - if(!src:flush) - switch(choice) - if("AICORE")//AI mob. - var/mob/living/silicon/ai/T = target - switch(interaction) - if("AICARD") - var/obj/item/device/aicard/C = src - if(C.contents.len)//If there is an AI on card. - U << "\red Transfer failed: \black Existing AI found on this terminal. Remove existing AI to install a new one." - else - if (ticker.mode.name == "AI malfunction") - var/datum/game_mode/malfunction/malf = ticker.mode - for (var/datum/mind/malfai in malf.malf_ai) - if (T.mind == malfai) - U << "\red ERROR: \black Remote transfer interface disabled."//Do ho ho ho~ - return - new /obj/structure/AIcore/deactivated(T.loc)//Spawns a deactivated terminal at AI location. - T.aiRestorePowerRoutine = 0//So the AI initially has power. - T.control_disabled = 1//Can't control things remotely if you're stuck in a card! - T.loc = C//Throw AI into the card. - C.name = "inteliCard - [T.name]" - if (T.stat == 2) - C.icon_state = "aicard-404" - else - C.icon_state = "aicard-full" - T.cancel_camera() - T << "You have been downloaded to a mobile storage device. Remote device connection severed." - U << "\blue Transfer successful: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." - /*if("NINJASUIT") - var/obj/item/clothing/suit/space/space_ninja/C = src - if(C.AI)//If there is an AI on card. - U << "\red Transfer failed: \black Existing AI found on this terminal. Remove existing AI to install a new one." - else - if (ticker.mode.name == "AI malfunction") - var/datum/game_mode/malfunction/malf = ticker.mode - for (var/datum/mind/malfai in malf.malf_ai) - if (T.mind == malfai) - U << "\red ERROR: \black Remote transfer interface disabled." - return - if(T.stat)//If the ai is dead/dying. - U << "\red ERROR: \black [T.name] data core is corrupted. Unable to install." - else - new /obj/structure/AIcore/deactivated(T.loc) - T.aiRestorePowerRoutine = 0 - T.control_disabled = 1 - T.loc = C - C.AI = T - T.cancel_camera() - T << "You have been downloaded to a mobile storage device. Remote device connection severed." - U << "\blue Transfer successful: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."*/ +//The type of interaction, the player performing the operation, the AI itself, and the card object, if any. - if("INACTIVE")//Inactive AI object. - var/obj/structure/AIcore/deactivated/T = target - switch(interaction) - if("AICARD") - var/obj/item/device/aicard/C = src - var/mob/living/silicon/ai/A = locate() in C//I love locate(). Best proc ever. - if(A)//If AI exists on the card. Else nothing since both are empty. - A.control_disabled = 0 - A.loc = T.loc//To replace the terminal. - C.icon_state = "aicard" - C.name = "inteliCard" - C.overlays.Cut() - A.cancel_camera() - A << "You have been uploaded to a stationary terminal. Remote device connection restored." - U << "\blue Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed." - qdel(T) - /*if("NINJASUIT") - var/obj/item/clothing/suit/space/space_ninja/C = src - var/mob/living/silicon/ai/A = C.AI - if(A) - A.control_disabled = 0 - C.AI = null - A.loc = T.loc - A.cancel_camera() - A << "You have been uploaded to a stationary terminal. Remote device connection restored." - U << "\blue Transfer succesful: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed." - del(T)*/ - if("AIFIXER")//AI Fixer terminal. - var/obj/machinery/computer/aifixer/T = target - switch(interaction) - if("AICARD") - var/obj/item/device/aicard/C = src - if(!T.contents.len) - if (!C.contents.len) - U << "No AI to copy over!"//Well duh - else for(var/mob/living/silicon/ai/A in C) - C.icon_state = "aicard" - C.name = "inteliCard" - C.overlays.Cut() - A.loc = T - T.occupant = A - A.control_disabled = 1 - if (A.stat == 2) - T.overlays += image('icons/obj/computer.dmi', "ai-fixer-404") - else - T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full") - T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-empty") - A.cancel_camera() - A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here." - U << "\blue Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed." - else - if(!C.contents.len && T.occupant && !T.active) - C.name = "inteliCard - [T.occupant.name]" - T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty") - if (T.occupant.stat == 2) - C.icon_state = "aicard-404" - T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404") - else - C.icon_state = "aicard-full" - T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full") - T.occupant << "You have been downloaded to a mobile storage device. Still no remote access." - U << "\blue Transfer succesful: \black [T.occupant.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." - T.occupant.loc = C - T.occupant.cancel_camera() - T.occupant = null - else if (C.contents.len) - U << "\red ERROR: \black Artificial intelligence detected on terminal." - else if (T.active) - U << "\red ERROR: \black Reconstruction in progress." - else if (!T.occupant) - U << "\red ERROR: \black Unable to locate artificial intelligence." - /*if("NINJASUIT") - var/obj/item/clothing/suit/space/space_ninja/C = src - if(!T.contents.len) - if (!C.AI) - U << "No AI to copy over!" - else - var/mob/living/silicon/ai/A = C.AI - A.loc = T - T.occupant = A - C.AI = null - A.control_disabled = 1 - T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full") - T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-empty") - A.cancel_camera() - A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here." - U << "\blue Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed." - else - if(!C.AI && T.occupant && !T.active) - if (T.occupant.stat) - U << "\red ERROR: \black [T.occupant.name] data core is corrupted. Unable to install." - else - T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty") - T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full") - T.occupant << "You have been downloaded to a mobile storage device. Still no remote access." - U << "\blue Transfer successful: \black [T.occupant.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." - T.occupant.loc = C - T.occupant.cancel_camera() - T.occupant = null - else if (C.AI) - U << "\red ERROR: \black Artificial intelligence detected on terminal." - else if (T.active) - U << "\red ERROR: \black Reconstruction in progress." - else if (!T.occupant) - U << "\red ERROR: \black Unable to locate artificial intelligence."*/ - /*if("NINJASUIT")//Ninjasuit - var/obj/item/clothing/suit/space/space_ninja/T = target - switch(interaction) - if("AICARD") - var/obj/item/device/aicard/C = src - if(T.s_initialized&&U==T.affecting)//If the suit is initialized and the actor is the user. - var/mob/living/silicon/ai/A_T = locate() in C//Determine if there is an AI on target card. Saves time when checking later. - var/mob/living/silicon/ai/A = T.AI//Deterine if there is an AI in suit. +atom/proc/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card) + if(istype(card)) + if(card.flush) + user << "ERROR: AI flush is in progress, cannot execute transfer protocol." + return 0 + return 1 - if(A)//If the host AI card is not empty. - if(A_T)//If there is an AI on the target card. - U << "\red ERROR: \black [A_T.name] already installed. Remove [A_T.name] to install a new one." - else - A.loc = C//Throw them into the target card. Since they are already on a card, transfer is easy. - C.name = "inteliCard - [A.name]" - C.icon_state = "aicard-full" - T.AI = null - A.cancel_camera() - A << "You have been uploaded to a mobile storage device." - U << "\blue SUCCESS: \black [A.name] ([rand(1000,9999)].exe) removed from host and stored within local memory." - else//If host AI is empty. - if(C.flush)//If the other card is flushing. - U << "\red ERROR: \black AI flush is in progress, cannot execute transfer protocol." - else - if(A_T&&!A_T.stat)//If there is an AI on the target card and it's not inactive. - A_T.loc = T//Throw them into suit. - C.icon_state = "aicard" - C.name = "inteliCard" - C.overlays.Cut() - T.AI = A_T - A_T.cancel_camera() - A_T << "You have been uploaded to a mobile storage device." - U << "\blue SUCCESS: \black [A_T.name] ([rand(1000,9999)].exe) removed from local memory and installed to host." - else if(A_T)//If the target AI is dead. Else just go to return since nothing would happen if both are empty. - U << "\red ERROR: \black [A_T.name] data core is corrupted. Unable to install."*/ - else - U << "\red ERROR: \black AI flush is in progress, cannot execute transfer protocol." - return \ No newline at end of file +/obj/structure/AIcore/deactivated/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card) + if(!..()) + return + //Transferring a carded AI to a core. + if(interaction == AI_TRANS_FROM_CARD) + AI.control_disabled = 0 + AI.aiRadio.disabledAi = 0 + AI.loc = loc//To replace the terminal. + AI << "You have been uploaded to a stationary terminal. Remote device connection restored." + user << "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed." + qdel(src) + else //If for some reason you use an empty card on an empty AI terminal. + user << "There is no AI loaded on this terminal!" + \ No newline at end of file diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index d291c65ac78..20d715a3a0e 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -10,28 +10,26 @@ light_color = LIGHT_COLOR_PURPLE -/obj/machinery/computer/aifixer/New() - src.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty") - - /obj/machinery/computer/aifixer/attackby(I as obj, user as mob, params) - if(istype(I, /obj/item/device/aicard)) + if(occupant && istype(I, /obj/item/weapon/screwdriver)) if(stat & (NOPOWER|BROKEN)) - user << "This terminal isn't functioning right now, get it working!" - return - I:transfer_ai("AIFIXER","AICARD",src,user) - - ..() - return - + user << "The screws on [name]'s screen won't budge." + else + user << "The screws on [name]'s screen won't budge and it emits a warning beep." + return + else + ..() + /obj/machinery/computer/aifixer/attack_ai(var/mob/user as mob) - return attack_hand(user) + return interact(user) /obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob) if(..()) return + + interact(user) - user.set_machine(src) +/obj/machinery/computer/aifixer/interact(mob/user) var/dat = "

AI System Integrity Restorer



" if (src.occupant) @@ -70,17 +68,11 @@ onclose(user, "computer") return -/obj/machinery/computer/aifixer/process() - if(..()) - src.updateDialog() - return - /obj/machinery/computer/aifixer/Topic(href, href_list) if(..()) return 1 if (href_list["fix"]) src.active = 1 - src.overlays += image('icons/obj/computer.dmi', "ai-fixer-on") while (src.occupant.health < 100) src.occupant.adjustOxyLoss(-1) src.occupant.adjustFireLoss(-1) @@ -92,32 +84,56 @@ src.occupant.lying = 0 dead_mob_list -= src.occupant living_mob_list += src.occupant - src.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404") - src.overlays += image('icons/obj/computer.dmi', "ai-fixer-full") src.updateUsrDialog() sleep(10) src.active = 0 - src.overlays -= image('icons/obj/computer.dmi', "ai-fixer-on") - - src.add_fingerprint(usr) src.updateUsrDialog() + update_icon() return - /obj/machinery/computer/aifixer/update_icon() ..() - // Broken / Unpowered - if((stat & BROKEN) || (stat & NOPOWER)) - overlays.Cut() - - // Working / Powered + if(stat & (NOPOWER|BROKEN)) + return else + var/overlay_layer = LIGHTING_LAYER+0.2 // +0.1 from the default computer overlays + if(active) + overlays += image(icon,"ai-fixer-on",overlay_layer) if (occupant) switch (occupant.stat) if (0) - overlays += image('icons/obj/computer.dmi', "ai-fixer-full") + overlays += image(icon,"ai-fixer-full",overlay_layer) if (2) - overlays += image('icons/obj/computer.dmi', "ai-fixer-404") + overlays += image(icon,"ai-fixer-404",overlay_layer) else - overlays += image('icons/obj/computer.dmi', "ai-fixer-empty") + overlays += image(icon,"ai-fixer-empty",overlay_layer) + +/obj/machinery/computer/aifixer/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card) + if(!..()) + return + //Downloading AI from card to terminal. + if(interaction == AI_TRANS_FROM_CARD) + if(stat & (NOPOWER|BROKEN)) + user << "[src] is offline and cannot take an AI at this time!" + return + AI.loc = src + occupant = AI + AI.control_disabled = 1 + AI.aiRadio.disabledAi = 1 + AI << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here." + user << "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed." + update_icon() + + else //Uploading AI from terminal to card + if(occupant && !active) + occupant << "You have been downloaded to a mobile storage device. Still no remote access." + user << "Transfer successful: [occupant.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." + occupant.loc = card + occupant = null + update_icon() + else if (active) + user << "ERROR: Reconstruction in progress." + else if (!occupant) + user << "ERROR: Unable to locate artificial intelligence." + \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index 90db7efaec9..7fa4e5668cb 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -284,12 +284,18 @@ var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock. var/disabled = 0 //malf var/canRwall = 0 + + New() + rcd_list += src + ..() + + Destroy() + rcd_list -= src + ..() action(atom/target) - if(istype(target,/area/shuttle)||istype(target, /turf/space/transit))//>implying these are ever made -Sieve - disabled = 1 - else - disabled = 0 + if(istype(target, /turf/space/transit))//>implying these are ever made -Sieve + return if(!istype(target, /turf) && !istype(target, /obj/machinery/door/airlock)) target = get_turf(target) if(!action_checks(target) || disabled || get_dist(chassis, target)>3) return diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 27fe49e746d..b812cab95bd 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -96,11 +96,6 @@ mechas_list += src //global mech list return -/obj/mecha/Destroy() - src.go_out() - mechas_list -= src //global mech list - return ..() - //////////////////////// ////// Helpers ///////// //////////////////////// @@ -615,50 +610,65 @@ return /obj/mecha/proc/destroy() - spawn() - go_out() - var/turf/T = get_turf(src) - tag = "\ref[src]" //better safe then sorry - if(loc) - loc.Exited(src) - loc = null - if(T) - if(istype(src, /obj/mecha/working/ripley/)) - var/obj/mecha/working/ripley/R = src - if(R.cargo) - for(var/obj/O in R.cargo) //Dump contents of stored cargo - O.loc = T - R.cargo -= O - T.Entered(O) + go_out() + for(var/mob/M in src) //Let's just be ultra sure + if(isAI(M)) + M.gib() //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. Forever. + else + M.Move(loc) + + if(prob(30)) + explosion(get_turf(loc), 0, 0, 1, 3) + + if(istype(src, /obj/mecha/working/ripley/)) + var/obj/mecha/working/ripley/R = src + if(R.cargo) + for(var/obj/O in R.cargo) //Dump contents of stored cargo + O.loc = loc + R.cargo -= O + loc.Entered(O) - if(prob(30)) - explosion(get_turf(loc), 0, 0, 1, 3) - spawn(0) - if(wreckage) - var/obj/effect/decal/mecha_wreckage/WR = new wreckage(T) - for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) - if(E.salvageable && prob(30)) - WR.crowbar_salvage += E - E.forceMove(WR) - E.equip_ready = 1 - E.reliability = round(rand(E.reliability/3,E.reliability)) - else - E.forceMove(T) - E.destroy() - if(cell) - WR.crowbar_salvage += cell - cell.forceMove(WR) - cell.charge = rand(0, cell.charge) - if(internal_tank) - WR.crowbar_salvage += internal_tank - internal_tank.forceMove(WR) - else - for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) - E.forceMove(T) - E.destroy() - spawn(0) - qdel(src) - return + if(wreckage) + var/obj/effect/decal/mecha_wreckage/WR = new wreckage(loc) + for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) + if(E.salvageable && prob(30)) + WR.crowbar_salvage += E + E.forceMove(WR) + E.equip_ready = 1 + E.reliability = round(rand(E.reliability/3,E.reliability)) + else + E.forceMove(loc) + E.destroy() + if(cell) + WR.crowbar_salvage += cell + cell.forceMove(WR) + cell.charge = rand(0, cell.charge) + if(internal_tank) + WR.crowbar_salvage += internal_tank + internal_tank.forceMove(WR) + else + for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) + E.forceMove(loc) + E.destroy() + if(cell) + qdel(cell) + if(internal_tank) + qdel(internal_tank) + equipment.Cut() + cell = null + internal_tank = null + + qdel(pr_int_temp_processor) + qdel(pr_give_air) + qdel(pr_internal_damage) + qdel(spark_system) + pr_int_temp_processor = null + pr_give_air = null + pr_internal_damage = null + spark_system = null + + mechas_list -= src //global mech list + return ..() /obj/mecha/ex_act(severity) src.log_message("Affected by explosion of severity: [severity].",1) @@ -916,16 +926,92 @@ return -/* +///////////////////////////////////// +//////////// AI piloting //////////// +///////////////////////////////////// + /obj/mecha/attack_ai(var/mob/living/silicon/ai/user as mob) - if(!istype(user, /mob/living/silicon/ai)) + if(!isAI(user)) return - var/output = {"Assume direct control over [src]? - Yes
- "} - user << browse(output, "window=mecha_attack_ai") - return -*/ + //Allows the Malf to scan a mech's status and loadout, helping it to decide if it is a worthy chariot. + if(user.can_dominate_mechs) + examine(user) //Get diagnostic information! + var/obj/item/mecha_parts/mecha_tracking/B = locate(/obj/item/mecha_parts/mecha_tracking) in src + if(B) //Beacons give the AI more detailed mech information. + user << "Warning: Tracking Beacon detected. Enter at your own risk. Beacon Data:" + user << "[B.get_mecha_info()]" + //Nothing like a big, red link to make the player feel powerful! + user << "ASSUME DIRECT CONTROL?
" + +/obj/mecha/transfer_ai(var/interaction, mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card) + if(!..()) + return + + //Transfer from core or card to mech. Proc is called by mech. + switch(interaction) + if(AI_TRANS_TO_CARD) //Upload AI from mech to AI card. + if(!maint_access) //Mech must be in maint mode to allow carding. + user << "[name] must have maintenance protocols active in order to allow a transfer." + return + AI = occupant + if(!AI || !isAI(occupant)) //Mech does not have an AI for a pilot + user << "No AI detected in the [name] onboard computer." + return + if (AI.mind.special_role == "malfunction") //Malf AIs cannot leave mechs. Except through death. + user << "ACCESS DENIED." + return + AI.aiRestorePowerRoutine = 0//So the AI initially has power. + AI.control_disabled = 1 + AI.aiRadio.disabledAi = 1 + AI.loc = card + occupant = null + AI.controlled_mech = null + AI.remote_control = null + icon_state = initial(icon_state)+"-open" + AI << "You have been downloaded to a mobile storage device. Wireless connection offline." + user << "Transfer successful: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory." + + if(AI_MECH_HACK) //Called by Malf AI mob on the mech. + new /obj/structure/AIcore/deactivated(AI.loc) + if(occupant) //Oh, I am sorry, were you using that? + AI << "Pilot detected! Forced ejection initiated!" + occupant << "You have been forcibly ejected!" + go_out(1) //IT IS MINE, NOW. SUCK IT, RD! + ai_enter_mech(AI, interaction) + + if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech. + AI = locate(/mob/living/silicon/ai) in card + if(!AI) + user << "There is no AI currently installed on this device." + return + else if(AI.stat || !AI.client) + user << "[AI.name] is currently unresponsive, and cannot be uploaded." + return + else if(occupant || dna) //Normal AIs cannot steal mechs! + user << "Access denied. [name] is [occupant ? "currently occupied" : "secured with a DNA lock"]." + return + AI.control_disabled = 0 + AI.aiRadio.disabledAi = 0 + user << "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed." + ai_enter_mech(AI, interaction) + +//Hack and From Card interactions share some code, so leave that here for both to use. +/obj/mecha/proc/ai_enter_mech(var/mob/living/silicon/ai/AI, var/interaction) + AI.aiRestorePowerRoutine = 0 + AI.loc = src + occupant = AI + icon_state = initial(icon_state) + playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) + if(!hasInternalDamage()) + occupant << sound('sound/mecha/nominal.ogg',volume=50) + AI.cancel_camera() + AI.controlled_mech = src + AI.remote_control = src + AI.canmove = 1 //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow. + AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES. + AI << "[interaction == AI_MECH_HACK ? "Takeover of [name] complete! You are now permanently loaded onto the onboard computer. Do not attempt to leave the station sector!" \ + : "You have been uploaded to a mech's onboard computer."]" + AI << "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions." ///////////////////////////////////// //////// Atmospheric stuff //////// @@ -1228,7 +1314,7 @@ return -/obj/mecha/proc/go_out() +/obj/mecha/proc/go_out(var/forced) if(!src.occupant) return var/atom/movable/mob_container if(ishuman(occupant)) @@ -1236,6 +1322,10 @@ else if(istype(occupant, /mob/living/carbon/brain)) var/mob/living/carbon/brain/brain = occupant mob_container = brain.container + else if(isAI(occupant) && forced) //This should only happen if there are multiple AIs in a round, and at least one is Malf. + occupant.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced. + occupant = null + return else return if(mob_container.forceMove(src.loc))//ejecting mob container @@ -1677,13 +1767,13 @@ user << browse(null,"window=exosuit_add_access") return if(href_list["dna_lock"]) - if(usr != src.occupant) return - if(istype(occupant, /mob/living/carbon/brain)) - occupant_message("You are a brain. No.") + if(usr != src.occupant) return - if(src.occupant) - src.dna = src.occupant.dna.unique_enzymes - src.occupant_message("You feel a prick as the needle takes your DNA sample.") + if(src.occupant && !iscarbon(src.occupant)) + src.occupant << "You do not have any DNA!" + return + src.dna = src.occupant.dna.unique_enzymes + src.occupant_message("You feel a prick as the needle takes your DNA sample.") return if(href_list["reset_dna"]) if(usr != src.occupant) return @@ -1712,54 +1802,6 @@ return */ - - -/* - - if (href_list["ai_take_control"]) - var/mob/living/silicon/ai/AI = locate(href_list["ai_take_control"]) - var/duration = text2num(href_list["duration"]) - var/mob/living/silicon/ai/O = new /mob/living/silicon/ai(src) - var/cur_occupant = src.occupant - O.invisibility = 0 - O.canmove = 1 - O.name = AI.name - O.real_name = AI.real_name - O.anchored = 1 - O.aiRestorePowerRoutine = 0 - O.control_disabled = 1 // Can't control things remotely if you're stuck in a card! - O.laws = AI.laws - O.stat = AI.stat - O.oxyloss = AI.getOxyLoss() - O.fireloss = AI.getFireLoss() - O.bruteloss = AI.getBruteLoss() - O.toxloss = AI.toxloss - O.updatehealth() - src.occupant = O - if(AI.mind) - AI.mind.transfer_to(O) - AI.name = "Inactive AI" - AI.real_name = "Inactive AI" - AI.icon_state = "ai-empty" - spawn(duration) - AI.name = O.name - AI.real_name = O.real_name - if(O.mind) - O.mind.transfer_to(AI) - AI.control_disabled = 0 - AI.laws = O.laws - AI.oxyloss = O.getOxyLoss() - AI.fireloss = O.getFireLoss() - AI.bruteloss = O.getBruteLoss() - AI.toxloss = O.toxloss - AI.updatehealth() - del(O) - if (!AI.stat) - AI.icon_state = "ai" - else - AI.icon_state = "ai-crash" - src.occupant = cur_occupant -*/ return /////////////////////// diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index ff16cf9e43c..e2c0ddf1df0 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -5,129 +5,138 @@ item_state = "electronic" w_class = 2.0 slot_flags = SLOT_BELT + flags = NOBLUDGEON var/flush = null origin_tech = "programming=4;materials=4" - attack(mob/living/silicon/ai/M as mob, mob/user as mob) - if(!istype(M, /mob/living/silicon/ai))//If target is not an AI. - return ..() - - M.attack_log += text("\[[time_stamp()]\] Has been carded with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to card [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] used the [src.name] to card [M.name] ([M.ckey]) (JMP)") - - transfer_ai("AICORE", "AICARD", M, user) +/obj/item/device/aicard/afterattack(atom/target, mob/user, proximity) + ..() + if(!proximity || !target) return + var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src + if(AI) //AI is on the card, implies user wants to upload it. + target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src) + add_logs(AI,user, "carded", object="[name]") + else //No AI on the card, therefore the user wants to download one. + target.transfer_ai(AI_TRANS_TO_CARD, user, null, src) + update_state() //Whatever happened, update the card's state (icon, name) to match. - attack(mob/living/silicon/decoy/M as mob, mob/user as mob) - if (!istype (M, /mob/living/silicon/decoy)) - return ..() +/obj/item/device/aicard/proc/update_state() + var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src //AI is inside. + if(AI) + name = "intelliCard - [AI.name]" + if (AI.stat == DEAD) + icon_state = "aicard-404" else - M.death() - user << "ERROR ERROR ERROR" + icon_state = "aicard-full" + AI.cancel_camera() //AI are forced to move when transferred, so do this whenver one is downloaded. + else + icon_state = "aicard" + name = "intelliCard" + overlays.Cut() + +/obj/item/device/aicard/attack_self(mob/user) + if (!in_range(src, user)) + return + user.set_machine(src) + var/dat = "Intelicard
" + var/laws + for(var/mob/living/silicon/ai/A in src) + dat += "Stored AI: [A.name]
System integrity: [(A.health+100)/2]%
" - attack_self(mob/user) - if (!in_range(src, user)) - return - user.set_machine(src) - var/dat = "Intelicard
" - var/laws - for(var/mob/living/silicon/ai/A in src) - dat += "Stored AI: [A.name]
System integrity: [(A.health+100)/2]%
" + for (var/index = 1, index <= A.laws.ion.len, index++) + var/law = A.laws.ion[index] + if (length(law) > 0) + var/num = ionnum() + laws += "[num]. [law]" - for (var/index = 1, index <= A.laws.ion.len, index++) - var/law = A.laws.ion[index] - if (length(law) > 0) - var/num = ionnum() - laws += "[num]. [law]" + if (A.laws.zeroth) + laws += "0: [A.laws.zeroth]
" - if (A.laws.zeroth) - laws += "0: [A.laws.zeroth]
" + var/number = 1 + for (var/index = 1, index <= A.laws.inherent.len, index++) + var/law = A.laws.inherent[index] + if (length(law) > 0) + laws += "[number]: [law]
" + number++ - var/number = 1 - for (var/index = 1, index <= A.laws.inherent.len, index++) - var/law = A.laws.inherent[index] - if (length(law) > 0) - laws += "[number]: [law]
" - number++ + for (var/index = 1, index <= A.laws.supplied.len, index++) + var/law = A.laws.supplied[index] + if (length(law) > 0) + laws += "[number]: [law]
" + number++ - for (var/index = 1, index <= A.laws.supplied.len, index++) - var/law = A.laws.supplied[index] - if (length(law) > 0) - laws += "[number]: [law]
" - number++ + dat += "Laws:
[laws]
" - dat += "Laws:
[laws]
" - - if (A.stat == 2) - dat += "AI nonfunctional" + if (A.stat == 2) + dat += "AI nonfunctional" + else + if (!src.flush) + dat += {"Wipe AI"} else - if (!src.flush) - dat += {"Wipe AI"} - else - dat += "Wipe in progress" - dat += "
" - dat += {"[A.control_disabled ? "Enable" : "Disable"] Wireless Activity"} - dat += "
" - dat += "Subspace Transceiver is: [A.aiRadio.disabledAi ? "Disabled" : "Enabled"]" - dat += "
" - dat += {"[A.aiRadio.disabledAi ? "Enable" : "Disable"] Subspace Transceiver"} - dat += "
" - dat += {" Close"} - user << browse(dat, "window=aicard") - onclose(user, "aicard") + dat += "Wipe in progress" + dat += "
" + dat += {"[A.control_disabled ? "Enable" : "Disable"] Wireless Activity"} + dat += "
" + dat += "Subspace Transceiver is: [A.aiRadio.disabledAi ? "Disabled" : "Enabled"]" + dat += "
" + dat += {"[A.aiRadio.disabledAi ? "Enable" : "Disable"] Subspace Transceiver"} + dat += "
" + dat += {" Close"} + user << browse(dat, "window=aicard") + onclose(user, "aicard") + return + +/obj/item/device/aicard/Topic(href, href_list) + var/mob/U = usr + if (!in_range(src, U)||U.machine!=src)//If they are not in range of 1 or less or their machine is not the card (ie, clicked on something else). + U << browse(null, "window=aicard") + U.unset_machine() return - Topic(href, href_list) - var/mob/U = usr - if (!in_range(src, U)||U.machine!=src)//If they are not in range of 1 or less or their machine is not the card (ie, clicked on something else). + add_fingerprint(U) + U.set_machine(src) + + switch(href_list["choice"])//Now we switch based on choice. + if ("Close") U << browse(null, "window=aicard") U.unset_machine() return - add_fingerprint(U) - U.set_machine(src) + if ("Wipe") + var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No") + if(confirm == "Yes") + if(isnull(src)||!in_range(src, U)||U.machine!=src) + U << browse(null, "window=aicard") + U.unset_machine() + return + else + flush = 1 + for(var/mob/living/silicon/ai/A in src) + A.suiciding = 1 + A << "Your core files are being wiped!" + while (A.stat != 2) + A.adjustOxyLoss(2) + A.updatehealth() + sleep(10) + flush = 0 - switch(href_list["choice"])//Now we switch based on choice. - if ("Close") - U << browse(null, "window=aicard") - U.unset_machine() - return + if ("Radio") + for(var/mob/living/silicon/ai/A in src) + A.aiRadio.disabledAi = !A.aiRadio.disabledAi + A << "Your Subspace Transceiver has been: [A.aiRadio.disabledAi ? "disabled" : "enabled"]" + U << "You [A.aiRadio.disabledAi ? "Disable" : "Enable"] the AI's Subspace Transceiver" - if ("Wipe") - var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No") - if(confirm == "Yes") - if(isnull(src)||!in_range(src, U)||U.machine!=src) - U << browse(null, "window=aicard") - U.unset_machine() - return - else - flush = 1 - for(var/mob/living/silicon/ai/A in src) - A.suiciding = 1 - A << "Your core files are being wiped!" - while (A.stat != 2) - A.adjustOxyLoss(2) - A.updatehealth() - sleep(10) - flush = 0 - - if ("Radio") - for(var/mob/living/silicon/ai/A in src) - A.aiRadio.disabledAi = !A.aiRadio.disabledAi - A << "Your Subspace Transceiver has been: [A.aiRadio.disabledAi ? "disabled" : "enabled"]" - U << "You [A.aiRadio.disabledAi ? "Disable" : "Enable"] the AI's Subspace Transceiver" - - if ("Wireless") - for(var/mob/living/silicon/ai/A in src) - A.control_disabled = !A.control_disabled - A << "The intelicard's wireless port has been [A.control_disabled ? "disabled" : "enabled"]!" - if (A.control_disabled) - overlays -= image('icons/obj/aicards.dmi', "aicard-on") - else - overlays += image('icons/obj/aicards.dmi', "aicard-on") - attack_self(U) + if ("Wireless") + for(var/mob/living/silicon/ai/A in src) + A.control_disabled = !A.control_disabled + A << "The intelicard's wireless port has been [A.control_disabled ? "disabled" : "enabled"]!" + if (A.control_disabled) + overlays -= image('icons/obj/aicards.dmi', "aicard-on") + else + overlays += image('icons/obj/aicards.dmi', "aicard-on") + attack_self(U) /obj/item/device/aicard/ex_act(severity) switch(severity) diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index 24788c42a0e..3330a3831cf 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -34,8 +34,14 @@ RCD src.spark_system = new /datum/effect/effect/system/spark_spread spark_system.set_up(5, 0, src) spark_system.attach(src) + rcd_list += src return - + + Destroy() + qdel(spark_system) + spark_system = null + rcd_list -= src + return ..() attackby(obj/item/weapon/W, mob/user, params) ..() diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 8fe44113b27..54cfb80de05 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -55,6 +55,7 @@ var/list/ai_verbs_default = list( var/ioncheck[1] var/lawchannel = "Common" // Default channel on which to state laws var/icon/holo_icon//Default is assigned when AI is created. + var/obj/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye. var/obj/item/device/pda/ai/aiPDA = null var/obj/item/device/multitool/aiMulti = null var/custom_sprite = 0 //For our custom sprites @@ -66,9 +67,10 @@ var/list/ai_verbs_default = list( var/processing_time = 100 var/list/datum/AI_Module/current_modules = list() var/fire_res_on_core = 0 - + var/can_dominate_mechs = 0 var/control_disabled = 0 // Set to 1 to stop AI from interacting via Click() -- TLE var/malfhacking = 0 // More or less a copy of the above var, so that malf AIs can hack and still get new cyborgs -- NeoFite + var/malf_cooldown = 0 //Cooldown var for malf modules var/obj/machinery/power/apc/malfhack = null var/explosive = 0 //does the AI explode when it dies? @@ -533,6 +535,14 @@ var/list/ai_verbs_default = list( botcall() return + if (href_list["ai_take_control"]) //Mech domination + var/obj/mecha/M = locate(href_list["ai_take_control"]) + if(controlled_mech) + src << "You are already loaded into an onboard computer!" + return + if(M) + M.transfer_ai(AI_MECH_HACK,src, usr) //Called om the mech itself. + else if (href_list["faketrack"]) var/mob/target = locate(href_list["track"]) in mob_list var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list @@ -980,6 +990,24 @@ var/list/ai_verbs_default = list( /mob/living/silicon/ai/proc/is_in_chassis() return istype(loc, /turf) + +/mob/living/silicon/ai/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card) + if(!..()) + return + if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card. + if(!mind) + user << "No intelligence patterns detected." //No more magical carding of empty cores, AI RETURN TO BODY!!!11 + return + if (mind.special_role == "malfunction") //AI MALF!! + user << "ERROR: Remote transfer interface disabled."//Do ho ho ho~ + return + new /obj/structure/AIcore/deactivated(loc)//Spawns a deactivated terminal at AI location. + aiRestorePowerRoutine = 0//So the AI initially has power. + control_disabled = 1//Can't control things remotely if you're stuck in a card! + aiRadio.disabledAi = 1 //No talking on the built-in radio for you either! + loc = card//Throw AI into the card. + src << "You have been downloaded to a mobile storage device. Remote device connection severed." + user << "Transfer successful: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." #undef AI_CHECK_WIRELESS #undef AI_CHECK_RADIO diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 5be1da223a9..b8bcfa4ead3 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -44,7 +44,7 @@ loc = T.loc if (istype(loc, /area)) //stage = 4 - if (!loc.power_equip && !istype(src.loc,/obj/item)) + if (!loc.power_equip && !is_type_in_list(src.loc,list(/obj/item, /obj/mecha))) //stage = 5 blind = 1 @@ -97,7 +97,7 @@ src.see_in_dark = 0 src.see_invisible = SEE_INVISIBLE_LIVING - if (((!loc.power_equip) || istype(T, /turf/space)) && !istype(src.loc,/obj/item)) + if (((!loc.power_equip) || istype(T, /turf/space)) && !is_type_in_list(src.loc,list(/obj/item, /obj/mecha))) if (src:aiRestorePowerRoutine==0) src:aiRestorePowerRoutine = 1 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index df5727e4315..1201c95b74c 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -191,8 +191,6 @@ if(world.time < move_delay) return - if(isAI(mob)) return AIMove(n,direct,mob) - if(!isliving(mob)) return mob.Move(n,direct) if(moving) return 0 @@ -211,10 +209,6 @@ var/mob/spirit/currentSpirit = mob return currentSpirit.Spirit_Move(direct) - // handle possible AI movement - if(isAI(mob)) - return AIMove(n,direct,mob) - if(mob.notransform) return//This is sota the goto stop mobs from moving var if(isliving(mob)) @@ -235,6 +229,9 @@ if(mob.remote_control) //we're controlling something, our movement is relayed to it return mob.remote_control.relaymove(mob, direct) + if(isAI(mob)) + return AIMove(n,direct,mob) + if(!mob.canmove) return From bbc249172cbff66c7d73e88704321722cef4df1b Mon Sep 17 00:00:00 2001 From: Markolie Date: Tue, 18 Aug 2015 20:56:21 +0200 Subject: [PATCH 04/30] Fix see_override, add uses to lockdown --- .../gamemodes/malfunction/Malf_Modules.dm | 64 +++++++++++-------- code/modules/mob/living/carbon/human/life.dm | 3 + code/modules/mob/living/silicon/ai/life.dm | 3 +- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index a464bfc29cd..8e0bf0ee2dd 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -81,6 +81,7 @@ rcd light flash thingy on matter drain mod_pick_name = "lockdown" description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 120 seconds." cost = 20 + uses = 1 power_type = /mob/living/silicon/ai/proc/lockdown @@ -91,27 +92,32 @@ rcd light flash thingy on matter drain if(stat) return - var/obj/machinery/door/airlock/AL - for(var/obj/machinery/door/D in airlocks) - if(!(D.z in config.contact_levels)) - continue - spawn() - if(istype(D, /obj/machinery/door/airlock)) - AL = D - if(AL.canAIControl() && !AL.stat) //Must be powered and have working AI wire. - AL.locked = 0 //For airlocks that were bolted open. - AL.safe = 0 //DOOR CRUSH - AL.close() - AL.lock() - AL.electrified_until = -1 //Shock it! - else if(!D.stat) //So that only powered doors are closed. - D.close() //Close ALL the doors! + for(var/datum/AI_Module/large/lockdown/lockdown in current_modules) + if(lockdown.uses > 0) + lockdown.uses -- + + var/obj/machinery/door/airlock/AL + for(var/obj/machinery/door/D in airlocks) + if(!(D.z in config.contact_levels)) + continue + spawn() + if(istype(D, /obj/machinery/door/airlock)) + AL = D + if(AL.canAIControl() && !AL.stat) //Must be powered and have working AI wire. + AL.locked = 0 //For airlocks that were bolted open. + AL.safe = 0 //DOOR CRUSH + AL.close() + AL.lock() + AL.electrified_until = -1 //Shock it! + else if(!D.stat) //So that only powered doors are closed. + D.close() //Close ALL the doors! - var/obj/machinery/computer/communications/C = locate() in machines - if(C) - C.post_status("alert", "lockdown") - - verbs -= /mob/living/silicon/ai/proc/lockdown + var/obj/machinery/computer/communications/C = locate() in machines + if(C) + C.post_status("alert", "lockdown") + else + src << "Out of uses." + minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.","Network Alert") src << "Lockdown initiated. Network reset in two minutes." spawn(1200) //120 Seconds. @@ -213,7 +219,7 @@ rcd light flash thingy on matter drain spawn(50) explosion(get_turf(M), 0,1,1,0) qdel(M) - else src << "Out of uses." + else src << "Out of uses." else src << "That's not a machine." /datum/AI_Module/small/override_machine @@ -246,7 +252,7 @@ rcd light flash thingy on matter drain spawn(50) if(M) new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, src, 1) - else src << "Out of uses." + else src << "Out of uses." else src << "That's not a machine." /datum/AI_Module/large/place_cyborg_transformer @@ -346,7 +352,7 @@ rcd light flash thingy on matter drain apc.overload_lighting() else apc.overload++ src << "Overcurrent applied to the powernet." - else src << "Out of uses." + else src << "Out of uses." /datum/AI_Module/small/reactivate_cameras module_name = "Reactivate Camera Network" @@ -362,7 +368,7 @@ rcd light flash thingy on matter drain set name = "Reactivate Cameranet" set category = "Malfunction" - if(!CanUseTopic() || malf_cooldown) + if(stat || malf_cooldown) return var/fixedcams = 0 //Tells the AI how many cams it fixed. Stats are fun. @@ -371,7 +377,7 @@ rcd light flash thingy on matter drain var/initial_range = initial(C.view_range) //To prevent calling the proc twice if(camera.uses > 0) if(!C.status) - C.deactivate(src, 0) //Reactivates the camera based on status. Badly named proc. + C.deactivate(src, 1) //Reactivates the camera based on status. Badly named proc. fixedcams++ camera.uses-- if(C.view_range != initial_range) @@ -453,9 +459,9 @@ rcd light flash thingy on matter drain Install Module:
The number afterwards is the amount of processing time it consumes.
"} for(var/datum/AI_Module/large/module in src.possible_modules) - dat += "[module.module_name] ([module.cost])
" + dat += "[module.module_name]\[?\] ([module.cost])
" for(var/datum/AI_Module/small/module in src.possible_modules) - dat += "[module.module_name] ([module.cost])
" + dat += "[module.module_name]\[?\] ([module.cost])
" dat += "
" if (src.temp) dat += "[src.temp]" @@ -497,5 +503,9 @@ rcd light flash thingy on matter drain temp = AM.description src.processing_time -= AM.cost + if(href_list["showdesc"]) + if(AM.mod_pick_name == href_list["showdesc"]) + temp = AM.description + src.use(usr) return diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index d51d1f9de64..685bbd538c7 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1212,6 +1212,9 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc else if(!seer) see_in_dark = species.darksight see_invisible = SEE_INVISIBLE_LIVING + + if(see_override) //Override all + see_invisible = see_override if(ticker && ticker.mode.name == "nations") process_nations() diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index b8bcfa4ead3..40facde6f9c 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -56,7 +56,8 @@ src.sight |= SEE_OBJS src.see_in_dark = 8 src.see_invisible = SEE_INVISIBLE_LEVEL_TWO - + if(see_override) + see_invisible = see_override //Congratulations! You've found a way for AI's to run without using power! //Todo: Without snowflaking up master_controller procs find a way to make AI use_power but only when APC's clear the area usage the tick prior From 8fb062706b18d01b6cbe49359223afc6131edaff Mon Sep 17 00:00:00 2001 From: Markolie Date: Tue, 18 Aug 2015 21:00:11 +0200 Subject: [PATCH 05/30] If check fix --- code/game/gamemodes/malfunction/Malf_Modules.dm | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 8e0bf0ee2dd..90e8eaaf814 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -115,13 +115,13 @@ rcd light flash thingy on matter drain var/obj/machinery/computer/communications/C = locate() in machines if(C) C.post_status("alert", "lockdown") + + minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.","Network Alert") + src << "Lockdown initiated. Network reset in two minutes." + spawn(1200) //120 Seconds. + disablelockdown() //Reset the lockdown after 120 seconds. else src << "Out of uses." - - minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.","Network Alert") - src << "Lockdown initiated. Network reset in two minutes." - spawn(1200) //120 Seconds. - disablelockdown() //Reset the lockdown after 120 seconds. /mob/living/silicon/ai/proc/disablelockdown() set category = "Malfunction" @@ -141,7 +141,11 @@ rcd light flash thingy on matter drain AL.safe = 1 else if(!D.stat) //Opens only powered doors. D.open() //Open everything! - + + var/obj/machinery/computer/communications/C = locate() in machines + if(C) + C.post_status("alert", "default") + minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network Reset") /datum/AI_Module/large/disable_rcd From dc442a88149ab95ea5fe9e74d2b2c96d893d493b Mon Sep 17 00:00:00 2001 From: Markolie Date: Tue, 18 Aug 2015 23:25:15 +0200 Subject: [PATCH 06/30] Pod tracking console NanoUI --- .../computer/pod_tracking_console.dm | 49 ++--- code/game/mecha/mecha_control_console.dm | 179 +++++++++--------- nano/templates/exosuit_control.tmpl | 1 + nano/templates/pod_tracking.tmpl | 32 ++++ 4 files changed, 149 insertions(+), 112 deletions(-) create mode 100644 nano/templates/exosuit_control.tmpl create mode 100644 nano/templates/pod_tracking.tmpl diff --git a/code/game/machinery/computer/pod_tracking_console.dm b/code/game/machinery/computer/pod_tracking_console.dm index 5c40d9a11f8..4ef7e046215 100644 --- a/code/game/machinery/computer/pod_tracking_console.dm +++ b/code/game/machinery/computer/pod_tracking_console.dm @@ -5,39 +5,42 @@ icon_screen = "rdcomp" light_color = LIGHT_COLOR_PURPLE req_access = list(access_robotics) - circuit = "/obj/item/weapon/circuitboard/pod_locater" + circuit = /obj/item/weapon/circuitboard/pod_locater /obj/machinery/computer/podtracker/attack_ai(var/mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/computer/podtracker/attack_hand(var/mob/user as mob) - if(..()) - return - user.set_machine(src) - var/dat = "[src.name]" - dat += "

Pod beacons data

" + return attack_hand(user) + +/obj/machinery/computer/podtracker/attack_hand(user as mob) + ui_interact(user) + +/obj/machinery/computer/podtracker/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + var/list/pods[0] for(var/obj/item/device/spacepod_equipment/misc/tracker/TR in world) var/obj/spacepod/myPod = TR.my_atom var/enabled = TR.enabled if(myPod && enabled) - dat += {"
[capitalize(myPod.name)]
-  Pod SPS X: [myPod.x]
-  Pod SPS Y: [myPod.y]
-  Pod SPS Z: [myPod.z]
"} + var/podname = sanitize(capitalize(myPod.name)) + var/occupant = "None" + var/occupant2 = "None" if(myPod.occupant) - dat += {" Pod Pilot: [myPod.occupant.name]
"} + occupant = myPod.occupant.name if(myPod.occupant2) - dat += {" Pod Passenger: [myPod.occupant2.name]
"} + occupant2 = myPod.occupant2.name + pods.Add(list(list("pod" = "\ref[myPod]", "name" = podname, "occupant" = occupant, "occupant2" = occupant2, "x" = myPod.x, "y" = myPod.y, "z" = myPod.z))) + + data["pods"] = pods - dat += "(Refresh)
" - dat += "" + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") - return + if (!ui) + ui = new(user, src, ui_key, "pod_tracking.tmpl", "Pod Tracking Console", 400, 500) + ui.set_initial_data(data) + ui.open() /obj/machinery/computer/podtracker/Topic(href, href_list) if(..()) - return - src.updateUsrDialog() - return + return 1 + + if(href_list["refresh"]) + nanomanager.update_uis(src) diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 036872780b2..fb29242fd70 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -5,64 +5,64 @@ icon_screen = "mecha" light_color = LIGHT_COLOR_FADEDPURPLE req_access = list(access_robotics) - circuit = "/obj/item/weapon/circuitboard/mecha_control" + circuit = /obj/item/weapon/circuitboard/mecha_control var/list/located = list() var/screen = 0 var/stored_data - attack_ai(var/mob/user as mob) - return src.attack_hand(user) +/obj/machinery/computer/mecha/attack_ai(var/mob/user as mob) + return attack_hand(user) - attack_hand(var/mob/user as mob) - if(..()) - return - user.set_machine(src) - var/dat = "[src.name]" - if(screen == 0) - dat += "

Tracking beacons data

" - for(var/obj/item/mecha_parts/mecha_tracking/TR in world) - var/answer = TR.get_mecha_info() - if(answer) - dat += {"
[answer]
- Send message
- Show exosuit log | (EMP pulse)
"} +/obj/machinery/computer/mecha/attack_hand(var/mob/user as mob) + ui_interact(user) + +/obj/machinery/computer/mecha/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + + if(screen == 0) + var/list/mechas[0] + for(var/obj/item/mecha_parts/mecha_tracking/TR in world) + var/answer = TR.get_mecha_info() + mechas.Add(list(answer)) + data["mechas"] = mechas + if(screen == 1) + data["log"] = stored_data - if(screen==1) - dat += "

Log contents

" - dat += "Return
" - dat += "[stored_data]" - - dat += "(Refresh)
" - dat += "" - - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") - return - - Topic(href, href_list) - if(..()) - return - var/datum/topic_input/filter = new /datum/topic_input(href,href_list) - if(href_list["send_message"]) - var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message") - var/message = strip_html_simple(input(usr,"Input message","Transmit message") as text) - var/obj/mecha/M = MT.in_mecha() - if(trim(message) && M) - M.occupant_message(message) - return - if(href_list["shock"]) - var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock") - MT.shock() - if(href_list["get_log"]) - var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log") - stored_data = MT.get_mecha_log() - screen = 1 - if(href_list["return"]) - screen = 0 - src.updateUsrDialog() - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "exosuit_control.tmpl", "Exosuit Control Console", 400, 500) + ui.set_initial_data(data) + ui.open() +/obj/machinery/computer/mecha/Topic(href, href_list) + if(..()) + return 1 + + var/datum/topic_input/filter = new /datum/topic_input(href,href_list) + if(href_list["send_message"]) + var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message") + var/message = strip_html_simple(input(usr,"Input message","Transmit message") as text) + if(!trim(message) || ..()) + return 1 + var/obj/mecha/M = MT.in_mecha() + if(M) + M.occupant_message(message) + + if(href_list["shock"]) + var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock") + MT.shock() + + if(href_list["get_log"]) + var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log") + stored_data = MT.get_mecha_log() + screen = 1 + + if(href_list["return"]) + screen = 0 + + nanomanager.update_uis(src) + return /obj/item/mecha_parts/mecha_tracking name = "Exosuit tracking beacon" @@ -73,49 +73,50 @@ construction_time = 50 construction_cost = list("metal"=500) - proc/get_mecha_info() - if(!in_mecha()) - return 0 - var/obj/mecha/M = src.loc - var/cell_charge = M.get_charge() - var/answer = {"Name: [M.name]
- Integrity: [M.health/initial(M.health)*100]%
- Cell charge: [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
- Airtank: [M.return_pressure()]kPa
- Pilot: [M.occupant||"None"]
- Location: [get_area(M)||"Unknown"]
- Active equipment: [M.selected||"None"]"} - if(istype(M, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/RM = M - answer += "Used cargo space: [RM.cargo.len/RM.cargo_capacity*100]%
" - - return answer - - emp_act() - qdel(src) - return - - ex_act() - qdel(src) - return - - proc/in_mecha() - if(istype(src.loc, /obj/mecha)) - return src.loc +/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info() + if(!in_mecha()) return 0 + var/obj/mecha/M = src.loc + var/list/answer[0] + answer["reference"] = "\ref[src]" + answer["name"] = sanitize(M.name) + answer["charge"] = M.get_charge() + answer["integrity"] = "[M.health/initial(M.health)*100]%" + answer["airtank"] = "[M.return_pressure()]kPa" + answer["pilot"] = "[M.occupant||"None"]" + answer["location"] = "[sanitize(get_area(M))||"Unknown"]" + answer["equipment"] = "[M.selected||"None"]" + + if(istype(M, /obj/mecha/working/ripley)) + var/obj/mecha/working/ripley/RM = M + answer["cargo"] = "[RM.cargo.len/RM.cargo_capacity*100]%" + + return answer - proc/shock() - var/obj/mecha/M = in_mecha() - if(M) - M.emp_act(2) - qdel(src) +/obj/item/mecha_parts/mecha_tracking/emp_act() + qdel(src) + return - proc/get_mecha_log() - if(!src.in_mecha()) - return 0 - var/obj/mecha/M = src.loc - return M.get_log_html() +/obj/item/mecha_parts/mecha_tracking/ex_act() + qdel(src) + return +/obj/item/mecha_parts/mecha_tracking/proc/in_mecha() + if(istype(src.loc, /obj/mecha)) + return src.loc + return 0 + +/obj/item/mecha_parts/mecha_tracking/proc/shock() + var/obj/mecha/M = in_mecha() + if(M) + M.emp_act(2) + qdel(src) + +/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log() + if(!src.in_mecha()) + return 0 + var/obj/mecha/M = src.loc + return M.get_log_html() /obj/item/weapon/storage/box/mechabeacons name = "Exosuit Tracking Beacons" diff --git a/nano/templates/exosuit_control.tmpl b/nano/templates/exosuit_control.tmpl new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/nano/templates/exosuit_control.tmpl @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/nano/templates/pod_tracking.tmpl b/nano/templates/pod_tracking.tmpl new file mode 100644 index 00000000000..71d96c312cb --- /dev/null +++ b/nano/templates/pod_tracking.tmpl @@ -0,0 +1,32 @@ + + +
{{:helper.link('Refresh', 'refresh', {'refresh' : 1})}}
+

Pods

+{{for data.pods}} +
+
+

{{:value.name}}

+
Pilot
+
{{:value.occupant}}
+
Passenger
+
{{:value.occupant2}}
+
Coordinates
+
{{:value.x}}, {{:value.y}}, {{:value.z}}
+
+
+{{empty}} +
No pod trackers detected!
+{{/for}} \ No newline at end of file From 6e036916ce380468796e3906c0ca216751502071 Mon Sep 17 00:00:00 2001 From: Markolie Date: Wed, 19 Aug 2015 01:25:32 +0200 Subject: [PATCH 07/30] Exosuit console NanoUI --- .../computer/pod_tracking_console.dm | 2 +- code/game/mecha/mecha_control_console.dm | 25 ++++-- nano/templates/exosuit_control.tmpl | 88 ++++++++++++++++++- nano/templates/pod_tracking.tmpl | 23 ++--- nano/templates/robot_control.tmpl | 3 +- 5 files changed, 117 insertions(+), 24 deletions(-) diff --git a/code/game/machinery/computer/pod_tracking_console.dm b/code/game/machinery/computer/pod_tracking_console.dm index 4ef7e046215..033a77801b4 100644 --- a/code/game/machinery/computer/pod_tracking_console.dm +++ b/code/game/machinery/computer/pod_tracking_console.dm @@ -20,7 +20,7 @@ var/obj/spacepod/myPod = TR.my_atom var/enabled = TR.enabled if(myPod && enabled) - var/podname = sanitize(capitalize(myPod.name)) + var/podname = capitalize(sanitize(myPod.name)) var/occupant = "None" var/occupant2 = "None" if(myPod.occupant) diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index fb29242fd70..0d0c6b255f3 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -18,12 +18,13 @@ /obj/machinery/computer/mecha/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) var/data[0] - + data["screen"] = screen if(screen == 0) var/list/mechas[0] for(var/obj/item/mecha_parts/mecha_tracking/TR in world) var/answer = TR.get_mecha_info() - mechas.Add(list(answer)) + if(answer) + mechas[++mechas.len] = answer data["mechas"] = mechas if(screen == 1) data["log"] = stored_data @@ -31,7 +32,7 @@ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) - ui = new(user, src, ui_key, "exosuit_control.tmpl", "Exosuit Control Console", 400, 500) + ui = new(user, src, ui_key, "exosuit_control.tmpl", "Exosuit Control Console", 420, 500) ui.set_initial_data(data) ui.open() @@ -79,17 +80,23 @@ var/obj/mecha/M = src.loc var/list/answer[0] answer["reference"] = "\ref[src]" - answer["name"] = sanitize(M.name) - answer["charge"] = M.get_charge() - answer["integrity"] = "[M.health/initial(M.health)*100]%" - answer["airtank"] = "[M.return_pressure()]kPa" + answer["name"] = html_encode(sanitize(M.name)) // Has to be encoded to prevent NanoUI from blanking - JavaScript decodes it in the .tmpl + if(M.cell) + answer["cell"] = 1 + answer["cell_capacity"] = M.cell.maxcharge + answer["cell_current"] = M.get_charge() + answer["cell_percentage"] = round(M.cell.percent()) + else + answer["cell"] = 0 + answer["integrity"] = M.health/initial(M.health)*100 + answer["airtank"] = M.return_pressure() answer["pilot"] = "[M.occupant||"None"]" answer["location"] = "[sanitize(get_area(M))||"Unknown"]" answer["equipment"] = "[M.selected||"None"]" - if(istype(M, /obj/mecha/working/ripley)) var/obj/mecha/working/ripley/RM = M - answer["cargo"] = "[RM.cargo.len/RM.cargo_capacity*100]%" + answer["hascargo"] = 1 + answer["cargo"] = RM.cargo.len/RM.cargo_capacity*100 return answer diff --git a/nano/templates/exosuit_control.tmpl b/nano/templates/exosuit_control.tmpl index 30d74d25844..98588c89e9a 100644 --- a/nano/templates/exosuit_control.tmpl +++ b/nano/templates/exosuit_control.tmpl @@ -1 +1,87 @@ -test \ No newline at end of file + + +{{if data.screen == 0}} + {{for data.mechas}} +
+
+

{{:value.name}}

+

Information

+
+ Pilot: +
+
+ {{:value.pilot}} +
+
+ Integrity: +
+
+ {{:value.integrity}}% +
+
+ Location: +
+
+ {{:value.location}} +
+
+ Airtank: +
+
+ {{:value.airtank}}kPa +
+
+ Active Equipment: +
+
+ {{:value.equipment}} +
+ {{if value.hascargo}} +
+ Cargo Used: +
+
+ {{:value.cargo}}% +
+ {{/if}} + +

Power Cell

+ {{if value.cell}} + + Rating: + + + {{:value.cell_capacity}} + + {{:helper.displayBar(value.cell_percentage, 0, 100, (value.cell_percentage >= 50) ? 'good' : (value.cell_percentage >= 25) ? 'average' : 'bad')}} + {{:value.cell_percentage}}% + {{else}} + Not Installed + {{:helper.displayBar(100, 0, 100, 'bad')}} + {{/if}} + + +

Actions

+ {{:helper.link('Send Message', 'mail-closed', {'send_message' : value.reference})}} + {{:helper.link('Exosuit Log', 'search', {'get_log' : value.reference})}} + {{:helper.link('EMP Pulse', 'alert', {'shock' : value.reference}, null, 'redButton')}} +
+ {{empty}} +
+

No mecha trackers were found.

+
+ {{/for}} +{{else}} +
+ {{:helper.link('Return', 'close', {'return' : 1})}} +
+ {{:data.log}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/pod_tracking.tmpl b/nano/templates/pod_tracking.tmpl index 71d96c312cb..4fd68df82f9 100644 --- a/nano/templates/pod_tracking.tmpl +++ b/nano/templates/pod_tracking.tmpl @@ -16,17 +16,18 @@ h3 {
{{:helper.link('Refresh', 'refresh', {'refresh' : 1})}}

Pods

{{for data.pods}} -
-
-

{{:value.name}}

-
Pilot
-
{{:value.occupant}}
-
Passenger
-
{{:value.occupant2}}
-
Coordinates
-
{{:value.x}}, {{:value.y}}, {{:value.z}}
-
+
+
+

{{:value.name}}

+
Pilot
+
{{:value.occupant}}
+
Passenger
+
{{:value.occupant2}}
+
Coordinates
+
{{:value.x}}, {{:value.y}}, {{:value.z}}
{{empty}} -
No pod trackers detected!
+
+

No pod trackers were found.

+
{{/for}} \ No newline at end of file diff --git a/nano/templates/robot_control.tmpl b/nano/templates/robot_control.tmpl index 61c5464ad2f..2e5e892e0e8 100644 --- a/nano/templates/robot_control.tmpl +++ b/nano/templates/robot_control.tmpl @@ -64,11 +64,10 @@ {{:value.cell_capacity}} {{:helper.displayBar(value.cell_percentage, 0, 100, (value.cell_percentage >= 50) ? 'good' : (value.cell_percentage >= 25) ? 'average' : 'bad')}} - {{:value.cell_percentage}} % + {{:value.cell_percentage}}% {{else}} Not Installed {{:helper.displayBar(100, 0, 100, 'bad')}} - N/A % {{/if}}

Actions

{{if value.status == "Operational"}} From 23071b580661fa6f7860bec5f613a14e5782adec Mon Sep 17 00:00:00 2001 From: Markolie Date: Wed, 19 Aug 2015 02:24:42 +0200 Subject: [PATCH 08/30] NanoUI AI fixer --- code/game/machinery/computer/aifixer.dm | 87 +++++++++++++------------ nano/templates/ai_fixer.tmpl | 63 ++++++++++++++++++ 2 files changed, 109 insertions(+), 41 deletions(-) create mode 100644 nano/templates/ai_fixer.tmpl diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 20d715a3a0e..a7dd1874424 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -21,57 +21,52 @@ ..() /obj/machinery/computer/aifixer/attack_ai(var/mob/user as mob) - return interact(user) + ui_interact(user) /obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob) - if(..()) - return + ui_interact(user) + +/obj/machinery/computer/aifixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + if(occupant) + data["occupant"] = occupant.name + data["reference"] = "\ref[occupant]" + data["integrity"] = (occupant.health+100)/2 + data["stat"] = occupant.stat + data["active"] = active + data["wireless"] = occupant.control_disabled + data["radio"] = occupant.aiRadio.disabledAi + data["zeroth"] = occupant.laws.zeroth - interact(user) - -/obj/machinery/computer/aifixer/interact(mob/user) - var/dat = "

AI System Integrity Restorer



" - - if (src.occupant) - var/laws - dat += "Stored AI: [src.occupant.name]
System integrity: [(src.occupant.health+100)/2]%
" - - if (src.occupant.laws.zeroth) - laws += "0: [src.occupant.laws.zeroth]
" - + var/laws[0] var/number = 1 - for (var/index = 1, index <= src.occupant.laws.inherent.len, index++) - var/law = src.occupant.laws.inherent[index] - if (length(law) > 0) - laws += "[number]: [law]
" + for (var/index = 1, index <= occupant.laws.inherent.len, index++) + var/law = occupant.laws.inherent[index] + if(length(law) > 0) + laws.Add(list(list("law" = law, "number" = number))) number++ - for (var/index = 1, index <= src.occupant.laws.supplied.len, index++) - var/law = src.occupant.laws.supplied[index] + for (var/index = 1, index <= occupant.laws.supplied.len, index++) + var/law = occupant.laws.supplied[index] if (length(law) > 0) - laws += "[number]: [law]
" - number++ + laws += "[number]: [law]
" + number++ + + data["laws"] = laws + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - dat += "Laws:
[laws]
" - - if (src.occupant.stat == 2) - dat += "AI nonfunctional" - else - dat += "AI functional" - if (!src.active) - dat += {"

Begin Reconstruction"} - else - dat += "

Reconstruction in process, please wait.
" - dat += {" Close"} - - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") - return + if (!ui) + ui = new(user, src, ui_key, "ai_fixer.tmpl", "AI System Integrity Restorer", 550, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) /obj/machinery/computer/aifixer/Topic(href, href_list) if(..()) return 1 - if (href_list["fix"]) + + if(href_list["fix"]) src.active = 1 while (src.occupant.health < 100) src.occupant.adjustOxyLoss(-1) @@ -84,11 +79,21 @@ src.occupant.lying = 0 dead_mob_list -= src.occupant living_mob_list += src.occupant - src.updateUsrDialog() sleep(10) src.active = 0 src.add_fingerprint(usr) - src.updateUsrDialog() + + if(href_list["wireless"]) + var/wireless = text2num(href_list["wireless"]) + if(wireless == 0 || wireless == 1) + occupant.control_disabled = wireless + + if(href_list["radio"]) + var/radio = text2num(href_list["radio"]) + if(radio == 0 || radio == 1) + occupant.aiRadio.disabledAi = radio + + nanomanager.update_uis(src) update_icon() return diff --git a/nano/templates/ai_fixer.tmpl b/nano/templates/ai_fixer.tmpl new file mode 100644 index 00000000000..4e88dc45c91 --- /dev/null +++ b/nano/templates/ai_fixer.tmpl @@ -0,0 +1,63 @@ + +{{if data.occupant}} +
+

Stored AI: {{:data.occupant}}

+

Information

+
+ Integrity +
+
+ {{:data.integrity}}% +
+
+ Status +
+
+ {{if data.stat == 2}} + Non-functional + {{else}} + Functional + {{/if}} +
+
+ Wireless Activity +
+
+ {{:helper.link('Enabled','check',{'wireless' : 0},data.wireless == 0 ? 'selected' : '')}} + {{:helper.link('Disabled','close',{'wireless' : 1},data.wireless == 1 ? 'selected' : '')}} +
+
+ Subspace Transceiver +
+
+ {{:helper.link('Enabled','check',{'radio' : 0},data.radio == 0 ? 'selected' : '')}} + {{:helper.link('Disabled','close',{'radio' : 1},data.radio == 1 ? 'selected' : '')}} +
+

Laws

+ {{if data.zeroth}} + 0: {{:data.zeroth}}
+ {{/if}} + {{for data.laws}} + {{:value.number}}: {{:value.law}}
+ {{empty}} + {{if !data.zeroth}} + No laws detected! + {{/if}} + {{/for}} + +

Actions

+ {{if data.active}} + Reconstruction in progress, please wait. + {{:helper.displayBar(data.integrity, 0, 100, (data.integrity >= 75) ? 'good' : (data.integrity >= 25) ? 'average' : 'bad')}} + {{:data.integrity}}% + {{/if}} +
+ {{:helper.link('Reconstruct', 'wrench', {'fix' : 1}, data.active || data.integrity >= 100 ? 'disabled' : '')}} +
+
+{{else}} +

No artificial intelligence detected.

+{{/if}} \ No newline at end of file From 4ef1f9ce0934a27ced46f0f8d921d99019c782b9 Mon Sep 17 00:00:00 2001 From: Alex6511 Date: Tue, 18 Aug 2015 22:04:27 -0400 Subject: [PATCH 09/30] Update shuttle_controller.dm --- code/controllers/shuttle_controller.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 9c536931ce1..7c8a9847496 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -279,7 +279,7 @@ var/global/datum/shuttle_controller/shuttle_controller ) WS.announcer = "NSV Icarus" - WS.arrival_message = "Attention, [station_name()], we just tracked a large medical vessel approaching the station from the telecommunications satellite. Can't fire on them without hitting the station - prepare for visitors." + WS.arrival_message = "Attention, [station_name()], we just tracked a large medical vessel approaching the station from the telecommunications satellite. Might have wounded on board, can't destroy it - prepare for visitors." WS.departure_message = "Your guests are pulling away, [station_name()] - moving too fast for us to draw a bead on them. Looks like they're heading back to the telecommunications satellite." WS.interim = locate(/area/shuttle/derelict/ship/transit) From 9bab32fec4ee0d618f18347ff151879d795c509d Mon Sep 17 00:00:00 2001 From: Markolie Date: Wed, 19 Aug 2015 21:58:56 +0200 Subject: [PATCH 10/30] Better escape solution --- code/game/machinery/computer/pod_tracking_console.dm | 1 + code/game/mecha/mecha_control_console.dm | 8 +++++--- nano/templates/exosuit_control.tmpl | 8 +------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/code/game/machinery/computer/pod_tracking_console.dm b/code/game/machinery/computer/pod_tracking_console.dm index 033a77801b4..060b58eda90 100644 --- a/code/game/machinery/computer/pod_tracking_console.dm +++ b/code/game/machinery/computer/pod_tracking_console.dm @@ -37,6 +37,7 @@ ui = new(user, src, ui_key, "pod_tracking.tmpl", "Pod Tracking Console", 400, 500) ui.set_initial_data(data) ui.open() + ui.set_auto_update(1) /obj/machinery/computer/podtracker/Topic(href, href_list) if(..()) diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 0d0c6b255f3..84c896a0ab3 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -35,6 +35,7 @@ ui = new(user, src, ui_key, "exosuit_control.tmpl", "Exosuit Control Console", 420, 500) ui.set_initial_data(data) ui.open() + ui.set_auto_update(1) /obj/machinery/computer/mecha/Topic(href, href_list) if(..()) @@ -80,7 +81,7 @@ var/obj/mecha/M = src.loc var/list/answer[0] answer["reference"] = "\ref[src]" - answer["name"] = html_encode(sanitize(M.name)) // Has to be encoded to prevent NanoUI from blanking - JavaScript decodes it in the .tmpl + answer["name"] = sanitize(replacetext(M.name,"\"","")) // Apostrophes break JSON if(M.cell) answer["cell"] = 1 answer["cell_capacity"] = M.cell.maxcharge @@ -90,8 +91,9 @@ answer["cell"] = 0 answer["integrity"] = M.health/initial(M.health)*100 answer["airtank"] = M.return_pressure() - answer["pilot"] = "[M.occupant||"None"]" - answer["location"] = "[sanitize(get_area(M))||"Unknown"]" + answer["pilot"] = "[M.occupant||"None"]" + var/area/area = get_area(M) + answer["location"] = "[sanitize(area.name)||"Unknown"]" answer["equipment"] = "[M.selected||"None"]" if(istype(M, /obj/mecha/working/ripley)) var/obj/mecha/working/ripley/RM = M diff --git a/nano/templates/exosuit_control.tmpl b/nano/templates/exosuit_control.tmpl index 98588c89e9a..c3b88d50f54 100644 --- a/nano/templates/exosuit_control.tmpl +++ b/nano/templates/exosuit_control.tmpl @@ -2,17 +2,11 @@ Title: Exosuit Control Console Used In File(s): \code\game\mecha\mecha_control_console.dm --> - {{if data.screen == 0}} {{for data.mechas}}
-

{{:value.name}}

+

{{:value.name}}

Information

Pilot: From 2b5f86e062f71c8f52a8fc36173eb491101cbeee Mon Sep 17 00:00:00 2001 From: Markolie Date: Wed, 19 Aug 2015 22:06:55 +0200 Subject: [PATCH 11/30] Single apostrophe instead of double --- code/game/mecha/mecha_control_console.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 84c896a0ab3..ce44f2e59b1 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -81,7 +81,7 @@ var/obj/mecha/M = src.loc var/list/answer[0] answer["reference"] = "\ref[src]" - answer["name"] = sanitize(replacetext(M.name,"\"","")) // Apostrophes break JSON + answer["name"] = sanitize(replacetext(M.name,"\"","'")) // Double apostrophes break JSON if(M.cell) answer["cell"] = 1 answer["cell_capacity"] = M.cell.maxcharge From b6a1e52e08e62e93d854d3056e24d009e36a51a4 Mon Sep 17 00:00:00 2001 From: Markolie Date: Wed, 19 Aug 2015 22:22:51 +0200 Subject: [PATCH 12/30] Hopefully fix uplink crashing --- code/datums/uplink_item.dm | 42 +++++++++++----------- code/game/objects/items/devices/uplinks.dm | 8 ++--- nano/templates/uplink.tmpl | 5 +-- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 7df1764a2a9..2a4a3d3a14b 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -141,7 +141,7 @@ var/list/uplink_items = list() /datum/uplink_item/jobspecific/syndidonk name = "Syndicate Donk Pockets" - desc = "A box of highly specialized donk pockets with a number of regenerative and stimulating chemicals inside of them; the box comes equipped with a self-heating mechanism." + desc = "A box of highly specialized Donk pockets with a number of regenerative and stimulating chemicals inside of them; the box comes equipped with a self-heating mechanism." reference = "SDP" item = /obj/item/weapon/storage/box/syndidonkpockets cost = 2 @@ -162,7 +162,7 @@ var/list/uplink_items = list() /datum/uplink_item/jobspecific/rad_laser name = "Radiation Laser" - desc = "A radiation laser concealed inside of a Health Analyser, After a moderate delay, causes temporary collapse and radiation. Has adjustable controls, but will not function as a regular health analyser, only appears like one. May not function correctly on radiation resistant humanoids!" + desc = "A radiation laser concealed inside of a Health Analyser. After a moderate delay, causes temporary collapse and radiation. Has adjustable controls, but will not function as a regular health analyser, only appears like one. May not function correctly on radiation resistant humanoids!" reference = "RL" item = /obj/item/device/rad_laser cost = 6 @@ -270,7 +270,7 @@ var/list/uplink_items = list() /datum/uplink_item/dangerous/car name = "C-90gl Compact Assault Rifle" - desc = "A fully-loaded Zashchita Industriya toploading bullpup assault rifle that uses 30-round 5.45x39mm magazines with a togglable underslung 40mm grenade launcher." + desc = "A fully-loaded Zashchita Industriya toploading bullpup assault rifle that uses 30-round 5.45x39mm magazines with a toggleable underslung 40mm grenade launcher." reference = "AR" item = /obj/item/weapon/gun/projectile/automatic/c90gl cost = 18 @@ -297,7 +297,7 @@ var/list/uplink_items = list() /datum/uplink_item/dangerous/flamethrower name = "Flamethrower" - desc = "A flamethrower, fueled by a portion of highly flammable biotoxins stolen previously from Nanotrasen stations. Make a statement by roasting the filth in their own greed. Use with caution." + desc = "A flamethrower, fuelled by a portion of highly flammable bio-toxins stolen previously from Nanotrasen stations. Make a statement by roasting the filth in their own greed. Use with caution." reference = "FT" item = /obj/item/weapon/flamethrower/full/tank cost = 11 @@ -306,7 +306,7 @@ var/list/uplink_items = list() /datum/uplink_item/dangerous/sword name = "Energy Sword" - desc = "The esword is an edged weapon with a blade of pure energy. The sword is small enough to be pocketed when inactive. Activating it produces a loud, distinctive noise." + desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be pocketed when inactive. Activating it produces a loud, distinctive noise." reference = "ES" item = /obj/item/weapon/melee/energy/sword cost = 8 @@ -329,7 +329,7 @@ var/list/uplink_items = list() /datum/uplink_item/dangerous/tabungrenades name = "Tabun Gas Grenades" - desc = "A box of four (4) grenades filled with tabun, a deadly neurotoxin. Use extreme caution when handling and be sure to vacate the premise after using; ensure communication is maintaind with team to avoid accidental gassings." + desc = "A box of four (4) grenades filled with Tabun, a deadly neurotoxin. Use extreme caution when handling and be sure to vacate the premise after using; ensure communication is maintained with team to avoid accidental gassings." reference = "TGG" item = /obj/item/weapon/storage/box/syndie_kit/tabun cost = 15 @@ -345,7 +345,7 @@ var/list/uplink_items = list() /datum/uplink_item/dangerous/syndicate_minibomb name = "Syndicate Minibomb" - desc = "The Minibomb is a grenade with a five-second fuse." + desc = "The minibomb is a grenade with a five-second fuse." reference = "SMB" item = /obj/item/weapon/grenade/syndieminibomb cost = 6 @@ -362,7 +362,7 @@ var/list/uplink_items = list() /datum/uplink_item/dangerous/mauler name = "Mauler Exosuit" - desc = "A massive and incredibly deadly Syndicate exosuit. Features long-range targetting, thrust vectoring, and deployable smoke." + desc = "A massive and incredibly deadly Syndicate exosuit. Features long-range targeting, thrust vectoring, and deployable smoke." reference = "ME" item = /obj/mecha/combat/marauder/mauler/loaded cost = 140 @@ -453,8 +453,8 @@ var/list/uplink_items = list() gamemodes = list("nuclear emergency") /datum/uplink_item/ammo/machinegun - name = "Box Magazine - 7.62×51mm" - desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW machinegun. By the time you need to use this, you'll already be on a pile of corpses." + name = "Box Magazine - 7.62x51mm" + desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW machine gun. By the time you need to use this, you'll already be on a pile of corpses." reference = "762" item = /obj/item/ammo_box/magazine/m762 cost = 12 @@ -489,8 +489,6 @@ var/list/uplink_items = list() item = /obj/item/weapon/cartridge/syndicate cost = 6 -// Commented out until a fix can be found, currently doesn't work with the PDA NanoUI and people keep wasting Telecrystals on it. -- Dave - /datum/uplink_item/stealthy_weapons/silencer name = "Universal Suppressor" desc = "Fitted for use on any small caliber weapon with a threaded barrel, this suppressor will silence the shots of the weapon for increased stealth and superior ambushing capability." @@ -528,7 +526,7 @@ var/list/uplink_items = list() /datum/uplink_item/stealthy_tools/chameleon_stamp name = "Chameleon Stamp" - desc = "A stamp that can be activated to imitate an official Nanotrasen Stamp™. The disguised stamp will work exactly like the real stamp and will allow you to forge false documents to gain access or equipment; \ + desc = "A stamp that can be activated to imitate an official Nanotrasen Stamp. The disguised stamp will work exactly like the real stamp and will allow you to forge false documents to gain access or equipment; \ it can also be used in a washing machine to forge clothing." reference = "CHST" item = /obj/item/weapon/stamp/chameleon @@ -551,14 +549,14 @@ var/list/uplink_items = list() /datum/uplink_item/stealthy_tools/voice_changer name = "Voice Changer" - desc = "A conspicuous gas mask that mimics the voice named on your identification card. When no identification is worn, the mask will render your voice unrecognizable." + desc = "A conspicuous gas mask that mimics the voice named on your identification card. When no identification is worn, the mask will render your voice unrecognisable." reference = "VC" item = /obj/item/clothing/mask/gas/voice cost = 5 /datum/uplink_item/stealthy_tools/chameleon_proj name = "Chameleon-Projector" - desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't move the projector from their hand. The disguised user cannot run and rojectiles pass over them." + desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't move the projector from their hand. The disguised user cannot run and projectiles pass over them." reference = "CP" item = /obj/item/device/chameleon cost = 7 @@ -594,7 +592,7 @@ var/list/uplink_items = list() /datum/uplink_item/device_tools/emag name = "Cryptographic Sequencer" - desc = "The emag is a small card that unlocks hidden functions in electronic devices, subverts intended functions and characteristically breaks security mechanisms." + desc = "The cryptographic sequencer, also known as an emag, is a small card that unlocks hidden functions in electronic devices, subverts intended functions and characteristically breaks security mechanisms." reference = "EMAG" item = /obj/item/weapon/card/emag cost = 6 @@ -609,7 +607,7 @@ var/list/uplink_items = list() /datum/uplink_item/device_tools/medkit name = "Syndicate Combat Medic Kit" - desc = "The syndicate medkit is a suspicious black and red. Included is a combat stimulant injector for rapid healing, a medical hud for quick identification of injured comrades, \ + desc = "The syndicate medkit is a suspicious black and red. Included is a combat stimulant injector for rapid healing, a medical HUD for quick identification of injured comrades, \ and other medical supplies helpful for a medical field operative." reference = "SCMK" item = /obj/item/weapon/storage/firstaid/tactical @@ -632,8 +630,8 @@ var/list/uplink_items = list() /datum/uplink_item/device_tools/hardsuit name = "Blood-red Hardsuit" - desc = "The feared suit of a syndicate nuclear agent. Features slightly better armoring. When the helmet is deployed your identity will be protected. Toggling the suit into combat mode \ - will allow you all the mobility of a loose fitting uniform without sacrificing armoring. Additionally the suit is collapsible, small enough to fit within a backpack. \ + desc = "The feared suit of a syndicate nuclear agent. Features slightly better armor. When the helmet is deployed your identity will be protected. Toggling the suit into combat mode \ + will allow you all the mobility of a loose fitting uniform without sacrificing armor. Additionally the suit is collapsible, small enough to fit within a backpack. \ Nanotrasen crewmembers are trained to report red space suit sightings, these suits in particular are known to drive employees into a panic." reference = "BRHS" item = /obj/item/weapon/storage/box/syndie_kit/hardsuit @@ -641,7 +639,7 @@ var/list/uplink_items = list() /datum/uplink_item/device_tools/thermal name = "Thermal Imaging Glasses" - desc = "These glasses are thermals disguised as engineers' optical meson scanners. They allow you to see organisms through walls by capturing the upper portion of the infrared light spectrum, emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks." + desc = "These glasses are thermals disguised as engineers' optical meson scanners. They allow you to see organisms through walls by capturing the upper portion of the infra-red light spectrum, emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks." reference = "THIG" item = /obj/item/clothing/glasses/thermal/syndi cost = 6 @@ -680,7 +678,7 @@ var/list/uplink_items = list() /datum/uplink_item/device_tools/plastic_explosives name = "Composition C-4" - desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls or connect a signaler to its wiring to make it remotely detonable. It has a modifiable timer with a minimum setting of 10 seconds." + desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls or connect a signaller to its wiring to make it remotely detonable. It has a modifiable timer with a minimum setting of 10 seconds." reference = "C4" item = /obj/item/weapon/c4 cost = 1 @@ -762,7 +760,7 @@ var/list/uplink_items = list() /datum/uplink_item/implants/uplink name = "Uplink Implant" - desc = "An implant injected into the body, and later activated using a bodily gesture to open an uplink with 5 telecrystals. The ability for an agent to open an uplink after their posessions have been stripped from them makes this implant excellent for escaping confinement." + desc = "An implant injected into the body, and later activated using a bodily gesture to open an uplink with 5 telecrystals. The ability for an agent to open an uplink after their possessions have been stripped from them makes this implant excellent for escaping confinement." reference = "UI" item = /obj/item/weapon/implanter/uplink cost = 14 diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index 4efc8bdc2ee..28c573be0bb 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -50,10 +50,10 @@ var/list/world_uplinks = list() job = user.mind.assigned_role var/dat = "[src.welcome]
" - dat += "Tele-Crystals left: [src.uses]
" + dat += "Telecrystals left: [src.uses]
" dat += "
" dat += "Request item:
" - dat += "Each item costs a number of tele-crystals as indicated by the number following their name.
" + dat += "Each item costs a number of telecrystals as indicated by the number following their name.
" var/category_items = 1 for(var/category in ItemsCategory) @@ -262,10 +262,6 @@ var/list/world_uplinks = list() for(var/datum/data/record/L in data_core.general) if(L.fields["id"] == id) nanoui_data["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value. - // We trade off being able to automatically add shit for more control over what gets passed to json - // and if it's sanitized for html. - nanoui_data["exploit"]["nanoui_exploit_record"] = html_encode(L.fields["exploit_record"]) // Change stuff into html - nanoui_data["exploit"]["nanoui_exploit_record"] = replacetext(nanoui_data["exploit"]["nanoui_exploit_record"], "\n", "
") // change line breaks into
nanoui_data["exploit"]["name"] = html_encode(L.fields["name"]) nanoui_data["exploit"]["sex"] = html_encode(L.fields["sex"]) nanoui_data["exploit"]["age"] = html_encode(L.fields["age"]) diff --git a/nano/templates/uplink.tmpl b/nano/templates/uplink.tmpl index a5080f05f36..77550917993 100644 --- a/nano/templates/uplink.tmpl +++ b/nano/templates/uplink.tmpl @@ -12,7 +12,7 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm
{{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}} - {{:helper.link(data.descriptions ? 'Hide Descriptions' : 'Show Descriptions', 'gear', {'descriptions' : 1}, null, 'fixedLeftWider')}} + {{:helper.link(data.descriptions ? 'Hide Descriptions' : 'Show Descriptions', 'gear', {'descriptions' : 1}, data.menu == 0 ? '' : 'disabled', 'fixedLeftWider')}} {{:helper.link('Exploitable Information', 'gear', {'menu' : 1}, null, 'fixedLeftWider')}} {{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}} {{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}} @@ -80,9 +80,6 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm Age: {{:data.exploit.age}}
Rank: {{:data.exploit.rank}}
Fingerprint: {{:data.exploit.fingerprint}}
- -
Acquired Information:
- Notes:
{{:data.exploit.nanoui_exploit_record}}

{{else}} No exploitative information acquired! From 4d21896e9809bb1ed13381e49ba11df458260591 Mon Sep 17 00:00:00 2001 From: Markolie Date: Wed, 19 Aug 2015 22:32:52 +0200 Subject: [PATCH 13/30] Fix cargo computer invalid request bug --- code/game/supplyshuttle.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index d40539cdbf7..847c4179d8f 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -676,11 +676,10 @@ var/list/mechtoys = list( supply_controller.points -= P.cost supply_controller.shoppinglist += O temp = "Thanks for your order.
" - temp += "
Back Main Menu" else temp = "Not enough supply points.
" - temp += "
Back Main Menu" break + temp += "
Back Main Menu" else if (href_list["vieworders"]) temp = "Current approved orders:

" From d623c977417bc019558676becc134f468f80ff01 Mon Sep 17 00:00:00 2001 From: Fox-McCloud Date: Wed, 19 Aug 2015 18:16:52 -0400 Subject: [PATCH 14/30] Detective Scanner Protolathe Production --- code/modules/DetectiveWork/scanner.dm | 1 + code/modules/research/designs/equipment_designs.dm | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/code/modules/DetectiveWork/scanner.dm b/code/modules/DetectiveWork/scanner.dm index d694e4c1645..5aec21ac94e 100644 --- a/code/modules/DetectiveWork/scanner.dm +++ b/code/modules/DetectiveWork/scanner.dm @@ -10,6 +10,7 @@ item_state = "electronic" flags = CONDUCT | NOBLUDGEON slot_flags = SLOT_BELT + origin_tech = "magnets=4;biotech=2" var/scanning = 0 var/list/log = list() diff --git a/code/modules/research/designs/equipment_designs.dm b/code/modules/research/designs/equipment_designs.dm index 10a6a18ee31..ab78834a877 100644 --- a/code/modules/research/designs/equipment_designs.dm +++ b/code/modules/research/designs/equipment_designs.dm @@ -99,4 +99,15 @@ build_type = PROTOLATHE materials = list("$metal" = 4000, "$glass" = 1000) build_path = /obj/item/clothing/mask/gas/welding + category = list("Equipment") + +/datum/design/detective_scanner + name = "Forensic Scanner" + desc = "A high tech scanner designed for forensic evidence collection, DNA recovery, and fiber analysis." + id = "detectivescanner" + req_tech = list("biotech" = 2, "magnets" = 4) + build_type = PROTOLATHE + materials = list("$metal" = 6000, "$glass" = 2000) + build_path = /obj/item/device/detective_scanner + locked = 1 //no validhunting scientists. category = list("Equipment") \ No newline at end of file From 52a99468f124a0ed30bffd76602c5581f57e2540 Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 00:59:53 +0200 Subject: [PATCH 15/30] Remove stray light switch in mime's office --- _maps/map_files/cyberiad/cyberiad.dmm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index e24dc3825bc..62d2c9ec126 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -1337,7 +1337,7 @@ "azK" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/crew_quarters/fitness) "azL" = (/turf/simulated/wall,/area/mimeoffice) "azM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/spray/waterflower,/turf/simulated/floor/wood,/area/mimeoffice) -"azN" = (/obj/structure/table/woodentable,/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/obj/item/weapon/paper_bin,/obj/item/toy/crayon/mime,/obj/machinery/light_switch{name = "light switch "; dir = 2; pixel_x = 0; pixel_y = -22},/turf/simulated/floor/wood,/area/mimeoffice) +"azN" = (/obj/structure/table/woodentable,/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/obj/item/weapon/paper_bin,/obj/item/toy/crayon/mime,/turf/simulated/floor/wood,/area/mimeoffice) "azO" = (/obj/machinery/camera{c_tag = "Magistrate's Office"; dir = 4; network = list("SS13")},/turf/simulated/floor/carpet,/area/magistrateoffice) "azP" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/carpet,/area/magistrateoffice) "azQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/carpet,/area/magistrateoffice) From 286d2301f4a4765693dff7625a616face5df0c7f Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 01:29:23 +0200 Subject: [PATCH 16/30] Replace disabling RCD's with exploding them --- .../gamemodes/malfunction/Malf_Modules.dm | 30 +++++++++++-------- code/game/mecha/equipment/tools/tools.dm | 9 +----- code/game/objects/items/weapons/RCD.dm | 4 --- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 90e8eaaf814..622ec56bf4f 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -81,7 +81,6 @@ rcd light flash thingy on matter drain mod_pick_name = "lockdown" description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 120 seconds." cost = 20 - uses = 1 power_type = /mob/living/silicon/ai/proc/lockdown @@ -148,10 +147,10 @@ rcd light flash thingy on matter drain minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network Reset") -/datum/AI_Module/large/disable_rcd - module_name = "RCD Disable" +/datum/AI_Module/large/destroy_rcd + module_name = "Destroy RCDs" mod_pick_name = "rcd" - description = "Send a specialised pulse to break all hand-held and exosuit Rapid Cconstruction Devices on the station." + description = "Send a specialised pulse to detonate all hand-held and exosuit Rapid Cconstruction Devices on the station." cost = 25 one_time = 1 @@ -159,19 +158,24 @@ rcd light flash thingy on matter drain /mob/living/silicon/ai/proc/disable_rcd() set category = "Malfunction" - set name = "Disable RCDs" - set desc = "Disable all RCD devices on the station, while sparing onboard cyborg RCDs." + set name = "Destroy RCDs" + set desc = "Detonate all RCDs on the station, while sparing onboard cyborg RCDs." - if(stat) + if(stat || malf_cooldown) return - for(var/obj/item/weapon/rcd/RCD in rcd_list) - if(!istype(/obj/item/weapon/rcd/borg, RCD)) //Ensures that cyborg RCDs are spared. - RCD.disabled = 1 - for(var/obj/item/mecha_parts/mecha_equipment/tool/rcd/MRCD in rcd_list) - MRCD.disabled = 1 + for(var/obj/item/RCD in rcd_list) + if(!istype(RCD, /obj/item/weapon/rcd/borg)) //Ensures that cyborg RCDs are spared. + RCD.audible_message("[RCD] begins to vibrate and buzz loudly!","[RCD] begins vibrating violently!") + spawn(50) //5 seconds to get rid of it! + if(RCD) //Make sure it still exists (In case of chain-reaction) + explosion(RCD, 0, 0, 3, 1, flame_range = 1) + qdel(RCD) - src << "RCD-disabling pulse emitted." + src << "RCD detonation pulse emitted." + malf_cooldown = 1 + spawn(100) + malf_cooldown = 0 /datum/AI_Module/large/mecha_domination module_name = "Viral Mech Domination" diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index c127723f704..9882151bb21 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -282,7 +282,6 @@ construction_time = 1200 construction_cost = list("metal"=30000,"plasma"=25000,"silver"=20000,"gold"=20000) var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock. - var/disabled = 0 //malf var/canRwall = 0 New() @@ -298,7 +297,7 @@ return if(!istype(target, /turf) && !istype(target, /obj/machinery/door/airlock)) target = get_turf(target) - if(!action_checks(target) || disabled || get_dist(chassis, target)>3) return + if(!action_checks(target) || get_dist(chassis, target)>3) return playsound(chassis, 'sound/machines/click.ogg', 50, 1) //meh switch(mode) @@ -309,7 +308,6 @@ occupant_message("Deconstructing [target]...") set_ready_state(0) if(do_after_cooldown(target)) - if(disabled) return chassis.spark_system.start() target:ChangeTurf(/turf/simulated/floor/plating) playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) @@ -318,7 +316,6 @@ occupant_message("Deconstructing [target]...") set_ready_state(0) if(do_after_cooldown(target)) - if(disabled) return chassis.spark_system.start() target:ChangeTurf(/turf/space) playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) @@ -327,7 +324,6 @@ occupant_message("Deconstructing [target]...") set_ready_state(0) if(do_after_cooldown(target)) - if(disabled) return chassis.spark_system.start() qdel(target) playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) @@ -337,7 +333,6 @@ occupant_message("Building Floor...") set_ready_state(0) if(do_after_cooldown(target)) - if(disabled) return target:ChangeTurf(/turf/simulated/floor/plating) playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) chassis.spark_system.start() @@ -346,7 +341,6 @@ occupant_message("Building Wall...") set_ready_state(0) if(do_after_cooldown(target)) - if(disabled) return target:ChangeTurf(/turf/simulated/wall) playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) chassis.spark_system.start() @@ -356,7 +350,6 @@ occupant_message("Building Airlock...") set_ready_state(0) if(do_after_cooldown(target)) - if(disabled) return chassis.spark_system.start() var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target) T.autoclose = 1 diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index 3330a3831cf..2d788e219a4 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -26,8 +26,6 @@ RCD var/working = 0 var/mode = 1 var/canRwall = 0 - var/disabled = 0 - New() desc = "A RCD. It currently holds [matter]/[max_matter] matter-units." @@ -88,8 +86,6 @@ RCD afterattack(atom/A, mob/user, proximity) if(!proximity) return - if(disabled && !isrobot(user)) - return 0 if(istype(A,/area/shuttle)||istype(A,/turf/space/transit)) return 0 if(!(istype(A, /turf) || istype(A, /obj/machinery/door/airlock))) From 87570fc08073bb17ea8d7c887160b506b731e822 Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 17:25:55 +0200 Subject: [PATCH 17/30] isNonCrewAntag() checks, key_name fixes --- code/game/dna/genes/vg_powers.dm | 19 ++++++++++++------- code/game/gamemodes/game_mode.dm | 3 ++- code/game/machinery/kitchen/gibber.dm | 6 +++--- code/game/objects/items/weapons/tools.dm | 2 +- code/modules/assembly/bomb.dm | 6 +++--- code/modules/hydroponics/grown.dm | 6 +++--- code/modules/karma/karma.dm | 2 +- code/modules/mob/mob_helpers.dm | 12 ++++++++++++ code/modules/reagents/reagent_dispenser.dm | 4 ++-- code/modules/recycling/disposal.dm | 6 +++--- .../tools/ano_device_battery.dm | 6 +++--- .../vehicle/train/trains/cargo/cargo_train.dm | 8 ++++---- 12 files changed, 49 insertions(+), 31 deletions(-) diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index aec9b2580b5..497e69bc10c 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -224,7 +224,7 @@ Obviously, requires DNA2. var/list/validtargets = new /list() for(var/mob/M in living_mob_list) if(M && M.mind) - if(isAntag(M)) + if(M.z != user.z || isNonCrewAntag(M)) continue validtargets += M @@ -277,17 +277,22 @@ Obviously, requires DNA2. action_icon_state = "genetic_view" -/obj/effect/proc_holder/spell/targeted/remoteview/choose_targets(mob/user = usr) +/obj/effect/proc_holder/spell/targeted/remoteview/choose_targets(mob/user = usr) var/list/targets = living_mob_list - var/list/remoteviewers = new /list() + var/list/validtargets = new /list() for(var/mob/M in targets) - if(REMOTE_VIEW in M.mutations) - remoteviewers += M - if(!remoteviewers.len || remoteviewers.len == 1) + if(M && M.mind) + if(M.z != user.z || isNonCrewAntag(M)) + continue + + validtargets += M + + if(!validtargets.len || validtargets.len == 1) usr << "No valid targets with remote view were found!" start_recharge() return - targets += input("Choose the target to spy on.", "Targeting") as mob in remoteviewers + + targets += input("Choose the target to spy on.", "Targeting") as mob in validtargets perform(targets) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index d0e2228162c..8809476c3ed 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -238,7 +238,7 @@ var/list/suspects = list() for(var/mob/living/carbon/human/man in player_list) if(man.client && man.mind) // NT relation option - if(isAntag(man)) + if(isNonCrewAntag(man)) continue //NT intelligence ruled out possiblity that those are too classy to pretend to be a crew. if(man.client.prefs.nanotrasen_relation == "Opposed" && prob(50) || \ man.client.prefs.nanotrasen_relation == "Skeptical" && prob(20)) @@ -246,6 +246,7 @@ // Antags else if(special_role == "traitor" && prob(40) || \ special_role == "Changeling" && prob(50) || \ + special_role == "Vampire" && prob(40) || \ special_role == "Cultist" && prob(30) || \ special_role == "Head Revolutionary" && prob(30) || \ special_role == "Shadowling" && prob(15)) diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index db49facd824..7c08f2ebd07 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -374,11 +374,11 @@ new /obj/effect/decal/cleanable/blood/gibs(src) if(!UserOverride) - src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [user]/[user.ckey]" //One shall not simply gib a mob unnoticed! - user.attack_log += "\[[time_stamp()]\] Gibbed [src.occupant]/[src.occupant.ckey]" + src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [key_name(user)]" //One shall not simply gib a mob unnoticed! + user.attack_log += "\[[time_stamp()]\] Gibbed [key_name(occupant)]" if(src.occupant.ckey) - msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] gibbed [src.occupant] ([src.occupant.ckey]) (JMP)") + msg_admin_attack("[key_name_admin(user)] gibbed [key_name_admin(occupant)]") if(!iscarbon(user)) src.occupant.LAssailant = null diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index a71b1c76df4..b94337a118c 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -258,7 +258,7 @@ playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6) return else if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1 && src.welding) - msg_admin_attack("[key_name_admin(user)][isAntag(user) ? "(ANTAG)" : ""] triggered a fueltank explosion.") + msg_admin_attack("[key_name_admin(user)] triggered a fueltank explosion.") log_game("[key_name(user)] triggered a fueltank explosion.") user << "\red That was stupid of you." var/obj/structure/reagent_dispensers/fueltank/tank = O diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index 8085fefd999..ec2277c22dd 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -44,12 +44,12 @@ if((istype(W, /obj/item/weapon/weldingtool) && W:welding)) if(!status) status = 1 - bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]" - msg_admin_attack("[key_name_admin(user)][isAntag(user) ? "(ANTAG)" : ""] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]") + bombers += "[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]" + msg_admin_attack("[key_name_admin(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]") user << "A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited." else status = 0 - bombers += "[key_name(user)] unwelded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]" + bombers += "[key_name(user)] unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]" user << "The hole has been closed." add_fingerprint(user) ..() diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 17417104463..f494d7336db 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -302,9 +302,9 @@ user.lastattacked = M M.lastattacker = user - user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) + user.attack_log += "\[[time_stamp()]\] Attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" + M.attack_log += "\[[time_stamp()]\] Attacked by [key_name(user)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" + msg_admin_attack("[key_name_admin(user)] attacked [key_name_admin(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 6c3a5d35046..4144c4ef5cc 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -63,7 +63,7 @@ var/list/karma_spenders = list() var/list/karma_list = list("Cancel") for(var/mob/M in player_list) if(M.client && M.mind) - if(isAntag(M)) // Don't include special roles, because players use it to meta + if(isNonCrewAntag(M)) // Don't include special roles, because players use it to meta continue karma_list += M diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index a67a2eed0d9..31f1c84e09c 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -174,6 +174,18 @@ proc/isAntag(A) if(C.mind && C.mind.special_role) return 1 return 0 + +proc/isNonCrewAntag(A) + if(!isAntag(A)) + return 0 + + var/mob/living/carbon/C = A + var/special_role = C.mind.special_role + var/list/crew_roles = list("traitor", "Changeling", "Vampire", "Cultist", "Head Revolutionary", "Revolutionary", "malfunctioning AI", "Shadowling", "loyalist", "mutineer", "Response Team") + if((special_role in allowed_roles)) + return 0 + + return 1 proc/isnewplayer(A) if(istype(A, /mob/new_player)) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index eb13ba91b21..b0d3a7e4a85 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -135,8 +135,8 @@ var/obj/item/device/assembly_holder/H = W if (istype(H.a_left,/obj/item/device/assembly/igniter) || istype(H.a_right,/obj/item/device/assembly/igniter)) - msg_admin_attack("[key_name_admin(user)][isAntag(user) ? "(ANTAG)" : ""] rigged fueltank at ([loc.x],[loc.y],[loc.z]) for explosion.") - log_game("[key_name(user)] rigged fueltank at ([loc.x],[loc.y],[loc.z]) for explosion.") + msg_admin_attack("[key_name_admin(user)] rigged a fueltank for explosion (JMP)") + log_game("[key_name(user)] rigged fueltank a fueltank for explosion at [loc.x], [loc.y], [loc.z]") rig = W user.drop_item() diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 21cbcd5c49d..e6a16f00765 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -169,10 +169,10 @@ msg = "[user.name] stuffs [target.name] into the [src]!" user << "You stuff [target.name] into the [src]!" - user.attack_log += text("\[[time_stamp()]\] Has placed [target.name] ([target.ckey]) in disposals.") - target.attack_log += text("\[[time_stamp()]\] Has been placed in disposals by [user.name] ([user.ckey])") + user.attack_log += text("\[[time_stamp()]\] Has placed [key_name(target)] in disposals.") + target.attack_log += text("\[[time_stamp()]\] Has been placed in disposals by [key_name(user)]") if(target.ckey) - msg_admin_attack("[user] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] placed [target] ([target.ckey]) in a disposals unit. (JMP)") + msg_admin_attack("[key_name_admin(user)] placed [key_name_admin(target)] in a disposals unit") else return if (target.client) diff --git a/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm b/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm index bb1d7e30c4f..6df826f3792 100644 --- a/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm +++ b/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm @@ -210,6 +210,6 @@ M.lastattacker = user if(inserted_battery.battery_effect) - user.attack_log += "\[[time_stamp()]\] Tapped [M.name] ([M.ckey]) with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" - M.attack_log += "\[[time_stamp()]\] Tapped by [user.name] ([user.ckey]) with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" - msg_admin_attack("[key_name(user)][isAntag(user) ? "(ANTAG)" : ""] tapped [key_name(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" ) + user.attack_log += "\[[time_stamp()]\] Tapped [key_name(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" + M.attack_log += "\[[time_stamp()]\] Tapped by [key_name(user)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" + msg_admin_attack("[key_name_admin(user)] tapped [key_name_admin(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" ) diff --git a/code/modules/vehicle/train/trains/cargo/cargo_train.dm b/code/modules/vehicle/train/trains/cargo/cargo_train.dm index 1daee673201..a8f50cd5463 100644 --- a/code/modules/vehicle/train/trains/cargo/cargo_train.dm +++ b/code/modules/vehicle/train/trains/cargo/cargo_train.dm @@ -144,7 +144,7 @@ /obj/vehicle/train/cargo/trolley/RunOver(var/mob/living/carbon/human/H) ..() - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey])") + attack_log += text("\[[time_stamp()]\] ran over [key_name(H)]") /obj/vehicle/train/cargo/engine/RunOver(var/mob/living/carbon/human/H) ..() @@ -153,10 +153,10 @@ var/mob/living/carbon/human/D = load D << "\red \b You ran over [H]!" visible_message("\red \The [src] ran over [H]!") - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey]), driven by [D.name] ([D.ckey])") - msg_admin_attack("[D.name] ([D.ckey])[isAntag(D) ? "(ANTAG)" : ""] ran over [H.name] ([H.ckey]). (JMP)") + attack_log += text("\[[time_stamp()]\] ran over [key_name(H)], driven by [key_name(D)]") + msg_admin_attack("[key_name_admin(D)] ran over [key_name_admin(H)]") else - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey])") + attack_log += text("\[[time_stamp()]\] ran over [key_name(H)]") //------------------------------------------- From c92e224c34b752a60788d32410cd96aac4f2fc6d Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 17:28:39 +0200 Subject: [PATCH 18/30] ERT backpack update --- code/game/response_team.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 03efff51ffe..09871374089 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -251,7 +251,7 @@ var/send_emergency_team if("Engineer") engineer_slots -= 1 M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/engineer(M), slot_w_uniform) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/engineer(M), slot_back) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full/multitool(M), slot_belt) @@ -275,7 +275,7 @@ var/send_emergency_team if("Security") security_slots -= 1 M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security(M), slot_w_uniform) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/security(M), slot_back) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/security/response_team(M), slot_belt) @@ -299,7 +299,7 @@ var/send_emergency_team if("Medic") medical_slots -= 1 M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(M), slot_w_uniform) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/medical(M), slot_back) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack) var/obj/item/weapon/card/id/W = new(src) @@ -321,7 +321,7 @@ var/send_emergency_team if("Commander") command_slots = 0 M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/captain(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/commander(M), slot_back) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack) var/obj/item/weapon/card/id/W = new(src) From 1e5d0ef4c801405d7ccd463cc8bc9164c1e845af Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 17:31:49 +0200 Subject: [PATCH 19/30] Fix compile --- code/modules/mob/mob_helpers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 31f1c84e09c..ce8ef0c8cdb 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -182,7 +182,7 @@ proc/isNonCrewAntag(A) var/mob/living/carbon/C = A var/special_role = C.mind.special_role var/list/crew_roles = list("traitor", "Changeling", "Vampire", "Cultist", "Head Revolutionary", "Revolutionary", "malfunctioning AI", "Shadowling", "loyalist", "mutineer", "Response Team") - if((special_role in allowed_roles)) + if((special_role in crew_roles)) return 0 return 1 From 5205f550859cc909bedd2db15bcc8eaa0c6edf4e Mon Sep 17 00:00:00 2001 From: DZD Date: Thu, 20 Aug 2015 11:42:09 -0400 Subject: [PATCH 20/30] Shadowling dethrall fix Should fix thralls not getting their spells removed upon dethralling. --- code/game/gamemodes/shadowling/shadowling.dm | 6 +++--- .../special_shadowling_abilities.dm | 20 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 8ce55e77526..421582d26a1 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -152,9 +152,9 @@ Made by Xhuis update_shadow_icons_added(new_thrall_mind) new_thrall_mind.current.attack_log += "\[[time_stamp()]\] Became a thrall" new_thrall_mind.current.add_language("Shadowling Hivemind") - new_thrall_mind.current.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_glare) - new_thrall_mind.current.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_shadow_walk) - //new_thrall_mind.current.AddSpell(new /obj/effect/proc_holder/spell/targeted/thrall_vision) //Uncomment when vision code is unfucked. + new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_glare) + new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_shadow_walk) + //new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/thrall_vision) //Uncomment when vision code is unfucked. new_thrall_mind.current << "You see the truth. Reality has been torn away and you realize what a fool you've been." new_thrall_mind.current << "The shadowlings are your masters. Serve them above all else and ensure they complete their goals." new_thrall_mind.current << "You may not harm other thralls or the shadowlings. However, you do not need to obey other thralls." diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 46d05fa38a9..1566e3b254b 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -91,11 +91,11 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N sleep(10) H << "Your powers are awoken. You may now live to your fullest extent. Remember your goal. Cooperate with your thralls and allies." H.mind.remove_spell(/obj/effect/proc_holder/spell/targeted/shadowling_hatch) - H.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare) - H.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/veil) - H.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_walk) - H.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/flashfreeze) - H.AddSpell(new /obj/effect/proc_holder/spell/targeted/collective_mind) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/veil) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_walk) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/flashfreeze) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/collective_mind) /obj/effect/proc_holder/spell/targeted/shadowling_ascend name = "Ascend" @@ -156,11 +156,11 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N H.mind.transfer_to(A) A.name = H.real_name A.languages = H.languages - A.AddSpell(new /obj/effect/proc_holder/spell/targeted/annihilate) - A.AddSpell(new /obj/effect/proc_holder/spell/targeted/hypnosis) - A.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_phase_shift) - A.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/ascendant_storm) - A.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowlingAscendantTransmit) + A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/annihilate) + A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/hypnosis) + A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_phase_shift) + A.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/ascendant_storm) + A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowlingAscendantTransmit) if(A.real_name) A.real_name = H.real_name H.invisibility = 60 //This is pretty bad, but is also necessary for the shuttle call to function properly From 59a86e57114bdd166176022125785973a4d88272 Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 18:47:19 +0200 Subject: [PATCH 21/30] Make nuclear bomb use wires datum --- code/datums/wires/nuclearbomb.dm | 60 +++++ code/game/gamemodes/nuclear/nuclearbomb.dm | 272 ++++++++------------- nano/templates/nuclear_bomb.tmpl | 121 ++++----- paradise.dme | 1 + 4 files changed, 211 insertions(+), 243 deletions(-) create mode 100644 code/datums/wires/nuclearbomb.dm diff --git a/code/datums/wires/nuclearbomb.dm b/code/datums/wires/nuclearbomb.dm new file mode 100644 index 00000000000..45485c6f272 --- /dev/null +++ b/code/datums/wires/nuclearbomb.dm @@ -0,0 +1,60 @@ +/datum/wires/nuclearbomb + holder_type = /obj/machinery/nuclearbomb + random = 1 + wire_count = 7 + +var/const/NUCLEARBOMB_WIRE_LIGHT = 1 +var/const/NUCLEARBOMB_WIRE_TIMING = 2 +var/const/NUCLEARBOMB_WIRE_SAFETY = 4 + +/datum/wires/nuclearbomb/CanUse(var/mob/living/L) + var/obj/machinery/nuclearbomb/N = holder + if(N.panel_open) + return 1 + return 0 + +/datum/wires/nuclearbomb/GetInteractWindow() + var/obj/machinery/nuclearbomb/N = holder + . += ..() + . += "
The device is [N.timing ? "shaking!" : "still."]
" + . += "The device is is [N.safety ? "quiet" : "whirring"].
" + . += "The lights are [N.lighthack ? "static" : "functional"].
" + +/datum/wires/nuclearbomb/UpdatePulsed(var/index) + var/obj/machinery/nuclearbomb/N = holder + switch(index) + if(NUCLEARBOMB_WIRE_LIGHT) + N.lighthack = !N.lighthack + spawn(100) + N.lighthack = !N.lighthack + if(NUCLEARBOMB_WIRE_TIMING) + if(N.timing) + spawn + N.explode() + if(NUCLEARBOMB_WIRE_SAFETY) + N.safety = !N.safety + spawn(100) + N.safety = !N.safety + if(N.safety == 1) + N.visible_message("\blue The [N] quiets down.") + if(!N.lighthack) + if (N.icon_state == "nuclearbomb2") + N.icon_state = "nuclearbomb1" + else + N.visible_message("\blue The [N] emits a quiet whirling noise!") + +/datum/wires/nuclearbomb/UpdateCut(var/index, var/mended) + var/obj/machinery/nuclearbomb/N = holder + switch(index) + if(NUCLEARBOMB_WIRE_SAFETY) + if(N.timing) + spawn + N.explode() + if(NUCLEARBOMB_WIRE_TIMING) + if(!N.lighthack) + if (N.icon_state == "nuclearbomb2") + N.icon_state = "nuclearbomb1" + N.timing = 0 + bomb_set = 0 + if(NUCLEARBOMB_WIRE_LIGHT) + N.lighthack = !N.lighthack diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index faf3f353c16..a23d3c61d2e 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -9,7 +9,6 @@ var/bomb_set var/deployable = 0.0 var/extended = 0.0 var/lighthack = 0 - var/opened = 0.0 var/timeleft = 120.0 var/timing = 0.0 var/r_code = "ADMIN" @@ -17,15 +16,12 @@ var/bomb_set var/yes_code = 0.0 var/safety = 1.0 var/obj/item/weapon/disk/nuclear/auth = null - var/list/wires = list() - var/light_wire - var/safety_wire - var/timing_wire var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open, 3 is sealant open, 4 is unwrenched, 5 is removed from bolts. var/lastentered var/is_syndicate = 0 use_power = 0 unacidable = 1 + var/datum/wires/nuclearbomb/wires = null /obj/machinery/nuclearbomb/syndicate is_syndicate = 1 @@ -33,23 +29,14 @@ var/bomb_set /obj/machinery/nuclearbomb/New() ..() r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn. - src.wires["Red"] = 0 - src.wires["Blue"] = 0 - src.wires["Green"] = 0 - src.wires["Marigold"] = 0 - src.wires["Fuschia"] = 0 - src.wires["Black"] = 0 - src.wires["Pearl"] = 0 - var/list/w = list("Red","Blue","Green","Marigold","Black","Fuschia","Pearl") - src.light_wire = pick(w) - w -= src.light_wire - src.timing_wire = pick(w) - w -= src.timing_wire - src.safety_wire = pick(w) - w -= src.safety_wire - + wires = new/datum/wires/nuclearbomb(src) + +/obj/machinery/nuclearbomb/Destroy() + qdel(wires) + return ..() + /obj/machinery/nuclearbomb/process() - if (src.timing) + if (timing) bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed. timeleft = max(timeleft - 2, 0) // 2 seconds per process() if (timeleft <= 0) @@ -60,40 +47,38 @@ var/bomb_set /obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob, params) if (istype(O, /obj/item/weapon/screwdriver)) - src.add_fingerprint(user) - if (src.auth) - if (src.opened == 0) - src.opened = 1 + add_fingerprint(user) + if (auth) + if (panel_open == 0) + panel_open = 1 overlays += image(icon, "npanel_open") user << "You unscrew the control panel of [src]." else - src.opened = 0 + panel_open = 0 overlays -= image(icon, "npanel_open") user << "You screw the control panel of [src] back on." else - if (src.opened == 0) + if (panel_open == 0) user << "[src] emits a buzzing noise, the panel staying locked in." - if (src.opened == 1) - src.opened = 0 + if (panel_open == 1) + panel_open = 0 overlays -= image(icon, "npanel_open") user << "You screw the control panel of [src] back on." flick("nuclearbombc", src) - ui_interact(user) return - if (istype(O, /obj/item/device/multitool) || istype(O, /obj/item/weapon/wirecutters)) - ui_interact(user) + if (panel_open && (istype(O, /obj/item/device/multitool) || istype(O, /obj/item/weapon/wirecutters))) + return attack_hand(user) - if (src.extended) + if (extended) if (istype(O, /obj/item/weapon/disk/nuclear)) usr.drop_item() O.loc = src - src.auth = O - src.add_fingerprint(user) - ui_interact(user) - return + auth = O + add_fingerprint(user) + return attack_hand(user) - if (src.anchored) + if (anchored) switch(removal_stage) if(0) if(istype(O,/obj/item/weapon/weldingtool)) @@ -163,73 +148,56 @@ var/bomb_set ..() /obj/machinery/nuclearbomb/attack_ghost(mob/user as mob) - ui_interact(user) + attack_hand(user) /obj/machinery/nuclearbomb/attack_hand(mob/user as mob) - if (src.extended) - if (src.opened) + if (extended) + if (panel_open) + wires.Interact(user) + else ui_interact(user) - else if (src.deployable) + else if (deployable) if(removal_stage < 5) - src.anchored = 1 + anchored = 1 visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring!") else visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") - if(!src.lighthack) + if(!lighthack) flick("nuclearbombc", src) - src.icon_state = "nuclearbomb1" - src.extended = 1 + icon_state = "nuclearbomb1" + extended = 1 return /obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) var/data[0] - var/uiwidth - var/uiheight - var/uititle data["is_syndicate"] = is_syndicate - if(!src.opened) - data["hacking"] = 0 - data["auth"] = is_auth(user) - if (is_auth(user)) - if (src.yes_code) - data["authstatus"] = src.timing ? "Functional/Set" : "Functional" - else - data["authstatus"] = "Auth. S2" + data["hacking"] = 0 + data["auth"] = is_auth(user) + if (is_auth(user)) + if (yes_code) + data["authstatus"] = timing ? "Functional/Set" : "Functional" else - if (src.timing) - data["authstatus"] = "Set" - else - data["authstatus"] = "Auth. S1" - data["safe"] = src.safety ? "Safe" : "Engaged" - data["time"] = src.timeleft - data["timer"] = src.timing - data["safety"] = src.safety - data["anchored"] = src.anchored - data["yescode"] = src.yes_code - data["message"] = "AUTH" - if (is_auth(user)) - data["message"] = src.code - if (src.yes_code) - data["message"] = "*****" - uiwidth = 300 - uiheight = 510 - uititle = "Nuke Control Panel" + data["authstatus"] = "Auth. S2" else - data["hacking"] = 1 - var/list/tempwires[0] - for(var/wire in src.wires) - tempwires.Add(list(list("name" = wire, "cut" = src.wires[wire]))) - data["wires"] = tempwires - data["timing"] = src.timing - data["safety"] = src.safety - data["lighthack"] = src.lighthack - uiwidth = 420 - uiheight = 440 - uititle = "Nuclear Bomb Defusion" + if (timing) + data["authstatus"] = "Set" + else + data["authstatus"] = "Auth. S1" + data["safe"] = safety ? "Safe" : "Engaged" + data["time"] = timeleft + data["timer"] = timing + data["safety"] = safety + data["anchored"] = anchored + data["yescode"] = yes_code + data["message"] = "AUTH" + if (is_auth(user)) + data["message"] = code + if (yes_code) + data["message"] = "*****" ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) - ui = new(user, src, ui_key, "nuclear_bomb.tmpl", uititle, uiwidth, uiheight) + ui = new(user, src, ui_key, "nuclear_bomb.tmpl", "Nuke Control Panel", 300, 510) ui.set_initial_data(data) ui.open() ui.set_auto_update(1) @@ -242,12 +210,12 @@ var/bomb_set if(usr.stat || !usr.canmove || usr.restrained()) return - if (src.deployable) + if (deployable) usr << "\red You close several panels to make [src] undeployable." - src.deployable = 0 + deployable = 0 else usr << "\red You adjust some panels to make [src] deployable." - src.deployable = 1 + deployable = 1 return /obj/machinery/nuclearbomb/proc/is_auth(user as mob) @@ -262,73 +230,29 @@ var/bomb_set if(..()) return 1 - if(href_list["act"]) - var/temp_wire = href_list["wire"] - if(href_list["act"] == "pulse") - if (!istype(usr.get_active_hand(), /obj/item/device/multitool)) - usr << "You need a multitool!" - else - if(src.wires[temp_wire]) - usr << "You can't pulse a cut wire." - else - if(src.light_wire == temp_wire) - src.lighthack = !src.lighthack - spawn(100) src.lighthack = !src.lighthack - if(src.timing_wire == temp_wire) - if(src.timing) - spawn - explode() - if(src.safety_wire == temp_wire) - src.safety = !src.safety - spawn(100) src.safety = !src.safety - if(src.safety == 1) - visible_message("\blue The [src] quiets down.") - if(!src.lighthack) - if (src.icon_state == "nuclearbomb2") - src.icon_state = "nuclearbomb1" - else - visible_message("\blue The [src] emits a quiet whirling noise!") - if(href_list["act"] == "wire") - if (!istype(usr.get_active_hand(), /obj/item/weapon/wirecutters)) - usr << "You need wirecutters!" - else - wires[temp_wire] = !wires[temp_wire] - if(src.safety_wire == temp_wire) - if(src.timing) - spawn - explode() - if(src.timing_wire == temp_wire) - if(!src.lighthack) - if (src.icon_state == "nuclearbomb2") - src.icon_state = "nuclearbomb1" - src.timing = 0 - bomb_set = 0 - if(src.light_wire == temp_wire) - src.lighthack = !src.lighthack - if (href_list["auth"]) - if (src.auth) - src.auth.loc = src.loc - src.yes_code = 0 - src.auth = null + if (auth) + auth.loc = loc + yes_code = 0 + auth = null else var/obj/item/I = usr.get_active_hand() if (istype(I, /obj/item/weapon/disk/nuclear)) usr.drop_item() I.loc = src - src.auth = I + auth = I if (is_auth(usr)) if (href_list["type"]) if (href_list["type"] == "E") - if (src.code == src.r_code) - src.yes_code = 1 - src.code = null + if (code == r_code) + yes_code = 1 + code = null else - src.code = "ERROR" + code = "ERROR" else if (href_list["type"] == "R") - src.yes_code = 0 - src.code = null + yes_code = 0 + code = null else lastentered = text("[]", href_list["type"]) if (text2num(lastentered) == null) @@ -336,48 +260,48 @@ var/bomb_set message_admins("[key_name_admin(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]! ([LOC ? "JMP" : "null"])", 0) log_admin("EXPLOIT: [key_name(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]!") else - src.code += lastentered - if (length(src.code) > 5) - src.code = "ERROR" - if (src.yes_code) + code += lastentered + if (length(code) > 5) + code = "ERROR" + if (yes_code) if (href_list["time"]) var/time = text2num(href_list["time"]) - src.timeleft += time - src.timeleft = min(max(round(src.timeleft), 120), 600) + timeleft += time + timeleft = min(max(round(src.timeleft), 120), 600) if (href_list["timer"]) - if (src.timing == -1.0) + if (timing == -1.0) nanomanager.update_uis(src) return - if (src.safety) + if (safety) usr << "\red The safety is still on." nanomanager.update_uis(src) return - src.timing = !( src.timing ) - if (src.timing) - if(!src.lighthack) - src.icon_state = "nuclearbomb2" - if(!src.safety) - bomb_set = 1//There can still be issues with this reseting when there are multiple bombs. Not a big deal tho for Nuke/N + timing = !(timing) + if (timing) + if(!lighthack) + icon_state = "nuclearbomb2" + if(!safety) + bomb_set = 1//There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke/N else bomb_set = 0 else bomb_set = 0 - if(!src.lighthack) - src.icon_state = "nuclearbomb1" + if(!lighthack) + icon_state = "nuclearbomb1" if (href_list["safety"]) - src.safety = !( src.safety ) + safety = !(safety) if(safety) - src.timing = 0 + timing = 0 bomb_set = 0 if (href_list["anchor"]) if(removal_stage == 5) - src.anchored = 0 + anchored = 0 visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") nanomanager.update_uis(src) return - src.anchored = !( src.anchored ) - if(src.anchored) + anchored = !(anchored) + if(anchored) visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.") else visible_message("\red The anchoring bolts slide back into the depths of [src].") @@ -388,7 +312,7 @@ var/bomb_set return /obj/machinery/nuclearbomb/blob_act() - if (src.timing == -1.0) + if (timing == -1.0) return else return ..() @@ -396,14 +320,14 @@ var/bomb_set #define NUKERANGE 80 /obj/machinery/nuclearbomb/proc/explode() - if (src.safety) - src.timing = 0 + if (safety) + timing = 0 return - src.timing = -1.0 - src.yes_code = 0 - src.safety = 1 - if(!src.lighthack) - src.icon_state = "nuclearbomb3" + timing = -1.0 + yes_code = 0 + safety = 1 + if(!lighthack) + icon_state = "nuclearbomb3" playsound(src,'sound/machines/Alarm.ogg',100,0,5) if (ticker && ticker.mode) ticker.mode.explosion_in_progress = 1 diff --git a/nano/templates/nuclear_bomb.tmpl b/nano/templates/nuclear_bomb.tmpl index 087e3efb640..0eb68e9bd8e 100644 --- a/nano/templates/nuclear_bomb.tmpl +++ b/nano/templates/nuclear_bomb.tmpl @@ -5,84 +5,67 @@ Used In File(s): \code\game\gamemodes\nuclear\nuclearbomb.dm {{if data.is_syndicate}} {{:helper.syndicateMode()}} {{/if}} -{{if !data.hacking}} +
+ Authorization Disk: {{if data.auth}}{{:helper.link('++++++++++', 'eject', {'auth' : 1})}} {{else}} {{:helper.link('----------', 'disk', {'auth' : 1})}}{{/if}} +
+
+
+
Status: {{:data.authstatus}} - {{:data.safe}}
+
Timer: {{:data.time}}
+
+
- Authorization Disk: {{if data.auth}}{{:helper.link('++++++++++', 'eject', {'auth' : 1})}} {{else}} {{:helper.link('----------', 'disk', {'auth' : 1})}}{{/if}} -
+ {{if data.auth && data.yescode}} +
+ Timer: {{:helper.link('On', 'play', {'timer' : 1}, data.timer ? 'selected' : '')}}{{:helper.link('Off', 'stop', {'timer' : 0}, !data.timer ? 'selected' : '')}} +
+
+ Time: {{:helper.link('--', '', {'time' : -10}, data.time <= 60 ? 'disabled' : '')}}{{:helper.link('-', '', {'time' : -1}, data.time <= 60 ? 'disabled' : '')}} {{:data.time}} {{:helper.link('+', '', {'time' : 1})}}{{:helper.link('++', '', {'time' : 10})}} +
+ {{else}} +
+ Timer: {{:helper.link('On', 'play', null, 'disabled')}}{{:helper.link('Off', 'pause', null, 'disabled')}} +
+
+ Time: {{:helper.link('-', '', null, 'disabled')}}{{:helper.link('-', '', null, 'disabled')}} {{:data.time}} {{:helper.link('+', '', null, 'disabled')}}{{:helper.link('++', '', null, 'disabled')}} +
+ {{/if}} +
+
+ {{if data.auth && data.yescode}} +
+ Safety: {{:helper.link('Engaged', 'info', {'safety' : 1}, data.safety ? 'selected' : '')}}{{:helper.link('Disengaged', 'alert', {'safety' : 0}, data.safety ? '' : 'selected')}} +
+
+ Anchor: {{:helper.link('Engaged', 'locked', {'anchor' : 1}, data.anchored ? 'selected' : '')}}{{:helper.link('Disengaged', 'unlocked', {'anchor' : 0}, data.anchored ? '' : 'selected')}} +
+ {{else}} +
+ Safety: {{:helper.link('Engaged', 'info', null, 'disabled')}}{{:helper.link('Disengaged', 'alert', null, 'disabled')}} +
+
+ Anchor: {{:helper.link('Engaged', 'locked', null, 'disabled')}}{{:helper.link('Disengaged', 'unlocked', null, 'disabled')}} +
+ {{/if}} +

+
+
-
Status: {{:data.authstatus}} - {{:data.safe}}
-
Timer: {{:data.time}}
+ >{{if data.message}} {{:data.message}}{{/if}}
- {{if data.auth && data.yescode}} -
- Timer: {{:helper.link('On', 'play', {'timer' : 1}, data.timer ? 'selected' : '')}}{{:helper.link('Off', 'stop', {'timer' : 0}, !data.timer ? 'selected' : '')}} -
-
- Time: {{:helper.link('--', '', {'time' : -10}, data.time <= 60 ? 'disabled' : '')}}{{:helper.link('-', '', {'time' : -1}, data.time <= 60 ? 'disabled' : '')}} {{:data.time}} {{:helper.link('+', '', {'time' : 1})}}{{:helper.link('++', '', {'time' : 10})}} -
- {{else}} -
- Timer: {{:helper.link('On', 'play', null, 'disabled')}}{{:helper.link('Off', 'pause', null, 'disabled')}} -
-
- Time: {{:helper.link('-', '', null, 'disabled')}}{{:helper.link('-', '', null, 'disabled')}} {{:data.time}} {{:helper.link('+', '', null, 'disabled')}}{{:helper.link('++', '', null, 'disabled')}} -
- {{/if}} + {{:helper.link('1', '', {'type' : 1})}}{{:helper.link('2', '', {'type' : 2})}}{{:helper.link('3', '', {'type' : 3})}}
- {{if data.auth && data.yescode}} -
- Safety: {{:helper.link('Engaged', 'info', {'safety' : 1}, data.safety ? 'selected' : '')}}{{:helper.link('Disengaged', 'alert', {'safety' : 0}, data.safety ? '' : 'selected')}} -
-
- Anchor: {{:helper.link('Engaged', 'locked', {'anchor' : 1}, data.anchored ? 'selected' : '')}}{{:helper.link('Disengaged', 'unlocked', {'anchor' : 0}, data.anchored ? '' : 'selected')}} -
- {{else}} -
- Safety: {{:helper.link('Engaged', 'info', null, 'disabled')}}{{:helper.link('Disengaged', 'alert', null, 'disabled')}} -
-
- Anchor: {{:helper.link('Engaged', 'locked', null, 'disabled')}}{{:helper.link('Disengaged', 'unlocked', null, 'disabled')}} -
- {{/if}} -
-
-
-
-
- >{{if data.message}} {{:data.message}}{{/if}} + {{:helper.link('4', '', {'type' : 4})}}{{:helper.link('5', '', {'type' : 5})}}{{:helper.link('6', '', {'type' : 6})}}
-
- {{:helper.link('1', '', {'type' : 1})}}{{:helper.link('2', '', {'type' : 2})}}{{:helper.link('3', '', {'type' : 3})}} -
-
- {{:helper.link('4', '', {'type' : 4})}}{{:helper.link('5', '', {'type' : 5})}}{{:helper.link('6', '', {'type' : 6})}} -
-
- {{:helper.link('7', '', {'type' : 7})}}{{:helper.link('8', '', {'type' : 8})}}{{:helper.link('9', '', {'type' : 9})}} -
-
- {{:helper.link('R', '', {'type' : 'R'})}}{{:helper.link('0', '', {'type' : 0})}}{{:helper.link('E', '', {'type' : 'E'})}} -
+ {{:helper.link('7', '', {'type' : 7})}}{{:helper.link('8', '', {'type' : 8})}}{{:helper.link('9', '', {'type' : 9})}} +
+
+ {{:helper.link('R', '', {'type' : 'R'})}}{{:helper.link('0', '', {'type' : 0})}}{{:helper.link('E', '', {'type' : 'E'})}}
-{{else}} -
-

Exposed Wires

- {{for data.wires}} -
-
{{:value.name}}
-
{{:helper.link(value.cut ? 'Mend' : 'Cut', '', {'wire' : value.name, 'act' : 'wire'})}} {{:helper.link('Pulse', '', {'wire' : value.name, 'act' : 'pulse'})}}
-
- {{/for}} -
-
- The device is {{if data.timing}}shaking!{{else}}still.{{/if}}
- The device is {{if data.safety}}quiet.{{else}}whirring.{{/if}}
- The lights are {{if data.lighthack}}static.{{else}}functional.{{/if}}
-
-{{/if}} \ No newline at end of file +
\ No newline at end of file diff --git a/paradise.dme b/paradise.dme index 2126b1b0b21..a6a115cd804 100644 --- a/paradise.dme +++ b/paradise.dme @@ -225,6 +225,7 @@ #include "code\datums\wires\camera.dm" #include "code\datums\wires\explosive.dm" #include "code\datums\wires\mulebot.dm" +#include "code\datums\wires\nuclearbomb.dm" #include "code\datums\wires\particle_accelerator.dm" #include "code\datums\wires\radio.dm" #include "code\datums\wires\robot.dm" From 4bd4452086f2bd17a57aee89727bfa6b0d9d02a6 Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 19:21:46 +0200 Subject: [PATCH 22/30] More nuke updates --- code/datums/wires/nuclearbomb.dm | 3 ++ code/game/gamemodes/nuclear/nuclearbomb.dm | 36 ++++++++++++++-------- nano/templates/nuclear_bomb.tmpl | 2 +- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/code/datums/wires/nuclearbomb.dm b/code/datums/wires/nuclearbomb.dm index 45485c6f272..47cce60e349 100644 --- a/code/datums/wires/nuclearbomb.dm +++ b/code/datums/wires/nuclearbomb.dm @@ -30,12 +30,14 @@ var/const/NUCLEARBOMB_WIRE_SAFETY = 4 if(NUCLEARBOMB_WIRE_TIMING) if(N.timing) spawn + message_admins("[key_name_admin(usr)] pulsed a nuclear bomb's detonation wire, causing it to explode (JMP)") N.explode() if(NUCLEARBOMB_WIRE_SAFETY) N.safety = !N.safety spawn(100) N.safety = !N.safety if(N.safety == 1) + set_security_level(N.previous_level) N.visible_message("\blue The [N] quiets down.") if(!N.lighthack) if (N.icon_state == "nuclearbomb2") @@ -49,6 +51,7 @@ var/const/NUCLEARBOMB_WIRE_SAFETY = 4 if(NUCLEARBOMB_WIRE_SAFETY) if(N.timing) spawn + message_admins("[key_name_admin(usr)] cut a nuclear bomb's timing wire, causing it to explode (JMP)") N.explode() if(NUCLEARBOMB_WIRE_TIMING) if(!N.lighthack) diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index a23d3c61d2e..4566c9d9d8f 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -6,21 +6,22 @@ var/bomb_set icon = 'icons/obj/stationobjs.dmi' icon_state = "nuclearbomb0" density = 1 - var/deployable = 0.0 - var/extended = 0.0 + var/deployable = 0 + var/extended = 0 var/lighthack = 0 - var/timeleft = 120.0 - var/timing = 0.0 + var/timeleft = 120 + var/timing = 0 var/r_code = "ADMIN" var/code = "" - var/yes_code = 0.0 - var/safety = 1.0 + var/yes_code = 0 + var/safety = 1 var/obj/item/weapon/disk/nuclear/auth = null var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open, 3 is sealant open, 4 is unwrenched, 5 is removed from bolts. var/lastentered var/is_syndicate = 0 use_power = 0 unacidable = 1 + var/previous_level = "" var/datum/wires/nuclearbomb/wires = null /obj/machinery/nuclearbomb/syndicate @@ -30,6 +31,7 @@ var/bomb_set ..() r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn. wires = new/datum/wires/nuclearbomb(src) + previous_level = get_security_level() /obj/machinery/nuclearbomb/Destroy() qdel(wires) @@ -53,10 +55,12 @@ var/bomb_set panel_open = 1 overlays += image(icon, "npanel_open") user << "You unscrew the control panel of [src]." + playsound(src, 'sound/items/Screwdriver.ogg', 50, 1) else panel_open = 0 overlays -= image(icon, "npanel_open") user << "You screw the control panel of [src] back on." + playsound(src, 'sound/items/Screwdriver.ogg', 50, 1) else if (panel_open == 0) user << "[src] emits a buzzing noise, the panel staying locked in." @@ -64,6 +68,7 @@ var/bomb_set panel_open = 0 overlays -= image(icon, "npanel_open") user << "You screw the control panel of [src] back on." + playsound(src, 'sound/items/Screwdriver.ogg', 50, 1) flick("nuclearbombc", src) return @@ -281,16 +286,20 @@ var/bomb_set if(!lighthack) icon_state = "nuclearbomb2" if(!safety) - bomb_set = 1//There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke/N + message_admins("[key_name_admin(usr)] engaged a nuclear bomb (JMP)") + set_security_level("delta") + bomb_set = 1 //There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke/N else bomb_set = 0 else + set_security_level(previous_level) bomb_set = 0 if(!lighthack) icon_state = "nuclearbomb1" if (href_list["safety"]) safety = !(safety) if(safety) + set_security_level(previous_level) timing = 0 bomb_set = 0 if (href_list["anchor"]) @@ -299,12 +308,15 @@ var/bomb_set visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") nanomanager.update_uis(src) return - - anchored = !(anchored) - if(anchored) - visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.") + + if(!isinspace()) + anchored = !(anchored) + if(anchored) + visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.") + else + visible_message("\red The anchoring bolts slide back into the depths of [src].") else - visible_message("\red The anchoring bolts slide back into the depths of [src].") + usr << "There is nothing to anchor to!" nanomanager.update_uis(src) diff --git a/nano/templates/nuclear_bomb.tmpl b/nano/templates/nuclear_bomb.tmpl index 0eb68e9bd8e..3536d17713f 100644 --- a/nano/templates/nuclear_bomb.tmpl +++ b/nano/templates/nuclear_bomb.tmpl @@ -20,7 +20,7 @@ Used In File(s): \code\game\gamemodes\nuclear\nuclearbomb.dm Timer: {{:helper.link('On', 'play', {'timer' : 1}, data.timer ? 'selected' : '')}}{{:helper.link('Off', 'stop', {'timer' : 0}, !data.timer ? 'selected' : '')}}
- Time: {{:helper.link('--', '', {'time' : -10}, data.time <= 60 ? 'disabled' : '')}}{{:helper.link('-', '', {'time' : -1}, data.time <= 60 ? 'disabled' : '')}} {{:data.time}} {{:helper.link('+', '', {'time' : 1})}}{{:helper.link('++', '', {'time' : 10})}} + Time: {{:helper.link('--', '', {'time' : -10}, data.time <= 120 ? 'disabled' : '')}}{{:helper.link('-', '', {'time' : -1}, data.time <= 120 ? 'disabled' : '')}} {{:data.time}} {{:helper.link('+', '', {'time' : 1})}}{{:helper.link('++', '', {'time' : 10})}}
{{else}}
From 93e320c64818261710a7da682be31f1d6aebb63c Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 19:33:35 +0200 Subject: [PATCH 23/30] Add mob sprites to ERT backpacks --- code/modules/admin/verbs/debug.dm | 4 ++-- icons/mob/back.dmi | Bin 73885 -> 76663 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index eb6b02cc626..1673171ceec 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -922,7 +922,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert/alt(M), slot_l_ear) M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert(M), slot_back) var/obj/item/weapon/card/id/W = new(M) W.name = "[M.real_name]'s ID Card (Emergency Response Team - Member)" @@ -944,7 +944,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert/alt(M), slot_l_ear) M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/commander(M), slot_back) var/obj/item/weapon/card/id/W = new(M) W.name = "[M.real_name]'s ID Card (Emergency Response Team - Leader)" diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 8773d2552482822f371bf8327146b04578b73398..a4c6dd0e843364e2c1fdcea4af15e3b45c22f156 100644 GIT binary patch literal 76663 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 Date: Thu, 20 Aug 2015 20:58:54 +0200 Subject: [PATCH 24/30] dsay fix --- code/modules/mob/mob_helpers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index ce8ef0c8cdb..7108ddc42b4 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -492,7 +492,7 @@ var/list/intents = list("help","disarm","grab","harm") name = realname for(var/mob/M in player_list) - if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || check_rights(R_MOD,0)) && (M.client.prefs.toggles & CHAT_DEAD)) + if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || check_rights(R_MOD,0,M)) && (M.client.prefs.toggles & CHAT_DEAD)) var/follow var/lname if(subject) From eb2d2b6df9cdd8778de1b4ba6ba6902686be8342 Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 21:13:17 +0200 Subject: [PATCH 25/30] Another dsay fix --- code/modules/mob/mob_helpers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 7108ddc42b4..e64ec58e553 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -503,7 +503,7 @@ var/list/intents = list("help","disarm","grab","harm") var/mob/dead/observer/DM if(istype(subject, /mob/dead/observer)) DM = subject - if(check_rights(R_MOD,0)) // What admins see + if(check_rights(R_MOD,0,M)) // What admins see lname = "[keyname][(DM && DM.anonsay) ? "*" : (DM ? "" : "^")] ([name])" else if(DM && DM.anonsay) // If the person is actually observer they have the option to be anonymous From 175bea62cacf9edf395bc55f346385d5a71a0572 Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 21:25:07 +0200 Subject: [PATCH 26/30] only change alert level on non-syndi nukes --- code/datums/wires/nuclearbomb.dm | 3 ++- code/game/gamemodes/nuclear/nuclearbomb.dm | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/datums/wires/nuclearbomb.dm b/code/datums/wires/nuclearbomb.dm index 47cce60e349..e260a90a02c 100644 --- a/code/datums/wires/nuclearbomb.dm +++ b/code/datums/wires/nuclearbomb.dm @@ -37,7 +37,8 @@ var/const/NUCLEARBOMB_WIRE_SAFETY = 4 spawn(100) N.safety = !N.safety if(N.safety == 1) - set_security_level(N.previous_level) + if(!is_syndicate) + set_security_level(N.previous_level) N.visible_message("\blue The [N] quiets down.") if(!N.lighthack) if (N.icon_state == "nuclearbomb2") diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 4566c9d9d8f..0850f6ad46b 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -287,19 +287,22 @@ var/bomb_set icon_state = "nuclearbomb2" if(!safety) message_admins("[key_name_admin(usr)] engaged a nuclear bomb (JMP)") - set_security_level("delta") + if(!is_syndicate) + set_security_level("delta") bomb_set = 1 //There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke/N else bomb_set = 0 else - set_security_level(previous_level) + if(!is_syndicate) + set_security_level(previous_level) bomb_set = 0 if(!lighthack) icon_state = "nuclearbomb1" if (href_list["safety"]) safety = !(safety) if(safety) - set_security_level(previous_level) + if(!is_syndicate) + set_security_level(previous_level) timing = 0 bomb_set = 0 if (href_list["anchor"]) From f6c8358fa2aa0e4adb14789e0e172638c621d17a Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 20 Aug 2015 21:57:41 +0200 Subject: [PATCH 27/30] Fix reference to nuke --- code/datums/wires/nuclearbomb.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/wires/nuclearbomb.dm b/code/datums/wires/nuclearbomb.dm index e260a90a02c..0e28c23fb91 100644 --- a/code/datums/wires/nuclearbomb.dm +++ b/code/datums/wires/nuclearbomb.dm @@ -37,7 +37,7 @@ var/const/NUCLEARBOMB_WIRE_SAFETY = 4 spawn(100) N.safety = !N.safety if(N.safety == 1) - if(!is_syndicate) + if(!N.is_syndicate) set_security_level(N.previous_level) N.visible_message("\blue The [N] quiets down.") if(!N.lighthack) From 8d691a2944d5db39a4f5ecbb2515a1829663b539 Mon Sep 17 00:00:00 2001 From: Spacemanspark Date: Thu, 20 Aug 2015 16:17:38 -0500 Subject: [PATCH 28/30] Making TullyBBurnalot happy (AKA the dumbest grammar PR ever.) Tully is a nerd. --- code/modules/events/mass_hallucination.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index b3fbea5343c..c1778e060bc 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -3,4 +3,4 @@ if(!(C.species.flags & IS_SYNTHETIC)) C.hallucination += rand(50, 100) /datum/event/mass_hallucination/announce() - command_announcement.Announce("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") \ No newline at end of file + command_announcement.Announce("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucinations, but no further damage") From 481b13b32e01094d3a48a69a9ce94a27735b251c Mon Sep 17 00:00:00 2001 From: Alex6511 Date: Thu, 20 Aug 2015 19:46:05 -0400 Subject: [PATCH 29/30] Update event_container.dm --- code/modules/events/event_container.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index f7924a83ed7..b1fa2acbed2 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -157,7 +157,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ion_storm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 20, list(ASSIGNMENT_SECURITY = 20), 1), + //new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 20, list(ASSIGNMENT_SECURITY = 20), 1), new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 15), 1), //new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), 1), // NON-BAY EVENTS From 45f6e2d34a0eb4285d1beaaf4f7ad5461b047956 Mon Sep 17 00:00:00 2001 From: Alex6511 Date: Thu, 20 Aug 2015 19:48:02 -0400 Subject: [PATCH 30/30] Update event_container.dm --- code/modules/events/event_container.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index b1fa2acbed2..f7924a83ed7 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -157,7 +157,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ion_storm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)), - //new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 20, list(ASSIGNMENT_SECURITY = 20), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 20, list(ASSIGNMENT_SECURITY = 20), 1), new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 15), 1), //new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), 1), // NON-BAY EVENTS