forked from 2009Scape/Server
Summoning rework
Pouches are not consumed. Points are not lost when summoning. However, lifespan is directly tied to summoning points, and the familiar despawns at zero points. Created a new pouch storage that can be accessed from the summoning tab by pressing "call pet" when no familiar is active. This allows freely switching familiars as long as points are maintained. Special move points start at empty instead of full, and replenish 1 point every 3 ticks instead of 15 points every 50 ticks.
This commit is contained in:
parent
4991b07ff8
commit
4799069ebd
10 changed files with 147 additions and 24 deletions
|
|
@ -4,6 +4,8 @@ import content.global.skill.summoning.pet.Pet
|
|||
import core.api.sendMessage
|
||||
import core.game.interaction.InterfaceListener
|
||||
|
||||
import content.global.skill.summoning.familiar.SnowscapeFamiliarInterface
|
||||
|
||||
class SummoningTabListener : InterfaceListener {
|
||||
override fun defineInterfaceListeners() {
|
||||
on(662) { player, _, opcode, buttonID, _, _ ->
|
||||
|
|
@ -12,7 +14,8 @@ class SummoningTabListener : InterfaceListener {
|
|||
if (player.familiarManager.hasFamiliar()) {
|
||||
player.familiarManager.familiar.call()
|
||||
} else {
|
||||
player.getPacketDispatch().sendMessage("You don't have a follower.")
|
||||
SnowscapeFamiliarInterface.Companion.openInterface(player)
|
||||
//player.getPacketDispatch().sendMessage("You don't have a follower.")
|
||||
}
|
||||
}
|
||||
67 -> {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ public final class BurdenInterfacePlugin extends ComponentPlugin {
|
|||
if (getAttribute(player, "openSatchel", null) != null) {
|
||||
SnowscapeSatchelListener.Companion.satchelInterfaceAction(player, component, opcode, button, slot, itemId);
|
||||
return true;
|
||||
}
|
||||
if (getAttribute(player, "openSummonStorage", false)) {
|
||||
SnowscapeFamiliarInterface.Companion.interfaceAction(player, component, opcode, button, slot, itemId);
|
||||
return true;
|
||||
}
|
||||
if (!player.getFamiliarManager().hasFamiliar() || !player.getFamiliarManager().getFamiliar().isBurdenBeast()) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ import java.util.List;
|
|||
|
||||
import static core.api.ContentAPIKt.*;
|
||||
|
||||
import core.game.component.Component;
|
||||
|
||||
/**
|
||||
* Represents a familiar.
|
||||
* @author Emperor
|
||||
|
|
@ -80,7 +82,7 @@ public abstract class Familiar extends NPC implements Plugin<Object> {
|
|||
/**
|
||||
* The amount of special points left.
|
||||
*/
|
||||
protected int specialPoints = 60;
|
||||
protected int specialPoints = 0;
|
||||
|
||||
/**
|
||||
* The pouch id.
|
||||
|
|
@ -178,7 +180,7 @@ public abstract class Familiar extends NPC implements Plugin<Object> {
|
|||
this.pointsPerTick = 0.0;
|
||||
} else {
|
||||
//int drain = pouch.getLevelRequired() - pouch.getSummonCost() + 1;
|
||||
// Snowscape: removing the initial drain and making it drain over the life of the familiar. Removing the +1 makes the final drain happen on the last tick of the familiar's life. That works for our new system, as the familiar timer won't start until that final tick happens.
|
||||
// Snowscape: removing the initial drain and making it drain over the life of the familiar. Removing the +1 makes the final drain happen on the last tick of the familiar's life. That works for our new system.
|
||||
int drain = pouch.getLevelRequired();
|
||||
this.pointsPerTick = (double) drain / maximumTicks;
|
||||
}
|
||||
|
|
@ -225,21 +227,20 @@ public abstract class Familiar extends NPC implements Plugin<Object> {
|
|||
|
||||
@Override
|
||||
public void handleTickActions() {
|
||||
//Snowscape: only count down the familiar timer if summoning points are zero, and give some summoning exp every minute a familiar is summoned.
|
||||
if (owner.getSkills().getLevel(Skills.SUMMONING) == 0) {
|
||||
ticks--;
|
||||
}
|
||||
//Snowscape: ticks are calculated from the summoning points (including fractional drain), so the familiar will despawn when points reach zero, but the timer goes up if points are restored
|
||||
//ticks--;
|
||||
ticks = Double.valueOf(maximumTicks*(owner.getSkills().getLevel(Skills.SUMMONING)-fracDrain)/pouch.getLevelRequired()).intValue();
|
||||
if (getWorldTicks() % 100 == 0) {
|
||||
owner.getSkills().addExperience(Skills.SUMMONING, pouch.getLevelRequired()+10, true);
|
||||
}
|
||||
|
||||
fracDrain += pointsPerTick;
|
||||
if (fracDrain > 1.0 && ticks > 0) {
|
||||
if (fracDrain > 1.0) {
|
||||
fracDrain -= 1.0;
|
||||
owner.getSkills().updateLevel(Skills.SUMMONING, -1, 0);
|
||||
}
|
||||
if (ticks % 50 == 0) {
|
||||
updateSpecialPoints(-15);
|
||||
if (getWorldTicks() % 3 == 0) {
|
||||
updateSpecialPoints(-1);
|
||||
if (!getText().isEmpty()) {
|
||||
super.sendChat(getText());
|
||||
}
|
||||
|
|
@ -258,6 +259,7 @@ public abstract class Familiar extends NPC implements Plugin<Object> {
|
|||
} else {
|
||||
owner.getPacketDispatch().sendMessage("<col=ff0000>Your familiar has vanished.");
|
||||
}
|
||||
playAudio(owner, Sounds.PRAYER_DRAIN_2672);
|
||||
dismiss();
|
||||
return;
|
||||
}
|
||||
|
|
@ -665,7 +667,8 @@ public abstract class Familiar extends NPC implements Plugin<Object> {
|
|||
setVarp(owner, 1175, 182986);
|
||||
setVarp(owner, 1174, -1);
|
||||
owner.getAppearance().sync();
|
||||
owner.getInterfaceManager().setViewedTab(3);
|
||||
owner.getInterfaceManager().openTab(new Component(662));
|
||||
owner.getInterfaceManager().setViewedTab(7);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -142,7 +142,13 @@ public final class FamiliarManager {
|
|||
((BurdenBeast) familiar).container.parse(famInv);
|
||||
}
|
||||
familiar.setAttribute("hp",Integer.parseInt( currentFamiliar.get("lifepoints").toString()));
|
||||
}
|
||||
} else {
|
||||
//Snowscape: Copied from Familiar.dismiss(), this clears the fields on the summoning tab if no familiar is loaded
|
||||
setVarp(player, 448, -1);
|
||||
setVarp(player, 1176, 0);
|
||||
setVarp(player, 1175, 182986);
|
||||
setVarp(player, 1174, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -164,12 +170,12 @@ public final class FamiliarManager {
|
|||
public void summon(Item item, boolean pet, boolean deleteItem) {
|
||||
boolean renew = false;
|
||||
if (hasFamiliar()) {
|
||||
if (familiar.getPouchId() == item.getId()) {
|
||||
renew = true;
|
||||
} else {
|
||||
//if (familiar.getPouchId() == item.getId()) {
|
||||
// renew = true;
|
||||
//} else {
|
||||
player.getPacketDispatch().sendMessage("You already have a follower.");
|
||||
return;
|
||||
}
|
||||
//}
|
||||
}
|
||||
if (player.getZoneMonitor().isRestricted(ZoneRestriction.FOLLOWERS) && !player.getLocks().isLocked("enable_summoning")) {
|
||||
player.getPacketDispatch().sendMessage("This is a Summoning-free area.");
|
||||
|
|
@ -193,6 +199,10 @@ public final class FamiliarManager {
|
|||
return;
|
||||
}
|
||||
*/
|
||||
if (player.getSkills().getLevel(Skills.SUMMONING) < 1) {
|
||||
player.getPacketDispatch().sendMessage("You need at least one Summoning point to summon this familiar.");
|
||||
return;
|
||||
}
|
||||
final int npcId = pouch.getNpcId();
|
||||
Familiar fam = !renew ? FAMILIARS.get(npcId) : familiar;
|
||||
if (fam == null) {
|
||||
|
|
@ -207,11 +217,11 @@ public final class FamiliarManager {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (!player.getInventory().remove(item)) {
|
||||
return;
|
||||
}
|
||||
//if (!player.getInventory().remove(item)) {
|
||||
// return;
|
||||
//}
|
||||
//player.getSkills().updateLevel(Skills.SUMMONING, -pouch.getSummonCost(), 0);
|
||||
player.getSkills().addExperience(Skills.SUMMONING, pouch.getSummonExperience());
|
||||
//player.getSkills().addExperience(Skills.SUMMONING, pouch.getSummonExperience());
|
||||
if (!renew) {
|
||||
familiar = fam;
|
||||
spawnFamiliar();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
package content.global.skill.summoning.familiar
|
||||
|
||||
import core.api.*
|
||||
import core.game.container.Container
|
||||
import content.global.skill.summoning.familiar.BurdenContainerListener
|
||||
//import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
//import core.game.interaction.InteractionListener
|
||||
//import core.game.interaction.IntType
|
||||
//import org.json.simple.JSONArray
|
||||
//import org.json.simple.JSONObject
|
||||
//import org.json.simple.parser.JSONParser
|
||||
import org.rs09.consts.Items
|
||||
|
||||
import core.game.component.Component
|
||||
import core.game.component.CloseEvent
|
||||
import core.game.container.access.InterfaceContainer
|
||||
|
||||
/* Custom Snowscape class. Allows storing summoning pouches in a special storage that can be accessed by using the "call familiar" button when no familiars are summoned.
|
||||
* Familiars can be summoned from this storage.
|
||||
* Designed around the snowscape summoning rework, where pouches are not consumed when summoning
|
||||
*/
|
||||
|
||||
class SnowscapeFamiliarInterface {
|
||||
companion object {
|
||||
|
||||
|
||||
//Function to handle constructing the interface
|
||||
public fun openInterface(player: Player) {
|
||||
val storage = player.summoningPouches
|
||||
if (storage.getListeners().count() < 1) storage.register(BurdenContainerListener(player))
|
||||
|
||||
player.getInterfaceManager().open(Component(671)).setCloseEvent(CloseEvent { player, component ->
|
||||
player.getInterfaceManager().closeSingleTab()
|
||||
removeAttribute(player, "openSummonStorage")
|
||||
//Summoning tab cannot be interacted with until it's closed and re-opened for some reason
|
||||
player.getInterfaceManager().removeTabs(7)
|
||||
player.getInterfaceManager().openTab(Component(662))
|
||||
player.getInterfaceManager().setViewedTab(7)
|
||||
return@CloseEvent true
|
||||
}
|
||||
)
|
||||
setAttribute(player, "openSummonStorage", true)
|
||||
storage.shift()
|
||||
player.getInterfaceManager().openSingleTab(Component(665))
|
||||
InterfaceContainer.generateItems(player, player.getInventory().toArray(), arrayOf("Add"),665,0,7,4,93)
|
||||
InterfaceContainer.generateItems(player, storage.toArray(), arrayOf("Remove","Summon"),671,27,5,6,30)
|
||||
}
|
||||
|
||||
|
||||
fun interfaceAction(player: Player, component: Component, opcode: Int, button: Int, slot: Int, itemId: Int) {
|
||||
val inventory = component.getId() == 665
|
||||
val container = if (inventory) player.getInventory() else player.summoningPouches
|
||||
val item = if (slot >= 0 && slot < container.capacity()) container.get(slot) else null
|
||||
if (item == null && button != 29) return
|
||||
|
||||
if (opcode == 9) player.sendMessage(item!!.getDefinition().getExamine())
|
||||
|
||||
if (inventory) {
|
||||
when (opcode) {
|
||||
155 -> addPouch(player, item!!)
|
||||
}
|
||||
} else {
|
||||
when (opcode) {
|
||||
155 -> if (button != 29) summonPouch(player, item!!)
|
||||
196 -> removePouch(player, item!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addPouch(player: Player, item: Item) {
|
||||
if (!hasOption(item, "Summon")){
|
||||
sendMessage(player, "You can only add summoning pouches.")
|
||||
return
|
||||
} else if (player.summoningPouches.containsItem(item)) {
|
||||
sendMessage(player, "You have already added this familiar's pouch.")
|
||||
return
|
||||
} else if (player.summoningPouches.add(item)) {
|
||||
player.getInventory().remove(item)
|
||||
}
|
||||
}
|
||||
|
||||
private fun removePouch(player: Player, item: Item) {
|
||||
if (player.getInventory().add(item)) {
|
||||
player.summoningPouches.remove(item)
|
||||
}
|
||||
}
|
||||
|
||||
private fun summonPouch(player: Player, item: Item) {
|
||||
player.getInterfaceManager().close()
|
||||
SummonFamiliarPlugin().handle(player, item, "summon")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -49,6 +49,7 @@ fun permadeath(target: Player) {
|
|||
target.goldSatchel.clear()
|
||||
target.runeSatchel.clear()
|
||||
target.blackSatchel.clear()
|
||||
target.summoningPouches.clear()
|
||||
|
||||
// Skills
|
||||
target.skills = Skills(target)
|
||||
|
|
|
|||
|
|
@ -319,6 +319,8 @@ public class Player extends Entity {
|
|||
public final Container blackSatchel = new Container(30, ContainerType.ALWAYS_STACK);
|
||||
public final Container goldSatchel = new Container(30, ContainerType.ALWAYS_STACK);
|
||||
public final Container runeSatchel = new Container(30, ContainerType.ALWAYS_STACK);
|
||||
// The summoning pouch storage
|
||||
public final Container summoningPouches = new Container(30);
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Player} {@code Object}.
|
||||
|
|
|
|||
|
|
@ -387,6 +387,8 @@ class PlayerSaveParser(val player: Player) {
|
|||
val runeSatchel = snowscapeData["runeSatchel"]
|
||||
if (runeSatchel != null) player.runeSatchel.parse(runeSatchel as JSONArray)
|
||||
|
||||
val summoningPouches = snowscapeData["summoningPouches"]
|
||||
if (summoningPouches != null) player.summoningPouches.parse(summoningPouches as JSONArray)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -656,6 +656,8 @@ class PlayerSaver (val player: Player){
|
|||
snowscapeData.put("goldSatchel", saveContainer(player.goldSatchel))
|
||||
snowscapeData.put("runeSatchel", saveContainer(player.runeSatchel))
|
||||
|
||||
snowscapeData.put("summoningPouches", saveContainer(player.summoningPouches))
|
||||
|
||||
root.put("snowscape_data",snowscapeData)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -358,9 +358,9 @@ public final class InterfaceManager {
|
|||
openTab(6, new Component(player.getSpellBookManager().getSpellBook())); // Magic
|
||||
break;
|
||||
case 7:
|
||||
if (player.getFamiliarManager().hasFamiliar()) {
|
||||
//if (player.getFamiliarManager().hasFamiliar()) {
|
||||
openTab(7, new Component(662));
|
||||
}
|
||||
//}
|
||||
break;
|
||||
default:
|
||||
openTab(i, new Component(DEFAULT_TABS[i]));
|
||||
|
|
@ -393,9 +393,9 @@ public final class InterfaceManager {
|
|||
openTab(4, new Component(Components.WORNITEMS_387)); // Equipment
|
||||
openTab(5, new Component(Components.PRAYER_271)); // Prayer
|
||||
openTab(6, new Component(player.getSpellBookManager().getSpellBook())); // Magic
|
||||
if (player.getFamiliarManager().hasFamiliar()) {
|
||||
//if (player.getFamiliarManager().hasFamiliar()) {
|
||||
openTab(7, new Component(Components.LORE_STATS_SIDE_662)); // summoning.
|
||||
}
|
||||
//}
|
||||
openTab(8, new Component(Components.FRIENDS2_550)); // Friends
|
||||
openTab(9, new Component(Components.IGNORE2_551)); // Ignores
|
||||
openTab(10, new Component(Components.CLANJOIN_589)); // Clan chat
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue