结构定义

Table of contents


例子:任务表

以下是个任务表的结构,通过这个例子来说明

struct Range {
	rmin:int; // 最小
	rmax:int; // 最大
}

struct RewardItem {
	chance:int; // 掉落概率
	itemids:list<int> ->item.item (fix=2); // 掉落物品
	range:Range; // 数量下限
}

struct Time (sep=':'){
    hour:int;
    minute:int;
    second:int;
}

interface completecondition (enumRef='completeconditiontype') {
	struct KillMonster {
		monsterid:int ->npc.monster;
		count:int;
	}

	struct TalkNpc {
		npcid:int ->npc.npcid;
	}

	struct ConditionAnd {
		cond1:task.completecondition (pack);
		cond2:task.completecondition (pack);
	}

	struct CollectItem {
		itemid:int ->item.item;
		count:int;
	}
}

interface taskexp (enumRef='taskexptype', defaultImpl='ConstValue', pack) {
    struct ByLevel { // 玩家等级相关 
		levelcoef:float;
		value:int;
	}

	struct ByServerUpDay { // 服务器启动天数相关
		updaycoef1:float;
		updaycoef2:float;
		value:int;
	}
	
	struct ConstValue { // 固定值
	    value:int;
	}
}

table completeconditiontype[id] (enum='name') {
	id:int; // 任务完成条件类型
	name:str; // 程序用名字
}

table taskexptype[id] (enum='name') {
	id:int; // 经验公式类型
	name:str; // 程序用名字
}

table task[taskid] (entry='entry') {
	taskid:int ->task.taskextraexp (nullable); // 任务id
	entry:str;
	text:text; // 需要国际化的文本
	nexttask:int ->task (nullable);
	completecondition:task.completecondition; // 任务完成条件
	exp:taskexp;  // 经验奖励
	rewardItems:list<RewardItem> (block=1); // 物品奖励
	time:Time; 
	[nexttask];
}

结构化支持

struct:定义结构

  • struct后接结构体名称,然后在{}里每行定义field或外键
  • field:字段名名字后面加:,然后是字段类型
  • 字段类型:
    • 基本类型primitive:bool,int,float,long,str,text
    • 聚合:struct,interface
    • 容器:list,map
  • 字段类型后可以接->,表明是外键,后接table名称,如果不是指向table的主键,则要接[],[]内含table的唯一键
  • 字段类型后可以接=>,后接table名称[],[]内含table的field名称 这里扩展了数据库的外键含义, 用=>表明不一定指向table的唯一键,而是任意字段,生成的程序代码会返回listRefXxx,是个列表。
  • {}内行如果以->开头,表明是外键,->后接一个identifier,然后:,然后[],[]内是字段名列表,然后是->或=>,之后跟字段类型后接的一致。
  • list类型配置外键时,表明list里每个item的外键
  • map类型配置外键时,表明时map里每个value的外键,(不支持key的外键配置)

RewardItem的range结构是Range,这是对嵌套结构的支持。

RewardItem.itemids 里配置->item.item,表明这个list<int>里每个int都指向item.item表。

KillMonster.monsterid 设置->npc.monster, 表明这个id是个外键,指向npc.monster表。

interface:定义接口

  • interface内定义struct做为此接口的实现类
  • interface后面()内可以加enumRef属性,指向一个表名,这个表里会有其实现类的信息, 假如这个表策划用excel来配,则有enumRef后策划可以不用看.cfg文件。这个表必须包含其实现类的名称,也可以给id,可以包含任意额外信息。
  • ()内可以加defaultImpl属性,指向一个此接口实现类,如果有这个属性,则excel中可以不配置这个属性,此时程序会读成这个默认实现。
  • 如果defaultImpl指向的结构,只包含一个数字或bool,并且此interface是pack,则excel中可以直接写一个数字,此时程序会读成这个默认实现,里面字段为此数字。

completecondition是任务的完成条件,其中ConditionAnd里的有字段其类型又是completecondition,形成了环,这样结构就是任意复杂的了。

taskexp是任务经验值公式。task表中经验奖励的格子可以大多数情况下只写数字就可以了,代表ConstValue。如果需要公式可以配置为ByLevel(10, 100),服务器读到这个结构可以用公式 role.level() * levelcoef + value得到具体的经验值。

table:定义excel文件对应的结构

  • 表名后[]内是此表的主键
  • {}内每行如果以[开始,以]结束, 则表示是在定义唯一键
  • 否则跟struct相同每行定义field或外键。
  • 表名[主键]后的()内可以包含enum,指向field名称,表明此表是个枚举表,excel中这一列由程序员来填写,每行都要填
  • 表名[主键]后的()内可以包含entry,指向field名称,这个会为程序生成静态成员变量,方便代码访问。 excel中这一列由程序员来填写,只有少数行需要填写。

task表的[taskid]:主键是第一列taskid

task表{}里的最后一行[nexttask]:定义了唯一键,会生成对应的访问代码GetByNextTask,给出nextTaskId,查找到task

task表的(entry=’entry’’),表明有其中一些行,程序代码需要访问,在对应行的第二列entry由程序来填上名字。

taskexptype表中的(enum=’name’),表明这是个枚举表,excel数据要包含3行,第二列name里的字符串要分别是taskexp中的struct名字:ByLevel,ByServerUpDay,ConstValue