Package com.teamjmonkey.controls

Source Code of com.teamjmonkey.controls.AggroControl

package com.teamjmonkey.controls;

import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.PhysicsTickListener;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.PhysicsCollisionObject;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.GhostControl;
import com.jme3.scene.Spatial;
import com.teamjmonkey.ai.aggro.AggroBehavior;
import com.teamjmonkey.entity.MovableEntity;

public class AggroControl extends BaseControl implements PhysicsCollisionListener, PhysicsTickListener {

    private MovableEntity entity;
    private GhostControl losGhost;
    private GhostControl attackGhost;
    private int collideWithGroup;
    private int ownCollisionGroup;
    private final float losRadius;
    private final float fightRadius;
    private boolean hasLosAggro;
    private boolean hadLosAggro;
    private boolean hasAttackAggro;
    private boolean hadAttackAggro;
    private Spatial losTarget;
    private Spatial attackTarget;
    private AggroBehavior[] losBehaviors;
    private AggroBehavior[] attackBehaviors;

    public AggroControl(MovableEntity entity, float losRadius, float fightRadius,
            int ownCollisionGroup, int collideWithGroup, AggroBehavior losBehavior,
            AggroBehavior attackBehavior) {
        this(entity, losRadius, fightRadius, collideWithGroup, ownCollisionGroup,
                losBehavior == null ? null : new AggroBehavior[]{losBehavior},
                attackBehavior == null ? null : new AggroBehavior[]{attackBehavior});
    }

    public AggroControl(MovableEntity entity, float losRadius, float fightRadius,
            int collideWithGroup, int ownCollisionGroup,
            AggroBehavior[] losBehaviors, AggroBehavior[] attackBehaviors) {
        this.entity = entity;
        this.losBehaviors = losBehaviors == null ? new AggroBehavior[0] : losBehaviors;
        this.attackBehaviors = attackBehaviors == null ? new AggroBehavior[0] : attackBehaviors;
        this.losRadius = losRadius;
        this.fightRadius = fightRadius;
        this.collideWithGroup = collideWithGroup;
        this.ownCollisionGroup = ownCollisionGroup;
        myApp.getBulletAppState().getPhysicsSpace().addCollisionListener(this);
        myApp.getBulletAppState().getPhysicsSpace().addTickListener(this);
    }

    @Override
    protected void controlUpdate(float tpf) {
        if (hasLosAggro && hadLosAggro) {
            fireLosUpdate(tpf, losTarget);
        } else if (!hasLosAggro && hadLosAggro) {
            fireLosAggroLoss();
        } else if (hasLosAggro && !hadLosAggro) {
            fireLosOnAggro(losTarget);
        }
        hadLosAggro = hasLosAggro;

        if (hasAttackAggro && hadAttackAggro) {
            fireAttackUpdate(tpf, attackTarget);
        } else if (!hasAttackAggro && hadAttackAggro) {
            fireAttackAggroLoss();
        } else if (hasAttackAggro && !hadAttackAggro) {
            fireAttackOnAggro(attackTarget);
        }
        hadAttackAggro = hasAttackAggro;
    }

    @Override
    public void setSpatial(Spatial spatial) {
        super.setSpatial(spatial);

        if (spatial != null) {
            losGhost = new GhostControl(new SphereCollisionShape(losRadius));
            attackGhost = new GhostControl(new SphereCollisionShape(fightRadius));
            addGhost(losGhost);
            addGhost(attackGhost);
            fireInit();
        }
    }

    private void addGhost(GhostControl ghost) {
        ghost.setCollisionGroup(ownCollisionGroup);
        ghost.setCollideWithGroups(collideWithGroup);
        spatial.addControl(ghost);
        myApp.getBulletAppState().getPhysicsSpace().add(ghost);
    }

    private void fireInit() {
        for (AggroBehavior ab : losBehaviors) {
            ab.init(myApp, entity, spatial);
        }
        for (AggroBehavior ab : attackBehaviors) {
            ab.init(myApp, entity, spatial);
        }
    }

    private void fireLosUpdate(float tpf, Spatial target) {
        for (AggroBehavior ab : losBehaviors) {
            ab.update(tpf, target, hasAttackAggro && attackBehaviors.length > 0);
        }
    }

    private void fireAttackUpdate(float tpf, Spatial target) {
        for (AggroBehavior ab : attackBehaviors) {
            ab.update(tpf, target, hasLosAggro && losBehaviors.length > 0);
        }
    }

    private void fireLosOnAggro(Spatial target) {
        for (AggroBehavior ab : losBehaviors) {
            ab.onAggro(target);
        }
    }

    private void fireAttackOnAggro(Spatial target) {
        for (AggroBehavior ab : attackBehaviors) {
            ab.onAggro(target);
        }
    }

    private void fireLosAggroLoss() {
        for (AggroBehavior ab : losBehaviors) {
            ab.onAggroLoss();
        }
    }

    private void fireAttackAggroLoss() {
        for (AggroBehavior ab : attackBehaviors) {
            ab.onAggroLoss();
        }
    }

    public void collision(PhysicsCollisionEvent event) {
        if (spatial == null || event.getNodeA() == null || event.getNodeB() == null) {
            return;
        }

        PhysicsCollisionObject object = null;
        Spatial target = null;
        if (event.getNodeA().equals(spatial)) {
            object = event.getObjectA();
            target = event.getNodeB();
        }
        if (event.getNodeB().equals(spatial)) {
            object = event.getObjectB();
            target = event.getNodeA();
        }
        if (object != null && target != null && object.equals(losGhost)) {
            hasLosAggro = true;
            losTarget = target;
        } else if (object != null && target != null && object.equals(attackGhost)) {
            hasAttackAggro = true;
            attackTarget = target;
        }
    }

    public void prePhysicsTick(PhysicsSpace space, float tpf) {
        hasLosAggro = false;
        hasAttackAggro = false;
    }

    public void physicsTick(PhysicsSpace space, float tpf) {
    }

    @Override
    public void cleanup() {
        spatial.removeControl(losGhost);

        myApp.getBulletAppState().getPhysicsSpace().removeCollisionListener(this);

        myApp.getBulletAppState().getPhysicsSpace().remove(losGhost);
        spatial.removeControl(attackGhost);
        myApp.getBulletAppState().getPhysicsSpace().remove(attackGhost);

        spatial.removeControl(this);
    }
}
TOP

Related Classes of com.teamjmonkey.controls.AggroControl

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.