diff --git a/app/bloonsa_api/views.py b/app/bloonsa_api/views.py index ed07304..203a490 100644 --- a/app/bloonsa_api/views.py +++ b/app/bloonsa_api/views.py @@ -28,7 +28,7 @@ class LoadLevel(CSRFexemptTemplateView): if request.user.is_authenticated: bloonsa_util.tag_player(request=request) player = Player.objects.get(user=request.user) - player.bloonsa_levelsPlayed.add(level) + player.bloonsa_levels_played.add(level) bloonsa_util.log(player=player, action=actions.bloonsa_load_level_by_id, note=level.levelId) @@ -45,7 +45,7 @@ class RandomLevel(CSRFexemptTemplateView): if request.user.is_authenticated: bloonsa_util.tag_player(request=request) player = Player.objects.get(user=request.user) - player.bloonsa_levelsPlayed.add(level) + level.played_by.add(player) bloonsa_util.log(player=player, action=actions.bloonsa_load_random_level, note=level.levelId) @@ -95,21 +95,20 @@ class RateLevel(CSRFexemptTemplateView): level_id = int(request.POST.get("level_id")) level = Level.objects.get(levelId=level_id) player = Player.objects.get(user=request.user) - ratingObject = Player.objects.filter(bloonsa_levelRatings__level=level).first() - if ratingObject: - ratingObject.rating = rating - ratingObject.save() - - else: - rating = LevelRating.objects.create(level=level, - rating=rating) - player.bloonsa_levelRatings.add(rating) - rating.save() - player.save() - + ratingObject = Player.objects.filter(bloonsa_level_ratings__level=level).first() bloonsa_util.log(player=player, action=actions.bloonsa_rate_level, note=level.levelId) + if ratingObject: + ratingObject.rating = rating + ratingObject.save() + return HttpResponse(content="OK", status=200) + + rating = LevelRating.objects.create(level=level, + rating=rating) + player.bloonsa_level_ratings.add(rating) + rating.save() + player.save() return HttpResponse(content="OK", status=200) return HttpResponse(status=400) diff --git a/app/bloonsa_game/migrations/0015_levelrating_player_levelscore_player.py b/app/bloonsa_game/migrations/0015_levelrating_player_levelscore_player.py new file mode 100644 index 0000000..daa77e6 --- /dev/null +++ b/app/bloonsa_game/migrations/0015_levelrating_player_levelscore_player.py @@ -0,0 +1,25 @@ +# Generated by Django 5.1.6 on 2025-02-14 03:01 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0014_alter_levelscore_level'), + ('users', '0021_remove_player_bloonsa_levelratings_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='levelrating', + name='player', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='bloonsa_level_ratings', to='users.player'), + ), + migrations.AddField( + model_name='levelscore', + name='player', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='bloonsa_level_scores', to='users.player'), + ), + ] diff --git a/app/bloonsa_game/migrations/0016_level_played_by.py b/app/bloonsa_game/migrations/0016_level_played_by.py new file mode 100644 index 0000000..3b34d91 --- /dev/null +++ b/app/bloonsa_game/migrations/0016_level_played_by.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.6 on 2025-02-14 03:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0015_levelrating_player_levelscore_player'), + ('users', '0021_remove_player_bloonsa_levelratings_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='level', + name='played_by', + field=models.ManyToManyField(blank=True, related_name='bloonsa_levels_played', to='users.player'), + ), + ] diff --git a/app/bloonsa_game/migrations/0017_alter_levelrating_rating.py b/app/bloonsa_game/migrations/0017_alter_levelrating_rating.py new file mode 100644 index 0000000..7c7fa24 --- /dev/null +++ b/app/bloonsa_game/migrations/0017_alter_levelrating_rating.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.6 on 2025-02-14 03:16 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bloonsa_game', '0016_level_played_by'), + ] + + operations = [ + migrations.AlterField( + model_name='levelrating', + name='rating', + field=models.SmallIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(10)]), + ), + ] diff --git a/app/bloonsa_game/models.py b/app/bloonsa_game/models.py index 88bf9b3..2cc4e24 100644 --- a/app/bloonsa_game/models.py +++ b/app/bloonsa_game/models.py @@ -1,5 +1,9 @@ +from django.core.validators import MinValueValidator, MaxValueValidator from django.db import models +from users.models import Player + + class Author(models.Model): name = models.CharField(max_length=255) authorId = models.IntegerField() @@ -18,6 +22,8 @@ class Level(models.Model): rating = models.FloatField(null=True, blank=True) data = models.CharField(max_length=288) + played_by = models.ManyToManyField(Player, blank=True, related_name="bloonsa_levels_played") + def __str__(self): return f"{self.author} - {self.title}" @@ -38,16 +44,19 @@ class Level(models.Model): class LevelRating(models.Model): + player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name="bloonsa_level_ratings", null=True) level = models.ForeignKey(Level, on_delete=models.CASCADE) - rating = models.SmallIntegerField() + rating = models.SmallIntegerField(validators=[MinValueValidator(1), + MaxValueValidator(10)]) def __str__(self): - return (f"{self.player.first().user.username}" + return (f"{self.player.user.username}" f" - [<{int(self.rating) * '★'}> - {self.level.title}]") # There should only be 1 score per player # Highest popcount wins class LevelScore(models.Model): + player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name="bloonsa_level_scores", null=True) level = models.ForeignKey(Level, on_delete=models.CASCADE) clear = models.BooleanField(default=True) # This is for if we ever submit scores for failed attempts darts_left = models.PositiveSmallIntegerField(null=True) @@ -55,5 +64,5 @@ class LevelScore(models.Model): def __str__(self): clearState = "✅" if self.clear else "❌" - return (f"{self.player.first().user.username}'s {clearState} @ {self.level.title}" + return (f"{self.player.user.username}'s {clearState} @ {self.level.title}" f"[🎈{self.pops} | 🎯{self.darts_left}]") \ No newline at end of file diff --git a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited.swf b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited.swf index 0e7387b..bc156f3 100644 Binary files a/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited.swf and b/app/bloonsa_game/static/bloonsa_game/misc/bloons_unlimited.swf differ diff --git a/app/bloonsa_game/templates/bloonsa_game/base.html b/app/bloonsa_game/templates/bloonsa_game/base.html index 78d5da8..b43dcb7 100644 --- a/app/bloonsa_game/templates/bloonsa_game/base.html +++ b/app/bloonsa_game/templates/bloonsa_game/base.html @@ -26,13 +26,15 @@ + "quality": "high", + "splashScreen": false, + "menu": false, + "polyfills": false, + }; {% if head %} diff --git a/app/bloonsa_game/templates/bloonsa_game/game.html b/app/bloonsa_game/templates/bloonsa_game/game.html index 590d29a..6bc694d 100644 --- a/app/bloonsa_game/templates/bloonsa_game/game.html +++ b/app/bloonsa_game/templates/bloonsa_game/game.html @@ -15,12 +15,13 @@ width="640" height="480" title="" allowScriptAccess=true> + --> -
+