Makar
Members-
Posts
25 -
Joined
-
Last visited
About Makar
- Birthday 02/20/1995
Personal Information
-
Sex
Male
Social Media
-
Youtube
https://youtube.com
- Homepage
-
Everything is open source eventually in RSPS it seems.
-
Absolutely wild.
-
Very nice thank you. Been looking for animation information.
-
Thanks, don't even know what this is but hey, we'll check it out.
-
Thank you for sharing. Will look through it.
- 385 replies
-
- runite
- osfatality
-
(and 3 more)
Tagged with:
-
Very nice.
-
For anyone developing 727 revision, I have managed to refactor almost all of the packets from going client->server and server->client. I would gladly accept any help with refactoring this as it has been a very fun project so far. I know that the index 36 packets have something to do with vorbis and those are the only packets I'm not too sure of. Client->Server Client Packets Server->Client Server Packets Also some eye opening information as to how frameworks like Matrix do not utilize all the bandwidth saving and efficient "update zone" packets. Every single framework I have seen so far only utilizes the packets jagex calls "specific" packets where it sends the entire tile for things such as ground items, spotanims, projectiles, etc. The way these packets should be utilized is as follow for maximum bandwidth and data efficiency: organize all tile-based update events that utilize the "update zone" system (spotanim/projectile/objects/ground items/etc) for each tile that needs updated send update zone packet for each update event that is on that tile send update zone version of packet for that event This means that instead of sending the tile and item for a giant ass pile of items on the floor, you send the coordinates once, then send every item that should be on that tile, only sending a new location when there are items on another tile. Same goes for projectiles, objects, and spotanims. Update Zone Packets Update Zone Packets As for projectiles, I noticed they have a couple more useful flags that can be set that I have not seen utilized in any frameworks yet as well, such as being able to make them follow terrain height rather than a predefined height, etc. Anyone who wants to help figure out the rest or has any information regarding some of the unidentified few that are left, let me know please. Or any corrections/advice are greatly appreciated.
-
Never seen full ale brewing before so here's mine. It's as accurate to real RS as information provides regarding spoiling and maturing rates and setting success rates. Brewable package com.rs.game.player.content.skills.cooking; import java.util.HashMap; import java.util.Map; public enum Brewable { KELDA_STOUT(new int[] { 6118, 6118 }, null, 17, 6113, 1, 1), DWARVEN_STOUT(new int[] { 1913, 5747 }, new int[] { 5777, 5857 }, 19, 5994, 4, 215), ASGARNIAN_ALE(new int[] { 1905, 5739 }, new int[] { 5785, 5865 }, 24, 5996, 4, 248), GREENMANS_ALE(new int[] { 1909, 5743 }, new int[] { 5793, 5873 }, 29, 255, 4, 281), WIZARD_MIND_BOMB(new int[] { 1907, 5741 }, new int[] { 5801, 5881 }, 34, 5998, 4, 314), DRAGON_BITTER(new int[] { 1911, 5745 }, new int[] { 5809, 5889 }, 39, 6000, 4, 347), MOONLIGHT_MEAD(new int[] { 5763, 5749 }, new int[] { 5817, 5897 }, 44, 6004, 4, 380), AXEMANS_FOLLY(new int[] { 5751, 5753 }, new int[] { 5825, 5905 }, 49, 6043, 1, 413), CHEFS_DELIGHT(new int[] { 5755, 5757 }, new int[] { 5833, 5913 }, 54, 1975, 4, 446), SLAYERS_RESPITE(new int[] { 5759, 5761 }, new int[] { 5841, 5921 }, 59, 6002, 4, 479), CIDER(new int[] { 5763, 5765 }, new int[] { 5849, 5929 }, 14, 5992, 4, 182); private int[] beerGlassId; private int[] calquatId; private int levelRequirement; private int ingredient; private int ingredientAmount; private int xp; private static Map<Integer, Brewable> MAP = new HashMap<Integer, Brewable>(); public static Brewable forId(int itemId) { return MAP.get(itemId); } static { for (final Brewable brewable : Brewable.values()) { MAP.put(brewable.ingredient, brewable); } } private Brewable(int[] beerGlassId, int[] calquatId, int levelRequirement, int ingredient, int ingredientAmount, int xp) { this.beerGlassId = beerGlassId; this.calquatId = calquatId; this.levelRequirement = levelRequirement; this.ingredient = ingredient; this.ingredientAmount = ingredientAmount; this.xp = xp; } public int getLevelRequirement() { return levelRequirement; } public int getBeerGlassId(boolean mature) { return beerGlassId[mature ? 1 : 0]; } public int getCalquatId(boolean mature) { return calquatId[mature ? 1 : 0]; } public int getIngredient() { return ingredient; } public int getIngredientAmount() { return ingredientAmount; } public int getXp() { return xp; } public int getVatVal(int stage) { if (this == KELDA_STOUT) return 68 + stage; return (ordinal() * 6) + 4 + stage; } public int getBarrelVal(boolean mature) { if (this == KELDA_STOUT) return 3; return (ordinal() * ? + (mature ? 128 : 0); } } Brewery package com.rs.game.player.content.skills.cooking; import com.rs.game.Animation; import com.rs.game.player.Player; import com.rs.game.player.Skills; import com.rs.plugin.PluginEventHandler; import com.rs.plugin.events.ItemOnObjectEvent; import com.rs.plugin.events.LoginEvent; import com.rs.plugin.events.ObjectClickEvent; import com.rs.plugin.methods.ItemOnObjectHandler; import com.rs.plugin.methods.ObjectClickHandler; import com.rs.utils.Utils; @PluginEventHandler public class Brewery { private static final int BUCKET_OF_WATER = 1929; private static final int BARLEY_MALT = 6008; private static final int ALE_YEAST = 5767; private static final int EMPTY_BUCKET = 1925; private static final int THE_STUFF = 8988; private static final int BEER_GLASS = 1919; private static final int CALQUAT_KEG = 5769; private static final Animation ADD_INGREDIENT = new Animation(2292); private static final Animation POUR_WATER = new Animation(2283); private static final Animation CALQUAT_LEVEL = new Animation(2284); private static final Animation BEER_GLASS_LEVEL = new Animation(2285); private static final long BREWING_CONSTANT = 12 * 60 * 60 * 1000; //12 hours private Brewable brew; private int prep; private int fermentStage; private long lastTime; private boolean barrelled; private boolean theStuff; private boolean spoiled; private boolean mature; private boolean keldagrim; private transient Player player; public Brewery(boolean keldagrim) { this.keldagrim = keldagrim; } public void setPlayer(Player player) { this.player = player; } public static boolean onLogin(LoginEvent e) { e.getPlayer().getKeldagrimBrewery().updateVars(); e.getPlayer().getPhasmatysBrewery().updateVars(); return false; } @ObjectClickHandler(ids = { 7442, 7443 }) public static void handleValve(ObjectClickEvent e) { Brewery brewery = e.getObjectId() == 7442 ? e.getPlayer().getKeldagrimBrewery() : e.getPlayer().getPhasmatysBrewery(); brewery.turnValve(); } @ObjectClickHandler(ids = { 7431, 7432 }) public static void handleBarrels(ObjectClickEvent e) { Brewery brewery = e.getObjectId() == 7431 ? e.getPlayer().getKeldagrimBrewery() : e.getPlayer().getPhasmatysBrewery(); switch(e.getOption()) { case "Drain": brewery.reset(); e.getPlayer().sendMessage("You drain the spoiled drink from the vat."); break; case "Level": brewery.level(); break; } } @ItemOnObjectHandler(ids = { 7494, 7495 }) public static void handleVats(ItemOnObjectEvent e) { Brewery brewery = e.getObjectId() == 7494 ? e.getPlayer().getKeldagrimBrewery() : e.getPlayer().getPhasmatysBrewery(); switch(e.getItem().getId()) { case BUCKET_OF_WATER: brewery.addWater(); break; case BARLEY_MALT: brewery.addMalt(); break; case ALE_YEAST: brewery.addYeast(); break; case THE_STUFF: brewery.addTheStuff(); break; default: brewery.addSecondary(e.getItem().getId()); break; } brewery.updateVars(); } public void ferment() { if (isFinished()) return; if (Utils.random(80 + player.getSkills().getLevel(Skills.COOKING)) == 0) spoiled = true; if (Utils.random(5) == 0) fermentStage = Utils.clampI(fermentStage+1, 0, 4); if (Utils.random(200) == 0) fermentStage = 4; } public void process() { if (lastTime <= 0) return; long currTime = System.currentTimeMillis(); long timePassed = currTime - lastTime; if (timePassed > BREWING_CONSTANT) { int cycles = (int) (timePassed / BREWING_CONSTANT); for (int i = 0;i < cycles;i++) ferment(); lastTime = currTime - (timePassed % (cycles * BREWING_CONSTANT)); } updateVars(); } public void addWater() { if (prep != 0) return; if (player.getInventory().containsItem(BUCKET_OF_WATER, 2)) { player.setNextAnimation(POUR_WATER); player.getInventory().deleteItem(BUCKET_OF_WATER, 2); player.getInventory().addItem(EMPTY_BUCKET, 2); prep = 1; } else { player.sendMessage("You need 2 buckets of water to add to the brew."); } } public void addMalt() { if (prep != 1) { player.sendMessage("Add water first, then malt, then ale yeast."); return; } if (player.getInventory().containsItem(BARLEY_MALT, 2)) { player.setNextAnimation(ADD_INGREDIENT); player.getInventory().deleteItem(BARLEY_MALT, 2); prep = 2; } else { player.sendMessage("You need two barley malts to add to the brew."); } } public void addSecondary(int itemId) { Brewable brew = Brewable.forId(itemId); if (brew != null) { if (player.getSkills().getLevel(Skills.COOKING) < brew.getLevelRequirement()) { player.sendMessage("You need a cooking level of " + brew.getLevelRequirement() + " to create that brew."); return; } if (prep == 2) { if (player.getInventory().containsItem(brew.getIngredient(), brew.getIngredientAmount())) { player.getInventory().deleteItem(brew.getIngredient(), brew.getIngredientAmount()); player.setNextAnimation(ADD_INGREDIENT); this.brew = brew; } else { player.sendMessage("You need " + brew.getIngredientAmount() + " to create that brew."); } } else { player.sendMessage("You need to have added water and barley malt before adding the ale's ingredients."); } } else { player.sendMessage("Nothing interesting happens."); } } public void addYeast() { if (prep != 2 || brew == null || !player.getInventory().containsItem(ALE_YEAST, 1)) { player.sendMessage("The brew isn't ready for the yeast yet."); return; } if (lastTime >= 1) { player.sendMessage("The brew is already fermenting."); return; } player.setNextAnimation(ADD_INGREDIENT); player.getInventory().deleteItem(ALE_YEAST, 1); lastTime = System.currentTimeMillis(); player.sendMessage("The brew begins to ferment."); } public void addTheStuff() { if (prep != 2 || !player.getInventory().containsItem(THE_STUFF, 1)) { player.sendMessage("Add water first, then malt, and the ale's ingredients before adding \"the stuff\"."); return; } if (theStuff) { player.sendMessage("You've already added \"the stuff\" to this batch."); return; } player.setNextAnimation(ADD_INGREDIENT); player.getInventory().deleteItem(THE_STUFF, 1); theStuff = true; } public void turnValve() { if (isFinished() && !barrelled) { barrelled = true; if (Utils.random(100) <= (theStuff ? 75 : 10)) mature = true; updateVars(); } else { player.sendMessage("The brew isn't done fermenting yet."); } } public void level() { if (brew == Brewable.KELDA_STOUT) { if (player.getInventory().containsItem(BEER_GLASS, 1)) { player.getInventory().deleteItem(BEER_GLASS, 1); player.getInventory().addItem(brew.getBeerGlassId(mature), 1); player.setNextAnimation(BEER_GLASS_LEVEL); reset(); } else { player.sendMessage("You need a beer glass to empty the stout into."); } return; } int container = -1; if (player.getInventory().containsItem(BEER_GLASS, 8)) container = BEER_GLASS; if (player.getInventory().containsItem(CALQUAT_KEG, 2)) container = CALQUAT_KEG; if (container == -1) { player.sendMessage("You need 8 beer glasses or 2 calquat kegs to empty this vat."); return; } player.incrementCount(brew.name() + " brewed"); if (mature) player.incrementCount("Mature " + brew.name() + " brewed"); player.getInventory().deleteItem(container, container == BEER_GLASS ? 8 : 2); player.getInventory().addItem(container == BEER_GLASS ? brew.getBeerGlassId(mature) : brew.getCalquatId(mature), container == BEER_GLASS ? 8 : 2); player.getSkills().addXp(Skills.COOKING, brew.getXp()*8); player.setNextAnimation(container == BEER_GLASS ? BEER_GLASS_LEVEL : CALQUAT_LEVEL); reset(); } public void reset() { this.brew = null; this.prep = 0; this.theStuff = false; this.spoiled = false; this.mature = false; this.barrelled = false; this.fermentStage = 0; this.lastTime = -1; updateVars(); } public boolean isFinished() { return brew != null && (spoiled || fermentStage >= 4 || (brew == Brewable.KELDA_STOUT && fermentStage >= 3)); } public void updateVars() { if (brew == null) { setBarrel(0); setVat(Utils.clampI(prep, 0, 2)); return; } if (isFinished()) { if (spoiled) { setBarrel(barrelled ? 1 : 0); setVat(barrelled ? 0 : 64); } else { setVat(barrelled ? 0 : brew.getVatVal(fermentStage)); setBarrel(barrelled ? brew.getBarrelVal(mature) : 0); } } else { setVat(brew.getVatVal(fermentStage)); } } private void setVat(int value) { player.getVars().setVarBit(keldagrim ? 736 : 737, value); } private void setBarrel(int value) { player.getVars().setVarBit(keldagrim ? 738 : 739, value); } } in Player class private Brewery keldagrimBrewery; private Brewery phasmatysBrewery; public Brewery getKeldagrimBrewery() { if (keldagrimBrewery == null) keldagrimBrewery = new Brewery(true); keldagrimBrewery.setPlayer(this); return keldagrimBrewery; } public Brewery getPhasmatysBrewery() { if (phasmatysBrewery == null) phasmatysBrewery = new Brewery(false); phasmatysBrewery.setPlayer(this); return phasmatysBrewery; }
-
Now I'm sure tons of you have seen ganodermic beasts, new chickens, and grotworms sliding around in a T-Pose when they should be animating while walking. I am sure some of you have seen this wonky hardcode fix going around (this example is from Matrix 3's polypore npc code) @Override public void processMovement() { super.processMovement(); if (realId == 14696 && getNextWalkDirection() != -1) { this.setNextAnimation(new Animation(15465)); this.setNextForceMovement(new NewForceMovement(this, 1, null, 0, Utils.getAngle(Utils.DIRECTION_DELTA_X[getNextWalkDirection()], Utils.DIRECTION_DELTA_Y[getNextWalkDirection()]))); } } Basically forcing a movement animation using forcemovement. Well the render animation definitions of the monster hold animations for a third movement type. Not walking, not running.It seems to be used for monsters that move either half speed of normal monsters, or monsters that move 2 squares in one direction at a time such as ganodermic beasts. The correct way to trigger this animation to be used directly from the render animation of the npc is to just have an exception inside where it updates an npc to be "running". As you can see in the client code here where the client determines which render animation to use, there is a "teleport" animation type. I only call it teleport because it's the same movement type id that players use in player update as a teleport movement. Should probably rename it to SPECIAL or something instead. Here is where the client determines if the NPC uses this specific type of movement so you can update your NPC update methods accordingly: NPCUpdate.java If you're using Matrix's crazy ass control flow for NPC updating, here's where you'd make the change: if (n.getNextRunDirection() == -1) { if (n.getDefinitions().walksSpecial()) { stream.writeBits(2, 2); stream.writeBits(1, 0); stream.writeBits(3, Utils.getNpcMoveDirection(n.getNextWalkDirection())); } else { stream.writeBits(2, 1); stream.writeBits(3, Utils.getNpcMoveDirection(n.getNextWalkDirection())); } } else { stream.writeBits(2, 2); stream.writeBits(1, 1); stream.writeBits(3, Utils.getNpcMoveDirection(n.getNextWalkDirection())); stream.writeBits(3, Utils.getNpcMoveDirection(n.getNextRunDirection())); }
-
Gimme gimme
- 140 replies
-
- nightmare-scape
- release
-
(and 1 more)
Tagged with:
-
Plan on using this site as an "untrustworthy, money hungry, salty assholes in the RSPS community" database. Thanks for providing this resource to the public. It's a real goldmine.