Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created a structure for handling travel through starports #534

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -0,0 +1,29 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.Starport.components;

import org.destinationsol.game.StarPort;
import org.terasology.gestalt.entitysystem.component.Component;

/**
* Indicates that an entity is being transported via a {@link StarPort}.
*/
public class InStarportTransit implements Component<InStarportTransit> {
@Override
public void copy(InStarportTransit other) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.Starport.events;

import org.destinationsol.Starport.systems.InTransitUpdateHandler;
import org.destinationsol.game.StarPort;
import org.destinationsol.game.planet.Planet;
import org.terasology.gestalt.entitysystem.event.Event;

/**
* When an entity enters a {@link StarPort}, this event is used to send the source and destination information to the
* {@link InTransitUpdateHandler} system.
*/
public class EnteringStarportEvent implements Event {

private final Planet sourcePlanet;
private final Planet destinationPlanet;

public EnteringStarportEvent(Planet sourcePlanet, Planet destinationPlanet) {
this.sourcePlanet = sourcePlanet;
this.destinationPlanet = destinationPlanet;
}

/**
* @return the planet that the entity entered the {@link StarPort} at
*/
public Planet getSourcePlanet() {
return sourcePlanet;
}

/**
* @return the planet that the entity is traveling to
*/
public Planet getDestinationPlanet() {
return destinationPlanet;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.Starport.events;

import org.destinationsol.game.StarPort;
import org.terasology.gestalt.entitysystem.event.Event;

/**
* Indicates that an entity that went through a {@link StarPort} should be updated.
*/
public class InTransitUpdateEvent implements Event {

private final float timeStep;

public InTransitUpdateEvent(float timeStep) {
this.timeStep = timeStep;
}

/**
* @return the amount of time elapsed since the last update
*/
public float getTimeStep() {
return timeStep;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.Starport.events;

import org.destinationsol.game.StarPort;
import org.terasology.gestalt.entitysystem.event.Event;

/**
* Indicates that an entity has finished traveling through a {@link StarPort}.
*/
public class StarportTransitFinishedEvent implements Event {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.Starport.systems;

import com.badlogic.gdx.math.Vector2;
import org.destinationsol.Const;
import org.destinationsol.Starport.components.InStarportTransit;
import org.destinationsol.Starport.events.EnteringStarportEvent;
import org.destinationsol.Starport.events.InTransitUpdateEvent;
import org.destinationsol.Starport.events.StarportTransitFinishedEvent;
import org.destinationsol.common.In;
import org.destinationsol.common.SolMath;
import org.destinationsol.entitysystem.EntitySystemManager;
import org.destinationsol.entitysystem.EventReceiver;
import org.destinationsol.game.StarPort;
import org.destinationsol.game.planet.Planet;
import org.destinationsol.location.components.Angle;
import org.destinationsol.location.components.Position;
import org.destinationsol.location.components.Velocity;
import org.terasology.gestalt.entitysystem.entity.EntityRef;
import org.terasology.gestalt.entitysystem.event.EventResult;
import org.terasology.gestalt.entitysystem.event.ReceiveEvent;

import java.util.HashMap;

public class InTransitUpdateHandler implements EventReceiver {

private static final float ENTITY_IN_TRANSIT_MOVEMENT_SPEED = Const.MAX_MOVE_SPD * 2;

private HashMap<EntityRef, Planet> sourcePlanetMap = new HashMap<>();
private HashMap<EntityRef, Planet> destinationPlanetMap = new HashMap<>();

@In
private EntitySystemManager entitySystemManager;

/**
* When an entity enters a {@link StarPort}, this stores its source and destination information.
*
* @param event the information about the source and destination
* @param entity the entity entering the StarPort
*/
@ReceiveEvent(components = InStarportTransit.class)
public EventResult onEnteringStarport(EnteringStarportEvent event, EntityRef entity) {
sourcePlanetMap.put(entity, event.getSourcePlanet());
destinationPlanetMap.put(entity, event.getDestinationPlanet());
return EventResult.CONTINUE;
}

/**
* @param event
* @param entity
* @return
*/
@ReceiveEvent(components = {InStarportTransit.class, Position.class, Angle.class, Velocity.class})
public EventResult onUpdate(InTransitUpdateEvent event, EntityRef entity) {

if (!sourcePlanetMap.containsKey(entity) || !destinationPlanetMap.containsKey(entity)) {
return EventResult.CANCEL;
}

Planet sourcePlanet = sourcePlanetMap.get(entity);
Planet destinationPlanet = destinationPlanetMap.get(entity);
Vector2 sourcePlanetPosition = sourcePlanet.getPosition();

Vector2 destinationStarportPosition = new Vector2();
float trajectoryAngle = SolMath.angle(destinationPlanet.getPosition(), sourcePlanetPosition);

//the following block calculates the location of the starport by getting the location relative to the planet,
//then adding the position of the planet to the relative position.
float distance = destinationPlanet.getFullHeight() + StarPort.DIST_FROM_PLANET + StarPort.SIZE / 2;
SolMath.fromAl(destinationStarportPosition, trajectoryAngle, distance);
destinationStarportPosition.add(destinationPlanet.getPosition());

Angle angleComponent = entity.getComponent(Angle.class).get();
Position positionComponent = entity.getComponent(Position.class).get();
float angle = SolMath.angle(positionComponent.position, destinationStarportPosition);
angleComponent.setAngle(angle);

Velocity velocityComponent = entity.getComponent(Velocity.class).get();
SolMath.fromAl(velocityComponent.velocity, angleComponent.getAngle(), ENTITY_IN_TRANSIT_MOVEMENT_SPEED);

float timeStep = event.getTimeStep();
Vector2 displacement = SolMath.getVec(velocityComponent.velocity);
displacement.scl(timeStep);
positionComponent.position.add(displacement);
SolMath.free(displacement);

entity.setComponent(positionComponent);
entity.setComponent(angleComponent);
entity.setComponent(velocityComponent);

if (positionComponent.position.dst(destinationStarportPosition) < .5f) {
entitySystemManager.sendEvent(new StarportTransitFinishedEvent(), entity);
return EventResult.COMPLETE;
}

return EventResult.CONTINUE;
}

/**
* After an entity travels through a {@link StarPort}, this removes the {@link InStarportTransit} component.
*/
@ReceiveEvent(components = InStarportTransit.class)
public EventResult onStarportTransitFinished(StarportTransitFinishedEvent event, EntityRef entity) {
entity.removeComponent(InStarportTransit.class);
return EventResult.CONTINUE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.Starport.systems;

import org.destinationsol.Starport.components.InStarportTransit;
import org.destinationsol.Starport.events.InTransitUpdateEvent;
import org.destinationsol.common.In;
import org.destinationsol.entitysystem.EntitySystemManager;
import org.destinationsol.game.SolGame;
import org.destinationsol.game.UpdateAwareSystem;

/**
* Sends an {@link InTransitUpdateEvent} every tick to each entity with an {@link InStarportTransit} component.
*/
public class InTransitUpdateSystem implements UpdateAwareSystem {

@In
private EntitySystemManager entitySystemManager;

@Override
public void update(SolGame game, float timeStep) {
entitySystemManager.sendEvent(new InTransitUpdateEvent(timeStep), new InStarportTransit());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2020 The Terasology Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.destinationsol.Starport.systems;

import org.destinationsol.Starport.components.InStarportTransit;
import org.destinationsol.body.components.BodyLinked;
import org.destinationsol.body.systems.BodyHandlerSystem;
import org.destinationsol.entitysystem.EventReceiver;
import org.destinationsol.force.events.ContactEvent;
import org.destinationsol.force.events.ForceEvent;
import org.destinationsol.force.events.ImpulseEvent;
import org.destinationsol.game.StarPort;
import org.destinationsol.health.components.Health;
import org.destinationsol.health.events.DamageEvent;
import org.destinationsol.health.systems.DamageSystem;
import org.terasology.gestalt.entitysystem.entity.EntityRef;
import org.terasology.gestalt.entitysystem.event.Before;
import org.terasology.gestalt.entitysystem.event.EventResult;
import org.terasology.gestalt.entitysystem.event.ReceiveEvent;

/**
* This system handles basic events that happen to an entity while it is traveling through a {@link StarPort}.
*/
public class StarportTravelSystem implements EventReceiver {

/**
* When an entity is going through a {@link StarPort}, this prevents it from taking damage.
*/
@ReceiveEvent(components = {InStarportTransit.class, Health.class})
@Before(DamageSystem.class)
public EventResult stopDamage(DamageEvent event, EntityRef entity) {
return EventResult.COMPLETE;
}

/**
* When an entity is going through a {@link StarPort}, this prevents it from being affected by contact.
*/
@ReceiveEvent(components = InStarportTransit.class)
public EventResult stopContact(ContactEvent event, EntityRef entity) {
event.getContact().setEnabled(false);
return EventResult.COMPLETE;
}

/**
* When an entity is going through a {@link StarPort}, this prevents it from being affected by forces.
*/
@ReceiveEvent(components = {InStarportTransit.class, BodyLinked.class})
@Before(BodyHandlerSystem.class)
public EventResult stopForce(ForceEvent event, EntityRef entity) {
return EventResult.COMPLETE;
}

/**
* When an entity is going through a {@link StarPort}, this prevents it from being affected by impulses.
*/
@ReceiveEvent(components = {InStarportTransit.class})
public EventResult stopImpulse(ImpulseEvent event, EntityRef entity) {
return EventResult.COMPLETE;
}

}
2 changes: 1 addition & 1 deletion engine/src/main/java/org/destinationsol/game/StarPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
public class StarPort implements SolObject {
public static final int SIZE = 8;

private static final float DIST_FROM_PLANET = Const.PLANET_GAP * .5f;
public static final float DIST_FROM_PLANET = Const.PLANET_GAP * .5f;
private static final float FARE = 10f;
private final Body body;
private final ArrayList<LightSource> lightSources;
Expand Down