killedMonster.createLoot(loot, player);
model.currentMap.remove(killedMonster);
+ VisualEffectController.addSplatter(model.currentMap, killedMonster);
player.ap.add(player.getSkillLevel(SkillCollection.SKILL_CLEAVE) * SkillCollection.PER_SKILLPOINT_INCREASE_CLEAVE_AP, false);
player.health.add(player.getSkillLevel(SkillCollection.SKILL_EATER) * SkillCollection.PER_SKILLPOINT_INCREASE_EATER_HEALTH, false);
private void onNewTick() {
view.controller.moveAndSpawnMonsters();
view.monsterMovementController.attackWithAgressiveMonsters();
+ VisualEffectController.updateSplatters(model.currentMap);
}
}
else playerVisitsMap(world, newMap);
refreshMonsterAggressiveness(newMap, model.player);
+ VisualEffectController.updateSplatters(newMap);
}
private static void playerVisitsMapFirstTime(final WorldContext world, PredefinedMap m) {
import com.gpl.rpg.AndorsTrail.VisualEffectCollection;
import com.gpl.rpg.AndorsTrail.VisualEffectCollection.VisualEffect;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
+import com.gpl.rpg.AndorsTrail.model.actor.Monster;
+import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
+import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
+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.Size;
public boolean isRunningVisualEffect() {
return effectCount > 0;
}
+
+
+ public static final class BloodSplatter {
+ public static final int TYPE_RED = 0;
+ public static final int TYPE_BROWN = 2;
+ public static final int TYPE_WHITE = 3;
+ public final long removeAfter;
+ public final long reduceIconAfter;
+ public final Coord position;
+ public int iconID;
+ public boolean updated = false;
+ public BloodSplatter(int iconID, Coord position) {
+ this.iconID = iconID;
+ this.position = position;
+ long now = System.currentTimeMillis();
+ removeAfter = now + 20000;
+ reduceIconAfter = now + 10000;
+ }
+ }
+
+ public static void updateSplatters(PredefinedMap map) {
+ long now = System.currentTimeMillis();
+ for (int i = map.splatters.size() - 1; i >= 0; --i) {
+ BloodSplatter b = map.splatters.get(i);
+ if (b.removeAfter <= now) map.splatters.remove(i);
+ else if (!b.updated && b.reduceIconAfter <= now) {
+ b.updated = true;
+ b.iconID++;
+ }
+ }
+ }
+
+ public static void addSplatter(PredefinedMap map, Monster m) {
+ int iconID = getSplatterIconFromMonsterClass(m.monsterClass);
+ if (iconID > 0) map.splatters.add(new BloodSplatter(iconID, m.position));
+ }
+
+ private static int getSplatterIconFromMonsterClass(int monsterClass) {
+ return -1;
+ /*
+ switch (monsterClass) {
+ case MonsterType.MONSTERCLASS_INSECT:
+ case MonsterType.MONSTERCLASS_UNDEAD:
+ case MonsterType.MONSTERCLASS_REPTILE:
+ return TileManager.iconID_splatter_brown_1a + Constants.rnd.nextInt(2) * 2;
+ case MonsterType.MONSTERCLASS_HUMANOID:
+ case MonsterType.MONSTERCLASS_ANIMAL:
+ case MonsterType.MONSTERCLASS_GIANT:
+ return TileManager.iconID_splatter_red_1a + Constants.rnd.nextInt(2) * 2;
+ case MonsterType.MONSTERCLASS_DEMON:
+ case MonsterType.MONSTERCLASS_CONSTRUCT:
+ return TileManager.iconID_splatter_white_1a;
+ default:
+ return -1;
+ }
+ */
+ }
}
public final int exp;
public final DropList dropList;
public final String faction;
+ public final int monsterClass;
public Monster(MonsterType monsterType, Coord position) {
super(monsterType, false);
this.exp = monsterType.exp;
this.dropList = monsterType.dropList;
this.faction = monsterType.faction;
+ this.monsterClass = monsterType.monsterClass;
}
public void createLoot(Loot container, Player player) {
this.dropList = monsterType.dropList;
this.forceAggressive = src.readBoolean();
this.faction = monsterType.faction;
+ this.monsterClass = monsterType.monsterClass;
}
private static Monster readFromParcel_pre_v0610(DataInputStream src, int fileversion, MonsterType monsterType) throws IOException {
import com.gpl.rpg.AndorsTrail.util.Size;
public final class MonsterType extends ActorTraits {
+ public static final int MONSTERCLASS_HUMANOID = 0;
+ public static final int MONSTERCLASS_INSECT = 1;
+ public static final int MONSTERCLASS_DEMON = 2;
+ public static final int MONSTERCLASS_CONSTRUCT = 3;
+ public static final int MONSTERCLASS_ANIMAL = 4;
+ public static final int MONSTERCLASS_GIANT = 5;
+ public static final int MONSTERCLASS_UNDEAD = 6;
+ public static final int MONSTERCLASS_REPTILE = 7;
+
public final String id;
public final String spawnGroup;
public final int exp;
public final DropList dropList;
public final String phraseID;
- public boolean isRespawnable = true;
+ public final boolean isRespawnable;
public final String faction;
+ public final int monsterClass;
public MonsterType(
String id,
int exp,
DropList dropList,
String phraseID,
- String faction) {
+ boolean isRespawnable,
+ String faction,
+ int monsterClass) {
super(iconID, tileSize, baseCombatTraits, moveCost, onHitEffects == null ? null : new ItemTraits_OnUse[] { onHitEffects });
this.id = id;
this.spawnGroup = spawnGroup;
this.dropList = dropList;
this.phraseID = phraseID;
this.faction = faction;
+ this.isRespawnable = isRespawnable;
+ this.monsterClass = monsterClass;
}
}
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.Constants;
+import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.BloodSplatter;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
public long lastVisitTime = VISIT_RESET;
public final boolean[][] isWalkable;
+ public final ArrayList<BloodSplatter> splatters = new ArrayList<BloodSplatter>();
public PredefinedMap(int xmlResourceId, String name, Size size, boolean[][] isWalkable, MapObject[] eventObjects, MonsterSpawnArea[] spawnAreas, boolean hasFOW) {
this.xmlResourceId = xmlResourceId;
for(MonsterSpawnArea a : spawnAreas) {
a.reset();
}
+ splatters.clear();
visited = false;
lastVisitTime = VISIT_RESET;
}
for(MonsterSpawnArea a : spawnAreas) {
if (!a.isUnique) a.reset();
}
+ splatters.clear();
lastVisitTime = VISIT_RESET;
}
String[] monsterTypeIDs = new String[types.size()];
for (int i = 0; i < monsterTypeIDs.length; ++i) {
monsterTypeIDs[i] = types.get(i).id;
- if (isUnique) types.get(i).isRespawnable = false;
}
MonsterSpawnArea area = new MonsterSpawnArea(
position
// ========================================================================
// Load various ui icons
- /*tiles.iconID_CHAR_HERO = */loader.prepareTileID(R.drawable.char_hero, 0);
- /*tiles.iconID_selection_red = */loader.prepareTileID(R.drawable.ui_selections, 0);
- /*tiles.iconID_selection_yellow = */loader.prepareTileID(R.drawable.ui_selections, 1);
- /*tiles.iconID_groundbag = */loader.prepareTileID(R.drawable.ui_icon_equipment, 0);
- /*tiles.iconID_boxopened = */loader.prepareTileID(R.drawable.ui_quickslots, 1);
- /*tiles.iconID_boxclosed = */loader.prepareTileID(R.drawable.ui_quickslots, 0);
- /*tiles.iconID_selection_blue = */loader.prepareTileID(R.drawable.ui_selections, 2);
- /*tiles.iconID_selection_purple = */loader.prepareTileID(R.drawable.ui_selections, 3);
- /*tiles.iconID_selection_green = */loader.prepareTileID(R.drawable.ui_selections, 4);
+ /*TileManager.iconID_CHAR_HERO = */loader.prepareTileID(R.drawable.char_hero, 0);
+ /*TileManager.iconID_selection_red = */loader.prepareTileID(R.drawable.ui_selections, 0);
+ /*TileManager.iconID_selection_yellow = */loader.prepareTileID(R.drawable.ui_selections, 1);
+ /*TileManager.iconID_groundbag = */loader.prepareTileID(R.drawable.ui_icon_equipment, 0);
+ /*TileManager.iconID_boxopened = */loader.prepareTileID(R.drawable.ui_quickslots, 1);
+ /*TileManager.iconID_boxclosed = */loader.prepareTileID(R.drawable.ui_quickslots, 0);
+ /*TileManager.iconID_selection_blue = */loader.prepareTileID(R.drawable.ui_selections, 2);
+ /*TileManager.iconID_selection_purple = */loader.prepareTileID(R.drawable.ui_selections, 3);
+ /*TileManager.iconID_selection_green = */loader.prepareTileID(R.drawable.ui_selections, 4);
+ for(int i = 0; i < 5; ++i) {
+ loader.prepareTileID(R.drawable.ui_splatters1, i);
+ loader.prepareTileID(R.drawable.ui_splatters1, i+8);
+ }
// ========================================================================
loader.prepareTileset(R.drawable.ui_selections, "ui_selections", new Size(5, 1), defaultTileSize);
loader.prepareTileset(R.drawable.ui_quickslots, "ui_quickslots", new Size(2, 1), defaultTileSize);
loader.prepareTileset(R.drawable.ui_icon_equipment, "ui_icon_equipment", src_sz1x1, defaultTileSize);
+ loader.prepareTileset(R.drawable.ui_splatters1, "ui_splatters1", new Size(8, 2), defaultTileSize);
loader.prepareTileset(R.drawable.actorconditions_1, "actorconditions_1", new Size(14, 8), defaultTileSize);
loader.prepareTileset(R.drawable.actorconditions_2, "actorconditions_2", new Size(3, 1), defaultTileSize);
final CombatTraits combatTraits = ResourceParserUtils.parseCombatTraits(parts, 8);
final ItemTraits_OnUse hitEffect = itemTraitsParser.parseItemTraits_OnUse(parts, 18, true);
final int exp = getExpectedMonsterExperience(combatTraits, hitEffect, maxHP, maxAP);
+ int monsterClass = MonsterType.MONSTERCLASS_HUMANOID;
+ if (parts[1].contains("insect")) monsterClass = MonsterType.MONSTERCLASS_INSECT; //TODO: Should be read from resource file.
+
return new Pair<String, MonsterType>(monsterTypeId, new MonsterType(
monsterTypeId
, parts[2] // Name
, exp // Exp
, droplists.getDropList(parts[16]) // Droplist
, ResourceParserUtils.parseNullableString(parts[17]) // PhraseID
+ , true // isRespawnable
, null // Faction
+ , monsterClass // Class
));
}
public static final int iconID_selection_purple = 8;
public static final int iconID_selection_green = 9;
+ public static final int iconID_splatter_red_1a = 10;
+ public static final int iconID_splatter_red_1b = 11;
+ public static final int iconID_splatter_red_2a = 12;
+ public static final int iconID_splatter_red_2b = 13;
+ public static final int iconID_splatter_brown_1a = 14;
+ public static final int iconID_splatter_brown_1b = 15;
+ public static final int iconID_splatter_brown_2a = 16;
+ public static final int iconID_splatter_brown_2b = 17;
+ public static final int iconID_splatter_white_1a = 18;
+ public static final int iconID_splatter_white_1b = 19;
+
private float density;
public int tileSize;
public final TileCache tileCache = new TileCache();
- public final TileCollection preloadedTiles = new TileCollection(74);
+ public final TileCollection preloadedTiles = new TileCollection(84);
public TileCollection currentMapTiles;
public TileCollection adjacentMapTiles;
private final HashSet<Integer> preloadedTileIDs = new HashSet<Integer>();
import com.gpl.rpg.AndorsTrail.context.ViewContext;
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.VisualEffectAnimation;
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
drawMapLayer(canvas, area, currentTileMap.layers[LayeredTileMap.LAYER_GROUND]);
tryDrawMapLayer(canvas, area, currentTileMap, LayeredTileMap.LAYER_OBJECTS);
+ for (BloodSplatter splatter : currentMap.splatters) {
+ drawFromMapPosition(canvas, area, splatter.position, splatter.iconID);
+ }
+
for (Loot l : currentMap.groundBags) {
if (l.isVisible) {
drawFromMapPosition(canvas, area, l.position, TileManager.iconID_groundbag);