Skip to content

Commit

Permalink
First pass on xeno special behaviors
Browse files Browse the repository at this point in the history
  • Loading branch information
morrowwolf committed Oct 30, 2023
1 parent f2c048f commit 071ebd3
Show file tree
Hide file tree
Showing 8 changed files with 394 additions and 177 deletions.
2 changes: 1 addition & 1 deletion code/controllers/subsystem/pathfinding.dm
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ SUBSYSTEM_DEF(xeno_pathfinding)
if(length(L))
for(var/i in L)
var/atom/A = i
distance_between += A.xeno_ai_obstacle(X, direction)
distance_between += A.xeno_ai_obstacle(X, direction, target)

if(distance_between < distances[neighbor])
distances[neighbor] = distance_between
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

/datum/component/ai_behavior_override/attack

/datum/component/ai_behavior_override/attack/check_behavior_validity(mob/living/carbon/xenomorph/checked_xeno, distance)
. = ..()

if(distance > 10)
return FALSE

return TRUE


/datum/component/ai_behavior_override/attack/process_override_behavior(mob/living/carbon/xenomorph/processing_xeno, delta_time)
. = ..()

if(processing_xeno.current_target == parent)
return FALSE

processing_xeno.current_target = parent
processing_xeno.resting = FALSE
if(prob(5))
processing_xeno.emote("hiss")

return FALSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
GLOBAL_LIST_EMPTY(all_ai_behavior_overrides)

/datum/component/ai_behavior_override

/// Icon file for the behavior attached to parent as game masters will see it
var/behavior_icon = 'icons/landmarks.dmi'

/// Specific icon state for the behavior attached to parent as game masters will see it
var/behavior_icon_state = "x2"

/// The actual image holder that sits on parent for game masters
var/image/behavior_image

/datum/component/ai_behavior_override/Initialize(...)
. = ..()

GLOB.all_ai_behavior_overrides += src

behavior_image = new(behavior_icon, parent, behavior_icon_state, layer = ABOVE_FLY_LAYER)

for(var/client/game_master in GLOB.game_masters)
game_master.images += behavior_image

/datum/component/ai_behavior_override/Destroy(force, silent, ...)
GLOB.all_ai_behavior_overrides -= src

for(var/client/game_master in GLOB.game_masters)
game_master.images -= behavior_image

QDEL_NULL(behavior_image)

. = ..()

/// Override this to check if we want our behavior to be valid for the checked_xeno, passes the common factor of "distance" which is the distance between the checked_xeno and src parent
/datum/component/ai_behavior_override/proc/check_behavior_validity(mob/living/carbon/xenomorph/checked_xeno, distance)
return FALSE

/// Processes what we want this behavior to do, return FALSE if we want to continue in the process_ai() proc or TRUE if we want to handle everything and have process_ai() return
/datum/component/ai_behavior_override/proc/process_override_behavior(mob/living/carbon/xenomorph/processing_xeno, delta_time)
SHOULD_NOT_SLEEP(TRUE)

return FALSE
134 changes: 105 additions & 29 deletions code/modules/admin/game_master/game_master.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@

/// Assoc list that holds our custom game master objectives, formatted as atom = objective_string
/// Holds our active game_masters
GLOBAL_LIST_EMPTY(game_masters)

/// List of assoc lists that hold "object_name", "objective_info", and "object_ref". Name of the objective, any info typed about the objective, and then a reference to be resolved of the object for passing through TGUI
GLOBAL_LIST_EMPTY(game_master_objectives)

/// Percentage of characters end up clear when sent via radio message
Expand Down Expand Up @@ -30,18 +33,26 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)

#define DEFAULT_XENO_AMOUNT_TO_SPAWN 1

// Behavior stuff
#define DEFAULT_BEHAVIOR_STRING "Attack"
#define SELECTABLE_XENO_BEHAVIORS list("Attack")
#define SELECTABLE_XENO_BEHAVIORS_ASSOC list("Attack" = /datum/component/ai_behavior_override/attack)

// Objective stuff
#define OBJECTIVE_NUMBER_OPTIONS list("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine")
#define OBJECTIVE_COLOR_OPTIONS list("red", "purple", "blue")
#define OBJECTIVE_COLOR_OPTIONS_ASSOC list("red" = COLOR_RED, "purple" = COLOR_PURPLE, "blue" = COLOR_BLUE)

/// Types of click intercepts used by /datum/game_master variable current_click_intercept_action
#define SPAWN_CLICK_INTERCEPT_ACTION "spawn_click_intercept_action"
#define BEHAVIOR_CLICK_INTERCEPT_ACTION "behavior_click_intercept_action"
#define OBJECTIVE_CLICK_INTERCEPT_ACTION "objective_click_intercept_action"


/datum/game_master

var/client/game_master_client

/// Associated list of game master submenus organized by object_type = game_master_submenu
var/list/submenu_types = list(
/obj/structure/pipes/vents/scrubber = /datum/game_master_submenu/vents,
Expand All @@ -51,8 +62,10 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)
/// List of current submenus
var/list/current_submenus

/// Holds what type of click intercept we are using
var/current_click_intercept_action

/// Spawn stuff
// Spawn stuff

/// The xeno selected to be spawned in the spawn section
var/selected_xeno = DEFAULT_SPAWN_XENO_STRING
Expand All @@ -66,43 +79,58 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)
/// If we are currently using the click intercept for the spawn section
var/spawn_click_intercept = FALSE

/// End Spawn Stuff

/// Objective stuff
// Behavior stuff

/// The current behavior to add when clicking with behavior_click_intercept on
var/selected_behavior = DEFAULT_BEHAVIOR_STRING

/// If we are currently using click intercept for the behavior section
var/behavior_click_intercept = FALSE


// Objective stuff

/// If we are currently using the click intercept for the objective section
var/objective_click_intercept = FALSE

/// End Objective Stuff

// Communication stuff

/// Communication stuff

/// The holder for the game master's virtual phone
var/atom/movable/game_master_phone

/// End Communication stuff

/// Holds what type of click intercept we are using
var/current_click_intercept_action

/datum/game_master/New(client/using_client)
. = ..()

tgui_interact(using_client.mob)
game_master_client = using_client

tgui_interact(game_master_client.mob)

current_submenus = list()

game_master_phone = new(null)
game_master_phone.AddComponent(/datum/component/phone/virtual, "Game Master", "white", "Company Command", null, PHONE_DO_NOT_DISTURB_ON, list(FACTION_MARINE, FACTION_COLONIST, FACTION_WY), list(FACTION_MARINE, FACTION_COLONIST, FACTION_WY), null, using_client)

using_client.click_intercept = src
game_master_client.click_intercept = src

for(var/datum/component/ai_behavior_override/override in GLOB.all_ai_behavior_overrides)
game_master_client.images += override.behavior_image

GLOB.game_masters += game_master_client

/datum/game_master/Destroy(force, ...)
. = ..()
submenu_types = null
current_submenus = null
QDEL_NULL(game_master_phone)

for(var/datum/component/ai_behavior_override/override in GLOB.all_ai_behavior_overrides)
game_master_client.images -= override.behavior_image

GLOB.game_masters -= game_master_client

/datum/game_master/ui_data(mob/user)
. = ..()

Expand All @@ -114,6 +142,10 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)
data["spawn_click_intercept"] = spawn_click_intercept
data["xeno_spawn_count"] = xeno_spawn_count

// Behavior stuff
data["selected_behavior"] = selected_behavior
data["behavior_click_intercept"] = behavior_click_intercept

// Objective stuff
data["objective_click_intercept"] = objective_click_intercept
data["game_master_objectives"] = length(GLOB.game_master_objectives) ? GLOB.game_master_objectives : ""
Expand All @@ -130,6 +162,8 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)

data["spawnable_xenos"] = GAME_MASTER_AI_XENOS

data["selectable_behaviors"] = SELECTABLE_XENO_BEHAVIORS

return data

/datum/game_master/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
Expand All @@ -138,31 +172,31 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)
switch(action)

//Spawn Section
if("toggle_click_spawn")
if(spawn_click_intercept)
spawn_click_intercept = FALSE
current_click_intercept_action = null
if("set_xeno_spawns")
var/new_number = text2num(params["value"])
if(!new_number)
return

spawn_click_intercept = TRUE
current_click_intercept_action = SPAWN_CLICK_INTERCEPT_ACTION
return

if("xeno_spawn_ai_toggle")
spawn_ai = !spawn_ai
xeno_spawn_count = clamp(new_number, 1, 10)
return

if("set_selected_xeno")
selected_xeno = params["new_xeno"]
xeno_spawn_count = DEFAULT_XENO_AMOUNT_TO_SPAWN
return

if("set_xeno_spawns")
var/new_number = text2num(params["value"])
if(!new_number)
if("xeno_spawn_ai_toggle")
spawn_ai = !spawn_ai
return

if("toggle_click_spawn")
if(spawn_click_intercept)
reset_click_overrides()
return

xeno_spawn_count = clamp(new_number, 1, 10)
reset_click_overrides()
spawn_click_intercept = TRUE
current_click_intercept_action = SPAWN_CLICK_INTERCEPT_ACTION
return

if("delete_all_xenos")
Expand All @@ -174,13 +208,28 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)

return

//Behavior Section
if("set_selected_behavior")
selected_behavior = params["new_behavior"]
return

if("toggle_click_behavior")
if(behavior_click_intercept)
reset_click_overrides()
return

reset_click_overrides()
behavior_click_intercept = TRUE
current_click_intercept_action = BEHAVIOR_CLICK_INTERCEPT_ACTION
return

//Objective Section
if("toggle_click_objective")
if(objective_click_intercept)
objective_click_intercept = FALSE
current_click_intercept_action = null
reset_click_overrides()
return

reset_click_overrides()
objective_click_intercept = TRUE
current_click_intercept_action = OBJECTIVE_CLICK_INTERCEPT_ACTION
return
Expand Down Expand Up @@ -222,6 +271,7 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)

spawn_click_intercept = FALSE
objective_click_intercept = FALSE
behavior_click_intercept = FALSE
current_click_intercept_action = null

/datum/game_master/ui_status(mob/user, datum/ui_state/state)
Expand Down Expand Up @@ -259,6 +309,18 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)

return TRUE

if(BEHAVIOR_CLICK_INTERCEPT_ACTION)
var/behavior_type = SELECTABLE_XENO_BEHAVIORS_ASSOC[selected_behavior]

if(LAZYACCESS(modifiers, MIDDLE_CLICK))
if(object.datum_components[behavior_type])
var/component_to_remove = object.datum_components[behavior_type]
qdel(component_to_remove)
return TRUE

object.AddComponent(behavior_type)
return TRUE

if(OBJECTIVE_CLICK_INTERCEPT_ACTION)
var/turf/object_turf = get_turf(object)

Expand Down Expand Up @@ -329,6 +391,12 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)

return TRUE

/datum/game_master/proc/reset_click_overrides()
spawn_click_intercept = FALSE
objective_click_intercept = FALSE
behavior_click_intercept = FALSE
current_click_intercept_action = null

/datum/game_master/proc/remove_objective(datum/destroying_datum)
SIGNAL_HANDLER

Expand All @@ -338,11 +406,19 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100)
GLOB.game_master_objectives.Remove(list(cycled_objective))
UnregisterSignal(objective_object, COMSIG_PARENT_QDELETING)



#undef DEFAULT_SPAWN_XENO_STRING
#undef GAME_MASTER_AI_XENOS
#undef DEFAULT_XENO_AMOUNT_TO_SPAWN

#undef OBJECTIVE_NUMBER_OPTIONS
#undef OBJECTIVE_COLOR_OPTIONS
#undef OBJECTIVE_COLOR_OPTIONS_ASSOC

#undef DEFAULT_BEHAVIOR_STRING
#undef SELECTABLE_XENO_BEHAVIORS
#undef SELECTABLE_XENO_BEHAVIORS_ASSOC

#undef SPAWN_CLICK_INTERCEPT_ACTION
#undef OBJECTIVE_CLICK_INTERCEPT_ACTION
Loading

0 comments on commit 071ebd3

Please sign in to comment.