From 0a546a0f788dcdd31bc366866de85d0af8526858 Mon Sep 17 00:00:00 2001 From: Greg Gauthier Date: Sun, 23 Jun 2024 12:13:42 +0100 Subject: [PATCH] add mental attack rolls --- app.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++- mentattack.py | 30 +++++++++++++++++++++ models.py | 6 +++++ 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 mentattack.py diff --git a/app.py b/app.py index 9b4acd6..682d76f 100644 --- a/app.py +++ b/app.py @@ -2,9 +2,11 @@ from flask import Flask from flask_cors import CORS from flask_restx import Api, Resource from marshmallow import Schema, fields, validate -from models import dice_model, ability_model, hp_model, character_model, encounter_model + +from models import dice_model, ability_model, hp_model, character_model, encounter_model, ma_model from encounters import EncounterTable +from mentattack import MentalAttackMatrix from mutations import Mutations import random @@ -18,12 +20,14 @@ api = Api(app, version='1.0', title='Gamma World Dice', description='Rolled Dice 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') character = api.namespace('character', description='Character operations') encounter = api.namespace('encounter', description='Encounter operations') dice_model = dice.model('Dice', dice_model) ability_model = ability.model('Ability', ability_model) hp_model = hp.model('HP', hp_model) +ma_model = ma.model('MA', ma_model) character_model = character.model('Character', character_model) encounter_model = encounter.model('Encounter', encounter_model) @@ -64,6 +68,28 @@ class EncounterSchema(Schema): encounter_schema = EncounterSchema() +class MentalAttackSchema(Schema): + ams = fields.Integer( + required=True, + validate=validate.Range(min=3, max=18), + description='The Attackers Mental Strength' + ) + dms = fields.Integer( + required=True, + validate=validate.Range(min=3, max=18), + description='The Defenders Mental Strength' + ) + modifier = fields.Integer( + required=False, + default=0, + validate=validate.Range(min=-100, max=100), + description='Roll modifier for mental attack' + ) + + +ma_schema = MentalAttackSchema() + + @api.route('/roll/dice', methods=['POST']) class RollDice(Resource): @dice.expect(dice_model) @@ -128,6 +154,51 @@ class RollEncounter(Resource): 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/tohit', methods=['GET']) class RollToHit(Resource): def get(self): diff --git a/mentattack.py b/mentattack.py new file mode 100644 index 0000000..6e126d0 --- /dev/null +++ b/mentattack.py @@ -0,0 +1,30 @@ +import pandas as pd +import numpy as np + + +class MentalAttackMatrix: + + def __init__(self): + ams = np.linspace(3, 18, 16).astype(int) + dms = np.linspace(3, 18, 16).astype(int) + + self.df = pd.DataFrame(index=dms, columns=ams) + + initval = 10 + for col in ams: + for row in dms: + if col == row: + self.df.loc[col, row] = initval + elif col < row: + self.df.loc[col, row] = initval - (row - col) + elif col > row: + self.df.loc[col, row] = initval + (col - row) + + def get_attack_score(self, ams, dms): + return int(self.df.loc[dms, ams]) + + def get_matrix(self): + return self.df + + def dump_matrix(self): + print(self.df) diff --git a/models.py b/models.py index 8977963..66f45f7 100644 --- a/models.py +++ b/models.py @@ -23,6 +23,12 @@ hp_model = { 'conscore': fields.Integer(required=True, description='Conscore') } +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 Strength'), +} + character_model = { 'chartype': chartype_field, 'emphasis': fields.String(