// Process the main text into lines that fix into the pop-up window // void Achievement::prepare(int win_x, int font_x, int border) { if (prepared) return; prepared = true; int col = 0; std::string::size_type last_space = 0; std::string::size_type start = 0; int chars_per_line = (win_x - 2 * border) / font_x; for (std::string::size_type i=0; i<text.size(); i++) { if (is_color(text[i])) continue; if (text[i] == ' ') last_space = i; if (col >= chars_per_line) { lines.push_back(text.substr(start, last_space-start)); start = last_space+1; col = i - start; } col++; } if (start < text.size()) lines.push_back(text.substr(start, text.size()-start)); }
void extract_text(struct image *img) { int y, x, sx; CHAR *buf, *s; struct rgb rgb; struct component *c, *last_c = NULL; int shape; struct text *t, *last_t = NULL; buf = malloc(sizeof(CHAR)*img->w); if (!buf) croak(1, "extract_text:malloc(buf)"); for (y = 0; y < img->h; y++) { last_c = NULL; last_t = NULL; for (x = 0; x < img->w; x++) { s = buf; sx = x; while (img->d[y][x] != ' ' && component_marks->d[y][x] == ' ') { *s++ = img->d[y][x++]; } *s = '\0'; if (s != buf) { printf("%d,%d: |%s|\n", y, sx, buf); c = find_enclosing_component(&components, y, sx); if (is_color(buf, &rgb) && c) { double percepted_luminance = 1 - ( 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b)/0xF; c->has_custom_background = 1; c->custom_background = rgb; if (percepted_luminance >= 0.5) c->white_text = 1; printf("COLOR %x%x%x\n", rgb.r, rgb.g, rgb.b); } else if (is_shape(buf, &shape) && c) { c->shape = shape; } else { if (last_t && last_c == c && sx > 0 && img->d[y][sx-1] == ' ' && last_t->x + last_t->len + 1 == sx) { extend_text(last_t, 1, buf); } else { t = create_text(y, sx, buf); TAILQ_INSERT_TAIL(c ? &c->text : &free_text, t, list); last_c = c; last_t = t; } } } } } free(buf); }
void LevelGen::generate_map() { typedef std::map<std::string, sf::Color*>::iterator it_type; //- map is always named map.png in the level folder sf::Image map; map.loadFromFile(this->path+"map.png"); size = map.getSize(); std::cout << "Loaded map size\n"; sf::Clock timer; for(int i = 0; i < size.x*size.y; ++i) { int x = (int)i%size.x, y = (int)floor(i/size.x); sf::Color color = map.getPixel(x, y); //- Set tiles based on colors in the map if(is_color(color, 255, 255, 255)) tiles.push_back(new Tile(x, y, false, txmgr.get_ref("floor.png"))); else if(is_color(color, 0, 0, 0)) tiles.push_back(new Tile(x, y, true, txmgr.get_ref("wall.png"))); else{ if(custom_tiles.size() < 1){continue;} for(it_type iterator = custom_tiles.begin(); iterator != custom_tiles.end(); iterator++) { if(is_color(color, (int)iterator->second->r, (int)iterator->second->g, (int)iterator->second->b)) tiles.push_back(new Tile(x, y, txmgr.get_ref(iterator->first))); } } } std::cout << "Level constructed in [" << timer.restart().asMilliseconds() << "] with a total of [" << tiles.size() << "] tiles\n"; }
void print_string_escaped (const char *str) { int i; for (i=0; str[i]; i++) { if (str[i]=='\r') printf ("\\r"); else if (str[i] == '\n') printf ("\\n\n"); else if (!is_color (str[i])) printf ("%c", str[i]); } printf ("\nlen = %d\n", i); }
// converts a character into which entry in font.bmp to use, negative on error or no output int find_font_char (unsigned char cur_char) { if (is_color (cur_char)) { float r,g,b; //must be a color int color = from_color_char (cur_char); r = (float) colors_list[color].r1 / 255.0f; g = (float) colors_list[color].g1 / 255.0f; b = (float) colors_list[color].b1 / 255.0f; //This fixes missing letters in the font on some clients //No idea why going from 3f to 4f helps, but it does glColor4f(r,g,b,1.0); return(-1); // nothing to do } return(get_font_char(cur_char)); }
static const char * actual_color(const char *param, int len, int arg) { const char *result; char *s = strmalloc(param); if (len > 0) { /* if not null-terminated, set it now */ s[len] = '\0'; } result = color_of(s, arg); if (*result == 0) result = keyword_attr(s); if (result != 0 && *result != 0 && !is_color(result)) { result = Literal_attr; } free(s); return result; }
// Searches for terminating characters based on type, from "input_text", adding them to "name" int get_name_from_text(const char * input_text, int len, int type, int offset, char * name) { int i, do_break; Uint8 ch; for (i = 0; i < MAX_USERNAME_LENGTH - 1 && (i + offset) < len; i++) { ch = input_text[i+offset]; //skip over the prefix do_break = 0; switch (type) { case 0: if (ch == ':' || ch == ' ') do_break = 1; break; case 1: if (ch == ':' || ch == ' ' || is_color (ch)) do_break = 1; break; case 2: if (isspace(ch)) do_break = 1; break; case 3: if (ch == ':' || ch == ' ' || ch == ']') do_break = 1; break; case 4: if (ch == ':' || ch == '-' || ch == ' ') do_break = 1; break; } if (do_break == 1) break; name[i] = ch; } name[i] = '\0'; return i; }
int is_in_buddylist(const char *name) { int i; char onlyname[32]; if(!name || !*name) { return 0; } while(name[0] != '\0' && is_color ((unsigned char)name[0])){ ++name; } // strip GuildTag if existing for(i = 0; name[i]>32; i++){ onlyname[i] = name[i]; } onlyname[i] = '\0'; for(i = 0; i < MAX_BUDDY; i++) { if(buddy_list[i].type < 0xff && strcasecmp(buddy_list[i].name, onlyname) == 0) { return 1; } } return 0; }
clan::Colorf SvgAttributeReader::get_color() { if (!is_color()) parse_error("expected color"); size_t end_pos = pos + 1; while (end_pos < attr.length()) { bool is_hex_char = (attr[end_pos] >= 'a' && attr[end_pos] <= 'f') || (attr[end_pos] >= 'A' && attr[end_pos] <= 'F') || (attr[end_pos] >= '0' && attr[end_pos] <= '9'); if (!is_hex_char) break; end_pos++; } if (end_pos != pos + 4 && end_pos != pos + 7) parse_error("invalid color"); clan::Colorf color; std::string hexstr = attr.substr(pos + 1, end_pos - pos - 1); unsigned int value = strtoul(hexstr.c_str(), 0, 16); if (end_pos == pos + 4) { int red = ((((value >> 8) & 0xf) + 1) << 4) - 1; int green = ((((value >> 4) & 0xf) + 1) << 4) - 1; int blue = (((value & 0xf) + 1) << 4) - 1; color = clan::Colorf(red / 255.0f, green / 255.0f, blue / 255.0f); }
void put_colored_text_in_buffer (Uint8 color, Uint8 channel, const Uint8 *text_to_add, int len) { text_message *msg; int minlen, text_color; Uint32 cnr = 0, ibreak = -1, jbreak = -1; char time_stamp[12]; struct tm *l_time; time_t c_time; check_chat_text_to_overtext (text_to_add, len, channel); // check for auto-length if (len < 0) len = strlen ((char*)text_to_add); // set the time when we got this message last_server_message_time = cur_time; // if the buffer is full, delete some old lines and move the remainder to the front if (++last_message >= DISPLAY_TEXT_BUFFER_SIZE) { const size_t num_move = DISPLAY_TEXT_BUFFER_SIZE - DISPLAY_TEXT_BUFFER_DEL; size_t i; for (i=0; i<DISPLAY_TEXT_BUFFER_DEL; i++) { msg = &(display_text_buffer[i]); if (msg->data) { msg->deleted = 1; update_text_windows(msg); free_text_message_data (msg); } } memmove(display_text_buffer, &display_text_buffer[DISPLAY_TEXT_BUFFER_DEL], sizeof(text_message)*num_move); last_message -= DISPLAY_TEXT_BUFFER_DEL; for (i = num_move; i < DISPLAY_TEXT_BUFFER_SIZE; i++) init_text_message (display_text_buffer + i, 0); } msg = &(display_text_buffer[last_message]); // Try to make a guess at the number of wrapping newlines required, // but allow al least for a null byte and up to 8 extra newlines and // colour codes minlen = len + 18 + (len/60); if (show_timestamp) { minlen += 12; time (&c_time); l_time = localtime (&c_time); strftime (time_stamp, sizeof(time_stamp), "[%H:%M:%S] ", l_time); } cnr = get_active_channel (channel); if (cnr != 0) // allow some space for the channel number minlen += 20; if (msg->data == NULL) alloc_text_message_data (msg, minlen); else resize_text_message_data (msg, minlen); if (cnr != 0) { for (ibreak = 0; ibreak < len; ibreak++) { if (text_to_add[ibreak] == ']') break; } } if (channel == CHAT_LOCAL) { for (jbreak = 0; jbreak < len; jbreak++) { if (text_to_add[jbreak] == ':' && text_to_add[jbreak+1] == ' ') break; } } if (dark_channeltext==1) text_color = c_grey2; else if (dark_channeltext==2) text_color = c_grey4; if (ibreak >= len) { // not a channel, or something's messed up if(!is_color (text_to_add[0])) { // force the color if (show_timestamp) { safe_snprintf (msg->data, msg->size, "%c%s%.*s", to_color_char (color), time_stamp, len, text_to_add); } else { safe_snprintf (msg->data, msg->size, "%c%.*s", to_color_char (color), len, text_to_add); } } else { // color set by server if (show_timestamp) { if(dark_channeltext && channel==CHAT_LOCAL && from_color_char(text_to_add[0])==c_grey1 && jbreak < (len-3)) { safe_snprintf (msg->data, msg->size, "%c%s%.*s%.*s", to_color_char (text_color), time_stamp, jbreak+1, &text_to_add[1], len-jbreak-3, &text_to_add[jbreak+3]); } else { safe_snprintf (msg->data, msg->size, "%c%s%.*s", text_to_add[0], time_stamp, len-1, &text_to_add[1]); } } else { if(dark_channeltext && channel==CHAT_LOCAL && from_color_char(text_to_add[0])==c_grey1 && jbreak < (len-3)) { safe_snprintf (msg->data, msg->size, "%c%.*s%.*s", to_color_char (text_color), jbreak+1, &text_to_add[1], len-jbreak-3, &text_to_add[jbreak+3]); } else { safe_snprintf (msg->data, msg->size, "%.*s", len, text_to_add); } } } } else { char nr_str[16]; int has_additional_color = is_color(text_to_add[ibreak+3]); if (cnr >= 1000000000) safe_snprintf (nr_str, sizeof (nr_str), "guild"); else safe_snprintf (nr_str, sizeof (nr_str), "%u", cnr); if(!is_color (text_to_add[0])) { // force the color if (show_timestamp) { if (dark_channeltext) { safe_snprintf (msg->data, msg->size, "%c%s%.*s @ %s%.*s%c%.*s", to_color_char (color), time_stamp, ibreak, text_to_add, nr_str, 3, &text_to_add[ibreak], to_color_char (text_color), len-ibreak-3-has_additional_color, &text_to_add[ibreak+3+has_additional_color]); } else { safe_snprintf (msg->data, msg->size, "%c%s%.*s @ %s%.*s", to_color_char (color), time_stamp, ibreak, text_to_add, nr_str, len-ibreak, &text_to_add[ibreak]); } } else { if (dark_channeltext) { safe_snprintf (msg->data, msg->size, "%c%.*s @ %s%.*s%c%.*s", to_color_char (color), ibreak, text_to_add, nr_str, 3, &text_to_add[ibreak], to_color_char (text_color), len-ibreak-3-has_additional_color, &text_to_add[ibreak+3+has_additional_color]); } else { safe_snprintf (msg->data, msg->size, "%c%.*s @ %s%.*s", to_color_char (color), ibreak, text_to_add, nr_str, len-ibreak, &text_to_add[ibreak]); } } } else { // color set by server if (show_timestamp) { if (dark_channeltext) { safe_snprintf (msg->data, msg->size, "%c%s%.*s @ %s%.*s%c%.*s", text_to_add[0], time_stamp, ibreak-1, &text_to_add[1], nr_str, 3, &text_to_add[ibreak], to_color_char (text_color), len-ibreak-3-has_additional_color, &text_to_add[ibreak+3+has_additional_color]); } else { safe_snprintf (msg->data, msg->size, "%c%s%.*s @ %s%.*s", text_to_add[0], time_stamp, ibreak-1, &text_to_add[1], nr_str, len-ibreak, &text_to_add[ibreak]); } } else { if (dark_channeltext) { safe_snprintf (msg->data, msg->size, "%.*s @ %s%.*s%c%.*s", ibreak, text_to_add, nr_str, 3, &text_to_add[ibreak], to_color_char (text_color), len-ibreak-3-has_additional_color, &text_to_add[ibreak+3+has_additional_color]); } else { safe_snprintf (msg->data, msg->size, "%.*s @ %s%.*s", ibreak, text_to_add, nr_str, len-ibreak, &text_to_add[ibreak]); } } } } msg->len = strlen (msg->data); msg->chan_idx = channel; msg->channel = cnr; // set invalid wrap data to force rewrapping msg->wrap_lines = 0; msg->wrap_zoom = 0.0f; msg->wrap_width = 0; msg->deleted = 0; recolour_message(msg); update_text_windows(msg); // log the message write_to_log (channel, (unsigned char*)msg->data, msg->len); return; }
int filter_or_ignore_text (char *text_to_add, int len, int size, Uint8 channel) { int l, idx; if (len <= 0) return 0; // no point //check for auto receiving #help for (idx = 0; idx < len; idx++) { if (!is_color (text_to_add[idx])) break; } l = len - idx; if (l >= strlen(help_request_str) && text_to_add[idx] == '#' && (strncasecmp (&text_to_add[idx], help_request_str, strlen(help_request_str)) == 0 || strncasecmp (&text_to_add[idx], "#mod chat", 9) == 0)) { auto_open_encyclopedia = 0; } /* DANGER, WILL ROBINSON! The below code should not exist in it's present form. I'd change it, but I'd need access to the server. Simply checking text output (which is used for all sorts of things) for the phrase "Game Date" is very dangerous. Example: what if, in the future, we allow spaces in character names? Someone chooses the name "Game Date" and walks around saying "hi". Everyone's clients in the area interpret this as being a Game Date command. I've made the below code not *as* dangerous. Had a user been able to fake out the below code, previously, it would have caused a buffer overflow in their client if they didn't write in only numbers after it. Now, they won't crash; it'll just be misparsed. General practice recommendation: don't mix server commands with user input. - Karen */ /* ed (ttlanhil): made it check if it's a server colour. still not perfect (this should have been done server-side instead of parsing the date), but safer */ if (from_color_char (text_to_add[0]) == c_green1 && my_strncompare(text_to_add+1,"Game Date", 9)) { //we assume that the server will still send little-endian dd/mm/yyyy... we could make it safer by parsing the format too, but it's simpler to assume const char * const month_names[] = { "Aluwia", "Seedar", "Akbar", "Zartia", "Elandra", "Viasia", "Fruitfall", "Mortia", "Carnelar", "Nimlos", "Chimar", "Vespia" }; const char * const day_names[] = { "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th", "11th", "12th", "13th", "14th", "15th", "16th", "17th", "18th", "19th", "20th", "21st", "22nd", "23rd", "24th", "25th", "26th", "27th", "28th", "29th", "30th" }; char new_str[100]; const char *ptr=text_to_add; short unsigned int day=1, month=1, year=0; int offset = 0; while(!isdigit(ptr[offset])) { offset++; if (offset >= sizeof(new_str)) { LOG_ERROR("error (1) parsing date string: %s",text_to_add); //something evil this way comes... return 0; } } ptr += offset; if (sscanf (ptr,"%hu%*[-/]%hu%*[-/]%hu",&day,&month,&year) < 3 || day <= 0 || month <= 0 || day > 30 || month > 12 || year > 9999) { LOG_ERROR("error (2) parsing date string: %s",text_to_add); //something evil this way comes... } else { // only display initial or "#date" user requested date if (!set_date(ptr)) { safe_snprintf(new_str, sizeof(new_str), date_format, day_names[day-1], month_names[month-1], year); LOG_TO_CONSOLE(c_green1, new_str); } //Calculate fraction Big Lunar month (2 conjunction months) less game clock time //Represented in Degrees. skybox_time_d = (SDL_GetTicks()%( 1296000 * 1000 )); skybox_time_d *= 360.0/( 1296000.0 * 1000.0); skybox_time_d = -skybox_time_d; skybox_time_d += 360.0 * (((month%2)*30 + day-1)*360 + game_minute)/21600.0; skybox_update_positions(); return 0; } } if (from_color_char (text_to_add[0]) == c_green1 && my_strncompare(text_to_add+1,"Game Time", 9)) { real_game_second = atoi(&text_to_add[18]); next_second_time = cur_time + 1000; new_second(); } // Check for local messages to be translated into actor movements (contains [somthing]) if (channel == CHAT_LOCAL) { if(parse_text_for_emote_commands(text_to_add, len)) return 0; } if (channel == CHAT_SERVER) { if (my_strncompare(text_to_add+1, "You started to harvest ", 23)) { strncpy(harvest_name, text_to_add+1+23, len-1-23-1); harvest_name[len-1-23-1] = '\0'; harvesting = 1; } else if ((my_strncompare(text_to_add+1, "You stopped harvesting.", 23)) || (my_strncompare(text_to_add+1, "You can't harvest while fighting (duh)!", 39)) || (my_strncompare(text_to_add+1, "You can't do that while trading!", 32)) || (my_strncompare(text_to_add+1, "You are too far away! Get closer!", 33)) || (my_strncompare(text_to_add+1, "You can't harvest here", 22)) || (my_strncompare(text_to_add+1, "You lack the knowledge of ", 26)) || ((my_strncompare(text_to_add+1, "You need to wear ", 17) && strstr(text_to_add, "order to harvest") != NULL)) || ((my_strncompare(text_to_add+1, "You need to have a ", 19) && strstr(text_to_add, "order to harvest") != NULL))) { harvesting = 0; } else if (is_death_message(text_to_add+1)) { // nothing to be done here cause all is done in the test function } else if (my_strncompare(text_to_add+1, "You found ", 10) && strstr(text_to_add+1, " coins.")) { decrement_harvest_counter(atoi(text_to_add+11)); } else if (my_strncompare(text_to_add+1, "Send Item UIDs ", 15)) { if (text_to_add[1+15] == '0') item_uid_enabled = 0; else if (text_to_add[1+15] == '1') item_uid_enabled = 1; printf("item_uid_enabled=%d\n", item_uid_enabled); } else if ((copy_next_LOCATE_ME > 0) && my_strncompare(text_to_add+1, "You are in ", 11)) { char buffer[4096]; switch (copy_next_LOCATE_ME) { case 1: copy_to_clipboard(text_to_add+1); break; case 2: snprintf(buffer, sizeof(buffer), "@My Position: %s", text_to_add + 12); send_input_text_line(buffer, strlen(buffer)); break; } copy_next_LOCATE_ME = 0; return 0; } else if (my_strncompare(text_to_add+1, "You see: ", 9)) { achievements_player_name(text_to_add+10, len-10); } else if (my_strncompare(text_to_add+1, "You just got food poisoned!", 27)) { increment_poison_incidence(); } else if (strstr(text_to_add+1, "aborted the trade.")) { trade_aborted(text_to_add+1); } else if (strstr(text_to_add+1, "Trade session failed")) { trade_aborted(text_to_add+1); } else if (strstr(text_to_add+1, "You have been saved!")) { last_save_time = time(NULL); } } else if (channel == CHAT_LOCAL) { if (harvesting && my_strncompare(text_to_add+1, username_str, strlen(username_str))) { char *ptr = text_to_add+1+strlen(username_str); if (my_strncompare(ptr, " found a ", 9)) { ptr += 9; if (my_strncompare(ptr, "bag of gold, getting ", 21)) { decrement_harvest_counter(atoi(ptr+21)); } else if (!strstr(ptr, " could not carry ")) { decrement_harvest_counter(1); } } } else if (my_strncompare(text_to_add+1, "(*) ", 4)) { increment_summon_counter(text_to_add+1+4); if (summoning_filter) return 0; } } /* check for misc counter strings */ catch_counters_text(text_to_add+1); /* put #mpm in a popup box, on top of all else */ if ((channel == CHAT_MODPM) && (my_strncompare(text_to_add+1, "[Mod PM from", 12))) { display_server_popup_win(text_to_add); } //Make sure we don't check our own messages. if( !(channel == CHAT_PERSONAL && len >= strlen(pm_from_str) && strncasecmp (text_to_add+1, pm_from_str, strlen(pm_from_str)) != 0) && !(channel == CHAT_MODPM && len >= strlen(mod_pm_from_str) && strncasecmp (text_to_add+1, mod_pm_from_str, strlen(mod_pm_from_str)) != 0) ) { //check if ignored - pre_check_if_ignored() checks for Mod PM's etc to not ignore (or it would be asking for trouble) if (pre_check_if_ignored (text_to_add, len, channel)) { return 0; } //All right, we do not ignore the person if (afk) { if (channel == CHAT_PERSONAL || channel == CHAT_MODPM) { // player sent us a PM add_message_to_pm_log (text_to_add, len, channel); if (afk_snd_warning) { do_afk_sound(); } } else if (channel == CHAT_LOCAL && from_color_char (text_to_add[0]) == c_grey1 && is_talking_about_me (&text_to_add[1], len-1, 0)) { // player mentions our name in local chat if (afk_local) { add_message_to_pm_log (&text_to_add[1], len - 1, channel); if (afk_snd_warning) { do_afk_sound(); } } else { send_afk_message (&text_to_add[1], len - 1, channel); } } else if (channel == CHAT_SERVER) { // check if this was a trade attempt int i; for (i = 1; i < len; i++) { if (text_to_add[i] == ' ' || text_to_add[i] == ':' || is_color (text_to_add[i])) { break; } } if (i < len-15 && strncasecmp (&text_to_add[i], " wants to trade", 15) == 0) { send_afk_message (&text_to_add[1], len - 1, channel); if (afk_snd_warning) { do_afk_sound(); } } } } } else { //We sent this PM or MODPM. Can we expect a reply? int len = 0; char name[MAX_USERNAME_LENGTH]; for(;text_to_add[len+8] != ':' && len < MAX_USERNAME_LENGTH - 1; ++len); safe_strncpy(name, text_to_add+8, len+1); if(check_if_ignored(name)){ char msg[65]; safe_snprintf(msg, sizeof(msg), warn_currently_ignoring, name); LOG_TO_CONSOLE(c_red2, msg); } } // parse for URLs find_all_url (text_to_add, len); // look for buddy-wants-to-add-you messages if(channel == CHAT_SERVER && from_color_char (text_to_add[0]) == c_green1) { for (l = 1; l < len; l++) { if (text_to_add[l] == ' ') break; } if (len - l >= strlen(msg_accept_buddy_str) && strncmp (&text_to_add[l], msg_accept_buddy_str, strlen(msg_accept_buddy_str)) == 0 && l <=32) { char name[32]; int i; int cur_char; /*entropy says: I really fail to understand the logic of that safe_snprintf. And gcc can't understand it either because the name is corrupted. so we implement it the old fashioned way. Grum responds: actually it's the MingW compiler on windows that doesn't understand it, because it doesn't terminate the string when the buffer threatens to overflow. It works fine with gcc on Unix, and using sane_safe_snprintf should also fix it on windows. safe_snprintf (name, l, "%s", &text_to_add[1]); */ for (i = 0; i < sizeof (name); i++) { cur_char = text_to_add[i+1]; name[i] = cur_char; if (cur_char == ' ') { name[i] = '\0'; break; } } add_buddy_confirmation (name); } } // look for astrology messages if((channel == CHAT_SERVER) && is_astrology_message (text_to_add)) { return 0; } // filter any naughty words out return filter_text (text_to_add, len, size); }
int parse_text_for_emote_commands(const char *text, int len) { int i=0, j = 0, wf=0,ef=0, itsme=0; char name[20]; // Yeah, this should be done correctly emote_dict emote_text; actor *act; //printf("parsing local for emotes\n"); //extract name while(text[i]&&i<20){ if (is_color(text[i])) {i++; continue;} name[j]=text[i]; if(text[i]==' ' || text[i]==':') { name[j]=0; if(text[i]==':') i++; break; } i++;j++; } if(j>=20||name[j]) return 0; //out of bound or not terminated //check if we are saying text LOCK_ACTORS_LISTS(); act = get_actor_ptr_from_id(yourself); if (!act){ UNLOCK_ACTORS_LISTS(); LOG_ERROR("Unable to find actor who just said local text?? name: %s", name); return 1; // Eek! We don't have an actor match... o.O } if (!(!strncasecmp(act->actor_name, name, strlen(name)) && (act->actor_name[strlen(name)] == ' ' || act->actor_name[strlen(name)] == '\0'))){ //we are not saying this text, return //UNLOCK_ACTORS_LISTS(); //return 0; itsme=0; } else itsme=1; j=0; do { if (is_color(text[i])) continue; if ((text[i]==' ' || text[i]==0)) { if (j&&j<=MAX_EMOTE_LEN) { wf++; emote_text.command[j]=0; ef+=match_emote(&emote_text,act,itsme); } else wf+= (j) ? 1:0; j=0; } else { if (j<MAX_EMOTE_LEN) emote_text.command[j]=text[i]; j++; } } while(text[i++]); //printf("ef=%i, wf=%i, filter=>%i\n",ef,wf,emote_filter); UNLOCK_ACTORS_LISTS(); return ((ef==wf) ? (emote_filter):(0)); }
void write_to_log (Uint8 channel, const Uint8* const data, int len) { int i, j; Uint8 ch; char str[1024]; struct tm *l_time; time_t c_time; FILE *fout; #ifdef NEW_SOUND // Check if this string matches text we play a sound for check_sound_alerts(data, len, channel); #endif // NEW_SOUND if(log_chat == LOG_NONE || (channel == CHAT_SERVER && log_chat == LOG_CHAT)) // We're not logging at all, or this is a server message and // we're not logging those return; if (chat_log == NULL){ open_chat_log(); if(chat_log == NULL){ return; } } // The file we'll write to fout = (channel == CHAT_SERVER && log_chat >= 3) ? srv_log : chat_log; if(!show_timestamp) { // Start filling the buffer with the time stamp time (&c_time); l_time = localtime (&c_time); j = strftime (str, sizeof(str), "[%H:%M:%S] ", l_time); } else { //we already have a time stamp j=0; } i = 0; while (i < len) { for ( ; i < len && j < sizeof (str) - 1; i++) { ch = data[i]; // remove colorization and soft wrapping characters when // writing to the chat log if (!is_color (ch) && ch != '\r') str[j++] = ch; } if (i >= len) str[j++]='\n'; fwrite (str, j, 1, fout); // start again at the beginning of the buffer j = 0; } // Flush the file, so the content is written even when EL crashes. fflush (fout); }
void put_small_colored_text_in_box (Uint8 color, const Uint8 *text_to_add, int len, int pixels_limit, char *buffer) { int i; Uint8 cur_char; int last_text = 0; int x_chars_limit; // force the color if (!is_color (text_to_add[0])) buffer[last_text++] = to_color_char (color); //see if the text fits on the screen x_chars_limit = pixels_limit / 8; if (len <= x_chars_limit) { for (i = 0; i < len; i++) { cur_char = text_to_add[i]; if (cur_char == '\0') break; buffer[last_text++] = cur_char; } if (last_text > 0 && buffer[last_text-1] != '\n') buffer[last_text++] = '\n'; buffer[last_text] = '\0'; } else //we have to add new lines to our text... { int k; int new_line_pos = 0; char semaphore = 0; Uint8 current_color = to_color_char (color); // go trought all the text for (i = 0; i < len; i++) { if (!semaphore && new_line_pos + x_chars_limit < len) //don't go through the last line { //find the closest space from the end of this line //if we have one really big word, then parse the string from the //end of the line backwards, untill the beginning of the line +2 //the +2 is so we avoid parsing the ": " thing... for (k = new_line_pos + x_chars_limit - 1; k > new_line_pos + 2; k--) { cur_char = text_to_add[k]; if (k > len) continue; if (cur_char == ' ' || cur_char == '\n') { k++; // let the space on the previous line break; } } if (k == new_line_pos + 2) new_line_pos += x_chars_limit; else new_line_pos = k; semaphore = 1; } cur_char = text_to_add[i]; if (cur_char == '\0') break; if (is_color (cur_char)) // we have a color, save it { current_color = cur_char; if (last_text > 0 && is_color (buffer[last_text-1])) last_text--; } else if (cur_char == '\n') { new_line_pos = i; } if (i == new_line_pos) { buffer[last_text++] = '\n'; // don't add color codes after the last newline if (i < len-1) buffer[last_text++] = current_color; semaphore = 0; } //don't add another new line, if the current char is already a new line... if (cur_char != '\n') buffer[last_text++] = cur_char; } // don't add extra newlines if there already is one if (last_text > 0 && buffer[last_text-1] != '\n') buffer[last_text++] = '\n'; buffer[last_text] = '\0'; } }
//returns the new length of the text int filter_text (char *buff, int len, int size) { int i, t, bad_len, rep_len, new_len, idx; if (len > 31 && my_strncompare (buff+1, "Items you have in your storage:", 31)){ //First up, attempt to save the storage list for re-reading later if(size <= sizeof(cached_storage_list)){ memcpy(cached_storage_list, buff, size); have_storage_list = 1; } // See if a search term has been added to the #storage command, and if so, //only list those items with that term if (storage_filter[0] != '\0'){ len = 33 + filter_storage_text (buff+33, len-33, size-33); } } //do we need to do CAPS filtering? if (caps_filter) { int idx, clen = len; // skip any coloring idx = 0; while (is_color (buff[idx]) && clen > 0) { idx++; clen--; } // handle PM's if (buff[idx] == '[' || buff[idx+1] == '[') { while (buff[idx] != '\0' && buff[idx] != ':' && clen > 0) { idx++; clen--; } } // or ignore first word else { while (buff[idx] != '\0' && buff[idx] != ' ' && buff[idx] != ':' && clen > 0) { idx++; clen--; } } while (buff[idx] != '\0' && (buff[idx] == ' ' || buff[idx] == ':' || is_color (buff[idx])) && clen > 0) { idx++; clen--; } // check for hitting the EOS if (buff[idx] == '\0') idx = 0; // if we pass the upper test, entire line goes lower if (len - idx > 4 && my_isupper (&buff[idx], clen)) { // don't call my_tolower, since we're not sure if the string is NULL terminated for (idx = 0; idx < len; idx++) buff[idx] = tolower (buff[idx]); } } //do we need to do any content filtering? if (filtered_so_far == 0) return len; // scan the text for any strings new_len = len; i = 0; while (i < new_len) { /* skip non-alpha characters */ while (i < new_len && !isalpha ((unsigned char)buff[i])) i++; if (i >= new_len) break; /* check if we need to filter this word */ idx = check_if_filtered (&buff[i]); if (idx >= 0) { /* oops, remove this word */ if (filter_list[idx].wildcard_type > 0) { bad_len = 0; for (t = 0; ; t++) { if (!isalpha (buff[i+t])) break; bad_len++; } } else { bad_len = filter_list[idx].len; } rep_len = filter_list[idx].rlen; if (bad_len == rep_len) { memcpy(buff+i, filter_list[idx].replacement, rep_len); } else if (new_len + rep_len - bad_len >= size - 1) { // not enough space for substitution break; } else { memmove(buff+i+rep_len, buff+i+bad_len, new_len-i-bad_len+1); memcpy(buff+i, filter_list[idx].replacement, rep_len); new_len+= rep_len - bad_len; } /* don't filter the replacement text */ i += rep_len; } else { /* skip this word */ while (i < new_len && isalpha (buff[i])) i++; } } return new_len; }
static __inline__ void draw_actor_points(float zoom_multip, float px, float py) { float size_x = float_minimap_size / (tile_map_size_x * 6); float size_y = float_minimap_size / (tile_map_size_y * 6); actor *a; int i; float x, y; glPushMatrix(); glDisable(GL_TEXTURE_2D); //display the actors glEnable( GL_POINT_SMOOTH ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glPointSize(8); rotate_actor_points(zoom_multip,px,py); glBegin(GL_POINTS); for (i = 0; i < max_actors; i++) { if (actors_list[i]) { a = actors_list[i]; if (a->attached_actor != -1 && a->actor_id == -1) continue; x = a->x_tile_pos * size_x; y = float_minimap_size - (a->y_tile_pos * size_y); glColor3f(0.0f,0.0f,0.0f); glVertex2f(x+2*zoom_multip, y+2*zoom_multip); if (a->kind_of_actor == NPC) elglColourN("minimap.npc"); else if(a->actor_id == yourself) elglColourN("minimap.yourself"); else if(a->is_enhanced_model && (a->kind_of_actor == PKABLE_HUMAN || a->kind_of_actor == PKABLE_COMPUTER_CONTROLLED)) elglColourN("minimap.pkable"); else if(a->is_enhanced_model && is_in_buddylist(a->actor_name)) elglColourN("minimap.buddy"); else if (is_color ((unsigned char)a->actor_name[0])) { if(a->is_enhanced_model && is_in_buddylist(a->actor_name)) elglColourN("minimap.buddy"); else { // Use the colour of their name. This gives purple bots, green demigods, etc. int color = from_color_char (a->actor_name[0]); glColor3ub (colors_list[color].r1, colors_list[color].g1, colors_list[color].b1); } } else if(!a->is_enhanced_model) { if (a->dead) elglColourN("minimap.deadcreature"); else // alive elglColourN("minimap.creature"); } else elglColourN("minimap.otherplayer"); // Draw it! glVertex2f(x, y); } } // mines for (i = 0; i < NUM_MINES; i++) { mine *m = &mine_list[i]; if (m->obj_3d_id != -1) { x = m->x * size_x; y = float_minimap_size - (m->y * size_y); if(is_within_radius(x,y,px,py,zoom_multip*(minimap_size/2-15))) { elglColourN("minimap.mine"); glVertex2f(x, y); } } } glEnd();//GL_POINTS glDisable(GL_BLEND); glDisable(GL_POINT_SMOOTH); glPopMatrix(); if (pf_follow_path) { x = pf_dst_tile->x * size_x; y = float_minimap_size - (pf_dst_tile->y * size_y); if (x != px || y != py) { float diff = 6.0f*zoom_multip; if(is_within_radius(x,y,px,py,zoom_multip*(minimap_size/2-15))) { glPushMatrix(); glDisable(GL_TEXTURE_2D); rotate_actor_points(zoom_multip,px,py); glBegin(GL_LINES); glColor3f(1.0f,0.0f,1.0f); //purple glVertex2f(x-diff, y-diff); glVertex2f(x+diff, y+diff); glVertex2f(x-diff, y+diff); glVertex2f(x+diff, y-diff); glEnd();//GL_LINES glPopMatrix(); } } } //draw map markings for(i=0;i<max_mark;i++){ if(!marks[i].server_side) continue; x= marks[i].x*size_x; y= float_minimap_size-(marks[i].y*size_y); if (x != px || y != py) { float diff = 4.0f*zoom_multip; if(is_within_radius(x,y,px,py,zoom_multip*(minimap_size/2-15))) { glPushMatrix(); glDisable(GL_TEXTURE_2D); rotate_actor_points(zoom_multip,px,py); glBegin(GL_LINES); elglColourN("minimap.servermark"); glVertex2f(x-diff, y-diff); glVertex2f(x+diff, y+diff); glVertex2f(x-diff, y+diff); glVertex2f(x+diff, y-diff); glEnd();//GL_LINES glPopMatrix(); } } } glColor4f(1.0f,1.0f,1.0f,1.0f); glEnable(GL_TEXTURE_2D); }
void draw_ortho_ingame_string(float x, float y,float z, const unsigned char * our_string, int max_lines, float font_x_scale, float font_y_scale) { float u_start,u_end,v_start,v_end; int col,row; float displayed_font_x_size; float displayed_font_y_size; float displayed_font_x_width; #ifndef SKY_FPV_OPTIONAL int font_x_size=FONT_X_SPACING; int font_y_size=FONT_Y_SPACING; #endif // not SKY_FPV_OPTIONAL int font_bit_width, ignored_bits; unsigned char cur_char; int chr; int i; float cur_x,cur_y; int current_lines=0; #ifndef SKY_FPV_OPTIONAL /* if(big) { displayed_font_x_size=0.17*zoom_level*name_zoom/3.0; displayed_font_y_size=0.25*zoom_level*name_zoom/3.0; } else { displayed_font_x_size=SMALL_INGAME_FONT_X_LEN*zoom_level*name_zoom/3.0; displayed_font_y_size=SMALL_INGAME_FONT_Y_LEN*zoom_level*name_zoom/3.0; } */ #endif // not SKY_FPV_OPTIONAL displayed_font_x_size=font_x_scale*name_zoom*12.0; displayed_font_y_size=font_y_scale*name_zoom*12.0; glEnable(GL_ALPHA_TEST);//enable alpha filtering, so we have some alpha key glAlphaFunc(GL_GREATER,0.1f); #ifdef NEW_TEXTURES bind_texture(font_text); #else /* NEW_TEXTURES */ get_and_set_texture_id(font_text); #endif /* NEW_TEXTURES */ i=0; cur_x=x; cur_y=y; glBegin(GL_QUADS); #ifndef SKY_FPV_OPTIONAL while(1) { cur_char=our_string[i]; if(!cur_char) { break; } else if(cur_char=='\n') { cur_y+=displayed_font_y_size; cur_x=x; i++; current_lines++; if(current_lines>=max_lines)break; continue; } else if (is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! } chr=find_font_char(cur_char); if(chr >= 0) { col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*font_x_size+ignored_bits)/256.0f; u_end=(float)(row*font_x_size+font_x_size-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*font_y_size)/256.0f; v_end=(float)(col*font_y_size+font_y_size-1)/256.0f; #else v_start=(float)1.0f-(1+col*font_y_size)/256.0f; v_end=(float)1.0f-(col*font_y_size+font_y_size-1)/256.0f; #endif //NEW_TEXTURES //v_end=(float)1.0f-(col*font_y_size+font_y_size-2)/256.0f; glTexCoord2f(u_start,v_start); glVertex3f(cur_x,cur_y+displayed_font_y_size,z); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,cur_y,z); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,cur_y,z); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,cur_y+displayed_font_y_size,z); //cur_x+=displayed_font_x_size; cur_x+=displayed_font_x_width; } else if (is_color (cur_char)) { glBegin(GL_QUADS); //Ooops - NV bug fix!! } #else // SKY_FPV_OPTIONAL while(1){ cur_char=our_string[i]; if(!cur_char){ break; } else if(cur_char=='\n'){ cur_y+=displayed_font_y_size; cur_x=x; #endif // SKY_FPV_OPTIONAL i++; #ifdef SKY_FPV_OPTIONAL current_lines++; if(current_lines>=max_lines)break; continue; } else if (is_color (cur_char)){ glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); } chr=find_font_char(cur_char); if(chr >= 0){ col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*FONT_X_SPACING+ignored_bits)/256.0f; u_end=(float)(row*FONT_X_SPACING+FONT_X_SPACING-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #else v_start=(float)1.0f-(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)1.0f-(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #endif //NEW_TEXTURES glTexCoord2f(u_start,v_start); glVertex3f(cur_x,cur_y+displayed_font_y_size,z); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,cur_y,z); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,cur_y,z); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,cur_y+displayed_font_y_size,z); cur_x+=displayed_font_x_width; } else if(is_color (cur_char)){ glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); #endif // SKY_FPV_OPTIONAL } #ifdef SKY_FPV_OPTIONAL i++; } #endif // SKY_FPV_OPTIONAL glEnd(); glDisable(GL_ALPHA_TEST); } void draw_ingame_string(float x, float y,const unsigned char * our_string, int max_lines, float font_x_scale, float font_y_scale) { float u_start,u_end,v_start,v_end; int col,row; float displayed_font_x_size; float displayed_font_y_size; float displayed_font_x_width; #ifndef SKY_FPV_OPTIONAL //int font_x_size=FONT_X_SPACING; //int font_y_size=FONT_Y_SPACING; #endif // not SKY_FPV_OPTIONAL int font_bit_width, ignored_bits; unsigned char cur_char; int chr; int i; float cur_x,cur_y; int current_lines=0; #ifdef SKY_FPV_OPTIONAL double model[16], proj[16],hx,hy,hz; int view[4]; displayed_font_x_size=font_x_scale*name_zoom*12.0*font_scale; displayed_font_y_size=font_y_scale*name_zoom*12.0*font_scale; glGetDoublev(GL_MODELVIEW_MATRIX, model); glGetDoublev(GL_PROJECTION_MATRIX, proj); glGetIntegerv(GL_VIEWPORT, view); gluProject((double)x,0.0f,(double)y,model, proj, view, &hx,&hy,&hz); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(view[0],view[2]+view[0],view[1],view[3]+view[1],0.0f,-1.0f); #endif // SKY_FPV_OPTIONAL #ifndef SKY_FPV_OPTIONAL displayed_font_x_size=font_x_scale*zoom_level*name_zoom/3.0; displayed_font_y_size=font_y_scale*zoom_level*name_zoom/3.0; #endif // not SKY_FPV_OPTIONAL glEnable(GL_ALPHA_TEST);//enable alpha filtering, so we have some alpha key glAlphaFunc(GL_GREATER,0.1f); #ifdef NEW_TEXTURES bind_texture(font_text); #else /* NEW_TEXTURES */ get_and_set_texture_id(font_text); #endif /* NEW_TEXTURES */ i=0; #ifndef SKY_FPV_OPTIONAL cur_x=x; cur_y=y; #else // SKY_FPV_OPTIONAL cur_x=hx; cur_y=hy; #endif // SKY_FPV_OPTIONAL glBegin(GL_QUADS); #ifndef SKY_FPV_OPTIONAL while(1) { cur_char=our_string[i]; if(!cur_char) { break; } else if(cur_char=='\n') { cur_y+=displayed_font_y_size; cur_x=x; i++; current_lines++; if(current_lines>=max_lines)break; continue; } else if(is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! } chr=find_font_char(cur_char); if(chr >= 0) { col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*FONT_X_SPACING+ignored_bits)/256.0f; u_end=(float)(row*FONT_X_SPACING+FONT_X_SPACING-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #else v_start=(float)1.0f-(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)1.0f-(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #endif //NEW_TEXTURES glTexCoord2f(u_start,v_start); glVertex3f(cur_x,0,cur_y+displayed_font_y_size); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,0,cur_y); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,0,cur_y); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,0,cur_y+displayed_font_y_size); cur_x+=displayed_font_x_width; } else if (is_color (cur_char)) { glBegin(GL_QUADS); //Ooops - NV bug fix!! } #else // SKY_FPV_OPTIONAL while(1){ cur_char=our_string[i]; if(!cur_char){ break; }else if(cur_char=='\n'){ cur_y+=displayed_font_y_size; cur_x=hx; #endif // SKY_FPV_OPTIONAL i++; #ifdef SKY_FPV_OPTIONAL current_lines++; if(current_lines>=max_lines)break; continue; } else if (is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); } chr=find_font_char(cur_char); if(chr >= 0){ col=chr/FONT_CHARS_PER_LINE; row=chr%FONT_CHARS_PER_LINE; font_bit_width=get_font_width(chr); displayed_font_x_width=((float)font_bit_width)*displayed_font_x_size/12.0; ignored_bits=(12-font_bit_width)/2; // how many bits on each side of the char are ignored? if(ignored_bits < 0)ignored_bits=0; //now get the texture coordinates u_start=(float)(row*FONT_X_SPACING+ignored_bits)/256.0f; u_end=(float)(row*FONT_X_SPACING+FONT_X_SPACING-7-ignored_bits)/256.0f; #ifdef NEW_TEXTURES v_start=(float)(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #else v_start=(float)1.0f-(1+col*FONT_Y_SPACING)/256.0f; v_end=(float)1.0f-(col*FONT_Y_SPACING+FONT_Y_SPACING-1)/256.0f; #endif // NEW_TEXTURES glTexCoord2f(u_start,v_start); glVertex3f(cur_x,cur_y+displayed_font_y_size,0); glTexCoord2f(u_start,v_end); glVertex3f(cur_x,cur_y,0); glTexCoord2f(u_end,v_end); glVertex3f(cur_x+displayed_font_x_width,cur_y,0); glTexCoord2f(u_end,v_start); glVertex3f(cur_x+displayed_font_x_width,cur_y+displayed_font_y_size,0); cur_x+=displayed_font_x_width; } else if (is_color (cur_char)) { glEnd(); //Ooops - NV bug fix!! glBegin(GL_QUADS); #endif // SKY_FPV_OPTIONAL } #ifdef SKY_FPV_OPTIONAL i++; } #endif // SKY_FPV_OPTIONAL glEnd(); glDisable(GL_ALPHA_TEST); #ifdef SKY_FPV_OPTIONAL glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); #endif // SKY_FPV_OPTIONAL } #endif //!MAP_EDITOR_2 #endif //ELC // font handling int get_font_width(int cur_char) { // ignore unknown characters if (cur_char < 0) { return 0; } // return width of character + spacing between chars (supports variable width fonts) return (fonts[cur_font_num]->widths[cur_char] + fonts[cur_font_num]->spacing); } int get_char_width(unsigned char cur_char) { return get_font_width(get_font_char(cur_char)); } int get_string_width(const unsigned char *str) { return get_nstring_width(str, strlen((char*)str)); } int get_nstring_width(const unsigned char *str, int len) { int i, wdt=0; for(i=0; i<len; i++) { wdt+= get_char_width(str[i]); } // adjust to ignore the final spacing wdt-= fonts[cur_font_num]->spacing; return wdt; }
// Returns 1 if ignored, 0 if not ignored int pre_check_if_ignored (const char *input_text, int len, Uint8 channel) { int offset; char name[MAX_USERNAME_LENGTH] = {0}; if (channel == CHAT_MODPM) { return 0; // Don't ever ignore MOD PM's } switch(channel) { case CHAT_PERSONAL: offset = strlen(pm_from_str) + 2; get_name_from_text(input_text, len, 0, offset, name); // Type 0 = ":" or " " break; case CHAT_LOCAL: offset = 0; while (is_color (input_text[offset])) { offset++; } offset += get_name_from_text(input_text, len, 1, offset, name); // Type 1 = ":", " " or is_color if (!name_is_valid(name)) { //This can be a lot. Let's separate them based on the color for now. switch (from_color_char (*input_text)) { case c_grey1: //Check for summoning messages //(*) NAME summoned a %s if (strcmp(name, "(*)") == 0) { while (offset < len && isspace(input_text[offset])) { offset++; } get_name_from_text(input_text, len, 2, offset, name); // Type 2 = isspace } break; } } break; case CHAT_GM: for (offset = 0; is_color (input_text[offset]); offset++); // Ignore colours if(strncasecmp(input_text+offset, gm_from_str, strlen(gm_from_str)) == 0) { offset = strlen(gm_from_str)+2; get_name_from_text(input_text, len, 0, offset, name); // Type 0 = ":" or " " } else if(strncasecmp(input_text+offset, ig_from_str, strlen(ig_from_str)) == 0) { offset = strlen(ig_from_str)+1; get_name_from_text(input_text, len, 4, offset, name); // Type 4 = ":", "-" or " " } break; case CHAT_MOD: for (offset = 0; is_color (input_text[offset]); offset++); // Ignore colours if(strncasecmp(input_text+offset, mc_from_str, strlen(mc_from_str)) == 0) { offset = strlen(mc_from_str)+2; get_name_from_text(input_text, len, 0, offset, name); // Type 0 = ":" or " " } break; case CHAT_SERVER: for (offset = 0; is_color (input_text[offset]); offset++); // Ignore colours if(strncasecmp(input_text+offset, "delayed: ", 9) == 0) { offset = 10; if(strncasecmp(input_text+offset, pm_from_str, strlen(pm_from_str)) == 0) { offset += strlen(pm_from_str)+1; get_name_from_text(input_text, len, 0, offset, name); // Type 0 = ":" or " " } } break; } #if defined(OTHER_LIFE) && defined(OTHER_LIFE_EXTENDED_CHAT) if(loadsofchannels == 3) { switch(channel) { case CHAT_CHANNEL1: case CHAT_CHANNEL2: case CHAT_CHANNEL3: for (offset = 0; is_color (input_text[offset]); offset++); // Ignore colours if (input_text[offset] == '[') { offset++; } get_name_from_text(input_text, len, 3, offset, name); // Type 3 = ":", " " or "]" } } else { switch(channel) { case CHAT_CHANNEL1: case CHAT_CHANNEL2: case CHAT_CHANNEL3: case CHAT_CHANNEL4: case CHAT_CHANNEL5: case CHAT_CHANNEL6: case CHAT_CHANNEL7: case CHAT_CHANNEL8: case CHAT_CHANNEL9: case CHAT_CHANNEL10: case CHAT_CHANNEL11: case CHAT_CHANNEL12: case CHAT_CHANNEL13: case CHAT_CHANNEL14: case CHAT_CHANNEL15: case CHAT_CHANNEL16: case CHAT_CHANNEL17: case CHAT_CHANNEL18: case CHAT_CHANNEL19: case CHAT_CHANNEL20: case CHAT_CHANNEL21: case CHAT_CHANNEL22: case CHAT_CHANNEL23: case CHAT_CHANNEL24: case CHAT_CHANNEL25: case CHAT_CHANNEL26: case CHAT_CHANNEL27: case CHAT_CHANNEL28: case CHAT_CHANNEL29: case CHAT_CHANNEL30: case CHAT_CHANNEL31: case CHAT_CHANNEL32: for (offset = 0; is_color (input_text[offset]); offset++); // Ignore colours if (input_text[offset] == '[') { offset++; } get_name_from_text(input_text, len, 3, offset, name); // Type 3 = ":", " " or "]" } } #else switch (channel) { case CHAT_CHANNEL1: case CHAT_CHANNEL2: case CHAT_CHANNEL3: for (offset = 0; is_color (input_text[offset]); offset++); // Ignore colours if (input_text[offset] == '[') { offset++; } get_name_from_text(input_text, len, 3, offset, name); // Type 3 = ":", " " or "]" } #endif // if defined(OTHER_LIFE) && defined(OTHER_LIFE_EXTENDED_CHAT) if (*name && name_is_valid(name)) { add_name_to_tablist(name); } else { for (offset = 0; is_color (input_text[offset]); offset++); // Ignore colours get_name_from_text(input_text, len, 1, offset, name); // Type 1 = ":", " " or is_color } if (!check_if_ignored (name)) { if (channel == CHAT_PERSONAL || channel == CHAT_MODPM) { //memorise the name my_strcp (last_pm_from, name); } return 0; } else { return 1; } }
void draw_messages (int x, int y, text_message *msgs, int msgs_size, Uint8 filter, int msg_start, int offset_start, int cursor, int width, int height, float text_zoom, select_info* select) { float displayed_font_x_size = DEFAULT_FONT_X_LEN * text_zoom; float displayed_font_y_size = DEFAULT_FONT_Y_LEN * text_zoom; float selection_red = 255 / 255.0f; float selection_green = 162 / 255.0f; float selection_blue = 0; unsigned char cur_char; int i; int imsg, ichar; int cur_x, cur_y; int cursor_x = x-1, cursor_y = y-1; unsigned char ch; int cur_line = 0; int cur_col = 0; unsigned char last_color_char = 0; int in_select = 0; imsg = msg_start; ichar = offset_start; if (msgs[imsg].data == NULL || msgs[imsg].deleted) return; if (width < displayed_font_x_size || height < displayed_font_y_size) // no point in trying return; #ifndef MAP_EDITOR2 if (filter != FILTER_ALL) { // skip all messages of the wrong channel while (1) { if (skip_message(&msgs[imsg], filter)) { ichar = 0; if (++imsg >= msgs_size) imsg = 0; if (msgs[imsg].data == NULL || imsg == msg_start || msgs[imsg].deleted) // nothing to draw return; } else { break; } } if (msgs[imsg].data == NULL || msgs[imsg].deleted) return; } #endif //! MAP_EDITOR2 ch = msgs[imsg].data[ichar]; if (!is_color (ch)) { // search backwards for the last color for (i = ichar-1; i >= 0; i--) { ch = msgs[imsg].data[i]; if (is_color (ch)) { find_font_char (ch); last_color_char = ch; break; } } if (i < 0) { // no color character found, try the message color if (msgs[imsg].r >= 0) glColor3f (msgs[imsg].r, msgs[imsg].g, msgs[imsg].b); } } glEnable (GL_ALPHA_TEST); // enable alpha filtering, so we have some alpha key glAlphaFunc (GL_GREATER, 0.1f); #ifdef NEW_TEXTURES bind_texture(font_text); #else /* NEW_TEXTURES */ get_and_set_texture_id(font_text); #endif /* NEW_TEXTURES */ i = 0; cur_x = x; cur_y = y; glBegin (GL_QUADS); while (1) { if (i == cursor) { cursor_x = cur_x; cursor_y = cur_y; if (cursor_x - x > width - displayed_font_x_size) { cursor_x = x; cursor_y = cur_y + displayed_font_y_size; } } cur_char = msgs[imsg].data[ichar]; // watch for special characters if (cur_char == '\0') { // end of message if (++imsg >= msgs_size) { imsg = 0; } #ifndef MAP_EDITOR2 if (filter != FILTER_ALL) { // skip all messages of the wrong channel while (skip_message (&msgs[imsg], filter)) { if (++imsg >= msgs_size) imsg = 0; if (msgs[imsg].data == NULL || imsg == msg_start) break; } } #endif if (msgs[imsg].data == NULL || imsg == msg_start || msgs[imsg].deleted) break; rewrap_message (&msgs[imsg], text_zoom, width, NULL); ichar = 0; last_color_char = 0; } if (select != NULL && select->lines && select->lines[cur_line].msg == -1) { select->lines[cur_line].msg = imsg; select->lines[cur_line].chr = ichar; } if (cur_char == '\n' || cur_char == '\r' || cur_char == '\0') { // newline cur_y += displayed_font_y_size; if (cur_y - y > height - displayed_font_y_size) break; cur_x = x; if (cur_char != '\0') ichar++; i++; cur_line++; cur_col = 0; continue; } if (pos_selected(imsg, ichar, select)) { if (!in_select) { glColor3f (selection_red, selection_green, selection_blue); in_select = 1; } } else { if (in_select) { if (last_color_char) find_font_char (last_color_char); else if (msgs[imsg].r < 0) find_font_char (to_color_char (c_grey1)); else glColor3f (msgs[imsg].r, msgs[imsg].g, msgs[imsg].b); in_select = 0; } } if (is_color (cur_char)) { last_color_char = cur_char; if (in_select) { // don't draw color characters in a selection i++; ichar++; continue; } } cur_x += draw_char_scaled (cur_char, cur_x, cur_y, displayed_font_x_size, displayed_font_y_size); cur_col++; ichar++; i++; if (cur_x - x > width - displayed_font_x_size) { // ignore rest of this line, but keep track of // color characters while (1) { ch = msgs[imsg].data[ichar]; if (ch == '\0' || ch == '\n' || ch == '\r') break; if (is_color (ch)) last_color_char = ch; ichar++; i++; } } } if (cursor_x >= x && cursor_y >= y && cursor_y - y <= height - displayed_font_y_size) { draw_char_scaled ('_', cursor_x, cursor_y, displayed_font_x_size, displayed_font_y_size); } glEnd(); glDisable(GL_ALPHA_TEST); #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE }
/*There are bugs in this code that case it to not fill in an entire shape. * Somehow it ends at the center. */ int flood_fill_fast(image img, int x, int y, stack_t * borders){ /* * cur, mark, and mark2 each hold either pixel coordinates or a null value NOTE: when mark is set to null, do not erase its previous coordinate value. Keep those coordinates available to be recalled if necessary. cur-dir, mark-dir, and mark2-dir each hold a direction (left, right, up, or down) backtrack and findloop each hold boolean values count is an integer * */ point_t cur, mark, mark2; int cur_dir, mark_dir, mark2_dir; bool backtrack, findloop; int fillcount = 0; bool skip_body = false; bool done = false; /* The algorithm: (NOTE: All directions (front, back, left, right) are relative to cur-dir) set cur to starting pixel set cur-dir to default direction clear mark and mark2 (set values to null) set backtrack and findloop to false */ cur.x = x; cur.y = y; cur_dir = UP; mark.x = mark.y = mark2.x = mark2.y = -1; backtrack = findloop = false; if(!isvalid(cur, img) || !is_color(img.data[toidx(cur, img)], CD_DETECT_COLOR)){ return fillcount; } /* while front-pixel is empty move forward end while */ while( isvalid(move_forward(cur, cur_dir), img) && is_color(img.data[toidx(move_forward(cur, cur_dir), img)], CD_DETECT_COLOR) ){ cur = move_forward(cur, cur_dir); } while(!done){ int count = 0; int fcount = 0; point_t up = move_forward(cur, UP); point_t down = move_forward(cur, DOWN); point_t left = move_forward(cur, LEFT); point_t right = move_forward(cur, RIGHT); //count non-empty spaces if(!isvalid(up, img) || !is_color(img.data[toidx(up, img)], CD_DETECT_COLOR)) count++; if(!isvalid(down, img) || !is_color(img.data[toidx(down, img)], CD_DETECT_COLOR)) count++; if(!isvalid(left, img) || !is_color(img.data[toidx(left, img)], CD_DETECT_COLOR)) count++; if(!isvalid(right, img) || !is_color(img.data[toidx(right, img)], CD_DETECT_COLOR)) count++; //count filled spaces if(isvalid(up, img) && (is_color(img.data[toidx(up, img)], CD_FILL_COLOR))) fcount++; if(isvalid(down, img) && (is_color(img.data[toidx(down, img)], CD_FILL_COLOR))) fcount++; if(isvalid(left, img) && (is_color(img.data[toidx(left, img)], CD_FILL_COLOR))) fcount++; if(isvalid(right, img) && (is_color(img.data[toidx(right, img)], CD_FILL_COLOR))) fcount++; if(count - fcount > 0) push_stack(cur, borders); /* * set count to number of non-diagonally adjacent pixels filled (front/back/left/right ONLY) if count is not 4 do turn right while front-pixel is empty do turn left while front-pixel is filled end if * */ if(count < 4){ point_t front; do{ cur_dir = turn_right(cur_dir); front = move_forward(cur, cur_dir); }while(isvalid(front, img) && is_color(img.data[toidx(front, img)],CD_DETECT_COLOR)); do{ cur_dir = turn_left(cur_dir); front = move_forward(cur, cur_dir); }while(isvalid(front, img) && !is_color(img.data[toidx(front, img)],CD_DETECT_COLOR)); } point_t back = move_forward(cur, turn_left(turn_left(cur_dir))); point_t front_left = move_forward(move_forward(cur, cur_dir), turn_left(cur_dir)); point_t back_left = move_forward(move_forward(cur, turn_left(turn_left(cur_dir))), turn_left(cur_dir)); skip_body = false; switch(count){ case 4: /* fill cur done */ img.data[toidx(cur, img)] = CD_FILL_COLOR; fillcount++; //draw borders done = true; skip_body = true; //return fillcount; break; case 3: /* clear mark turn left fill cur jump to PAINT * */ mark.x = mark.y = -1; img.data[toidx(cur, img)] = CD_FILL_COLOR; fillcount++; //jump to paint skip_body = true; break; case 2: /* if back-pixel is filled if front-left-pixel is not filled clear mark turn around fill cur jump to PAINT end if */ if(isvalid(back, img) && is_color(img.data[toidx(back, img)], CD_FILL_COLOR)){ if(isvalid(front_left, img) &&!is_color(img.data[toidx(front_left, img)], CD_FILL_COLOR)){ mark.x = mark.y = -1; cur_dir = turn_left(turn_left(cur_dir)); img.data[toidx(cur, img)] = CD_FILL_COLOR; fillcount++; //jump to paint skip_body = true; } } /* else if mark is not set set mark to cur set mark-dir to cur-dir clear mark2 set findloop and backtrack to false */ else if(mark.x == -1 && mark.y == -1){ mark = cur; mark_dir = cur_dir; mark2.x = mark2.y = -1; findloop = backtrack = false; } else{ /* * if mark2 is not set if cur is at mark if cur-dir is the same as mark-dir clear mark turn around fill cur jump to PAINT else set backtrack to true set findloop to false set cur-dir to mark-dir end if else if findloop is true set mark2 to cur set mark2-dir to cur-dir end if * */ if(mark2.x == -1 && mark2.y == -1){ if(cur.x == mark.x && cur.y == mark.y){ if(cur_dir == mark_dir){ mark.x = mark.y = -1; cur_dir = turn_left(turn_left(cur_dir)); img.data[toidx(cur, img)] = CD_FILL_COLOR; fillcount++; //jump to paint skip_body = true; } else{ backtrack = true; findloop = false; cur_dir = mark_dir; } } else if(findloop == true){ mark2 = cur; mark2_dir = cur_dir; } } /* * else if cur is at mark set cur to mark2 set cur-dir to mark2-dir clear mark and mark2 set backtrack to false turn around fill cur jump to PAINT else if cur at mark2 set mark to cur set cur-dir and mark-dir to mark2-dir clear mark2 end end if * */ else{ if(cur.x == mark.x && cur.y == mark.y){ cur = mark2; cur_dir = mark2_dir; mark.x = mark.y = mark2.x = mark2.y = -1; backtrack = false; cur_dir = turn_left(turn_left(cur_dir)); img.data[toidx(cur, img)] = CD_FILL_COLOR; fillcount++; //jump to paint skip_body = true; } else if(cur.x == mark2.x && cur.y == mark2.y){ mark = cur; cur_dir = mark2_dir; mark_dir = mark2_dir; mark2.x = mark2.y = -1; } } } break; case 1: case 0: /* if backtrack is true set findloop to true else if findloop is true if mark is null restore mark end if else if front-left-pixel and back-left-pixel are both empty clear mark turn left fill cur jump to PAINT end if * */ if(backtrack == true){ findloop = true; } else if(findloop == true){ if(mark.x == -1 && mark.y == -1){ mark = mark2; } } else if(isvalid(front_left, img) && isvalid(back_left, img) && is_color(img.data[toidx(front_left, img)], CD_DETECT_COLOR) && is_color(img.data[toidx(back_left, img)], CD_DETECT_COLOR)){ mark.x = mark.y = -1; cur_dir = turn_left(cur_dir); img.data[toidx(cur, img)] = CD_FILL_COLOR; fillcount++; //jump to paint skip_body = true; } break; } /* move forward if right-pixel is empty if backtrack is true and findloop is false and either front-pixel or left-pixel is empty set findloop to true end if turn right PAINT: move forward end if * */ if(!skip_body){ cur = move_forward(cur, cur_dir); point_t right_pixel = move_forward(cur, turn_right(cur_dir)); point_t left_pixel = move_forward(cur, turn_left(cur_dir)); point_t front_pixel = move_forward(cur, cur_dir); if(isvalid(right_pixel, img) && is_color(img.data[toidx(right_pixel, img)], CD_DETECT_COLOR)){ if(backtrack==true && findloop == false && ((isvalid(front_pixel, img) && is_color(img.data[toidx(front_pixel, img)], CD_DETECT_COLOR))|| (isvalid(left_pixel, img) && is_color(img.data[toidx(left_pixel, img)], CD_DETECT_COLOR))) ) { findloop = true; } cur_dir = turn_right(cur_dir); cur = move_forward(cur, cur_dir); } } else cur = move_forward(cur, cur_dir); } #ifdef DEBUG int i,n = stack_size(borders); for(i=0; i < n ; i++){ point_t p = borders->s[i]; if(isvalid(p, img)){ img.data[toidx(p, img)] = CD_BORDER_COLOR; } } #endif return fillcount; }