## Python ITEM writer script for Tyran
## Version: 1.0
## 19/3/2012
## ITEMcreator.py
################################
# This script is a little sloppy. It gets the job done though.
#
# Copyright (c) 2012 Joshua Woods
#
# This software is provided 'as-is', without any express or implied warranty.
# In no event will the authors be held liable for any damages arising from
# the use of this software.
#
# Permission is granted to anyone to use this software for any purpose,
# including commercial applications, and to alter it and redistribute it freely,
# subject to the following restrictions:
#
# 1. The origin of this software must not be misrepresented; you must not
# claim that you wrote the original software. If you use this software in a
# product, an acknowledgment in the product documentation would be
# appreciated but is not required.
#
# 2. Altered source versions must be plainly marked as such, and must not
# be misrepresented as being the original software.
#
# 3. This notice may not be removed or altered from any source distribution.
################################
## Updated: 24/3/2012
################################
itemVersion = 0x0002 # please do not change
magic = 'ITEM\0' # please do not change
################################
## These classes are currently not used. But may be used in the future.
################################
class itemType:
NONE, WEAPON, ARMOUR, CONSUMABLE, INGREDIENT, MATERIAL = range(6)
class itemQuality:
NONE, CRUDE, PETTY, COMMON, SUPRERIOR = range(5)
class itemEffect:
NONE, HEALTHHEAL, HEALTHHARM, MANAHEAL, MANAHARM, FATIGUEHEAL, FATIGUEHARM, HUNGERHEAL, HUNGERHARM, SLOW, HASTE,FORTSTR,FORTAGI,FORTPER,FORTINT,FORTCON,FORTWIS,FORTSPD,WEAKSTR,WEAKAGI,WEAKPER,WEAKINT,WEAKCON,WEAKWIS,WEAKSPD,RESISTPOISON, VULNURPOISON,RESISTDISEASE,VULNURDISEASE,RESISTMAGIC,VULNURMAGIC,RESISTPARALYSIS,VULNURPARALYSIS,CUREPOISON, CUREDISEASE,INVISIBILITY,DIZZY,INSANITY,FEAR,KILL = range(40)
################################
## Default values
##
## Don't alter these without knowing exactly what
## you're doing. Some values like -666 are important
## to the way Tyran determines ITEM versions.
################################
fileName = 'newitem.item'
fileNameSub = fileName.split('.')
weight = 0
type = 0
# f 0, it is indestructible
durability = 0
#maximum durability
maxdur = 0
# higher the quality, the less chance of durability being decreased. 1 is to lose 1 durability per use.
quality = 0
equipable = 0
placeable = 0
description = 'item description (max 256 chars)\0'
name = 'item name (max 64 chars)\0'
# type of effect if consumable (eg. Healing) and the magnitude of the effect(eg. 20 would heal 20 points)
effect1 = 0
effect2 = 0
effect3 = 0
magnitude1 = 0
magnitude2 = 0
magnitude3 = 0
meshpath = "Models/Plane.obj\0"
texturepath = "Textures/texture_basecube.bmp\0"
armour = -666
################################
welcomeMessage = '\nWelcome :) Change the values below and when you\'re done hit the Export button. Things to be aware of:\n\nDurability, maxdur, weight and armour only take integers.\nItem description takes a maximum of 256 characters\nItem name, mesh path and texture path take a maximum of 64 characters.\n\nIf you don\'t follow these rules, Tyran will crash when it tries to load the ITEM file.\n\nITEM versions supported: %d, %d' % (0x0001, itemVersion)
################################
import os.path, tkMessageBox, sys, struct
import Tkinter as tk
from Tkinter import *
from string import rstrip, split
################################
## Check fileName already exists as a file. If it does, rename
## fileName.
################################
def ifFileExistsRenameIt():
global fileName
global fileNameSub
if os.path.isfile(fileName):
# Check if file is already there
if os.path.isfile(fileName):
# File does exist, rename our new file
temp = fileName.split('.')
print temp
i = 0
print temp[0] + repr(i)
while i != 100: # you can't possibly have more than 100 unnamed ITEM files, can you?
while 1:
if temp[0] == fileName + repr(i):
i += 1
final = fileNameSub[0] + repr(i) + '.' + fileNameSub[1]
print 'Final: %s' % final
fileName = final
if os.path.isfile(fileName) != True:
break
i += 1
break
################################
################################
def settings():
tkMessageBox.showinfo('Sorry','This feature isn\'t available yet.')
def quit():
sys.exit(0)
def about():
abo.deiconify()
abo.mainloop()
def hideabout():
abo.withdraw()
class About:
def __init__(self,master):
frame = Frame(master)
frame.pack()
# Label
lbl = Label(master, text='ITEM Creator v1.0\n\n19/3/2012\nJoshua Woods\n\ntyrangame.blogspot.com.au')
lbl.config(font=("arial", 12, 'bold'), justify=LEFT, fg='royalblue',bg='black')
lbl.pack()
class Help:
def __init__(self, master):
frame = Frame(master)
frame.pack()
lbl = Label(master, text='contact me for help on this format.')
lbl.config(font=("arial", 12, 'bold'), justify=LEFT, fg='royalblue',bg='black')
lbl.pack()
class Program:
def __init__(self, master):
frame = Frame(master)
frame.pack()
scrollbar = Scrollbar(master)
scrollbar.pack(side=RIGHT, fill=Y)
#self.canvas = tk.Canvas(frame, bg='black', bd=3, relief='sunken')
self.cmbDataItemType = StringVar(master)
self.cmbDataItemType.set("Item type: None") # default value
self.w = OptionMenu(master, self.cmbDataItemType, "Item type: None", 'weapon', 'armour', 'consumable', 'ingredient', 'material')
self.cmbDataItemQual = StringVar(master)
self.cmbDataItemQual.set("Item quality: None") # default value
self.w2 = OptionMenu(master, self.cmbDataItemQual, "Item quality: None", 'crude', 'petty', 'common', 'superior')
self.cmbDataPlaceable = StringVar(master)
self.cmbDataPlaceable.set("Placeable: False") # default value
self.w3 = OptionMenu(master, self.cmbDataPlaceable, "true")
self.cmbDataEquipable = StringVar(master)
self.cmbDataEquipable.set("Equipable: False") # default value
self.w4 = OptionMenu(master, self.cmbDataEquipable, "true")
self.txtIntro = Text(master, yscrollcommand=scrollbar.set,font=('arial', 13, 'normal'),fg='yellow',bg='black',width=40, height=6,insertbackground='yellow',wrap=WORD,borderwidth=4)
self.txtfilename = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)
self.txtitemname = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)
self.txtitemdesc = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=4,insertbackground='royalblue',wrap=WORD,borderwidth=4)
self.txtmeshpath = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)
self.txttexturepath = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)
self.txtdurability = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)
self.txtmaxdurability = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)
self.txtweight = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)
self.txtarmour = Text(master,font=('arial', 13, 'normal'),fg='royalblue',bg='black',width=40, height=1,insertbackground='royalblue',wrap=WORD,borderwidth=4)
self.btnexport = Button(master, text='Export', fg='royalblue', bg='black', command=self.btnexportcallback,font=('arial',13,'bold'))
# Packing:
self.txtIntro.pack(side=TOP, fill=BOTH)
scrollbar.config(command=self.txtIntro.yview)
self.btnexport.pack(side=TOP)
self.txtfilename.pack(side=TOP)
self.txtitemname.pack(side=TOP)
self.txtitemdesc.pack(side=TOP)
self.txtmeshpath.pack(side=TOP)
self.txttexturepath.pack(side=TOP)
self.txtdurability.pack(side=TOP)
self.txtmaxdurability.pack(side=TOP)
self.txtweight.pack(side=TOP)
self.txtarmour.pack(side=TOP)
#self.canvas.pack(side=RIGHT)
self.w.pack(side=LEFT)
self.w2.pack(side=LEFT)
self.w3.pack(side=LEFT)
self.w4.pack(side=LEFT)
#self.w.pack(side= RIGHT)
# Inject some data into new fields
self.txtIntro.insert(END, welcomeMessage)
self.txtfilename.insert(END, fileName)
self.txtitemname.insert(END,name)
self.txtitemdesc.insert(END,description)
self.txtmeshpath.insert(END, meshpath)
self.txttexturepath.insert(END, texturepath)
self.txtdurability.insert(END, "durability")
self.txtmaxdurability.insert(END, "maximum durability")
self.txtweight.insert(END, "weight")
self.txtarmour.insert(END, "armour")
#print drawWireframe(self.canvas, (200,200), meshpath)
def printValues(self):
#self.txtIntro.delete
self.txtIntro.insert(1.0, ("%s" % self.txtfilename.get(1.0, END)))
self.txtIntro.insert(1.0, ("%s" % self.txtitemname.get(1.0, END)))
self.txtIntro.insert(1.0, ("%s" % self.txtitemdesc.get(1.0, END)))
self.txtIntro.insert(1.0, ("%s" % self.txtmeshpath.get(1.0, END)))
self.txtIntro.insert(1.0, ("%s" % self.txttexturepath.get(1.0, END)))
self.txtIntro.insert(1.0, ("%s" % self.txtdurability.get(1.0, END)))
self.txtIntro.insert(1.0, ("%s" % self.txtmaxdurability.get(1.0, END)))
self.txtIntro.insert(1.0, ("%s" % self.txtweight.get(1.0, END)))
self.txtIntro.insert(1.0, ("\n%s" % self.txtarmour.get(1.0, END)))
self.txtIntro.insert(1.0, ("\n%s" % self.cmbDataItemType.get()))
self.txtIntro.insert(1.0, ("\n%s" % self.cmbDataItemQual.get()))
self.txtIntro.insert(1.0, ("\n%s" % self.cmbDataPlaceable.get()))
self.txtIntro.insert(1.0, ("\n%s" % self.cmbDataEquipable.get()))
def btnexportcallback(self):
# extract data from fields
fileName = (self.txtfilename.get(1.0, END)).strip()
weight = (self.txtweight.get(1.0, END)).strip()# + '\0'
if weight == 'weight':
weight = 0
else:
weight = int(weight)
durability = (self.txtdurability.get(1.0, END)).strip()# + '\0'
if durability == 'durability':
durability = 0
else:
durability = int(durability)
maxdur = (self.txtmaxdurability.get(1.0, END)).strip() #+ '\0'
if maxdur == 'maximum durability':
maxdur = 0
else:
maxdur = int(maxdur)
type = self.cmbDataItemType.get()
if type == "Item type: None":
type = 0
elif type == 'weapon':
type = 1
elif type == 'armour':
type = 2
elif type == 'consumable':
type = 3
elif type == 'ingredient':
type = 4
elif type == 'material':
type = 5
print type
quality = self.cmbDataItemQual.get()
if quality == "Item quality: None":
quality = 0
elif quality == 'crude':
quality = 1
elif quality == 'petty':
quality = 2
elif quality == 'common':
quality = 3
elif quality == 'superior':
quality = 4
equipable = self.cmbDataEquipable.get()
if equipable == "Equipable: False":
equipable = 0
else:
equipable = 1
placeable = self.cmbDataPlaceable.get()
if placeable == "Placeable: False":
placeable = 0
else:
placeable = 1
description = (self.txtitemdesc.get(1.0, END)).strip() + '\0'
name = (self.txtitemname.get(1.0, END)).strip() + '\0'
effect1 = 0
effect2 = 0
effect3 = 0
magnitude1 = 0
magnitude2 = 0
magnitude3 = 0
meshpath = (self.txtmeshpath.get(1.0, END)).strip() + '\0'
texturepath = (self.txttexturepath.get(1.0, END)).strip() + '\0'
armour = (self.txtarmour.get(1.0, END)).strip()# + '\0'
if armour != 'armour':
armour = int(armour)
else:
itemVersion = 0x0001
print weight
print equipable
###############################
ifFileExistsRenameIt()
print 'Creating %s' % fileName
file = open(fileName, 'wb')
print 'Writing to file ...'
file.write(magic)
format = "h" # write short
data = struct.pack(format, itemVersion)
print '[' + repr(itemVersion) + ']'
file.write(data)
format = 'i' # write integers
data = struct.pack(format, weight)
print '[' + repr(weight) + ']'
file.write(data)
data = struct.pack(format, type)
print '[' +repr( type) + ']'
file.write(data)
data = struct.pack(format, durability)
print '[' + repr(durability) + ']'
file.write(data)
data = struct.pack(format, maxdur)
print '[' + repr(maxdur) + ']'
file.write(data)
data = struct.pack(format, quality)
print '[' + repr(quality) + ']'
file.write(data)
data = struct.pack(format, equipable)
print '[' + repr(equipable) + ']'
file.write(data)
data = struct.pack(format, placeable)
print '[' + repr(placeable) + ']'
file.write(data)
# effects and magnitude ignored for now
data = struct.pack(format, 0)
print '[' + repr(data) + ']'
file.write(data)
print '[' + repr(data) + ']'
file.write(data)
print '[' + repr(data) + ']'
file.write(data)
print '[' + repr(data) + ']'
file.write(data)
print '[' + repr(data) + ']'
file.write(data)
print '[' + repr(data) + ']'
file.write(data)
print '[' + name + ']'
file.write(name)
print '[' + description + ']'
file.write(description)
print '[' + meshpath + ']'
file.write(meshpath)
print '[' + texturepath + ']'
file.write(texturepath)
if itemVersion == 0x0002:
data = struct.pack(format, armour)
print '[' + repr(armour) + ']'
file.write(data)
print 'Finished... Closing...'
file.close()
################################
#file = open(fileName, 'wb')
root = Tk()
root.title('ITEM Creator')
toplevel = tk.Toplevel(root)
toplevel.geometry('640x480')
toplevel.resizable(0,0)
toplevel.withdraw()
root.config(bg='black')
root.protocol("WM_DELETE_WINDOW", quit)
program = Program(root)
# Main Menu
menubar = Menu(root)
root.config(menu=menubar)
# Options Menu
optionsmenu = Menu(menubar, tearoff=0)
optionsmenu.add_command(label='Data to text field', command=program.printValues)
optionsmenu.add_separator()
optionsmenu.add_command(label='Quit', command=quit)
menubar.add_cascade(label='Options', menu=optionsmenu)
# Help Menu
helpmenu = Menu(menubar, tearoff=0)
helpmenu.add_command(label='About', command=about)
menubar.add_cascade(label='Help', menu=helpmenu)
# About
abo = Tk()
abo.title('About')
abo.config(bg='black')
abo.protocol('WM_DELETE_WINDOW', hideabout)
aviabo = About(abo)
hideabout()
root.mainloop()
It's not optimised, just quick and dirty. But that's what I use Python for. I only bother polishing the stuff that matters: the C++ that runs the game.