Author Topic: daemon creation  (Read 5018 times)

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
daemon creation
« on: February 02, 2008, 02:37:06 pm »

I am attempting to create a daemon that regulates skills.  The goal are to have skills (inherit abilities rather than commands) that determine how good a player is at using a sword or casting a spell.  For instance if a player wants to use a longsword(tier 1) they need to have the skill sword to be useful with the weapon, however, on top of that they need to be practiced in the longsword (tier 2) skill.

So far, Im not making much progress... this is what I have:

Code: [Select]
#include <lib.h>
#include <dirs.h>

inherit LIB_DAEMON;

private mapping skills = ([]);


varargs int AddSkill(string skill, int cls, int level)
 {
    if( !stringp(skill) ) {
        error("Bad argument 1 to AddSkill().\n\tExpected: string, Got: " +
          typeof(skill) + "\n");
    }
    if( !nullp(Skills[skill]) ) {
        return 0;
    }
    if( !cls ) {
        cls = 1;
    }
    if(!level){
        level = 1;
    }
    else if( cls < 0 || cls > 4) {
        return 0;
    }
    Skills[skill] = ([ "points" : 0, "level" : level, "class" : cls ]);
    return 1;
 }

mapping GetSkill(string skill) {
    return copy(Skills[skill]);
}

void RemoveSkill(string skill) {
    if( !Skills[skill] ) {
        return;
    }
    map_delete(Skills, skill);
}

varargs void SetSkill(string skill, int level, mixed cls) {
    int tmp;
    if(cls && !intp(cls)) {
        tmp = 1;
        cls = tmp;
    }
    if( !stringp(skill) ) {
        error("Bad argument 1 to SetSkill().\n\tExpected: string, Got: " +
          typeof(skill) + "\n");
    }
    if( !cls ) {
        if( Skills[skill] ) {
            cls = Skills[skill]["class"];
        }
        else {
            cls = 1;
        }
    }
    else if( cls < 1 || cls > 4) {
        return 0;
    }
    Skills[skill] = ([ "points" : 0, "level" : level, "class" : cls ]);
}

string array GetSkills() {
    return keys(Skills);
}

mapping GetSkillsMap(){
    return copy(Skills);
}
 
 
void eventReloadSkills() {
    string array skills;

    Skills = ([]);
    skills = get_dir(DIR_SKILLS "/*.c");
    foreach(string skill in skills) {
        object ob = find_object(DIR_SKILS "/" + skill);

        if( ob ) {
            ob->eventDestruct();
        }
        if( ob = load_object(DIR_SKILLS "/" + skill) ) {
            spell = ob->GetSkill();
            if( skill ) {
                Skills[skill] = ob;
            }
        }
    }
}

object GetSkill(string skill) {
    if( !Skills[skill] ) {
        eventReloadSkills();
    }
    return Skills[skill];
}


Thoughts, help, examples would be great and very appreciated.

Offline detah

  • BFF
  • ***
  • Posts: 190
  • Ruler of 2D
    • View Profile
Re: daemon creation
« Reply #1 on: February 02, 2008, 03:03:14 pm »
I could make a dozen comments on this. But Im still not sure about what your design should look like at the end. Write out the skills mapping. Then you can use that to start sketching out how you want your skills system to look.

Regarding if(!level), I would set this to error out. Suppose somewhere down the line you forget to add the proper arguments for this fun, then it wil pass the AddSkill() fun and set everybody to Level 1. that does not seem desireable. You should prompt yourself wtih an error so that you know aha, I forgot to put the level argument in the AddSkill fun in place X.

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
Re: daemon creation
« Reply #2 on: February 02, 2008, 04:02:53 pm »

I must admit that this isn't even close to being bad.  As asked on dchat, I am trying to set up a tree system where the skills are constant but the player level in the skill is not.  Moreover, I am trying to set it up so that skills further down the tree are reliant upon those further up the tree.

Offline detah

  • BFF
  • ***
  • Posts: 190
  • Ruler of 2D
    • View Profile
Re: daemon creation
« Reply #3 on: February 02, 2008, 04:29:36 pm »
Could you give me an example of how you want the skills to look in the skills command and the skills mapping in the pfile? You said players can learn the 'sword' skill at the beginning of the game, but later they can learn the 'broadsword' skill. How do you want the 'broadsword' skill to be given to the player? Is it linked to their player level, the skill in sword (ie at sword skill 5% they automatically learn broadsword) or is it given by the guildmaster at fighter guildlevel 8?

Offline silenus

  • BFF
  • ***
  • Posts: 199
    • View Profile
Re: daemon creation
« Reply #4 on: February 02, 2008, 04:32:29 pm »
Hello Capo,

I hope you dont mind me chiming in here- but I suspect that the system you would like to have would probably consist of three components.

a module in player.c which tracks data specific to the player for skills. i.e. which skills he possesses and what levels they are at.

a daemon for skills which would keep track of the skill tree/hierarchy and which skills are related to which other skills and in what manner.

and some manner of skill/commands which might be tied to the above skill hierarchy either directly or indirectly indicating which players may execute which skills.

So perhaps 3 mappings

mapping 1 (inside the player object) this would keep the current level, points of each skill.

mapping 2 (inside the daemon) would be the skill dependencies tree

mapping 3 (inside the daemon) would consist of rules indicating which checks needed to be passed in order to execute a given skill.

I suspect there could be otherways to decompose the system but that seems to me to be the simplest way to implement it. Good luck!

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
Re: daemon creation
« Reply #5 on: February 02, 2008, 04:44:41 pm »
Could you give me an example of how you want the skills to look in the skills command and the skills mapping in the pfile? You said players can learn the 'sword' skill at the beginning of the game, but later they can learn the 'broadsword' skill. How do you want the 'broadsword' skill to be given to the player? Is it linked to their player level, the skill in sword (ie at sword skill 5% they automatically learn broadsword) or is it given by the guildmaster at fighter guildlevel 8?

I sure can.

player types skills and gets a rough output like this:

Quote

Tier 1 Skills

Sword Attack (10) Sword Defense (5) Basic Sorcery (6) Basic Magic (3)
Sorcery Defense (1) Magic Defense (4) Mining (2) Crafting (2)

Tier 2 Skills

Broadswords (5) Longsword (6) Rapiers (5)

Tier 3 Skills

Magical Broadsword (2)



The skill "broadsword", "longsword", "rapiers", etc can be given to the player in a number of ways:  joining a guild and learning from their trainer, finding a npc master, finding a player willing to try to teach it to you.  The skills are not level based, ie you dont have to be level 20 to learn a skill, rather, your capacity to learn a skill is limited by your level.  For instance, if you are level 20 all of your tier 1 skills can reach level 60.  All tier 2 skills can reach level 40, and all tier 3 skills can be level 20. 

Does that make sense?

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
Re: daemon creation
« Reply #6 on: February 02, 2008, 04:45:06 pm »
PS the numbers in () are skill levels.

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
Re: daemon creation
« Reply #7 on: February 02, 2008, 04:45:58 pm »
Hello Capo,

I hope you dont mind me chiming in here- but I suspect that the system you would like to have would probably consist of three components.



I certainly don't mind at all, I value help.

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
Re: daemon creation
« Reply #8 on: February 05, 2008, 07:21:45 pm »
Ok, Im back... daemon has been created (thanks to Alecksy's help).

I have attempted to modify the teach command to work with the new daemon, to check to see if the person has the requisit skills.... however, right now Im creating a number of errors.  I was hoping that someone could help me stomp them out.  Here is the teach file:

Code: [Select]
#include <lib.h>
#include <daemons.h>

private static mapping Teaching = ([]);
private static int OfferExpires = 60;

int direct_teach_str_to_liv(){ return 1;}
int direct_teach_liv_to_str(){ return 1;}

int CanTeach()
 {
   int can_teach = 1;
   string spell;
   object target;
   string skilltoteach = "spell";
   object student = find_player("target");
   string *requisites = ({ });

   requisites = SKILLS_D->GetSkillRequisites(spell);

  if (sizeof(requisites))
     {
       foreach(string req in requisites)
         {
           if (member_array(req,student->GetSkills()) == -1)
             {
              can_teach = 0;
              write("You cannot teach that!");
              return 0;
             }
          else if (member_array(req,student->GetSkills()) != -1)
             {
              can_teach = 1; 
              return 1;
             }
         }
      }
   }

int eventOfferTeaching(object who, string spell){
    if(!CanTeach()){
        write("You can't teach that.");
        return 0;
    }
    tell_player(who,this_object()->GetName()+" offers to teach you "+spell+".");
    Teaching[who] = ({ spell, time() });
    return 1;
}

int eventTeach(object who, string spell){
    if(!CanTeach()){
        write("They can't teach that.");
        return 0;
    }
    if(!Teaching[who]){
        write("They're not interested in teaching you anything.");
        return 0;
    }
    if(time() - Teaching[who][1] > OfferExpires){
        write("It's too late. Their offer to teach you expired.");
        map_delete(Teaching,who);
        return 0;
    }
    if( !who->eventLearnSpell(spell) ) {
        write("You are not prepared to learn that!");
        return 0;
    }

    who->eventPrint(this_object()->GetName() + " touches your forehead and gives you knowledge of " + spell + ".");
    environment()->eventPrint(this_object()->GetName() + " touches " + possessive_noun(who) + " forehead and gives " +
    objective(who) + " knowledge of " + spell + ".", who);
    map_delete(Teaching,who);
    return 1;
}

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
Re: daemon creation
« Reply #9 on: February 05, 2008, 07:23:30 pm »
And this is the error:

> teach broadswords to gillan
---
2008.02.05-19.23
*Tried to take a member of something that isn't a class.
Object: /daemon/skills at line 58

'<fake>' at /secure/save/creators/c/capo (/<driver>) at line 0
'cmdAll' at /secure/save/creators/c/capo (/lib/command.c) at line 141
'do_teach_str_to_liv' at /verbs/players/teach at line 42
'eventOfferTeaching' at /secure/save/creators/c/capo (/lib/teach.c) at line 37
'CanTeach' at /secure/save/creators/c/capo (/lib/teach.c) at line 19
'GetSkillRequisites' at /daemon/skills at line 58
Trace written to /log/runtime

>

Offline Alecksy

  • Acquaintance
  • *
  • Posts: 21
    • View Profile
    • BucketMUD
Re: daemon creation
« Reply #10 on: February 06, 2008, 12:18:49 pm »
The immediate problem that I see is that in CanTeach, the "string spell;" variable is not being initialized with anything before being passed to SKILLS_D->GetSkillRequisites() which will indeed make it a very sad panda. Also, you're not passing any arguments to CanTeach, when you should (based on what I see in this file) be passing it the skill/spell name you want to check.

I've added in those changes below:


Code: [Select]
#include <lib.h>
#include <daemons.h>

private static mapping Teaching = ([]);
private static int OfferExpires = 60;

int direct_teach_str_to_liv(){ return 1;}
int direct_teach_liv_to_str(){ return 1;}

int CanTeach(string skilltoteach)
 {
   int can_teach = 1;
   object target;
   object student = find_player("target");
   string *requisites = ({ });

   requisites = SKILLS_D->GetSkillRequisites(skilltoteach);

  if (sizeof(requisites))
     {
       foreach(string req in requisites)
         {
           if (member_array(req,student->GetSkills()) == -1)
             {
              can_teach = 0;
              write("You cannot teach that!");
              return 0;
             }
          else if (member_array(req,student->GetSkills()) != -1)
             {
              can_teach = 1; 
              return 1;
             }
         }
      }
   }

int eventOfferTeaching(object who, string spell){
    if(!CanTeach(spell)){
        write("You can't teach that.");
        return 0;
    }
    tell_player(who,this_object()->GetName()+" offers to teach you "+spell+".");
    Teaching[who] = ({ spell, time() });
    return 1;
}

int eventTeach(object who, string spell){
    if(!CanTeach(spell)){
        write("They can't teach that.");
        return 0;
    }
    if(!Teaching[who]){
        write("They're not interested in teaching you anything.");
        return 0;
    }
    if(time() - Teaching[who][1] > OfferExpires){
        write("It's too late. Their offer to teach you expired.");
        map_delete(Teaching,who);
        return 0;
    }
    if( !who->eventLearnSpell(spell) ) {
        write("You are not prepared to learn that!");
        return 0;
    }

    who->eventPrint(this_object()->GetName() + " touches your forehead and gives you knowledge of " + spell + ".");
    environment()->eventPrint(this_object()->GetName() + " touches " + possessive_noun(who) + " forehead and gives " +
    objective(who) + " knowledge of " + spell + ".", who);
    map_delete(Teaching,who);
    return 1;
}

See if that gets you any closer. :)
Chil@BucketMUD
www.bucketmud.tk

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
Re: daemon creation
« Reply #11 on: February 06, 2008, 05:15:07 pm »
Closer!  Gets me to:

Quote
> teach broadswords to gillan
---
2008.02.06-17.14
*Bad argument 1 to call_other()
Expected: string or array or object Got: 0.
Object: /secure/save/creators/c/capo (/lib/teach.c) at line 23

'<fake>' at /secure/save/creators/c/capo (/<driver>) at line 0
'cmdAll' at /secure/save/creators/c/capo (/lib/command.c) at line 141
'do_teach_str_to_liv' at /verbs/players/teach at line 42
'eventOfferTeaching' at /secure/save/creators/c/capo (/lib/teach.c) at line 39
'CanTeach' at /secure/save/creators/c/capo (/lib/teach.c) at line 23
Trace written to /log/runtime

Offline tay

  • Acquaintance
  • *
  • Posts: 23
    • View Profile
Re: daemon creation
« Reply #12 on: March 01, 2008, 05:47:24 pm »
Hey Capo, whatever happened to this?

It seemed like a good system, and I was looking on creating a skill system similar.  But, if you've already got one functioning/close to functioning, I'd like to see the completed thing.  Don't forget to put your header on it. ;)