/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /* MurkMUD++ - A Windows compatible, C++ compatible Merc 2.2 Mud. \author Jon A. Lambert \date 08/30/2006 \version 1.4 \remarks This source code copyright (C) 2005, 2006 by Jon A. Lambert All rights reserved. Use governed by the MurkMUD++ public license found in license.murk++ */ #include "os.hpp" #include "config.hpp" /* * Generate a random number in an inclusive range. */ int number_range (int from, int to) { if (to <= from) return from; return (from + (OS_RAND () % (1 + to - from))); } /* * Stick a little fuzz on a number. */ int number_fuzzy (int number) { switch (number_range (0, 3)) { case 0: number -= 1; break; case 3: number += 1; break; } return std::max (1, number); } /* * Roll some dice. */ int dice (int number, int size) { int idice; int sum; switch (size) { case 0: return 0; case 1: return number; } for (idice = 0, sum = 0; idice < number; idice++) sum += number_range (1, size); return sum; } /* * Generate a percentile roll. */ int number_percent (void) { return number_range (1, 100); } /* * Generate a random door. */ int number_door (void) { return number_range (0, 5); } /* * Simple linear interpolation. */ int interpolate (int level, int value_00, int value_32) { return value_00 + level * (value_32 - value_00) / 32; } // Case insensitive compare bool str_cmp(const std::string & s1, const std::string & s2) { if (s1.size() != s2.size()) return true; std::string::const_iterator p1 = s1.begin(), p2 = s2.begin(); while(p1 != s1.end() && p2 != s2.end()) { if(tolower(*p1) != tolower(*p2)) return true; p1++; p2++; } return false; } /* * Compare strings, case insensitive, for prefix matching. * Return true if s1 not a prefix of bstr * (compatibility with historical functions). */ bool str_prefix(const std::string & s1, const std::string & s2) { if (s1.size() > s2.size()) return true; std::string::const_iterator p1 = s1.begin(), p2 = s2.begin(); while(p1 != s1.end() && p2 != s2.end()) { if(tolower(*p1) != tolower(*p2)) return true; p1++; p2++; } return false; } /* * Compare strings, case insensitive, for match anywhere. * Returns true is astr not part of bstr. * (compatibility with historical functions). */ bool str_infix (const std::string & astr, const std::string & bstr) { if (astr.empty()) return false; int cmpsz = bstr.size() - astr.size(); char c0 = tolower(astr[0]); for (int ichar = 0; ichar <= cmpsz; ichar++) { if (c0 == tolower(bstr[ichar]) && !str_prefix(astr, bstr.substr(ichar))) return false; } return true; } /* * Compare strings, case insensitive, for suffix matching. * Return true if astr not a suffix of bstr * (compatibility with historical functions). */ bool str_suffix(const std::string& s1, const std::string& s2) { if (s1.size() <= s2.size() && !str_cmp(s1, s2.substr(s2.size() - s1.size()))) return false; else return true; } /* * Returns an initial-capped string. */ std::string capitalize (const std::string & str) { std::string strcap; std::string::const_iterator p = str.begin(); while(p != str.end()) { if (p == str.begin()) strcap.append(1, (char)toupper(*p)); else strcap.append(1, (char)tolower(*p)); p++; } return strcap; } // replaces all occurances of a s1 in str with s2 void global_replace (std::string & str, const std::string & s1, const std::string & s2) { std::string::size_type pos = 0; while ((pos = str.find(s1, pos)) != std::string::npos) { str.replace(pos, s1.size(), s2); pos += s2.size(); } } /* * Return true if an argument is completely numeric. */ bool is_number (const std::string & arg) { if (arg.empty()) return false; std::string::const_iterator p = arg.begin(); if (*p == '+' || *p == '-') p++; for (; p != arg.end(); p++) { if (!isdigit (*p)) return false; } return true; } /* * Given a string like 14.foo, return 14 and 'foo' */ int number_argument (const std::string & argument, std::string & arg) { std::string::size_type pos; arg.erase(); if ((pos = argument.find(".")) != std::string::npos) { arg = argument.substr(pos+1); return std::atoi (argument.substr(0, pos).c_str()); } arg = argument; return 1; } /* * Pick off one argument from a string and return the rest. * Understands quotes. */ std::string one_argument (const std::string & argument, std::string & arg_first) { char cEnd; std::string::const_iterator argp = argument.begin(); arg_first.erase(); while (argp != argument.end() && isspace (*argp)) argp++; cEnd = ' '; if (*argp == '\'' || *argp == '"') cEnd = *argp++; while (argp != argument.end()) { if (*argp == cEnd) { argp++; break; } arg_first.append(1, (char)tolower(*argp)); argp++; } while (argp != argument.end() && isspace (*argp)) argp++; return std::string(argp, argument.end()); } /* * See if a string is one of the names of an object. */ /* * New is_name sent in by Alander. */ bool is_name (const std::string & str, std::string namelist) { std::string name; for (;;) { namelist = one_argument (namelist, name); if (name.empty()) return false; if (!str_cmp (str, name)) return true; } } /* * Removes the tildes from a string. * Used for player-entered strings that go into disk files. */ void smash_tilde (std::string & str) { global_replace(str, "~", "-"); }