Skip to content

Commit

Permalink
Initial commit of exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
phrack committed Feb 27, 2016
1 parent e1aa751 commit 7f7214a
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/bin/
19 changes: 19 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apply plugin: 'java'
apply plugin: 'eclipse'

eclipse {
jdt {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}

repositories {
flatDir {
dirs 'libs'
}
}

dependencies {
compile name: 'ShootOFF'
}
156 changes: 156 additions & 0 deletions src/main/java/com/shootoff/plugins/PistolIsometrics.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package com.shootoff.plugins;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.shootoff.camera.Shot;
import com.shootoff.gui.Hit;
import com.shootoff.util.NamedThreadFactory;

import javafx.scene.Group;

public class PistolIsometrics extends TrainingExerciseBase implements TrainingExercise {
private static final int START_DELAY = 5; // s
private static final int NOTICE_INTERVAL = 30; // s
private static final int CORE_POOL_SIZE = 4;
private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(CORE_POOL_SIZE,
new NamedThreadFactory("PistolIsometricsExercise"));
private boolean repeatExercise = true;
private TrainingExerciseBase api;

public PistolIsometrics() {}

public PistolIsometrics(List<Group> targets) {
super(targets);
api = super.getInstance();
}

@Override
public ExerciseMetadata getInfo() {
return new ExerciseMetadata("Pistol Isometrics", "1.0", "phrack",
"This exercise walks you through hold exercises to strengthen "
+ "arm and hand muscles that help you shoot a pistol accurately. "
+ "You will be asked to shoot, then you must shoot until you hit "
+ "any target. Once you hit a target, hold your exact position for "
+ "60 seconds. The exercise will tell you how much longer there is "
+ "every 30 seconds. After you've held for 60 seconds, you will "
+ "get two minutes to rest before you must fire again.");
}

@Override
public void init() {
startRound();
}

private void startRound() {
super.pauseShotDetection(true);
// Standard sound file shipped with ShootOFF
playSound(new File("sounds/voice/shootoff-makeready.wav"));

executorService.schedule(new Fire(), START_DELAY, TimeUnit.SECONDS);
}

/*
* Load a sound file from the exercise's JAR file into a
* BufferedInputStream. This specific type of stream is required to play
* audio.
*/
private InputStream getSoundStream(String soundResource) {
return new BufferedInputStream(PistolIsometrics.class.getResourceAsStream(soundResource));
}

private class Fire implements Runnable {
@Override
public void run() {
if (!repeatExercise) return;

api.pauseShotDetection(false);

InputStream fire = getSoundStream("/sounds/fire.wav");
TrainingExerciseBase.playSound(fire);
}
}

private class TimeNotice implements Runnable {
private int timeLeft;
private boolean justShot;

public TimeNotice(int timeLeft, boolean justShot) {
this.timeLeft = timeLeft;
this.justShot = justShot;
}

@Override
public void run() {
if (!repeatExercise) return;

InputStream notice;

switch (timeLeft) {
case 30:
notice = getSoundStream("/sounds/30remaining.wav");
break;

case 60:
notice = getSoundStream("/sounds/60remaining.wav");
break;

case 90:
notice = getSoundStream("/sounds/90remaining.wav");
break;

default: // happens when timeLeft = 0 in this
if (justShot) {
notice = getSoundStream("/sounds/relax120.wav");
timeLeft = 120;
justShot = false;
} else {
notice = getSoundStream("/sounds/congrats-complete.wav");
executorService.schedule(() -> startRound(), START_DELAY, TimeUnit.SECONDS);
}
}

TrainingExerciseBase.playSound(notice);
executorService.schedule(new TimeNotice(timeLeft - NOTICE_INTERVAL, justShot), NOTICE_INTERVAL,
TimeUnit.SECONDS);
}
}

@Override
public void reset(List<Group> targets) {
repeatExercise = false;
executorService.shutdownNow();

repeatExercise = true;
executorService = Executors.newScheduledThreadPool(CORE_POOL_SIZE,
new NamedThreadFactory("PistolIsometricsExercise"));
startRound();
}

@Override
public void shotListener(Shot shot, Optional<Hit> hit) {
if (!hit.isPresent()) {
new Fire().run();
} else {
super.pauseShotDetection(true);

InputStream hold = getSoundStream("/sounds/hold60.wav");
TrainingExerciseBase.playSound(hold);

executorService.schedule(new TimeNotice(30, true), NOTICE_INTERVAL, TimeUnit.SECONDS);
}
}

@Override
public void destroy() {
repeatExercise = false;
executorService.shutdownNow();
super.destroy();
}
}
2 changes: 2 additions & 0 deletions src/main/resources/shootoff.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<shootoffExercise exerciseClass="com.shootoff.plugins.PistolIsometrics" />
Binary file added src/main/resources/sounds/30remaining.wav
Binary file not shown.
Binary file added src/main/resources/sounds/60remaining.wav
Binary file not shown.
Binary file added src/main/resources/sounds/90remaining.wav
Binary file not shown.
Binary file added src/main/resources/sounds/congrats-complete.wav
Binary file not shown.
Binary file added src/main/resources/sounds/fire.wav
Binary file not shown.
Binary file added src/main/resources/sounds/hold60.wav
Binary file not shown.
Binary file added src/main/resources/sounds/relax120.wav
Binary file not shown.

0 comments on commit 7f7214a

Please sign in to comment.