/* * Drop-in code that can replace any use of send_to_char * for dynamic room descriptions, character and object * descs, extra descs and anything else. Idea from a post * on kyndig.com: thought about, discarded, thought about * again, nagged by, forgotten, remembered and finally * coded in self defense to shut the little voice in my * head up. * * Requirements: OLC -or- the format_string function from * Ivan Toledo's OLC. Not really required, but won't look * nicely formatted without it. * * No credit required. Contact me if you have interesting * projects: imapopsyckle@hotmail.com. New coders welcome. * Queries of a below average IQ level amusingly mocked. * * Written for Rot 1.4, compatible with ROM with minor * changes to allow for small differences. */ /* * Notes: * * This supports room "taglines" much like HTML tags if * you've ever played with making webpages. They look like * this: * [#weather sunny: The sun shines on a field of flowers.] * [#sex male: A pretty barmaid winks at you as she goes about.] * [#wis > 16: You notice a sale on dresses in your size.] * [#name: The mirror shows your reflection $.] * * It is important to note that the operators can't really be * combined: I was just too lazy to go through the process of * determining how they combine and affect the outcome. If you * want something like 'wis >= 15', feel free to write it in. * * To Install: * Add this line to merc.h under the "/* act_info.c */" header: * void tagline_to_char args( ( const char *text, CHAR_DATA *ch ) ); * * Drop the following function into act_info.c anywhere you * like. If you want to make your own taglines, there's a * section below marked for it, the format should be simple if * you have code experience. Now anywhere that send_to_char * is used to send players a description, such as do_look in the * act_info.c file, just replace send_to_char with this function. * This: "send_to_char(ch->in_room->description, ch);" * To this: "tagline_to_char(ch->in_room->description, ch);" * * Other things might be sending extra descs to players, or * showing players' descriptions to each other. Your choice. * Examples and arguments are listed below the code. */ void tagline_to_char(const char *text, CHAR_DATA *ch) { /* If it's an empty string, save some time. */ if (strlen(text) <= 0) { return; } char output[MAX_STRING_LENGTH]; char tagline[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; char arg[256]; char arg2[256]; int value; bool bGo = FALSE; const char *desc; char *p_output = output; char *common; for (desc = text; *desc; desc++) { /* Reset. */ bGo = FALSE; value = 0; if (*desc != '[') { *p_output = *desc; *++p_output = '\0'; continue; } if (*++desc != '#') { *p_output = *--desc; *++p_output = '\0'; continue; } /* Skip beginning '[#'. */ ++desc; /* Read in the tag. */ common = buf; while(*desc != ':') { if (*desc == '\0') { logf("Error: tag has no parser ':'. Room: %d.", ch->in_room->vnum); *common = *desc; break; } *common = *desc; *++common = '\0'; ++desc; } /* Skip the colon and space ': '. */ desc += 2; /* Read in the description. */ common = tagline; while (*desc != ']') { if (*desc == '\0') { logf("Error: tag has no ending ']'. Room: %d.", ch->in_room->vnum); *common = *desc; break; } *common = *desc; *++common = '\0'; ++desc; } /* Separate the arguments. */ common = buf; common = one_argument(common, arg); common = one_argument(common, arg2); if (is_number(common)) { value = atoi(common); } else if (strlen(common) > 0) { logf("Tag in room %d is odd: %s %s %s.", ch->in_room->vnum, arg, arg2, common); } /*======[ Cases ]======*/ switch (UPPER(arg[0])) { case 'A': if (!str_cmp(arg, "age")) { if (value < 0) { bGo = FALSE; } else { switch (arg2[0]) { case '>': if (get_age(ch) > value) { bGo = TRUE; }; break; case '<': if (get_age(ch) < value) { bGo = TRUE; }; break; case '=': if (get_age(ch) == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } } else if (!str_cmp(arg, "align") || !str_cmp(arg, "alignment")) { if (!str_cmp(arg2, "good") && (ch->alignment > 250)) { bGo = TRUE; } else if (!str_cmp(arg2, "evil") && (ch->alignment < -250)) { bGo = TRUE; } else if (!str_cmp(arg2, "nuetral") && ((ch->alignment < 250) && (ch->alignment > -250)) ) { bGo = TRUE; } } break; case 'C': if (!str_cmp(arg, "con")) { switch (arg2[0]) { case '>': if (get_curr_stat(ch, STAT_CON) > value) { bGo = TRUE; }; break; case '<': if (get_curr_stat(ch, STAT_CON) < value) { bGo = TRUE; }; break; case '=': if (get_curr_stat(ch, STAT_CON) == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } else if (!str_cmp(arg, "class")) { if (class_lookup(arg2) == ch->class) { bGo = TRUE; } } break; case 'D': if (!str_cmp(arg, "dex")) { switch (arg2[0]) { case '>': if (get_curr_stat(ch, STAT_DEX) > value) { bGo = TRUE; }; break; case '<': if (get_curr_stat(ch, STAT_DEX) < value) { bGo = TRUE; }; break; case '=': if (get_curr_stat(ch, STAT_DEX) == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } else if (!str_cmp(arg, "day")) { switch (arg2[0]) { case '>': if (time_info.day > value) { bGo = TRUE; }; break; case '<': if (time_info.day < value) { bGo = TRUE; }; break; case '=': if (time_info.day == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } break; case 'G': if (!str_cmp(arg, "gold")) { if (value < 0) { bGo = FALSE; } else { switch (arg2[0]) { case '>': if (ch->gold > value) { bGo = TRUE; }; break; case '<': if (ch->gold < value) { bGo = TRUE; }; break; case '=': if (ch->gold == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } } break; case 'I': if (!str_cmp(arg, "int")) { switch (arg2[0]) { case '>': if (get_curr_stat(ch, STAT_INT) > value) { bGo = TRUE; }; break; case '<': if (get_curr_stat(ch, STAT_INT) < value) { bGo = TRUE; }; break; case '=': if (get_curr_stat(ch, STAT_INT) == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } break; case 'L': if (!str_cmp(arg, "level")) { if (value < 1) { bGo = FALSE; } else { switch (arg2[0]) { case '>': if (ch->level > value) { bGo = TRUE; }; break; case '<': if (ch->level < value) { bGo = TRUE; }; break; case '=': if (ch->level == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } } break; case 'M': if (!str_cmp(arg, "month")) { if (value < 1) { bGo = FALSE; } else { switch (arg2[0]) { case '>': if (time_info.month > value) { bGo = TRUE; }; break; case '<': if (time_info.month < value) { bGo = TRUE; }; break; case '=': if (time_info.month == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } } break; case 'N': if (!str_cmp(arg, "name")) { bGo = TRUE; char p_name[128]; common = buf; char *t = tagline; char *n; while (*t != '\0') { if (*t != '$') { *common = *t; *++common = '\0'; ++t; continue; } sprintf(p_name, "%s", ch->name); n = p_name; while (*n != '\0') { *common = *n; *++common = '\0'; ++n; } ++t; } sprintf(tagline, "%s", buf); } break; case 'P': if (!str_cmp(arg, "plat") || !str_cmp(arg, "platinum")) { if (value < 0) { bGo = FALSE; } else { switch (arg2[0]) { case '>': if (ch->platinum > value) { bGo = TRUE; }; break; case '<': if (ch->platinum < value) { bGo = TRUE; }; break; case '=': if (ch->platinum == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } } break; case 'R': if (!str_cmp(arg, "race")) { if (race_lookup(arg2) == ch->race) { bGo = TRUE; } } break; case 'S': if (!str_cmp(arg, "sex")) { if (sex_lookup(arg2) == ch->sex) { bGo = TRUE; } } else if (!str_cmp(arg, "silver")) { if (value < 0) { bGo = FALSE; } else { switch (arg2[0]) { case '>': if (ch->silver > value) { bGo = TRUE; }; break; case '<': if (ch->silver < value) { bGo = TRUE; }; break; case '=': if (ch->silver == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } } else if (!str_cmp(arg, "str")) { switch (arg2[0]) { case '>': if (get_curr_stat(ch, STAT_STR) > value) { bGo = TRUE; }; break; case '<': if (get_curr_stat(ch, STAT_STR) < value) { bGo = TRUE; }; break; case '=': if (get_curr_stat(ch, STAT_STR) == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } else if (!str_cmp(arg, "sun")) { if (!str_cmp(arg2, "sunrise") && (weather_info.sunlight == SUN_RISE)) { bGo = TRUE; } else if (!str_cmp(arg2, "sunset") && (weather_info.sunlight == SUN_SET)) { bGo = TRUE; } else if (!str_cmp(arg2, "day") && (weather_info.sunlight == SUN_LIGHT)) { bGo = TRUE; } else if (!str_cmp(arg2, "night") && (weather_info.sunlight == SUN_DARK)) { bGo = TRUE; } } break; case 'T': if (!str_cmp(arg, "time")) { if (value < 0 || value > 24) { bGo = FALSE; } else { switch (arg2[0]) { case '>': if (time_info.hour > value) { bGo = TRUE; }; break; case '<': if (time_info.hour < value) { bGo = TRUE; }; break; case '=': if (time_info.hour == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } } break; case 'W': if (!str_cmp(arg, "wis")) { switch (arg2[0]) { case '>': if (get_curr_stat(ch, STAT_WIS) > value) { bGo = TRUE; }; break; case '<': if (get_curr_stat(ch, STAT_WIS) < value) { bGo = TRUE; }; break; case '=': if (get_curr_stat(ch, STAT_WIS) == value) { bGo = TRUE; }; break; default: bGo = FALSE; break; } } else if (!str_cmp(arg, "weather")) { if (!str_cmp(arg2, "sunny") && (weather_info.sky == SKY_CLOUDLESS)) { bGo = TRUE; } else if (!str_cmp(arg2, "cloudy") && (weather_info.sky == SKY_CLOUDY)) { bGo = TRUE; } else if (!str_cmp(arg2, "rainy") && (weather_info.sky == SKY_RAINING)) { bGo = TRUE; } else if (!str_cmp(arg2, "lightning") && (weather_info.sky == SKY_LIGHTNING)) { bGo = TRUE; } } break; default: bGo = FALSE; break; } /*======[End Cases]======*/ /* Copy in the tagline. */ if (bGo == TRUE) { common = tagline; while (*common != '\0') { if (strlen(output) >= (MAX_STRING_LENGTH - 1)) { break; } *p_output = *common; ++common; *++p_output = '\0'; } } } /* ^=--> End of for. */ /* Send the whole thing to the player. */ common = str_dup(strdup(output)); common = format_string(common); send_to_char(common, ch); free_string(common); return; } /**********[ Examples ]************** Rooms: [#weather rainy: Rain drips from overhangings and clotheslines.] [#weather lightning: Bolts of lightning periodically strike treetops.] [#weather sunny: A mysterious figure shades their face from the sun beneath a cowl.] [#wis > 14: You sense something unusual about the oakwood ahead.] [#sex female: You catch several men staring at you with interest.] [#name: Your guild is to the north $.] [#time = 19: The sun is setting above the rooftops.] [#class thief: Wealthy shoppers are practically begging to be robbed.] [#class cleric: A crowd of cripples stare at you with desperate hope.] Mobs: [#int > 14: You notice rune tattoos on their skin.] [#class warrior: It looks like a rough match-up with this creature.] [#sex male: She doesn't look like the sweep-me-off-my-feet type.] [#weather rainy: Rain cleans the filth from this troll's hide.] [#align evil: This looks like your kind of rotten guy!] Objects: [#name: This degree is for $ as a Graduate of Mud School.] [#str < 10: This sword appears too heavy for you to use effectively.] [#weather sunny: Sunlight gleams off of the well polished mace head.] [#name: A small tag on the side says 'Made for $'.] Tag Name Usage ----------- --------------- str [#str < 9: You're a weakling!] int [#int > 15: You're a smart cookie.] wis [#wis = 10: You're no wiser than normal.] dex [#dex < 9: You stumble over your own feet.] con [#con > 17: You've never been sick once.] age [#age < 21: This bar is not open to minors.] sun [#sun sunset: The sunset through the leaves is nice.] time [#time > 19: Thieves come out with the night.] day [#day = 20: Today is Ribbon Day!] month [#month = 12: It is the depths of winter.] weather [#weather rainy: Rain drips from the rooflines.] plat [#plat < 2: Merchants sneer at your poor appearance.] gold [#gold > 40: You draw the eye of every thief here.] silver [#silver > 90: Beggars look at you hopefully.] level [#level < 50: These creatures look too hard for you.] sex [#sex female: The bartender hurries to fill your order.] race [#race human: Humans are not welcome in the village.] class [#class thief: The bodies of failed thieves rot here.] align [#align evil: This place stinks of holiness.] name [#name: Your guild is to the north $.] Tag Name Arguments ------------ -------------- All Stats > < = Age > < = Sun sunrise, sunset, day, night Time > < = (Time is in hours, from 1 - 24) Day > < = (There are 35 days to a month) Month > < = (There are 17 months in a year) Weather sunny, cloudy, rainy, lightning Platinum > < = Gold > < = Silver > < = Level > < = Alignment good, evil, nuetral Sex male, female, none, either Race (any race name you have) Class (any class name you have) Name (no arguments) ***********************************/