/*******************************************************************************
* Copyright 2015 Maximilian Stark | Dakror <mail@dakror.de>
*
* 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 de.dakror.arise.game.world;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.concurrent.CopyOnWriteArrayList;
import org.json.JSONArray;
import de.dakror.arise.game.Game;
import de.dakror.arise.layer.MPLayer;
import de.dakror.arise.layer.WorldHUDLayer;
import de.dakror.arise.net.packet.Packet;
import de.dakror.arise.net.packet.Packet.PacketTypes;
import de.dakror.arise.net.packet.Packet03World;
import de.dakror.arise.net.packet.Packet04City;
import de.dakror.arise.net.packet.Packet05Resources;
import de.dakror.arise.net.packet.Packet07RenameCity;
import de.dakror.arise.net.packet.Packet19Transfer;
import de.dakror.arise.net.packet.Packet20Takeover;
import de.dakror.arise.settings.CFG;
import de.dakror.gamesetup.GameFrame;
import de.dakror.gamesetup.ui.Component;
import de.dakror.gamesetup.util.Helper;
/**
* @author Dakror
*/
public class World extends MPLayer {
public static int CHUNKSIZE = 256;
String name;
int speed, id, width, height, tick, minX, minY;
public int x, y;
public boolean anyCityActive;
long lastCheck;
BufferedImage chunk;
JSONArray citiesData;
City gotoCity;
Point dragStart, worldDragStart;
public World(Packet03World packet) {
try {
id = packet.getId();
name = packet.getName();
speed = packet.getSpeed();
minX = minY = 0;
chunk = new BufferedImage(CHUNKSIZE, CHUNKSIZE, BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < chunk.getWidth(); i += 32)
for (int j = 0; j < chunk.getHeight(); j += 32)
Helper.drawImage2(Game.getImage("world/ground.png"), i, j, 32, 32, 32, 0, 32, 32, (Graphics2D) chunk.getGraphics());
updateSize();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void init() {}
@Override
public void draw(Graphics2D g) {
AffineTransform old = g.getTransform();
AffineTransform at = g.getTransform();
at.translate(x, y);
g.setTransform(at);
for (int i = 0; i < Math.ceil(width / (float) CHUNKSIZE); i++)
for (int j = 0; j < Math.ceil(height / (float) CHUNKSIZE); j++)
if (new Rectangle(0, 0, Game.getWidth(), Game.getHeight()).intersects(new Rectangle(minX + i * CHUNKSIZE + x, minY + j * CHUNKSIZE + y, CHUNKSIZE, CHUNKSIZE)))
g.drawImage(chunk, minX + i * CHUNKSIZE, minY + j * CHUNKSIZE, null);
Component hovered = null;
for (Component c : components) {
if (!new Rectangle(0, 0, Game.getWidth(), Game.getHeight()).intersects(new Rectangle(c.getX() + x, c.getY() + y, c.getWidth(), c.getHeight()))) continue;
c.draw(g);
if (c.state == 2) hovered = c;
}
if (hovered != null) hovered.drawTooltip(GameFrame.currentFrame.mouse.x, GameFrame.currentFrame.mouse.y, g);
g.setTransform(old);
}
@Override
public void update(int tick) {
this.tick = tick;
if (tick % 120 == 0) sortComponents();
updateComponents(tick);
}
public void updateSize() {
int minX = -65536, minY = -65536, maxX = -65536, maxY = -65536;
for (Component c : components) {
if (c.getX() < minX || minX == -65536) minX = c.getX();
if (c.getY() < minY || minY == -65536) minY = c.getY();
if (c.getX() + c.getWidth() > maxX || maxX == -65536) maxX = c.getX() + c.getWidth();
if (c.getY() + c.getHeight() > maxY || maxY == -65536) maxY = c.getY() + c.getHeight();
}
minX = minX > 0 ? 0 : minX;
minY = minY > 0 ? 0 : minY;
this.minX = minX;
this.minY = minY;
width = maxX - minX;
width = width < Game.getWidth() ? Game.getWidth() : width;
height = maxY - minY;
height = height < Game.getHeight() ? Game.getHeight() : height;
x = x < -(width - Game.getWidth() + minX) ? -(width - Game.getWidth() + minX) : x;
y = y < -(height - Game.getHeight() + minY) ? -(height - Game.getHeight() + minY) : y;
x = x > -minX ? -minX : x;
y = y > -minY ? -minY : y;
}
public void sortComponents() {
ArrayList<Component> c = new ArrayList<>(components);
Collections.sort(c, new Comparator<Component>() {
@Override
public int compare(Component o1, Component o2) {
if (o1.getClass().equals(o2.getClass())) return 1;
if (o1 instanceof Transfer) return -1;
return 1;
}
});
components = new CopyOnWriteArrayList<>(c);
}
@Override
public void mouseDragged(MouseEvent e) {
if (e.getModifiers() == 4) // RMB
{
if (dragStart == null) {
dragStart = e.getPoint();
worldDragStart = new Point(x, y);
}
int x = worldDragStart.x + e.getX() - dragStart.x;
int y = worldDragStart.y + e.getY() - dragStart.y;
x = x < -(width - Game.getWidth() + minX) ? -(width - Game.getWidth() + minX) : x;
y = y < -(height - Game.getHeight() + minY) ? -(height - Game.getHeight() + minY) : y;
this.x = x > -minX ? -minX : x;
this.y = y > -minY ? -minY : y;
e.translatePoint(-x, -y);
}
super.mouseDragged(e);
}
@Override
public void mousePressed(MouseEvent e) {
e.translatePoint(-x, -y);
super.mousePressed(e);
anyCityActive = false;
for (Component c : components) {
if (c instanceof City && c.state == 1) {
anyCityActive = true;
break;
}
}
}
@Override
public void mouseMoved(MouseEvent e) {
e.translatePoint(-x, -y);
super.mouseMoved(e);
for (Component c : components) {
if (c instanceof City && c.state == 2) {
WorldHUDLayer.hoveredCity = (City) c;
return;
}
}
WorldHUDLayer.hoveredCity = null;
}
@Override
public void mouseReleased(MouseEvent e) {
worldDragStart = dragStart = null;
e.translatePoint(-x, -y);
super.mouseReleased(e);
}
public int getSpeed() {
return speed;
}
public int getId() {
return id;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public int getCityCount() {
int i = 0;
for (Component c : components)
if (c instanceof City) i++;
return i;
}
public City getCityForId(int id) {
for (Component c : components)
if (c instanceof City && ((City) c).getId() == id) return (City) c;
return null;
}
@Override
public void onReceivePacket(Packet p) {
super.onReceivePacket(p);
if (p.getType() == PacketTypes.CITY) {
Packet04City packet = (Packet04City) p;
int middleX = (Game.getWidth() - City.SIZE) / 2;
int middleY = (Game.getHeight() - City.SIZE) / 2;
int x = middleX + packet.getX() * City.SIZE;
int y = middleY + packet.getY() * City.SIZE;
boolean found = false;
for (Component c : components) {
if (c instanceof City && c.getX() == x && c.getY() == y) {
((City) c).setName(packet.getCityName());
((City) c).setLevel(packet.getLevel());
found = true;
break;
}
}
if (!found) {
City c = new City(x, y, packet);
components.add(c);
updateSize();
sortComponents();
}
}
if (p.getType() == PacketTypes.RENAMECITY) {
Packet07RenameCity packet = (Packet07RenameCity) p;
for (Component c : components) {
if (c instanceof City && ((City) c).getId() == packet.getCityId()) {
((City) c).setName(packet.getNewName());
break;
}
}
}
if (p.getType() == PacketTypes.RESOURCES && gotoCity != null) {
if (gotoCity.getId() == ((Packet05Resources) p).getCityId()) {
gotoCity.resourcePacket = (Packet05Resources) p;
Game.currentGame.fadeTo(1, 0.05f);
} else CFG.e("Received invalid packet05resources: current gotoCity.id=" + gotoCity.getId() + ", packet.id=" + ((Packet05Resources) p).getCityId());
}
if (p.getType() == PacketTypes.TRANSFER) {
Packet19Transfer packet = (Packet19Transfer) p;
if (packet.isMarkedForRemoval()) {
for (Component c : components)
if (c instanceof Transfer && ((Transfer) c).getId() == packet.getId()) components.remove(c);
sortComponents();
} else {
components.add(new Transfer(getCityForId(packet.getCityFrom()), getCityForId(packet.getCityTo()), packet));
sortComponents();
}
}
if (p.getType() == PacketTypes.TAKEOVER) {
Packet20Takeover packet = (Packet20Takeover) p;
for (Component c : components) {
if (c instanceof City && ((City) c).getId() == packet.getCityTakenOverId()) {
((City) c).updateTakeoverStage(packet.getStage(), packet.getTimeleft());
if (packet.getNewUserId() != 0) ((City) c).setUser(packet.getNewUserId(), packet.getNewUsername());
}
}
}
}
}