2 from pygame
.locals import *
11 from statistic
import Statistic
12 from screen
import BattleScreen
13 from battle
import Battle
14 from equiption
import Equiption
15 from fighter
import Fighter
16 from eventtype
import EventType
20 """ This is the game controller. Currently, it mostly controls
21 battles, but does a few other meta processes that will no doubt be
22 completely unnecessary in a few releases. Additionally, it handles
23 saving, loading and game initialization using binary saves and XML
27 """ A link to the model currently being used. Battle is currently the only model. """
30 """ A link to the current screen being used. BattleScreen is currently the only screen. """
34 def __init__(self
,m
,v
):
35 """ Hook up Battle, BattleScreen and Asgard Controller. Initialize display surface. """
39 self
.__battle
.view
= v
44 self
.__display
= pygame
.display
.set_mode((800,600))
45 pygame
.display
.set_caption("Asgard Free Software RPG - Menu Testing Module")
47 s
= pygame
.Surface((20,20))
48 pygame
.draw
.rect(s
,255,pygame
.Rect((0,0),(20,20)))
49 self
.__display
.blit(s
,(20,20))
55 """ Handles Pygame Events. Especially quit, minimize, maximize, window movement, up, down, left, right, and enter. When enter is pressed, it processes the requested operation (through hardcoded procedures). """
58 et
= pygame
.event
.wait()
60 # Program needs to be shut down
66 elif et
.type == KEYUP
:
75 elif et
.key
== K_UP
or et
.key
== K_LEFT
:
78 elif et
.key
== K_DOWN
or et
.key
== K_RIGHT
:
84 self.unloadStaticData()
85 self.loadStaticData(True)
89 print "Path to Save File: ",
90 path = sys.stdin.readline()
91 self.load("" + path.strip() + "")
95 print "Path to Save File: ",
96 path = sys.stdin.readline()
97 self.save("" + path.strip() + "")
102 if self.__battle.getParty1() == None:
103 print "No game loaded."
106 self.createRandomBattle()
107 print "============================================================="
113 """ Show dummy menu. Get user choices. If New Game selected, call self.createNewSave(..). If Load Game selected, call self.load(..). If Save Game selected, call self.save(..) (show only if game loaded), show menu again. If Random Battle selected: (1)Create a random battle. (self.createRandomBattle(..)). (2)Print out the state of affairs before the battle begins. Executes Battle.nextTurn() once. The experience passed to giveExp should be the sum of the defeated party's experience. (3)After battle, show dummy menu again. If Quit selected, end program. """
115 self
.loadStaticData(False)
118 self
.__view
.drawStartup()
119 self
.__view
.drawMagic(None,None)
120 self
.__view
.drawCommands()
124 print "Battle Starts."
125 self
.__view
.printState()
127 # initialize the event checker boolean
130 while not self
.__battle
.isOver():
132 wereEvents
= self
.__battle
.nextTurn()
134 # only print out state if something actually happened
136 self
.__view
.printState()
138 if self
.__battle
.getParty1().isAlive():
141 # sum exp from enemy party
143 for f
in self
.__battle
.getParty2().getFighters():
144 exp
+= f
.getStat("exp").getMax()
146 # hero party gets exp
147 self
.__battle
.getParty1().giveExp(exp
)
150 print "Final Results"
151 print "============================================================="
152 self
.__view
.printParty(self
.__battle
.getParty1())
153 print "============================================================="
154 print "Victory Fanfare. Hand's party wins "+str(exp
)+" exp!"
156 for f
in self
.__battle
.getParty1().getFighters():
157 # remove all statuses
158 for s
in f
.getStatus():
160 f
.getStat("mp").setCurrent(f
.getStat("mp").getMax())
163 print "Game Over. Asgard mourns."
165 # clear out the hero party - they're dead!
166 self
.__battle
.setParty1(None)
169 def load(self
,savefile
):
170 """ Destroy hero Party and playable Fighters. Construct new hero Party and playable Fighters. """
172 #clear party1 and it's fighters
173 self
.__battle
.setParty1(Party("Heroes"))
176 fptr
= open(savefile
,"rb")
183 # number of bytes read in so far
186 while readin
!= size
:
187 #read in struct descriptor
189 tstring
= fptr
.read(struct
.calcsize("!B"))
190 [type] = struct
.unpack("!B",tstring
)
191 readin
+= struct
.calcsize("!B")
195 fstring
= fptr
.read(struct
.calcsize("!20s20s20s20s20s20sB7I6B"))
196 readin
+= struct
.calcsize("!20s20s20s20s20s20sB7I6B")
201 fighter
= Fighter(binary
=fstring
)
202 self
.__battle
.getParty1().addFighter(fighter
)
207 def save(self
,savefile
):
208 """ Calls Party.getBinaryString() for hero Party. Calls Fighter.getBinaryString() for all playable Fighters. Concatenates binary string and writes to save file. """
210 # Retrieving playable fighters
211 fighters
= self
.__battle
.getParty1().getFighters()
213 # Writing each fighter to savefile
214 fptr
= open(savefile
,"wb")
217 # Convert fighter f to binary string
218 binStr
= f
.toBinaryString()
220 # Write binary string to savefile
221 fptr
.write(binStr
.strip())
225 def createRandomBattle(self
):
226 """ Randomly selects some number (1 to 6) of monsters, and randomly determines which monsters they are. Copies each monster to populate an enemy party. """
228 self
.__battle
.setParty2(Party("Villains"))
230 partySize
+= random
.randint(-1,2)
231 for x
in range(0, partySize
):
232 monstI
= random
.randint(0,len(self
.__battle
.getMonsters())-1)
234 monster
= copy
.deepcopy(self
.__battle
.getMonsters()[monstI
])
235 self
.__battle
.getParty2().addFighter(monster
)
237 for f
in self
.__battle
.getParty1().getFighters():
238 spd
= f
.getStat("spd").getCurrent()
239 tom
= round((1/float(spd
)*100))
240 f
.getStat("tom").setCurrent(tom
)
241 f
.getStat("tom").setMax(tom
)
242 f
.getStat("canMove").setCurrent(1)
243 f
.getStat("ai").setCurrent(0)
245 self
.__battle
.setCurrentTime(0)
247 def loadStaticData(self
,newGame
):
248 """ Loads EventTypes and non-playable/initial playable Fighters. (at some point, other things too). Utilizes the Fighter xml constructor. By default it loads fighter objects that are non-playable into Battle.monsters, but when newGame is True, it also creates the hero party from the files in ./data/fighter/playable. It does not load playable fighters into Battle.monsters. """
250 dir = listdir('./data/eventtypes/')
252 self
.__battle
.setEventTypeList([])
259 etTree
= libxml2
.parseFile('./data/eventtypes/'+et
)
262 eventType
= EventType(etTree
)
263 self
.__battle
.getEventTypeList().append(eventType
)
266 self
.__battle
.setParty1(Party("Heroes"))
268 ### Loading fighters ###
269 dir = listdir('./data/fighter/')
272 # f cannot be a "." file
276 # Create Fighter XML Tree
277 fTree
= libxml2
.parseFile('./data/fighter/'+f
)
279 # Create Fighter Object
280 fighter
= Fighter(fTree
=fTree
)
282 # Add fighter to respective party (1 or 2)
283 if fighter
.getPlayable() and newGame
:
284 self
.__battle
.getParty1().addFighter(fighter
)
285 elif not fighter
.getPlayable():
286 self
.__battle
.getMonsters().append(fighter
)
288 def unloadStaticData(self
):
289 """ Clears out all monsters and EventTypes. """
291 # Clearing out monsters
292 self
.__battle
.setMonsters([])
294 # Clearing out EventTypes
295 self
.__battle
.setEventTypeList([])