Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions proto/cityio/entity/v1/battle.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ message BattleSide {
int64 starting_militia_count = 8;
BattleLossSummary cumulative_losses = 9;
BattleLossSummary last_round_losses = 10;
// Effective durability added by a settlement center and/or owned fort.
int32 defense_bonus_percent = 11;
}

// Battle exists only while combat is active. Each side can contain armies
Expand Down
5 changes: 4 additions & 1 deletion proto/cityio/entity/v1/building.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "cityio/entity/v1/common.proto";
import "cityio/entity/v1/ids.proto";
import "google/protobuf/timestamp.proto";

// Building is a structure within a city.
// Building is either part of a city or a standalone player-owned structure.
message Building {
BuildingId building_id = 1;
CityId city_id = 2;
Expand All @@ -16,4 +16,7 @@ message Building {
Coordinates coords = 6;
optional google.protobuf.Timestamp construction_start = 7;
optional google.protobuf.Timestamp construction_end = 8;
// Set only for standalone structures. City buildings inherit ownership from
// their city and continue to use city_id.
optional UserId owner = 9;
}
2 changes: 2 additions & 0 deletions proto/cityio/entity/v1/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ enum BuildingType {
BUILDING_TYPE_HOUSE = 4;
BUILDING_TYPE_FARM = 5;
BUILDING_TYPE_MINE = 6;
BUILDING_TYPE_WATCHTOWER = 7;
BUILDING_TYPE_FORT = 8;
}

// TroopType identifies a kind of troop.
Expand Down
3 changes: 3 additions & 0 deletions proto/cityio/service/v1/building.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import "cityio/entity/v1/common.proto";
import "cityio/entity/v1/ids.proto";

message CreateBuildingRequest {
// Required for city buildings and omitted for standalone watchtowers/forts,
// which require one of the caller's armies on the target tile.
cityio.entity.v1.CityId city_id = 1;
cityio.entity.v1.BuildingType type = 2;
cityio.entity.v1.Coordinates coords = 3;
Expand All @@ -33,6 +35,7 @@ message DeleteBuildingRequest {
message DeleteBuildingResponse {}

message ListBuildingsRequest {
// When omitted, returns the caller's standalone structures.
cityio.entity.v1.CityId city_id = 1;
}
message ListBuildingsResponse {
Expand Down
5 changes: 5 additions & 0 deletions proto/cityio/service/v1/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ message BuildingLevelStats {
double population = 5;
// Barracks only: throughput relative to a level-one training lane.
double training_speed_multiplier = 6;
// Watchtower only: Chebyshev map-vision radius at this completed level.
int32 vision_radius = 7;
// Centers and forts: effective durability added during eligible battles.
int32 defense_bonus_percent = 8;
}

message BuildingConfig {
Expand Down Expand Up @@ -58,6 +62,7 @@ message GetGameConfigResponse {
repeated BuildingConfig buildings = 5;
google.protobuf.Duration city_tick = 6;
PopulationPolicyConfig population_policy = 7;
int32 structure_placement_radius = 8;
}

service ConfigService {
Expand Down
52 changes: 51 additions & 1 deletion src/lib/game/sprites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { tileHash } from './colors';

export type TerrainKind = 'grassland' | 'plains' | 'forest' | 'hills' | 'mountains' | 'desert' | 'marsh' | 'water' | 'fog';
export type TerrainNeighbors = readonly [TerrainKind | null, TerrainKind | null, TerrainKind | null, TerrainKind | null];
export type StructureKind = 'house' | 'farm' | 'mine' | 'barracks' | 'city_center' | 'town_center';
export type StructureKind = 'house' | 'farm' | 'mine' | 'barracks' | 'watchtower' | 'fort' | 'city_center' | 'town_center';

const PAD = 2;
const W = 2 * HW + PAD * 2;
Expand Down Expand Up @@ -52,6 +52,8 @@ const STRUCTURE_HEADROOM: Record<StructureKind, number> = {
mine: 14,
house: 24,
barracks: 28,
watchtower: 42,
fort: 30,
town_center: 32,
city_center: 42
};
Expand Down Expand Up @@ -320,6 +322,48 @@ function drawBarracks(ctx: CanvasRenderingContext2D, cx: number, cy: number) {
ctx.fillRect(cx - 2, baseY - 5, 4, 7);
}

function drawWatchtower(ctx: CanvasRenderingContext2D, cx: number, cy: number) {
const baseY = cy - 2;
drawStructureShadow(ctx, cx, cy, 10);
ctx.fillStyle = '#76563c';
ctx.fillRect(cx - 7, baseY - 27, 4, 29);
ctx.fillRect(cx + 3, baseY - 27, 4, 29);
ctx.strokeStyle = '#4d3524';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(cx - 6, baseY - 20);
ctx.lineTo(cx + 6, baseY - 5);
ctx.moveTo(cx + 6, baseY - 20);
ctx.lineTo(cx - 6, baseY - 5);
ctx.stroke();
ctx.fillStyle = '#9a7650';
ctx.fillRect(cx - 11, baseY - 31, 22, 7);
pitchedRoof(ctx, cx, baseY - 31, 13, 8, 0x5c3926);
ctx.fillStyle = '#32251a';
ctx.fillRect(cx - 2, baseY - 29, 4, 3);
}

function drawFort(ctx: CanvasRenderingContext2D, cx: number, cy: number) {
const baseY = cy - 2;
drawStructureShadow(ctx, cx, cy, 17);
ctx.fillStyle = '#8f8b7c';
ctx.fillRect(cx - 16, baseY - 16, 32, 18);
ctx.fillStyle = '#777568';
ctx.fillRect(cx + 3, baseY - 16, 13, 18);
ctx.fillStyle = '#aaa594';
for (let x = -16; x <= 11; x += 9) ctx.fillRect(cx + x, baseY - 21, 6, 6);
ctx.fillStyle = '#4c4438';
ctx.fillRect(cx - 4, baseY - 7, 8, 9);
ctx.strokeStyle = 'rgba(55,52,45,.55)';
ctx.lineWidth = 1;
for (let y = baseY - 12; y < baseY; y += 5) {
ctx.beginPath();
ctx.moveTo(cx - 15, y);
ctx.lineTo(cx + 15, y);
ctx.stroke();
}
}

function drawTownCenter(ctx: CanvasRenderingContext2D, cx: number, cy: number) {
const baseY = cy - 2;
drawStructureShadow(ctx, cx, cy, 16);
Expand Down Expand Up @@ -438,6 +482,12 @@ function renderStructure(kind: StructureKind): HTMLCanvasElement {
case 'barracks':
drawBarracks(ctx, cx, cy);
break;
case 'watchtower':
drawWatchtower(ctx, cx, cy);
break;
case 'fort':
drawFort(ctx, cx, cy);
break;
case 'town_center':
drawTownCenter(ctx, cx, cy);
break;
Expand Down
48 changes: 27 additions & 21 deletions src/lib/gen/cityio/entity/v1/battle_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,26 @@
// @generated from file cityio/entity/v1/battle.proto (package cityio.entity.v1, syntax proto3)
/* eslint-disable */

import type { GenFile, GenMessage } from '@bufbuild/protobuf/codegenv2';
import { fileDesc, messageDesc } from '@bufbuild/protobuf/codegenv2';
import type { TroopStack } from './army_pb';
import { file_cityio_entity_v1_army } from './army_pb';
import type { ArmyId, BattleId, CityId, TileId, UserId } from './ids_pb';
import { file_cityio_entity_v1_ids } from './ids_pb';
import type { Timestamp } from '@bufbuild/protobuf/wkt';
import { file_google_protobuf_timestamp } from '@bufbuild/protobuf/wkt';
import type { Message } from '@bufbuild/protobuf';
import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
import type { TroopStack } from "./army_pb";
import { file_cityio_entity_v1_army } from "./army_pb";
import type { ArmyId, BattleId, CityId, TileId, UserId } from "./ids_pb";
import { file_cityio_entity_v1_ids } from "./ids_pb";
import type { Timestamp } from "@bufbuild/protobuf/wkt";
import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
import type { Message } from "@bufbuild/protobuf";

/**
* Describes the file cityio/entity/v1/battle.proto.
*/
export const file_cityio_entity_v1_battle: GenFile =
/*@__PURE__*/
fileDesc(
'Ch1jaXR5aW8vZW50aXR5L3YxL2JhdHRsZS5wcm90bxIQY2l0eWlvLmVudGl0eS52MSJlChFCYXR0bGVMb3NzU3VtbWFyeRIsCgZ0cm9vcHMYASADKAsyHC5jaXR5aW8uZW50aXR5LnYxLlRyb29wU3RhY2sSDwoHbWlsaXRpYRgCIAEoAxIRCgljaXZpbGlhbnMYAyABKAMi8AMKCkJhdHRsZVNpZGUSKgoIdXNlcl9pZHMYASADKAsyGC5jaXR5aW8uZW50aXR5LnYxLlVzZXJJZBIqCghhcm15X2lkcxgCIAMoCzIYLmNpdHlpby5lbnRpdHkudjEuQXJteUlkEjYKD21pbGl0aWFfY2l0eV9pZBgDIAEoCzIYLmNpdHlpby5lbnRpdHkudjEuQ2l0eUlkSACIAQESFQoNbWlsaXRpYV9jb3VudBgEIAEoAxIYChBzdHJlbmd0aF92aXNpYmxlGAUgASgIEjUKD3N0YXJ0aW5nX3Ryb29wcxgGIAMoCzIcLmNpdHlpby5lbnRpdHkudjEuVHJvb3BTdGFjaxI2ChBzdXJ2aXZpbmdfdHJvb3BzGAcgAygLMhwuY2l0eWlvLmVudGl0eS52MS5Ucm9vcFN0YWNrEh4KFnN0YXJ0aW5nX21pbGl0aWFfY291bnQYCCABKAMSPgoRY3VtdWxhdGl2ZV9sb3NzZXMYCSABKAsyIy5jaXR5aW8uZW50aXR5LnYxLkJhdHRsZUxvc3NTdW1tYXJ5Ej4KEWxhc3Rfcm91bmRfbG9zc2VzGAogASgLMiMuY2l0eWlvLmVudGl0eS52MS5CYXR0bGVMb3NzU3VtbWFyeUISChBfbWlsaXRpYV9jaXR5X2lkIsACCgZCYXR0bGUSLQoJYmF0dGxlX2lkGAEgASgLMhouY2l0eWlvLmVudGl0eS52MS5CYXR0bGVJZBIpCgd0aWxlX2lkGAIgASgLMhguY2l0eWlvLmVudGl0eS52MS5UaWxlSWQSLwoJYXR0YWNrZXJzGAMgASgLMhwuY2l0eWlvLmVudGl0eS52MS5CYXR0bGVTaWRlEi8KCWRlZmVuZGVycxgEIAEoCzIcLmNpdHlpby5lbnRpdHkudjEuQmF0dGxlU2lkZRIuCgpzdGFydGVkX2F0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIwCgxuZXh0X3RpY2tfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhgKEGNvbXBsZXRlZF9yb3VuZHMYByABKAViBnByb3RvMw',
[file_cityio_entity_v1_army, file_cityio_entity_v1_ids, file_google_protobuf_timestamp]
);
export const file_cityio_entity_v1_battle: GenFile = /*@__PURE__*/
fileDesc("Ch1jaXR5aW8vZW50aXR5L3YxL2JhdHRsZS5wcm90bxIQY2l0eWlvLmVudGl0eS52MSJlChFCYXR0bGVMb3NzU3VtbWFyeRIsCgZ0cm9vcHMYASADKAsyHC5jaXR5aW8uZW50aXR5LnYxLlRyb29wU3RhY2sSDwoHbWlsaXRpYRgCIAEoAxIRCgljaXZpbGlhbnMYAyABKAMijwQKCkJhdHRsZVNpZGUSKgoIdXNlcl9pZHMYASADKAsyGC5jaXR5aW8uZW50aXR5LnYxLlVzZXJJZBIqCghhcm15X2lkcxgCIAMoCzIYLmNpdHlpby5lbnRpdHkudjEuQXJteUlkEjYKD21pbGl0aWFfY2l0eV9pZBgDIAEoCzIYLmNpdHlpby5lbnRpdHkudjEuQ2l0eUlkSACIAQESFQoNbWlsaXRpYV9jb3VudBgEIAEoAxIYChBzdHJlbmd0aF92aXNpYmxlGAUgASgIEjUKD3N0YXJ0aW5nX3Ryb29wcxgGIAMoCzIcLmNpdHlpby5lbnRpdHkudjEuVHJvb3BTdGFjaxI2ChBzdXJ2aXZpbmdfdHJvb3BzGAcgAygLMhwuY2l0eWlvLmVudGl0eS52MS5Ucm9vcFN0YWNrEh4KFnN0YXJ0aW5nX21pbGl0aWFfY291bnQYCCABKAMSPgoRY3VtdWxhdGl2ZV9sb3NzZXMYCSABKAsyIy5jaXR5aW8uZW50aXR5LnYxLkJhdHRsZUxvc3NTdW1tYXJ5Ej4KEWxhc3Rfcm91bmRfbG9zc2VzGAogASgLMiMuY2l0eWlvLmVudGl0eS52MS5CYXR0bGVMb3NzU3VtbWFyeRIdChVkZWZlbnNlX2JvbnVzX3BlcmNlbnQYCyABKAVCEgoQX21pbGl0aWFfY2l0eV9pZCLAAgoGQmF0dGxlEi0KCWJhdHRsZV9pZBgBIAEoCzIaLmNpdHlpby5lbnRpdHkudjEuQmF0dGxlSWQSKQoHdGlsZV9pZBgCIAEoCzIYLmNpdHlpby5lbnRpdHkudjEuVGlsZUlkEi8KCWF0dGFja2VycxgDIAEoCzIcLmNpdHlpby5lbnRpdHkudjEuQmF0dGxlU2lkZRIvCglkZWZlbmRlcnMYBCABKAsyHC5jaXR5aW8uZW50aXR5LnYxLkJhdHRsZVNpZGUSLgoKc3RhcnRlZF9hdBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASMAoMbmV4dF90aWNrX2F0GAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIYChBjb21wbGV0ZWRfcm91bmRzGAcgASgFYgZwcm90bzM", [file_cityio_entity_v1_army, file_cityio_entity_v1_ids, file_google_protobuf_timestamp]);

/**
* @generated from message cityio.entity.v1.BattleLossSummary
*/
export type BattleLossSummary = Message<'cityio.entity.v1.BattleLossSummary'> & {
export type BattleLossSummary = Message<"cityio.entity.v1.BattleLossSummary"> & {
/**
* @generated from field: repeated cityio.entity.v1.TroopStack troops = 1;
*/
Expand All @@ -46,12 +42,13 @@ export type BattleLossSummary = Message<'cityio.entity.v1.BattleLossSummary'> &
* Describes the message cityio.entity.v1.BattleLossSummary.
* Use `create(BattleLossSummarySchema)` to create a new message.
*/
export const BattleLossSummarySchema: GenMessage<BattleLossSummary> = /*@__PURE__*/ messageDesc(file_cityio_entity_v1_battle, 0);
export const BattleLossSummarySchema: GenMessage<BattleLossSummary> = /*@__PURE__*/
messageDesc(file_cityio_entity_v1_battle, 0);

/**
* @generated from message cityio.entity.v1.BattleSide
*/
export type BattleSide = Message<'cityio.entity.v1.BattleSide'> & {
export type BattleSide = Message<"cityio.entity.v1.BattleSide"> & {
/**
* @generated from field: repeated cityio.entity.v1.UserId user_ids = 1;
*/
Expand Down Expand Up @@ -103,13 +100,21 @@ export type BattleSide = Message<'cityio.entity.v1.BattleSide'> & {
* @generated from field: cityio.entity.v1.BattleLossSummary last_round_losses = 10;
*/
lastRoundLosses?: BattleLossSummary | undefined;

/**
* Effective durability added by a settlement center and/or owned fort.
*
* @generated from field: int32 defense_bonus_percent = 11;
*/
defenseBonusPercent: number;
};

/**
* Describes the message cityio.entity.v1.BattleSide.
* Use `create(BattleSideSchema)` to create a new message.
*/
export const BattleSideSchema: GenMessage<BattleSide> = /*@__PURE__*/ messageDesc(file_cityio_entity_v1_battle, 1);
export const BattleSideSchema: GenMessage<BattleSide> = /*@__PURE__*/
messageDesc(file_cityio_entity_v1_battle, 1);

/**
* Battle exists only while combat is active. Each side can contain armies
Expand All @@ -118,7 +123,7 @@ export const BattleSideSchema: GenMessage<BattleSide> = /*@__PURE__*/ messageDes
*
* @generated from message cityio.entity.v1.Battle
*/
export type Battle = Message<'cityio.entity.v1.Battle'> & {
export type Battle = Message<"cityio.entity.v1.Battle"> & {
/**
* @generated from field: cityio.entity.v1.BattleId battle_id = 1;
*/
Expand Down Expand Up @@ -159,4 +164,5 @@ export type Battle = Message<'cityio.entity.v1.Battle'> & {
* Describes the message cityio.entity.v1.Battle.
* Use `create(BattleSchema)` to create a new message.
*/
export const BattleSchema: GenMessage<Battle> = /*@__PURE__*/ messageDesc(file_cityio_entity_v1_battle, 2);
export const BattleSchema: GenMessage<Battle> = /*@__PURE__*/
messageDesc(file_cityio_entity_v1_battle, 2);
14 changes: 11 additions & 3 deletions src/lib/gen/cityio/entity/v1/building_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
import type { BuildingType, Coordinates } from "./common_pb";
import { file_cityio_entity_v1_common } from "./common_pb";
import type { BuildingId, CityId } from "./ids_pb";
import type { BuildingId, CityId, UserId } from "./ids_pb";
import { file_cityio_entity_v1_ids } from "./ids_pb";
import type { Timestamp } from "@bufbuild/protobuf/wkt";
import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
Expand All @@ -16,10 +16,10 @@ import type { Message } from "@bufbuild/protobuf";
* Describes the file cityio/entity/v1/building.proto.
*/
export const file_cityio_entity_v1_building: GenFile = /*@__PURE__*/
fileDesc("Ch9jaXR5aW8vZW50aXR5L3YxL2J1aWxkaW5nLnByb3RvEhBjaXR5aW8uZW50aXR5LnYxIo4DCghCdWlsZGluZxIxCgtidWlsZGluZ19pZBgBIAEoCzIcLmNpdHlpby5lbnRpdHkudjEuQnVpbGRpbmdJZBIpCgdjaXR5X2lkGAIgASgLMhguY2l0eWlvLmVudGl0eS52MS5DaXR5SWQSLAoEdHlwZRgDIAEoDjIeLmNpdHlpby5lbnRpdHkudjEuQnVpbGRpbmdUeXBlEg0KBWxldmVsGAQgASgFEhQKDHRhcmdldF9sZXZlbBgFIAEoBRItCgZjb29yZHMYBiABKAsyHS5jaXR5aW8uZW50aXR5LnYxLkNvb3JkaW5hdGVzEjsKEmNvbnN0cnVjdGlvbl9zdGFydBgHIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIAIgBARI5ChBjb25zdHJ1Y3Rpb25fZW5kGAggASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgBiAEBQhUKE19jb25zdHJ1Y3Rpb25fc3RhcnRCEwoRX2NvbnN0cnVjdGlvbl9lbmRiBnByb3RvMw", [file_cityio_entity_v1_common, file_cityio_entity_v1_ids, file_google_protobuf_timestamp]);
fileDesc("Ch9jaXR5aW8vZW50aXR5L3YxL2J1aWxkaW5nLnByb3RvEhBjaXR5aW8uZW50aXR5LnYxIsYDCghCdWlsZGluZxIxCgtidWlsZGluZ19pZBgBIAEoCzIcLmNpdHlpby5lbnRpdHkudjEuQnVpbGRpbmdJZBIpCgdjaXR5X2lkGAIgASgLMhguY2l0eWlvLmVudGl0eS52MS5DaXR5SWQSLAoEdHlwZRgDIAEoDjIeLmNpdHlpby5lbnRpdHkudjEuQnVpbGRpbmdUeXBlEg0KBWxldmVsGAQgASgFEhQKDHRhcmdldF9sZXZlbBgFIAEoBRItCgZjb29yZHMYBiABKAsyHS5jaXR5aW8uZW50aXR5LnYxLkNvb3JkaW5hdGVzEjsKEmNvbnN0cnVjdGlvbl9zdGFydBgHIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIAIgBARI5ChBjb25zdHJ1Y3Rpb25fZW5kGAggASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgBiAEBEiwKBW93bmVyGAkgASgLMhguY2l0eWlvLmVudGl0eS52MS5Vc2VySWRIAogBAUIVChNfY29uc3RydWN0aW9uX3N0YXJ0QhMKEV9jb25zdHJ1Y3Rpb25fZW5kQggKBl9vd25lcmIGcHJvdG8z", [file_cityio_entity_v1_common, file_cityio_entity_v1_ids, file_google_protobuf_timestamp]);

/**
* Building is a structure within a city.
* Building is either part of a city or a standalone player-owned structure.
*
* @generated from message cityio.entity.v1.Building
*/
Expand Down Expand Up @@ -63,6 +63,14 @@ export type Building = Message<"cityio.entity.v1.Building"> & {
* @generated from field: optional google.protobuf.Timestamp construction_end = 8;
*/
constructionEnd?: Timestamp | undefined;

/**
* Set only for standalone structures. City buildings inherit ownership from
* their city and continue to use city_id.
*
* @generated from field: optional cityio.entity.v1.UserId owner = 9;
*/
owner?: UserId | undefined;
};

/**
Expand Down
12 changes: 11 additions & 1 deletion src/lib/gen/cityio/entity/v1/common_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { Message } from "@bufbuild/protobuf";
* Describes the file cityio/entity/v1/common.proto.
*/
export const file_cityio_entity_v1_common: GenFile = /*@__PURE__*/
fileDesc("Ch1jaXR5aW8vZW50aXR5L3YxL2NvbW1vbi5wcm90bxIQY2l0eWlvLmVudGl0eS52MSIjCgtDb29yZGluYXRlcxIJCgF4GAEgASgFEgkKAXkYAiABKAUiJAoEUmF0ZRINCgV2YWx1ZRgBIAEoAxINCgVzY2FsZRgCIAEoBSpNCghDaXR5VHlwZRIZChVDSVRZX1RZUEVfVU5TUEVDSUZJRUQQABISCg5DSVRZX1RZUEVfQ0lUWRABEhIKDkNJVFlfVFlQRV9UT1dOEAIq0AEKDEJ1aWxkaW5nVHlwZRIdChlCVUlMRElOR19UWVBFX1VOU1BFQ0lGSUVEEAASHQoZQlVJTERJTkdfVFlQRV9DSVRZX0NFTlRFUhABEh0KGUJVSUxESU5HX1RZUEVfVE9XTl9DRU5URVIQAhIaChZCVUlMRElOR19UWVBFX0JBUlJBQ0tTEAMSFwoTQlVJTERJTkdfVFlQRV9IT1VTRRAEEhYKEkJVSUxESU5HX1RZUEVfRkFSTRAFEhYKEkJVSUxESU5HX1RZUEVfTUlORRAGKogBCglUcm9vcFR5cGUSGgoWVFJPT1BfVFlQRV9VTlNQRUNJRklFRBAAEhYKElRST09QX1RZUEVfU09MRElFUhABEhUKEVRST09QX1RZUEVfQVJDSEVSEAISFgoSVFJPT1BfVFlQRV9DQVZBTFJZEAMSGAoUVFJPT1BfVFlQRV9BUlRJTExFUlkQBGIGcHJvdG8z");
fileDesc("Ch1jaXR5aW8vZW50aXR5L3YxL2NvbW1vbi5wcm90bxIQY2l0eWlvLmVudGl0eS52MSIjCgtDb29yZGluYXRlcxIJCgF4GAEgASgFEgkKAXkYAiABKAUiJAoEUmF0ZRINCgV2YWx1ZRgBIAEoAxINCgVzY2FsZRgCIAEoBSpNCghDaXR5VHlwZRIZChVDSVRZX1RZUEVfVU5TUEVDSUZJRUQQABISCg5DSVRZX1RZUEVfQ0lUWRABEhIKDkNJVFlfVFlQRV9UT1dOEAIqhgIKDEJ1aWxkaW5nVHlwZRIdChlCVUlMRElOR19UWVBFX1VOU1BFQ0lGSUVEEAASHQoZQlVJTERJTkdfVFlQRV9DSVRZX0NFTlRFUhABEh0KGUJVSUxESU5HX1RZUEVfVE9XTl9DRU5URVIQAhIaChZCVUlMRElOR19UWVBFX0JBUlJBQ0tTEAMSFwoTQlVJTERJTkdfVFlQRV9IT1VTRRAEEhYKEkJVSUxESU5HX1RZUEVfRkFSTRAFEhYKEkJVSUxESU5HX1RZUEVfTUlORRAGEhwKGEJVSUxESU5HX1RZUEVfV0FUQ0hUT1dFUhAHEhYKEkJVSUxESU5HX1RZUEVfRk9SVBAIKogBCglUcm9vcFR5cGUSGgoWVFJPT1BfVFlQRV9VTlNQRUNJRklFRBAAEhYKElRST09QX1RZUEVfU09MRElFUhABEhUKEVRST09QX1RZUEVfQVJDSEVSEAISFgoSVFJPT1BfVFlQRV9DQVZBTFJZEAMSGAoUVFJPT1BfVFlQRV9BUlRJTExFUlkQBGIGcHJvdG8z");

/**
* Coordinates is a position on the game map.
Expand Down Expand Up @@ -130,6 +130,16 @@ export enum BuildingType {
* @generated from enum value: BUILDING_TYPE_MINE = 6;
*/
MINE = 6,

/**
* @generated from enum value: BUILDING_TYPE_WATCHTOWER = 7;
*/
WATCHTOWER = 7,

/**
* @generated from enum value: BUILDING_TYPE_FORT = 8;
*/
FORT = 8,
}

/**
Expand Down
5 changes: 5 additions & 0 deletions src/lib/gen/cityio/service/v1/building_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export const file_cityio_service_v1_building: GenFile = /*@__PURE__*/
*/
export type CreateBuildingRequest = Message<"cityio.service.v1.CreateBuildingRequest"> & {
/**
* Required for city buildings and omitted for standalone watchtowers/forts,
* which require one of the caller's armies on the target tile.
*
* @generated from field: cityio.entity.v1.CityId city_id = 1;
*/
cityId?: CityId | undefined;
Expand Down Expand Up @@ -161,6 +164,8 @@ export const DeleteBuildingResponseSchema: GenMessage<DeleteBuildingResponse> =
*/
export type ListBuildingsRequest = Message<"cityio.service.v1.ListBuildingsRequest"> & {
/**
* When omitted, returns the caller's standalone structures.
*
* @generated from field: cityio.entity.v1.CityId city_id = 1;
*/
cityId?: CityId | undefined;
Expand Down
Loading
Loading