mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 18:32:03 +00:00
Refactored new AI components (#31421)
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
#define EVENT_HANDLER_OBJREF_INDEX 1
|
||||
#define EVENT_HANDLER_PROCNAME_INDEX 2
|
||||
// WARNING
|
||||
// Event handlers (i.e.: procs that are registered with `proc/register_event` MUST NOT sleep()).
|
||||
|
||||
// Declare children of this type path to use as identifiers for the events.
|
||||
/event
|
||||
|
||||
// TODO: Document here the arguments that need to be passed to the procs invoked by each event
|
||||
|
||||
// Called by human/proc/apply_radiation()
|
||||
// Arguments:
|
||||
// mob/carbon/living/human/user: The human.
|
||||
@@ -238,6 +236,25 @@
|
||||
// mob/source: the mob performing the emote
|
||||
/event/emote
|
||||
|
||||
// Called by mob/living/Hear
|
||||
// Arguments:
|
||||
// datum/speech/speech: the speech datum being heard
|
||||
/event/hear
|
||||
|
||||
// Called by area/Entered
|
||||
// Arguments:
|
||||
// atom/movable/enterer: the movable entering the area
|
||||
/event/area_entered
|
||||
|
||||
// Called by area/Exited
|
||||
// Arguments:
|
||||
// atom/movable/exiter: the movable exiting the area
|
||||
/event/area_exited
|
||||
|
||||
// Note: the following are used by datum/component/ai subtypes to give instructions to each other.
|
||||
// AI components are expected to INVOKE_EVENT these to send commands to other components
|
||||
// on the same datum without having to hold references to them.
|
||||
// They may need to be reworked, and they are currently undocumented.
|
||||
/event/comp_ai_friend_attacked
|
||||
|
||||
/event/comp_ai_cmd_get_best_target
|
||||
@@ -260,11 +277,8 @@
|
||||
/event/comp_ai_cmd_set_state
|
||||
/event/comp_ai_cmd_get_state
|
||||
|
||||
/event/comp_ai_cmd_hear
|
||||
/event/comp_ai_cmd_say
|
||||
/event/comp_ai_cmd_specific_say
|
||||
/event/comp_ai_cmd_area_enter
|
||||
/event/comp_ai_cmd_area_exit
|
||||
|
||||
/datum
|
||||
/// Associative list of type path -> list(),
|
||||
@@ -283,6 +297,9 @@
|
||||
*/
|
||||
#define INVOKE_EVENT(target, event_type, arguments...) (target.registered_events?[event_type] && target.invoke_event(event_type, list(##arguments)))
|
||||
|
||||
#define EVENT_HANDLER_OBJREF_INDEX 1
|
||||
#define EVENT_HANDLER_PROCNAME_INDEX 2
|
||||
|
||||
/datum/proc/invoke_event(event/event_type, list/arguments)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
var/list/event_handlers = registered_events[event_type]
|
||||
|
||||
@@ -446,10 +446,9 @@ var/area/space_area
|
||||
thing.area_entered(src)
|
||||
|
||||
for(var/mob/mob_in_obj in Obj.contents)
|
||||
|
||||
CallHook("MobAreaChange", list("mob" = mob_in_obj, "new" = src, "old" = oldArea))
|
||||
|
||||
INVOKE_EVENT(src, /event/comp_ai_cmd_area_enter, "enterer" = Obj)
|
||||
INVOKE_EVENT(src, /event/area_entered, "enterer" = Obj)
|
||||
var/mob/M = Obj
|
||||
if(istype(M))
|
||||
CallHook("MobAreaChange", list("mob" = M, "new" = src, "old" = oldArea)) // /vg/ - EVENTS!
|
||||
@@ -457,7 +456,7 @@ var/area/space_area
|
||||
narrator.Crossed(M)
|
||||
|
||||
/area/Exited(atom/movable/Obj)
|
||||
INVOKE_EVENT(src, /event/comp_ai_cmd_area_exit, "exiter" = Obj)
|
||||
INVOKE_EVENT(src, /event/area_exited, "exiter" = Obj)
|
||||
..()
|
||||
|
||||
/area/proc/subjectDied(target)
|
||||
|
||||
@@ -7,17 +7,17 @@
|
||||
|
||||
/datum/component/ai/area_territorial/proc/SetArea(var/area/new_area)
|
||||
if(territory)
|
||||
territory.unregister_event(/event/comp_ai_cmd_area_enter, src, .proc/area_enter)
|
||||
territory.unregister_event(/event/comp_ai_cmd_area_exit, src, .proc/area_exit)
|
||||
territory.unregister_event(/event/area_entered, src, .proc/area_enter)
|
||||
territory.unregister_event(/event/area_exited, src, .proc/area_exit)
|
||||
territory = new_area
|
||||
territory.register_event(/event/comp_ai_cmd_area_enter, src, .proc/area_enter)
|
||||
territory.register_event(/event/comp_ai_cmd_area_exit, src, .proc/area_exit)
|
||||
territory.register_event(/event/area_entered, src, .proc/area_enter)
|
||||
territory.register_event(/event/area_exited, src, .proc/area_exit)
|
||||
|
||||
/datum/component/ai/area_territorial/proc/area_enter(var/obj/enterer)
|
||||
/datum/component/ai/area_territorial/proc/area_enter(atom/movable/enterer)
|
||||
if(isliving(enterer)) // No ghosts
|
||||
INVOKE_EVENT(parent, enter_signal, enter_args)
|
||||
|
||||
/datum/component/ai/area_territorial/proc/area_exit(var/obj/exiter)
|
||||
/datum/component/ai/area_territorial/proc/area_exit(atom/movable/exiter)
|
||||
if(isliving(exiter)) // No ghosts
|
||||
INVOKE_EVENT(parent, exit_signal, exit_args)
|
||||
|
||||
|
||||
@@ -25,11 +25,9 @@
|
||||
var/speech_prob = 30
|
||||
var/next_speech
|
||||
var/speech_delay
|
||||
var/datum/component/ai/target_finder/finder = null
|
||||
|
||||
/datum/component/ai/conversation/auto/initialize()
|
||||
if(..())
|
||||
finder = parent.get_component(/datum/component/ai/target_finder/simple_view)
|
||||
active_components += src
|
||||
return TRUE
|
||||
|
||||
@@ -38,15 +36,13 @@
|
||||
..()
|
||||
|
||||
/datum/component/ai/conversation/auto/process()
|
||||
if(finder && next_speech < world.time && prob(speech_prob))
|
||||
var/listener
|
||||
for(var/mob/living/M in finder.cmd_find_targets())
|
||||
if(next_speech < world.time && prob(speech_prob))
|
||||
var/list/targets = INVOKE_EVENT(parent, /event/comp_ai_cmd_find_targets)
|
||||
for(var/mob/living/M in targets)
|
||||
if(M == src)
|
||||
continue
|
||||
if(M.isDead()) //No speaking to the dead
|
||||
continue
|
||||
listener = TRUE
|
||||
break
|
||||
if(listener)
|
||||
next_speech = world.time+speech_delay
|
||||
next_speech = world.time + speech_delay
|
||||
cmd_say()
|
||||
break
|
||||
|
||||
@@ -1,43 +1,44 @@
|
||||
/datum/component/ai/hearing
|
||||
var/hear_signal
|
||||
var/list/required_messages = list()
|
||||
var/list/hear_args
|
||||
var/response_delay = 10
|
||||
var/hear_signal
|
||||
var/list/required_messages = list()
|
||||
var/list/hear_args
|
||||
var/response_delay = 10
|
||||
|
||||
/datum/component/ai/hearing/initialize()
|
||||
parent.register_event(/event/comp_ai_cmd_hear, src, .proc/on_hear)
|
||||
return TRUE
|
||||
parent.register_event(/event/hear, src, .proc/on_hear)
|
||||
return TRUE
|
||||
|
||||
/datum/component/ai/hearing/Destroy()
|
||||
parent.unregister_event(/event/comp_ai_cmd_hear, src, .proc/on_hear)
|
||||
..()
|
||||
parent.unregister_event(/event/hear, src, .proc/on_hear)
|
||||
..()
|
||||
|
||||
/datum/component/ai/hearing/proc/on_hear(var/datum/speech/speech)
|
||||
var/filtered_message = speech.message
|
||||
filtered_message = replacetext(filtered_message , "?" , "") //Ignores punctuation.
|
||||
filtered_message = replacetext(filtered_message , "!" , "") //Ignores punctuation.
|
||||
filtered_message = replacetext(filtered_message , "." , "") //Ignores punctuation.
|
||||
filtered_message = replacetext(filtered_message , "," , "") //Ignores punctuation.
|
||||
if(speech.speaker != parent)
|
||||
if(!required_messages.len)
|
||||
sleep(response_delay)
|
||||
INVOKE_EVENT(parent, hear_signal, hear_args)
|
||||
else
|
||||
for(var/message in required_messages)
|
||||
if(findtext(filtered_message,message))
|
||||
sleep(response_delay)
|
||||
INVOKE_EVENT(parent, hear_signal, hear_args)
|
||||
return
|
||||
/datum/component/ai/hearing/proc/on_hear(datum/speech/speech)
|
||||
set waitfor = FALSE
|
||||
var/filtered_message = speech.message
|
||||
filtered_message = replacetext(filtered_message , "?" , "") //Ignores punctuation.
|
||||
filtered_message = replacetext(filtered_message , "!" , "") //Ignores punctuation.
|
||||
filtered_message = replacetext(filtered_message , "." , "") //Ignores punctuation.
|
||||
filtered_message = replacetext(filtered_message , "," , "") //Ignores punctuation.
|
||||
if(speech.speaker != parent)
|
||||
if(!required_messages.len)
|
||||
sleep(response_delay)
|
||||
INVOKE_EVENT(parent, hear_signal, hear_args)
|
||||
else
|
||||
for(var/message in required_messages)
|
||||
if(findtext(filtered_message,message))
|
||||
sleep(response_delay)
|
||||
INVOKE_EVENT(parent, hear_signal, hear_args)
|
||||
return
|
||||
|
||||
/datum/component/ai/hearing/say
|
||||
hear_signal = /event/comp_ai_cmd_say
|
||||
hear_signal = /event/comp_ai_cmd_say
|
||||
|
||||
/datum/component/ai/hearing/say_response
|
||||
hear_signal = /event/comp_ai_cmd_specific_say
|
||||
hear_signal = /event/comp_ai_cmd_specific_say
|
||||
|
||||
/datum/component/ai/hearing/say_response/time
|
||||
required_messages = list("what time is it","whats the time","do you have the time")
|
||||
required_messages = list("what time is it","whats the time","do you have the time")
|
||||
|
||||
/datum/component/ai/hearing/say_response/time/on_hear(var/datum/speech/speech)
|
||||
hear_args = list("The current time is [worldtime2text()].")
|
||||
..()
|
||||
hear_args = list("The current time is [worldtime2text()].")
|
||||
..()
|
||||
|
||||
@@ -244,7 +244,7 @@ var/list/headset_modes = list(
|
||||
if(V.spread & SPREAD_MEMETIC)
|
||||
infect_disease2(V, notes="(Memed, from [L])")
|
||||
|
||||
INVOKE_EVENT(src, /event/comp_ai_cmd_hear, "speech" = speech)
|
||||
INVOKE_EVENT(src, /event/hear, "speech" = speech)
|
||||
if(!client)
|
||||
return
|
||||
say_testing(src, "[src] ([src.type]) has heard a message (lang=[speech.language ? speech.language.name : "null"])")
|
||||
|
||||
Reference in New Issue
Block a user