Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Builder
- {
- constructor(...parts)
- {
- this.parts = parts
- }
- setParts(...parts)
- {
- this.parts = parts
- return this
- }
- addPart(part)
- {
- if (!this.parts)
- this.parts = []
- this.parts.push(part)
- return this
- }
- setMaxCost(value)
- {
- this.maxCost = value
- return this
- }
- setMaxLevel(value)
- {
- this.maxLevel = value
- return this
- }
- setTerrainFactor(value)
- {
- this.terrainFactor = value
- return this
- }
- build(maxCost = Infinity, terrainFactor = GROUND, maxLevel = Infinity)
- {
- maxCost = this.maxCost < maxCost
- ? this.maxCost
- : maxCost
- maxLevel = this.maxLevel || maxLevel
- terrainFactor = this.terrainFactor || terrainFactor
- const body = new Body(this.parts, maxCost, maxLevel, terrainFactor)
- while(body.upgrade()) { }
- return body.build()
- }
- }
- class Body
- {
- constructor(parts, maxCost, maxLevel, terrainFactor)
- {
- this.parts = parts
- this.maxLevel = maxLevel
- this.maxCost = maxCost
- this.terrainFactor = terrainFactor
- this.reset()
- }
- reset()
- {
- this.level = 0
- this.cost = 0
- this.countMove = 0
- this.resetParts()
- }
- resetParts()
- {
- for (var part of this.parts)
- {
- if (part.level)
- part.reset()
- if (part.type == MOVE)
- this.movePart = part
- }
- if (!this.movePart)
- this.addMovePart()
- this.setupMovePart()
- }
- addMovePart()
- {
- this.movePart = new Part(MOVE)
- this.parts.unshift(this.movePart)
- }
- setupMovePart()
- {
- this.movePart.excludeMove = true
- if (this.parts.length == 1)
- this.movePart.maxCount = 1
- }
- upgrade()
- {
- if (this.canUpgrade() == false)
- {
- this.fixCostOverflow()
- return false
- }
- this.initializeUpgrade()
- const result = this.upgradeAllParts()
- this.finalizeUpgrade(result)
- return result
- }
- canUpgrade()
- {
- return this.cost < this.maxCost
- && this.level < this.maxLevel
- }
- fixCostOverflow()
- {
- if (this.cost > this.maxCost)
- this.downgrade()
- }
- initializeUpgrade()
- {
- this.cost = 0
- this.movePart.proportion = 0
- }
- upgradeAllParts()
- {
- const baseResult = this.upgradeBaseParts()
- const moveResult = this.upgradeMove()
- if (baseResult == false) return false
- return baseResult | moveResult
- }
- finalizeUpgrade(result)
- {
- if (result) this.level++
- }
- upgradeBaseParts()
- {
- var someDone = false
- for (var part of this.parts)
- {
- if (part.type == MOVE && this.parts.length > 1) continue
- someDone |= this.upgradePart(part)
- }
- return someDone
- }
- upgradePart(part)
- {
- if (part.type == MOVE)
- part.proportion = 1
- const upgradeResult = part.upgrade()
- if (part.excludeMove == false)
- this.movePart.proportion += part.proportion
- this.cost += part.cost
- return upgradeResult
- }
- upgradeMove()
- {
- if (this.parts.length == 1)
- return false
- this.movePart.proportion *= this.terrainFactor
- const result = this.movePart.upgrade()
- this.cost += this.movePart.cost
- return result
- }
- downgrade()
- {
- this.initializeDowngrade()
- this.downgradeParts()
- this.finalizeDowngrade()
- }
- initializeDowngrade()
- {
- this.cost = 0
- }
- finalizeDowngrade()
- {
- this.level--
- }
- downgradeParts()
- {
- for (var part of this.parts)
- this.downgradePart(part)
- }
- downgradePart(part)
- {
- part.downgrade()
- this.cost += part.cost
- }
- build()
- {
- return new UpgradedBody(
- this.buildBody(),
- this.level,
- this.cost
- )
- }
- buildBody()
- {
- const body = []
- for (var part of this.parts)
- body.push(...part.build())
- return body
- }
- }
- class UpgradedBody
- {
- constructor(body, level, cost)
- {
- this.body = body
- this.level = level
- this.cost = cost
- this.success = level != 0
- }
- }
- class Part
- {
- constructor(type,
- maxCount = Infinity,
- proportion = 1,
- maxLevel = Infinity,
- maxCost = Infinity,
- excludeMove = false)
- {
- this.type = type
- this.baseCost = BODYPART_COST[type]
- this.maxCost = maxCost
- this.maxLevel = maxLevel
- this.maxCount = maxCount
- this.baseProportion = proportion
- this.proportion = proportion
- this.excludeMove = excludeMove
- this.reset()
- }
- setType(value)
- {
- this.type = value
- return this
- }
- setMaxCost(value)
- {
- this.maxCost = value
- return this
- }
- setMaxLevel(value)
- {
- this.maxLevel = value
- return this
- }
- setMaxCount(value)
- {
- this.max = value
- return this
- }
- setProportion(value)
- {
- this.proportion = this.baseProportion = value
- return this
- }
- setExcludeMove(value)
- {
- this.excludeMove = value
- return this
- }
- reset()
- {
- this.count = 0
- this.level = 0
- this.fullCount = 0
- this.cost = 0
- this.proportion = this.baseProportion
- }
- upgrade()
- {
- if (this.canUpgrade() == false)
- {
- this.proportion = 0
- return false
- }
- this.addLevel()
- return true
- }
- canUpgrade()
- {
- return this.cost < this.maxCost
- && this.level < this.maxLevel
- && this.count < this.maxCount
- && this.proportion > 0
- }
- addLevel()
- {
- this.changeLevel(this.level + 1)
- }
- downgrade()
- {
- if (this.canDowngrade())
- this.subLevel()
- }
- canDowngrade()
- {
- return this.proportion > 0
- }
- subLevel()
- {
- this.changeLevel(this.level - 1)
- }
- changeLevel(value)
- {
- if (this.level < value)
- this.count += this.proportion
- else if (this.level > value)
- this.count -= this.proportion
- this.level = value
- this.fullCount = Math.ceil(this.count)
- this.cost = this.baseCost * this.fullCount
- }
- build()
- {
- const body = []
- for (var i = 0; i < this.fullCount; i++)
- body.push(this.type)
- return body
- }
- }
- // TerrainFactors
- const ROAD = 0.5
- const GROUND = 1
- const SWAMP = 5
- module.exports = {
- Builder : Builder,
- Body : Body,
- UpgradedBody : UpgradedBody,
- Part : Part,
- // Terrain factors
- ROAD : ROAD,
- GROUND : GROUND,
- SWAMP : SWAMP
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement