Big map update 11

* Added a dummy texture in Graphics. Useful to add raw pixels or solid color boxes to a drawing batch.
* Dialogue actions added: Heal (negative too) player, Add gold.
* Dialogue conditions added: Check for gold >= X, check for health >= X.
* Added "Manasight" effect to equipment and blessings. Allows to see the colors used by enemies.
* All existing enemies have their color identities assigned.
* Console command to dump all deck colors used by enemies (to update the data for color view)
* Console command to force reload of status scenes (for faster design)
* Less delay when clicking "Done" in a reward scene.
* Adjustments to (landscape) Status and Inventory scenes.
* Blessings properly assign map effects (speed, manasight)
* Added "Manasight Amulet" (sprite pending) to grant the user manasight.
* Added "Scroll" pickup template. It's meant to grant single cards.
This commit is contained in:
Magpie
2022-04-20 11:07:23 +02:00
parent caf2d5279c
commit c058a7c863
29 changed files with 585 additions and 341 deletions

View File

@@ -4,9 +4,7 @@ import java.util.ArrayDeque;
import java.util.Deque;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
@@ -44,6 +42,8 @@ public class Graphics {
private final ShaderProgram shaderWarp = new ShaderProgram(Gdx.files.internal("shaders").child("grayscale.vert"), Gdx.files.internal("shaders").child("warp.frag"));
private final ShaderProgram shaderUnderwater = new ShaderProgram(Gdx.files.internal("shaders").child("grayscale.vert"), Gdx.files.internal("shaders").child("underwater.frag"));
private Texture dummyTexture = null;
public Graphics() {
ShaderProgram.pedantic = false;
}
@@ -87,6 +87,7 @@ public class Graphics {
shaderGrayscale.dispose();
shaderUnderwater.dispose();
shaderWarp.dispose();
if(dummyTexture != null) dummyTexture.dispose();
}
public SpriteBatch getBatch() {
@@ -1124,4 +1125,14 @@ public class Graphics {
int brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000;
return brightness > 155 ? Color.valueOf("#171717") : Color.valueOf("#fffffd");
}
public Texture getDummyTexture(){
if (dummyTexture == null){
Pixmap P = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
P.setColor(1f,1f,1f,1f);
P.drawPixel(0, 0);
dummyTexture = new Texture(P);
}
return dummyTexture;
}
}

View File

@@ -1,9 +1,12 @@
package forge.adventure.character;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.utils.Array;
import forge.Forge;
import forge.adventure.data.EffectData;
import forge.adventure.data.EnemyData;
import forge.adventure.data.RewardData;
@@ -47,7 +50,6 @@ public class EnemySprite extends CharacterSprite {
return data;
}
public Array<Reward> getRewards() {
Array<Reward> ret=new Array<Reward>();
if(data.rewards == null)
@@ -58,5 +60,57 @@ public class EnemySprite extends CharacterSprite {
return ret;
}
private void drawColorHints(Batch batch){
int size = Math.min(data.colors.length(), 6);
int DX = Math.round(getX() - 2);
int DY = Math.round(getY());
for(int i = 0; i < size; i++){
char C = data.colors.toUpperCase().charAt(i);
switch (C) {
default: break;
case 'C': {
batch.setColor(Color.DARK_GRAY);
batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2);
DY += 2; break;
}
case 'B': {
batch.setColor(Color.PURPLE);
batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2);
DY += 2; break;
}
case 'G': {
batch.setColor(Color.GREEN);
batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2);
DY += 2; break;
}
case 'R': {
batch.setColor(Color.RED);
batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2);
DY += 2; break;
}
case 'U': {
batch.setColor(Color.BLUE);
batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2);
DY += 2; break;
}
case 'W': {
batch.setColor(Color.WHITE);
batch.draw(Forge.getGraphics().getDummyTexture(), DX, DY, 2, 2);
DY += 2; break;
}
}
}
batch.setColor(Color.WHITE);
}
@Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
if(Current.player().hasColorView() && !data.colors.isEmpty()) {
drawColorHints(batch);
}
}
}

View File

@@ -25,8 +25,9 @@ public class PlayerSprite extends CharacterSprite {
PlayerSprite.this.updatePlayer();
}
});
playerSpeed=Config.instance().getConfigData().playerBaseSpeed;
Current.player().onEquipmentChanged(() -> playerSpeedEquipmentModifier=Current.player().equipmentSpeed());
playerSpeed = Config.instance().getConfigData().playerBaseSpeed;
Current.player().onBlessing( () -> playerSpeedEquipmentModifier = Current.player().equipmentSpeed() );
Current.player().onEquipmentChanged( () -> playerSpeedEquipmentModifier=Current.player().equipmentSpeed() );
}
private void updatePlayer() {

View File

@@ -16,6 +16,8 @@ public class DialogData {
static public class ActionData {
public String removeItem; //Remove item name from inventory.
public String addItem; //Add item name to inventory.
public int addLife = 0; //Gives the player X health. Negative to take.
public int addGold = 0; //Gives the player X gold. Negative to take.
public int deleteMapObject = 0; //Remove ID from the map. -1 for self.
public int battleWithActorID = 0; //Start a battle with enemy ID. -1 for self if possible.
public EffectData giveBlessing; //Give a blessing to the player.
@@ -27,6 +29,8 @@ public class DialogData {
public int flag = 0; //Check for a local dungeon flag.
public int actorID = 0; //Check for an actor ID.
public String hasBlessing = null; //Check for specific blessing, if named.
public int hasGold = 0; //Check for player gold. True if gold is equal or higher than X.
public int hasLife = 0; //Check for player life. True if life is equal or higher than X.
public String colorIdentity = null;//Check for player's current color identity.
public boolean not = false; //Reverse the result of a condition ("actorID":"XX" + "not":true => true if XX is not in the map.)
}

View File

@@ -51,6 +51,8 @@ public class EffectData implements Serializable {
String description = "";
if(this.name != null && !this.name.isEmpty())
description += this.name + "\n";
if(this.colorView)
description += "Manasight.\n";
if(this.lifeModifier != 0)
description += "Life: " + ((this.lifeModifier > 0) ? "+" : "") + this.lifeModifier + "\n";
if(this.startBattleWithCard != null && this.startBattleWithCard.length != 0)

View File

@@ -1,7 +1,11 @@
package forge.adventure.data;
import forge.adventure.util.CardUtil;
import forge.card.ColorSet;
import forge.deck.Deck;
import forge.deck.DeckProxy;
import forge.game.GameType;
import forge.model.FModel;
/**
* Data class that will be used to read Json configuration files
@@ -19,29 +23,25 @@ public class EnemyData {
public int life;
public RewardData[] rewards;
public String[] equipment;
public String colors = "";
public EnemyData()
{
}
public EnemyData() { }
public EnemyData(EnemyData enemyData) {
name =enemyData.name;
sprite =enemyData.sprite;
deck =enemyData.deck;
ai =enemyData.ai;
spawnRate =enemyData.spawnRate;
difficulty =enemyData.difficulty ;
speed =enemyData.speed;
life =enemyData.life;
equipment =enemyData.equipment;
if(enemyData.rewards==null)
{
name = enemyData.name;
sprite = enemyData.sprite;
deck = enemyData.deck;
ai = enemyData.ai;
spawnRate = enemyData.spawnRate;
difficulty = enemyData.difficulty;
speed = enemyData.speed;
life = enemyData.life;
equipment = enemyData.equipment;
colors = enemyData.colors;
if(enemyData.rewards == null) {
rewards=null;
}
else
{
rewards =new RewardData[enemyData.rewards.length];
for(int i=0;i<rewards.length;i++)
} else {
rewards = new RewardData[enemyData.rewards.length];
for(int i=0; i<rewards.length; i++)
rewards[i]=new RewardData(enemyData.rewards[i]);
}
}

View File

@@ -6,6 +6,10 @@ import com.badlogic.gdx.utils.Json;
import forge.adventure.util.Config;
import forge.adventure.util.Paths;
import forge.adventure.world.BiomeSprites;
import forge.card.ColorSet;
import forge.deck.Deck;
import forge.deck.DeckProxy;
import forge.game.GameType;
import java.io.Serializable;
import java.util.ArrayList;
@@ -51,9 +55,7 @@ public class WorldData implements Serializable {
if (allEnemies == null) {
Json json = new Json();
FileHandle handle = Config.instance().getFile(Paths.ENEMIES);
if (handle.exists())
{
if (handle.exists()) {
Array readList = json.fromJson(Array.class, EnemyData.class, handle);
allEnemies = readList;
}
@@ -62,8 +64,7 @@ public class WorldData implements Serializable {
}
public static EnemyData getEnemy(String enemy) {
for(EnemyData data: new Array.ArrayIterator<>(getAllEnemies()))
{
for(EnemyData data: new Array.ArrayIterator<>(getAllEnemies())) {
if(data.name.equals(enemy))
return data;
}

View File

@@ -48,11 +48,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
private final Array<String> inventoryItems=new Array<>();
private final HashMap<String,String> equippedItems=new HashMap<>();
public AdventurePlayer()
{
for(int i=0;i<NUMBER_OF_DECKS;i++)
{
public AdventurePlayer() {
for(int i=0;i<NUMBER_OF_DECKS;i++) {
decks[i]=new Deck("Empty Deck");
}
}
@@ -303,19 +300,6 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
return data;
}
public void addBlessing(EffectData bless){ blessing = bless; }
public void clearBlessing() { blessing = null; }
public @Null EffectData getBlessing(){ return blessing; }
public boolean hasBlessing(String name){
if(blessing == null) return false;
if(blessing.name.equals(name)) return true;
return false;
}
public String spriteName() {
return HeroListData.getHero(heroRace, isFemale);
}
@@ -329,15 +313,12 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
}
public void addCard(PaperCard card) {
cards.add(card);
newCards.add(card);
}
public void addReward(Reward reward) {
switch (reward.getType())
{
public void addReward(Reward reward) {
switch (reward.getType()) {
case Card:
cards.add(reward.getCard());
newCards.add(reward.getCard());
@@ -352,13 +333,13 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
addMaxLife(reward.getCount());
break;
}
}
SignalList onLifeTotalChangeList=new SignalList();
SignalList onGoldChangeList=new SignalList();
SignalList onPlayerChangeList=new SignalList();
SignalList onEquipmentChange=new SignalList();
SignalList onBlessing=new SignalList();
private void addGold(int goldCount) {
gold+=goldCount;
@@ -388,6 +369,11 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
o.run();
}
public void onBlessing(Runnable o) {
onBlessing.add(o);
o.run();
}
public int getLife() {
return life;
}
@@ -424,6 +410,34 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
onGoldChangeList.emit();
}
public void addBlessing(EffectData bless){
blessing = bless;
onBlessing.emit();
}
public void clearBlessing() { blessing = null; }
public @Null EffectData getBlessing(){ return blessing; }
public boolean hasBlessing(String name){ //Checks for a named blessing.
//It is not necessary to name all blessings, only the ones you'd want to check for.
if(blessing == null) return false;
if(blessing.name.equals(name)) return true;
return false;
}
public boolean hasColorView() {
for(String name:equippedItems.values()) {
ItemData data=ItemData.getItem(name);
if(data != null && data.effect.colorView) return true;
}
if(blessing != null) {
if(blessing.colorView) return true;
}
return false;
}
public DifficultyData getDifficulty() {
return difficultyData;
}
@@ -482,9 +496,12 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
float factor=1.0f;
for(String name:equippedItems.values()) {
ItemData data=ItemData.getItem(name);
if(data.effect.moveSpeed > 0.0) { //Avoid negative speeds. It would be silly.
if(data != null && data.effect.moveSpeed > 0.0) //Avoid negative speeds. It would be silly.
factor*=data.effect.moveSpeed;
}
}
if(blessing != null) { //If a blessing gives speed, take it into account.
if(blessing.moveSpeed > 0.0)
factor *= blessing.moveSpeed;
}
return factor;
}

View File

@@ -63,91 +63,92 @@ public class InventoryScene extends UIScene {
@Override
public void resLoaded() {
super.resLoaded();
equipOverlay = new Texture(Config.instance().getFile(Paths.ITEMS_EQUIP));
ui.onButtonPress("return", () -> done());
leave = ui.findActor("return");
ui.onButtonPress("delete", () -> confirm.show(stage));
ui.onButtonPress("equip", () -> equip());
equipButton = ui.findActor("equip");
deleteButton = ui.findActor("delete");
itemDescription = ui.findActor("item_description");
leave.getLabel().setText(Forge.getLocalizer().getMessage("lblBack"));
equipOverlay = new Texture(Config.instance().getFile(Paths.ITEMS_EQUIP));
ui.onButtonPress("return", () -> done());
leave = ui.findActor("return");
ui.onButtonPress("delete", () -> confirm.show(stage));
ui.onButtonPress("equip", () -> equip());
equipButton = ui.findActor("equip");
deleteButton = ui.findActor("delete");
itemDescription = ui.findActor("item_description");
itemDescription.setAlignment(Align.topLeft);
leave.getLabel().setText(Forge.getLocalizer().getMessage("lblBack"));
inventoryButtons=new Array<>();
equipmentSlots=new HashMap<>();
inventoryButtons=new Array<>();
equipmentSlots=new HashMap<>();
Array<Actor> children = ui.getChildren();
for (int i = 0, n = children.size; i < n; i++)
Array<Actor> children = ui.getChildren();
for (int i = 0, n = children.size; i < n; i++)
{
if(children.get(i).getName()!=null&&children.get(i).getName().startsWith("Equipment"))
{
if(children.get(i).getName()!=null&&children.get(i).getName().startsWith("Equipment"))
{
String slotName=children.get(i).getName().split("_")[1];
equipmentSlots.put(slotName, (Button) children.get(i));
Actor slot=children.get(i);
slot.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
Button button=((Button) actor);
if(button.isChecked())
String slotName=children.get(i).getName().split("_")[1];
equipmentSlots.put(slotName, (Button) children.get(i));
Actor slot=children.get(i);
slot.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
Button button=((Button) actor);
if(button.isChecked())
{
for(Button otherButton:equipmentSlots.values())
{
for(Button otherButton:equipmentSlots.values())
{
if(button!=otherButton&&otherButton.isChecked()){
otherButton.setChecked(false);
}
}
String item=Current.player().itemInSlot(slotName);
if(item!=null&&item!="")
{
Button changeButton=null;
for(Button invButton:inventoryButtons)
{
if(itemLocation.get(invButton)!=null&&itemLocation.get(invButton).equals(item))
{
changeButton=invButton;
break;
}
}
if(changeButton!=null)
changeButton.setChecked(true);
}
else
{
setSelected(null);
if(button!=otherButton&&otherButton.isChecked()){
otherButton.setChecked(false);
}
}
String item=Current.player().itemInSlot(slotName);
if(item!=null&&item!="")
{
Button changeButton=null;
for(Button invButton:inventoryButtons)
{
if(itemLocation.get(invButton)!=null&&itemLocation.get(invButton).equals(item))
{
changeButton=invButton;
break;
}
}
if(changeButton!=null)
changeButton.setChecked(true);
}
else
{
setSelected(null);
}
}
});
}
}
});
}
inventory = new Table(Controls.GetSkin());
ScrollPane scrollPane = ui.findActor("inventory");
scrollPane.setScrollingDisabled(true,false);
scrollPane.setActor(inventory);
columns= (int) (scrollPane.getWidth()/createInventorySlot().getWidth());
columns-=1;
if(columns<=0)columns=1;
scrollPane.setActor(inventory);
confirm = new Dialog("\n "+Forge.getLocalizer().getMessage("lblDelete"), Controls.GetSkin())
}
inventory = new Table(Controls.GetSkin());
ScrollPane scrollPane = ui.findActor("inventory");
scrollPane.setScrollingDisabled(true,false);
scrollPane.setActor(inventory);
columns= (int) (scrollPane.getWidth()/createInventorySlot().getWidth());
columns-=1;
if(columns<=0)columns=1;
scrollPane.setActor(inventory);
confirm = new Dialog("\n "+Forge.getLocalizer().getMessage("lblDelete"), Controls.GetSkin())
{
protected void result(Object object)
{
protected void result(Object object)
{
if(object!=null&&object.equals(true))
delete();
confirm.hide();
};
if(object!=null&&object.equals(true))
delete();
confirm.hide();
};
};
confirm.button(Forge.getLocalizer().getMessage("lblYes"), true);
confirm.button(Forge.getLocalizer().getMessage("lblNo"), false);
ui.addActor(confirm);
confirm.hide();
confirm.button(Forge.getLocalizer().getMessage("lblYes"), true);
confirm.button(Forge.getLocalizer().getMessage("lblNo"), false);
ui.addActor(confirm);
confirm.hide();
itemDescription.setWrap(true);
//makes confirm dialog hidden immediately when you open inventory first time..
confirm.getColor().a = 0;
itemDescription.setWrap(true);
//makes confirm dialog hidden immediately when you open inventory first time..
confirm.getColor().a = 0;
}
private void setSelected(Button actor) {
@@ -198,17 +199,15 @@ public class InventoryScene extends UIScene {
}
private void updateInventory()
{
private void updateInventory() {
inventoryButtons.clear();
inventory.clear();
for(int i=0;i<Current.player().getItems().size;i++)
{
for(int i=0;i<Current.player().getItems().size;i++) {
if(i%columns==0)
inventory.row();
Button newActor=createInventorySlot();
inventory.add(newActor).align(Align.left|Align.top).space(1);
inventory.add(newActor).top().left().space(1);
inventoryButtons.add(newActor);
ItemData item=ItemData.getItem(Current.player().getItems().get(i));
if(item==null)

View File

@@ -157,6 +157,7 @@ public class PlayerStatisticScene extends UIScene {
enemiesGroup.row();
blessingScroll = Controls.newLabel("");
blessingScroll.setStyle(new Label.LabelStyle(Controls.getBitmapFont("default"), Color.BLACK));
blessingScroll.setAlignment(Align.topLeft);
ui.onButtonPress("return", new Runnable() {
@Override
public void run() {

View File

@@ -66,7 +66,7 @@ public class RewardScene extends UIScene {
}
}
if (wait) {
flipCountDown = 3.0f;
flipCountDown = 1.5f;
doneClicked = true;
} else {
Forge.switchToLast();

View File

@@ -1,9 +1,18 @@
package forge.adventure.stage;
import com.badlogic.gdx.utils.Array;
import forge.StaticData;
import forge.adventure.data.EnemyData;
import forge.adventure.data.WorldData;
import forge.adventure.pointofintrest.PointOfInterest;
import forge.adventure.scene.InventoryScene;
import forge.adventure.scene.SceneType;
import forge.adventure.util.Current;
import forge.card.ColorSet;
import forge.deck.Deck;
import forge.deck.DeckProxy;
import forge.game.GameType;
import forge.item.PaperCard;
import java.util.ArrayList;
@@ -165,6 +174,28 @@ public class ConsoleCommandInterpreter {
Current.player().fullHeal();
return "Player life back to "+Current.player().getLife();
});
registerCommand(new String[]{"reloadScenes"}, s -> {
SceneType.InventoryScene.instance.resLoaded();
SceneType.PlayerStatisticScene.instance.resLoaded();
return "Force reload status scenes. Might be unstable.";
});
registerCommand(new String[]{"dumpEnemyDeckColors"}, s -> {
for(EnemyData E : new Array.ArrayIterator<>(WorldData.getAllEnemies())){
Deck D = E.generateDeck();
DeckProxy DP = new DeckProxy(D, "Constructed", GameType.Constructed, null);
ColorSet colorSet = DP.getColor();
System.out.printf("%s: Colors: %s (%s%s%s%s%s%s)\n", D.getName(), DP.getColor(),
(colorSet.hasBlack() ? "B" : ""),
(colorSet.hasGreen() ? "G" : ""),
(colorSet.hasRed() ? "R" : ""),
(colorSet.hasBlue() ? "U" : ""),
(colorSet.hasWhite() ? "W" : ""),
(colorSet.isColorless() ? "C" : "")
);
}
return "Enemy deck color list dumped to stdout.";
});
registerCommand(new String[]{"heal", "amount"}, s -> {
if(s.length<1) return "Command needs 1 parameter";
int N = 0;

View File

@@ -206,8 +206,8 @@ public class MapStage extends GameStage {
for (MapActor actor : new Array.ArrayIterator<>(actors)) {
actor.remove();
foregroundSprites.removeActor(actor);
}
actors = new Array<>();
width = Float.parseFloat(map.getProperties().get("width").toString());
height = Float.parseFloat(map.getProperties().get("height").toString());
@@ -220,8 +220,8 @@ public class MapStage extends GameStage {
MapProperties MP = map.getProperties();
if( MP.get("dungeonEffect") != null && !MP.get("dungeonEffect").toString().isEmpty()){
JSONStringLoader json = new JSONStringLoader();
effect = json.parse(EffectData.class, map.getProperties().get("dungeonEffect").toString(), "");
JSONStringLoader J = new JSONStringLoader();
effect = J.parse(EffectData.class, map.getProperties().get("dungeonEffect").toString(), "");
effectDialog(effect);
}
if (MP.get("preventEscape") != null) preventEscape = (boolean)MP.get("preventEscape");
@@ -266,7 +266,6 @@ public class MapStage extends GameStage {
private void loadObjects(MapLayer layer, String sourceMap) {
player.setMoveModifier(2);
for (MapObject obj : layer.getObjects()) {
MapProperties prop = obj.getProperties();
Object typeObject = prop.get("type");
if (typeObject != null) {
@@ -297,7 +296,12 @@ public class MapStage extends GameStage {
case "enemy":
Object E = prop.get("enemy");
if(E != null && !E.toString().isEmpty()) {
EnemySprite mob = new EnemySprite(id, WorldData.getEnemy(E.toString()));
EnemyData EN = WorldData.getEnemy(E.toString());
if(EN == null){
System.err.printf("Enemy \"%s\" not found.", E.toString());
break;
}
EnemySprite mob = new EnemySprite(id, EN);
Object D = prop.get("dialog"); //Check if the enemy has a dialogue attached to it.
if (D != null && !D.toString().isEmpty()) {
mob.dialog = new MapDialog(D.toString(), this, mob.getId());
@@ -314,6 +318,7 @@ public class MapStage extends GameStage {
if (D != null && !D.toString().isEmpty()) {
mob.effect = JSONStringLoader.parse(EffectData.class, D.toString(), "");
}
//TODO: Additional rewards.
addMapActor(obj, mob);
}
break;
@@ -321,6 +326,8 @@ public class MapStage extends GameStage {
TiledMapTileMapObject obj2 = (TiledMapTileMapObject) obj;
DummySprite D = new DummySprite(id, obj2.getTextureRegion(), this);
addMapActor(obj, D);
//TODO: Ability to toggle their solid state.
//TODO: Ability to move them (using a sequence such as "UULU" for up, up, left, up).
break;
case "inn":
addMapActor(obj, new OnCollide(new Runnable() {
@@ -436,7 +443,8 @@ public class MapStage extends GameStage {
return false;
}
public boolean lookForID(int id){
public boolean lookForID(int id){ //Search actor by ID.
for(MapActor A : new Array.ArrayIterator<>(actors)){
if(A.getId() == id)
return true;
@@ -444,7 +452,7 @@ public class MapStage extends GameStage {
return false;
}
public EnemySprite getEnemyByID(int id) {
public EnemySprite getEnemyByID(int id) { //Search actor by ID, enemies only.
for(MapActor A : new Array.ArrayIterator<>(actors)){
if(A instanceof EnemySprite && A.getId() == id)
return ((EnemySprite) A);
@@ -492,7 +500,7 @@ public class MapStage extends GameStage {
currentMob = mob;
if (mob.dialog != null){ //This enemy has something to say. Display a dialog like if it was a DialogActor.
resetPosition();
showDialog();
//showDialog();
mob.dialog.activate();
} else { //Duel the enemy.
beginDuel(mob);
@@ -534,7 +542,7 @@ public class MapStage extends GameStage {
}
}, ScreenUtils.getFrameBufferTexture(), true, false));
}
startPause(0.4f, new Runnable() {
startPause(0.3f, new Runnable() {
@Override
public void run() {
DuelScene S = ((DuelScene) SceneType.DuelScene.instance);
@@ -568,7 +576,6 @@ public class MapStage extends GameStage {
}
public void resetPosition() {
player.setPosition(oldPosition4);
stop();
}

View File

@@ -40,7 +40,6 @@ public class MapDialog {
return;
}
this.data = JSONStringLoader.parse(Array.class, DialogData.class, S, defaultJSON);
}
private void loadDialog(DialogData dialog) { //Displays a dialog with dialogue and possible choices.
@@ -91,6 +90,13 @@ public class MapDialog {
if (E.addItem != null){ //Gives an item to the player.
Current.player().addItem(E.addItem);
}
if(E.addLife != 0){ //Gives (positive or negative) life to the player. Cannot go over max health.
Current.player().heal(E.addLife);
}
if(E.addGold != 0){ //Gives (positive or negative) gold to the player.
if(E.addGold > 0) Current.player().giveGold(E.addGold);
else Current.player().takeGold(-E.addGold);
}
if (E.deleteMapObject != 0){ //Removes a dummy object from the map.
if(E.deleteMapObject < 0) stage.deleteObject(parentID);
else stage.deleteObject(E.deleteMapObject);
@@ -106,6 +112,9 @@ public class MapDialog {
Current.player().setColorIdentity(E.setColorIdentity);
}
//Create map object.
//Toggle dummy object's hitbox. (Like to make a door passable)
//Set world flag.
//Set dungeon flag.
}
}
@@ -123,6 +132,16 @@ public class MapDialog {
if(!condition.not) return false;
} else if(condition.not) return false;
}
if(condition.hasGold != 0){ //Check for at least X gold.
if(player.getGold() < condition.hasGold){
if(!condition.not) return false;
} else if(condition.not) return false;
}
if(condition.hasLife != 0){ //Check for at least X life..
if(player.getLife() < condition.hasLife + 1){
if(!condition.not) return false;
} else if(condition.not) return false;
}
if(condition.hasBlessing != null && !condition.hasBlessing.isEmpty()){ //Check for a named blessing.
if(!player.hasBlessing(condition.hasBlessing)){
if(!condition.not) return false;

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.4" orientation="orthogonal" renderorder="right-down" width="30" height="30" tilewidth="16" tileheight="16" infinite="0" nextlayerid="6" nextobjectid="84">
<map version="1.8" tiledversion="1.8.4" orientation="orthogonal" renderorder="right-down" width="30" height="30" tilewidth="16" tileheight="16" infinite="0" nextlayerid="6" nextobjectid="86">
<editorsettings>
<export format="tmx"/>
</editorsettings>
@@ -32,8 +32,7 @@
</data>
</layer>
<objectgroup id="4" name="Objects">
<object id="47" template="../obj/gold.tx" x="96" y="224"/>
<object id="49" template="../obj/gold.tx" x="176" y="224"/>
<object id="47" template="../obj/gold.tx" x="32" y="352"/>
<object id="50" template="../obj/enemy.tx" x="112" y="192" width="64" height="64">
<properties>
<property name="effect">{
@@ -77,12 +76,11 @@
<property name="sprite" value="sprites/3life.atlas"/>
</properties>
</object>
<object id="69" template="../obj/treasure.tx" x="192" y="352"/>
<object id="69" template="../obj/treasure.tx" x="48" y="336"/>
<object id="74" template="../obj/treasure.tx" x="224" y="352"/>
<object id="70" template="../obj/booster.tx" x="32" y="336"/>
<object id="72" template="../obj/booster.tx" x="224" y="320"/>
<object id="71" template="../obj/gold.tx" x="48" y="352"/>
<object id="73" template="../obj/gold.tx" x="224" y="288"/>
<object id="78" template="../obj/gate.tx" x="144" y="208" visible="0">
<properties>
<property name="dialog">[
@@ -207,5 +205,68 @@
</properties>
</object>
<object id="83" template="../obj/gate.tx" type="dummy" gid="3651" x="64" y="336" width="16" height="16"/>
<object id="84" template="../obj/enemy.tx" x="320" y="304">
<properties>
<property name="dialog">[
{
&quot;effect&quot;:[],
&quot;text&quot;:&quot;I have some things to offer for that life you have...&quot;,
&quot;condition&quot;:[],
&quot;options&quot;:[
{ &quot;name&quot;:&quot;You are suspicious and have two shadows, I'm out.&quot; },
{
&quot;name&quot;:&quot;I'll vanquish you, demon!&quot;,
&quot;text&quot;: &quot;Oh look we got a tough guy over here!&quot;,
&quot;options&quot;: [ { &quot;name&quot;: &quot;I FEAR NOTHING!!&quot;, &quot;effect&quot;: [ { &quot;battleWithActorID&quot;: -1 } ]} ]
},
{
&quot;name&quot;: &quot;I dig your edge.&quot;,
&quot;condition&quot;: [ { &quot;colorIdentity&quot;: &quot;B&quot;, &quot;not&quot;: true }, { &quot;hasLife&quot;: 2 } ],
&quot;text&quot;: &quot;You can be dark and edgy like me. Maybe for some of your life force...&quot;,
&quot;options&quot;: [ { &quot;name&quot;: &quot;I'm doing nothing better with it.&quot;, &quot;effect&quot;: [ { &quot;setColorIdentity&quot;: &quot;B&quot;, &quot;addLife&quot;: -2 } ]} ]
},
{
&quot;name&quot;: &quot;I dig your edge.&quot;,
&quot;condition&quot;: [ { &quot;colorIdentity&quot;: &quot;B&quot;, &quot;not&quot;: true }, { &quot;hasLife&quot;: 2, &quot;not&quot;: true } ],
&quot;text&quot;: &quot;You don't have enough life force...come back with more to offer.&quot;,
&quot;options&quot;: [ { &quot;name&quot;: &quot;Aw man...&quot; } ]
},
{
&quot;name&quot;: &quot;Any cool demon deals?&quot;,
&quot;condition&quot;: [ { &quot;colorIdentity&quot;: &quot;B&quot; }, { &quot;hasGold&quot;: 200 } ],
&quot;text&quot;: &quot;I can offer you this Treasure for the fair price of 200 gold.&quot;,
&quot;options&quot;: [
{ &quot;name&quot;: &quot;This gem has a lot of edge, just like me. Deal!&quot; , &quot;effect&quot;: [ { &quot;addGold&quot;: -20000, &quot;addItem&quot;: &quot;Treasure&quot; } ] },
{ &quot;name&quot;: &quot;I'll think about it.&quot; }
]
},
{
&quot;name&quot;:&quot;Got any fancy demon blessing?&quot;,
&quot;condition&quot;: [ {&quot;colorIdentity&quot;: &quot;B&quot;}, { &quot;item&quot;: &quot;Treasure&quot; }, { &quot;hasBlessing&quot;: &quot;Debug Demon&quot;, &quot;not&quot;: true } ],
&quot;text&quot;: &quot;Give me that Treasure of yours...\n(+1 health, Manasight, move speed 120%, Lord of the Pit starts in play)&quot;,
&quot;options&quot;: [
{ &quot;name&quot;: &quot;That's shady.&quot;},
{
&quot;name&quot;: &quot;What can possibly go wrong?&quot;,
&quot;effect&quot;: [
{ &quot;removeItem&quot;: &quot;Treasure&quot;, &quot;giveBlessing&quot;: { &quot;name&quot;: &quot;Debug Demon&quot; , &quot;lifeModifier&quot;: 1, &quot;colorView&quot;: true, &quot;moveSpeed&quot;: 2, &quot;startBattleWithCard&quot;: [ &quot;Lord of the Pit&quot; ] } }
]
}
]
}
]
}
]</property>
<property name="enemy" value="Demon"/>
<property name="name" value="Debug Demon"/>
</properties>
</object>
<object id="85" template="../obj/scroll.tx" x="224" y="288">
<properties>
<property name="reward">[
{ &quot;cardName&quot;: &quot;Black Lotus&quot;, &quot;type&quot;:&quot;card&quot;, &quot;count&quot;:1 }
]</property>
</properties>
</object>
</objectgroup>
</map>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<template>
<tileset firstgid="1" source="../tileset/buildings.tsx"/>
<object name="Scroll" type="reward" gid="1363" width="16" height="16">
<properties>
<property name="reward" value="[ { &quot;type&quot;: &quot;card&quot;, &quot;cardName&quot;: &quot;Black Lotus&quot;, &quot;amount&quot;: 1 } ]"/>
<property name="sprite" value="sprites/scroll.atlas"/>
</properties>
</object>
</template>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 KiB

After

Width:  |  Height:  |  Size: 227 KiB

View File

@@ -1,5 +1,5 @@
treasure.png
size: 64,112
size: 64,128
format: RGBA8888
filter: Nearest,Nearest
repeat: none

View File

@@ -1,5 +1,5 @@
treasure.png
size: 64,112
size: 64,128
format: RGBA8888
filter: Nearest,Nearest
repeat: none

View File

@@ -1,5 +1,5 @@
treasure.png
size: 64,112
size: 64,128
format: RGBA8888
filter: Nearest,Nearest
repeat: none

View File

@@ -1,5 +1,5 @@
treasure.png
size: 64,112
size: 64,128
format: RGBA8888
filter: Nearest,Nearest
repeat: none

View File

@@ -1,5 +1,5 @@
treasure.png
size: 64,112
size: 64,128
format: RGBA8888
filter: Nearest,Nearest
repeat: none

View File

@@ -0,0 +1,17 @@
treasure.png
size: 64,128
format: RGBA8888
filter: Nearest,Nearest
repeat: none
Idle
xy: 0, 112
size: 16, 16
Idle
xy: 16, 112
size: 16, 16
Idle
xy: 32, 112
size: 16, 16
Idle
xy: 48, 112
size: 16, 16

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -3,64 +3,65 @@
"height": 270,
"yDown": true,
"elements": [
{
{
"type": "Image",
"image": "ui/title_bg.png",
"width": 480,
"height": 270
}, {
},
{
"type": "Image",
"image": "ui/equipment.png",
"x": 8,
"image": "ui/equipment.png",
"x": 8,
"y": 8,
"width": 129,
"height": 243
},
},
{
"type": "ImageButton",
"name": "Equipment_Neck",
"style": "item_frame",
"name": "Equipment_Neck",
"style": "item_frame",
"width": 20,
"height": 20,
"x": 62,
"y": 40
} ,
},
{
"type": "ImageButton",
"name": "Equipment_Body",
"style": "item_frame",
"name": "Equipment_Body",
"style": "item_frame",
"width": 20,
"height": 20,
"x": 62,
"y": 85
} ,
},
{
"type": "ImageButton",
"name": "Equipment_Boots",
"style": "item_frame",
"name": "Equipment_Boots",
"style": "item_frame",
"width": 20,
"height": 20,
"x": 62,
"y": 220
} ,
},
{
"type": "ImageButton",
"name": "Equipment_Left",
"style": "item_frame",
"name": "Equipment_Left",
"style": "item_frame",
"width": 20,
"height": 20,
"x": 17,
"y": 130
} ,
},
{
"type": "ImageButton",
"name": "Equipment_Right",
"style": "item_frame",
"name": "Equipment_Right",
"style": "item_frame",
"width": 20,
"height": 20,
"x": 107,
"y": 130
} ,
},
{
"type": "Scroll",
"name": "inventory",
@@ -68,22 +69,22 @@
"y": 110,
"width": 330,
"height": 100
},
},
{
"type": "Window",
"type": "Window",
"x": 145,
"y": 8,
"width": 330,
"height": 98
} ,
},
{
"type": "Label",
"name": "item_description",
"x": 155,
"y": 8,
"y": 12,
"width": 310,
"height": 98
} ,
"height": 94
},
{
"type": "TextButton",
"name": "return",
@@ -99,17 +100,17 @@
"text": "Equip",
"width": 60,
"height": 30,
"x": 330,
"x": 320,
"y": 222
} ,
},
{
"type": "TextButton",
"name": "delete",
"text": "Delete",
"text": "Discard",
"width": 60,
"height": 30,
"x": 240,
"y": 222
}
}
]
}

View File

@@ -43,20 +43,11 @@
"width": 64,
"height": 64
},
{
"type": "Label",
"name": "playerName",
"x": 400,
"y": 20,
"width": 80,
"height": 24,
"font": "black"
},
{
"type": "Label",
"name": "totalWins",
"x": 410,
"y": 99,
"y": 102,
"width": 80,
"height": 24,
"font": "black"
@@ -66,7 +57,7 @@
"name": "wins",
"text": "Win:",
"x": 330,
"y": 99,
"y": 102,
"width": 80,
"height": 24,
"font": "black"
@@ -75,7 +66,7 @@
"type": "Label",
"name": "totalLoss",
"x": 410,
"y": 111,
"y": 113,
"width": 80,
"height": 24,
"font": "black"
@@ -85,7 +76,7 @@
"name": "loss",
"text": "Loss:",
"x": 330,
"y": 111,
"y": 113,
"width": 80,
"height": 24,
"font": "black"
@@ -94,7 +85,7 @@
"type": "Label",
"name": "lossWinRatio",
"x": 410,
"y": 123,
"y": 125,
"width": 80,
"height": 24,
"font": "black"
@@ -104,19 +95,19 @@
"name": "winloss",
"text": "Win Loss Ratio:",
"x": 330,
"y": 123,
"y": 125,
"width": 80,
"height": 24,
"font": "black"
},
{
"type": "Scroll",
"name": "blessingInfo",
"type": "Scroll",
"name": "blessingInfo",
"style": "nobg",
"x": 305,
"y": 135,
"width": 150,
"height": 88
"x": 308,
"y": 143,
"width": 144,
"height": 72
},
{
"type": "TextButton",
@@ -125,13 +116,13 @@
"width": 100,
"height": 30,
"x": 335,
"y": 226
"y": 224
},
{
"type": "Image",
"name": "lifeIcon",
"image": "ui/life.png",
"x": 400,
"x": 392,
"y": 40,
"width": 16,
"height": 16
@@ -140,18 +131,27 @@
"type": "Image",
"name": "goldIcon",
"image": "ui/money.png",
"x": 400,
"x": 392,
"y": 60,
"width": 16,
"height": 16
},
{
"type": "Label",
"name": "playerName",
"x": 394,
"y": 20,
"width": 80,
"height": 24,
"font": "black"
},
{
"type": "Label",
"name": "lifePoints",
"font": "black",
"width": 64,
"height": 16,
"x": 420,
"x": 410,
"y": 40
},
{
@@ -160,7 +160,7 @@
"font": "black",
"width": 64,
"height": 16,
"x": 420,
"x": 410,
"y": 60
},
{

File diff suppressed because it is too large Load Diff

View File

@@ -587,6 +587,14 @@
]
}
},
{
"name": "Manasight Amulet",
"equipmentSlot": "Neck",
"iconName": "RelicAmulet",
"effect": {
"colorView": true
}
},
{
"name": "Amulet of Kroog",
"equipmentSlot": "Neck",