From: Oskar Wiksten Date: Sat, 28 Jul 2012 19:51:35 +0000 (+0200) Subject: WIP display duration & magnitude on condition icons. X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=bd0ee9713d9bae5171f8c5ed234aa3c596ad0bb1;p=users%2Fmchehab%2Fandors-trail.git WIP display duration & magnitude on condition icons. --- diff --git a/AndorsTrail/res/anim/scalebeat.xml b/AndorsTrail/res/anim/scalebeat.xml new file mode 100644 index 0000000..3471f26 --- /dev/null +++ b/AndorsTrail/res/anim/scalebeat.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/AndorsTrail/res/anim/scaledown.xml b/AndorsTrail/res/anim/scaledown.xml new file mode 100644 index 0000000..0c15c5a --- /dev/null +++ b/AndorsTrail/res/anim/scaledown.xml @@ -0,0 +1,12 @@ + + diff --git a/AndorsTrail/res/anim/scaleup.xml b/AndorsTrail/res/anim/scaleup.xml new file mode 100644 index 0000000..138d2a3 --- /dev/null +++ b/AndorsTrail/res/anim/scaleup.xml @@ -0,0 +1,12 @@ + + diff --git a/AndorsTrail/res/layout/main.xml b/AndorsTrail/res/layout/main.xml index fb98625..9be5d01 100644 --- a/AndorsTrail/res/layout/main.xml +++ b/AndorsTrail/res/layout/main.xml @@ -54,13 +54,12 @@ android:shadowColor="#000" /> - diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java index badc06f..5e0384a 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java @@ -16,6 +16,7 @@ import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.view.CombatView; +import com.gpl.rpg.AndorsTrail.view.DisplayActiveActorConditionIcons; import com.gpl.rpg.AndorsTrail.view.MainView; import com.gpl.rpg.AndorsTrail.view.VirtualDpadView; import com.gpl.rpg.AndorsTrail.view.QuickButton.QuickButtonContextMenuInfo; @@ -33,7 +34,7 @@ import android.view.View; import android.view.ContextMenu.ContextMenuInfo; import android.view.MenuItem.OnMenuItemClickListener; import android.view.View.OnClickListener; -import android.widget.LinearLayout; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -59,7 +60,7 @@ public final class MainActivity extends Activity { public StatusView statusview; public CombatView combatview; public QuickitemView quickitemview; - private LinearLayout activeConditions; + private DisplayActiveActorConditionIcons activeConditions; private VirtualDpadView dpad; private static final int NUM_MESSAGES = 3; @@ -84,7 +85,7 @@ public final class MainActivity extends Activity { statusview = (StatusView) findViewById(R.id.main_statusview); combatview = (CombatView) findViewById(R.id.main_combatview); quickitemview = (QuickitemView) findViewById(R.id.main_quickitemview); - activeConditions = (LinearLayout) findViewById(R.id.statusview_activeconditions); + activeConditions = new DisplayActiveActorConditionIcons(world.tileManager, this, (RelativeLayout) findViewById(R.id.statusview_activeconditions)); dpad = (VirtualDpadView) findViewById(R.id.main_virtual_dpad); statusText = (TextView) findViewById(R.id.statusview_statustext); @@ -165,6 +166,8 @@ public final class MainActivity extends Activity { view.gameRoundController.pause(); view.movementController.stopMovement(); + activeConditions.unsubscribe(world); + save(Savegames.SLOT_QUICKSAVE); } @@ -173,6 +176,8 @@ public final class MainActivity extends Activity { super.onResume(); if (!AndorsTrailApplication.getApplicationFromActivity(this).setup.isSceneReady) return; + activeConditions.subscribe(world); + view.gameRoundController.resume(); if (world.model.uiSelections.isInCombat) { @@ -257,7 +262,6 @@ public final class MainActivity extends Activity { public void updateStatus() { statusview.updateStatus(); - statusview.updateActiveConditions(this, activeConditions); quickitemview.refreshQuickitems(); combatview.updateStatus(); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java index 0d53eab..8937faa 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java @@ -59,10 +59,12 @@ public class ActorStatsController { if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue; if (c.duration != duration) continue; - actor.conditions.remove(i); - magnitude = c.magnitude - magnitude; - if (magnitude > 0) { - actor.conditions.add(new ActorCondition(type, magnitude, duration)); + if (c.magnitude > magnitude) { + c.magnitude -= magnitude; + actor.conditionListener.onActorConditionMagnitudeChanged(actor, c); + } else { + actor.conditions.remove(i); + actor.conditionListener.onActorConditionRemoved(actor, c); } break; } @@ -109,12 +111,14 @@ public class ActorStatsController { if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue; if (c.duration == duration) { // If the actor already has a condition of this type and the same duration, just increase the magnitude instead. - actor.conditions.remove(i); - magnitude += c.magnitude; - break; + c.magnitude += magnitude; + actor.conditionListener.onActorConditionMagnitudeChanged(actor, c); + return; } } - actor.conditions.add(new ActorCondition(type, magnitude, duration)); + ActorCondition c = new ActorCondition(type, magnitude, duration); + actor.conditions.add(c); + actor.conditionListener.onActorConditionAdded(actor, c); } private static void addNonStackableActorCondition(Actor actor, ActorConditionEffect e, int duration) { final ActorConditionType type = e.conditionType; @@ -123,24 +127,34 @@ public class ActorStatsController { ActorCondition c = actor.conditions.get(i); if (!type.conditionTypeID.equals(c.conditionType.conditionTypeID)) continue; if (c.magnitude > e.magnitude) return; + else if (c.magnitude == e.magnitude) { + if (c.duration >= duration) return; + } // If the actor already has this condition, but of a lower magnitude, we remove the old one and add this higher magnitude. actor.conditions.remove(i); + actor.conditionListener.onActorConditionRemoved(actor, c); } - actor.conditions.add(e.createCondition(duration)); + + ActorCondition c = e.createCondition(duration); + actor.conditions.add(c); + actor.conditionListener.onActorConditionAdded(actor, c); } public static void removeAllTemporaryConditions(final Actor actor) { for(int i = actor.conditions.size() - 1; i >= 0; --i) { - if (!actor.conditions.get(i).isTemporaryEffect()) continue; + ActorCondition c = actor.conditions.get(i); + if (!c.isTemporaryEffect()) continue; actor.conditions.remove(i); + actor.conditionListener.onActorConditionRemoved(actor, c); } } private static void removeAllConditionsOfType(final Actor actor, final String conditionTypeID) { for(int i = actor.conditions.size() - 1; i >= 0; --i) { - if (actor.conditions.get(i).conditionType.conditionTypeID.equals(conditionTypeID)) { - actor.conditions.remove(i); - } + ActorCondition c = actor.conditions.get(i); + if (!c.conditionType.conditionTypeID.equals(conditionTypeID)) continue; + actor.conditions.remove(i); + actor.conditionListener.onActorConditionRemoved(actor, c); } } @@ -210,10 +224,13 @@ public class ActorStatsController { if (SkillController.rollForSkillChance(player, SkillCollection.SKILL_REJUVENATION, SkillCollection.PER_SKILLPOINT_INCREASE_REJUVENATION_CHANCE)) { int i = getRandomConditionForRejuvenate(player); if (i >= 0) { - ActorCondition c = player.conditions.remove(i); + ActorCondition c = player.conditions.get(i); if (c.magnitude > 1) { - int magnitude = c.magnitude - 1; - player.conditions.add(i, new ActorCondition(c.conditionType, magnitude, c.duration)); + c.magnitude -= 1; + player.conditionListener.onActorConditionMagnitudeChanged(player, c); + } else { + player.conditions.remove(i); + player.conditionListener.onActorConditionRemoved(player, c); } recalculateActorCombatTraits(player); } @@ -258,6 +275,7 @@ public class ActorStatsController { for (ActorCondition c : actor.conditions) { StatsModifierTraits effect = isFullRound ? c.conditionType.statsEffect_everyFullRound : c.conditionType.statsEffect_everyRound; effectToStart = applyStatsModifierEffect(actor, effect, c.magnitude, effectToStart); + if (effect != null) actor.conditionListener.onActorConditionRoundEffectApplied(actor, c); } startVisualEffect(actor, effectToStart); } @@ -267,10 +285,13 @@ public class ActorStatsController { for(int i = actor.conditions.size() - 1; i >= 0; --i) { ActorCondition c = actor.conditions.get(i); if (!c.isTemporaryEffect()) continue; - c.duration -= 1; - if (c.duration <= 0) { + if (c.duration <= 1) { actor.conditions.remove(i); + actor.conditionListener.onActorConditionRemoved(actor, c); removedAnyConditions = true; + } else { + c.duration -= 1; + actor.conditionListener.onActorConditionDurationChanged(actor, c); } } if (removedAnyConditions) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/ActorCondition.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/ActorCondition.java index 772a48f..bb0848e 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/ActorCondition.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/ability/ActorCondition.java @@ -11,7 +11,7 @@ public class ActorCondition { public static final int DURATION_FOREVER = 999; public final ActorConditionType conditionType; - public final int magnitude; + public int magnitude; public int duration; public ActorCondition(ActorConditionType conditionType, int magnitude, int duration) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java index bec0b10..20efe74 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Actor.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.CombatTraits; import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.listeners.ActorConditionListeners; import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.CoordRect; import com.gpl.rpg.AndorsTrail.util.Range; @@ -20,6 +21,7 @@ public class Actor { public final Coord position; public final CoordRect rectPosition; public final ArrayList conditions = new ArrayList(); + public final ActorConditionListeners conditionListener = new ActorConditionListeners(); public final boolean isPlayer; public final boolean isImmuneToCriticalHits; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListener.java new file mode 100644 index 0000000..6db1770 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListener.java @@ -0,0 +1,12 @@ +package com.gpl.rpg.AndorsTrail.model.listeners; + +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.actor.Actor; + +public interface ActorConditionListener { + public void onActorConditionAdded(Actor actor, ActorCondition condition); + public void onActorConditionRemoved(Actor actor, ActorCondition condition); + public void onActorConditionDurationChanged(Actor actor, ActorCondition condition); + public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition); + public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition); +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListeners.java new file mode 100644 index 0000000..3ea9271 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ActorConditionListeners.java @@ -0,0 +1,48 @@ +package com.gpl.rpg.AndorsTrail.model.listeners; + +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.actor.Actor; + +public class ActorConditionListeners extends ListOfListeners implements ActorConditionListener { + + private final Function2 onActorConditionAdded = new Function2() { + @Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionAdded(actor, condition); } + }; + private final Function2 onActorConditionRemoved = new Function2() { + @Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionRemoved(actor, condition); } + }; + private final Function2 onActorConditionDurationChanged = new Function2() { + @Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionDurationChanged(actor, condition); } + }; + private final Function2 onActorConditionMagnitudeChanged = new Function2() { + @Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionMagnitudeChanged(actor, condition); } + }; + private final Function2 onActorConditionRoundEffectApplied = new Function2() { + @Override public void call(ActorConditionListener listener, Actor actor, ActorCondition condition) { listener.onActorConditionRoundEffectApplied(actor, condition); } + }; + + @Override + public void onActorConditionAdded(Actor actor, ActorCondition condition) { + callAllListeners(this.onActorConditionAdded, actor, condition); + } + + @Override + public void onActorConditionRemoved(Actor actor, ActorCondition condition) { + callAllListeners(this.onActorConditionRemoved, actor, condition); + } + + @Override + public void onActorConditionDurationChanged(Actor actor, ActorCondition condition) { + callAllListeners(this.onActorConditionDurationChanged, actor, condition); + } + + @Override + public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition) { + callAllListeners(this.onActorConditionMagnitudeChanged, actor, condition); + } + + @Override + public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition) { + callAllListeners(this.onActorConditionRoundEffectApplied, actor, condition); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java new file mode 100644 index 0000000..c51c05f --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/listeners/ListOfListeners.java @@ -0,0 +1,52 @@ +package com.gpl.rpg.AndorsTrail.model.listeners; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; + +public class ListOfListeners { + private final ArrayList> listeners = new ArrayList>(); + + public void add(T listener) { + listeners.add(new WeakReference(listener)); + } + public void remove(T listenerToRemove) { + for (int i = listeners.size()-1; i >= 0; --i) { + T listener = listeners.get(i).get(); + if (listener == null || listener == listenerToRemove) { + listeners.remove(i); + } + } + } + + protected void callAllListeners(Function e) { + for (int i = listeners.size()-1; i >= 0; --i) { + T listener = listeners.get(i).get(); + if (listener == null) listeners.remove(i); + else e.call(listener); + } + } + protected void callAllListeners(Function1 e, Arg1 arg) { + for (int i = listeners.size()-1; i >= 0; --i) { + T listener = listeners.get(i).get(); + if (listener == null) listeners.remove(i); + else e.call(listener, arg); + } + } + protected void callAllListeners(Function2 e, Arg1 arg1, Arg2 arg2) { + for (int i = listeners.size()-1; i >= 0; --i) { + T listener = listeners.get(i).get(); + if (listener == null) listeners.remove(i); + else e.call(listener, arg1, arg2); + } + } + + protected static interface Function { + public void call(Listener listener); + } + protected static interface Function1 { + public void call(Listener listener, Arg1 arg1); + } + protected static interface Function2 { + public void call(Listener listener, Arg1 arg1, Arg2 arg2); + } +} \ No newline at end of file diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java new file mode 100644 index 0000000..37a30ad --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/DisplayActiveActorConditionIcons.java @@ -0,0 +1,260 @@ +package com.gpl.rpg.AndorsTrail.view; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; + +import android.content.Context; +import android.content.res.Resources; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; +import android.view.animation.AnimationUtils; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.RelativeLayout.LayoutParams; + +import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.actor.Actor; +import com.gpl.rpg.AndorsTrail.model.listeners.ActorConditionListener; +import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; + +public class DisplayActiveActorConditionIcons implements ActorConditionListener { + + private final TileManager tileManager; + private final RelativeLayout activeConditions; + private final ArrayList currentConditionIcons = new ArrayList(); + private final WeakReference androidContext; + + public DisplayActiveActorConditionIcons(final TileManager tileManager, Context androidContext, RelativeLayout activeConditions) { + this.tileManager = tileManager; + this.androidContext = new WeakReference(androidContext); + this.activeConditions = activeConditions; + } + + private ActiveConditionIcon getIconFor(ActorCondition condition) { + for (ActiveConditionIcon icon : currentConditionIcons) { + if (icon.condition == condition) return icon; + } + return null; + } + private ActiveConditionIcon getFirstFreeIcon() { + for (ActiveConditionIcon icon : currentConditionIcons) { + if (!icon.isVisible()) return icon; + } + return addNewActiveConditionIcon(); + } + + private RelativeLayout.LayoutParams getLayoutParamsForIconIndex(int index) { + RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + layout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + if (index == 0) { + layout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + } else { + layout.addRule(RelativeLayout.LEFT_OF, currentConditionIcons.get(index-1).id); + } + return layout; + } + + private ActiveConditionIcon addNewActiveConditionIcon() { + int index = currentConditionIcons.size(); + + ActiveConditionIcon icon = new ActiveConditionIcon(androidContext.get(), index+1); + + activeConditions.addView(icon.image, getLayoutParamsForIconIndex(index)); + + RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + layout.addRule(RelativeLayout.ALIGN_RIGHT, icon.id); + layout.addRule(RelativeLayout.ALIGN_BOTTOM, icon.id); + activeConditions.addView(icon.text, layout); + + /* + layout = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + layout.addRule(RelativeLayout.ALIGN_RIGHT, icon.image.getId()); + layout.addRule(RelativeLayout.ALIGN_BOTTOM, icon.image.getId()); + activeConditions.addView(icon.duration, layout); + */ + + currentConditionIcons.add(icon); + + return icon; + } + + private final class ActiveConditionIcon implements AnimationListener { + public final int id; + public ActorCondition condition; + public final ImageView image; + public final TextView text; + //public final TextView duration; + private final Animation onNewIconAnimation; + private final Animation onRemovedIconAnimation; + private final Animation onAppliedEffectAnimation; + + public ActiveConditionIcon(Context context, int id) { + this.id = id; + this.image = new ImageView(context); + this.image.setId(id); + this.text = new TextView(context); + this.onNewIconAnimation = AnimationUtils.loadAnimation(context, R.anim.scaleup); + this.onRemovedIconAnimation = AnimationUtils.loadAnimation(context, R.anim.scaledown); + this.onAppliedEffectAnimation = AnimationUtils.loadAnimation(context, R.anim.scalebeat); + this.onRemovedIconAnimation.setAnimationListener(this); + //duration = new TextView(context); + + final Resources res = context.getResources(); + + //float textSize = ; + //magnitude.setTextSize(res.getDimension(R.dimen.smalltext)); + /* + duration.setTextSize(res.getDimension(R.dimen.smalltext)); + + int textColor = res.getColor(android.R.color.white); + int shadowColor = res.getColor(android.R.color.black); + magnitude.setTextColor(textColor); + duration.setTextColor(textColor); + + magnitude.setShadowLayer(1, 1, 1, shadowColor); + duration.setShadowLayer(2, 1, 1, shadowColor); + */ + + text.setTextColor(res.getColor(android.R.color.white)); + text.setShadowLayer(1, 1, 1, res.getColor(android.R.color.black)); + } + + private void setActiveCondition(ActorCondition condition) { + this.condition = condition; + tileManager.setImageViewTile(image, condition.conditionType); + image.setVisibility(View.VISIBLE); + setIconText(); + } + + public void setIconText() { + boolean showMagnitude = (condition.magnitude != 1); + boolean showDuration = condition.isTemporaryEffect(); + if (showMagnitude/* || showDuration*/) { + /*if (showMagnitude && showDuration) { + icon.text.setText(condition.duration + "x" + condition.magnitude); + } else if (showDuration) { + icon.text.setText(condition.duration); + } else if (showMagnitude) { + icon.text.setText("x" + condition.magnitude); + }*/ + text.setText(Integer.toString(condition.magnitude)); + text.setVisibility(View.VISIBLE); + } else { + text.setVisibility(View.GONE); + } + /* + if (condition.magnitude != 1) { + icon.magnitude.setText(Integer.toString(condition.magnitude)); + icon.magnitude.setVisibility(View.VISIBLE); + } else { + icon.magnitude.setVisibility(View.GONE); + } + if (condition.isTemporaryEffect()) { + icon.duration.setText(Integer.toString(condition.duration)); + icon.duration.setVisibility(View.VISIBLE); + } else { + icon.duration.setVisibility(View.GONE); + } + */ + } + + public void hide(boolean useAnimation) { + if (useAnimation) { + image.startAnimation(onRemovedIconAnimation); + } else { + image.setVisibility(View.GONE); + condition = null; + } + text.setVisibility(View.GONE); + } + public void show() { + image.startAnimation(onNewIconAnimation); + if (text.getVisibility() == View.VISIBLE) text.startAnimation(onNewIconAnimation); + } + + public void pulseAnimate() { + image.startAnimation(onAppliedEffectAnimation); + } + + public boolean isVisible() { + return condition != null; + } + + @Override + public void onAnimationEnd(Animation animation) { + if (animation == this.onRemovedIconAnimation) { + hide(false); + rearrangeIconsLeftOf(this); + } + } + + @Override public void onAnimationRepeat(Animation animation) { } + @Override public void onAnimationStart(Animation animation) { } + } + + protected void rearrangeIconsLeftOf(ActiveConditionIcon icon) { + int i = currentConditionIcons.indexOf(icon); + currentConditionIcons.remove(i); + currentConditionIcons.add(icon); + for(; i < currentConditionIcons.size(); ++i) { + ActiveConditionIcon aci = currentConditionIcons.get(i); + aci.image.setLayoutParams(getLayoutParamsForIconIndex(i)); + } + } + + @Override + public void onActorConditionAdded(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getFirstFreeIcon(); + icon.setActiveCondition(condition); + icon.show(); + } + + @Override + public void onActorConditionRemoved(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.hide(true); + } + + @Override + public void onActorConditionDurationChanged(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.setIconText(); + } + + @Override + public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.setIconText(); + } + + @Override + public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition) { + ActiveConditionIcon icon = getIconFor(condition); + if (icon == null) return; + icon.pulseAnimate(); + } + + public void unsubscribe(final WorldContext world) { + world.model.player.conditionListener.remove(this); + hideAllIcons(); + } + + public void subscribe(final WorldContext world) { + hideAllIcons(); + for (ActorCondition condition : world.model.player.conditions) { + getFirstFreeIcon().setActiveCondition(condition); + } + world.model.player.conditionListener.add(this); + } + + private void hideAllIcons() { + for (ActiveConditionIcon icon : currentConditionIcons) icon.hide(false); + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java index c6d0a36..f2897c7 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/StatusView.java @@ -6,7 +6,6 @@ import com.gpl.rpg.AndorsTrail.activity.MainActivity; import com.gpl.rpg.AndorsTrail.activity.HeroinfoActivity; import com.gpl.rpg.AndorsTrail.context.ViewContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; -import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; @@ -17,8 +16,6 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.util.AttributeSet; import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.ImageButton; @@ -97,15 +94,6 @@ public final class StatusView extends RelativeLayout { world.tileManager.setImageViewTile(heroImage, player); } } - - public void updateActiveConditions(Context androidContext, LinearLayout activeConditions) { - GreedyImageViewAppender t = new GreedyImageViewAppender(androidContext, activeConditions); - for (ActorCondition condition : player.conditions) { - ImageView iv = t.getNextImage(); - world.tileManager.setImageViewTile(iv, condition.conditionType); - } - t.removeOtherImages(); - } public void updateQuickItemImage(boolean visible){ if(visible){ @@ -114,41 +102,4 @@ public final class StatusView extends RelativeLayout { world.tileManager.setImageViewTileForUIIcon(quickToggle, TileManager.iconID_boxclosed); } } - - private static class GreedyImageViewAppender { - private final LinearLayout container; - private final Context context; - private int currentChildIndex = 0; - private final int previousChildCount; - private final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); - - public GreedyImageViewAppender(Context context, LinearLayout container) { - this.container = container; - this.context = context; - this.previousChildCount = container.getChildCount(); - } - public ImageView getNextImage() { - // Since this is called a lot, we do not want to recreate the view objects every time. - // Therefore, we reuse existing ImageView:s if they are present, but just change the image on them. - ImageView iv; - if (currentChildIndex < previousChildCount) { - // There already is a create dimage on this position, reuse it. - iv = (ImageView) container.getChildAt(currentChildIndex); - iv.setVisibility(View.VISIBLE); - } else { - // The player has never had this many conditions, create a new ImageView to hold the condition image. - iv = new ImageView(context); - container.addView(iv, layoutParams); - } - ++currentChildIndex; - return iv; - } - public void removeOtherImages() { - for(int i = previousChildCount - 1; i >= currentChildIndex; --i) { - //container.removeViewAt(i); - // Don't actually remove them, just hide them (so we won't have to recreate them next time the player get a condition) - container.getChildAt(i).setVisibility(View.GONE); - } - } - } }