resurrection spells hide invalid targets & hide res spells when all alive
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <limits>
|
||||
#include <boost/optional.hpp>
|
||||
#include <set>
|
||||
|
||||
enum class eDamageType {
|
||||
WEAPON = 0,
|
||||
@@ -92,6 +93,8 @@ enum class eMainStatus {
|
||||
SPLIT_WON = SPLIT + WON,
|
||||
};
|
||||
|
||||
const std::set<eMainStatus> dead_statuses = { eMainStatus::DEAD, eMainStatus::STONE, eMainStatus::DUST };
|
||||
|
||||
inline eMainStatus exceptSplit(eMainStatus stat) {
|
||||
if(int(stat) >= 10)
|
||||
return (eMainStatus) (-10 + (int)stat);
|
||||
|
@@ -1002,6 +1002,12 @@ short select_pc(eSelectPC mode, std::string title, eSkill highlight_highest, boo
|
||||
extra_info = "";
|
||||
}
|
||||
break;
|
||||
case eSelectPC::ONLY_STONE:
|
||||
if(univ.party[i].main_status != eMainStatus::STONE){
|
||||
can_pick = false;
|
||||
extra_info = "";
|
||||
}
|
||||
break;
|
||||
case eSelectPC::ONLY_DEAD:
|
||||
if(univ.party[i].main_status == eMainStatus::ALIVE){
|
||||
can_pick = false;
|
||||
|
@@ -55,6 +55,7 @@ enum class eSelectPC {
|
||||
// Must have skill points
|
||||
ONLY_CAN_TRAIN,
|
||||
ONLY_DEAD,
|
||||
ONLY_STONE,
|
||||
};
|
||||
// Prompt the player to choose a party member. Returns 0-5 for a pc, 6 for cancel, 7 for all, or 8 if no PCs fit the mode's filter.
|
||||
// Pass a string poiner to no_choice_reason to get the reason why no choices were available, if none are.
|
||||
|
@@ -1598,6 +1598,20 @@ bool pc_can_cast_spell(const cPlayer& pc,eSpell spell_num) {
|
||||
eSkill type = (*spell_num).type;
|
||||
cSpell spell = *spell_num;
|
||||
|
||||
if(spell.need_select == eSpellSelect::SELECT_DEAD){
|
||||
bool any_dead = false;
|
||||
for(int i = 0; i < 6; ++i){
|
||||
if(dead_statuses.count(univ.party[i].main_status)) any_dead = true;
|
||||
}
|
||||
if(!any_dead) return false;
|
||||
}else if(spell.need_select == eSpellSelect::SELECT_STONE){
|
||||
bool any_stone = false;
|
||||
for(int i = 0; i < 6; ++i){
|
||||
if(univ.party[i].main_status == eMainStatus::STONE) any_stone = true;
|
||||
}
|
||||
if(!any_stone) return false;
|
||||
}
|
||||
|
||||
level = spell.level;
|
||||
int effective_skill = pc.skill(type);
|
||||
if(pc.status[eStatus::DUMB] < 0)
|
||||
@@ -1696,7 +1710,21 @@ static void draw_spell_info(cDialog& me, const eSkill store_situation, const sho
|
||||
me[id].hide();
|
||||
}
|
||||
break;
|
||||
|
||||
case SELECT_DEAD:
|
||||
if(dead_statuses.count(univ.party[i].main_status)) {
|
||||
me[id].show();
|
||||
}else{
|
||||
me[id].hide();
|
||||
}
|
||||
break;
|
||||
case SELECT_STONE:
|
||||
if(univ.party[i].main_status == eMainStatus::STONE) {
|
||||
me[id].show();
|
||||
}
|
||||
else {
|
||||
me[id].hide();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1887,22 +1915,12 @@ static bool pick_spell_caster(cDialog& me, std::string id, const eSkill store_si
|
||||
}
|
||||
|
||||
static bool pick_spell_target(cDialog& me, std::string id, const eSkill store_situation, short& last_darkened, const short& store_spell) {
|
||||
static const char*const no_target = " No target needed.";
|
||||
static const char*const bad_target = " Can't cast on them.";
|
||||
static const char*const got_target = " Target selected.";
|
||||
short item_hit = id[id.length() - 1] - '1';
|
||||
std::string casting = id;
|
||||
casting[casting.length() - 1] = pc_casting + '1';
|
||||
if(!me[casting].isVisible()) {
|
||||
me["feedback"].setText(no_target);
|
||||
} else if(!me[id].isVisible()) {
|
||||
me["feedback"].setText(bad_target);
|
||||
} else {
|
||||
me["feedback"].setText(got_target);
|
||||
store_spell_target = item_hit;
|
||||
draw_spell_info(me, store_situation, store_spell);
|
||||
put_pc_target_buttons(me, last_darkened);
|
||||
}
|
||||
me["feedback"].setText(got_target);
|
||||
store_spell_target = item_hit;
|
||||
draw_spell_info(me, store_situation, store_spell);
|
||||
put_pc_target_buttons(me, last_darkened);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1941,14 +1959,21 @@ static bool pick_spell_select_led(cDialog& me, std::string id, eKeyMod mods, con
|
||||
put_pc_target_buttons(me, last_darkened);
|
||||
}
|
||||
}
|
||||
// Cute trick now... if a target is needed, caster can always be picked
|
||||
std::string targ = "target" + boost::lexical_cast<std::string>(pc_casting + 1);
|
||||
if((store_spell_target == 6) && me[targ].isVisible()) {
|
||||
bool any_targets = false;
|
||||
for(int i = 0; i < 6; ++i){
|
||||
std::string targ = "target" + boost::lexical_cast<std::string>(i + 1);
|
||||
if(me[targ].isVisible()){
|
||||
any_targets = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if((store_spell_target == 6) && any_targets) {
|
||||
me["feedback"].setText(choose_target);
|
||||
draw_spell_info(me, store_situation, store_spell);
|
||||
play_sound(45); // formerly force_play_sound
|
||||
}
|
||||
else if(!me[targ].isVisible()) {
|
||||
else{
|
||||
me["feedback"].setText("");
|
||||
store_spell_target = 6;
|
||||
put_pc_target_buttons(me, last_darkened);
|
||||
}
|
||||
|
@@ -1133,6 +1133,8 @@ void use_item(short pc,short item) {
|
||||
case SELECT_NO: break;
|
||||
case SELECT_ACTIVE: store_spell_target = select_pc(eSelectPC::ONLY_LIVING); break;
|
||||
case SELECT_ANY: store_spell_target = select_pc(eSelectPC::ANY); break;
|
||||
case SELECT_DEAD: store_spell_target = select_pc(eSelectPC::ONLY_DEAD); break;
|
||||
case SELECT_STONE: store_spell_target = select_pc(eSelectPC::ONLY_STONE); break;
|
||||
}
|
||||
if(overall_mode == MODE_COMBAT) {
|
||||
bool priest = (*spell).is_priest();
|
||||
|
@@ -328,7 +328,7 @@ cSpell P_BLESS_PARTY = cSpell(eSpell::BLESS_PARTY).asType(eSkill::PRIEST_SPELLS)
|
||||
cSpell P_HEAL_MAJOR = cSpell(eSpell::HEAL_MAJOR).asType(eSkill::PRIEST_SPELLS).asLevel(5)
|
||||
.withCost(7).needsSelect().when(WHEN_COMBAT).when(WHEN_TOWN).when(WHEN_OUTDOORS).finish();
|
||||
cSpell P_RAISE_DEAD = cSpell(eSpell::RAISE_DEAD).asType(eSkill::PRIEST_SPELLS).asLevel(5)
|
||||
.withCost(25).needsSelect(SELECT_ANY).when(WHEN_TOWN).when(WHEN_OUTDOORS).finish();
|
||||
.withCost(25).needsSelect(SELECT_DEAD).when(WHEN_TOWN).when(WHEN_OUTDOORS).finish();
|
||||
cSpell P_FLAMESTRIKE = cSpell(eSpell::FLAMESTRIKE).asType(eSkill::PRIEST_SPELLS).asLevel(5)
|
||||
.withRange(9).withTargetLock().withCost(8).withRefer(REFER_TARGET).when(WHEN_COMBAT).finish();
|
||||
cSpell P_SANCTUARY_MASS = cSpell(eSpell::SANCTUARY_MASS).asType(eSkill::PRIEST_SPELLS).asLevel(5)
|
||||
@@ -348,7 +348,7 @@ cSpell P_REVIVE = cSpell(eSpell::REVIVE).asType(eSkill::PRIEST_SPELLS).asLevel(6
|
||||
cSpell P_HYPERACTIVITY = cSpell(eSpell::HYPERACTIVITY).asType(eSkill::PRIEST_SPELLS).asLevel(6)
|
||||
.withCost(8).when(WHEN_COMBAT).when(WHEN_TOWN).when(WHEN_OUTDOORS).asPeaceful().finish();
|
||||
cSpell P_DESTONE = cSpell(eSpell::DESTONE).asType(eSkill::PRIEST_SPELLS).asLevel(6)
|
||||
.withCost(8).needsSelect(SELECT_ANY).when(WHEN_TOWN).when(WHEN_OUTDOORS).finish();
|
||||
.withCost(8).needsSelect(SELECT_STONE).when(WHEN_TOWN).when(WHEN_OUTDOORS).finish();
|
||||
cSpell P_SUMMON_GUARDIAN = cSpell(eSpell::SUMMON_GUARDIAN).asType(eSkill::PRIEST_SPELLS).asLevel(6)
|
||||
.withRange(4).withCost(14).withRefer(REFER_TARGET).when(WHEN_COMBAT).when(WHEN_TOWN).finish();
|
||||
// This is always centered on the caster:
|
||||
@@ -366,7 +366,7 @@ cSpell P_REVIVE_ALL = cSpell(eSpell::REVIVE_ALL).asType(eSkill::PRIEST_SPELLS).a
|
||||
cSpell P_RAVAGE_SPIRIT = cSpell(eSpell::RAVAGE_SPIRIT).asType(eSkill::PRIEST_SPELLS).asLevel(7)
|
||||
.withRange(4).withTargetLock().withCost(10).withRefer(REFER_TARGET).when(WHEN_COMBAT).finish();
|
||||
cSpell P_RESURRECT = cSpell(eSpell::RESURRECT).asType(eSkill::PRIEST_SPELLS).asLevel(7)
|
||||
.withCost(35).needsSelect(SELECT_ANY).when(WHEN_TOWN).when(WHEN_OUTDOORS).finish();
|
||||
.withCost(35).needsSelect(SELECT_DEAD).when(WHEN_TOWN).when(WHEN_OUTDOORS).finish();
|
||||
cSpell P_DIVINE_THUD = cSpell(eSpell::DIVINE_THUD).asType(eSkill::PRIEST_SPELLS).asLevel(7)
|
||||
.withRange(12).withTargetLock().withCost(10).withRefer(REFER_TARGET).when(WHEN_COMBAT).finish();
|
||||
cSpell P_AVATAR = cSpell(eSpell::AVATAR).asType(eSkill::PRIEST_SPELLS).asLevel(7)
|
||||
|
@@ -16,7 +16,7 @@
|
||||
// This controls how a spell is cast in combat; YES means it's the same as in town, IMMED means it has a special implementation in town, and TARGET / FANCY both mean it requires target selection.
|
||||
enum eSpellRefer {REFER_YES, REFER_IMMED, REFER_TARGET, REFER_FANCY};
|
||||
// This specifies whether a spell targets a party member and whether dead PCs can be chosen.
|
||||
enum eSpellSelect {SELECT_NO, SELECT_ACTIVE, SELECT_ANY};
|
||||
enum eSpellSelect {SELECT_NO, SELECT_ACTIVE, SELECT_ANY, SELECT_DEAD, SELECT_STONE};
|
||||
// This one is meant for indexing a bit field
|
||||
enum eSpellWhen {WHEN_COMBAT = 1, WHEN_TOWN = 2, WHEN_OUTDOORS = 4};
|
||||
|
||||
|
Reference in New Issue
Block a user