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

Add city centre icon to minimap #42

Merged
merged 5 commits into from Jun 9, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -11,3 +11,6 @@ This [techdemo](https://www.youtube.com/watch?v=feEMmo1pRSY&feature=youtu.be) pr
![sc2](/images/niceCity5.jpg)

This module originates from the GSOC 2016 Project Citysimulation by [CptCrispyCrunchy](https://github.com/CptCrispyCrunchy) with [Skaldarnar](https://github.com/skaldarnar) and [msteiger](https://github.com/msteiger) as mentors.

### Images
The building icon image was taken from http://www.iconsmind.com (Linkware License)
Binary file added assets/textures/city-icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
120 changes: 120 additions & 0 deletions src/main/java/org/terasology/dynamicCities/minimap/CentreOverlay.java
@@ -0,0 +1,120 @@
/*
* Copyright 2019 MovingBlocks
*
* 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.terasology.dynamicCities.minimap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.dynamicCities.settlements.SettlementsCacheComponent;
import org.terasology.entitySystem.entity.EntityRef;
import org.terasology.logic.location.LocationComponent;
import org.terasology.math.geom.Rect2f;
import org.terasology.math.geom.Rect2fTransformer;
import org.terasology.math.geom.Rect2i;
import org.terasology.math.geom.Vector2f;
import org.terasology.math.geom.Vector2i;
import org.terasology.minimap.overlays.MinimapOverlay;
import org.terasology.rendering.assets.texture.Texture;
import org.terasology.rendering.nui.Canvas;
import org.terasology.utilities.Assets;

import java.util.Optional;

public class CentreOverlay implements MinimapOverlay {

private EntityRef settlementCachingEntity;
private Logger logger = LoggerFactory.getLogger(DistrictOverlay.class);

private Vector2f iconSize = new Vector2f(32f, 32f);
mayant15 marked this conversation as resolved.
Show resolved Hide resolved


public CentreOverlay(EntityRef entityRef) {
this.settlementCachingEntity = entityRef;
}

@Override
public void render(Canvas canvas, Rect2f worldRect) {
if (!settlementCachingEntity.hasComponent(SettlementsCacheComponent.class)) {
logger.error("No SettlementCacheComponent found!");
return;
}

Rect2f screenRect = Rect2f.createFromMinAndSize(
new Vector2f(canvas.getRegion().minX(), canvas.getRegion().minY()),
new Vector2f(canvas.getRegion().maxX(), canvas.getRegion().maxY())
);

Rect2fTransformer transformer = new Rect2fTransformer(worldRect, screenRect);

for (EntityRef settlement : settlementCachingEntity.getComponent(SettlementsCacheComponent.class).settlementEntities.values()) {
if (!settlement.isActive()) {
continue;
}
LocationComponent locationComponent = settlement.getComponent(LocationComponent.class);
if (locationComponent == null) {
logger.error("Cannot find location component for settlement: " + settlement.toString());
return;
}

Vector2f location = new Vector2f(locationComponent.getLocalPosition().x(), locationComponent.getLocalPosition().z());
Vector2f mapPoint = new Vector2f(
transformer.applyX(location.x),
transformer.applyY(location.y)
);

Vector2i min = clamp(mapPoint, screenRect);
Rect2i region = Rect2i.createFromMinAndSize(min.x, min.y, (int) iconSize.x, (int) iconSize.y);

Optional<Texture> icon = Assets.getTexture("DynamicCities:city-icon");
if (icon.isPresent()) {
canvas.drawTexture(icon.get(), region);
} else {
logger.error("No icon found for city");
}
}
}

private Vector2i clamp(Vector2f point, Rect2f box) {
float x;
float y;
Rect2f iconRegion = Rect2f.createFromMinAndSize(point, iconSize);
if (box.contains(iconRegion)) {
return new Vector2i(point.x, point.y);
} else {
if (iconRegion.maxX() >= box.maxX()) {
x = (int) box.maxX() - iconSize.x;
} else if (iconRegion.minX() <= box.minX()) {
x = (int) box.minX();
} else {
x = point.x;
}

if (iconRegion.maxY() >= box.maxY()) {
y = (int) box.maxY() - iconSize.y;
} else if (iconRegion.minY() <= box.minY()) {
y = (int) box.minY();
} else {
y = point.y;
}
}
return new Vector2i(x, y);
}

@Override
public int getZOrder() {
return 0;
}

}
Expand Up @@ -18,6 +18,7 @@

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.dynamicCities.minimap.events.AddCentreOverlayEvent;
import org.terasology.dynamicCities.minimap.events.AddDistrictOverlayEvent;
import org.terasology.dynamicCities.minimap.events.RemoveDistrictOverlayEvent;
import org.terasology.dynamicCities.settlements.SettlementsCacheComponent;
Expand All @@ -39,7 +40,7 @@
import java.util.Map;

@RegisterSystem(RegisterMode.CLIENT)
public class DistrictOverlaySystem extends BaseComponentSystem {
public class MinimapOverlaySystem extends BaseComponentSystem {


@In
Expand All @@ -54,7 +55,7 @@ public class DistrictOverlaySystem extends BaseComponentSystem {
@In
private NetworkSystem networkSystem;

private Logger logger = LoggerFactory.getLogger(DistrictOverlaySystem.class);
private Logger logger = LoggerFactory.getLogger(MinimapOverlaySystem.class);

private EntityRef clientEntity;

Expand All @@ -69,8 +70,9 @@ public void initialise() {
}
isOverlayAdded = new HashMap<>();
}

@ReceiveEvent
public void onAddOverlayEvent(AddDistrictOverlayEvent event, EntityRef entityRef) {
public void onAddDistrictOverlayEvent(AddDistrictOverlayEvent event, EntityRef entityRef) {
if (networkSystem.getMode() == NetworkMode.NONE && !isOverlaySinglePlayerAdded) {
Iterator<EntityRef> entityRefs = entityManager.getEntitiesWith(SettlementsCacheComponent.class).iterator();
if (entityRefs.hasNext()) {
Expand Down Expand Up @@ -105,6 +107,34 @@ public void onAddOverlayEvent(AddDistrictOverlayEvent event, EntityRef entityRef
}
}

@ReceiveEvent
public void onAddCentreOverlayEvent(AddCentreOverlayEvent event, EntityRef entityRef) {
if (networkSystem.getMode() == NetworkMode.NONE) {
Iterator<EntityRef> entities = entityManager.getEntitiesWith(SettlementsCacheComponent.class).iterator();
if (entities.hasNext()) {
minimapSystem.addOverlay(new CentreOverlay(entities.next()));
}
}

if (networkSystem.getMode() == NetworkMode.CLIENT) {
if (clientEntity.getComponent(ClientComponent.class).character.getId() == entityRef.getId() && !isOverlayAdded.getOrDefault(entityRef, false)) {
Iterator<EntityRef> entities = entityManager.getEntitiesWith(SettlementsCacheComponent.class).iterator();
if (entities.hasNext()) {
minimapSystem.addOverlay(new CentreOverlay(entities.next()));
}
}
}

if (networkSystem.getMode() == NetworkMode.DEDICATED_SERVER && !isOverlayAdded.getOrDefault(entityRef, false)) {
if (localPlayer.getCharacterEntity() == entityRef) {
Iterator<EntityRef> entities = entityManager.getEntitiesWith(SettlementsCacheComponent.class).iterator();
if (entities.hasNext()) {
minimapSystem.addOverlay(new CentreOverlay(entities.next()));
}
}
}
}

@ReceiveEvent
public void onRemoveDistrictOverlayEvent(RemoveDistrictOverlayEvent event, EntityRef entityRef) {
if (networkSystem.getMode() == NetworkMode.CLIENT) {
Expand Down
@@ -0,0 +1,26 @@
/*
* Copyright 2019 MovingBlocks
*
* 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.terasology.dynamicCities.minimap.events;

import org.terasology.entitySystem.event.Event;
import org.terasology.network.BroadcastEvent;

@BroadcastEvent
public class AddCentreOverlayEvent implements Event {
public AddCentreOverlayEvent() {

}
}
Expand Up @@ -18,6 +18,7 @@

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.dynamicCities.minimap.events.AddCentreOverlayEvent;
import org.terasology.dynamicCities.minimap.events.AddDistrictOverlayEvent;
import org.terasology.dynamicCities.minimap.events.RemoveDistrictOverlayEvent;
import org.terasology.dynamicCities.playerTracking.OnEnterSettlementEvent;
Expand Down Expand Up @@ -93,6 +94,7 @@ public void registerSettlement(SettlementRegisterEvent event, EntityRef settleme
@ReceiveEvent
public void addOverlayToClient(OnEnterSettlementEvent event, EntityRef player) {
player.send(new AddDistrictOverlayEvent());
player.send(new AddCentreOverlayEvent());
}

@ReceiveEvent
Expand Down