mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Adventure mode content
Preview release of Liliana dungeon Autosave when entering POI Improved POI enemy pathing (slightly) Addition of Portal mechanics Rework of Death Ring Increased land quantity in basic land shops Removed problematic objective from quest "(Almost) Open for Business"
This commit is contained in:
@@ -1034,6 +1034,13 @@ public class Forge implements ApplicationListener {
|
||||
if (currentScene != null) {
|
||||
if (!currentScene.leave())
|
||||
return false;
|
||||
if (lastScene.contains(currentScene, false))
|
||||
{
|
||||
int i = lastScene.indexOf(currentScene, false);
|
||||
if (i > -1){
|
||||
lastScene.setSize(i);
|
||||
}
|
||||
}
|
||||
lastScene.add(currentScene);
|
||||
}
|
||||
storeScreen();
|
||||
|
||||
@@ -20,6 +20,7 @@ public class CharacterSprite extends MapActor {
|
||||
private AnimationDirections currentAnimationDir = AnimationDirections.None;
|
||||
private final Array<Sprite> avatar=new Array<>();
|
||||
public boolean hidden = false;
|
||||
public boolean inactive = false;
|
||||
private String atlasPath;
|
||||
private float wakeTimer = 0.0f;
|
||||
|
||||
@@ -175,10 +176,18 @@ public class CharacterSprite extends MapActor {
|
||||
|
||||
public void moveBy(float x, float y, float delta) {
|
||||
|
||||
if (inactive){
|
||||
return;
|
||||
}
|
||||
|
||||
if (hidden) {
|
||||
setAnimation(AnimationTypes.Wake);
|
||||
wakeTimer = 0.0f;
|
||||
hidden = false;
|
||||
if (animations.containsKey(AnimationTypes.Wake)) {
|
||||
//Todo: Need another check here if we want objects revealed by activateMapObject to play wake animation
|
||||
setAnimation(AnimationTypes.Wake);
|
||||
wakeTimer = 0.0f;
|
||||
hidden = false;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
|
||||
if (currentAnimationType == AnimationTypes.Wake && wakeTimer <= currentAnimation.getAnimationDuration()){
|
||||
@@ -192,7 +201,7 @@ public class CharacterSprite extends MapActor {
|
||||
Vector2 vec = new Vector2(x, y);
|
||||
float degree = vec.angleDeg();
|
||||
|
||||
setAnimation(AnimationTypes.Walk);
|
||||
if (!hidden) setAnimation(AnimationTypes.Walk);
|
||||
if (degree < 22.5)
|
||||
setDirection(AnimationDirections.Right);
|
||||
else if (degree < 22.5 + 45)
|
||||
@@ -229,9 +238,8 @@ public class CharacterSprite extends MapActor {
|
||||
|
||||
@Override
|
||||
public void draw(Batch batch, float parentAlpha) {
|
||||
if (currentAnimation == null || hidden)
|
||||
if (currentAnimation == null || hidden || inactive)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
super.draw(batch,parentAlpha);
|
||||
|
||||
@@ -64,8 +64,10 @@ public class DialogActor extends CharacterSprite {
|
||||
public void onPlayerCollide() {
|
||||
if (dialog != null) {
|
||||
stage.resetPosition();
|
||||
stage.showDialog();
|
||||
dialog.activate();
|
||||
|
||||
if (dialog.activate()){
|
||||
stage.showDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
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;
|
||||
@@ -51,8 +50,10 @@ public class EnemySprite extends CharacterSprite {
|
||||
private final Float _movementTimeout = 150.0f;
|
||||
private boolean _freeze = false; //freeze movement after defeating player
|
||||
public float unfreezeRange = 30.0f;
|
||||
public float threatRange = 0.0f;
|
||||
public float fleeRange = 0.0f;
|
||||
public float threatRange = 0.0f; //If range < threatRange, begin pursuit
|
||||
public float pursueRange = 0.0f; //If range > pursueRange, abandon pursuit
|
||||
public float fleeRange = 0.0f; //If range < fleeRange, attempt to move away to fleeRange
|
||||
private boolean aggro = false;
|
||||
public boolean ignoreDungeonEffect = false;
|
||||
public String questStageID;
|
||||
|
||||
@@ -77,11 +78,6 @@ public class EnemySprite extends CharacterSprite {
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle navigationBoundingRect() {
|
||||
//This version of the bounds will be used for navigation purposes to allow mobile mobs to not need pixel perfect pathing
|
||||
return new Rectangle(boundingRect).setSize(boundingRect.width * collisionHeight, boundingRect.height * collisionHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
void updateBoundingRect() { //We want enemies to take the full tile.
|
||||
float scale = data == null ? 1f : data.scale;
|
||||
@@ -124,9 +120,9 @@ public class EnemySprite extends CharacterSprite {
|
||||
}
|
||||
|
||||
if (threatRange > 0 || fleeRange > 0){
|
||||
|
||||
if (routeToPlayer.len() <= threatRange)
|
||||
if (routeToPlayer.len() <= threatRange || (aggro && routeToPlayer.len() <= pursueRange))
|
||||
{
|
||||
aggro = true;
|
||||
return routeToPlayer;
|
||||
}
|
||||
if (routeToPlayer.len() <= fleeRange)
|
||||
@@ -291,6 +287,8 @@ public class EnemySprite extends CharacterSprite {
|
||||
|
||||
@Override
|
||||
public void draw(Batch batch, float parentAlpha) {
|
||||
if (inactive || hidden)
|
||||
return;
|
||||
super.draw(batch, parentAlpha);
|
||||
if(Current.player().hasColorView() && !data.colors.isEmpty()) {
|
||||
drawColorHints(batch);
|
||||
@@ -303,7 +301,7 @@ public class EnemySprite extends CharacterSprite {
|
||||
if(effect != null){ //Draw a crown icon on top.
|
||||
Texture T = Current.world().getGlobalTexture();
|
||||
TextureRegion TR = new TextureRegion(T, 16, 0, 16, 16);
|
||||
batch.draw(TR, getX(), getY() + 16, 16, 16);
|
||||
batch.draw(TR, getX(), getY() + 16, 16*getScaleX(), 16*getScaleY());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,15 +8,17 @@ import forge.adventure.stage.MapStage;
|
||||
* Used to teleport the player in and out of the map
|
||||
*/
|
||||
public class EntryActor extends MapActor{
|
||||
private final MapStage stage;
|
||||
final MapStage stage;
|
||||
String targetMap;
|
||||
private float x;
|
||||
private float y;
|
||||
private float w;
|
||||
private float h;
|
||||
private String direction;
|
||||
float x;
|
||||
float y;
|
||||
float w;
|
||||
float h;
|
||||
String direction;
|
||||
String currentMap;
|
||||
int entryTargetObject;
|
||||
|
||||
public EntryActor(MapStage stage, int id,String targetMap,float x,float y,float w,float h,String direction)
|
||||
public EntryActor(MapStage stage, int id,String targetMap,float x,float y,float w,float h,String direction, String currentMap, int entryTargetObject)
|
||||
{
|
||||
super(id);
|
||||
this.stage = stage;
|
||||
@@ -25,7 +27,8 @@ public class EntryActor extends MapActor{
|
||||
this.y = y;
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
|
||||
this.currentMap = currentMap;
|
||||
this.entryTargetObject = entryTargetObject;
|
||||
|
||||
this.direction = direction;
|
||||
}
|
||||
@@ -44,7 +47,15 @@ public class EntryActor extends MapActor{
|
||||
}
|
||||
else
|
||||
{
|
||||
TileMapScene.instance().loadNext(targetMap);
|
||||
if (targetMap.equals(currentMap))
|
||||
{
|
||||
stage.spawn(entryTargetObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentMap = targetMap;
|
||||
TileMapScene.instance().loadNext(targetMap, entryTargetObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
183
forge-gui-mobile/src/forge/adventure/character/PortalActor.java
Normal file
183
forge-gui-mobile/src/forge/adventure/character/PortalActor.java
Normal file
@@ -0,0 +1,183 @@
|
||||
package forge.adventure.character;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.*;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import forge.adventure.scene.TileMapScene;
|
||||
import forge.adventure.stage.MapStage;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Paths;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* PortalActor
|
||||
* Extension of EntryActor, visible on map, multiple states that change behavior
|
||||
*/
|
||||
public class PortalActor extends EntryActor{
|
||||
|
||||
private final HashMap<PortalAnimationTypes, Animation<TextureRegion>> animations = new HashMap<>();
|
||||
private Animation<TextureRegion> currentAnimation = null;
|
||||
private PortalAnimationTypes currentAnimationType = PortalAnimationTypes.Closed;
|
||||
|
||||
float timer;
|
||||
|
||||
float transitionTimer;
|
||||
|
||||
public PortalActor(MapStage stage, int id, String targetMap, float x, float y, float w, float h, String direction, String currentMap, int portalTargetObject, String path)
|
||||
{
|
||||
super(stage, id, targetMap, x, y, w, h, direction, currentMap, portalTargetObject);
|
||||
load(path);
|
||||
}
|
||||
|
||||
public MapStage getMapStage()
|
||||
{
|
||||
return stage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCollide()
|
||||
{
|
||||
if(currentAnimationType == PortalAnimationTypes.Inactive) {
|
||||
//Activate portal? Launch Dialog?
|
||||
}
|
||||
if(currentAnimationType == PortalAnimationTypes.Active) {
|
||||
if (targetMap == null || targetMap.isEmpty()) {
|
||||
stage.exitDungeon();
|
||||
} else {
|
||||
if (targetMap.equals(currentMap))
|
||||
{
|
||||
stage.spawn(entryTargetObject);
|
||||
stage.getPlayerSprite().playEffect(Paths.EFFECT_TELEPORT, 0.5f);
|
||||
stage.startPause(1.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentMap = targetMap;
|
||||
TileMapScene.instance().loadNext(targetMap, entryTargetObject);
|
||||
stage.getPlayerSprite().playEffect(Paths.EFFECT_TELEPORT, 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void spawn() {
|
||||
switch(direction)
|
||||
{
|
||||
case "up":
|
||||
stage.getPlayerSprite().setPosition(x+w/2-stage.getPlayerSprite().getWidth()/2,y+h);
|
||||
break;
|
||||
case "down":
|
||||
stage.getPlayerSprite().setPosition(x+w/2-stage.getPlayerSprite().getWidth()/2,y-stage.getPlayerSprite().getHeight());
|
||||
break;
|
||||
case "right":
|
||||
stage.getPlayerSprite().setPosition(x-stage.getPlayerSprite().getWidth(),y+h/2-stage.getPlayerSprite().getHeight()/2);
|
||||
break;
|
||||
case "left":
|
||||
stage.getPlayerSprite().setPosition(x+w,y+h/2-stage.getPlayerSprite().getHeight()/2);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void load(String path) {
|
||||
if(path==null||path.isEmpty())return;
|
||||
TextureAtlas atlas = Config.instance().getAtlas(path);
|
||||
animations.clear();
|
||||
for (PortalAnimationTypes stand : PortalAnimationTypes.values()) {
|
||||
Array<Sprite> anim = atlas.createSprites(stand.toString());
|
||||
if (anim.size != 0) {
|
||||
animations.put(stand, new Animation<>(0.2f, anim));
|
||||
if(getWidth()==0.0)//init size onload
|
||||
{
|
||||
setWidth(anim.first().getWidth());
|
||||
setHeight(anim.first().getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setAnimation(PortalAnimationTypes.Closed);
|
||||
updateAnimation();
|
||||
}
|
||||
|
||||
public void setAnimation(PortalAnimationTypes type) {
|
||||
if (currentAnimationType != type) {
|
||||
currentAnimationType = type;
|
||||
updateAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
public void setAnimation(String typeName) {
|
||||
switch(typeName.toLowerCase()){
|
||||
case "active":
|
||||
setAnimation(PortalAnimationTypes.Active);
|
||||
break;
|
||||
case "inactive":
|
||||
setAnimation(PortalAnimationTypes.Inactive);
|
||||
break;
|
||||
case "closed":
|
||||
setAnimation(PortalAnimationTypes.Closed);
|
||||
break;
|
||||
case "opening":
|
||||
setAnimation(PortalAnimationTypes.Opening);
|
||||
break;
|
||||
case "closing":
|
||||
setAnimation(PortalAnimationTypes.Closing);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAnimation() {
|
||||
PortalAnimationTypes aniType = currentAnimationType;
|
||||
if (!animations.containsKey(aniType)) {
|
||||
aniType = PortalAnimationTypes.Inactive;
|
||||
}
|
||||
if (!animations.containsKey(aniType)) {
|
||||
return;
|
||||
}
|
||||
currentAnimation = animations.get(aniType);
|
||||
}
|
||||
|
||||
public enum PortalAnimationTypes {
|
||||
Closed,
|
||||
Active,
|
||||
Inactive,
|
||||
Opening,
|
||||
Closing
|
||||
}
|
||||
|
||||
public void act(float delta) {
|
||||
timer += delta;
|
||||
super.act(delta);
|
||||
}
|
||||
|
||||
public void draw(Batch batch, float parentAlpha) {
|
||||
if (currentAnimation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
super.draw(batch,parentAlpha);
|
||||
beforeDraw(batch,parentAlpha);
|
||||
|
||||
TextureRegion currentFrame;
|
||||
if (currentAnimationType.equals(PortalAnimationTypes.Opening) || currentAnimationType.equals(PortalAnimationTypes.Closing))
|
||||
{
|
||||
currentFrame = currentAnimation.getKeyFrame(transitionTimer, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentFrame = currentAnimation.getKeyFrame(timer, true);
|
||||
}
|
||||
|
||||
setHeight(currentFrame.getRegionHeight());
|
||||
setWidth(currentFrame.getRegionWidth());
|
||||
Color oldColor=batch.getColor().cpy();
|
||||
batch.setColor(getColor());
|
||||
batch.draw(currentFrame, getX(), getY(), getWidth(), getHeight());
|
||||
batch.setColor(oldColor);
|
||||
super.draw(batch,parentAlpha);
|
||||
//batch.draw(getDebugTexture(),getX(),getY());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ public class DialogData implements Serializable {
|
||||
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 activateMapObject = 0; //Remove inactive state from ID.
|
||||
public int battleWithActorID = 0; //Start a battle with enemy ID. -1 for self if possible.
|
||||
public EffectData giveBlessing; //Give a blessing to the player.
|
||||
public String setColorIdentity; //Change player's color identity.
|
||||
@@ -77,6 +78,7 @@ public class DialogData implements Serializable {
|
||||
addLife = other.addLife;
|
||||
addGold = other.addGold;
|
||||
deleteMapObject = other.deleteMapObject;
|
||||
activateMapObject = other.activateMapObject;
|
||||
battleWithActorID = other.battleWithActorID;
|
||||
giveBlessing = other.giveBlessing;
|
||||
setColorIdentity = other.setColorIdentity;
|
||||
|
||||
@@ -23,6 +23,7 @@ public class TileMapScene extends HudScene {
|
||||
TiledMap map;
|
||||
PointOfInterestMapRenderer tiledMapRenderer;
|
||||
private String nextMap;
|
||||
private int nextSpawnPoint;
|
||||
private boolean autoheal = false;
|
||||
|
||||
private TileMapScene() {
|
||||
@@ -56,8 +57,9 @@ public class TileMapScene extends HudScene {
|
||||
if (map == null)
|
||||
return;
|
||||
if (nextMap != null) {
|
||||
load(nextMap);
|
||||
load(nextMap, nextSpawnPoint);
|
||||
nextMap = null;
|
||||
nextSpawnPoint = 0;
|
||||
}
|
||||
stage.act(Gdx.graphics.getDeltaTime());
|
||||
hud.act(Gdx.graphics.getDeltaTime());
|
||||
@@ -108,7 +110,7 @@ public class TileMapScene extends HudScene {
|
||||
((MapStage) stage).setPointOfInterest(WorldSave.getCurrentSave().getPointOfInterestChanges(point.getID() + oldMap));
|
||||
stage.getPlayerSprite().setPosition(0, 0);
|
||||
WorldSave.getCurrentSave().getWorld().setSeed(point.getSeedOffset());
|
||||
tiledMapRenderer.loadMap(map, "");
|
||||
tiledMapRenderer.loadMap(map, "", oldMap,0);
|
||||
stage.getPlayerSprite().stop();
|
||||
}
|
||||
|
||||
@@ -120,12 +122,12 @@ public class TileMapScene extends HudScene {
|
||||
public PointOfInterest rootPoint;
|
||||
String oldMap;
|
||||
|
||||
private void load(String targetMap) {
|
||||
private void load(String targetMap, int nextSpawnPoint) {
|
||||
map = new TemplateTmxMapLoader().load(Config.instance().getFilePath(targetMap));
|
||||
((MapStage) stage).setPointOfInterest(WorldSave.getCurrentSave().getPointOfInterestChanges(rootPoint.getID() + targetMap));
|
||||
stage.getPlayerSprite().setPosition(0, 0);
|
||||
WorldSave.getCurrentSave().getWorld().setSeed(rootPoint.getSeedOffset());
|
||||
tiledMapRenderer.loadMap(map, oldMap);
|
||||
tiledMapRenderer.loadMap(map, oldMap, targetMap, nextSpawnPoint);
|
||||
oldMap = targetMap;
|
||||
stage.getPlayerSprite().stop();
|
||||
}
|
||||
@@ -136,8 +138,9 @@ public class TileMapScene extends HudScene {
|
||||
return MapStage.getInstance().getDialogOnlyInput();
|
||||
}
|
||||
|
||||
public void loadNext(String targetMap) {
|
||||
public void loadNext(String targetMap, int entryTargetObject) {
|
||||
nextMap = targetMap;
|
||||
nextSpawnPoint = entryTargetObject;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -163,32 +163,6 @@ public class MapStage extends GameStage {
|
||||
return false;
|
||||
}
|
||||
|
||||
public float lengthWithoutCollision(EnemySprite mob, Vector2 end) {
|
||||
Vector2 start = mob.pos();
|
||||
Vector2 safeVector = start.cpy().add(end);
|
||||
|
||||
int segmentsToCheck = 100;
|
||||
float safeLen = safeVector.len();
|
||||
float partialLength = safeLen / segmentsToCheck;
|
||||
|
||||
for (Rectangle collision : collisionRect) {
|
||||
float uncollidedLen = 0.0f;
|
||||
while (uncollidedLen < safeLen) {
|
||||
Rectangle mRect = new Rectangle(mob.navigationBoundingRect());
|
||||
Vector2 testVector = new Vector2(end).setLength(uncollidedLen + partialLength);
|
||||
mRect.setPosition(mRect.x + testVector.x, mRect.y + testVector.y);
|
||||
if (mRect.overlaps(collision)) {
|
||||
break;
|
||||
}
|
||||
uncollidedLen += partialLength;
|
||||
}
|
||||
safeLen = Math.min(safeLen, uncollidedLen);
|
||||
}
|
||||
|
||||
return safeLen;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void prepareCollision(Vector2 pos, Vector2 direction, Rectangle boundingRect) {
|
||||
|
||||
@@ -330,7 +304,11 @@ public class MapStage extends GameStage {
|
||||
Array<EntryActor> spawnClassified = new Array<>();
|
||||
Array<EntryActor> sourceMapMatch = new Array<>();
|
||||
|
||||
public void loadMap(TiledMap map, String sourceMap) {
|
||||
public void loadMap(TiledMap map, String sourceMap, String targetMap) {
|
||||
loadMap(map, sourceMap, targetMap, 0);
|
||||
}
|
||||
|
||||
public void loadMap(TiledMap map, String sourceMap, String targetMap, int spawnTargetId) {
|
||||
isLoadingMatch = false;
|
||||
isInMap = true;
|
||||
GameHUD.getInstance().showHideMap(false);
|
||||
@@ -339,7 +317,7 @@ public class MapStage extends GameStage {
|
||||
actor.remove();
|
||||
foregroundSprites.removeActor(actor);
|
||||
}
|
||||
|
||||
positions.clear();
|
||||
actors.clear();
|
||||
collisionRect.clear();
|
||||
|
||||
@@ -390,15 +368,10 @@ public class MapStage extends GameStage {
|
||||
if (layer instanceof TiledMapTileLayer) {
|
||||
loadCollision((TiledMapTileLayer) layer);
|
||||
} else {
|
||||
loadObjects(layer, sourceMap);
|
||||
loadObjects(layer, sourceMap, targetMap);
|
||||
}
|
||||
}
|
||||
if (!spawnClassified.isEmpty())
|
||||
spawnClassified.first().spawn();
|
||||
else if (!sourceMapMatch.isEmpty())
|
||||
sourceMapMatch.first().spawn();
|
||||
else if (!otherEntries.isEmpty())
|
||||
otherEntries.first().spawn();
|
||||
spawn(spawnTargetId);
|
||||
|
||||
//reduce geometry in collision rectangles
|
||||
int oldSize;
|
||||
@@ -433,6 +406,28 @@ public class MapStage extends GameStage {
|
||||
getPlayerSprite().stop();
|
||||
}
|
||||
|
||||
public void spawn(int targetId){
|
||||
boolean hasSpawned = false;
|
||||
if (targetId > 0){
|
||||
for (int i = 0; i < actors.size; i++) {
|
||||
if (actors.get(i).getObjectId() == targetId) {
|
||||
if (actors.get(i) instanceof EntryActor) {
|
||||
((EntryActor)(actors.get(i))).spawn();
|
||||
hasSpawned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasSpawned){
|
||||
if (!spawnClassified.isEmpty())
|
||||
spawnClassified.first().spawn();
|
||||
else if (!sourceMapMatch.isEmpty())
|
||||
sourceMapMatch.first().spawn();
|
||||
else if (!otherEntries.isEmpty())
|
||||
otherEntries.first().spawn();
|
||||
}
|
||||
}
|
||||
|
||||
void replaceWaypoints() {
|
||||
for (EnemySprite enemy : enemies) {
|
||||
for (EnemySprite.MovementBehavior behavior : enemy.movementBehaviors) {
|
||||
@@ -479,7 +474,7 @@ public class MapStage extends GameStage {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void loadObjects(MapLayer layer, String sourceMap) {
|
||||
private void loadObjects(MapLayer layer, String sourceMap, String currentMap) {
|
||||
player.setMoveModifier(2);
|
||||
Array<String> shopsAlreadyPresent = new Array<>();
|
||||
for (MapObject obj : layer.getObjects()) {
|
||||
@@ -489,6 +484,7 @@ public class MapStage extends GameStage {
|
||||
int id = prop.get("id", int.class);
|
||||
if (changes.isObjectDeleted(id))
|
||||
continue;
|
||||
|
||||
boolean hidden = !obj.isVisible(); //Check if the object is invisible.
|
||||
|
||||
String rotatingShop = "";
|
||||
@@ -511,19 +507,51 @@ public class MapStage extends GameStage {
|
||||
float h = Float.parseFloat(prop.get("height").toString());
|
||||
|
||||
String targetMap = prop.get("teleport").toString();
|
||||
boolean spawnPlayerThere = (targetMap == null || targetMap.isEmpty() && sourceMap.isEmpty()) ||//if target is null and "from world"
|
||||
boolean canStillSpawnPlayerThere = (targetMap == null || targetMap.isEmpty() && sourceMap.isEmpty()) ||//if target is null and "from world"
|
||||
!sourceMap.isEmpty() && targetMap.equals(sourceMap);
|
||||
|
||||
EntryActor entry = new EntryActor(this, id, prop.get("teleport").toString(), x, y, w, h, prop.get("direction").toString());
|
||||
if ((prop.containsKey("spawn") && prop.get("spawn").toString().equals("true")) && spawnPlayerThere) {
|
||||
int entryTargetId = (!prop.containsKey("teleportObjectId") || prop.get("teleportObjectId") ==null || prop.get("teleportObjectId").toString().isEmpty())? 0: Integer.parseInt(prop.get("teleportObjectId").toString());
|
||||
|
||||
EntryActor entry = new EntryActor(this, id, prop.get("teleport").toString(), x, y, w, h, prop.get("direction").toString(), currentMap, entryTargetId);
|
||||
if (prop.containsKey("spawn") && prop.get("spawn").toString().equals("true")) {
|
||||
spawnClassified.add(entry);
|
||||
} else if (spawnPlayerThere) {
|
||||
} else if (canStillSpawnPlayerThere) {
|
||||
sourceMapMatch.add(entry);
|
||||
} else {
|
||||
otherEntries.add(entry);
|
||||
}
|
||||
addMapActor(obj, entry);
|
||||
break;
|
||||
case "portal":
|
||||
float px = Float.parseFloat(prop.get("x").toString());
|
||||
float py = Float.parseFloat(prop.get("y").toString());
|
||||
float pw = Float.parseFloat(prop.get("width").toString());
|
||||
float ph = Float.parseFloat(prop.get("height").toString());
|
||||
|
||||
Object portalSpriteProvided = prop.get("sprite");
|
||||
String portalSpriteToUse;
|
||||
portalSpriteToUse = "sprites/portal.atlas";
|
||||
if (portalSpriteProvided != null && !portalSpriteProvided.toString().isEmpty()) portalSpriteToUse = portalSpriteProvided.toString();
|
||||
else
|
||||
System.err.printf("No sprite defined for portal (ID:%s), defaulting to \"sprites/portal.atlas\"", id);
|
||||
|
||||
String portalTargetMap = prop.get("teleport").toString();
|
||||
boolean validSpawnPoint = (portalTargetMap == null || portalTargetMap.isEmpty() && sourceMap.isEmpty()) ||//if target is null and "from world"
|
||||
!sourceMap.isEmpty() && portalTargetMap.equals(sourceMap);
|
||||
|
||||
int portalTargetId = (!prop.containsKey("teleportObjectId") || prop.get("teleportObjectId") ==null || prop.get("teleportObjectId").toString().isEmpty())? 0: Integer.parseInt(prop.get("teleportObjectId").toString());
|
||||
|
||||
PortalActor portal = new PortalActor(this, id, prop.get("teleport").toString(), px, py, pw, ph, prop.get("direction").toString(), currentMap, portalTargetId, portalSpriteToUse);
|
||||
portal.setAnimation(prop.get("portalState").toString());
|
||||
if (prop.containsKey("spawn") && prop.get("spawn").toString().equals("true")) {
|
||||
spawnClassified.add(portal);
|
||||
} else if (validSpawnPoint) {
|
||||
sourceMapMatch.add(portal);
|
||||
} else {
|
||||
otherEntries.add(portal);
|
||||
}
|
||||
addMapActor(obj, portal);
|
||||
break;
|
||||
case "reward":
|
||||
if (!canSpawn(prop)) break;
|
||||
Object R = prop.get("reward");
|
||||
@@ -577,13 +605,30 @@ public class MapStage extends GameStage {
|
||||
{
|
||||
mob.threatRange = Float.parseFloat(prop.get("threatRange").toString());
|
||||
}
|
||||
if (prop.containsKey("threatRange")) //Check for threat range.
|
||||
{
|
||||
mob.pursueRange = Float.parseFloat(prop.get("pursueRange").toString());
|
||||
}
|
||||
if (prop.containsKey("fleeRange")) //Check for flee range.
|
||||
{
|
||||
mob.fleeRange = Float.parseFloat(prop.get("fleeRange").toString());
|
||||
}
|
||||
if (prop.containsKey("speed")) //Check for flee range.
|
||||
{
|
||||
mob.getData().speed = Float.parseFloat(prop.get("speed").toString());
|
||||
}
|
||||
if (prop.containsKey("flying"))
|
||||
{
|
||||
mob.getData().flying = Boolean.parseBoolean(prop.get("flying").toString());
|
||||
}
|
||||
if (prop.containsKey("hidden"))
|
||||
{
|
||||
mob.hidden = Boolean.parseBoolean(prop.get("hidden").toString());
|
||||
hidden = Boolean.parseBoolean(prop.get("hidden").toString());
|
||||
}
|
||||
if (prop.containsKey("inactive"))
|
||||
{
|
||||
mob.inactive = Boolean.parseBoolean(prop.get("inactive").toString());
|
||||
if (mob.inactive) mob.clearCollisionHeight();
|
||||
}
|
||||
if (hidden){
|
||||
mob.hidden = hidden; //Evil.
|
||||
@@ -601,6 +646,9 @@ public class MapStage extends GameStage {
|
||||
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);
|
||||
if (prop.containsKey("hidden")){
|
||||
D.setVisible(!Boolean.parseBoolean(prop.get("hidden").toString()));
|
||||
}
|
||||
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).
|
||||
@@ -642,8 +690,10 @@ public class MapStage extends GameStage {
|
||||
DialogActor dialog;
|
||||
if (prop.containsKey("sprite"))
|
||||
dialog = new DialogActor(this, id, prop.get("dialog").toString(), prop.get("sprite").toString());
|
||||
else
|
||||
else {
|
||||
dialog = new DialogActor(this, id, prop.get("dialog").toString(), tiledObj.getTextureRegion());
|
||||
dialog.setVisible(false);
|
||||
}
|
||||
addMapActor(obj, dialog);
|
||||
}
|
||||
break;
|
||||
@@ -780,6 +830,7 @@ public class MapStage extends GameStage {
|
||||
}
|
||||
|
||||
public boolean exitDungeon() {
|
||||
WorldSave.getCurrentSave().autoSave();
|
||||
AdventureQuestController.instance().updateQuestsLeave();
|
||||
AdventureQuestController.instance().showQuestDialogs(this);
|
||||
isLoadingMatch = false;
|
||||
@@ -876,6 +927,22 @@ public class MapStage extends GameStage {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean activateMapObject(int id){
|
||||
if (changes.isObjectDeleted(id)){
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < actors.size; i++) {
|
||||
if (actors.get(i).getObjectId() == id && id > 0) {
|
||||
if (actors.get(i) instanceof EnemySprite) {
|
||||
((EnemySprite)(actors.get(i))).inactive = false;
|
||||
(actors.get(i)).resetCollisionHeight();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean lookForID(int id) { //Search actor by ID.
|
||||
|
||||
for (MapActor A : new Array.ArrayIterator<>(actors)) {
|
||||
@@ -928,6 +995,8 @@ public class MapStage extends GameStage {
|
||||
for (Integer i : idsToRemove) deleteObject(i);
|
||||
}
|
||||
|
||||
final Rectangle tempBoundingRect = new Rectangle();
|
||||
|
||||
@Override
|
||||
protected void onActing(float delta) {
|
||||
if (isPaused() || isDialogOnlyInput())
|
||||
@@ -942,6 +1011,9 @@ public class MapStage extends GameStage {
|
||||
if (!matchJustEnded) {
|
||||
while (it.hasNext()) {
|
||||
EnemySprite mob = it.next();
|
||||
if (mob.inactive){
|
||||
continue;
|
||||
}
|
||||
mob.updatePositon();
|
||||
mob.targetVector = mob.getTargetVector(player, delta);
|
||||
Vector2 currentVector = new Vector2(mob.targetVector);
|
||||
@@ -951,29 +1023,33 @@ public class MapStage extends GameStage {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mob.getData().flying)//if direct path is not possible
|
||||
{
|
||||
//Todo: fix below for collision logic
|
||||
float safeLen = lengthWithoutCollision(mob, mob.targetVector);
|
||||
if (safeLen > 0.1f) {
|
||||
currentVector.setLength(Math.min(safeLen, mob.targetVector.len()));
|
||||
} else {
|
||||
currentVector = Vector2.Zero;
|
||||
}
|
||||
}
|
||||
currentVector.setLength(Math.min(mob.speed() * delta, mob.targetVector.len()));
|
||||
mob.moveBy(currentVector.x, currentVector.y,delta);
|
||||
|
||||
tempBoundingRect.set(mob.getX() + currentVector.x, mob.getY() + currentVector.y, mob.getWidth() * 0.4f, mob.getHeight() * 0.4f);
|
||||
|
||||
if (!mob.getData().flying && isColliding(tempBoundingRect))//if direct path is not possible
|
||||
{
|
||||
currentVector = adjustMovement(currentVector,tempBoundingRect);
|
||||
tempBoundingRect.set(mob.getX() + currentVector.x, mob.getY(), mob.getWidth() * 0.4f, mob.getHeight() * 0.4f);
|
||||
if (isColliding(tempBoundingRect))//if only x path is not possible
|
||||
{
|
||||
tempBoundingRect.set(mob.getX(), mob.getY() + currentVector.y, mob.getWidth() * 0.4f, mob.getHeight() * 0.4f);
|
||||
if (!isColliding(tempBoundingRect))//if y path is possible
|
||||
{
|
||||
mob.moveBy(0, currentVector.y, delta);
|
||||
}
|
||||
} else {
|
||||
mob.moveBy(currentVector.x, 0, delta);
|
||||
}
|
||||
} else {
|
||||
mob.moveBy(currentVector.x, currentVector.y, delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float sprintingMod = currentModifications.containsKey(PlayerModification.Sprint) ? 2 : 1;
|
||||
player.setMoveModifier(2 * sprintingMod);
|
||||
|
||||
// oldPosition4.set(oldPosition3);
|
||||
// oldPosition3.set(oldPosition2);
|
||||
// oldPosition2.set(oldPosition);
|
||||
// oldPosition.set(player.pos());
|
||||
|
||||
positions.add(player.pos());
|
||||
if (positions.size() > 4)
|
||||
positions.remove();
|
||||
|
||||
@@ -31,8 +31,8 @@ public class PointOfInterestMapRenderer extends OrthogonalTiledMapRendererBleedi
|
||||
endRender();
|
||||
}
|
||||
|
||||
public void loadMap(TiledMap map, String sourceMap) {
|
||||
stage.loadMap(map, sourceMap);
|
||||
public void loadMap(TiledMap map, String sourceMap, String targetMap, int spawnPoint) {
|
||||
stage.loadMap(map, sourceMap, targetMap, spawnPoint);
|
||||
|
||||
super.setMap(map);
|
||||
}
|
||||
|
||||
@@ -201,6 +201,7 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
WorldSave.getCurrentSave().autoSave();
|
||||
TileMapScene.instance().load(point.getPointOfInterest());
|
||||
stop();
|
||||
Forge.switchScene(TileMapScene.instance());
|
||||
|
||||
@@ -275,12 +275,15 @@ public class MapDialog {
|
||||
GameHUD.getInstance().fadeOut();
|
||||
}
|
||||
|
||||
public void activate() { //Method for actors to show their dialogues.
|
||||
public boolean activate() { //Method for actors to show their dialogues.
|
||||
boolean dialogShown = false;
|
||||
for (DialogData dialog : data) {
|
||||
if (isConditionOk(dialog.condition)) {
|
||||
loadDialog(dialog);
|
||||
dialogShown = true;
|
||||
}
|
||||
}
|
||||
return dialogShown;
|
||||
}
|
||||
|
||||
void setEffects(DialogData.ActionData[] data) {
|
||||
@@ -315,6 +318,9 @@ public class MapDialog {
|
||||
if (E.deleteMapObject < 0) stage.deleteObject(parentID);
|
||||
else stage.deleteObject(E.deleteMapObject);
|
||||
}
|
||||
if (E.activateMapObject != 0){
|
||||
stage.activateMapObject(E.activateMapObject);
|
||||
}
|
||||
if (E.battleWithActorID != 0) { //Starts a battle with the given enemy ID.
|
||||
if (E.battleWithActorID < 0) stage.beginDuel(stage.getEnemyByID(parentID));
|
||||
else stage.beginDuel(stage.getEnemyByID(E.battleWithActorID));
|
||||
|
||||
Reference in New Issue
Block a user