Stage 5: Add Prisma integration and enhance mission management
- Introduced Prisma as a dependency in package.json and updated pnpm-lock.yaml. - Created Prisma module and service for database interactions. - Added initial Prisma schema and migration for user, survivor, mission, and related entities. - Implemented throttling in the API using @nestjs/throttler for rate limiting. - Enhanced mission management logic to utilize Prisma for database transactions. - Updated missions controller and service to handle mission state and participant management. - Added Twitch PubSub service for real-time updates on mission states.
This commit is contained in:
@@ -2,11 +2,11 @@ import seedrandom = require('seedrandom');
|
||||
import type {
|
||||
EncounterDefinition,
|
||||
EncounterResult,
|
||||
ModifierApplication,
|
||||
Perk,
|
||||
SurvivorState,
|
||||
SurvivorStats,
|
||||
} from '@fog-explorer/api-interfaces';
|
||||
import { applyPerkModifiers } from './perk-math';
|
||||
|
||||
export interface ResolverInput {
|
||||
seed: string;
|
||||
@@ -23,15 +23,10 @@ export interface ResolverInput {
|
||||
};
|
||||
}
|
||||
|
||||
// Probability adjustments per stat point and per difficulty level.
|
||||
const OBJECTIVES_BONUS = 0.02;
|
||||
const ALTRUISM_BONUS = 0.02;
|
||||
const DIFFICULTY_PENALTY = 0.12;
|
||||
|
||||
// Tag that enables the altruism stat bonus.
|
||||
const ALTRUISM_TAG = 'altruistic';
|
||||
|
||||
// Injury probability floor/ceiling when active survivor fails.
|
||||
const INJURY_CHANCE_BASE = 0.8;
|
||||
const INJURY_CHANCE_FLOOR = 0.2;
|
||||
const SURVIVAL_INJURY_REDUCTION = 0.05;
|
||||
@@ -40,25 +35,28 @@ export function resolveEncounter(input: ResolverInput): EncounterResult {
|
||||
const rng = seedrandom(input.seed);
|
||||
|
||||
let probability = input.encounter.baseProbability;
|
||||
|
||||
probability -= (input.difficulty - 1) * DIFFICULTY_PENALTY;
|
||||
probability += input.survivor.stats.objectives * OBJECTIVES_BONUS;
|
||||
|
||||
if (input.encounter.tags.includes(ALTRUISM_TAG)) {
|
||||
probability += input.survivor.stats.altruism * ALTRUISM_BONUS;
|
||||
}
|
||||
|
||||
const modifiersApplied = applyPerkModifiers(probability, input);
|
||||
probability = modifiersApplied.adjusted;
|
||||
const appliedList = modifiersApplied.applied;
|
||||
const { probability: finalProbability, applied } = applyPerkModifiers(
|
||||
probability,
|
||||
input.survivor.perkSlots,
|
||||
input.encounter.tags
|
||||
);
|
||||
|
||||
probability = Math.max(0, Math.min(1, probability));
|
||||
|
||||
const success = rng() < probability;
|
||||
const success = rng() < finalProbability;
|
||||
|
||||
const survivorStateChange = success
|
||||
? null
|
||||
: computeStateChange(rng, input.survivor.state, input.survivor.stats.survival, input.survivor.hookCount);
|
||||
: computeStateChange(
|
||||
rng,
|
||||
input.survivor.state,
|
||||
input.survivor.stats.survival,
|
||||
input.survivor.hookCount
|
||||
);
|
||||
|
||||
return {
|
||||
missionId: input.missionId,
|
||||
@@ -68,47 +66,11 @@ export function resolveEncounter(input: ResolverInput): EncounterResult {
|
||||
seed: input.seed,
|
||||
success,
|
||||
survivorStateChange,
|
||||
modifiersApplied: appliedList,
|
||||
modifiersApplied: applied,
|
||||
logText: buildLogText(input.encounter.key, success, survivorStateChange),
|
||||
};
|
||||
}
|
||||
|
||||
function applyPerkModifiers(
|
||||
startProbability: number,
|
||||
input: ResolverInput
|
||||
): { adjusted: number; applied: ModifierApplication[] } {
|
||||
let probability = startProbability;
|
||||
const applied: ModifierApplication[] = [];
|
||||
|
||||
for (const perk of input.survivor.perkSlots) {
|
||||
for (const mod of perk.modifiers) {
|
||||
if (mod.target !== 'successChance') continue;
|
||||
|
||||
if (mod.condition) {
|
||||
const tagMatch = mod.condition.encounterTags.some((t) =>
|
||||
input.encounter.tags.includes(t)
|
||||
);
|
||||
if (!tagMatch) continue;
|
||||
}
|
||||
|
||||
if (mod.type === 'additive') {
|
||||
probability += mod.amount;
|
||||
} else {
|
||||
probability *= 1 + mod.amount;
|
||||
}
|
||||
|
||||
applied.push({
|
||||
perkKey: perk.key,
|
||||
target: mod.target,
|
||||
type: mod.type,
|
||||
effectiveAmount: mod.amount,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return { adjusted: probability, applied };
|
||||
}
|
||||
|
||||
function computeStateChange(
|
||||
rng: seedrandom.PRNG,
|
||||
currentState: SurvivorState,
|
||||
|
||||
Reference in New Issue
Block a user