Arcturus-Community/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java

449 lines
14 KiB
Java
Raw Normal View History

2018-07-06 15:30:00 +02:00
package com.eu.habbo.habbohotel.games.battlebanzai;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.achievements.AchievementManager;
2019-03-18 02:22:00 +01:00
import com.eu.habbo.habbohotel.games.*;
2019-05-04 22:41:18 +02:00
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer;
2018-07-06 15:30:00 +02:00
import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiSphere;
import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTile;
import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTimer;
import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates.InteractionBattleBanzaiGate;
import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards.InteractionBattleBanzaiScoreboard;
import com.eu.habbo.habbohotel.rooms.Room;
2018-11-17 14:28:00 +01:00
import com.eu.habbo.habbohotel.rooms.RoomTile;
2018-07-06 15:30:00 +02:00
import com.eu.habbo.habbohotel.rooms.RoomUserAction;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboItem;
2019-05-04 22:41:18 +02:00
import com.eu.habbo.habbohotel.wired.WiredHandler;
import com.eu.habbo.habbohotel.wired.WiredTriggerType;
2018-07-06 15:30:00 +02:00
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserActionComposer;
import com.eu.habbo.threading.runnables.BattleBanzaiTilesFlicker;
import gnu.trove.map.hash.THashMap;
import gnu.trove.set.hash.THashSet;
2019-05-12 12:35:23 +02:00
import java.util.*;
2018-07-06 15:30:00 +02:00
public class BattleBanzaiGame extends Game
{
2018-07-08 23:32:00 +02:00
2018-07-06 15:30:00 +02:00
public static final int effectId = 33;
2018-07-08 23:32:00 +02:00
2018-07-06 15:30:00 +02:00
public static final int POINTS_HIJACK_TILE = Emulator.getConfig().getInt("hotel.banzai.points.tile.steal");
2018-07-08 23:32:00 +02:00
2018-07-06 15:30:00 +02:00
public static final int POINTS_FILL_TILE = Emulator.getConfig().getInt("hotel.banzai.points.tile.fill");
2018-07-08 23:32:00 +02:00
2018-07-06 15:30:00 +02:00
public static final int POINTS_LOCK_TILE = Emulator.getConfig().getInt("hotel.banzai.points.tile.lock");
private int tileCount;
private int countDown;
2018-07-08 23:32:00 +02:00
2018-07-06 15:30:00 +02:00
private final THashMap<GameTeamColors, THashSet<HabboItem>> lockedTiles;
2019-03-18 02:22:00 +01:00
private final THashMap<Integer, HabboItem> gameTiles;
2018-07-06 15:30:00 +02:00
public BattleBanzaiGame(Room room)
{
super(BattleBanzaiGameTeam.class, BattleBanzaiGamePlayer.class, room, true);
2018-09-28 21:25:00 +02:00
this.lockedTiles = new THashMap<>();
2019-03-18 02:22:00 +01:00
this.gameTiles = new THashMap<>();
2018-07-06 15:30:00 +02:00
room.setAllowEffects(true);
}
@Override
public void initialise()
{
2019-03-18 02:22:00 +01:00
if(!this.state.equals(GameState.IDLE))
2018-07-06 15:30:00 +02:00
return;
this.countDown = 3;
this.resetMap();
synchronized (this.teams)
{
for (GameTeam t : this.teams.values())
{
t.initialise();
}
}
for(HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionBattleBanzaiSphere.class))
{
item.setExtradata("1");
this.room.updateItemState(item);
}
this.start();
}
@Override
public boolean addHabbo(Habbo habbo, GameTeamColors teamColor)
{
return super.addHabbo(habbo, teamColor);
}
@Override
public void start()
{
2019-03-18 02:22:00 +01:00
if(!this.state.equals(GameState.IDLE))
2018-07-06 15:30:00 +02:00
return;
super.start();
2018-11-17 14:28:00 +01:00
this.refreshGates();
2018-07-06 15:30:00 +02:00
Emulator.getThreading().run(this, 0);
}
@Override
public void run()
{
try
{
2019-03-18 02:22:00 +01:00
if (this.state.equals(GameState.IDLE))
2018-07-06 15:30:00 +02:00
return;
if(this.countDown > 0)
{
this.countDown--;
if(this.countDown == 0)
{
for(HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionBattleBanzaiSphere.class))
{
item.setExtradata("2");
this.room.updateItemState(item);
}
}
if(this.countDown > 1)
{
Emulator.getThreading().run(this, 500);
return;
}
}
2019-05-04 22:41:18 +02:00
Emulator.getThreading().run(this, 1000);
2019-03-18 02:22:00 +01:00
2019-05-04 22:41:18 +02:00
if (this.state.equals(GameState.PAUSED)) return;
2018-07-06 15:30:00 +02:00
2019-05-04 22:41:18 +02:00
int total = 0;
synchronized (this.lockedTiles)
{
for (Map.Entry<GameTeamColors, THashSet<HabboItem>> set : this.lockedTiles.entrySet())
2018-07-06 15:30:00 +02:00
{
2019-05-04 22:41:18 +02:00
total += set.getValue().size();
2018-07-06 15:30:00 +02:00
}
2019-05-04 22:41:18 +02:00
}
2018-07-06 15:30:00 +02:00
2019-05-04 22:41:18 +02:00
GameTeam highestScore = null;
2018-07-06 15:30:00 +02:00
2019-05-04 22:41:18 +02:00
synchronized (this.teams)
{
for (Map.Entry<GameTeamColors, GameTeam> set : this.teams.entrySet())
2018-07-06 15:30:00 +02:00
{
2019-05-04 22:41:18 +02:00
if (highestScore == null || highestScore.getTotalScore() < set.getValue().getTotalScore())
2018-07-06 15:30:00 +02:00
{
2019-05-04 22:41:18 +02:00
highestScore = set.getValue();
2018-07-06 15:30:00 +02:00
}
}
2019-05-04 22:41:18 +02:00
}
2018-07-06 15:30:00 +02:00
2019-05-04 22:41:18 +02:00
if(highestScore != null)
{
for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionBattleBanzaiSphere.class))
2018-07-06 15:30:00 +02:00
{
2019-05-04 22:41:18 +02:00
item.setExtradata((highestScore.teamColor.type + 3) + "");
this.room.updateItemState(item);
2018-07-06 15:30:00 +02:00
}
2019-05-04 22:41:18 +02:00
}
2018-07-06 15:30:00 +02:00
2019-05-04 22:41:18 +02:00
if(total >= this.tileCount && this.tileCount != 0)
{
for(InteractionGameTimer timer : room.getRoomSpecialTypes().getGameTimers().values())
2018-07-06 15:30:00 +02:00
{
2019-05-04 22:41:18 +02:00
if(timer.isRunning())
timer.setRunning(false);
2018-07-06 15:30:00 +02:00
}
2019-05-04 22:41:18 +02:00
2019-05-05 04:51:27 +02:00
InteractionGameTimer.endGames(room, true);
2018-07-06 15:30:00 +02:00
}
2019-05-04 22:41:18 +02:00
}
catch (Exception e)
{
Emulator.getLogging().logErrorLine(e);
}
}
2018-07-06 15:30:00 +02:00
2019-05-04 22:41:18 +02:00
@Override
public void onEnd() {
GameTeam winningTeam = null;
2018-07-06 15:30:00 +02:00
2019-05-04 22:41:18 +02:00
for (GameTeam team : this.teams.values())
{
for(GamePlayer player : team.getMembers())
{
if (player.getScore() > 0)
2018-07-06 15:30:00 +02:00
{
2019-05-04 22:41:18 +02:00
AchievementManager.progressAchievement(player.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("BattleBallPlayer"));
AchievementManager.progressAchievement(player.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("BattleBallQuestCompleted"));
2018-07-06 15:30:00 +02:00
}
2019-05-04 22:41:18 +02:00
}
2018-07-06 15:30:00 +02:00
2019-05-04 22:41:18 +02:00
if (winningTeam == null || team.getTotalScore() > winningTeam.getTotalScore())
{
winningTeam = team;
2018-07-06 15:30:00 +02:00
}
}
2019-05-04 22:41:18 +02:00
if (winningTeam != null)
2018-07-06 15:30:00 +02:00
{
2019-05-04 22:41:18 +02:00
for (GamePlayer player : winningTeam.getMembers())
{
if (player.getScore() > 0)
{
this.room.sendComposer(new RoomUserActionComposer(player.getHabbo().getRoomUnit(), RoomUserAction.WAVE).compose());
AchievementManager.progressAchievement(player.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("BattleBallWinner"));
}
}
for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionBattleBanzaiSphere.class))
{
item.setExtradata((7 + winningTeam.teamColor.type) + "");
this.room.updateItemState(item);
}
Emulator.getThreading().run(new BattleBanzaiTilesFlicker(this.lockedTiles.get(winningTeam.teamColor), winningTeam.teamColor, this.room));
2018-07-06 15:30:00 +02:00
}
2019-05-04 22:41:18 +02:00
super.onEnd();
2018-07-06 15:30:00 +02:00
}
@Override
public void stop()
{
super.stop();
2018-11-17 14:28:00 +01:00
this.refreshGates();
2018-07-06 15:30:00 +02:00
2019-03-18 02:22:00 +01:00
for (HabboItem tile : this.gameTiles.values())
{
if (tile.getExtradata().equals("1"))
{
tile.setExtradata("0");
2019-05-04 22:41:18 +02:00
this.room.updateItem(tile);
2019-03-18 02:22:00 +01:00
}
}
2018-07-06 15:30:00 +02:00
this.lockedTiles.clear();
}
2018-07-08 23:32:00 +02:00
2019-03-18 02:22:00 +01:00
private synchronized void resetMap()
2018-07-06 15:30:00 +02:00
{
for (HabboItem item : this.room.getFloorItems())
{
if (item instanceof InteractionBattleBanzaiTile)
{
item.setExtradata("1");
this.room.updateItemState(item);
this.tileCount++;
2019-03-18 02:22:00 +01:00
this.gameTiles.put(item.getId(), item);
2018-07-06 15:30:00 +02:00
}
if (item instanceof InteractionBattleBanzaiScoreboard)
{
item.setExtradata("0");
this.room.updateItemState(item);
}
}
}
2018-07-08 23:32:00 +02:00
2018-07-06 15:30:00 +02:00
public void tileLocked(GameTeamColors teamColor, HabboItem item, Habbo habbo)
2019-05-12 12:35:23 +02:00
{
this.tileLocked(teamColor, item, habbo, false);
}
public void tileLocked(GameTeamColors teamColor, HabboItem item, Habbo habbo, boolean doNotCheckFill)
2018-07-06 15:30:00 +02:00
{
if(item instanceof InteractionBattleBanzaiTile)
{
if(!this.lockedTiles.containsKey(teamColor))
{
2018-09-28 21:25:00 +02:00
this.lockedTiles.put(teamColor, new THashSet<>());
2018-07-06 15:30:00 +02:00
}
this.lockedTiles.get(teamColor).add(item);
}
if(habbo != null)
{
AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("BattleBallTilesLocked"));
}
2019-05-12 12:35:23 +02:00
if (doNotCheckFill) return;
int x = item.getX();
int y = item.getY();
List<List<RoomTile>> filledAreas = new ArrayList<>();
filledAreas.add(this.floodFill(x, y - 1, this.lockedTiles.get(teamColor), new ArrayList<>()));
filledAreas.add(this.floodFill(x, y + 1, this.lockedTiles.get(teamColor), new ArrayList<>()));
filledAreas.add(this.floodFill(x - 1, y, this.lockedTiles.get(teamColor), new ArrayList<>()));
filledAreas.add(this.floodFill(x + 1, y, this.lockedTiles.get(teamColor), new ArrayList<>()));
Optional<List<RoomTile>> largestAreaOfAll = filledAreas.stream().filter(Objects::nonNull).max(Comparator.comparing(List::size));
if (largestAreaOfAll.isPresent())
{
for (RoomTile tile: largestAreaOfAll.get())
{
Optional<HabboItem> tileItem = this.gameTiles.values().stream().filter(i -> i.getX() == tile.x && i.getY() == tile.y && i instanceof InteractionBattleBanzaiTile).findAny();
tileItem.ifPresent(habboItem -> {
this.tileLocked(teamColor, habboItem, habbo, true);
habboItem.setExtradata((2 + (teamColor.type * 3) + 3) + "");
this.room.updateItem(habboItem);
});
}
this.refreshCounters(teamColor);
if (habbo != null)
{
habbo.getHabboInfo().getGamePlayer().addScore(BattleBanzaiGame.POINTS_LOCK_TILE * largestAreaOfAll.get().size());
}
}
2018-07-06 15:30:00 +02:00
}
2019-05-12 12:35:23 +02:00
private List<RoomTile> floodFill(int x, int y, THashSet<HabboItem> lockedTiles, List<RoomTile> stack)
{
if (this.isOutOfBounds(x, y)) return null;
RoomTile tile = this.room.getLayout().getTile((short)x, (short)y);
if (this.hasLockedTileAtCoordinates(x, y, lockedTiles) || stack.contains(tile)) return stack;
stack.add(tile);
List<List<RoomTile>> result = new ArrayList<>();
result.add(this.floodFill(x, y - 1, lockedTiles, stack));
result.add(this.floodFill(x, y + 1, lockedTiles, stack));
result.add(this.floodFill(x - 1, y, lockedTiles, stack));
result.add(this.floodFill(x + 1, y, lockedTiles, stack));
if (result.contains(null)) return null;
Optional<List<RoomTile>> biggestArea = result.stream().max(Comparator.comparing(List::size));
return biggestArea.orElse(null);
}
private boolean hasLockedTileAtCoordinates(int x, int y, THashSet<HabboItem> lockedTiles)
{
for (HabboItem item: lockedTiles)
{
if (item.getX() == x && item.getY() == y) return true;
}
return false;
}
private boolean isOutOfBounds(int x, int y)
{
for (HabboItem item: this.gameTiles.values())
{
if (item.getX() == x && item.getY() == y) return false;
}
return true;
}
2018-07-08 23:32:00 +02:00
2018-07-06 15:30:00 +02:00
public void refreshCounters()
{
for(GameTeam team : this.teams.values())
{
if(team.getMembers().isEmpty())
continue;
this.refreshCounters(team.teamColor);
}
}
2018-07-08 23:32:00 +02:00
2018-07-06 15:30:00 +02:00
public void refreshCounters(GameTeamColors teamColors)
{
int totalScore = this.teams.get(teamColors).getTotalScore();
THashMap<Integer, InteractionBattleBanzaiScoreboard> scoreBoards = this.room.getRoomSpecialTypes().getBattleBanzaiScoreboards(teamColors);
for (InteractionBattleBanzaiScoreboard scoreboard : scoreBoards.values())
{
if(scoreboard.getExtradata().isEmpty())
{
scoreboard.setExtradata("0");
}
int oldScore = Integer.valueOf(scoreboard.getExtradata());
if(oldScore == totalScore)
continue;
scoreboard.setExtradata(totalScore + "");
this.room.updateItemState(scoreboard);
}
}
2018-11-17 14:28:00 +01:00
private void refreshGates()
{
2019-03-18 02:22:00 +01:00
Collection<InteractionBattleBanzaiGate> gates = this.room.getRoomSpecialTypes().getBattleBanzaiGates().values();
THashSet<RoomTile> tilesToUpdate = new THashSet<>(gates.size());
for (HabboItem item : gates)
2018-11-17 14:28:00 +01:00
{
tilesToUpdate.add(this.room.getLayout().getTile(item.getX(), item.getY()));
}
this.room.updateTiles(tilesToUpdate);
}
2019-03-18 02:22:00 +01:00
public void markTile(Habbo habbo, InteractionBattleBanzaiTile tile, int state)
{
if (!this.gameTiles.contains(tile.getId())) return;
int check = state - (habbo.getHabboInfo().getGamePlayer().getTeamColor().type * 3);
if(check == 3 || check == 4)
{
state++;
if(state % 3 == 2)
{
habbo.getHabboInfo().getGamePlayer().addScore(BattleBanzaiGame.POINTS_LOCK_TILE);
this.tileLocked(habbo.getHabboInfo().getGamePlayer().getTeamColor(), tile, habbo);
}
else
{
habbo.getHabboInfo().getGamePlayer().addScore(BattleBanzaiGame.POINTS_FILL_TILE);
}
}
else
{
state = (habbo.getHabboInfo().getGamePlayer().getTeamColor().type * 3) + 3;
habbo.getHabboInfo().getGamePlayer().addScore(BattleBanzaiGame.POINTS_HIJACK_TILE);
}
this.refreshCounters(habbo.getHabboInfo().getGamePlayer().getTeamColor());
tile.setExtradata(state + "");
this.room.updateItem(tile);
}
2018-07-06 15:30:00 +02:00
}