Android build v1.1.22

This commit is contained in:
Warren H
2026-07-05 12:08:11 -04:00
parent 547044892d
commit 956c9e32f9
69 changed files with 9259 additions and 196 deletions
+166 -26
View File
@@ -15,6 +15,10 @@ const MAX_FIRE_PUDDLES = 8
const FIRE_PUDDLE_TICK_SECONDS = 0.55
const FIRE_PUDDLE_FADE_SECONDS = 0.8
const FIRE_PUDDLE_MERGE_DISTANCE = 28
const MAX_POISON_PUDDLES = 6
const MAX_MUD_PUDDLES = 7
const MUD_PUDDLE_TICK_SECONDS = 0.22
const MUD_SLOW_SECONDS = 0.5
export function addFirePuddle({
damage,
@@ -34,9 +38,115 @@ export function addFirePuddle({
radius: number
sourceId: Iwt2EntityId
time: number
}): { hazards: Iwt2GroundHazardState[], nextHazardId: number } {
return addGroundPuddle({
damage,
duration,
fadeSeconds: FIRE_PUDDLE_FADE_SECONDS,
hazardKind: 'firePuddle',
hazards,
maxActive: MAX_FIRE_PUDDLES,
nextHazardId,
position,
radius,
sourceId,
time,
})
}
export function addPoisonPuddle({
damage,
duration,
hazards,
nextHazardId,
position,
radius,
sourceId,
time,
}: {
damage: number
duration: number
hazards: Iwt2GroundHazardState[]
nextHazardId: number
position: Iwt2Vec2
radius: number
sourceId: Iwt2EntityId
time: number
}): { hazards: Iwt2GroundHazardState[], nextHazardId: number } {
return addGroundPuddle({
damage,
duration,
fadeSeconds: 1,
hazardKind: 'poisonPuddle',
hazards,
maxActive: MAX_POISON_PUDDLES,
nextHazardId,
position,
radius,
sourceId,
time,
})
}
export function addMudPuddle({
duration,
hazards,
nextHazardId,
position,
radius,
sourceId,
time,
}: {
duration: number
hazards: Iwt2GroundHazardState[]
nextHazardId: number
position: Iwt2Vec2
radius: number
sourceId: Iwt2EntityId
time: number
}): { hazards: Iwt2GroundHazardState[], nextHazardId: number } {
return addGroundPuddle({
damage: 0,
duration,
fadeSeconds: 0.9,
hazardKind: 'mudPuddle',
hazards,
maxActive: MAX_MUD_PUDDLES,
nextHazardId,
position,
radius,
sourceId,
time,
})
}
function addGroundPuddle({
damage,
duration,
fadeSeconds,
hazardKind,
hazards,
maxActive,
nextHazardId,
position,
radius,
sourceId,
time,
}: {
damage: number
duration: number
fadeSeconds: number
hazardKind: Iwt2GroundHazardState['hazardKind']
hazards: Iwt2GroundHazardState[]
maxActive: number
nextHazardId: number
position: Iwt2Vec2
radius: number
sourceId: Iwt2EntityId
time: number
}): { hazards: Iwt2GroundHazardState[], nextHazardId: number } {
const overlappingIndex = hazards.findIndex((hazard) => (
hazard.hazardKind === 'firePuddle'
hazard.hazardKind === hazardKind
&& hazard.remainingSeconds > hazard.fadeSeconds
&& Math.hypot(hazard.position.x - position.x, hazard.position.y - position.y) <= FIRE_PUDDLE_MERGE_DISTANCE
))
@@ -59,19 +169,19 @@ export function addFirePuddle({
}
const nextHazard: Iwt2GroundHazardState = {
id: `fire-puddle-${nextHazardId}`,
id: `${hazardKind}-${nextHazardId}`,
kind: 'groundHazard',
hazardKind: 'firePuddle',
hazardKind,
sourceId,
position: { ...position },
radius,
damage,
remainingSeconds: duration,
fadeSeconds: FIRE_PUDDLE_FADE_SECONDS,
fadeSeconds,
nextDamageAt: time + 0.12,
}
return {
hazards: capFirePuddles([...hazards, nextHazard]),
hazards: capPuddles([...hazards, nextHazard], hazardKind, maxActive),
nextHazardId: nextHazardId + 1,
}
}
@@ -101,22 +211,27 @@ export function tickGroundHazards({
let nextDamageAt = hazard.nextDamageAt
if (time >= hazard.nextDamageAt) {
const result = applyPartyDamageInShape(
nextParty,
{
kind: 'circle',
position: hazard.position,
radius: hazard.radius,
},
{
damage: hazard.damage,
sourceId: hazard.sourceId,
time,
},
)
nextParty = result.party
events.push(...result.events)
nextDamageAt = time + FIRE_PUDDLE_TICK_SECONDS
if (hazard.hazardKind === 'mudPuddle') {
nextParty = applyMudSlow(nextParty, hazard)
nextDamageAt = time + MUD_PUDDLE_TICK_SECONDS
} else {
const result = applyPartyDamageInShape(
nextParty,
{
kind: 'circle',
position: hazard.position,
radius: hazard.radius,
},
{
damage: hazard.damage,
sourceId: hazard.sourceId,
time,
},
)
nextParty = result.party
events.push(...result.events)
nextDamageAt = time + FIRE_PUDDLE_TICK_SECONDS
}
}
nextHazards.push({
@@ -135,9 +250,9 @@ export function tickGroundHazards({
export function createHazardIndicators(hazards: Iwt2GroundHazardState[]): Iwt2ArenaIndicator[] {
return hazards.map((hazard) => createCircleIndicator({
color: '#ff7a2f',
color: hazardColor(hazard),
id: `${hazard.id}:indicator`,
mechanicId: 'fire-puddle',
mechanicId: hazard.hazardKind,
phase: hazard.remainingSeconds <= hazard.fadeSeconds ? 'recover' : 'active',
position: hazard.position,
radius: hazard.radius,
@@ -145,16 +260,41 @@ export function createHazardIndicators(hazards: Iwt2GroundHazardState[]): Iwt2Ar
}))
}
function capFirePuddles(hazards: Iwt2GroundHazardState[]): Iwt2GroundHazardState[] {
function applyMudSlow(party: Iwt2PartyEntityState[], hazard: Iwt2GroundHazardState): Iwt2PartyEntityState[] {
return party.map((member) => {
if (member.health <= 0) return member
const distance = Math.hypot(member.position.x - hazard.position.x, member.position.y - hazard.position.y)
if (distance > hazard.radius + member.radius) return member
return {
...member,
status: {
...member.status,
slowedSeconds: Math.max(member.status.slowedSeconds, MUD_SLOW_SECONDS),
},
}
})
}
function hazardColor(hazard: Iwt2GroundHazardState): string {
if (hazard.hazardKind === 'poisonPuddle') return '#7bd84f'
if (hazard.hazardKind === 'mudPuddle') return '#9a6a3a'
return '#ff7a2f'
}
function capPuddles(
hazards: Iwt2GroundHazardState[],
hazardKind: Iwt2GroundHazardState['hazardKind'],
maxActive: number,
): Iwt2GroundHazardState[] {
let activePuddles = 0
let oldestActivePuddleIndex = -1
for (let index = 0; index < hazards.length; index += 1) {
const hazard = hazards[index]
if (hazard.hazardKind !== 'firePuddle' || hazard.remainingSeconds <= hazard.fadeSeconds) continue
if (hazard.hazardKind !== hazardKind || hazard.remainingSeconds <= hazard.fadeSeconds) continue
activePuddles += 1
if (oldestActivePuddleIndex < 0) oldestActivePuddleIndex = index
}
if (activePuddles <= MAX_FIRE_PUDDLES || oldestActivePuddleIndex < 0) return hazards
if (activePuddles <= maxActive || oldestActivePuddleIndex < 0) return hazards
return hazards.map((hazard, index) => index === oldestActivePuddleIndex
? { ...hazard, remainingSeconds: Math.min(hazard.remainingSeconds, hazard.fadeSeconds) }