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
QuestConsumer object in consumers.py.
"""
# TODO: quest owner only events
import re
import time
import types
@ -11,7 +12,7 @@ import random
import bleach
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
def message(socket, data):
@ -62,16 +63,17 @@ def message(socket, data):
assert -1000 < dice_mod < 1000
except (ValueError, AssertionError):
return
dice = [random.randint(1, dice_sides) for _ in range(dice_num)]
total = sum(dice) + dice_mod
roll_msg = f"Rolled {', '.join(map(str, dice))}"
dice_results = [random.randint(1, dice_sides) for _ in range(dice_num)]
total = sum(dice_results) + dice_mod
roll_msg = f"Rolled {', '.join(map(str, dice_results))}"
if dice_mod:
if dice_mod > 0:
roll_msg += " + " + str(dice_mod)
else:
roll_msg += " - " + str(dice_mod)[1:]
roll_msg += " = " + str(total)
message += '<hr class="msgSrvHr" /><b>' + roll_msg + "</b>"
message += '<hr class="msgSrvHr"><b>' + roll_msg + "</b>"
user = socket.scope['user']
@ -89,6 +91,46 @@ def message(socket, data):
data['name'] = user.username
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):
"""
@ -131,6 +173,13 @@ def dice_post(socket, data):
return # error message?
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['diceSides'])
if form['diceMod']:
@ -149,7 +198,7 @@ def dice_post(socket, data):
post_text=post_text
)
p.save()
d = DiceCall(
dc = DiceCall(
post=p,
dice_roll=dice_roll,
strict=form['diceStrict'],
@ -157,9 +206,7 @@ def dice_post(socket, data):
rolls_taken=form['diceRollsTaken'],
open=True,
)
d.save()
socket.send('close_all_posts')
dc.save()
data = {}
data['post_text'] = post_text
@ -174,6 +221,7 @@ def close_post(socket, data):
Called when the QM closes an open post.
"""
post_id = data.get('post_id')
quest_id = data.get('quest_id')
p = Post.objects.get(id=post_id)
if data.get('post_type') == 'dice':
p.dicecall.open = False
@ -193,9 +241,11 @@ def open_post(socket, data):
"""
# TODO: only posts on last page can be opened
post_id = data.get('post_id')
quest_id = data.get('quest_id')
p = Post.objects.get(id=post_id)
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:
post.dicecall.open = False
post.dicecall.save()

View File

@ -60,11 +60,11 @@
{% endautoescape %}
{% elif post.post_type == "dice" %}
<h3>{{ post.post_text }} - {% if post.dicecall.open %}Open{% else %}Closed{% endif %}</h3>
{# for dice_roll in dice_rolls.get(post.id, []) %}
<div id="questRollId-{{ dice_roll[0] }}">
<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>
{% for dice_roll in dice_rolls.filter(dicecall=post.dicecall) %}
<div id="questRollId-{{ dice_roll.id }}">
<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>
{% endfor #}
{% endfor %}
{% elif post.post_type == "poll" %}
<h3>{{ post.post_text }} - {% if post.poll.open %}Open{% else %}Closed{% endif %}</h3>
<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)
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):
"""
An object for arbituary posts. Contains all post data, type, etc.
@ -62,6 +76,21 @@ class DiceCall(models.Model):
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):
"""
Represents the title of a quest page.
@ -72,17 +101,3 @@ class PageTitle(models.Model):
def __str__(self):
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;
let mtarea = document.getElementById('messageTextArea');
mtarea.addEventListener('keypress', function(event) {
if (event.key == 'Enter' && !event.shiftKey) {
if (event.key === 'Enter' && !event.shiftKey) {
let text = mtarea.value.trim();
mtarea.value = '';
if (text == '') { return; }
if (text === '') { return; }
document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight;
socket.send('message', {message: text, quest_id: quest_id});
}
@ -45,20 +45,20 @@ socket.events['new_post'] = function(data) {
//deactivate_post();
let qposts = document.getElementById('questPosts');
let post_str = '<div class="questPost ';
if (data.post_type == 'text') {
if (data.post_type === 'text') {
post_str += 'textPost">';
} else if (data.post_type == 'dice') {
} else if (data.post_type === 'dice') {
post_str += 'dicePost active_post">';
} else if (data.post_type == 'poll') {
} else if (data.post_type === 'poll') {
post_str += 'pollPost active_post">';
}
post_str += '<div class="questPostMeta">' + data.date;
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;
} else if (data.post_type == 'dice') {
} else if (data.post_type === 'dice') {
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 += '<table class="poll" id="poll-' + data.post_id + '">';
post_str += '<col/><col/><col/>';
@ -87,14 +87,36 @@ socket.events['open_post'] = function(data) {
}
socket.events['close_all_posts'] = function(data) {
let class_set = '';
if (data.post_type == 'dice') { class_set = 'dicePost activePost'; }
else if (data.post_type == 'poll') { class_set = 'pollPost activePost'; }
if (data.post_type === 'dice') { class_set = 'dicePost activePost'; }
else if (data.post_type === 'poll') { class_set = 'pollPost activePost'; }
else { class_set = 'activePost'; }
let posts = document.getElementsByClassName(class_set);
for (let i = 0; i < posts.length; i++) {
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 */
function padToTwo(number) {
@ -155,7 +177,6 @@ function open_post(post_id) {
let post = document.getElementById('questPostData-' + post_id);
post.firstElementChild.textContent = post.firstElementChild.textContent.replace('Closed', 'Open');
post.parentElement.className += ' activePost';
console.log(post.parentElement.className);
if (post.parentElement.classList.contains('pollPost')) {
let table = document.getElementById('poll-' + post_id);
let boxes = table.getElementsByTagName('input');

View File

@ -3,29 +3,29 @@ socket.events['new_post'] = function(data) {
//deactivate_post();
let qposts = document.getElementById('questPosts');
let post_str = '<div class="questPost ';
if (data.post_type == 'text') {
if (data.post_type === 'text') {
post_str += 'textPost">';
} else if (data.post_type == 'dice') {
} else if (data.post_type === 'dice') {
post_str += 'dicePost active_post">';
} else if (data.post_type == 'poll') {
} else if (data.post_type === 'poll') {
post_str += 'pollPost active_post">';
}
post_str += '<div class="questPostMeta">' + data.date;
/* 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 += '<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 += '<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 */
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;
} else if (data.post_type == 'dice') {
} else if (data.post_type === 'dice') {
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 += '<table class="poll" id="poll-' + data.post_id + '">';
post_str += '<col/><col/><col/>';
@ -52,7 +52,7 @@ function makePost() {
let qparea = document.getElementById('postTextArea');
let text = qparea.value.trim();
qparea.value = '';
if (text == '') { return; }
if (text === '') { return; }
socket.send('text_post', {text: text, page_num: page_num, quest_id: quest_id});
}
function form_post(form_id, event) {
@ -67,20 +67,22 @@ function form_post(form_id, event) {
document.getElementById(form_id).reset();
}
function close_post_send(post_id) {
data = {post_id: post_id, quest_id: quest_id}
let post = document.getElementById('questPostData-' + post_id);
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')) {
data = {post_type: 'poll', post_id: post_id};
data.post_type = 'poll';
}
socket.send('close_post', data);
}
function open_post_send(post_id) {
data = {post_id: post_id, quest_id: quest_id}
let post = document.getElementById('questPostData-' + post_id);
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')) {
data = {post_type: 'poll', post_id: post_id};
data.post_type = 'poll';
}
socket.send('open_post', data);
}

View File

@ -5,7 +5,7 @@ Quest and quest accessory views.
from django.shortcuts import render
from django.http import HttpResponse
from .models import Quest
from .models import Quest, DiceRoll
def index(request):
"""
@ -22,5 +22,6 @@ def quest(request, quest_id, page_num=1):
quest = Quest.objects.get(id=quest_id)
messages = quest.message_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)