Android build v1.1.22
This commit is contained in:
+166
-26
@@ -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) }
|
||||
|
||||
Reference in New Issue
Block a user