Advanced event types

This commit is contained in:
2019-10-17 20:35:18 +02:00
parent d6d0d0fcbb
commit ad3b216a0d
9 changed files with 151 additions and 38 deletions

View File

@@ -43,10 +43,11 @@ def enemy_choice_for_season(season_id: int):
"""
db = new_session()
season: Season = db.query(Season).get(season_id)
season_enemies = [enemy for enemy in season.enemies if not enemy.is_defeated]
global_enemies = db.query(Enemy).filter(Enemy.season_id == -1).all()
if not season and not global_enemies:
return []
combined = global_enemies + season.enemies
combined = global_enemies + season_enemies
return [(e.id, e.name) for e in combined]

View File

@@ -79,9 +79,7 @@ class EventForm(FlaskForm):
event_id = HiddenField("Event ID")
episode_id = HiddenField("Episode ID")
event_type = SelectField(
"Type", choices=choices.EventChoiceIterable(), coerce=int,
validators=[DataRequired()]
)
"Type", choices=choices.EventChoiceIterable(), coerce=int)
time = TimeField("Time", format="%H:%M", validators=[DataRequired()])
player = SelectField("Player", choices=choices.PlayerChoiceIterable(), coerce=int)
enemy = SelectField("Enemy", coerce=int)

View File

@@ -94,6 +94,10 @@ class Enemy(Base):
events: Iterable["Event"] = relationship('Event', back_populates="enemy")
@property
def is_defeated(self):
return any([e for e in self.events if e.type == EventType.Victory])
def populate_from_form(self, form: "forms.EnemyForm"):
self.name = str(form.name.data)
self.boss = bool(form.is_boss.data)

View File

@@ -51,8 +51,19 @@ a:hover {
font-family: 'DarkSouls', serif;
}
.nav-container{
margin-bottom: 10px;
}
.btn-toolbar{
padding: 5px 0;
margin: 10px 0;
}
.btn-toolbar .btn {
margin-right: 10px;
}
.card{
margin-bottom: 25px;
}
.vertical-center {
@@ -64,6 +75,11 @@ a:hover {
}
/* Theme customizations */
.list-group-item {
display: flex;
justify-content: space-between;
}
.list-group-item:hover {
color: inherit;
background-color: rgb(34, 34, 34);
@@ -72,3 +88,19 @@ a:hover {
h1 {
font-size: 2.5rem;
}
html {
height: 100%;
}
body {
display: flex;
flex-direction: column;
height: 100%;
}
.content{
flex: 1 0 auto;
}
.footer {
flex-shrink: 0;
}

View File

@@ -14,7 +14,8 @@
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
{% endblock %}
{% block body %}
<div class="content">
{% block navbar %}
{% set nav_bar = [
('/season', 'seasons', 'Seasons', 'fas fa-calendar'),
@@ -22,7 +23,7 @@
('/enemy', 'enemies', 'Enemies', 'fas fa-skull-crossbones'),
('/drink', 'drinks', 'Drinks', 'fas fa-beer')
]-%}
<div class="container">
<div class="container nav-container">
<nav class="navbar navbar-expand-lg bg-dark navbar-dark">
<a class="navbar-brand">
@@ -58,11 +59,12 @@
{% block page %}
{% endblock %}
<div>
{% block footer %}
&copy; Sauf Software by D⁵: <a href="#">Durstiger Donnerstag Digital Drinking Divison</a>.
{% endblock %}
</div>
</div>
</div>
{% endblock %}
</div>
<div class="container footer">&copy; Sauf Software by D⁵: <a href="#">Durstiger Donnerstag Digital Drinking Divison</a>.</div>
{% endblock %}

View File

@@ -19,6 +19,7 @@
<th scope="col" class="col-sm-auto text-center">Name</th>
<th scope="col" class="col-sm-auto text-center">Season</th>
<th scope="col" class="col-sm-auto text-center">Boss Enemy</th>
<th scope="col" class="col-sm-auto text-center">Defeated</th>
{% if g.is_editor %}
<th scope="col" class="col-sm-auto text-center">Editor</th>
@@ -32,7 +33,12 @@
<td class="col-sm-auto text-center">{{ enemy.season.game }}</td>
<td class="col-sm-auto text-center">
{% if enemy.boss %}
<span class="fas fa-check"></span>
<i class="fas fa-check"></i>
{% endif %}
</td>
<td class="col-sm-auto text-center">
{% if enemy.is_defeated %}
<i class="fas fa-check"></i>
{% endif %}
</td>

View File

@@ -17,7 +17,7 @@
{% endif %}
<div class="row">
<div class="col-sm-6">
<div class="col-sm-4">
<!--region Info Card-->
@@ -46,7 +46,7 @@
</li>
<li class="list-group-item">
<span class="font-weight-bold">Enemies Defeated:</span>
{{ 0 }}
{{ model.victories|length or 0 }}
</li>
<li class="list-group-item">
<span class="font-weight-bold">Deaths:</span>
@@ -59,8 +59,6 @@
<!--endregion-->
<hr>
<!--region Player Card-->
<div class="card">
@@ -72,12 +70,14 @@
<thead>
<tr>
<th scope="col" class="col-sm-auto text-center">Name</th>
<th scope="col" class="col-sm-auto text-center">Playtime</th>
</tr>
</thead>
<tbody>
{% for player in model.players %}
<tr>
<td class="col-sm-auto text-center">{{ player.name }}</td>
<td class="col-sm-auto text-center">{{ "0m" }}</td>
</tr>
{% endfor %}
</tbody>
@@ -89,7 +89,7 @@
</div>
<div class="col-sm-6">
<div class="col-sm-8">
<!--region Deaths Card-->
@@ -130,6 +130,45 @@
<!--endregion-->
<!--region Victories Card-->
<div class="card">
<div class="card-header text-center">
Victories
</div>
<div class="card-body">
{% if model.victories %}
<table class="table table-striped table-bordered">
<thead>
<tr>
<th scope="col" class="col-xs-auto text-center">Time</th>
<th scope="col" class="col-xs text-center">Enemy</th>
<th scope="col" class="col-xs text-center">Player</th>
</tr>
</thead>
<tbody>
{% for entry in model.victories %}
<tr>
<td class="col-xs-auto text-center">{{ entry.time|format_time }}</td>
<td class="col-xs text-center">{{ entry.enemy.name }}</td>
<td class="col-xs text-center">{{ entry.player.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="alert alert-info">No Enemies were defeated</div>
{% endif %}
</div>
</div>
<!--endregion-->
</div>
</div>
{% endblock %}

View File

@@ -3,7 +3,7 @@ from flask import render_template, request, redirect, url_for
from estusshots import app
from estusshots import forms, models, orm
from estusshots.util import authorize
from estusshots.orm import Season, Episode, Player, Event
from estusshots.orm import Season, Episode, Player
@app.route("/season/<season_id>/episode/<episode_id>")
@@ -12,13 +12,14 @@ def episode_detail(season_id: int, episode_id: int):
db = orm.new_session()
episode: Episode = db.query(Episode).get(episode_id)
deaths = [event for event in episode.events if event.type == orm.EventType.Death]
victories = [event for event in episode.events if event.type == orm.EventType.Victory]
model = {
"title": f"{episode.season.code}{episode.code}",
"episode": episode,
"season": episode.season,
"players": episode.players,
"deaths": sorted(deaths, key=lambda x: x.time),
"victories": sorted(victories, key=lambda x: x.time)
}
return render_template("episode_details.html", model=model)

View File

@@ -3,11 +3,49 @@ from collections import namedtuple
from flask import render_template, request, redirect
from estusshots import app, orm
from estusshots import forms, models, choices
from estusshots import forms, choices
from estusshots.util import authorize
from estusshots.orm import new_session, EventType, Event, Episode, Enemy, Penalty
def death_event(event, db, form):
"""Add penalties to the event if it is a death event"""
if not event.id:
for entry in form.penalties:
penalty = orm.Penalty()
penalty.player_id = entry.player_id.data
penalty.drink_id = entry.drink.data
db.add(penalty)
event.penalties.append(penalty)
else:
for event in event.penalties:
penalty = next((p for p in form.penalties.data if p["penalty_id"] == event.id), None)
if not penalty:
continue
penalty.player_id = form.player_id.data
penalty.drink_id = form.drink.data
def victory_event(event, db, form):
"""No need for additional actions yet"""
pass
def pause_event(event, db, form):
"""Pause events have neither penalties or enemies"""
event.enemy_id = None
event.enemy = None
event.player_id = None
event.player = None
event_type_map = {
EventType.Death: death_event,
EventType.Victory: victory_event,
EventType.Pause: pause_event
}
@app.route("/season/<s_id>/episode/<ep_id>/event/new", methods=["GET"])
@authorize
def event_new(s_id: int, ep_id: int):
@@ -61,21 +99,13 @@ def event_edit(s_id: int, ep_id: int, ev_id: int):
return render_template("event_editor.html", model=model, form=form)
if not event:
event = Event()
for entry in form.penalties:
penalty = orm.Penalty()
penalty.player_id = entry.player_id.data
penalty.drink_id = entry.drink.data
db.add(penalty)
event.penalties.append(penalty)
db.add(event)
else:
for event in event.penalties:
penalty = next((p for p in form.penalties.data if p["penalty_id"] == event.id), None)
if not penalty:
continue
penalty.player_id = form.player_id.data
penalty.drink_id = form.drink.data
event.populate_from_form(form)
# Different event types fill different fields
func = event_type_map[event.type]
func(event, db, form)
db.commit()
return redirect(f"/season/{s_id}/episode/{ep_id}")