View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0003073 | FSSCP | graphics | public | 2014-07-03 16:42 | 2014-07-30 10:09 |
Reporter | ngld | Assigned To | |||
Priority | normal | Severity | feature | Reproducibility | N/A |
Status | resolved | Resolution | fixed | ||
Summary | 0003073: Additional Mainhall capabilities (Cheats and "+Misc anim over doors:") | ||||
Description | This patch adds three new mainhall.tbl options: * "+Misc anim over doors:" (after "+Misc anim flags:") This option renders the given misc anim after the doors. * "+Cheat String:", "+Anim To Change:" and "+Anim To Change To:" (after "+Name:") This option exchanges misc anims once the given cheat code has been entered. The patch is attached. The test mainhall is here: https://dl.dropboxusercontent.com/u/6681376/main_hall_ext_test.7z You have to replace the data/tables/krios-hall.tbm with this one: http://pastebin.com/iybzSJ9Y | ||||
Tags | No tags attached. | ||||
|
mainhall_anims.patch (8,496 bytes)
diff --git a/code/menuui/mainhallmenu.cpp b/code/menuui/mainhallmenu.cpp index b63ab58..618e015 100644 --- a/code/menuui/mainhallmenu.cpp +++ b/code/menuui/mainhallmenu.cpp @@ -44,6 +44,8 @@ #endif +// A reference to io/keycontrol.cpp +extern void game_process_cheats(int k); // ---------------------------------------------------------------------------- // MAIN HALL DATA DEFINES @@ -60,7 +62,7 @@ main_hall_defines *Main_hall = NULL; int Vasudan_funny = 0; int Vasudan_funny_plate = -1; -char Main_hall_campaign_cheat[512] = ""; +SCP_string Main_hall_cheat = ""; // ---------------------------------------------------------------------------- // MISC interface data @@ -132,7 +134,7 @@ void main_hall_handle_random_intercom_sounds(); SCP_vector<generic_anim> Main_hall_misc_anim; // render all playing misc animations -void main_hall_render_misc_anims(float frametime); +void main_hall_render_misc_anims(float frametime, bool over_doors); // ---------------------------------------------------------------------------- @@ -573,8 +575,6 @@ void main_hall_init(const SCP_string &main_hall_name) Main_hall_region_linger_stamp = -1; - strcpy_s(Main_hall_campaign_cheat, ""); - // initialize door sound handles Main_hall_door_sound_handles.clear(); for (idx = 0; idx < Main_hall->num_door_animations; idx++) { @@ -662,8 +662,91 @@ void main_hall_do(float frametime) code = snazzy_menu_do(Main_hall_mask_data, Main_hall_mask_w, Main_hall_mask_h, Main_hall_num_options, Main_hall_region, &snazzy_action, 1, &key); if (key) { - extern void game_process_cheats(int k); game_process_cheats(key); + + Main_hall_cheat += (char) key_to_ascii(key); + if(Main_hall_cheat.length() > 40) { + Main_hall_cheat = Main_hall_cheat.substr(Main_hall_cheat.length() - 40); + } + + int cur_frame; + float anim_time; + bool cheat_anim_found, cheat_found = false; + + for (int c_idx = 0; c_idx < (int) Main_hall->cheat.size(); c_idx++) { + cheat_anim_found = false; + + if(Main_hall_cheat.find(Main_hall->cheat.at(c_idx)) != SCP_string::npos) { + cheat_found = true; + // switch animations + + for (int idx = 0; idx < Main_hall->num_misc_animations; idx++) { + if (Main_hall->misc_anim_name.at(idx) == Main_hall->cheat_anim_from.at(c_idx)) { + Main_hall->misc_anim_name.at(idx) = Main_hall->cheat_anim_to.at(c_idx); + + cur_frame = Main_hall_misc_anim.at(idx).current_frame; + anim_time = Main_hall_misc_anim.at(idx).anim_time; + + generic_anim_unload(&Main_hall_misc_anim.at(idx)); + generic_anim_init(&Main_hall_misc_anim.at(idx), Main_hall->misc_anim_name.at(idx)); + + if (generic_anim_stream(&Main_hall_misc_anim.at(idx)) == -1) { + nprintf(("General","WARNING! Could not load misc %s anim in main hall\n", Main_hall->misc_anim_name.at(idx).c_str())); + } else { + // start paused + if (Main_hall->misc_anim_modes.at(idx) == MISC_ANIM_MODE_HOLD) + Main_hall_misc_anim.at(idx).direction |= GENERIC_ANIM_DIRECTION_NOLOOP; + } + + Main_hall_misc_anim.at(idx).current_frame = cur_frame; + Main_hall_misc_anim.at(idx).anim_time = anim_time; + + // null out the delay timestamps + Main_hall->misc_anim_delay.at(idx).at(0) = -1; + + cheat_anim_found = true; + break; + } + } + + if (!cheat_anim_found) { + for (int idx = 0; idx < Main_hall->num_door_animations; idx++) { + if (Main_hall->door_anim_name.at(idx) == Main_hall->cheat_anim_from.at(c_idx)) { + Main_hall->door_anim_name.at(idx) = Main_hall->cheat_anim_to.at(c_idx); + + cur_frame = Main_hall_door_anim.at(idx).current_frame; + anim_time = Main_hall_door_anim.at(idx).anim_time; + + generic_anim_unload(&Main_hall_door_anim.at(idx)); + generic_anim_init(&Main_hall_door_anim.at(idx), Main_hall->door_anim_name.at(idx)); + + if (generic_anim_stream(&Main_hall_door_anim.at(idx)) == -1) { + nprintf(("General","WARNING! Could not load door anim %s in main hall\n", Main_hall->door_anim_name.at(idx).c_str())); + } else { + Main_hall_door_anim.at(idx).direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP; + } + + Main_hall_door_anim.at(idx).current_frame = cur_frame; + Main_hall_door_anim.at(idx).anim_time = anim_time; + + cheat_anim_found = true; + break; + } + } + } + + if (!cheat_anim_found) { + // Note: This can also happen if the cheat triggers a second time since the animations are already switched at that point. + nprintf(("General", "Could not find animation '%s' for cheat '%s'!", Main_hall->cheat_anim_from.at(c_idx).c_str(), Main_hall->cheat.at(c_idx).c_str())); + } + } + } + + if(cheat_found) { + // Found a cheat, clear the buffer. + + Main_hall_cheat = ""; + } } switch(key) { @@ -709,11 +792,7 @@ void main_hall_do(float frametime) gamesnd_play_iface(SND_IFACE_MOUSE_CLICK); main_hall_do_multi_ready(); } else { - if (strlen(Main_hall_campaign_cheat)) { - gameseq_post_event(GS_EVENT_CAMPAIGN_CHEAT); - } else { - gameseq_post_event(GS_EVENT_NEW_CAMPAIGN); - } + gameseq_post_event(GS_EVENT_NEW_CAMPAIGN); gamesnd_play_iface(SND_IFACE_MOUSE_CLICK); } break; @@ -825,10 +904,13 @@ void main_hall_do(float frametime) } // render misc animations - main_hall_render_misc_anims(frametime); + main_hall_render_misc_anims(frametime, false); // render door animtions main_hall_render_door_anims(frametime); + + // render misc animations (over doors) + main_hall_render_misc_anims(frametime, true); // blit any appropriate tooltips main_hall_maybe_blit_tooltips(); @@ -1050,7 +1132,7 @@ void main_hall_stop_music(bool fade) * * @param frametime Animation frame time */ -void main_hall_render_misc_anims(float frametime) +void main_hall_render_misc_anims(float frametime, bool over_doors) { std::deque<bool> group_anims_weve_checked; int idx, s_idx, jdx; @@ -1061,7 +1143,7 @@ void main_hall_render_misc_anims(float frametime) group_anims_weve_checked.push_back(false); // render it - if (Main_hall_misc_anim.at(idx).num_frames > 0) { + if (Main_hall_misc_anim.at(idx).num_frames > 0 && Main_hall->misc_anim_over_doors.at(idx) == over_doors) { // animation is paused if (Main_hall->misc_anim_paused.at(idx)) { // if the timestamp is -1, then regenerate it @@ -1996,6 +2078,20 @@ void parse_main_hall_table(const char* filename) m->name = Main_hall_defines.at(count).at(0).name; } + + // add cheats + while (optional_string("+Cheat String:")) { + stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN); + m->cheat.push_back(temp_string); + + required_string("+Anim To Change:"); + stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN); + m->cheat_anim_from.push_back(temp_string); + + required_string("+Anim To Change To:"); + stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN); + m->cheat_anim_to.push_back(temp_string); + } // minimum resolution if (optional_string("+Min Resolution:")) { @@ -2165,6 +2261,16 @@ void parse_main_hall_table(const char* filename) m->misc_anim_sound_flag.at(idx).push_back(0); } } + + for (idx = 0; idx < m->num_misc_animations; idx++) { + // render over doors - default to false + m->misc_anim_over_doors.push_back(0); + + if (optional_string("+Misc anim over doors:")) { + stuff_boolean(&rval); + m->misc_anim_over_doors.at(idx) = rval; + } + } // door animations required_string("+Num Door Animations:"); diff --git a/code/menuui/mainhallmenu.h b/code/menuui/mainhallmenu.h index 6ef6915..e771e33 100644 --- a/code/menuui/mainhallmenu.h +++ b/code/menuui/mainhallmenu.h @@ -19,6 +19,10 @@ typedef struct main_hall_defines { // mainhall name identifier SCP_string name; + + SCP_vector<SCP_string> cheat; + SCP_vector<SCP_string> cheat_anim_from; + SCP_vector<SCP_string> cheat_anim_to; // minimum resolution and aspect ratio needed to display this main hall int min_width; @@ -90,6 +94,9 @@ typedef struct main_hall_defines { //flags for each of the misc anim sounds SCP_vector<SCP_vector<int> > misc_anim_sound_flag; + + // controls the render order + SCP_vector<bool> misc_anim_over_doors; // door animations -------------------- |
|
I have tested the patch and it works. :) |
|
Does this patch depend on 0003071 at all? |
|
I'm 99% sure they are exclusive from each other. EDIT: Clarification. The feature don't depend on the features in the other patch at all. I'm also pretty sure the patches work exclusively of each other. |
|
The patch is completly independent (you can apply it straight to trunk). It should work but it still uses at() to access vector elements and no iterators. I can update it according to Goober's advice but I never got a response from him on the other bug. |
|
Patch needs to be in svn format to make it into 3.7.2 |
|
I've got off my lazy rear and have reviewed the patch - comments below: if(Main_hall_cheat.length() > 40) { Main_hall_cheat = Main_hall_cheat.substr(Main_hall_cheat.length() - 40); I'm not fond of magic numbers, could the 40 be replaced with a name, either a #define or a const int variable? I'm guessing that the purpose is to keep 40 chars in a rolling buffer and search for valid cheat strings in this buffer. If that's correct then a warning should be generated when parsing "+Cheat String" if the string is greater than 40 chars in length. Also the 40 is much less than the previous limit of 512? (which admittedly seems rather excessive) Is there a limit of 40 elsewhere in cheat-code handling? I guess I'm just wondering what prompted the selection of this size? In addition, maybe use size() instead of length to be consistent with the other new code. It also seems that other FSO vectors prefer the use of size(). for (int c_idx = 0; c_idx < (int) Main_hall->cheat.size(); c_idx++) { It would probably be a good idea to use an iterator here rather than an int (per the other patch). Lastly, I don't mind the use of .at() without exceptions in place to catch the error. Firstly, FSO doesn't currently have a defined exception handling scheme/hierarachy in place. Secondly, an exception from .at() will crash FSO and that seems like a perfectly reasonable response to the attempt to access out-of-bounds data :) |
|
mainhall_anims2.patch (8,825 bytes)
Index: code/menuui/mainhallmenu.cpp =================================================================== --- code/menuui/mainhallmenu.cpp (revision 10960) +++ code/menuui/mainhallmenu.cpp (working copy) @@ -45,6 +45,8 @@ #endif +// A reference to io/keycontrol.cpp +extern void game_process_cheats(int k); // ---------------------------------------------------------------------------- // MAIN HALL DATA DEFINES @@ -53,6 +55,7 @@ #define MISC_ANIM_MODE_HOLD 1 // play to the end and hold the animation #define MISC_ANIM_MODE_TIMED 2 // uses timestamps to determine when a finished anim should be checked again #define NUM_REGIONS 7 // (6 + 1 for multiplayer equivalent of campaign room) +#define MAIN_HALL_MAX_CHEAT_LEN 40 // cheat buffer length (also maximum cheat length) SCP_vector< SCP_vector<main_hall_defines> > Main_hall_defines; @@ -61,7 +64,7 @@ int Vasudan_funny = 0; int Vasudan_funny_plate = -1; -char Main_hall_campaign_cheat[512] = ""; +SCP_string Main_hall_cheat = ""; // ---------------------------------------------------------------------------- // MISC interface data @@ -133,7 +136,7 @@ SCP_vector<generic_anim> Main_hall_misc_anim; // render all playing misc animations -void main_hall_render_misc_anims(float frametime); +void main_hall_render_misc_anims(float frametime, bool over_doors); // ---------------------------------------------------------------------------- @@ -595,8 +598,6 @@ Main_hall_region_linger_stamp = -1; - strcpy_s(Main_hall_campaign_cheat, ""); - // initialize door sound handles Main_hall_door_sound_handles.clear(); for (idx = 0; idx < Main_hall->num_door_animations; idx++) { @@ -685,8 +686,91 @@ code = snazzy_menu_do(Main_hall_mask_data, Main_hall_mask_w, Main_hall_mask_h, (int)Main_hall->regions.size(), Main_hall_region, &snazzy_action, 1, &key); if (key) { - extern void game_process_cheats(int k); game_process_cheats(key); + + Main_hall_cheat += (char) key_to_ascii(key); + if(Main_hall_cheat.size() > MAIN_HALL_MAX_CHEAT_LEN) { + Main_hall_cheat = Main_hall_cheat.substr(Main_hall_cheat.size() - MAIN_HALL_MAX_CHEAT_LEN); + } + + int cur_frame; + float anim_time; + bool cheat_anim_found, cheat_found = false; + + for (int c_idx = 0; c_idx < (int) Main_hall->cheat.size(); c_idx++) { + cheat_anim_found = false; + + if(Main_hall_cheat.find(Main_hall->cheat.at(c_idx)) != SCP_string::npos) { + cheat_found = true; + // switch animations + + for (int idx = 0; idx < Main_hall->num_misc_animations; idx++) { + if (Main_hall->misc_anim_name.at(idx) == Main_hall->cheat_anim_from.at(c_idx)) { + Main_hall->misc_anim_name.at(idx) = Main_hall->cheat_anim_to.at(c_idx); + + cur_frame = Main_hall_misc_anim.at(idx).current_frame; + anim_time = Main_hall_misc_anim.at(idx).anim_time; + + generic_anim_unload(&Main_hall_misc_anim.at(idx)); + generic_anim_init(&Main_hall_misc_anim.at(idx), Main_hall->misc_anim_name.at(idx)); + + if (generic_anim_stream(&Main_hall_misc_anim.at(idx)) == -1) { + nprintf(("General","WARNING! Could not load misc %s anim in main hall\n", Main_hall->misc_anim_name.at(idx).c_str())); + } else { + // start paused + if (Main_hall->misc_anim_modes.at(idx) == MISC_ANIM_MODE_HOLD) + Main_hall_misc_anim.at(idx).direction |= GENERIC_ANIM_DIRECTION_NOLOOP; + } + + Main_hall_misc_anim.at(idx).current_frame = cur_frame; + Main_hall_misc_anim.at(idx).anim_time = anim_time; + + // null out the delay timestamps + Main_hall->misc_anim_delay.at(idx).at(0) = -1; + + cheat_anim_found = true; + break; + } + } + + if (!cheat_anim_found) { + for (int idx = 0; idx < Main_hall->num_door_animations; idx++) { + if (Main_hall->door_anim_name.at(idx) == Main_hall->cheat_anim_from.at(c_idx)) { + Main_hall->door_anim_name.at(idx) = Main_hall->cheat_anim_to.at(c_idx); + + cur_frame = Main_hall_door_anim.at(idx).current_frame; + anim_time = Main_hall_door_anim.at(idx).anim_time; + + generic_anim_unload(&Main_hall_door_anim.at(idx)); + generic_anim_init(&Main_hall_door_anim.at(idx), Main_hall->door_anim_name.at(idx)); + + if (generic_anim_stream(&Main_hall_door_anim.at(idx)) == -1) { + nprintf(("General","WARNING! Could not load door anim %s in main hall\n", Main_hall->door_anim_name.at(idx).c_str())); + } else { + Main_hall_door_anim.at(idx).direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP; + } + + Main_hall_door_anim.at(idx).current_frame = cur_frame; + Main_hall_door_anim.at(idx).anim_time = anim_time; + + cheat_anim_found = true; + break; + } + } + } + + if (!cheat_anim_found) { + // Note: This can also happen if the cheat triggers a second time since the animations are already switched at that point. + nprintf(("General", "Could not find animation '%s' for cheat '%s'!", Main_hall->cheat_anim_from.at(c_idx).c_str(), Main_hall->cheat.at(c_idx).c_str())); + } + } + } + + if(cheat_found) { + // Found a cheat, clear the buffer. + + Main_hall_cheat = ""; + } } switch(key) { @@ -759,11 +843,7 @@ Player->flags &= ~PLAYER_FLAGS_IS_MULTI; Game_mode = GM_NORMAL; - if (strlen(Main_hall_campaign_cheat)) { - gameseq_post_event(GS_EVENT_CAMPAIGN_CHEAT); - } else { - gameseq_post_event(GS_EVENT_NEW_CAMPAIGN); - } + gameseq_post_event(GS_EVENT_NEW_CAMPAIGN); gamesnd_play_iface(SND_IFACE_MOUSE_CLICK); break; @@ -873,10 +953,13 @@ } // render misc animations - main_hall_render_misc_anims(frametime); + main_hall_render_misc_anims(frametime, false); // render door animtions main_hall_render_door_anims(frametime); + + // render misc animations (over doors) + main_hall_render_misc_anims(frametime, true); // blit any appropriate tooltips main_hall_maybe_blit_tooltips(); @@ -1098,7 +1181,7 @@ * * @param frametime Animation frame time */ -void main_hall_render_misc_anims(float frametime) +void main_hall_render_misc_anims(float frametime, bool over_doors) { std::deque<bool> group_anims_weve_checked; int idx, s_idx, jdx; @@ -1109,7 +1192,7 @@ group_anims_weve_checked.push_back(false); // render it - if (Main_hall_misc_anim.at(idx).num_frames > 0) { + if (Main_hall_misc_anim.at(idx).num_frames > 0 && Main_hall->misc_anim_over_doors.at(idx) == over_doors) { // animation is paused if (Main_hall->misc_anim_paused.at(idx)) { // if the timestamp is -1, then regenerate it @@ -2051,7 +2134,27 @@ m->name = Main_hall_defines.at(count).at(0).name; } + + // add cheats + while (optional_string("+Cheat String:")) { + stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN); + m->cheat.push_back(temp_string); + if(strlen(temp_string) > MAIN_HALL_MAX_CHEAT_LEN) { + // Since the value is longer than the cheat buffer it will never match. + + Warning(LOCATION, "The value '%s' for '+Cheat String:' is too long! It can be at most %d characters long.", temp_string, MAIN_HALL_MAX_CHEAT_LEN); + } + + required_string("+Anim To Change:"); + stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN); + m->cheat_anim_from.push_back(temp_string); + + required_string("+Anim To Change To:"); + stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN); + m->cheat_anim_to.push_back(temp_string); + } + // minimum resolution if (optional_string("+Min Resolution:")) { stuff_int(&m->min_width); @@ -2221,6 +2324,17 @@ } } + for (idx = 0; idx < m->num_misc_animations; idx++) { + // render over doors - default to false + + if (optional_string("+Misc anim over doors:")) { + stuff_boolean(&rval); + m->misc_anim_over_doors.push_back(rval); + } else { + m->misc_anim_over_doors.push_back(0); + } + } + region_info_init(*m); int mask; Index: code/menuui/mainhallmenu.h =================================================================== --- code/menuui/mainhallmenu.h (revision 10960) +++ code/menuui/mainhallmenu.h (working copy) @@ -26,6 +26,10 @@ typedef struct main_hall_defines { // mainhall name identifier SCP_string name; + + SCP_vector<SCP_string> cheat; + SCP_vector<SCP_string> cheat_anim_from; + SCP_vector<SCP_string> cheat_anim_to; // minimum resolution and aspect ratio needed to display this main hall int min_width; @@ -97,6 +101,9 @@ //flags for each of the misc anim sounds SCP_vector<SCP_vector<int> > misc_anim_sound_flag; + + // controls the render order + SCP_vector<bool> misc_anim_over_doors; // door animations -------------------- |
|
I've uploaded a new patch. This time it's in svn format. I've defined the new constant MAIN_HALL_MAX_CHEAT_LEN which now holds the length of the rolling buffer. I've picked 40 for no particular reason, I just thought that would be long enough for cheat codes. I also added a warning, if the "+Cheat String" is too long. I could use an iterator but then I'd have to calculate the index for each item to access Main_hall->cheat_anim_from and Main_hall->cheat_anim_to. I don't see the benefit in this case. |
|
When parsing the "+Cheat String" values you stuff the string into a char array although you always assign the string value to a SCP_string. You could just stuff that into a SCP_string and push that into the vector which would also get rid of the hard-coded string length limits. Apart from that it looks good to me. |
|
mainhall_anims3.patch (8,809 bytes)
Index: code/menuui/mainhallmenu.cpp =================================================================== --- code/menuui/mainhallmenu.cpp (revision 10960) +++ code/menuui/mainhallmenu.cpp (working copy) @@ -45,6 +45,8 @@ #endif +// A reference to io/keycontrol.cpp +extern void game_process_cheats(int k); // ---------------------------------------------------------------------------- // MAIN HALL DATA DEFINES @@ -53,6 +55,7 @@ #define MISC_ANIM_MODE_HOLD 1 // play to the end and hold the animation #define MISC_ANIM_MODE_TIMED 2 // uses timestamps to determine when a finished anim should be checked again #define NUM_REGIONS 7 // (6 + 1 for multiplayer equivalent of campaign room) +#define MAIN_HALL_MAX_CHEAT_LEN 40 // cheat buffer length (also maximum cheat length) SCP_vector< SCP_vector<main_hall_defines> > Main_hall_defines; @@ -61,7 +64,7 @@ int Vasudan_funny = 0; int Vasudan_funny_plate = -1; -char Main_hall_campaign_cheat[512] = ""; +SCP_string Main_hall_cheat = ""; // ---------------------------------------------------------------------------- // MISC interface data @@ -133,7 +136,7 @@ SCP_vector<generic_anim> Main_hall_misc_anim; // render all playing misc animations -void main_hall_render_misc_anims(float frametime); +void main_hall_render_misc_anims(float frametime, bool over_doors); // ---------------------------------------------------------------------------- @@ -595,8 +598,6 @@ Main_hall_region_linger_stamp = -1; - strcpy_s(Main_hall_campaign_cheat, ""); - // initialize door sound handles Main_hall_door_sound_handles.clear(); for (idx = 0; idx < Main_hall->num_door_animations; idx++) { @@ -685,8 +686,91 @@ code = snazzy_menu_do(Main_hall_mask_data, Main_hall_mask_w, Main_hall_mask_h, (int)Main_hall->regions.size(), Main_hall_region, &snazzy_action, 1, &key); if (key) { - extern void game_process_cheats(int k); game_process_cheats(key); + + Main_hall_cheat += (char) key_to_ascii(key); + if(Main_hall_cheat.size() > MAIN_HALL_MAX_CHEAT_LEN) { + Main_hall_cheat = Main_hall_cheat.substr(Main_hall_cheat.size() - MAIN_HALL_MAX_CHEAT_LEN); + } + + int cur_frame; + float anim_time; + bool cheat_anim_found, cheat_found = false; + + for (int c_idx = 0; c_idx < (int) Main_hall->cheat.size(); c_idx++) { + cheat_anim_found = false; + + if(Main_hall_cheat.find(Main_hall->cheat.at(c_idx)) != SCP_string::npos) { + cheat_found = true; + // switch animations + + for (int idx = 0; idx < Main_hall->num_misc_animations; idx++) { + if (Main_hall->misc_anim_name.at(idx) == Main_hall->cheat_anim_from.at(c_idx)) { + Main_hall->misc_anim_name.at(idx) = Main_hall->cheat_anim_to.at(c_idx); + + cur_frame = Main_hall_misc_anim.at(idx).current_frame; + anim_time = Main_hall_misc_anim.at(idx).anim_time; + + generic_anim_unload(&Main_hall_misc_anim.at(idx)); + generic_anim_init(&Main_hall_misc_anim.at(idx), Main_hall->misc_anim_name.at(idx)); + + if (generic_anim_stream(&Main_hall_misc_anim.at(idx)) == -1) { + nprintf(("General","WARNING! Could not load misc %s anim in main hall\n", Main_hall->misc_anim_name.at(idx).c_str())); + } else { + // start paused + if (Main_hall->misc_anim_modes.at(idx) == MISC_ANIM_MODE_HOLD) + Main_hall_misc_anim.at(idx).direction |= GENERIC_ANIM_DIRECTION_NOLOOP; + } + + Main_hall_misc_anim.at(idx).current_frame = cur_frame; + Main_hall_misc_anim.at(idx).anim_time = anim_time; + + // null out the delay timestamps + Main_hall->misc_anim_delay.at(idx).at(0) = -1; + + cheat_anim_found = true; + break; + } + } + + if (!cheat_anim_found) { + for (int idx = 0; idx < Main_hall->num_door_animations; idx++) { + if (Main_hall->door_anim_name.at(idx) == Main_hall->cheat_anim_from.at(c_idx)) { + Main_hall->door_anim_name.at(idx) = Main_hall->cheat_anim_to.at(c_idx); + + cur_frame = Main_hall_door_anim.at(idx).current_frame; + anim_time = Main_hall_door_anim.at(idx).anim_time; + + generic_anim_unload(&Main_hall_door_anim.at(idx)); + generic_anim_init(&Main_hall_door_anim.at(idx), Main_hall->door_anim_name.at(idx)); + + if (generic_anim_stream(&Main_hall_door_anim.at(idx)) == -1) { + nprintf(("General","WARNING! Could not load door anim %s in main hall\n", Main_hall->door_anim_name.at(idx).c_str())); + } else { + Main_hall_door_anim.at(idx).direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP; + } + + Main_hall_door_anim.at(idx).current_frame = cur_frame; + Main_hall_door_anim.at(idx).anim_time = anim_time; + + cheat_anim_found = true; + break; + } + } + } + + if (!cheat_anim_found) { + // Note: This can also happen if the cheat triggers a second time since the animations are already switched at that point. + nprintf(("General", "Could not find animation '%s' for cheat '%s'!", Main_hall->cheat_anim_from.at(c_idx).c_str(), Main_hall->cheat.at(c_idx).c_str())); + } + } + } + + if(cheat_found) { + // Found a cheat, clear the buffer. + + Main_hall_cheat = ""; + } } switch(key) { @@ -759,11 +843,7 @@ Player->flags &= ~PLAYER_FLAGS_IS_MULTI; Game_mode = GM_NORMAL; - if (strlen(Main_hall_campaign_cheat)) { - gameseq_post_event(GS_EVENT_CAMPAIGN_CHEAT); - } else { - gameseq_post_event(GS_EVENT_NEW_CAMPAIGN); - } + gameseq_post_event(GS_EVENT_NEW_CAMPAIGN); gamesnd_play_iface(SND_IFACE_MOUSE_CLICK); break; @@ -873,10 +953,13 @@ } // render misc animations - main_hall_render_misc_anims(frametime); + main_hall_render_misc_anims(frametime, false); // render door animtions main_hall_render_door_anims(frametime); + + // render misc animations (over doors) + main_hall_render_misc_anims(frametime, true); // blit any appropriate tooltips main_hall_maybe_blit_tooltips(); @@ -1098,7 +1181,7 @@ * * @param frametime Animation frame time */ -void main_hall_render_misc_anims(float frametime) +void main_hall_render_misc_anims(float frametime, bool over_doors) { std::deque<bool> group_anims_weve_checked; int idx, s_idx, jdx; @@ -1109,7 +1192,7 @@ group_anims_weve_checked.push_back(false); // render it - if (Main_hall_misc_anim.at(idx).num_frames > 0) { + if (Main_hall_misc_anim.at(idx).num_frames > 0 && Main_hall->misc_anim_over_doors.at(idx) == over_doors) { // animation is paused if (Main_hall->misc_anim_paused.at(idx)) { // if the timestamp is -1, then regenerate it @@ -2051,7 +2134,27 @@ m->name = Main_hall_defines.at(count).at(0).name; } + + // add cheats + while (optional_string("+Cheat String:")) { + stuff_string(temp_scp_string, F_RAW); + m->cheat.push_back(temp_scp_string); + if(temp_scp_string.size() > MAIN_HALL_MAX_CHEAT_LEN) { + // Since the value is longer than the cheat buffer it will never match. + + Warning(LOCATION, "The value '%s' for '+Cheat String:' is too long! It can be at most %d characters long.", temp_scp_string.size(), MAIN_HALL_MAX_CHEAT_LEN); + } + + required_string("+Anim To Change:"); + stuff_string(temp_scp_string, F_NAME); + m->cheat_anim_from.push_back(temp_scp_string); + + required_string("+Anim To Change To:"); + stuff_string(temp_scp_string, F_NAME); + m->cheat_anim_to.push_back(temp_scp_string); + } + // minimum resolution if (optional_string("+Min Resolution:")) { stuff_int(&m->min_width); @@ -2221,6 +2324,17 @@ } } + for (idx = 0; idx < m->num_misc_animations; idx++) { + // render over doors - default to false + + if (optional_string("+Misc anim over doors:")) { + stuff_boolean(&rval); + m->misc_anim_over_doors.push_back(rval); + } else { + m->misc_anim_over_doors.push_back(0); + } + } + region_info_init(*m); int mask; Index: code/menuui/mainhallmenu.h =================================================================== --- code/menuui/mainhallmenu.h (revision 10960) +++ code/menuui/mainhallmenu.h (working copy) @@ -26,6 +26,10 @@ typedef struct main_hall_defines { // mainhall name identifier SCP_string name; + + SCP_vector<SCP_string> cheat; + SCP_vector<SCP_string> cheat_anim_from; + SCP_vector<SCP_string> cheat_anim_to; // minimum resolution and aspect ratio needed to display this main hall int min_width; @@ -97,6 +101,9 @@ //flags for each of the misc anim sounds SCP_vector<SCP_vector<int> > misc_anim_sound_flag; + + // controls the render order + SCP_vector<bool> misc_anim_over_doors; // door animations -------------------- |
|
Fixed. The MAIN_HALL_MAX_CHEAT_LEN limit still applies though. |
|
Sure, MAIN_HALL_MAX_CHEAT_LEN has to stay. As noted above, looks good to me in the current version. |
|
ok, looks good to me, I'll commit it tonight or tomorrow night. |
|
Fix committed to trunk@10961. |
fs2open: trunk r10961 2014-07-30 06:36 Ported: N/A Details Diff |
Fix mantis 3073: Additional Mainhall capabilities (from ngld) Adds two new mainhall.tbl options: 1) "+Misc anim over doors:" (misc anim rendered after doors) 2) "+Cheat String:" (exchanges misc anim when cheat is entered) |
Affected Issues 0003073 |
|
mod - /trunk/fs2_open/code/menuui/mainhallmenu.cpp | Diff File | ||
mod - /trunk/fs2_open/code/menuui/mainhallmenu.h | Diff File |
Date Modified | Username | Field | Change |
---|---|---|---|
2014-07-03 16:42 | ngld | New Issue | |
2014-07-03 16:42 | ngld | File Added: mainhall_anims.patch | |
2014-07-03 16:43 | MjnMixael | Note Added: 0016015 | |
2014-07-03 16:44 | MjnMixael | Assigned To | => MjnMixael |
2014-07-03 16:44 | MjnMixael | Status | new => code review |
2014-07-03 16:44 | MjnMixael | Assigned To | MjnMixael => |
2014-07-17 23:16 | niffiwan | Note Added: 0016085 | |
2014-07-17 23:44 | MjnMixael | Note Added: 0016087 | |
2014-07-18 01:46 | MjnMixael | Note Edited: 0016087 | |
2014-07-18 09:27 | ngld | Note Added: 0016094 | |
2014-07-20 17:59 | The_E | Note Added: 0016099 | |
2014-07-21 03:31 | niffiwan | Note Added: 0016109 | |
2014-07-29 18:03 | ngld | File Added: mainhall_anims2.patch | |
2014-07-29 18:11 | ngld | Note Added: 0016143 | |
2014-07-29 20:13 | m_m | Note Added: 0016144 | |
2014-07-29 21:23 | ngld | File Added: mainhall_anims3.patch | |
2014-07-29 21:25 | ngld | Note Added: 0016145 | |
2014-07-29 21:32 | m_m | Note Added: 0016146 | |
2014-07-30 03:17 | niffiwan | Note Added: 0016147 | |
2014-07-30 10:09 | niffiwan | Changeset attached | => fs2open trunk r10961 |
2014-07-30 10:09 | niffiwan | Note Added: 0016148 | |
2014-07-30 10:09 | niffiwan | Status | code review => resolved |
2014-07-30 10:09 | niffiwan | Resolution | open => fixed |