Several more tweaks/fixes
- Missing special node opcodes - Pass the party's (or in combat, the active character's) current location to special nodes triggered by timers - Fix the set pointer node - Fix terrain palette not correctly registering clicks while scrolled down - Fix sheets not correctly being copied from the temporary files folder - Fix monster abilities not being loaded from new scenarios - Fix custom sheets not being reloaded if they have changed - Documentation tweaks
This commit is contained in:
@@ -211,7 +211,11 @@ flag. Put the two parts of the required stuff done flag in these two text areas.
|
||||
<p><b>Message 1-3, Pict, Pict type -</b> Some special nodes display a piece of text on the
|
||||
screen. Other special nodes display a dialog box, with text in the middle and a picture in
|
||||
the upper left corner. The numbers for these messages and the number of the picture to
|
||||
display can be put in these text fields.</p>
|
||||
display can be put in these text fields. When attaching a simple text message (two
|
||||
strings) to some other type of node, keep in mind that the text will display <i>after</i>
|
||||
the main action of the node. For example, a Missile Animation node with attached text
|
||||
messages will show the missile, then display the text. Similarly, a Pause special node will
|
||||
display the text after the delay is complete.</p>
|
||||
<p>Each picture and each text message has a number associated with it (for example, every
|
||||
town has 100 text messages, numbered from 0 to 99). Most of the time, you really dont want
|
||||
to have to worry about these. Fortunately, there is an easier way to deal with this. Press
|
||||
|
@@ -1689,7 +1689,8 @@ both in town and outdoors, but the first few only work in town. For these nodes,
|
||||
values have slightly different meanings than before:</p>
|
||||
<dt>Extra 1a, Extra 1b, Extra 2a, Extra 2b:</dt><dd>For each of these specials, Extra 1a
|
||||
and Extra 1b are the top and left of the rectangle. Extra 2a and Extra 2b are the bottom
|
||||
and right of the rectangle.
|
||||
and right of the rectangle. Note that this is the reverse of standard coordinate order -
|
||||
Y coordinate first, then X coordinate.
|
||||
<p>The default values of Extra 2a and Extra 2b are -1. If you want the effect to only
|
||||
apply to one space (and not a whole rectangle), leave Extra 2a and Extra 2b at -1. In this
|
||||
case, the node only affects the space specified by Extra 1a and Extra 1b.</dd>
|
||||
|
@@ -88,13 +88,13 @@ status
|
||||
traits
|
||||
ap
|
||||
name
|
||||
level
|
||||
morale
|
||||
soul-crystal
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
monst-attack
|
||||
monst-statistic
|
||||
statistic
|
||||
spell-mage
|
||||
spell-priest
|
||||
|
@@ -1789,11 +1789,20 @@ void special_increase_age(long length, bool queue) {
|
||||
unsigned short i;
|
||||
short s1,s2,s3;
|
||||
bool redraw = false,stat_area = false;
|
||||
location null_loc; // TODO: Should we pass the party's location here? It doesn't quite make sense to me though...
|
||||
location trigger_loc;
|
||||
unsigned long age_before = univ.party.age - length;
|
||||
unsigned long current_age = univ.party.age;
|
||||
bool failed_job = false;
|
||||
|
||||
if(is_combat()) {
|
||||
extern short combat_active_pc;
|
||||
trigger_loc = univ.party[combat_active_pc].combat_pos;
|
||||
} else if(is_town()) {
|
||||
trigger_loc = univ.town.p_loc;
|
||||
} else if(is_out()) {
|
||||
trigger_loc = univ.party.p_loc;
|
||||
}
|
||||
|
||||
for(auto& p : univ.party.quest_status) {
|
||||
if(p.second != eQuestStatus::STARTED)
|
||||
continue;
|
||||
@@ -1844,8 +1853,8 @@ void special_increase_age(long length, bool queue) {
|
||||
if(j % time == 0) {
|
||||
if(queue) {
|
||||
univ.party.age = j;
|
||||
queue_special(eSpecCtx::TOWN_TIMER, 2, univ.town->timers[i].node, null_loc);
|
||||
} else run_special(eSpecCtx::TOWN_TIMER,2,univ.town->timers[i].node,null_loc,&s1,&s2,&s3);
|
||||
queue_special(eSpecCtx::TOWN_TIMER, 2, univ.town->timers[i].node, trigger_loc);
|
||||
} else run_special(eSpecCtx::TOWN_TIMER,2,univ.town->timers[i].node,trigger_loc,&s1,&s2,&s3);
|
||||
}
|
||||
stat_area = true;
|
||||
if(s3 > 0)
|
||||
@@ -1860,8 +1869,8 @@ void special_increase_age(long length, bool queue) {
|
||||
if(j % time == 0) {
|
||||
if(queue) {
|
||||
univ.party.age = j;
|
||||
queue_special(eSpecCtx::SCEN_TIMER, 0, univ.scenario.scenario_timers[i].node, null_loc);
|
||||
} else run_special(eSpecCtx::SCEN_TIMER,0,univ.scenario.scenario_timers[i].node,null_loc,&s1,&s2,&s3);
|
||||
queue_special(eSpecCtx::SCEN_TIMER, 0, univ.scenario.scenario_timers[i].node, trigger_loc);
|
||||
} else run_special(eSpecCtx::SCEN_TIMER,0,univ.scenario.scenario_timers[i].node,trigger_loc,&s1,&s2,&s3);
|
||||
}
|
||||
stat_area = true;
|
||||
if(s3 > 0)
|
||||
@@ -1873,8 +1882,8 @@ void special_increase_age(long length, bool queue) {
|
||||
univ.party.age = age_before + univ.party.party_event_timers[i].time;
|
||||
short which_type = univ.party.party_event_timers[i].node_type;
|
||||
if(queue)
|
||||
queue_special(eSpecCtx::PARTY_TIMER, which_type, univ.party.party_event_timers[i].node, null_loc);
|
||||
else run_special(eSpecCtx::PARTY_TIMER,which_type,univ.party.party_event_timers[i].node,null_loc,&s1,&s2,&s3);
|
||||
queue_special(eSpecCtx::PARTY_TIMER, which_type, univ.party.party_event_timers[i].node, trigger_loc);
|
||||
else run_special(eSpecCtx::PARTY_TIMER,which_type,univ.party.party_event_timers[i].node,trigger_loc,&s1,&s2,&s3);
|
||||
univ.party.party_event_timers[i].time = 0;
|
||||
univ.party.party_event_timers[i].node = -1;
|
||||
stat_area = true;
|
||||
@@ -2248,7 +2257,7 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
else try {
|
||||
if(spec.sd1 < 0 && spec.sd2 < 0)
|
||||
univ.party.clear_ptr(spec.ex1a);
|
||||
else univ.party.set_ptr(spec.sd1,spec.sd2,spec.ex1a);
|
||||
else univ.party.set_ptr(spec.ex1a,spec.sd1,spec.sd2);
|
||||
} catch(std::range_error x) {
|
||||
giveError(x.what());
|
||||
}
|
||||
|
@@ -996,7 +996,7 @@ bool handle_action(location the_point,sf::Event /*event*/) {
|
||||
if(overall_mode < MODE_MAIN_SCREEN) {
|
||||
switch(draw_mode) {
|
||||
case DRAW_TERRAIN:
|
||||
set_new_terrain(i);
|
||||
set_new_terrain(pal_sbar->getPosition() * 16 + i);
|
||||
break;
|
||||
case DRAW_ITEM:
|
||||
if(scenario.scen_items[mode_count].variety == eItemType::NO_ITEM) {
|
||||
@@ -1004,12 +1004,12 @@ bool handle_action(location the_point,sf::Event /*event*/) {
|
||||
break;
|
||||
}
|
||||
overall_mode = MODE_PLACE_ITEM;
|
||||
mode_count = i;
|
||||
mode_count = pal_sbar->getPosition() * 16 + i;
|
||||
set_string("Place the item:",scenario.scen_items[mode_count].full_name.c_str());
|
||||
break;
|
||||
case DRAW_MONST:
|
||||
overall_mode = MODE_PLACE_CREATURE;
|
||||
mode_count = i + 1;
|
||||
mode_count = pal_sbar->getPosition() * 16 + i + 1;
|
||||
set_string("Place the monster:",scenario.scen_monsters[mode_count].m_name.c_str());
|
||||
break;
|
||||
}
|
||||
|
@@ -1003,25 +1003,26 @@ void save_scenario(fs::path toFile) {
|
||||
pic_out << fin.rdbuf();
|
||||
fin.close();
|
||||
}
|
||||
} else if(spec_scen_g) {
|
||||
} else {
|
||||
fs::path picPath = tempDir/"scenario"/"graphics";
|
||||
if(fs::exists(picPath) && fs::is_directory(picPath)) {
|
||||
// First build a list of overridable sheets
|
||||
std::set<std::string> sheet_names;
|
||||
fs::directory_iterator sheet_iter(progDir/"Scenario Editor"/"graphics.exd"/"mac");
|
||||
while(sheet_iter != fs::directory_iterator()) {
|
||||
for(; sheet_iter != fs::directory_iterator(); sheet_iter++) {
|
||||
std::string fname = sheet_iter->path().filename().string();
|
||||
size_t dot = fname.find_last_of('.');
|
||||
if(dot == std::string::npos) continue;
|
||||
if(fname.substr(dot) == ".png")
|
||||
sheet_names.insert(fname);
|
||||
sheet_iter++;
|
||||
}
|
||||
fs::directory_iterator dir_iter(picPath);
|
||||
while(dir_iter != fs::directory_iterator()) {
|
||||
for(; dir_iter != fs::directory_iterator(); dir_iter++) {
|
||||
std::string fname = dir_iter->path().filename().string();
|
||||
bool is_sheet = false;
|
||||
if(fname.substr(0,5) == "sheet") {
|
||||
size_t dot = fname.find_last_of('.');
|
||||
if(dot == std::string::npos) continue;
|
||||
if(fname.substr(dot) == ".png" && std::all_of(fname.begin() + 5, fname.begin() + dot, isdigit)) {
|
||||
// Looks like a valid sheet!
|
||||
is_sheet = true;
|
||||
@@ -1036,7 +1037,6 @@ void save_scenario(fs::path toFile) {
|
||||
pic_out << fin.rdbuf();
|
||||
fin.close();
|
||||
}
|
||||
dir_iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1049,6 +1049,7 @@ static void readMonstAbilFromXml(ticpp::Element& data, cMonster& monst) {
|
||||
if(abil_type == eMonstAbil::NO_ABIL)
|
||||
throw xMissingAttr(type, "type", data.Row(), data.Column(), fname);
|
||||
uAbility& abil = monst.abil[abil_type];
|
||||
abil.active = true;
|
||||
Iterator<Element> elem;
|
||||
if(type == "general") {
|
||||
auto& general = abil.gen;
|
||||
@@ -2134,6 +2135,7 @@ void load_spec_graphics_v2(int num_sheets) {
|
||||
}
|
||||
while(num_sheets-- > 0) {
|
||||
std::string name = "sheet" + std::to_string(num_sheets);
|
||||
ResMgr::free<ImageRsrc>(name);
|
||||
spec_scen_g.sheets[num_sheets].loadFromImage(*ResMgr::get<ImageRsrc>(name));
|
||||
}
|
||||
reload_core_graphics();
|
||||
|
Reference in New Issue
Block a user