Skip to content

Commit

Permalink
Remove GearChangeFrame code duplication (#989)
Browse files Browse the repository at this point in the history
* Some KoLCharacter tidying I did while reading through it

* Reuse code that speculates gear mods in GearChangeFrame

* Add tests for GearChangeFrame

* Remove unused import

* Update test

* Formatting

* Simplify gear change frame cell renderers

* Remove reliance on render layer to test GearChangeFrame modifier formatting

* Further simplify slot-related things

* Make method that avoids huge switch statements

Co-authored-by: Jamie Adams <82782908+jaadams5@users.noreply.github.com>
  • Loading branch information
gausie and jaadams5 committed Aug 18, 2022
1 parent 4828bdf commit f9a268c
Show file tree
Hide file tree
Showing 10 changed files with 334 additions and 420 deletions.
303 changes: 110 additions & 193 deletions src/net/sourceforge/kolmafia/KoLCharacter.java

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/net/sourceforge/kolmafia/maximizer/Maximizer.java
Expand Up @@ -169,7 +169,7 @@ public static void maximize(

boolean[] alreadyDone = new boolean[EquipmentManager.ALL_SLOTS];

for (int slot = EquipmentManager.ACCESSORY1; slot <= EquipmentManager.ACCESSORY3; ++slot) {
for (int slot : EquipmentManager.ACCESSORY_SLOTS) {
if (Maximizer.best.equipment[slot].getItemId() == ItemPool.SPECIAL_SAUCE_GLOVE
&& EquipmentManager.getEquipment(slot).getItemId() != ItemPool.SPECIAL_SAUCE_GLOVE) {
equipScope = Maximizer.emitSlot(slot, equipScope, maxPrice, priceLevel, current);
Expand Down
40 changes: 15 additions & 25 deletions src/net/sourceforge/kolmafia/request/EquipmentRequest.java
@@ -1,5 +1,6 @@
package net.sourceforge.kolmafia.request;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.kolmafia.AdventureResult;
Expand Down Expand Up @@ -442,11 +443,12 @@ private void initializeFolderData(final AdventureResult folder, final int slot)
return;
}

for (int i = EquipmentManager.FOLDER1; i <= EquipmentManager.FOLDER5; i++) {
if (i != slot && folder.equals(EquipmentManager.getEquipment(i))) {
this.error = "You can't equip two of the same folder";
return;
}
if (Arrays.stream(EquipmentManager.FOLDER_SLOTS)
.filter(s -> s != slot)
.mapToObj(EquipmentManager::getEquipment)
.anyMatch(folder::equals)) {
this.error = "You can't equip two of the same folder";
return;
}

// Find out what item is being equipped
Expand Down Expand Up @@ -749,17 +751,9 @@ private static int availableSticker() {
return EquipmentRequest.availableSlot(STICKER_SLOTS);
}

public static final int[] FOLDER_SLOTS =
new int[] {
EquipmentManager.FOLDER1,
EquipmentManager.FOLDER2,
EquipmentManager.FOLDER3,
EquipmentManager.FOLDER4,
EquipmentManager.FOLDER5,
};

public static final int availableFolder() {
return EquipmentRequest.availableSlot(FOLDER_SLOTS, KoLCharacter.inHighschool() ? 5 : 3);
public static int availableFolder() {
return EquipmentRequest.availableSlot(
EquipmentManager.FOLDER_SLOTS, KoLCharacter.inHighschool() ? 5 : 3);
}

public String getOutfitName() {
Expand Down Expand Up @@ -1171,7 +1165,7 @@ private static boolean switchItem(final AdventureResult oldItem, final Adventure

public static final void parseBedazzlements(final String responseText) {
Matcher matcher = EquipmentRequest.STICKER_PATTERN.matcher(responseText);
for (int slot = EquipmentManager.STICKER1; slot <= EquipmentManager.STICKER3; ++slot) {
for (int slot : EquipmentManager.STICKER_SLOTS) {
if (!matcher.find()) {
return; // presumably doesn't have a sticker weapon
}
Expand Down Expand Up @@ -1830,16 +1824,12 @@ private static void donOutfit(final String responseText) {
}

// Calculate accessory fill order
int[] accessories =
new int[] {
EquipmentManager.ACCESSORY1, EquipmentManager.ACCESSORY2, EquipmentManager.ACCESSORY3
};
int accessoryIndex = 0;

// Consume unfilled slots from 1 to 3
for (int slot = EquipmentManager.ACCESSORY1; slot <= EquipmentManager.ACCESSORY3; slot++) {
for (int slot : EquipmentManager.ACCESSORY_SLOTS) {
if (oldEquipment[slot] == EquipmentRequest.UNEQUIP) {
accessories[accessoryIndex++] = slot;
EquipmentManager.ACCESSORY_SLOTS[accessoryIndex++] = slot;
}
}
// Consume filled slots from 3 to 1
Expand All @@ -1848,7 +1838,7 @@ private static void donOutfit(final String responseText) {
slot--) {
if (oldEquipment[slot] != EquipmentRequest.UNEQUIP
&& newEquipment[slot] == EquipmentRequest.UNEQUIP) {
accessories[accessoryIndex++] = slot;
EquipmentManager.ACCESSORY_SLOTS[accessoryIndex++] = slot;
}
}

Expand Down Expand Up @@ -1889,7 +1879,7 @@ private static void donOutfit(final String responseText) {
// KoL error: four accessories
continue;
}
slot = accessories[accessoryIndex++];
slot = EquipmentManager.ACCESSORY_SLOTS[accessoryIndex++];
break;

case EquipmentManager.WEAPON:
Expand Down
2 changes: 1 addition & 1 deletion src/net/sourceforge/kolmafia/session/ChoiceControl.java
Expand Up @@ -6259,7 +6259,7 @@ else if (text.contains("pretty good understanding")) {
// If you change the mode with the item equipped, you need to un-equip and re-equip it to
// get the modifiers
if (ChoiceManager.lastDecision >= 1 && ChoiceManager.lastDecision <= 3) {
for (int i = EquipmentManager.ACCESSORY1; i <= EquipmentManager.ACCESSORY3; ++i) {
for (int i : EquipmentManager.ACCESSORY_SLOTS) {
AdventureResult item = EquipmentManager.getEquipment(i);
if (item != null && item.getItemId() == ItemPool.BACKUP_CAMERA) {
RequestThread.postRequest(new EquipmentRequest(EquipmentRequest.UNEQUIP, i));
Expand Down
21 changes: 19 additions & 2 deletions src/net/sourceforge/kolmafia/session/EquipmentManager.java
Expand Up @@ -89,6 +89,23 @@ public class EquipmentManager {
private static final List<List<AdventureResult>> historyLists =
new ArrayList<>(EquipmentManager.ALL_SLOTS);

public static final int[] FOLDER_SLOTS =
new int[] {
EquipmentManager.FOLDER1,
EquipmentManager.FOLDER2,
EquipmentManager.FOLDER3,
EquipmentManager.FOLDER4,
EquipmentManager.FOLDER5,
};

public static int[] ACCESSORY_SLOTS =
new int[] {
EquipmentManager.ACCESSORY1, EquipmentManager.ACCESSORY2, EquipmentManager.ACCESSORY3
};

public static int[] STICKER_SLOTS =
new int[] {EquipmentManager.STICKER1, EquipmentManager.STICKER2, EquipmentManager.STICKER3};

private static int fakeHandCount = 0;
private static int stinkyCheeseLevel = 0;

Expand Down Expand Up @@ -225,7 +242,7 @@ public static final void processResult(AdventureResult item) {
// Make sure the current sticker in each slot remains in the list, even if
// there are no more of that type in inventory.

for (int slot = EquipmentManager.STICKER1; slot <= EquipmentManager.STICKER3; ++slot) {
for (int slot : EquipmentManager.STICKER_SLOTS) {
AdventureResult current = EquipmentManager.getEquipment(slot);
AdventureResult.addResultToList(EquipmentManager.equipmentLists.get(slot), item);
if (!EquipmentManager.equipmentLists.get(slot).contains(current)) {
Expand All @@ -235,7 +252,7 @@ public static final void processResult(AdventureResult item) {
} else if (consumeType == KoLConstants.CONSUME_FOLDER) {
// Folders are similar to stickers

for (int slot = EquipmentManager.FOLDER1; slot <= EquipmentManager.FOLDER5; ++slot) {
for (int slot : EquipmentManager.FOLDER_SLOTS) {
AdventureResult current = EquipmentManager.getEquipment(slot);
AdventureResult.addResultToList(EquipmentManager.equipmentLists.get(slot), item);
if (!EquipmentManager.equipmentLists.get(slot).contains(current)) {
Expand Down
188 changes: 52 additions & 136 deletions src/net/sourceforge/kolmafia/swingui/GearChangeFrame.java
Expand Up @@ -27,6 +27,7 @@
import net.sourceforge.kolmafia.KoLCharacter;
import net.sourceforge.kolmafia.KoLConstants;
import net.sourceforge.kolmafia.KoLmafia;
import net.sourceforge.kolmafia.Modeable;
import net.sourceforge.kolmafia.Modifiers;
import net.sourceforge.kolmafia.RequestThread;
import net.sourceforge.kolmafia.SpecialOutfit;
Expand All @@ -36,7 +37,6 @@
import net.sourceforge.kolmafia.objectpool.ItemPool;
import net.sourceforge.kolmafia.persistence.EquipmentDatabase;
import net.sourceforge.kolmafia.persistence.ItemDatabase;
import net.sourceforge.kolmafia.preferences.Preferences;
import net.sourceforge.kolmafia.request.EquipmentRequest;
import net.sourceforge.kolmafia.request.FamiliarRequest;
import net.sourceforge.kolmafia.session.EquipmentManager;
Expand Down Expand Up @@ -138,139 +138,34 @@ public GearChangeFrame() {
RequestThread.executeMethodAfterInitialization(this, "validateSelections");
}

public static void showModifiers(Object value, boolean isFamiliarItem) {
if (GearChangeFrame.INSTANCE == null) {
return;
}

EquipmentTabPanel pane =
(EquipmentTabPanel) GearChangeFrame.INSTANCE.tabs.getSelectedComponent();

public static StringBuffer getModifiers(
Object value, final int slot, final boolean isCustomizablePanel, final int width) {
StringBuffer buff = new StringBuffer();
Modifiers mods;

if (value instanceof AdventureResult) {
AdventureResult item = (AdventureResult) value;
int itemId = item.getItemId();
int familiarId = KoLCharacter.getFamiliar().getId();
int consumption = ItemDatabase.getConsumptionType(itemId);

if (itemId == -1) {
// Nothing for (none)
mods = null;
}
if (isFamiliarItem
&& consumption != KoLConstants.EQUIP_FAMILIAR
&& (familiarId == FamiliarPool.HATRACK || (familiarId == FamiliarPool.SCARECROW))) {
// Mad Hat Racks can equip hats.
// Fancypants Scarecrows can equip pants.
//
// In each case, there is a special familiar
// effect; the standard item modifiers are
// meaningless.
//
// Disembodied Hands can equip one-handed weapons.
// Left Mand Man can equip off-hand items.
//
// In each case, the standard item modifiers
// are in force.
mods = null;
} else {
Modifiers newMods = new Modifiers();
newMods.add(Modifiers.getItemModifiers(itemId));

switch (itemId) {
case ItemPool.CROWN_OF_ED:
{
newMods.add(Modifiers.getModifiers("Edpiece", Preferences.getString("edPiece")));
break;
}
case ItemPool.SNOW_SUIT:
{
newMods.add(Modifiers.getModifiers("Snowsuit", Preferences.getString("snowsuit")));
break;
}
case ItemPool.KNOCK_OFF_RETRO_SUPERHERO_CAPE:
{
newMods.add(
Modifiers.getModifiers(
"RetroCape",
Preferences.getString("retroCapeSuperhero")
+ " "
+ Preferences.getString("retroCapeWashingInstructions")));
break;
}
case ItemPool.BACKUP_CAMERA:
{
newMods.add(
Modifiers.getModifiers(
"BackupCamera", Preferences.getString("backupCameraMode")));
break;
}
case ItemPool.COWBOY_BOOTS:
{
AdventureResult skin = EquipmentManager.getEquipment(EquipmentManager.BOOTSKIN);
AdventureResult spur = EquipmentManager.getEquipment(EquipmentManager.BOOTSPUR);
if (skin != null && skin != EquipmentRequest.UNEQUIP) {
newMods.add(Modifiers.getItemModifiers(skin.getItemId()));
}
if (spur != null && spur != EquipmentRequest.UNEQUIP) {
newMods.add(Modifiers.getItemModifiers(spur.getItemId()));
}
break;
}
case ItemPool.FOLDER_HOLDER:
{
for (int i = EquipmentManager.FOLDER1; i <= EquipmentManager.FOLDER5; ++i) {
AdventureResult folder = EquipmentManager.getEquipment(i);
if (folder != null && folder != EquipmentRequest.UNEQUIP) {
newMods.add(Modifiers.getItemModifiers(folder.getItemId()));
}
}
break;
}
case ItemPool.STICKER_CROSSBOW:
case ItemPool.STICKER_SWORD:
{
for (int i = EquipmentManager.STICKER1; i <= EquipmentManager.STICKER3; ++i) {
AdventureResult sticker = EquipmentManager.getEquipment(i);
if (sticker != null && sticker != EquipmentRequest.UNEQUIP) {
newMods.add(Modifiers.getItemModifiers(sticker.getItemId()));
}
}
break;
}
case ItemPool.CARD_SLEEVE:
{
AdventureResult card = EquipmentManager.getEquipment(EquipmentManager.CARDSLEEVE);
if (card != null && card != EquipmentRequest.UNEQUIP) {
newMods.add(Modifiers.getItemModifiers(card.getItemId()));
}
break;
}
case ItemPool.UNBREAKABLE_UMBRELLA:
{
newMods.add(
Modifiers.getModifiers(
"UnbreakableUmbrella", Preferences.getString("umbrellaState")));
break;
}
case ItemPool.VAMPYRIC_CLOAKE:
newMods.applyVampyricCloakeModifiers();
}
mods = newMods;
}
} else if (value instanceof SpecialOutfit) {
mods = Modifiers.getModifiers("Outfit", ((SpecialOutfit) value).getName());
} else if (value instanceof FamiliarData
&& pane == GearChangeFrame.INSTANCE.customizablePanel) {
mods = Modifiers.getModifiers("Throne", ((FamiliarData) value).getRace());
if (value instanceof AdventureResult item) {
mods = new Modifiers();
var taoFactor = KoLCharacter.hasSkill("Tao of the Terrapin") ? 2 : 1;
KoLCharacter.addItemAdjustment(
mods,
slot,
item,
EquipmentManager.allEquipment(),
KoLCharacter.getEnthroned(),
KoLCharacter.getBjorned(),
Modeable.getStateMap(),
true,
taoFactor);
} else if (value instanceof SpecialOutfit outfit) {
mods = Modifiers.getModifiers("Outfit", outfit.getName());
} else if (value instanceof FamiliarData familiar && isCustomizablePanel) {
mods = Modifiers.getModifiers("Throne", familiar.getRace());
} else {
return;
return null;
}

if (mods == null) {
pane.getModifiersLabel().setText("");
return;
return buff;
}

String name = mods.getString(Modifiers.INTRINSIC_EFFECT);
Expand All @@ -281,9 +176,8 @@ public static void showModifiers(Object value, boolean isFamiliarItem) {
mods = newMods;
}

StringBuilder buff = new StringBuilder();
buff.append("<html><table><tr><td width=");
buff.append(pane.getModifiersWidth());
buff.append(width);
buff.append(">");

for (int i = 0; i < Modifiers.DOUBLE_MODIFIERS; ++i) {
Expand Down Expand Up @@ -341,7 +235,32 @@ public static void showModifiers(Object value, boolean isFamiliarItem) {
}

buff.append("</td></tr></table></html>");
pane.getModifiersLabel().setText(buff.toString());
return buff;
}

public static void showModifiers(Object value) {
var slot =
(value instanceof AdventureResult item)
? EquipmentManager.consumeFilterToEquipmentType(ItemDatabase.getConsumptionType(item))
: -1;
showModifiers(value, slot);
}

public static void showModifiers(Object value, final int slot) {
if (GearChangeFrame.INSTANCE == null) {
return;
}

EquipmentTabPanel pane =
(EquipmentTabPanel) GearChangeFrame.INSTANCE.tabs.getSelectedComponent();

var isCustomizablePanel = pane == GearChangeFrame.INSTANCE.customizablePanel;

StringBuffer buff = getModifiers(value, slot, isCustomizablePanel, pane.getModifiersWidth());

if (buff != null) {
pane.getModifiersLabel().setText(buff.toString());
}
}

private abstract class EquipmentTabPanel extends GenericPanel {
Expand Down Expand Up @@ -537,7 +456,7 @@ private void changeItems() {

// Start with accessories

for (int i = EquipmentManager.ACCESSORY1; i <= EquipmentManager.ACCESSORY3; ++i) {
for (int i : EquipmentManager.ACCESSORY_SLOTS) {
if (pieces[i] != null) {
RequestThread.postRequest(new EquipmentRequest(pieces[i], i, true));
pieces[i] = null;
Expand Down Expand Up @@ -844,10 +763,7 @@ private class EquipmentComboBox extends JComboBox<AdventureResult> {
public EquipmentComboBox(final LockableListModel<AdventureResult> model, final int slot) {
super(model);

DefaultListCellRenderer renderer =
(slot == EquipmentManager.FAMILIAR)
? ListCellRendererFactory.getFamiliarEquipmentRenderer()
: ListCellRendererFactory.getUsableEquipmentRenderer();
DefaultListCellRenderer renderer = ListCellRendererFactory.getUsableEquipmentRenderer(slot);

this.setRenderer(renderer);
this.addPopupMenuListener(new ChangeItemListener());
Expand Down

0 comments on commit f9a268c

Please sign in to comment.