dice rolls get appended appropriately

This commit is contained in:
iou1name 2018-08-24 21:51:03 -04:00
parent 3e015e75d9
commit a51db58cbc
7 changed files with 167 additions and 54 deletions

View File

@ -3,6 +3,7 @@
Individual functions for handling WebSocket events. Gets called by the Individual functions for handling WebSocket events. Gets called by the
QuestConsumer object in consumers.py. QuestConsumer object in consumers.py.
""" """
# TODO: quest owner only events
import re import re
import time import time
import types import types
@ -11,7 +12,7 @@ import random
import bleach import bleach
from django.utils.timezone import localtime from django.utils.timezone import localtime
from quest.models import Message, Quest, Post, DiceCall from quest.models import Message, Quest, Post, DiceCall, DiceRoll
from quest.forms import DiceCallForm from quest.forms import DiceCallForm
def message(socket, data): def message(socket, data):
@ -62,16 +63,17 @@ def message(socket, data):
assert -1000 < dice_mod < 1000 assert -1000 < dice_mod < 1000
except (ValueError, AssertionError): except (ValueError, AssertionError):
return return
dice = [random.randint(1, dice_sides) for _ in range(dice_num)] dice_results = [random.randint(1, dice_sides) for _ in range(dice_num)]
total = sum(dice) + dice_mod total = sum(dice_results) + dice_mod
roll_msg = f"Rolled {', '.join(map(str, dice))}" roll_msg = f"Rolled {', '.join(map(str, dice_results))}"
if dice_mod: if dice_mod:
if dice_mod > 0: if dice_mod > 0:
roll_msg += " + " + str(dice_mod) roll_msg += " + " + str(dice_mod)
else: else:
roll_msg += " - " + str(dice_mod)[1:] roll_msg += " - " + str(dice_mod)[1:]
roll_msg += " = " + str(total) roll_msg += " = " + str(total)
message += '<hr class="msgSrvHr" /><b>' + roll_msg + "</b>" message += '<hr class="msgSrvHr"><b>' + roll_msg + "</b>"
user = socket.scope['user'] user = socket.scope['user']
@ -89,6 +91,46 @@ def message(socket, data):
data['name'] = user.username data['name'] = user.username
socket.send('message', data) socket.send('message', data)
# append rolls to dicecall
if any(map(message.startswith, ["/dice", "/roll"])):
try:
dc = DiceCall.objects.get(post__quest__id=quest_id, open=True)
except DiceCall.DoesNotExist:
return
dice_roll = f"{dice_num}d{dice_sides}"
if dice_mod:
if dice_mod > 0:
dice_roll += "+"
dice_roll += str(dice_mod)
if dc.strict and dc.dice_roll != dice_roll:
return
dr = DiceRoll(
dicecall=dc,
message=m,
roll=dice_roll,
results=re.search(r"Rolled (.+) =", roll_msg).group(1),
total=total,
)
dr.save()
if DiceRoll.objects.filter(dicecall=dc).count() == dc.rolls_taken:
dc.open = False
dc.save()
socket.send('close_post', {'post_id': dc.post_id})
data = {}
data['post_text'] = roll_msg + " (" + dice_roll + ")"
if dc.dice_challenge:
if total >= dc.dice_challenge:
data["post_text"] += " - Pass"
else:
data["post_text"] += " - Fail"
data['post_type'] = 'dice'
data['post_id'] = dc.post_id
socket.send('update_post', data)
def text_post(socket, data): def text_post(socket, data):
""" """
@ -131,6 +173,13 @@ def dice_post(socket, data):
return # error message? return # error message?
form = form.cleaned_data form = form.cleaned_data
posts = Post.objects.filter(
quest__id=quest_id, post_type='dice', dicecall__open=True)
for post in posts:
post.dicecall.open = False
post.dicecall.save()
socket.send('close_all_posts')
dice_roll = str(form['diceNum']) + "d" dice_roll = str(form['diceNum']) + "d"
dice_roll += str(form['diceSides']) dice_roll += str(form['diceSides'])
if form['diceMod']: if form['diceMod']:
@ -149,7 +198,7 @@ def dice_post(socket, data):
post_text=post_text post_text=post_text
) )
p.save() p.save()
d = DiceCall( dc = DiceCall(
post=p, post=p,
dice_roll=dice_roll, dice_roll=dice_roll,
strict=form['diceStrict'], strict=form['diceStrict'],
@ -157,9 +206,7 @@ def dice_post(socket, data):
rolls_taken=form['diceRollsTaken'], rolls_taken=form['diceRollsTaken'],
open=True, open=True,
) )
d.save() dc.save()
socket.send('close_all_posts')
data = {} data = {}
data['post_text'] = post_text data['post_text'] = post_text
@ -174,6 +221,7 @@ def close_post(socket, data):
Called when the QM closes an open post. Called when the QM closes an open post.
""" """
post_id = data.get('post_id') post_id = data.get('post_id')
quest_id = data.get('quest_id')
p = Post.objects.get(id=post_id) p = Post.objects.get(id=post_id)
if data.get('post_type') == 'dice': if data.get('post_type') == 'dice':
p.dicecall.open = False p.dicecall.open = False
@ -193,9 +241,11 @@ def open_post(socket, data):
""" """
# TODO: only posts on last page can be opened # TODO: only posts on last page can be opened
post_id = data.get('post_id') post_id = data.get('post_id')
quest_id = data.get('quest_id')
p = Post.objects.get(id=post_id) p = Post.objects.get(id=post_id)
if data.get('post_type') == 'dice': if data.get('post_type') == 'dice':
posts = Post.objects.filter(post_type='dice', dicecall__open=True) posts = Post.objects.filter(
quest__id=quest_id, post_type='dice', dicecall__open=True)
for post in posts: for post in posts:
post.dicecall.open = False post.dicecall.open = False
post.dicecall.save() post.dicecall.save()

View File

@ -60,11 +60,11 @@
{% endautoescape %} {% endautoescape %}
{% elif post.post_type == "dice" %} {% elif post.post_type == "dice" %}
<h3>{{ post.post_text }} - {% if post.dicecall.open %}Open{% else %}Closed{% endif %}</h3> <h3>{{ post.post_text }} - {% if post.dicecall.open %}Open{% else %}Closed{% endif %}</h3>
{# for dice_roll in dice_rolls.get(post.id, []) %} {% for dice_roll in dice_rolls.filter(dicecall=post.dicecall) %}
<div id="questRollId-{{ dice_roll[0] }}"> <div id="questRollId-{{ dice_roll.id }}">
<b>Rolled {{ dice_roll[4] }} = {{ dice_roll[5] }} ({{ dice_roll[3] }}){% if post.id|dice_chal != 0 %} - {% if dice_roll[5] >= post.id|dice_chal %}Pass{% else %}Fail{% endif %}{% endif %}</b> <b>Rolled {{ dice_roll.results }} = {{ dice_roll.total }} ({{ dice_roll.roll }}){% if post.dicecall.dice_challenge %} - {% if dice_roll.total >= post.dicecall.dice_challenge %}Pass{% else %}Fail{% endif %}{% endif %}</b>
</div> </div>
{% endfor #} {% endfor %}
{% elif post.post_type == "poll" %} {% elif post.post_type == "poll" %}
<h3>{{ post.post_text }} - {% if post.poll.open %}Open{% else %}Closed{% endif %}</h3> <h3>{{ post.post_text }} - {% if post.poll.open %}Open{% else %}Closed{% endif %}</h3>
<table class="poll" id="poll-{{ post.id }}"> <table class="poll" id="poll-{{ post.id }}">

View File

@ -0,0 +1,24 @@
# Generated by Django 2.1 on 2018-08-25 01:06
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('quest', '0008_auto_20180824_0855'),
]
operations = [
migrations.CreateModel(
name='DiceRoll',
fields=[
('message', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='quest.Message')),
('roll', models.CharField(max_length=9)),
('results', models.TextField()),
('total', models.IntegerField()),
('dicecall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.DiceCall')),
],
),
]

View File

@ -16,6 +16,20 @@ class Quest(models.Model):
on_delete=models.CASCADE) on_delete=models.CASCADE)
class Message(models.Model):
"""
Represents a chat message.
"""
quest = models.ForeignKey(Quest, on_delete=models.CASCADE)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
blank=True,
null=True)
timestamp = models.DateTimeField(auto_now=True)
message = models.TextField(max_length=512)
class Post(models.Model): class Post(models.Model):
""" """
An object for arbituary posts. Contains all post data, type, etc. An object for arbituary posts. Contains all post data, type, etc.
@ -62,6 +76,21 @@ class DiceCall(models.Model):
open = models.BooleanField(default=False) open = models.BooleanField(default=False)
class DiceRoll(models.Model):
"""
Represents a dice roll made on a valid dicecall.
"""
dicecall = models.ForeignKey(DiceCall, on_delete=models.CASCADE)
message = models.OneToOneField(
Message,
on_delete=models.CASCADE,
primary_key=True,
)
roll = models.CharField(max_length=9)
results = models.TextField()
total = models.IntegerField()
class PageTitle(models.Model): class PageTitle(models.Model):
""" """
Represents the title of a quest page. Represents the title of a quest page.
@ -72,17 +101,3 @@ class PageTitle(models.Model):
def __str__(self): def __str__(self):
return self.title return self.title
class Message(models.Model):
"""
Represents a chat message.
"""
quest = models.ForeignKey(Quest, on_delete=models.CASCADE)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
blank=True,
null=True)
timestamp = models.DateTimeField(auto_now=True)
message = models.TextField(max_length=512)

View File

@ -17,10 +17,10 @@ function load() {
document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight; document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight;
let mtarea = document.getElementById('messageTextArea'); let mtarea = document.getElementById('messageTextArea');
mtarea.addEventListener('keypress', function(event) { mtarea.addEventListener('keypress', function(event) {
if (event.key == 'Enter' && !event.shiftKey) { if (event.key === 'Enter' && !event.shiftKey) {
let text = mtarea.value.trim(); let text = mtarea.value.trim();
mtarea.value = ''; mtarea.value = '';
if (text == '') { return; } if (text === '') { return; }
document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight; document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight;
socket.send('message', {message: text, quest_id: quest_id}); socket.send('message', {message: text, quest_id: quest_id});
} }
@ -45,20 +45,20 @@ socket.events['new_post'] = function(data) {
//deactivate_post(); //deactivate_post();
let qposts = document.getElementById('questPosts'); let qposts = document.getElementById('questPosts');
let post_str = '<div class="questPost '; let post_str = '<div class="questPost ';
if (data.post_type == 'text') { if (data.post_type === 'text') {
post_str += 'textPost">'; post_str += 'textPost">';
} else if (data.post_type == 'dice') { } else if (data.post_type === 'dice') {
post_str += 'dicePost active_post">'; post_str += 'dicePost active_post">';
} else if (data.post_type == 'poll') { } else if (data.post_type === 'poll') {
post_str += 'pollPost active_post">'; post_str += 'pollPost active_post">';
} }
post_str += '<div class="questPostMeta">' + data.date; post_str += '<div class="questPostMeta">' + data.date;
post_str += '</div><div class="questPostData" id="questPostData-' + data.post_id + '">'; post_str += '</div><div class="questPostData" id="questPostData-' + data.post_id + '">';
if (data.post_type == 'text') { if (data.post_type === 'text') {
post_str += data.post_text; post_str += data.post_text;
} else if (data.post_type == 'dice') { } else if (data.post_type === 'dice') {
post_str += '<h3>' + data.post_text + ' - Open</h3>'; post_str += '<h3>' + data.post_text + ' - Open</h3>';
} else if (data.post_type == 'poll') { } else if (data.post_type === 'poll') {
post_str += '<h3>' + data.post_text + ' - Open</h3>'; post_str += '<h3>' + data.post_text + ' - Open</h3>';
post_str += '<table class="poll" id="poll-' + data.post_id + '">'; post_str += '<table class="poll" id="poll-' + data.post_id + '">';
post_str += '<col/><col/><col/>'; post_str += '<col/><col/><col/>';
@ -87,14 +87,36 @@ socket.events['open_post'] = function(data) {
} }
socket.events['close_all_posts'] = function(data) { socket.events['close_all_posts'] = function(data) {
let class_set = ''; let class_set = '';
if (data.post_type == 'dice') { class_set = 'dicePost activePost'; } if (data.post_type === 'dice') { class_set = 'dicePost activePost'; }
else if (data.post_type == 'poll') { class_set = 'pollPost activePost'; } else if (data.post_type === 'poll') { class_set = 'pollPost activePost'; }
else { class_set = 'activePost'; } else { class_set = 'activePost'; }
let posts = document.getElementsByClassName(class_set); let posts = document.getElementsByClassName(class_set);
for (let i = 0; i < posts.length; i++) { for (let i = 0; i < posts.length; i++) {
close_post(posts[i].children[1].id.slice(14)); // retreive the id number at the end close_post(posts[i].children[1].id.slice(14)); // retreive the id number at the end
} }
} }
socket.events['update_post'] = function(data) {
let post = document.getElementById('questPostData-' + data.post_id);
if (data.post_type === 'text') {
post.innerHTML = data.post_text;
} else if (data.post_type === 'dice') {
post.innerHTML += '<b>' + data.post_text + '</b><br>';
} else if (data.post_type === 'poll') {
let row = post.children[1].insertRow(-1);
let cell = row.insertCell(0);
cell.className = 'pollCheckBox';
cell.innerHTML = '<input type="checkbox" id="pollInput-' + data.options_id + '" onchange="pollVote(' + data.post_id + ',' + data.options_id + ')"/>';
cell.innerHTML += '<label for="pollInput-' + data.options_id + '"></label>';
cell = row.insertCell(1);
cell.className = 'option_text';
cell.innerHTML = data.option_text;
cell = row.insertCell(2);
cell.className = "optionVotes";
cell.innerHTML = "0";
}
}
/* Helpers */ /* Helpers */
function padToTwo(number) { function padToTwo(number) {
@ -155,7 +177,6 @@ function open_post(post_id) {
let post = document.getElementById('questPostData-' + post_id); let post = document.getElementById('questPostData-' + post_id);
post.firstElementChild.textContent = post.firstElementChild.textContent.replace('Closed', 'Open'); post.firstElementChild.textContent = post.firstElementChild.textContent.replace('Closed', 'Open');
post.parentElement.className += ' activePost'; post.parentElement.className += ' activePost';
console.log(post.parentElement.className);
if (post.parentElement.classList.contains('pollPost')) { if (post.parentElement.classList.contains('pollPost')) {
let table = document.getElementById('poll-' + post_id); let table = document.getElementById('poll-' + post_id);
let boxes = table.getElementsByTagName('input'); let boxes = table.getElementsByTagName('input');

View File

@ -3,29 +3,29 @@ socket.events['new_post'] = function(data) {
//deactivate_post(); //deactivate_post();
let qposts = document.getElementById('questPosts'); let qposts = document.getElementById('questPosts');
let post_str = '<div class="questPost '; let post_str = '<div class="questPost ';
if (data.post_type == 'text') { if (data.post_type === 'text') {
post_str += 'textPost">'; post_str += 'textPost">';
} else if (data.post_type == 'dice') { } else if (data.post_type === 'dice') {
post_str += 'dicePost active_post">'; post_str += 'dicePost active_post">';
} else if (data.post_type == 'poll') { } else if (data.post_type === 'poll') {
post_str += 'pollPost active_post">'; post_str += 'pollPost active_post">';
} }
post_str += '<div class="questPostMeta">' + data.date; post_str += '<div class="questPostMeta">' + data.date;
/* QM only */ /* QM only */
if (data.post_type == 'text') { if (data.post_type === 'text') {
post_str += '<br /><a href="javascript:void(0);" onclick="edit_post(\'' + data.post_id + '\')">Edit</a>'; post_str += '<br /><a href="javascript:void(0);" onclick="edit_post(\'' + data.post_id + '\')">Edit</a>';
post_str += '<a href="javascript:void(0);" id="savePost-' + data.post_id + '" onclick="save_post(\'' + data.post_id + '\')" style="display:none;">Save</a>'; post_str += '<a href="javascript:void(0);" id="savePost-' + data.post_id + '" onclick="save_post(\'' + data.post_id + '\')" style="display:none;">Save</a>';
} else if (data.post_type == 'dice' || data.post_type == 'poll') { } else if (data.post_type === 'dice' || data.post_type === 'poll') {
post_str += '<br /><a href="javascript:void(0);" id="close_post_id-' + data.post_id + '" onclick="close_post(' + data.post_id + ')">Close</a>'; post_str += '<br /><a href="javascript:void(0);" id="close_post_id-' + data.post_id + '" onclick="close_post(' + data.post_id + ')">Close</a>';
post_str += '<a href="javascript:void(0);" id="open_post_id-' + data.post_id + '" onclick="open_post(' + data.post_id + ')" style="display:none;">Open</a>' post_str += '<a href="javascript:void(0);" id="open_post_id-' + data.post_id + '" onclick="open_post(' + data.post_id + ')" style="display:none;">Open</a>'
} }
/* end QM only */ /* end QM only */
post_str += '</div><div class="questPostData" id="questPostData-' + data.post_id + '">'; post_str += '</div><div class="questPostData" id="questPostData-' + data.post_id + '">';
if (data.post_type == 'text') { if (data.post_type === 'text') {
post_str += data.post_text; post_str += data.post_text;
} else if (data.post_type == 'dice') { } else if (data.post_type === 'dice') {
post_str += '<h3>' + data.post_text + ' - Open</h3>'; post_str += '<h3>' + data.post_text + ' - Open</h3>';
} else if (data.post_type == 'poll') { } else if (data.post_type === 'poll') {
post_str += '<h3>' + data.post_text + ' - Open</h3>'; post_str += '<h3>' + data.post_text + ' - Open</h3>';
post_str += '<table class="poll" id="poll-' + data.post_id + '">'; post_str += '<table class="poll" id="poll-' + data.post_id + '">';
post_str += '<col/><col/><col/>'; post_str += '<col/><col/><col/>';
@ -52,7 +52,7 @@ function makePost() {
let qparea = document.getElementById('postTextArea'); let qparea = document.getElementById('postTextArea');
let text = qparea.value.trim(); let text = qparea.value.trim();
qparea.value = ''; qparea.value = '';
if (text == '') { return; } if (text === '') { return; }
socket.send('text_post', {text: text, page_num: page_num, quest_id: quest_id}); socket.send('text_post', {text: text, page_num: page_num, quest_id: quest_id});
} }
function form_post(form_id, event) { function form_post(form_id, event) {
@ -67,20 +67,22 @@ function form_post(form_id, event) {
document.getElementById(form_id).reset(); document.getElementById(form_id).reset();
} }
function close_post_send(post_id) { function close_post_send(post_id) {
data = {post_id: post_id, quest_id: quest_id}
let post = document.getElementById('questPostData-' + post_id); let post = document.getElementById('questPostData-' + post_id);
if (post.parentElement.classList.contains('dicePost')) { if (post.parentElement.classList.contains('dicePost')) {
data = {post_type: 'dice', post_id: post_id}; data.post_type = 'dice';
} else if (post.parentElement.classList.contains('pollPost')) { } else if (post.parentElement.classList.contains('pollPost')) {
data = {post_type: 'poll', post_id: post_id}; data.post_type = 'poll';
} }
socket.send('close_post', data); socket.send('close_post', data);
} }
function open_post_send(post_id) { function open_post_send(post_id) {
data = {post_id: post_id, quest_id: quest_id}
let post = document.getElementById('questPostData-' + post_id); let post = document.getElementById('questPostData-' + post_id);
if (post.parentElement.classList.contains('dicePost')) { if (post.parentElement.classList.contains('dicePost')) {
data = {post_type: 'dice', post_id: post_id}; data.post_type = 'dice';
} else if (post.parentElement.classList.contains('pollPost')) { } else if (post.parentElement.classList.contains('pollPost')) {
data = {post_type: 'poll', post_id: post_id}; data.post_type = 'poll';
} }
socket.send('open_post', data); socket.send('open_post', data);
} }

View File

@ -5,7 +5,7 @@ Quest and quest accessory views.
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse from django.http import HttpResponse
from .models import Quest from .models import Quest, DiceRoll
def index(request): def index(request):
""" """
@ -22,5 +22,6 @@ def quest(request, quest_id, page_num=1):
quest = Quest.objects.get(id=quest_id) quest = Quest.objects.get(id=quest_id)
messages = quest.message_set.all() messages = quest.message_set.all()
posts = quest.post_set.all() posts = quest.post_set.all()
context = {'quest': quest, 'posts': posts, 'messages': messages, 'page_num': page_num} dice_rolls = DiceRoll.objects.filter(dicecall__post__quest__id=quest_id)
context = locals()
return render(request, 'quest/quest.html', context) return render(request, 'quest/quest.html', context)