def isSameLeafAsPlayer(self, plyr): if not CIGlobals.isNodePathOk(plyr) or not CIGlobals.isNodePathOk(self): return False plLeaf = self.battleZone.bspLoader.findLeaf(plyr.getPos() + (0, 0, 0.05)) myLeaf = self.battleZone.bspLoader.findLeaf(self.getPos() + (0, 0, 0.05)) return plLeaf == myLeaf
def isPlayerInPVS(self, plyr): if not CIGlobals.isNodePathOk(plyr) or not CIGlobals.isNodePathOk(self): return False plLeaf = self.battleZone.bspLoader.findLeaf(plyr.getPos() + (0, 0, 0.05)) myLeaf = self.battleZone.bspLoader.findLeaf(self.getPos() + (0, 0, 0.05)) return self.battleZone.bspLoader.isClusterVisible(myLeaf, plLeaf)
def cleanupGag(self): print "cleanupGag" if self.state == GagState.LOADED or self.state == GagState.RECHARGING: Gag.cleanupGag(self) if CIGlobals.isNodePathOk(self.megaphone): if CIGlobals.isNodePathOk(self.avatar): copies = self.avatar.findAllMatches('**/%s' % self.megaphone.getName()) for copy in copies: copy.removeNode() self.megaphone = None
def calibrate(self): self.traceOrigin = self.avatar.getPos() + (0, 0, self.avatar.getHeight() / 2) if CIGlobals.isNodePathOk(self.target): self.traceVector = ((self.target.getPos() + (0, 0, self.target.getHeight() / 2.0)) - self.traceOrigin).normalized() else: self.traceVector = self.avatar.getQuat().getForward()
def runTask(self): if not CIGlobals.isNodePathOk(self.npc.followTarget): return SCHED_FAILED wps = self.npc.getMotor().getWaypoints() if len(wps) >= 0: if len(wps) > 0: dest = wps[len(wps) - 1] dist = 5 * 5 else: dest = self.npc.getPos() dist = 15 * 15 if (dest - self.npc.followTarget.getPos()).lengthSquared() > dist: self.npc.planPath(self.npc.followTarget.getPos()) self.npc.getMotor().startMotor() elif (self.npc.followTarget.getPos() - self.npc.getPos() ).lengthSquared() <= 10 * 10 and self.npc.isPlayerVisible( self.npc.followTarget): if len(wps) > 0: self.npc.getMotor().stopMotor() self.npc.getMotor().clearWaypoints() # Do we need to stop and heal our friend? if self.npc.followTarget.getHealth( ) < self.npc.followTarget.getMaxHealth(): return SCHED_COMPLETE self.npc.makeIdealYaw(self.npc.followTarget.getPos()) if not self.npc.isFacingIdeal(): self.npc.changeYaw() return SCHED_CONTINUE
def think(self): BaseAttackAI.think(self) if self.action == self.StateAttack: if not CIGlobals.isNodePathOk(self.target): return # Lock onto the target self.avatar.headsUp(self.target) now = globalClock.getFrameTime() if now - self.lastFireTime >= self.EmitFlameIval: startPos = self.avatar.getPos() + self.avatar.getEyePosition() endPos = self.target.getPos() + self.target.getEyePosition() distance = (endPos - startPos).length() duration = distance / self.FlameSpeed flame = FiredProjectileAI(base.air) flame.setProjectile(duration, startPos, endPos, 0.9, globalClockDelta.getFrameNetworkTime()) flame.generateWithRequired(self.avatar.getBattleZone().zoneId) flame.addHitCallback(self.onProjectileHit) flame.addExclusion(self.avatar) self.lastFireTime = now
def __updateParticleParent(self): if not CIGlobals.isNodePathOk(self.waterStreamParent): return time = globalClock.getFrameTime() streamPos = self.waterStreamParent.getPos(render) distance = self.sprayParticleDist if self.isLocal(): camQuat = camera.getQuat(render) pFrom = camera.getPos(render) push = (streamPos - pFrom).length() pFrom += camQuat.xform(Vec3.forward()) * push pTo = pFrom + camQuat.xform( Vec3.forward()) * (self.sprayParticleDist + (pFrom - streamPos).length()) hitPos = Point3(pTo) result = base.physicsWorld.rayTestClosest(pFrom, pTo, CIGlobals.WorldGroup) if result.hasHit(): node = result.getNode() hitPos = result.getHitPos() distance = (hitPos - streamPos).length() if time - self.lastSprayTime >= self.SprayTraceIval and not self.released: if result.hasHit(): self.__doSplat(distance, hitPos) self.getFPSCam().addViewPunch( Vec3(random.uniform(-0.6, 0.6), random.uniform(0.25, 1.0), 0.0)) self.primaryFirePress(True) self.lastSprayTime = time else: pFrom = self.avatar.getPos(render) + self.avatar.getEyePoint() + ( 1, 0, 0) quat = Quat() quat.setHpr( self.avatar.getHpr(render) + (0, self.avatar.lookPitch, 0)) pTo = pFrom + quat.xform( Vec3.forward()) * (self.sprayParticleDist + (pFrom - streamPos).length()) hitPos = Point3(pTo) hit = PhysicsUtils.rayTestClosestNotMe( self.avatar, pFrom, pTo, CIGlobals.WorldGroup | CIGlobals.LocalAvGroup) if hit is not None: hitPos = hit.getHitPos() distance = (hitPos - streamPos).length() self.waterStreamParent.lookAt(render, hitPos) if self.sprayParticle: system = self.sprayParticle.getParticlesNamed('particles-1') # Make the particles die off at the hit point. lifespan = min( 1, distance / self.sprayParticleDist) * self.sprayParticleLife system.factory.setLifespanBase(lifespan)
def clearWaterNode(self, node): if CIGlobals.isNodePathOk(node): node.removeNode() if node in self.waterNodes: self.waterNodes.remove(node) if len(self.waterNodes) == 0 and self.hasScenes: self.cleanupScenes()
def runTask(self): if not CIGlobals.isNodePathOk(self.npc.followTarget): return SCHED_FAILED if len(self.npc.getMotor().waypoints) == 1 and self.npc.getDistance( self.npc.followTarget) <= 5: return SCHED_COMPLETE return SCHED_CONTINUE
def doGagEffect(suit, flags): if not CIGlobals.isNodePathOk(suit): return effect = Parallel() for id in Effects.keys(): if (flags & id) != 0: print("Doing effect", id) effect.append(Effects[id](suit)) effect.start()
def runTask(self): if not CIGlobals.isNodePathOk(self.npc.followTarget): return SCHED_FAILED self.npc.makeIdealYaw(self.npc.followTarget.getPos()) if self.npc.isFacingIdeal(): return SCHED_COMPLETE self.npc.changeYaw() return SCHED_CONTINUE
def runTask(self): if not CIGlobals.isNodePathOk(self.npc.followTarget): return SCHED_FAILED path = self.npc.getBattleZone().planPath( self.npc.getPos(), self.npc.followTarget.getPos()) if len(path) < 2: return SCHED_FAILED self.npc.getMotor().setWaypoints(path) return SCHED_COMPLETE
def runTask(self): if self.npc.getEquippedAttack() == -1: return SCHED_FAILED if not CIGlobals.isNodePathOk(self.npc.followTarget): return SCHED_FAILED self.npc.attackFinished = False attack = self.npc.attacks[self.npc.getEquippedAttack()] if not attack.npcUseAttack(self.npc.followTarget): return SCHED_CONTINUE return SCHED_COMPLETE
def popTarget(self): for i in range(len(self.oldTargets) - 1, -1, -1): target = self.oldTargets[i] if not target or not CIGlobals.isNodePathOk(target.entity): continue if target.entity.getHealth() > 0: self.target = target return True self.oldTargets.pop() return False
def runTask(self): if len(self.npc.getMotor().getWaypoints()) == 0: self.npc.getMotor().stopMotor() return SCHED_COMPLETE if self.watchTarget: if self.npc.hasConditions(COND_SEE_TARGET) and self.npc.target: if CIGlobals.isNodePathOk(self.npc.target.entity): self.npc.makeIdealYaw(self.npc.target.entity.getPos()) if self.changeYaw: # Continue looking in our ideal direction self.npc.changeYaw() return SCHED_CONTINUE
def __holdAttackModel(self): if not self.hasAvatar(): self.notify.warning( "Tried to hold attack model, but no valid avatar.") return if not CIGlobals.isNodePathOk(self.model): return if self.Hold == ATTACK_HOLD_LEFT: self.model.reparentTo(self.avatar.getLeftHandNode()) elif self.Hold == ATTACK_HOLD_RIGHT: self.model.reparentTo(self.avatar.getRightHandNode()) else: self.model.reparentTo(NodePath())
def think(self): BaseAttackAI.think(self) time = self.ThrowAfterTime if not time: try: time = self.__calculateThrowAfterTime() except: pass if self.action == self.StateThrow: if not CIGlobals.isNodePathOk(self.target): return # Lock onto the target self.avatar.headsUp(self.target) if self.getActionTime() >= time and not self.didThrow: self.calibrate(self.target) # Trace a line from the trace origin outward along the trace direction # to find out what we hit, and adjust the direction of the projectile launch traceEnd = self.traceOrigin + (self.traceVector * 10000) hit = PhysicsUtils.rayTestClosestNotMe( self.avatar, self.traceOrigin, traceEnd, CIGlobals.WorldGroup | CIGlobals.CharacterGroup, self.avatar.getBattleZone().getPhysicsWorld()) if hit is not None: hitPos = hit.getHitPos() else: hitPos = traceEnd vecThrow = (hitPos - self.throwOrigin).normalized() endPos = self.throwOrigin + (vecThrow * self.ThrowPower) proj = GenericThrowableLinearProjectileAI(base.air) proj.setData(self.ID) proj.setLinear(1.5, self.throwOrigin, endPos, globalClockDelta.getFrameNetworkTime()) proj.generateWithRequired(self.avatar.getBattleZone().zoneId) proj.addHitCallback(self.onProjectileHit) proj.addExclusion(self.avatar) self.didThrow = True
def think(self): BaseHitscan.think(self) if CIGlobals.isNodePathOk(self.hoseJoint): hand = self.avatar.getLeftHandNode() self.hoseJoint.setHpr(self.avatar, hand.getHpr(self.avatar) + (-5, 5, 0)) self.hoseJoint.setPos(self.avatar, hand.getPos(self.avatar) + (-0.1, 0.2, 0.1)) if self.action == self.StateFire: self.__updateParticleParent() if self.isLocal(): if self.waterBar: perct = self.__updateWaterBar() if perct <= 0.3: time = globalClock.getFrameTime() alpha = 0.5 + ((math.sin(time * 7) + 1) / 4) self.waterBar.setBarAlpha(alpha)
def getSchedule(self): if self.npcState in [STATE_DEAD, STATE_NONE]: return BaseNPCAI.getSchedule(self) if self.hasConditions(COND_VP_JUMPING): return self.getScheduleByName("VP_JUMP_DODGE") if self.npcState == STATE_COMBAT: if self.hasConditions(COND_TARGET_DEAD): self.clearConditions(COND_TARGET_DEAD) task_oneOff( Task_Speak(self, 0.25, [ "Got one!", "Take that!", "Piece of cake!", "That's going to leave a mark!", "Rock and roll!" ])) if (self.getHealthPercentage() <= self.LOW_HP_PERCT): # we need some health return self.getScheduleByName("GET_HP_FROM_BARREL") if self.hasConditions(COND_SEE_FEAR): return self.getScheduleByName("TAKE_COVER_FROM_ORIGIN") if self.npcState in [STATE_IDLE, STATE_ALERT]: if self.hasConditions(COND_LIGHT_DAMAGE | COND_HEAVY_DAMAGE): return self.getScheduleByName("TAKE_COVER_FROM_ORIGIN") elif self.hasConditions(COND_HEAR_SOMETHING): return self.getScheduleByName("ALERT_FACE") sched = self.getScheduleByName("MAINTAIN_FOLLOW_TARGET") if CIGlobals.isNodePathOk( self.followTarget) and not self.followTarget.isDead(): if self.getDistance(self.followTarget ) <= 15.0 and self.followTarget.getHealth( ) < self.followTarget.getMaxHealth(): return self.getScheduleByName("HEAL_FOLLOW_TARGET") if not self.hasConditions(sched.interruptMask): return sched return BaseNPCAI.getSchedule(self)
def think(self): BaseAttackAI.think(self) if (self.action == self.StateAttack and self.getActionTime() >= self.WaitForSprayTime and not self.didAttack): self.didAttack = True self.doTraceAndDamage(self.traceOrigin, self.traceVector, self.AttackRange) self.target = None elif (self.action == self.StateAttack and self.getActionTime() < self.StopLockOnTime): if CIGlobals.isNodePathOk(self.target): self.avatar.headsUp(self.target) elif (self.action == self.StateAttack and not self.calibrated): self.calibrate() self.calibrated = True
def throw(self, p): if not self.owner or not CIGlobals.isNodePathOk(self.owner.avatar): return self.isAirborne = True self.owner.avatar.play('pie', partName='torso', fromFrame=62) base.playSfx(self.owner.throwSound, node=self.owner.avatar) start = NodePath('StartPath') start.reparentTo(self.owner.avatar) start.setScale(render, 1) start.setPos(0, 0, 0) start.setP(p) end = NodePath('ThrowPath') end.reparentTo(start) end.setScale(render, 1) end.setPos(0, 160, -35) end.setHpr(90, -90, 90) self.wrtReparentTo(render) self.setScale(1.0) self.throwIval = ProjectileInterval( self, startPos=self.owner.avatar.find('**/def_joint_right_hold').getPos( render), endPos=end.getPos(render), gravityMult=0.9, duration=2) self.throwIval.start() if self.owner.avId == base.localAvatar.doId: self.accept('snowball-coll-' + str(id(self)) + '-into', self.__handleSnowballCollision) start.removeNode() del start end.removeNode() del end
def think(self): BaseHitscanAI.think(self) if self.action == self.StateFire: if self.isAIUser(): if CIGlobals.isNodePathOk(self.target): self.avatar.headsUp(self.target) self.calibrate(self.target) else: return if (self.gumballsToFire > 0 and globalClock.getFrameTime() >= self.nextFireTime): throwVector = PhysicsUtils.getThrowVector( self.traceOrigin, self.traceVector, self.fireOrigin, self.avatar, self.avatar.getBattleZone().getPhysicsWorld()) endPos = CIGlobals.extrude(self.fireOrigin, self.FirePower, throwVector) - (0, 0, 90) if self.isAIUser(): endPos = endPos + Point3(random.uniform(-2.5, 2.5), random.uniform(-2.5, 2.5), random.uniform(-2.5, 2.5)) self.takeAmmo(-1) self.fireProjectile(endPos) self.gumballsToFire = self.gumballsToFire - 1 if (self.gumballsToFire > 0): self.nextFireTime = globalClock.getFrameTime( ) + random.uniform(self.MIN_BURST_DELAY, self.MAX_BURST_DELAY)
def setAvatar(self, avatar): self.avatar = avatar if CIGlobals.isNodePathOk(self.avatar): base.audio3d.attachSoundToObject(self.drawSfx, self.avatar) if self.hitSfx: base.audio3d.attachSoundToObject(self.hitSfx, self.avatar)
def hasAvatar(self): return CIGlobals.isNodePathOk(self.avatar)
def hasEyeTarget(self): if isinstance(self.eyeTarget, NodePath): return CIGlobals.isNodePathOk(self.eyeTarget) return self.eyeTarget is not None
def destroyFriendButton(self): if CIGlobals.isNodePathOk(self.friendButton): self.friendButton.destroy() self.friendButton = None
def hasPupils(self): return CIGlobals.isNodePathOk( self.__lpupil) and CIGlobals.isNodePathOk(self.__rpupil)