Skip to content

Commit fe54b11

Browse files
georgeglarsonclaude
andcommitted
Fix combat diagonal stuck state, equipment level regression, and minor bugs
- Fix player getting stuck diagonally adjacent to mobs (no diagonal correction existed for the player, only for mobs targeting players) - Sync SLOT_CONFIG with gametypes rankedWeapons/rankedArmors — all dimension, set, and legendary items were falling back to level 1 (Soul Harvester hitting like Sword1, Hellfire Mantle = Cloth Armor) - Fix Population message using || instead of ?? (total=0 incorrectly fell back to world count) - Clear hurt timeout on entity cleanup to prevent stale sprite updates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 85a49ae commit fe54b11

7 files changed

Lines changed: 58 additions & 23 deletions

File tree

client/ts/entity/character/character.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export class Character extends Entity {
7878
attacker.disengage();
7979
attacker.idle();
8080
});
81+
this.stopHurting();
8182
}
8283

8384
setMaxHitPoints(hp) {

client/ts/game.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,10 +1323,16 @@ export class Game {
13231323
}
13241324
} else {
13251325
if (character.hasTarget()
1326-
&& character.isDiagonallyAdjacent(character.target)
1327-
&& character.target instanceof Player
1328-
&& !character.target.isMoving()) {
1329-
character.follow(character.target);
1326+
&& character.isDiagonallyAdjacent(character.target)) {
1327+
if (character.target instanceof Player
1328+
&& !character.target.isMoving()) {
1329+
// Mob is diagonally adjacent to player — move to cardinal position
1330+
character.follow(character.target);
1331+
} else if (character.id === this.playerId
1332+
&& !character.isMoving()) {
1333+
// Player is diagonally adjacent to mob — move to cardinal position
1334+
character.follow(character.target);
1335+
}
13301336
}
13311337
}
13321338
}

server/ts/__tests__/equipment-manager.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ describe('EquipmentManager', () => {
111111

112112
it('armorLevel should increase after equipping better armor', () => {
113113
mgr.equip(Types.Entities.PLATEARMOR);
114-
// PLATEARMOR is index 3 in SLOT_CONFIG armor rankedItems => level 4
115-
expect(mgr.armorLevel).toBe(4);
114+
// PLATEARMOR is index 5 in SLOT_CONFIG armor rankedItems => level 6
115+
expect(mgr.armorLevel).toBe(6);
116116
});
117117
});
118118

@@ -169,8 +169,8 @@ describe('EquipmentManager', () => {
169169

170170
it('should update the level when equipping a new item', () => {
171171
mgr.equip(Types.Entities.GOLDENSWORD);
172-
// GOLDENSWORD is index 6 in SLOT_CONFIG weapon rankedItems => level 7
173-
expect(mgr.getLevel('weapon')).toBe(7);
172+
// GOLDENSWORD is index 14 in SLOT_CONFIG weapon rankedItems => level 15
173+
expect(mgr.getLevel('weapon')).toBe(15);
174174
});
175175

176176
it('should mark slot as non-default after equipping a non-default item', () => {

server/ts/__tests__/equipment.handler.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ describe('EquipmentHandler', () => {
184184

185185
it('should update armor level after equipping', () => {
186186
equipArmor(ctx, Types.Entities.PLATEARMOR);
187-
// PLATEARMOR is index 3 in rankedItems => level 4
188-
expect(ctx.getEquipment().armorLevel).toBe(4);
187+
// PLATEARMOR is index 5 in rankedItems => level 6
188+
expect(ctx.getEquipment().armorLevel).toBe(6);
189189
});
190190

191191
it('should not affect weapon slot', () => {
@@ -219,8 +219,8 @@ describe('EquipmentHandler', () => {
219219

220220
it('should update weapon level after equipping', () => {
221221
equipWeapon(ctx, Types.Entities.GOLDENSWORD);
222-
// GOLDENSWORD is index 6 in rankedItems => level 7
223-
expect(ctx.getEquipment().weaponLevel).toBe(7);
222+
// GOLDENSWORD is index 14 in rankedItems => level 15
223+
expect(ctx.getEquipment().weaponLevel).toBe(15);
224224
});
225225

226226
it('should not affect armor slot', () => {
@@ -535,8 +535,8 @@ describe('EquipmentHandler', () => {
535535

536536
it('getArmorLevel should reflect equipped armor rank', () => {
537537
equipArmor(ctx, Types.Entities.REDARMOR);
538-
// REDARMOR is index 4 => level 5
539-
expect(getArmorLevel(ctx)).toBe(5);
538+
// REDARMOR is index 7 => level 8
539+
expect(getArmorLevel(ctx)).toBe(8);
540540
});
541541
});
542542

server/ts/__tests__/message.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,10 +400,10 @@ describe('Messages.Population', () => {
400400
expect(msg.serialize()).toEqual([Types.Messages.POPULATION, 15, 15]);
401401
});
402402

403-
it('should fall back total to world count when total is 0 (falsy)', () => {
403+
it('should use total=0 correctly instead of falling back', () => {
404404
const msg = new Messages.Population(5, 0);
405-
// Because of `this.total || this.world`, total=0 is falsy, falls back to world
406-
expect(msg.serialize()).toEqual([Types.Messages.POPULATION, 5, 5]);
405+
// total=0 is a valid value (no players), should not fall back to world count
406+
expect(msg.serialize()).toEqual([Types.Messages.POPULATION, 5, 0]);
407407
});
408408

409409
it('should handle world count of 0', () => {

server/ts/message.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,9 @@ export const Messages = {
156156
}
157157

158158
serialize(): unknown[] {
159-
// Hacked this
160-
// Made total prop optional
161-
// Added condition to fallbac to world count
162159
return [Types.Messages.POPULATION,
163160
this.world,
164-
this.total || this.world];
161+
this.total ?? this.world];
165162
}
166163
},
167164

shared/ts/equipment/equipment-types.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,28 @@ export const SLOT_CONFIG: Record<EquipmentSlot, SlotConfig> = {
3737
Types.Entities.SWORD1,
3838
Types.Entities.SWORD2,
3939
Types.Entities.AXE,
40+
Types.Entities.TEC9,
4041
Types.Entities.MORNINGSTAR,
42+
Types.Entities.MP5,
43+
Types.Entities.RAYGUN,
4144
Types.Entities.BLUESWORD,
45+
Types.Entities.TENTACLE,
46+
Types.Entities.LASERGUN,
4247
Types.Entities.REDSWORD,
43-
Types.Entities.GOLDENSWORD
48+
Types.Entities.CRYSTALSTAFF,
49+
Types.Entities.VOIDBLADE,
50+
Types.Entities.PLASMAHELIX,
51+
Types.Entities.GOLDENSWORD,
52+
// Set Weapons (high tier)
53+
Types.Entities.BERSERKER_BLADE,
54+
Types.Entities.GUARDIAN_HAMMER,
55+
Types.Entities.SHADOW_DAGGER,
56+
Types.Entities.DRAGON_SWORD,
57+
// Legendary Weapons (boss-only drops, highest tier)
58+
Types.Entities.GREEDS_EDGE,
59+
Types.Entities.DRAGONBONE_CLEAVER,
60+
Types.Entities.VOIDHEART_BLADE,
61+
Types.Entities.SOUL_HARVESTER
4462
],
4563
defaultItem: Types.Entities.SWORD1,
4664
affectsHP: false,
@@ -50,10 +68,23 @@ export const SLOT_CONFIG: Record<EquipmentSlot, SlotConfig> = {
5068
rankedItems: [
5169
Types.Entities.CLOTHARMOR,
5270
Types.Entities.LEATHERARMOR,
71+
Types.Entities.HAZMATSUIT,
5372
Types.Entities.MAILARMOR,
73+
Types.Entities.VOIDCLOAK,
5474
Types.Entities.PLATEARMOR,
75+
Types.Entities.SHIELDBUBBLE,
5576
Types.Entities.REDARMOR,
56-
Types.Entities.GOLDENARMOR
77+
Types.Entities.CRYSTALSHELL,
78+
Types.Entities.MECHARMOR,
79+
Types.Entities.GOLDENARMOR,
80+
// Set Armors (high tier)
81+
Types.Entities.BERSERKER_MAIL,
82+
Types.Entities.GUARDIAN_PLATE,
83+
Types.Entities.SHADOW_CLOAK,
84+
Types.Entities.DRAGON_SCALE,
85+
// Legendary Armors (boss-only drops, highest tier)
86+
Types.Entities.CROWN_UNDYING,
87+
Types.Entities.HELLFIRE_MANTLE
5788
],
5889
defaultItem: Types.Entities.CLOTHARMOR,
5990
affectsHP: true,

0 commit comments

Comments
 (0)