#include #include #include #include #include "global.h" #include "actors.h" #include "draw_scene.h" typedef int my_enum;//This enumeration will decrease, then wrap to top, increase and then wrap to bottom, when using the inc() and dec() functions. Special purpose though, since you have to have between 2 and 255 values in the enumeration and you have to have the same value in enum[0] as in enum[max] - otherwise we'll probably segfault... my_enum normal_skin_enum[] = { SKIN_BROWN, SKIN_NORMAL, SKIN_PALE, SKIN_TAN, SKIN_BROWN }; my_enum elf_skin_enum[] = { SKIN_BROWN, SKIN_NORMAL, SKIN_PALE, SKIN_TAN, SKIN_DARK_BLUE, SKIN_BROWN }; my_enum draegoni_skin_enum[]= { SKIN_BROWN, SKIN_NORMAL, SKIN_PALE, SKIN_TAN, SKIN_WHITE, SKIN_BROWN }; my_enum normal_hair_enum[] = { HAIR_BLACK, HAIR_BLOND, HAIR_BROWN, HAIR_GRAY, HAIR_RED, HAIR_WHITE, HAIR_DARK_BROWN, HAIR_STRAWBERRY, HAIR_LIGHT_BLOND, HAIR_DIRTY_BLOND, HAIR_BROWN_GRAY, HAIR_DARK_GRAY, HAIR_DARK_RED, HAIR_BLACK }; my_enum draegoni_hair_enum[]= { HAIR_BLACK, HAIR_BLOND, HAIR_BROWN, HAIR_GRAY, HAIR_RED, HAIR_WHITE, HAIR_DARK_BROWN, HAIR_STRAWBERRY, HAIR_LIGHT_BLOND, HAIR_DIRTY_BLOND, HAIR_BROWN_GRAY, HAIR_DARK_GRAY, HAIR_DARK_RED, HAIR_BLUE, HAIR_GREEN, HAIR_PURPLE, HAIR_BLACK }; my_enum male_shirt_enum[] = { SHIRT_BLACK, SHIRT_BLUE, SHIRT_BROWN, SHIRT_GREY, SHIRT_GREEN, SHIRT_LIGHTBROWN, SHIRT_ORANGE, SHIRT_PURPLE, SHIRT_RED, SHIRT_WHITE, SHIRT_YELLOW, SHIRT_BLACK }; my_enum normal_shirt_enum[] = { SHIRT_BLACK, SHIRT_BLUE, SHIRT_BROWN, SHIRT_GREY, SHIRT_GREEN, SHIRT_LIGHTBROWN, SHIRT_ORANGE, SHIRT_PINK, SHIRT_PURPLE, SHIRT_RED, SHIRT_WHITE, SHIRT_YELLOW, SHIRT_BLACK }; my_enum normal_pants_enum[] = { PANTS_BLACK, PANTS_BLUE, PANTS_BROWN, PANTS_DARKBROWN, PANTS_GREY, PANTS_GREEN, PANTS_LIGHTBROWN, PANTS_RED, PANTS_WHITE, PANTS_BLACK }; my_enum normal_boots_enum[] = { BOOTS_BLACK, BOOTS_BROWN, BOOTS_DARKBROWN, BOOTS_DULLBROWN, BOOTS_LIGHTBROWN, BOOTS_ORANGE, BOOTS_BLACK }; my_enum normal_head_enum[] = { HEAD_1, HEAD_2, HEAD_3, HEAD_4, HEAD_1 }; my_enum human_head_enum[] = { HEAD_1, HEAD_2, HEAD_3, HEAD_4, HEAD_5, HEAD_1 }; struct race_def { int type; my_enum *skin; my_enum *hair; my_enum *shirts; my_enum *pants; my_enum *boots; my_enum *head; float x, y, z_rot; } races[12] = { {human_female, normal_skin_enum, normal_hair_enum, normal_shirt_enum, normal_pants_enum, normal_boots_enum, human_head_enum, 43.0f, 156.0f, 140.0f}, {human_male, normal_skin_enum, normal_hair_enum, male_shirt_enum, normal_pants_enum, normal_boots_enum, human_head_enum, 43.0f, 156.0f, 140.0f}, {elf_female, elf_skin_enum, normal_hair_enum, normal_shirt_enum, normal_pants_enum, normal_boots_enum, normal_head_enum, 42.0f, 92.0f, 180.0f}, {elf_male, elf_skin_enum, normal_hair_enum, male_shirt_enum, normal_pants_enum, normal_boots_enum, normal_head_enum, 42.0f, 92.0f, 180.0f}, {dwarf_female, normal_skin_enum, normal_hair_enum, normal_shirt_enum, normal_pants_enum, normal_boots_enum, normal_head_enum, 100.0f, 149.0f, 180.0f}, {dwarf_male, normal_skin_enum, normal_hair_enum, male_shirt_enum, normal_pants_enum, normal_boots_enum, normal_head_enum, 100.0f, 149.0f, 180.0f}, {gnome_female, normal_skin_enum, normal_hair_enum, normal_shirt_enum, normal_pants_enum, normal_boots_enum, normal_head_enum, 43.0f, 156.0f, 180.0f}, {gnome_male, normal_skin_enum, normal_hair_enum, male_shirt_enum, normal_pants_enum, normal_boots_enum, normal_head_enum, 43.0f, 156.0f, 180.0f}, {orchan_female, normal_skin_enum, normal_hair_enum, normal_shirt_enum, normal_pants_enum, normal_boots_enum, normal_head_enum, 42.0f, 92.0f, 180.0f}, {orchan_male, normal_skin_enum, normal_hair_enum, male_shirt_enum, normal_pants_enum, normal_boots_enum, normal_head_enum, 42.0f, 92.0f, 180.0f}, {draegoni_female, draegoni_skin_enum, draegoni_hair_enum, normal_shirt_enum, normal_pants_enum, normal_boots_enum, normal_head_enum, 100.0f, 149.0f, 180.0f}, {draegoni_male, draegoni_skin_enum, draegoni_hair_enum, male_shirt_enum, normal_pants_enum, normal_boots_enum, normal_head_enum, 100.0f, 149.0f, 180.0f}, }; struct char_def { int male; int race_id;//races[race_id] int race; int skin; int hair; int shirt; int pants; int boots; int head; struct race_def * def; actor * our_model; } our_actor = { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL }; //Enum handling int find_pos_in_enum(my_enum * def, int val) { int i; for(i=1;i<255;i++){ if(def[i]==val) return i; else if(def[i]==def[0])return 0; } return 0; } int inc(my_enum * def, int val, int no_steps) { my_enum * here=&def[find_pos_in_enum(def, val)]; while(no_steps--){ if(*here==def[0])here=&def[1]; else here++; } return *here; } int dec(my_enum * def, int val, int no_steps) { my_enum * top=&def[find_pos_in_enum(def, def[0])]; my_enum * here=&def[find_pos_in_enum(def, val)]; while(no_steps--){ if(*here==*top)here=top; here--; } return *here; } //New char interface int display_time=0; struct input_text { char str[40]; int pos; } inputs[3] = { {"Player", 6}, {"", 0}, {"", 0} }; int creating_char = 1; void set_create_char_error (const char *msg, int len) { char buf[512]; if (len <= 0) { // server didn't send a message, use the default safe_snprintf (create_char_error_str, sizeof(create_char_error_str), "%s: %s", reg_error_str, char_name_in_use); } else { int prelen = strlen (reg_error_str) + 2; int maxlen = sizeof (create_char_error_str) - prelen - 1; if (len > maxlen) len = maxlen; safe_snprintf (create_char_error_str, sizeof(create_char_error_str), "%s: %.*s", reg_error_str, len, msg); create_char_error_str[len+prelen] = '\0'; reset_soft_breaks (create_char_error_str, len+prelen, sizeof (create_char_error_str), 1.0, window_width - 20, NULL, NULL); } LOG_TO_CONSOLE(c_red1, create_char_error_str); put_small_colored_text_in_box(c_red1, (unsigned char*)create_char_error_str, strlen(create_char_error_str), 200, buf); safe_snprintf(create_char_error_str, sizeof(create_char_error_str), "%s", buf); display_time=cur_time+6000; creating_char=1; } void change_actor () { // We only need to reload the core model, and attach all the correct mesh types. if (our_actor.our_model){ if(our_actor.our_model->calmodel!=NULL) CalModel_Delete(our_actor.our_model->calmodel); our_actor.our_model->calmodel = CalModel_New(actors_defs[our_actor.race].coremodel); // Attach the Meshes. CalModel_AttachMesh(our_actor.our_model->calmodel,actors_defs[our_actor.race].head[our_actor.head].mesh_index); CalModel_AttachMesh(our_actor.our_model->calmodel,actors_defs[our_actor.race].shirt[our_actor.shirt].mesh_index); CalModel_AttachMesh(our_actor.our_model->calmodel,actors_defs[our_actor.race].legs[our_actor.pants].mesh_index); // Save which mesh is which. our_actor.our_model->body_parts->head_meshindex=actors_defs[our_actor.race].head[our_actor.head].mesh_index; our_actor.our_model->body_parts->torso_meshindex=actors_defs[our_actor.race].shirt[our_actor.shirt].mesh_index; our_actor.our_model->body_parts->legs_meshindex=actors_defs[our_actor.race].legs[our_actor.pants].mesh_index; // Recopy all of the textures. my_strncp(our_actor.our_model->body_parts->hands_tex,actors_defs[our_actor.race].skin[our_actor.skin].hands_name,sizeof(our_actor.our_model->body_parts->hands_tex)); my_strncp(our_actor.our_model->body_parts->head_tex,actors_defs[our_actor.race].skin[our_actor.skin].head_name,sizeof(our_actor.our_model->body_parts->head_tex)); my_strncp(our_actor.our_model->body_parts->hair_tex,actors_defs[our_actor.race].hair[our_actor.hair].hair_name,sizeof(our_actor.our_model->body_parts->hair_tex)); my_strncp(our_actor.our_model->body_parts->arms_tex,actors_defs[our_actor.race].shirt[our_actor.shirt].arms_name,sizeof(our_actor.our_model->body_parts->arms_tex)); my_strncp(our_actor.our_model->body_parts->torso_tex,actors_defs[our_actor.race].shirt[our_actor.shirt].torso_name,sizeof(our_actor.our_model->body_parts->torso_tex)); my_strncp(our_actor.our_model->body_parts->pants_tex,actors_defs[our_actor.race].legs[our_actor.pants].legs_name,sizeof(our_actor.our_model->body_parts->pants_tex)); my_strncp(our_actor.our_model->body_parts->boots_tex,actors_defs[our_actor.race].boots[our_actor.boots].boots_name,sizeof(our_actor.our_model->body_parts->boots_tex)); glDeleteTextures(1,&our_actor.our_model->texture_id); // Free the textures our_actor.our_model->texture_id = load_bmp8_enhanced_actor(our_actor.our_model->body_parts, 255); // Rebuild the textures. // Move the actor. Could be a little disorienting, though. our_actor.our_model->x_tile_pos = our_actor.def->x; our_actor.our_model->y_tile_pos = our_actor.def->y; our_actor.our_model->x_pos = our_actor.def->x*0.5f; our_actor.our_model->y_pos = our_actor.def->y*0.5f; our_actor.our_model->z_rot = our_actor.def->z_rot; } } ////////////////////////////////////////////////////////////////////////// // New character window code below. int newchar_root_win = -1; int color_race_win = -1; int namepass_win = -1; int display_newchar_handler (window_info *win) { int any_reflection; static int main_count = 0; //see if we have to load a model (male or female) if (creating_char && !our_actor.our_model){ move_camera();//Make sure we lag a little... our_actor.our_model = add_actor_interface (our_actor.def->x, our_actor.def->y, our_actor.def->z_rot, 1.0f, our_actor.race, our_actor.skin, our_actor.hair, our_actor.shirt, our_actor.pants, our_actor.boots, our_actor.head); yourself = 0; your_actor = our_actor.our_model; } if(disconnected)connect_to_server(); if (!(main_count%10)) read_mouse_now = 1; else read_mouse_now = 0; reset_under_the_mouse(); //This window is a bit special since it's not fully 2D Leave2DMode (); glPushMatrix (); if (new_zoom_level != zoom_level) { zoom_level = new_zoom_level; resize_root_window (); } move_camera (); save_scene_matrix (); CalculateFrustum (); #ifdef NEW_FRUSTUM set_click_line(); #endif any_reflection = find_reflection (); CHECK_GL_ERRORS (); if (SDL_GetAppState() & SDL_APPACTIVE) { get_tmp_actor_data(); #ifndef NEW_WEATHER //now, determine the current weather light level get_weather_light_level (); #endif draw_global_light (); update_scene_lights(); draw_lights(); CHECK_GL_ERRORS (); if (shadows_on && is_day) { render_light_view(); CHECK_GL_ERRORS (); } if (weather_use_fog()) render_fog(); if (any_reflection > 1) { draw_sky_background (); CHECK_GL_ERRORS (); if (show_reflection) display_3d_reflection (); } CHECK_GL_ERRORS (); if (shadows_on && is_day) { draw_sun_shadowed_scene (any_reflection); } else { glNormal3f (0.0f,0.0f,1.0f); if (any_reflection) draw_lake_tiles (); draw_tile_map (); CHECK_GL_ERRORS (); display_2d_objects (); CHECK_GL_ERRORS (); anything_under_the_mouse (0, UNDER_MOUSE_NOTHING); display_objects (); display_ground_objects(); display_actors (1, 0); display_alpha_objects(); display_blended_objects(); } CHECK_GL_ERRORS (); } //particles should be last, we have no Z writting display_particles (); CHECK_GL_ERRORS (); Enter2DMode (); glColor3f(1.0f,1.0f,1.0f); draw_hud_frame(); CHECK_GL_ERRORS (); { int msg, offset, ytext, filter; ytext = use_windowed_chat == 1 ? 25 : 20; filter = use_windowed_chat == 1 ? current_filter : FILTER_ALL; if ( find_last_lines_time (&msg, &offset, current_filter, console_text_width) ){ set_font(chat_font); // switch to the chat font draw_messages (10, ytext, display_text_buffer, DISPLAY_TEXT_BUFFER_SIZE, filter, msg, offset, -1, win->len_x - hud_x - 20, win->len_y, chat_zoom); set_font (0); // switch to fixed } } glColor3f(251/255.0f, 250/255.0f, 190/255.0f); draw_string_small(132, win->len_y-hud_y+15, (unsigned char*)zoom_in_out, 1); draw_string_small(132, win->len_y-hud_y+32, (unsigned char*)rotate_camera, 1); Leave2DMode (); glEnable (GL_LIGHTING); glPopMatrix (); // restore the state Enter2DMode (); main_count++; #ifdef OPENGL_TRACE CHECK_GL_ERRORS(); #endif //OPENGL_TRACE return 1; } int mouseover_newchar_handler (window_info *win, int mx, int my) { return 1; } int click_newchar_handler (window_info *win, int mx, int my, Uint32 flags) { if (flags & ELW_WHEEL_UP) { if (camera_zoom_dir == -1) camera_zoom_frames += 5; else camera_zoom_frames = 5; camera_zoom_dir = -1; return 1; } if (flags & ELW_WHEEL_DOWN) { if (camera_zoom_dir == 1) camera_zoom_frames += 5; else camera_zoom_frames = 5; camera_zoom_dir = 1; return 1; } return 1; // we captured this mouseclick } int keypress_newchar_handler (window_info *win, int mx, int my, Uint32 key, Uint32 unikey) { static int last_time=0; if ( check_quit_or_fullscreen (key) ) { return 1; } else if(disconnected && !alt_on && !ctrl_on){ connect_to_server(); } else if (key == K_CAMERAUP) { if (rx > -60) rx -= 1.0f; } else if (key == K_CAMERADOWN) { if (rx < -45) rx += 1.0f; } else if (key == K_ZOOMIN) { if (zoom_level >= 1.00f) new_zoom_level = zoom_level - 0.25; } else if (key == K_ZOOMOUT) { if (zoom_level <= 3.50f) new_zoom_level = zoom_level + 0.25; } else if(key==K_OPTIONS){ view_window(&elconfig_win, 0); } else if(key==K_ENCYCLOPEDIA){ view_tab(&tab_help_win, &tab_help_collection_id, HELP_TAB_ENCYCLOPEDIA); } else if(key==K_HELP) { view_tab(&tab_help_win, &tab_help_collection_id, HELP_TAB_HELP); } else if (key == K_RULES) { view_tab(&tab_help_win, &tab_help_collection_id, HELP_TAB_RULES); } else if (key == K_ROTATELEFT) { camera_rotation_speed = normal_camera_rotation_speed / 40; camera_rotation_frames = 40; } else if (key == K_FROTATELEFT) { camera_rotation_speed = fine_camera_rotation_speed / 10; camera_rotation_frames = 10; } else if (key == K_ROTATERIGHT) { camera_rotation_speed = -normal_camera_rotation_speed / 40; camera_rotation_frames = 40; } else if (key == K_FROTATERIGHT) { camera_rotation_speed = -fine_camera_rotation_speed / 10; camera_rotation_frames = 10; } else if(key==K_TURNLEFT){ if(last_time+666skin, SKIN_BROWN, RAND (SKIN_BROWN, SKIN_TAN));//Increment a random # of times. our_actor.hair = inc(our_actor.def->hair, HAIR_BLACK, RAND (HAIR_BLACK, our_actor.def->type >= draegoni_female ? HAIR_PURPLE:HAIR_WHITE)); our_actor.shirt = inc(our_actor.def->shirts, SHIRT_BLACK, RAND (SHIRT_BLACK, SHIRT_YELLOW)); our_actor.pants = inc(our_actor.def->pants, PANTS_BLACK, RAND (PANTS_BLACK, PANTS_WHITE)); our_actor.boots = inc(our_actor.def->boots, BOOTS_BLACK, RAND (BOOTS_BLACK, BOOTS_ORANGE)); our_actor.head = inc(our_actor.def->head, HEAD_1, RAND (HEAD_1, our_actor.def->type==human_female?HEAD_5:HEAD_4)); our_actor.race = our_actor.def->type; our_actor.male = our_actor.race