kharlashkin Posted July 9, 2014 Share Posted July 9, 2014 (edited) Доброе время суток всем форумчанам и гостям! Интересуюсь следующей возможностью (может кто встречал или подскажет направление) - хочется для более комфортной стрельбы геймпадом увеличить точку прицела в игре до "пятна", например как в Crysis. P.S. Требуется вот для чего, на любой дистанции если нет "подсветки" контура врага/союзника, расчет выстрела снаряда делается отдельной формулой (может я не прав - поправьте меня). В случае пятна прицела (не точки) танк будет подсвечиваться даже когда край пятна попадет на контуры, соответственно формула полета снаряда применяется, соответственно будет проще попадать, как бонус можно попробовать сделать автодоводку прицела ;) Edited July 9, 2014 by kharlashkin @ Quote Link to comment Short link Share on other sites More sharing options...
TornadoCat Posted July 9, 2014 Share Posted July 9, 2014 Как вариант - декомпильнуть дефолтный прицел в Sothink, найти пнг-шку или спрайт с точкой (в дефолте присутствует) и намалевать чего то своё @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted July 9, 2014 Author Share Posted July 9, 2014 (edited) Как вариант - декомпильнуть дефолтный прицел в Sothink, найти пнг-шку или спрайт с точкой (в дефолте присутствует) и намалевать чего то своё Не-не-не, мне не нужна картинка :) Нужно поведение прицела, как для консольных игр. Я наверное не совсем внятно описал что к чему. Есть так называемый круг сведения, т.е. случайным образом снаряд летит в любую точку внутри этого круга. Есть так называемый прицел, который по сути является точкой по середине экрана. Существуют формулы полета снаряда, и если прицел наведен на танк и танк подсвечен - в формулу добавляется расстояние до цели. Необходимо каким-то образом подсвечивать танк, когда он находиться в кругу сведения, ведь тогда будет в формуле учитываться расстояние до этого танка и с большей вероятностью снаряд влетит в танк (чем если целиться рядом с противником, особенно когда он не подсвечен). Учитывая клиент-серверную архитектуру игры, наверное это невозможно, но я - я ж просто спрашиваю. Edited July 9, 2014 by kharlashkin @ Quote Link to comment Short link Share on other sites More sharing options...
Наталья19 Posted July 11, 2014 Share Posted July 11, 2014 Не-не-не, мне не нужна картинка :) Нужно поведение прицела, как для консольных игр. Я наверное не совсем внятно описал что к чему. Есть так называемый круг сведения, т.е. случайным образом снаряд летит в любую точку внутри этого круга. Есть так называемый прицел, который по сути является точкой по середине экрана. Существуют формулы полета снаряда, и если прицел наведен на танк и танк подсвечен - в формулу добавляется расстояние до цели. Необходимо каким-то образом подсвечивать танк, когда он находиться в кругу сведения, ведь тогда будет в формуле учитываться расстояние до этого танка и с большей вероятностью снаряд влетит в танк (чем если целиться рядом с противником, особенно когда он не подсвечен). Учитывая клиент-серверную архитектуру игры, наверное это невозможно, но я - я ж просто спрашиваю. я понимаю чего вы хотите т это на самом деле интересно, дествительно, может есть гений, который это воплотит? @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted July 15, 2014 Author Share Posted July 15, 2014 Люди добрые, разбираю по-полочкам код прицеливания в игре, а именно папку "X:\Games\World_of_Tanks\res\scripts\client\avatarinputhandler\aimingsystems", прошу помощи... Согласиться ли кто прокомментировать код? '__init__.pyc' import BigWorld import Math from Math import Vector3, Matrix import math from AvatarInputHandler import mathUtils from AvatarInputHandler.mathUtils import MatrixProviders from ProjectileMover import collideDynamicAndStatic from debug_utils import LOG_CODEPOINT_WARNING class IAimingSystem(object): matrix = property(lambda self: self._matrix) def __init__(self): self._matrix = mathUtils.createIdentityMatrix() def destroy(self): pass def enable(self, targetPos): pass def disable(self): pass def getDesiredShotPoint(self): pass def handleMovement(self, dx, dy): pass def update(self, deltaTime): pass def getTurretJointMat(vehicleTypeDescriptor, vehicleMatrix, turretYaw = 0.0): turretOffset = vehicleTypeDescriptor.chassis['hullPosition'] + vehicleTypeDescriptor.hull['turretPositions'][0] turretJointMat = mathUtils.createRTMatrix(Vector3(turretYaw, 0, 0), turretOffset) turretJointMat.postMultiply(vehicleMatrix) return turretJointMat def getGunJointMat(vehicleTypeDescriptor, turretMatrix, gunPitch): gunOffset = vehicleTypeDescriptor.turret['gunPosition'] gunMat = mathUtils.createRTMatrix(Vector3(0, gunPitch, 0), gunOffset) gunMat.postMultiply(turretMatrix) return gunMat def getPlayerTurretMats(turretYaw = 0.0, gunPitch = 0.0): player = BigWorld.player() vehicleTypeDescriptor = player.vehicleTypeDescriptor vehicleMatrix = player.getOwnVehicleMatrix() turretMat = getTurretJointMat(vehicleTypeDescriptor, vehicleMatrix, turretYaw) return (turretMat, getGunJointMat(vehicleTypeDescriptor, turretMat, gunPitch)) def getPlayerGunMat(turretYaw = 0.0, gunPitch = 0.0): return getPlayerTurretMats(turretYaw, gunPitch)[1] def getTurretMatrixProvider(vehicleTypeDescriptor, vehicleMatrixProvider, turretYawMatrixProvider): turretOffset = vehicleTypeDescriptor.chassis['hullPosition'] + vehicleTypeDescriptor.hull['turretPositions'][0] return MatrixProviders.product(turretYawMatrixProvider, MatrixProviders.product(mathUtils.createTranslationMatrix(turretOffset), vehicleMatrixProvider)) def getGunMatrixProvider(vehicleTypeDescriptor, turretMatrixProvider, gunPitchMatrixProvider): gunOffset = vehicleTypeDescriptor.turret['gunPosition'] return MatrixProviders.product(gunPitchMatrixProvider, MatrixProviders.product(mathUtils.createTranslationMatrix(gunOffset), turretMatrixProvider)) def getTurretYawGunPitch(vehTypeDescr, vehicleMatrix, targetPos, compensateGravity = False): turretOffs = vehTypeDescr.hull['turretPositions'][0] + vehTypeDescr.chassis['hullPosition'] gunOffs = vehTypeDescr.turret['gunPosition'] speed = vehTypeDescr.shot['speed'] gravity = vehTypeDescr.shot['gravity'] if not compensateGravity else 0.0 return BigWorld.wg_getShotAngles(turretOffs, gunOffs, vehicleMatrix, speed, gravity, 0.0, 0.0, targetPos, False) def getDesiredShotPoint(start, dir, onlyOnGround = False, isStrategicMode = False): end = start + dir.scale(10000.0) if isStrategicMode: point1 = __collideStaticOnly(start, end) point2 = collideDynamicAndStatic(start, end, (BigWorld.player().playerVehicleID,), skipGun=isStrategicMode) if point1 is None or point2 is None: point = None else: dir = Math.Vector3(point2[0]) - Math.Vector3(point1[0]) point = (Math.Vector3(point1[0]) + dir.scale(0.5), None) else: point = collideDynamicAndStatic(start, end, (BigWorld.player().playerVehicleID,), skipGun=isStrategicMode) if point is not None: return point[0] elif not onlyOnGround: return shootInSkyPoint(start, dir) else: return return def shootInSkyPoint(startPos, dir): dirFromCam = dir start = startPos dirFromCam.normalise() vehicle = BigWorld.player().vehicle if vehicle is not None and vehicle.inWorld and vehicle.isStarted: shotPos = Math.Vector3(vehicle.appearance.modelsDesc['gun']['model'].position) shotDesc = vehicle.typeDescriptor.shot else: type = BigWorld.player().arena.vehicles[BigWorld.player().playerVehicleID]['vehicleType'] shotPos = BigWorld.player().getOwnVehiclePosition() shotPos += type.hull['turretPositions'][0] + type.turret['gunPosition'] shotDesc = type.shot dirAtCam = shotPos - start dirAtCam.normalise() cosAngle = dirAtCam.dot(dirFromCam) a = shotDesc['maxDistance'] b = shotPos.distTo(start) try: dist = b * cosAngle + math.sqrt(b * b * (cosAngle * cosAngle - 1) + a * a) except: dist = shotDesc['maxDistance'] LOG_CODEPOINT_WARNING() if dist < 0.0: dist = shotDesc['maxDistance'] finalPoint = start + dirFromCam.scale(dist) intersecPoint = BigWorld.player().arena.collideWithSpaceBB(start, finalPoint) if intersecPoint is not None: finalPoint = intersecPoint return finalPoint def __collideStaticOnly(startPoint, endPoint): res = None testRes = BigWorld.wg_collideSegment(BigWorld.player().spaceID, startPoint, endPoint, 128) if testRes is not None: res = (testRes[0], None) return res 'ArcadeAimingSystem.pyc' import BigWorld import Math from Math import Vector3, Matrix import functools import math from AvatarInputHandler import mathUtils, AimingSystems, cameras from AvatarInputHandler.AimingSystems import IAimingSystem from ProjectileMover import collideDynamic from debug_utils import LOG_WARNING import gun_rotation_shared class ArcadeAimingSystem(IAimingSystem): def __setDistanceFromFocus(self, value): shotPoint = self.getThirdPersonShotPoint() self.__cursor.distanceFromFocus = value posOnVehicleProv = self.positionAboveVehicleProv.value posOnVehicle = Vector3(posOnVehicleProv.x, posOnVehicleProv.y, posOnVehicleProv.z) camPos = self.matrix.translation triBase = camPos - posOnVehicle pivotToTarget = shotPoint - posOnVehicle camPosToTarget = shotPoint - camPos if triBase.dot(camPosToTarget) * triBase.dot(pivotToTarget) > 0: if self.__shotPointCalculator is not None: self.__adjustFocus() else: self.focusOnPos(shotPoint) return def __setVehicleMProv(self, value): self.__vehicleMProv = value self.__cursor.base = value def __setYaw(self, value): self.__cursor.yaw = value if self.__cursor.yaw > 2.0 * math.pi: self.__cursor.yaw -= 2.0 * math.pi elif self.__cursor.yaw < -2.0 * math.pi: self.__cursor.yaw += 2.0 * math.pi def __setPitch(self, value): self.__cursor.pitch = mathUtils.clamp(self.__anglesRange[0], self.__anglesRange[1], value) def __setAimMatrix(self, aimMatrix): self.__aimMatrix = aimMatrix self.__setDistanceFromFocus(self.distanceFromFocus) vehicleMProv = property(lambda self: self.__vehicleMProv, __setVehicleMProv) positionAboveVehicleProv = property(lambda self: self.__cursor.positionAboveBaseProvider) distanceFromFocus = property(lambda self: self.__cursor.distanceFromFocus, __setDistanceFromFocus) aimMatrix = property(lambda self: self.__aimMatrix, __setAimMatrix) yaw = property(lambda self: self.__cursor.yaw, __setYaw) pitch = property(lambda self: self.__cursor.pitch, __setPitch) def __init__(self, vehicleMProv, heightAboveTarget, focusRadius, aimMatrix, anglesRange, enableSmartShotPointCalc = True): IAimingSystem.__init__(self) self.__aimMatrix = aimMatrix self.__vehicleMProv = vehicleMProv self.__anglesRange = anglesRange self.__cursor = BigWorld.ThirdPersonProvider() self.__cursor.base = vehicleMProv self.__cursor.heightAboveBase = heightAboveTarget self.__cursor.focusRadius = focusRadius self.__shotPointCalculator = ShotPointCalculatorPlanar() if enableSmartShotPointCalc else None return def getPivotSettings(self): return (self.__cursor.heightAboveBase, self.__cursor.focusRadius) def setPivotSettings(self, heightAboveBase, focusRadius): self.__cursor.heightAboveBase = heightAboveBase self.__cursor.focusRadius = focusRadius def destroy(self): IAimingSystem.destroy(self) def enable(self, targetPos, turretYaw = None, gunPitch = None): if targetPos is not None: self.focusOnPos(targetPos) if turretYaw is not None and gunPitch is not None: self.__adjustFocus((turretYaw, gunPitch)) return def __adjustFocus(self, yawPitch = None): if self.__shotPointCalculator is None: return else: scanStart, scanDir = self.__getScanRay() self.focusOnPos(self.__shotPointCalculator.focusAtPos(scanStart, scanDir, yawPitch)) return def disable(self): pass def setModelsToCollideWith(self, models): self.__cursor.setModelsToCollideWith(models) def focusOnPos(self, preferredPos): vehPos = Matrix(self.__vehicleMProv).translation posOnVehicle = vehPos + Vector3(0, self.__cursor.heightAboveBase, 0) self.yaw = (preferredPos - vehPos).yaw xzDir = Vector3(self.__cursor.focusRadius * math.sin(self.__cursor.yaw), 0, self.__cursor.focusRadius * math.cos(self.__cursor.yaw)) pivotPos = posOnVehicle + xzDir self.pitch = self.__calcPitchAngle(self.__cursor.distanceFromFocus, preferredPos - pivotPos) self.__cursor.update(True) aimMatrix = self.__getLookToAimMatrix() aimMatrix.postMultiply(self.__cursor.matrix) self._matrix.set(aimMatrix) def __calcPitchAngle(self, distanceFromFocus, dir): fov = BigWorld.projection().fov near = BigWorld.projection().nearPlane yLength = near * math.tan(fov * 0.5) alpha = -self.__aimMatrix.pitch a = distanceFromFocus b = dir.length A = 2.0 * a * math.cos(alpha) B = a * a - b * b D = A * A - 4.0 * B if D > 0.0: c1 = (A + math.sqrt(D)) * 0.5 c2 = (A - math.sqrt(D)) * 0.5 c = c1 if c1 > c2 else c2 cosValue = (a * a + b * b - c * c) / (2.0 * a * b) if a * b != 0.0 else 2.0 if cosValue < -1.0 or cosValue > 1.0: LOG_WARNING('Invalid arg for acos: %f; distanceFromFocus: %f, dir: %s' % (cosValue, distanceFromFocus, dir)) return -dir.pitch beta = math.acos(cosValue) eta = math.pi - beta return -dir.pitch - eta else: return -dir.pitch def getDesiredShotPoint(self): scanStart, scanDir = self.__getScanRay() if self.__shotPointCalculator is None: return self.getThirdPersonShotPoint() else: return self.__shotPointCalculator.getDesiredShotPoint(scanStart, scanDir) return def getThirdPersonShotPoint(self): if self.__shotPointCalculator is not None: return self.__shotPointCalculator.aimPlane.intersectRay(*self.__getScanRay()) else: return AimingSystems.getDesiredShotPoint(*self.__getScanRay()) return def handleMovement(self, dx, dy): self.yaw += dx self.pitch += dy def update(self, deltaTime): self.__cursor.update(True) aimMatrix = self.__getLookToAimMatrix() aimMatrix.postMultiply(self.__cursor.matrix) self._matrix.set(aimMatrix) if self.__shotPointCalculator is not None: self.__shotPointCalculator.update(*self.__getScanRay()) return 0.0 def __getScanRay(self): scanDir = self.matrix.applyVector(Vector3(0, 0, 1)) scanStart = self.matrix.translation + scanDir * 0.3 return (scanStart, scanDir) def __getLookToAimMatrix(self): return Matrix(self.__aimMatrix) class _AimPlane(object): __EPS_COLLIDE_ARENA = 0.001 def __init__(self): self.__plane = Math.Plane() self.init(Vector3(0, 0, 0), Vector3(0, 0, 0)) def init(self, aimPos, targetPos): lookDir = targetPos - aimPos self.__lookLength = lookDir.length lookDir.normalise() self.__plane.init(targetPos, targetPos + Vector3(0, 0, 1), targetPos + Vector3(1, 0, 0)) self.__initialProjection = Vector3(0, 1, 0).dot(lookDir) def intersectRay(self, startPos, dir, checkCloseness = True, checkSign = True): collisionPoint = self.__plane.intersectRay(startPos, dir) projection = Vector3(0, 1, 0).dot(dir) tooClose = collisionPoint.distTo(startPos) - self.__lookLength < -0.0001 and checkCloseness parallelToPlane = abs(projection) <= _AimPlane.__EPS_COLLIDE_ARENA projectionSignDiffers = projection * self.__initialProjection < 0.0 and checkSign backwardCollision = (collisionPoint - startPos).dot(dir) <= 0.0 if tooClose or parallelToPlane or projectionSignDiffers or backwardCollision: return startPos + dir * self.__lookLength return collisionPoint class ShotPointCalculatorPlanar(object): MIN_DIST = 50 TERRAIN_MIN_ANGLE = math.pi / 6 aimPlane = property(lambda self: self.__aimPlane) def __init__(self): self.__vehicleMat = BigWorld.player().getOwnVehicleMatrix() self.__vehicleDesc = BigWorld.player().vehicleTypeDescriptor self.__aimPlane = _AimPlane() self.__getTurretMat = functools.partial(AimingSystems.getTurretJointMat, self.__vehicleDesc, self.__vehicleMat) def update(self, scanStart, scanDir): point, isPointConvenient = self.__testMouseTargetPoint(scanStart, scanDir) if isPointConvenient: self.__aimPlane.init(scanStart, point) def focusAtPos(self, scanStart, scanDir, yawPitch = None): scanPos, isPointConvenient = self.__testMouseTargetPoint(scanStart, scanDir) if not isPointConvenient: if yawPitch is not None: turretYaw, gunPitch = yawPitch gunMat = AimingSystems.getGunJointMat(self.__vehicleDesc, self.__getTurretMat(turretYaw), gunPitch) planePos = self.__aimPlane.intersectRay(gunMat.translation, gunMat.applyVector(Vector3(0, 0, 1)), False, False) else: planePos = self.__aimPlane.intersectRay(scanStart, scanDir, False) if scanStart.distSqrTo(planePos) < scanStart.distSqrTo(scanPos): return scanPos return planePos else: self.__aimPlane.init(scanStart, scanPos) return scanPos def getDesiredShotPoint(self, scanStart, scanDir): scanPos, isPointConvenient = self.__testMouseTargetPoint(scanStart, scanDir) if isPointConvenient: return scanPos planePos = self.__aimPlane.intersectRay(scanStart, scanDir) if scanStart.distSqrTo(planePos) < scanStart.distSqrTo(scanPos): return scanPos turretYaw, gunPitch = AimingSystems.getTurretYawGunPitch(self.__vehicleDesc, self.__vehicleMat, planePos, True) gunMat = AimingSystems.getGunJointMat(self.__vehicleDesc, self.__getTurretMat(turretYaw), gunPitch) aimDir = gunMat.applyVector(Vector3(0, 0, 1)) return AimingSystems.getDesiredShotPoint(gunMat.translation, aimDir) def __calculateClosestPoint(self, start, dir): dir.normalise() end = start + dir.scale(10000.0) testResTerrain = BigWorld.wg_collideSegment(BigWorld.player().spaceID, start, end, 128, lambda matKind, collFlags, itemId, chunkId: collFlags & 8) terrainSuitsForCheck = testResTerrain and testResTerrain[1].dot(Math.Vector3(0, 1, 0)) <= math.cos(ShotPointCalculatorPlanar.TERRAIN_MIN_ANGLE) testResNonTerrain = BigWorld.wg_collideSegment(BigWorld.player().spaceID, start, end, 136) testResDynamic = collideDynamic(start, end, (BigWorld.player().playerVehicleID,), False) closestPoint = None closestDist = 1000000 isPointConvenient = True if testResTerrain: closestPoint = testResTerrain[0] closestDist = (testResTerrain[0] - start).length if terrainSuitsForCheck: isPointConvenient = closestDist >= ShotPointCalculatorPlanar.MIN_DIST if testResNonTerrain is not None: dist = (testResNonTerrain[0] - start).length if dist < closestDist: closestPoint = testResNonTerrain[0] closestDist = dist isPointConvenient = closestDist >= ShotPointCalculatorPlanar.MIN_DIST if closestPoint is None and testResDynamic is None: return (AimingSystems.shootInSkyPoint(start, dir), True) else: if testResDynamic is not None: dynDist = testResDynamic[0] if dynDist <= closestDist: dir = end - start dir.normalise() closestPoint = start + dir * dynDist isPointConvenient = True return (closestPoint, isPointConvenient) def __testMouseTargetPoint(self, start, dir): closestPoint, isPointConvenient = self.__calculateClosestPoint(start, dir) turretYaw, gunPitch = AimingSystems.getTurretYawGunPitch(self.__vehicleDesc, self.__vehicleMat, closestPoint, True) if not isPointConvenient: minPitch, maxPitch = gun_rotation_shared.calcPitchLimitsFromDesc(turretYaw, self.__vehicleDesc.gun['pitchLimits']) pitchInBorders = gunPitch <= maxPitch + 0.001 isPointConvenient = not pitchInBorders if isPointConvenient: isPointConvenient = not self.__isTurretTurnRequired(dir, turretYaw, closestPoint) return (closestPoint, isPointConvenient) def __isTurretTurnRequired(self, viewDir, turretYawOnPoint, targetPoint): turretMat = self.__getTurretMat(turretYawOnPoint) turretPos = turretMat.translation gunPos = AimingSystems.getGunJointMat(self.__vehicleDesc, turretMat, 0.0).translation dirFromTurretPos = targetPoint - turretPos dirFromSniperPos = targetPoint - gunPos viewDir = Math.Vector3(viewDir) viewDir.y = 0 viewDir.normalise() dirFromSniperPos.y = 0 dirFromTurretPos.y = 0 return viewDir.dot(dirFromSniperPos) < 0 or viewDir.dot(dirFromTurretPos) < 0 'SniperAimingSystem.pyc' import BigWorld import Math import GUI from Math import Vector3, Matrix import math from AvatarInputHandler import mathUtils from AvatarInputHandler import AimingSystems from AvatarInputHandler.AimingSystems import IAimingSystem from AvatarInputHandler.Oscillator import Oscillator from gun_rotation_shared import calcPitchLimitsFromDesc from projectile_trajectory import getShotAngles class SniperAimingSystem(IAimingSystem): turretYaw = property(lambda self: self.__idealTurretYaw + self.__oscillator.deviation.x) gunPitch = property(lambda self: self.__idealGunPitch + self.__oscillator.deviation.y) __CONSTRAINTS_MULTIPLIERS = Vector3(1.0, 1.0, 1.0) __activeSystem = None @staticmethod def setStabilizerSettings(useHorizontalStabilizer, useVerticalStabilizer): SniperAimingSystem.__CONSTRAINTS_MULTIPLIERS.x = 1.0 if useHorizontalStabilizer else 0.0 SniperAimingSystem.__CONSTRAINTS_MULTIPLIERS.y = 1.0 if useVerticalStabilizer else 0.0 if SniperAimingSystem.__activeSystem is not None: SniperAimingSystem.__activeSystem.resetIdealDirection() return @staticmethod def getStabilizerSettings(): return (SniperAimingSystem.__CONSTRAINTS_MULTIPLIERS.x > 0.0, SniperAimingSystem.__CONSTRAINTS_MULTIPLIERS.y > 0.0) def __init__(self): IAimingSystem.__init__(self) self.__idealTurretYaw = 0.0 self.__idealGunPitch = 0.0 self.__worldYaw = 0.0 self.__worldPitch = 0.0 self.__vehicleTypeDescriptor = None self.__vehicleMProv = None self.__vehiclePrevMat = None self.__yprDeviationConstraints = Vector3(math.pi * 2.1, math.pi / 2 * 0.95, 0.0) self.__oscillator = Oscillator(1.0, Vector3(0.0, 0.0, 15.0), Vector3(0.0, 0.0, 3.5), self.__yprDeviationConstraints) return def destroy(self): IAimingSystem.destroy(self) SniperAimingSystem.__activeSystem = None return def enableHorizontalStabilizerRuntime(self, enable): yawConstraint = math.pi * 2.1 if enable else 0.0 self.__yprDeviationConstraints.x = yawConstraint def enable(self, targetPos): player = BigWorld.player() self.__vehicleTypeDescriptor = player.vehicleTypeDescriptor self.__vehicleMProv = player.getOwnVehicleMatrix() self.__vehiclePrevMat = Matrix(self.__vehicleMProv) IAimingSystem.enable(self, targetPos) player = BigWorld.player() desc = player.vehicleTypeDescriptor self.__yawLimits = desc.gun['turretYawLimits'] self.__idealTurretYaw, self.__idealGunPitch = getShotAngles(desc, player.getOwnVehicleMatrix(), (0, 0), targetPos, False) self.__idealTurretYaw, self.__idealGunPitch = self.__clampToLimits(self.__idealTurretYaw, self.__idealGunPitch) currentGunMat = AimingSystems.getPlayerGunMat(self.__idealTurretYaw, self.__idealGunPitch) self.__worldYaw = currentGunMat.yaw self.__worldPitch = (targetPos - currentGunMat.translation).pitch self._matrix.set(currentGunMat) self.__idealTurretYaw, self.__idealGunPitch = self.__worldYawPitchToTurret(self.__worldYaw, self.__worldPitch) self.__idealTurretYaw, self.__idealGunPitch = self.__clampToLimits(self.__idealTurretYaw, self.__idealGunPitch) self.__oscillator.reset() SniperAimingSystem.__activeSystem = self def disable(self): SniperAimingSystem.__activeSystem = None return def getDesiredShotPoint(self): start = self.matrix.translation scanDir = self.matrix.applyVector(Vector3(0, 0, 1)) return AimingSystems.getDesiredShotPoint(start, scanDir) def resetIdealDirection(self): self.__idealTurretYaw, self.__idealGunPitch = self.__worldYawPitchToTurret(self.__worldYaw, self.__worldPitch) self.__idealTurretYaw, self.__idealGunPitch = self.__clampToLimits(self.__idealTurretYaw, self.__idealGunPitch) def handleMovement(self, dx, dy): self.resetIdealDirection() self.__idealTurretYaw += dx self.__idealGunPitch += dy self.__idealTurretYaw, self.__idealGunPitch = self.__clampToLimits(self.__idealTurretYaw, self.__idealGunPitch) currentGunMat = AimingSystems.getPlayerGunMat(self.__idealTurretYaw, self.__idealGunPitch) self.__worldYaw = currentGunMat.yaw self.__worldPitch = currentGunMat.pitch self._matrix.set(currentGunMat) self.__oscillator.velocity = Vector3(0, 0, 0) def __clampToLimits(self, turretYaw, gunPitch): if self.__yawLimits is not None: turretYaw = mathUtils.clamp(self.__yawLimits[0], self.__yawLimits[1], turretYaw) desc = BigWorld.player().vehicleTypeDescriptor pitchLimits = calcPitchLimitsFromDesc(turretYaw, desc.gun['pitchLimits']) pitchLimitsMin = pitchLimits[0] pitchLimitsMax = pitchLimits[1] gunPitch = mathUtils.clamp(pitchLimitsMin, pitchLimitsMax, gunPitch) return (turretYaw, gunPitch) def __worldYawPitchToTurret(self, worldYaw, worldPitch): worldToTurret = Matrix(self.__vehicleMProv) worldToTurret.invert() worldToTurret.preMultiply(mathUtils.createRotationMatrix((worldYaw, worldPitch, 0))) return (worldToTurret.yaw, worldToTurret.pitch) def update(self, deltaTime): self.__oscillator.constraints = mathUtils.matrixScale(self.__yprDeviationConstraints, SniperAimingSystem.__CONSTRAINTS_MULTIPLIERS) vehicleMat = Matrix(self.__vehicleMProv) curTurretYaw, curGunPitch = self.__worldYawPitchToTurret(self.__worldYaw, self.__worldPitch) yprDelta = Vector3(curTurretYaw - self.__idealTurretYaw, curGunPitch - self.__idealGunPitch, 0) self.__oscillator.deviation = yprDelta self.__oscillator.update(deltaTime) curTurretYaw = self.__idealTurretYaw + self.__oscillator.deviation.x curGunPitch = self.__idealGunPitch + self.__oscillator.deviation.y curTurretYaw, curGunPitch = self.__clampToLimits(curTurretYaw, curGunPitch) yprDelta = Vector3(curTurretYaw - self.__idealTurretYaw, curGunPitch - self.__idealGunPitch, 0) self.__oscillator.deviation = yprDelta currentGunMat = AimingSystems.getPlayerGunMat(curTurretYaw, curGunPitch) self.__worldYaw = currentGunMat.yaw self.__worldPitch = currentGunMat.pitch self._matrix.set(currentGunMat) self.__vehiclePrevMat = vehicleMat return 0.0 'StrategicAimingSystem.pyc' import BigWorld import Math from Math import Vector3, Matrix import math from AvatarInputHandler import mathUtils, AimingSystems from AvatarInputHandler.AimingSystems import IAimingSystem from AvatarInputHandler.cameras import _clampPoint2DInBox2D class StrategicAimingSystem(IAimingSystem): _LOOK_DIR = Vector3(0, -math.cos(0.001), math.sin(0.001)) height = property(lambda self: self.__height) def __init__(self, height, yaw): self._matrix = mathUtils.createRotationMatrix((yaw, 0, 0)) self.__planePosition = Vector3(0, 0, 0) self.__height = height def destroy(self): pass def enable(self, targetPos): self.updateTargetPos(targetPos) def disable(self): pass def getDesiredShotPoint(self): return AimingSystems.getDesiredShotPoint(self._matrix.translation, Vector3(0, -1, 0), True, True) def handleMovement(self, dx, dy): shift = self._matrix.applyVector(Vector3(dx, 0, dy)) self.__planePosition += Vector3(shift.x, 0, shift.z) self.__updateMatrix() def updateTargetPos(self, targetPos): self.__planePosition.x = targetPos.x self.__planePosition.z = targetPos.z self.__updateMatrix() def __updateMatrix(self): bb = BigWorld.player().arena.arenaType.boundingBox pos2D = _clampPoint2DInBox2D(bb[0], bb[1], Math.Vector2(self.__planePosition.x, self.__planePosition.z)) self.__planePosition.x = pos2D[0] self.__planePosition.z = pos2D[1] collPoint = BigWorld.wg_collideSegment(BigWorld.player().spaceID, self.__planePosition + Math.Vector3(0, 1000.0, 0), self.__planePosition + Math.Vector3(0, -250.0, 0), 3) heightFromPlane = 0.0 if collPoint is None else collPoint[0][1] self._matrix.translation = self.__planePosition + Vector3(0, heightFromPlane + self.__height, 0) return @ Quote Link to comment Short link Share on other sites More sharing options...
Slava7572 Posted July 15, 2014 Share Posted July 15, 2014 Не-не-не, мне не нужна картинка :) Нужно поведение прицела, как для консольных игр. Я наверное не совсем внятно описал что к чему. Есть так называемый круг сведения, т.е. случайным образом снаряд летит в любую точку внутри этого круга. Есть так называемый прицел, который по сути является точкой по середине экрана. Существуют формулы полета снаряда, и если прицел наведен на танк и танк подсвечен - в формулу добавляется расстояние до цели. Необходимо каким-то образом подсвечивать танк, когда он находиться в кругу сведения, ведь тогда будет в формуле учитываться расстояние до этого танка и с большей вероятностью снаряд влетит в танк (чем если целиться рядом с противником, особенно когда он не подсвечен). Учитывая клиент-серверную архитектуру игры, наверное это невозможно, но я - я ж просто спрашиваю. Есть похожий мод(фиксация прицела).Наводишь на положение танка противника, зажимаешь кнопку и прицел наводится на то место с пересчитыванием траектории.Особенно помогает таким танкам как Е100 или 268 с "фугасной" траекторией.Правда не знаю, был ли апдейт под текущий патч, но в теме можете узнать. Есть еще нечто подобное(помимо автоприцела), но работа мода отличается, не вникал глубоко,но работа мода отличается,не вникал глубоко. 1 @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted July 15, 2014 Author Share Posted July 15, 2014 Есть похожий мод(фиксация прицела).Наводишь на положение танка противника, зажимаешь кнопку и прицел наводится на то место с пересчитыванием траектории.Особенно помогает таким танкам как Е100 или 268 с "фугасной" траекторией.Правда не знаю, был ли апдейт под текущий патч, но в теме можете узнать. Есть еще нечто подобное(помимо автоприцела), но работа мода отличается, не вникал глубоко,но работа мода отличается,не вникал глубоко. Ушёл курить темы, спасибо!P.S. За авторога отдельное спасибо! Вручную влом постоянно переставлять, а тут такой подарок. Правильный расчёт баллистики и расширенный автоприцел в принципе тоже "маст хэв". @ Quote Link to comment Short link Share on other sites More sharing options...
Slava7572 Posted July 15, 2014 Share Posted July 15, 2014 Ушёл курить темы, спасибо! P.S. За авторога отдельное спасибо! Вручную влом постоянно переставлять, а тут такой подарок. Правильный расчёт баллистики и расширенный автоприцел в принципе тоже "маст хэв". Да,крайне удобный мод,уже несколько патчей юзаю)) @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted July 16, 2014 Author Share Posted July 16, 2014 Написал создателю "Вычислителю Баллистического Мода" просьбу о предоставлении исходников для ковыряний. Думаю не даст, но натолкнул на мысль что мне подойдет замена луча в прицеле на угол. Может есть у кого исходники мода лазерного прицела? Думаю стоит поковырять их... @ Quote Link to comment Short link Share on other sites More sharing options...
StranikS_Scan Posted July 16, 2014 Share Posted July 16, 2014 Написал создателю "Вычислителю Баллистического Мода" просьбу о предоставлении исходников для ковыряний. Думаю не даст, но натолкнул на мысль что мне подойдет замена луча в прицеле на угол. Может есть у кого исходники мода лазерного прицела? Думаю стоит поковырять их... Скинул тебе исходники БалВыча в личку. 1 @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted July 16, 2014 Author Share Posted July 16, 2014 (edited) Скинул тебе исходники БалВыча в личку.Спасибо тебе, добрый человек!!! С разрешения уважаемого StranikS_Scan, выкладываю нашу личную переписку для понимания общей картины для жителей форума: Доброе время суток, изучаю тему относительно модернизации прицела. Как я понимаю в игре точка, являющаяся видимым прицелом, есть некий луч, который в Вашем моде сделали видимым. Интересует следующее - Ваше мнение каково, можно ли поменять луч (прицел) на телесный угол, скажем в 1 градус? Про порыться в исходниках и не спрашиваю... Ээээ, в моём это каком моде? Вы про лазеры? Тогда я скажу что ни какого отношения лазеры не имеют к прицелу и механизму прицеливания вообще. Лазер это модель в виде тонкого цветного цилиндра, которая добавляется в игру и жестко скрепляется с моделью пушки, в результате этот лазер перемещается вместе с пушкой. Почитал тему: 1. Вы правы в игре есть условный "дальномер", который показывает расстояние между центром вашего танка (обычно точка на вертикальной оси вращения башни, лежащая на уровне земли) и точкой куда показывает центр вашего прицела. Обратите внимание что именно вашего прицела, а не серверного. 2. Del 3. "В случае пятна прицела (не точки) танк будет подсвечиваться даже когда край пятна попадет на контуры" - да в принципе такое можно сделать, если проверять наличие танка в определенном радиусе от точки прицеливания 4. "соответственно формула полета снаряда применяется" - в формуле расчета выстрела фигурирует только дальность измеряемая дальномером из п.1. и эа цифра передается на сервер после чего сервер делает расчет траектории и сам выстрел. Если у вас вместо точки пятно - то какую цифру вы будете передавать серверу как дальность??? Передать можно только одну цифру, одна цифра соот. одной точке, а у вас область будет а не точка - так какую цифру передавать? 5. Судя по тому что вы пишите в теме. В вашем случае надо из всех точек области найти точку с минимальным расстояние и именно эту цифру и выдать как результат работы дальномера. Тогда да, если в моем пятне будет небо и кусочек танка, то дальномер вернет в качестве дальности расстояние до танка а не "неба" 6. Что касается реализации, то нужно написать алгоритм, который анализирует расстояние до n-точек в пределах r-радиуса (или на самой окружности r-радиуса, смотря как делать) от центра прицела. Думаю если n будет много, то будут жуткие тормоза, а если n будет мало, то мелкие краешки попадающие на границу такого пятна могут быть и не проанализированы. 7. Я на оф. форуме вроде выдел аналог БалВыча, в котором не нужно нажимать кнопку для фиксации расстояния, там какой алгоритм есть более хитрый, который не дает скакать дальномеру. Но думаю там просто таймер есть на время действия которого запоминается предыдущее значение дальномера при больших разностях в его показаниях. Поищите этот мод. 1. Значит не даром мое гугление прошло. 2. Спасибо! Буду курить скрипт. Небольшое отступление перед следующими пунктами. Более детальное взвешивание всех составляющих приводит к мысли 6-ти гранного конуса (сота в основании). Формула проста и подходит под параметры. 3. Проверять наличие танка в 7 точках (шестигранник или сота и центр). 4. Передавать точку из шестигранника, если более 2 одновременно наведены на цель, то среднее значение. 5. Оффтоп - фугасами будет интересно стрелять - можно и мод обозвать как фугасный прицел ;) 6. Вот это и хочу подсмотреть в скрипте (как вы выразились) БалВыча, а рассчитываться в игре будет то только одна точка, просто 7 будет проверяться. 7. Поищу, спасибо за подсказку. Я так понимаю, что цифра от центра соты "будет поступать" как базовая дальность, после чего будет проверка наличия моделей танков в 6 точках соты и если одна из них сработает, то дальность с нее будет использована вместо базовой, если сработает больше 1 вершины, то будет браться среднее/мин/макс... значение из их дальностей. Если ни одна вершина не сработает, то дальность останется базовой. В такой логике вроде нет изъянов. Качество работы будет зависеть от размеры соты и от критерия расчета дальности при "срабатывании" больше 1 вершины. Размер соты будет неплохо сделать динамическим. Соответственно надо отталкиваться от угла а не от размера соты, 1 или 2 градуса, методом проб можно подобрать, как и формулу расчета по вершинам. Я понимаю о каком конусе идёт речь, но если угол вращения константа, а мы видим только соту в основании 6-гранной пирамиды, то размер этой соты будет зависеть от расстояния от нас до базовой точки, значит по принципу перспективы будет так, когда я прицеливаюсь в даль размер соты будет большой, а когда смотрю на близкостоящий объект - то сота будет очень маленькой.... зачем такое нужно? мммм или нет, будет константа из-за перспективы? Не проще ли сначала сделать соту статического размера на экране прицела и глянуть что это даст? Если бы знать ещё как её делать ;) Я пока только в теории разбираюсь. Согласен, что сделать сотовый прицел статикой - это начало, но правильное понимание всей картины в целом тоже нужно, мое мнение имхо. Хотя иногда бывает, что лучше делать правильно изначально пусть и более трудоемко, как гласит пословица - "нет ничего более постоянного, чем временное". Разумеется что такой прицел будет сугубо аркадным (снайперский нужно оставить как есть), например для максимальной дальности обнаружения противника в 445 метров диаметр соты для конуса в 1о составит чуть менее 8 метров, но даст преимущество в захвате врага в автоприцел на высокой скорости, а так же будет правильные значения отправлять в игру при выстреле. Так что ХЗ как будет правильно. Буду курить скрипты и python. Хочу спросить разрешение выложить нашу переписку в темку. Да выложи, а то там не поняли что ты хочешь сделать Edited July 16, 2014 by kharlashkin @ Quote Link to comment Short link Share on other sites More sharing options...
BADoBEST Posted July 24, 2014 Share Posted July 24, 2014 @StranikS_Scan, @kharlashkin, прошу помощи! С каждым новым обновлением AvatarInputHandler нуждается в переделке. Я понятия не имею, где и как... Постоянно приходится выковыривать из чужих модпаков, а т.к. в последнее время многие устремились к ПМОДу (который мне не нравится), вообще не могу найти AvatarInputHandler. Помогите, пожалуйста, если это не сложно, объясните, что именно меняется от версии к версии. Ну или просто (если есть конечно) залейте AvatarInputHandler для 0.9.2. Заранее благодарен! @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted July 24, 2014 Author Share Posted July 24, 2014 @StranikS_Scan, @kharlashkin, прошу помощи! С каждым новым обновлением AvatarInputHandler нуждается в переделке. Я понятия не имею, где и как... Постоянно приходится выковыривать из чужих модпаков, а т.к. в последнее время многие устремились к ПМОДу (который мне не нравится), вообще не могу найти AvatarInputHandler. Помогите, пожалуйста, если это не сложно, объясните, что именно меняется от версии к версии. Ну или просто (если есть конечно) залейте AvatarInputHandler для 0.9.2. Заранее благодарен! Вообще непонятно... AvatarInputHandler - это "картохины" скрипты, для 0.9.2 я не качал тестовый клиент, но и не факт что те скрипты попадут в "продакшн". Если имеются ввиду какие-то модифицированные скрипты, то лучше наверное у создателей модов поспрашивать. @ Quote Link to comment Short link Share on other sites More sharing options...
StranikS_Scan Posted July 24, 2014 Share Posted July 24, 2014 (edited) У меня 0.9.2 нет, но могу написать как научиться делать такой мод на примере клиента 0.9.1. 1. AvatarInputHandler.xml орыыыгинальный хранится усегда в: c:\Games\World_of_Tanks\res\packages\gui.pkg\\gui\avatar_input_handler.xml Извлюкать мона любым архиватором так как это по сути zip-архив 2. Теперь его надо перекодировать из сжатого формата в обычный текстовый - берем идем в эту тему и качаем вот ету программу WotModTools - запускаем, пететаскиваем туда наш xml, видим читабельный текст, сохраняем его в тот же файл - открываем файл любым тектовым редактором и через Замена - Заменить всё, заменяем все запятые в тексте на точки В итоге получаем читабельную рабочую версию этого файла для 0.9.1. 3. Берем старый модифицированный файл avatar_input_handler.xml из темы скажем Старый серверный прицел 0.9.1 или из темы PMOD c баранками 0.9.1, открываем TotalCommander, выделяем наш новый avatar_input_handler.xml полученный в п.2. и старый модифицированный avatar_input_handler.xml, после чего жмякаем в главном меню - Сравнить файлы по содержимому. Далее сидим, курим и сравниваем в чем разница. Эта разница и есть - то что мододелы в нем изменили. Изучаем и запоминаем. 4. Теперь качаем 0.9.2 и делаем такой файлик уже самостоятельно.... 5. Не забываем что в папке res_mods чтобы этот файлик работал его класть надо вот так: c:\Games\World_of_Tanks\res_mods\0.9.1\gui\avatar_input_handler.xml Edited July 24, 2014 by StranikS_Scan 4 @ Quote Link to comment Short link Share on other sites More sharing options...
BADoBEST Posted July 24, 2014 Share Posted July 24, 2014 @StranikS_Scan, спасибо!файлы полученные в результате п.2 в 0.9.1 и 0.9.2_СТ - идентичны (запятых, кстати, не было изначально) . поместив этот файлик по указанному пути, результат тот же: в бой не заходит. не пускает папка AvatarInputHandler из (res_mods\0.9.2 Common Test\scripts\client) в которой aims.pyc и папка DynamicCameras с ArcadeCamera.pyc, SniperCamera.pyc и StrategicCamera.pyc. ЗЫ. может быть вы знаете автора мода, обращусь к нему. @ Quote Link to comment Short link Share on other sites More sharing options...
StranikS_Scan Posted July 24, 2014 Share Posted July 24, 2014 ArcadeCamera.pyc, SniperCamera.pyc и StrategicCamera.pyc. А вот про эти файлики я ни чего не писал выше. Именно эти файлики и не работают с 0.9.1 на 0.9.2, их авторы постарались чтоб они не робили :)))) @ Quote Link to comment Short link Share on other sites More sharing options...
BADoBEST Posted July 24, 2014 Share Posted July 24, 2014 я предположил, что т.к они находятся в папке AvatarInputHandler, то вы про них тоже что нибудь расскажете! но видать придется дальше "бороздить просторы", "в поисках утраченного" ))) @ Quote Link to comment Short link Share on other sites More sharing options...
StranikS_Scan Posted July 24, 2014 Share Posted July 24, 2014 я предположил, что т.к они находятся в папке AvatarInputHandler, то вы про них тоже что нибудь расскажете! но видать придется дальше "бороздить просторы", "в поисках утраченного" ))) Там шифрование стоит, вскрыть их не удастся. Попробуйте через авторов. Но они скорее всего напишу, ждите выхода патча, мы сами обновим, вы скачаете. Как-то так. 1 @ Quote Link to comment Short link Share on other sites More sharing options...
BADoBEST Posted July 24, 2014 Share Posted July 24, 2014 Попробуйте через авторов кто они? @ Quote Link to comment Short link Share on other sites More sharing options...
kharlashkin Posted July 24, 2014 Author Share Posted July 24, 2014 (edited) кто они? Евгений Киселев, [email protected], http://world-of-ru.livejournal.com/2805216.html, если Вы про БалВыч. Edited July 24, 2014 by kharlashkin @ Quote Link to comment Short link Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.