// SPDX-FileCopyrightText: In 2019, Chris Pressey, the original author of this work, placed it into the public domain.
// SPDX-License-Identifier: Unlicense
// For more information, please refer to <https://unlicense.org/>
import { concoctJaft as concoct } from '../contrib/jaft-0.2/jaftConcoctor.js';
import { get, newList, push, reduce } from './immutable.js';
import { abs, makeAction } from './utils.js';
import { updatePlayer } from './player.js';
import { updateBoulder } from './boulder.js';
import { updateMissile } from './missile.js';
/* --[ Collision ]-------------------------------------------------------- */
const isCollidingMissileBoulder = concoct({get, abs}, `(missile, boulder) =>
abs(get(missile, "x") - get(boulder, "x")) < 10 &&
abs(get(missile, "y") - get(boulder, "y")) < 10`);
const isCollidingPlayerBoulder = concoct({get, abs}, `(player, boulder) =>
abs(get(player, "x") - get(boulder, "x")) < 10 &&
abs(get(player, "y") + 5 - get(boulder, "y")) < 10`);
const missileCollisionReducer = concoct({
push, makeAction, updatePlayer, updateMissile, updateBoulder,
isCollidingMissileBoulder
}, `(accum, missile) =>
const [player, missiles, boulder] = accum;
isCollidingMissileBoulder(missile, boulder) ?
[
updatePlayer(player, makeAction("SCORE_POINTS")),
push(missiles, updateMissile(missile, makeAction("EXPLODE"))),
updateBoulder(boulder, makeAction("EXPLODE"))
] :
[player, push(missiles, missile), boulder]
`);
const boulderCollisionReducer = concoct({
get, push, reduce, newList, makeAction, updatePlayer, updateBoulder,
isCollidingPlayerBoulder, missileCollisionReducer
}, `(accum, boulder) =>
const [player, missiles, boulders] = accum;
get(boulder, "mode") === "GONE" ? accum : (
get(boulder, "mode") === "MOVING" ? (
get(player, "mode") === "PLAYING" && isCollidingPlayerBoulder(player, boulder) ? (
[
updatePlayer(player, makeAction("EXPLODE")),
missiles,
push(boulders, updateBoulder(boulder, makeAction("EXPLODE")))
]
) : (
const [player2, missiles2, boulder2] = reduce(
missiles, missileCollisionReducer, [player, newList(), boulder]
);
[player2, missiles2, push(boulders, boulder2)]
)
) : [player, missiles, push(boulders, boulder)]
)`);
const detectCollisions = concoct({
reduce, newList, boulderCollisionReducer
}, `(player, missiles, boulders) =>
reduce(
boulders, boulderCollisionReducer, [player, missiles, newList()]
)`);
export { detectCollisions };