/*
Copyright 2012 Jan Ove Saltvedt
This file is part of KBot.
KBot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KBot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with KBot. If not, see <http://www.gnu.org/licenses/>.
*/
package com.kbotpro.scriptsystem.fetch;
import com.kbotpro.scriptsystem.various.ModuleConnector;
import com.kbotpro.scriptsystem.wrappers.PhysicalObject;
import com.kbotpro.scriptsystem.wrappers.Player;
import com.kbotpro.scriptsystem.wrappers.Tile;
import com.kbotpro.bot.BotEnvironment;
import com.kbotpro.hooks.Client;
import com.kbotpro.hooks.TileData;
import com.kbotpro.hooks.GameObjectNode;
import com.kbotpro.hooks.GameObject;
import java.awt.*;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* Class to handle the fetching of in game Physical Objects like trees.
*/
public class Objects extends ModuleConnector {
public static int MASK_OBJECT2 = 1;
public static int MASK_BOUNDARY = 6; // 2+4
public static int MASK_OBJECT5 = 8;
public static int MASK_DECORATIONS = 16;
public static int MASK_INTERACTIVE = 32;
public Objects(BotEnvironment botEnv) {
super(botEnv);
}
public PhysicalObject[] getObjectsAt(int x, int y, int mask){
Client client = getClient();
int currentPlane = client.getCurrentPlane();
x -= client.getBaseX();
y -= client.getBaseY();
if(x < 0 || y < 0 || x > 103 || y > 103){
return new PhysicalObject[0];
}
TileData[][][] datas = client.getTileDataArray();
if(datas == null){
return new PhysicalObject[0];
}
TileData tileData = datas[currentPlane][x][y];
if(tileData == null){
return new PhysicalObject[0];
}
List<PhysicalObject> physicalObjects = new ArrayList<PhysicalObject>();
if((mask & MASK_INTERACTIVE) != 0){
GameObjectNode current = tileData.getGameObjectNodeHeader();
while(current != null){
GameObject containedGameObject = current.getContainedGameObject();
if(containedGameObject != null){
if(containedGameObject instanceof com.kbotpro.hooks.PhysicalObject){
physicalObjects.add(new PhysicalObject(botEnv, (com.kbotpro.hooks.PhysicalObject) containedGameObject, PhysicalObject.Type.INTERACTIVE));
}
}
current = current.getNextNode();
}
}
if((mask & MASK_DECORATIONS) != 0){
com.kbotpro.hooks.PhysicalObject decoration = tileData.getDecorationObject();
if(decoration != null){
physicalObjects.add(new PhysicalObject(botEnv, decoration, PhysicalObject.Type.DECORATION));
}
}
if((mask & MASK_OBJECT2) != 0){
com.kbotpro.hooks.PhysicalObject object2 = tileData.getObject2();
if(object2 != null){
physicalObjects.add(new PhysicalObject(botEnv, object2, PhysicalObject.Type.UNKNOWN_1));
}
}
if((mask & MASK_BOUNDARY) != 0){
com.kbotpro.hooks.PhysicalObject bounding1 = tileData.getBoundingObject1();
if(bounding1 != null){
physicalObjects.add(new PhysicalObject(botEnv, bounding1, PhysicalObject.Type.BOUNDARY));
}
com.kbotpro.hooks.PhysicalObject bounding2 = tileData.getBoundingObject2();
if(bounding2 != null){
physicalObjects.add(new PhysicalObject(botEnv, bounding2, PhysicalObject.Type.BOUNDARY));
}
}
if((mask & MASK_OBJECT5) != 0){
com.kbotpro.hooks.PhysicalObject object5 = tileData.getObject5();
if(object5 != null){
physicalObjects.add(new PhysicalObject(botEnv, object5, PhysicalObject.Type.UNKNOWN_2));
}
}
return physicalObjects.toArray(new PhysicalObject[1]);
}
public PhysicalObject[] getObjects(int range) {
List<PhysicalObject> out = new LinkedList<PhysicalObject>();
Tile myPos = botEnv.players.getMyPlayer().getLocation();
int minX = myPos.getX() - range;
int minY = myPos.getY() - range;
int maxX = myPos.getX() + range;
int maxY = myPos.getY() + range;
for (int x = minX; x < maxX; x++) {
for (int y = minY; y < maxY; y++) {
PhysicalObject[] physicalObjects = getObjectsAt(x, y);
for(PhysicalObject o: physicalObjects){
if (o != null) {
out.add(o);
}
}
}
}
return out.toArray(new PhysicalObject[out.size()]);
}
public PhysicalObject[] getObjectsAt(int x, int y) {
return getObjectsAt(x, y, MASK_BOUNDARY|MASK_INTERACTIVE);
}
public PhysicalObject getClosestObjectNoID(int range) {
Tile myPos = botEnv.players.getMyPlayer().getLocation();
int minX = myPos.getX() - range;
int minY = myPos.getY() - range;
int maxX = myPos.getX() + range;
int maxY = myPos.getY() + range;
List<PhysicalObject> objList = new ArrayList<PhysicalObject>();
for (int x = minX; x < maxX; x++) {
for (int y = minY; y < maxY; y++) {
PhysicalObject[] physicalObjects = getObjectsAt(x, y);
for(PhysicalObject o: physicalObjects){
if (o != null) {
objList.add(o);
}
}
}
}
if (objList.isEmpty())
return null;
double closest = 9999;
PhysicalObject closestObj = null;
for (PhysicalObject o : objList) {
double distance = myPos.distanceToPrecise(o.getLocation());
if (distance < closest) {
closest = distance;
closestObj = o;
}
}
return closestObj;
}
public PhysicalObject[] getObjects(int range, int... ids) {
List<PhysicalObject> out = new LinkedList<PhysicalObject>();
Tile myPos = botEnv.players.getMyPlayer().getLocation();
int minX = myPos.getX() - range;
int minY = myPos.getY() - range;
int maxX = myPos.getX() + range;
int maxY = myPos.getY() + range;
for (int x = minX; x < maxX; x++) {
for (int y = minY; y < maxY; y++) {
PhysicalObject[] physicalObjects = getObjectsAt(x, y);
for(PhysicalObject o: physicalObjects){
if (o != null) {
int oID = o.getID();
for(int id: ids){
if(id == oID){
out.add(o);
}
}
}
}
}
}
return out.toArray(new PhysicalObject[out.size()]);
}
public PhysicalObject getClosestObject(int range, int... ids) {
Tile myPos = botEnv.players.getMyPlayer().getLocation();
int minX = myPos.getX() - range;
int minY = myPos.getY() - range;
int maxX = myPos.getX() + range;
int maxY = myPos.getY() + range;
List<PhysicalObject> objList = new ArrayList<PhysicalObject>();
for (int x = minX; x < maxX; x++) {
for (int y = minY; y < maxY; y++) {
PhysicalObject[] physicalObjects = getObjectsAt(x, y);
for(PhysicalObject o: physicalObjects){
if (o != null) {
int oID = o.getID();
for(int id: ids){
if(id == oID){
objList.add(o);
}
}
}
}
}
}
if (objList.isEmpty())
return null;
double closest = 9999;
PhysicalObject closestObj = null;
for (PhysicalObject o : objList) {
double distance = myPos.distanceToPrecise(o.getLocation());
if (distance < closest) {
closest = distance;
closestObj = o;
}
}
return closestObj;
}
/**
* Gets all the objects at the given tile that matches the mask give.
* @param tile
* @param mask_interactive
* @return
*/
public PhysicalObject[] getObjectsAtWithMask(Tile tile, int mask_interactive) {
return getObjectsAt(tile.getX(), tile.getY(), mask_interactive);
}
/**
* Gets all the objects at the given tile.
* @param tile
* @return
*/
public PhysicalObject[] getObjectsAt(Tile tile) {
return getObjectsAt(tile.getX(), tile.getY());
}
/**
* Gets all the objects at the given tile that matches the mask give.
* @param tile
* @param mask_interactive
* @param IDs The object IDs to accept
* @return
*/
public PhysicalObject[] getObjectsAt(Tile tile, int mask_interactive, int... IDs) {
return matchID(getObjectsAtWithMask(tile, mask_interactive), IDs);
}
/**
* Gets all the objects at the given tile that matches the mask give.
* @param tile
* @param IDs The object IDs to accept
* @return
*/
public PhysicalObject[] getObjectsAt(Tile tile, int... IDs) {
return matchID(getObjectsAt(tile), IDs);
}
/**
* Takes an array of objects and matches the IDs and returns those hwo matches.
* @param physicalObjects
* @param IDs
* @return
*/
public PhysicalObject[] matchID(PhysicalObject[] physicalObjects, int... IDs){
List<PhysicalObject> out = new ArrayList<PhysicalObject>();
for(PhysicalObject physicalObject: physicalObjects){
if(physicalObject == null){
continue;
}
int pID = physicalObject.getID();
for(int id: IDs){
if(id == pID){
out.add(physicalObject);
break;
}
}
}
return out.toArray(new PhysicalObject[out.size()]);
}
/**
* Finds the object thats closest to the player.
* @param objects
* @return
*/
public PhysicalObject getClosest(PhysicalObject[] objects){
PhysicalObject closestObj = null;
Tile loc = botEnv.players.getMyPlayer().getLocation();
double cloestDist = 9999;
for(PhysicalObject object: objects){
if(object == null){
continue;
}
if(loc.distanceToPrecise(object) < cloestDist){
closestObj = object;
}
}
return closestObj;
}
/**
*
* @param tiles
* The Zone in which you want to get the Closest PhysicalObject.
* @param ids
* IDs of the PhysicalObjects you want to look for.
* @return closest PhysicalObject in zone defined by Tile[]
* @author SpeedWing
*/
public PhysicalObject getClosestObjectInZone(Tile[] tiles, int... ids) {
try {
PhysicalObject nearest = null;
final Player player = botEnv.players.getMyPlayer();
final Polygon zone = new Polygon();
for (Tile t : tiles)
zone.addPoint(t.getX(), t.getY());
for (int x = zone.getBounds().x; x < zone.getBounds().x
+ zone.getBounds().width; x++)
for (int y = zone.getBounds().y; y < zone.getBounds().y
+ zone.getBounds().height; y++)
if (zone.contains(new Point(x, y)))
if (getObjectsAt(x, y) != null) {
PhysicalObject[] objects = getObjectsAt(x, y);
for (int i = 0; i < objects.length; i++)
if (objects[i] != null)
for (int curID : ids)
if (objects[i].getID() == curID)
if (nearest == null
|| player.distanceTo(objects[i]) < player.distanceTo(nearest))
nearest = objects[i];
}
return nearest;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}