Thread: [Apollo] PositionEvent - GroundItem

Results 1 to 10 of 10
  1. #1 [Apollo] PositionEvent - GroundItem 
    Registered Member derpscape's Avatar
    Join Date
    Jul 2011
    Posts
    212
    Thanks given
    37
    Thanks received
    20
    Rep Power
    43
    After failing for way too long, I have decided to ask for help on this. This is super easy, I just fail at java.

    The problem is can't find out how to write these 4 lines in GroundItem.java to work with my new PositionEvent.java.

    The error is obvious, I am not calling it properly. It wants "position Position" and I only have "position" which is getPosition() *I think*

    I have tried getPosition(), .getBase and I can't get it to compile. Maybe I am going about it wrong. Anyways, here are the class files and the errors.


    Spoiler for CMD console errors:




    Spoiler for PositionEvent.java:
    [/code]
    package org.apollo.game.event.impl;

    import org.apollo.game.event.Event;
    import org.apollo.game.model.Position;

    /**
    * An {@link Event} which tells the client to focus on a specific {@link Position} (on which an action should
    * be performed).
    * @author Chris Fletcher
    */
    public final class PositionEvent extends Event {

    /**
    * The base position.
    */
    private final Position base;

    /**
    * The target position.
    */
    private final Position position;

    /**
    * Creates a new focus position event.
    * @param base The base from which the position is being focused on.
    * @param position The position to focus on.
    */
    public PositionEvent(Position base, Position position) {
    this.base = base;
    this.position = position;
    }

    /**
    * Gets the base position.
    * @return The position.
    */
    public Position getBase() {
    return base;
    }

    /**
    * Gets the position to focus on.
    * @return The target position.
    */
    public Position getPosition() {
    return position;
    }

    }
    [/code]


    Spoiler for GroundItem.java:
    [/code]
    package org.apollo.game.model;

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;

    import java.util.Set;
    import org.apollo.game.event.impl.GroundItemEvent;
    import org.apollo.game.event.impl.RemoveGroundItemEvent;
    import org.apollo.game.event.impl.PositionEvent;
    import org.apollo.game.scheduling.impl.ProcessGroundItems Task;

    public class GroundItem {

    /**
    * The amount of pulses before a ground item turns global.
    */
    public static final int GLOBAL_PULSES = 250;

    /**
    * The task that processes all registered ground items.
    */
    private static ProcessGroundItemsTask processTask;

    /**
    * The name of the player who controls this item.
    */
    private final String controllerName;

    /**
    * The item that is on the floor.
    */
    private final Item item;

    /**
    * The position of the item.
    */
    private final Position position;

    /**
    * The x region coordinate.
    */
    private final int regionX;

    /**
    * The y region coordinate.
    */
    private final int regionY;

    /**
    * The amount of remaining pulses until this item disappears.
    */
    private int pulses;

    /**
    * Creates a private ground item.
    * @param controllerName The controller of this item.
    * @param item The item.
    * @param position The position.
    */
    public GroundItem(String controllerName, Item item, Position position, int regionX, int regionY) {
    pulses = /*item.getDefinition().isUntradeable() ? 300 :*/ 350;
    // Tradeable items appear to other players 60 seconds after being dropped, and disappear
    // after another 150 seconds if not picked up. Untradeable items simply disappear 180 seconds after being dropped.
    this.controllerName = controllerName;
    this.item = item;
    this.position = position;
    this.regionX = regionX;
    this.regionY = regionY;
    }

    /**
    * The map of the list of ground items on a position.
    */
    private static final Map<Position, List<GroundItem>> groundItems = new HashMap<Position, List<GroundItem>>();

    /**
    * Gets a the map of ground items.
    */
    public static Map<Position, List<GroundItem>> getGroundItems() {
    return groundItems;
    }

    /**
    * Gets a the map of ground items for a position.
    * @param position The position.
    */
    public static List<GroundItem> getGroundItems(Position position) {
    return groundItems.get(position);
    }

    /**
    * Gets a ground item by its id.
    * @param id The id.
    * @return {@code null} if there is no ground item of this id on this position, the ground item otherwise.
    */
    public static GroundItem getGroundItem(Position position, int id) {
    if (groundItems.get(position) != null) {
    for (GroundItem groundItem : groundItems.get(position)) {
    if (groundItem.getItem().getId() == id) {
    return groundItem;
    }
    }
    }
    return null;
    }

    public static void createGroundItem(final Player p, int itemId, int itemAmount, Position pos) {
    Item item = new Item(itemId, itemAmount);
    boolean stackable = item.getDefinition().isStackable();
    if(stackable) {
    GroundItem groundItem = new GroundItem(p.getName(), item, pos, p.getLastKnownRegion().getTopLeftRegionX(), p.getLastKnownRegion().getTopLeftRegionY());
    p.send(new PositionEvent(p.getPosition()));
    p.send(new GroundItemEvent(itemId, itemAmount));
    updateMap(groundItem, item);
    } else {
    for(int i = 0; i < itemAmount; i++) {
    GroundItem groundItem = new GroundItem(p.getName(), new Item(itemId, 1), pos, p.getLastKnownRegion().getTopLeftRegionX(), p.getLastKnownRegion().getTopLeftRegionY());
    p.send(new PositionEvent(p.getPosition()));
    p.send(new GroundItemEvent(itemId, 1));
    updateMap(groundItem, new Item(itemId, 1));
    }
    }
    }

    public static void updateMap(GroundItem g, Item item) {
    if(groundItems.get(g.getPosition()) == null) {
    groundItems.put(g.getPosition(), new ArrayList<GroundItem>());
    }
    groundItems.get(g.getPosition()).add(g);
    processTaskCheck();
    }

    public static void processTaskCheck() {
    if (processTask == null) {
    processTask = new ProcessGroundItemsTask();
    World.getWorld().schedule(processTask);
    }
    }

    /**
    * Deletes and unregisters a ground item.
    * @param groundItem The ground item to unregister.
    */
    public static void deleteGroundItem(GroundItem groundItem) {
    groundItems.get(groundItem.getPosition()).remove(g roundItem);

    if (groundItems.get(groundItem.getPosition()).isEmpty ()) {
    groundItems.remove(groundItem.getPosition());
    }

    boolean global = groundItem.getPulses() <= GLOBAL_PULSES /*&& !groundItem.getItem().getDefinition().*/;

    for (Player player : World.getWorld().getPlayerRepository()) {
    //if (global || player.getName().equals(groundItem.getControllerNa me()))
    //if (player.getPosition().isWithinDistance(groundItem. getPosition(), 60)) {
    player.send(new PositionEvent(groundItem.getPosition()));
    player.send(new RemoveGroundItemEvent(groundItem.getItem().getId() , groundItem.getItem().getAmount()));
    //}
    }
    }

    /*
    * Handles login
    *
    */

    public static void login(Player player) {
    Collection collection = getGroundItems().values();

    Iterator iterator = collection.iterator();

    while(iterator.hasNext()) {
    List list = (List) iterator.next();
    if(list == null) {
    return;
    }
    for(int i = 0; i < list.size(); i++) {
    GroundItem g = (GroundItem) list.get(i);
    if(g == null) {
    continue;
    }
    if(g.controllerName.equals(player.getName())) {
    player.send(new PositionEvent(g.getPosition()));
    player.send(new GroundItemEvent(g.getItem().getId(), g.getItem().getAmount()));

    }
    }
    }
    }

    /*
    * Handles pickupItem
    *
    */

    public static void pickupItem(Player p, Position position, int itemId) {
    if(p.getInventory().freeSlots() <= 0) {
    p.sendMessage("Not enough inventory slots");
    return;
    }
    List list = getGroundItems(position);
    if(list == null) {
    return;
    }
    for(int i = 0; i < list.size(); i++) {
    GroundItem groundItem = (GroundItem) list.get(i);
    if(groundItem == null) {
    continue;
    }
    if(groundItem.item.getId() == itemId) {
    deleteGroundItem(groundItem);
    p.getInventory().add(groundItem.item);
    return;
    }
    }
    }

    /**
    * Gets the controller's name.
    * @return The controller's name.
    */
    public String getControllerName() {
    return controllerName;
    }

    /**
    * Gets the pulses.
    * @return The pulses.
    */
    public int getPulses() {
    return pulses;
    }

    /**
    * Decreases the pulses.
    * @param pulses The pulses to decrease by.
    */
    public void decreasePulses(int pulses) {
    this.pulses -= pulses;
    }

    /**
    * Gets the item.
    * @return The item.
    */
    public Item getItem() {
    return item;
    }

    /**
    * Gets the position.
    * @return The position.
    */
    public Position getPosition() {
    return position;
    }

    /**
    * Gets the regionX.
    * @return The regionX.
    */
    public int getRegionX() {
    return regionX;
    }

    /**
    * Gets the regionY.
    * @return The regionY.
    */
    public int getRegionY() {
    return regionY;
    }

    }
    [/code]


    Spoiler for PositionEventEncoder.java:

    package org.apollo.net.release.r317;

    import org.apollo.game.event.impl.PositionEvent;
    import org.apollo.game.model.Position;
    import org.apollo.net.codec.game.DataTransformation;
    import org.apollo.net.codec.game.DataType;
    import org.apollo.net.codec.game.GamePacket;
    import org.apollo.net.codec.game.GamePacketBuilder;
    import org.apollo.net.release.EventEncoder;

    /**
    * An {@link EventEncoder} for the {@link PositionEvent}.
    * @author Chris Fletcher
    */
    final class PositionEventEncoder extends EventEncoder<PositionEvent> {

    @Override
    public GamePacket encode(PositionEvent event) {
    GamePacketBuilder builder = new GamePacketBuilder(85);
    Position base = event.getBase(), pos = event.getPosition();

    builder.put(DataType.BYTE, DataTransformation.NEGATE, pos.getLocalY(base));
    builder.put(DataType.BYTE, DataTransformation.NEGATE, pos.getLocalX(base));

    return builder.toGamePacket();
    }

    }
    [/code]
    Reply With Quote  
     

  2. #2  
    Registered Member Sixpack's Avatar
    Join Date
    Sep 2010
    Posts
    339
    Thanks given
    81
    Thanks received
    80
    Rep Power
    24
    Hey Derpscape.

    Code:
    public PositionEvent(Position base, Position position) {
    and
    Code:
    player.send(new PositionEvent(g.getPosition()));
    wouldn't work together. I don't know what 'base' is used for, as a ground item can't really walk around so it's current position is its base, but that's up to you.

    To remove the errors just replace the red lines with:
    Code:
    player.send(new PositionEvent(g.getPosition(), g.getPosition()));
    Reply With Quote  
     

  3. #3  
    Registered Member derpscape's Avatar
    Join Date
    Jul 2011
    Posts
    212
    Thanks given
    37
    Thanks received
    20
    Rep Power
    43
    If I were to replace all of the lines with what you said, it wouldn't work. The lines in the red aren't the same.

    As for your method, I understand what you tried to say. You wanted me to replace the lines by doubling up ".getPosition()" in the argument, which WOULD remove the errors, but would not fix my problem with trying to get the 2 files to interact with each other the way they were intended.

    You also mentioned you don't know what "base" is for, so here is my Position.java.

    Spoiler for Position.java:
    Code:
    package org.apollo.game.model;
    
    /**
     * Represents a position in the world.
     * @author Graham
     */
    public final class Position {
    
    	/**
    	 * The number of height levels.
    	 */
    	public static final int HEIGHT_LEVELS = 4;
    
    	/**
    	 * The maximum distance players/NPCs can 'see'.
    	 */
    	public static final int MAX_DISTANCE = 15;
    
    	/**
    	 * The x coordinate.
    	 */
    	private final int x;
    
    	/**
    	 * The y coordinate.
    	 */
    	private final int y;
    
    	/**
    	 * The height level.
    	 */
    	private final int height;
    
    	/**
    	 * Creates a position at the default height.
    	 * @param x The x coordinate.
    	 * @param y The y coordinate.
    	 */
    	public Position(int x, int y) {
    		this(x, y, 0);
    	}
    
    	/**
    	 * Creates a position with the specified height.
    	 * @param x The x coordinate.
    	 * @param y The y coordinate.
    	 * @param height The height.
    	 */
    	public Position(int x, int y, int height) {
    		if (height < 0 || height >= HEIGHT_LEVELS) {
    			throw new IllegalArgumentException("Height out of bounds");
    		}
    		this.x = x;
    		this.y = y;
    		this.height = height;
    	}
    
    	/**
    	 * Gets the x coordinate.
    	 * @return The x coordinate.
    	 */
    	public int getX() {
    		return x;
    	}
    
    	/**
    	 * Gets the y coordinate.
    	 * @return The y coordinate.
    	 */
    	public int getY() {
    		return y;
    	}
    
    	/**
    	 * Gets the height level.
    	 * @return The height level.
    	 */
    	public int getHeight() {
    		return height;
    	}
    
    	/**
    	 * Gets the x coordinate of the region.
    	 * @return The region x coordinate.
    	 */
    	public int getTopLeftRegionX() {
    		return (x / 8) - 6;
    	}
    
    	/**
    	 * Gets the y coordinate of the region.
    	 * @return The region y coordinate.
    	 */
    	public int getTopLeftRegionY() {
    		return (y / 8) - 6;
    	}
    
    	/**
    	 * Gets the x coordinate of the central region.
    	 * @return The x coordinate of the central region.
    	 */
    	public int getCentralRegionX() {
    		return x / 8;
    	}
    
    	/**
    	 * Gets the y coordinate of the central region.
    	 * @return The y coordinate of the central region.
    	 */
    	public int getCentralRegionY() {
    		return y / 8;
    	}
    
    	/**
    	 * Gets the x coordinate inside the region of this position.
    	 * @return The local x coordinate.
    	 */
    	public int getLocalX() {
    		return getLocalX(this);
    	}
    
    	/**
    	 * Gets the y coordinate inside the region of this position.
    	 * @return The local y coordinate.
    	 */
    	public int getLocalY() {
    		return getLocalY(this);
    	}
    
    	/**
    	 * Gets the local x coordinate inside the region of the {@code base}
    	 * position.
    	 * @param base The base position.
    	 * @return The local x coordinate.
    	 */
    	public int getLocalX(Position base) {
    		return x - (base.getTopLeftRegionX() * 8);
    	}
    
    	/**
    	 * Gets the local y coordinate inside the region of the {@code base}
    	 * position.
    	 * @param base The base position.
    	 * @return The local y coordinate.
    	 */
    	public int getLocalY(Position base) {
    		return y - (base.getTopLeftRegionY() * 8);
    	}
    
    	@Override
    	public int hashCode() {
    		return ((height << 30) & 0xC0000000) | ((y << 15) & 0x3FFF8000) | (x & 0x7FFF);
    	}
    
    	/**
    	 * Gets the distance between this position and another position. Only X and
    	 * Y are considered (i.e. 2 dimensions).
    	 * @param other The other position.
    	 * @return The distance.
    	 */
    	public int getDistance(Position other) {
    		int deltaX = x - other.x;
    		int deltaY = y - other.y;
    		// TODO will rounding up interfere with other stuff?
    		return (int) Math.ceil(Math.sqrt(deltaX * deltaX + deltaY * deltaY));
    	}
    
    	/**
    	 * Gets the longest horizontal or vertical delta between the two positions.
    	 * @param other The other position.
    	 * @return The longest horizontal or vertical delta.
    	 */
    	public int getLongestDelta(Position other) {
    		int deltaX = x - other.x;
    		int deltaY = y - other.y;
    		return Math.max(deltaX, deltaY);
    	}
    
    	/**
    	 * Checks if the position is within distance of another.
    	 * @param other The other position.
    	 * @param distance The distance.
    	 * @return {@code true} if so, {@code false} if not.
    	 */
    	public boolean isWithinDistance(Position other, int distance) {
    		int deltaX = Math.abs(x - other.x);
    		int deltaY = Math.abs(y - other.y);
    		return deltaX <= distance && deltaY <= distance;
    	}
    
    	@Override
    	public boolean equals(Object obj) {
    		if (this == obj) {
    			return true;
    		}
    		if (obj == null) {
    			return false;
    		}
    		if (getClass() != obj.getClass()) {
    			return false;
    		}
    		Position other = (Position) obj;
    		if (height != other.height) {
    			return false;
    		}
    		if (x != other.x) {
    			return false;
    		}
    		if (y != other.y) {
    			return false;
    		}
    		return true;
    	}
    
    	@Override
    	public String toString() {
    		return Position.class.getName() + " [x=" + x + ", y=" + y + ", height=" + height + "]";
    	}
    
    }


    Oh and this might help, the previous version was written like this:

    Code:
     p.send(new PositionEvent(p.getPosition(), (byte) 0, (byte) 0));
    but because my PositionEvent was never written for "Position, Int, Int", it never worked.
    Reply With Quote  
     

  4. #4  
    Registered Member

    Join Date
    Feb 2012
    Posts
    901
    Thanks given
    96
    Thanks received
    480
    Rep Power
    654
    As stated above, the PositionEvent uses two positions to encode properly. The reason we're using 2 positions instead of one is because the client needs to determine the target position from a base. This is because the client makes use of the region system. If you would send the PositionEvent for a target that is not located within the player's map region, the client won't put it on the map (saving memory and stuff). I'm not going to explain the entire region system here, mainly because it's too much information and because I'm still studying it myself. I am going to explain what you're doing wrong here, though.

    Again, the PositionEvent requires two positions: A base position and a target position. In this case, the base position would be the player's position (hint: last known region) and the target position would be the GroundItem's position. The client uses the player's position to determine the GroundItem's position.

    So try something like this;
    Code:
    p.send(new PositionEvent(p.getLastKnownRegion(), item.getPosition());
    So conclusions:
    • You've got to use 2 positions for the PositionEvent, that's just how it works.
    • The base position of the event is the player's position/last known region.
    • The previous PositionEvent you used, doesn't really make any sense in my eyes.


    Hope this clarifies it...
    Chris Fletcher
    Economist & Hobbyist Developer
    Reply With Quote  
     

  5. #5  
    Registered Member derpscape's Avatar
    Join Date
    Jul 2011
    Posts
    212
    Thanks given
    37
    Thanks received
    20
    Rep Power
    43
    Thank you for helping me better understand things Chris.

    I am still stuck because I have yet to be spoon fed the 4 lines of code I am asking for, but its ok I understand its too much to ask for. xD

    And didn't you mean:

    Code:
    p.send(new PositionEvent(p.getLastKnownRegion(), groundItem.getPosition()));
    ?

    What about this part where its like "g", how would I reword it?

    Spoiler for code:
    Code:
    if(g.controllerName.equals(player.getName())) {
                            player.send(new PositionEvent(player.getLastKnownRegion(), groundItem.getPosition()));
                            player.send(new GroundItemEvent(g.getItem().getId(), g.getItem().getAmount()));
    			
                        }
                    }
                }
            }


    Spoiler for cmd error:
    Code:
    Reply With Quote  
     

  6. #6  
    Registered Member

    Join Date
    Feb 2012
    Posts
    901
    Thanks given
    96
    Thanks received
    480
    Rep Power
    654
    Quote Originally Posted by derpscape View Post
    Thank you for helping me better understand things Chris.

    I am still stuck because I have yet to be spoon fed the 4 lines of code I am asking for, but its ok I understand its too much to ask for. xD

    And didn't you mean:

    Code:
    p.send(new PositionEvent(p.getLastKnownRegion(), groundItem.getPosition()));
    ?

    What about this part where its like "g", how would I reword it?

    Spoiler for code:
    Code:
    if(g.controllerName.equals(player.getName())) {
                            player.send(new PositionEvent(player.getLastKnownRegion(), groundItem.getPosition()));
                            player.send(new GroundItemEvent(g.getItem().getId(), g.getItem().getAmount()));
    			
                        }
                    }
                }
            }


    Spoiler for cmd error:
    Code:
    Have you considered using an IDE like Eclipse?
    Chris Fletcher
    Economist & Hobbyist Developer
    Reply With Quote  
     

  7. #7  
    Registered Member derpscape's Avatar
    Join Date
    Jul 2011
    Posts
    212
    Thanks given
    37
    Thanks received
    20
    Rep Power
    43
    Quote Originally Posted by Chris Fletcher View Post
    Have you considered using an IDE like Eclipse?
    Now, why would I go and do that?

    It always worried me that I could compile code with Eclipse that wouldn't normally compile in the cmd prompt.. Explain?
    Reply With Quote  
     

  8. #8  
    Registered Member

    Join Date
    Feb 2012
    Posts
    901
    Thanks given
    96
    Thanks received
    480
    Rep Power
    654
    Quote Originally Posted by derpscape View Post
    Now, why would I go and do that?

    It always worried me that I could compile code with Eclipse that wouldn't normally compile in the cmd prompt.. Explain?
    An IDE compiles your code the moment you save your Java files. The fact that you can't compile with a prompt but you can with Eclipse is probably because you forgot to add the server libraries and such to be included.

    I'm just saying that these are very simple errors which would have been solved in a second if you had used an IDE.
    Chris Fletcher
    Economist & Hobbyist Developer
    Reply With Quote  
     

  9. #9  
    Programmer, Contributor, RM and Veteran




    Join Date
    Mar 2007
    Posts
    5,147
    Thanks given
    2,656
    Thanks received
    3,731
    Rep Power
    5000
    Quote Originally Posted by Chris Fletcher View Post
    The reason we're using 2 positions instead of one is because the client needs to determine the target position from a base. This is because the client makes use of the region system. If you would send the PositionEvent for a target that is not located within the player's map region, the client won't put it on the map (saving memory and stuff).
    Actual reason is the PositionEvent is sending local coordinates that start from the top left tile stored in the client's memory (it stores 104x104 tiles locally.)

    However, if you send a single Position, this is not enough to know where this top left tile is, and therefore you can't calculate from it to send.

    getLastKnownRegion() returns the position from where the last map region load packet was sent, this allows you to know where this top left tile is and calculate the correct difference from it to send to the client.
    .
    Reply With Quote  
     

  10. Thankful user:


  11. #10  
    Registered Member

    Join Date
    Feb 2012
    Posts
    901
    Thanks given
    96
    Thanks received
    480
    Rep Power
    654
    Quote Originally Posted by Graham View Post
    Actual reason is the PositionEvent is sending local coordinates that start from the top left tile stored in the client's memory (it stores 104x104 tiles locally.)

    However, if you send a single Position, this is not enough to know where this top left tile is, and therefore you can't calculate from it to send.

    getLastKnownRegion() returns the position from where the last map region load packet was sent, this allows you to know where this top left tile is and calculate the correct difference from it to send to the client.
    You should have released Apollo with a region storage system.

    inb4theblamefallsonme
    Chris Fletcher
    Economist & Hobbyist Developer
    Reply With Quote  
     


Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Replies: 10
    Last Post: 10-13-2013, 08:22 PM
  2. Grounditem
    By Xx Dice xX in forum Help
    Replies: 5
    Last Post: 02-10-2012, 12:14 AM
  3. [PI] groundItem
    By Jason in forum Help
    Replies: 13
    Last Post: 11-26-2011, 07:33 PM
  4. [PI] GroundItem
    By Senpai in forum Help
    Replies: 9
    Last Post: 10-05-2011, 11:33 PM
  5. grounditem
    By E C T A S Y in forum Help
    Replies: 0
    Last Post: 04-09-2010, 02:25 AM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •