mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-30 00:21:11 +01:00
Landmark Shuttles (#8512)
The lifeless live again. Or in this case, what never actually lived here. Ports Baystation12/Baystation12#17460 probably for real this time. What this allows us to do is create shuttles on runtime and make shuttles easier by just making landmarks and a shuttle instead of areas and shuttles. Also allows runtime landmark creation via flares or whatever AND allows shuttles to use different landmarks at will. I removed most of the overmap stuff, I think. It shouldn't be hard to slam it in whenever we need to. Changes: "Shuttle code has been completely reworked." "Shuttles can now be modified to have more than one destination." "Shuttles now have a takeoff sound." "You can now throw mobs against walls to damage them. A lot." "You now need a neckgrab to throw mobs." "BEING UNBUCKLED DURING SHUTTLE LAUNCH IS DANGEROUS! Don't do it." "Adminghosts can now interact with all shuttles."
This commit is contained in:
@@ -45,31 +45,27 @@
|
||||
// Turf matches, add it.
|
||||
. += T
|
||||
|
||||
// Moves the contents of this area to A. If turf_to_leave is defined, that type will be excluded from the area.
|
||||
/area/proc/move_contents_to(area/A, turf_to_leave = null)
|
||||
var/list/source_turfs = src.build_ordered_turf_list(turf_to_leave)
|
||||
var/list/target_turfs = A.build_ordered_turf_list()
|
||||
/area/proc/move_contents_to(var/area/A)
|
||||
//Takes: Area.
|
||||
//Returns: Nothing.
|
||||
//Notes: Attempts to move the contents of one area to another area.
|
||||
// Movement based on lower left corner.
|
||||
|
||||
ASSERT(source_turfs.len == target_turfs.len)
|
||||
if(!A || !src) return
|
||||
|
||||
for (var/i = 1 to source_turfs.len)
|
||||
var/turf/ST = source_turfs[i]
|
||||
if (!ST) // Excluded turfs are null to keep the list ordered.
|
||||
continue
|
||||
var/list/turfs_src = get_area_turfs("\ref[src]")
|
||||
|
||||
if(istype(ST, /turf/unsimulated) || istype(ST, /turf/space))
|
||||
ST.ChangeTurf(A.base_turf, 1, 0, 1)
|
||||
if(!turfs_src.len)
|
||||
return
|
||||
|
||||
var/turf/TT = ST.copy_turf(target_turfs[i])
|
||||
//figure out a suitable origin - this assumes the shuttle areas are the exact same size and shape
|
||||
//might be worth doing this with a shuttle core object instead of areas, in the future
|
||||
var/src_origin = locate(src.x, src.y, src.z)
|
||||
var/trg_origin = locate(A.x, A.y, A.z)
|
||||
|
||||
for (var/thing in ST)
|
||||
var/atom/movable/AM = thing
|
||||
AM.shuttle_move(TT)
|
||||
|
||||
ST.ChangeTurf(ST.baseturf)
|
||||
|
||||
TT.update_icon()
|
||||
TT.update_above()
|
||||
if(src_origin && trg_origin)
|
||||
var/translation = get_turf_translation(src_origin, trg_origin, turfs_src)
|
||||
translate_turfs(translation, null)
|
||||
|
||||
// Called when a movable area wants to move this object.
|
||||
/atom/movable/proc/shuttle_move(turf/loc)
|
||||
|
||||
+102
-49
@@ -1,55 +1,108 @@
|
||||
//Takes: Area type as text string or as typepath OR an instance of the area.
|
||||
//Returns: A list of all turfs in areas of that type of that type in the world.
|
||||
/proc/get_area_turfs(areatype, var/list/predicates, target_z = 0, subtypes=TRUE)
|
||||
if(istext(areatype))
|
||||
areatype = text2path(areatype)
|
||||
else if(isarea(areatype))
|
||||
var/area/areatemp = areatype
|
||||
areatype = areatemp.type
|
||||
else if(!ispath(areatype))
|
||||
return null
|
||||
/*
|
||||
List generation helpers
|
||||
*/
|
||||
/proc/get_filtered_areas(var/list/predicates = list(/proc/is_area_with_turf))
|
||||
. = list()
|
||||
if(!predicates)
|
||||
return
|
||||
if(!islist(predicates))
|
||||
predicates = list(predicates)
|
||||
for(var/area/A)
|
||||
if(all_predicates_true(list(A), predicates))
|
||||
. += A
|
||||
|
||||
var/list/turfs = list()
|
||||
if(subtypes)
|
||||
var/list/cache = typecacheof(areatype)
|
||||
for(var/V in all_areas)
|
||||
var/area/A = V
|
||||
if(!cache[A.type])
|
||||
continue
|
||||
for(var/turf/T in A)
|
||||
CHECK_TICK
|
||||
if(target_z == 0 || target_z == T.z)
|
||||
if (predicates && predicates.len)
|
||||
var/predicates_true = TRUE
|
||||
for (var/predicate in predicates)
|
||||
if (!call(predicate)(T))
|
||||
predicates_true = FALSE
|
||||
break
|
||||
if (predicates_true)
|
||||
turfs += T
|
||||
else
|
||||
turfs += T
|
||||
else
|
||||
for(var/V in all_areas)
|
||||
var/area/A = V
|
||||
if(A.type != areatype)
|
||||
continue
|
||||
for(var/turf/T in A)
|
||||
CHECK_TICK
|
||||
if (target_z == 0 || target_z == T.z)
|
||||
if (predicates && predicates.len)
|
||||
var/predicates_true = TRUE
|
||||
for (var/predicate in predicates)
|
||||
if (!call(predicate)(T))
|
||||
predicates_true = FALSE
|
||||
break
|
||||
if (predicates_true)
|
||||
turfs += T
|
||||
else
|
||||
turfs += T
|
||||
return turfs
|
||||
/proc/get_area_turfs(var/area/A, var/list/predicates)
|
||||
. = new/list()
|
||||
A = istype(A) ? A : locate(A)
|
||||
if(!A)
|
||||
return
|
||||
for(var/turf/T in A.contents)
|
||||
if(!predicates || all_predicates_true(list(T), predicates))
|
||||
. += T
|
||||
|
||||
/proc/get_subarea_turfs(var/area/A, var/list/predicates)
|
||||
. = new/list()
|
||||
A = istype(A) ? A.type : A
|
||||
if(!ispath(A))
|
||||
return
|
||||
for(var/sub_area_type in typesof(A))
|
||||
var/area/sub_area = locate(sub_area_type)
|
||||
for(var/turf/T in sub_area.contents)
|
||||
if(!predicates || all_predicates_true(list(T), predicates))
|
||||
. += T
|
||||
|
||||
/proc/group_areas_by_name(var/list/predicates)
|
||||
. = list()
|
||||
for(var/area/A in get_filtered_areas(predicates))
|
||||
group_by(., A.name, A)
|
||||
|
||||
/proc/group_areas_by_z_level(var/list/predicates)
|
||||
. = list()
|
||||
var/enough_digits_to_contain_all_zlevels = 3
|
||||
for(var/area/A in get_filtered_areas(predicates))
|
||||
group_by(., add_zero(num2text(A.z), enough_digits_to_contain_all_zlevels), A)
|
||||
|
||||
/*
|
||||
Pick helpers
|
||||
*/
|
||||
/proc/pick_subarea_turf(var/areatype, var/list/predicates)
|
||||
var/list/turfs = get_subarea_turfs(areatype, predicates)
|
||||
if(LAZYLEN(turfs))
|
||||
return pick(turfs)
|
||||
|
||||
/proc/pick_area(var/list/predicates)
|
||||
var/list/areas = get_filtered_areas(predicates)
|
||||
if(LAZYLEN(areas))
|
||||
. = pick(areas)
|
||||
|
||||
/proc/pick_area_and_turf(var/list/area_predicates, var/list/turf_predicates)
|
||||
var/list/areas = get_filtered_areas(area_predicates)
|
||||
// We loop over all area candidates, until we finally get a valid turf or run out of areas
|
||||
while(!. && length(areas))
|
||||
var/area/A = pick_n_take(areas)
|
||||
. = pick_area_turf(A, turf_predicates)
|
||||
|
||||
/proc/pick_area_turf_in_connected_z_levels(var/list/area_predicates, var/list/turf_predicates, var/z_level)
|
||||
area_predicates = area_predicates.Copy()
|
||||
|
||||
var/z_levels = GetConnectedZlevels(z_level)
|
||||
area_predicates[/proc/area_belongs_to_zlevels] = z_levels
|
||||
return pick_area_and_turf(area_predicates, turf_predicates)
|
||||
|
||||
/proc/pick_area_turf(var/areatype, var/list/predicates)
|
||||
var/list/turfs = get_area_turfs(areatype, predicates)
|
||||
if(turfs && turfs.len)
|
||||
return pick(turfs)
|
||||
|
||||
/*
|
||||
Predicate Helpers
|
||||
*/
|
||||
/proc/area_belongs_to_zlevels(var/area/A, var/list/z_levels)
|
||||
. = (A.z in z_levels)
|
||||
|
||||
/proc/is_station_area(var/area/A)
|
||||
. = isStationLevel(A.z)
|
||||
|
||||
/proc/is_contact_area(var/area/A)
|
||||
. = isContactLevel(A.z)
|
||||
|
||||
/proc/is_player_area(var/area/A)
|
||||
. = isPlayerLevel(A.z)
|
||||
|
||||
/proc/is_not_space_area(var/area/A)
|
||||
. = !istype(A,/area/space)
|
||||
|
||||
/proc/is_not_shuttle_area(var/area/A)
|
||||
. = !istype(A,/area/shuttle)
|
||||
|
||||
/proc/is_area_with_turf(var/area/A)
|
||||
. = isnum(A.x)
|
||||
|
||||
/proc/is_area_without_turf(var/area/A)
|
||||
. = !is_area_with_turf(A)
|
||||
|
||||
/proc/is_maint_area(var/area/A)
|
||||
. = istype(A,/area/maintenance)
|
||||
|
||||
/proc/is_not_maint_area(var/area/A)
|
||||
. = !is_maint_area(A)
|
||||
@@ -690,3 +690,17 @@
|
||||
for(var/entry in L)
|
||||
if(istype(entry, type))
|
||||
. += entry
|
||||
|
||||
/proc/group_by(var/list/group_list, var/key, var/value)
|
||||
var/values = group_list[key]
|
||||
if(!values)
|
||||
values = list()
|
||||
group_list[key] = values
|
||||
|
||||
values += value
|
||||
|
||||
// Return a list of the values in an assoc list (including null)
|
||||
/proc/list_values(var/list/L)
|
||||
. = list()
|
||||
for(var/e in L)
|
||||
. += L[e]
|
||||
@@ -95,3 +95,59 @@
|
||||
if(pressure < SOUND_MINIMUM_PRESSURE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/*
|
||||
Turf manipulation
|
||||
*/
|
||||
|
||||
//Returns an assoc list that describes how turfs would be changed if the
|
||||
//turfs in turfs_src were translated by shifting the src_origin to the dst_origin
|
||||
/proc/get_turf_translation(turf/src_origin, turf/dst_origin, list/turfs_src)
|
||||
var/list/turf_map = list()
|
||||
for(var/turf/source in turfs_src)
|
||||
var/x_pos = (source.x - src_origin.x)
|
||||
var/y_pos = (source.y - src_origin.y)
|
||||
var/z_pos = (source.z - src_origin.z)
|
||||
|
||||
var/turf/target = locate(dst_origin.x + x_pos, dst_origin.y + y_pos, dst_origin.z + z_pos)
|
||||
if(!target)
|
||||
error("Null turf in translation @ ([dst_origin.x + x_pos], [dst_origin.y + y_pos], [dst_origin.z + z_pos])")
|
||||
turf_map[source] = target //if target is null, preserve that information in the turf map
|
||||
|
||||
return turf_map
|
||||
|
||||
|
||||
/proc/translate_turfs(var/list/translation, var/area/base_area = null, var/turf/base_turf)
|
||||
for(var/turf/source in translation)
|
||||
|
||||
var/turf/target = translation[source]
|
||||
|
||||
if(target)
|
||||
if(base_area)
|
||||
ChangeArea(target, get_area(source))
|
||||
ChangeArea(source, base_area)
|
||||
transport_turf_contents(source, target)
|
||||
|
||||
//change the old turfs
|
||||
for(var/turf/source in translation)
|
||||
source.ChangeTurf(base_turf ? base_turf : get_base_turf_by_area(source), 1, 1)
|
||||
|
||||
//Transports a turf from a source turf to a target turf, moving all of the turf's contents and making the target a copy of the source.
|
||||
/proc/transport_turf_contents(turf/source, turf/target)
|
||||
|
||||
var/turf/new_turf = target.ChangeTurf(source.type, 1, 1)
|
||||
new_turf.transport_properties_from(source)
|
||||
|
||||
for(var/obj/O in source)
|
||||
if(O.simulated)
|
||||
O.forceMove(new_turf)
|
||||
else if(istype(O,/obj/effect))
|
||||
var/obj/effect/E = O
|
||||
if(E.movable_flags & MOVABLE_FLAG_EFFECTMOVE)
|
||||
E.forceMove(new_turf)
|
||||
|
||||
for(var/mob/M in source)
|
||||
if(isEye(M)) continue // If we need to check for more mobs, I'll add a variable
|
||||
M.forceMove(new_turf)
|
||||
|
||||
return new_turf
|
||||
|
||||
Reference in New Issue
Block a user