From fb600f9bce4a94f0bf42f852d0877be0988c7d1e Mon Sep 17 00:00:00 2001 From: "elly1989@rocketmail.com" Date: Sun, 5 Aug 2012 15:29:15 +0000 Subject: [PATCH] Ok, part 1 of this huge mind datum fix. I need to run over the next part again because I've made a lot inconsistencies in it. This is sort of all the misc stuff that got tidied up whilst I was trying to get my head around how everything related to eachother. This part focuses on: -structuring the way silicon mobs initialise upon login (there was some hideous copypasta in Login() and New() which used spawn() to change the order of the calls so it was all jumbled up. I think I've got it sorted now. -Borgs var/real_name was not initialising as "Cyborg". Meaning the name checks were kind of borked. -Ghosts are now deleted at logout if they no longer have a key. This will stop unneeded ghosts being left lying around. It will not delete ghosts with keys assigned (so people can't respawn or anything). Removed all the del(ghost_ref) stuff I could find. Generally movign the key from a ghost should be the last thing you do as the ghost will be deleted by Logout. However I've put it in a spawn() to hopefully avoid coders accisentally using it in a way which causes runtimes. -Fixed clone-plants spawning dud potato-people left, right and centre. They'll now dump seeds if it fails for whatever reason. -Cultist and Rev status are removed at mob/living/silicon/Login() rather than having to be called on a special-case basis everywhere. This may not be necessary when this stuff is finished. -Removed a bunch of : -Commented mob/living/Login() with the rest of the antag-indicator code from cloning.dm and hydroponics.dm for any coders whom feel brave/suicidal to fix the related issues Next on the agenda, replacing mob/var/original_name with datum/mind/var/name to fix the ticker runtimes Then, fixing mind/proc/transfer_to(mob) once and for all. (There are issues with duplicate minds, role updates, inconsistent initialisation etc etc *yawn* There's probably a few obscure bugs in there somewhere. Might want to hold off on the updates for a bit. Coderbus will likely spot them all by the end of the week. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4322 316c924e-a436-60f5-8080-3fe189b3f50e --- .../datums/diseases/robotic_transformation.dm | 5 +- code/datums/helper_datums/tension.dm | 10 +-- code/defines/mob/living/silicon/robot.dm | 5 +- code/defines/procs/global_lists.dm | 14 +-- code/game/gamemodes/blob/blobs/core.dm | 3 +- .../gamemodes/changeling/changeling_powers.dm | 1 - code/game/gamemodes/events.dm | 1 - code/game/gamemodes/events/space_ninja.dm | 6 +- code/game/gamemodes/wizard/spells.dm | 33 ++++--- code/game/jobs/job_controller.dm | 35 ++++---- code/game/machinery/cloning.dm | 89 ++++++++----------- code/game/machinery/hydroponics.dm | 49 ++++------ code/game/magic/cultist/runes.dm | 1 - code/game/objects/items/robot_parts.dm | 28 +++--- code/modules/admin/IsBanned.dm | 2 +- code/modules/admin/verbs/debug.dm | 6 +- code/modules/admin/verbs/randomverbs.dm | 9 +- code/modules/admin/verbs/striketeam.dm | 3 +- code/modules/mob/dead/observer/logout.dm | 5 ++ code/modules/mob/dead/observer/observer.dm | 40 ++++----- code/modules/mob/living/login.dm | 42 ++++++++- code/modules/mob/living/silicon/ai/ai.dm | 2 +- code/modules/mob/living/silicon/login.dm | 5 ++ .../modules/mob/living/silicon/robot/login.dm | 16 +--- .../modules/mob/living/silicon/robot/robot.dm | 83 +++-------------- code/modules/mob/login.dm | 6 +- code/modules/mob/mob_transformation_simple.dm | 9 +- code/modules/mob/new_player/logout.dm | 7 ++ code/modules/mob/new_player/new_player.dm | 14 +-- code/modules/mob/transform_procs.dm | 28 ++---- tgstation.dme | 3 + 31 files changed, 239 insertions(+), 321 deletions(-) create mode 100644 code/modules/mob/dead/observer/logout.dm create mode 100644 code/modules/mob/living/silicon/login.dm create mode 100644 code/modules/mob/new_player/logout.dm diff --git a/code/datums/diseases/robotic_transformation.dm b/code/datums/diseases/robotic_transformation.dm index 34b074e34f4..9648191fb01 100644 --- a/code/datums/diseases/robotic_transformation.dm +++ b/code/datums/diseases/robotic_transformation.dm @@ -57,8 +57,9 @@ gibs(T) src.cure(0) gibbed = 1 - if(!jobban_isbanned(affected_mob, "Cyborg")) - affected_mob:Robotize() + var/mob/living/carbon/human/H = affected_mob + if(istype(H) && !jobban_isbanned(affected_mob, "Cyborg")) + H.Robotize() else affected_mob.death(1) diff --git a/code/datums/helper_datums/tension.dm b/code/datums/helper_datums/tension.dm index e735fa0d28e..af9dbd89d32 100644 --- a/code/datums/helper_datums/tension.dm +++ b/code/datums/helper_datums/tension.dm @@ -453,7 +453,7 @@ var/global/datum/tension/tension_master sleep(300) for(var/mob/dead/observer/G in candidates) - if(!G.client || !G.key) + if(!G.client) candidates.Remove(G) spawn(0) @@ -464,11 +464,8 @@ var/global/datum/tension/tension_master if(!theghost) return 0 var/mob/living/carbon/human/new_character=makeBody(theghost) - del(theghost) new_character.mind.make_Wizard() - - return 1 // Has to return one before it knows if there's a wizard to prevent the parent from automatically selecting another game mode. @@ -536,7 +533,7 @@ var/global/datum/tension/tension_master sleep(300) for(var/mob/dead/observer/G in candidates) - if(!G.client || !G.key) + if(!G.client) candidates.Remove(G) spawn(0) @@ -551,7 +548,6 @@ var/global/datum/tension/tension_master if(!theghost) break var/mob/living/carbon/human/new_character=makeBody(theghost) - del(theghost) new_character.mind.make_Nuke() @@ -674,7 +670,6 @@ var/global/datum/tension/tension_master new_syndicate_commando.key = theghost.key new_syndicate_commando.internal = new_syndicate_commando.s_store new_syndicate_commando.internals.icon_state = "internal1" - del(theghost) //So they don't forget their code or mission. @@ -748,7 +743,6 @@ var/global/datum/tension/tension_master new_borg_deathsquad.mind.key = theghost.key//For mind stuff. new_borg_deathsquad.key = theghost.key - del(theghost) //So they don't forget their code or mission. diff --git a/code/defines/mob/living/silicon/robot.dm b/code/defines/mob/living/silicon/robot.dm index 343832b9426..8cdd9e7a379 100644 --- a/code/defines/mob/living/silicon/robot.dm +++ b/code/defines/mob/living/silicon/robot.dm @@ -1,9 +1,12 @@ /mob/living/silicon/robot name = "Cyborg" + real_name = "Cyborg" icon = 'icons/mob/robots.dmi'// icon_state = "robot" maxHealth = 300 health = 300 + var/started = null//A fix to ensure people don't try to bypass law assignment. Initial assignment sets it to one but it check on login whether they have been initiated -Sieve + #define BORGMESON 1 #define BORGTHERM 2 @@ -41,7 +44,7 @@ //var/list/laws = list() var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list()) var/viewalerts = 0 - var/modtype = null + var/modtype = "robot" var/lower_mod = 0 var/jetpack = 0 var/datum/effect/effect/system/ion_trail_follow/ion_trail = null diff --git a/code/defines/procs/global_lists.dm b/code/defines/procs/global_lists.dm index 315277b131e..7d036593855 100644 --- a/code/defines/procs/global_lists.dm +++ b/code/defines/procs/global_lists.dm @@ -1,13 +1,13 @@ //Since it didn't really belong in any other category, I'm putting this here //This is for procs to replace all the goddamn 'in world's that are chilling around the code -var/global/list/player_list = list()//List of all logged in players (Based on mob reference) -var/global/list/admin_list = list()//List of all logged in admins (Based on mob reference) -var/global/list/mob_list = list()//List of all mobs, including clientless -var/global/list/living_mob_list = list()//List of all living mobs, including clientless -var/global/list/dead_mob_list = list()//List of all dead mobs, including clientless -var/global/list/client_list = list()//List of all clients, based on ckey -var/global/list/cable_list = list()//Index for all cables, so that powernets don't have to look through the entire world all the time +var/global/list/player_list = list() //List of all logged in players (Based on mob reference) +var/global/list/admin_list = list() //List of all logged in admins (Based on mob reference) +var/global/list/mob_list = list() //List of all mobs, including clientless +var/global/list/living_mob_list = list() //List of all living mobs, including clientless +var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless +var/global/list/client_list = list() //List of all clients, based on ckey +var/global/list/cable_list = list() //Index for all cables, so that powernets don't have to look through the entire world all the time var/global/list/hair_styles_list = list() //stores /datum/sprite_accessory/hair indexed by name var/global/list/facial_hair_styles_list = list() //stores /datum/sprite_accessory/facial_hair indexed by name var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index ed62e4dd4d6..7b84bdc3d31 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -55,8 +55,7 @@ if(G.client) G.client.screen.len = null B.ghost_name = G.real_name - G.client.mob = B - del(G) + B.key = G.key /* Pulse(var/pulse = 0, var/origin_dir = 0)//Todo: Fix spaceblob expand diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 9b346843e21..027d3dda548 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -495,7 +495,6 @@ new_commando.internal = new_commando.s_store new_commando.internals.icon_state = "internal1" candidates -= G - del(G) else break diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 56f0b772175..846227ff484 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -264,7 +264,6 @@ var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc) new_xeno.mind_initialize(G,"Larva") new_xeno.key = G.key - del(G) vents.Remove(vent) spawncount -= 1 diff --git a/code/game/gamemodes/events/space_ninja.dm b/code/game/gamemodes/events/space_ninja.dm index f849bf77356..6d51f7ac8b4 100644 --- a/code/game/gamemodes/events/space_ninja.dm +++ b/code/game/gamemodes/events/space_ninja.dm @@ -153,7 +153,6 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp new_ninja.wear_suit:randomize_param()//Give them a random set of suit parameters. new_ninja.internal = new_ninja.s_store //So the poor ninja has something to breath when they spawn in spess. new_ninja.internals.icon_state = "internal1" - del(G) else del(new_ninja) return @@ -420,13 +419,13 @@ As such, it's hard-coded for now. No reason for it not to be, really. spawn_list.Add(L) - var/input = input("Pick character to spawn as the Space Ninja", "Key", "") + var/input = ckey(input("Pick character to spawn as the Space Ninja", "Key", "")) if(!input) return var/mob/dead/observer/G for(var/mob/dead/observer/G_find in player_list) - if(ckey(G_find.key)==ckey(input)) + if(G_find.ckey == input) G = G_find break @@ -453,7 +452,6 @@ As such, it's hard-coded for now. No reason for it not to be, really. message_admins("\blue [admin_name] has spawned [new_ninja.key] as a Space Ninja. Hide yo children! \nTheir mission is: [mission]", 1) log_admin("[admin_name] used Spawn Space Ninja.") - del(G) return //=======//NINJA CREATION PROCS//=======// diff --git a/code/game/gamemodes/wizard/spells.dm b/code/game/gamemodes/wizard/spells.dm index 9e233f9d17b..04f6c701fdc 100644 --- a/code/game/gamemodes/wizard/spells.dm +++ b/code/game/gamemodes/wizard/spells.dm @@ -543,20 +543,27 @@ U.whisper("GIN'YU CAPAN") U.verbs -= /mob/proc/swap + //Remove special verbs from both mobs if(U.mind.special_verbs.len) for(var/V in U.mind.special_verbs) U.verbs -= V - - var/mob/dead/observer/G = new /mob/dead/observer(H) //To properly transfer clients so no-one gets kicked off the game. - - H.client.mob = G if(H.mind.special_verbs.len) for(var/V in H.mind.special_verbs) - H.verbs -= V - G.mind = H.mind + H.verbs -= V - U.client.mob = H - H.mind = U.mind + //empty out H + var/mob/dead/observer/G = new /mob/dead/observer(H) //Temp-mob + G.key = H.key //Stops H.key getting kicked + var/datum/mind/temp_mind = H.mind //ghosts shouldn't hold minds + temp_mind.current = null + H.mind = null + + + //Start the Transfer + U.mind.transfer_to(H) + temp_mind.transfer_to(U) + + //Re-add those special verbs and stuff if(H.mind.special_verbs.len) var/spell_loss = 1//Can lose only one spell during transfer. var/probability = 95 //To determine the chance of wizard losing their spell. @@ -573,19 +580,10 @@ spawn(500) H << "The mind transfer has robbed you of a spell." - /* //This code SHOULD work to prevent Mind Swap spam since the spell transfer code above instantly resets it. - //I can't test this code because I can't test mind stuff on my own :x -- Darem. - if(hascall(H, /mob/proc/swap)) - H.verbs -= /mob/proc/swap - */ - G.client.mob = U - U.mind = G.mind if(U.mind.special_verbs.len)//Basic fix to swap verbs for any mob if needed. for(var/V in U.mind.special_verbs) U.verbs += V - U.mind.current = U - H.mind.current = H spawn(500) U << "Something about your body doesn't seem quite right..." @@ -595,7 +593,6 @@ spawn(600) H.verbs += /mob/proc/swap - del(G) else src << "Their mind is not compatible." return diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 2f6d3abfeef..84b36e7e6e0 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -314,26 +314,25 @@ var/global/datum/controller/occupations/job_master if(istype(S, /obj/effect/landmark/start) && istype(S.loc, /turf)) H.loc = S.loc - if(H.mind && H.mind.assigned_role == "Cyborg")//This could likely be done somewhere else - H.Robotize() - return 1 + if(H.mind) + if(H.mind.assigned_role == "Cyborg")//This could likely be done somewhere else + H.Robotize() + return 1 + + if(H.mind.assigned_role != "AI" && H.mind.assigned_role != "Clown") + switch(H.backbag) + if(1) + H.equip_if_possible(new /obj/item/weapon/storage/box/survival(H), H.slot_r_hand) + if(2) + var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack(H) + new /obj/item/weapon/storage/box/survival(BPK) + H.equip_if_possible(BPK, H.slot_back,1) + if(3) + var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack/satchel_norm(H) + new /obj/item/weapon/storage/box/survival(BPK) + H.equip_if_possible(BPK, H.slot_back,1) H.equip_if_possible(new /obj/item/device/radio/headset(H), H.slot_ears) - - if(H.mind && H.mind.assigned_role != "Cyborg" && H.mind.assigned_role != "AI" && H.mind.assigned_role != "Clown") - if(H.backbag == 1) //Clown always gets his backbuddy. - H.equip_if_possible(new /obj/item/weapon/storage/box/survival(H), H.slot_r_hand) - - if(H.backbag == 2) - var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack(H) - new /obj/item/weapon/storage/box/survival(BPK) - H.equip_if_possible(BPK, H.slot_back,1) - - if(H.backbag == 3) - var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack/satchel_norm(H) - new /obj/item/weapon/storage/box/survival(BPK) - H.equip_if_possible(BPK, H.slot_back,1) - H.regenerate_icons() return 1 diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 795b6ca6c6f..5d710b92cdb 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -118,7 +118,7 @@ return 0 var/datum/mind/clonemind = locate(mindref) in ticker.minds - if( !(clonemind && istype(clonemind) && clonemind.current && clonemind.current.stat==DEAD) ) + if( !(istype(clonemind,/datum/mind) && (!clonemind.current || clonemind.current.stat==DEAD)) ) return 0 src.heal_level = rand(75,100) //Randomizes what health the clone is when ejected @@ -130,76 +130,63 @@ spawn(30) src.eject_wait = 0 - src.occupant = new /mob/living/carbon/human(src) - - occupant:UI = UI // set interface preference - - ghost.client.mob = src.occupant - src.occupant.hud_used = new/obj/hud( src.occupant ) - // probably redundant because previous line calls mob/Login() which does this line of code - // but until this is proven useless keep it for safety - Doohl - - src.icon_state = "pod_1" - //Get the clone body ready - src.occupant.adjustCloneLoss(190) //new damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite - src.occupant.adjustBrainLoss(heal_level) - src.occupant.Paralyse(4) - - //Here let's calculate their health so the pod doesn't immediately eject them!!! - src.occupant.health = (src.occupant.getBruteLoss() + src.occupant.getToxLoss() + src.occupant.getOxyLoss() + src.occupant.getCloneLoss()) - - src.occupant << "\blue Clone generation process initiated." - src.occupant << "\blue This will take a moment, please hold." + var/mob/living/carbon/human/H = new /mob/living/carbon/human(src) + occupant = H + H.UI = UI // set interface preference if(!clonename) //to prevent null names clonename = "clone ([rand(0,999)])" + H.real_name = clonename + H.original_name = clonename //we don't want random ghost names should we die again. - occupant.real_name = clonename - occupant.original_name = clonename //we don't want random ghost names should we die again. + src.icon_state = "pod_1" + //Get the clone body ready + H.adjustCloneLoss(190) //new damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite + H.adjustBrainLoss(heal_level) + H.Paralyse(4) + + //Here let's calculate their health so the pod doesn't immediately eject them!!! + H.updatehealth() + + clonemind.transfer_to(H) + H << "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like. I wonder what happened to the old me... My memories are kinda fuzzy.
" - clonemind.transfer_to(src.occupant) - clonemind.original = src.occupant // -- Mode/mind specific stuff goes here switch(ticker.mode.name) if("revolution") - if(src.occupant.mind in ticker.mode:revolutionaries) - ticker.mode:update_all_rev_icons() //So the icon actually appears - if(src.occupant.mind in ticker.mode:head_revolutionaries) - ticker.mode:update_all_rev_icons() + if((H.mind in ticker.mode:revolutionaries) || (H.mind in ticker.mode:head_revolutionaries)) + ticker.mode.update_all_rev_icons() //So the icon actually appears if("nuclear emergency") - if (src.occupant.mind in ticker.mode:syndicates) - ticker.mode:update_all_synd_icons() + if(H.mind in ticker.mode.syndicates) + ticker.mode.update_all_synd_icons() if("cult") - if (src.occupant.mind in ticker.mode:cult) - ticker.mode:add_cultist(src.occupant.mind) - ticker.mode:update_all_cult_icons() //So the icon actually appears + if (H.mind in ticker.mode.cult) + ticker.mode.add_cultist(src.occupant.mind) + ticker.mode.update_all_cult_icons() //So the icon actually appears - if (changelingClone && occupant.mind in ticker.mode.changelings) - occupant.changeling = changelingClone - src.occupant.make_changeling() + if (changelingClone && H.mind in ticker.mode.changelings) + H.changeling = changelingClone + H.make_changeling() // -- End mode specific stuff - if(istype(ghost, /mob/dead/observer)) - del(ghost) //Don't leave ghosts everywhere!! - - if(!src.occupant.dna) - src.occupant.dna = new /datum/dna( ) + if(!H.dna) + H.dna = new /datum/dna() if(ui) - src.occupant.dna.uni_identity = ui - updateappearance(src.occupant, ui) + H.dna.uni_identity = ui + updateappearance(H, ui) if(se) - src.occupant.dna.struc_enzymes = se - randmutb(src.occupant) //Sometimes the clones come out wrong. + H.dna.struc_enzymes = se + randmutb(H) //Sometimes the clones come out wrong. - src.occupant:f_style = "Shaved" - src.occupant:h_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") + H.f_style = "Shaved" + H.h_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") - src.occupant:mutantrace = mrace - src.occupant:update_mutantrace() - src.occupant:suiciding = 0 + H.mutantrace = mrace + H.update_mutantrace() + H.suiciding = 0 src.attempting = 0 return 1 diff --git a/code/game/machinery/hydroponics.dm b/code/game/machinery/hydroponics.dm index 6ca5c9d626f..b8db3d6e082 100644 --- a/code/game/machinery/hydroponics.dm +++ b/code/game/machinery/hydroponics.dm @@ -875,32 +875,24 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob) /obj/item/seeds/replicapod/harvest(mob/user = usr) //now that one is fun -- Urist var/obj/machinery/hydroponics/parent = loc - - if(ckey && config.revival_pod_plants) //if there's human data stored in it, make a human - var/mob/ghost = find_dead_player("[ckey]") - + var/make_podman = 0 + var/mob/ghost + if(ckey && config.revival_pod_plants) + ghost = find_dead_player("[ckey]") + if(ismob(ghost)) + if(istype(mind,/datum/mind)) + if(!mind.current || mind.current == DEAD) + make_podman = 1 + if(make_podman) //all conditions met! var/mob/living/carbon/human/podman = new /mob/living/carbon/human(parent.loc) - if(ghost) - ghost.client.mob = podman - - if (realName) + if(realName) podman.real_name = realName - podman.original_name = realName //don't want a random ghost name if we die again else - podman.real_name = "pod person" //No null names!! - - if(mind && istype(mind,/datum/mind) && mind.current && mind.current.stat == 2) //only transfer dead people's minds - mind:transfer_to(podman) - mind:original = podman - else //welp - podman.mind = new /datum/mind( ) - podman.mind.key = podman.key - podman.mind.current = podman - podman.mind.original = podman - podman.mind.transfer_to(podman) - ticker.minds += podman.mind - - // -- Mode/mind specific stuff goes here + podman.real_name = "Pod Person [rand(0,999)]" + podman.original_name = podman.real_name + + mind.transfer_to(podman) + // -- Mode/mind specific stuff goes here. TODO! Broken :( Should be merged into mob/living/Login switch(ticker.mode.name) if ("revolution") if (podman.mind in ticker.mode:revolutionaries) @@ -921,18 +913,15 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob) // -- End mode specific stuff - if(ghost) - if (istype(ghost, /mob/dead/observer)) - del(ghost) //Don't leave ghosts everywhere!! podman.gender = gender - if (!podman.dna) - podman.dna = new /datum/dna( ) - if (ui) + if(!podman.dna) + podman.dna = new /datum/dna() + if(ui) podman.dna.uni_identity = ui updateappearance(podman, ui) - if (se) + if(se) podman.dna.struc_enzymes = se if(!prob(potency)) //if it fails, plantman! podman.mutantrace = "plant" diff --git a/code/game/magic/cultist/runes.dm b/code/game/magic/cultist/runes.dm index 2d37e9d5987..81675f5556a 100644 --- a/code/game/magic/cultist/runes.dm +++ b/code/game/magic/cultist/runes.dm @@ -270,7 +270,6 @@ var/list/sacrificed = list() corpse_to_raise.mind.original = corpse_to_raise corpse_to_raise.mind.key = ghost.key corpse_to_raise.key = ghost.key - del(ghost) for(var/datum/organ/external/affecting in corpse_to_raise.organs) affecting.heal_damage(1000, 1000) corpse_to_raise.setToxLoss(0) diff --git a/code/game/objects/items/robot_parts.dm b/code/game/objects/items/robot_parts.dm index c7cb9726d91..359f1bb5883 100644 --- a/code/game/objects/items/robot_parts.dm +++ b/code/game/objects/items/robot_parts.dm @@ -165,7 +165,17 @@ if(!M.brainmob) user << "\red Sticking an empty MMI into the frame would sort of defeat the purpose." return - if(M.brainmob.stat == 2) + if(!M.brainmob.key) + var/ghost_can_reenter = 0 + for(var/mob/dead/observer/G in dead_mob_list) + if(G.corpse == M.brainmob) + ghost_can_reenter = 1 + break + if(!ghost_can_reenter) + user << "The mmi indicates that their mind is completely unresponsive; there's no point." + return + + if(M.brainmob.stat == DEAD) user << "\red Sticking a dead brain into the frame would sort of defeat the purpose." return @@ -186,28 +196,14 @@ O.name = created_name O.real_name = created_name - if (M.brainmob && M.brainmob.mind) - M.brainmob.mind.transfer_to(O) - else - for(var/mob/dead/observer/G in player_list) - if(G.corpse == M.brainmob && G.corpse.mind) - G.corpse.mind.transfer_to(O) - del(G) - break + M.brainmob.mind.transfer_to(O) - if(O.mind) - ticker.mode.remove_cultist(O.mind, 1) - ticker.mode.remove_revolutionary(O.mind, 1) if(O.mind && O.mind.special_role) O.mind.store_memory("In case you look at this after being borged, the objectives are only here until I find a way to make them not show up for you, as I can't simply delete them without screwing up round-end reporting. --NeoFite") - //O << "You are playing a Cyborg. The Cyborg can interact with most electronic objects in its view point." - //O << "You must follow the laws that the AI has. You must follow orders the AI gives you." - //O << "To use something, simply click on it." - //O << {"Use say ":s to speak to fellow cyborgs and the AI through binary."} O.job = "Cyborg" diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index e70fa4b6662..a3321b1655e 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -7,7 +7,7 @@ world/IsBanned(key,address,computer_id) if( !guests_allowed && IsGuestKey(key) ) log_access("Failed Login: [key] - Guests not allowed") message_admins("\blue Failed Login: [key] - Guests not allowed") - return list("reason"="guest", "desc"="\nReason: Guests not allowed.brb") + return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.") //check if the IP address is a known TOR node if( config && config.ToRban && ToRban_isbanned(address) ) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 3abb7fbf7a6..e16a3ec7614 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -396,10 +396,10 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that if(alert("This mob is being controlled by [M.ckey]. Are you sure you wish to assume control of it? [M.ckey] will be made a ghost.",,"Yes","No") != "Yes") return else - var/mob/dead/observer/ghost = new/mob/dead/observer() - ghost.ckey = M.ckey; + var/mob/dead/observer/ghost = new/mob/dead/observer(M,1) + ghost.ckey = M.ckey var/mob/adminmob = src.mob - M.ckey = src.ckey; + M.ckey = src.ckey if( isobserver(adminmob) ) del(adminmob) feedback_add_details("admin_verb","ADC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 7388d8e2414..efc8790f174 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -238,11 +238,11 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0) var/mob/living/carbon/alien/humanoid/new_xeno switch(alien_caste) if("Hunter") - new_xeno = new /mob/living/carbon/alien/humanoid/hunter (spawn_here) + new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here) if("Sentinel") - new_xeno = new /mob/living/carbon/alien/humanoid/sentinel (spawn_here) + new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here) if("Drone") - new_xeno = new /mob/living/carbon/alien/humanoid/drone (spawn_here) + new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here) else return 0 @@ -269,7 +269,6 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0) else//We won't be reporting duds. del(new_xeno) - del(G) return 1 alert("There are no available ghosts to throw into the xeno. Aborting command.") @@ -294,7 +293,7 @@ Traitors and the like can also be revived with the previous role mostly intact. var/mob/dead/observer/G_found for(var/mob/dead/observer/G in player_list) - if(G.client&&ckey(G.key)==ckey(input)) + if(G.client&&G.ckey==ckey(input)) G_found = G break diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index 30ce8900448..a1cb4069802 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -74,12 +74,11 @@ var/global/sent_strike_team = 0 if(commandos_list.len) G = pick(commandos_list) + commandos_list -= G new_commando.mind.key = G.key//For mind stuff. new_commando.key = G.key new_commando.internal = new_commando.s_store new_commando.internals.icon_state = "internal1" - commandos_list -= G - del(G) //So they don't forget their code or mission. if(nuke_code) diff --git a/code/modules/mob/dead/observer/logout.dm b/code/modules/mob/dead/observer/logout.dm new file mode 100644 index 00000000000..cf51df634eb --- /dev/null +++ b/code/modules/mob/dead/observer/logout.dm @@ -0,0 +1,5 @@ +/mob/dead/observer/Logout() + ..() + spawn(0) + if(src && !key) //we've transferred to another mob. This ghost should be deleted. + del(src) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 7e87196f222..a507c431086 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -8,28 +8,28 @@ dead_mob_list += src add_to_mob_list(src) - if(body) - var/turf/T = get_turf(body) //Where is the body located? - if(!T) T = pick(latejoin) //Safety in case we cannot find the body's position - loc = T - if(ismob(body)) - if(body.original_name) - original_name = body.original_name - else - if(body.real_name) - original_name = body.real_name - else - original_name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + var/turf/T + if(ismob(body)) + T = get_turf(body) //Where is the body located? + attack_log = body.attack_log //preserve our attack logs by copying them to our ghost + + if(body.original_name) + original_name = body.original_name + else if(body.real_name) - real_name = body.real_name + original_name = body.real_name else - real_name = original_name + original_name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) - name = original_name + name = original_name + + if(can_reenter_corpse) + corpse = body + + if(!T) T = pick(latejoin) //Safety in case we cannot find the body's position + loc = T - if(can_reenter_corpse) - corpse = body if(!name) //To prevent nameless ghosts name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) real_name = name @@ -46,7 +46,6 @@ Works together with spawning an observer, noted above. /mob/proc/ghostize(var/can_reenter_corpse = 1) if(key) var/mob/dead/observer/ghost = new(src,can_reenter_corpse) //Transfer safety to observer spawning proc. - ghost.attack_log = attack_log //preserve our attack logs by copying them to our ghost ghost.key = key return @@ -137,11 +136,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp corpse.ajourn=0 if(corpse.key) //makes sure we don't accidentally kick any clients usr << "Another consciousness is in your body...It is resisting you." - return + return corpse.key = key - remove_from_mob_list(src) - dead_mob_list -= src - del(src) /mob/dead/observer/proc/dead_tele() set category = "Ghost" diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index a60280bd606..5ff6c825df3 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -1,12 +1,46 @@ /mob/living/Login() + ticker.minds |= mind //failsafe whilst I track down all the inconsistencies ~Carn. ..() if(ticker && ticker.mode) switch(ticker.mode.name) if("sandbox") CanBuild() if("revolution") - if ((src.mind in ticker.mode:revolutionaries) || (src.mind in ticker.mode:head_revolutionaries)) - ticker.mode:update_rev_icons_added(src.mind) + if((mind in ticker.mode.revolutionaries) || (src.mind in ticker.mode:head_revolutionaries)) + ticker.mode.update_rev_icons_added(src.mind) if("cult") - if (src.mind in ticker.mode:cult) - ticker.mode:update_cult_icons_added(src.mind) \ No newline at end of file + if(mind in ticker.mode:cult) + ticker.mode.update_cult_icons_added(src.mind) + +//This stuff needs to be merged from cloning.dm but I'm not in the mood to be shouted at for breaking all the things :< ~Carn + /* clones + switch(ticker.mode.name) + if("revolution") + if(src.occupant.mind in ticker.mode:revolutionaries) + ticker.mode:update_all_rev_icons() //So the icon actually appears + if(src.occupant.mind in ticker.mode:head_revolutionaries) + ticker.mode:update_all_rev_icons() + if("nuclear emergency") + if (src.occupant.mind in ticker.mode:syndicates) + ticker.mode:update_all_synd_icons() + if("cult") + if (src.occupant.mind in ticker.mode:cult) + ticker.mode:add_cultist(src.occupant.mind) + ticker.mode:update_all_cult_icons() //So the icon actually appears + */ + + /* Plantpeople + switch(ticker.mode.name) + if("revolution") + if(src.occupant.mind in ticker.mode:revolutionaries) + ticker.mode:update_all_rev_icons() //So the icon actually appears + if(src.occupant.mind in ticker.mode:head_revolutionaries) + ticker.mode:update_all_rev_icons() + if("nuclear emergency") + if (src.occupant.mind in ticker.mode:syndicates) + ticker.mode:update_all_synd_icons() + if("cult") + if (src.occupant.mind in ticker.mode:cult) + ticker.mode:add_cultist(src.occupant.mind) + ticker.mode:update_all_cult_icons() //So the icon actually appears + */ \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 7914e24c1e8..f5e22848686 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -11,10 +11,10 @@ real_name = pickedName name = real_name - original_name = real_name anchored = 1 canmove = 0 loc = loc + holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1")) proc_holder_list = new() diff --git a/code/modules/mob/living/silicon/login.dm b/code/modules/mob/living/silicon/login.dm new file mode 100644 index 00000000000..32e0c8d3460 --- /dev/null +++ b/code/modules/mob/living/silicon/login.dm @@ -0,0 +1,5 @@ +/mob/living/silicon/Login() + if(mind && ticker && ticker.mode) + ticker.mode.remove_cultist(mind, 1) + ticker.mode.remove_revolutionary(mind, 1) + ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm index 6b70330957f..a9c48732103 100644 --- a/code/modules/mob/living/silicon/robot/login.dm +++ b/code/modules/mob/living/silicon/robot/login.dm @@ -2,22 +2,10 @@ ..() regenerate_icons() - if(real_name == "Cyborg") - ident = rand(1, 999) - real_name += " " - real_name += "-[ident]" - name = real_name - /*if(!connected_ai) - for(var/mob/living/silicon/ai/A in world) - connected_ai = A - A.connected_robots += src - break - */ if(!started) if(!syndie) - if (client) - connected_ai = activeais() - if (connected_ai) + connected_ai = activeais() + if(connected_ai) connected_ai.connected_robots += src // laws = connected_ai.laws //The borg inherits its AI's laws laws = new /datum/ai_laws diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 3affde53b92..6ab19ab7274 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1,64 +1,17 @@ -/mob/living/silicon/robot - var/started = null//A fix to ensure people don't try to bypass law assignment. Initial assignment sets it to one but it check on login whether they have been initiated -Sieve - /mob/living/silicon/robot/New(loc,var/syndie = 0) spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, src) spark_system.attach(src) - spawn (1) - src << "\blue Your icons have been generated!" - playsound(loc, 'liveagain.ogg', 50, 1, -3) - modtype = "robot" - updateicon() -// syndicate = syndie - if(real_name == "Cyborg") - ident = rand(1, 999) - real_name += "-[ident]" - name = real_name - src << "You are playing a Cyborg. You can move around and remotely interact with the machines around you." - src << "You can use things such as computers, APCs, intercoms, doors, etc. To use something, simply click on it." - src << "As a new Cyborg you can choose your class. Each class have different modules that help them perform their duties." - src << "Remember that you have a limited charge and the more modules you have active the more power you will drain." - src << "Finally, you are loyal to your linked AI. You should obey all orders of the linked AI as long as it does not conflict with your laws." - src << "Use say :b to speak to your fellow machines through binary." - spawn (4) - if(!syndie) - if (client) - connected_ai = activeais() - if (connected_ai) - connected_ai.connected_robots += src - // laws = connected_ai.laws //The borg inherits its AI's laws - laws = new /datum/ai_laws - lawsync() - src << "Unit slaved to [connected_ai.name], downloading laws." - lawupdate = 1 - else - laws = new /datum/ai_laws/asimov - lawupdate = 0 - src << "Unable to locate an AI, reverting to standard Asimov laws." - else - laws = new /datum/ai_laws/antimov - lawupdate = 0 - scrambledcodes = 1 - src << "Follow your laws." - cell.maxcharge = 25000 - cell.charge = 25000 - module = new /obj/item/weapon/robot_module/syndicate(src) - hands.icon_state = "standard" - icon_state = "secborg" - modtype = "Synd" + if(real_name == "Cyborg") + ident = rand(1, 999) + real_name += "-[ident]" + name = real_name - radio = new /obj/item/device/radio/borg(src) - if(!scrambledcodes) - camera = new /obj/machinery/camera(src) - camera.c_tag = real_name - camera.network = "SS13" if(!cell) var/obj/item/weapon/cell/C = new(src) C.charge = 1500 cell = C - started = 1 ..() //If there's an MMI in the robot, have it ejected when the mob goes away. --NEO @@ -67,26 +20,18 @@ if(mmi)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside. add_to_mob_list(mmi.brainmob) var/turf/T = get_turf(loc)//To hopefully prevent run time errors. - if(T) - mmi.loc = T + if(T) mmi.loc = T - if(!key) //if we don't have an associated key, try to find the ghost of this body - for(var/mob/dead/observer/ghost in player_list) - if(ghost.corpse == src && ghost.client) - ghost.client.mob = ghost.corpse + if(key && !mind) //failsafe in case we've somehow lost our mind! (code will do that to you!) + if(mmi.brainmob.mind) + mind = mmi.brainmob.mind + else + mind = new /datum/mind() + mind.assigned_role = "Cyborg" + mind.key = key - if(key)//If there is a client attached to host. - if(client) - client.screen.len = null - if(mind)//If the cyborg has a mind. It should if it's a player. May not. - mind.transfer_to(mmi.brainmob) - else if(!mmi.brainmob.mind)//If the brainmob has no mind and neither does the cyborg. Shouldn't happen but can due to admun canspiraucy. - mmi.brainmob.mind = new()//Quick mind initialize - mmi.brainmob.mind.current = mmi.brainmob - mmi.brainmob.mind.assigned_role = "Assistant"//Default to an assistant. - mmi.brainmob.key = key - else//If the brain does have a mind. Also shouldn't happen but who knows. - mmi.brainmob.key = key + if(mind) + mind.transfer_to(mmi.brainmob) mmi = null ..() diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 0f2296958ec..d2451c67709 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -26,12 +26,14 @@ player_list |= src update_Login_details() world.update_status() + client.images = null //remove the images such as AIs being unable to see runes client.screen = null //remove hud items just in case - if(!dna) dna = new /datum/dna(null) - if(hud_used) del(hud_used) + if(hud_used) del(hud_used) //remove the hud objects hud_used = new/obj/hud( src ) + if(!dna) dna = new /datum/dna(null) + next_move = 1 sight |= SEE_SELF ..() diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index dc8546a20fd..0e9b0c6a08c 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -22,14 +22,15 @@ usr << "\red cannot convert into a new_player mob type." return - var/mob/M = null - if( !isnull(location) && isturf(location)) + var/mob/M + if(isturf(location)) M = new new_type( location ) else M = new new_type( src.loc ) if(!M || !ismob(M)) usr << "Type path is not a mob (new_type = [new_type]) in change_mob_type(). Contact a coder." + del(M) return if( istext(new_name) ) @@ -44,9 +45,11 @@ M.dna = src.dna M.UI = src.UI - M.ckey = src.ckey + if(mind) mind.transfer_to(M) + else + M.key = key if(delete_old_mob) spawn(1) diff --git a/code/modules/mob/new_player/logout.dm b/code/modules/mob/new_player/logout.dm new file mode 100644 index 00000000000..9f064a99cd5 --- /dev/null +++ b/code/modules/mob/new_player/logout.dm @@ -0,0 +1,7 @@ +/mob/new_player/Logout() + ready = 0 + ..() + if(!spawning)//Here so that if they are spawning and log out, the other procs can play out and they will have a mob to come back to. + key = null//We null their key before deleting the mob, so they are properly kicked out. + del(src) + return \ No newline at end of file diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index acd202e8cf7..a73a031c93d 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -15,14 +15,6 @@ anchored = 1 // don't get pushed around - Logout() - ready = 0 - ..() - if(!spawning)//Here so that if they are spawning and log out, the other procs can play out and they will have a mob to come back to. - key = null//We null their key before deleting the mob, so they are properly kicked out. - del(src) - return - verb/new_player_panel() set src = usr new_player_panel_proc() @@ -147,7 +139,6 @@ preferences.randomize_name() observer.name = preferences.real_name observer.real_name = observer.name - observer.original_name = observer.name //Original name is only used in ghost chat! It is not to be edited by anything! preferences.copy_to_observer(observer) @@ -377,7 +368,7 @@ close_spawn_windows() if(ticker.random_players) - new_character.gender = pick(MALE, MALE, FEMALE) + new_character.gender = pick(MALE, FEMALE) preferences.randomize_name() preferences.randomize_appearance_for(new_character) else @@ -388,9 +379,8 @@ new_character.dna.ready_dna(new_character) new_character.dna.b_type = preferences.b_type if(mind) - mind.transfer_to(new_character) mind.original = new_character - + mind.transfer_to(new_character) return new_character diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 7e181532e71..1b4ef45460f 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -72,7 +72,6 @@ /mob/proc/AIize() if(client) - client.screen.len = null src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jams for AIs var/mob/living/silicon/ai/O = new (loc, /datum/ai_laws/asimov,,1)//No MMI but safety is in effect. O.invisibility = 0 @@ -89,8 +88,7 @@ O.mind.assigned_role = "AI" O.key = key - if(!(O.mind in ticker.minds)) - ticker.minds += O.mind//Adds them to regular mind list. + var/obj/loc_landmark for(var/obj/effect/landmark/start/sloc in world) @@ -164,12 +162,7 @@ invisibility = 101 for(var/t in organs) del(t) - if(client) - //client.screen -= main_hud1.contents - client.screen -= hud_used.contents - client.screen -= hud_used.adding - client.screen -= list( oxygen, throw_icon, i_select, m_select, toxin, internals, fire, hands, healths, pullin, blind, flash, rest, sleep, mach ) - client.screen -= list( zone_sel, oxygen, throw_icon, i_select, m_select, toxin, internals, fire, hands, healths, pullin, blind, flash, rest, sleep, mach ) + var/mob/living/silicon/robot/O = new /mob/living/silicon/robot( loc ) // cyborgs produced by Robotize get an automatic power cell @@ -180,11 +173,9 @@ O.gender = gender O.invisibility = 0 - O.name = "Cyborg" - O.real_name = "Cyborg" + O.UI = UI - if(client) - O.lastKnownIP = client.address ? client.address : null + if (mind) mind.transfer_to(O) if (mind.assigned_role == "Cyborg") @@ -197,23 +188,14 @@ mind.original = O mind.transfer_to(O) - if(!(O.mind in ticker.minds)) - ticker.minds += O.mind//Adds them to regular mind list. + O.loc = loc - //O << "You are playing a Cyborg. A Cyborg can interact with most electronic objects in its view point." - //O << "You must follow the laws that the AI has. You must follow orders the AI gives you." - //O << "To use something, simply click on it." - //O << {"Use say ":s to speak to fellow cyborgs and the AI through binary."} - O.job = "Cyborg" O.mmi = new /obj/item/device/mmi(O) O.mmi.transfer_identity(src)//Does not transfer key/client. - if(O.mind) - ticker.mode.remove_cultist(O.mind, 1) - ticker.mode.remove_revolutionary(O.mind, 1) spawn(0)//To prevent the proc from returning null. del(src) diff --git a/tgstation.dme b/tgstation.dme index b17188df1f2..82b46063a6e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -931,6 +931,7 @@ #include "code\modules\mob\update_icons.dm" #include "code\modules\mob\dead\death.dm" #include "code\modules\mob\dead\observer\hud.dm" +#include "code\modules\mob\dead\observer\logout.dm" #include "code\modules\mob\dead\observer\observer.dm" #include "code\modules\mob\dead\observer\say.dm" #include "code\modules\mob\living\damage_procs.dm" @@ -1014,6 +1015,7 @@ #include "code\modules\mob\living\carbon\monkey\say.dm" #include "code\modules\mob\living\carbon\monkey\update_icons.dm" #include "code\modules\mob\living\silicon\death.dm" +#include "code\modules\mob\living\silicon\login.dm" #include "code\modules\mob\living\silicon\say.dm" #include "code\modules\mob\living\silicon\silicon.dm" #include "code\modules\mob\living\silicon\ai\ai.dm" @@ -1067,6 +1069,7 @@ #include "code\modules\mob\living\simple_animal\worm.dm" #include "code\modules\mob\new_player\hud.dm" #include "code\modules\mob\new_player\login.dm" +#include "code\modules\mob\new_player\logout.dm" #include "code\modules\mob\new_player\new_player.dm" #include "code\modules\mob\new_player\poll.dm" #include "code\modules\mob\new_player\preferences.dm"