diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index b17485bfd3c..5011ff60733 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -6911,10 +6911,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) -"Fi" = ( -/obj/effect/landmark/basketball/game_area, -/turf/open/space/basic, -/area/space) "Fj" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/centcom{ @@ -36282,7 +36278,7 @@ aa aa aa aa -Fi +aa aa aa aa diff --git a/_maps/map_files/Basketball/ash_gladiators.dmm b/_maps/minigame/basketball/ash_gladiators.dmm similarity index 100% rename from _maps/map_files/Basketball/ash_gladiators.dmm rename to _maps/minigame/basketball/ash_gladiators.dmm diff --git a/_maps/map_files/Basketball/ass_blast_usa.dmm b/_maps/minigame/basketball/ass_blast_usa.dmm similarity index 100% rename from _maps/map_files/Basketball/ass_blast_usa.dmm rename to _maps/minigame/basketball/ass_blast_usa.dmm diff --git a/_maps/map_files/Basketball/beach_bums.dmm b/_maps/minigame/basketball/beach_bums.dmm similarity index 100% rename from _maps/map_files/Basketball/beach_bums.dmm rename to _maps/minigame/basketball/beach_bums.dmm diff --git a/_maps/map_files/Basketball/greytide_worldwide.dmm b/_maps/minigame/basketball/greytide_worldwide.dmm similarity index 100% rename from _maps/map_files/Basketball/greytide_worldwide.dmm rename to _maps/minigame/basketball/greytide_worldwide.dmm diff --git a/_maps/map_files/Basketball/lusty_xenomorphs.dmm b/_maps/minigame/basketball/lusty_xenomorphs.dmm similarity index 100% rename from _maps/map_files/Basketball/lusty_xenomorphs.dmm rename to _maps/minigame/basketball/lusty_xenomorphs.dmm diff --git a/_maps/map_files/Basketball/soviet_bear.dmm b/_maps/minigame/basketball/soviet_bear.dmm similarity index 100% rename from _maps/map_files/Basketball/soviet_bear.dmm rename to _maps/minigame/basketball/soviet_bear.dmm diff --git a/_maps/map_files/Basketball/space_surfers.dmm b/_maps/minigame/basketball/space_surfers.dmm similarity index 100% rename from _maps/map_files/Basketball/space_surfers.dmm rename to _maps/minigame/basketball/space_surfers.dmm diff --git a/_maps/map_files/Basketball/stadium.dmm b/_maps/minigame/basketball/stadium.dmm similarity index 100% rename from _maps/map_files/Basketball/stadium.dmm rename to _maps/minigame/basketball/stadium.dmm diff --git a/code/__HELPERS/lazy_templates.dm b/code/__HELPERS/lazy_templates.dm index 10b9b6dac16..87f51d9d129 100644 --- a/code/__HELPERS/lazy_templates.dm +++ b/code/__HELPERS/lazy_templates.dm @@ -9,6 +9,8 @@ GLOBAL_LIST_INIT(lazy_templates, generate_lazy_template_map()) . = list() for(var/datum/lazy_template/template as anything in subtypesof(/datum/lazy_template)) var/key = initial(template.key) + if(!key) // some subtypes like basketball and deathmatch have a base datum with no key + continue if(key in .) stack_trace("Found multiple lazy templates with the same key! '[key]'") .[key] = new template diff --git a/code/modules/basketball/basketball_map_loading.dm b/code/modules/basketball/basketball_map_loading.dm index 5ed18997dde..1dac2043668 100644 --- a/code/modules/basketball/basketball_map_loading.dm +++ b/code/modules/basketball/basketball_map_loading.dm @@ -1,9 +1,6 @@ /obj/effect/landmark/basketball name = "Basketball Map Spawner" -/obj/effect/landmark/basketball/game_area - name = "Basketball Game Location" - /obj/effect/landmark/basketball/team_spawn name = "Basketball Team Spawner" var/game_id = "basketball" @@ -35,66 +32,79 @@ flags_1 = NONE area_flags = UNIQUE_AREA | NOTELEPORT | NO_DEATH_MESSAGE | BLOCK_SUICIDE -/datum/map_template/basketball - should_place_on_top = FALSE +/datum/lazy_template/basketball + map_dir = "_maps/minigame/basketball" + place_on_top = TRUE + turf_reservation_type = /datum/turf_reservation/turf_not_baseturf + /// Map UI Name + var/name + /// Map Description var/description = "" /// The name of the basketball team var/team_name /// The basketball teams home stadium uniform var/home_team_uniform -/datum/map_template/basketball/stadium +/datum/lazy_template/basketball/stadium name = "Stadium" description = "The homecourt for the Nanotrasen Basketball Department." - mappath = "_maps/map_files/basketball/stadium.dmm" + map_name = "stadium" + key = "stadium" team_name = "Nanotrasen Basketball Department" home_team_uniform = /datum/outfit/basketball/nanotrasen -/datum/map_template/basketball/lusty_xenomorphs +/datum/lazy_template/basketball/lusty_xenomorphs name = "Lusty Xenomorphs Stadium" description = "The homecourt of the Lusty Xenomorphs." - mappath = "_maps/map_files/basketball/lusty_xenomorphs.dmm" + map_name = "lusty_xenomorphs" + key = "lusty_xenomorphs" team_name = "Lusty Xenomorphs" home_team_uniform = /datum/outfit/basketball/lusty_xenomorphs -/datum/map_template/basketball/space_surfers +/datum/lazy_template/basketball/space_surfers name = "Space Surfers Stadium" description = "The homecourt of the Space Surfers." - mappath = "_maps/map_files/basketball/space_surfers.dmm" + map_name = "space_surfers" + key = "space_surfers" team_name = "Space Surfers" home_team_uniform = /datum/outfit/basketball/space_surfers -/datum/map_template/basketball/greytide_worldwide +/datum/lazy_template/basketball/greytide_worldwide name = "Greytide Worldwide Stadium" description = "The homecourt of the Greytide Worldwide." - mappath = "_maps/map_files/basketball/greytide_worldwide.dmm" + map_name = "greytide_worldwide" + key = "greytide_worldwide" team_name = "Greytide Worldwide" home_team_uniform = /datum/outfit/basketball/greytide_worldwide -/datum/map_template/basketball/ass_blast_usa +/datum/lazy_template/basketball/ass_blast_usa name = "Ass Blast USA Stadium" description = "The homecourt of the Ass Blast USA." - mappath = "_maps/map_files/basketball/ass_blast_usa.dmm" + map_name = "ass_blast_usa" + key = "ass_blast_usa" team_name = "Ass Blast USA" home_team_uniform = /datum/outfit/basketball/ass_blast_usa -/datum/map_template/basketball/soviet_bears +/datum/lazy_template/basketball/soviet_bears name = "Soviet Bears Stadium" description = "The homecourt of the Soviet Bears." - mappath = "_maps/map_files/basketball/soviet_bears.dmm" + map_name = "soviet_bear" + key = "soviet_bear" team_name = "Soviet Bears" home_team_uniform = /datum/outfit/basketball/soviet_bears -/datum/map_template/basketball/ash_gladiators +/datum/lazy_template/basketball/ash_gladiators name = "Ash Gladiators Stadium" description = "The homecourt of the Ash Gladiators." - mappath = "_maps/map_files/basketball/ash_gladiators.dmm" + map_name = "ash_gladiators" + key = "ash_gladiators" team_name = "Ash Gladiators" home_team_uniform = /datum/outfit/basketball/ash_gladiators -/datum/map_template/basketball/beach_bums +/datum/lazy_template/basketball/beach_bums name = "Beach Bums Stadium" description = "The homecourt of the Beach Bums." - mappath = "_maps/map_files/basketball/beach_bums.dmm" + map_name = "beach_bums" + key = "beach_bums" team_name = "Beach Bums" home_team_uniform = /datum/outfit/basketball/beach_bums diff --git a/code/modules/basketball/controller.dm b/code/modules/basketball/controller.dm index d7f58f11903..de32aa766bb 100644 --- a/code/modules/basketball/controller.dm +++ b/code/modules/basketball/controller.dm @@ -18,26 +18,29 @@ GLOBAL_VAR(basketball_game) */ /datum/basketball_controller /// Template picked when the game starts. used for the name and desc reading - var/datum/map_template/basketball/current_map - /// Map generation tool that deletes the current map after the game finishes - var/datum/map_generator/massdelete/map_deleter + var/datum/lazy_template/basketball/current_map + /// Our turf reservation AKA where the arena is + var/datum/turf_reservation/location /// Total amount of time basketball is played for var/game_duration = 3 MINUTES /// List of all players ckeys involved in the minigame - var/list/minigame_players = list() + var/list/minigame_players_ckeys = list() + /// List of all player mobs involved in the minigame + var/list/minigame_basketball_mobs = list() /// Spawn points for home team players var/list/home_team_landmarks = list() /// List of home team players ckeys - var/list/home_team_players = list() + var/list/home_team_ckeys = list() + /// The basketball hoop used by home team var/obj/structure/hoop/minigame/home_hoop /// Spawn points for away team players var/list/away_team_landmarks = list() /// List of away team players ckeys - var/list/away_team_players = list() + var/list/away_team_ckeys = list() /// The basketball hoop used by away team var/obj/structure/hoop/minigame/away_hoop @@ -46,14 +49,17 @@ GLOBAL_VAR(basketball_game) /datum/basketball_controller/New() . = ..() + if(GLOB.basketball_game) + qdel(src) + CRASH("A basketball controller already exists.") GLOB.basketball_game = src - map_deleter = new /datum/basketball_controller/Destroy(force) . = ..() GLOB.basketball_game = null + current_map = null + location = null end_game() - qdel(map_deleter) /** * Triggers at beginning of the game when there is a confirmed list of valid, ready players. @@ -68,18 +74,13 @@ GLOBAL_VAR(basketball_game) * * ready_players: list of filtered, sane players (so not playing or disconnected) for the game to put into roles */ /datum/basketball_controller/proc/prepare_game(ready_players) - var/list/possible_maps = subtypesof(/datum/map_template/basketball) - var/turf/spawn_area = get_turf(locate(/obj/effect/landmark/basketball/game_area) in GLOB.landmarks_list) + var/list/possible_maps = subtypesof(/datum/lazy_template/basketball) current_map = pick(possible_maps) current_map = new current_map - - if(!spawn_area) - CRASH("No spawn area detected for Basketball Minigame!") - var/list/bounds = current_map.load(spawn_area) - if(!bounds) + location = current_map.lazy_load() + if(!location) CRASH("Loading basketball map failed!") - map_deleter.defineRegion(spawn_area, locate(spawn_area.x + 23, spawn_area.y + 25, spawn_area.z), replace = TRUE) //so we're ready to mass delete when round ends var/turf/home_hoop_turf = get_turf(locate(/obj/effect/landmark/basketball/team_spawn/home_hoop) in GLOB.landmarks_list) if(!home_hoop_turf) @@ -134,9 +135,8 @@ GLOBAL_VAR(basketball_game) * Called when the game is setting up, AFTER map is loaded but BEFORE the game start. Creates and places each body and gives the correct player key */ /datum/basketball_controller/proc/create_bodies(ready_players) - var/list/possible_away_teams = subtypesof(/datum/map_template/basketball) - current_map.type - var/datum/map_template/basketball/away_map = pick(possible_away_teams) - away_map = new away_map + var/list/possible_away_teams = subtypesof(/datum/lazy_template/basketball) - current_map.type + var/datum/lazy_template/basketball/away_map = pick(possible_away_teams) var/list/home_spawnpoints = home_team_landmarks.Copy() var/list/away_spawnpoints = away_team_landmarks.Copy() @@ -148,7 +148,7 @@ GLOBAL_VAR(basketball_game) // rename the hoops to their appropriate teams names home_hoop.name = current_map.team_name - away_hoop.name = away_map.team_name + away_hoop.name = away_map::team_name var/player_count = 0 // if total players is odd number then the odd man out is a referee @@ -156,7 +156,7 @@ GLOBAL_VAR(basketball_game) for(var/player_key in ready_players) player_count++ - minigame_players |= player_key + minigame_players_ckeys |= player_key var/is_player_referee = (player_count == length(ready_players) && minigame_has_referee) @@ -165,16 +165,16 @@ GLOBAL_VAR(basketball_game) team_uniform = /datum/outfit/basketball/referee else if(player_count % 2) // odd is home team spawn_landmark = pick_n_take(home_spawnpoints) - home_team_players |= player_key + home_team_ckeys |= player_key away_hoop.team_ckeys |= player_key // to restrict scoring on opponents hoop rapidly team_uniform = current_map.home_team_uniform team_name = current_map.team_name else // even is away team spawn_landmark = pick_n_take(away_spawnpoints) - away_team_players |= player_key + away_team_ckeys |= player_key home_hoop.team_ckeys |= player_key // to restrict scoring on opponents hoop rapidly - team_uniform = away_map.home_team_uniform - team_name = away_map.team_name + team_uniform = away_map::home_team_uniform + team_name = away_map::team_name var/mob/living/carbon/human/baller = new(get_turf(spawn_landmark)) @@ -199,6 +199,7 @@ GLOBAL_VAR(basketball_game) old_body = player_client.mob.mind.current, \ ) baller.PossessByPlayer(player_key) + minigame_basketball_mobs |= baller SEND_SOUND(baller, sound('sound/items/whistle/whistle.ogg', volume=30)) if(is_player_referee) @@ -221,34 +222,31 @@ GLOBAL_VAR(basketball_game) if(home_hoop.total_score == away_hoop.total_score) is_game_draw = TRUE - winner_team_ckeys |= home_team_players - winner_team_ckeys |= away_team_players + winner_team_ckeys |= home_team_ckeys + winner_team_ckeys |= away_team_ckeys else if(home_hoop.total_score > away_hoop.total_score) - winner_team_ckeys = away_team_players + winner_team_ckeys = away_team_ckeys winner_team_name = away_hoop.name - loser_team_ckeys = home_team_players + loser_team_ckeys = home_team_ckeys else if(home_hoop.total_score < away_hoop.total_score) - winner_team_ckeys = home_team_players + winner_team_ckeys = home_team_ckeys winner_team_name = home_hoop.name - loser_team_ckeys = away_team_players + loser_team_ckeys = away_team_ckeys if(is_game_draw) for(var/ckey in winner_team_ckeys) var/mob/living/competitor = get_mob_by_ckey(ckey) - var/area/mob_area = get_area(competitor) - if(istype(competitor) && istype(mob_area, /area/centcom/basketball)) + if(competitor in minigame_basketball_mobs) to_chat(competitor, span_hypnophrase("The game resulted in a draw!")) else for(var/ckey in winner_team_ckeys) var/mob/living/competitor = get_mob_by_ckey(ckey) - var/area/mob_area = get_area(competitor) - if(istype(competitor) && istype(mob_area, /area/centcom/basketball)) + if(competitor in minigame_basketball_mobs) to_chat(competitor, span_hypnophrase("[winner_team_name] team wins!")) for(var/ckey in loser_team_ckeys) var/mob/living/competitor = get_mob_by_ckey(ckey) - var/area/mob_area = get_area(competitor) - if(istype(competitor) && istype(mob_area, /area/centcom/basketball)) + if(competitor in minigame_basketball_mobs) to_chat(competitor, span_hypnophrase("[winner_team_name] team wins!")) competitor.dust() @@ -258,19 +256,20 @@ GLOBAL_VAR(basketball_game) * Cleans up the game, resetting variables back to the beginning and removing the map with the generator. */ /datum/basketball_controller/proc/end_game() - for(var/ckey in minigame_players) - var/mob/living/competitor = get_mob_by_ckey(ckey) - var/area/mob_area = get_area(competitor) - if(istype(competitor) && istype(mob_area, /area/centcom/basketball)) - QDEL_NULL(competitor) - - map_deleter.generate() //remove the map, it will be loaded at the start of the next one - QDEL_NULL(current_map) - - //map gen does not deal with landmarks + for(var/mob/living/living in minigame_basketball_mobs) + living.ghostize(can_reenter_corpse = FALSE) // avoids runtimes when a cliented mob is qdel'd + QDEL_LIST(minigame_basketball_mobs) QDEL_LIST(home_team_landmarks) QDEL_LIST(away_team_landmarks) QDEL_LIST(referee_landmark) + for(var/obj/effect/landmark/basketball/team_spawn/hoop in GLOB.landmarks_list) + qdel(hoop) + + for(var/turf/victimized_turf as anything in location.reserved_turfs) //remove this once clearing turf reservations is actually reliable + victimized_turf.empty() + current_map.reservations -= location + current_map = null + QDEL_NULL(location) /** * Called when enough players have signed up to fill a setup. DOESN'T NECESSARILY MEAN THE GAME WILL START.