Skip to content

Commit

Permalink
Merge branch 'tgstation:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Huz2e authored Dec 28, 2023
2 parents b375aa3 + 9b3b026 commit 57608d4
Show file tree
Hide file tree
Showing 76 changed files with 1,016 additions and 401 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tgs_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
env:
Database__DatabaseType: Sqlite
Database__ConnectionString: Data Source=TGS_TGTest.sqlite3;Mode=ReadWriteCreate
General__ConfigVersion: 4.1.0
General__ConfigVersion: 5.0.0
General__ApiPort: ${{ env.TGS_API_PORT }}
General__SetupWizardMode: Never
ports:
Expand All @@ -59,7 +59,7 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v2
with:
dotnet-version: 7.0.x
dotnet-version: 8.0.x

- name: Checkout Repository
uses: actions/checkout@v3
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/ai/monkey.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
#define BB_MONKEY_TARGET_MONKEYS "BB_monkey_target_monkeys"
#define BB_MONKEY_DISPOSING "BB_monkey_disposing"
#define BB_MONKEY_RECRUIT_COOLDOWN "BB_monkey_recruit_cooldown"
#define BB_RESISTING "BB_resisting"
10 changes: 7 additions & 3 deletions code/__DEFINES/dcs/signals/signals_material_container.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
/// Called from datum/component/material_container/proc/can_hold_material() : (mat)
#define COMSIG_MATCONTAINER_MAT_CHECK "matcontainer_mat_check"
#define MATCONTAINER_ALLOW_MAT (1<<0)
/// Called from datum/component/material_container/proc/user_insert() : (held_item, user)
/// Called from datum/component/material_container/proc/user_insert() : (target_item, user)
#define COMSIG_MATCONTAINER_PRE_USER_INSERT "matcontainer_pre_user_insert"
#define MATCONTAINER_BLOCK_INSERT (1<<1)
/// Called from datum/component/material_container/proc/insert_item() : (target, last_inserted_id, mats_consumed, material_amount, context)
/// Called from datum/component/material_container/proc/insert_item() : (item, primary_mat, mats_consumed, material_amount, context)
#define COMSIG_MATCONTAINER_ITEM_CONSUMED "matcontainer_item_consumed"
/// Called from datum/component/material_container/proc/retrieve_sheets() : (sheets, context)
/// Called from datum/component/material_container/proc/retrieve_sheets() : (new_sheets, context)
#define COMSIG_MATCONTAINER_SHEETS_RETRIEVED "matcontainer_sheets_retrieved"

//mat container signals but from the ore silo's perspective
/// Called from /obj/machinery/ore_silo/on_item_consumed() : (container, item_inserted, last_inserted_id, mats_consumed, amount_inserted)
#define COMSIG_SILO_ITEM_CONSUMED "silo_item_consumed"
2 changes: 2 additions & 0 deletions code/__DEFINES/dcs/signals/signals_moveloop.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@
#define COMSIG_MOVELOOP_POSTPROCESS "moveloop_postprocess"
//from [/datum/move_loop/has_target/jps/recalculate_path] ():
#define COMSIG_MOVELOOP_JPS_REPATH "moveloop_jps_repath"
///from [/datum/move_loop/has_target/jps/on_finish_pathing]
#define COMSIG_MOVELOOP_JPS_FINISHED_PATHING "moveloop_jps_finished_pathing"
1 change: 1 addition & 0 deletions code/__DEFINES/wall_dents.dm
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#define WALL_DENT_HIT 1
#define WALL_DENT_SHOT 2
#define MAX_DENT_DECALS 15
6 changes: 0 additions & 6 deletions code/__DEFINES/wires.dm
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@
#define WIRE_ZAP1 "High Voltage Circuit 1"
#define WIRE_ZAP2 "High Voltage Circuit 2"
#define WIRE_OVERCLOCK "Overclock"
#define WIRE_VALVE "Valve"
#define WIRE_SHIELDING "Shielding"
#define WIRE_REGULATOR_MIN "Minimize Regulator Pressure"
#define WIRE_REGULATOR_MAX "Maximize Regulator Pressure"
#define WIRE_TANK_EJECT "Eject Tank"
#define WIRE_REACTION_SUPPRESSION "Reaction Suppression"

// Wire states for the AI
#define AI_WIRE_NORMAL 0
Expand Down
10 changes: 8 additions & 2 deletions code/controllers/subsystem/movement/movement_types.dm
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
turf/avoid,
skip_first,
subsystem,
diagonal_handling,
priority,
flags,
datum/extra_info,
Expand All @@ -343,6 +344,7 @@
simulated_only,
avoid,
skip_first,
diagonal_handling,
initial_path)

/datum/move_loop/has_target/jps
Expand All @@ -360,6 +362,8 @@
var/turf/avoid
///Should we skip the first step? This is the tile we're currently on, which breaks some things
var/skip_first
///Whether we replace diagonal movements with cardinal movements or follow through with them
var/diagonal_handling
///A list for the path we're currently following
var/list/movement_path
///Cooldown for repathing, prevents spam
Expand All @@ -373,7 +377,7 @@
. = ..()
on_finish_callbacks += CALLBACK(src, PROC_REF(on_finish_pathing))

/datum/move_loop/has_target/jps/setup(delay, timeout, atom/chasing, repath_delay, max_path_length, minimum_distance, list/access, simulated_only, turf/avoid, skip_first, list/initial_path)
/datum/move_loop/has_target/jps/setup(delay, timeout, atom/chasing, repath_delay, max_path_length, minimum_distance, list/access, simulated_only, turf/avoid, skip_first, diagonal_handling, list/initial_path)
. = ..()
if(!.)
return
Expand All @@ -384,6 +388,7 @@
src.simulated_only = simulated_only
src.avoid = avoid
src.skip_first = skip_first
src.diagonal_handling = diagonal_handling
movement_path = initial_path?.Copy()

/datum/move_loop/has_target/jps/compare_loops(datum/move_loop/loop_type, priority, flags, extra_info, delay, timeout, atom/chasing, repath_delay, max_path_length, minimum_distance, list/access, simulated_only, turf/avoid, skip_first, initial_path)
Expand All @@ -410,14 +415,15 @@
if(!COOLDOWN_FINISHED(src, repath_cooldown))
return
COOLDOWN_START(src, repath_cooldown, repath_delay)
if(SSpathfinder.pathfind(moving, target, max_path_length, minimum_distance, access, simulated_only, avoid, skip_first, on_finish = on_finish_callbacks))
if(SSpathfinder.pathfind(moving, target, max_path_length, minimum_distance, access, simulated_only, avoid, skip_first, diagonal_handling, on_finish = on_finish_callbacks))
is_pathing = TRUE
SEND_SIGNAL(src, COMSIG_MOVELOOP_JPS_REPATH)

///Called when a path has finished being created
/datum/move_loop/has_target/jps/proc/on_finish_pathing(list/path)
movement_path = path
is_pathing = FALSE
SEND_SIGNAL(src, COMSIG_MOVELOOP_JPS_FINISHED_PATHING, path)

/datum/move_loop/has_target/jps/move()
if(!length(movement_path))
Expand Down
20 changes: 17 additions & 3 deletions code/controllers/subsystem/persistence/_persistence.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,23 @@ SUBSYSTEM_DEF(persistence)
var/list/blocked_maps = list()
var/list/saved_trophies = list()
var/list/picture_logging_information = list()
var/list/obj/structure/sign/picture_frame/photo_frames
var/list/obj/item/storage/photo_album/photo_albums

/// A json_database linking to data/photo_frames.json.
/// Schema is persistence_id => array of photo names.
var/datum/json_database/photo_frames_database

/// A lazy list of every picture frame that is going to be loaded with persistent photos.
/// Will be null'd once the persistence system initializes, and never read from again.
var/list/obj/structure/sign/picture_frame/queued_photo_frames

/// A json_database linking to data/photo_albums.json.
/// Schema is persistence_id => array of photo names.
var/datum/json_database/photo_albums_database

/// A lazy list of every photo album that is going to be loaded with persistent photos.
/// Will be null'd once the persistence system initializes, and never read from again.
var/list/obj/item/storage/photo_album/queued_photo_albums

var/rounds_since_engine_exploded = 0
var/delam_highscore = 0
var/tram_hits_this_round = 0
Expand All @@ -47,7 +62,6 @@ SUBSYSTEM_DEF(persistence)
save_prisoner_tattoos()
collect_trophies()
collect_maps()
save_photo_persistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION.
save_randomized_recipes()
save_scars()
save_custom_outfits()
Expand Down
79 changes: 14 additions & 65 deletions code/controllers/subsystem/persistence/photo_albums.dm
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
///Loads up the photo album source file.
/datum/controller/subsystem/persistence/proc/get_photo_albums()
var/album_path = file("data/photo_albums.json")
if(fexists(album_path))
return json_decode(file2text(album_path))

///Loads up the photo frames source file.
/datum/controller/subsystem/persistence/proc/get_photo_frames()
var/frame_path = file("data/photo_frames.json")
if(fexists(frame_path))
return json_decode(file2text(frame_path))

/// Removes the identifier of a persistent photo frame from the json.
/datum/controller/subsystem/persistence/proc/remove_photo_frames(identifier)
var/frame_path = file("data/photo_frames.json")
Expand All @@ -25,62 +13,23 @@

///Loads photo albums, and populates them; also loads and applies frames to picture frames.
/datum/controller/subsystem/persistence/proc/load_photo_persistence()
var/album_path = file("data/photo_albums.json")
var/frame_path = file("data/photo_frames.json")
if(fexists(album_path))
var/list/json = json_decode(file2text(album_path))
if(json.len)
for(var/i in photo_albums)
var/obj/item/storage/photo_album/A = i
if(!A.persistence_id)
continue
if(json[A.persistence_id])
A.populate_from_id_list(json[A.persistence_id])

if(fexists(frame_path))
var/list/json = json_decode(file2text(frame_path))
if(json.len)
for(var/i in photo_frames)
var/obj/structure/sign/picture_frame/PF = i
if(!PF.persistence_id)
continue
if(json[PF.persistence_id])
PF.load_from_id(json[PF.persistence_id])

///Saves the contents of photo albums and the picture frames.
/datum/controller/subsystem/persistence/proc/save_photo_persistence()
var/album_path = file("data/photo_albums.json")
var/frame_path = file("data/photo_frames.json")

var/list/frame_json = list()
var/list/album_json = list()

if(fexists(album_path))
album_json = json_decode(file2text(album_path))
fdel(album_path)

for(var/i in photo_albums)
var/obj/item/storage/photo_album/A = i
if(!istype(A) || !A.persistence_id)
photo_albums_database = new("data/photo_albums.json")
for (var/obj/item/storage/photo_album/album as anything in queued_photo_albums)
if (isnull(album.persistence_id))
continue
var/list/L = A.get_picture_id_list()
album_json[A.persistence_id] = L

album_json = json_encode(album_json)

WRITE_FILE(album_path, album_json)

if(fexists(frame_path))
frame_json = json_decode(file2text(frame_path))
fdel(frame_path)
var/album_data = photo_albums_database.get_key(album.persistence_id)
if (!isnull(album_data))
album.populate_from_id_list(album_data)

for(var/i in photo_frames)
var/obj/structure/sign/picture_frame/F = i
if(!istype(F) || !F.persistence_id)
photo_frames_database = new("data/photo_frames.json")
for (var/obj/structure/sign/picture_frame/frame as anything in queued_photo_frames)
if (isnull(frame.persistence_id))
continue
frame_json[F.persistence_id] = F.get_photo_id()

frame_json = json_encode(frame_json)

WRITE_FILE(frame_path, frame_json)
var/frame_data = photo_frames_database.get_key(frame.persistence_id)
if (!isnull(frame_data))
frame.load_from_id(frame_data)

queued_photo_albums = null
queued_photo_frames = null
1 change: 1 addition & 0 deletions code/datums/ai/_ai_controller.dm
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ multiple modular subtrees with behaviors

///Runs any actions that are currently running
/datum/ai_controller/process(seconds_per_tick)

if(!able_to_run())
SSmove_manager.stop_looping(pawn) //stop moving
return //this should remove them from processing in the future through event-based stuff.
Expand Down
11 changes: 6 additions & 5 deletions code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/// List of objects that AIs will treat as targets
GLOBAL_LIST_EMPTY_TYPED(hostile_machines, /atom)

/datum/ai_behavior/find_potential_targets
action_cooldown = 2 SECONDS
/// How far can we see stuff?
var/vision_range = 9
/// Blackboard key for aggro range, uses vision range if not specified
var/aggro_range_key = BB_AGGRO_RANGE
/// Static typecache list of potentially dangerous objs
var/static/list/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/vehicle/sealed/mecha))

/datum/ai_behavior/find_potential_targets/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
. = ..()
Expand All @@ -26,9 +27,9 @@

var/list/potential_targets = hearers(aggro_range, get_turf(controller.pawn)) - living_mob //Remove self, so we don't suicide

for(var/HM in typecache_filter_list(range(aggro_range, living_mob), hostile_machines)) //Can we see any hostile machines?
if(can_see(living_mob, HM, aggro_range))
potential_targets += HM
for (var/atom/hostile_machine as anything in GLOB.hostile_machines)
if (can_see(living_mob, hostile_machine, aggro_range))
potential_targets += hostile_machine

if(!potential_targets.len)
finish_action(controller, succeeded = FALSE)
Expand Down
1 change: 1 addition & 0 deletions code/datums/ai/generic/generic_behaviors.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/datum/ai_behavior/resist/perform(seconds_per_tick, datum/ai_controller/controller)
. = ..()
var/mob/living/living_pawn = controller.pawn
living_pawn.ai_controller.set_blackboard_key(BB_RESISTING, TRUE)
living_pawn.execute_resist()
finish_action(controller, TRUE)

Expand Down
15 changes: 14 additions & 1 deletion code/datums/ai/monkey/monkey_controller.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,22 @@ have ways of interacting with a specific mob and control it.
BB_MONKEY_GUN_NEURONS_ACTIVATED = FALSE,
BB_MONKEY_GUN_WORKED = TRUE,
BB_SONG_LINES = MONKEY_SONG,
BB_RESISTING = FALSE,
)
idle_behavior = /datum/idle_behavior/idle_monkey

/datum/ai_controller/monkey/process(seconds_per_tick)

var/mob/living/living_pawn = src.pawn

if(!length(living_pawn.do_afters) && living_pawn.ai_controller.blackboard[BB_RESISTING])
living_pawn.ai_controller.set_blackboard_key(BB_RESISTING, FALSE)

if(living_pawn.ai_controller.blackboard[BB_RESISTING])
return

. = ..()

/datum/ai_controller/monkey/New(atom/new_pawn)
var/static/list/control_examine = list(
ORGAN_SLOT_EYES = span_monkey("eyes have a primal look in them."),
Expand Down Expand Up @@ -91,7 +104,7 @@ have ways of interacting with a specific mob and control it.
/datum/ai_controller/monkey/able_to_run()
var/mob/living/living_pawn = pawn

if(IS_DEAD_OR_INCAP(living_pawn))
if(living_pawn.incapacitated(IGNORE_RESTRAINTS | IGNORE_GRAB | IGNORE_STASIS) || living_pawn.stat > CONSCIOUS)
return FALSE
return ..()

Expand Down
15 changes: 14 additions & 1 deletion code/datums/ai/movement/ai_movement_jps.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,32 @@
/datum/ai_movement/jps
max_pathing_attempts = 20
var/maximum_length = AI_MAX_PATH_LENGTH
///how we deal with diagonal movement, whether we try to avoid them or follow through with them
var/diagonal_flags = DIAGONAL_REMOVE_CLUNKY

/datum/ai_movement/jps/start_moving_towards(datum/ai_controller/controller, atom/current_movement_target, min_distance)
. = ..()
var/atom/movable/moving = controller.pawn
var/delay = controller.movement_delay

var/datum/move_loop/loop = SSmove_manager.jps_move(moving,
var/datum/move_loop/has_target/jps/loop = SSmove_manager.jps_move(moving,
current_movement_target,
delay,
repath_delay = 0.5 SECONDS,
max_path_length = maximum_length,
minimum_distance = controller.get_minimum_distance(),
access = controller.get_access(),
subsystem = SSai_movement,
diagonal_handling = diagonal_flags,
extra_info = controller,
)

RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move))
RegisterSignal(loop, COMSIG_MOVELOOP_JPS_REPATH, PROC_REF(repath_incoming))

return loop

/datum/ai_movement/jps/proc/repath_incoming(datum/move_loop/has_target/jps/source)
SIGNAL_HANDLER
var/datum/ai_controller/controller = source.extra_info
Expand All @@ -35,3 +40,11 @@
/datum/ai_movement/jps/bot
max_pathing_attempts = 25
maximum_length = AI_BOT_PATH_LENGTH
diagonal_flags = DIAGONAL_REMOVE_ALL

/datum/ai_movement/jps/bot/start_moving_towards(datum/ai_controller/controller, atom/current_movement_target, min_distance)
var/datum/move_loop/loop = ..()
var/atom/our_pawn = controller.pawn
if(isnull(our_pawn))
return
our_pawn.RegisterSignal(loop, COMSIG_MOVELOOP_JPS_FINISHED_PATHING, TYPE_PROC_REF(/mob/living/basic/bot, generate_bot_path))
6 changes: 3 additions & 3 deletions code/datums/components/energized.dm
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
if(prob(100 - toast_prob))
if(prob(25))
do_sparks(1, FALSE, source)
playsound(src, SFX_SPARKS, 40, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
playsound(parent, SFX_SPARKS, 40, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
source.audible_message(span_danger("[parent] makes an electric crackle..."))
return FALSE

Expand Down Expand Up @@ -116,10 +116,10 @@
header = "Electrifying!",
)
do_sparks(4, FALSE, source)
playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
playsound(parent, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
source.audible_message(span_danger("[parent] makes a loud electric crackle!"))
to_chat(future_tram_victim, span_userdanger("You hear a loud electric crackle!"))
future_tram_victim.electrocute_act(15, src, 1)
future_tram_victim.electrocute_act(15, parent, 1)
return TRUE

#undef NORMAL_TOAST_PROB
Expand Down
Loading

0 comments on commit 57608d4

Please sign in to comment.