Skip to content
This repository has been archived by the owner on Oct 1, 2022. It is now read-only.

Movable Refactoring #563

Open
wants to merge 54 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
f10bf7d
Create Entity and delegate all calls to Movable's interfaces to the C…
homoroselaps Feb 6, 2017
c7cb40f
Merge branch 'master' into MovableRefactoring
homoroselaps Feb 6, 2017
c5be586
Filled in the boilerplate code for the Components
homoroselaps Feb 16, 2017
a8547e9
missed file
homoroselaps Feb 16, 2017
400bcbd
remove String indexing, switch to Class IdentityHashMap
homoroselaps Mar 27, 2017
3d2fffa
incorporate IScheduleTimerable into Entity
homoroselaps Mar 28, 2017
7353c95
add SimpleBehaviourTree
homoroselaps Mar 28, 2017
94df9bd
Merge remote-tracking branch 'original/master' into MovableRefactoring
homoroselaps Mar 28, 2017
2ca099a
Implement Pathing Code into SteeringComponent
homoroselaps Mar 28, 2017
df49b0f
unify the Movable interface to support future refactorings
homoroselaps Mar 28, 2017
40799ce
remove author
homoroselaps Mar 28, 2017
8396115
Merge branch 'MovableInterface' into MovableRefactoring
homoroselaps Mar 29, 2017
08c034f
lambda behavior tree, basc geologist
homoroselaps Apr 1, 2017
40423a0
Entity lifecycle, convertTo
homoroselaps Apr 3, 2017
5b6bd8a
introduce OnEnable/OnDisable/OnDestroy in Component life cycle
homoroselaps Apr 4, 2017
65fd543
cleanup
homoroselaps Apr 5, 2017
1a7fffb
first draft for bearer behavior tree and component cleanup
homoroselaps Apr 13, 2017
20a7456
fix geologist behavior tree
homoroselaps Apr 13, 2017
1a4e916
first donkey behavior tree and cleanup
homoroselaps Apr 14, 2017
b1f911c
architecture runs, Donkey AI works, too many fixes
homoroselaps Apr 15, 2017
c7b8018
fix AnimationComponent
homoroselaps Apr 15, 2017
7f308b6
support game serialization
homoroselaps Apr 17, 2017
9c0c2da
Clean up code, fix static code inspection issues
homoroselaps Apr 28, 2017
aff376b
Merge remote-tracking branch 'original/master' into MovableRefactoring
homoroselaps Apr 28, 2017
d7ca002
Merge branch 'master' into MovableRefactoring and regenerate replay s…
homoroselaps Aug 31, 2017
adb8826
fix: more than one material got removed at each call
homoroselaps Oct 28, 2017
474fd44
Improve BehaviorTree nodes and design, improve donkey BT
homoroselaps Dec 4, 2017
623daf4
fix run components multiple times per timerEvent, support Notificatio…
homoroselaps Dec 4, 2017
cf110b7
fix Entity called only once
homoroselaps Dec 5, 2017
3c94118
Merge branch 'master' into MovableRefactoring
homoroselaps Dec 6, 2017
f86b87c
implement idle behavior
homoroselaps Dec 6, 2017
186e419
implement basic reaction to push requests, improve handling of entity…
homoroselaps Dec 7, 2017
2005940
Merge branch 'master' into MovableRefactoring
andreas-eberle May 6, 2018
7de0f8f
Fix some method and field names
andreas-eberle May 10, 2018
4027c57
Further renamings
andreas-eberle May 10, 2018
d140c09
Change notification retrieval to use streams instead of iterator
andreas-eberle May 10, 2018
f2bf74d
Refactor MovableWrapper
andreas-eberle May 10, 2018
918c57a
Add test map with specialists
andreas-eberle May 12, 2018
db980d2
Further refactorings and started work on Geologist
andreas-eberle May 12, 2018
116bc1f
Improve debugging node to print debug information in levels and only …
andreas-eberle May 12, 2018
ac76ec4
Add DynamicGuardSelector and make Geologist mostly working
andreas-eberle May 12, 2018
e76340f
Improve stop working behavior of geologist
andreas-eberle May 12, 2018
076a981
Make Notification implement Serializable
andreas-eberle May 12, 2018
1fd9452
Use notification to start and stop work of geologist
andreas-eberle May 13, 2018
54e5d7f
Improve tree readability by including debug message to parameters of …
andreas-eberle May 13, 2018
b3aa62f
Merge remote-tracking branch 'original/master' into MovableRefactoring
homoroselaps Jul 26, 2019
1b7175b
fix notificationCondition, fix chained animation
homoroselaps Jul 27, 2019
7761f6e
fix bearer steeringComponent idleBehavior
homoroselaps Jul 28, 2019
8ddfef7
implement convertTo other entity
homoroselaps Jul 29, 2019
a54b76c
start implementing BuildingWorker
homoroselaps Aug 3, 2019
ea0d6f8
WIP: BuildingWorkerBehaviorComponent
Jul 6, 2020
0642bbb
BuldingWorker Melter is working
Jul 9, 2020
0a3b0e9
presumably all BuildingWorkers work (tested: StoneCutter, Farmer, Shi…
Jul 16, 2020
7fccf39
basic BrickLayer Behavior implemented. not tested yet
Aug 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import jsettlers.input.tasks.ConvertGuiTask;
import jsettlers.logic.map.grid.movable.MovableGrid;
import jsettlers.logic.movable.Movable;
import jsettlers.logic.movable.MovableDataManager;
import jsettlers.logic.movable.interfaces.ILogicMovable;
import jsettlers.network.client.interfaces.ITaskScheduler;

Expand Down Expand Up @@ -60,7 +61,7 @@ public void clear() {
public void removeDeadPioneers() {
Collection<Integer> idsToRemove = new ArrayList<>(pioneerIds.size());
for (Integer pioneerId : pioneerIds) {
if (Movable.getMovableByID(pioneerId) == null) {
if (MovableDataManager.getMovableByID(pioneerId) == null) {
idsToRemove.add(pioneerId);
}
}
Expand Down Expand Up @@ -90,10 +91,11 @@ public void fill(ITaskScheduler taskScheduler, AiStatistics aiStatistics, byte p
}

public PioneerGroup getPioneersWithNoAction() {
List<Integer> pioneersWithNoAction = stream(pioneerIds).filter(pioneerId -> Movable.getMovableByID(pioneerId).getAction() == EMovableAction.NO_ACTION).collect(Collectors.toList());
List<Integer> pioneersWithNoAction = stream(pioneerIds).filter(pioneerId -> MovableDataManager.getMovableByID(pioneerId).getAction() == EMovableAction.NO_ACTION).collect(Collectors.toList());
return new PioneerGroup(pioneersWithNoAction);
}


public void addAll(List<Integer> pioneerIds) {
this.pioneerIds.addAll(pioneerIds);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import jsettlers.logic.buildings.others.StockBuilding;
import jsettlers.logic.buildings.trading.TradingBuilding;
import jsettlers.logic.movable.Movable;
import jsettlers.logic.movable.MovableDataManager;
import jsettlers.logic.movable.interfaces.ILogicMovable;
import jsettlers.network.client.task.packets.TaskPacket;
import jsettlers.network.synchronic.timer.ITaskExecutor;
Expand Down Expand Up @@ -260,7 +261,7 @@ private void setBuildingPriority(SetBuildingPriorityGuiTask guiTask) {

private void convertMovables(ConvertGuiTask guiTask) {
for (Integer currID : guiTask.getSelection()) {
ILogicMovable movable = Movable.getMovableByID(currID);
ILogicMovable movable = MovableDataManager.getMovableByID(currID);
if (movable != null) {
movable.convertTo(guiTask.getTargetType());
}
Expand All @@ -270,7 +271,7 @@ private void convertMovables(ConvertGuiTask guiTask) {

private void stopOrStartWorking(List<Integer> selectedMovables, boolean stop) {
for (Integer currID : selectedMovables) {
ILogicMovable movable = Movable.getMovableByID(currID);
ILogicMovable movable = MovableDataManager.getMovableByID(currID);
if (movable != null) {
movable.stopOrStartWorking(stop);
}
Expand All @@ -279,7 +280,7 @@ private void stopOrStartWorking(List<Integer> selectedMovables, boolean stop) {

private void killSelectedMovables(List<Integer> selectedMovables) {
for (Integer currID : selectedMovables) {
ILogicMovable curr = Movable.getMovableByID(currID);
ILogicMovable curr = MovableDataManager.getMovableByID(currID);
if (curr != null) {
curr.kill();
}
Expand All @@ -296,7 +297,7 @@ private void killSelectedMovables(List<Integer> selectedMovables) {
*/
private void moveSelectedTo(ShortPoint2D targetPosition, List<Integer> movableIds) {
if (movableIds.size() == 1) {
ILogicMovable currMovable = Movable.getMovableByID(movableIds.get(0));
ILogicMovable currMovable = MovableDataManager.getMovableByID(movableIds.get(0));
if (currMovable != null) {
currMovable.moveTo(targetPosition);
}
Expand All @@ -306,7 +307,7 @@ private void moveSelectedTo(ShortPoint2D targetPosition, List<Integer> movableId
}

private void sendMovablesNew(ShortPoint2D targetPosition, List<Integer> movableIds) {
List<ILogicMovable> movables = stream(movableIds).map(Movable::getMovableByID).filter(Objects::nonNull).collect(Collectors.toList());
List<ILogicMovable> movables = stream(movableIds).map(MovableDataManager::getMovableByID).filter(Objects::nonNull).collect(Collectors.toList());
if (movables.isEmpty()) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import jsettlers.common.position.ShortPoint2D;
import jsettlers.logic.buildings.Building;
import jsettlers.logic.buildings.IBuildingsGrid;
import jsettlers.logic.movable.EntityFactory;
import jsettlers.logic.movable.Movable;
import jsettlers.logic.movable.interfaces.ILogicMovable;
import jsettlers.logic.player.Player;
Expand Down Expand Up @@ -56,7 +57,7 @@ protected int subTimerEvent() {
ILogicMovable movableAtDoor = super.grid.getMovable(super.getDoor());

if (movableAtDoor == null) {
movableAtDoor = new Movable(super.grid.getMovableGrid(), getMovableType(), getDoor(), super.getPlayer());
movableAtDoor = EntityFactory.CreateMovable(super.grid.getMovableGrid(), getMovableType(), getDoor(), super.getPlayer());
produced++;

if (produced < getProduceLimit()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@
import jsettlers.logic.map.loading.list.MapList;
import jsettlers.logic.map.loading.newmap.MapFileHeader;
import jsettlers.logic.map.loading.newmap.MapFileHeader.MapType;
import jsettlers.logic.movable.EntityFactory;
import jsettlers.logic.movable.Movable;
import jsettlers.logic.movable.MovableDataManager;
import jsettlers.logic.movable.interfaces.AbstractMovableGrid;
import jsettlers.logic.movable.interfaces.IAttackable;
import jsettlers.logic.movable.interfaces.ILogicMovable;
Expand Down Expand Up @@ -430,7 +432,7 @@ public final boolean isInBounds(int x, int y) {
}

final ILogicMovable createNewMovableAt(ShortPoint2D pos, EMovableType type, Player player) {
return new Movable(movablePathfinderGrid, type, pos, player);
return EntityFactory.CreateMovable(movablePathfinderGrid, type, pos, player);
}

/**
Expand Down Expand Up @@ -930,7 +932,7 @@ public void hitWithArrowAt(ArrowObject arrow) {
@Override
public void spawnDonkey(ShortPoint2D position, Player player) {
Player realPlayer = partitionsGrid.getPlayer(player.getPlayerId());
ILogicMovable donkey = new Movable(movablePathfinderGrid, EMovableType.DONKEY, position, realPlayer);
ILogicMovable donkey = EntityFactory.CreateMovable(movablePathfinderGrid, EMovableType.DONKEY, position, realPlayer);
donkey.leavePosition();
}

Expand Down Expand Up @@ -1924,7 +1926,7 @@ public final IMapObject getMapObjectsAt(short x, short y) {

@Override
public final ConcurrentLinkedQueue<? extends IViewDistancable> getMovableViewDistancables() {
return Movable.getAllMovables();
return MovableDataManager.allMovables();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package jsettlers.logic.movable;

import java.io.Serializable;

import jsettlers.common.movable.EMovableAction;
import jsettlers.common.movable.EMovableType;
import jsettlers.logic.movable.components.SteeringComponent;
import jsettlers.logic.movable.simplebehaviortree.Decorator;
import jsettlers.logic.movable.simplebehaviortree.Node;
import jsettlers.logic.movable.simplebehaviortree.NodeStatus;
import jsettlers.logic.movable.simplebehaviortree.Tick;
import jsettlers.logic.movable.simplebehaviortree.nodes.Action;
import jsettlers.logic.movable.simplebehaviortree.nodes.Condition;
import jsettlers.logic.movable.simplebehaviortree.nodes.Guard;
import jsettlers.logic.movable.simplebehaviortree.nodes.Inverter;
import jsettlers.logic.movable.simplebehaviortree.nodes.Selector;
import jsettlers.logic.movable.simplebehaviortree.nodes.Sequence;
import jsettlers.logic.movable.simplebehaviortree.nodes.Succeeder;
import jsettlers.logic.movable.simplebehaviortree.nodes.WaitFor;

/**
* @author homoroselaps
*/

public abstract class BehaviorTreeFactory implements Serializable {
private static final long serialVersionUID = 8396039806339873520L;

protected static Node<Entity> WaitForTargetReached_FailIfNot() {
// wait for targetReached, but abort if target not reachable
return new Sequence<>(
new Inverter<>(TriggerCondition(SteeringComponent.TargetNotReachedTrigger.class)),
new WaitFor(SteeringComponent.TargetReachedTrigger.class, true)
);
}

protected static Guard<Entity> TriggerGuard(Class<? extends Notification> type, Node<Entity> child) {
return new Guard<>(entity -> entity.getNotificationsIt(type).hasNext(), true, child);
}

protected static Action<Entity> StartAnimation(EMovableAction animation, short duration) {
return new Action<>(e -> {
e.aniC().startAnimation(animation, duration);
});
}

protected static void convertTo(Entity entity, EMovableType type) {
Entity blueprint = EntityFactory.CreateEntity(entity.gameC().getMovableGrid(), type, entity.movC().getPos(), entity.movC().getPlayer());
entity.convertTo(blueprint);
}

protected static <T> Node<T> Optional(Node<T> child) {
return new Selector<T>(child, new Succeeder<T>());
}

protected static class Wait extends Node<Entity> {
private static final long serialVersionUID = 8774557186392581042L;
boolean done = false;
int delay = -1;
public Wait(int milliseconds) {
super();
delay = milliseconds;
}

@Override
protected NodeStatus onTick(Tick<Entity> tick) {
if (done) return NodeStatus.Success;
tick.Target.setInvocationDelay(delay);
done = true;
return NodeStatus.Running();
}

@Override
protected void onOpen(Tick<Entity> tick) {
done = false;
}
}

protected static Condition<Entity> TriggerCondition(Class<? extends Notification> type) {
return new Condition<>(entity -> entity.getNotificationsIt(type).hasNext());
}

protected static Debug $(String message, Node<Entity> child) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name of the method does not express its behaviour.

Copy link
Contributor Author

@homoroselaps homoroselaps Sep 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your annotation. You are completely right, this indicates bad code style.
In this decision I prioritized readability of the whole behavior tree over comprehensibility of this single function. Some behavior tree frameworks ship with a graphical tool, which we don't have. Therefore, I did my best to avoid as much boilerplate code/code repetition as possible, to support behavior design in code.
The function $ is here defined as a shorthand for the creation of a ´Debug´ node, which annotates tree nodes with debug information/comments.
I choose $ as to imitate the jQuery function, which developers might already be familiar with.
I'd fine with any other valid symbol, but would rather not clatter the tree with to many
new Debug(...) statements.

return new Debug(message, child);
}

protected static Debug $(String message) {
return new Debug(message);
}

protected static class Debug extends Decorator<Entity> {
private static final boolean DEBUG = false;
private static final long serialVersionUID = 9019598003328102086L;
private final String message;
public Debug(String message) {
super(null);
this.message = message;
}

public Debug(String message, Node<Entity> child) {
super(child);
this.message = message;
}

@Override
protected NodeStatus onTick(Tick<Entity> tick) {
if (DEBUG) System.out.println(message);
if (child != null) {
NodeStatus result = child.execute(tick);
String res = result == NodeStatus.Success ? "Success" : result == NodeStatus.Failure ? "Failure" : "Running";
if (DEBUG) System.out.println(message + ": " + res);
return result;
}
return NodeStatus.Success;
}
}
}
Loading