Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function associationSerializers(modelClass, propName, options) {
return {
serializer: options.serializer ||
modelClass.serialize ||
object(getDefaultModelSchema(modelClass)).serializer,
deserializer: options.deserializer ||
modelClass.deserializer ||
(
(attrs, context) => {
let model;
// double equals catches null/undefined
if (null == attrs) { attrs = {}; }
if (attrs instanceof modelClass) {
model = attrs;
} else {
model = setupModel(
Object.assign({}, options, { attrs, modelClass }),
);
}
if (options.inverseOf) {
markNonserializable(model, options.inverseOf);
import {list, object, serializable} from 'serializr';
import {QuestRoom} from './QuestRoom';
import {Bounds} from '../../Bounds';
import {Dungeon} from './Dungeon';
import {Difficulty} from './Difficulty';
export class QuestMap {
@serializable(list(object(QuestRoom))) rooms: QuestRoom[];
@serializable(object(QuestRoom)) entrance: QuestRoom;
@serializable size: MapSize = MapSize.Short;
get bounds () {
return QuestMap.findBoundingBox(this.rooms);
}
static generate (dungeon: Dungeon, difficulty: Difficulty, size: MapSize) {
const memory = new Map();
const m = new QuestMap();
m.size = size;
m.entrance = QuestRoom.walk(
dungeon, memory, difficulty, size,
(room, coords) => !(coords.x === 0 && coords.y === 0) // No monsters in the entrance
);
m.rooms = Array.from(memory.values());
return m;
import {Vector} from './Vector';
import {identifier, list, object, serializable} from 'serializr';
import {v4 as uuid} from 'uuid';
import {Character} from './Character';
import {generateCurio, generateMonster} from '../Generators';
import {observable} from 'mobx';
import {count} from '../../lib/Helpers';
import {Curio} from './Curio';
import {Dungeon} from './Dungeon';
import {Difficulty} from './Difficulty';
export type MapLocationId = string;
export class QuestRoom {
@serializable(identifier()) id: MapLocationId = uuid();
@serializable(object(Vector)) coordinates: Vector;
@serializable roomImageIndex: number = 0;
// Mutable
@serializable(list(object(Character))) @observable monsters: Character[] = [];
@serializable @observable isScouted: boolean = false;
@serializable(list(object(Curio))) @observable curios: Curio[] = [];
isConnectedTo (other: QuestRoom) {
return this.coordinates.distance(other.coordinates) === 1;
}
static walk (
dungeon: Dungeon,
memory: Map = new Map(),
difficulty: Difficulty,
stepsLeft: number = 10,
}
});
// eslint-disable-next-line new-cap
createModelSchema(model, serializeSchema, ({ json }) => new model(json));
properties.forEach(({ type, options }, name) => {
if (Associations[type] || options.model) {
addReference(model, name, options, Associations[type] || Associations.belongsTo);
}
});
for (let i = PendingLookups.length - 1; i >= 0; i -= 1) {
const { parentModel, propName, options, cb } = PendingLookups[i];
const referencedModel = findModel(options.model, propName);
if (referencedModel) {
const parentModelSchema = getDefaultModelSchema(parentModel);
parentModelSchema.props[propName] = cb(referencedModel, propName, options);
PendingLookups.splice(i, 1);
}
}
}
import {Character} from './Character';
import {Skill} from './Skill';
import {list, object, serializable} from 'serializr';
import {cmp, contains, moveItem} from '../../lib/Helpers';
import {randomizeItem} from '../../lib/Helpers';
import {CharacterStatus} from './CharacterStatus';
type AllyOrEnemy = Character;
export class Battler<
TAlly extends AllyOrEnemy = AllyOrEnemy,
TEnemy extends AllyOrEnemy = AllyOrEnemy
> {
@serializable @observable turn: number = 0;
@serializable @observable turnActorIndex: number = 0;
@serializable(list(object(Character))) @observable enemies: TEnemy[] = [];
@serializable(list(object(Character))) @observable deceasedEnemies: TEnemy[] = [];
// No need to serialize since it's automated by quest behavior
@observable public allies: TAlly[] = null;
@observable private enemySource: TEnemy[] = null;
@observable public inBattle: boolean = false;
@computed get turnActorOrder (): AllyOrEnemy[] {
return [...this.allies, ...this.enemies]
.sort((a, b) => cmp(a.stats.speed, b.stats.speed));
}
@computed get turnActor () {
return this.turnActorOrder[this.turnActorIndex];
}
@serializable isEscapable?: boolean = true;
@serializable(object(QuestMap))
map: QuestMap;
@serializable(object(QuestObjective))
objective: QuestObjective = new QuestObjective();
@serializable(list(object(Item)))
rewards: Item[] = [];
@serializable(list(object(Hero)))
@observable
party: Hero[] = [];
@serializable(list(object(Hero)))
@observable
deceased: Hero[] = [];
// Data that changes throughout a quest
@serializable @observable status: QuestStatus = QuestStatus.Idle;
@serializable @observable light: number = 100;
@serializable(list(object(Item))) @observable items: Item[] = [];
@serializable @observable previousRoomId: MapLocationId = null;
@serializable @observable currentRoomId: MapLocationId = null;
@computed get lightPercentage () {
return cap(this.light / 100, 0, 1);
}
@computed get previousRoom () {
return this.map.rooms.find((room) => room.id === this.previousRoomId);
@serializable(object(TurnStats))
@observable
buff: TurnStats;
@serializable(map(object(TurnStats)))
@observable
dots = new Map();
@serializable(object(Stats))
@observable mutableStats = new Stats();
@serializable(map(primitive()))
@observable
private skillLevels = new Map();
@serializable(map(primitive()))
@observable
private skillSelections = new Map();
get skills () {
return this.classInfo.skills.map((info) => new Skill(this.skillLevels, this.skillSelections, info));
}
get selectedSkills () {
return this.skills.filter((skill) => skill.isSelected);
}
@computed get scaledClassInfo () {
const scaled = {...this.classInfo}; // Clone to avoid mutating static instance
scaled.stats = new Stats();
scaled.stats.add(this.classInfo.stats);
scaled.stats.scale(this.classInfoStatsScale);
function decorateModel(model) {
Object.assign(model.prototype, MixedInInstanceMethods);
Object.assign(model, MixedInClassMethods);
registerModel(model);
const serializeSchema = {};
const { properties } = getSchema(model);
properties.forEach(({ type, options }, name) => {
if (Fields[type]) {
serializeSchema[name] = Fields[type](options, name);
}
});
// eslint-disable-next-line new-cap
createModelSchema(model, serializeSchema, ({ json }) => new model(json));
properties.forEach(({ type, options }, name) => {
if (Associations[type] || options.model) {
addReference(model, name, options, Associations[type] || Associations.belongsTo);
}
});
for (let i = PendingLookups.length - 1; i >= 0; i -= 1) {
const { parentModel, propName, options, cb } = PendingLookups[i];
const referencedModel = findModel(options.model, propName);
if (referencedModel) {
const parentModelSchema = getDefaultModelSchema(parentModel);
parentModelSchema.props[propName] = cb(referencedModel, propName, options);
PendingLookups.splice(i, 1);
}
}
}
test("decorate a property with two decorators", function() {
let updatedByAutorun
class Obj {
x = null
}
decorate(Obj, {
x: [serializable(primitive()), observable]
})
const obj = deserialize(Obj, {
x: 0
})
const d = autorun(() => {
updatedByAutorun = obj.x
})
expect(isObservableProp(obj, "x")).toBe(true)
expect(updatedByAutorun).toEqual(0)
obj.x++
expect(obj.x).toEqual(1)
test("decorate a property with two decorators", function() {
let updatedByAutorun
class Obj {
x = null
}
decorate(Obj, {
x: [serializable(primitive()), observable]
})
const obj = deserialize(Obj, {
x: 0
})
const d = autorun(() => {
updatedByAutorun = obj.x
})
expect(isObservableProp(obj, "x")).toBe(true)
expect(updatedByAutorun).toEqual(0)
obj.x++
expect(obj.x).toEqual(1)
expect(updatedByAutorun).toEqual(1)
expect(serialize(obj).x).toEqual(1)