controller::controller(CVideo& video, const vconfig& data, const std::string& scenario_name, int segment_index) : video_(video) , evt_context_() , scenario_name_(scenario_name) , segment_index_(segment_index) , parts_() { ASSERT_LOG(resources::gamedata != nullptr, "Ouch: gamedata is nullptr when initializing storyscreen controller"); resolve_wml(data); }
part::part(const vconfig &part_cfg) : show_title_() , text_() , text_title_() , text_block_loc_(part::BLOCK_BOTTOM) , title_alignment_(part::TEXT_LEFT) , music_() , sound_() , background_layers_() , floating_images_() { resolve_wml(part_cfg); }
void part::resolve_wml(const vconfig &cfg) { if(cfg.null()) { return; } // Converts shortcut syntax to members of [background_layer] background_layer bl; if(cfg.has_attribute("background")) { bl.set_file(cfg["background"].str()); } if(cfg.has_attribute("scale_background")) { bl.set_scale_horizontally(cfg["scale_background"].to_bool(true)); bl.set_scale_vertically(cfg["scale_background"].to_bool(true)); } else { if(cfg.has_attribute("scale_background_vertically")) { bl.set_scale_vertically(cfg["scale_background_vertically"].to_bool(true)); } if(cfg.has_attribute("scale_background_horizontally")) { bl.set_scale_horizontally(cfg["scale_background_horizontally"].to_bool(true)); } } if(cfg.has_attribute("tile_background")) { bl.set_tile_horizontally(cfg["tile_background"].to_bool(false)); bl.set_tile_vertically(cfg["tile_background"].to_bool(false)); } else { if(cfg.has_attribute("tile_background_vertically")) { bl.set_tile_vertically(cfg["tile_background_vertically"].to_bool(false)); } if(cfg.has_attribute("tile_background_horizontally")) { bl.set_tile_vertically(cfg["tile_background_horizontally"].to_bool(false)); } } if(cfg.has_attribute("keep_aspect_ratio")) { bl.set_keep_aspect_ratio(cfg["keep_aspect_ratio"].to_bool(true)); } background_layers_.push_back(bl); if(cfg.has_attribute("show_title")) { show_title_ = cfg["show_title"].to_bool(); } if(cfg.has_attribute("story")) { text_ = cfg["story"].str(); } if(cfg.has_attribute("title")) { text_title_ = cfg["title"].str(); if(!cfg.has_attribute("show_title")) { show_title_ = true; } } if(cfg.has_attribute("text_layout")) { text_block_loc_ = string_tblock_loc(cfg["text_layout"]); } if(cfg.has_attribute("title_alignment")) { title_alignment_ = string_title_align(cfg["title_alignment"]); } if(cfg.has_attribute("music")) { music_ = cfg["music"].str(); } if(cfg.has_attribute("sound")) { sound_ = cfg["sound"].str(); } // Execution flow/branching/[image] for(vconfig::all_children_iterator i = cfg.ordered_begin(); i != cfg.ordered_end(); ++ i) { // i->first and i->second are goddamn temporaries; do not make references const std::string key = i->first; const vconfig node = i->second; // [background_layer] if (key == "background_layer") { background_layers_.push_back(node.get_parsed_config()); } // [image] else if(key == "image") { floating_images_.push_back(node.get_parsed_config()); } // [if] else if(key == "if") { // check if the [if] tag has a [then] child; // if we try to execute a non-existing [then], we get a segfault if (game_events::conditional_passed(node)) { if (node.has_child("then")) { resolve_wml(node.child("then")); } } // condition not passed, check [elseif] and [else] else { // get all [elseif] children and set a flag vconfig::child_list elseif_children = node.get_children("elseif"); bool elseif_flag = false; // for each [elseif]: test if it has a [then] child // if the condition matches, execute [then] and raise flag for (vconfig::child_list::const_iterator elseif = elseif_children.begin(); elseif != elseif_children.end(); ++elseif) { if (game_events::conditional_passed(*elseif)) { if (elseif->has_child("then")) { resolve_wml(elseif->child("then")); } elseif_flag = true; break; } } // if we have an [else] tag and no [elseif] was successful (flag not raised), execute it if (node.has_child("else") && !elseif_flag) { resolve_wml(node.child("else")); } } } // [switch] else if(key == "switch") { const std::string var_name = node["variable"]; const std::string var_actual_value = resources::gamedata->get_variable_const(var_name); bool case_not_found = true; for(vconfig::all_children_iterator j = node.ordered_begin(); j != node.ordered_end(); ++j) { if(j->first != "case") continue; // Enter all matching cases. const std::string var_expected_value = (j->second)["value"]; if(var_actual_value == var_expected_value) { case_not_found = false; resolve_wml(j->second); } } if(case_not_found) { for(vconfig::all_children_iterator j = node.ordered_begin(); j != node.ordered_end(); ++j) { if(j->first != "else") continue; // Enter all elses. resolve_wml(j->second); } } } // [deprecated_message] else if(key == "deprecated_message") { // Won't appear until the scenario start event finishes. lg::wml_error() << node["message"] << '\n'; } // [wml_message] else if(key == "wml_message") { // As with [deprecated_message], // it won't appear until the scenario start event is complete. resources::game_events->pump().put_wml_message(node["logger"],node["message"],node["in_chat"]); } } }
void part::resolve_wml(const vconfig &cfg) { if(cfg.null()) { return; } if(cfg.has_attribute("background")) { background_file_ = cfg["background"].str(); } if(cfg.has_attribute("scale_background")) { scale_background_ = cfg["scale_background"].to_bool(true); } if(cfg.has_attribute("show_title")) { show_title_ = cfg["show_title"].to_bool(); } if(cfg.has_attribute("story")) { text_ = cfg["story"].str(); } if(cfg.has_attribute("title")) { text_title_ = cfg["title"].str(); if(!cfg.has_attribute("show_title")) { show_title_ = true; } } if(cfg.has_attribute("text_layout")) { text_block_loc_ = string_tblock_loc(cfg["text_layout"]); } if(cfg.has_attribute("title_alignment")) { title_alignment_ = string_title_align(cfg["title_alignment"]); } if(cfg.has_attribute("music")) { music_ = cfg["music"].str(); } if(cfg.has_attribute("sound")) { sound_ = cfg["sound"].str(); } // Execution flow/branching/[image] for(vconfig::all_children_iterator i = cfg.ordered_begin(); i != cfg.ordered_end(); ++ i) { // i->first and i->second are goddamn temporaries; do not make references const std::string key = i->first; const vconfig node = i->second; // [image] if(key == "image") { floating_images_.push_back(node.get_parsed_config()); } // [if] else if(key == "if") { const std::string branch_label = game_events::conditional_passed(node) ? "then" : "else"; if(node.has_child(branch_label)) { const vconfig branch = node.child(branch_label); resolve_wml(branch); } } // [switch] else if(key == "switch") { const std::string var_name = node["variable"]; const std::string var_actual_value = resources::state_of_game->get_variable_const(var_name); bool case_not_found = true; for(vconfig::all_children_iterator j = node.ordered_begin(); j != node.ordered_end(); ++j) { if(j->first != "case") continue; // Enter all matching cases. const std::string var_expected_value = (j->second)["value"]; if(var_actual_value == var_expected_value) { case_not_found = false; resolve_wml(j->second); } } if(case_not_found) { for(vconfig::all_children_iterator j = node.ordered_begin(); j != node.ordered_end(); ++j) { if(j->first != "else") continue; // Enter all elses. resolve_wml(j->second); } } } // [deprecated_message] else if(key == "deprecated_message") { // Won't appear until the scenario start event finishes. game_events::handle_deprecated_message(node.get_parsed_config()); } // [wml_message] else if(key == "wml_message") { // Pass to game events handler. As with [deprecated_message], // it won't appear until the scenario start event is complete. game_events::handle_wml_log_message(node.get_parsed_config()); } } }
void controller::resolve_wml(const vconfig& cfg) { for(vconfig::all_children_iterator i = cfg.ordered_begin(); i != cfg.ordered_end(); ++i) { // i->first and i->second are goddamn temporaries; do not make references const std::string key = i->first; const vconfig node = i->second; if(key == "part" && !node.empty()) { part_pointer_type const story_part(new part(node)); // Use scenario name as part title if the WML doesn't supply a custom one. if((*story_part).show_title() && (*story_part).title().empty()) { (*story_part).set_title( scenario_name_ ); } parts_.push_back(story_part); } // [if] else if(key == "if") { // check if the [if] tag has a [then] child; // if we try to execute a non-existing [then], we get a segfault if (game_events::conditional_passed(node)) { if (node.has_child("then")) { resolve_wml(node.child("then")); } } // condition not passed, check [elseif] and [else] else { // get all [elseif] children and set a flag vconfig::child_list elseif_children = node.get_children("elseif"); bool elseif_flag = false; // for each [elseif]: test if it has a [then] child // if the condition matches, execute [then] and raise flag for (vconfig::child_list::const_iterator elseif = elseif_children.begin(); elseif != elseif_children.end(); ++elseif) { if (game_events::conditional_passed(*elseif)) { if (elseif->has_child("then")) { resolve_wml(elseif->child("then")); } elseif_flag = true; break; } } // if we have an [else] tag and no [elseif] was successful (flag not raised), execute it if (node.has_child("else") && !elseif_flag) { resolve_wml(node.child("else")); } } } // [switch] else if(key == "switch") { const std::string var_name = node["variable"]; const std::string var_actual_value = resources::gamedata->get_variable_const(var_name); bool case_not_found = true; for(vconfig::all_children_iterator j = node.ordered_begin(); j != node.ordered_end(); ++j) { if(j->first != "case") continue; // Enter all matching cases. const std::string var_expected_value = (j->second)["value"]; if(var_actual_value == var_expected_value) { case_not_found = false; resolve_wml(j->second); } } if(case_not_found) { for(vconfig::all_children_iterator j = node.ordered_begin(); j != node.ordered_end(); ++j) { if(j->first != "else") continue; // Enter all elses. resolve_wml(j->second); } } } // [deprecated_message] else if(key == "deprecated_message") { // Won't appear until the scenario start event finishes. game_events::handle_deprecated_message(node.get_parsed_config()); } // [wml_message] else if(key == "wml_message") { // Pass to game events handler. As with [deprecated_message], // it won't appear until the scenario start event is complete. game_events::handle_wml_log_message(node.get_parsed_config()); } } }