一、Lua脚本功能接口

1. LuaInterface.h/.cpp声明和实现LuaInterface。

LuaInterface成员如下:

//脚本引擎

FoxLuaScript mLua ;

//注册器

LuaCFuncRegister mFuncRegister;

//场景关联

Scene* mOwner;

//已经读取的脚本表

IDTable m_ScriptTable ;

主要方法:

VOID Init(Scene* pScene);//完成Lua脚本环境的初始化和C导出函数的注册

Scene* GetOwner();

执行Lua脚本的C++接口,提供多达8个参数支持。

INT ExeScript( ScriptID_t scriptid, CHAR* funcname ) ;

INT ExeScript_D( ScriptID_t scriptid, CHAR* funcname, INT Param0 ) ;

INT ExeScript_DD( ScriptID_t scriptid, CHAR* funcname, INT Param0, INT Param1 ) ;

INT ExeScript_DDD( ScriptID_t scriptid, CHAR* funcname, INT Param0, INT Param1, INT Param2 ) ;

INT ExeScript_DDDD( ScriptID_t scriptid, CHAR* funcname, INT Param0, INT Param1, INT Param2, INT Param3 ) ;

LuaInterface::Init里面会初始化mLua引擎,注册C++提供给Lua脚本的函数(LuaCFuncRegister),并加载ScriptGlobal.lua脚本。

2. LuaCFuncRegister.cpp里面对所有导出到Lua的C++函数进行注册。

struct _Str2Func functbl[] =

{

{"AddEventList",FuncProto(LuaFnAddNumText)},

{"GetMission", FuncProto(LuaFnGetMission)},

{"GetMissionCount", FuncProto(LuaFnGetMissionCount)},

{"SetMissionByIndex", FuncProto(LuaFnSetMissionByIndex)},

{"AddMission", FuncProto(LuaFnAddMission)},

{"AddMissionEx", FuncProto(LuaFnAddMissionEx)},

{"SetMissionEvent", FuncProto(LuaFnSetMissionEvent)},

...

};

这些C++函数的实现是在下列头文件中进行的:

#include "LuaFnTbl_Mission.h"

#include "LuaFnTbl_Misc.h"

#include "LuaFnTbl_Ability.h"

#include "LuaFnTbl_Attr.h"

#include "LuaFnTbl_Pet.h"

#include "LuaFnTbl_Battle.h"

#include "LuaFnTbl_Shop.h"

#include "LuaFnTbl_PetPlacard.h"

#include "LuaFnTbl_Scene.h"

#include "LuaFnTbl_Team.h"

#include "LuaFnTbl_DoAction.h"

#include "LuaFnTbl_Relation.h"

#include "LuaFnTbl_Guild.h"

#include "LuaFnTbl_City.h"

这些函数并不是功能的真正实现地方,真正的实现代码在Scene、Obj_Human等地方。这里只是集中转调而已。

3. 注册完成后,在Lua脚本中就可以使用类似AddMission接口调用C++里面功能。

二、Lua脚本位置

所有脚本在Bin\Public\Data\Script子目录中。

Bin\Public\Data\Script.dat是索引,里面保存了ScriptID和对应的脚本文件名。如:

888888=\scene.lua

888889=\mail.lua

888890=\player_login.lua

...

脚本ID是6位的。

三、脚本索引的初始化

每个场景都会进行脚本初始化,具体是在Scene::Load里面,在在m_pLuaInterface初始化之后。

m_pLuaInterface->Init(this);

if( !m_pScriptFileMgr->IsInit() )

{

m_pScriptFileMgr->Init( FILE_SCRIPT, FALSE);

}

Log::SaveLog( SERVER_LOGFILE, "Load ../Public/Data/script.dat OK!" );

m_pScriptFileMgr->Init将"888888=\scene.lua"拆开,保存ID和文件名到SFileData里面。所有的SFileData用SFileDataLink串起来。

四、脚本加载和调用

每个脚本的调用都是通过INT LuaFnCallScriptFunction(Lua_State* L);来进行的。该函数是一个C++函数,脚本里面调用名是CallScriptFunction,注册如下:

{"CallScriptFunction", FuncProto(LuaFnCallScriptFunction)},

LuaFnCallScriptFunction的实现在文件LuaFnTbl_Misc.h里。

可以看到在,此函数:

l 把SFileData添加到pScene->GetLuaInterface()->m_ScriptTable表里面;

pSFileData = pScene->GetLuaInterface()->GetOwner()->GetScriptFileMgr()->GetFileData(scriptId);

pScene->GetLuaInterface()->m_ScriptTable.Add( scriptId, pSFileData ) ;

l 然后加载脚本;

pScene->GetLuaInterface()->mLua.Load( const_cast<CHAR*>(filename) ) ;

l 最后调用脚本。

五、典型脚本的结构

见ScriptDef.h,定义了一些脚本接口函数,如OnDefaultEvent,对于脚本805007,就是:

function x805007_OnDefaultEvent( sceneId, selfId,targetId );

有一些调用没有在这里定义宏,直接写在C++代码里面,如OnScenePlayerLogin。

#define DEF_EVENT_ENTRY_FUNC_NAME ("OnDefaultEvent") //脚本进入函数

#define DEF_ON_KILL_OBJECT_FUNC_NAME ("OnKillObject")

#define DEF_ON_ITEM_CHANGED_FUNC_NAME ("OnItemChanged")

#define DEF_ON_PET_CHANGED_FUNC_NAME ("OnPetChanged")

#define DEF_ON_ENTER_AREA_FUNC_NAME ("OnEnterArea")

#define DEF_ON_LEAVE_AREA_FUNC_NAME ("OnLeaveArea")

#define DEF_EVENT_ON_TIMER ("OnTimer")

#define DEF_MISSION_ACCEPT ("OnMissionAccept") //接受任务

#define DEF_MISSION_ABANDON ("OnAbandon") //放弃任务

#define DEF_MISSION_REFUSE ("OnMissionRefuse") // 拒绝接受任务

#define DEF_MISSION_SUBMIT ("OnMissionSubmit") //任务完成后,提交任务

#define DEF_MISSION_CHECK ("OnMissionCheck") //任务完成条件检查

#define DEF_MISSION_CONTINUE ("OnMissionContinue") //任务没完成,继续

六、样例分析

大理NPC赵天师脚本分析

脚本名:Script\obj\dali\odali_xinshoutian.lua,汗,居然叫这个名字,找了半天,一般的命名都是拼音。

--赵天师

--脚本号

x002030_g_scriptId = 002030

--所拥有的事件ID列表

x002030_g_eventList={210200,210204,210205,210208,210210,210212,210213,210214,210216,210217,210220,210223, 210224, 210225, 210229, 210230, 210232, 210238, 210239, 210237, 210240, 200080, 200083, 200086, 200091, 200094,200095,210241,050022}

一般情况,每个event对于一个任务,也是一段脚本实现的。如210200对于:

;大理城新手指导任务

210200=\event\dali\edali_zhidao_0200.lua

--找人任务

--赵天师寻找蒲良

NPC脚本触发接口函数是xxx_OnDefaultEvent,在AI_Human的PushCommand_DefaultEvent里面触发。

ORESULT PushCommand_DefaultEvent( ObjID_t idNPC );

pCharacter->getScene()->GetLuaInterface()->ExeScript_DDD(

idScript,

DEF_EVENT_ENTRY_FUNC_NAME,

(INT)pCharacter->getScene()->SceneID(),

(INT)pCharacter->GetID(),

(INT)pNPC->GetID() ) ;

天龙八部服务器端Lua脚本系统相关推荐

  1. 天龙八部服务端Lua脚本系统(转)

    一.Lua脚本功能接口 1. LuaInterface.h/.cpp声明和实现LuaInterface. LuaInterface成员如下: //脚本引擎 FoxLuaScript mLua ;//注 ...

  2. lua游戏脚本实例源码_Lua脚本引擎教程(六):饥荒Lua脚本系统

    目录 饥荒的Lua逻辑层架构 迁移到Unity中使用Lua Lua擅长什么? 饥荒的Lua逻辑层架构 饥荒的整个逻辑层都是用Lua写的,并且把代码和艺术资产都开放给玩家,主要是供玩家中的mod制作者学 ...

  3. 在windows程序中嵌入Lua脚本引擎--建立一个简易的“云命令”执行的系统

    在<在windows程序中嵌入Lua脚本引擎--使用VS IDE编译Luajit脚本引擎>开始处,我提到某公司被指责使用"云命令"暗杀一些软件.本文将讲述如何去模拟一个 ...

  4. lua软件测试自动化,一种基于Lua脚本的嵌入式软件自动化测试系统及方法专利_专利查询 - 天眼查...

    1.一种基于Lua脚本的嵌入式软件自动化测试系统,其特征在于,所述系统包括:目标 测试系统及测试主控系统,其中: 目标测试系统包括: 标准化的软件接口 :用于与被测对象进行数据交换: Lua解析器:用 ...

  5. Redis Lua脚本中学教程(上)

    失踪人口回来啦! 有读者问我为什么这么久都没有出Redis Lua中学教程,表示村头厕所已经好久没有纸了.其实我早就要写这篇中学教程了,奈何最近太忙了,就一拖再拖,直到今天我终于又开始动笔了.忘记Lu ...

  6. lua游戏脚本实例源码_Redis Lua脚本中学教程(上)

    失踪人口回来啦! 有读者问我为什么这么久都没有出Redis Lua中学教程,表示村头厕所已经好久没有纸了.其实我早就要写这篇中学教程了,奈何最近太忙了,就一拖再拖,直到今天我终于又开始动笔了.忘记Lu ...

  7. 高性能分布式缓存Redis(缓存分类 安装 数据类型选择和应用场景 发布订阅 事务 Lua脚本 慢查询日志)

    高性能分布式缓存Redis 高性能分布式缓存Redis 1. 缓存发展史&缓存分类 1.1 大型网站中缓存的使用 1.2 常见缓存的分类 1.3 分布式缓存选型方案对比 2. Redis概述& ...

  8. Redis:EVAL执行Lua脚本

    EVAL 脚本 numkeys 键[键...] arg [arg ...] 自Redis2.6.0版本起可用. 时间复杂度:取决于执行的脚本. EVAL介绍 EVAL和EVALSHA用于从Redis2 ...

  9. Redis Lua脚本的详细介绍以及使用入门

    Redis Lua脚本的详细介绍以及使用入门. 文章目录 Redis Lua脚本的引入 开源软件的可扩展性 Redis的扩展性脚本 Redis Lua脚本的基本使用 通过EVAL命令执行Lua脚本 通 ...

最新文章

  1. github后端开发面试题大集合(一)
  2. R语言计算曼哈顿距离(Manhattan Distance)实战:计算两个向量的曼哈顿距离、dist函数计算矩阵中两两元素的曼哈顿距离
  3. mysql decode语句_mysql数据灾难恢复方案
  4. ICE简单介绍及使用示例
  5. filesaver.js 保存文件路径_iOS把UIImage保存到沙盒目录下以及沙盒目录概述
  6. postgres安装02--postgis
  7. Windows常用软件列表(2012.03 Update)
  8. 韩寒 一个 新版本 android 收藏,韩寒的应用《ONE·一个》正式登陆Android平台,韩寒称一年运营成本约250万...
  9. python计时器单位,python(计时器)
  10. 隐式类型转换中显式申明的非必要性
  11. java考前复习之数组
  12. 宿华辞任快手CEO 联合创始人程一笑接任
  13. qt connect函数_Qt Inside信号和槽之connect
  14. Q113:PBRT-V3分别在Linux和Mac下的编译与调试(汇总)
  15. android 支付宝私钥加密,支付宝支付密钥RSA1升级到RSA2
  16. 催收行业再现“暴力(利)”
  17. h5压缩图片 亲测有效
  18. ios 抓娃娃开发_可爱抓娃娃ios版_可爱抓娃娃手机版1.0.4 - 系统城
  19. 华氏度摄氏度温度转换
  20. ROS源代码阅读(9)——DWA算法

热门文章

  1. mysql 触发器 模板_MySQL 触发器例子(两张表同步增加和删除)
  2. rospy基础--001_talker_listener
  3. libusb系列-007-Qt下使用libusb1.0.26源码
  4. java服务程序假死(进程存在但请求无响应)的几种原因
  5. Microsoft Edge (92.0.902.55 ) 打印(window.print) 卡死/无响应
  6. datax(10): 源码解读Communication(Datax通讯类)
  7. 什么是stub文件_stub code
  8. Network Slimming——有效的通道剪枝方法(Channel Pruning)
  9. Cython的学习方法
  10. 简单讲解前序遍历,中序遍历,后序遍历和层次遍历