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
예제 #2
0
    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)
예제 #3
0
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
예제 #5
0
def enableLocalAvatarTriggerEvents(ghostNode, extraArgs=[]):
    if ghostNode is None or ghostNode.isEmpty(
    ) or not ghostNode.node().isOfType(BulletGhostNode.getClassType()):
        return

    GhostNodeLocalAvBroadcaster(ghostNode, extraArgs)
예제 #6
0
    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