"Levels class" import os, string, glob import pygame from pygame.locals import * import random, math from levelsdata import LevelsData import game, gfx, input, snd import sprites.objairexplosion import sprites.objblast import sprites.objbomb import sprites.objexhaust import sprites.objflame import sprites.objgroundexplosion import sprites.objplane0 import sprites.objplane1 import sprites.objballoon import sprites.objradar import sprites.objrocket import sprites.objrocketlauncher import sprites.objship import sprites.objshiptest import sprites.objsstext import sprites.objstoragetank0 import sprites.objstoragetank1 import sprites.objtower import sprites.objhouse import sprites.objbuilding import sprites.objcactus import sprites.objtree0 import sprites.objtank0 import sprites.objtank1 import sprites.objheadquarters import sprites.objicbm import sprites.objfuelship # for sprite types from basespriteobj import * from nesteddict import NestedDict from levelsdata import LevelsData LEVELS_DIR = 'data' LEVELS_FILENAME = 'levels.txt' LEVELS_PATH = os.path.join(LEVELS_DIR,LEVELS_FILENAME) RANDOM = random.random global levels_text levels_text = None def load_game_resources(): global levels_text try: file = open(LEVELS_PATH,'r') levels_text = file.read() file.close() except: # major error reading text raise "Error reading %s file" % LEVELS_PATH class Levels: def __init__(self,groundobjects,airobjects,exhaust): global levels_data #print "entering Levels.__init__()" self.debug = 0 self.levels_data = LevelsData(levels_text) self.groundobjs = groundobjects self.airobjs = airobjects self.exhaust = exhaust # some shortcuts self.missions_data = self.levels_data.missions self.levels_data.show() self.missions_len = len(self.missions_data) if self.missions_len <= 0: raise "No missions!" #print "about to validate missions" self.validate_missions() self.start_game() #print "missions data: ",self.missions_data #print "current_mission_data: ",self.current_mission_data #print "current part data:",self.current_part_data #print len(self.current_mission_data) #print len(self.current_part_data) def addactor(self,actor): "given one actor, see if we should add it..." # check to see if there are too many actors on screen already... # first look at the max_instances from levelsdata if actor.max_instances != None: if actor.class_object.count >= actor.max_instances: return 0 # if levelsdata max_instances is 0, we use the class object's max. elif actor.class_object.max != None: if actor.class_object.count >= actor.class_object.max: return 0 p = RANDOM() #print "in add actor- t:%d p:%f actor.p:%f" % (self.time,p,actor.probability) if p < actor.probability: #print "adding actor",self.time #print "apply(%s,%s)" % (actor.class_object, actor.parameters) actor_object = apply(actor.class_object,actor.parameters) # is this object a mission objective? if actor.is_objective == 1: actor_object.objective = 1 if actor.is_objective == 1 and self.mission_over == 1: # don't add in this case return 0 if actor_object.type == GROUND_OBJECT: self.groundobjs.append(actor_object) elif actor_object.type == AIR_OBJECT: self.airobjs.append(actor_object) else: # should never get here! raise "Error: sprite object has undefined type!" # we added an actor return actor_object.type else: # no actor added return None def addactors(self): """Use levels data when adding actors...""" # see if we need to add the fuel ship... # only do this roughly once per second if self.time % 1000 == 0: if self.current_mission_data.refuel_actor != None: if self.time/game.desired_fps > self.current_mission_data.refuel_actor.interval * self.refuel_counter: self.refuel_counter += 1 self.addactor(self.current_mission_data.refuel_actor) # go on to next part if necessary self.update_part() if self.time % game.add_actor_interval == 0: # call self.addactor once for every item in self.current_part_data.actors addactor = self.addactor actors = self.current_part_data.actors map(addactor, actors) # try to add one ground object and one air object each time #for wanted_type in (GROUND_OBJECT,AIR_OBJECT): # for actor in actors: # actor_type = actor.class_object.type # if actor_type == wanted_type: # if self.addactor(actor) != None: # # if we've added an actor already, wait until next add interval... # break def update_part(self): "do this at every tick- increments time, and changes part if necessary." self.time += 1 seconds = self.time / game.desired_fps if seconds >= self.current_part_data.time: self.next_part() #print "mission: %d part: %d time: %d" % (self.current_mission_number, self.current_part_number, self.time) def set_mission_and_part(self): # we are beginning a mission... self.mission_over = 0 if self.current_mission_number >= self.missions_len: self.current_mission_number = self.missions_len - 1 #print self.current_mission self.current_mission_data = self.missions_data[self.current_mission_number] parts_len = len(self.current_mission_data.parts) if self.current_part_number >= parts_len: self.current_part_number = parts_len - 1 #print self.current_part self.current_part_data = self.current_mission_data.parts[self.current_part_number] def next_mission(self): "return 1 if there is a next mission, 0 if there are no more missions..." self.last_mission_number = self.current_mission_number self.current_mission_number += 1 self.set_mission_and_part() return self.last_mission_number != self.current_mission_number def next_part(self): self.current_part_number += 1 self.set_mission_and_part() def get_mission_descr(self): return self.current_mission_data.description def get_mission_number(self): return self.current_mission_number + 1 def mission_complete(self): self.mission_over = 1 def start_game(self): self.time = 0 self.current_mission_number = 0 self.last_mission_number = -1 self.current_part_number = 0 self.set_mission_and_part() return self.current_mission_number def start_mission_over(self): self.time = 0 self.refuel_counter = 1 # start at one, because we don't need the fuel ship at the start self.current_part_number = 0 self.set_mission_and_part() return self.current_mission_number def validate_actor(self,actor): try: method_name = "sprites.%s" % actor.class_string method = eval(method_name) #print "class %s ok." % actor.class_string actor.class_object = method except: # Fatal raise "In %s, Module sprite has no method %s!" % (LEVELS_PATH, actor.class_string) # now see if there are any objects that need eval'ing... new_parameters = [] for parameter in actor.parameters_sequence: if type(parameter) == type(''): # it's a method name, so try to eval it try: new_parameter = eval(parameter) #print "Setting parameter %s to object." % parameter new_parameters.append(new_parameter) except: # Fatal raise "In %s, no method %s!" % (LEVELS_PATH, parameter) else: # it's not a method name- add it new_parameters.append(parameter) actor.parameters = new_parameters def validate_missions(self): """check the missions data structure to make sure the classes are all valid, and fill in the class object""" for mission in self.missions_data: for part in mission.parts: for actor in part.actors: self.validate_actor(actor) if mission.refuel_actor != None: self.validate_actor(mission.refuel_actor) if __name__ == "__main__": load_game_resources() levels_data.show()