/* ************************************************************************ * File: specials.c EmpireMUD AD 1.0 * * Usage: houses special procedures and their protocols * * * * All rights reserved. See license.doc for complete information. * * * * Code base by Paul Clarke. EmpireMUD Project, a tbgMUD Production. * * Based upon CircleMUD 3.0, beta patch level 17, by Jeremy Elson. * * * * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * ************************************************************************ */ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "db.h" #include "comm.h" #include "handler.h" #include "interpreter.h" #include "skills.h" #include "empire.h" #include "vnums.h" /* ** Introduction ****************************************************** * This file is used for handling functions for special procedures, and the procedures themselves for mobs and objects. While they resemble those standard to CircleMUD, they are not the same. I have written them in a way which I feel is more economical for EmpireMUD because it is designed to have a much greater number of creatures and objects. * ********************************************************************** */ /* ** Definitions ******************************************************* */ #define MOB_SPECIAL Creature mob = (Creature) me #define OBJ_SPECIAL Object obj = (Object) me /* ** Prototypes ******************************************************** */ SPECIAL(spec_bee_hive); LOOK_SPECIAL(lspec_bee_hive); LOOK_SPECIAL(lspec_ship_window); LOOK_SPECIAL(lspec_bad_mirror); LOOK_SPECIAL(lspec_mirror); /* ** Tables ************************************************************ */ struct special_procedure_table obj_spec[] = { { 0, "none", NULL, NULL }, { 1, "bee hive", spec_bee_hive, lspec_bee_hive }, { 2, "ship window", NULL, lspec_ship_window }, { 3, "bad mirror", NULL, lspec_bad_mirror }, { 4, "mirror", NULL, lspec_mirror }, /* this entry must be last */ { -1, "none", NULL, NULL } }; struct special_procedure_table mob_spec[] = { { 0, "none", NULL, NULL }, /* this entry must be last */ { -1, "none", NULL, NULL } }; /* ** Handlers ********************************************************** */ /* updates object spec proc: called from point_update */ void update_object_special(Object obj) { if (GET_OBJ_RNUM(obj) != NOTHING && obj_index[GET_OBJ_RNUM(obj)].spec_proc) (obj_index[GET_OBJ_RNUM(obj)].spec_proc) (obj); } /* updates mobile spec proc: called from point_update */ void update_mobile_special(Creature mob) { if (GET_MOB_RNUM(mob) != NOTHING && obj_index[GET_MOB_RNUM(mob)].spec_proc) (mob_index[GET_MOB_RNUM(mob)].spec_proc) (mob); } /* functions for accessing the tables */ int find_obj_special_by_number(int number) { int i; for (i = 0; obj_spec[i].number != -1; i++) if (obj_spec[i].number == number) return i; return -1; } int find_mob_special_by_number(int number) { int i; for (i = 0; mob_spec[i].number != -1; i++) if (mob_spec[i].number == number) return i; return -1; } int find_obj_spec_by_function(SPECIAL(*func)) { int i; for (i = 0; obj_spec[i].number != -1; i++) if (obj_spec[i].spec_proc == func) return i; return -1; } int find_obj_look_spec_by_function(LOOK_SPECIAL(*func)) { int i; for (i = 0; obj_spec[i].number != -1; i++) if (obj_spec[i].look_spec == func) return i; return -1; } int find_mob_spec_by_function(SPECIAL(*func)) { int i; for (i = 0; mob_spec[i].number != -1; i++) if (mob_spec[i].spec_proc == func) return i; return -1; } int find_mob_look_spec_by_function(LOOK_SPECIAL(*func)) { int i; for (i = 0; mob_spec[i].number != -1; i++) if (mob_spec[i].look_spec == func) return i; return -1; } /* ** Object Procedures ************************************************ */ SPECIAL(spec_bee_hive) { OBJ_SPECIAL; /* * This spec controls the flow of a bee hive object, which is used * to grow wax and honey. To be as realistic as possible, it will * keep track of its population and other factors, and use seasons * so that the bees will die if you steal all their honey. */ #define Population GET_OBJ_VAL(obj, 0) #define Honey GET_OBJ_VAL(obj, 1) #define Wax GET_OBJ_VAL(obj, 2) /* only work if in a room */ if (obj->in_room == NOWHERE) return; if (number(0, 23)) return; switch (get_season()) { case SEASON_WINTER: if (Population > Honey) Population -= 5; Honey -= Population / 25; break; case SEASON_SPRING: Population += 2; Honey -= Population / 25; break; case SEASON_SUMMER: Population += 5; Honey += Population / 25; Wax += Population / 25; break; case SEASON_AUTUMN: Honey += Population / 5; Wax += Population / 5; break; } /* idiot checks */ Population = MAX(0, MIN(Population, 200)); Honey = MAX(0, MIN(Honey, 1000)); Wax = MAX(0, MIN(Wax, 1000)); } LOOK_SPECIAL(lspec_bee_hive) { OBJ_SPECIAL; /* * This spec displays the status of a beehive. */ #define Population GET_OBJ_VAL(obj, 0) #define Honey GET_OBJ_VAL(obj, 1) #define Wax GET_OBJ_VAL(obj, 2) switch (Population / 40) { case 0: sprintf(buf, "The hive seems strangely vacant."); break; case 1: sprintf(buf, "A few bees swarm around the hive."); break; case 2: sprintf(buf, "Bees swarm around the hive."); break; case 3: sprintf(buf, "The hive is swarming with bees."); break; case 4: sprintf(buf, "Bees swarm all over this hive!"); break; case 5: sprintf(buf, "As you approach the hive, you find yourself overwhelmed with bees!"); break; } msg_to_char(ch, "%s You find it to be %d%% full of honey and %d%% full of wax.\r\n", buf, (int) (Honey * 100 / 1000), (int) (Wax * 100 / 1000)); return TRUE; } LOOK_SPECIAL(lspec_ship_window) { OBJ_SPECIAL; /* * This spec shows what's outside of a ship to a person on deck when * he looks at the window. */ Object ship; if (!(ship = world[HOME_ROOM(obj->in_room)].boat)) msg_to_char(ch, "Unable to find ship associated with this window!\r\n"); else look_at_room_by_rnum(ch, ship->in_room); return TRUE; } LOOK_SPECIAL(lspec_bad_mirror) { OBJ_SPECIAL; /* * This spec is for tarnished, low-quality mirrors. */ act("$p is too tarnished to see a good reflection.", FALSE, ch, obj, 0, TO_CHAR); return TRUE; } LOOK_SPECIAL(lspec_mirror) { OBJ_SPECIAL; /* * This spec is used to look at your own description, and to see Lasombra. */ void look_at_char(Creature i, Creature ch, bool eq, bool self); Creature i; /* Clan weakness: Lasombra */ if (GET_CLAN(ch) == CLAN_LASOMBRA) msg_to_char(ch, "You have no reflection!\r\n"); else { act("You at your reflection in $p.", FALSE, ch, obj, 0, TO_CHAR); look_at_char(ch, ch, FALSE, TRUE); } /* Clan weakness: Lasombra */ for (i = world[ch->in_room].people; i; i = i->next_in_room) if (GET_CLAN(i) == CLAN_LASOMBRA && ch != i && CAN_SEE(ch, i) && ww_dice(GET_PERCEPTION(ch) + GET_ALERTNESS(ch), GET_WITS(i) + GET_STEALTH(i) - SENSES_BONUS(ch)) > 0) act("Looking over your shoulder, you notice that $N has no reflection!", TRUE, ch, 0, i, TO_CHAR); /* Oops */ act("$n looks into $p.", TRUE, ch, obj, 0, TO_ROOM); return TRUE; } /* ** Mobile Procedures ************************************************ */