mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 11:20:45 +00:00
implement battleship
This commit is contained in:
@@ -195,10 +195,10 @@
|
||||
* BUG: destroys destroy trade ships instead of capturing them DONE 11/25/2024
|
||||
* nukes break alliance DONE 11/25/2024
|
||||
* BUG: nuke yourself makes you traitor DONE 11/25/2024
|
||||
* don't capture trade ships if allied with either port
|
||||
* make ports cost more for more ports
|
||||
* NPC has relations
|
||||
* make ports cost more for more ports DONE 11/25/2024
|
||||
* add battleship
|
||||
* cache images in UnitLayer
|
||||
* NPC has relations
|
||||
* add defense post
|
||||
* add radiation from nuke
|
||||
* only show units you can build in the build menu
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
id="svg10"
|
||||
sodipodi:docname="BattleshipIconWhite.svg"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
width="100"
|
||||
height="100"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs14" />
|
||||
<sodipodi:namedview
|
||||
id="namedview12"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="6.984"
|
||||
inkscape:cx="32.216495"
|
||||
inkscape:cy="61.85567"
|
||||
inkscape:window-width="3072"
|
||||
inkscape:window-height="1653"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="38"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg10" />
|
||||
<g
|
||||
transform="translate(0,-952.36218)"
|
||||
id="g4">
|
||||
<path
|
||||
style="color:#000000;enable-background:accumulate"
|
||||
d="m 52.875,983.36892 c -0.49121,0.062 -0.89424,0.536 -0.875,1.0302 v 1.0302 c -2.47779,0.1677 -4.34288,0.8536 -7,-0.031 v 3.996 c 2.65712,0.8848 4.52221,0.1989 7,0.031 v 2.9658 h -2 v 5.994 h 12 v -2.0604 c 0,-1.9427 -2.01271,-3.9336 -4.09375,-3.9336 H 54 v -7.992 c 0.0226,-0.5776 -0.55092,-1.1028 -1.125,-1.0302 z m -12.78125,11.0202 c -2.08104,0 -4.09375,1.991 -4.09375,3.9336 v 2.06048 h -2 v 4.995 h 8 v -4.995 -5.99408 z m -23.07224,5.83428 c -0.0488,0.425 0.20924,0.867 0.60349,1.0339 l 4.5625,2.2789 c -0.4409,0.504 -0.75431,1.1371 -0.9375,1.842 H 28 v -2.997 c -1.24549,-0.011 -2.50235,0 -3.59375,0.031 l -5.875,-2.93438 c -0.85866,-0.2369 -1.37087,0.069 -1.50974,0.74568 z M 48,1000.3832 v 6.993 H 21 v 2.997 h 41 2.125 l 1.1875,-1.3425 c 0.334581,-0.3723 0.81362,-0.6116 1.3125,-0.6555 1.11945,0 2.274,0 3.40625,0 0.0754,-0.9548 0.0856,-1.9919 -0.0625,-2.8722 l 4.46875,-2.2477 c 0.410701,-0.1915 0.65307,-0.6875 0.551681,-1.1288 -0.10139,-0.4413 -0.53598,-0.782 -0.989181,-0.7755 -1.703,0.6041 -3.38144,1.6053 -5.03125,2.435 -0.773669,-0.8346 -1.85083,-1.4048 -2.96875,-1.4048 h -4 v -1.998 z m 37.5625,3.0907 -5.90625,2.9657 c -0.83623,-0.1168 -1.68953,-0.062 -2.5625,-0.062 v 1.998 h 5.34375 c -0.19284,-0.293 -0.400279,-0.5665 -0.65625,-0.8117 l 4.65625,-2.3102 c 0.410701,-0.1915 0.65307,-0.6875 0.551681,-1.1288 -0.296351,-0.8059 -0.86733,-0.8923 -1.426681,-0.6511 z m -80.3795695,2.3138 c -0.35758,0.6586 -0.0648,1.1335 0.44207,1.4636 l 4.6562495,2.3102 c -0.25578,0.2452 -0.4679495,0.5186 -0.6562495,0.8117 H 15 v -1.998 c -0.84395,-0.026 -1.76714,-0.01 -2.5625,0.062 l -5.9062495,-2.9657 c -0.60205,-0.2213 -1.02929,-0.1474 -1.34832,0.3163 z m 61.6295695,4.5855 -1.75,1.998 H 5.0000005 c 0,3.996 3,8.991 4.9999995,8.991 h 77 l 8,-10.989 z"
|
||||
fill="#000000"
|
||||
stroke="none"
|
||||
marker="none"
|
||||
visibility="visible"
|
||||
display="inline"
|
||||
overflow="visible"
|
||||
id="path2" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:#ffffff;stroke-width:0.143184"
|
||||
d="M 8.9021363,68.443587 C 7.2087477,67.216903 5.5079645,63.864846 5.1781154,61.103952 L 5.0626464,60.137457 H 35.082363 65.102079 l 0.846727,-0.999502 0.846727,-0.999502 14.008664,-0.0028 14.008664,-0.0028 -0.448212,0.608534 c -0.246516,0.334694 -2.007086,2.750931 -3.912377,5.369416 l -3.464163,4.760882 H 48.240623 9.4931382 Z"
|
||||
id="path1081" />
|
||||
<path
|
||||
style="fill:#ffffff;stroke-width:0.143184"
|
||||
d="m 9.9979505,57.658297 c 0.1712305,-0.182266 0.3113275,-0.375185 0.3113275,-0.42871 0,-0.05352 -1.0470357,-0.620035 -2.3267465,-1.258913 C 6.7028207,55.331796 5.5430269,54.709316 5.4052119,54.587387 4.8631251,54.107784 5.232159,53.12142 5.9536824,53.12142 c 0.1919693,0 1.7009565,0.676547 3.353305,1.503437 l 3.0042696,1.503436 h 1.289962 1.289961 v 0.930699 0.930699 H 12.288901 9.6866226 Z"
|
||||
id="path1120" />
|
||||
<path
|
||||
style="fill:#ffffff;stroke-width:0.143184"
|
||||
d="m 21.48941,52.58938 c 0.08131,-0.213871 0.289125,-0.642753 0.461805,-0.953071 0.233262,-0.41919 0.267045,-0.580237 0.131433,-0.62655 -0.100392,-0.03428 -1.198966,-0.566295 -2.441276,-1.182245 -1.780636,-0.882858 -2.296958,-1.203778 -2.439274,-1.516129 -0.156194,-0.342807 -0.143671,-0.445819 0.09289,-0.764168 0.150383,-0.202373 0.437562,-0.387694 0.638178,-0.411825 0.23926,-0.02878 1.403932,0.476165 3.385168,1.467641 l 3.020413,1.511515 h 1.791107 1.791106 v 1.431844 1.431844 h -3.289698 -3.289697 z"
|
||||
id="path1159" />
|
||||
<path
|
||||
style="fill:#ffffff;stroke-width:0.143184"
|
||||
d="m 21.04811,56.557847 v -1.431845 h 13.530928 13.530928 v -3.508018 -3.508018 h 6.944444 6.944445 v 1.002291 1.002291 h 2.265443 c 2.566892,0 3.232208,0.148442 4.125235,0.920402 l 0.54747,0.473251 2.41565,-1.197972 c 1.328608,-0.658885 2.560374,-1.197972 2.737257,-1.197972 0.688286,0 1.065636,1.011253 0.54497,1.460458 -0.137815,0.1189 -1.25168,0.738048 -2.475257,1.375884 l -2.224682,1.159703 0.05734,1.427574 0.05734,1.427574 -2.100273,0.04663 -2.100274,0.04662 -0.938055,0.966495 -0.938056,0.966495 H 42.510536 21.04811 Z"
|
||||
id="path1198" />
|
||||
<path
|
||||
style="fill:#ffffff;stroke-width:0.143184"
|
||||
d="m 34.077892,50.544101 v -2.434135 h 1.002291 1.002291 l 0.0031,-1.396048 c 0.0036,-1.605199 0.211653,-2.216094 1.083205,-3.180798 0.884174,-0.978675 1.745706,-1.336946 3.388163,-1.40898 l 1.396049,-0.06123 v 5.457662 5.457661 h -3.937572 -3.937572 z"
|
||||
id="path1237" />
|
||||
<path
|
||||
style="fill:#ffffff;stroke-width:0.143184"
|
||||
d="m 50.114548,43.026919 v -2.935281 h 1.00229 1.002291 v -1.586405 -1.586406 l -0.393757,0.07534 c -2.099692,0.401766 -5.334423,0.458101 -6.228522,0.108472 l -0.393757,-0.153974 v -1.881642 -1.881641 l 0.322165,0.100046 c 0.662429,0.205712 3.382745,0.230183 4.975658,0.04476 l 1.646621,-0.191676 0.0744,-0.832568 c 0.104937,-1.174253 0.698918,-1.568355 1.448967,-0.96138 l 0.338028,0.273548 0.04186,4.227408 0.04186,4.227408 2.392272,0.04515 c 2.719781,0.05133 3.233067,0.203712 4.308416,1.279062 0.87953,0.879531 1.171787,1.61851 1.266244,3.201748 l 0.08134,1.363308 h -5.963191 -5.96319 z"
|
||||
id="path1276" />
|
||||
<path
|
||||
style="fill:#ffffff;stroke-width:0.143184"
|
||||
d="m 77.176403,55.05441 v -0.930699 h 1.289961 1.289962 l 3.00427,-1.503436 c 1.652348,-0.82689 3.162284,-1.503437 3.355413,-1.503437 0.669479,0 1.049829,1.020533 0.546362,1.465967 -0.137815,0.12193 -1.297609,0.744409 -2.577319,1.383287 -1.279711,0.638878 -2.326747,1.217761 -2.326747,1.286406 0,0.06864 0.09665,0.205021 0.214776,0.303058 0.118127,0.09804 0.214777,0.234792 0.214777,0.303901 0,0.06911 -1.127577,0.125652 -2.505727,0.125652 h -2.505728 z"
|
||||
id="path1315" />
|
||||
<path
|
||||
id="rect19723"
|
||||
style="fill:#0a0905;fill-opacity:0.00325377"
|
||||
d="m -16.457031,106.02344 c -0.09869,-0.0101 -0.226864,0.0135 -0.337891,0.0176 v 4.50195 c 2.858361,-0.0741 5.717295,-0.13045 8.576172,-0.19141 -0.068853,-0.0359 -0.1376782,-0.0728 -0.2011719,-0.12109 -0.032427,-0.0246 -0.052834,-0.0565 -0.076172,-0.0859 -0.1390539,-0.0172 -0.031246,-0.005 -0.1816406,-0.0234 0.031812,-0.0539 0.054148,-0.12027 0.080078,-0.18164 -0.047055,-0.21237 0.00416,-0.47542 0.048828,-0.73633 -0.6462425,-0.0804 -1.2940664,-0.15598 -1.9394525,-0.24023 -0.170699,-0.0262 -1.578114,-0.24279 -2.152344,-0.36719 -0.382403,0.0426 -0.758146,0.0799 -0.888672,-0.21484 -0.08023,-0.18117 -0.01566,-0.37747 0.0957,-0.56445 -0.09785,-0.31782 -0.104835,-0.64471 0.08984,-0.85743 0.08715,-0.0952 0.193996,-0.13548 0.314453,-0.14062 0.361372,-0.0154 0.837989,0.28285 1.220703,0.3418 2.1227589,0.32716 3.5275433,0.56043 4.9628905,0.8125 0.9858406,0.12017 1.9716153,0.23945 2.9570312,0.36132 0.1728924,-0.24751 0.3778528,-0.5237 0.6582031,-0.86718 -0.012909,-0.0395 -0.015132,-0.0814 -0.027344,-0.1211 -1.2522898,-0.12533 -2.5056202,-0.23943 -3.7578125,-0.36523 -3.1472303,-0.31618 -6.2947943,-0.63477 -9.4414063,-0.95703 z m 1.292969,12.93164 c -0.499562,-0.0409 -1.176812,0.20752 -1.63086,0.0918 v 0.46874 c 1.37429,0.0254 2.748777,0.0511 4.123047,0.0762 -0.128696,-0.0893 -0.235011,-0.20761 -0.345703,-0.32032 -0.0253,-0.005 -0.05088,-0.008 -0.07617,-0.0137 -0.237847,-0.0491 -0.738557,-0.0409 -0.755859,-0.22461 -0.470907,-0.0285 -0.808539,-0.0478 -1.314453,-0.0781 z m -1.63086,6.39258 v 5.33593 H 37.658203 V 128.625 c -4.451195,-0.23361 -8.895228,-0.60523 -13.34375,-0.88867 C 17.043465,127.27306 9.7729959,126.8095 2.5,126.37891 c -4.5047987,-0.26671 -9.0134779,-0.48978 -13.519531,-0.73438 -1.925325,-0.0987 -3.850468,-0.19528 -5.775391,-0.29687 z" />
|
||||
<path
|
||||
id="rect19727"
|
||||
style="fill:#0a0905;fill-opacity:0.00325377"
|
||||
d="m -5.5507812,107.12305 v 1.01367 c 0.5522335,0.0673 1.1040927,0.13552 1.65625,0.20312 0.1734369,-0.2487 0.381598,-0.52697 0.6640624,-0.87304 -0.012909,-0.0395 -0.015132,-0.0814 -0.027344,-0.1211 -0.7641245,-0.0765 -1.5285643,-0.14933 -2.2929684,-0.22265 z m 0,18.81836 v 1.41015 H 18.130859 C 12.920964,127.02141 7.7113698,126.68744 2.5,126.37891 c -2.68257778,-0.15883 -5.3668253,-0.29587 -8.0507812,-0.4375 z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.9 KiB |
@@ -78,6 +78,12 @@ export class UnitLayer implements Layer {
|
||||
case UnitType.Destroyer:
|
||||
this.handleDestroyerEvent(event);
|
||||
break;
|
||||
case UnitType.Battleship:
|
||||
this.handleBattleshipEvent(event);
|
||||
break;
|
||||
case UnitType.Shell:
|
||||
this.handleShellEvent(event)
|
||||
break;
|
||||
case UnitType.TradeShip:
|
||||
this.handleTradeShipEvent(event)
|
||||
break;
|
||||
@@ -116,6 +122,14 @@ export class UnitLayer implements Layer {
|
||||
.forEach(t => this.paintCell(t.cell(), this.theme.territoryColor(event.unit.owner().info()), 255));
|
||||
}
|
||||
|
||||
private handleShellEvent(event: UnitEvent) {
|
||||
this.clearCell(event.oldTile.cell())
|
||||
if (!event.unit.isActive()) {
|
||||
return
|
||||
}
|
||||
this.paintCell(event.unit.tile().cell(), this.theme.borderColor(event.unit.owner().info()), 255)
|
||||
}
|
||||
|
||||
|
||||
private handleNuke(event: UnitEvent) {
|
||||
bfs(event.oldTile, euclDist(event.oldTile, 2)).forEach(t => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { BuildUnitIntentEvent } from '../../../Transport';
|
||||
import atomBombIcon from '../../../../../resources/images/NukeIconWhite.svg';
|
||||
import hydrogenBombIcon from '../../../../../resources/images/MushroomCloudIconWhite.svg';
|
||||
import destroyerIcon from '../../../../../resources/images/DestroyerIconWhite.svg';
|
||||
import battleshipIcon from '../../../../../resources/images/BattleshipIconWhite.svg';
|
||||
import missileSiloIcon from '../../../../../resources/images/MissileSiloIconWhite.svg';
|
||||
import goldCoinIcon from '../../../../../resources/images/GoldCoinIcon.svg';
|
||||
import portIcon from '../../../../../resources/images/PortIcon.svg';
|
||||
@@ -22,6 +23,7 @@ const buildTable: BuildItemDisplay[][] = [
|
||||
{ unitType: UnitType.AtomBomb, icon: atomBombIcon },
|
||||
{ unitType: UnitType.HydrogenBomb, icon: hydrogenBombIcon },
|
||||
{ unitType: UnitType.Destroyer, icon: destroyerIcon },
|
||||
{ unitType: UnitType.Battleship, icon: battleshipIcon },
|
||||
{ unitType: UnitType.Port, icon: portIcon },
|
||||
{ unitType: UnitType.MissileSilo, icon: missileSiloIcon }
|
||||
]
|
||||
@@ -156,23 +158,7 @@ export class BuildMenu extends LitElement {
|
||||
}
|
||||
|
||||
public onBuildSelected = (item: BuildItemDisplay) => {
|
||||
switch (item.unitType) {
|
||||
case UnitType.AtomBomb:
|
||||
this.eventBus.emit(new BuildUnitIntentEvent(UnitType.AtomBomb, this.clickedCell))
|
||||
break
|
||||
case UnitType.HydrogenBomb:
|
||||
this.eventBus.emit(new BuildUnitIntentEvent(UnitType.HydrogenBomb, this.clickedCell))
|
||||
break
|
||||
case UnitType.Destroyer:
|
||||
this.eventBus.emit(new BuildUnitIntentEvent(UnitType.Destroyer, this.clickedCell))
|
||||
break
|
||||
case UnitType.Port:
|
||||
this.eventBus.emit(new BuildUnitIntentEvent(UnitType.Port, this.clickedCell))
|
||||
break
|
||||
case UnitType.MissileSilo:
|
||||
this.eventBus.emit(new BuildUnitIntentEvent(UnitType.MissileSilo, this.clickedCell))
|
||||
break
|
||||
}
|
||||
this.eventBus.emit(new BuildUnitIntentEvent(item.unitType, this.clickedCell))
|
||||
this.hideMenu()
|
||||
};
|
||||
|
||||
|
||||
@@ -29,9 +29,19 @@ export class DefaultConfig implements Config {
|
||||
cost: (p: Player) => (p.units(UnitType.Destroyer).length + 1) * 250_000,
|
||||
territoryBound: false
|
||||
}
|
||||
case UnitType.Battleship:
|
||||
return {
|
||||
cost: (p: Player) => (p.units(UnitType.Battleship).length + 1) * 500_000,
|
||||
territoryBound: false
|
||||
}
|
||||
case UnitType.Shell:
|
||||
return {
|
||||
cost: (p: Player) => (p.units(UnitType.Destroyer).length + 1) * 500_000,
|
||||
territoryBound: false
|
||||
}
|
||||
case UnitType.Port:
|
||||
return {
|
||||
cost: (p: Player) => (p.units(UnitType.Port).length + 1) * 250_000,
|
||||
cost: (p: Player) => Math.pow(2, p.units(UnitType.Port).length) * 250_000,
|
||||
territoryBound: true
|
||||
}
|
||||
case UnitType.AtomBomb:
|
||||
|
||||
@@ -13,7 +13,7 @@ export const devConfig = new class extends DefaultConfig {
|
||||
return 95
|
||||
}
|
||||
numSpawnPhaseTurns(): number {
|
||||
return 40
|
||||
return 80
|
||||
}
|
||||
gameCreationRate(): number {
|
||||
return 20 * 1000
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import { Cell, Execution, MutableGame, MutablePlayer, MutableUnit, PlayerID, Tile, UnitType } from "../game/Game";
|
||||
import { AStar, PathFinder, PathFindResultType } from "../PathFinding";
|
||||
import { PseudoRandom } from "../PseudoRandom";
|
||||
import { distSort, distSortUnit, manhattanDist } from "../Util";
|
||||
import { ShellExecution } from "./ShellExecution";
|
||||
|
||||
export class BattleshipExecution implements Execution {
|
||||
private random: PseudoRandom
|
||||
|
||||
private _owner: MutablePlayer
|
||||
private active = true
|
||||
private battleship: MutableUnit = null
|
||||
private mg: MutableGame = null
|
||||
|
||||
private pathfinder = new PathFinder(5000, t => t.isWater())
|
||||
|
||||
private patrolTile: Tile;
|
||||
private patrolCenterTile: Tile
|
||||
|
||||
// TODO: put in config
|
||||
private searchRange = 100
|
||||
private attackRate = 20
|
||||
private lastAttack = 0
|
||||
|
||||
constructor(
|
||||
private playerID: PlayerID,
|
||||
private cell: Cell,
|
||||
) { }
|
||||
|
||||
|
||||
init(mg: MutableGame, ticks: number): void {
|
||||
this._owner = mg.player(this.playerID)
|
||||
this.mg = mg
|
||||
this.patrolCenterTile = mg.tile(this.cell)
|
||||
this.patrolTile = this.patrolCenterTile
|
||||
this.random = new PseudoRandom(mg.ticks())
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.battleship == null) {
|
||||
const spawn = this._owner.canBuild(UnitType.Battleship, this.patrolTile)
|
||||
if (spawn == false) {
|
||||
this.active = false
|
||||
return
|
||||
}
|
||||
this.battleship = this._owner.buildUnit(UnitType.Battleship, 0, spawn)
|
||||
return
|
||||
}
|
||||
if (!this.battleship.isActive()) {
|
||||
this.active = false
|
||||
return
|
||||
}
|
||||
|
||||
if (this.mg.ticks() % 2 == 0) {
|
||||
const result = this.pathfinder.nextTile(this.battleship.tile(), this.patrolTile)
|
||||
switch (result.type) {
|
||||
case PathFindResultType.Completed:
|
||||
this.patrolTile = this.randomTile()
|
||||
break
|
||||
case PathFindResultType.NextTile:
|
||||
this.battleship.move(result.tile)
|
||||
break
|
||||
case PathFindResultType.Pending:
|
||||
return
|
||||
case PathFindResultType.PathNotFound:
|
||||
console.log(`path not found to patrol tile`)
|
||||
this.patrolTile = this.randomTile()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (this.mg.ticks() - this.lastAttack < this.attackRate) {
|
||||
return
|
||||
}
|
||||
|
||||
const ships = this.mg.units(UnitType.TransportShip, UnitType.Destroyer, UnitType.TradeShip, UnitType.Battleship)
|
||||
.filter(u => manhattanDist(u.tile().cell(), this.battleship.tile().cell()) < 100)
|
||||
.filter(u => u.owner() != this.battleship.owner())
|
||||
.filter(u => u != this.battleship)
|
||||
.filter(u => !u.owner().isAlliedWith(this.battleship.owner()))
|
||||
.sort(distSortUnit(this.battleship));
|
||||
|
||||
if (ships.length > 0) {
|
||||
this.lastAttack = this.mg.ticks()
|
||||
this.mg.addExecution(new ShellExecution(this.battleship.tile(), this.battleship.owner(), ships[0]))
|
||||
}
|
||||
}
|
||||
|
||||
owner(): MutablePlayer {
|
||||
return this._owner
|
||||
}
|
||||
|
||||
isActive(): boolean {
|
||||
return this.active
|
||||
}
|
||||
|
||||
activeDuringSpawnPhase(): boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
randomTile(): Tile {
|
||||
while (true) {
|
||||
const x = this.patrolCenterTile.cell().x + this.random.nextInt(-this.searchRange / 2, this.searchRange / 2)
|
||||
const y = this.patrolCenterTile.cell().y + this.random.nextInt(-this.searchRange / 2, this.searchRange / 2)
|
||||
const cell = new Cell(x, y)
|
||||
if (!this.mg.isOnMap(cell)) {
|
||||
continue
|
||||
}
|
||||
const tile = this.mg.tile(cell)
|
||||
if (!tile.isOcean()) {
|
||||
continue
|
||||
}
|
||||
return tile
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -52,7 +52,7 @@ export class DestroyerExecution implements Execution {
|
||||
this.target = null
|
||||
}
|
||||
if (this.target == null) {
|
||||
const ships = this.mg.units(UnitType.TransportShip, UnitType.Destroyer, UnitType.TradeShip)
|
||||
const ships = this.mg.units(UnitType.TransportShip, UnitType.Destroyer, UnitType.TradeShip, UnitType.Battleship)
|
||||
.filter(u => manhattanDist(u.tile().cell(), this.destroyer.tile().cell()) < 100)
|
||||
.filter(u => u.owner() != this.destroyer.owner())
|
||||
.filter(u => u != this.destroyer)
|
||||
|
||||
@@ -19,6 +19,7 @@ import { SetTargetTroopRatioExecution } from "./SetTargetTroopRatioExecution";
|
||||
import { DestroyerExecution } from "./DestroyerExecution";
|
||||
import { PortExecution } from "./PortExecution";
|
||||
import { MissileSiloExecution } from "./MissileSiloExecution";
|
||||
import { BattleshipExecution } from "./BattleshipExecution";
|
||||
|
||||
|
||||
|
||||
@@ -88,6 +89,8 @@ export class Executor {
|
||||
return new NukeExecution(intent.unit, intent.player, new Cell(intent.x, intent.y))
|
||||
case UnitType.Destroyer:
|
||||
return new DestroyerExecution(intent.player, new Cell(intent.x, intent.y))
|
||||
case UnitType.Battleship:
|
||||
return new BattleshipExecution(intent.player, new Cell(intent.x, intent.y))
|
||||
case UnitType.Port:
|
||||
return new PortExecution(intent.player, new Cell(intent.x, intent.y))
|
||||
case UnitType.MissileSilo:
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { Execution, MutableGame, MutablePlayer, MutableUnit, Tile, Unit, UnitType } from "../game/Game";
|
||||
import { PathFinder, PathFindResultType } from "../PathFinding";
|
||||
|
||||
export class ShellExecution implements Execution {
|
||||
|
||||
private active = true
|
||||
private pathFinder = new PathFinder(2000, () => true, 10)
|
||||
private shell: MutableUnit
|
||||
|
||||
constructor(private spawn: Tile, private _owner: MutablePlayer, private target: MutableUnit) {
|
||||
|
||||
}
|
||||
|
||||
init(mg: MutableGame, ticks: number): void {
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.shell == null) {
|
||||
this.shell = this._owner.buildUnit(UnitType.Shell, 0, this.spawn)
|
||||
}
|
||||
if (!this.target.isActive()) {
|
||||
this.shell.delete()
|
||||
this.active = false
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const result = this.pathFinder.nextTile(this.shell.tile(), this.target.tile())
|
||||
switch (result.type) {
|
||||
case PathFindResultType.Completed:
|
||||
this.active = false
|
||||
this.target.delete()
|
||||
this.shell.delete()
|
||||
return
|
||||
case PathFindResultType.NextTile:
|
||||
this.shell.move(result.tile)
|
||||
break
|
||||
case PathFindResultType.Pending:
|
||||
return
|
||||
case PathFindResultType.PathNotFound:
|
||||
console.log(`Shell ${this.shell} could not find target`)
|
||||
this.active = false
|
||||
this.shell.delete()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
owner(): MutablePlayer {
|
||||
return null
|
||||
}
|
||||
isActive(): boolean {
|
||||
return this.active
|
||||
}
|
||||
activeDuringSpawnPhase(): boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,8 @@ export interface UnitInfo {
|
||||
export enum UnitType {
|
||||
TransportShip = "Transport",
|
||||
Destroyer = "Destroyer",
|
||||
Battleship = "Battleship",
|
||||
Shell = "Shell",
|
||||
Port = "Port",
|
||||
AtomBomb = "Atom Bomb",
|
||||
HydrogenBomb = "Hydrogen Bomb",
|
||||
|
||||
@@ -357,7 +357,10 @@ export class PlayerImpl implements MutablePlayer {
|
||||
case UnitType.Port:
|
||||
return this.portSpawn(targetTile)
|
||||
case UnitType.Destroyer:
|
||||
return this.destroyerSpawn(targetTile)
|
||||
case UnitType.Battleship:
|
||||
return this.warshipSpawn(targetTile)
|
||||
case UnitType.Shell:
|
||||
return targetTile
|
||||
case UnitType.MissileSilo:
|
||||
return this.missileSiloSpawn(targetTile)
|
||||
case UnitType.TransportShip:
|
||||
@@ -387,7 +390,7 @@ export class PlayerImpl implements MutablePlayer {
|
||||
return spawns[0]
|
||||
}
|
||||
|
||||
destroyerSpawn(tile: Tile): Tile | false {
|
||||
warshipSpawn(tile: Tile): Tile | false {
|
||||
if (!tile.isOcean()) {
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user