massive, madman refactoring. What was I thinking?

This commit is contained in:
Greg Gauthier 2024-06-25 22:26:04 +01:00
parent 0e97185ce8
commit 4d92acf3ee
29 changed files with 571 additions and 458 deletions

455
app.py
View File

@ -1,455 +0,0 @@
from flask import Flask
from flask_cors import CORS
from flask_restx import Api, Resource
from models import dice_model, ability_model, hp_model, character_model, encounter_model, ma_model, mutation_model, \
check_model
from schemas import DiceSchema, CharacterSchema, EncounterSchema, MentalAttackSchema, AbilitySchema, HPSchema, \
MutationSchema, CheckSchema
from encounters import EncounterTable
from mentattack import MentalAttackMatrix
from mutations import Mutations
from cybermods import CyberMods
import random
app = Flask(__name__)
CORS(app)
app.config.SWAGGER_UI_JSONEDITOR = True
app.config['SWAGGER_UI_JSONEDITOR'] = True
api = Api(app, version='1.0', title='Gamma World Dice', description='Rolled Dice As A Service')
dice = api.namespace('dice', description='Dice operations')
ability = api.namespace('ability', description='Ability operations')
hp = api.namespace('hp', description='HP operations')
ma = api.namespace('ma', description='Mental Attack operations')
mut = api.namespace('mut', description='Mutation operations')
character = api.namespace('character', description='Character operations')
encounter = api.namespace('encounter', description='Encounter operations')
check = api.namespace('check', description='Check operations')
check_model = check.model('Check', check_model )
check_schema = CheckSchema()
ability_model = ability.model('Ability', ability_model)
ability_schema = AbilitySchema()
mutation_model = mut.model('Mutation', mutation_model)
mutation_schema = MutationSchema()
hp_model = hp.model('HP', hp_model)
hp_schema = HPSchema()
dice_model = dice.model('Dice', dice_model)
dice_schema = DiceSchema()
ma_model = ma.model('MA', ma_model)
ma_schema = MentalAttackSchema()
character_model = character.model('Character', character_model)
character_schema = CharacterSchema()
encounter_model = encounter.model('Encounter', encounter_model)
encounter_schema = EncounterSchema()
@api.route('/roll/dice', methods=['POST'])
class RollDice(Resource):
@dice.expect(dice_model)
def post(self):
data = api.payload
errors = dice_schema.validate(data)
if errors:
return errors, 400
quantity = data.get('quantity')
geometry = data.get('geometry')
discard_lowest = data.get('discard_lowest')
if quantity is None or geometry is None:
return {"message": "Required dice data not provided"}, 400
return roll_dices(quantity, geometry, discard_lowest), 200
@api.route('/roll/ability', methods=['POST'])
class RollAbility(Resource):
@ability.expect(ability_model)
def post(self):
data = api.payload
errors = ability_schema.validate(data)
if errors:
return errors, 400
chartype = data.get('chartype')
attribute = data.get('ability')
return roll_ability_scores(chartype, attribute), 200
@api.route('/roll/hp', methods=['POST'])
class RollHP(Resource):
@hp.expect(hp_model)
def post(self):
data = api.payload
errors = hp_schema.validate(data)
if errors:
return errors, 400
chartype = data.get('chartype')
conscore = data.get('conscore')
if conscore is None:
return {"message": "A constitution score is required"}, 400
if chartype == 'human':
geometry = 8
else:
geometry = 6
return roll_dices(conscore, geometry, False), 200
@api.route('/roll/encounter', methods=['POST'])
class RollEncounter(Resource):
@encounter.expect(encounter_model)
def post(self):
data = api.payload
errors = encounter_schema.validate(data)
if errors:
return errors, 400
terrain = data.get('terrain').lower()
roll = roll_dices(1, 20, False).get('result')
et = EncounterTable()
creature = et.get_encounter(roll, terrain)
if creature is None:
creature = "All clear!"
return {"encounter": creature}, 200
@api.route('/roll/attack/mental', methods=['POST'])
class RollMentalAttack(Resource):
@ma.expect(ma_model)
def post(self):
data = api.payload
errors = ma_schema.validate(data)
if errors:
return errors, 400
ams = data.get('ams')
dms = data.get('dms')
modifier = data.get('modifier')
result = {}
mam = MentalAttackMatrix()
needed = mam.get_attack_score(ams, dms)
result["needed"] = needed
outcome = None
if needed < 2:
outcome = "Automatic Success!"
elif needed > 20:
outcome = "Absolutely No Chance!"
else:
raw_roll = roll_dices(1, 20, False).get('result')
if modifier != 0:
result["original-roll"] = raw_roll
result["modifier"] = modifier
rolled = raw_roll + modifier # negative modifiers will subtract themselves naturally
result["adjusted-roll"] = rolled
else:
rolled = raw_roll
result["original-roll"] = rolled
if (rolled >= 20) and (needed <= 16):
outcome = "Devastating Success!"
elif needed <= rolled:
outcome = "Attack Successful!"
elif needed > rolled:
outcome = "Attack Failed!"
result["outcome"] = outcome
return result, 200
@api.route('/roll/check', methods=['POST'])
class RollCheck(Resource):
@check.expect(check_model)
def post(self):
data = api.payload
errors = check_schema.validate(data)
if errors:
return errors, 400
ability_score = data.get('ability_score')
multiplier = data.get('multiplier')
threshold = ability_score * multiplier
rolled = roll_dices(1, 100, False).get('result')
if rolled < threshold:
return {'threshold': threshold, 'rolled': rolled, 'success': True}, 200
else:
return {'threshold': threshold, 'rolled': rolled, 'success': False}, 200
@api.route('/roll/tohit', methods=['GET'])
class RollToHit(Resource):
@staticmethod
def get():
return roll_dices(1, 20, False), 200
@api.route('/roll/chance', methods=['GET'])
class RollChance(Resource):
@staticmethod
def get():
return roll_dices(1, 100, False), 200
@api.route('/coinflip', methods=['GET'])
class RollCoinflip(Resource):
@staticmethod
def get():
return random.choice(['Heads', 'Tails']), 200
@api.route('/roll/mutations', methods=['POST'])
class RollMutations(Resource):
@mut.expect(mutation_model)
def post(self):
data = api.payload
errors = mutation_schema.validate(data)
if errors:
return errors, 400
conscore = data.get('conscore')
intscore = data.get('intscore')
return roll_mutations(conscore, intscore), 200
@api.route('/character/generate', methods=['POST'])
class GenerateCharacter(Resource):
@character.expect(character_model)
def post(self):
data = api.payload
errors = character_schema.validate(data)
if errors:
return errors, 400
chartype = data.get('chartype')
character_sheet = {}
if chartype == 'mutant':
character_sheet['animal-stock'] = (roll_mutant_animal())
ability_scores = roll_ability_scores(chartype)
character_sheet['abilities'] = ability_scores
character_sheet['hp'] = roll_hp(chartype, ability_scores['constitution'])
character_sheet['gold'] = roll_dices(4, 4, False).get('result') * 10
character_sheet['domar'] = roll_dices(2, 4, False).get('result') * 5
if chartype == 'humanoid' or chartype == 'mutant':
character_sheet['mutations'] = (
roll_mutations(ability_scores['constitution'], ability_scores['intelligence'])
)
if chartype == 'cyborg':
character_sheet['cybermods'] = (
roll_cybermods()
)
return character_sheet, 200
def roll_dices(dice_count, dice_sides, discard_lowest):
roll_results = []
discarded = []
for _ in range(dice_count):
roll_results.append(random.randint(1, dice_sides))
if discard_lowest and len(roll_results) > 0:
discarded.append(min(roll_results))
roll_results.remove(min(roll_results))
if discarded:
net_dice_count = dice_count - 1
mnemonic = str(dice_count) + "(-1)d" + str(dice_sides)
else:
mnemonic = str(dice_count) + 'd' + str(dice_sides)
net_dice_count = dice_count
result = {
'dice-set': {
'mnemonic': mnemonic,
'min-roll': net_dice_count,
'max-roll': dice_sides * net_dice_count
},
'rolls': roll_results,
'result': sum(roll_results)
}
if discarded:
result['discarded'] = discarded
return result
def roll_ability_scores(chartype, attribute=None):
if attribute is None or attribute == "all":
ability_list = ['p-strength', 'm-strength', 'constitution', 'dexterity', 'charisma', 'intelligence']
else:
ability_list = [attribute]
ability_scores = {}
for abil in ability_list:
if ((chartype == 'human') and
((abil == 'intelligence') or
(abil == 'charisma') or
(abil == 'constitution'))):
roll = roll_dices(4, 6, False) # humans are special
if (abil == 'constitution') and roll["result"] > 18:
roll["capped"] = True
roll["result"] = 18
if (abil == 'intelligence' or abil == 'charisma') and roll["result"] > 21:
roll["capped"] = True
roll["result"] = 21
ability_scores[abil] = roll["result"]
else:
roll = roll_dices(4, 6, True) # nothing else is special
ability_scores[abil] = roll["result"]
return ability_scores
def roll_hp(chartype, conscore):
if chartype == 'human':
geometry = 8
else:
geometry = 6
return roll_dices(conscore, geometry, False).get('result')
def roll_cybermods():
"""
Cybermods are similar to mutations, except that they are artificial changes to the body,
where mutations are 'natural' changes to the body. Fewer cybermods are possible than with
mutations. So, you make one roll of 1d4, and then parse up the score between the two
types of mods, as you see fit. If no emphasis is specified, the score will be split as evenly
as possible. If the score is 1, then a physical mod will be the default.
:return: table of cybermods (in json format)
"""
cybermods_table = {}
cybermods_count = roll_dices(1, 4, False)["result"]
phys_cnt = split_number(cybermods_count)[1] # This ends up being the higher of the two numbers
ment_cnt = split_number(cybermods_count)[0]
cybermods_table['count'] = {'mental': ment_cnt, 'physical': phys_cnt}
mental_cybermods_scores = []
physical_cybermods_scores = []
for _ in range(ment_cnt):
mscore = roll_dices(1, 10, False).get('result')
if mscore in mental_cybermods_scores:
mscore = roll_dices(1, 10, False).get('result')
mental_cybermods_scores.append(mscore)
for _ in range(phys_cnt):
pscore = roll_dices(1, 10, False).get('result')
if pscore in physical_cybermods_scores:
pscore = roll_dices(1, 10, False).get('result')
physical_cybermods_scores.append(pscore)
cyb = CyberMods()
mcyb = []
pcyb = []
for score in mental_cybermods_scores:
modification = cyb.get_mental_cybermod(score)
mcyb.append(modification)
if len(mcyb) != 0:
cybermods_table['mental'] = mcyb
for score in physical_cybermods_scores:
modification = cyb.get_physical_cybermod(score)
pcyb.append(modification)
if len(pcyb) != 0:
cybermods_table['physical'] = pcyb
return cybermods_table
def roll_mutations(conscore, intscore):
"""
:param conscore: modifier for physical mutation determination
:param intscore: modifier for mental mutation determination
:return: table of mutations (in json form)
"""
mutations_table = {}
mental_mutations_cnt = roll_dices(1, 4, False).get('result')
physical_mutations_cnt = roll_dices(1, 4, False).get('result')
mutations_table['count'] = {'mental': mental_mutations_cnt, 'physical': physical_mutations_cnt}
mental_mutations_scores = get_score_list(mental_mutations_cnt, intscore)
mutations_table['mental'] = get_mutations(mental_mutations_scores)
physical_mutations_scores = get_score_list(physical_mutations_cnt, conscore)
mutations_table['physical'] = get_mutations(physical_mutations_scores)
return mutations_table
def get_mutations(scorelist):
mut_table = Mutations()
mut_list = []
for score in scorelist:
mutation = mut_table.get_mental_mutation(score)
mut_list.append(mutation)
return mut_list
def get_score_list(count, modifier):
tmp_scores = []
for _ in range(count):
roll = roll_dices(1, 100, False).get('result') + modifier
if roll in tmp_scores:
roll = roll_dices(1, 100, False).get('result') + modifier
if roll > 100:
roll = 100
tmp_scores.append(roll)
return tmp_scores
def roll_mutant_animal():
creature = dict()
animal_stock = ['badger', 'racoon', 'hound', 'wolf', 'big-cat', 'fox',
'spider', 'lizard', 'ant', 'hornet', 'hawk', 'ostrich', 'emu', 'crocodile',
'snake', 'rabbit', 'rat', 'bear', 'elephant', 'platypus', 'bull', 'horse', 'goat', 'bat',
'silverfish', 'cockroach', 'turtle', 'gibbon', 'penguin', 'orangutan', 'chimpanzee',
'housefly', 'lobster', 'crab', 'prawn', 'pig', 'chicken', 'duck', 'parrot', 'mouse',
'heron', 'weasel', 'squirrel', 'pigeon', 'crow', 'house-cat', 'shark', 'dolphin', 'narwhal',
'buffalo']
posture = ['upright', 'prone', 'mixed']
creature['stock'] = random.choice(animal_stock)
creature['posture'] = random.choice(posture)
if creature['posture'] == 'upright' or creature['posture'] == 'mixed':
creature['arms'] = random.choice(list(range(2, 4, 2))) # if you're upright 4 is the limit
creature['legs'] = random.choice(list(range(2, 6, 2))) # same with legs
if creature['posture'] == 'prone':
creature['legs'] = random.choice(list(range(4, 8, 2))) # if you're prone, you only get legs
return creature
def split_number(n):
first_split = n // 2 # this will split the number in two equal parts, if it is even
second_split = n % 2 + first_split # this will add one to one part if the number is odd
return first_split, second_split
if __name__ == '__main__':
app.run()

0
app/__init__.py Normal file
View File

205
app/app.py Normal file
View File

@ -0,0 +1,205 @@
import random
from flask import Flask
from flask_cors import CORS
from flask_restx import Api, Resource
from app.functions.build_character_sheet import build_character_sheet
from app.functions.roll_ability_scores import roll_ability_scores
from app.functions.roll_ability_check import roll_ability_check
from app.functions.roll_dices import roll_dices
from app.functions.roll_encounter import roll_encounter
from app.functions.roll_mental_attack import roll_mental_attack
from app.functions.roll_mutations import roll_mutations
from app.models.models import dice_model, ability_model, hp_model, character_model, encounter_model, ma_model, \
mutation_model, \
check_model
from app.schemas.schemas import DiceSchema, CharacterSchema, EncounterSchema, MentalAttackSchema, AbilitySchema, \
HPSchema, \
MutationSchema, CheckSchema
app = Flask(__name__)
CORS(app)
app.config.SWAGGER_UI_JSONEDITOR = True
app.config['SWAGGER_UI_JSONEDITOR'] = True
api = Api(app, version='1.0', title='Gamma World Dice', description='Rolled Dice As A Service')
dice = api.namespace('dice', description='Dice operations')
ability = api.namespace('ability', description='Ability operations')
hp = api.namespace('hp', description='HP operations')
ma = api.namespace('ma', description='Mental Attack operations')
mut = api.namespace('mut', description='Mutation operations')
character = api.namespace('character', description='Character operations')
encounter = api.namespace('encounter', description='Encounter operations')
check = api.namespace('check', description='Check operations')
check_model = check.model('Check', check_model)
check_schema = CheckSchema()
ability_model = ability.model('Ability', ability_model)
ability_schema = AbilitySchema()
mutation_model = mut.model('Mutation', mutation_model)
mutation_schema = MutationSchema()
hp_model = hp.model('HP', hp_model)
hp_schema = HPSchema()
dice_model = dice.model('Dice', dice_model)
dice_schema = DiceSchema()
ma_model = ma.model('MA', ma_model)
ma_schema = MentalAttackSchema()
character_model = character.model('Character', character_model)
character_schema = CharacterSchema()
encounter_model = encounter.model('Encounter', encounter_model)
encounter_schema = EncounterSchema()
@api.route('/roll/dice', methods=['POST'])
class RollDice(Resource):
@dice.expect(dice_model)
def post(self):
data = api.payload
errors = dice_schema.validate(data)
if errors:
return errors, 400
quantity = data.get('quantity')
geometry = data.get('geometry')
discard_lowest = data.get('discard_lowest')
if quantity is None or geometry is None:
return {"message": "Required dice data not provided"}, 400
return roll_dices(quantity, geometry, discard_lowest), 200
@api.route('/roll/ability', methods=['POST'])
class RollAbility(Resource):
@ability.expect(ability_model)
def post(self):
data = api.payload
errors = ability_schema.validate(data)
if errors:
return errors, 400
chartype = data.get('chartype')
attribute = data.get('ability')
return roll_ability_scores(chartype, attribute), 200
@api.route('/roll/hp', methods=['POST'])
class RollHP(Resource):
@hp.expect(hp_model)
def post(self):
data = api.payload
errors = hp_schema.validate(data)
if errors:
return errors, 400
chartype = data.get('chartype')
conscore = data.get('conscore')
if conscore is None:
return {"message": "A constitution score is required"}, 400
if chartype == 'human':
geometry = 8
else:
geometry = 6
return roll_dices(conscore, geometry, False), 200
@api.route('/roll/encounter', methods=['POST'])
class RollEncounter(Resource):
@encounter.expect(encounter_model)
def post(self):
data = api.payload
errors = encounter_schema.validate(data)
if errors:
return errors, 400
terrain = data.get('terrain').lower()
return roll_encounter(terrain), 200
@api.route('/roll/attack/mental', methods=['POST'])
class RollMentalAttack(Resource):
@ma.expect(ma_model)
def post(self):
data = api.payload
errors = ma_schema.validate(data)
if errors:
return errors, 400
ams = data.get('ams')
dms = data.get('dms')
modifier = data.get('modifier')
return roll_mental_attack(ams, dms, modifier), 200
@api.route('/roll/check', methods=['POST'])
class RollCheck(Resource):
@check.expect(check_model)
def post(self):
data = api.payload
errors = check_schema.validate(data)
if errors:
return errors, 400
ability_score = data.get('ability_score')
multiplier = data.get('multiplier')
return roll_ability_check(ability_score, multiplier), 200
@api.route('/roll/tohit', methods=['GET'])
class RollToHit(Resource):
@staticmethod
def get():
return roll_dices(1, 20, False), 200
@api.route('/roll/chance', methods=['GET'])
class RollChance(Resource):
@staticmethod
def get():
return roll_dices(1, 100, False), 200
@api.route('/coinflip', methods=['GET'])
class RollCoinflip(Resource):
@staticmethod
def get():
return random.choice(['Heads', 'Tails']), 200
@api.route('/roll/mutations', methods=['POST'])
class RollMutations(Resource):
@mut.expect(mutation_model)
def post(self):
data = api.payload
errors = mutation_schema.validate(data)
if errors:
return errors, 400
conscore = data.get('conscore')
intscore = data.get('intscore')
return roll_mutations(conscore, intscore), 200
@api.route('/character/generate', methods=['POST'])
class GenerateCharacter(Resource):
@character.expect(character_model)
def post(self):
data = api.payload
errors = character_schema.validate(data)
if errors:
return errors, 400
chartype = data.get('chartype')
return build_character_sheet(chartype), 200
if __name__ == '__main__':
app.run()

View File

View File

@ -0,0 +1,36 @@
from app.functions.roll_dices import roll_dices
from app.functions.roll_ability_scores import roll_ability_scores
from app.functions.roll_cybermods import roll_cybermods
from app.functions.roll_mutations import roll_mutations
from app.functions.roll_hp import roll_hp
from app.functions.generate_profile import generate_profile
from app.functions.roll_mutant_animal import roll_mutant_animal
def build_character_sheet(chartype):
character_sheet = dict()
character_sheet['profile'] = generate_profile(chartype)
if chartype == 'mutant':
character_sheet['animal-stock'] = (roll_mutant_animal())
ability_scores = roll_ability_scores(chartype)
character_sheet['abilities'] = ability_scores
character_sheet['hp'] = roll_hp(chartype, ability_scores['constitution'])
character_sheet['gold'] = roll_dices(4, 4, False).get('result') * 10
character_sheet['domar'] = roll_dices(2, 4, False).get('result') * 5
if chartype == 'humanoid' or chartype == 'mutant':
character_sheet['mutations'] = (
roll_mutations(ability_scores['constitution'], ability_scores['intelligence'])
)
if chartype == 'cyborg':
character_sheet['cybermods'] = (
roll_cybermods()
)
return character_sheet

View File

@ -0,0 +1,16 @@
import random
from app.functions.get_character_age import get_age
def generate_profile(chartype):
profile = {
'name': "Anon",
'sex': random.choice(['male', 'female', 'male', 'female', 'male', 'female']),
'age': get_age(chartype)
}
if chartype == 'human':
profile['hair'] = random.choice(['black', 'brown', 'auburn', 'blonde', 'copper', 'brass', 'blue', 'bald'])
profile['eyes'] = random.choice(['blue', 'brown', 'green', 'hazel', 'gray'])
profile['skintone'] = random.choice(['dark', 'olive', 'medium', 'light', 'pale'])
return profile

View File

@ -0,0 +1,36 @@
import random
def get_age(chartype):
ages = {
"human": {
'youth': (14, 18),
'young': (19, 38),
'midage': (39, 58),
'veteran': (59, 72)
},
"humanoid": {
'youth': (8, 19),
'young': (20, 48),
'midage': (49, 68),
'veteran': (69, 82)
},
"mutant": {
'youth': (8, 13),
'young': (14, 28),
'midage': (29, 48),
'veteran': (49, 62)
},
"cyborg": {
'youth': (14, 18),
'young': (19, 38),
'midage': (39, 58),
'veteran': (59, 72)
}
}
char_range = ages[chartype]
age_group = random.choice(list(char_range.keys()))
age_range = char_range[age_group]
return random.choice(age_range)

View File

@ -0,0 +1,10 @@
from app.tables.mutations import Mutations
def get_mutations(scorelist):
mut_table = Mutations()
mut_list = []
for score in scorelist:
mutation = mut_table.get_mental_mutation(score)
mut_list.append(mutation)
return mut_list

View File

@ -0,0 +1,14 @@
from app.functions.roll_dices import roll_dices
def get_score_list(count, modifier):
tmp_scores = []
for _ in range(count):
roll = roll_dices(1, 100, False).get('result') + modifier
if roll in tmp_scores:
roll = roll_dices(1, 100, False).get('result') + modifier
if roll > 100:
roll = 100
tmp_scores.append(roll)
return tmp_scores

View File

@ -0,0 +1,10 @@
from app.functions.roll_dices import roll_dices
def roll_ability_check(score, multiplier):
threshold = score * multiplier
rolled = roll_dices(1, 100, False).get('result')
if rolled < threshold:
return {'threshold': threshold, 'rolled': rolled, 'success': True}, 200
else:
return {'threshold': threshold, 'rolled': rolled, 'success': False}, 200

View File

@ -0,0 +1,29 @@
from app.functions.roll_dices import roll_dices
def roll_ability_scores(chartype, attribute=None):
if attribute is None or attribute == "all":
ability_list = ['p-strength', 'm-strength', 'constitution', 'dexterity', 'charisma', 'intelligence']
else:
ability_list = [attribute]
ability_scores = {}
for abil in ability_list:
if ((chartype == 'human') and
((abil == 'intelligence') or
(abil == 'charisma') or
(abil == 'constitution'))):
roll = roll_dices(4, 6, False) # humans are special
if (abil == 'constitution') and roll["result"] > 18:
roll["capped"] = True
roll["result"] = 18
if (abil == 'intelligence' or abil == 'charisma') and roll["result"] > 21:
roll["capped"] = True
roll["result"] = 21
ability_scores[abil] = roll["result"]
else:
roll = roll_dices(4, 6, True) # nothing else is special
ability_scores[abil] = roll["result"]
return ability_scores

View File

@ -0,0 +1,55 @@
from app.functions.roll_dices import roll_dices
from app.tables.cybermods import CyberMods
from app.functions.split_number import split_number
def roll_cybermods():
"""
Cybermods are similar to mutations, except that they are artificial changes to the body,
where mutations are 'natural' changes to the body. Fewer cybermods are possible than with
mutations. So, you make one roll of 1d4, and then parse up the score between the two
types of mods, as you see fit. If no emphasis is specified, the score will be split as evenly
as possible. If the score is 1, then a physical mod will be the default.
:return: table of cybermods (in json format)
"""
cybermods_table = {}
cybermods_count = roll_dices(1, 4, False)["result"]
phys_cnt = split_number(cybermods_count)[1] # This ends up being the higher of the two numbers
ment_cnt = split_number(cybermods_count)[0]
cybermods_table['count'] = {'mental': ment_cnt, 'physical': phys_cnt}
mental_cybermods_scores = []
physical_cybermods_scores = []
for _ in range(ment_cnt):
mscore = roll_dices(1, 10, False).get('result')
if mscore in mental_cybermods_scores:
mscore = roll_dices(1, 10, False).get('result')
mental_cybermods_scores.append(mscore)
for _ in range(phys_cnt):
pscore = roll_dices(1, 10, False).get('result')
if pscore in physical_cybermods_scores:
pscore = roll_dices(1, 10, False).get('result')
physical_cybermods_scores.append(pscore)
cyb = CyberMods()
mcyb = []
pcyb = []
for score in mental_cybermods_scores:
modification = cyb.get_mental_cybermod(score)
mcyb.append(modification)
if len(mcyb) != 0:
cybermods_table['mental'] = mcyb
for score in physical_cybermods_scores:
modification = cyb.get_physical_cybermod(score)
pcyb.append(modification)
if len(pcyb) != 0:
cybermods_table['physical'] = pcyb
return cybermods_table

View File

@ -0,0 +1,32 @@
import random
def roll_dices(dice_count, dice_sides, discard_lowest):
roll_results = []
discarded = []
for _ in range(dice_count):
roll_results.append(random.randint(1, dice_sides))
if discard_lowest and len(roll_results) > 0:
discarded.append(min(roll_results))
roll_results.remove(min(roll_results))
if discarded:
net_dice_count = dice_count - 1
mnemonic = str(dice_count) + "(-1)d" + str(dice_sides)
else:
mnemonic = str(dice_count) + 'd' + str(dice_sides)
net_dice_count = dice_count
result = {
'dice-set': {
'mnemonic': mnemonic,
'min-roll': net_dice_count,
'max-roll': dice_sides * net_dice_count
},
'rolls': roll_results,
'result': sum(roll_results)
}
if discarded:
result['discarded'] = discarded
return result

View File

@ -0,0 +1,9 @@
from app.functions.roll_dices import roll_dices
from app.tables.encounters import EncounterTable
def roll_encounter(terrain):
roll = roll_dices(1, 20, False).get('result')
et = EncounterTable()
creature = et.get_encounter(roll, terrain)
return {"encounter": creature}

9
app/functions/roll_hp.py Normal file
View File

@ -0,0 +1,9 @@
from app.functions.roll_dices import roll_dices
def roll_hp(chartype, conscore):
if chartype == 'human':
geometry = 8
else:
geometry = 6
return roll_dices(conscore, geometry, False).get('result')

View File

@ -0,0 +1,35 @@
from app.functions.roll_dices import roll_dices
from app.tables.mentattack import MentalAttackMatrix
def roll_mental_attack(ams, dms, modifier):
result = {}
mam = MentalAttackMatrix()
needed = mam.get_attack_score(ams, dms)
result["needed"] = needed
outcome = None
if needed < 2:
outcome = "Automatic Success!"
elif needed > 20:
outcome = "Absolutely No Chance!"
else:
raw_roll = roll_dices(1, 20, False).get('result')
if modifier != 0:
result["original-roll"] = raw_roll
result["modifier"] = modifier
rolled = raw_roll + modifier # negative modifiers will subtract themselves naturally
result["adjusted-roll"] = rolled
else:
rolled = raw_roll
result["original-roll"] = rolled
if (rolled >= 20) and (needed <= 16):
outcome = "Devastating Success!"
elif needed <= rolled:
outcome = "Attack Successful!"
elif needed > rolled:
outcome = "Attack Failed!"
result["outcome"] = outcome
return result

View File

@ -0,0 +1,27 @@
import random
def roll_mutant_animal():
creature = dict()
animal_stock = ['badger', 'racoon', 'hound', 'wolf', 'big-cat', 'fox',
'spider', 'lizard', 'ant', 'hornet', 'hawk', 'ostrich', 'emu', 'crocodile',
'snake', 'rabbit', 'rat', 'bear', 'elephant', 'platypus', 'bull', 'horse', 'goat', 'bat',
'silverfish', 'cockroach', 'turtle', 'gibbon', 'penguin', 'orangutan', 'chimpanzee',
'housefly', 'lobster', 'crab', 'prawn', 'pig', 'chicken', 'duck', 'parrot', 'mouse',
'heron', 'weasel', 'squirrel', 'pigeon', 'crow', 'house-cat', 'shark', 'dolphin', 'narwhal',
'buffalo']
posture = ['upright', 'prone', 'mixed']
creature['stock'] = random.choice(animal_stock)
creature['posture'] = random.choice(posture)
if creature['posture'] == 'upright' or creature['posture'] == 'mixed':
creature['arms'] = random.choice(list(range(2, 4, 2))) # if you're upright 4 is the limit
creature['legs'] = random.choice(list(range(2, 6, 2))) # same with legs
if creature['posture'] == 'prone':
creature['legs'] = random.choice(list(range(4, 8, 2))) # if you're prone, you only get legs
return creature

View File

@ -0,0 +1,24 @@
from app.functions.get_mutations import get_mutations
from app.functions.get_score_list import get_score_list
from app.functions.roll_dices import roll_dices
def roll_mutations(conscore, intscore):
"""
:param conscore: modifier for physical mutation determination
:param intscore: modifier for mental mutation determination
:return: table of mutations (in json form)
"""
mutations_table = {}
mental_mutations_cnt = roll_dices(1, 4, False).get('result')
physical_mutations_cnt = roll_dices(1, 4, False).get('result')
mutations_table['count'] = {'mental': mental_mutations_cnt, 'physical': physical_mutations_cnt}
mental_mutations_scores = get_score_list(mental_mutations_cnt, intscore)
mutations_table['mental'] = get_mutations(mental_mutations_scores)
physical_mutations_scores = get_score_list(physical_mutations_cnt, conscore)
mutations_table['physical'] = get_mutations(physical_mutations_scores)
return mutations_table

View File

@ -0,0 +1,4 @@
def split_number(n):
first_split = n // 2 # this will split the number in two equal parts, if it is even
second_split = n % 2 + first_split # this will add one to one part if the number is odd
return first_split, second_split

0
app/models/__init__.py Normal file
View File

View File

@ -67,9 +67,26 @@ hp_model = {
}
ma_model = {
'ams': fields.Integer(required=True, description='Attacker Mental Strength'),
'dms': fields.Integer(required=True, description='Defender Mental Strength'),
'modifier': fields.Integer(required=True, description='Modifier For Mental Attack Roll'),
'ams': fields.Integer(
required=True,
min=3,
max=18,
default=10,
description='Attacker Mental Strength'
),
'dms': fields.Integer(
required=True,
min=3,
max=18,
default=10,
description='Defender Mental Strength'
),
'modifier': fields.Integer(
required=False,
min=-100,
max=100,
default=0,
description='Modifier For Mental Attack Roll'),
}
character_model = {

0
app/schemas/__init__.py Normal file
View File

0
app/tables/__init__.py Normal file
View File