Jump to content
Korean Random
VasyaPRO_2014

Python и расстояние до врагов

Recommended Posts

Помогите найти расстояние до врагов в python.
Пробовал сам, но не думаю, что это лучший способ:

import BigWorld
import math
myPosition = BigWorld.player().getOwnVehiclePosition()
for pl in list(BigWorld.player().vehicles):
    if BigWorld.player().arena.vehicles[pl.id]['team'] == BigWorld.player().team:
        continue
    else:
        enemyPosition = pl.position
        distance = math.sqrt(pow(math.sqrt(pow(list(myPosition)[0] - list(enemyPosition)[0], 2) + pow(list(myPosition)[2] - list(enemyPosition)[2], 2)), 2) + pow(list(myPosition)[1] - list(enemyPosition)[1], 2))#Да да, мои познания в геометрии ограничиваются теоремой Пифагора :D

Для чего это нужно спросите вы? Хочу сделать мод, что-бы отображать на экране (Конечно же с помощью BigWorld.GUI ибо я нисмог в AS) что-то типа "Внимание ренген! ​Отьедь ракал", а потом когда отьехал "осталось 10сек,9,8....".

И ещё очень важный вопрос как организовать постоянную проверку? Пробовал с помощью BigWorld.callback() с интервалом в 0.5сек. Производительность оставляет желать лучшего. Должен же быть нормальный способ.

Share this post


Link to post

Short link
Share on other sites

 

 

Должен же быть нормальный способ.
уже есть нормальный готовый мод. "атас "

Share this post


Link to post

Short link
Share on other sites

Идейка мода норм :)

В моде таймер сведения орудия смотри (в версии автора)

Насчет ас, в исходниках мода спотера есть же код использования флешки, если не поймешь в лс пиши

И выведди это все в нормальный вид

Нахрена тут else, проще сделать так if not player .....

И зачем pl пихать в лист?

 

import BigWorld
import math
def position():
    player = BigWorld.player()
    myPosition = player.getOwnVehiclePosition()
    if player is not None:
        if not player.arena.vehicles.get(player.playerVehicleID)['team'] == player.team:
            enemyPosition = player.position
            distance = math.sqrt(pow(math.sqrt(pow(list(myPosition)[0] - list(enemyPosition)[0], 2) + pow(list(myPosition)[2] - list(enemyPosition)[2], 2)), 2) + pow(list(myPosition)[1] - list(enemyPosition)[1], 2))
    BigWorld.callbak(0.1, position)
Edited by Ekspoint

Share this post


Link to post

Short link
Share on other sites

уже есть нормальный готовый мод. "атас "

Немного не то, что я хочу.

В моде таймер сведения орудия смотри (в версии автора)

Где можно глянуть исходники?

Насчет ас, в исходниках мода спотера есть же код использования флешки, если не поймешь в лс пиши

Попробую.

Нахрена тут else, проще сделать так if not player .....

Тупанул)

И зачем pl пихать в лист?

Ибо это set и я не знаю как обратиться к его элементам.

if not player.arena.vehicles.get(player.playerVehicleID)['team'] == player.team:

А разве оно так будет проверять всех игроков? И цикл вовсе не нужен? У меня не рабоает.

Share this post


Link to post

Short link
Share on other sites

Чуть менее чем полностью не понимаю код.))
1. updateOwnVehiclePosition Особно не вникал, что делает. Но по идее должен выполнятся когда игрок в движении. Не понимаю зачем при каждом движении запускать кучу callback'ов + это ещё и не работает (по крайней мере у меня).
2.

   if player is not None:
        for vehicle in BigWorld.entities.values():
            if True: # if not player.team == player.arena.vehicles[vehicle.id]['team']:
                distance = get_aim_distance()
                print 'дистанция до враг а %s м' % distance
                if distance == 50:
                    print 'хватит ренгенить падла'
    BigWorld.callbak(0.1, x_ray_position)

Почему BigWorld.entities? Ввел len(BigWorld.entities) - получил 133 в тренировке с тремя игроками.
if distance == 50: думаю стоит заменить на if distance <= 50:
BigWorld.callback(0.1, x_ray_position) - Тут хоть понял - опечатка)
3.

def get_aim_distance():
    player = BigWorld.player()
    x, y, z = player.gunRotator.markerInfo[0]
    v = player.getOwnVehiclePosition() - Math.Vector3(x, y, z)
    return int(v.length)

И тут взорвался мой моск. Почему player.gunRotator.markerInfo[0]?
v = player.getOwnVehiclePosition() - Math.Vector3(x, y, z) - а эту магию я вообще не понимаю. Если я правльно понимаю, то каким то хитрым способом узнается дистанция от точки на которую смотрит игрок к центру своего танка. Но зачем это делать (тем более 133 раза в 0.1сек) я не понимаю.

Share this post


Link to post

Short link
Share on other sites
def distance_to_vehicle(vehicle):
    if vehicle is not None and BigWorld.player().vehicle is not None:
        return (vehicle.position - BigWorld.player().getOwnVehiclePosition()).length
    return 10000

и всё. на вход подаёте танк противника, к примеру.

на выходе получаете дистанцию до него, либо 10000, дескать дистанция не определена.

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

import BigWorld
from Avatar import PlayerAvatar

def target_distance(player, vehicle):
    distance = (player.getOwnVehiclePosition() - vehicle.position).length
    return int(distance)

  
def x_ray_position(vehicle):
    try:  
        player = BigWorld.player()
        if vehicle is not None and player.vehicle is not None:
            if not player.team == player.arena.vehicles[vehicle.id]['team']:
                if target_distance(player, vehicle) <= 50:
                    print 'хватит ренгенить падла'
    except:
        pass
    BigWorld.callback(1, lambda: x_ray_position(vehicle))
   

def new_vehicle_onEnterWorld(self, vehicle):
    old_vehicle_onEnterWorld(self, vehicle)
    x_ray_position(vehicle)


old_vehicle_onEnterWorld = PlayerAvatar.vehicle_onEnterWorld
PlayerAvatar.vehicle_onEnterWorld = new_vehicle_onEnterWorld

callback стоит для того что бы данные обновлялись

считай что мод уже готов :), приделать флешку и готов

Edited by Ekspoint
  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

@spoter,@Ekspoint, Спасибо большое.

Дописал костылей GUI.

Внимание, то что написано ниже имеет огромною концентрацию велосипедов на 1 байт кода.

Код полюбому требует переписывания и выложен в чисто ознакомительных целях (Чисто поржать).

# -*- coding: utf-8 -*-
import BigWorld
import GUI
import Keys
import game
from gui import InputHandler
from gui.app_loader import g_appLoader
from Avatar import PlayerAvatar
from gui.Scaleform.Battle import Battle

def target_distance(player, vehicle):
    distance = (player.getOwnVehiclePosition() - vehicle.position).length
    return int(distance)

def x_ray_position(vehicle):
    global xRays
    try:
        player = BigWorld.player()
        if vehicle is not None and player.vehicle is not None:
            if not vehicle.isAlive(): #Удалить дохлых врагов
                if vehicle.id in xRays:
                    del xRays[vehicle.id]
                return
            #print target_distance(player, vehicle)
            if target_distance(player, vehicle) <= 50:
                xRays[vehicle.id]=True
            else:
                xRays[vehicle.id]=False
            if True in xRays.values(): #Это бы по хорошему убрать отсюда, но куда и как я хз?
                timer.stop()
                ss.text = 'X-Ray'
            elif ss.text == 'X-Ray':
                timer(10)
    except:
        pass
    BigWorld.callback(1.0, lambda: x_ray_position(vehicle))# Внимание утечка памяти (а может и нет=D)! Если враги не подохнут до конца боя то колбэк скорее всего ни куда не денеться что какбы не очень хорошо
    #Скорее всего нужно хранить callbackID всех живих врагов и потом вручную их отменять (мне лень, плюс в коде и без этого достаточно костылей)

def new_vehicle_onEnterWorld(self, vehicle):
    old_vehicle_onEnterWorld(self, vehicle)
    player=BigWorld.player()
    if vehicle is not None and player is not None:
        if not player.team == player.arena.vehicles[vehicle.id]['team']: #добавлять только врагов
            x_ray_position(vehicle)

old_vehicle_onEnterWorld = PlayerAvatar.vehicle_onEnterWorld
PlayerAvatar.vehicle_onEnterWorld = new_vehicle_onEnterWorld

ss = GUI.Text('spottedStatus')# Собственно сам GUI
ss.position = (0, 0.7, 1) #Идеально выбраная позиция (на самом деле нет)

def inject_handle_key_event(event): #Ручной запуск таймера (к примеру заехал в сейв нажал кнопку - видишь таймер)
    is_down, key, mods, is_repeat = game.convertKeyEvent(event)
    isInBattle = g_appLoader.getDefBattleApp()
    try:
        if isInBattle:
            if key is Keys.KEY_B and is_down: #Кнопка B
                timer.stop()
                timer(10)
    except Exception as e:
        print ('error in inject_handle_key_event', e)

InputHandler.g_instance.onKeyDown += inject_handle_key_event
InputHandler.g_instance.onKeyUp += inject_handle_key_event

class SpottedTimer: #Уже и не помню зачем создавал класс =D
    def __call__(self,t):
        self.timer=t
        self.update()
    def update(self):
        try:
            #print 'timer =',self.timer
            if self.timer>0:
                ss.text = 'Spotted %d sec' % self.timer
                self.timer-=1
                self.cbID=BigWorld.callback(1.0,self.update)
            else:
                ss.text = 'Maybe lost'
        except Exception as err:
            print err
    def stop(self):
        try:
            BigWorld.cancelCallback(self.cbID)
        except (AttributeError,ValueError):
            pass

old_showSixthSenseIndicator = Battle._showSixthSenseIndicator
def new_showSixthSenseIndicator(self, isShow): #Таймер при лампочке
    old_showSixthSenseIndicator(self, isShow)
    timer(10) #Думаю тут лучше поставить 7сек. Правда?
Battle._showSixthSenseIndicator = new_showSixthSenseIndicator

old_beforeDelete = Battle.beforeDelete
def new_beforeDelete(self):
    old_beforeDelete(self)
    GUI.delRoot(ss)
Battle.beforeDelete = new_beforeDelete

old_afterCreate = Battle.afterCreate
def new_afterCreate(self):
    global xRays,timer
    old_afterCreate(self)
    xRays={}
    GUI.addRoot(ss)
    ss.text = 'Never seen'
    timer=SpottedTimer()
Battle.afterCreate = new_afterCreate

Буду очень рад, если у кого нибудь появиться желание написать нормальний gui на as. И заодно логику поменять ибо на это стыдно смотреть)

Share this post


Link to post

Short link
Share on other sites

Напиши в личку свой скайп если есть, завтра напишу и помогу

Мдя, ну и классы у тебя

vehicle_onEnterWorld Это тоже самое что и afterCreate

Вызывая afterCreate и бефор в реплее ломает все нахрен вот я и вызываю в vehicle_onEnterWorld

Share this post


Link to post

Short link
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...