Implemented houses
This commit is contained in:
@@ -25,6 +25,13 @@ class FalukantController {
|
||||
this.acceptMarriageProposal = this.acceptMarriageProposal.bind(this);
|
||||
this.getGifts = this.getGifts.bind(this);
|
||||
this.sendGift = this.sendGift.bind(this);
|
||||
this.getHouseTypes = this.getHouseTypes.bind(this);
|
||||
this.getTitelsOfNobility = this.getTitelsOfNobility.bind(this);
|
||||
this.getMoodAffect = this.getMoodAffect.bind(this);
|
||||
this.getCharacterAffect = this.getCharacterAffect.bind(this);
|
||||
this.getUserHouse = this.getUserHouse.bind(this);
|
||||
this.getBuyableHouses = this.getBuyableHouses.bind(this);
|
||||
this.buyUserHouse = this.buyUserHouse.bind(this);
|
||||
}
|
||||
|
||||
async getUser(req, res) {
|
||||
@@ -368,16 +375,17 @@ class FalukantController {
|
||||
|
||||
async sendGift(req, res) {
|
||||
try {
|
||||
const { userid: hashedUserId } = req.headers;
|
||||
const { giftId} = req.body;
|
||||
const result = await FalukantService.sendGift(hashedUserId, giftId);
|
||||
res.status(200).json(result);
|
||||
const { userid: hashedUserId } = req.headers;
|
||||
const { giftId } = req.body;
|
||||
const result = await FalukantService.sendGift(hashedUserId, giftId);
|
||||
res.status(200).json(result);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
console.log(error);
|
||||
const status = error.status === 412 ? 412 : 500;
|
||||
res.status(status).json({ error: error.message });
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async getTitelsOfNobility(req, res) {
|
||||
try {
|
||||
const { userid: hashedUserId } = req.headers;
|
||||
@@ -399,6 +407,63 @@ class FalukantController {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
async getMoodAffect(req, res) {
|
||||
try {
|
||||
const { userid: hashedUserId } = req.headers;
|
||||
const result = await FalukantService.getMoodAffect(hashedUserId);
|
||||
res.status(200).json(result);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
async getCharacterAffect(req, res) {
|
||||
try {
|
||||
const { userid: hashedUserId } = req.headers;
|
||||
const result = await FalukantService.getCharacterAffect(hashedUserId);
|
||||
res.status(200).json(result);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
async getUserHouse(req, res) {
|
||||
try {
|
||||
const { userid: hashedUserId } = req.headers;
|
||||
const result = await FalukantService.getUserHouse(hashedUserId);
|
||||
console.log(result);
|
||||
res.status(200).json(result);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
async getBuyableHouses(req, res) {
|
||||
try {
|
||||
const { userid: hashedUserId } = req.headers;
|
||||
const result = await FalukantService.getBuyableHouses(hashedUserId);
|
||||
res.status(200).json(result);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
async buyUserHouse(req, res) {
|
||||
try {
|
||||
const { userid: hashedUserId } = req.headers;
|
||||
const { houseId } = req.body;
|
||||
const result = await FalukantService.buyUserHouse(hashedUserId, houseId);
|
||||
res.status(201).json(result);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default FalukantController;
|
||||
|
||||
@@ -62,6 +62,9 @@ import PromotionalGiftMood from './falukant/predefine/promotional_gift_mood.js';
|
||||
import RelationshipType from './falukant/type/relationship.js';
|
||||
import Relationship from './falukant/data/relationship.js';
|
||||
import PromotionalGiftLog from './falukant/log/promotional_gift.js';
|
||||
import HouseType from './falukant/type/house.js';
|
||||
import BuyableHouse from './falukant/data/buyable_house.js';
|
||||
import UserHouse from './falukant/data/user_house.js';
|
||||
|
||||
export default function setupAssociations() {
|
||||
// UserParam related associations
|
||||
@@ -352,4 +355,16 @@ export default function setupAssociations() {
|
||||
|
||||
PromotionalGiftCharacterTrait.belongsTo(PromotionalGift, { foreignKey: 'gift_id', as: 'promotionalgiftcharactertrait' });
|
||||
PromotionalGiftMood.belongsTo(PromotionalGift, { foreignKey: 'gift_id', as: 'promotionalgiftcharactermood' });
|
||||
|
||||
HouseType.hasMany(BuyableHouse, { foreignKey: 'houseTypeId', as: 'buyableHouses' });
|
||||
BuyableHouse.belongsTo(HouseType, { foreignKey: 'houseTypeId', as: 'houseType' });
|
||||
|
||||
HouseType.hasMany(UserHouse, { foreignKey: 'houseTypeId', as: 'userHouses' });
|
||||
UserHouse.belongsTo(HouseType, { foreignKey: 'houseTypeId', as: 'houseType' });
|
||||
|
||||
FalukantUser.hasOne(UserHouse, { foreignKey: 'userId', as: 'userHouse' });
|
||||
UserHouse.belongsTo(FalukantUser, { foreignKey: 'userId', as: 'houseUser' });
|
||||
|
||||
TitleOfNobility.hasMany(HouseType, { foreignKey: 'minimumNobleTitle', as: 'houseTypes' });
|
||||
HouseType.belongsTo(TitleOfNobility, { foreignKey: 'minimumNobleTitle', as: 'titleOfNobility' });
|
||||
}
|
||||
|
||||
40
backend/models/falukant/data/buyable_house.js
Normal file
40
backend/models/falukant/data/buyable_house.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Model, DataTypes } from 'sequelize';
|
||||
import { sequelize } from '../../../utils/sequelize.js';
|
||||
|
||||
class BuyableHouse extends Model { }
|
||||
|
||||
BuyableHouse.init({
|
||||
roofCondition: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 100
|
||||
},
|
||||
floorCondition: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 100
|
||||
},
|
||||
wallCondition: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 100
|
||||
},
|
||||
windowCondition: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 100
|
||||
},
|
||||
houseTypeId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
}
|
||||
}, {
|
||||
sequelize,
|
||||
modelName: 'BuyableHouse',
|
||||
tableName: 'buyable_house',
|
||||
schema: 'falukant_data',
|
||||
timestamps: false,
|
||||
underscored: true,
|
||||
});
|
||||
|
||||
export default BuyableHouse;
|
||||
46
backend/models/falukant/data/user_house.js
Normal file
46
backend/models/falukant/data/user_house.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Model, DataTypes } from 'sequelize';
|
||||
import { sequelize } from '../../../utils/sequelize.js';
|
||||
|
||||
class UserHouse extends Model { }
|
||||
|
||||
UserHouse.init({
|
||||
roofCondition: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 100
|
||||
},
|
||||
floorCondition: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 100
|
||||
},
|
||||
wallCondition: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 100
|
||||
},
|
||||
windowCondition: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 100
|
||||
},
|
||||
houseTypeId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 1
|
||||
},
|
||||
userId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 1
|
||||
}
|
||||
}, {
|
||||
sequelize,
|
||||
modelName: 'UserHouse',
|
||||
tableName: 'user_house',
|
||||
schema: 'falukant_data',
|
||||
timestamps: false,
|
||||
underscored: true,
|
||||
});
|
||||
|
||||
export default UserHouse;
|
||||
38
backend/models/falukant/type/house.js
Normal file
38
backend/models/falukant/type/house.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Model, DataTypes } from 'sequelize';
|
||||
import { sequelize } from '../../../utils/sequelize.js';
|
||||
|
||||
class HouseType extends Model { }
|
||||
|
||||
HouseType.init({
|
||||
labelTr: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
cost: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
position: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
minimumNobleTitle: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
}, {
|
||||
sequelize,
|
||||
modelName: 'HouseType',
|
||||
tableName: 'house',
|
||||
schema: 'falukant_type',
|
||||
timestamps: false,
|
||||
underscored: true,
|
||||
indexes: [
|
||||
{
|
||||
unique: true,
|
||||
fields: ['label_tr']
|
||||
}
|
||||
],
|
||||
});
|
||||
|
||||
export default HouseType;
|
||||
@@ -66,6 +66,9 @@ import PromotionalGiftCharacterTrait from './falukant/predefine/promotional_gift
|
||||
import PromotionalGiftMood from './falukant/predefine/promotional_gift_mood.js';
|
||||
import Relationship from './falukant/data/relationship.js';
|
||||
import PromotionalGiftLog from './falukant/log/promotional_gift.js';
|
||||
import HouseType from './falukant/type/house.js';
|
||||
import BuyableHouse from './falukant/data/buyable_house.js';
|
||||
import UserHouse from './falukant/data/user_house.js';
|
||||
|
||||
const models = {
|
||||
SettingsType,
|
||||
@@ -136,6 +139,9 @@ const models = {
|
||||
PromotionalGiftCharacterTrait,
|
||||
PromotionalGiftMood,
|
||||
PromotionalGiftLog,
|
||||
HouseType,
|
||||
BuyableHouse,
|
||||
UserHouse,
|
||||
};
|
||||
|
||||
export default models;
|
||||
|
||||
@@ -36,5 +36,9 @@ router.post('/family/gift', falukantController.sendGift);
|
||||
router.get('/family', falukantController.getFamily);
|
||||
router.get('/nobility/titels', falukantController.getTitelsOfNobility);
|
||||
router.get('/houses/types', falukantController.getHouseTypes);
|
||||
|
||||
router.get('/houses/buyable', falukantController.getBuyableHouses);
|
||||
router.get('/mood/affect', falukantController.getMoodAffect);
|
||||
router.get('/character/affect', falukantController.getCharacterAffect);
|
||||
router.get('/houses', falukantController.getUserHouse);
|
||||
router.post('/houses', falukantController.buyUserHouse);
|
||||
export default router;
|
||||
|
||||
@@ -33,6 +33,10 @@ import PromotionalGiftCharacterTrait from '../models/falukant/predefine/promotio
|
||||
import PromotionalGiftMood from '../models/falukant/predefine/promotional_gift_mood.js';
|
||||
import PromotionalGiftLog from '../models/falukant/log/promotional_gift.js';
|
||||
import CharacterTrait from '../models/falukant/type/character_trait.js';
|
||||
import Mood from '../models/falukant/type/mood.js';
|
||||
import UserHouse from '../models/falukant/data/user_house.js';
|
||||
import HouseType from '../models/falukant/type/house.js';
|
||||
import BuyableHouse from '../models/falukant/data/buyable_house.js';
|
||||
|
||||
function calcAge(birthdate) {
|
||||
const b = new Date(birthdate); b.setHours(0, 0);
|
||||
@@ -67,6 +71,14 @@ function calculateMarriageCost(titleOfNobility, age) {
|
||||
return baseCost * Math.pow(adjustedTitle, 1.3) - (age - 12) * 20;
|
||||
}
|
||||
|
||||
class PreconditionError extends Error {
|
||||
constructor(label) {
|
||||
super(label);
|
||||
this.name = 'PreconditionError';
|
||||
this.status = 412;
|
||||
}
|
||||
}
|
||||
|
||||
class FalukantService extends BaseService {
|
||||
async getFalukantUserByHashedId(hashedId) {
|
||||
const user = await FalukantUser.findOne({
|
||||
@@ -78,10 +90,22 @@ class FalukantService extends BaseService {
|
||||
include: [
|
||||
{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] },
|
||||
{ model: FalukantPredefineLastname, as: 'definedLastName', attributes: ['name'] },
|
||||
{ model: TitleOfNobility, as: 'nobleTitle', attributes: ['labelTr'] },
|
||||
{ model: TitleOfNobility, as: 'nobleTitle', attributes: ['labelTr', 'id'] },
|
||||
{ model: CharacterTrait, as: 'traits', attributes: ['id', 'tr'] }
|
||||
],
|
||||
attributes: ['id', 'birthdate', 'gender']
|
||||
attributes: ['id', 'birthdate', 'gender', 'moodId']
|
||||
},
|
||||
{
|
||||
model: UserHouse,
|
||||
as: 'userHouse',
|
||||
attributes: ['roofCondition', 'wallCondition', 'floorCondition', 'windowCondition'],
|
||||
include: [
|
||||
{
|
||||
model: HouseType,
|
||||
as: 'houseType',
|
||||
attributes: ['labelTr', 'position']
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
});
|
||||
@@ -262,9 +286,7 @@ class FalukantService extends BaseService {
|
||||
|
||||
async getProducts(hashedUserId) {
|
||||
const u = await getFalukantUserOrFail(hashedUserId);
|
||||
console.log(u);
|
||||
const c = await FalukantCharacter.findOne({ where: { userId: u.id } });
|
||||
console.log(c);
|
||||
if (!c) {
|
||||
throw new Error(`No FalukantCharacter found for user with id ${u.id}`);
|
||||
}
|
||||
@@ -348,9 +370,7 @@ class FalukantService extends BaseService {
|
||||
if (!inventory.length) {
|
||||
throw new Error('No inventory found');
|
||||
}
|
||||
console.log(inventory);
|
||||
const available = inventory.reduce((sum, i) => sum + i.quantity, 0);
|
||||
console.log(available);
|
||||
if (available < quantity) throw new Error('Not enough inventory available');
|
||||
const item = inventory[0].productType;
|
||||
const knowledgeVal = item.knowledges?.[0]?.knowledge || 0;
|
||||
@@ -443,7 +463,7 @@ class FalukantService extends BaseService {
|
||||
const branch = await Branch.findOne({
|
||||
where: { id: branchId },
|
||||
})
|
||||
;
|
||||
;
|
||||
const daySell = await DaySell.findOne({
|
||||
where: {
|
||||
regionId: branch.regionId,
|
||||
@@ -549,23 +569,47 @@ class FalukantService extends BaseService {
|
||||
async buyStorage(hashedUserId, branchId, amount, stockTypeId) {
|
||||
const user = await getFalukantUserOrFail(hashedUserId);
|
||||
const branch = await getBranchOrFail(user.id, branchId);
|
||||
const buyable = await BuyableStock.findOne({
|
||||
const buyableStocks = await BuyableStock.findAll({
|
||||
where: { regionId: branch.regionId, stockTypeId },
|
||||
include: [{ model: FalukantStockType, as: 'stockType' }]
|
||||
});
|
||||
if (!buyable || buyable.quantity < amount) throw new Error('Not enough buyable stock');
|
||||
const costPerUnit = buyable.stockType.cost;
|
||||
if (!buyableStocks || buyableStocks.length === 0) {
|
||||
throw new Error('Not enough buyable stock');
|
||||
}
|
||||
const totalAvailable = buyableStocks.reduce((sum, entry) => sum + entry.quantity, 0);
|
||||
if (totalAvailable < amount) {
|
||||
throw new Error('Not enough buyable stock');
|
||||
}
|
||||
const costPerUnit = buyableStocks[0].stockType.cost;
|
||||
const totalCost = costPerUnit * amount;
|
||||
if (user.money < totalCost) throw new Error('notenoughmoney');
|
||||
if (user.money < totalCost) {
|
||||
throw new Error('notenoughmoney');
|
||||
}
|
||||
const moneyResult = await updateFalukantUserMoney(
|
||||
user.id,
|
||||
-totalCost,
|
||||
`Buy storage (type: ${buyable.stockType.labelTr})`,
|
||||
`Buy storage (type: ${buyableStocks[0].stockType.labelTr})`,
|
||||
user.id
|
||||
);
|
||||
if (!moneyResult.success) throw new Error('Failed to update money');
|
||||
buyable.quantity -= amount;
|
||||
await buyable.save();
|
||||
if (!moneyResult.success) {
|
||||
throw new Error('Failed to update money');
|
||||
}
|
||||
let remainingToDeduct = amount;
|
||||
for (const entry of buyableStocks) {
|
||||
if (entry.quantity > remainingToDeduct) {
|
||||
entry.quantity -= remainingToDeduct;
|
||||
await entry.save();
|
||||
remainingToDeduct = 0;
|
||||
break;
|
||||
} else if (entry.quantity === remainingToDeduct) {
|
||||
await entry.destroy();
|
||||
remainingToDeduct = 0;
|
||||
break;
|
||||
} else {
|
||||
remainingToDeduct -= entry.quantity;
|
||||
await entry.destroy();
|
||||
}
|
||||
}
|
||||
let stock = await FalukantStock.findOne({
|
||||
where: { branchId: branch.id, stockTypeId },
|
||||
include: [{ model: FalukantStockType, as: 'stockType' }]
|
||||
@@ -576,13 +620,19 @@ class FalukantService extends BaseService {
|
||||
stockTypeId,
|
||||
quantity: amount,
|
||||
});
|
||||
return { success: true, bought: amount, totalCost, stockType: buyable.stockType.labelTr };
|
||||
} else {
|
||||
stock.quantity += amount;
|
||||
await stock.save();
|
||||
}
|
||||
stock.quantity += amount;
|
||||
await stock.save();
|
||||
notifyUser(user.user.hashedId, 'falukantUpdateStatus', {});
|
||||
notifyUser(user.user.hashedId, 'falukantBranchUpdate', { branchId });
|
||||
return { success: true, bought: amount, totalCost, stockType: buyable.stockType.labelTr };
|
||||
|
||||
return {
|
||||
success: true,
|
||||
bought: amount,
|
||||
totalCost,
|
||||
stockType: buyableStocks[0].stockType.labelTr
|
||||
};
|
||||
}
|
||||
|
||||
async sellStorage(hashedUserId, branchId, amount, stockTypeId) {
|
||||
@@ -725,7 +775,7 @@ class FalukantService extends BaseService {
|
||||
const newProposals = await this.fetchProposals(falukantUserId, regionId);
|
||||
return this.formatProposals(newProposals);
|
||||
}
|
||||
|
||||
|
||||
async deleteExpiredProposals() {
|
||||
const expirationTime = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
||||
await DirectorProposal.destroy({
|
||||
@@ -736,7 +786,7 @@ class FalukantService extends BaseService {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async fetchProposals(falukantUserId, regionId) {
|
||||
return DirectorProposal.findAll({
|
||||
where: { employerUserId: falukantUserId },
|
||||
@@ -750,19 +800,19 @@ class FalukantService extends BaseService {
|
||||
{ model: FalukantPredefineFirstname, as: 'definedFirstName' },
|
||||
{ model: FalukantPredefineLastname, as: 'definedLastName' },
|
||||
{ model: TitleOfNobility, as: 'nobleTitle' },
|
||||
{
|
||||
model: Knowledge,
|
||||
{
|
||||
model: Knowledge,
|
||||
as: 'knowledges',
|
||||
include: [
|
||||
{ model: ProductType, as: 'productType' },
|
||||
]
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async generateProposals(falukantUserId, regionId) {
|
||||
const proposalCount = Math.floor(Math.random() * 3) + 3;
|
||||
for (let i = 0; i < proposalCount; i++) {
|
||||
@@ -789,7 +839,7 @@ class FalukantService extends BaseService {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async calculateAverageKnowledge(characterId) {
|
||||
const averageKnowledge = await Knowledge.findAll({
|
||||
where: { characterId },
|
||||
@@ -798,7 +848,7 @@ class FalukantService extends BaseService {
|
||||
});
|
||||
return parseFloat(averageKnowledge[0]?.avgKnowledge || 0);
|
||||
}
|
||||
|
||||
|
||||
formatProposals(proposals) {
|
||||
return proposals.map((proposal) => {
|
||||
const age = Math.floor((Date.now() - new Date(proposal.character.birthdate)) / (24 * 60 * 60 * 1000));
|
||||
@@ -820,47 +870,40 @@ class FalukantService extends BaseService {
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async convertProposalToDirector(hashedUserId, proposalId) {
|
||||
console.log('convert proposal to director - start');
|
||||
const user = await getFalukantUserOrFail(hashedUserId);
|
||||
console.log('convert proposal to director - check user');
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
console.log('convert proposal to director - find proposal', proposalId);
|
||||
const proposal = await DirectorProposal.findOne(
|
||||
{
|
||||
{
|
||||
where: { id: proposalId },
|
||||
include: [
|
||||
{ model: FalukantCharacter, as: 'character' },
|
||||
]
|
||||
}
|
||||
);
|
||||
console.log('convert proposal to director - check proposal');
|
||||
if (!proposal || proposal.employerUserId !== user.id) {
|
||||
throw new Error('Proposal does not belong to the user');
|
||||
}
|
||||
|
||||
console.log('convert proposal to director - check existing director', user, proposal);
|
||||
const existingDirector = await Director.findOne({
|
||||
where: {
|
||||
employerUserId: user.id
|
||||
const existingDirector = await Director.findOne({
|
||||
where: {
|
||||
employerUserId: user.id
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: FalukantCharacter,
|
||||
{
|
||||
model: FalukantCharacter,
|
||||
as: 'character',
|
||||
where: {
|
||||
regionId: proposal.character.regionId,
|
||||
}
|
||||
},
|
||||
]
|
||||
]
|
||||
});
|
||||
if (existingDirector) {
|
||||
throw new Error('A director already exists for this region');
|
||||
}
|
||||
console.log('convert proposal to director - create new director');
|
||||
const newDirector = await Director.create({
|
||||
directorCharacterId: proposal.directorCharacterId,
|
||||
employerUserId: proposal.employerUserId,
|
||||
@@ -871,8 +914,8 @@ class FalukantService extends BaseService {
|
||||
employerUserId: proposal.employerUserId,
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: FalukantCharacter,
|
||||
{
|
||||
model: FalukantCharacter,
|
||||
as: 'character',
|
||||
where: {
|
||||
regionId: proposal.character.regionId,
|
||||
@@ -880,13 +923,11 @@ class FalukantService extends BaseService {
|
||||
},
|
||||
]
|
||||
});
|
||||
console.log('convert proposal to director - remove propsals');
|
||||
if (regionUserDirectorProposals.length > 0) {
|
||||
for (const proposal of regionUserDirectorProposals) {
|
||||
await DirectorProposal.destroy();
|
||||
}
|
||||
}
|
||||
console.log('convert proposal to director - notify user');
|
||||
notifyUser(hashedUserId, 'directorchanged');
|
||||
return newDirector;
|
||||
}
|
||||
@@ -978,7 +1019,7 @@ class FalukantService extends BaseService {
|
||||
}
|
||||
const updateData = {};
|
||||
updateData[settingKey] = value || false;
|
||||
|
||||
|
||||
await Director.update(updateData, {
|
||||
where: {
|
||||
id: director.id,
|
||||
@@ -1008,15 +1049,17 @@ class FalukantService extends BaseService {
|
||||
where: {
|
||||
character1Id: character.id,
|
||||
},
|
||||
attributes: ['createdAt', 'widowFirstName2'],
|
||||
attributes: ['createdAt', 'widowFirstName2', 'nextStepProgress'],
|
||||
include: [
|
||||
{
|
||||
model: FalukantCharacter,
|
||||
as: 'character2',
|
||||
attributes: ['id', 'birthdate', 'gender'],
|
||||
attributes: ['id', 'birthdate', 'gender', 'moodId'],
|
||||
include: [
|
||||
{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] },
|
||||
{ model: TitleOfNobility, as: 'nobleTitle', attributes: ['labelTr'] },
|
||||
{ model: CharacterTrait, as: 'traits' },
|
||||
{ model: Mood, as: 'mood' },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -1030,22 +1073,28 @@ class FalukantService extends BaseService {
|
||||
relationships = relationships.map((relationship) => ({
|
||||
createdAt: relationship.createdAt,
|
||||
widowFirstName2: relationship.widowFirstName2,
|
||||
progress: relationship.nextStepProgress,
|
||||
character2: {
|
||||
id: relationship.character2.id,
|
||||
age: calcAge(relationship.character2.birthdate),
|
||||
gender: relationship.character2.gender,
|
||||
firstName: relationship.character2.definedFirstName?.name || 'Unknown',
|
||||
nobleTitle: relationship.character2.nobleTitle?.labelTr || '',
|
||||
mood: relationship.character2.mood,
|
||||
characterTrait: relationship.character2.traits,
|
||||
},
|
||||
relationshipType: relationship.relationshipType.tr,
|
||||
}));
|
||||
family.relationships = relationships.filter((relationship) => ['wooing', 'engaged', 'married'].includes(relationship.relationshipType));
|
||||
family.lovers = relationships.filter((relationship) => ['lover'].includes(relationship.relationshipType.tr));
|
||||
family.deathPartners = relationships.filter((relationship) => ['widowed'].includes(relationship.relationshipType.tr));
|
||||
if (family.relationships.length === 0 ) {
|
||||
const ownAge = calcAge(character.birthdate);
|
||||
if (ownAge < 12) {
|
||||
family.possiblePartners = [];
|
||||
} else if (family.relationships.length === 0) {
|
||||
family.possiblePartners = await this.getPossiblePartners(character.id);
|
||||
if (family.possiblePartners.length === 0) {
|
||||
await this.createPossiblePartners(character.id, character.gender, character.regionId, character.titleOfNobility);
|
||||
await this.createPossiblePartners(character.id, character.gender, character.regionId, character.titleOfNobility, ownAge);
|
||||
family.possiblePartners = await this.getPossiblePartners(character.id);
|
||||
}
|
||||
}
|
||||
@@ -1073,7 +1122,6 @@ class FalukantService extends BaseService {
|
||||
return proposals.map(proposal => {
|
||||
const birthdate = new Date(proposal.proposedCharacter.birthdate);
|
||||
const age = calcAge(birthdate);
|
||||
console.log(proposal.proposedCharacter);
|
||||
return {
|
||||
id: proposal.id,
|
||||
requesterCharacterId: proposal.requesterCharacterId,
|
||||
@@ -1087,27 +1135,32 @@ class FalukantService extends BaseService {
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async createPossiblePartners(requestingCharacterId, requestingCharacterGender, requestingRegionId, requestingCharacterTitleOfNobility) {
|
||||
|
||||
async createPossiblePartners(requestingCharacterId, requestingCharacterGender, requestingRegionId, requestingCharacterTitleOfNobility, ownAge) {
|
||||
try {
|
||||
const minTitleResult = await TitleOfNobility.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
order: [['id', 'ASC']],
|
||||
attributes: ['id'],
|
||||
});
|
||||
if (!minTitleResult) {
|
||||
throw new Error('No title of nobility found');
|
||||
}
|
||||
const minTitle = minTitleResult.id;
|
||||
const minTitle = minTitleResult.id;
|
||||
|
||||
const potentialPartners = await FalukantCharacter.findAll({
|
||||
where: {
|
||||
id: { [Op.ne]: requestingCharacterId },
|
||||
gender: { [Op.ne]: requestingCharacterGender },
|
||||
regionId: requestingRegionId,
|
||||
createdAt: { [Op.lt]: new Date(new Date() - 12 * 24 * 60 * 60 * 1000) },
|
||||
id: { [Op.ne]: requestingCharacterId },
|
||||
gender: { [Op.ne]: requestingCharacterGender },
|
||||
regionId: requestingRegionId,
|
||||
createdAt: { [Op.lt]: new Date(new Date() - 12 * 24 * 60 * 60 * 1000) },
|
||||
titleOfNobility: { [Op.between]: [requestingCharacterTitleOfNobility - 1, requestingCharacterTitleOfNobility + 1] }
|
||||
},
|
||||
order: [
|
||||
[Sequelize.literal(`ABS((EXTRACT(EPOCH FROM (NOW() - "birthdate")) / 86400) - ${ownAge})`), 'ASC']
|
||||
],
|
||||
limit: 5,
|
||||
});
|
||||
|
||||
const proposals = potentialPartners.map(partner => {
|
||||
const age = calcAge(partner.birthdate);
|
||||
return {
|
||||
@@ -1130,8 +1183,8 @@ class FalukantService extends BaseService {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
const proposal = await MarriageProposal.findOne({
|
||||
where: {
|
||||
requesterCharacterId: character.id,
|
||||
where: {
|
||||
requesterCharacterId: character.id,
|
||||
proposedCharacterId: proposedCharacterId,
|
||||
},
|
||||
});
|
||||
@@ -1139,7 +1192,6 @@ class FalukantService extends BaseService {
|
||||
throw new Error('Proposal not found');
|
||||
}
|
||||
if (user.money < proposal.cost) {
|
||||
console.log(user, proposal);
|
||||
throw new Error('Not enough money to accept the proposal');
|
||||
}
|
||||
const moneyResult = await updateFalukantUserMoney(user.id, -proposal.cost, 'Marriage cost', user.id);
|
||||
@@ -1158,12 +1210,12 @@ class FalukantService extends BaseService {
|
||||
relationshipTypeId: marriedType.id,
|
||||
});
|
||||
await MarriageProposal.destroy({
|
||||
where: { character1Id: character.id },
|
||||
where: { requesterCharacterId: character.id },
|
||||
})
|
||||
;
|
||||
;
|
||||
return { success: true, message: 'Marriage proposal accepted' };
|
||||
}
|
||||
|
||||
|
||||
async getGifts(hashedUserId) {
|
||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||
const character = await FalukantCharacter.findOne({
|
||||
@@ -1172,7 +1224,20 @@ class FalukantService extends BaseService {
|
||||
if (!character) {
|
||||
throw new Error('Character not found');
|
||||
}
|
||||
let gifts = await PromotionalGift.findAll();
|
||||
let gifts = await PromotionalGift.findAll({
|
||||
include: [
|
||||
{
|
||||
model: PromotionalGiftMood,
|
||||
as: 'promotionalgiftmoods',
|
||||
attributes: ['mood_id', 'suitability']
|
||||
},
|
||||
{
|
||||
model: PromotionalGiftCharacterTrait,
|
||||
as: 'characterTraits',
|
||||
attributes: ['trait_id', 'suitability']
|
||||
}
|
||||
]
|
||||
});
|
||||
const lowestTitleOfNobility = await TitleOfNobility.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
});
|
||||
@@ -1181,61 +1246,107 @@ class FalukantService extends BaseService {
|
||||
id: gift.id,
|
||||
name: gift.name,
|
||||
cost: await this.getGiftCost(gift.value, character.titleOfNobility, lowestTitleOfNobility.id),
|
||||
moodsAffects: gift.promotionalgiftmoods,
|
||||
charactersAffects: gift.characterTraits,
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
async sendGift(hashedUserId, giftId) {
|
||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||
const lowestTitleOfNobility = await TitleOfNobility.findOne({
|
||||
order: [['id', 'ASC']],
|
||||
});
|
||||
const relation = Relationship.findOne({
|
||||
where: {
|
||||
character1Id: user.character.id,
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: RelationshipType,
|
||||
as: 'relationshipType',
|
||||
where: { tr: 'wooing' },
|
||||
}
|
||||
],
|
||||
const lowestTitle = await TitleOfNobility.findOne({ order: [['id', 'ASC']] });
|
||||
const currentMoodId = user.character.moodId;
|
||||
if (currentMoodId == null) {
|
||||
throw new Error('moodNotSet');
|
||||
}
|
||||
const relation = await Relationship.findOne({
|
||||
where: { character1Id: user.character.id },
|
||||
include: [{
|
||||
model: RelationshipType,
|
||||
as: 'relationshipType',
|
||||
where: { tr: 'wooing' }
|
||||
}]
|
||||
});
|
||||
if (!relation) {
|
||||
throw new Error('User and character are not related');
|
||||
throw new Error('notRelated');
|
||||
}
|
||||
console.log(user);
|
||||
const gift = await PromotionalGift.findOne({
|
||||
const lastGift = await PromotionalGiftLog.findOne({
|
||||
where: { senderCharacterId: user.character.id },
|
||||
order: [['createdAt', 'DESC']],
|
||||
limit: 1
|
||||
});
|
||||
if (lastGift && (lastGift.createdAt.getTime() + 3_600_000) > Date.now()) {
|
||||
throw new PreconditionError('tooOften');
|
||||
}
|
||||
const gift = await PromotionalGift.findOne({
|
||||
where: { id: giftId },
|
||||
include: [
|
||||
{
|
||||
model: PromotionalGiftCharacterTrait,
|
||||
as: 'characterTraits',
|
||||
where: { trait_id: { [Op.in]: user.character.characterTraits.map(trait => trait.id) }, },
|
||||
where: { trait_id: { [Op.in]: user.character.traits.map(t => t.id) } },
|
||||
required: false
|
||||
},
|
||||
{
|
||||
model: PromotionalGiftMood,
|
||||
as: 'promotionalgiftmoods',
|
||||
},
|
||||
where: { mood_id: currentMoodId },
|
||||
required: false
|
||||
}
|
||||
]
|
||||
});
|
||||
const cost = await this.getGiftCost(gift.value, user.character.titleOfNobility, lowestTitleOfNobility.id);
|
||||
if (user.money < cost) {
|
||||
console.log(user, user.money, cost);
|
||||
throw new Error('Not enough money to send the gift');
|
||||
if (!gift) {
|
||||
throw new Error('notFound');
|
||||
}
|
||||
console.log(JSON.stringify(gift));
|
||||
const changeValue = gift.characterTraits.suitability + gift.promotionalgiftmoods.suitability - 4;
|
||||
this.updateFalukantUserMoney(user.id, -cost, 'Gift cost', user.id);
|
||||
await relation.update({ value: relation.value + changeValue });
|
||||
const cost = await this.getGiftCost(
|
||||
gift.value,
|
||||
user.character.nobleTitle.id,
|
||||
lowestTitle.id
|
||||
);
|
||||
if (user.money < cost) {
|
||||
throw new PreconditionError('insufficientFunds');
|
||||
}
|
||||
const traits = gift.characterTraits;
|
||||
if (!traits.length) {
|
||||
throw new Error('noTraits');
|
||||
}
|
||||
const traitAvg = traits.reduce((sum, ct) => sum + ct.suitability, 0) / traits.length;
|
||||
const moodRecord = gift.promotionalgiftmoods[0];
|
||||
if (!moodRecord) {
|
||||
throw new Error('noMoodData');
|
||||
}
|
||||
const moodSuitability = moodRecord.suitability;
|
||||
const changeValue = Math.round(traitAvg + moodSuitability - 5);
|
||||
await updateFalukantUserMoney(user.id, -cost, 'Gift cost', user.id);
|
||||
await relation.update({ nextStepProgress: relation.nextStepProgress + changeValue });
|
||||
await PromotionalGiftLog.create({
|
||||
senderCharacterId: user.character.id,
|
||||
recipientCharacterId: relation.character2Id,
|
||||
giftId: giftId,
|
||||
changeValue: changeValue,
|
||||
giftId,
|
||||
changeValue
|
||||
});
|
||||
return { success: true, message: 'Gift sent' };
|
||||
this.checkProposalProgress(relation);
|
||||
return { success: true, message: 'sent' };
|
||||
}
|
||||
|
||||
async checkProposalProgress(relation) {
|
||||
const { nextStepProgress } = relation;
|
||||
if (nextStepProgress >= 100) {
|
||||
const engagedStatus = await RelationshipType.findOne({ where: { tr: 'engaged' } });
|
||||
await relation.update({ nextStepProgress: 0, relationshipTypeId: engagedStatus.id });
|
||||
const user = await User.findOne({
|
||||
include: [{
|
||||
model: FalukantUser,
|
||||
as: 'falukantData',
|
||||
include: [{
|
||||
model: FalukantCharacter,
|
||||
as: 'character',
|
||||
where: { id: relation.character1Id }
|
||||
}]
|
||||
}]
|
||||
});
|
||||
await notifyUser(user.hashedId, 'familychanged');
|
||||
}
|
||||
}
|
||||
|
||||
async getGiftCost(value, titleOfNobility, lowestTitleOfNobility) {
|
||||
@@ -1248,8 +1359,114 @@ class FalukantService extends BaseService {
|
||||
}
|
||||
|
||||
async getHouseTypes() {
|
||||
// return House
|
||||
// return House
|
||||
}
|
||||
|
||||
async getMoodAffect() {
|
||||
return PromotionalGiftMood.findAll();
|
||||
}
|
||||
|
||||
async getCharacterAffect() {
|
||||
return PromotionalGiftCharacterTrait.findAll();
|
||||
}
|
||||
|
||||
async getUserHouse(hashedUserId) {
|
||||
try {
|
||||
const user = await User.findOne({
|
||||
where: { hashedId: hashedUserId },
|
||||
include: [{
|
||||
model: FalukantUser,
|
||||
as: 'falukantData',
|
||||
include: [{
|
||||
model: UserHouse,
|
||||
as: 'userHouse',
|
||||
include: [{
|
||||
model: HouseType,
|
||||
as: 'houseType',
|
||||
attributes: ['position', 'cost']
|
||||
}],
|
||||
attributes: ['roofCondition', 'wallCondition', 'floorCondition', 'windowCondition']
|
||||
}],
|
||||
}
|
||||
]
|
||||
});
|
||||
console.log(user.falukantData[0].userHouse);
|
||||
return user.falukantData[0].userHouse ?? { position: 0, roofCondition: 100, wallCondition: 100, floorCondition: 100, windowCondition: 100 };
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
async getBuyableHouses(hashedUserId) {
|
||||
try {
|
||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||
const houses = await BuyableHouse.findAll({
|
||||
include: [{
|
||||
model: HouseType,
|
||||
as: 'houseType',
|
||||
attributes: ['position', 'cost'],
|
||||
where: {
|
||||
minimumNobleTitle: {
|
||||
[Op.lte]: user.character.nobleTitle.id
|
||||
}
|
||||
}
|
||||
}],
|
||||
attributes: ['roofCondition', 'wallCondition', 'floorCondition', 'windowCondition', 'id'],
|
||||
order: [
|
||||
[{ model: HouseType, as: 'houseType' }, 'position', 'DESC'],
|
||||
['wallCondition', 'DESC'],
|
||||
['roofCondition', 'DESC'],
|
||||
['floorCondition', 'DESC'],
|
||||
['windowCondition', 'DESC']
|
||||
]
|
||||
});
|
||||
return houses;
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden der kaufbaren Häuser:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async buyUserHouse(hashedUserId, houseId) {
|
||||
try {
|
||||
const falukantUser = await getFalukantUserOrFail(hashedUserId);
|
||||
const house = await BuyableHouse.findByPk(houseId, {
|
||||
include: [{
|
||||
model: HouseType,
|
||||
as: 'houseType',
|
||||
}],
|
||||
});
|
||||
if (!house) {
|
||||
throw new Error('Das Haus wurde nicht gefunden.');
|
||||
}
|
||||
const housePrice = this.housePrice(house);
|
||||
const oldHouse = await UserHouse.findOne({ where: { userId: falukantUser.id } });
|
||||
if (falukantUser.money < housePrice) {
|
||||
throw new Error('notenoughmoney.');
|
||||
}
|
||||
if (oldHouse) {
|
||||
await oldHouse.destroy();
|
||||
}
|
||||
await UserHouse.create({
|
||||
userId: falukantUser.id,
|
||||
houseTypeId: house.houseTypeId,
|
||||
});
|
||||
await house.destroy();
|
||||
await updateFalukantUserMoney(falukantUser.id, -housePrice, "housebuy", falukantUser.id);
|
||||
const user = await User.findByPk(falukantUser.userId);
|
||||
notifyUser(user.hashedId, 'falukantHouseUpdate', {});
|
||||
return {};
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Kaufen des Hauses:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
housePrice(house) {
|
||||
const houseQuality = (house.roofCondition + house.windowCondition + house.floorCondition + house.wallCondition) / 4;
|
||||
return (house.houseType.cost / 100 * houseQuality ).toFixed(2);
|
||||
}
|
||||
}
|
||||
|
||||
export default new FalukantService();
|
||||
|
||||
@@ -6,6 +6,8 @@ import CharacterTrait from "../../models/falukant/type/character_trait.js";
|
||||
import PromotionalGift from "../../models/falukant/type/promotional_gift.js";
|
||||
import PromotionalGiftCharacterTrait from "../../models/falukant/predefine/promotional_gift_character_trait.js";
|
||||
import PromotionalGiftMood from "../../models/falukant/predefine/promotional_gift_mood.js";
|
||||
import HouseType from '../../models/falukant/type/house.js';
|
||||
import TitleOfNobility from "../../models/falukant/type/title_of_nobility.js";
|
||||
|
||||
export const initializeFalukantTypes = async () => {
|
||||
await initializeFalukantTypeRegions();
|
||||
@@ -14,6 +16,7 @@ export const initializeFalukantTypes = async () => {
|
||||
await initializeFalukantCharacterTraits();
|
||||
await initializeFalukantPromotionalGifts();
|
||||
await initializePromotionalGiftMoodLinks();
|
||||
await initializeFalukantHouseTypes();
|
||||
};
|
||||
|
||||
const regionTypes = [];
|
||||
@@ -204,6 +207,52 @@ const promotionalGiftMoodLinks = [
|
||||
{ gift: "Horse", mood: "nervous", suitability: 4 },
|
||||
];
|
||||
|
||||
const houseTypes = [
|
||||
{ labelTr: 'Unter der Brücke', abbr: 'under_bridge', cost: 10, position: 1, minimumTitle: 'noncivil' },
|
||||
{ labelTr: 'Strohhütte', abbr: 'straw_hut', cost: 20, position: 2, minimumTitle: 'noncivil' },
|
||||
{ labelTr: 'Holzhaus', abbr: 'wooden_house', cost: 50, position: 3, minimumTitle: 'civil' },
|
||||
{ labelTr: 'Hinterhofzimmer', abbr: 'backyard_room', cost: 5, position: 4, minimumTitle: 'civil' },
|
||||
{ labelTr: 'Kleines Familienhaus', abbr: 'family_house', cost: 100, position: 5, minimumTitle: 'sir' },
|
||||
{ labelTr: 'Stadthaus', abbr: 'townhouse', cost: 200, position: 6, minimumTitle: 'townlord' },
|
||||
{ labelTr: 'Villa', abbr: 'villa', cost: 500, position: 7, minimumTitle: 'knight' },
|
||||
{ labelTr: 'Herrenhaus', abbr: 'mansion', cost: 1000, position: 8, minimumTitle: 'ruler' },
|
||||
{ labelTr: 'Schloss', abbr: 'castle', cost: 5000, position: 9, minimumTitle: 'prince-regent' },
|
||||
];
|
||||
|
||||
{
|
||||
const giftNames = promotionalGifts.map(g => g.name);
|
||||
const traitNames = characterTraits.map(t => t.name);
|
||||
|
||||
giftNames.forEach(giftName => {
|
||||
traitNames.forEach(traitName => {
|
||||
if (!promotionalGiftTraitLinks.some(l => l.gift === giftName && l.trait === traitName)) {
|
||||
promotionalGiftTraitLinks.push({
|
||||
gift: giftName,
|
||||
trait: traitName,
|
||||
suitability: Math.floor(Math.random() * 5) + 1,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const giftNames = promotionalGifts.map(g => g.name);
|
||||
const moodNames = moods.map(m => m.name);
|
||||
|
||||
giftNames.forEach(giftName => {
|
||||
moodNames.forEach(moodName => {
|
||||
if (!promotionalGiftMoodLinks.some(l => l.gift === giftName && l.mood === moodName)) {
|
||||
promotionalGiftMoodLinks.push({
|
||||
gift: giftName,
|
||||
mood: moodName,
|
||||
suitability: Math.floor(Math.random() * 5) + 1,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const initializeFalukantTypeRegions = async () => {
|
||||
for (const regionType of regionTypeTrs) {
|
||||
const [regionTypeRecord] = await RegionType.findOrCreate({
|
||||
@@ -303,6 +352,8 @@ export const initializePromotionalGiftTraitLinks = async () => {
|
||||
},
|
||||
defaults: {
|
||||
suitability: link.suitability,
|
||||
gift_id: gift.id,
|
||||
trait_id: trait.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -316,15 +367,27 @@ export const initializePromotionalGiftMoodLinks = async () => {
|
||||
console.error(`Gift or Mood not found for: ${link.gift}, ${link.mood}`);
|
||||
continue;
|
||||
}
|
||||
await PromotionalGiftMood.findOrCreate({
|
||||
where: {
|
||||
gift_id: gift.id,
|
||||
mood_id: mood.id,
|
||||
},
|
||||
defaults: {
|
||||
suitability: link.suitability,
|
||||
},
|
||||
|
||||
await PromotionalGiftMood.create({
|
||||
gift_id: gift.id,
|
||||
mood_id: mood.id,
|
||||
suitability: link.suitability,
|
||||
}).catch(err => {
|
||||
if (err.name !== 'SequelizeUniqueConstraintError') throw err;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const initializeFalukantHouseTypes = async () => {
|
||||
for (const ht of houseTypes) {
|
||||
const [record, created] = await HouseType.findOrCreate({
|
||||
where: { labelTr: ht.abbr },
|
||||
defaults: {
|
||||
cost: ht.cost,
|
||||
imageUrl: null,
|
||||
position: ht.position,
|
||||
minimumNobleTitle: await TitleOfNobility.findOne({ where: { labelTr: ht.minimumTitle } }).then(title => title.id),
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user