mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-28 13:56:18 +00:00
Split the 'not_living' unit status into...
...unpoisonable, undrainable and unplagueable
This commit is contained in:
parent
6a6780af0d
commit
d82762b87d
@ -30,6 +30,8 @@ Version 1.11.1+svn:
|
||||
* When not replacing values, [effect] apply_to=defense will now modify
|
||||
absolute values instead of signed values (bug #20242). This allows for
|
||||
cleaner WML when the unit type is not necessarily known in advance.
|
||||
* Split the 'not_living' unit status into 'unpoisonable', 'undrainable' and
|
||||
'unplagueable'. 'not_living' now acts on the whole group
|
||||
* Miscellaneous and bug fixes:
|
||||
* The undo stack is preserved across a save-reload.
|
||||
* Removed several unused private member variables.
|
||||
|
@ -24,7 +24,15 @@
|
||||
description= _ "Immune to drain, poison, and plague"
|
||||
[effect]
|
||||
apply_to=status
|
||||
add=not_living
|
||||
add=unpoisonable
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=status
|
||||
add=undrainable
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=status
|
||||
add=unplagueable
|
||||
[/effect]
|
||||
[/trait]
|
||||
#enddef
|
||||
@ -39,7 +47,15 @@
|
||||
description= _ "Immune to drain, poison, and plague"
|
||||
[effect]
|
||||
apply_to=status
|
||||
add=not_living
|
||||
add=unpoisonable
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=status
|
||||
add=undrainable
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=status
|
||||
add=unplagueable
|
||||
[/effect]
|
||||
[/trait]
|
||||
#enddef
|
||||
@ -54,7 +70,15 @@
|
||||
description= _ "Immune to drain, poison, and plague"
|
||||
[effect]
|
||||
apply_to=status
|
||||
add=not_living
|
||||
add=unpoisonable
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=status
|
||||
add=undrainable
|
||||
[/effect]
|
||||
[effect]
|
||||
apply_to=status
|
||||
add=unplagueable
|
||||
[/effect]
|
||||
[/trait]
|
||||
#enddef
|
||||
|
@ -3237,6 +3237,92 @@ Result:
|
||||
[/replace_schedule]
|
||||
[/event]
|
||||
|
||||
[label]
|
||||
x,y=23,10
|
||||
text="livingness"
|
||||
[/label]
|
||||
[event]
|
||||
name=moveto
|
||||
first_time_only=no
|
||||
[filter]
|
||||
x,y=23,10
|
||||
[/filter]
|
||||
|
||||
[while]
|
||||
[variable]
|
||||
name="choice"
|
||||
not_equals="done"
|
||||
[/variable]
|
||||
[do]
|
||||
[store_unit]
|
||||
variable="wml_unit"
|
||||
[filter]
|
||||
x=$x1,y=$y1
|
||||
[/filter]
|
||||
[/store_unit]
|
||||
[message]
|
||||
speaker=narrator
|
||||
message="Unit statuses in WML:
|
||||
|
||||
not_living: $wml_unit.status.not_living
|
||||
unpoisonable: $wml_unit.status.unpoisonable
|
||||
undrainable: $wml_unit.status.undrainable
|
||||
unplagueable: $wml_unit.status.unplagueable"
|
||||
[/message]
|
||||
[lua]
|
||||
code=<<
|
||||
local args = ...
|
||||
local unit = wesnoth.get_unit(args.x1, args.y1)
|
||||
local raw_msg = "Unit statuses in LUA:\
|
||||
\
|
||||
not_living: %s\
|
||||
unpoisonable: %s\
|
||||
undrainable: %s\
|
||||
unplagueable: %s"
|
||||
local msg = string.format(raw_msg, unit.status.not_living, unit.status.unpoisonable, unit.status.undrainable, unit.status.unplagueable)
|
||||
wesnoth.wml_actions.message({speaker = "narrator", message = msg})
|
||||
|
||||
wesnoth.wml_actions.message({speaker = "narrator", message = "Do you want to change any of that?",
|
||||
{ "option", { message = "Flip not_living",
|
||||
{ "command", {
|
||||
{ "set_variable", { name = "choice", value = "not_living" } } } } } },
|
||||
{ "option", { message = "Flip unpoisonable",
|
||||
{ "command", {
|
||||
{ "set_variable", { name = "choice", value = "unpoisonable" } } } } } },
|
||||
{ "option", { message = "Flip undrainable",
|
||||
{ "command", {
|
||||
{ "set_variable", { name = "choice", value = "undrainable" } } } } } },
|
||||
{ "option", { message = "Flip unplagueable",
|
||||
{ "command", {
|
||||
{ "set_variable", { name = "choice", value = "unplagueable" } } } } } },
|
||||
{ "option", { message = "Nope",
|
||||
{ "command", {
|
||||
{ "set_variable", { name = "choice", value = "done" } } } } } }
|
||||
})
|
||||
local choice = wesnoth.get_variable("choice")
|
||||
-- debug :unit will reapply musthave traits, breaking these modifications for undead
|
||||
-- if you want something more permanent, give the unit an object
|
||||
if choice == "not_living" then
|
||||
unit.status.not_living = not unit.status.not_living
|
||||
elseif choice == "unpoisonable" then
|
||||
unit.status.unpoisonable = not unit.status.unpoisonable
|
||||
elseif choice == "undrainable" then
|
||||
unit.status.undrainable = not unit.status.undrainable
|
||||
elseif choice == "unplagueable" then
|
||||
unit.status.unplagueable = not unit.status.unplagueable
|
||||
end
|
||||
>>
|
||||
[args]
|
||||
x1=$x1
|
||||
y1=$y1
|
||||
[/args]
|
||||
[/lua]
|
||||
[/do]
|
||||
[/while]
|
||||
{CLEAR_VARIABLE choice}
|
||||
{CLEAR_VARIABLE wml_unit}
|
||||
[/event]
|
||||
|
||||
# Capture connected villages near 13,2 for team 2
|
||||
[event]
|
||||
name=prestart
|
||||
|
@ -109,18 +109,17 @@ battle_context_unit_stats::battle_context_unit_stats(const unit &u,
|
||||
weapon->set_specials_context(u_loc, opp_loc, attacking, opp_weapon);
|
||||
if (opp_weapon)
|
||||
opp_weapon->set_specials_context(opp_loc, u_loc, !attacking, weapon);
|
||||
bool not_living = opp.get_state("not_living");
|
||||
slows = weapon->get_special_bool("slow");
|
||||
drains = !not_living && weapon->get_special_bool("drains");
|
||||
drains = !opp.get_state("undrainable") && weapon->get_special_bool("drains");
|
||||
petrifies = weapon->get_special_bool("petrifies");
|
||||
poisons = !not_living && weapon->get_special_bool("poison") && !opp.get_state(unit::STATE_POISONED);
|
||||
poisons = !opp.get_state("unpoisonable") && weapon->get_special_bool("poison") && !opp.get_state(unit::STATE_POISONED);
|
||||
backstab_pos = is_attacker && backstab_check(u_loc, opp_loc, units, *resources::teams);
|
||||
rounds = weapon->get_specials("berserk").highest("value", 1).first;
|
||||
firststrike = weapon->get_special_bool("firststrike");
|
||||
|
||||
// Handle plague.
|
||||
unit_ability_list plague_specials = weapon->get_specials("plague");
|
||||
plagues = !not_living && !plague_specials.empty() &&
|
||||
plagues = !opp.get_state("unplagueable") && !plague_specials.empty() &&
|
||||
strcmp(opp.undead_variation().c_str(), "null") && !resources::game_map->is_village(opp_loc);
|
||||
|
||||
if (plagues) {
|
||||
|
@ -357,7 +357,7 @@ int ai_default_recruitment_stage::average_resistance_against(const unit_type& a,
|
||||
|
||||
// calculation of the average damage taken
|
||||
bool steadfast = a.has_ability_by_id("steadfast");
|
||||
bool living = !a.not_living();
|
||||
bool poisonable = !a.musthave_status("unpoisonable");
|
||||
const std::vector<attack_type>& attacks = b.attacks();
|
||||
for (std::vector<attack_type>::const_iterator i = attacks.begin(),
|
||||
i_end = attacks.end(); i != i_end; ++i)
|
||||
@ -370,7 +370,7 @@ int ai_default_recruitment_stage::average_resistance_against(const unit_type& a,
|
||||
int cth = i->get_special_bool("chance_to_hit", true) ? 70 : defense;
|
||||
int weight = i->damage() * i->num_attacks();
|
||||
// if cth == 0 the division will do 0/0 so don't execute this part
|
||||
if (living && cth != 0 && i->get_special_bool("poison", true)) {
|
||||
if (poisonable && cth != 0 && i->get_special_bool("poison", true)) {
|
||||
// Compute the probability of not poisoning the unit.
|
||||
int prob = 100;
|
||||
for (int j = 0; j < i->num_attacks(); ++j)
|
||||
|
@ -404,7 +404,7 @@ int recruitment_phase::average_resistance_against(const unit_type& a, const unit
|
||||
|
||||
// calculation of the average damage taken
|
||||
bool steadfast = a.has_ability_by_id("steadfast");
|
||||
bool living = !a.not_living();
|
||||
bool poisonable = !a.musthave_status("unpoisonable");
|
||||
const std::vector<attack_type>& attacks = b.attacks();
|
||||
for (std::vector<attack_type>::const_iterator i = attacks.begin(),
|
||||
i_end = attacks.end(); i != i_end; ++i)
|
||||
@ -417,7 +417,7 @@ int recruitment_phase::average_resistance_against(const unit_type& a, const unit
|
||||
int cth = i->get_special_bool("chance_to_hit", true) ? 70 : defense;
|
||||
int weight = i->damage() * i->num_attacks();
|
||||
// if cth == 0 the division will do 0/0 so don't execute this part
|
||||
if (living && cth != 0 && i->get_special_bool("poison", true)) {
|
||||
if (poisonable && cth != 0 && i->get_special_bool("poison", true)) {
|
||||
// Compute the probability of not poisoning the unit.
|
||||
int prob = 100;
|
||||
for (int j = 0; j < i->num_attacks(); ++j)
|
||||
|
@ -289,7 +289,7 @@ static int average_resistance_against(const unit_type& a, const unit_type& b)
|
||||
|
||||
// calculation of the average damage taken
|
||||
bool steadfast = a.has_ability_by_id("steadfast");
|
||||
bool living = !a.not_living();
|
||||
bool poisonable = !a.musthave_status("unpoisonable");
|
||||
const std::vector<attack_type>& attacks = b.attacks();
|
||||
for (std::vector<attack_type>::const_iterator i = attacks.begin(),
|
||||
i_end = attacks.end(); i != i_end; ++i)
|
||||
@ -302,7 +302,7 @@ static int average_resistance_against(const unit_type& a, const unit_type& b)
|
||||
int cth = i->get_special_bool("chance_to_hit", true) ? 70 : defense;
|
||||
int weight = i->damage() * i->num_attacks();
|
||||
// if cth == 0 the division will do 0/0 so don't execute this part
|
||||
if (living && cth != 0 && i->get_special_bool("poison", true)) {
|
||||
if (poisonable && cth != 0 && i->get_special_bool("poison", true)) {
|
||||
// Compute the probability of not poisoning the unit.
|
||||
int prob = 100;
|
||||
for (int j = 0; j < i->num_attacks(); ++j)
|
||||
|
@ -309,8 +309,12 @@ variant unit_type_callable::get_value(const std::string& key) const
|
||||
return variant(u_.level());
|
||||
} else if(key == "total_movement") {
|
||||
return variant(u_.movement());
|
||||
} else if(key == "undead") {
|
||||
return variant(u_.not_living());
|
||||
} else if(key == "unpoisonable") {
|
||||
return variant(u_.musthave_status("unpoisonable"));
|
||||
} else if(key == "undrainable") {
|
||||
return variant(u_.musthave_status("undrainable"));
|
||||
} else if(key == "unplagueable") {
|
||||
return variant(u_.musthave_status("unplagueable"));
|
||||
} else if(key == "cost") {
|
||||
return variant(u_.cost());
|
||||
} else if(key == "usage") {
|
||||
|
17
src/unit.cpp
17
src/unit.cpp
@ -1208,6 +1208,11 @@ const std::map<std::string,std::string> unit::get_states() const
|
||||
}
|
||||
|
||||
}
|
||||
// Backwards compatibility for not_living. Don't remove before 1.12
|
||||
if (all_states.find("undrainable") != all_states.end() &&
|
||||
all_states.find("unpoisonable") != all_states.end() &&
|
||||
all_states.find("unplagueable") != all_states.end())
|
||||
all_states["not_living"] = "yes";
|
||||
return all_states;
|
||||
}
|
||||
|
||||
@ -1217,6 +1222,12 @@ bool unit::get_state(const std::string &state) const
|
||||
if (known_boolean_state_id!=STATE_UNKNOWN){
|
||||
return get_state(known_boolean_state_id);
|
||||
}
|
||||
// Backwards compatibility for not_living. Don't remove before 1.12
|
||||
if (state == "not_living") {
|
||||
return get_state("undrainable") &&
|
||||
get_state("unpoisonable") &&
|
||||
get_state("unplagueable");
|
||||
}
|
||||
return states_.find(state) != states_.end();
|
||||
}
|
||||
|
||||
@ -1260,6 +1271,12 @@ void unit::set_state(const std::string &state, bool value)
|
||||
set_state(known_boolean_state_id, value);
|
||||
return;
|
||||
}
|
||||
// Backwards compatibility for not_living. Don't remove before 1.12
|
||||
if (state == "not_living") {
|
||||
set_state("undrainable", value);
|
||||
set_state("unpoisonable", value);
|
||||
set_state("unplagueable", value);
|
||||
}
|
||||
if (value)
|
||||
states_.insert(state);
|
||||
else
|
||||
|
@ -1419,15 +1419,15 @@ const unit_race *unit_type_data::find_race(const std::string &key) const
|
||||
return i != races_.end() ? &i->second : NULL;
|
||||
}
|
||||
|
||||
// This function is only meant to return the likely state of not_living
|
||||
// This function is only meant to return the likely state a given status
|
||||
// for a new recruit of this type. It should not be used to check if
|
||||
// a particular unit is living or not, use get_state("not_living") for that.
|
||||
bool unit_type::not_living() const
|
||||
// a particular unit has it, use get_state(status_name) for that.
|
||||
bool unit_type::musthave_status(const std::string& status_name) const
|
||||
{
|
||||
// If a unit hasn't been modified it starts out as living.
|
||||
bool not_living = false;
|
||||
// Statuses default to absent.
|
||||
bool current_status = false;
|
||||
|
||||
// Look at all of the "musthave" traits to see if the not_living
|
||||
// Look at all of the "musthave" traits to see if the
|
||||
// status gets changed. In the unlikely event it gets changed
|
||||
// multiple times, we want to try to do it in the same order
|
||||
// that unit::apply_modifications does things.
|
||||
@ -1454,16 +1454,16 @@ bool unit_type::not_living() const
|
||||
if (effect["apply_to"] != "status") {
|
||||
continue;
|
||||
}
|
||||
if (effect["add"] == "not_living") {
|
||||
not_living = true;
|
||||
if (effect["add"] == status_name) {
|
||||
current_status = true;
|
||||
}
|
||||
if (effect["remove"] == "not_living") {
|
||||
not_living = false;
|
||||
if (effect["remove"] == status_name) {
|
||||
current_status = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return not_living;
|
||||
return current_status;
|
||||
}
|
||||
|
||||
bool unit_type::has_random_traits() const
|
||||
|
@ -283,7 +283,7 @@ public:
|
||||
|
||||
bool can_advance() const { return !advances_to_.empty(); }
|
||||
|
||||
bool not_living() const;
|
||||
bool musthave_status(const std::string& status) const;
|
||||
|
||||
bool has_zoc() const { return zoc_; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user