implement rank system
This commit is contained in:
parent
65c924c3a8
commit
93a9ffb268
@ -51,7 +51,6 @@ class Level(models.Model):
|
||||
result = list(self.bloonsa_level_ratings.aggregate(Avg("rating")).values())[0]
|
||||
return 0 if result is None else round(result)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.level_id}: {self.author.name} - {self.title}"
|
||||
|
||||
|
||||
@ -109,3 +109,10 @@
|
||||
.invisible {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#global-leaderboard-iframe {
|
||||
height: 629px;
|
||||
width: 160px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
#glb-global {
|
||||
height: 629px;
|
||||
width: 160px;
|
||||
font-family: "Comic Sans MS", "Comic Sans", cursive;
|
||||
color: white;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.rowa {
|
||||
background-color: #563EAB;
|
||||
}
|
||||
.rowb {
|
||||
background-color: #6B0047;
|
||||
}
|
||||
|
||||
.glb-position {
|
||||
color: #ffcf24;
|
||||
}
|
||||
|
||||
.glb-username {
|
||||
z-index: 100;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.glb-entry {
|
||||
height: 56px;
|
||||
width: 160px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.glb-main-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 62px;
|
||||
}
|
||||
|
||||
.glb-rank-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.glb-avatar {
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
margin: 2px;
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
.glb-wins-img, .glb-darts-img {
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.glb-volforce {
|
||||
font-size: 15px;
|
||||
color: #FF00AA;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.glb-rank-icon {
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
BIN
app/bloonsa_game/static/bloonsa_game/img/ranks/1.png
Normal file
BIN
app/bloonsa_game/static/bloonsa_game/img/ranks/1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
@ -27,6 +27,7 @@
|
||||
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="{% static 'bloonsa_game/css/main.css' %}"/>
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="{% static 'bloonsa_game/css/append.css' %}"/>
|
||||
|
||||
{% block head %}{% endblock head %}
|
||||
</head>
|
||||
|
||||
@ -47,6 +48,13 @@
|
||||
</div>
|
||||
|
||||
<div class="skyscraper" id="skyscraper-l">
|
||||
<iframe id="global-leaderboard-iframe"
|
||||
frameborder="0"
|
||||
scrolling="no"
|
||||
sandbox="allow-same-origin"
|
||||
onload="this.style.height=(this.contentWindow.document.body.scrollHeight+20)+'px';"
|
||||
src="{% url 'bloonsa_game:leaderboard_global' %}"></iframe>
|
||||
{% include 'bloonsa_game/modules/leaderboard_global.html' %}
|
||||
</div>
|
||||
<div id="content">
|
||||
{% block content %}{% endblock content %}
|
||||
@ -77,19 +85,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="adholder1">
|
||||
<script type="text/javascript"><!--
|
||||
e9 = new Object();
|
||||
e9.size = "728x90";
|
||||
//--></script>
|
||||
|
||||
</div>
|
||||
<div id="adholder1"></div>
|
||||
<div id="adholder2"></div>
|
||||
<div id="adholder3">
|
||||
<script type="text/javascript"><!--
|
||||
e9 = new Object();
|
||||
e9.size = "160x600";
|
||||
//--></script></div>
|
||||
<div id="adholder3"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
document.getElementById('adslot1').appendChild(document.getElementById('adholder1'));
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
{% load static %}
|
||||
{% load bloonsa_game_tags %}
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="{% static 'bloonsa_game/css/leaderboard_global.css' %}"/>
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="{% static 'bloonsa_game/css/append.css' %}"/>
|
||||
<div id="glb-global">
|
||||
{% for player in players %}
|
||||
<div class="rowa glb-entry">
|
||||
<div class="glb-avatar-box">
|
||||
<img class="glb-avatar" src="{{ player.avatar.url }}" height=48px width=48px>
|
||||
</div>
|
||||
<div class="glb-main-info">
|
||||
<div class="glb-user">
|
||||
<span class="glb-position">#{{ forloop.counter }}</span>
|
||||
<span class="glb-username">{{ player.user.username }}</span>
|
||||
</div>
|
||||
|
||||
<div class="glb-wins-box">
|
||||
<object data="{% static 'bloonsa_game/img/levelinfo/wins.svg' %}"
|
||||
class="filter-orange glb-wins-img"
|
||||
type="image/svg+xml"></object>
|
||||
<span>{{ player.bloonsa_levels_beaten_count }}</span>
|
||||
</div>
|
||||
<div class="glb-gdarts-box">
|
||||
<object data="{% static 'bloonsa_game/img/levelinfo/dart.svg' %}"
|
||||
class="filter-orange glb-darts-img"
|
||||
type="image/svg+xml"></object>
|
||||
<span>{{ player.bloonsa_dart_glitch_count }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="glb-rank-box">
|
||||
<img src="{% static 'bloonsa_game/img/ranks/'|concat:player.bloonsa_rank|concat:'.png' %}"
|
||||
height=36px width=36px
|
||||
class="glb-rank-icon">
|
||||
<span class="glb-volforce">{{ player.bloonsa_volforce_rating }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@ -12,3 +12,7 @@ def dummy(text):
|
||||
@register.simple_tag(name="bloonsa_total_levels")
|
||||
def total_levels():
|
||||
return int(Level.objects.count())
|
||||
|
||||
@register.filter
|
||||
def concat(arg1, arg2):
|
||||
return str(arg1) + str(arg2)
|
||||
@ -1,14 +1,15 @@
|
||||
from django.urls import path, include
|
||||
from django.views.generic import RedirectView
|
||||
|
||||
from bloonsa_game.views import IndexView, TermsView, GameView, WIPView
|
||||
from bloonsa_game.views import IndexView, TermsView, GameView, LeaderboardGlobalView
|
||||
|
||||
app_name = "bloonsa_game"
|
||||
|
||||
urlpatterns = [
|
||||
path("", RedirectView.as_view(pattern_name="bloonsa_game:game", permanent=False), name="index"),
|
||||
path("game", GameView.as_view(), name="game"),
|
||||
path("game/<int:pk>", GameView.as_view(), name="gameSelect"),
|
||||
path("game/<int:pk>", GameView.as_view(), name="game_select"),
|
||||
path("leaderboard_global", LeaderboardGlobalView.as_view(), name="leaderboard_global")
|
||||
# path("terms", TermsView.as_view(), name="terms"),
|
||||
# path("contact", WIPView.as_view(), name="contact"),
|
||||
]
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
from django.db.models import F, BooleanField, IntegerField, ExpressionWrapper, Count, Sum, DecimalField
|
||||
from django.db.models.functions import Cast
|
||||
from django.shortcuts import render
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from bloonsa_game.models import Level
|
||||
from users.models import Player
|
||||
from users.util import bloonsa_util, actions
|
||||
|
||||
|
||||
@ -33,13 +36,28 @@ class GameView(TemplateView):
|
||||
"total_levels": total_levels,
|
||||
"flashVars": level.get_flash_vars(seperator="&"),
|
||||
})
|
||||
return render(request, "bloonsa_game/game.html",
|
||||
|
||||
r = render(request, "bloonsa_game/game.html",
|
||||
context={"total_levels": total_levels,})
|
||||
r["x-frame-options"] = "sameorigin"
|
||||
return r
|
||||
|
||||
class WIPView(TemplateView):
|
||||
|
||||
|
||||
class LeaderboardGlobalView(TemplateView):
|
||||
def get(self, request, *args, **kwargs):
|
||||
return render(request, "bloonsa_game/error.html", context={})
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
return render(request, "bloonsa_game/error.html", context={})
|
||||
# Get top 100 best players
|
||||
players = Player.objects.annotate(
|
||||
clears=Count(F("bloonsa_level_scores__clear")),
|
||||
golds=Count(F("bloonsa_level_scores__dart_glitch_ever"))
|
||||
).annotate(
|
||||
volforce=F("clears") + F("golds")
|
||||
).order_by("-volforce")[:100]
|
||||
for player in players:
|
||||
print(player.bloonsa_volforce_rating)
|
||||
r = render(request, "bloonsa_game/modules/leaderboard_global.html",
|
||||
context={
|
||||
"players": players
|
||||
})
|
||||
r["x-frame-options"] = "sameorigin"
|
||||
return r
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import math
|
||||
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.contrib.auth.models import User
|
||||
@ -50,6 +52,31 @@ class Player(models.Model):
|
||||
def has_beaten_bloonsa_level(self, level):
|
||||
return bool(self.bloonsa_level_scores.filter(clear=True, level=level).exists())
|
||||
|
||||
@property
|
||||
def bloonsa_dart_glitch_count(self):
|
||||
return self.bloonsa_level_scores.filter(dart_glitch_ever=True).count()
|
||||
|
||||
@property
|
||||
def bloonsa_volforce_rating(self):
|
||||
total_levels = 66396
|
||||
beaten_levels = self.bloonsa_levels_beaten_count
|
||||
gold_levels = self.bloonsa_dart_glitch_count
|
||||
|
||||
estimated_limit = total_levels + ((total_levels / 100) * 20)
|
||||
estimated_max_rank = 80.00
|
||||
player_score = beaten_levels + gold_levels
|
||||
player_volforce = player_score * (estimated_max_rank / estimated_limit)
|
||||
|
||||
import random
|
||||
player_volforce = random.randint(100, 2700) / 100
|
||||
|
||||
return "{:.2f}".format(player_volforce)
|
||||
|
||||
@property
|
||||
def bloonsa_rank(self):
|
||||
return math.floor(float(self.bloonsa_volforce_rating) / 100) + 1
|
||||
|
||||
|
||||
def __str__(self):
|
||||
statesDict = {
|
||||
"cheater": "😈" if self.suspected_cheater else "",
|
||||
|
||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user