From 53b4182eefc2ea47df71c2cc3d2a3c69fcbc502d Mon Sep 17 00:00:00 2001 From: clusterfack Date: Sun, 5 Jul 2015 01:38:58 -0500 Subject: [PATCH] Optimizes Say I dunno make say code faster or something --- code/__HELPERS/game.dm | 108 ---------------- code/game/atoms_movable.dm | 21 +++- code/game/machinery/bots/buttbot.dm | 1 + .../objects/items/weapons/implants/implant.dm | 4 +- code/game/say.dm | 115 ++++++++++++++++++ code/modules/mob/hearing/virtualhearer.dm | 52 ++++++++ code/modules/mob/login.dm | 3 + code/modules/mob/logout.dm | 4 + vgstation13.dme | 5 +- 9 files changed, 200 insertions(+), 113 deletions(-) create mode 100644 code/modules/mob/hearing/virtualhearer.dm diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 65f6acdb99b..feed5b0e952 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -127,29 +127,6 @@ turfs += T return turfs - -//This is the new version of recursive_mob_check, used for say(). -//The other proc was left intact because morgue trays use it. -/proc/recursive_hear_check(atom/O) - var/list/processing_list = list(O) - var/list/processed_list = list() - var/found_atoms = list() - - while (processing_list.len) - var/atom/A = processing_list[1] - - if (A.flags & HEAR) - found_atoms |= A - - for (var/atom/B in A) - if (!processed_list[B]) - processing_list |= B - - processing_list.Cut(1, 2) - processed_list[A] = A - - return found_atoms - /proc/recursive_type_check(atom/O, type = /atom) var/list/processing_list = list(O) var/list/processed_list = new/list() @@ -172,97 +149,12 @@ //var/debug_mob = 0 -// Will recursively loop through an atom's contents and check for mobs, then it will loop through every atom in that atom's contents. -// It will keep doing this until it checks every content possible. This will fix any problems with mobs, that are inside objects, -// being unable to hear people due to being in a box within a bag. - -/proc/recursive_mob_check(var/atom/O,var/client_check=1,var/sight_check=1,var/include_radio=1) - - var/list/processing_list = list(O) - var/list/processed_list = list() - var/list/found_mobs = list() - - while(processing_list.len) - - var/atom/A = processing_list[1] - var/passed = 0 - - if(ismob(A)) - var/mob/A_tmp = A - passed=1 - - if(client_check && !A_tmp.client) - passed=0 - - if(sight_check && !isInSight(A_tmp, O)) - passed=0 - - else if(include_radio && istype(A, /obj/item/device/radio)) - passed=1 - - if(sight_check && !isInSight(A, O)) - passed=0 - - if(passed) - found_mobs |= A - - for(var/atom/B in A) - if(!processed_list[B]) - processing_list |= B - - processing_list.Cut(1, 2) - processed_list[A] = A - - return found_mobs - -// The old system would loop through lists for a total of 5000 per function call, in an empty server. -// This new system will loop at around 1000 in an empty server. - -/proc/get_hearers_in_view(var/R, var/atom/source) - // Returns a list of hearers in range of R from source. Used in saycode. - var/turf/T = get_turf(source) - var/list/hear = list() - - if(!T) - return hear - - var/list/range = get_hear(R, T) - for(var/atom/movable/A in range) - hear |= recursive_hear_check(A) - - return hear - /proc/get_contents_in_object(atom/O, type_path = /atom/movable) if (O) return recursive_type_check(O, type_path) - O else return new/list() -/proc/get_movables_in_radio_ranges(var/list/obj/item/device/radio/radios) - - //set background = 1 - - . = list() - // Returns a list of mobs who can hear any of the radios given in @radios - for(var/i = 1; i <= radios.len; i++) - var/obj/item/device/radio/R = radios[i] - if(R) - . |= get_hearers_in_view(R) - . |= get_mobs_in_radio_ranges(radios) - return . - -/** - * Returns a list of mobs who can hear any of the radios given in @radios. - */ -/proc/get_mobs_in_radio_ranges(list/obj/item/device/radio/radios) - set background = BACKGROUND_ENABLED - - . = new/list() - - for (var/obj/item/device/radio/R in radios) - if (R) - . |= get_hearers_in_view(R.canhear_range, R) - #define SIGN(X) ((X<0)?-1:1) proc diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index d0ba67c93e2..4eca363ae4e 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -28,12 +28,17 @@ /atom/movable/New() . = ..() areaMaster = get_area_master(src) + if(flags & HEAR && !ismob(src)) + getFromPool(/mob/virtualhearer, src) /atom/movable/Destroy() + if(flags & HEAR && !ismob(src)) + for(var/mob/virtualhearer/VH in virtualhearers) + if(VH.attached == src) + returnToPool(VH) gcDestroyed = "Bye, world!" tag = null loc = null - ..() /proc/delete_profile(var/type, code = 0) @@ -338,3 +343,17 @@ /atom/movable/proc/say_understands(var/mob/other) return 1 + +//////////// +/// HEAR /// +//////////// +/atom/movable/proc/addHear() + flags |= HEAR + getFromPool(/mob/virtualhearer, src) + +/atom/movable/proc/removeHear() + flags &= ~HEAR + for(var/mob/virtualhearer/VH in virtualhearers) + if(VH.attached == src) + returnToPool(VH) + diff --git a/code/game/machinery/bots/buttbot.dm b/code/game/machinery/bots/buttbot.dm index 8d79e4fd555..97685b4c218 100644 --- a/code/game/machinery/bots/buttbot.dm +++ b/code/game/machinery/bots/buttbot.dm @@ -21,6 +21,7 @@ Here it is: Buttbot. maxhealth = 25 var/buttchance = 80 //Like an 80% chance of it working. It's just a butt with an arm in it. var/sincelastfart = 0 + flags = HEAR /obj/machinery/bot/buttbot/attack_hand(mob/living/user as mob) . = ..() diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index c6309895368..e3ea5971762 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -180,7 +180,7 @@ Implant Specifics:
"} phrase = sanitize_simple(phrase, replacechars) usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate.", 0, 0) usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate." - flags |= HEAR + addHear() return 1 /obj/item/weapon/implant/explosive/emp_act(severity) @@ -443,7 +443,7 @@ the implant may become unstable and either pre-maturely inject the subject or si if("death") if(!announcement_intercom || !istype(announcement_intercom)) announcement_intercom = new(null) - + if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) ) //give the syndies a bit of stealth Broadcast_Message(announcement_intercom, all_languages["Sol Common"], null, announcement_intercom, "[mobname] has died in Space!", "[mobname]'s Death Alarm", "Death Alarm", "[mobname]'s Death Alarm", 0, 0, list(0,1), 1459) diff --git a/code/game/say.dm b/code/game/say.dm index eedffdd9cb0..0ee43bc4719 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -206,3 +206,118 @@ proc/handle_render(var/mob,var/message,var/speaker) mob << message else mob << message + +var/global/resethearers = 0 + +/proc/sethearing() + var/atom/A + for(var/mob/virtualhearer/VH in virtualhearers) + for(A=VH.attached.loc, A && !isturf(A), A=A.loc); + VH.loc = A + resethearers = world.time + 5 + +// Returns a list of hearers in range of R from source. Used in saycode. +/proc/get_hearers_in_view(var/R, var/atom/source) + if(world.time>resethearers) sethearing() + + var/turf/T = get_turf(source) + . = new/list() + + if(!T) + return + + for(var/mob/virtualhearer/VH in hearers(R, T)) + . += VH.attached + +/** + * Returns a list of mobs who can hear any of the radios given in @radios. + */ +/proc/get_mobs_in_radio_ranges(list/obj/item/device/radio/radios) + if(world.time>resethearers) sethearing() + + . = new/list() + + for(var/obj/item/device/radio/radio in radios) + if(radio) + var/turf/turf = get_turf(radio) + + if(turf) + for(var/mob/virtualhearer/VH in hearers(radio.canhear_range, turf)) + . |= VH.attached + +/* Unused +/proc/get_movables_in_radio_ranges(var/list/obj/item/device/radio/radios) + . = new/list() + // Returns a list of mobs who can hear any of the radios given in @radios + for(var/i = 1; i <= radios.len; i++) + var/obj/item/device/radio/R = radios[i] + if(R) + . |= get_hearers_in_view(R) + . |= get_mobs_in_radio_ranges(radios) + +//But I don't want to check EVERYTHING to find a hearer you say? I agree +//This is the new version of recursive_mob_check, used for say(). +//The other proc was left intact because morgue trays use it. +/proc/recursive_hear_check(atom/O) + var/list/processing_list = list(O) + var/list/processed_list = list() + var/found_atoms = list() + + while (processing_list.len) + var/atom/A = processing_list[1] + + if (A.flags & HEAR) + found_atoms |= A + + for (var/atom/B in A) + if (!processed_list[B]) + processing_list |= B + + processing_list.Cut(1, 2) + processed_list[A] = A + + return found_atoms + +Even further legacy saycode +// Will recursively loop through an atom's contents and check for mobs, then it will loop through every atom in that atom's contents. +// It will keep doing this until it checks every content possible. This will fix any problems with mobs, that are inside objects, +// being unable to hear people due to being in a box within a bag. + +/proc/recursive_mob_check(var/atom/O,var/client_check=1,var/sight_check=1,var/include_radio=1) + + var/list/processing_list = list(O) + var/list/processed_list = list() + var/list/found_mobs = list() + + while(processing_list.len) + + var/atom/A = processing_list[1] + var/passed = 0 + + if(ismob(A)) + var/mob/A_tmp = A + passed=1 + + if(client_check && !A_tmp.client) + passed=0 + + if(sight_check && !isInSight(A_tmp, O)) + passed=0 + + else if(include_radio && istype(A, /obj/item/device/radio)) + passed=1 + + if(sight_check && !isInSight(A, O)) + passed=0 + + if(passed) + found_mobs |= A + + for(var/atom/B in A) + if(!processed_list[B]) + processing_list |= B + + processing_list.Cut(1, 2) + processed_list[A] = A + + return found_mobs*/ diff --git a/code/modules/mob/hearing/virtualhearer.dm b/code/modules/mob/hearing/virtualhearer.dm new file mode 100644 index 00000000000..57fa96f7586 --- /dev/null +++ b/code/modules/mob/hearing/virtualhearer.dm @@ -0,0 +1,52 @@ +var/global/list/mob/virtualhearer/virtualhearers = list() + +/mob/virtualhearer + name = "" + see_in_dark = 8 + icon = null + icon_state = null + var/atom/movable/attached = null + anchored = 1 + density = 0 + invisibility = INVISIBILITY_MAXIMUM + alpha = 0 + animate_movement = 0 + //This can be expanded with vision flags to make a device to hear through walls for example + +/mob/virtualhearer/New(attachedto) + AddToProfiler() + virtualhearers += src + loc = get_turf(attachedto) + attached = attachedto + if(istype(attached,/obj/item/device/radio/intercom)) + virtualhearers -= src + +/mob/virtualhearer/Destroy() + virtualhearers -= src + attached = null +/* +/mob/virtualhearer/proc/process() + var/atom/A + while(attached) + for(A=attached.loc, A && !isturf(A), A=A.loc); + loc = A + sleep(10) + returnToPool(src)*/ + +/mob/virtualhearer/resetVariables() + return + +/mob/virtualhearer/Hear(message, atom/movable/speaker, var/datum/language/speaking, raw_message, radio_freq) + if(attached) + attached.Hear(args) + else + returnToPool(src) + +/mob/virtualhearer/ex_act() + return + +/mob/virtualhearer/singularity_act() + return + +/mob/virtualhearer/singularity_pull() + return diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index bc804a791cf..6f5b2f20eb0 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -51,6 +51,9 @@ reset_view() + if(flags & HEAR) + getFromPool(/mob/virtualhearer, src) + //Clear ability list and update from mob. client.verbs -= ability_verbs diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index d3064960dba..7efa5357967 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -3,6 +3,10 @@ var/obj/location = loc location.on_log() + for(var/mob/virtualhearer/VH in virtualhearers) + if(VH.attached == src) + returnToPool(VH) + nanomanager.user_logout(src) // this is used to clean up (remove) this user's Nano UIs player_list -= src diff --git a/vgstation13.dme b/vgstation13.dme index 011dbc7beaf..3d1cdf795b1 100644 --- a/vgstation13.dme +++ b/vgstation13.dme @@ -811,7 +811,7 @@ #include "code\game\objects\structures\vehicles\adminbus_powers.dm" #include "code\game\objects\structures\vehicles\clowncart.dm" #include "code\game\objects\structures\vehicles\gokart.dm" -#include "code\game\objects\structures\vehicles\vehicle.dm" +#include "code\game\objects\structures\vehicles\vehicle.dm" #include "code\game\objects\structures\vehicles\wheelchair.dm" #include "code\game\objects\structures\vehicles\wizmobile.dm" #include "code\game\turfs\simulated.dm" @@ -1146,6 +1146,7 @@ #include "code\modules\mob\dead\observer\observer.dm" #include "code\modules\mob\dead\observer\say.dm" #include "code\modules\mob\dead\observer\spells.dm" +#include "code\modules\mob\hearing\virtualhearer.dm" #include "code\modules\mob\living\damage_procs.dm" #include "code\modules\mob\living\default_language.dm" #include "code\modules\mob\living\living.dm" @@ -1741,4 +1742,4 @@ #include "maps\RandomZLevels\challenge.dm" #include "maps\RandomZLevels\stationCollision.dm" #include "maps\RandomZLevels\wildwest.dm" -// END_INCLUDE +// END_INCLUDE