muddy/
muddy/CVS/
muddy/area/
muddy/area/CVS/
muddy/clans/CVS/
muddy/classes/CVS/
muddy/doc/
muddy/doc/CVS/
muddy/etc/CVS/
muddy/etc/i3/
muddy/etc/i3/CVS/
muddy/imc/CVS/
muddy/lang/CVS/
muddy/licenses/CVS/
muddy/msgdb/CVS/
muddy/new/CVS/
muddy/notes/
muddy/player/
muddy/races/CVS/
muddy/religions/CVS/
muddy/src/CVS/
muddy/src/comm/CVS/
muddy/src/db/CVS/
muddy/src/intermud/
muddy/src/intermud/CVS/
muddy/src/irc/CVS/
muddy/src/olc/CVS/
/* $Id: olc_skill.c,v 1.666 2004/09/20 10:50:30 shrike Exp $ */

/************************************************************************************
 *    Copyright 2004 Astrum Metaphora consortium                                    *
 *                                                                                  *
 *    Licensed under the Apache License, Version 2.0 (the "License");               *
 *    you may not use this file except in compliance with the License.              *
 *    You may obtain a copy of the License at                                       *
 *                                                                                  *
 *    http://www.apache.org/licenses/LICENSE-2.0                                    *
 *                                                                                  *
 *    Unless required by applicable law or agreed to in writing, software           *
 *    distributed under the License is distributed on an "AS IS" BASIS,             *
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.      *
 *    See the License for the specific language governing permissions and           *
 *    limitations under the License.                                                *
 *                                                                                  *
 ************************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "merc.h"
#include "olc.h"
#include "skills.h"

#define EDIT_SKILL(ch, skill) (skill = (skill_t*) ch->desc->pEdit)

DECLARE_OLC_FUN(skilled_create        );
DECLARE_OLC_FUN(skilled_edit      );
DECLARE_OLC_FUN(skilled_show      );
DECLARE_OLC_FUN(skilled_list      );

DECLARE_OLC_FUN(skilled_name      );
DECLARE_OLC_FUN(skilled_min_pos   );
DECLARE_OLC_FUN(skilled_spell_fun );
DECLARE_OLC_FUN(skilled_do_fun );
DECLARE_OLC_FUN(skilled_gsn       );
DECLARE_OLC_FUN(skilled_flag      );
DECLARE_OLC_FUN(skilled_group     );
DECLARE_OLC_FUN(skilled_minmana   );
DECLARE_OLC_FUN(skilled_initial   );
DECLARE_OLC_FUN(skilled_wearoff   );
DECLARE_OLC_FUN(skilled_wearoffother   );
DECLARE_OLC_FUN(skilled_wearoffobj );
DECLARE_OLC_FUN(skilled_beats     );
DECLARE_OLC_FUN(skilled_initial   );
DECLARE_OLC_FUN(skilled_clan_energy);
DECLARE_OLC_FUN(skilled_maintain  );
DECLARE_OLC_FUN(skilled_noun_damage);
DECLARE_OLC_FUN(skilled_noun_rus  );
DECLARE_OLC_FUN(skilled_target    );
DECLARE_OLC_FUN(skilled_delay     );
DECLARE_OLC_FUN(skilled_discipline);
DECLARE_OLC_FUN(skilled_learn1    );
DECLARE_OLC_FUN(skilled_learn2    );
DECLARE_OLC_FUN(skilled_gender    );
DECLARE_OLC_FUN(skilled_type      );
DECLARE_OLC_FUN(skilled_bonus     );
DECLARE_OLC_FUN(skilled_stat1     );
DECLARE_OLC_FUN(skilled_stat2     );
DECLARE_OLC_FUN(skilled_stat3     );


static DECLARE_VALIDATE_FUN(validate_name  );
static DECLARE_VALIDATE_FUN(validate_gender);

olc_cmd_t olc_cmds_skill[] =
{
    { "create",         skilled_create,       5},
    { "edit",           skilled_edit,         2},
    { "touch",          olced_dummy,          0},
    { "show",           skilled_show,         0},
    { "list",           skilled_list,         0},

    { "name",           skilled_name,         0,       validate_name},
    { "min_pos",        skilled_min_pos,      0,      position_table},
    { "spell_fun",      skilled_spell_fun,    0,       spellfn_table},
    { "do_fun",         skilled_do_fun,       0,         dofun_table},
    { "gsn",            skilled_gsn,          0,           gsn_table},
    { "flag",           skilled_flag,         0,         skill_flags},
    { "group",          skilled_group,        0,        skill_groups},
    { "target",         skilled_target,       0,       skill_targets},
    { "type",           skilled_type,         0,         skill_types},
    { "discipline",     skilled_discipline,   0,     psi_disciplines},
    { "stat1",          skilled_stat1,        0,          stat_names},
    { "stat2",          skilled_stat2,        0,          stat_names},
    { "stat3",          skilled_stat3,        0,          stat_names},
    { "minman",         skilled_minmana,      0},
    { "learn1",         skilled_learn1,       0},
    { "learn2",         skilled_learn2,       0},
    { "bonus",          skilled_bonus,        0},
    { "initialcost",    skilled_initial,      0},
    { "clanenergy",     skilled_clan_energy,  0},
    { "maintaincost",   skilled_maintain,     0},
    { "wearoffself",    skilled_wearoff,      0},
    { "wearoffother",   skilled_wearoffother, 0},
    { "wearoffobj",     skilled_wearoffobj,   0},
    { "noundamage",     skilled_noun_damage,  0},
    { "nounrus",        skilled_noun_rus,     0},
    { "beats",          skilled_beats,        0},
    { "delay",          skilled_delay,        0},
    { "gender",         skilled_gender,       0,    validate_gender},

    { "commands",       show_commands,        0},
    { NULL}
};

OLC_FUN(skilled_create)
{
    int sn;
    skill_t *skill;
    char arg[MAX_STRING_LENGTH];

    if (!char_security(ch,"SECURITY_SKILLS"))
    {
       char_puts("SkillEd: Insufficient security for creating skills\n", ch);
       return FALSE;
    }

   one_argument(argument, arg, sizeof(arg));
   if (arg[0] == '\0')
   {
       do_help(ch, "'OLC CREATE'");
       return FALSE;
   }

   if ((sn = sn_lookup(arg)) >= 0)
   {
       char_printf(ch, "SkillEd: %s: already exists.\n", SKILL(sn)->name);
       return FALSE;
   }

   skill         = skill_new();
   skill->name   = str_dup(arg);

   ch->desc->pEdit = (void *) skill;
   OLCED(ch)       = olced_lookup(ED_SKILL);
   char_puts("Skill created.\n",ch);
   return FALSE;
}

OLC_FUN(skilled_edit)
{
   int sn;
   char arg[MAX_STRING_LENGTH];

   if (!char_security(ch,"SECURITY_SKILLS"))
   {
       char_puts("SkillEd: Insufficient security.\n", ch);
       return FALSE;
   }

  one_argument(argument, arg, sizeof(arg));
  if (arg[0] == '\0')
  {
      do_help(ch, "'OLC EDIT'");
      return FALSE;
  }

  if ((sn = sn_lookup(arg)) == -1)
  {
      char_printf(ch, "SkillEd: %s: No such skill.\n", arg);
      return FALSE;
  }

  ch->desc->pEdit = SKILL(sn);
  OLCED(ch)   = olced_lookup(ED_SKILL);
  return FALSE;
}

OLC_FUN(skilled_wearoff)
{
     skill_t *skill;

     EDIT_SKILL(ch, skill);
     return olced_str(ch, argument, cmd, &skill->msg_off);
}

OLC_FUN(skilled_wearoffother)
{
     skill_t *skill;

     EDIT_SKILL(ch, skill);
     return olced_str(ch, argument, cmd, &skill->msg_off_other);
}

OLC_FUN(skilled_wearoffobj)
{
     skill_t *skill;

     EDIT_SKILL(ch, skill);
     return olced_str(ch, argument, cmd, &skill->msg_obj);
}

OLC_FUN(skilled_noun_damage)
{
     skill_t *skill;

     EDIT_SKILL(ch, skill);
     return olced_str(ch, argument, cmd, &skill->noun_damage);
}

OLC_FUN(skilled_noun_rus)
{
     skill_t *skill;

     EDIT_SKILL(ch, skill);
     return olced_str(ch, argument, cmd, &skill->noun_rus);
}

OLC_FUN(skilled_target)
{
    skill_t *skill;

    EDIT_SKILL(ch, skill);
    return olced_flag32(ch, argument, cmd, &skill->target);
}

OLC_FUN(skilled_discipline)
{
    skill_t *skill;

    EDIT_SKILL(ch, skill);
    return olced_flag32(ch, argument, cmd, &skill->discipline);
}

OLC_FUN(skilled_type)
{
    skill_t *skill;

    EDIT_SKILL(ch, skill);
    return olced_flag32(ch, argument, cmd, &skill->type);
}

OLC_FUN(skilled_stat1)
{
    skill_t *skill;

    EDIT_SKILL(ch, skill);
    return olced_flag32(ch, argument, cmd, &skill->stat1);
}

OLC_FUN(skilled_stat2)
{
    skill_t *skill;

    EDIT_SKILL(ch, skill);
    return olced_flag32(ch, argument, cmd, &skill->stat2);
}

OLC_FUN(skilled_stat3)
{
    skill_t *skill;

    EDIT_SKILL(ch, skill);
    return olced_flag32(ch, argument, cmd, &skill->stat3);
}


OLC_FUN(skilled_show)
{
      int sn;
      char arg[MAX_STRING_LENGTH];
      BUFFER *output;
      skill_t *skill;

      one_argument(argument, arg, sizeof(arg));
      if (arg[0] == '\0')
      {
          if (IS_EDIT(ch, ED_SKILL))
          EDIT_SKILL(ch, skill);
          else
          {
              do_help(ch, "'OLC ASHOW'");
              return FALSE;
          }
      }
      else
      {
          if ((sn = sn_lookup(arg)) == -1)
          {
              char_printf(ch, "SkillEd: %s: No such skill.\n", arg);
              return FALSE;
          }

          skill = SKILL(sn);
      }

      output = buf_new(-1);

      buf_printf(output, "Name:          [%s]\n", skill->name);
      buf_printf(output, "Type:          [%s]\n", flag_string(skill_types, skill->type));
      buf_printf(output, "Group:         [%s]\n", flag_string(skill_groups, skill->group));
      buf_printf(output, "Discipline:    [%s]\n", flag_string(psi_disciplines, skill->discipline));
      buf_printf(output, "MinPos:        [%s]\n", flag_string(position_table, skill->min_pos));
      buf_printf(output, "Flags:         [%s]\n", flag_string(skill_flags, skill->flags));
      buf_printf(output, "SkillGender:   [%d]\n", skill->gender);
      buf_printf(output, "Target:        [%s]\n", flag_string(skill_targets, skill->target));
      if (IS_SET(skill->group, GROUP_CLAN))
            buf_printf(output, "ClanEnergy:    [%d]\n", skill->clan_energy);
      buf_printf(output, "InitialCost:   [%d]\n", skill->initial);
      buf_printf(output, "MaintainCost:  [%d]\n", skill->maintain);
      buf_printf(output, "MinMana:       [%d]\n", skill->min_mana);
      buf_printf(output, "Delay:         [%d]\n", skill->delay);
      buf_printf(output, "Beats:         [%d]\n", skill->beats);
      buf_printf(output, "Learn:         [%d %d]\n", skill->learnmult[0], skill->learnmult[1]);
      buf_printf(output, "Bonus:         [%d]\n", skill->bonus);
      buf_printf(output, "Stat1:         [%s]\n", flag_string(stat_names, skill->stat1));
      buf_printf(output, "Stat2:         [%s]\n", flag_string(stat_names, skill->stat2));
      buf_printf(output, "Stat3:         [%s]\n", flag_string(stat_names, skill->stat3));
      buf_printf(output, "WearOffSelf:   [%s]\n", skill->msg_off);
      buf_printf(output, "WearOffOther:  [%s]\n", skill->msg_off_other);
      buf_printf(output, "WearOffObj:    [%s]\n", skill->msg_obj);
      buf_printf(output, "NounDamage:    [%s]\n", skill->noun_damage);
      buf_printf(output, "NounRus:       [%s]\n", skill->noun_rus);
      if (skill->spell_fun)
          buf_printf(output, "SpellFun:      [%s]\n", namedp_name(spellfn_table, skill->spell_fun));
      if (skill->do_fun)
          buf_printf(output, "DoFun:      [%s]\n", namedp_name(dofun_table, skill->do_fun));
      if (skill->pgsn)
          buf_printf(output, "Gsn:           [%s] (%d)\n", namedp_name(gsn_table, skill->pgsn), *skill->pgsn);

      page_to_char(buf_string(output), ch);
      buf_free(output);

      return FALSE;
}

OLC_FUN(skilled_list)
{
      int i;
      int col = 0;
      char arg[MAX_STRING_LENGTH];

      one_argument(argument, arg, sizeof(arg));

      for (i = 0; i < skills.nused; i++)
      {
          skill_t *skill = (skill_t*) VARR_GET(&skills, i);

          if (arg[0] && str_prefix(arg, skill->name))
               continue;

          char_printf(ch, "%-12s", skill->name);
          if (++col % 6 == 0)
              char_puts("\n", ch);
      }

      if (col % 6)
          char_puts("\n", ch);

      return FALSE;
}

OLC_FUN(skilled_name)
{
      skill_t *skill;
      EDIT_SKILL(ch, skill);
      return olced_str(ch, argument, cmd, &skill->name);
}

OLC_FUN(skilled_min_pos)
{
      skill_t *skill;
      EDIT_SKILL(ch, skill);
      return olced_flag32(ch, argument, cmd, &skill->min_pos);
}

OLC_FUN(skilled_bonus)
{
      skill_t *skill;
      EDIT_SKILL(ch, skill);
      return olced_number(ch, argument, cmd, &skill->bonus);
}

OLC_FUN(skilled_group)
{
      skill_t *skill;
      EDIT_SKILL(ch, skill);
      return olced_flag64(ch, argument, cmd, &skill->group);
}


OLC_FUN(skilled_spell_fun)
{
      bool res;
      skill_t *skill;
      void *p;

      EDIT_SKILL(ch, skill);
      p = (void *) skill->spell_fun;
      res = olced_named_pointer(ch, argument, cmd, &p);
      skill->spell_fun = (SPELL_FUN *) p;
      return res;
}

OLC_FUN(skilled_do_fun)
{
      bool res;
      skill_t *skill;
      void *p;

      EDIT_SKILL(ch, skill);
      p = (void *) skill->do_fun;
      res = olced_named_pointer(ch, argument, cmd, &p);
      skill->do_fun = (DO_FUN *) p;
      return res;
}

OLC_FUN(skilled_gsn)
{
      bool res;
      skill_t *skill;
      void *p;

      EDIT_SKILL(ch, skill);
      p = (void *) skill->pgsn;
      res = olced_named_pointer(ch, argument, cmd, &p);
      skill->pgsn = (int *) p;

      return res;
}

OLC_FUN(skilled_minmana)
{
      skill_t  *skill;

      EDIT_SKILL(ch, skill);
      return olced_number(ch, argument, cmd, &skill->min_mana);
}

OLC_FUN(skilled_beats)
{
      skill_t  *skill;

      EDIT_SKILL(ch, skill);
      return olced_number(ch, argument, cmd, &skill->beats);
}

OLC_FUN(skilled_gender)
{
      skill_t  *skill;

      EDIT_SKILL(ch, skill);
      return olced_number(ch, argument, cmd, &skill->gender);
}

OLC_FUN(skilled_initial)
{
      skill_t  *skill;

      EDIT_SKILL(ch, skill);
      return olced_number(ch, argument, cmd, &skill->initial);
}

OLC_FUN(skilled_clan_energy)
{
      skill_t  *skill;

      EDIT_SKILL(ch, skill);
      return olced_number(ch, argument, cmd, &skill->clan_energy);
}

OLC_FUN(skilled_learn1)
{
      skill_t  *skill;

      EDIT_SKILL(ch, skill);
      return olced_number(ch, argument, cmd, &skill->learnmult[0]);
}

OLC_FUN(skilled_learn2)
{
      skill_t  *skill;

      EDIT_SKILL(ch, skill);
      return olced_number(ch, argument, cmd, &skill->learnmult[1]);
}

OLC_FUN(skilled_maintain)
{
      skill_t  *skill;

      EDIT_SKILL(ch, skill);
      return olced_number(ch, argument, cmd, &skill->maintain);
}

OLC_FUN(skilled_delay)
{
      skill_t  *skill;

      EDIT_SKILL(ch, skill);
      return olced_number(ch, argument, cmd, &skill->delay);
}

OLC_FUN(skilled_flag)
{
    skill_t *skill;

    EDIT_SKILL(ch, skill);
      return olced_flag32(ch, argument, cmd, &skill->flags);
}


static VALIDATE_FUN(validate_name)
{
      int sn;
      const char *name = (const char*) arg;
      skill_t *skill;

      EDIT_SKILL(ch, skill);

      if (strpbrk(name, " \t"))
      {
          char_printf(ch,"SkillEd: %s: illegal character in skill name.\n", arg);
          return FALSE;
      }

      if ((sn = sn_lookup(name)) &&  SKILL(sn) != skill)
      {
          char_printf(ch, "SkillEd: %s: duplicate skill name.\n", arg);
          return FALSE;
      }

      return TRUE;
}

static VALIDATE_FUN(validate_gender)
{
      const char *name = (const char*) arg;
      skill_t *skill;

      EDIT_SKILL(ch, skill);

      if (!is_number(name))
      {
          char_printf(ch,"SkillEd: gender must be 0 or 1.\n");
          return FALSE;
      }

      if (atoi(name) < 0 || atoi(name) > 1)
      {
          char_printf(ch,"SkillEd: gender must be 0 or 1.\n");
          return FALSE;
      }

      return TRUE;
}