/* * IDK Game Server by Steve Winfield * https://github.com/WinfieldSteve */ package org.stevewinfield.suja.idk.game.rooms; import org.apache.log4j.Logger; import org.magicwerk.brownies.collections.GapList; import org.stevewinfield.suja.idk.Bootloader; import org.stevewinfield.suja.idk.IDK; import org.stevewinfield.suja.idk.communication.ISerialize; import org.stevewinfield.suja.idk.communication.MessageWriter; import org.stevewinfield.suja.idk.communication.room.writers.RoomFloorItemUpdateFlagsWriter; import org.stevewinfield.suja.idk.communication.room.writers.RoomWallItemMovedWriter; import org.stevewinfield.suja.idk.game.furnitures.Furniture; import org.stevewinfield.suja.idk.game.furnitures.FurnitureInteractor; import org.stevewinfield.suja.idk.game.furnitures.FurnitureType; import org.stevewinfield.suja.idk.game.furnitures.IFurnitureInteractor; import org.stevewinfield.suja.idk.game.miscellaneous.MoodlightData; import org.stevewinfield.suja.idk.game.rooms.coordination.*; import org.stevewinfield.suja.idk.game.rooms.coordination.Pathfinder.Node; import org.stevewinfield.suja.idk.game.rooms.wired.WiredManager; import org.stevewinfield.suja.idk.network.sessions.Session; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.concurrent.ConcurrentHashMap; public class RoomItem implements ISerialize { public int getItemId() { return itemId; } public Furniture getBase() { return base; } public RoomInstance getRoom() { return room; } public Vector3 getPosition() { return position; } public IFurnitureInteractor getInteractor() { return interactor; } public int getInteractorId() { return interactorId; } public String getWallPosition() { return wallPosition; } public double getAbsoluteHeight() { return this.getPosition().getAltitude() + this.getBase().getHeight(); } public int getRotation() { return rotation; } public boolean isWiredItem() { return this.base.isWiredItem(); } public List<Vector2> getAffectedTiles() { final List<Vector2> list = new GapList<>(); if (this.rotation == 0 || this.rotation == 2 || this.rotation == 4 || this.rotation == 6) { for (int i = 0; i < this.getBase().getWidth(); i++) { final int x = this.rotation == 0 || this.rotation == 4 ? this.getPosition().getX() + i : this.getPosition().getX(); final int y = this.rotation == 2 || this.rotation == 6 ? this.getPosition().getY() + i : this.getPosition().getY(); for (int j = 0; j < this.getBase().getLength(); j++) { final int xb = this.rotation == 2 || this.rotation == 6 ? x + j : x; final int xn = this.rotation == 0 || this.rotation == 4 ? y + j : y; list.add(new Vector2(xb, xn)); } } } return list; } public String getFlags() { return flags; } public int getFlagsState() { int x; try { x = Integer.valueOf(this.flags); } catch (final NumberFormatException ex) { x = 0; } return x; } public String[] getTermFlags() { return termFlags; } public void setFlags(final int data) { this.setFlags(data + ""); } public void setFlags(final String data) { this.flags = data; } public ConcurrentHashMap<Integer, Integer> getInteractingPlayers() { return this.interactingPlayers; } public int getState() { if (this.getBase().isLayable()) { return TileState.LAYABLE; } if (this.getBase().isSitable()) { return TileState.SITABLE; } return this.walkable ? TileState.OPEN : TileState.BLOCKED; } public RoomItem(final RoomInstance room) { this.itemId = 0; this.base = null; this.position = new Vector3(); this.interactorId = 0; this.interactor = null; this.rotation = 0; this.flags = "0"; this.room = room; this.walkable = false; this.termCycles = 0; this.wallPosition = ""; this.interactingPlayers = new ConcurrentHashMap<>(); } public RoomItem(final RoomInstance room, final int itemId, final Furniture base, final int interactorId, final String flags) { this.itemId = itemId; this.base = base; this.room = room; this.interactorId = interactorId; this.interactor = Bootloader.getGame().getFurnitureManager().getInteractor(interactorId); this.position = new Vector3(); this.flags = flags; this.interactingPlayers = new ConcurrentHashMap<>(); this.walkable = (this.base.getInteractor() == FurnitureInteractor.GATE && this.flags.equals("1")) || this.base.isWalkable(); this.termCycles = 0; this.loadTermFlags(); } private void loadTermFlags() { if (WiredManager.isWiredItem(base) || this.getBase().getInteractor() == FurnitureInteractor.POST_IT || this.getBase().getInteractor() == FurnitureInteractor.MOODLIGHT || this.getBase().getInteractor() == FurnitureInteractor.FIREWORK || this.getBase().isGift() || this.getBase().getId() == IDK.CATA_RECYCLER_BOX_ID || this.getBase().getInteractor() == FurnitureInteractor.TELEPORTER) { this.termFlags = flags.split("" + (char) 10); this.flags = ""; } if (this.getBase().getInteractor() == FurnitureInteractor.MOODLIGHT) { final MoodlightData data = MoodlightData.getInstance(this.getTermFlags()[0]); this.flags = data.getDisplayData(); } if ((this.getBase().isGift() || this.getBase().getId() == IDK.CATA_RECYCLER_BOX_ID) && this.termFlags.length > 0) { this.flags = this.termFlags[0]; } if (this.getBase().getInteractor() == FurnitureInteractor.POST_IT) { this.flags = this.termFlags[0]; } } public void set(final ResultSet row) throws SQLException { this.itemId = row.getInt("room_items.item_id"); this.base = Bootloader.getGame().getFurnitureManager().getFurniture(row.getInt("base_item")); this.interactorId = row.getInt("special_interactor") > -1 ? row.getInt("special_interactor") : this.base.getInteractor(); this.interactor = Bootloader.getGame().getFurnitureManager().getInteractor(interactorId); this.rotation = row.getInt("rotation"); this.position = new Vector3(row.getInt("position_x"), row.getInt("position_y"), row.getDouble("position_altitude")); this.wallPosition = row.getString("wall_position"); final ResultSet _row = Bootloader.getStorage().queryParams("SELECT flag FROM item_flags WHERE item_id=" + this.itemId).executeQuery(); if (_row != null && _row.next()) { this.flags = _row.getString("flag"); } else { this.flags = "0"; } this.walkable = (this.base.getInteractor() == FurnitureInteractor.GATE && this.flags.equals("1")) || this.base.isWalkable(); this.loadTermFlags(); } public void setPosition(final Vector3 position, final int rotation) { this.position = position; this.rotation = rotation; } public boolean updateState(final boolean x, final boolean checkForPlayers) { boolean update = false; for (final Vector2 posAct : this.getAffectedTiles()) { if (checkForPlayers) { final GapList<RoomPlayer> players = room.getRoomPlayersForTile(posAct); if (players.size() > 0) { return false; } } RoomItem oldHighest = null; for (final RoomItem yitem : room.getRoomItemsForTile(posAct)) { if (oldHighest == null || yitem.getAbsoluteHeight() > oldHighest.getAbsoluteHeight()) { oldHighest = yitem; } } if (oldHighest != null && oldHighest.getItemId() == this.getItemId()) { update = true; break; } } if (update) { this.walkable = x; for (final Vector2 posAct : this.getAffectedTiles()) { room.getGamemap().updateTile(posAct, this.getState()); } } return update; } public boolean updateState(final boolean x) { return this.updateState(x, true); } public void update(final boolean db, final boolean com) { this.update(db, com, null); } public void update(final boolean db, final boolean com, final Session session) { if (db) { this.room.addItemToUpdate(this.itemId); } if (com) { MessageWriter message; if (this.base.getType().equals(FurnitureType.WALL)) { message = new RoomWallItemMovedWriter(this); } else { message = new RoomFloorItemUpdateFlagsWriter(this); } this.room.writeMessage(message, session); } } public void update() { this.update(true, true, null); } public void update(final boolean b, final Session session) { this.update(b, true, session); } public void update(final Session session) { this.update(true, true, session); } public void update(final boolean b) { this.update(b, true, null); } public void onPlayerWalksOn(final RoomPlayer player, final boolean handleInteractor) { if (handleInteractor) { this.getInteractor().onPlayerWalksOn(player, this); } this.room.getWiredHandler().onPlayerWalksOnFurni(player, this); } public void onPlayerWalksOff(final RoomPlayer player, final boolean handleInteractor) { if (handleInteractor) { this.getInteractor().onPlayerWalksOff(player, this); } this.room.getWiredHandler().onPlayerWalksOffFurni(player, this); } @Override public void serialize(final MessageWriter writer) { if (this.getBase().getType().equals(FurnitureType.WALL)) { writer.push(this.itemId + ""); writer.push(this.base.getSpriteId()); writer.push(this.wallPosition); writer.push(this.flags); writer.push(false); // TODO -> use button } else { int secondaryId = 1; if (this.base.isGift() && this.termFlags != null && this.termFlags.length > 2) { secondaryId = (Integer.valueOf(this.termFlags[1]) * 1000) + Integer.valueOf(this.termFlags[2]); } writer.push(this.itemId); writer.push(this.base.getSpriteId()); writer.push(this.position.getX()); writer.push(this.position.getY()); writer.push(this.rotation); // rotation writer.push(String.valueOf(this.position.getAltitude())); writer.push(secondaryId); // secondary id box -> schleife writer.push(this.flags); // flags writer.push(0); // rental expire writer.push(false); // TODO -> use button } } public boolean isTouching(final Vector3 pos, final int rotation, final boolean ignoreItemRotation) { return isTouching(pos, rotation, ignoreItemRotation, -1); } public boolean isTouching(final Vector3 pos, final int rotation, final boolean ignoreItemRotation, final double itemAltitude) { if (itemAltitude != -1 && (itemAltitude - pos.getAltitude()) >= IDK.ROOM_MAX_WALK_ALTITUDE_DIFFERENCE) { return false; } if (ignoreItemRotation) { return !(rotation != -1 && rotation != this.getFrontRotation(pos.getVector2())) && (this.getPosition().getX() == pos.getX() && this.getPosition().getY() == pos.getY() || (pos.getX() == this.getPosition().getX() && pos.getY() == this.getPosition().getY() + 1) || (pos.getX() == this.getPosition().getX() - 1 && pos.getY() == this.getPosition().getY() + 1) || (pos.getX() == this.getPosition().getX() - 1 && pos.getY() == this.getPosition().getY()) || (pos.getX() == this.getPosition().getX() + 1 && pos.getY() == this.getPosition().getY() + 1) || (pos.getX() == this.getPosition().getX() && pos.getY() == this.getPosition().getY() - 1) || (pos.getX() == this.getPosition().getX() + 1 && pos.getY() == this.getPosition().getY() - 1) || (pos.getX() == this.getPosition().getX() + 1 && pos.getY() == this.getPosition().getY()) || (pos.getX() == this.getPosition().getX() - 1 && pos.getY() == this.getPosition().getY() - 1)); } if (rotation != -1 && rotation != this.getFrontRotation()) { return false; } if (this.getPosition().getX() == pos.getX() && this.getPosition().getY() == pos.getY()) { return true; } if (this.rotation == 2 || this.rotation == 6) { return pos.getX() == (this.rotation == 2 ? this.getPosition().getX() + 1 : this.getPosition().getX() - 1) && pos.getY() >= this.getPosition().getY() && pos.getY() < this.getPosition().getY() + this.getBase().getWidth(); } else { return pos.getY() == (this.rotation == 4 ? this.getPosition().getY() + 1 : this.getPosition().getY() - 1) && pos.getX() >= this.getPosition().getX() && pos.getX() < this.getPosition().getX() + this.getBase().getLength(); } } public boolean isTouching(final Vector3 pos) { return isTouching(pos, -1, true, -1); } public boolean isTouching(final Vector3 pos, final int rotation, final double altitude) { return isTouching(pos, rotation, false, altitude); } public boolean isTouching(final Vector3 pos, final int rotation) { return isTouching(pos, rotation, false, -1); } public Vector2 getFrontPosition(final Vector2 playerPosition) { int lowestWay = -1; Vector2 lowestPosition = null; for (final Vector2 possibility : Pathfinder.DIRECTIONS) { if (room.getGamemap().getTileState(position.getX() + possibility.getX(), position.getY() + possibility.getY()) == TileState.OPEN) { final Vector2 possibilityPosition = new Vector2(position.getX() + possibility.getX(), position.getY() + possibility.getY()); if (playerPosition.getX() == possibilityPosition.getX() && playerPosition.getY() == possibilityPosition.getY()) { return playerPosition; } Node node = Pathfinder.getPathInArray(room.getGamemap().getTileStates(), room.getGamemap().getTileHeights(), playerPosition, possibilityPosition); if (node != null) { int count = 0; while (node != null) { node = node.getParent(); count++; } if (count < lowestWay || lowestWay == -1) { lowestWay = count; lowestPosition = possibilityPosition; } } } } return lowestPosition; } public Vector2 getFrontPosition() { return getFrontPosition(false); } public Vector2 getFrontPosition(final boolean onlyFront) { int x = this.getPosition().getX(); int y = this.getPosition().getY(); if (!this.walkable || onlyFront) { if (this.rotation == 2 || this.rotation == 6) { x = this.rotation == 2 ? this.getPosition().getX() + 1 : this.getPosition().getX() - 1; } else { y = this.rotation == 4 ? this.getPosition().getY() + 1 : this.getPosition().getY() - 1; } } return new Vector2(x, y); } public int getFrontRotation(final Vector2 front) { return Rotation.calculate(front.getX(), front.getY(), this.getPosition().getX(), this.getPosition().getY()); } public int getFrontRotation() { if (this.getRotation() == 2) { return 6; } else if (this.getRotation() == 6) { return 2; } else if (this.getRotation() == 0) { return 4; } else { return 0; } } public void requestCycles(final int s) { this.cycles = s; this.room.queueItemCycle(this); } public void setWallPosition(final String pos) { this.wallPosition = pos; } public void onCycle() { if (this.termCycles >= this.cycles) { this.cycles = 0; this.termCycles = 0; this.interactor.onCycle(this); return; } termCycles++; this.room.queueItemCycle(this); } public void setTermFlags(final String[] x) { this.termFlags = x; } public int getIncementedCounter() { return ++this.counter; } public int getCounter() { return this.counter; } public void setCounter(final int counter) { this.counter = counter; } public Vector2 getNextInfoData() { return nextInfoData; } public void setNextInfoData(final Vector2 pos) { this.nextInfoData = pos; } public RoomPlayer getActingPlayer() { return this.actingPlayer; } public void setActingPlayer(final RoomPlayer pl) { this.actingPlayer = pl; } // fields private int itemId; private int interactorId; private Furniture base; private Vector3 position; private String wallPosition; private int rotation; private IFurnitureInteractor interactor; private String flags; private String[] termFlags; private final RoomInstance room; private boolean walkable; private Vector2 nextInfoData; private int cycles; private int termCycles; private int counter; private RoomPlayer actingPlayer; private final ConcurrentHashMap<Integer, Integer> interactingPlayers; }