Skip to content

Commit

Permalink
Fix issue #337: Displacement
Browse files Browse the repository at this point in the history
  • Loading branch information
openhands-agent committed Jan 28, 2025
1 parent 697b6d4 commit 000057b
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
81 changes: 81 additions & 0 deletions app/src/libs/combat/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,87 @@ export const lifesteal = (
* 2. Add user to any new ground effect
* 3. Move user
*/
export const displacement = (
effect: UserEffect,
usersEffects: UserEffect[],
usersState: BattleUserState[],
groundEffects: GroundEffect[],
) => {
const target = usersState.find((u) => u.userId === effect.targetId);
const user = usersState.find((u) => u.userId === effect.creatorId);
let info: ActionEffect | undefined = undefined;

if (target && user) {
// Prevent?
const { pass } = preventCheck(usersEffects, "moveprevent", target);
if (!pass) return preventResponse(effect, target, "resisted being displaced");

// Find an empty ground position
const occupiedPositions = new Set(
usersState.map((u) => `${u.latitude},${u.longitude}`)
);

// Try positions in a spiral pattern around the target
const dx = [0, 1, 0, -1]; // right, down, left, up
const dy = [1, 0, -1, 0];
let x = target.longitude;
let y = target.latitude;
let layer = 1;
let found = false;

while (layer <= 5 && !found) { // Try up to 5 layers out
for (let direction = 0; direction < 4; direction++) {
for (let step = 0; step < layer; step++) {
x += dx[direction];
y += dy[direction];

if (!occupiedPositions.has(`${y},${x}`)) {
// Found an empty spot
// Update movement information
info = {
txt: `${user.username} displaces ${target.username} to [${y}, ${x}]`,
color: "blue",
};

// Handle ground effects
groundEffects.forEach((g) => {
if (g.timeTracker && target.userId in g.timeTracker) {
delete g.timeTracker[target.userId];
}
});

groundEffects.forEach((g) => {
if (
g.timeTracker &&
g.longitude === x &&
g.latitude === y
) {
g.timeTracker[target.userId] = effect.createdRound;
}
});

// Update target location
target.longitude = x;
target.latitude = y;
found = true;
break;
}
}
if (found) break;
}
layer++;
}

if (!found) {
info = {
txt: `${user.username} failed to displace ${target.username} - no empty ground found`,
color: "red",
};
}
}
return info;
};

export const move = (
effect: GroundEffect,
usersEffects: UserEffect[],
Expand Down
10 changes: 10 additions & 0 deletions app/src/libs/combat/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,15 @@ export const MoveTag = z.object({

export type MoveTagType = z.infer<typeof MoveTag>;

export const DisplacementTag = z.object({
...BaseAttributes,
...PowerAttributes,
type: z.literal("displacement").default("displacement"),
description: msg("Move target to an empty ground"),
});

export type DisplacementTagType = z.infer<typeof DisplacementTag>;

export const MovePreventTag = z.object({
...BaseAttributes,
...PowerAttributes,
Expand Down Expand Up @@ -702,6 +711,7 @@ export const AllTags = z.union([
LifeStealTag.default({}),
MoveTag.default({}),
MovePreventTag.default({}),
DisplacementTag.default({}),
OneHitKillPreventTag.default({}),
OneHitKillTag.default({}),
PierceTag.default({}),
Expand Down
1 change: 1 addition & 0 deletions app/src/libs/combat/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ export const sortEffects = (
"increaseheal",
// End-modifiers
"move",
"displacement",
"visual",
];
if (ordered.includes(a.type) && ordered.includes(b.type)) {
Expand Down

0 comments on commit 000057b

Please sign in to comment.