Merge pull request #8 from duckietm/Dev

Dev
This commit is contained in:
DuckieTM
2026-03-16 12:43:04 +01:00
committed by GitHub
7 changed files with 274 additions and 1 deletions
@@ -49,4 +49,20 @@ public class RoomUserPetComposer extends MessageComposer {
this.response.appendString("");
return this.response;
}
public int getPetType() {
return petType;
}
public int getRace() {
return race;
}
public String getColor() {
return color;
}
public Habbo getHabbo() {
return habbo;
}
}
@@ -15,7 +15,7 @@ public class AboutCommand extends Command {
}
public static String credits = "Arcturus Morningstar is an opensource project based on Arcturus By TheGeneral \n" +
"The Following people have all contributed to this emulator:\n" +
"TheGeneral\n Beny\n Alejandro\n Capheus\n Skeletor\n Harmonic\n Mike\n Remco\n zGrav \n Quadral \n Harmony\n Swirny\n ArpyAge\n Mikkel\n Rodolfo\n Rasmus\n Kitt Mustang\n Snaiker\n nttzx\n necmi\n Dome\n Jose Flores\n Cam\n Oliver\n Narzo\n Tenshie\n MartenM\n Ridge\n SenpaiDipper\n Snaiker\n Thijmen\n DuckieTM\n Medievalshell\n Lorenzune";
"TheGeneral\n Beny\n Alejandro\n Capheus\n Skeletor\n Harmonic\n Mike\n Remco\n zGrav \n Quadral \n Harmony\n Swirny\n ArpyAge\n Mikkel\n Rodolfo\n Rasmus\n Kitt Mustang\n Snaiker\n nttzx\n necmi\n Dome\n Jose Flores\n Cam\n Oliver\n Narzo\n Tenshie\n MartenM\n Ridge\n SenpaiDipper\n Snaiker\n Thijmen\n DuckieTM\n simoleo89\n Medievalshell\n Lorenzune";
@Override
public boolean handle(GameClient gameClient, String[] params) {
@@ -17,6 +17,7 @@ import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards
import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards.InteractionBattleBanzaiScoreboardYellow;
import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootball;
import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootballGate;
import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionRebugFootball;
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalBlue;
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalGreen;
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalRed;
@@ -344,6 +345,7 @@ public class ItemManager {
this.interactionsList.add(new ItemInteraction("football", InteractionFootball.class));
this.interactionsList.add(new ItemInteraction("rebug_football", InteractionRebugFootball.class));
this.interactionsList.add(new ItemInteraction("football_gate", InteractionFootballGate.class));
this.interactionsList.add(new ItemInteraction("football_counter_blue", InteractionFootballScoreboardBlue.class));
this.interactionsList.add(new ItemInteraction("football_counter_green", InteractionFootballScoreboardGreen.class));
@@ -0,0 +1,54 @@
package com.eu.habbo.habbohotel.items.interactions.games.football;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.items.interactions.InteractionDefault;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.threading.runnables.RebugKickBallAction;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Rebug-style football interaction.
* Uses simplified momentum-decay physics with 180-degree bounce.
* Set interaction_type to "rebug_football" on a ball item to use this instead of the default football physics.
*/
public class InteractionRebugFootball extends InteractionDefault {
private RebugKickBallAction currentThread;
public InteractionRebugFootball(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
this.setExtradata("0");
}
public InteractionRebugFootball(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
this.setExtradata("0");
}
@Override
public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) {
return true;
}
@Override
public boolean isWalkable() {
return true;
}
@Override
public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception {
super.onWalkOn(roomUnit, room, objects);
if (this.currentThread != null) {
this.currentThread.dead = true;
}
boolean hasPath = !roomUnit.getPath().isEmpty();
this.currentThread = new RebugKickBallAction(this, room, roomUnit, hasPath);
Emulator.getThreading().run(this.currentThread, 50);
}
}
@@ -0,0 +1,106 @@
package com.eu.habbo.threading.runnables;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomTile;
import com.eu.habbo.habbohotel.rooms.RoomTileState;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer;
import com.eu.habbo.util.pathfinding.Direction8;
import gnu.trove.set.hash.THashSet;
/**
* Alternative football physics based on the Rebug plugin.
* Uses momentum decay (ball slows down over time) and simple 180-degree bounce.
*/
public class RebugKickBallAction implements Runnable {
private final HabboItem ball;
private final Room room;
private Direction8 direction;
private int momentum;
public boolean dead = false;
public RebugKickBallAction(HabboItem ball, Room room, RoomUnit kicker, boolean hasPath) {
this.ball = ball;
this.room = room;
this.direction = Direction8.fromDelta(
ball.getX() - kicker.getX(),
ball.getY() - kicker.getY()
);
this.momentum = hasPath ? 55 : 0;
}
private boolean isTileBlocked(int x, int y) {
RoomTile tile = this.room.getLayout().getTile((short) x, (short) y);
if (tile == null) return true;
if (tile.hasUnits()) return true;
return tile.getState() != RoomTileState.OPEN;
}
@Override
public void run() {
if (this.dead || !this.room.isLoaded()) return;
try {
int nextX = this.ball.getX() + this.direction.getDiffX();
int nextY = this.ball.getY() + this.direction.getDiffY();
if (isTileBlocked(nextX, nextY)) {
this.direction = this.direction.rotateDirection180Degrees();
nextX = this.ball.getX() + this.direction.getDiffX();
nextY = this.ball.getY() + this.direction.getDiffY();
}
RoomTile nextTile = this.room.getLayout().getTile((short) nextX, (short) nextY);
if (nextTile == null) return;
RoomTile oldTile = this.room.getLayout().getTile(this.ball.getX(), this.ball.getY());
double oldZ = this.ball.getZ();
this.ball.setRotation(this.direction.getRot());
this.ball.setX(nextTile.x);
this.ball.setY(nextTile.y);
this.ball.setZ(nextTile.getStackHeight());
this.ball.needsUpdate(true);
// Schedule next movement based on momentum
long delay = getDelayForMomentum(this.momentum);
if (delay > 0) {
Emulator.getThreading().run(this, delay);
}
// Update tiles
this.room.updateTile(oldTile);
this.room.updateTile(nextTile);
THashSet<HabboItem> oldItems = this.room.getItemsAt(oldTile);
if (oldItems != null && !oldItems.isEmpty()) {
oldItems.remove(this.ball);
}
this.room.getItemsAt(nextTile).add(this.ball);
// Send rolling animation
this.room.sendComposer(new FloorItemOnRollerComposer(
this.ball, null, oldTile, oldZ, nextTile, this.ball.getZ(), 0.0D, this.room
).compose());
// Decay momentum
this.momentum -= 11;
} catch (Exception e) {
this.dead = true;
}
}
private long getDelayForMomentum(int momentum) {
switch (momentum) {
case 55: return 100L;
case 44: return 100L;
case 33: return 200L;
case 22: return 250L;
case 11: return 500L;
default: return 0L;
}
}
}
@@ -0,0 +1,95 @@
package com.eu.habbo.util.pathfinding;
/**
* 8-directional movement utility for ball physics.
* Ported from the Rebug soccer plugin.
*/
public class Direction8 {
public static final Direction8[] DIRECTIONS = new Direction8[8];
public static final Direction8 N = new Direction8(0, "N", 0, -1);
public static final Direction8 NE = new Direction8(1, "NE", 1, -1);
public static final Direction8 E = new Direction8(2, "E", 1, 0);
public static final Direction8 SE = new Direction8(3, "SE", 1, 1);
public static final Direction8 S = new Direction8(4, "S", 0, 1);
public static final Direction8 SW = new Direction8(5, "SW", -1, 1);
public static final Direction8 W = new Direction8(6, "W", -1, 0);
public static final Direction8 NW = new Direction8(7, "NW", -1, -1);
private final int rot;
private final String rotName;
private final int xDiff;
private final int yDiff;
public Direction8(int rot, String rotName, int diffX, int diffY) {
this.rot = rot;
this.rotName = rotName;
this.xDiff = diffX;
this.yDiff = diffY;
DIRECTIONS[rot] = this;
}
public static Direction8 fromDelta(int deltaX, int deltaY) {
if (deltaX == 0) {
if (deltaY < 0) return N;
if (deltaY > 0) return S;
}
if (deltaX > 0) {
if (deltaY < 0) return NE;
if (deltaY == 0) return E;
if (deltaY > 0) return SE;
}
if (deltaX < 0) {
if (deltaY < 0) return NW;
if (deltaY == 0) return W;
if (deltaY > 0) return SW;
}
return N;
}
public static Direction8 getDirection(int dir) {
if (dir < 0 || dir > 7) return N;
return DIRECTIONS[dir];
}
public static int validateDirection8Value(int dir) {
return dir & 0x7;
}
public int getRot() {
return this.rot;
}
public String getRotName() {
return this.rotName;
}
public int getDiffX() {
return this.xDiff;
}
public int getDiffY() {
return this.yDiff;
}
public Direction8 rotateDirection180Degrees() {
return getDirectionAtRot(4);
}
public Direction8 rotateDirection90Degrees(boolean clockwise) {
return getDirectionAtRot(clockwise ? 2 : -2);
}
public Direction8 rotateDirection45Degrees(boolean clockwise) {
return getDirectionAtRot(clockwise ? 1 : -1);
}
public Direction8 getDirectionAtRot(int diff) {
return DIRECTIONS[validateDirection8Value(this.rot + diff)];
}
@Override
public String toString() {
return this.rotName + "(" + this.rot + ")";
}
}