@cruncheevos/core
Version:
Parse and generate achievements and leaderboards for RetroAchievements.org
182 lines (181 loc) • 7.56 kB
TypeScript
import { ConditionBuilder } from './define.js';
import { DeepPartial } from './util.js';
export declare namespace Condition {
type Hits = number;
interface Value {
/** Specifies if value is read from memory and the way it's read/interpreted, or if value is constant. Empty string is allowed for rvalue. */
type: ValueType;
/** Specifies how to interpret the value at specified memory address. Not required for constant values. */
size: Size;
/** If value type implies reading from memory - this specifies memory address, otherwise specifies constant value. */
value: number;
}
type ValueArray = [ValueType, Size, number];
type Array = [Flag, ValueType, Size, number, Operator?, ValueType?, Size?, number?, Hits?];
interface Data {
/**
* Affects condition logic or the way it reads memory.
*
* Individual documentation for each flag [can be seen here](https://docs.retroachievements.org/developer-docs/achievement-development-overview.html#flags).
*/
flag: Flag;
/**
* Condition's left value, it always exists.
*/
lvalue: Value;
/**
* An operator set between left and right value. Empty string is allowed for conditions that don't specify right value.
*/
cmp: Operator;
/**
* Condition's optional right value. If it's not set - rvalue properties are empty strings.
*/
rvalue: Value;
/**
* Amount of hits set (also known as Hit Count), additional explanation [can be seen here](https://docs.retroachievements.org/developer-docs/hit-counts.html).
*/
hits: number;
}
type PartialMergedData = DeepPartial<Data> | {
lvalue?: Partial<ValueArray>;
rvalue?: Partial<ValueArray>;
};
type Input = Condition.Data | Condition.Array | string | Condition;
type FlagForReading = '' | 'PauseIf' | 'ResetIf' | 'ResetNextIf' | 'AddHits' | 'SubHits' | 'AndNext' | 'OrNext' | 'Measured' | 'Measured%' | 'MeasuredIf' | 'Trigger';
type FlagForCalculation = 'AddSource' | 'SubSource' | 'AddAddress' | 'Remember';
type Flag = FlagForReading | FlagForCalculation;
type OperatorComparison = '=' | '!=' | '<' | '<=' | '>' | '>=';
type OperatorModifier = '+' | '-' | '*' | '/' | '%' | '&' | '^';
type Operator = '' | OperatorComparison | OperatorModifier;
type SizeRegular = '' | 'Bit0' | 'Bit1' | 'Bit2' | 'Bit3' | 'Bit4' | 'Bit5' | 'Bit6' | 'Bit7' | 'Lower4' | 'Upper4' | '8bit' | '16bit' | '24bit' | '32bit' | '16bitBE' | '24bitBE' | '32bitBE' | 'BitCount';
type SizeExtended = 'Float' | 'FloatBE' | 'Double32' | 'Double32BE' | 'MBF32' | 'MBF32LE';
type Size = SizeRegular | SizeExtended;
type ValueTypeSized = 'Mem' | 'Delta' | 'Prior' | 'BCD' | 'Invert';
type ValueTypeNoSize = 'Value' | 'Float' | 'Recall';
type ValueType = '' | ValueTypeSized | ValueTypeNoSize;
type GroupNormalized = Condition[][];
type Group = (Condition.Input | ConditionBuilder)[] | string | ConditionBuilder;
type GroupSetObject<G = Group> = {
core: G;
[x: `alt${bigint}`]: G;
};
type GroupSet = Group | GroupSetObject;
}
interface GroupSetParseOptions {
considerLegacyValueFormat?: boolean;
}
export declare function validateRegularMeasuredConditions(conditions: Condition.GroupNormalized): void;
/**
* This class represents a code piece that can be part of achievements, leaderboards or rich presence for RetroAchievements.
*
* Conditions are immutable, if you need to a make a new Condition instance based of existing one - use `with()` method.
*/
export declare class Condition implements Condition.Data {
flag: Condition.Flag;
lvalue: Condition.Value;
cmp: Condition.Operator;
rvalue: Condition.Value;
hits: number;
/**
* Creates Condition using array representing it.
*
* @example
* new Condition(['ResetIf', 'Mem', 'Bit0', 71, '>', 'Delta', 'Bit1', 71, 3])
*/
constructor(def: Condition.Array);
/**
* Creates Condition using a string representing the condition.
*
* @example
* new Condition('R:0xM47>d0xN47.3.')
* // same as
* new Condition(['ResetIf', 'Mem', 'Bit0', 71, '>', 'Delta', 'Bit1', 71, 3])
*/
constructor(def: string);
/**
* Returns the same Condition instance passed,
* which is due to Conditions being immutable.
*/
constructor(def: Condition);
/**
* Creates Condition using an object that directly represents the Condition data.
*
* @example
* new Condition({
* flag: '',
* lvalue: {
* type: 'Mem',
* size: '32bit',
* value: 0xcafe,
* },
* cmp: '=',
* rvalue: {
* type: 'Value',
* size: '',
* value: 47,
* },
* hits: 0,
* })
*/
constructor(def: Condition.Data);
/**
* @ignore Stub definition to please TypeScript, this accepts all the previous types.
*/
constructor(def: Condition.Input);
/**
* Returns new Condition instance with different values merged.
*
* `lvalue` and `rvalue` can be specified as partial array, which can be less verbose
*
* @param {DeepPartial<Condition.Data>} data DeepPartial<Condition.Data>
*
* @example
* new Condition('0=1')
* .with({ cmp: '!=', rvalue: { value: 47 } })
* .toString() // 0!=47
*
* new Condition('0xXcafe=0xXfeed')
* .with({ rvalue: ['Delta', '16bit', 0xabcd] })
* .toString() // 0xXcafe=d0x abcd
*
* new Condition('0xXcafe=0xXfeed')
* .with({ rvalue: ['Delta'] })
* .toString() // 0xXcafe=d0xXfeed
*/
with(data: Condition.PartialMergedData): Condition;
/**
* Returns string representation of Condition
* suitable for RetroAchievements and local files.
* @example
* new Condition(['ResetIf', 'Mem', 'Bit0', 71, '>', 'Delta', 'Bit1', 71, 3]).toString() // 'R:0xM47>d0xN47.3.'
*/
toString(): string;
/**
* Returns direct Array representation of Condition,
* values are exactly same as properties of Condition.
*
* @example
* new Condition(['Measured', 'Mem', '8bit', 4]).toArray()
* // [ "Measured", "Mem", "8bit", 4, "", "", "", 0, 0 ]
*/
toArray(): Condition.Array;
/**
* Returns prettier Array representation of Condition, which is more suitable for display:
*
* * Everything is a string
* * Values are formatted as hexadecimal if they are greater or equal to 100000
* * Negative values are formatted as decimal if they are greater or equal to -4096, otherwise formatted as hexadecimal with underflow correction
* * Hits are empty string if equal to zero
*
* @example
* new cruncheevos.Condition(['ResetIf', 'Mem', '32bit', 0xfeedcafe, '>', 'Value', '', 71]).toArrayPretty()
* // [ "ResetIf", "Mem", "32bit", "0xfeedcafe", ">", "Value", "", "71", "" ]
*
* new cruncheevos.Condition(['', 'Value', '', -4097, '>', 'Value', '', -1]).toArrayPretty()
* // [ "", "Value", "", "0xffffefff", ">", "Value", "", "-1", "" ]
*/
toArrayPretty(): string[];
}
export declare function normalizedConditionGroupSetFromString(str: string, options?: GroupSetParseOptions): Condition[][];
export declare function normalizedConditionGroupSet(def: Condition.GroupSet, options?: GroupSetParseOptions): Condition.GroupNormalized;
export {};