|
1) 最简单的房间的撰写
最简单的房间是什么?就是里面什么都没有,机关,人物(npc),物品,什么都没有
比如说就是一条路上的一
程序举例如下:(//表示注释)
// Room: /d/snow/eroad1.c //程序开头注一下,说明是什么文件,在什么地方
inherit ROOM; //继承 ROOM 类
void create() // 创建函数;在里面定义各种属性
set("short", "黄土小径"); // 房间的 短描述
set("long", @LONG // 房间的长描述
这是一条普通的黄土小径,弯弯曲曲往东北一路盘旋上山,北边有
一间城隍庙,往西则是雪亭镇的街道。 //@LONG&LONG是一对宏,表示里面是字符串
LONG
);
set("exits", ([ /* sizeof() == 3 */ // 设房间出口
"northeast" : "/d/snow/eroad2", // 不同的方向指令,跳转到
"north" : "/d/snow/temple", // 不同的房间
"west" : "/d/snow/sroad1", // 注意,不加 .c 后缀
]));
set("outdoors", "snow"); // 是雪淳镇的室外
setup(); //不用管它,照抄就是
replace_program(ROOM);
2) 房间的物品和门
最简单的房间说完了,就再复杂一点儿加上 物品定义,和物品拿枋?还有建个门吧
还是举例说明
// inn.c
#include
inherit ROOM;
string look_sign(object me); // 函数原型定义
void create()
set("short", "饮风客栈");
set("long", @LONG
你现在正站在雪亭镇南边的一家小客栈里,这家客栈虽小,却是方圆
五百里内最负盛名的一家,客栈的主人据说是一位云游四海的仙人,如果
你的福缘深厚的话,也许可以在这里遇到他。除此之外,来自各地的旅人
都喜欢聚集在这里交换旅途上的见闻,你也可以在这里打听到许多有趣的
消息。靠近门口的地方有一块乌木雕成的招牌(sign)。
西北边有一个红木门(door),门上泛著一层白色的光晕,一种令人感
觉很有力量,又很柔和的光芒。
LONG
);
// This enables players to save this room as their startroom.
set("valid_startroom", 1); //使该房间可以成为下一次进来的地方
set("item_desc", ([
"sign": (: look_sign , // 物品(其实不是物品)描述
// 只是一个记号而已,玩家可以用 look sign 来看你的描述 , 不是实际存在的物品
// 冒号左边的是名称,右边的是描述 如 :
// "pillar" : "石柱上刻著:剑气指天、剑心内敛、剑芒不显、剑神如电。"
// 玩家 look pillar 是,就会出来 后面跟的话
// 如果你想叫玩家look 时,去调一个函数,就后面跟一个 (: 函数名 
"door": (: look_door, "northwest" ,
// 这里调的就是look_door函数,参数是northwest
]) );
set("exits", ([
"east" : "/d/snow/square",
"up" : "/d/snow/inn_2f",
"northwest" : "/d/wiz/entrance" ]) );
// 下面是定义房间里的NPC, 这就是一个店小二啦
set("objects", ([
"/d/snow/npc/waiter" : 1 ]) ); // 后面的1, 就是一个的意思
// 创建房间的门, 平时是关闭的
create_door("northwest", "木门", "southeast", DOOR_CLOSED);
setup();
// 建一个公告板,是另一个地方定义的函数
// To "load" the board, don't ever "clone" a bulletin board.
call_other( "/obj/board/common_b", "???" );
// look sign时调用,根据玩家的级别返回描述
string look_sign(object me) // me是一个对象,指向动作的主人
// 这里的me是参数,如果没有这个参数,
// 可以在函数里用
// object me; me = this_player();定
if( wizardp(me) ) // wizardp(me) 是一个efun, 是mudos 定义的
// 判断me这个对象是否是巫师
return "招牌写著:饮风客栈。旁边一排小字:庄思哑题。\n";
else
return "招牌写著:饮风客栈。\n";
3) 人物创作入门
每一个人物都需要单独的一个*.c文件,由其所在房间的源码调用.前面已经说过
一般来说,NPC放在npc各个地方的npc目录下,如 /d/snow/npc下是雪淳镇的npc
记住一点就是:NPC其实和玩家是一样的,只不过是电脑控制而已,
玩家有的各项值它都有,而且比如说,fight的时候,它也会涨经验值的
也会慢慢恢复. 所以它可以用command来执行命令.
举例说明:
::::::::::::::
fist_trainer.c
::::::::::::::
// trainer.c
inherit NPC; // 继承 NPC类
void create()
set_name("李火狮", ({ "trainer", "lee" }) ); //设NPC名字和中文名字
^^^^^^^^^|^^^^^
+-------就是有两个名字,哪个都可以
set("title", "拳法教练"); // 头
set("gender", "男性" ); // 性别
set("age", 28); // 年龄
set("str", 26); // str, int 都是天赋值
set("int", 14);
set("long", // 人物的长描述,当玩家look trainer时
// 显示该描述
"李火狮是个孔武有力的大块头,他正在训练他的弟子们习练「柳家拳\n"
"法」(liuh-ken)。\n" );
set("combat_exp", 3000); // 人物的实战经验
set("attitude", "heroism"); // 好战态度
set("force", 120); // 内力值
set("max_force", 120); // 最大内力
set("force_factor", 1); // 一次发出多少点内力
set("inquiry", ([ // 玩家ask 时的反应
"here": "这里当然是淳风武馆,不然还是哪里?\n",
// 如上句, 玩家ask trainer about here 就会出后面的话
"name": "在下姓李,名字就叫火狮,人称李教头的便是我。\n",
"柳家拳法": "哦….说来惭愧,小弟这套拳法还没学得到家,
柳馆主就教我在这里传艺。\n"
]) );
set_skill("unarmed", 30); // 设置各项武功技能
set_skill("liuh-ken", 20);
set_skill("dodge", 30);
map_skill("unarmed", "liuh-ken"); // enable 柳家拳法
setup();
int recognize_apprentice(object ob) // 接受玩家拜师时的反应
if( (string)ob->query("family/family_name")=="封山剑派" ) return 1;
^^^^^^^^^^^^|^^^^^^^^^^^^
+---------------查询玩家的派别
command("say 对不起,这位" + RANK_D->query_respect(ob) +
^^^^^^^^^^^|^^^^^^^^^^^^
+---对象ob, 就是玩家,的头衔
",您不是我们武馆的弟子。");
return notify_fail( "李火狮不愿意教你拳法。\n");
^^^^^|^^^^^
+-------这是一个很有用的函数,就是给出错误信息
int accept_fight(object me) // 接受玩家fight时调用
if( (string)me->query("family/family_name")=="封山剑派" ) {
command("say 进招吧。");
return 1;
}
command("say 馆主吩咐过,不许和来这里的客人过招。");
return 0;
4) 几个零散的问题
*******************************************
1. NPC怎么有货物?
*******************************************
如店小二,在create()函数里定义
set("vendor_goods", ([
"匕首": "/obj/example/dagger",
"酒": "/obj/example/wineskin",
"包子": "/obj/example/dumpling",
"鸡腿": "/obj/example/chicken_leg",
]) );
增加一个list功能
在init()里定义
void init() // 当一个玩家进入同一环境时,调用
object ob;
::init();
if( interactive(ob = this_player()) && !is_fighting() ) {
^^^^^^^^^^^^^^|^^^^^^^^^^^^^^^ ^^^^^^|^^^^^^^
+---判断玩家是否存在 +---相互是否处于战斗状态
remove_call_out("greeting");
call_out("greeting", 1, ob);
}
add_action("do_vendor_list", "list"); //增加一个list的动作,
// list时自动调do_vendor_list,是系统函数
*************************************************
2. 进门时,自动问好
*************************************************
init()中函数设置如上
另外写一个greeting函数
void greeting(object ob)
if( !ob || environment(ob) != environment() ) return;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^判断是否是同一个房间
switch( random(3) ) { // 随机问好
case 0:
say( "店小二笑咪咪地说道:这位" +
RANK_D->query_respect(ob)
+ ",进来喝杯茶,歇歇腿吧。\n");
break;
case 1:
say( "店小二用脖子上的毛巾抹了抹手,说道:这位" +
RANK_D->query_respect(ob)
+ ",请进请进。\n");
break;
case 2:
say( "店小二说道:这位" + RANK_D->query_respect(ob)
+",进来喝几盅小店的红酒吧,这几天\
才从窖子里开封的哟。\n");
break;
}
******************************************** |
|