def onBulletCollision(victim, bulletStartPos, bulletSpeed, bulletDir, bulletPos, contacts, data): gunDescription = db.DBLogic.g_instance.getComponentByIndex( COMPONENT_TYPE.GUNS, data['gunID']) if IS_CLIENT: for bulletId in data['bullets']: if bulletId != None: BigWorld.removeBullet(bulletId) Weapons.onClientBulletExplosion(gunDescription, contacts, data['isPlayer'], victim, bulletDir) else: shooter = BigWorld.entities.get(data['shooterID'], None) bIsTeamObject = isTeamObject(victim) if shooter and not victim.isDestroyed and ( not bIsTeamObject or shooter.teamIndex != victim.teamIndex): ammoDescription = db.DBLogic.g_instance.getComponentByIndex( COMPONENT_TYPE.AMMO, data['ammoID']) distEffectiveness = Weapons.calculateDistEffectiveness( gunDescription, ammoDescription, bulletStartPos, bulletPos) damage = Weapons.calculateBulletDamage( shooter, victim, gunDescription, bulletSpeed / WORLD_SCALING, ammoDescription, distEffectiveness) parts = [c[1] for c in contacts] victim.receiveBullet(shooter, parts, shooter.entityGroupMask, shooter.teamIndex, data['ammoID'], data['gunID'], data['modsActivity'], shooter.objTypeID, shooter.unitNumber, damage) shooter.onHitTarget([victim], DAMAGE_REASON.BULLET, ACTION_DEALER.PILOT) return
def isActive(self): if self._lockTargetId > 0: target = BigWorld.entities.get(self._lockTargetId) if target is not None and isTeamObject( target) and EntityStates.inState(target, EntityStates.GAME): return self._lockTargetDamage > _HotChickSkillTargetHPCfc * target.maxHealth self._lockTargetId = -1 return False
def _execute(self, entityId, triggerName, isOn): e = BigWorld.entities.get(entityId) if e is None: logEntityDoesNotExistError(entityId, self) return elif not isAvatar(e) and not isTeamObject(e): logNotSupportedEntityError(e, self) return else: e.controllers['modelManipulator'].setEffectVisible( triggerName, isOn) return 'out'
def _update(self): super(MultiStateBombTarget, self)._update() isOnTarget = False btPos = self._matrixProvider.position btScale = self._matrixProvider.hypotScale * bombMarkerCollisionRadius inZone = lambda ent: (ent.position - btPos).length < btScale for entity in BigWorld.entities.values(): if isTeamObject(entity) and canAimToEnemyEntity( self._player, entity) and inZone(entity): isOnTarget = True break self.setOnTarget(isOnTarget) self.__updateScaleFormHud()
def setOwner(self, owner): AvatarControllerBase.setOwner(self, owner) self.__pastTime = 0.0 self.__isMainEntityAvatar = False if not owner else isAvatar(owner) self._wrdh.setOwner(owner) if IS_CLIENT: if owner: self.__isPlayer = self._owner.isPlayer() self.__isOwnerAvatar = not isTeamObject(owner) self.__initClientUpdateCallBack() elif self.__updateCallBack: BigWorld.cancelCallback(self.__updateCallBack) self.__updateCallBack = None return
def _onInvalidSettings(self, message): if self._owner: if isTeamObject(self._owner): if IS_CLIENT: arenaSettings = db.DBLogic.g_instance.getArenaData( BigWorld.player().arenaType) else: arenaSettings = db.DBLogic.g_instance.getArenaData( self._owner.arenaType) objData = arenaSettings.getTeamObjectData( self._owner.arenaObjID) LOG_ERROR('TeamObject', message, objData['guid']) else: LOG_ERROR('Avatar', message, self._owner.globalID) else: LOG_ERROR(message)
def processTileDamage(self, targetID, startPos, targetImaginePos, damagePerTile, aliveTurretsCount, reduction): settings = self._ownerLogic.settings tileDir = targetImaginePos - startPos tileDir.normalise() tileNextTickPos = targetImaginePos + self._ownerLogic.gunDescription.bulletSpeed * 0.1 * tileDir tilePrevTickPos = targetImaginePos - self._ownerLogic.gunDescription.bulletSpeed * 0.1 * tileDir collidedParts = BigWorld.hm_collideParts(self._ownerEntity.spaceID, tilePrevTickPos, tileNextTickPos, self._ownerEntity) victim = None victimDist = 0 precisionK = 1.0 if collidedParts: for entity, partID, position in collidedParts: dist = (targetImaginePos - position).length if not isTeamObject(entity) and (not victim or dist < victimDist): victim = entity victimDist = dist else: victim = BigWorld.entities.get(targetID) if victim: victimDist = (victim.position - targetImaginePos).length precisionK = max( 1 - victimDist / self._ownerLogic.minDamageRadius, settings.minDamagePrc) if victim: planeTypeDamageK = settings.aircraftClassSettings.getDataForClassByGlobalID( victim.globalID)['damageK'] * self._ownerLogic.damageK damage = damagePerTile * precisionK * self._ownerLogic.TURRET_FOCUS * planeTypeDamageK * aliveTurretsCount * reduction if damage > 0: victim.receiveTurretDamage( self._ownerEntity, damage, self._ownerEntity.objTypeID, self._ownerEntity.entityGroupMask, self._ownerEntity.teamIndex, self._ownerEntity.unitNumber, settings.critAbility * self._ownerLogic.TURRET_INFLICT_CRIT, self._ownerLogic.targetSkillModsActivity, DAMAGE_REASON.BULLET, TurretDamageDealer.undefined) actionDealer = ACTION_DEALER.TURRET if self._ownerEntity.className in TEAM_OBJECT_CLASS_NAMES else ACTION_DEALER.GUNNER self._ownerEntity.onHitTarget([victim], DAMAGE_REASON.AA_EXPLOSION, actionDealer) return
def processTileDamage(self, targetID, startPos, targetImaginePos, damagePerTile, aliveTurretsCount, reduction): closestParts = BigWorld.hm_closestParts(self._ownerEntity.spaceID, targetImaginePos, self._ownerLogic.explosionRadius) if closestParts: victimsMap = {} for victim, partID, closestPos, dist in closestParts: isFriendlyVictim = victim.teamIndex == self._ownerEntity.teamIndex if not (isFriendlyVictim or isTeamObject(victim)): prevData = victimsMap.get(victim, (partID, dist)) if dist <= prevData[1]: victimsMap[victim] = (partID, dist) for victim, victimData in victimsMap.items(): partID, dist = victimData self.__onDamageToVictimPart(victim, dist, damagePerTile, aliveTurretsCount, reduction) else: victim = BigWorld.entities.get(targetID) if victim: self.__onDamageToVictimPart(victim, (targetImaginePos - victim.position).length, damagePerTile, aliveTurretsCount, reduction)
def onClientBulletExplosion(gd, contacts, isPlayer, victim, bulletDir): materialId = isTeamObject(victim) and 254 or 255 materialName = db.DBLogic.g_instance.getMaterialName(materialId) if hasattr(gd.explosionParticles, materialName): explosionEffectName = gd.explosionParticles.__dict__[materialName] else: explosionEffectName = gd.explosionParticles.default if explosionEffectName: import Avatar for position, partID, bbox, armor in contacts: Avatar.onBulletExplosion( Effects.getEffectId(explosionEffectName), isPlayer, position, bulletDir if materialName == 'aircraft' else None, victim) if isPlayer: Weapons.debug_addBulletCollisionEffects( explosionEffectName) Weapons.debug_drawBulletCollisionLines(position) return
def setTarget(self, entity): if not self.__inited: self.__createTarget() if entity is not None and isAvatar(entity): self.__matrixProvider.target = entity.matrix self.__deflectionTarget(entity) self.__offsetMtx.target = self.__matrixProvider self.__centerPointOffsetMtx.target = self.__matrixProvider if COLLISION_RECORDER: self.__matrixProvider.targetEntity = entity else: self.__matrixProvider.target = None self.__deflectionTarget(None) if entity is not None and TEAM_OBJECT_PARALLAX_ENABLED and isTeamObject( entity): self.__offsetMtx.target = entity.matrix self.__centerPointOffsetMtx.target = entity.matrix else: self.__offsetMtx.target = None self.__centerPointOffsetMtx.target = None if COLLISION_RECORDER: self.__matrixProvider.targetEntity = None return
def doUnownedExplosion(spaceID, bulletPos, explosionRadius, explosionRadiusEffective, explosionDamage, teamIndex, damageReason=DAMAGE_REASON.COMMON_EXPLOSION): """ Perform unowned explosion in specified point with specified params """ closestParts = BigWorld.hm_closestParts(spaceID, bulletPos, explosionRadius) if not closestParts: return else: victimsMap = collections.defaultdict(list) for victim, partId, closestPos, dist in closestParts: if victim.teamIndex != teamIndex: victimsMap[victim].append((partId, dist)) normalizeVictimsPartsMap(victimsMap) for victim, victimParts in victimsMap.iteritems(): victimData = db.DBLogic.g_instance.getDestructibleObjectData( victim) damagedParts = [] storePartId = -1 storeDamage = -1 if isTeamObject(victim): numParts = len(victimParts) else: numParts = 1 for partId, dist in victimParts: victimPartData = getEntityPartDataByID( victim, partId, victimData) if victimPartData: damage = 1.0 if dist < explosionRadiusEffective: damage *= explosionDamage / numParts elif dist <= explosionRadius: distK = (explosionRadius - dist) / ( (explosionRadius - explosionRadiusEffective) * numParts) damage *= explosionDamage * distK else: LOG_ERROR( 'doUnownedExplosion : dist > explosionRadius, ', partId, 'for object', victim.id) if damage > 0: damagedParts.append({ 'key': partId, 'value': damage }) else: LOG_ERROR('Invalid partID', partId, 'for object', victim, victim.id) if storeDamage > 0 and storePartId != -1: damagedParts.append({ 'key': storePartId, 'value': storeDamage }) if damagedParts: victim.receiveExplosiveDamage(None, damagedParts, 0, teamIndex, damageReason, 0) return
def doExplosiveDamage(owner, bulletPos, explosionRadius, explosionRadiusEffective, explosionDamage, damageReason=DAMAGE_REASON.COMMON_EXPLOSION): try: spaceID = owner.spaceID except: return closestParts = BigWorld.hm_closestParts(spaceID, bulletPos, explosionRadius) if not closestParts: return victimsMap = {} for victim, partId, closestPos, dist in closestParts: isFriendlyVictim = victim.teamIndex == owner.teamIndex if not (isFriendlyVictim and isTeamObject(victim)): victimParts = victimsMap.get(victim, []) if not victimParts: victimsMap[victim] = victimParts victimParts.append((partId, dist)) normalizeVictimsPartsMap(victimsMap) for victim, victimParts in victimsMap.items(): victimData = db.DBLogic.g_instance.getDestructibleObjectData( victim) damagedParts = [] storePartId = -1 storeDamage = -1 if isTeamObject(victim): numParts = len(victimParts) else: numParts = 1 isFriendlyVictim = victim.teamIndex == owner.teamIndex for partId, dist in victimParts: victimPartData = getEntityPartDataByID(victim, partId, victimData) if victimPartData: if isFriendlyVictim: if damageReason == DAMAGE_REASON.BOMB_EXPLOSION: damage = BOMB_ALLY_DAMAGE elif damageReason == DAMAGE_REASON.ROCKET_EXPLOSION: damage = owner.SETTINGS.ROCKET_ALLY_DAMAGE else: damage = 1.0 elif isAvatar( victim ) and damageReason == DAMAGE_REASON.BOMB_EXPLOSION: damage = BOMB_ENEMY_DAMAGE else: damage = 1.0 if dist < explosionRadiusEffective: damage *= explosionDamage / numParts elif dist <= explosionRadius: damage *= explosionDamage * ( explosionRadius - dist) / ( (explosionRadius - explosionRadiusEffective) * numParts) else: LOG_ERROR( 'doExplosiveDamage : dist > explosionRadius, ', partId, 'for object', victim, victim.id) if damage > 0: damagedParts.append({'key': partId, 'value': damage}) else: LOG_ERROR('Invalid partID', partId, 'for object', victim, victim.id) if storeDamage > 0 and storePartId != -1: damagedParts.append({'key': storePartId, 'value': storeDamage}) if damagedParts: victim.receiveExplosiveDamage(owner, damagedParts, owner.entityGroupMask, owner.teamIndex, damageReason, owner.unitNumber) owner.onHitTarget(victimsMap.iterkeys(), damageReason, ACTION_DEALER.PILOT)
def __calcGunShootData(self, historyLayer, group, gun, gd, shootPosition, shootOrientation, bulletTime): bulletStartPos = shootPosition + shootOrientation.rotateVec( gun.posDelta) rnd = group.syncedRandom.random() externalModifiers = self._owner.controllers.get( 'externalModifiers', None) if hasattr(self._owner, 'controllers') else None autoAim = externalModifiers.modifiers.AUTO_AIM if externalModifiers else 1 reductionDir = gun.reductionDir( self._wrdh.getLocalShootDirection(shootOrientation)) if AUTOGIDER_ENABLED and autoAim: autoAimAngleMod = externalModifiers.modifiers.AUTOAIM_ANGLE if externalModifiers else 1 aimAxis, aimAngle, entityId = self._owner.autoAim( historyLayer, bulletStartPos, shootOrientation.rotateVec(reductionDir), gd.bulletSpeed, gd.bulletFlyDist, bulletTime, AUTOGUIDER_ANGLE_GROUND, group.autoguiderAngle, autoAimAngleMod) entity = BigWorld.entities.get(entityId) if entity: autogiuderAngle = AUTOGUIDER_ANGLE_GROUND if isTeamObject( entity) else group.autoguiderAngle dist = (self._owner.position - entity.position).length norm = min(dist / gd.bulletFlyDist, 1.0) k = AUTOGUIDER_SCALE_MINDIST * ( 1 - norm) + AUTOGUIDER_SCALE_MAXDIST * norm if aimAngle < k * autogiuderAngle * autoAimAngleMod: aimAngleNorm = aimAngle / (autogiuderAngle * k * autoAimAngleMod) smoothCfc = MathExt.clamp( 0.0, 1 - (aimAngleNorm - AUTOGUIDER_SMOOTH_ANGLE) / (1 - AUTOGUIDER_SMOOTH_ANGLE), 1.0) if aimAngleNorm <= AUTOGUIDER_FULL_POWER_ANGLE: autoguiderEdge = AUTOGUIDER_EDGE_MIN else: autoguiderEdge = AUTOGUIDER_EDGE_MIN + math.pow( (aimAngleNorm - AUTOGUIDER_FULL_POWER_ANGLE) / (1 - AUTOGUIDER_FULL_POWER_ANGLE), AUTOGUIDER_SMOOTH_POWER) * (AUTOGUIDER_EDGE_MAX - AUTOGUIDER_EDGE_MIN) angularArgument = Angle(getEntityVector(self._owner), getEntityVector(entity)) if angularArgument > math.pi * 0.5: angularArgument = math.pi - angularArgument angularNorm = MathExt.clamp( 0.0, (angularArgument - AUTOGUIDER_ANGULAR_MIN_PLATO) / (AUTOGUIDER_ANGULAR_MAX_PLATO - AUTOGUIDER_ANGULAR_MIN_PLATO), 1.0) angularCfc = MathExt.lerp(AUTOGUIDER_ANGULAR_MIN_EFFECT, 1.0, angularNorm) if rnd >= autoguiderEdge: minAngle = aimAngle * AUTOGIDER_ANGLE_SCALE * smoothCfc * angularCfc else: minAngle = aimAngle * AUTOGIDER_ANGLE_SCALE * rnd * smoothCfc * angularCfc self.__tempQuat.fromAngleAxis(minAngle, aimAxis) shootOrientation = self.__tempQuat.mul(shootOrientation) axisRnd, powRnd = group.syncedRandom.random( ), group.syncedRandom.random() shootDirection = self.__calculateBulletDir(shootOrientation, group, reductionDir, axisRnd, powRnd) bulletMinFlightDist = self._owner.settings.airplane.flightModel.weaponOptions.bulletMinFlightDist distDispersion = bulletMinFlightDist + (1 - bulletMinFlightDist) * rnd return (bulletStartPos, shootDirection * gd.bulletSpeed, gd.bulletFlyDist * distDispersion / gd.bulletSpeed, axisRnd, powRnd)