Starsector API
Loading...
Searching...
No Matches
DuelPanel.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.eventide;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.Iterator;
6import java.util.List;
7
8import org.lwjgl.input.Keyboard;
9import org.lwjgl.opengl.GL11;
10import org.lwjgl.util.vector.Vector2f;
11
12import com.fs.starfarer.api.Global;
13import com.fs.starfarer.api.campaign.BaseCustomUIPanelPlugin;
14import com.fs.starfarer.api.campaign.CustomVisualDialogDelegate.DialogCallbacks;
15import com.fs.starfarer.api.campaign.InteractionDialogAPI;
16import com.fs.starfarer.api.input.InputEventAPI;
17import com.fs.starfarer.api.ui.CustomPanelAPI;
18import com.fs.starfarer.api.ui.PositionAPI;
19import com.fs.starfarer.api.util.FaderUtil;
20import com.fs.starfarer.api.util.Misc;
21
22public class DuelPanel extends BaseCustomUIPanelPlugin {
23
24 public static enum AttackResult {
25 NO_HIT,
26 BLOCK,
27 HIT,
28 }
29
30 public static float SOUND_LOC_MULT = 0.25f;
31
32 public static boolean DEBUG = true;
33
34
35 protected InteractionDialogAPI dialog;
36 protected DialogCallbacks callbacks;
37 protected CustomPanelAPI panel;
38 protected PositionAPI p;
39
40 protected Actor player;
41 protected Actor enemy;
42 protected List<QuadParticles> particles = new ArrayList<QuadParticles>();
43 protected float floorLevel;
44 protected float leftBorder, rightBorder;
45 protected float viewAreaWidth = 512;
46 protected DuelEnemyAI ai;
48
49 protected boolean tutorialMode = false;
51
52 protected FaderUtil blinker = new FaderUtil(0f, 0.25f, 0.25f, true, true);
53 protected String ambienceLoopId = null;
54
55 public static DuelPanel createDefault(boolean playerSkilled, boolean enemySkilled, String ambienceLoopId) {
57 //playerSkilled = false;
58
59 Actor player = createActor(Actions.TEX, playerSkilled);
60// player.actionRemap1.put(Actions.IDLE, Actions.IDLE_HIGH);
61// player.actionRemap1.put(Actions.MOVE_FORWARD, Actions.MOVE_FORWARD_HIGH);
62// player.actionRemap1.put(Actions.MOVE_BACK, Actions.MOVE_BACK_HIGH);
63// player.actionRemap1.put(Actions.ATTACK, Actions.ATTACK_HIGH);
64// player.actionRemap1.put(Actions.BLOCK, Actions.BLOCK_LOW);
65 //player.actionRemap1.put(Actions.ATTACK, Actions.RIPOSTE_HIGH);
66
67// player.actionRemap1.put(Actions.BLOCK, Actions.ATTACK_RECOVERY);
68// player.actionRemap1.put(Actions.BLOCK, Actions.ATTACK_HIGH_RECOVERY);
69 //player.actionRemap1.put(Actions.ATTACK, Actions.ATTACK_HIGH);
70 //player.actionRemap1.put(Actions.ATTACK, Actions.ATTACK_RECOVERY);
71 //player.actionRemap1.put(Actions.BLOCK, Actions.BLOCK_LOW);
72 //player.actionRemap1.put(Actions.BLOCK, Actions.ATTACK_HIGH_RECOVERY);
73// player.actionRemap1.put(Actions.ATTACK, Actions.BLOCK_LOW);
74// player.actionRemap1.put(Actions.BLOCK, Actions.FALL);
75// player.actionRemap1.put(Actions.BLOCK, Actions.BLOCK_LOW);
76 //player.actionRemap1.put(Actions.ATTACK, Actions.ATTACK_HIGH);
77 //player.actionRemap1.put(Actions.ATTACK, Actions.ATTACK_RECOVERY);
78// player.actionRemap1.put(Actions.RIPOSTE, Actions.RIPOSTE_HIGH);
79// player.actionRemap1.put(Actions.IDLE, Actions.IDLE_HIGH);
80// player.actionRemap1.put(Actions.MOVE_FORWARD, Actions.MOVE_FORWARD_HIGH);
81
82 Actor enemy = createActor(Actions.TEX, enemySkilled);
90
93 //panel = new DuelPanel(player, enemy, null, bg); // this turns off enemy AI!!!
94// DO_CYCLE = true; // do block - attack - recover cycle automatically w/ no interaction
95// DO_CYCLE_HIGH = true; // do the enemy cycle, on the player actor
96 DO_CYCLE = false;
97 DO_CYCLE_HIGH = false;
98
99 panel.ambienceLoopId = ambienceLoopId;
100
101 return panel;
102 }
103
104 public static DuelPanel createTutorial(boolean playerSkilled, String ambienceLoopId) {
106
107 Actor player = createActor(Actions.TEX, playerSkilled);
108
110
112 DuelPanel panel = new DuelPanel(player, enemy, null, bg);
113 panel.tutorialMode = true;
114 panel.ambienceLoopId = ambienceLoopId;
115 return panel;
116 }
117
118 public static Actor createActor(String tex, boolean skilled) {
119 Actor actor = new Actor(tex);
120 int health = 5;
121 if (!skilled) {
122 health = 3;
125// float speedMult = 0.8f;
126// actor.actionSpeedMult.put(Actions.ATTACK, speedMult);
127// actor.actionSpeedMult.put(Actions.ATTACK_HIGH, speedMult);
128// actor.actionSpeedMult.put(Actions.BLOCK, speedMult);
129// actor.actionSpeedMult.put(Actions.BLOCK_LOW, speedMult);
130 }
131
132 //health = 15;
133 actor.maxHealth = health;
134 actor.health = health;
135 return actor;
136 }
137
138
140 this.player = player;
141 this.enemy = enemy;
142 this.ai = ai;
143 this.background = background;
144 }
145
146 public void init(CustomPanelAPI panel, DialogCallbacks callbacks, InteractionDialogAPI dialog) {
147 this.panel = panel;
148 this.callbacks = callbacks;
149 this.dialog = dialog;
150
151// Actions.initActions();
152// player = new Actor();
153// enemy = new Actor();
154
155 blinker.fadeIn();
156
157 if (tutorialMode) {
159 CustomPanelAPI p = panel.createCustomPanel(450, 120, prompt);
160 panel.addComponent(p).inTL(10, 30);
162 }
163 }
164
165 public CustomPanelAPI getPanel() {
166 return panel;
167 }
168
169 public PositionAPI getPosition() {
170 return p;
171 }
172
173 public float getFloorLevel() {
174 return floorLevel;
175 }
176
177 protected float desiredViewCenterX = 0f;
178 protected float viewCenterX = 0f;
179 public void positionChanged(PositionAPI position) {
180 this.p = position;
181
182 if (player != null) {
183 float cx = p.getCenterX();
184 float cy = p.getCenterY();
185
186
187 float charHeight = getCharacterHeight();
188
189 floorLevel = (int)(cy - charHeight/2f);
190 leftBorder = (int)(cx - p.getWidth() / 2f + 50);
191 rightBorder = (int)(cx + p.getWidth() / 2f - 50);
192
193 float width = background.getStageWidth();
194 float extra = width - p.getWidth();
195
196 leftBorder -= (int)(extra/2f);
197 rightBorder += (int)(extra/2f);
198
199 float down = 5f;
200 player.loc.set(cx - 200, floorLevel + charHeight/2f - down);
201 player.facing = 1;
202 enemy.loc.set(cx + 200, floorLevel + charHeight/2f - down);
203 enemy.facing = -1;
204
205 viewAreaWidth = 200f;
206 desiredViewCenterX = player.loc.x + viewAreaWidth / 2f - 50f;
208 }
209 }
210
211 public void render(float alphaMult) {
212
213 }
214
215 public void renderBelow(float alphaMult) {
216 //if (tutorialMode) return;
217 if (p == null) return;
218
219 float x = p.getX();
220 float y = p.getY();
221 float cx = p.getCenterX();
222 float cy = p.getCenterY();
223 float w = p.getWidth();
224 float h = p.getHeight();
225
226 GL11.glDisable(GL11.GL_TEXTURE_2D);
227 GL11.glEnable(GL11.GL_SCISSOR_TEST);
228
230 GL11.glScissor((int)(x * s), (int)(y * s), (int)(w * s), (int)(h * s));
231
232// SpriteAPI s = Global.getSettings().getSprite(TEX);
233// s.render(x, y + h - s.getHeight());
234 DEBUG = true;
235 DEBUG = false;
236
237 if (DEBUG && false) {
238 float w2 = player.currAction.curr.width * player.currAction.anim.scale;
239 float h2 = player.currAction.curr.height * player.currAction.anim.scale;
240 Misc.renderQuad(player.loc.x - w2/2f, player.loc.y - h2/2f, w2, h2, new Color(50,50,50,255), alphaMult);
241 }
242
243 float centerX = player.loc.x - (desiredViewCenterX - cx);
244 if (player.currAction != null && player.currAction.anim != null &&
246 centerX = cx;
247 } else if (player.currAction != null && player.currAction.anim != null && player.currAction.curr != null) {
248 if (!player.currAction.curr.hittableArea.isEmpty()) {
250 centerX = player.loc.x + (area.x + area.w / 2f) - (desiredViewCenterX - cx);
251 }
252 }
253 float leftX = cx - viewAreaWidth / 2f;
254 float rightX = cx + viewAreaWidth / 2f;
255
256 //System.out.println("[" + leftX + ", " + rightX + "] centerX: " + centerX + ", prev: " + prevOffsetX);
257
258 if (centerX < leftX) {
259 desiredViewCenterX -= leftX - centerX + 100f;
260 } else if (centerX > rightX) {
261 desiredViewCenterX += centerX - rightX + 100f;
262 }
263 float minVX = leftBorder + w / 2f - 50f;
264 float maxVX = rightBorder - w / 2f + 50f;
265 if (desiredViewCenterX < minVX) desiredViewCenterX = minVX;
266 if (desiredViewCenterX > maxVX) desiredViewCenterX = maxVX;
267
268 float offsetX = -(viewCenterX - cx);
269
270 if (background == null) {
271 GL11.glDisable(GL11.GL_TEXTURE_2D);
272 Misc.renderQuad(x, y, w, h, Color.black, alphaMult);
273 Misc.renderQuad(x, y, w, h, new Color(50,50,50,255), alphaMult);
274 } else {
275 background.render(this, offsetX, 0f, alphaMult);
276 }
277
278// GL11.glDisable(GL11.GL_TEXTURE_2D);
279// Misc.renderQuad(leftX, y, 5, h, Color.black, alphaMult);
280// Misc.renderQuad(rightX, y, 5, h, Color.black, alphaMult);
281// Misc.renderQuad(centerX, y, 5, h, Color.green, alphaMult);
282
283 GL11.glPushMatrix();
284 GL11.glTranslatef(offsetX, 0, 0);
285// Misc.renderQuad(leftBorder, y, 5, h, Color.red, alphaMult);
286// Misc.renderQuad(rightBorder - 5, y, 5, h, Color.red, alphaMult);
287
288 for (QuadParticles p : particles) {
289 p.render(alphaMult, true);
290 }
291
292 if (enemy.health > 0 && player.health > 0) {
293 boolean playerAttack = player.currAction != null && player.currAction.anim != null &&
295 if (playerAttack) {
296 if (!tutorialMode) enemy.render(alphaMult);
297 player.render(alphaMult);
298 } else {
299 player.render(alphaMult);
300 if (!tutorialMode) enemy.render(alphaMult);
301 }
302 } else if (enemy.health > 0) {
303 player.render(alphaMult);
304 if (!tutorialMode) enemy.render(alphaMult);
305 } else {
306 if (!tutorialMode) enemy.render(alphaMult);
307 player.render(alphaMult);
308 }
309
310 for (QuadParticles p : particles) {
311 p.render(alphaMult, false);
312 }
313 GL11.glPopMatrix();
314
315 if (background != null) {
316 background.renderForeground(this, offsetX, 0f, alphaMult);
317 }
318
319 renderHealth(alphaMult);
320
321 if (ai != null) {
322 ai.render(alphaMult);
323 }
324
325 GL11.glDisable(GL11.GL_SCISSOR_TEST);
326 }
327
328 public void renderHealth(float alphaMult) {
329 float x = p.getX();
330 float y = p.getY();
331 float w = p.getWidth();
332 float h = p.getHeight();
333
334 float pipW = 20f;
335 float pipH = 20f / 1.6f;
336 float pad = 3f;
337 float opad = 10f;
338
339 GL11.glDisable(GL11.GL_TEXTURE_2D);
340 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
341
342 for (int i = 0; i < player.maxHealth; i++) {
343 boolean filled = i < player.health;
344 if (player.health == 1 && i == 0 && blinker.isFadingIn()) filled = false;
345 renderPip(x + opad + (pipW + pad) * i, y + h - opad - pipH,
346 pipW, pipH, Misc.getPositiveHighlightColor(), alphaMult,
347 filled);
348 }
349
350 if (!tutorialMode) {
351 for (int i = enemy.maxHealth - 1; i >= 0; i--) {
352 renderPip(x + w - opad - (pipW + pad) * (i + 1), y + h - opad - pipH,
353 pipW, pipH, Misc.getNegativeHighlightColor(), alphaMult,
354 i < enemy.health);
355 }
356 }
357 }
358
359 public void renderPip(float x, float y, float w, float h, Color c, float a, boolean filled) {
360 if (filled) {
361 Misc.renderQuad(x, y, w, h, c, a);
362 } else {
363 Misc.renderQuad(x, y, w, 1, c, a);
364 Misc.renderQuad(x, y + h - 1, w, 1, c, a);
365 Misc.renderQuad(x, y + 1, 1, h - 2, c, a);
366 Misc.renderQuad(x + w - 1, y + 1, 1, h - 2, c, a);
367 }
368 Misc.renderQuad(x + w, y - 1, 1, h, Color.black, a);
369 Misc.renderQuad(x + 1, y - 1, w - 1, 1, Color.black, a);
370
371 }
372
373 public static boolean DO_CYCLE = false;
374 public static boolean DO_CYCLE_HIGH = false;
375 public int cycleIndex = -1;
376 public static List<String> cycle = new ArrayList<String>();
377 static {
378 cycle.add(Actions.BLOCK);
379 cycle.add(Actions.ATTACK);
381 }
382 public static List<String> cycleHigh = new ArrayList<String>();
383 static {
387 }
388
389 public void advance(float amount) {
390 if (p == null) return;
391 if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && Global.getSettings().isDevMode()) {
392 amount *= 0.25f;
393 }
394 if (tutorialMode) {
395 panel.bringComponentToTop(prompt.getPanel());
396 }
397 //amount *= 0.5f;
398 //System.out.println(player.loc.x);
399
400 viewCenterX = Misc.approach(viewCenterX, desiredViewCenterX, 3f, 1f, amount);
401 //Global.getSoundPlayer().setListenerPosOverrideOneFrame(new Vector2f(viewCenterX * 0f, player.loc.y));
402 float soundOffset = viewCenterX - player.loc.x;
403 soundOffset *= SOUND_LOC_MULT;
405 new Vector2f(soundOffset + (player.loc.x + enemy.loc.x)/2f * SOUND_LOC_MULT, player.loc.y));
406 //System.out.println("VCX " + viewCenterX + ", playerLoc: " + player.loc.x);
407
408 if (ambienceLoopId != null) {
410 }
411
412 if (background != null) {
413 background.advance(amount);
414 }
415
416 if (DO_CYCLE || DO_CYCLE_HIGH) {
417 amount *= 1f;// 0.25f;
418 if (player.getActionId() != null && (player.getActionId().equals(Actions.ATTACK) ||
420 float timeUntilAttack = 0f;
422 if (!f.attackArea.isEmpty()) break;
423 timeUntilAttack += f.dur;
424 }
425 //if (player.currAction.framesUntilAttackFrame() <= 1) {
426 if (timeUntilAttack <= player.currAction.progress + 0.05f) {
427 player.currAction = null;
428 }
429 }
430 if (player.getActionId().isEmpty() || player.getActionId().equals(Actions.IDLE) ||
432 cycleIndex++;
433 if (cycleIndex < 0) cycleIndex = 0;
434 if (DO_CYCLE_HIGH) {
437 } else {
438 cycleIndex = cycleIndex % cycle.size();
439 player.doAction(cycle.get(cycleIndex), true);
440 }
441 }
442 }
443
444 //amount *= 0.2f;
445 blinker.advance(amount * 1.5f);
446
447 Iterator<QuadParticles> iter = particles.iterator();
448 while (iter.hasNext()) {
449 QuadParticles curr = iter.next();
450 curr.advance(amount);
451 if (curr.isDone()) {
452 iter.remove();
453 }
454 }
455 player.advance(amount);
456 enemy.advance(amount);
457
458 if (!tutorialMode) {
459 if (player.loc.x - 100 > enemy.loc.x) {
460 player.facing = -1f;
461 enemy.facing = 1f;
462 } else if (player.loc.x + 100 < enemy.loc.x){
463 player.facing = 1f;
464 enemy.facing = -1f;
465 }
466 }
467
468 float minDist = 40;
469 //minDist = 100;
470 if (getDistance() < minDist && player.health > 0 && enemy.health > 0 && !tutorialMode) {
473 } else {
474// if (player.loc.x < leftBorder || player.loc.x > rightBorder) {
475// player.doAction(Actions.MOVE_FORWARD, true);
476// }
477// if (enemy.loc.x < leftBorder || enemy.loc.x > rightBorder) {
478// enemy.doAction(Actions.MOVE_FORWARD, true);
479// }
480 if (player.loc.x < leftBorder) {
481 player.loc.x = leftBorder;
482 }
483 if (player.loc.x > rightBorder) {
484 player.loc.x = rightBorder;
485 }
486 if (enemy.loc.x < leftBorder) {
487 enemy.loc.x = leftBorder;
488 }
489 if (enemy.loc.x > rightBorder) {
490 enemy.loc.x = rightBorder;
491 }
492 }
493
495
496 doAI(amount);
497 }
498
499 public float getDistance() {
500 return Math.abs(player.loc.x - enemy.loc.x);
501 }
502
503 protected boolean prevWasAttack;
504
505 public void doAI(float amount) {
506 if (ai != null) {
507 ai.advance(amount, this);
508 }
509// if (enemy.currAction != null && enemy.currAction.anim.action == Actions.IDLE) {
510// //float r = (float) Math.random();
511// //System.out.println("PICKING " + rand);
512// if (prevWasAttack) {
513// //enemy.doAction(Actions.BLOCK, false);
514// enemy.doAction(Actions.ATTACK, false);
515// prevWasAttack = false;
516// } else {
517// enemy.doAction(Actions.ATTACK, false);
518// prevWasAttack = true;
519// }
525// }
526 }
527
528
529 public void processInput(List<InputEventAPI> events) {
530 if (p == null) return;
531
532 for (InputEventAPI event : events) {
533 if (event.isConsumed()) continue;
535 event.isKeyDownEvent() && event.getEventValue() == Keyboard.KEY_ESCAPE) {
536 event.consume();
537 callbacks.dismissDialog();
538 return;
539 }
540
541 if (event.isKeyDownEvent() &&
542 (event.getEventValue() == Keyboard.KEY_UP ||
543 event.getEventValue() == Keyboard.KEY_NUMPAD8 ||
544 event.getEventValue() == Keyboard.KEY_W)) {
545 event.consume();
548 continue;
549 }
550 if (event.isKeyDownEvent() &&
551 (event.getEventValue() == Keyboard.KEY_LEFT ||
552 event.getEventValue() == Keyboard.KEY_NUMPAD4 ||
553 event.getEventValue() == Keyboard.KEY_A)) {
554 event.consume();
555 if (player.facing > 0) {
558 } else {
561 }
562 continue;
563 }
564 if (event.isKeyDownEvent() &&
565 (event.getEventValue() == Keyboard.KEY_RIGHT ||
566 event.getEventValue() == Keyboard.KEY_NUMPAD6 ||
567 event.getEventValue() == Keyboard.KEY_D)) {
568 event.consume();
569 if (player.facing > 0) {
572 } else {
575 }
576 continue;
577 }
578 if (event.isKeyDownEvent() &&
579 event.getEventValue() == Keyboard.KEY_SPACE) {
580 event.consume();
583 continue;
584 }
585 if (Global.getSettings().isDevMode() && event.isKeyDownEvent() &&
586 event.getEventValue() == Keyboard.KEY_F) {
587 event.consume();
589
590 //wasHit(player, null);
591 //wasHit(enemy, null);
592 continue;
593 }
594 if (event.isKeyDownEvent() &&
595 event.getEventValue() == Keyboard.KEY_G) {
596 event.consume();
598 continue;
599 }
600 }
601 }
602
603 public void checkBlocksAndHits() {
604 if (tutorialMode) return;
605
606 AttackResult playerAttackResult = checkAttackVsDefense(player, enemy);
607 AttackResult enemyAttackResult = checkAttackVsDefense(enemy, player);
608
609 if (playerAttackResult == AttackResult.HIT && enemyAttackResult == AttackResult.HIT) {
610 if ((float) Math.random() < 0.5f) {
611 playerAttackResult = AttackResult.NO_HIT;
612 } else {
613 enemyAttackResult = AttackResult.NO_HIT;
614 }
615 }
616
617 if (playerAttackResult == AttackResult.BLOCK) {
619 player.currAction.wasBlocked = true;
621 enemy.currAction.performedBlock = true;
623 //enemy.endCurrentAnimation();
624 } else if (playerAttackResult == AttackResult.HIT) {
626 player.currAction.scoredHit = true;
627 }
628
629 if (enemyAttackResult == AttackResult.BLOCK) {
631 enemy.currAction.wasBlocked = true;
633 player.currAction.performedBlock = true;
635 //player.endCurrentAnimation();
636 } else if (enemyAttackResult == AttackResult.HIT) {
638 enemy.currAction.scoredHit = true;
639 }
640 }
641
642 public AttackResult checkAttackVsDefense(Actor attacker, Actor defender) {
643 AnimAction a = attacker.currAction;
644 AnimAction d = defender.currAction;
645 if (a.curr == null || a.curr.attackArea.isEmpty()) return AttackResult.NO_HIT;
646 if (d.curr == null || d.curr.hittableArea.isEmpty()) return AttackResult.NO_HIT;
647
648 if (a.wasBlocked) return AttackResult.NO_HIT;
649 if (a.scoredHit) return AttackResult.NO_HIT;
650
651 for (HitArea attack : a.curr.attackArea) {
652 attack = attack.getAdjustedForAction(a);
653 for (HitArea block : d.curr.blockArea) {
654 block = block.getAdjustedForAction(d);
655 if (attack.intersects(block)) {
656 return AttackResult.BLOCK;
657 }
658 }
659 }
660
661 for (HitArea attack : a.curr.attackArea) {
662 attack = attack.getAdjustedForAction(a);
663 for (HitArea hit : d.curr.hittableArea) {
664 hit = hit.getAdjustedForAction(d);
665 if (attack.intersects(hit)) {
666 return AttackResult.HIT;
667 }
668 }
669 }
670
671 return AttackResult.NO_HIT;
672 }
673
674 public void addSparks(Actor attacker, Actor defender) {
675 //Global.getSoundPlayer().playUISound(Actions.SOUND_CLASH, 1f, 1f);
676 if (true) {
677// attacker.freeze(0.1f);
678// defender.freeze(0.1f);
679// attacker.freeze(1.9f);
680// defender.freeze(1.9f);
681 return;
682 }
684 p.additiveBlend = true;
685 p.minDur = 0.1f;
686 p.maxDur = 0.3f;
687 p.minSize = 1f;
688 p.maxSize = 2f;
689 p.fadeTime = 0.1f;
690 p.minColor = new Color(255, 200, 100, 155);
691 p.maxColor = new Color(255, 255, 150, 255);
692
693
694 Vector2f loc = Vector2f.add(attacker.loc, defender.loc, new Vector2f());
695 loc.scale(0.5f);
696 loc.y += getCharacterHeight() * 0.18f;
697
698 AnimAction block = defender.currAction;
699
700 if (block != null && block.curr != null) {
701 if (!block.curr.blockArea.isEmpty()) {
702 HitArea area = block.curr.blockArea.get(0);
703 area = area.getAdjustedForAction(block);
704 Vector2f loc2 = new Vector2f(loc);
705 loc2.x = area.x + area.w / 2f + block.actor.facing * area.w * 0.25f;
706 float dist1 = Misc.getDistance(defender.loc, loc);
707 float dist2 = Misc.getDistance(defender.loc, loc2);
708 // if the "in between" location is farther than the one in the block area, use the block area
709 // otherwise opponents are close, use in-between location
710 if (dist1 > dist2) {
711 loc.set(loc2);
712 }
713 }
714 }
715
716 int num = 30 + Misc.random.nextInt(10);
717 for (int i = 0; i < num; i++) {
718 Vector2f pos = Misc.getPointWithinRadius(loc, 5f);
719 Vector2f vel = Misc.getPointWithinRadius(new Vector2f(), 200f);
720 p.addParticle(pos.x, pos.y, vel.x, vel.y);
721 }
722
723 p.gravity = getGravity() * 0.1f;
724
725 particles.add(p);
726 }
727
728
729 public void wasHit(Actor actor, Actor by) {
730 int damage = 1;
731 if (by != null && by.currAction != null && by.currAction.curr != null) {
732 damage = by.currAction.curr.hitDamage;
733 }
734 //damage = 0;
735 actor.health -= damage;
736 if (actor.health > 0) {
737 actor.doAction(Actions.GOT_HIT, true);
738 } else {
739 actor.doAction(Actions.FALL, true);
740 }
741 addBlood(actor);
742 }
743 public void addBlood(Actor actor) {
744 Vector2f loc = new Vector2f(actor.loc);
745 //loc.y += 3f * player.currAction.anim.scale;
746 loc.y += getCharacterHeight() * 0.07f;
747 addBlood(loc, actor);
748 }
749 public void addBlood(Vector2f loc, Actor actor) {
750// if (true) {
751// actor.freeze(1.9f);
752// return;
753// }
754 //Global.getSoundPlayer().playUISound(Actions.SOUND_RIP, 1f, 1f);
755
757 p.minDur = 5f;
758 p.maxDur = 8f;
759 p.minSize = 2f;
760 p.maxSize = 3f;
761 p.fadeTime = 3f;
762 p.minColor = new Color(136, 8, 8, 155);
763 p.maxColor = new Color(238, 75, 43, 255);
764 //p.maxFloorMod = 7f;
765 p.maxFloorMod = 30f;
766
767 int base = 100;
768 base -= actor.health * 15;
769 if (base < 20) base = 20;
770 //base = 20;
771 int num = base + Misc.random.nextInt((int) (base * 0.5f));
772 num *= 2f;
773 for (int i = 0; i < num; i++) {
774 Vector2f pos = Misc.getPointWithinRadius(loc, 15f);
775 Vector2f vel = Misc.getPointWithinRadius(new Vector2f(), 150f);
776 p.addParticle(pos.x, pos.y, vel.x, vel.y);
777 }
778
779 p.gravity = getGravity();
780 p.floor = floorLevel - 10f;
781 p.floorFriction = 100f;
782 particles.add(p);
783 }
784
785
786 public float getGravity() {
787 // assume player is about 2m tall
788 float h = getCharacterHeight();
789 return h / 2f * 9.81f;
790 }
791
792 public float getCharacterHeight() {
794 return anim.frameHeight * anim.scale;
795 }
796
797 public Actor getPlayer() {
798 return player;
799 }
800
801 public Actor getEnemy() {
802 return enemy;
803 }
804
805
806}
807
808
809
static SettingsAPI getSettings()
Definition Global.java:51
static SoundPlayerAPI getSoundPlayer()
Definition Global.java:43
static Map< String, CharAnim > ANIMATIONS
Definition Actions.java:39
void doAction(String action, boolean forceInterruptCurrent)
Definition Actor.java:81
void processInput(List< InputEventAPI > events)
void init(CustomPanelAPI panel, DialogCallbacks callbacks, InteractionDialogAPI dialog)
static Actor createActor(String tex, boolean skilled)
static DuelPanel createTutorial(boolean playerSkilled, String ambienceLoopId)
void renderPip(float x, float y, float w, float h, Color c, float a, boolean filled)
void addSparks(Actor attacker, Actor defender)
static DuelPanel createDefault(boolean playerSkilled, boolean enemySkilled, String ambienceLoopId)
AttackResult checkAttackVsDefense(Actor attacker, Actor defender)
DuelPanel(Actor player, Actor enemy, DuelEnemyAI ai, DuelBackground background)
void init(CustomPanelAPI panel, DialogCallbacks callbacks, InteractionDialogAPI dialog)
HitArea getAdjustedForAction(AnimAction action)
Definition HitArea.java:15
void playUILoop(String id, float pitch, float volume)
void setListenerPosOverrideOneFrame(Vector2f listenerPosOverrideOneFrame)
void renderForeground(DuelPanel panel, float xOffset, float yOffset, float alphaMult)
void render(DuelPanel panel, float xOffset, float yOffset, float alphaMult)
void advance(float amount, DuelPanel duel)