Equipment Slots - avoiding double-up

A-Moonless-Night

WINTER IS COMING
Veteran
Joined
Mar 17, 2012
Messages
681
Reaction score
446
First Language
English
Primarily Uses
RMVXA
Tena koutou kind folks,

I'm trying to make it so that if you have a certain kind of item equipped in one of your accessory slots, you cannot equip another in the other. I'm using Yanfly's Equip Engine to give multiple slots. I like the idea of the items still being in the list, just disabled, which is why I decided to edit the 'enable?' method. I've aliased it because Yanfly edits it in his Equip Engine.

So, I thought I'd use a notetag, <equiptype: a>, where a is the name. For example, I have multiple coloured shawls, so their notetag would be <equiptype: shawl>, and if a Red Shawl was equipped in accessory slot 1, you couldn't have a Green Shawl equipped in accessory slot 2.

Here's what I have so far:
Code:
class Window_EquipItem < Window_ItemList
  #--------------------------------------------------------------------------
  # * Display in Enabled State?
  #--------------------------------------------------------------------------
   alias amn_windowequipitem_enable?   enable?
  def enable?(item)
    return true if !doubleup?(item)
  end
 
  def doubleup?(item)
    return false if item == nil
    if item.note =~ /<equiptype:\s+(\w+)>/i
      inote = $1
      if @actor.equips[4].note =~ /<equiptype:\s+(\w+)>/i
        et = $1
        if et == inote
          return true
        else
          return false
        end
      else
        return false
      end
    else
      return false
    end
  end
 
end
It's not throwing an error or anything, it's just not working. I also feel a bit weird about all the nested if statements.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,100
Reaction score
13,705
First Language
English
Primarily Uses
RMMV
Can you define "not working"? Is it letting you put the same equiptype into both accessory slots? Is it affecting what you can/can't put into other slots?

Can you provide a link to Yanfly's script that you're using?

Without knowing what the other script does, I can see that you've aliased the enable? method but you're not calling the aliased method at all. That means if doubleup? is false, enable? will return true, but it doesn't return anything if doubleup? is true. That means, if it's not a doubleup, it will let you equip anything! You should probably change that to
Code:
return false if doubleup?(item)
return amn_windowequipitem_enable?(item)
so if it's not a doubleup, it goes back to the previous version of the method to check.

Now, in the doubleup? method, I see some issues ... you're assuming they're looking for equipment for slot 5, and you're comparing it with what's in slot 4. But what if they're trying to equip slot 2? It's also doing the comparison, and if the currently-equipped armor happens to have the same equiptype as the item they're trying to equip, it's going to be a doubleup, even though it's a different kind of slot (not accessory). And what happens if they're actually trying to put something into slot 4 and not slot 5? It's going to compare with what's already in slot 4, and won't let them replace the red shawl with the green shawl, which they should be able to do.

My suggestion would be to only call the doubleup? check if the current slot is 4 or 5. That means all your other slots will be left alone. Then in the doubleup? logic, rather than hardcoding slot 4, you want to say "if I'm equipping slot 4, then I want to look at what's in slot 5; but if I'm equipping slot 5, then I want to look at what's in slot 4". An easy way to determine what slot you want to check is to take the current slot that's being equipped away from 9. So if you're equipping slot 5, it will check 9-5 = slot 4; and if you're equipping slot 4, it will check 9-4 = slot 5.

What if they don't have a currently-equipped item in that slot? I suspect it might throw an error when you try to compare.

I know I'll have the syntax wrong here, so I hope you will be able to see where the mistakes are and correct them. References to <current slot> below are whatever the code uses to determine what is being equipped - I suspect there's some kind of index or something. You'll need to change all of those to the correct variable. But here's a suggestion:

Code:
alias amn_windowequipitem_enable?   enable?
def enable?(item)
  return false if (<current slot> == 4 || <current slot> == 5) && doubleup?(item)
  return amn_windowequipitem_enable?
end

def doubleup?(item)
  return false if item.nil?
  other_slot = 9 - <current slot>
  return false if @actor.equips[other_slot].nil?
  if item.note =~ /<equiptype:\s+(\w+)>/i
    note1 = $1
  end
  if @actor.equips[4].note =~ /<equiptype:\s+(\w+)>/i
    note2 = $1
  end
  return note1 && note2 && note1 == note2
end
So if you're equipping slot 4 or 5 and there's a doubleup, the current item isn't enabled. If you're equipping another slot, or there is no doubleup, it's going back to check the logic in other scripts to determine whether it should be enabled or not.

And to check for a doubleup, it's doing your original nil test, and also no doubleup if there's nothing in the other accessory slot. Then it grabs the two notes and checks if they both have a value and the values are the same, then it's a doubleup, otherwise it isn't.

Hope this is helpful (I haven't tested it so there may still be some logic errors).

In these situations I find it really helpful to have a console window open and to issue a lot of p statements just to show what's happening - simply some text to show what lines of code are being executed, or some variables or expressions to show how things are being evaluated. When a script isn't doing what you think it should be doing, the first thing to determine is what it actually IS doing.
 

A-Moonless-Night

WINTER IS COMING
Veteran
Joined
Mar 17, 2012
Messages
681
Reaction score
446
First Language
English
Primarily Uses
RMVXA
Thanks Shaz. Link to Yanfly's script is here: https://yanflychannel.wordpress.com/rmvxa/gameplay-scripts/ace-equip-engine/

I have the slots set up like so:
Code:
DEFAULT_BASE_SLOTS = [ 0, 1, 1, 2, 3, 4, 4]
It seems to just clone them rather than making separate slots with new numbers (from what I can see).

Forgot to mention that I'm using the console. It's getting the note from the item, but not from the item in the equip slot, so not sure if there's another call I'm supposed to be using for that ...
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,100
Reaction score
13,705
First Language
English
Primarily Uses
RMMV
I'm not really sure how to read that. I think it might be slots 5 & 6 that you're interested in. It looks like you have one weapon slot, 2 shield slots, an armor slot and a headgear slot, and 2 accessory slots.
 

A-Moonless-Night

WINTER IS COMING
Veteran
Joined
Mar 17, 2012
Messages
681
Reaction score
446
First Language
English
Primarily Uses
RMVXA
Ahh, yes, it is slots 5 and 6, thank you! I had tried that before, but it threw me an error, but I think that was because something else in the code wasn't right.

Now I just need to find the right method for calling the currently selected slot ... any suggestions? The closest I've come to is @actor.equip_slots[@slot_id], but that's just the slot ID (so it returns 4).

EDIT:
Okay, I was overthinking things and it was just @slot_id.

Now it works, but only if I've already got both items in both slots. Here's my code:
Code:
class Window_EquipItem < Window_ItemList
  #--------------------------------------------------------------------------
  # * Display in Enabled State?
  #--------------------------------------------------------------------------
  alias amn_windowequipitem_enable?   enable?
  def enable?(item)
    @current_slot = @slot_id
    @other_slot = 9 - @current_slot
    return false if (@current_slot == 5 || @current_slot == 6) && doubleup?(item)
    return amn_windowequipitem_enable?(item)
  end
 
  def doubleup?(item)
#~     return false if item == nil
    return false if @actor.equips[@other_slot].nil?
    if item.note =~ /<equiptype:\s+(\w+)>/i
      note1 = $1
    end
    if @actor.equips[@current_slot].note =~ /<equiptype:\s+(\w+)>/i #|| @actor.equips[@other_slot].note =~ /<equiptype:\s+(\w+)>/i
      note2 = $1
      msgbox_p("equip note" + $1.to_s)
    end
    return true if note1 && note2 && note1 == note2
  end
 
end
It might be one of those things where I sleep on it and wake up and it's glaringly obvious.
 
Last edited:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,100
Reaction score
13,705
First Language
English
Primarily Uses
RMMV
oh - maybe because note1 and/or note2 are not defined?

try putting this just after the return false if ... lines
Code:
note1 = nil
note2 = nil
You can also just do
Code:
p("equip note" + $1.to_s)
instead of putting it in a message box, and it will come out on the console instead of interrupting the game. If you didn't want it to interrupt the game.
 

A-Moonless-Night

WINTER IS COMING
Veteran
Joined
Mar 17, 2012
Messages
681
Reaction score
446
First Language
English
Primarily Uses
RMVXA
Yeah, I was using the console but it wasn't printing anything, so I switched to msgbox_p, thinking that perhaps the console wouldn't work if I was in a menu, but turns out it just wasn't reaching the messages.

Cool, was just about ready to pull my hair out because I was SO SURE everything should work, and that's when I realised that I cannot do maths, haha. 5+6 != 9.

It's working now, thanks so much for all your help! Here's what I've got:

Code:
class RPG::BaseItem
 
  #--------------------------------------------------------------------------
  # * Cache - Load Variables                                   # NEW METHOD #
  #--------------------------------------------------------------------------
  def amn_loadnotetag_equiptype
    self.note.split(/[\r\n]+/).each { |line|
    case line
    when /<equiptype:\s+(\w+)>/i
      @equiptype = $1
    else
      @equiptype = nil
    end
    }
  end
 
  #--------------------------------------------------------------------------
  # * Equip Type                                               # NEW METHOD #
  #--------------------------------------------------------------------------
  def equiptype
    amn_loadnotetag_equiptype if @equiptype.nil?
    return @equiptype
  end

end

#==============================================================================
# ** Window_EquipItem
#------------------------------------------------------------------------------
#  This window displays choices when opting to change equipment on the
# equipment screen.
#==============================================================================

class Window_EquipItem < Window_ItemList
  #--------------------------------------------------------------------------
  # * Display in Enabled State?
  #--------------------------------------------------------------------------
  alias amn_windowequipitem_enable?   enable?
  def enable?(item)
    @current_slot = @slot_id
    @other_slot = 11 - @current_slot
    return false if (@current_slot == 5 || @current_slot == 6) && doubleup?(item)
    return amn_windowequipitem_enable?(item)
  end
 
  def doubleup?(item)
    p(@current_slot)
    p(@other_slot)
    return false if item == nil
    return false if item.equiptype == nil
    return false if @actor.equips[@other_slot].nil?
    return false if @actor.equips[@other_slot].equiptype == nil
    return true if item.equiptype == @actor.equips[@other_slot].equiptype
  end
  
end
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,100
Reaction score
13,705
First Language
English
Primarily Uses
RMMV
nice! You just need to do a return false at the end of doubleup? just in case it falls through all other tests.

or change that last line from this
Code:
return true if item.equiptype == @actor.equips[@other_slot].equiptype
to this
Code:
return item.equiptype == @actor.equips[@other_slot].equiptype
 

Sixth

Veteran
Veteran
Joined
Jul 4, 2014
Messages
2,162
Reaction score
822
First Language
Hungarian
Primarily Uses
RMVXA
nice! You just need to do a return false at the end of doubleup? just in case it falls through all other tests.
Not necessary, since he didn't check for a false nor true value specifically, it just checks if that method returns a value or not.
In this case, the method will return nil if it passes all other checks, which is not a "value" for Ruby (well, it is, just in a different sense, I guess), so that check will not be true at the end anyway.

Regardless, I usually force return a value anyway for extra clarification in my debug prints, and I generally find it a good habit if someone returns a value even in these cases, so yeah, I would do the second thing you suggested too.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

"You can thank my later", "But you haven't done anything", "Well, that's why ..."
Are we allowed to post about non-RPG Maker games?
I should realize that error was produced by a outdated version of MZ so that's why it pop up like that
Ami
i can't wait to drink some ice after struggling with my illness in 9 days. 9 days is really bad for me,i can't focus with my shop and even can't do something with my project
How many hours have you got in mz so far?

Forum statistics

Threads
105,884
Messages
1,017,243
Members
137,609
Latest member
shododdydoddy
Top