Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

issue with skill_can_use?[resolved]

ok so im working on this AI system, which is working great!!! all except it lets my healers use moves they dont know :( here is the code giving me issues:
[rgss]#@values is the power of a skill(all neg because i filtered out the healing skills beforehand)
#@skill is the skill ^^^^
#@choice starts at 0
    for i in 1...$data_skills.size
      if @values != nil #just to be safe, tho it shouldn't occur
        if @values < @choice && self.skill_can_use?(@skill.id)
          p(i.to_s+","+self.skill_can_use?(@skill.id).to_s+","+self.id.to_s)
          @choice = @values
          @skill_choice = @skill.id
        end  
      end  
    end
[/rgss]
my print give me:
1,true,1 <---right
2,true,1 <---wrong
everything is default (1 is heal, 2 is greater heal)
as you can see below enemy 1 does not know greater heal
14dojsg.jpg

any idea why @skill_choice keeps ending up as 2 when self.skill_can_use? should prevent it
 
I have to wonder what your @skills variables is - you wrote that it's a skill, but a skill doesn't have an index you could address. I think you error is somewhat connected to this mysterious piece of code here:
Code:
@skill[i].id
From my logic, I'd use this instead:
Code:
self.skill_can_use?($data_skills[i])
Code:
@skill_choice = $data_skills[i]

I guess tell me if that does anything, or alternatively what you @skill variable is (and @value, for that matter).
 
Instead of
Ruby:
p(i.to_s+","+self.skill_can_use?(@skill[i].id).to_s+","+self.id.to_s)
you can use
Ruby:
p i, skill_can_use?(@skill[i].id), self.id.to_s
 
@blue, did you not read my comments? value is the power of the skill(neg values for healing spells)
2rgnej9.jpg

@skill contains literately RPG::Skill objects thats why i need id(which is an indexable value btw), because otherwise i get error(cannot convert RPG::Skill to integer) idk im quite sure that isnt the problem :(

@neo, i do know that, but i prefer my way, i know its more typing but i looks cleaner, just a personal preference, thanks for caring tho :D
 
@skill contains literately RPG::Skill objects thats why i need id(which is an indexable value btw), because otherwise i get error(cannot convert RPG::Skill to integer) idk im quite sure that isnt the problem :(
Try printing @skill.
How do you create @skill?

@neo, i do know that, but i prefer my way, i know its more typing but i looks cleaner, just a personal preference, thanks for caring tho :D
You care about clean code of a test print? oô
Anyway, then use inspect() instead of to_s() at least. I don't care if you want to use a weird style but inspect() is much better for this purpose.
 
here is the whole method im sure that would be more helpful, the method isnt completely done there is still some other logic i wanna add. but i dont wanna add more code till i get whats there to return the right vaule.
[rgss]def best_choice
    @choice = 0
    @skill_choice = 0
    @skill = {}
    @values = {}
    # check for any skills that heal(not revive)
    for i in 1...$data_skills.size
      if $data_skills.power < 0 && $data_skills.scope != 5
        if ally_needs_to_heal == false
          # include skills that heal all allys only if allys need healing
          if $data_skills.scope != 4
            @skill = $data_skills
            @values = $data_skills.power
          end
        else  
          @skill = $data_skills
          @values = $data_skills.power
        end
      end
    end
    #find what skill will heal the most, and if enemy can use it
    for i in 1...$data_skills.size
      if @values != nil
        if @values < @choice && self.skill_can_use?(@skill.id)
          @choice = @values
          @skill_choice = @skill.id
        end  
      end  
    end
    @selected_skill = @skill_choice
    if @selected_skill != -1
      return @selected_skill
    else
      return 1
    end
  end
[/rgss]
 
While I don't see an error I didn't see before on the short run, what you definately should do is store IDs in @skills instead of RPG::Skill instances. It'll be much easier for you to work with $data_skills[@skill] than what you have right now; and on top of that, should allow you to locate related errors easier (as I'm still not convinced that this strange @skill.id setup has nothing to do with it XD ). And yeah, it'll keep your variable multiple times smaller ^^ nevermind you don't have to use a hash, but an array for it, which is much easier and nicer coding-wise.
 
say what you wand blue i have put in numbers instead of skill, that is not what is causing the problem, idk ive spent like 4 hours trying to solve this method :( i hope some one can see the error :( btw im gonna use @skill for lots of stuff so i need skill objects because to to @skill.scope or @skill.power, eta. but what i dont need is the value hash at all because i could just use @skill.power, so i dont need to store the values. gonna work on that
 
btw im gonna use @skill for lots of stuff so i need skill objects because to to @skill.scope or @skill.power, eta. but what i dont need is the value hash at all because i could just use @skill.power, so i dont need to store the values. gonna work on that

When you are writing a print message for debug, you don't care about its length as long as you like it's look, but when it's about code which will stay in the finished script you are too lazy to write much :eek:hdear:

And here's the solution for your problem:
Ruby:
class Game_Enemy

  def skill_can_use?(skill_id)

    return false if !super(skill_id)

    return self.actions.any? do |action|

      action.kind == 1 and action.skill_id == skill_id and can_use_action?(action)

    end

  end

  

  def can_use_action?(action)

    n = $game_temp.battle_turn

    a = action.condition_turn_a

    b = action.condition_turn_b

    return false if (b == 0 and n != a) or (b > 0 and (n < 1 or n < a or n % b != a % b))

    return false if self.hp * 100.0 / self.maxhp > action.condition_hp

    return false if $game_party.max_level < action.condition_level

    switch_id = action.condition_switch_id

    return false if switch_id > 0 and !$game_switches[switch_id]

    return true

  end

end
 
Neo-Bahamut":48dzls34 said:
btw im gonna use @skill for lots of stuff so i need skill objects because to to @skill.scope or @skill.power, eta. but what i dont need is the value hash at all because i could just use @skill.power, so i dont need to store the values. gonna work on that

When you are writing a print message for debug, you don't care about its length as long as you like it's look, but when it's about code which will stay in the finished script you are too lazy to write much :eek:hdear:

And here's the solution for your problem:
Ruby:
class Game_Enemy

  def skill_can_use?(skill_id)

    return false if !super(skill_id)

    return self.actions.any? do |action|

      action.kind == 1 and action.skill_id == skill_id and can_use_action?(action)

    end

  end

  

  def can_use_action?(action)

    n = $game_temp.battle_turn

    a = action.condition_turn_a

    b = action.condition_turn_b

    return false if (b == 0 and n != a) or (b > 0 and (n < 1 or n < a or n % b != a % b))

    return false if self.hp * 100.0 / self.maxhp > action.condition_hp

    return false if $game_party.max_level < action.condition_level

    switch_id = action.condition_switch_id

    return false if switch_id > 0 and !$game_switches[switch_id]

    return true

  end

end

firstly thank you for your help. as for you being rude i dont at all appreciate it, i work way more then you irl most likely and im not at all lazy, i was just gonna move on to another problem so i had time to think about something else. that tends to help. but really thanks for the help, i should have read more into how the method worked. i will credit you for your help :)
 
I mean, no one cares, if your print messages look messy and unusual as no one sees them.
But if someone wants to understand you finished code and learn from it, he may ask himself "Why did he save RPG::Skill instaces in that Hash instead of the IDs?". The only reason why you do that is, that you want to write @skill instead of $data_skill. That's what I meant with lazy.
 
well you are still wrong because @skill DOESNT contain all of $data_skill only selected skills. but i do understand what you mean. i would like to say thanks again i cant imagine how long it would have took me to look at how the method works, i was stuck on a one way train of thought(i hate when i get all single minded)
 
@medinastories (and everyone else interested): 'and' is the weaker operator - '&&' is actually the one enforcing the conditional more in some way (I don't exactly know how). Therefore, && will always work, while there's occasions (that are more or less often depending on your scripting style) that'll require an '&&' operator.

@plague: As you're so resistant against help on this matter, let me show you what difference it makes...

Taking 3 skills as an example, this is what your @skill array looks like when...
69652059.jpg
18920245.jpg
Obviously, the difference will be all the more noticeable with more skills... and all you really have to change is one mass-replaceable setup of characters, so yeah... it's totally worth it!

On a side note, don't mind the project title... yay trebor, you're the last person before plague who actually got me to fire up RPG Maker :p
 
Well, as I'm apparently the only one left (together with my countryman Bahamut ;) ) who's actually trying to talk some efficiency into folks, I figure I gotta be as extreme as that sometimes >:|

;)
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top