Introduce enum for monster time flags

- Also, this probably fixes the issues with certain time flags (particularly the "sometimes ones) not working correctly
This commit is contained in:
2015-01-22 20:22:36 -05:00
parent aa705fac13
commit 34ee2b2c29
6 changed files with 141 additions and 56 deletions

View File

@@ -205,43 +205,41 @@ void start_town_mode(short which_town, short entry_dir) {
// These should have protected status (i.e. spec1 >= 200, spec1 <= 204)
for(j = 0; j < univ.town->max_monst(); j++) {
switch(univ.town.monst[j].time_flag){
case 4: case 5 : //case 6:
if((((short) (univ.party.age / 1000) % 3) + 4) != univ.town.monst[j].time_flag)
case eMonstTime::SOMETIMES_A: case eMonstTime::SOMETIMES_B: case eMonstTime::SOMETIMES_C:
if((calc_day() % 3) + 3 != int(univ.town.monst[i].time_flag))
univ.town.monst[j].active = 0;
else {
univ.town.monst[j].active = 1;
univ.town.monst[j].spec_enc_code = 0;
// Now remove time flag so it doesn't get reappearing
univ.town.monst[j].time_flag = 0;
univ.town.monst[j].cur_loc = univ.town->creatures(j).start_loc;
univ.town.monst[j].health = univ.town.monst[j].m_health;
}
break ;
// Now, appearing/disappearing monsters might have arrived/disappeared.
case 1:
case eMonstTime::APPEAR_ON_DAY:
if(day_reached(univ.town.monst[j].monster_time, univ.town.monst[j].time_code)) {
univ.town.monst[j].active = 1;
univ.town.monst[j].time_flag=0; // Now remove time flag so it doesn't get reappearing
univ.town.monst[j].time_flag = eMonstTime::ALWAYS;
}
break;
case 2:
case eMonstTime::DISAPPEAR_ON_DAY:
if(day_reached(univ.town.monst[j].monster_time, univ.town.monst[j].time_code)) {
univ.town.monst[j].active = 0;
univ.town.monst[j].time_flag=0; // Now remove time flag so it doesn't get disappearing again
univ.town.monst[j].time_flag = eMonstTime::ALWAYS;
}
break;
case 7:
case eMonstTime::APPEAR_WHEN_EVENT:
if(calc_day() >= univ.party.key_times[univ.town.monst[j].time_code]){ //calc_day is used because of the "definition" of univ.party.key_times
univ.town.monst[j].active = 1;
univ.town.monst[j].time_flag=0; // Now remove time flag so it doesn't get reappearing
univ.town.monst[j].time_flag = eMonstTime::ALWAYS;
}
break;
case 8:
case eMonstTime::DISAPPEAR_WHEN_EVENT:
if(calc_day() >= univ.party.key_times[univ.town.monst[j].time_code]){
univ.town.monst[j].active = 0;
univ.town.monst[j].time_flag=0; // Now remove time flag so it doesn't get disappearing again
univ.town.monst[j].time_flag = eMonstTime::ALWAYS;
}
break;
}
@@ -261,7 +259,7 @@ void start_town_mode(short which_town, short entry_dir) {
if(univ.town->creatures(i).number == 0) {
univ.town.monst[i].active = 0;
univ.town.monst[i].number = 0;
univ.town.monst[i].time_flag = 0;
univ.town.monst[i].time_flag = eMonstTime::ALWAYS;
univ.town.monst[i].cur_loc.x = 80;
}
else {
@@ -274,50 +272,40 @@ void start_town_mode(short which_town, short entry_dir) {
// Now, if necessary, fry the monster.
switch(univ.town.monst[i].time_flag) {
case 1:
case eMonstTime::APPEAR_ON_DAY:
if(!day_reached(univ.town.monst[i].monster_time, univ.town.monst[i].time_code))
univ.town.monst[i].active = 0;
break;
case 2:
case eMonstTime::DISAPPEAR_ON_DAY:
if(day_reached(univ.town.monst[i].monster_time, univ.town.monst[i].time_code))
univ.town.monst[i].active = 0;
break;
case 3:
// unused
break;
case 4: case 5: case 6:
if((((short) (univ.party.age / 1000) % 3) + 4) != univ.town.monst[i].time_flag) {
case eMonstTime::SOMETIMES_A: case eMonstTime::SOMETIMES_B: case eMonstTime::SOMETIMES_C:
if((calc_day() % 3) + 3 != int(univ.town.monst[i].time_flag)) {
univ.town.monst[i].active = 0;
univ.town.monst[i].spec_enc_code = 50;
}
else {
univ.town.monst[i].active = 1;
// Now remove time flag so it doesn't keep reappearing
univ.town.monst[i].time_flag = 0;
}
break;
case 7:
case eMonstTime::APPEAR_WHEN_EVENT:
if(calc_day() < univ.party.key_times[univ.town.monst[i].time_code])
univ.town.monst[i].active = 0;
break;
case 8:
case eMonstTime::DISAPPEAR_WHEN_EVENT:
if(calc_day() >= univ.party.key_times[univ.town.monst[i].time_code])
univ.town.monst[i].active = 0;
break;
case 9:
if(univ.town->town_chop_time > 0)
if(day_reached(univ.town->town_chop_time,univ.town->town_chop_key)) {
univ.town.monst[i].active += 10;
break;
}
univ.town.monst[i].active = 0;
case eMonstTime::APPEAR_AFTER_CHOP:
// TODO: Should these two cases be separated?
if(univ.town->town_chop_time > 0 && day_reached(univ.town->town_chop_time,univ.town->town_chop_key))
univ.town.monst[i].active += 10;
else if(univ.party.m_killed[univ.town.num] > univ.town->max_num_monst)
univ.town.monst[i].active += 10;
else univ.town.monst[i].active = 0;
break;
case 0:
break;
default:
ASB("ERROR! Odd character data.");
print_nums(0,i,univ.town.monst[i].time_flag);
case eMonstTime::ALWAYS:
break;
}
}

View File

@@ -387,7 +387,8 @@ cCreature::cCreature(){
id = number = active = attitude = start_attitude = 0;
start_loc.x = start_loc.y = cur_loc.x = cur_loc.y = targ_loc.x = targ_loc.y = 80;
mobility = 1;
time_flag = summoned = 0;
summoned = 0;
time_flag = eMonstTime::ALWAYS;
spec1 = spec2 = spec_enc_code = time_code = monster_time = 0;
personality = special_on_kill = facial_pic = -1;
target = 6;
@@ -403,7 +404,16 @@ void cCreature::append(legacy::creature_start_type old){
start_loc.x = old.start_loc.x;
start_loc.y = old.start_loc.y;
mobility = old.mobile;
time_flag = old.time_flag;
switch(old.time_flag) {
case 0: time_flag = eMonstTime::ALWAYS; break;
case 1: time_flag = eMonstTime::APPEAR_ON_DAY; break;
case 2: time_flag = eMonstTime::DISAPPEAR_ON_DAY; break;
case 4: time_flag = eMonstTime::SOMETIMES_A; break;
case 5: time_flag = eMonstTime::SOMETIMES_B; break;
case 6: time_flag = eMonstTime::SOMETIMES_C; break;
case 7: time_flag = eMonstTime::APPEAR_WHEN_EVENT; break;
case 8: time_flag = eMonstTime::DISAPPEAR_WHEN_EVENT; break;
}
spec1 = old.spec1;
spec2 = old.spec2;
spec_enc_code = old.spec_enc_code;
@@ -428,7 +438,16 @@ void cCreature::append(legacy::creature_data_type old){
start_loc.x = old.monst_start.start_loc.x;
start_loc.y = old.monst_start.start_loc.y;
mobility = old.monst_start.mobile;
time_flag = old.monst_start.time_flag;
switch(old.monst_start.time_flag) {
case 0: time_flag = eMonstTime::ALWAYS; break;
case 1: time_flag = eMonstTime::APPEAR_ON_DAY; break;
case 2: time_flag = eMonstTime::DISAPPEAR_ON_DAY; break;
case 4: time_flag = eMonstTime::SOMETIMES_A; break;
case 5: time_flag = eMonstTime::SOMETIMES_B; break;
case 6: time_flag = eMonstTime::SOMETIMES_C; break;
case 7: time_flag = eMonstTime::APPEAR_WHEN_EVENT; break;
case 8: time_flag = eMonstTime::DISAPPEAR_WHEN_EVENT; break;
}
spec1 = old.monst_start.spec1;
spec2 = old.monst_start.spec2;
spec_enc_code = old.monst_start.spec_enc_code;
@@ -547,6 +566,54 @@ std::istream& operator >> (std::istream& in, eRace& e){
return in;
}
std::ostream& operator << (std::ostream& out, eMonstTime e){
switch(e) {
case eMonstTime::ALWAYS: out << "always"; break;
case eMonstTime::APPEAR_ON_DAY: out << "after-day"; break;
case eMonstTime::DISAPPEAR_ON_DAY: out << "until-day"; break;
case eMonstTime::SOMETIMES_A: out << "travel-a"; break;
case eMonstTime::SOMETIMES_B: out << "travel-b"; break;
case eMonstTime::SOMETIMES_C: out << "travel-c"; break;
case eMonstTime::APPEAR_WHEN_EVENT: out << "after-event"; break;
case eMonstTime::DISAPPEAR_WHEN_EVENT: out << "until-event"; break;
case eMonstTime::APPEAR_AFTER_CHOP: out << "after-death"; break;
}
return out;
}
std::istream& operator >> (std::istream& in, eMonstTime& e){
std::string key;
in >> key;
e = eMonstTime::ALWAYS;
try {
int i = boost::lexical_cast<int>(key);
if(i >= 0 && i != 3 && i < 6)
e = eMonstTime(i);
else if(i > 6 && i <= 8)
e = eMonstTime(i - 1);
} catch(boost::bad_lexical_cast) {
if(key == "always")
e = eMonstTime::ALWAYS;
else if(key == "after-day")
e = eMonstTime::APPEAR_ON_DAY;
else if(key == "until-day")
e = eMonstTime::DISAPPEAR_ON_DAY;
else if(key == "travel-a")
e = eMonstTime::SOMETIMES_A;
else if(key == "travel-b")
e = eMonstTime::SOMETIMES_B;
else if(key == "travel-c")
e = eMonstTime::SOMETIMES_C;
else if(key == "after-event")
e = eMonstTime::APPEAR_WHEN_EVENT;
else if(key == "until-event")
e = eMonstTime::DISAPPEAR_WHEN_EVENT;
else if(key == "after-death")
e = eMonstTime::APPEAR_AFTER_CHOP;
}
return in;
}
std::ostream& operator << (std::ostream& out, eDirection e) {
return out << (int)e;
}
@@ -1009,7 +1076,7 @@ void cCreature::writeTo(std::ostream& file) const {
file << "STARTLOC " << start_loc.x << ' ' << start_loc.y << '\n';
file << "LOCATION " << cur_loc.x << ' ' << cur_loc.y << '\n';
file << "MOBILITY " << unsigned(mobility) << '\n';
file << "TIMEFLAG " << unsigned(time_flag) << '\n';
file << "TIMEFLAG " << time_flag << '\n';
file << "SUMMONED " << summoned << '\n';
file << "SPEC " << spec1 << ' ' << spec2 << '\n';
file << "SPECCODE " << int(spec_enc_code) << '\n';
@@ -1054,9 +1121,7 @@ void cCreature::readFrom(std::istream& file) {
line >> i;
mobility = i;
} else if(cur == "TIMEFLAG") {
unsigned int i;
line >> i;
time_flag = i;
line >> time_flag;
} else if(cur == "SUMMONED")
line >> summoned;
else if(cur == "SPEC")

View File

@@ -155,6 +155,14 @@ public:
void readFrom(std::istream& file);
};
enum class eMonstTime {
ALWAYS,
APPEAR_ON_DAY, DISAPPEAR_ON_DAY,
SOMETIMES_C, SOMETIMES_A, SOMETIMES_B,
APPEAR_WHEN_EVENT, DISAPPEAR_WHEN_EVENT,
APPEAR_AFTER_CHOP,
};
class cCreature : public cMonster {
public:
unsigned long id;
@@ -163,7 +171,7 @@ public:
unsigned char start_attitude;
location start_loc, cur_loc;
unsigned short mobility;
unsigned char time_flag;
eMonstTime time_flag;
short summoned;
short spec1, spec2;
char spec_enc_code, time_code;
@@ -209,5 +217,7 @@ std::ostream& operator << (std::ostream& out, eDamageType e);
std::istream& operator >> (std::istream& in, eDamageType& e);
std::ostream& operator << (std::ostream& out, eFieldType e);
std::istream& operator >> (std::istream& in, eFieldType& e);
std::ostream& operator << (std::ostream& out, eMonstTime e);
std::istream& operator >> (std::istream& in, eMonstTime& e);
std::ostream& operator<<(std::ostream& out, const cMonster::cAttack& att);
#endif

View File

@@ -606,7 +606,7 @@ bool handle_action(location the_point,sf::Event /*event*/) {
town->creatures(i).start_attitude =
scenario.scen_monsters[mode_count].default_attitude;
town->creatures(i).mobility = 1;
town->creatures(i).time_flag = 0;
town->creatures(i).time_flag = eMonstTime::ALWAYS;
town->creatures(i).spec1 = -1;
town->creatures(i).spec2 = -1;
town->creatures(i).spec_enc_code = 0;

View File

@@ -114,9 +114,21 @@ static void put_placed_monst_adv_in_dlog(cDialog& me) {
me["num"].setTextToNum(store_which_placed_monst);
me["type"].setText(scenario.scen_monsters[store_placed_monst2.number].m_name);
dynamic_cast<cLedGroup&>(me["time"]).setSelected("time" + std::to_string(store_placed_monst2.time_flag + 1));
me["extra1-lbl"].setText(day_str_1[store_placed_monst2.time_flag]);
me["extra2-lbl"].setText(day_str_2[store_placed_monst2.time_flag]);
int iTime = 0;
switch(store_placed_monst2.time_flag) {
case eMonstTime::ALWAYS: iTime = 0; break;
case eMonstTime::APPEAR_ON_DAY: iTime = 1; break;
case eMonstTime::DISAPPEAR_ON_DAY: iTime = 2; break;
case eMonstTime::SOMETIMES_A: iTime = 3; break;
case eMonstTime::SOMETIMES_B: iTime = 4; break;
case eMonstTime::SOMETIMES_C: iTime = 5; break;
case eMonstTime::APPEAR_WHEN_EVENT: iTime = 6; break;
case eMonstTime::DISAPPEAR_WHEN_EVENT: iTime = 7; break;
case eMonstTime::APPEAR_AFTER_CHOP: iTime = 8; break;
}
dynamic_cast<cLedGroup&>(me["time"]).setSelected("time" + std::to_string(iTime + 1));
me["extra1-lbl"].setText(day_str_1[iTime]);
me["extra2-lbl"].setText(day_str_2[iTime]);
me["extra1"].setTextToNum(store_placed_monst2.monster_time);
me["extra2"].setTextToNum(store_placed_monst2.time_code);
// TODO: Why on earth is this an LED group? Just use a text field!
@@ -127,7 +139,17 @@ static void put_placed_monst_adv_in_dlog(cDialog& me) {
}
static bool get_placed_monst_adv_in_dlog(cDialog& me) {
store_placed_monst2.time_flag = dynamic_cast<cLedGroup&>(me["time"]).getSelected()[4] - '1';
switch(dynamic_cast<cLedGroup&>(me["time"]).getSelected()[4] - '1') {
case 0: store_placed_monst2.time_flag = eMonstTime::ALWAYS; break;
case 1: store_placed_monst2.time_flag = eMonstTime::APPEAR_ON_DAY; break;
case 2: store_placed_monst2.time_flag = eMonstTime::DISAPPEAR_ON_DAY; break;
case 3: store_placed_monst2.time_flag = eMonstTime::SOMETIMES_A; break;
case 4: store_placed_monst2.time_flag = eMonstTime::SOMETIMES_B; break;
case 5: store_placed_monst2.time_flag = eMonstTime::SOMETIMES_C; break;
case 6: store_placed_monst2.time_flag = eMonstTime::APPEAR_WHEN_EVENT; break;
case 7: store_placed_monst2.time_flag = eMonstTime::DISAPPEAR_WHEN_EVENT; break;
case 8: store_placed_monst2.time_flag = eMonstTime::APPEAR_AFTER_CHOP; break;
}
store_placed_monst2.monster_time = me["extra1"].getTextAsNum();
if(cre(store_placed_monst2.monster_time,0,1000,"Given day must be from 0 to 1000.","",&me)) return false;
store_placed_monst2.time_code = me["extra2"].getTextAsNum();