diff --git a/_maps/map_files/RandomZLevels/spacehotel.dmm b/_maps/map_files/RandomZLevels/spacehotel.dmm
index 73d86c17201..56df786fab5 100644
--- a/_maps/map_files/RandomZLevels/spacehotel.dmm
+++ b/_maps/map_files/RandomZLevels/spacehotel.dmm
@@ -3125,7 +3125,6 @@
},
/area/awaymission/spacehotel/kitchen)
"gE" = (
-/mob/living/carbon/human/interactive/away/hotel/chef,
/turf/unsimulated/floor{
icon_state = "cafeteria"
},
@@ -3278,7 +3277,6 @@
},
/area/awaymission/spacehotel)
"ha" = (
-/mob/living/carbon/human/interactive/away/hotel/bartender,
/turf/unsimulated/floor{
icon_state = "whiteyellowfull"
},
@@ -4135,9 +4133,6 @@
/turf/unsimulated/floor/carpet,
/area/awaymission/spacehotel)
"jm" = (
-/obj/effect/spawner/snpc_squad{
- squad_type = /mob/living/carbon/human/interactive/away/hotel/guard
- },
/turf/unsimulated/floor/carpet,
/area/awaymission/spacehotel)
"jn" = (
@@ -4489,7 +4484,6 @@
/obj/structure/chair{
dir = 8
},
-/mob/living/carbon/human/interactive/away/hotel/concierge,
/turf/unsimulated/floor/carpet,
/area/awaymission/spacehotel/reception)
"kk" = (
diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index ba4bf0090c7..a8c6b4bd5e8 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -52,12 +52,6 @@
#define GRAB_UPGRADING 4
#define GRAB_KILL 5
-
-//Hostile Mob AI Status
-#define AI_ON 1
-#define AI_IDLE 2
-#define AI_OFF 3
-
//Attack types for checking shields/hit reactions
#define MELEE_ATTACK 1
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 0f05c08b2f7..284b0e4d745 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -94,6 +94,13 @@
#define APPEARANCE_ALL_BODY APPEARANCE_ALL_HAIR|APPEARANCE_HEAD_ACCESSORY|APPEARANCE_MARKINGS|APPEARANCE_BODY_ACCESSORY|APPEARANCE_ALT_HEAD
#define APPEARANCE_ALL 32767
+//If you add a new status, be sure to add a list for it to the simple_animals global in _globalvars/lists/mobs.dm
+//Hostile Mob AI Status
+#define AI_ON 1
+#define AI_IDLE 2
+#define AI_OFF 3
+#define AI_Z_OFF 4
+
// Intents
#define INTENT_HELP "help"
#define INTENT_DISARM "disarm"
diff --git a/code/__DEFINES/snpc.dm b/code/__DEFINES/snpc.dm
deleted file mode 100644
index 8d4768005cd..00000000000
--- a/code/__DEFINES/snpc.dm
+++ /dev/null
@@ -1,23 +0,0 @@
-#define SNPC_MAX_RANGE_FIND 32
-#define SNPC_MIN_RANGE_FIND 16
-#define SNPC_FUZZY_CHANCE_HIGH 85
-#define SNPC_FUZZY_CHANCE_LOW 50
-#define SNPC_CHANCE_TALK 15
-
-#define SNPC_BRUTE 1
-#define SNPC_STEALTH 2
-#define SNPC_MARTYR 3
-#define SNPC_PSYCHO 4
-
-#define SNPC_INTERACTING 2
-#define SNPC_TRAVEL 4
-#define SNPC_FIGHTING 8
-#define SNPC_SPECIAL 16
-
-#define TRAIT_ROBUST 2
-#define TRAIT_UNROBUST 4
-#define TRAIT_SMART 8
-#define TRAIT_DUMB 16
-#define TRAIT_MEAN 32
-#define TRAIT_FRIENDLY 64
-#define TRAIT_THIEVING 128
\ No newline at end of file
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index 551b729028e..b6fcae25061 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -22,8 +22,7 @@ GLOBAL_LIST_INIT(living_mob_list, list()) //List of all alive mobs, including
GLOBAL_LIST_INIT(dead_mob_list, list()) //List of all dead mobs, including clientless. Excludes /mob/new_player
GLOBAL_LIST_INIT(respawnable_list, list()) //List of all mobs, dead or in mindless creatures that still be respawned.
GLOBAL_LIST_INIT(non_respawnable_keys, list()) //List of ckeys that are excluded from respawning for remainder of round.
-GLOBAL_LIST_INIT(simple_animal_list, list()) //List of all simple animals, including clientless
-GLOBAL_LIST_INIT(snpc_list, list()) //List of all snpc's, including clientless
+GLOBAL_LIST_INIT(simple_animals, list(list(), list(), list(), list())) //One for each AI_* status define, List of all simple animals, including clientless
GLOBAL_LIST_INIT(bots_list, list()) //List of all bots(beepsky, medibots,etc)
GLOBAL_LIST_INIT(med_hud_users, list())
diff --git a/code/controllers/Processes/npcai.dm b/code/controllers/Processes/npcai.dm
deleted file mode 100644
index 127429efd34..00000000000
--- a/code/controllers/Processes/npcai.dm
+++ /dev/null
@@ -1,41 +0,0 @@
-var/global/datum/controller/process/npcai/npcai_master
-
-/datum/controller/process/npcai
- var/current_cycle
-
-/datum/controller/process/npcai/setup()
- name = "npc ai"
- schedule_interval = 20 // every 2 seconds
- start_delay = 16
- log_startup_progress("NPC ticker starting up.")
-
-/datum/controller/process/npcai/started()
- ..()
- if(!GLOB.simple_animal_list)
- GLOB.simple_animal_list = list()
- if(!GLOB.snpc_list)
- GLOB.snpc_list = list()
-
-/datum/controller/process/npcai/statProcess()
- ..()
- stat(null, "[GLOB.simple_animal_list.len] simple animals")
- stat(null, "[GLOB.snpc_list.len] SNPC's")
-
-/datum/controller/process/npcai/doWork()
- for(last_object in GLOB.simple_animal_list)
- var/mob/living/simple_animal/M = last_object
- if(istype(M) && !QDELETED(M))
- if(!M.client && M.stat == CONSCIOUS)
- try
- M.process_ai()
- catch(var/exception/e)
- catchException(e, M)
- SCHECK
- else
- catchBadType(M)
- GLOB.simple_animal_list -= M
-
- current_cycle++
-
-
-DECLARE_GLOBAL_CONTROLLER(npcai, npcai_master)
diff --git a/code/controllers/subsystem/idlenpcpool.dm b/code/controllers/subsystem/idlenpcpool.dm
new file mode 100644
index 00000000000..2dad0abca0f
--- /dev/null
+++ b/code/controllers/subsystem/idlenpcpool.dm
@@ -0,0 +1,41 @@
+SUBSYSTEM_DEF(idlenpcpool)
+ name = "Idling NPC Pool"
+ flags = SS_POST_FIRE_TIMING|SS_BACKGROUND
+ priority = FIRE_PRIORITY_IDLE_NPC
+ wait = 60
+ runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
+
+ var/list/currentrun = list()
+ var/static/list/idle_mobs_by_zlevel[][]
+
+/datum/controller/subsystem/idlenpcpool/stat_entry()
+ var/list/idlelist = GLOB.simple_animals[AI_IDLE]
+ var/list/zlist = GLOB.simple_animals[AI_Z_OFF]
+ ..("IdleNPCS:[idlelist.len]|Z:[zlist.len]")
+
+/datum/controller/subsystem/idlenpcpool/Initialize(start_timeofday)
+ idle_mobs_by_zlevel = new /list(world.maxz,0)
+ return ..()
+
+/datum/controller/subsystem/idlenpcpool/fire(resumed = FALSE)
+ if(!resumed)
+ var/list/idlelist = GLOB.simple_animals[AI_IDLE]
+ src.currentrun = idlelist.Copy()
+
+ //cache for sanic speed (lists are references anyways)
+ var/list/currentrun = src.currentrun
+
+ while(currentrun.len)
+ var/mob/living/simple_animal/SA = currentrun[currentrun.len]
+ --currentrun.len
+ if(!SA)
+ GLOB.simple_animals[AI_IDLE] -= SA
+ continue
+
+ if(!SA.ckey)
+ if(SA.stat != DEAD)
+ SA.handle_automated_movement()
+ if(SA.stat != DEAD)
+ SA.consider_wakeup()
+ if(MC_TICK_CHECK)
+ return
\ No newline at end of file
diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm
index d19396af767..20061d7489b 100644
--- a/code/controllers/subsystem/mobs.dm
+++ b/code/controllers/subsystem/mobs.dm
@@ -1,14 +1,19 @@
SUBSYSTEM_DEF(mobs)
name = "Mobs"
priority = FIRE_PRIORITY_MOBS
- flags = SS_KEEP_TIMING | SS_NO_INIT
+ flags = SS_KEEP_TIMING
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/currentrun = list()
+ var/static/list/clients_by_zlevel[][]
/datum/controller/subsystem/mobs/stat_entry()
..("P:[GLOB.mob_list.len]")
+/datum/controller/subsystem/mobs/Initialize(start_timeofday)
+ clients_by_zlevel = new /list(world.maxz,0)
+ return ..()
+
/datum/controller/subsystem/mobs/fire(resumed = 0)
var/seconds = wait * 0.1
if(!resumed)
diff --git a/code/controllers/subsystem/npcai.dm b/code/controllers/subsystem/npcai.dm
deleted file mode 100644
index f8fa3a5aa0f..00000000000
--- a/code/controllers/subsystem/npcai.dm
+++ /dev/null
@@ -1,24 +0,0 @@
-SUBSYSTEM_DEF(npcai)
- name = "NPC AI" // Simple AI controller, isolated from the SNPC one (NPCPool).
- flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
- priority = FIRE_PRIORITY_NPC
- runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
- var/list/simple_animal_list = list()
-
-/datum/controller/subsystem/npcai/stat_entry()
- ..("SimAnimals:[simple_animal_list.len]")
-
-/datum/controller/subsystem/npcai/fire(resumed = FALSE)
- if(!resumed)
- src.simple_animal_list = simple_animal_list.Copy()
- for(var/mob/living/simple_animal/M in simple_animal_list)
- if(istype(M) && !QDELETED(M))
- if(!M.client && M.stat == CONSCIOUS)
- M.process_ai()
- if(MC_TICK_CHECK)
- return
- else
- simple_animal_list -= M
-
-/datum/controller/subsystem/npcai/Recover()
- simple_animal_list = SSnpcai.simple_animal_list
\ No newline at end of file
diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm
index b06d33f6f32..0de306b12eb 100644
--- a/code/controllers/subsystem/npcpool.dm
+++ b/code/controllers/subsystem/npcpool.dm
@@ -1,127 +1,33 @@
-#define PROCESSING_NPCS 0
-#define PROCESSING_DELEGATES 1
-#define PROCESSING_ASSISTANTS 2
-
SUBSYSTEM_DEF(npcpool)
- name = "NPC Pool"
- flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
- priority = FIRE_PRIORITY_NPC
- runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
+ name = "NPC Pool"
+ flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
+ priority = FIRE_PRIORITY_NPC
+ runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
- var/list/canBeUsed = list()
- var/list/needsDelegate = list()
- var/list/needsAssistant = list()
-
- var/list/processing = list()
- var/list/currentrun = list()
- var/stage
+ var/list/currentrun = list()
/datum/controller/subsystem/npcpool/stat_entry()
- ..("NPCS:[processing.len]|D:[needsDelegate.len]|A:[needsAssistant.len]|U:[canBeUsed.len]")
-
-/datum/controller/subsystem/npcpool/proc/stop_processing(mob/living/carbon/human/interactive/I)
- processing -= I
- currentrun -= I
- needsDelegate -= I
- canBeUsed -= I
- needsAssistant -= I
+ var/list/activelist = GLOB.simple_animals[AI_ON]
+ ..("SimpleAnimals:[activelist.len]")
/datum/controller/subsystem/npcpool/fire(resumed = FALSE)
- //bot delegation and coordination systems
- //General checklist/Tasks for delegating a task or coordinating it (for SNPCs)
- // 1. Bot proximity to task target: if too far, delegate, if close, coordinate
- // 2. Bot Health/status: check health with bots in local area, if their health is higher, delegate task to them, else coordinate
- // 3. Process delegation: if a bot (or bots) has been delegated, assign them to the task.
- // 4. Process coordination: if a bot(or bots) has been asked to coordinate, assign them to help.
- // 5. Do all assignments: goes through the delegated/coordianted bots and assigns the right variables/tasks to them.
- if (!resumed)
- currentrun = processing.Copy()
- stage = PROCESSING_NPCS
- //cache for sanic speed (lists are references anyways)
- var/list/cachecurrentrun = currentrun
- var/list/cachecanBeUsed = canBeUsed
+ if(!resumed)
+ var/list/activelist = GLOB.simple_animals[AI_ON]
+ src.currentrun = activelist.Copy()
- if(stage == PROCESSING_NPCS)
- while(cachecurrentrun.len)
- var/mob/living/carbon/human/interactive/thing = cachecurrentrun[cachecurrentrun.len]
- --cachecurrentrun.len
+ var/list/currentrun = src.currentrun
- thing.InteractiveProcess()
+ while(currentrun.len)
+ var/mob/living/simple_animal/SA = currentrun[currentrun.len]
+ --currentrun.len
- var/checkInRange = view(SNPC_MAX_RANGE_FIND,thing)
- if(thing.IsDeadOrIncap(FALSE) || !(locate(thing.TARGET) in checkInRange))
- needsDelegate += thing
- else if(thing.doing & SNPC_FIGHTING)
- needsAssistant += thing
- else
- cachecanBeUsed += thing
-
- if (MC_TICK_CHECK)
- return
- stage = PROCESSING_DELEGATES
- cachecurrentrun = needsDelegate //localcache
- currentrun = cachecurrentrun
-
- if(stage == PROCESSING_DELEGATES)
- while(cachecurrentrun.len && cachecanBeUsed.len)
- var/mob/living/carbon/human/interactive/check = cachecurrentrun[cachecurrentrun.len]
- var/mob/living/carbon/human/interactive/candidate = cachecanBeUsed[cachecanBeUsed.len]
- --cachecurrentrun.len
-
- var/helpProb = 0
- var/list/chfac = check.faction
- var/list/canfac = candidate.faction
- var/facCount = LAZYLEN(chfac) * LAZYLEN(canfac)
-
- for(var/C in chfac)
- if(C in canfac)
- helpProb = min(100,helpProb + 25)
- if(helpProb >= 100)
- break
-
- if(facCount == 1 && helpProb)
- helpProb = 100
-
- if(prob(helpProb) && candidate.takeDelegate(check))
- --cachecanBeUsed.len
- candidate.change_eye_color(255, 0, 0)
- candidate.update_icons()
-
- if(MC_TICK_CHECK)
- return
- stage = PROCESSING_ASSISTANTS
- cachecurrentrun = needsAssistant //localcache
- currentrun = cachecurrentrun
-
- //no need for the stage check
-
- while(cachecurrentrun.len && cachecanBeUsed.len)
- var/mob/living/carbon/human/interactive/check = cachecurrentrun[cachecurrentrun.len]
- var/mob/living/carbon/human/interactive/candidate = cachecanBeUsed[cachecanBeUsed.len]
- --cachecurrentrun.len
-
- var/helpProb = 0
- var/list/chfac = check.faction
- var/list/canfac = candidate.faction
- var/facCount = LAZYLEN(chfac) * LAZYLEN(canfac)
-
- for(var/C in chfac)
- if(C in canfac)
- helpProb = min(100,helpProb + 25)
- if(helpProb >= 100)
- break
-
- if(facCount == 1 && helpProb)
- helpProb = 100
-
- if(prob(helpProb) && candidate.takeDelegate(check,FALSE))
- --cachecanBeUsed.len
- candidate.change_eye_color(255, 255, 0)
- candidate.update_icons()
-
- if(!cachecurrentrun.len || MC_TICK_CHECK) //don't change SS state if it isn't necessary
- return
-
-/datum/controller/subsystem/npcpool/Recover()
- processing = SSnpcpool.processing
\ No newline at end of file
+ if(!SA.ckey && !SA.notransform)
+ if(SA.stat != DEAD)
+ SA.handle_automated_movement()
+ if(SA.stat != DEAD)
+ SA.handle_automated_action()
+ if(SA.stat != DEAD)
+ SA.handle_automated_speech()
+ if(MC_TICK_CHECK)
+ return
\ No newline at end of file
diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm
index eeef65bd2e2..b23c9fe030a 100644
--- a/code/controllers/verbs.dm
+++ b/code/controllers/verbs.dm
@@ -80,9 +80,9 @@
if("Mob")
debug_variables(SSmobs)
feedback_add_details("admin_verb","DMob")
- if("NPC AI")
- debug_variables(SSnpcai)
- feedback_add_details("admin_verb","DNPCAI")
+ if("NPC Pool")
+ debug_variables(SSnpcpool)
+ feedback_add_details("admin_verb","DNPCPool")
if("Shuttle")
debug_variables(SSshuttle)
feedback_add_details("admin_verb","DShuttle")
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 2d3f01a139d..e962365451e 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -219,7 +219,12 @@
destination.Entered(src)
for(var/atom/movable/AM in destination)
AM.Crossed(src)
-
+ var/turf/oldturf = get_turf(old_loc)
+ var/turf/destturf = get_turf(destination)
+ var/old_z = (oldturf ? oldturf.z : null)
+ var/dest_z = (destturf ? destturf.z : null)
+ if(old_z != dest_z)
+ onTransitZ(old_z, dest_z)
if(isturf(destination) && opacity)
var/turf/new_loc = destination
new_loc.reconsider_lights()
@@ -232,6 +237,11 @@
return 1
+/atom/movable/proc/onTransitZ(old_z,new_z)
+ for(var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care.
+ var/atom/movable/AM = item
+ AM.onTransitZ(old_z,new_z)
+
/mob/living/forceMove(atom/destination)
if(buckled)
addtimer(CALLBACK(src, .proc/check_buckled), 1, TIMER_UNIQUE)
diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm
index bd934eefb44..0482a8e19ae 100644
--- a/code/game/gamemodes/blob/blobs/core.dm
+++ b/code/game/gamemodes/blob/blobs/core.dm
@@ -135,4 +135,9 @@
else
log_debug("/obj/structure/blob/core/proc/lateblobcheck: Blob core lacks a overmind.mind.")
else
- log_debug("/obj/structure/blob/core/proc/lateblobcheck: Blob core lacks an overmind.")
\ No newline at end of file
+ log_debug("/obj/structure/blob/core/proc/lateblobcheck: Blob core lacks an overmind.")
+
+/obj/structure/blob/core/onTransitZ(old_z, new_z)
+ if(overmind && is_station_level(new_z))
+ overmind.forceMove(get_turf(src))
+ return ..()
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm
index fbe1774525f..2b0162829e1 100644
--- a/code/game/gamemodes/miniantags/abduction/gland.dm
+++ b/code/game/gamemodes/miniantags/abduction/gland.dm
@@ -320,69 +320,6 @@
for(var/mob/living/carbon/human/H in oview(3,owner)) //Blood decals for simple animals would be neat. aka Carp with blood on it.
H.add_mob_blood(owner)
-/obj/item/organ/internal/heart/gland/bodysnatch
- cooldown_low = 600
- cooldown_high = 600
- human_only = 1
- uses = 1
-
-/obj/item/organ/internal/heart/gland/bodysnatch/activate()
- to_chat(owner, "You feel something moving around inside you...")
- //spawn cocoon with clone greytide snpc inside
- if(ishuman(owner))
- var/obj/effect/cocoon/abductor/C = new (get_turf(owner))
- C.Copy(owner)
- C.Start()
- owner.adjustBruteLoss(40)
- owner.add_splatter_floor()
-
-/obj/effect/cocoon/abductor
- name = "slimy cocoon"
- desc = "Something is moving inside."
- icon = 'icons/effects/effects.dmi'
- icon_state = "cocoon_large3"
- color = rgb(10,120,10)
- density = 1
- var/hatch_time = 0
-
-/obj/effect/cocoon/abductor/proc/Copy(mob/living/carbon/human/H)
- var/mob/living/carbon/human/interactive/greytide/clone = new(src)
- var/datum/dna/owner_dna = H.dna
- clone.rename_character(clone.name, owner_dna.real_name)
- clone.set_species(owner_dna.species.type)
- clone.dna = owner_dna.Clone()
- clone.body_accessory = H.body_accessory
- domutcheck(clone)
-
- for(var/obj/item/I in clone)
- if(istype(I, /obj/item/implant))
- continue
- if(istype(I, /obj/item/organ))
- continue
- qdel(I)
-
- //There's no define for this / get all items ?
- var/list/slots = list(slot_back,slot_w_uniform,slot_wear_suit,\
- slot_wear_mask,slot_head,slot_shoes,slot_gloves,slot_l_ear,slot_r_ear,\
- slot_glasses,slot_belt,slot_s_store,slot_l_store,slot_r_store,slot_wear_id,slot_wear_pda)
-
- for(var/slot in slots)
- var/obj/item/I = H.get_item_by_slot(slot)
- if(I)
- clone.equip_to_slot_or_del(new I.type(clone), slot)
-
-/obj/effect/cocoon/abductor/proc/Start()
- hatch_time = world.time + 600
- START_PROCESSING(SSobj, src)
-
-/obj/effect/cocoon/abductor/process()
- if(world.time > hatch_time)
- STOP_PROCESSING(SSobj, src)
- for(var/mob/M in contents)
- src.visible_message("[src] hatches!")
- M.forceMove(get_turf(src))
- qdel(src)
-
/obj/item/organ/internal/heart/gland/plasma
cooldown_low = 1200
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index d0872fa8f93..dc4b9124d77 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -741,6 +741,8 @@
throw_item.throw_at(target, 16, 3, src)
visible_message("[src] launches [throw_item.name] at [target.name]!")
+/obj/machinery/vending/onTransitZ()
+ return
/*
* Vending machine types
*/
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 6b4072a800b..4a455cd8e5d 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -72,7 +72,6 @@ var/list/admin_verbs_admin = list(
/client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */
/client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */
/client/proc/debug_variables,
- /client/proc/show_snpc_verbs,
/client/proc/reset_all_tcs, /*resets all telecomms scripts*/
/client/proc/toggle_mentor_chat,
/client/proc/toggle_advanced_interaction, /*toggle admin ability to interact with not only machines, but also atoms such as buttons and doors*/
@@ -216,11 +215,6 @@ var/list/admin_verbs_proccall = list(
/client/proc/callproc_datum,
/client/proc/SDQL2_query
)
-var/list/admin_verbs_snpc = list(
- /client/proc/resetSNPC,
- /client/proc/customiseSNPC,
- /client/proc/hide_snpc_verbs
-)
var/list/admin_verbs_ticket = list(
/client/proc/openAdminTicketUI,
/client/proc/toggleticketlogs,
@@ -291,8 +285,6 @@ var/list/admin_verbs_ticket = list(
admin_verbs_proccall,
admin_verbs_show_debug_verbs,
/client/proc/readmin,
- admin_verbs_snpc,
- /client/proc/hide_snpc_verbs,
admin_verbs_ticket
)
@@ -1013,28 +1005,6 @@ var/list/admin_verbs_ticket = list(
log_admin("[key_name(usr)] told everyone to man up and deal with it.")
message_admins("[key_name_admin(usr)] told everyone to man up and deal with it.")
-/client/proc/show_snpc_verbs()
- set name = "Show SNPC Verbs"
- set category = "Admin"
-
- if(!check_rights(R_ADMIN))
- return
-
- verbs += admin_verbs_snpc
- verbs -= /client/proc/show_snpc_verbs
- to_chat(src, "SNPC verbs have been toggled on.")
-
-/client/proc/hide_snpc_verbs()
- set name = "Hide SNPC Verbs"
- set category = "Admin"
-
- if(!check_rights(R_ADMIN))
- return
-
- verbs -= admin_verbs_snpc
- verbs += /client/proc/show_snpc_verbs
- to_chat(src, "SNPC verbs have been toggled off.")
-
/client/proc/toggle_advanced_interaction()
set name = "Toggle Advanced Admin Interaction"
set category = "Admin"
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 36c0e5cf90d..970defdd672 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -390,10 +390,7 @@
/datum/admins/proc/check_antagonists_line(mob/M, caption = "", close = 1)
var/logout_status
- if(istype(M, /mob/living/carbon/human/interactive))
- logout_status = " (snpc)"
- else
- logout_status = M.client ? "" : " (logged out)"
+ logout_status = M.client ? "" : " (logged out)"
var/dname = M.real_name
if(!dname)
dname = M
diff --git a/code/modules/awaymissions/mission_code/spacehotel.dm b/code/modules/awaymissions/mission_code/spacehotel.dm
index 0328dea5b53..fc8b4f4d260 100644
--- a/code/modules/awaymissions/mission_code/spacehotel.dm
+++ b/code/modules/awaymissions/mission_code/spacehotel.dm
@@ -152,14 +152,6 @@
/obj/machinery/door/unpowered/hotel_door/autoclose()
if(!density && !operating && autoclose)
close()
-
-/obj/machinery/door/unpowered/hotel_door/emag_act(mob/user)
- if(isliving(user) && density)
- var/obj/effect/hotel_controller/H
- if(H.controller)
- H.controller.deploy_sec(user)
- ..()
-
/obj/item/card/hotel_card
name = "Key Card"
icon_state = "guest"
@@ -283,20 +275,4 @@
spawn(300)
if(D.occupant == deadbeat)
// they still haven't checked out...
- deploy_sec(deadbeat)
- checkout(roomid)
-
-/obj/effect/hotel_controller/proc/deploy_sec(mob/living/target)
- if(!istype(target) || !istype(get_area(target), /area/awaymission/spacehotel))
- return
-
- var/list/secs[0]
- for(var/mob/living/carbon/human/interactive/away/hotel/guard/M in get_area(src))
- if(!M.retal)
- secs += M
- var/mob/living/carbon/human/interactive/away/hotel/guard/S = safepick(secs)
- if(!S)
- return
-
- S.retal_target = target
- S.retal = 1
+ checkout(roomid)
\ No newline at end of file
diff --git a/code/modules/awaymissions/mission_code/spacehotel_npcs.dm b/code/modules/awaymissions/mission_code/spacehotel_npcs.dm
deleted file mode 100644
index 2a524ab738c..00000000000
--- a/code/modules/awaymissions/mission_code/spacehotel_npcs.dm
+++ /dev/null
@@ -1,132 +0,0 @@
-/mob/living/carbon/human/interactive/away/hotel
- away_area = /area/awaymission/spacehotel
- override_under = /obj/item/clothing/under/mafia
- chattyness = SNPC_CHANCE_TALK / 4
-
-/mob/living/carbon/human/interactive/away/hotel/Initialize(mapload)
- . = ..(mapload, /datum/species/skrell)
-
-/mob/living/carbon/human/interactive/away/hotel/doSetup()
- ..()
- MYID.access = list(access_syndicate)
- RPID.access = list(access_syndicate)
-
-/mob/living/carbon/human/interactive/away/hotel/guard
- default_job = /datum/job/officer
-
-/mob/living/carbon/human/interactive/away/hotel/guard/doSetup()
- ..("Guard")
-
- // anti-pinata cheese
- var/obj/item/implant/dust/D = new /obj/item/implant/dust(src)
- D.implant(src)
-
- for(var/obj/item/I in get_all_slots())
- I.flags |= NODROP
-
-/mob/living/carbon/human/interactive/away/hotel/guard/KnockOut()
- // you'll never take me alive (this triggers the implant)
- emote("deathgasp")
- if(stat != DEAD)
- // mission failed. we'll get em next time
- ..()
-
-/mob/living/carbon/human/interactive/away/hotel/chef
- default_job = /datum/job/chef
- away_area = /area/awaymission/spacehotel/kitchen
- override_under = /obj/item/clothing/under/mafia/vest
-
-/mob/living/carbon/human/interactive/away/hotel/bartender
- default_job = /datum/job/bartender
- override_under = /obj/item/clothing/under/mafia/vest
-
-/mob/living/carbon/human/interactive/away/hotel/concierge
- override_under = /obj/item/clothing/under/mafia/white
- away_area = /area/awaymission/spacehotel/reception
- var/list/known_guests[0]
- var/obj/effect/hotel_controller/hotel
- var/obj/item/card/id/last_seen_id = null
-
-/mob/living/carbon/human/interactive/away/hotel/concierge/random()
- ..()
- equip_or_collect(new /obj/item/clipboard(src), slot_l_hand)
-
-/mob/living/carbon/human/interactive/away/hotel/concierge/doSetup()
- ..("Concierge")
-
-/mob/living/carbon/human/interactive/away/hotel/concierge/setup_job()
- favoured_types = list(/obj/item/paper, /obj/item/clipboard)
- functions += list("stamping", "concierge")
- restrictedJob = 1
-
-/mob/living/carbon/human/interactive/away/hotel/concierge/proc/concierge()
- if(!hotel)
- hotel = hotel.controller
- if(!hotel)
- return
-
- var/verbs_use = pick_list(speak_file, "verbs_use")
- var/verbs_touch = pick_list(speak_file, "verbs_touch")
- var/verbs_move = pick_list(speak_file, "verbs_move")
- var/nouns_generic = pick_list(speak_file, "nouns_generic")
- var/adjective_insult = pick_list(speak_file, "adjective_insult")
- var/adjective_objects = pick_list(speak_file, "adjective_objects")
- var/adjective_generic = pick_list(speak_file, "adjective_generic")
- var/curse_words = pick_list(speak_file, "curse_words")
-
- var/found = 0
- for(var/mob/living/carbon/human/H in nearby - known_guests)
- pointed(H)
- known_guests += H
- found = 1
- if(found)
- say("Welcome to [hotel], [nouns_generic]! Please check in by [ing_verb(verbs_move)] and [ing_verb(verbs_use)] your [adjective_objects] ID onto the table.")
- return
-
- var/obj/item/card/id
- var/id_seen = 0
- for(var/obj/item/card/id/I in get_area(src))
- id_seen = 1
- if(I != last_seen_id)
- id = I
- if(!id_seen)
- last_seen_id = null
- return
- if(!id)
- return
- var/turf/idloc = get_turf(id)
- if(!Adjacent(idloc))
- tryWalk(idloc)
- else
- // is the last jerk that touched it over here?
- var/mob/id_owner
- for(var/mob/living/carbon/human/H in nearby)
- if(H.ckey == id.fingerprintslast)
- id_owner = H
- break
-
- if(!id_owner)
- say("Whose card is this?")
- pointed(id)
- return
-
- last_seen_id = id
- // Checking in or out?
- if(id_owner in hotel.guests)
- // Check out
- say ("Hope you enjoyed your [adjective_objects] stay at our [adjective_generic] hotel!")
- hotel.checkout(hotel.guests[id_owner])
- else
- // pick a room
- var/obj/machinery/door/unpowered/hotel_door/D = safepick(hotel.vacant_rooms)
- if(!D)
- say("Sorry, all the [adjective_objects] are occupied currently.")
- else
- // Check in
- say("$100 per 10 minutes. The cost will be automatically [past_verb(verbs_touch)] while you're checked in.")
-
- var/obj/item/card/hotel_card/K = hotel.checkin(D.id, id_owner, id)
- if(K)
- K.forceMove(idloc)
- else
- say("Your [adjective_insult] [curse_words] card was rejected.")
diff --git a/code/modules/awaymissions/snpc.dm b/code/modules/awaymissions/snpc.dm
deleted file mode 100644
index 8d65aa44a92..00000000000
--- a/code/modules/awaymissions/snpc.dm
+++ /dev/null
@@ -1,85 +0,0 @@
-/mob/living/carbon/human/interactive/away
- var/away_area = /area/awaymission // their overriden job area
- var/override_under = null // optional type for uniform, else default for job
- var/squad_member = 0 // was spawned by squad
- var/home_z
-
-/mob/living/carbon/human/interactive/away/Initialize(mapload)
- . = ..()
- TRAITS |= TRAIT_ROBUST
- faction += "away"
-
-/mob/living/carbon/human/interactive/away/random()
- ..()
- // a little hacky but it should prevent doubled uniforms
- if(ispath(override_under, /obj/item/clothing/under))
- var/old_under = w_uniform
- w_uniform = null
- equip_to_slot(new override_under(src), slot_w_uniform)
- qdel(old_under)
-
-/mob/living/carbon/human/interactive/away/doSetup()
- ..()
- var/datum/data/pda/app/messenger/M = MYPDA.find_program(/datum/data/pda/app/messenger)
- M.toff = 1
-
-/mob/living/carbon/human/interactive/away/job2area()
- return away_area
-
-/mob/living/carbon/human/interactive/away/doProcess()
- if(!home_z)
- home_z = get_turf(z)
- if(home_z != get_turf(z))
- gib()
- ..()
-
-/obj/effect/spawner/snpc_squad
- name = "squad spawner"
- icon = 'icons/mob/screen_gen.dmi'
- icon_state = "x"
- density = 0
- opacity = 0
- invisibility = 101
- var/squad_type = /mob/living/carbon/human/interactive/away
- var/squad_size = 3
-
- var/global/list/squads[0]
- var/list/squad
-
-/obj/effect/spawner/snpc_squad/New()
- START_PROCESSING(SSobj, src)
-
- squad = squads[squad_type]
- if(!squad)
- squad = list()
- squads[squad_type] = squad
- squad += src
-
-/obj/effect/spawner/snpc_squad/Destroy()
- squad = null
- STOP_PROCESSING(SSobj, src)
- return ..()
-
-/obj/effect/spawner/snpc_squad/process()
- // check squad memebers
- var/living = 0
- for(var/mob/living/carbon/human/interactive/away/A in squad)
- if(!A.stat)
- living++
- else
- // see if anyone's looking, if not, despawn
- var/can_despawn = 1
- for(var/mob/living/M in viewers(A, world.view + 1))
- if(M.client)
- living++ // dead guy that can be seen still takes up a slot
- can_despawn = 0
- break
- if(can_despawn)
- squad -= A
- qdel(A)
-
- // spawn new ones
- if(living < squad_size && !length(viewers(src, world.view)))
- var/mob/living/carbon/human/interactive/away/A = new squad_type(loc)
- squad += A
- A.squad_member = 1
diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm
index cf8b897104c..17262ec4a7a 100644
--- a/code/modules/mining/minebot.dm
+++ b/code/modules/mining/minebot.dm
@@ -69,7 +69,7 @@
visible_message("[src] crackles and buzzes violently!")
/mob/living/simple_animal/hostile/mining_drone/sentience_act()
- AIStatus = AI_OFF
+ ..()
check_friendly_fire = 0
/mob/living/simple_animal/hostile/mining_drone/attackby(obj/item/I, mob/user, params)
diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm
index 0edb81c8321..43bc1b57226 100644
--- a/code/modules/mining/satchel_ore_boxdm.dm
+++ b/code/modules/mining/satchel_ore_boxdm.dm
@@ -83,6 +83,9 @@ obj/structure/ore_box/ex_act(severity, target)
O.forceMove(loc)
CHECK_TICK
+/obj/structure/ore_box/onTransitZ()
+ return
+
/obj/structure/ore_box/verb/empty_box()
set name = "Empty Ore Box"
set category = "Object"
diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm
index 922f3181c27..ca868b5e88f 100644
--- a/code/modules/mob/dead/dead.dm
+++ b/code/modules/mob/dead/dead.dm
@@ -20,4 +20,4 @@
for(var/datum/light_source/L in light_sources)
L.source_atom.update_light()
- return 1
+ return 1
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index aa714f0d527..f16d04e3e86 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -315,15 +315,7 @@
msg += "[p_they(TRUE)] [p_have()] a stupid expression on [p_their()] face.\n"
if(get_int_organ(/obj/item/organ/internal/brain))
- if(istype(src, /mob/living/carbon/human/interactive))
- var/mob/living/carbon/human/interactive/auto = src
- if(auto.showexaminetext)
- msg += "[p_they(TRUE)] [p_are()] appears to be some sort of sick automaton, [p_their()] eyes are glazed over and [p_their()] mouth is slightly agape.\n"
- if(auto.debugexamine)
- var/dodebug = auto.doing2string(auto.doing)
- var/interestdebug = auto.interest2string(auto.interest)
- msg += "[p_they(TRUE)] [p_are()] appears to be [interestdebug] and [dodebug].\n"
- else if(dna.species.show_ssd)
+ if(dna.species.show_ssd)
if(!key)
msg += "[p_they(TRUE)] [p_are()] totally catatonic. The stresses of life in deep-space must have been too much for [p_them()]. Any recovery is unlikely.\n"
else if(!client)
diff --git a/code/modules/mob/living/carbon/human/interactive/functions.dm b/code/modules/mob/living/carbon/human/interactive/functions.dm
deleted file mode 100644
index 06df994df5f..00000000000
--- a/code/modules/mob/living/carbon/human/interactive/functions.dm
+++ /dev/null
@@ -1,874 +0,0 @@
-/mob/living/carbon/human/interactive/proc/chatter(obj)
- var/verbs_use = pick_list(speak_file, "verbs_use")
- var/verbs_touch = pick_list(speak_file, "verbs_touch")
- var/verbs_move = pick_list(speak_file, "verbs_move")
- var/nouns_insult = pick_list(speak_file, "nouns_insult")
- var/nouns_generic = pick_list(speak_file, "nouns_generic")
- var/nouns_objects = pick_list(speak_file, "nouns_objects")
- var/nouns_body = pick_list(speak_file, "nouns_body")
- var/adjective_insult = pick_list(speak_file, "adjective_insult")
- var/adjective_objects = pick_list(speak_file, "adjective_objects")
- var/adjective_generic = pick_list(speak_file, "adjective_generic")
- var/curse_words = pick_list(speak_file, "curse_words")
-
- var/chatmsg = ""
-
- if(prob(10)) // 10% chance to broadcast it over the radio
- chatmsg = ";"
-
- if(prob(chattyness) || knownStrings.len < 10) // say a generic phrase, otherwise draw from our strings.
- if(doing & SNPC_INTERACTING)
- if(prob(chattyness))
- chatmsg += pick("This [nouns_objects] is a little [adjective_objects].",
- "Well [verbs_use] my [nouns_body], this [nouns_insult] is pretty [adjective_insult].",
- "[capitalize(curse_words)], what am I meant to do with this [adjective_insult] [nouns_objects].")
- else if(doing & SNPC_TRAVEL)
- if(prob(chattyness))
- chatmsg += pick("Oh [curse_words], [verbs_move]!",
- "Time to get my [adjective_generic] [adjective_insult] [nouns_body] elsewhere.",
- "I wonder if there is anything to [verbs_use] and [verbs_touch] somewhere else..")
- else if(doing & SNPC_FIGHTING)
- if(prob(chattyness))
- chatmsg += pick("I'm going to [verbs_use] you, you [adjective_insult] [nouns_insult]!",
- "Rend and [verbs_touch], Rend and [verbs_use]!",
- "You [nouns_insult], I'm going to [verbs_use] you right in the [nouns_body]. JUST YOU WAIT!")
- if(prob(chattyness/2))
- chatmsg = ";"
- var/what = pick(1,2,3,4,5)
- switch(what)
- if(1)
- chatmsg += "Well [curse_words], this is a [adjective_generic] situation."
- if(2)
- chatmsg += "Oh [curse_words], that [nouns_insult] was one hell of an [adjective_insult] [nouns_body]."
- if(3)
- chatmsg += "I want to [verbs_use] that [nouns_insult] when I find them."
- if(4)
- chatmsg += "[pick("Innocent","Guilty","Traitorous","Honk")] until proven [adjective_generic]!"
- if(5)
- var/toSay = ""
- for(var/i = 0; i < 5; i++)
- curse_words = pick_list(speak_file, "curse_words")
- toSay += "[curse_words] "
- chatmsg += "Hey [nouns_generic], why don't you go [copytext(toSay, 1, length(toSay))], you [nouns_insult]!"
- else if(prob(chattyness))
- chatmsg += pick(knownStrings)
- if(prob(25)) // cut out some phrases now and then to make sure we're fresh and new
- knownStrings -= pick(chatmsg)
-
- if(chatmsg != ";" && chatmsg != "")
- say(chatmsg)
-
-/mob/living/carbon/human/interactive/proc/traitor(obj)
-
- if(traitorType == SNPC_PSYCHO && nearby.len)
- traitorTarget = pick(nearby)
-
- if(prob(traitorScale))
- if(!Adjacent(traitorTarget) && !(traitorType == SNPC_PSYCHO))
- tryWalk(get_turf(traitorTarget))
- else
- switch(traitorType)
- if(SNPC_BRUTE)
- retal = 1
- retal_target = traitorTarget
- if(SNPC_STEALTH)
- if(istype(traitorTarget,/mob)) // it's inside something, lets kick their shit in
- var/mob/M = traitorTarget
- if(!M.stat)
- retal = 1
- retal_target = traitorTarget
- else
- var/obj/item/I = traitorTarget
- I.loc = get_turf(traitorTarget) // pull it outta them
- else
- take_to_slot(traitorTarget)
- if(SNPC_MARTYR)
- custom_emote(1, "[src]'s chest opens up, revealing a large mass of explosives and tangled wires!")
- if(inactivity_period <= 0)
- inactivity_period = 9999 // technically infinite
- if(do_after(src, 60, target = traitorTarget))
- custom_emote(1, "A fire bursts from [src]'s eyes, igniting white hot and consuming [p_their()] body in a flaming explosion!")
- explosion(src, 6, 6, 6)
- else
- inactivity_period = 0
- custom_emote(1, "[src]'s chest closes, hiding [p_their()] insides.")
- if(SNPC_PSYCHO)
- var/choice = pick(typesof(/obj/item/grenade/chem_grenade) - /obj/item/grenade/chem_grenade)
-
- new choice(src)
-
- retal = 1
- retal_target = traitorTarget
-
-/mob/living/carbon/human/interactive/proc/botany(obj)
- if(shouldModulePass())
- return
-
- if(enforceHome())
- return
-
- var/list/allContents = getAllContents()
-
- var/obj/item/reagent_containers/glass/beaker/bluespace/internalBeaker = locate(/obj/item/reagent_containers/glass/beaker/bluespace) in allContents
- var/obj/item/storage/bag/plants/internalBag = locate(/obj/item/storage/bag/plants) in allContents
-
- if(!internalBag)
- internalBag = new/obj/item/storage/bag/plants(src)
- if(!internalBeaker)
- internalBeaker = new/obj/item/reagent_containers/glass/beaker/bluespace(src)
- internalBeaker.name = "Grow-U-All Super Spray"
-
- if(internalBeaker && internalBag)
- var/obj/machinery/hydroponics/HP
-
- //consider the appropriate target
- var/list/considered = list()
-
- for(var/obj/machinery/hydroponics/tester in view(12,src))
- considered[tester] = 1
-
- if(!tester.myseed)
- considered[tester] += 50
- if(tester.weedlevel > 0)
- considered[tester] += 5
- if(tester.pestlevel > 0)
- considered[tester] += 5
- if(tester.nutrilevel < tester.maxnutri)
- considered[tester] += 15
- if(tester.waterlevel < tester.maxwater)
- considered[tester] += 15
- if(tester.harvest || tester.dead)
- considered[tester] += 100
- considered[tester] = max(1, considered[tester] - get_dist(src,tester))
-
- var/index = 0
- for(var/A in considered)
- ++index
- if(considered[A] > considered[HP] || !HP)
- HP = considered[index]
-
- if(HP)
- TARGET = HP
- if(!Adjacent(HP))
- tryWalk(get_turf(HP))
- else
- if(HP.harvest || HP.dead)
- HP.attack_hand(src)
- else if(!HP.myseed)
- var/obj/item/seeds/SEED = new /obj/item/seeds/random(src)
- custom_emote(1, "[pick("gibbers","drools","slobbers","claps wildly","spits")] towards [TARGET], producing a [SEED]!")
- HP.attackby(SEED, src)
- else
- var/change = 0
- if(HP.weedlevel > 0)
- change = 1
- if(!internalBeaker.reagents.has_reagent("atrazine", 10))
- internalBeaker.reagents.add_reagent("atrazine", 10)
- if(HP.pestlevel > 0)
- change = 1
- if(!internalBeaker.reagents.has_reagent("diethylamine", 10))
- internalBeaker.reagents.add_reagent("diethylamine", 10)
- if(HP.nutrilevel < HP.maxnutri)
- change = 1
- if(!internalBeaker.reagents.has_reagent("eznutriment", 15))
- internalBeaker.reagents.add_reagent("eznutriment", 15)
- if(!internalBeaker.reagents.has_reagent("diethylamine", 15))
- internalBeaker.reagents.add_reagent("diethylamine", 15)
- if(HP.waterlevel < HP.maxwater)
- change = 1
- if(!internalBeaker.reagents.has_reagent("holywater", 50))
- internalBeaker.reagents.add_reagent("holywater", 50)
- if(change)
- HP.attackby(internalBeaker,src)
-
- var/obj/item/reagent_containers/food/snacks/grown/GF = locate(/obj/item/reagent_containers/food/snacks/grown) in view(12,src)
- if(GF)
- if(!Adjacent(GF))
- tryWalk(get_turf(GF))
- else
- GF.attackby(internalBag,src)
-
- if(internalBag.contents.len)
- var/obj/machinery/smartfridge/SF = locate(/obj/machinery/smartfridge) in range(12, src)
- if(!Adjacent(SF))
- tryWalk(get_turf(SF))
- else
- custom_emote(1, "[pick("gibbers","drools","slobbers","claps wildly","spits")], upending the [internalBag]'s contents all over the [SF]!")
- //smartfridges call updateUsrDialog when you call attackby, so we're going to have to cheese-magic-space this
- for(var/obj/toLoad in internalBag.contents)
- if(contents.len >= SF.max_n_of_items)
- break
- if(SF.accept_check(toLoad))
- SF.load(toLoad, src)
- else
- qdel(toLoad) // destroy everything we dont need
-
-/mob/living/carbon/human/interactive/proc/bartend(obj)
- if(shouldModulePass())
- return
-
- if(enforceHome())
- return
-
- var/list/rangeCheck = oview(6,src)
- var/obj/structure/table/RT
-
- var/mob/living/carbon/human/serveTarget
-
- for(var/mob/living/carbon/human/H in rangeCheck)
- if(!locate(/obj/item/reagent_containers/food/drinks) in orange(1, H))
- serveTarget = H
-
-
- if(serveTarget)
- RT = locate(/obj/structure/table) in orange(1, serveTarget)
-
- if(RT && serveTarget)
- if(!Adjacent(RT))
- tryWalk(get_turf(RT))
- else
- var/drinkChoice = pick(typesof(/obj/item/reagent_containers/food/drinks) - /obj/item/reagent_containers/food/drinks)
- if(drinkChoice)
- var/obj/item/reagent_containers/food/drinks/D = new drinkChoice(get_turf(src))
- RT.attackby(D,src)
- say("[pick("Something to wet your whistle!","Down the hatch, a tasty beverage!","One drink, coming right up!","Tasty liquid for your oral intake!","Enjoy!")]")
- custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")], serving up a [D]!")
-
-/mob/living/carbon/human/interactive/proc/shitcurity(obj)
- var/list/allContents = getAllContents()
-
- if(retal && TARGET)
- if(Adjacent(TARGET))
- var/obj/item/restraints/R = locate() in allContents
- if(R)
- R.attack(TARGET, src) // go go bluespace restraint launcher!
- else if(TARGET in oview(7, src))
- var/obj/item/gun/G = locate() in allContents
- if(G)
- G.afterattack(TARGET, src)
-
-/mob/living/carbon/human/interactive/proc/clowning(obj)
- if(shouldModulePass())
- return
- var/list/allContents = getAllContents()
- var/list/rangeCheck = oview(12, src)
-
- var/mob/living/carbon/human/clownTarget
- var/list/clownPriority = list()
-
- var/obj/item/reagent_containers/spray/S
- if(!locate(/obj/item/reagent_containers/spray) in allContents)
- new/obj/item/reagent_containers/spray(src)
- else
- S = locate(/obj/item/reagent_containers/spray) in allContents
-
- for(var/mob/living/carbon/human/C in rangeCheck)
- var/pranksNearby = 100
- for(var/turf/simulated/T in orange(1, C))
- for(var/obj/item/A in T)
- if(istype(A,/obj/item/soap) || istype(A,/obj/item/reagent_containers/food/snacks/grown/banana) || istype(A,/obj/item/grown/bananapeel))
- pranksNearby--
- if(T.wet)
- pranksNearby -= 10
- clownPriority[C] = pranksNearby
-
- for(var/A in clownPriority)
- if(!clownTarget)
- clownTarget = A
- else
- if(clownPriority[A] > clownPriority[clownTarget])
- clownTarget = clownPriority[A]
-
- if(clownTarget)
- if(!Adjacent(clownTarget))
- tryWalk(clownTarget)
- else
- var/hasPranked = 0
- for(var/A in allContents)
- if(prob(smartness/2) && !hasPranked)
- if(istype(A,/obj/item/soap))
- npcDrop(A)
- hasPranked = 1
- if(istype(A,/obj/item/reagent_containers/food/snacks/grown/banana))
- var/obj/item/reagent_containers/food/snacks/B = A
- B.attack(src, src)
- if(istype(A,/obj/item/grown/bananapeel))
- npcDrop(A)
- hasPranked = 1
- if(!hasPranked)
- if(S.reagents.total_volume <= 5)
- S.reagents.add_reagent("water", 25)
- S.afterattack(get_turf(pick(orange(1, clownTarget))),src)
-
-
-/mob/living/carbon/human/interactive/proc/healpeople(obj)
- var/shouldTryHeal = 0
- var/obj/item/stack/medical/M
-
- var/list/allContents = getAllContents()
-
- for(var/A in allContents)
- if(istype(A,/obj/item/stack/medical))
- shouldTryHeal = 1
- M = A
-
- var/obj/item/reagent_containers/hypospray/HPS
-
- if(!locate(/obj/item/reagent_containers/hypospray) in allContents)
- new/obj/item/reagent_containers/hypospray(src)
- else
- HPS = locate(/obj/item/reagent_containers/hypospray) in allContents
- if(!shouldTryHeal)
- shouldTryHeal = 2 // we have no stackables to use, lets use our internal hypospray instead
-
- if(shouldTryHeal == 1)
- for(var/mob/living/carbon/human/C in nearby)
- if(istype(C,/mob/living/carbon/human)) //I haven't the foggiest clue why this is turning up non-carbons but sure here whatever
- if(C.health <= 75)
- if(get_dist(src,C) <= 2)
- src.say("Wait, [C], let me heal you!")
- M.attack(C,src)
- sleep(25)
- else
- tryWalk(get_turf(C))
- else if(shouldTryHeal == 2)
- if(HPS)
- if(HPS.reagents.total_volume <= 0)
- HPS.reagents.add_reagent("omnizine",30)
- for(var/mob/living/carbon/human/C in nearby)
- if(istype(C,/mob/living/carbon/human))
- if(C.health <= 75 && C.reagents.get_reagent_amount("omnizine") <= 0) // make sure they wont be overdosing
- if(get_dist(src,C) <= 2)
- src.say("Wait, [C], let me heal you!")
- HPS.attack(C,src)
- sleep(25)
- else
- tryWalk(get_turf(C))
-
-
-/mob/living/carbon/human/interactive/proc/dojanitor(obj)
- if(shouldModulePass())
- return
- var/list/allContents = getAllContents()
- //now with bluespace magic!
- var/obj/item/reagent_containers/spray/SP = locate() in allContents
- if(!SP)
- SP = new /obj/item/reagent_containers/spray(src)
- var/obj/item/soap/SO = locate() in allContents
- if(!SO)
- SO = new /obj/item/soap(src)
-
- if(SP.reagents.total_volume <= 5)
- SP.reagents.add_reagent("cleaner", 25) // bluespess water delivery for AI
-
- var/obj/effect/decal/cleanable/TC
- TC = locate(/obj/effect/decal/cleanable) in view(6, src)
-
- if(TC)
- if(!Adjacent(TC))
- tryWalk(TC)
- else
- var/turf/T = get_turf(TC)
- if(T && !T.density)
- SP.afterattack(TC, src, 1)
- else
- SO.afterattack(TC, src, 1)
- qdel(TC)
-
-// START COOKING MODULE
-/mob/living/carbon/human/interactive/proc/refundrecipe(list/ingredients)
- for(var/obj/I in ingredients)
- I.loc = contents
-
-// Ingredients may be in the rangeCheck or inside the chef's inventory.
-// As they are checked off, they are moved to a seperate list as to not be counted twice
-// If the recipe fails (eg somebody else took an ingredient before it was picked up) the ingredients are dumped back to inventory
-// That way, the chef has a better chance of making a recipe next ptick, if he has more stuff on him
-/mob/living/carbon/human/interactive/proc/makerecipe(datum/recipe/R, allContents, rangeCheck)
- set background = 1
-
- var/list/ingredients[0]
-
- for(var/P in R.items)
- var/obj/item/I = locate(P) in allContents
- if(I)
- ingredients += I
- I.forceMove(null)
- continue
-
- I = locate(P) in rangeCheck
- TARGET = I
- if(I && !Adjacent(I))
- tryWalk(get_turf(I))
- sleep(get_dist(src, I))
- if(!I || !(I in rangeCheck))
- refundrecipe(ingredients)
- return 0
- custom_emote(1, "[pick("gibbers","drools","slobbers","claps wildly","spits")], picking up [I].")
- ingredients += I
- I.forceMove(null)
-
- // cheaply cook the ingredients into result
- sleep(R.time)
- for(var/obj/I in ingredients)
- qdel(I)
- ingredients.Cut()
- var/result = new R.result(get_turf(src))
- custom_emote(1, "[pick("gibbers","drools","slobbers","claps wildly","spits")] and, with a bang, \a [result] is cooked!")
- return 1
-
-/mob/living/carbon/human/interactive/proc/souschef(obj)
- if(shouldModulePass() || enforceHome() || prob(SNPC_FUZZY_CHANCE_HIGH) || prob(SNPC_FUZZY_CHANCE_HIGH))
- return
-
- if(doing & SNPC_SPECIAL)
- return
- doing |= SNPC_SPECIAL
-
- var/static/list/customableTypes = list(/obj/item/reagent_containers/food/snacks/customizable,/obj/item/reagent_containers/food/snacks/breadslice,/obj/item/reagent_containers/food/snacks/bun,/obj/item/reagent_containers/food/snacks/sliceable/flatdough,/obj/item/reagent_containers/food/snacks/boiledspaghetti,/obj/item/trash/plate,/obj/item/trash/bowl)
-
- var/static/list/rawtypes = list(/obj/item/reagent_containers/food/snacks/grown, /obj/item/reagent_containers/food/snacks/rawcutlet, /obj/item/reagent_containers/food/snacks/rawsticks, /obj/item/reagent_containers/food/snacks/salmonmeat, /obj/item/reagent_containers/food/snacks/carpmeat, /obj/item/reagent_containers/food/snacks/catfishmeat, /obj/item/reagent_containers/food/snacks/spaghetti, /obj/item/reagent_containers/food/snacks/dough, /obj/item/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/reagent_containers/food/snacks/doughslice, /obj/item/reagent_containers/food/snacks/meat, /obj/item/reagent_containers/food/snacks/boiledrice, /obj/item/reagent_containers/food/snacks/cheesewedge, /obj/item/reagent_containers/food/snacks/raw_bacon)
-
- try
- var/list/allContents = getAllContents()
- var/list/rangeCheck = view(6, src)
-
- //Bluespace in some inbuilt tools
- var/obj/item/kitchen/rollingpin/RP = locate() in allContents
- if(!RP)
- RP = new /obj/item/kitchen/rollingpin(src)
-
- var/obj/item/kitchen/knife/KK = locate() in allContents
- if(!KK)
- KK = new /obj/item/kitchen/knife(src)
-
- var/global/list/available_recipes
- if(!available_recipes)
- available_recipes = list()
- for(var/type in subtypesof(/datum/recipe))
- var/datum/recipe/recipe = new type
- if(recipe.result) // Ignore recipe subtypes that lack a result
- available_recipes += recipe
- else
- qdel(recipe)
-
- var/foundCookable = 0
-
- //Make some basic custom food
- var/foundCustom
- for(var/customType in customableTypes)
- var/A = locate(customType) in rangeCheck
- var/obj/item/reagent_containers/food/snacks/customizable/I = A
- if(A && (!istype(I) || I.ingredients.len <= 3))
- foundCustom = A // this will eventually wittle down to 0
- break
-
- var/obj/machinery/smartfridge/SF = locate(/obj/machinery/smartfridge) in rangeCheck
- if(SF)
- if(SF.contents.len > 0)
- if(!Adjacent(SF))
- tryWalk(get_turf(SF))
- else
- custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")], grabbing various foodstuffs from [SF] and sticking them in its mouth!")
- for(var/obj/item/A in SF.contents)
- if(prob(smartness/2))
- var/count = SF.item_quants[A.name]
- if(count)
- SF.item_quants[A.name] = count - 1
- A.forceMove(src)
-
- if(foundCustom)
- var/obj/item/reagent_containers/food/snacks/FC = foundCustom
- for(var/obj/item/reagent_containers/food/snacks/toMake in allContents)
- if(prob(smartness))
- if(FC.reagents)
- if(toMake.reagents)
- var/raw = 0
- for(var/type in rawtypes)
- if(istype(toMake, type))
- raw = 1
- break
- if(!raw)
- npcDrop(toMake)
- FC.attackby(toMake, src)
- allContents -= toMake
- break
- else
- qdel(FC) // this food is usless, toss it
-
- // Process tool-based ingredients
- var/obj/item/reagent_containers/food/snacks/dough/D = locate() in rangeCheck
- var/obj/item/reagent_containers/food/snacks/sliceable/flatdough/FD = locate() in rangeCheck
- var/obj/item/reagent_containers/food/snacks/rawcutlet/RC = locate() in rangeCheck
- var/obj/item/reagent_containers/food/snacks/sliceable/cheesewheel/CW = locate() in rangeCheck
- var/obj/item/reagent_containers/food/snacks/grown/potato/PO = locate() in rangeCheck
- var/obj/item/reagent_containers/food/snacks/meat/ME = locate() in rangeCheck
- var/obj/item/reagent_containers/food/snacks/raw_bacon/RB = locate() in rangeCheck
-
- if(D)
- TARGET = D
- if(prob(50))
- tryWalk(get_turf(D))
- sleep(get_dist(src, D))
- D.attackby(RP, src)
- foundCookable = 1
- else if(FD)
- TARGET = FD
- if(prob(50))
- tryWalk(get_turf(FD))
- sleep(get_dist(src, FD))
- FD.attackby(KK, src)
- foundCookable = 1
- else if(RC)
- TARGET = RC
- if(prob(50))
- tryWalk(get_turf(RC))
- sleep(get_dist(src, RC))
- RC.attackby(KK, src)
- foundCookable = 1
- else if(CW)
- TARGET = CW
- if(prob(50))
- tryWalk(get_turf(CW))
- sleep(get_dist(src, CW))
- CW.attackby(KK, src)
- foundCookable = 1
- else if(PO)
- TARGET = PO
- if(prob(50))
- tryWalk(get_turf(PO))
- sleep(get_dist(src, PO))
- PO.attackby(KK, src)
- foundCookable = 1
- else if(ME)
- TARGET = ME
- if(prob(50))
- tryWalk(get_turf(ME))
- sleep(get_dist(src, ME))
- ME.attackby(KK, src)
- foundCookable = 1
- else if(RB)
- TARGET = RB
- if(prob(50))
- tryWalk(get_turf(RB))
- sleep(get_dist(src, RB))
- RB.attackby(KK, src)
- foundCookable = 1
-
- // refresh
- allContents = getAllContents()
- rangeCheck = view(6, src)
-
- // Find most complex recipe we can cook
- var/ingredientZone = rangeCheck + allContents
- var/highest_count = 0
- var/datum/recipe/winner = null
- for(var/datum/recipe/R in available_recipes)
- if(R.check_items(ingredientZone) >= 0)
- var/count = (R.items ? R.items.len : 0)
- if(count > highest_count)
- highest_count = count
- winner = R
-
- // make winner
- if(winner)
- if(makerecipe(winner, allContents, rangeCheck))
- foundCookable = 1
-
- // refresh
- allContents = getAllContents()
- rangeCheck = view(6, src)
-
- // dont display our ingredients
- var/list/finishedList = list()
- for(var/obj/item/reagent_containers/food/snacks/toDisplay in allContents)
- var/raw = 0
- for(var/type in rawtypes)
- if(istype(toDisplay, type))
- raw = 1
- break
- if(!raw)
- finishedList += toDisplay
-
- for(var/obj/item/reagent_containers/food/snacks/toGrab in rangeCheck)
- if(!(locate(/obj/structure/table/reinforced) in get_turf(toGrab))) //it's not being displayed
- var/raw = 0
- for(var/type in rawtypes)
- if(istype(toGrab, type))
- raw = 1
- break
- if(!raw)
- foundCookable = 1
- if(!Adjacent(toGrab))
- tryWalk(toGrab)
- else
- finishedList += toGrab
- toGrab.forceMove(src)
-
- if(finishedList.len)
- var/obj/structure/table/reinforced/RT
-
- for(var/obj/structure/table/reinforced/toCheck in rangeCheck)
- var/counted = 0
- for(var/obj/item/reagent_containers/food/snacks/S in get_turf(toCheck))
- ++counted
- if(counted < 12) // make sure theres not too much food here
- RT = toCheck
- break
-
- if(RT)
- foundCookable = 1
- if(!Adjacent(RT))
- tryWalk(get_turf(RT))
- else
- for(var/obj/item/reagent_containers/food/snacks/toPlop in finishedList)
- RT.attackby(toPlop,src)
-
- if(!foundCookable)
- var/chosenType = pick(rawtypes)
-
- var/obj/item/reagent_containers/food/snacks/newSnack = new chosenType(get_turf(src))
- TARGET = newSnack
- newSnack.reagents.remove_any((newSnack.reagents.total_volume/2)-1)
- newSnack.name = "synthetic [newSnack.name]"
- custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")] as [p_they()] vomit[p_s()] [newSnack] from [p_their()] mouth!")
- catch(var/exception/e)
- log_runtime(e, src, "Caught in SNPC cooking module")
- doing &= ~SNPC_SPECIAL
-// END COOKING MODULE
-
-/mob/living/carbon/human/interactive/proc/combat(obj)
- set background = 1
- enforce_hands()
- if(canmove)
- if((graytide || (TRAITS & TRAIT_MEAN)) || retal)
- interest += targetInterestShift
- a_intent = INTENT_HARM
- zone_sel.selecting = pick("chest","r_leg","l_leg","r_arm","l_arm","head")
- doing |= SNPC_FIGHTING
- if(retal)
- TARGET = retal_target
- else
- var/mob/living/M = locate(/mob/living) in oview(7, src)
- if(!M)
- doing = doing & ~SNPC_FIGHTING
- else if(M != src && !compareFaction(M.faction))
- TARGET = M
-
- //no infighting
- if(retal)
- if(retal_target)
- if(compareFaction(retal_target.faction))
- retal = 0
- retal_target = null
- TARGET = null
- doing = 0
-
- //ensure we're using the best object possible
-
- var/obj/item/best
- var/foundFav = 0
- var/list/allContents = getAllContents()
- for(var/test in allContents)
- for(var/a in favoured_types)
- if(ispath(test,a) && !(doing & SNPC_FIGHTING)) // if we're not in combat and we find our favourite things, use them (for people like janitor and doctors)
- best = test
- foundFav = 1
- return
- if(!foundFav)
- if(istype(test,/obj/item))
- var/obj/item/R = test
- if(R.force > 2) // make sure we don't equip any non-weaponlike items, ie bags and stuff
- if(!best)
- best = R
- else
- if(best.force < R.force)
- best = R
- if(istype(R, /obj/item/gun))
- var/obj/item/gun/G = R
- if(G.can_shoot())
- best = R
- break // gun with ammo? screw the rest
- if(best && best != main_hand)
- take_to_slot(best,1)
-
- if(TARGET && (doing & SNPC_FIGHTING)) // this is a redundancy check
- var/mob/living/M = TARGET
- if(istype(M,/mob/living))
- if(M.health > 1 && (M in oview(src, 6)))
- //THROWING OBJECTS
- for(var/A in allContents)
- if(istype(A,/obj/item/gun)) // guns are for shooting, not throwing.
- continue
- if(prob(robustness))
- if(istype(A,/obj/item))
- var/obj/item/W = A
- if(W.throwforce > 19) // Only throw worthwile stuff, no more lobbing wrenches at wenches
- npcDrop(W, 1)
- throw_item(TARGET)
- if(istype(A,/obj/item/grenade)) // Allahu ackbar! ALLAHU ACKBARR!!
- var/obj/item/grenade/G = A
- G.attack_self(src)
- if(prob(smartness))
- npcDrop(G, 1)
- sleep(15)
- throw_item(TARGET)
-
- if(!main_hand && other_hand)
- swap_hands()
- if(main_hand)
- if(main_hand.force != 0)
- if(istype(main_hand,/obj/item/gun))
- var/obj/item/gun/G = main_hand
- if(G.can_trigger_gun(src))
- var/shouldFire = 1
- if(istype(main_hand, /obj/item/gun/energy))
- var/obj/item/gun/energy/P = main_hand
- var/stunning = 0
- for(var/A in P.ammo_type)
- if(ispath(A,/obj/item/ammo_casing/energy/electrode))
- stunning = 1
- var/mob/stunCheck = TARGET
- if(stunning && stunCheck.stunned)
- shouldFire = 0
- if(shouldFire)
- if(!G.can_shoot())
- G.shoot_with_empty_chamber(src)
- npcDrop(G, 1)
- else
- G.process_fire(TARGET, src)
- else
- if(get_dist(src,TARGET) > 6)
- if(!walk2derpless(TARGET))
- timeout++
- else
- var/obj/item/W = main_hand
- W.attack(TARGET, src)
- else
- npcDrop(G, 1)
- else
- if(targetRange(TARGET) > 2)
- tryWalk(TARGET)
- else
- if(Adjacent(TARGET))
- a_intent = pick(INTENT_DISARM, INTENT_HARM)
- M.attack_hand(src)
- timeout++
- else if(timeout >= 10 || !(targetRange(M) > 14))
- doing = doing & ~SNPC_FIGHTING
- timeout = 0
- TARGET = null
- retal = 0
- retal_target = null
- else
- timeout++
-
-/mob/living/carbon/human/interactive/proc/past_verb(word)
- if(copytext(word, length(word)) == "e")
- return "[word]d"
- else
- return "[word]ed"
-
-/mob/living/carbon/human/interactive/proc/ing_verb(word)
- if(copytext(word, length(word)) == "e")
- return "[copytext(word, 1, length(word))]ing"
- else
- return "[word]ing"
-
-/mob/living/carbon/human/interactive/proc/paperwork_sentence()
- var/verbs_use = pick_list(speak_file, "verbs_use")
- var/verbs_touch = pick_list(speak_file, "verbs_touch")
- var/verbs_move = pick_list(speak_file, "verbs_move")
- var/nouns_insult = pick_list(speak_file, "nouns_insult")
- var/nouns_generic = pick_list(speak_file, "nouns_generic")
- var/nouns_objects = pick_list(speak_file, "nouns_objects")
- var/nouns_body = pick_list(speak_file, "nouns_body")
- var/adjective_insult = pick_list(speak_file, "adjective_insult")
- var/adjective_objects = pick_list(speak_file, "adjective_objects")
- var/adjective_generic = pick_list(speak_file, "adjective_generic")
- var/curse_words = pick_list(speak_file, "curse_words")
- var/result = pick("fired", "promoted", "demoted", "terminated", "incinerated", "sent to CentCom", "borged")
-
- return pick(
- "The [adjective_insult] [pick(command_positions)] [past_verb(verbs_touch)] the [adjective_objects] [nouns_objects] and was [result].",
- "The [adjective_generic] [pick(engineering_positions)] [past_verb(verbs_touch)] the [adjective_insult] [nouns_objects]. [capitalize(curse_words)], the [nouns_insult] was [result].",
- "The [adjective_insult] [pick(security_positions)] [past_verb(verbs_touch)] the [adjective_generic] [nouns_insult] [pick(support_positions)]'s [nouns_body] and had to be [result].",
- "Medical had to [verbs_use] the [adjective_generic] [pick(command_positions)]'s [adjective_objects] [nouns_body] after the incident.",
- "I demand that [nouns_generic] respond with a [adjective_generic] update ASAP.",
- "Would like an update from [nouns_generic] regarding the [adjective_insult] [pick(command_positions)] being [result].",
- "The [pick(medical_positions)] needs to [verbs_move] faster when the crew's [adjective_objects] [nouns_body]s are injured, or they will be [result].",
- "[capitalize(curse_words)] [adjective_insult] [curse_words].",
- "
")
-
-/mob/living/carbon/human/interactive/proc/pickStamp(allContents)
- var/list/stamps[0]
- for(var/obj/item/stamp/S in allContents)
- stamps += S
- if(stamps.len)
- return pick(stamps)
-
- // just make one, maybe
- if(prob(SNPC_FUZZY_CHANCE_LOW / 2))
- for(var/p in favoured_types)
- if(ispath(p, /obj/item/stamp))
- return new p(src)
- return null
-
-/mob/living/carbon/human/interactive/proc/paperwork(obj)
- set background = 1
-
- if(shouldModulePass() || !prob(SNPC_FUZZY_CHANCE_LOW / 4))
- return
-
- var/list/allContents = getAllContents()
-
- var/obj/item/paper/P = locate() in allContents
- var/obj/item/stamp/S = pickStamp(allContents)
- var/mob/living/carbon/human/H = locate() in nearby
-
- if(!P)
- P = new /obj/item/paper(src)
-
- if(P && S && H)
- if(!P.stamped || !P.stamped.len)
- // generate form
- P.name = pick("Inspection Report", "Re: Crew", "Complaint", "To: CentCom")
- P.info = {"

Name | Status | Location | Control |
| [Bot.hacked ? "(!) [Bot.name]" : Bot.name] ([Bot.model]) | " diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 3ff26f7850c..970ac596482 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -451,7 +451,7 @@ response_harm = "kicks" gold_core_spawnable = CHEM_MOB_SPAWN_INVALID -/mob/living/simple_animal/pet/corgi/Ian/process_ai() +/mob/living/simple_animal/pet/corgi/Ian/Life() ..() //Feeding, chasing food, FOOOOODDDD @@ -578,7 +578,7 @@ return ..() -/mob/living/simple_animal/pet/corgi/Lisa/process_ai() +/mob/living/simple_animal/pet/corgi/Lisa/Life() ..() make_babies() diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index ae19106e1af..869c663e312 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -54,9 +54,8 @@ else if(prob(5)) emote("snuffles") -/mob/living/simple_animal/mouse/process_ai() +/mob/living/simple_animal/mouse/Life() ..() - if(prob(0.5)) stat = UNCONSCIOUS icon_state = "mouse_[mouse_color]_sleep" diff --git a/code/modules/mob/living/simple_animal/friendly/pug.dm b/code/modules/mob/living/simple_animal/friendly/pug.dm index e1e16ef42b2..36ce34094a0 100644 --- a/code/modules/mob/living/simple_animal/friendly/pug.dm +++ b/code/modules/mob/living/simple_animal/friendly/pug.dm @@ -19,7 +19,7 @@ see_in_dark = 5 gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY -/mob/living/simple_animal/pet/pug/process_ai() +/mob/living/simple_animal/pet/pug/Life() ..() if(!resting && !buckled) diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 50568fb37d0..852d7c406d1 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -30,8 +30,6 @@ var/stat_exclusive = 0 //Mobs with this set to 1 will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction - var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever) - //typecache of things this mob will attack in DestroySurroundings() if it has environment_smash var/list/environment_target_typecache = list( /obj/machinery/door/window, @@ -66,12 +64,6 @@ walk(src, 0) return 0 -/mob/living/simple_animal/hostile/process_ai() - ..() - if(!AICanContinue()) - return 0 - return 1 - /mob/living/simple_animal/hostile/handle_automated_action() if(AIStatus == AI_OFF) return 0 @@ -83,7 +75,7 @@ DestroySurroundings() if(!MoveToTarget(possible_targets)) //if we lose our target if(AIShouldSleep(possible_targets)) // we try to acquire a new one - AIStatus = AI_IDLE // otherwise we go idle + toggle_ai(AI_IDLE) // otherwise we go idle return 1 /mob/living/simple_animal/hostile/attacked_by(obj/item/I, mob/living/user) @@ -264,8 +256,8 @@ if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight search_objects = 0 target = null - if(AIStatus == AI_IDLE) - AIStatus = AI_ON + if(AIStatus != AI_ON && AIStatus != AI_OFF) + toggle_ai(AI_ON) FindTarget() else if(target != null && prob(40))//No more pulling a mob forever and having a second player attack it, it can switch targets now if it finds a more suitable one FindTarget() @@ -401,9 +393,43 @@ if(AI_IDLE) if(FindTarget(possible_targets, 1)) . = 1 - AIStatus = AI_ON //Wake up for more than one Life() cycle. + toggle_ai(AI_ON) //Wake up for more than one Life() cycle. else . = 0 /mob/living/simple_animal/hostile/proc/AIShouldSleep(var/list/possible_targets) return !FindTarget(possible_targets, 1) + +/mob/living/simple_animal/hostile/consider_wakeup() + ..() + var/list/tlist + var/turf/T = get_turf(src) + + if(!T) + return + + if(!length(SSmobs.clients_by_zlevel[T.z])) // It's fine to use .len here but doesn't compile on 511 + toggle_ai(AI_Z_OFF) + return + + var/cheap_search = isturf(T) && !(T.z == 1) // The original check for SSmapping's station z level trait, unfortunately it isn't here. + if(cheap_search) + tlist = ListTargetsLazy(T.z) + else + tlist = ListTargets() + + if(AIStatus == AI_IDLE && FindTarget(tlist, 1)) + if(cheap_search) //Try again with full effort + FindTarget() + toggle_ai(AI_ON) + +/mob/living/simple_animal/hostile/proc/ListTargetsLazy(var/_Z)//Step 1, find out what we can see + var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/spacepod)) + . = list() + for(var/I in SSmobs.clients_by_zlevel[_Z]) + var/mob/M = I + if(get_dist(M, src) < vision_range) + if(isturf(M.loc)) + . += M + else if(M.loc.type in hostile_machines) + . += M.loc \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 81b384f56b7..60b0f7277c8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -142,7 +142,7 @@ var/pre_attack = 0 loot = list(/obj/item/asteroid/goliath_hide{layer = 4.1}) -/mob/living/simple_animal/hostile/asteroid/goliath/process_ai() +/mob/living/simple_animal/hostile/asteroid/goliath/Life() ..() handle_preattack() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index b4019cff988..867b0eb5073 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -80,10 +80,14 @@ var/deathmessage = "" var/death_sound = null //The sound played on death + var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever) + var/can_have_ai = TRUE //once we have become sentient, we can never go back + var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check. + /mob/living/simple_animal/Initialize() ..() - GLOB.simple_animal_list += src + GLOB.simple_animals[AIStatus] += src verbs -= /mob/verb/observe if(!can_hide) verbs -= /mob/living/simple_animal/verb/hide @@ -97,7 +101,18 @@ collar.forceMove(loc) collar = null master_commander = null - GLOB.simple_animal_list -= src + GLOB.simple_animals[AIStatus] -= src + if(SSnpcpool.state == SS_PAUSED && LAZYLEN(SSnpcpool.currentrun)) + SSnpcpool.currentrun -= src + + if(nest) + nest.spawned_mobs -= src + nest = null + + var/turf/T = get_turf(src) + if (T && AIStatus == AI_Z_OFF) + SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src + return ..() /mob/living/simple_animal/Login() @@ -111,12 +126,6 @@ health = Clamp(health, 0, maxHealth) med_hud_set_status() - -/mob/living/simple_animal/proc/process_ai() - handle_automated_movement() - handle_automated_action() - handle_automated_speech() - /mob/living/simple_animal/lay_down() ..() handle_resting_state_icons() @@ -562,6 +571,8 @@ /* End Inventory */ /mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion + toggle_ai(AI_OFF) + can_have_ai = FALSE return /mob/living/simple_animal/update_sight() @@ -581,4 +592,37 @@ return /mob/living/simple_animal/can_hear() - . = TRUE \ No newline at end of file + . = TRUE + +/mob/living/simple_animal/proc/consider_wakeup() + if(pulledby || shouldwakeup) + toggle_ai(AI_ON) + +/mob/living/simple_animal/adjustHealth(amount, updating_health = TRUE, forced = FALSE) + . = ..() + if(!ckey && !stat)//Not unconscious + if(AIStatus == AI_IDLE) + toggle_ai(AI_ON) + +/mob/living/simple_animal/proc/toggle_ai(togglestatus) + if(!can_have_ai && (togglestatus != AI_OFF)) + return + if(AIStatus != togglestatus) + if(togglestatus > 0 && togglestatus < 5) + if(togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF) + var/turf/T = get_turf(src) + if(AIStatus == AI_Z_OFF) + SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src + else + SSidlenpcpool.idle_mobs_by_zlevel[T.z] += src + GLOB.simple_animals[AIStatus] -= src + GLOB.simple_animals[togglestatus] += src + AIStatus = togglestatus + else + stack_trace("Something attempted to set simple animals AI to an invalid state: [togglestatus]") + +/mob/living/simple_animal/onTransitZ(old_z, new_z) + ..() + if(AIStatus == AI_Z_OFF) + SSidlenpcpool.idle_mobs_by_zlevel[old_z] -= src + toggle_ai(initial(AIStatus)) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/spawner.dm b/code/modules/mob/living/simple_animal/spawner.dm index 7a17dfb202b..686a20cee36 100644 --- a/code/modules/mob/living/simple_animal/spawner.dm +++ b/code/modules/mob/living/simple_animal/spawner.dm @@ -29,7 +29,7 @@ spawned_mobs = null return ..() -/mob/living/simple_animal/hostile/spawner/process_ai() +/mob/living/simple_animal/hostile/spawner/Life() ..() spawn_mob() diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 3e9ff0b7ba6..6a078ff2ba9 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -202,3 +202,4 @@ var/list/tkgrabbed_objects = list() // Assoc list of items to TK grabs var/forced_look = null // This can either be a numerical direction or a soft object reference (UID). It makes the mob always face towards the selected thing. + var/registered_z \ 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 a46b9a94fc7..bbc3d6d7abe 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -193,7 +193,7 @@ close_spawn_windows() var/obj/O = locate("landmark*Observer-Start") to_chat(src, "Now teleporting.") - observer.loc = O.loc + observer.forceMove(O.loc) observer.timeofdeath = world.time // Set the time of death so that the respawn timer works correctly. client.prefs.update_preview_icon(1) observer.icon = client.prefs.preview_icon @@ -344,27 +344,27 @@ else if(IsSyndicateCommand(rank)) character.loc = pick(syndicateofficer) else - character.loc = pick(aroomwarp) + character.forceMove(pick(aroomwarp)) join_message = "has arrived" else if(spawning_at) S = spawntypes[spawning_at] if(S && istype(S)) if(S.check_job_spawning(rank)) - character.loc = pick(S.turfs) + character.forceMove(pick(S.turfs)) join_message = S.msg else to_chat(character, "Your chosen spawnpoint ([S.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead.") - character.loc = pick(latejoin) + character.forceMove(pick(latejoin)) join_message = "has arrived on the station" else - character.loc = pick(latejoin) + character.forceMove(pick(latejoin)) join_message = "has arrived on the station" character.lastarea = get_area(loc) // Moving wheelchair if they have one if(character.buckled && istype(character.buckled, /obj/structure/chair/wheelchair)) - character.buckled.loc = character.loc + character.buckled.forceMove(character.loc) character.buckled.dir = character.dir character = SSjobs.EquipRank(character, rank, 1) //equips the human diff --git a/code/modules/pda/cart_apps.dm b/code/modules/pda/cart_apps.dm index de2414da743..a66e72d17a3 100644 --- a/code/modules/pda/cart_apps.dm +++ b/code/modules/pda/cart_apps.dm @@ -392,7 +392,7 @@ BucketData[++BucketData.len] = list("x" = 0, "y" = 0, dir=null, status = null) var/CbotData[0] - for(var/mob/living/simple_animal/bot/cleanbot/B in GLOB.simple_animal_list) + for(var/mob/living/simple_animal/bot/cleanbot/B in GLOB.simple_animals) var/turf/bl = get_turf(B) if(bl) if(bl.z != cl.z) diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 44edebdca50..c130ea1d447 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -1,9 +1,12 @@ // Shuttle on-movement // -/atom/movable/proc/onShuttleMove(turf/T1, rotation) - if(rotation) - shuttleRotate(rotation) - forceMove(T1) - return 1 +/atom/movable/proc/onShuttleMove(turf/oldT, turf/T1, rotation) + var/turf/newT = get_turf(src) + if(newT.z != oldT.z) + onTransitZ(oldT.z, newT.z) + if(rotation) + shuttleRotate(rotation) + forceMove(T1) + return 1 /atom/movable/lighting_overlay/onShuttleMove() return 0 diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index f3c0249941b..5c6445b2927 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -501,7 +501,7 @@ //move mobile to new location for(var/atom/movable/AM in T0) - AM.onShuttleMove(T1, rotation) + AM.onShuttleMove(T0, T1, rotation) if(rotation) T1.shuttleRotate(rotation) diff --git a/paradise.dme b/paradise.dme index 1b7a691c820..271e872ba5a 100644 --- a/paradise.dme +++ b/paradise.dme @@ -57,7 +57,6 @@ #include "code\__DEFINES\rolebans.dm" #include "code\__DEFINES\shuttle.dm" #include "code\__DEFINES\sight.dm" -#include "code\__DEFINES\snpc.dm" #include "code\__DEFINES\sound.dm" #include "code\__DEFINES\stat.dm" #include "code\__DEFINES\station_goals.dm" @@ -199,7 +198,6 @@ #include "code\controllers\subsystem.dm" #include "code\controllers\verbs.dm" #include "code\controllers\Processes\lighting.dm" -#include "code\controllers\Processes\npcai.dm" #include "code\controllers\Processes\ticker.dm" #include "code\controllers\ProcessScheduler\core\process.dm" #include "code\controllers\ProcessScheduler\core\processScheduler.dm" @@ -212,6 +210,7 @@ #include "code\controllers\subsystem\garbage.dm" #include "code\controllers\subsystem\holiday.dm" #include "code\controllers\subsystem\icon_smooth.dm" +#include "code\controllers\subsystem\idlenpcpool.dm" #include "code\controllers\subsystem\jobs.dm" #include "code\controllers\subsystem\machinery.dm" #include "code\controllers\subsystem\mapping.dm" @@ -219,7 +218,6 @@ #include "code\controllers\subsystem\nano_mob_hunter.dm" #include "code\controllers\subsystem\nanoui.dm" #include "code\controllers\subsystem\nightshift.dm" -#include "code\controllers\subsystem\npcai.dm" #include "code\controllers\subsystem\npcpool.dm" #include "code\controllers\subsystem\overlays.dm" #include "code\controllers\subsystem\radio.dm" @@ -1237,7 +1235,6 @@ #include "code\modules\awaymissions\loot.dm" #include "code\modules\awaymissions\map_rng.dm" #include "code\modules\awaymissions\pamphlet.dm" -#include "code\modules\awaymissions\snpc.dm" #include "code\modules\awaymissions\trigger.dm" #include "code\modules\awaymissions\zlevel.dm" #include "code\modules\awaymissions\zvis.dm" @@ -1253,7 +1250,6 @@ #include "code\modules\awaymissions\mission_code\evil_santa.dm" #include "code\modules\awaymissions\mission_code\spacebattle.dm" #include "code\modules\awaymissions\mission_code\spacehotel.dm" -#include "code\modules\awaymissions\mission_code\spacehotel_npcs.dm" #include "code\modules\awaymissions\mission_code\stationCollision.dm" #include "code\modules\awaymissions\mission_code\UO71-terrorspiders.dm" #include "code\modules\awaymissions\mission_code\wildwest.dm" @@ -1746,9 +1742,6 @@ #include "code\modules\mob\living\carbon\human\status_procs.dm" #include "code\modules\mob\living\carbon\human\update_icons.dm" #include "code\modules\mob\living\carbon\human\update_stat.dm" -#include "code\modules\mob\living\carbon\human\interactive\functions.dm" -#include "code\modules\mob\living\carbon\human\interactive\interactive.dm" -#include "code\modules\mob\living\carbon\human\interactive\prefabs.dm" #include "code\modules\mob\living\carbon\human\species\_species.dm" #include "code\modules\mob\living\carbon\human\species\abductor.dm" #include "code\modules\mob\living\carbon\human\species\diona.dm" diff --git a/strings/npc_chatter.json b/strings/npc_chatter.json deleted file mode 100644 index 833cb68605e..00000000000 --- a/strings/npc_chatter.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "nouns_insult": [ - "gaylord", - "shitcurity", - "noob", - "comdom", - "greyshirt", - "tator", - "lingbin", - "bitch", - "whorelord", - "cluwne", - "monkey", - "cheesemonger", - "milkdrinker" - ], - "adjective_objects": [ - "big", - "small", - "tiny", - "round", - "square", - "oblong", - "colorful", - "dull", - "shiny", - "sparkling", - "blinking", - "awful" - ], - "verbs_use": [ - "touch", - "hold", - "poke", - "punch", - "smash", - "assault", - "wrench", - "tickle", - "modify", - "whack", - "beat", - "tackle", - "destroy" - ], - "nouns_objects": [ - "thing", - "tool", - "whatever", - "potential murder weapon", - "object", - "toy", - "device", - "whatever" - ], - "nouns_generic": [ - "you", - "you there", - "guy", - "person", - "dude", - "jerk", - "officer" - ], - "curse_words": [ - "damn", - "shit", - "arse", - "ass", - "wank", - "jerk", - "bitch" - ], - "adjective_generic": [ - "nice", - "pretty", - "ugly", - "bad", - "okay", - "stupid" - ], - "verbs_move": [ - "run", - "jog", - "leg it", - "slide", - "cheese it", - "walk", - "stroll", - "fly", - "scoot", - "yakkety", - "speed", - "fuck off", - "escape" - ], - "verbs_touch": [ - "pat", - "mess with", - "absorb", - "sneeze on", - "inject", - "rip", - "slap", - "grab", - "choke" - ], - "adjective_insult": [ - "ugly", - "repulsive", - "dumb", - "asian", - "mongoloid", - "childish", - "captain-like", - "monkey-like", - "whoreish", - "dimwit", - "jerk-face", - "vomit-inducer" - ], - "nouns_body": [ - "ass", - "head", - "face", - "arms", - "fingers", - "toes", - "chest", - "eyes", - "nails", - "groin", - "stomach", - "intestines", - "head" - ] -}