musicmud-2.1.6/data/
musicmud-2.1.6/data/help/
musicmud-2.1.6/data/policy/
musicmud-2.1.6/data/wild/
musicmud-2.1.6/data/world/
musicmud-2.1.6/doc/
musicmud-2.1.6/src/ident/
musicmud-2.1.6/src/lua/
musicmud-2.1.6/src/lua/include/
musicmud-2.1.6/src/lua/src/lib/
musicmud-2.1.6/src/lua/src/lua/
musicmud-2.1.6/src/lua/src/luac/
/* 
 * MusicMUD - Levels module
 * Copyright (C) 1998-2003 Abigail Brady
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 */
#include <unistd.h>

#include "musicmud.h"
#include "Player.h"
#include "State.h"
#include "verbs.h"
#include "levels.h"
#include "misc.h"
#include "pflags.h"
#include "match.h"
#include "pflagnames.h"
#include "flagnames.h"
#include "units.h"
#include "zoneload.h"
#include "hooks.h"
#include "nations.h"

#define MODULE "levels"

static bool verb_calc_strength(MudObject *who, int, const char **) {
	who->set("maxstrength", 200);
	set_mass_capacity(who, 200 * HECTOGRAM);
	if (IS_CAPTAIN(who)) {
	  set_mass_capacity(who, 100 * TON);
	}
	return true;
}

static int quest_points(const MudObject *who);
static int holo_points(const MudObject *who);

int qpts_for_level[] = {
    -1,     // 0   Civ
	0,  // 1   Freshman
	0,  // 2   Sophomore
	0,  // 3   Senior
	1,  // 4   Crewman 3                Private                Spacecraftsman
	3,  // 5   Crewman 2                Lance Corporal         Leading Spacecraftsman
	5,  // 6   Crewman 1                Corporal               Senior Spacecraftsman

	8,  // 7   Petty 3                  Sergeant               Junior Technician
	11, // 8   Petty 2                  Staff Sergeant         Corporal
	15, // 9   Petty 1                  Staff Corporal         Sergeant
        18, // 10  CPO                      Gunnery Sergeant       Chief Technician
        21, // 11  SCPO                     Master Sergeant
        24, // 12  MCPO                     Sergeant Major         Flight Sergeant

        28, // 13  Warrant 3
        32, // 14  Warrant 2
        36, // 15  Warrant 1
        40, // 16  CWO
        44, // 17  SCWO
        48, // 18  MCWO

	53, // 19  Midshipman (Ensign)      Second Lieutentant     Pilot Officer
	58, // 20  Sub Lieutenant (Lt JG)   Lieutenant             Flying Officer
	64, // 21  Lieutenant               Captain                Flight Lieutenant
	70, // 22  Lieutenant Commander     Major                  Squadron Leader
	78, // 23  Commander                Lieutentant-Colonel    Wing Commander
};


#define LEVELS 23

#define MAX(a, b) (a>b?a:b)

static void entitle(MudObject *who) {
  who->unset("title");
}

static bool verb_title(MudObject *player, int argc, const char **argv) {
    if (argc < 2) {
	player->printf("%s <who> [<text>]\n", argv[0]);
	return true;
    }
    MudObject *what = get_player(player, argv[1]);
    if (!what) {
	player->printf("Set whose title?\n");
	return true;
    }
    if (what != player && (privs_of(player) <= privs_of(what)
	|| (!IS_CAPTAIN(player)))) {
	player->printf("You can't set that person's title.\n");
	return true;
    }

    if (!argv[2]) {
      entitle(what);
      return true;
    }

    string text = the_rest(argc, argv, 2);

    char *p = strchr(text.c_str(), '%');
    if (p) {
      p++;
      if (strchr(p, '%')) {
	player->printf("Too many %% signs.\n");
	return true;
      }
    }

    what->set("title", sprinta(0, text.c_str(), what, 0).c_str());
    
    return true;
}

// XXX - convert to lua
static bool verb_calc_level(MudObject *who, int argc, const char **argv) {
  int qpts = quest_points(who);
  int privsof = privs_of(who);
  int level = 1;

  int remort = who->get_int("remort") != -1;

  if ((qpts == 0) && (level < 4)) {
    int holo = holo_points(who);
    if (holo >= 1) level = 2;
    if (holo >= 5) level = 3;
  } else {
    if ((qpts < 1) && (privsof > LEV_COMMANDER || privsof < 4))
      return false; 
  }

  for (int i=0;i<=(int)LEVELS;i++) {
    if (qpts && qpts >= qpts_for_level[i]) {
      level = MAX(level, i);
    }
  }
  who->set("level", level);
  int newprivs = privs_of(who);

  if (!remort) {
	
    if (newprivs > privsof) {
      who->printf("Congratulations. You have reached the level of ^G%s^n.\n", get_long_rank(who));
      broadcast(avoid(who), "^p%M^n has reached the level of ^G%s^n.\n", who, get_long_rank(who));

      entitle(who);
      
    } else if (newprivs < privsof) {
      if (streq(argv[1], "loud")) {
	who->printf("Commiserations, you have ^Rfallen^n to the rank of ^G%s^n....\n",
		    get_long_rank(who));
	broadcast(avoid(who), "^p%M^n has ^Rfallen^n to the rank of ^G%s^n.\n",
		  who, get_long_rank(who));
      }

      entitle(who);
      
    }    
  } else {
    if (newprivs != privsof) {
      who->printf("Your remorted rank is now ^G%s^n.\n", get_long_rank(who));
    }
  }

  if (newprivs >= 4 && privsof < 4)
  { 
    who->set("start", MUD_DEFHOME);
  }

  verb_calc_strength(who, argc, argv);

  return false;
}

static int quest_points(const MudObject *who) {
  int points = DONE_MINIS?DONE_MINIS(who):0;
  extern set<MudObject *> s_quests;
  set<MudObject*>::iterator i=s_quests.begin();
  while (i != s_quests.end()) {
    if (quest_done(who, *i))
      points += (*i)->get_int("questpoints");
    i++;
  }
  return points;
}

static int holo_points(const MudObject *who) {
  int hp = 0;
  int holo = who->get_int("holodone", 0);
  while (holo) {
    if (holo & 1) 
      hp += 1;
    holo >>= 1;
  }
  return hp;
}
	
static bool verb_score(MudObject *who, int argc, const char **argv) {

  OfflinePlayer o = who;
	
  if (argc > 1)
    if (!who->get_priv(PFL_SEESTATS)) {
      
      who->printf("You can only see your own score.\n");
      return true;      
    } else {
    o.grab(who, argv[1]);

    if (!o) {
      who->printf("Can't find : %s\n", argv[1]);
      return true;
    }

    if (!o.person()) {
      who->printf("%#M is not a player.\n", o);
      return true;
    }
  }
    
  who->printf("%s\n", title_for("Score", who).c_str());
  who->printf("Name                : %M^n\n", o);

  if (const Player *p=o.pl()) {
    if (!o.temp()) {
      who->printf("Connected for       : %s\n", howsoon(now - p->on_since+now));
    }
    who->printf("Total time on       : %s\n", howsoon(p->get_int("timeon", 0) + now - p->time_since + now));
  }
  
  if (o->get_int("insurance")>now) {
    who->printf("Insured for         : %s\n", howsoon(o->get_int("insurance")));
  }
  
  if (o.pl()) {
    who->printf("Rank                : ^G%s^n (^G%i^n)\n", get_long_rank(o), privs_of(o));    
  }

  if (holo_points(o))
    who->printf("Simulator Points    : ^Y%i^n\n", holo_points(o));
	
  who->printf("Mission Points      : ^Y%i^n\n", quest_points(o));
  
  {
    int level = privs_of(o);
    if (level < LEV_COMMANDER && level >= 1) {
      who->printf("Points to Promotion : ^Y%i^n\n", qpts_for_level[level+1] - quest_points(o));
    }
  }
  
  if (o->get_int("crim.fine")!=-1) {
    who->printf("Outstanding Fine    : %K\n", o->get_int("crim.fine"));
  }
  
  if (!o->get_priv(PFL_IMMORTAL)) {    
    who->printf("Strength            : ^r%i ^n/ ^R%i^n\n", o->get_int(KEY_STRENGTH),
		o->get_int("maxstrength"));
  }
  who->printf("%s\n", footer_for(who).c_str());
  
  return true;
}

static bool verb_frob(MudObject *who, int argc, const char **argv) {
    if (argc < 3) {
	who->printf("frob <who> <level>\n");
	return true;
    }
    MudObject *t = (MudObject *)planet->get(argv[1]);
    if (!t || !is_player(t)) {
	who->printf("Can't find ^p%s^n.\n", argv[1]);
	return true;
    }
    char *e;
    int old = privs_of(t);
    int new_lev = strtol(argv[2], &e, 0);
    if (new_lev > privs_of(who)) {
        who->printf("I don't think so!\n");
        return true;
    }
    if (new_lev < 0) new_lev = 1;
        
    if (*e) {
	who->printf("Numeric second argument please.\n");
	return true;
    }
    if (t==who) {
	who->printf("Not a good idea.\n");
	return true;
    }
    if (privs_of(t) > privs_of(who)) {
	who->printf("Leave %s level alone.\n", his_or_her(t));
	return true;
    }
    t->set("privs", new_lev);
    log(PFL_SEEINFO, 0, "frob", "frobbed ^p%s^n to level ^G%i^n",
	t->id, level_of(t));
    if (old != privs_of(t))
      t->printf("You have been %s by %M to level ^G%i^n.\n", 
		old>privs_of(t) ? "demoted" : "frobbed", who, privs_of(t));
    entitle(t);
    return true;
}

static bool verb_remort(MudObject *who, int, const char **) {
  bool ok = false;
  if (who->owner->get_flag(FL_REMORTHERE)) ok = true;
  if (who->get_priv(PFL_REMORTANYWHERE)) ok = true;
  if (!ok) {
    who->printf("You can't remort here.\n");
    return true;
  }
  int rem = who->get_int("remort");
  if (rem >= 0) {
    who->printf("You are already remorted.\n");
    return true;
  }

  if (!who->get_priv(PFL_REMORT)) {
    who->printf("You can't do that.\n");
    return true;
  }

  if (mass_in_grams(who)>20*KILOGRAM) {
    who->printf("You can't remort carrying more than 20kg.\n");
    return true;
  }
  
  who->set_gpriv(PFL_REMORTANYWHERE, who->get_priv(PFL_REMORTANYWHERE));
  who->set("remort", 9);
  
  log(PFL_SEEINFO, 0, "wiz", "remort");
  who->printf("You feel diminished.\n");
  who->oprintf(cansee, "%#M transforms and assumes a diminished shape.\n", who);
  if (who->get_int("maxstrength")!=-1) {
    who->set(KEY_STRENGTH, who->get_int("maxstrength"));
    who->set("!holostrength", who->get_int("maxstrength"));
  }
  if (invis(who)>0) {
    who->printf("Note that you are no longer invisible.\n");
  }
  
  Flag badflags[] = {
    FL_SPACESUIT,
    FL_NOLEGS,
    FL_RADIATIONSUIT,
    FL_GILLS,
    FL_NIGHTVISION,
    FL_CANFLOAT,
    FL_CANTWALK,
    FL_COLDPROTECT,
    FL_HEATPROTECT,
    FL_LIT,
    FL_MAGICPASS,
    FL_FLYING,
    FL_POLICE,
    FL_MISSIONSBOARD,
    FL_NONE,
  };
  
  int i=0;
  int first=1;
  while (badflags[i]!=FL_NONE) {
    if (who->get_flag(badflags[i])) {
      if (first) {
	who->printf("You had %s", flag_names[badflags[i]]);
	first = 0;
      } else {
	who->printf(", %s", flag_names[badflags[i]]);
      }
      who->set_bflag(badflags[i], 0);
    }
    i++;
  }
  
  if (who->get_int("pockets")>0) {
    if (first) {
      who->printf("You had pockets %i.\n", who->get_int("pockets"));
      first = 1;
    }
    else
      who->printf(", pockets %i", who->get_int("pockets"));
    who->unset("pockets");
  }
  
  if (who->get_int("damage")>10) {
    if (first) {
      who->printf("You had damage %i.\n", who->get_int("damage"));
      first = 1;
    }
    else
      who->printf(", damage %i", who->get_int("damage"));
    who->unset("damage");
  }
  
  if (!first)
    who->printf(".\n");
  
  who->set("invis", 0);
  return true;
}

static bool verb_refrob(MudObject *who, int argc, const char **argv) {
  bool ok = false;
  if (who->owner->get_flag(FL_REMORTHERE)) ok = true;
  if (who->get_priv(PFL_REMORTANYWHERE)) ok = true;
  if (!ok) {
    if (who->get("_fighting")) {
        who->printf("Not whilst fighting.\n");
        return true;
    }
    who->printf("You can't refrob here.\n");
    return true;
  }
  int rem = who->get_int("remort");
  if (rem >= 0) {
    who->printf("You feel much stronger.\n");
    who->oprintf(cansee, "%#M resumes %s normal shape.\n", who, his_or_her(who));
    log(PFL_SEEINFO, 0, "wiz", "refrob");
    who->unset("remort");
    set_mass_capacity(who, 100 * TON);
  } else {
    who->printf("You can't do that.\n");
  }
  return true;
}



#include "verbmodule.h"

void startup() {
  AUTO_VERB(calc_level, 9, 0, PFL_NONE);
  AUTO_VERB(calc_strength, 9, 0, PFL_NONE);

  AUTO_VERB(remort, 5, 0, PFL_NONE);
  AUTO_VERB(refrob, 5, 0, PFL_NONE);

  AUTO_VERB(frob, 4, 0, PFL_FROB);

  AUTO_VERB(score, 2, 0, PFL_NONE);

  AUTO_VERB(title, 4, 0, PFL_TITLE);

}