This commit is the compilation of all of the changes that were done for the sake of the BattleManager class and the Move class. This PR includes changes that directly impact the classes and some miscellaneous changes. The BattleManager class was created for the purpose of managing the fight encounters between Entity objects. The Move class was created to take the structured move data from JSON and turn it into a real object.
To begin with, this PR introduces the Move class. This class takes in an Entity object and the dictionary it needs for it's attributes. It only has one notable function, the parse_damage_calculation() function. This function uses the damage formula present in the dictionary to calculate the damage this Move object can do. If there is no damage formula in the dictionary information, the damage is 0.
To begin with, this PR introduces the BattleManager class. This class has the following attributes. moveDict, hero, enemies, turnOrder and lootPool.
moveDict: A dictionary formed by loading the information from the "JSON/Moves/Complete_Move_List.json" file.
hero: a reference to the Knight object
enemies: A list of enemies for the given combat encounter
turnOrder: a list of Entities in the order in which they can act
lootPool: A dictionary containing all the eperience, money and items the player gains when they win.
The BattleManager class has the following relevant functions. do_battle(), use_move(), parse_effects(), apply_effects(), apply_effect_buff(), parse_restriction(), reset_turn_order() and clear_dead_enemies().
clear_dead_enemies(): This function iterates through the enemies and turnOrder list and adds the Entity objects that aren't dead to a new list. This effectively removes dead Entity objects from the two lists.
reset_turn_order(): This function adds all of the Entity objects in the battle to a list and sorts them based on their Agl stats. This list then becomes the new turnOrder.
parse_restriction(): This function takes in an Entity object and a dictionary containing information about the move they want to use. It then uses the restriction string (if there is any) to determine whether the Entity object meets the requirement to use the move by returning a boolean value.
parse_effects(): this function take in a Move object. It then uses the effect attribute of the object to determine the type of effect that it has. It parses the string (if it's present) and returns a list of tuples containing the effects and their targets in an easier to understand way. If there is no effect, an empty list is returned.
apply_effect_buff(): This function takes in a target Entity and a dictionary that describes a buff. To ensure that there is no permanent stat loss or gain, the target's buffs are removed first before the buffs are updated and re-applied. To do this, a False boolean value is passed to the Entity object's remove_bonuses() and apply_bonuses() function. This flag tells the functions to not remove buffs that have reached the end of their turn count in the case of remove_bonuses() and to not lower the turn count of existing buffs when apply_bonuses() is used.
apply_effects(): This function takes in an effectList, the object whose turn it is and the object this object is targetting. This function iterates through the effectList and parses the curated effects. It first determines who the target of the effect should be by using the value at index 0 of the tupple, it then looks at the class of the value in index 1 of the tupple. If the class is a string then it deals with it in a "try-except" block. If the class is a dictionary then it calls the apply_effect_buff() function for the target.
use_move(): This function takes in the turnObject, a Move object and a list of targets that the move is to be used on. It gets the effectList from the parse_effects() function and then iterates through the list of targets. If the Move object's type attribute is "Attack" then the target takes damage equal to the Move object's damage attribute. Depending on which class the object is part of, the function called for this is different. The effects of the move are then applied.
do_battle(): this function pops the object at the 0 index of the turnOrder list. If the object is of the Knight class, the player will then have to choose what to do. If not, the enemy randomly determines what move in their movelist will do. There is a failsafe for this where if the enemy fails to land on a usable move 20 times over, the enemy will just attack.
Other Changes:
The Entity classes init function now includes the Mp and Mpcap stats. As a result the Enemy and Knight classes needed to change their constructors to accomodate the change.
the Attack() function of the Entity class was removed allowing with any reference to it. Since BattleManager will handle this, this function is useless.
both the apply_bonuses() and remove_bonuses() functions for the Entity class now take in an optional flag. If this flag is False, the apply_bonuses() function will not decrease the turn count of the buffs applied and the remove_bonuses() function will not strip off any buffs that have reached the end of their turn counts.
correct_stats() function for the Entity class has been created for future use. At the moment it simply fixes any stats that have a higher or lower value than what should be possible. This will be called every turn.
The Knight class' moveList attribute starts with the "Attack" value in index 0.
Changes to the files in the JSON/Enemies directory. Because of this, the Entities_test.py file needed a small change to the damage that was dealt to the dummy object.
Creation of the JSON/Moves/Complete_Move_List.json file. This file contains the JSON information for every single move that is currently in the game and is read from by the BattleManager class.
Added pytest Entity folder command to the run-tests option in script file
added refresh-enemy-data option to script file. This option applies any of the newly made changes to the Scripts.py file's create-enemy option to every file in the JSON/Enemies directory. The bad news is that all data is reset for this
create-move option added to script file. This simply creates a new Move object JSON schema for me to add move info too.
PR checklist
[x] All Pytests pass
[x] All changes are documented somewhere in the commit
[x] Rpg2.py is tested and works even with the changes
Pygame-RPG 14 Creation of BattleManager class
This commit is the compilation of all of the changes that were done for the sake of the BattleManager class and the Move class. This PR includes changes that directly impact the classes and some miscellaneous changes. The BattleManager class was created for the purpose of managing the fight encounters between Entity objects. The Move class was created to take the structured move data from JSON and turn it into a real object.
To begin with, this PR introduces the Move class. This class takes in an Entity object and the dictionary it needs for it's attributes. It only has one notable function, the
parse_damage_calculation()
function. This function uses the damage formula present in the dictionary to calculate the damage this Move object can do. If there is no damage formula in the dictionary information, the damage is 0.To begin with, this PR introduces the BattleManager class. This class has the following attributes.
moveDict
,hero
,enemies
,turnOrder
andlootPool
.moveDict
: A dictionary formed by loading the information from the "JSON/Moves/Complete_Move_List.json" file.hero
: a reference to the Knight objectenemies
: A list of enemies for the given combat encounterturnOrder
: a list of Entities in the order in which they can actlootPool
: A dictionary containing all the eperience, money and items the player gains when they win.The BattleManager class has the following relevant functions.
do_battle()
,use_move()
,parse_effects()
,apply_effects()
,apply_effect_buff()
,parse_restriction()
,reset_turn_order()
andclear_dead_enemies()
.clear_dead_enemies()
: This function iterates through the enemies and turnOrder list and adds the Entity objects that aren't dead to a new list. This effectively removes dead Entity objects from the two lists.reset_turn_order()
: This function adds all of the Entity objects in the battle to a list and sorts them based on their Agl stats. This list then becomes the new turnOrder.parse_restriction()
: This function takes in an Entity object and a dictionary containing information about the move they want to use. It then uses the restriction string (if there is any) to determine whether the Entity object meets the requirement to use the move by returning a boolean value.parse_effects()
: this function take in a Move object. It then uses theeffect
attribute of the object to determine the type of effect that it has. It parses the string (if it's present) and returns a list of tuples containing the effects and their targets in an easier to understand way. If there is no effect, an empty list is returned.apply_effect_buff()
: This function takes in a target Entity and a dictionary that describes a buff. To ensure that there is no permanent stat loss or gain, the target's buffs are removed first before the buffs are updated and re-applied. To do this, a False boolean value is passed to the Entity object'sremove_bonuses()
andapply_bonuses()
function. This flag tells the functions to not remove buffs that have reached the end of their turn count in the case ofremove_bonuses()
and to not lower the turn count of existing buffs whenapply_bonuses()
is used.apply_effects()
: This function takes in an effectList, the object whose turn it is and the object this object is targetting. This function iterates through the effectList and parses the curated effects. It first determines who the target of the effect should be by using the value at index 0 of the tupple, it then looks at the class of the value in index 1 of the tupple. If the class is a string then it deals with it in a "try-except" block. If the class is a dictionary then it calls theapply_effect_buff()
function for the target.use_move()
: This function takes in the turnObject, a Move object and a list of targets that the move is to be used on. It gets the effectList from theparse_effects()
function and then iterates through the list of targets. If the Move object's type attribute is "Attack" then the target takes damage equal to the Move object's damage attribute. Depending on which class the object is part of, the function called for this is different. The effects of the move are then applied.do_battle()
: this function pops the object at the 0 index of the turnOrder list. If the object is of theKnight
class, the player will then have to choose what to do. If not, the enemy randomly determines what move in their movelist will do. There is a failsafe for this where if the enemy fails to land on a usable move 20 times over, the enemy will just attack.Other Changes:
The Entity classes init function now includes the Mp and Mpcap stats. As a result the
Enemy
andKnight
classes needed to change their constructors to accomodate the change.the
Attack()
function of the Entity class was removed allowing with any reference to it. Since BattleManager will handle this, this function is useless.both the
apply_bonuses()
andremove_bonuses()
functions for the Entity class now take in an optional flag. If this flag is False, theapply_bonuses()
function will not decrease the turn count of the buffs applied and theremove_bonuses()
function will not strip off any buffs that have reached the end of their turn counts.correct_stats()
function for the Entity class has been created for future use. At the moment it simply fixes any stats that have a higher or lower value than what should be possible. This will be called every turn.The
Knight
class' moveList attribute starts with the "Attack" value in index 0.Changes to the files in the JSON/Enemies directory. Because of this, the Entities_test.py file needed a small change to the damage that was dealt to the dummy object.
Creation of the JSON/Moves/Complete_Move_List.json file. This file contains the JSON information for every single move that is currently in the game and is read from by the BattleManager class.
Added pytest Entity folder command to the run-tests option in script file
added refresh-enemy-data option to script file. This option applies any of the newly made changes to the Scripts.py file's create-enemy option to every file in the JSON/Enemies directory. The bad news is that all data is reset for this
create-move option added to script file. This simply creates a new Move object JSON schema for me to add move info too.
PR checklist