mirror of
https://github.com/OMGeeky/andors-trail.git
synced 2026-01-20 18:41:09 +01:00
Merge remote-tracking branch 'origin/animated_moves' into tbrawl_attack_missed_animation
This commit is contained in:
@@ -62,7 +62,7 @@
|
||||
"monsterClass": "insect",
|
||||
"maxHP": 10,
|
||||
"maxAP": 10,
|
||||
"moveCost": 10,
|
||||
"moveCost": 5,
|
||||
"attackCost": 10,
|
||||
"attackChance": 50,
|
||||
"droplistID": "debuglist1",
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
Additional programming by Ethan Wessel<br />
|
||||
Additional programming by Scott Lund<br />
|
||||
Additional programming by <a href="https://github.com/Zukero">Kevin Pochat</a><br />
|
||||
Additional programming by Lucas Delvallet<br />
|
||||
Additional programming by Florian Doublet<br />
|
||||
Additional graphics by Karvis<br />
|
||||
Russian translation by Dreamer..., e.solodookhin, shell.andor, konstmih, istasman, Aleksey Kabanov, Alexander Zubok, Paul Sulemenkov and dromoz<br />
|
||||
Italian translation by k6blue, liogiu, Joker and Andrea Luciano Damico<br />
|
||||
|
||||
@@ -355,8 +355,11 @@
|
||||
<item>@xml/blackwater_mountain3</item>
|
||||
<item>@xml/blackwater_mountain4</item>
|
||||
<item>@xml/blackwater_mountain5</item>
|
||||
<item>@xml/blackwater_mountain5a</item>
|
||||
<item>@xml/blackwater_mountain5c</item>
|
||||
<item>@xml/blackwater_mountain6</item>
|
||||
<item>@xml/blackwater_mountain7</item>
|
||||
<item>@xml/blackwater_mountain7a</item>
|
||||
<item>@xml/blackwater_mountain8</item>
|
||||
<item>@xml/blackwater_mountain9</item>
|
||||
<item>@xml/blackwater_mountain10</item>
|
||||
|
||||
@@ -174,11 +174,11 @@
|
||||
<property name="place" value="north"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object name="quest:queststage" type="replace" x="192" y="352" width="96" height="128">
|
||||
<object name="futurequest:10" type="replace" x="192" y="352" width="96" height="128">
|
||||
<properties>
|
||||
<property name="Above" value="Above_replace"/>
|
||||
<property name="Objects" value="Objects_replace"/>
|
||||
<property name="Walkalbe" value="Walkalbe_replace"/>
|
||||
<property name="Walkable" value="Walkable_replace"/>
|
||||
</properties>
|
||||
</object>
|
||||
</objectgroup>
|
||||
|
||||
@@ -237,15 +237,10 @@
|
||||
</objectgroup>
|
||||
<objectgroup name="Keys" width="19" height="12"/>
|
||||
<objectgroup name="Replace" width="19" height="12">
|
||||
<object name="quest:queststage" type="replace" x="0" y="224" width="192" height="96">
|
||||
<object name="futurequest:10" type="replace" x="0" y="192" width="192" height="128">
|
||||
<properties>
|
||||
<property name="Walkalbe" value="Walkalbe_replace"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object name="quest:queststage" type="replace" x="0" y="192" width="192" height="128">
|
||||
<properties>
|
||||
<property name="Above" value="Walkable_replace"/>
|
||||
<property name="Objects" value="Objects_replace"/>
|
||||
<property name="Walkable" value="Walkable_replace"/>
|
||||
</properties>
|
||||
</object>
|
||||
</objectgroup>
|
||||
|
||||
@@ -122,12 +122,12 @@
|
||||
</tileset>
|
||||
<layer name="Ground" width="10" height="10">
|
||||
<data encoding="base64" compression="zlib">
|
||||
eJw7ysbAcHSQ4ydUNOsEEqalultkmgcAw35PpQ==
|
||||
eJw7ysbAcHQQ4wYOBoYnVDTvBBKmpbpbZJoHAISsT2I=
|
||||
</data>
|
||||
</layer>
|
||||
<layer name="Objects" width="10" height="10">
|
||||
<data encoding="base64" compression="zlib">
|
||||
eJxjYMAOktlxSNAYSFDRXlsm6plFLwAA6HwAyQ==
|
||||
eJyby88AB7FI7JvMDBSDbDLMyOQnrIZYYMtEPbNIBfPI9AcAQ5QDxw==
|
||||
</data>
|
||||
</layer>
|
||||
<layer name="Above" width="10" height="10">
|
||||
@@ -140,7 +140,7 @@
|
||||
eJxjYBi+wFVgoF1AOgAAPUQAVg==
|
||||
</data>
|
||||
</layer>
|
||||
<objectgroup name="Object Layer 1">
|
||||
<objectgroup name="Object Layer 1" width="0" height="0">
|
||||
<object name="debugsign" type="sign" x="192" y="96" width="32" height="32"/>
|
||||
<object name="start" type="rest" x="96" y="64" width="32" height="32"/>
|
||||
<object name="Unopenable key area" type="key" x="32" y="128" width="32" height="32">
|
||||
@@ -181,10 +181,10 @@
|
||||
</properties>
|
||||
</object>
|
||||
</objectgroup>
|
||||
<objectgroup name="Spawn">
|
||||
<objectgroup name="Spawn" width="0" height="0">
|
||||
<object name="insect" type="spawn" x="96" y="128" width="192" height="160">
|
||||
<properties>
|
||||
<property name="quantity" value="2"/>
|
||||
<property name="quantity" value="15"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object name="troll" type="spawn" x="256" y="256" width="64" height="64">
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress;
|
||||
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.ListIterator;
|
||||
|
||||
public final class ConversationActivity
|
||||
extends Activity
|
||||
@@ -46,11 +47,16 @@ public final class ConversationActivity
|
||||
private static final int playerPhraseColor = 0;
|
||||
private static final int NPCPhraseColor = 0;
|
||||
private static final int rewardColor = Color.argb(255, 0x99, 0x99, 0x55);
|
||||
private static final int oldPhraseColor = Color.argb(255,0x5a,0x5a, 0x5a);
|
||||
private static final int oldPlayerNameColor = Color.argb(255, 0x5d, 0x11, 0x11);
|
||||
private static final int oldNPCNameColor = Color.argb(255, 0x5d, 0x5d, 0x11);
|
||||
private static final int oldRewardColor = Color.argb(255, 0x4C, 0x4C, 0x2A);
|
||||
|
||||
private WorldContext world;
|
||||
private Player player;
|
||||
private final ArrayList<ConversationStatement> conversationHistory = new ArrayList<ConversationStatement>();
|
||||
private ConversationController.ConversationStatemachine conversationState;
|
||||
private int numberOfNewMessage = 0;
|
||||
|
||||
private StatementContainerAdapter listAdapter;
|
||||
private Button nextButton;
|
||||
@@ -206,7 +212,26 @@ public final class ConversationActivity
|
||||
return null; // No reply was found. This is probably an error.
|
||||
}
|
||||
|
||||
private void greyAllConversationStatement(){
|
||||
int numberOfMessage = this.conversationHistory.size();
|
||||
while(numberOfNewMessage != 0){
|
||||
ConversationStatement conversation = conversationHistory.get(numberOfMessage - numberOfNewMessage);
|
||||
if(conversation.hasActor()){
|
||||
conversation.textColor = oldPhraseColor;
|
||||
if(conversation.isPlayerActor){
|
||||
conversation.nameColor = oldPlayerNameColor;
|
||||
} else {
|
||||
conversation.nameColor = oldNPCNameColor;
|
||||
}
|
||||
}else{
|
||||
conversation.textColor = oldRewardColor;
|
||||
}
|
||||
numberOfNewMessage--;
|
||||
}
|
||||
}
|
||||
|
||||
private void nextButtonClicked() {
|
||||
greyAllConversationStatement();
|
||||
RadioButton rb = getSelectedReplyButton();
|
||||
replyGroup.removeAllViews();
|
||||
nextButton.setEnabled(false);
|
||||
@@ -233,6 +258,7 @@ public final class ConversationActivity
|
||||
s.textColor = textColor;
|
||||
s.isPlayerActor = actor != null && actor == player;
|
||||
conversationHistory.add(s);
|
||||
numberOfNewMessage++;
|
||||
statementList.clearFocus();
|
||||
listAdapter.notifyDataSetChanged();
|
||||
statementList.requestLayout();
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class DebugInterface {
|
||||
private final ControllerContext controllerContext;
|
||||
private final MainActivity mainActivity;
|
||||
|
||||
@@ -32,7 +32,7 @@ public final class Constants {
|
||||
public static final int TICKS_PER_FULLROUND = FULLROUND_DURATION / TICK_DELAY;
|
||||
public static final int SPLATTER_DURATION_MS = 20000;
|
||||
|
||||
public static final ConstRange monsterWaitTurns = new ConstRange(30,4);
|
||||
public static final ConstRange monsterWaitTurns = new ConstRange(5,1);
|
||||
public static final long MAP_UNVISITED_RESPAWN_DURATION_MS = 3 * 60 * 1000; // 3 min in milliseconds
|
||||
|
||||
public static final String PREFERENCE_MODEL_LASTRUNVERSION = "lastversion";
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.res.Resources;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.model.GameStatistics;
|
||||
import com.gpl.rpg.AndorsTrail.model.ability.*;
|
||||
import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
|
||||
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect;
|
||||
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionType;
|
||||
import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection;
|
||||
import com.gpl.rpg.AndorsTrail.model.ability.SkillInfo;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Player;
|
||||
@@ -25,8 +32,6 @@ import com.gpl.rpg.AndorsTrail.model.script.ScriptEffect;
|
||||
import com.gpl.rpg.AndorsTrail.util.ConstRange;
|
||||
import com.gpl.rpg.AndorsTrail.util.L;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class ConversationController {
|
||||
|
||||
private final ControllerContext controllers;
|
||||
@@ -108,6 +113,9 @@ public final class ConversationController {
|
||||
case deactivateMapChangeArea:
|
||||
deactivateMapChangeArea(effect.mapName, effect.effectID);
|
||||
break;
|
||||
case removeQuestProgress:
|
||||
addRemoveQuestProgressReward(player, effect.effectID, effect.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,14 +164,21 @@ public final class ConversationController {
|
||||
private void addQuestProgressReward(Player player, String questID, int questProgress, ScriptEffectResult result) {
|
||||
QuestProgress progress = new QuestProgress(questID, questProgress);
|
||||
boolean added = player.addQuestProgress(progress);
|
||||
|
||||
if (!added) return; // Only apply exp reward if the quest stage was reached just now (and not re-reached)
|
||||
|
||||
QuestLogEntry stage = world.quests.getQuestLogEntry(progress);
|
||||
if (stage == null) return;
|
||||
|
||||
result.loot.exp += stage.rewardExperience;
|
||||
result.questProgress.add(progress);
|
||||
}
|
||||
|
||||
private void addRemoveQuestProgressReward(Player player, String questID, int questProgress) {
|
||||
QuestProgress progress = new QuestProgress(questID, questProgress);
|
||||
player.removeQuestProgress(progress);
|
||||
}
|
||||
|
||||
private void addDropListReward(Player player, String droplistID, ScriptEffectResult result) {
|
||||
world.dropLists.getDropList(droplistID).createRandomLoot(result.loot, player);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public final class MonsterMovementController implements EvaluateWalkable {
|
||||
private void moveMonster(final Monster m, final MonsterSpawnArea area) {
|
||||
PredefinedMap map = world.model.currentMap;
|
||||
LayeredTileMap tileMap = world.model.currentTileMap;
|
||||
m.nextActionTime += getMillisecondsPerMove(m);
|
||||
m.nextActionTime = System.currentTimeMillis() + getMillisecondsPerMove(m);
|
||||
if (m.movementDestination == null) {
|
||||
// Monster has waited and should start to move again.
|
||||
m.movementDestination = new Coord(m.position);
|
||||
@@ -128,7 +128,7 @@ public final class MonsterMovementController implements EvaluateWalkable {
|
||||
|
||||
private static void cancelCurrentMonsterMovement(final Monster m) {
|
||||
m.movementDestination = null;
|
||||
m.nextActionTime += getMillisecondsPerMove(m) * Constants.rollValue(Constants.monsterWaitTurns);
|
||||
m.nextActionTime = System.currentTimeMillis() + (getMillisecondsPerMove(m) * Constants.rollValue(Constants.monsterWaitTurns));
|
||||
}
|
||||
|
||||
private static int getMillisecondsPerMove(Monster m) {
|
||||
@@ -151,9 +151,17 @@ public final class MonsterMovementController implements EvaluateWalkable {
|
||||
return monsterCanMoveTo(world.model.currentMap, world.model.currentTileMap, r);
|
||||
}
|
||||
|
||||
public void moveMonsterToNextPosition(Monster m, PredefinedMap map) {
|
||||
CoordRect previousPosition = new CoordRect(new Coord(m.position), m.rectPosition.size);
|
||||
public void moveMonsterToNextPosition(final Monster m, final PredefinedMap map) {
|
||||
final CoordRect previousPosition = new CoordRect(new Coord(m.position), m.rectPosition.size);
|
||||
m.lastPosition.set(previousPosition.topLeft);
|
||||
m.position.set(m.nextPosition.topLeft);
|
||||
monsterMovementListeners.onMonsterMoved(map, m, previousPosition);
|
||||
controllers.effectController.startActorMoveEffect(m, previousPosition.topLeft, m.position, getMillisecondsPerMove(m) / 4, new VisualEffectController.VisualEffectCompletedCallback() {
|
||||
|
||||
@Override
|
||||
public void onVisualEffectCompleted(int callbackValue) {
|
||||
|
||||
monsterMovementListeners.onMonsterMoved(map, m, previousPosition);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,15 +228,24 @@ public final class MovementController implements TimedMessageTask.Callback {
|
||||
player.lastPosition.set(player.position);
|
||||
player.position.set(newPosition);
|
||||
controllers.combatController.setCombatSelection(null, null);
|
||||
playerMovementListeners.onPlayerMoved(newPosition, player.lastPosition);
|
||||
|
||||
controllers.effectController.startActorMoveEffect(player, player.lastPosition, newPosition, (int) (Constants.MINIMUM_INPUT_INTERVAL / 2), new VisualEffectController.VisualEffectCompletedCallback() {
|
||||
|
||||
@Override
|
||||
public void onVisualEffectCompleted(int callbackValue) {
|
||||
playerMovementListeners.onPlayerMoved(newPosition, player.lastPosition);
|
||||
|
||||
controllers.mapController.handleMapEventsAfterMovement(currentMap, newPosition, player.lastPosition);
|
||||
controllers.mapController.handleMapEventsAfterMovement(currentMap, newPosition, player.lastPosition);
|
||||
|
||||
if (!world.model.uiSelections.isInCombat) {
|
||||
//currentMap can be outdated due to mapchange events processed above.
|
||||
Loot loot = world.model.currentMap.getBagAt(newPosition);
|
||||
if (loot != null) controllers.itemController.playerSteppedOnLootBag(loot);
|
||||
}
|
||||
if (!world.model.uiSelections.isInCombat) {
|
||||
//currentMap can be outdated due to mapchange events processed above.
|
||||
Loot loot = world.model.currentMap.getBagAt(newPosition);
|
||||
if (loot != null) controllers.itemController.playerSteppedOnLootBag(loot);
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void respawnPlayer(Resources res) {
|
||||
|
||||
@@ -4,9 +4,11 @@ import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.controller.listeners.VisualEffectFrameListeners;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
|
||||
import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
|
||||
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
|
||||
@@ -54,7 +56,70 @@ public final class VisualEffectController {
|
||||
enqueuedEffectID = null;
|
||||
enqueuedEffectValue = 0;
|
||||
}
|
||||
|
||||
public void startActorMoveEffect(Actor actor, Coord origin, Coord destination, int duration, VisualEffectCompletedCallback callback, int callbackValue) {
|
||||
++effectCount;
|
||||
(new SpriteMoveAnimation(origin, destination, duration, actor, callback, callbackValue))
|
||||
.start();
|
||||
}
|
||||
|
||||
public final class SpriteMoveAnimation extends Handler implements Runnable {
|
||||
|
||||
private static final int millisecondsPerFrame=25;
|
||||
|
||||
private final VisualEffectCompletedCallback callback;
|
||||
private final int callbackValue;
|
||||
|
||||
public final int duration;
|
||||
public final Actor actor;
|
||||
public final Coord origin;
|
||||
public final Coord destination;
|
||||
|
||||
public int timeElapsed;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
update();
|
||||
if (System.currentTimeMillis() - actor.vfxStartTime >= duration) {
|
||||
onCompleted();
|
||||
} else {
|
||||
postDelayed(this, millisecondsPerFrame);
|
||||
}
|
||||
}
|
||||
|
||||
public SpriteMoveAnimation(Coord origin, Coord destination, int duration, Actor actor, VisualEffectCompletedCallback callback, int callbackValue) {
|
||||
this.callback = callback;
|
||||
this.callbackValue = callbackValue;
|
||||
this.duration = duration;
|
||||
this.actor = actor;
|
||||
this.origin = origin;
|
||||
this.destination = destination;
|
||||
this.timeElapsed = 0;
|
||||
|
||||
}
|
||||
|
||||
private void update() {
|
||||
|
||||
visualEffectFrameListeners.onNewSpriteMoveFrame(this);
|
||||
}
|
||||
|
||||
private void onCompleted() {
|
||||
--effectCount;
|
||||
actor.hasVFXRunning = false;
|
||||
if (callback != null) callback.onVisualEffectCompleted(callbackValue);
|
||||
visualEffectFrameListeners.onSpriteMoveCompleted(this);
|
||||
}
|
||||
|
||||
|
||||
public void start() {
|
||||
actor.hasVFXRunning = true;
|
||||
actor.vfxDuration = duration;
|
||||
actor.vfxStartTime = System.currentTimeMillis();
|
||||
postDelayed(this, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final class VisualEffectAnimation extends Handler implements Runnable {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.SpriteMoveAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation;
|
||||
|
||||
public interface VisualEffectFrameListener {
|
||||
void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset);
|
||||
void onAnimationCompleted(VisualEffectAnimation animation);
|
||||
void onNewSpriteMoveFrame(SpriteMoveAnimation animation);
|
||||
void onSpriteMoveCompleted(SpriteMoveAnimation animation);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gpl.rpg.AndorsTrail.controller.listeners;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.SpriteMoveAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.util.ListOfListeners;
|
||||
|
||||
@@ -12,6 +13,14 @@ public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffe
|
||||
private final Function1<VisualEffectFrameListener, VisualEffectAnimation> onAnimationCompleted = new Function1<VisualEffectFrameListener, VisualEffectAnimation>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, VisualEffectAnimation animation) { listener.onAnimationCompleted(animation); }
|
||||
};
|
||||
|
||||
private final Function1<VisualEffectFrameListener, SpriteMoveAnimation> onNewSpriteMoveFrame = new Function1<VisualEffectFrameListener, SpriteMoveAnimation>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, SpriteMoveAnimation animation) { listener.onNewSpriteMoveFrame(animation); }
|
||||
};
|
||||
|
||||
private final Function1<VisualEffectFrameListener, SpriteMoveAnimation> onSpriteMoveCompleted = new Function1<VisualEffectFrameListener, SpriteMoveAnimation>() {
|
||||
@Override public void call(VisualEffectFrameListener listener, SpriteMoveAnimation animation) { listener.onSpriteMoveCompleted(animation); }
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onNewAnimationFrame(VisualEffectAnimation animation, int tileID, int textYOffset) {
|
||||
@@ -22,4 +31,14 @@ public final class VisualEffectFrameListeners extends ListOfListeners<VisualEffe
|
||||
public void onAnimationCompleted(VisualEffectAnimation animation) {
|
||||
callAllListeners(this.onAnimationCompleted, animation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewSpriteMoveFrame(SpriteMoveAnimation animation) {
|
||||
callAllListeners(this.onNewSpriteMoveFrame, animation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpriteMoveCompleted(SpriteMoveAnimation animation) {
|
||||
callAllListeners(this.onSpriteMoveCompleted, animation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ public class Actor {
|
||||
public int blockChance;
|
||||
public int damageResistance;
|
||||
public ItemTraits_OnUse[] onHitEffects;
|
||||
public boolean hasVFXRunning = false;
|
||||
public long vfxStartTime = 0;
|
||||
public int vfxDuration = 0;
|
||||
public final Coord lastPosition = new Coord();
|
||||
|
||||
public Actor(
|
||||
Size tileSize
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
package com.gpl.rpg.AndorsTrail.model.actor;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import android.util.FloatMath;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
@@ -18,17 +26,9 @@ import com.gpl.rpg.AndorsTrail.util.Coord;
|
||||
import com.gpl.rpg.AndorsTrail.util.Range;
|
||||
import com.gpl.rpg.AndorsTrail.util.Size;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public final class Player extends Actor {
|
||||
|
||||
public static final int DEFAULT_PLAYER_ATTACKCOST = 4;
|
||||
public final Coord lastPosition;
|
||||
public final Coord nextPosition;
|
||||
|
||||
// TODO: Should be privates
|
||||
@@ -86,7 +86,6 @@ public final class Player extends Actor {
|
||||
, true // isPlayer
|
||||
, false // isImmuneToCriticalHits
|
||||
);
|
||||
this.lastPosition = new Coord();
|
||||
this.nextPosition = new Coord();
|
||||
this.levelExperience = new Range();
|
||||
this.inventory = new Inventory();
|
||||
@@ -154,6 +153,12 @@ public final class Player extends Actor {
|
||||
return true; //Progress was added.
|
||||
}
|
||||
|
||||
public boolean removeQuestProgress(QuestProgress progress){
|
||||
if (!hasExactQuestProgress(progress.questID, progress.progress)) return false;
|
||||
questProgress.get(progress.questID).remove(progress.progress);
|
||||
return true; //Progress was removed.
|
||||
}
|
||||
|
||||
public void recalculateLevelExperience() {
|
||||
int experienceRequiredToReachThisLevel = getRequiredExperience(level);
|
||||
levelExperience.set(getRequiredExperienceForNextLevel(level), totalExperience - experienceRequiredToReachThisLevel);
|
||||
|
||||
@@ -14,6 +14,7 @@ public final class ScriptEffect {
|
||||
, deactivateSpawnArea
|
||||
, activateMapChangeArea
|
||||
, deactivateMapChangeArea
|
||||
, removeQuestProgress
|
||||
}
|
||||
|
||||
public final ScriptEffectType type;
|
||||
|
||||
@@ -72,4 +72,24 @@ public final class CoordRect {
|
||||
public String toString() {
|
||||
return '{' + topLeft.toString() + ", " + size.toString() + '}';
|
||||
}
|
||||
|
||||
public static CoordRect getBoundingRect(Coord c1, Coord c2) {
|
||||
int x, y, w, h;
|
||||
if (c2.x < c1.x) {
|
||||
x = c2.x;
|
||||
w = 1 + c1.x - c2.x;
|
||||
} else {
|
||||
x = c1.x;
|
||||
w = 1 + c2.x - c1.x;
|
||||
}
|
||||
if (c2.y < c1.y) {
|
||||
y = c2.y;
|
||||
h = 1 + c1.y - c2.y;
|
||||
} else {
|
||||
y = c1.y;
|
||||
h = 1 + c2.y - c1.y;
|
||||
}
|
||||
|
||||
return new CoordRect(new Coord(x, y), new Size(w, h));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,14 @@ import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
|
||||
import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
|
||||
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
|
||||
import com.gpl.rpg.AndorsTrail.context.WorldContext;
|
||||
import com.gpl.rpg.AndorsTrail.controller.InputController;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.BloodSplatter;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.SpriteMoveAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.VisualEffectAnimation;
|
||||
import com.gpl.rpg.AndorsTrail.controller.listeners.*;
|
||||
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
|
||||
@@ -29,6 +31,7 @@ import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection;
|
||||
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
|
||||
import com.gpl.rpg.AndorsTrail.util.Coord;
|
||||
import com.gpl.rpg.AndorsTrail.util.CoordRect;
|
||||
import com.gpl.rpg.AndorsTrail.util.L;
|
||||
import com.gpl.rpg.AndorsTrail.util.Size;
|
||||
|
||||
public final class MainView extends SurfaceView
|
||||
@@ -49,7 +52,8 @@ public final class MainView extends SurfaceView
|
||||
private final Coord screenOffset = new Coord(); // pixel offset where the image begins
|
||||
private final Coord mapTopLeft = new Coord(); // Map coords of visible map
|
||||
private CoordRect mapViewArea; // Area in mapcoordinates containing the visible map. topleft == this.topleft
|
||||
|
||||
private Rect redrawClip = new Rect(); //Area in screen coordinates containing the visible map.
|
||||
|
||||
private final ModelContainer model;
|
||||
private final WorldContext world;
|
||||
private final ControllerContext controllers;
|
||||
@@ -199,6 +203,7 @@ public final class MainView extends SurfaceView
|
||||
}
|
||||
}
|
||||
synchronized (holder) { synchronized (tiles) {
|
||||
c.clipRect(redrawClip);
|
||||
c.translate(screenOffset.x, screenOffset.y);
|
||||
c.scale(scale, scale);
|
||||
doDrawRect(c, area);
|
||||
@@ -213,6 +218,34 @@ public final class MainView extends SurfaceView
|
||||
if (c != null) holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void redrawMoveArea_(CoordRect area, final SpriteMoveAnimation effect) {
|
||||
if (!hasSurface) return;
|
||||
|
||||
if (currentMap.isOutside(area)) return;
|
||||
if (!mapViewArea.intersects(area)) return;
|
||||
|
||||
calculateRedrawRect(area);
|
||||
Canvas c = null;
|
||||
try {
|
||||
c = holder.lockCanvas(redrawRect);
|
||||
// lockCanvas sometimes changes redrawRect, when the double-buffer has not been
|
||||
// sufficiently filled beforehand. In those cases, we need to redraw the whole scene.
|
||||
if (area != mapViewArea) {
|
||||
if (isRedrawRectWholeScreen(redrawRect)) {
|
||||
area = mapViewArea;
|
||||
}
|
||||
}
|
||||
synchronized (holder) { synchronized (tiles) {
|
||||
c.clipRect(redrawClip);
|
||||
c.translate(screenOffset.x, screenOffset.y);
|
||||
c.scale(scale, scale);
|
||||
doDrawRect(c, area);
|
||||
} }
|
||||
} finally {
|
||||
if (c != null) holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRedrawRectWholeScreen(Rect redrawRect) {
|
||||
if (redrawRect.width() < mapViewArea.size.width * scaledTileSize) return false;
|
||||
@@ -256,13 +289,25 @@ public final class MainView extends SurfaceView
|
||||
}
|
||||
|
||||
private void doDrawRect(Canvas canvas, CoordRect area) {
|
||||
|
||||
doDrawRect_Below(canvas, area);
|
||||
doDrawRect_Objects(canvas, area);
|
||||
doDrawRect_Above(canvas, area);
|
||||
|
||||
}
|
||||
|
||||
private void doDrawRect_Below(Canvas canvas, CoordRect area) {
|
||||
drawMapLayer(canvas, area, currentTileMap.currentLayout.layerGround);
|
||||
tryDrawMapLayer(canvas, area, currentTileMap.currentLayout.layerObjects);
|
||||
|
||||
for (BloodSplatter splatter : currentMap.splatters) {
|
||||
drawFromMapPosition(canvas, area, splatter.position, splatter.iconID);
|
||||
}
|
||||
}
|
||||
|
||||
private void doDrawRect_Objects(Canvas canvas, CoordRect area) {
|
||||
for (BloodSplatter splatter : currentMap.splatters) {
|
||||
drawFromMapPosition(canvas, area, splatter.position, splatter.iconID);
|
||||
}
|
||||
|
||||
for (Loot l : currentMap.groundBags) {
|
||||
if (l.isVisible) {
|
||||
@@ -270,13 +315,31 @@ public final class MainView extends SurfaceView
|
||||
}
|
||||
}
|
||||
|
||||
drawFromMapPosition(canvas, area, playerPosition, model.player.iconID);
|
||||
if (!model.player.hasVFXRunning) {
|
||||
drawFromMapPosition(canvas, area, playerPosition, model.player.iconID);
|
||||
} else if (area.contains(playerPosition)) {
|
||||
int vfxElapsedTime = (int) (System.currentTimeMillis() - model.player.vfxStartTime);
|
||||
if (vfxElapsedTime > model.player.vfxDuration) vfxElapsedTime = model.player.vfxDuration;
|
||||
int x = ((model.player.position.x - mapViewArea.topLeft.x) * tileSize * vfxElapsedTime + ((model.player.lastPosition.x - mapViewArea.topLeft.x) * tileSize * (model.player.vfxDuration - vfxElapsedTime))) / model.player.vfxDuration;
|
||||
int y = ((model.player.position.y - mapViewArea.topLeft.y) * tileSize * vfxElapsedTime + ((model.player.lastPosition.y - mapViewArea.topLeft.y) * tileSize * (model.player.vfxDuration - vfxElapsedTime))) / model.player.vfxDuration;
|
||||
tiles.drawTile(canvas, model.player.iconID, x, y, mPaint);
|
||||
}
|
||||
for (MonsterSpawnArea a : currentMap.spawnAreas) {
|
||||
for (Monster m : a.monsters) {
|
||||
drawFromMapPosition(canvas, area, m.rectPosition, m.iconID);
|
||||
if (!m.hasVFXRunning) {
|
||||
drawFromMapPosition(canvas, area, m.rectPosition, m.iconID);
|
||||
} else if (area.intersects(m.rectPosition) || area.contains(m.lastPosition)) {
|
||||
int vfxElapsedTime = (int) (System.currentTimeMillis() - m.vfxStartTime);
|
||||
if (vfxElapsedTime > m.vfxDuration) vfxElapsedTime = m.vfxDuration;
|
||||
int x = ((m.position.x - mapViewArea.topLeft.x) * tileSize * vfxElapsedTime + ((m.lastPosition.x - mapViewArea.topLeft.x) * tileSize * (m.vfxDuration - vfxElapsedTime))) / m.vfxDuration;
|
||||
int y = ((m.position.y - mapViewArea.topLeft.y) * tileSize * vfxElapsedTime + ((m.lastPosition.y - mapViewArea.topLeft.y) * tileSize * (m.vfxDuration - vfxElapsedTime))) / m.vfxDuration;
|
||||
tiles.drawTile(canvas, m.iconID, x, y, mPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void doDrawRect_Above(Canvas canvas, CoordRect area) {
|
||||
tryDrawMapLayer(canvas, area, currentTileMap.currentLayout.layerAbove);
|
||||
|
||||
if (model.uiSelections.selectedPosition != null) {
|
||||
@@ -342,6 +405,7 @@ public final class MainView extends SurfaceView
|
||||
,Math.min(screenSizeTileCount.height, currentMap.size.height)
|
||||
);
|
||||
mapViewArea = new CoordRect(mapTopLeft, visibleNumberOfTiles);
|
||||
updateClip();
|
||||
|
||||
screenOffset.set(
|
||||
(surfaceSize.width - scaledTileSize * visibleNumberOfTiles.width) / 2
|
||||
@@ -370,8 +434,13 @@ public final class MainView extends SurfaceView
|
||||
mapTopLeft.y = Math.max(0, playerPosition.y - mapViewArea.size.height/2);
|
||||
mapTopLeft.y = Math.min(mapTopLeft.y, currentMap.size.height - mapViewArea.size.height);
|
||||
}
|
||||
updateClip();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateClip() {
|
||||
worldCoordsToScreenCords(mapViewArea, redrawClip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerMoved(Coord newPosition, Coord previousPosition) {
|
||||
@@ -492,6 +561,16 @@ public final class MainView extends SurfaceView
|
||||
public void onAnimationCompleted(VisualEffectAnimation animation) {
|
||||
redrawArea(animation.area, RedrawAreaDebugReason.EffectCompleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewSpriteMoveFrame(SpriteMoveAnimation animation) {
|
||||
redrawMoveArea_(CoordRect.getBoundingRect(animation.origin, animation.destination), animation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpriteMoveCompleted(SpriteMoveAnimation animation) {
|
||||
redrawArea(CoordRect.getBoundingRect(animation.origin, animation.destination), RedrawAreaDebugReason.EffectCompleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewTick() {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<label for="rewardType">Reward Type:</label>
|
||||
<select class="field" id="rewardType" ng-model="reward.rewardType">
|
||||
<option value="questProgress">Quest progress</option>
|
||||
<option value="removeQuestProgress">Remove Quest progress</option>
|
||||
<option value="dropList">Droplist</option>
|
||||
<option value="skillIncrease">Skill increase</option>
|
||||
<option value="actorCondition">Actor condition</option>
|
||||
@@ -74,6 +75,16 @@
|
||||
<input type="text" size="3" id="rewardvalue" class="field at-input-quantity" ng-model="reward.value" />
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="reward.rewardType=='removeQuestProgress'">
|
||||
<div class="fieldWithLabel">
|
||||
<label for="rewardID">Quest ID:</label>
|
||||
<input type="text" size="30" id="rewardID" class="field at-input-id" ng-model="reward.rewardID" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="rewardvalue">Stage:</label>
|
||||
<input type="text" size="3" id="rewardvalue" class="field at-input-quantity" ng-model="reward.value" />
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="reward.rewardType=='dropList'">
|
||||
<div class="fieldWithLabel">
|
||||
<label for="rewardID">Droplist ID:</label>
|
||||
|
||||
Reference in New Issue
Block a user