Spiel erweitert

This commit is contained in:
Torsten Schulz
2025-06-02 11:26:45 +02:00
parent a9e6c82275
commit 5029be81e9
56 changed files with 4549 additions and 436 deletions

View File

@@ -20,6 +20,7 @@ class FalukantController {
this.getDirectorProposals = this.getDirectorProposals.bind(this);
this.convertProposalToDirector = this.convertProposalToDirector.bind(this);
this.getDirectorForBranch = this.getDirectorForBranch.bind(this);
this.getAllDirectors = this.getAllDirectors.bind(this);
this.setSetting = this.setSetting.bind(this);
this.getFamily = this.getFamily.bind(this);
this.acceptMarriageProposal = this.acceptMarriageProposal.bind(this);
@@ -32,6 +33,21 @@ class FalukantController {
this.getUserHouse = this.getUserHouse.bind(this);
this.getBuyableHouses = this.getBuyableHouses.bind(this);
this.buyUserHouse = this.buyUserHouse.bind(this);
this.getPartyTypes = this.getPartyTypes.bind(this);
this.createParty = this.createParty.bind(this);
this.getParties = this.getParties.bind(this);
this.getNotBaptisedChildren = this.getNotBaptisedChildren.bind(this);
this.baptise = this.baptise.bind(this);
this.getEducation = this.getEducation.bind(this);
this.getChildren = this.getChildren.bind(this);
this.sendToSchool = this.sendToSchool.bind(this);
this.getBankOverview = this.getBankOverview.bind(this);
this.getBankCredits = this.getBankCredits.bind(this);
this.takeBankCredits = this.takeBankCredits.bind(this);
this.getNobility = this.getNobility.bind(this);
this.advanceNobility = this.advanceNobility.bind(this);
this.getHealth = this.getHealth.bind(this);
this.healthActivity = this.healthActivity.bind(this);
}
async getUser(req, res) {
@@ -324,6 +340,27 @@ class FalukantController {
}
}
async getAllDirectors(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.getAllDirectors(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
}
async updateDirector(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const { directorId, income } = req.body;
const result = await FalukantService.updateDirector(hashedUserId, directorId, income);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
}
async setSetting(req, res) {
try {
const { userid: hashedUserId } = req.headers;
@@ -373,6 +410,17 @@ class FalukantController {
}
}
async getChildren(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.getChildren(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async sendGift(req, res) {
try {
const { userid: hashedUserId } = req.headers;
@@ -464,6 +512,165 @@ class FalukantController {
console.log(error);
}
}
async getPartyTypes(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.getPartyTypes(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async createParty(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const { partyTypeId, musicId, banquetteId, nobilityIds, servantRatio } = req.body;
const result = await FalukantService.createParty(hashedUserId, partyTypeId, musicId, banquetteId, nobilityIds, servantRatio);
res.status(201).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async getParties(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.getParties(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async getNotBaptisedChildren(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.getNotBaptisedChildren(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async baptise(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const { characterId: childId, firstName } = req.body;
const result = await FalukantService.baptise(hashedUserId, childId, firstName);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async getEducation(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.getEducation(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async sendToSchool(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const { item, student, studentId } = req.body;
const result = await FalukantService.sendToSchool(hashedUserId, item, student, studentId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async getBankOverview(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.getBankOverview(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async getBankCredits(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.getBankCredits(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async takeBankCredits(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const { height } = req.body;
const result = await FalukantService.takeBankCredits(hashedUserId, height);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async getNobility(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.getNobility(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async advanceNobility(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.advanceNobility(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async getHealth(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const result = await FalukantService.getHealth(hashedUserId);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
async healthActivity(req, res) {
try {
const { userid: hashedUserId } = req.headers;
const { measureTr: activity } = req.body;
const result = await FalukantService.healthActivity(hashedUserId, activity);
res.status(200).json(result);
} catch (error) {
res.status(500).json({ error: error.message });
console.log(error);
}
}
}
export default FalukantController;

View File

@@ -105,6 +105,10 @@ const menuStructure = {
visible: ["hasfalukantaccount"],
path: "/falukant/nobility"
},
church: {
visible: ["hasfalukantaccount"],
path: "/falukant/church"
},
politics: {
visible: ["hasfalukantaccount"],
path: "/falukant/politics"

View File

@@ -65,6 +65,26 @@ 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';
import PartyType from './falukant/type/party.js';
import Party from './falukant/data/party.js';
import MusicType from './falukant/type/music.js';
import BanquetteType from './falukant/type/banquette.js';
import PartyInvitedNobility from './falukant/data/partyInvitedNobility.js';
import ChildRelation from './falukant/data/child_relation.js';
import Learning from './falukant/data/learning.js';
import LearnRecipient from './falukant/type/learn_recipient.js';
import Credit from './falukant/data/credit.js';
import DebtorsPrism from './falukant/data/debtors_prism.js';
import HealthActivity from './falukant/log/health_activity.js';
import Election from './falukant/data/election.js';
import ElectionResult from './falukant/data/election_result.js';
import Candidate from './falukant/data/candidate.js';
import Vote from './falukant/data/vote.js';
import PoliticalOfficeType from './falukant/type/political_office_type.js';
import PoliticalOffice from './falukant/data/political_office.js';
import PoliticalOfficeBenefit from './falukant/predefine/political_office_benefit.js';
import PoliticalOfficeBenefitType from './falukant/type/political_office_benefit_type.js';
import PoliticalOfficeRequirement from './falukant/predefine/political_office_prerequisite.js';
export default function setupAssociations() {
// UserParam related associations
@@ -275,7 +295,7 @@ export default function setupAssociations() {
BuyableStock.belongsTo(FalukantStockType, { foreignKey: 'stockTypeId', as: 'stockType' });
FalukantStockType.hasMany(BuyableStock, { foreignKey: 'stockTypeId', as: 'buyableStocks' });
Director.belongsTo(FalukantUser, { foreignKey: 'employerUserId', as: 'user' });
FalukantUser.hasMany(Director, { foreignKey: 'employerUserId', as: 'directors' });
@@ -315,31 +335,31 @@ export default function setupAssociations() {
Notification.belongsTo(FalukantUser, { foreignKey: 'userId', as: 'user' });
FalukantUser.hasMany(Notification, { foreignKey: 'userId', as: 'notifications' });
MarriageProposal.belongsTo(FalukantCharacter, {foreignKey: 'requesterCharacterId', as: 'requesterCharacter', });
MarriageProposal.belongsTo(FalukantCharacter, { foreignKey: 'requesterCharacterId', as: 'requesterCharacter', });
FalukantCharacter.hasMany(MarriageProposal, { foreignKey: 'requesterCharacterId', as: 'initiatedProposals' });
MarriageProposal.belongsTo(FalukantCharacter, {foreignKey: 'proposedCharacterId', as: 'proposedCharacter', });
FalukantCharacter.hasMany(MarriageProposal, {foreignKey: 'proposedCharacterId', as: 'receivedProposals' });
FalukantCharacter.belongsToMany(CharacterTrait, {through: FalukantCharacterTrait, foreignKey: 'character_id', as: 'traits', });
CharacterTrait.belongsToMany(FalukantCharacter, {through: FalukantCharacterTrait, foreignKey: 'trait_id', as: 'characters', });
Mood.hasMany(FalukantCharacter, {foreignKey: 'mood_id', as: 'moods'});
FalukantCharacter.belongsTo(Mood, {foreignKey: 'mood_id', as: 'mood'});
PromotionalGift.belongsToMany(CharacterTrait, {through: PromotionalGiftCharacterTrait, foreignKey: 'gift_id', as: 'traits',});
CharacterTrait.belongsToMany(PromotionalGift, {through: PromotionalGiftCharacterTrait, foreignKey: 'trait_id', as: 'gifts',});
MarriageProposal.belongsTo(FalukantCharacter, { foreignKey: 'proposedCharacterId', as: 'proposedCharacter', });
FalukantCharacter.hasMany(MarriageProposal, { foreignKey: 'proposedCharacterId', as: 'receivedProposals' });
PromotionalGift.belongsToMany(Mood, {through: PromotionalGiftMood, foreignKey: 'gift_id', as: 'moods',});
Mood.belongsToMany(PromotionalGift, {through: PromotionalGiftMood, foreignKey: 'mood_id', as: 'gifts',});
FalukantCharacter.belongsToMany(CharacterTrait, { through: FalukantCharacterTrait, foreignKey: 'character_id', as: 'traits', });
CharacterTrait.belongsToMany(FalukantCharacter, { through: FalukantCharacterTrait, foreignKey: 'trait_id', as: 'characters', });
Mood.hasMany(FalukantCharacter, { foreignKey: 'mood_id', as: 'moods' });
FalukantCharacter.belongsTo(Mood, { foreignKey: 'mood_id', as: 'mood' });
PromotionalGift.belongsToMany(CharacterTrait, { through: PromotionalGiftCharacterTrait, foreignKey: 'gift_id', as: 'traits', });
CharacterTrait.belongsToMany(PromotionalGift, { through: PromotionalGiftCharacterTrait, foreignKey: 'trait_id', as: 'gifts', });
PromotionalGift.belongsToMany(Mood, { through: PromotionalGiftMood, foreignKey: 'gift_id', as: 'moods', });
Mood.belongsToMany(PromotionalGift, { through: PromotionalGiftMood, foreignKey: 'mood_id', as: 'gifts', });
Relationship.belongsTo(RelationshipType, { foreignKey: 'relationshipTypeId', as: 'relationshipType' });
RelationshipType.hasMany(Relationship, { foreignKey: 'relationshipTypeId', as: 'relationships' });
Relationship.belongsTo(FalukantCharacter, {foreignKey: 'character1Id', as: 'character1', });
Relationship.belongsTo(FalukantCharacter, {foreignKey: 'character2Id', as: 'character2', });
FalukantCharacter.hasMany(Relationship, {foreignKey: 'character1Id', as: 'relationshipsAsCharacter1', });
FalukantCharacter.hasMany(Relationship, {foreignKey: 'character2Id', as: 'relationshipsAsCharacter2', });
Relationship.belongsTo(FalukantCharacter, { foreignKey: 'character1Id', as: 'character1', });
Relationship.belongsTo(FalukantCharacter, { foreignKey: 'character2Id', as: 'character2', });
FalukantCharacter.hasMany(Relationship, { foreignKey: 'character1Id', as: 'relationshipsAsCharacter1', });
FalukantCharacter.hasMany(Relationship, { foreignKey: 'character2Id', as: 'relationshipsAsCharacter2', });
PromotionalGiftLog.belongsTo(PromotionalGift, { foreignKey: 'giftId', as: 'gift' });
PromotionalGift.hasMany(PromotionalGiftLog, { foreignKey: 'giftId', as: 'logs' });
@@ -367,4 +387,262 @@ export default function setupAssociations() {
TitleOfNobility.hasMany(HouseType, { foreignKey: 'minimumNobleTitle', as: 'houseTypes' });
HouseType.belongsTo(TitleOfNobility, { foreignKey: 'minimumNobleTitle', as: 'titleOfNobility' });
PartyType.hasMany(Party, { foreignKey: 'partyTypeId', as: 'parties' });
Party.belongsTo(PartyType, { foreignKey: 'partyTypeId', as: 'partyType' });
MusicType.hasMany(Party, { foreignKey: 'musicTypeId', as: 'parties' });
Party.belongsTo(MusicType, { foreignKey: 'musicTypeId', as: 'musicType' });
BanquetteType.hasMany(Party, { foreignKey: 'banquetteTypeId', as: 'parties' });
Party.belongsTo(BanquetteType, { foreignKey: 'banquetteTypeId', as: 'banquetteType' });
FalukantUser.hasMany(Party, { foreignKey: 'falukantUserId', as: 'parties' });
Party.belongsTo(FalukantUser, { foreignKey: 'falukantUserId', as: 'partyUser' });
Party.belongsToMany(TitleOfNobility, {
through: PartyInvitedNobility,
foreignKey: 'party_id',
otherKey: 'title_of_nobility_id',
as: 'invitedNobilities',
});
TitleOfNobility.belongsToMany(Party, {
through: PartyInvitedNobility,
foreignKey: 'title_of_nobility_id',
otherKey: 'party_id',
as: 'partiesInvitedTo',
});
ChildRelation.belongsTo(FalukantCharacter, {
foreignKey: 'fatherCharacterId',
as: 'father'
});
FalukantCharacter.hasMany(ChildRelation, {
foreignKey: 'fatherCharacterId',
as: 'childrenFather'
});
ChildRelation.belongsTo(FalukantCharacter, {
foreignKey: 'motherCharacterId',
as: 'mother'
});
FalukantCharacter.hasMany(ChildRelation, {
foreignKey: 'motherCharacterId',
as: 'childrenMother'
});
ChildRelation.belongsTo(FalukantCharacter, {
foreignKey: 'childCharacterId',
as: 'child'
});
FalukantCharacter.hasMany(ChildRelation, {
foreignKey: 'childCharacterId',
as: 'parentRelations'
});
Learning.belongsTo(LearnRecipient, {
foreignKey: 'learningRecipientId',
as: 'recipient'
}
);
LearnRecipient.hasMany(Learning, {
foreignKey: 'learningRecipientId',
as: 'learnings'
});
Learning.belongsTo(FalukantUser, {
foreignKey: 'associatedFalukantUserId',
as: 'learner'
}
);
FalukantUser.hasMany(Learning, {
foreignKey: 'associatedFalukantUserId',
as: 'learnings'
});
Learning.belongsTo(ProductType, {
foreignKey: 'productId',
as: 'productType'
});
ProductType.hasMany(Learning, {
foreignKey: 'productId',
as: 'learnings'
});
Learning.belongsTo(FalukantCharacter, {
foreignKey: 'associatedLearningCharacterId',
as: 'learningCharacter'
});
FalukantCharacter.hasMany(Learning, {
foreignKey: 'associatedLearningCharacterId',
as: 'learningsCharacter'
});
FalukantUser.hasMany(Credit, {
foreignKey: 'falukantUserId',
as: 'credits'
});
Credit.belongsTo(FalukantUser, {
foreignKey: 'falukantUserId',
as: 'user'
});
FalukantCharacter.hasMany(DebtorsPrism, {
foreignKey: 'character_id',
as: 'debtorsPrisms'
});
DebtorsPrism.belongsTo(FalukantCharacter, {
foreignKey: 'character_id',
as: 'character'
});
HealthActivity.belongsTo(FalukantCharacter, {
foreignKey: 'character_id',
as: 'character'
});
FalukantCharacter.hasMany(HealthActivity, {
foreignKey: 'character_id',
as: 'healthActivities'
});
// — Political Offices —
// predefine requirements for office
PoliticalOfficeRequirement.belongsTo(PoliticalOfficeType, {
foreignKey: 'officeTypeId',
as: 'officeType'
});
PoliticalOfficeType.hasMany(PoliticalOfficeRequirement, {
foreignKey: 'officeTypeId',
as: 'requirements'
});
// predefine benefits for office
PoliticalOfficeBenefit.belongsTo(
PoliticalOfficeBenefitType,
{ foreignKey: 'benefitTypeId', as: 'benefitDefinition' }
);
PoliticalOfficeBenefitType.hasMany(
PoliticalOfficeBenefit,
{ foreignKey: 'benefitTypeId', as: 'benefitDefinitions' }
);
// tie benefits back to office type
PoliticalOfficeBenefit.belongsTo(PoliticalOfficeType, {
foreignKey: 'officeTypeId',
as: 'officeType'
});
PoliticalOfficeType.hasMany(PoliticalOfficeBenefit, {
foreignKey: 'officeTypeId',
as: 'benefits'
});
// actual office holdings
PoliticalOffice.belongsTo(PoliticalOfficeType, {
foreignKey: 'officeTypeId',
as: 'type'
});
PoliticalOfficeType.hasMany(PoliticalOffice, {
foreignKey: 'officeTypeId',
as: 'offices'
});
PoliticalOffice.belongsTo(FalukantCharacter, {
foreignKey: 'characterId',
as: 'holder'
});
FalukantCharacter.hasMany(PoliticalOffice, {
foreignKey: 'characterId',
as: 'heldOffices'
});
// elections
Election.belongsTo(PoliticalOfficeType, {
foreignKey: 'officeTypeId',
as: 'officeType'
});
PoliticalOfficeType.hasMany(Election, {
foreignKey: 'officeTypeId',
as: 'elections'
});
// candidates in an election
Candidate.belongsTo(Election, {
foreignKey: 'electionId',
as: 'election'
});
Election.hasMany(Candidate, {
foreignKey: 'electionId',
as: 'candidates'
});
Candidate.belongsTo(FalukantCharacter, {
foreignKey: 'characterId',
as: 'character'
});
FalukantCharacter.hasMany(Candidate, {
foreignKey: 'characterId',
as: 'candidacies'
});
// votes cast
Vote.belongsTo(Election, {
foreignKey: 'electionId',
as: 'election'
});
Election.hasMany(Vote, {
foreignKey: 'electionId',
as: 'votes'
});
Vote.belongsTo(Candidate, {
foreignKey: 'candidateId',
as: 'candidate'
});
Candidate.hasMany(Vote, {
foreignKey: 'candidateId',
as: 'votes'
});
Vote.belongsTo(FalukantCharacter, {
foreignKey: 'voterCharacterId',
as: 'voter'
});
FalukantCharacter.hasMany(Vote, {
foreignKey: 'voterCharacterId',
as: 'votesCast'
});
// election results
ElectionResult.belongsTo(Election, {
foreignKey: 'electionId',
as: 'election'
});
Election.hasMany(ElectionResult, {
foreignKey: 'electionId',
as: 'results'
});
ElectionResult.belongsTo(Candidate, {
foreignKey: 'candidateId',
as: 'candidate'
});
Candidate.hasMany(ElectionResult, {
foreignKey: 'candidateId',
as: 'results'
});
PoliticalOffice.belongsTo(RegionData, {
foreignKey: 'regionId',
as: 'region'
});
RegionData.hasMany(PoliticalOffice, {
foreignKey: 'regionId',
as: 'offices'
});
}

View File

@@ -0,0 +1,30 @@
// falukant/data/candidate.js
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class Candidate extends Model {}
Candidate.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
election_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
character_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'Candidate',
tableName: 'candidate',
schema: 'falukant_data',
timestamps: true,
underscored: true,
});
export default Candidate;

View File

@@ -0,0 +1,45 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class ChildRelation extends Model {}
ChildRelation.init(
{
fatherCharacterId: {
type: DataTypes.INTEGER,
allowNull: false,
},
motherCharacterId: {
type: DataTypes.INTEGER,
allowNull: false,
},
childCharacterId: {
type: DataTypes.INTEGER,
allowNull: false,
},
fatherName: {
type: DataTypes.STRING,
allowNull: false,
},
motherName: {
type: DataTypes.STRING,
allowNull: false,
},
nameSet: {
type: DataTypes.BOOLEAN,
allowNull: false,
default: false,
},
},
{
sequelize,
modelName: 'ChildRelation',
tableName: 'child_relation', // exakter Tabellenname
schema: 'falukant_data', // exaktes Schema
freezeTableName: true, // keine Pluralisierung
timestamps: true,
underscored: true,
}
);
export default ChildRelation;

View File

@@ -0,0 +1,37 @@
// models/falukant/data/credit.js
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class Credit extends Model {}
Credit.init({
// aufgenommener Kredit-Betrag
amount: {
type: DataTypes.DECIMAL(14,2),
allowNull: false,
},
// noch offener Kreditbetrag
remainingAmount: {
type: DataTypes.DECIMAL(14,2),
allowNull: false,
},
// Zinssatz als Prozentsatz (z.B. 3.5 für 3.5%)
interestRate: {
type: DataTypes.DECIMAL(5,2),
allowNull: false,
},
// Verknüpfung auf FalukantUser
falukantUserId: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'Credit',
tableName: 'credit',
schema: 'falukant_data',
timestamps: true,
underscored: true,
});
export default Credit;

View File

@@ -0,0 +1,21 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class DebtorsPrism extends Model {}
DebtorsPrism.init({
// Verknüpfung auf FalukantCharacter
characterId: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'DebtorsPrism',
tableName: 'debtors_prism',
schema: 'falukant_data',
timestamps: true,
underscored: true,
});
export default DebtorsPrism;

View File

@@ -0,0 +1,34 @@
// falukant/data/election.js
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class Election extends Model {}
Election.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
political_office_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
date: {
type: DataTypes.DATE,
allowNull: false,
},
posts_to_fill: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'Election',
tableName: 'election',
schema: 'falukant_data',
timestamps: true,
underscored: true,
});
export default Election;

View File

@@ -0,0 +1,34 @@
// falukant/data/election_result.js
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class ElectionResult extends Model {}
ElectionResult.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
election_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
candidate_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
votes_received: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'ElectionResult',
tableName: 'election_result',
schema: 'falukant_data',
timestamps: true,
underscored: true,
});
export default ElectionResult;

View File

@@ -0,0 +1,48 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class Learning extends Model {}
Learning.init(
{
learningRecipientId: {
type: DataTypes.INTEGER,
allowNull: false,
},
productId: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
},
learnAllProducts: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
associatedFalukantUserId: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
},
associatedLearningCharacterId: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
},
learningIsExecuted: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
}
},
{
sequelize,
modelName: 'Learning',
tableName: 'learning',
schema: 'falukant_data',
timestamps: true,
underscored: true,
}
);
export default Learning;

View File

@@ -0,0 +1,30 @@
// falukant/data/occupied_political_office.js
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class OccupiedPoliticalOffice extends Model {}
OccupiedPoliticalOffice.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
political_office_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
character_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'OccupiedPoliticalOffice',
tableName: 'occupied_political_office',
schema: 'falukant_data',
timestamps: true,
underscored: true,
});
export default OccupiedPoliticalOffice;

View File

@@ -0,0 +1,46 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class Party extends Model {}
Party.init({
partyTypeId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'party_type_id'
},
falukantUserId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'falukant_user_id'
},
musicTypeId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'music_type'
},
banquetteTypeId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'banquette_type'
},
servantRatio: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'servant_ratio'
},
cost: {
type: DataTypes.FLOAT,
allowNull: false,
defaultValue: 0
},
}, {
sequelize,
modelName: 'Party',
tableName: 'party',
schema: 'falukant_data',
timestamps: true,
underscored: true,
});
export default Party;

View File

@@ -0,0 +1,26 @@
import { Model, DataTypes } from 'sequelize'
import { sequelize } from '../../../utils/sequelize.js'
class PartyInvitedNobility extends Model {}
PartyInvitedNobility.init({
partyId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'party_id'
},
titleOfNobilityId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'title_of_nobility_id'
}
}, {
sequelize,
modelName: 'PartyInvitedNobility',
tableName: 'party_invited_nobility',
schema: 'falukant_data',
timestamps: false,
underscored: true
})
export default PartyInvitedNobility

View File

@@ -0,0 +1,34 @@
// backend/models/falukant/data/political_office.js
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class PoliticalOffice extends Model {}
PoliticalOffice.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
officeTypeId: {
type: DataTypes.INTEGER,
allowNull: false,
},
characterId: {
type: DataTypes.INTEGER,
allowNull: false,
},
regionId: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'PoliticalOffice',
tableName: 'political_office',
schema: 'falukant_data',
timestamps: true,
underscored: true,
});
export default PoliticalOffice;

View File

@@ -0,0 +1,39 @@
// falukant/data/vote.js
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class Vote extends Model {}
Vote.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
election_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
voter_character_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
candidate_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
timestamp: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW,
},
}, {
sequelize,
modelName: 'Vote',
tableName: 'vote',
schema: 'falukant_data',
timestamps: false,
underscored: true,
});
export default Vote;

View File

@@ -0,0 +1,37 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class HealthActivity extends Model { }
HealthActivity.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
characterId: {
type: DataTypes.INTEGER,
allowNull: false,
},
activityTr: {
type: DataTypes.STRING,
allowNull: false,
},
cost: {
type: DataTypes.FLOAT,
allowNull: false,
},
successPercentage: {
type: DataTypes.INTEGER,
allowNull: false
}
}, {
sequelize,
modelName: 'health_activity',
tableName: 'health_activity',
schema: 'falukant_log',
timestamps: true,
underscored: true,
});
export default HealthActivity;

View File

@@ -0,0 +1,45 @@
// falukant/predefine/political_office_benefit.js
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
import PoliticalOfficeBenefitType from '../type/political_office_benefit_type.js';
class PoliticalOfficeBenefit extends Model {}
PoliticalOfficeBenefit.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
political_office_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
benefit_type_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
value: {
type: DataTypes.JSONB,
allowNull: false,
},
}, {
sequelize,
modelName: 'PoliticalOfficeBenefit',
tableName: 'political_office_benefit',
schema: 'falukant_predefine',
timestamps: false,
underscored: true,
});
// Association
PoliticalOfficeBenefit.belongsTo(PoliticalOfficeBenefitType, {
foreignKey: 'benefit_type_id',
as: 'benefitType'
});
PoliticalOfficeBenefitType.hasMany(PoliticalOfficeBenefit, {
foreignKey: 'benefit_type_id',
as: 'benefits'
});
export default PoliticalOfficeBenefit;

View File

@@ -0,0 +1,30 @@
// falukant/predefine/political_office_prerequisite.js
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class PoliticalOfficePrerequisite extends Model {}
PoliticalOfficePrerequisite.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
political_office_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
prerequisite: {
type: DataTypes.JSONB,
allowNull: false,
},
}, {
sequelize,
modelName: 'PoliticalOfficePrerequisite',
tableName: 'political_office_prerequisite',
schema: 'falukant_predefine',
timestamps: false,
underscored: true,
});
export default PoliticalOfficePrerequisite;

View File

@@ -0,0 +1,31 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class BanquetteType extends Model {}
BanquetteType.init(
{
tr: {
type: DataTypes.STRING,
allowNull: false,
},
cost: {
type: DataTypes.INTEGER,
allowNull: false,
},
reputationGrowth: {
type: DataTypes.INTEGER,
allowNull: false,
},
},
{
sequelize,
modelName: 'BanquetteType',
tableName: 'banquette',
schema: 'falukant_type',
timestamps: false,
underscored: true,
}
);
export default BanquetteType;

View File

@@ -0,0 +1,23 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class LearnRecipient extends Model {}
LearnRecipient.init(
{
tr: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
sequelize,
modelName: 'LearnRecipient',
tableName: 'learn_recipient',
schema: 'falukant_type',
timestamps: false,
underscored: true,
}
);
export default LearnRecipient;

View File

@@ -0,0 +1,31 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class MusicType extends Model {}
MusicType.init(
{
tr: {
type: DataTypes.STRING,
allowNull: false,
},
cost: {
type: DataTypes.INTEGER,
allowNull: false,
},
reputationGrowth: {
type: DataTypes.INTEGER,
allowNull: false,
},
},
{
sequelize,
modelName: 'MusicType',
tableName: 'music',
schema: 'falukant_type',
timestamps: false,
underscored: true,
}
);
export default MusicType;

View File

@@ -0,0 +1,36 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class PartyType extends Model {}
PartyType.init(
{
tr: {
type: DataTypes.STRING,
allowNull: false,
},
cost: {
type: DataTypes.INTEGER,
allowNull: false,
},
forMarriage: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
reputationGrowth: {
type: DataTypes.INTEGER,
allowNull: false,
}
},
{
sequelize,
modelName: 'PartyType',
tableName: 'party',
schema: 'falukant_type',
timestamps: false,
underscored: true,
}
);
export default PartyType;

View File

@@ -0,0 +1,26 @@
// falukant/type/political_office_benefit_type.js
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class PoliticalOfficeBenefitType extends Model {}
PoliticalOfficeBenefitType.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
tr: {
type: DataTypes.STRING,
allowNull: false,
},
}, {
sequelize,
modelName: 'PoliticalOfficeBenefitType',
tableName: 'political_office_benefit_type',
schema: 'falukant_type',
timestamps: false,
underscored: true,
});
export default PoliticalOfficeBenefitType;

View File

@@ -0,0 +1,38 @@
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../../utils/sequelize.js';
class PoliticalOfficeType extends Model {}
PoliticalOfficeType.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
seatsPerRegion: {
type: DataTypes.INTEGER,
allowNull: false,
},
regionType: {
type: DataTypes.STRING,
allowNull: false,
},
termLength: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
},
}, {
sequelize,
modelName: 'PoliticalOfficeType',
tableName: 'political_office_type',
schema: 'falukant_type',
timestamps: false,
underscored: true,
});
export default PoliticalOfficeType;

View File

@@ -8,6 +8,11 @@ TitleOfNobility.init({
type: DataTypes.STRING,
allowNull: false,
},
level: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
},
}, {
sequelize,
modelName: 'Title',

View File

@@ -4,12 +4,16 @@ import { sequelize } from '../../../utils/sequelize.js';
class TitleRequirement extends Model { }
TitleRequirement.init({
titleId: {
id : {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true,
},
titleId: {
type: DataTypes.INTEGER,
allowNull: false,
},
requirementType: {
type: DataTypes.STRING,
allowNull: false,
@@ -19,12 +23,19 @@ TitleRequirement.init({
allowNull: false,
},
}, {
sequelize,
modelName: 'TitleRequirement',
sequelize,
modelName: 'TitleRequirement',
tableName: 'title_requirement',
schema: 'falukant_type',
timestamps: false,
underscored: true,
indexes: [
{
unique: true,
fields: ['title_id', 'requirement_type'],
name: 'title_requirement_titleid_reqtype_unique'
}
]
});
export default TitleRequirement;

View File

@@ -1,3 +1,5 @@
// models/index.js
import SettingsType from './type/settings.js';
import UserParamValue from './type/user_param_value.js';
import UserParamType from './type/user_param.js';
@@ -32,6 +34,7 @@ import MessageHistory from './forum/message_history.js';
import MessageImage from './forum/message_image.js';
import ForumForumPermission from './forum/forum_forum_permission.js';
import Friendship from './community/friendship.js';
import FalukantUser from './falukant/data/user.js';
import RegionType from './falukant/type/region.js';
import RegionData from './falukant/data/region.js';
@@ -58,90 +61,136 @@ import DaySell from './falukant/log/daysell.js';
import Notification from './falukant/log/notification.js';
import MarriageProposal from './falukant/data/marriage_proposal.js';
import RelationshipType from './falukant/type/relationship.js';
import Relationship from './falukant/data/relationship.js';
import CharacterTrait from './falukant/type/character_trait.js';
import FalukantCharacterTrait from './falukant/data/falukant_character_trait.js';
import Mood from './falukant/type/mood.js';
import PromotionalGift from './falukant/type/promotional_gift.js';
import PromotionalGiftCharacterTrait from './falukant/predefine/promotional_gift_character_trait.js';
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';
import PartyType from './falukant/type/party.js';
import Party from './falukant/data/party.js';
import MusicType from './falukant/type/music.js';
import BanquetteType from './falukant/type/banquette.js';
import PartyInvitedNobility from './falukant/data/partyInvitedNobility.js';
import ChildRelation from './falukant/data/child_relation.js';
import LearnRecipient from './falukant/type/learn_recipient.js';
import Learning from './falukant/data/learning.js';
import Credit from './falukant/data/credit.js';
import DebtorsPrism from './falukant/data/debtors_prism.js';
import HealthActivity from './falukant/log/health_activity.js';
// — Politische Ämter (Politics) —
import PoliticalOfficeType from './falukant/type/political_office_type.js';
import PoliticalOfficeRequirement from './falukant/predefine/political_office_prerequisite.js';
import PoliticalOfficeBenefitType from './falukant/type/political_office_benefit_type.js';
import PoliticalOfficeBenefit from './falukant/predefine/political_office_benefit.js';
import PoliticalOffice from './falukant/data/political_office.js';
import Election from './falukant/data/election.js';
import Candidate from './falukant/data/candidate.js';
import Vote from './falukant/data/vote.js';
import ElectionResult from './falukant/data/election_result.js';
const models = {
SettingsType,
UserParamValue,
UserParamType,
UserRightType,
User,
UserParam,
Login,
UserRight,
InterestType,
InterestTranslationType,
Interest,
ContactMessage,
UserParamVisibilityType,
UserParamVisibility,
Folder,
Image,
ImageVisibilityType,
ImageVisibilityUser,
FolderImageVisibility,
ImageImageVisibility,
FolderVisibilityUser,
GuestbookEntry,
DiaryHistory,
Diary,
Forum,
ForumPermission,
ForumForumPermission,
ForumUserPermission,
Title,
TitleHistory,
Message,
MessageHistory,
MessageImage,
Friendship,
RegionType,
RegionData,
FalukantUser,
FalukantPredefineFirstname,
FalukantPredefineLastname,
FalukantCharacter,
FalukantStock,
FalukantStockType,
ProductType,
Knowledge,
TitleOfNobility,
TitleRequirement,
BranchType,
Branch,
Production,
Inventory,
BuyableStock,
MoneyFlow,
Director,
DirectorProposal,
TownProductWorth,
DayProduction,
DaySell,
Notification,
MarriageProposal,
RelationshipType,
Relationship,
CharacterTrait,
FalukantCharacterTrait,
Mood,
PromotionalGift,
PromotionalGiftCharacterTrait,
PromotionalGiftMood,
PromotionalGiftLog,
HouseType,
BuyableHouse,
UserHouse,
SettingsType,
UserParamValue,
UserParamType,
UserRightType,
User,
UserParam,
Login,
UserRight,
InterestType,
InterestTranslationType,
Interest,
ContactMessage,
UserParamVisibilityType,
UserParamVisibility,
Folder,
Image,
ImageVisibilityType,
ImageVisibilityUser,
FolderImageVisibility,
ImageImageVisibility,
FolderVisibilityUser,
GuestbookEntry,
DiaryHistory,
Diary,
Forum,
ForumPermission,
ForumForumPermission,
ForumUserPermission,
Title,
TitleHistory,
Message,
MessageHistory,
MessageImage,
Friendship,
// Falukant core
RegionType,
RegionData,
FalukantUser,
FalukantPredefineFirstname,
FalukantPredefineLastname,
FalukantCharacter,
FalukantStock,
FalukantStockType,
ProductType,
Knowledge,
TitleOfNobility,
TitleRequirement,
BranchType,
Branch,
Production,
Inventory,
BuyableStock,
MoneyFlow,
Director,
DirectorProposal,
TownProductWorth,
DayProduction,
DaySell,
Notification,
MarriageProposal,
RelationshipType,
Relationship,
CharacterTrait,
FalukantCharacterTrait,
Mood,
PromotionalGift,
PromotionalGiftCharacterTrait,
PromotionalGiftMood,
PromotionalGiftLog,
HouseType,
BuyableHouse,
UserHouse,
PartyType,
MusicType,
BanquetteType,
Party,
PartyInvitedNobility,
ChildRelation,
LearnRecipient,
Learning,
Credit,
DebtorsPrism,
HealthActivity,
// Politics
PoliticalOfficeType,
PoliticalOfficeRequirement,
PoliticalOfficeBenefitType,
PoliticalOfficeBenefit,
PoliticalOffice,
Election,
Candidate,
Vote,
ElectionResult,
};
export default models;

View File

@@ -180,6 +180,67 @@ export async function createTriggers() {
$function$;
`;
const createChildRelationNameFunction = `
CREATE OR REPLACE FUNCTION falukant_data.populate_child_relation_names()
RETURNS TRIGGER AS $$
DECLARE
v_first_name TEXT;
v_last_name TEXT;
v_full_father TEXT;
v_full_mother TEXT;
BEGIN
-- Vaternamen holen
SELECT pf.name, pl.name
INTO v_first_name, v_last_name
FROM falukant_data.character c
JOIN falukant_predefine.firstname pf ON pf.id = c.first_name
JOIN falukant_predefine.lastname pl ON pl.id = c.last_name
WHERE c.id = NEW.father_character_id;
v_full_father := v_first_name || ' ' || v_last_name;
-- Mutternamen holen
SELECT pf.name, pl.name
INTO v_first_name, v_last_name
FROM falukant_data.character c
JOIN falukant_predefine.firstname pf ON pf.id = c.first_name
JOIN falukant_predefine.lastname pl ON pl.id = c.last_name
WHERE c.id = NEW.mother_character_id;
v_full_mother := v_first_name || ' ' || v_last_name;
-- Felder füllen
NEW.father_name := v_full_father;
NEW.mother_name := v_full_mother;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
`;
const createChildRelationNameTrigger = `
DROP TRIGGER IF EXISTS trg_child_relation_populate_names
ON falukant_data.child_relation;
CREATE TRIGGER trg_child_relation_populate_names
BEFORE INSERT ON falukant_data.child_relation
FOR EACH ROW
EXECUTE FUNCTION falukant_data.populate_child_relation_names();
`;
const createRandomMoodUpdateMethod = `
CREATE OR REPLACE FUNCTION falukant_data.get_random_mood_id()
RETURNS INTEGER AS $$
BEGIN
RETURN (
SELECT id
FROM falukant_type.mood
ORDER BY random()
LIMIT 1
);
END;
$$ LANGUAGE plpgsql VOLATILE;
`;
try {
await sequelize.query(createTriggerFunction);
await sequelize.query(createInsertTrigger);
@@ -193,7 +254,10 @@ export async function createTriggers() {
await sequelize.query(createKnowledgeTriggerMethod);
await sequelize.query(createKnowledgeTrigger);
await sequelize.query(updateMoney);
await initializeCharacterTraitTrigger();
await sequelize.query(createChildRelationNameFunction);
await sequelize.query(createChildRelationNameTrigger);
await sequelize.query(createRandomMoodUpdateMethod);
await initializeCharacterTraitTrigger();
console.log('Triggers created successfully');
} catch (error) {
@@ -250,4 +314,3 @@ export const initializeCharacterTraitTrigger = async () => {
console.error('❌ Fehler beim Erstellen des Triggers:', error);
}
};

View File

@@ -6,6 +6,8 @@ const falukantController = new FalukantController();
router.get('/user', falukantController.getUser);
router.post('/user', falukantController.createUser);
router.get('/mood/affect', falukantController.getMoodAffect);
router.get('/character/affect', falukantController.getCharacterAffect);
router.get('/name/randomfirstname/:gender', falukantController.randomFirstName);
router.get('/name/randomlastname', falukantController.randomLastName);
router.get('/info', falukantController.getInfo);
@@ -30,15 +32,30 @@ router.post('/director/proposal', falukantController.getDirectorProposals);
router.post('/director/convertproposal', falukantController.convertProposalToDirector);
router.post('/director/settings', falukantController.setSetting);
router.get('/director/:branchId', falukantController.getDirectorForBranch);
router.get('/directors', falukantController.getAllDirectors);
router.post('/directors', falukantController.updateDirector);
router.post('/family/acceptmarriageproposal', falukantController.acceptMarriageProposal);
router.get('/family/gifts', falukantController.getGifts);
router.get('/family/children', falukantController.getChildren);
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);
router.get('/party/types', falukantController.getPartyTypes);
router.post('/party', falukantController.createParty);
router.get('/party', falukantController.getParties);
router.get('/family/notbaptised', falukantController.getNotBaptisedChildren);
router.post('/church/baptise', falukantController.baptise);
router.get('/education', falukantController.getEducation);
router.post('/education', falukantController.sendToSchool);
router.get('/bank/overview', falukantController.getBankOverview);
router.get('/bank/credits', falukantController.getBankCredits);
router.post('/bank/credits', falukantController.takeBankCredits);
router.get('/nobility', falukantController.getNobility);
router.post('/nobility', falukantController.advanceNobility);
router.get('/health', falukantController.getHealth);
router.post('/health', falukantController.healthActivity)
export default router;

File diff suppressed because it is too large Load Diff

View File

@@ -267,73 +267,81 @@ async function initializeFalukantProducts() {
}
async function initializeFalukantTitles() {
await TitleOfNobility.bulkCreate([
{ labelTr: "noncivil" },
{ labelTr: "civil" },
{ labelTr: "sir" },
{ labelTr: "townlord" },
{ labelTr: "by" },
{ labelTr: "landlord" },
{ labelTr: "knight" },
{ labelTr: "baron" },
{ labelTr: "count" },
{ labelTr: "palsgrave" },
{ labelTr: "margrave" },
{ labelTr: "landgrave" },
{ labelTr: "ruler" },
{ labelTr: "elector" },
{ labelTr: "imperial-prince" },
{ labelTr: "duke" },
{ labelTr: "grand-duke" },
{ labelTr: "prince-regent" },
{ labelTr: "king" },
], {
updateOnDuplicate: ['labelTr'],
});
try {
await TitleOfNobility.bulkCreate([
{ labelTr: "noncivil", level: 1 },
{ labelTr: "civil", level: 2 },
{ labelTr: "sir", level: 3 },
{ labelTr: "townlord", level: 4 },
{ labelTr: "by", level: 5 },
{ labelTr: "landlord", level: 6 },
{ labelTr: "knight", level: 7 },
{ labelTr: "baron", level: 8 },
{ labelTr: "count", level: 9 },
{ labelTr: "palsgrave", level: 10 },
{ labelTr: "margrave", level: 11 },
{ labelTr: "landgrave", level: 12 },
{ labelTr: "ruler", level: 13 },
{ labelTr: "elector", level: 14 },
{ labelTr: "imperial-prince", level: 15 },
{ labelTr: "duke", level: 16 },
{ labelTr: "grand-duke", level: 17 },
{ labelTr: "prince-regent", level: 18 },
{ labelTr: "king", level: 19 },
], {
updateOnDuplicate: ['labelTr'],
});
} catch (error) {
console.error('Error initializing Falukant titles:', error);
}
}
async function initializeFalukantTitleRequirements() {
const titleRequirements = [
{ labelTr: "civil", requirements: [{ type: "money", value: 500 }] },
{ labelTr: "sir", requirements: [{ type: "branches", value: 2 }] },
{ labelTr: "townlord", requirements: [] },
{ labelTr: "by", requirements: [] },
{ labelTr: "landlord", requirements: [] },
{ labelTr: "knight", requirements: [] },
{ labelTr: "baron", requirements: [{ type: "branches", value: 4 }] },
{ labelTr: "count", requirements: [] },
{ labelTr: "palsgrave", requirements: [] },
{ labelTr: "margrave", requirements: [] },
{ labelTr: "landgrave", requirements: [] },
{ labelTr: "ruler", requirements: [] },
{ labelTr: "elector", requirements: [] },
{ labelTr: "imperial-prince", requirements: [] },
{ labelTr: "duke", requirements: [] },
{ labelTr: "grand-duke", requirements: [] },
{ labelTr: "prince-regent", requirements: [] },
{ labelTr: "king", requirements: [] },
{ labelTr: "civil", requirements: [{ type: "money", value: 5000 }, { type: "cost", value: 500 }] },
{ labelTr: "sir", requirements: [{ type: "branches", value: 2 }, { type: "cost", value: 1000 }] },
{ labelTr: "townlord", requirements: [{ type: "cost", value: 3000 }] },
{ labelTr: "by", requirements: [{ type: "cost", value: 6000 }] },
{ labelTr: "landlord", requirements: [{ type: "cost", value: 9000 }] },
{ labelTr: "knight", requirements: [{ type: "cost", value: 11000 }] },
{ labelTr: "baron", requirements: [{ type: "branches", value: 4 }, { type: "cost", value: 15000 }] },
{ labelTr: "count", requirements: [{ type: "cost", value: 19000 }] },
{ labelTr: "palsgrave", requirements: [{ type: "cost", value: 25000 }] },
{ labelTr: "margrave", requirements: [{ type: "cost", value: 33000 }] },
{ labelTr: "landgrave", requirements: [{ type: "cost", value: 47000 }] },
{ labelTr: "ruler", requirements: [{ type: "cost", value: 66000 }] },
{ labelTr: "elector", requirements: [{ type: "cost", value: 79000 }] },
{ labelTr: "imperial-prince", requirements: [{ type: "cost", value: 99999 }] },
{ labelTr: "duke", requirements: [{ type: "cost", value: 130000 }] },
{ labelTr: "grand-duke",requirements: [{ type: "cost", value: 170000 }] },
{ labelTr: "prince-regent", requirements: [{ type: "cost", value: 270000 }] },
{ labelTr: "king", requirements: [{ type: "cost", value: 500000 }] },
];
const titles = await TitleOfNobility.findAll();
const requirementsToInsert = [];
for (let i = 0; i < titleRequirements.length; i++) {
const titleRequirement = titleRequirements[i];
const title = titles.find(t => t.labelTr === titleRequirement.labelTr);
const titleReq = titleRequirements[i];
const title = titles.find(t => t.labelTr === titleReq.labelTr);
if (!title) continue;
if (i > 1) {
const moneyRequirement = {
type: "money",
titleReq.requirements.push({
type: "money",
value: 5000 * Math.pow(3, i - 1),
};
titleRequirement.requirements.push(moneyRequirement);
});
}
for (const requirement of titleRequirement.requirements) {
for (const req of titleReq.requirements) {
requirementsToInsert.push({
titleId: title.id,
requirementType: requirement.type,
requirementValue: requirement.value,
titleId: title.id,
requirementType: req.type,
requirementValue: req.value,
});
}
}
await TitleRequirement.bulkCreate(requirementsToInsert, { ignoreDuplicates: true });
}

View File

@@ -8,6 +8,10 @@ import PromotionalGiftCharacterTrait from "../../models/falukant/predefine/promo
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";
import PartyType from "../../models/falukant/type/party.js";
import MusicType from "../../models/falukant/type/music.js";
import BanquetteType from "../../models/falukant/type/banquette.js";
import LearnRecipient from "../../models/falukant/type/learn_recipient.js";
export const initializeFalukantTypes = async () => {
await initializeFalukantTypeRegions();
@@ -17,6 +21,10 @@ export const initializeFalukantTypes = async () => {
await initializeFalukantPromotionalGifts();
await initializePromotionalGiftMoodLinks();
await initializeFalukantHouseTypes();
await initializeFalukantPartyTypes();
await initializeFalukantMusicTypes();
await initializeFalukantBanquetteTypes();
await initializeLearnerTypes();
};
const regionTypes = [];
@@ -208,15 +216,44 @@ const promotionalGiftMoodLinks = [
];
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' },
{ labelTr: 'Unter der Brücke', abbr: 'under_bridge', cost: 0, position: 1, minimumTitle: 'noncivil' },
{ labelTr: 'Strohhütte', abbr: 'straw_hut', cost: 100, position: 2, minimumTitle: 'noncivil' },
{ labelTr: 'Holzhaus', abbr: 'wooden_house', cost: 5000, position: 3, minimumTitle: 'civil' },
{ labelTr: 'Hinterhofzimmer', abbr: 'backyard_room', cost: 75000, position: 4, minimumTitle: 'civil' },
{ labelTr: 'Kleines Familienhaus', abbr: 'family_house', cost: 273000, position: 5, minimumTitle: 'sir' },
{ labelTr: 'Stadthaus', abbr: 'townhouse', cost: 719432, position: 6, minimumTitle: 'townlord' },
{ labelTr: 'Villa', abbr: 'villa', cost: 3500000, position: 7, minimumTitle: 'knight' },
{ labelTr: 'Herrenhaus', abbr: 'mansion', cost: 18000000, position: 8, minimumTitle: 'ruler' },
{ labelTr: 'Schloss', abbr: 'castle', cost: 500000000, position: 9, minimumTitle: 'prince-regent' },
];
const partyTypes = [
{ labelTr: 'wedding', cost: 50, forMarriage: true, reputationGrowth: 5 },
{ labelTr: 'ball', cost: 250, forMarriage: false, reputationGrowth: 7 },
{ labelTr: 'town fair', cost: 1000, forMarriage: false, reputationGrowth: 10 },
{ labelTr: 'royal feast', cost: 50000, forMarriage: false, reputationGrowth: 25 },
];
const musicTypes = [
{ type: 'none', cost: 0, reputationGrowth: 0 },
{ type: 'bard', cost: 100, reputationGrowth: 2 },
{ type: 'villageBand', cost: 2500, reputationGrowth: 5 },
{ type: 'chamberOrchestra', cost: 12000, reputationGrowth: 10 },
{ type: 'symphonyOrchestra', cost: 37000, reputationGrowth: 15 },
{ type: 'symphonyOrchestraWithChorusAndSolists', cost: 500000, reputationGrowth: 25 },
];
const banquetteTypes = [
{ type: 'bread', cost: 5, reputationGrowth: 0 },
{ type: 'roastWithBeer', cost: 200, reputationGrowth: 5 },
{ type: 'poultryWithVegetablesAndWine', cost: 5000, reputationGrowth: 10 },
{ type: 'extensiveBuffet', cost: 100000, reputationGrowth: 20 }
];
const learnerTypes = [
{ tr: 'self', },
{ tr: 'children', },
{ tr: 'director', },
];
{
@@ -379,7 +416,7 @@ export const initializePromotionalGiftMoodLinks = async () => {
};
export const initializeFalukantHouseTypes = async () => {
for (const ht of houseTypes) {
for (const ht of houseTypes) {
const [record, created] = await HouseType.findOrCreate({
where: { labelTr: ht.abbr },
defaults: {
@@ -391,3 +428,54 @@ export const initializeFalukantHouseTypes = async () => {
});
}
};
export const initializeFalukantPartyTypes = async () => {
for (const pt of partyTypes) {
const [record, created] = await PartyType.findOrCreate({
where: { tr: pt.labelTr },
defaults: {
cost: pt.cost,
tr: pt.labelTr,
forMarriage: pt.forMarriage,
reputationGrowth: pt.reputationGrowth,
}
});
}
}
export const initializeFalukantMusicTypes = async () => {
for (const mt of musicTypes) {
const [record, created] = await MusicType.findOrCreate({
where: { tr: mt.type },
defaults: {
cost: mt.cost,
tr: mt.type,
reputationGrowth: mt.reputationGrowth,
}
});
}
}
export const initializeFalukantBanquetteTypes = async () => {
for (const bt of banquetteTypes) {
const [record, created] = await BanquetteType.findOrCreate({
where: { tr: bt.type },
defaults: {
tr: bt.type,
cost: bt.cost,
reputationGrowth: bt.reputationGrowth,
}
});
}
};
export const initializeLearnerTypes = async () => {
for (const lt of learnerTypes) {
const [record, created] = await LearnRecipient.findOrCreate({
where: { tr: lt.tr },
defaults: {
tr: lt.tr,
}
});
}
}