mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Adds the framework for randomlly loading an additional external z-level at server start. Loading during the game should also be possible.
Fixes assorted bugs git-svn-id: http://tgstation13.googlecode.com/svn/trunk@3559 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
@@ -96,6 +96,7 @@
|
|||||||
|
|
||||||
var/turf/destturf
|
var/turf/destturf
|
||||||
var/turf/curturf = get_turf(teleatom)
|
var/turf/curturf = get_turf(teleatom)
|
||||||
|
var/area/destarea = get_area(destination)
|
||||||
if(precision)
|
if(precision)
|
||||||
var/list/posturfs = circlerangeturfs(destination,precision)
|
var/list/posturfs = circlerangeturfs(destination,precision)
|
||||||
destturf = safepick(posturfs)
|
destturf = safepick(posturfs)
|
||||||
@@ -121,6 +122,7 @@
|
|||||||
// Re-Apply lum
|
// Re-Apply lum
|
||||||
teleatom.sd_SetLuminosity(prevlum)
|
teleatom.sd_SetLuminosity(prevlum)
|
||||||
|
|
||||||
|
destarea.Entered(teleatom)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|||||||
@@ -1390,6 +1390,21 @@ proc/process_ghost_teleport_locs()
|
|||||||
icon_state = "tcomsatlounge"
|
icon_state = "tcomsatlounge"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/area/turret_protected/AssistantRoom
|
||||||
|
name = "Assistant Room"
|
||||||
|
icon_state = "storage"
|
||||||
|
sd_lighting = 0
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
/*
|
/*
|
||||||
Lists of areas to be used with is_type_in_list.
|
Lists of areas to be used with is_type_in_list.
|
||||||
|
|||||||
@@ -56,8 +56,10 @@
|
|||||||
|
|
||||||
for(var/obj/item/device/radio/beacon/R in world)
|
for(var/obj/item/device/radio/beacon/R in world)
|
||||||
var/turf/T = get_turf(R)
|
var/turf/T = get_turf(R)
|
||||||
if (!T) continue
|
if (!T)
|
||||||
if(T.z == 2) continue
|
continue
|
||||||
|
if(T.z == 2)
|
||||||
|
continue
|
||||||
var/tmpname = T.loc.name
|
var/tmpname = T.loc.name
|
||||||
if(areaindex[tmpname])
|
if(areaindex[tmpname])
|
||||||
tmpname = "[tmpname] ([++areaindex[tmpname]])"
|
tmpname = "[tmpname] ([++areaindex[tmpname]])"
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
|
|
||||||
//TODO: make teleporting to places trigger Entered() ~Carn
|
//TODO: make teleporting to places trigger Entered() ~Carn
|
||||||
|
// Done.
|
||||||
|
|
||||||
/area/turret_protected/Entered(O)
|
/area/turret_protected/Entered(O)
|
||||||
..()
|
..()
|
||||||
if( master && master != src )
|
if( master && master != src )
|
||||||
@@ -83,6 +85,7 @@
|
|||||||
anchored = 1
|
anchored = 1
|
||||||
layer = 3.5
|
layer = 3.5
|
||||||
density = 0
|
density = 0
|
||||||
|
var/obj/machinery/turret/host = null
|
||||||
|
|
||||||
/obj/machinery/turret/proc/isPopping()
|
/obj/machinery/turret/proc/isPopping()
|
||||||
return (popping!=0)
|
return (popping!=0)
|
||||||
@@ -156,6 +159,7 @@
|
|||||||
return
|
return
|
||||||
if(src.cover==null)
|
if(src.cover==null)
|
||||||
src.cover = new /obj/machinery/turretcover(src.loc)
|
src.cover = new /obj/machinery/turretcover(src.loc)
|
||||||
|
src.cover.host = src
|
||||||
protected_area = get_protected_area()
|
protected_area = get_protected_area()
|
||||||
if(!enabled || !protected_area || protected_area.turretTargets.len<=0)
|
if(!enabled || !protected_area || protected_area.turretTargets.len<=0)
|
||||||
if(!isDown() && !isPopping())
|
if(!isDown() && !isPopping())
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ datum/controller/game_controller
|
|||||||
|
|
||||||
world.tick_lag = config.Ticklag
|
world.tick_lag = config.Ticklag
|
||||||
|
|
||||||
|
createRandomZlevel()
|
||||||
|
|
||||||
setup_objects()
|
setup_objects()
|
||||||
|
|
||||||
setupgenetics()
|
setupgenetics()
|
||||||
|
|||||||
@@ -234,7 +234,7 @@
|
|||||||
verbs += /client/proc/cmd_admin_world_narrate
|
verbs += /client/proc/cmd_admin_world_narrate
|
||||||
verbs += /client/proc/cmd_debug_del_all
|
verbs += /client/proc/cmd_debug_del_all
|
||||||
verbs += /client/proc/cmd_debug_tog_aliens
|
verbs += /client/proc/cmd_debug_tog_aliens
|
||||||
verbs += /client/proc/mapload
|
// verbs += /client/proc/mapload
|
||||||
verbs += /client/proc/check_words
|
verbs += /client/proc/check_words
|
||||||
verbs += /client/proc/drop_bomb
|
verbs += /client/proc/drop_bomb
|
||||||
verbs += /client/proc/kill_airgroup
|
verbs += /client/proc/kill_airgroup
|
||||||
@@ -325,7 +325,7 @@
|
|||||||
verbs -= /client/proc/Cell
|
verbs -= /client/proc/Cell
|
||||||
verbs -= /client/proc/cmd_debug_del_all
|
verbs -= /client/proc/cmd_debug_del_all
|
||||||
verbs -= /client/proc/cmd_debug_tog_aliens
|
verbs -= /client/proc/cmd_debug_tog_aliens
|
||||||
verbs -= /client/proc/mapload
|
// verbs -= /client/proc/mapload
|
||||||
verbs -= /client/proc/check_words
|
verbs -= /client/proc/check_words
|
||||||
verbs -= /client/proc/drop_bomb
|
verbs -= /client/proc/drop_bomb
|
||||||
//verbs -= /client/proc/cmd_admin_drop_everything --merged with view variables
|
//verbs -= /client/proc/cmd_admin_drop_everything --merged with view variables
|
||||||
|
|||||||
@@ -140,6 +140,10 @@
|
|||||||
|
|
||||||
|
|
||||||
proc/set_frequency(new_frequency)
|
proc/set_frequency(new_frequency)
|
||||||
|
if(!radio_controller)
|
||||||
|
sleep(20)
|
||||||
|
if(!radio_controller)
|
||||||
|
return
|
||||||
radio_controller.remove_object(src, frequency)
|
radio_controller.remove_object(src, frequency)
|
||||||
frequency = new_frequency
|
frequency = new_frequency
|
||||||
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
|
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
|
||||||
|
|||||||
672
code/modules/maps/SwapMaps.dm
Normal file
672
code/modules/maps/SwapMaps.dm
Normal file
@@ -0,0 +1,672 @@
|
|||||||
|
/*
|
||||||
|
SwapMaps library by Lummox JR
|
||||||
|
developed for digitalBYOND
|
||||||
|
http://www.digitalbyond.org
|
||||||
|
|
||||||
|
Version 2.1
|
||||||
|
|
||||||
|
The purpose of this library is to make it easy for authors to swap maps
|
||||||
|
in and out of their game using savefiles. Swapped-out maps can be
|
||||||
|
transferred between worlds for an MMORPG, sent to the client, etc.
|
||||||
|
This is facilitated by the use of a special datum and a global list.
|
||||||
|
|
||||||
|
Uses of swapmaps:
|
||||||
|
|
||||||
|
- Temporary battle arenas
|
||||||
|
- House interiors
|
||||||
|
- Individual custom player houses
|
||||||
|
- Virtually unlimited terrain
|
||||||
|
- Sharing maps between servers running different instances of the same
|
||||||
|
game
|
||||||
|
- Loading and saving pieces of maps for reusable room templates
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
User Interface:
|
||||||
|
|
||||||
|
VARS:
|
||||||
|
|
||||||
|
swapmaps_iconcache
|
||||||
|
An associative list of icon files with names, like
|
||||||
|
'player.dmi' = "player"
|
||||||
|
swapmaps_mode
|
||||||
|
This must be set at runtime, like in world/New().
|
||||||
|
|
||||||
|
SWAPMAPS_SAV 0 (default)
|
||||||
|
Uses .sav files for raw /savefile output.
|
||||||
|
SWAPMAPS_TEXT 1
|
||||||
|
Uses .txt files via ExportText() and ImportText(). These maps
|
||||||
|
are easily editable and appear to take up less space in the
|
||||||
|
current version of BYOND.
|
||||||
|
|
||||||
|
PROCS:
|
||||||
|
|
||||||
|
SwapMaps_Find(id)
|
||||||
|
Find a map by its id
|
||||||
|
SwapMaps_Load(id)
|
||||||
|
Load a map by its id
|
||||||
|
SwapMaps_Save(id)
|
||||||
|
Save a map by its id (calls swapmap.Save())
|
||||||
|
SwapMaps_Unload(id)
|
||||||
|
Save and unload a map by its id (calls swapmap.Unload())
|
||||||
|
SwapMaps_Save_All()
|
||||||
|
Save all maps
|
||||||
|
SwapMaps_DeleteFile(id)
|
||||||
|
Delete a map file
|
||||||
|
SwapMaps_CreateFromTemplate(id)
|
||||||
|
Create a new map by loading another map to use as a template.
|
||||||
|
This map has id==src and will not be saved. To make it savable,
|
||||||
|
change id with swapmap.SetID(newid).
|
||||||
|
SwapMaps_LoadChunk(id,turf/locorner)
|
||||||
|
Load a swapmap as a "chunk", at a specific place. A new datum is
|
||||||
|
created but it's not added to the list of maps to save or unload.
|
||||||
|
The new datum can be safely deleted without affecting the turfs
|
||||||
|
it loaded. The purpose of this is to load a map file onto part of
|
||||||
|
another swapmap or an existing part of the world.
|
||||||
|
locorner is the corner turf with the lowest x,y,z values.
|
||||||
|
SwapMaps_SaveChunk(id,turf/corner1,turf/corner2)
|
||||||
|
Save a piece of the world as a "chunk". A new datum is created
|
||||||
|
for the chunk, but it can be deleted without destroying any turfs.
|
||||||
|
The chunk file can be reloaded as a swapmap all its own, or loaded
|
||||||
|
via SwapMaps_LoadChunk() to become part of another map.
|
||||||
|
SwapMaps_GetSize(id)
|
||||||
|
Return a list corresponding to the x,y,z sizes of a map file,
|
||||||
|
without loading the map.
|
||||||
|
Returns null if the map is not found.
|
||||||
|
SwapMaps_AddIconToCache(name,icon)
|
||||||
|
Cache an icon file by name for space-saving storage
|
||||||
|
|
||||||
|
swapmap.New(id,x,y,z)
|
||||||
|
Create a new map; specify id, width (x), height (y), and
|
||||||
|
depth (z)
|
||||||
|
Default size is world.maxx,world.maxy,1
|
||||||
|
swapmap.New(id,turf1,turf2)
|
||||||
|
Create a new map; specify id and 2 corners
|
||||||
|
This becomes a /swapmap for one of the compiled-in maps, for
|
||||||
|
easy saving.
|
||||||
|
swapmap.New()
|
||||||
|
Create a new map datum, but does not allocate space or assign an
|
||||||
|
ID (used for loading).
|
||||||
|
swapmap.Del()
|
||||||
|
Deletes a map but does not save
|
||||||
|
swapmap.Save()
|
||||||
|
Saves to map_[id].sav
|
||||||
|
Maps with id==src are not saved.
|
||||||
|
swapmap.Unload()
|
||||||
|
Saves the map and then deletes it
|
||||||
|
Maps with id==src are not saved.
|
||||||
|
swapmap.SetID(id)
|
||||||
|
Change the map's id and make changes to the lookup list
|
||||||
|
swapmap.AllTurfs(z)
|
||||||
|
Returns a block of turfs encompassing the entire map, or on just
|
||||||
|
one z-level
|
||||||
|
z is in world coordinates; it is optional
|
||||||
|
swapmap.Contains(turf/T)
|
||||||
|
Returns nonzero if T is inside the map's boundaries.
|
||||||
|
Also works for objs and mobs, but the proc is not area-safe.
|
||||||
|
swapmap.InUse()
|
||||||
|
Returns nonzero if a mob with a key is within the map's
|
||||||
|
boundaries.
|
||||||
|
swapmap.LoCorner(z=z1)
|
||||||
|
Returns locate(x1,y1,z), where z=z1 if none is specified.
|
||||||
|
swapmap.HiCorner(z=z2)
|
||||||
|
Returns locate(x2,y2,z), where z=z2 if none is specified.
|
||||||
|
swapmap.BuildFilledRectangle(turf/corner1,turf/corner2,item)
|
||||||
|
Builds a filled rectangle of item from one corner turf to the
|
||||||
|
other, on multiple z-levels if necessary. The corners may be
|
||||||
|
specified in any order.
|
||||||
|
item is a type path like /turf/wall or /obj/barrel{full=1}.
|
||||||
|
swapmap.BuildRectangle(turf/corner1,turf/corner2,item)
|
||||||
|
Builds an unfilled rectangle of item from one corner turf to
|
||||||
|
the other, on multiple z-levels if necessary.
|
||||||
|
swapmap.BuildInTurfs(list/turfs,item)
|
||||||
|
Builds item on all of the turfs listed. The list need not
|
||||||
|
contain only turfs, or even only atoms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
swapmap
|
||||||
|
var/id // a string identifying this map uniquely
|
||||||
|
var/x1 // minimum x,y,z coords
|
||||||
|
var/y1
|
||||||
|
var/z1
|
||||||
|
var/x2 // maximum x,y,z coords (also used as width,height,depth until positioned)
|
||||||
|
var/y2
|
||||||
|
var/z2
|
||||||
|
var/tmp/locked // don't move anyone to this map; it's saving or loading
|
||||||
|
var/tmp/mode // save as text-mode
|
||||||
|
var/ischunk // tells the load routine to load to the specified location
|
||||||
|
|
||||||
|
New(_id,x,y,z)
|
||||||
|
if(isnull(_id)) return
|
||||||
|
id=_id
|
||||||
|
mode=swapmaps_mode
|
||||||
|
if(isturf(x) && isturf(y))
|
||||||
|
/*
|
||||||
|
Special format: Defines a map as an existing set of turfs;
|
||||||
|
this is useful for saving a compiled map in swapmap format.
|
||||||
|
Because this is a compiled-in map, its turfs are not deleted
|
||||||
|
when the datum is deleted.
|
||||||
|
*/
|
||||||
|
x1=min(x:x,y:x);x2=max(x:x,y:x)
|
||||||
|
y1=min(x:y,y:y);y2=max(x:y,y:y)
|
||||||
|
z1=min(x:z,y:z);z2=max(x:z,y:z)
|
||||||
|
InitializeSwapMaps()
|
||||||
|
if(z2>swapmaps_compiled_maxz ||\
|
||||||
|
y2>swapmaps_compiled_maxy ||\
|
||||||
|
x2>swapmaps_compiled_maxx)
|
||||||
|
del(src)
|
||||||
|
return
|
||||||
|
x2=x?(x):world.maxx
|
||||||
|
y2=y?(y):world.maxy
|
||||||
|
z2=z?(z):1
|
||||||
|
AllocateSwapMap()
|
||||||
|
|
||||||
|
Del()
|
||||||
|
// a temporary datum for a chunk can be deleted outright
|
||||||
|
// for others, some cleanup is necessary
|
||||||
|
if(!ischunk)
|
||||||
|
swapmaps_loaded-=src
|
||||||
|
swapmaps_byname-=id
|
||||||
|
if(z2>swapmaps_compiled_maxz ||\
|
||||||
|
y2>swapmaps_compiled_maxy ||\
|
||||||
|
x2>swapmaps_compiled_maxx)
|
||||||
|
var/list/areas=new
|
||||||
|
for(var/atom/A in block(locate(x1,y1,z1),locate(x2,y2,z2)))
|
||||||
|
for(var/obj/O in A) del(O)
|
||||||
|
for(var/mob/M in A)
|
||||||
|
if(!M.key) del(M)
|
||||||
|
else M.loc=null
|
||||||
|
areas[A.loc]=null
|
||||||
|
del(A)
|
||||||
|
// delete areas that belong only to this map
|
||||||
|
for(var/area/a in areas)
|
||||||
|
if(a && !a.contents.len) del(a)
|
||||||
|
if(x2>=world.maxx || y2>=world.maxy || z2>=world.maxz) CutXYZ()
|
||||||
|
del(areas)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/*
|
||||||
|
Savefile format:
|
||||||
|
map
|
||||||
|
id
|
||||||
|
x // size, not coords
|
||||||
|
y
|
||||||
|
z
|
||||||
|
areas // list of areas, not including default
|
||||||
|
[each z; 1 to depth]
|
||||||
|
[each y; 1 to height]
|
||||||
|
[each x; 1 to width]
|
||||||
|
type // of turf
|
||||||
|
AREA // if non-default; saved as a number (index into areas list)
|
||||||
|
vars // all other changed vars
|
||||||
|
*/
|
||||||
|
Write(savefile/S)
|
||||||
|
var
|
||||||
|
x;y;z;n
|
||||||
|
list/areas
|
||||||
|
area/defarea=locate(world.area)
|
||||||
|
if(!defarea) defarea=new world.area
|
||||||
|
areas=list()
|
||||||
|
for(var/turf/T in block(locate(x1,y1,z1),locate(x2,y2,z2)))
|
||||||
|
areas[T.loc]=null
|
||||||
|
for(n in areas) // quickly eliminate associations for smaller storage
|
||||||
|
areas-=n
|
||||||
|
areas+=n
|
||||||
|
areas-=defarea
|
||||||
|
InitializeSwapMaps()
|
||||||
|
locked=1
|
||||||
|
S["id"] << id
|
||||||
|
S["z"] << z2-z1+1
|
||||||
|
S["y"] << y2-y1+1
|
||||||
|
S["x"] << x2-x1+1
|
||||||
|
S["areas"] << areas
|
||||||
|
for(n in 1 to areas.len) areas[areas[n]]=n
|
||||||
|
var/oldcd=S.cd
|
||||||
|
for(z=z1,z<=z2,++z)
|
||||||
|
S.cd="[z-z1+1]"
|
||||||
|
for(y=y1,y<=y2,++y)
|
||||||
|
S.cd="[y-y1+1]"
|
||||||
|
for(x=x1,x<=x2,++x)
|
||||||
|
S.cd="[x-x1+1]"
|
||||||
|
var/turf/T=locate(x,y,z)
|
||||||
|
S["type"] << T.type
|
||||||
|
if(T.loc!=defarea) S["AREA"] << areas[T.loc]
|
||||||
|
T.Write(S)
|
||||||
|
S.cd=".."
|
||||||
|
S.cd=".."
|
||||||
|
sleep()
|
||||||
|
S.cd=oldcd
|
||||||
|
locked=0
|
||||||
|
del(areas)
|
||||||
|
|
||||||
|
Read(savefile/S,_id,turf/locorner)
|
||||||
|
var
|
||||||
|
x;y;z;n
|
||||||
|
list/areas
|
||||||
|
area/defarea=locate(world.area)
|
||||||
|
id=_id
|
||||||
|
if(locorner)
|
||||||
|
ischunk=1
|
||||||
|
x1=locorner.x
|
||||||
|
y1=locorner.y
|
||||||
|
z1=locorner.z
|
||||||
|
if(!defarea) defarea=new world.area
|
||||||
|
if(!_id)
|
||||||
|
S["id"] >> id
|
||||||
|
else
|
||||||
|
var/dummy
|
||||||
|
S["id"] >> dummy
|
||||||
|
S["z"] >> z2 // these are depth,
|
||||||
|
S["y"] >> y2 // height,
|
||||||
|
S["x"] >> x2 // width
|
||||||
|
S["areas"] >> areas
|
||||||
|
locked=1
|
||||||
|
AllocateSwapMap() // adjust x1,y1,z1 - x2,y2,z2 coords
|
||||||
|
var/oldcd=S.cd
|
||||||
|
for(z=z1,z<=z2,++z)
|
||||||
|
S.cd="[z-z1+1]"
|
||||||
|
for(y=y1,y<=y2,++y)
|
||||||
|
S.cd="[y-y1+1]"
|
||||||
|
for(x=x1,x<=x2,++x)
|
||||||
|
S.cd="[x-x1+1]"
|
||||||
|
var/tp
|
||||||
|
S["type"]>>tp
|
||||||
|
var/turf/T=locate(x,y,z)
|
||||||
|
T.loc.contents-=T
|
||||||
|
T=new tp(locate(x,y,z))
|
||||||
|
if("AREA" in S.dir)
|
||||||
|
S["AREA"]>>n
|
||||||
|
var/area/A=areas[n]
|
||||||
|
A.contents+=T
|
||||||
|
else defarea.contents+=T
|
||||||
|
// clear the turf
|
||||||
|
for(var/obj/O in T) del(O)
|
||||||
|
for(var/mob/M in T)
|
||||||
|
if(!M.key) del(M)
|
||||||
|
else M.loc=null
|
||||||
|
// finish the read
|
||||||
|
T.Read(S)
|
||||||
|
S.cd=".."
|
||||||
|
S.cd=".."
|
||||||
|
sleep()
|
||||||
|
S.cd=oldcd
|
||||||
|
locked=0
|
||||||
|
del(areas)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Find an empty block on the world map in which to load this map.
|
||||||
|
If no space is found, increase world.maxz as necessary. (If the
|
||||||
|
map is greater in x,y size than the current world, expand
|
||||||
|
world.maxx and world.maxy too.)
|
||||||
|
|
||||||
|
Ignore certain operations if loading a map as a chunk. Use the
|
||||||
|
x1,y1,z1 position for it, and *don't* count it as a loaded map.
|
||||||
|
*/
|
||||||
|
proc/AllocateSwapMap()
|
||||||
|
InitializeSwapMaps()
|
||||||
|
world.maxx=max(x2,world.maxx) // stretch x/y if necessary
|
||||||
|
world.maxy=max(y2,world.maxy)
|
||||||
|
if(!ischunk)
|
||||||
|
if(world.maxz<=swapmaps_compiled_maxz)
|
||||||
|
z1=swapmaps_compiled_maxz+1
|
||||||
|
x1=1;y1=1
|
||||||
|
else
|
||||||
|
var/list/l=ConsiderRegion(1,1,world.maxx,world.maxy,swapmaps_compiled_maxz+1)
|
||||||
|
x1=l[1]
|
||||||
|
y1=l[2]
|
||||||
|
z1=l[3]
|
||||||
|
del(l)
|
||||||
|
x2+=x1-1
|
||||||
|
y2+=y1-1
|
||||||
|
z2+=z1-1
|
||||||
|
world.maxz=max(z2,world.maxz) // stretch z if necessary
|
||||||
|
if(!ischunk)
|
||||||
|
swapmaps_loaded[src]=null
|
||||||
|
swapmaps_byname[id]=src
|
||||||
|
|
||||||
|
proc/ConsiderRegion(X1,Y1,X2,Y2,Z1,Z2)
|
||||||
|
while(1)
|
||||||
|
var/nextz=0
|
||||||
|
var/swapmap/M
|
||||||
|
for(M in swapmaps_loaded)
|
||||||
|
if(M.z2<Z1 || (Z2 && M.z1>Z2) || M.z1>=Z1+z2 ||\
|
||||||
|
M.x1>X2 || M.x2<X1 || M.x1>=X1+x2 ||\
|
||||||
|
M.y1>Y2 || M.y2<Y1 || M.y1>=Y1+y2) continue
|
||||||
|
// look for sub-regions with a defined ceiling
|
||||||
|
var/nz2=Z2?(Z2):Z1+z2-1+M.z2-M.z1
|
||||||
|
if(M.x1>=X1+x2)
|
||||||
|
.=ConsiderRegion(X1,Y1,M.x1-1,Y2,Z1,nz2)
|
||||||
|
if(.) return
|
||||||
|
else if(M.x2<=X2-x2)
|
||||||
|
.=ConsiderRegion(M.x2+1,Y1,X2,Y2,Z1,nz2)
|
||||||
|
if(.) return
|
||||||
|
if(M.y1>=Y1+y2)
|
||||||
|
.=ConsiderRegion(X1,Y1,X2,M.y1-1,Z1,nz2)
|
||||||
|
if(.) return
|
||||||
|
else if(M.y2<=Y2-y2)
|
||||||
|
.=ConsiderRegion(X1,M.y2+1,X2,Y2,Z1,nz2)
|
||||||
|
if(.) return
|
||||||
|
nextz=nextz?min(nextz,M.z2+1):(M.z2+1)
|
||||||
|
if(!M)
|
||||||
|
/* If nextz is not 0, then at some point there was an overlap that
|
||||||
|
could not be resolved by using an area to the side */
|
||||||
|
if(nextz) Z1=nextz
|
||||||
|
if(!nextz || (Z2 && Z2-Z1+1<z2))
|
||||||
|
return (!Z2 || Z2-Z1+1>=z2)?list(X1,Y1,Z1):null
|
||||||
|
X1=1;X2=world.maxx
|
||||||
|
Y1=1;Y2=world.maxy
|
||||||
|
|
||||||
|
proc/CutXYZ()
|
||||||
|
var/mx=swapmaps_compiled_maxx
|
||||||
|
var/my=swapmaps_compiled_maxy
|
||||||
|
var/mz=swapmaps_compiled_maxz
|
||||||
|
for(var/swapmap/M in swapmaps_loaded) // may not include src
|
||||||
|
mx=max(mx,M.x2)
|
||||||
|
my=max(my,M.y2)
|
||||||
|
mz=max(mz,M.z2)
|
||||||
|
world.maxx=mx
|
||||||
|
world.maxy=my
|
||||||
|
world.maxz=mz
|
||||||
|
|
||||||
|
// save and delete
|
||||||
|
proc/Unload()
|
||||||
|
Save()
|
||||||
|
del(src)
|
||||||
|
|
||||||
|
proc/Save()
|
||||||
|
if(id==src) return 0
|
||||||
|
var/savefile/S=mode?(new):new("map_[id].sav")
|
||||||
|
S << src
|
||||||
|
while(locked) sleep(1)
|
||||||
|
if(mode)
|
||||||
|
fdel("map_[id].txt")
|
||||||
|
S.ExportText("/","map_[id].txt")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
// this will not delete existing savefiles for this map
|
||||||
|
proc/SetID(newid)
|
||||||
|
swapmaps_byname-=id
|
||||||
|
id=newid
|
||||||
|
swapmaps_byname[id]=src
|
||||||
|
|
||||||
|
proc/AllTurfs(z)
|
||||||
|
if(isnum(z) && (z<z1 || z>z2)) return null
|
||||||
|
return block(LoCorner(z),HiCorner(z))
|
||||||
|
|
||||||
|
// this could be safely called for an obj or mob as well, but
|
||||||
|
// probably not an area
|
||||||
|
proc/Contains(turf/T)
|
||||||
|
return (T && T.x>=x1 && T.x<=x2\
|
||||||
|
&& T.y>=y1 && T.y<=y2\
|
||||||
|
&& T.z>=z1 && T.z<=z2)
|
||||||
|
|
||||||
|
proc/InUse()
|
||||||
|
for(var/turf/T in AllTurfs())
|
||||||
|
for(var/mob/M in T) if(M.key) return 1
|
||||||
|
|
||||||
|
proc/LoCorner(z=z1)
|
||||||
|
return locate(x1,y1,z)
|
||||||
|
proc/HiCorner(z=z2)
|
||||||
|
return locate(x2,y2,z)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Build procs: Take 2 turfs as corners, plus an item type.
|
||||||
|
An item may be like:
|
||||||
|
|
||||||
|
/turf/wall
|
||||||
|
/obj/fence{icon_state="iron"}
|
||||||
|
*/
|
||||||
|
proc/BuildFilledRectangle(turf/T1,turf/T2,item)
|
||||||
|
if(!Contains(T1) || !Contains(T2)) return
|
||||||
|
var/turf/T=T1
|
||||||
|
// pick new corners in a block()-friendly form
|
||||||
|
T1=locate(min(T1.x,T2.x),min(T1.y,T2.y),min(T1.z,T2.z))
|
||||||
|
T2=locate(max(T.x,T2.x),max(T.y,T2.y),max(T.z,T2.z))
|
||||||
|
for(T in block(T1,T2)) new item(T)
|
||||||
|
|
||||||
|
proc/BuildRectangle(turf/T1,turf/T2,item)
|
||||||
|
if(!Contains(T1) || !Contains(T2)) return
|
||||||
|
var/turf/T=T1
|
||||||
|
// pick new corners in a block()-friendly form
|
||||||
|
T1=locate(min(T1.x,T2.x),min(T1.y,T2.y),min(T1.z,T2.z))
|
||||||
|
T2=locate(max(T.x,T2.x),max(T.y,T2.y),max(T.z,T2.z))
|
||||||
|
if(T2.x-T1.x<2 || T2.y-T1.y<2) BuildFilledRectangle(T1,T2,item)
|
||||||
|
else
|
||||||
|
//for(T in block(T1,T2)-block(locate(T1.x+1,T1.y+1,T1.z),locate(T2.x-1,T2.y-1,T2.z)))
|
||||||
|
for(T in block(T1,locate(T2.x,T1.y,T2.z))) new item(T)
|
||||||
|
for(T in block(locate(T1.x,T2.y,T1.z),T2)) new item(T)
|
||||||
|
for(T in block(locate(T1.x,T1.y+1,T1.z),locate(T1.x,T2.y-1,T2.z))) new item(T)
|
||||||
|
for(T in block(locate(T2.x,T1.y+1,T1.z),locate(T2.x,T2.y-1,T2.z))) new item(T)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Supplementary build proc: Takes a list of turfs, plus an item
|
||||||
|
type. Actually the list doesn't have to be just turfs.
|
||||||
|
*/
|
||||||
|
proc/BuildInTurfs(list/turfs,item)
|
||||||
|
for(var/T in turfs) new item(T)
|
||||||
|
|
||||||
|
atom
|
||||||
|
Write(savefile/S)
|
||||||
|
for(var/V in vars-"x"-"y"-"z"-"contents"-"icon"-"overlays"-"underlays")
|
||||||
|
if(issaved(vars[V]))
|
||||||
|
if(vars[V]!=initial(vars[V])) S[V]<<vars[V]
|
||||||
|
else S.dir.Remove(V)
|
||||||
|
if(icon!=initial(icon))
|
||||||
|
if(swapmaps_iconcache && swapmaps_iconcache[icon])
|
||||||
|
S["icon"]<<swapmaps_iconcache[icon]
|
||||||
|
else S["icon"]<<icon
|
||||||
|
// do not save mobs with keys; do save other mobs
|
||||||
|
var/mob/M
|
||||||
|
for(M in src) if(M.key) break
|
||||||
|
if(overlays.len) S["overlays"]<<overlays
|
||||||
|
if(underlays.len) S["underlays"]<<underlays
|
||||||
|
if(contents.len && !isarea(src))
|
||||||
|
var/list/l=contents
|
||||||
|
if(M)
|
||||||
|
l=l.Copy()
|
||||||
|
for(M in src) if(M.key) l-=M
|
||||||
|
if(l.len) S["contents"]<<l
|
||||||
|
if(l!=contents) del(l)
|
||||||
|
Read(savefile/S)
|
||||||
|
var/list/l
|
||||||
|
if(contents.len) l=contents
|
||||||
|
..()
|
||||||
|
// if the icon was a text string, it would not have loaded properly
|
||||||
|
// replace it from the cache list
|
||||||
|
if(!icon && ("icon" in S.dir))
|
||||||
|
var/ic
|
||||||
|
S["icon"]>>ic
|
||||||
|
if(istext(ic)) icon=swapmaps_iconcache[ic]
|
||||||
|
if(l && contents!=l)
|
||||||
|
contents+=l
|
||||||
|
del(l)
|
||||||
|
|
||||||
|
|
||||||
|
// set this up (at runtime) as follows:
|
||||||
|
// list(\
|
||||||
|
// 'player.dmi'="player",\
|
||||||
|
// 'monster.dmi'="monster",\
|
||||||
|
// ...
|
||||||
|
// 'item.dmi'="item")
|
||||||
|
var/list/swapmaps_iconcache
|
||||||
|
|
||||||
|
// preferred mode; sav or text
|
||||||
|
var/const/SWAPMAPS_SAV=0
|
||||||
|
var/const/SWAPMAPS_TEXT=1
|
||||||
|
var/swapmaps_mode=SWAPMAPS_SAV
|
||||||
|
|
||||||
|
var/swapmaps_compiled_maxx
|
||||||
|
var/swapmaps_compiled_maxy
|
||||||
|
var/swapmaps_compiled_maxz
|
||||||
|
var/swapmaps_initialized
|
||||||
|
var/swapmaps_loaded
|
||||||
|
var/swapmaps_byname
|
||||||
|
|
||||||
|
proc/InitializeSwapMaps()
|
||||||
|
if(swapmaps_initialized) return
|
||||||
|
swapmaps_initialized=1
|
||||||
|
swapmaps_compiled_maxx=world.maxx
|
||||||
|
swapmaps_compiled_maxy=world.maxy
|
||||||
|
swapmaps_compiled_maxz=world.maxz
|
||||||
|
swapmaps_loaded=list()
|
||||||
|
swapmaps_byname=list()
|
||||||
|
if(swapmaps_iconcache)
|
||||||
|
for(var/V in swapmaps_iconcache)
|
||||||
|
// reverse-associate everything
|
||||||
|
// so you can look up an icon file by name or vice-versa
|
||||||
|
swapmaps_iconcache[swapmaps_iconcache[V]]=V
|
||||||
|
|
||||||
|
proc/SwapMaps_AddIconToCache(name,icon)
|
||||||
|
if(!swapmaps_iconcache) swapmaps_iconcache=list()
|
||||||
|
swapmaps_iconcache[name]=icon
|
||||||
|
swapmaps_iconcache[icon]=name
|
||||||
|
|
||||||
|
proc/SwapMaps_Find(id)
|
||||||
|
InitializeSwapMaps()
|
||||||
|
return swapmaps_byname[id]
|
||||||
|
|
||||||
|
proc/SwapMaps_Load(id)
|
||||||
|
InitializeSwapMaps()
|
||||||
|
var/swapmap/M=swapmaps_byname[id]
|
||||||
|
if(!M)
|
||||||
|
var/savefile/S
|
||||||
|
var/text=0
|
||||||
|
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[id].txt"))
|
||||||
|
text=1
|
||||||
|
else if(fexists("map_[id].sav"))
|
||||||
|
S=new("map_[id].sav")
|
||||||
|
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[id].txt"))
|
||||||
|
text=1
|
||||||
|
else return // no file found
|
||||||
|
if(text)
|
||||||
|
S=new
|
||||||
|
S.ImportText("/",file("map_[id].txt"))
|
||||||
|
S >> M
|
||||||
|
while(M.locked) sleep(1)
|
||||||
|
M.mode=text
|
||||||
|
return M
|
||||||
|
|
||||||
|
proc/SwapMaps_Save(id)
|
||||||
|
InitializeSwapMaps()
|
||||||
|
var/swapmap/M=swapmaps_byname[id]
|
||||||
|
if(M) M.Save()
|
||||||
|
return M
|
||||||
|
|
||||||
|
proc/SwapMaps_Save_All()
|
||||||
|
InitializeSwapMaps()
|
||||||
|
for(var/swapmap/M in swapmaps_loaded)
|
||||||
|
if(M) M.Save()
|
||||||
|
|
||||||
|
proc/SwapMaps_Unload(id)
|
||||||
|
InitializeSwapMaps()
|
||||||
|
var/swapmap/M=swapmaps_byname[id]
|
||||||
|
if(!M) return // return silently from an error
|
||||||
|
M.Unload()
|
||||||
|
return 1
|
||||||
|
|
||||||
|
proc/SwapMaps_DeleteFile(id)
|
||||||
|
fdel("map_[id].sav")
|
||||||
|
fdel("map_[id].txt")
|
||||||
|
|
||||||
|
proc/SwapMaps_CreateFromTemplate(template_id)
|
||||||
|
var/swapmap/M=new
|
||||||
|
var/savefile/S
|
||||||
|
var/text=0
|
||||||
|
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[template_id].txt"))
|
||||||
|
text=1
|
||||||
|
else if(fexists("map_[template_id].sav"))
|
||||||
|
S=new("map_[template_id].sav")
|
||||||
|
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[template_id].txt"))
|
||||||
|
text=1
|
||||||
|
else
|
||||||
|
world.log << "SwapMaps error in SwapMaps_CreateFromTemplate(): map_[template_id] file not found."
|
||||||
|
return
|
||||||
|
if(text)
|
||||||
|
S=new
|
||||||
|
S.ImportText("/",file("map_[template_id].txt"))
|
||||||
|
/*
|
||||||
|
This hacky workaround is needed because S >> M will create a brand new
|
||||||
|
M to fill with data. There's no way to control the Read() process
|
||||||
|
properly otherwise. The //.0 path should always match the map, however.
|
||||||
|
*/
|
||||||
|
S.cd="//.0"
|
||||||
|
M.Read(S,M)
|
||||||
|
M.mode=text
|
||||||
|
while(M.locked) sleep(1)
|
||||||
|
return M
|
||||||
|
|
||||||
|
proc/SwapMaps_LoadChunk(chunk_id,turf/locorner)
|
||||||
|
var/swapmap/M=new
|
||||||
|
var/savefile/S
|
||||||
|
var/text=0
|
||||||
|
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[chunk_id].txt"))
|
||||||
|
text=1
|
||||||
|
else if(fexists("map_[chunk_id].sav"))
|
||||||
|
S=new("map_[chunk_id].sav")
|
||||||
|
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[chunk_id].txt"))
|
||||||
|
text=1
|
||||||
|
else
|
||||||
|
world.log << "SwapMaps error in SwapMaps_LoadChunk(): map_[chunk_id] file not found."
|
||||||
|
return
|
||||||
|
if(text)
|
||||||
|
S=new
|
||||||
|
S.ImportText("/",file("map_[chunk_id].txt"))
|
||||||
|
/*
|
||||||
|
This hacky workaround is needed because S >> M will create a brand new
|
||||||
|
M to fill with data. There's no way to control the Read() process
|
||||||
|
properly otherwise. The //.0 path should always match the map, however.
|
||||||
|
*/
|
||||||
|
S.cd="//.0"
|
||||||
|
M.Read(S,M,locorner)
|
||||||
|
while(M.locked) sleep(1)
|
||||||
|
del(M)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
proc/SwapMaps_SaveChunk(chunk_id,turf/corner1,turf/corner2)
|
||||||
|
if(!corner1 || !corner2)
|
||||||
|
world.log << "SwapMaps error in SwapMaps_SaveChunk():"
|
||||||
|
if(!corner1) world.log << " corner1 turf is null"
|
||||||
|
if(!corner2) world.log << " corner2 turf is null"
|
||||||
|
return
|
||||||
|
var/swapmap/M=new
|
||||||
|
M.id=chunk_id
|
||||||
|
M.ischunk=1 // this is a chunk
|
||||||
|
M.x1=min(corner1.x,corner2.x)
|
||||||
|
M.y1=min(corner1.y,corner2.y)
|
||||||
|
M.z1=min(corner1.z,corner2.z)
|
||||||
|
M.x2=max(corner1.x,corner2.x)
|
||||||
|
M.y2=max(corner1.y,corner2.y)
|
||||||
|
M.z2=max(corner1.z,corner2.z)
|
||||||
|
M.mode=swapmaps_mode
|
||||||
|
M.Save()
|
||||||
|
while(M.locked) sleep(1)
|
||||||
|
del(M)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
proc/SwapMaps_GetSize(id)
|
||||||
|
var/savefile/S
|
||||||
|
var/text=0
|
||||||
|
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[id].txt"))
|
||||||
|
text=1
|
||||||
|
else if(fexists("map_[id].sav"))
|
||||||
|
S=new("map_[id].sav")
|
||||||
|
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[id].txt"))
|
||||||
|
text=1
|
||||||
|
else
|
||||||
|
world.log << "SwapMaps error in SwapMaps_GetSize(): map_[id] file not found."
|
||||||
|
return
|
||||||
|
if(text)
|
||||||
|
S=new
|
||||||
|
S.ImportText("/",file("map_[id].txt"))
|
||||||
|
/*
|
||||||
|
The //.0 path should always be the map. There's no other way to
|
||||||
|
read this data.
|
||||||
|
*/
|
||||||
|
S.cd="//.0"
|
||||||
|
var/x
|
||||||
|
var/y
|
||||||
|
var/z
|
||||||
|
S["x"] >> x
|
||||||
|
S["y"] >> y
|
||||||
|
S["z"] >> z
|
||||||
|
return list(x,y,z)
|
||||||
73
code/modules/maps/dmm_suite.dm
Normal file
73
code/modules/maps/dmm_suite.dm
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
var/global/dmm_suite/maploader = new
|
||||||
|
|
||||||
|
dmm_suite{
|
||||||
|
/*
|
||||||
|
|
||||||
|
dmm_suite version 1.0
|
||||||
|
Released January 30th, 2011.
|
||||||
|
|
||||||
|
defines the object /dmm_suite
|
||||||
|
- Provides the proc load_map()
|
||||||
|
- Loads the specified map file onto the specified z-level.
|
||||||
|
- provides the proc write_map()
|
||||||
|
- Returns a text string of the map in dmm format
|
||||||
|
ready for output to a file.
|
||||||
|
- provides the proc save_map()
|
||||||
|
- Returns a .dmm file if map is saved
|
||||||
|
- Returns FALSE if map fails to save
|
||||||
|
|
||||||
|
The dmm_suite provides saving and loading of map files in BYOND's native DMM map
|
||||||
|
format. It approximates the map saving and loading processes of the Dream Maker
|
||||||
|
and Dream Seeker programs so as to allow editing, saving, and loading of maps at
|
||||||
|
runtime.
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
To save a map at runtime, create an instance of /dmm_suite, and then call
|
||||||
|
write_map(), which accepts three arguments:
|
||||||
|
- A turf representing one corner of a three dimensional grid (Required).
|
||||||
|
- Another turf representing the other corner of the same grid (Required).
|
||||||
|
- Any, or a combination, of several bit flags (Optional, see documentation).
|
||||||
|
|
||||||
|
The order in which the turfs are supplied does not matter, the /dmm_writer will
|
||||||
|
determine the grid containing both, in much the same way as DM's block() function.
|
||||||
|
write_map() will then return a string representing the saved map in dmm format;
|
||||||
|
this string can then be saved to a file, or used for any other purose.
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
To load a map at runtime, create an instance of /dmm_suite, and then call load_map(),
|
||||||
|
which accepts two arguments:
|
||||||
|
- A .dmm file to load (Required).
|
||||||
|
- A number representing the z-level on which to start loading the map (Optional).
|
||||||
|
|
||||||
|
The /dmm_suite will load the map file starting on the specified z-level. If no
|
||||||
|
z-level was specified, world.maxz will be increased so as to fit the map. Note
|
||||||
|
that if you wish to load a map onto a z-level that already has objects on it,
|
||||||
|
you will have to handle the removal of those objects. Otherwise the new map will
|
||||||
|
simply load the new objects on top of the old ones.
|
||||||
|
|
||||||
|
Also note that all type paths specified in the .dmm file must exist in the world's
|
||||||
|
code, and that the /dmm_reader trusts that files to be loaded are in fact valid
|
||||||
|
.dmm files. Errors in the .dmm format will cause runtime errors.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
verb/load_map(var/dmm_file as file, var/z_offset as num){
|
||||||
|
// dmm_file: A .dmm file to load (Required).
|
||||||
|
// z_offset: A number representing the z-level on which to start loading the map (Optional).
|
||||||
|
}
|
||||||
|
verb/write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num){
|
||||||
|
// t1: A turf representing one corner of a three dimensional grid (Required).
|
||||||
|
// t2: Another turf representing the other corner of the same grid (Required).
|
||||||
|
// flags: Any, or a combination, of several bit flags (Optional, see documentation).
|
||||||
|
}
|
||||||
|
|
||||||
|
// save_map is included as a legacy proc. Use write_map instead.
|
||||||
|
verb/save_map(var/turf/t1 as turf, var/turf/t2 as turf, var/map_name as text, var/flags as num){
|
||||||
|
// t1: A turf representing one corner of a three dimensional grid (Required).
|
||||||
|
// t2: Another turf representing the other corner of the same grid (Required).
|
||||||
|
// map_name: A valid name for the map to be saved, such as "castle" (Required).
|
||||||
|
// flags: Any, or a combination, of several bit flags (Optional, see documentation).
|
||||||
|
}
|
||||||
|
}
|
||||||
237
code/modules/maps/fromdmp.dm
Normal file
237
code/modules/maps/fromdmp.dm
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
/*
|
||||||
|
DMP to swapmap converter
|
||||||
|
version 1.0
|
||||||
|
|
||||||
|
by Lummox JR
|
||||||
|
*/
|
||||||
|
|
||||||
|
mob/verb/Convert(filename as file)
|
||||||
|
dmp2swapmap(filename)
|
||||||
|
|
||||||
|
proc/d2sm_prepmap(filename)
|
||||||
|
var/txt = file2text(filename)
|
||||||
|
if(!txt) return
|
||||||
|
var/i,j
|
||||||
|
i=findText(txt,ascii2text(13)) // eliminate carriage returns
|
||||||
|
while(i)
|
||||||
|
txt=copytext(txt,1,i)+copytext(txt,i+1)
|
||||||
|
i=findText(txt,ascii2text(13),i)
|
||||||
|
i=findText(txt,"\\\n")
|
||||||
|
while(i)
|
||||||
|
for(j=i+2,j<=length(txt),++j) if(text2ascii(txt,j)>32) break
|
||||||
|
txt=copytext(txt,1,i)+copytext(txt,j)
|
||||||
|
i=findText(txt,"\\\n",i)
|
||||||
|
return txt
|
||||||
|
|
||||||
|
proc/dmp2swapmap(filename)
|
||||||
|
//var/txt = file2text(filename)
|
||||||
|
//if(!txt) return
|
||||||
|
var/txt = d2sm_prepmap(filename)
|
||||||
|
var/mapname="[filename]"
|
||||||
|
var/i,j,k
|
||||||
|
i=findtext(mapname,".dmp")
|
||||||
|
while(i && i+4<length(mapname)) i=findtext(mapname,".dmp",i+1)
|
||||||
|
mapname=copytext(mapname,1,i)
|
||||||
|
/* i=findText(txt,ascii2text(13))
|
||||||
|
while(i)
|
||||||
|
txt=copytext(txt,1,i)+copytext(txt,i+1)
|
||||||
|
i=findText(txt,ascii2text(13),i)
|
||||||
|
i=findText(txt,"\\\n")
|
||||||
|
while(i)
|
||||||
|
for(j=i+2,j<=length(txt),++j) if(text2ascii(txt,j)>32) break
|
||||||
|
txt=copytext(txt,1,i)+copytext(txt,j)
|
||||||
|
i=findText(txt,"\\\n",i) */
|
||||||
|
var/list/codes=new
|
||||||
|
var/codelen=1
|
||||||
|
var/list/areas
|
||||||
|
var/mode=34
|
||||||
|
var/z=0
|
||||||
|
var/X=0,Y=0,Z=0
|
||||||
|
while(txt)
|
||||||
|
if(text2ascii(txt)==34)
|
||||||
|
if(mode!=34)
|
||||||
|
world << "Corrupt map file [filename]: Unexpected code found after z-level [z]"
|
||||||
|
return
|
||||||
|
// standard line:
|
||||||
|
// "a" = (/obj, /obj, /turf, /area)
|
||||||
|
i=findtext(txt,"\"",2)
|
||||||
|
var/code=copytext(txt,2,i)
|
||||||
|
codelen=length(code)
|
||||||
|
i=findtext(txt,"(",i)
|
||||||
|
if(!i)
|
||||||
|
world << "Corrupt map file [filename]: No type list follows \"[code]\""
|
||||||
|
return
|
||||||
|
k=findtext(txt,"\n",++i)
|
||||||
|
j=(k || length(txt+1))
|
||||||
|
while(--j>=i && text2ascii(txt,j)!=41)
|
||||||
|
if(j<i)
|
||||||
|
world << "Corrupt map file [filename]: Type list following \"[code]\" is incomplete"
|
||||||
|
return
|
||||||
|
var/list/L = d2sm_ParseCommaList(copytext(txt,i,j))
|
||||||
|
if(istext(L))
|
||||||
|
world << "Corrupt map file [filename]: [L]"
|
||||||
|
return
|
||||||
|
if(L.len<2)
|
||||||
|
world << "Corrupt map file [filename]: Type list following \"[code]\" has only 1 item"
|
||||||
|
return
|
||||||
|
txt=k?copytext(txt,k+1):null
|
||||||
|
if(L[L.len] == "[world.area]") L[L.len]=0
|
||||||
|
else
|
||||||
|
if(!areas) areas=list()
|
||||||
|
i=areas.Find(L[L.len])
|
||||||
|
if(i) L[L.len]=i
|
||||||
|
else
|
||||||
|
areas+=L[L.len]
|
||||||
|
L[L.len]=areas.len
|
||||||
|
var/codetrans=d2sm_ConvertType(L[L.len-1],"\t\t\t\t")
|
||||||
|
if(L[L.len]) codetrans+="\t\t\t\tAREA = [L[L.len]]\n"
|
||||||
|
if(L.len>2) codetrans+=d2sm_Contents(L,L.len-2,"\t\t\t\t")
|
||||||
|
codes[code]=copytext(codetrans,1,length(codetrans))
|
||||||
|
else if(text2ascii(txt)==40)
|
||||||
|
mode=40
|
||||||
|
// standard line (top-down, left-right symbol order):
|
||||||
|
// (1,1,1) = {"
|
||||||
|
// abcde
|
||||||
|
// bcdef
|
||||||
|
// "}
|
||||||
|
i=d2sm_MatchBrace(txt,1,40)
|
||||||
|
if(!i)
|
||||||
|
world << "Corrupt map file [filename]: No matching ) for coordinates: [copytext(txt,1,findtext(txt,"\n"))]"
|
||||||
|
return
|
||||||
|
var/list/coords=d2sm_ParseCommaList(copytext(txt,2,i))
|
||||||
|
if(istext(coords) || coords.len!=3)
|
||||||
|
world << "Corrupt map file [filename]: [istext(coords)?(coords):"[copytext(txt,1,i+1)] is not a valid (x,y,z) coordinate"]"
|
||||||
|
return
|
||||||
|
j=findtext(txt,"{",i+1)
|
||||||
|
if(!j)
|
||||||
|
world << "Corrupt map file [filename]: No braces {} following [copytext(txt,1,i+1)]"
|
||||||
|
return
|
||||||
|
k=d2sm_MatchBrace(txt,j,123)
|
||||||
|
if(!k)
|
||||||
|
world << "Corrupt map file [filename]: No closing brace } following [copytext(txt,1,i+1)]"
|
||||||
|
return
|
||||||
|
var/mtxt=copytext(txt,j+1,k)
|
||||||
|
if(findText(mtxt,"\"\n")!=1 || !findText(mtxt,"\n\"",length(mtxt)-1))
|
||||||
|
world << findText(mtxt,"\"\n")
|
||||||
|
world << findText(mtxt,"\n\"",length(mtxt)-1)
|
||||||
|
world << "Corrupt map file [filename]: No quotes in braces following [copytext(txt,1,i+1)]"
|
||||||
|
return
|
||||||
|
mtxt=copytext(mtxt,2,length(mtxt))
|
||||||
|
var/_x=0,_y=0
|
||||||
|
for(i=1,,++_y)
|
||||||
|
j=findText(mtxt,"\n",i+1)
|
||||||
|
if(!j) break
|
||||||
|
_x=max(_x,(j-i-1)/codelen)
|
||||||
|
i=j
|
||||||
|
X=max(X,_x)
|
||||||
|
Y=max(Y,_y)
|
||||||
|
z=text2num(coords[3])
|
||||||
|
Z=max(Z,z)
|
||||||
|
txt=copytext(txt,k+1)
|
||||||
|
else
|
||||||
|
i=findtext(txt,"\n")
|
||||||
|
txt=i?copytext(txt,i+1):null
|
||||||
|
world << "Map size: [X],[Y],[Z]"
|
||||||
|
//for(var/code in codes)
|
||||||
|
// world << "Code \"[code]\":\n[codes[code]]"
|
||||||
|
fdel("map_[mapname].txt")
|
||||||
|
var/F = file("map_[mapname].txt")
|
||||||
|
F << ". = object(\".0\")\n.0\n\ttype = /swapmap\n\tid = \"[mapname]\"\n\tz = [Z]\n\ty = [Y]\n\tx = [X]"
|
||||||
|
if(areas)
|
||||||
|
txt=""
|
||||||
|
for(i=0,i<areas.len,++i)
|
||||||
|
txt+="[i?", ":""]object(\".[i]\")"
|
||||||
|
F << "\tareas = list([txt])"
|
||||||
|
for(i=0,i<areas.len,++i)
|
||||||
|
F << "\t\t.[i]"
|
||||||
|
txt=d2sm_ConvertType(areas[i+1],"\t\t\t")
|
||||||
|
F << copytext(txt,1,length(txt))
|
||||||
|
|
||||||
|
// 2nd pass
|
||||||
|
txt=d2sm_prepmap(filename)
|
||||||
|
while(txt)
|
||||||
|
// skip all non-data sections
|
||||||
|
if(text2ascii(txt)!=40)
|
||||||
|
i=findText(txt,"\n")
|
||||||
|
if(i) txt=copytext(txt,i+1)
|
||||||
|
else txt=null
|
||||||
|
continue
|
||||||
|
i=d2sm_MatchBrace(txt,1,40)
|
||||||
|
var/list/coords=d2sm_ParseCommaList(copytext(txt,2,i))
|
||||||
|
j=findtext(txt,"{",i+1)
|
||||||
|
k=d2sm_MatchBrace(txt,j,123)
|
||||||
|
var/mtxt=copytext(txt,j+2,k-1)
|
||||||
|
var/_x=0,_y=0
|
||||||
|
for(i=1,,++_y)
|
||||||
|
j=findText(mtxt,"\n",i+1)
|
||||||
|
if(!j) break
|
||||||
|
_x=max(_x,(j-i-1)/codelen)
|
||||||
|
i=j
|
||||||
|
// print out this z-level now
|
||||||
|
F << "\t[coords[3]]"
|
||||||
|
i=1
|
||||||
|
for(var/y=_y,y>0,--y) // map is top-down
|
||||||
|
++i
|
||||||
|
F << "\t\t[y]"
|
||||||
|
for(var/x in 1 to _x)
|
||||||
|
F << "\t\t\t[x]"
|
||||||
|
j=i+codelen
|
||||||
|
F << codes[copytext(mtxt,i,j)]
|
||||||
|
i=j
|
||||||
|
txt=copytext(txt,k+1)
|
||||||
|
/* for(z in 1 to Z)
|
||||||
|
F << "\t[z]"
|
||||||
|
for(var/y in 1 to Y)
|
||||||
|
F << "\t\t[y]"
|
||||||
|
for(var/x in 1 to X)
|
||||||
|
F << "\t\t\t[x]"
|
||||||
|
F << codes[pick(codes)] */
|
||||||
|
|
||||||
|
proc/d2sm_ParseCommaList(txt)
|
||||||
|
var/list/L=new
|
||||||
|
var/i,ch
|
||||||
|
for(i=1,i<=length(txt),++i)
|
||||||
|
if(text2ascii(txt,i)>32) break
|
||||||
|
for(,i<=length(txt),++i)
|
||||||
|
ch=text2ascii(txt,i)
|
||||||
|
if(ch==44)
|
||||||
|
L+=copytext(txt,1,i)
|
||||||
|
for(++i,i<=length(txt),++i) if(text2ascii(txt,i)>32) break
|
||||||
|
txt=copytext(txt,i)
|
||||||
|
i=0;continue
|
||||||
|
if(ch==40 || ch==91 || ch==123)
|
||||||
|
i=d2sm_MatchBrace(txt,i,ch)
|
||||||
|
if(!i) return "No matching brace found for [ascii2text(ch)]"
|
||||||
|
if(i>1) L+=copytext(txt,1,i)
|
||||||
|
return L
|
||||||
|
|
||||||
|
proc/d2sm_MatchBrace(txt, i, which)
|
||||||
|
if(which==40) ++which
|
||||||
|
else which+=2
|
||||||
|
var/j,ch
|
||||||
|
for(j=i+1,j<=length(txt),++j)
|
||||||
|
ch=text2ascii(txt,j)
|
||||||
|
if(ch==which) return j
|
||||||
|
if(ch==40 || ch==91 || ch==123)
|
||||||
|
j=d2sm_MatchBrace(txt,j,ch)
|
||||||
|
if(!j) return 0
|
||||||
|
|
||||||
|
proc/d2sm_ConvertType(tt,tabs="")
|
||||||
|
var/i=findText(tt,"{")
|
||||||
|
if(!i) return "[tabs]type = [tt]\n"
|
||||||
|
.="[tabs]type = [copytext(tt,1,i)]\n"
|
||||||
|
var/list/L=d2sm_ParseCommaList(copytext(tt,i+1,d2sm_MatchBrace(tt,i,123)))
|
||||||
|
if(istext(L)) return
|
||||||
|
for(var/pair in L)
|
||||||
|
.="[.][tabs][pair]\n"
|
||||||
|
|
||||||
|
proc/d2sm_Contents(list/conts,n,tabs="")
|
||||||
|
.="[tabs]contents = list("
|
||||||
|
var/i
|
||||||
|
for(i=0,i<n,++i)
|
||||||
|
.+="[i?", ":""]object(\".[i]\")"
|
||||||
|
.+=")\n"
|
||||||
|
tabs+="\t"
|
||||||
|
for(i=0,i<n,++i)
|
||||||
|
.+="[tabs].[i]\n"
|
||||||
|
.+=d2sm_ConvertType(conts[i+1],tabs+"\t")
|
||||||
47
code/modules/maps/randomZlevel.dm
Normal file
47
code/modules/maps/randomZlevel.dm
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
var/list/potentialRandomZlevels = list()
|
||||||
|
|
||||||
|
proc/createRandomZlevel()
|
||||||
|
|
||||||
|
var/text = file2text("maps/RandomZLevels/fileList.txt")
|
||||||
|
|
||||||
|
if (!text) // No random Z-levels for you.
|
||||||
|
return
|
||||||
|
|
||||||
|
world << "\red \b Reticulating Splines"
|
||||||
|
|
||||||
|
var/list/CL = dd_text2list(text, "\n")
|
||||||
|
|
||||||
|
for (var/t in CL)
|
||||||
|
if (!t)
|
||||||
|
continue
|
||||||
|
|
||||||
|
t = trim(t)
|
||||||
|
if (length(t) == 0)
|
||||||
|
continue
|
||||||
|
else if (copytext(t, 1, 2) == "#")
|
||||||
|
continue
|
||||||
|
|
||||||
|
var/pos = findtext(t, " ")
|
||||||
|
var/name = null
|
||||||
|
// var/value = null
|
||||||
|
|
||||||
|
if (pos)
|
||||||
|
name = lowertext(copytext(t, 1, pos))
|
||||||
|
// value = copytext(t, pos + 1)
|
||||||
|
else
|
||||||
|
name = lowertext(t)
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
continue
|
||||||
|
|
||||||
|
potentialRandomZlevels.Add(t)
|
||||||
|
|
||||||
|
|
||||||
|
if(potentialRandomZlevels.len)
|
||||||
|
var/map = pick(potentialRandomZlevels)
|
||||||
|
var/file = file(map)
|
||||||
|
if(isfile(file))
|
||||||
|
maploader.load_map(file)
|
||||||
|
|
||||||
|
else
|
||||||
|
return
|
||||||
249
code/modules/maps/reader.dm
Normal file
249
code/modules/maps/reader.dm
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
dmm_suite{
|
||||||
|
load_map(var/dmm_file as file, var/z_offset as num){
|
||||||
|
if(!z_offset){
|
||||||
|
z_offset = world.maxz+1
|
||||||
|
}
|
||||||
|
var/quote = ascii2text(34)
|
||||||
|
var/tfile = file2text(dmm_file)
|
||||||
|
var/tfile_len = length(tfile)
|
||||||
|
var/list/grid_models[0]
|
||||||
|
var/key_len = length(copytext(tfile,2,findtext(tfile,quote,2,0)))
|
||||||
|
for(var/lpos=1;lpos<tfile_len;lpos=findtext(tfile,"\n",lpos,0)+1){
|
||||||
|
var/tline = copytext(tfile,lpos,findtext(tfile,"\n",lpos,0))
|
||||||
|
if(copytext(tline,1,2)!=quote){break}
|
||||||
|
var/model_key = copytext(tline,2,findtext(tfile,quote,2,0))
|
||||||
|
var/model_contents = copytext(tline,findtext(tfile,"=")+3,length(tline))
|
||||||
|
grid_models[model_key] = model_contents
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
var/zcrd=-1
|
||||||
|
var/ycrd=0
|
||||||
|
var/xcrd=0
|
||||||
|
for(var/zpos=findtext(tfile,"\n(1,1,");TRUE;zpos=findtext(tfile,"\n(1,1,",zpos+1,0)){
|
||||||
|
zcrd++
|
||||||
|
world.maxz = max(world.maxz, zcrd+z_offset)
|
||||||
|
ycrd=0
|
||||||
|
var/zgrid = copytext(tfile,findtext(tfile,quote+"\n",zpos,0)+2,findtext(tfile,"\n"+quote,zpos,0)+1)
|
||||||
|
for(var/gpos=1;gpos!=0;gpos=findtext(zgrid,"\n",gpos,0)+1){
|
||||||
|
var/grid_line = copytext(zgrid,gpos,findtext(zgrid,"\n",gpos,0)+1)
|
||||||
|
var/y_depth = length(zgrid)/(length(grid_line))
|
||||||
|
if(world.maxy<y_depth){world.maxy=y_depth}
|
||||||
|
grid_line=copytext(grid_line,1,length(grid_line))
|
||||||
|
if(!ycrd){
|
||||||
|
ycrd = y_depth
|
||||||
|
}
|
||||||
|
else{ycrd--}
|
||||||
|
xcrd=0
|
||||||
|
for(var/mpos=1;mpos<=length(grid_line);mpos+=key_len){
|
||||||
|
xcrd++
|
||||||
|
if(world.maxx<xcrd){world.maxx=xcrd}
|
||||||
|
var/model_key = copytext(grid_line,mpos,mpos+key_len)
|
||||||
|
parse_grid(grid_models[model_key],xcrd,ycrd,zcrd+z_offset)
|
||||||
|
}
|
||||||
|
if(gpos+length(grid_line)+1>length(zgrid)){break}
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
if(findtext(tfile,quote+"}",zpos,0)+2==tfile_len){break}
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
proc{
|
||||||
|
parse_grid(var/model as text,var/xcrd as num,var/ycrd as num,var/zcrd as num){
|
||||||
|
/*Method parse_grid()
|
||||||
|
- Accepts a text string containing a comma separated list of type paths of the
|
||||||
|
same construction as those contained in a .dmm file, and instantiates them.
|
||||||
|
*/
|
||||||
|
var/list/text_strings[0]
|
||||||
|
for(var/index=1;findtext(model,quote);index++){
|
||||||
|
/*Loop: Stores quoted portions of text in text_strings, and replaces them with an
|
||||||
|
index to that list.
|
||||||
|
- Each iteration represents one quoted section of text.
|
||||||
|
*/
|
||||||
|
text_strings.len=index
|
||||||
|
text_strings[index] = copytext(model,findtext(model,quote)+1,findtext(model,quote,findtext(model,quote)+1,0))
|
||||||
|
model = copytext(model,1,findtext(model,quote))+"~[index]"+copytext(model,findtext(model,quote,findtext(model,quote)+1,0)+1,0)
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
var/list/old_turf_underlays[0]
|
||||||
|
var/old_turf_density
|
||||||
|
var/old_turf_opacity
|
||||||
|
/*The old_turf variables store information about turfs instantiated in this location/iteration.
|
||||||
|
This is done to approximate the layered turf effect of DM's map editor.
|
||||||
|
An image of each turf is stored in old_turf_underlays[], and is later added to the new turf's underlays.
|
||||||
|
*/
|
||||||
|
for(var/dpos=1;dpos!=0;dpos=findtext(model,",",dpos,0)+1){
|
||||||
|
/*Loop: Identifies each object's data, instantiates it, and reconstitues it's fields.
|
||||||
|
- Each iteration represents one object's data, including type path and field values.
|
||||||
|
*/
|
||||||
|
var/full_def = copytext(model,dpos,findtext(model,",",dpos,0))
|
||||||
|
var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))
|
||||||
|
var/list/attributes[0]
|
||||||
|
if(findtext(full_def,"{")){
|
||||||
|
full_def = copytext(full_def,1,length(full_def))
|
||||||
|
for(var/apos=findtext(full_def,"{")+1;apos!=0;apos=findtext(full_def,";",apos,0)+1){
|
||||||
|
//Loop: Identifies each attribute/value pair, and stores it in attributes[].
|
||||||
|
attributes.Add(copytext(full_def,apos,findtext(full_def,";",apos,0)))
|
||||||
|
if(!findtext(copytext(full_def,apos,0),";")){break}
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Construct attributes associative list
|
||||||
|
var/list/fields = new(0)
|
||||||
|
for(var/index=1;index<=attributes.len;index++){
|
||||||
|
var/trim_left = trim_text(copytext(attributes[index],1,findtext(attributes[index],"=")))
|
||||||
|
var/trim_right = trim_text(copytext(attributes[index],findtext(attributes[index],"=")+1,0))
|
||||||
|
//Check for string
|
||||||
|
if(findtext(trim_right,"~")){
|
||||||
|
var/reference_index = copytext(trim_right,findtext(trim_right,"~")+1,0)
|
||||||
|
trim_right=text_strings[text2num(reference_index)]
|
||||||
|
}
|
||||||
|
//Check for number
|
||||||
|
else if(isnum(text2num(trim_right))){
|
||||||
|
trim_right = text2num(trim_right)
|
||||||
|
}
|
||||||
|
//Check for file
|
||||||
|
else if(copytext(trim_right,1,2) == "'"){
|
||||||
|
trim_right = file(copytext(trim_right,2,length(trim_right)))
|
||||||
|
}
|
||||||
|
fields[trim_left] = trim_right
|
||||||
|
}
|
||||||
|
//End construction
|
||||||
|
|
||||||
|
|
||||||
|
//Begin Instanciation
|
||||||
|
var/atom/instance
|
||||||
|
var/dmm_suite/preloader/_preloader = new(fields)
|
||||||
|
if(ispath(atom_def,/area)){
|
||||||
|
instance = locate(atom_def)
|
||||||
|
instance.contents.Add(locate(xcrd,ycrd,zcrd))
|
||||||
|
}
|
||||||
|
else if(ispath(atom_def,/turf)){
|
||||||
|
var/turf/old_turf = locate(xcrd,ycrd,zcrd)
|
||||||
|
if(old_turf.density){old_turf_density = 1}
|
||||||
|
if(old_turf.opacity){old_turf_opacity = 1}
|
||||||
|
if(old_turf.icon){
|
||||||
|
var/image/old_turf_image = image(old_turf.icon,null,old_turf.icon_state,old_turf.layer,old_turf.dir)
|
||||||
|
old_turf_underlays.Add(old_turf_image)
|
||||||
|
}
|
||||||
|
instance = new atom_def(old_turf, _preloader)
|
||||||
|
for(var/inverse_index=old_turf_underlays.len;inverse_index;inverse_index--){
|
||||||
|
var/image/image_underlay = old_turf_underlays[inverse_index]
|
||||||
|
image_underlay.loc = instance
|
||||||
|
instance.underlays.Add(image_underlay)
|
||||||
|
}
|
||||||
|
if(!instance.density){instance.density = old_turf_density}
|
||||||
|
if(!instance.opacity){instance.opacity = old_turf_opacity}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_preloader && instance){
|
||||||
|
_preloader.load(instance)
|
||||||
|
}
|
||||||
|
//End Instanciation
|
||||||
|
if(!findtext(copytext(model,dpos,0),",")){break}
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
for(var/dpos=1;dpos!=0;dpos=findtext(model,",",dpos,0)+1)
|
||||||
|
{
|
||||||
|
/*Loop: Identifies each object's data, instantiates it, and reconstitues it's fields.
|
||||||
|
- Each iteration represents one object's data, including type path and field values.
|
||||||
|
*/
|
||||||
|
var/full_def = copytext(model,dpos,findtext(model,",",dpos,0))
|
||||||
|
var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))
|
||||||
|
var/list/attributes[0]
|
||||||
|
if(findtext(full_def,"{")){
|
||||||
|
full_def = copytext(full_def,1,length(full_def))
|
||||||
|
for(var/apos=findtext(full_def,"{")+1;apos!=0;apos=findtext(full_def,";",apos,0)+1){
|
||||||
|
//Loop: Identifies each attribute/value pair, and stores it in attributes[].
|
||||||
|
attributes.Add(copytext(full_def,apos,findtext(full_def,";",apos,0)))
|
||||||
|
if(!findtext(copytext(full_def,apos,0),";")){break}
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Construct attributes associative list
|
||||||
|
var/list/fields = new(0)
|
||||||
|
for(var/index=1;index<=attributes.len;index++){
|
||||||
|
var/trim_left = trim_text(copytext(attributes[index],1,findtext(attributes[index],"=")))
|
||||||
|
var/trim_right = trim_text(copytext(attributes[index],findtext(attributes[index],"=")+1,0))
|
||||||
|
//Check for string
|
||||||
|
if(findtext(trim_right,"~")){
|
||||||
|
var/reference_index = copytext(trim_right,findtext(trim_right,"~")+1,0)
|
||||||
|
trim_right=text_strings[text2num(reference_index)]
|
||||||
|
}
|
||||||
|
//Check for number
|
||||||
|
else if(isnum(text2num(trim_right))){
|
||||||
|
trim_right = text2num(trim_right)
|
||||||
|
}
|
||||||
|
//Check for file
|
||||||
|
else if(copytext(trim_right,1,2) == "'"){
|
||||||
|
trim_right = file(copytext(trim_right,2,length(trim_right)))
|
||||||
|
}
|
||||||
|
fields[trim_left] = trim_right
|
||||||
|
}
|
||||||
|
//End construction
|
||||||
|
|
||||||
|
|
||||||
|
//Begin Instanciation
|
||||||
|
var/atom/instance
|
||||||
|
var/dmm_suite/preloader/_preloader = new(fields)
|
||||||
|
if(!ispath(atom_def,/area) && !ispath(atom_def,/turf))
|
||||||
|
{
|
||||||
|
instance = new atom_def(locate(xcrd,ycrd,zcrd), _preloader)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(_preloader && instance)
|
||||||
|
{
|
||||||
|
_preloader.load(instance)
|
||||||
|
}
|
||||||
|
//End Instanciation
|
||||||
|
if(!findtext(copytext(model,dpos,0),",")){break}
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
trim_text(var/what as text){
|
||||||
|
while(length(what) && findtext(what," ",1,2)){
|
||||||
|
what=copytext(what,2,0)
|
||||||
|
}
|
||||||
|
while(length(what) && findtext(what," ",length(what),0)){
|
||||||
|
what=copytext(what,1,length(what))
|
||||||
|
}
|
||||||
|
return what
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
atom/New(atom/loc, dmm_suite/preloader/_dmm_preloader){
|
||||||
|
if(istype(_dmm_preloader, /dmm_suite/preloader)){
|
||||||
|
_dmm_preloader.load(src)
|
||||||
|
}
|
||||||
|
. = ..()
|
||||||
|
}
|
||||||
|
dmm_suite{
|
||||||
|
preloader{
|
||||||
|
parent_type = /datum
|
||||||
|
var{
|
||||||
|
list/attributes
|
||||||
|
}
|
||||||
|
New(list/the_attributes){
|
||||||
|
.=..()
|
||||||
|
if(!the_attributes.len){ Del()}
|
||||||
|
attributes = the_attributes
|
||||||
|
}
|
||||||
|
proc{
|
||||||
|
load(atom/what){
|
||||||
|
for(var/attribute in attributes){
|
||||||
|
what.vars[attribute] = attributes[attribute]
|
||||||
|
}
|
||||||
|
Del()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
174
code/modules/maps/writer.dm
Normal file
174
code/modules/maps/writer.dm
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
#define DMM_IGNORE_AREAS 1
|
||||||
|
#define DMM_IGNORE_TURFS 2
|
||||||
|
#define DMM_IGNORE_OBJS 4
|
||||||
|
#define DMM_IGNORE_NPCS 8
|
||||||
|
#define DMM_IGNORE_PLAYERS 16
|
||||||
|
#define DMM_IGNORE_MOBS 24
|
||||||
|
dmm_suite{
|
||||||
|
var{
|
||||||
|
quote = "\""
|
||||||
|
list/letter_digits = list(
|
||||||
|
"a","b","c","d","e",
|
||||||
|
"f","g","h","i","j",
|
||||||
|
"k","l","m","n","o",
|
||||||
|
"p","q","r","s","t",
|
||||||
|
"u","v","w","x","y",
|
||||||
|
"z",
|
||||||
|
"A","B","C","D","E",
|
||||||
|
"F","G","H","I","J",
|
||||||
|
"K","L","M","N","O",
|
||||||
|
"P","Q","R","S","T",
|
||||||
|
"U","V","W","X","Y",
|
||||||
|
"Z"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
save_map(var/turf/t1 as turf, var/turf/t2 as turf, var/map_name as text, var/flags as num){
|
||||||
|
//Check for illegal characters in file name... in a cheap way.
|
||||||
|
if(!((ckeyEx(map_name)==map_name) && ckeyEx(map_name))){
|
||||||
|
CRASH("Invalid text supplied to proc save_map, invalid characters or empty string.")
|
||||||
|
}
|
||||||
|
//Check for valid turfs.
|
||||||
|
if(!isturf(t1) || !isturf(t2)){
|
||||||
|
CRASH("Invalid arguments supplied to proc save_map, arguments were not turfs.")
|
||||||
|
}
|
||||||
|
var/file_text = write_map(t1,t2,flags)
|
||||||
|
if(fexists("[map_name].dmm")){
|
||||||
|
fdel("[map_name].dmm")
|
||||||
|
}
|
||||||
|
var/saved_map = file("[map_name].dmm")
|
||||||
|
saved_map << file_text
|
||||||
|
return saved_map
|
||||||
|
}
|
||||||
|
write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num){
|
||||||
|
//Check for valid turfs.
|
||||||
|
if(!isturf(t1) || !isturf(t2)){
|
||||||
|
CRASH("Invalid arguments supplied to proc write_map, arguments were not turfs.")
|
||||||
|
}
|
||||||
|
var/turf/nw = locate(min(t1.x,t2.x),max(t1.y,t2.y),min(t1.z,t2.z))
|
||||||
|
var/turf/se = locate(max(t1.x,t2.x),min(t1.y,t2.y),max(t1.z,t2.z))
|
||||||
|
var/list/templates[0]
|
||||||
|
var/template_buffer = {""}
|
||||||
|
var/dmm_text = {""}
|
||||||
|
for(var/pos_z=nw.z;pos_z<=se.z;pos_z++){
|
||||||
|
for(var/pos_y=nw.y;pos_y>=se.y;pos_y--){
|
||||||
|
for(var/pos_x=nw.x;pos_x<=se.x;pos_x++){
|
||||||
|
var/turf/test_turf = locate(pos_x,pos_y,pos_z)
|
||||||
|
var/test_template = make_template(test_turf, flags)
|
||||||
|
var/template_number = templates.Find(test_template)
|
||||||
|
if(!template_number){
|
||||||
|
templates.Add(test_template)
|
||||||
|
template_number = templates.len
|
||||||
|
}
|
||||||
|
template_buffer += "[template_number],"
|
||||||
|
}
|
||||||
|
template_buffer += ";"
|
||||||
|
}
|
||||||
|
template_buffer += "."
|
||||||
|
}
|
||||||
|
var/key_length = round/*floor*/(log(letter_digits.len,templates.len-1)+1)
|
||||||
|
var/list/keys[templates.len]
|
||||||
|
for(var/key_pos=1;key_pos<=templates.len;key_pos++){
|
||||||
|
keys[key_pos] = get_model_key(key_pos,key_length)
|
||||||
|
dmm_text += {""[keys[key_pos]]" = ([templates[key_pos]])\n"}
|
||||||
|
}
|
||||||
|
var/z_level = 0
|
||||||
|
for(var/z_pos=1;TRUE;z_pos=findtext(template_buffer,".",z_pos)+1){
|
||||||
|
if(z_pos>=length(template_buffer)){break}
|
||||||
|
if(z_level){dmm_text+={"\n"}}
|
||||||
|
dmm_text += {"\n(1,1,[++z_level]) = {"\n"}
|
||||||
|
var/z_block = copytext(template_buffer,z_pos,findtext(template_buffer,".",z_pos))
|
||||||
|
for(var/y_pos=1;TRUE;y_pos=findtext(z_block,";",y_pos)+1){
|
||||||
|
if(y_pos>=length(z_block)){break}
|
||||||
|
var/y_block = copytext(z_block,y_pos,findtext(z_block,";",y_pos))
|
||||||
|
for(var/x_pos=1;TRUE;x_pos=findtext(y_block,",",x_pos)+1){
|
||||||
|
if(x_pos>=length(y_block)){break}
|
||||||
|
var/x_block = copytext(y_block,x_pos,findtext(y_block,",",x_pos))
|
||||||
|
var/key_number = text2num(x_block)
|
||||||
|
var/temp_key = keys[key_number]
|
||||||
|
dmm_text += temp_key
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
dmm_text += {"\n"}
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
dmm_text += {"\"}"}
|
||||||
|
sleep(-1)
|
||||||
|
}
|
||||||
|
return dmm_text
|
||||||
|
}
|
||||||
|
proc{
|
||||||
|
make_template(var/turf/model as turf, var/flags as num){
|
||||||
|
var/template = ""
|
||||||
|
var/obj_template = ""
|
||||||
|
var/mob_template = ""
|
||||||
|
var/turf_template = ""
|
||||||
|
if(!(flags & DMM_IGNORE_TURFS)){
|
||||||
|
turf_template = "[model.type][check_attributes(model)],"
|
||||||
|
} else{ turf_template = "[world.turf],"}
|
||||||
|
var/area_template = ""
|
||||||
|
if(!(flags & DMM_IGNORE_OBJS)){
|
||||||
|
for(var/obj/O in model.contents){
|
||||||
|
obj_template += "[O.type][check_attributes(O)],"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(var/mob/M in model.contents){
|
||||||
|
if(M.client){
|
||||||
|
if(!(flags & DMM_IGNORE_PLAYERS)){
|
||||||
|
mob_template += "[M.type][check_attributes(M)],"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(!(flags & DMM_IGNORE_NPCS)){
|
||||||
|
mob_template += "[M.type][check_attributes(M)],"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!(flags & DMM_IGNORE_AREAS)){
|
||||||
|
var/area/m_area = model.loc
|
||||||
|
area_template = "[m_area.type][check_attributes(m_area)]"
|
||||||
|
} else{ area_template = "[world.area]"}
|
||||||
|
template = "[obj_template][mob_template][turf_template][area_template]"
|
||||||
|
return template
|
||||||
|
}
|
||||||
|
check_attributes(var/atom/A){
|
||||||
|
var/attributes_text = {"{"}
|
||||||
|
for(var/V in A.vars){
|
||||||
|
sleep(-1)
|
||||||
|
if((!issaved(A.vars[V])) || (A.vars[V]==initial(A.vars[V]))){continue}
|
||||||
|
if(istext(A.vars[V])){
|
||||||
|
attributes_text += {"[V] = "[A.vars[V]]""}
|
||||||
|
}
|
||||||
|
else if(isnum(A.vars[V])||ispath(A.vars[V])){
|
||||||
|
attributes_text += {"[V] = [A.vars[V]]"}
|
||||||
|
}
|
||||||
|
else if(isicon(A.vars[V])||isfile(A.vars[V])){
|
||||||
|
attributes_text += {"[V] = '[A.vars[V]]'"}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if(attributes_text != {"{"}){
|
||||||
|
attributes_text+={"; "}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(attributes_text=={"{"}){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(copytext(attributes_text, length(attributes_text)-1, 0) == {"; "}){
|
||||||
|
attributes_text = copytext(attributes_text, 1, length(attributes_text)-1)
|
||||||
|
}
|
||||||
|
attributes_text += {"}"}
|
||||||
|
return attributes_text
|
||||||
|
}
|
||||||
|
get_model_key(var/which as num, var/key_length as num){
|
||||||
|
var/key = ""
|
||||||
|
var/working_digit = which-1
|
||||||
|
for(var/digit_pos=key_length;digit_pos>=1;digit_pos--){
|
||||||
|
var/place_value = round/*floor*/(working_digit/(letter_digits.len**(digit_pos-1)))
|
||||||
|
working_digit-=place_value*(letter_digits.len**(digit_pos-1))
|
||||||
|
key = "[key][letter_digits[place_value+1]]"
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -157,6 +157,9 @@
|
|||||||
SetParalysis(0)
|
SetParalysis(0)
|
||||||
SetStunned(0)
|
SetStunned(0)
|
||||||
SetWeakened(0)
|
SetWeakened(0)
|
||||||
|
src.radiation = 0
|
||||||
|
src.nutrition = 400
|
||||||
|
src.bodytemperature = 310
|
||||||
//src.health = 100
|
//src.health = 100
|
||||||
if(ishuman(src))
|
if(ishuman(src))
|
||||||
var/mob/living/carbon/human/H = src
|
var/mob/living/carbon/human/H = src
|
||||||
|
|||||||
66
maps/RandomZLevels/assistantChamber.dmm
Normal file
66
maps/RandomZLevels/assistantChamber.dmm
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
"a" = (/turf/space,/area)
|
||||||
|
"b" = (/turf/unsimulated/wall,/area)
|
||||||
|
"c" = (/obj/machinery/shield,/turf/simulated/wall/cult,/area/turret_protected/AssistantRoom)
|
||||||
|
"d" = (/obj/machinery/turret{dir = 8; lasers = 1; name = "Angry Turret"},/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"e" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/turret{dir = 8; lasers = 1; name = "Angry Turret"},/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"f" = (/obj/item/weapon/gift,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"g" = (/obj/effect/accelerated_particle,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"h" = (/obj/item/weapon/gun/energy/gun/nuclear,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"i" = (/obj/item/device/soulstone,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"j" = (/obj/item/ammo_magazine,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"k" = (/obj/effect/rune,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"l" = (/obj/machinery/turret{dir = 8; lasers = 1; name = "Angry Turret"},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"m" = (/obj/item/weapon/mousetrap/armed,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"n" = (/obj/item/weapon/nullrod,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"o" = (/obj/item/weapon/card/id/captains_spare,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"p" = (/obj/item/weapon/gun/energy/pulse_rifle/M1911,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"q" = (/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"r" = (/obj/item/weapon/card/emag,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"s" = (/obj/item/tk_grab,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"t" = (/obj/item/device/powersink,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"u" = (/obj/item/device/radio/beacon,/obj/item/weapon/caution,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"v" = (/obj/item/brain,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"w" = (/obj/item/weapon/gun/energy/laser/captain,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"x" = (/obj/item/weapon/gun/projectile/deagle/gold,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"y" = (/obj/item/weapon/sord,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"z" = (/obj/item/weapon/gun/energy/lasercannon,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"A" = (/obj/item/weapon/gun/energy/crossbow/largecrossbow,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"B" = (/obj/item/weapon/gun/energy/pulse_rifle/destroyer,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"C" = (/obj/item/toy/spinningtoy,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"D" = (/obj/item/weapon/card/id/centcom,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"E" = (/obj/item/weapon/gun/grenadelauncher,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"F" = (/obj/item/weapon/chemsprayer,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
"G" = (/obj/machinery/turret{dir = 8; lasers = 1; name = "Angry Turret"},/obj/machinery/light,/turf/simulated/floor{icon_state = "whiteshiny"},/area/turret_protected/AssistantRoom)
|
||||||
|
|
||||||
|
(1,1,1) = {"
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaabbbbbbbbbbbbaaaaaaaaa
|
||||||
|
aaaaaaaaabccccccccccbaaaaaaaaa
|
||||||
|
aaaaaaaaabccddddddccbaaaaaaaaa
|
||||||
|
aaaaaaaaabcefghijklcbaaaaaaaaa
|
||||||
|
aaaaaaaaabcemnopqrlcbaaaaaaaaa
|
||||||
|
aaaaaaaaabcestquvqlcbaaaaaaaaa
|
||||||
|
aaaaaaaaabcewqqxqylcbaaaaaaaaa
|
||||||
|
aaaaaaaaabceqzAqBqlcbaaaaaaaaa
|
||||||
|
aaaaaaaaabceCqDqEFlcbaaaaaaaaa
|
||||||
|
aaaaaaaaabccGGGGGGccbaaaaaaaaa
|
||||||
|
aaaaaaaaabccccccccccbaaaaaaaaa
|
||||||
|
aaaaaaaaabbbbbbbbbbbbaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
"}
|
||||||
8
maps/RandomZLevels/fileList.txt
Normal file
8
maps/RandomZLevels/fileList.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#List the potential random Z-levels here.
|
||||||
|
#Maps must be the full path to them
|
||||||
|
#Maps should be 255x255 or smaller and be bounded. Falling off the edge of the map will result in undefined behavior.
|
||||||
|
#Please ensure that your maps have a minimum distnace from the edge of 10 units, due to 'seamless transition' range
|
||||||
|
#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START
|
||||||
|
|
||||||
|
#maps/RandomZLevels/assistantChamber.dmm
|
||||||
|
|
||||||
@@ -96,6 +96,7 @@
|
|||||||
#define FILE_DIR "code/modules/detectivework"
|
#define FILE_DIR "code/modules/detectivework"
|
||||||
#define FILE_DIR "code/modules/flufftext"
|
#define FILE_DIR "code/modules/flufftext"
|
||||||
#define FILE_DIR "code/modules/food"
|
#define FILE_DIR "code/modules/food"
|
||||||
|
#define FILE_DIR "code/modules/maps"
|
||||||
#define FILE_DIR "code/modules/mining"
|
#define FILE_DIR "code/modules/mining"
|
||||||
#define FILE_DIR "code/modules/mob"
|
#define FILE_DIR "code/modules/mob"
|
||||||
#define FILE_DIR "code/modules/mob/dead"
|
#define FILE_DIR "code/modules/mob/dead"
|
||||||
@@ -178,6 +179,7 @@
|
|||||||
#define FILE_DIR "icons/vending_icons"
|
#define FILE_DIR "icons/vending_icons"
|
||||||
#define FILE_DIR "interface"
|
#define FILE_DIR "interface"
|
||||||
#define FILE_DIR "maps"
|
#define FILE_DIR "maps"
|
||||||
|
#define FILE_DIR "maps/RandomZLevels"
|
||||||
#define FILE_DIR "sound"
|
#define FILE_DIR "sound"
|
||||||
#define FILE_DIR "sound/AI"
|
#define FILE_DIR "sound/AI"
|
||||||
#define FILE_DIR "sound/ambience"
|
#define FILE_DIR "sound/ambience"
|
||||||
@@ -814,6 +816,11 @@
|
|||||||
#include "code\modules\food\food.dm"
|
#include "code\modules\food\food.dm"
|
||||||
#include "code\modules\food\meat.dm"
|
#include "code\modules\food\meat.dm"
|
||||||
#include "code\modules\food\recipes_microwave.dm"
|
#include "code\modules\food\recipes_microwave.dm"
|
||||||
|
#include "code\modules\maps\dmm_suite.dm"
|
||||||
|
#include "code\modules\maps\randomZlevel.dm"
|
||||||
|
#include "code\modules\maps\reader.dm"
|
||||||
|
#include "code\modules\maps\SwapMaps.dm"
|
||||||
|
#include "code\modules\maps\writer.dm"
|
||||||
#include "code\modules\mining\machine_input_output_plates.dm"
|
#include "code\modules\mining\machine_input_output_plates.dm"
|
||||||
#include "code\modules\mining\machine_processing.dm"
|
#include "code\modules\mining\machine_processing.dm"
|
||||||
#include "code\modules\mining\machine_stacking.dm"
|
#include "code\modules\mining\machine_stacking.dm"
|
||||||
@@ -1071,8 +1078,6 @@
|
|||||||
#include "code\WorkInProgress\explosion_particles.dm"
|
#include "code\WorkInProgress\explosion_particles.dm"
|
||||||
#include "code\WorkInProgress\BS12\uplink_kits.dm"
|
#include "code\WorkInProgress\BS12\uplink_kits.dm"
|
||||||
#include "code\WorkInProgress\BS12\uplinks.dm"
|
#include "code\WorkInProgress\BS12\uplinks.dm"
|
||||||
#include "code\WorkInProgress\mapload\dmm_suite.dm"
|
|
||||||
#include "code\WorkInProgress\mapload\reader.dm"
|
|
||||||
#include "code\WorkInProgress\organs\implants.dm"
|
#include "code\WorkInProgress\organs\implants.dm"
|
||||||
#include "code\WorkInProgress\organs\organs.dm"
|
#include "code\WorkInProgress\organs\organs.dm"
|
||||||
#include "interface\interface.dm"
|
#include "interface\interface.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user