@rpgjs/server 3.3.2 → 4.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/lib/Game/Map.d.ts +58 -5
- package/lib/Game/Map.js +185 -80
- package/lib/Game/Map.js.map +1 -1
- package/lib/Game/WorldMaps.d.ts +3 -2
- package/lib/Game/WorldMaps.js +6 -11
- package/lib/Game/WorldMaps.js.map +1 -1
- package/lib/Gui/DialogGui.d.ts +1 -1
- package/lib/Gui/DialogGui.js +12 -13
- package/lib/Gui/DialogGui.js.map +1 -1
- package/lib/Gui/Gui.js +2 -6
- package/lib/Gui/Gui.js.map +1 -1
- package/lib/Gui/MenuGui.js +4 -8
- package/lib/Gui/MenuGui.js.map +1 -1
- package/lib/Gui/NotificationGui.js +4 -8
- package/lib/Gui/NotificationGui.js.map +1 -1
- package/lib/Gui/ShopGui.js +4 -8
- package/lib/Gui/ShopGui.js.map +1 -1
- package/lib/Gui/index.js +6 -13
- package/lib/Gui/index.js.map +1 -1
- package/lib/Interfaces/Gui.js +1 -2
- package/lib/Interfaces/StateStore.js +1 -2
- package/lib/MatchMaker.js +28 -46
- package/lib/MatchMaker.js.map +1 -1
- package/lib/Monitor/index.js +3 -5
- package/lib/Monitor/index.js.map +1 -1
- package/lib/Player/BattleManager.js +17 -16
- package/lib/Player/BattleManager.js.map +1 -1
- package/lib/Player/ClassManager.js +6 -10
- package/lib/Player/ClassManager.js.map +1 -1
- package/lib/Player/ComponentManager.d.ts +4 -4
- package/lib/Player/ComponentManager.js +37 -24
- package/lib/Player/ComponentManager.js.map +1 -1
- package/lib/Player/EffectManager.js +8 -12
- package/lib/Player/EffectManager.js.map +1 -1
- package/lib/Player/ElementManager.js +5 -9
- package/lib/Player/ElementManager.js.map +1 -1
- package/lib/Player/GoldManager.js +1 -5
- package/lib/Player/GoldManager.js.map +1 -1
- package/lib/Player/GuiManager.js +17 -15
- package/lib/Player/GuiManager.js.map +1 -1
- package/lib/Player/ItemFixture.js +1 -5
- package/lib/Player/ItemFixture.js.map +1 -1
- package/lib/Player/ItemManager.d.ts +3 -3
- package/lib/Player/ItemManager.js +29 -31
- package/lib/Player/ItemManager.js.map +1 -1
- package/lib/Player/MoveManager.d.ts +7 -6
- package/lib/Player/MoveManager.js +67 -74
- package/lib/Player/MoveManager.js.map +1 -1
- package/lib/Player/ParameterManager.js +10 -14
- package/lib/Player/ParameterManager.js.map +1 -1
- package/lib/Player/Player.d.ts +7 -1
- package/lib/Player/Player.js +193 -191
- package/lib/Player/Player.js.map +1 -1
- package/lib/Player/SkillManager.js +18 -22
- package/lib/Player/SkillManager.js.map +1 -1
- package/lib/Player/StateManager.js +9 -13
- package/lib/Player/StateManager.js.map +1 -1
- package/lib/Player/VariableManager.js +1 -5
- package/lib/Player/VariableManager.js.map +1 -1
- package/lib/Query.d.ts +2 -1
- package/lib/Query.js +19 -15
- package/lib/Query.js.map +1 -1
- package/lib/RpgServer.d.ts +11 -3
- package/lib/RpgServer.js +1 -2
- package/lib/Scenes/Map.d.ts +27 -4
- package/lib/Scenes/Map.js +117 -122
- package/lib/Scenes/Map.js.map +1 -1
- package/lib/decorators/event.js +4 -7
- package/lib/decorators/event.js.map +1 -1
- package/lib/decorators/map.d.ts +1 -1
- package/lib/decorators/map.js +5 -9
- package/lib/decorators/map.js.map +1 -1
- package/lib/entry-point.js +59 -65
- package/lib/entry-point.js.map +1 -1
- package/lib/express/api.d.ts +3 -0
- package/lib/express/api.js +105 -0
- package/lib/express/api.js.map +1 -0
- package/lib/express/errors/NotAuthorized.d.ts +4 -0
- package/lib/express/errors/NotAuthorized.js +7 -0
- package/lib/express/errors/NotAuthorized.js.map +1 -0
- package/lib/express/errors/NotFound.d.ts +4 -0
- package/lib/express/errors/NotFound.js +7 -0
- package/lib/express/errors/NotFound.js.map +1 -0
- package/lib/express/server.js +20 -5
- package/lib/express/server.js.map +1 -1
- package/lib/index.js +15 -68
- package/lib/index.js.map +1 -1
- package/lib/logs/index.js +5 -11
- package/lib/logs/index.js.map +1 -1
- package/lib/logs/item.js +11 -15
- package/lib/logs/item.js.map +1 -1
- package/lib/logs/log.js +1 -5
- package/lib/logs/log.js.map +1 -1
- package/lib/logs/skill.js +6 -10
- package/lib/logs/skill.js.map +1 -1
- package/lib/logs/state.js +5 -9
- package/lib/logs/state.js.map +1 -1
- package/lib/models/Item.js +1 -2
- package/lib/presets/index.js +28 -36
- package/lib/presets/index.js.map +1 -1
- package/lib/server.d.ts +23 -2
- package/lib/server.js +227 -134
- package/lib/server.js.map +1 -1
- package/package.json +24 -16
- package/src/Game/Map.ts +513 -0
- package/src/Game/WorldMaps.ts +45 -0
- package/src/Gui/DialogGui.ts +67 -0
- package/src/Gui/Gui.ts +45 -0
- package/src/Gui/MenuGui.ts +26 -0
- package/src/Gui/NotificationGui.ts +10 -0
- package/src/Gui/ShopGui.ts +43 -0
- package/src/Gui/index.ts +13 -0
- package/src/Interfaces/Gui.ts +4 -0
- package/src/Interfaces/StateStore.ts +5 -0
- package/src/MatchMaker.ts +63 -0
- package/src/Monitor/index.ts +78 -0
- package/src/Player/BattleManager.ts +123 -0
- package/src/Player/ClassManager.ts +72 -0
- package/src/Player/ComponentManager.ts +538 -0
- package/src/Player/EffectManager.ts +94 -0
- package/src/Player/ElementManager.ts +142 -0
- package/src/Player/GoldManager.ts +26 -0
- package/src/Player/GuiManager.ts +308 -0
- package/src/Player/ItemFixture.ts +24 -0
- package/src/Player/ItemManager.ts +474 -0
- package/src/Player/MoveManager.ts +635 -0
- package/src/Player/ParameterManager.ts +468 -0
- package/src/Player/Player.ts +931 -0
- package/src/Player/SkillManager.ts +229 -0
- package/src/Player/StateManager.ts +230 -0
- package/src/Player/VariableManager.ts +55 -0
- package/src/Query.ts +172 -0
- package/src/RpgServer.ts +429 -0
- package/src/Scenes/Map.ts +302 -0
- package/src/decorators/event.ts +57 -0
- package/src/decorators/map.ts +223 -0
- package/src/entry-point.ts +102 -0
- package/src/express/api.ts +118 -0
- package/src/express/errors/NotAuthorized.ts +6 -0
- package/src/express/errors/NotFound.ts +6 -0
- package/src/express/server.ts +93 -0
- package/src/index.ts +28 -0
- package/src/logs/index.ts +11 -0
- package/src/logs/item.ts +31 -0
- package/src/logs/log.ts +3 -0
- package/src/logs/skill.ts +16 -0
- package/src/logs/state.ts +13 -0
- package/src/models/Item.ts +11 -0
- package/src/presets/index.ts +71 -0
- package/src/server.ts +394 -0
- package/tsconfig.json +27 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Router } from 'express'
|
|
2
|
+
import { RpgServerEngine } from '../server'
|
|
3
|
+
import { Query } from '../Query'
|
|
4
|
+
import { RpgMap } from '../Game/Map'
|
|
5
|
+
import { NotAuthorized } from './errors/NotAuthorized'
|
|
6
|
+
import { NotFound } from './errors/NotFound'
|
|
7
|
+
|
|
8
|
+
type ApiConfig = {
|
|
9
|
+
enabled?: boolean,
|
|
10
|
+
authSecret?: string,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function api(rpgServer: RpgServerEngine): Router {
|
|
14
|
+
const router = new Router()
|
|
15
|
+
|
|
16
|
+
router.use((req, res, next) => {
|
|
17
|
+
try {
|
|
18
|
+
const apiConfig: ApiConfig = rpgServer.globalConfig.api || {}
|
|
19
|
+
const enabled = apiConfig.enabled === undefined ? false : apiConfig.enabled
|
|
20
|
+
const { dev } = req.query
|
|
21
|
+
if (process.env.NODE_ENV === 'development' && dev) {
|
|
22
|
+
return next()
|
|
23
|
+
}
|
|
24
|
+
if (!enabled) {
|
|
25
|
+
throw new NotAuthorized('API disabled')
|
|
26
|
+
}
|
|
27
|
+
const authSecret = apiConfig.authSecret
|
|
28
|
+
if (!authSecret) {
|
|
29
|
+
throw new NotAuthorized('API secret not defined')
|
|
30
|
+
}
|
|
31
|
+
// headers
|
|
32
|
+
const authHeader = req.headers.authorization
|
|
33
|
+
if (!authHeader) {
|
|
34
|
+
throw new NotAuthorized('Authorization header not defined')
|
|
35
|
+
}
|
|
36
|
+
const [type, token] = authHeader.split(' ')
|
|
37
|
+
if (type !== 'Bearer') {
|
|
38
|
+
throw new NotAuthorized('Authorization type not supported')
|
|
39
|
+
}
|
|
40
|
+
if (token !== authSecret) {
|
|
41
|
+
throw new NotAuthorized('Authorization token not valid')
|
|
42
|
+
}
|
|
43
|
+
next()
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
next(err)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
router.get('/players', (req, res) => {
|
|
51
|
+
const players = Query.getPlayers()
|
|
52
|
+
res.json(players)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
router.put('/maps', (req, res, next) => {
|
|
56
|
+
try {
|
|
57
|
+
const { mapId, data, mapFile } = req.body
|
|
58
|
+
const maps = rpgServer.sceneMap.getMaps()
|
|
59
|
+
const findMap = maps.find(map => {
|
|
60
|
+
if (mapId) {
|
|
61
|
+
return map.id === mapId
|
|
62
|
+
}
|
|
63
|
+
else if (mapFile) {
|
|
64
|
+
return map.file === mapFile
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
if (findMap) {
|
|
68
|
+
const map = Query.getRoom<RpgMap>(findMap.id as string)
|
|
69
|
+
map.update(data)
|
|
70
|
+
res.json({ success: true })
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
throw new NotFound('Map not found')
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
next(err)
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
router.put('/tilesets', async (req, res, next) => {
|
|
82
|
+
try {
|
|
83
|
+
const { data, tilesetId } = req.body
|
|
84
|
+
const maps = Query.getRooms<RpgMap>()
|
|
85
|
+
for (let [id, map] of maps) {
|
|
86
|
+
const findTileset = map.tilesets.find(tileset => tileset.name === tilesetId)
|
|
87
|
+
if (findTileset) {
|
|
88
|
+
await map.updateTileset(data)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
res.json({ success: true })
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
next(err)
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
router.put('/worlds', (req, res, next) => {
|
|
99
|
+
try {
|
|
100
|
+
const { worldId, data } = req.body
|
|
101
|
+
const sceneMap = rpgServer.sceneMap
|
|
102
|
+
const world = sceneMap.getWorldMaps(worldId)
|
|
103
|
+
if (world) {
|
|
104
|
+
sceneMap.deleteWorldMaps(worldId)
|
|
105
|
+
sceneMap.createDynamicWorldMaps(data)
|
|
106
|
+
res.json({ success: true })
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
throw new NotFound('World not found')
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
next(err)
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
return router
|
|
118
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import http from 'http'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import express from 'express'
|
|
4
|
+
import { Server } from 'socket.io'
|
|
5
|
+
import entryPoint from '../entry-point'
|
|
6
|
+
import PrettyError from 'pretty-error'
|
|
7
|
+
import { ModuleType } from '@rpgjs/common'
|
|
8
|
+
import { RpgServerEngine } from '../server'
|
|
9
|
+
import { api } from './api'
|
|
10
|
+
import { Query } from '../Query'
|
|
11
|
+
|
|
12
|
+
type ExpressServerOptions = {
|
|
13
|
+
basePath: string,
|
|
14
|
+
globalConfig?: any,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function expressServer(modules: ModuleType[], options: ExpressServerOptions): Promise<{
|
|
18
|
+
app: express.Express,
|
|
19
|
+
server: http.Server,
|
|
20
|
+
game: RpgServerEngine
|
|
21
|
+
}> {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const dirname = options.basePath
|
|
24
|
+
const PORT = process.env.PORT || 3000
|
|
25
|
+
const pe = new PrettyError()
|
|
26
|
+
const app = express()
|
|
27
|
+
const server = http.createServer(app)
|
|
28
|
+
const io = new Server(server, {
|
|
29
|
+
maxHttpBufferSize: 1e10,
|
|
30
|
+
cors: {
|
|
31
|
+
origin: "*",
|
|
32
|
+
methods: ["GET", "POST"]
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
const isBuilt = !!import.meta.env.VITE_BUILT
|
|
38
|
+
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
const hasStatic = process.env.STATIC_DIRECTORY_ENABLED
|
|
41
|
+
const staticDirectory = isBuilt ? '' : 'dist'
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
const staticEnabled = (isBuilt && hasStatic === undefined) || hasStatic === 'true'
|
|
44
|
+
|
|
45
|
+
if (!isBuilt) {
|
|
46
|
+
app.use(express.json({
|
|
47
|
+
// TODO
|
|
48
|
+
limit: '50mb'
|
|
49
|
+
}))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (staticEnabled) {
|
|
53
|
+
app.use('/', express.static(path.join(dirname, '..', staticDirectory, 'client')))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function start() {
|
|
57
|
+
const rpgGame = await entryPoint(modules, { io, ...options })
|
|
58
|
+
rpgGame.app = app
|
|
59
|
+
rpgGame.start()
|
|
60
|
+
app.use('/api', api(rpgGame))
|
|
61
|
+
app.use((err: any, req: any, res: any, next: any) => {
|
|
62
|
+
const status = err.status || 500
|
|
63
|
+
res.status(status).json({ error: err.message })
|
|
64
|
+
})
|
|
65
|
+
resolve({
|
|
66
|
+
app,
|
|
67
|
+
server,
|
|
68
|
+
game: rpgGame
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
const serverPort = (import.meta.env.VITE_SERVER_URL || '').split(':')[1] || PORT
|
|
74
|
+
server.listen(serverPort, start)
|
|
75
|
+
|
|
76
|
+
process.on('uncaughtException', function (error) {
|
|
77
|
+
console.log(pe.render(error))
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
process.on('unhandledRejection', function (reason: any) {
|
|
81
|
+
console.log(pe.render(reason))
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
if (import.meta['hot']) {
|
|
85
|
+
import.meta['hot'].on("vite:beforeFullReload", () => {
|
|
86
|
+
server.close()
|
|
87
|
+
Query.getPlayers().forEach(player => {
|
|
88
|
+
player.gameReload()
|
|
89
|
+
})
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export { default as entryPoint } from './entry-point'
|
|
2
|
+
export {
|
|
3
|
+
Direction,
|
|
4
|
+
Input,
|
|
5
|
+
Control,
|
|
6
|
+
RpgPlugin,
|
|
7
|
+
HookServer,
|
|
8
|
+
HookClient,
|
|
9
|
+
RpgModule,
|
|
10
|
+
RpgShape,
|
|
11
|
+
ShapePositioning,
|
|
12
|
+
AbstractObject
|
|
13
|
+
} from '@rpgjs/common'
|
|
14
|
+
export { RpgServer, RpgPlayerHooks, RpgServerEngineHooks } from './RpgServer'
|
|
15
|
+
export { EventData } from './decorators/event'
|
|
16
|
+
export { MapData } from './decorators/map'
|
|
17
|
+
export { RpgPlayer, RpgEvent, EventMode } from './Player/Player'
|
|
18
|
+
export { RpgMap } from './Game/Map'
|
|
19
|
+
export { RpgWorldMaps } from './Game/WorldMaps'
|
|
20
|
+
export { Query, Query as RpgWorld } from './Query'
|
|
21
|
+
export { default as Monitor } from './Monitor'
|
|
22
|
+
export * as Presets from './presets'
|
|
23
|
+
export { Move, Frequency, Speed } from './Player/MoveManager'
|
|
24
|
+
export { RpgServerEngine } from './server'
|
|
25
|
+
export { SceneMap as RpgSceneMap, RpgClassMap } from './Scenes/Map'
|
|
26
|
+
export { RpgMatchMaker } from './MatchMaker'
|
|
27
|
+
export { IStoreState } from './Interfaces/StateStore'
|
|
28
|
+
export { Components } from './Player/ComponentManager'
|
package/src/logs/item.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Log } from './log'
|
|
2
|
+
|
|
3
|
+
export class ItemLog {
|
|
4
|
+
static notInInventory(itemClass) {
|
|
5
|
+
return new Log('ITEM_NOT_INVENTORY', `The item ${itemClass.name} is not in inventory`)
|
|
6
|
+
}
|
|
7
|
+
static notUseItem(itemClass) {
|
|
8
|
+
return new Log('NOT_USE_ITEM', `The player cannot use the ${itemClass.name} item.`)
|
|
9
|
+
}
|
|
10
|
+
static chanceToUseFailed(itemClass) {
|
|
11
|
+
return new Log('USE_CHANCE_ITEM_FAILED', `Chance to use the ${itemClass.name} item has failed`)
|
|
12
|
+
}
|
|
13
|
+
static invalidToEquiped(itemClass) {
|
|
14
|
+
return new Log('INVALID_ITEM_TO_EQUIP', `The item ${itemClass.name} is not a weapon or armor`)
|
|
15
|
+
}
|
|
16
|
+
static isAlreadyEquiped(itemClass) {
|
|
17
|
+
return new Log('ITEM_ALREADY_EQUIPED', `The item ${itemClass.name} is already equiped`)
|
|
18
|
+
}
|
|
19
|
+
static haveNotPrice(itemClass) {
|
|
20
|
+
return new Log('NOT_PRICE', `Define a price > 0 to buy ${itemClass.name}`)
|
|
21
|
+
}
|
|
22
|
+
static notEnoughGold(itemClass, nb) {
|
|
23
|
+
return new Log('NOT_ENOUGH_GOLD', `not enough gold to buy ${nb} ${itemClass.name}`)
|
|
24
|
+
}
|
|
25
|
+
static tooManyToSell(itemClass, nbToSell, nb) {
|
|
26
|
+
return new Log('TOO_MANY_ITEM_TO_SELL', `Too many items to sell: ${nbToSell} ${itemClass.name}, only ${nb} in inventory`)
|
|
27
|
+
}
|
|
28
|
+
static restriction(itemClass) {
|
|
29
|
+
return new Log('RESTRICTION_ITEM', `A state blocks the use of the ${itemClass.name} skill`)
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/logs/log.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Log } from './log'
|
|
2
|
+
|
|
3
|
+
export class SkillLog {
|
|
4
|
+
static notLearned(skillClass) {
|
|
5
|
+
return new Log('SKILL_NOT_LEARNED', `the skill ${skillClass.name} is not learned`)
|
|
6
|
+
}
|
|
7
|
+
static notEnoughSp(skillClass, skillSp, playerSp) {
|
|
8
|
+
return new Log('NOT_ENOUGH_SP', `not enough SP to use ${skillClass.name} skill. ${skillSp} Skill'SP is is greater than ${playerSp} Player'SP`)
|
|
9
|
+
}
|
|
10
|
+
static chanceToUseFailed(skillClass) {
|
|
11
|
+
return new Log('USE_CHANCE_SKILL_FAILED', `Chance to use the ${skillClass.name} skill has failed`)
|
|
12
|
+
}
|
|
13
|
+
static restriction(skillClass) {
|
|
14
|
+
return new Log('RESTRICTION_SKILL', `A state blocks the use of the ${skillClass.name} skill`)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Log } from './log'
|
|
2
|
+
|
|
3
|
+
export class StateLog {
|
|
4
|
+
static addFailed(stateClass) {
|
|
5
|
+
return new Log('ADD_STATE_FAILED', `Adding the ${stateClass.name} state has failed`)
|
|
6
|
+
}
|
|
7
|
+
static removeFailed(stateClass) {
|
|
8
|
+
return new Log('REMOVE_STATE_FAILED', `Removing the ${stateClass.name} state has failed`)
|
|
9
|
+
}
|
|
10
|
+
static notApplied(stateClass) {
|
|
11
|
+
return new Log('STATE_NOT_APPLIED', `State ${stateClass.name} does not exist`)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ItemOptions } from '@rpgjs/database'
|
|
2
|
+
import { RpgPlayer } from '../Player/Player';
|
|
3
|
+
|
|
4
|
+
export interface ItemModel extends ItemOptions {
|
|
5
|
+
id: string
|
|
6
|
+
equipped?: boolean
|
|
7
|
+
onUseFailed?: (player: RpgPlayer) => {}
|
|
8
|
+
onUse?: (player: RpgPlayer) => {}
|
|
9
|
+
onAdd?: (player: RpgPlayer) => {}
|
|
10
|
+
onRemove?: (player: RpgPlayer) => {}
|
|
11
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Utils } from '@rpgjs/common'
|
|
2
|
+
|
|
3
|
+
const { random } = Utils
|
|
4
|
+
|
|
5
|
+
export const MAXHP: string = 'maxHp'
|
|
6
|
+
export const MAXSP: string = 'maxSp'
|
|
7
|
+
export const ATK: string = 'atk'
|
|
8
|
+
export const PDEF: string = 'pdef'
|
|
9
|
+
export const SDEF: string = 'sdef'
|
|
10
|
+
export const STR: string = 'str'
|
|
11
|
+
export const AGI: string = 'agi'
|
|
12
|
+
export const INT: string = 'int'
|
|
13
|
+
export const DEX: string = 'dex'
|
|
14
|
+
|
|
15
|
+
export const MAXHP_CURVE = {
|
|
16
|
+
start: 741,
|
|
17
|
+
end: 7467
|
|
18
|
+
}
|
|
19
|
+
export const MAXSP_CURVE = {
|
|
20
|
+
start: 534,
|
|
21
|
+
end: 5500
|
|
22
|
+
}
|
|
23
|
+
export const STR_CURVE = {
|
|
24
|
+
start: 67,
|
|
25
|
+
end: 635
|
|
26
|
+
}
|
|
27
|
+
export const AGI_CURVE = {
|
|
28
|
+
start: 58,
|
|
29
|
+
end: 582
|
|
30
|
+
}
|
|
31
|
+
export const INT_CURVE = {
|
|
32
|
+
start: 36,
|
|
33
|
+
end: 7318
|
|
34
|
+
}
|
|
35
|
+
export const DEX_CURVE = {
|
|
36
|
+
start: 54,
|
|
37
|
+
end: 564
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const DAMAGE_CRITICAL = function(damage, a, b) {
|
|
41
|
+
if (random(0, 100) < 4 * a[DEX] / b[AGI]) {
|
|
42
|
+
damage *= 2
|
|
43
|
+
}
|
|
44
|
+
return damage
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const DAMAGE_PHYSIC = function(a, b) {
|
|
48
|
+
let damage = Math.round((a[ATK] - b[PDEF] / 2) * ((20 + a[STR]) / 20))
|
|
49
|
+
if (damage < 0) damage = 0
|
|
50
|
+
return damage
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const DAMAGE_GUARD = function(damage) {
|
|
54
|
+
return damage / 2
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const COEFFICIENT_ELEMENTS = function(a, b, bDef) {
|
|
58
|
+
return ((a.rate + 1) * (b.rate + 1)) / (bDef.rate == 0 ? bDef.rate * 4 : 1)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const DAMAGE_SKILL = function(a, b, skill) {
|
|
62
|
+
let power = skill.power + (a[ATK] * (skill.coefficient[ATK] || 0))
|
|
63
|
+
if (power > 0) {
|
|
64
|
+
power -= b[PDEF] * (skill.coefficient[PDEF] || 0) / 2
|
|
65
|
+
power -= b[SDEF] * (skill.coefficient[SDEF] || 0) / 2
|
|
66
|
+
power = Math.max(power, 0)
|
|
67
|
+
}
|
|
68
|
+
let rate = 20;
|
|
69
|
+
[STR, DEX, AGI, INT].forEach(val => rate += a[val] * (skill.coefficient[val] || 0))
|
|
70
|
+
return Math.round(power * rate / 20)
|
|
71
|
+
}
|