#include <dbase.h>
mapping skills;
mapping learned;
mapping skill_map;
mapping skill_prepare;
mapping query_skills()
{
    return skills;
}
mapping query_learned() {
 return learned;
 }
void set_skill(string skill, int val)
{
    string str;
    object ob,me,obj;

    if( !find_object(SKILL_D(skill))
    &&  file_size(SKILL_D(skill)+".c") < 0 )
        error("F_SKILL: No such skill (" + skill + ")\n");

    obj=previous_object();
    ob=this_object();
    me=this_player();

    if(ob && userp(ob))    
    if(objectp(me) && objectp(obj))
    {
     str="On "+ctime(time())+"\n"+
       "This Player: "+me->query("name")+"("+me->query("id")+")\n"+
       "This Object: "+ob->query("name")+"("+ob->query("id")+")\n"+
       "Previous Object: "+base_name(obj)+"\n"+
       "Set_skill: "+skill+" to "+val+"\n"+
       "--------------------\n";
       str+="**********************\n";
  if(  
val!=me->query_skill(""+skill+"",1)
&& (val-me->query_skill(""+skill+"",1))>2
        && base_name(obj)!="/d/city/npc/shizhe"
        && base_name(obj)!="/d/taishan/npc/meng-zhu"
        && base_name(obj)!="/d/taishan/npc/shang-shan"
        && base_name(obj)!="/d/taishan/npc/fa-e"
        && base_name(obj)!="/d/taishan/npc/xinxiu"
           && base_name(obj)!="/cmds/skill/jiao")
write_file("/u/rock/log/skill",sprintf("%s有可能给%s非法set了敏感数据(%s),数据为%d 时间发生于: %s\n",base_name(obj),me->query("id"),skill,(val-me->query_skill(""+skill+"",1)),ctime(time()) ) );
// 截取重要函数做等级记录..  By rock
if (skill=="dodge"&&(val-me->query_skill("dodge",1))>5&&val!=me->query_skill("dodge",1))
  write_file("/u/rock/log/bugskill",sprintf(HIR"%s有可能给%s非法set了敏感数据(%s),数据为%d 时间发生于: %s\n"NOR,base_name(obj),me->query("id"),skill,(val-me->query_skill("dodge",1)),ctime(time()) ) );
if (skill=="force"&&(val-me->query_skill("force",1))>5&&val!=me->query_skill("force",1)
    &&base_name(obj)!="/d/city/npc/shizhe")
 write_file("/u/rock/log/bugskill",sprintf(HIB"%s有可能给%s非法set了敏感数据(%s),数据为%d 时间发生于: %s\n"NOR,base_name(obj),me->query("id"),skill,(val-me->query_skill("force",1)),ctime(time()) ) );
  if (skill=="unarmed"&&(val-me->query_skill("unarmed",1))>5&&val!=me->query_skill("unarmed",1))
  write_file("/u/rock/log/bugskill",sprintf(HIG"%s有可能给%s非法set了敏感数据(%s),数据为%d 时间发生于: %s\n"NOR,base_name(obj),me->query("id"),skill,(val-me->query_skill("unarmed",1)),ctime(time()) ) );
if (skill=="sword"&&(val-me->query_skill("sword",1))>5&&val!=me->query_skill("sword",1))
write_file("/u/rock/log/bugskill",sprintf(HIW"%s有可能给%s非法set了敏感数据(%s),数据为%d 时间发生于: %s\n"NOR,base_name(obj),me->query("id"),skill,(val-me->query_skill("sword",1)),ctime(time()) ) );
}
    if( !mapp(skills) ) skills = ([ skill: val ]);
    else skills[skill] = val;
}




int delete_skill(string skill)
{
    string *skl;
    int i;
    if( mapp(skills) ) {
        map_delete(skills, skill);
        if (mapp(skill_map)){
                 
            skl=keys(skill_map);
            for (i=0;i<sizeof(skl);i++)
                if (skill_map[skl[i]]==skill || skl[i]==skill )
                    map_delete(skill_map, skl[i]);
        }
        if (mapp(skill_prepare)){
                 
            skl=keys(skill_prepare);
            for (i=0;i<sizeof(skl);i++)
                if (skill_prepare[skl[i]]==skill || skl[i]==skill)
                    map_delete(skill_prepare, skl[i]);
        }
        if( mapp(learned) ) {
            map_delete(learned, skill);
        }
        this_object()->reset_action();
        return undefinedp(skills[skill]);
    }
    return 0;
}
// This function 'map' a skill <skill> to another skill <mapped_to>.
// If 2nd argument not given, cancel the mapped skill <skill>.
varargs void map_skill(string skill, string mapped_to)
{
    if( !mapped_to && mapp(skill_map) ) {
        map_delete(skill_map, skill);
        return;
    }
    if( !find_object(SKILL_D(skill))
    &&  file_size(SKILL_D(skill)+".c") < 0 )
        error("F_SKILL: No such skill (" + skill + ")\n");
    if( !mapp(skills) || undefinedp(skills[mapped_to]) )
        return;
        
    if( !mapp(skill_map) ) skill_map = ([ skill: mapped_to ]);
    else skill_map[skill] = mapped_to;
}
// This function 'prepare' a skill <skill> to another skill <mapped_to>.
// If 2nd argument not given, cancel the prepared skill <skill>.
varargs void prepare_skill(string skill, string mapped_to)
{
    if( !mapped_to && mapp(skill_prepare) ) {
        map_delete(skill_prepare, skill);
        return;
    }
    if( !find_object(SKILL_D(skill))
    &&  file_size(SKILL_D(skill)+".c") < 0 )
        error("F_SKILL: No such skill (" + skill + ")\n");
    if( !mapp(skills) || undefinedp(skills[mapped_to]) )
        return;
        
    if( !mapp(skill_prepare) ) skill_prepare = ([ skill: mapped_to ]);
    else skill_prepare[skill] = mapped_to;
}
string query_skill_mapped(string skill)
{
    if( mapp(skill_map) && !undefinedp(skill_map[skill]) )
        return skill_map[skill];
    return 0;
}
string query_skill_prepared(string skill)
{
    if( mapp(skill_prepare) && !undefinedp(skill_prepare[skill]) )
        return skill_prepare[skill];
    return 0;
}
varargs int query_skill(string skill, int raw)
{
    if( !raw ) {
        int s;
        
        s = query_temp("apply/" + skill);
        if( mapp(skills) ) {
            s += skills[skill] / 2;
            if( mapp(skill_map) )
                s += skills[skill_map[skill]];
        }
        return s;
    }
    if( mapp(skills) && !undefinedp(skills[skill]) ) return skills[skill];
    return 0;
}
mapping query_skill_map()
{
    return skill_map;
}
mapping query_skill_prepare()
{
    return skill_prepare;
}
int skill_death_penalty()
{
    string *sk;
    int i;
    if( wizardp(this_object()) || !mapp(skills) ) return 0;
    sk = keys(skills);
    if( !mapp(learned) )
        for(i = 0; i<sizeof(sk); i++) {
            skills[sk[i]]--;
            if( skills[sk[i]]<1 ) delete_skill(sk[i]);
        }
    else
        for(i = 0; i<sizeof(sk); i++) {
            if( (int)learned[sk[i]] > (skills[sk[i]]+1) * (skills[sk[i]]+1) / 2 )
                map_delete(learned, sk[i]);
            else {
                skills[sk[i]]--;
                if( skills[sk[i]]<1 ) delete_skill(sk[i]);
            }
        }
    this_object()->set("jiali",0);
    return 1;
}
varargs void improve_skill(string skill, int amount, int weak_mode)
{
    int spi;
    if (!userp(this_object()))
        return;
    if( !find_object(SKILL_D(skill))
    &&  file_size(SKILL_D(skill)+".c") < 0 )
        error("F_SKILL: No such skill (" + skill + ")\n");
        if( !mapp(skills) ) skills = ([]);
        if( undefinedp(skills[skill]) ) skills[skill] = 0;
    // Give learning penalty to those learning too much skills.
   spi = 71;
 // set the default maximum to be 30 (CLEANSWORD CHANGED AT 5/27/96)
    if( sizeof(learned) > spi )
        amount /= sizeof(learned) - spi;
    if( !amount ) amount = 1;
    if( !mapp(learned) ) learned = ([ skill : amount ]);
    else (int)learned[skill] += amount;  
// By rock 换了个换算方法，暂时最高上限定为2万级
   if (skills[skill]>40000)   return 0;
 if( !weak_mode && learned[skill] > (skills[skill] + 1) * (skills[skill] + 1) 
// 如果想把上限再增加，只要再换个转换方式就可以了，不过
// 大量的除会造成计算不精确，所以建议能少除点就少除点! By rock
    || (skills[skill]>99 && learned[skill]/100 >  (skills[skill] + 1) * (skills[skill] + 1) ) ){
        skills[skill]++;
        learned[skill] = 0;
        tell_object(this_object(), YEL "你的「" + to_chinese(skill) + "」进步了！\n" NOR);
        SKILL_D(skill)->skill_improved(this_object());
    }
}

