wileymud-1.187b/
wileymud-1.187b/attic/
wileymud-1.187b/attic/bin/
wileymud-1.187b/attic/lib/
wileymud-1.187b/attic/lib/adm/
wileymud-1.187b/attic/lib/man/
wileymud-1.187b/attic/lib/new-wld/
wileymud-1.187b/attic/lib/new-wld/default/
wileymud-1.187b/attic/lib/old/
wileymud-1.187b/attic/lib/wld/
wileymud-1.187b/attic/public_html/
wileymud-1.187b/attic/public_html/gfx/
wileymud-1.187b/attic/src/bin/
wileymud-1.187b/attic/src/etc/
wileymud-1.187b/attic/src/libauth-4.0-p5/
wileymud-1.187b/attic/src/sedna/
wileymud-1.187b/backups/
wileymud-1.187b/bin/
wileymud-1.187b/docs/
wileymud-1.187b/etc/
wileymud-1.187b/lib/
wileymud-1.187b/lib/adm/
wileymud-1.187b/lib/boards/
wileymud-1.187b/lib/log/
wileymud-1.187b/lib/man/
wileymud-1.187b/lib/ply/
wileymud-1.187b/lib/ply/a/
wileymud-1.187b/lib/ply/b/
wileymud-1.187b/lib/ply/c/
wileymud-1.187b/lib/ply/d/
wileymud-1.187b/lib/ply/g/
wileymud-1.187b/lib/ply/k/
wileymud-1.187b/lib/ply/m/
wileymud-1.187b/lib/ply/s/
wileymud-1.187b/lib/ply/t/
wileymud-1.187b/public_html/gfx/
wileymud-1.187b/src/bin/
wileymud-1.187b/src/convert/attic/
wileymud-1.187b/src/convert/obj/
wileymud-1.187b/src/convert/perl/
wileymud-1.187b/src/convert/perl/MudConvert/
wileymud-1.187b/src/convert/perl/MudConvert/DUMP/
wileymud-1.187b/src/convert/perl/MudConvert/Report/
wileymud-1.187b/src/convert/perl/MudConvert/WileyMUD/
wileymud-1.187b/src/convert/perl/output/
wileymud-1.187b/src/convert/perl/output/DUMP/
wileymud-1.187b/src/convert/perl/output/Report/
wileymud-1.187b/src/convert/perl/output/WileyMUD/
wileymud-1.187b/src/etc/
wileymud-1.187b/src/etc/init.d/
wileymud-1.187b/src/etc/rc.d/
wileymud-1.187b/src/etc/rc.d/init.d/
wileymud-1.187b/src/lib/
wileymud-1.187b/src/lib/adm/
wileymud-1.187b/src/lib/boards/
wileymud-1.187b/src/lib/log/
wileymud-1.187b/src/lib/man/
wileymud-1.187b/src/lib/ply/
wileymud-1.187b/src/lib/ply/a/
wileymud-1.187b/src/lib/ply/b/
wileymud-1.187b/src/lib/ply/c/
wileymud-1.187b/src/lib/ply/d/
wileymud-1.187b/src/lib/ply/e/
wileymud-1.187b/src/lib/ply/f/
wileymud-1.187b/src/lib/ply/g/
wileymud-1.187b/src/lib/ply/h/
wileymud-1.187b/src/lib/ply/i/
wileymud-1.187b/src/lib/ply/j/
wileymud-1.187b/src/lib/ply/k/
wileymud-1.187b/src/lib/ply/l/
wileymud-1.187b/src/lib/ply/m/
wileymud-1.187b/src/lib/ply/n/
wileymud-1.187b/src/lib/ply/o/
wileymud-1.187b/src/lib/ply/p/
wileymud-1.187b/src/lib/ply/q/
wileymud-1.187b/src/lib/ply/r/
wileymud-1.187b/src/lib/ply/s/
wileymud-1.187b/src/lib/ply/t/
wileymud-1.187b/src/lib/ply/u/
wileymud-1.187b/src/lib/ply/v/
wileymud-1.187b/src/lib/ply/w/
wileymud-1.187b/src/lib/ply/x/
wileymud-1.187b/src/lib/ply/y/
wileymud-1.187b/src/lib/ply/z/
wileymud-1.187b/src/obj/
wileymud-1.187b/src/utils/
wileymud-1.187b/src/utils/mobmaker/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>

#include "global.h"
#include "bug.h"
#include "utils.h"

#include "act_off.h"
#include "comm.h"
#include "db.h"
#include "mudlimits.h"
#include "multiclass.h"
#include "spells.h"

#define _BREATH_WEAPONS_C
#include "breath_weapons.h"

static funcp                            breaths[] = {
    (funcp)cast_acid_breath,
    NULL,
    (funcp)cast_frost_breath,
    NULL,
    (funcp)cast_lightning_breath,
    NULL,
    (funcp)cast_fire_breath,
    NULL,
    (funcp)cast_acid_breath, (funcp)cast_fire_breath, (funcp)cast_lightning_breath,
    NULL
};

struct breather                         breath_monsters[] = {
    {5030, 15, breaths + 6},
    {-1},
};

struct breath_victim                   *choose_victims(struct char_data *ch,
						       struct char_data *first_victim)
{
    /*
     * this is goofy, dopey extraordinaire 
     */
    struct char_data                       *cons = NULL;
    struct breath_victim                   *head = NULL;
    struct breath_victim                   *temp = NULL;

    if (DEBUG > 2)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch),
		 SAFE_NAME(first_victim));

    for (cons = real_roomp(ch->in_room)->people; cons; cons = cons->next_in_room) {
	CREATE_VOID(temp, struct breath_victim, 1);

	temp->ch = cons;
	temp->next = head;
	head = temp;
	if (first_victim == cons) {
	    temp->yesno = 1;
	} else if (ch == cons) {
	    temp->yesno = 0;
	} else if ((in_group(first_victim, cons) ||
		    cons == first_victim->master ||
		    cons->master == first_victim) && (temp->yesno = (3 != dice(1, 5)))) {
	    /*
	     * group members will get hit 4/5 times 
	     */
	} else if (cons->specials.fighting == ch) {
	    /*
	     * people fighting the dragon get hit 4/5 times 
	     */
	    temp->yesno = (3 != dice(1, 5));
	} else						       /* bystanders get his 2/5 times */
	    temp->yesno = (dice(1, 5) < 3);
    }
    return head;
}

void free_victims(struct breath_victim *head)
{
    struct breath_victim                   *temp = NULL;

    if (DEBUG > 2)
	log_info("called %s with %08zx", __PRETTY_FUNCTION__, (size_t) head);

    while (head) {
	temp = head->next;
	DESTROY(head);
	head = temp;
    }
}

int breath_weapon(struct char_data *ch, struct char_data *target, int mana_cost, funcp func)
{
    struct breath_victim                   *hitlist = NULL;
    struct breath_victim                   *scan = NULL;
    int                                     victim = 0;

    if (DEBUG > 2)
	log_info("called %s with %s, %s, %d, %08zx", __PRETTY_FUNCTION__, SAFE_NAME(ch),
		 SAFE_NAME(target), mana_cost, (size_t) func);

    hitlist = choose_victims(ch, target);

    act("$n rears back and inhales", 1, ch, 0, ch->specials.fighting, TO_ROOM);
    victim = 0;
    for (scan = hitlist; scan; scan = scan->next) {
	if (!scan->yesno || IS_IMMORTAL(scan->ch) || scan->ch->in_room != ch->in_room	/* this should not happen */
	    )
	    continue;
	victim = 1;
	cast_fear(GetMaxLevel(ch), ch, "", SPELL_TYPE_SPELL, scan->ch, 0);
    }

    if (func != NULL && victim) {
	act("$n Breathes...", 1, ch, 0, ch->specials.fighting, TO_ROOM);

	for (scan = hitlist; scan; scan = scan->next) {
	    if (!scan->yesno || IS_IMMORTAL(scan->ch) || scan->ch->in_room != ch->in_room	/* this could happen if 
												 * someone fled, I
												 * guess */
		)
		continue;
	    func(GetMaxLevel(ch), ch, "", SPELL_TYPE_SPELL, scan->ch, 0);
	}
	GET_MANA(ch) -= mana_cost;
    } else {
	act("$n Breathes...coughs and sputters...", 1, ch, 0, ch->specials.fighting, TO_ROOM);
	do_flee(ch, "", 0);
    }
    free_victims(hitlist);
    return TRUE;
}

void use_breath_weapon(struct char_data *ch, struct char_data *target, int cost, funcp func)
{
    if (DEBUG > 2)
	log_info("called %s with %s, %s, %d, %08zx", __PRETTY_FUNCTION__, SAFE_NAME(ch),
		 SAFE_NAME(target), cost, (size_t) func);

    if (GET_MANA(ch) >= 0) {
	breath_weapon(ch, target, cost, func);
    } else if ((GET_HIT(ch) < GET_MAX_HIT(ch) / 2) && (GET_MANA(ch) >= -cost)) {
	breath_weapon(ch, target, cost, func);
    } else if ((GET_HIT(ch) < GET_MAX_HIT(ch) / 4) && (GET_MANA(ch) >= -2 * cost)) {
	breath_weapon(ch, target, cost, func);
    } else if (GET_MANA(ch) <= -3 * cost) {
	breath_weapon(ch, target, 0, NULL);		       /* sputter */
    }
}

int BreathWeapon(struct char_data *ch, int cmd, const char *arg)
{
    struct breather                        *scan = NULL;
    int                                     count = 0;

    if (DEBUG > 2)
	log_info("called %s with %s, %d, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch), cmd,
		 VNULL(arg));

    if (cmd)
	return FALSE;

    if (ch->specials.fighting && (ch->specials.fighting->in_room == ch->in_room)) {

	for (scan = breath_monsters;
	     scan->vnum >= 0 && scan->vnum != mob_index[ch->nr].virtual; scan++);

	if (scan->vnum < 0) {
	    log_info("monster %s tries to breath, but isn't listed.", ch->player.short_descr);
	    return FALSE;
	}
	for (count = 0; scan->breaths[count]; count++);

	if (count < 1) {
	    log_info("monster %s has no breath weapons", ch->player.short_descr);
	    return FALSE;
	}
	use_breath_weapon(ch, ch->specials.fighting, scan->cost,
			  scan->breaths[dice(1, count) - 1]);
    }
    return TRUE;
}