8 Commits
v5 ... v5d
28 changed files with 168 additions and 217 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
/bin/ /bin/
/target/ /target/
/~local/
/.rogue-save/ /.rogue-save/
/build/.rogue-save/ /build/
/build/out/.rogue-save/
/build/out/*.jar /build/out/*.jar
/build/in/*.jar /build/in/*.jar
*.log *.log
Binary file not shown.
Binary file not shown.
@@ -15,20 +15,23 @@ import mightypork.gamecore.eventbus.event_flags.SingleReceiverEvent;
public class MainLoopRequest extends BusEvent<MainLoop> { public class MainLoopRequest extends BusEvent<MainLoop> {
private final Runnable task; private final Runnable task;
private final boolean priority;
/** /**
* @param task task to run on main thread in rendering context * @param task task to run on main thread in rendering context
* @param priority if true, skip other tasks in queue
*/ */
public MainLoopRequest(Runnable task) public MainLoopRequest(Runnable task, boolean priority)
{ {
this.task = task; this.task = task;
this.priority = priority;
} }
@Override @Override
public void handleBy(MainLoop handler) public void handleBy(MainLoop handler)
{ {
handler.queueTask(task); handler.queueTask(task, priority);
} }
} }
@@ -5,6 +5,7 @@ import mightypork.gamecore.core.modules.MainLoop;
import mightypork.gamecore.eventbus.BusEvent; import mightypork.gamecore.eventbus.BusEvent;
import mightypork.gamecore.eventbus.event_flags.NonConsumableEvent; import mightypork.gamecore.eventbus.event_flags.NonConsumableEvent;
import mightypork.gamecore.eventbus.event_flags.SingleReceiverEvent; import mightypork.gamecore.eventbus.event_flags.SingleReceiverEvent;
import mightypork.gamecore.resources.audio.SoundSystem;
/** /**
@@ -27,6 +28,6 @@ public class ShudownRequest extends BusEvent<MainLoop> {
{ {
handler.shutdown(); handler.shutdown();
} }
}); }, true);
} }
} }
@@ -1,14 +1,18 @@
package mightypork.gamecore.core.modules; package mightypork.gamecore.core.modules;
import java.util.Deque;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import mightypork.gamecore.eventbus.events.UpdateEvent; import mightypork.gamecore.eventbus.events.UpdateEvent;
import mightypork.gamecore.gui.screens.ScreenRegistry; import mightypork.gamecore.gui.screens.ScreenRegistry;
import mightypork.gamecore.logging.Log;
import mightypork.gamecore.render.Renderable; import mightypork.gamecore.render.Renderable;
import mightypork.gamecore.render.TaskTakeScreenshot; import mightypork.gamecore.render.TaskTakeScreenshot;
import mightypork.gamecore.render.events.ScreenshotRequestListener; import mightypork.gamecore.render.events.ScreenshotRequestListener;
import mightypork.gamecore.resources.Profiler;
import mightypork.gamecore.util.Utils; import mightypork.gamecore.util.Utils;
import mightypork.gamecore.util.annot.DefaultImpl; import mightypork.gamecore.util.annot.DefaultImpl;
import mightypork.gamecore.util.math.timing.TimerDelta; import mightypork.gamecore.util.math.timing.TimerDelta;
@@ -21,7 +25,10 @@ import mightypork.gamecore.util.math.timing.TimerDelta;
*/ */
public class MainLoop extends AppModule implements ScreenshotRequestListener { public class MainLoop extends AppModule implements ScreenshotRequestListener {
private final Queue<Runnable> taskQueue = new ConcurrentLinkedQueue<>(); private static final double MAX_TIME_TASKS = 1 / 30D; // (avoid queue from hogging timing)
private static final double MAX_DELTA = 1 / 20D; // (skip huge gaps caused by loading resources etc)
private final Deque<Runnable> tasks = new ConcurrentLinkedDeque<>();
private TimerDelta timer; private TimerDelta timer;
private Renderable rootRenderable; private Renderable rootRenderable;
private volatile boolean running = true; private volatile boolean running = true;
@@ -58,11 +65,23 @@ public class MainLoop extends AppModule implements ScreenshotRequestListener {
while (running) { while (running) {
getDisplay().beginFrame(); getDisplay().beginFrame();
getEventBus().sendDirect(new UpdateEvent(timer.getDelta())); double delta = timer.getDelta();
if (delta > MAX_DELTA) {
Log.f3("(timing) Cropping delta: was " + delta + " , limit " + MAX_DELTA);
delta = MAX_DELTA;
}
getEventBus().sendDirect(new UpdateEvent(delta));
Runnable r; Runnable r;
while ((r = taskQueue.poll()) != null) { long t = Profiler.begin();
while ((r = tasks.poll()) != null) {
Log.f3(" * Main loop task.");
r.run(); r.run();
if (Profiler.end(t) > MAX_TIME_TASKS) {
Log.f3("! Postponing main loop tasks to next cycle.");
break;
}
} }
beforeRender(); beforeRender();
@@ -109,10 +128,15 @@ public class MainLoop extends AppModule implements ScreenshotRequestListener {
* Add a task to queue to be executed in the main loop (OpenGL thread) * Add a task to queue to be executed in the main loop (OpenGL thread)
* *
* @param request task * @param request task
* @param priority if true, skip other tasks
*/ */
public synchronized void queueTask(Runnable request) public synchronized void queueTask(Runnable request, boolean priority)
{ {
taskQueue.add(request); if (priority) {
tasks.addFirst(request);
} else {
tasks.addLast(request);
}
} }
@@ -127,7 +151,7 @@ public class MainLoop extends AppModule implements ScreenshotRequestListener {
{ {
Utils.runAsThread(new TaskTakeScreenshot()); Utils.runAsThread(new TaskTakeScreenshot());
} }
}); }, false);
} }
} }
@@ -1,153 +0,0 @@
package mightypork.gamecore.eventbus;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
/**
* HashSet that buffers "add" and "remove" calls and performs them all at once
* when a flush() method is called.
*
* @author MightyPork
* @param <E> element type
*/
public class BufferedHashSet<E> extends HashSet<E> {
private final List<E> toAdd = new LinkedList<>();
private final List<Object> toRemove = new LinkedList<>();
private boolean buffering = false;
/**
* make empty
*/
public BufferedHashSet()
{
super();
}
/**
* make from elements of a collection
*
* @param c
*/
public BufferedHashSet(Collection<? extends E> c)
{
super(c);
}
/**
* make new
*
* @param initialCapacity
* @param loadFactor
*/
public BufferedHashSet(int initialCapacity, float loadFactor)
{
super(initialCapacity, loadFactor);
}
/**
* make new
*
* @param initialCapacity
*/
public BufferedHashSet(int initialCapacity)
{
super(initialCapacity);
}
@Override
public boolean add(E e)
{
if (buffering) {
toAdd.add(e);
} else {
super.add(e);
}
return true;
}
@Override
public boolean remove(Object e)
{
if (buffering) {
toRemove.add(e);
} else {
super.remove(e);
}
return true;
}
/**
* Flush all
*/
public void flush()
{
for (final E e : toAdd) {
super.add(e);
}
for (final Object e : toRemove) {
super.remove(e);
}
toAdd.clear();
toRemove.clear();
}
@Override
public boolean removeAll(Collection<?> c)
{
throw new UnsupportedOperationException();
}
@Override
public boolean containsAll(Collection<?> c)
{
throw new UnsupportedOperationException();
}
@Override
public boolean addAll(Collection<? extends E> c)
{
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(Collection<?> c)
{
throw new UnsupportedOperationException();
}
/**
* Toggle buffering
*
* @param enable enable buffering
*/
public void setBuffering(boolean enable)
{
if (this.buffering && !enable) {
flush();
}
this.buffering = enable;
}
}
@@ -4,6 +4,9 @@ package mightypork.gamecore.eventbus;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.DelayQueue; import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed; import java.util.concurrent.Delayed;
@@ -104,7 +107,7 @@ final public class EventBus implements Destroyable, BusAccess {
} }
static final String logMark = "<BUS> "; static final String logMark = "(bus) ";
private static Class<?> getEventListenerClass(BusEvent<?> event) private static Class<?> getEventListenerClass(BusEvent<?> event)
@@ -132,13 +135,13 @@ final public class EventBus implements Destroyable, BusAccess {
private final QueuePollingThread busThread; private final QueuePollingThread busThread;
/** Registered clients */ /** Registered clients */
private final BufferedHashSet<Object> clients = new BufferedHashSet<>(); private final Set<Object> clients = Collections.newSetFromMap(new ConcurrentHashMap<Object,Boolean>());
/** Whether the bus was destroyed */ /** Whether the bus was destroyed */
private boolean dead = false; private boolean dead = false;
/** Message channels */ /** Message channels */
private final ConcurrentLinkedDeque<EventChannel<?, ?>> channels = new ConcurrentLinkedDeque<>(); private final Set<EventChannel<?, ?>> channels = Collections.newSetFromMap(new ConcurrentHashMap<EventChannel<?, ?>,Boolean>());
/** Messages queued for delivery */ /** Messages queued for delivery */
private final DelayQueue<DelayQueueEntry> sendQueue = new DelayQueue<>(); private final DelayQueue<DelayQueueEntry> sendQueue = new DelayQueue<>();
@@ -341,12 +344,8 @@ final public class EventBus implements Destroyable, BusAccess {
{ {
assertLive(); assertLive();
clients.setBuffering(true);
doDispatch(clients, event); doDispatch(clients, event);
event.onDispatchComplete(this); event.onDispatchComplete(this);
clients.setBuffering(false);
} }
@@ -6,6 +6,8 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.TreeSet; import java.util.TreeSet;
import org.newdawn.slick.opengl.GLUtils;
import mightypork.gamecore.core.modules.AppAccess; import mightypork.gamecore.core.modules.AppAccess;
import mightypork.gamecore.core.modules.AppModule; import mightypork.gamecore.core.modules.AppModule;
import mightypork.gamecore.gui.events.LayoutChangeEvent; import mightypork.gamecore.gui.events.LayoutChangeEvent;
@@ -83,6 +85,8 @@ public class ScreenRegistry extends AppModule implements ScreenRequestListener,
toShow.setActive(true); toShow.setActive(true);
active = toShow; active = toShow;
fireLayoutUpdateEvent();
} }
@@ -110,7 +114,7 @@ public class ScreenRegistry extends AppModule implements ScreenRequestListener,
@Override @Override
public void onViewportChanged(ViewportChangeEvent event) public void onViewportChanged(ViewportChangeEvent event)
{ {
fireLayoutUpdateEvent(); if(active != null) fireLayoutUpdateEvent();
} }
@@ -67,6 +67,11 @@ public class CrossfadeOverlay extends Overlay {
{ {
requestedScreenName = screen; requestedScreenName = screen;
if(screen == null) {
// going for halt
getSoundSystem().fadeOutAllLoops();
}
if (fromDark) { if (fromDark) {
alpha.setTo(1); alpha.setTo(1);
revealTask.run(); revealTask.run();
@@ -3,6 +3,7 @@ package mightypork.gamecore.gui.screens.impl;
import mightypork.gamecore.gui.screens.Screen; import mightypork.gamecore.gui.screens.Screen;
import mightypork.gamecore.gui.screens.ScreenLayer; import mightypork.gamecore.gui.screens.ScreenLayer;
import mightypork.gamecore.util.annot.DefaultImpl;
import mightypork.gamecore.util.math.Easing; import mightypork.gamecore.util.math.Easing;
import mightypork.gamecore.util.math.constraints.num.mutable.NumAnimated; import mightypork.gamecore.util.math.constraints.num.mutable.NumAnimated;
import mightypork.gamecore.util.math.timing.TimedTask; import mightypork.gamecore.util.math.timing.TimedTask;
@@ -73,6 +74,7 @@ public abstract class FadingLayer extends ScreenLayer {
/** /**
* Called after the fade-out was completed * Called after the fade-out was completed
*/ */
@DefaultImpl
protected void onHideFinished() protected void onHideFinished()
{ {
} }
@@ -81,6 +83,7 @@ public abstract class FadingLayer extends ScreenLayer {
/** /**
* Called after the fade-in was completed * Called after the fade-in was completed
*/ */
@DefaultImpl
protected void onShowFinished() protected void onShowFinished()
{ {
} }
@@ -98,6 +101,7 @@ public abstract class FadingLayer extends ScreenLayer {
super.show(); super.show();
numa.fadeIn(); numa.fadeIn();
hideTimer.stop(); hideTimer.stop();
showTimer.start(numa.getDefaultDuration());
fadingOut = false; fadingOut = false;
fadingIn = true; fadingIn = true;
@@ -18,7 +18,7 @@ import mightypork.gamecore.logging.Log;
*/ */
public class AsyncResourceLoader extends Thread implements ResourceLoader, Destroyable { public class AsyncResourceLoader extends Thread implements ResourceLoader, Destroyable {
private final ExecutorService exs = Executors.newCachedThreadPool(); private final ExecutorService exs = Executors.newFixedThreadPool(2);
private final LinkedBlockingQueue<LazyResource> toLoad = new LinkedBlockingQueue<>(); private final LinkedBlockingQueue<LazyResource> toLoad = new LinkedBlockingQueue<>();
private volatile boolean stopped; private volatile boolean stopped;
@@ -57,9 +57,9 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
if (resource.getClass().isAnnotationPresent(TextureBasedResource.class)) { if (resource.getClass().isAnnotationPresent(TextureBasedResource.class)) {
if (!mainLoopQueuing) { if (!mainLoopQueuing) {
Log.f3("<LOADER> Cannot load async: " + Log.str(resource)); // just let it be
} else { } else {
Log.f3("<LOADER> Delegating to main thread:\n " + Log.str(resource)); Log.f3("(loader) Delegating to main thread: " + Log.str(resource));
app.getEventBus().send(new MainLoopRequest(new Runnable() { app.getEventBus().send(new MainLoopRequest(new Runnable() {
@@ -68,7 +68,7 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
{ {
resource.load(); resource.load();
} }
})); }, false));
} }
return; return;
@@ -91,15 +91,17 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
if (!def.isLoaded()) { if (!def.isLoaded()) {
Log.f3("<LOADER> Loading: " + Log.str(def)); Log.f3("(loader) Scheduling... " + Log.str(def));
exs.submit(new Runnable() { exs.submit(new Runnable() {
@Override @Override
public void run() public void run()
{ {
if(!def.isLoaded()) {
def.load(); def.load();
} }
}
}); });
} }
@@ -6,6 +6,8 @@ import java.io.IOException;
import mightypork.gamecore.eventbus.events.Destroyable; import mightypork.gamecore.eventbus.events.Destroyable;
import mightypork.gamecore.logging.Log; import mightypork.gamecore.logging.Log;
import mightypork.gamecore.logging.LogAlias; import mightypork.gamecore.logging.LogAlias;
import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.strings.StringUtils;
/** /**
@@ -34,8 +36,12 @@ public abstract class BaseLazyResource implements LazyResource, Destroyable {
@Override @Override
public synchronized final void load() public synchronized final void load()
{ {
if (loadFailed) return; if (!loadFailed && loadAttempted) return;
if (loadAttempted) return;
//
// if (loadFailed) return;
// if (loadAttempted) return;
//
loadAttempted = true; loadAttempted = true;
loadFailed = false; loadFailed = false;
@@ -45,12 +51,14 @@ public abstract class BaseLazyResource implements LazyResource, Destroyable {
throw new NullPointerException("Resource string cannot be null for non-null resource."); throw new NullPointerException("Resource string cannot be null for non-null resource.");
} }
Log.f3("<RES> Loading: " + this); long time = Profiler.begin();
Log.f3("(res) + Load: " + this);
loadResource(resource); loadResource(resource);
Log.f3("<RES> Loaded: " + this); Log.f3("(res) - Done: " + this + " in " + Profiler.endStr(time));
} catch (final Throwable t) { } catch (final Throwable t) {
loadFailed = true; loadFailed = true;
Log.e("<RES> Failed to load: " + this, t); Log.e("(res) Failed to load: " + this, t);
} }
} }
@@ -74,7 +82,7 @@ public abstract class BaseLazyResource implements LazyResource, Destroyable {
} else { } else {
if (loadFailed) return false; if (loadFailed) return false;
Log.f3("<RES> (!) Loading on access: " + this); Log.f3("(res) !! Loading on access: " + this);
load(); load();
} }
@@ -99,7 +107,7 @@ public abstract class BaseLazyResource implements LazyResource, Destroyable {
@Override @Override
public String toString() public String toString()
{ {
return Log.str(getClass()) + "(\"" + resource + "\")"; return StringUtils.fromLastChar(resource, '/');
} }
@@ -0,0 +1,32 @@
package mightypork.gamecore.resources;
import mightypork.gamecore.util.math.Calc;
public class Profiler {
public static long begin()
{
return System.currentTimeMillis();
}
public static double end(long begun)
{
return endLong(begun) / 1000D;
}
public static long endLong(long begun)
{
return System.currentTimeMillis() - begun;
}
public static String endStr(long begun)
{
return Calc.toString(end(begun)) + " s";
}
}
+1 -1
View File
@@ -94,8 +94,8 @@ public final class Res {
public static void load(ResourceSetup binder) public static void load(ResourceSetup binder)
{ {
binder.addFonts(fonts); binder.addFonts(fonts);
binder.addSounds(sounds);
binder.addTextures(textures); binder.addTextures(textures);
binder.addSounds(sounds);
} }
} }
@@ -2,7 +2,9 @@ package mightypork.gamecore.resources.audio;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import mightypork.gamecore.core.modules.AppAccess; import mightypork.gamecore.core.modules.AppAccess;
@@ -71,8 +73,8 @@ public class SoundSystem extends RootBusNode implements Updateable {
private final Volume effectsVolume = new JointVolume(masterVolume); private final Volume effectsVolume = new JointVolume(masterVolume);
private final Volume loopsVolume = new JointVolume(masterVolume); private final Volume loopsVolume = new JointVolume(masterVolume);
private final Set<LoopPlayer> loopPlayers = new HashSet<>(); private final List<LoopPlayer> loopPlayers = new ArrayList<>();
private final Set<LazyAudio> resources = new HashSet<>(); private final List<LazyAudio> resources = new ArrayList<>();
/** /**
@@ -130,7 +132,7 @@ public class SoundSystem extends RootBusNode implements Updateable {
*/ */
public EffectPlayer createEffect(String resource, double pitch, double gain) public EffectPlayer createEffect(String resource, double pitch, double gain)
{ {
return new EffectPlayer(getResource(resource), pitch, gain, effectsVolume); return new EffectPlayer(createResource(resource), pitch, gain, effectsVolume);
} }
@@ -146,7 +148,7 @@ public class SoundSystem extends RootBusNode implements Updateable {
*/ */
public LoopPlayer createLoop(String resource, double pitch, double gain, double fadeIn, double fadeOut) public LoopPlayer createLoop(String resource, double pitch, double gain, double fadeIn, double fadeOut)
{ {
final LoopPlayer p = new LoopPlayer(getResource(resource), pitch, gain, loopsVolume); final LoopPlayer p = new LoopPlayer(createResource(resource), pitch, gain, loopsVolume);
p.setFadeTimes(fadeIn, fadeOut); p.setFadeTimes(fadeIn, fadeOut);
loopPlayers.add(p); loopPlayers.add(p);
return p; return p;
@@ -160,12 +162,10 @@ public class SoundSystem extends RootBusNode implements Updateable {
* @return the resource * @return the resource
* @throws IllegalArgumentException if resource is already registered * @throws IllegalArgumentException if resource is already registered
*/ */
private LazyAudio getResource(String res) private LazyAudio createResource(String res)
{ {
final LazyAudio a = new LazyAudio(res); final LazyAudio a = new LazyAudio(res);
getEventBus().send(new ResourceLoadRequest(a)); getEventBus().send(new ResourceLoadRequest(a));
if (resources.contains(a)) throw new IllegalArgumentException("Sound resource " + res + " is already registered.");
resources.add(a); resources.add(a);
return a; return a;
} }
@@ -98,6 +98,8 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
sourceID = getAudio().resumeLoop(); sourceID = getAudio().resumeLoop();
paused = false; paused = false;
adjustGain(getGain(fadeAnim.value()));
} }
@@ -112,7 +114,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
final double gain = getGain(fadeAnim.value()); final double gain = getGain(fadeAnim.value());
if (!paused && gain != lastUpdateGain) { if (!paused && gain != lastUpdateGain) {
AL10.alSourcef(sourceID, AL10.AL_GAIN, (float) gain); adjustGain(gain);
lastUpdateGain = gain; lastUpdateGain = gain;
} }
@@ -120,6 +122,12 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
} }
private void adjustGain(double gain)
{
AL10.alSourcef(sourceID, AL10.AL_GAIN, (float) gain);
}
/** /**
* Resume if paused, and fade in (pick up from current volume). * Resume if paused, and fade in (pick up from current volume).
* *
@@ -129,6 +137,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
{ {
if (!hasAudio()) return; if (!hasAudio()) return;
if (isPaused()) fadeAnim.setTo(0);
resume(); resume();
fadeAnim.fadeIn(secs); fadeAnim.fadeIn(secs);
} }
@@ -142,7 +151,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
public void fadeOut(double secs) public void fadeOut(double secs)
{ {
if (!hasAudio()) return; if (!hasAudio()) return;
if (isPaused()) return;
fadeAnim.fadeOut(secs); fadeAnim.fadeOut(secs);
} }
@@ -1,6 +1,7 @@
package mightypork.gamecore.resources.fonts; package mightypork.gamecore.resources.fonts;
import mightypork.gamecore.resources.TextureBasedResource;
import mightypork.gamecore.util.math.color.Color; import mightypork.gamecore.util.math.color.Color;
import mightypork.gamecore.util.math.constraints.vect.Vect; import mightypork.gamecore.util.math.constraints.vect.Vect;
@@ -19,6 +19,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import mightypork.gamecore.logging.Log; import mightypork.gamecore.logging.Log;
import mightypork.gamecore.resources.TextureBasedResource;
import mightypork.gamecore.resources.fonts.GLFont; import mightypork.gamecore.resources.fonts.GLFont;
import mightypork.gamecore.resources.textures.FilterMode; import mightypork.gamecore.resources.textures.FilterMode;
import mightypork.gamecore.resources.textures.LazyTexture; import mightypork.gamecore.resources.textures.LazyTexture;
+1 -1
View File
@@ -139,7 +139,7 @@ public final class RogueApp extends BaseApp implements ViewportChangeListener, S
getEventBus().send(new RogueStateRequest(RogueState.MAIN_MENU, true)); getEventBus().send(new RogueStateRequest(RogueState.MAIN_MENU, true));
} }
} }
})); }, false));
} }
@@ -65,12 +65,12 @@ public class EntityBrownRat extends Entity {
{ {
// drop rat stuff // drop rat stuff
if (Calc.rand.nextInt(2) == 0) { if (Calc.rand.nextInt(2) != 0) {
getLevel().dropNear(getCoord(), Items.MEAT.createItem()); getLevel().dropNear(getCoord(), Items.MEAT.createItem());
return; return;
} }
if (Calc.rand.nextInt(4) == 0) { if (Calc.rand.nextInt(3) == 0) {
getLevel().dropNear(getCoord(), Items.CHEESE.createItem()); getLevel().dropNear(getCoord(), Items.CHEESE.createItem());
return; return;
} }
@@ -17,12 +17,15 @@ public class StorageRoom extends SecretRoom {
{ {
int maxStuff = Calc.randInt(rand, 3, 5); int maxStuff = Calc.randInt(rand, 3, 5);
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { // at least one meat or cheese.
boolean oneMeat = rand.nextBoolean();
for (int i = 0; i < Calc.randInt(rand, oneMeat ? 1 : 0, 3); i++) {
map.addItemInArea(Items.MEAT.createItem(), min, max, 50); map.addItemInArea(Items.MEAT.createItem(), min, max, 50);
if (--maxStuff == 0) return; if (--maxStuff == 0) return;
} }
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { for (int i = 0; i < Calc.randInt(rand, oneMeat ? 0 : 1, 2); i++) {
map.addItemInArea(Items.CHEESE.createItem(), min, max, 50); map.addItemInArea(Items.CHEESE.createItem(), min, max, 50);
if (--maxStuff == 0) return; if (--maxStuff == 0) return;
} }
+9 -5
View File
@@ -5,15 +5,17 @@ import java.io.IOException;
import mightypork.gamecore.logging.Log; import mightypork.gamecore.logging.Log;
import mightypork.gamecore.util.annot.DefaultImpl; import mightypork.gamecore.util.annot.DefaultImpl;
import mightypork.gamecore.util.ion.IonBundle;
import mightypork.gamecore.util.ion.IonInput; import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonObjBlob; import mightypork.gamecore.util.ion.IonObjBlob;
import mightypork.gamecore.util.ion.IonObjBundled;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
import mightypork.gamecore.util.math.Calc; import mightypork.gamecore.util.math.Calc;
import mightypork.gamecore.util.math.constraints.rect.Rect; import mightypork.gamecore.util.math.constraints.rect.Rect;
import mightypork.rogue.world.PlayerFacade; import mightypork.rogue.world.PlayerFacade;
public abstract class Item implements IonObjBlob { public abstract class Item implements IonObjBundled {
private final ItemModel model; private final ItemModel model;
private ItemRenderer renderer; private ItemRenderer renderer;
@@ -42,17 +44,19 @@ public abstract class Item implements IonObjBlob {
@Override @Override
@DefaultImpl @DefaultImpl
public void save(IonOutput out) throws IOException public void save(IonBundle out) throws IOException
{ {
out.writeIntShort(amount); out.put("c", amount);
out.put("u", uses);
} }
@Override @Override
@DefaultImpl @DefaultImpl
public void load(IonInput in) throws IOException public void load(IonBundle in) throws IOException
{ {
amount = in.readIntShort(); amount = in.get("c", amount);
uses = in.get("u", uses);
} }
@@ -3,6 +3,8 @@ package mightypork.rogue.world.item;
import java.io.IOException; import java.io.IOException;
import mightypork.gamecore.util.ion.Ion;
import mightypork.gamecore.util.ion.IonBundle;
import mightypork.gamecore.util.ion.IonInput; import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
import mightypork.gamecore.util.math.Calc; import mightypork.gamecore.util.math.Calc;
@@ -46,7 +48,7 @@ public final class ItemModel {
} }
public Item loadItem(IonInput in) throws IOException public Item loadItem(IonBundle in) throws IOException
{ {
final Item t = createItem(); final Item t = createItem();
t.load(in); t.load(in);
@@ -54,11 +56,10 @@ public final class ItemModel {
} }
public void saveItem(IonOutput out, Item tile) throws IOException public void saveItem(IonBundle out, Item item) throws IOException
{ {
if (itemClass != tile.getClass()) throw new RuntimeException("Item class mismatch."); if (itemClass != item.getClass()) throw new RuntimeException("Item class mismatch.");
item.save(out);
tile.save(out);
} }
+6 -3
View File
@@ -4,6 +4,7 @@ package mightypork.rogue.world.item;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import mightypork.gamecore.util.ion.IonBundle;
import mightypork.gamecore.util.ion.IonInput; import mightypork.gamecore.util.ion.IonInput;
import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.ion.IonOutput;
import mightypork.rogue.world.item.impl.active.ItemHeartPiece; import mightypork.rogue.world.item.impl.active.ItemHeartPiece;
@@ -64,9 +65,8 @@ public final class Items {
public static Item loadItem(IonInput in) throws IOException public static Item loadItem(IonInput in) throws IOException
{ {
final int id = in.readIntByte(); final int id = in.readIntByte();
final ItemModel model = get(id); final ItemModel model = get(id);
return model.loadItem(in); return model.loadItem(in.readBundle());
} }
@@ -75,7 +75,10 @@ public final class Items {
final ItemModel model = item.getModel(); final ItemModel model = item.getModel();
out.writeIntByte(model.id); out.writeIntByte(model.id);
model.saveItem(out, item);
IonBundle ib = new IonBundle();
model.saveItem(ib, item);
out.writeBundle(ib);
} }
@@ -33,7 +33,7 @@ public class ItemKnife extends ItemBaseWeapon {
@Override @Override
public int getMaxUses() public int getMaxUses()
{ {
return 60; return 70;
} }
@@ -33,7 +33,7 @@ public class ItemRock extends ItemBaseWeapon {
@Override @Override
public int getMaxUses() public int getMaxUses()
{ {
return 30; return 35;
} }
@@ -33,7 +33,7 @@ public class ItemSword extends ItemBaseWeapon {
@Override @Override
public int getMaxUses() public int getMaxUses()
{ {
return 200; return 210;
} }