/****************************************************************************** Snippet: Wilderness system (v1.0). Author: Richard Woolcock (aka KaVir). Date: 2nd September 1998. ****************************************************************************** File: wild_spec.c Purpose: Deals with special wilderness mobs. ****************************************************************************** This code is copyright (C) 1998 by Richard Woolcock. It may be used and distributed freely, as long as you do not remove this copyright notice. ******************************************************************************/ /****************************************************************************** Required libraries ******************************************************************************/ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "wild.h" /****************************************************************************** Local operation prototypes ******************************************************************************/ int close_room args( ( CHAR_DATA *ch, int x, int y ) ); int walk_room args( ( CHAR_DATA *ch, int x, int y ) ); bool check_forest args( ( int x, int y ) ); /****************************************************************************** Global operations ******************************************************************************/ /* Wild animal special procedures. */ bool spec_wildmob( CHAR_DATA *ch ) { CHAR_DATA *victim; bool del_char = TRUE; if (ch->in_room == NULL) { return ( FALSE ); } for ( victim = ch->in_room->people; victim; victim = victim->next_in_room ) { if (victim == ch) continue; if (!IS_NPC(victim) || victim->pIndexData->vnum >= 100 ) { del_char = FALSE; break; } } if (del_char) { extract_char(ch,TRUE); return ( TRUE ); } if ( !IS_AWAKE(ch) || number_range(1,3) > 1 || ch->position == POS_FIGHTING ) { return ( FALSE ); } switch (ch->pIndexData->vnum) { default: break; case MOB_VNUM_SHARK: switch (number_range(1,3)) { default: case 1: act("$n lashes $s tail.",ch,NULL,NULL,TO_ROOM); break; case 2: act("$n glances hungrilly around.",ch,NULL,NULL,TO_ROOM); break; case 3: act("$n snaps its huge teeth.",ch,NULL,NULL,TO_ROOM); break; } break; case MOB_VNUM_BEAR: switch (number_range(1,3)) { default: case 1: act("$n snarls at you.",ch,NULL,NULL,TO_ROOM); break; case 2: act("$n growls to $mself.",ch,NULL,NULL,TO_ROOM); break; case 3: act("$n licks $s paw.",ch,NULL,NULL,TO_ROOM); break; } break; case MOB_VNUM_WOLF: switch (number_range(1,3)) { default: case 1: act("$n snarls at you.",ch,NULL,NULL,TO_ROOM); break; case 2: act("$n growls to $mself.",ch,NULL,NULL,TO_ROOM); break; case 3: act("$n throws back $s head and howls.",ch,NULL,NULL,TO_ROOM); break; } break; } return ( FALSE ); } /* Lumberjack, goes around chopping down trees. */ bool spec_lumberjack( CHAR_DATA *ch ) { OBJ_DATA *axe; int x,y; if ( ch->in_room == NULL ) { return ( FALSE ); } if ( !IS_AWAKE(ch) ) return ( spec_wildmob(ch) ); if (ch->quality > 0) return ( TRUE ); if (ch->home_x < 0 || ch->home_y < 0) { for ( x = ch->x - 50; x <= ch->x + 50; x++ ) { for ( y = ch->y - 50; y <= ch->y + 50; y++ ) { if (check_forest(x,y)) { if (ch->home_x < 0 || ch->home_y < 0 || close_room(ch,x,y) <= close_room(ch,ch->home_x, ch->home_y)) { if (close_room(ch,x,y) < close_room(ch,ch->home_x, ch->home_y) || number_range(1,2) == 1) { ch->home_x = x; ch->home_y = y; } } } } } if (ch->home_x < 0 && ch->home_y < 0) { do_say(ch,"Bah...there are no tree's to cut down...I'm taking a nap..."); do_sleep(ch,""); return ( TRUE ); } } else if (ch->home_x == ch->x && ch->home_y == ch->y && !check_forest(ch->x,ch->y)) { do_say(ch,"Time to find some more trees!"); ch->home_x = -1; ch->home_y = -1; return ( TRUE ); } if (get_obj_wear(ch,"axe") == NULL) { if ( ( axe = get_eq_char(ch, WEAR_WIELD) ) == NULL || axe->item_type != ITEM_WEAPON || axe->value[3] != 1 ) { if ( ( axe = get_eq_char(ch, WEAR_HOLD) ) == NULL || axe->item_type != ITEM_WEAPON || axe->value[3] != 1 ) { if ( ( axe = create_object(get_obj_index(OBJ_VNUM_AXE),0) ) != NULL ) { obj_to_char(axe,ch); do_wear(ch,"axe"); do_say(ch,"Time to chop down some trees!"); return ( TRUE ); } } } } if ( ch->position <= POS_RESTING ) { do_stand(ch,""); return ( TRUE ); } if (ch->x != ch->home_x || ch->y != ch->home_y) { switch (walk_room(ch,ch->home_x,ch->home_y)) { default: ch->home_x = -1; ch->home_y = -1; break; case DIR_NORTH: do_north(ch,""); break; case DIR_SOUTH: do_south(ch,""); break; case DIR_EAST: do_east(ch,""); break; case DIR_WEST: do_west(ch,""); break; } } else if (check_forest(ch->x,ch->y) && ch->quality <= 0 && ch->home_x >= 0 && ch->home_y >= 0) { do_say(ch,"Just what I was after!"); do_chop(ch,""); } return ( TRUE ); } /****************************************************************************** Local operations ******************************************************************************/ /* Returns the number of rooms away the specified location is. */ int close_room( CHAR_DATA *ch, int x, int y ) { while (x < 0) x += 1000; while (y < 0) y += 1000; while (x >= 1000) x -= 1000; while (y >= 1000) y -= 1000; x = ch->x > x ? ch->x - x : x - ch->x; y = ch->y > y ? ch->y - y : y - ch->y; if (x >= 500) x -= 1000; else if (x < -500) x += 1000; if (y >= 500) y -= 1000; else if (y < -500) y += 1000; return ( x + y ); } /* Returns the direction that should be walked to get to the specified room. * If you are there already, it returns -1. */ int walk_room( CHAR_DATA *ch, int x, int y ) { int xx, yy; while (x < 0) x += 1000; while (y < 0) y += 1000; while (x >= 1000) x -= 1000; while (y >= 1000) y -= 1000; xx = ch->x - x; yy = ch->y - y; if (xx > 500) xx -= 1000; else if (xx <= -500) xx += 1000; if (yy > 500) yy -= 1000; else if (yy <= -500) yy += 1000; if (xx == 0 && yy == 0) { return ( -1 ); } else if (xx == 0) { if (yy < 0) { return ( DIR_NORTH ); } else { return ( DIR_SOUTH ); } } else if (yy == 0) { if (xx < 0) { return ( DIR_EAST ); } else { return ( DIR_WEST ); } } else { switch (number_range(1,2)) { default: case 1: if (xx < 0) return ( DIR_EAST ); else return ( DIR_WEST ); break; case 2: if (yy < 0) return ( DIR_NORTH ); else return ( DIR_SOUTH ); break; } } return ( -1 ); } /* Returns TRUE if the specified location is a forest. */ bool check_forest( int x, int y ) { bool is_forest; while (x < 0) x += 1000; while (y < 0) y += 1000; while (x >= 1000) x -= 1000; while (y >= 1000) y -= 1000; switch (map_data(x,y)) { default: is_forest = FALSE; break; case WILD_FOREST_1: case WILD_FOREST_2: case WILD_FOREST_3: case WILD_FOREST_4: is_forest = TRUE; break; } return ( is_forest ); }