Advertisement
_LINKI

BodyBuilder | Screeps

Aug 13th, 2020 (edited)
1,241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class Builder
  2. {
  3.     constructor(...parts)
  4.     {
  5.         this.parts = parts
  6.     }
  7.    
  8.     setParts(...parts)
  9.     {
  10.         this.parts = parts
  11.         return this
  12.     }
  13.     addPart(part)
  14.     {
  15.         if (!this.parts)
  16.             this.parts = []
  17.        
  18.         this.parts.push(part)
  19.         return this
  20.     }
  21.    
  22.     setMaxCost(value)
  23.     {
  24.         this.maxCost = value
  25.         return this
  26.     }
  27.     setMaxLevel(value)
  28.     {
  29.         this.maxLevel = value
  30.         return this
  31.     }
  32.     setTerrainFactor(value)
  33.     {
  34.         this.terrainFactor = value
  35.         return this
  36.     }
  37.    
  38.     build(maxCost = Infinity, terrainFactor = GROUND, maxLevel = Infinity)
  39.     {
  40.         maxCost = this.maxCost < maxCost
  41.             ? this.maxCost
  42.             : maxCost
  43.        
  44.         maxLevel = this.maxLevel || maxLevel
  45.         terrainFactor = this.terrainFactor || terrainFactor
  46.        
  47.         const body = new Body(this.parts, maxCost, maxLevel, terrainFactor)
  48.         while(body.upgrade()) { }
  49.        
  50.         return body.build()
  51.     }
  52. }
  53.  
  54. class Body
  55. {
  56.     constructor(parts, maxCost, maxLevel, terrainFactor)
  57.     {
  58.         this.parts = parts
  59.         this.maxLevel = maxLevel
  60.         this.maxCost = maxCost
  61.         this.terrainFactor = terrainFactor
  62.        
  63.         this.reset()
  64.     }
  65.    
  66.     reset()
  67.     {
  68.         this.level = 0
  69.         this.cost = 0
  70.         this.countMove = 0
  71.        
  72.         this.resetParts()
  73.     }
  74.     resetParts()
  75.     {
  76.         for (var part of this.parts)
  77.         {
  78.             if (part.level)
  79.                 part.reset()
  80.                
  81.             if (part.type == MOVE)
  82.                 this.movePart = part
  83.         }
  84.        
  85.         if (!this.movePart)
  86.             this.addMovePart()
  87.        
  88.         this.setupMovePart()
  89.     }
  90.     addMovePart()
  91.     {
  92.         this.movePart = new Part(MOVE)
  93.         this.parts.unshift(this.movePart)
  94.     }
  95.     setupMovePart()
  96.     {
  97.         this.movePart.excludeMove = true
  98.        
  99.         if (this.parts.length == 1)
  100.             this.movePart.maxCount = 1
  101.     }
  102.    
  103.     upgrade()
  104.     {
  105.         if (this.canUpgrade() == false)
  106.         {
  107.             this.fixCostOverflow()
  108.             return false
  109.         }
  110.        
  111.         this.initializeUpgrade()
  112.         const result = this.upgradeAllParts()
  113.         this.finalizeUpgrade(result)
  114.        
  115.         return result
  116.     }
  117.     canUpgrade()
  118.     {
  119.         return this.cost < this.maxCost
  120.             && this.level < this.maxLevel
  121.     }
  122.     fixCostOverflow()
  123.     {
  124.         if (this.cost > this.maxCost)
  125.             this.downgrade()
  126.     }
  127.     initializeUpgrade()
  128.     {
  129.         this.cost = 0
  130.         this.movePart.proportion = 0
  131.     }
  132.     upgradeAllParts()
  133.     {
  134.         const baseResult = this.upgradeBaseParts()
  135.         const moveResult = this.upgradeMove()
  136.         if (baseResult == false) return false
  137.        
  138.         return baseResult | moveResult
  139.     }
  140.     finalizeUpgrade(result)
  141.     {
  142.         if (result) this.level++
  143.     }
  144.    
  145.     upgradeBaseParts()
  146.     {
  147.         var someDone = false
  148.        
  149.         for (var part of this.parts)
  150.         {
  151.             if (part.type == MOVE && this.parts.length > 1) continue
  152.             someDone |= this.upgradePart(part)
  153.         }
  154.        
  155.         return someDone
  156.     }
  157.     upgradePart(part)
  158.     {
  159.         if (part.type == MOVE)
  160.             part.proportion = 1
  161.        
  162.         const upgradeResult = part.upgrade()
  163.        
  164.         if (part.excludeMove == false)
  165.             this.movePart.proportion += part.proportion
  166.        
  167.         this.cost += part.cost
  168.         return upgradeResult
  169.     }
  170.     upgradeMove()
  171.     {
  172.         if (this.parts.length == 1)
  173.             return false
  174.        
  175.         this.movePart.proportion *= this.terrainFactor
  176.         const result = this.movePart.upgrade()
  177.        
  178.         this.cost += this.movePart.cost
  179.         return result
  180.     }
  181.    
  182.     downgrade()
  183.     {
  184.         this.initializeDowngrade()
  185.         this.downgradeParts()
  186.         this.finalizeDowngrade()
  187.     }
  188.     initializeDowngrade()
  189.     {
  190.         this.cost = 0
  191.     }
  192.     finalizeDowngrade()
  193.     {
  194.         this.level--
  195.     }
  196.    
  197.     downgradeParts()
  198.     {
  199.         for (var part of this.parts)
  200.             this.downgradePart(part)
  201.     }
  202.     downgradePart(part)
  203.     {
  204.         part.downgrade()
  205.         this.cost += part.cost
  206.     }
  207.    
  208.     build()
  209.     {
  210.         return new UpgradedBody(
  211.             this.buildBody(),
  212.             this.level,
  213.             this.cost
  214.         )
  215.     }
  216.     buildBody()
  217.     {
  218.         const body = []
  219.        
  220.         for (var part of this.parts)
  221.             body.push(...part.build())
  222.        
  223.         return body
  224.     }
  225. }
  226.  
  227. class UpgradedBody
  228. {
  229.     constructor(body, level, cost)
  230.     {
  231.         this.body = body
  232.         this.level = level
  233.         this.cost = cost
  234.         this.success = level != 0
  235.     }
  236. }
  237.  
  238. class Part
  239. {
  240.     constructor(type,
  241.         maxCount = Infinity,
  242.         proportion = 1,
  243.         maxLevel = Infinity,
  244.         maxCost = Infinity,
  245.         excludeMove = false)
  246.     {
  247.         this.type = type
  248.         this.baseCost = BODYPART_COST[type]
  249.        
  250.         this.maxCost = maxCost
  251.         this.maxLevel = maxLevel
  252.         this.maxCount = maxCount
  253.        
  254.         this.baseProportion = proportion
  255.         this.proportion = proportion
  256.         this.excludeMove = excludeMove
  257.        
  258.         this.reset()
  259.     }
  260.    
  261.     setType(value)
  262.     {
  263.         this.type = value
  264.         return this
  265.     }
  266.    
  267.     setMaxCost(value)
  268.     {
  269.         this.maxCost = value
  270.         return this
  271.     }
  272.     setMaxLevel(value)
  273.     {
  274.         this.maxLevel = value
  275.         return this
  276.     }
  277.     setMaxCount(value)
  278.     {
  279.         this.max = value
  280.         return this
  281.     }
  282.    
  283.     setProportion(value)
  284.     {
  285.         this.proportion = this.baseProportion = value
  286.         return this
  287.     }
  288.     setExcludeMove(value)
  289.     {
  290.         this.excludeMove = value
  291.         return this
  292.     }
  293.    
  294.    
  295.     reset()
  296.     {
  297.         this.count = 0
  298.         this.level = 0
  299.        
  300.         this.fullCount = 0
  301.         this.cost = 0
  302.        
  303.         this.proportion = this.baseProportion
  304.     }
  305.    
  306.     upgrade()
  307.     {
  308.         if (this.canUpgrade() == false)
  309.         {
  310.             this.proportion = 0
  311.             return false
  312.         }
  313.        
  314.         this.addLevel()
  315.         return true
  316.     }
  317.     canUpgrade()
  318.     {
  319.         return this.cost < this.maxCost
  320.             && this.level < this.maxLevel
  321.             && this.count < this.maxCount
  322.             && this.proportion > 0
  323.     }
  324.     addLevel()
  325.     {
  326.         this.changeLevel(this.level + 1)
  327.     }
  328.    
  329.     downgrade()
  330.     {
  331.         if (this.canDowngrade())
  332.             this.subLevel()
  333.     }
  334.     canDowngrade()
  335.     {
  336.         return this.proportion > 0
  337.     }
  338.     subLevel()
  339.     {
  340.         this.changeLevel(this.level - 1)
  341.     }
  342.    
  343.     changeLevel(value)
  344.     {
  345.         if (this.level < value)
  346.             this.count += this.proportion
  347.         else if (this.level > value)
  348.             this.count -= this.proportion
  349.        
  350.         this.level = value
  351.        
  352.         this.fullCount = Math.ceil(this.count)
  353.         this.cost = this.baseCost * this.fullCount
  354.     }
  355.    
  356.     build()
  357.     {
  358.         const body = []
  359.        
  360.         for (var i = 0; i < this.fullCount; i++)
  361.             body.push(this.type)
  362.        
  363.         return body
  364.     }
  365. }
  366.  
  367. // TerrainFactors
  368. const ROAD = 0.5
  369. const GROUND = 1
  370. const SWAMP = 5
  371.  
  372. module.exports = {
  373.     Builder : Builder,
  374.     Body : Body,
  375.     UpgradedBody : UpgradedBody,
  376.     Part : Part,
  377.    
  378.     // Terrain factors
  379.     ROAD : ROAD,
  380.     GROUND : GROUND,
  381.     SWAMP : SWAMP
  382. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement