home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 07 DecisionMaking Architectures / 01 Isla, Blumberg / Commander.java < prev    next >
Encoding:
Java Source  |  2001-09-25  |  7.3 KB  |  200 lines

  1. package bb;
  2.  
  3. import java.awt.*;
  4. import java.util.*;
  5. import javax.swing.*;
  6. import java.awt.geom.*;
  7.  
  8. /*
  9. The commander is a rank above the soldiers. It actually gathers soldiers into little
  10. groups of six to fulfill various kinds of missions, including location defense and
  11. attack.
  12.  
  13. @author naimad
  14. */
  15. public class Commander extends Agent {
  16.  
  17.     /*
  18.     The commanders skills.
  19.     Note that many of these skills themselves create and post missions when
  20.     they become active. These missions are usually intended for soldiers, who 
  21.     will form small squads.
  22.     */
  23.     
  24.     /*
  25.     This mission causes the commander to defend a piece of land. This is often 
  26.     in response to a mission posted by a defenseTactician, who has identified
  27.     a strategically important area.
  28.     */
  29.     class DefendLocationSkill extends Skill {
  30.     
  31.         public final static String DEFENDLOCATION = "defend location";
  32.         
  33.         public DefendLocationSkill(Agent agent) {
  34.             super(DEFENDLOCATION, agent);
  35.         }
  36.  
  37.         LocatableMission myMission = null;
  38.         Vec2 vtemp = new Vec2();
  39.         
  40.         //When I activate, I create a mission that soldiers can satisfy.
  41.         public void activate() {
  42.             if (myMission!=null) System.out.println("WARNING! " + agent + "'s myMission != null");
  43.             myMission = new LocatableMission(Soldier.AttackLocationSkill.ATTACKLOCATION, 6, 2, vtemp, 0.0);
  44.             agent.bb.addMission(myMission);
  45.         }
  46.         
  47.         public void apply(double time, Mission mission) {
  48.             if (mission!=null) {
  49.                 LocatableMission dmission = (LocatableMission)mission;
  50.                 dmission.getTargetPosition(vtemp);
  51.                 myMission.setTargetPosition(vtemp);
  52.             
  53.                 //Go toward my target position
  54.                 Vec2.sub(vtemp, agent.pos, vtemp);
  55.                 double dist = vtemp.mag();
  56.                 vtemp.scale(dist-20.0/dist);
  57.                 agent.addForce(vtemp);
  58.             }
  59.         }
  60.         
  61.         public void deActivate() {
  62.             if (myMission!=null) {
  63.                 myMission.setMissionComplete();
  64.                 myMission = null;
  65.             }
  66.         }
  67.     }
  68.  
  69.     /*
  70.     The purpose of this skill is self-explanatory.
  71.     This skill can be directed (if the mission it is passed contains the
  72.     location of a city to attack) or undirected, since this skill is also
  73.     the default skill of the commander (i.e. if there are no appropriate 
  74.     missions available, it performs its AttackCitySkill). That means that
  75.     it makes its own decision about what city to attack.
  76.     */
  77.     class AttackCitySkill extends Skill {
  78.     
  79.         public final static String ATTACKCITY = "attack city";
  80.         public final static double DESIRED_DIST = 50.0;
  81.         
  82.         public AttackCitySkill(Agent agent) {
  83.             super(ATTACKCITY, agent);
  84.             targetLocation = new Vec2(agent.pos);
  85.         }
  86.         
  87.         Vec2 vtemp = new Vec2();
  88.         City pickCity(Mission mission) {
  89.             //if no other indication, choose the nearest one...
  90.             if (mission!=null) {
  91.                 LocatableMission lmission = (LocatableMission)mission;
  92.                 lmission.getTargetPosition(vtemp);
  93.                 return agent.world.getNearestEnemyCityWithinRange(agent, vtemp, agent.viewRange);
  94.             }
  95.             else return agent.world.getNearestEnemyCityWithinRange(agent, agent.pos, agent.viewRange);
  96.         }
  97.         
  98.         LocatableMission myMission = null;
  99.         Vec2 targetLocation = new Vec2();
  100.         Vec2 direction = new Vec2();
  101.         City tcity = null;
  102.         boolean missionBegun = false;
  103.         
  104.         public void activate() {
  105.             if (myMission!=null) System.out.println("WARNING! " + agent + "'s myMission != null");
  106.             myMission = new LocatableMission(Soldier.AttackLocationSkill.ATTACKLOCATION, 6, 2, agent.pos);
  107.             tcity = null;
  108.         }
  109.         
  110.         public void apply(double time, Mission mission) {
  111.             if (tcity==null) {
  112.                 //create the mission and post it!
  113.                 tcity = pickCity(mission);
  114.                 if (tcity!=null) {
  115.                     agent.bb.addMission(myMission);     //it hasn't been added yet!
  116.                     tcity.getPosition(agent, targetLocation);
  117.                 }
  118.             }
  119.             
  120.             if (tcity!=null) {
  121.                 if (!tcity.isAlive()) {
  122.                     //disband the mission!
  123.                     System.out.println(agent + " --> Mission a success!");
  124.                     if (mission!=null) mission.setMissionComplete();    //completed the mission I was executing
  125.                     else {                                                //we're acting on our own ... 
  126.                         currentMission = null;
  127.                         this.deActivate();
  128.                         currentSkill = null;
  129.                     }
  130.                 }
  131.                 else {
  132.                     if (myMission.isFull() && !missionBegun) {
  133.                         boolean allNearMe = true;
  134.                         for (int c=0; c < myMission.members.size() && allNearMe; c++) {
  135.                             Agent member = (Agent)myMission.members.elementAt(c);
  136.                             allNearMe &= (member.pos.distance(agent.pos) < 40.0);
  137.                         }
  138.                         missionBegun = allNearMe;
  139.                     }
  140.                     
  141.                     if (missionBegun) {
  142.                         //Go toward my target position
  143.                         Vec2.sub(targetLocation, agent.pos, direction);
  144.                         double dist = direction.mag();
  145.                         if (dist!=0) {
  146.                             direction.normalize();
  147.                             direction.scale((dist-DESIRED_DIST)/DESIRED_DIST);
  148.                             agent.addForce(direction);
  149.                         }
  150.                         if (dist < DESIRED_DIST*1.1) myMission.setTargetPosition(targetLocation);
  151.                         else {    //have my soldier march in front of me.
  152.                             direction.normalize();
  153.                             direction.scale(50.0);
  154.                             Vec2.add(direction, agent.pos, direction);
  155.                             myMission.setTargetPosition(direction);
  156.                         }
  157.                     }
  158.                 }
  159.             }
  160.         }
  161.  
  162.         public void deActivate() {
  163.             if (myMission!=null) {
  164.                 missionBegun= false;
  165.                 myMission.setMissionComplete();
  166.                 myMission = null;
  167.             }
  168.         }
  169.     }
  170.  
  171.     public final static int COST = 200;
  172.     AttackCitySkill attackCity;
  173.  
  174.     //The COMMANDER constructor
  175.     public Commander(int team, Vec2 pos, Blackboard bb, World world) {
  176.         super(team, 2, pos, 4.0, 20.0, 2000.0, bb, world);
  177.  
  178.         //subclasses should add skills to their skill hashTable...
  179.         attackCity = new AttackCitySkill(this);
  180.         skills.put(attackCity.getName(), attackCity);
  181.         
  182.         DefendLocationSkill defendLoc = new DefendLocationSkill(this);
  183.         skills.put(defendLoc.getName(), defendLoc);
  184.  
  185.         defaultSkill = attackCity;
  186.     }
  187.  
  188.     //--------------------------------GRAPHICS------------------------------------
  189.     
  190.     Shape outline = new Ellipse2D.Double(-6.0, -6.0, 12.0, 12.0);
  191.     public Shape createShape() {
  192.         return new Ellipse2D.Double(-4.0, -4.0, 8.0, 8.0);
  193.     }
  194.  
  195.     public void drawShape(double time, Graphics2D g2) {
  196.         g2.fill(drawShape);
  197.         g2.draw(outline);
  198.     }
  199. }
  200.