import random from flask import Flask from flask_cors import CORS from flask_restx import Api, Resource from app.functions.role_physical_attack import roll_physical_attack from .functions.build_character_sheet import build_character_sheet from .functions.roll_ability_scores import roll_ability_scores from .functions.roll_ability_check import roll_ability_check from .functions.roll_dices import roll_dices from .functions.roll_encounter import roll_encounter from .functions.roll_mental_attack import roll_mental_attack from .functions.roll_mutations import roll_mutations from .models.models import dice_model, ability_model, hp_model, character_model, encounter_model, ma_model, \ mutation_model, check_model, pa_model from .schemas.schemas import DiceSchema, CharacterSchema, EncounterSchema, MentalAttackSchema, AbilitySchema, \ HPSchema, MutationSchema, CheckSchema, PhysicalAttackSchema 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') pa = api.namespace('pa', description='Physical 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() pa_model = pa.model('PA', pa_model) pa_schema = PhysicalAttackSchema() character_model = character.model('Character', character_model) character_schema = CharacterSchema() encounter_model = encounter.model('Encounter', encounter_model) encounter_schema = EncounterSchema() @api.route('/coinflip', methods=['GET']) class RollCoinflip(Resource): @staticmethod def get(): return random.choice(['Heads', 'Tails']), 200 @api.route('/roll/chance', methods=['GET']) class RollChance(Resource): @staticmethod def get(): return roll_dices(1, 100, False), 200 @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/attack/physical', methods=['POST']) class RollPhysicalAttack(Resource): @pa.expect(pa_model) def post(self): data = api.payload errors = pa_schema.validate(data) if errors: return errors, 400 weapon_attack = data.get('weapon_attack') # to pick the attack table dac = data.get('dac') # needed for both attacks awc = data.get('awc') # only needed for weapon attacks ahd = data.get('ahd') # only needed for non-weapon attacks modifier = data.get('modifier') return roll_physical_attack(weapon_attack, dac, modifier, awc, ahd), 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/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()