home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 07 DecisionMaking Architectures / 01 Isla, Blumberg / Soldier.java < prev    next >
Encoding:
Java Source  |  2001-09-25  |  4.9 KB  |  145 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 soldier agent. This is the agent that actually does most of the work, both for attack
  10. and for defense.
  11.  
  12. @author naimad
  13. */
  14.  
  15. public class Soldier extends Agent {
  16.  
  17.     //This skill just randomly approaches and attacks the nearest enemy.
  18.     class ShootSkill extends Skill {
  19.     
  20.         double hitProb;
  21.         public final static double SHOOT_DAMAGE = 10.0;
  22.         public final static String SHOOT = "shoot";
  23.         public final static int SHOOT_FREQ = 10;
  24.         public final static double SHOOT_RANGE = 100.0;
  25.         
  26.         public double DESIRED_DIST = 15.0;
  27.     
  28.         public ShootSkill(Agent a, double prof) {
  29.             this(SHOOT, a, prof);
  30.         }
  31.         
  32.         public ShootSkill(String name, Agent a, double prof) {
  33.             super(name, a, prof);
  34.             hitProb = 1.0 - 1.0/(1.0+getProficiency());
  35.             count = (int)((double)SHOOT_FREQ*Math.random());
  36.         }
  37.         
  38.         Vec2 targetPosition(Mission mission) {
  39.             if (enemy==null) return null;
  40.             else return enemy.pos;
  41.         }
  42.         
  43.         int count = 0;
  44.         double lastShootTime = 0.0;
  45.         Agent enemy = null;
  46.         Vec2 direction = new Vec2();
  47.         Vec2 scratch = new Vec2();
  48.         public void apply(double time, Mission mission) {
  49.             enemy = agent.world.getNearestWithinRegion(agent, agent.pos, agent.viewRange);
  50.             Vec2 target = targetPosition(mission);
  51.             if (target!=null) {
  52.                 Vec2.sub(target, agent.pos, direction);
  53.                 double dist = direction.mag();
  54.                 if (dist==0.0) {
  55.                     direction.x(Math.random()-0.5);
  56.                     direction.y(Math.random()-0.5);
  57.                     direction.normalize();
  58.                 }
  59.                 direction.normalize();
  60.                 scratch.set(direction);
  61.                 
  62.                 double desiredDist = DESIRED_DIST;
  63.                 if (mission instanceof LocatableMission) {
  64.                     desiredDist = ((LocatableMission)mission).getRange();
  65.                 }
  66.                 
  67.                 scratch.scale((dist-desiredDist)/DESIRED_DIST);
  68.                 agent.addForce(scratch);
  69.             }
  70.             
  71.             
  72.             if (enemy!=null) {
  73.                 //shoot him!
  74.                 
  75.                 Vec2.sub(enemy.pos, agent.pos, direction);
  76.                 double dist = direction.mag();
  77.                 direction.normalize();
  78.                 
  79.                 if (dist <= SHOOT_RANGE) {
  80.                     if (count%SHOOT_FREQ==0) {   //just so that we can't shoot all the time...
  81.                         //System.out.println("Agent " + agent + " shooting " + enemy);
  82.                         if (Math.random() <= hitProb) {
  83.                             double damage = Math.random()*SHOOT_DAMAGE;
  84.                             enemy.damage(damage);
  85.                             direction.scale(damage*1.0);
  86.                             enemy.addExternalForce(direction);
  87.                             lastShootTime = time;
  88.                         }
  89.                     }
  90.                     count++;
  91.                 }
  92.             }
  93.         }
  94.         
  95.         public void drawSkill(double time, Graphics2D g2) {
  96.             if (time==lastShootTime && enemy!=null) {
  97.                 //draw me!
  98.                 Shape line = new Line2D.Double(agent.pos.x(), agent.pos.y(), enemy.pos.x(), enemy.pos.y());
  99.                 g2.draw(line);
  100.             }
  101.         }
  102.     }
  103.  
  104.     //This skill ALSO attacks the nearest enemy but also moves in the direction of the
  105.     //target location specified by the mission.
  106.     class AttackLocationSkill extends ShootSkill {
  107.         
  108.         public static final String ATTACKLOCATION = "attack location";
  109.         Vec2 location = new Vec2();
  110.         
  111.         public AttackLocationSkill(Agent a, double prof) {
  112.             super(ATTACKLOCATION, a, prof);
  113.             DESIRED_DIST = 20.0;
  114.         }
  115.         
  116.         Vec2 targetPosition(Mission mission) {
  117.             if (mission!=null && (mission instanceof LocatableMission)) {
  118.                 ((LocatableMission)mission).getTargetPosition(location);
  119.                 return location;
  120.             }
  121.             else return super.targetPosition(mission);
  122.         }
  123.     }
  124.  
  125.  
  126.     public final static int COST = 50;
  127.  
  128.     public Soldier(int team, Vec2 pos, Blackboard bb, World world) {
  129.         super(team, 0, pos, 7.5, 10.0, 250.0, bb, world);
  130.  
  131.         //subclasses should add skills to their skill hashTable...
  132.         Skill shoot = new ShootSkill(this, 1.0);
  133.         skills.put(shoot.getName(), shoot);
  134.  
  135.         Skill attackLocation = new AttackLocationSkill(this, 1.0);
  136.         skills.put(attackLocation.getName(), attackLocation);
  137.  
  138.         defaultSkill = shoot;
  139.     }
  140.     
  141.     public Shape createShape() {
  142.         return new Ellipse2D.Double(-5.0, -5.0, 10.0, 10.0);
  143.     }    
  144. }
  145.