Not really going into much detail about this one
If i've missed anything just lemme know below.
Credits where due to Flub
Please note that this is not an advanced version of Flubs
You're also going to want to go into your packetsender and under everything
Code:
if (player.isMiniMe)
return this;
World.java under savePlayers method add
Code:
players.forEach(MiniMeData::save);
CombatBuilder under the method attack add
Code:
if (victim instanceof Player) { //If you attack a mini me, you will attack the owner
Player attackedBot = (Player) victim;
if (attackedBot.isMiniMe) {
if (attackedBot.getMinimeOwner() != null) {
if (World.getPlayers().contains(attackedBot.getMinimeOwner())) {
victim = attackedBot.getMinimeOwner();
character.setPositionToFace(victim.getPosition());
}
}
}
}
Code:
/** Mini me commands **/
if (wholeCommand.equalsIgnoreCase("minime")) {
if (player.getMinime() != null) {
player.getMinime().flagBotRemoval();
} else {
MiniMeFunctions.create(player);
player.getPacketSender().sendMessage("You Summon Your Minime!");
}
}
if (command[0].equalsIgnoreCase("minime") && wholeCommand.length() > command[0].length()) {
// Handle other commands
switch (command[1]) {
case "follow":
MiniMeFunctions.startFollowing(player);
break;
case "unfollow":
case "stopfollow":
MiniMeFunctions.stopFollowing(player);
break;
case "save":
MiniMeData.save(player.getMinime());
break;
}
}
Code:
public void attack(Character target) {
// Make sure we aren't attacking ourself.
if (character.equals(target)) {
return;
}
if (victim instanceof Player) { //If you attack a mini me, you will attack the owner
Player attackedBot = (Player) victim;
if (attackedBot.isMiniMe) {
if (attackedBot.getMinimeOwner() != null) {
if (World.getPlayers().contains(attackedBot.getMinimeOwner())) {
victim = attackedBot.getMinimeOwner();
character.setPositionToFace(victim.getPosition());
}
}
}
}
if (target.equals(victim)) {
determineStrategy();
if (!character.getPosition().equals(victim.getPosition()) && character.getPosition().isWithinDistance(victim.getPosition(), strategy.attackDistance(character))) {
character.getMovementQueue().reset();
}
}
Code:
package com.zamron.world.content.minimes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.zamron.GameServer;
import com.zamron.model.*;
import com.zamron.util.Misc;
import com.zamron.world.content.combat.magic.CombatSpells;
import com.zamron.world.content.combat.weapon.FightType;
import com.zamron.world.content.skill.SkillManager;
import com.zamron.world.content.skill.impl.slayer.SlayerMaster;
import com.zamron.world.content.skill.impl.slayer.SlayerTasks;
import com.zamron.world.entity.impl.player.Player;
import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
public class MiniMeData {
public static void save(Player player) {
if (!player.isMiniMe)
return;
Player owner = player.getMinimeOwner();
// Create the path and file objects.
Path path = Paths.get("./data/saves/minimes/", player.getUsername() + ".json");
File file = path.toFile();
file.getParentFile().setWritable(true);
// Attempt to make the player save directory if it doesn't
// exist.
if (!file.getParentFile().exists()) {
try {
file.getParentFile().mkdirs();
} catch (SecurityException e) {
//System.out.println("Unable to create directory for player data!");
}
}
try (FileWriter writer = new FileWriter(file)) {
Gson builder = new GsonBuilder().setPrettyPrinting().create();
JsonObject object = new JsonObject();
object.addProperty("total-play-time-ms", owner.getTotalPlayTime());
object.add("position", builder.toJsonTree(player.getPosition()));
object.addProperty("money-pouch", new Long(player.getMoneyInPouch()));
object.addProperty("gender", player.getAppearance().getGender().name());
object.addProperty("spell-book", player.getSpellbook().name());
object.addProperty("prayer-book", player.getPrayerbook().name());
object.addProperty("running", new Boolean(player.isRunning()));
object.addProperty("run-energy", new Integer(owner.getRunEnergy()));
object.addProperty("auto-retaliate", new Boolean(owner.isAutoRetaliate()));
object.addProperty("xp-locked", new Boolean(owner.experienceLocked()));
object.addProperty("veng-cast", new Boolean(player.hasVengeance()));
object.addProperty("last-veng", new Long(player.getLastVengeance().elapsed()));
object.addProperty("fight-type", player.getFightType().name());
object.addProperty("accept-aid", new Boolean(owner.isAcceptAid()));
object.addProperty("poison-damage", new Integer(player.getPoisonDamage()));
object.addProperty("poison-immunity", new Integer(player.getPoisonImmunity()));
object.addProperty("overload-timer", new Integer(player.getOverloadPotionTimer()));
object.addProperty("fire-immunity", new Integer(player.getFireImmunity()));
object.addProperty("fire-damage-mod", new Integer(player.getFireDamageModifier()));
object.addProperty("prayer-renewal-timer", new Integer(player.getPrayerRenewalPotionTimer()));
object.addProperty("teleblock-timer", new Integer(player.getTeleblockTimer()));
object.addProperty("special-amount", new Integer(player.getSpecialPercentage()));
object.addProperty("autocast", new Boolean(player.isAutocast()));
object.addProperty("autocast-spell",
owner.getAutocastSpell() != null ? player.getAutocastSpell().spellId() : -1);
object.add("appearance", builder.toJsonTree(player.getAppearance().getLook()));
object.add("skills", builder.toJsonTree(player.getSkillManager().getSkills()));
object.add("inventory", builder.toJsonTree(player.getInventory().getItems()));
object.add("equipment", builder.toJsonTree(player.getEquipment().getItems()));
writer.write(builder.toJson(object));
} catch (Exception e) {
// An error happened while saving.
GameServer.getLogger().log(Level.WARNING, "An error has occured while saving a minime file!", e);
}
}
public static void load(Player player) {
if (!player.isMiniMe)
return;
Player owner = player.getMinimeOwner();
// Create the path and file objects.
Path path = Paths.get("./data/saves/minimes/", player.getUsername() + ".json");
File file = path.toFile();
// If the file doesn't exist, we're logging in for the first
// time and can skip all of this.
if (!file.exists()) {
return;
}
// Now read the properties from the json parser.
try (FileReader fileReader = new FileReader(file)) {
JsonParser fileParser = new JsonParser();
Gson builder = new GsonBuilder().create();
JsonObject reader = (JsonObject) fileParser.parse(fileReader);
if (reader.has("total-play-time-ms")) {
player.setTotalPlayTime(reader.get("total-play-time-ms").getAsLong());
}
if (reader.has("staff-rights")) {
player.setRights(PlayerRights.valueOf(reader.get("staff-rights").getAsString()));
}
if (reader.has("secondary-rights")) {
player.setSecondaryPlayerRights(SecondaryPlayerRights.valueOf(reader.get("secondary-rights").getAsString()));
}
player.setGameMode(GameMode.valueOf(owner.getGameMode().toString()));
if (reader.has("position")) {
player.getPosition().setAs(builder.fromJson(reader.get("position"), Position.class));
}
if (reader.has("money-pouch")) {
player.setMoneyInPouch(reader.get("money-pouch").getAsLong());
}
if (reader.has("gender")) {
player.getAppearance().setGender(Gender.valueOf(reader.get("gender").getAsString()));
}
if (reader.has("spell-book")) {
player.setSpellbook(MagicSpellbook.valueOf(reader.get("spell-book").getAsString()));
}
if (reader.has("prayer-book")) {
player.setPrayerbook(Prayerbook.valueOf(reader.get("prayer-book").getAsString()));
}
if (reader.has("running")) {
player.setRunning(reader.get("running").getAsBoolean());
}
if (reader.has("run-energy")) {
player.setRunEnergy(reader.get("run-energy").getAsInt());
}
if (reader.has("auto-retaliate")) {
player.setAutoRetaliate(reader.get("auto-retaliate").getAsBoolean());
}
if (reader.has("xp-locked")) {
player.setExperienceLocked(reader.get("xp-locked").getAsBoolean());
}
if (reader.has("veng-cast")) {
player.setHasVengeance(reader.get("veng-cast").getAsBoolean());
}
if (reader.has("last-veng")) {
player.getLastVengeance().reset(reader.get("last-veng").getAsLong());
}
if (reader.has("fight-type")) {
player.setFightType(FightType.valueOf(reader.get("fight-type").getAsString()));
}
if (reader.has("accept-aid")) {
player.setAcceptAid(reader.get("accept-aid").getAsBoolean());
}
if (reader.has("poison-damage")) {
player.setPoisonDamage(reader.get("poison-damage").getAsInt());
}
if (reader.has("poison-immunity")) {
player.setPoisonImmunity(reader.get("poison-immunity").getAsInt());
}
if (reader.has("overload-timer")) {
player.setOverloadPotionTimer(reader.get("overload-timer").getAsInt());
}
if (reader.has("fire-immunity")) {
player.setFireImmunity(reader.get("fire-immunity").getAsInt());
}
if (reader.has("fire-damage-mod")) {
player.setFireDamageModifier(reader.get("fire-damage-mod").getAsInt());
}
if (reader.has("overload-timer")) {
player.setOverloadPotionTimer(reader.get("overload-timer").getAsInt());
}
if (reader.has("prayer-renewal-timer")) {
player.setPrayerRenewalPotionTimer(reader.get("prayer-renewal-timer").getAsInt());
}
if (reader.has("teleblock-timer")) {
player.setTeleblockTimer(reader.get("teleblock-timer").getAsInt());
}
if (reader.has("special-amount")) {
player.setSpecialPercentage(reader.get("special-amount").getAsInt());
}
if (reader.has("autocast")) {
player.setAutocast(reader.get("autocast").getAsBoolean());
}
if (reader.has("autocast-spell")) {
int spell = reader.get("autocast-spell").getAsInt();
if (spell != -1)
player.setAutocastSpell(CombatSpells.getSpell(spell));
}
player.getSlayer().setSlayerMaster(SlayerMaster.valueOf(owner.getSlayer().getSlayerMaster().name()));
player.getSlayer().setSlayerTask(SlayerTasks.valueOf(owner.getSlayer().getSlayerTask().name()));
player.getSlayer().setAmountToSlay(owner.getSlayer().getAmountToSlay());
player.getSlayer().setTaskStreak(owner.getSlayer().getTaskStreak());
if (reader.has("appearance")) {
player.getAppearance().set(builder.fromJson(reader.get("appearance").getAsJsonArray(), int[].class));
}
if (reader.has("skills")) {
player.getSkillManager().setSkills(builder.fromJson(reader.get("skills"), SkillManager.Skills.class));
}
if (reader.has("inventory")) {
player.getInventory()
.setItems(builder.fromJson(reader.get("inventory").getAsJsonArray(), Item[].class));
}
if (reader.has("equipment")) {
player.getEquipment()
.setItems(builder.fromJson(reader.get("equipment").getAsJsonArray(), Item[].class));
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static boolean miniMeExists(String p) {
p = Misc.formatPlayerName(p.toLowerCase());
return new File("./data/saves/minimes/" + p + ".json").exists();
}
}
Code:
package com.zamron.world.content.minimes;
import com.zamron.engine.task.Task;
import com.zamron.engine.task.TaskManager;
import com.zamron.model.*;
import com.zamron.model.container.impl.Equipment;
import com.zamron.model.definitions.ItemDefinition;
import com.zamron.model.definitions.WeaponAnimations;
import com.zamron.util.NameUtils;
import com.zamron.world.World;
import com.zamron.world.entity.impl.npc.NPC;
import com.zamron.world.entity.impl.player.Player;
public class MiniMeFunctions {
public static void create(Player owner) {
Player shadow = new Player(null).setUsername("Mini " + owner.getUsername() + "!");
if (owner.getMinime() != null) {
owner.sendMessage("@red@You call your mini-me!");
MiniMeFunctions.startFollowing(owner);
return;
}
shadow.moveTo(owner.getPosition());
shadow.setLongUsername(NameUtils.stringToLong(shadow.getUsername()));
shadow.isMiniMe = true;
shadow.minimeOwner = owner;
owner.setMinime(shadow);
World.register(shadow);
shadow.getSkillManager().setSkills(owner.getSkillManager().getSkills());
owner.sendMessage("@blu@You call your mini-me!");
shadow.getMovementQueue().setFollowCharacter(owner);
CharacterAnimations originalPlayer = owner.getCharacterAnimations().clone(); // Makes it possible to store animations from the owner of the bot.
Player MiniMe = owner.getMinime();
MiniMeData.load(MiniMe);
MiniMe.getEquipment().setItems(owner.getEquipment().getItems());
MiniMe.setWeapon(owner.getWeapon());
MiniMe.getUpdateFlag().flag(Flag.APPEARANCE);
TaskManager.submit(new Task(1, owner.getMinime(), false) {
@Override
public void execute() {
MiniMe.setCharacterAnimations(originalPlayer); //Fix shit animation
if (owner.getCombatBuilder().isAttacking() || owner.getCombatBuilder().isBeingAttacked()) {
if (owner.getCombatBuilder().isAttacking()) {
MiniMe.getMovementQueue().setFollowCharacter(null);
MiniMe.setPositionToFace(owner.getCombatBuilder().getVictim().getPosition());
MiniMe.getCombatBuilder().attack(owner.getCombatBuilder().getVictim());
}
} else {
if (MiniMe.getCombatBuilder().isAttacking())
MiniMe.getCombatBuilder().reset(true);
/*if (MiniMe.getMovementQueue().getFollowCharacter() != owner)
MiniMe.getMovementQueue().setFollowCharacter(owner);*/
}
if (!MiniMe.getLocalPlayers().contains(owner)) {
MiniMe.moveTo(owner.getPosition());
MiniMe.getMovementQueue().setFollowCharacter(owner);
}
if (MiniMe.checkPendingBotRemoval()) {
World.deregister(MiniMe);
owner.setMinime(null);
MiniMe.getMinimeOwner().sendMessage("@blu@Your mini-me vanishes.");
stop();
return;
}
if (!World.getPlayers().contains(owner) && World.getPlayers().contains(MiniMe)) {
World.deregister(MiniMe);
//System.out.println("stopped");
stop();
}
}
});
}
public static void startFollowing(Player owner) {
if (owner.getMinime() == null) {
owner.sendMessage("You need to summon your mini me first.");
return;
}
if (owner.getMinime().getMovementQueue().getFollowCharacter() == owner) {
owner.sendMessage("Your minime is already following you.");
return;
}
owner.getMinime().moveTo(owner.getPosition());
owner.sendMessage("Your minime begins to follow you.");
owner.getMinime().getMovementQueue().setFollowCharacter(owner);
}
public static void stopFollowing(Player owner) {
if (owner.getMinime() == null) {
owner.sendMessage("You need to summon your mini me first.");
return;
}
owner.getMinime().getMovementQueue().setFollowCharacter(null);
owner.getMinime().setEntityInteraction(null);
owner.getMinime().getMovementQueue().reset();
owner.sendMessage("Your minime stops following you.");
}
}