001package com.fs.starfarer.api.impl.campaign.eventide;
002
003public class DuelEnemyAIImpl implements DuelEnemyAI {
004
005        public static class WaitThenAct {
006                float delay;
007                String actionId;
008                public WaitThenAct(float delay, String actionId) {
009                        this.delay = delay;
010                        this.actionId = actionId;
011                }
012        }
013        
014        
015        public float initialDelay = 1f;
016        public float moveDelay = 0f;
017        public WaitThenAct next;
018        public float recentBlocks = 0;
019        public float noBlockDur = 0f;
020        
021        public DuelEnemyAIImpl() {
022                
023        }
024        
025        
026        public void advance(float amount, DuelPanel duel) {
027                Actor actor = duel.enemy;
028                Actor opponent = duel.player;
029                
030                if (opponent.health <= 0) return;
031                
032                initialDelay -= amount;
033                if (initialDelay > 0) return;
034                
035                recentBlocks -= amount * 0.25f;
036                if (recentBlocks < 0) recentBlocks = 0;
037                
038                moveDelay -= amount;
039                if (moveDelay < 0) moveDelay = 0;
040                noBlockDur -= amount;
041                if (noBlockDur < 0) noBlockDur = 0;
042                
043                if (next != null) {
044                        next.delay -= amount;
045                        if (next.delay <= 0) {
046                                actor.doAction(next.actionId, false);
047                                next = null;
048                        }
049                        return;
050                }
051        
052                //float attackRange = 165;
053                float attackRange = 142;
054                float tooCloseRange = 50;
055                float waitRange = attackRange + 50;
056                
057                float dist = duel.getDistance();
058                
059                boolean actorAttacking = actor.currAction != null && actor.currAction.anim.hasAttackFrames() &&
060                                                        !actor.currAction.scoredHit && !actor.currAction.wasBlocked;  
061                boolean actorBlocking = actor.currAction != null && actor.currAction.anim.hasBlockFrames() &&
062                                                        !actor.currAction.performedBlock;
063                if (actor.nextAction != null && actor.nextAction.anim.hasBlockFrames()) {
064                        actorBlocking = true;
065                }
066                
067                boolean actorPerformedBlock = actor.currAction != null && actor.currAction.performedBlock;  
068                boolean opponentAttacking = opponent.currAction != null && opponent.currAction.anim.hasAttackFrames() &&
069                                                        !opponent.currAction.scoredHit && !opponent.currAction.wasBlocked;  
070                boolean opponentBlocking = opponent.currAction != null && opponent.currAction.anim.hasBlockFrames() &&
071                                                        !opponent.currAction.performedBlock;
072                
073                if (actorBlocking || actorAttacking) return;
074                
075                boolean blockOnlyMode = false;
076                boolean allowAttack = true;
077        //      blockOnlyMode = true;
078        //      allowAttack = false;
079                
080                if (opponentAttacking && dist < attackRange + 10 && opponent.currAction.framesUntilAttackFrame() < 4) {
081                        if (noBlockDur > 0) return;
082                        
083                        if (1f + (float) Math.random() * 4f < recentBlocks) {
084                                noBlockDur = 0.5f + (float) Math.random() * 0.2f;
085                                if (!blockOnlyMode) {
086                                        actor.doAction(Actions.MOVE_BACK, false);
087                                        next = new WaitThenAct(0.1f, Actions.MOVE_BACK);
088                                }
089                                return;
090                        }
091                        //next = new WaitThenAct(0.1f + (float) Math.random() * 0.1f, Actions.BLOCK_LOW);
092                        float delay = 0.2f * (float) Math.random();
093                        //delay = 0f;
094                        //delay += (float) Math.random() * Math.min(0.2f, recentBlocks * 0.1f);
095                        next = new WaitThenAct(delay, Actions.BLOCK);
096                        recentBlocks++;
097                        if (blockOnlyMode) recentBlocks = 0;
098                        if (recentBlocks > 4f) recentBlocks = 4f;
099                        return;
100                }
101                
102                if (opponentAttacking) {
103                        return;
104                }
105                
106                if (actorPerformedBlock) {
107                        moveDelay = 0.1f + (float) Math.random() * 0.05f;
108                        //moveDelay = 0.1f;
109                        //moveDelay = 0f;
110                        return;
111                }
112                
113                if (moveDelay <= 0 && !blockOnlyMode) {
114                        if (dist > waitRange) {
115                                actor.doAction(Actions.MOVE_FORWARD, false);
116                                moveDelay = 0.3f + (float) Math.random() * 0.2f;
117                                return;
118                        } else if (dist > attackRange) {
119                                actor.doAction(Actions.MOVE_FORWARD, false);
120                                moveDelay = 0.3f + (float) Math.random() * 0.2f;
121                                return;
122                        }
123                }
124                
125                if ((dist < attackRange || actorPerformedBlock) && moveDelay <= 0 && (!blockOnlyMode || allowAttack)) {
126                        actor.doAction(Actions.ATTACK, false);
127                        moveDelay = 0.1f + (float) Math.random() * 2f;
128                        //next = new WaitThenAct((float) Math.random() * 0.1f, Actions.ATTACK_HIGH);
129                        return;
130                }
131                
132                //if (true) return;
133//              if (dist < tooCloseRange && !opponentAttacking) {
134//                      
135//              }
136                
137                
138//              if (opponentAttacking && !actorBlocking) {
139//                      actor.doAction(Actions.BLOCK_LOW, false);
140//                      //moveDelay = 0.4f;
141//              } else {
142
143//              else if (moveDelay <= 0) {
144//                      actor.doAction(Actions.ATTACK_HIGH, false);
145//                      moveDelay = 0.5f;
146//              }
147                
148                //System.out.println("Dist: " + dist);
149                
150        }
151        
152        public void render(float alphaMult) {
153                
154        }
155}