223 lines
8.0 KiB
Python
223 lines
8.0 KiB
Python
import os
|
|
import re
|
|
from typing import List
|
|
from flask import Flask, render_template, request
|
|
from flask_wtf import FlaskForm
|
|
from wtforms import StringField, PasswordField, BooleanField
|
|
from wtforms import DecimalField, RadioField, SelectField, TextAreaField, FileField, IntegerField
|
|
from wtforms.validators import InputRequired,DataRequired,length
|
|
|
|
app = Flask(__name__)
|
|
app.config['SECRET_KEY'] = 'secretkey'
|
|
|
|
class MyForm(FlaskForm):
|
|
chatTekst = TextAreaField('Chat tekst', validators=[InputRequired()])
|
|
ac = IntegerField(label='Ac', validators=[InputRequired()])
|
|
advantage = BooleanField(label='Har advantage')
|
|
critRange = IntegerField(label='Crit over :' , validators=[InputRequired()])
|
|
|
|
|
|
|
|
class Action:
|
|
def __init__(self) -> None:
|
|
self.Dam=[]
|
|
self.hit=[]
|
|
self.targetAc=0
|
|
self.advantage=0
|
|
self.failedHitValue=0
|
|
self.critAbove=20
|
|
self.crits=False
|
|
self.atkMod=0
|
|
|
|
|
|
def setActionTypeToDam(self,value,value2,DamType):
|
|
self.Dam.append([value,value2,DamType])
|
|
|
|
def setAtkMod(self, mod):
|
|
if(mod>0):
|
|
self.atkMod=mod
|
|
|
|
def setActionTypeToHit(self,hitArray):
|
|
if(len(hitArray)>1):
|
|
self.hit=[hitArray[0][0],hitArray[0][1],hitArray[1][0],hitArray[1][1]]
|
|
else:
|
|
self.hit=[hitArray[0][0],hitArray[0][1],0,0]
|
|
|
|
def setTargetAc(self,ac):
|
|
self.targetAc=ac
|
|
def setWithAdvantage(self):
|
|
self.advantage=self.advantage+1
|
|
def setWithDisAdvantage(self):
|
|
self.advantage=self.advantage-1
|
|
def setCritRange(self,crit):
|
|
self.critAbove=crit
|
|
|
|
def getDamForHit(self):
|
|
dam=dict()
|
|
hits=False
|
|
crit=False
|
|
if(self.advantage==0):
|
|
if(((self.hit[0]+self.hit[1]) >=self.targetAc and (self.hit[0]-self.atkMod)>1) or self.critAbove<=(self.hit[0]-self.atkMod)): # 0 (rul 1 value), 1 (rul 1 bonus), 2 (rul 2 value), 3(rul 2 bonus)
|
|
hits=1
|
|
if(self.critAbove<=(self.hit[0]-self.atkMod)):
|
|
self.crits=1
|
|
if(self.advantage==1):
|
|
if(((self.hit[2]+self.hit[3]) >=self.targetAc and (self.hit[2]-self.atkMod)>1 or (self.hit[0]+self.hit[1]) >=self.targetAc and (self.hit[0]-self.atkMod)>1) or (self.critAbove<=self.hit[2]-self.atkMod) or (self.critAbove<=self.hit[0]-self.atkMod)):
|
|
hits=1
|
|
if((self.critAbove<=self.hit[2]-self.atkMod) or (self.critAbove<=self.hit[0]-self.atkMod)):
|
|
self.crits=1
|
|
|
|
if(self.advantage==-1):
|
|
if((((self.hit[2]+self.hit[3]) >=self.targetAc and (self.hit[2]-self.atkMod)>1) or ((self.critAbove<=self.hit[2]-self.atkMod))) and (((self.hit[0]+self.hit[1]) >=self.targetAc and (self.hit[0]-self.atkMod)>1) or (self.critAbove<=self.hit[0]-self.atkMod))):
|
|
hits=1
|
|
if((self.critAbove<=self.hit[2]-self.atkMod) and (self.critAbove<=self.hit[0]-self.atkMod)):
|
|
self.crits=1
|
|
|
|
if(hits==1):
|
|
for d in self.Dam: # Dam def: value,value2,DamType
|
|
if(self.crits):
|
|
dam[d[2]]=d[0]+d[1]
|
|
else:
|
|
dam[d[2]]=d[0]
|
|
return dam
|
|
|
|
def getFumble(self):
|
|
fumbles=True
|
|
if(self.advantage==0):
|
|
if((self.hit[0]-self.atkMod)>1): # 0 (rul 1 value), 1 (rul 1 bonus), 2 (rul 2 value), 3(rul 2 bonus)
|
|
fumbles=False
|
|
if(self.advantage==1):
|
|
if((self.hit[0]-self.atkMod)>1 or (self.hit[2]-self.atkMod)>1):
|
|
fumbles=False
|
|
if(self.advantage==-1):
|
|
if((self.hit[0]-self.atkMod)>1 and (self.hit[2]-self.atkMod)>1):
|
|
fumbles=False
|
|
return fumbles
|
|
|
|
damTypes=["Slashing","Radiant","Great Weapon Master","Divine","Holy Weapon","Great Weapon Master/Radiant", "Bludgeoning","arm of dawn, Awakend","Lightning"]
|
|
con=0
|
|
def incContext():
|
|
res=0
|
|
if(con==0):
|
|
con=1
|
|
res=1
|
|
con=con+1
|
|
if(con>2):
|
|
con=1
|
|
res=1
|
|
|
|
def getContext():
|
|
return con
|
|
def isItTheRightContext(c,line):
|
|
res=0
|
|
return res
|
|
|
|
def checkIfCounts(line):
|
|
estCon=0
|
|
if(re.match("(^_?[0-9]+){1}( \+ [0-9]+)?( [0-9]+( \+ [0-9])*)?", line)):
|
|
print("match : " + line)
|
|
estCon=1 # attackroll eller
|
|
s=re.search('\([-|\+][0-9]+\)+', line)
|
|
if(s!=None):
|
|
print("match modifier: " + line)
|
|
estCon=3
|
|
return estCon
|
|
|
|
def getAllDamage(runder):
|
|
dam=dict()
|
|
dam['Samlet']=0
|
|
for r in runder:
|
|
print(r)
|
|
damage = r.getDamForHit()
|
|
for d in damage:
|
|
print(d)
|
|
if(dam.get(d)==None):
|
|
dam[d]=damage[d]
|
|
dam['Samlet']=dam['Samlet']+damage[d]
|
|
else:
|
|
dam[d]=dam[d]+damage[d]
|
|
dam['Samlet']=dam['Samlet']+damage[d]
|
|
|
|
return dam
|
|
|
|
|
|
|
|
def parseText(runder,lines,ac,advantage,critRange):
|
|
line=None
|
|
attMod=0
|
|
for nextLine in lines:
|
|
nextLine=nextLine.strip()
|
|
if(line==None):
|
|
line=nextLine
|
|
continue
|
|
|
|
print(line)
|
|
c=checkIfCounts(line)
|
|
|
|
if(c==3): # attack modifier
|
|
s=re.search('\([-|\+][0-9]+\)+', line)
|
|
v=re.search('[0-9]+', s.group(0))
|
|
if(s.group(0)[1]=='+'):
|
|
curAction.setAtkMod(int(v.group(0)))
|
|
else:
|
|
curAction.setAtkMod(0-int(v.group(0)))
|
|
if(c==1):
|
|
if(nextLine in damTypes):
|
|
c=2 # damage
|
|
else:
|
|
c=1 # to hit
|
|
if(c==1): # Hit
|
|
lastActionFumble=False
|
|
if(len(runder)>0):
|
|
lastActionFumble=curAction.getFumble()
|
|
curAction=Action()
|
|
curAction.setTargetAc(ac)
|
|
if(critRange!=20 and critRange!=None): curAction.setCritRange(critRange)
|
|
if(advantage): curAction.setWithAdvantage()
|
|
if(lastActionFumble): curAction.setWithDisAdvantage()
|
|
h=line.split(" ")
|
|
HitArray=[]
|
|
if(h[0].rfind("+")>-1 or h[0].rfind("-")>-1):
|
|
if(h[0].rfind("+")>-1):
|
|
HitArray.append([int(h[0].split("+")[0]),int(h[0].split("+")[1].strip())])
|
|
else:
|
|
HitArray.append([int(h[0].split("+")[0]),0-int(h[0].split("+")[1].strip())])
|
|
else:
|
|
HitArray.append([int(h[0].strip()),0])
|
|
if(len(h)>1):
|
|
if((h[1].rfind("+")>-1 or h[1].rfind("-")>-1)):
|
|
if(h[1].rfind("+")>-1):
|
|
HitArray.append([int(h[1].split("+")[0]),int(h[1].split("+")[1].strip())])
|
|
else:
|
|
HitArray.append([int(h[1].split("-")[0]),0-int(h[1].split("-")[1].strip())])
|
|
else:
|
|
HitArray.append([int(h[1].strip()),0])
|
|
curAction.setActionTypeToHit(HitArray)
|
|
runder.append(curAction)
|
|
if(c==2): # Skade
|
|
if(len(runder)==0):
|
|
continue
|
|
curAction=runder[len(runder)-1]
|
|
if(line.rfind("+")>-1 or line.rfind("-")>-1):
|
|
if(line.rfind("+")>-1):
|
|
curAction.setActionTypeToDam(int(line.split("+")[0]),int(line.split("+")[1].strip()),nextLine)
|
|
else:
|
|
curAction.setActionTypeToDam(int(line.split("-")[0]),0-int(line.split("-")[1].strip()),nextLine)
|
|
else:
|
|
curAction.setActionTypeToDam(int(line.strip()),0,nextLine)
|
|
line=nextLine
|
|
file1 = open("input.txt", "w")
|
|
@app.route('/', methods=['GET', 'POST'])
|
|
def main():
|
|
form = MyForm()
|
|
runder: List[Action] = list()
|
|
if form.validate_on_submit():
|
|
for a in form.chatTekst.data.splitlines():
|
|
file1.writelines(form.chatTekst.data.splitlines())
|
|
parseText(runder,form.chatTekst.data.splitlines(),form.ac.data, form.advantage.data, form.critRange.data)
|
|
|
|
|
|
dam=getAllDamage(runder)
|
|
return render_template('index.html', dam=dam, form=form)
|
|
if __name__ == '__main__':
|
|
app.run(debug=False, port=5432, host='0.0.0.0') |