223 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			223 lines
		
	
	
		
			7.9 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"]
 | |
| 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 dam
 | |
|     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') |