Return to repo list

heart-of-gold

Tactical RPG written in python, using pygame.
Return to HMagellan.com

commit 2bd58550b78d351ac7a988f8e711213693cace27
parent 022794c75ebcebd7f9e267d58f0c5b0feb189672
Author: Erik Letson <hmagellan@hmagellan.com>
Date:   Thu, 19 Nov 2020 13:03:10 -0600

Actual damage formula

Diffstat:
Mmain.py | 1+
Msrc/constants.py | 28++++++++++++++++++++++++++++
Msrc/piece.py | 50+++++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/main.py b/main.py @@ -25,6 +25,7 @@ from src import game # 9. Animations should not be image-file-specific. Rather, a field should be added to sheets.json entries called "anim" which will point to a # specific entry in the anims.json file. These entries can then be generalized for entire classes of spritesheets (in particular for piece sprite # sheets). This will require a rewrite of anims.json and a modification to the sheet manager. +# 10. All places where 'database' is loaded on the fly need to be replaced with a single DATABASE const in constants.py that is always available. # Initialization of pygame and submodules pygame.mixer.pre_init(44100, -16, 4, 1024) diff --git a/src/constants.py b/src/constants.py @@ -29,6 +29,34 @@ PIECE_MOVE_DELAY = PIECE_MOVE_SPEED * 4 SCROLL_SPEED = 4 UI_FONT = "ArchivoNarrow-Regular.otf" +# Item constants +WEAPON_TYPE_SOURCES = { + "Dagger" : "ATK", + "Sword" : "ATK", + "Spear" : "ATK", + "Axe" : "ATK", + "Glove" : "ATK", + "Blunt" : "ATK", + "Bow" : "ACC", + "Thrown" : "ACC", + "Staff" : "INT", + "Book" : "INT", + "Wand" : "INT" +} +WEAPON_TYPE_BONUSES = { + "Dagger" : "SPD", + "Sword" : None, + "Spear" : "DEF", + "Axe" : "ATK", + "Glove" : "SPD", + "Blunt" : None, + "Bow" : "ACC", + "Thrown" : "ATK", + "Staff" : "ATK", + "Book" : "WIS", + "Wand" : "INT" +} + # File paths DATA_PATH = os.path.join(os.getcwd(), "data") IMAGE_PATH = os.path.join(DATA_PATH, "img") diff --git a/src/piece.py b/src/piece.py @@ -1,4 +1,4 @@ -import pygame, os, json +import pygame, os, json, random from . import manager, entity from .constants import * @@ -248,6 +248,12 @@ class Piece(entity.Entity): self.being_damaged = False self.damage_timer = 0 self.damage_to_receive = 0 + self.damage_number_font = None + self.damage_number_outline_font = None + self.damage_number_surface = None + self.damage_number_outline = None + self.damage_number_rect = None + self.damage_number_outline_rect = None self.has_moved = False self.has_acted = False self.health_bar = None @@ -316,6 +322,17 @@ class Piece(entity.Entity): else: self.attack_range = 0 + def render_damage_number(self): + """ + Render the name font image for display. + """ + self.damage_number_font = pygame.font.Font(os.path.join(FONT_PATH, UI_FONT), self.rect.height // 2) + self.damage_number_outline_font = pygame.font.Font(os.path.join(FONT_PATH, UI_FONT), (self.rect.height // 2) + 6) + self.damage_number_surface = self.damage_number_font.render(str(self.damage_to_receive), False, (255, 255, 255)).convert() + self.damage_number_outline = self.damage_number_outline_font.render(str(self.damage_to_receive), False, (0, 0, 0)).convert() + self.damage_number_rect = self.damage_number_surface.get_rect() + self.damage_number_outline_rect = self.damage_number_outline.get_rect() + def set_facing(self, direction): """ Set the direction this piece should face. 'direction' should @@ -360,16 +377,28 @@ class Piece(entity.Entity): self.attack_anim_timer = 90 # Tell the other guy to be damaged - dam = self.active_stats["ATK"] * 2 - self.attack_target.active_stats["DEF"] # TODO: Obv not perm - self.attack_target.set_be_damaged_action(dam) + database = json.load(open(os.path.join(JSON_PATH, "items.json"))) + prim = self.active_stats[WEAPON_TYPE_SOURCES[database[self.equipment["weapon"]]["type"]]] + bon = WEAPON_TYPE_SOURCES[database[self.equipment["weapon"]]["type"]] + raw_dam = max(round((prim * 1.8) + random.randint(-(self.active_stats["LUK"] // 2), self.active_stats["LUK"])), 0) + if bon != None and raw_dam != 0: + raw_dam += round((self.active_stats[bon] + random.randint(0, self.active_stats["LUK"] // 2)) * 0.2) + self.attack_target.set_be_damaged_action(raw_dam) - def set_be_damaged_action(self, damage): + def set_be_damaged_action(self, raw_damage): """ Setup the action of being damaged. """ - self.damage_to_receive = damage + # TODO: This could eventually take a 'damage_aff' var which determines + # the element of the damage and could be figured into the post-def + # calculations to account for elemental strength/weakness + self.damage_to_receive = (raw_damage - round(self.active_stats["DEF"] * 1.1)) + random.randint(-(self.active_stats["LUK"] // 2), + self.active_stats["LUK"]) + if self.damage_to_receive < 0: + self.damage_to_receive = 0 self.damage_timer = 100 self.being_damaged = True + self.render_damage_number() def create_health_bar(self): """ @@ -469,6 +498,12 @@ class Piece(entity.Entity): else: self.being_damaged = False self.damage_to_receive = 0 + self.damage_number_font = None + self.damage_number_outline_font = None + self.damage_number_surface = None + self.damage_number_outline = None + self.damage_number_rect = None + self.damage_number_outline_rect = None if self.active_stats["HP"] <= 0: self.manager.kill_piece(self) self.manager.bus.perform_turn_manager_kill_piece(self) @@ -502,6 +537,11 @@ class Piece(entity.Entity): surface.blit(self.health_bar_fill, self.health_bar_fill_rect) if self.facing_arrow != None: self.facing_arrow.update(surface) + if self.damage_timer > 0 and self.damage_timer < 55: + self.damage_number_rect.center = (self.rect.center[0], self.rect.center[1] + (self.damage_timer // 10)) + self.damage_number_outline_rect.center = self.damage_number_rect.center + surface.blit(self.damage_number_outline, self.damage_number_outline_rect) + surface.blit(self.damage_number_surface, self.damage_number_rect) ########################## # Section 3 - TileCursor #