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:
jjayers99
2023-05-10 23:55:55 -04:00
parent fbf401cb55
commit f5e062d06d
96 changed files with 10403 additions and 873 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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();
}
}
}

View File

@@ -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());
}
}

View File

@@ -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);
}
}
}

View 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());
}
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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());

View File

@@ -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));