Skip to content

Commit

Permalink
Merge in tank disconnect changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
FGlazov committed May 1, 2023
1 parent 3d6bf15 commit 7e4a99f
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 28 deletions.
47 changes: 38 additions & 9 deletions src/mission_report/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
from itertools import count
import logging
import operator
from django.conf import settings

from mission_report.constants import COALITION_ALIAS
from mission_report.statuses import BotLifeStatus, SortieStatus, LifeStatus
from mission_report.helpers import distance, point_in_polygon, is_pos_correct
from mission_report import parse_mission_log_line

SORTIE_DAMAGE_DISCO_TIME = settings.SORTIE_DAMAGE_DISCO_TIME

logger = logging.getLogger('mission_report')


Expand Down Expand Up @@ -256,7 +259,11 @@ def event_damage(self, tik, damage, attacker_id, target_id, pos):
target.got_damaged(damage=damage, attacker=attacker, pos=pos)
# получить время об последний урон для диско - get time of last damage done to airplane when sortie is disco
if target.sortie:
target.sortie.tik_lastdamage = tik
if target.cls_base == 'aircraft':
target.sortie.tik_lastdamage = tik
if (target.cls_base == 'tank' or target.cls_base == 'vehicle' or target.cls_base == 'turret'):
if (attacker != None):
target.sortie.tik_lastdamage = tik

def event_kill(self, tik, attacker_id, target_id, pos):
attacker = self.get_object(object_id=attacker_id)
Expand Down Expand Up @@ -380,8 +387,8 @@ def event_player_disconnected(self, tik, account_id, profile_id):
# self.online_uuid.discard(account_id)
sortie = self.sorties_accounts.get(account_id)
# TODO работает только в Ил2, в РОФ нет такого события
if sortie:
# you can determine the amount of damage that is considered
if sortie and not (sortie.cls in ('tank_light', 'tank_heavy', 'tank_medium', 'tank_turret', 'truck')):
# you can determine the amount of damage that is considered for airplanes
dmg_pct = 0
# the departure was completed, there was a jump, no plane was created, the plane on the ground, and the plane was damaged,
# player disconection can then be changed into captured.
Expand All @@ -391,10 +398,17 @@ def event_player_disconnected(self, tik, account_id, profile_id):
self.logger_event({'type': 'disco', 'sortie': sortie})
sortie.aircraft.got_killed(force_by_dmg=True)
# вылет был завершен, был прыжок, не был создан самолет, самолет на земле
if not (sortie.is_ended or sortie.is_bailout or (not sortie.aircraft) or sortie.aircraft.on_ground):
elif not (sortie.is_ended or sortie.is_bailout or (not sortie.aircraft) or sortie.aircraft.on_ground):
sortie.is_disco = True
self.logger_event({'type': 'disco', 'sortie': sortie})

if sortie and (sortie.cls in ('tank_light', 'tank_heavy', 'tank_medium', 'tank_turret', 'truck')):

# this is for case when tank player discnects, log will record its time and event.
if sortie.tik_lastdamage:
if (sortie.tank_is_ended_by_exit(tik=tik)) and (not sortie.is_bailout):
self.logger_event({'type': 'disco', 'sortie': sortie})

def event_tank_travel(self, tik, tank_id, pos):
pass

Expand Down Expand Up @@ -496,6 +510,7 @@ def __init__(self, mission, object_id, object_name, country_id, coal_id, parent_
self.life_status = LifeStatus()

self.is_deinitialized = False
self.is_tank_exit_damaged = False

self.is_takeoff = False
self.is_killed = False
Expand Down Expand Up @@ -672,7 +687,8 @@ def got_killed(self, attacker=None, pos=None, force_by_dmg=False):
attacker = None

# dont give kill to attacker for tank/truck when its RTB and total damage to tank is less then 75%, if higher tank will be destroyed, no RTB, and attacker will get kill.
if (self.cls_base == 'tank' or self.cls_base == 'vehicle' or self.cls_base == 'turret') and self.is_tank_rtb(pos=pos) and (self.damage < 75):
if (self.cls_base == 'tank' or self.cls_base == 'vehicle' or self.cls_base == 'turret') and self.is_tank_rtb(
pos=pos) and (self.damage < 75):
attacker = None

is_friendly_fire = True if attacker and attacker.coal_id == self.coal_id else False
Expand All @@ -693,12 +709,11 @@ def got_killed(self, attacker=None, pos=None, force_by_dmg=False):
self.mission.logger_event({'type': 'kill', 'attacker': attacker, 'pos': pos,
'target': self, 'is_friendly_fire': is_friendly_fire})

def killed_by_damage(self, dmg_pct=0, dmg_pct_tk=0 ):
def killed_by_damage(self, dmg_pct=0, dmg_pct_tk=0):
if self.cls_base == 'tank' or self.cls_base == 'vehicle':
# - by changing dmg_pct_tk value you can set up to what damage % tank or truck can be damaged to not give kill to attacker or sortie status changed to destroyed.
if not self.is_killed and (self.damage > dmg_pct_tk or self.is_captured):
if (self.on_ground and not self.is_rtb) or self.is_bailout or (
self.bot and self.bot.life_status.is_destroyed):
if not self.is_killed and (self.damage > dmg_pct_tk):
if self.is_tank_exit_damaged:
self.got_killed(force_by_dmg=True)
if self.cls_base == 'aircraft':
if not self.is_killed and (self.damage > dmg_pct or self.is_captured):
Expand All @@ -707,6 +722,10 @@ def killed_by_damage(self, dmg_pct=0, dmg_pct_tk=0 ):
if (self.on_ground and not self.is_rtb) or self.is_bailout or (
self.bot and self.bot.life_status.is_destroyed):
self.got_killed(force_by_dmg=True)
# in case of disconection - the player who damaged him gets kill, when damage occurs at any time in flight
if self.sortie and not self.is_rtb:
if not self.sortie.is_ended:
self.got_killed(force_by_dmg=True)

def update_by_sortie(self, sortie, is_aircraft=True):
"""
Expand Down Expand Up @@ -822,6 +841,7 @@ def __init__(self, mission, tik, aircraft_id, bot_id, account_id, profile_id, na
self.is_disco = False
self.is_discobailout = False
self.is_damageddisco = False
self.is_tank_exit_damaged = False
self.is_ended = False

# логи могут баговать и идти не по порядку
Expand Down Expand Up @@ -956,3 +976,12 @@ def is_ended_by_timeout(self, timeout, tik):
return False
else:
return True

# for Tanks/trucks , set True if last damage is with in specified time set in conf.ini.
# its used to give kill to attacker when sortie is turned to capture, if player bailout then dont count, bailed out game log gives kill to attacker automaticly.
def tank_is_ended_by_exit(self, tik):
if (self.cls_base == 'tank' or self.cls_base == 'vehicle' or self.cls_base == 'turret' ) and (self.tik_lastdamage is not None):
if (SORTIE_DAMAGE_DISCO_TIME > (tik - self.tik_lastdamage // 50)) and not (self.is_bailout):
return False
else:
return True
6 changes: 5 additions & 1 deletion src/mod_rating_by_type/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,11 @@ def event_damage(self, tik, damage, attacker_id, target_id, pos):
target.got_damaged(damage=damage, tik=tik, attacker=attacker, pos=pos)
# получить время об последний урон для диско - get time of last damage done to airplane when sortie is disco
if target.sortie:
target.sortie.tik_lastdamage = tik
if target.cls_base == 'aircraft':
target.sortie.tik_lastdamage = tik
if (target.cls_base == 'tank' or target.cls_base == 'vehicle' or target.cls_base == 'turret'):
if (attacker != None):
target.sortie.tik_lastdamage = tik


# Monkey patched into Object class inside report.py
Expand Down
18 changes: 13 additions & 5 deletions src/mod_rating_by_type/stats_whore.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,16 @@ def create_new_sortie(mission, profile, player, sortie, sortie_aircraft_id):
is_ignored = True

# for disco sorties, if the total departure time is less than the one set by the config, disco = bailout sortie (time is set in seconds)

if SORTIE_DISCO_MIN_TIME and sortie.is_disco:
if (sortie_tik_last // 50) - (sortie.tik_takeoff // 50) < SORTIE_DISCO_MIN_TIME:
sortie.is_discobailout = True
sortie.is_disco = False

# in case of disconect if time of damage to airplane happend outside of time set in conf.ini file, sortie is considered disco,
# if time of damage happend inside time set, sortie will be considered captured (time is set in seconds)

if SORTIE_DAMAGE_DISCO_TIME and sortie.is_damageddisco:

if (sortie.tik_last // 50) - (sortie.tik_lastdamage // 50) > SORTIE_DAMAGE_DISCO_TIME:
if ((sortie_tik_last // 50) - (sortie.tik_lastdamage // 50) > SORTIE_DAMAGE_DISCO_TIME) and not (
(sortie.cls_base == 'tank' or sortie.cls_base == 'vehicle' or sortie.cls_base == 'turret')):
sortie.is_disco = True
sortie.is_damageddisco = False
# for damaged disco sorties, if the total departure time is less than the one set by the config for disco_min_time, damageddisco = bailout sortie
Expand All @@ -120,6 +118,16 @@ def create_new_sortie(mission, profile, player, sortie, sortie_aircraft_id):
sortie.is_disco = False
sortie.is_damageddisco = False

# in case of tank exit under fire, if time of damage to tank or truck happend outside of time set in conf.ini file, sortie is considered ok,
# if time of damage happend inside time set, sortie will be considered captured (time is set in seconds), if mission ends or crah while player is in sortie then it dont count.
if SORTIE_DAMAGE_DISCO_TIME and (
(sortie.cls_base == 'tank' or sortie.cls_base == 'vehicle' or sortie.cls_base == 'turret')) and (
sortie.tik_lastdamage) and (mission.date_end != sortie_date_end):
if (SORTIE_DAMAGE_DISCO_TIME > (sortie_tik_last // 50) - (sortie.tik_lastdamage // 50)) and (
not sortie.tik_bailout):
sortie.is_tank_exit_damaged = True
sortie.aircraft.got_killed(force_by_dmg=True)

killboard_pvp = defaultdict(int)
killboard_pve = defaultdict(int)

Expand Down Expand Up @@ -203,7 +211,7 @@ def create_new_sortie(mission, profile, player, sortie, sortie_aircraft_id):
bot_status=sortie.bot_status.status,

is_bailout=sortie.is_bailout or sortie.is_discobailout,
is_captured=sortie.is_captured or sortie.is_damageddisco,
is_captured=sortie.is_captured or sortie.is_damageddisco or sortie.is_tank_exit_damaged,
is_disco=sortie.is_disco,

score=score,
Expand Down
47 changes: 34 additions & 13 deletions src/stats/stats_whore.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
SORTIE_DISCO_MIN_TIME = settings.SORTIE_DISCO_MIN_TIME
SORTIE_DAMAGE_DISCO_TIME = settings.SORTIE_DAMAGE_DISCO_TIME


def main():
logger.info('IL2 stats {stats}, Python {python}, Django {django}'.format(
stats=__version__, python=sys.version[0:5], django=django.get_version()))
Expand Down Expand Up @@ -186,7 +187,8 @@ def stats_whore(m_report_file):
mission.save()

# собираем/создаем профили игроков и сквадов
profiles, players_pilots, players_gunners, players_tankmans, squads = create_profiles(tour=tour, sorties=m_report.sorties)
profiles, players_pilots, players_gunners, players_tankmans, squads = create_profiles(tour=tour,
sorties=m_report.sorties)

players_aircraft = defaultdict(dict)
players_mission = {}
Expand Down Expand Up @@ -244,7 +246,8 @@ def stats_whore(m_report_file):

player_aircraft = players_aircraft[_player_id].setdefault(
new_sortie.aircraft.id,
PlayerAircraft.objects.get_or_create(profile_id=_profile_id, player_id=_player_id, aircraft_id=new_sortie.aircraft.id)[0]
PlayerAircraft.objects.get_or_create(profile_id=_profile_id, player_id=_player_id,
aircraft_id=new_sortie.aircraft.id)[0]
)

vlife = VLife.objects.get_or_create(profile_id=_profile_id, player_id=_player_id, tour_id=tour.id, relive=0)[0]
Expand All @@ -253,7 +256,8 @@ def stats_whore(m_report_file):
if mission.win_reason == 'score':
update_bonus_score(new_sortie=new_sortie)

update_sortie(new_sortie=new_sortie, player_mission=player_mission, player_aircraft=player_aircraft, vlife=vlife)
update_sortie(new_sortie=new_sortie, player_mission=player_mission, player_aircraft=player_aircraft,
vlife=vlife)
reward_sortie(sortie=new_sortie)

vlife.save()
Expand Down Expand Up @@ -341,7 +345,8 @@ def stats_whore(m_report_file):
else:
params['type'] = 'damaged'
if event['attacker']:
if ((event['attacker'].cls == 'tank_turret' or (event['attacker'].cls_base == 'tank' or (event['attacker'].cls_base == 'vehicle')))
if ((event['attacker'].cls == 'tank_turret' or (
event['attacker'].cls_base == 'tank' or (event['attacker'].cls_base == 'vehicle')))
and event['attacker'].parent and event['attacker'].parent.sortie):
# Credit the damage to the tank driver.
params['act_object_id'] = event[
Expand All @@ -366,7 +371,8 @@ def stats_whore(m_report_file):
else:
params['type'] = 'destroyed'
if event['attacker']:
if ((event['attacker'].cls == 'tank_turret' or (event['attacker'].cls_base == 'tank' or (event['attacker'].cls_base == 'vehicle')))
if ((event['attacker'].cls == 'tank_turret' or (
event['attacker'].cls_base == 'tank' or (event['attacker'].cls_base == 'vehicle')))
and event['attacker'].parent and event['attacker'].parent.sortie):
# Credit the kill to the tank driver.
params['act_object_id'] = event[
Expand All @@ -384,8 +390,11 @@ def stats_whore(m_report_file):
params['cact_object_id'] = objects[event['target'].log_name]['id']

l = LogEntry.objects.create(**params)
if l.type == 'shotdown' and l.act_sortie and l.cact_sortie and not l.act_sortie.is_disco and not l.extra_data.get('is_friendly_fire'):
update_killboard_pvp(player=l.act_sortie.player, opponent=l.cact_sortie.player, players_killboard=players_killboard)
if l.type in {'shotdown',
'destroyed'} and l.act_sortie and l.cact_sortie and not l.act_sortie.is_disco and not l.extra_data.get(
'is_friendly_fire'):
update_killboard_pvp(player=l.act_sortie.player, opponent=l.cact_sortie.player,
players_killboard=players_killboard)

for p in players_killboard.values():
p.save()
Expand Down Expand Up @@ -464,16 +473,17 @@ def create_new_sortie(mission, profile, player, sortie, sortie_aircraft_id):
if (sortie_tik_last // 50) - (sortie.tik_spawn // 50) < SORTIE_MIN_TIME:
is_ignored = True

# for disco sorties, if the total departure time is less than the one set by the config, disco = bailout sortie (time is set in seconds)
# for disco sorties, if the total departure time is less than the one set by the config, disco = bailout sortie (time is set in seconds)
if SORTIE_DISCO_MIN_TIME and sortie.is_disco:
if (sortie_tik_last // 50) - (sortie.tik_takeoff // 50) < SORTIE_DISCO_MIN_TIME:
sortie.is_discobailout = True
sortie.is_disco = False

# in case of disconect if time of damage to airplane happend outside of time set in conf.ini file, sortie is considered disco,
# if time of damage happend inside time set, sortie will be considered captured (time is set in seconds)
# if time of damage happend inside time set, sortie will be considered captured (time is set in seconds)
if SORTIE_DAMAGE_DISCO_TIME and sortie.is_damageddisco:
if (sortie.tik_last // 50) - (sortie.tik_lastdamage // 50) > SORTIE_DAMAGE_DISCO_TIME:
if ((sortie_tik_last // 50) - (sortie.tik_lastdamage // 50) > SORTIE_DAMAGE_DISCO_TIME) and not (
(sortie.cls_base == 'tank' or sortie.cls_base == 'vehicle' or sortie.cls_base == 'turret')):
sortie.is_disco = True
sortie.is_damageddisco = False
# for damaged disco sorties, if the total departure time is less than the one set by the config for disco_min_time, damageddisco = bailout sortie
Expand All @@ -482,6 +492,15 @@ def create_new_sortie(mission, profile, player, sortie, sortie_aircraft_id):
sortie.is_disco = False
sortie.is_damageddisco = False

# in case of tank exit under fire, if time of damage to tank or truck happend outside of time set in conf.ini file, sortie is considered ok,
# if time of damage happend inside time set, sortie will be considered captured (time is set in seconds), if mission ends or crah while player is in sortie then it dont count.
if SORTIE_DAMAGE_DISCO_TIME and (
(sortie.cls_base == 'tank' or sortie.cls_base == 'vehicle' or sortie.cls_base == 'turret')) and (
sortie.tik_lastdamage) and (mission.date_end != sortie_date_end):
if (SORTIE_DAMAGE_DISCO_TIME > (sortie_tik_last // 50) - (sortie.tik_lastdamage // 50)) and (
not sortie.tik_bailout):
sortie.is_tank_exit_damaged = True
sortie.aircraft.got_killed(force_by_dmg=True)

killboard_pvp = defaultdict(int)
killboard_pve = defaultdict(int)
Expand Down Expand Up @@ -567,7 +586,7 @@ def create_new_sortie(mission, profile, player, sortie, sortie_aircraft_id):
bot_status=sortie.bot_status.status,

is_bailout=sortie.is_bailout or sortie.is_discobailout,
is_captured=sortie.is_captured or sortie.is_damageddisco,
is_captured=sortie.is_captured or sortie.is_damageddisco or sortie.is_tank_exit_damaged,
is_disco=sortie.is_disco,

score=score,
Expand Down Expand Up @@ -615,7 +634,7 @@ def update_sortie(new_sortie, player_mission, player_aircraft, vlife):
vlife.aircraft_status = new_sortie.aircraft_status
vlife.bot_status = new_sortie.bot_status

# TODO проверить как это отработает для вылетов стрелков
# TODO проверить как это отработает для вылетов стрелков
if new_sortie.aircraft.cls_base == 'aircraft' and not new_sortie.is_not_takeoff:
player.sorties_coal[new_sortie.coalition] += 1
player_mission.sorties_coal[new_sortie.coalition] += 1
Expand Down Expand Up @@ -734,7 +753,8 @@ def update_sortie(new_sortie, player_mission, player_aircraft, vlife):

def update_general(player, new_sortie):
flight_time_add = 0
if (not new_sortie.is_not_takeoff) or ( new_sortie.aircraft.cls_base == 'tank' or (new_sortie.aircraft.cls_base == 'vehicle')):
if (not new_sortie.is_not_takeoff) or (
new_sortie.aircraft.cls_base == 'tank' or (new_sortie.aircraft.cls_base == 'vehicle')):
player.sorties_total += 1
flight_time_add = new_sortie.flight_time
player.flight_time += flight_time_add
Expand Down Expand Up @@ -765,6 +785,7 @@ def update_general(player, new_sortie):
except AttributeError:
pass # Some player objects have no score or relive attributes for light/medium/heavy aircraft.


def update_ammo(sortie, player):
# в логах есть баги, по окончание вылета у самолета может быть больше боемкомплекта чем было вначале
if sortie.ammo['used_cartridges'] >= sortie.ammo['hit_bullets']:
Expand Down

0 comments on commit 7e4a99f

Please sign in to comment.