def __checkFutureSpace(self, globalVel): globalVel = globalVel * self.futureSpacePredictionDistance pFrom = Point3(self.capsuleNP.getPos(render) + globalVel) pUp = Point3(pFrom + Point3(0, 0, self.__capsuleH * 2.0)) pDown = Point3(pFrom - Point3(0, 0, self.__capsuleH * 2.0 + self.__levitation)) upTest = self.__world.rayTestClosest(pFrom, pUp, CIGlobals.WallGroup) downTest = self.__world.rayTestClosest( pFrom, pDown, CIGlobals.FloorGroup | CIGlobals.StreetVisGroup) if not (upTest.hasHit() and downTest.hasHit()): return True upNode = upTest.getNode() if upNode.getMass() or upNode.isOfType(BulletGhostNode.getClassType()): return True space = abs(upTest.getHitPos().z - downTest.getHitPos().z) if space < self.__levitation + self.__capsuleH + self.capsule.getRadius( ): return False return True
def think(self): elapsed = self.getEntityStateElapsed() state = self.getEntityState() if state == self.StateUp: if self.timeInAir >= 0 and elapsed >= (self.timeInAir + self.startDelay): self.b_setEntityState(self.StateStomp) elif state == self.StateDown: if self.timeOnGround >= 0 and elapsed >= self.timeOnGround: self.b_setEntityState(self.StateRaise) if not self.stomped: self.stomped = True result = self.dispatch.getPhysicsWorld().contactTest( self.floorColl.node()) for contact in result.getContacts(): node = contact.getNode1() if node == self.floorColl.node(): node = contact.getNode0() if node.isOfType(BulletGhostNode.getClassType()): continue avNP = NodePath(node).getParent() for obj in self.air.avatars[self.dispatch.zoneId]: if (CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey() and obj not in self.damaged): if self.damage != -1: obj.takeDamage( TakeDamageInfo(self, damageAmount=self.damage, damageType=DMG_FORCE)) else: obj.takeDamage( TakeDamageInfo( self, damageAmount=obj.getHealth(), damageType=DMG_FORCE)) self.damaged.append(obj) break elif state == self.StateStomp: self.startDelay = 0.0 if elapsed >= self.height / self.stompSpeed: self.b_setEntityState(self.StateDown) elif state == self.StateRaise: if elapsed >= self.height / self.raiseSpeed: self.b_setEntityState(self.StateUp)
def __ghostNodeWatcherTask(triggerNp, callback, extraArgs, task): if triggerNp.isEmpty() or not triggerNp.node().isOfType( BulletGhostNode.getClassType()): return task.done for node in triggerNp.node().getOverlappingNodes(): if node.hasPythonTag( "localAvatar" ) and base.localAvatar.walkControls.getCollisionsActive(): callback(*extraArgs) return task.done return task.cont
def tick(self, task): if self.isEmpty(): return task.done currPos = self.getPos(render) intoNode = None if self.useSweep: #print "From", self.lastPos, "to", currPos #print "Exclusions", self.__exclusions # Sweep test ensures no slip-throughs, but is a bit more expensive. result = self.world.sweepTestClosest( self.node().getShape(0), TransformState.makePos(self.lastPos), TransformState.makePos(currPos), self.mask) if result.hasHit(): #print "has hit" intoNode = result.getNode() for excl in self.__exclusions: if excl.isAncestorOf( NodePath(intoNode)) or excl == NodePath(intoNode): #print "Collided with exclusion", excl intoNode = None break contact = result #else: #print "no hit" else: result = self.world.contactTest(self.node()) for contact in result.getContacts(): node = contact.getNode1() if node == self.node(): node = contact.getNode0() if node.isOfType(BulletGhostNode.getClassType()): continue isExcluded = False for excl in self.__exclusions: if excl.isAncestorOf( NodePath(node)) or excl == NodePath(node): isExcluded = True break if isExcluded: continue intoNode = node break if intoNode is None: if currPos != self.lastPos: self.lastPos = currPos return task.cont mask = intoNode.getIntoCollideMask() if self.bitsIntersecting(mask, self.mask): args = [NodePath(intoNode)] if self.needSelfInArgs: args.insert(0, self) if self.resultInArgs: args.insert(0, contact) messenger.send(self.getCollideEvent(), args) if hasattr(self, 'onCollide'): self.onCollide(*args) for clbk in self.hitCallbacks: clbk(*args) return task.done if currPos != self.lastPos: self.lastPos = currPos return task.cont
def enableLocalAvatarTriggerEvents(ghostNode, extraArgs=[]): if ghostNode is None or ghostNode.isEmpty( ) or not ghostNode.node().isOfType(BulletGhostNode.getClassType()): return GhostNodeLocalAvBroadcaster(ghostNode, extraArgs)
def __moveShadow(self, task): if base.mouseWatcherNode.hasMouse(): currPos = self.dropShadow.getPos(render) if (currPos - self.prevPos).length() >= self.MovedEpsilon: # Shadow moved. messenger.send(self.moveShadowEventName) mouse = base.mouseWatcherNode.getMouse() pFrom = Point3(0) pTo = Point3(0) base.camLens.extrude(mouse, pFrom, pTo) pFrom = render.getRelativePoint(base.cam, pFrom) pTo = render.getRelativePoint(base.cam, pTo) groups = [ CIGlobals.WallGroup, CIGlobals.FloorGroup, CIGlobals.StreetVisGroup ] result, hits = PhysicsUtils.rayTestAllSorted( pFrom, pTo, (CIGlobals.WallGroup | CIGlobals.FloorGroup | CIGlobals.StreetVisGroup)) if result.hasHits(): for i in xrange(len(hits)): hit = hits[i] node = hit.getNode() if node.isOfType(BulletGhostNode.getClassType()): continue mask = node.getIntoCollideMask() # Figure out what we hit. if mask not in groups: # Ignore this hit. continue elif mask == CIGlobals.WallGroup: # A wall is blocking the floor, bad spot! self.goodSpot = False break else: # The other two possibilities are floors, so this must be a good spot. self.dropShadow.setPos(hit.getHitPos()) self.goodSpot = True break else: # We might be aiming at the sky or something? Bad spot! self.goodSpot = False distance = self.avatar.getDistance(self.dropShadow) if self.goodSpot and (distance < self.minDistance or distance > self.maxDistance): # Spot is either too close or too far, guess it's not a good spot after all. self.goodSpot = False if self.goodSpot: self.dropShadow.setColorScale(self.GoodCS, 1) else: self.dropShadow.setColorScale(self.BadCS, 1) self.prevPos = currPos return task.cont