/* * 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); }