UI to show actor conditions active on the targeted NPC during battle.

This commit is contained in:
Zukero
2017-10-24 18:23:45 +02:00
parent 8667e925f3
commit 29379be41c
13 changed files with 599 additions and 141 deletions

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:fromYDelta="0%"
android:toYDelta="-100%"
android:duration="300"
/>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:fromXDelta="0%"
android:toXDelta="100%"
android:duration="300"
/>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:fromYDelta="-100%"
android:toYDelta="0%"
android:duration="300"
/>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:fromXDelta="100%"
android:toXDelta="0%"
android:duration="300"
/>

View File

@@ -1,93 +1,130 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
>
<LinearLayout
android:id="@+id/combatview_actionbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal" >
<Button android:id="@+id/combatview_moveattack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:textSize="@dimen/actionbar_text"
android:text="@string/combat_attack"
/>
<RelativeLayout
android:id="@+id/combatview_fixedarea"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView android:id="@+id/combatview_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/actionbar_text"
android:layout_weight="1"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="1"
android:shadowColor="#000"
android:paddingBottom="4sp"
android:text="@string/status_ap"
/>
<LinearLayout
android:id="@+id/combatview_actionbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal" >
<Button android:id="@+id/combatview_endturn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:textSize="@dimen/actionbar_text"
android:text="@string/combat_endturn"
/>
<Button
android:id="@+id/combatview_moveattack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:text="@string/combat_attack"
android:textSize="@dimen/actionbar_text" />
<Button android:id="@+id/combatview_flee"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:textSize="@dimen/actionbar_text"
android:text="@string/combat_flee"
/>
<TextView
android:id="@+id/combatview_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingBottom="4sp"
android:shadowColor="#000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="1"
android:text="@string/status_ap"
android:textSize="@dimen/actionbar_text" />
</LinearLayout>
<Button
android:id="@+id/combatview_endturn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:text="@string/combat_endturn"
android:textSize="@dimen/actionbar_text" />
<TextView android:id="@+id/combatview_monsterismoving"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/actionbar_text"
android:layout_alignBottom="@id/combatview_actionbar"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="1"
android:shadowColor="#000"
android:paddingBottom="4sp"
android:text="@string/combat_monsteraction"
android:gravity="center"
/>
<Button
android:id="@+id/combatview_flee"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:text="@string/combat_flee"
android:textSize="@dimen/actionbar_text" />
</LinearLayout>
<LinearLayout
android:id="@+id/combatview_monsterbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_below="@id/combatview_actionbar"
>
<TextView
android:id="@+id/combatview_monsterismoving"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/combatview_actionbar"
android:gravity="center"
android:paddingBottom="4sp"
android:shadowColor="#000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="1"
android:text="@string/combat_monsteraction"
android:textSize="@dimen/actionbar_text" />
<ImageButton android:id="@+id/combatview_monsterinfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:layout_marginRight="5sp"
android:contentDescription="@string/dialog_monsterencounter_info"
/>
<RelativeLayout
android:id="@+id/combatview_monsterbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/combatview_actionbar"
android:gravity="center_vertical"
android:orientation="horizontal"
>
<!-- android:animateLayoutChanges="true" -->
<com.gpl.rpg.AndorsTrail.view.RangeBar
android:id="@+id/combatview_monsterhealth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ImageButton
android:id="@+id/combatview_monsterinfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_margin="0sp"
android:contentDescription="@string/dialog_monsterencounter_info"
android:padding="8dp"
android:scaleType="fitCenter" />
</LinearLayout>
<ImageButton
android:id="@+id/combatview_monsterconditions_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_margin="0sp"
android:contentDescription="@string/dialog_monsterencounter_conditions"
android:padding="8dp"
android:scaleType="fitCenter" />
<com.gpl.rpg.AndorsTrail.view.RangeBar
android:id="@+id/combatview_monsterhealth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/combatview_monsterconditions_button"
android:layout_toRightOf="@id/combatview_monsterinfo" />
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/combatview_activeconditions_cliparea"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/combatview_fixedarea"
android:layout_margin="5dp"
android:gravity="right" >
<RelativeLayout
android:id="@+id/combatview_activeconditions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right" />
</RelativeLayout>
</merge>

View File

@@ -9,6 +9,26 @@
"increaseDamageResistance": -1
}
},
{
"id": "chaotic_test",
"iconID": "actorconditions_1:95",
"name": "Chaotic test",
"category": "mental",
"abilityEffect": {
"increaseBlockChance": -10,
"increaseDamageResistance": -1
}
},
{
"id": "chaotic_test2",
"iconID": "actorconditions_1:94",
"name": "Chaotic test2",
"category": "mental",
"abilityEffect": {
"increaseBlockChance": -10,
"increaseDamageResistance": -1
}
},
{
"id": "chaotic_curse",
"iconID": "actorconditions_1:89",

View File

@@ -161,7 +161,7 @@
"addedConditions":[
{
"condition":"chaotic_grip",
"magnitude": 1
"magnitude": 5
}
]
},
@@ -171,7 +171,17 @@
"max": 1
}
},
"hitReceivedEffect" : {
"hitEffect":{
"conditionsTarget":[
{
"condition":"chaotic_test",
"magnitude":5,
"duration":2,
"chance":"100"
}
]
},
"hitReceivedEffect" : {
"increaseCurrentHP": {
"min": 1,
"max": 1
@@ -191,7 +201,7 @@
"conditionsSource":[
{
"condition":"chaotic_grip",
"magnitude": 1,
"magnitude": 2,
"duration": 5,
"chance":"50"
}
@@ -199,9 +209,15 @@
"conditionsTarget":[
{
"condition":"chaotic_grip",
"magnitude": 1,
"magnitude": 2,
"duration": 5,
"chance":"80"
},
{
"condition":"chaotic_test2",
"magnitude":3,
"duration":4,
"chance":"50"
}
]
}

View File

@@ -25,6 +25,7 @@
<string name="dialog_monsterencounter_title">Encounter</string>
<string name="dialog_monsterencounter_message">Do you want to attack?\nDifficulty: %1$s</string>
<string name="dialog_monsterencounter_info">Info</string>
<string name="dialog_monsterencounter_conditions">Conditions</string>
<string name="status_hp">HP:</string>
<string name="status_ap">AP:</string>

View File

@@ -14,11 +14,11 @@ import java.util.Locale;
public final class AndorsTrailApplication extends Application {
public static final boolean DEVELOPMENT_DEBUGRESOURCES = true;
public static final boolean DEVELOPMENT_DEBUGRESOURCES = false;
public static final boolean DEVELOPMENT_FORCE_STARTNEWGAME = false;
public static final boolean DEVELOPMENT_FORCE_CONTINUEGAME = false;
public static final boolean DEVELOPMENT_DEBUGBUTTONS = true;
public static final boolean DEVELOPMENT_FASTSPEED = false;
public static final boolean DEVELOPMENT_FASTSPEED = true;
public static final boolean DEVELOPMENT_VALIDATEDATA = true;
public static final boolean DEVELOPMENT_DEBUGMESSAGES = false;
public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES || DEVELOPMENT_DEBUGBUTTONS || DEVELOPMENT_FASTSPEED;

View File

@@ -1,17 +1,17 @@
package com.gpl.rpg.AndorsTrail.activity;
import java.lang.ref.WeakReference;
import java.util.Collection;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.*;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -33,18 +33,22 @@ import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry;
import com.gpl.rpg.AndorsTrail.model.item.Loot;
import com.gpl.rpg.AndorsTrail.model.map.MapObject;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection;
import com.gpl.rpg.AndorsTrail.savegames.Savegames;
import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.view.*;
import com.gpl.rpg.AndorsTrail.view.QuickButton.QuickButtonContextMenuInfo;
import java.lang.ref.WeakReference;
import java.util.Collection;
import com.gpl.rpg.AndorsTrail.view.CombatView;
import com.gpl.rpg.AndorsTrail.view.DisplayActiveActorConditionIcons;
import com.gpl.rpg.AndorsTrail.view.ItemContainerAdapter;
import com.gpl.rpg.AndorsTrail.view.MainView;
import com.gpl.rpg.AndorsTrail.view.QuickButton;
import com.gpl.rpg.AndorsTrail.view.QuickitemView;
import com.gpl.rpg.AndorsTrail.view.QuickslotsItemContainerAdapter;
import com.gpl.rpg.AndorsTrail.view.StatusView;
import com.gpl.rpg.AndorsTrail.view.ToolboxView;
import com.gpl.rpg.AndorsTrail.view.VirtualDpadView;
public final class MainActivity
extends Activity
@@ -90,6 +94,7 @@ public final class MainActivity
combatview = (CombatView) findViewById(R.id.main_combatview);
quickitemview = (QuickitemView) findViewById(R.id.main_quickitemview);
activeConditions = new DisplayActiveActorConditionIcons(controllers, world, this, (RelativeLayout) findViewById(R.id.statusview_activeconditions));
activeConditions.setTarget(world.model.player);
VirtualDpadView dpad = (VirtualDpadView) findViewById(R.id.main_virtual_dpad);
toolboxview = (ToolboxView) findViewById(R.id.main_toolboxview);
statusview.registerToolboxViews(toolboxview, quickitemview);

View File

@@ -1,12 +1,17 @@
package com.gpl.rpg.AndorsTrail.resource.tiles;
import android.R;
import java.util.HashMap;
import java.util.HashSet;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ScaleDrawable;
import android.os.AsyncTask;
import android.widget.ImageView;
import android.widget.TextView;
@@ -21,12 +26,13 @@ import com.gpl.rpg.AndorsTrail.model.item.Inventory;
import com.gpl.rpg.AndorsTrail.model.item.ItemContainer;
import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.map.*;
import com.gpl.rpg.AndorsTrail.model.map.LayeredTileMap;
import com.gpl.rpg.AndorsTrail.model.map.MapObject;
import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.model.map.TMXMapTranslator;
import com.gpl.rpg.AndorsTrail.util.L;
import java.util.HashMap;
import java.util.HashSet;
public final class TileManager {
public static final int CHAR_HERO = 1;
public static final int iconID_selection_red = 2;
@@ -216,6 +222,7 @@ public final class TileManager {
public void setImageViewTileForPlayer(Resources res, ImageView imageView, int iconID) { setImageViewTile(res, imageView, preloadedTiles.getBitmap(iconID)); }
// public void setImageViewTile(Resources res, ImageView imageView, ActorConditionType conditionType) { setImageViewTile(res, imageView, preloadedTiles.getBitmap(conditionType.iconID)); }
public void setImageViewTile(Resources res, ImageView imageView, ActorConditionType conditionType, boolean immunityOverlay) { setImageViewTile(res, imageView, preloadedTiles.getBitmap(conditionType.iconID), immunityOverlay); }
public void setImageViewTile(Resources res, ImageView imageView, ActorConditionType conditionType, boolean immunityOverlay, String exponent, String index) { setImageViewTile(res, imageView, preloadedTiles.getBitmap(conditionType.iconID), immunityOverlay, exponent, index); }
public void setImageViewTileForUIIcon(Resources res, ImageView imageView, int iconID) { setImageViewTile(res, imageView, preloadedTiles.getBitmap(iconID)); }
public void setImageViewTile(Resources res, ImageView imageView, Bitmap b) {
if (density > 1) {
@@ -225,20 +232,41 @@ public final class TileManager {
}
}
public void setImageViewTile(Resources res, ImageView imageView, Bitmap b, boolean immunityOverlay) {
if (!immunityOverlay) setImageViewTile(res, imageView, b);
setImageViewTile(res, imageView, b, immunityOverlay, null, null);
}
public void setImageViewTile(Resources res, ImageView imageView, Bitmap b, boolean immunityOverlay, String exponent, String index) {
if (!immunityOverlay && exponent == null && index == null) setImageViewTile(res, imageView, b);
else {
Drawable[] layers = new Drawable[2];
Drawable[] layers = new Drawable[1+
(immunityOverlay ? 1 : 0)+
(exponent != null ? 1 : 0)+
(index != null ? 1 : 0)];
int tileWidth;
if (density > 1) {
layers[0] = new BitmapDrawable(res, Bitmap.createScaledBitmap(b, (int)(tileSize*density), (int)(tileSize*density), true));
layers[1] = new BitmapDrawable(res, preloadedTiles.getBitmap(iconID_immunity_overlay));
tileWidth = (int)(tileSize*density);
layers[0] = new BitmapDrawable(res, Bitmap.createScaledBitmap(b, tileWidth, tileWidth, true));
} else {
tileWidth = tileSize;
layers[0] = new BitmapDrawable(res, b);
layers[1] = new BitmapDrawable(res, preloadedTiles.getBitmap(iconID_immunity_overlay));
}
int nextIndex = 1;
if (immunityOverlay) {
layers[nextIndex] = new BitmapDrawable(res, preloadedTiles.getBitmap(iconID_immunity_overlay));
nextIndex++;
}
if (exponent != null) {
layers[nextIndex] = new TextDrawable(res, tileWidth, tileWidth, exponent, TextDrawable.Align.TOP_RIGHT);
nextIndex++;
}
if (index != null) {
layers[nextIndex] = new TextDrawable(res, tileWidth, tileWidth, index, TextDrawable.Align.BOTTOM_RIGHT);
nextIndex++;
}
LayerDrawable layered = new LayerDrawable(layers);
setImageViewTile(imageView, layered);
}
}
public void setImageViewTile(ImageView imageView, Drawable d) {
imageView.setImageDrawable(d);
}
@@ -257,20 +285,19 @@ public final class TileManager {
overlayDrawable = new BitmapDrawable(res, preloadedTiles.getBitmap(overlayIconID));
iconDrawable = new BitmapDrawable(res, icon);
}
if (overlayAbove) {
setImageViewTile(imageView,
new LayerDrawable(new Drawable[] {
iconDrawable
,overlayDrawable
})
);
LayerDrawable layered = new LayerDrawable(new Drawable[] {
iconDrawable
,overlayDrawable
});
setImageViewTile(imageView, layered);
} else {
setImageViewTile(imageView,
new LayerDrawable(new Drawable[] {
overlayDrawable
,iconDrawable
})
);
LayerDrawable layered = new LayerDrawable(new Drawable[] {
overlayDrawable
,iconDrawable
});
setImageViewTile(imageView, layered);
}
} else {
setImageViewTile(res, imageView, icon);
@@ -335,4 +362,143 @@ public final class TileManager {
}
}).execute();
}
private static class TextDrawable extends Drawable {
private String text;
private int size = 15;
private Align align = Align.CENTER;
private Paint mPaint;
private Rect textBounds;
private int cHeight;
private int cWidth;
public enum Align {
TOP,
TOP_LEFT,
TOP_RIGHT,
CENTER,
LEFT,
RIGHT,
BOTTOM,
BOTTOM_LEFT,
BOTTOM_RIGHT
}
public TextDrawable(Resources res, int cWidth, int cHeight, String text, Align align, int size) {
this.text= text;
this.align = align;
this.size = size;
this.cWidth = cWidth;
this.cHeight = cHeight;
init(res);
}
public TextDrawable(Resources res, int cWidth, int cHeight, String text, Align align) {
this.text= text;
this.align = align;
this.cWidth = cWidth;
this.cHeight = cHeight;
init(res);
}
public TextDrawable(Resources res, int cWidth, int cHeight, String text) {
this.text= text;
this.cWidth = cWidth;
this.cHeight = cHeight;
init(res);
}
public void init(Resources res) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(res.getColor(android.R.color.black));
mPaint.setShadowLayer(1, 1, 1, res.getColor(android.R.color.white));
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextSize(size * res.getDisplayMetrics().scaledDensity);
textBounds = new Rect();
mPaint.getTextBounds(text, 0, text.length(), textBounds);
}
@Override
public void draw(Canvas canvas) {
float x,y;
switch (align) {
case BOTTOM:
case BOTTOM_LEFT:
case BOTTOM_RIGHT:
y = cHeight - textBounds.bottom;
break;
case CENTER:
case LEFT:
case RIGHT:
y = (cHeight - textBounds.height()) / 2;
break;
case TOP:
case TOP_LEFT:
case TOP_RIGHT:
default:
y = 0 - textBounds.top;
break;
}
switch (align) {
case BOTTOM:
case CENTER:
case TOP:
x = (cWidth - textBounds.width()) / 2;
break;
case BOTTOM_LEFT:
case LEFT:
case TOP_LEFT:
default:
x = 0 - textBounds.left;
break;
case BOTTOM_RIGHT:
case RIGHT:
case TOP_RIGHT:
x = cWidth - textBounds.right;
break;
}
canvas.drawText(text, x, y, mPaint);
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return mPaint.getAlpha();
}
@Override
public int getIntrinsicWidth() {
return cWidth;
}
@Override
public int getIntrinsicHeight() {
return cHeight;
}
@Override
public boolean getPadding(Rect padding) {
padding.bottom = 0;
padding.top = 0;
padding.left = 0;
padding.right = 0;
return false;
}
}
}

View File

@@ -1,10 +1,12 @@
package com.gpl.rpg.AndorsTrail.view;
import android.R.color;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
@@ -12,6 +14,7 @@ import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
import com.gpl.rpg.AndorsTrail.Dialogs;
@@ -19,21 +22,26 @@ import com.gpl.rpg.AndorsTrail.R;
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.CombatController;
import com.gpl.rpg.AndorsTrail.controller.listeners.ActorConditionListener;
import com.gpl.rpg.AndorsTrail.controller.listeners.ActorStatsListener;
import com.gpl.rpg.AndorsTrail.controller.listeners.CombatSelectionListener;
import com.gpl.rpg.AndorsTrail.controller.listeners.CombatTurnListener;
import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.util.Coord;
public final class CombatView extends RelativeLayout implements CombatSelectionListener, CombatTurnListener, ActorStatsListener {
public final class CombatView extends RelativeLayout implements CombatSelectionListener, CombatTurnListener, ActorStatsListener, ActorConditionListener {
private final TextView statusTextView;
private final Button attackMoveButton;
private final ImageButton monsterInfo;
private final RangeBar monsterHealth;
private final View monsterBar;
private final View actionBar;
private final ImageButton monsterConditionsButton;
private final RelativeLayout activeConditionsBar;
private DisplayActiveActorConditionIcons activeConditions;
private final ViewGroup monsterBar;
private final ViewGroup actionBar;
private final TextView monsterActionText;
private final WorldContext world;
@@ -43,8 +51,13 @@ public final class CombatView extends RelativeLayout implements CombatSelectionL
private final Player player;
private final Animation displayAnimation;
private final Animation hideAnimation;
private final Animation displayConditionsButtonAnimation;
private final Animation hideConditionsButtonAnimation;
private final Animation displayConditionsBarAnimation;
private final Animation hideConditionsBarAnimation;
private Monster currentMonster;
private boolean conditionsBarToggled = false;
public CombatView(final Context context, AttributeSet attr) {
super(context, attr);
@@ -57,7 +70,8 @@ public final class CombatView extends RelativeLayout implements CombatSelectionL
setFocusable(false);
inflate(context, R.layout.combatview, this);
this.setBackgroundResource(R.drawable.ui_gradientshape_translucent);
findViewById(R.id.combatview_fixedarea).setBackgroundResource(R.drawable.ui_gradientshape_translucent);
// this.setBackgroundResource(R.drawable.ui_gradientshape_translucent);
final CombatController c = controllers.combatController;
attackMoveButton = (Button) findViewById(R.id.combatview_moveattack);
@@ -95,10 +109,22 @@ public final class CombatView extends RelativeLayout implements CombatSelectionL
monsterHealth = (RangeBar) findViewById(R.id.combatview_monsterhealth);
monsterHealth.init(R.drawable.ui_progress_health, R.string.combat_monsterhealth);
monsterBar = findViewById(R.id.combatview_monsterbar);
actionBar = findViewById(R.id.combatview_actionbar);
monsterBar = (ViewGroup) findViewById(R.id.combatview_monsterbar);
actionBar = (ViewGroup) findViewById(R.id.combatview_actionbar);
monsterActionText = (TextView) findViewById(R.id.combatview_monsterismoving);
monsterConditionsButton = (ImageButton) findViewById(R.id.combatview_monsterconditions_button);
monsterConditionsButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
toggleConditionsBarVisibility();
}
});
activeConditionsBar = (RelativeLayout) findViewById(R.id.combatview_activeconditions);
activeConditions = new DisplayActiveActorConditionIcons(controllers, world, context, activeConditionsBar);
monsterBar.setBackgroundColor(res.getColor(color.transparent));
actionBar.setBackgroundColor(res.getColor(color.transparent));
@@ -111,8 +137,34 @@ public final class CombatView extends RelativeLayout implements CombatSelectionL
CombatView.this.setVisibility(View.GONE);
}
});
displayConditionsButtonAnimation = AnimationUtils.loadAnimation(context, R.anim.showmonsterconditionbutton);
hideConditionsButtonAnimation = AnimationUtils.loadAnimation(context, R.anim.hidemonsterconditionbutton);
hideConditionsButtonAnimation.setAnimationListener(new AnimationListener() {
@Override public void onAnimationStart(Animation animation) {}
@Override public void onAnimationRepeat(Animation animation) {}
@Override public void onAnimationEnd(Animation arg0) {
monsterConditionsButton.setVisibility(View.GONE);
}
});
displayConditionsBarAnimation = AnimationUtils.loadAnimation(context, R.anim.showmonsterconditionbar);
hideConditionsBarAnimation = AnimationUtils.loadAnimation(context, R.anim.hidemonsterconditionbar);
hideConditionsBarAnimation.setAnimationListener(new AnimationListener() {
@Override public void onAnimationStart(Animation animation) {}
@Override public void onAnimationRepeat(Animation animation) {}
@Override public void onAnimationEnd(Animation arg0) {
activeConditionsBar.setVisibility(View.GONE);
}
});
}
private void toggleConditionsBarVisibility() {
conditionsBarToggled = !conditionsBarToggled;
if (conditionsBarToggled) showConditionsBar();
else hideConditionsBar();
}
private void updateTurnInfo(Monster currentActiveMonster) {
if (currentActiveMonster != null) {
actionBar.setVisibility(View.INVISIBLE);
@@ -144,8 +196,73 @@ public final class CombatView extends RelativeLayout implements CombatSelectionL
currentMonster = selectedMonster;
}
updateAttackMoveButtonText(selectedMonster != null);
updateConditions();
}
private void updateConditions() {
activeConditions.setTarget(currentMonster);
if (currentMonster == null) {
hideConditionsButton();
return;
}
if (currentMonster.conditions.size()+currentMonster.immunities.size() > 0) {
if (currentMonster.conditions.size() > 0) world.tileManager.setImageViewTile(res, monsterConditionsButton, currentMonster.conditions.get(0).conditionType, false, Integer.toString(currentMonster.conditions.size()+currentMonster.immunities.size()), null);
else world.tileManager.setImageViewTile(res, monsterConditionsButton, currentMonster.immunities.get(0).conditionType, true, Integer.toString(currentMonster.conditions.size()+currentMonster.immunities.size()), null);
showConditionsButton();
if (conditionsBarToggled) showConditionsBar();
} else {
hideConditionsButton();
hideConditionsBar();
}
}
private void showConditionsButton() {
if (monsterConditionsButton.getVisibility() != View.VISIBLE) {
monsterConditionsButton.setVisibility(View.VISIBLE);
if (preferences.enableUiAnimations) {
monsterConditionsButton.startAnimation(displayConditionsButtonAnimation);
}
}
}
private void hideConditionsButton() {
if (monsterConditionsButton.getVisibility() == View.VISIBLE) {
if (preferences.enableUiAnimations) {
monsterConditionsButton.startAnimation(hideConditionsButtonAnimation);
} else {
monsterConditionsButton.setVisibility(View.GONE);
}
}
}
@SuppressLint("NewApi")
private void showConditionsBar() {
if (activeConditionsBar.getVisibility() != View.VISIBLE) {
activeConditionsBar.setVisibility(View.VISIBLE);
if (preferences.enableUiAnimations) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
// monsterBar.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
// }
activeConditionsBar.startAnimation(displayConditionsBarAnimation);
}
}
}
@SuppressLint("NewApi")
private void hideConditionsBar() {
if (activeConditionsBar.getVisibility() == View.VISIBLE) {
if (preferences.enableUiAnimations) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
// monsterBar.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
// }
activeConditionsBar.startAnimation(hideConditionsBarAnimation);
} else {
activeConditionsBar.setVisibility(View.GONE);
}
}
}
private void updateAttackMoveButtonText() {
updateAttackMoveButtonText(world.model.uiSelections.selectedMonster != null);
}
@@ -183,11 +300,15 @@ public final class CombatView extends RelativeLayout implements CombatSelectionL
controllers.combatController.combatSelectionListeners.add(this);
controllers.combatController.combatTurnListeners.add(this);
controllers.actorStatsController.actorStatsListeners.add(this);
controllers.actorStatsController.actorConditionListeners.add(this);
activeConditions.subscribe();
}
public void unsubscribe() {
controllers.actorStatsController.actorStatsListeners.remove(this);
controllers.combatController.combatTurnListeners.remove(this);
controllers.combatController.combatSelectionListeners.remove(this);
controllers.actorStatsController.actorConditionListeners.remove(this);
activeConditions.unsubscribe();
}
@Override
@@ -245,4 +366,40 @@ public final class CombatView extends RelativeLayout implements CombatSelectionL
public void onActorMoveCostChanged(Actor actor, int newMoveCost) {
if (actor == player) updateAttackMoveButtonText();
}
@Override
public void onActorConditionAdded(Actor actor, ActorCondition condition) {
if (actor == currentMonster) updateConditions();
}
@Override
public void onActorConditionRemoved(Actor actor, ActorCondition condition) {
if (actor == currentMonster) updateConditions();
}
@Override
public void onActorConditionDurationChanged(Actor actor, ActorCondition condition) {
}
@Override
public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition) {
}
@Override
public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition) {
}
@Override
public void onActorConditionImmunityAdded(Actor actor, ActorCondition condition) {
if (actor == currentMonster) updateConditions();
}
@Override
public void onActorConditionImmunityRemoved(Actor actor, ActorCondition condition) {
if (actor == currentMonster) updateConditions();
}
@Override
public void onActorConditionImmunityDurationChanged(Actor actor, ActorCondition condition) {
}
}

View File

@@ -1,7 +1,13 @@
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.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
@@ -10,6 +16,7 @@ import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
import com.gpl.rpg.AndorsTrail.R;
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
@@ -19,9 +26,6 @@ import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
public final class DisplayActiveActorConditionIcons implements ActorConditionListener {
private final AndorsTrailPreferences preferences;
@@ -31,6 +35,8 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
private final RelativeLayout activeConditions;
private final ArrayList<ActiveConditionIcon> currentConditionIcons = new ArrayList<ActiveConditionIcon>();
private final WeakReference<Context> androidContext;
private Actor target;
public DisplayActiveActorConditionIcons(
final ControllerContext controllers,
@@ -44,10 +50,16 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
this.androidContext = new WeakReference<Context>(androidContext);
this.activeConditions = activeConditions;
}
public void setTarget(Actor target) {
if (this.target == target) return;
this.target = target;
cleanUp();
}
@Override
public void onActorConditionAdded(Actor actor, ActorCondition condition) {
if (actor != world.model.player) return;
if (actor != target) return;
ActiveConditionIcon icon = getFirstFreeIcon();
icon.setActiveCondition(condition, false);
icon.show();
@@ -55,7 +67,7 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
@Override
public void onActorConditionRemoved(Actor actor, ActorCondition condition) {
if (actor != world.model.player) return;
if (actor != target) return;
ActiveConditionIcon icon = getIconFor(condition, false);
if (icon == null) return;
icon.hide(true);
@@ -67,7 +79,7 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
@Override
public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition) {
if (actor != world.model.player) return;
if (actor != target) return;
ActiveConditionIcon icon = getIconFor(condition, false);
if (icon == null) return;
icon.setIconText();
@@ -75,7 +87,7 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
@Override
public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition) {
if (actor != world.model.player) return;
if (actor != target) return;
ActiveConditionIcon icon = getIconFor(condition, false);
if (icon == null) return;
icon.pulseAnimate();
@@ -84,7 +96,7 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
@Override
public void onActorConditionImmunityAdded(Actor actor, ActorCondition condition) {
if (actor != world.model.player) return;
if (actor != target) return;
ActiveConditionIcon icon = getFirstFreeIcon();
icon.setActiveCondition(condition, true);
icon.show();
@@ -92,7 +104,7 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
@Override
public void onActorConditionImmunityRemoved(Actor actor, ActorCondition condition) {
if (actor != world.model.player) return;
if (actor != target) return;
ActiveConditionIcon icon = getIconFor(condition, true);
if (icon == null) return;
icon.hide(true);
@@ -108,15 +120,21 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
}
public void subscribe() {
for (ActiveConditionIcon icon : currentConditionIcons) icon.hide(false);
for (ActorCondition condition : world.model.player.conditions) {
getFirstFreeIcon().setActiveCondition(condition, false);
}
for (ActorCondition condition : world.model.player.immunities) {
getFirstFreeIcon().setActiveCondition(condition, true);
}
cleanUp();
controllers.actorStatsController.actorConditionListeners.add(this);
}
private void cleanUp() {
for (ActiveConditionIcon icon : currentConditionIcons) icon.hide(false);
if (target != null) {
for (ActorCondition condition : target.conditions) {
getFirstFreeIcon().setActiveCondition(condition, false);
}
for (ActorCondition condition : target.immunities) {
getFirstFreeIcon().setActiveCondition(condition, true);
}
}
}
private final class ActiveConditionIcon implements AnimationListener {
public final int id;
@@ -133,6 +151,9 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
this.id = id;
this.image = new ImageView(context);
this.image.setId(id);
GradientDrawable grad = new GradientDrawable(target == world.model.player ? Orientation.BOTTOM_TOP : Orientation.TOP_BOTTOM, new int[]{Color.argb(190, 68, 68, 68), Color.argb(10, 34, 34, 34)});
grad.setCornerRadius(3);
this.image.setBackgroundDrawable(grad);
this.text = new TextView(context);
this.onNewIconAnimation = AnimationUtils.loadAnimation(context, R.anim.scaleup);
this.onRemovedIconAnimation = AnimationUtils.loadAnimation(context, R.anim.scaledown);
@@ -227,7 +248,8 @@ public final class DisplayActiveActorConditionIcons implements ActorConditionLis
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 (target == world.model.player) layout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
else layout.addRule(RelativeLayout.ALIGN_PARENT_TOP);
if (index == 0) {
layout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
} else {