package com.mycompany.mavenproject1; import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView; import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEvent; import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener; import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.AnnotationListenerRegistrator; import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.EventListener; import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectClassEventListener; import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectClassListener; import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectEventListener; import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectListener; import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObject; import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent; import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectDestroyedEvent; import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectFirstEncounteredEvent; import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectUpdatedEvent; 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.Location; import cz.cuni.amis.pogamut.base3d.worldview.object.event.WorldObjectAppearedEvent; import cz.cuni.amis.pogamut.base3d.worldview.object.event.WorldObjectDisappearedEvent; import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId; 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.gbcommands.Initialize; 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.Bumped; import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange; import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage; import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo; import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.InitedMessage; 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.Self; import cz.cuni.amis.pogamut.ut2004.utils.UT2004BotRunner; import cz.cuni.amis.pogamut.ut2004.utils.UnrealUtils; import cz.cuni.amis.utils.exception.PogamutException; /** * Example of Simple Pogamut bot, that can listen to some events coming from * the game engine and respond to them appropriately. The logic of the bot is * completely event driven. * *
* Notice that we're using a special annotations * for various methods, i.e., for the method {@link ResponsiveBot${symbol_pound}bumped(Bumped)} * the annotation {@link EventListener}, for the method {@link ResponsiveBot${symbol_pound}playerAppeared(WorldObjectAppearedEvent)} * we're using {@link ObjectClassEventListener}, etc. You may perceive is as a bit magic as * some methods are called as a response to some event, e.g., the method {@link ResponsiveBot${symbol_pound}bumped(Bumped)} * is called whenever GameBots2004 sends a message {@link Bumped} to the bot. * *
* How is this possible? * *
* Well, the {@link UT2004BotModuleController} * is using {@link AnnotationListenerRegistrator} that introspects (via Java * Reflection API) the methods declared by the {@link ResponsiveBot} looking for * annotations: {@link EventListener}, {@link ObjectClassEventListener}, * {@link ObjectClassListener}, {@link ObjectEventListener} or {@link ObjectListener} * (I recommend you to read javadoc for all of them) automatically registering a * listener inside {@link ResponsiveBot${symbol_pound}getWorldView()} using one of the * "addListener" methods (e.g. {@link EventListener} annotated method is recalled * from listener added via {@link IWorldView${symbol_pound}addEventListener(java.lang.Class, cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener)}. * It provides you with a simple way how to create methods that reacts on certain events inside the game. * *
* WARNING: these annotations works only in THIS class only. If you want other of your classes to have the * same option, you will have to instantiate {@link AnnotationListenerRegistrator} for yourself * within that class. * *
* We advise you to read through all comments carefully and try to understand * when {@link EventListener} suffices and when you need to use one * of {@link ObjectClassEventListener} / * {@link ObjectClassListener} / {@link ObjectEventListener} / {@link ObjectListener}s. * *
* The trick is that some messages from GB2004 are {@link IWorldEvent}s only and some of them are {@link IWorldObject}s as well. * For listening {@link IWorldEvent}s only you must use {@link EventListener}, for listening to object updates, * you must use one of {@link ObjectClassEventListener} / {@link ObjectClassListener} / {@link ObjectEventListener} / {@link ObjectListener}s. * *
* We recommend you to run the bot on DM-TrainingDay map. * *
* Start the bot and run to it. Note that whenever the bot sees you (you enter bot's field of view} * {@link ResponsiveBot${symbol_pound}playerAppeared(cz.cuni.amis.pogamut.base3d.worldview.object.event.WorldObjectAppearedEvent)} will be triggered * and the bot will greet you. * *
* Then try to approach very close to the bot and it will ask you "what do you want". See {@link ResponsiveBot${symbol_pound}playerUpdated(cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectUpdatedEvent) } * event listener method. * *
* Check out comments inside {@link ResponsiveBot${symbol_pound}gb2004BatchEnd(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage)} message. * * @author Rudolf Kadlec aka ik * @author Jakub Gemrot aka Jimmy */ @AgentScoped public class ResponsiveBot extends UT2004BotModuleController { /** * Listener called when someone/something bumps into the bot. The bot * responds by moving in the opposite direction than the bump come from. * *
* We're using {@link EventListener} here that is registered by the {@link AnnotationListenerRegistrator} * to listen for {@link Bumped} events. * *
* Notice that {@link Bumped} is {@link IWorldEvent} only, it's not {@link IWorldObject}, * thus we're using {@link EventListener}. */ @EventListener(eventClass = Bumped.class) protected void bumped(Bumped event) { // schema of the vector computations // // e<->a<------>t // | | v | // | | target - bot will be heading there // | getLocation() // event.getLocation() Location v = event.getLocation().sub(bot.getLocation()).scale(5); Location target = bot.getLocation().sub(v); // make the bot to go to the computed location while facing the bump source move.strafeTo(target, event.getLocation()); } /** * Listener called when a player appears. * *
* We're using {@link ObjectClassEventListener} here that is registered by the {@link AnnotationListenerRegistrator} to * listen on all {@link WorldObjectAppearedEvent} that happens on any object * of the class {@link Player}. * *
* I.e., whenever the GameBots2004 sends an * update about arbitrary {@link Player} object in the game notifying us that the * player has become visible (it's {@link Player${symbol_pound}isVisible()} is switched to * true and the {@link WorldObjectAppearedEvent} is generated), this method * is called. * *
* Notice that {@link Player} implements {@link IWorldObject} thus you CANNOT use
* {@link EventListener} to catch events that updates {@link Player} objects.
*/
@ObjectClassEventListener(eventClass = WorldObjectAppearedEvent.class, objectClass = Player.class)
protected void playerAppeared(WorldObjectAppearedEvent
* Again, we're using {@link ObjectClassEventListener}
* that is registered by the {@link AnnotationListenerRegistrator} to listen
* on all {@link WorldObjectUpdatedEvent} that happens on any object of the
* class {@link Player}.
*
*
* I.e., whenever the GameBots2004 sends an update
* about arbitrary {@link Player} in the game notifying us that some
* information about the player has changed (the {@link WorldObjectUpdatedEvent}
* is generated), this method is called.
*
*
* Again, {@link Player} implements {@link IWorldObject}, thus you CANNOT use
* {@link EventListener} annotation to check for events regarding {@link Player}
* objects.
*/
@ObjectClassEventListener(eventClass = WorldObjectUpdatedEvent.class, objectClass = Player.class)
protected void playerUpdated(WorldObjectUpdatedEvent
* Note, that this is old/manual way how to add listeners on various events that are rised
* within the {@link IWorldView} (obtainable from {@link UT2004Bot${symbol_pound}getWorldView()} via
*
* Such event listener MUST BE registered via some method of {@link IWorldView} offers.
* This particular listener is registered inside {@link ResponsiveBot${symbol_pound}prepareBot(cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot)}.
* Note that you can add/remove any listener during runtime.
*/
IWorldEventListener
* Notice that we have to specify which ID
* class the world object is using and have explicit representation of it's
* id - note that this is totally unsuitable for any dynamic IDs, such as
* NavPoint ids, etc... you will probably never use this annotation.
*
*
* See implementations of {@link IWorldObjectEvent}, which are
* {@link WorldObjectFirstEncounteredEvent}, {@link WorldObjectAppearedEvent},
* {@link WorldObjectUpdatedEvent}, {@link WorldObjectDisappearedEvent}
* and {@link WorldObjectDestroyedEvent}. All such events may be possibly
* caught by this {@link ObjectListener} annotated method.
*
* @param info
*/
@ObjectListener(idClass = UnrealId.class, objectId = "GameInfoId")
public void gameInfo1(IWorldObjectEvent
* This method will receive ALL events that are raised on any {@link Player}
* object whereas {@link ResponsiveBot${symbol_pound}playerAppeared(WorldObjectAppearedEvent)}
* will receive only {@link WorldObjectAppearedEvent}.
*
*
* See implementations of {@link IWorldObjectEvent}, which are
* {@link WorldObjectFirstEncounteredEvent}, {@link WorldObjectAppearedEvent},
* {@link WorldObjectUpdatedEvent}, {@link WorldObjectDisappearedEvent}
* and {@link WorldObjectDestroyedEvent}. All such events may be possibly
* caught by this {@link ObjectListener} annotated method.
*
* @param playerEvent
*/
@ObjectClassListener(objectClass = Player.class)
public void playerEvent(IWorldObjectEvent Notice that the method is empty as this bot is completely
* event-driven.
*/
@Override
public void logic() throws PogamutException {
}
/**
* Called each time our bot die. Good for reseting all bot state dependent
* variables.
*
* @param event
*/
@Override
public void botKilled(BotKilled event) {
}
/**
* This method is called when the bot is started either from IDE or from
* command line.
*
* @param args
*/
public static void main(String args[]) throws PogamutException {
// wrapped logic for bots executions, suitable to run single bot in single JVM
new UT2004BotRunner(ResponsiveBot.class, "ResponsiveBot").setMain(true).startAgent();
}
}
bot.getWorldView()
or simply accessing {@link UT2004BotModuleController${symbol_pound}world} field).
*
*