mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-09 16:45:44 -07:00
Rewrote pet back end to use a more authentic system
Pets can now stack Fixes a bug where a pet could get reset to 0 hunger and growth when dropped Player save version migration messages are no longer shown Pets now morph into adults in-place
This commit is contained in:
parent
6b0f942598
commit
9c202aa47a
19 changed files with 204 additions and 684 deletions
|
|
@ -47,7 +47,7 @@ class CatOnArdougneCivilian: InteractionListener {
|
|||
override fun defineListeners() {
|
||||
onUseWith(IntType.NPC,cats,*civilians){ player, used, _ ->
|
||||
sendItemDialogue(player,Items.DEATH_RUNE_560,"You hand over the cat.<br>You are given 100 Death Runes.")
|
||||
player.familiarManager.removeDetails(used.idHash)
|
||||
player.familiarManager.removeDetails(used.id)
|
||||
removeItem(player,used,Container.INVENTORY)
|
||||
addItem(player,Items.DEATH_RUNE_560,100)
|
||||
return@onUseWith true
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class SummoningTabListener : InterfaceListener {
|
|||
// Dismiss now
|
||||
if (player.getFamiliarManager().getFamiliar() is Pet) {
|
||||
val pet = player.familiarManager.familiar as Pet
|
||||
player.familiarManager.removeDetails(pet.getItemIdHash())
|
||||
player.familiarManager.removeDetails(pet.getItemId())
|
||||
}
|
||||
player.familiarManager.dismiss()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
package content.global.skill.summoning.familiar;
|
||||
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.dialogue.FacialExpression;
|
||||
import core.game.node.entity.npc.Metamorphosis;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.plugin.Initializable;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* Handles the baby chinchompa pet.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
@Initializable
|
||||
public class BabyChinchompaNPC extends Metamorphosis {
|
||||
|
||||
/**
|
||||
* The chinchompa ids.
|
||||
*/
|
||||
private static final int[] CHINCHOMPA_IDS = new int[] { 8643, 8644, 8657, 8658 };
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BabyChinchompaNPC} object.
|
||||
*/
|
||||
public BabyChinchompaNPC() {
|
||||
super(CHINCHOMPA_IDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin getDialoguePlugin() {
|
||||
return new BabyChinchompaDialogue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRandomNpcId() {
|
||||
int i = RandomFunction.getRandom(getIds().length - 1);
|
||||
if (getIds()[i] == 8658) {
|
||||
int x = RandomFunction.getRandom(30);
|
||||
if (x == 1) {
|
||||
return getIds()[i];
|
||||
} else {
|
||||
return getIds()[i-1];
|
||||
}
|
||||
}
|
||||
return getIds()[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the BabyChinchompa Dialogue.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
public final class BabyChinchompaDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BabyChinchompaDialogue} {@code Object}.
|
||||
*/
|
||||
public BabyChinchompaDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BabyChinchompaDialogue} {@code Object}.
|
||||
*
|
||||
* @param player the player.
|
||||
*/
|
||||
public BabyChinchompaDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new BabyChinchompaDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
npc = (NPC) args[0];
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, npc.getId() != 8658 ? "Squeak! Squeak!" : "Squeaka! Squeaka!");
|
||||
stage = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
end();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 8643, 8644, 8657, 8658 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ public final class DismissDialoguePlugin extends DialoguePlugin {
|
|||
if (player.getFamiliarManager().getFamiliar() instanceof Pet) {
|
||||
interpreter.sendDialogues(player, null, "Run along; I'm setting you free.");
|
||||
Pet pet = (Pet) player.getFamiliarManager().getFamiliar();
|
||||
player.getFamiliarManager().removeDetails(pet.getItemIdHash());
|
||||
player.getFamiliarManager().removeDetails(pet.getItemId());
|
||||
} else {
|
||||
end();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import content.global.skill.summoning.pet.Pet;
|
|||
import content.global.skill.summoning.pet.Pets;
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.game.component.Component;
|
||||
import core.game.container.Container;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
|
|
@ -20,7 +19,6 @@ import core.game.world.update.flag.context.Animation;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static core.api.ContentAPIKt.*;
|
||||
|
|
@ -38,9 +36,9 @@ public final class FamiliarManager {
|
|||
private static final Map<Integer, Familiar> FAMILIARS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The pet details mapping, sorted by item id.
|
||||
* The pet details mapping.
|
||||
*/
|
||||
private final Map<Integer, PetDetails> petDetails = new HashMap<Integer, PetDetails>();
|
||||
private final Map<Integer, ArrayList<PetDetails>> petDetails = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The player.
|
||||
|
|
@ -70,50 +68,69 @@ public final class FamiliarManager {
|
|||
this.player = player;
|
||||
}
|
||||
|
||||
public final void parse(JSONObject familiarData) {
|
||||
public void parse(JSONObject familiarData) {
|
||||
for (Pets pet : Pets.values()) {
|
||||
for (int id : new int[]{pet.getBabyItemId(), pet.getGrownItemId(), pet.getOvergrownItemId()}) {
|
||||
if (id != -1) {
|
||||
petDetails.put(id, new ArrayList<PetDetails>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int currentPet = -1;
|
||||
if (familiarData.containsKey("currentPet")) {
|
||||
currentPet = Integer.parseInt(familiarData.get("currentPet").toString());
|
||||
}
|
||||
JSONArray petDetails = (JSONArray) familiarData.get("petDetails");
|
||||
for (int i = 0; i < petDetails.size(); i++) {
|
||||
JSONObject detail = (JSONObject) petDetails.get(i);
|
||||
PetDetails details = new PetDetails(0);
|
||||
details.updateHunger(Double.parseDouble(detail.get("hunger").toString()));
|
||||
details.updateGrowth(Double.parseDouble(detail.get("growth").toString()));
|
||||
int itemIdHash = Integer.parseInt(detail.get("petId").toString());
|
||||
// The below is for migrating legacy saves, which stored baby item IDs + growth stages
|
||||
if (detail.containsKey("stage")) {
|
||||
// The "itemIdHash" is actually the baby item ID. The "stage" gives the actual pet stage we want.
|
||||
int babyItemId = itemIdHash;
|
||||
int itemId = babyItemId;
|
||||
int stage = Integer.parseInt(detail.get("stage").toString());
|
||||
if (stage > 0) {
|
||||
Pets pets = Pets.forId(babyItemId);
|
||||
itemId = pets.getNextStageItemId(itemId);
|
||||
if (stage > 1) {
|
||||
if (player.version < 2) { //migrate the v1 format
|
||||
JSONArray petDetails = (JSONArray) familiarData.get("petDetails");
|
||||
for (Object petDetail : petDetails) {
|
||||
JSONObject detail = (JSONObject) petDetail;
|
||||
PetDetails details = new PetDetails(0);
|
||||
details.updateHunger(Double.parseDouble(detail.get("hunger").toString()));
|
||||
details.updateGrowth(Double.parseDouble(detail.get("growth").toString()));
|
||||
int itemId;
|
||||
int itemIdHash = Integer.parseInt(detail.get("petId").toString());
|
||||
// The below is for migrating the v0 format, which stored baby item IDs + growth stages
|
||||
if (detail.containsKey("stage")) {
|
||||
// The itemIdHash is actually the baby item ID. The "stage" gives the actual pet stage we want.
|
||||
int babyItemId = itemIdHash;
|
||||
itemId = babyItemId;
|
||||
int stage = Integer.parseInt(detail.get("stage").toString());
|
||||
if (stage > 0) {
|
||||
Pets pets = Pets.forId(babyItemId);
|
||||
itemId = pets.getNextStageItemId(itemId);
|
||||
if (stage > 1) {
|
||||
itemId = pets.getNextStageItemId(itemId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
itemId = itemIdHash >> 16 & 0xFFFF; //in the legacy v1 format, was hash rather than item id
|
||||
}
|
||||
Item item = new Item(itemId);
|
||||
item.setCharge(1000); //this is the default value that will correspond to the player's item
|
||||
itemIdHash = item.getIdHash();
|
||||
if (currentPet != -1 && currentPet == babyItemId) {
|
||||
currentPet = itemIdHash;
|
||||
this.petDetails.get(itemId).add(details);
|
||||
}
|
||||
if (currentPet > 65536) {
|
||||
currentPet = currentPet >> 16 & 0xFFFF; //in the legacy v1 format, was hash rather than item id
|
||||
}
|
||||
} else {
|
||||
JSONObject petDetails = (JSONObject) familiarData.get("petDetails");
|
||||
for (Object key : petDetails.keySet()) {
|
||||
int itemId = Integer.parseInt(key.toString());
|
||||
this.petDetails.put(itemId, new ArrayList<>());
|
||||
JSONArray values = (JSONArray) petDetails.get(key.toString());
|
||||
for (Object petDetail : values) {
|
||||
JSONObject detail = (JSONObject) petDetail;
|
||||
PetDetails details = new PetDetails(0);
|
||||
details.updateHunger(Double.parseDouble(detail.get("hunger").toString()));
|
||||
details.updateGrowth(Double.parseDouble(detail.get("growth").toString()));
|
||||
this.petDetails.get(itemId).add(details);
|
||||
}
|
||||
}
|
||||
this.petDetails.put(itemIdHash, details);
|
||||
}
|
||||
|
||||
if (currentPet != -1) {
|
||||
PetDetails details = this.petDetails.get(currentPet);
|
||||
int itemId = currentPet >> 16 & 0xFFFF;
|
||||
Pets pets = Pets.forId(itemId);
|
||||
if (details == null) {
|
||||
details = new PetDetails(pets.getGrowthRate() == 0.0 ? 100.0 : 0.0);
|
||||
this.petDetails.put(currentPet, details);
|
||||
}
|
||||
familiar = new Pet(player, details, itemId, pets.getNpcId(itemId));
|
||||
int last = this.petDetails.get(currentPet).size() - 1;
|
||||
PetDetails details = this.petDetails.get(currentPet).get(last);
|
||||
Pets pets = Pets.forId(currentPet);
|
||||
familiar = new Pet(player, details, currentPet, pets.getNpcId(currentPet));
|
||||
} else if (familiarData.containsKey("familiar")) {
|
||||
JSONObject currentFamiliar = (JSONObject) familiarData.get("familiar");
|
||||
int familiarId = Integer.parseInt( currentFamiliar.get("originalId").toString());
|
||||
|
|
@ -147,7 +164,7 @@ public final class FamiliarManager {
|
|||
public void summon(Item item, boolean pet, boolean deleteItem) {
|
||||
boolean renew = false;
|
||||
if (hasFamiliar()) {
|
||||
if(familiar.getPouchId() == item.getId()) {
|
||||
if (familiar.getPouchId() == item.getId()) {
|
||||
renew = true;
|
||||
} else {
|
||||
player.getPacketDispatch().sendMessage("You already have a follower.");
|
||||
|
|
@ -180,7 +197,7 @@ public final class FamiliarManager {
|
|||
player.getPacketDispatch().sendMessage("Invalid familiar " + npcId + " - report on 2009Scape GitLab");
|
||||
return;
|
||||
}
|
||||
if(!renew) {
|
||||
if (!renew) {
|
||||
fam = fam.construct(player, npcId);
|
||||
if (fam.getSpawnLocation() == null) {
|
||||
player.getPacketDispatch().sendMessage("The spirit in this pouch is too big to summon here. You will need to move to a larger");
|
||||
|
|
@ -193,7 +210,7 @@ public final class FamiliarManager {
|
|||
}
|
||||
player.getSkills().updateLevel(Skills.SUMMONING, -pouch.getSummonCost(), 0);
|
||||
player.getSkills().addExperience(Skills.SUMMONING, pouch.getSummonExperience());
|
||||
if(!renew) {
|
||||
if (!renew) {
|
||||
familiar = fam;
|
||||
spawnFamiliar();
|
||||
} else {
|
||||
|
|
@ -217,11 +234,10 @@ public final class FamiliarManager {
|
|||
* @param deleteItem the item.
|
||||
* @param location the location.
|
||||
*/
|
||||
public void morphPet(final Item item, boolean deleteItem, Location location) {
|
||||
if (hasFamiliar()) {
|
||||
familiar.dismiss();
|
||||
}
|
||||
summonPet(item, deleteItem, true, location);
|
||||
public void morphPet(final Item item, boolean deleteItem, Location location, double hunger, double growth) {
|
||||
int hasWarned = ((Pet) familiar).getHasWarned();
|
||||
familiar.dismiss();
|
||||
summonPet(item, deleteItem, true, location, hasWarned, hunger, growth);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -230,7 +246,7 @@ public final class FamiliarManager {
|
|||
* @param deleteItem the item.
|
||||
*/
|
||||
private boolean summonPet(final Item item, boolean deleteItem) {
|
||||
return summonPet(item, deleteItem, false, null);
|
||||
return summonPet(item, deleteItem, false, null, 0, -1, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -238,9 +254,8 @@ public final class FamiliarManager {
|
|||
* @param item the item.
|
||||
* @param morph the pet.
|
||||
*/
|
||||
private boolean summonPet(final Item item, boolean deleteItem, boolean morph, Location location) {
|
||||
private boolean summonPet(final Item item, boolean deleteItem, boolean morph, Location location, int hasWarned, double hunger, double growth) {
|
||||
final int itemId = item.getId();
|
||||
int itemIdHash = item.getIdHash();
|
||||
if (itemId > 8850 && itemId < 8900) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -252,52 +267,24 @@ public final class FamiliarManager {
|
|||
player.getDialogueInterpreter().sendDialogue("You need a summoning level of " + pets.getSummoningLevel() + " to summon this.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this pet does not have an individual ID yet, we need to find it an available one.
|
||||
// If it does, we need to verify that this ID is not already used for a different pet. This is needed to correct a historical bug that allowed multiple pets to be assigned the same individual ID (the historical code only checked the *current* stage item ID, failing to realize that we also need to account for *future* stage item IDs, in case the current pet grows up, resulting in a clash when it did). Saves affected by that bug will have multiple copies of the same item pointing to the same pet, which we have an opportunity to rectify now.
|
||||
ArrayList<Integer> taken = new ArrayList<Integer>();
|
||||
Container[] searchSpace = {player.getInventory(), player.getBankPrimary(), player.getBankSecondary()};
|
||||
for (int checkId = pets.getBabyItemId(); checkId != -1; checkId = pets.getNextStageItemId(checkId)) {
|
||||
Item check = new Item(checkId, 1);
|
||||
for (Container container : searchSpace) {
|
||||
for (Item i : container.getAll(check)) {
|
||||
taken.add(i.getCharge());
|
||||
}
|
||||
}
|
||||
}
|
||||
PetDetails details = petDetails.get(itemIdHash);
|
||||
int individual = item.getCharge();
|
||||
if (details != null) { //we have this pet on file, but we need to check that it wasn't affected by the historical bug mentioned above
|
||||
details.setIndividual(individual);
|
||||
int count = 0;
|
||||
for (int i : taken) {
|
||||
if (i == individual) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count > 1) { //this pet is sadly conjoined with another individual of its kind; untangle it by initializing it anew (which is what should have happened in the first place, save the minor detail of hunger propagation from the previous stage, which we no longer have any record of)
|
||||
details = null;
|
||||
}
|
||||
}
|
||||
if (details == null) { //init new pet
|
||||
details = new PetDetails(pets.getGrowthRate() == 0.0 ? 100.0 : 0.0);
|
||||
for (individual = 0; taken.contains(individual) && individual < 0xFFFF; individual++) {}
|
||||
details.setIndividual(individual);
|
||||
// Make a copy of the item to extract what the item's idHash will be when including the individual ID as a "charge" value.
|
||||
// The copy is necessary since the player's inventory still contains the default-charged item, which we will be removing only later.
|
||||
Item newItem = item.copy();
|
||||
newItem.setCharge(individual);
|
||||
petDetails.put(newItem.getIdHash(), details);
|
||||
int last = this.petDetails.get(itemId).size() - 1;
|
||||
if (last < 0) { //new pet
|
||||
last = 0;
|
||||
PetDetails details = new PetDetails(pets.getGrowthRate() == 0.0 ? 100.0 : 0.0);
|
||||
this.petDetails.get(itemId).add(details);
|
||||
}
|
||||
PetDetails details = this.petDetails.get(itemId).get(last);
|
||||
int npcId = pets.getNpcId(itemId);
|
||||
if (npcId > 0) {
|
||||
familiar = new Pet(player, details, itemId, npcId);
|
||||
((Pet) familiar).setHasWarned(hasWarned);
|
||||
if (hunger != -1) ((Pet) familiar).getDetails().setHunger(hunger);
|
||||
if (growth != -1) ((Pet) familiar).getDetails().setGrowth(growth);
|
||||
if (deleteItem) {
|
||||
player.animate(new Animation(827));
|
||||
// We cannot use player().getInventory().remove(item), because that will remove the first pet item it sees, rather than the specific one (with the specific charge value) the player clicked.
|
||||
// Instead, find the specific item the player dropped by slot, and remove that specific one.
|
||||
int slot = player.getInventory().getSlotHash(item);
|
||||
player.getInventory().remove(item, slot, true);
|
||||
if (!player.getInventory().remove(item, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (morph) {
|
||||
morphFamiliar(location);
|
||||
|
|
@ -364,11 +351,7 @@ public final class FamiliarManager {
|
|||
return;
|
||||
}
|
||||
Pet pet = ((Pet) familiar);
|
||||
PetDetails details = pet.getDetails();
|
||||
Item petItem = new Item(pet.getItemId());
|
||||
petItem.setCharge(details.getIndividual());
|
||||
if (player.getInventory().add(petItem)) {
|
||||
petDetails.put(pet.getItemIdHash(),details);
|
||||
if (player.getInventory().add(new Item(pet.getItemId()))) {
|
||||
player.animate(Animation.create(827));
|
||||
player.getFamiliarManager().dismiss();
|
||||
}
|
||||
|
|
@ -423,11 +406,23 @@ public final class FamiliarManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Removes the details for this pet.
|
||||
* @param itemIdHash The item id hash of the pet.
|
||||
* Adds pet details for a new pet to that pet's stack.
|
||||
* @param itemId The item id of the pet.
|
||||
* @param details The new pet details.
|
||||
*/
|
||||
public void removeDetails(int itemIdHash) {
|
||||
petDetails.remove(itemIdHash);
|
||||
public void addDetails(int itemId, PetDetails details) {
|
||||
petDetails.get(itemId).add(details);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the details for this pet.
|
||||
* @param itemId The item id of the pet.
|
||||
*/
|
||||
public void removeDetails(int itemId) {
|
||||
int last = petDetails.get(itemId).size() - 1;
|
||||
if (last >= 0) {
|
||||
petDetails.get(itemId).remove(last);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -521,7 +516,7 @@ public final class FamiliarManager {
|
|||
}
|
||||
|
||||
|
||||
public Map<Integer, PetDetails> getPetDetails() {
|
||||
public Map<Integer, ArrayList<PetDetails>> getPetDetails() {
|
||||
return petDetails;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,117 +0,0 @@
|
|||
package content.global.skill.summoning.familiar;
|
||||
|
||||
import core.plugin.Initializable;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.dialogue.FacialExpression;
|
||||
import core.game.node.entity.npc.Metamorphosis;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* Handles the kalphite princess pet.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
@Initializable
|
||||
public class KalphiteNPC extends Metamorphosis {
|
||||
|
||||
/**
|
||||
* The kalphite ids.
|
||||
*/
|
||||
private static final int[] KALPHITE_IDS = new int[] { 8602, 8603 };
|
||||
|
||||
/**
|
||||
* Constructs a new {@code KalphiteNPC} object.
|
||||
*/
|
||||
public KalphiteNPC() {
|
||||
super(KALPHITE_IDS);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DialoguePlugin getDialoguePlugin() {
|
||||
return new KalphitePrincessDialogue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the KalphitePrincess dialogue.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
public final class KalphitePrincessDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code KalphitePrincessDialogue} {@code Object}.
|
||||
*/
|
||||
public KalphitePrincessDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code KalphitePrincessDialogue} {@code Object}.
|
||||
*
|
||||
* @param player the player.
|
||||
*/
|
||||
public KalphitePrincessDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new KalphitePrincessDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
npc = (NPC) args[0];
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is it with your kind and potato cactus?");
|
||||
stage = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Truthfully?");
|
||||
stage = 1;
|
||||
break;
|
||||
case 1:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yeah, please.");
|
||||
stage = 2;
|
||||
break;
|
||||
case 2:
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Soup. We make a fine soup with it.");
|
||||
stage = 3;
|
||||
break;
|
||||
case 3:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Kalphites can cook?");
|
||||
stage = 4;
|
||||
break;
|
||||
case 4:
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Nah, we just collect it and put it there because we", "know fools like yourself will come down looking for it", "then inevitably be killed by my mother.");
|
||||
stage = 5;
|
||||
break;
|
||||
case 5:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Evidently not, that's how I got you!");
|
||||
stage = 6;
|
||||
break;
|
||||
case 6:
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Touch<EFBFBD>.");
|
||||
stage = 7;
|
||||
break;
|
||||
case 7:
|
||||
end();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 8602, 8603 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
package content.global.skill.summoning.familiar;
|
||||
|
||||
import core.plugin.Initializable;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.dialogue.FacialExpression;
|
||||
import core.game.node.entity.npc.Metamorphosis;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* Handles the metamorphosis of the zulrah pet.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
@Initializable
|
||||
public class SnakelingNPC extends Metamorphosis {
|
||||
|
||||
/**
|
||||
* The snakeling ids.
|
||||
*/
|
||||
public static final int[] SNAKELING_IDS = new int[] { 8626, 8627, 8628 };
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructs a new {@code SnakelingNPC} object.
|
||||
*/
|
||||
public SnakelingNPC() {
|
||||
super(SNAKELING_IDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin getDialoguePlugin() {
|
||||
return new PetSnakelingDialogue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the pet snakeling dialogue.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
public final class PetSnakelingDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PetSnakelingDialogue} {@code Object}.
|
||||
*/
|
||||
public PetSnakelingDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PetSnakelingDialogue} {@code Object}.
|
||||
*
|
||||
* @param player the player.
|
||||
*/
|
||||
public PetSnakelingDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new PetSnakelingDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
npc = (NPC) args[0];
|
||||
player("Hey little snake!");
|
||||
stage = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
npc(FacialExpression.OLD_NORMAL, "Soon, Zulrah shall establish dominion over this plane.");
|
||||
stage = 1;
|
||||
break;
|
||||
case 1:
|
||||
player("Wanna play fetch?");
|
||||
stage = 2;
|
||||
break;
|
||||
case 2:
|
||||
npc(FacialExpression.OLD_NORMAL, "Submit to the almighty Zulrah.");
|
||||
stage = 3;
|
||||
break;
|
||||
case 3:
|
||||
player("Walkies? Or slidies...?");
|
||||
stage = 4;
|
||||
break;
|
||||
case 4:
|
||||
npc(FacialExpression.OLD_NORMAL, "Zulrah's wilderness as a God will soon be demonstrated.");
|
||||
stage = 5;
|
||||
break;
|
||||
case 5:
|
||||
player("I give up...");
|
||||
stage = 6;
|
||||
break;
|
||||
case 6:
|
||||
end();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return SNAKELING_IDS;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
package content.global.skill.summoning.familiar;
|
||||
|
||||
import core.plugin.Initializable;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.node.entity.npc.Metamorphosis;
|
||||
|
||||
/**
|
||||
* Handles the metamorphosis of Vet'ion Jr.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
@Initializable
|
||||
public class VetionNPC extends Metamorphosis {
|
||||
|
||||
/**
|
||||
* The Vet'ion Ids.
|
||||
*/
|
||||
public static final int[] VETION_IDS = new int[] { 8600, 8654 };
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructs a new{@code VetionNPC} object.
|
||||
*/
|
||||
public VetionNPC() {
|
||||
super(VETION_IDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin getDialoguePlugin() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -117,8 +117,8 @@ public final class KittenInteractDialogue extends DialoguePlugin {
|
|||
player.sendChat("Shoo cat!");
|
||||
Pet currentPet = (Pet) player.getFamiliarManager().getFamiliar();
|
||||
player.getFamiliarManager().getFamiliar().sendChat("Miaow!");
|
||||
player.getFamiliarManager().removeDetails(currentPet.getItemIdHash());
|
||||
player.getFamiliarManager().getFamiliar().dismiss();
|
||||
player.getFamiliarManager().removeDetails(currentPet.getItemId());
|
||||
player.getPacketDispatch().sendMessage("The cat has run away.");
|
||||
}
|
||||
end();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public final class Pet extends Familiar {
|
|||
/**
|
||||
* The growth rate of the pet.
|
||||
*/
|
||||
private double growthRate;
|
||||
private final double growthRate;
|
||||
|
||||
/**
|
||||
* The pets type.
|
||||
|
|
@ -86,8 +86,8 @@ public final class Pet extends Familiar {
|
|||
hasWarned = 2;
|
||||
}
|
||||
if (hunger >= 100.0 && growthRate != 0 && pet.getFood().length != 0) {
|
||||
owner.getFamiliarManager().removeDetails(this.getItemIdHash());
|
||||
owner.getFamiliarManager().dismiss();
|
||||
owner.getFamiliarManager().removeDetails(getItemId());
|
||||
owner.getFamiliarManager().setFamiliar(null);
|
||||
setVarp(owner, 1175, 0);
|
||||
owner.sendMessage("<col=ff0000>Your pet has run away.</col>");
|
||||
|
|
@ -126,16 +126,10 @@ public final class Pet extends Familiar {
|
|||
// then this pet is already overgrown
|
||||
return;
|
||||
}
|
||||
owner.getFamiliarManager().removeDetails(this.getItemIdHash());
|
||||
owner.getFamiliarManager().dismiss();
|
||||
owner.getFamiliarManager().removeDetails(getItemId());
|
||||
owner.getFamiliarManager().addDetails(newItemId, details);
|
||||
owner.getFamiliarManager().morphPet(new Item(newItemId), false, location, details.getHunger(), 0);
|
||||
owner.getPacketDispatch().sendMessage("<col=ff0000>Your pet has grown larger.</col>");
|
||||
int npcId = pet.getNpcId(newItemId);
|
||||
details.updateGrowth(-100.0);
|
||||
Pet newPet = new Pet(owner, details, newItemId, npcId);
|
||||
newPet.growthRate = growthRate;
|
||||
newPet.hasWarned = hasWarned;
|
||||
owner.getFamiliarManager().setFamiliar(newPet);
|
||||
owner.getFamiliarManager().spawnFamiliar();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -161,16 +155,6 @@ public final class Pet extends Familiar {
|
|||
return itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the itemId with the individual hashed in.
|
||||
* @return The itemIdHash.
|
||||
*/
|
||||
public int getItemIdHash() {
|
||||
Item item = new Item(itemId);
|
||||
item.setCharge(details.getIndividual());
|
||||
return item.getIdHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the details.
|
||||
* @return The details.
|
||||
|
|
@ -187,9 +171,36 @@ public final class Pet extends Familiar {
|
|||
return pet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hunger level.
|
||||
*/
|
||||
public double getHunger() {
|
||||
return details.getHunger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the growth level.
|
||||
*/
|
||||
public double getGrowth() {
|
||||
return details.getGrowth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hunger warning level.
|
||||
*/
|
||||
public int getHasWarned() {
|
||||
return hasWarned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hunger warning level.
|
||||
*/
|
||||
public void setHasWarned(int value) {
|
||||
this.hasWarned = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 761, 762, 763, 764, 765, 766, 3505, 3598, 6969, 7259, 7260, 6964, 7249, 7251, 6960, 7241, 7243, 6962, 7245, 7247, 6966, 7253, 7255, 6958, 7237, 7239, 6915, 7277, 7278, 7279, 7280, 7018, 7019, 7020, 6908, 7313, 7316, 6947, 7293, 7295, 7297, 7299, 6911, 7261, 7263, 7265, 7267, 7269, 6919, 7301, 7303, 7305, 7307, 6949, 6952, 6955, 6913, 7271, 7273, 6945, 7319, 7321, 7323, 7325, 7327, 6922, 6942, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 7224, 7226, 6900, 6902, 6904, 6906, 768, 769, 770, 771, 772, 773, 3504, 6968, 7257, 7258, 6965, 7250, 7252, 6961, 7242, 7244, 6963, 7246, 7248, 6967, 7254, 7256, 6859, 7238, 7240, 6916, 7281, 7282, 7283, 7284, 7015, 7016, 7017, 6909, 7314, 7317, 6948, 7294, 7296, 7298, 7300, 6912, 7262, 7264, 7266, 7268, 7270, 6920, 7302, 7304, 7306, 7308, 6950, 6953, 6956, 6914, 7272, 7274, 6946, 7320, 7322, 7324, 7326, 7328, 6923, 6943, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 6901, 6903, 6905, 6907, 774, 775, 776, 777, 778, 779, 3503, 6951, 6954, 6957 };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,6 @@ public final class PetDetails {
|
|||
*/
|
||||
private double growth = 0.0;
|
||||
|
||||
/**
|
||||
* The individual, an in principle arbitrary integer read off of the item's charge slot.
|
||||
*/
|
||||
private int individual;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PetDetails} {@code Object}.
|
||||
* @param growth The growth value.
|
||||
|
|
@ -64,6 +59,13 @@ public final class PetDetails {
|
|||
return hunger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hunger. (You probably want to use updateHunger() instead.)
|
||||
*/
|
||||
public void setHunger(double value) {
|
||||
this.hunger = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the growth.
|
||||
* @return The growth.
|
||||
|
|
@ -73,18 +75,9 @@ public final class PetDetails {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the individual.
|
||||
* @param individual The individual to set.
|
||||
* Sets the growth. (You probably want to use updateGrowth() instead.)
|
||||
*/
|
||||
public void setIndividual(int individual) {
|
||||
this.individual = individual;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the individual.
|
||||
* @return The individual.
|
||||
*/
|
||||
public int getIndividual() {
|
||||
return individual;
|
||||
public void setGrowth(double value) {
|
||||
this.growth = value;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,61 +180,6 @@ public enum Pets {
|
|||
*/
|
||||
BABY_DRAGON(12469, 12470, -1, 6900, 6901, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), BABY_DRAGON_1(12471, 12472, -1, 6902, 6903, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), BABY_DRAGON_2(12473, 12474, -1, 6904, 6905, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), BABY_DRAGON_3(12475, 12476, -1, 6906, 6907, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270);
|
||||
|
||||
|
||||
// /**
|
||||
// * Emperor's pets (that's right, MY pet"S").
|
||||
// */
|
||||
// GIANT_WOLPERTINGER(8888, -1, -1, 6990, -1, -1, 0.0, 99), DRAKAN(8889, -1, -1, 4794, -1, -1, 0.0, 99), DILL(8890, -1, -1, 7770, -1, -1, 0.0, 99),
|
||||
|
||||
// /**
|
||||
// * Vexias pet.
|
||||
// */
|
||||
// IMP(9952, -1, -1, 1531, -1, -1, 0.0, 99), BIG_GUY(9951, -1, -1, 3101, -1, -1, 0.0, 99), LITTLE_GUY(8887, -1, -1, 5805, -1, -1, 0.0, 99),
|
||||
//
|
||||
// /**
|
||||
// * Godwars boss pets.
|
||||
// */
|
||||
// KRIL_JR(14648, -1, -1, 8591, -1, -1, 0.0, 1), KREE_JR(14645, -1, -1, 8592, -1, -1, 0.0, 1), ZILYANA_JR(14647, -1, -1, 8593, -1, -1, 0.0, 1), GRAARDOOR_JR(14646, -1, -1, 8594, -1, -1, 0.0, 1),
|
||||
//
|
||||
// /**
|
||||
// * Classic boss pets.
|
||||
// */
|
||||
// CHAOS_ELE_JR(14638, -1, -1, 8595, -1, -1, 0.0, 1), PRINCE_BLACK_DRAGON(14649, -1, -1, 8596, -1, -1, 0.0, 1), BABY_MOLE(14642, -1, -1, 8601, -1, -1, 0.0, 1), KQ_FORM_1(14643, -1, -1, 8602, -1, -1, 0.0, 1), KQ_FORM_2(14650, -1, -1, 8603, -1, -1, 0.0, 1), DARK_CORE(14653, -1, -1, 8630, -1, -1, 0.0, 1),
|
||||
//
|
||||
// /**
|
||||
// * The boss pets for the Dagannoths
|
||||
// */
|
||||
// DAGANNOTH_SUPREME(14639, -1, -1, 8605, -1, -1, 0.0, 1), DAGANNOTH_PRIME(14640, -1, -1, 8606, -1, -1, 0.0, 1), DAGANNOTH_REX(14641, -1, -1, 8607, -1, -1, 0.0, 1),
|
||||
// /**
|
||||
// * The new OSRS bosses.
|
||||
// */
|
||||
// CALLISTO_CUB(14658, -1, -1, 8597, -1, -1, 0.0, 1),
|
||||
// SCORPIA_JR(14661, -1, -1, 8598, -1, -1, 0.0, 1),
|
||||
// VENENATIS_JR(14657, -1, -1, 8654, -1, -1, 0.0, 1),
|
||||
// VETION_JR(14659, -1, -1, 8600, -1, -1, 0.0, 1),
|
||||
// VETION_JR_2(14660, -1, -1, 8654, -1, -1, 0.0, 1),
|
||||
// RELEASE_THE_KRAKEN(14651, -1, -1, 8608, -1, -1, 0.0, 1),
|
||||
// SMOKE_DEVIL(14644, -1, -1, 8609, -1, -1, 0.0, 1),
|
||||
// SNAKELING_YELLOW(14654, -1, -1, 8626, -1, -1, 0.0, 1),
|
||||
// SNAKELING_ORANGE(14655, -1, -1, 8627, -1, -1, 0.0, 1),
|
||||
// SNAKELING_PURPLE(14656, -1, -1, 8628, -1, -1, 0.0, 1),
|
||||
// /**
|
||||
// * The boss pet representing the likeness of the Penance Queen
|
||||
// */
|
||||
// DRAMA_QUEEN(14652, -1, -1, 8604, -1, -1, 0.0, 1),
|
||||
// /**
|
||||
// * The skilling pets
|
||||
// */
|
||||
// BEAVER(14821, -1, -1, 8635, -1, -1, 0.0, 1),
|
||||
// ROCK_GOLEM(14822, -1, -1, 8637, -1, -1, 0.0, 1),
|
||||
// BABY_RED_CHINCHOMPA(14823, -1, -1, 8643, -1, -1, 0.0, 1),
|
||||
// BABY_GREY_CHINCHOMPA(14824, -1, -1, 8644, -1, -1, 0.0, 1),
|
||||
// BABY_BLACK_CHINCHOMPA(14825, -1, -1, 8657, -1, -1, 0.0, 1),
|
||||
// BABY_GOLD_CHINCHOMPA(14826, -1, -1, 8658, -1, -1, 0.0, 1),
|
||||
// HERON(14827, -1, -1, 8647, -1, -1, 0.0, 1),
|
||||
// TZREK_JAD(14828, -1, -1, 8650, -1, -1, 0.0, 1);
|
||||
|
||||
|
||||
/**
|
||||
* The baby pets mapping.
|
||||
*/
|
||||
|
|
@ -481,4 +426,4 @@ public enum Pets {
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class ServerConstants {
|
|||
var NOAUTH_DEFAULT_ADMIN: Boolean = true
|
||||
|
||||
@JvmField
|
||||
var CURRENT_SAVEFILE_VERSION = 1
|
||||
var CURRENT_SAVEFILE_VERSION = 2
|
||||
|
||||
@JvmField
|
||||
var DAILY_ACCOUNT_LIMIT = 3
|
||||
|
|
|
|||
|
|
@ -326,6 +326,7 @@ fun addItem(player: Player, id: Int, amount: Int = 1, container: Container = Con
|
|||
* @param player the player whose container to modify
|
||||
* @param slot the slot to use
|
||||
* @param item the item to replace the slot with
|
||||
* @param currentItem the current item that is being replaced
|
||||
* @param container the Container to modify
|
||||
* @return the item that was previously in the slot, or null if none.
|
||||
*/
|
||||
|
|
@ -358,6 +359,41 @@ fun replaceSlot(player: Player, slot: Int, item: Item, currentItem: Item? = null
|
|||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all items a player owns anywhere (equipment, inventory, bank, second bank)
|
||||
* @param player the player whose inventory to remove the item from
|
||||
* @param itemId the item ID to replace
|
||||
* @param replaceId the replacement item ID
|
||||
* @author Player Name
|
||||
*/
|
||||
fun replaceAllItems(player: Player, itemId: Int, replaceId: Int) {
|
||||
val item = Item(itemId)
|
||||
for (container in arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary)) {
|
||||
val hasItems = container.getAll(item)
|
||||
if (!item.definition.isStackable && (container == player.inventory || container == player.equipment)) {
|
||||
for (target in hasItems) {
|
||||
val newItem = Item(replaceId, target.amount)
|
||||
container.replace(newItem, target.slot, true)
|
||||
}
|
||||
} else {
|
||||
if (hasItems.size > 0) {
|
||||
val target = hasItems[0]
|
||||
var count = 0
|
||||
for (x in hasItems) {
|
||||
count += x.amount
|
||||
}
|
||||
val newItem = Item(replaceId, count)
|
||||
container.replace(newItem, target.slot, true)
|
||||
}
|
||||
if (hasItems.size > 1) {
|
||||
for (i in 1 until hasItems.size) {
|
||||
container.remove(hasItems[i], hasItems[i].slot, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item with a variable quantity or drop it if a player does not have enough space
|
||||
* @param player the player whose inventory to add to
|
||||
|
|
|
|||
|
|
@ -1,94 +0,0 @@
|
|||
package core.game.node.entity.npc;
|
||||
|
||||
import core.cache.def.impl.NPCDefinition;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import content.global.skill.summoning.familiar.Familiar;
|
||||
import content.global.skill.summoning.pet.Pets;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* A superclass plugin for any pets that have a metamorphosis option.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
public abstract class Metamorphosis extends OptionHandler {
|
||||
|
||||
/**
|
||||
* The ids of the possible npcs to metamorph into.
|
||||
*/
|
||||
protected int[] ids;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Metamorphosis} {@code Object}.
|
||||
* @param ids the id to transform.
|
||||
*/
|
||||
public Metamorphosis(int...ids) {
|
||||
this.ids = ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* The dialogue plugin for the pet.
|
||||
* @return the plugin.
|
||||
*/
|
||||
public abstract DialoguePlugin getDialoguePlugin();
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
for (int id : getIds()) {
|
||||
NPCDefinition.forId(id).getHandlers().put("option:metamorphosis", this);
|
||||
}
|
||||
if (getDialoguePlugin() != null) {
|
||||
ClassScanner.definePlugin(getDialoguePlugin());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
Familiar familiar = (Familiar) node;
|
||||
switch (option) {
|
||||
case "metamorphosis":
|
||||
if (player.getFamiliarManager().isOwner(familiar)) {
|
||||
int newNpc = player.getFamiliarManager().getFamiliar().getId();
|
||||
while (newNpc == player.getFamiliarManager().getFamiliar().getId()) {
|
||||
newNpc = getRandomNpcId();
|
||||
}
|
||||
for (Pets p : Pets.values()) {
|
||||
if (p.getBabyNpcId() == newNpc) {
|
||||
player.getFamiliarManager().morphPet(new Item(p.getBabyItemId()), false, player.getFamiliarManager().getFamiliar().getLocation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.getPacketDispatch().sendMessage("You transform your " + player.getFamiliarManager().getFamiliar().getName() + "!");
|
||||
} else {
|
||||
player.getPacketDispatch().sendMessage("This is not your familiar.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random npc id.
|
||||
* @return
|
||||
*/
|
||||
public int getRandomNpcId() {
|
||||
int i = RandomFunction.getRandom(getIds().length - 1);
|
||||
return getIds()[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the npc ids.
|
||||
* @return the id.
|
||||
*/
|
||||
public int[] getIds() {
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
|
|
@ -53,6 +53,7 @@ class PlayerSaveParser(val player: Player) {
|
|||
}
|
||||
|
||||
fun parseData() {
|
||||
parseVersion()
|
||||
parseCore()
|
||||
parseAttributes()
|
||||
parseSkills()
|
||||
|
|
@ -77,7 +78,6 @@ class PlayerSaveParser(val player: Player) {
|
|||
parseStatistics()
|
||||
parseAchievements()
|
||||
parsePouches()
|
||||
parseVersion()
|
||||
}
|
||||
|
||||
fun runContentHooks()
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class PlayerSaver (val player: Player){
|
|||
}
|
||||
fun populate(): JSONObject {
|
||||
val saveFile = JSONObject()
|
||||
saveVersion(saveFile)
|
||||
saveCoreData(saveFile)
|
||||
saveSkills(saveFile)
|
||||
saveSettings(saveFile)
|
||||
|
|
@ -56,7 +57,6 @@ class PlayerSaver (val player: Player){
|
|||
saveStatManager(saveFile)
|
||||
saveAttributes(saveFile)
|
||||
savePouches(saveFile)
|
||||
saveVersion(saveFile)
|
||||
contentHooks.forEach { it.savePlayer(player, saveFile) }
|
||||
return saveFile
|
||||
}
|
||||
|
|
@ -278,17 +278,21 @@ class PlayerSaver (val player: Player){
|
|||
|
||||
fun saveFamiliarManager(root: JSONObject){
|
||||
val familiarManager = JSONObject()
|
||||
val petDetails = JSONArray()
|
||||
val petDetails = JSONObject()
|
||||
player.familiarManager.petDetails.map {
|
||||
val detail = JSONObject()
|
||||
detail.put("petId",it.key.toString())
|
||||
detail.put("hunger",it.value.hunger.toString())
|
||||
detail.put("growth",it.value.growth.toString())
|
||||
petDetails.add(detail)
|
||||
val petId = it.key
|
||||
val petData = JSONArray()
|
||||
for (v in it.value) {
|
||||
val pet = JSONObject()
|
||||
pet.put("hunger",v.hunger.toString())
|
||||
pet.put("growth",v.growth.toString())
|
||||
petData.add(pet)
|
||||
}
|
||||
petDetails.put(petId.toString(), petData)
|
||||
}
|
||||
familiarManager.put("petDetails",petDetails)
|
||||
if(player.familiarManager.hasPet()){
|
||||
familiarManager.put("currentPet",(player.familiarManager.familiar as Pet).getItemIdHash().toString())
|
||||
familiarManager.put("currentPet",(player.familiarManager.familiar as Pet).getItemId().toString())
|
||||
} else if (player.familiarManager.hasFamiliar()){
|
||||
val familiar = JSONObject()
|
||||
familiar.put("originalId",player.familiarManager.familiar.originalId.toString())
|
||||
|
|
|
|||
|
|
@ -1,25 +1,22 @@
|
|||
package core.game.node.entity.player.info.login
|
||||
|
||||
import content.global.skill.summoning.pet.Pets
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
|
||||
|
||||
/**
|
||||
* Runs one-time save-version-related hooks.
|
||||
* @author Player Name
|
||||
*/
|
||||
|
||||
class SaveVersionHooks : LoginListener {
|
||||
|
||||
override fun login(player: Player) {
|
||||
if (player.version < ServerConstants.CURRENT_SAVEFILE_VERSION) {
|
||||
sendMessage(player, "<col=CC6600>Migrating save file version ${player.version} to current save file version ${ServerConstants.CURRENT_SAVEFILE_VERSION}.</col>")
|
||||
|
||||
// Perform actual migrations
|
||||
if (player.version < 1) { // GL #1811
|
||||
if (player.version < 1) { // GL !1811
|
||||
// Give out crafting hoods if the player bought any crafting capes when the hoods were not obtainable
|
||||
var hasHoods = 0
|
||||
var hasCapes = 0
|
||||
|
|
@ -60,10 +57,18 @@ class SaveVersionHooks : LoginListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Finish up
|
||||
if (player.version < 2) { //GL !1799
|
||||
// Most of the migration for this MR happens in FamiliarManager.java, but we fix up any pet items here
|
||||
val pets = Pets.values()
|
||||
for (pet in pets) {
|
||||
for (id in arrayOf(pet.babyItemId, pet.grownItemId, pet.overgrownItemId)) {
|
||||
replaceAllItems(player, id, id)
|
||||
// The trick here is that replaceAllItems ignores the item charge value, and will hence cause it to be lost, making all pets authentically stack again
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player.version = ServerConstants.CURRENT_SAVEFILE_VERSION
|
||||
sendMessage(player, "<col=CC6600>Save file migration complete. Happy scaping!</col>")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,14 +196,6 @@ public class Item extends Node{
|
|||
return idHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the id hash.
|
||||
* @param hash the hash to set
|
||||
*/
|
||||
public void setIdHash(int hash) {
|
||||
this.idHash = hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the item has a wrapper plugin.
|
||||
* @return {@code True} if so.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue