Added Run EventType. exitBattle boolean is now in the EventType schema. If exitBatt...
[asgard.git] / consolecontroller.py
blob823a51e199beb06c8f94f876159e5fd9a2c927be
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 # For Attack and Magic
54 if t.getTargetSelection() == True:
55 self.__view.printTargetSelectMenu(vp,hp)
56 n = raw_input("% ")
57 # Select Villain
58 if vp.sizeOfParty() - int(n) >= 0:
59 d = vp.getFighter(int(n)-1)
60 # Select Hero
61 else:
62 d = hp.getFighter(int(n)-vp.sizeOfParty()-1)
63 # For Defend
64 else:
65 d = f
67 return [d,t]
69 def getMenuCommand(self):
71 self.__view.printStartupMenu()
73 n = raw_input("% ")
75 return int(n)
77 def getDebug(self):
78 return self.__debug
80 def setDebug(self,d):
81 self.__debug = d
83 def __gameLoop(self):
84 """Retrieves events from Parties and Executes all Events in queue per iteration"""
86 print "Asgard Free Software RPG - Testing Module"
88 self.loadStaticData(False)
90 while True:
91 choice = 0
92 while choice != 4:
93 choice = self.getMenuCommand()
95 if choice == 1:
96 self.unloadStaticData()
97 self.loadStaticData(True)
98 print "loaded..."
99 else:
100 if choice == 2:
101 print "Path to Save File: ",
102 path = sys.stdin.readline()
103 self.load("" + path.strip() + "")
104 print "loaded..."
106 elif choice == 3:
107 print "Path to Save File: ",
108 path = sys.stdin.readline()
109 self.save("" + path.strip() + "")
110 print "saved..."
112 elif choice == 4:
113 if self.__battle.getParty1() == None:
114 print "No game loaded."
115 choice = 0
116 else:
117 self.createRandomBattle()
118 print "============================================================="
119 else:
120 sys.exit()
122 print "Battle Starts."
123 self.__view.printState()
125 # initialize the event checker boolean
126 wereEvents = False
128 while not self.__battle.isOver():
129 # next iteration
130 wereEvents = self.__battle.nextTurn()
132 # only print out state if something actually happened
133 if wereEvents:
134 self.__view.printState()
136 if self.__battle.getRunFlag():
137 x = randint(1,3)
139 if x == 1:
140 print "Gotta get outta here!"
141 elif x == 2:
142 print "Hand's party runs away."
143 elif x == 3:
144 print "Battle's over. You've escaped."
146 self.__battle.setRunFlag(False)
148 elif self.__battle.getParty1().isAlive():
149 # sum exp from enemy party
150 exp = 0
151 for f in self.__battle.getParty2().getFighters():
152 exp += f.getStat("exp").getMax()
154 # hero party gets exp
155 self.__battle.getParty1().giveExp(exp)
158 print "Final Results"
159 print "============================================================="
160 self.__view.printParty(self.__battle.getParty1())
161 print "============================================================="
162 print "Victory Fanfare. Hand's party wins "+str(exp)+" exp!"
164 for f in self.__battle.getParty1().getFighters():
165 # remove all statuses
166 for s in f.getStatus():
167 s.genExit()
168 f.getStat("mp").setCurrent(f.getStat("mp").getMax())
170 else:
171 print "Game Over. Asgard mourns."
173 # clear out the hero party - they're dead!
174 self.__battle.setParty1(None)
177 def load(self,savefile):
178 #clear party1 and it's fighters
179 self.__battle.setParty1(Party("Heroes"))
181 #open savefile
182 fptr = open(savefile,"rb")
184 fptr.seek(0,2)
185 size = fptr.tell()
187 fptr.seek(0,0)
189 # number of bytes read in so far
190 readin = 0
192 while readin != size:
193 #read in struct descriptor
195 tstring = fptr.read(struct.calcsize("!B"))
196 [type] = struct.unpack("!B",tstring)
197 readin += struct.calcsize("!B")
200 if type == 0:
201 fstring = fptr.read(struct.calcsize("!20s20s20s20s20s20sB7I6B"))
202 readin += struct.calcsize("!20s20s20s20s20s20sB7I6B")
206 fptr.seek(readin,0)
207 fighter = Fighter(binary=fstring)
208 self.__battle.getParty1().addFighter(fighter)
210 #close savefile
211 fptr.close()
213 def save(self,savefile):
214 """ Writes all playable fighters to savefile. """
215 # Retrieving playable fighters
216 fighters = self.__battle.getParty1().getFighters()
218 # Writing each fighter to savefile
219 fptr = open(savefile,"wb")
221 for f in fighters:
222 # Convert fighter f to binary string
223 binStr = f.toBinaryString()
225 # Write binary string to savefile
226 fptr.write(binStr.strip())
228 fptr.close()
230 def createRandomBattle(self):
231 self.__battle.setParty2(Party("Villains"))
232 partySize = 2
233 partySize += random.randint(-1,2)
234 for x in range(0, partySize):
235 monstI = random.randint(0,len(self.__battle.getMonsters())-1)
237 monster = copy.deepcopy(self.__battle.getMonsters()[monstI])
238 self.__battle.getParty2().addFighter(monster)
240 for f in self.__battle.getParty1().getFighters():
241 spd = f.getStat("spd").getCurrent()
242 tom = round((1/float(spd)*100))
243 f.getStat("tom").setCurrent(tom)
244 f.getStat("tom").setMax(tom)
245 f.getStat("canMove").setCurrent(1)
246 f.getStat("ai").setCurrent(0)
248 self.__battle.setCurrentTime(0)
250 def loadStaticData(self,newGame):
251 """Load static game data: eventtypes, fighters (with stats and jobs)"""
254 dir = listdir('./data/eventtypes/')
256 self.__battle.setEventTypeList([])
258 for et in dir:
260 if et[0] == ".":
261 continue
263 etTree = libxml2.parseFile('./data/eventtypes/'+et)
265 #uncomment these
266 eventType = EventType(etTree)
267 self.__battle.getEventTypeList().append(eventType)
269 if newGame:
270 self.__battle.setParty1(Party("Heroes"))
272 ### Loading fighters ###
273 dir = listdir('./data/fighter/')
274 for f in dir:
276 # f cannot be a "." file
277 if f[0] == '.':
278 continue
280 # Create Fighter XML Tree
281 fTree = libxml2.parseFile('./data/fighter/'+f)
283 # Create Fighter Object
284 fighter = Fighter(fTree=fTree)
286 # Add fighter to respective party (1 or 2)
287 if fighter.getPlayable() and newGame:
288 self.__battle.getParty1().addFighter(fighter)
289 elif not fighter.getPlayable():
290 self.__battle.getMonsters().append(fighter)
292 def unloadStaticData(self):
293 """ Clears out all monsters and EventTypes. """
295 # Clearing out monsters
296 self.__battle.setMonsters([])
298 # Clearing out EventTypes
299 self.__battle.setEventTypeList([])
301 def getBattle(self):
302 return self.__battle
304 def getView(self):
305 return self.__view