You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-20 15:36:17 +00:00
🆙 Added Pets play ⚾️
- Max 5 Pets per room can play - Max 5 Pets per user in any room can play
This commit is contained in:
+12
@@ -159,4 +159,16 @@ public abstract class InteractionPushable extends InteractionDefault {
|
|||||||
|
|
||||||
public abstract boolean canStillMove(Room room, RoomTile from, RoomTile to, RoomUserRotation direction, RoomUnit kicker, int nextRoll, int currentStep, int totalSteps);
|
public abstract boolean canStillMove(Room room, RoomTile from, RoomTile to, RoomUserRotation direction, RoomUnit kicker, int nextRoll, int currentStep, int totalSteps);
|
||||||
|
|
||||||
|
public boolean isMoving() {
|
||||||
|
return this.currentThread != null && !this.currentThread.dead;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initiateKick(Room room, RoomUnit kicker, int velocity, RoomUserRotation direction) {
|
||||||
|
if (velocity <= 0) return;
|
||||||
|
if (this.currentThread != null)
|
||||||
|
this.currentThread.dead = true;
|
||||||
|
this.currentThread = new KickBallAction(this, room, kicker, direction, velocity, false);
|
||||||
|
Emulator.getThreading().run(this.currentThread, 0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+30
-1
@@ -7,6 +7,8 @@ import com.eu.habbo.habbohotel.items.Item;
|
|||||||
import com.eu.habbo.habbohotel.items.interactions.InteractionPushable;
|
import com.eu.habbo.habbohotel.items.interactions.InteractionPushable;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTeamItem;
|
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTeamItem;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoal;
|
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoal;
|
||||||
|
import com.eu.habbo.habbohotel.pets.Pet;
|
||||||
|
import com.eu.habbo.habbohotel.pets.PetTasks;
|
||||||
import com.eu.habbo.habbohotel.rooms.*;
|
import com.eu.habbo.habbohotel.rooms.*;
|
||||||
import com.eu.habbo.habbohotel.users.HabboItem;
|
import com.eu.habbo.habbohotel.users.HabboItem;
|
||||||
import com.eu.habbo.messages.outgoing.rooms.items.ItemStateComposer;
|
import com.eu.habbo.messages.outgoing.rooms.items.ItemStateComposer;
|
||||||
@@ -15,10 +17,13 @@ import com.eu.habbo.util.pathfinding.Rotation;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
|
||||||
public class InteractionFootball extends InteractionPushable {
|
public class InteractionFootball extends InteractionPushable {
|
||||||
|
|
||||||
|
public static final int MAX_FOOTBALL_PETS = 5;
|
||||||
|
|
||||||
public InteractionFootball(ResultSet set, Item baseItem) throws SQLException {
|
public InteractionFootball(ResultSet set, Item baseItem) throws SQLException {
|
||||||
super(set, baseItem);
|
super(set, baseItem);
|
||||||
}
|
}
|
||||||
@@ -194,6 +199,28 @@ public class InteractionFootball extends InteractionPushable {
|
|||||||
|
|
||||||
//Events
|
//Events
|
||||||
|
|
||||||
|
private void triggerPetFollowBall(Room room, RoomTile ballTile) {
|
||||||
|
if (ballTile == null) return;
|
||||||
|
|
||||||
|
Collection<Pet> pets = room.getUnitManager().getPets();
|
||||||
|
if (pets.isEmpty()) return;
|
||||||
|
|
||||||
|
for (Pet pet : pets) {
|
||||||
|
if (pet.getRoomUnit() == null) continue;
|
||||||
|
if (pet.getTask() == PetTasks.PLAY_FOOTBALL) {
|
||||||
|
pet.getRoomUnit().setGoalLocation(ballTile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void petKick(Room room, RoomUnit petUnit) {
|
||||||
|
if (isMoving()) return;
|
||||||
|
int velocity = this.getWalkOnVelocity(petUnit, room);
|
||||||
|
RoomUserRotation direction = this.getWalkOnDirection(petUnit, room);
|
||||||
|
this.onKick(room, petUnit, velocity, direction);
|
||||||
|
this.initiateKick(room, petUnit, velocity, direction);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDrag(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction) {
|
public void onDrag(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction) {
|
||||||
|
|
||||||
@@ -201,7 +228,7 @@ public class InteractionFootball extends InteractionPushable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onKick(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction) {
|
public void onKick(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction) {
|
||||||
|
triggerPetFollowBall(room, room.getLayout().getTile(this.getX(), this.getY()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -243,6 +270,8 @@ public class InteractionFootball extends InteractionPushable {
|
|||||||
public void onStop(Room room, RoomUnit kicker, int currentStep, int totalSteps) {
|
public void onStop(Room room, RoomUnit kicker, int currentStep, int totalSteps) {
|
||||||
this.setExtradata("0");
|
this.setExtradata("0");
|
||||||
room.sendComposer(new ItemStateComposer(this).compose());
|
room.sendComposer(new ItemStateComposer(this).compose());
|
||||||
|
|
||||||
|
triggerPetFollowBall(room, room.getLayout().getTile(this.getX(), this.getY()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.eu.habbo.habbohotel.pets;
|
|||||||
import com.eu.habbo.Emulator;
|
import com.eu.habbo.Emulator;
|
||||||
import com.eu.habbo.habbohotel.achievements.AchievementManager;
|
import com.eu.habbo.habbohotel.achievements.AchievementManager;
|
||||||
import com.eu.habbo.habbohotel.items.Item;
|
import com.eu.habbo.habbohotel.items.Item;
|
||||||
|
import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootball;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetToy;
|
import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetToy;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetTree;
|
import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetTree;
|
||||||
import com.eu.habbo.habbohotel.rooms.*;
|
import com.eu.habbo.habbohotel.rooms.*;
|
||||||
@@ -25,10 +26,12 @@ import java.sql.*;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class Pet implements ISerialize, Runnable {
|
public class Pet implements ISerialize, Runnable {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Pet.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(Pet.class);
|
||||||
|
|
||||||
|
public static final AtomicInteger GLOBAL_FOOTBALL_PET_COUNT = new AtomicInteger(0);
|
||||||
public int levelThirst;
|
public int levelThirst;
|
||||||
public int levelHunger;
|
public int levelHunger;
|
||||||
public boolean needsUpdate = false;
|
public boolean needsUpdate = false;
|
||||||
@@ -56,6 +59,7 @@ public class Pet implements ISerialize, Runnable {
|
|||||||
private int stayStartedAt = 0;
|
private int stayStartedAt = 0;
|
||||||
private int idleCommandTicks = 0;
|
private int idleCommandTicks = 0;
|
||||||
private int freeCommandTicks = -1;
|
private int freeCommandTicks = -1;
|
||||||
|
private InteractionFootball cachedBall = null;
|
||||||
|
|
||||||
// Command cooldown tracking to prevent spam
|
// Command cooldown tracking to prevent spam
|
||||||
private int lastCommandId = -1;
|
private int lastCommandId = -1;
|
||||||
@@ -321,6 +325,10 @@ public class Pet implements ISerialize, Runnable {
|
|||||||
this.task = null;
|
this.task = null;
|
||||||
this.getRoomUnit().setCanWalk(true);
|
this.getRoomUnit().setCanWalk(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.task == PetTasks.PLAY_FOOTBALL) {
|
||||||
|
this.chaseBall();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int timeout = Emulator.getRandom().nextInt(10) * 2;
|
int timeout = Emulator.getRandom().nextInt(10) * 2;
|
||||||
this.roomUnit.setWalkTimeOut(timeout < 20 ? 20 + time : timeout + time);
|
this.roomUnit.setWalkTimeOut(timeout < 20 ? 20 + time : timeout + time);
|
||||||
@@ -389,11 +397,66 @@ public class Pet implements ISerialize, Runnable {
|
|||||||
this.getRoomUnit().setCanWalk(true);
|
this.getRoomUnit().setCanWalk(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.task == PetTasks.PLAY_FOOTBALL) {
|
||||||
|
this.setTask(null);
|
||||||
|
this.getRoomUnit().setCanWalk(true);
|
||||||
|
}
|
||||||
|
|
||||||
command.handle(this, habbo, data);
|
command.handle(this, habbo, data);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void chaseBall() {
|
||||||
|
RoomTile petTile = this.roomUnit.getCurrentLocation();
|
||||||
|
if (petTile == null) {
|
||||||
|
this.setTask(PetTasks.FREE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.cachedBall != null && this.cachedBall.getRoomId() != this.room.getId()) {
|
||||||
|
this.cachedBall = null;
|
||||||
|
this.setTask(PetTasks.FREE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.cachedBall != null && this.cachedBall.isMoving()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.cachedBall == null) {
|
||||||
|
InteractionFootball nearest = null;
|
||||||
|
double nearestDistance = Double.MAX_VALUE;
|
||||||
|
for (HabboItem item : this.room.getFloorItems()) {
|
||||||
|
if (item instanceof InteractionFootball ball) {
|
||||||
|
RoomTile ballTile = this.room.getLayout().getTile(ball.getX(), ball.getY());
|
||||||
|
if (ballTile != null) {
|
||||||
|
double dist = petTile.distance(ballTile);
|
||||||
|
if (dist < nearestDistance) {
|
||||||
|
nearestDistance = dist;
|
||||||
|
nearest = ball;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nearest == null) {
|
||||||
|
// No ball in room — stop playing
|
||||||
|
this.setTask(PetTasks.FREE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.cachedBall = nearest;
|
||||||
|
}
|
||||||
|
|
||||||
|
RoomTile ballTile = this.room.getLayout().getTile(this.cachedBall.getX(), this.cachedBall.getY());
|
||||||
|
if (RoomLayout.tilesAdjecent(petTile, ballTile)) {
|
||||||
|
// Adjacent — kick the ball
|
||||||
|
this.cachedBall.petKick(this.room, this.roomUnit);
|
||||||
|
} else {
|
||||||
|
// Still walking toward the ball
|
||||||
|
this.roomUnit.setGoalLocation(ballTile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean canWalk() {
|
public boolean canWalk() {
|
||||||
if (this.task == null)
|
if (this.task == null)
|
||||||
return true;
|
return true;
|
||||||
@@ -506,7 +569,7 @@ public class Pet implements ISerialize, Runnable {
|
|||||||
} else {
|
} else {
|
||||||
this.roomUnit.setStatus(RoomUnitStatus.LAY, this.room.getStackHeight(this.roomUnit.getX(), this.roomUnit.getY(), false) + "");
|
this.roomUnit.setStatus(RoomUnitStatus.LAY, this.room.getStackHeight(this.roomUnit.getX(), this.roomUnit.getY(), false) + "");
|
||||||
this.say(this.petData.randomVocal(PetVocalsType.SLEEPING));
|
this.say(this.petData.randomVocal(PetVocalsType.SLEEPING));
|
||||||
this.task = PetTasks.DOWN;
|
this.setTask(PetTasks.DOWN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -706,7 +769,7 @@ public class Pet implements ISerialize, Runnable {
|
|||||||
|
|
||||||
|
|
||||||
public void freeCommand() {
|
public void freeCommand() {
|
||||||
this.task = null;
|
this.setTask(null);
|
||||||
this.roomUnit.setGoalLocation(this.getRoomUnit().getCurrentLocation());
|
this.roomUnit.setGoalLocation(this.getRoomUnit().getCurrentLocation());
|
||||||
this.roomUnit.clearStatus();
|
this.roomUnit.clearStatus();
|
||||||
this.roomUnit.setCanWalk(true);
|
this.roomUnit.setCanWalk(true);
|
||||||
@@ -840,6 +903,12 @@ public class Pet implements ISerialize, Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setTask(PetTasks newTask) {
|
public void setTask(PetTasks newTask) {
|
||||||
|
if (this.task == PetTasks.PLAY_FOOTBALL && newTask != PetTasks.PLAY_FOOTBALL) {
|
||||||
|
GLOBAL_FOOTBALL_PET_COUNT.decrementAndGet();
|
||||||
|
this.cachedBall = null; // release cached ball reference
|
||||||
|
} else if (this.task != PetTasks.PLAY_FOOTBALL && newTask == PetTasks.PLAY_FOOTBALL) {
|
||||||
|
GLOBAL_FOOTBALL_PET_COUNT.incrementAndGet();
|
||||||
|
}
|
||||||
this.task = newTask;
|
this.task = newTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ public class PetCommand implements Comparable<PetCommand> {
|
|||||||
|
|
||||||
if (Emulator.getRandom().nextInt(100) >= obeyChance) {
|
if (Emulator.getRandom().nextInt(100) >= obeyChance) {
|
||||||
pet.say(pet.getPetData().randomVocal(PetVocalsType.DISOBEY));
|
pet.say(pet.getPetData().randomVocal(PetVocalsType.DISOBEY));
|
||||||
pet.recordCommandExecution(this.id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-3
@@ -1,6 +1,7 @@
|
|||||||
package com.eu.habbo.habbohotel.pets.actions;
|
package com.eu.habbo.habbohotel.pets.actions;
|
||||||
|
|
||||||
import com.eu.habbo.habbohotel.items.interactions.InteractionPushable;
|
import com.eu.habbo.habbohotel.items.interactions.InteractionPushable;
|
||||||
|
import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootball;
|
||||||
import com.eu.habbo.habbohotel.pets.Pet;
|
import com.eu.habbo.habbohotel.pets.Pet;
|
||||||
import com.eu.habbo.habbohotel.pets.PetAction;
|
import com.eu.habbo.habbohotel.pets.PetAction;
|
||||||
import com.eu.habbo.habbohotel.pets.PetTasks;
|
import com.eu.habbo.habbohotel.pets.PetTasks;
|
||||||
@@ -9,6 +10,7 @@ import com.eu.habbo.habbohotel.rooms.Room;
|
|||||||
import com.eu.habbo.habbohotel.rooms.RoomTile;
|
import com.eu.habbo.habbohotel.rooms.RoomTile;
|
||||||
import com.eu.habbo.habbohotel.users.Habbo;
|
import com.eu.habbo.habbohotel.users.Habbo;
|
||||||
import com.eu.habbo.habbohotel.users.HabboItem;
|
import com.eu.habbo.habbohotel.users.HabboItem;
|
||||||
|
import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer;
|
||||||
|
|
||||||
public class ActionPlayFootball extends PetAction {
|
public class ActionPlayFootball extends PetAction {
|
||||||
public ActionPlayFootball() {
|
public ActionPlayFootball() {
|
||||||
@@ -27,7 +29,15 @@ public class ActionPlayFootball extends PetAction {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the nearest ball to the pet
|
if (pet.getTask() != PetTasks.PLAY_FOOTBALL
|
||||||
|
&& Pet.GLOBAL_FOOTBALL_PET_COUNT.get() >= InteractionFootball.MAX_FOOTBALL_PETS) {
|
||||||
|
if (habbo != null && habbo.getClient() != null) {
|
||||||
|
habbo.getClient().sendResponse(new GenericAlertComposer(
|
||||||
|
"Sorry, you already have 5 pets playing football in the rooms"));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
HabboItem nearestBall = null;
|
HabboItem nearestBall = null;
|
||||||
double nearestDistance = Double.MAX_VALUE;
|
double nearestDistance = Double.MAX_VALUE;
|
||||||
RoomTile petTile = pet.getRoomUnit().getCurrentLocation();
|
RoomTile petTile = pet.getRoomUnit().getCurrentLocation();
|
||||||
@@ -50,12 +60,10 @@ public class ActionPlayFootball extends PetAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nearestBall == null) {
|
if (nearestBall == null) {
|
||||||
// No ball in room - disobey
|
|
||||||
pet.say(pet.getPetData().randomVocal(PetVocalsType.DISOBEY));
|
pet.say(pet.getPetData().randomVocal(PetVocalsType.DISOBEY));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set task and pathfind to the ball
|
|
||||||
pet.setTask(PetTasks.PLAY_FOOTBALL);
|
pet.setTask(PetTasks.PLAY_FOOTBALL);
|
||||||
pet.getRoomUnit().setCanWalk(true);
|
pet.getRoomUnit().setCanWalk(true);
|
||||||
pet.getRoomUnit().setGoalLocation(room.getLayout().getTile(nearestBall.getX(), nearestBall.getY()));
|
pet.getRoomUnit().setGoalLocation(room.getLayout().getTile(nearestBall.getX(), nearestBall.getY()));
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user