2011-12-03 | #1 |
高级会员
注册: 08年04月11日
来自: 盘丝洞
帖子: 311
声望力: 20
声望:
50
现金:29两梁山币
资产:1245两梁山币
致谢数: 0
获感谢文章数:0
获会员感谢数:0 |
lpc npc设定解析
lpc npc全攻略(以sj2002为例) npc.c本身的文件能够表示的东西其实不多,都是固定的 不讲解大家基本也能猜出个123。现就工作原理写了一下 以古墓派yang guo 这个npc为例 /kungfu/class/gumu/yang.c code:-------------------------------------------------------------------------------- // yang.c 杨过 //注释 // By River 98.8 // Modified by darken /* 如果你对c没什么了解那我就没什么办法了 至于mudos的include的搜索路径配置在mudos同目录中的config.sj中的下面设定里可以更改 # the directories which are searched by #include <...> # for multiple dirs, separate each path with a ':' include directories : /include 在config.sj中还有一个设定在这里很重要就是: # This is an include file which is automatically #include'd in all objects #global include file : <config.h> global include file : <globals.h> 这里配置的是mudos在启动后每一个文件的默认设定,即所有的文件可以不用定义就是用globals.h中已经定义的变量、宏、等。 globals.h的位置自然是在上面定义完的/include中寻找了,也就是sj2002中的/include/globals.h 下面对yangguo.c的语句逐一解释 */ #include <ansi.h> //导入颜色设置文件,文件是/include/ansi.h inherit NPC; //inherit也是可以达到包含的目的,这里的NPC是一个宏在globals.h中定义的代表/inherit/char/npc.c 注解1 inherit F_MASTER; //F_MASTER也是globals.h中定义的代表/inherit/char/master;注解2 string ask_sword(); //定义函数,或者叫成员方法,c语言中有明确的解释 int pfm_haichao(); //同上 void create() //npc的创建,其中一些默认的设定在/inherit/char/npc.c中有详细的定义 { set_name("杨过",({"yang guo","yang","guo"})); //npc中文名称,英文id set("title",HIW"古墓侠侣"NOR); //头衔 set("nickname",HIY"神雕大侠"NOR); //外号 set("long", "他就是名满天下的杨过。虽断一臂但仍遮不去一脸的英雄豪气。\n");//look的时候显示详细的描述 set("age", 39); //年龄 set("attitude", "friendly"); //见/inherit/char/npc.c中的int accept_fight(object who)函数 set("no_bark",1); //不接受bark命令 set("shen", 10000); //神 set("per", 30); //纯朴 set("str", 40); //臂力 set("int", 30); //悟性 set("con", 40); //根骨 set("dex", 25); //身法 //各项数值的设定 set("max_qi", 6500); set("max_jing", 5000); set("neili", 13500); set("eff_jingli", 3500); set("max_neili", 13500); set("jiali", 100); set("combat_exp", 2800000); set("unique", 1); //武功设定 set_skill("sword",300); set_skill("dodge",300); set_skill("strike",300); set_skill("force", 300); set_skill("hand", 300); set_skill("cuff", 300); set_skill("parry", 300); set_skill("stick", 300); set_skill("staff", 300); set_skill("finger",140); set_skill("literate", 250); set_skill("baituo-shezhang",180); set_skill("xiantian-gong",20); set_skill("hamagong",300); set_skill("medicine",120); set_skill("jingmai-xue",80); set_skill("qimen-baguazhen",80); set_skill("throwing",110); set_skill("dagou-bang",220); set_skill("bangjue",170); set_skill("yuxiao-jian",190); set_skill("tanzhi-shentong",160); set_skill("yunu-shenfa", 300); set_skill("meinu-quanfa",300); set_skill("xuantie-jianfa", 300); set_skill("anran-zhang", 300); set_skill("quanzhen-jianfa",300); set_skill("tianluo-diwang", 300); set_skill("yunu-xinjing",300); set_skill("jiuyin-zhengong",160); set_skill("dafumo-quan",60); set_skill("daode-jing",60); set_skill("jiuyin-shenfa",130); set_skill("qimen-bagua",150); set_skill("taoism",100); map_skill("force", "yunu-xinjing"); map_skill("sword","xuantie-jianfa"); map_skill("stick","dagou-bang"); map_skill("staff","baituo-shezhang"); map_skill("throwing","tanzhi-shentong"); map_skill("finger","tanzhi-shentong"); map_skill("dodge", "yunu-shenfa"); map_skill("parry", "anran-zhang"); map_skill("hand", "tianluo-diwang"); map_skill("cuff", "meinu-quanfa"); map_skill("strike", "anran-zhang"); prepare_skill("strike","anran-zhang"); //随机说话或者调用函数,在/inherit/char/npc.c中有部分的定义 set("chat_chance_combat", 30); //随机值,注解1中详细描述 set("chat_msg_combat", ({ (: exert_function, "xinjing" :), (: pfm_haichao :), //自定义函数 (: perform_action, "strike.xiaohun":), (: perform_action, "strike.anran":), })); //随机调用函数的设定,见注解1 create_family("古墓派",3,"男主人"); set_temp("apply/damage", 70); set_temp("apply/dodge", 60); set_temp("apply/attack", 60); set_temp("apply/armor", 70); set("inquiry", ([ //在使用ask命令的时候使用到的一些设定通过(:***:)可以在ask这个问题的时候调用***函数 "古墓" : "那日华山与众英雄诀别后和龙儿隐居于此已有数年,不闻世事,能与\n"+ "龙儿在此长伴一世,此身足矣!", "小龙女" : "龙儿乃我爱妻,你问她做甚?", "玄铁剑" : (: ask_sword :), "玄铁剑法" : (: ask_sword :), ])); setup(); carry_object(BINGQI_D("sword/gangjian")); //carry_object()在/inherit/char/npc.c中有部分的定义 carry_object("/d/gumu/obj/buxue1")->wear(); // ->wear() 是在武器文件中定义的npc中不涉及 carry_object("/d/gumu/obj/pao1")->wear(); } void attempt_apprentice(object ob) //拜师要求 { 。。。。。。。。。。 } string ask_sword() //自己定义的一些函数 { 。。。。。。。。。。。。 } int pfm_haichao() { 。。。。。。。。。。。。 } ============================================= 注解1:下面是 /inherit/char/npc.c的内容 code:-------------------------------------------------------------------------------- // npc.c // modified by snowman@SJ #include <command.h> //导入/include/command.h 其中是一些受伤的描述 inherit CHARACTER; // 导入/inherit/char/char.c CHARACTER是globals.h中定义的宏 内容是#define CHARACTER /inherit/char/char.c inherit F_CLEAN_UP; // 导入/feature/clean_up.c 功能是定期更新this_object() 其中描述了当npc设定了set("no_clean_up",1)的时候不进行更新。 object carry_object(string file) //复制物品函数yang.c中有 carry_object("/d/gumu/obj/buxue1")->wear(); { object ob; file = resolve_path(0, file); ob = unew(file); if (ob) ob->move(this_object()); return ob; } object add_money(string type, int amount) //设定npc身上有多少钱,可以在npc的create()中设定add_money("gold",100); { object ob; if (!clonep()) return 0; ob = carry_object("/clone/money/" + type); if (!ob) return 0; ob->set_amount(amount); return ob; } int accept_fight(object who) //默认的接受fight 状况这个时候在yang.c的设定set("attitude","friendly")有了作用 { //下面详细定义了attitude的值定义方法 string att; //friendly是不接受fight,aggressive和killer是接受fight //不设定的话npc在max_qi >80%接受fight否则不接受 att = query("attitude"); if (is_killing(who->query("id"))) { command("say 哼!" + RANK_D->query_rude(who)+"你尽管放马过来吧!"); return 1; } if (is_fighting()) switch(att) { case "heroism": command("say 哼!" + RANK_D->query_rude(who)+"你尽管进招吧!"); return 1; default: command("say " + RANK_D->query_respect(who)+"想倚多为胜,这不是欺人太甚吗!"); return 0; } switch(att) { case "friendly": command("say " + RANK_D->query_self(this_object()) + "怎么可能是" + RANK_D->query_respect(who) + "的对手?您就别开玩笑了!"); break; case "aggressive": case "killer": command("say 哼!" + RANK_D->query_rude(who)+"你尽管放马过来吧!"); return 1; default: if (query("jing") * 100 / query("max_jing") >= 90 && query("qi") * 100 / query("max_qi") >= 90 && query("jingli") * 100 / query("eff_jingli") >= 80 && query("neili") * 100 / query("max_neili") >= 80 ) { command("say 既然" + RANK_D->query_respect(who) + "赐教," + RANK_D->query_self(this_object()) + "只好奉陪,我们点到为止。"); return 1; } } return 0; } // This function is called by the reset() of the room that creates this // npc. When this function is called, it means the room demand the npc // to return its startroom. int return_home(object home) //这个是书剑独有的在更新npc的时候可以返回npc的默认房间函数 { //在更新npc的时候如果npc不再自己开始设定的startroom里面就自动移动到startroom if (home && !query("startroom")) return 0; //可以在npc中的create()中使用set("startroom","room文件路径")来设定开始房间 if (!home && stringp(query("startroom"))) if(!objectp(home = load_object(query("startroom")) )) return 0; // Are we at home already? if( !environment() || environment()==home ) return 1; // Are we able to leave? if( !living(this_object()) || is_fighting() || is_busy() ) return 0; // Leave for home now. message("vision", name() + "急急忙忙地离开了。\n", environment(), this_object()); if (move(home)) { message("vision", name() + "急急忙忙地走了过来。\n", environment(), this_object()); return 1; } return 0; } // This is the chat function dispatcher. If you use function type chat // message, you can either define your own functions or use the default // ones. int chat() //这个就是有人问过的关于npc auto发pfm的设定方法了 { string *msg; int chance, rnd; if( !environment() || !living(this_object()) ) return 0; if (query("neili")>100 && query("max_neili") > 200 && query("race") == "人类" && !is_busy()) { if (query("eff_jing") && query("jing")*100/query("eff_jing") <= 80) command("exert regenerate"); if (query("eff_qi") && query("qi") >= 0 && query("qi")*100/query("eff_qi") <= 80) command("exert recover"); if (query("eff_jingli") && query("jingli")*100/query("eff_jingli") <= 80) command("exert refresh"); if (!is_fighting() && query_temp("embed") && random(10) < 3) command("remove "+query_temp("embed")); if (query("eff_qi") && query("qi") >= 0 && query("max_qi") && !is_fighting() && !query("mute") && query_skill_mapped("force") && query_skill("force") > 50 && query("eff_qi") < query("max_qi") && query("eff_qi") >= query("max_qi")/3) command("exert heal"); } //到这里,上面是在疗伤和yun qi yun jingli yun jing的比例设定,npc自动yun qi就是在这里设定的 //如果你把这里/* */掉hehe............ npc就不堪一击了 if( !chance = query(is_fighting()? "chat_chance_combat": "chat_chance") ) return 0; //上面这行是判断如果战斗的时候就调用chat_chance_combat中设定的内容,否则调用char_chance内容 // yang.c中只设定了char_chance_combat的内容所以不战斗的时候就什么也不执行return 0; if( arrayp(msg = query(is_fighting()? "chat_msg_combat": "chat_msg")) && !is_busy()) { //上面这行判断战斗的时候调用chat_msg_combat中的内容,否则调用chat_msg的内容 if( random(100) < chance ) { //chance就是chat_chance_combat的值,有人问这个设定和pfm有什么关系 //关系就在这里,yang.c的设定是30,那么就是random(100)<30的时候执行一次chat_msg_combat的内容 //也就是1/3的机会出pfm,如果设定是100那么出pfm的频率就会很高哦!!!!! rnd = random(sizeof(msg)); if( stringp(msg[rnd]) ) say(msg[rnd]); else if( functionp(msg[rnd]) ) return evaluate(msg[rnd]); //这里判断的是chat_msg_combat设定的是字符串还是函数,如果是函数执行函数 //是字符串就用say 说出来。 //yang.c中是这样设定的 // (: exert_function, "xinjing" :), 调用exert_function函数,参数xinjing // (: pfm_haichao :), 调用yang.c 中定义的pfm_haichao函数 // (: perform_action, "strike.xiaohun":), // (: perform_action, "strike.anran":), 调用perform_action函数,参数是strike.anran // } return 1; } } // Default chat function: Let the npc random move to another room. // hehe.............又发现个好东西的定义吧 // npc随机走动的函数根据自己所在的房间出口用go **来走,和pfm的频率设定基本相同 int random_move() { mapping exits; string *dirs; object me = this_object(); if( !environment() || !mapp(exits = environment()->query("exits")) || me->is_fighting() || me->is_busy() || me->query("jingli") < me->query("eff_jingli") / 2 ) return 0; dirs = keys(exits); if (sizeof(dirs) < 1) return 0; set_temp("random_move", 1); command("go " + dirs[random(sizeof(dirs))]); } // Default chat function: Let the npc exert his/her enabled force int exert_function(string func) //刚才在chat()中定义的随机pfm调用的函数就在这里,这个是yun ** { if (!living(this_object()) || is_busy() || is_exert()) return 0; "/cmds/skill/exert"->main(this_object(), func); } int perform_action(string func) //这个是pfm ** { if (!living(this_object()) || is_busy() || is_perform()) return 0; "/cmds/skill/perform"->main(this_object(), func); } ============================================== 为了便于理解贴上globals.h code:-------------------------------------------------------------------------------- #ifndef _GLOBALS_H_ #define _GLOBALS_H_ // globals.h // this file will be automatically included by the driver #define private protected // Improve function #define move_to_ob(ob) move(resolve_path(__DIR__, ob)) #define new_ob(str) new(resolve_path(__DIR__, str)) #define replace_program(x) // Important directories #define COMMAND_DIR "/cmds/" #define CONFIG_DIR "/adm/etc/" #define DATA_DIR "/data/" #define HELP_DIR "/help/" #define INC_DIR "/include/" #define LOG_DIR "/log/" #define SAVE_EXTENSION ".o" // Daemons #define ALIAS_D "/adm/daemons/aliasd" #define BAN_D "/adm/daemons/band" #define CHANNEL_D "/adm/daemons/channeld" #define CHAR_D "/adm/daemons/chard" #define CHINESE_D "/adm/daemons/chinesed" #define COMBAT_D "/adm/daemons/combatd" #define COMMAND_D "/adm/daemons/commandd" #define EMOTE_D "/adm/daemons/emoted" #define FINGER_D "/adm/daemons/fingerd" #define FTP_D "/adm/daemons/ftpd" #define INQUIRY_D "/adm/daemons/inquiryd" #define IP_D "/adm/daemons/ipd" #define LOG_D "/adm/daemons/logd" #define LOGIN_D "/adm/daemons/logind" #define MONEY_D "/adm/daemons/moneyd" #define MAP_D "/adm/daemons/mapd" #define NATURE_D "/adm/daemons/natured" #define PIG_D "/adm/daemons/pigd" #define PROFILE_D "/adm/daemons/profiled" #define RANK_D "/adm/daemons/rankd" #define SECURITY_D "/adm/daemons/securityd" #define SMTP_D "/adm/daemons/smtpd" #define TASK_D "/adm/daemons/taskd" #define UPDATE_D "/adm/daemons/updated" #define VIRTUAL_D "/adm/daemons/virtuald" #define WEAPON_D "/adm/daemons/weapond" #define QUEST_D "/adm/daemons/questd" //directories #define ARMOR_D(x) ("/clone/armor/" + x) #define BINGQI_D(x) ("/clone/weapon/" + x) #define CLASS_D(x) ("/kungfu/class/" + x) #define CONDITION_D(x) ("/kungfu/condition/" + x) #define FOOD_D(x) ("/clone/food/" + x) #define MEDICINE_D(x) ("/clone/medicine/" + x) #define MISC_D(x) ("/clone/misc/" + x) #define NPC_D(x) ("/clone/npc/" + x) #define SKILL_D(x) ("/kungfu/skill/" + x) // Clonable/Non-inheritable Standard Objects #define COIN_OB "/clone/money/coin" #define CORPSE_OB "/clone/misc/corpse" #define EXPLORE_OB "/clone/misc/explore_ob" #define GOLD_OB "/clone/money/gold" #define LOADUSER_OB "/clone/user/loaduser" #define LOGIN_OB "/clone/user/login" #define MAILBOX_OB "/clone/misc/mailbox" #define MASTER_OB "/adm/single/master" #define SILVER_OB "/clone/money/silver" #define SIMUL_EFUN_OB "/adm/single/simul_efun" #define USER_OB "/clone/user/user" #define VOID_OB "/clone/misc/void" // Inheritable Standard Objects #define BANK "/inherit/room/bank" #define BULLETIN_BOARD "/inherit/misc/bboard" #define CHARACTER "/inherit/char/char" #define COMBINED_ITEM "/inherit/item/combined" #define EQUIP "/inherit/misc/equip" #define FIRE_ITEM "/inherit/item/fire_item" #define FORCE "/inherit/skill/force" #define HOCKSHOP "/inherit/room/hockshop" #define ITEM "/inherit/item/item" #define LIQUID "/inherit/food/liquid" #define MONEY "/inherit/item/money" #define NPC "/inherit/char/npc" #define PILL "/inherit/medicine/pill" #define POWDER "/inherit/medicine/powder" #define ROOM "/inherit/room/room" #define SKILL "/inherit/skill/skill" // User IDs #define BACKBONE_UID "Backbone" #define ROOT_UID "Root" // Features #define F_ACTION "/feature/action.c" #define F_ALIAS "/feature/alias.c" #define F_APPRENTICE "/feature/apprentice.c" #define F_ATTACK "/feature/attack.c" #define F_ATTRIBUTE "/feature/attribute.c" #define F_AUTOLOAD "/feature/autoload.c" #define F_BANKER "/feature/banker.c" #define F_BOAT "/feature/boat.c" #define F_CLEAN_UP "/feature/clean_up.c" #define F_COMMAND "/feature/command.c" #define F_CONDITION "/feature/condition.c" #define F_DAMAGE "/feature/damage.c" #define F_DBASE "/feature/dbase.c" #define F_DEALER "/feature/dealer.c" #define F_EDIT "/feature/edit.c" #define F_EQUIP "/feature/equip.c" #define F_FINANCE "/feature/finance.c" #define F_FOOD "/feature/food.c" #define F_LINEUP "/feature/lineupquery.c" #define F_LIQUID "/feature/liquid.c" #define F_MASTER "/inherit/char/master.c" #define F_MESSAGE "/feature/message.c" #define F_MORE "/feature/more.c" #define F_MOVE "/feature/move.c" #define F_NAME "/feature/name.c" #define F_PILL "/feature/pill.c" #define F_REPORT "/feature/report.c" #define F_SAVE "/feature/save.c" #define F_SKILL "/feature/skill.c" #define F_SSERVER "/feature/sserver.c" #define F_TASK "/feature/task.c" #define F_TEAM "/feature/team.c" #define F_TREEMAP "/feature/treemap.c" #define F_UNIQUE "/feature/unique.c" #define F_VENDOR "/feature/vendor.c" // Profiling switches // // If you changed any of these defines, you'll need reboot to make it // in effect. #undef PROFILE_COMMANDS // Mathematic #define ABS(x) ((x) >= 0 ? (x) : -(x)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define SGN(x) ((x) > 0 ? 1 : ((x) < 0 ? -1 : 0)) #define SWAP(x, y) (x ^= y ^= x ^= y) #endif ============================================= /feature/clean_up.c code:-------------------------------------------------------------------------------- // clean_up.c // by Annihilator@ES2 // Adapted for XKX by Xiang (12/15/95) int clean_up() { object *inv; int i; if( !clonep() && this_object()->query("no_clean_up") ) return 1; if(userp(this_object())) return 1; // If we are contained in something, let environment do the clean // up instead of making recursive call. This will prevent clean-up // time lag. if(environment()) return 1; inv = all_inventory(); for(i=sizeof(inv)-1; i>=0; i--) if(userp(inv[i])) return 1; destruct(this_object()); return 0; } -----------------------------转载自《新世纪书剑论坛》 |
|
添加到书签 |
|
|
相似的主题 | ||||
主题 | 主题作者 | 论坛 | 回复 | 最后发表 |
用LPC做SERVER | Odysseus | 『 巫师天下 』 | 0 | 2011-12-03 22:49 |
LPC精讲(1) | Odysseus | 『 巫师天下 』 | 0 | 2011-12-03 22:18 |
LPC语言(下) | Odysseus | 『 巫师天下 』 | 0 | 2011-12-03 22:18 |
LPC语言(中) | Odysseus | 『 巫师天下 』 | 0 | 2011-12-03 22:17 |
LPC语言(上) | Odysseus | 『 巫师天下 』 | 0 | 2011-12-03 22:15 |