Merge remote branch 'rusanon/master'
commit
ccc234fc4a
@ -0,0 +1,6 @@
|
|||||||
|
mkdir build-real
|
||||||
|
cd build-real
|
||||||
|
cmake ..\.. -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE:string=Release --trace > trace-stdout.txt 2> trace-stderr.txt
|
||||||
|
mingw32-make 2> log.txt
|
||||||
|
pause
|
||||||
|
dir file.xxx
|
@ -0,0 +1,284 @@
|
|||||||
|
#!python
|
||||||
|
"""Bootstrap setuptools installation
|
||||||
|
|
||||||
|
If you want to use setuptools in your package's setup.py, just include this
|
||||||
|
file in the same directory with it, and add this to the top of your setup.py::
|
||||||
|
|
||||||
|
from ez_setup import use_setuptools
|
||||||
|
use_setuptools()
|
||||||
|
|
||||||
|
If you want to require a specific version of setuptools, set a download
|
||||||
|
mirror, or use an alternate download directory, you can do so by supplying
|
||||||
|
the appropriate options to ``use_setuptools()``.
|
||||||
|
|
||||||
|
This file can also be run as a script to install or upgrade setuptools.
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
DEFAULT_VERSION = "0.6c11"
|
||||||
|
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
|
||||||
|
|
||||||
|
md5_data = {
|
||||||
|
'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
|
||||||
|
'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
|
||||||
|
'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
|
||||||
|
'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
|
||||||
|
'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
|
||||||
|
'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
|
||||||
|
'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
|
||||||
|
'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
|
||||||
|
'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
|
||||||
|
'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
|
||||||
|
'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
|
||||||
|
'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
|
||||||
|
'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
|
||||||
|
'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
|
||||||
|
'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
|
||||||
|
'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
|
||||||
|
'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
|
||||||
|
'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
|
||||||
|
'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
|
||||||
|
'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
|
||||||
|
'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
|
||||||
|
'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
|
||||||
|
'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
|
||||||
|
'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
|
||||||
|
'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
|
||||||
|
'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
|
||||||
|
'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
|
||||||
|
'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
|
||||||
|
'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
|
||||||
|
'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
|
||||||
|
'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
|
||||||
|
'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
|
||||||
|
'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
|
||||||
|
'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
|
||||||
|
'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
|
||||||
|
'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
|
||||||
|
'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
|
||||||
|
'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
|
||||||
|
'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
|
||||||
|
'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
|
||||||
|
'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
|
||||||
|
'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
|
||||||
|
}
|
||||||
|
|
||||||
|
import sys, os
|
||||||
|
try: from hashlib import md5
|
||||||
|
except ImportError: from md5 import md5
|
||||||
|
|
||||||
|
def _validate_md5(egg_name, data):
|
||||||
|
if egg_name in md5_data:
|
||||||
|
digest = md5(data).hexdigest()
|
||||||
|
if digest != md5_data[egg_name]:
|
||||||
|
print >>sys.stderr, (
|
||||||
|
"md5 validation of %s failed! (Possible download problem?)"
|
||||||
|
% egg_name
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def use_setuptools(
|
||||||
|
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
|
||||||
|
download_delay=15
|
||||||
|
):
|
||||||
|
"""Automatically find/download setuptools and make it available on sys.path
|
||||||
|
|
||||||
|
`version` should be a valid setuptools version number that is available
|
||||||
|
as an egg for download under the `download_base` URL (which should end with
|
||||||
|
a '/'). `to_dir` is the directory where setuptools will be downloaded, if
|
||||||
|
it is not already available. If `download_delay` is specified, it should
|
||||||
|
be the number of seconds that will be paused before initiating a download,
|
||||||
|
should one be required. If an older version of setuptools is installed,
|
||||||
|
this routine will print a message to ``sys.stderr`` and raise SystemExit in
|
||||||
|
an attempt to abort the calling script.
|
||||||
|
"""
|
||||||
|
was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
|
||||||
|
def do_download():
|
||||||
|
egg = download_setuptools(version, download_base, to_dir, download_delay)
|
||||||
|
sys.path.insert(0, egg)
|
||||||
|
import setuptools; setuptools.bootstrap_install_from = egg
|
||||||
|
try:
|
||||||
|
import pkg_resources
|
||||||
|
except ImportError:
|
||||||
|
return do_download()
|
||||||
|
try:
|
||||||
|
pkg_resources.require("setuptools>="+version); return
|
||||||
|
except pkg_resources.VersionConflict, e:
|
||||||
|
if was_imported:
|
||||||
|
print >>sys.stderr, (
|
||||||
|
"The required version of setuptools (>=%s) is not available, and\n"
|
||||||
|
"can't be installed while this script is running. Please install\n"
|
||||||
|
" a more recent version first, using 'easy_install -U setuptools'."
|
||||||
|
"\n\n(Currently using %r)"
|
||||||
|
) % (version, e.args[0])
|
||||||
|
sys.exit(2)
|
||||||
|
else:
|
||||||
|
del pkg_resources, sys.modules['pkg_resources'] # reload ok
|
||||||
|
return do_download()
|
||||||
|
except pkg_resources.DistributionNotFound:
|
||||||
|
return do_download()
|
||||||
|
|
||||||
|
def download_setuptools(
|
||||||
|
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
|
||||||
|
delay = 15
|
||||||
|
):
|
||||||
|
"""Download setuptools from a specified location and return its filename
|
||||||
|
|
||||||
|
`version` should be a valid setuptools version number that is available
|
||||||
|
as an egg for download under the `download_base` URL (which should end
|
||||||
|
with a '/'). `to_dir` is the directory where the egg will be downloaded.
|
||||||
|
`delay` is the number of seconds to pause before an actual download attempt.
|
||||||
|
"""
|
||||||
|
import urllib2, shutil
|
||||||
|
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
|
||||||
|
url = download_base + egg_name
|
||||||
|
saveto = os.path.join(to_dir, egg_name)
|
||||||
|
src = dst = None
|
||||||
|
if not os.path.exists(saveto): # Avoid repeated downloads
|
||||||
|
try:
|
||||||
|
from distutils import log
|
||||||
|
if delay:
|
||||||
|
log.warn("""
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
This script requires setuptools version %s to run (even to display
|
||||||
|
help). I will attempt to download it for you (from
|
||||||
|
%s), but
|
||||||
|
you may need to enable firewall access for this script first.
|
||||||
|
I will start the download in %d seconds.
|
||||||
|
|
||||||
|
(Note: if this machine does not have network access, please obtain the file
|
||||||
|
|
||||||
|
%s
|
||||||
|
|
||||||
|
and place it in this directory before rerunning this script.)
|
||||||
|
---------------------------------------------------------------------------""",
|
||||||
|
version, download_base, delay, url
|
||||||
|
); from time import sleep; sleep(delay)
|
||||||
|
log.warn("Downloading %s", url)
|
||||||
|
src = urllib2.urlopen(url)
|
||||||
|
# Read/write all in one block, so we don't create a corrupt file
|
||||||
|
# if the download is interrupted.
|
||||||
|
data = _validate_md5(egg_name, src.read())
|
||||||
|
dst = open(saveto,"wb"); dst.write(data)
|
||||||
|
finally:
|
||||||
|
if src: src.close()
|
||||||
|
if dst: dst.close()
|
||||||
|
return os.path.realpath(saveto)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv, version=DEFAULT_VERSION):
|
||||||
|
"""Install or upgrade setuptools and EasyInstall"""
|
||||||
|
try:
|
||||||
|
import setuptools
|
||||||
|
except ImportError:
|
||||||
|
egg = None
|
||||||
|
try:
|
||||||
|
egg = download_setuptools(version, delay=0)
|
||||||
|
sys.path.insert(0,egg)
|
||||||
|
from setuptools.command.easy_install import main
|
||||||
|
return main(list(argv)+[egg]) # we're done here
|
||||||
|
finally:
|
||||||
|
if egg and os.path.exists(egg):
|
||||||
|
os.unlink(egg)
|
||||||
|
else:
|
||||||
|
if setuptools.__version__ == '0.0.1':
|
||||||
|
print >>sys.stderr, (
|
||||||
|
"You have an obsolete version of setuptools installed. Please\n"
|
||||||
|
"remove it from your system entirely before rerunning this script."
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
req = "setuptools>="+version
|
||||||
|
import pkg_resources
|
||||||
|
try:
|
||||||
|
pkg_resources.require(req)
|
||||||
|
except pkg_resources.VersionConflict:
|
||||||
|
try:
|
||||||
|
from setuptools.command.easy_install import main
|
||||||
|
except ImportError:
|
||||||
|
from easy_install import main
|
||||||
|
main(list(argv)+[download_setuptools(delay=0)])
|
||||||
|
sys.exit(0) # try to force an exit
|
||||||
|
else:
|
||||||
|
if argv:
|
||||||
|
from setuptools.command.easy_install import main
|
||||||
|
main(argv)
|
||||||
|
else:
|
||||||
|
print "Setuptools version",version,"or greater has been installed."
|
||||||
|
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
|
||||||
|
|
||||||
|
def update_md5(filenames):
|
||||||
|
"""Update our built-in md5 registry"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
for name in filenames:
|
||||||
|
base = os.path.basename(name)
|
||||||
|
f = open(name,'rb')
|
||||||
|
md5_data[base] = md5(f.read()).hexdigest()
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
data = [" %r: %r,\n" % it for it in md5_data.items()]
|
||||||
|
data.sort()
|
||||||
|
repl = "".join(data)
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
srcfile = inspect.getsourcefile(sys.modules[__name__])
|
||||||
|
f = open(srcfile, 'rb'); src = f.read(); f.close()
|
||||||
|
|
||||||
|
match = re.search("\nmd5_data = {\n([^}]+)}", src)
|
||||||
|
if not match:
|
||||||
|
print >>sys.stderr, "Internal error!"
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
src = src[:match.start(1)] + repl + src[match.end(1):]
|
||||||
|
f = open(srcfile,'w')
|
||||||
|
f.write(src)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
if len(sys.argv)>2 and sys.argv[1]=='--md5update':
|
||||||
|
update_md5(sys.argv[2:])
|
||||||
|
else:
|
||||||
|
main(sys.argv[1:])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
|||||||
import pydfhack, os
|
|
||||||
|
|
||||||
class API(pydfhack._API):
|
|
||||||
for file in ["Memory.xml", os.path.join("..","..","output","Memory.xml")]:
|
|
||||||
if os.path.isfile(file):
|
|
||||||
datafile = file
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
raise ImportError, "Memory.xml not found."
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwds):
|
|
||||||
pydfhack._API.__init__(self, API.datafile)
|
|
||||||
|
|
||||||
self._map_mgr_type = Map
|
|
||||||
self._vegetation_mgr_type = Vegetation
|
|
||||||
self._gui_mgr_type = GUI
|
|
||||||
|
|
||||||
class Map(pydfhack._MapManager):
|
|
||||||
def __init__(self, *args, **kwds):
|
|
||||||
pydfhack._MapManager.__init__(self, args, kwds)
|
|
||||||
|
|
||||||
class Vegetation(pydfhack._VegetationManager):
|
|
||||||
def __init__(self, *args, **kwds):
|
|
||||||
pydfhack._VegetationManager.__init__(self, args, kwds)
|
|
||||||
|
|
||||||
class GUI(pydfhack._GUIManager):
|
|
||||||
def __init__(self, *args, **kwds):
|
|
||||||
pydfhack._GUIManager.__init__(self, args, kwds)
|
|
@ -0,0 +1 @@
|
|||||||
|
from .pydfapi import API
|
@ -0,0 +1,139 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Module for high-level abstraction of tiles
|
||||||
|
"""
|
||||||
|
from collections import namedtuple
|
||||||
|
from .pydftypes import Rectangle
|
||||||
|
from .mixins import NoStart
|
||||||
|
from .decorators import suspend
|
||||||
|
|
||||||
|
class Point(object):
|
||||||
|
x = None
|
||||||
|
y = None
|
||||||
|
z = None
|
||||||
|
block = False
|
||||||
|
def __init__(self, x, y, z, block=False):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.z = z
|
||||||
|
self.block = block
|
||||||
|
|
||||||
|
def get_block(self):
|
||||||
|
if not self.block:
|
||||||
|
return Point(self.x/16, self.y/16, self.z, True)
|
||||||
|
else:
|
||||||
|
return self
|
||||||
|
|
||||||
|
@property
|
||||||
|
def xyz(self):
|
||||||
|
return (self.x, self.y, self.z)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def rect(self):
|
||||||
|
"""
|
||||||
|
Return block coords in form (x1, y1, x2, y2)
|
||||||
|
"""
|
||||||
|
block = self.get_block()
|
||||||
|
x1 = block.x * 16
|
||||||
|
y1 = block.y * 16
|
||||||
|
return Rectangle(x1, y1, x1+15, y1+15)
|
||||||
|
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
b = ''
|
||||||
|
if self.block:
|
||||||
|
b = ', Block'
|
||||||
|
return "<Point(X:{0.x}, Y:{0.y}, Z:{0.z}{1})>".format(self, b)
|
||||||
|
|
||||||
|
class Block(NoStart):
|
||||||
|
"""
|
||||||
|
16x16 tiles block
|
||||||
|
"""
|
||||||
|
api = None
|
||||||
|
tiles = None
|
||||||
|
coords = None
|
||||||
|
x1 = None
|
||||||
|
y1 = None
|
||||||
|
def __init__(self, api, coords):
|
||||||
|
"""
|
||||||
|
api is instance of API, which is used for read/write operations
|
||||||
|
coords is Point object
|
||||||
|
"""
|
||||||
|
self.api = api
|
||||||
|
if not isinstance(coords, Point):
|
||||||
|
raise Exception(u"coords parameter should be Point")
|
||||||
|
|
||||||
|
coords = coords.get_block()
|
||||||
|
self.coords = coords
|
||||||
|
self.rect = self.coords.rect
|
||||||
|
self.reload()
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def reload(self):
|
||||||
|
tile_types = self.api.maps.Read_Tile_Types(point=self.coords)
|
||||||
|
tile_flags = self.api.maps.Read_Designations(point=self.coords)
|
||||||
|
if self.tiles:
|
||||||
|
for x in range(16):
|
||||||
|
for y in range(16):
|
||||||
|
self.tiles[x][y].update(ttype=tile_types[x][y], flags=tile_flags[x][y])
|
||||||
|
else:
|
||||||
|
self.tiles = []
|
||||||
|
for x in range(16):
|
||||||
|
row = []
|
||||||
|
for y in range(16):
|
||||||
|
row.append(Tile(self, tile_types[x][y], tile_flags[x][y], self.rect.x1 + x, self.rect.y1 + y, self.coords.z))
|
||||||
|
self.tiles.append(row)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def save(self):
|
||||||
|
tile_types = map(lambda x:range(16), range(16))
|
||||||
|
tile_flags = map(lambda x:range(16), range(16))
|
||||||
|
for x in range(16):
|
||||||
|
for y in range(16):
|
||||||
|
tile_types[x][y] = self.tiles[x][y].ttype
|
||||||
|
tile_flags[x][y] = self.tiles[x][y].flags
|
||||||
|
self.api.maps.Write_Tile_Types(point=self.coords, tiles=tile_types)
|
||||||
|
# Designations are bugged
|
||||||
|
|
||||||
|
#self.api.maps.Write_Designations(point=self.coords, tiles=tile_flags)
|
||||||
|
|
||||||
|
def get_tile(self, x=0, y=0, z=0, point=None):
|
||||||
|
if point:
|
||||||
|
x, y, z = point.xyz
|
||||||
|
|
||||||
|
if z == self.coords.z and (self.rect.y1 <= y <= self.rect.y2) and (self.rect.x1 <= x <= self.rect.x2):
|
||||||
|
return self.tiles[x%16][y%16]
|
||||||
|
else:
|
||||||
|
raise Exception("This tile does not belong to this block")
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<Block(X:{2}-{4}, Y:{3}-{5}, Z:{1.z})>".format(self, self.coords, *self.coords.rect)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Tile(object):
|
||||||
|
coords = None
|
||||||
|
block = None
|
||||||
|
ttype = None
|
||||||
|
temperature = None
|
||||||
|
flags = None
|
||||||
|
def __init__(self, block, ttype, flags, x=0, y=0, z=0, point=None):
|
||||||
|
self.ttype = ttype
|
||||||
|
self.flags = flags
|
||||||
|
if not point:
|
||||||
|
point = Point(x, y, z)
|
||||||
|
self.coords = point
|
||||||
|
self.block = block
|
||||||
|
|
||||||
|
def update(self, ttype, flags):
|
||||||
|
self.ttype = ttype
|
||||||
|
self.flags = flags
|
||||||
|
|
||||||
|
def reload(self):
|
||||||
|
self.block.reload()
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
self.block.save()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<Tile({0.ttype} at {1.x}, {1.y}, {1.z})>".format(self, self.coords)
|
@ -0,0 +1,18 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python class for DF_Hack::Construction
|
||||||
|
"""
|
||||||
|
from ._pydfhack import _ConstructionManager
|
||||||
|
from .mixins import NeedsStart
|
||||||
|
from .decorators import suspend
|
||||||
|
|
||||||
|
class Construction(NeedsStart, _ConstructionManager):
|
||||||
|
api = None
|
||||||
|
cls = _ConstructionManager
|
||||||
|
def __init__(self, api, *args, **kwds):
|
||||||
|
self.cls.__init__(self, args, kwds)
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read(self, *args, **kw):
|
||||||
|
return self.cls.Read(self, *args, **kw)
|
@ -0,0 +1,34 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python class for DF_Hack::Creature
|
||||||
|
"""
|
||||||
|
from ._pydfhack import _CreatureManager
|
||||||
|
from .mixins import NeedsStart
|
||||||
|
from .decorators import suspend
|
||||||
|
|
||||||
|
class Creature(NeedsStart, _CreatureManager):
|
||||||
|
api = None
|
||||||
|
cls = _CreatureManager
|
||||||
|
def __init__(self, api, *args, **kwds):
|
||||||
|
self.cls.__init__(self, args, kwds)
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Creature(self, *args, **kw):
|
||||||
|
return self.cls.Read_Creature(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Get_Dwarf_Race_Index(self, *args, **kw):
|
||||||
|
return self.cls.Get_Dwarf_Race_Index(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Write_Labors(self, *args, **kw):
|
||||||
|
return self.cls.Write_Labors(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Creature_In_Box(self, *args, **kw):
|
||||||
|
return self.cls.Read_Creature_In_Box(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Get_Dwarf_Civ_id(self, *args, **kw):
|
||||||
|
return self.cls.Get_Dwarf_Civ_id(self, *args, **kw)
|
@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Decorators for bound classes
|
||||||
|
"""
|
||||||
|
from decorator import decorator
|
||||||
|
|
||||||
|
@decorator
|
||||||
|
def suspend(func, self, *args, **kw):
|
||||||
|
"""
|
||||||
|
This decorator will try to suspend DF and start needed module before running func.
|
||||||
|
If DF was resumed when decorator was run, it will try to resume back after executing func
|
||||||
|
"""
|
||||||
|
susp = not self.api.is_attached or self.api.is_suspended
|
||||||
|
if self.prepare():
|
||||||
|
res = func(self, *args, **kw)
|
||||||
|
if not susp:
|
||||||
|
self.api.Resume()
|
||||||
|
return res
|
||||||
|
else:
|
||||||
|
raise Exception(u"Could not suspend/start")
|
@ -0,0 +1,25 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python class for DF_Hack::GUI
|
||||||
|
"""
|
||||||
|
from ._pydfhack import _GUIManager
|
||||||
|
class GUI(_GUIManager):
|
||||||
|
api = None
|
||||||
|
started = False
|
||||||
|
def __init__(self, api, *args, **kwds):
|
||||||
|
_GUIManager.__init__(self, args, kwds)
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
def prepare(self):
|
||||||
|
"""
|
||||||
|
Enforce Suspend/Start
|
||||||
|
"""
|
||||||
|
if self.api.prepare():
|
||||||
|
if not self.started:
|
||||||
|
self.started = self.Start()
|
||||||
|
return self.started
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,116 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python class for DF_Hack::Maps
|
||||||
|
"""
|
||||||
|
from ._pydfhack import _MapManager
|
||||||
|
from .mixins import NeedsStart
|
||||||
|
from .decorators import suspend
|
||||||
|
from .blocks import Block, Point
|
||||||
|
|
||||||
|
class Map(NeedsStart, _MapManager):
|
||||||
|
api = None
|
||||||
|
cls = _MapManager
|
||||||
|
def __init__(self, api, *args, **kwds):
|
||||||
|
self.cls.__init__(self, args, kwds)
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def get_size(self):
|
||||||
|
return self.size
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Is_Valid_Block(self, x=0, y=0, z=0, point=None):
|
||||||
|
"""
|
||||||
|
Checks if coords are valid
|
||||||
|
"""
|
||||||
|
if point:
|
||||||
|
point = point.get_block()
|
||||||
|
x, y, z = point.xyz
|
||||||
|
return self.cls.Is_Valid_Block(self, x, y, z)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Tile_Types(self, x=0, y=0, z=0, point=None):
|
||||||
|
"""
|
||||||
|
Returns 16x16 block in form of list of lists.
|
||||||
|
Should be called either by point or x,y,z coords. Coords are in block form.
|
||||||
|
"""
|
||||||
|
if point:
|
||||||
|
point = point.get_block()
|
||||||
|
x, y, z = point.xyz
|
||||||
|
return self.cls.Read_Tile_Types(self, x, y, z)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Write_Tile_Types(self, x=0, y=0, z=0, tiles=None, point=None):
|
||||||
|
if point:
|
||||||
|
point = point.get_block()
|
||||||
|
x, y, z = point.xyz
|
||||||
|
return self.cls.Write_Tile_Types(self, x, y, z, tiles)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Designations(self, x=0, y=0, z=0, point=None):
|
||||||
|
"""
|
||||||
|
Returns 16x16 block in form of list of lists.
|
||||||
|
"""
|
||||||
|
if point:
|
||||||
|
point = point.get_block()
|
||||||
|
x, y, z = point.xyz
|
||||||
|
return self.cls.Read_Designations(self, x, y, z)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Write_Designations(self, x=0, y=0, z=0, tiles=None, point=None):
|
||||||
|
if point:
|
||||||
|
point = point.get_block()
|
||||||
|
x, y, z = point.xyz
|
||||||
|
return self.cls.Write_Designations(self, x, y, z, tiles)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Write_Occupancy(self, *args, **kw):
|
||||||
|
return self.cls.Write_Occupancy(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Write_Dirty_Bit(self, *args, **kw):
|
||||||
|
return self.cls.Write_Dirty_Bit(self, *args, **kw)
|
||||||
|
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Write_Block_Flags(self, *args, **kw):
|
||||||
|
return self.cls.Write_Block_Flags(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Region_Offsets(self, *args, **kw):
|
||||||
|
return self.cls.Read_Region_Offsets(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Dirty_Bit(self, *args, **kw):
|
||||||
|
return self.cls.Read_Dirty_Bit(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Occupancy(self, *args, **kw):
|
||||||
|
return self.cls.Read_Occupancy(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Block_Flags(self, *args, **kw):
|
||||||
|
return self.cls.Read_Block_Flags(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Geology(self, *args, **kw):
|
||||||
|
return self.cls.Read_Geology(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Block_40d(self, *args, **kw):
|
||||||
|
return self.cls.Read_Block_40d(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def get_block(self, point):
|
||||||
|
point = point.get_block()
|
||||||
|
block = Block(api=self.api, coords=point)
|
||||||
|
return block
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def get_tile(self, x=0, y=0, z=0, point=None):
|
||||||
|
if not point:
|
||||||
|
point = Point(x, y, z)
|
||||||
|
block = Block(api=self.api, coords=point.get_block())
|
||||||
|
return block.get_tile(point=point)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python class for DF_Hack::Materials
|
||||||
|
"""
|
||||||
|
from ._pydfhack import _MaterialsManager
|
||||||
|
from .mixins import NoStart
|
||||||
|
from .decorators import suspend
|
||||||
|
|
||||||
|
class Materials(NoStart, _MaterialsManager):
|
||||||
|
api = None
|
||||||
|
cls = _MaterialsManager
|
||||||
|
def __init__(self, api, *args, **kwds):
|
||||||
|
cls.__init__(self, args, kwds)
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Wood_Materials(self, *args, **kw):
|
||||||
|
return self.cls.Read_Wood_Materials(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Plant_Materials(self, *args, **kw):
|
||||||
|
return self.cls.Read_Plant_Materials(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Inorganic_Materials(self, *args, **kw):
|
||||||
|
return self.cls.Read_Inorganic_Materials(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Descriptor_Colors(self, *args, **kw):
|
||||||
|
return self.cls.Read_Descriptor_Colors(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Creature_Types(self, *args, **kw):
|
||||||
|
return self.cls.Read_Creature_Types(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Organic_Materials(self, *args, **kw):
|
||||||
|
return self.cls.Read_Organic_Materials(self, *args, **kw)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read_Creature_Types_Ex(self, *args, **kw):
|
||||||
|
return self.cls.Read_Creature_Types_Ex(self, *args, **kw)
|
@ -0,0 +1,98 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python class for DF_Hack::MemInfo
|
||||||
|
"""
|
||||||
|
from ._pydfhack import _MemInfo
|
||||||
|
from .mixins import NoStart
|
||||||
|
from .decorators import suspend
|
||||||
|
|
||||||
|
class MemInfo(NoStart, _MemInfo):
|
||||||
|
api = None
|
||||||
|
cls = _MemInfo
|
||||||
|
def __init__(self, api, *args, **kwds):
|
||||||
|
self.cls.__init__(self, args, kwds)
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
## Properties:
|
||||||
|
# version
|
||||||
|
# base
|
||||||
|
|
||||||
|
## No idea if these should work only on suspend. To check later.
|
||||||
|
|
||||||
|
def Rebase_All(self, *args, **kw):
|
||||||
|
return self.cls.Rebase_All(self, *args, **kw)
|
||||||
|
|
||||||
|
def Set_String(self, *args, **kw):
|
||||||
|
return self.cls.Set_String(self, *args, **kw)
|
||||||
|
|
||||||
|
def Resolve_Object_To_Class_ID(self, *args, **kw):
|
||||||
|
return self.cls.Resolve_Object_To_Class_ID(self, *args, **kw)
|
||||||
|
|
||||||
|
def Get_Trait(self, *args, **kw):
|
||||||
|
return self.cls.Get_Trait(self, *args, **kw)
|
||||||
|
|
||||||
|
def Get_Job(self, *args, **kw):
|
||||||
|
return self.cls.Get_Job(self, *args, **kw)
|
||||||
|
|
||||||
|
def Rebase_VTable(self, *args, **kw):
|
||||||
|
return self.cls.Rebase_VTable(self, *args, **kw)
|
||||||
|
|
||||||
|
def Get_String(self, *args, **kw):
|
||||||
|
return self.cls.Get_String(self, *args, **kw)
|
||||||
|
|
||||||
|
def Get_Trait_Name(self, *args, **kw):
|
||||||
|
return self.cls.Get_Trait_Name(self, *args, **kw)
|
||||||
|
|
||||||
|
def Set_Job(self, *args, **kw):
|
||||||
|
return self.cls.Set_Job(self, *args, **kw)
|
||||||
|
|
||||||
|
def Set_Offset(self, *args, **kw):
|
||||||
|
return self.cls.Set_Offset(self, *args, **kw)
|
||||||
|
|
||||||
|
def Rebase_Addresses(self, *args, **kw):
|
||||||
|
return self.cls.Rebase_Addresses(self, *args, **kw)
|
||||||
|
|
||||||
|
def Resolve_Classname_To_Class_ID(self, *args, **kw):
|
||||||
|
return self.cls.Resolve_Classname_To_Class_ID(self, *args, **kw)
|
||||||
|
|
||||||
|
def Set_Labor(self, *args, **kw):
|
||||||
|
return self.cls.Set_Labor(self, *args, **kw)
|
||||||
|
|
||||||
|
def Get_Skill(self, *args, **kw):
|
||||||
|
return self.cls.Get_Skill(self, *args, **kw)
|
||||||
|
|
||||||
|
def Set_Profession(self, *args, **kw):
|
||||||
|
return self.cls.Set_Profession(self, *args, **kw)
|
||||||
|
|
||||||
|
def Get_Profession(self, *args, **kw):
|
||||||
|
return self.cls.Get_Profession(self, *args, **kw)
|
||||||
|
|
||||||
|
def Get_Offset(self, *args, **kw):
|
||||||
|
return self.cls.Get_Offset(self, *args, **kw)
|
||||||
|
|
||||||
|
def Get_HexValue(self, *args, **kw):
|
||||||
|
return self.cls.Get_HexValue(self, *args, **kw)
|
||||||
|
|
||||||
|
def Set_Address(self, *args, **kw):
|
||||||
|
return self.cls.Set_Address(self, *args, **kw)
|
||||||
|
|
||||||
|
def Set_HexValue(self, *args, **kw):
|
||||||
|
return self.cls.Set_HexValue(self, *args, **kw)
|
||||||
|
|
||||||
|
def Get_Address(self, *args, **kw):
|
||||||
|
return self.cls.Get_Address(self, *args, **kw)
|
||||||
|
|
||||||
|
def Set_Trait(self, *args, **kw):
|
||||||
|
return self.cls.Set_Trait(self, *args, **kw)
|
||||||
|
|
||||||
|
def Resolve_Classname_To_VPtr(self, *args, **kw):
|
||||||
|
return self.cls.Resolve_Classname_To_VPtr(self, *args, **kw)
|
||||||
|
|
||||||
|
def Get_Labor(self, *args, **kw):
|
||||||
|
return self.cls.Get_Labor(self, *args, **kw)
|
||||||
|
|
||||||
|
def Set_Skill(self, *args, **kw):
|
||||||
|
return self.cls.Set_Skill(self, *args, **kw)
|
||||||
|
|
||||||
|
def Resolve_Class_ID_To_Classname(self, *args, **kw):
|
||||||
|
return self.cls.Resolve_Class_ID_To_Classname(self, *args, **kw)
|
@ -0,0 +1,63 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Mix-ins for bound classes
|
||||||
|
"""
|
||||||
|
|
||||||
|
class NeedsStart(object):
|
||||||
|
"""
|
||||||
|
This mixin enforces Start/Finish routines
|
||||||
|
"""
|
||||||
|
started = False
|
||||||
|
def prepare(self):
|
||||||
|
"""
|
||||||
|
Enforce Suspend/Start
|
||||||
|
"""
|
||||||
|
if self.api.prepare():
|
||||||
|
if not self.started:
|
||||||
|
self.Start()
|
||||||
|
return self.started
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def Start(self):
|
||||||
|
if self.started:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if self.api.prepare():
|
||||||
|
self.started = self.cls.Start(self)
|
||||||
|
if self.started:
|
||||||
|
self.api.started.append(self)
|
||||||
|
return self.started
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
start = Start
|
||||||
|
|
||||||
|
def Finish(self):
|
||||||
|
if self.started:
|
||||||
|
self.cls.Finish(self)
|
||||||
|
self.started = False
|
||||||
|
if self in self.api.started:
|
||||||
|
self.api.started.remove(self)
|
||||||
|
|
||||||
|
finish = Finish
|
||||||
|
|
||||||
|
class NoStart(object):
|
||||||
|
"""
|
||||||
|
This mixin enforces Suspend, and disables Start/Finish
|
||||||
|
"""
|
||||||
|
def prepare(self):
|
||||||
|
"""
|
||||||
|
Enforce Suspend
|
||||||
|
"""
|
||||||
|
return self.api.prepare()
|
||||||
|
|
||||||
|
def Start(self):
|
||||||
|
raise Exception("{0.cls} does not need Start()".format(self))
|
||||||
|
|
||||||
|
start = Start
|
||||||
|
|
||||||
|
def Finish(self):
|
||||||
|
raise Exception("{0.cls} does not need Finish()".format(self))
|
||||||
|
|
||||||
|
finish = Finish
|
@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python class for DF_Hack::Position
|
||||||
|
"""
|
||||||
|
from ._pydfhack import _PositionManager
|
||||||
|
from .blocks import Point, Block
|
||||||
|
from .mixins import NoStart
|
||||||
|
from .decorators import suspend
|
||||||
|
|
||||||
|
class Position(NoStart, _PositionManager):
|
||||||
|
api = None
|
||||||
|
cls = _PositionManager
|
||||||
|
def __init__(self, api, *args, **kwds):
|
||||||
|
self.cls.__init__(self, args, kwds)
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def get_cursor(self):
|
||||||
|
coords = self.cursor_coords
|
||||||
|
if coords:
|
||||||
|
return Point(*coords)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def get_window_size(self):
|
||||||
|
wsize = self.window_size
|
||||||
|
return wsize
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def get_view_coords(self):
|
||||||
|
coords = self.view_coords
|
||||||
|
return Point(*coords)
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def get_cursor_tile(self):
|
||||||
|
point = self.get_cursor()
|
||||||
|
if point:
|
||||||
|
tile = self.api.maps.get_tile(point=point)
|
||||||
|
return tile
|
||||||
|
else:
|
||||||
|
return None
|
@ -0,0 +1,71 @@
|
|||||||
|
import _pydfhack, os, copy
|
||||||
|
from .blocks import Point, Block
|
||||||
|
from .meminfo import MemInfo
|
||||||
|
from .position import Position
|
||||||
|
from .materials import Materials
|
||||||
|
from .creature import Creature
|
||||||
|
from .map import Map
|
||||||
|
from .translation import Translation
|
||||||
|
from .construction import Construction
|
||||||
|
from .vegetation import Vegetation
|
||||||
|
from .gui import GUI
|
||||||
|
class API(_pydfhack._API):
|
||||||
|
started = None
|
||||||
|
path = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
datafile = os.path.join(path, "Memory.xml")
|
||||||
|
if not os.path.isfile(datafile):
|
||||||
|
raise ImportError, "Memory.xml not found."
|
||||||
|
|
||||||
|
# Rude hack to bypass xml location restrictions
|
||||||
|
datafile = "./" + "../"*20 + datafile
|
||||||
|
|
||||||
|
def prepare(self):
|
||||||
|
"""
|
||||||
|
Enforce Attach/Suspend behavior.
|
||||||
|
Return True if succeeded, else False
|
||||||
|
"""
|
||||||
|
r = True
|
||||||
|
if not self.is_attached:
|
||||||
|
r = self.Attach()
|
||||||
|
if r and not self.is_suspended:
|
||||||
|
r = self.Suspend()
|
||||||
|
return r
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwds):
|
||||||
|
_pydfhack._API.__init__(self, API.datafile)
|
||||||
|
self._mem_info_mgr_type = MemInfo
|
||||||
|
self._position_mgr_type = Position
|
||||||
|
self._material_mgr_type = Materials
|
||||||
|
self._creature_mgr_type = Creature
|
||||||
|
self._map_mgr_type = Map
|
||||||
|
self._translate_mgr_type = Translation
|
||||||
|
self._construction_mgr_type = Construction
|
||||||
|
self._vegetation_mgr_type = Vegetation
|
||||||
|
self._gui_mgr_type = GUI
|
||||||
|
self.started = []
|
||||||
|
|
||||||
|
def Attach(self, *args, **kw):
|
||||||
|
print "API.Attach()"
|
||||||
|
return _pydfhack._API.Attach(self, *args, **kw)
|
||||||
|
|
||||||
|
def Detach(self, *args, **kw):
|
||||||
|
print "API.Detach()"
|
||||||
|
return _pydfhack._API.Detach(self, *args, **kw)
|
||||||
|
|
||||||
|
def Suspend(self, *args, **kw):
|
||||||
|
print "API.Suspend()"
|
||||||
|
return _pydfhack._API.Suspend(self, *args, **kw)
|
||||||
|
|
||||||
|
def Resume(self):
|
||||||
|
print "API.Resume()"
|
||||||
|
# Reference counting is fcked, so leave it alone for now
|
||||||
|
|
||||||
|
## Explicitly Finish() all started modules
|
||||||
|
#print self.started
|
||||||
|
#started = copy.copy(self.started)
|
||||||
|
#print started
|
||||||
|
#for m in started:
|
||||||
|
# print m
|
||||||
|
# m.Finish()
|
||||||
|
#self.started = []
|
||||||
|
return _pydfhack._API.Resume(self)
|
@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python class for DF_Hack::Translation
|
||||||
|
"""
|
||||||
|
from ._pydfhack import _TranslationManager
|
||||||
|
from .mixins import NeedsStart
|
||||||
|
from .decorators import suspend
|
||||||
|
|
||||||
|
class Translation(NeedsStart, _TranslationManager):
|
||||||
|
api = None
|
||||||
|
cls = _TranslationManager
|
||||||
|
def __init__(self, api, *args, **kwds):
|
||||||
|
self.cls.__init__(self, args, kwds)
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
def get_dictionaries(self):
|
||||||
|
return self.dictionaries
|
||||||
|
|
||||||
|
def Translate_Name(self, *args, **kw):
|
||||||
|
return self.cls.Translate_Name(self, *args, **kw)
|
@ -0,0 +1,18 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python class for DF_Hack::Vegetation
|
||||||
|
"""
|
||||||
|
from ._pydfhack import _VegetationManager
|
||||||
|
from .mixins import NeedsStart
|
||||||
|
from .decorators import suspend
|
||||||
|
|
||||||
|
class Vegetation(NeedsStart, _VegetationManager):
|
||||||
|
api = None
|
||||||
|
cls = _VegetationManager
|
||||||
|
def __init__(self, api, *args, **kwds):
|
||||||
|
self.cls.__init__(self, args, kwds)
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
@suspend
|
||||||
|
def Read(self, *args, **kw):
|
||||||
|
return self.cls.Read(self, *args, **kw)
|
@ -1,12 +1,59 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from distutils.core import setup, Extension
|
try:
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
except ImportError:
|
||||||
|
from ez_setup import use_setuptools
|
||||||
|
use_setuptools()
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
from distutils.core import Extension
|
||||||
|
from os import path
|
||||||
|
import platform
|
||||||
|
|
||||||
e = Extension("pydfhack",
|
if platform.system() == 'Windows':
|
||||||
sources=["DF_API.cpp", "DF_Buildings.cpp", "DF_Constructions.cpp", "DF_CreatureManager.cpp", "DF_GUI.cpp", "DF_Maps.cpp", "DF_Material.cpp", "DF_Position.cpp", "DF_Translate.cpp", "DF_Vegetation.cpp", "pydfhack.cpp"],
|
# dfhack.lib location can differ, search for it
|
||||||
include_dirs=["../", "../include", "../depends/md5", "../depends/tinyxml"],
|
for libdir in ["..", path.join("..",".."), path.join("..", "..", "output"), path.join("..", "..", "output", "Release")]:
|
||||||
library_dirs=["..\\..\\output"],
|
if path.isfile(path.join(libdir, "dfhack.lib")):
|
||||||
#extra_compile_args=["-w"],
|
lib_dirs = libdir
|
||||||
libraries=["libdfhack"],
|
libraries=["dfhack"]
|
||||||
export_symbols=["initpydfhack", "ReadRaw", "WriteRaw"])
|
break
|
||||||
|
if path.isfile(path.join(libdir, "libdfhack.dll")):
|
||||||
|
lib_dirs = libdir
|
||||||
|
libraries = ["libdfhack"]
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise Exception("dfhack.lib is not found")
|
||||||
|
osspec = dict(library_dirs=[lib_dirs],
|
||||||
|
libraries=libraries)
|
||||||
|
|
||||||
setup(name="PyDFHack", version="1.0", ext_modules=[e])
|
elif platform.system() == 'Linux':
|
||||||
|
osspec = dict(extra_compile_args=["-DLINUX_BUILD", "-w"],
|
||||||
|
library_dirs=[path.join("..","..","output")],
|
||||||
|
libraries=["dfhack"])
|
||||||
|
|
||||||
|
e = Extension("pydfhack._pydfhack",
|
||||||
|
sources=["DF_API.cpp", "DF_Buildings.cpp", "DF_Constructions.cpp", "DF_CreatureManager.cpp",\
|
||||||
|
"DF_GUI.cpp", "DF_Maps.cpp", "DF_Material.cpp", "DF_Position.cpp", "DF_Translate.cpp",\
|
||||||
|
"DF_Vegetation.cpp", "pydfhack.cpp"],
|
||||||
|
include_dirs=["../", path.join("..", "include"), path.join("..","depends","md5"), path.join("..","depends","tinyxml")],
|
||||||
|
export_symbols=["init_pydfhack", "ReadRaw", "WriteRaw"],
|
||||||
|
**osspec)
|
||||||
|
|
||||||
|
for file in ["Memory.xml", path.join("..","..","output","Memory.xml")]:
|
||||||
|
if path.isfile(file):
|
||||||
|
datafile = file
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise Exception("Memory.xml is not found.")
|
||||||
|
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="PyDFHack",
|
||||||
|
description="Python wrapper and bindings for DFHack library",
|
||||||
|
version="1.0",
|
||||||
|
packages=find_packages(exclude=['ez_setup']),
|
||||||
|
data_files=[('pydfhack', [datafile])],
|
||||||
|
include_package_data=True,
|
||||||
|
test_suite='nose.collector',
|
||||||
|
zip_safe=False,
|
||||||
|
ext_modules=[e],
|
||||||
|
)
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import sys
|
||||||
|
import pydfhack
|
||||||
|
DF = pydfhack.API("Memory.xml")
|
||||||
|
|
||||||
|
DF.Attach()
|
||||||
|
|
||||||
|
pos = DF.position
|
||||||
|
maps = DF.maps
|
||||||
|
refc = dict(pydfhack=pydfhack, API=pydfhack.API, DF=DF, pos=pos, maps=maps)
|
||||||
|
cursor = pos.get_cursor()
|
||||||
|
msize = maps.get_size()
|
||||||
|
block = None
|
||||||
|
tile = None
|
||||||
|
if cursor:
|
||||||
|
block = maps.get_block(point=cursor)
|
||||||
|
if block:
|
||||||
|
tile = block.get_tile(point=cursor)
|
||||||
|
DF.Resume()
|
||||||
|
|
||||||
|
locs = dict(pydfhack=pydfhack, API=pydfhack.API, DF=DF, pos=pos, maps=maps, msize=msize, cursor=cursor, block=block, tile=tile)
|
||||||
|
|
||||||
|
banner = """DFHack Shell\n\n"""\
|
||||||
|
"""\tpydfhack = {pydfhack}\n"""\
|
||||||
|
"""\tAPI = {API}\n"""\
|
||||||
|
"""\tDF = {DF}\n"""\
|
||||||
|
"""\tpos = {pos}\n"""\
|
||||||
|
"""\tmaps = {maps}\n"""\
|
||||||
|
"""\tmsize = {msize}\n"""\
|
||||||
|
"""\tcursor = {cursor}\n"""\
|
||||||
|
"""\tblock = {block}\n"""\
|
||||||
|
"""\ttile = {tile}\n""".format(**locs)
|
||||||
|
|
||||||
|
from IPython.Shell import IPShellEmbed
|
||||||
|
shell = IPShellEmbed()
|
||||||
|
shell.set_banner(shell.IP.BANNER + '\n\n' + banner)
|
||||||
|
shell(local_ns=locs, global_ns={})
|
||||||
|
DF.Detach()
|
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import sys
|
||||||
|
import pydfhack
|
||||||
|
from pydfhack.blocks import Point
|
||||||
|
DF = pydfhack.API("Memory.xml")
|
||||||
|
|
||||||
|
DF.Attach()
|
||||||
|
|
||||||
|
pos = DF.position
|
||||||
|
maps = DF.maps
|
||||||
|
cursor = pos.get_cursor()
|
||||||
|
refc = dict(pydfhack=pydfhack, API=pydfhack.API, DF=DF, pos=pos, maps=maps)
|
||||||
|
msize = maps.get_size()
|
||||||
|
print msize
|
||||||
|
locs = dict(pydfhack=pydfhack, API=pydfhack.API, DF=DF, pos=pos, maps=maps, msize=msize, cursor=cursor)
|
||||||
|
for z in range(msize[2]):
|
||||||
|
trees = 0
|
||||||
|
saplings = 0
|
||||||
|
dead_saplings = 0
|
||||||
|
for x in range(msize[0]):
|
||||||
|
for y in range(msize[1]):
|
||||||
|
p = Point(x, y, z, True)
|
||||||
|
block = maps.get_block(point=p)
|
||||||
|
changed = False
|
||||||
|
if not block.tiles:
|
||||||
|
break
|
||||||
|
for tx in range(16):
|
||||||
|
for ty in range(16):
|
||||||
|
tile = block.tiles[tx][ty]
|
||||||
|
if tile.ttype == 24:
|
||||||
|
trees += 1
|
||||||
|
elif tile.ttype == 231:
|
||||||
|
saplings += 1
|
||||||
|
tile.ttype = 24
|
||||||
|
changed = True
|
||||||
|
elif tile.ttype == 392:
|
||||||
|
dead_saplings += 1
|
||||||
|
tile.ttype = 24
|
||||||
|
changed = True
|
||||||
|
if changed:
|
||||||
|
block.save()
|
||||||
|
print "Saved block {0}".format(block)
|
||||||
|
print "Z-Level {0}: Trees {1}, Saplings {2}, Dead saplings {3}".format(z, trees, saplings, dead_saplings)
|
||||||
|
DF.Resume()
|
||||||
|
DF.Detach()
|
@ -0,0 +1,83 @@
|
|||||||
|
// This is a reveal program. It reveals the map.
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <integers.h>
|
||||||
|
#include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include <DFTypes.h>
|
||||||
|
#include <DFHackAPI.h>
|
||||||
|
#include <modules/Maps.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
uint32_t x_max,y_max,z_max;
|
||||||
|
DFHack::designations40d designations;
|
||||||
|
|
||||||
|
DFHack::API DF("Memory.xml");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DF.Attach();
|
||||||
|
}
|
||||||
|
catch (exception& e)
|
||||||
|
{
|
||||||
|
cerr << e.what() << endl;
|
||||||
|
#ifndef LINUX_BUILD
|
||||||
|
cin.ignore();
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DFHack::Maps *Maps =DF.getMaps();
|
||||||
|
// init the map
|
||||||
|
if(!Maps->Start())
|
||||||
|
{
|
||||||
|
cerr << "Can't init map." << endl;
|
||||||
|
#ifndef LINUX_BUILD
|
||||||
|
cin.ignore();
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
DFHack::t_blockflags bflags;
|
||||||
|
Maps->getSize(x_max,y_max,z_max);
|
||||||
|
// walk the map, count flowing tiles, magma, water
|
||||||
|
uint32_t flow1=0, flow2=0, flowboth=0, water=0, magma=0;
|
||||||
|
cout << "Counting flows and liquids .";
|
||||||
|
for(uint32_t x = 0; x< x_max;x++)
|
||||||
|
{
|
||||||
|
for(uint32_t y = 0; y< y_max;y++)
|
||||||
|
{
|
||||||
|
for(uint32_t z = 0; z< z_max;z++)
|
||||||
|
{
|
||||||
|
if(Maps->isValidBlock(x,y,z))
|
||||||
|
{
|
||||||
|
Maps->ReadBlockFlags(x, y, z, bflags);
|
||||||
|
Maps->ReadDesignations(x, y, z, &designations);
|
||||||
|
if (bflags.bits.liquid_1)
|
||||||
|
flow1++;
|
||||||
|
if (bflags.bits.liquid_2)
|
||||||
|
flow2++;
|
||||||
|
if (bflags.bits.liquid_1 && bflags.bits.liquid_2)
|
||||||
|
flowboth++;
|
||||||
|
for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++)
|
||||||
|
{
|
||||||
|
if (designations[i][j].bits.liquid_type == DFHack::liquid_magma)
|
||||||
|
magma++;
|
||||||
|
if (designations[i][j].bits.liquid_type == DFHack::liquid_water)
|
||||||
|
water++;
|
||||||
|
}
|
||||||
|
// Maps->WriteDesignations(x, y, z, &designations);
|
||||||
|
// Maps->WriteBlockFlags(x, y, z, bflags);
|
||||||
|
cout << ".";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << endl << "Done." << endl;
|
||||||
|
cout << "Blocks with liquid_1=true: " << flow1 << endl;
|
||||||
|
cout << "Blocks with liquid_2=true: " << flow2 << endl;
|
||||||
|
cout << "Blocks with both: " << flowboth << endl;
|
||||||
|
cout << "Water tiles: " << water << endl;
|
||||||
|
cout << "Magma tiles: " << magma << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue