My issue occurs when I try to use an attack. The sequence of events is this: it determines whether the attack hits or misses, what effect the attack has, and then should display a message accordingly with battle_popup. Then another message with battle_popup saying it's the enemy's turn, what attack they use, and its effect. Then it's the player's turn again.
The problem is, the timer in the battle_popup screen is ignored, as the next message using the battle_popup screen immediately replaces it. So instead of seeing the series of messages going from the result of your attack through the enemy turn, it only displays the very last popup from the series of if statements in the perform_attack method. (So you just get the effect of the enemy's attack, and no other messages.)
I cannot add renpy.pause after the messages, because it is already in use. I can't use label control, because I need to pass the enemy variable back to the check to progress to the enemy's turn. I've tried time.sleep, but that stops everything for the allotted time and displays no message. I've tried a while loop, but that just freezes my game.
How can I approach this? I'm not sure in this circumstance how to have it display the messages sequentially over a set time rather than just jumping to the end.
Is there a way that I can use global variables to be able to use label control without losing the information that I'm passing between methods?
I currently have one tester battle accessible through an existing screen:
Code: Select all
elif area == "NightForest":
vbox:
imagebutton:
idle "images/Enemies/Taffyblob.png"
hover Transform("images/Enemies/Taffyblob.png", matrixcolor=TintMatrix("#10e91a"))
xpos 1100 ypos 490
action [SetVariable("canclickscreen", False),SetVariable("activebattle", True),Hide("nightnav", _layer="nav"),Hide("green_inventory_button", _layer="invent"),Play("music", battlemusic),Show("battleon", enemy=taffyblob, x=1100, y=490)]
Code: Select all
python:
def hptotal():
return caffeine + sugar + snack + festive + delicious + spice
init:
image lightningborder:
"images/Battle/LightningH.png"
xalign 1.0
linear 1 xalign 0.0
repeat
image lightningborderrev:
"images/Battle/LightningH.png"
xalign 0.0 yalign 1.05
linear 1 xalign 1.0
repeat
screen battleon(enemy, x, y):
add "images/Battle/BattleBlue.png"
vbox:
add "images/Enemies/" + enemy.name + ".png"
xpos 800
add "lightningborder"
add "images/Battle/BattleGreenName.png"
add "images/Battle/Battle.png"
add "images/Battle/TaffyblobName.png"
add "lightningborderrev"
vbox:
imagebutton:
idle "images/bg/bg Transparency.png"
action [Hide("battleon"),Show("battler", enemy=enemy),Show("battlestats", enemy=enemy),Show("combatant", enemy=enemy, x=x, y=y)]
screen battler(enemy):
vbox:
imagebutton:
idle "images/Battle/AttackButton.png"
hover Transform("images/Battle/AttackButton.png", matrixcolor=TintMatrix("#10e91a"))
action [Play("sound", menubutt),Hide("battler"),Show("battleattack", enemy=enemy)]
focus_mask True
vbox:
imagebutton:
idle "images/Battle/AbilitiesButton.png"
hover Transform("images/Battle/AbilitiesButton.png", matrixcolor=TintMatrix("#10e91a"))
action [Play("sound", menubutt),Hide("battler"),Show("battleabilities", enemy=enemy)]
focus_mask True
vbox:
imagebutton:
idle "images/Battle/ItemsButton.png"
hover Transform("images/Battle/ItemsButton.png", matrixcolor=TintMatrix("#10e91a"))
action [Play("sound", menubutt),Hide("battler"),Show("battleitems", enemy=enemy)]
focus_mask True
vbox:
imagebutton:
idle "images/Battle/RunAwayButton.png"
hover Transform("images/Battle/RunAwayButton.png", matrixcolor=TintMatrix("#10e91a"))
action [Play("sound", menuback),SetVariable("activebattle", False),Hide("battler"),Hide("battlestats"),Hide("combatant"),Show("nightnav", _layer="nav"),Show("green_inventory_button", _layer="invent"),Play("music", forestchill)]
focus_mask True
screen combatant(enemy, x, y):
vbox:
add "images/Enemies/" + enemy.name + ".png"
xpos x ypos y
bar:
value enemy.hp # Bind the bar value to the enemy's HP attribute
range enemy.max_hp
xpos x + 60 # Adjust the x-position of the HP bar
ypos y - 50 # Adjust the y-position of the HP bar
xsize 200 # Set the width of the HP bar
ysize 50 # Set the height of the HP bar
# left_bar "#ffffffaa"
# right_bar "#FFFF0099"
screen battlestats(enemy):
vbox:
add "images/Battle/StatsBox.png"
hbox:
text "EXP" color "#ffffff"
text " "
text "CAFFEINE" color "#ffffff"
text " "
text "SUGAR" color "#ffffff"
text " "
text "SNACK" color "#ffffff"
text " "
text "FESTIVE" color "#ffffff"
text " "
text "DELICIOUS" color "#ffffff"
text " "
text "SPICE" color "#ffffff"
text " "
text "HP" color "#ffffff" size 40
xpos 535 ypos 890
hbox:
text "[exp]" color "#ffffff" size 30
xpos 555 ypos 960
hbox:
text "[caffeine]" color "#ffffff" size 40
xpos 720 ypos 950
hbox:
text "[sugar]" color "#ffffff" size 40
xpos 900 ypos 950
hbox:
text "[snack]" color "#ffffff" size 40
xpos 1050 ypos 950
hbox:
text "[festive]" color "#ffffff" size 40
xpos 1220 ypos 950
hbox:
text "[delicious]" color "#ffffff" size 40
xpos 1410 ypos 950
hbox:
text "[spice]" color "#ffffff" size 40
xpos 1590 ypos 950
hbox:
text "[hp]" color "#ffffff" size 60
xpos 1750 ypos 940
screen battleattack(enemy):
vbox:
add "images/Battle/BattleMenu.png"
vbox:
xpos 100 ypos 200
for attack in attacks:
textbutton attack['name'] action [
Hide("battleattack"),
Show("battler", enemy=enemy),
Function(attack['function'], enemy=enemy),
Jump("sortout")
]
vbox:
add "images/Battle/AttackButton.png"
vbox:
imagebutton:
idle "images/Battle/BackButton.png"
hover Transform("images/Battle/BackButton.png", matrixcolor=TintMatrix("#10e91a"))
action [Play("sound", menuback),Hide("battleattack"),Show("battler", enemy=enemy)]
focus_mask True
screen battleabilities(enemy):
vbox:
add "images/Battle/BattleMenu.png"
vbox:
add "images/Battle/AbilitiesButton.png"
ypos -220
vbox:
imagebutton:
idle "images/Battle/BackButton.png"
hover Transform("images/Battle/BackButton.png", matrixcolor=TintMatrix("#10e91a"))
action [Play("sound", menuback),Hide("battleabilities"),Show("battler", enemy=enemy)]
focus_mask True
screen battleitems(enemy):
vbox:
add "images/Battle/BattleMenu.png"
vbox:
xpos 70 ypos 200
for item in foster_inv.inv:
if item[0].battle: # Check if item is a battle item
textbutton "[item[0].name]" action (item[0].act) # Use the item's action
vbox:
add "images/Battle/ItemsButton.png"
ypos -440
vbox:
imagebutton:
idle "images/Battle/BackButton.png"
hover Transform("images/Battle/BackButton.png", matrixcolor=TintMatrix("#10e91a"))
action [Play("sound", menuback),Hide("battleitems"),Show("battler", enemy=enemy)]
focus_mask True
screen battle_popup(message):
zorder 5000
layer "invent"
frame:
style_group "invstyle"
hbox:
text message
timer 2.0 action Hide("battle_popup")
Code: Select all
init python:
def kick_attack(enemy):
hit_probability = 0.8 + luck - enemy.agility
if random.random() < hit_probability:
if enemy.attribute == "Sludge":
dodge = 0
renpy.play("audio/SFX/Sludge.mp3", "sound")
renpy.show_screen("battle_popup", "Your foot gets stuck in the sludge!")
else:
damage_dealt = 2
enemy.take_damage(damage_dealt)
renpy.show_screen("battle_popup", f"You Kick {enemy.name} for {damage_dealt} damage!.")
else:
renpy.show_screen("battle_popup", f"You try to kick {enemy.name}, but miss.")
if enemy.is_alive():
renpy.show_screen("battle_popup", "Enemy turn!")
enemy.perform_attack()
attacks = [
{
'name': "Kick",
'function': kick_attack,
'damage': 2 # Added missing ':' and corrected key name
}
]
Code: Select all
init python:
import random
# Define the Enemy class
class Enemy:
def __init__(self, name, hp, max_hp, defense, agility, attacks, attribute, flee):
self.name = name
self.hp = 0
self.max_hp = 0
self.defense = 0
self.agility = 0
self.attacks = attacks or [] # List to store enemy's attacks
self.attribute = attribute
self.flee = flee
def set_stats(self, hp, max_hp, defense, agility):
self.hp = hp
self.max_hp = max_hp
self.defense = defense
self.agility = agility
def take_damage(self, damage):
self.hp -= max(0, damage - self.defense)
if self.hp < 0:
self.hp = 0
def is_alive(self):
return self.hp > 0
def perform_attack(self):
global sugar, spice, festive, caffeine, delicious, snack
# Filter attacks based on conditions/rules
available_attacks = [attack for attack in self.attacks if self.can_use_attack(attack)]
# Select a random attack from the list of available attacks
selected_attack = random.choice(available_attacks)
# Perform the selected attack
renpy.show_screen("battle_popup", f"{self.name} performs {selected_attack['name']}!")
if 'sugar' in selected_attack:
sugar -= selected_attack['sugar']
renpy.show_screen("battle_popup", f"-{selected_attack['sugar']} sugar!")
if 'spice' in selected_attack:
spice -= selected_attack['spice']
renpy.show_screen("battle_popup", f"-{selected_attack['spice']} spice!")
if 'festive' in selected_attack:
festive -= selected_attack['festive']
renpy.show_screen("battle_popup", f"-{selected_attack['festive']} festive!")
if 'caffeine' in selected_attack:
caffeine -= selected_attack['caffeine']
renpy.show_screen("battle_popup", f"-{selected_attack['caffeine']} caffeine!")
if 'delicious' in selected_attack:
delicious -= selected_attack['delicious']
renpy.show_screen("battle_popup", f"-{selected_attack['delicious']} delicious!")
if 'snack' in selected_attack:
snack -= selected_attack['snack']
renpy.show_screen("battle_popup", f"-{selected_attack['snack']} snack!")
if 'heal' in selected_attack:
self.hp += selected_attack['heal']
renpy.show_screen("battle_popup", f"Heals for {selected_attack['heal']}!")
if 'defense' in selected_attack:
self.defense += selected_attack['defense']
renpy.show_screen("battle_popup", f"Defense boosted by {selected_attack['defense']}!")
# Apply animation if available
if 'animation' in selected_attack:
self.play_animation(selected_attack['animation'])
# Apply sound effect if available
if 'sound_effect' in selected_attack:
self.play_sound_effect(selected_attack['sound_effect'])
renpy.jump("sortout")
def can_use_attack(self, attack):
if 'rule' in attack:
return attack['rule'](self)
else:
return True # Default to allowing the attack if no rule specified
def play_animation(self, animation_name):
# Simulate playing animation (replace with actual implementation)
print(f"Playing animation: {animation_name}")
def play_sound_effect(self, sound_effect_name):
# Simulate playing sound effect (replace with actual implementation)
print(f"Playing sound effect: {sound_effect_name}")
def pull_rule(enemy):
return enemy.hp <= 5
# Define enemy data with attacks including rules
taffyblob_data = {
'name': "Taffyblob",
'hp': 10,
'max_hp': 10,
'defense': 0,
'agility': 0,
'attacks': [
{'name': "Stretch", 'sugar': 1},
{'name': "Pull", 'heal': 3, 'rule': pull_rule},
{'name': "Harden", 'defense': 2}
],
'attribute': "Sludge",
'flee': "sugar <= 0"
}
# Create an instance of an enemy using the defined data
taffyblob = Enemy(**taffyblob_data)
# Set specific stats for the Taffyblob enemy
taffyblob.set_stats(hp=10, max_hp=10, defense=0, agility=0)
Code: Select all
label sortout:
if activebattle == True:
$ hp = caffeine + sugar + snack + delicious + festive + spice
$ renpy.restart_interaction()
$ renpy.pause(hard=True)