2020-05-09 14:45:23 +00:00
import { Loader } from "../../core/loader" ;
import { enumDirection , Vector , enumAngleToDirection , enumDirectionToVector } from "../../core/vector" ;
import { ItemAcceptorComponent } from "../components/item_acceptor" ;
import { ItemEjectorComponent } from "../components/item_ejector" ;
import { enumUndergroundBeltMode , UndergroundBeltComponent } from "../components/underground_belt" ;
import { Entity } from "../entity" ;
2020-05-16 21:48:56 +00:00
import { MetaBuilding , defaultBuildingVariant } from "../meta_building" ;
2020-06-28 17:34:10 +00:00
import { GameRoot , enumLayer } from "../root" ;
2020-05-09 14:45:23 +00:00
import { globalConfig } from "../../core/config" ;
import { enumHubGoalRewards } from "../tutorial_goals" ;
2020-05-17 13:32:19 +00:00
import { formatItemsPerSecond } from "../../core/utils" ;
import { T } from "../../translations" ;
2020-05-09 14:45:23 +00:00
/** @enum {string} */
export const arrayUndergroundRotationVariantToMode = [
enumUndergroundBeltMode . sender ,
enumUndergroundBeltMode . receiver ,
] ;
2020-05-16 21:48:56 +00:00
/** @enum {string} */
2020-08-06 18:24:21 +00:00
//Github insisted these needed to be on multiple lines to pass a check.
2020-08-06 18:36:39 +00:00
export const enumUndergroundBeltVariants = {
2020-08-06 18:29:17 +00:00
side : "side" ,
sideMirrored : "side-mirrored" ,
tier2 : "tier2" ,
tier2Side : "tier2-side" ,
tier2SideMirrored : "tier2-side-mirrored" ,
2020-08-06 18:24:21 +00:00
} ;
2020-05-16 21:48:56 +00:00
export const enumUndergroundBeltVariantToTier = {
[ defaultBuildingVariant ] : 0 ,
2020-08-02 17:35:40 +00:00
[ enumUndergroundBeltVariants . side ] : 0 ,
[ enumUndergroundBeltVariants . sideMirrored ] : 0 ,
2020-05-16 21:48:56 +00:00
[ enumUndergroundBeltVariants . tier2 ] : 1 ,
2020-08-02 17:35:40 +00:00
[ enumUndergroundBeltVariants . tier2Side ] : 1 ,
[ enumUndergroundBeltVariants . tier2SideMirrored ] : 1 ,
2020-05-16 21:48:56 +00:00
} ;
2020-08-04 16:27:16 +00:00
//This might want to be looked at. I don't understand the whole enum thing well enough to make this return them, nor indeed whether that would be the appropriate course of action.
export const enumUndergroundBeltVariantToDirection = {
[ defaultBuildingVariant ] : "straight" ,
[ enumUndergroundBeltVariants . side ] : "left" ,
[ enumUndergroundBeltVariants . sideMirrored ] : "right" ,
[ enumUndergroundBeltVariants . tier2 ] : "straight" ,
[ enumUndergroundBeltVariants . tier2Side ] : "left" ,
[ enumUndergroundBeltVariants . tier2SideMirrored ] : "right" ,
} ;
2020-05-09 14:45:23 +00:00
export class MetaUndergroundBeltBuilding extends MetaBuilding {
constructor ( ) {
super ( "underground_belt" ) ;
}
getSilhouetteColor ( ) {
return "#555" ;
}
getFlipOrientationAfterPlacement ( ) {
return true ;
}
getStayInPlacementMode ( ) {
return true ;
}
2020-05-17 13:32:19 +00:00
/ * *
* @ param { GameRoot } root
* @ param { string } variant
* @ returns { Array < [ string , string ] > }
* /
getAdditionalStatistics ( root , variant ) {
2020-05-17 13:51:58 +00:00
const rangeTiles =
globalConfig . undergroundBeltMaxTilesByTier [ enumUndergroundBeltVariantToTier [ variant ] ] ;
2020-05-17 13:32:19 +00:00
const beltSpeed = root . hubGoals . getUndergroundBeltBaseSpeed ( ) ;
2020-05-17 13:51:58 +00:00
return [
[
T . ingame . buildingPlacement . infoTexts . range ,
T . ingame . buildingPlacement . infoTexts . tiles . replace ( "<x>" , "" + rangeTiles ) ,
] ,
[ T . ingame . buildingPlacement . infoTexts . speed , formatItemsPerSecond ( beltSpeed ) ] ,
] ;
2020-05-17 13:32:19 +00:00
}
2020-05-17 12:46:33 +00:00
/ * *
* @ param { GameRoot } root
* /
2020-05-16 21:48:56 +00:00
getAvailableVariants ( root ) {
2020-05-17 12:46:33 +00:00
if ( root . hubGoals . isRewardUnlocked ( enumHubGoalRewards . reward _underground _belt _tier _2 ) ) {
2020-08-06 18:24:21 +00:00
//Github insisted these needed to be on multiple lines to pass a check.
return [
2020-08-06 18:29:17 +00:00
defaultBuildingVariant ,
enumUndergroundBeltVariants . side ,
enumUndergroundBeltVariants . sideMirrored ,
enumUndergroundBeltVariants . tier2 ,
enumUndergroundBeltVariants . tier2Side ,
enumUndergroundBeltVariants . tier2SideMirrored ,
2020-08-06 18:24:21 +00:00
] ;
2020-05-17 12:46:33 +00:00
}
2020-08-06 18:24:21 +00:00
return [
2020-08-06 18:29:17 +00:00
defaultBuildingVariant ,
enumUndergroundBeltVariants . side ,
enumUndergroundBeltVariants . sideMirrored ,
2020-08-06 18:24:21 +00:00
] ;
2020-05-16 21:48:56 +00:00
}
2020-07-27 15:14:29 +00:00
/ * *
* @ param { number } rotationVariant
* @ param { string } variant
* /
2020-05-16 21:48:56 +00:00
getPreviewSprite ( rotationVariant , variant ) {
let suffix = "" ;
if ( variant !== defaultBuildingVariant ) {
suffix = "-" + variant ;
}
2020-05-09 14:45:23 +00:00
switch ( arrayUndergroundRotationVariantToMode [ rotationVariant ] ) {
case enumUndergroundBeltMode . sender :
2020-05-16 21:48:56 +00:00
return Loader . getSprite ( "sprites/buildings/underground_belt_entry" + suffix + ".png" ) ;
2020-05-09 14:45:23 +00:00
case enumUndergroundBeltMode . receiver :
2020-05-16 21:48:56 +00:00
return Loader . getSprite ( "sprites/buildings/underground_belt_exit" + suffix + ".png" ) ;
2020-05-09 14:45:23 +00:00
default :
assertAlways ( false , "Invalid rotation variant" ) ;
}
}
2020-07-27 15:14:29 +00:00
/ * *
* @ param { number } rotationVariant
* @ param { string } variant
* /
2020-05-16 21:48:56 +00:00
getBlueprintSprite ( rotationVariant , variant ) {
let suffix = "" ;
if ( variant !== defaultBuildingVariant ) {
suffix = "-" + variant ;
}
2020-05-10 15:00:02 +00:00
switch ( arrayUndergroundRotationVariantToMode [ rotationVariant ] ) {
case enumUndergroundBeltMode . sender :
2020-05-16 21:48:56 +00:00
return Loader . getSprite ( "sprites/blueprints/underground_belt_entry" + suffix + ".png" ) ;
2020-05-10 15:00:02 +00:00
case enumUndergroundBeltMode . receiver :
2020-05-16 21:48:56 +00:00
return Loader . getSprite ( "sprites/blueprints/underground_belt_exit" + suffix + ".png" ) ;
2020-05-10 15:00:02 +00:00
default :
assertAlways ( false , "Invalid rotation variant" ) ;
}
}
2020-07-27 15:14:29 +00:00
/ * *
* @ param { number } rotationVariant
* @ param { string } variant
* /
getSprite ( rotationVariant , variant ) {
return this . getPreviewSprite ( rotationVariant , variant ) ;
}
2020-05-09 14:45:23 +00:00
/ * *
* @ param { GameRoot } root
* /
getIsUnlocked ( root ) {
return root . hubGoals . isRewardUnlocked ( enumHubGoalRewards . reward _tunnel ) ;
}
/ * *
* Creates the entity at the given location
* @ param { Entity } entity
* /
setupEntityComponents ( entity ) {
// Required, since the item processor needs this.
entity . addComponent (
new ItemEjectorComponent ( {
slots : [ ] ,
} )
) ;
entity . addComponent ( new UndergroundBeltComponent ( { } ) ) ;
entity . addComponent (
new ItemAcceptorComponent ( {
slots : [ ] ,
} )
) ;
}
/ * *
2020-06-30 06:23:05 +00:00
* Should compute the optimal rotation variant on the given tile
* @ param { object } param0
* @ param { GameRoot } param0 . root
* @ param { Vector } param0 . tile
* @ param { number } param0 . rotation
* @ param { string } param0 . variant
* @ param { string } param0 . layer
2020-05-09 14:45:23 +00:00
* @ return { { rotation : number , rotationVariant : number , connectedEntities ? : Array < Entity > } }
* /
2020-06-30 06:23:05 +00:00
computeOptimalDirectionAndRotationVariantAtTile ( { root , tile , rotation , variant , layer } ) {
2020-05-09 14:45:23 +00:00
const searchDirection = enumAngleToDirection [ rotation ] ;
const searchVector = enumDirectionToVector [ searchDirection ] ;
2020-05-16 21:48:56 +00:00
const tier = enumUndergroundBeltVariantToTier [ variant ] ;
2020-05-09 14:45:23 +00:00
const targetRotation = ( rotation + 180 ) % 360 ;
2020-05-23 09:08:27 +00:00
const targetSenderRotation = rotation ;
2020-05-09 14:45:23 +00:00
2020-05-16 21:48:56 +00:00
for (
let searchOffset = 1 ;
searchOffset <= globalConfig . undergroundBeltMaxTilesByTier [ tier ] ;
++ searchOffset
) {
2020-05-09 14:45:23 +00:00
tile = tile . addScalars ( searchVector . x , searchVector . y ) ;
2020-06-28 17:34:10 +00:00
/* WIRES: FIXME */
const contents = root . map . getTileContent ( tile , enumLayer . regular ) ;
2020-05-09 14:45:23 +00:00
if ( contents ) {
const undergroundComp = contents . components . UndergroundBelt ;
2020-05-16 21:48:56 +00:00
if ( undergroundComp && undergroundComp . tier === tier ) {
2020-05-09 14:45:23 +00:00
const staticComp = contents . components . StaticMapEntity ;
2020-05-10 15:45:48 +00:00
if ( staticComp . rotation === targetRotation ) {
2020-05-09 14:45:23 +00:00
if ( undergroundComp . mode !== enumUndergroundBeltMode . sender ) {
// If we encounter an underground receiver on our way which is also faced in our direction, we don't accept that
break ;
}
return {
rotation : targetRotation ,
rotationVariant : 1 ,
connectedEntities : [ contents ] ,
} ;
2020-05-23 09:08:27 +00:00
} else if ( staticComp . rotation === targetSenderRotation ) {
// Draw connections to receivers
if ( undergroundComp . mode === enumUndergroundBeltMode . receiver ) {
return {
rotation : rotation ,
rotationVariant : 0 ,
connectedEntities : [ contents ] ,
} ;
2020-06-11 15:33:25 +00:00
} else {
break ;
2020-05-23 09:08:27 +00:00
}
2020-05-09 14:45:23 +00:00
}
}
}
}
return {
rotation ,
rotationVariant : 0 ,
} ;
}
/ * *
2020-05-16 21:48:56 +00:00
*
2020-05-09 14:45:23 +00:00
* @ param { Entity } entity
* @ param { number } rotationVariant
2020-05-16 21:48:56 +00:00
* @ param { string } variant
2020-05-09 14:45:23 +00:00
* /
2020-05-16 21:48:56 +00:00
updateVariants ( entity , rotationVariant , variant ) {
entity . components . UndergroundBelt . tier = enumUndergroundBeltVariantToTier [ variant ] ;
2020-08-06 16:54:27 +00:00
entity . components . UndergroundBelt . direction = enumUndergroundBeltVariantToDirection [ variant ] ;
2020-05-09 14:45:23 +00:00
switch ( arrayUndergroundRotationVariantToMode [ rotationVariant ] ) {
case enumUndergroundBeltMode . sender : {
entity . components . UndergroundBelt . mode = enumUndergroundBeltMode . sender ;
entity . components . ItemEjector . setSlots ( [ ] ) ;
2020-08-06 16:54:27 +00:00
switch ( enumUndergroundBeltVariantToDirection [ variant ] ) {
case "straight" : {
entity . components . ItemAcceptor . setSlots ( [
{
pos : new Vector ( 0 , 0 ) ,
directions : [ enumDirection . bottom ] ,
} ,
] ) ;
2020-08-06 17:56:15 +00:00
return ;
2020-08-06 16:54:27 +00:00
}
case "left" : {
entity . components . ItemAcceptor . setSlots ( [
{
pos : new Vector ( 0 , 0 ) ,
directions : [ enumDirection . left ] ,
} ,
] ) ;
2020-08-06 17:56:15 +00:00
return ;
2020-08-06 16:54:27 +00:00
}
case "right" : {
entity . components . ItemAcceptor . setSlots ( [
{
pos : new Vector ( 0 , 0 ) ,
directions : [ enumDirection . right ] ,
} ,
] ) ;
2020-08-06 17:56:15 +00:00
return ;
2020-08-06 16:54:27 +00:00
}
}
2020-05-09 14:45:23 +00:00
return ;
}
case enumUndergroundBeltMode . receiver : {
entity . components . UndergroundBelt . mode = enumUndergroundBeltMode . receiver ;
entity . components . ItemAcceptor . setSlots ( [ ] ) ;
2020-08-06 16:54:27 +00:00
switch ( enumUndergroundBeltVariantToDirection [ variant ] ) {
case "straight" : {
entity . components . ItemEjector . setSlots ( [
{
pos : new Vector ( 0 , 0 ) ,
directions : [ enumDirection . bottom ] ,
} ,
] ) ;
2020-08-06 17:56:15 +00:00
return ;
2020-08-06 16:54:27 +00:00
}
case "left" : {
entity . components . ItemEjector . setSlots ( [
{
pos : new Vector ( 0 , 0 ) ,
directions : [ enumDirection . left ] ,
} ,
] ) ;
2020-08-06 17:56:15 +00:00
return ;
2020-08-06 16:54:27 +00:00
}
case "right" : {
entity . components . ItemEjector . setSlots ( [
{
pos : new Vector ( 0 , 0 ) ,
directions : [ enumDirection . right ] ,
} ,
] ) ;
2020-08-06 17:56:15 +00:00
return ;
2020-08-06 18:13:59 +00:00
}
2020-08-06 16:54:27 +00:00
}
2020-05-09 14:45:23 +00:00
return ;
}
default :
assertAlways ( false , "Invalid rotation variant" ) ;
}
}
}