mirror of
https://github.com/guilhermewerner/site-pi
synced 2025-06-16 22:04:22 +00:00
415 lines
14 KiB
Java
Vendored
415 lines
14 KiB
Java
Vendored
|
|
package com.mycompany.mavenproject1;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.logging.Level;
|
|
|
|
import cz.cuni.amis.introspection.java.JProp;
|
|
import cz.cuni.amis.pogamut.base.agent.navigation.IPathExecutorState;
|
|
import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.EventListener;
|
|
import cz.cuni.amis.pogamut.base.utils.Pogamut;
|
|
import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
|
|
import cz.cuni.amis.pogamut.base.utils.math.DistanceUtils;
|
|
import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
|
|
import cz.cuni.amis.pogamut.ut2004.agent.module.utils.TabooSet;
|
|
import cz.cuni.amis.pogamut.ut2004.agent.navigation.NavigationState;
|
|
import cz.cuni.amis.pogamut.ut2004.agent.navigation.UT2004PathAutoFixer;
|
|
import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004DistanceStuckDetector;
|
|
import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004PositionStuckDetector;
|
|
import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004TimeStuckDetector;
|
|
import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
|
|
import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004BotModuleController;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.ItemType;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.UT2004ItemType;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Initialize;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Move;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Rotate;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Stop;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.StopShooting;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.BotDamaged;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.BotKilled;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Item;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.PlayerDamaged;
|
|
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.PlayerKilled;
|
|
import cz.cuni.amis.pogamut.ut2004.utils.UT2004BotRunner;
|
|
import cz.cuni.amis.utils.collections.MyCollections;
|
|
import cz.cuni.amis.utils.exception.PogamutException;
|
|
import cz.cuni.amis.utils.flag.FlagListener;
|
|
|
|
/**
|
|
* Example of Simple Pogamut bot, that randomly walks around the map searching
|
|
* for preys shooting at everything that is in its way.
|
|
*
|
|
* @author Rudolf Kadlec aka ik
|
|
* @author Jimmy
|
|
*/
|
|
@AgentScoped
|
|
public class HunterBot extends UT2004BotModuleController<UT2004Bot> {
|
|
|
|
/**
|
|
* boolean switch to activate engage behavior
|
|
*/
|
|
@JProp
|
|
public boolean shouldEngage = true;
|
|
/**
|
|
* boolean switch to activate pursue behavior
|
|
*/
|
|
@JProp
|
|
public boolean shouldPursue = true;
|
|
/**
|
|
* boolean switch to activate rearm behavior
|
|
*/
|
|
@JProp
|
|
public boolean shouldRearm = true;
|
|
/**
|
|
* boolean switch to activate collect health behavior
|
|
*/
|
|
@JProp
|
|
public boolean shouldCollectHealth = true;
|
|
/**
|
|
* how low the health level should be to start collecting health items
|
|
*/
|
|
@JProp
|
|
public int healthLevel = 75;
|
|
/**
|
|
* how many bot the hunter killed other bots (i.e., bot has fragged them /
|
|
* got point for killing somebody)
|
|
*/
|
|
@JProp
|
|
public int frags = 0;
|
|
/**
|
|
* how many times the hunter died
|
|
*/
|
|
@JProp
|
|
public int deaths = 0;
|
|
|
|
/**
|
|
* {@link PlayerKilled} listener that provides "frag" counting + is switches
|
|
* the state of the hunter.
|
|
*
|
|
* @param event
|
|
*/
|
|
@EventListener(eventClass = PlayerKilled.class)
|
|
public void playerKilled(PlayerKilled event) {
|
|
if (event.getKiller().equals(info.getId())) {
|
|
++frags;
|
|
}
|
|
if (enemy == null) {
|
|
return;
|
|
}
|
|
if (enemy.getId().equals(event.getId())) {
|
|
enemy = null;
|
|
}
|
|
}
|
|
/**
|
|
* Used internally to maintain the information about the bot we're currently
|
|
* hunting, i.e., should be firing at.
|
|
*/
|
|
protected Player enemy = null;
|
|
/**
|
|
* Item we're running for.
|
|
*/
|
|
protected Item item = null;
|
|
/**
|
|
* Taboo list of items that are forbidden for some time.
|
|
*/
|
|
protected TabooSet<Item> tabooItems = null;
|
|
|
|
private UT2004PathAutoFixer autoFixer;
|
|
|
|
private static int instanceCount = 0;
|
|
|
|
/**
|
|
* Bot's preparation - called before the bot is connected to GB2004 and
|
|
* launched into UT2004.
|
|
*/
|
|
@Override
|
|
public void prepareBot(UT2004Bot bot) {
|
|
tabooItems = new TabooSet<Item>(bot);
|
|
|
|
autoFixer = new UT2004PathAutoFixer(bot, navigation.getPathExecutor(), fwMap, aStar, navBuilder); // auto-removes wrong navigation links between navpoints
|
|
|
|
// listeners
|
|
navigation.getState().addListener(new FlagListener<NavigationState>() {
|
|
|
|
@Override
|
|
public void flagChanged(NavigationState changedValue) {
|
|
switch (changedValue) {
|
|
case PATH_COMPUTATION_FAILED:
|
|
case STUCK:
|
|
if (item != null) {
|
|
tabooItems.add(item, 10);
|
|
}
|
|
reset();
|
|
break;
|
|
|
|
case TARGET_REACHED:
|
|
reset();
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
// DEFINE WEAPON PREFERENCES
|
|
weaponPrefs.addGeneralPref(UT2004ItemType.LIGHTNING_GUN, true);
|
|
weaponPrefs.addGeneralPref(UT2004ItemType.SHOCK_RIFLE, true);
|
|
weaponPrefs.addGeneralPref(UT2004ItemType.MINIGUN, false);
|
|
weaponPrefs.addGeneralPref(UT2004ItemType.FLAK_CANNON, true);
|
|
weaponPrefs.addGeneralPref(UT2004ItemType.ROCKET_LAUNCHER, true);
|
|
weaponPrefs.addGeneralPref(UT2004ItemType.LINK_GUN, true);
|
|
weaponPrefs.addGeneralPref(UT2004ItemType.ASSAULT_RIFLE, true);
|
|
weaponPrefs.addGeneralPref(UT2004ItemType.BIO_RIFLE, true);
|
|
}
|
|
|
|
/**
|
|
* Here we can modify initializing command for our bot.
|
|
*
|
|
* @return
|
|
*/
|
|
@Override
|
|
public Initialize getInitializeCommand() {
|
|
// just set the name of the bot and his skill level, 1 is the lowest, 7 is the highest
|
|
// skill level affects how well will the bot aim
|
|
return new Initialize().setName("Hunter-" + (++instanceCount)).setDesiredSkill(5);
|
|
}
|
|
|
|
/**
|
|
* Resets the state of the Hunter.
|
|
*/
|
|
protected void reset() {
|
|
item = null;
|
|
enemy = null;
|
|
navigation.stopNavigation();
|
|
itemsToRunAround = null;
|
|
}
|
|
|
|
@EventListener(eventClass=PlayerDamaged.class)
|
|
public void playerDamaged(PlayerDamaged event) {
|
|
log.info("I have just hurt other bot for: " + event.getDamageType() + "[" + event.getDamage() + "]");
|
|
}
|
|
|
|
@EventListener(eventClass=BotDamaged.class)
|
|
public void botDamaged(BotDamaged event) {
|
|
log.info("I have just been hurt by other bot for: " + event.getDamageType() + "[" + event.getDamage() + "]");
|
|
}
|
|
|
|
/**
|
|
* Main method that controls the bot - makes decisions what to do next. It
|
|
* is called iteratively by Pogamut engine every time a synchronous batch
|
|
* from the environment is received. This is usually 4 times per second - it
|
|
* is affected by visionTime variable, that can be adjusted in GameBots ini
|
|
* file in UT2004/System folder.
|
|
*
|
|
* @throws cz.cuni.amis.pogamut.base.exceptions.PogamutException
|
|
*/
|
|
@Override
|
|
public void logic() {
|
|
// 1) do you see enemy? -> go to PURSUE (start shooting / hunt the enemy)
|
|
if (shouldEngage && players.canSeeEnemies() && weaponry.hasLoadedWeapon()) {
|
|
stateEngage();
|
|
return;
|
|
}
|
|
|
|
// 2) are you shooting? -> stop shooting, you've lost your target
|
|
if (info.isShooting() || info.isSecondaryShooting()) {
|
|
getAct().act(new StopShooting());
|
|
}
|
|
|
|
// 3) are you being shot? -> go to HIT (turn around - try to find your enemy)
|
|
if (senses.isBeingDamaged()) {
|
|
this.stateHit();
|
|
return;
|
|
}
|
|
|
|
// 4) have you got enemy to pursue? -> go to the last position of enemy
|
|
if (enemy != null && shouldPursue && weaponry.hasLoadedWeapon()) { // !enemy.isVisible() because of 2)
|
|
this.statePursue();
|
|
return;
|
|
}
|
|
|
|
// 5) are you hurt? -> get yourself some medKit
|
|
if (shouldCollectHealth && info.getHealth() < healthLevel) {
|
|
this.stateMedKit();
|
|
return;
|
|
}
|
|
|
|
// 6) if nothing ... run around items
|
|
stateRunAroundItems();
|
|
}
|
|
|
|
//////////////////
|
|
// STATE ENGAGE //
|
|
//////////////////
|
|
protected boolean runningToPlayer = false;
|
|
|
|
/**
|
|
* Fired when bot see any enemy. <ol> <li> if enemy that was attacked last
|
|
* time is not visible than choose new enemy <li> if enemy is reachable and the bot is far - run to him
|
|
* <li> otherwise - stand still (kind a silly, right? :-)
|
|
* </ol>
|
|
*/
|
|
protected void stateEngage() {
|
|
//log.info("Decision is: ENGAGE");
|
|
//config.setName("Hunter [ENGAGE]");
|
|
|
|
boolean shooting = false;
|
|
double distance = Double.MAX_VALUE;
|
|
pursueCount = 0;
|
|
|
|
// 1) pick new enemy if the old one has been lost
|
|
if (enemy == null || !enemy.isVisible()) {
|
|
// pick new enemy
|
|
enemy = players.getNearestVisiblePlayer(players.getVisibleEnemies().values());
|
|
if (enemy == null) {
|
|
log.info("Can't see any enemies... ???");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 2) stop shooting if enemy is not visible
|
|
if (!enemy.isVisible()) {
|
|
if (info.isShooting() || info.isSecondaryShooting()) {
|
|
// stop shooting
|
|
getAct().act(new StopShooting());
|
|
}
|
|
runningToPlayer = false;
|
|
} else {
|
|
// 2) or shoot on enemy if it is visible
|
|
distance = info.getLocation().getDistance(enemy.getLocation());
|
|
if (shoot.shoot(weaponPrefs, enemy) != null) {
|
|
log.info("Shooting at enemy!!!");
|
|
shooting = true;
|
|
}
|
|
}
|
|
|
|
// 3) if enemy is far or not visible - run to him
|
|
int decentDistance = Math.round(random.nextFloat() * 800) + 200;
|
|
if (!enemy.isVisible() || !shooting || decentDistance < distance) {
|
|
if (!runningToPlayer) {
|
|
navigation.navigate(enemy);
|
|
runningToPlayer = true;
|
|
}
|
|
} else {
|
|
runningToPlayer = false;
|
|
navigation.stopNavigation();
|
|
}
|
|
|
|
item = null;
|
|
}
|
|
|
|
///////////////
|
|
// STATE HIT //
|
|
///////////////
|
|
protected void stateHit() {
|
|
//log.info("Decision is: HIT");
|
|
bot.getBotName().setInfo("HIT");
|
|
if (navigation.isNavigating()) {
|
|
navigation.stopNavigation();
|
|
item = null;
|
|
}
|
|
getAct().act(new Rotate().setAmount(32000));
|
|
}
|
|
|
|
//////////////////
|
|
// STATE PURSUE //
|
|
//////////////////
|
|
/**
|
|
* State pursue is for pursuing enemy who was for example lost behind a
|
|
* corner. How it works?: <ol> <li> initialize properties <li> obtain path
|
|
* to the enemy <li> follow the path - if it reaches the end - set lastEnemy
|
|
* to null - bot would have seen him before or lost him once for all </ol>
|
|
*/
|
|
protected void statePursue() {
|
|
//log.info("Decision is: PURSUE");
|
|
++pursueCount;
|
|
if (pursueCount > 30) {
|
|
reset();
|
|
}
|
|
if (enemy != null) {
|
|
bot.getBotName().setInfo("PURSUE");
|
|
navigation.navigate(enemy);
|
|
item = null;
|
|
} else {
|
|
reset();
|
|
}
|
|
}
|
|
protected int pursueCount = 0;
|
|
|
|
//////////////////
|
|
// STATE MEDKIT //
|
|
//////////////////
|
|
protected void stateMedKit() {
|
|
//log.info("Decision is: MEDKIT");
|
|
Item item = items.getPathNearestSpawnedItem(ItemType.Category.HEALTH);
|
|
if (item == null) {
|
|
log.warning("NO HEALTH ITEM TO RUN TO => ITEMS");
|
|
stateRunAroundItems();
|
|
} else {
|
|
bot.getBotName().setInfo("MEDKIT");
|
|
navigation.navigate(item);
|
|
this.item = item;
|
|
}
|
|
}
|
|
|
|
////////////////////////////
|
|
// STATE RUN AROUND ITEMS //
|
|
////////////////////////////
|
|
protected List<Item> itemsToRunAround = null;
|
|
|
|
protected void stateRunAroundItems() {
|
|
//log.info("Decision is: ITEMS");
|
|
//config.setName("Hunter [ITEMS]");
|
|
if (navigation.isNavigatingToItem()) return;
|
|
|
|
List<Item> interesting = new ArrayList<Item>();
|
|
|
|
// ADD WEAPONS
|
|
for (ItemType itemType : ItemType.Category.WEAPON.getTypes()) {
|
|
if (!weaponry.hasLoadedWeapon(itemType)) interesting.addAll(items.getSpawnedItems(itemType).values());
|
|
}
|
|
// ADD ARMORS
|
|
for (ItemType itemType : ItemType.Category.ARMOR.getTypes()) {
|
|
interesting.addAll(items.getSpawnedItems(itemType).values());
|
|
}
|
|
// ADD QUADS
|
|
interesting.addAll(items.getSpawnedItems(UT2004ItemType.U_DAMAGE_PACK).values());
|
|
// ADD HEALTHS
|
|
if (info.getHealth() < 100) {
|
|
interesting.addAll(items.getSpawnedItems(UT2004ItemType.HEALTH_PACK).values());
|
|
}
|
|
|
|
Item item = MyCollections.getRandom(tabooItems.filter(interesting));
|
|
if (item == null) {
|
|
log.warning("NO ITEM TO RUN FOR!");
|
|
if (navigation.isNavigating()) return;
|
|
bot.getBotName().setInfo("RANDOM NAV");
|
|
navigation.navigate(navPoints.getRandomNavPoint());
|
|
} else {
|
|
this.item = item;
|
|
log.info("RUNNING FOR: " + item.getType().getName());
|
|
bot.getBotName().setInfo("ITEM: " + item.getType().getName() + "");
|
|
navigation.navigate(item);
|
|
}
|
|
}
|
|
|
|
////////////////
|
|
// BOT KILLED //
|
|
////////////////
|
|
@Override
|
|
public void botKilled(BotKilled event) {
|
|
reset();
|
|
}
|
|
|
|
///////////////////////////////////
|
|
public static void main(String args[]) throws PogamutException {
|
|
// starts 3 Hunters at once
|
|
// note that this is the most easy way to get a bunch of (the same) bots running at the same time
|
|
new UT2004BotRunner(HunterBot.class, "Hunter").setMain(true).setLogLevel(Level.INFO).startAgents(2);
|
|
}
|
|
}
|