388 lines
12 KiB
TypeScript
388 lines
12 KiB
TypeScript
import { createHero } from "../create";
|
|
import type { BuildingType } from "../types";
|
|
import { getEmptyResources } from "../utils";
|
|
import type { VillageState } from "../village";
|
|
|
|
|
|
function getStandardTimeToBuild(level: number) {
|
|
return Math.round(Math.pow(level, 1 / 1.2) + 1);
|
|
}
|
|
|
|
|
|
function getResourceBuildingCost(level: number, initial: number) {
|
|
return initial * level * (level - 1);
|
|
}
|
|
|
|
|
|
function getStorageBuildingCost(level: number, initial: number) {
|
|
return initial * Math.round( (level + level * level) / 3);
|
|
}
|
|
|
|
|
|
function getUnitBuildingCost(level: number, initial: number) {
|
|
return initial * Math.round( (level + level * level) / 2);
|
|
}
|
|
|
|
|
|
export default [
|
|
{
|
|
type: 'townhall',
|
|
name: 'Town Hall',
|
|
autoBuilt: true,
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 0,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getResourceBuildingCost(level, 10),
|
|
stone: getResourceBuildingCost(level, 15),
|
|
iron: getResourceBuildingCost(level, 20),
|
|
food: getResourceBuildingCost(level, 5),
|
|
};
|
|
},
|
|
timeToBuild: getStandardTimeToBuild,
|
|
behavior: {
|
|
storage: (_V: VillageState, _self: BuildingType) => {
|
|
return {
|
|
'wood': 100,
|
|
'stone': 100,
|
|
'iron': 100,
|
|
'food': 100,
|
|
}
|
|
},
|
|
constructionTimeReductionPerLevel: 0.025,
|
|
},
|
|
},
|
|
{
|
|
type: 'woodcutter',
|
|
name: 'Woodcutter',
|
|
autoBuilt: true,
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 0,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getResourceBuildingCost(level, 6),
|
|
stone: getResourceBuildingCost(level, 10),
|
|
iron: getResourceBuildingCost(level, 14),
|
|
food: getResourceBuildingCost(level, 10),
|
|
};
|
|
},
|
|
timeToBuild: getStandardTimeToBuild,
|
|
behavior: {
|
|
production: (V: VillageState, self: BuildingType) => {
|
|
const prod = getEmptyResources();
|
|
const outputPerMinute = 5 * (self.level * self.level);
|
|
prod.wood = outputPerMinute;
|
|
|
|
const intakePerMinute = Math.ceil(self.level / 5);
|
|
prod.food = -intakePerMinute;
|
|
|
|
return prod;
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'mine',
|
|
name: 'Mine',
|
|
autoBuilt: true,
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 0,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getResourceBuildingCost(level, 10),
|
|
stone: getResourceBuildingCost(level, 14),
|
|
iron: getResourceBuildingCost(level, 6),
|
|
food: getResourceBuildingCost(level, 10),
|
|
};
|
|
},
|
|
timeToBuild: getStandardTimeToBuild,
|
|
behavior: {
|
|
production: (V: VillageState, self: BuildingType) => {
|
|
const prod = getEmptyResources();
|
|
const outputPerMinute = 5 * (self.level * self.level);
|
|
prod.iron = outputPerMinute;
|
|
|
|
const intakePerMinute = Math.ceil(self.level / 5);
|
|
prod.food = -intakePerMinute;
|
|
|
|
return prod;
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'pit',
|
|
name: 'Pit',
|
|
autoBuilt: true,
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 0,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getResourceBuildingCost(level, 14),
|
|
stone: getResourceBuildingCost(level, 6),
|
|
iron: getResourceBuildingCost(level, 10),
|
|
food: getResourceBuildingCost(level, 10),
|
|
};
|
|
},
|
|
timeToBuild: getStandardTimeToBuild,
|
|
behavior: {
|
|
production: (V: VillageState, self: BuildingType) => {
|
|
const prod = getEmptyResources();
|
|
const outputPerMinute = 5 * (self.level * self.level);
|
|
prod.stone = outputPerMinute;
|
|
|
|
const intakePerMinute = Math.ceil(self.level / 5);
|
|
prod.food = -intakePerMinute;
|
|
|
|
return prod;
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'field',
|
|
name: 'Field',
|
|
autoBuilt: true,
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 0,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getResourceBuildingCost(level, 14),
|
|
stone: getResourceBuildingCost(level, 14),
|
|
iron: getResourceBuildingCost(level, 12),
|
|
food: getResourceBuildingCost(level, 0),
|
|
};
|
|
},
|
|
timeToBuild: getStandardTimeToBuild,
|
|
behavior: {
|
|
production: (V: VillageState, self: BuildingType) => {
|
|
const prod = getEmptyResources();
|
|
const outputPerMinute = 5 * (self.level * self.level);
|
|
prod.food = outputPerMinute;
|
|
return prod;
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'warehouse',
|
|
name: 'Warehouse',
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 0,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getStorageBuildingCost(level, 15),
|
|
stone: getStorageBuildingCost(level, 20),
|
|
iron: getStorageBuildingCost(level, 10),
|
|
food: getStorageBuildingCost(level, 15),
|
|
};
|
|
},
|
|
timeToBuild: getStandardTimeToBuild,
|
|
behavior: {
|
|
storage: (V: VillageState, self: BuildingType) => {
|
|
const x = self.level;
|
|
const capacity = ( ( ( x + ( x * x ) ) / 2 ) + 3 ) * 25;
|
|
return {
|
|
'wood': capacity,
|
|
'stone': capacity,
|
|
'iron': capacity,
|
|
'food': 0,
|
|
};
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'granary',
|
|
name: 'Granary',
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 0,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getStorageBuildingCost(level, 12),
|
|
stone: getStorageBuildingCost(level, 22),
|
|
iron: getStorageBuildingCost(level, 10),
|
|
food:getStorageBuildingCost(level, 6),
|
|
};
|
|
},
|
|
timeToBuild: getStandardTimeToBuild,
|
|
behavior: {
|
|
storage: (V: VillageState, self: BuildingType) => {
|
|
const x = self.level;
|
|
const capacity = ( ( ( x + ( x * x ) ) / 2 ) + 3 ) * 25;
|
|
return {
|
|
'wood': 0,
|
|
'stone': 0,
|
|
'iron': 0,
|
|
'food': capacity,
|
|
};
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'great-warehouse',
|
|
name: 'Great Warehouse',
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 15,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getStorageBuildingCost(level, 150),
|
|
stone: getStorageBuildingCost(level, 200),
|
|
iron: getStorageBuildingCost(level, 100),
|
|
food: getStorageBuildingCost(level, 150),
|
|
};
|
|
},
|
|
timeToBuild: (level: number) => getStandardTimeToBuild(level) * 2,
|
|
behavior: {
|
|
storage: (V: VillageState, self: BuildingType) => {
|
|
const x = self.level;
|
|
const capacity = ( ( ( x + ( x * x ) ) / 2 ) + 3 ) * 250;
|
|
return {
|
|
'wood': capacity,
|
|
'stone': capacity,
|
|
'iron': capacity,
|
|
'food': 0,
|
|
};
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'great-granary',
|
|
name: 'Great Granary',
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 15,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getStorageBuildingCost(level, 120),
|
|
stone: getStorageBuildingCost(level, 220),
|
|
iron: getStorageBuildingCost(level, 100),
|
|
food:getStorageBuildingCost(level, 60),
|
|
};
|
|
},
|
|
timeToBuild: (level: number) => getStandardTimeToBuild(level) * 2,
|
|
behavior: {
|
|
storage: (V: VillageState, self: BuildingType) => {
|
|
const x = self.level;
|
|
const capacity = ( ( ( x + ( x * x ) ) / 2 ) + 3 ) * 250;
|
|
return {
|
|
'wood': 0,
|
|
'stone': 0,
|
|
'iron': 0,
|
|
'food': capacity,
|
|
};
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'university',
|
|
name: 'University',
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 5,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getUnitBuildingCost(level, 75),
|
|
stone: getUnitBuildingCost(level, 90),
|
|
iron: getUnitBuildingCost(level, 50),
|
|
food: getUnitBuildingCost(level, 45),
|
|
};
|
|
},
|
|
timeToBuild: getStandardTimeToBuild,
|
|
behavior: {
|
|
production: (V: VillageState, self: BuildingType) => {
|
|
const prod = getEmptyResources();
|
|
const intakePerMinute = self.level * 2;
|
|
prod.food = -intakePerMinute;
|
|
return prod;
|
|
},
|
|
units: {
|
|
type: 'philosopher',
|
|
recruitmentTime: (V: VillageState, self: BuildingType) => 2 - 0.06 * self.level,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'barracks',
|
|
name: 'Barracks',
|
|
maxLevel: 20,
|
|
requiredTownhallLevel: 3,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getUnitBuildingCost(level, 60),
|
|
stone: getUnitBuildingCost(level, 30),
|
|
iron: getUnitBuildingCost(level, 90),
|
|
food: getUnitBuildingCost(level, 40),
|
|
};
|
|
},
|
|
timeToBuild: getStandardTimeToBuild,
|
|
behavior: {
|
|
production: (V: VillageState, self: BuildingType) => {
|
|
const prod = getEmptyResources();
|
|
const intakePerMinute = Math.ceil(self.level / 3) * 3;
|
|
prod.food = -intakePerMinute;
|
|
return prod;
|
|
},
|
|
units: {
|
|
type: 'soldier',
|
|
recruitmentTime: (V: VillageState, self: BuildingType) => 1 - 0.03 * self.level,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'palace',
|
|
name: 'Palace',
|
|
maxLevel: 20,
|
|
unique: true,
|
|
requiredTownhallLevel: 10,
|
|
cost: (level: number) => {
|
|
return {
|
|
wood: getStorageBuildingCost(level, 200),
|
|
stone: getStorageBuildingCost(level, 240),
|
|
iron: getStorageBuildingCost(level, 110),
|
|
food: getStorageBuildingCost(level, 70),
|
|
};
|
|
},
|
|
timeToBuild: getStandardTimeToBuild,
|
|
behavior: {
|
|
production: (V: VillageState, self: BuildingType) => {
|
|
const prod = getEmptyResources();
|
|
prod.food = self.level * -30;
|
|
return prod;
|
|
},
|
|
triggers: {
|
|
onLevelUp: (V: VillageState, self: BuildingType) => {
|
|
if (self.level === 10 || self.level === 20) {
|
|
// Create a new hero.
|
|
V.heroes.push(createHero());
|
|
}
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: 'wonder',
|
|
name: 'World Wonder',
|
|
maxLevel: 1,
|
|
unique: true,
|
|
requiredTownhallLevel: 20,
|
|
cost: () => {
|
|
return {
|
|
wood: 42000,
|
|
stone: 42000,
|
|
iron: 42000,
|
|
food: 38000,
|
|
};
|
|
},
|
|
timeToBuild: () => 120,
|
|
behavior: {
|
|
production: (V: VillageState, self: BuildingType) => {
|
|
const prod = getEmptyResources();
|
|
prod.food = self.level * -300;
|
|
return prod;
|
|
},
|
|
triggers: {
|
|
onLevelUp: (V: VillageState, self: BuildingType) => {
|
|
if (self.level === 1) {
|
|
// Gain a lot of culture.
|
|
V.resources.culture += 18000;
|
|
}
|
|
},
|
|
},
|
|
},
|
|
},
|
|
];
|