implement if monsters alive node
This commit is contained in:
@@ -158,7 +158,7 @@ if-num-response
|
||||
if-boat
|
||||
if-horse
|
||||
if-quest
|
||||
|
||||
if-monsters-alive
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -304,18 +304,7 @@ void make_town_hostile() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set Attitude node adapted from *i, meant to replace make_town_hostile node
|
||||
void set_town_attitude(short lo,short hi,eAttitude att) {
|
||||
short num;
|
||||
|
||||
if(is_combat() && which_combat_type == 0)
|
||||
return;
|
||||
|
||||
give_help(53,0);
|
||||
|
||||
static std::set<eAttitude> hostile_attitudes = { eAttitude::HOSTILE_A, eAttitude::HOSTILE_B };
|
||||
univ.town.monst.hostile = hostile_attitudes.count(att);
|
||||
|
||||
void foreach_townperson(short lo, short hi, std::function<void(cCreature&)> func) {
|
||||
long long num_monst = univ.town.monst.size();
|
||||
|
||||
// Nice smart indexing, like Python :D
|
||||
@@ -332,22 +321,39 @@ void set_town_attitude(short lo,short hi,eAttitude att) {
|
||||
|
||||
for(short i = lo; i <= hi; i++) {
|
||||
if(univ.town.monst[i].is_alive() && univ.town.monst[i].summon_time == 0){
|
||||
univ.town.monst[i].attitude = att;
|
||||
num = univ.town.monst[i].number;
|
||||
// If made hostile, make mobile
|
||||
if(!univ.town.monst[i].is_friendly()) {
|
||||
univ.town.monst[i].mobility = 1;
|
||||
// If a "guard", give a power boost
|
||||
if(univ.scenario.scen_monsters[num].guard) {
|
||||
univ.town.monst[i].active = eCreatureStatus::ALERTED;
|
||||
univ.town.monst[i].health *= 3;
|
||||
univ.town.monst[i].status[eStatus::HASTE_SLOW] = 8;
|
||||
univ.town.monst[i].status[eStatus::BLESS_CURSE] = 8;
|
||||
}
|
||||
|
||||
}
|
||||
func(univ.town.monst[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set Attitude node adapted from *i, meant to replace make_town_hostile node
|
||||
void set_town_attitude(short lo,short hi,eAttitude att) {
|
||||
|
||||
if(is_combat() && which_combat_type == 0)
|
||||
return;
|
||||
|
||||
// TODO this message would happen even if a node were making hostile monsters friendly or modifying a small range,
|
||||
// or if it's a dungeon, not a friendly town
|
||||
give_help(53,0);
|
||||
|
||||
static std::set<eAttitude> hostile_attitudes = { eAttitude::HOSTILE_A, eAttitude::HOSTILE_B };
|
||||
univ.town.monst.hostile = hostile_attitudes.count(att);
|
||||
|
||||
foreach_townperson(lo, hi, [att](cCreature& creature) -> void {
|
||||
creature.attitude = att;
|
||||
short num = creature.number;
|
||||
// If made hostile, make mobile
|
||||
if(!creature.is_friendly()) {
|
||||
creature.mobility = 1;
|
||||
// If a "guard", give a power boost
|
||||
if(univ.scenario.scen_monsters[num].guard) {
|
||||
creature.active = eCreatureStatus::ALERTED;
|
||||
creature.health *= 3;
|
||||
creature.status[eStatus::HASTE_SLOW] = 8;
|
||||
creature.status[eStatus::BLESS_CURSE] = 8;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// In some towns, doin' this'll getcha' killed.
|
||||
// (Or something else! Killing the party would be the responsibility of whatever special node is called.)
|
||||
|
||||
@@ -20,6 +20,7 @@ short dist_from_party(location where);
|
||||
void set_item_flag(cItem *item);
|
||||
short get_item(location place,short pc_num,bool check_container);
|
||||
|
||||
void foreach_townperson(short lo, short hi, std::function<void(cCreature&)> func);
|
||||
void make_town_hostile();
|
||||
void set_town_attitude(short lo,short hi,eAttitude att);
|
||||
bool show_get_items(std::string titleText, std::vector<cItem*>& itemRefs, short pc_getting, bool overload = false);
|
||||
|
||||
@@ -3805,6 +3805,41 @@ void ifthen_spec(const runtime_state& ctx) {
|
||||
if(univ.party.in_horse >= 0 && (spec.ex1b < 0 || spec.ex1b == univ.party.in_horse))
|
||||
ctx.next_spec = spec.ex1c;
|
||||
break;
|
||||
case eSpecType::IF_MONSTERS_ALIVE:{
|
||||
if(univ.party.town_num == 200){
|
||||
showError("This node can only run in town!");
|
||||
ctx.next_spec = -1;
|
||||
break;
|
||||
}
|
||||
if(spec.ex1c < -3 || spec.ex1c > 3){
|
||||
showError("Invalid attitude (0-Friendly Docile, 1-Hostile A, 2-Friendly Will Fight, 3-Hostile B).");
|
||||
break;
|
||||
}
|
||||
int min = spec.ex2a;
|
||||
int count = 0;
|
||||
foreach_townperson(spec.ex1a, spec.ex1b, [&count, spec](cCreature& creature) -> void {
|
||||
std::map<eAttitude, int> att_counts;
|
||||
// I know there must be many better ways of doing this...
|
||||
if(spec.ex1c == 0 || spec.ex1c == -2 || spec.ex1c == -3){
|
||||
att_counts[eAttitude::DOCILE] = 1;
|
||||
}
|
||||
if(spec.ex1c == 1 || spec.ex1c == -1 || spec.ex1c == -3){
|
||||
att_counts[eAttitude::HOSTILE_A] = 1;
|
||||
}
|
||||
if(spec.ex1c == 2 || spec.ex1c == -2 || spec.ex1c == -3){
|
||||
att_counts[eAttitude::FRIENDLY] = 1;
|
||||
}
|
||||
if(spec.ex1c == 3 || spec.ex1c == -1 || spec.ex1c == -3){
|
||||
att_counts[eAttitude::HOSTILE_B] = 1;
|
||||
}
|
||||
count += att_counts[creature.attitude];
|
||||
});
|
||||
if(count >= min){
|
||||
ctx.next_spec = spec.ex2b;
|
||||
}else{
|
||||
ctx.next_spec = spec.jumpto;
|
||||
}
|
||||
}break;
|
||||
default:
|
||||
showError(fmt::format("Special node type \"{}\" is either miscategorized or unimplemented!", (*cur_node.type).name()));
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user