Skip to content

Commit 9b05375

Browse files
committed
Speed up hostile NPC animations if they are faster than player
* Refresh mouse tooltip & ranged attack path when NPC is killed by player
1 parent af4d649 commit 9b05375

File tree

11 files changed

+87
-64
lines changed

11 files changed

+87
-64
lines changed

README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22
### Open-world sandbox roguelike
33
### <a href="https://github.com/Hitonoriol/MadSand/releases/download/launcher/MadSandLauncher.jar">Download Launcher</a>
44
### <a href="https://github.com/Hitonoriol/MadSand/wiki">Wiki</a>
5+
<br>
56

6-
7-
### Dependencies
7+
### How to build
8+
#### Game
9+
<pre>
10+
./gradlew desktop:dist
11+
</pre>
12+
--> desktop/build/libs/MadSand-\<VERSION\>.jar
13+
<br><br>
14+
#### Launcher/Auto-updater
815
<pre>
9-
libgdx
10-
commons-lang
11-
jackson-annotations
12-
jackson-core
13-
jackson-databind
16+
./gradlew launcher:dist
1417
</pre>
18+
--> launcher/build/libs/MadSandLauncher-\<VERSION\>.jar
19+
<br><br>
1520
### Screenshots
1621
![screenshot](https://raw.githubusercontent.com/Hitonoriol/MadSand/master/screenshots/title%20screen.png)
1722
![screenshot](https://raw.githubusercontent.com/Hitonoriol/MadSand/master/screenshots/big%20dungeon%20room.png)

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
allprojects {
22
apply plugin: "eclipse"
33

4-
version = 'v0.49.5a-rc3'
4+
version = 'v0.49.5a-rc4'
55

66
ext {
77
appName = "MadSand"

core/src/hitonoriol/madsand/GameSaver.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ public static String readFile(String name) {
112112
return readFile(name, false);
113113
}
114114

115-
public static String getProdStationFile(int wx, int wy, int layer) {
116-
return getCurSaveDir() + "productionstations" + getSectorString(wx, wy, layer)
115+
public static String getItemFactoryFile(int wx, int wy, int layer) {
116+
return getCurSaveDir() + "itemfactories" + getSectorString(wx, wy, layer)
117117
+ MadSand.SAVE_EXT;
118118
}
119119

@@ -197,7 +197,6 @@ public static void loadErrMsg() {
197197
"Couldn't to load this world. \n"
198198
+ "Maybe it was saved in older/newer version of the game or some files are corrupted.\n"
199199
+ "Check " + Resources.ERR_FILE + " for details.");
200-
// MadSand.justStarted = false;
201200
}
202201

203202
public static boolean verifyNextSector(int x, int y) {

core/src/hitonoriol/madsand/entities/Entity.java

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
import com.badlogic.gdx.graphics.g2d.Sprite;
1414
import com.badlogic.gdx.graphics.g2d.TextureRegion;
1515
import com.fasterxml.jackson.annotation.JsonAutoDetect;
16-
import com.fasterxml.jackson.annotation.JsonIgnore;
1716
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
17+
import com.fasterxml.jackson.annotation.JsonIgnore;
1818

1919
import hitonoriol.madsand.MadSand;
2020
import hitonoriol.madsand.Resources;
@@ -41,12 +41,7 @@ public abstract class Entity extends MapEntity {
4141
@JsonIgnore
4242
private Sprite upSpr, downSpr, leftSpr, rightSpr;
4343

44-
public static Comparator<Entity> speedComparator = new Comparator<Entity>() {
45-
@Override
46-
public int compare(Entity o1, Entity o2) {
47-
return Double.compare(o2.getSpeed(), o1.getSpeed());
48-
}
49-
};
44+
public static final Comparator<Entity> speedComparator = (e1, e2) -> Double.compare(e2.getSpeed(), e1.getSpeed());
5045

5146
@JsonIgnore
5247
private Sprite sprite;
@@ -72,7 +67,8 @@ public int compare(Entity o1, Entity o2) {
7267
@JsonIgnore
7368
public float stepx = MadSand.TILESIZE;
7469

75-
boolean moving = false;
70+
protected boolean moving = false, hasMoved = false;
71+
protected boolean running = false;
7672

7773
public Entity(String name) {
7874
stats = isPlayer() ? new PlayerStats() : new Stats();
@@ -142,8 +138,9 @@ public float getActDelay() {
142138
return actDelay;
143139
}
144140

145-
public void resetActDelay() {
141+
public void prepareToAct() {
146142
actDelay = 0;
143+
hasMoved = false;
147144
}
148145

149146
public boolean hasActDelay() {
@@ -442,6 +439,19 @@ public void calcMovementSpeed() {
442439
movementSpeed = speed / 17f + (float) Math.pow(Math.sqrt(speed), 1.225f) * 1.075f;
443440
}
444441

442+
public void speedUp(float by) {
443+
movementSpeed *= by;
444+
running = true;
445+
}
446+
447+
public void stopRunning() {
448+
if (!running)
449+
return;
450+
451+
calcMovementSpeed();
452+
running = false;
453+
}
454+
445455
@JsonIgnore
446456
public PairFloat getWorldPos() {
447457
if (!isMoving())
@@ -461,12 +471,17 @@ else if (stats.look == Direction.UP)
461471
return worldPos;
462472
}
463473

474+
public boolean hasMoved() {
475+
return hasMoved;
476+
}
477+
464478
public boolean isMoving() {
465479
return moving;
466480
}
467481

468482
public void setMoving(boolean val) {
469-
moving = val;
483+
if (moving = val)
484+
hasMoved = true;
470485
}
471486

472487
public void queueMovement(Direction dir) {
@@ -485,6 +500,9 @@ protected void pollMovementQueue() {
485500
public void stopMovement() {
486501
moving = false;
487502
stepx = stepy = MadSand.TILESIZE;
503+
if (!hasQueuedMovement())
504+
stopRunning();
505+
488506
pollMovementQueue();
489507
}
490508

@@ -520,7 +538,7 @@ public boolean move(Direction dir) {
520538
++x;
521539
globalPos.x += MadSand.TILESIZE;
522540
}
523-
moving = true;
541+
setMoving(true);
524542
return true;
525543
}
526544
return false;

core/src/hitonoriol/madsand/entities/Player.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import hitonoriol.madsand.gui.dialogs.WaitDialog;
6161
import hitonoriol.madsand.gui.widgets.ResourceProgressBar;
6262
import hitonoriol.madsand.input.Keyboard;
63+
import hitonoriol.madsand.input.Mouse;
6364
import hitonoriol.madsand.lua.Lua;
6465
import hitonoriol.madsand.map.FishingSpot;
6566
import hitonoriol.madsand.map.Loot;
@@ -84,7 +85,6 @@ public class Player extends Entity {
8485
public PlayerStats stats; // Reference to the same Stats object as super.stats
8586
float elapsedTime; // TODO: move to AnimationContainer
8687
private float runSpeedCoef = 3.5f;
87-
private boolean running = false;
8888

8989
private int targetedByNpcs = 0;
9090
private Set<Integer> unlockedItems = new HashSet<>(); // set of items player obtained at least once
@@ -357,6 +357,7 @@ private void attack(AbstractNpc npc, int dmg) {
357357
}
358358

359359
if (npc.stats.dead) {
360+
Mouse.refreshTooltip();
360361
MadSand.notice("You kill " + npc.stats.name + "! [+" + npc.rewardExp + " exp]");
361362
addExp(npc.rewardExp);
362363
reputation.change(npc.stats.faction, Reputation.KILL_PENALTY);
@@ -1178,21 +1179,14 @@ public boolean walk(Direction dir) {
11781179

11791180
@Override
11801181
public void stopMovement() {
1181-
if (!hasQueuedMovement()) {
1182+
if (!hasQueuedMovement())
11821183
Keyboard.resumeInput();
1183-
if (running) {
1184-
Utils.dbg("Stopped running");
1185-
running = false;
1186-
calcMovementSpeed();
1187-
}
1188-
}
11891184

11901185
super.stopMovement();
11911186
}
11921187

11931188
public void run(Path path) {
1194-
movementSpeed *= runSpeedCoef;
1195-
running = true;
1189+
speedUp(runSpeedCoef);
11961190
super.move(path);
11971191
}
11981192

core/src/hitonoriol/madsand/entities/npc/AbstractNpc.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public abstract class AbstractNpc extends Entity {
3838
public static int NULL_NPC = 0;
3939
static double IDLE_MOVE_CHANCE = 15;
4040
static float MAX_FOV_COEF = 1.5f;
41+
public static final float HOSTILE_SPEEDUP = 1.35f;
4142

4243
public int id;
4344
public long uid;
@@ -59,7 +60,9 @@ public abstract class AbstractNpc extends Entity {
5960

6061
public State state = State.Idle;
6162

63+
@JsonIgnore
6264
Path path = new Path();
65+
@JsonIgnore
6366
Pair prevDestination = new Pair();
6467
int pathIdx = 0;
6568

core/src/hitonoriol/madsand/input/Mouse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,12 @@ public static void updCoords() {
128128

129129
cellInfo.set(wx, wy);
130130
pointingAtObject = cellInfo.isCellOccupied();
131-
highlightRangedTarget();
132131
refreshTooltip();
133132
}
134133

135134
public static void refreshTooltip() {
136135
Gui.overlay.getTooltip().setText(cellInfo.getInfo());
136+
highlightRangedTarget();
137137
}
138138

139139
private static void refreshPathToCursor() {

core/src/hitonoriol/madsand/map/CellInfo.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public MapObject getObject() {
9090
}
9191

9292
public String getInfo() {
93+
refresh();
9394
infoBuilder.setLength(0);
9495
infoBuilder.append("Looking at (" + x + ", " + y + ")").append(NEWLINE);
9596

core/src/hitonoriol/madsand/map/Map.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public class Map {
7474
private HashMap<Pair, Loot> mapLoot;
7575
private HashMap<Pair, Crop> mapCrops;
7676
private HashMap<Pair, AbstractNpc> mapNpcs;
77-
private ArrayList<Pair> mapProductionStations;
77+
private ArrayList<Pair> mapItemFactories;
7878

7979
IndexedAStarPathFinder<Node> pathFinder;
8080
Graph graph;
@@ -192,24 +192,24 @@ public void rollSize() {
192192
}
193193

194194
@JsonIgnore
195-
public HashMap<Pair, ItemProducer> getMapProductionStations() {
196-
HashMap<Pair, ItemProducer> prodStations = new HashMap<>();
195+
public HashMap<Pair, ItemProducer> getMapItemFactories() {
196+
HashMap<Pair, ItemProducer> itemFactories = new HashMap<>();
197197

198-
for (Pair coords : mapProductionStations)
198+
for (Pair coords : mapItemFactories)
199199
getObject(coords).as(ItemFactory.class)
200-
.ifPresent(itemfactory -> prodStations.put(coords, itemfactory.getItemProducer()));
200+
.ifPresent(factory -> itemFactories.put(coords, factory.getItemProducer()));
201201

202-
return prodStations;
202+
return itemFactories;
203203
}
204204

205-
public void setMapProductionStations(HashMap<Pair, ItemProducer> productionStations) {
206-
mapProductionStations.clear();
207-
for (Entry<Pair, ItemProducer> entry : productionStations.entrySet()) {
205+
public void setMapItemFactories(HashMap<Pair, ItemProducer> itemFactories) {
206+
mapItemFactories.clear();
207+
for (Entry<Pair, ItemProducer> entry : itemFactories.entrySet()) {
208208
Pair coords = entry.getKey();
209209
getObject(coords).as(ItemFactory.class)
210210
.ifPresent(itemFactory -> {
211211
itemFactory.setItemProducer(entry.getValue());
212-
mapProductionStations.add(coords);
212+
mapItemFactories.add(coords);
213213
});
214214

215215
}
@@ -359,7 +359,7 @@ public Map purge() {
359359
mapLoot = new HashMap<>();
360360
mapNpcs = new HashMap<>();
361361
mapCrops = new HashMap<>();
362-
mapProductionStations = new ArrayList<>();
362+
mapItemFactories = new ArrayList<>();
363363

364364
graph = new Graph();
365365
nodeMap = new NodeMap(graph, xsz, ysz);
@@ -712,7 +712,7 @@ public boolean addObject(int x, int y, int id, boolean force) {
712712
setObjectSize(x, y, id);
713713

714714
object.as(ItemFactory.class)
715-
.ifPresent(itemFactory -> mapProductionStations.add(coords));
715+
.ifPresent(itemFactory -> mapItemFactories.add(coords));
716716

717717
if (graph.getNodeCount() > 0) {
718718
if (!object.nocollide) {
@@ -1076,7 +1076,7 @@ public boolean removeNpc(int x, int y) {
10761076
}
10771077

10781078
public void updateProductionStations() {
1079-
for (Pair coords : mapProductionStations)
1079+
for (Pair coords : mapItemFactories)
10801080
getObject(coords).as(ItemFactory.class)
10811081
.ifPresent(itemFactory -> itemFactory.getItemProducer().produce());
10821082

core/src/hitonoriol/madsand/world/World.java

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.ArrayList;
55
import java.util.Collections;
66
import java.util.HashMap;
7+
import java.util.List;
78
import java.util.function.Consumer;
89

910
import org.apache.commons.lang3.mutable.MutableFloat;
@@ -614,18 +615,13 @@ private void timeTick() {
614615

615616
private void forEachEntity(Consumer<Entity> action) {
616617
Map loc = getCurLoc();
617-
HashMap<Pair, AbstractNpc> npcs = loc.getNpcs();
618-
ArrayList<Entity> queue = new ArrayList<Entity>();
618+
List<Entity> queue = new ArrayList<Entity>();
619619
Graph graph = loc.getPathfindingGraph();
620620

621621
graph.reIndex();
622-
player.resetActDelay();
623-
npcs.forEach((position, npc) -> {
624-
npc.resetActDelay();
625-
queue.add(npc);
626-
});
622+
queue.addAll(loc.getNpcs().values());
627623
queue.add(player);
628-
624+
queue.forEach(entity -> entity.prepareToAct());
629625
Collections.sort(queue, Entity.speedComparator);
630626
queue.forEach(entity -> action.accept(entity));
631627
graph.reIndex();
@@ -640,17 +636,24 @@ public void timeSubtick(float time) {
640636
MutableFloat maxDelay = new MutableFloat(0);
641637
MutableInt stopLevel = new MutableInt(0);
642638
float totalTick = globalTick + time;
643-
639+
644640
forEachEntity(entity -> {
645641
if (timeSkip && entity.distanceTo(player) > maxSimDst)
646642
return;
647643

648-
float actDelay = cumulativeDelay.getValue() + entity.getAnimationDuration() + entity.getActDelay();
649-
maxDelay.setValue(Math.max(maxDelay.getValue(), actDelay));
650-
651644
if (player.canSee(entity)) {
645+
boolean hostile = entity != player && !((AbstractNpc) entity).isNeutral();
646+
boolean actBeforePlayer = hostile && entity.getSpeed() >= player.getSpeed();
647+
648+
if (actBeforePlayer)
649+
entity.speedUp(AbstractNpc.HOSTILE_SPEEDUP);
650+
651+
float actDelay = entity.getAnimationDuration() + entity.getActDelay();
652+
652653
if (entity != player) {
653-
if (!((AbstractNpc) entity).isNeutral() && entity.getSpeed() >= player.getSpeed()) {
654+
actDelay += cumulativeDelay.getValue();
655+
if (actBeforePlayer) {
656+
maxDelay.setValue(Math.max(maxDelay.getValue(), actDelay));
654657
Keyboard.stopInput();
655658
stopLevel.increment();
656659
player.setActDelay(maxDelay.getValue());
@@ -677,7 +680,7 @@ public void timeSubtick(float time) {
677680
if (timeSkip)
678681
endTimeSkip();
679682
Utils.dbg("[end of subtick #%f]", totalTick);
680-
}, maxDelay.getValue());
683+
}, maxDelay.getValue() + 0.01f);
681684
}
682685

683686
public void updateLight() {

0 commit comments

Comments
 (0)