/*
* file: utility.c, Utility module. Part of DIKUMUD
* Usage: Utility procedures
* Copyright (C) 1990, 1991 - see 'license.doc' for complete information.
*/
#include <stdio.h>
#include <stdlib.h>
/* #include <unistd.h> */
#include <sys/types.h>
/* #include <malloc.h> */
#include <string.h>
#include <assert.h>
#include <time.h>
#include "global.h"
#include "bug.h"
#include "spells.h"
#include "constants.h"
#include "db.h"
#include "opinion.h"
#include "comm.h"
#include "hash.h"
#include "multiclass.h"
#include "handler.h"
#include "fight.h"
#include "act_info.h"
#include "reception.h"
#include "act_off.h"
#include "magic_utils.h"
#include "mudlimits.h"
#include "act_skills.h"
#define _UTILS_C
#include "utils.h"
int MobVnum(struct char_data *c)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(c));
if (!c || IS_PC(c))
return 0;
if (IS_MOB(c)) {
return mob_index[c->nr].virtual;
} else {
return -1;
}
}
int ObjVnum(struct obj_data *o)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_ONAME(o));
if (!o)
return 0;
if (o->item_number >= 0)
return obj_index[o->item_number].virtual;
else
return -1;
}
int percent(int value, int total)
{
if (DEBUG > 3)
log_info("called %s with %d, %d", __PRETTY_FUNCTION__, value, total);
if (!total)
return 0;
return ((value * 100) / total);
}
const char *ordinal(int x)
{
if (DEBUG > 3)
log_info("called %s with %d", __PRETTY_FUNCTION__, x);
if (x < 14 && x > 10)
x = 4;
else
x %= 10;
switch (x) {
case 1:
return "st";
case 2:
return "nd";
case 3:
return "rd";
default:
return "th";
}
}
int GetItemClassRestrictions(struct obj_data *obj)
{
int total = 0;
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_ONAME(obj));
if (IS_SET(obj->obj_flags.extra_flags, ITEM_ANTI_MAGE))
total += CLASS_MAGIC_USER;
if (IS_SET(obj->obj_flags.extra_flags, ITEM_ANTI_THIEF))
total += CLASS_THIEF;
if (IS_SET(obj->obj_flags.extra_flags, ITEM_ANTI_RANGER))
total += CLASS_RANGER;
if (IS_SET(obj->obj_flags.extra_flags, ITEM_ANTI_FIGHTER))
total += CLASS_WARRIOR;
if (IS_SET(obj->obj_flags.extra_flags, ITEM_ANTI_CLERIC))
total += CLASS_CLERIC;
return (total);
}
int CAN_SEE(struct char_data *s, struct char_data *o)
{
if (DEBUG > 3)
log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(s), SAFE_NAME(o));
if (!o || !s)
return (FALSE);
if ((s->in_room == -1) || (o->in_room == -1))
return (FALSE);
if (o->invis_level >= GetMaxLevel(s))
return FALSE;
if (IS_IMMORTAL(s))
return (TRUE);
if (IS_AFFECTED(s, AFF_TRUE_SIGHT))
return (TRUE);
if (IS_AFFECTED(s, AFF_BLIND) && s != o)
return (FALSE);
if (IS_AFFECTED(o, AFF_HIDE))
return (FALSE);
if (IS_AFFECTED(o, AFF_INVISIBLE)) {
if (IS_IMMORTAL(o))
return (FALSE);
if (!IS_AFFECTED(s, AFF_DETECT_INVISIBLE))
return (FALSE);
}
if ((IS_DARK(s->in_room) || IS_DARK(o->in_room)) && (!IS_AFFECTED(s, AFF_INFRAVISION)))
return (FALSE);
return (TRUE);
}
int exit_ok(struct room_direction_data *room_exit, struct room_data **rpp)
{
struct room_data *rp = NULL;
if (DEBUG > 3)
log_info("called %s with %08zx, %08zx", __PRETTY_FUNCTION__, (size_t) room_exit,
(size_t) rpp);
if (rpp == NULL)
rpp = &rp;
if (!room_exit) {
*rpp = NULL;
return FALSE;
}
*rpp = real_roomp(room_exit->to_room);
return (*rpp != NULL);
}
int IsImmune(struct char_data *ch, int bit)
{
if (DEBUG > 3)
log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch), bit);
if (!ch)
return 0;
return IS_SET(bit, ch->M_immune);
}
int IsResist(struct char_data *ch, int bit)
{
if (DEBUG > 3)
log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch), bit);
if (!ch)
return 0;
if (GetMaxLevel(ch) >= LOW_IMMORTAL)
return 1;
return IS_SET(bit, ch->immune);
}
int IsSusc(struct char_data *ch, int bit)
{
if (DEBUG > 3)
log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch), bit);
if (!ch)
return 0;
return IS_SET(bit, ch->susc);
}
/* creates a random number in interval [from;to] */
int number(int from, int to)
{
if (DEBUG > 3)
log_info("called %s with %d, %d", __PRETTY_FUNCTION__, from, to);
if (to - from + 1)
return ((random() % (to - from + 1)) + from);
else
return from;
}
/* simulates dice roll */
int dice(int rolls, int size)
{
int r = 0;
int sum = 0;
if (DEBUG > 3)
log_info("called %s with %d, %d", __PRETTY_FUNCTION__, rolls, size);
if (size < 1 || rolls < 1)
return 0;
if (size == 1)
return rolls;
for (r = 1; r <= rolls; r++)
sum += ((random() % size) + 1);
return sum;
}
int fuzz(int x)
{
if (DEBUG > 3)
log_info("called %s with %d", __PRETTY_FUNCTION__, x);
if (!x)
return 0;
if (x < 0)
x = -x;
return ((random() % ((2 * x) + 1)) - x);
}
int scan_number(const char *text, int *rval)
{
int length = 0;
if (DEBUG > 3)
log_info("called %s with %s, %08zx", __PRETTY_FUNCTION__, VNULL(text), (size_t) rval);
if (!text || !*text)
return 0;
if (1 != sscanf(text, " %i %n", rval, &length))
return 0;
if (text[length] != 0)
return 0;
return 1;
}
int str_cmp(const char *arg1, const char *arg2)
{
if (DEBUG > 3)
log_info("called %s with %s, %s", __PRETTY_FUNCTION__, VNULL(arg1), VNULL(arg2));
if (!arg1 || !arg2)
return 1;
return strcasecmp(arg1, arg2);
}
int strn_cmp(const char *arg1, const char *arg2, const int n)
{
if (DEBUG > 3)
log_info("called %s with %s, %s, %d", __PRETTY_FUNCTION__, VNULL(arg1), VNULL(arg2), n);
if (!arg1 || !arg2)
return 1;
return strncasecmp(arg1, arg2, n);
}
void sprintbit(unsigned long vektor, const char *names[], char *result)
{
long nr = 0L;
if (DEBUG > 3)
log_info("called %s with %lu, %08zx, %08zx", __PRETTY_FUNCTION__, vektor,
(size_t) names, (size_t) result);
*result = '\0';
for (nr = 0; vektor; vektor >>= 1) {
if (IS_SET(1, vektor)) {
if (*names[nr] != '\n') {
strcat(result, names[nr]);
strcat(result, " ");
} else {
strcat(result, "UNDEFINED");
strcat(result, " ");
}
}
if (*names[nr] != '\n')
nr++;
}
if (!*result)
strcat(result, "NOBITS");
}
void sprinttype(int type, const char *names[], char *result)
{
int nr = 0;
if (DEBUG > 3)
log_info("called %s with %d, %08zx, %08zx", __PRETTY_FUNCTION__, type, (size_t) names,
(size_t) result);
for (nr = 0; (*names[nr] != '\n'); nr++);
if (type < nr)
strcpy(result, names[type]);
else
strcpy(result, "UNDEFINED");
}
/* Calculate the REAL time passed over the last t2-t1 centuries (secs) */
struct time_info_data real_time_passed(time_t t2, time_t t1)
{
long secs = 0L;
struct time_info_data now;
if (DEBUG > 3)
log_info("called %s with %ld, %ld", __PRETTY_FUNCTION__, t2, t1);
secs = (long)(t2 - t1);
now.hours = (secs / SECS_PER_REAL_HOUR) % 24; /* 0..23 hours */
secs -= SECS_PER_REAL_HOUR * now.hours;
now.day = (secs / SECS_PER_REAL_DAY); /* 0..34 days */
secs -= SECS_PER_REAL_DAY * now.day;
now.month = -1;
now.year = -1;
return now;
}
/* Calculate the MUD time passed over the last t2-t1 centuries (secs) */
struct time_info_data mud_time_passed(time_t t2, time_t t1)
{
long secs = 0L;
struct time_info_data now;
if (DEBUG > 3)
log_info("called %s with %ld, %ld", __PRETTY_FUNCTION__, t2, t1);
secs = (long)(t2 - t1);
now.hours = (secs / SECS_PER_MUD_HOUR) % 24; /* 0..23 hours */
secs -= SECS_PER_MUD_HOUR * now.hours;
now.day = (secs / SECS_PER_MUD_DAY) % 35; /* 0..34 days */
secs -= SECS_PER_MUD_DAY * now.day;
now.month = (secs / SECS_PER_MUD_MONTH) % 17; /* 0..16 months */
secs -= SECS_PER_MUD_MONTH * now.month;
now.year = (secs / SECS_PER_MUD_YEAR); /* 0..XX? years */
return now;
}
struct time_info_data age(struct char_data *ch)
{
struct time_info_data player_age;
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
player_age = mud_time_passed(time(0), ch->player.time.birth);
player_age.year += 17; /* All players start at 17 */
return player_age;
}
int in_group(struct char_data *ch1, struct char_data *ch2)
{
if (DEBUG > 3)
log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch1), SAFE_NAME(ch2));
/*
* three possibilities ->
* 1. char is char2's master
* 2. char2 is char's master
* 3. char and char2 follow same.
*
* otherwise not true.
*/
if ((!ch1) || (!ch2))
return (0);
if (ch1 == ch2)
return (TRUE);
if ((!ch1->master) && (!ch2->master))
return (0);
if (ch2->master)
if (!strcmp(GET_NAME(ch1), GET_NAME(ch2->master))) {
return (1);
}
if (ch1->master)
if (!strcmp(GET_NAME(ch1->master), GET_NAME(ch2))) {
return (1);
}
if ((ch2->master) && (ch1->master))
if (!strcmp(GET_NAME(ch1->master), GET_NAME(ch2->master))) {
return (1);
}
return (0);
}
/*
* more new procedures
*/
/*
* these two procedures give the player the ability to buy 2*bread
* or put all.bread in bag, or put 2*bread in bag...
*/
int getall(char *name, char *newname)
{
char arg[40] = "\0\0\0\0\0\0\0";
char tmpname[80] = "\0\0\0\0\0\0\0";
char otname[80] = "\0\0\0\0\0\0\0";
char prd = '\0';
if (DEBUG > 3)
log_info("called %s with %s, %s", __PRETTY_FUNCTION__, VNULL(name), VNULL(newname));
sscanf(name, "%s ", otname); /* reads up to first space */
if (strlen(otname) < 5)
return (FALSE);
sscanf(otname, "%3s%c%s", arg, &prd, tmpname);
if (prd != '.')
return (FALSE);
if (tmpname == NULL)
return (FALSE);
if (strcmp(arg, "all"))
return (FALSE);
while (*name != '.')
name++;
name++;
for (; (*newname = *name); name++, newname++);
return (TRUE);
}
int getabunch(char *name, char *newname)
{
int num = 0;
char tmpname[80] = "\0\0\0\0\0\0\0";
if (DEBUG > 3)
log_info("called %s with %s, %s", __PRETTY_FUNCTION__, VNULL(name), VNULL(newname));
sscanf(name, "%d*%s", &num, tmpname);
if (tmpname[0] == '\0')
return (FALSE);
if (num < 1)
return (FALSE);
if (num > 9)
num = 9;
while (*name != '*')
name++;
name++;
for (; (*newname = *name); name++, newname++);
return (num);
}
int DetermineExp(struct char_data *mob, int exp_flags)
{
int base = 0;
int phit = 0;
int sab = 0;
/*
* reads in the monster, and adds the flags together
* for simplicity, 1 exceptional ability is 2 special abilities
*/
if (DEBUG > 3)
log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(mob), exp_flags);
if (GetMaxLevel(mob) < 0)
return (1);
switch (GetMaxLevel(mob)) {
case 0:
base = 5;
phit = 1;
sab = 10;
break;
case 1:
base = 10;
phit = 1;
sab = 15;
break;
case 2:
base = 20;
phit = 2;
sab = 20;
break;
case 3:
base = 35;
phit = 3;
sab = 25;
break;
case 4:
base = 60;
phit = 4;
sab = 30;
break;
case 5:
base = 90;
phit = 5;
sab = 40;
break;
case 6:
base = 150;
phit = 6;
sab = 75;
break;
case 7:
base = 225;
phit = 8;
sab = 125;
break;
case 8:
base = 600;
phit = 12;
sab = 175;
break;
case 9:
base = 900;
phit = 14;
sab = 300;
break;
case 10:
base = 1100;
phit = 15;
sab = 450;
break;
case 11:
base = 1300;
phit = 16;
sab = 700;
break;
case 12:
base = 1550;
phit = 17;
sab = 700;
break;
case 13:
base = 1800;
phit = 18;
sab = 950;
break;
case 14:
base = 2100;
phit = 19;
sab = 950;
break;
case 15:
base = 2400;
phit = 20;
sab = 1250;
break;
case 16:
base = 2700;
phit = 23;
sab = 1250;
break;
case 17:
base = 3000;
phit = 25;
sab = 1550;
break;
case 18:
base = 3500;
phit = 28;
sab = 1550;
break;
case 19:
base = 4000;
phit = 30;
sab = 2100;
break;
case 20:
base = 4500;
phit = 33;
sab = 2100;
break;
case 21:
base = 5000;
phit = 35;
sab = 2600;
break;
case 22:
base = 6000;
phit = 40;
sab = 3000;
break;
case 23:
base = 7000;
phit = 45;
sab = 3500;
break;
case 24:
base = 8000;
phit = 50;
sab = 4000;
break;
case 25:
base = 9000;
phit = 55;
sab = 4500;
break;
case 26:
base = 10000;
phit = 60;
sab = 5000;
break;
case 27:
base = 12000;
phit = 70;
sab = 6000;
break;
case 28:
base = 14000;
phit = 80;
sab = 7000;
break;
case 29:
base = 16000;
phit = 90;
sab = 8000;
break;
case 30:
base = 20000;
phit = 100;
sab = 10000;
break;
default:
base = 25000;
phit = 150;
sab = 20000;
break;
}
return (base + (phit * GET_HIT(mob)) + (sab * exp_flags));
}
void down_river(int current_pulse)
{
struct char_data *ch = NULL;
struct char_data *tmp = NULL;
struct obj_data *obj_object = NULL;
struct obj_data *next_obj = NULL;
int rd = 0;
int or = 0;
struct room_data *rp = NULL;
if (DEBUG > 3)
log_info("called %s with %d", __PRETTY_FUNCTION__, current_pulse);
if (current_pulse < 0)
return;
for (ch = character_list; ch; ch = tmp) {
tmp = ch->next;
if (!IS_NPC(ch)) {
if (ch->in_room != NOWHERE) {
if (real_roomp(ch->in_room)->sector_type == SECT_WATER_NOSWIM)
if ((real_roomp(ch->in_room))->river_speed > 0) {
if ((current_pulse % (real_roomp(ch->in_room))->river_speed) == 0) {
if (((real_roomp(ch->in_room))->river_dir < MAX_NUM_EXITS) &&
((real_roomp(ch->in_room))->river_dir >= 0)) {
rd = (real_roomp(ch->in_room))->river_dir;
for (obj_object = (real_roomp(ch->in_room))->contents;
obj_object; obj_object = next_obj) {
next_obj = obj_object->next_content;
if ((real_roomp(ch->in_room))->dir_option[rd]) {
obj_from_room(obj_object);
obj_to_room(obj_object,
(real_roomp(ch->in_room))->
dir_option[rd]->to_room);
}
}
/*
* flyers don't get moved
*/
if (!IS_AFFECTED(ch, AFF_FLYING)) {
rp = real_roomp(ch->in_room);
if (rp && rp->dir_option[rd] && rp->dir_option[rd]->to_room
&& (EXIT(ch, rd)->to_room != NOWHERE)) {
if (ch->specials.fighting) {
stop_fighting(ch);
}
cprintf(ch, "You drift %s...\r\n", dirs[rd]);
if (MOUNTED(ch)) {
or = ch->in_room;
char_from_room(ch);
char_from_room(MOUNTED(ch));
char_to_room(ch,
(real_roomp(or))->
dir_option[rd]->to_room);
char_to_room(MOUNTED(ch),
(real_roomp(or))->
dir_option[rd]->to_room);
do_look(ch, "", 15);
} else if (RIDDEN(ch)) {
or = ch->in_room;
char_from_room(ch);
char_from_room(RIDDEN(ch));
char_to_room(ch,
(real_roomp(or))->
dir_option[rd]->to_room);
char_to_room(RIDDEN(ch),
(real_roomp(or))->
dir_option[rd]->to_room);
do_look(ch, "", 15);
} else {
or = ch->in_room;
char_from_room(ch);
char_to_room(ch,
(real_roomp(or))->
dir_option[rd]->to_room);
do_look(ch, "", 15);
}
if (IS_SET(RM_FLAGS(ch->in_room), DEATH)
&& GetMaxLevel(ch) < LOW_IMMORTAL) {
death_cry(ch);
zero_rent(ch);
extract_char(ch);
}
}
}
}
}
}
}
}
}
}
/* these are all very arbitrary */
int IsHumanoid(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
switch (GET_RACE(ch)) {
case RACE_HALFBREED:
case RACE_HUMAN:
case RACE_GNOME:
case RACE_ELVEN:
case RACE_DWARF:
case RACE_HALFLING:
case RACE_ORC:
case RACE_LYCANTH:
case RACE_UNDEAD:
case RACE_GIANT:
case RACE_GOBLIN:
case RACE_DEVIL:
case RACE_TROLL:
case RACE_VEGMAN:
case RACE_MFLAYER:
case RACE_DEMON:
case RACE_GHOST:
case RACE_PRIMATE:
return TRUE;
default:
return FALSE;
}
}
int IsAnimal(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
switch (GET_RACE(ch)) {
case RACE_PREDATOR:
case RACE_FISH:
case RACE_BIRD:
case RACE_HERBIV:
case RACE_ANIMAL:
case RACE_LYCANTH:
return TRUE;
default:
return FALSE;
}
}
int IsUndead(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
switch (GET_RACE(ch)) {
case RACE_UNDEAD:
case RACE_GHOST:
return TRUE;
default:
return FALSE;
}
}
int IsLycanthrope(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
switch (GET_RACE(ch)) {
case RACE_LYCANTH:
return TRUE;
default:
return FALSE;
}
}
int IsDiabolic(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
switch (GET_RACE(ch)) {
case RACE_DEMON:
case RACE_DEVIL:
return TRUE;
default:
return FALSE;
}
}
int IsReptile(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
switch (GET_RACE(ch)) {
case RACE_REPTILE:
case RACE_DRAGON:
case RACE_DINOSAUR:
case RACE_SNAKE:
return TRUE;
default:
return FALSE;
}
}
int IsDraconic(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
switch (GET_RACE(ch)) {
case RACE_DRAGON:
return TRUE;
default:
return FALSE;
}
}
int IsAvian(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
switch (GET_RACE(ch)) {
case RACE_BIRD:
case RACE_DRAGON:
case RACE_GHOST: /* insubstantial? */
return TRUE;
default:
return FALSE;
}
}
int IsExtraPlanar(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
switch (GET_RACE(ch)) {
case RACE_DEMON:
case RACE_DEVIL:
case RACE_PLANAR:
case RACE_ELEMENT:
return TRUE;
default:
return FALSE;
}
}
int HasHands(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
if (IsHumanoid(ch) || IsDiabolic(ch) || IsDraconic(ch))
return TRUE;
else
return FALSE;
}
int IsPerson(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
switch (GET_RACE(ch)) {
case RACE_HUMAN:
case RACE_ELVEN:
case RACE_DWARF:
case RACE_HALFLING:
case RACE_GNOME:
return TRUE;
default:
return FALSE;
}
}
void SetHunting(struct char_data *ch, struct char_data *tch)
{
int persist = 0;
int dist = 0;
if (DEBUG > 3)
log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch), SAFE_NAME(tch));
persist = GetMaxLevel(ch);
/*
* persist *= (int) GET_ALIGNMENT(ch) / 100;
*/
persist *= (int)GET_ALIGNMENT(ch) / 200;
if (persist < 0)
persist = -persist;
dist = GET_INT(ch) + GetMaxLevel(ch);
/*
* dist = GET_ALIGNMENT(tch) - GET_ALIGNMENT(ch);
*/
dist = (dist > 0) ? dist : -dist;
if (DoesHate(ch, tch))
dist *= 2;
SET_BIT(ch->specials.act, ACT_HUNTING);
ch->specials.hunting = tch;
ch->hunt_dist = dist;
ch->persist = persist;
ch->old_room = ch->in_room;
if (GetMaxLevel(tch) >= IMMORTAL) {
cprintf(tch, ">>%s is hunting you from %s\r\n",
ch->player.short_descr, (real_roomp(ch->in_room))->name);
}
}
void CallForGuard(struct char_data *ch, struct char_data *vict, int lev)
{
struct char_data *i = NULL;
if (DEBUG > 3)
log_info("called %s with %s, %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch),
SAFE_NAME(vict), lev);
if (lev == 0)
lev = 3;
for (i = character_list; i && lev > 0; i = i->next) {
if (IS_NPC(i) && (i != ch)) {
if (!i->specials.fighting) {
if ((mob_index[i->nr].virtual == GUARD_VNUM)
|| (mob_index[i->nr].virtual == GUARD2_VNUM)) {
if (number(1, 6) >= 3) {
if (!IS_SET(i->specials.act, ACT_HUNTING)) {
if (vict) {
SetHunting(i, vict);
lev--;
}
}
}
}
}
}
}
}
void CallForAGuard(struct char_data *ch, struct char_data *vict, int lev)
{
struct char_data *point = NULL;
if (DEBUG > 3)
log_info("called %s with %s, %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch),
SAFE_NAME(vict), lev);
if (lev == 0)
lev = 3;
for (point = character_list; point && (lev > 0); point = point->next) {
if (IS_NPC(point) &&
(ch != point) &&
(!point->specials.fighting) &&
(real_roomp(ch->in_room)->zone == real_roomp(point->in_room)->zone) &&
(IS_SET(point->specials.act, ACT_PROTECTOR))) {
if (number(0, 1)) {
if (!IS_SET(point->specials.act, ACT_HUNTING)) {
if (vict) {
SetHunting(point, vict);
lev--;
}
}
}
}
}
}
void StandUp(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
if ((GET_POS(ch) < POSITION_STANDING) && (GET_POS(ch) > POSITION_STUNNED)) {
if (ch->points.hit > (ch->points.max_hit / 2))
act("$n quickly stands up.", 1, ch, 0, 0, TO_ROOM);
else if (ch->points.hit > (ch->points.max_hit / 6))
act("$n slowly stands up.", 1, ch, 0, 0, TO_ROOM);
else
act("$n gets to $s feet very slowly.", 1, ch, 0, 0, TO_ROOM);
GET_POS(ch) = POSITION_STANDING;
}
}
void FighterMove(struct char_data *ch)
{
int num = 0;
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
num = number(1, 4);
switch (num) {
case 1:
if (!ch->skills[SKILL_BASH].learned)
ch->skills[SKILL_BASH].learned = 10 + GetMaxLevel(ch) * 4;
do_bash(ch, GET_NAME(ch->specials.fighting), 0);
break;
case 2:
if (ch->equipment[WIELD] || ch->equipment[WIELD_TWOH]) {
if (!ch->skills[SKILL_DISARM].learned)
ch->skills[SKILL_DISARM].learned = 10 + GetMaxLevel(ch) * 4;
do_disarm(ch, GET_NAME(ch->specials.fighting), 0);
} else {
if (!ch->skills[SKILL_DISARM].learned)
ch->skills[SKILL_DISARM].learned = 60 + GetMaxLevel(ch) * 4;
do_disarm(ch, GET_NAME(ch->specials.fighting), 0);
}
break;
case 3:
case 4:
if (!ch->skills[SKILL_KICK].learned)
ch->skills[SKILL_KICK].learned = 10 + GetMaxLevel(ch) * 4;
do_kick(ch, GET_NAME(ch->specials.fighting), 0);
break;
}
}
void DevelopHatred(struct char_data *ch, struct char_data *v)
{
if (DEBUG > 3)
log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch), SAFE_NAME(v));
if (DoesHate(ch, v))
return;
if (ch == v)
return;
/*
* diff = GET_ALIGNMENT(ch) - GET_ALIGNMENT(v);
* (diff > 0) ? diff : diff = -diff;
*
* diff /= 20;
*
* patience = (int) 100 * (float) (GET_HIT(ch) / GET_MAX_HIT(ch));
*
* var = number(1,40) - 20;
*
* if (patience+var < diff)
* AddHated(ch, v);
*/
AddHated(ch, v);
}
void Teleport(int current_pulse)
{
struct char_data *ch = NULL;
struct char_data *tmp = NULL;
struct char_data *pers = NULL;
struct obj_data *obj_object = NULL;
struct obj_data *temp_obj = NULL;
struct room_data *rp = NULL;
struct room_data *dest = NULL;
if (DEBUG > 3)
log_info("called %s with %d", __PRETTY_FUNCTION__, current_pulse);
if (current_pulse < 0)
return;
for (ch = character_list; ch; ch = ch->next) {
if (IS_NPC(ch))
continue;
rp = real_roomp(ch->in_room);
if (rp &&
(rp)->tele_targ > 0 &&
rp->tele_targ != rp->number &&
(rp)->tele_time > 0 && (current_pulse % (rp)->tele_time) == 0) {
dest = real_roomp(rp->tele_targ);
if (!dest) {
log_error("invalid tele_target:ROOM %s", rp->name);
continue;
}
obj_object = (rp)->contents;
while (obj_object) {
temp_obj = obj_object->next_content;
obj_from_room(obj_object);
obj_to_room(obj_object, (rp)->tele_targ);
obj_object = temp_obj;
}
while (rp->people /* should never fail */ ) {
/*
* find an NPC in the room
*/
for (tmp = rp->people; tmp; tmp = tmp->next_in_room) {
if (IS_NPC(tmp))
break;
}
if (tmp == NULL)
break; /* we've run out of NPCs */
char_from_room(tmp); /* the list of people in the room has changed */
char_to_room(tmp, rp->tele_targ);
if (IS_SET(dest->room_flags, DEATH)) {
death_cry(tmp);
if (IS_NPC(tmp) && (IS_SET(tmp->specials.act, ACT_POLYSELF))) {
/*
* take char from storage, to room
*/
pers = tmp->desc->original;
char_from_room(pers);
char_to_room(pers, tmp->in_room);
SwitchStuff(tmp, pers);
zero_rent(pers);
extract_char(tmp);
tmp = pers;
}
zero_rent(tmp);
extract_char(tmp);
}
}
char_from_room(ch);
char_to_room(ch, rp->tele_targ);
if (rp->tele_look) {
do_look(ch, "", 15);
}
if (IS_SET(dest->room_flags, DEATH) && GetMaxLevel(ch) < LOW_IMMORTAL) {
death_cry(ch);
if (IS_NPC(ch) && (IS_SET(ch->specials.act, ACT_POLYSELF))) {
/*
* take char from storage, to room
*/
pers = ch->desc->original;
char_from_room(pers);
char_to_room(pers, ch->in_room);
SwitchStuff(ch, pers);
zero_rent(ch);
extract_char(ch);
ch = pers;
}
zero_rent(ch);
extract_char(ch);
}
}
}
}
int HasObject(struct char_data *ch, int ob_num)
{
int j = 0;
int found = FALSE;
struct obj_data *i = NULL;
if (DEBUG > 3)
log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch), ob_num);
/*
* equipment too
*/
for (j = 0; j < MAX_WEAR; j++)
if (ch->equipment[j])
found += RecCompObjNum(ch->equipment[j], ob_num);
if (found > 0)
return (TRUE);
/*
* carrying
*/
for (i = ch->carrying; i; i = i->next_content)
found += RecCompObjNum(i, ob_num);
if (found > 0)
return (TRUE);
else
return (FALSE);
}
int room_of_object(struct obj_data *obj)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_ONAME(obj));
if (obj->in_room != NOWHERE)
return obj->in_room;
else if (obj->carried_by)
return obj->carried_by->in_room;
else if (obj->equipped_by)
return obj->equipped_by->in_room;
else if (obj->in_obj)
return room_of_object(obj->in_obj);
else
return NOWHERE;
}
struct char_data *char_holding(struct obj_data *obj)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_ONAME(obj));
if (obj->in_room != NOWHERE)
return NULL;
else if (obj->carried_by)
return obj->carried_by;
else if (obj->equipped_by)
return obj->equipped_by;
else if (obj->in_obj)
return char_holding(obj->in_obj);
else
return NULL;
}
int RecCompObjNum(struct obj_data *o, int obj_num)
{
int total = 0;
struct obj_data *i = NULL;
if (DEBUG > 3)
log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_ONAME(o), obj_num);
if (obj_index[o->item_number].virtual == obj_num)
total = 1;
if (ITEM_TYPE(o) == ITEM_CONTAINER) {
for (i = o->contains; i; i = i->next_content)
total += RecCompObjNum(i, obj_num);
}
return (total);
}
void RestoreChar(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
GET_MANA(ch) = GET_MAX_MANA(ch);
GET_HIT(ch) = GET_MAX_HIT(ch);
GET_MOVE(ch) = GET_MAX_MOVE(ch);
if (GetMaxLevel(ch) < LOW_IMMORTAL) {
GET_COND(ch, THIRST) = 24;
GET_COND(ch, FULL) = 24;
} else {
GET_COND(ch, THIRST) = -1;
GET_COND(ch, FULL) = -1;
}
}
void RemAllAffects(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
spell_dispel_magic(IMPLEMENTOR, ch, ch, 0);
}
const char *pain_level(struct char_data *ch)
{
int health_percent = 0;
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
if (GET_MAX_HIT(ch) > 0)
health_percent = (100 * GET_HIT(ch)) / GET_MAX_HIT(ch);
else
health_percent = -1; /* How could MAX_HIT be < 1?? */
if (health_percent >= 100)
return ("is in an excellent condition");
else if (health_percent >= 90)
return ("has a few scratches");
else if (health_percent >= 75)
return ("has some small wounds and bruises");
else if (health_percent >= 50)
return ("has quite a few wounds");
else if (health_percent >= 30)
return ("has some big nasty wounds and scratches");
else if (health_percent >= 15)
return ("looks pretty hurt");
else if (health_percent >= 0)
return ("is in an awful condition");
else
return ("is bleeding awfully from big wounds");
}
int IsWizard(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
if (!ch)
return 0;
return ch->player.class & CLASS_WIZARD;
}
int IsPriest(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
if (!ch)
return 0;
return ch->player.class & CLASS_PRIEST;
}
int IsMagical(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
if (!ch)
return 0;
return ch->player.class & CLASS_MAGICAL;
}
int IsFighter(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
if (!ch)
return 0;
return ch->player.class & CLASS_FIGHTER;
}
int IsSneak(struct char_data *ch)
{
if (DEBUG > 3)
log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));
if (!ch)
return 0;
return ch->player.class & CLASS_SNEAK;
}