2008-10-11 03:22:26 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# Map journey track editor. Just a stub at the moment, not yet working.
|
|
|
|
|
2008-10-11 12:34:44 +00:00
|
|
|
import sys, exceptions
|
2008-10-11 03:22:26 +00:00
|
|
|
|
|
|
|
import pygtk
|
|
|
|
pygtk.require('2.0')
|
|
|
|
import gtk
|
|
|
|
|
|
|
|
import wesnoth.wmltools
|
|
|
|
|
2008-10-11 12:34:44 +00:00
|
|
|
# All dependencies on the shape of the data tree live here
|
2008-10-11 03:22:26 +00:00
|
|
|
default_map = "data/core/images/maps/wesnoth.png"
|
2008-10-11 12:34:44 +00:00
|
|
|
journey_icon = "data/core/images/misc/new-journey.png"
|
|
|
|
battle_icon = "data/core/images/misc/new-battle.png"
|
|
|
|
rest_icon = "data/core/images/misc/flag-red.png"
|
|
|
|
|
|
|
|
class ReadException(exceptions.Exception):
|
|
|
|
"Exception thrown while reading a track file."
|
|
|
|
def __init__(self, message, filename, lineno):
|
|
|
|
self.message = message
|
|
|
|
self.filename = filename
|
|
|
|
self.lineno = lineno
|
|
|
|
|
|
|
|
class JourneyTrack:
|
|
|
|
"Represent a journey track on a map."
|
|
|
|
def __init__(self):
|
|
|
|
self.filename = None # Map background of the journey
|
|
|
|
self.track = [] # List of (action, x, y) tuples
|
|
|
|
def write(self, fp):
|
|
|
|
"Record a journey track."
|
|
|
|
fp.write("FILE %s\n" % self.filename)
|
|
|
|
for location in self.track:
|
|
|
|
fp.write("%s %d %d\n" % location)
|
|
|
|
def read(self, fp):
|
|
|
|
"Initialize a journey from map and track information."
|
|
|
|
if type(fp) == type(""):
|
|
|
|
try:
|
|
|
|
fp = open(fp)
|
|
|
|
except FileError:
|
|
|
|
raise ReadException("cannot read", fp)
|
|
|
|
if self.track:
|
|
|
|
raise ReadException("reading with track nonempty", fp.name, 1)
|
|
|
|
if fp.name.endswith(".png") or fp.name.endswith(".jpg"):
|
|
|
|
self.filename = fp.name
|
|
|
|
return
|
|
|
|
if not fp.name.endswith(".trk"):
|
|
|
|
raise ReadException("cannot read this filetype", fp.name, 0)
|
|
|
|
header = fp.readline().split()
|
|
|
|
if header[0] != 'FILE':
|
|
|
|
raise ReadException("missing FILE element", fp.name, 1)
|
|
|
|
else:
|
|
|
|
self.filename = header[1]
|
|
|
|
while (i, line) in enumerate(fp):
|
|
|
|
fields = line.split()
|
|
|
|
if len(fields) != 3:
|
|
|
|
raise ReadException("ill-formed line", fp.name, i+1)
|
|
|
|
(tag, x, y) = fields
|
|
|
|
if tag not in ("JOURNEY", "BATTLE", "REST"):
|
|
|
|
raise ReadException("invalid tag field", fp.name, i+1)
|
|
|
|
try:
|
|
|
|
x = int(x)
|
|
|
|
y = int(y)
|
|
|
|
except ValuError:
|
|
|
|
raise ReadException("invalid coordinate field", fp.name, i+1)
|
|
|
|
self.track.append((tag, x, y))
|
|
|
|
def __getitem__(self, n):
|
|
|
|
return self.track[n]
|
|
|
|
def __setitem__(self, n, v):
|
|
|
|
self.track[n] = v
|
|
|
|
def pop(self):
|
|
|
|
self.track.pop()
|
2008-10-11 03:22:26 +00:00
|
|
|
|
|
|
|
class ModalFileSelector:
|
|
|
|
def __init__(self, default):
|
|
|
|
self.default = default
|
|
|
|
self.filename = None
|
|
|
|
# Create a new file selection widget
|
|
|
|
self.filew = gtk.FileSelection("File selection")
|
|
|
|
|
|
|
|
self.filew.connect("destroy", self.destroy)
|
|
|
|
# Connect the ok_button to file_selected method
|
|
|
|
self.filew.ok_button.connect("clicked", self.file_selected)
|
|
|
|
|
|
|
|
# Connect the cancel_button to destroy the widget
|
|
|
|
self.filew.cancel_button.connect("clicked",
|
|
|
|
lambda w: self.filew.destroy())
|
|
|
|
|
|
|
|
self.filew.set_filename(self.default)
|
|
|
|
self.filew.show()
|
|
|
|
gtk.main()
|
|
|
|
|
|
|
|
def file_selected(self, w):
|
|
|
|
self.filename = self.filew.get_filename()
|
|
|
|
gtk.main_quit()
|
|
|
|
|
|
|
|
def destroy(self, widget):
|
|
|
|
gtk.main_quit()
|
|
|
|
sys.exit(0)
|
|
|
|
|
2008-10-11 12:34:44 +00:00
|
|
|
def log(msg):
|
|
|
|
"Notify user of error and die."
|
|
|
|
# FIXME: conditionalize of a debug flag
|
|
|
|
print >>sys.stderr, "trackplacer:", msg
|
|
|
|
|
|
|
|
def fatal_error(msg):
|
|
|
|
"Notify user of error and die."
|
|
|
|
# FIXME: Needs to change to modal notification window
|
|
|
|
print >>sys.stderr, msg
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
class TrackEditor:
|
|
|
|
def __init__(self):
|
|
|
|
# Initialize our info about the map and track
|
|
|
|
self.journey = JourneyTrack()
|
|
|
|
self.journey.read(ModalFileSelector(default_map).filename)
|
|
|
|
# We need two copies of the map -- one scratchpad for scribbling on,
|
|
|
|
# and one for restoring from when we erase track dots.
|
|
|
|
log("about to read map %s" % self.journey.filename)
|
|
|
|
try:
|
|
|
|
self.background = gtk.Image()
|
|
|
|
self.background.set_from_file(self.journey.filename)
|
|
|
|
self.scratchpad = gtk.Image()
|
|
|
|
self.scratchpad.set_from_file(self.journey.filename)
|
|
|
|
except:
|
|
|
|
fatal_error("Error while reading background map %s" % self.journey.filename)
|
|
|
|
#try:
|
|
|
|
self.journey_image = gtk.Image()
|
|
|
|
self.journey_image.set_from_file(journey_icon)
|
|
|
|
self.battle.image = gtk.Image()
|
|
|
|
self.battle_image.set_from_file(battle_icon)
|
|
|
|
self.rest_image = gtk.Image()
|
|
|
|
self.rest_image.set_from_file(rest_icon)
|
|
|
|
#except:
|
|
|
|
# fatal_error("Error while reading icons")
|
|
|
|
log("initialization successful")
|
2008-10-11 03:22:26 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
wesnoth.wmltools.pop_to_top("trackplacer")
|
2008-10-11 12:34:44 +00:00
|
|
|
TrackEditor()
|