|
|
|
 |
Reply From: |
timothybrentwood |
If you want to return multiple values you can either create an Object
to handle those multiple values (not preferred), return an Array
(less preferred) or return a Dictionary
. (Vectors
work as well if you’re dealing with numbers.)
I would suggest that you let the attacker handle the logic of determining the damage and at the end emitting a signal with the amount of damage and the unit that is supposed to be damaged.
Then you could print something like “Attacker uses Move, it was a critical strike!” in the attacker’s logic and “Target takes x damage” when the target takes the damage. I think separating the logic in this manner will allow you to avoid the need to return multiple variables in the first place.
As it stands your take_damage()
function is quite overloaded: it determines if it was a critical, uses the attacker’s stats to determine the amount of damage in conjunction with the target’s defense (very brittle), prints the amount of damage done, and finally applies the damage to the target. If I was reading code and came across a function called take_damage()
I would expect it to have 1-2 inputs (amount and maybe damage class/type) and I would apply my defense to that amount then reduce my health (which would probably be the responsibility of a separate function so it can handle UI stuff).
So your suggesting I should try to think outside the box and not make it like this, this function is in a resource script where I can make multiple enemys but I could do it that way but I would still be adding a function that adds the stats and defence stats together, a object sounds good though I don’t really know how an object is presented in code.
Thanks for the tip to make it better but for now I just want things to work my way and then I will improve it with people’s comments of course, thanks though I appreciate it!
Dragon20C | 2021-05-06 18:08
Absolutely man! Don’t get me wrong what you’re doing works and it’s a prototype. It’s good to delegate tasks to different objects from the get go though. I’m spitballing but I would do something like this:
signal damage_target(amount, target)
# how you handle this part is really up to how your game is structured
func start_battle(enemies):
for enemy in enemies:
enemy.connect("damage_target", self, "determine_damage")
func use_move_on_target(move, target):
var critical_multiplier = determine_critical()
var damage = determine_move_damage(move)
damage = int(damage * critical multiplier)
print_move(move, critical > 1)
emit_signal("damage_target", damage, target)
func determine_critical()
randomize()
critical = 1
var critical_chance = randi() % 100 + 1
#var critical_chance = 5
if critical_chance <= 6.25:
critical = 2
return critical
func determine_move_damage(move)
var type : float = Get_effectiveness(move.type,type_1) * Get_effectiveness(move.type,type_2)
var modifier : float = rand_range(0.85,1.0) * type
var a : float = (2.0 * self.level / 5.0 + 2.0)
var b : float = (a * self.attack * move.power) / 50.0
var c : float = (b + 2.0) * modifier
var damage = c
return damage
func print_move(move, is_critical):
var to_print = self.name + " uses " + move.name
if is_critical:
to_print += ", it was a critical hit!"
else:
to_print += "."
print(to_print)
# called when the damage_target signal is emitted
func determine_damage(amount, target):
if target == self:
apply_damage(amount)
func apply_damage(amount)
var reduced_by_defence = int(amount / self.defence)
self.current_health -= reduced_by_defence
var damage_message = str(self.name) + " took " + str(reduced_by_defence) + " damage."
if self.current_health <= 0:
print(damage_message + " " + str(self.name), " has died.")
else:
print(damage_message)
timothybrentwood | 2021-05-06 18:47
I see, I don’t usually use signals or I mainly use them for simple tasks but I can try this, thanks!
Dragon20C | 2021-05-06 18:51