class PlacementGhost(GameObject): def __init__(self,player,type,scale): self.type = type self.player = player self.node_path = NodePath("PlacementGhost") self.scale = scale self.model_dict = {"army":["../models/infantry_counter_grey.egg","../models/infantry_counter_red.egg","../models/infantry_counter_green.egg"],"tower":["../models/tower_grey.egg","../models/tower_red.egg","../models/tower_green.egg"]} self.model = loader.loadModel(self.model_dict[type][player]) self.model.reparentTo(self.node_path) self.node_path.reparentTo(render) self.node_path.setScale(self.scale,self.scale,self.scale) self.node_path.setColor(1,1,1,0.4) self.node_path.setTransparency(True) def place(self,type,x,y): if self.type == "tower": tower = Tower(self.player,base.object_scale,self.node_path.getX(),self.node_path.getY()) return tower if self.type == "army": army = Army(self.player,base.object_scale,self.node_path.getX(),self.node_path.getY()) return army def change_player(self,player): if base.state == "placement": self.model.remove() self.player = player self.model = loader.loadModel(self.model_dict[self.type][self.player]) self.model.reparentTo(self.node_path) def change_type(self,type): if base.state == "placement": self.model.remove() self.type = type self.model = loader.loadModel(self.model_dict[self.type][self.player]) self.model.reparentTo(self.node_path)
class PlacementGhost(GameObject): def __init__(self, player, type, scale): self.type = type self.player = player self.node_path = NodePath("PlacementGhost") self.scale = scale self.model_dict = { "army": [ "../models/infantry_counter_grey.egg", "../models/infantry_counter_red.egg", "../models/infantry_counter_green.egg" ], "tower": [ "../models/tower_grey.egg", "../models/tower_red.egg", "../models/tower_green.egg" ] } self.model = loader.loadModel(self.model_dict[type][player]) self.model.reparentTo(self.node_path) self.node_path.reparentTo(render) self.node_path.setScale(self.scale, self.scale, self.scale) self.node_path.setColor(1, 1, 1, 0.4) self.node_path.setTransparency(True) def place(self, type, x, y): if self.type == "tower": tower = Tower(self.player, base.object_scale, self.node_path.getX(), self.node_path.getY()) return tower if self.type == "army": army = Army(self.player, base.object_scale, self.node_path.getX(), self.node_path.getY()) return army def change_player(self, player): if base.state == "placement": self.model.remove() self.player = player self.model = loader.loadModel( self.model_dict[self.type][self.player]) self.model.reparentTo(self.node_path) def change_type(self, type): if base.state == "placement": self.model.remove() self.type = type self.model = loader.loadModel( self.model_dict[self.type][self.player]) self.model.reparentTo(self.node_path)
def generateToonMoveTrack(self, toon): node = NodePath('tempNode') displacement = Vec3(toon.getPos(render) - self.getPos(render)) displacement.setZ(0) displacement.normalize() movieDistance = self.movieNode.getDistance(self.rotateNode) displacement *= movieDistance node.reparentTo(render) node.setPos(displacement + self.getPos(render)) node.lookAt(self) heading = PythonUtil.fitDestAngle2Src(toon.getH(render), node.getH(render)) hpr = toon.getHpr(render) hpr.setX(heading) finalX = node.getX(render) finalY = node.getY(render) finalZ = node.getZ(render) node.removeNode() toonTrack = Sequence( Parallel( ActorInterval(toon, 'walk', loop=True, duration=1), Parallel( LerpPosInterval(toon, 1.0, Point3(finalX, finalY, toon.getZ(render)), fluid=True, bakeInStart=False)), LerpHprInterval(toon, 1.0, hpr=hpr)), Func(toon.loop, 'neutral')) return toonTrack
class Water(AssetBase): def __init__(self, name, size=10000, resolution=1024): """Arguments: size -- Edge length of the water square. resolution -- Texture size of the rendered reflection buffer. """ # Uncomment to see the output of the refclection buffer. base.bufferViewer.toggleEnable() AssetBase.__init__(self) self.name = name self.cm = CardMaker("water surface") self.cm.setFrame(-0.5 * size, 0.5 * size, -0.5 * size, 0.5 * size) self.cm.setHasUvs(True) self.node = NodePath(self.cm.generate()) self.node.setP(self.node, -90) self.node.flattenLight() self.node.hide(BitMask32.bit(1)) #self.node.setTwoSided(True) self.node.setShaderOff() # size of one texture tile in meters self.tex_size = 100.0 diffuse = TexturePool.loadTexture("textures/water.diffuse.png") diffuse.setWrapU(Texture.WMRepeat) diffuse.setWrapV(Texture.WMRepeat) diffuse.setMinfilter(Texture.FTLinearMipmapLinear) diffuse.setMagfilter(Texture.FTLinearMipmapLinear) self.diffuse_stage = TextureStage("diffuse") self.diffuse_stage.setSort(2) self.node.setTexture(self.diffuse_stage, diffuse) self.node.setTexScale(self.diffuse_stage, size / self.tex_size, size / self.tex_size) # Reflection camera renders to 'buffer' which is projected onto the # water surface. buffer = base.win.makeTextureBuffer("water reflection", resolution, resolution) buffer.setClearColor(Vec4(0, 0, 0, 1)) self.refl_cam = base.makeCamera(buffer) self.refl_cam.reparentTo(self.node) self.refl_cam.node().setCameraMask(BitMask32.bit(1)) self.refl_cam.node().getLens().setFov(base.camLens.getFov()) self.refl_cam.node().getLens().setNearFar(1, 100000) plane = PlaneNode("water culling plane", Plane(Vec3(0, 0, 1), Point3(0, 0, 0))) cfa = CullFaceAttrib.makeReverse() cpa = ClipPlaneAttrib.make(PlaneNode.CEVisible, plane) rs = RenderState.make(cfa, cpa) self.refl_cam.node().setInitialState(rs) reflection = buffer.getTexture() reflection.setMinfilter(Texture.FTLinear) reflection.setMagfilter(Texture.FTLinear) self.refl_stage = TextureStage("reflection") self.refl_stage.setSort(1) self.node.projectTexture(self.refl_stage, reflection, base.cam) self.node.setTexture(self.refl_stage, reflection) # Blend between diffuse and reflection. self.diffuse_stage.setColor(VBase4(1, 1, 1, 0.2)) # opacity of 20% self.diffuse_stage.setCombineRgb( TextureStage.CMInterpolate, TextureStage.CSTexture, TextureStage.COSrcColor, TextureStage.CSPrevious, TextureStage.COSrcColor, TextureStage.CSConstant, TextureStage.COSrcAlpha) self.addTask(self.update, name="water update", sort=1, taskChain="world") def update(self, task): """Updates position of the reflection camera and the water plane.""" mc = base.cam.getMat(render) #mf = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)).getReflectionMat() mf = Mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1) self.refl_cam.setMat(mc * mf) self.node.setX(camera.getX(render)) self.node.setY(camera.getY(render)) self.node.setTexOffset(self.diffuse_stage, self.node.getX() / self.tex_size, self.node.getY() / self.tex_size) return task.cont def destroy(self): self.removeAllTasks() self.node.removeNode() self.refl_cam.removeNode()
class Battle(GameObject): def __init__(self,counters,start=-1): global battle_count self.combatants = counters self.my_id = battle_count self.turn = 0 self.chance_range = 100 self.chance_success = 80 self.col_scale_orig = 2.0 self.col_scale = self.col_scale_orig self.col_scale_inc = 0.4 battle_count += 1 if start != -1: self.turn = start self.combatants[start].turn_start() coords = [(self.combatants[0].get_x(),self.combatants[0].get_y()),(self.combatants[1].get_x(),self.combatants[1].get_y())] self.x,self.y = TCalc.midpoint(coords) self.node_path = NodePath("battle"+str(self.my_id)+"_node_path") self.node_path.setPos(self.x,self.y,0) self.node_path.setTag("id",str(self.my_id)) self.node_path.setTag("type","battle") self.node_path.reparentTo(render) self.bat_col = self.node_path.attachNewNode(CollisionNode("battle"+str(self.my_id)+"_c_node")) self.bat_col.setScale((self.col_scale,self.col_scale,0.2)) self.bat_col.setPos(0,0,0) self.bat_col.node().addSolid(CollisionSphere(0,0,0,10)) self.bat_col.setTag("type","battle") self.bat_col.show() self.battle_speed = 1.0 for a in self.combatants: #a.turn_start() a.stop() a.state = "battle" a.army_fight_col.setTag("state","battle") a.battle = self.my_id if base.client == False: taskMgr.add(self.battle_init_rolls, "battle"+str(self.my_id)+"_task_start") def recenter(self): new_x = 0.0 new_y = 0.0 x_list = [] y_list = [] counter = 0 try: for a in self.combatants: if a.state != "dead": x_list.append(a.node_path.getX()) y_list.append(a.node_path.getY()) counter += 1 new_x += a.node_path.getX() new_y += a.node_path.getY() new_x /= len(x_list) new_y /= len(y_list) self.node_path.setPos(new_x,new_y,0) except: pass def shrink(self): if len(self.combatants) <= 10: self.col_scale -= self.col_scale_orig*self.col_scale_inc self.bat_col.setScale((self.col_scale,self.col_scale,0.2)) def battle_init_rolls(self,task): init_rolls = [] highest_roll = -1 counter = 0 leader = 0 for a in self.combatants: roll = random.randint(0,self.chance_range)+a.stat_init print counter,"rolled",roll init_rolls.append(roll) if roll > highest_roll: highest_roll = roll leader = counter counter += 1 self.turn = leader print leader,"wins!" self.combatants[self.turn].turn_start() a1 = self.combatants[0] a2 = self.combatants[1] if base.client == False: if base.single_player == False: base.net_manager.server_messager("battle_start",[a1.my_id,a1.node_path.getX(),a1.node_path.getY(), a2.my_id,a2.node_path.getX(),a2.node_path.getY(), self.turn]) taskMgr.doMethodLater(1,self.battle_loop,"battle"+str(self.my_id)+"_task_loop") self.get_odds() return task.done def get_odds(self): side1 = [] side2 = [] counter = 0 for a in self.combatants: if a.player == 1 and a.state != "dead": side1.append(a) counter += 1 elif a.player == 2 and a.state != "dead": side2.append(a) counter += 1 self.odds = (100/counter)*len(side1) if base.col_manager.selected_node == self.node_path: base.vis_manager.statbar.refresh_battle(self.odds) def target_recheck(self): army = self.combatants[self.turn] target_id = random.randint(0,len(self.combatants)-1) target = self.combatants[target_id] while target == army or target.player == army.player or target.state == "dead": target_id = random.randint(0,len(self.combatants)-1) target = self.combatants[target_id] print "recheck target - aquired",target_id return army,target,target_id def turn_change(self,new_turn): self.combatants[self.turn].turn_end() self.combatants[new_turn].turn_start() self.turn = new_turn def battle_loop(self,task): towerBuff = 0 battle_end = False army,target,target_id = self.target_recheck() task.delayTime = self.battle_speed+army.stat_delay roll = random.randint(0,self.chance_range)+army.stat_hit #Make towers pown arse for t in base.towers: if t.player == army.player: distanceToTower = base.calculator.dist_to_point(army.get_x(),army.get_y(),t.get_x(),t.get_y()) if distanceToTower < 80: towerBuff = random.randint(0, 40) roll+=towerBuff if roll >= self.chance_success: roll = random.randint(0,self.chance_range)+target.stat_block if roll >= self.chance_success: result = "block" else: result = "hit" target.state = "dead" battle_end = True for a in self.combatants: if a.player != army.player and a.state != "dead": battle_end = False else: result = "fail" if base.client == False and base.single_player == False: randomness = 80 army.battle_shuffle(self.node_path.getX()+random.randint(0,randomness)-randomness/2,self.node_path.getY()+random.randint(0,randomness)-randomness/2) if base.single_player == False: base.net_manager.server_messager("battle_clash",[self.my_id,army.my_id,target.my_id,result,towerBuff]) self.clash(army,target,result,towerBuff) army.turn_end() last_turn = self.turn if battle_end: if base.single_player == False: base.net_manager.server_messager("battle_end",[self.my_id]) self.end() return task.done else: self.get_odds() if self.turn < len(self.combatants)-1: self.turn += 1 else: self.turn = 0 while self.combatants[self.turn].state == "dead": if self.turn < len(self.combatants)-1: self.turn += 1 else: self.turn = 0 if base.single_player == False: base.net_manager.server_messager("battle_turn",[self.my_id,self.turn]) self.combatants[self.turn].turn_start() return task.again def end(self): if base.col_manager.selected_node == self.node_path: base.vis_manager.statbar.reset_statbar() for a in self.combatants: a.turn_end() if a.state != "dead": a.state = "normal" a.battle = -1 a.army_fight_col.setTag("state","normal") self.destroy() def clash(self,a1,a2,result,buff): if buff != 0: buffText = "^+" +str(buff) TimVisuals.BattleText(self.node_path,buffText,self.x,self.y + 10,(1,1,0,1)) if result == "block": TimVisuals.BattleText(self.node_path,"BLOCK!",self.x,self.y,a2.colour) elif result == "hit": TimVisuals.BattleText(self.node_path,"HIT AND KILL!",self.x,self.y,a1.colour) a2.state = "dead" a2.die() else: TimVisuals.BattleText(self.node_path,"Attack Failed!",self.x,self.y,a1.colour) def add_army(self,army): army.stop() army.state = "battle" army.army_fight_col.setTag("state","battle") army.battle = self.my_id self.combatants.append(army) if len(self.combatants) <= 10: self.col_scale += self.col_scale_orig*self.col_scale_inc self.bat_col.setScale((self.col_scale,self.col_scale,0.2)) self.get_odds() self.recenter() def destroy(self): self.node_path.removeNode()
class Character(DirectObject, XMLExportable, PropertiesTableAbstract, GameEntity): def __init__(self, attributes, showCollisions, grid_currentx, grid_currenty, grid_playable_pos, parent): GameEntity.__init__(self, parent) #running parent constructor self.movtask = 0 self.showCollisions = showCollisions self.grid_currentx = grid_currentx self.grid_currenty = grid_currenty self.grid_playable_pos = grid_playable_pos self.attributes = attributes self.onPicked = '' self.onWalked = '' self.typeName = 'character' self.properties = { 'url': '', 'onWalked': '', 'onPicked': '', 'id': '', 'inclination': '', 'scale': '', 'hitboxscale': '', 'speed': '', 'playable': '', 'direction': '' } if attributes.has_key('url'): self.properties['url'] = attributes['url'].value else: print "WARNING: url not defined, loading placeholder" self.properties['url'] = 'misc/placeholder' if attributes.has_key('id'): self.properties['id'] = attributes['id'].value else: self.properties['id'] = 'all' if attributes.has_key('inclination'): self.properties['inclination'] = float( attributes['inclination'].value) else: self.properties['inclination'] = 30.0 if attributes.has_key('scale'): self.properties['scale'] = float(attributes['scale'].value) else: self.properties['scale'] = 1.0 if attributes.has_key('hitboxscale'): self.properties['hitboxscale'] = float( attributes['hitboxscale'].value) else: self.properties['hitboxscale'] = 1.0 if attributes.has_key('speed'): self.properties['speed'] = float(attributes['speed'].value) else: self.properties['speed'] = 1.0 #self.isNPC remains true while isPlayable is changable if attributes.has_key('playable'): self.playable = playable = attributes['playable'].value if self.playable == 'false': self.isNPC = False #print "setting ", self.properties['id'], " to ", self.isNPC else: self.isNPC = True #print "setting ", self.properties['id'], " to ", self.isNPC else: self.playable = playable = 'false' self.isNPC = True self.properties['playable'] = self.playable if attributes.has_key('direction'): self.properties['direction'] = attributes['direction'].value else: self.properties['direction'] = "down" if attributes.has_key('onWalked'): self.properties['onWalked'] = self.onWalked = attributes[ 'onWalked'].value else: self.properties['onWalked'] = self.onWalked = "" if attributes.has_key('onPicked'): self.properties['onPicked'] = self.onPicked = attributes[ 'onPicked'].value self.generateNode(showCollisions) def generateNode(self, showCollisions): self.destroy() #setting local variable attributes = self.attributes #defaulted to None self.pickCTrav = None #movement self.state = "still" self.showCollisions = showCollisions self.movtask = 0 self.currentlydown = [] self.currentlyfollowed = 0 self.pickRequest = False #public props self.node = NodePath("characternode") self.node.setTwoSided(True) self.wtop = self.applyNearestFilter( loader.loadModel( resourceManager.getResource(self.properties['url']) + '/wtop.egg')) self.wdown = self.applyNearestFilter( loader.loadModel( resourceManager.getResource(self.properties['url']) + '/wdown.egg')) self.wleft = self.applyNearestFilter( loader.loadModel( resourceManager.getResource(self.properties['url']) + '/wleft.egg')) self.wright = self.applyNearestFilter( loader.loadModel( resourceManager.getResource(self.properties['url']) + '/wright.egg')) self.stop = self.applyNearestFilter( loader.loadModel( resourceManager.getResource(self.properties['url']) + '/stop.egg')) self.sdown = self.applyNearestFilter( loader.loadModel( resourceManager.getResource(self.properties['url']) + '/sdown.egg')) self.sleft = self.applyNearestFilter( loader.loadModel( resourceManager.getResource(self.properties['url']) + '/sleft.egg')) self.sright = self.applyNearestFilter( loader.loadModel( resourceManager.getResource(self.properties['url']) + '/sright.egg')) #Texture.FTNearest self.wtop.reparentTo(self.node) self.wdown.reparentTo(self.node) self.wleft.reparentTo(self.node) self.wright.reparentTo(self.node) self.stop.reparentTo(self.node) self.sdown.reparentTo(self.node) self.sleft.reparentTo(self.node) self.sright.reparentTo(self.node) self.leftdown = False self.rightdown = False self.downdown = False self.topdown = False if self.playable == "true": self.setPlayable( False) #seems nonsense, triggered on grid.changeMap event self.node.setTag( "playable", "true" ) #setting this to make it recognizable from grid changeMap api self.setCollisions(True) self.setPickCollisions(True) else: self.setPlayable(False) self.node.setTag("playable", "false") self.setCollisions(False) self.setPickCollisions(False) #self.node.setX((-32/2)+0.5) self.node.setP(-(360 - int(self.properties['inclination']))) self.node.setScale(float(self.properties['scale'])) self.node.setTransparency(TransparencyAttrib.MAlpha) self.lastpos = self.node.getPos() self.showAllSubnodes() #taskMgr.doMethodLater(4, self.face, 'charload'+self.properties['id'], [self.properties['direction']]) self.face(self.properties['direction']) #set unique id self.node.setTag("id", self.properties['id']) #setting scripting part self.node.setTag("onWalked", self.onWalked) self.node.setTag("onPicked", self.onPicked) #storing a pointer of the gamenode self.node.setPythonTag("gamenode", self) self.npc_walk_stack = [] self.npc_walk_happening = False self.globalLock = False self.setX(self.grid_currentx) self.setY(self.grid_currenty) if self.isNPC != True: print "attempting creation of NPC in ", self.grid_currentx, "-", self.grid_currenty if attributes.has_key('playable'): if self.isNPC != False: if ((self.grid_playable_pos.getX() != 0) and (self.grid_playable_pos.getY() != 0)): print 'GRID: moving player to ' + str( self.grid_playable_pos) self.setX(self.grid_playable_pos.getX()) self.setY(self.grid_playable_pos.getY()) #automatic reparenting (and showing) when (re)generating node self.node.wrtReparentTo(self.parent.node) def getName(self): return 'Character: ' + self.properties['id'] def xmlAttributes(self): return self.properties def xmlTypeName(self): return self.typeName ''' Sanitize properties data to be of correct type from string ''' def sanitizeProperties(self): #sanitizing data self.properties['inclination'] = float(self.properties['inclination']) self.properties['hitboxscale'] = float(self.properties['hitboxscale']) self.properties['speed'] = float(self.properties['speed']) self.properties['scale'] = float(self.properties['scale']) self.updateTilePosition() #interface needed by PropertiesTable # regenerates the node at every change def onPropertiesUpdated(self): self.sanitizeProperties() self.generateNode(self.showCollisions) #interface needed by PropertiesTable #TODO: implement as real interface? def getPropertyList(self): return self.properties #interface needed by PropertiesTable def setProperty(self, key, value): self.properties[key] = value def setSpeed(self, s): self.properties['speed'] = s def applyNearestFilter(self, model): for tex in model.findAllTextures(): tex.setMinfilter(Texture.FT_nearest) tex.setMagfilter(Texture.FT_nearest) return model ''' make the npc walk in direction for units ''' def npc_push_walk(self, direction, units): #locking script execution self.globalLock = True script.addOneCustomLock(self) #start the walking self.npc_walk_stack.append([direction, units]) self.npc_walk_helper() #apicall def npc_walk_helper(self): x = self.node.getX() y = self.node.getZ() #concurrent protection if self.npc_walk_happening == True: return #returning if no movement has to be performed if len(self.npc_walk_stack) < 0: return movement = self.npc_walk_stack.pop(0) direction = movement[0] units = movement[1] self.npc_targetx = x self.npc_targety = y self.npc_direction = direction if (direction == "down"): self.npc_targety = self.npc_targety - units elif (direction == "up"): self.npc_targety = self.npc_targety + units elif (direction == "left"): self.npc_targetx = self.npc_targetx - units elif (direction == "right"): self.npc_targetx = self.npc_targetx + units self.setAnim(direction) self.npc_walk_happening = True self.npc_movtask = taskMgr.add(self.npc_walk_task, "npc_moveCharacterTask" + self.properties['id'], uponDeath=self.npc_walk_callback) def npc_walk_task(self, task): dt = globalClock.getDt() if (self.npc_direction == 'left'): self.node.setX(self.node.getX() - 1 * dt * self.properties['speed']) currentx = self.node.getX() if currentx <= self.npc_targetx: return task.done if (self.npc_direction == 'right'): self.node.setX(self.node.getX() + 1 * dt * self.properties['speed']) currentx = self.node.getX() if currentx >= self.npc_targetx: return task.done if (self.npc_direction == 'up'): self.node.setZ(self.node.getZ() + 1 * dt * self.properties['speed']) currenty = self.node.getZ() if currenty >= self.npc_targety: return task.done if (self.npc_direction == 'down'): self.node.setZ(self.node.getZ() - 1 * dt * self.properties['speed']) currenty = self.node.getZ() if currenty <= self.npc_targety: return task.done return task.cont def npc_walk_callback(self, task): self.face(self.npc_direction) #unlocking concurrent movement protection self.npc_walk_happening = False if len(self.npc_walk_stack) > 0: self.npc_walk_helper() else: #character ended walking, unlock self.globalLock = False ''' write destroyfunction ''' def destroy(self): #not accepting events self.ignoreAll() #destroying everything down if self.node != None: self.node.remove_node() #removing all tasks if self.movtask != 0: taskMgr.remove(self.movtask) self.movtask = 0 def face(self, direction): if direction == "left": self.hideAllSubnodes() self.sleft.show() if direction == "right": self.hideAllSubnodes() self.sright.show() if direction == "top" or direction == "up": #let's keep retrocompatibility self.hideAllSubnodes() self.stop.show() if direction == "down": self.hideAllSubnodes() self.sdown.show() def setCollisions(self, value): if value == True: b = self.node.getBounds().getRadius() self.cTrav = CollisionTraverser() self.collisionTube = CollisionSphere( b / 2, 0, b / 2, 0.035 * self.properties['hitboxscale']) self.collisionNode = CollisionNode('characterTube') self.collisionNode.addSolid(self.collisionTube) self.collisionNodeNp = self.node.attachNewNode(self.collisionNode) self.collisionHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.collisionNodeNp, self.collisionHandler) if self.showCollisions == True or main.editormode: # Uncomment this line to see the collision rays self.collisionNodeNp.show() # Uncomment this line to show a visual representation of the # collisions occuring self.cTrav.showCollisions(render) else: b = self.node.getBounds().getRadius() self.collisionTube = CollisionSphere( b / 2, 0, b / 2, 0.035 * self.properties['hitboxscale']) #allowing playables to collide with npcs if self.isNPC == True: #TODO: fix because it's completely f****d up self.collisionNode = CollisionNode('characterTube') else: self.collisionNode = CollisionNode('characterNPCTube') self.collisionNode.addSolid(self.collisionTube) self.collisionNodeNp = self.node.attachNewNode(self.collisionNode) #set if camera has to effectively follow the character #while it moves def setFollowedByCamera(self, value): #camera follow if value: if self.currentlyfollowed != True: customCamera.follow(self) self.currentlyfollowed = True else: if self.currentlyfollowed != False: customCamera.dontFollow() self.currentlyfollowed = False def setPickCollisions(self, value): if value: print "setting pick collisions" b = self.node.getBounds().getRadius() self.pickCTrav = CollisionTraverser() self.pickCollisionTube = CollisionSphere( b / 2, 0, b / 2, 0.035 * self.properties['hitboxscale'] + 0.01) self.pickCollisionNode = CollisionNode('characterPickTube') self.pickCollisionNode.addSolid(self.pickCollisionTube) self.pickCollisionNodeNp = NodePath(self.pickCollisionNode) self.pickCollisionNodeNp.reparentTo(self.node) self.pickCollisionHandler = CollisionHandlerQueue() self.pickCTrav.addCollider(self.pickCollisionNodeNp, self.pickCollisionHandler) if self.showCollisions == True: # Uncomment this line to see the collision rays self.pickCollisionNodeNp.show() # Uncomment this line to show a visual representation of the # collisions occuring self.pickCTrav.showCollisions(render) else: #dereferincing all pick colliders (must be done in order not to collide onto NPCs) self.pickCTrav = None self.pickCollisionTube = None self.pickCollisionNode = None self.pickCollisionNodeNp = None self.pickCollisionHandler = None #used to set playability in real time #useful when we want to switch context/scripted scenes def setPlayable(self, value): if self.isNPC != False: if value == True: #down events self.accept("arrow_left", self.arrowLeftDown) self.accept("arrow_right", self.arrowRightDown) self.accept("arrow_up", self.arrowUpDown) self.accept("arrow_down", self.arrowDownDown) #up events self.accept("arrow_left-up", self.arrowLeftUp) self.accept("arrow_right-up", self.arrowRightUp) self.accept("arrow_up-up", self.arrowUpUp) self.accept("arrow_down-up", self.arrowDownUp) self.accept("space", self.spaceDown) self.node.setTag("playable", "true") self.setFollowedByCamera(True) self.accept("pauseGameplay", self.setPlayable, [False]) #can pause play else: self.ignoreAll() self.node.setTag("playable", "false") self.setFollowedByCamera(False) self.resetMovement() #reset every movement happening self.accept("resumeGameplay", self.setPlayable, [True]) #can resume play if not NPC #estimate loading time 4 seconds... lol... UPDATE: seems fixed in newer panda versions, inspect def showAllSubnodes(self): self.wtop.show() self.wdown.show() self.wleft.show() self.wright.show() self.stop.show() self.sdown.show() self.sleft.show() self.sright.show() def hideAllSubnodes(self): self.wtop.hide() self.wdown.hide() self.wleft.hide() self.wright.hide() self.stop.hide() self.sdown.hide() self.sleft.hide() self.sright.hide() def setMovement(self, value): if value == True: if self.movtask == 0: self.movtask = taskMgr.add(self.moveCharacter, "moveCharacterTask") if value == False: if self.movtask != 0: if len(self.currentlydown) == 0: taskMgr.remove(self.movtask) self.movtask = 0 ''' reset every movement actually happening ''' def resetMovement(self): if self.leftdown == True: self.face("left") if self.rightdown == True: self.face("right") if self.downdown == True: self.face("down") if self.topdown == True: self.face("top") self.leftdown = False self.rightdown = False self.downdown = False self.topdown = False self.currentlydown = [] self.setMovement(False) def setAnim(self, direction=''): self.hideAllSubnodes() if direction == '': if len(self.currentlydown) > 0: if self.currentlydown[-1] == 'left': self.wleft.show() if self.currentlydown[-1] == 'right': self.wright.show() if self.currentlydown[-1] == 'top': self.wtop.show() if self.currentlydown[-1] == 'down': self.wdown.show() else: if direction == 'left': self.wleft.show() if direction == 'right': self.wright.show() if direction == 'up': self.wtop.show() if direction == 'down': self.wdown.show() #pick request function def spaceDown(self): self.pickRequest = True #movement related functions def arrowLeftDown(self): #track key down self.leftdown = True self.setMovement(True) #show changes to screen self.currentlydown.append("left") self.setAnim() def arrowLeftUp(self): self.leftdown = False self.setMovement(False) #show changes to screen if len(self.currentlydown) == 1: self.hideAllSubnodes() self.sleft.show() if "left" in self.currentlydown: self.currentlydown.remove("left") if len(self.currentlydown) > 0: self.setAnim() def arrowRightDown(self): #track key down self.rightdown = True self.setMovement(True) #show changes to screen self.currentlydown.append("right") self.setAnim() def arrowRightUp(self): self.setMovement(False) self.rightdown = False #show changes to screen if len(self.currentlydown) == 1: self.hideAllSubnodes() self.sright.show() if "right" in self.currentlydown: self.currentlydown.remove("right") if len(self.currentlydown) > 0: self.setAnim() def arrowDownDown(self): #track key down self.downdown = True self.setMovement(True) #show changes to screen self.currentlydown.append("down") self.setAnim() def arrowDownUp(self): self.downdown = False self.setMovement(False) #show changes to screen if len(self.currentlydown) == 1: self.hideAllSubnodes() self.sdown.show() if "down" in self.currentlydown: self.currentlydown.remove("down") if len(self.currentlydown) > 0: self.setAnim() def arrowUpDown(self): #track key down self.topdown = True self.setMovement(True) #show changes to screen self.currentlydown.append("top") self.setAnim() def arrowUpUp(self): self.topdown = False self.setMovement(False) #show changes to screen if len(self.currentlydown) == 1: self.hideAllSubnodes() self.stop.show() if "top" in self.currentlydown: self.currentlydown.remove("top") if len(self.currentlydown) > 0: self.setAnim() def moveCharacter(self, task): dt = globalClock.getDt() if len(self.currentlydown) > 0: if self.currentlydown[-1] == 'left': self.node.setX(self.node.getX() - 1 * dt * self.properties['speed']) if self.currentlydown[-1] == 'right': self.node.setX(self.node.getX() + 1 * dt * self.properties['speed']) if self.currentlydown[-1] == 'top': self.node.setZ(self.node.getZ() + 1 * dt * self.properties['speed']) if self.currentlydown[-1] == 'down': self.node.setZ(self.node.getZ() - 1 * dt * self.properties['speed']) #check collisions if self.cTrav != None: self.cTrav.traverse(render) if self.pickCTrav != None: self.pickCTrav.traverse(render) #entries python list entries = list(self.collisionHandler.getEntries()) pickentries = list(self.pickCollisionHandler.getEntries()) for e in entries[:]: if e.getIntoNodePath().getName() == "characterPickTube": entries.remove(e) for e in pickentries[:]: if e.getIntoNodePath().getName() == "characterTube": pickentries.remove(e) if len(entries) == 0: self.lastpos = self.node.getPos() else: sp = entries[0].getSurfacePoint(self.node) #surface point objectNode = entries[0].getIntoNodePath().getParent( ) #into object node groundNode = entries[0].getIntoNodePath() #into object node if objectNode.hasTag("collideandwalk"): if objectNode.getTag("collideandwalk") != "yes": self.node.setPos(self.lastpos) else: self.node.setPos(self.lastpos) #if node is a real object (not a wall) if objectNode.hasTag("avoidable"): if objectNode.getTag( "avoidable" ) == "true": #see if object is intelligently avoidable if objectNode.hasTag("xscaled") and objectNode.hasTag( "yscaled"): if len( self.currentlydown ) > 0: #at least 1, avoids list index out of range exception if self.currentlydown[ -1] == 'left' or self.currentlydown[ -1] == 'right': #TODO: fix the shiet, not always working bottomObjPos = objectNode.getZ() - ( float(objectNode.getTag("yscaled")) / 2) topObjPos = objectNode.getZ() + ( float(objectNode.getTag("yscaled")) / 2) if self.node.getZ() < bottomObjPos: self.node.setZ(self.node.getZ() - 1 * dt * self.properties['speed']) if self.node.getZ() > topObjPos: self.node.setZ(self.node.getZ() + 1 * dt * self.properties['speed']) pass if self.currentlydown[ -1] == 'top' or self.currentlydown[ -1] == 'down': leftObjPos = objectNode.getX() - ( float(objectNode.getTag("xscaled")) / 2) rightObjPos = objectNode.getX() + ( float(objectNode.getTag("xscaled")) / 2) if self.node.getX() < leftObjPos: self.node.setX(self.node.getX() - 1 * dt * self.properties['speed']) if self.node.getX() > rightObjPos: self.node.setX(self.node.getX() + 1 * dt * self.properties['speed']) self.lastpos = self.node.getPos() for entry in entries: objectNode = entry.getIntoNodePath().getParent() onWalked = objectNode.getTag("onWalked") if len(onWalked) > 0: eval(onWalked) #oh lol, danger detected here evaluatedOnce = False if self.pickRequest == True: for entry in pickentries: objectNode = entry.getIntoNodePath().getParent() onPicked = objectNode.getTag("onPicked") if len(onPicked) > 0 and evaluatedOnce == False: eval(onPicked) #oh lol, danger detected again here evaluatedOnce = True else: if hasattr(objectNode.getPythonTag('gamenode'), 'name'): print "WARNING: picking on this object is not defined: ", objectNode.getPythonTag( 'gamenode').name print "X: ", objectNode.getX() print "Y: ", objectNode.getZ() self.pickRequest = False #resetting request #this is needed for empty pick if self.pickRequest == True: self.pickRequest = False #resetting request return Task.cont def getWorldPos(self): return self.node.getPos(render) def setX(self, x): self.node.setX(x) self.lastpos.setX(x) def setY(self, y): self.node.setZ(y) self.lastpos.setZ(y) #here for polymorph def getTileX(self): return self.parent.getX() #here for polymorph def getTileY(self): return self.parent.getY()
def generateNode(self): self.destroy() self.node = NodePath('gameobjectnode') self.node.setTwoSided(True) self.node.reparentTo(self.parent.node) if self.properties['avoidable'] == True: self.node.setTag("avoidable", 'true') else: self.node.setTag("avoidable", 'false') #setting scripting part self.node.setTag("onWalked", self.onWalked) self.node.setTag("onPicked", self.onPicked) #set unique id self.node.setTag("id", self.properties['id']) tex = loader.loadTexture(resourceManager.getResource(self.properties['url'])+'.png') tex.setWrapV(Texture.WM_clamp) tex.setWrapU(Texture.WM_clamp) #this is true pixel art #change to FTLinear for linear interpolation between pixel colors tex.setMagfilter(Texture.FTNearest) tex.setMinfilter(Texture.FTNearest) xorig = tex.getOrigFileXSize() / self.baseDimension yorig = tex.getOrigFileYSize() / self.baseDimension xscaled = (tex.getOrigFileXSize() / self.baseDimension) * self.properties['scale'] yscaled = (tex.getOrigFileYSize() / self.baseDimension) * self.properties['scale'] self.node.setTag("xscaled", str(xscaled)) self.node.setTag("yscaled", str(yscaled)) cm = CardMaker("tileobject") cm.setFrame(0,xorig,0,yorig) ts = TextureStage('ts') ts.setMode(TextureStage.MDecal) # distinguish between 3d collisions (for objects with an height and sensible self.properties['inclination']) # and 2d collisions for plain sprites if self.properties['walkable'] == 'false': if self.properties['collisionmode'] == "3d": #must handle differently objects which are small and big if xscaled < 1: self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2 - self.properties['offsetwidth'],0,0),LPoint3f(0.5 + xscaled/2 + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight'])) if xscaled >= 1: self.collisionTube = CollisionBox(LPoint3f(0 - self.properties['offsetwidth'],0,0),LPoint3f(xscaled + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight'])) self.collisionNode = CollisionNode('objectSphere') self.collisionNode.addSolid(self.collisionTube) self.collisionNodeNp = self.node.attachNewNode(self.collisionNode) self.collisionNodeNp.setX(self.properties['offsethorizontal']) self.collisionNodeNp.setZ(self.properties['offsetvertical']) self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh']) self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1) if main.editormode: self.collisionNodeNp.show() elif self.properties['collisionmode'] == "2d": #must handle differently objects which are small and big if xscaled < 1: self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2,0,0),LPoint3f(0.5 + xscaled/2,yscaled,0.3)) if xscaled >= 1: self.collisionTube = CollisionBox(LPoint3f(0,0,0),LPoint3f(xscaled,yscaled,0.3)) self.collisionNode = CollisionNode('objectSphere') self.collisionNode.addSolid(self.collisionTube) self.collisionNodeNp = self.node.attachNewNode(self.collisionNode) self.collisionNodeNp.setP(-(270-int(self.properties['inclination']))) self.collisionNodeNp.setX(self.properties['offsethorizontal']) self.collisionNodeNp.setZ(self.properties['offsetvertical']) self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh']) self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1) if main.editormode: self.collisionNodeNp.show() geomnode = NodePath(cm.generate()) if xscaled >= 1: geomnode.setX(0) if xscaled < 1: geomnode.setX(0.5 - xscaled/2) geomnode.setScale(self.properties['scale']) geomnode.setX(geomnode.getX()+self.properties['offsethorizontal']) geomnode.setZ(geomnode.getZ()+self.properties['offsetvertical']) geomnode.setY(-self.properties['elevation']) geomnode.setP(-(360-int(self.properties['inclination']))) geomnode.setTexture(tex) geomnode.setTransparency(TransparencyAttrib.MAlpha) geomnode.reparentTo(self.node)
class ChargeProjectile(DirectObject): dur = 2 delta = .15 flag = False def __init__(self, spawn, taregt, id): self.projectileNode = NodePath('projectile'+str(id)) self.projectileNode.reparentTo(render) self.projectileNode.setPos(spawn,0,-10, 0) self.projectileNode.setScale(1.5) self.projectileModel = Actor("./resources/sphereShot",{"grow":"./resources/sphereShot-grow"}) self.projectileModel.setColorScale(200, 0, 255, 100) self.projectileModel.reparentTo(self.projectileNode) self.projectileNode.setHpr(spawn, 0, 0, 0) dir = render.getRelativeVector(spawn, Vec3(0, 1, 0)) self.vec = dir*-100 cs = CollisionSphere(0, 0, 0, 2.5) cnodepath = self.projectileNode.attachNewNode(CollisionNode('projNode')) cnodepath.node().addSolid(cs) self.collHand = CollisionHandlerEvent() self.collHand.addInPattern('bossProjectileinto'+str(id)) self.collHand.addOutPattern('outof') base.cTrav.addCollider(cnodepath, self.collHand) self.acceptOnce('bossProjectileinto'+str(id), self.hit) self.damage = 15 def moveTask(self, task): if self.flag: return task.done velx = self.vec.x*self.delta vely = self.vec.y*self.delta velz = self.vec.z*self.delta x = self.projectileNode.getX() y = self.projectileNode.getY() z = self.projectileNode.getZ() self.projectileNode.setPos(x+velx, y+vely, z+velz) if task.time < self.dur: return task.cont else: self.flag = True return task.done def hit(self, collEntry): #throw out a custom message for what hit if collEntry.getIntoNodePath().getName() != 'projNode': temp = collEntry.getIntoNodePath().getName() print temp messenger.send(temp, [self.damage]) #remove the impacting projectile collEntry.getFromNodePath().getParent().getParent().removeNode() self.flag = True del self def wait(self, task): if task.time > 2.24: return task.done return task.cont
def generateNode(self): self.destroy() self.node = NodePath('gameobjectnode') self.node.setTwoSided(True) self.node.reparentTo(self.parent.node) if self.properties['avoidable'] == True: self.node.setTag("avoidable", 'true') else: self.node.setTag("avoidable", 'false') #setting scripting part self.node.setTag("onWalked", self.onWalked) self.node.setTag("onPicked", self.onPicked) #set unique id self.node.setTag("id", self.properties['id']) tex = loader.loadTexture(resourceManager.getResource(self.properties['url'])+'.png') tex.setWrapV(Texture.WM_clamp) tex.setWrapU(Texture.WM_clamp) #this is true pixel art #change to FTLinear for linear interpolation between pixel colors tex.setMagfilter(Texture.FTNearest) tex.setMinfilter(Texture.FTNearest) xorig = tex.getOrigFileXSize() / self.baseDimension yorig = tex.getOrigFileYSize() / self.baseDimension xscaled = (tex.getOrigFileXSize() / self.baseDimension) * self.properties['scale'] yscaled = (tex.getOrigFileYSize() / self.baseDimension) * self.properties['scale'] self.node.setTag("xscaled", str(xscaled)) self.node.setTag("yscaled", str(yscaled)) cm = CardMaker("tileobject") cm.setFrame(0,xorig,0,yorig) ts = TextureStage('ts') ts.setMode(TextureStage.MDecal) # distinguish between 3d collisions (for objects with an height and sensible self.properties['inclination']) # and 2d collisions for plain sprites if self.properties['walkable'] == 'false': if self.properties['collisionmode'] == "3d": #must handle differently objects which are small and big if xscaled < 1: self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2 - self.properties['offsetwidth'],0,0),LPoint3f(0.5 + xscaled/2 + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight'])) if xscaled >= 1: self.collisionTube = CollisionBox(LPoint3f(0 - self.properties['offsetwidth'],0,0),LPoint3f(xscaled + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight'])) self.collisionNode = CollisionNode('objectSphere') self.collisionNode.addSolid(self.collisionTube) self.collisionNodeNp = self.node.attachNewNode(self.collisionNode) self.collisionNodeNp.setX(self.properties['offsethorizontal']) self.collisionNodeNp.setZ(self.properties['offsetvertical']) self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh']) self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1) if main.editormode: self.collisionNodeNp.show() elif self.properties['collisionmode'] == "2d": #must handle differently objects which are small and big if xscaled < 1: self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2 - self.properties['offsetwidth'],0,0),LPoint3f(0.5 + xscaled/2 + self.properties['offsetwidth'],yscaled + self.properties['offsetheight'],0.3)) if xscaled >= 1: self.collisionTube = CollisionBox(LPoint3f(0 - self.properties['offsetwidth'],0,0),LPoint3f(xscaled + self.properties['offsetwidth'],yscaled + self.properties['offsetheight'],0.3)) self.collisionNode = CollisionNode('objectSphere') self.collisionNode.addSolid(self.collisionTube) self.collisionNodeNp = self.node.attachNewNode(self.collisionNode) self.collisionNodeNp.setP(-(270-int(self.properties['inclination']))) self.collisionNodeNp.setX(self.properties['offsethorizontal']) self.collisionNodeNp.setZ(self.properties['offsetvertical']) self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh']) self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1) if main.editormode: self.collisionNodeNp.show() geomnode = NodePath(cm.generate()) if geomnode.node().isGeomNode(): vdata = geomnode.node().modifyGeom(0).modifyVertexData() writer = GeomVertexWriter(vdata, 'vertex') reader = GeomVertexReader(vdata, 'vertex') ''' this part apply rotation flattening to the perspective view by modifying directly structure vertices ''' i = 0 #counter while not reader.isAtEnd(): v = reader.getData3f() x = v[0] y = v[1] z = v[2] newx = x newy = y newz = z if self.properties['rotation'] == -90.0: if i == 0: newx = math.fabs(math.cos(math.radians(self.properties['inclination']))) * z newz = 0 ssen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * z sparsen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * ssen spercos = math.fabs(math.cos(math.radians(self.properties['inclination']))) * ssen newy -= spercos newz += sparsen if i == 2: newx += math.fabs(math.cos(math.radians(self.properties['inclination']))) * z newz = 0 ssen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * z sparsen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * ssen spercos = math.fabs(math.cos(math.radians(self.properties['inclination']))) * ssen newy -= spercos newz += sparsen writer.setData3f(newx, newy, newz) i += 1 #increase vertex counter if xscaled >= 1: geomnode.setX(0) if xscaled < 1: geomnode.setX(0.5 - xscaled/2) geomnode.setScale(self.properties['scale']) geomnode.setX(geomnode.getX()+self.properties['offsethorizontal']) geomnode.setZ(geomnode.getZ()+self.properties['offsetvertical']) geomnode.setY(-self.properties['elevation']) geomnode.setP(int(self.properties['inclination'])-360) geomnode.setTexture(tex) geomnode.setTransparency(TransparencyAttrib.MAlpha) geomnode.reparentTo(self.node) self.node.setR(self.properties['rotation'])
class Water(AssetBase): def __init__(self, name, size=10000, resolution=1024): """Arguments: size -- Edge length of the water square. resolution -- Texture size of the rendered reflection buffer. """ # Uncomment to see the output of the refclection buffer. base.bufferViewer.toggleEnable() AssetBase.__init__(self) self.name = name self.cm = CardMaker("water surface") self.cm.setFrame(-0.5 * size, 0.5 * size, -0.5 * size, 0.5 * size) self.cm.setHasUvs(True) self.node = NodePath(self.cm.generate()) self.node.setP(self.node, -90) self.node.flattenLight() self.node.hide(BitMask32.bit(1)) # self.node.setTwoSided(True) self.node.setShaderOff() # size of one texture tile in meters self.tex_size = 100.0 diffuse = TexturePool.loadTexture("textures/water.diffuse.png") diffuse.setWrapU(Texture.WMRepeat) diffuse.setWrapV(Texture.WMRepeat) diffuse.setMinfilter(Texture.FTLinearMipmapLinear) diffuse.setMagfilter(Texture.FTLinearMipmapLinear) self.diffuse_stage = TextureStage("diffuse") self.diffuse_stage.setSort(2) self.node.setTexture(self.diffuse_stage, diffuse) self.node.setTexScale(self.diffuse_stage, size / self.tex_size, size / self.tex_size) # Reflection camera renders to 'buffer' which is projected onto the # water surface. buffer = base.win.makeTextureBuffer("water reflection", resolution, resolution) buffer.setClearColor(Vec4(0, 0, 0, 1)) self.refl_cam = base.makeCamera(buffer) self.refl_cam.reparentTo(self.node) self.refl_cam.node().setCameraMask(BitMask32.bit(1)) self.refl_cam.node().getLens().setFov(base.camLens.getFov()) self.refl_cam.node().getLens().setNearFar(1, 100000) plane = PlaneNode("water culling plane", Plane(Vec3(0, 0, 1), Point3(0, 0, 0))) cfa = CullFaceAttrib.makeReverse() cpa = ClipPlaneAttrib.make(PlaneNode.CEVisible, plane) rs = RenderState.make(cfa, cpa) self.refl_cam.node().setInitialState(rs) reflection = buffer.getTexture() reflection.setMinfilter(Texture.FTLinear) reflection.setMagfilter(Texture.FTLinear) self.refl_stage = TextureStage("reflection") self.refl_stage.setSort(1) self.node.projectTexture(self.refl_stage, reflection, base.cam) self.node.setTexture(self.refl_stage, reflection) # Blend between diffuse and reflection. self.diffuse_stage.setColor(VBase4(1, 1, 1, 0.2)) # opacity of 20% self.diffuse_stage.setCombineRgb( TextureStage.CMInterpolate, TextureStage.CSTexture, TextureStage.COSrcColor, TextureStage.CSPrevious, TextureStage.COSrcColor, TextureStage.CSConstant, TextureStage.COSrcAlpha, ) self.addTask(self.update, name="water update", sort=1, taskChain="world") def update(self, task): """Updates position of the reflection camera and the water plane.""" mc = base.cam.getMat(render) # mf = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)).getReflectionMat() mf = Mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1) self.refl_cam.setMat(mc * mf) self.node.setX(camera.getX(render)) self.node.setY(camera.getY(render)) self.node.setTexOffset(self.diffuse_stage, self.node.getX() / self.tex_size, self.node.getY() / self.tex_size) return task.cont def destroy(self): self.removeAllTasks() self.node.removeNode() self.refl_cam.removeNode()
class Player(object): """ Player is the main actor in the fps game """ FORWARD = Vec3(0,2,0) BACK = Vec3(0,-1,0) LEFT = Vec3(-1,0,0) RIGHT = Vec3(1,0,0) FLYUP = Vec3(0,0,1) FLYDN = Vec3(0,0,-1) STOP = Vec3(0) PORTAL_CYCLE = { 'blue' : 'orange', 'orange' : 'blue', } def __init__(self, base, fps, osd): self.base = base self.fps = fps self.osd = osd self.speed = RUN_SPEED self.walk = self.STOP self.readyToJump = False self.intoPortal = None self.mass = Mass() self.origin = self.fps.level.settings.origin self.bporigin = (999,999,999) self.oporigin = (999,999,999) self.current_target = None self.canPortal = [] self.canSetTarget = True self.selectedCubes = [] self.editorTextureStage = TextureStage('editor') self.editorSelectedTexture = loader.loadTexture('models/tex/selected.png') self.selectingForMulti = False # Init functions self.loadModel() self.makePortals() self.setUpCamera() if self.fps.editor_mode: self.createMouseCollisions() self.speed = self.speed * 5 self.attachEditorControls() self.attachEditorTasks() else: self.createCollisions() self.attachStandardControls() self.attachStandardTasks() def loadModel(self): """ make the nodepath for player """ self.node = NodePath('player') self.node.reparentTo(render) self.node.setPos(*self.origin) self.node.setScale(0.05) self.mass.pos = VBase3(self.node.getX(), self.node.getY(), self.node.getZ()) def makePortals(self): # The BLUE CUBE bpor = loader.loadModel("cube_nocol") bpor.setTag('noportals', '1') bpor.reparentTo(render) bpor.setPos(*self.bporigin) bpor.setScale(0.3,0.02,0.5) # The BLUE CUBE's camera bbuffer = self.base.win.makeTextureBuffer("B Buffer", 512, 512) bbuffer.setSort(-100) bcamera = self.base.makeCamera(bbuffer) bcamera.node().getLens().setAspectRatio(0.3/0.5) bcamera.node().getLens().setFov(15) bcamera.reparentTo(bpor) bcamera.node().setScene(render) # The ORANGE CUBE opor = loader.loadModel("cube_nocol") opor.setTag('noportals', '1') opor.reparentTo(render) opor.setPos(*self.oporigin) opor.setScale(0.3,0.02,0.5) # The ORANGE CUBE's camera obuffer = self.base.win.makeTextureBuffer("O Buffer", 512, 512) obuffer.setSort(-100) ocamera = self.base.makeCamera(obuffer) ocamera.node().getLens().setAspectRatio(0.3/0.5) ocamera.node().getLens().setFov(15) ocamera.reparentTo(opor) ocamera.node().setScene(render) # Assign the textures bpor.setTexture(obuffer.getTexture()) opor.setTexture(bbuffer.getTexture()) # Store the portals and theirs cameras self.bluePortal = bpor self.bluePortal.setHpr(0,90,0) self.orangePortal = opor self.orangePortal.setHpr(0,-90,0) self.bcamera = bcamera self.ocamera = ocamera def setUpCamera(self): """ puts camera at the players node """ pl = self.base.cam.node().getLens() pl.setFov(70) self.base.cam.node().setLens(pl) self.base.camera.reparentTo(self.node) self.base.camLens.setFov(100) if self.fps.editor_mode: self.node.lookAt(self.fps.level.cubes_hash.keys()[0]) def createCollisions(self): self.createPlayerCollisions() self.createMouseCollisions() self.createPortalCollisions() def createPlayerCollisions(self): """ create a collision solid and ray for the player """ cn = CollisionNode('player') cn.setFromCollideMask(COLLISIONMASKS['geometry']) cn.setIntoCollideMask(COLLISIONMASKS['portals'] | COLLISIONMASKS['exit'] | COLLISIONMASKS['lava']) cn.addSolid(CollisionSphere(0,0,0,3)) solid = self.node.attachNewNode(cn) # TODO : find a way to remove that, it's the cause of the little # "push me left" effect we see sometime when exiting a portal self.base.cTrav.addCollider(solid,self.base.pusher) self.base.pusher.addCollider(solid,self.node, self.base.drive.node()) # init players floor collisions ray = CollisionRay() ray.setOrigin(0,0,-.2) ray.setDirection(0,0,-1) cn = CollisionNode('playerRay') cn.setFromCollideMask(COLLISIONMASKS['player']) cn.setIntoCollideMask(BitMask32.allOff()) cn.addSolid(ray) solid = self.node.attachNewNode(cn) self.nodeGroundHandler = CollisionHandlerQueue() self.base.cTrav.addCollider(solid, self.nodeGroundHandler) # init players ceil collisions ray = CollisionRay() ray.setOrigin(0,0,.2) ray.setDirection(0,0,1) cn = CollisionNode('playerUpRay') cn.setFromCollideMask(COLLISIONMASKS['player']) cn.setIntoCollideMask(BitMask32.allOff()) cn.addSolid(ray) solid = self.node.attachNewNode(cn) self.ceilGroundHandler = CollisionHandlerQueue() self.base.cTrav.addCollider(solid, self.ceilGroundHandler) def createMouseCollisions(self): # Fire the portals firingNode = CollisionNode('mouseRay') firingNP = self.base.camera.attachNewNode(firingNode) firingNode.setFromCollideMask(COLLISIONMASKS['geometry']) firingNode.setIntoCollideMask(BitMask32.allOff()) firingRay = CollisionRay() firingRay.setOrigin(0,0,0) firingRay.setDirection(0,1,0) firingNode.addSolid(firingRay) self.firingHandler = CollisionHandlerQueue() self.base.cTrav.addCollider(firingNP, self.firingHandler) def createPortalCollisions(self): # Enter the portals cn = CollisionNode('bluePortal') cn.setFromCollideMask(COLLISIONMASKS['portals']) cn.setIntoCollideMask(BitMask32.allOff()) np = self.bluePortal.attachNewNode(cn) cn.addSolid(CollisionSphere(0,0,0,2)) h = CollisionHandlerEvent() h.addInPattern('%fn-into-%in') h.addOutPattern('%fn-outof-%in') self.base.cTrav.addCollider(np, h) cn = CollisionNode('orangePortal') cn.setFromCollideMask(COLLISIONMASKS['portals']) cn.setIntoCollideMask(BitMask32.allOff()) np = self.orangePortal.attachNewNode(cn) cn.addSolid(CollisionSphere(0,0,0,2)) h = CollisionHandlerEvent() h.addInPattern('%fn-into-%in') h.addOutPattern('%fn-outof-%in') self.base.cTrav.addCollider(np, h) def attachCommonControls(self): self.base.accept( "z" if AZERTY else "w" , self.addWalk,[self.FORWARD]) self.base.accept( "z-up" if AZERTY else "w-up" , self.addWalk,[-self.FORWARD] ) self.base.accept( "s" , self.addWalk,[self.BACK] ) self.base.accept( "s-up" , self.addWalk,[-self.BACK] ) self.base.accept( "q" if AZERTY else "a" , self.addWalk,[self.LEFT]) self.base.accept( "q-up" if AZERTY else "a-up" , self.addWalk,[-self.LEFT] ) self.base.accept( "d" , self.addWalk,[self.RIGHT] ) self.base.accept( "d-up" , self.addWalk,[-self.RIGHT] ) self.base.accept( "r-up" , self.resetPosition ) self.base.accept( "p-up" , self.showPosition ) self.base.accept( "b-up" , self.deBug ) def attachStandardControls(self): self.attachCommonControls() self.base.accept( "space" , self.__setattr__,["readyToJump",True]) self.base.accept( "space-up" , self.__setattr__,["readyToJump",False]) self.base.accept( "c-up" , self.__setattr__,["intoPortal",None] ) self.base.accept( "e-up" , self.erasePortals ) self.base.accept( "mouse1" , self.fireBlue ) self.base.accept( "mouse3" , self.fireOrange ) # Events self.base.accept( "bluePortal-into-player" , self.enterPortal, ["blue"] ) self.base.accept( "orangePortal-into-player" , self.enterPortal, ["orange"] ) self.base.accept( "bluePortal-outof-player" , self.exitPortal, ["blue"] ) self.base.accept( "orangePortal-outof-player" , self.exitPortal, ["orange"] ) self.base.accept( "levelExit-into-player" , self.levelExit) self.base.accept( "lava-into-player" , self.fallIntoLava) def attachStandardTasks(self): taskMgr.add(self.mouseUpdate, 'mouse-task') taskMgr.add(self.moveUpdate, 'move-task') taskMgr.add(self.jumpUpdate, 'jump-task') def attachEditorControls(self): self.attachCommonControls() self.base.accept( "space" , self.__setattr__, ['selectingForMulti', 1]) self.base.accept( "space-up" , self.__setattr__, ['selectingForMulti', 0]) self.base.accept( "shift-space" , self.__setattr__, ['selectingForMulti', 2]) self.base.accept( "shift-space-up" , self.__setattr__, ['selectingForMulti', 0]) self.base.accept( "c-up" , self.clearMultiSelectedCubes) self.base.accept( "mouse1" , self.selectCubeForCopy, [1]) self.base.accept( "wheel_up" , self.selectCubeForChange, [1] ) self.base.accept( "wheel_down" , self.selectCubeForChange, [-1] ) self.base.accept( "mouse3" , self.selectCubeForDelete ) self.base.accept("f11", self.saveLevel) self.base.accept("x", self.selectCubeForRectangle) self.base.accept("shift-x", self.selectCubeForRectangle, [True]) self.base.accept("l", self.addLightHere) self.base.accept("u", self.fps.level.undo, [1]) for i in range(1,10): self.base.accept( "%i-up" % (i,), self.selectCubeForCopy, [i]) for key, vec in [("a" if AZERTY else "q", self.FLYUP),("w" if AZERTY else "z", self.FLYDN)]: self.base.accept(key, self.addWalk, [vec]) self.base.accept(key + "-up", self.addWalk, [-vec]) def attachEditorTasks(self): taskMgr.add(self.mouseUpdate, 'mouse-task') taskMgr.add(self.moveInEditor, 'move-task') def deBug(self): import pdb pdb.set_trace() def showPosition(self): print self.node.getPos() print self.mass def fallIntoLava(self, *args, **kwargs): # TODO : sound and message + little delay self.erasePortals() self.resetPosition() def resetPosition(self, *args, **kwargs): self.node.setHpr(VBase3(0,0,0)) self.mass.pos = VBase3(*self.origin) self.mass.vel = VBase3(0,0,0) self.mass.force = VBase3(0,0,0) self.node.setPos(self.mass.pos) def erasePortals(self): self.bluePortal.setPos(*self.bporigin) self.orangePortal.setPos(*self.oporigin) self.bluePortal.detachNode() self.orangePortal.detachNode() self.intoPortal = None self.canPortal = [] #@oldpostracker def mouseUpdate(self,task): """ this task updates the mouse """ md = self.base.win.getPointer(0) x = md.getX() y = md.getY() if self.base.win.movePointer(0, self.base.win.getXSize()/2, self.base.win.getYSize()/2): self.node.setH(self.node.getH() - (x - self.base.win.getXSize()/2)*0.1) if self.fps.editor_mode: self.node.setP(self.node.getP() - (y - self.base.win.getYSize()/2)*0.1) else: self.base.camera.setP(self.base.camera.getP() - (y - self.base.win.getYSize()/2)*0.1) self.canSetTarget = True self.bcamera.lookAt(self.bluePortal, self.node.getPos(self.orangePortal)) self.ocamera.lookAt(self.orangePortal, self.node.getPos(self.bluePortal)) #self.canPortal = ['blue','orange'] if self.fps.editor_mode: cube, point, normal = self.selectCube() self.osd.updateTargetPosition(cube) if self.selectingForMulti: self.selectCubeForMulti() return task.cont def addWalk(self, vec): self.walk += vec def moveUpdate(self,task): """ this task makes the player move """ # move where the keys set it self.node.setPos(self.node, self.walk*globalClock.getDt()*self.speed) return task.cont #@oldpostracker def jumpUpdate(self,task): """ this task simulates gravity and makes the player jump """ # get the highest Z from the down casting ray highestZ = -100 lowestZ = 100 for i in range(self.nodeGroundHandler.getNumEntries()): entry = self.nodeGroundHandler.getEntry(i) z = entry.getSurfacePoint(render).getZ() if z > highestZ and entry.getIntoNode().getName() in ( "CollisionStuff", "Plane", "Cube" ): highestZ = z for i in range(self.ceilGroundHandler.getNumEntries()): entry = self.ceilGroundHandler.getEntry(i) z = entry.getSurfacePoint(render).getZ() if z < lowestZ and entry.getIntoNode().getName() in ( "CollisionStuff", "Plane", "Cube" ): lowestZ = z # gravity effects and jumps self.mass.simulate(globalClock.getDt()) self.node.setZ(self.mass.pos.getZ()) if highestZ > self.node.getZ()-PLAYER_TO_FLOOR_TOLERANCE: self.mass.zero() self.mass.pos.setZ(highestZ+PLAYER_TO_FLOOR_TOLERANCE) self.node.setZ(highestZ+PLAYER_TO_FLOOR_TOLERANCE) if lowestZ < self.node.getZ()+PLAYER_TO_FLOOR_TOLERANCE: self.mass.zero() self.mass.pos.setZ(lowestZ-PLAYER_TO_FLOOR_TOLERANCE) self.node.setZ(lowestZ-PLAYER_TO_FLOOR_TOLERANCE) if self.readyToJump and self.node.getZ() < highestZ + PLAYER_TO_FLOOR_TOLERANCE_FOR_REJUMP: self.mass.jump(JUMP_FORCE) return task.cont def firePortal(self, name, node): def hasTagValue(node, tag, value): if node.getTag(tag) == value: return True for pnum in range(node.getNumParents()): return hasTagValue(node.getParent(pnum), tag, value) return False self.firingHandler.sortEntries() if self.firingHandler.getNumEntries() > 0: closest = self.firingHandler.getEntry(0) if hasTagValue(closest.getIntoNode(), 'noportals', '1'): return point = closest.getSurfacePoint(render) normal = closest.getSurfaceNormal(render) node.setPos(point) node.lookAt(point + normal) node.reparentTo(render) dest = self.PORTAL_CYCLE[name] if dest not in self.canPortal: self.canPortal.append(dest) def fireBlue(self, *arg, **kwargs): self.firePortal("blue", self.bluePortal) def fireOrange(self, *arg, **kwargs): self.firePortal("orange", self.orangePortal) #@oldpostracker def enterPortal(self, color, collision): if self.intoPortal is None and color in self.canPortal: self.intoPortal = color portal = {"orange": self.bluePortal, "blue": self.orangePortal}.get(color) otherportal = {"orange": self.orangePortal, "blue": self.bluePortal}.get(color) # Handle horizontal portals : if portal.getH() == 0: self.node.setP(0) self.node.setR(0) elif otherportal.getH() == 0: self.node.setH(portal.getH()) self.node.setP(0) self.node.setR(0) else: # New HPR is relative to 'new' portal but it the 'same' value # as the old HPR seen from the 'other' portal oldh_fromportal = self.node.getH(otherportal) self.node.setHpr(Vec3(0,0,0)) self.node.setH(portal, 180-oldh_fromportal) newh_fromportal = self.node.getH(portal) self.node.setPos(portal, self.walk * 10.) self.mass.pos = self.node.getPos() # Make half a turn (only if we straffing without walking) if self.walk.getY() == 0 and self.walk.getX() != 0: self.node.setH(self.node, 180) self.node.setPos(self.node, self.walk * 10) #@oldpostracker def exitPortal(self, color, collision): # When you entered the blue portal, you have to exit the orange one if self.intoPortal != color: self.intoPortal = None def levelExit(self, event): if self.fps.level.settings.next_level: self.fps.level.loadlevel(self.fps.level.settings.next_level) self.origin = self.fps.level.settings.origin self.resetPosition() self.erasePortals() self.walk = self.STOP else: print "You won !" sys.exit(0) # EDITOR MODE def selectCube(self): self.firingHandler.sortEntries() if self.firingHandler.getNumEntries() > 0: closest = self.firingHandler.getEntry(0) return closest.getIntoNodePath().getParent().getParent(), closest.getSurfacePoint(render), closest.getSurfaceNormal(render) # render/cube.egg/-PandaNode/-GeomNode else: return None, None, None def clearMultiSelectedCubes(self): for c in self.selectedCubes: c.clearTexture(self.editorTextureStage) self.selectedCubes = [] def selectCubeForMulti(self): cube, point, normal = self.selectCube() if cube: if self.selectingForMulti == 1: cube.setTexture(self.editorTextureStage, self.editorSelectedTexture) if cube not in self.selectedCubes: self.selectedCubes.append(cube) elif cube in self.selectedCubes: cube.clearTexture(self.editorTextureStage) self.selectedCubes.remove(cube) def selectCubeForCopy(self, qty = 1): cube, point, normal = self.selectCube() if not (cube and point and normal): return if self.selectedCubes: for c in self.selectedCubes: self.fps.level.copyCube(c, normal, qty) self.clearMultiSelectedCubes() else: self.fps.level.copyCube(cube, normal, qty) def selectCubeForDelete(self): cube, point, normal = self.selectCube() if not (cube and point and normal): return if self.selectedCubes: for c in self.selectedCubes: self.fps.level.deleteCube(c) self.clearMultiSelectedCubes() else: self.fps.level.deleteCube(cube) def selectCubeForChange(self, step = 1): cube, point, normal = self.selectCube() if not (cube and point and normal): return if self.selectedCubes: for c in self.selectedCubes: self.fps.level.changeCube(c, step) else: self.fps.level.changeCube(cube, step) def selectCubeForRectangle(self, makeRoom = False): cube, point, normal = self.selectCube() if makeRoom: self.fps.level.createRoom(cube, self.node) # creates a room from the selected cube to the player(camera) position else: self.fps.level.createRectangle(cube, self.node) # creates a rectangle from the selected cube to the player(camera) position def saveLevel(self): camerapos = [self.node.getX(), self.node.getY(), self.node.getZ()] levelname = self.fps.levelname self.fps.level.savelevel(levelname, camerapos) def addLightHere(self): camerapos = [self.node.getX(), self.node.getY(), self.node.getZ()] self.fps.level.addLightHere(camerapos) def moveInEditor(self,task): self.node.setPos(self.node, self.walk*globalClock.getDt()*self.speed) self.osd.updatePosition(self.node) return task.cont
class Ship: def __init__(self, game): self.game = game self.shipPoint = NodePath(PandaNode("shipFloaterPoint")) self.shipPoint.reparentTo(render) self.x_pos = 0 self.z_pos = 0 self.x_speed = 0 self.z_speed = 0 self.x_pid = PID(3.0, 5.0, 1.0) self.z_pid = PID(3.0, 5.0, 1.0) self.model = Actor("data/ship.egg") self.model.setPos(0, 0, 0) self.model.setHpr(0, 0, 0) self.normal_speed = 3.5 self.low_speed = 2 self.speed = self.normal_speed self.cool_down = 0.1 self.last_shoot = 0 self.keyMap = { "up": 0, "down": 0, "left": 0, "right": 0, "brake": 0, "attack": 0, } # This list will stored fired bullets. self.bullets = [] self.game.accept("mouse1", self.setKey, ["attack", 1]) self.game.accept("mouse1-up", self.setKey, ["attack", 0]) self.game.accept("shift-mouse1", self.setKey, ["attack", 1]) self.game.accept("shift-mouse1-up", self.setKey, ["attack", 0]) self.game.accept("x", self.setKey, ["attack", 1]) self.game.accept("x-up", self.setKey, ["attack", 0]) self.game.accept("c", self.setKey, ["brake", 1]) self.game.accept("c-up", self.setKey, ["brake", 0]) self.game.accept("arrow_up", self.setKey, ["up", 1]) self.game.accept("arrow_up-up", self.setKey, ["up", 0]) self.game.accept("arrow_down", self.setKey, ["down", 1]) self.game.accept("arrow_down-up", self.setKey, ["down", 0]) self.game.accept("arrow_left", self.setKey, ["left", 1]) self.game.accept("arrow_left-up", self.setKey, ["left", 0]) self.game.accept("arrow_right", self.setKey, ["right", 1]) self.game.accept("arrow_right-up", self.setKey, ["right", 0]) def setKey(self, key, value): self.keyMap[key] = value def draw(self): self.model.reparentTo(render) self.p = ParticleEffect() self.p.loadConfig(Filename('data/particles/fireish.ptf')) self.p.setR(180) self.p.setScale(0.25) # Sets particles to birth relative to the teapot, but to render at # toplevel self.p.start(self.model) self.p.setPos(0.000, 0.000, 0.000) def update(self, task): dt = globalClock.getDt() if self.model: # Movement if self.keyMap["brake"]: self.speed = self.low_speed else: self.speed = self.normal_speed if self.game.ship_control_type == 0: if self.keyMap["up"]: self.model.setZ(self.model, self.speed * dt) elif self.keyMap["down"]: self.model.setZ(self.model, -self.speed * dt) if self.keyMap["left"]: self.model.setX(self.model, -self.speed * dt) elif self.keyMap["right"]: self.model.setX(self.model, self.speed * dt) elif self.game.ship_control_type == 1: self.x_pos = self.shipPoint.getX() self.z_pos = self.shipPoint.getZ() self.x_pid.setPoint(self.x_pos) self.z_pid.setPoint(self.z_pos) pid_x = self.x_pid.update(self.model.getX()) pid_z = self.z_pid.update(self.model.getZ()) self.x_speed = pid_x self.z_speed = pid_z self.x_speed = min(self.speed, self.x_speed) self.x_speed = max(-self.speed, self.x_speed) self.z_speed = min(self.speed, self.z_speed) self.z_speed = max(-self.speed, self.z_speed) self.model.setX(self.model, self.x_speed * dt) self.model.setZ(self.model, self.z_speed * dt) self.model.setR(self.x_speed) # Shoot if self.keyMap["attack"]: current_shoot_time = task.time if current_shoot_time - self.last_shoot >= self.cool_down: self.last_shoot = current_shoot_time self.bullet = Bullet(self) return task.cont
class Tower(GameObject): def __init__(self, player, name, x, y, income): global tower_count self.my_id = tower_count tower_count += 1 self.player = player self.name = name self.x = x self.y = y self.state = "normal" self.build_progress = 0.0 self.build_speed = 1.0 self.gold_inc = 1.0 if base.player == self.player: base.ecn_manager.gold_inc += self.gold_inc base.vis_manager.update() self.model_list = [ "models/farmhouse_grey.egg", "models/farmhouse_red.egg", "models/farmhouse_green.egg" ] self.model_list = [ "models/tower_grey.egg", "models/tower_red.egg", "models/tower_green.egg" ] self.model = loader.loadModel(self.model_list[self.player]) # if self.player == 0: # self.model = loader.loadModel("models/tower_grey.egg") # elif self.player == 1: # self.model = loader.loadModel("models/tower_red.egg") # elif self.player == 2: # self.model = loader.loadModel("models/tower_green.egg") self.node_path = NodePath("tower" + str(self.my_id) + "_node_path") self.model.reparentTo(self.node_path) self.node_path.setPos(x, y, 0) self.node_path.setTag("player", str(player)) self.node_path.setScale(tower_scale, tower_scale, tower_scale) self.node_path.setColor(1, 1, 1, 0.1) self.node_col = self.node_path.attachNewNode( CollisionNode("tower" + str(self.my_id) + "_c_node")) self.node_col.setScale((2, 2, 1)) self.node_col.setPos(0, 0, 0) self.node_col.node().addSolid(CollisionSphere(0, 0, 0, 1)) self.node_col.setTag("type", "tower") base.cTrav.addCollider(self.node_col, base.col_manager.col_handler) #self.node_col.show() self.node_path.setTag("id", str(self.my_id)) self.tower_fight_col = self.node_path.attachNewNode( CollisionNode("tower" + str(self.my_id) + "_batcol_node")) self.tower_fight_col.setScale((2, 2, 0.5)) self.tower_fight_col.setPos(0, 0, 0) self.tower_fight_col.node().addSolid(CollisionSphere(0, 0, 0, 1)) self.tower_fight_col.setColor(1, 0, 0, 0.1) self.tower_fight_col.setTag("player", str(player)) self.tower_fight_col.setTag("state", "normal") #self.tower_fight_col.show() base.cTrav.addCollider(self.tower_fight_col, base.col_manager.col_handler) self.selection_ring = self.selection_ring_create(size=1.5) self.selection_ring.reparentTo(self.node_path) self.selection_ring.hide() self.node_path.reparentTo(render) def capture_check(self): has_guard = False for a in base.armies: if a.player == self.player and (a.state == "normal" or a.state == "battle"): if base.calculator.dist_to_point(self.get_x(), self.get_y(), a.get_x(), a.get_y()) < 80: has_guard = True if has_guard == True: return False else: return True def change_owner(self, new_owner): if self.player == base.player: base.ecn_manager.gold_inc -= self.gold_inc elif new_owner == base.player: base.ecn_manager.gold_inc += self.gold_inc base.vis_manager.update() self.model.remove() self.model = loader.loadModel(self.model_list[new_owner]) self.node_path.setTag("player", str(new_owner)) self.tower_fight_col.setTag("player", str(new_owner)) self.player = new_owner self.model.reparentTo(self.node_path) def build_cancel(self): if self.player == base.player: base.ecn_manager.gold += base.ecn_manager.cost_army_gold base.vis_manager.update() if base.single_player == False and base.client == False: base.net_manager.server_messager("build_cancel", [self.my_id]) taskMgr.remove("task_tower" + str(self.my_id) + "_build") self.build_progress = 0.0 if base.vis_manager.statbar.focus == self: base.vis_manager.statbar.show_tower(self.my_id) def build_start(self): if self.player == base.player: base.ecn_manager.gold -= base.ecn_manager.cost_army_gold base.vis_manager.update() print "Started Building" if base.single_player == False and base.client == False: base.net_manager.server_messager("build_start", [self.my_id, self.player, "army"]) self.build_progress = self.build_speed taskMgr.add(self.task_build, "task_tower" + str(self.my_id) + "_build") if base.vis_manager.statbar.focus == self: base.vis_manager.statbar.show_tower(self.my_id) def build_start_request(self): base.net_manager.client_messager("build_start_request", [self.my_id, self.player, "army"]) def build_cancel_request(self): base.net_manager.client_messager("build_cancel_request", [self.my_id]) def task_build(self, task): if self.build_progress < 100.00: self.build_progress += self.build_speed if base.vis_manager.statbar.focus == self: base.vis_manager.statbar.bar_build.set_value( self.build_progress) return Task.again else: self.build_progress = 0.0 if base.vis_manager.statbar.focus == self: base.vis_manager.statbar.show_tower(self.my_id) if base.single_player == False and base.client == False: base.net_manager.server_messager( "build_complete", [self.my_id, self.player, "army"]) if base.client == False: self.create_counter() return Task.done def create_counter(self): new_army = Army(self.player, "Infantry", self.node_path.getX(), self.node_path.getY(), 1) base.armies.append(new_army) new_army.state = "new" new_army.army_fight_col.setTag("state", "new") intvl_exit = new_army.node_path.posInterval( 2, Point3(self.x, self.y - 24, 0), startPos=Point3(self.x, self.y, 0)) def army_ready(): new_army.state = "normal" new_army.army_fight_col.setTag("state", "normal") func_armyready = Func(army_ready) sq_army_move = Sequence(intvl_exit, func_armyready) sq_army_move.start()
class Battle(GameObject): def __init__(self, counters, start=-1): global battle_count self.combatants = counters self.my_id = battle_count self.turn = 0 self.chance_range = 100 self.chance_success = 80 self.col_scale_orig = 2.0 self.col_scale = self.col_scale_orig self.col_scale_inc = 0.4 battle_count += 1 if start != -1: self.turn = start self.combatants[start].turn_start() coords = [(self.combatants[0].get_x(), self.combatants[0].get_y()), (self.combatants[1].get_x(), self.combatants[1].get_y())] self.x, self.y = TCalc.midpoint(coords) self.node_path = NodePath("battle" + str(self.my_id) + "_node_path") self.node_path.setPos(self.x, self.y, 0) self.node_path.setTag("id", str(self.my_id)) self.node_path.setTag("type", "battle") self.node_path.reparentTo(render) self.bat_col = self.node_path.attachNewNode( CollisionNode("battle" + str(self.my_id) + "_c_node")) self.bat_col.setScale((self.col_scale, self.col_scale, 0.2)) self.bat_col.setPos(0, 0, 0) self.bat_col.node().addSolid(CollisionSphere(0, 0, 0, 10)) self.bat_col.setTag("type", "battle") self.bat_col.show() self.battle_speed = 1.0 for a in self.combatants: #a.turn_start() a.stop() a.state = "battle" a.army_fight_col.setTag("state", "battle") a.battle = self.my_id if base.client == False: taskMgr.add(self.battle_init_rolls, "battle" + str(self.my_id) + "_task_start") def recenter(self): new_x = 0.0 new_y = 0.0 x_list = [] y_list = [] counter = 0 try: for a in self.combatants: if a.state != "dead": x_list.append(a.node_path.getX()) y_list.append(a.node_path.getY()) counter += 1 new_x += a.node_path.getX() new_y += a.node_path.getY() new_x /= len(x_list) new_y /= len(y_list) self.node_path.setPos(new_x, new_y, 0) except: pass def shrink(self): if len(self.combatants) <= 10: self.col_scale -= self.col_scale_orig * self.col_scale_inc self.bat_col.setScale((self.col_scale, self.col_scale, 0.2)) def battle_init_rolls(self, task): init_rolls = [] highest_roll = -1 counter = 0 leader = 0 for a in self.combatants: roll = random.randint(0, self.chance_range) + a.stat_init print counter, "rolled", roll init_rolls.append(roll) if roll > highest_roll: highest_roll = roll leader = counter counter += 1 self.turn = leader print leader, "wins!" self.combatants[self.turn].turn_start() a1 = self.combatants[0] a2 = self.combatants[1] if base.client == False: if base.single_player == False: base.net_manager.server_messager("battle_start", [ a1.my_id, a1.node_path.getX(), a1.node_path.getY(), a2.my_id, a2.node_path.getX(), a2.node_path.getY(), self.turn ]) taskMgr.doMethodLater(1, self.battle_loop, "battle" + str(self.my_id) + "_task_loop") self.get_odds() return task.done def get_odds(self): side1 = [] side2 = [] counter = 0 for a in self.combatants: if a.player == 1 and a.state != "dead": side1.append(a) counter += 1 elif a.player == 2 and a.state != "dead": side2.append(a) counter += 1 self.odds = (100 / counter) * len(side1) if base.col_manager.selected_node == self.node_path: base.vis_manager.statbar.refresh_battle(self.odds) def target_recheck(self): army = self.combatants[self.turn] target_id = random.randint(0, len(self.combatants) - 1) target = self.combatants[target_id] while target == army or target.player == army.player or target.state == "dead": target_id = random.randint(0, len(self.combatants) - 1) target = self.combatants[target_id] print "recheck target - aquired", target_id return army, target, target_id def turn_change(self, new_turn): self.combatants[self.turn].turn_end() self.combatants[new_turn].turn_start() self.turn = new_turn def battle_loop(self, task): towerBuff = 0 battle_end = False army, target, target_id = self.target_recheck() task.delayTime = self.battle_speed + army.stat_delay roll = random.randint(0, self.chance_range) + army.stat_hit #Make towers pown arse for t in base.towers: if t.player == army.player: distanceToTower = base.calculator.dist_to_point( army.get_x(), army.get_y(), t.get_x(), t.get_y()) if distanceToTower < 80: towerBuff = random.randint(0, 40) roll += towerBuff if roll >= self.chance_success: roll = random.randint(0, self.chance_range) + target.stat_block if roll >= self.chance_success: result = "block" else: result = "hit" target.state = "dead" battle_end = True for a in self.combatants: if a.player != army.player and a.state != "dead": battle_end = False else: result = "fail" if base.client == False and base.single_player == False: randomness = 80 army.battle_shuffle( self.node_path.getX() + random.randint(0, randomness) - randomness / 2, self.node_path.getY() + random.randint(0, randomness) - randomness / 2) if base.single_player == False: base.net_manager.server_messager( "battle_clash", [self.my_id, army.my_id, target.my_id, result, towerBuff]) self.clash(army, target, result, towerBuff) army.turn_end() last_turn = self.turn if battle_end: if base.single_player == False: base.net_manager.server_messager("battle_end", [self.my_id]) self.end() return task.done else: self.get_odds() if self.turn < len(self.combatants) - 1: self.turn += 1 else: self.turn = 0 while self.combatants[self.turn].state == "dead": if self.turn < len(self.combatants) - 1: self.turn += 1 else: self.turn = 0 if base.single_player == False: base.net_manager.server_messager("battle_turn", [self.my_id, self.turn]) self.combatants[self.turn].turn_start() return task.again def end(self): if base.col_manager.selected_node == self.node_path: base.vis_manager.statbar.reset_statbar() for a in self.combatants: a.turn_end() if a.state != "dead": a.state = "normal" a.battle = -1 a.army_fight_col.setTag("state", "normal") self.destroy() def clash(self, a1, a2, result, buff): if buff != 0: buffText = "^+" + str(buff) TimVisuals.BattleText(self.node_path, buffText, self.x, self.y + 10, (1, 1, 0, 1)) if result == "block": TimVisuals.BattleText(self.node_path, "BLOCK!", self.x, self.y, a2.colour) elif result == "hit": TimVisuals.BattleText(self.node_path, "HIT AND KILL!", self.x, self.y, a1.colour) a2.state = "dead" a2.die() else: TimVisuals.BattleText(self.node_path, "Attack Failed!", self.x, self.y, a1.colour) def add_army(self, army): army.stop() army.state = "battle" army.army_fight_col.setTag("state", "battle") army.battle = self.my_id self.combatants.append(army) if len(self.combatants) <= 10: self.col_scale += self.col_scale_orig * self.col_scale_inc self.bat_col.setScale((self.col_scale, self.col_scale, 0.2)) self.get_odds() self.recenter() def destroy(self): self.node_path.removeNode()
class Army(GameObject): def __init__(self, player, name, x, y, soldiers, general=None): global army_count self.my_id = army_count army_count += 1 print "ARMY ID IS", self.my_id self.name = name self.x = x self.y = y self.target_x = x self.target_y = y self.scale = counter_scale self.range = 50.0 self.selected = False self.general = general self.soldiers = soldiers self.state = "normal" self.speed = 25.0 self.battle = -1 self.stat_init = 0.0 self.stat_hit = 0.0 self.stat_block = 0.0 self.stat_delay = 0.0 self.player = player if self.player == 0: self.colour = (0.5, 0.5, 0.5, 1) self.model = loader.loadModel("models/infantry_counter_grey.egg") if self.player == 1: self.colour = (1, 0, 0, 1) self.model = loader.loadModel("models/infantry_counter_red.egg") elif self.player == 2: self.colour = (0, 1, 0, 1) self.model = loader.loadModel("models/infantry_counter_green.egg") self.node_path = NodePath("army" + str(self.my_id) + "_node_path") self.model.reparentTo(self.node_path) self.node_path.setPos(x, y, 0) self.node_path.setTag("player", str(player)) self.node_path.setScale(self.scale, self.scale, self.scale) self.node_col = self.node_path.attachNewNode( CollisionNode("army" + str(self.my_id) + "_c_node")) self.node_col.setScale((1, 1, 0.5)) self.node_col.setPos(0, 0, 0) self.node_col.node().addSolid(CollisionSphere(0, 0, 0, 1)) self.node_col.setTag("type", "army") base.cTrav.addCollider(self.node_col, base.col_manager.col_handler) #self.node_col.show() self.node_path.setTag("id", str(self.my_id)) self.army_fight_col = self.node_path.attachNewNode( CollisionNode("army" + str(self.my_id) + "_batcol_node")) self.army_fight_col.setScale((2, 2, 0.5)) self.army_fight_col.setPos(0, 0, 0) self.army_fight_col.node().addSolid(CollisionSphere(0, 0, 0, 1)) self.army_fight_col.setColor(1, 0, 0, 0.1) self.army_fight_col.setTag("player", str(player)) self.army_fight_col.setTag("state", "normal") self.army_fight_col.setTag("type", "army") base.cTrav.addCollider(self.army_fight_col, base.col_manager.col_handler) #self.army_fight_col.show() self.selection_ring = self.selection_ring_create(size=1.2) self.selection_ring.reparentTo(self.node_path) self.selection_ring.hide() self.node_path.reparentTo(render) def turn_start(self): rate = 0.5 army_scl_up = self.model.scaleInterval(rate, Point3(1.5, 1.5, 1.5)) army_scl_down = self.model.scaleInterval(rate, Point3(1, 1, 1)) self.sq_army_bat = Sequence(army_scl_up, army_scl_down) self.sq_army_bat.loop() def turn_end(self): try: self.sq_army_bat.finish() except: print "no sequence to end" def die(self): if base.single_player == False and base.client == False: base.net_manager.server_messager("army_kill", [self.my_id]) self.state = "dead" self.army_fight_col.removeNode() self.node_col.removeNode() rate = 4 intvl_shrink = self.model.scaleInterval(rate, Point3(0, 0, 0)) func_destroy = Func(self.destroy) self.sq_die = Sequence(intvl_shrink, func_destroy) self.sq_die.start() base.battles[self.battle].recenter() base.battles[self.battle].shrink() if self.selected: i = base.col_manager.selecteds.index(self) del base.col_manager.selecteds[i] def stop(self): try: self.sq_army_move.pause() except: print "already stopped" def move_to_point(self, tx, ty): self.target_x = tx self.target_y = ty dist = float( TCalc.dist_to_point(self.node_path.getX(), self.node_path.getY(), tx, ty)) print dist #time = dist/speed #print dist/speed #print time*speed,dist try: self.sq_army_move.pause() self.intvl_army_move = None except: print "no sequence" if dist > 1: self.intvl_army_move = self.node_path.posInterval( dist / self.speed, Point3(self.target_x, self.target_y, 0), startPos=Point3(self.node_path.getX(), self.node_path.getY(), 0)) self.sq_army_move = Sequence(self.intvl_army_move) self.sq_army_move.start() else: try: self.sq_army_move.finish() except: print "no sequence" def set_target(self, sender, tx, ty): if self.state == "normal": if base.single_player == False: base.net_manager.army_move(self.my_id, tx, ty) else: self.move_to_point(tx, ty) def battle_shuffle(self, tx, ty): if base.single_player == False: base.net_manager.army_move(self.my_id, tx, ty) else: self.move_to_point(tx, ty)
class Main(ShowBase): def __init__(self): ShowBase.__init__(self) self.key = { "left": 0, "right": 0, "forward": 0, "backward": 0, "cam_left": 0, "cam_right": 0, "cam_down": 0, "cam_up": 0, "up": 0, "down": 0 } ##################### # # Simply testing procedural cave generation # ##################### self.start = PlatformSeg(LVector3(0, 0, 0)) self.start.generateAllParts(render) self.lostWood = LostWood( LVector3(self.start.pos.x + 750, self.start.parts[0].pos.y + self.start.parts[0].wid, self.start.pos.z)) self.lostWood.generateAllParts(render) self.cave = Cave( LVector3(self.lostWood.pos.x + 1100, self.lostWood.parts[6].pos.y + self.lostWood.parts[6].wid, self.lostWood.pos.z)) self.cave.generateAllParts(render) self.end = End( LVector3( self.cave.thirdRoomParts[8].pos.x - 200, self.cave.thirdRoomParts[8].pos.y + self.cave.thirdRoomParts[8].wid, self.cave.thirdRoomParts[8].pos.z)) self.end.generate(render) #################### # # Setting light so that we could see the definition in the walls # #################### render.setShaderAuto() self.dlight = DirectionalLight('dlight') self.dlight.setColor(LVector4(0.3, 0.1, 0.7, 1)) dlnp = render.attachNewNode(self.dlight) dlnp.setHpr(90, 20, 0) render.setLight(dlnp) self.alight = render.attachNewNode(AmbientLight("Ambient")) self.alight.node().setColor(LVector4(0.5, 0.5, 1, .1)) render.setLight(self.alight) base.disableMouse() self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) base.camera.reparentTo(self.floater) base.camera.setPos(0, -20, 500) base.camera.setP(-50) self.bindKeys() def setKey(self, key, value): self.key[key] = value def bindKeys(self): self.accept("escape", sys.exit) self.accept("a", self.setKey, ["left", True]) self.accept("a-up", self.setKey, ["left", False]) self.accept("d", self.setKey, ["right", True]) self.accept("d-up", self.setKey, ["right", False]) self.accept("w", self.setKey, ["forward", True]) self.accept("w-up", self.setKey, ["forward", False]) self.accept("s", self.setKey, ["backward", True]) self.accept("s-up", self.setKey, ["backward", False]) self.accept("space", self.setKey, ["down", True]) self.accept("space-up", self.setKey, ["down", False]) self.accept("shift", self.setKey, ["up", True]) self.accept("shift-up", self.setKey, ["up", False]) self.accept("arrow_up", self.setKey, ["cam_up", True]) self.accept("arrow_up-up", self.setKey, ["cam_up", False]) self.accept("arrow_down", self.setKey, ["cam_down", True]) self.accept("arrow_down-up", self.setKey, ["cam_down", False]) self.accept("arrow_left", self.setKey, ["cam_left", True]) self.accept("arrow_left-up", self.setKey, ["cam_left", False]) self.accept("arrow_right", self.setKey, ["cam_right", True]) self.accept("arrow_right-up", self.setKey, ["cam_right", False]) taskMgr.add(self.update, "update") def update(self, task): delta = globalClock.getDt() WALKSPEED = 300 SPEED = 100 if self.key["left"]: self.floater.setX(self.floater.getX() - WALKSPEED * delta) if self.key["right"]: self.floater.setX(self.floater.getX() + WALKSPEED * delta) if self.key["forward"]: self.floater.setY(self.floater.getY() + WALKSPEED * delta) if self.key["backward"]: self.floater.setY(self.floater.getY() - WALKSPEED * delta) if self.key["up"]: self.floater.setZ(self.floater.getZ() + WALKSPEED * delta) if self.key["down"]: self.floater.setZ(self.floater.getZ() - WALKSPEED * delta) if self.key["cam_left"]: base.camera.setH(base.camera.getH() + SPEED * delta) if self.key["cam_right"]: base.camera.setH(base.camera.getH() - SPEED * delta) if self.key["cam_up"]: base.camera.setP(base.camera.getP() + SPEED * delta) if self.key["cam_down"]: base.camera.setP(base.camera.getP() - SPEED * delta) ###################### # # SIMPLE OCCLUSION FOR START AREA # ###################### for p in self.start.parts: if p.type == 'IceCube': if math.fabs( (math.sqrt((p.model.getX() * p.model.getX()) + (p.model.getY() * p.model.getY())) - math.sqrt( (self.floater.getX() * self.floater.getX()) + (self.floater.getY() * self.floater.getY())))) <= 400: p.show() #Ice cube movement p.bob(delta) else: p.hide() if p.type == 'Prism': if p.type == 'Prism': if math.fabs( (math.sqrt((p.pos.x * p.pos.x) + (p.pos.y * p.pos.y)) - math.sqrt( (self.floater.getX() * self.floater.getX()) + (self.floater.getY() * self.floater.getY())) )) <= 1000: p.show() else: p.hide() ###################### # # SIMPLE OCCLUSION FOR CAVE PARTS # ###################### for p in self.cave.parts: if p.type == 'Prism': if math.fabs( (math.sqrt((p.pos.x * p.pos.x) + (p.pos.y * p.pos.y)) - math.sqrt((self.floater.getX() * self.floater.getX()) + (self.floater.getY() * self.floater.getY())) )) <= 2200: p.show() else: p.hide() if p.type == 'IceCube': if math.fabs( (math.sqrt((p.model.getX() * p.model.getX()) + (p.model.getY() * p.model.getY())) - math.sqrt((self.floater.getX() * self.floater.getX()) + (self.floater.getY() * self.floater.getY())) )) <= 1250: p.show() #Ice cube movement self.cave.moveIceCubes(delta / 25) for p in self.cave.iceCubesThirdRoom: p.bob(delta / 25) for p in self.cave.iceCubesSecondRoom: p.bob(delta / 25) self.cave.bigCube.bob(delta / 25) for p in self.start.iceCubes: p.bob(delta) else: p.hide() return task.cont
class KVProjectile(DirectObject): #Property stuff creaTime = time.clock() dur = 1 vec = 0 delta = .5 prevtime = 0 flag = False #defining the thing fired by whatever gun we have def __init__(self, camera, look, id): #nodepath of the projectile, give it a trajectory self.projectileNode = NodePath('projectile'+str(id)) self.projectileNode.reparentTo(render) #by passing the camera node form the camMov object, all projectiles are spawned 5 units in front of the camera self.projectileNode.setHpr(look, 0, 0, 0) self.projectileNode.setPos(camera,0,3, 3) #fix z position to line up with gun self.projectileNode.setScale(.1) self.projectileModel = loader.loadModel("./resources/beam.egg") self.projectileModel.reparentTo(self.projectileNode) #must calculate unit vector based on direction dir = render.getRelativeVector(look, Vec3(0, 1, 0)) #speed up or slow down projectiles here dir = dir*5 self.vec = dir #base.cTrav = CollisionTraverser() cs = CollisionSphere(0, 0, 0, 2.5) cnodepath = self.projectileNode.attachNewNode(CollisionNode('projNode')) cnodepath.node().addSolid(cs) self.collHand = CollisionHandlerEvent() self.collHand.addInPattern('into'+str(id)) self.collHand.addOutPattern('outof') #cTrav has the distinction of global colider handler base.cTrav.addCollider(cnodepath, self.collHand) self.acceptOnce('into'+str(id), self.hit) #deal with colliding or special effects here. #wanted projectiles to be short lived #so i will make them delete themselves after impact or time expired #writing a task that will rek the projectiles at the end of time self.damage = 5 def moveTask(self, task): #curtime = time.clock() #self.delta = curtime-self.prevtime if self.flag: return task.done velx = self.vec.x*self.delta vely = self.vec.y*self.delta velz = self.vec.z*self.delta x = self.projectileNode.getX() y = self.projectileNode.getY() z = self.projectileNode.getZ() self.projectileNode.setPos(x+velx, y+vely, z+velz) #prevtime = time.clock() if task.time < self.dur: return task.cont else: self.flag = True return task.done def hit(self, collEntry): #throw out a custom message for what hit if collEntry.getIntoNodePath().getName() != 'projNode': temp = collEntry.getIntoNodePath().getName() messenger.send(temp, [self.damage]) #remove the impacting projectile collEntry.getFromNodePath().getParent().getParent().removeNode() self.flag = True del self
class CogdoFlyingCameraManager: def __init__(self, cam, parent, player, level): self._toon = player.toon self._camera = cam self._parent = parent self._player = player self._level = level self._enabled = False def enable(self): if self._enabled: return self._toon.detachCamera() self._prevToonY = 0.0 levelBounds = self._level.getBounds() l = Globals.Camera.LevelBoundsFactor self._bounds = ((levelBounds[0][0] * l[0], levelBounds[0][1] * l[0]), (levelBounds[1][0] * l[1], levelBounds[1][1] * l[1]), (levelBounds[2][0] * l[2], levelBounds[2][1] * l[2])) self._lookAtZ = self._toon.getHeight( ) + Globals.Camera.LookAtToonHeightOffset self._camParent = NodePath('CamParent') self._camParent.reparentTo(self._parent) self._camParent.setPos(self._toon, 0, 0, 0) self._camParent.setHpr(180, Globals.Camera.Angle, 0) self._camera.reparentTo(self._camParent) self._camera.setPos(0, Globals.Camera.Distance, 0) self._camera.lookAt(self._toon, 0, 0, self._lookAtZ) self._cameraLookAtNP = NodePath('CameraLookAt') self._cameraLookAtNP.reparentTo(self._camera.getParent()) self._cameraLookAtNP.setPosHpr(self._camera.getPos(), self._camera.getHpr()) self._levelBounds = self._level.getBounds() self._enabled = True self._frozen = False self._initCollisions() def _initCollisions(self): self._camCollRay = CollisionRay() camCollNode = CollisionNode('CameraToonRay') camCollNode.addSolid(self._camCollRay) camCollNode.setFromCollideMask(OTPGlobals.WallBitmask | OTPGlobals.CameraBitmask | ToontownGlobals.FloorEventBitmask | ToontownGlobals.CeilingBitmask) camCollNode.setIntoCollideMask(0) self._camCollNP = self._camera.attachNewNode(camCollNode) self._camCollNP.show() self._collOffset = Vec3(0, 0, 0.5) self._collHandler = CollisionHandlerQueue() self._collTrav = CollisionTraverser() self._collTrav.addCollider(self._camCollNP, self._collHandler) self._betweenCamAndToon = {} self._transNP = NodePath('trans') self._transNP.reparentTo(render) self._transNP.setTransparency(True) self._transNP.setAlphaScale(Globals.Camera.AlphaBetweenToon) self._transNP.setBin('fixed', 10000) def _destroyCollisions(self): self._collTrav.removeCollider(self._camCollNP) self._camCollNP.removeNode() del self._camCollNP del self._camCollRay del self._collHandler del self._collOffset del self._betweenCamAndToon self._transNP.removeNode() del self._transNP def freeze(self): self._frozen = True def unfreeze(self): self._frozen = False def disable(self): if not self._enabled: return self._destroyCollisions() self._camera.wrtReparentTo(render) self._cameraLookAtNP.removeNode() del self._cameraLookAtNP self._camParent.removeNode() del self._camParent del self._prevToonY del self._lookAtZ del self._bounds del self._frozen self._enabled = False def update(self, dt=0.0): self._updateCam(dt) self._updateCollisions() def _updateCam(self, dt): toonPos = self._toon.getPos() camPos = self._camParent.getPos() x = camPos[0] z = camPos[2] toonWorldX = self._toon.getX(render) maxX = Globals.Camera.MaxSpinX toonWorldX = clamp(toonWorldX, -1.0 * maxX, maxX) spinAngle = Globals.Camera.MaxSpinAngle * toonWorldX * toonWorldX / ( maxX * maxX) newH = 180.0 + spinAngle self._camParent.setH(newH) spinAngle = spinAngle * (pi / 180.0) distBehindToon = Globals.Camera.SpinRadius * cos(spinAngle) distToRightOfToon = Globals.Camera.SpinRadius * sin(spinAngle) d = self._camParent.getX() - clamp(toonPos[0], *self._bounds[0]) if abs(d) > Globals.Camera.LeewayX: if d > Globals.Camera.LeewayX: x = toonPos[0] + Globals.Camera.LeewayX else: x = toonPos[0] - Globals.Camera.LeewayX x = self._toon.getX(render) + distToRightOfToon boundToonZ = min(toonPos[2], self._bounds[2][1]) d = z - boundToonZ if d > Globals.Camera.MinLeewayZ: if self._player.velocity[2] >= 0 and toonPos[ 1] != self._prevToonY or self._player.velocity[2] > 0: z = boundToonZ + d * INVERSE_E**(dt * Globals.Camera.CatchUpRateZ) elif d > Globals.Camera.MaxLeewayZ: z = boundToonZ + Globals.Camera.MaxLeewayZ elif d < -Globals.Camera.MinLeewayZ: z = boundToonZ - Globals.Camera.MinLeewayZ if self._frozen: y = camPos[1] else: y = self._toon.getY(render) - distBehindToon self._camParent.setPos(x, smooth(camPos[1], y), smooth(camPos[2], z)) if toonPos[2] < self._bounds[2][1]: h = self._cameraLookAtNP.getH() if d >= Globals.Camera.MinLeewayZ: self._cameraLookAtNP.lookAt(self._toon, 0, 0, self._lookAtZ) elif d <= -Globals.Camera.MinLeewayZ: self._cameraLookAtNP.lookAt(self._camParent, 0, 0, self._lookAtZ) self._cameraLookAtNP.setHpr(h, self._cameraLookAtNP.getP(), 0) self._camera.setHpr( smooth(self._camera.getHpr(), self._cameraLookAtNP.getHpr())) self._prevToonY = toonPos[1] def _updateCollisions(self): pos = self._toon.getPos(self._camera) + self._collOffset self._camCollRay.setOrigin(pos) direction = -Vec3(pos) direction.normalize() self._camCollRay.setDirection(direction) self._collTrav.traverse(render) nodesInBetween = {} if self._collHandler.getNumEntries() > 0: self._collHandler.sortEntries() for entry in self._collHandler.getEntries(): name = entry.getIntoNode().getName() if name.find('col_') >= 0: np = entry.getIntoNodePath().getParent() if np not in nodesInBetween: nodesInBetween[np] = np.getParent() for np in nodesInBetween.keys(): if np in self._betweenCamAndToon: del self._betweenCamAndToon[np] else: np.setTransparency(True) np.wrtReparentTo(self._transNP) if np.getName().find('lightFixture') >= 0: if not np.find('**/*floor_mesh').isEmpty(): np.find('**/*floor_mesh').hide() elif np.getName().find('platform') >= 0: if not np.find('**/*Floor').isEmpty(): np.find('**/*Floor').hide() for np, parent in self._betweenCamAndToon.items(): np.wrtReparentTo(parent) np.setTransparency(False) if np.getName().find('lightFixture') >= 0: if not np.find('**/*floor_mesh').isEmpty(): np.find('**/*floor_mesh').show() elif np.getName().find('platform') >= 0: if not np.find('**/*Floor').isEmpty(): np.find('**/*Floor').show() self._betweenCamAndToon = nodesInBetween
class Player(DirectObject): def __init__(self, _main): self.main = _main # Stats self.moveSpeed = 8 self.inventory = [] self.maxCarryWeight = 20.0 #kg ? self.currentInventoryWeight = 0.0 # Inventory GUI self.inventoryGui = Inventory() self.inventoryGui.hide() self.inventoryActive = False self.craftInventory = CraftInventory() self.craftInventory.hide() # enable movements through the level self.keyMap = {"left":0, "right":0, "forward":0, "backward":0} self.player = NodePath("Player")#loader.loadModel("smiley") self.player.setPos(149.032, 329.324, 11.3384) self.player.setH(180) self.player.reparentTo(render) self.accept("w", self.setKey, ["forward",1]) self.accept("w-up", self.setKey, ["forward",0]) self.accept("a", self.setKey, ["left",1]) self.accept("a-up", self.setKey, ["left",0]) self.accept("s", self.setKey, ["backward",1]) self.accept("s-up", self.setKey, ["backward",0]) self.accept("d", self.setKey, ["right",1]) self.accept("d-up", self.setKey, ["right",0]) self.accept("mouse1", self.handleLeftMouse) self.accept("i", self.toggleInventory) self.accept("c", self.toggleCraftInventory) # screen sizes self.winXhalf = base.win.getXSize() / 2 self.winYhalf = base.win.getYSize() / 2 self.mouseSpeedX = 0.1 self.mouseSpeedY = 0.1 camera.setH(180) camera.reparentTo(self.player) camera.setZ(self.player, 2) base.camLens.setFov(75) base.camLens.setNear(0.8) # Mouse controls self.mouseNode = CollisionNode('mouseRay') self.mouseNodeNP = camera.attachNewNode(self.mouseNode) self.mouseNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.mouseRay = CollisionRay() self.mouseNode.addSolid(self.mouseRay) self.mouseRayHandler = CollisionHandlerQueue() # Collision Traverser self.traverser = CollisionTraverser("Player Traverser") base.cTrav = self.traverser self.traverser.addCollider(self.mouseNodeNP, self.mouseRayHandler) def run(self): taskMgr.add(self.move, "moveTask", priority=-4) def pause(self): taskMgr.remove("moveTask") def setKey(self, key, value): self.keyMap[key] = value def move(self, task): if not base.mouseWatcherNode.hasMouse(): return task.cont pointer = base.win.getPointer(0) mouseX = pointer.getX() mouseY = pointer.getY() if base.win.movePointer(0, self.winXhalf, self.winYhalf): # calculate the looking up/down of the camera. # NOTE: for first person shooter, the camera here can be replaced # with a controlable joint of the player model p = camera.getP() - (mouseY - self.winYhalf) * self.mouseSpeedY if p <-80: p = -80 elif p > 90: p = 90 camera.setP(p) # rotate the player's heading according to the mouse x-axis movement h = self.player.getH() - (mouseX - self.winXhalf) * self.mouseSpeedX if h <-360: h = 360 elif h > 360: h = -360 self.player.setH(h) # basic movement of the player if self.keyMap["left"] != 0: self.player.setX(self.player, self.moveSpeed * globalClock.getDt()) if self.keyMap["right"] != 0: self.player.setX(self.player, -self.moveSpeed * globalClock.getDt()) if self.keyMap["forward"] != 0: self.player.setY(self.player, -self.moveSpeed * globalClock.getDt()) if self.keyMap["backward"] != 0: self.player.setY(self.player, self.moveSpeed * globalClock.getDt()) # keep the player on the ground elevation = self.main.t.terrain.getElevation(self.player.getX(), self.player.getY()) self.player.setZ(elevation*self.main.t.zScale) return task.cont def toggleInventory(self): if self.inventoryActive: self.inventoryGui.hide() self.inventoryActive = False self.run() else: self.inventoryGui.show() self.inventoryActive = True self.pause() def toggleCraftInventory(self): if self.inventoryActive: self.craftInventory.hide() self.inventoryActive = False self.run() else: self.craftInventory.updateList(self.inventory) self.craftInventory.show() self.inventoryActive = True self.pause() def handleLeftMouse(self): # Do the mining if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.mouseRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) self.traverser.traverse(render) # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue. if self.mouseRayHandler.getNumEntries() > 0: # This is so we get the closest object. self.mouseRayHandler.sortEntries() pickedObj = self.mouseRayHandler.getEntry(0).getIntoNodePath() # Range check if (self.player.getPos() - pickedObj.getPos(render)).length() <= 3.0: self.mine(pickedObj) else: print "You are to far, move closer!" def mine(self, _nodeNP): self.nodeNP = _nodeNP # get the object class for node in self.main.nodeGen.currentNodes: if self.main.nodeGen.currentNodes[node] in self.inventory: print "new Loot:", self.main.nodeGen.currentNodes[node].giveLoot() self.inventory.append(self.main.nodeGen.currentNodes[node]) if self.main.nodeGen.currentNodes[node].lootLeft == 0: self.main.nodeGen.currentNodes[node].removeModel() break break # if mining node else: if self.main.nodeGen.currentNodes[node].model and self.main.nodeGen.currentNodes[node].model.getPos() == self.nodeNP.getPos(render): #self.main.nodeGen.currentNodes[node].removeModel() self.inventory.append(self.main.nodeGen.currentNodes[node]) self.currentInventoryWeight += self.main.nodeGen.currentNodes[node].weight self.inventoryGui.updateList(self.inventory) print "You received:", self.main.nodeGen.currentNodes[node].giveLoot(), self.main.nodeGen.currentNodes[node].giveType(), "Ores" print "Inventory:", self.inventory print "Current Weight:", self.currentInventoryWeight break print self.player.getPos()
class Vehicle(ActorNode): def __init__(self, parent=None): ''' Create a new Vehicle node. Physics should be initialized before any instances of Vehicle are created. arguments: parent -- A PandaNode for the vehicle to attach to. Default is None, in which case the Vehicle should be added to the scene graph via NodePath.attachNewNode(). ''' ActorNode.__init__(self, 'VehiclePhysics') base.physicsMgr.attachPhysicalNode(self) self.getPhysicsObject().setMass(MASS) if parent: self.myPath = parent.attachNewNode(self) else: self.myPath = NodePath(self) # Load vehicle model and place in the transparent bin. vehicleModel = loader.loadModel(MODEL_PATH) hull = vehicleModel.find('**/Hull') hull.setBin('transparent', 30) pwnsEnclosure = vehicleModel.find('**/Pwns_Enclosure') pwnsEnclosure.setBin('transparent', 30) self.myPath.setPos(0, 0, -0.0) selectable = self.myPath.attachNewNode(SelectableNode('vehicle sel')) vehicleModel.reparentTo(selectable) # ==== Initialize Physics ==== # thrusterForceNode = ForceNode('ThrusterForce') self.myPath.attachNewNode(thrusterForceNode) self.linearForce = LinearVectorForce(0, 0, 0) self.linearForce.setMassDependent(1) self.angularForce = AngularVectorForce(0, 0, 0) thrusterForceNode.addForce(self.linearForce) thrusterForceNode.addForce(self.angularForce) self.getPhysical(0).addLinearForce(self.linearForce) self.getPhysical(0).addAngularForce(self.angularForce) self.previousXY = (self.myPath.getX(), self.myPath.getY()) self.tm = ThrusterManager() # Add self.updatePhysics to the task manager and run this task as # frequently as possible. self.updatePhysicsTask = taskMgr.add(self.updatePhysics, 'UpdatePhysics') # ==== Initialize Cameras ==== # lens = PerspectiveLens() lens.setNearFar(0.05, 100.0) #Use either FocalLength or Fov. Fov ~40 is about what actual forward cameras are #lens.setFocalLength(0.8) lens.setFov(70, 70) camera = Camera("Forward_left", lens).getPath() camera.reparentTo(vehicleModel.find('**/Forward_Camera')) camera.setX(camera.getX() - 0.1) # Forward cameras 20cm apart camera.setY( camera.getY() + 0.05) # Move in front of torpedo tubes to avoid abstruction camera.setHpr(0, 0, 0) camera = Camera("Forward_right", lens).getPath() camera.reparentTo(vehicleModel.find('**/Forward_Camera')) camera.setX(camera.getX() + 0.1) # Forward cameras 20cm apart camera.setY( camera.getY() + 0.05) # Move in front of torpedo tubes to avoid abstruction camera.setHpr(0, 0, 0) lens = PerspectiveLens() lens.setNearFar(0.05, 100.0) lens.setFocalLength(0.8) camera = Camera("Downward", lens).getPath() camera.reparentTo(vehicleModel.find('**/Downward_Camera')) camera.setHpr(0, -90, 0) #Layout link (to access hydrophone information) self.layout = None #Hydrophone variables self.start_time = time() self.last_hydro_update = time() def setLayout(self, layout): #Add a link to the layout to allow for referencing other objects #This is necessary for the hydrophone addition self.layout = layout def getDepth(self): ''' Returns the depth of the vehicle, in meters. ''' return -0.15 - self.myPath.getZ() def getHeading(self): ''' Returns the heading of the vehicle, in clockwise degrees. ''' # Panda uses counter-clockwise degrees, with the range (-180, 180]. heading = self.myPath.getH() if heading < 0: return -heading elif heading > 0: return 360 - heading else: return 0 def updatePhysics(self, task): ''' Use the motor PWM values calculated by the controller to apply forces to the simulated vehicle. This runs at every frame, so it needs to complete quickly. ''' outputs = shm.kalman.get() self.tm.update(outputs) passive_wrench = vehicle.passive_forces(outputs, self.tm) passive_forces, passive_torques = passive_wrench[:3], \ passive_wrench[3:] # Get motor thrusts thrusts = np.array(self.tm.get_thrusts()) # Add passive forces and torques to that produced by thrusters, # converting them to sub space first. force = self.tm.total_thrust(thrusts) + \ self.tm.orientation.conjugate() * passive_forces torque = self.tm.total_torque(thrusts) + \ self.tm.orientation.conjugate() * passive_torques # Finally apply forces and torques to the model # we also need to account for panda3d's strange coordinate system # (x and y are flipped and z points up (instead of down)) self.linearForce.setVector(force_subspace[1], \ force_subspace[0], \ -force_subspace[2]) # We're supposed to use axis angle here, but I'm being sneaky # and using the torque vector directly, i.e. non normalized axis angle # with the hopes that this LRotationf constructor will figure it out self.angularForce.setQuat(\ LRotationf(LVector3f(torque_subspace[1], \ torque_subspace[0], \ -torque_subspace[2]), 1)) # Update shared variables for controller outputs.heading = self.getHeading() outputs.pitch = self.myPath.getP() outputs.roll = self.myPath.getR() # This velocity is in world space # We need to put it into THRUST CONVENTION SPACE # which we assume kalman outputs in... velocity = self.getPhysicsObject().getVelocity() # Bring the velocity into THRUST CONVENTION SPACE # Don't forget to account for panda's coordinate system velocity = self.tm.heading_quat.conjugate() * \ np.array((velocity.getY(), velocity.getX(), -velocity.getZ())) outputs.velx = velocity[0] outputs.vely = velocity[1] outputs.depth_rate = velocity[2] outputs.depth = self.getDepth() outputs.north = self.myPath.getY() outputs.east = self.myPath.getX() dX = self.myPath.getX() - self.previousXY[0] dY = self.myPath.getY() - self.previousXY[1] # Forward and sway are in THRUST CONVENTION SPACE # don't forget to account for panda's coordinate system dF, dS, dD = self.tm.heading_quat.conjugate() * np.array((dY, dX, 0.0)) outputs.forward += dF outputs.sway += dS # Output some quaternions, accounting for Panda's coordinate system outputs.q0, outputs.q2, outputs.q1, outputs.q3 = self.myPath.getQuat() outputs.q3 *= -1.0 shm.kalman.set(outputs) svHeadingInt.set(self.getHeading()) svDepth.set(self.getDepth()) #XXX: Approximate altitude assuming that the pool is 12 feet deep svAltitude.set(3.6 - self.getDepth()) svDvlDmgNorth.set(self.myPath.getY()) svDvlDmgEast.set(self.myPath.getX()) self.previousXY = (self.myPath.getX(), self.myPath.getY()) #update self.output_hydro_data() return Task.cont def output_hydro_data(self): #Update simulated hydrophone values pingers = [] #Get all pingers from the layout for element in self.layout.elements: if element.getTypeName() == "Pinger": pingers.append(element) HYDRO_TICK_PERIOD = 1 if time() - self.last_hydro_update > HYDRO_TICK_PERIOD: dt = time() - self.last_hydro_update self.last_hydro_update = time() if shm.hydrophones_settings.dsp_mode.get() == 1: #Search mode #Incr search count shm.hydrophones_results.search_count.set( shm.hydrophones_results.search_count.get() + 1) #Generate proper "hydrophone bins" marks sb = 0 for p in pingers: f = p.pinger_frequency dc = (f - (shm.hydrophones_settings.searchCenter.get() - shm.hydrophones_settings.searchDelta.get()) ) / shm.hydrophones_settings.searchStep.get() + 0.5 sb |= 1 << int(dc) shm.hydrophones_results.search_bins.set(sb) else: #Track Mode #Incr ping count shm.hydrophones_results.ping_count.set( shm.hydrophones_results.ping_count.get() + 1) #Determine which pinger we are actively tracking (within 0.7khz of target) targetp = None for p in pingers: if abs(shm.hydrophones_settings.trackFrequency.get() - p.pinger_frequency) < 700: targetp = p if targetp is not None: shm.hydrophones_results.intensity.set( int(shm.hydrophones_settings.trackMagThresh.get() + 1e4 * random())) shm.hydrophones_results.ping_time.set(int(dt * 1000)) pp = targetp.path.getPos() vv = vector.Vector(self.myPath.getY(), self.myPath.getX()) pv = vector.Vector(pp.getY(), pp.getX()) #heading dv = pv - vv ang = vector.GetAuvAngle(dv) hdiff = helpers.heading_diff(self.getHeading(), ang) shm.hydrophones_results.heading.set(hdiff) #elevation dh = self.myPath.getZ() - pp.getZ() dist = vector.Length(dv) elev = math.degrees(math.atan2(dist, dh)) elev = min(elev, 90) shm.hydrophones_results.elevation.set(elev) #phase calculations dy = self.myPath.getY() - pp.getY() dx = self.myPath.getX() - pp.getX() yang = math.degrees(math.atan2(dist, dy)) xang = math.degrees(math.atan2(dist, dx)) shm.hydrophones_results.phaseX.set((90.0 - xang) / 90.0) shm.hydrophones_results.phaseY.set((90.0 - yang) / 90.0) shm.hydrophones_results.phaseZ.set((90.0 - elev) / 90.0) else: shm.hydrophones_results.heading.set(0) shm.hydrophones_results.elevation.set(0) shm.hydrophones_results.intensity.set(0) shm.hydrophones_results.ping_time.set(0) shm.hydrophones_results.uptime.set(int(time() - self.start_time)) def __del__(self): ''' Remove update tasks from the panda task manager. ''' taskMgr.remove(self.updatePhysicsTask) ActorNode.__del__(self)
class Maleficium(ShowBase): def __init__(self): compressedTextures = ConfigVariableString('compressed-textures','1') # Compresses Textures on load (increases loadtime / framerate) ShowBase.__init__(self) ## Debug Values (True/False) self.fpsMeter = True debug.checkDebugSettings(self) self.KeyBindings() ## Load World world.load('prisonCrater') ## Add Player to World self.playerBox = NodePath('player') self.player = Actor("data/models/hm.bam", {"run":"data/models/hm-run.bam", "idle":"data/models/hm.bam"}) self.player.reparentTo(self.playerBox) self.player.setScale(.01) self.playerBox.reparentTo(render) self.isMoving = False ## Create Camera base.disableMouse() self.cameratarget = self.render.attachNewNode('Camera Target') base.camera.setPos(self.playerBox.getX(),self.playerBox.getY()+20,self.playerBox.getZ()+5) self.cameratarget.setPos(self.playerBox.getX(),self.playerBox.getY(),self.playerBox.getZ()+6) self.radius = 10 self.XYAngle = .028 self.ZAngle = .01 ## Set Up Ground Collisions ## Player Collision base.cTrav = CollisionTraverser() self.ColHandler = CollisionHandlerFloor() self.colGroundRay = CollisionNode('colGroundRay') self.colGroundRay.addSolid(CollisionRay(0,0,2,0,0,-1)) self.playerCol = self.playerBox.attachNewNode(self.colGroundRay) base.cTrav.addCollider(self.playerCol,self.ColHandler) self.ColHandler.addCollider(self.playerCol,self.playerBox) ## Add main Game Loop to taskmanager taskMgr.add(self.gameLoop,'mainLoop') ### Input Structure; Coded by Darren Kent (Modeled after Roaming-Ralph by Ryan Myers) def KeyBindings(self): ## Setup Map self.startRightClick = True self.keyMap = { "forward":0, "backward":0, "turn_left":0, "turn_right":0, "strafe_left":0, "strafe_right":0, "cam_up":0, "cam_down":0, "cam_right":0, "cam_left":0, "zoom_in":0, "zoom_out":0, "right_click":0, "wheel_zoom_in":0, "wheel_zoom_out":0, } ## Accept Keys self.accept('escape',sys.exit) self.accept('w', self.setKey, ['forward',1]) self.accept('w-up', self.setKey, ['forward',0]) self.accept('s', self.setKey, ['backward',1]) self.accept('s-up', self.setKey, ['backward',0]) self.accept('a', self.setKey, ['turn_left',1]) self.accept('a-up', self.setKey, ['turn_left',0]) self.accept('d', self.setKey, ['turn_right',1]) self.accept('d-up', self.setKey, ['turn_right',0]) self.accept('q', self.setKey, ['strafe_left',1]) self.accept('q-up', self.setKey, ['strafe_left',0]) self.accept('e', self.setKey, ['strafe_right',1]) self.accept('e-up', self.setKey, ['strafe_right',0]) self.accept('arrow_up', self.setKey, ['cam_down',1]) self.accept('arrow_up-up', self.setKey, ['cam_down',0]) self.accept('arrow_down', self.setKey, ['cam_up',1]) self.accept('arrow_down-up', self.setKey, ['cam_up',0]) self.accept('arrow_right', self.setKey, ['cam_right',1]) self.accept('arrow_right-up', self.setKey, ['cam_right',0]) self.accept('arrow_left', self.setKey, ['cam_left',1]) self.accept('arrow_left-up', self.setKey, ['cam_left',0]) self.accept('[', self.setKey, ['zoom_in',1]) self.accept('[-up', self.setKey, ['zoom_in',0]) self.accept(']', self.setKey, ['zoom_out',1]) self.accept(']-up', self.setKey, ['zoom_out',0]) ## Accept Mouse self.accept('mouse3',self.setKey, ['right_click',1]) self.accept('mouse3-up',self.setKey, ['right_click',0]) self.accept('wheel_up',self.setKey, ['wheel_zoom_in',1]) self.accept('wheel_down',self.setKey, ['wheel_zoom_out',1]) ### Set Key Presses; Coded by Darren Kent (Modeled after Roaming-Ralph by Ryan Myers) def setKey(self,key,value): self.keyMap[key] = value ### Main Game Loop; Coded by Darren Kent def gameLoop(self,task): ## Keyboard Camera Controls if (self.keyMap["cam_left"]!=0): self.XYAngle += .002 if (self.keyMap["cam_right"]!=0): self.XYAngle -= .002 if (self.keyMap["cam_up"] != 0): if self.ZAngle <= .045: self.ZAngle += .001 if (self.keyMap["cam_down"] != 0): if self.ZAngle >= .002: self.ZAngle -= .001 if (self.keyMap["zoom_in"] != 0): if self.radius >= 4: self.radius -= 1 self.setRadius = self.radius if (self.keyMap["zoom_out"] != 0): if self.radius <= 40: self.radius += 1 self.setRadius = self.radius ## Mouse Camera Controls if (self.keyMap["right_click"]!=0): if self.startRightClick == True: self.startRightClick = False self.tempMouseX = base.mouseWatcherNode.getMouseX() self.tempMouseY = base.mouseWatcherNode.getMouseY() self.tempXAngle = self.XYAngle self.tempZAngle = self.ZAngle self.tempPlayerH = self.playerBox.getH() elif self.startRightClick == False: Ztemp = self.tempZAngle + (base.mouseWatcherNode.getMouseY() - self.tempMouseY) / 20 self.XYAngle = self.tempXAngle - (base.mouseWatcherNode.getMouseX() - self.tempMouseX) / 20 if Ztemp >= .045: Ztemp = .045 if Ztemp <= 0.002: Ztemp = 0.002 self.ZAngle = Ztemp else: self.startRightClick = True if (self.keyMap["wheel_zoom_in"] != 0): if self.radius >= 7: self.radius -= 3 self.setRadius = self.radius if (self.keyMap["wheel_zoom_out"] != 0): if self.radius <= 38: self.radius += 2 self.setRadius = self.radius self.setKey("wheel_zoom_out",0) self.setKey("wheel_zoom_in", 0) ## Reposition Camera x = self.cameratarget.getX() + self.radius * math.sin(math.degrees(self.ZAngle)) * math.cos(math.degrees(self.XYAngle)) y = self.cameratarget.getY() + self.radius * math.sin(math.degrees(self.ZAngle)) * math.sin(math.degrees(self.XYAngle)) z = self.cameratarget.getZ() + self.radius * math.cos(math.degrees(self.ZAngle)) base.camera.setPos(x,y,z) base.camera.lookAt(self.cameratarget) self.cameratarget.setPos(self.playerBox.getX(),self.playerBox.getY(),self.playerBox.getZ()+6) ## Keyboard Movement Controls if (self.keyMap["turn_left"]!=0): self.playerBox.setH(self.playerBox.getH() + 200 * globalClock.getDt()) if (self.keyMap["turn_right"]!=0): self.playerBox.setH(self.playerBox.getH() - 200 * globalClock.getDt()) if (self.keyMap["strafe_left"]!=0): self.playerBox.setX(self.playerBox, +20 * globalClock.getDt()) if (self.keyMap["strafe_right"]!=0): self.playerBox.setX(self.playerBox, -20 * globalClock.getDt()) if (self.keyMap["forward"]!=0): self.playerBox.setY(self.playerBox, -25 * globalClock.getDt()) if (self.keyMap["backward"] != 0): self.playerBox.setY(self.playerBox, +15 * globalClock.getDt()) if (self.keyMap["forward"]!=0): if self.isMoving == False: self.player.setPlayRate(2.5,'run') self.player.loop('run') self.isMoving = True else: if self.isMoving: self.player.setPlayRate(1,'idle') self.player.loop('idle') self.isMoving = False ## Check Collisions return task.cont
class Ship: def __init__(self, game): self.game = game self.shipPoint = NodePath(PandaNode("shipFloaterPoint")) self.shipPoint.reparentTo(render) self.x_pos = 0 self.z_pos = 0 self.x_speed = 0 self.z_speed = 0 self.x_pid = PID(3.0, 5.0, 1.0) self.z_pid = PID(3.0, 5.0, 1.0) self.model = Actor("data/ship.egg") self.model.setPos(0, 0, 0) self.model.setHpr(0, 0, 0) self.normal_speed = 3.5 self.low_speed = 2 self.speed = self.normal_speed self.cool_down = 0.1 self.last_shoot = 0 self.keyMap = { "up": 0, "down": 0, "left": 0, "right": 0, "brake": 0, "attack": 0, } # This list will stored fired bullets. self.bullets = [] self.game.accept("mouse1", self.setKey, ["attack", 1]) self.game.accept("mouse1-up", self.setKey, ["attack", 0]) self.game.accept("shift-mouse1", self.setKey, ["attack", 1]) self.game.accept("shift-mouse1-up", self.setKey, ["attack", 0]) self.game.accept("x", self.setKey, ["attack", 1]) self.game.accept("x-up", self.setKey, ["attack", 0]) self.game.accept("c", self.setKey, ["brake", 1]) self.game.accept("c-up", self.setKey, ["brake", 0]) self.game.accept("arrow_up", self.setKey, ["up", 1]) self.game.accept("arrow_up-up", self.setKey, ["up", 0]) self.game.accept("arrow_down", self.setKey, ["down", 1]) self.game.accept("arrow_down-up", self.setKey, ["down", 0]) self.game.accept("arrow_left", self.setKey, ["left", 1]) self.game.accept("arrow_left-up", self.setKey, ["left", 0]) self.game.accept("arrow_right", self.setKey, ["right", 1]) self.game.accept("arrow_right-up", self.setKey, ["right", 0]) def setKey(self, key, value): self.keyMap[key] = value def draw(self): self.model.reparentTo(render) def update(self, task): dt = globalClock.getDt() # Movement if self.keyMap["brake"]: self.speed = self.low_speed else: self.speed = self.normal_speed if self.game.ship_control_type == 0: if self.keyMap["up"]: self.model.setZ(self.model, self.speed * dt) elif self.keyMap["down"]: self.model.setZ(self.model, -self.speed * dt) if self.keyMap["left"]: self.model.setX(self.model, -self.speed * dt) elif self.keyMap["right"]: self.model.setX(self.model, self.speed * dt) elif self.game.ship_control_type == 1: self.x_pos = self.shipPoint.getX() self.z_pos = self.shipPoint.getZ() self.x_pid.setPoint(self.x_pos) self.z_pid.setPoint(self.z_pos) pid_x = self.x_pid.update(self.model.getX()) pid_z = self.z_pid.update(self.model.getZ()) self.x_speed_ = pid_x self.z_speed = pid_z self.x_speed_ = min(self.speed, self.x_speed_) self.x_speed_ = max(-self.speed, self.x_speed_) self.z_speed = min(self.speed, self.z_speed) self.z_speed = max(-self.speed, self.z_speed) self.model.setX(self.model, self.x_speed_ * dt) self.model.setZ(self.model, self.z_speed * dt) # Shoot if self.keyMap["attack"]: current_shoot_time = task.time if current_shoot_time - self.last_shoot >= self.cool_down: self.last_shoot = current_shoot_time self.bullet = Bullet(self) return task.cont
class Army(GameObject): def __init__(self,player,name,x,y,soldiers,general=None): global army_count self.my_id = army_count army_count += 1 print "ARMY ID IS",self.my_id self.name = name self.x = x self.y = y self.target_x = x self.target_y = y self.scale = counter_scale self.range = 50.0 self.selected = False self.general = general self.soldiers = soldiers self.state = "normal" self.speed = 25.0 self.battle = -1 self.stat_init = 0.0 self.stat_hit = 0.0 self.stat_block = 0.0 self.stat_delay = 0.0 self.player = player if self.player == 0: self.colour = (0.5,0.5,0.5,1) self.model = loader.loadModel("models/infantry_counter_grey.egg") if self.player == 1: self.colour = (1,0,0,1) self.model = loader.loadModel("models/infantry_counter_red.egg") elif self.player == 2: self.colour = (0,1,0,1) self.model = loader.loadModel("models/infantry_counter_green.egg") self.node_path = NodePath("army"+str(self.my_id)+"_node_path") self.model.reparentTo(self.node_path) self.node_path.setPos(x,y,0) self.node_path.setTag("player",str(player)) self.node_path.setScale(self.scale,self.scale,self.scale) self.node_col = self.node_path.attachNewNode(CollisionNode("army"+str(self.my_id)+"_c_node")) self.node_col.setScale((1,1,0.5)) self.node_col.setPos(0,0,0) self.node_col.node().addSolid(CollisionSphere(0,0,0,1)) self.node_col.setTag("type","army") base.cTrav.addCollider(self.node_col,base.col_manager.col_handler) #self.node_col.show() self.node_path.setTag("id",str(self.my_id)) self.army_fight_col = self.node_path.attachNewNode(CollisionNode("army"+str(self.my_id)+"_batcol_node")) self.army_fight_col.setScale((2,2,0.5)) self.army_fight_col.setPos(0,0,0) self.army_fight_col.node().addSolid(CollisionSphere(0,0,0,1)) self.army_fight_col.setColor(1,0,0,0.1) self.army_fight_col.setTag("player",str(player)) self.army_fight_col.setTag("state","normal") self.army_fight_col.setTag("type","army") base.cTrav.addCollider(self.army_fight_col,base.col_manager.col_handler) #self.army_fight_col.show() self.selection_ring = self.selection_ring_create(size = 1.2) self.selection_ring.reparentTo(self.node_path) self.selection_ring.hide() self.node_path.reparentTo(render) def turn_start(self): rate = 0.5 army_scl_up = self.model.scaleInterval(rate, Point3(1.5, 1.5, 1.5)) army_scl_down = self.model.scaleInterval(rate, Point3(1, 1, 1)) self.sq_army_bat = Sequence(army_scl_up,army_scl_down) self.sq_army_bat.loop() def turn_end(self): try: self.sq_army_bat.finish() except: print "no sequence to end" def die(self): if base.single_player == False and base.client == False: base.net_manager.server_messager("army_kill",[self.my_id]) self.state = "dead" self.army_fight_col.removeNode() self.node_col.removeNode() rate = 4 intvl_shrink = self.model.scaleInterval(rate, Point3(0, 0, 0)) func_destroy = Func(self.destroy) self.sq_die = Sequence(intvl_shrink,func_destroy) self.sq_die.start() base.battles[self.battle].recenter() base.battles[self.battle].shrink() if self.selected: i = base.col_manager.selecteds.index(self) del base.col_manager.selecteds[i] def stop(self): try: self.sq_army_move.pause() except: print "already stopped" def move_to_point(self,tx,ty): self.target_x = tx self.target_y = ty dist = float(TCalc.dist_to_point(self.node_path.getX(),self.node_path.getY(),tx,ty)) print dist #time = dist/speed #print dist/speed #print time*speed,dist try: self.sq_army_move.pause() self.intvl_army_move = None except: print "no sequence" if dist > 1: self.intvl_army_move = self.node_path.posInterval(dist/self.speed, Point3(self.target_x, self.target_y, 0),startPos=Point3(self.node_path.getX(), self.node_path.getY(), 0)) self.sq_army_move = Sequence(self.intvl_army_move) self.sq_army_move.start() else: try: self.sq_army_move.finish() except: print "no sequence" def set_target(self,sender,tx,ty): if self.state == "normal": if base.single_player == False: base.net_manager.army_move(self.my_id,tx,ty) else: self.move_to_point(tx,ty) def battle_shuffle(self,tx,ty): if base.single_player == False: base.net_manager.army_move(self.my_id,tx,ty) else: self.move_to_point(tx,ty)
class PartyCog(FSM): notify = directNotify.newCategory('PartyCog') HpTextGenerator = TextNode('HpTextGenerator') hpText = None height = 7 def __init__(self, parentNode, id, bounceSpeed=3, bounceHeight=1, rotateSpeed=1, heightShift=1, xMoveSpeed=0, xMoveDistance=0, bounceOffset=0): self.id = id FSM.__init__(self, 'PartyCogFSM-%d' % self.id) self.showFacingStatus = False self.xMoveSpeed = xMoveSpeed self.xMoveDistance = xMoveDistance self.heightShift = heightShift self.bounceSpeed = bounceSpeed self.bounceHeight = bounceHeight self.rotateSpeed = rotateSpeed self.parentNode = parentNode self.bounceOffset = bounceOffset self.hitInterval = None self.kaboomTrack = None self.resetRollIval = None self.netTimeSentToStartByHit = 0 self.load() self.request('Down') return def load(self): self.root = NodePath('PartyCog-%d' % self.id) self.root.reparentTo(self.parentNode) path = 'phase_13/models/parties/cogPinata_' self.actor = Actor( path + 'actor', { 'idle': path + 'idle_anim', 'down': path + 'down_anim', 'up': path + 'up_anim', 'bodyHitBack': path + 'bodyHitBack_anim', 'bodyHitFront': path + 'bodyHitFront_anim', 'headHitBack': path + 'headHitBack_anim', 'headHitFront': path + 'headHitFront_anim' }) self.actor.reparentTo(self.root) self.temp_transform = Mat4() self.head_locator = self.actor.attachNewNode('temphead') self.bodyColl = CollisionTube(0, 0, 1, 0, 0, 5.75, 0.75) self.bodyColl.setTangible(1) self.bodyCollNode = CollisionNode('PartyCog-%d-Body-Collision' % self.id) self.bodyCollNode.setCollideMask(ToontownGlobals.PieBitmask) self.bodyCollNode.addSolid(self.bodyColl) self.bodyCollNodePath = self.root.attachNewNode(self.bodyCollNode) self.headColl = CollisionTube(0, 0, 3, 0, 0, 3.0, 1.5) self.headColl.setTangible(1) self.headCollNode = CollisionNode('PartyCog-%d-Head-Collision' % self.id) self.headCollNode.setCollideMask(ToontownGlobals.PieBitmask) self.headCollNode.addSolid(self.headColl) self.headCollNodePath = self.root.attachNewNode(self.headCollNode) self.arm1Coll = CollisionSphere(1.65, 0, 3.95, 1.0) self.arm1Coll.setTangible(1) self.arm1CollNode = CollisionNode('PartyCog-%d-Arm1-Collision' % self.id) self.arm1CollNode.setCollideMask(ToontownGlobals.PieBitmask) self.arm1CollNode.addSolid(self.arm1Coll) self.arm1CollNodePath = self.root.attachNewNode(self.arm1CollNode) self.arm2Coll = CollisionSphere(-1.65, 0, 3.45, 1.0) self.arm2Coll.setTangible(1) self.arm2CollNode = CollisionNode('PartyCog-%d-Arm2-Collision' % self.id) self.arm2CollNode.setCollideMask(ToontownGlobals.PieBitmask) self.arm2CollNode.addSolid(self.arm2Coll) self.arm2CollNodePath = self.root.attachNewNode(self.arm2CollNode) splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splatType = globalPropPool.getPropType(splatName) self.pieHitSound = globalBattleSoundCache.getSound( 'AA_wholepie_only.ogg') self.upSound = globalBattleSoundCache.getSound('AV_jump_to_side.ogg') self.hole = loader.loadModel('phase_13/models/parties/cogPinataHole') self.hole.setTransparency(True) self.hole.setP(-90.0) self.hole.setScale(3) self.hole.setBin('ground', 3) self.hole.reparentTo(self.parentNode) def unload(self): self.request('Off') self.clearHitInterval() if self.hole is not None: self.hole.removeNode() self.hole = None if self.actor is not None: self.actor.cleanup() self.actor.removeNode() self.actor = None if self.root is not None: self.root.removeNode() self.root = None if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.kaboomTrack = None if self.resetRollIval is not None and self.resetRollIval.isPlaying(): self.resetRollIval.finish() self.resetRollIval = None if self.hitInterval is not None and self.hitInterval.isPlaying(): self.hitInterval.finish() self.hitInterval = None del self.upSound del self.pieHitSound return def enterStatic(self): pass def exitStatic(self): pass def enterActive(self, startTime): self.root.setR(0.0) updateTask = Task.Task(self.updateTask) updateTask.startTime = startTime taskMgr.add(updateTask, 'PartyCog.update-%d' % self.id) def exitActive(self): taskMgr.remove('PartyCog.update-%d' % self.id) taskMgr.remove('PartyCog.bounceTask-%d' % self.id) self.clearHitInterval() self.resetRollIval = self.root.hprInterval(0.5, Point3( self.root.getH(), 0.0, 0.0), blendType='easeInOut') self.resetRollIval.start() self.actor.stop() def enterDown(self): if self.oldState == 'Off': downAnimControl = self.actor.getAnimControl('down') self.actor.pose('down', downAnimControl.getNumFrames() - 1) return self.clearHitInterval() startScale = self.hole.getScale() endScale = Point3(5, 5, 5) self.hitInterval = Sequence( LerpFunc(self.setAlongSpline, duration=1.0, fromData=self.currentT, toData=0.0), LerpScaleInterval(self.hole, duration=0.175, scale=endScale, startScale=startScale, blendType='easeIn'), Parallel( SoundInterval(self.upSound, volume=0.6, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), ActorInterval(self.actor, 'down', loop=0)), LerpScaleInterval(self.hole, duration=0.175, scale=Point3(3, 3, 3), startScale=endScale, blendType='easeOut')) self.hitInterval.start() def exitDown(self): self.root.setR(0.0) self.root.setH(0.0) self.targetDistance = 0.0 self.targetFacing = 0.0 self.currentT = 0.0 self.setAlongSpline(0.0) self.clearHitInterval() startScale = self.hole.getScale() endScale = Point3(5, 5, 5) self.hitInterval = Sequence( LerpScaleInterval(self.hole, duration=0.175, scale=endScale, startScale=startScale, blendType='easeIn'), Parallel( SoundInterval(self.upSound, volume=0.6, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), ActorInterval(self.actor, 'up', loop=0)), Func(self.actor.loop, 'idle'), LerpScaleInterval(self.hole, duration=0.175, scale=Point3(3, 3, 3), startScale=endScale, blendType='easeOut')) self.hitInterval.start() def filterDown(self, request, args): if request == 'Down': return None else: return self.defaultFilter(request, args) return None def setEndPoints(self, start, end, amplitude=1.7): self.sinAmplitude = amplitude self.sinPeriod = (end.getX() - start.getX()) / 2 self.sinDisplacement = start.getY() self.startPoint = start self.endPoint = end self.currentT = 0.0 self.targetDistance = 0.0 self.currentFacing = 0.0 self.targetFacing = 0.0 self.setAlongSpline(self.currentT) self.hole.setPos(self.root.getPos()) self.hole.setZ(0.02) def rockBackAndForth(self, task): t = task.startTime + task.time angle = math.sin(t) * 20.0 self.root.setR(angle) return task.cont def updateDistance(self, distance): self.targetDistance = clamp(distance, -1.0, 1.0) def updateTask(self, task): self.rockBackAndForth(task) if self.targetDistance > self.currentT: self.currentT += min(0.01, self.targetDistance - self.currentT) self.setAlongSpline(self.currentT) elif self.targetDistance < self.currentT: self.currentT += max(-0.01, self.targetDistance - self.currentT) self.setAlongSpline(self.currentT) if self.currentT < 0.0: self.targetFacing = -90.0 elif self.currentT > 0.0: self.targetFacing = 90.0 else: self.targetFacing = 0.0 if self.targetFacing > self.currentFacing: self.currentFacing += min(10, self.targetFacing - self.currentFacing) elif self.targetFacing < self.currentFacing: self.currentFacing += max(-10, self.targetFacing - self.currentFacing) self.root.setH(self.currentFacing) return task.cont def setAlongSpline(self, t): t = t + 1.0 dist = (self.endPoint.getX() - self.startPoint.getX()) / 2.0 x = self.startPoint.getX() + t * dist y = self.startPoint.getY() - math.sin( t * 2 * math.pi) * self.sinAmplitude self.root.setPos(x, y, 0) def startBounce(self): taskMgr.add(self.bounce, 'PartyCog.bounceTask-%d' % self.id) def bounce(self, task): self.root.setZ( math.sin((self.bounceOffset + task.time) * self.bounceSpeed) * self.bounceHeight + self.heightShift) return task.cont def setPos(self, position): self.root.setPos(position) def respondToPieHit(self, timestamp, position, hot=False, direction=1.0): if self.netTimeSentToStartByHit < timestamp: self.__showSplat(position, direction, hot) if self.netTimeSentToStartByHit < timestamp: self.netTimeSentToStartByHit = timestamp else: self.notify.debug( 'respondToPieHit self.netTimeSentToStartByHit = %s' % self.netTimeSentToStartByHit) def clearHitInterval(self): if self.hitInterval is not None and self.hitInterval.isPlaying(): self.hitInterval.clearToInitial() return def __showSplat(self, position, direction, hot=False): if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.clearHitInterval() splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splat.reparentTo(render) self.splat.setPos(self.root, position) self.splat.setAlphaScale(1.0) if not direction == 1.0: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[0]) if self.currentFacing > 0.0: facing = 'HitFront' else: facing = 'HitBack' else: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[1]) if self.currentFacing > 0.0: facing = 'HitBack' else: facing = 'HitFront' if hot: targetscale = 0.75 part = 'head' else: targetscale = 0.5 part = 'body' def setSplatAlpha(amount): self.splat.setAlphaScale(amount) self.hitInterval = Sequence( ActorInterval(self.actor, part + facing, loop=0), Func(self.actor.loop, 'idle')) self.hitInterval.start() self.kaboomTrack = Parallel( SoundInterval(self.pieHitSound, volume=1.0, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), Sequence( Func(self.splat.showThrough), Parallel( Sequence( LerpScaleInterval(self.splat, duration=0.175, scale=targetscale, startScale=Point3(0.1, 0.1, 0.1), blendType='easeOut'), Wait(0.175)), Sequence( Wait(0.1), LerpFunc(setSplatAlpha, duration=1.0, fromData=1.0, toData=0.0, blendType='easeOut'))), Func(self.splat.cleanup), Func(self.splat.removeNode))) self.kaboomTrack.start() return def showHitScore(self, number, scale=1): if number <= 0: return if self.hpText: self.hideHitScore() self.HpTextGenerator.setFont(ToontownGlobals.getSignFont()) if number < 0: self.HpTextGenerator.setText(str(number)) else: self.HpTextGenerator.setText('+' + str(number)) self.HpTextGenerator.clearShadow() self.HpTextGenerator.setAlign(TextNode.ACenter) r = 1 g = 1 b = 0 a = 1 self.HpTextGenerator.setTextColor(r, g, b, a) self.hpTextNode = self.HpTextGenerator.generate() self.hpText = render.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) self.hpText.setBillboardPointEye() self.hpText.setBin('fixed', 100) self.hpText.setPos(self.root, 0, 0, self.height / 2) seq = Sequence( self.hpText.posInterval( 0.25, Point3(self.root.getX(render), self.root.getY(render), self.root.getZ(render) + self.height + 1.0), blendType='easeOut'), Wait(0.25), self.hpText.colorInterval(0.1, Vec4(r, g, b, 0)), Func(self.hideHitScore)) seq.start() def hideHitScore(self): if self.hpText: taskMgr.remove('PartyCogHpText' + str(self.id)) self.hpText.removeNode() self.hpText = None return def getHeadLocation(self): self.actor.getJoints(jointName='head')[0].getNetTransform( self.temp_transform) self.head_locator.setMat(self.temp_transform) return self.head_locator.getZ(self.root)
class Tower(GameObject): def __init__(self,player,name,x,y,income): global tower_count self.my_id = tower_count tower_count += 1 self.player = player self.name = name self.x = x self.y = y self.state = "normal" self.build_progress = 0.0 self.build_speed = 1.0 self.gold_inc = 1.0 if base.player == self.player: base.ecn_manager.gold_inc += self.gold_inc base.vis_manager.update() self.model_list = ["models/farmhouse_grey.egg","models/farmhouse_red.egg","models/farmhouse_green.egg"] self.model_list = ["models/tower_grey.egg","models/tower_red.egg","models/tower_green.egg"] self.model = loader.loadModel(self.model_list[self.player]) # if self.player == 0: # self.model = loader.loadModel("models/tower_grey.egg") # elif self.player == 1: # self.model = loader.loadModel("models/tower_red.egg") # elif self.player == 2: # self.model = loader.loadModel("models/tower_green.egg") self.node_path = NodePath("tower"+str(self.my_id)+"_node_path") self.model.reparentTo(self.node_path) self.node_path.setPos(x,y,0) self.node_path.setTag("player",str(player)) self.node_path.setScale(tower_scale,tower_scale,tower_scale) self.node_path.setColor(1,1,1,0.1) self.node_col = self.node_path.attachNewNode(CollisionNode("tower"+str(self.my_id)+"_c_node")) self.node_col.setScale((2,2,1)) self.node_col.setPos(0,0,0) self.node_col.node().addSolid(CollisionSphere(0,0,0,1)) self.node_col.setTag("type","tower") base.cTrav.addCollider(self.node_col,base.col_manager.col_handler) #self.node_col.show() self.node_path.setTag("id",str(self.my_id)) self.tower_fight_col = self.node_path.attachNewNode(CollisionNode("tower"+str(self.my_id)+"_batcol_node")) self.tower_fight_col.setScale((2,2,0.5)) self.tower_fight_col.setPos(0,0,0) self.tower_fight_col.node().addSolid(CollisionSphere(0,0,0,1)) self.tower_fight_col.setColor(1,0,0,0.1) self.tower_fight_col.setTag("player",str(player)) self.tower_fight_col.setTag("state","normal") #self.tower_fight_col.show() base.cTrav.addCollider(self.tower_fight_col,base.col_manager.col_handler) self.selection_ring = self.selection_ring_create(size = 1.5) self.selection_ring.reparentTo(self.node_path) self.selection_ring.hide() self.node_path.reparentTo(render) def capture_check(self): has_guard = False for a in base.armies: if a.player == self.player and (a.state == "normal" or a.state == "battle"): if base.calculator.dist_to_point(self.get_x(),self.get_y(),a.get_x(),a.get_y()) < 80: has_guard = True if has_guard == True: return False else: return True def change_owner(self,new_owner): if self.player == base.player: base.ecn_manager.gold_inc -= self.gold_inc elif new_owner == base.player: base.ecn_manager.gold_inc += self.gold_inc base.vis_manager.update() self.model.remove() self.model = loader.loadModel(self.model_list[new_owner]) self.node_path.setTag("player",str(new_owner)) self.tower_fight_col.setTag("player",str(new_owner)) self.player = new_owner self.model.reparentTo(self.node_path) def build_cancel(self): if self.player == base.player: base.ecn_manager.gold += base.ecn_manager.cost_army_gold base.vis_manager.update() if base.single_player == False and base.client == False: base.net_manager.server_messager("build_cancel",[self.my_id]) taskMgr.remove("task_tower"+str(self.my_id)+"_build") self.build_progress = 0.0 if base.vis_manager.statbar.focus == self: base.vis_manager.statbar.show_tower(self.my_id) def build_start(self): if self.player == base.player: base.ecn_manager.gold -= base.ecn_manager.cost_army_gold base.vis_manager.update() print "Started Building" if base.single_player == False and base.client == False: base.net_manager.server_messager("build_start",[self.my_id,self.player,"army"]) self.build_progress = self.build_speed taskMgr.add(self.task_build,"task_tower"+str(self.my_id)+"_build") if base.vis_manager.statbar.focus == self: base.vis_manager.statbar.show_tower(self.my_id) def build_start_request(self): base.net_manager.client_messager("build_start_request",[self.my_id,self.player,"army"]) def build_cancel_request(self): base.net_manager.client_messager("build_cancel_request",[self.my_id]) def task_build(self,task): if self.build_progress < 100.00: self.build_progress += self.build_speed if base.vis_manager.statbar.focus == self: base.vis_manager.statbar.bar_build.set_value(self.build_progress) return Task.again else: self.build_progress = 0.0 if base.vis_manager.statbar.focus == self: base.vis_manager.statbar.show_tower(self.my_id) if base.single_player == False and base.client == False: base.net_manager.server_messager("build_complete",[self.my_id,self.player,"army"]) if base.client == False: self.create_counter() return Task.done def create_counter(self): new_army = Army(self.player,"Infantry",self.node_path.getX(),self.node_path.getY(),1) base.armies.append(new_army) new_army.state = "new" new_army.army_fight_col.setTag("state","new") intvl_exit = new_army.node_path.posInterval(2, Point3(self.x, self.y-24, 0),startPos=Point3(self.x, self.y, 0)) def army_ready(): new_army.state = "normal" new_army.army_fight_col.setTag("state","normal") func_armyready = Func(army_ready) sq_army_move = Sequence(intvl_exit,func_armyready) sq_army_move.start()
class CogdoFlyingCameraManager: def __init__(self, cam, parent, player, level): self._toon = player.toon self._camera = cam self._parent = parent self._player = player self._level = level self._enabled = False def enable(self): if self._enabled: return self._toon.detachCamera() self._prevToonY = 0.0 levelBounds = self._level.getBounds() l = Globals.Camera.LevelBoundsFactor self._bounds = ((levelBounds[0][0] * l[0], levelBounds[0][1] * l[0]), (levelBounds[1][0] * l[1], levelBounds[1][1] * l[1]), (levelBounds[2][0] * l[2], levelBounds[2][1] * l[2])) self._lookAtZ = self._toon.getHeight() + Globals.Camera.LookAtToonHeightOffset self._camParent = NodePath('CamParent') self._camParent.reparentTo(self._parent) self._camParent.setPos(self._toon, 0, 0, 0) self._camParent.setHpr(180, Globals.Camera.Angle, 0) self._camera.reparentTo(self._camParent) self._camera.setPos(0, Globals.Camera.Distance, 0) self._camera.lookAt(self._toon, 0, 0, self._lookAtZ) self._cameraLookAtNP = NodePath('CameraLookAt') self._cameraLookAtNP.reparentTo(self._camera.getParent()) self._cameraLookAtNP.setPosHpr(self._camera.getPos(), self._camera.getHpr()) self._levelBounds = self._level.getBounds() self._enabled = True self._frozen = False self._initCollisions() def _initCollisions(self): self._camCollRay = CollisionRay() camCollNode = CollisionNode('CameraToonRay') camCollNode.addSolid(self._camCollRay) camCollNode.setFromCollideMask(OTPGlobals.WallBitmask | OTPGlobals.CameraBitmask | ToontownGlobals.FloorEventBitmask | ToontownGlobals.CeilingBitmask) camCollNode.setIntoCollideMask(0) self._camCollNP = self._camera.attachNewNode(camCollNode) self._camCollNP.show() self._collOffset = Vec3(0, 0, 0.5) self._collHandler = CollisionHandlerQueue() self._collTrav = CollisionTraverser() self._collTrav.addCollider(self._camCollNP, self._collHandler) self._betweenCamAndToon = {} self._transNP = NodePath('trans') self._transNP.reparentTo(render) self._transNP.setTransparency(True) self._transNP.setAlphaScale(Globals.Camera.AlphaBetweenToon) self._transNP.setBin('fixed', 10000) def _destroyCollisions(self): self._collTrav.removeCollider(self._camCollNP) self._camCollNP.removeNode() del self._camCollNP del self._camCollRay del self._collHandler del self._collOffset del self._betweenCamAndToon self._transNP.removeNode() del self._transNP def freeze(self): self._frozen = True def unfreeze(self): self._frozen = False def disable(self): if not self._enabled: return self._destroyCollisions() self._camera.wrtReparentTo(render) self._cameraLookAtNP.removeNode() del self._cameraLookAtNP self._camParent.removeNode() del self._camParent del self._prevToonY del self._lookAtZ del self._bounds del self._frozen self._enabled = False def update(self, dt = 0.0): self._updateCam(dt) self._updateCollisions() def _updateCam(self, dt): toonPos = self._toon.getPos() camPos = self._camParent.getPos() x = camPos[0] z = camPos[2] toonWorldX = self._toon.getX(render) maxX = Globals.Camera.MaxSpinX toonWorldX = clamp(toonWorldX, -1.0 * maxX, maxX) spinAngle = Globals.Camera.MaxSpinAngle * toonWorldX * toonWorldX / (maxX * maxX) newH = 180.0 + spinAngle self._camParent.setH(newH) spinAngle = spinAngle * (pi / 180.0) distBehindToon = Globals.Camera.SpinRadius * cos(spinAngle) distToRightOfToon = Globals.Camera.SpinRadius * sin(spinAngle) d = self._camParent.getX() - clamp(toonPos[0], *self._bounds[0]) if abs(d) > Globals.Camera.LeewayX: if d > Globals.Camera.LeewayX: x = toonPos[0] + Globals.Camera.LeewayX else: x = toonPos[0] - Globals.Camera.LeewayX x = self._toon.getX(render) + distToRightOfToon boundToonZ = min(toonPos[2], self._bounds[2][1]) d = z - boundToonZ if d > Globals.Camera.MinLeewayZ: if self._player.velocity[2] >= 0 and toonPos[1] != self._prevToonY or self._player.velocity[2] > 0: z = boundToonZ + d * INVERSE_E ** (dt * Globals.Camera.CatchUpRateZ) elif d > Globals.Camera.MaxLeewayZ: z = boundToonZ + Globals.Camera.MaxLeewayZ elif d < -Globals.Camera.MinLeewayZ: z = boundToonZ - Globals.Camera.MinLeewayZ if self._frozen: y = camPos[1] else: y = self._toon.getY(render) - distBehindToon self._camParent.setPos(x, smooth(camPos[1], y), smooth(camPos[2], z)) if toonPos[2] < self._bounds[2][1]: h = self._cameraLookAtNP.getH() if d >= Globals.Camera.MinLeewayZ: self._cameraLookAtNP.lookAt(self._toon, 0, 0, self._lookAtZ) elif d <= -Globals.Camera.MinLeewayZ: self._cameraLookAtNP.lookAt(self._camParent, 0, 0, self._lookAtZ) self._cameraLookAtNP.setHpr(h, self._cameraLookAtNP.getP(), 0) self._camera.setHpr(smooth(self._camera.getHpr(), self._cameraLookAtNP.getHpr())) self._prevToonY = toonPos[1] def _updateCollisions(self): pos = self._toon.getPos(self._camera) + self._collOffset self._camCollRay.setOrigin(pos) direction = -Vec3(pos) direction.normalize() self._camCollRay.setDirection(direction) self._collTrav.traverse(render) nodesInBetween = {} if self._collHandler.getNumEntries() > 0: self._collHandler.sortEntries() for entry in self._collHandler.getEntries(): name = entry.getIntoNode().getName() if name.find('col_') >= 0: np = entry.getIntoNodePath().getParent() if np not in nodesInBetween: nodesInBetween[np] = np.getParent() for np in nodesInBetween.keys(): if np in self._betweenCamAndToon: del self._betweenCamAndToon[np] else: np.setTransparency(True) np.wrtReparentTo(self._transNP) if np.getName().find('lightFixture') >= 0: np.find('**/*floor_mesh').hide() elif np.getName().find('platform') >= 0: np.find('**/*Floor').hide() for np, parent in self._betweenCamAndToon.items(): np.wrtReparentTo(parent) np.setTransparency(False) if np.getName().find('lightFixture') >= 0: np.find('**/*floor_mesh').show() elif np.getName().find('platform') >= 0: np.find('**/*Floor').show() self._betweenCamAndToon = nodesInBetween
class Ship: set = 0 fuel = 1 air = 1 current = 0 acceleration = 0.002 max = 0.25 fall = 0.001 gravity = 0.3 steer = 0 steerspeed = 0.05 slide = 0 jumpheight = 0.2 jump = True control = True dead = False under = None def __init__(self, root, model): self.root = root self.node = NodePath("ship") self.model = model self.model.reparentTo(self.node) self.node.reparentTo(render) self.setColliders() self.explosion = loader.loadModel("assets/models/explosion.bam") self.explosion.reparentTo(render) self.explosion.hide() self.explosion.setLightOff() self.loadAudio() def loadAudio(self): # each ship has their own set of sounds folder = "assets/audio/sfx/" self.audio = { "bounce":loader.loadSfx(folder+"bounce.wav"), "engine":loader.loadSfx(folder+"engine.wav"), "explode":loader.loadSfx(folder+"explode.wav"), "land":loader.loadSfx(folder+"land.wav"), "pickup":loader.loadSfx(folder+"pickup.wav"), "shave":loader.loadSfx(folder+"shave.wav"), } def setColliders(self): self.handlers = [] for i in range(3): if i == 1: y = 0.2 else: y = -0.2 h = colRay(self.node, ((-1+i)/4, y, .1)) self.handlers.append(h) self.colNose = colSpheres(self.node, [((0,.1,.1),.02)]) self.colLeft = colSpheres(self.node, [((-.15,-.1,.2), .1)]) self.colRight = colSpheres(self.node, [((.15,-.1,.2), .1)]) self.colTop = colSpheres(self.node, [((0,0.2,0.4), .1)]) def update(self): self.control = True self.air -= (1/5000)*self.o2drain self.fuel -= (self.speed/1000)*self.fueldrain if self.air <= 0.01 or self.fuel <= 0.01: self.control = False if not self.dead: self.collide() self.specialFloor() # Set fw/bw speed self.speed = clamp(self.speed, 0, self.max) self.audio["engine"].setPlayRate((self.speed*7)) # Update node position x = self.node.getX()+((self.steer+self.slide)*self.steerspeed) y = self.node.getY()+self.speed z = self.node.getZ()-self.fall self.node.setFluidPos(x, y, z) # Point nose to fall speed self.model.setP(-(self.fall*300)) # Set flame color to speed cc = (self.speed*7)-uniform(0,0.3) self.model.getChild(0).setColorScale(cc*2,cc,cc,1) # Respawn if fallen off. if z < -20: self.respawn() self.setMeters() def specialFloor(self): f = self.under if f: if f == 1: self.root.road.playNextMap() self.respawn() elif f == 2: self.explode() elif f == 3: self.speed += self.acceleration*2 elif f == 4: self.fuel = 0.99 self.air = 0.99 elif f == 5: self.control = False elif f == 6: self.speed -= self.acceleration*2 def collide(self): if self.colNose.getNumEntries() > 0: if self.speed > 0.1: # full frontal crash self.explode() else: # full frontal bump self.audio["shave"].play() self.speed = 0 self.node.setY(self.node.getY()-0.2) # bounce left and right if self.colLeft.getNumEntries() > 0: self.steer = 1 self.audio["shave"].play() elif self.colRight.getNumEntries() > 0: self.steer = -1 self.audio["shave"].play() # connect to floor self.grounded = False self.under = under = None self.root.cTrav.traverse(render) hits = [0,0,0] for h, handler in enumerate(self.handlers): if len(list(handler.entries)) > 0: handler.sortEntries() entry = list(handler.entries)[0] hitPos = entry.getSurfacePoint(render) distToGround = self.node.getZ() - hitPos.getZ() if distToGround < 0.03: hits[h] = 1 if distToGround < self.fall+0.05: if self.fall > 0.05: #go bounce self.fall = -0.05 self.jump = True self.audio["bounce"].play() elif self.fall > 0: #land self.fall = 0 self.jump = True self.audio["land"].play() if self.colTop.getNumEntries() > 0: self.fall = 0 self.grounded = True under = entry.getSurfacePoint(render) self.node.setZ(hitPos.getZ()+0.01) s = self.getSteerVal() if hits == [1,0,0]: self.slide += 0.01 elif hits == [0,0,1]: self.slide -= 0.01 elif not hits == [0,0,0]: self.slide = 0 # fall if not on floor if not self.grounded: self.fall += (self.gravity)/550 if self.colTop.getNumEntries() > 0: if self.fall < 0: self.fall = -self.fall # else see what color the floor is elif under: x, y, z = under x = round(x) y = round(y/2) z = round(z*2)-1 try: color = self.root.road.map[y][x][z][1] if color <= 8 : self.under = color except: pass def setMeters(self): self.root.hud.setSpeed(self.speed*114) self.root.hud.setAir(self.air*14) self.root.hud.setFuel(self.fuel*14) self.root.hud.setMiles(self.node.getY(), len(self.root.road.map)) self.root.hud.setGravity(self.gravity) def explode(self): Explosion(self, self.explosion) self.audio["engine"].stop() self.audio["explode"].play() self.node.hide() self.dead = True def accelerate(self): if not self.dead and self.control: self.speed += self.acceleration def decelerate(self): if not self.dead and self.control: self.speed -= self.acceleration def getSteerVal(self): return ((self.speed*4)+0.1) def goLeft(self): if not self.dead and self.control: if self.grounded or self.fall < -0.07: if self.colLeft.getNumEntries() == 0: self.steer = -self.getSteerVal() self.slide = 0 def goRight(self): if not self.dead and self.control: if self.grounded or self.fall < -0.07: if self.colRight.getNumEntries() == 0: self.steer = self.getSteerVal() self.slide = 0.01 def jumpUp(self): if self.gravity < 8: if not self.dead and self.control: if self.colTop.getNumEntries() == 0: if self.jump and self.fall < 0.05: self.fall = -0.1 self.jump = False def respawn(self): self.audio["engine"].setLoop(True) self.audio["engine"].setVolume(1) self.audio["engine"].play() self.node.show() self.node.setPos(4,0,0.7) self.fall = 0 self.speed = 0 self.jump = True self.control = True self.dead = False self.air = 1 self.fuel = 1 self.gravity = self.root.road.gravity self.fueldrain = self.root.road.fueldrain self.o2drain = self.root.road.o2drain self.setMeters()