This commit is contained in:
Bishop 2026-07-26 08:56:19 -05:00
parent 4d675294df
commit 9ab4edc276
10 changed files with 74 additions and 16 deletions

View file

@ -44,7 +44,7 @@ public final class AutocastSelectPlugin extends ComponentPlugin {
player.removeAttribute("autocast_select");
final WeaponInterface w = player.getExtension(WeaponInterface.class);
if (w != null) {
w.selectAutoSpell(button, true);
w.selectAutoSpell(button, true, false);
player.getInterfaceManager().openTab(w);
}
return true;

View file

@ -82,7 +82,7 @@ public class CombatTabInterface extends ComponentPlugin {
if (button == 4 || button == 5) {
inter.openAutocastSelect();
} else if (p.getProperties().getAutocastSpell() != null) {
inter.selectAutoSpell(-1, false);
inter.selectAutoSpell(-1, false, true);
}
return true;
}

View file

@ -54,7 +54,7 @@ class MagicAltarListener : InteractionListener {
}
val weaponInterface = player.getExtension<WeaponInterface>(WeaponInterface::class.java)
if (weaponInterface != null && player.properties.autocastSpell != null) {
weaponInterface.selectAutoSpell(-1, true)
weaponInterface.selectAutoSpell(-1, true, true)
}
if (SpellBook.forInterface(player.spellBookManager.spellBook) == if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR) {
player.dispatch(SpellbookChangeEvent(

View file

@ -215,7 +215,7 @@ enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)?
}
val weaponInterface = player.getExtension<WeaponInterface>(WeaponInterface::class.java)
if (weaponInterface != null && player.properties.autocastSpell != null) {
weaponInterface.selectAutoSpell(-1, true)
weaponInterface.selectAutoSpell(-1, true, true)
}
player.dispatch(SpellbookChangeEvent(
SpellBookManager.SpellBook.forInterface(player.spellBookManager.spellBook),

View file

@ -82,7 +82,7 @@ class EquipHandler : InteractionListener {
if (itemEquipmentSlot == EquipmentContainer.SLOT_WEAPON) {
player.properties.autocastSpell = null
val wif = player.getExtension<WeaponInterface>(WeaponInterface::class.java)
wif.selectAutoSpell(-1, true)
wif.selectAutoSpell(-1, true, true)
wif.openAutocastSelect()
}
}

View file

@ -52,7 +52,7 @@ open class MagicSwingHandler (vararg flags: SwingHandlerFlag)
entity.properties.spell = null
val inter = entity.getExtension<WeaponInterface>(WeaponInterface::class.java)
if (inter != null) {
inter.selectAutoSpell(-1, true)
inter.selectAutoSpell(-1, true, true)
entity.properties.combatPulse.updateStyle()
}
return -1

View file

@ -125,6 +125,16 @@ public final class WeaponInterface extends Component {
*/
public static final int STYLE_CAST = 8;
/**
* Attribute storing the player's autocast spell for reload upon relog.
*/
public static final String attributeAutocastButtonId = "/save:autocast:buttonid";
/**
* Attribute storing the player's autocast combat style for reload upon relog.
*/
public static final String attributeAutocastStyle = "/save:autocast:style";
/**
* The player.
*/
@ -259,7 +269,7 @@ public final class WeaponInterface extends Component {
player.getProperties().setAttackAnimation(attackAnimations[player.getSettings().getAttackStyleIndex()]);
}
if (current != WeaponInterfaces.STAFF) {
selectAutoSpell(-1, false);
selectAutoSpell(-1, false, false);
PacketRepository.send(InterfaceConfig.class, new InterfaceConfigContext(player, id, getConfig(current.getAttackStyles().length, current.getInterfaceId()), !specialBar));
} else { //if staff
PacketRepository.send(InterfaceConfig.class, new InterfaceConfigContext(player, id, 87, !specialBar));
@ -268,7 +278,7 @@ public final class WeaponInterface extends Component {
if (current == WeaponInterfaces.STAFF && player.getAttribute("autocast_select", false)) {
open();
}
selectAutoSpell(-1, true);
selectAutoSpell(-1, true, false);
}
PacketRepository.send(StringPacket.class, new StringContext(player, name, id, 0));
if (player.getSettings().isSpecialToggled()) {
@ -317,7 +327,7 @@ public final class WeaponInterface extends Component {
*/
private void checkStaffConfigs(int slot) {
if (current != WeaponInterfaces.STAFF) {
selectAutoSpell(-1, false);
selectAutoSpell(-1, false, false);
return;
}
boolean defensive = slot == 3;
@ -354,7 +364,7 @@ public final class WeaponInterface extends Component {
* @param buttonId The button id.
* @param adjustAttackStyle If the attack style should be adjusted.
*/
public void selectAutoSpell(int buttonId, boolean adjustAttackStyle) {
public void selectAutoSpell(int buttonId, boolean adjustAttackStyle, boolean forgetAutocast) {
boolean modern = player.getSpellBookManager().getSpellBook() == Components.MAGIC_192;
int[] data = modern ? MODERN_SPELL_IDS : ANCIENT_SPELL_IDS;
if (modern && player.getEquipment().getNew(3).getName().equalsIgnoreCase("Slayer's staff")) {
@ -376,8 +386,13 @@ public final class WeaponInterface extends Component {
}
}
}
if (forgetAutocast) {
removeAttributes(player, attributeAutocastButtonId, attributeAutocastStyle);
}
if (buttonId < 0) {
player.getProperties().setAutocastSpell(null);
setComponentVisibility(player, Components.WEAPON_STAFF_SEL_90, 83, false);
setComponentVisibility(player, Components.WEAPON_STAFF_SEL_90, 183, false);
if (adjustAttackStyle && current != null) {
setAttackStyle(3);
player.getProperties().getCombatPulse().updateStyle();
@ -389,6 +404,8 @@ public final class WeaponInterface extends Component {
player.getPacketDispatch().sendInterfaceConfig(Components.WEAPON_STAFF_SEL_90, 83, !defensive);
current = (CombatSpell) (modern ? SpellBookManager.SpellBook.MODERN.getSpell(data[buttonId]) : SpellBookManager.SpellBook.ANCIENT.getSpell(data[buttonId]));
player.getProperties().setAutocastSpell(current);
setAttribute(player, attributeAutocastButtonId, buttonId);
setAttribute(player, attributeAutocastStyle, player.getSettings().getAttackStyleIndex());
int configId = configStart + (2 * buttonId);
if (modern && player.getEquipment().getNew(3).getName().equalsIgnoreCase("Slayer's staff") || modern && player.getEquipment().getNew(3).getName().equalsIgnoreCase("Void knight mace")) {
boolean slayer = player.getEquipment().getNew(3).getName().equalsIgnoreCase("Slayer's staff");
@ -508,6 +525,37 @@ public final class WeaponInterface extends Component {
return WeaponInterfaces.values()[slot];
}
/**
* Restores the player's autocast settings to what they were in the prior login session.
* Returns false if the player has no autocast to restore, true otherwise.
*/
public boolean restoreAutocast() {
int buttonID = getAttribute(player, attributeAutocastButtonId, -1);
int style = getAttribute(player, attributeAutocastStyle, -1);
if (buttonID < 0 || style < 0 || current != WeaponInterfaces.STAFF || !canAutocast(false)) {
removeAttributes(player, attributeAutocastButtonId, attributeAutocastStyle);
return false;
}
restoreAttackStyle(style);
checkStaffConfigs(style);
selectAutoSpell(buttonID, false, false);
player.getProperties().getCombatPulse().updateStyle();
return true;
}
/**
* Restores the player's attack style settings to what they were in the prior login session.
*/
public void restoreAttackStyle(int index) {
if (index < 0 || index >= current.getAttackStyles().length) return;
player.getSettings().toggleAttackStyleIndex(index);
player.getProperties().setAttackStyle(current.getAttackStyles()[index]);
if (index < attackAnimations.length && !player.getAppearance().isNpc()) {
player.getProperties().setAttackAnimation(attackAnimations[index]);
}
player.getProperties().getCombatPulse().updateStyle();
}
/**
* Represents an attack style.
* @author Emperor

View file

@ -1,5 +1,6 @@
package core.game.node.entity.player.info.login;
import core.api.EquipmentSlot;
import core.game.component.Component;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.emote.Emotes;
@ -11,6 +12,7 @@ import core.net.packet.out.Interface;
import core.plugin.Plugin;
import core.ServerConstants;
import core.game.interaction.InteractionListeners;
import core.game.node.entity.combat.equipment.WeaponInterface;
import content.global.handlers.iface.RulesAndInfo;
import core.tools.Log;
import core.game.world.GameWorld;
@ -138,15 +140,23 @@ public final class LoginConfiguration {
player.getEmoteManager().unlock(Emotes.SAFETY_FIRST);
}
int savedAttackStyle = player.getSettings().getAttackStyleIndex();
for (Item item : player.getEquipment().toArray()) {
//Run equip hooks for all items equipped on login.
//We should have already been doing this.
//Frankly, I don't even want to imagine the number of bugs us *not* doing this has caused.
if (item == null) continue;
player.getEquipment().remove(item);
if (!InteractionListeners.run(item.getId(), player, item, true) || !player.getEquipment().add(item, true, false)) {
player.sendMessage(colorize("%RAs you can no longer wear " + item.getName() + ", it has been unequipped."));
addItemOrBank(player, item.getId(), item.getAmount());
if (player.getEquipment().remove(item)) {
if (!InteractionListeners.run(item.getId(), player, item, true) || !player.getEquipment().add(item, true, false)) {
player.sendMessage(colorize("%RAs you can no longer wear " + item.getName() + ", it has been unequipped."));
addItemOrBank(player, item.getId(), item.getAmount());
} else if (equipSlot(item.getId()) == EquipmentSlot.WEAPON) {
// Put player's weapon style back to how it was before it was re-equipped.
WeaponInterface inter = player.getExtension(WeaponInterface.class);
if (!inter.restoreAutocast()) {
inter.restoreAttackStyle(savedAttackStyle);
}
}
}
}

View file

@ -410,7 +410,7 @@ public final class InterfaceManager {
}
}
if (player.getProperties().getAutocastSpell() != null) {
inter.selectAutoSpell(inter.getAutospellId(player.getProperties().getAutocastSpell().getSpellId()), true);
inter.selectAutoSpell(inter.getAutospellId(player.getProperties().getAutocastSpell().getSpellId()), true, false);
}
}

View file

@ -79,7 +79,7 @@ class SpellbookSwap : PersistTimer(runInterval = minutesToTicks(2), identifier =
// Clear autocast
val weaponInterface = entity.getExtension<WeaponInterface>(WeaponInterface::class.java)
if (weaponInterface != null && entity.properties.autocastSpell != null) {
weaponInterface.selectAutoSpell(-1, true)
weaponInterface.selectAutoSpell(-1, true, true)
}
// Close autocast selection interface if it's still open
if (entity.getAttribute("autocast_select", false)) {