Merge branch 'master' of https://github.com/Card-Forge/forge into adventure

 Conflicts:
	forge-gui-mobile/src/forge/adventure/world/WorldSave.java
This commit is contained in:
Grimm
2022-08-09 13:50:01 +02:00
3 changed files with 442 additions and 447 deletions

View File

@@ -18,6 +18,8 @@ import forge.adventure.util.Config;
import forge.adventure.util.Paths;
import forge.adventure.util.SaveFileContent;
import forge.adventure.util.SaveFileData;
import forge.gui.FThreads;
import forge.gui.GuiBase;
import forge.util.ThreadUtil;
import org.apache.commons.lang3.tuple.Pair;
@@ -44,16 +46,15 @@ public class World implements Disposable, SaveFileContent {
private boolean worldDataLoaded = false;
private Texture globalTexture = null;
public Random getRandom()
{
public Random getRandom() {
return random;
}
static public int highestBiome(long biome) {
return (int) (Math.log(Long.highestOneBit(biome)) / Math.log(2));
}
public boolean collidingTile(Rectangle boundingRect)
{
public boolean collidingTile(Rectangle boundingRect) {
int xLeft = (int) boundingRect.getX() / getTileSize();
int yTop = (int) boundingRect.getY() / getTileSize();
@@ -71,6 +72,7 @@ public class World implements Disposable, SaveFileContent {
return false;
}
public void loadWorldData() {
if (worldDataLoaded)
return;
@@ -103,7 +105,6 @@ public class World implements Disposable, SaveFileContent {
terrainMap = (int[][]) saveFileData.readObject("terrainMap");
width = saveFileData.readInt("width");
height = saveFileData.readInt("height");
mapObjectIds = new SpritesDataMap(getChunkSize(), this.data.tileSize, this.data.width / getChunkSize());
@@ -135,6 +136,7 @@ public class World implements Disposable, SaveFileContent {
public BiomeSpriteData getObject(int id) {
return mapObjectIds.get(id);
}
private class DrawingInformation {
private int neighbors;
@@ -152,6 +154,7 @@ public class World implements Disposable, SaveFileContent {
regions.drawPixmapOn(terrain, neighbors, drawingPixmap);
}
}
public Pixmap getBiomeSprite(int x, int y) {
if (x < 0 || y <= 0 || x >= width || y > height)
return new Pixmap(data.tileSize, data.tileSize, Pixmap.Format.RGBA8888);
@@ -186,8 +189,7 @@ public class World implements Disposable, SaveFileContent {
bitIndex--;
}
}
if(biomeTerrain!=0&&neighbors!=0b111_111_111)
{
if (biomeTerrain != 0 && neighbors != 0b111_111_111) {
bitIndex = 8;
int baseNeighbors = 0;
for (int ny = 1; ny > -2; ny--) {
@@ -204,8 +206,7 @@ public class World implements Disposable, SaveFileContent {
}
int lastFullNeighbour = -1;
int counter = 0;
for(DrawingInformation info:information)
{
for (DrawingInformation info : information) {
if (info.neighbors == 0b111_111_111)
lastFullNeighbour = counter;
counter++;
@@ -214,10 +215,8 @@ public class World implements Disposable, SaveFileContent {
counter = 0;
if (lastFullNeighbour < 0 && information.size() != 0)
information.get(0).neighbors = 0b111_111_111;
for(DrawingInformation info:information)
{
if(counter<lastFullNeighbour)
{
for (DrawingInformation info : information) {
if (counter < lastFullNeighbour) {
counter++;
continue;
}
@@ -234,6 +233,7 @@ public class World implements Disposable, SaveFileContent {
return 0;
}
}
public boolean isStructure(int x, int y) {
try {
return (terrainMap[x][height - y - 1] & ~isStructureBit) != 0;
@@ -257,34 +257,34 @@ public class World implements Disposable, SaveFileContent {
return true;
}
}
public WorldData getData() {
return data;
}
private void clearTerrain(int x,int y,int size)
{
private void clearTerrain(int x, int y, int size) {
for (int xclear = -size; xclear < size; xclear++)
for(int yclear=-size;yclear<size;yclear++)
{
for (int yclear = -size; yclear < size; yclear++) {
try {
terrainMap[x + xclear][height - 1 - (y + yclear)] = 0;
}
catch (ArrayIndexOutOfBoundsException e)
{
} catch (ArrayIndexOutOfBoundsException e) {
}
}
}
private long measureGenerationTime(String msg,long lastTime)
{
private long measureGenerationTime(String msg, long lastTime) {
long currentTime = System.currentTimeMillis();
System.out.print("\n" + msg + " :\t\t" + ((currentTime - lastTime) / 1000f) + " s");
return currentTime;
}
public World generateNew(long seed) {
long currentTime = System.currentTimeMillis();
public World generateNew(long seed) {
if (GuiBase.isAndroid())
GuiBase.getInterface().preventSystemSleep(true);
final long[] currentTime = {System.currentTimeMillis()};
long startTime = System.currentTimeMillis();
loadWorldData();
@@ -314,8 +314,8 @@ private long measureGenerationTime(String msg,long lastTime)
pix.setColor(1, 0, 0, 1);
pix.fill();
int biomeIndex = -1;
currentTime = measureGenerationTime("loading data", currentTime);
final int[] biomeIndex = {-1};
currentTime[0] = measureGenerationTime("loading data", currentTime[0]);
HashMap<BiomeStructureData, BiomeStructure> structureDataMap = new HashMap<>();
@@ -335,11 +335,10 @@ private long measureGenerationTime(String msg,long lastTime)
}
}
}
FThreads.invokeInEdtNowOrLater(() -> {
for (BiomeData biome : data.GetBiomes()) {
biomeIndex++;
biomeIndex[0]++;
int biomeXStart = (int) Math.round(biome.startPointX * (double) width);
int biomeYStart = (int) Math.round(biome.startPointY * (double) height);
int biomeWidth = (int) Math.round(biome.width * (double) width);
@@ -372,16 +371,13 @@ private long measureGenerationTime(String msg,long lastTime)
color.fromHsv(hsv);
pix.setColor(color.r, color.g, color.b, 1);
pix.drawPixel(x, y);
biomeMap[x][y] |= (1L << biomeIndex);
biomeMap[x][y] |= (1L << biomeIndex[0]);
int terrainCounter = 1;
terrainMap[x][y] = 0;
if(biome.terrain!=null)
{
for(BiomeTerrainData terrain:biome.terrain)
{
if (biome.terrain != null) {
for (BiomeTerrainData terrain : biome.terrain) {
float terrainNoise = ((float) noise.eval(x / (float) width * (noiseZoom * terrain.resolution), y / (float) height * (noiseZoom * terrain.resolution)) + 1) / 2;
if(terrainNoise>=terrain.min&&terrainNoise<=terrain.max)
{
if (terrainNoise >= terrain.min && terrainNoise <= terrain.max) {
terrainMap[x][y] = terrainCounter;
}
terrainCounter++;
@@ -389,10 +385,8 @@ private long measureGenerationTime(String msg,long lastTime)
}
if (biome.collision)
terrainMap[x][y] |= collisionBit;
if(biome.structures!=null)
{
for(BiomeStructureData data:biome.structures)
{
if (biome.structures != null) {
for (BiomeStructureData data : biome.structures) {
while (!structureDataMap.containsKey(data)) {
try {
Thread.sleep(10);
@@ -406,8 +400,7 @@ private long measureGenerationTime(String msg,long lastTime)
int structureYStart = y - (biomeYStart - biomeHeight / 2) - (int) ((data.y * biomeHeight) - (data.height * biomeHeight / 2));
int structureIndex = structure.objectID(structureXStart, structureYStart);
if(structureIndex>=0)
{
if (structureIndex >= 0) {
pix.setColor(data.mappingInfo[structureIndex].getColor());
pix.drawPixel(x, y);
terrainMap[x][y] = terrainCounter + structureIndex;
@@ -425,7 +418,7 @@ private long measureGenerationTime(String msg,long lastTime)
}
}
}
currentTime=measureGenerationTime("biomes in total",currentTime);
currentTime[0] = measureGenerationTime("biomes in total", currentTime[0]);
mapPoiIds = new PointOfInterestMap(getChunkSize(), data.tileSize, data.width / getChunkSize(), data.height / getChunkSize());
List<PointOfInterest> towns = new ArrayList<>();
@@ -450,8 +443,7 @@ private long measureGenerationTime(String msg,long lastTime)
y *= (biome.height * height / 2);
y += (height - (biome.startPointY * height));
if((int)x<0||(int)y<=0||(int)y>=height||(int)x>=width|| biomeIndex2!= highestBiome(getBiome((int)x,(int)y)))
{
if ((int) x < 0 || (int) y <= 0 || (int) y >= height || (int) x >= width || biomeIndex2 != highestBiome(getBiome((int) x, (int) y))) {
continue;
}
@@ -465,36 +457,29 @@ private long measureGenerationTime(String msg,long lastTime)
break;
}
}
if (breakNextLoop)
{
if (breakNextLoop) {
boolean foundSolution = false;
boolean noSolution = false;
breakNextLoop = false;
for(int xi=-1;xi<2&&!foundSolution;xi++)
{
for(int yi=-1;yi<2&&!foundSolution;yi++)
{
for (int xi = -1; xi < 2 && !foundSolution; xi++) {
for (int yi = -1; yi < 2 && !foundSolution; yi++) {
for (Rectangle rect : otherPoints) {
if (rect.contains(x + xi * data.tileSize, y + yi * data.tileSize)) {
noSolution = true;
break;
}
}
if(!noSolution)
{
if (!noSolution) {
foundSolution = true;
x = x + xi * data.tileSize;
y = y + yi * data.tileSize;
}
}
}
if(!foundSolution)
{
if(counter==499)
{
if (!foundSolution) {
if (counter == 499) {
System.err.print("Can not place POI " + poi.name + "\n");
}
continue;
@@ -513,9 +498,7 @@ private long measureGenerationTime(String msg,long lastTime)
if (poi.type != null && poi.type.equals("town")) {
towns.add(newPoint);
}
else
{
} else {
notTowns.add(newPoint);
}
break;
@@ -525,7 +508,7 @@ private long measureGenerationTime(String msg,long lastTime)
}
}
currentTime=measureGenerationTime("poi placement",currentTime);
currentTime[0] = measureGenerationTime("poi placement", currentTime[0]);
//sort towns
List<Pair<PointOfInterest, PointOfInterest>> allSortedTowns = new ArrayList<>();
@@ -582,7 +565,7 @@ private long measureGenerationTime(String msg,long lastTime)
continue;
allPOIPathsToNextTown.add(Pair.of(poi, towns.get(smallestIndex)));
}
biomeIndex++;
biomeIndex[0]++;
pix.setColor(1, 1, 1, 1);
//reset terrain path to the next town
@@ -598,8 +581,7 @@ private long measureGenerationTime(String msg,long lastTime)
int sy = startY < y1 ? 1 : -1;
int err = dx - dy;
int e2;
while (true)
{
while (true) {
if (startX < 0 || startY <= 0 || startX >= width || startY > height) continue;
if ((terrainMap[startX][height - startY] & collisionBit) != 0)//clear terrain if it has collision
terrainMap[startX][height - startY] = 0;
@@ -608,13 +590,10 @@ private long measureGenerationTime(String msg,long lastTime)
if (startX == x1 && startY == y1)
break;
e2 = 2 * err;
if (e2 > -dy)
{
if (e2 > -dy) {
err = err - dy;
startX = startX + sx;
}
else if (e2 < dx)
{
} else if (e2 < dx) {
err = err + dx;
startY = startY + sy;
}
@@ -630,7 +609,7 @@ private long measureGenerationTime(String msg,long lastTime)
for (int x = startX - 1; x < startX + 2; x++) {
for (int y = startY - 1; y < startY + 2; y++) {
if (x < 0 || y <= 0 || x >= width || y > height) continue;
biomeMap[x][height - y-1] |= (1L << biomeIndex);
biomeMap[x][height - y - 1] |= (1L << biomeIndex[0]);
terrainMap[x][height - y - 1] = 0;
@@ -643,29 +622,25 @@ private long measureGenerationTime(String msg,long lastTime)
int sy = startY < y1 ? 1 : -1;
int err = dx - dy;
int e2;
while (true)
{
while (true) {
if (startX < 0 || startY <= 0 || startX >= width || startY > height) continue;
biomeMap[startX][height - startY] |= (1L << biomeIndex);
biomeMap[startX][height - startY] |= (1L << biomeIndex[0]);
terrainMap[startX][height - startY] = 0;
pix.drawPixel(startX, height - startY);
if (startX == x1 && startY == y1)
break;
e2 = 2 * err;
if (e2 > -dy)
{
if (e2 > -dy) {
err = err - dy;
startX = startX + sx;
}
else if (e2 < dx)
{
} else if (e2 < dx) {
err = err + dx;
startY = startY + sy;
}
}
}
currentTime=measureGenerationTime("roads",currentTime);
currentTime[0] = measureGenerationTime("roads", currentTime[0]);
mapObjectIds = new SpritesDataMap(getChunkSize(), data.tileSize, data.width / getChunkSize());
for (int x = 0; x < width; x++) {
@@ -698,11 +673,14 @@ private long measureGenerationTime(String msg,long lastTime)
}
}
biomeImage = pix;
measureGenerationTime("sprites",currentTime);
measureGenerationTime("sprites", currentTime[0]);
});
System.out.print("\nGenerating world took :\t\t" + ((System.currentTimeMillis() - startTime) / 1000f) + " s\n");
WorldStage.getInstance().clearCache();
ThreadUtil.getServicePool().shutdownNow();
ThreadUtil.refreshServicePool();
if (GuiBase.isAndroid())
GuiBase.getInterface().preventSystemSleep(false);
return this;
}
@@ -753,6 +731,7 @@ private long measureGenerationTime(String msg,long lastTime)
public PointOfInterest findPointsOfInterest(String name) {
return mapPoiIds.findPointsOfInterest(name);
}
public int getChunkSize() {
return (Scene.getIntendedWidth() > Scene.getIntendedHeight() ? Scene.getIntendedWidth() : Scene.getIntendedHeight()) / data.tileSize;
}

View File

@@ -55,12 +55,16 @@ public class Assets implements Disposable {
}
@Override
public void dispose() {
if (counterFonts != null)
for (BitmapFont bitmapFont : counterFonts.values())
bitmapFont.dispose();
if (generatedCards != null)
for (Texture texture : generatedCards.values())
texture.dispose();
if (fallback_skins != null)
for (Texture texture : fallback_skins.values())
texture.dispose();
if (tmxMap != null)
for (Texture texture : tmxMap.values())
texture.dispose();
if (defaultImage != null)

View File

@@ -0,0 +1,12 @@
Name:Big Spender
ManaCost:1 R
Types:Creature Devil Citizen
PT:2/1
K:Haste
T:Mode$ AttackerBlockedOnce | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigTreasure | TriggerDescription$ Whenever one or more creatures you control become blocked, create a Treasure token.
SVar:TrigTreasure:DB$ Token | TokenScript$ c_a_treasure_sac
A:AB$ Draft | Cost$ Sac<2/Artifact> | Spellbook$ Arcane Encyclopedia,Daredevil Dragster,Diamond Mare,Filigree Familiar,Fountain of Renewal,Gilded Lotus,Golden Egg,Guild Globe,Heraldic Banner,Honored Heirloom,Key to the City,Prophetic Prism,Stuffed Bear,Treasure Vault,Zephyr Boots | SpellDescription$ Draft a card from CARDNAME's spellbook.
DeckHas:Ability$Sacrifice|Token|Discard|LifeGain & Type$Treasure|Artifact|Horse|Fox|Food|Equipment|Bear
DeckHints:Type$Treasure
SVar:AIPreference:SacCost$Treasure.Token,Artifact.Token
Oracle:Haste\nWhenever one or more creatures you control become blocked, create a Treasure token.\nSacrifice two artifacts: Draft a card from Big Spender's spellbook.