背景:
阅读文章

lpc npc设定解析

[日期:2007-05-12] 来源:  作者: [字体: ]

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;
}

尊重作者 转载请注明出处52mud.com

收藏 推荐 打印 | 录入:sbso | 阅读:
相关内容      
内容推送
52mud提供
一起回忆泥巴游戏QQ群68186072
52mud官方微信公众平台
热门评论