Package net.cis.client.game.ctrl.ai

Source Code of net.cis.client.game.ctrl.ai.AIController

package net.cis.client.game.ctrl.ai;

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

import net.cis.client.game.common.ctrl.IDispatcher;
import net.cis.client.game.common.ctrl.IGameApplication;
import net.cis.client.game.common.ctrl.IObjectController;
import net.cis.client.game.common.ctrl.TimedCallbackController;
import net.cis.client.game.common.engine.SimpleBoundingVolumeFactory;
import net.cis.client.game.common.model.ai.impl.simple.SimpleRotator;
import net.cis.client.game.common.model.ai.impl.simple.SimpleWobble;
import net.cis.client.game.common.model.co.AbstractControlledObject;
import net.cis.client.game.common.model.co.ControlledSpaceObject;
import net.cis.client.game.common.model.event.AbstractEventListener;
import net.cis.client.game.common.model.event.ObjectEvent;
import net.cis.client.game.common.threading.ICallback;
import net.cis.client.game.common.util.GlobalObjectStore;
import net.cis.client.game.ctrl.threading.AbstractInterruptableRunnable;
import net.cis.client.game.scenery.ctrl.SpatialUpdater;
import net.cis.common.model.spaceobject.SpaceObject;
import net.cis.common.model.spaceobject.SpaceobjectFactory;

import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Line;
import com.jme3.scene.shape.Sphere;

/**
*
* @author Omega
*
*/
public class AIController extends AbstractInterruptableRunnable
  {
  protected final IGameApplication gameApplication;
  protected boolean initialized = false;
  protected TimedCallbackController tcc = new TimedCallbackController();
  protected ConcurrentHashMap<Integer, AbstractControlledObject<?,?>> smartObjects = new ConcurrentHashMap<Integer, AbstractControlledObject<?,?>>();

  public AIController(IGameApplication gameApp)
    {
    this.gameApplication = gameApp;
    }

  /**
   * Loads the AI structure from X to memory
   */
  protected boolean loadAIDefinition()
    {
    return true;
    }

  /**
   * Fetches the appropriate AI for the {@link AbstractControlledObject} and
   * attaches it, after detaching any existing AI.
   *
   */
  protected boolean attachAI(AbstractControlledObject<?, ?> obj)
    {
    log.trace("Attaching to " + obj);

    if (obj.getAINode() != null && !detachAI(obj))
      {
      log.error("Failed to detach AI from " + obj);
      return false;
      }

    if (obj.dataObject == null)
      {
      log.error("No data object set for " + obj);
      return false;
      }

    int objID = obj.dataObject.getId();
   
    //TODO: switch to external data defined
    if(objID == 2//2 == Asteroid
      obj.setAINode(new SimpleRotator());
    else if(objID >= 100000//debug objects
      obj.setAINode(new SimpleWobble());
   
    if(obj.getAINode() != null)
      smartObjects.put(objID, obj);

    return obj.getAINode() != null;
    }

  /**
   * Detaches the AI from an {@link AbstractControlledObject}, making it
   * non-interactive.
   */
  protected boolean detachAI(AbstractControlledObject<?, ?> obj)
    {
    log.trace("Detaching from " + obj);
    obj.setAINode(null);

    if (obj.dataObject == null)
      {
      log.error("No data object set for " + obj);
      return false;
      }

    smartObjects.remove(obj.dataObject.getId());
   
    return true;
    }

  @Override
  protected int getSleepTime()
    {
    // This will most likely be dynamic depending on actual workload
    return 100;
    }

  @Override
  protected void doRun(float timeSinceLastRun)
    {
    tcc.update(timeSinceLastRun);
   
    for (AbstractControlledObject<?,?> co : smartObjects.values())
      {
      co.getAINode().Execute(co, null, timeSinceLastRun);
      }
    }

  @Override
  protected boolean initialize()
    {
    // just be careful
    if (initialized) log.warn("Already initialized");

    // load entire ai to memory
    if (!loadAIDefinition())
      {
      log.error("Failed to load AI definitions");
      initialized = false;
      return initialized;
      }
    log.info("AI definitions loaded");

    // attach ai to existing objects
    int preExistingObjectCount = 0;
    int objectsAlreadyWithAI = 0;
    Iterator<AbstractControlledObject<?, ?>> ite = GlobalObjectStore.<IObjectController> getObject(IObjectController.class).getAllObjects(null);
    while (ite.hasNext())
      {
      ++preExistingObjectCount;
      AbstractControlledObject<?, ?> obj = ite.next();

      if (obj.getAINode() != null)
        {
        ++objectsAlreadyWithAI;
        continue;
        }

      if (!attachAI(obj)) log.error("Failed to attach AI to " + obj);
      }
    log.info("Found " + preExistingObjectCount + " objects; " + objectsAlreadyWithAI + " objects already had AI");

    // attach object listeners for future objects
    GlobalObjectStore.<IDispatcher> getObject(IDispatcher.class).addCallee(new AbstractEventListener<ObjectEvent>("ObjectAdded")
      {
        @Override
        public void onEvent(ObjectEvent event)
          {
          if (!attachAI(event.value)) log.error("Attaching AI failed: " + event.value);
          }
      });

    GlobalObjectStore.<IDispatcher> getObject(IDispatcher.class).addCallee(new AbstractEventListener<ObjectEvent>("ObjectDestroyed")
      {
        @Override
        public void onEvent(ObjectEvent event)
          {
          if (!detachAI(event.value)) log.error("Detaching AI failed: " + event.value);
          }
      });

    initDebugObjects();
   
    initialized = true;
    log.info("Initialisation complete");
    return initialized;
    }
 
  protected static int nextID = 100000;
  protected void initDebugObjects()
    {
        log.trace("Population scene with debug objects");
       
        //friend
        final Material friendMat = new Material(GlobalObjectStore.<AssetManager>getObject(AssetManager.class), "Common/MatDefs/Misc/Unshaded.j3md");
        friendMat.setColor("Color", new ColorRGBA(0, .5f, 0, 1));
        final Material friendMat2 = new Material(GlobalObjectStore.<AssetManager>getObject(AssetManager.class), "Common/MatDefs/Misc/Unshaded.j3md");
        friendMat2.setColor("Color", new ColorRGBA(.5f, .99f, .5f, 1));
        //foe
        final Material foeMat = new Material(GlobalObjectStore.<AssetManager>getObject(AssetManager.class), "Common/MatDefs/Misc/Unshaded.j3md");
        foeMat.setColor("Color", new ColorRGBA(.5f, 0, 0, 1));
        final Material foeMat2 = new Material(GlobalObjectStore.<AssetManager>getObject(AssetManager.class), "Common/MatDefs/Misc/Unshaded.j3md");
        foeMat2.setColor("Color", new ColorRGBA(.99f, .5f, .5f, 1));

        for(int i = 0; i< 10; ++i)
          createDebugFighter("Friend " + i,friendMat, friendMat2, new Vector3f((float)Math.random()*10, (float)Math.random()*10, (float)Math.random() * 10 + 15));

        for(int i = 0; i< 10; ++i)
          createDebugFighter("Foe " + i,foeMat, foeMat2, new Vector3f((float)Math.random()*-10, (float)Math.random()*-10, (float)Math.random() * 10 + 15));
    }
 
  protected void createDebugFighter(final String name, final Material main, final Material scnd, final Vector3f pos)
    {
    final IObjectController objCtrl = GlobalObjectStore.getObject(IObjectController.class);

    tcc.AddTimedCallback(new ICallback()
      {
      @Override
      public void execute()
        {
        SpaceObject so = SpaceobjectFactory.eINSTANCE.createAsteroid();
       
        so.setId(nextID++);
        so.setLocation(pos);
        so.setName(name);
        so.setRotation(new Quaternion());
        so.setLinearVelocity(new Vector3f());
        so.setAngularVelocity(new Quaternion());

        Node fighter = new Node(name);
        ControlledSpaceObject cso = new ControlledSpaceObject(so, fighter);
        cso.setDebugDisplay(name);
        cso.setGameThreadCallback(new SpatialUpdater(cso));

        Geometry gSphere = new Geometry("Sphere", new Sphere(10,10,0.25f));
        Geometry gDirection =  new Geometry("Direction-Line", new Line(new Vector3f(0,0,0), new Vector3f(0,0,2)));
       
        gSphere.setMaterial(main);
        gDirection.setMaterial(scnd);

        fighter.attachChild(gSphere);
        fighter.attachChild(gDirection);
       
       
        SimpleBoundingVolumeFactory.createBestBoundingVolume(fighter);
        fighter.setLocalTranslation(pos);
       
        objCtrl.addSpaceObject(cso, true);
        }
      }, (float) (Math.random() * 5));
    }

  @Override
  protected void shutdown()
    {
    log.debug("Beginning shutdown");

    // remove event listeners
    // ...

    // save all AI states to X
    // ...

    // detach all AI states
    // ...

    // free resources
    // ...

    log.debug("Shutdown complete");
    this.initialized = false;
    }

  }
TOP

Related Classes of net.cis.client.game.ctrl.ai.AIController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.