diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index e32405cad5..9505248753 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -32,3 +32,5 @@ GLOBAL_LIST_EMPTY(all_languages) GLOBAL_LIST_EMPTY(latejoiners) //CIT CHANGE - All latejoining people, for traitor-target purposes. GLOBAL_LIST_EMPTY(sentient_disease_instances) + +GLOBAL_LIST_EMPTY(latejoin_ai_cores) diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 8e29207fe1..9fae8ac8a8 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -66,18 +66,18 @@ SUBSYSTEM_DEF(job) SetupOccupations() return type_occupations[jobtype] -/datum/controller/subsystem/job/proc/AssignRole(mob/dead/new_player/player, rank, latejoin=0) +/datum/controller/subsystem/job/proc/AssignRole(mob/dead/new_player/player, rank, latejoin = FALSE) Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]") if(player && player.mind && rank) var/datum/job/job = GetJob(rank) if(!job) - return 0 + return FALSE if(jobban_isbanned(player, rank)) - return 0 + return FALSE if(!job.player_old_enough(player.client)) - return 0 + return FALSE if(job.required_playtime_remaining(player.client)) - return 0 + return FALSE var/position_limit = job.total_positions if(!latejoin) position_limit = job.spawn_positions @@ -85,9 +85,9 @@ SUBSYSTEM_DEF(job) player.mind.assigned_role = rank unassigned -= player job.current_positions++ - return 1 + return TRUE Debug("AR has failed, Player: [player], Rank: [rank]") - return 0 + return FALSE /datum/controller/subsystem/job/proc/FindOccupationCandidates(datum/job/job, level, flag) @@ -224,6 +224,8 @@ SUBSYSTEM_DEF(job) if(SSticker.triai) for(var/datum/job/ai/A in occupations) A.spawn_positions = 3 + for(var/obj/effect/landmark/start/ai/secondary/S in GLOB.start_landmarks_list) + S.latejoin_active = TRUE //Get the players who are ready for(var/mob/dead/new_player/player in GLOB.player_list) @@ -359,7 +361,7 @@ SUBSYSTEM_DEF(job) return 1 //Gives the player the stuff he should have with his rank -/datum/controller/subsystem/job/proc/EquipRank(mob/M, rank, joined_late=0) +/datum/controller/subsystem/job/proc/EquipRank(mob/M, rank, joined_late = FALSE) var/mob/dead/new_player/N var/mob/living/H if(!joined_late) @@ -382,6 +384,7 @@ SUBSYSTEM_DEF(job) if(locate(/mob/living) in sloc.loc) continue S = sloc + sloc.used = TRUE break if(length(GLOB.jobspawn_overrides[rank])) S = pick(GLOB.jobspawn_overrides[rank]) @@ -396,9 +399,13 @@ SUBSYSTEM_DEF(job) H.mind.assigned_role = rank if(job) +<<<<<<< HEAD if(!job.dresscodecompliant)// CIT CHANGE - dress code compliance equip_loadout(N, H) // CIT CHANGE - allows players to spawn with loadout items var/new_mob = job.equip(H) +======= + var/new_mob = job.equip(H, null, null, joined_late) +>>>>>>> 0c27e22... Latejoin Silicons (#36560) if(ismob(new_mob)) H = new_mob if(!joined_late) @@ -406,23 +413,28 @@ SUBSYSTEM_DEF(job) else M = H - SSpersistence.antag_rep_change[M.client.ckey] += job.antag_rep + SSpersistence.antag_rep_change[M.client.ckey] += job.antag_rep to_chat(M, "You are the [rank].") - to_chat(M, "As the [rank] you answer directly to [job.supervisors]. Special circumstances may change this.") - to_chat(M, "To speak on your departments radio, use the :h button. To see others, look closely at your headset.") - if(job.req_admin_notify) - to_chat(M, "You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.") - if(CONFIG_GET(number/minimal_access_threshold)) - to_chat(M, "As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.") + if(job) + to_chat(M, "As the [rank] you answer directly to [job.supervisors]. Special circumstances may change this.") + to_chat(M, "To speak on your departments radio, use the :h button. To see others, look closely at your headset.") + if(job.req_admin_notify) + to_chat(M, "You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.") + if(CONFIG_GET(number/minimal_access_threshold)) + to_chat(M, "As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.") if(job && H) +<<<<<<< HEAD if(job.dresscodecompliant)// CIT CHANGE - dress code compliance equip_loadout(N, H) // CIT CHANGE - allows players to spawn with loadout items job.after_spawn(H, M) equip_loadout(N, H, TRUE)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works //handle_roundstart_items(H, M.ckey, H.mind.assigned_role, H.mind.special_role) //CIT CHANGE - makes donators spawn with their items. This can safely be commented out when all of the donator items are migrated to the loadout system +======= + job.after_spawn(H, M, joined_late) +>>>>>>> 0c27e22... Latejoin Silicons (#36560) return H diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 2db34bb897..c734699002 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -323,11 +323,6 @@ SUBSYSTEM_DEF(ticker) mode.post_setup() GLOB.start_state = new /datum/station_state() GLOB.start_state.count() - //Cleanup some stuff - for(var/obj/effect/landmark/start/S in GLOB.landmarks_list) - //Deleting Startpoints but we need the ai point to AI-ize people later - if(S.delete_after_roundstart) - qdel(S) //assign crew objectives and generate miscreants if(CONFIG_GET(flag/allow_extended_miscreants) && GLOB.master_mode == "extended") @@ -341,6 +336,14 @@ SUBSYSTEM_DEF(ticker) send2irc("Server", "Round [GLOB.round_id ? "#[GLOB.round_id]:" : "of"] [hide_mode ? "secret":"[mode.name]"] has started[allmins.len ? ".":" with no active admins online!"]") setup_done = TRUE + for(var/i in GLOB.start_landmarks_list) + var/obj/effect/landmark/start/S = i + if(istype(S)) //we can not runtime here. not in this important of a proc. + S.after_round_start() + else + stack_trace("[S] [S.type] found in start landmarks list, which isn't a start landmark!") + + //These callbacks will fire after roundstart key transfer /datum/controller/subsystem/ticker/proc/OnRoundstart(datum/callback/cb) if(!HasRoundStarted()) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index cb215ab7e4..0b502d4fe6 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -111,7 +111,7 @@ if(current) current.transfer_observers_to(new_character) //transfer anyone observing the old character to the new one current = new_character //associate ourself with our new body - new_character.mind = src //and associate our new body with ourself + new_character.mind = src //and associate our new body with ourself for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body var/datum/antagonist/A = a A.on_body_transfer(old_current, current) @@ -311,7 +311,7 @@ else uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key) var/unlock_note - + if(uplink_loc == R) R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ)) @@ -331,7 +331,7 @@ if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.") unlock_note = "Uplink Degrees: [P.traitor_unlock_degrees] ([P.name])." - + if(uplink_owner) uplink_owner.antag_memory += unlock_note + "
" else diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 8f0bbae4b6..ed88d51c2d 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -35,6 +35,11 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) layer = MOB_LAYER var/jobspawn_override = FALSE var/delete_after_roundstart = TRUE + var/used = FALSE + +/obj/effect/landmark/start/proc/after_round_start() + if(delete_after_roundstart) + qdel(src) /obj/effect/landmark/start/New() GLOB.start_landmarks_list += src @@ -187,12 +192,18 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) icon_state = "AI" delete_after_roundstart = FALSE var/primary_ai = TRUE + var/latejoin_active = TRUE + +/obj/effect/landmark/start/ai/after_round_start() + if(latejoin_active && !used) + new /obj/structure/AIcore/latejoin_inactive(loc) + return ..() /obj/effect/landmark/start/ai/secondary icon = 'icons/effects/landmarks_static.dmi' icon_state = "ai_spawn" primary_ai = FALSE - + latejoin_active = FALSE //Department Security spawns diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 4425dcff6c..a8061f6c2a 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -7,12 +7,14 @@ desc = "The framework for an artificial intelligence core." max_integrity = 500 var/state = 0 - var/datum/ai_laws/laws = new() + var/datum/ai_laws/laws var/obj/item/circuitboard/circuit = null var/obj/item/device/mmi/brain = null + var/can_deconstruct = TRUE -/obj/structure/AIcore/New() - ..() +/obj/structure/AIcore/Initialize() + . = ..() + laws = new laws.set_laws_config() /obj/structure/AIcore/Destroy() @@ -24,11 +26,60 @@ brain = null return ..() +/obj/structure/AIcore/latejoin_inactive + name = "Networked AI core" + desc = "This AI core is connected by bluespace transmitters to NTNet, allowing for an AI personality to be downloaded to it on the fly mid-shift." + can_deconstruct = FALSE + icon_state = "ai-empty" + anchored = TRUE + state = AI_READY_CORE + var/available = TRUE + var/safety_checks = TRUE + var/active = TRUE + +/obj/structure/AIcore/latejoin_inactive/examine(mob/user) + . = ..() + to_chat(user, "Its transmitter seems to be [active? "on" : "off"].") + +/obj/structure/AIcore/latejoin_inactive/proc/is_available() //If people still manage to use this feature to spawn-kill AI latejoins ahelp them. + if(!available) + return FALSE + if(!safety_checks) + return TRUE + if(!active) + return FALSE + var/turf/T = get_turf(src) + var/area/A = get_area(src) + if(!A.blob_allowed) + return FALSE + if(!A.power_equip) + return FALSE + if(!SSmapping.level_trait(T.z,ZTRAIT_STATION)) + return FALSE + if(!istype(T, /turf/open/floor)) + return FALSE + return TRUE + +/obj/structure/AIcore/latejoin_inactive/attackby(obj/item/P, mob/user, params) + if(istype(P, /obj/item/device/multitool)) + active = !active + to_chat(user, "You [active? "activate" : "deactivate"] [src]'s transimtters.") + return + return ..() + +/obj/structure/AIcore/latejoin_inactive/Initialize() + . = ..() + GLOB.latejoin_ai_cores += src + +/obj/structure/AIcore/latejoin_inactive/Destroy() + GLOB.latejoin_ai_cores -= src + return ..() + /obj/structure/AIcore/attackby(obj/item/P, mob/user, params) if(istype(P, /obj/item/wrench)) return default_unfasten_wrench(user, P, 20) if(!anchored) - if(istype(P, /obj/item/weldingtool)) + if(istype(P, /obj/item/weldingtool) && can_deconstruct) if(state != EMPTY_CORE) to_chat(user, "The core must be empty to deconstruct it!") return @@ -259,7 +310,6 @@ That prevents a few funky behaviors. return 0 return 1 - /obj/structure/AIcore/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card) if(state != AI_READY_CORE || !..()) return @@ -275,6 +325,5 @@ That prevents a few funky behaviors. else //If for some reason you use an empty card on an empty AI terminal. to_chat(user, "There is no AI loaded on this terminal!") - /obj/item/circuitboard/aicore name = "AI core (AI Core Board)" //Well, duh, but best to be consistent diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index d1f58dfe7f..3d22385513 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -769,11 +769,7 @@ var/J_totPos = html_encode(job.total_positions) dat += "[J_title]: [J_opPos]/[job.total_positions < 0 ? " (unlimited)" : J_totPos]" - if(job.title == "AI" || job.title == "Cyborg") - dat += " (Cannot Late Join)" - continue - else - dat += "" + dat += "" dat += "" if(job.total_positions >= 0) dat += "Custom | " diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index b4a973220c..c384d21e97 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -53,19 +53,24 @@ //Only override this proc //H is usually a human unless an /equip override transformed it -/datum/job/proc/after_spawn(mob/living/H, mob/M) +/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE) //do actions on H but send messages to M as the key may not have been transferred_yet - /datum/job/proc/announce(mob/living/carbon/human/H) if(head_announce) announce_head(H, head_announce) +/datum/job/proc/override_latejoin_spawn(mob/living/carbon/human/H) //Return TRUE to force latejoining to not automatically place the person in latejoin shuttle/whatever. + return FALSE + +//Used for a special check of whether to allow a client to latejoin as this job. +/datum/job/proc/special_check_latejoin(client/C) + return TRUE //Don't override this unless the job transforms into a non-human (Silicons do this for example) -/datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE) +/datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE, latejoin = FALSE) if(!H) - return 0 + return FALSE if(CONFIG_GET(flag/enforce_human_authority) && (title in GLOB.command_positions)) if(H.dna.species.id != "human") @@ -106,8 +111,8 @@ //If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 /datum/job/proc/player_old_enough(client/C) if(available_in_days(C) == 0) - return 1 //Available in 0 days = available right now = player is old enough to play. - return 0 + return TRUE //Available in 0 days = available right now = player is old enough to play. + return FALSE /datum/job/proc/available_in_days(client/C) @@ -123,7 +128,7 @@ return max(0, minimal_player_age - C.player_age) /datum/job/proc/config_check() - return 1 + return TRUE /datum/job/proc/map_check() return TRUE diff --git a/code/modules/jobs/job_types/silicon.dm b/code/modules/jobs/job_types/silicon.dm index 89a44f8c1b..2080edac50 100644 --- a/code/modules/jobs/job_types/silicon.dm +++ b/code/modules/jobs/job_types/silicon.dm @@ -6,21 +6,35 @@ AI flag = AI_JF department_flag = ENGSEC faction = "Station" - total_positions = 0 + total_positions = 1 spawn_positions = 1 selection_color = "#ccffcc" supervisors = "your laws" - req_admin_notify = 1 + req_admin_notify = TRUE minimal_player_age = 30 exp_requirements = 180 exp_type = EXP_TYPE_CREW antag_rep = 20 + var/do_special_check = TRUE -/datum/job/ai/equip(mob/living/carbon/human/H) - return H.AIize(FALSE) +/datum/job/ai/equip(mob/living/carbon/human/H, visualsOnly, announce, latejoin) + . = H.AIize(latejoin) -/datum/job/ai/after_spawn(mob/living/silicon/ai/AI, mob/M) - AI.rename_self("ai", M.client) +/datum/job/ai/after_spawn(mob/H, mob/M, latejoin) + . = ..() + if(latejoin) + var/obj/structure/AIcore/latejoin_inactive/lateJoinCore + for(var/obj/structure/AIcore/latejoin_inactive/P in GLOB.latejoin_ai_cores) + if(P.is_available()) + lateJoinCore = P + GLOB.latejoin_ai_cores -= P + break + if(lateJoinCore) + lateJoinCore.available = FALSE + H.forceMove(lateJoinCore.loc) + qdel(lateJoinCore) + var/mob/living/silicon/ai/AI = H + AI.rename_self("ai", M.client) //If this runtimes oh well jobcode is fucked. //we may have been created after our borg if(SSticker.current_state == GAME_STATE_SETTING_UP) @@ -28,6 +42,27 @@ AI if(!R.connected_ai) R.TryConnectToAI() + if(latejoin) + announce(AI) + +/datum/job/ai/override_latejoin_spawn() + return TRUE + +/datum/job/ai/special_check_latejoin(client/C) + if(!do_special_check) + return TRUE + for(var/i in GLOB.latejoin_ai_cores) + var/obj/structure/AIcore/latejoin_inactive/LAI = i + if(istype(LAI)) + if(LAI.is_available()) + return TRUE + return FALSE + +/datum/job/ai/announce(mob/living/silicon/ai/AI) + . = ..() + var/area/A = get_area(AI) + var/turf/T = get_turf(AI) + SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/minor_announce, "[AI] has been downloaded to an empty bluespace-networked AI core at [COORD(T)], [A.name].")) /datum/job/ai/config_check() return CONFIG_GET(flag/allow_ai) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 8930a02036..47677780e9 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -293,8 +293,8 @@ if(JOB_UNAVAILABLE_SLOTFULL) return "[jobtitle] is already filled to capacity." return "Error: Unknown job availability." - -/mob/dead/new_player/proc/IsJobUnavailable(rank) + +/mob/dead/new_player/proc/IsJobUnavailable(rank, latejoin = FALSE) var/datum/job/job = SSjob.GetJob(rank) if(!job) return JOB_UNAVAILABLE_GENERIC @@ -313,6 +313,8 @@ return JOB_UNAVAILABLE_ACCOUNTAGE if(job.required_playtime_remaining(client)) return JOB_UNAVAILABLE_PLAYTIME + if(latejoin && !job.special_check_latejoin(client)) + return JOB_UNAVAILABLE_GENERIC return JOB_AVAILABLE /mob/dead/new_player/proc/AttemptLateSpawn(rank) @@ -343,18 +345,20 @@ SSjob.AssignRole(src, rank, 1) var/mob/living/character = create_character(TRUE) //creates the human and transfers vars and mind - var/equip = SSjob.EquipRank(character, rank, 1) + var/equip = SSjob.EquipRank(character, rank, TRUE) if(isliving(equip)) //Borgs get borged in the equip, so we need to make sure we handle the new mob. character = equip - SSjob.SendToLateJoin(character) + var/datum/job/job = SSjob.GetJob(rank) - if(!arrivals_docked) - var/obj/screen/splash/Spl = new(character.client, TRUE) - Spl.Fade(TRUE) - character.playsound_local(get_turf(character), 'sound/voice/ApproachingTG.ogg', 25) + if(job && !job.override_latejoin_spawn(character)) + SSjob.SendToLateJoin(character) + if(!arrivals_docked) + var/obj/screen/splash/Spl = new(character.client, TRUE) + Spl.Fade(TRUE) + character.playsound_local(get_turf(character), 'sound/voice/ApproachingTG.ogg', 25) - character.update_parallax_teleport() + character.update_parallax_teleport() SSticker.minds += character.mind @@ -395,7 +399,7 @@ if(SSshuttle.emergency.timeLeft(1) > initial(SSshuttle.emergencyCallTime)*0.5) SSticker.mode.make_antag_chance(humanc) - if(CONFIG_GET(flag/roundstart_traits)) + if(humanc && CONFIG_GET(flag/roundstart_traits)) SStraits.AssignTraits(humanc, humanc.client, TRUE) log_manifest(character.mind.key,character.mind,character,latejoin = TRUE) @@ -421,10 +425,9 @@ var/available_job_count = 0 for(var/datum/job/job in SSjob.occupations) - if(job && IsJobUnavailable(job.title) == JOB_AVAILABLE) + if(job && IsJobUnavailable(job.title, TRUE) == JOB_AVAILABLE) available_job_count++; - for(var/datum/job/prioritized_job in SSjob.prioritized_jobs) if(prioritized_job.current_positions >= prioritized_job.total_positions) SSjob.prioritized_jobs -= prioritized_job @@ -444,7 +447,7 @@ dat += "
" var/job_count = 0 for(var/datum/job/job in SSjob.occupations) - if(job && IsJobUnavailable(job.title) == JOB_AVAILABLE) + if(job && IsJobUnavailable(job.title, TRUE) == JOB_AVAILABLE) job_count++; if (job_count > round(available_job_count / 2)) dat += "
" diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index f148ac7fdb..5c030552d3 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -18,7 +18,7 @@ icon_state = "ai" anchored = TRUE density = TRUE - canmove = 0 + canmove = FALSE status_flags = CANSTUN|CANPUSH a_intent = INTENT_HARM //so we always get pushed instead of trying to swap sight = SEE_TURFS | SEE_MOBS | SEE_OBJS @@ -28,7 +28,7 @@ d_hud = DATA_HUD_DIAGNOSTIC_ADVANCED mob_size = MOB_SIZE_LARGE var/list/network = list("ss13") - var/obj/machinery/camera/current = null + var/obj/machinery/camera/current var/list/connected_robots = list() var/aiRestorePowerRoutine = 0 var/requires_power = POWER_REQ_ALL @@ -37,44 +37,44 @@ var/viewalerts = 0 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/radio_enabled = 1 //Determins if a carded AI can speak with its built in radio or not. + var/radio_enabled = TRUE //Determins if a carded AI can speak with its built in radio or not. radiomod = ";" //AIs will, by default, state their laws on the internal radio. - var/obj/item/device/pda/ai/aiPDA = null - var/obj/item/device/multitool/aiMulti = null + var/obj/item/device/pda/ai/aiPDA + var/obj/item/device/multitool/aiMulti var/mob/living/simple_animal/bot/Bot - var/tracking = 0 //this is 1 if the AI is currently tracking somebody, but the track has not yet been completed. + var/tracking = FALSE //this is 1 if the AI is currently tracking somebody, but the track has not yet been completed. var/datum/effect_system/spark_spread/spark_system//So they can initialize sparks whenever/N //MALFUNCTION var/datum/module_picker/malf_picker var/list/datum/AI_Module/current_modules = list() - var/can_dominate_mechs = 0 - var/shunted = 0 //1 if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead + var/can_dominate_mechs = FALSE + var/shunted = FALSE //1 if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead - var/control_disabled = 0 // Set to 1 to stop AI from interacting via Click() - 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, stores a worldtime + cooldown + var/control_disabled = FALSE // Set to 1 to stop AI from interacting via Click() + var/malfhacking = FALSE // 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, stores a worldtime + cooldown - var/obj/machinery/power/apc/malfhack = null - var/explosive = 0 //does the AI explode when it dies? + var/obj/machinery/power/apc/malfhack + var/explosive = FALSE //does the AI explode when it dies? - var/mob/living/silicon/ai/parent = null - var/camera_light_on = 0 + var/mob/living/silicon/ai/parent + var/camera_light_on = FALSE var/list/obj/machinery/camera/lit_cameras = list() - var/datum/trackable/track = new() + var/datum/trackable/track = new var/last_paper_seen = null - var/can_shunt = 1 - var/last_announcement = "" // For AI VOX, if enabled + var/can_shunt = TRUE + var/last_announcement = "" // For AI VOX, if enabled var/turf/waypoint //Holds the turf of the currently selected waypoint. - var/waypoint_mode = 0 //Waypoint mode is for selecting a turf via clicking. - var/call_bot_cooldown = 0 //time of next call bot command - var/apc_override = 0 //hack for letting the AI use its APC even when visionless + var/waypoint_mode = FALSE //Waypoint mode is for selecting a turf via clicking. + var/call_bot_cooldown = 0 //time of next call bot command + var/apc_override = FALSE //hack for letting the AI use its APC even when visionless var/nuking = FALSE var/obj/machinery/doomsday_device/doomsday_device - var/mob/camera/aiEye/eyeobj = new() + var/mob/camera/aiEye/eyeobj = new var/sprint = 10 var/cooldown = 0 var/acceleration = 1