mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
Added multiplayer fights
This commit is contained in:
@@ -19,7 +19,7 @@ public class CharacterSprite extends MapActor {
|
||||
private Animation<TextureRegion> currentAnimation = null;
|
||||
private AnimationTypes currentAnimationType = AnimationTypes.Idle;
|
||||
private AnimationDirections currentAnimationDir = AnimationDirections.None;
|
||||
private Sprite avatar;
|
||||
private Array<Sprite> avatar=new Array<>();
|
||||
public boolean hidden = false;
|
||||
|
||||
public CharacterSprite(int id,String path) {
|
||||
@@ -45,7 +45,7 @@ public class CharacterSprite extends MapActor {
|
||||
animations.clear();
|
||||
for (AnimationTypes stand : AnimationTypes.values()) {
|
||||
if (stand == AnimationTypes.Avatar) {
|
||||
avatar = atlas.createSprite(stand.toString());
|
||||
avatar.addAll(atlas.createSprites(stand.toString()));
|
||||
continue;
|
||||
}
|
||||
HashMap<AnimationDirections, Animation<TextureRegion>> dirs = new HashMap<>();
|
||||
@@ -227,7 +227,10 @@ public class CharacterSprite extends MapActor {
|
||||
}
|
||||
|
||||
public Sprite getAvatar() {
|
||||
return avatar;
|
||||
return avatar.first();
|
||||
}
|
||||
public Sprite getAvatar(int index) {
|
||||
return avatar.get(index);
|
||||
}
|
||||
|
||||
public enum AnimationTypes {
|
||||
|
||||
@@ -24,6 +24,9 @@ public class EnemyData {
|
||||
public String[] equipment;
|
||||
public String colors = "";
|
||||
|
||||
public EnemyData nextEnemy;
|
||||
public int teamNumber=-1;
|
||||
|
||||
public EnemyData() { }
|
||||
public EnemyData(EnemyData enemyData) {
|
||||
name = enemyData.name;
|
||||
|
||||
@@ -9,6 +9,7 @@ import forge.LobbyPlayer;
|
||||
import forge.adventure.character.EnemySprite;
|
||||
import forge.adventure.character.PlayerSprite;
|
||||
import forge.adventure.data.EffectData;
|
||||
import forge.adventure.data.EnemyData;
|
||||
import forge.adventure.data.ItemData;
|
||||
import forge.adventure.player.AdventurePlayer;
|
||||
import forge.adventure.util.Config;
|
||||
@@ -51,7 +52,7 @@ public class DuelScene extends ForgeScene {
|
||||
PlayerSprite player;
|
||||
RegisteredPlayer humanPlayer;
|
||||
private EffectData dungeonEffect;
|
||||
Deck playerDeck, enemyDeck;
|
||||
Deck playerDeck;
|
||||
boolean chaosBattle = false;
|
||||
boolean callbackExit = false;
|
||||
List<IPaperCard> playerExtras = new ArrayList<>();
|
||||
@@ -134,7 +135,7 @@ public class DuelScene extends ForgeScene {
|
||||
changeStartCards+= data.changeStartCards;
|
||||
startCards.addAll(data.startBattleWithCards());
|
||||
}
|
||||
player.setCardsOnBattlefield(startCards);
|
||||
player.addExtraCardsOnBattlefield(startCards);
|
||||
player.setStartingLife(Math.max(1,lifeMod+player.getStartingLife()));
|
||||
player.setStartingHand(player.getStartingHand()+changeStartCards);
|
||||
}
|
||||
@@ -154,25 +155,41 @@ public class DuelScene extends ForgeScene {
|
||||
int missingCards= Config.instance().getConfigData().minDeckSize-playerDeck.getMain().countAll();
|
||||
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();
|
||||
FSkin.getAvatars().put(90001, advPlayer.avatar());
|
||||
playerObject.setAvatarIndex(90001);
|
||||
humanPlayer.setPlayer(playerObject);
|
||||
humanPlayer.setStartingLife(advPlayer.getLife());
|
||||
Current.setLatestDeck(enemyDeck);
|
||||
RegisteredPlayer aiPlayer = RegisteredPlayer.forVariants(2, appliedVariants, Current.latestDeck(), null, false, null, null);
|
||||
LobbyPlayer enemyPlayer = GamePlayerUtil.createAiPlayer(this.enemy.getData().name, selectAI(this.enemy.getData().ai));
|
||||
if(!enemy.nameOverride.isEmpty()) enemyPlayer.setName(enemy.nameOverride); //Override name if defined in the map.
|
||||
FSkin.getAvatars().put(90000, this.enemy.getAvatar());
|
||||
enemyPlayer.setAvatarIndex(90000);
|
||||
int playerCount=1;
|
||||
EnemyData currentEnemy=enemy.getData();
|
||||
for(int i=0;i<8&¤tEnemy!=null;i++)
|
||||
{
|
||||
playerCount++;
|
||||
currentEnemy=currentEnemy.nextEnemy;
|
||||
}
|
||||
|
||||
aiPlayer.setPlayer(enemyPlayer);
|
||||
aiPlayer.setStartingLife(Math.round((float)enemy.getData().life*advPlayer.getDifficulty().enemyLifeFactor));
|
||||
humanPlayer = RegisteredPlayer.forVariants(playerCount, appliedVariants,playerDeck, null, false, null, null);
|
||||
LobbyPlayer playerObject = GamePlayerUtil.getGuiPlayer();
|
||||
FSkin.getAvatars().put(90000, advPlayer.avatar());
|
||||
playerObject.setAvatarIndex(90000);
|
||||
humanPlayer.setPlayer(playerObject);
|
||||
humanPlayer.setTeamNumber(0);
|
||||
humanPlayer.setStartingLife(advPlayer.getLife());
|
||||
|
||||
Array<EffectData> playerEffects = new Array<>();
|
||||
Array<EffectData> oppEffects = new Array<>();
|
||||
|
||||
|
||||
Map<DeckProxy, Pair<List<String>, List<String>>> deckProxyMapMap = null;
|
||||
DeckProxy deckProxy =null;
|
||||
if(chaosBattle)
|
||||
{
|
||||
deckProxyMapMap = DeckProxy.getAllQuestChallenges();
|
||||
List<DeckProxy> decks = new ArrayList<>(deckProxyMapMap.keySet());
|
||||
deckProxy = Aggregates.random(decks);
|
||||
//playerextras
|
||||
List<IPaperCard> playerCards = new ArrayList<>();
|
||||
for (String s : deckProxyMapMap.get(deckProxy).getLeft()) {
|
||||
playerCards.add(QuestUtil.readExtraCard(s));
|
||||
}
|
||||
humanPlayer.addExtraCardsOnBattlefield(playerCards);
|
||||
}
|
||||
|
||||
//Collect and add items effects first.
|
||||
for(String playerItem:advPlayer.getEquippedItems()) {
|
||||
ItemData item=ItemData.getItem(playerItem);
|
||||
@@ -183,13 +200,6 @@ public class DuelScene extends ForgeScene {
|
||||
System.err.printf("Item %s not found.", playerItem);
|
||||
}
|
||||
}
|
||||
if(enemy.getData().equipment!=null) {
|
||||
for(String oppItem:enemy.getData().equipment) {
|
||||
ItemData item=ItemData.getItem(oppItem);
|
||||
oppEffects.add(item.effect);
|
||||
if(item.effect.opponent !=null) playerEffects.add(item.effect.opponent);
|
||||
}
|
||||
}
|
||||
|
||||
//Collect and add player blessings.
|
||||
if(advPlayer.getBlessing() != null){
|
||||
@@ -212,16 +222,62 @@ public class DuelScene extends ForgeScene {
|
||||
}
|
||||
|
||||
addEffects(humanPlayer,playerEffects);
|
||||
addEffects(aiPlayer,oppEffects);
|
||||
|
||||
//add extra cards for challenger mode
|
||||
if (chaosBattle) {
|
||||
humanPlayer.addExtraCardsOnBattlefield(playerExtras);
|
||||
aiPlayer.addExtraCardsOnBattlefield(AIExtras);
|
||||
currentEnemy=enemy.getData();
|
||||
for(int i=0;i<8&¤tEnemy!=null;i++)
|
||||
{
|
||||
Deck deck=null;
|
||||
|
||||
if (this.chaosBattle) { //random challenge for chaos mode
|
||||
//aiextras
|
||||
List<IPaperCard> aiCards = new ArrayList<>();
|
||||
for (String s : deckProxyMapMap.get(deck).getRight()) {
|
||||
aiCards.add(QuestUtil.readExtraCard(s));
|
||||
}
|
||||
this.AIExtras = aiCards;
|
||||
deck = deckProxy.getDeck();
|
||||
} else {
|
||||
deck=currentEnemy.copyPlayerDeck ? this.playerDeck : currentEnemy.generateDeck(Current.player().isFantasyMode(), Current.player().getDifficulty().name.equalsIgnoreCase("Hard"));
|
||||
}
|
||||
RegisteredPlayer aiPlayer = RegisteredPlayer.forVariants(playerCount, appliedVariants, deck, null, false, null, null);
|
||||
|
||||
LobbyPlayer enemyPlayer = GamePlayerUtil.createAiPlayer(currentEnemy.name, selectAI(currentEnemy.ai));
|
||||
if(!enemy.nameOverride.isEmpty()) enemyPlayer.setName(enemy.nameOverride); //Override name if defined in the map.(only supported for 1 enemy atm)
|
||||
FSkin.getAvatars().put(90001+i, enemy.getAvatar(i));
|
||||
enemyPlayer.setAvatarIndex(90001+i);
|
||||
aiPlayer.setPlayer(enemyPlayer);
|
||||
aiPlayer.setTeamNumber(currentEnemy.teamNumber);
|
||||
aiPlayer.setStartingLife(Math.round((float)currentEnemy.life*advPlayer.getDifficulty().enemyLifeFactor));
|
||||
|
||||
Array<EffectData> equipmentEffects = new Array<>();
|
||||
if(currentEnemy.equipment!=null) {
|
||||
for(String oppItem:currentEnemy.equipment) {
|
||||
ItemData item=ItemData.getItem(oppItem);
|
||||
equipmentEffects.add(item.effect);
|
||||
if(item.effect.opponent !=null) playerEffects.add(item.effect.opponent);
|
||||
}
|
||||
}
|
||||
addEffects(aiPlayer,oppEffects);
|
||||
addEffects(aiPlayer,equipmentEffects);
|
||||
|
||||
|
||||
//add extra cards for challenger mode
|
||||
if (chaosBattle) {
|
||||
aiPlayer.addExtraCardsOnBattlefield(AIExtras);
|
||||
}
|
||||
|
||||
players.add(aiPlayer);
|
||||
|
||||
|
||||
|
||||
Current.setLatestDeck(deck);
|
||||
|
||||
currentEnemy=currentEnemy.nextEnemy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
players.add(humanPlayer);
|
||||
players.add(aiPlayer);
|
||||
|
||||
final Map<RegisteredPlayer, IGuiGame> guiMap = new HashMap<>();
|
||||
guiMap.put(humanPlayer, MatchController.instance);
|
||||
@@ -253,7 +309,7 @@ public class DuelScene extends ForgeScene {
|
||||
"It's all or nothing!","It's all on the line!","You can't back down now!","Do you have what it takes?","What will happen next?",
|
||||
"Don't blink!","You can't lose here!","There's no turning back!","It's all or nothing now!");
|
||||
String message = Aggregates.random(list);
|
||||
FThreads.delayInEDT(600, () -> FThreads.invokeInEdtNowOrLater(() -> FOptionPane.showMessageDialog(message, aiPlayer.getPlayer().getName(), new FBufferedImage(120, 120) {
|
||||
FThreads.delayInEDT(600, () -> FThreads.invokeInEdtNowOrLater(() -> FOptionPane.showMessageDialog(message, enemy.getName(), new FBufferedImage(120, 120) {
|
||||
@Override
|
||||
protected void draw(Graphics g, float w, float h) {
|
||||
if (FSkin.getAvatars().get(90000) != null)
|
||||
@@ -285,34 +341,11 @@ public class DuelScene extends ForgeScene {
|
||||
this.enemy = enemySprite;
|
||||
this.playerDeck = (Deck)AdventurePlayer.current().getSelectedDeck().copyTo("PlayerDeckCopy");
|
||||
this.chaosBattle = this.enemy.getData().copyPlayerDeck && Current.player().isFantasyMode();
|
||||
if (this.chaosBattle) { //random challenge for chaos mode
|
||||
Map<DeckProxy, Pair<List<String>, List<String>>> deckProxyMapMap = DeckProxy.getAllQuestChallenges();
|
||||
List<DeckProxy> decks = new ArrayList<>(deckProxyMapMap.keySet());
|
||||
DeckProxy deck = Aggregates.random(decks);
|
||||
//playerextras
|
||||
List<IPaperCard> playerCards = new ArrayList<>();
|
||||
for (String s : deckProxyMapMap.get(deck).getLeft()) {
|
||||
playerCards.add(QuestUtil.readExtraCard(s));
|
||||
}
|
||||
this.playerExtras = playerCards;
|
||||
//aiextras
|
||||
List<IPaperCard> aiCards = new ArrayList<>();
|
||||
for (String s : deckProxyMapMap.get(deck).getRight()) {
|
||||
aiCards.add(QuestUtil.readExtraCard(s));
|
||||
}
|
||||
this.AIExtras = aiCards;
|
||||
this.enemyDeck = deck.getDeck();
|
||||
} else {
|
||||
this.AIExtras.clear();
|
||||
this.playerExtras.clear();
|
||||
this.enemyDeck = this.enemy.getData().copyPlayerDeck ? this.playerDeck : this.enemy.getData().generateDeck(Current.player().isFantasyMode(), Current.player().getDifficulty().name.equalsIgnoreCase("Hard"));
|
||||
}
|
||||
}
|
||||
public Deck getPlayerDeck() {
|
||||
return this.playerDeck;
|
||||
}
|
||||
public Deck getEnemyDeck() {
|
||||
return this.enemyDeck;
|
||||
|
||||
|
||||
this.AIExtras.clear();
|
||||
this.playerExtras.clear();
|
||||
|
||||
}
|
||||
|
||||
private String selectAI(String ai) { //Decide opponent AI.
|
||||
|
||||
@@ -117,6 +117,13 @@ public class ConsoleCommandInterpreter {
|
||||
WorldStage.getInstance().GetPlayer().setPosition(poi.getPosition());
|
||||
return "Teleported to " + s[0] + "(" + poi.getPosition() + ")";
|
||||
});
|
||||
registerCommand(new String[]{"spawn","enemy"}, s -> {
|
||||
if(s.length<1) return "Command needs 1 parameter: enemy name.";
|
||||
|
||||
if(WorldStage.getInstance().spawn(s[0]))
|
||||
return "Spawn " + s[0];
|
||||
return "Can not find enemy "+s[0];
|
||||
});
|
||||
registerCommand(new String[]{"give", "gold"}, s -> {
|
||||
if(s.length<1) return "Command needs 1 parameter: Amount.";
|
||||
int amount;
|
||||
|
||||
@@ -202,6 +202,10 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
|
||||
return WorldSave.getCurrentSave().getWorld().collidingTile(boundingRect);
|
||||
}
|
||||
public boolean spawn(String enemy)
|
||||
{
|
||||
return spawn(WorldData.getEnemy(enemy));
|
||||
}
|
||||
|
||||
private void HandleMonsterSpawn(float delta) {
|
||||
World world = WorldSave.getCurrentSave().getWorld();
|
||||
@@ -223,8 +227,12 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
if (list == null)
|
||||
return;
|
||||
EnemyData enemyData = data.getEnemy( 1.0f );
|
||||
spawn(enemyData);
|
||||
}
|
||||
|
||||
private boolean spawn(EnemyData enemyData) {
|
||||
if (enemyData == null)
|
||||
return;
|
||||
return false;
|
||||
EnemySprite sprite = new EnemySprite(enemyData);
|
||||
float unit = Scene.getIntendedHeight() / 6f;
|
||||
Vector2 spawnPos = new Vector2(1, 1);
|
||||
@@ -242,11 +250,12 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
{
|
||||
enemies.add(Pair.of(globalTimer,sprite));
|
||||
foregroundSprites.addActor(sprite);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
int g=0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
75
forge-gui/res/adventure/Shandalar/sprites/goblin_group.atlas
Normal file
75
forge-gui/res/adventure/Shandalar/sprites/goblin_group.atlas
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
goblin_group.png
|
||||
size: 64,96
|
||||
format: RGBA8888
|
||||
filter: Nearest,Nearest
|
||||
repeat: none
|
||||
Avatar
|
||||
xy: 0, 0
|
||||
size: 16, 16
|
||||
Avatar
|
||||
xy: 16, 0
|
||||
size: 16, 16
|
||||
Avatar
|
||||
xy: 32, 0
|
||||
size: 16, 16
|
||||
Idle
|
||||
xy: 0, 16
|
||||
size: 32, 16
|
||||
Idle
|
||||
xy: 32, 16
|
||||
size: 32, 16
|
||||
Idle
|
||||
xy: 64, 16
|
||||
size: 32, 16
|
||||
Idle
|
||||
xy: 96, 16
|
||||
size: 32, 16
|
||||
Walk
|
||||
xy: 0, 32
|
||||
size: 32, 16
|
||||
Walk
|
||||
xy: 32, 32
|
||||
size: 32, 16
|
||||
Walk
|
||||
xy: 64, 32
|
||||
size: 32, 16
|
||||
Walk
|
||||
xy: 96, 32
|
||||
size: 32, 16
|
||||
Attack
|
||||
xy: 0, 48
|
||||
size: 32, 16
|
||||
Attack
|
||||
xy: 32, 48
|
||||
size: 32, 16
|
||||
Attack
|
||||
xy: 64, 48
|
||||
size: 32, 16
|
||||
Attack
|
||||
xy: 96, 48
|
||||
size: 32, 16
|
||||
Hit
|
||||
xy: 0, 64
|
||||
size: 32, 16
|
||||
Hit
|
||||
xy: 32, 64
|
||||
size: 32, 16
|
||||
Hit
|
||||
xy: 64, 64
|
||||
size: 32, 16
|
||||
Hit
|
||||
xy: 96, 64
|
||||
size: 32, 16
|
||||
Death
|
||||
xy: 0, 80
|
||||
size: 32, 16
|
||||
Death
|
||||
xy: 32, 80
|
||||
size: 32, 16
|
||||
Death
|
||||
xy: 64, 80
|
||||
size: 32, 16
|
||||
Death
|
||||
xy: 96, 80
|
||||
size: 32, 16
|
||||
BIN
forge-gui/res/adventure/Shandalar/sprites/goblin_group.png
Normal file
BIN
forge-gui/res/adventure/Shandalar/sprites/goblin_group.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -3547,5 +3547,56 @@
|
||||
"Black Lotus"
|
||||
],
|
||||
"colors": "BGRUW"
|
||||
},
|
||||
{
|
||||
"name": "Goblin pack",
|
||||
"sprite": "sprites/goblin_group.atlas",
|
||||
"deck": "decks/goblin_bad.json",
|
||||
"ai": "",
|
||||
"teamNumber" :1,
|
||||
"spawnRate": 1,
|
||||
"difficulty": 0.1,
|
||||
"speed": 27,
|
||||
"life": 8,
|
||||
"rewards": [
|
||||
{
|
||||
"type": "deckCard",
|
||||
"probability": 1,
|
||||
"count": 2,
|
||||
"addMaxCount": 4
|
||||
},
|
||||
{
|
||||
"type": "gold",
|
||||
"probability": 0.7,
|
||||
"count": 10,
|
||||
"addMaxCount": 90
|
||||
},
|
||||
{
|
||||
"type": "card",
|
||||
"probability": 0.5,
|
||||
"count": 3,
|
||||
"colors": [
|
||||
"Red"
|
||||
],
|
||||
"rarity": [
|
||||
"Rare"
|
||||
]
|
||||
}
|
||||
],
|
||||
"colors": "R",
|
||||
"nextEnemy": {
|
||||
"name": "Goblin",
|
||||
"teamNumber" :1,
|
||||
"deck": "decks/goblin_bad.json",
|
||||
"ai": "",
|
||||
"life": 8,
|
||||
"nextEnemy": {
|
||||
"name": "Goblin",
|
||||
"teamNumber" :1,
|
||||
"deck": "decks/goblin_bad.json",
|
||||
"ai": "",
|
||||
"life": 8
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user