FlexCore-TS-SDK 是为 FlexCore 游戏引擎提供的 TypeScript 脚本开发接口,支持热重载、事件系统、NPC配置、物品系统等完整的游戏开发功能。
| 文件名 | 说明 |
|---|---|
| common.ts | 通用类型定义(Vector2、Gender、Job、Attribute、BaseObject等) |
| actor.ts | 角色基类接口,所有游戏对象的父类 |
| playobject.ts | 玩家对象接口,包含物品、货币、行会等功能 |
| hero.ts | 英雄对象接口,继承自Actor |
| monster.ts | 怪物对象接口,继承自Actor |
| npc.ts | NPC对象接口及配置接口(NpcConfig) |
| environment.ts | 地图环境对象接口,提供地图查询、对象获取等功能 |
| guild.ts | 行会对象接口,提供行会管理功能 |
| magic.ts | 魔法对象接口 |
| stditem.ts | 标准物品接口,定义物品模板属性 |
| useritem.ts | 用户物品接口,定义物品实例属性及扩展功能 |
| event.ts | 事件系统接口,定义事件类型、订阅、发布机制 |
| game.ts | 游戏核心库接口,提供公告、怪物管理、脚本管理、FlexWindow等功能 |
| http.ts | HTTP客户端接口,提供同步/异步GET/POST/PUT/DELETE请求 |
按功能分类:
| 名称 | 类型 | 说明 |
|---|---|---|
GameLib |
对象 | 游戏核心库,提供公告、怪物、脚本管理等功能 |
EventSystem |
对象 | 事件系统,提供事件订阅、发布等功能 |
__module__ |
常量 | 当前模块元信息(name、tag) |
MODULE_TAG |
常量 | 模块标签(可选导出) |
subscribe() |
函数 | 订阅事件 |
unsubscribe() |
函数 | 取消订阅事件 |
publish() |
函数 | 发布事件 |
setTimeout() |
函数 | 设置一次性定时器 |
setInterval() |
函数 | 设置周期性定时器 |
clearTimeout() |
函数 | 清除定时器 |
clearInterval() |
函数 | 清除定时器 |
setTimerPriority() |
函数 | 设置定时器优先级 |
getVersion() |
函数 | 获取游戏版本 |
serverLog() |
函数 | 输出日志到服务端窗口 |
registerImageLibrary() |
函数 | 注册素材库 |
Http |
对象 | HTTP客户端,提供GET/POST/PUT/DELETE请求 |
// index.ts - 引擎启动时自动执行
import './playerlogin';
// 输出日志
serverLog('FlexCore 引擎启动完成');
// 发送全服公告
GameLib.sendBroadcastMsg('欢迎来到游戏世界!');
// 监听玩家登录事件
subscribe(EventType.PlayerLogin, (player: PlayObject) => {
serverLog(`玩家 ${player.charName} 登录了`);
// 发送欢迎消息
player.sendMessage('欢迎来到游戏世界!', 255);
});
// 监听玩家升级事件
subscribe(EventType.PlayerLevelUp, (event: PlayerLevelUpEvent) => {
const player = event.player;
serverLog(`玩家 ${player.charName} 升到了 ${player.ability.level} 级`);
});
// 监听物品使用事件(可拦截)
subscribe(EventType.ItemUse, (event: ItemUseEvent) => {
const player = event.player;
const stdItem = event.stdItem;
const itemIndex = event.itemIndex;
serverLog(`玩家 ${player.charName} 使用了物品 ${stdItem.Name}`);
// 返回 false 可以拦截事件(阻止使用)
// if (player.level < stdItem.NeedLevel) {
// player.sendMessage('等级不够,无法使用此物品!');
// return false;
// }
// 返回 true 或不返回值允许事件继续
});
// npc/weaponseller.ts
import { NPC, PlayObject, NpcConfig } from '../api';
// 导出NPC配置
export const NPC_CONFIG: NpcConfig = {
name: '武器商人',
map: '3',
pos: { x: 330, y: 330 },
face: 0,
buy: true,
sell: true,
priceRate: 100,
goods: [
{ name: '木剑', count: 10, refillTime: 60 },
{ name: '铁剑', count: 5, refillTime: 120 }
]
};
// 导出NPC处理函数
export function ExecuteNpc(npc: NPC, player: PlayObject, label: string): void {
switch (label) {
case 'main':
npc.sendMsgToUser(player, '欢迎光临武器店!\\<购买/@buy>\\<出售/@sell>');
break;
case 'buy':
// 打开购买窗口
npc.openShop(player);
break;
case 'sell':
// 检查玩家等级
if (player.ability.level < 10) {
npc.preventDefault(); // 阻止默认行为
npc.sendMsgToUser(player, '等级不够,不能出售物品!\\<返回/@main>');
return;
}
// 不调用 preventDefault,服务端会打开出售窗口
break;
}
}
// 给玩家物品
const success = player.give('木剑', 1);
if (success) {
player.sendMessage('成功获得木剑!');
}
// 获取背包物品列表
const bagItems = player.getBagItems();
serverLog(`背包物品数量: ${bagItems.length}`);
// 遍历背包物品
for (const item of bagItems) {
const stdItem = item.getStdItem();
serverLog(`物品: ${stdItem.Name}, 耐久度: ${item.dura}/${item.duraMax}`);
// 读取扩展属性
const extAttrs = item.getExtAttrs();
if (extAttrs) {
const attrs = JSON.parse(extAttrs);
serverLog(`扩展属性: ${JSON.stringify(attrs)}`);
}
// 设置扩展属性
item.setExtAttr('强化等级', 5);
// 批量设置扩展属性
item.setExtAttrs('{"力量":100,"敏捷":50}');
}
// 货币操作
player.addCurrency(player.CT_GAMEGOLD, 100); // 增加100元宝
const gold = player.getCurrency(player.CT_GOLD); // 获取金币数量
serverLog(`金币: ${gold}, 元宝: ${player.getCurrency(player.CT_GAMEGOLD)}`);
Mermaid 类图:
classDiagram
BaseObject <|-- Actor
Actor <|-- PlayObject
Actor <|-- Hero
Actor <|-- Monster
Actor <|-- NPC
BaseObject <|-- Environment
BaseObject <|-- Guild
BaseObject <|-- Magic
StdItem <-- UserItem
class BaseObject {
<<基类>>
+userId: string
+charName: string
+mapName: string
+currX: number
+currY: number
+ability: Ability
+walk(nDirection): boolean
+turnTo(nDirection): void
+spaceMove(mapName, x, y): boolean
+damage(nDamage): void
+inSafeZone(): boolean
}
class Actor {
<<角色基类>>
继承 BaseObject 所有属性和方法
}
class PlayObject {
+addItemToBag(userItem): boolean
+give(itemName, count, upgrade): boolean
+sendMessage(msg, msgColor, msgType): void
+addCurrency(currencyType, amount): boolean
+getGuild(): Guild | null
+getSlaveList(): Monster[]
}
class Hero {
+followMaster(): boolean
+attackTarget(target): void
+stopAttack(): void
+useSkill(skillId, target): void
}
class Monster {
+searchTarget(): void
+die(): void
+reAlive(): void
+dropItems(): void
+slaveExpLevel: number
+getExtAttr(key): string
+setExtAttr(key, value): boolean
+delExtAttr(key): boolean
+changeName(newName): boolean
}
class NPC {
+priceRate: number
+sayMsg(message): void
+openShop(player): void
+teleport(player, mapName, x, y): void
+preventDefault(): void
}
class Environment {
+MapFileName: string
+Width: number
+Height: number
+canWalk(x, y, flag): boolean
+getMonsters(): BaseObject[]
+getPlayers(): PlayObject[]
}
class Guild {
+GuildName: string
+MemberCount: number
+isMember(memberName): boolean
+addMember(member): boolean
+sendGuildMsg(msg, color): void
}
class Magic {
+btLevel: number
+wMagIdx: number
+MagicInfo: number
}
class StdItem {
+Name: string
+StdMode: number
+DC: number
+MC: number
+AC: number
+MAC: number
+NeedLevel: number
+Price: number
}
class UserItem {
+makeIndex: number
+dura: number
+duraMax: number
+getStdItem(): StdItem
+getBtValue(index): number
+setExtAttr(key, value): void
+setCustomHintText(text): void
}
ASCII 图示:
┌─────────────┐
│ BaseObject │ (基类)
└──────┬──────┘
│
┌────────────────┼────────────────┐
│ │ │
┌────▼────┐ ┌─────▼──────┐ ┌────▼─────┐
│ Actor │ │Environment │ │ Guild │
└────┬────┘ └────────────┘ └──────────┘
│ │
┌─────┼─────┬──────────┼─────┐
│ │ │ │ │
┌───▼──┐ ┌▼───┐ ┌▼────┐ ┌─▼────┐┌▼──────┐
│Play │ │Hero│ │NPC │ │Monst │ │ Magic │
│Object│ │ │ │ │ │ er │ │ │
└──────┘ └────┘ └─────┘ └──────┘└───────┘
独立类型(不参与继承):
┌────────┐ ┌──────────┐
│StdItem │◄──────│ UserItem │
│标准物品│ │ 用户物品 │
└────────┘ └──────────┘
说明: BaseObject 是所有游戏对象的基类,提供了基础的身份识别、位置移动、能力属性、战斗属性等通用接口。
继承 BaseObject 的类型:
Actor - 角色基类(玩家、英雄、怪物、NPC的父类)Environment - 地图环境对象Guild - 行会对象Magic - 魔法对象BaseObject 主要属性分组:
| 分组 | 属性 | 说明 |
|---|---|---|
| 身份识别 | userId, charName, fCharName, gender, job, hair, nameColor, light | 角色身份信息 |
| 位置移动 | mapName, currX, currY, direction, viewRange, homeMap, homeX, homeY | 位置和移动相关 |
| 能力属性 | ability, weaponAbility, addAbility | 基础能力值 |
| 战斗属性 | hitSpeed, walkSpeed | 攻击和移动速度 |
| 服务端限速 | nextHitTime, actionIntervalTime, runIntervalTime, walkIntervalTime等 | 控制操作频率 |
| 客户端加速 | superSpeed, superAttackInterval, superMoveInterval, superSpellInterval | 极速模式控制 |
| 资源属性 | permission, killMonExpRate | 权限和经验倍率 |
| 生存状态 | death, canReAlive, invisible, healthRecover, spellRecover, poisonRecover | 生存相关 |
| 状态效果 | charStatus, charStatusEx, paralysis, magicShield, superMan, hideMode等 | 各种状态标志 |
| 类型 | 说明 | 所属文件 |
|---|---|---|
StdItem |
标准物品(物品模板,定义物品基础属性) | stditem.ts |
UserItem |
用户物品(物品实例,包含耐久度、极品属性、扩展属性等) | useritem.ts |
NpcConfig |
NPC配置接口(定义NPC的名称、位置、功能开关、商品列表等) | npc.ts |
NpcGoods |
商品配置接口(定义NPC商品名称、数量、刷新时间) | npc.ts |
DialogConfig |
对话框配置接口(预留扩展) | npc.ts |
CurrencyType |
货币类型枚举(金币、元宝、游戏点、金刚石、灵符、声望、潜能点) | playobject.ts |
EventType |
事件类型枚举(14种事件类型) | event.ts |
EventModifyResult |
事件参数修改结果(用于拦截和修改事件参数) | event.ts |
RegisterModulesOptions |
脚本目录注册选项(directory、exclude、pattern) | game.ts |
本节定义了 SDK 中使用的基础数据结构、枚举类型、属性结构等通用类型,所有接口文件都依赖这些基础类型。
二维坐标点结构。
interface Vector2 {
x: number; // X坐标
y: number; // Y坐标
}
示例代码:
const pos: Vector2 = { x: 100, y: 200 };
serverLog(`位置: (${pos.x}, ${pos.y})`);
三维坐标点结构。
interface Vector3 {
x: number; // X坐标
y: number; // Y坐标
z: number; // Z坐标(高度)
}
矩形区域结构。
interface Rect {
left: number; // 左边界X坐标
top: number; // 上边界Y坐标
right: number; // 右边界X坐标
bottom: number; // 下边界Y坐标
}
示例代码:
const area: Rect = { left: 100, top: 100, right: 200, bottom: 200 };
位置结构,包含地图名称和坐标。
interface Position {
mapName: string; // 地图名称
x: number; // X坐标
y: number; // Y坐标
}
示例代码:
const playerPos: Position = {
mapName: '盟重省',
x: 330,
y: 330
};
性别枚举。
| 值 | 名称 | 说明 |
|---|---|---|
| 0 | Male | 男性 |
| 1 | Female | 女性 |
示例代码:
const gender = player.gender;
if (gender === Gender.Male) {
serverLog('男性角色');
} else if (gender === Gender.Female) {
serverLog('女性角色');
}
职业枚举。
| 值 | 名称 | 说明 |
|---|---|---|
| 0 | Warrior | 战士 |
| 1 | Mage | 法师 |
| 2 | Taoist | 道士 |
示例代码:
const job = player.job;
switch (job) {
case Job.Warrior:
serverLog('战士职业');
break;
case Job.Mage:
serverLog('法师职业');
break;
case Job.Taoist:
serverLog('道士职业');
break;
}
方向枚举(8个方向)。
| 值 | 名称 | 说明 |
|---|---|---|
| 0 | Up | 上 |
| 1 | UpRight | 右上 |
| 2 | Right | 右 |
| 3 | DownRight | 右下 |
| 4 | Down | 下 |
| 5 | DownLeft | 左下 |
| 6 | Left | 左 |
| 7 | UpLeft | 左上 |
示例代码:
// 向右移动
player.walk(Direction.Right);
// 转向下方
player.turnTo(Direction.Down);
基础属性结构(包含HP、MP、攻击、防御等)。
interface Attribute {
hp: number; // 当前生命值
maxHp: number; // 最大生命值
mp: number; // 当前魔法值
maxMp: number; // 最大魔法值
attack: number; // 物理攻击
defense: number; // 物理防御
magicAttack: number; // 魔法攻击
magicDefense: number;// 魔法防御
speed: number; // 移动速度
}
角色能力结构(包含等级、经验、负重等完整属性)。
interface Ability {
level: number; // 等级
ac: number; // 防御(AC)
mac: number; // 魔法防御(MAC)
dc: number; // 物理攻击(DC)
mc: number; // 魔法攻击(MC)
sc: number; // 神圣攻击(SC)
hp: number; // 当前生命值
mp: number; // 当前魔法值
maxHP: number; // 最大生命值
maxMP: number; // 最大魔法值
exp: number; // 当前经验值
maxExp: number; // 升级所需经验值
weight: number; // 当前负重
maxWeight: number; // 最大负重
wearWeight: number; // 当前装备负重
maxWearWeight: number;// 最大装备负重
handWeight: number; // 当前手持负重
maxHandWeight: number;// 最大手持负重
}
示例代码:
const ability = player.ability;
serverLog(`等级: ${ability.level}, HP: ${ability.hp}/${ability.maxHP}`);
serverLog(`攻击: ${ability.dc}, 魔法: ${ability.mc}`);
serverLog(`负重: ${ability.weight}/${ability.maxWeight}`);
附加能力结构(包含武器强化、幸运、抗毒等扩展属性)。
interface AddAbility {
weaponStrong: number; // 武器强化
holy: number; // 神圣属性
hitPoint: number; // 命中点数
speedPoint: number; // 速度点数
antiPoison: number; // 抗毒
poisonRecover: number; // 中毒恢复
healthRecover: number; // 生命恢复
spellRecover: number; // 魔法恢复
antiMagic: number; // 抗魔法
luck: number; // 幸运
unLuck: number; // 厄运
hitSpeed: number; // 攻击速度
hp: number; // 生命值加成
mp: number; // 魔法值加成
ac: number; // 防御加成
mac: number; // 魔法防御加成
dc: number; // 物理攻击加成
mc: number; // 魔法攻击加成
sc: number; // 神圣攻击加成
}
物品的基础接口,定义了物品的通用属性。
interface Item {
id: number; // 物品ID
name: string; // 物品名称
type: number; // 物品类型
level: number; // 物品等级
durability: number; // 当前耐久度
maxDurability: number; // 最大耐久度
attributes: Record<string, any>; // 物品属性字典
}
事件回调函数类型。回调函数可以返回 void(允许事件继续)、boolean(返回 false 拦截事件)或 EventModifyResult(修改事件参数)。
type EventCallback = (...args: any[]) => boolean | EventModifyResult | void;
事件订阅对象。
interface EventSubscription {
eventName: string; // 事件名称
callback: EventCallback; // 回调函数
unsubscribe: () => void; // 取消订阅函数
}
解析标签字符串,提取标签名称和参数。
函数签名:
function parseLabel(label: string): ParsedLabel
参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| label | string | 是 | 标签字符串,如 "main" 或 "buy(item,100)" |
返回值: ParsedLabel 对象,包含标签名称和参数数组。
ParsedLabel 接口:
interface ParsedLabel {
labelName: string; // 标签名称
params: string[]; // 参数数组
}
示例代码:
// 解析简单标签
const result1 = parseLabel('main');
serverLog(`标签: ${result1.labelName}, 参数: ${result1.params}`);
// 输出: 标签: main, 参数:
// 解析带参数的标签
const result2 = parseLabel('buy(木剑,10)');
serverLog(`标签: ${result2.labelName}, 参数: ${result2.params.join(', ')}`);
// 输出: 标签: buy, 参数: 木剑, 10
// 在NPC中使用
export function ExecuteNpc(npc: NPC, player: PlayObject, label: string): void {
const parsed = parseLabel(label);
switch (parsed.labelName) {
case 'buy':
const itemName = parsed.params[0];
const count = parseInt(parsed.params[1]) || 1;
// 处理购买逻辑
break;
}
}
BaseObject 是所有游戏对象的基类,提供了基础的身份识别、位置移动、能力属性、战斗属性等通用接口。
造成伤害。
所属接口: BaseObject
返回类型: void
功能说明: 对对象造成指定数值的伤害。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nDamage | number | 是 | 伤害数值 |
示例代码:
player.damage(100); // 对玩家造成100点伤害
向指定方向移动。
所属接口: BaseObject
返回类型: boolean
功能说明: 向指定方向移动一格。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nDirection | number | 是 | 方向(0-7,参考 Direction 枚举) |
返回值: 移动成功返回 true,失败返回 false。
示例代码:
const success = player.walk(Direction.Right);
if (success) {
serverLog('移动成功');
}
转向指定方向。
所属接口: BaseObject
返回类型: void
功能说明: 将角色朝向指定方向(不移动位置)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nDirection | number | 是 | 方向(0-7,参考 Direction 枚举) |
示例代码:
player.turnTo(Direction.Down); // 转向下方
检查是否在安全区。
所属接口: BaseObject
返回类型: boolean
功能说明: 判断当前对象是否在安全区内。
返回值: 在安全区返回 true,否则返回 false。
示例代码:
if (player.inSafeZone()) {
player.sendMessage('你在安全区内');
} else {
player.sendMessage('你在危险区域');
}
传送指定位置。
所属接口: BaseObject
返回类型: boolean
功能说明: 将对象传送到指定地图的指定坐标。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 目标地图名称 |
| x | number | 是 | 目标X坐标 |
| y | number | 是 | 目标Y坐标 |
返回值: 传送成功返回 true,失败返回 false。
示例代码:
const success = player.spaceMove('盟重省', 330, 330);
if (success) {
player.sendMessage('传送成功');
}
在当前地图随机移动。
所属接口: BaseObject
返回类型: boolean
功能说明: 在当前地图随机位置移动一格。
返回值: 移动成功返回 true,失败返回 false。
在指定范围内随机传送。
所属接口: BaseObject
返回类型: boolean
功能说明: 在当前位置的指定范围内随机传送。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| range | number | 是 | 随机传送范围(格子数) |
返回值: 传送成功返回 true,失败返回 false。
示例代码:
// 在当前坐标周围5格范围内随机传送
player.randomSpaceMoveInRange(5);
受到伤害。
所属接口: BaseObject
返回类型: boolean
功能说明: 处理受到伤害的逻辑,包括扣血、死亡判定等。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| attacker | BaseObject | 是 | 攻击者对象 |
| damage | number | 是 | 伤害数值 |
| magIdx | number | 否 | 魔法索引(可选) |
返回值: 处理成功返回 true,失败返回 false。
重新计算能力值。
所属接口: BaseObject
返回类型: boolean
功能说明: 重新计算对象的所有能力值(通常在属性修改后调用)。
返回值: 计算成功返回 true,失败返回 false。
示例代码:
// 修改怪物经验等级后,刷新能力值
monster.slaveExpLevel = 10;
monster.recalcAbilitys();
BaseObject 的属性按功能分组如下:
| 属性名 | 类型 | 说明 |
|---|---|---|
| userId | string | 用户ID |
| charName | string | 角色名称 |
| fCharName | string | 角色全名 |
| gender | number | 性别(参考 Gender 枚举) |
| job | number | 职业(参考 Job 枚举) |
| hair | number | 发型 |
| hairEx | number | 发型扩展 |
| nameColor | number | 名称颜色 |
| light | number | 光环 |
| 属性名 | 类型 | 说明 |
|---|---|---|
| mapName | string | 当前地图名称 |
| currX | number | 当前X坐标 |
| currY | number | 当前Y坐标 |
| direction | number | 当前朝向(0-7) |
| viewRange | number | 视野范围 |
| homeMap | string | 家园地图 |
| homeX | number | 家园X坐标 |
| homeY | number | 家园Y坐标 |
| 属性名 | 类型 | 说明 |
|---|---|---|
| ability | Ability | 基础能力值 |
| weaponAbility | Ability | 武器能力值 |
| addAbility | AddAbility | 附加能力值 |
| 属性名 | 类型 | 说明 |
|---|---|---|
| hitSpeed | number | 攻击速度 |
| walkSpeed | number | 移动速度 |
以下属性控制 M2Engine 服务端的处理频率,仅在 boSpeedHackCheck=False 时生效。用于限制玩家的最大操作频率,防止超速。值越小限制越严格。
| 属性名 | 类型 | 说明 |
|---|---|---|
| nextHitTime | number | 下次攻击时间 |
| actionIntervalTime | number | 动作间隔时间 |
| runIntervalTime | number | 奔跑间隔时间 |
| walkIntervalTime | number | 行走间隔时间 |
| runHitIntervalTime | number | 奔跑攻击间隔时间 |
| walkHitIntervalTime | number | 行走攻击间隔时间 |
| runLongHitIntervalTime | number | 奔跑长击间隔时间 |
| runMagicIntervalTime | number | 奔跑施法间隔时间 |
| speedPoint | number | 速度点数 |
以下属性通过 SuperSpeed 极速模式直接控制客户端的请求发送频率。开启后客户端将按设定的间隔(毫秒)发送攻击/移动/施法请求,不受客户端默认动画限制。每个玩家可以独立设置不同的值,设置后立即下发到客户端生效。
| 属性名 | 类型 | 说明 |
|---|---|---|
| superSpeed | boolean | 开启/关闭极速模式(true/false) |
| superAttackInterval | number | 攻击间隔,单位毫秒,范围 10-60000,值越小攻击越快 |
| superMoveInterval | number | 移动间隔,单位毫秒,范围 10-60000,值越小移动越快 |
| superSpellInterval | number | 施法间隔,单位毫秒,范围 10-60000,值越小施法越快 |
示例代码:
// 开启极速模式
player.superSpeed = true;
player.superAttackInterval = 500; // 每500毫秒攻击一次
player.superMoveInterval = 300; // 每300毫秒移动一次
player.superSpellInterval = 800; // 每800毫秒施法一次
// 关闭极速模式
player.superSpeed = false;
| 属性名 | 类型 | 说明 |
|---|---|---|
| hitPlus | number | 命中加成 |
| luck | number | 幸运值 |
| defenceRate | number | 防御率 |
| magDefenceRate | number | 魔法防御率 |
| hitPoint | number | 命中点数 |
| perHealth | number | 生命恢复百分比 |
| perHealing | number | 治疗百分比 |
| perSpell | number | 魔法恢复百分比 |
| 属性名 | 类型 | 说明 |
|---|---|---|
| permission | number | 权限等级 |
| killMonExpRate | number | 杀怪经验倍率 |
| 属性名 | 类型 | 说明 |
|---|---|---|
| death | boolean | 是否死亡 |
| canReAlive | boolean | 是否可以复活 |
| invisible | boolean | 是否隐身 |
| healthRecover | number | 生命恢复值 |
| spellRecover | number | 魔法恢复值 |
| poisonRecover | number | 中毒恢复值 |
| 属性名 | 类型 | 说明 |
|---|---|---|
| charStatus | number | 角色状态 |
| charStatusEx | number | 角色状态扩展 |
| paralysis | boolean | 是否麻痹 |
| paralysis2 | boolean | 是否麻痹2 |
| mParalysis | boolean | 是否魔法麻痹 |
| magicShield | boolean | 是否魔法盾 |
| magicShield2 | boolean | 是否魔法盾2 |
| superMan | boolean | 是否超级模式 |
| adminMode | boolean | 是否管理员模式 |
| obMode | boolean | 是否观察者模式 |
| hideMode | boolean | 是否隐身模式 |
| fixedHideMode | boolean | 是否固定隐身模式 |
| stoneMode | boolean | 是否石化模式 |
| revival | boolean | 是否复活状态 |
| unRevival | boolean | 是否不可复活 |
| newHuman | boolean | 是否新人 |
示例代码:
// 读取玩家属性
serverLog(`玩家名称: ${player.charName}`);
serverLog(`等级: ${player.ability.level}`);
serverLog(`位置: ${player.mapName} (${player.currX}, ${player.currY})`);
serverLog(`是否死亡: ${player.death}`);
serverLog(`是否在安全区: ${player.inSafeZone()}`);
// 修改玩家属性
player.invisible = true; // 隐身
player.magicShield = true; // 开启魔法盾
player.superMan = true; // 开启超级模式
本节介绍游戏中各种对象(玩家、英雄、怪物、NPC、地图环境、行会、魔法)的接口定义。这些对象都继承自 BaseObject 基类,拥有通用的身份识别、位置移动、能力属性等功能。
Actor 是所有角色类对象(玩家、英雄、怪物、NPC)的基类,继承自 BaseObject。
继承关系:
Actor 继承自 BaseObjectPlayObject、Hero、Monster、NPC 继承自 Actor说明: Actor 接口目前只继承了 BaseObject 的所有属性和方法,未添加额外的特有属性或方法。
示例代码:
// Actor 作为函数参数时,可以传入任何继承自 Actor 的对象
function processActor(actor: Actor) {
serverLog(`角色名称: ${actor.charName}`);
serverLog(`等级: ${actor.ability.level}`);
serverLog(`位置: ${actor.mapName} (${actor.currX}, ${actor.currY})`);
// 调用 BaseObject 的方法
actor.walk(Direction.Right);
actor.turnTo(Direction.Down);
}
// 可以传入 PlayObject、Hero、Monster、NPC
processActor(player);
processActor(hero);
processActor(monster);
processActor(npc);
PlayObject 代表游戏中的玩家角色,继承自 Actor,提供了物品操作、货币管理、消息发送、行会管理等功能。
新人标记,表示是否为新玩家。
| 属性名 | 类型 | 说明 |
|---|---|---|
| newHuman | boolean | 是否为新人 |
示例代码:
if (player.newHuman) {
player.sendMessage('欢迎新玩家!');
// 给予新手奖励
player.give('新手礼包', 1);
}
向背包添加物品。
所属接口: PlayObject
返回类型: boolean
功能说明: 将指定的用户物品对象添加到玩家背包。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| userItem | UserItem | 是 | 用户物品对象 |
返回值: 添加成功返回 true,失败返回 false。
示例代码:
// 创建物品对象(需要通过其他方式获取)
// const item = ...;
// const success = player.addItemToBag(item);
给玩家物品(简化接口)。
所属接口: PlayObject
返回类型: boolean
功能说明: 根据物品名称给玩家添加物品,是最常用的给物品方法。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| itemName | string | 是 | 物品名称 |
| count | number | 否 | 物品数量(默认1) |
| upgrade | boolean | 否 | 是否升级(默认false) |
返回值: 给予成功返回 true,失败返回 false。
示例代码:
// 给予1把木剑
if (player.give('木剑', 1)) {
player.sendMessage('获得了木剑!');
}
// 给予10瓶生命药水
if (player.give('生命药水', 10)) {
player.sendMessage('获得了10瓶生命药水!');
}
// 给予升级后的物品
if (player.give('强化铁剑', 1, true)) {
player.sendMessage('获得了强化铁剑!');
}
给玩家物品并返回物品对象。
所属接口: PlayObject
返回类型: UserItem
功能说明: 根据物品名称给玩家添加物品,并返回物品对象以便进一步操作。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| itemName | string | 是 | 物品名称 |
| upgrade | boolean | 否 | 是否升级(默认false) |
返回值: 返回用户物品对象,失败返回 null。
示例代码:
// 给予物品并获取对象
const item = player.giveItem('木剑');
if (item) {
const stdItem = item.getStdItem();
serverLog(`物品名称: ${stdItem.Name}, 耐久度: ${item.dura}/${item.duraMax}`);
// 设置扩展属性
item.setExtAttr('强化等级', 5);
}
通过物品索引给玩家物品并返回物品对象。
所属接口: PlayObject
返回类型: UserItem
功能说明: 根据物品索引给玩家添加物品,并返回物品对象。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| itemIndex | number | 是 | 物品索引 |
| upgrade | boolean | 否 | 是否升级(默认false) |
返回值: 返回用户物品对象,失败返回 null。
示例代码:
// 通过索引给予物品
const item = player.giveItemByIndex(100);
if (item) {
serverLog(`物品索引: ${item.wIndex}`);
}
从玩家背包拿走指定数量的物品。
所属接口: PlayObject
返回类型: number
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| itemName | string | 是 | 物品名称 |
| count | number | 是 | 数量 |
返回值: 实际拿走的数量。
示例代码:
const taken = player.takeItem('金币', 100);
serverLog(`拿走了 ${taken} 个金币`);
通过 MakeIndex 删除指定物品。
所属接口: PlayObject
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| makeIndex | number | 是 | 物品唯一标识 |
示例代码:
const items = player.getBagItems();
if (items.length > 0) {
player.removeItem(items[0].makeIndex);
}
获取背包物品列表。
所属接口: PlayObject
返回类型: UserItem[]
功能说明: 获取玩家背包中所有物品的列表。
返回值: 用户物品对象数组。
示例代码:
// 获取背包物品列表
const bagItems = player.getBagItems();
serverLog(`背包物品数量: ${bagItems.length}`);
// 遍历背包物品
for (const item of bagItems) {
const stdItem = item.getStdItem();
serverLog(`物品: ${stdItem.Name}, 耐久度: ${item.dura}/${item.duraMax}`);
}
// 查找指定物品
const findItem = (itemName: string): UserItem | null => {
const bagItems = player.getBagItems();
for (const item of bagItems) {
const stdItem = item.getStdItem();
if (stdItem.Name === itemName) {
return item;
}
}
return null;
};
const sword = findItem('木剑');
if (sword) {
serverLog('找到了木剑');
}
获取最大背包格子数。
所属接口: PlayObject
返回类型: number
功能说明: 获取玩家背包的最大格子数。
返回值: 最大背包格子数(普通玩家46,英雄根据等级10-40)。
示例代码:
const maxBag = player.getMaxBagItem();
serverLog(`背包最大格子数: ${maxBag}`);
const currentBag = player.getBagItems().length;
serverLog(`当前使用: ${currentBag}/${maxBag}`);
发送消息给玩家。
所属接口: PlayObject
返回类型: void
功能说明: 向玩家发送聊天消息或系统消息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| msg | string | 是 | 消息内容 |
| msgColor | number | 否 | 消息颜色(默认0) |
| msgType | number | 否 | 消息类型(默认0) |
示例代码:
// 发送普通消息
player.sendMessage('欢迎来到游戏!');
// 发送红色消息
player.sendMessage('重要通知!', 255);
// 发送系统消息
player.sendMessage('系统消息', 255, 1);
弹出确认提示框给玩家。
所属接口: PlayObject
返回类型: void
功能说明: 在客户端显示居中的确认对话框,带"确定"按钮。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| msg | string | 是 | 提示消息内容 |
示例代码:
// 弹出提示框
player.showMessageBox('确定要删除此物品吗?');
在客户端内嵌浏览器中打开指定URL。
所属接口: PlayObject
返回类型: void
功能说明: 在游戏客户端中打开内嵌浏览器并访问指定网页。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| url | string | 是 | 要打开的网页地址(支持 http:// 和 https://) |
| width | number | 否 | 浏览器窗口宽度(像素,0或不传则全屏) |
| height | number | 否 | 浏览器窗口高度(像素,0或不传则全屏) |
示例代码:
// 全屏打开网页
player.openUrl('https://www.example.com');
// 打开指定大小的窗口
player.openUrl('https://www.example.com', 800, 600);
PlayObject 提供了完整的货币系统,支持多种货币类型:金币、元宝、游戏点、金刚石、灵符、声望、潜能点。
| 常量名 | 值 | 说明 |
|---|---|---|
CT_GOLD |
1 | 金币 |
CT_GAMEGOLD |
2 | 元宝 |
CT_GAMEPOINT |
3 | 游戏点 |
CT_GAMEDIAMOND |
4 | 金刚石 |
CT_GAMEGIRD |
5 | 灵符 |
CT_CREDITPOINT |
6 | 声望 |
CT_BONUSPOINT |
7 | 潜能点 |
注意:
CurrencyType枚举还包含None = 0(无类型),实际使用中应使用 1-7 的值。
增加货币。
所属接口: PlayObject
返回类型: boolean
功能说明: 增加玩家指定类型的货币数量。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| currencyType | number | 是 | 货币类型(使用 player.CT_GOLD 等常量) |
| amount | number | 是 | 增加数量 |
返回值: 增加成功返回 true,失败返回 false。
示例代码:
// 增加100金币
player.addCurrency(player.CT_GOLD, 100);
// 增加50元宝
player.addCurrency(player.CT_GAMEGOLD, 50);
// 增加10金刚石
player.addCurrency(player.CT_GAMEDIAMOND, 10);
减少货币。
所属接口: PlayObject
返回类型: boolean
功能说明: 减少玩家指定类型的货币数量。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| currencyType | number | 是 | 货币类型(使用 player.CT_GOLD 等常量) |
| amount | number | 是 | 减少数量 |
返回值: 减少成功返回 true,失败返回 false。
示例代码:
// 扣除100金币
if (player.decCurrency(player.CT_GOLD, 100)) {
player.sendMessage('扣除100金币成功');
} else {
player.sendMessage('金币不足!');
}
设置货币值。
所属接口: PlayObject
返回类型: boolean
功能说明: 直接设置玩家指定类型货币的数量。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| currencyType | number | 是 | 货币类型(使用 player.CT_GOLD 等常量) |
| value | number | 是 | 设置的值 |
返回值: 设置成功返回 true,失败返回 false。
示例代码:
// 设置金币数量为1000
player.setCurrency(player.CT_GOLD, 1000);
获取货币值。
所属接口: PlayObject
返回类型: number
功能说明: 获取玩家指定类型货币的数量。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| currencyType | number | 是 | 货币类型(使用 player.CT_GOLD 等常量) |
返回值: 货币数量。
示例代码:
// 获取金币数量
const gold = player.getCurrency(player.CT_GOLD);
serverLog(`金币: ${gold}`);
// 获取元宝数量
const gameGold = player.getCurrency(player.CT_GAMEGOLD);
serverLog(`元宝: ${gameGold}`);
// 显示所有货币
serverLog(`金币: ${player.getCurrency(player.CT_GOLD)}`);
serverLog(`元宝: ${player.getCurrency(player.CT_GAMEGOLD)}`);
serverLog(`游戏点: ${player.getCurrency(player.CT_GAMEPOINT)}`);
serverLog(`金刚石: ${player.getCurrency(player.CT_GAMEDIAMOND)}`);
serverLog(`灵符: ${player.getCurrency(player.CT_GAMEGIRD)}`);
serverLog(`声望: ${player.getCurrency(player.CT_CREDITPOINT)}`);
serverLog(`潜能点: ${player.getCurrency(player.CT_BONUSPOINT)}`);
检查货币是否足够。
所属接口: PlayObject
返回类型: boolean
功能说明: 检查玩家是否有足够的指定类型货币。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| currencyType | number | 是 | 货币类型(使用 player.CT_GOLD 等常量) |
| amount | number | 是 | 需要的数量 |
返回值: 货币足够返回 true,否则返回 false。
示例代码:
// 检查金币是否足够
if (player.checkCurrency(player.CT_GOLD, 1000)) {
player.sendMessage('金币足够,可以购买');
// 执行购买逻辑
player.decCurrency(player.CT_GOLD, 1000);
} else {
player.sendMessage('金币不足!');
}
增加大数值货币(BigInt,支持无限精度)。
所属接口: PlayObject
返回类型: string(操作后的余额)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| currencyType | number | 是 | 货币类型 |
| amount | string | 是 | 增加数量(字符串形式的大数值) |
减少大数值货币。
所属接口: PlayObject
返回类型: string
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| currencyType | number | 是 | 货币类型 |
| amount | string | 是 | 减少数量 |
获取大数值货币余额。
所属接口: PlayObject
返回类型: string
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| currencyType | number | 是 | 货币类型 |
检查大数值货币是否足够。
所属接口: PlayObject
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| currencyType | number | 是 | 货币类型 |
| amount | string | 是 | 需要的数量 |
判断是否是人类。
所属接口: PlayObject
返回类型: boolean
功能说明: 判断当前对象是否为人类玩家。
返回值: 是人类返回 true,否则返回 false。
示例代码:
if (player.isHuman()) {
serverLog('这是一个人类玩家');
}
判断是否是英雄。
所属接口: PlayObject
返回类型: boolean
功能说明: 判断当前对象是否为英雄。
返回值: 是英雄返回 true,否则返回 false。
示例代码:
if (player.isHero()) {
serverLog('这是一个英雄');
}
判断是否是怪物。
所属接口: PlayObject
返回类型: boolean
功能说明: 判断当前对象是否为怪物。
返回值: 是怪物返回 true,否则返回 false。
示例代码:
if (player.isMonster()) {
serverLog('这是一个怪物');
}
获取玩家当前存活的下属列表。
所属接口: PlayObject
返回类型: Monster[]
功能说明: 获取玩家当前所有存活的下属(召唤的怪物、宠物等)。
返回值: 怪物对象数组。
示例代码:
// 获取下属列表
const slaves = player.getSlaveList();
serverLog(`下属数量: ${slaves.length}`);
// 遍历下属
for (const slave of slaves) {
serverLog(`下属: ${slave.charName}, 等级: ${slave.slaveExpLevel}`);
}
// 给所有下属回城
for (const slave of player.getSlaveList()) {
slave.spaceMove(player.homeMap, player.homeX, player.homeY);
}
获取玩家所属行会对象。
所属接口: PlayObject
返回类型: Guild | null
功能说明: 获取玩家所属的行会对象。
返回值: 行会对象,未加入行会时返回 null。
示例代码:
// 获取行会对象
const guild = player.getGuild();
if (guild) {
serverLog(`行会名称: ${guild.GuildName}`);
serverLog(`成员数量: ${guild.MemberCount}`);
// 发送行会消息
guild.sendGuildMsg('欢迎新成员!');
} else {
serverLog('玩家未加入行会');
}
判断玩家是否是行会会长。
所属接口: PlayObject
返回类型: boolean
功能说明: 判断玩家是否是其所属行会的会长。
返回值: 是会长返回 true,否则返回 false。
示例代码:
if (player.isGuildMaster()) {
player.sendMessage('你是行会会长');
} else {
player.sendMessage('你不是行会会长');
}
判断玩家是否是沙巴克城堡成员。
所属接口: PlayObject
返回类型: boolean
功能说明: 判断玩家是否属于拥有沙巴克城堡的行会。
返回值: 是沙巴克成员返回 true,否则返回 false。
示例代码:
if (player.isCastleMember()) {
player.sendMessage('你是沙巴克成员');
}
判断玩家是否是沙巴克城主。
所属接口: PlayObject
返回类型: boolean
功能说明: 判断玩家是否是沙巴克城主(行会会长且属于拥有沙巴克的行会)。
返回值: 是沙巴克城主返回 true,否则返回 false。
示例代码:
if (player.isCastleMaster()) {
player.sendMessage('你是沙巴克城主');
// 给予城主专属奖励
player.give('城主令', 1);
}
| 属性名 | 类型 | 说明 |
|---|---|---|
| screenWidth | number | 客户端屏幕宽度(像素) |
| screenHeight | number | 客户端屏幕高度(像素) |
serverLog(`玩家分辨率: ${player.screenWidth}x${player.screenHeight}`);
获取指定装备槽位的物品。
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| slot | number | 装备位置:0=衣服, 1=武器, 2=勋章, 3=项链, 4=头盔, 5=左手镯, 6=右手镯, 7=左戒指, 8=右戒指, 9=毒符, 10=腰带, 11=鞋子, 12=宝石, 13=面纱/斗笠, 14=军鼓, 15=马牌, 16=时装 |
返回: UserItem | null — 槽位为空时返回 null
检查指定装备槽位的装备是否可以脱下(检查摆摊、锁定、背包空间等)。
将背包中的物品穿戴到指定槽位。如果目标槽位已有装备,会自动脱下旧装备。
const weapon = player.getEquipItem(1);
if (weapon) {
serverLog(`当前武器: ${weapon.name}`);
}
脱下指定槽位的装备放入背包。
从背包中搜索指定名称的物品并自动穿戴到指定槽位。
player.autoEquipItem('裁决之杖', 1);
| 属性名 | 类型 | 说明 |
|---|---|---|
| autoPlay | boolean | 自动挂机开关(TS侧控制) |
| autoPickupEnabled | boolean | 服务端自动拾取开关 |
| autoPickupRange | number | 自动拾取范围(0-12) |
| autoPickupType | number | 自动拾取类型(0=全部, 1=仅怪物掉落) |
设置自动拾取物品过滤列表。
player.autoPlay = true;
player.autoPickupEnabled = true;
player.autoPickupRange = 12;
player.setAutoPickupItems(['金创药(中)量', '魔法药(中)量']);
按名称使用背包中的物品(药品、卷轴等)。
if (player.useItemByName('强效金创药')) {
serverLog('使用金创药成功');
}
获取已学技能列表,返回 Magic[]。
学习技能,支持按技能ID(number)或技能名称(string)。
const magics = player.getMagicList();
for (const m of magics) {
serverLog(`技能: idx=${m.wMagIdx} level=${m.btLevel}`);
}
player.learnSkill('基础剑术');
player.learnSkill(10);
施放技能。
player.useSkill(1);
player.useSkill(2, monster.currX, monster.currY, monster);
删除技能。
所属接口: PlayObject
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| skillIdOrName | number | string | 是 | 技能ID或名称 |
设置技能等级。
所属接口: PlayObject
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| skillIdOrName | number | string | 是 | 技能ID或名称 |
| level | number | 是 | 技能等级 |
删除所有技能。
所属接口: PlayObject
返回类型: boolean
直接增加经验(不触发事件,用于经验重新分配)。
所属接口: PlayObject
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| amount | number | 是 | 经验值数量 |
示例代码:
player.gainExp(10000);
查找范围内最近的怪物。
const mon = player.findNearestMonster(10);
if (mon) {
serverLog(`最近怪物: ${mon.charName} 距离=${Math.abs(mon.currX - player.currX) + Math.abs(mon.currY - player.currY)}`);
}
拾取指定坐标的物品。
弹出确认提示框(客户端MessageBox),带"确定"按钮。
player.showMessageBox('系统维护通知:服务器将在10分钟后重启');
// NPC中使用 PlayObject 的综合示例
export function ExecuteNpc(npc: NPC, player: PlayObject, label: string): void {
switch (label) {
case 'main':
const guild = player.getGuild();
let guildInfo = '';
if (guild) {
guildInfo = `行会: ${guild.GuildName}`;
} else {
guildInfo = '未加入行会';
}
npc.sendMsgToUser(player,
`欢迎,${player.charName}!\n` +
`等级: ${player.ability.level}\n` +
`金币: ${player.getCurrency(player.CT_GOLD)}\n` +
`${guildInfo}\n\n` +
`\\<领取新手礼包/@gift>\n` +
`\\<查看背包/@bag>\n` +
`\\<行会功能/@guild>`
);
break;
case 'gift':
// 给予新手礼包
if (player.give('新手礼包', 1)) {
player.sendMessage('获得了新手礼包!');
}
break;
case 'bag':
// 显示背包物品
const bagItems = player.getBagItems();
let bagText = `背包物品 (${bagItems.length}/${player.getMaxBagItem()}):\n`;
for (const item of bagItems) {
const stdItem = item.getStdItem();
bagText += `${stdItem.Name} x1\n`;
}
npc.sendMsgToUser(player, bagText + '\n\\<返回/@main>');
break;
case 'guild':
// 行会功能
const playerGuild = player.getGuild();
if (!playerGuild) {
npc.sendMsgToUser(player, '你还没有加入行会!\n\\<返回/@main>');
return;
}
npc.sendMsgToUser(player,
`行会名称: ${playerGuild.GuildName}\n` +
`成员数量: ${playerGuild.MemberCount}\n` +
`行会点数: ${playerGuild.ContestPoint}\n\n` +
(player.isGuildMaster() ? '你是行会会长\n' : '你是行会成员\n') +
`\\<返回/@main>`
);
break;
}
}
Hero 代表玩家召唤的英雄角色,继承自 Actor,提供了跟随、攻击、使用技能等英雄特有功能。
英雄跟随主人。
所属接口: Hero
返回类型: boolean
功能说明: 英雄跟随玩家移动。
返回值: 跟随成功返回 true,失败返回 false。
示例代码:
// 让英雄跟随
if (hero.followMaster()) {
serverLog('英雄开始跟随');
}
英雄攻击目标。
所属接口: Hero
返回类型: void
功能说明: 英雄攻击指定的目标对象。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| target | Actor | 是 | 攻击目标(玩家、怪物、NPC等) |
示例代码:
// 让英雄攻击怪物
const monster = ...; // 获取怪物对象
hero.attackTarget(monster);
英雄停止战斗。
所属接口: Hero
返回类型: void
功能说明: 英雄停止当前攻击。
示例代码:
// 停止攻击
hero.stopAttack();
英雄使用技能。
所属接口: Hero
返回类型: void
功能说明: 英雄使用指定技能。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| skillId | number | 是 | 技能ID |
| target | Actor | 否 | 目标对象(可选) |
示例代码:
// 使用技能(无目标)
hero.useSkill(1); // 技能ID 1
// 使用技能(指定目标)
const monster = ...; // 获取怪物对象
hero.useSkill(2, monster); // 对怪物使用技能ID 2
Monster 代表游戏中的怪物,继承自 Actor,提供了搜索目标、死亡、复活、掉落物品等功能。
搜索目标。
所属接口: Monster
返回类型: void
功能说明: 怪物搜索附近的攻击目标(通常是玩家)。
示例代码:
// 让怪物主动搜索目标
monster.searchTarget();
搜索英雄目标。
所属接口: Monster
返回类型: void
功能说明: 怪物搜索附近的英雄目标。
示例代码:
// 让怪物搜索英雄目标
monster.searchTargetHero();
怪物死亡。
所属接口: Monster
返回类型: void
功能说明: 触发怪物死亡逻辑,包括掉落物品、清理等。
示例代码:
// 让怪物死亡
monster.die();
怪物消失。
所属接口: Monster
返回类型: void
功能说明: 怪物从地图上消失。
示例代码:
// 让怪物消失
monster.disappear();
怪物复活。
所属接口: Monster
返回类型: void
功能说明: 怪物复活到初始位置。
示例代码:
// 让怪物复活
monster.reAlive();
怪物掉落物品。
所属接口: Monster
返回类型: void
功能说明: 怪物掉落物品到地面。
示例代码:
// 让怪物掉落物品
monster.dropItems();
怪物散落物品。
所属接口: Monster
返回类型: void
功能说明: 怪物将物品散落到周围。
示例代码:
// 让怪物散落物品
monster.scatterItems();
下属经验等级(0-15),可读写。
所属接口: Monster
类型: number
功能说明: 设置或读取怪物的经验等级,修改后需调用 recalcAbilitys() 刷新能力值。
示例代码:
// 设置经验等级为10
monster.slaveExpLevel = 10;
// 刷新能力值
monster.recalcAbilitys();
// 读取经验等级
const level = monster.slaveExpLevel;
serverLog(`经验等级: ${level}`);
刷新名称颜色。
所属接口: BaseObject(所有对象类型可用)
返回类型: boolean
功能说明: 将当前 nameColor 属性值刷新到客户端显示。需先设置 nameColor 属性,再调用此方法。
返回值: 刷新成功返回 true,失败返回 false。
示例代码:
// 设置怪物名字颜色并刷新显示
monster.nameColor = 249;
monster.refNameColor();
// 修改经验等级后刷新名称颜色
monster.slaveExpLevel = 10;
monster.recalcAbilitys();
monster.refNameColor();
刷新名称显示。
所属接口: BaseObject(所有对象类型可用)
返回类型: boolean
功能说明: 将当前名称刷新到客户端显示。改名或修改颜色后调用此方法更新客户端显示。
返回值: 刷新成功返回 true,失败返回 false。
示例代码:
// 改名后刷新显示
monster.changeName('[BOSS]' + monster.fCharName);
monster.refShowName();
读取怪物自定义属性。
所属接口: Monster
返回类型: string
功能说明: 读取指定键名的自定义属性值,属性仅存在于内存中,不持久化。
参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | string | 是 | 属性键名 |
返回值: 属性值字符串,不存在时返回空字符串 ""。
示例代码:
const tag = monster.getExtAttr('tag');
if (tag === '') {
serverLog('属性不存在');
} else {
serverLog('属性值: ' + tag);
}
设置怪物自定义属性。
所属接口: Monster
返回类型: boolean
功能说明: 设置指定键名的自定义属性值,属性仅存在于内存中,不持久化。
参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | string | 是 | 属性键名 |
| value | string | 是 | 属性值 |
返回值: 设置成功返回 true,失败返回 false。
示例代码:
monster.setExtAttr('tag', 'BOSS');
monster.setExtAttr('attackCount', '0');
const tag = monster.getExtAttr('tag');
serverLog('tag=' + tag);
删除怪物自定义属性。
所属接口: Monster
返回类型: boolean
功能说明: 删除指定键名的自定义属性。
参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | string | 是 | 属性键名 |
返回值: 删除成功返回 true,失败返回 false。
示例代码:
monster.setExtAttr('temp', 'test');
serverLog(monster.getExtAttr('temp'));
monster.delExtAttr('temp');
serverLog(monster.getExtAttr('temp'));
修改怪物显示名称。
所属接口: Monster
返回类型: boolean
功能说明: 动态修改怪物的显示名称,仅修改内存中的名称,不持久化。改名后自动刷新客户端显示。
参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| newName | string | 是 | 新的怪物名称 |
返回值: 改名成功返回 true,失败返回 false。
示例代码:
const originalName = monster.fCharName;
monster.nameColor = 249;
monster.changeName('[BOSS]' + originalName);
serverLog('改名: ' + originalName + ' -> ' + monster.charName);
将怪物变为幽灵状态。
所属接口: Monster
返回类型: boolean
功能说明: 将怪物变为幽灵状态(从游戏中移除/消失)。
返回值: 执行成功返回 true,失败返回 false。
示例代码:
// 将怪物变为幽灵
if (monster.makeGhost()) {
serverLog('怪物已变为幽灵');
}
NPC 代表游戏中的非玩家角色,继承自 Actor,提供了对话框、商店、传送、任务等功能。
NPC价格比率(默认100表示原价,可运行时修改)。
所属接口: NPC
类型: number
功能说明: NPC的商品价格比率,100表示原价,90表示9折,120表示加价20%。
示例代码:
// 设置NPC价格为8折
npc.priceRate = 80;
// 恢复原价
npc.priceRate = 100;
城堡成员价格折扣率(只读)。
所属接口: NPC
类型: number
功能说明: 全局配置,默认80表示8折,城堡成员享受折扣。
示例代码:
serverLog(`城堡成员折扣率: ${npc.castleMemberPriceRate}%`);
发送对话。
所属接口: NPC
返回类型: void
功能说明: NPC向周围玩家发送对话消息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| message | string | 是 | 对话内容 |
示例代码:
// NPC发送对话
npc.sayMsg('欢迎光临!');
打开商店。
所属接口: NPC
返回类型: void
功能说明: 为指定玩家打开商店界面。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| player | PlayObject | 是 | 玩家对象 |
示例代码:
export function ExecuteNpc(npc: NPC, player: PlayObject, label: string): void {
switch (label) {
case 'buy':
npc.openShop(player); // 打开商店
break;
}
}
传送玩家。
所属接口: NPC
返回类型: void
功能说明: 将玩家传送到指定地图和坐标。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| player | PlayObject | 是 | 玩家对象 |
| mapName | string | 是 | 目标地图名称 |
| x | number | 是 | 目标X坐标 |
| y | number | 是 | 目标Y坐标 |
示例代码:
export function ExecuteNpc(npc: NPC, player: PlayObject, label: string): void {
switch (label) {
case 'teleport':
// 传送到盟重省
npc.teleport(player, '盟重省', 330, 330);
break;
}
}
阻止服务端对标签的默认处理。
所属接口: NPC
返回类型: void
功能说明: 阻止服务端对当前标签执行默认逻辑(类似DOM的event.preventDefault())。
示例代码:
export function ExecuteNpc(npc: NPC, player: PlayObject, label: string): void {
switch (label) {
case 'buy':
// 检查玩家等级
if (player.ability.level < 10) {
npc.preventDefault(); // 阻止默认行为
npc.sendMsgToUser(player, '等级不够,无法购买!\\<返回/@main>');
return;
}
// 不调 preventDefault,服务端会正常打开购买窗口
break;
}
}
发送消息给用户。
所属接口: NPC
返回类型: void
功能说明: 向玩家发送NPC对话消息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| player | PlayObject | 是 | 玩家对象 |
| message | string | DialogConfig | 是 | 消息内容或配置对象 |
| bigDialog | boolean | 否 | 是否大对话框(默认false) |
示例代码:
// 普通对话框
npc.sendMsgToUser(player, '欢迎光临!');
// 大对话框
npc.sendMsgToUser(player, '欢迎光临!', true);
// 使用配置对象
npc.sendMsgToUser(player, {
message: '欢迎',
bigDialog: true
});
关闭对话框。
所属接口: NPC
返回类型: void
功能说明: 强制关闭玩家的NPC对话框。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| player | PlayObject | 是 | 玩家对象 |
示例代码:
// 强制关闭对话框
npc.closeDialog(player);
开始任务。
所属接口: NPC
返回类型: void
功能说明: 为指定玩家开始一个任务。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| player | PlayObject | 是 | 玩家对象 |
| questId | number | 是 | 任务ID |
示例代码:
// 为玩家开始任务
npc.startQuest(player, 1001);
player.sendMessage('任务已开始!');
完成任务。
所属接口: NPC
返回类型: void
功能说明: 为指定玩家完成一个任务。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| player | PlayObject | 是 | 玩家对象 |
| questId | number | 是 | 任务ID |
示例代码:
// 为玩家完成任务
npc.completeQuest(player, 1001);
player.sendMessage('任务已完成!');
player.give('任务奖励宝箱', 1);
重新加载NPC脚本。
所属接口: NPC
返回类型: void
功能说明: 重新加载当前NPC的脚本模块。
示例代码:
// 热重载NPC脚本
npc.reloadScript();
serverLog('NPC脚本已重载');
清除NPC脚本。
所属接口: NPC
返回类型: void
功能说明: 清除当前NPC的脚本,使NPC不再响应脚本逻辑。
示例代码:
// 清除NPC脚本
npc.clearScript();
补充商品(商户NPC专用)。
所属接口: NPC
返回类型: void
功能说明: 手动触发商品补充,将商品数量恢复到配置的最大值。
示例代码:
// 手动补充商品
npc.refillGoods();
player.sendMessage('商品已补充!');
保存NPC数据(商户NPC专用)。
所属接口: NPC
返回类型: void
功能说明: 将NPC当前的数据(如商品库存等)保存到持久化存储。
示例代码:
// 修改商品后保存数据
npc.refillGoods();
npc.saveNPCData();
serverLog('NPC数据已保存');
加载NPC数据(商户NPC专用)。
所属接口: NPC
返回类型: void
功能说明: 从持久化存储加载NPC的数据(如商品库存等)。
示例代码:
// 加载NPC数据
npc.loadNPCData();
serverLog('NPC数据已加载');
NPC配置接口,用于定义NPC的名称、位置、功能开关、商品列表等。
interface NpcConfig {
// ===== 基础属性 =====
name: string; // NPC名称(显示名称,允许重复)
map: string; // 地图名称
pos: { x: number; y: number }; // NPC坐标
face?: number; // NPC朝向(0-7)
appr?: number; // NPC外观ID
castle?: boolean; // 是否为城堡NPC
canMove?: boolean; // NPC是否可移动
moveTime?: number; // 移动间隔(毫秒)
desc?: string; // NPC描述
// ===== 商户功能开关 =====
buy?: boolean; // 购买功能开关
sell?: boolean; // 出售功能开关
repair?: boolean; // 修理功能开关
sRepair?: boolean; // 特殊修理功能开关
makeDrug?: boolean; // 炼药功能开关
prices?: boolean; // 价格查询功能开关
priceRate?: number; // NPC价格比率(默认100)
storage?: boolean; // 仓库功能开关
getBack?: boolean; // 取回物品功能开关
// ===== 物品类型限制 =====
sellItems?: number[]; // 允许出售的物品类型数组(StdMode值)
repairItems?: number[]; // 允许修理的物品类型数组(StdMode值)
// ===== 商品列表 =====
goods?: NpcGoods[]; // 商品列表
}
StdMode 物品类型对照表:
| StdMode | 物品类型 |
|---|---|
| 5, 6 | 武器 |
| 10, 11 | 衣服 |
| 15 | 头盔 |
| 16 | 斗笠 |
| 19, 20, 21 | 项链 |
| 22, 23 | 戒指 |
| 24, 25, 26 | 腰带 |
| 30, 31 | 鞋子 |
| 40, 41 | 宝石 |
| 2, 42, 31 | 药水/其他 |
| 3, 4 | 任务/传送 |
示例代码:
import { NpcConfig } from '../api';
export const NPC_CONFIG: NpcConfig = {
name: '武器商人',
map: '3',
pos: { x: 330, y: 330 },
face: 0,
buy: true,
sell: true,
repair: true,
priceRate: 100,
sellItems: [5, 6], // 只出售武器
repairItems: [5, 6], // 只修理武器
goods: [
{ name: '木剑', count: 10, refillTime: 60 },
{ name: '铁剑', count: 5, refillTime: 120 }
]
};
商品配置接口。
interface NpcGoods {
name: string; // 物品名称(标准物品名)
count: number; // 数量
refillTime?: number; // 刷新时间(分钟),0表示不自动刷新
}
示例代码:
const goods: NpcGoods[] = [
{ name: '木剑', count: 10, refillTime: 60 }, // 10把木剑,60分钟后刷新
{ name: '铁剑', count: 5, refillTime: 120 }, // 5把铁剑,120分钟后刷新
{ name: '生命药水', count: 20, refillTime: 30 }, // 20瓶生命药水,30分钟后刷新
{ name: '特殊物品', count: 1, refillTime: 0 } // 1个特殊物品,不刷新
];
对话框配置接口(预留扩展)。
interface DialogConfig {
message: string; // 消息内容
bigDialog?: boolean; // 是否大对话框(默认false)
dialogId?: string; // 对话框ID(未来扩展)
imageUrl?: string; // 对话框图片URL(未来扩展)
buttons?: Array<{ // 自定义按钮(未来扩展)
label: string;
action: string;
color?: string;
}>;
}
Environment 代表游戏中的地图环境,继承自 BaseObject,提供了地图查询、对象获取、行走检测等功能。
| 属性名 | 类型 | 说明 |
|---|---|---|
| MapFileName | string | 地图文件名 |
| ClientMapName | string | 客户端地图名称 |
| MapDesc | string | 地图描述 |
| NimbusCount | number | 光环数量 |
| Width | number | 地图宽度 |
| Height | number | 地图高度 |
| MapTitle | string | 地图标题 |
检查是否可以行走。
所属接口: Environment
返回类型: boolean
功能说明: 检查指定坐标是否可以行走。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
| flag | boolean | 否 | 标志(默认false) |
返回值: 可以行走返回 true,否则返回 false。
示例代码:
const env = GameLib.findMap('盟重省');
if (env) {
const canWalk = env.canWalk(330, 330);
if (canWalk) {
serverLog('该位置可以行走');
} else {
serverLog('该位置无法行走');
}
}
扩展的行走检测。
所属接口: Environment
返回类型: boolean
功能说明: 检查指定坐标是否可以行走(扩展版本,可指定玩家对象)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
| flag | boolean | 否 | 标志(默认false) |
| playObject | any | 否 | 玩家对象(可选) |
返回值: 可以行走返回 true,否则返回 false。
检查是否可以飞行(直线穿越检测)。
所属接口: Environment
返回类型: boolean
功能说明: 检查从起点到终点之间是否有障碍物(用于魔法飞行等)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| sx | number | 是 | 起点X坐标 |
| sy | number | 是 | 起点Y坐标 |
| dx | number | 是 | 终点X坐标 |
| dy | number | 是 | 终点Y坐标 |
返回值: 可以飞行返回 true,否则返回 false。
示例代码:
const env = GameLib.findMap('盟重省');
if (env) {
// 检查两点之间是否可以飞行
const canFly = env.canFly(330, 330, 340, 340);
serverLog(`是否可以飞行: ${canFly}`);
}
检查坐标是否是有效格子。
所属接口: Environment
返回类型: boolean
功能说明: 检查指定坐标是否在地图有效范围内。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
返回值: 有效格子返回 true,否则返回 false。
获取指定坐标的地面物品。
所属接口: Environment
返回类型: any
功能说明: 获取指定坐标上的地面物品信息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
返回值: 物品信息,无物品时返回空。
获取指定坐标的门。
所属接口: Environment
返回类型: any
功能说明: 获取指定坐标上的门信息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
返回值: 门信息,无门时返回空。
获取指定坐标的事件。
所属接口: Environment
返回类型: any
功能说明: 获取指定坐标上的地图事件信息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
返回值: 事件信息,无事件时返回空。
获取指定范围内的事件。
所属接口: Environment
返回类型: any
功能说明: 获取指定坐标范围内指定ID的事件。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | 中心X坐标 |
| y | number | 是 | 中心Y坐标 |
| range | number | 是 | 搜索范围 |
| id | number | 是 | 事件ID |
返回值: 事件信息。
获取指定坐标的对象数量。
所属接口: Environment
返回类型: number
功能说明: 获取指定坐标上站立的物体数量。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
返回值: 对象数量。
示例代码:
const env = GameLib.findMap('盟重省');
if (env) {
const count = env.getXYObjCount(330, 330);
serverLog(`坐标(330,330)上有 ${count} 个对象`);
}
检查是否可以安全行走。
所属接口: Environment
返回类型: boolean
功能说明: 检查指定坐标是否可以安全行走(安全区)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
返回值: 可以安全行走返回 true,否则返回 false。
检查指定位置是否在安全区。
所属接口: Environment
返回类型: boolean
功能说明: 检查指定坐标是否在安全区内。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
返回值: 在安全区返回 true,否则返回 false。
获取地图上所有怪物列表。
所属接口: Environment
返回类型: BaseObject[]
功能说明: 获取地图上所有怪物的列表。
返回值: 怪物对象数组。
示例代码:
const env = GameLib.findMap('盟重省');
if (env) {
const monsters = env.getMonsters();
serverLog(`怪物数量: ${monsters.length}`);
// 遍历怪物
for (const monster of monsters) {
serverLog(`怪物: ${monster.charName}, 位置: (${monster.currX}, ${monster.currY})`);
}
}
获取地图上所有玩家列表。
所属接口: Environment
返回类型: PlayObject[]
功能说明: 获取地图上所有玩家的列表。
返回值: 玩家对象数组。
示例代码:
const env = GameLib.findMap('盟重省');
if (env) {
const players = env.getPlayers();
serverLog(`玩家数量: ${players.length}`);
// 遍历玩家
for (const player of players) {
serverLog(`玩家: ${player.charName}, 等级: ${player.ability.level}`);
}
}
获取指定坐标范围内的所有可移动对象。
所属接口: Environment
返回类型: BaseObject[]
功能说明: 获取指定坐标范围内的所有对象。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | 中心X坐标 |
| y | number | 是 | 中心Y坐标 |
| range | number | 是 | 搜索范围 |
返回值: 对象数组。
示例代码:
const env = GameLib.findMap('盟重省');
if (env) {
// 获取坐标(330, 330)周围5格内的所有对象
const objects = env.getRangeObjects(330, 330, 5);
serverLog(`范围内的对象数量: ${objects.length}`);
}
获取指定坐标范围内的怪物列表。
所属接口: Environment
返回类型: BaseObject[]
功能说明: 获取指定坐标范围内的怪物。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | 中心X坐标 |
| y | number | 是 | 中心Y坐标 |
| range | number | 是 | 搜索范围 |
返回值: 怪物对象数组。
示例代码:
const env = GameLib.findMap('盟重省');
if (env) {
// 获取坐标(330, 330)周围5格内的所有怪物
const monsters = env.getRangeMonsters(330, 330, 5);
serverLog(`范围内的怪物数量: ${monsters.length}`);
}
获取指定坐标范围内的玩家列表。
所属接口: Environment
返回类型: PlayObject[]
功能说明: 获取指定坐标范围内的玩家。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number | 是 | 中心X坐标 |
| y | number | 是 | 中心Y坐标 |
| range | number | 是 | 搜索范围 |
返回值: 玩家对象数组。
示例代码:
const env = GameLib.findMap('盟重省');
if (env) {
// 获取坐标(330, 330)周围5格内的所有玩家
const players = env.getRangePlayers(330, 330, 5);
serverLog(`范围内的玩家数量: ${players.length}`);
}
获取地图上怪物数量(轻量计数)。
所属接口: Environment
返回类型: number
功能说明: 获取地图上怪物数量(不返回对象列表,性能更高)。
返回值: 怪物数量。
示例代码:
const env = GameLib.findMap('盟重省');
if (env) {
const monsterCount = env.getMonsterCount();
serverLog(`怪物数量: ${monsterCount}`);
}
获取地图上玩家数量(轻量计数)。
所属接口: Environment
返回类型: number
功能说明: 获取地图上玩家数量(不返回对象列表,性能更高)。
返回值: 玩家数量。
示例代码:
const env = GameLib.findMap('盟重省');
if (env) {
const playerCount = env.getPlayerCount();
serverLog(`玩家数量: ${playerCount}`);
}
Guild 代表游戏中的行会,继承自 BaseObject,提供了行会管理、成员管理、联盟战争等功能。
| 属性名 | 类型 | 说明 |
|---|---|---|
| GuildName | string | 行会名称 |
| ContestPoint | number | 竞争点 |
| TeamFight | boolean | 是否组队战斗 |
| BuildPoint | number | 建设点 |
| Aurae | number | 光环 |
| Stability | number | 稳定性 |
| Flourishing | number | 繁荣度 |
| ChiefItemCount | number | 首领物品数量 |
| MemberCount | number | 成员数量 |
| IsFull | boolean | 是否已满 |
检查是否是成员。
所属接口: Guild
返回类型: boolean
功能说明: 检查指定名称的玩家是否是行会成员。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| memberName | string | 是 | 成员名称 |
返回值: 是成员返回 true,否则返回 false。
示例代码:
const guild = player.getGuild();
if (guild) {
if (guild.isMember('张三')) {
serverLog('张三是行会成员');
}
}
添加成员。
所属接口: Guild
返回类型: boolean
功能说明: 将玩家添加到行会。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| member | PlayObject | 是 | 玩家对象 |
返回值: 添加成功返回 true,失败返回 false。
示例代码:
const guild = player.getGuild();
if (guild && player.isGuildMaster()) {
const targetPlayer = ...; // 获取目标玩家对象
if (guild.addMember(targetPlayer)) {
serverLog('成功添加成员');
}
}
删除成员。
所属接口: Guild
返回类型: boolean
功能说明: 将指定名称的成员从行会删除。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| memberName | string | 是 | 成员名称 |
返回值: 删除成功返回 true,失败返回 false。
示例代码:
const guild = player.getGuild();
if (guild && player.isGuildMaster()) {
if (guild.delMember('张三')) {
serverLog('成功删除成员');
}
}
发送行会消息。
所属接口: Guild
返回类型: void
功能说明: 向行会所有成员发送消息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| msg | string | 是 | 消息内容 |
| color | number | 否 | 颜色(默认0) |
| fc | number | 否 | 前景色(默认-1) |
| bc | number | 否 | 背景色(默认-1) |
| sec | number | 否 | 延迟(默认0) |
示例代码:
const guild = player.getGuild();
if (guild && player.isGuildMaster()) {
guild.sendGuildMsg('今晚8点攻城!');
}
检查是否是联盟行会。
所属接口: Guild
返回类型: boolean
功能说明: 检查指定行会是否是本行的联盟行会。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| guild | Guild | 是 | 行会对象 |
返回值: 是联盟返回 true,否则返回 false。
示例代码:
const myGuild = player.getGuild();
const targetGuild = ...; // 获取目标行会对象
if (myGuild && myGuild.isAllyGuild(targetGuild)) {
serverLog('这是联盟行会');
}
检查是否是战争行会。
所属接口: Guild
返回类型: boolean
功能说明: 检查指定行会是否是本行的战争行会。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| guild | Guild | 是 | 行会对象 |
返回值: 是战争行会返回 true,否则返回 false。
联盟行会。
所属接口: Guild
返回类型: boolean
功能说明: 与指定行会结盟。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| guild | Guild | 是 | 行会对象 |
返回值: 联盟成功返回 true,失败返回 false。
添加战争行会。
所属接口: Guild
返回类型: boolean
功能说明: 与指定行会宣战。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| guild | Guild | 是 | 行会对象 |
返回值: 添加成功返回 true,失败返回 false。
Magic 代表游戏中的魔法技能,继承自 BaseObject。
| 属性名 | 类型 | 说明 |
|---|---|---|
| btLevel | number | 魔法等级 |
| wMagIdx | number | 魔法索引 |
| MagicInfo | number | 魔法信息指针 |
示例代码:
// 读取魔法属性
serverLog(`魔法等级: ${magic.btLevel}`);
serverLog(`魔法索引: ${magic.wMagIdx}`);
本节介绍全局对象、全局函数和事件系统,这些接口不依附于特定对象,可在任何脚本中直接使用。
GameLib 是游戏核心库对象,提供了公告系统、怪物管理、脚本管理、文件监控、地图查询等全局功能。
发送全服公告。
所属对象: GameLib
返回类型: void
功能说明: 向全服玩家发送公告消息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| msg | string | 是 | 消息内容 |
| msgType | number | 否 | 消息类型(默认1) |
| msgColor | number | 否 | 消息颜色(默认1) |
| fc | number | 否 | 前景色(默认-1) |
| bc | number | 否 | 背景色(默认-1) |
| sec | number | 否 | 滚动次数(默认0) |
示例代码:
// 发送简单公告
GameLib.sendBroadcastMsg('欢迎来到游戏世界!');
// 发送彩色公告
GameLib.sendBroadcastMsg('重要通知!', 1, 255);
// 发送滚动公告
GameLib.sendBroadcastMsg('活动开始啦!', 1, 255, 0, 0, 3);
发送全服滚动公告。
所属对象: GameLib
返回类型: void
功能说明: 向全服发送滚动公告消息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| msg | string | 是 | 消息内容 |
| msgType | number | 否 | 消息类型(默认1) |
| msgColor | number | 否 | 消息颜色(默认1) |
| fc | number | 否 | 前景色(默认0) |
| bc | number | 否 | 背景色(默认0) |
| y | number | 否 | Y坐标位置(默认100) |
示例代码:
// 发送滚动公告
GameLib.sendScrollMsg('系统维护公告', 1, 255, 0, 0, 100);
发送扩展公告(红色)。
所属对象: GameLib
返回类型: void
功能说明: 发送红色扩展公告。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| msg | string | 是 | 消息内容 |
| msgType | number | 否 | 消息类型(默认1) |
示例代码:
// 发送红色扩展公告
GameLib.sendBroadcastMsgExt('紧急通知!');
发送扩展公告2(红色)。
所属对象: GameLib
返回类型: void
功能说明: 发送红色扩展公告2。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| msg | string | 是 | 消息内容 |
| msgType | number | 否 | 消息类型(默认1) |
生成单个怪物。
所属对象: GameLib
返回类型: Monster | null
功能说明: 在指定地图位置生成单个怪物。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图名称 |
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
| monsterName | string | 是 | 怪物名称 |
返回值: 怪物对象,失败返回 null。
示例代码:
// 在盟重省生成一只鹿
const monster = GameLib.spawnMonster('盟重省', 330, 330, '鹿');
if (monster) {
serverLog('生成怪物成功');
}
批量生成怪物。
所属对象: GameLib
返回类型: Monster[]
功能说明: 在指定位置批量生成怪物,支持复活配置。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图名称 |
| x | number | 是 | 中心点X坐标 |
| y | number | 是 | 中心点Y坐标 |
| count | number | 是 | 生成数量 |
| range | number | 是 | 生成范围(随机偏移),0表示不随机 |
| canReAlive | boolean | 是 | 是否可以复活(true=服务端自动复活,false=TS侧完全控制) |
| reAliveTime | number | 是 | 复活时间(毫秒),仅在 canReAlive=true 时有效,0表示默认60秒 |
| monsterName | string | 是 | 怪物名称 |
返回值: 成功生成的怪物对象数组。
示例代码:
// 服务端自动复活(60秒后复活)
const monsters = GameLib.spawnMonsterEx('盟重省', 330, 330, 50, 10, true, 60000, '鹿');
serverLog(`生成了 ${monsters.length} 只鹿`);
// 服务端自动复活(使用默认60秒)
GameLib.spawnMonsterEx('盟重省', 330, 330, 50, 10, true, 0, '鹿');
// TS侧完全控制(不自动复活)
GameLib.spawnMonsterEx('活动地图', 100, 100, 10, 20, false, 0, '活动BOSS');
清除地图上的所有怪物。
所属对象: GameLib
返回类型: number
功能说明: 清除指定地图上的所有怪物。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图名称 |
| dropItems | boolean | 是 | 是否掉落物品 |
返回值: 清除的怪物数量。
示例代码:
// 清除盟重省的所有怪物,不掉落物品
const count = GameLib.clearMonstersByMap('盟重省', false);
serverLog(`清除了 ${count} 只怪物`);
// 清除活动地图的所有怪物,掉落物品
const count2 = GameLib.clearMonstersByMap('活动地图', true);
serverLog(`清除了 ${count2} 只怪物,已掉落物品`);
清除地图上指定名称的怪物。
所属对象: GameLib
返回类型: number
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图名称 |
| monsterName | string | 是 | 怪物名称 |
| dropItems | boolean | 是 | 是否掉落物品 |
返回值: 清除的怪物数量。
示例代码:
const count = GameLib.clearMonstersByName('盟重省', '鹿', false);
serverLog(`清除了 ${count} 只鹿`);
注册脚本模块。
所属对象: GameLib
返回类型: boolean
功能说明: 注册单个脚本模块。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| moduleName | string | 是 | 模块名称 |
| filePath | string | 是 | 文件路径 |
| permissions | any[] | 否 | 权限集合(可选) |
返回值: 注册成功返回 true,失败返回 false。
示例代码:
const success = GameLib.registerScriptModule('npc-test', './npc/npc-test.ts');
if (success) {
serverLog('脚本模块注册成功');
}
初始化所有脚本。
所属对象: GameLib
返回类型: boolean
功能说明: 初始化所有脚本模块。
返回值: 初始化成功返回 true,失败返回 false。
重新加载所有脚本。
所属对象: GameLib
返回类型: boolean
功能说明: 重新加载所有脚本模块。
返回值: 重载成功返回 true,失败返回 false。
示例代码:
// 热重载所有脚本
if (GameLib.reloadAllScripts()) {
serverLog('所有脚本重载成功');
}
重新加载指定脚本模块。
所属对象: GameLib
返回类型: boolean
功能说明: 重新加载指定名称的脚本模块。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| moduleName | string | 是 | 模块名称 |
返回值: 重载成功返回 true,失败返回 false。
示例代码:
// 重载指定模块
if (GameLib.reloadScriptModule('npc-test')) {
serverLog('npc-test 模块重载成功');
}
通过 MODULE_TAG 重新加载指定脚本模块。
所属对象: GameLib
返回类型: boolean
功能说明: 根据模块标签重载脚本模块。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| tag | number | 是 | 模块标签(数字类型) |
返回值: 重载成功返回 true,失败返回 false。
示例代码:
// 在脚本中声明 tag
// export const MODULE_TAG = 101;
// 通过 tag 重载
GameLib.reloadByTag(101);
// 或使用注入的 __module__ 变量重载自身
GameLib.reloadByTag(__module__.tag);
获取已加载的脚本列表。
所属对象: GameLib
返回类型: string[]
功能说明: 获取所有已加载脚本模块的名称列表。
返回值: 脚本名称数组。
示例代码:
const scripts = GameLib.getLoadedScripts();
serverLog(`已加载的脚本数量: ${scripts.length}`);
for (const scriptName of scripts) {
serverLog(`- ${scriptName}`);
}
检查脚本是否已加载。
所属对象: GameLib
返回类型: boolean
功能说明: 检查指定名称的脚本模块是否已加载。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| moduleName | string | 是 | 模块名称 |
返回值: 已加载返回 true,否则返回 false。
示例代码:
if (GameLib.isScriptLoaded('npc-test')) {
serverLog('npc-test 模块已加载');
}
从目录注册脚本模块。
所属对象: GameLib
返回类型: boolean
功能说明: 从指定目录批量注册脚本模块。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| options | RegisterModulesOptions | 是 | 注册选项对象 |
返回值: 注册成功返回 true,失败返回 false。
RegisterModulesOptions 接口:
interface RegisterModulesOptions {
directory: string; // 目录路径
exclude?: string[]; // 排除的文件模式数组(可选)
pattern?: string; // 文件匹配模式(可选,默认'*.js')
}
示例代码:
// 从npc目录批量注册脚本
const success = GameLib.registerScriptModulesFromDirectory({
directory: './npc',
exclude: ['*.test.ts'],
pattern: '*.ts'
});
if (success) {
serverLog('目录脚本注册成功');
}
开始文件监控。
所属对象: GameLib
返回类型: boolean
功能说明: 启动对指定目录的文件监控,文件变化时自动重载脚本。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| directory | string | 是 | 监控目录 |
| interval | number | 否 | 监控间隔(毫秒,默认1000) |
| useOsApi | boolean | 否 | 是否使用操作系统API(默认false) |
返回值: 启动成功返回 true,失败返回 false。
示例代码:
// 启动npc目录的文件监控
if (GameLib.startFileWatch('./npc', 1000, false)) {
serverLog('文件监控启动成功');
}
停止文件监控。
所属对象: GameLib
返回类型: boolean
功能说明: 停止对指定目录的文件监控。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| directory | string | 是 | 监控目录 |
返回值: 停止成功返回 true,失败返回 false。
示例代码:
// 停止npc目录的文件监控
if (GameLib.stopFileWatch('./npc')) {
serverLog('文件监控已停止');
}
通过地图文件名查找地图对象。
所属对象: GameLib
返回类型: Environment | null
功能说明: 根据地图文件名查找地图环境对象。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图文件名 |
返回值: 地图环境对象,未找到返回 null。
示例代码:
// 查找地图对象
const env = GameLib.findMap('0');
if (env) {
serverLog(`地图: ${env.MapDesc}, 怪物数: ${env.getMonsterCount()}`);
// 使用地图对象的方法
const players = env.getPlayers();
serverLog(`玩家数量: ${players.length}`);
}
获取所有已注册的地图配置。
所属对象: GameLib
返回类型: Record<string, MapConfig>
示例代码:
const configs = GameLib.getMapConfigs();
serverLog(`已注册 ${Object.keys(configs).length} 张地图`);
获取指定地图的配置。
所属对象: GameLib
返回类型: MapConfig | null
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图文件名 |
示例代码:
const cfg = GameLib.getMapConfig('0');
if (cfg) serverLog(`地图描述: ${cfg.mapDesc}`);
动态修改地图标志位(运行时生效)。
所属对象: GameLib
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图文件名 |
| flags | Partial<MapFlags> | 是 | 要修改的标志位(部分更新) |
示例代码:
GameLib.setMapFlags('3', { safe: true, expRate: { rate: 200 } });
动态重置地图标志位(恢复为配置中的原始值)。
所属对象: GameLib
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图文件名 |
动态添加传送路由(运行时生效)。
所属对象: GameLib
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| fromMap | string | 是 | 起始地图 |
| fromX | number | 是 | 起始X坐标 |
| fromY | number | 是 | 起始Y坐标 |
| toMap | string | 是 | 目标地图 |
| toX | number | 是 | 目标X坐标 |
| toY | number | 是 | 目标Y坐标 |
移除传送路由。
所属对象: GameLib
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图名称 |
| x | number | 是 | X坐标 |
| y | number | 是 | Y坐标 |
获取地图的所有传送路由。
所属对象: GameLib
返回类型: MapRoute[]
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图名称 |
热重载地图配置(从 TS 模块重新加载)。
所属对象: GameLib
返回类型: boolean
注册地图配置数据到引擎缓存。由 mapLoader 在模块加载时自动调用。
所属对象: GameLib
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| configs | Record<string, MapConfig> | 是 | 地图名到配置的映射 |
批量注册地图配置(一次性传入所有地图),启动时调用比单张 addMap 循环更高效。
所属对象: GameLib
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| configs | Record<string, MapConfig> | 是 | 地图名到配置的映射 |
运行时动态新增一张地图。前提:对应的 .map 文件必须存在于 MapDir 目录下。
所属对象: GameLib
返回类型: Environment | null
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图编号 |
| config | MapConfig | 是 | 地图配置 |
示例代码:
const env = GameLib.addMap('D6001', { mapDesc: '活动地图', miniMapIndex: 100 });
if (env) serverLog('地图添加成功');
运行时动态移除一张地图。
所属对象: GameLib
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mapName | string | 是 | 地图编号 |
注册怪物掉落函数。当指定名称的怪物死亡时,引擎会调用注册的函数来计算掉落。重复注册同一怪物名会覆盖之前的函数。
所属对象: GameLib
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| monsterName | string | 是 | 怪物名称(必须与怪物数据库中的名称完全一致) |
| dropFunc | (ctx: DropContext) => DropResultItem[] | 是 | 掉落计算函数 |
示例代码:
import { GameLib } from 'api/game';
import { DropResultItem } from 'api/drop';
GameLib.registerMonsterDrop('稻草人', (ctx) => {
const items: DropResultItem[] = [];
if (Math.random() < 0.1) {
items.push({ name: '木剑', count: 1 });
}
if (ctx.killer) {
items.push({ name: '金币', count: 100 + Math.floor(Math.random() * 500) });
}
return items;
});
注销怪物掉落函数。注销后该怪物死亡时不再触发JS掉落,且不掉落任何物品。
所属对象: GameLib
返回类型: boolean
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| monsterName | string | 是 | 怪物名称 |
独立 FlexUI 窗口不依赖 NPC,可在任何时机(如事件回调、定时器)打开,支持动态更新内容。
打开独立 FlexUI 窗口。
| 参数 | 类型 | 说明 |
|---|---|---|
| player | PlayObject | 玩家对象 |
| windowId | string | 窗口唯一标识(如 'mail_box'、'market') |
| json | string | 排版 JSON 内容 |
关闭独立 FlexUI 窗口。
更新独立 FlexUI 窗口内容(不关闭重开,直接替换内容)。
JSON 排版支持的控件类型:
| 控件 | type 值 | 说明 |
|---|---|---|
| 文本 | text |
支持 color、size、bold、italic、underline |
| 按钮 | button |
支持 id、color、underline、text |
| 分割线 | separator |
支持 color |
| 输入框 | edit |
支持 id、width、height、placeholder、maxLength、fontSize、fontColor |
| 多行编辑 | memo |
同 edit,额外支持多行输入 |
| 图片 | image |
支持 lib(素材库编号)、index、width、height |
| 进度条 | progress |
支持 lib、index、rate、max、height、text、color |
| 物品栏 | itembox |
支持 id(0-11) |
container 配置:
| 字段 | 类型 | 说明 |
|---|---|---|
| width | number | 窗口宽度 |
| bgColor | string/number | 背景颜色 |
| alpha | number | 透明度(0-255) |
| floating | boolean | 是否浮动窗口 |
| position | number | 位置:0=左上, 1=右上, 2=左下, 3=右下, 4=居中, 5=世界坐标 |
| left | number | position=0时的自定义X坐标(可选) |
| top | number | position=0时的自定义Y坐标(可选) |
| clickThrough | boolean | 鼠标穿透,窗口不拦截下层点击事件(可选,默认false) |
| worldX | number | 世界坐标X(position=5时生效) |
| worldY | number | 世界坐标Y(position=5时生效) |
| autoClose | boolean | 动画播完后自动关闭窗口(默认false) |
| broadcast | string | 广播模式:'self'(默认) |
| broadcastRange | number | nearby模式范围(默认26格) |
| border | object | 边框配置 |
示例代码:
GameLib.openFlexWindow(player, 'test_win', JSON.stringify({
container: {
width: 360,
bgColor: '#1a1a2e',
alpha: 235,
floating: true,
position: 4,
border: { color: '#3a3a5a', width: 1 }
},
lines: [
{ type: 'text', text: '标题', color: '#FFD700', size: 14, bold: true },
{ type: 'separator', color: '#3a3a5a' },
[
{ type: 'button', text: '确认', id: 'btn_ok', color: '#00FF00', underline: false },
{ type: 'text', text: ' ' },
{ type: 'button', text: '关闭', id: 'btn_close', color: '#808080', underline: false },
],
{ type: 'edit', id: 'ed_input', width: 340, height: 22, placeholder: '请输入', maxLength: 50, fontSize: 12, fontColor: '#FFFFFF' },
]
}));
subscribe(EventType.UIClick, (...args: any[]) => {
const player = args[0];
const elementId = args[2];
const windowId = args.length > 3 ? args[3] : '';
if (windowId === 'test_win' && elementId === 'btn_close') {
GameLib.closeFlexWindow(player, 'test_win');
}
});
subscribe(EventType.UIEdit, (...args: any[]) => {
const player = args[0];
const elementId = args[2];
const windowId = args[3];
const text = args.length > 4 ? args[4] : '';
serverLog(`输入变更: ${elementId} = ${text}`);
});
按角色名更新独立 FlexUI 窗口内容。适用于定时器回调、异步场景(此时 player 对象可能已失效)。
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| charName | string | 角色名 |
| windowId | string | 窗口唯一标识 |
| json | string | 新的排版 JSON |
返回值: boolean - 是否成功
示例代码:
import { GameLib } from 'api/game';
const charName = player.charName;
const timerId = setInterval(function() {
GameLib.updateFlexWindowByCharName(charName, 'my_window', buildJson());
}, 5000);
按角色名关闭独立 FlexUI 窗口。适用于定时器回调、异步场景(此时 player 对象可能已失效)。
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| charName | string | 角色名 |
| windowId | string | 窗口唯一标识 |
返回值: boolean - 是否成功
示例代码:
GameLib.closeFlexWindowByCharName(playerName, 'effect_win');
获取游戏版本。
返回类型: string
功能说明: 获取游戏引擎的版本字符串。
返回值: 游戏版本字符串。
示例代码:
const version = getVersion();
serverLog(`游戏版本: ${version}`);
输出日志到服务端窗口。
返回类型: void
功能说明: 将日志消息输出到服务端控制台窗口。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| message | string | 是 | 日志消息 |
| color | number | 否 | 日志颜色(默认白色) |
示例代码:
// 输出普通日志
serverLog('这是普通日志');
// 输出红色日志
serverLog('这是红色日志', 255);
// 输出调试日志
serverLog(`玩家 ${player.charName} 执行了某操作`);
设置一次性定时器。
返回类型: number
功能说明: 在指定延迟后执行回调函数一次。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| handler | function | 是 | 要执行的回调函数 |
| delay | number | 是 | 延迟时间(毫秒) |
| args | any[] | 否 | 传递给回调函数的参数(可选) |
返回值: 定时器ID,用于清除定时器。
示例代码:
// 5秒后执行
const timerId = setTimeout(() => {
serverLog('5秒后执行的任务');
}, 5000);
// 带参数的定时器
setTimeout((name: string) => {
serverLog(`你好,${name}`);
}, 3000, '张三');
// 清除定时器
clearTimeout(timerId);
设置周期性定时器。
返回类型: number
功能说明: 按指定间隔重复执行回调函数。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| handler | function | 是 | 要执行的回调函数 |
| interval | number | 是 | 执行间隔(毫秒) |
| args | any[] | 否 | 传递给回调函数的参数(可选) |
返回值: 定时器ID,用于清除定时器。
示例代码:
// 每10秒执行一次
let count = 0;
const timerId = setInterval(() => {
count++;
serverLog(`定时器执行次数: ${count}`);
if (count >= 5) {
clearInterval(timerId); // 执行5次后停止
}
}, 10000);
// 清除定时器
// clearInterval(timerId);
清除由 setTimeout 设置的定时器。
返回类型: void
功能说明: 清除一次性定时器,阻止其执行。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| timerId | number | 是 | 要清除的定时器ID |
示例代码:
const timerId = setTimeout(() => {
serverLog('这不会执行');
}, 5000);
clearTimeout(timerId); // 清除定时器
清除由 setInterval 设置的定时器。
返回类型: void
功能说明: 清除周期性定时器,停止重复执行。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| timerId | number | 是 | 要清除的定时器ID |
示例代码:
const timerId = setInterval(() => {
serverLog('定时任务');
}, 1000);
// 5秒后清除定时器
setTimeout(() => {
clearInterval(timerId);
}, 5000);
动态修改定时器的优先级。
返回类型: void
功能说明: 修改定时器的执行优先级。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| timerId | number | 是 | 定时器ID(由 setTimeout 或 setInterval 返回) |
| priority | TimerPriority | 是 | 优先级:0=高、1=普通、2=低 |
TimerPriority 类型说明:
0 - 高优先级(tpHigh),每次 tick 优先处理,适合关键逻辑(如战斗判定)1 - 普通优先级(tpNormal),每次 tick 在高优先级之后处理,默认级别2 - 低优先级(tpLow),每 50ms 批量处理一次,适合非关键任务(如日志、统计)示例代码:
// 创建高优先级定时器(关键逻辑)
const highTimer = setTimeout(() => {
serverLog('高优先级任务');
}, 1000);
// 创建低优先级定时器(日志统计)
const lowTimer = setInterval(() => {
serverLog('统计信息');
}, 60000);
// 修改优先级
setTimerPriority(highTimer, 0); // 高优先级
setTimerPriority(lowTimer, 2); // 低优先级
注册 WIL/WZL/PAK 素材库。
返回类型: number
功能说明: 注册自定义素材库文件(仅在脚本初始化阶段调用)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| fileName | string | 是 | 素材文件名(相对于 Data\ 目录) |
返回值: 素材库编号,用于 JSON 排版中引用。
示例代码:
// 在脚本初始化阶段注册素材库
const libId = registerImageLibrary('CustomEffect.wil');
serverLog(`素材库ID: ${libId}`);
// 在 JSON 排版中使用
// {
// "container": { "bgImage": { "lib": libId, "index": 0 } },
// "lines": [...]
// }
全局对象 Http 提供同步和异步 HTTP 请求能力,开发者可自行部署后端服务实现数据交互。
HttpResponse 响应对象:
| 字段 | 类型 | 说明 |
|---|---|---|
| status | number | HTTP状态码(200=成功, 404=未找到, 500=服务器错误, 负数=本地错误) |
| data | string | 响应体内容(通常是JSON字符串) |
| headers | string | 响应头(CRLF分隔) |
同步 API(阻塞当前JS线程):
| 方法 | 说明 |
|---|---|
Http.get(url, headers?) |
GET请求 |
Http.post(url, body, headers?) |
POST请求(默认 Content-Type: application/json) |
Http.put(url, body, headers?) |
PUT请求 |
Http.del(url, headers?) |
DELETE请求 |
异步 API(不阻塞,后台线程执行):
| 方法 | 说明 |
|---|---|
Http.getAsync(url, callback, headers?) |
异步GET请求 |
Http.postAsync(url, body, callback, headers?) |
异步POST请求 |
Http.putAsync(url, body, callback, headers?) |
异步PUT请求 |
Http.delAsync(url, callback, headers?) |
异步DELETE请求 |
示例代码:
const res = Http.post('http://127.0.0.1:3000/api/query',
JSON.stringify({ name: player.charName }));
if (res.status === 200) {
const data = JSON.parse(res.data);
serverLog('查询结果: ' + data.result);
}
Http.getAsync('http://127.0.0.1:3000/api/heartbeat', (res) => {
serverLog('心跳: ' + res.status);
});
当前模块元信息(脚本执行时由引擎自动注入,无需手动声明)。
类型:
{
name: string; // 模块名(如 'npc/npc-test')
tag: number | null; // MODULE_TAG 值,未声明则为 null
}
示例代码:
// 在任意脚本中直接使用
serverLog(`当前模块: ${__module__.name}, tag: ${__module__.tag}`);
// 重载自身
if (__module__.tag !== null) {
GameLib.reloadByTag(__module__.tag);
}
模块标签(可选导出常量)。
说明: 在脚本模块中通过 export 声明,引擎注册模块时自动读取并建立 tag → 模块名映射。
示例代码:
// 在脚本中声明标签
export const MODULE_TAG = 101;
// 引擎注册时会自动读取并建立映射
// 后续可以通过 reloadByTag(101) 重载此模块
定时器优先级类型(见 setTimerPriority 函数说明)。
类型: 0 | 1 | 2
事件系统是 FlexCore SDK 的核心功能之一,提供了完整的事件订阅、发布、拦截机制。
| 事件名称 | 事件值 | 说明 |
|---|---|---|
| PlayerLogin | 'onPlayerLogin' | 玩家登录事件 |
| PlayerLogout | 'onPlayerLogout' | 玩家登出事件 |
| PlayerLevelUp | 'onPlayerLevelUp' | 玩家升级事件 |
| HeroLevelUp | 'onHeroLevelUp' | 英雄升级事件 |
| EngineStartup | 'onEngineStartup' | 引擎启动事件 |
| ObjectTakeDamage | 'onObjectTakeDamage' | 对象受到伤害事件 |
| ItemUse | 'onItemUse' | 物品使用事件 |
| ItemPickup | 'onItemPickup' | 物品拾取事件 |
| ItemDrop | 'onItemDrop' | 物品丢弃事件 |
| ItemEquip | 'onItemEquip' | 装备穿戴事件 |
| ItemUnequip | 'onItemUnequip' | 装备卸下事件 |
| SlaveAdd | 'onSlaveAdd' | 下属加入事件 |
| MapLeave | 'onMapLeave' | 离开地图事件 |
| MapEnter | 'onMapEnter' | 进入地图事件 |
| MapFlagChanged | 'onMapFlagChanged' | 地图标志位变更事件 |
| MapRouteAdded | 'onMapRouteAdded' | 传送路由添加事件 |
| MapRouteRemoved | 'onMapRouteRemoved' | 传送路由移除事件 |
| MapAdd | 'onMapAdd' | 地图添加事件 |
| MapRemove | 'onMapRemove' | 地图移除事件 |
| MagicCast | 'onMagicCast' | 技能释放事件 |
以下事件支持通过回调返回值来控制游戏逻辑执行:
| 事件名称 | 说明 |
|---|---|
| PlayerLogin | 可拦截玩家登录 |
| ItemUse | 可拦截物品使用 |
| ItemPickup | 可拦截物品拾取 |
| ItemDrop | 可拦截物品丢弃 |
| ItemEquip | 可拦截装备穿戴 |
| ItemUnequip | 可拦截装备卸下 |
| ObjectTakeDamage | 可拦截伤害计算 |
| SlaveAdd | 可拦截下属加入 |
| MapLeave | 可拦截地图传送 |
返回值语义:
false = 拦截(阻止游戏逻辑)true 或不返回 = 允许继续{ intercepted: false, args: {...} } = 允许继续,并修改指定参数的值{ intercepted: true, args: {...} } = 拦截,同时修改参数(参数修改无实际意义)订阅事件。
所属对象: EventSystem
返回类型: string
功能说明: 订阅指定事件,返回订阅ID用于取消订阅。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| eventName | string | EventType | 是 | 事件名称或事件类型枚举 |
| callback | EventCallback | 是 | 事件回调函数 |
| priority | number | 否 | 事件优先级(默认0),数值越大优先级越高 |
| enabled | boolean | 否 | 是否启用(默认true) |
| executionMode | 'synchronous' | 'asynchronous' | 否 | 执行模式(默认'synchronous') |
返回值: 订阅ID,用于取消订阅。
示例代码:
// 订阅玩家登录事件
const subId1 = subscribe(EventType.PlayerLogin, (player: PlayObject) => {
serverLog(`玩家 ${player.charName} 登录了`);
});
// 订阅物品使用事件(可拦截)
const subId2 = subscribe(EventType.ItemUse, (event: ItemUseEvent) => {
const player = event.player;
const stdItem = event.stdItem;
serverLog(`玩家 ${player.charName} 使用了物品 ${stdItem.Name}`);
// 返回 false 可以拦截事件
// if (player.ability.level < stdItem.NeedLevel) {
// player.sendMessage('等级不够,无法使用此物品!');
// return false;
// }
}, 10, true, 'synchronous'); // 优先级10,启用,同步执行
// 订阅玩家升级事件
const subId3 = subscribe(EventType.PlayerLevelUp, (event: PlayerLevelUpEvent) => {
serverLog(`玩家 ${event.player.charName} 升级了`);
}, 5, true, 'asynchronous'); // 优先级5,启用,异步执行
取消订阅事件。
所属对象: EventSystem
返回类型: boolean
功能说明: 根据订阅ID取消事件订阅。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| subscriptionId | string | 是 | 订阅ID |
返回值: 取消成功返回 true,失败返回 false。
示例代码:
// 订阅事件
const subId = subscribe(EventType.PlayerLogin, (player: PlayObject) => {
serverLog(`玩家 ${player.charName} 登录了`);
});
// 取消订阅
if (unsubscribe(subId)) {
serverLog('事件订阅已取消');
}
发布事件。
所属对象: EventSystem
返回类型: boolean
功能说明: 发布指定事件,触发所有订阅该事件的回调。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| eventName | string | EventType | 是 | 事件名称或事件类型枚举 |
| args | any[] | 是 | 事件参数数组 |
返回值: 发布成功返回 true,失败返回 false。
示例代码:
// 发布自定义事件
publish('CustomEvent', { data: 'some data' });
// 发布玩家登录事件(模拟)
// publish(EventType.PlayerLogin, player);
获取事件监听器数量。
所属对象: EventSystem
返回类型: number
功能说明: 获取指定事件的监听器数量,或所有监听器的总数。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| eventName | string | EventType | 否 | 事件名称(不指定则返回所有监听器数量) |
返回值: 事件监听器数量。
示例代码:
// 获取玩家登录事件的监听器数量
const count1 = EventSystem.getListenerCount(EventType.PlayerLogin);
serverLog(`玩家登录事件监听器数量: ${count1}`);
// 获取所有监听器总数
const totalCount = EventSystem.getListenerCount();
serverLog(`所有事件监听器总数: ${totalCount}`);
启用/禁用事件处理。
所属对象: EventSystem
返回类型: void
功能说明: 启用或禁用全局事件处理。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| enabled | boolean | 是 | 是否启用 |
示例代码:
// 暂停事件处理
EventSystem.setEventProcessingEnabled(false);
// 执行一些操作...
// 恢复事件处理
EventSystem.setEventProcessingEnabled(true);
清空事件队列。
所属对象: EventSystem
返回类型: void
功能说明: 清空当前的事件队列。
示例代码:
// 清空事件队列
EventSystem.clearEventQueue();
获取事件统计信息。
所属对象: EventSystem
返回类型: 事件统计信息对象
功能说明: 获取事件系统的统计信息。
返回值: 事件统计信息对象。
返回值结构:
{
totalListeners: number; // 总监听器数量
enqueueCount: number; // 入队次数
dequeueCount: number; // 出队次数
overflowCount: number; // 溢出次数
queueSize: number; // 队列大小
listenersByEvent: Record<string, number>; // 各事件的监听器数量
}
示例代码:
const stats = EventSystem.getEventStatistics();
serverLog(`总监听器: ${stats.totalListeners}`);
serverLog(`入队次数: ${stats.enqueueCount}`);
serverLog(`出队次数: ${stats.dequeueCount}`);
serverLog(`队列大小: ${stats.queueSize}`);
玩家升级事件参数。
interface PlayerLevelUpEvent {
player: PlayObject; // 玩家对象
}
英雄升级事件参数。
interface HeroLevelUpEvent {
player: PlayObject; // 英雄的主人玩家对象
}
物品使用事件参数(可拦截事件)。
interface ItemUseEvent {
player: PlayObject; // 使用物品的玩家对象
stdItem: StdItem; // 标准物品对象
itemIndex: number; // 物品在背包中的位置索引
}
物品拾取事件参数(可拦截事件)。
interface ItemPickupEvent {
player: PlayObject; // 拾取物品的玩家对象
userItem: UserItem; // 用户物品对象
}
物品丢弃事件参数(可拦截事件)。
interface ItemDropEvent {
player: PlayObject; // 丢弃物品的玩家对象
stdItem: StdItem; // 标准物品对象
}
装备穿戴事件参数(可拦截事件)。
interface ItemEquipEvent {
player: any; // 穿戴装备的角色对象(玩家或英雄)
item: any; // 穿戴的物品对象
}
装备卸下事件参数(可拦截事件)。
interface ItemUnequipEvent {
player: any; // 卸下装备的角色对象(玩家或英雄)
item: any; // 卸下的物品对象
}
下属加入事件参数(可拦截事件)。
interface SlaveAddEvent {
player: PlayObject; // 主人(玩家对象)
slave: Monster; // 下属对象(怪物),可修改属性如 slaveExpLevel
}
离开地图事件参数(可拦截事件)。
interface MapLeaveEvent {
player: PlayObject; // 离开地图的玩家对象
targetMapName: string; // 目标地图文件名
targetX: number; // 目标X坐标
targetY: number; // 目标Y坐标
}
进入地图事件参数(纯通知事件,不可拦截)。
interface MapEnterEvent {
player: PlayObject; // 进入地图的玩家对象
mapName: string; // 当前地图文件名
x: number; // 当前X坐标
y: number; // 当前Y坐标
}
对象受到伤害事件参数(可拦截事件)。
interface ObjectTakeDamageEvent {
victim: any; // 受伤对象(不可修改)
attacker: any; // 攻击对象(不可修改)
damage: number; // 伤害值(可通过 EventModifyResult 修改)
skillId: number; // 技能ID(0表示物理攻击,不可修改)
}
注意: 300人以上伤害回调必须在0.5ms内完成,否则会导致游戏性能问题。
全局事件函数是 EventSystem 接口的快捷方式,可以直接调用。
| 函数名 | 说明 |
|---|---|
subscribe() |
订阅事件(同 EventSystem.subscribe) |
unsubscribe() |
取消订阅(同 EventSystem.unsubscribe) |
publish() |
发布事件(同 EventSystem.publish) |
示例代码:
// 使用全局函数订阅事件
const subId = subscribe(EventType.PlayerLogin, (player: PlayObject) => {
serverLog(`玩家 ${player.charName} 登录了`);
});
// 使用全局函数取消订阅
unsubscribe(subId);
// 使用全局函数发布事件
publish('CustomEvent', { data: 'test' });
事件参数修改结果,用于同步订阅回调返回值。
interface EventModifyResult {
intercepted: boolean; // 是否拦截游戏逻辑(false=允许继续,true=拦截)
args: Record<string, any>; // 需要修改的事件参数
}
1. 简单拦截(返回 false):
subscribe(EventType.ItemUse, (event: ItemUseEvent) => {
const player = event.player;
const stdItem = event.stdItem;
// 等级不够,拦截事件
if (player.ability.level < stdItem.NeedLevel) {
player.sendMessage('等级不够,无法使用此物品!');
return false; // 拦截,阻止使用
}
// 返回 true 或不返回值,允许事件继续
});
2. 修改事件参数:
subscribe(EventType.ObjectTakeDamage, (event: ObjectTakeDamageEvent) => {
const victim = event.victim;
const attacker = event.attacker;
// 玩家攻击怪物时,伤害减半
if (victim.isMonster() && attacker.isHuman()) {
return {
intercepted: false,
args: {
damage: event.damage * 0.5 // 修改伤害值为原来的50%
}
};
}
// 返回 true 或不返回值,使用原伤害值
});
3. 同时拦截和修改参数:
subscribe(EventType.SlaveAdd, (event: SlaveAddEvent) => {
const player = event.player;
const slave = event.slave;
// 玩家等级太低,阻止加入并修改下属属性
if (player.ability.level < 10) {
slave.slaveExpLevel = 0; // 修改下属等级
slave.recalcAbilitys(); // 刷新能力值
return {
intercepted: true, // 拦截,阻止加入
args: {} // 参数修改无实际意义
};
}
// 返回 true 或不返回值,允许加入
});
4. 地图传送拦截:
subscribe(EventType.MapLeave, (event: MapLeaveEvent) => {
const player = event.player;
const targetMap = event.targetMapName;
// 阻止传送到危险地图
if (targetMap === '危险地图') {
player.sendMessage('该地图危险,无法进入!');
return false; // 拦截传送
}
// 修改传送坐标
return {
intercepted: false,
args: {
targetX: event.targetX + 1, // X坐标+1
targetY: event.targetY + 1 // Y坐标+1
}
};
});
本节介绍物品系统的核心接口,包括标准物品模板(StdItem)和用户物品实例(UserItem)。物品系统是游戏中最基础的数据结构之一,贯穿于背包管理、装备穿戴、NPC商店、掉落拾取等几乎所有玩法。
StdItem 是标准物品模板接口,定义了物品的基础属性。每个物品在数据库中对应一条 StdItem 记录,作为物品的"蓝图"或"模板"。
注意:StdItem 是只读的模板数据,不包含极品属性和扩展属性。如需获取含极品附加的完整属性,请使用 UserItem.getAddValue()。
| 属性名 | 类型 | 说明 |
|---|---|---|
| Name | string | 物品名称 |
| StdMode | number | 物品类型(如武器、防具、药品等) |
| Shape | number | 物品形状(影响外观显示) |
| Weight | number | 物品重量 |
| AniCount | number | 动画数量 |
| Looks | number | 外观编号 |
| DuraMax | number | 最大耐久度 |
| AC | number | 防御力 |
| MAC | number | 魔法防御力 |
| DC | number | 物理攻击力 |
| MC | number | 魔法攻击力 |
| SC | number | 神圣攻击力(道术) |
| NeedLevel | number | 需求等级 |
| Price | number | 价格 |
| Source | number | 来源/神圣属性 |
| Reserved | number | 保留字段(含伤害吸收等扩展用途) |
| NeedIdentify | number | 是否需要鉴定/日志标记(1=记录日志,4=金币,5=元宝) |
| Need | number | 需求属性值(配合 NeedLevel 使用,如需要多少攻击力/魔法力等) |
| UniqueItem | number | 唯一物品标记 |
| Overlap | number | 是否可堆叠(0=不可堆叠,1=可堆叠) |
| ItemType | number | 物品子类型 |
| ItemSet | number | 套装编号 |
| Binded | number | 是否绑定 |
获取保留扩展属性数组的指定索引值。
所属接口: StdItem
返回类型: number
功能说明: 读取保留字段中的扩展属性,可用于获取隐藏属性。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| index | number | 是 | 索引(0-8) |
返回值: 对应索引的值,越界返回 0。
示例代码:
const stdItem = userItem.getStdItem();
// 读取保留扩展属性
for (let i = 0; i < 9; i++) {
const val = stdItem.getReserve(i);
if (val > 0) {
serverLog(`保留属性[${i}] = ${val}`);
}
}
获取附加属性副本数组的指定索引值。
所属接口: StdItem
返回类型: number
功能说明: 读取附加属性副本中的值。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| index | number | 是 | 索引(0-9) |
返回值: 对应索引的值,越界返回 0。
示例代码:
const stdItem = userItem.getStdItem();
// 读取附加属性
for (let i = 0; i < 10; i++) {
const val = stdItem.getAddOn(i);
if (val > 0) {
serverLog(`附加属性[${i}] = ${val}`);
}
}
UserItem 是用户物品实例接口,代表玩家背包或装备栏中的一个具体物品。它在 StdItem 模板的基础上,增加了耐久度、极品属性、扩展属性和自定义悬浮框等功能。
| 属性名 | 类型 | 说明 |
|---|---|---|
| makeIndex | number | 制造索引(物品唯一标识) |
| wIndex | number | 物品索引(对应 StdItem 的索引) |
| dura | number | 当前耐久度 |
| duraMax | number | 最大耐久度 |
示例代码:
// 遍历玩家背包物品
const items = player.getBagItems();
for (const item of items) {
const std = item.getStdItem();
serverLog(`物品: ${std.Name}, 耐久: ${item.dura}/${item.duraMax}`);
serverLog(`制造索引: ${item.makeIndex}, 物品索引: ${item.wIndex}`);
}
获取极品属性数组的指定索引值。
所属接口: UserItem
返回类型: number
功能说明: 读取极品附加属性。极品属性是在基础属性之上的额外加成。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| index | number | 是 | 索引(0-25) |
极品属性索引含义:
| 索引 | 含义 | 索引 | 含义 |
|---|---|---|---|
| 0 | DC(物理攻击) | 1 | MC(魔法攻击) |
| 2 | SC(神圣攻击) | 3 | AC低(防御低) |
| 4 | MAC低(魔防低) | 5 | 幸运 |
| 6 | 攻击速度 | 7 | 神圣 |
| 8-9 | 套装属性 | 10 | 超级制造 |
| 13 | 改名标记 | 14 | 防爆 |
| 15-17 | 扩展附加属性 | 20 | 伤害吸收 |
| 22-25 | 绑定属性 |
返回值: 对应索引的值,越界返回 0。
示例代码:
// 检查物品极品属性
const items = player.getBagItems();
for (const item of items) {
const std = item.getStdItem();
const dc = item.getBtValue(0); // 极品物理攻击
const mc = item.getBtValue(1); // 极品魔法攻击
const sc = item.getBtValue(2); // 极品神圣攻击
const luck = item.getBtValue(5); // 幸运值
if (dc > 0 || mc > 0 || sc > 0) {
serverLog(`${std.Name}: DC+${dc} MC+${mc} SC+${sc} 幸运+${luck}`);
}
}
设置极品属性数组的指定索引值。
所属接口: UserItem
返回类型: void
功能说明: 设置指定索引的极品属性值。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| index | number | 是 | 索引(0-25) |
| value | number | 是 | 值(0-255) |
示例代码:
// 给物品添加极品属性
const item = player.getBagItems()[0];
if (item) {
item.setBtValue(0, 10); // DC+10
item.setBtValue(5, 3); // 幸运+3
serverLog('已为物品添加极品属性');
}
获取扩展属性数组的指定索引值(隐藏属性、技能属性等)。
所属接口: UserItem
返回类型: number
功能说明: 读取扩展隐藏属性,用于技能附加等高级功能。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| index | number | 是 | 索引(0-19) |
返回值: 对应索引的值,越界返回 0。
示例代码:
// 读取扩展隐藏属性
const item = player.getBagItems()[0];
if (item) {
for (let i = 0; i < 20; i++) {
const val = item.getBtValueEx(i);
if (val > 0) {
serverLog(`扩展属性[${i}] = ${val}`);
}
}
}
获取标准物品模板信息(不含极品附加属性)。
所属接口: UserItem
返回类型: StdItem
功能说明: 返回物品的基础模板数据,不包含极品属性的加成。
返回值: 标准物品模板对象。
示例代码:
const item = player.getBagItems()[0];
const stdItem = item.getStdItem();
serverLog(`物品名称: ${stdItem.Name}`);
serverLog(`基础攻击: ${stdItem.DC}`);
serverLog(`基础魔法: ${stdItem.MC}`);
serverLog(`物品类型: ${stdItem.StdMode}`);
获取合成后的完整物品属性(含极品附加属性)。
所属接口: UserItem
返回类型: StdItem
功能说明: 将极品属性叠加到 StdItem 基础属性上,返回完整的属性数据。
返回值: 含附加属性的完整标准物品信息。
示例代码:
const item = player.getBagItems()[0];
const stdItem = item.getStdItem(); // 基础属性
const fullItem = item.getAddValue(); // 含极品加成的完整属性
serverLog(`基础DC: ${stdItem.DC}, 完整DC: ${fullItem.DC}`);
serverLog(`基础MC: ${stdItem.MC}, 完整MC: ${fullItem.MC}`);
serverLog(`基础SC: ${stdItem.SC}, 完整SC: ${fullItem.SC}`);
检查物品是否可以被指定角色穿戴。
所属接口: UserItem
返回类型: boolean
功能说明: 检查物品的等级需求、属性需求等是否满足穿戴条件。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| actor | any | 是 | 角色对象 |
返回值: 可以穿戴返回 true,否则返回 false。
示例代码:
const item = player.getBagItems()[0];
if (item.canWear(player)) {
serverLog('该物品可以穿戴');
} else {
player.sendMessage('你的条件不满足,无法穿戴此物品!');
}
检查物品是否可以被指定角色使用。
所属接口: UserItem
返回类型: boolean
功能说明: 检查物品的使用条件是否满足(如等级限制、职业限制等)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| actor | any | 是 | 角色对象 |
返回值: 可以使用返回 true,否则返回 false。
示例代码:
subscribe(EventType.ItemUse, (event: ItemUseEvent) => {
const item = event.item;
if (!item.canUse(event.player)) {
event.player.sendMessage('条件不足,无法使用此物品!');
return false;
}
});
UserItem 提供了一套基于键值对的扩展属性系统,允许脚本为物品附加自定义数据。这些数据会持久化保存。
读取单个扩展属性。
所属接口: UserItem
返回类型: any
功能说明: 根据键名读取扩展属性值。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | string | 是 | 属性键名 |
返回值: 属性值,不存在返回 undefined。
设置单个扩展属性。
所属接口: UserItem
返回类型: void
功能说明: 设置指定键名的扩展属性值。如键名已存在则覆盖。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | string | 是 | 属性键名 |
| value | any | 是 | 属性值 |
删除单个扩展属性。
所属接口: UserItem
返回类型: void
功能说明: 删除指定键名的扩展属性。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | string | 是 | 属性键名 |
获取所有扩展属性。
所属接口: UserItem
返回类型: string
功能说明: 返回所有扩展属性的 JSON 字符串。
返回值: 所有扩展属性的 JSON 字符串,如 '{"力量":100,"敏捷":50}'。
批量设置扩展属性。
所属接口: UserItem
返回类型: void
功能说明: 通过 JSON 字符串批量设置扩展属性。已有键被覆盖,其他键不变。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| jsonAttrs | string | 是 | JSON 字符串,如 '{"力量":100,"敏捷":50}' |
扩展属性综合示例:
// 给物品添加自定义扩展属性
const item = player.getBagItems()[0];
if (item) {
// 设置单个扩展属性
item.setExtAttr('强化等级', 5);
item.setExtAttr('附加经验', 1000);
item.setExtAttr('拥有者', player.name);
// 读取单个扩展属性
const level = item.getExtAttr('强化等级');
serverLog(`强化等级: ${level}`);
// 批量设置扩展属性
item.setExtAttrs('{"镶嵌宝石": "红宝石", "宝石等级": 3}');
// 获取所有扩展属性
const allAttrs = item.getExtAttrs();
serverLog(`所有扩展属性: ${allAttrs}`);
// 删除扩展属性
item.delExtAttr('附加经验');
}
UserItem 支持自定义悬浮提示框,允许脚本完全控制物品的鼠标悬浮显示内容。
获取自定义悬浮框排版文本。
所属接口: UserItem
返回类型: string
功能说明: 返回当前的自定义悬浮框渲染指令文本,空字符串表示无自定义显示。
设置自定义悬浮框排版文本。
所属接口: UserItem
返回类型: void
功能说明: 设置物品的自定义悬浮提示框内容。支持两种格式:旧版标记语法和 JSON 排版语法。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| text | string | 是 | 渲染指令文本,单条最大约 64KB |
JSON 排版格式详解:
// JSON 排版格式结构
{
container: {
width?: number, // 固定宽度(像素),不设则自动计算
maxHeight?: number, // 最大高度(像素),超出裁剪并追加省略号
padding?: number, // 内边距(像素),默认 8
bgColor?: string | number, // 背景色: "clRed" | "#FF0000" | 253,默认浅灰
alpha?: number, // 背景透明度 0-255,默认 255(不透明)
border?: { // 边框配置(可选)
color?: string | number, // 边框颜色,默认 85(深灰)
width?: number // 边框宽度 1/2/3,默认 1
},
bgImage?: { // 容器底图(可选,优先于纯色背景)
lib: number, // registerImageLibrary 返回的素材库编号
index: number, // 起始图片索引
anim?: { // 帧动画(可选)
frames: number, // 动画总帧数
speed: number // 帧间隔(毫秒)
}
}
},
lines: [ // 行列表,每行占一行高度(14px)
// 文本段
{
type?: "text", // 默认可省略
text: string, // 显示文本
color?: string | number, // 文字颜色
size?: number, // 字号,默认 10
bold?: boolean, // 粗体
italic?: boolean, // 斜体(以粗体渲染)
underline?: boolean, // 下划线
left?: number, // 水平偏移(像素)
top?: number // 垂直偏移(像素)
},
// 分割线段
{
type: "separator", // 水平分割线
color?: string | number // 线条颜色,默认灰色
},
// 图片段
{
type: "image",
lib: number, // 素材库编号
index: number, // 图片索引
width?: number, // 显示宽度(像素)
height?: number, // 显示高度(像素)
left?: number, // 水平偏移(像素)
top?: number, // 垂直偏移(像素)
anim?: { // 帧动画(可选)
frames: number,
speed: number
}
},
// 进度条段
{
type: "progress",
lib: number, // 素材库编号
index: number, // 进度条底图索引
rate: number, // 当前值
max: number, // 最大值
height?: number, // 显示高度(像素)
text?: string, // 进度文字
color?: string | number, // 进度文字颜色
left?: number, // 水平偏移(像素)
top?: number // 垂直偏移(像素)
},
// 多段行(数组,段之间水平排列在同一行)
[
{ type: "image", lib: 0, index: 0, width: 16, height: 16 },
{ text: " 描述文字", color: "clRed", size: 10 }
]
]
}
悬浮框示例代码:
// 示例1:简单的文本悬浮框
const item = player.getBagItems()[0];
const hintText = JSON.stringify({
container: {
width: 200,
bgColor: "clBlack",
alpha: 200,
border: { color: "clYellow", width: 1 }
},
lines: [
{ text: "【神器】屠龙刀", color: "clYellow", size: 12, bold: true },
{ type: "separator" },
{ text: "物理攻击: 50-100", color: "clWhite" },
{ text: "需要等级: 40", color: "clGray" },
{ text: "强化等级: +5", color: "clLime" }
]
});
item.setCustomHintText(hintText);
// 示例2:带图片和进度条的悬浮框
const itemLib = registerImageLibrary('Items.wil');
const hint2 = JSON.stringify({
container: {
width: 250,
bgColor: "#1a1a2e",
alpha: 230,
padding: 10,
border: { color: "#e94560", width: 2 }
},
lines: [
[
{ type: "image", lib: itemLib, index: 10, width: 20, height: 20 },
{ text: " 神秘宝箱", color: "clGold", size: 13, bold: true }
],
{ type: "separator", color: "#e94560" },
{ text: "开启进度:", color: "clSilver" },
{
type: "progress",
lib: itemLib,
index: 20,
rate: 75,
max: 100,
height: 16,
text: "75/100",
color: "clWhite"
},
{ text: "剩余时间: 2小时", color: "clAqua" }
]
});
item.setCustomHintText(hint2);
// 示例3:旧版标记语法
item.setCustomHintText('<神器之刃|C=clYellow S=12 B=Bold>\\-\\<攻击力+50|C=clRed S=10>');
以下提供几个物品系统的综合使用场景。
// 查询物品的完整属性信息
function showItemDetail(player: any, item: UserItem): void {
const std = item.getStdItem(); // 基础属性
const full = item.getAddValue(); // 含极品加成
player.sendMessage(`物品名称: ${std.Name}`);
player.sendMessage(`物品类型: ${std.StdMode}`);
player.sendMessage(`耐久度: ${item.dura}/${item.duraMax}`);
player.sendMessage(`基础攻击: ${std.DC} → 实际攻击: ${full.DC}`);
player.sendMessage(`基础魔法: ${std.MC} → 实际魔法: ${full.MC}`);
player.sendMessage(`基础道术: ${std.SC} → 实际道术: ${full.SC}`);
player.sendMessage(`防御: ${full.AC} / 魔防: ${full.MAC}`);
player.sendMessage(`需求等级: ${std.NeedLevel}`);
player.sendMessage(`价格: ${std.Price}`);
// 极品属性检测
const dc = item.getBtValue(0);
const mc = item.getBtValue(1);
const sc = item.getBtValue(2);
const luck = item.getBtValue(5);
if (dc > 0 || mc > 0 || sc > 0 || luck > 0) {
player.sendMessage('--- 极品属性 ---');
if (dc > 0) player.sendMessage(`物理攻击+${dc}`);
if (mc > 0) player.sendMessage(`魔法攻击+${mc}`);
if (sc > 0) player.sendMessage(`道术攻击+${sc}`);
if (luck > 0) player.sendMessage(`幸运+${luck}`);
}
}
// 简单的物品强化系统
function upgradeItem(player: any, item: UserItem): boolean {
const cost = 100; // 强化消耗金币
const currencyType = 1; // 金币
// 检查金币是否足够
if (!player.checkCurrency(currencyType, cost)) {
player.sendMessage('金币不足,强化失败!');
return false;
}
// 扣除金币
player.decCurrency(currencyType, cost);
// 随机强化(50%成功率)
const success = Math.random() > 0.5;
if (success) {
// 增加极品攻击属性
const currentDc = item.getBtValue(0);
item.setBtValue(0, currentDc + 1);
// 更新扩展属性中的强化等级
const level = (item.getExtAttr('强化等级') || 0) as number;
item.setExtAttr('强化等级', level + 1);
player.sendMessage(`强化成功!当前强化等级: +${level + 1}`);
// 更新悬浮框
updateItemHint(item);
return true;
} else {
player.sendMessage('强化失败!');
return false;
}
}
// 更新物品悬浮框
function updateItemHint(item: UserItem): void {
const std = item.getStdItem();
const full = item.getAddValue();
const level = (item.getExtAttr('强化等级') || 0) as number;
const hintText = JSON.stringify({
container: {
width: 200,
bgColor: "clBlack",
alpha: 200,
border: { color: level >= 5 ? "clGold" : "clGray", width: 1 }
},
lines: [
{ text: `${std.Name} +${level}`, color: level >= 5 ? "clGold" : "clWhite", size: 12, bold: true },
{ type: "separator" },
{ text: `攻击: ${full.DC}`, color: "clRed" },
{ text: `魔法: ${full.MC}`, color: "clBlue" },
{ text: `强化等级: +${level}`, color: level >= 5 ? "clLime" : "clSilver" }
]
});
item.setCustomHintText(hintText);
}
// 监听物品使用事件,实现自定义药水效果
subscribe(EventType.ItemUse, (event: ItemUseEvent) => {
const player = event.player;
const item = event.item;
const stdItem = item.getStdItem();
// 根据物品名称判断特殊效果
if (stdItem.Name === '双倍经验丹') {
// 读取扩展属性中的经验倍率
const rate = item.getExtAttr('经验倍率') || 2;
const duration = item.getExtAttr('持续时间') || 3600;
player.sendMessage(`使用双倍经验丹,${duration}秒内经验翻${rate}倍!`);
// 这里可以添加实际的buff逻辑
}
// 根据物品子类型判断
if (stdItem.ItemType === 1) {
// 特殊类型物品的处理逻辑
serverLog(`玩家 ${player.name} 使用了特殊物品: ${stdItem.Name}`);
}
});
本章汇总了使用 FlexCore-TS-SDK 开发时的常见注意事项、最佳实践和常见问题。
export const MODULE_TAG 声明唯一标签(非必须,但不要重复),以便通过 GameLib.reloadByTag() 进行热重载import加载// 推荐的模块声明方式
export const MODULE_TAG = 101; // 每个模块使用不同的数字标签
GameLib.reloadAllScripts() 或 GameLib.reloadByTag() 进行热重载GameLib.startFileWatch() 监控文件变化自动重载TimerPriority.HIGH,非关键逻辑使用 TimerPriority.LOWEventModifyResult 对象false 都会拦截unsubscribe() 清理sendMsgToUser() 发送带选项的对话框,玩家选择后触发对应事件(后续会json化)checkCurrency() 检查余额是否充足A: 可以通过以下方式:
GameLib.reloadAllScripts() - 重载所有脚本GameLib.reloadScriptModule('模块名') - 重载指定模块GameLib.reloadByTag(MODULE_TAG) - 通过标签重载GameLib.startFileWatch() 自动监控A: 使用 serverLog() 输出调试信息到服务端日志,日志会显示在服务端控制台中。
A: 可以,但注意异步回调的返回值不会被事件系统检查。需要拦截事件时必须使用同步回调。
A: 使用 UserItem.getAddValue() 而不是 getStdItem(),前者会将极品属性叠加到基础属性上。
A: 定时器回调函数中的 this 取决于函数的声明方式,箭头函数捕获定义时的 this,普通函数的 this 为 undefined。建议使用箭头函数。
A: setExtAttr 接受 any 类型,但建议使用基本类型(string、number、boolean),复杂对象需要先序列化为 JSON 字符串。
文档版本:FlexCore-TS-SDK API 参考文档 v1.0
生成日期:2026-05-12
覆盖模块:actor, common, environment, event, game, guild, hero, magic, monster, npc, playobject, stditem, useritem