Documentation Update. Part 2.
[asgard.git] / consolecontroller.py
blob43e35f824094f45705822c560ccca597a525a500
1 ########################################################
2 #Copyright (c) 2006 Russ Adams, Sean Eubanks, Asgard Contributors
3 #This file is part of Asgard.
5 #Asgard is free software; you can redistribute it and/or modify
6 #it under the terms of the GNU General Public License as published by
7 #the Free Software Foundation; either version 2 of the License, or
8 #(at your option) any later version.
10 #Asgard is distributed in the hope that it will be useful,
11 #but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 #GNU General Public License for more details.
15 #You should have received a copy of the GNU General Public License
16 #along with Asgard; if not, write to the Free Software
17 #Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 ########################################################
19 from statistic import *
20 from os import listdir
21 from battle import *
22 from equiption import *
23 from fighter import *
24 from eventtype import *
25 import struct
26 import copy
27 import sys
28 import utilities
30 class ConsoleController:
31 def __init__(self,debug,battle,view):
32 self.__debug = debug
33 self.__battle = battle
34 self.__view = view
36 battle.setController(self)
37 battle.setView(view)
38 view.setController(self)
39 view.setBattle(battle)
41 self.__gameLoop()
43 def getBattleCommand(self,vp,hp,f):
45 command = []
47 print "\033[1;34m[SELCT]\033[1;0m Turn:" + f.getName() + "; HP:" + str(f.getStat("hp").getCurrent()) + "/" + str(f.getStat("hp").getMax()) + " - MP:"+str(f.getStat("mp").getCurrent())+"/"+str(f.getStat("mp").getMax())
49 self.__view.printEventTypeMenu(f,self.__battle.getEventTypeList())
50 n = raw_input("% ")
51 t = self.__battle.getEventType(f.getEventTypes(self.__battle.getEventTypeList())[int(n)-1])
53 if t.getName() == "quit":
54 sys.exit()
56 self.__view.printTargetSelectMenu(vp,hp)
57 n = raw_input("% ")
58 # Select Villain
59 if vp.sizeOfParty() - int(n) >= 0:
60 d = vp.getFighter(int(n)-1)
61 # Select Hero
62 else:
63 d = hp.getFighter(int(n)-vp.sizeOfParty()-1)
64 return [d,t]
66 def getMenuCommand(self):
68 self.__view.printStartupMenu()
70 n = raw_input("% ")
72 return int(n)
74 def getDebug(self):
75 return self.__debug
77 def setDebug(self,d):
78 self.__debug = d
80 def __gameLoop(self):
81 """Retrieves events from Parties and Executes all Events in queue per iteration"""
83 print "Asgard Free Software RPG - Testing Module"
85 self.loadStaticData(False)
87 while True:
88 choice = 0
89 while choice != 4:
90 choice = self.getMenuCommand()
92 if choice == 1:
93 self.unloadStaticData()
94 self.loadStaticData(True)
95 print "loaded..."
96 else:
97 if choice == 2:
98 print "Path to Save File: ",
99 path = sys.stdin.readline()
100 self.load("" + path.strip() + "")
101 print "loaded..."
103 elif choice == 3:
104 print "Path to Save File: ",
105 path = sys.stdin.readline()
106 self.save("" + path.strip() + "")
107 print "saved..."
109 elif choice == 4:
111 if self.__battle.getParty1() == None:
112 print "No game loaded."
113 choice = 0
114 else:
115 self.createRandomBattle()
116 print "============================================================="
117 else:
118 sys.exit()
120 print "Battle Starts."
121 self.__view.printState()
123 # initialize the event checker boolean
124 wereEvents = False
126 while not self.__battle.isOver():
127 # next iteration
128 wereEvents = self.__battle.nextTurn()
130 # only print out state if something actually happened
131 if wereEvents:
132 self.__view.printState()
134 if self.__battle.getParty1().isAlive():
137 # sum exp from enemy party
138 exp = 0
139 for f in self.__battle.getParty2().getFighters():
140 exp += f.getStat("exp").getMax()
142 # hero party gets exp
143 self.__battle.getParty1().giveExp(exp)
146 print "Final Results"
147 print "============================================================="
148 self.__view.printParty(self.__battle.getParty1())
149 print "============================================================="
150 print "Victory Fanfare. Hand's party wins "+str(exp)+" exp!"
152 for f in self.__battle.getParty1().getFighters():
153 # remove all statuses
154 for s in f.getStatus():
155 s.genExit()
156 f.getStat("mp").setCurrent(f.getStat("mp").getMax())
158 else:
159 print "Game Over. Asgard mourns."
161 # clear out the hero party - they're dead!
162 self.__battle.setParty1(None)
165 def load(self,savefile):
166 #clear party1 and it's fighters
167 self.__battle.setParty1(Party("Heroes"))
169 #open savefile
170 fptr = open(savefile,"rb")
172 fptr.seek(0,2)
173 size = fptr.tell()
175 fptr.seek(0,0)
177 # number of bytes read in so far
178 readin = 0
180 while readin != size:
181 #read in struct descriptor
183 tstring = fptr.read(struct.calcsize("!B"))
184 [type] = struct.unpack("!B",tstring)
185 readin += struct.calcsize("!B")
188 if type == 0:
189 fstring = fptr.read(struct.calcsize("!20s20s20s20s20s20sB7I6B"))
190 readin += struct.calcsize("!20s20s20s20s20s20sB7I6B")
194 fptr.seek(readin,0)
195 fighter = Fighter(binary=fstring)
196 self.__battle.getParty1().addFighter(fighter)
198 #close savefile
199 fptr.close()
201 def save(self,savefile):
202 """ Writes all playable fighters to savefile. """
203 # Retrieving playable fighters
204 fighters = self.__battle.getParty1().getFighters()
206 # Writing each fighter to savefile
207 fptr = open(savefile,"wb")
209 for f in fighters:
210 # Convert fighter f to binary string
211 binStr = f.toBinaryString()
213 # Write binary string to savefile
214 fptr.write(binStr.strip())
216 fptr.close()
218 def createRandomBattle(self):
219 self.__battle.setParty2(Party("Villains"))
220 partySize = 2
221 partySize += random.randint(-1,2)
222 for x in range(0, partySize):
223 monstI = random.randint(0,len(self.__battle.getMonsters())-1)
225 monster = copy.deepcopy(self.__battle.getMonsters()[monstI])
226 self.__battle.getParty2().addFighter(monster)
228 for f in self.__battle.getParty1().getFighters():
229 spd = f.getStat("spd").getCurrent()
230 tom = round((1/float(spd)*100))
231 f.getStat("tom").setCurrent(tom)
232 f.getStat("tom").setMax(tom)
233 f.getStat("canMove").setCurrent(1)
234 f.getStat("ai").setCurrent(0)
236 self.__battle.setCurrentTime(0)
238 def loadStaticData(self,newGame):
239 """Load static game data: eventtypes, fighters (with stats and jobs)"""
242 dir = listdir('./data/eventtypes/')
244 self.__battle.setEventTypeList([])
246 for et in dir:
248 if et[0] == ".":
249 continue
251 etTree = libxml2.parseFile('./data/eventtypes/'+et)
253 #uncomment these
254 eventType = EventType(etTree)
255 self.__battle.getEventTypeList().append(eventType)
257 if newGame:
258 self.__battle.setParty1(Party("Heroes"))
260 ### Loading fighters ###
261 dir = listdir('./data/fighter/')
262 for f in dir:
264 # f cannot be a "." file
265 if f[0] == '.':
266 continue
268 # Create Fighter XML Tree
269 fTree = libxml2.parseFile('./data/fighter/'+f)
271 # Create Fighter Object
272 fighter = Fighter(fTree=fTree)
274 # Add fighter to respective party (1 or 2)
275 if fighter.getPlayable() and newGame:
276 self.__battle.getParty1().addFighter(fighter)
277 elif not fighter.getPlayable():
278 self.__battle.getMonsters().append(fighter)
280 def unloadStaticData(self):
281 """ Clears out all monsters and EventTypes. """
283 # Clearing out monsters
284 self.__battle.setMonsters([])
286 # Clearing out EventTypes
287 self.__battle.setEventTypeList([])
289 def getBattle(self):
290 return self.__battle
292 def getView(self):
293 return self.__view