package cz.cuni.amis.pogamut.ut2004.bot.commands;

import cz.cuni.amis.pogamut.base3d.worldview.objects.ILocated;
import cz.cuni.amis.pogamut.base3d.worldview.objects.Location;
import cz.cuni.amis.pogamut.base3d.worldview.objects.Rotation;
import cz.cuni.amis.pogamut.ut2004.bot.AbstractUT2004Bot;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.*;

import java.util.logging.Logger;

/**
 * Class providing Pogamut2 UT2004 bot action commands - throwing weapon, issuing
 * combos, item interactions and other commands that didn't fit in other categories.
 *
 * @author Michal 'Knight' Bida
 */
public class Action extends BotCommands
{      
        
        /** 
         * Causes bot to perform desired adrenaline combo (only if it has enough 
         * adrenaline usually >= 100). Combo cannot be turned off when triggered. 
         * Combo will consume bot adrenaline slowly, when it reaches 0 combo stops.
         * Combo can modify bots abilities or appearance. Combos can be xGame.ComboBerserk 
         * (bigger damage), xGame.ComboDefensive (every few seconds adds health), 
         * xGame.ComboInvis (bot is invisible and is very hard to spot) or xGame.ComboSpeed
         * (bots speed is increased).
         * 
         * (issues GB COMBO command)
         * 
         * @param desiredCombo Holds the class name of the desired adrenaline combo (can be xGame.ComboBerserk, xGame.ComboDefensive, xGame.ComboInvis or xGame.ComboSpeed).
         */
        public void startCombo(String desiredCombo)
        {
            agent.getAct().act(new Combo(desiredCombo));
        }
        
        /**
         * Throws out bots current weapon (just if he is allowed to throw this kind
         * of weapon out - some weapons cannot be thrown e.g. ShieldGun) and will 
         * change to best weapon available.
         * 
         * (issues GB THROW command)
         */
        public void throwWeapon()
        {
            agent.getAct().act(new Throw());
        }
        
        /**
         * This function will kill the bot and force him to respawn. He will respawn
         * on some randomly chosen starting point in the map.
         * 
         * (issues GB RESPAWN command)
         * 
         * @see respawn(ILocated)
         * @see respawn(ILocated,Rotation)
         */
        public void respawn()
        {
            agent.getAct().act(new Respawn());
        } 
        
        /**
         * This function will kill the bot and force him to respawn. He will respawn
         * at the location supplied (if he is allowed to respawn there). Be carefull
         * when supporting some object in the game that is ILocated, may kill other player 
         * if respawned at his positions.
         * 
         * (issues GB RESPAWN command)
         * 
         * @param location Bot will be respawned at this location (if he can). Be carefull may kill players this way. Usefull when wanted to specify NavPoint you want the bot to have respawned at.       
         * 
         * @see respawn()
         * @see respawn(ILocated,Rotation)
         * 
         */
        public void respawn(ILocated location)
        {
            Respawn respawn = new Respawn();
            
            respawn.setStartLocation(location.getLocation());
            agent.getAct().act(respawn);        
        }        
        
        /**
         * This function will kill the bot and force him to respawn. He will respawn
         * at the location specified (if he is allowed to respawn there). Be carefull
         * when supporting some object in the game that is ILocated, may kill other player 
         * if respawned at his positions. He will be respawned with supplied rotation set.
         * 
         * (issues GB RESPAWN command)
         * 
         * @param location Location where the bot will be respawned.
         * @param rotation Initial rotation of the bot.
         * 
         * @see respawn()
         * @see respawn(ILocated)
         * 
         */
        public void respawn(ILocated location, Rotation rotation)
        {
            Respawn respawn = new Respawn();
            
            respawn.setStartLocation(location.getLocation());
            respawn.setStartRotation(rotation);
            agent.getAct().act(respawn);        
        }
             
                                    
	/**
	 * Constructor. Setups the command module based on given agent and logger.
	 * @param agent AbstractUT2004Bot we will send commands for
	 * @param log Logger to be used for logging runtime/debug info.
	 */        
        public Action(AbstractUT2004Bot agent, Logger log)
	{
		super(agent, log);                
	}
        
}