Skip to content

Commit

Permalink
Merge pull request #23 from wadobo/#17-game-status-for-player
Browse files Browse the repository at this point in the history
Implements game status for a player distance
  • Loading branch information
danigm authored Jan 11, 2019
2 parents 2338fc4 + 97ea1ef commit a19c4be
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 2 deletions.
92 changes: 91 additions & 1 deletion game/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
from .factories import GameFactory
from .models import Game
from .serializers import GameSerializer

from character.models import Player, NPC
from character.factories import NPCFactory

class GameTestCase(BaseTestCase):

Expand Down Expand Up @@ -216,3 +217,92 @@ def test_create_game_contents(self):
response = self.client.post('/content/', content)
self.assertEqual(response.status_code, 201)
self.assertEqual(Content.objects.count(), 3)


class GameStatusForPlayerTestCase(BaseTestCase):

def setUp(self):
super().setUp()
self.npc = NPCFactory.create()

self.ct_player = ContentType.objects.get(model='player').pk
self.ct_npc = ContentType.objects.get(model='npc').pk
self.ct_item = ContentType.objects.get(model='item').pk
self.ct_knowledge = ContentType.objects.get(model='knowledge').pk
self.ct_rol = ContentType.objects.get(model='rol').pk

def test_game_status_for_player(self):
self.authenticate()
data = {
'title': 'My game',
'description': 'Example game',
'start': timezone.now().isoformat(),
'preferences': {
'vision_distance': 100,
'meeting_distance': 10,
'visible_character': True
},
'contents': [
{ # New, Player
'content_type': self.ct_player,
'content_id': Player.objects.first().pk,
'position': {
'longitude': 37.241421,
'latitude': -6.9447224
},
},
{ # New, Player
'content_type': self.ct_npc,
'content_id': NPC.objects.first().pk,
'position': {
'longitude': 37.241421,
'latitude': -6.9447224
},
},
{ # New, near item
'content_type': self.ct_item,
'content_id': 0,
'content': {
'name': 'key 1',
'description': 'key number 1',
'pickable': True,
'shareable': False,
'consumable': False,
},
'position': {
'longitude': 37.241421,
'latitude': -6.9447224
},
},
{ # New, far item
'content_type': self.ct_item,
'content_id': 0,
'content': {
'name': 'key 2',
'description': 'key number 2',
'pickable': True,
'shareable': False,
'consumable': False,
},
'position': {
'longitude': 80.241421,
'latitude': -60.9447224
},
},
]
}

## Create game
response = self.client.post('/game/', data)
game_id = response.json().get('id')

## Create contents
for content in data.pop('contents'):
content.update({'game': game_id})
response = self.client.post('/content/', content)

response = self.client.get('/game/{}/status/'.format(str(game_id)))

self.assertEqual(len(response.data.get('npcs')) , 1)
self.assertEqual(len(response.data.get('players')) , 0)
self.assertEqual(len(response.data.get('items')) , 1)
1 change: 1 addition & 0 deletions game/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
urlpatterns = [
path('', views.GameListCreate.as_view(), name="game_list"),
path('<int:pk>/', views.GameDetail.as_view(), name="game_detail"),
path('<int:pk>/status/', views.GameStatusForPlayer.as_view(), name="game_status_for_player"),
]
46 changes: 45 additions & 1 deletion game/views.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
from django.db.models import Q
from django_filters.rest_framework import DjangoFilterBackend
from django.contrib.gis.measure import D
from django.core.exceptions import FieldError
from rest_framework import generics
from django.shortcuts import get_object_or_404
from rest_framework import generics, views
from rest_framework.permissions import IsAuthenticatedOrReadOnly, SAFE_METHODS
from rest_framework.response import Response


from owner.models import Owner
from .models import Game
from .serializers import GameSerializer
from character.models import Player
from contents.serializers import ContentSerializer
from contents.models import Content
from django.contrib.contenttypes.models import ContentType


class GameListCreate(generics.ListCreateAPIView):
Expand Down Expand Up @@ -45,3 +54,38 @@ def get_queryset(self):
player = self.request.user.character_player
games = Game.objects.filter(owners__in=player.owners.all())
return games


class GameStatusForPlayer(views.APIView):
"""
This call return everycontents of game that is near player.
Call format: GET /api/{version}/game/{game_pk}/status/
"""

permission_classes = (IsAuthenticatedOrReadOnly,)

def get(self, request, version, pk, *args, **kwargs):
self.player = Player.objects.get(user=request.user)
player_ctype = ContentType.objects.get(model='player')
self.player_content = get_object_or_404(
Content, content_type=player_ctype, content_id=self.player.pk)
game = get_object_or_404(Game, pk=pk)
contents = Content.objects.filter(game=game)

q = Q(position__distance_lte=(self.player_content.position,
D(m=game.preferences.vision_distance)))

result = {
'npcs': [ContentSerializer(x).data
for x in contents.filter(content_type=ContentType.objects.get(model='npc'))
.filter(q)],
'players': [ContentSerializer(x).data
for x in contents.filter(content_type=ContentType.objects.get(model='player'))
.filter(q)
.exclude(pk=self.player_content.pk)],
'items': [ContentSerializer(x).data
for x in contents.filter(content_type=ContentType.objects.get(model='item'))
.filter(q)]
}

return Response(result)

0 comments on commit a19c4be

Please sign in to comment.