mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-05-19 05:09:49 +01:00
9f124e5b14
* Initial * Remove corrupt dmis * Fixup maps in TGM format4e5a32721f: maps/_templates_and_guidance/Public Event Templates/Maze_Reward_-_Copy.dmm4e5a32721f: maps/_templates_and_guidance/Templates/shelter_Medical.dmm4e5a32721f: maps/expedition_vr/aerostat/aerostat.dmm4e5a32721f: maps/expedition_vr/aerostat/aerostat_science_outpost.dmm4e5a32721f: maps/expedition_vr/beach/submaps/deadBeacon.dmm4e5a32721f: maps/expedition_vr/wild/tether_wild-crash-alt.dmm4e5a32721f: maps/expedition_vr/wild/tether_wild-crash.dmm4e5a32721f: maps/expedition_vr/wild/tether_wild-surface.dmm4e5a32721f: maps/expedition_vr/wild/tether_wild-temple.dmm4e5a32721f: maps/gateway_vr/lucky_7.dmm4e5a32721f: maps/gateway_vr/snow_outpost.dmm4e5a32721f: maps/overmap/_map.dmm4e5a32721f: maps/overmap/bearcat/bearcat.dmm4e5a32721f: maps/overmap/example_sector1.dmm4e5a32721f: maps/overmap/example_sector2.dmm4e5a32721f: maps/redgate/falls/falls.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/CaveS.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/DeadSettlers1.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/DeadSettlers2.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/DoomP.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/Lab1.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/Rockybase.dmm4e5a32721f: maps/submaps/pois_vr/debris_field/debris14.dmm4e5a32721f: maps/submaps/pois_vr/debris_field/derelict.dmm4e5a32721f: maps/submaps/pois_vr/debris_field/new_escapepod_xeno.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/BlastMine1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/CaveTrench.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Cavelake.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Cliff1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/CrashedMedShuttle1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Geyser1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Geyser2.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Geyser3.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Mineshaft1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Scave1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/SupplyDrop1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crashed_ufo.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crashed_ufo_frigate.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crashedcontainmentshuttle.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crystal1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crystal2.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crystal3.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/deadBeacon.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/deadly_rabbit_vr.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/deadspy.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/digsite.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/excavation1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/lava_trench.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/prepper1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/ritual.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/spatial_anomaly.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/speakeasy_vr.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault2.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault3.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault4.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault5.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault6.dmm4e5a32721f: maps/submaps/surface_submaps/plains/Boathouse.dmm4e5a32721f: maps/submaps/surface_submaps/plains/BuriedTreasure.dmm4e5a32721f: maps/submaps/surface_submaps/plains/BuriedTreasure2.dmm4e5a32721f: maps/submaps/surface_submaps/plains/BuriedTreasure3.dmm4e5a32721f: maps/submaps/surface_submaps/plains/Oldhouse.dmm4e5a32721f: maps/submaps/surface_submaps/plains/PooledR.dmm4e5a32721f: maps/submaps/surface_submaps/plains/Rocky5.dmm4e5a32721f: maps/submaps/surface_submaps/plains/Shakden.dmm4e5a32721f: maps/submaps/surface_submaps/plains/Thiefc.dmm4e5a32721f: maps/submaps/surface_submaps/plains/beacons.dmm4e5a32721f: maps/submaps/surface_submaps/plains/chemspill1.dmm4e5a32721f: maps/submaps/surface_submaps/plains/farm1.dmm4e5a32721f: maps/submaps/surface_submaps/plains/house1.dmm4e5a32721f: maps/submaps/surface_submaps/plains/lonehome.dmm4e5a32721f: maps/submaps/surface_submaps/plains/smol2.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Blackshuttledown.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Blueshuttledown.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Boombase.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/CaveS.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Chapel.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Cragzone1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DJOutpost1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DJOutpost2.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DJOutpost3.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DJOutpost4.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DecoupledEngine.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DoomP.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Drugden.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Epod3.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Epod4.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Flake.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/FrostflyNest.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/MCamp1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/MHR.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Manor1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Mudpit.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Rocky1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Rocky3.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Rocky4.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Rockybase.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Shack1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Shelter.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Smol1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Snowrock1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/borglab.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/butchershack.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/chasm.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/chemspill2.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/deathden.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/derelictengine.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/frostoasis.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/kururakden.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/spider1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/wolfden.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/xenohive.dmm4e5a32721f: maps/tether/tether-02-surface2.dmm4e5a32721f: maps/virgo_minitest/virgo_minitest-sector-2.dmm Automatically commited by: tools\mapmerge2\fixup.py * Remove unnecessary whitespace edits from mapmerger * Cable dirs update path * Fix area var edits * Put the area over there * Ignore archive maps folder * Forgot to port multivar support too * A few changes I forgot about for hook install * restore multivar support that chomp doesn't have yet * ban those * Forgot to add code for the marker too * Couple more of these invalid cables were added in master * Update multiple_blood_effects.yml * Update multiple_blood_effects.yml * Fixup maps in TGM format612ca9cbb9: maps/tether/submaps/tether_misc.dmm Automatically commited by: tools\mapmerge2\fixup.py * Fixup now logs the map its currently checking * Final fixes? * Fixup maps in TGM format3078e5cd0a: maps/expedition_vr/beach/submaps/crashedcontainmentshuttle.dmm3078e5cd0a: maps/redgate/fantasy_dungeon.dmm3078e5cd0a: maps/submaps/pois_vr/aerostat/Rockybase.dmm3078e5cd0a: maps/submaps/surface_submaps/mountains/crashedcontainmentshuttle_vr.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/Oldhouse_vr.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/dogbase.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/greatwolfden.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/lonehome_vr.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/methlab.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/oldhotel.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/priderock.dmm3078e5cd0a: maps/submaps/surface_submaps/wilderness/Rockybase.dmm3078e5cd0a: maps/submaps/surface_submaps/wilderness/demonpool.dmm3078e5cd0a: maps/submaps/surface_submaps/wilderness/dogbase.dmm3078e5cd0a: maps/submaps/surface_submaps/wilderness/greatwolfden.dmm3078e5cd0a: maps/tether/submaps/underdark_pois/abandonded_outpost.dmm3078e5cd0a: maps/tether/submaps/underdark_pois/phoron_rat_den.dmm Automatically commited by: tools\mapmerge2\fixup.py * Fix tether_misc error * Remap reused solar farm area * Fix erroneous bearcat entries * Fix weird whitespace (most archive maps also affected but didn't bother) * misc mdb cleanup * moar * grr --------- Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com>
130 lines
5.3 KiB
Python
130 lines
5.3 KiB
Python
#!/usr/bin/env python3
|
|
import sys
|
|
import collections
|
|
from . import dmm, mapmerge
|
|
from hooks.merge_frontend import MergeDriver
|
|
|
|
|
|
debug_stats = collections.defaultdict(int)
|
|
|
|
|
|
def select(base, left, right, *, debug=None):
|
|
if left == right:
|
|
# whether or not it's in the base, both sides agree
|
|
if debug:
|
|
debug_stats[f"select {debug} both"] += 1
|
|
return left
|
|
elif base == left:
|
|
# base == left, but right is different: accept right
|
|
if debug:
|
|
debug_stats[f"select {debug} right"] += 1
|
|
return right
|
|
elif base == right:
|
|
# base == right, but left is different: accept left
|
|
if debug:
|
|
debug_stats[f"select {debug} left"] += 1
|
|
return left
|
|
else:
|
|
# all three versions are different
|
|
if debug:
|
|
debug_stats[f"select {debug} fail"] += 1
|
|
return None
|
|
|
|
|
|
def three_way_merge(base, left, right):
|
|
if base.size != left.size or base.size != right.size:
|
|
print("Dimensions have changed:")
|
|
print(f" Base: {base.size}")
|
|
print(f" Ours: {left.size}")
|
|
print(f" Theirs: {right.size}")
|
|
return True, None
|
|
|
|
trouble = False
|
|
merged = dmm.DMM(base.key_length, base.size)
|
|
merged.dictionary = base.dictionary.copy()
|
|
|
|
for (z, y, x) in base.coords_zyx:
|
|
coord = x, y, z
|
|
base_tile = base.get_tile(coord)
|
|
left_tile = left.get_tile(coord)
|
|
right_tile = right.get_tile(coord)
|
|
|
|
# try to merge the whole tiles
|
|
whole_tile_merge = select(base_tile, left_tile, right_tile, debug='tile')
|
|
if whole_tile_merge is not None:
|
|
merged.set_tile(coord, whole_tile_merge)
|
|
continue
|
|
|
|
# try to merge each group independently (movables, turfs, areas)
|
|
base_movables, base_turfs, base_areas = dmm.split_atom_groups(base_tile)
|
|
left_movables, left_turfs, left_areas = dmm.split_atom_groups(left_tile)
|
|
right_movables, right_turfs, right_areas = dmm.split_atom_groups(right_tile)
|
|
|
|
merged_movables = select(base_movables, left_movables, right_movables, debug='movable')
|
|
merged_turfs = select(base_turfs, left_turfs, right_turfs, debug='turf')
|
|
merged_areas = select(base_areas, left_areas, right_areas, debug='area')
|
|
|
|
if merged_movables is not None and merged_turfs is not None and merged_areas is not None:
|
|
merged.set_tile(coord, merged_movables + merged_turfs + merged_areas)
|
|
continue
|
|
|
|
# TODO: more advanced strategies?
|
|
|
|
# fall back to requiring manual conflict resolution
|
|
trouble = True
|
|
print(f" C: Both sides touch the tile at {coord}")
|
|
|
|
if merged_movables is None:
|
|
# Note that if you do not have an object that matches this path in your DME, the invalid path may be discarded when the map is loaded into a map editor.
|
|
# To rectify this, either add an object with this same path, or create a new object/denote an existing object in the obj_path define.
|
|
obj_path = "/obj/merge_conflict_marker"
|
|
obj_name = "---Merge Conflict Marker---"
|
|
obj_desc = "A best-effort merge was performed. You must resolve this conflict yourself (manually) and remove this object once complete."
|
|
merged_movables = left_movables + [f'{obj_path}{{name = "{obj_name}";\n\tdesc = "{obj_desc}"}}'] + right_movables
|
|
print(f" Left and right movable groups are split by an `{obj_path}` named \"{obj_name}\"")
|
|
if merged_turfs is None:
|
|
merged_turfs = left_turfs
|
|
print(f" Saving turf: {', '.join(left_turfs)}")
|
|
print(f" Alternative: {', '.join(right_turfs)}")
|
|
print(f" Original: {', '.join(base_turfs)}")
|
|
if merged_areas is None:
|
|
merged_areas = left_areas
|
|
print(f" Saving area: {', '.join(left_areas)}")
|
|
print(f" Alternative: {', '.join(right_areas)}")
|
|
print(f" Original: {', '.join(base_areas)}")
|
|
|
|
merged.set_tile(coord, merged_movables + merged_turfs + merged_areas)
|
|
|
|
merged = mapmerge.merge_map(merged, base) # is this necessary or correct?
|
|
merged = mapmerge.merge_map(merged, right)
|
|
return trouble, merged
|
|
|
|
|
|
class DmmDriver(MergeDriver):
|
|
driver_id = 'dmm'
|
|
|
|
def merge(self, base, left, right):
|
|
map_base = dmm.DMM.from_bytes(base.read())
|
|
map_left = dmm.DMM.from_bytes(left.read())
|
|
map_right = dmm.DMM.from_bytes(right.read())
|
|
trouble, merge_result = three_way_merge(map_base, map_left, map_right)
|
|
return not trouble, merge_result
|
|
|
|
def to_file(self, outfile, merge_result):
|
|
outfile.write(merge_result.to_bytes())
|
|
|
|
def post_announce(self, success, merge_result):
|
|
if not success:
|
|
print("!!! Manual merge required!")
|
|
if merge_result:
|
|
print(" A best-effort merge was performed. You must edit the map and confirm")
|
|
print(" that all coordinates mentioned above are as desired.")
|
|
else:
|
|
print(" The map was totally unable to be merged; you must start with one version")
|
|
print(" or the other and manually resolve the conflict. Information about the")
|
|
print(" conflicting tiles is listed above.")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
exit(DmmDriver().main())
|