fixed game hud

This commit is contained in:
Grimm
2022-04-15 13:16:37 +02:00
50 changed files with 12017 additions and 808 deletions

View File

@@ -1,116 +1,36 @@
package forge.adventure.character;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json;
import forge.adventure.data.DialogData;
import forge.adventure.stage.MapStage;
import forge.adventure.util.Config;
import forge.adventure.util.Controls;
import forge.adventure.util.Current;
import forge.adventure.util.MapDialog;
/**
* Map actor that will open the Shop on collision
* Map actor that will show a text message with optional choices
*/
public class DialogActor extends MapActor{
public class DialogActor extends MapActor {
private final MapStage stage;
private final String dialogPath;
private final TextureRegion textureRegion;
private final MapDialog dialog;
public DialogActor(MapStage stage, int id, String dialog, TextureRegion textureRegion)
{
public DialogActor(MapStage stage, int id, String S, TextureRegion textureRegion) {
super(id);
this.stage = stage;
this.dialogPath = dialog;
dialog = new MapDialog(S, stage, id);
this.textureRegion = textureRegion;
}
@Override
public void onPlayerCollide()
{
Json json = new Json();
FileHandle handle = Config.instance().getFile(dialogPath);
if (handle.exists()) {
Array<DialogData> data = json.fromJson(Array.class, DialogData.class, handle);
stage.resetPosition();
stage.showDialog();
for(DialogData dialog:data)
{
if(isConditionOk(dialog.condition))
{
loadDialog(dialog);
}
}
}
}
private void loadDialog(DialogData dialog) {
setEffects(dialog.effect);
stage.getDialog().getContentTable().clear();
stage.getDialog().getButtonTable().clear();
stage.getDialog().text((dialog.text));
if(dialog.options!=null)
{
for(DialogData option:dialog.options)
{
if( isConditionOk(option.condition) )
{
stage.getDialog().getButtonTable().add(Controls.newTextButton(option.name,() -> {
loadDialog(option);
}));
}
}
stage.showDialog();
}
else
{
stage.hideDialog();
}
}
void setEffects(DialogData.EffectData[] data)
{
if(data==null)
return ;
for(DialogData.EffectData effectData:data)
{
Current.player().removeItem(effectData.removeItem);
if(effectData.deleteMapObject<0)
stage.deleteObject(getObjectId());
else if(effectData.deleteMapObject>0)
stage.deleteObject(effectData.deleteMapObject);
}
}
boolean isConditionOk(DialogData.ConditionData[] data)
{
if(data==null)
return true;
for(DialogData.ConditionData condition:data)
{
if(condition.item!=null && !condition.item.equals(""))
{
if(!Current.player().hasItem(condition.item))
{
return false;
}
}
}
return true;
public void onPlayerCollide() {
stage.resetPosition();
stage.showDialog();
dialog.activate();
}
@Override
public void draw(Batch batch, float alpha) {
batch.draw(textureRegion,getX(),getY(),getWidth(),getHeight());
super.draw(batch,alpha);
batch.draw(textureRegion, getX(), getY(), getWidth(), getHeight());
super.draw(batch, alpha);
}
}

View File

@@ -0,0 +1,29 @@
package forge.adventure.character;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import forge.adventure.stage.MapStage;
/**
* DummySprite
* Solid map entity. Cannot move or be interacted with, but can be removed from events.
*/
public class DummySprite extends MapActor {
private final TextureRegion textureRegion;
private final MapStage stage;
public DummySprite(int id, TextureRegion textureRegion, MapStage stage) {
super(id);
this.textureRegion = textureRegion;
this.stage = stage;
}
@Override
public void onPlayerCollide() { stage.resetPosition(); }
@Override
public void draw(Batch batch, float alpha) {
batch.draw(textureRegion, getX(), getY(), getWidth(), getHeight());
super.draw(batch, alpha);
}
}

View File

@@ -7,6 +7,7 @@ import com.badlogic.gdx.utils.Array;
import forge.adventure.data.EnemyData;
import forge.adventure.data.RewardData;
import forge.adventure.util.Current;
import forge.adventure.util.MapDialog;
import forge.adventure.util.Reward;
/**
@@ -16,6 +17,7 @@ import forge.adventure.util.Reward;
public class EnemySprite extends CharacterSprite {
EnemyData data;
private int id;
public MapDialog dialog;
public EnemySprite(EnemyData enemyData) {
super(enemyData.sprite);
@@ -48,11 +50,10 @@ public class EnemySprite extends CharacterSprite {
public Array<Reward> getRewards() {
Array<Reward> ret=new Array<Reward>();
if(data.rewards==null)
if(data.rewards == null)
return ret;
for(RewardData rdata:data.rewards)
{
ret.addAll(rdata.generate(false,Current.latestDeck()!=null? Current.latestDeck().getMain().toFlatList():null,data.equipment));
for(RewardData rdata:data.rewards) {
ret.addAll(rdata.generate(false,(Current.latestDeck()!=null? Current.latestDeck().getMain().toFlatList():null)));
}
return ret;
}

View File

@@ -94,6 +94,10 @@ public class MapActor extends Actor {
}
public int getId(){
return objectId;
}
public boolean collideWith(MapActor other) {
return collideWith(other.boundingRect());
}

View File

@@ -1,18 +1,28 @@
package forge.adventure.data;
/**
* Dialog Data JSON loader class.
* Carries all text, branches and effects of dialogs.
*/
public class DialogData {
public EffectData[] effect;
public ConditionData[] condition;
public String name;
public String text;
public DialogData[] options;
public EffectData[] effect; //List of effects to cause when the dialog shows.
public ConditionData[] condition; //List of conditions for the action to show.
public String name; //Text to display when action is listed as a button.
public String text; //The text body.
public String loctext; //References a localized string.
public DialogData[] options; //
static public class EffectData {
public String removeItem;
public int deleteMapObject;
public String removeItem; //Remove item name from inventory.
public String addItem; //Add item name to inventory.
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.
}
static public class ConditionData {
public String item;
public int flag = 0; //Check for a local dungeon flag.
public int actorID = 0; //Check for an actor ID.
public boolean not = false; //Reverse the result of a condition ("actorID":"XX" + "not":true => true if XX is not in the map.)
}
}

View File

@@ -0,0 +1,68 @@
package forge.adventure.data;
import com.badlogic.gdx.utils.Array;
import forge.item.IPaperCard;
import forge.item.PaperCard;
import forge.item.PaperToken;
import forge.model.FModel;
public class EffectData {
//Duel effects.
public int lifeModifier = 0; //Amount to add to starting Life.
public int changeStartCards = 0; //Amount to add to starting hand size.
public String[] startBattleWithCard; //Cards that start in the Battlefield.
//Map only effects.
public float moveSpeed = 1.0f; //Change of movement speed. Map only.
//Opponent field.
public EffectData opponent; //Effects to be applied to the opponent's side.
public Array<IPaperCard> startBattleWithCards() {
Array<IPaperCard> startCards=new Array<>();
if(startBattleWithCard != null) {
for (String name:startBattleWithCard) {
PaperCard C = FModel.getMagicDb().getCommonCards().getCard(name);
if(C != null)
startCards.add(C);
else {
PaperToken T = FModel.getMagicDb().getAllTokens().getToken(name);
if (T != null) startCards.add(T);
else System.err.print("Can not find card \"" + name + "\"\n");
}
}
}
return startCards;
}
public String cardNames() {
String ret = "";
Array<IPaperCard> array=startBattleWithCards();
for(int i =0;i<array.size;i++) {
ret+=array.get(i).toString();
if(i!=array.size-1) ret+=" , ";
}
return ret;
}
public String getDescription() {
String description = "";
if(this.lifeModifier != 0)
description += "Life: " + ((this.lifeModifier > 0) ? "+" : "") + this.lifeModifier + "\n";
if(this.startBattleWithCard != null && this.startBattleWithCard.length != 0)
description+="Cards on battlefield: \n" + this.cardNames() + "\n";
if(this.moveSpeed!=0 && this.moveSpeed != 1)
description+="Movement speed: " + ((this.lifeModifier > 0) ? "+" : "") + Math.round((this.moveSpeed-1.f)*100) + "%\n";
if(this.changeStartCards != 0)
description+="Starting hand: " + this.changeStartCards + "\n";
if(this.opponent != null) {
String oppEffect=this.opponent.getDescription();
if(oppEffect != "") {
description += "Gives Opponent:\n";
description += oppEffect;
}
}
return description;
}
}

View File

@@ -7,8 +7,6 @@ import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json;
import forge.adventure.util.Config;
import forge.adventure.util.Paths;
import forge.item.IPaperCard;
import forge.model.FModel;
import static forge.adventure.util.Paths.ITEMS_ATLAS;
@@ -20,16 +18,10 @@ import static forge.adventure.util.Paths.ITEMS_ATLAS;
public class ItemData {
public String name;
public String equipmentSlot;
public int lifeModifier=0;
public int changeStartCards=0;
public String[] startBattleWithCard;
public EffectData effect;
public String iconName;
public float moveSpeed=1.0f;
public boolean questItem=false;
public int cost=1000;
//not an item on it owns but effects will be applied to the opponent
public ItemData opponent;
public Sprite sprite()
{
@@ -64,56 +56,12 @@ public class ItemData {
return null;
}
public Array<IPaperCard> startBattleWithCards() {
Array<IPaperCard> startCards=new Array<>();
if(startBattleWithCard!=null)
{
for (String name:startBattleWithCard)
{
if(FModel.getMagicDb().getCommonCards().contains(name))
startCards.add(FModel.getMagicDb().getCommonCards().getCard(name));
else if (FModel.getMagicDb().getAllTokens().containsRule(name))
startCards.add(FModel.getMagicDb().getAllTokens().getToken(name));
else
{
System.err.print("Can not find card "+name+"\n");
}
}
}
return startCards;
}
public String cardNames() {
String ret="";
Array<IPaperCard> array=startBattleWithCards();
for(int i =0;i<array.size;i++)
{
ret+=array.get(i).toString();
if(i!=array.size-1)
ret+=" , ";
}
return ret;
}
public String getDescription() {
String description = "";
if(this.equipmentSlot != null && !this.equipmentSlot.equals(""))
if(this.equipmentSlot != null && !this.equipmentSlot.isEmpty())
description += "Slot: " + this.equipmentSlot + "\n";
if(this.lifeModifier != 0)
description += "Life: " + ((this.lifeModifier > 0) ? "+" : "") + this.lifeModifier + "\n";
if(this.startBattleWithCard != null && this.startBattleWithCard.length != 0)
description+="Cards on battlefield: \n" + this.cardNames() + "\n";
if(this.moveSpeed!=0 && this.moveSpeed != 1)
description+="Movement speed: " + ((this.lifeModifier > 0) ? "+" : "") + Math.round((this.moveSpeed-1.f)*100) + "%\n";
if(this.changeStartCards != 0)
description+="Starting hand: " + this.changeStartCards + "\n";
if(this.opponent != null) {
String oppEffect=this.opponent.getDescription();
if(oppEffect != "") {
description += "Gives Opponent:\n";
description += oppEffect;
}
}
if(effect != null)
description += effect.getDescription();
return description;
}
}

View File

@@ -69,9 +69,9 @@ public class RewardData {
private static Iterable<PaperCard> allEnemyCards;
public Array<Reward> generate(boolean isForEnemy)
{
return generate(isForEnemy,null,null);
return generate(isForEnemy, null);
}
public Array<Reward> generate(boolean isForEnemy,Iterable<PaperCard> cards,String[] enemyItems)
public Array<Reward> generate(boolean isForEnemy,Iterable<PaperCard> cards)
{
if(allCards==null)
{
@@ -127,17 +127,6 @@ public class RewardData {
}
}
break;
case "enemyItems":
if(enemyItems==null)return ret;
for(int i=0;i<count+addedCount;i++)
{
ret.add(new Reward(ItemData.getItem(enemyItems[WorldSave.getCurrentSave().getWorld().getRandom().nextInt(enemyItems.length)])));
}
for(PaperCard card: CardUtil.generateCards(cards,this, count+addedCount))
{
ret.add(new Reward(card));
}
break;
case "deckCard":
if(cards==null)return ret;
for(PaperCard card: CardUtil.generateCards(cards,this, count+addedCount))

View File

@@ -418,12 +418,10 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
public float equipmentSpeed() {
float factor=1.0f;
for(String name:equippedItems.values())
{
for(String name:equippedItems.values()) {
ItemData data=ItemData.getItem(name);
if(data.moveSpeed!=0.0)
{
factor*=data.moveSpeed;
if(data.effect.moveSpeed > 0.0) { //Avoid negative speeds. It would be silly.
factor*=data.effect.moveSpeed;
}
}
return factor;

View File

@@ -6,6 +6,7 @@ import forge.Forge;
import forge.LobbyPlayer;
import forge.adventure.character.EnemySprite;
import forge.adventure.character.PlayerSprite;
import forge.adventure.data.EffectData;
import forge.adventure.data.ItemData;
import forge.adventure.player.AdventurePlayer;
import forge.adventure.util.Config;
@@ -40,6 +41,7 @@ public class DuelScene extends ForgeScene {
EnemySprite enemy;
PlayerSprite player;
RegisteredPlayer humanPlayer;
private EffectData dungeonEffect;
public DuelScene() {
@@ -57,6 +59,7 @@ public class DuelScene extends ForgeScene {
@Override
public void run() {
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); //start background music
dungeonEffect = null;
Scene last = Forge.switchToLast();
if (last instanceof HudScene) {
@@ -68,17 +71,14 @@ public class DuelScene extends ForgeScene {
}
void addItemEffects(RegisteredPlayer player,Array<ItemData> items)
{
if(items==null)
return;
void addEffects(RegisteredPlayer player,Array<EffectData> effects) {
if( effects == null ) return;
//Apply various effects.
int lifeMod=0;
int changeStartCards=0;
Array<IPaperCard> startCards=new Array<>();
for(ItemData data:items)
{
for(EffectData data:effects) {
lifeMod+=data.lifeModifier;
changeStartCards+= data.changeStartCards;
startCards.addAll(data.startBattleWithCards());
@@ -88,6 +88,10 @@ public class DuelScene extends ForgeScene {
player.setStartingHand(player.getStartingHand()+changeStartCards);
}
public void setDungeonEffect(EffectData E) {
dungeonEffect = E;
}
@Override
public void enter() {
@@ -97,7 +101,7 @@ public class DuelScene extends ForgeScene {
List<RegisteredPlayer> players = new ArrayList<>();
Deck playerDeck=(Deck)AdventurePlayer.current().getSelectedDeck().copyTo("PlayerDeckCopy");
int missingCards= Config.instance().getConfigData().minDeckSize-playerDeck.getMain().countAll();
if(missingCards>0)
if( missingCards > 0 ) //Replace unknown cards for a Wastes.
playerDeck.getMain().add("Wastes",missingCards);
humanPlayer = RegisteredPlayer.forVariants(2, appliedVariants,playerDeck, null, false, null, null);
LobbyPlayer playerObject = GamePlayerUtil.getGuiPlayer();
@@ -117,29 +121,36 @@ public class DuelScene extends ForgeScene {
Array<ItemData> playerItems=new Array<>();
Array<ItemData> oppItems=new Array<>();
Array<EffectData> playerEffects = new Array<>();
Array<EffectData> oppEffects = new Array<>();
for(String playerItem:Current.player().getEquippedItems())
{
//Collect and add items effects first.
for(String playerItem:Current.player().getEquippedItems()) {
ItemData item=ItemData.getItem(playerItem);
playerItems.add(item);
if(item.opponent !=null)
oppItems.add(item.opponent);
playerEffects.add(item.effect);
if(item.effect.opponent != null) oppEffects.add(item.effect.opponent);
}
if(enemy.getData().equipment!=null)
{
for(String oppItem:enemy.getData().equipment)
{
if(enemy.getData().equipment!=null) {
for(String oppItem:enemy.getData().equipment) {
ItemData item=ItemData.getItem(oppItem);
oppItems.add(item);
if(item.opponent !=null)
playerItems.add(item.opponent);
oppEffects.add(item.effect);
if(item.effect.opponent !=null) playerEffects.add(item.effect.opponent);
}
}
addItemEffects(humanPlayer,playerItems);
addItemEffects(aiPlayer,oppItems);
//Collect and add player blessings.
//Collect and add enemy effects (same as blessings but for individual enemies).
//Collect and add dungeon-wide effects.
if(dungeonEffect != null) {
oppEffects.add(dungeonEffect);
if (dungeonEffect.opponent != null)
playerEffects.add(dungeonEffect.opponent);
}
addEffects(humanPlayer,playerEffects);
addEffects(aiPlayer,oppEffects);
players.add(humanPlayer);
players.add(aiPlayer);
@@ -163,10 +174,10 @@ public class DuelScene extends ForgeScene {
}
});
hostedMatch.startMatch(rules, appliedVariants, players, guiMap);
MatchController.instance.setGameView(hostedMatch.getGameView());
for (final Player p : hostedMatch.getGame().getPlayers()) {
if (p.getController() instanceof PlayerControllerHuman) {
final PlayerControllerHuman humanController = (PlayerControllerHuman) p.getController();

View File

@@ -12,12 +12,16 @@ import com.badlogic.gdx.utils.viewport.ScalingViewport;
import forge.Forge;
import forge.adventure.character.MapActor;
import forge.adventure.character.PlayerSprite;
import forge.adventure.data.PointOfInterestData;
import forge.adventure.pointofintrest.PointOfInterest;
import forge.adventure.scene.Scene;
import forge.adventure.scene.SceneType;
import forge.adventure.scene.TileMapScene;
import forge.adventure.util.Current;
import forge.adventure.world.WorldSave;
import forge.gui.GuiBase;
import forge.util.MyRandom;
import forge.localinstance.properties.ForgePreferences;
import forge.model.FModel;
@@ -194,6 +198,13 @@ public abstract class GameStage extends Stage {
setDebugAll(true);
player.setBoundDebug(true);
}
if (keycode == Input.Keys.F2) {
TileMapScene S = ((TileMapScene)SceneType.TileMapScene.instance);
PointOfInterestData P = PointOfInterestData.getPointOfInterest("DEBUGZONE");
PointOfInterest PoI = new PointOfInterest(P,new Vector2(0,0), MyRandom.getRandom());
S.load(PoI);
Forge.switchScene(S);
}
if (keycode == Input.Keys.F11) {
debugCollision(false);
for (Actor actor : foregroundSprites.getChildren()) {

View File

@@ -16,20 +16,17 @@ import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.ScreenUtils;
import com.badlogic.gdx.utils.SerializationException;
import forge.Forge;
import forge.adventure.character.*;
import forge.adventure.data.RewardData;
import forge.adventure.data.ShopData;
import forge.adventure.data.WorldData;
import forge.adventure.data.*;
import forge.adventure.pointofintrest.PointOfInterestChanges;
import forge.adventure.scene.DuelScene;
import forge.adventure.scene.RewardScene;
import forge.adventure.scene.SceneType;
import forge.adventure.util.Config;
import forge.adventure.util.Controls;
import forge.adventure.util.Current;
import forge.adventure.util.Reward;
import forge.adventure.util.*;
import forge.adventure.world.WorldSave;
import forge.screens.TransitionScreen;
import forge.sound.SoundEffectType;
@@ -67,14 +64,18 @@ public class MapStage extends GameStage {
private Stage dialogStage;
private boolean dialogOnlyInput;
private EffectData effect;
public boolean getDialogOnlyInput() {
return dialogOnlyInput;
}
public Dialog getDialog() {
return dialog;
}
public void clearIsInMap() {
isInMap = false;
effect = null;
GameHUD.getInstance().showHideMap(true);
}
public void draw (Batch batch) {
@@ -83,9 +84,7 @@ public class MapStage extends GameStage {
//update camera after all layers got drawn
if (!getRoot().isVisible()) return;
getRoot().draw(batch, 1);
}
public MapLayer getSpriteLayer() {
@@ -181,6 +180,17 @@ public class MapStage extends GameStage {
}
private void effectDialog(EffectData E){
dialog.getContentTable().clear();
dialog.getButtonTable().clear();
String text = "Strange magical energies flow within this place...\nAll opponents get:\n";
text += E.getDescription();
dialog.text(text);
dialog.getButtonTable().add(Controls.newTextButton("OK", this::hideDialog));
dialog.setKeepWithinStage(true);
showDialog();
}
public void loadMap(TiledMap map, String sourceMap) {
isLoadingMatch = false;
isInMap = true;
@@ -199,6 +209,18 @@ public class MapStage extends GameStage {
setBounds(width * tileWidth, height * tileHeight);
collision = new ArrayList[(int) width][(int) height];
//Load dungeon effects.
if( map.getProperties().get("dungeonEffect") != null && !map.getProperties().get("dungeonEffect").toString().isEmpty()){
Json json = new Json();
try { effect = json.fromJson(EffectData.class, map.getProperties().get("dungeonEffect").toString()); }
catch(SerializationException E) {
//JSON parsing could fail. Since this an user written part, assume failure is possible (it happens).
System.err.printf("[%s] while loading JSON file for dialog actor. JSON:\n%s\nUsing a default dialog.", E.getMessage(), map.getProperties().get("dungeonEffect").toString());
effect = json.fromJson(EffectData.class, "");
}
effectDialog(effect);
}
GetPlayer().stop();
for (MapLayer layer : map.getLayers()) {
@@ -254,12 +276,22 @@ public class MapStage extends GameStage {
addMapActor(obj, entry);
break;
case "reward":
RewardSprite R = new RewardSprite(id, prop.get("reward").toString(), prop.get("sprite").toString());
addMapActor(obj, R);
if (prop.get("reward") != null) {
RewardSprite R = new RewardSprite(id, prop.get("reward").toString(), prop.get("sprite").toString());
addMapActor(obj, R);
}
break;
case "enemy":
EnemySprite mob = new EnemySprite(id, WorldData.getEnemy(prop.get("enemy").toString()));
addMapActor(obj, mob);
if(prop.get("dialog") != null && !prop.get("dialog").toString().isEmpty()) {
mob.dialog = new MapDialog(prop.get("dialog").toString(), this, mob.getId());
}
break;
case "dummy": //Does nothing. Mostly obstacles to be removed by ID by switches or such.
TiledMapTileMapObject obj2 = (TiledMapTileMapObject) obj;
DummySprite D = new DummySprite(id, obj2.getTextureRegion(), this);
addMapActor(obj, D);
break;
case "inn":
addMapActor(obj, new OnCollide(new Runnable() {
@@ -278,13 +310,11 @@ public class MapStage extends GameStage {
}));
break;
case "dialog":
if(obj instanceof TiledMapTileMapObject)
{
if(obj instanceof TiledMapTileMapObject) {
TiledMapTileMapObject tiledObj = (TiledMapTileMapObject) obj;
DialogActor dialog = new DialogActor(this, id, prop.get("dialog").toString(),tiledObj.getTextureRegion());
DialogActor dialog = new DialogActor(this, id, prop.get("dialog").toString(), tiledObj.getTextureRegion());
addMapActor(obj, dialog);
}
break;
case "shop":
String shopList = prop.get("shopList").toString();
@@ -304,7 +334,7 @@ public class MapStage extends GameStage {
continue;
ShopData data = shops.get(WorldSave.getCurrentSave().getWorld().getRandom().nextInt(shops.size));
Array<Reward> ret = new Array<Reward>();
Array<Reward> ret = new Array<>();
for (RewardData rdata : new Array.ArrayIterator<>(data.rewards)) {
ret.addAll(rdata.generate(false));
}
@@ -328,6 +358,7 @@ public class MapStage extends GameStage {
public boolean exit() {
isLoadingMatch = false;
effect = null; //Reset dungeon effects.
clearIsInMap();
Forge.switchScene(SceneType.GameScene.instance);
return true;
@@ -374,7 +405,22 @@ public class MapStage extends GameStage {
}
}
return false;
}
public boolean lookForID(int id){
for(MapActor A : new Array.ArrayIterator<>(actors)){
if(A.getId() == id)
return true;
}
return false;
}
public EnemySprite getEnemyByID(int id) {
for(MapActor A : new Array.ArrayIterator<>(actors)){
if(A instanceof EnemySprite && A.getId() == id)
return ((EnemySprite) A);
}
return null;
}
protected void getReward() {
@@ -398,41 +444,14 @@ public class MapStage extends GameStage {
if (actor instanceof EnemySprite) {
EnemySprite mob = (EnemySprite) actor;
currentMob = mob;
if (mob.getData().deck == null || mob.getData().deck.isEmpty()) {
currentMob.setAnimation(CharacterSprite.AnimationTypes.Death);
Gdx.input.vibrate(50);
startPause(0.3f, new Runnable() {
@Override
public void run() {
MapStage.this.getReward();
}
});
break;
} else {
player.setAnimation(CharacterSprite.AnimationTypes.Attack);
mob.setAnimation(CharacterSprite.AnimationTypes.Attack);
Gdx.input.vibrate(50);
Forge.setCursor(null, Forge.magnifyToggle ? "1" : "2");
SoundSystem.instance.play(SoundEffectType.ManaBurn, false);
if (!isLoadingMatch) {
isLoadingMatch = true;
Forge.setTransitionScreen(new TransitionScreen(new Runnable() {
@Override
public void run() {
Forge.clearTransitionScreen();
}
}, ScreenUtils.getFrameBufferTexture(), true, false));
}
startPause(0.5f, new Runnable() {
@Override
public void run() {
((DuelScene) SceneType.DuelScene.instance).setEnemy(mob);
((DuelScene) SceneType.DuelScene.instance).setPlayer(player);
Forge.switchScene(SceneType.DuelScene.instance);
}
});
break;
if (mob.dialog != null){ //This enemy has something to say. Display a dialog like if it was a DialogActor.
resetPosition();
showDialog();
mob.dialog.activate();
} else { //Duel the enemy.
beginDuel(mob);
}
break;
} else if (actor instanceof RewardSprite) {
Gdx.input.vibrate(50);
startPause(0.1f, new Runnable() {
@@ -452,6 +471,34 @@ public class MapStage extends GameStage {
}
}
public void beginDuel(EnemySprite mob){
if(mob == null) return;
currentMob = mob;
player.setAnimation(CharacterSprite.AnimationTypes.Attack);
mob.setAnimation(CharacterSprite.AnimationTypes.Attack);
Gdx.input.vibrate(50);
Forge.setCursor(null, Forge.magnifyToggle ? "1" : "2");
SoundSystem.instance.play(SoundEffectType.ManaBurn, false);
if (!isLoadingMatch) {
isLoadingMatch = true;
Forge.setTransitionScreen(new TransitionScreen(new Runnable() {
@Override
public void run() {
Forge.clearTransitionScreen();
}
}, ScreenUtils.getFrameBufferTexture(), true, false));
}
startPause(0.4f, new Runnable() {
@Override
public void run() {
DuelScene S = ((DuelScene) SceneType.DuelScene.instance);
S.setEnemy(mob);
S.setPlayer(player);
if(isInMap && effect != null) S.setDungeonEffect(effect);
Forge.switchScene(SceneType.DuelScene.instance);
}
});
}
public void setPointOfInterest(PointOfInterestChanges change) {
changes = change;
@@ -461,8 +508,6 @@ public class MapStage extends GameStage {
return isInMap;
}
public void showDialog() {
dialog.show(dialogStage);
dialogOnlyInput=true;

View File

@@ -0,0 +1,129 @@
package forge.adventure.util;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.SerializationException;
import forge.Forge;
import forge.adventure.data.DialogData;
import forge.adventure.stage.MapStage;
/**
* MapDialog
* Implements a dialogue/event tree for dialogs.
*/
public class MapDialog {
private final MapStage stage;
private Array<DialogData> data;
private final int parentID;
static private final String defaultJSON = "[\n" +
" {\n" +
" \"effect\":[],\n" +
" \"name\":\"Error\",\n" +
" \"text\":\"This is a fallback dialog.\\nPlease check Forge logs for errors.\",\n" +
" \"condition\":[],\n" +
" \"options\":[\n" +
" { \"name\":\"OK\" }\n" +
" ]\n" +
" }\n" +
"]";
public MapDialog(String S, MapStage ST, int parentID) {
this.stage = ST;
this.parentID = parentID;
Json json = new Json();
if (S.isEmpty()){
System.err.print("Dialog error. Dialog property is empty.\n");
this.data = json.fromJson(Array.class, DialogData.class, defaultJSON);
return;
}
try { data = json.fromJson(Array.class, DialogData.class, S); }
catch(SerializationException E){
//JSON parsing could fail. Since this an user written part, assume failure is possible (it happens).
System.err.printf("[%s] while loading JSON file for dialog actor. JSON:\n%s\nUsing a default dialog.", E.getMessage(), S);
this.data = json.fromJson(Array.class, DialogData.class, defaultJSON);
}
}
private void loadDialog(DialogData dialog) {
setEffects(dialog.effect);
stage.getDialog().getContentTable().clear();
stage.getDialog().getButtonTable().clear();
String text;
if(dialog.loctext != null && !dialog.loctext.isEmpty()){ //Check for localized string, otherwise print text.
text = Forge.getLocalizer().getMessage(dialog.loctext);
} else {
text = dialog.text;
}
int charCount = 0;
stage.getDialog().text(text);
if(dialog.options != null) {
for(DialogData option:dialog.options) {
if( isConditionOk(option.condition) ) {
charCount += option.name.length();
if(charCount > 35){ //Gross hack.
stage.getDialog().getButtonTable().row();
charCount = 0;
}
stage.getDialog().getButtonTable().add(Controls.newTextButton(option.name,() -> loadDialog(option)));
}
}
stage.showDialog();
}
else {
stage.hideDialog();
}
}
public void activate() {
for(DialogData dialog:data) {
if(isConditionOk(dialog.condition)) {
loadDialog(dialog);
}
}
}
void setEffects(DialogData.EffectData[] data) {
if(data==null) return;
for(DialogData.EffectData E:data) {
if (E.removeItem != null){
Current.player().removeItem(E.removeItem);
}
if (E.addItem != null){
Current.player().addItem(E.addItem);
}
if (E.deleteMapObject != 0){
if(E.deleteMapObject < 0) stage.deleteObject(parentID);
else stage.deleteObject(E.deleteMapObject);
}
if (E.battleWithActorID != 0){
if(E.battleWithActorID < 0) stage.beginDuel(stage.getEnemyByID(parentID));
else stage.beginDuel(stage.getEnemyByID(E.battleWithActorID));
}
}
}
boolean isConditionOk(DialogData.ConditionData[] data) {
if(data==null) return true;
for(DialogData.ConditionData condition:data) {
if(condition.item != null && !condition.item.isEmpty()) { //Check for item.
if(!Current.player().hasItem(condition.item)) {
if(!condition.not) return false; //Only return on a false.
} else if(condition.not) return false;
}
if(condition.actorID != 0) { //Check for actor ID.
if(!stage.lookForID(condition.actorID)){
if(!condition.not) return false; //Same as above.
} else if(condition.not) return false;
}
}
return true;
}
}

View File

@@ -250,13 +250,13 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
else
drawable.setMinSize(Scene.getIntendedWidth() * 0.95f, Scene.getIntendedWidth()* RewardScene.CARD_WIDTH_TO_HEIGHT * 0.95f);
toolTipImage = new Image(drawable);
tooltip = new Tooltip<Image>(toolTipImage);
tooltip = new Tooltip<>(toolTipImage);
holdTooltip = new HoldTooltip(new Image(drawable));
tooltip.setInstant(true);
if (GuiBase.isAndroid())
addListener(holdTooltip);
else
addListener(tooltip);
if (frontSideUp()) {
if (GuiBase.isAndroid()) addListener(holdTooltip);
else addListener(tooltip);
}
generatedTooltip = result; //Dispose of this later.
}